UNPKG

causalityjs

Version:

A library for reactive programming based on Javascript proxies.

188 lines (148 loc) 4.99 kB
'use strict'; require('../../causality').install(); const log = console.log.bind(console); const graph = { 1: {a: [2,3,4,5,6] }, 2: {a: [7,8,9], b: 10}, 3: {a: [8], b: 11}, 4: {a: [9], b: 11}, 5: {a: [8], b: 12}, 6: {a: [9], b: 12}, 7: {}, 8: {}, 9: {}, 10: {b: 13}, 11: {b: 14}, 12: {b: 14}, }; const state = {}; function stateGet( id, o ){ if( state[id] ) return state[id]; state[id] = o; o.obs = c({id}); return o; } class C { constructor( id ){ if( state[id] ) return state[id]; state[id] = this; this.obs = c({id}); const props = this.constructor.properties || {}; const name = this.constructor.name; for( let prop of Object.keys( props ) ){ const propP = prop+'P'; if( this[propP] ){ const propS = '_' + prop; const nameR = `${name}.${prop}`; this[propS] = c([]); setTimeout(()=> repeat(nameR, async con=>{ //log(`*${nameR} repeated`); const res = await this[propP](con); // Does update outside recording context this._updateArray(propS, res); }) ,1); Object.defineProperty( this, prop, { value: this[propS], enumerable: true, writable: false, }); //log('**prop', prop); } } //log( '**props', this.constructor.properties ); return this; } async listP( context, ofClass ){ const newlist = []; for( let id of graph[this.obs.id].a ){ newlist.push( new ofClass( id ) ); } return newlist; } async relP( ofClass ){ const id = graph[this.obs.id].b; return new ofClass( id ); } _updateArray( prop, content ){ if( !this[prop] ) return this[prop] = c(Array.from(content)); this[prop].splice( 0, this[prop].length, ... content ); return this[prop]; } } class B extends C { static get properties(){return{ listL: Array, listD: Array, }} async listLP( context = emptyContext() ){ const newlist = new Map(); for( let r of await context.record(()=> this.listP( context, R ) ) ){ const l = await context.record(()=> r.relLP( context ) ); if( newlist.has( l.obs.id ) ) continue; context.record(()=> newlist.set( l.obs.id, l ) ); } return newlist.values(); } async listDP( context = emptyContext() ){ const newlist = new Map(); for( let r of await context.record(()=> this.listP( context, R ) ) ){ for( let d of await context.record(()=> r.listP( context, D ) ) ){ if( newlist.has( d.obs.id ) ) continue; context.record(()=> newlist.set( d.obs.id, d ) ); } } return newlist.values(); } } class R extends C { async relLP( context = emptyContext() ){ const a = await context.record(()=> this.relP( A ) ); const l = await context.record(()=> a.relP( L ) ); return l; } } class D extends C {} class A extends C { static get properties(){return{ listR: Array, listD: Array, }} async listRP( context = emptyContext() ){ const b = new B(1); const newlist = new Map(); for( let r of await context.record(()=> b.listP( context, R ) ) ){ const a = await context.record(()=> r.relP( A ) ); if( a.obs.id !== this.obs.id ) continue; context.record(()=> newlist.set( r.obs.id, r) ); } return newlist.values(); } async listDP( context = emptyContext() ){ const newlist = new Map(); for( let r of await context.record(()=> this.listRP( context ) ) ){ for( let d of await context.record(()=> r.listP( context, D ) ) ){ context.record(()=> newlist.set( d.obs.id, d) ); } } return newlist.values(); } } class L extends C { static get properties(){return{ listA: Array, }} async listAP( context = emptyContext() ){ const b = new B(1); const newlist = new Map(); for( let r of await context.record(()=> b.listP( context, R ) ) ){ const a = await context.record(()=> r.relP( A ) ); const l = await context.record(()=> r.relLP( context ) ); if( l.obs.id !== this.obs.id ) continue; context.record(()=> newlist.set( a.obs.id, a) ); } return newlist.values(); } } module.exports.B = B;