@cyysummer/projector 0.0.10 → 0.0.12

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/README.md CHANGED
@@ -1,3 +1,51 @@
1
1
  # Structural Data Projector
2
2
 
3
3
  结构化对象映射引擎
4
+
5
+ ## Usage
6
+
7
+ ### Common
8
+
9
+
10
+ ```typescript
11
+ interface IMyData {
12
+ }
13
+
14
+ const schema: Schema<IMyData> = {
15
+ };
16
+
17
+ class OutputTarget {
18
+ }
19
+
20
+ type TargetLocation = string;
21
+
22
+ const strategy = new DemoStrategy(container);
23
+ ```
24
+
25
+ ### Svelte 5 with runes
26
+
27
+ ```typescript
28
+ let initialState: IMyData = $state({});
29
+ const builder = new Builder<IMyData, OutputTarget, TargetLocation>(initialState, schema)
30
+ .onFlush(() => {
31
+ // Do something when scheduler flushed. For example, update UI.
32
+ })
33
+ .withStrategy(strategy);
34
+ const { tracked } = builder.buildStatic();
35
+ let formData: IMyData = $derived(tracked);
36
+ // bind `formData` to UI.
37
+ ```
38
+
39
+ ### Vue
40
+
41
+ ```typescript
42
+ const initialState: IMyData = {};
43
+ const builder = new Builder<IMyData, OutputTarget, TargetLocation>(initialState, schema)
44
+ .onFlush(() => {
45
+ // Do something when scheduler flushed. For example, update UI.
46
+ })
47
+ .withStrategy(strategy);
48
+ const { tracked } = builder.buildStatic();
49
+ const formData: IMyData = reactive(tracked);
50
+ // bind `formData` to UI.
51
+ ```
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * @cyysummer/projector v0.0.10
2
+ * @cyysummer/projector v0.0.12
3
3
  * (c) 2021-PRESENT Chris Liu
4
4
  * @license MIT
5
5
  **/
6
- import L from"on-change";import{cloneDeep as x,set as w}from"lodash-es";import{withEvents as v}from"@cyysummer/core";var i=class extends v(){constructor(t){super();this._paused=!1;this._shadow=x(t)}receive(t,r){if(this._paused)return;w(this._shadow,t,r);let o=[{path:t,value:r}];this.emit("record",{next:this._shadow,patches:o}),this._ensureProjector(),this._projector?.project(this._shadow,...o)}sendTo(t){typeof t=="function"?this._projectorFactory=t:this._projector=t}pause(){this._paused=!0}resume(){this._paused=!1}_ensureProjector(){!this._projector&&this._projectorFactory&&(this._projector=this._projectorFactory())}};import F from"on-change";var l=class{constructor(e,t){this._schema=e;this._scheduler=t;if(!e)throw new Error("Projector: Schema is required.")}project(e,...t){for(let r of t)this._dispatch(e,r)}_dispatch(e,t){let{path:r,value:o}=t,c=this._resolveEffect(r);c&&(this._ensureScheduler(),this._scheduler.enqueue({path:r.join("."),effect:c,ctx:{source:e,path:r,value:o}}))}_ensureScheduler(){if(!this._scheduler)throw new Error("Projector: no scheduler.")}_resolveEffect(e){let t=this._schema;for(let r of e){if(!t)return null;t=t[r]}return typeof t=="function"?t:null}},f=class extends l{constructor(e,t){super(e,t)}},y=class extends l{withScheduler(e){return typeof e=="function"?this._schedulerFactory=e:this._scheduler=e,this}_ensureScheduler(){if(!this._scheduler&&this._schedulerFactory&&(this._scheduler=this._schedulerFactory()),!this._scheduler)throw new Error("Projector: no scheduler.")}};import{debounce as b}from"lodash-es";var d=class{constructor(e){this._strategy=e;this._queue=new Map}enqueue(e){return this._queue.set(e.path,e),this}flush(){return this.checkStrategy(),log.trace("Scheduler.flush()",[...this._queue.keys()]),this.flushCore()}withStrategy(e){return typeof e=="function"?this._strategyFactory=e:this._strategy=e,this}checkStrategy(){if(!this._strategy&&this._strategyFactory&&(this._strategy=this._strategyFactory()),!this._strategy)throw new Error("Scheduler: no strategy.")}async run(e){for(let t of e){let{effect:r,ctx:o}=t,c=r(this._strategy,o);c instanceof Promise&&await c}}},p=class extends d{constructor(t,r=500){super(t);this.wait=r;this.flushCore=b(async()=>{let t=[...this._queue.values()];this._queue.clear(),this.run(t)},this.wait)}},S=class extends d{async flushCore(){this._strategy.reset(),this.run([...this._queue.values()])}};import{debounce as j}from"lodash-es";var _=class{constructor(e,t){this._initial=e;this._schema=t;this._flushWait=0}buildDynamic(){this.track();let e=new y(this._schema);return this._scheduler&&e.withScheduler(this._scheduler),this._recorder.sendTo(e),{tracked:this._tracked,recorder:this._recorder,projector:e,scheduler:this._scheduler}}buildStatic(){if(!this._scheduler)throw new Error("Builder: no scheduler was provided. Call `withLazyScheduler()` or `withTotalScheduler()` to provide.");if(!this._strategy&&!this._strategyFactory)throw new Error("Builder: no strategy was provided. Call `withStrategy()` to provide.");if(!this._onFlush)throw new Error("Builder: no flush handler was provided. Call `onFlush()` to provide.");let e=async()=>{await this._scheduler.flush(),this._onFlush()};this.track(),this._scheduler.withStrategy(this._strategy??this._strategyFactory);let t=new f(this._schema,this._scheduler);return this._recorder.sendTo(t),this._recorder.on("record",this._flushWait?j(e,this._flushWait):e),{tracked:this._tracked,recorder:this._recorder,scheduler:this._scheduler}}onFlush(e,t=500){return this._onFlush=e,this._flushWait=t,this}withLazyScheduler(e=500){return this._scheduler=new p(void 0,e),this}withTotalScheduler(){return this._scheduler=new S,this}withStrategy(e){return typeof e=="function"?this._strategyFactory=e:this._strategy=e,this}track(){this._recorder&&this._tracked||(this._recorder=new i(this._initial),this._tracked=F(this._initial,(e,t)=>this._recorder.receive(e,t),{pathAsArray:!0}))}};import{get as g,keys as E}from"lodash-es";var m=u=>{},I=class{at(e){return(t,r)=>{let o=h(r);return t.execute(e,o)}}atWith(e,t){return(o,c)=>{let a=h(c),s=t(a);return o.execute(e,s)}}arrayAt(e,t){return(r,o)=>{let c=o.path?g(o.source,o.path):o.value;if(c&&Array.isArray(c)&&c.length>0){let a={keys:typeof c[0]=="object"?E(c[0]):[],resolveHeader:(s,n)=>String(s),...t};return r.executeArray(e,c,a)}}}arrayAtWith(e,t,r){return(o,c)=>{let a=c.path?g(c.source,c.path):c.value;if(a&&Array.isArray(a)&&a.length>0){let s=a.map(t),n={keys:typeof a[0]=="object"?E(a[0]):[],resolveHeader:(T,P)=>String(T),...r};return o.executeArray(e,s,n)}}}loop(e){return async(t,r)=>{let o=h(r);if(Array.isArray(o)){let c=o;for(let a=0;a<c.length;a++){let s=c[a],T=e(s,a)(t,{value:s});T instanceof Promise&&await T}}else throw new Error(`Effect: Value at path '${r.path}' is not an array.`)}}sourceWith(e,t){return(r,o)=>{let c=t(o.source);return r.execute(e,c)}}raw(e,t){return(r,o)=>r.execute(e,t)}sequence(e){return async(t,r)=>{let o=h(r);for(let c of e)await c(t,{value:o})}}sequenceWith(e,t){return async(o,c)=>{let a=h(c),s=t(a);for(let n of e)await n(o,{value:s})}}when(e,t,r=m){return(o,c)=>{let a=h(c);return(e(a)?t:r)(o,{value:a})}}whenFromSource(e,t,r=m){return(o,c)=>(e(c.source)?t:r)(o,c)}},h=u=>u.source&&u.path?g(u.source,u.path):u.value;function G(u){let e=new i(u);return[L(u,(r,o)=>e.receive(r,o),{pathAsArray:!0}),e]}export{_ as Builder,y as DynamicProjector,I as EffectFactory,p as LazyScheduler,f as Projector,l as ProjectorBase,i as Recorder,d as Scheduler,S as TotalScheduler,G as track};
6
+ import"on-change";var l=class{constructor(e,t){this._schema=e;this._scheduler=t;if(!e)throw new Error("Projector: Schema is required.")}project(e,...t){for(let r of t)this._dispatch(e,r)}_dispatch(e,t){let{path:r,value:c}=t,o=this._resolveEffect(r);o&&(this._ensureScheduler(),this._scheduler.enqueue({path:r.join("."),effect:o,ctx:{source:e,path:r,value:c}}))}_ensureScheduler(){if(!this._scheduler)throw new Error("Projector: no scheduler.")}_resolveEffect(e){let t=this._schema;for(let r of e){if(!t)return null;t=t[r]}return typeof t=="function"?t:null}},f=class extends l{constructor(e,t){super(e,t)}},d=class extends l{withScheduler(e){return typeof e=="function"?this._schedulerFactory=e:this._scheduler=e,this}_ensureScheduler(){if(!this._scheduler&&this._schedulerFactory&&(this._scheduler=this._schedulerFactory()),!this._scheduler)throw new Error("Projector: no scheduler.")}};import{cloneDeep as F,debounce as j,set as E}from"lodash-es";import{withEvents as L}from"@cyysummer/core";var p=class extends L(){constructor(t){super();this._paused=!1;this._shadow=F(t)}sendTo(t){this._projectorFactory=typeof t=="function"?t:()=>t}pause(){this._paused=!0}resume(){this._paused=!1}},y=class extends p{receive(e,t){if(this._paused)return;E(this._shadow,e,t);let r=[{path:e,value:t}];this._projectorFactory?.()?.project(this._shadow,...r),this.emit("record",{next:this._shadow,patches:r})}},S=class extends p{constructor(t,r=500){super(t);this._wait=r;this._buffer=new Map;this.receiveCore=j(()=>{let t=[...this._buffer.values()];log.trace("LazyRecorder.receiveCore,",t),this._buffer.clear();for(let r of t)E(this._shadow,r.path,r.value);this._projectorFactory?.()?.project(this._shadow,...t),this.emit("record",{next:this._shadow,patches:t})},this._wait,{trailing:!0})}receive(t,r){this._paused||(this._buffer.set(t.join("."),{path:t,value:r}),this.receiveCore())}};import{debounce as P}from"lodash-es";var g=class{constructor(e){this._queue=new Map;e&&(this._strategyFactory=()=>e)}enqueue(e){return this._queue.set(e.path,e),this}flush(){return log.trace("Scheduler.flush()",[...this._queue.keys()]),this.flushCore()}reset(){this._queue.clear()}withStrategy(e){return this._strategyFactory=typeof e=="function"?e:()=>e,this}ensureStrategy(){let e=this._strategyFactory?.();if(!e)throw new Error("Scheduler: no strategy.");return e}async run(e){for(let t of e){let{effect:r,ctx:c}=t,o=r(this.ensureStrategy(),c);o instanceof Promise&&await o}}},T=class extends g{constructor(t,r=500){super(t);this.wait=r;this.flushCore=P(async()=>{let t=[...this._queue.values()];this._queue.clear(),this.run(t)},this.wait)}},_=class extends g{async flushCore(){this.ensureStrategy().reset(),this.run([...this._queue.values()])}};import{debounce as k}from"lodash-es";import C from"on-change";function I(a,e=500){let t=e>0?new S(a,e):new y(a);return[C(a,(c,o)=>t.receive(c,o),{pathAsArray:!0}),t]}var b=class{constructor(e,t,r=500){this._initial=e;this._schema=t;this._waitTime=r;if(!e||!t||!r)throw new Error("Builder: all params are required.");if(Number(r)<0)throw new Error("Builder: wait time must be >= 0.")}buildDynamic(){this.track();let e=new d(this._schema);return this._scheduler&&e.withScheduler(this._scheduler),this._recorder.sendTo(e),{tracked:this._tracked,recorder:this._recorder,projector:e,scheduler:this._scheduler}}build(){if(!this._strategyFactory)throw new Error("Builder: no strategy was provided. Call `withStrategy()` to provide.");this._scheduler||(this._scheduler=new T),this._flushCallback||log.warn("Builder: no flush callback was provided.");let e=async()=>{await this._scheduler.flush(),this._flushCallback?.()};this.track(),this._scheduler.withStrategy(this._strategyFactory);let t=new f(this._schema,this._scheduler);return this._recorder.sendTo(t),this._recorder.on("record",this._waitTime?k(e,this._waitTime):e),{tracked:this._tracked,recorder:this._recorder,scheduler:this._scheduler}}onFlush(e){return this._flushCallback=e,this}withLazyScheduler(){return this._scheduler=new T(void 0,this._waitTime),this}withTotalScheduler(){return this._scheduler=new _,this}withStrategy(e){return this._strategyFactory=typeof e=="function"?e:()=>e,this}track(){this._recorder&&this._tracked||([this._tracked,this._recorder]=I(this._initial,this._waitTime))}};import{get as m,keys as w}from"lodash-es";var x=a=>{},v=class{at(e){return(t,r)=>{let c=i(r);return t.execute(e,c)}}atWith(e,t){return(c,o)=>{let u=i(o),n=t(u);return c.execute(e,n)}}arrayAt(e,t){return(r,c)=>{let o=c.path?m(c.source,c.path):c.value;if(o&&Array.isArray(o)&&o.length>0){let u={keys:typeof o[0]=="object"?w(o[0]):[],resolveHeader:(n,s)=>String(n),...t};return r.executeArray(e,o,u)}}}arrayAtWith(e,t,r){return(c,o)=>{let u=o.path?m(o.source,o.path):o.value;if(u&&Array.isArray(u)&&u.length>0){let n=u.map(t),s={keys:typeof u[0]=="object"?w(u[0]):[],resolveHeader:(h,R)=>String(h),...r};return c.executeArray(e,n,s)}}}loop(e){return async(t,r)=>{let c=i(r);if(Array.isArray(c)){let o=c;for(let u=0;u<o.length;u++){let n=o[u],h=e(n,u)(t,{value:n});h instanceof Promise&&await h}}else throw new Error(`Effect: Value at path '${r.path}' is not an array.`)}}sourceWith(e,t){return(r,c)=>{let o=t(c.source);return r.execute(e,o)}}raw(e,t){return(r,c)=>r.execute(e,t)}sequence(e){return async(t,r)=>{let c=i(r);for(let o of e)await o(t,{value:c})}}sequenceWith(e,t){return async(c,o)=>{let u=i(o),n=t(u);for(let s of e)await s(c,{value:n})}}when(e,t,r=x){return(c,o)=>{let u=i(o);return(e(u)?t:r)(c,{value:u})}}whenFromSource(e,t,r=x){return(c,o)=>(e(o.source)?t:r)(c,o)}},i=a=>a.source&&a.path?m(a.source,a.path):a.value;export{b as Builder,d as DynamicProjector,v as EffectFactory,S as LazyRecorder,T as LazyScheduler,f as Projector,l as ProjectorBase,y as Recorder,p as RecorderBase,g as Scheduler,_ as TotalScheduler,I 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.10",
3
+ "version": "0.0.12",
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
@@ -56,6 +56,19 @@ type ArrayEffectOptions = {
56
56
  resolveHeader: (key: string | symbol, index?: number) => string;
57
57
  }
58
58
 
59
+
60
+ type RecorderEvents = {
61
+ record: { next: any; patches: Patch[]; };
62
+ };
63
+
64
+ interface IRecorder<TSource extends object> extends IEventful<RecorderEvents> {
65
+ pause(): void;
66
+ receive(path: any[], value: any): void;
67
+ resume(): void;
68
+ sendTo(projector: IProjector<TSource>): void;
69
+ sendTo(factory: Func<IProjector<TSource>>): void;
70
+ }
71
+
59
72
  /**
60
73
  * Strategy defines actual execution methods for projecting values to target.
61
74
  */
@@ -63,6 +76,7 @@ interface ITargetExecutionStrategy<TTarget, TLocation> {
63
76
  execute<T extends any>(location: TLocation, value: T): MaybePromise<void>;
64
77
  executeArray<T extends any>(location: TLocation, rows: T[], options: ArrayEffectOptions): MaybePromise<void>;
65
78
  reset(): void;
79
+ get target(): TTarget;
66
80
  }
67
81
 
68
82
  interface IProjector<TSource> {
@@ -72,6 +86,7 @@ interface IProjector<TSource> {
72
86
  interface IScheduler<TTarget> {
73
87
  enqueue(effect: IScheduleItem): void;
74
88
  flush(): MaybePromise<void>;
89
+ reset(): void;
75
90
  withStrategy(strategy: ITargetExecutionStrategy<TTarget, any>): IScheduler<TTarget>;
76
91
  withStrategy(factory: Func<ITargetExecutionStrategy<TTarget, any>>): IScheduler<TTarget>;
77
92
  }
@@ -87,44 +102,6 @@ interface Patch {
87
102
  value: any;
88
103
  }
89
104
 
90
- type RecorderEvents = {
91
- record: {
92
- next: any;
93
- patches: Patch[];
94
- };
95
- };
96
- declare const Recorder_base: Constructor<object> & (new (...args: any[]) => object & IEventful<RecorderEvents>);
97
- /**
98
- * Record changes to an object.
99
- */
100
- declare class Recorder<TSource extends object> extends Recorder_base {
101
- private _paused;
102
- private _projector?;
103
- private _projectorFactory?;
104
- private _shadow;
105
- constructor(initial: TSource);
106
- /**
107
- * Receive changes from the tracked object.
108
- * @param path
109
- * @param value
110
- * @returns
111
- */
112
- receive(path: any[], value: any): void;
113
- /**
114
- * Send changes to a projector.
115
- * @param projector
116
- */
117
- sendTo(projector: IProjector<TSource>): void;
118
- /**
119
- * Send changes to a projector.
120
- * @param factory
121
- */
122
- sendTo(factory: Func<IProjector<TSource>>): void;
123
- pause(): void;
124
- resume(): void;
125
- private _ensureProjector;
126
- }
127
-
128
105
  declare abstract class ProjectorBase<TSource> implements IProjector<TSource> {
129
106
  protected _schema: Schema<TSource>;
130
107
  protected _scheduler?: IScheduler<any> | undefined;
@@ -147,27 +124,31 @@ declare class DynamicProjector<TSource> extends ProjectorBase<TSource> {
147
124
  declare class Builder<TSource extends object, TTarget, TLocation> {
148
125
  private _initial;
149
126
  private _schema;
150
- private _flushWait;
151
- private _onFlush?;
127
+ private _waitTime;
128
+ private _flushCallback?;
152
129
  private _recorder?;
153
130
  private _scheduler?;
154
- private _strategy?;
155
131
  private _strategyFactory?;
156
132
  private _tracked?;
157
- constructor(_initial: TSource, _schema: Schema<TSource>);
133
+ constructor(_initial: TSource, _schema: Schema<TSource>, _waitTime?: number);
158
134
  buildDynamic(): {
159
135
  tracked: TSource;
160
- recorder: Recorder<TSource>;
136
+ recorder: IRecorder<TSource>;
161
137
  projector: DynamicProjector<TSource>;
162
138
  scheduler: IScheduler<TTarget> | undefined;
163
139
  };
164
- buildStatic(): {
140
+ build(): {
165
141
  tracked: TSource;
166
- recorder: Recorder<TSource>;
142
+ recorder: IRecorder<TSource>;
167
143
  scheduler: IScheduler<TTarget>;
168
144
  };
169
- onFlush(callback: Action, wait?: number): Builder<TSource, TTarget, TLocation>;
170
- withLazyScheduler(wait?: number): Builder<TSource, TTarget, TLocation>;
145
+ /**
146
+ * Provide a callback to execute after scheduler flushed.
147
+ * @param callback
148
+ * @returns
149
+ */
150
+ onFlush(callback: Action): Builder<TSource, TTarget, TLocation>;
151
+ withLazyScheduler(): Builder<TSource, TTarget, TLocation>;
171
152
  withTotalScheduler(): Builder<TSource, TTarget, TLocation>;
172
153
  withStrategy(strategy: ITargetExecutionStrategy<TTarget, TLocation>): Builder<TSource, TTarget, TLocation>;
173
154
  withStrategy(factory: Func<ITargetExecutionStrategy<TTarget, TLocation>>): Builder<TSource, TTarget, TLocation>;
@@ -258,19 +239,71 @@ declare class EffectFactory<TSource extends object, TLocation = any> {
258
239
  whenFromSource<T>(condition: Predicate<TSource>, ifTrue: Effect<TSource, any>, ifFalse?: Effect<TSource, any>): Effect<TSource, T>;
259
240
  }
260
241
 
242
+ declare const RecorderBase_base: Constructor<object> & (new (...args: any[]) => object & IEventful<RecorderEvents>);
243
+ /**
244
+ * Record changes to an object.
245
+ */
246
+ declare abstract class RecorderBase<TSource extends object> extends RecorderBase_base implements IRecorder<TSource> {
247
+ protected _paused: boolean;
248
+ protected _projectorFactory?: Func<IProjector<TSource>>;
249
+ protected _shadow: TSource;
250
+ constructor(initial: TSource);
251
+ /**
252
+ * Receive changes from the tracked object.
253
+ * @param path
254
+ * @param value
255
+ * @returns
256
+ */
257
+ abstract receive(path: any[], value: any): void;
258
+ /**
259
+ * Send changes to a projector.
260
+ * @param projector
261
+ */
262
+ sendTo(projector: IProjector<TSource>): void;
263
+ /**
264
+ * Send changes to a projector.
265
+ * @param factory
266
+ */
267
+ sendTo(factory: Func<IProjector<TSource>>): void;
268
+ pause(): void;
269
+ resume(): void;
270
+ }
271
+ declare class Recorder<TSource extends object> extends RecorderBase<TSource> {
272
+ /**
273
+ * Receive changes from the tracked object.
274
+ * @param path
275
+ * @param value
276
+ * @returns
277
+ */
278
+ receive(path: any[], value: any): void;
279
+ }
280
+ declare class LazyRecorder<TSource extends object> extends RecorderBase<TSource> {
281
+ protected _wait: number;
282
+ protected _buffer: Map<string, Patch>;
283
+ constructor(initial: TSource, _wait?: number);
284
+ /**
285
+ * Receive changes from the tracked object.
286
+ * @param path
287
+ * @param value
288
+ * @returns
289
+ */
290
+ receive(path: any[], value: any): void;
291
+ protected readonly receiveCore: lodash_es.DebouncedFunc<() => void>;
292
+ }
293
+
261
294
  /**
262
295
  * Scheduler abstract class, used to schedule projector effects.
263
296
  */
264
297
  declare abstract class Scheduler<TTarget> implements IScheduler<TTarget> {
265
- protected _strategy?: ITargetExecutionStrategy<TTarget, any> | undefined;
266
298
  protected readonly _queue: Map<string, IScheduleItem<any, any>>;
267
299
  protected _strategyFactory?: Func<ITargetExecutionStrategy<TTarget, any>>;
268
- constructor(_strategy?: ITargetExecutionStrategy<TTarget, any> | undefined);
300
+ constructor(strategy?: ITargetExecutionStrategy<TTarget, any>);
269
301
  enqueue(item: IScheduleItem<any, any>): IScheduler<TTarget>;
270
302
  flush(): MaybePromise<void>;
303
+ reset(): void;
271
304
  withStrategy(strategy: ITargetExecutionStrategy<TTarget, any>): IScheduler<TTarget>;
272
305
  withStrategy(factory: Func<ITargetExecutionStrategy<TTarget, any>>): IScheduler<TTarget>;
273
- protected checkStrategy(): void;
306
+ protected ensureStrategy(): ITargetExecutionStrategy<TTarget, any>;
274
307
  protected abstract flushCore(): MaybePromise<void>;
275
308
  protected run(list: IScheduleItem<any, any>[]): Promise<void>;
276
309
  }
@@ -301,8 +334,9 @@ declare class TotalScheduler<TTarget> extends Scheduler<TTarget> {
301
334
  /**
302
335
  * Track changes to an object.
303
336
  * @param initial Source object to track. This must the raw object, not reactive-enabled object.
337
+ * @param [wait=500] Wait before change notification. Useful when the object changes at high frequency.
304
338
  * @returns A tuple of the tracked object and a recorder.
305
339
  */
306
- declare function track<TSource extends object>(initial: TSource): [TSource, Recorder<TSource>];
340
+ declare function track<TSource extends object>(initial: TSource, wait?: number): [TSource, IRecorder<TSource>];
307
341
 
308
- export { Builder, DynamicProjector, EffectFactory, LazyScheduler, Projector, ProjectorBase, Recorder, Scheduler, TotalScheduler, track };
342
+ export { Builder, DynamicProjector, EffectFactory, LazyRecorder, LazyScheduler, Projector, ProjectorBase, Recorder, RecorderBase, Scheduler, TotalScheduler, track };
package/types/types.d.ts CHANGED
@@ -54,6 +54,19 @@ export type ArrayEffectOptions = {
54
54
  resolveHeader: (key: string | symbol, index?: number) => string;
55
55
  }
56
56
 
57
+
58
+ export type RecorderEvents = {
59
+ record: { next: any; patches: Patch[]; };
60
+ };
61
+
62
+ export interface IRecorder<TSource extends object> extends IEventful<RecorderEvents> {
63
+ pause(): void;
64
+ receive(path: any[], value: any): void;
65
+ resume(): void;
66
+ sendTo(projector: IProjector<TSource>): void;
67
+ sendTo(factory: Func<IProjector<TSource>>): void;
68
+ }
69
+
57
70
  /**
58
71
  * Strategy defines actual execution methods for projecting values to target.
59
72
  */
@@ -61,6 +74,7 @@ export interface ITargetExecutionStrategy<TTarget, TLocation> {
61
74
  execute<T extends any>(location: TLocation, value: T): MaybePromise<void>;
62
75
  executeArray<T extends any>(location: TLocation, rows: T[], options: ArrayEffectOptions): MaybePromise<void>;
63
76
  reset(): void;
77
+ get target(): TTarget;
64
78
  }
65
79
 
66
80
  export interface IProjector<TSource> {
@@ -70,6 +84,7 @@ export interface IProjector<TSource> {
70
84
  export interface IScheduler<TTarget> {
71
85
  enqueue(effect: IScheduleItem): void;
72
86
  flush(): MaybePromise<void>;
87
+ reset(): void;
73
88
  withStrategy(strategy: ITargetExecutionStrategy<TTarget, any>): IScheduler<TTarget>;
74
89
  withStrategy(factory: Func<ITargetExecutionStrategy<TTarget, any>>): IScheduler<TTarget>;
75
90
  }