can-define-stream
Add useful stream conversion methods to a supplied can-define/map/map or can-define/list/list constructor using a stream interface such as can-stream-kefir.
    canDefineStream(streamInterface)
  
  The can-define-stream module exports a function that takes a streamInterface and returns a function that takes a DefineMap.prototype or DefineList.prototype and uses the supplied stream interface to create streamed property definitions.
import canStream from "can-stream-kefir";
import canDefineStream from "can-define-stream";
import DefineMap from "can-define/map/map";
const Person = DefineMap.extend( {
    first: "string",
    last: "string",
    fullName: {
        get: function() {
            return this.first + " " + this.last;
        }
    },
    fullNameChangeCount: {
        stream: function() {
            return this.toStream( ".fullName" ).scan( function( last ) {
                return last + 1;
            }, 0 );
        }
    }
} );
canDefineStream( canStream )( Person );
const me = new Person( { name: "Justin", last: "Meyer" } );
me.on( "fullNameChangeCount", function( ev, newVal ) {
    console.log( newVal );
} );
me.fullNameChangeCount; //-> 0
me.first = "Obaid"; //-> console.logs 1
me.last = "Ahmed"; //-> console.logs 2
  
  Parameters
- streamInterface 
{streamInterface()}:A streamInterface function. See can-stream-kefir for implementation.
 
Use
The toStream method has shorthands for all of the other methods:
toStream( "eventName" );           //-> stream
toStream( ".propName" );           //-> stream
toStream( ".propName eventName" ); //-> stream
For example:
Update map property based on stream value
import DefineMap from "can-define/map/map";
import canStream from "can-stream-kefir";
import canDefineStream from "can-define-stream";
const Person = DefineMap.extend( {
    name: "string",
    lastValidName: {
        stream: function() {
            return this.toStream( ".name" ).filter( function( name ) { // using propName
                return name.indexOf( " " ) >= 0;
            } );
        }
    }
} );
canDefineStream( canStream )( Person );
const me = new Person( { name: "James" } );
me.on( "lastValidName", function( lastValid ) {} );
me.name = "JamesAtherton"; //lastValidName -> undefined
me.name = "James Atherton"; //lastValidName -> James Atherton
Stream on DefineList
import DefineList from "can-define/list/list";
import canStream from "can-stream-kefir";
import canDefineStream from "can-define-stream";
const PeopleList = DefineList.extend( {} );
canDefineStream( canStream )( PeopleList );
const people = new PeopleList( [
    { first: "Justin", last: "Meyer" },
    { first: "Paula", last: "Strozak" }
] );
const stream = people.toStream( "length" ); // using eventName
stream.onValue( function( val ) {
    val; //-> 2, 3
} );
people.push( {
    first: "Obaid",
    last: "Ahmed"
} ); //-> stream.onValue -> 3