@cyysummer/projector 0.0.5 → 0.0.7
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 +2 -2
- package/package.json +1 -1
- package/types/lib.d.ts +53 -53
- package/types/types.d.ts +12 -14
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @cyysummer/projector v0.0.
|
|
2
|
+
* @cyysummer/projector v0.0.7
|
|
3
3
|
* (c) 2021-PRESENT Chris Liu
|
|
4
4
|
* @license MIT
|
|
5
5
|
**/
|
|
6
|
-
import
|
|
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};
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
package/types/lib.d.ts
CHANGED
|
@@ -2,18 +2,16 @@
|
|
|
2
2
|
* A Schema defines how to project changes from a source object to a target object.
|
|
3
3
|
*/
|
|
4
4
|
// prettier-ignore
|
|
5
|
-
type Schema<TSource, T =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
T[K] extends
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// Else map T to effect.
|
|
16
|
-
: Effect<TSource, T>;
|
|
5
|
+
type Schema<TSource, T = TSource> = {
|
|
6
|
+
// If the property is an array, map to effect.
|
|
7
|
+
[K in keyof T]?: T[K] extends Array<infer U>
|
|
8
|
+
? Effect<TSource, U[]>
|
|
9
|
+
// Else, if the property is an object, map to schema or effect.
|
|
10
|
+
: T[K] extends object
|
|
11
|
+
? Schema<TSource, T[K]> | Effect<TSource, T[K]>
|
|
12
|
+
// Else, leaf property, map to effect.
|
|
13
|
+
: Effect<TSource, T[K]>;
|
|
14
|
+
};
|
|
17
15
|
|
|
18
16
|
/**
|
|
19
17
|
* An effect defines how to project a value from source to target.
|
|
@@ -45,8 +43,8 @@ interface IEffectContext<TSource, TValue> {
|
|
|
45
43
|
* Strategy defines actual execution methods for projecting values to target.
|
|
46
44
|
*/
|
|
47
45
|
interface ITargetExecutionStrategy<TTarget, TLocation = any> {
|
|
48
|
-
execute<T>(target: TTarget,
|
|
49
|
-
executeArray<T>(target: TTarget,
|
|
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>;
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
interface IProjector<TSource> {
|
|
@@ -112,71 +110,73 @@ declare class Recorder<TSource extends object> extends Recorder_base {
|
|
|
112
110
|
/**
|
|
113
111
|
* Build effects for a target.
|
|
114
112
|
*/
|
|
115
|
-
declare class
|
|
116
|
-
|
|
117
|
-
constructor(_strategy: ITargetExecutionStrategy<TTarget>);
|
|
113
|
+
declare class EffectFactory<TTarget, TSource extends object, TLocation = any> {
|
|
114
|
+
protected _strategy: ITargetExecutionStrategy<TTarget, TLocation>;
|
|
115
|
+
constructor(_strategy: ITargetExecutionStrategy<TTarget, TLocation>);
|
|
118
116
|
/**
|
|
119
|
-
*
|
|
120
|
-
* @param
|
|
117
|
+
* Create an effect that will applied at the specified location.
|
|
118
|
+
* @param location The location in `TTarget` where the effect is executed.
|
|
121
119
|
* @returns
|
|
122
120
|
*/
|
|
123
|
-
|
|
121
|
+
create<T>(location: TLocation): Effect<TSource, T>;
|
|
124
122
|
/**
|
|
125
|
-
*
|
|
126
|
-
* @param
|
|
127
|
-
* @param
|
|
123
|
+
* Create an effect that will applied at the specified location. Use `mapper` to transform the source object.
|
|
124
|
+
* @param location The location in `TTarget` where the effect is executed.
|
|
125
|
+
* @param mapper Function to transform the source object.
|
|
128
126
|
* @returns
|
|
129
127
|
*/
|
|
130
|
-
|
|
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>;
|
|
131
130
|
/**
|
|
132
|
-
* Create an effect
|
|
133
|
-
* @param
|
|
131
|
+
* Create an effect that will applied at the specified location for array data.
|
|
132
|
+
* @param location The location in `TTarget` where the effect is executed.
|
|
134
133
|
* @returns
|
|
135
134
|
*/
|
|
136
|
-
|
|
135
|
+
fromArray<T extends Array<U>, U extends object = any>(location: TLocation): Effect<TSource, T>;
|
|
136
|
+
fromPrimitive<T>(location: TLocation): Effect<TSource, T>;
|
|
137
137
|
/**
|
|
138
|
-
*
|
|
139
|
-
* @param
|
|
140
|
-
* @param
|
|
141
|
-
* @param whenFalse When condition is false, this effect is executed.
|
|
138
|
+
* Create an effect that will applied at the specified location. Use `mapper` to transform the source object.
|
|
139
|
+
* @param location The location in `TTarget` where the effect is executed.
|
|
140
|
+
* @param mapper Function to transform the source object.
|
|
142
141
|
* @returns
|
|
143
142
|
*/
|
|
144
|
-
|
|
143
|
+
fromSource<T>(location: TLocation, mapper: Func1<TSource, string>): Effect<TSource, T>;
|
|
145
144
|
/**
|
|
146
|
-
*
|
|
147
|
-
* @param
|
|
148
|
-
* @param
|
|
149
|
-
* @param whenFalse When condition is false, this effect is executed.
|
|
145
|
+
* Create an effect that will applied at the specified location for raw value. This effect will not read from source object.
|
|
146
|
+
* @param location The location in `TTarget` where the effect is executed.
|
|
147
|
+
* @param value The value to use.
|
|
150
148
|
* @returns
|
|
151
149
|
*/
|
|
152
|
-
|
|
150
|
+
fromValue<T>(location: TLocation, value: T): Effect<TSource, T>;
|
|
153
151
|
/**
|
|
154
|
-
*
|
|
155
|
-
* @param
|
|
156
|
-
* @param customizer Function to transform the source object.
|
|
152
|
+
* Call multiple effects in sequence.
|
|
153
|
+
* @param effects Effects to call.
|
|
157
154
|
* @returns
|
|
158
155
|
*/
|
|
159
|
-
|
|
156
|
+
sequence<T>(effects: Effect<TSource, T>[]): Effect<TSource, T>;
|
|
160
157
|
/**
|
|
161
|
-
*
|
|
162
|
-
* @param
|
|
158
|
+
* Call multiple effects in sequence. Use `mapper` to transform the original value.
|
|
159
|
+
* @param effects Effects to call.
|
|
160
|
+
* @param mapper Function to transform the original value.
|
|
163
161
|
* @returns
|
|
164
162
|
*/
|
|
165
|
-
|
|
163
|
+
sequenceWith<T, R>(effects: Effect<TSource, R>[], mapper: Func1<T, R>): Effect<TSource, R>;
|
|
166
164
|
/**
|
|
167
|
-
*
|
|
168
|
-
* @param
|
|
169
|
-
* @param
|
|
165
|
+
* 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.
|
|
167
|
+
* @param ifTrue When condition is true, this effect is executed.
|
|
168
|
+
* @param ifFalse When condition is false, this effect is executed.
|
|
170
169
|
* @returns
|
|
171
170
|
*/
|
|
172
|
-
|
|
171
|
+
when<T>(condition: Predicate<T>, ifTrue: Effect<TSource, any>, ifFalse?: Effect<TSource, any>): Effect<TSource, T>;
|
|
173
172
|
/**
|
|
174
|
-
*
|
|
175
|
-
* @param
|
|
176
|
-
* @param
|
|
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.
|
|
175
|
+
* @param ifTrue When condition is true, this effect is executed.
|
|
176
|
+
* @param ifFalse When condition is false, this effect is executed.
|
|
177
177
|
* @returns
|
|
178
178
|
*/
|
|
179
|
-
|
|
179
|
+
whenFromSource<T>(condition: Predicate<TSource>, ifTrue: Effect<TSource, any>, ifFalse?: Effect<TSource, any>): Effect<TSource, T>;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
declare abstract class ProjectorBase<TSource> implements IProjector<TSource> {
|
|
@@ -227,4 +227,4 @@ declare class BufferedScheduler<TTarget> extends Scheduler<TTarget> {
|
|
|
227
227
|
*/
|
|
228
228
|
declare function track<TSource extends object>(initial: TSource): [TSource, Recorder<TSource>];
|
|
229
229
|
|
|
230
|
-
export { BufferedScheduler, DynamicProjector,
|
|
230
|
+
export { BufferedScheduler, DynamicProjector, EffectFactory, Projector, ProjectorBase, Recorder, Scheduler, track };
|
package/types/types.d.ts
CHANGED
|
@@ -2,18 +2,16 @@
|
|
|
2
2
|
* A Schema defines how to project changes from a source object to a target object.
|
|
3
3
|
*/
|
|
4
4
|
// prettier-ignore
|
|
5
|
-
export type Schema<TSource, T =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
T[K] extends
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// Else map T to effect.
|
|
16
|
-
: Effect<TSource, T>;
|
|
5
|
+
export type Schema<TSource, T = TSource> = {
|
|
6
|
+
// If the property is an array, map to effect.
|
|
7
|
+
[K in keyof T]?: T[K] extends Array<infer U>
|
|
8
|
+
? Effect<TSource, U[]>
|
|
9
|
+
// Else, if the property is an object, map to schema or effect.
|
|
10
|
+
: T[K] extends object
|
|
11
|
+
? Schema<TSource, T[K]> | Effect<TSource, T[K]>
|
|
12
|
+
// Else, leaf property, map to effect.
|
|
13
|
+
: Effect<TSource, T[K]>;
|
|
14
|
+
};
|
|
17
15
|
|
|
18
16
|
/**
|
|
19
17
|
* An effect defines how to project a value from source to target.
|
|
@@ -45,8 +43,8 @@ export interface IEffectContext<TSource, TValue> {
|
|
|
45
43
|
* Strategy defines actual execution methods for projecting values to target.
|
|
46
44
|
*/
|
|
47
45
|
export interface ITargetExecutionStrategy<TTarget, TLocation = any> {
|
|
48
|
-
execute<T>(target: TTarget,
|
|
49
|
-
executeArray<T>(target: TTarget,
|
|
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>;
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
export interface IProjector<TSource> {
|