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,13 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyStoreMask = applyStoreMask;
4
+ exports.applyStorePatch = applyStorePatch;
5
+ exports.applyStorePatches = applyStorePatches;
3
6
  exports.createStore = createStore;
4
7
  exports.exposeStore = exposeStore;
5
8
  exports.createStoreMirror = createStoreMirror;
9
+ const Listen_1 = require("../events/Listen");
6
10
  const reactive2_1 = require("./reactive2");
7
11
  const hasSetImmediate = typeof setImmediate == "function";
8
- function pathKey(path) {
12
+ function pathText(path) {
9
13
  return path.map(String).join(".");
10
14
  }
15
+ const symbolIds = new Map();
16
+ let nextSymbolId = 1;
17
+ function symbolKey(k) {
18
+ let id = symbolIds.get(k);
19
+ if (id == null) {
20
+ id = nextSymbolId++;
21
+ symbolIds.set(k, id);
22
+ }
23
+ return id;
24
+ }
25
+ function pathKey(path) {
26
+ return JSON.stringify(path.map(k => typeof k == "symbol" ? ["symbol", symbolKey(k)] : ["key", String(k)]));
27
+ }
11
28
  function schedule(drain, flush) {
12
29
  if (drain == null) {
13
30
  flush();
@@ -102,6 +119,7 @@ function setAt(root, path, value) {
102
119
  p[path[path.length - 1]] = value;
103
120
  }
104
121
  function snapshotValue(value, seen = new WeakMap()) {
122
+ value = (0, reactive2_1.toRaw)(value);
105
123
  if (!isObj(value))
106
124
  return value;
107
125
  if (value instanceof Date)
@@ -135,26 +153,176 @@ function maskPaths(mask, base = []) {
135
153
  if (!isObj(mask))
136
154
  return [base];
137
155
  const out = [];
138
- for (const k of Object.keys(mask))
156
+ for (const k of Reflect.ownKeys(mask))
139
157
  out.push(...maskPaths(mask[k], [...base, k]));
140
158
  return out;
141
159
  }
142
160
  function pickSnapshot(root, mask, base = []) {
161
+ root = (0, reactive2_1.toRaw)(root);
143
162
  if (mask === true || mask == null)
144
163
  return snapshotValue(getAt(root, base));
145
164
  const out = {};
146
- for (const k of Object.keys(mask))
165
+ for (const k of Reflect.ownKeys(mask))
147
166
  out[k] = pickSnapshot(root, mask[k], [...base, k]);
148
167
  return out;
149
168
  }
169
+ function deleteAt(root, path) {
170
+ if (path.length == 0) {
171
+ replaceRoot(root, {});
172
+ return;
173
+ }
174
+ const parent = getAt(root, path.slice(0, -1));
175
+ if (isObj(parent))
176
+ delete parent[path[path.length - 1]];
177
+ }
150
178
  function applyMask(root, mask, data, base = []) {
151
179
  if (mask === true || mask == null) {
152
- setAt(root, base, snapshotValue(data));
180
+ if (data === undefined && base.length)
181
+ deleteAt(root, base);
182
+ else
183
+ setAt(root, base, snapshotValue(data));
153
184
  return;
154
185
  }
155
- for (const k of Object.keys(mask))
186
+ for (const k of Reflect.ownKeys(mask))
156
187
  applyMask(root, mask[k], data?.[k], [...base, k]);
157
188
  }
189
+ function applyStoreMask(store, mask, data) {
190
+ applyMask(store.state, mask ?? true, data);
191
+ }
192
+ function applyStorePatch(store, patch) {
193
+ if (patch.exists === false)
194
+ deleteAt(store.state, patch.path);
195
+ else
196
+ setAt(store.state, patch.path, snapshotValue(patch.value));
197
+ }
198
+ function applyStorePatches(store, patches) {
199
+ for (const patch of patches)
200
+ applyStorePatch(store, patch);
201
+ }
202
+ function pathToMask(path) {
203
+ let out = true;
204
+ for (let i = path.length - 1; i >= 0; i--)
205
+ out = { [path[i]]: out };
206
+ return out;
207
+ }
208
+ function hasMaskKey(mask, key) {
209
+ return isObj(mask) && Reflect.ownKeys(mask).some(k => Object.is(k, key));
210
+ }
211
+ function mergeMasks(a, b) {
212
+ if (a === undefined)
213
+ return b;
214
+ if (b === undefined)
215
+ return a;
216
+ if (a === true || a == null || b === true || b == null)
217
+ return true;
218
+ if (!isObj(a) || !isObj(b))
219
+ return true;
220
+ const out = {};
221
+ for (const k of Reflect.ownKeys(a))
222
+ out[k] = a[k];
223
+ for (const k of Reflect.ownKeys(b)) {
224
+ out[k] = hasMaskKey(a, k) ? mergeMasks(a[k], b[k]) : b[k];
225
+ }
226
+ return out;
227
+ }
228
+ function startsWithPath(path, prefix) {
229
+ return prefix.length <= path.length && prefix.every((k, i) => Object.is(k, path[i]));
230
+ }
231
+ function intersectMaskWithPaths(mask, dirtyPaths) {
232
+ const baseMask = mask ?? true;
233
+ if (!Array.isArray(dirtyPaths))
234
+ return baseMask;
235
+ if (dirtyPaths.length == 0)
236
+ return undefined;
237
+ const selected = maskPaths(baseMask);
238
+ let out = undefined;
239
+ for (const dirty of dirtyPaths) {
240
+ if (!Array.isArray(dirty))
241
+ continue;
242
+ if (dirty.length == 0) {
243
+ out = mergeMasks(out, baseMask);
244
+ continue;
245
+ }
246
+ for (const selectedPath of selected) {
247
+ if (startsWithPath(dirty, selectedPath))
248
+ out = mergeMasks(out, pathToMask(dirty));
249
+ else if (startsWithPath(selectedPath, dirty))
250
+ out = mergeMasks(out, pathToMask(selectedPath));
251
+ }
252
+ }
253
+ return out;
254
+ }
255
+ function maskFromPaths(paths) {
256
+ let out = undefined;
257
+ for (const path of paths)
258
+ out = mergeMasks(out, pathToMask(path));
259
+ return out ?? true;
260
+ }
261
+ function makePatch(root, path) {
262
+ root = (0, reactive2_1.toRaw)(root);
263
+ const exists = hasAt(root, path);
264
+ return {
265
+ path: [...path],
266
+ exists,
267
+ value: exists ? snapshotValue(getAt(root, path)) : undefined,
268
+ };
269
+ }
270
+ function patchesForMask(patch, mask) {
271
+ const selected = maskPaths(mask ?? true);
272
+ const out = [];
273
+ let emittedWholePatch = false;
274
+ for (const selectedPath of selected) {
275
+ if (startsWithPath(patch.path, selectedPath)) {
276
+ if (!emittedWholePatch) {
277
+ out.push(patch);
278
+ emittedWholePatch = true;
279
+ }
280
+ continue;
281
+ }
282
+ if (!startsWithPath(selectedPath, patch.path))
283
+ continue;
284
+ const rel = selectedPath.slice(patch.path.length);
285
+ const exists = patch.exists && hasAt(patch.value, rel);
286
+ out.push({
287
+ path: [...selectedPath],
288
+ exists,
289
+ value: exists ? snapshotValue(getAt(patch.value, rel)) : undefined,
290
+ });
291
+ }
292
+ return out;
293
+ }
294
+ function createPatchesListen(store) {
295
+ return (0, Listen_1.funcListenCallbackBase)((emit) => {
296
+ const off = store.listenPaths().on((change) => {
297
+ for (const path of change.paths)
298
+ emit(makePatch(store.state, path));
299
+ });
300
+ return off;
301
+ }, {
302
+ event: (type, count, api) => {
303
+ if (type == "add" && count == 1 && !api.isRun())
304
+ api.run();
305
+ if (type == "remove" && count == 0 && api.isRun())
306
+ api.close();
307
+ },
308
+ });
309
+ }
310
+ function createChangedDataListen(store) {
311
+ return (0, Listen_1.funcListenCallbackBase)((emit) => {
312
+ const off = store.listenPaths().on((change) => {
313
+ const mask = maskFromPaths(change.paths);
314
+ emit({ mask, data: pickSnapshot(store.state, mask) });
315
+ });
316
+ return off;
317
+ }, {
318
+ event: (type, count, api) => {
319
+ if (type == "add" && count == 1 && !api.isRun())
320
+ api.run();
321
+ if (type == "remove" && count == 0 && api.isRun())
322
+ api.close();
323
+ },
324
+ });
325
+ }
158
326
  function watchTarget(root, path) {
159
327
  let cur = root;
160
328
  let lastReactive = root;
@@ -183,7 +351,7 @@ function makeCtx(store, path) {
183
351
  store,
184
352
  node: getNode(store, path),
185
353
  path: [...path],
186
- pathString: pathKey(path),
354
+ pathString: pathText(path),
187
355
  exists: hasAt(store._state, path),
188
356
  };
189
357
  }
@@ -259,7 +427,7 @@ function getNode(store, path) {
259
427
  return cached;
260
428
  const api = {
261
429
  get path() { return [...path]; },
262
- get pathString() { return pathKey(path); },
430
+ get pathString() { return pathText(path); },
263
431
  get: () => getAt(store._state, path),
264
432
  has: () => hasAt(store._state, path),
265
433
  snapshot: () => snapshotValue(getAt(store._state, path)),
@@ -309,8 +477,12 @@ function createSelection(store, base, mask, defaults = {}) {
309
477
  off(); };
310
478
  },
311
479
  once(cb, opts = {}) {
480
+ let done = false;
312
481
  let off = () => { };
313
- off = this.on((v, c) => { off(); cb(v, c); }, { ...opts, current: opts.current ?? defaults.current });
482
+ off = this.on(function fireOnce(v, c) { if (done)
483
+ return; done = true; off(); cb(v, c); }, { ...opts, current: opts.current ?? defaults.current });
484
+ if (done)
485
+ off();
314
486
  return off;
315
487
  },
316
488
  onEach(cb, opts = {}) {
@@ -337,13 +509,15 @@ function createStore(initial, opts = {}) {
337
509
  once: (cb, opts) => getNode(store, []).once(cb, opts),
338
510
  update: (mask, opts) => createSelection(store, [], mask, opts),
339
511
  listen: () => (0, reactive2_1.listenUpdate)(state),
512
+ listenPaths: () => (0, reactive2_1.listenUpdatePaths)(state),
340
513
  count: () => Array.from(store._counts.values()).reduce((a, b) => a + b, 0),
341
514
  };
342
515
  return store;
343
516
  }
344
- function exposeStore(store) {
345
- return {
346
- get: (mask) => mask ? store.update(mask).get() : store.snapshot(),
517
+ function exposeStore(store, opts = {}) {
518
+ const get = ((mask) => mask ? store.update(mask).get() : store.snapshot());
519
+ const api = {
520
+ get,
347
521
  set: (path, value) => {
348
522
  let node = store.node;
349
523
  for (const k of path)
@@ -357,25 +531,127 @@ function exposeStore(store) {
357
531
  node.replace(value);
358
532
  },
359
533
  changed: store.listen(),
534
+ changedPaths: store.listenPaths(),
535
+ };
536
+ if (opts.push) {
537
+ api.patches = createPatchesListen(store);
538
+ api.changedData = createChangedDataListen(store);
539
+ }
540
+ return api;
541
+ }
542
+ function isRemoteListen(listen) {
543
+ return typeof listen?.on == "function" || typeof listen?.addListen == "function";
544
+ }
545
+ function subscribeRemote(listen, cb) {
546
+ let handle;
547
+ if (typeof listen?.on == "function")
548
+ handle = listen.on(cb);
549
+ else if (typeof listen?.addListen == "function")
550
+ handle = listen.addListen(cb);
551
+ else
552
+ return () => { };
553
+ return () => {
554
+ if (typeof handle == "function")
555
+ handle();
556
+ else if (typeof handle?.off == "function")
557
+ handle.off();
558
+ else if (typeof listen?.off == "function")
559
+ listen.off(cb);
560
+ else if (typeof listen?.removeListen == "function")
561
+ listen.removeListen(cb);
360
562
  };
361
563
  }
362
564
  function createStoreMirror(remote, initial = {}, opts = {}) {
363
565
  const store = createStore(initial, opts);
566
+ const makeReport = (subOpts) => (error) => {
567
+ if (subOpts.onError)
568
+ subOpts.onError(error);
569
+ else
570
+ setTimeout(() => { throw error; }, 0);
571
+ };
572
+ async function pull(mask) {
573
+ const snap = await remote.get(mask);
574
+ applyMask(store.state, mask, snap);
575
+ }
364
576
  async function sync(mask, subOpts = { current: true }) {
365
- async function pull() {
366
- const snap = await remote.get(mask);
367
- applyMask(store.state, mask, snap);
368
- }
577
+ const baseMask = mask ?? true;
578
+ const report = makeReport(subOpts);
579
+ if (subOpts.current !== false)
580
+ await pull(baseMask);
581
+ let pendingMask = undefined;
582
+ let chain = Promise.resolve();
583
+ const drained = createDrained(() => {
584
+ const nextMask = pendingMask === undefined ? baseMask : pendingMask;
585
+ pendingMask = undefined;
586
+ chain = chain.then(() => pull(nextMask)).catch(report);
587
+ }, subOpts.drain);
588
+ const queue = (nextMask) => {
589
+ pendingMask = pendingMask === undefined ? nextMask : mergeMasks(pendingMask, nextMask);
590
+ drained.push();
591
+ };
592
+ const changedPaths = remote.changedPaths;
593
+ const usePaths = subOpts.partial !== false && isRemoteListen(changedPaths);
594
+ const off = usePaths
595
+ ? subscribeRemote(changedPaths, (change) => {
596
+ const nextMask = intersectMaskWithPaths(baseMask, change?.paths);
597
+ if (nextMask !== undefined)
598
+ queue(nextMask);
599
+ })
600
+ : subscribeRemote(remote.changed, () => queue(baseMask));
601
+ return () => { drained.close(); off(); };
602
+ }
603
+ async function syncPatches(mask, subOpts = { current: true }) {
604
+ if (!isRemoteListen(remote.patches))
605
+ throw new Error("createStoreMirror.syncPatches: remote.patches is not exposed");
606
+ const baseMask = mask ?? true;
607
+ const report = makeReport(subOpts);
369
608
  if (subOpts.current !== false)
370
- await pull();
371
- const drained = createDrained(() => { void pull(); }, subOpts.drain);
372
- const changed = remote.changed;
373
- const off = typeof changed?.on == "function"
374
- ? changed.on(() => drained.push())
375
- : typeof changed?.addListen == "function"
376
- ? changed.addListen(() => drained.push())
377
- : (() => { });
378
- return () => { drained.close(); off?.(); };
609
+ await pull(baseMask);
610
+ const pending = [];
611
+ const drained = createDrained(() => {
612
+ const batch = pending.splice(0);
613
+ try {
614
+ applyStorePatches(store, batch);
615
+ }
616
+ catch (e) {
617
+ report(e);
618
+ }
619
+ }, subOpts.drain);
620
+ const off = subscribeRemote(remote.patches, (patch) => {
621
+ const next = patchesForMask(patch, baseMask);
622
+ if (next.length == 0)
623
+ return;
624
+ pending.push(...next);
625
+ drained.push();
626
+ });
627
+ return () => { drained.close(); off(); };
628
+ }
629
+ async function syncChangedData(mask, subOpts = { current: true }) {
630
+ if (!isRemoteListen(remote.changedData))
631
+ throw new Error("createStoreMirror.syncChangedData: remote.changedData is not exposed");
632
+ const baseMask = mask ?? true;
633
+ const report = makeReport(subOpts);
634
+ if (subOpts.current !== false)
635
+ await pull(baseMask);
636
+ const pending = [];
637
+ const drained = createDrained(() => {
638
+ const batch = pending.splice(0);
639
+ try {
640
+ for (const change of batch) {
641
+ const nextMask = intersectMaskWithPaths(baseMask, maskPaths(change?.mask ?? true));
642
+ if (nextMask !== undefined)
643
+ applyMask(store.state, nextMask, change.data);
644
+ }
645
+ }
646
+ catch (e) {
647
+ report(e);
648
+ }
649
+ }, subOpts.drain);
650
+ const off = subscribeRemote(remote.changedData, (change) => {
651
+ pending.push(change);
652
+ drained.push();
653
+ });
654
+ return () => { drained.close(); off(); };
379
655
  }
380
- return Object.assign(store, { sync });
656
+ return Object.assign(store, { sync, syncPatches, syncChangedData });
381
657
  }
@@ -33,10 +33,15 @@ export type ListenStoreOptions<T> = ListenOptions<T> & {
33
33
  };
34
34
  export declare function getListenByOn(fn: any): any;
35
35
  export declare function isListenOn(fn: any): boolean;
36
+ export declare function registerListenOn(on: Function, api: any): void;
37
+ export type ListenOnBrand<Z extends any[] = any[]> = {
38
+ readonly [LISTEN_ON_BRAND]: Z;
39
+ };
36
40
  export declare function funcListenCore<T>(options?: ListenCoreOptions<T>): {
37
41
  func: Listener<NormalizeTuple<T>>;
38
42
  has: (k: key) => boolean;
39
43
  on: ListenOn<NormalizeTuple<T>>;
44
+ off: (k: Listener<NormalizeTuple<T>> | null | key) => void;
40
45
  addListen: (cb: Listener<NormalizeTuple<T>>, opts?: {
41
46
  key?: key;
42
47
  }) => () => void;
@@ -58,11 +63,12 @@ export declare function funcListenCallbackBase<T>(b: (e: Listener<NormalizeTuple
58
63
  onClose: (cb: cbClose) => () => void;
59
64
  removeEventClose: (cb: cbClose) => void;
60
65
  on: ListenOn<NormalizeTuple<T>>;
66
+ off: (k: key | Listener<NormalizeTuple<T>> | null) => void;
61
67
  addListen: (cb: Listener<NormalizeTuple<T>>, opts?: {
62
68
  cbClose?: cbClose;
63
69
  key?: key;
64
70
  }) => () => void;
65
- removeListen: (k: key | Listener<NormalizeTuple<T>> | null) => void;
71
+ removeListen: (k: Listener<NormalizeTuple<T>> | null | key) => void;
66
72
  once: (cb: Listener<NormalizeTuple<T>>, opts?: {
67
73
  key?: key;
68
74
  }) => () => void;
@@ -79,6 +85,7 @@ export declare function funcListenCallbackFast<T>(a: (e: (Listener<NormalizeTupl
79
85
  onClose: (cb: cbClose) => () => void;
80
86
  removeEventClose: (cb: cbClose) => void;
81
87
  on: ListenOn<NormalizeTuple<T>>;
88
+ off: (k: key | Listener<NormalizeTuple<T>> | null) => void;
82
89
  addListen: (cb: Listener<NormalizeTuple<T>>, opts?: {
83
90
  cbClose?: cbClose;
84
91
  key?: key;
@@ -100,6 +107,7 @@ export declare function UseListen<T>(data?: ListenOptions<T>): readonly [(...a:
100
107
  onClose: (cb: cbClose) => () => void;
101
108
  removeEventClose: (cb: cbClose) => void;
102
109
  on: ListenOn<NormalizeTuple<T>>;
110
+ off: (k: key | Listener<NormalizeTuple<T>> | null) => void;
103
111
  addListen: (cb: Listener<NormalizeTuple<T>>, opts?: {
104
112
  cbClose?: cbClose;
105
113
  key?: key;
@@ -118,6 +126,7 @@ export declare function withStoreListen<T>(base: ListenApi<T>, currentProvider:
118
126
  key?: key;
119
127
  current?: ListenCurrent<NormalizeTuple<T>>;
120
128
  }) => () => void;
129
+ removeListen: (k: Listener<NormalizeTuple<T>> | null | key) => void;
121
130
  once: (cb: Listener<NormalizeTuple<T>>, opts?: {
122
131
  key?: key;
123
132
  current?: ListenCurrent<NormalizeTuple<T>>;
@@ -130,7 +139,7 @@ export declare function withStoreListen<T>(base: ListenApi<T>, currentProvider:
130
139
  eventClose: (cb: cbClose) => () => void;
131
140
  onClose: (cb: cbClose) => () => void;
132
141
  removeEventClose: (cb: cbClose) => void;
133
- removeListen: (k: key | Listener<NormalizeTuple<T>> | null) => void;
142
+ off: (k: key | Listener<NormalizeTuple<T>> | null) => void;
134
143
  count: () => number;
135
144
  };
136
145
  export type ListenStoreApi<T> = ReturnType<typeof withStoreListen<T>>;
@@ -141,6 +150,7 @@ export declare function funcListenCallbackStore<T>(b: (e: Listener<NormalizeTupl
141
150
  key?: key;
142
151
  current?: ListenCurrent<NormalizeTuple<T>> | undefined;
143
152
  }) => () => void;
153
+ removeListen: (k: key | Listener<NormalizeTuple<T>> | null) => void;
144
154
  once: (cb: Listener<NormalizeTuple<T>>, opts?: {
145
155
  key?: key;
146
156
  current?: ListenCurrent<NormalizeTuple<T>> | undefined;
@@ -153,7 +163,7 @@ export declare function funcListenCallbackStore<T>(b: (e: Listener<NormalizeTupl
153
163
  eventClose: (cb: cbClose) => () => void;
154
164
  onClose: (cb: cbClose) => () => void;
155
165
  removeEventClose: (cb: cbClose) => void;
156
- removeListen: (k: key | Listener<NormalizeTuple<T>> | null) => void;
166
+ off: (k: key | Listener<NormalizeTuple<T>> | null) => void;
157
167
  count: () => number;
158
168
  };
159
169
  export declare function UseListenStore<T>(data: ListenStoreOptions<T>): readonly [(...a: NormalizeTuple<T>) => void, {
@@ -163,6 +173,7 @@ export declare function UseListenStore<T>(data: ListenStoreOptions<T>): readonly
163
173
  key?: key;
164
174
  current?: ListenCurrent<NormalizeTuple<T>> | undefined;
165
175
  }) => () => void;
176
+ removeListen: (k: key | Listener<NormalizeTuple<T>> | null) => void;
166
177
  once: (cb: Listener<NormalizeTuple<T>>, opts?: {
167
178
  key?: key;
168
179
  current?: ListenCurrent<NormalizeTuple<T>> | undefined;
@@ -175,13 +186,14 @@ export declare function UseListenStore<T>(data: ListenStoreOptions<T>): readonly
175
186
  eventClose: (cb: cbClose) => () => void;
176
187
  onClose: (cb: cbClose) => () => void;
177
188
  removeEventClose: (cb: cbClose) => void;
178
- removeListen: (k: key | Listener<NormalizeTuple<T>> | null) => void;
189
+ off: (k: key | Listener<NormalizeTuple<T>> | null) => void;
179
190
  count: () => number;
180
191
  }];
181
192
  export declare function toListen2<T>(full: ListenApi<T>): {
182
193
  on: (cb: Listener<NormalizeTuple<T>>, opts?: {
183
194
  key?: key;
184
195
  }) => () => void;
196
+ off: (k: Listener<NormalizeTuple<T>> | null | key) => void;
185
197
  close: () => void;
186
198
  count: () => number;
187
199
  };
@@ -190,6 +202,7 @@ export declare function UseListen2<T>(data?: ListenOptions<T>): readonly [(...a:
190
202
  on: (cb: Listener<NormalizeTuple<T>>, opts?: {
191
203
  key?: key;
192
204
  } | undefined) => () => void;
205
+ off: (k: key | Listener<NormalizeTuple<T>> | null) => void;
193
206
  close: () => void;
194
207
  count: () => number;
195
208
  }];
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.funcListenCallback = void 0;
4
4
  exports.getListenByOn = getListenByOn;
5
5
  exports.isListenOn = isListenOn;
6
+ exports.registerListenOn = registerListenOn;
6
7
  exports.funcListenCore = funcListenCore;
7
8
  exports.funcListenCallbackBase = funcListenCallbackBase;
8
9
  exports.funcListenCallbackFast = funcListenCallbackFast;
@@ -16,6 +17,7 @@ exports.isListenCallback = isListenCallback;
16
17
  const listenByOn = new WeakMap();
17
18
  function getListenByOn(fn) { return typeof fn == 'function' ? listenByOn.get(fn) : undefined; }
18
19
  function isListenOn(fn) { return typeof fn == 'function' && listenByOn.has(fn); }
20
+ function registerListenOn(on, api) { listenByOn.set(on, api); }
19
21
  function funcListenCore(options = {}) {
20
22
  const { fast = true, onRemove, event } = options;
21
23
  const subs = new Map();
@@ -68,8 +70,7 @@ function funcListenCore(options = {}) {
68
70
  event?.('add', subs.size, api);
69
71
  return function off() { removeOne(k); };
70
72
  }),
71
- addListen: (cb, opts = {}) => api.on(cb, opts),
72
- removeListen: (k) => {
73
+ off: (k) => {
73
74
  if (typeof k == 'function') {
74
75
  for (const [kk, cb] of [...subs])
75
76
  if (cb === k)
@@ -79,6 +80,8 @@ function funcListenCore(options = {}) {
79
80
  if (k != null)
80
81
  removeOne(k);
81
82
  },
83
+ addListen: (cb, opts = {}) => api.on(cb, opts),
84
+ removeListen: (k) => api.off(k),
82
85
  once: (cb, opts = {}) => {
83
86
  let off = () => { };
84
87
  off = api.on(((...e) => { off(); cb(...e); }), opts);
@@ -151,8 +154,9 @@ function funcListenCallbackBase(b, options = {}) {
151
154
  event?.('add', core.count(), api);
152
155
  return off;
153
156
  }),
157
+ off: core.off,
154
158
  addListen: (cb, opts = {}) => api.on(cb, opts),
155
- removeListen: core.removeListen,
159
+ removeListen: (k) => api.off(k),
156
160
  once: (cb, opts = {}) => {
157
161
  let off = () => { };
158
162
  off = api.on(((...e) => { off(); cb(...e); }), opts);
@@ -193,6 +197,7 @@ function withStoreListen(base, currentProvider) {
193
197
  return off;
194
198
  }),
195
199
  addListen: (cb, opts = {}) => api.on(cb, opts),
200
+ removeListen: (k) => api.off(k),
196
201
  once: (cb, opts = {}) => {
197
202
  if (opts.current) {
198
203
  const m = currentValue(opts.current);
@@ -226,6 +231,7 @@ function UseListenStore(data) {
226
231
  function toListen2(full) {
227
232
  return {
228
233
  on: (cb, opts) => full.on(cb, opts),
234
+ off: (k) => full.off(k),
229
235
  close: () => full.close(),
230
236
  count: () => full.count(),
231
237
  };
@@ -33,6 +33,7 @@ export declare function funcListenCallbackSnapshot<T extends realSocket2<any | a
33
33
  onClose: (cb: () => void) => () => void;
34
34
  removeEventClose: (cb: () => void) => void;
35
35
  on: import("./Listen3").ListenOn<[data: getTypeCallback<T>, memo: T3]>;
36
+ off: (k: (string | symbol) | import("./Listen3").Listener<[data: getTypeCallback<T>, memo: T3]> | null) => void;
36
37
  addListen: (cb: import("./Listen3").Listener<[data: getTypeCallback<T>, memo: T3]>, opts?: {
37
38
  cbClose?: () => void;
38
39
  key?: string | symbol;
@@ -13,6 +13,7 @@ export declare function SocketServerHook(opt?: {
13
13
  onClose: (cb: () => void) => () => void;
14
14
  removeEventClose: (cb: () => void) => void;
15
15
  on: import("./Listen3").ListenOn<[unknown]>;
16
+ off: (k: (string | symbol) | import("./Listen3").Listener<[unknown]> | null) => void;
16
17
  addListen: (cb: import("./Listen3").Listener<[unknown]>, opts?: {
17
18
  cbClose?: () => void;
18
19
  key?: string | symbol;
@@ -34,6 +35,7 @@ export declare function SocketServerHook(opt?: {
34
35
  onClose: (cb: () => void) => () => void;
35
36
  removeEventClose: (cb: () => void) => void;
36
37
  on: import("./Listen3").ListenOn<[unknown]>;
38
+ off: (k: (string | symbol) | import("./Listen3").Listener<[unknown]> | null) => void;
37
39
  addListen: (cb: import("./Listen3").Listener<[unknown]>, opts?: {
38
40
  cbClose?: () => void;
39
41
  key?: string | symbol;
@@ -55,6 +57,7 @@ export declare function WebSocketServerHook(s: ReturnType<typeof SocketServerHoo
55
57
  on: (z: (...args: any[]) => void) => import("../rcp/listen-socket").tSubHandle;
56
58
  once: (z: (...args: any[]) => void) => import("../rcp/listen-socket").tSubHandle;
57
59
  close: () => void;
60
+ off: () => boolean;
58
61
  removeCallback: () => boolean;
59
62
  };
60
63
  };
@@ -10,6 +10,7 @@ export declare function UseListenTransform<TSource extends any[], TTarget extend
10
10
  onClose: (cb: () => void) => () => void;
11
11
  removeEventClose: (cb: () => void) => void;
12
12
  on: import("./Listen3").ListenOn<NormalizeTuple<TTarget>>;
13
+ off: (k: (string | symbol) | Listener<NormalizeTuple<TTarget>> | null) => void;
13
14
  addListen: (cb: Listener<NormalizeTuple<TTarget>>, opts?: {
14
15
  cbClose?: () => void;
15
16
  key?: string | symbol;
@@ -0,0 +1,45 @@
1
+ import { NormalizeTuple } from './Listen3';
2
+ import { ListenReplayApi, ReplayEvent } from './replay-listen';
3
+ export type ConflateOpts<Z extends any[] = any[]> = {
4
+ pending: () => number;
5
+ highWater: number;
6
+ lowWater?: number;
7
+ pollMs?: number;
8
+ keyOf?: (...event: Z) => PropertyKey | null | undefined;
9
+ maxKeys?: number;
10
+ };
11
+ export declare function conflateReplay<T>(replay: ListenReplayApi<T>, opts: ConflateOpts<NormalizeTuple<T>>): {
12
+ api: {
13
+ line: {
14
+ func: import("./Listen3").Listener<[ReplayEvent<NormalizeTuple<T>>]>;
15
+ isRun: () => boolean;
16
+ run: () => void;
17
+ close: () => void;
18
+ eventClose: (cb: () => void) => () => void;
19
+ onClose: (cb: () => void) => () => void;
20
+ removeEventClose: (cb: () => void) => void;
21
+ on: import("./Listen3").ListenOn<[ReplayEvent<NormalizeTuple<T>>]>;
22
+ off: (k: (string | symbol) | import("./Listen3").Listener<[ReplayEvent<NormalizeTuple<T>>]> | null) => void;
23
+ addListen: (cb: import("./Listen3").Listener<[ReplayEvent<NormalizeTuple<T>>]>, opts?: {
24
+ cbClose?: () => void;
25
+ key?: string | symbol;
26
+ }) => () => void;
27
+ removeListen: (k: (string | symbol) | import("./Listen3").Listener<[ReplayEvent<NormalizeTuple<T>>]> | null) => void;
28
+ once: (cb: import("./Listen3").Listener<[ReplayEvent<NormalizeTuple<T>>]>, opts?: {
29
+ key?: string | symbol;
30
+ }) => () => void;
31
+ count: () => number;
32
+ readonly getAllKeys: (string | symbol)[];
33
+ };
34
+ since: (seq: number) => ReplayEvent<NormalizeTuple<T>>[] | null;
35
+ keyframe: () => ReplayEvent<NormalizeTuple<T>> | null;
36
+ };
37
+ close: () => void;
38
+ stats: () => {
39
+ conflating: boolean;
40
+ dropped: number;
41
+ keyframes: number;
42
+ coalesced: number;
43
+ flushes: number;
44
+ };
45
+ };