@cyysummer/projector 0.0.7 → 0.0.8

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
@@ -1,7 +1,7 @@
1
1
  /**
2
- * @cyysummer/projector v0.0.7
2
+ * @cyysummer/projector v0.0.8
3
3
  * (c) 2021-PRESENT Chris Liu
4
4
  * @license MIT
5
5
  **/
6
- import I from"on-change";import{set as E}from"lodash-es";import{withEvents as m}from"@cyysummer/core";var i=class extends m(){constructor(e){super();this._paused=!1;this._shadow=structuredClone(e)}receive(e,r){if(this._paused)return;E(this._shadow,e,r);let c=[{path:e,value:r}];this.emit("record",{next:this._shadow,patches:c}),this._ensureProjector(),this._projector?.project(this._shadow,...c)}sendTo(e){typeof e=="function"?this._projectorFactory=e:this._projector=e}pause(){this._paused=!0}resume(){this._paused=!1}_ensureProjector(){!this._projector&&this._projectorFactory&&(this._projector=this._projectorFactory())}};import{get as S}from"lodash-es";var p=u=>{},d=class{constructor(t){this._strategy=t}create(t){return(e,r)=>{let c=a(r);return this._strategy.execute(e,t,c)}}createWith(t,e){return(c,o)=>{let s=a(o),n=e(s);return this._strategy.execute(c,t,n)}}forEach(t){return async(e,r)=>{let c=a(r);if(Array.isArray(c)){let o=c;for(let s=0;s<o.length;s++){let n=o[s],l=t(n,s)(e,{value:n});l instanceof Promise&&await l}}else throw new Error(`Effect: Value at path '${r.path}' is not an array.`)}}fromArray(t){return(e,r)=>{let c=r.path?S(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)}}}fromPrimitive(t){return(e,r)=>{let c=a(r);return this._strategy.execute(e,t,c)}}fromSource(t,e){return(r,c)=>{let o=e(c.source);return this._strategy.execute(r,t,o)}}fromValue(t,e){return(r,c)=>this._strategy.execute(r,t,e)}sequence(t){return async(e,r)=>{let c=a(r);for(let o of t)await o(e,{value:c})}}sequenceWith(t,e){return async(c,o)=>{let s=a(o),n=e(s);for(let T of t)await T(c,{value:n})}}when(t,e,r=p){return(c,o)=>{let s=a(o);return(t(s)?e:r)(c,{value:s})}}whenFromSource(t,e,r=p){return(c,o)=>(t(o.source)?e:r)(c,o)}};function a(u){return u.source&&u.path?S(u.source,u.path):u.value}var f=class{constructor(t){this._schema=t;if(!t)throw new Error("Projector: Schema is required.")}project(t,...e){for(let r of e)this._dispatch(t,r)}_dispatch(t,e){let{path:r,value:c}=e,o=this._resolveEffect(r);o&&(this._ensureScheduler(),this._scheduler.enqueue({path:r.join("."),effect:o,ctx:{source:t,path:r,value:c}}))}_ensureScheduler(){if(!this._scheduler)throw new Error("Projector: no scheduler.")}_resolveEffect(t){let e=this._schema;for(let r of t){if(!e)return null;e=e[r]}return typeof e=="function"?e:null}},y=class extends f{constructor(t,e){super(t),this._scheduler=e}},_=class extends f{scheduleWith(t){return typeof t=="function"?this._schedulerFactory=t:this._scheduler=t,this}_ensureScheduler(){if(!this._scheduler&&this._schedulerFactory&&(this._scheduler=this._schedulerFactory()),!this._scheduler)throw new Error("Projector: no scheduler.")}};var h=class{constructor(t){this._target=t}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")}},g=class extends h{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,s=c(this._target,o);s instanceof Promise&&await s}}};function k(u){let t=new i(u);return[I(u,t.receive.bind(t),{pathAsArray:!0}),t]}export{g as BufferedScheduler,_ as DynamicProjector,d as EffectFactory,y as Projector,f as ProjectorBase,i as Recorder,h as Scheduler,k as track};
6
+ import b from"on-change";import{set as m}from"lodash-es";import{withEvents as I}from"@cyysummer/core";var T=class extends I(){constructor(e){super();this._paused=!1;this._shadow=structuredClone(e)}receive(e,r){if(this._paused)return;m(this._shadow,e,r);let o=[{path:e,value:r}];this.emit("record",{next:this._shadow,patches:o}),this._ensureProjector(),this._projector?.project(this._shadow,...o)}sendTo(e){typeof e=="function"?this._projectorFactory=e:this._projector=e}pause(){this._paused=!0}resume(){this._paused=!1}_ensureProjector(){!this._projector&&this._projectorFactory&&(this._projector=this._projectorFactory())}};import{get as l,keys as d}from"lodash-es";var y=s=>{},S=class{constructor(t){this._strategy=t}at(t){return(e,r)=>{let o=i(r);return this._strategy.execute(e,t,o)}}atWith(t,e){return(o,c)=>{let u=i(c),a=e(u);return this._strategy.execute(o,t,a)}}arrayAt(t,e){return(r,o)=>{let c=o.path?l(o.source,o.path):o.value;if(c&&Array.isArray(c)&&c.length>0){let u={keys:typeof c[0]=="object"?d(c[0]):[],resolveHeader:(a,n)=>String(a),...e};return this._strategy.executeArray(r,t,c,u)}}}arrayAtWith(t,e,r){return(o,c)=>{let u=c.path?l(c.source,c.path):c.value;if(u&&Array.isArray(u)&&u.length>0){let a=u.map(e),n={keys:typeof u[0]=="object"?d(u[0]):[],resolveHeader:(f,v)=>String(f),...r};return this._strategy.executeArray(o,t,a,n)}}}loop(t){return async(e,r)=>{let o=i(r);if(Array.isArray(o)){let c=o;for(let u=0;u<c.length;u++){let a=c[u],f=t(a,u)(e,{value:a});f instanceof Promise&&await f}}else throw new Error(`Effect: Value at path '${r.path}' is not an array.`)}}sourceWith(t,e){return(r,o)=>{let c=e(o.source);return this._strategy.execute(r,t,c)}}raw(t,e){return(r,o)=>this._strategy.execute(r,t,e)}sequence(t){return async(e,r)=>{let o=i(r);for(let c of t)await c(e,{value:o})}}sequenceWith(t,e){return async(o,c)=>{let u=i(c),a=e(u);for(let n of t)await n(o,{value:a})}}when(t,e,r=y){return(o,c)=>{let u=i(c);return(t(u)?e:r)(o,{value:u})}}whenFromSource(t,e,r=y){return(o,c)=>(t(c.source)?e:r)(o,c)}},i=s=>s.source&&s.path?l(s.source,s.path):s.value;var h=class{constructor(t){this._schema=t;if(!t)throw new Error("Projector: Schema is required.")}project(t,...e){for(let r of e)this._dispatch(t,r)}_dispatch(t,e){let{path:r,value:o}=e,c=this._resolveEffect(r);c&&(this._ensureScheduler(),this._scheduler.enqueue({path:r.join("."),effect:c,ctx:{source:t,path:r,value:o}}))}_ensureScheduler(){if(!this._scheduler)throw new Error("Projector: no scheduler.")}_resolveEffect(t){let e=this._schema;for(let r of t){if(!e)return null;e=e[r]}return typeof e=="function"?e:null}},_=class extends h{constructor(t,e){super(t),this._scheduler=e}},g=class extends h{scheduleWith(t){return typeof t=="function"?this._schedulerFactory=t:this._scheduler=t,this}_ensureScheduler(){if(!this._scheduler&&this._schedulerFactory&&(this._scheduler=this._schedulerFactory()),!this._scheduler)throw new Error("Projector: no scheduler.")}};var p=class{constructor(t){this._target=t}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")}},E=class extends p{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",[...this._queue.keys()]);let e=[...this._queue.values()];this._queue.clear();for(let r of e){let{effect:o,ctx:c}=r,u=o(this._target,c);u instanceof Promise&&await u}}};function k(s){let t=new T(s);return[b(s,t.receive.bind(t),{pathAsArray:!0}),t]}export{E as BufferedScheduler,g as DynamicProjector,S as EffectFactory,_ as Projector,h as ProjectorBase,T as Recorder,p as Scheduler,k as track};
7
7
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyysummer/projector",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
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
@@ -39,12 +39,27 @@ interface IEffectContext<TSource, TValue> {
39
39
  value: TValue;
40
40
  }
41
41
 
42
+ /**
43
+ * Options for execute array effect.
44
+ */
45
+ type ArrayEffectOptions = {
46
+ /**
47
+ * The keys of the objects in the array. Use this only when element of array is object.
48
+ */
49
+ keys: (string | symbol)[];
50
+
51
+ /**
52
+ * Function to generate header for each column.
53
+ */
54
+ resolveHeader: (key: string | symbol, index?: number) => string;
55
+ }
56
+
42
57
  /**
43
58
  * Strategy defines actual execution methods for projecting values to target.
44
59
  */
45
60
  interface ITargetExecutionStrategy<TTarget, TLocation = any> {
46
- execute<T>(target: TTarget, location: TLocation, value: T): MaybePromise<void>;
47
- executeArray<T>(target: TTarget, location: TLocation, keys: Partial<keyof T>[], rows: T[]): MaybePromise<void>;
61
+ execute<T extends any>(target: TTarget, location: TLocation, value: T): MaybePromise<void>;
62
+ executeArray<T extends any>(target: TTarget, location: TLocation, rows: T[], options: ArrayEffectOptions): MaybePromise<void>;
48
63
  }
49
64
 
50
65
  interface IProjector<TSource> {
@@ -114,40 +129,52 @@ declare class EffectFactory<TTarget, TSource extends object, TLocation = any> {
114
129
  protected _strategy: ITargetExecutionStrategy<TTarget, TLocation>;
115
130
  constructor(_strategy: ITargetExecutionStrategy<TTarget, TLocation>);
116
131
  /**
117
- * Create an effect that will applied at the specified location.
132
+ * Create an effect that will be applied at the specified location.
118
133
  * @param location The location in `TTarget` where the effect is executed.
119
134
  * @returns
120
135
  */
121
- create<T>(location: TLocation): Effect<TSource, T>;
136
+ at<T>(location: TLocation): Effect<TSource, T>;
122
137
  /**
123
- * Create an effect that will applied at the specified location. Use `mapper` to transform the source object.
138
+ * Create an effect that will be applied at the specified location. Use `mapper` to transform the value.
124
139
  * @param location The location in `TTarget` where the effect is executed.
125
- * @param mapper Function to transform the source object.
140
+ * @param mapper Function to transform the value.
126
141
  * @returns
127
142
  */
128
- createWith<T, R>(location: TLocation, mapper: Func1<T, R>): Effect<TSource, R>;
129
- forEach<T, U = T extends Array<infer K> ? K : never>(each: Func2<U, number, Effect<TSource, U>>): Effect<TSource, T>;
143
+ atWith<T, R>(location: TLocation, mapper: Func1<T, R>): Effect<TSource, R>;
130
144
  /**
131
- * Create an effect that will applied at the specified location for array data.
145
+ * Create an effect that will be applied at the specified location for array data.
132
146
  * @param location The location in `TTarget` where the effect is executed.
133
147
  * @returns
134
148
  */
135
- fromArray<T extends Array<U>, U extends object = any>(location: TLocation): Effect<TSource, T>;
136
- fromPrimitive<T>(location: TLocation): Effect<TSource, T>;
149
+ arrayAt<T, U = UnwrapArray<T>>(location: TLocation, options?: Partial<ArrayEffectOptions>): Effect<TSource, T>;
150
+ /**
151
+ * Create an effect that will be applied at the specified location for array data.
152
+ * @param location The location in `TTarget` where the effect is executed.
153
+ * @param mapper Function to transform the element of the array.
154
+ * @returns
155
+ */
156
+ arrayAtWith<T, U = UnwrapArray<T>, R = any>(location: TLocation, mapper: Func1<U, R>, options?: Partial<ArrayEffectOptions>): Effect<TSource, T>;
157
+ /**
158
+ *
159
+ * @param each
160
+ * @returns
161
+ * @experimental
162
+ */
163
+ loop<T, U = T extends Array<infer K> ? K : never>(each: Func2<U, number, Effect<TSource, U>>): Effect<TSource, T>;
137
164
  /**
138
- * Create an effect that will applied at the specified location. Use `mapper` to transform the source object.
165
+ * Create an effect that will be applied at the specified location for `TSource` object. Use `mapper` to transform the `TSource` object.
139
166
  * @param location The location in `TTarget` where the effect is executed.
140
- * @param mapper Function to transform the source object.
167
+ * @param mapper Function to transform the `TSource` object.
141
168
  * @returns
142
169
  */
143
- fromSource<T>(location: TLocation, mapper: Func1<TSource, string>): Effect<TSource, T>;
170
+ sourceWith<T>(location: TLocation, mapper: Func1<TSource, string>): Effect<TSource, T>;
144
171
  /**
145
- * Create an effect that will applied at the specified location for raw value. This effect will not read from source object.
172
+ * Create an effect that will be applied at the specified location for raw value. This effect will not read from `TSource` object.
146
173
  * @param location The location in `TTarget` where the effect is executed.
147
- * @param value The value to use.
174
+ * @param rawValue The value to use.
148
175
  * @returns
149
176
  */
150
- fromValue<T>(location: TLocation, value: T): Effect<TSource, T>;
177
+ raw<T>(location: TLocation, rawValue: T): Effect<TSource, T>;
151
178
  /**
152
179
  * Call multiple effects in sequence.
153
180
  * @param effects Effects to call.
@@ -155,23 +182,23 @@ declare class EffectFactory<TTarget, TSource extends object, TLocation = any> {
155
182
  */
156
183
  sequence<T>(effects: Effect<TSource, T>[]): Effect<TSource, T>;
157
184
  /**
158
- * Call multiple effects in sequence. Use `mapper` to transform the original value.
185
+ * Call multiple effects in sequence. Use `mapper` to transform the value.
159
186
  * @param effects Effects to call.
160
- * @param mapper Function to transform the original value.
187
+ * @param mapper Function to transform the value.
161
188
  * @returns
162
189
  */
163
190
  sequenceWith<T, R>(effects: Effect<TSource, R>[], mapper: Func1<T, R>): Effect<TSource, R>;
164
191
  /**
165
192
  * Execute effect based on condition. The condition is based on the value of the current property path.
166
- * @param condition Condition delegate that takes the original value of the property and returns true or false.
193
+ * @param condition Condition delegate that takes the value of the property and returns true or false.
167
194
  * @param ifTrue When condition is true, this effect is executed.
168
195
  * @param ifFalse When condition is false, this effect is executed.
169
196
  * @returns
170
197
  */
171
198
  when<T>(condition: Predicate<T>, ifTrue: Effect<TSource, any>, ifFalse?: Effect<TSource, any>): Effect<TSource, T>;
172
199
  /**
173
- * Execute effect based on condition. The condition is based on the source object.
174
- * @param condition Condition delegate that takes the source object and returns true or false.
200
+ * Execute effect based on condition. The condition is based on the `TSource` object.
201
+ * @param condition Condition delegate that takes the `TSource` object and returns true or false.
175
202
  * @param ifTrue When condition is true, this effect is executed.
176
203
  * @param ifFalse When condition is false, this effect is executed.
177
204
  * @returns
package/types/types.d.ts CHANGED
@@ -39,12 +39,27 @@ export interface IEffectContext<TSource, TValue> {
39
39
  value: TValue;
40
40
  }
41
41
 
42
+ /**
43
+ * Options for execute array effect.
44
+ */
45
+ export type ArrayEffectOptions = {
46
+ /**
47
+ * The keys of the objects in the array. Use this only when element of array is object.
48
+ */
49
+ keys: (string | symbol)[];
50
+
51
+ /**
52
+ * Function to generate header for each column.
53
+ */
54
+ resolveHeader: (key: string | symbol, index?: number) => string;
55
+ }
56
+
42
57
  /**
43
58
  * Strategy defines actual execution methods for projecting values to target.
44
59
  */
45
60
  export interface ITargetExecutionStrategy<TTarget, TLocation = any> {
46
- execute<T>(target: TTarget, location: TLocation, value: T): MaybePromise<void>;
47
- executeArray<T>(target: TTarget, location: TLocation, keys: Partial<keyof T>[], rows: T[]): MaybePromise<void>;
61
+ execute<T extends any>(target: TTarget, location: TLocation, value: T): MaybePromise<void>;
62
+ executeArray<T extends any>(target: TTarget, location: TLocation, rows: T[], options: ArrayEffectOptions): MaybePromise<void>;
48
63
  }
49
64
 
50
65
  export interface IProjector<TSource> {