@cyysummer/projector 0.0.4 → 0.0.6

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.4
2
+ * @cyysummer/projector v0.0.6
3
3
  * (c) 2021-PRESENT Chris Liu
4
4
  * @license MIT
5
5
  **/
6
- import _ from"on-change";import{set as d}from"lodash-es";import{withEvents as g}from"@cyysummer/core";var i=class extends g(){constructor(e){super();this._paused=!1;this._shadow=structuredClone(e)}receive(e,r){if(this._paused)return;d(this._shadow,e,r);let c=[{path:e,value:r}];this.emit("record",{next:this._shadow,patches:c}),this._checkProjector(),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}_checkProjector(){!this._projector&&this._projectorFactory&&(this._projector=this._projectorFactory())}};import{get as l}from"lodash-es";var h=a=>{},p=class{constructor(t){this._strategy=t}chain(t){return async(e,r)=>{let c=n(r);for(let o of t)await o(e,{value:c})}}chainWith(t,e){return async(c,o)=>{let u=n(o),s=e(u);for(let f of t)await f(c,{value:s})}}create(t){return(e,r)=>{let c=n(r);return this._strategy.execute(e,t,c)}}createIf(t,e,r=h){return(c,o)=>{let u=n(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?l(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=n(o),s=e(u);return this._strategy.execute(c,t,s)}}};function n(a){return a.source&&a.path?l(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 T=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")}},S=class extends T{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 i(a);return[_(a,t.receive.bind(t),{pathAsArray:!0}),t]}export{S as BufferedScheduler,p as EffectBuilder,y as Projector,i as Recorder,T as Scheduler,F as track};
6
+ import m from"on-change";import{set as g}from"lodash-es";import{withEvents as I}from"@cyysummer/core";var i=class extends I(){constructor(e){super();this._paused=!1;this._shadow=structuredClone(e)}receive(e,r){if(this._paused)return;g(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 d}from"lodash-es";var l=u=>{},p=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(e,r)=>{}}fromArray(t){return(e,r)=>{let c=r.path?d(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)}}}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 h of t)await h(c,{value:n})}}when(t,e,r=l){return(c,o)=>{let s=a(o);return(t(s)?e:r)(c,{value:s})}}whenFromSource(t,e,r=l){return(c,o)=>(t(o.source)?e:r)(c,o)}};function a(u){return u.source&&u.path?d(u.source,u.path):u.value}var T=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}},S=class extends T{constructor(t,e){super(t),this._scheduler=e}},y=class extends T{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 f=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")}},_=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,s=c(this._target,o);s instanceof Promise&&await s}}};function R(u){let t=new i(u);return[m(u,t.receive.bind(t),{pathAsArray:!0}),t]}export{_ as BufferedScheduler,y as DynamicProjector,p as EffectFactory,S as Projector,T as ProjectorBase,i as Recorder,f as Scheduler,R 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.4",
3
+ "version": "0.0.6",
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
@@ -45,8 +45,8 @@ interface IEffectContext<TSource, TValue> {
45
45
  * Strategy defines actual execution methods for projecting values to target.
46
46
  */
47
47
  interface ITargetExecutionStrategy<TTarget, TLocation = any> {
48
- execute<T>(target: TTarget, at: TLocation, value: T): MaybePromise<void>;
49
- executeArray<T>(target: TTarget, at: TLocation, keys: Partial<keyof T>[], rows: T[]): MaybePromise<void>;
48
+ execute<T>(target: TTarget, location: TLocation, value: T): MaybePromise<void>;
49
+ executeArray<T>(target: TTarget, location: TLocation, keys: Partial<keyof T>[], rows: T[]): MaybePromise<void>;
50
50
  }
51
51
 
52
52
  interface IProjector<TSource> {
@@ -106,86 +106,97 @@ declare class Recorder<TSource extends object> extends Recorder_base {
106
106
  sendTo(factory: Func<IProjector<TSource>>): void;
107
107
  pause(): void;
108
108
  resume(): void;
109
- private _checkProjector;
109
+ private _ensureProjector;
110
110
  }
111
111
 
112
112
  /**
113
113
  * Build effects for a target.
114
114
  */
115
- declare class EffectBuilder<TTarget, TSource extends object> {
116
- private _strategy;
117
- constructor(_strategy: ITargetExecutionStrategy<TTarget>);
115
+ declare class EffectFactory<TTarget, TSource extends object, TLocation = any> {
116
+ protected _strategy: ITargetExecutionStrategy<TTarget, TLocation>;
117
+ constructor(_strategy: ITargetExecutionStrategy<TTarget, TLocation>);
118
118
  /**
119
- * Call multiple effects in sequence.
120
- * @param effects Effects to call.
119
+ * Create an effect that will applied at the specified location.
120
+ * @param location The location in `TTarget` where the effect is executed.
121
121
  * @returns
122
122
  */
123
- chain<T>(effects: Effect<TSource, T>[]): Effect<TSource, T>;
123
+ create<T>(location: TLocation): Effect<TSource, T>;
124
124
  /**
125
- * Call multiple effects in sequence. Use `customizer` to transform the original value.
126
- * @param effects Effects to call.
127
- * @param customizer Function to transform the original value.
125
+ * Create an effect that will applied at the specified location. Use `mapper` to transform the source object.
126
+ * @param location The location in `TTarget` where the effect is executed.
127
+ * @param mapper Function to transform the source object.
128
128
  * @returns
129
129
  */
130
- chainWith<T, R>(effects: Effect<TSource, R>[], customizer: Func1<T, R>): Effect<TSource, R>;
130
+ createWith<T, R>(location: TLocation, mapper: Func1<T, R>): Effect<TSource, R>;
131
+ forEach<T extends Array<U>, U extends object = any>(location: Func1<number, TLocation>): Effect<TSource, any>;
131
132
  /**
132
- * Create an effect for the specified location.
133
- * @param at The location in `TTarget` where the effect is to be executed.
133
+ * Create an effect that will applied at the specified location for array data.
134
+ * @param location The location in `TTarget` where the effect is executed.
134
135
  * @returns
135
136
  */
136
- create<T>(at: string): Effect<TSource, T>;
137
+ fromArray<T extends Array<U>, U extends object = any>(location: TLocation): Effect<TSource, T>;
137
138
  /**
138
- * Execute effect based on condition. The condition is based on the value of the current property path.
139
- * @param condition Condition delegate that takes the original value of the property and returns true or false.
140
- * @param whenTrue When condition is true, this effect is executed.
141
- * @param whenFalse When condition is false, this effect is executed.
139
+ * Create an effect that will applied at the specified location. Use `mapper` to transform the source object.
140
+ * @param location The location in `TTarget` where the effect is executed.
141
+ * @param mapper Function to transform the source object.
142
142
  * @returns
143
143
  */
144
- createIf<T>(condition: Predicate<T>, whenTrue: Effect<TSource, any>, whenFalse?: Effect<TSource, any>): Effect<TSource, T>;
144
+ fromSource<T>(location: TLocation, mapper: Func1<TSource, string>): Effect<TSource, T>;
145
145
  /**
146
- * Execute effect based on condition. The condition is based on the source object.
147
- * @param condition Condition delegate that takes the source object and returns true or false.
148
- * @param whenTrue When condition is true, this effect is executed.
149
- * @param whenFalse When condition is false, this effect is executed.
146
+ * Create an effect that will applied at the specified location for raw value. This effect will not read from source object.
147
+ * @param location The location in `TTarget` where the effect is executed.
148
+ * @param value The value to use.
150
149
  * @returns
151
150
  */
152
- createIfRoot<T>(condition: Predicate<TSource>, whenTrue: Effect<TSource, any>, whenFalse?: Effect<TSource, any>): Effect<TSource, T>;
151
+ fromValue<T>(location: TLocation, value: T): Effect<TSource, T>;
153
152
  /**
154
- * Create an effect for the specified location. Use customizer to transform the source object.
155
- * @param at The location in `TTarget` where the effect is to be executed.
156
- * @param customizer Function to transform the source object.
153
+ * Call multiple effects in sequence.
154
+ * @param effects Effects to call.
157
155
  * @returns
158
156
  */
159
- createRoot<T>(at: string, customizer: Func1<TSource, string>): Effect<TSource, T>;
157
+ sequence<T>(effects: Effect<TSource, T>[]): Effect<TSource, T>;
160
158
  /**
161
- * Create an effect for the specified location for array data.
162
- * @param at The location in `TTarget` where the effect is to be executed.
159
+ * Call multiple effects in sequence. Use `mapper` to transform the original value.
160
+ * @param effects Effects to call.
161
+ * @param mapper Function to transform the original value.
163
162
  * @returns
164
163
  */
165
- createForArray<T extends Array<U>, U extends object = any>(at: string): Effect<TSource, T>;
164
+ sequenceWith<T, R>(effects: Effect<TSource, R>[], mapper: Func1<T, R>): Effect<TSource, R>;
166
165
  /**
167
- * Create an effect for the specified location for raw value. This will not read from source object.
168
- * @param at The location in `TTarget` where the effect is to be executed.
169
- * @param raw Raw value to use.
166
+ * Execute effect based on condition. The condition is based on the value of the current property path.
167
+ * @param condition Condition delegate that takes the original value of the property and returns true or false.
168
+ * @param ifTrue When condition is true, this effect is executed.
169
+ * @param ifFalse When condition is false, this effect is executed.
170
170
  * @returns
171
171
  */
172
- createForRaw<T>(at: string, raw: T): Effect<TSource, T>;
172
+ when<T>(condition: Predicate<T>, ifTrue: Effect<TSource, any>, ifFalse?: Effect<TSource, any>): Effect<TSource, T>;
173
173
  /**
174
- * Create an effect for the specified location. Use `customizer` to transform the source object.
175
- * @param at The location in `TTarget` where the effect is to be executed.
176
- * @param customizer Function to transform the source object.
174
+ * Execute effect based on condition. The condition is based on the source object.
175
+ * @param condition Condition delegate that takes the source object and returns true or false.
176
+ * @param ifTrue When condition is true, this effect is executed.
177
+ * @param ifFalse When condition is false, this effect is executed.
177
178
  * @returns
178
179
  */
179
- createWith<T, R>(at: string, customizer: Func1<T, R>): Effect<TSource, R>;
180
+ whenFromSource<T>(condition: Predicate<TSource>, ifTrue: Effect<TSource, any>, ifFalse?: Effect<TSource, any>): Effect<TSource, T>;
180
181
  }
181
182
 
182
- declare class Projector<TSource> implements IProjector<TSource> {
183
- private _schema;
184
- private _scheduler;
185
- constructor(_schema: Schema<TSource>, _scheduler: IScheduler<any>);
183
+ declare abstract class ProjectorBase<TSource> implements IProjector<TSource> {
184
+ protected _schema: Schema<TSource>;
185
+ protected _scheduler?: IScheduler<any>;
186
+ constructor(_schema: Schema<TSource>);
186
187
  project(next: TSource, ...patches: Patch[]): void;
187
- private _dispatch;
188
- private _resolveEffect;
188
+ protected _dispatch(next: TSource, patch: Patch): void;
189
+ protected _ensureScheduler(): void;
190
+ protected _resolveEffect(path: (string | symbol)[]): Effect<TSource, any> | null;
191
+ }
192
+ declare class Projector<TSource> extends ProjectorBase<TSource> {
193
+ constructor(_schema: Schema<TSource>, _scheduler: IScheduler<any>);
194
+ }
195
+ declare class DynamicProjector<TSource> extends ProjectorBase<TSource> {
196
+ private _schedulerFactory?;
197
+ scheduleWith(scheduler: IScheduler<any>): IProjector<TSource>;
198
+ scheduleWith(schedulerFactory: Func<IScheduler<any>>): IProjector<TSource>;
199
+ protected _ensureScheduler(): void;
189
200
  }
190
201
 
191
202
  /**
@@ -217,4 +228,4 @@ declare class BufferedScheduler<TTarget> extends Scheduler<TTarget> {
217
228
  */
218
229
  declare function track<TSource extends object>(initial: TSource): [TSource, Recorder<TSource>];
219
230
 
220
- export { BufferedScheduler, EffectBuilder, Projector, Recorder, Scheduler, track };
231
+ export { BufferedScheduler, DynamicProjector, EffectFactory, Projector, ProjectorBase, Recorder, Scheduler, track };
package/types/types.d.ts CHANGED
@@ -45,8 +45,8 @@ export interface IEffectContext<TSource, TValue> {
45
45
  * Strategy defines actual execution methods for projecting values to target.
46
46
  */
47
47
  export interface ITargetExecutionStrategy<TTarget, TLocation = any> {
48
- execute<T>(target: TTarget, at: TLocation, value: T): MaybePromise<void>;
49
- executeArray<T>(target: TTarget, at: TLocation, keys: Partial<keyof T>[], rows: T[]): MaybePromise<void>;
48
+ execute<T>(target: TTarget, location: TLocation, value: T): MaybePromise<void>;
49
+ executeArray<T>(target: TTarget, location: TLocation, keys: Partial<keyof T>[], rows: T[]): MaybePromise<void>;
50
50
  }
51
51
 
52
52
  export interface IProjector<TSource> {