teamplay 0.5.0-alpha.34 → 0.5.0-alpha.36
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/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/orm/Compat/SignalCompat.js +8 -423
- package/dist/orm/Doc.js +0 -100
- package/dist/orm/Query.js +0 -51
- package/dist/orm/SignalBase.js +2 -24
- package/dist/orm/connection.d.ts +0 -11
- package/dist/orm/connection.js +0 -17
- package/dist/orm/dataTree.d.ts +12 -12
- package/dist/orm/dataTree.js +17 -69
- package/dist/orm/disposeRootContext.js +0 -14
- package/dist/orm/getSignal.d.ts +1 -1
- package/dist/orm/getSignal.js +2 -12
- package/dist/orm/rootContext.d.ts +0 -16
- package/dist/orm/rootContext.js +0 -28
- package/dist/server.d.ts +1 -2
- package/dist/server.js +2 -3
- package/package.json +3 -2
- package/dist/orm/Compat/modelEvents.d.ts +0 -6
- package/dist/orm/Compat/modelEvents.js +0 -228
- package/dist/orm/Compat/refFallback.d.ts +0 -13
- package/dist/orm/Compat/refFallback.js +0 -65
- package/dist/orm/Compat/refRegistry.d.ts +0 -6
- package/dist/orm/Compat/refRegistry.js +0 -54
- package/dist/orm/Compat/silentContext.d.ts +0 -4
- package/dist/orm/Compat/silentContext.js +0 -19
package/dist/index.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ export { emit, useOn, useEmit } from './orm/events.js';
|
|
|
62
62
|
export { default as reaction } from './orm/reaction.js';
|
|
63
63
|
export type { ReactionHandle, ReactionOptions } from './orm/reaction.js';
|
|
64
64
|
export { useDidUpdate, useOnce, useSyncEffect } from './react/helpers.js';
|
|
65
|
-
export { connection, setConnection, getConnection, getDefaultFetchOnly, setDefaultFetchOnly
|
|
65
|
+
export { connection, setConnection, getConnection, getDefaultFetchOnly, setDefaultFetchOnly } from './orm/connection.js';
|
|
66
66
|
export type { TeamplayConnection, TeamplayShareDoc } from './orm/connection.js';
|
|
67
67
|
export { TEAMPLAY_RUNTIME_CONFIG_SYMBOL, configureTeamplay, getTeamplayConfig, getDefaultIdFields, setDefaultIdFields } from './config.js';
|
|
68
68
|
export type { IdField, IdFields, TeamplayRuntimeConfig } from './config.js';
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ export const observer = runtimeObserver;
|
|
|
21
21
|
export { emit, useOn, useEmit } from './orm/events.js';
|
|
22
22
|
export { default as reaction } from "./orm/reaction.js";
|
|
23
23
|
export { useDidUpdate, useOnce, useSyncEffect } from "./react/helpers.js";
|
|
24
|
-
export { connection, setConnection, getConnection, getDefaultFetchOnly, setDefaultFetchOnly
|
|
24
|
+
export { connection, setConnection, getConnection, getDefaultFetchOnly, setDefaultFetchOnly } from "./orm/connection.js";
|
|
25
25
|
export { TEAMPLAY_RUNTIME_CONFIG_SYMBOL, configureTeamplay, getTeamplayConfig, getDefaultIdFields, setDefaultIdFields } from "./config.js";
|
|
26
26
|
export { getSubscriptionGcDelay, setSubscriptionGcDelay } from "./orm/subscriptionGcDelay.js";
|
|
27
27
|
export { useId, useNow, useScheduleUpdate, useTriggerUpdate } from "./react/helpers.js";
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import { raw
|
|
1
|
+
import { raw } from '@nx-js/observer-util';
|
|
2
2
|
import arrayDiff from 'arraydiff';
|
|
3
|
-
import { Signal, GETTERS, DEFAULT_GETTERS, SEGMENTS, isPublicCollection
|
|
4
|
-
import { getRoot, ROOT, ROOT_ID
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { AGGREGATIONS, IS_AGGREGATION, aggregationSubscriptions } from '../Aggregation.js';
|
|
3
|
+
import { Signal, GETTERS, DEFAULT_GETTERS, SEGMENTS, isPublicCollection } from "../SignalBase.js";
|
|
4
|
+
import { getRoot, ROOT, ROOT_ID } from "../Root.js";
|
|
5
|
+
import { IS_QUERY } from '../Query.js';
|
|
6
|
+
import { AGGREGATIONS, IS_AGGREGATION } from '../Aggregation.js';
|
|
8
7
|
import { getIdFieldsForSegments, isIdFieldPath, isPublicDocPath, normalizeIdFields, isPlainObject } from "../idFields.js";
|
|
9
8
|
import { incrementPublic as _incrementPublic, arrayPushPublic as _arrayPushPublic, arrayUnshiftPublic as _arrayUnshiftPublic, arrayInsertPublic as _arrayInsertPublic, arrayPopPublic as _arrayPopPublic, arrayShiftPublic as _arrayShiftPublic, arrayRemovePublic as _arrayRemovePublic, arrayMovePublic as _arrayMovePublic, setPublicDocReplace as _setPublicDocReplace, stringInsertPublic as _stringInsertPublic, stringRemovePublic as _stringRemovePublic } from '../dataTree.js';
|
|
10
9
|
import { on as onCustomEvent, removeListener as removeCustomEventListener } from '../events.js';
|
|
11
|
-
import { waitForImperativeQueryReady } from '../queryReadiness.js';
|
|
12
|
-
import { isModelEventsEnabled } from './modelEvents.js';
|
|
13
|
-
import { setRefLink, removeRefLink, getAllRefLinks } from './refRegistry.js';
|
|
14
|
-
import { REF_TARGET, resolveRefSignalSafe, resolveRefSegmentsSafe } from './refFallback.js';
|
|
15
10
|
import { runInBatch } from '../batchScheduler.js';
|
|
16
|
-
import { runInModelEventsSilentContext, isSilentContextActive } from './silentContext.js';
|
|
17
|
-
import universal$ from "../../react/universal$.js";
|
|
18
|
-
import { getRootContext } from "../rootContext.js";
|
|
19
11
|
import { arrayInsertPrivateData, arrayMovePrivateData, arrayPopPrivateData, arrayPushPrivateData, arrayRemovePrivateData, arrayShiftPrivateData, arrayUnshiftPrivateData, delPrivateData, setReplacePrivateData, stringInsertPrivateData, stringRemovePrivateData } from '../privateData.js';
|
|
20
12
|
class SignalCompat extends Signal {
|
|
21
13
|
static [GETTERS] = DEFAULT_GETTERS;
|
|
@@ -27,15 +19,9 @@ class SignalCompat extends Signal {
|
|
|
27
19
|
getId() {
|
|
28
20
|
if (isAggregationValuePath(this[SEGMENTS]))
|
|
29
21
|
return super.getId();
|
|
30
|
-
const $target = resolveRefSignal(this);
|
|
31
|
-
if ($target !== this)
|
|
32
|
-
return $target.getId();
|
|
33
22
|
return super.getId();
|
|
34
23
|
}
|
|
35
24
|
getCollection() {
|
|
36
|
-
const $target = resolveRefSignal(this);
|
|
37
|
-
if ($target !== this)
|
|
38
|
-
return $target.getCollection();
|
|
39
25
|
return super.getCollection();
|
|
40
26
|
}
|
|
41
27
|
getCopy() {
|
|
@@ -48,16 +34,6 @@ class SignalCompat extends Signal {
|
|
|
48
34
|
throw Error('Signal.getDeepCopy() does not accept any arguments');
|
|
49
35
|
return deepCopy(this.get());
|
|
50
36
|
}
|
|
51
|
-
fetch(...items) {
|
|
52
|
-
if (items.length > 0)
|
|
53
|
-
return subscribeMany(items, 'subscribe', 'fetch', 'fetch');
|
|
54
|
-
return subscribeSelf(this, 'fetch', 'fetch');
|
|
55
|
-
}
|
|
56
|
-
unfetch(...items) {
|
|
57
|
-
if (items.length > 0)
|
|
58
|
-
return subscribeMany(items, 'unsubscribe', 'fetch', 'unfetch');
|
|
59
|
-
return unsubscribeSelf(this, 'fetch', 'unfetch');
|
|
60
|
-
}
|
|
61
37
|
getExtra() {
|
|
62
38
|
if (arguments.length > 0)
|
|
63
39
|
throw Error('Signal.getExtra() does not accept any arguments');
|
|
@@ -75,25 +51,14 @@ class SignalCompat extends Signal {
|
|
|
75
51
|
peek() {
|
|
76
52
|
if (arguments.length > 0)
|
|
77
53
|
throw Error('Signal.peek() does not accept any arguments');
|
|
78
|
-
const $target = resolveRefSignal(this);
|
|
79
|
-
if ($target !== this)
|
|
80
|
-
return Signal.prototype.peek.apply($target, arguments);
|
|
81
54
|
return Signal.prototype.peek.apply(this, arguments);
|
|
82
55
|
}
|
|
83
56
|
async set(value) {
|
|
84
|
-
const forwarded = forwardRef(this, 'set', arguments);
|
|
85
|
-
if (forwarded)
|
|
86
|
-
return forwarded;
|
|
87
57
|
if (arguments.length > 1)
|
|
88
58
|
throw Error('Signal.set() expects a single argument');
|
|
89
|
-
|
|
90
|
-
return Signal.prototype.set.call(this, value);
|
|
91
|
-
return setReplaceOnSignal(this, value);
|
|
59
|
+
return Signal.prototype.set.call(this, value);
|
|
92
60
|
}
|
|
93
61
|
async setReplace(value) {
|
|
94
|
-
const forwarded = forwardRef(this, 'setReplace', arguments);
|
|
95
|
-
if (forwarded)
|
|
96
|
-
return forwarded;
|
|
97
62
|
if (arguments.length > 1)
|
|
98
63
|
throw Error('Signal.setReplace() expects a single argument');
|
|
99
64
|
if (value === undefined)
|
|
@@ -101,9 +66,6 @@ class SignalCompat extends Signal {
|
|
|
101
66
|
return setReplaceOnSignal(this, value);
|
|
102
67
|
}
|
|
103
68
|
async setNull(value) {
|
|
104
|
-
const forwarded = forwardRef(this, 'setNull', arguments);
|
|
105
|
-
if (forwarded)
|
|
106
|
-
return forwarded;
|
|
107
69
|
if (arguments.length > 1)
|
|
108
70
|
throw Error('Signal.setNull() expects a single argument');
|
|
109
71
|
if (this.get() != null)
|
|
@@ -111,17 +73,11 @@ class SignalCompat extends Signal {
|
|
|
111
73
|
return setReplaceOnSignal(this, value);
|
|
112
74
|
}
|
|
113
75
|
async setDiffDeep(value) {
|
|
114
|
-
const forwarded = forwardRef(this, 'setDiffDeep', arguments);
|
|
115
|
-
if (forwarded)
|
|
116
|
-
return forwarded;
|
|
117
76
|
if (arguments.length > 1)
|
|
118
77
|
throw Error('Signal.setDiffDeep() expects a single argument');
|
|
119
78
|
return runInBatch(() => setDiffDeepOnSignal(this, value));
|
|
120
79
|
}
|
|
121
80
|
async setDiff(value) {
|
|
122
|
-
const forwarded = forwardRef(this, 'setDiff', arguments);
|
|
123
|
-
if (forwarded)
|
|
124
|
-
return forwarded;
|
|
125
81
|
if (arguments.length > 1)
|
|
126
82
|
throw Error('Signal.setDiff() expects a single argument');
|
|
127
83
|
const before = this.peek();
|
|
@@ -130,9 +86,6 @@ class SignalCompat extends Signal {
|
|
|
130
86
|
return setReplaceOnSignal(this, value);
|
|
131
87
|
}
|
|
132
88
|
async setEach(object) {
|
|
133
|
-
const forwarded = forwardRef(this, 'setEach', arguments);
|
|
134
|
-
if (forwarded)
|
|
135
|
-
return forwarded;
|
|
136
89
|
if (arguments.length > 1)
|
|
137
90
|
throw Error('Signal.setEach() expects a single argument');
|
|
138
91
|
if (!object)
|
|
@@ -149,9 +102,6 @@ class SignalCompat extends Signal {
|
|
|
149
102
|
});
|
|
150
103
|
}
|
|
151
104
|
async del() {
|
|
152
|
-
const forwarded = forwardRef(this, 'del', arguments);
|
|
153
|
-
if (forwarded)
|
|
154
|
-
return forwarded;
|
|
155
105
|
if (arguments.length > 0)
|
|
156
106
|
throw Error('Signal.del() does not accept any arguments');
|
|
157
107
|
try {
|
|
@@ -164,9 +114,6 @@ class SignalCompat extends Signal {
|
|
|
164
114
|
}
|
|
165
115
|
}
|
|
166
116
|
async increment(byNumber) {
|
|
167
|
-
const forwarded = forwardRef(this, 'increment', arguments);
|
|
168
|
-
if (forwarded)
|
|
169
|
-
return forwarded;
|
|
170
117
|
if (arguments.length > 1)
|
|
171
118
|
throw Error('Signal.increment() expects zero or one argument');
|
|
172
119
|
if (byNumber != null && (typeof byNumber !== 'number' || !Number.isFinite(byNumber))) {
|
|
@@ -175,25 +122,16 @@ class SignalCompat extends Signal {
|
|
|
175
122
|
return incrementOnSignal(this, byNumber);
|
|
176
123
|
}
|
|
177
124
|
async push(value) {
|
|
178
|
-
const forwarded = forwardRef(this, 'push', arguments);
|
|
179
|
-
if (forwarded)
|
|
180
|
-
return forwarded;
|
|
181
125
|
if (arguments.length > 1)
|
|
182
126
|
throw Error('Signal.push() expects a single argument');
|
|
183
127
|
return arrayPushOnSignal(this, value);
|
|
184
128
|
}
|
|
185
129
|
async unshift(value) {
|
|
186
|
-
const forwarded = forwardRef(this, 'unshift', arguments);
|
|
187
|
-
if (forwarded)
|
|
188
|
-
return forwarded;
|
|
189
130
|
if (arguments.length > 1)
|
|
190
131
|
throw Error('Signal.unshift() expects a single argument');
|
|
191
132
|
return arrayUnshiftOnSignal(this, value);
|
|
192
133
|
}
|
|
193
134
|
async insert(index, values) {
|
|
194
|
-
const forwarded = forwardRef(this, 'insert', arguments);
|
|
195
|
-
if (forwarded)
|
|
196
|
-
return forwarded;
|
|
197
135
|
if (arguments.length < 2)
|
|
198
136
|
throw Error('Not enough arguments for insert');
|
|
199
137
|
if (arguments.length > 2)
|
|
@@ -204,25 +142,16 @@ class SignalCompat extends Signal {
|
|
|
204
142
|
return arrayInsertOnSignal(this, index, values);
|
|
205
143
|
}
|
|
206
144
|
async pop() {
|
|
207
|
-
const forwarded = forwardRef(this, 'pop', arguments);
|
|
208
|
-
if (forwarded)
|
|
209
|
-
return forwarded;
|
|
210
145
|
if (arguments.length > 0)
|
|
211
146
|
throw Error('Signal.pop() does not accept any arguments');
|
|
212
147
|
return arrayPopOnSignal(this);
|
|
213
148
|
}
|
|
214
149
|
async shift() {
|
|
215
|
-
const forwarded = forwardRef(this, 'shift', arguments);
|
|
216
|
-
if (forwarded)
|
|
217
|
-
return forwarded;
|
|
218
150
|
if (arguments.length > 0)
|
|
219
151
|
throw Error('Signal.shift() does not accept any arguments');
|
|
220
152
|
return arrayShiftOnSignal(this);
|
|
221
153
|
}
|
|
222
154
|
async remove(index, howMany) {
|
|
223
|
-
const forwarded = forwardRef(this, 'remove', arguments);
|
|
224
|
-
if (forwarded)
|
|
225
|
-
return forwarded;
|
|
226
155
|
if (arguments.length === 0) {
|
|
227
156
|
const segments = this[SEGMENTS].slice();
|
|
228
157
|
if (!segments.length || typeof segments[segments.length - 1] !== 'number') {
|
|
@@ -241,9 +170,6 @@ class SignalCompat extends Signal {
|
|
|
241
170
|
return arrayRemoveOnSignal(this, index, howMany);
|
|
242
171
|
}
|
|
243
172
|
async move(from, to, howMany) {
|
|
244
|
-
const forwarded = forwardRef(this, 'move', arguments);
|
|
245
|
-
if (forwarded)
|
|
246
|
-
return forwarded;
|
|
247
173
|
if (arguments.length < 2)
|
|
248
174
|
throw Error('Not enough arguments for move');
|
|
249
175
|
if (arguments.length > 3)
|
|
@@ -254,9 +180,6 @@ class SignalCompat extends Signal {
|
|
|
254
180
|
return arrayMoveOnSignal(this, from, to, howMany);
|
|
255
181
|
}
|
|
256
182
|
async stringInsert(index, text) {
|
|
257
|
-
const forwarded = forwardRef(this, 'stringInsert', arguments);
|
|
258
|
-
if (forwarded)
|
|
259
|
-
return forwarded;
|
|
260
183
|
if (arguments.length < 2)
|
|
261
184
|
throw Error('Not enough arguments for stringInsert');
|
|
262
185
|
if (arguments.length > 2)
|
|
@@ -267,9 +190,6 @@ class SignalCompat extends Signal {
|
|
|
267
190
|
return stringInsertOnSignal(this, index, text);
|
|
268
191
|
}
|
|
269
192
|
async stringRemove(index, howMany) {
|
|
270
|
-
const forwarded = forwardRef(this, 'stringRemove', arguments);
|
|
271
|
-
if (forwarded)
|
|
272
|
-
return forwarded;
|
|
273
193
|
if (arguments.length < 2)
|
|
274
194
|
throw Error('Not enough arguments for stringRemove');
|
|
275
195
|
if (arguments.length > 2)
|
|
@@ -282,9 +202,6 @@ class SignalCompat extends Signal {
|
|
|
282
202
|
return stringRemoveOnSignal(this, index, howMany);
|
|
283
203
|
}
|
|
284
204
|
async assign(value) {
|
|
285
|
-
const forwarded = forwardRef(this, 'assign', arguments);
|
|
286
|
-
if (forwarded)
|
|
287
|
-
return forwarded;
|
|
288
205
|
if (arguments.length > 1)
|
|
289
206
|
throw Error('Signal.assign() expects a single argument');
|
|
290
207
|
return Signal.prototype.assign.call(this, value);
|
|
@@ -319,245 +236,15 @@ class SignalCompat extends Signal {
|
|
|
319
236
|
throw Error('Signal.removeListener() expects two arguments');
|
|
320
237
|
return removeCustomEventListener(eventName, handler);
|
|
321
238
|
}
|
|
322
|
-
ref(path, target, options) {
|
|
323
|
-
if (arguments.length < 1 || arguments.length > 2)
|
|
324
|
-
throw Error('Signal.ref() expects one or two arguments');
|
|
325
|
-
let $to;
|
|
326
|
-
if (arguments.length === 1) {
|
|
327
|
-
$to = resolveRefTarget(this, path, 'Signal.ref()');
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
$to = resolveRefTarget(this, path, 'Signal.ref()');
|
|
331
|
-
options = target;
|
|
332
|
-
}
|
|
333
|
-
if (!$to)
|
|
334
|
-
throw Error('Signal.ref() expects a target path or signal');
|
|
335
|
-
if (this === $to)
|
|
336
|
-
return this;
|
|
337
|
-
ensurePrivateRefSource(this, 'Signal.ref()');
|
|
338
|
-
const store = getRefStore(this);
|
|
339
|
-
const fromPath = this.path();
|
|
340
|
-
const existing = store.get(fromPath);
|
|
341
|
-
if (existing)
|
|
342
|
-
existing.stop();
|
|
343
|
-
const mirrorOnly = !!($to?.[IS_QUERY] || $to?.[IS_AGGREGATION]);
|
|
344
|
-
const { stop, onChange } = createRefLink(this, $to, { mirrorOnly, options });
|
|
345
|
-
store.set(fromPath, { stop });
|
|
346
|
-
const fromRootId = (getRoot(this) || this)?.[ROOT_ID];
|
|
347
|
-
const toRootId = (getRoot($to) || $to)?.[ROOT_ID];
|
|
348
|
-
if (!mirrorOnly) {
|
|
349
|
-
this[REF_TARGET] = $to;
|
|
350
|
-
setRefLink(fromRootId, fromPath, $to.path(), this[SEGMENTS], $to[SEGMENTS], {
|
|
351
|
-
mirrorOnly: false,
|
|
352
|
-
fromRootId,
|
|
353
|
-
toRootId
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
setRefLink(fromRootId, fromPath, $to.path(), this[SEGMENTS], $to[SEGMENTS], {
|
|
358
|
-
mirrorOnly: true,
|
|
359
|
-
onChange,
|
|
360
|
-
fromRootId,
|
|
361
|
-
toRootId
|
|
362
|
-
});
|
|
363
|
-
if (this[REF_TARGET])
|
|
364
|
-
delete this[REF_TARGET];
|
|
365
|
-
}
|
|
366
|
-
return this;
|
|
367
|
-
}
|
|
368
|
-
refExtra(path) {
|
|
369
|
-
if (arguments.length !== 1)
|
|
370
|
-
throw Error('Signal.refExtra() expects a single argument');
|
|
371
|
-
const segments = parseAtSubpath(path, 1, 'Signal.refExtra()');
|
|
372
|
-
const $root = getRoot(this) || this;
|
|
373
|
-
const $target = resolveSignal($root, segments);
|
|
374
|
-
let $source = this;
|
|
375
|
-
if (this[IS_QUERY]) {
|
|
376
|
-
$source = this.extra;
|
|
377
|
-
}
|
|
378
|
-
return SignalCompat.prototype.ref.call($target, $source);
|
|
379
|
-
}
|
|
380
|
-
refIds(path) {
|
|
381
|
-
if (arguments.length !== 1)
|
|
382
|
-
throw Error('Signal.refIds() expects a single argument');
|
|
383
|
-
if (!this[IS_QUERY]) {
|
|
384
|
-
throw Error('Signal.refIds() can only be used on query signals');
|
|
385
|
-
}
|
|
386
|
-
const segments = parseAtSubpath(path, 1, 'Signal.refIds()');
|
|
387
|
-
const $root = getRoot(this) || this;
|
|
388
|
-
const $target = resolveSignal($root, segments);
|
|
389
|
-
return SignalCompat.prototype.ref.call($target, this.ids);
|
|
390
|
-
}
|
|
391
|
-
removeRef() {
|
|
392
|
-
if (arguments.length > 0)
|
|
393
|
-
throw Error('Signal.removeRef() does not accept any arguments');
|
|
394
|
-
const store = getRefStore(this);
|
|
395
|
-
const fromPath = this.path();
|
|
396
|
-
const existing = store.get(fromPath);
|
|
397
|
-
if (existing) {
|
|
398
|
-
existing.stop();
|
|
399
|
-
store.delete(fromPath);
|
|
400
|
-
}
|
|
401
|
-
const fromRootId = (getRoot(this) || this)?.[ROOT_ID];
|
|
402
|
-
removeRefLink(fromRootId, fromPath);
|
|
403
|
-
const $target = resolveRefSignal(this);
|
|
404
|
-
if ($target !== this) {
|
|
405
|
-
setDiffDeepBypassRef(this, deepCopy($target.get()));
|
|
406
|
-
}
|
|
407
|
-
if (this[REF_TARGET])
|
|
408
|
-
delete this[REF_TARGET];
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
function getRefStore($signal) {
|
|
412
|
-
const $root = getRoot($signal) || $signal;
|
|
413
|
-
const rootId = $root?.[ROOT_ID];
|
|
414
|
-
return getRootContext(rootId, true).activeRefs;
|
|
415
|
-
}
|
|
416
|
-
function createRefLink($from, $to, { mirrorOnly = false } = {}) {
|
|
417
|
-
let disposed = false;
|
|
418
|
-
let pendingRead = null;
|
|
419
|
-
let mirrorObserver;
|
|
420
|
-
const syncFromTarget = () => {
|
|
421
|
-
const value = readRefValue($to);
|
|
422
|
-
if (isThenable(value)) {
|
|
423
|
-
pendingRead = value;
|
|
424
|
-
value.then(() => {
|
|
425
|
-
if (disposed || pendingRead !== value)
|
|
426
|
-
return;
|
|
427
|
-
pendingRead = null;
|
|
428
|
-
syncFromTarget();
|
|
429
|
-
}, () => {
|
|
430
|
-
if (pendingRead === value)
|
|
431
|
-
pendingRead = null;
|
|
432
|
-
});
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
if (value === undefined)
|
|
436
|
-
return;
|
|
437
|
-
setDiffDeepBypassRef($from, deepCopy(value));
|
|
438
|
-
};
|
|
439
|
-
syncFromTarget();
|
|
440
|
-
if (mirrorOnly) {
|
|
441
|
-
mirrorObserver = observe(() => {
|
|
442
|
-
syncFromTarget();
|
|
443
|
-
return readRefValue($to);
|
|
444
|
-
}, {
|
|
445
|
-
scheduler: job => job()
|
|
446
|
-
});
|
|
447
|
-
// initialize dependency graph
|
|
448
|
-
mirrorObserver();
|
|
449
|
-
}
|
|
450
|
-
return {
|
|
451
|
-
onChange: syncFromTarget,
|
|
452
|
-
stop: () => {
|
|
453
|
-
disposed = true;
|
|
454
|
-
if (mirrorObserver)
|
|
455
|
-
unobserve(mirrorObserver);
|
|
456
|
-
// Subsequent sync happens directly at mutation time via mirrorRefMutationFromTarget().
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
function readRefValue($signal) {
|
|
461
|
-
try {
|
|
462
|
-
return $signal.get();
|
|
463
|
-
}
|
|
464
|
-
catch (err) {
|
|
465
|
-
if (isThenable(err))
|
|
466
|
-
return err;
|
|
467
|
-
throw err;
|
|
468
|
-
}
|
|
469
239
|
}
|
|
470
240
|
function isAggregationValuePath(segments) {
|
|
471
241
|
return Array.isArray(segments) &&
|
|
472
242
|
segments.length >= 3 &&
|
|
473
243
|
segments[0] === AGGREGATIONS;
|
|
474
244
|
}
|
|
475
|
-
function resolveRefSignal($signal) {
|
|
476
|
-
const directTarget = resolveRefSignalSafe($signal);
|
|
477
|
-
if (directTarget && directTarget !== $signal)
|
|
478
|
-
return directTarget;
|
|
479
|
-
const resolvedSegments = resolveRefSegmentsSafe($signal[SEGMENTS], (getRoot($signal) || $signal)?.[ROOT_ID]);
|
|
480
|
-
if (!resolvedSegments)
|
|
481
|
-
return $signal;
|
|
482
|
-
const $root = getRoot($signal) || $signal;
|
|
483
|
-
return resolveSignal($root, resolvedSegments);
|
|
484
|
-
}
|
|
485
|
-
function forwardRef($signal, methodName, args) {
|
|
486
|
-
const $target = resolveRefSignal($signal);
|
|
487
|
-
if ($target === $signal)
|
|
488
|
-
return null;
|
|
489
|
-
return SignalCompat.prototype[methodName].apply($target, args);
|
|
490
|
-
}
|
|
491
|
-
function setDiffDeepBypassRef($signal, value) {
|
|
492
|
-
const segments = $signal[SEGMENTS];
|
|
493
|
-
if (isPublicCollection(segments[0]))
|
|
494
|
-
return Signal.prototype.set.call($signal, value);
|
|
495
|
-
return setReplacePrivateData(getOwningRootId($signal), segments, value);
|
|
496
|
-
}
|
|
497
|
-
function mirrorRefMutationFromTarget(targetSegments, value) {
|
|
498
|
-
if (!Array.isArray(targetSegments) || targetSegments.length === 0)
|
|
499
|
-
return;
|
|
500
|
-
const updates = [];
|
|
501
|
-
for (const link of getAllRefLinks()) {
|
|
502
|
-
if (!isPathPrefix(link.toSegments, targetSegments))
|
|
503
|
-
continue;
|
|
504
|
-
const suffix = targetSegments.slice(link.toSegments.length);
|
|
505
|
-
updates.push({
|
|
506
|
-
fromRootId: link.fromRootId,
|
|
507
|
-
segments: link.fromSegments.concat(suffix),
|
|
508
|
-
value: deepCopy(value)
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
if (!updates.length)
|
|
512
|
-
return;
|
|
513
|
-
runInModelEventsSilentContext(() => {
|
|
514
|
-
for (const update of updates) {
|
|
515
|
-
const $root = getRootSignal({
|
|
516
|
-
rootId: update.fromRootId || GLOBAL_ROOT_ID,
|
|
517
|
-
rootFunction: universal$
|
|
518
|
-
});
|
|
519
|
-
const $target = resolveSignal($root, update.segments);
|
|
520
|
-
setDiffDeepBypassRef($target, update.value);
|
|
521
|
-
}
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
function isPathPrefix(prefixSegments, fullSegments) {
|
|
525
|
-
if (prefixSegments.length > fullSegments.length)
|
|
526
|
-
return false;
|
|
527
|
-
for (let i = 0; i < prefixSegments.length; i++) {
|
|
528
|
-
if (String(prefixSegments[i]) !== String(fullSegments[i]))
|
|
529
|
-
return false;
|
|
530
|
-
}
|
|
531
|
-
return true;
|
|
532
|
-
}
|
|
533
|
-
function isSignalLike(value) {
|
|
534
|
-
return value && typeof value.path === 'function' && typeof value.get === 'function';
|
|
535
|
-
}
|
|
536
245
|
function isReactLike(value) {
|
|
537
246
|
return !!(value && typeof value === 'object' && typeof value.$$typeof === 'symbol');
|
|
538
247
|
}
|
|
539
|
-
function isThenable(value) {
|
|
540
|
-
return !!value && typeof value.then === 'function';
|
|
541
|
-
}
|
|
542
|
-
function resolveRefTarget($signal, target, methodName) {
|
|
543
|
-
if (isSignalLike(target))
|
|
544
|
-
return target;
|
|
545
|
-
if (typeof target === 'string') {
|
|
546
|
-
const segments = parseAtSubpath(target, 1, methodName);
|
|
547
|
-
const $root = getRoot($signal) || $signal;
|
|
548
|
-
return resolveSignal($root, segments);
|
|
549
|
-
}
|
|
550
|
-
return undefined;
|
|
551
|
-
}
|
|
552
|
-
function parseAtSubpath(subpath, argsLength, methodName) {
|
|
553
|
-
if (argsLength === 0)
|
|
554
|
-
return [];
|
|
555
|
-
if (typeof subpath === 'string')
|
|
556
|
-
return subpath.split('.').filter(Boolean);
|
|
557
|
-
if (typeof subpath === 'number' && Number.isFinite(subpath) && Number.isInteger(subpath))
|
|
558
|
-
return [subpath];
|
|
559
|
-
throw Error(`${methodName} expects a string or integer argument`);
|
|
560
|
-
}
|
|
561
248
|
function resolveSignal($signal, segments) {
|
|
562
249
|
let $cursor = $signal;
|
|
563
250
|
for (const segment of segments) {
|
|
@@ -716,9 +403,6 @@ function setReplacePrivateCompatSync($signal, value) {
|
|
|
716
403
|
value = normalizeIdFields(value, idFields, segments[1]);
|
|
717
404
|
}
|
|
718
405
|
setReplacePrivateData(getOwningRootId($signal), segments, value);
|
|
719
|
-
if (shouldMirrorPrivateRefMutationLocally()) {
|
|
720
|
-
mirrorRefMutationFromTarget(segments, value);
|
|
721
|
-
}
|
|
722
406
|
}
|
|
723
407
|
function delPrivateCompatSync($signal, options) {
|
|
724
408
|
const segments = $signal[SEGMENTS];
|
|
@@ -775,17 +459,9 @@ async function setReplaceOnSignal($signal, value) {
|
|
|
775
459
|
value = normalizeIdFields(value, idFields, segments[1]);
|
|
776
460
|
}
|
|
777
461
|
if (isPublicCollection(segments[0])) {
|
|
778
|
-
|
|
779
|
-
if (shouldMirrorPublicRefMutationLocally(segments)) {
|
|
780
|
-
mirrorRefMutationFromTarget(segments, value);
|
|
781
|
-
}
|
|
782
|
-
return result;
|
|
783
|
-
}
|
|
784
|
-
const result = setReplacePrivateData(getOwningRootId($signal), segments, value);
|
|
785
|
-
if (shouldMirrorPrivateRefMutationLocally()) {
|
|
786
|
-
mirrorRefMutationFromTarget(segments, value);
|
|
462
|
+
return _setPublicDocReplace(segments, value);
|
|
787
463
|
}
|
|
788
|
-
return
|
|
464
|
+
return setReplacePrivateData(getOwningRootId($signal), segments, value);
|
|
789
465
|
}
|
|
790
466
|
async function incrementOnSignal($signal, byNumber) {
|
|
791
467
|
const segments = $signal[SEGMENTS];
|
|
@@ -911,28 +587,6 @@ function getOwningRootId($signal) {
|
|
|
911
587
|
const $root = getRoot($signal) || $signal;
|
|
912
588
|
return $root?.[ROOT_ID];
|
|
913
589
|
}
|
|
914
|
-
function ensurePrivateRefSource($signal, methodName) {
|
|
915
|
-
const segments = $signal?.[SEGMENTS];
|
|
916
|
-
const collection = segments?.[0];
|
|
917
|
-
if (typeof collection === 'string' && /^[_$]/.test(collection))
|
|
918
|
-
return;
|
|
919
|
-
throw Error(`${methodName} source path must be in a private collection`);
|
|
920
|
-
}
|
|
921
|
-
function shouldMirrorPublicRefMutationLocally(segments) {
|
|
922
|
-
if (isSilentContextActive())
|
|
923
|
-
return true;
|
|
924
|
-
if (!Array.isArray(segments) || segments.length < 2)
|
|
925
|
-
return true;
|
|
926
|
-
// Public doc ops emit compat model events only when there is an initialized
|
|
927
|
-
// Doc runtime (subscribed/fetched). Without runtime we must mirror immediately.
|
|
928
|
-
const transportHash = JSON.stringify([segments[0], segments[1]]);
|
|
929
|
-
return !docSubscriptions.hasRuntime(transportHash);
|
|
930
|
-
}
|
|
931
|
-
function shouldMirrorPrivateRefMutationLocally() {
|
|
932
|
-
if (isSilentContextActive())
|
|
933
|
-
return true;
|
|
934
|
-
return !isModelEventsEnabled();
|
|
935
|
-
}
|
|
936
590
|
function shallowCopy(value) {
|
|
937
591
|
const rawValue = raw(value);
|
|
938
592
|
if (Array.isArray(rawValue))
|
|
@@ -953,75 +607,6 @@ function deepCopy(value) {
|
|
|
953
607
|
}
|
|
954
608
|
return racerDeepCopy(rawValue);
|
|
955
609
|
}
|
|
956
|
-
function subscribeMany(items, action, intent = 'subscribe', methodName = action) {
|
|
957
|
-
const targets = flattenItems(items);
|
|
958
|
-
const promises = [];
|
|
959
|
-
for (const target of targets) {
|
|
960
|
-
if (!target)
|
|
961
|
-
continue;
|
|
962
|
-
if (!(target instanceof Signal)) {
|
|
963
|
-
throw Error(`Signal.${methodName}() accepts only Signal instances. Got: ${target}`);
|
|
964
|
-
}
|
|
965
|
-
const result = action === 'subscribe'
|
|
966
|
-
? subscribeSelf(target, intent, methodName)
|
|
967
|
-
: unsubscribeSelf(target, intent, methodName);
|
|
968
|
-
if (result?.then)
|
|
969
|
-
promises.push(result);
|
|
970
|
-
}
|
|
971
|
-
if (promises.length)
|
|
972
|
-
return Promise.all(promises);
|
|
973
|
-
}
|
|
974
|
-
function flattenItems(items, result = []) {
|
|
975
|
-
for (const item of items) {
|
|
976
|
-
if (!item)
|
|
977
|
-
continue;
|
|
978
|
-
if (Array.isArray(item)) {
|
|
979
|
-
flattenItems(item, result);
|
|
980
|
-
}
|
|
981
|
-
else {
|
|
982
|
-
result.push(item);
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
return result;
|
|
986
|
-
}
|
|
987
|
-
function subscribeSelf($signal, intent = 'subscribe', methodName = 'subscribe') {
|
|
988
|
-
if ($signal[IS_QUERY]) {
|
|
989
|
-
return (async () => {
|
|
990
|
-
await querySubscriptions.subscribe($signal, { intent });
|
|
991
|
-
await waitForImperativeQueryReady($signal);
|
|
992
|
-
})();
|
|
993
|
-
}
|
|
994
|
-
if ($signal[IS_AGGREGATION]) {
|
|
995
|
-
return (async () => {
|
|
996
|
-
await aggregationSubscriptions.subscribe($signal, { intent });
|
|
997
|
-
await waitForImperativeQueryReady($signal);
|
|
998
|
-
})();
|
|
999
|
-
}
|
|
1000
|
-
if (isPublicDocumentSignal($signal))
|
|
1001
|
-
return docSubscriptions.subscribe($signal, { intent });
|
|
1002
|
-
if (isPublicCollectionSignal($signal)) {
|
|
1003
|
-
throw Error(`Signal.${methodName}() expects a document or query signal. Use sub($collection, params, { mode: 'fetch' }) for collection fetches.`);
|
|
1004
|
-
}
|
|
1005
|
-
if ($signal[SEGMENTS].length === 0) {
|
|
1006
|
-
throw Error(`Signal.${methodName}() cannot be called on the root signal`);
|
|
1007
|
-
}
|
|
1008
|
-
throw Error(`Signal.${methodName}() expects a document or query signal`);
|
|
1009
|
-
}
|
|
1010
|
-
function unsubscribeSelf($signal, intent = 'subscribe', methodName = 'unsubscribe') {
|
|
1011
|
-
if ($signal[IS_QUERY])
|
|
1012
|
-
return querySubscriptions.unsubscribe($signal, { intent });
|
|
1013
|
-
if ($signal[IS_AGGREGATION])
|
|
1014
|
-
return aggregationSubscriptions.unsubscribe($signal, { intent });
|
|
1015
|
-
if (isPublicDocumentSignal($signal))
|
|
1016
|
-
return docSubscriptions.unsubscribe($signal, { intent });
|
|
1017
|
-
if (isPublicCollectionSignal($signal)) {
|
|
1018
|
-
throw Error(`Signal.${methodName}() expects a document or query signal`);
|
|
1019
|
-
}
|
|
1020
|
-
if ($signal[SEGMENTS].length === 0) {
|
|
1021
|
-
throw Error(`Signal.${methodName}() cannot be called on the root signal`);
|
|
1022
|
-
}
|
|
1023
|
-
throw Error(`Signal.${methodName}() expects a document or query signal`);
|
|
1024
|
-
}
|
|
1025
610
|
// Racer-style deep copy:
|
|
1026
611
|
// - Preserves prototypes by instantiating via `new value.constructor()`
|
|
1027
612
|
// - Copies own enumerable props recursively
|