wenay-common2 1.0.52 → 1.0.55

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.
Files changed (34) hide show
  1. package/lib/Common/ObserveAll2/index.d.ts +1 -0
  2. package/lib/Common/ObserveAll2/index.js +1 -0
  3. package/lib/Common/ObserveAll2/reactive2.d.ts +28 -0
  4. package/lib/Common/ObserveAll2/reactive2.js +108 -18
  5. package/lib/Common/ObserveAll2/store-replay.d.ts +102 -0
  6. package/lib/Common/ObserveAll2/store-replay.js +53 -0
  7. package/lib/Common/ObserveAll2/store.d.ts +39 -27
  8. package/lib/Common/ObserveAll2/store.js +301 -25
  9. package/lib/Common/events/Listen3.d.ts +17 -4
  10. package/lib/Common/events/Listen3.js +9 -3
  11. package/lib/Common/events/SocketBuffer.d.ts +1 -0
  12. package/lib/Common/events/SocketServerHook.d.ts +3 -0
  13. package/lib/Common/events/UseListenTransform.d.ts +1 -0
  14. package/lib/Common/events/replay-conflate.d.ts +45 -0
  15. package/lib/Common/events/replay-conflate.js +99 -0
  16. package/lib/Common/events/replay-history.d.ts +55 -0
  17. package/lib/Common/events/replay-history.js +123 -0
  18. package/lib/Common/events/replay-index.d.ts +4 -0
  19. package/lib/Common/events/replay-index.js +20 -0
  20. package/lib/Common/events/replay-listen.d.ts +114 -0
  21. package/lib/Common/events/replay-listen.js +134 -0
  22. package/lib/Common/events/replay-wire.d.ts +43 -0
  23. package/lib/Common/events/replay-wire.js +84 -0
  24. package/lib/Common/rcp/createRpcServerAutoWithProtocolDetection.js +6 -6
  25. package/lib/Common/rcp/listen-socket.d.ts +6 -1
  26. package/lib/Common/rcp/listen-socket.js +23 -14
  27. package/lib/Common/rcp/rpc-client.js +1 -1
  28. package/lib/Common/rcp/rpc-limits.d.ts +1 -0
  29. package/lib/Common/rcp/rpc-limits.js +1 -0
  30. package/lib/Common/rcp/rpc-server-auto.js +8 -8
  31. package/lib/Common/rcp/rpc-walk.js +13 -0
  32. package/lib/index.d.ts +1 -0
  33. package/lib/index.js +2 -1
  34. package/package.json +2 -1
@@ -1,2 +1,3 @@
1
1
  export * from "./reactive2";
2
2
  export * from "./store";
3
+ export * from "./store-replay";
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./reactive2"), exports);
18
18
  __exportStar(require("./store"), exports);
19
+ __exportStar(require("./store-replay"), exports);
@@ -1,4 +1,8 @@
1
1
  type Fn = () => void;
2
+ export type ReactiveChange = {
3
+ paths: PropertyKey[][];
4
+ };
5
+ type PathUpdateFn = (change: ReactiveChange) => void;
2
6
  type Drain = 'micro' | 'immediate' | number | ((flush: Fn) => void);
3
7
  export type Opts = {
4
8
  drain?: Drain;
@@ -7,7 +11,9 @@ export type Opts = {
7
11
  };
8
12
  export declare function reactive<T extends object>(root: T, opts?: Opts): T;
9
13
  export declare function isReactive(p: any): boolean;
14
+ export declare function toRaw<T>(p: T): T;
10
15
  export declare function onUpdate(p: any, cb: Fn): () => void;
16
+ export declare function onUpdatePaths(p: any, cb: PathUpdateFn): () => void;
11
17
  export declare function flushReactive(p: any): Promise<void>;
12
18
  export declare function listenUpdate(p: any): {
13
19
  func: import("../events/Listen3").Listener<[]>;
@@ -18,6 +24,7 @@ export declare function listenUpdate(p: any): {
18
24
  onClose: (cb: () => void) => () => void;
19
25
  removeEventClose: (cb: () => void) => void;
20
26
  on: import("../events/Listen3").ListenOn<[]>;
27
+ off: (k: (string | symbol) | import("../events/Listen3").Listener<[]> | null) => void;
21
28
  addListen: (cb: import("../events/Listen3").Listener<[]>, opts?: {
22
29
  cbClose?: () => void;
23
30
  key?: string | symbol;
@@ -29,5 +36,26 @@ export declare function listenUpdate(p: any): {
29
36
  count: () => number;
30
37
  readonly getAllKeys: (string | symbol)[];
31
38
  };
39
+ export declare function listenUpdatePaths(p: any): {
40
+ func: import("../events/Listen3").Listener<[ReactiveChange]>;
41
+ isRun: () => boolean;
42
+ run: () => void;
43
+ close: () => void;
44
+ eventClose: (cb: () => void) => () => void;
45
+ onClose: (cb: () => void) => () => void;
46
+ removeEventClose: (cb: () => void) => void;
47
+ on: import("../events/Listen3").ListenOn<[ReactiveChange]>;
48
+ off: (k: (string | symbol) | import("../events/Listen3").Listener<[ReactiveChange]> | null) => void;
49
+ addListen: (cb: import("../events/Listen3").Listener<[ReactiveChange]>, opts?: {
50
+ cbClose?: () => void;
51
+ key?: string | symbol;
52
+ }) => () => void;
53
+ removeListen: (k: (string | symbol) | import("../events/Listen3").Listener<[ReactiveChange]> | null) => void;
54
+ once: (cb: import("../events/Listen3").Listener<[ReactiveChange]>, opts?: {
55
+ key?: string | symbol;
56
+ }) => () => void;
57
+ count: () => number;
58
+ readonly getAllKeys: (string | symbol)[];
59
+ };
32
60
  export type Reactive<T extends object> = T;
33
61
  export {};
@@ -2,9 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.reactive = reactive;
4
4
  exports.isReactive = isReactive;
5
+ exports.toRaw = toRaw;
5
6
  exports.onUpdate = onUpdate;
7
+ exports.onUpdatePaths = onUpdatePaths;
6
8
  exports.flushReactive = flushReactive;
7
9
  exports.listenUpdate = listenUpdate;
10
+ exports.listenUpdatePaths = listenUpdatePaths;
8
11
  const Listen_1 = require("../events/Listen");
9
12
  const NODE = Symbol('reactive2.node');
10
13
  const isObj = (v) => v != null && typeof v == 'object';
@@ -30,7 +33,7 @@ function reactive(root, opts = {}) {
30
33
  const { drain = 'immediate', depth = Infinity, eager = false } = opts;
31
34
  const fire = scheduler(drain);
32
35
  const eng = {
33
- live: 0, dirty: new Set(), scheduled: false, waiters: new Set(), depth,
36
+ live: 0, pathLive: 0, dirty: new Set(), dirtyPaths: [], scheduled: false, waiters: new Set(), depth,
34
37
  schedule() {
35
38
  if (eng.scheduled)
36
39
  return;
@@ -39,8 +42,10 @@ function reactive(root, opts = {}) {
39
42
  eng.scheduled = false;
40
43
  const batch = [...eng.dirty];
41
44
  eng.dirty.clear();
45
+ const dirtyPaths = eng.dirtyPaths;
46
+ eng.dirtyPaths = [];
42
47
  let err;
43
- for (const n of batch)
48
+ for (const n of batch) {
44
49
  for (const cb of [...n.subs]) {
45
50
  try {
46
51
  cb();
@@ -49,7 +54,20 @@ function reactive(root, opts = {}) {
49
54
  err ??= e;
50
55
  }
51
56
  }
52
- if (!eng.scheduled && eng.dirty.size == 0) {
57
+ if (n.pathSubs.size) {
58
+ const paths = pathsForNode(n, dirtyPaths);
59
+ if (paths.length)
60
+ for (const cb of [...n.pathSubs]) {
61
+ try {
62
+ cb({ paths });
63
+ }
64
+ catch (e) {
65
+ err ??= e;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ if (!eng.scheduled && eng.dirty.size == 0 && eng.dirtyPaths.length == 0) {
53
71
  const waiters = [...eng.waiters];
54
72
  eng.waiters.clear();
55
73
  for (const w of waiters)
@@ -60,13 +78,16 @@ function reactive(root, opts = {}) {
60
78
  });
61
79
  },
62
80
  };
63
- const rootNode = makeNode(root, null, 0, eng);
81
+ const rootNode = makeNode(root, null, [], 0, eng);
64
82
  if (eager)
65
83
  prewalk(rootNode);
66
84
  return rootNode.proxy;
67
85
  }
68
- function makeNode(target, parent, level, eng) {
69
- const node = { target, parent, active: true, level, subs: new Set(), kids: new Map(), proxy: null, eng };
86
+ function makeNode(target, parent, path, level, eng) {
87
+ const node = {
88
+ target, parent, path, active: true, level,
89
+ subs: new Set(), pathSubs: new Set(), kids: new Map(), proxy: null, eng,
90
+ };
70
91
  const proxyTarget = (Array.isArray(target) ? [] : {});
71
92
  node.proxy = new Proxy(proxyTarget, {
72
93
  get(_, k) {
@@ -78,7 +99,7 @@ function makeNode(target, parent, level, eng) {
78
99
  if (isReactiveObj(v) && level < eng.depth) {
79
100
  let kid = node.kids.get(k);
80
101
  if (!kid) {
81
- kid = makeNode(v, node, level + 1, eng);
102
+ kid = makeNode(v, node, [...node.path, k], level + 1, eng);
82
103
  node.kids.set(k, kid);
83
104
  }
84
105
  else if (kid.target !== v)
@@ -88,8 +109,10 @@ function makeNode(target, parent, level, eng) {
88
109
  return v;
89
110
  },
90
111
  set(_, k, v) {
112
+ v = toRaw(v);
91
113
  if (Object.is(node.target[k], v))
92
114
  return true;
115
+ const dirtyPath = dirtyPathFor(node, k);
93
116
  node.target[k] = v;
94
117
  if (Array.isArray(proxyTarget) && k == "length")
95
118
  proxyTarget.length = v;
@@ -97,21 +120,23 @@ function makeNode(target, parent, level, eng) {
97
120
  if (kid)
98
121
  rebind(kid, v);
99
122
  if (eng.live > 0)
100
- bubble(node);
123
+ bubble(node, dirtyPath);
101
124
  return true;
102
125
  },
103
126
  defineProperty(_, k, d) {
104
127
  const old = node.target[k];
105
- const ok = Reflect.defineProperty(node.target, k, d);
128
+ const desc = 'value' in d ? { ...d, value: toRaw(d.value) } : d;
129
+ const ok = Reflect.defineProperty(node.target, k, desc);
106
130
  if (!ok)
107
131
  return false;
108
- if (d.configurable === false) {
109
- const mirror = Reflect.defineProperty(proxyTarget, k, d);
132
+ if (desc.configurable === false) {
133
+ const mirror = Reflect.defineProperty(proxyTarget, k, desc);
110
134
  if (!mirror)
111
135
  return false;
112
136
  }
113
137
  const v = node.target[k];
114
138
  if (!Object.is(old, v)) {
139
+ const dirtyPath = dirtyPathFor(node, k);
115
140
  const kid = node.kids.get(k);
116
141
  if (kid) {
117
142
  if (isReactiveObj(v))
@@ -123,13 +148,14 @@ function makeNode(target, parent, level, eng) {
123
148
  }
124
149
  }
125
150
  if (eng.live > 0)
126
- bubble(node);
151
+ bubble(node, dirtyPath);
127
152
  }
128
153
  return true;
129
154
  },
130
155
  deleteProperty(_, k) {
131
156
  if (!(k in node.target))
132
157
  return true;
158
+ const dirtyPath = dirtyPathFor(node, k);
133
159
  delete node.target[k];
134
160
  const kid = node.kids.get(k);
135
161
  if (kid) {
@@ -138,7 +164,7 @@ function makeNode(target, parent, level, eng) {
138
164
  detachTree(kid);
139
165
  }
140
166
  if (eng.live > 0)
141
- bubble(node);
167
+ bubble(node, dirtyPath);
142
168
  return true;
143
169
  },
144
170
  has(_, k) { return k in node.target; },
@@ -165,16 +191,18 @@ function makeNode(target, parent, level, eng) {
165
191
  });
166
192
  return node;
167
193
  }
168
- function bubble(from) {
194
+ function bubble(from, dirtyPath) {
169
195
  const eng = from.eng;
196
+ if (eng.pathLive > 0 && dirtyPath)
197
+ addDirtyPath(eng, dirtyPath);
170
198
  for (let n = from; n && n.active; n = n.parent)
171
- if (n.subs.size)
199
+ if (n.subs.size || n.pathSubs.size)
172
200
  eng.dirty.add(n);
173
201
  eng.schedule();
174
202
  }
175
203
  function rebind(node, next) {
176
204
  node.target = next;
177
- if (node.subs.size)
205
+ if (node.subs.size || node.pathSubs.size)
178
206
  node.eng.dirty.add(node);
179
207
  for (const [k, kid] of [...node.kids]) {
180
208
  const cv = isReactiveObj(next) ? next[k] : undefined;
@@ -188,11 +216,37 @@ function rebind(node, next) {
188
216
  }
189
217
  }
190
218
  function markChanged(node) {
191
- if (node.subs.size)
219
+ if (node.subs.size || node.pathSubs.size)
192
220
  node.eng.dirty.add(node);
193
221
  for (const kid of node.kids.values())
194
222
  markChanged(kid);
195
223
  }
224
+ function dirtyPathFor(node, key) {
225
+ return Array.isArray(node.target) ? [...node.path] : [...node.path, key];
226
+ }
227
+ function addDirtyPath(eng, path) {
228
+ if (!eng.dirtyPaths.some(p => samePath(p, path)))
229
+ eng.dirtyPaths.push([...path]);
230
+ }
231
+ function samePath(a, b) {
232
+ return a.length == b.length && a.every((k, i) => Object.is(k, b[i]));
233
+ }
234
+ function startsWithPath(path, prefix) {
235
+ return prefix.length <= path.length && prefix.every((k, i) => Object.is(k, path[i]));
236
+ }
237
+ function pathsForNode(node, dirtyPaths) {
238
+ const out = [];
239
+ for (const path of dirtyPaths) {
240
+ let next = null;
241
+ if (startsWithPath(path, node.path))
242
+ next = path.slice(node.path.length);
243
+ else if (startsWithPath(node.path, path))
244
+ next = [];
245
+ if (next && !out.some(p => samePath(p, next)))
246
+ out.push(next);
247
+ }
248
+ return out;
249
+ }
196
250
  function detachTree(node) {
197
251
  if (!node.active)
198
252
  return;
@@ -218,6 +272,10 @@ function isReactive(p) {
218
272
  const node = p && p[NODE];
219
273
  return !!node && node.active;
220
274
  }
275
+ function toRaw(p) {
276
+ const node = p && p[NODE];
277
+ return node ? node.target : p;
278
+ }
221
279
  function onUpdate(p, cb) {
222
280
  const node = p && p[NODE];
223
281
  if (!node)
@@ -232,12 +290,33 @@ function onUpdate(p, cb) {
232
290
  return; done = true; if (node.subs.delete(sub))
233
291
  node.eng.live--; };
234
292
  }
293
+ function onUpdatePaths(p, cb) {
294
+ const node = p && p[NODE];
295
+ if (!node)
296
+ throw new Error('onUpdatePaths: not a reactive object');
297
+ if (!node.active)
298
+ throw new Error('onUpdatePaths: reactive object is detached');
299
+ const sub = (change) => cb(change);
300
+ node.pathSubs.add(sub);
301
+ node.eng.live++;
302
+ node.eng.pathLive++;
303
+ let done = false;
304
+ return () => {
305
+ if (done)
306
+ return;
307
+ done = true;
308
+ if (node.pathSubs.delete(sub)) {
309
+ node.eng.live--;
310
+ node.eng.pathLive--;
311
+ }
312
+ };
313
+ }
235
314
  function flushReactive(p) {
236
315
  const node = p && p[NODE];
237
316
  if (!node)
238
317
  throw new Error('flushReactive: not a reactive object');
239
318
  const eng = node.eng;
240
- if (!eng.scheduled && eng.dirty.size == 0)
319
+ if (!eng.scheduled && eng.dirty.size == 0 && eng.dirtyPaths.length == 0)
241
320
  return Promise.resolve();
242
321
  return new Promise(resolve => { eng.waiters.add(resolve); });
243
322
  }
@@ -252,3 +331,14 @@ function listenUpdate(p) {
252
331
  });
253
332
  return listen;
254
333
  }
334
+ function listenUpdatePaths(p) {
335
+ const listen = (0, Listen_1.funcListenCallbackBase)((emit) => onUpdatePaths(p, change => emit(change)), {
336
+ event: (type, count, api) => {
337
+ if (type == "add" && count == 1 && !api.isRun())
338
+ api.run();
339
+ if (type == "remove" && count == 0 && api.isRun())
340
+ api.close();
341
+ },
342
+ });
343
+ return listen;
344
+ }
@@ -0,0 +1,102 @@
1
+ import { Store, StorePatch } from './store';
2
+ import { ReplayListenOptions } from '../events/replay-listen';
3
+ import { ReplayRemote, ReplaySubscribeOpts } from '../events/replay-wire';
4
+ import { ReplayStorage } from '../events/replay-history';
5
+ export type StoreReplayOpts = Pick<ReplayListenOptions<[StorePatch]>, 'history' | 'getSince' | 'onJournal' | 'now'>;
6
+ export declare function storePatchKey(patch: StorePatch): string | null;
7
+ export declare function exposeStoreReplay<T extends object>(store: Store<T>, opts?: StoreReplayOpts): {
8
+ api: {
9
+ replay: {
10
+ line: {
11
+ func: import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]>;
12
+ isRun: () => boolean;
13
+ run: () => void;
14
+ close: () => void;
15
+ eventClose: (cb: () => void) => () => void;
16
+ onClose: (cb: () => void) => () => void;
17
+ removeEventClose: (cb: () => void) => void;
18
+ on: import("../..").ListenOn<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]>;
19
+ off: (k: (string | symbol) | import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]> | null) => void;
20
+ addListen: (cb: import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]>, opts?: {
21
+ cbClose?: () => void;
22
+ key?: string | symbol;
23
+ }) => () => void;
24
+ removeListen: (k: (string | symbol) | import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]> | null) => void;
25
+ once: (cb: import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]>, opts?: {
26
+ key?: string | symbol;
27
+ }) => () => void;
28
+ count: () => number;
29
+ readonly getAllKeys: (string | symbol)[];
30
+ };
31
+ since: (seq: number) => import("../events/replay-listen").ReplayEvent<[StorePatch]>[] | null;
32
+ keyframe: () => import("../events/replay-listen").ReplayEvent<[StorePatch]> | null;
33
+ };
34
+ get(): T;
35
+ get<M extends import("./store").StoreMask<T>>(mask: M): import("./store").StorePick<T, M>;
36
+ set(path: import("./store").StorePath, value: any): void;
37
+ replace(path: import("./store").StorePath, value: any): void;
38
+ changed: any;
39
+ changedPaths: any;
40
+ patches?: any;
41
+ changedData?: any;
42
+ };
43
+ replay: {
44
+ func: import("../..").Listener<[StorePatch]>;
45
+ head: () => number;
46
+ getSince: (seq: number) => import("../events/replay-listen").ReplayEvent<[StorePatch]>[] | undefined;
47
+ line: {
48
+ func: import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]>;
49
+ isRun: () => boolean;
50
+ run: () => void;
51
+ close: () => void;
52
+ eventClose: (cb: () => void) => () => void;
53
+ onClose: (cb: () => void) => () => void;
54
+ removeEventClose: (cb: () => void) => void;
55
+ on: import("../..").ListenOn<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]>;
56
+ off: (k: (string | symbol) | import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]> | null) => void;
57
+ addListen: (cb: import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]>, opts?: {
58
+ cbClose?: () => void;
59
+ key?: string | symbol;
60
+ }) => () => void;
61
+ removeListen: (k: (string | symbol) | import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]> | null) => void;
62
+ once: (cb: import("../..").Listener<[import("../events/replay-listen").ReplayEvent<[StorePatch]>]>, opts?: {
63
+ key?: string | symbol;
64
+ }) => () => void;
65
+ count: () => number;
66
+ readonly getAllKeys: (string | symbol)[];
67
+ };
68
+ hasKeyframe: boolean;
69
+ keyframe: () => import("../events/replay-listen").ReplayEvent<[StorePatch]> | undefined;
70
+ on: import("../events/replay-listen").ListenOnReplay<[StorePatch]>;
71
+ addListen: (cb: import("../..").Listener<[StorePatch]>, opts?: {
72
+ cbClose?: () => void;
73
+ key?: string | symbol;
74
+ current?: import("../..").ListenCurrent<[StorePatch]> | undefined;
75
+ since?: number;
76
+ onSeq?: (seq: number) => void;
77
+ }) => () => void;
78
+ removeListen: (k: import("../..").Listener<[StorePatch]> | (string | symbol) | null) => void;
79
+ once: (cb: import("../..").Listener<[StorePatch]>, opts?: {
80
+ key?: string | symbol;
81
+ current?: import("../..").ListenCurrent<[StorePatch]> | undefined;
82
+ }) => () => void;
83
+ getAllKeys: (string | symbol)[];
84
+ isRun: () => boolean;
85
+ run: () => void;
86
+ close: () => void;
87
+ eventClose: (cb: () => void) => () => void;
88
+ onClose: (cb: () => void) => () => void;
89
+ removeEventClose: (cb: () => void) => void;
90
+ off: (k: (string | symbol) | import("../..").Listener<[StorePatch]> | null) => void;
91
+ count: () => number;
92
+ };
93
+ close: () => void;
94
+ };
95
+ export declare function syncStoreReplay<T extends object>(store: Store<T>, remote: ReplayRemote<[StorePatch]>, opts?: ReplaySubscribeOpts): (() => void) & {
96
+ ready: Promise<void>;
97
+ seq: () => number;
98
+ };
99
+ export declare function storeReplayAt<T extends object>(storage: ReplayStorage<[StorePatch]>, at?: {
100
+ seq?: number;
101
+ ts?: number;
102
+ }): T | undefined;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.storePatchKey = storePatchKey;
4
+ exports.exposeStoreReplay = exposeStoreReplay;
5
+ exports.syncStoreReplay = syncStoreReplay;
6
+ exports.storeReplayAt = storeReplayAt;
7
+ const store_1 = require("./store");
8
+ const replay_listen_1 = require("../events/replay-listen");
9
+ const replay_wire_1 = require("../events/replay-wire");
10
+ const replay_history_1 = require("../events/replay-history");
11
+ function makeStorePatch(store, path) {
12
+ let node = store.node;
13
+ for (const k of path)
14
+ node = node.at(k);
15
+ const exists = node.has();
16
+ return { path: [...path], exists, value: exists ? node.snapshot() : undefined };
17
+ }
18
+ function storePatchKey(patch) {
19
+ for (const k of patch.path)
20
+ if (typeof k == 'symbol')
21
+ return null;
22
+ return JSON.stringify(patch.path);
23
+ }
24
+ function exposeStoreReplay(store, opts = {}) {
25
+ const [emitPatch, lineApi] = (0, replay_listen_1.UseReplayListen)({
26
+ current: () => [{ path: [], exists: true, value: store.snapshot() }],
27
+ history: opts.getSince ? undefined : (opts.history ?? 1024),
28
+ getSince: opts.getSince,
29
+ onJournal: opts.onJournal,
30
+ now: opts.now,
31
+ });
32
+ const offStore = store.listenPaths().on(function journalStoreChange(change) {
33
+ for (const path of change.paths)
34
+ emitPatch(makeStorePatch(store, path));
35
+ });
36
+ return {
37
+ api: { ...(0, store_1.exposeStore)(store), replay: (0, replay_wire_1.exposeReplay)(lineApi) },
38
+ replay: lineApi,
39
+ close: () => { offStore(); },
40
+ };
41
+ }
42
+ function syncStoreReplay(store, remote, opts = {}) {
43
+ return (0, replay_wire_1.replaySubscribe)(remote, function applyLine(patch) { (0, store_1.applyStorePatch)(store, patch); }, opts);
44
+ }
45
+ function storeReplayAt(storage, at = {}) {
46
+ const envelopes = (0, replay_history_1.openHistory)(storage).at(at);
47
+ if (!envelopes)
48
+ return undefined;
49
+ const scratch = (0, store_1.createStore)({});
50
+ for (const ev of envelopes)
51
+ (0, store_1.applyStorePatch)(scratch, ev.event[0]);
52
+ return scratch.snapshot();
53
+ }
@@ -1,4 +1,4 @@
1
- import { listenUpdate, reactive } from "./reactive2";
1
+ import { listenUpdate, listenUpdatePaths, reactive, ReactiveChange } from "./reactive2";
2
2
  export type StorePath = readonly PropertyKey[];
3
3
  export type StoreDrain = "micro" | "immediate" | number | ((flush: () => void) => void);
4
4
  export type StoreSubOpts = {
@@ -6,6 +6,23 @@ export type StoreSubOpts = {
6
6
  drain?: StoreDrain;
7
7
  key?: string;
8
8
  };
9
+ export type StoreChange = ReactiveChange;
10
+ export type StorePatch = {
11
+ path: PropertyKey[];
12
+ value: any;
13
+ exists: boolean;
14
+ };
15
+ export type StoreChangedData<M = any> = {
16
+ mask: M;
17
+ data: any;
18
+ };
19
+ export type StoreSyncOpts = StoreSubOpts & {
20
+ partial?: boolean;
21
+ onError?: (error: any) => void;
22
+ };
23
+ export type StoreExposeOpts = {
24
+ push?: boolean;
25
+ };
9
26
  export type StoreCtx<T = any> = {
10
27
  store: Store<any>;
11
28
  node: StoreNode<T>;
@@ -60,39 +77,34 @@ export type Store<T extends object> = {
60
77
  once(cb: (value: T, ctx: StoreCtx<T>) => void, opts?: StoreSubOpts): () => void;
61
78
  update<M extends StoreMask<T>>(mask: M, opts?: StoreSubOpts): StoreSelection<T, M>;
62
79
  listen(): ReturnType<typeof listenUpdate>;
80
+ listenPaths(): ReturnType<typeof listenUpdatePaths>;
63
81
  count(): number;
64
82
  };
65
83
  type RemoteStore<T extends object> = {
66
84
  get(mask?: any): T | Promise<T>;
67
85
  changed: any;
86
+ changedPaths?: any;
87
+ patches?: any;
88
+ changedData?: any;
68
89
  };
69
- export declare function createStore<T extends object>(initial: T, opts?: Parameters<typeof reactive<T>>[1]): Store<T>;
70
- export declare function exposeStore<T extends object>(store: Store<T>): {
71
- get: (mask?: StoreMask<T>) => T extends object ? T | { [K in (string | number | symbol) & keyof T]: T[K] | (NonNullable<T[K]> extends object ? T[K] | { [K_2 in (string | number | symbol) & keyof NonNullable<T[K]>]: NonNullable<T[K]>[K_2] | (NonNullable<NonNullable<T[K]>[K_2]> extends object ? NonNullable<T[K]>[K_2] | { [K_3 in (string | number | symbol) & keyof NonNullable<NonNullable<T[K]>[K_2]>]: NonNullable<NonNullable<T[K]>[K_2]>[K_3] | (NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]> extends object ? NonNullable<NonNullable<T[K]>[K_2]>[K_3] | { [K_4 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>]: NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4] | (NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]> extends object ? NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4] | { [K_5 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>]: NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5] | { [K_6 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6] | { [K_7 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7] | { [K_8 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8] | { [K_9 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9] | { [K_10 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10] | { [K_11 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10]>[K_11] | any; } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10]); } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]); } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]); } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]); } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]); } : NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]); } : NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]); } : NonNullable<NonNullable<T[K]>[K_2]>[K_3]); } : NonNullable<T[K]>[K_2]); } : T[K]); } : T;
72
- set: (path: StorePath, value: any) => void;
73
- replace: (path: StorePath, value: any) => void;
74
- changed: {
75
- func: import("../events/Listen3").Listener<[]>;
76
- isRun: () => boolean;
77
- run: () => void;
78
- close: () => void;
79
- eventClose: (cb: () => void) => () => void;
80
- onClose: (cb: () => void) => () => void;
81
- removeEventClose: (cb: () => void) => void;
82
- on: import("../events/Listen3").ListenOn<[]>;
83
- addListen: (cb: import("../events/Listen3").Listener<[]>, opts?: {
84
- cbClose?: () => void;
85
- key?: string | symbol;
86
- }) => () => void;
87
- removeListen: (k: (string | symbol) | import("../events/Listen3").Listener<[]> | null) => void;
88
- once: (cb: import("../events/Listen3").Listener<[]>, opts?: {
89
- key?: string | symbol;
90
- }) => () => void;
91
- count: () => number;
92
- readonly getAllKeys: (string | symbol)[];
93
- };
90
+ export type StoreRemoteApi<T extends object> = {
91
+ get(): T;
92
+ get<M extends StoreMask<T>>(mask: M): StorePick<T, M>;
93
+ set(path: StorePath, value: any): void;
94
+ replace(path: StorePath, value: any): void;
95
+ changed: any;
96
+ changedPaths: any;
97
+ patches?: any;
98
+ changedData?: any;
94
99
  };
100
+ export declare function applyStoreMask<T extends object>(store: Store<T>, mask: StoreMask<T> | any, data: any): void;
101
+ export declare function applyStorePatch<T extends object>(store: Store<T>, patch: StorePatch): void;
102
+ export declare function applyStorePatches<T extends object>(store: Store<T>, patches: readonly StorePatch[]): void;
103
+ export declare function createStore<T extends object>(initial: T, opts?: Parameters<typeof reactive<T>>[1]): Store<T>;
104
+ export declare function exposeStore<T extends object>(store: Store<T>, opts?: StoreExposeOpts): StoreRemoteApi<T>;
95
105
  export declare function createStoreMirror<T extends object>(remote: RemoteStore<T>, initial?: T, opts?: Parameters<typeof createStore<T>>[1]): Store<T> & {
96
- sync: <M extends StoreMask<T>>(mask: M, subOpts?: StoreSubOpts) => Promise<() => void>;
106
+ sync: <M extends StoreMask<T>>(mask: M, subOpts?: StoreSyncOpts) => Promise<() => void>;
107
+ syncPatches: <M extends StoreMask<T>>(mask: M, subOpts?: StoreSyncOpts) => Promise<() => void>;
108
+ syncChangedData: <M extends StoreMask<T>>(mask: M, subOpts?: StoreSyncOpts) => Promise<() => void>;
97
109
  };
98
110
  export {};