@cyysummer/projector 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,4 +3,4 @@
3
3
  * (c) 2021-PRESENT Chris Liu
4
4
  * @license MIT
5
5
  **/
6
- import _ from"on-change";import{set as g}from"lodash-es";import{withEvents as S}from"@cyysummer/core";var T=class extends S(){constructor(e){super();this._paused=!1;this._shadow=structuredClone(e)}record(e,r){this._paused||(g(this._shadow,e,r),this.emit("record",{next:this._shadow,path:e,value:r}))}pause(){this._paused=!0}resume(){this._paused=!1}};import{get as p}from"lodash-es";var l=a=>{},h=class{constructor(t){this._strategy=t}chain(t){return async(e,r)=>{let c=s(r);for(let o of t)await o(e,{value:c})}}chainWith(t,e){return async(c,o)=>{let u=s(o),n=e(u);for(let f of t)await f(c,{value:n})}}create(t){return(e,r)=>{let c=s(r);return this._strategy.execute(e,t,c)}}createIf(t,e,r=l){return(c,o)=>{let u=s(o);return(t(u)?e:r)(c,{value:u})}}createIfRoot(t,e,r=l){return(c,o)=>(t(o.source)?e:r)(c,o)}createRoot(t,e){return(r,c)=>{let o=e(c.source);return this._strategy.execute(r,t,o)}}createForArray(t){return(e,r)=>{let c=r.path?p(r.source,r.path):r.value;if(c&&Array.isArray(c)&&c.length>0){let o=Object.keys(c[0]);return this._strategy.executeArray(e,t,o,c)}}}createForRaw(t,e){return(r,c)=>this._strategy.execute(r,t,e)}createWith(t,e){return(c,o)=>{let u=s(o),n=e(u);return this._strategy.execute(c,t,n)}}};function s(a){return a.source&&a.path?p(a.source,a.path):a.value}var y=class{constructor(t,e){this._schema=t;this._scheduler=e}project(t,...e){if(!this._schema)throw new Error("Schema not loaded");for(let r of e)this._dispatch(t,r)}_dispatch(t,e){let{path:r,value:c}=e,o=this._resolveEffect(r);o&&this._scheduler.enqueue({path:r.join("."),effect:o,ctx:{source:t,path:r,value:c}})}_resolveEffect(t){let e=this._schema;for(let r of t){if(!e)return null;e=e[r]}return typeof e=="function"?e:null}};var i=class{constructor(t=null){this._target=t;this._targetFactory=null}withTarget(t){return typeof t=="function"?this._targetFactory=t:this._target=t,this}checkTarget(){if(!this._target&&this._targetFactory&&(this._target=this._targetFactory()),!this._target)throw new Error("Scheduler: target is not set")}},d=class extends i{constructor(){super(...arguments);this._queue=new Map}enqueue(e){return this._queue.set(e.path,e),this}async flush(){this.checkTarget(),log.trace("BufferedScheduler: flushing");let e=[...this._queue.values()];this._queue.clear();for(let r of e){let{effect:c,ctx:o}=r,u=c(this._target,o);u instanceof Promise&&await u}}};function F(a){let t=new T(a);return[_(a,t.record.bind(t),{pathAsArray:!0}),t]}export{d as BufferedScheduler,h as EffectBuilder,y as Projector,T as Recorder,i as Scheduler,F as track};
6
+ import m from"on-change";import{set as d}from"lodash-es";import{withEvents as g}from"@cyysummer/core";var T=class extends g(){constructor(e){super();this._paused=!1;this._shadow=structuredClone(e)}record(e,r){this._paused||(d(this._shadow,e,r),this.emit("record",{next:this._shadow,patches:[{path:e,value:r}]}))}pause(){this._paused=!0}resume(){this._paused=!1}};import{get as p}from"lodash-es";var h=a=>{},l=class{constructor(t){this._strategy=t}chain(t){return async(e,r)=>{let c=s(r);for(let o of t)await o(e,{value:c})}}chainWith(t,e){return async(c,o)=>{let u=s(o),n=e(u);for(let i of t)await i(c,{value:n})}}create(t){return(e,r)=>{let c=s(r);return this._strategy.execute(e,t,c)}}createIf(t,e,r=h){return(c,o)=>{let u=s(o);return(t(u)?e:r)(c,{value:u})}}createIfRoot(t,e,r=h){return(c,o)=>(t(o.source)?e:r)(c,o)}createRoot(t,e){return(r,c)=>{let o=e(c.source);return this._strategy.execute(r,t,o)}}createForArray(t){return(e,r)=>{let c=r.path?p(r.source,r.path):r.value;if(c&&Array.isArray(c)&&c.length>0){let o=Object.keys(c[0]);return this._strategy.executeArray(e,t,o,c)}}}createForRaw(t,e){return(r,c)=>this._strategy.execute(r,t,e)}createWith(t,e){return(c,o)=>{let u=s(o),n=e(u);return this._strategy.execute(c,t,n)}}};function s(a){return a.source&&a.path?p(a.source,a.path):a.value}var y=class{constructor(t,e){this._schema=t;this._scheduler=e}project(t,...e){if(!this._schema)throw new Error("Schema not loaded");for(let r of e)this._dispatch(t,r)}_dispatch(t,e){let{path:r,value:c}=e,o=this._resolveEffect(r);o&&this._scheduler.enqueue({path:r.join("."),effect:o,ctx:{source:t,path:r,value:c}})}_resolveEffect(t){let e=this._schema;for(let r of t){if(!e)return null;e=e[r]}return typeof e=="function"?e:null}};var f=class{constructor(t=null){this._target=t;this._targetFactory=null}withTarget(t){return typeof t=="function"?this._targetFactory=t:this._target=t,this}checkTarget(){if(!this._target&&this._targetFactory&&(this._target=this._targetFactory()),!this._target)throw new Error("Scheduler: target is not set")}},S=class extends f{constructor(){super(...arguments);this._queue=new Map}enqueue(e){return this._queue.set(e.path,e),this}async flush(){this.checkTarget(),log.trace("BufferedScheduler: flushing");let e=[...this._queue.values()];this._queue.clear();for(let r of e){let{effect:c,ctx:o}=r,u=c(this._target,o);u instanceof Promise&&await u}}};function F(a){let t=new T(a);return[m(a,t.record.bind(t),{pathAsArray:!0}),t]}export{S as BufferedScheduler,l as EffectBuilder,y as Projector,T as Recorder,f as Scheduler,F as track};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyysummer/projector",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "A powerful state projection library for creating anything.",
5
5
  "license": "MIT",
6
6
  "author": "Chris Liu",
package/types/lib.d.ts CHANGED
@@ -1,8 +1,68 @@
1
+ // prettier-ignore
2
+ type Schema<TSource, T = any> = TSource extends object ?
3
+ Partial<{
4
+ // If the property is an array, map whole array to effect.
5
+ // Else map property to schema.
6
+ [K in keyof T]:
7
+ T[K] extends Array<infer U> ?
8
+ Effect<TSource, U>
9
+ // If TSource is an object, map each property to schema, or write effect for the property.
10
+ : Schema<TSource, T[K]> | Effect<TSource, T[K]>;
11
+ }>
12
+ // Else map T to effect.
13
+ : Effect<TSource, T>;
14
+
15
+ // todo: Solve this `any`
16
+ type Effect<TSource, TValue> = (target: any, ctx: IEffectContext<TSource, TValue>) => MaybePromise<void>;
17
+
18
+ interface IEffectContext<TSource, TValue> {
19
+ /**
20
+ * The source object.
21
+ */
22
+ source?: TSource;
23
+ /**
24
+ * The path of the property.
25
+ */
26
+ path?: string;
27
+ /**
28
+ * The value of the property.
29
+ *
30
+ * If `source` or `path` is not specified, the value is passed from another effect.
31
+ */
32
+ value: TValue;
33
+ }
34
+
35
+ interface ITargetStrategy<TTarget> {
36
+ execute<T>(target: TTarget, at: string, value: T): MaybePromise<void>;
37
+ executeArray<T>(target: TTarget, at: string, keys: Partial<keyof T>[], rows: T[]): MaybePromise<void>;
38
+ }
39
+
40
+ interface IProjector<TSource> {
41
+ project(next: TSource, ...patches: Patch[]): void;
42
+ }
43
+
44
+ interface IScheduler<TTarget> {
45
+ enqueue(effect: IScheduleItem): void;
46
+ flush(): MaybePromise<void>;
47
+ withTarget(target: TTarget): IScheduler<TTarget>;
48
+ withTarget(target: Func<TTarget>): IScheduler<TTarget>;
49
+ }
50
+
51
+ interface IScheduleItem<TSource, TValue> {
52
+ path: string;
53
+ effect: Effect<TSource, TValue>;
54
+ ctx: IEffectContext<TSource, TValue>;
55
+ }
56
+
57
+ interface Patch {
58
+ path: (string | symbol)[];
59
+ value: any;
60
+ }
61
+
1
62
  type RecorderEvents = {
2
63
  record: {
3
64
  next: any;
4
- path: any[];
5
- value: any;
65
+ patches: Patch[];
6
66
  };
7
67
  };
8
68
  declare const Recorder_base: Constructor<object> & (new (...args: any[]) => object & IEventful<RecorderEvents>);
package/types/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // prettier-ignore
2
- type Schema<TSource, T = any> = TSource extends object ?
2
+ export type Schema<TSource, T = any> = TSource extends object ?
3
3
  Partial<{
4
4
  // If the property is an array, map whole array to effect.
5
5
  // Else map property to schema.
@@ -13,9 +13,9 @@ type Schema<TSource, T = any> = TSource extends object ?
13
13
  : Effect<TSource, T>;
14
14
 
15
15
  // todo: Solve this `any`
16
- type Effect<TSource, TValue> = (target: any, ctx: IEffectContext<TSource, TValue>) => MaybePromise<void>;
16
+ export type Effect<TSource, TValue> = (target: any, ctx: IEffectContext<TSource, TValue>) => MaybePromise<void>;
17
17
 
18
- interface IEffectContext<TSource, TValue> {
18
+ export interface IEffectContext<TSource, TValue> {
19
19
  /**
20
20
  * The source object.
21
21
  */
@@ -32,29 +32,29 @@ interface IEffectContext<TSource, TValue> {
32
32
  value: TValue;
33
33
  }
34
34
 
35
- interface ITargetStrategy<TTarget> {
35
+ export interface ITargetStrategy<TTarget> {
36
36
  execute<T>(target: TTarget, at: string, value: T): MaybePromise<void>;
37
37
  executeArray<T>(target: TTarget, at: string, keys: Partial<keyof T>[], rows: T[]): MaybePromise<void>;
38
38
  }
39
39
 
40
- interface IProjector<TSource> {
40
+ export interface IProjector<TSource> {
41
41
  project(next: TSource, ...patches: Patch[]): void;
42
42
  }
43
43
 
44
- interface IScheduler<TTarget> {
44
+ export interface IScheduler<TTarget> {
45
45
  enqueue(effect: IScheduleItem): void;
46
46
  flush(): MaybePromise<void>;
47
47
  withTarget(target: TTarget): IScheduler<TTarget>;
48
48
  withTarget(target: Func<TTarget>): IScheduler<TTarget>;
49
49
  }
50
50
 
51
- interface IScheduleItem<TSource, TValue> {
51
+ export interface IScheduleItem<TSource, TValue> {
52
52
  path: string;
53
53
  effect: Effect<TSource, TValue>;
54
54
  ctx: IEffectContext<TSource, TValue>;
55
55
  }
56
56
 
57
- interface Patch {
57
+ export interface Patch {
58
58
  path: (string | symbol)[];
59
59
  value: any;
60
60
  }