wenay-common2 1.0.62 → 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.
@@ -1,374 +1,17 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.reactive = reactive;
4
- exports.isReactive = isReactive;
5
- exports.toRaw = toRaw;
6
- exports.onUpdate = onUpdate;
7
- exports.onUpdatePaths = onUpdatePaths;
8
- exports.flushReactive = flushReactive;
9
- exports.listenUpdate = listenUpdate;
10
- exports.listenUpdatePaths = listenUpdatePaths;
11
- const Listen_1 = require("../events/Listen");
12
- const NODE = Symbol('reactive2.node');
13
- const isObj = (v) => v != null && typeof v == 'object';
14
- const isReactiveObj = (v) => {
15
- if (!isObj(v))
16
- return false;
17
- if (Array.isArray(v))
18
- return true;
19
- const p = Object.getPrototypeOf(v);
20
- return p == Object.prototype || p == null;
21
- };
22
- const hasSetImmediate = typeof setImmediate == 'function';
23
- function scheduler(drain) {
24
- if (drain == 'micro')
25
- return f => queueMicrotask(f);
26
- if (typeof drain == 'number')
27
- return f => { setTimeout(f, drain); };
28
- if (typeof drain == 'function')
29
- return f => drain(f);
30
- return hasSetImmediate ? f => { setImmediate(f); } : f => { setTimeout(f, 0); };
31
- }
32
- function reactive(root, opts = {}) {
33
- const { drain = 'immediate', depth = Infinity, eager = false } = opts;
34
- const fire = scheduler(drain);
35
- const eng = {
36
- live: 0, pathLive: 0, dirty: new Set(), dirtyPaths: [],
37
- dirtyPathKeys: new Set(), pathKey: createPathKeyer(),
38
- scheduled: false, waiters: new Set(), depth,
39
- schedule() {
40
- if (eng.scheduled)
41
- return;
42
- eng.scheduled = true;
43
- fire(function flush() {
44
- eng.scheduled = false;
45
- const batch = [...eng.dirty];
46
- eng.dirty.clear();
47
- const dirtyPaths = eng.dirtyPaths;
48
- eng.dirtyPaths = [];
49
- eng.dirtyPathKeys = new Set();
50
- eng.pathKey = createPathKeyer();
51
- let err;
52
- for (const n of batch) {
53
- for (const cb of [...n.subs]) {
54
- try {
55
- cb();
56
- }
57
- catch (e) {
58
- err ??= e;
59
- }
60
- }
61
- if (n.pathSubs.size) {
62
- const paths = pathsForNode(n, dirtyPaths);
63
- if (paths.length)
64
- for (const cb of [...n.pathSubs]) {
65
- try {
66
- cb({ paths });
67
- }
68
- catch (e) {
69
- err ??= e;
70
- }
71
- }
72
- }
73
- }
74
- if (!eng.scheduled && eng.dirty.size == 0 && eng.dirtyPaths.length == 0) {
75
- const waiters = [...eng.waiters];
76
- eng.waiters.clear();
77
- for (const w of waiters)
78
- w();
79
- }
80
- if (err !== undefined)
81
- setTimeout(() => { throw err; }, 0);
82
- });
83
- },
84
- };
85
- const rootNode = makeNode(root, null, [], 0, eng);
86
- if (eager)
87
- prewalk(rootNode);
88
- return rootNode.proxy;
89
- }
90
- function makeNode(target, parent, path, level, eng) {
91
- const node = {
92
- target, parent, path, active: true, level,
93
- subs: new Set(), pathSubs: new Set(), kids: new Map(), proxy: null, eng,
94
- };
95
- const proxyTarget = (Array.isArray(target) ? [] : {});
96
- node.proxy = new Proxy(proxyTarget, {
97
- get(_, k) {
98
- if (k == NODE)
99
- return node;
100
- if (k == 'toJSON' && Array.isArray(proxyTarget) && !Array.isArray(node.target) && node.target?.toJSON === undefined)
101
- return () => node.target;
102
- const v = node.target[k];
103
- if (isReactiveObj(v) && level < eng.depth) {
104
- let kid = node.kids.get(k);
105
- if (!kid) {
106
- kid = makeNode(v, node, [...node.path, k], level + 1, eng);
107
- node.kids.set(k, kid);
108
- }
109
- else if (kid.target !== v)
110
- kid.target = v;
111
- return kid.proxy;
112
- }
113
- return v;
114
- },
115
- set(_, k, v) {
116
- v = toRaw(v);
117
- if (Object.is(node.target[k], v))
118
- return true;
119
- node.target[k] = v;
120
- if (Array.isArray(proxyTarget) && k == "length")
121
- proxyTarget.length = v;
122
- const kid = node.kids.get(k);
123
- if (kid)
124
- rebind(kid, v);
125
- if (eng.live > 0)
126
- bubble(node, k);
127
- return true;
128
- },
129
- defineProperty(_, k, d) {
130
- const old = node.target[k];
131
- const desc = 'value' in d ? { ...d, value: toRaw(d.value) } : d;
132
- const ok = Reflect.defineProperty(node.target, k, desc);
133
- if (!ok)
134
- return false;
135
- if (desc.configurable === false) {
136
- const mirror = Reflect.defineProperty(proxyTarget, k, desc);
137
- if (!mirror)
138
- return false;
139
- }
140
- const v = node.target[k];
141
- if (!Object.is(old, v)) {
142
- const kid = node.kids.get(k);
143
- if (kid) {
144
- if (isReactiveObj(v))
145
- rebind(kid, v);
146
- else {
147
- node.kids.delete(k);
148
- markChanged(kid);
149
- detachTree(kid);
150
- }
151
- }
152
- if (eng.live > 0)
153
- bubble(node, k);
154
- }
155
- return true;
156
- },
157
- deleteProperty(_, k) {
158
- if (!(k in node.target))
159
- return true;
160
- delete node.target[k];
161
- const kid = node.kids.get(k);
162
- if (kid) {
163
- node.kids.delete(k);
164
- markChanged(kid);
165
- detachTree(kid);
166
- }
167
- if (eng.live > 0)
168
- bubble(node, k);
169
- return true;
170
- },
171
- has(_, k) { return k in node.target; },
172
- ownKeys() {
173
- const keys = Reflect.ownKeys(node.target);
174
- for (const k of Reflect.ownKeys(proxyTarget)) {
175
- const d = Reflect.getOwnPropertyDescriptor(proxyTarget, k);
176
- if (d?.configurable === false && !keys.includes(k))
177
- keys.push(k);
178
- }
179
- return keys;
180
- },
181
- getOwnPropertyDescriptor(_, k) {
182
- if (Array.isArray(proxyTarget) && k == "length")
183
- return Reflect.getOwnPropertyDescriptor(proxyTarget, k);
184
- const pd = Reflect.getOwnPropertyDescriptor(proxyTarget, k);
185
- if (pd && pd.configurable === false)
186
- return pd;
187
- const d = Reflect.getOwnPropertyDescriptor(node.target, k);
188
- if (d)
189
- d.configurable = true;
190
- return d;
191
- },
192
- });
193
- return node;
194
- }
195
- function bubble(from, key) {
196
- const eng = from.eng;
197
- if (eng.pathLive > 0)
198
- addDirtyPath(eng, dirtyPathFor(from, key));
199
- for (let n = from; n && n.active; n = n.parent)
200
- if (n.subs.size || n.pathSubs.size)
201
- eng.dirty.add(n);
202
- eng.schedule();
203
- }
204
- function rebind(node, next) {
205
- node.target = next;
206
- if (node.subs.size || node.pathSubs.size)
207
- node.eng.dirty.add(node);
208
- for (const [k, kid] of [...node.kids]) {
209
- const cv = isReactiveObj(next) ? next[k] : undefined;
210
- if (isReactiveObj(cv))
211
- rebind(kid, cv);
212
- else {
213
- node.kids.delete(k);
214
- markChanged(kid);
215
- detachTree(kid);
216
- }
217
- }
218
- }
219
- function markChanged(node) {
220
- if (node.subs.size || node.pathSubs.size)
221
- node.eng.dirty.add(node);
222
- for (const kid of node.kids.values())
223
- markChanged(kid);
224
- }
225
- function dirtyPathFor(node, key) {
226
- return Array.isArray(node.target) ? [...node.path] : [...node.path, key];
227
- }
228
- function createPathKeyer() {
229
- let symIds = null;
230
- return function pathKey(path) {
231
- let out = '';
232
- for (const p of path) {
233
- if (typeof p == 'symbol') {
234
- symIds ??= new Map();
235
- let id = symIds.get(p);
236
- if (id == null) {
237
- id = symIds.size;
238
- symIds.set(p, id);
239
- }
240
- out += 'y' + id + '|';
241
- }
242
- else {
243
- const s = String(p);
244
- out += (typeof p)[0] + s.length + ':' + s + '|';
245
- }
246
- }
247
- return out;
248
- };
249
- }
250
- function addDirtyPath(eng, path) {
251
- const k = eng.pathKey(path);
252
- if (eng.dirtyPathKeys.has(k))
253
- return;
254
- eng.dirtyPathKeys.add(k);
255
- eng.dirtyPaths.push(path);
256
- }
257
- function startsWithPath(path, prefix) {
258
- return prefix.length <= path.length && prefix.every((k, i) => Object.is(k, path[i]));
259
- }
260
- function pathsForNode(node, dirtyPaths) {
261
- const out = [];
262
- const seen = new Set();
263
- const pathKey = createPathKeyer();
264
- for (const path of dirtyPaths) {
265
- let next = null;
266
- if (startsWithPath(path, node.path))
267
- next = path.slice(node.path.length);
268
- else if (startsWithPath(node.path, path))
269
- next = [];
270
- if (next == null)
271
- continue;
272
- const k = pathKey(next);
273
- if (seen.has(k))
274
- continue;
275
- seen.add(k);
276
- out.push(next);
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]; } };
277
7
  }
278
- return out;
279
- }
280
- function detachTree(node) {
281
- if (!node.active)
282
- return;
283
- node.active = false;
284
- node.parent = null;
285
- for (const kid of node.kids.values())
286
- detachTree(kid);
287
- node.kids.clear();
288
- }
289
- function prewalk(node) {
290
- if (node.level >= node.eng.depth)
291
- return;
292
- for (const k of Reflect.ownKeys(node.target)) {
293
- if (isReactiveObj(node.target[k])) {
294
- node.proxy[k];
295
- const kid = node.kids.get(k);
296
- if (kid)
297
- prewalk(kid);
298
- }
299
- }
300
- }
301
- function isReactive(p) {
302
- const node = p && p[NODE];
303
- return !!node && node.active;
304
- }
305
- function toRaw(p) {
306
- const node = p && p[NODE];
307
- return node ? node.target : p;
308
- }
309
- function onUpdate(p, cb) {
310
- const node = p && p[NODE];
311
- if (!node)
312
- throw new Error('onUpdate: not a reactive object');
313
- if (!node.active)
314
- throw new Error('onUpdate: reactive object is detached');
315
- const sub = () => cb();
316
- node.subs.add(sub);
317
- node.eng.live++;
318
- let done = false;
319
- return () => { if (done)
320
- return; done = true; if (node.subs.delete(sub))
321
- node.eng.live--; };
322
- }
323
- function onUpdatePaths(p, cb) {
324
- const node = p && p[NODE];
325
- if (!node)
326
- throw new Error('onUpdatePaths: not a reactive object');
327
- if (!node.active)
328
- throw new Error('onUpdatePaths: reactive object is detached');
329
- const sub = (change) => cb(change);
330
- node.pathSubs.add(sub);
331
- node.eng.live++;
332
- node.eng.pathLive++;
333
- let done = false;
334
- return () => {
335
- if (done)
336
- return;
337
- done = true;
338
- if (node.pathSubs.delete(sub)) {
339
- node.eng.live--;
340
- node.eng.pathLive--;
341
- }
342
- };
343
- }
344
- function flushReactive(p) {
345
- const node = p && p[NODE];
346
- if (!node)
347
- throw new Error('flushReactive: not a reactive object');
348
- const eng = node.eng;
349
- if (!eng.scheduled && eng.dirty.size == 0 && eng.dirtyPaths.length == 0)
350
- return Promise.resolve();
351
- return new Promise(resolve => { eng.waiters.add(resolve); });
352
- }
353
- function listenUpdate(p) {
354
- const listen = (0, Listen_1.createListen)((emit) => onUpdate(p, () => emit()), {
355
- event: (type, count, api) => {
356
- if (type == "add" && count == 1 && !api.isRunning())
357
- api.run();
358
- if (type == "remove" && count == 0 && api.isRunning())
359
- api.close();
360
- },
361
- });
362
- return listen;
363
- }
364
- function listenUpdatePaths(p) {
365
- const listen = (0, Listen_1.createListen)((emit) => onUpdatePaths(p, change => emit(change)), {
366
- event: (type, count, api) => {
367
- if (type == "add" && count == 1 && !api.isRunning())
368
- api.run();
369
- if (type == "remove" && count == 0 && api.isRunning())
370
- api.close();
371
- },
372
- });
373
- return listen;
374
- }
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("./reactive"), exports);
@@ -0,0 +1,123 @@
1
+ import { ReplayRemote, ReplaySubscribeOpts } from '../events/replay-wire';
2
+ import { createStore, Store, StoreMask, StorePatch, StoreSyncOpts } from './store';
3
+ import { OfflineStorage, OfflineStore } from './store-offline';
4
+ type RemoteStore<T extends object> = {
5
+ get(mask?: any): T | Promise<T>;
6
+ changed: any;
7
+ changedPaths?: any;
8
+ patches?: any;
9
+ changedData?: any;
10
+ };
11
+ export type StoreMirror<T extends object> = Store<T> & {
12
+ sync<M extends StoreMask<T>>(mask: M, opts?: StoreSyncOpts): Promise<() => void>;
13
+ syncPatches<M extends StoreMask<T>>(mask: M, opts?: StoreSyncOpts): Promise<() => void>;
14
+ syncChangedData<M extends StoreMask<T>>(mask: M, opts?: StoreSyncOpts): Promise<() => void>;
15
+ };
16
+ export type ManagedStoreKind = 'mirror' | 'replay' | 'offline';
17
+ export type ManagedStoreState = 'idle' | 'starting' | 'ready' | 'stopped' | 'error';
18
+ export type ManagedStoreSyncMode = 'pull' | 'patches' | 'changedData';
19
+ export type ManagedStoreUsage = {
20
+ count: number;
21
+ weight: number;
22
+ lastUsedAt?: number;
23
+ };
24
+ export type ManagedStorePriorityContext = {
25
+ key: string;
26
+ now: number;
27
+ usage?: ManagedStoreUsage;
28
+ };
29
+ type CommonResource<T extends object> = {
30
+ key?: string;
31
+ initial: T;
32
+ tags?: readonly string[];
33
+ priority?: number | ((ctx: ManagedStorePriorityContext) => number);
34
+ usageKey?: string;
35
+ explicitOnly?: boolean;
36
+ large?: boolean;
37
+ autoStart?: boolean;
38
+ storeOpts?: Parameters<typeof createStore<T>>[1];
39
+ };
40
+ export type ManagedMirrorResource<T extends object> = CommonResource<T> & {
41
+ kind?: 'mirror';
42
+ remote: RemoteStore<T>;
43
+ mask: StoreMask<T>;
44
+ sync?: {
45
+ mode?: ManagedStoreSyncMode;
46
+ opts?: StoreSyncOpts;
47
+ };
48
+ };
49
+ export type ManagedReplayResource<T extends object> = CommonResource<T> & {
50
+ kind?: 'replay';
51
+ remote: ReplayRemote<[StorePatch]>;
52
+ syncOpts?: ReplaySubscribeOpts;
53
+ };
54
+ export type ManagedOfflineResource<T extends object> = CommonResource<T> & {
55
+ kind?: 'offline';
56
+ remote?: ReplayRemote<[StorePatch]>;
57
+ storage: OfflineStorage;
58
+ storageKey?: string;
59
+ version?: number;
60
+ debounceMs?: number;
61
+ syncOpts?: ReplaySubscribeOpts;
62
+ migrate?: (oldSnapshot: unknown, fromVersion: number, toVersion: number) => T | Promise<T>;
63
+ };
64
+ export type ManagedStoreResource<T extends object = any> = ManagedMirrorResource<T> | ManagedReplayResource<T> | ManagedOfflineResource<T>;
65
+ export type ManagedStoreResources = Record<string, ManagedStoreResource<any>>;
66
+ export type ManagedStoreOf<R> = R extends ManagedOfflineResource<infer T> ? OfflineStore<T> : R extends ManagedReplayResource<infer T> ? Store<T> : R extends ManagedMirrorResource<infer T> ? StoreMirror<T> : never;
67
+ export type ManagedStoreStatus = {
68
+ key: string;
69
+ state: ManagedStoreState;
70
+ kind: ManagedStoreKind;
71
+ error?: unknown;
72
+ startedAt?: number;
73
+ stoppedAt?: number;
74
+ };
75
+ export type ManagedStorePlanItem = {
76
+ key: string;
77
+ kind: ManagedStoreKind;
78
+ score: number;
79
+ state: ManagedStoreState;
80
+ large: boolean;
81
+ explicitOnly: boolean;
82
+ tags: readonly string[];
83
+ };
84
+ export type ManagedStoreStartOpts = {
85
+ explicit?: boolean;
86
+ reason?: string;
87
+ };
88
+ export type ManagedStorePlanOpts = {
89
+ keys?: Iterable<string>;
90
+ tags?: readonly string[];
91
+ includeLarge?: boolean;
92
+ includeExplicit?: boolean;
93
+ limit?: number;
94
+ now?: number;
95
+ };
96
+ export type ManagedStoreHandle<TStore> = {
97
+ readonly key: string;
98
+ readonly kind: ManagedStoreKind;
99
+ start(opts?: ManagedStoreStartOpts): Promise<TStore>;
100
+ stop(): void;
101
+ get(): TStore | undefined;
102
+ status(): ManagedStoreStatus;
103
+ touch(weight?: number): void;
104
+ };
105
+ export declare const managedStore: {
106
+ mirror<T extends object>(resource: ManagedMirrorResource<T>): ManagedMirrorResource<T>;
107
+ replay<T extends object>(resource: ManagedReplayResource<T>): ManagedReplayResource<T>;
108
+ offline<T extends object>(resource: ManagedOfflineResource<T>): ManagedOfflineResource<T>;
109
+ };
110
+ export declare function createStoreManager<const R extends ManagedStoreResources>(resources: R): {
111
+ handles: { [K in keyof R]: ManagedStoreHandle<ManagedStoreOf<R[K]>>; };
112
+ statusListen: import("../events/Listen").ListenApi<[ManagedStoreStatus]>;
113
+ plan: (opts?: ManagedStorePlanOpts) => ManagedStorePlanItem[];
114
+ start: <K extends keyof R & string>(key: K, opts?: ManagedStoreStartOpts) => Promise<ManagedStoreOf<R[K]>>;
115
+ startMany: (keys: Iterable<keyof R & string>, opts?: ManagedStoreStartOpts) => Promise<Partial<{ [K in keyof R]: ManagedStoreOf<R[K]>; }>>;
116
+ startPlanned: (opts?: ManagedStorePlanOpts & ManagedStoreStartOpts) => Promise<Partial<{ [K in keyof R]: ManagedStoreOf<R[K]>; }>>;
117
+ stop: <K extends keyof R & string>(key: K) => void;
118
+ stopAll: () => void;
119
+ get: <K extends keyof R & string>(key: K) => ManagedStoreOf<R[K]> | undefined;
120
+ touch: <K extends keyof R & string>(key: K, weight?: number) => void;
121
+ usage: () => Map<string, ManagedStoreUsage>;
122
+ };
123
+ export {};