wenay-common2 1.0.53 → 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.
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.conflateReplay = conflateReplay;
4
+ const Listen3_1 = require("./Listen3");
5
+ const replay_wire_1 = require("./replay-wire");
6
+ function conflateReplay(replay, opts) {
7
+ const { pending, highWater, lowWater = 0, pollMs = 25, keyOf, maxKeys = 1024 } = opts;
8
+ if (!replay.hasKeyframe)
9
+ throw new TypeError('conflateReplay: нужен current-провайдер (keyframe recovery)');
10
+ const gate = (0, Listen3_1.funcListenCallbackBase)(() => { });
11
+ gate.run();
12
+ let conflating = false;
13
+ let closed = false;
14
+ let dropped = 0;
15
+ let keyframes = 0;
16
+ let coalesced = 0;
17
+ let flushes = 0;
18
+ let held = null;
19
+ let timer = null;
20
+ function stopPoll() {
21
+ if (timer) {
22
+ clearInterval(timer);
23
+ timer = null;
24
+ }
25
+ }
26
+ function startPoll() {
27
+ if (timer || closed)
28
+ return;
29
+ timer = setInterval(recoverIfDrained, pollMs);
30
+ timer.unref?.();
31
+ }
32
+ function recoverIfDrained() {
33
+ if (!conflating || closed)
34
+ return;
35
+ if (pending() > lowWater)
36
+ return;
37
+ conflating = false;
38
+ stopPoll();
39
+ if (held) {
40
+ const tail = [...held.values()];
41
+ held = null;
42
+ flushes++;
43
+ for (const ev of tail)
44
+ gate.func(ev);
45
+ return;
46
+ }
47
+ const kf = replay.keyframe();
48
+ if (kf) {
49
+ keyframes++;
50
+ gate.func(kf);
51
+ }
52
+ }
53
+ function absorb(ev) {
54
+ const k = keyOf(...ev.event);
55
+ if (k == null || (!held.has(k) && held.size >= maxKeys)) {
56
+ dropped += held.size + 1;
57
+ held = null;
58
+ return;
59
+ }
60
+ if (held.delete(k))
61
+ coalesced++;
62
+ held.set(k, ev);
63
+ }
64
+ const offLine = replay.line.on(function gateForward(ev) {
65
+ if (closed)
66
+ return;
67
+ if (!conflating && pending() > highWater) {
68
+ conflating = true;
69
+ held = keyOf ? new Map() : null;
70
+ startPoll();
71
+ }
72
+ if (conflating) {
73
+ if (held) {
74
+ absorb(ev);
75
+ recoverIfDrained();
76
+ return;
77
+ }
78
+ recoverIfDrained();
79
+ if (conflating)
80
+ dropped++;
81
+ return;
82
+ }
83
+ gate.func(ev);
84
+ });
85
+ function close() {
86
+ if (closed)
87
+ return;
88
+ closed = true;
89
+ held = null;
90
+ stopPoll();
91
+ offLine();
92
+ gate.close();
93
+ }
94
+ return {
95
+ api: { ...(0, replay_wire_1.exposeReplay)(replay), line: gate },
96
+ close,
97
+ stats: () => ({ conflating, dropped, keyframes, coalesced, flushes }),
98
+ };
99
+ }
@@ -0,0 +1,55 @@
1
+ import { Listener, NormalizeTuple } from './Listen3';
2
+ import { ListenOnReplay, ListenReplayApi, ReplayEvent } from './replay-listen';
3
+ export type ReplayStorage<Z extends any[] = any[]> = {
4
+ putEvent: (ev: ReplayEvent<Z>) => void;
5
+ putKeyframe: (kf: ReplayEvent<Z>) => void;
6
+ getKeyframe: (at?: {
7
+ seq?: number;
8
+ ts?: number;
9
+ }) => ReplayEvent<Z> | undefined;
10
+ getEvents: (from: number, to: number) => ReplayEvent<Z>[];
11
+ };
12
+ export declare function createMemoryReplayStorage<Z extends any[] = any[]>(opts?: {
13
+ maxEvents?: number;
14
+ maxKeyframes?: number;
15
+ }): {
16
+ putEvent: (ev: ReplayEvent<Z>) => void;
17
+ putKeyframe: (kf: ReplayEvent<Z>) => void;
18
+ getKeyframe: (at?: {
19
+ seq?: number;
20
+ ts?: number;
21
+ }) => ReplayEvent<Z>;
22
+ getEvents: (from: number, to: number) => ReplayEvent<Z>[];
23
+ size: () => {
24
+ events: number;
25
+ keyframes: number;
26
+ };
27
+ };
28
+ export type ArchiveReplayOpts<Z extends any[]> = {
29
+ storage: ReplayStorage<Z>;
30
+ everyEvents?: number;
31
+ everyMs?: number;
32
+ };
33
+ export declare function archiveReplay<T>(replay: ListenReplayApi<T>, opts: ArchiveReplayOpts<NormalizeTuple<T>>): {
34
+ close: () => void;
35
+ stats: () => {
36
+ events: number;
37
+ keyframes: number;
38
+ };
39
+ };
40
+ export type HistorySubscribeOpts = {
41
+ since?: number;
42
+ ts?: number;
43
+ onSeq?: (seq: number) => void;
44
+ };
45
+ export declare function openHistory<Z extends any[]>(storage: ReplayStorage<Z>, live?: {
46
+ on: ListenOnReplay<Z>;
47
+ }): {
48
+ at: (where?: {
49
+ seq?: number;
50
+ ts?: number;
51
+ }) => ReplayEvent<Z>[] | undefined;
52
+ subscribe: (cb: Listener<Z>, opts?: HistorySubscribeOpts) => (() => void) & {
53
+ seq: () => number;
54
+ };
55
+ };
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMemoryReplayStorage = createMemoryReplayStorage;
4
+ exports.archiveReplay = archiveReplay;
5
+ exports.openHistory = openHistory;
6
+ function upperBy(arr, k, v) {
7
+ let lo = 0;
8
+ let hi = arr.length;
9
+ while (lo < hi) {
10
+ const mid = (lo + hi) >> 1;
11
+ if (k(arr[mid]) <= v)
12
+ lo = mid + 1;
13
+ else
14
+ hi = mid;
15
+ }
16
+ return lo;
17
+ }
18
+ const bySeq = (e) => e.seq;
19
+ const byTs = (e) => e.ts;
20
+ function createMemoryReplayStorage(opts = {}) {
21
+ const { maxEvents, maxKeyframes } = opts;
22
+ const events = [];
23
+ const keyframes = [];
24
+ return {
25
+ putEvent: (ev) => {
26
+ events.push(ev);
27
+ if (maxEvents && events.length > maxEvents)
28
+ events.shift();
29
+ },
30
+ putKeyframe: (kf) => {
31
+ keyframes.push(kf);
32
+ if (maxKeyframes && keyframes.length > maxKeyframes)
33
+ keyframes.shift();
34
+ },
35
+ getKeyframe: (at = {}) => {
36
+ const end = at.ts != null ? upperBy(keyframes, byTs, at.ts) : upperBy(keyframes, bySeq, at.seq ?? Infinity);
37
+ return keyframes[end - 1];
38
+ },
39
+ getEvents: (from, to) => events.slice(upperBy(events, bySeq, from), upperBy(events, bySeq, to)),
40
+ size: () => ({ events: events.length, keyframes: keyframes.length }),
41
+ };
42
+ }
43
+ function archiveReplay(replay, opts) {
44
+ const { storage, everyEvents = 64, everyMs } = opts;
45
+ if (!replay.hasKeyframe)
46
+ throw new TypeError('archiveReplay: нужен current-провайдер (keyframe)');
47
+ let events = 0;
48
+ let keyframes = 0;
49
+ let lastKfSeq = 0;
50
+ let lastKfTs = 0;
51
+ function takeKeyframe() {
52
+ const kf = replay.keyframe();
53
+ if (!kf)
54
+ return;
55
+ storage.putKeyframe(kf);
56
+ keyframes++;
57
+ lastKfSeq = kf.seq;
58
+ lastKfTs = kf.ts;
59
+ }
60
+ takeKeyframe();
61
+ const offLine = replay.line.on(function archiveLineEvent(ev) {
62
+ storage.putEvent(ev);
63
+ events++;
64
+ const due = ev.seq - lastKfSeq >= everyEvents || (everyMs != null && ev.ts - lastKfTs >= everyMs);
65
+ if (due)
66
+ takeKeyframe();
67
+ });
68
+ return {
69
+ close: () => offLine(),
70
+ stats: () => ({ events, keyframes }),
71
+ };
72
+ }
73
+ function openHistory(storage, live) {
74
+ function at(where = {}) {
75
+ const kf = storage.getKeyframe(where);
76
+ if (!kf)
77
+ return undefined;
78
+ let tail = storage.getEvents(kf.seq, where.seq ?? Infinity);
79
+ if (where.ts != null) {
80
+ const cut = tail.findIndex(ev => ev.ts > where.ts);
81
+ if (cut >= 0)
82
+ tail = tail.slice(0, cut);
83
+ }
84
+ return [kf, ...tail];
85
+ }
86
+ function subscribe(cb, opts = {}) {
87
+ const { since, ts, onSeq } = opts;
88
+ let last = since ?? 0;
89
+ function deliver(ev) {
90
+ if (ev.seq <= last)
91
+ return;
92
+ last = ev.seq;
93
+ cb(...ev.event);
94
+ onSeq?.(ev.seq);
95
+ }
96
+ function deliverFromKeyframe(envs) {
97
+ if (!envs)
98
+ return;
99
+ last = envs[0].seq - 1;
100
+ for (const ev of envs)
101
+ deliver(ev);
102
+ }
103
+ if (since != null) {
104
+ const tail = storage.getEvents(since, Infinity);
105
+ if (tail.length && tail[0].seq != since + 1)
106
+ deliverFromKeyframe(at({}));
107
+ else
108
+ for (const ev of tail)
109
+ deliver(ev);
110
+ }
111
+ else {
112
+ deliverFromKeyframe(at(ts != null ? { ts } : {}));
113
+ }
114
+ let offLive = null;
115
+ if (live)
116
+ offLive = live.on(cb, { since: last, onSeq: function trackSeq(s) { last = s; onSeq?.(s); } });
117
+ function off() { offLive?.(); }
118
+ return Object.assign(off, {
119
+ seq: () => last,
120
+ });
121
+ }
122
+ return { at, subscribe };
123
+ }
@@ -0,0 +1,4 @@
1
+ export * from './replay-listen';
2
+ export * from './replay-wire';
3
+ export * from './replay-conflate';
4
+ export * from './replay-history';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./replay-listen"), exports);
18
+ __exportStar(require("./replay-wire"), exports);
19
+ __exportStar(require("./replay-conflate"), exports);
20
+ __exportStar(require("./replay-history"), exports);
@@ -0,0 +1,114 @@
1
+ import { Listener, ListenApi, ListenCurrent, ListenCurrentProvider, ListenOnBrand, ListenOptions, NormalizeTuple } from './Listen3';
2
+ type key = string | symbol;
3
+ type cbClose = () => void;
4
+ export type ReplayEvent<Z extends any[] = any[]> = {
5
+ seq: number;
6
+ ts: number;
7
+ event: Z;
8
+ };
9
+ export type ReplayListenOptions<Z extends any[]> = {
10
+ current?: ListenCurrentProvider<Z>;
11
+ history?: number;
12
+ getSince?: (seq: number) => ReplayEvent<Z>[] | undefined;
13
+ onJournal?: (ev: ReplayEvent<Z>) => void;
14
+ now?: () => number;
15
+ };
16
+ type ReplayOnOptions<Z extends any[]> = {
17
+ cbClose?: cbClose;
18
+ key?: key;
19
+ current?: ListenCurrent<Z>;
20
+ since?: number;
21
+ onSeq?: (seq: number) => void;
22
+ };
23
+ export type ListenOnReplay<Z extends any[] = any[]> = ((cb: Listener<Z>, opts?: ReplayOnOptions<Z>) => (() => void)) & ListenOnBrand<Z>;
24
+ export declare function withReplayListen<T>(base: ListenApi<T>, options?: ReplayListenOptions<NormalizeTuple<T>>): {
25
+ func: Listener<NormalizeTuple<T>>;
26
+ head: () => number;
27
+ getSince: (seq: number) => ReplayEvent<NormalizeTuple<T>>[] | undefined;
28
+ line: {
29
+ func: Listener<[ReplayEvent<NormalizeTuple<T>>]>;
30
+ isRun: () => boolean;
31
+ run: () => void;
32
+ close: () => void;
33
+ eventClose: (cb: () => void) => () => void;
34
+ onClose: (cb: () => void) => () => void;
35
+ removeEventClose: (cb: () => void) => void;
36
+ on: import("./Listen3").ListenOn<[ReplayEvent<NormalizeTuple<T>>]>;
37
+ off: (k: (string | symbol) | Listener<[ReplayEvent<NormalizeTuple<T>>]> | null) => void;
38
+ addListen: (cb: Listener<[ReplayEvent<NormalizeTuple<T>>]>, opts?: {
39
+ cbClose?: () => void;
40
+ key?: string | symbol;
41
+ }) => () => void;
42
+ removeListen: (k: (string | symbol) | Listener<[ReplayEvent<NormalizeTuple<T>>]> | null) => void;
43
+ once: (cb: Listener<[ReplayEvent<NormalizeTuple<T>>]>, opts?: {
44
+ key?: string | symbol;
45
+ }) => () => void;
46
+ count: () => number;
47
+ readonly getAllKeys: (string | symbol)[];
48
+ };
49
+ hasKeyframe: boolean;
50
+ keyframe: () => ReplayEvent<NormalizeTuple<T>> | undefined;
51
+ on: ListenOnReplay<NormalizeTuple<T>>;
52
+ addListen: (cb: Listener<NormalizeTuple<T>>, opts?: ReplayOnOptions<NormalizeTuple<T>>) => () => void;
53
+ removeListen: (k: Listener<NormalizeTuple<T>> | null | key) => void;
54
+ once: (cb: Listener<NormalizeTuple<T>>, opts?: {
55
+ key?: key;
56
+ current?: ListenCurrent<NormalizeTuple<T>>;
57
+ }) => () => void;
58
+ getAllKeys: key[];
59
+ isRun: () => boolean;
60
+ run: () => void;
61
+ close: () => void;
62
+ eventClose: (cb: () => void) => () => void;
63
+ onClose: (cb: () => void) => () => void;
64
+ removeEventClose: (cb: () => void) => void;
65
+ off: (k: (string | symbol) | Listener<NormalizeTuple<T>> | null) => void;
66
+ count: () => number;
67
+ };
68
+ export type ListenReplayApi<T> = ReturnType<typeof withReplayListen<T>>;
69
+ export type ReplayListenUseOptions<T> = ListenOptions<T> & ReplayListenOptions<NormalizeTuple<T>>;
70
+ export declare function UseReplayListen<T>(options?: ReplayListenUseOptions<T>): readonly [(...a: NormalizeTuple<T>) => void, {
71
+ func: Listener<NormalizeTuple<T>>;
72
+ head: () => number;
73
+ getSince: (seq: number) => ReplayEvent<NormalizeTuple<T>>[] | undefined;
74
+ line: {
75
+ func: Listener<[ReplayEvent<NormalizeTuple<T>>]>;
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("./Listen3").ListenOn<[ReplayEvent<NormalizeTuple<T>>]>;
83
+ off: (k: (string | symbol) | Listener<[ReplayEvent<NormalizeTuple<T>>]> | null) => void;
84
+ addListen: (cb: Listener<[ReplayEvent<NormalizeTuple<T>>]>, opts?: {
85
+ cbClose?: () => void;
86
+ key?: string | symbol;
87
+ }) => () => void;
88
+ removeListen: (k: (string | symbol) | Listener<[ReplayEvent<NormalizeTuple<T>>]> | null) => void;
89
+ once: (cb: Listener<[ReplayEvent<NormalizeTuple<T>>]>, opts?: {
90
+ key?: string | symbol;
91
+ }) => () => void;
92
+ count: () => number;
93
+ readonly getAllKeys: (string | symbol)[];
94
+ };
95
+ hasKeyframe: boolean;
96
+ keyframe: () => ReplayEvent<NormalizeTuple<T>> | undefined;
97
+ on: ListenOnReplay<NormalizeTuple<T>>;
98
+ addListen: (cb: Listener<NormalizeTuple<T>>, opts?: ReplayOnOptions<NormalizeTuple<T>>) => () => void;
99
+ removeListen: (k: key | Listener<NormalizeTuple<T>> | null) => void;
100
+ once: (cb: Listener<NormalizeTuple<T>>, opts?: {
101
+ key?: key;
102
+ current?: ListenCurrent<NormalizeTuple<T>> | undefined;
103
+ }) => () => void;
104
+ getAllKeys: key[];
105
+ isRun: () => boolean;
106
+ run: () => void;
107
+ close: () => void;
108
+ eventClose: (cb: () => void) => () => void;
109
+ onClose: (cb: () => void) => () => void;
110
+ removeEventClose: (cb: () => void) => void;
111
+ off: (k: (string | symbol) | Listener<NormalizeTuple<T>> | null) => void;
112
+ count: () => number;
113
+ }];
114
+ export {};
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withReplayListen = withReplayListen;
4
+ exports.UseReplayListen = UseReplayListen;
5
+ const Listen3_1 = require("./Listen3");
6
+ function withReplayListen(base, options = {}) {
7
+ const { current, history = 0, getSince, onJournal, now = Date.now } = options;
8
+ let head = 0;
9
+ const ring = [];
10
+ let emitting = null;
11
+ const line = (0, Listen3_1.funcListenCallbackBase)(() => { });
12
+ line.run();
13
+ function journalSince(seq) {
14
+ if (getSince)
15
+ return getSince(seq);
16
+ if (seq > head)
17
+ return undefined;
18
+ if (seq == head)
19
+ return [];
20
+ const oldest = Math.max(1, head - history + 1);
21
+ if (seq + 1 < oldest)
22
+ return undefined;
23
+ const out = [];
24
+ for (let s = seq + 1; s <= head; s++)
25
+ out.push(ring[(s - 1) % history]);
26
+ return out;
27
+ }
28
+ function currentValue(c) {
29
+ if (typeof c == 'function')
30
+ return c();
31
+ return c ? current?.() : undefined;
32
+ }
33
+ const api = {
34
+ ...base,
35
+ func: function emitJournaled(...e) {
36
+ const ev = { seq: ++head, ts: now(), event: e };
37
+ if (history > 0)
38
+ ring[(ev.seq - 1) % history] = ev;
39
+ onJournal?.(ev);
40
+ line.func(ev);
41
+ const prev = emitting;
42
+ emitting = ev;
43
+ try {
44
+ base.func(...e);
45
+ }
46
+ finally {
47
+ emitting = prev;
48
+ }
49
+ },
50
+ head: () => head,
51
+ getSince: journalSince,
52
+ line,
53
+ hasKeyframe: current != null,
54
+ keyframe: () => {
55
+ const m = current?.();
56
+ return m ? { seq: head, ts: now(), event: m } : undefined;
57
+ },
58
+ on: ((cb, { cbClose, key, current: cur, since, onSeq } = {}) => {
59
+ if (since == null) {
60
+ const off = base.on(cb, { cbClose, key });
61
+ if (cur) {
62
+ const m = currentValue(cur);
63
+ if (m)
64
+ cb(...m);
65
+ }
66
+ return off;
67
+ }
68
+ let lastDelivered = since;
69
+ let replaying = true;
70
+ const queue = [];
71
+ function deliver(ev) {
72
+ if (ev.seq <= lastDelivered)
73
+ return;
74
+ lastDelivered = ev.seq;
75
+ cb(...ev.event);
76
+ onSeq?.(ev.seq);
77
+ }
78
+ const off = base.on(function liveTap(...e) {
79
+ const ev = emitting;
80
+ if (ev == null) {
81
+ cb(...e);
82
+ return;
83
+ }
84
+ if (replaying)
85
+ queue.push(ev);
86
+ else
87
+ deliver(ev);
88
+ }, { cbClose, key });
89
+ const tail = journalSince(since);
90
+ if (tail) {
91
+ for (const ev of tail)
92
+ deliver(ev);
93
+ }
94
+ else {
95
+ const m = current?.();
96
+ lastDelivered = head;
97
+ if (m) {
98
+ cb(...m);
99
+ onSeq?.(head);
100
+ }
101
+ }
102
+ while (queue.length)
103
+ deliver(queue.shift());
104
+ replaying = false;
105
+ return off;
106
+ }),
107
+ addListen: (cb, opts = {}) => api.on(cb, opts),
108
+ removeListen: (k) => api.off(k),
109
+ once: (cb, opts = {}) => {
110
+ if (opts.current) {
111
+ const m = currentValue(opts.current);
112
+ if (m) {
113
+ cb(...m);
114
+ return () => { };
115
+ }
116
+ }
117
+ let off = () => { };
118
+ off = base.on(((...e) => { off(); cb(...e); }), { key: opts.key });
119
+ return off;
120
+ },
121
+ get getAllKeys() { return base.getAllKeys; },
122
+ };
123
+ (0, Listen3_1.registerListenOn)(api.on, api);
124
+ return api;
125
+ }
126
+ function UseReplayListen(options = {}) {
127
+ const { current, history, getSince, onJournal, now, ...listenOptions } = options;
128
+ let t;
129
+ const base = (0, Listen3_1.funcListenCallbackBase)((e) => { t = e; }, { fast: true, ...listenOptions });
130
+ const listen = withReplayListen(base, { current, history, getSince, onJournal, now });
131
+ base.run();
132
+ t = listen.func;
133
+ return [t, listen];
134
+ }
@@ -0,0 +1,43 @@
1
+ import { Listener } from './Listen3';
2
+ import { ListenReplayApi, ReplayEvent } from './replay-listen';
3
+ export declare function exposeReplay<T>(replay: ListenReplayApi<T>): {
4
+ line: {
5
+ func: Listener<[ReplayEvent<import("./Listen3").NormalizeTuple<T>>]>;
6
+ isRun: () => boolean;
7
+ run: () => void;
8
+ close: () => void;
9
+ eventClose: (cb: () => void) => () => void;
10
+ onClose: (cb: () => void) => () => void;
11
+ removeEventClose: (cb: () => void) => void;
12
+ on: import("./Listen3").ListenOn<[ReplayEvent<import("./Listen3").NormalizeTuple<T>>]>;
13
+ off: (k: (string | symbol) | Listener<[ReplayEvent<import("./Listen3").NormalizeTuple<T>>]> | null) => void;
14
+ addListen: (cb: Listener<[ReplayEvent<import("./Listen3").NormalizeTuple<T>>]>, opts?: {
15
+ cbClose?: () => void;
16
+ key?: string | symbol;
17
+ }) => () => void;
18
+ removeListen: (k: (string | symbol) | Listener<[ReplayEvent<import("./Listen3").NormalizeTuple<T>>]> | null) => void;
19
+ once: (cb: Listener<[ReplayEvent<import("./Listen3").NormalizeTuple<T>>]>, opts?: {
20
+ key?: string | symbol;
21
+ }) => () => void;
22
+ count: () => number;
23
+ readonly getAllKeys: (string | symbol)[];
24
+ };
25
+ since: (seq: number) => ReplayEvent<import("./Listen3").NormalizeTuple<T>>[] | null;
26
+ keyframe: () => ReplayEvent<import("./Listen3").NormalizeTuple<T>> | null;
27
+ };
28
+ export type ReplayRemote<Z extends any[] = any[]> = {
29
+ line: {
30
+ on: (cb: (ev: ReplayEvent<Z>) => void) => any;
31
+ };
32
+ since: (seq: number) => Promise<ReplayEvent<Z>[] | null | undefined> | ReplayEvent<Z>[] | null | undefined;
33
+ keyframe: () => Promise<ReplayEvent<Z> | null | undefined> | ReplayEvent<Z> | null | undefined;
34
+ };
35
+ export type ReplaySubscribeOpts = {
36
+ since?: number;
37
+ onSeq?: (seq: number) => void;
38
+ onError?: (e: any) => void;
39
+ };
40
+ export declare function replaySubscribe<Z extends any[]>(remote: ReplayRemote<Z>, cb: Listener<Z>, opts?: ReplaySubscribeOpts): (() => void) & {
41
+ ready: Promise<void>;
42
+ seq: () => number;
43
+ };
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.exposeReplay = exposeReplay;
4
+ exports.replaySubscribe = replaySubscribe;
5
+ function exposeReplay(replay) {
6
+ return {
7
+ line: replay.line,
8
+ since: (seq) => replay.getSince(seq) ?? null,
9
+ keyframe: () => replay.keyframe() ?? null,
10
+ };
11
+ }
12
+ function unsubscribeHandle(handle) {
13
+ if (typeof handle == 'function') {
14
+ handle();
15
+ return;
16
+ }
17
+ if (typeof handle?.off == 'function')
18
+ handle.off();
19
+ else if (typeof handle?.unsubscribe == 'function')
20
+ handle.unsubscribe();
21
+ }
22
+ function replaySubscribe(remote, cb, opts = {}) {
23
+ const { since = -1, onSeq, onError } = opts;
24
+ let lastDelivered = since;
25
+ let replaying = true;
26
+ let closed = false;
27
+ const queue = [];
28
+ function deliver(ev) {
29
+ if (closed || ev.seq <= lastDelivered)
30
+ return;
31
+ lastDelivered = ev.seq;
32
+ cb(...ev.event);
33
+ onSeq?.(ev.seq);
34
+ }
35
+ const handle = remote.line.on(function liveTap(ev) {
36
+ if (replaying)
37
+ queue.push(ev);
38
+ else
39
+ deliver(ev);
40
+ });
41
+ async function catchUp() {
42
+ try {
43
+ const tail = since >= 0 ? await remote.since(since) : null;
44
+ if (closed)
45
+ return;
46
+ if (tail) {
47
+ for (const ev of tail)
48
+ deliver(ev);
49
+ }
50
+ else {
51
+ const kf = await remote.keyframe();
52
+ if (closed)
53
+ return;
54
+ if (kf) {
55
+ lastDelivered = kf.seq;
56
+ cb(...kf.event);
57
+ onSeq?.(kf.seq);
58
+ }
59
+ }
60
+ }
61
+ catch (e) {
62
+ if (onError)
63
+ onError(e);
64
+ else
65
+ setTimeout(function rethrowCatchUp() { throw e; }, 0);
66
+ }
67
+ finally {
68
+ while (queue.length)
69
+ deliver(queue.shift());
70
+ replaying = false;
71
+ }
72
+ }
73
+ const ready = catchUp();
74
+ function off() {
75
+ if (closed)
76
+ return;
77
+ closed = true;
78
+ unsubscribeHandle(handle);
79
+ }
80
+ return Object.assign(off, {
81
+ ready,
82
+ seq: () => lastDelivered,
83
+ });
84
+ }
@@ -7,6 +7,7 @@ export type RpcLimits = {
7
7
  maxStringLen?: number;
8
8
  maxCallbacks?: number;
9
9
  maxPathLen?: number;
10
+ maxBinaryLen?: number;
10
11
  };
11
12
  export declare const resolveLimits: (opts?: RpcLimits) => Required<RpcLimits>;
12
13
  export declare class PayloadLimitError extends Error {