wenay-common2 1.0.61 → 1.0.63
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 +8 -8
- package/lib/Common/Observe/index.d.ts +5 -0
- package/lib/Common/{ObserveAll2 → Observe}/index.js +3 -1
- package/lib/Common/Observe/reactive.d.ts +21 -0
- package/lib/Common/{ObserveAll2/reactive2.js → Observe/reactive.js} +7 -7
- package/lib/Common/Observe/reactive2.d.ts +1 -0
- package/lib/Common/{events/Listen2.js → Observe/reactive2.js} +1 -1
- package/lib/Common/Observe/store-manager.d.ts +123 -0
- package/lib/Common/Observe/store-manager.js +227 -0
- package/lib/Common/Observe/store-offline.d.ts +88 -0
- package/lib/Common/Observe/store-offline.js +278 -0
- package/lib/Common/{ObserveAll2 → Observe}/store-replay.d.ts +9 -38
- package/lib/Common/{ObserveAll2 → Observe}/store-replay.js +1 -1
- package/lib/Common/{ObserveAll2 → Observe}/store.d.ts +3 -3
- package/lib/Common/{ObserveAll2 → Observe}/store.js +25 -31
- package/lib/Common/async/promiseProgress.d.ts +12 -0
- package/lib/Common/async/promiseProgress.js +29 -0
- package/lib/Common/events/Listen.d.ts +129 -1
- package/lib/Common/events/Listen.js +243 -15
- package/lib/Common/events/Listen3.d.ts +1 -210
- package/lib/Common/events/Listen3.js +15 -253
- package/lib/Common/events/SocketBuffer.d.ts +13 -33
- package/lib/Common/events/SocketBuffer.js +8 -8
- package/lib/Common/events/SocketServerHook.d.ts +5 -45
- package/lib/Common/events/SocketServerHook.js +1 -1
- package/lib/Common/events/joinListens.d.ts +6 -7
- package/lib/Common/events/joinListens.js +3 -4
- package/lib/Common/events/mapListen.d.ts +4 -0
- package/lib/Common/events/mapListen.js +25 -0
- package/lib/Common/events/replay-conflate.d.ts +2 -22
- package/lib/Common/events/replay-conflate.js +5 -5
- package/lib/Common/events/replay-history.d.ts +1 -1
- package/lib/Common/events/replay-listen.d.ts +20 -66
- package/lib/Common/events/replay-listen.js +10 -13
- package/lib/Common/events/replay-wire.d.ts +1 -1
- package/lib/Common/rcp/createRpcServerAutoWithProtocolDetection.d.ts +3 -3
- package/lib/Common/rcp/createRpcServerAutoWithProtocolDetection.js +10 -10
- package/lib/Common/rcp/listen-deep.d.ts +10 -10
- package/lib/Common/rcp/listen-deep.js +1 -1
- package/lib/Common/rcp/listen-socket.d.ts +13 -13
- package/lib/Common/rcp/listen-socket.js +4 -3
- package/lib/Common/rcp/rpc-client-auto.d.ts +2 -2
- package/lib/Common/rcp/rpc-client-auto.js +3 -2
- package/lib/Common/rcp/rpc-client.js +6 -4
- package/lib/Common/rcp/rpc-index.d.ts +2 -1
- package/lib/Common/rcp/rpc-index.js +3 -2
- package/lib/Common/rcp/rpc-path.d.ts +1 -0
- package/lib/Common/rcp/rpc-path.js +6 -0
- package/lib/Common/rcp/rpc-server-auto.d.ts +2 -2
- package/lib/Common/rcp/rpc-server-auto.js +7 -11
- package/lib/Common/rcp/rpc-server.js +11 -7
- package/lib/client.d.ts +1 -1
- package/lib/client.js +1 -1
- package/lib/index.d.ts +3 -4
- package/lib/index.js +4 -5
- package/package.json +5 -3
- package/lib/Common/ObserveAll2/index.d.ts +0 -3
- package/lib/Common/ObserveAll2/reactive2.d.ts +0 -61
- package/lib/Common/async/PromiseArrayListen.d.ts +0 -14
- package/lib/Common/async/PromiseArrayListen.js +0 -37
- package/lib/Common/events/Listen2.d.ts +0 -1
- package/lib/Common/events/UseListenTransform.d.ts +0 -24
- package/lib/Common/events/UseListenTransform.js +0 -28
- package/lib/Common/rcp/test.d.ts +0 -1
- package/lib/Common/rcp/test.js +0 -79
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMemoryOfflineStorage = createMemoryOfflineStorage;
|
|
4
|
+
exports.persistStore = persistStore;
|
|
5
|
+
exports.createOfflineStore = createOfflineStore;
|
|
6
|
+
const common_1 = require("../core/common");
|
|
7
|
+
const Listen_1 = require("../events/Listen");
|
|
8
|
+
const store_1 = require("./store");
|
|
9
|
+
const store_replay_1 = require("./store-replay");
|
|
10
|
+
function isRecord(v) {
|
|
11
|
+
return !!v && typeof v == 'object' && typeof v.version == 'number'
|
|
12
|
+
&& typeof v.seq == 'number' && 'snapshot' in v;
|
|
13
|
+
}
|
|
14
|
+
function cloneValue(value) {
|
|
15
|
+
return (0, common_1.clone)(value);
|
|
16
|
+
}
|
|
17
|
+
function createMemoryOfflineStorage(initial) {
|
|
18
|
+
const data = new Map();
|
|
19
|
+
for (const [k, v] of Object.entries(initial ?? {}))
|
|
20
|
+
data.set(k, cloneValue(v));
|
|
21
|
+
const api = {
|
|
22
|
+
async read(key) {
|
|
23
|
+
return data.has(key) ? cloneValue(data.get(key)) : undefined;
|
|
24
|
+
},
|
|
25
|
+
async write(key, value) {
|
|
26
|
+
data.set(key, cloneValue(value));
|
|
27
|
+
},
|
|
28
|
+
async remove(key) {
|
|
29
|
+
data.delete(key);
|
|
30
|
+
},
|
|
31
|
+
async transaction(fn) {
|
|
32
|
+
return fn(api);
|
|
33
|
+
},
|
|
34
|
+
dump() {
|
|
35
|
+
const out = {};
|
|
36
|
+
for (const [k, v] of data)
|
|
37
|
+
out[k] = cloneValue(v);
|
|
38
|
+
return out;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
return api;
|
|
42
|
+
}
|
|
43
|
+
function emitError(opts, error) {
|
|
44
|
+
if (opts.onError)
|
|
45
|
+
opts.onError(error);
|
|
46
|
+
else
|
|
47
|
+
setTimeout(function rethrowOfflineStoreError() { throw error; }, 0);
|
|
48
|
+
}
|
|
49
|
+
function copyStatus(status) {
|
|
50
|
+
return { ...status };
|
|
51
|
+
}
|
|
52
|
+
function persistStore(store, opts) {
|
|
53
|
+
const { key, storage, version = 1, debounceMs = 250, now = Date.now, onStatus } = opts;
|
|
54
|
+
let seq = opts.seq ?? -1;
|
|
55
|
+
let savedAt = opts.savedAt;
|
|
56
|
+
let closed = false;
|
|
57
|
+
let dirty = false;
|
|
58
|
+
let timer = null;
|
|
59
|
+
let chain = Promise.resolve();
|
|
60
|
+
const status = {
|
|
61
|
+
ready: true,
|
|
62
|
+
syncing: false,
|
|
63
|
+
offline: false,
|
|
64
|
+
stale: false,
|
|
65
|
+
saving: false,
|
|
66
|
+
seq,
|
|
67
|
+
savedAt,
|
|
68
|
+
};
|
|
69
|
+
const [emitStatus, statusListen] = (0, Listen_1.listenStore)({
|
|
70
|
+
current: () => [copyStatus(status)],
|
|
71
|
+
});
|
|
72
|
+
function updateStatus(patch = {}) {
|
|
73
|
+
Object.assign(status, patch, { seq, savedAt });
|
|
74
|
+
const snap = copyStatus(status);
|
|
75
|
+
emitStatus(snap);
|
|
76
|
+
onStatus?.(snap);
|
|
77
|
+
}
|
|
78
|
+
function clearTimer() {
|
|
79
|
+
if (timer)
|
|
80
|
+
clearTimeout(timer);
|
|
81
|
+
timer = null;
|
|
82
|
+
}
|
|
83
|
+
function scheduleSave() {
|
|
84
|
+
if (closed)
|
|
85
|
+
return;
|
|
86
|
+
dirty = true;
|
|
87
|
+
clearTimer();
|
|
88
|
+
timer = setTimeout(function flushOfflineStoreTimer() {
|
|
89
|
+
timer = null;
|
|
90
|
+
flush().catch(e => emitError(opts, e));
|
|
91
|
+
}, Math.max(0, debounceMs));
|
|
92
|
+
timer.unref?.();
|
|
93
|
+
}
|
|
94
|
+
async function writeRecord(record) {
|
|
95
|
+
if (storage.transaction) {
|
|
96
|
+
await storage.transaction(async function writeOfflineStoreTx(tx) {
|
|
97
|
+
await tx.write(key, record);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
await storage.write(key, record);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function runFlush(force = false) {
|
|
105
|
+
if (closed)
|
|
106
|
+
return;
|
|
107
|
+
if (!dirty && !force)
|
|
108
|
+
return;
|
|
109
|
+
dirty = false;
|
|
110
|
+
updateStatus({ saving: true, error: undefined });
|
|
111
|
+
const nextSavedAt = now();
|
|
112
|
+
const record = {
|
|
113
|
+
version,
|
|
114
|
+
seq,
|
|
115
|
+
snapshot: store.snapshot(),
|
|
116
|
+
savedAt: nextSavedAt,
|
|
117
|
+
};
|
|
118
|
+
try {
|
|
119
|
+
await writeRecord(record);
|
|
120
|
+
savedAt = nextSavedAt;
|
|
121
|
+
updateStatus({ saving: false, error: undefined });
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
updateStatus({ saving: false, error: e });
|
|
125
|
+
throw e;
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
if (dirty && !closed)
|
|
129
|
+
scheduleSave();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function flush() {
|
|
133
|
+
clearTimer();
|
|
134
|
+
const task = chain.catch(() => { }).then(function flushOfflineStore() { return runFlush(false); });
|
|
135
|
+
chain = task.catch(() => { });
|
|
136
|
+
return task;
|
|
137
|
+
}
|
|
138
|
+
function forceFlush() {
|
|
139
|
+
clearTimer();
|
|
140
|
+
dirty = true;
|
|
141
|
+
const task = chain.catch(() => { }).then(function forceFlushOfflineStore() { return runFlush(true); });
|
|
142
|
+
chain = task.catch(() => { });
|
|
143
|
+
return task;
|
|
144
|
+
}
|
|
145
|
+
function setSeq(nextSeq) {
|
|
146
|
+
if (nextSeq == seq)
|
|
147
|
+
return;
|
|
148
|
+
seq = nextSeq;
|
|
149
|
+
updateStatus();
|
|
150
|
+
scheduleSave();
|
|
151
|
+
}
|
|
152
|
+
const offStore = store.listenPaths().on(function persistStoreChange() {
|
|
153
|
+
scheduleSave();
|
|
154
|
+
});
|
|
155
|
+
function close() {
|
|
156
|
+
if (closed)
|
|
157
|
+
return;
|
|
158
|
+
closed = true;
|
|
159
|
+
clearTimer();
|
|
160
|
+
offStore();
|
|
161
|
+
statusListen.close();
|
|
162
|
+
}
|
|
163
|
+
function setSyncStatus(patch) {
|
|
164
|
+
updateStatus(patch);
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
flush,
|
|
168
|
+
forceFlush,
|
|
169
|
+
close,
|
|
170
|
+
setSeq,
|
|
171
|
+
seq: () => seq,
|
|
172
|
+
status: () => copyStatus(status),
|
|
173
|
+
statusListen,
|
|
174
|
+
setSyncStatus,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async function loadSnapshot(opts) {
|
|
178
|
+
const { key, storage, initial, version = 1, migrate } = opts;
|
|
179
|
+
const raw = await storage.read(key);
|
|
180
|
+
if (raw == null)
|
|
181
|
+
return { snapshot: initial, seq: -1 };
|
|
182
|
+
if (isRecord(raw)) {
|
|
183
|
+
if (raw.version == version)
|
|
184
|
+
return { snapshot: raw.snapshot, seq: raw.seq, savedAt: raw.savedAt };
|
|
185
|
+
if (migrate)
|
|
186
|
+
return {
|
|
187
|
+
snapshot: await migrate(raw.snapshot, raw.version, version),
|
|
188
|
+
seq: raw.seq,
|
|
189
|
+
savedAt: raw.savedAt,
|
|
190
|
+
};
|
|
191
|
+
return { snapshot: initial, seq: -1 };
|
|
192
|
+
}
|
|
193
|
+
if (migrate)
|
|
194
|
+
return { snapshot: await migrate(raw, 0, version), seq: -1 };
|
|
195
|
+
return { snapshot: initial, seq: -1 };
|
|
196
|
+
}
|
|
197
|
+
async function createOfflineStore(opts) {
|
|
198
|
+
const { remote, storeOpts, syncOpts = {}, onStatus } = opts;
|
|
199
|
+
if (opts.mode && opts.mode != 'snapshot')
|
|
200
|
+
throw new Error('createOfflineStore: only snapshot mode is implemented');
|
|
201
|
+
let loaded;
|
|
202
|
+
try {
|
|
203
|
+
loaded = await loadSnapshot(opts);
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
emitError(opts, e);
|
|
207
|
+
loaded = { snapshot: opts.initial, seq: -1 };
|
|
208
|
+
}
|
|
209
|
+
const store = (0, store_1.createStore)(loaded.snapshot, storeOpts);
|
|
210
|
+
const persist = persistStore(store, {
|
|
211
|
+
key: opts.key,
|
|
212
|
+
storage: opts.storage,
|
|
213
|
+
version: opts.version,
|
|
214
|
+
seq: loaded.seq,
|
|
215
|
+
savedAt: loaded.savedAt,
|
|
216
|
+
debounceMs: opts.debounceMs,
|
|
217
|
+
now: opts.now,
|
|
218
|
+
onError: opts.onError,
|
|
219
|
+
onStatus,
|
|
220
|
+
});
|
|
221
|
+
let sub = null;
|
|
222
|
+
let ready = Promise.resolve();
|
|
223
|
+
async function reconnect(nextRemote, nextSyncOpts = syncOpts) {
|
|
224
|
+
sub?.();
|
|
225
|
+
persist.setSyncStatus({ syncing: true, offline: false, ready: false, error: undefined });
|
|
226
|
+
const { onSeq, onError, onStale, since, ...rest } = nextSyncOpts;
|
|
227
|
+
const effectiveSince = since ?? (persist.seq() >= 0 ? persist.seq() : undefined);
|
|
228
|
+
try {
|
|
229
|
+
sub = (0, store_replay_1.syncStoreReplay)(store, nextRemote, {
|
|
230
|
+
...rest,
|
|
231
|
+
since: effectiveSince,
|
|
232
|
+
onSeq: function offlineStoreOnSeq(seq) {
|
|
233
|
+
persist.setSeq(seq);
|
|
234
|
+
onSeq?.(seq);
|
|
235
|
+
},
|
|
236
|
+
onError: function offlineStoreOnError(error) {
|
|
237
|
+
persist.setSyncStatus({ offline: true, syncing: false, error });
|
|
238
|
+
onError?.(error);
|
|
239
|
+
if (!onError)
|
|
240
|
+
opts.onError?.(error);
|
|
241
|
+
},
|
|
242
|
+
onStale: onStale && function offlineStoreOnStale(info) {
|
|
243
|
+
persist.setSyncStatus({ stale: info.stale });
|
|
244
|
+
onStale(info);
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
ready = sub.ready.then(function offlineStoreReady() {
|
|
248
|
+
persist.setSyncStatus({ ready: true, syncing: false });
|
|
249
|
+
});
|
|
250
|
+
await ready;
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
persist.setSyncStatus({ ready: true, syncing: false, offline: true, error: e });
|
|
254
|
+
emitError(opts, e);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (remote) {
|
|
258
|
+
ready = reconnect(remote);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
persist.setSyncStatus({ ready: true, syncing: false, offline: true });
|
|
262
|
+
}
|
|
263
|
+
function close() {
|
|
264
|
+
sub?.();
|
|
265
|
+
persist.close();
|
|
266
|
+
}
|
|
267
|
+
function flush() {
|
|
268
|
+
return persist.flush();
|
|
269
|
+
}
|
|
270
|
+
return Object.assign(store, {
|
|
271
|
+
get ready() { return ready; },
|
|
272
|
+
close,
|
|
273
|
+
flush,
|
|
274
|
+
status: persist.status,
|
|
275
|
+
statusListen: persist.statusListen,
|
|
276
|
+
reconnect,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
@@ -17,57 +17,28 @@ export declare function exposeStoreReplay<T extends object>(store: Store<T>, opt
|
|
|
17
17
|
changedData?: any;
|
|
18
18
|
};
|
|
19
19
|
replay: {
|
|
20
|
-
|
|
20
|
+
emit: import("../..").Listener<[StorePatch]>;
|
|
21
21
|
head: () => number;
|
|
22
22
|
isStale: () => boolean;
|
|
23
23
|
lastTs: () => number;
|
|
24
24
|
close: () => void;
|
|
25
25
|
getSince: (seq: number) => ReplayEvent<[StorePatch]>[] | undefined;
|
|
26
|
-
line:
|
|
27
|
-
func: import("../..").Listener<[ReplayEvent<[StorePatch]>]>;
|
|
28
|
-
isRun: () => boolean;
|
|
29
|
-
run: () => void;
|
|
30
|
-
close: () => void;
|
|
31
|
-
eventClose: (cb: () => void) => () => void;
|
|
32
|
-
onClose: (cb: () => void) => () => void;
|
|
33
|
-
removeEventClose: (cb: () => void) => void;
|
|
34
|
-
on: import("../..").ListenOn<[ReplayEvent<[StorePatch]>]>;
|
|
35
|
-
off: (k: (string | symbol) | import("../..").Listener<[ReplayEvent<[StorePatch]>]> | null) => void;
|
|
36
|
-
addListen: (cb: import("../..").Listener<[ReplayEvent<[StorePatch]>]>, opts?: {
|
|
37
|
-
cbClose?: () => void;
|
|
38
|
-
key?: string | symbol;
|
|
39
|
-
}) => () => void;
|
|
40
|
-
removeListen: (k: (string | symbol) | import("../..").Listener<[ReplayEvent<[StorePatch]>]> | null) => void;
|
|
41
|
-
once: (cb: import("../..").Listener<[ReplayEvent<[StorePatch]>]>, opts?: {
|
|
42
|
-
key?: string | symbol;
|
|
43
|
-
}) => () => void;
|
|
44
|
-
count: () => number;
|
|
45
|
-
readonly getAllKeys: (string | symbol)[];
|
|
46
|
-
};
|
|
26
|
+
line: import("../..").ListenApi<[ReplayEvent<[StorePatch]>]>;
|
|
47
27
|
hasKeyframe: boolean;
|
|
48
28
|
keyframe: () => ReplayEvent<[StorePatch]> | undefined;
|
|
49
29
|
frame: (sinceSeq: number, hint?: unknown) => ReplayEvent<[StorePatch]>[];
|
|
50
30
|
on: import("../events/replay-listen").ListenOnReplay<[StorePatch]>;
|
|
51
|
-
addListen: (cb: import("../..").Listener<[StorePatch]>, opts?: {
|
|
52
|
-
cbClose?: () => void;
|
|
53
|
-
key?: string | symbol;
|
|
54
|
-
current?: import("../..").ListenCurrent<[StorePatch]> | undefined;
|
|
55
|
-
since?: number;
|
|
56
|
-
onSeq?: (seq: number) => void;
|
|
57
|
-
}) => () => void;
|
|
58
|
-
removeListen: (k: (string | symbol) | import("../..").Listener<[StorePatch]> | null) => void;
|
|
59
31
|
once: (cb: import("../..").Listener<[StorePatch]>, opts?: {
|
|
60
32
|
key?: string | symbol;
|
|
61
33
|
current?: import("../..").ListenCurrent<[StorePatch]> | undefined;
|
|
62
34
|
}) => () => void;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
count: () => number;
|
|
35
|
+
has(key: import("../..").ListenKey): boolean;
|
|
36
|
+
off(keyOrCallback: import("../..").ListenKey | import("../..").Listener<[StorePatch]> | null): void;
|
|
37
|
+
count(): number;
|
|
38
|
+
keys(): import("../..").ListenKey[];
|
|
39
|
+
isRunning(): boolean;
|
|
40
|
+
run(): void;
|
|
41
|
+
onClose(cb: () => void): import("../..").ListenOff;
|
|
71
42
|
};
|
|
72
43
|
close: () => void;
|
|
73
44
|
};
|
|
@@ -34,7 +34,7 @@ function condensePatchTail(tail) {
|
|
|
34
34
|
return [...held.values()];
|
|
35
35
|
}
|
|
36
36
|
function exposeStoreReplay(store, opts = {}) {
|
|
37
|
-
const [emitPatch, lineApi] = (0, replay_listen_1.
|
|
37
|
+
const [emitPatch, lineApi] = (0, replay_listen_1.replayListen)({
|
|
38
38
|
current: () => [{ path: [], exists: true, value: store.snapshot() }],
|
|
39
39
|
frame: condensePatchTail,
|
|
40
40
|
history: opts.getSince ? undefined : (opts.history ?? 1024),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { listenUpdate, listenUpdatePaths, reactive, ReactiveChange } from "./
|
|
1
|
+
import { createListen } from "../events/Listen";
|
|
2
|
+
import { listenUpdate, listenUpdatePaths, reactive, ReactiveChange } from "./reactive";
|
|
3
3
|
export type StorePath = readonly PropertyKey[];
|
|
4
4
|
export type StoreDrain = "micro" | "immediate" | number | ((flush: () => void) => void);
|
|
5
5
|
export type StoreSubOpts = {
|
|
@@ -83,7 +83,7 @@ export type Store<T extends object> = {
|
|
|
83
83
|
on(cb: (value: T, ctx: StoreCtx<T>) => void, opts?: StoreSubOpts): () => void;
|
|
84
84
|
once(cb: (value: T, ctx: StoreCtx<T>) => void, opts?: StoreSubOpts): () => void;
|
|
85
85
|
update<M extends StoreMask<T>>(mask: M, opts?: StoreSubOpts): StoreSelection<T, M>;
|
|
86
|
-
each(opts?: StoreEachOpts): ReturnType<typeof
|
|
86
|
+
each(opts?: StoreEachOpts): ReturnType<typeof createListen<[key: string, value: T[keyof T] | undefined, ctx: StoreEachCtx]>>;
|
|
87
87
|
listen(): ReturnType<typeof listenUpdate>;
|
|
88
88
|
listenPaths(): ReturnType<typeof listenUpdatePaths>;
|
|
89
89
|
count(): number;
|
|
@@ -7,7 +7,7 @@ exports.createStore = createStore;
|
|
|
7
7
|
exports.exposeStore = exposeStore;
|
|
8
8
|
exports.createStoreMirror = createStoreMirror;
|
|
9
9
|
const Listen_1 = require("../events/Listen");
|
|
10
|
-
const
|
|
10
|
+
const reactive_1 = require("./reactive");
|
|
11
11
|
const hasSetImmediate = typeof setImmediate == "function";
|
|
12
12
|
function pathText(path) {
|
|
13
13
|
return path.map(String).join(".");
|
|
@@ -119,7 +119,7 @@ function setAt(root, path, value) {
|
|
|
119
119
|
p[path[path.length - 1]] = value;
|
|
120
120
|
}
|
|
121
121
|
function snapshotValue(value, seen = new WeakMap()) {
|
|
122
|
-
value = (0,
|
|
122
|
+
value = (0, reactive_1.toRaw)(value);
|
|
123
123
|
if (!isObj(value))
|
|
124
124
|
return value;
|
|
125
125
|
const old = seen.get(value);
|
|
@@ -158,7 +158,7 @@ function maskPaths(mask, base = []) {
|
|
|
158
158
|
return out;
|
|
159
159
|
}
|
|
160
160
|
function pickSnapshot(root, mask, base = []) {
|
|
161
|
-
root = (0,
|
|
161
|
+
root = (0, reactive_1.toRaw)(root);
|
|
162
162
|
if (mask === true || mask == null)
|
|
163
163
|
return snapshotValue(getAt(root, base));
|
|
164
164
|
const out = {};
|
|
@@ -259,7 +259,7 @@ function maskFromPaths(paths) {
|
|
|
259
259
|
return out ?? true;
|
|
260
260
|
}
|
|
261
261
|
function makePatch(root, path) {
|
|
262
|
-
root = (0,
|
|
262
|
+
root = (0, reactive_1.toRaw)(root);
|
|
263
263
|
const exists = hasAt(root, path);
|
|
264
264
|
return {
|
|
265
265
|
path: [...path],
|
|
@@ -292,7 +292,7 @@ function patchesForMask(patch, mask) {
|
|
|
292
292
|
return out;
|
|
293
293
|
}
|
|
294
294
|
function createPatchesListen(store) {
|
|
295
|
-
return (0, Listen_1.
|
|
295
|
+
return (0, Listen_1.createListen)((emit) => {
|
|
296
296
|
const off = store.listenPaths().on((change) => {
|
|
297
297
|
for (const path of change.paths)
|
|
298
298
|
emit(makePatch(store.state, path));
|
|
@@ -300,9 +300,9 @@ function createPatchesListen(store) {
|
|
|
300
300
|
return off;
|
|
301
301
|
}, {
|
|
302
302
|
event: (type, count, api) => {
|
|
303
|
-
if (type == "add" && count == 1 && !api.
|
|
303
|
+
if (type == "add" && count == 1 && !api.isRunning())
|
|
304
304
|
api.run();
|
|
305
|
-
if (type == "remove" && count == 0 && api.
|
|
305
|
+
if (type == "remove" && count == 0 && api.isRunning())
|
|
306
306
|
api.close();
|
|
307
307
|
},
|
|
308
308
|
});
|
|
@@ -310,10 +310,10 @@ function createPatchesListen(store) {
|
|
|
310
310
|
function createEachListen(store, opts = {}) {
|
|
311
311
|
if (opts.depth != null && opts.depth != 1)
|
|
312
312
|
throw new Error("store.each: only depth 1 is supported (reserved option)");
|
|
313
|
-
return (0, Listen_1.
|
|
314
|
-
const known = new Set(Reflect.ownKeys((0,
|
|
313
|
+
return (0, Listen_1.createListen)((emit) => {
|
|
314
|
+
const known = new Set(Reflect.ownKeys((0, reactive_1.toRaw)(store.state)));
|
|
315
315
|
function emitKey(key) {
|
|
316
|
-
const raw = (0,
|
|
316
|
+
const raw = (0, reactive_1.toRaw)(store.state);
|
|
317
317
|
const exists = isObj(raw) && key in raw;
|
|
318
318
|
if (exists)
|
|
319
319
|
known.add(key);
|
|
@@ -331,7 +331,7 @@ function createEachListen(store, opts = {}) {
|
|
|
331
331
|
keys.add(path[0]);
|
|
332
332
|
}
|
|
333
333
|
if (root) {
|
|
334
|
-
for (const key of Reflect.ownKeys((0,
|
|
334
|
+
for (const key of Reflect.ownKeys((0, reactive_1.toRaw)(store.state)))
|
|
335
335
|
keys.add(key);
|
|
336
336
|
for (const key of known)
|
|
337
337
|
keys.add(key);
|
|
@@ -342,15 +342,15 @@ function createEachListen(store, opts = {}) {
|
|
|
342
342
|
return off;
|
|
343
343
|
}, {
|
|
344
344
|
event: (type, count, api) => {
|
|
345
|
-
if (type == "add" && count == 1 && !api.
|
|
345
|
+
if (type == "add" && count == 1 && !api.isRunning())
|
|
346
346
|
api.run();
|
|
347
|
-
if (type == "remove" && count == 0 && api.
|
|
347
|
+
if (type == "remove" && count == 0 && api.isRunning())
|
|
348
348
|
api.close();
|
|
349
349
|
},
|
|
350
350
|
});
|
|
351
351
|
}
|
|
352
352
|
function createChangedDataListen(store) {
|
|
353
|
-
return (0, Listen_1.
|
|
353
|
+
return (0, Listen_1.createListen)((emit) => {
|
|
354
354
|
const off = store.listenPaths().on((change) => {
|
|
355
355
|
const mask = maskFromPaths(change.paths);
|
|
356
356
|
emit({ mask, data: pickSnapshot(store.state, mask) });
|
|
@@ -358,9 +358,9 @@ function createChangedDataListen(store) {
|
|
|
358
358
|
return off;
|
|
359
359
|
}, {
|
|
360
360
|
event: (type, count, api) => {
|
|
361
|
-
if (type == "add" && count == 1 && !api.
|
|
361
|
+
if (type == "add" && count == 1 && !api.isRunning())
|
|
362
362
|
api.run();
|
|
363
|
-
if (type == "remove" && count == 0 && api.
|
|
363
|
+
if (type == "remove" && count == 0 && api.isRunning())
|
|
364
364
|
api.close();
|
|
365
365
|
},
|
|
366
366
|
});
|
|
@@ -372,7 +372,7 @@ function watchTarget(root, path) {
|
|
|
372
372
|
if (!isObj(cur) || !(k in cur))
|
|
373
373
|
return lastReactive;
|
|
374
374
|
const next = cur[k];
|
|
375
|
-
if ((0,
|
|
375
|
+
if ((0, reactive_1.isReactive)(next)) {
|
|
376
376
|
cur = next;
|
|
377
377
|
lastReactive = next;
|
|
378
378
|
}
|
|
@@ -427,10 +427,10 @@ function subscribePath(store, path, cb, opts = {}, once = false) {
|
|
|
427
427
|
function attach() {
|
|
428
428
|
offUpdate?.();
|
|
429
429
|
const target = watchTarget(store._state, path);
|
|
430
|
-
offUpdate = (0,
|
|
430
|
+
offUpdate = (0, reactive_1.onUpdate)(target, () => {
|
|
431
431
|
const exists = hasAt(store._state, path);
|
|
432
432
|
const value = getAt(store._state, path);
|
|
433
|
-
const valueIsObject = (0,
|
|
433
|
+
const valueIsObject = (0, reactive_1.isReactive)(value);
|
|
434
434
|
const watchedSelf = target === value;
|
|
435
435
|
if (!valueIsObject && !watchedSelf && sameLeaf(lastValue, value, lastExists, exists))
|
|
436
436
|
return;
|
|
@@ -541,7 +541,7 @@ function createSelection(store, base, mask, defaults = {}) {
|
|
|
541
541
|
};
|
|
542
542
|
}
|
|
543
543
|
function createStore(initial, opts = {}) {
|
|
544
|
-
const state = (0,
|
|
544
|
+
const state = (0, reactive_1.reactive)(initial, opts);
|
|
545
545
|
let store;
|
|
546
546
|
store = {
|
|
547
547
|
_state: state,
|
|
@@ -556,8 +556,8 @@ function createStore(initial, opts = {}) {
|
|
|
556
556
|
once: (cb, opts) => getNode(store, []).once(cb, opts),
|
|
557
557
|
update: (mask, opts) => createSelection(store, [], mask, opts),
|
|
558
558
|
each: (opts) => createEachListen(store, opts),
|
|
559
|
-
listen: () => (0,
|
|
560
|
-
listenPaths: () => (0,
|
|
559
|
+
listen: () => (0, reactive_1.listenUpdate)(state),
|
|
560
|
+
listenPaths: () => (0, reactive_1.listenUpdatePaths)(state),
|
|
561
561
|
count: () => Array.from(store._counts.values()).reduce((a, b) => a + b, 0),
|
|
562
562
|
};
|
|
563
563
|
return store;
|
|
@@ -588,16 +588,12 @@ function exposeStore(store, opts = {}) {
|
|
|
588
588
|
return api;
|
|
589
589
|
}
|
|
590
590
|
function isRemoteListen(listen) {
|
|
591
|
-
return typeof listen?.on == "function"
|
|
591
|
+
return typeof listen?.on == "function";
|
|
592
592
|
}
|
|
593
593
|
function subscribeRemote(listen, cb) {
|
|
594
|
-
|
|
595
|
-
if (typeof listen?.on == "function")
|
|
596
|
-
handle = listen.on(cb);
|
|
597
|
-
else if (typeof listen?.addListen == "function")
|
|
598
|
-
handle = listen.addListen(cb);
|
|
599
|
-
else
|
|
594
|
+
if (typeof listen?.on != "function")
|
|
600
595
|
return () => { };
|
|
596
|
+
const handle = listen.on(cb);
|
|
601
597
|
return () => {
|
|
602
598
|
if (typeof handle == "function")
|
|
603
599
|
handle();
|
|
@@ -605,8 +601,6 @@ function subscribeRemote(listen, cb) {
|
|
|
605
601
|
handle.off();
|
|
606
602
|
else if (typeof listen?.off == "function")
|
|
607
603
|
listen.off(cb);
|
|
608
|
-
else if (typeof listen?.removeListen == "function")
|
|
609
|
-
listen.removeListen(cb);
|
|
610
604
|
};
|
|
611
605
|
}
|
|
612
606
|
function createStoreMirror(remote, initial = {}, opts = {}) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function promiseProgress<T extends any = unknown>(array: ((() => Promise<T>) | (() => any) | Promise<T>)[]): {
|
|
2
|
+
onOk: (cb: (...data: [data: T, i: number, countOk: number, countError: number, count: number]) => any) => import("../events/Listen").ListenOff;
|
|
3
|
+
onError: (cb: (...data: [error: any, i: number, countOk: number, countError: number, count: number]) => any) => import("../events/Listen").ListenOff;
|
|
4
|
+
all: () => Promise<any[]>;
|
|
5
|
+
allSettled: () => Promise<PromiseSettledResult<any>[]>;
|
|
6
|
+
items: () => Promise<any>[];
|
|
7
|
+
stats: () => {
|
|
8
|
+
ok: number;
|
|
9
|
+
error: number;
|
|
10
|
+
count: number;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.promiseProgress = promiseProgress;
|
|
4
|
+
const Listen_1 = require("../events/Listen");
|
|
5
|
+
function promiseProgress(array) {
|
|
6
|
+
let ok = 0, errorCount = 0;
|
|
7
|
+
const count = array.length;
|
|
8
|
+
const okEvents = (0, Listen_1.listen)();
|
|
9
|
+
const errorEvents = (0, Listen_1.listen)();
|
|
10
|
+
const emitOk = (data, i) => {
|
|
11
|
+
++ok;
|
|
12
|
+
okEvents[0](data, i, ok, errorCount, count);
|
|
13
|
+
};
|
|
14
|
+
const emitError = (error, i) => {
|
|
15
|
+
++errorCount;
|
|
16
|
+
errorEvents[0](error, i, ok, errorCount, count);
|
|
17
|
+
};
|
|
18
|
+
const wrap = (promise, i) => promise.then(r => { emitOk(r, i); return r; }).catch((er) => { emitError(er, i); throw er; });
|
|
19
|
+
const arr = array.map((e, i) => e instanceof Promise ? wrap(e, i) : () => wrap((async () => e())(), i));
|
|
20
|
+
const started = [];
|
|
21
|
+
const startAll = () => arr.map((x, i) => started[i] ??= (typeof x === "function" ? x() : x));
|
|
22
|
+
const onOk = (cb) => okEvents[1].on(cb);
|
|
23
|
+
const onError = (cb) => errorEvents[1].on(cb);
|
|
24
|
+
const all = () => Promise.all(startAll());
|
|
25
|
+
const allSettled = () => Promise.allSettled(startAll());
|
|
26
|
+
const items = () => startAll();
|
|
27
|
+
const stats = () => ({ ok, error: errorCount, count });
|
|
28
|
+
return { onOk, onError, all, allSettled, items, stats };
|
|
29
|
+
}
|