opshot 0.3.4 → 0.4.0
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 +33 -39
- package/dist/index.d.ts +435 -42
- package/dist/index.js +2993 -1241
- package/package.json +20 -10
package/dist/index.js
CHANGED
|
@@ -1,69 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { memo, useState, useReducer, useRef, useEffect, createElement, useLayoutEffect } from 'react';
|
|
2
3
|
|
|
3
4
|
// node_modules/proxy-compare/dist/index.js
|
|
4
5
|
var GET_ORIGINAL_SYMBOL = /* @__PURE__ */ Symbol();
|
|
5
|
-
var HAS_KEY_PROPERTY = "h";
|
|
6
|
-
var ALL_OWN_KEYS_PROPERTY = "w";
|
|
7
|
-
var HAS_OWN_KEY_PROPERTY = "o";
|
|
8
|
-
var KEYS_PROPERTY = "k";
|
|
9
6
|
var getProto = Object.getPrototypeOf;
|
|
10
7
|
var objectsToTrack = /* @__PURE__ */ new WeakMap();
|
|
11
8
|
var isObjectToTrack = (obj) => obj && (objectsToTrack.has(obj) ? objectsToTrack.get(obj) : getProto(obj) === Object.prototype || getProto(obj) === Array.prototype);
|
|
12
|
-
var isObject = (x) => typeof x === "object" && x !== null;
|
|
13
|
-
var getOriginalObject = (obj) => (
|
|
14
|
-
// unwrap proxy
|
|
15
|
-
obj[GET_ORIGINAL_SYMBOL] || // otherwise
|
|
16
|
-
obj
|
|
17
|
-
);
|
|
18
|
-
var isAllOwnKeysChanged = (prevObj, nextObj) => {
|
|
19
|
-
const prevKeys = Reflect.ownKeys(prevObj);
|
|
20
|
-
const nextKeys = Reflect.ownKeys(nextObj);
|
|
21
|
-
return prevKeys.length !== nextKeys.length || prevKeys.some((k, i) => k !== nextKeys[i]);
|
|
22
|
-
};
|
|
23
|
-
var isChanged = (prevObj, nextObj, affected, cache, isEqual = Object.is) => {
|
|
24
|
-
if (isEqual(prevObj, nextObj)) {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
if (!isObject(prevObj) || !isObject(nextObj))
|
|
28
|
-
return true;
|
|
29
|
-
const used = affected.get(getOriginalObject(prevObj));
|
|
30
|
-
if (!used)
|
|
31
|
-
return true;
|
|
32
|
-
if (cache) {
|
|
33
|
-
const hit = cache.get(prevObj);
|
|
34
|
-
if (hit === nextObj) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
cache.set(prevObj, nextObj);
|
|
38
|
-
}
|
|
39
|
-
let changed = null;
|
|
40
|
-
for (const key of used[HAS_KEY_PROPERTY] || []) {
|
|
41
|
-
changed = Reflect.has(prevObj, key) !== Reflect.has(nextObj, key);
|
|
42
|
-
if (changed)
|
|
43
|
-
return changed;
|
|
44
|
-
}
|
|
45
|
-
if (used[ALL_OWN_KEYS_PROPERTY] === true) {
|
|
46
|
-
changed = isAllOwnKeysChanged(prevObj, nextObj);
|
|
47
|
-
if (changed)
|
|
48
|
-
return changed;
|
|
49
|
-
} else {
|
|
50
|
-
for (const key of used[HAS_OWN_KEY_PROPERTY] || []) {
|
|
51
|
-
const hasPrev = !!Reflect.getOwnPropertyDescriptor(prevObj, key);
|
|
52
|
-
const hasNext = !!Reflect.getOwnPropertyDescriptor(nextObj, key);
|
|
53
|
-
changed = hasPrev !== hasNext;
|
|
54
|
-
if (changed)
|
|
55
|
-
return changed;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
for (const key of used[KEYS_PROPERTY] || []) {
|
|
59
|
-
changed = isChanged(prevObj[key], nextObj[key], affected, cache, isEqual);
|
|
60
|
-
if (changed)
|
|
61
|
-
return changed;
|
|
62
|
-
}
|
|
63
|
-
if (changed === null)
|
|
64
|
-
throw new Error("invalid used");
|
|
65
|
-
return changed;
|
|
66
|
-
};
|
|
67
9
|
var getUntracked = (obj) => {
|
|
68
10
|
if (isObjectToTrack(obj)) {
|
|
69
11
|
return obj[GET_ORIGINAL_SYMBOL] || null;
|
|
@@ -75,8 +17,8 @@ var markToTrack = (obj, mark = true) => {
|
|
|
75
17
|
};
|
|
76
18
|
|
|
77
19
|
// node_modules/valtio/esm/vanilla.mjs
|
|
78
|
-
var
|
|
79
|
-
var canProxyDefault = (x) =>
|
|
20
|
+
var isObject = (x) => typeof x === "object" && x !== null;
|
|
21
|
+
var canProxyDefault = (x) => isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer) && !(x instanceof Promise);
|
|
80
22
|
var createSnapshotDefault = (target, version) => {
|
|
81
23
|
const cache = snapCache.get(target);
|
|
82
24
|
if ((cache == null ? void 0 : cache[0]) === version) {
|
|
@@ -130,7 +72,7 @@ var createHandlerDefault = (isInitializing, addPropListener, removePropListener,
|
|
|
130
72
|
return true;
|
|
131
73
|
}
|
|
132
74
|
removePropListener(prop);
|
|
133
|
-
if (
|
|
75
|
+
if (isObject(value)) {
|
|
134
76
|
value = getUntracked(value) || value;
|
|
135
77
|
}
|
|
136
78
|
const nextValue = !proxyStateMap.has(value) && canProxy(value) ? proxy(value) : value;
|
|
@@ -151,7 +93,7 @@ var canProxy = canProxyDefault;
|
|
|
151
93
|
var createSnapshot = createSnapshotDefault;
|
|
152
94
|
var createHandler = createHandlerDefault;
|
|
153
95
|
function proxy(baseObject = {}) {
|
|
154
|
-
if (!
|
|
96
|
+
if (!isObject(baseObject)) {
|
|
155
97
|
throw new Error("object required");
|
|
156
98
|
}
|
|
157
99
|
const found = proxyCache.get(baseObject);
|
|
@@ -266,31 +208,19 @@ function subscribe(proxyObject, callback, notifyInSync) {
|
|
|
266
208
|
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !proxyState) {
|
|
267
209
|
console.warn("Please use proxy object");
|
|
268
210
|
}
|
|
269
|
-
let promise;
|
|
270
211
|
const ops = [];
|
|
271
212
|
const addListener = proxyState[2];
|
|
272
|
-
let isListenerActive = false;
|
|
273
213
|
const listener = (op) => {
|
|
274
214
|
if (op) {
|
|
275
215
|
ops.push(op);
|
|
276
216
|
}
|
|
277
|
-
|
|
217
|
+
{
|
|
278
218
|
callback(ops.splice(0));
|
|
279
219
|
return;
|
|
280
220
|
}
|
|
281
|
-
if (!promise) {
|
|
282
|
-
promise = Promise.resolve().then(() => {
|
|
283
|
-
promise = void 0;
|
|
284
|
-
if (isListenerActive) {
|
|
285
|
-
callback(ops.splice(0));
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
221
|
};
|
|
290
222
|
const removeListener = addListener(listener);
|
|
291
|
-
isListenerActive = true;
|
|
292
223
|
return () => {
|
|
293
|
-
isListenerActive = false;
|
|
294
224
|
removeListener();
|
|
295
225
|
};
|
|
296
226
|
}
|
|
@@ -302,10 +232,6 @@ function snapshot(proxyObject) {
|
|
|
302
232
|
const [target, ensureVersion] = proxyState;
|
|
303
233
|
return createSnapshot(target, ensureVersion());
|
|
304
234
|
}
|
|
305
|
-
function ref(obj) {
|
|
306
|
-
refSet.add(obj);
|
|
307
|
-
return obj;
|
|
308
|
-
}
|
|
309
235
|
function unstable_getInternalStates() {
|
|
310
236
|
return {
|
|
311
237
|
proxyStateMap,
|
|
@@ -337,19 +263,222 @@ function unstable_replaceInternalFunction(name, fn) {
|
|
|
337
263
|
}
|
|
338
264
|
}
|
|
339
265
|
|
|
340
|
-
// src/
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
266
|
+
// src/declarations.ts
|
|
267
|
+
function createDeclarationTrie() {
|
|
268
|
+
return { ignored: false, unsafe: false, children: /* @__PURE__ */ new Map() };
|
|
269
|
+
}
|
|
270
|
+
function declarationChild(trie, key) {
|
|
271
|
+
return trie?.children.get(String(key));
|
|
272
|
+
}
|
|
273
|
+
function ensureDeclarationChild(trie, key) {
|
|
274
|
+
const name = String(key);
|
|
275
|
+
const existing = trie.children.get(name);
|
|
276
|
+
if (existing !== void 0) return existing;
|
|
277
|
+
const child = createDeclarationTrie();
|
|
278
|
+
trie.children.set(name, child);
|
|
279
|
+
return child;
|
|
280
|
+
}
|
|
281
|
+
function declarationAtPath(trie, path) {
|
|
282
|
+
let current = trie;
|
|
283
|
+
for (const segment of path) current = ensureDeclarationChild(current, segment);
|
|
284
|
+
return current;
|
|
285
|
+
}
|
|
286
|
+
function graftDeclarationChildren(source, target) {
|
|
287
|
+
for (const [key, sourceChild] of source.children) {
|
|
288
|
+
const targetChild = ensureDeclarationChild(target, key);
|
|
289
|
+
if (sourceChild.ignored) targetChild.ignored = true;
|
|
290
|
+
if (sourceChild.unsafe) targetChild.unsafe = true;
|
|
291
|
+
graftDeclarationChildren(sourceChild, targetChild);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function hasDeclarations(trie) {
|
|
295
|
+
if (trie.ignored || trie.unsafe) return true;
|
|
296
|
+
for (const child of trie.children.values()) {
|
|
297
|
+
if (hasDeclarations(child)) return true;
|
|
298
|
+
}
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/identity.ts
|
|
303
|
+
var isObjectLike = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
304
|
+
var targetRegistry = /* @__PURE__ */ new WeakMap();
|
|
305
|
+
var readProxyTargets = /* @__PURE__ */ new WeakMap();
|
|
306
|
+
var identityRecords = /* @__PURE__ */ new WeakMap();
|
|
307
|
+
var nextInternId = 0;
|
|
308
|
+
var { proxyStateMap: proxyStateMap2 } = unstable_getInternalStates();
|
|
309
|
+
function registerSnapshotCopy(copy, target) {
|
|
310
|
+
targetRegistry.set(copy, target);
|
|
311
|
+
}
|
|
312
|
+
function getRegisteredTarget(copy) {
|
|
313
|
+
return targetRegistry.get(copy);
|
|
314
|
+
}
|
|
315
|
+
var registerReadProxyTarget = (readProxy, target) => {
|
|
316
|
+
readProxyTargets.set(readProxy, target);
|
|
317
|
+
};
|
|
318
|
+
var getRegisteredReadProxyTarget = (readProxy) => readProxyTargets.get(readProxy);
|
|
319
|
+
function peelIdentityLayer(current) {
|
|
320
|
+
const untracked = getUntracked(current);
|
|
321
|
+
if (untracked !== null && untracked !== current) return untracked;
|
|
322
|
+
const readProxyTarget = getRegisteredReadProxyTarget(current);
|
|
323
|
+
if (readProxyTarget !== void 0 && readProxyTarget !== current) return readProxyTarget;
|
|
324
|
+
const registeredTarget = targetRegistry.get(current);
|
|
325
|
+
if (registeredTarget !== void 0 && registeredTarget !== current) return registeredTarget;
|
|
326
|
+
return void 0;
|
|
327
|
+
}
|
|
328
|
+
function resolveIdentity(value) {
|
|
329
|
+
let current = value;
|
|
330
|
+
while (isObjectLike(current)) {
|
|
331
|
+
const peeled = peelIdentityLayer(current);
|
|
332
|
+
if (peeled !== void 0) {
|
|
333
|
+
current = peeled;
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
const entry = proxyStateMap2.get(current);
|
|
337
|
+
if (entry !== void 0) {
|
|
338
|
+
const target = entry[0];
|
|
339
|
+
if (target !== current) {
|
|
340
|
+
current = target;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
return current;
|
|
347
|
+
}
|
|
348
|
+
var recordFor = (key) => {
|
|
349
|
+
let record = identityRecords.get(key);
|
|
350
|
+
if (record === void 0) {
|
|
351
|
+
record = {};
|
|
352
|
+
identityRecords.set(key, record);
|
|
353
|
+
}
|
|
354
|
+
return record;
|
|
355
|
+
};
|
|
356
|
+
function identify(value) {
|
|
357
|
+
const target = resolveIdentity(value);
|
|
358
|
+
if (!isObjectLike(target)) return value;
|
|
359
|
+
const record = recordFor(target);
|
|
360
|
+
if (record.token !== void 0) return record.token;
|
|
361
|
+
const token = Object.freeze({});
|
|
362
|
+
record.token = token;
|
|
363
|
+
return token;
|
|
364
|
+
}
|
|
365
|
+
var internIdentity = (key) => {
|
|
366
|
+
const resolved = resolveIdentity(key);
|
|
367
|
+
const record = recordFor(resolved);
|
|
368
|
+
if (record.id !== void 0) return record.id;
|
|
369
|
+
const id = nextInternId;
|
|
370
|
+
nextInternId += 1;
|
|
371
|
+
record.id = id;
|
|
372
|
+
return id;
|
|
373
|
+
};
|
|
374
|
+
function isSameIdentity(first, second) {
|
|
375
|
+
const resolvedFirst = resolveIdentity(first);
|
|
376
|
+
const resolvedSecond = resolveIdentity(second);
|
|
377
|
+
return resolvedFirst === resolvedSecond;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/peelReadProxy.ts
|
|
381
|
+
var { proxyStateMap: proxyStateMap3 } = unstable_getInternalStates();
|
|
382
|
+
var isObjectLike2 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
383
|
+
function peelReadProxy(value) {
|
|
384
|
+
if (!isObjectLike2(value) || proxyStateMap3.has(value)) return value;
|
|
385
|
+
let current = value;
|
|
386
|
+
while (isObjectLike2(current)) {
|
|
387
|
+
const registeredTarget = getRegisteredReadProxyTarget(current);
|
|
388
|
+
if (registeredTarget === void 0) break;
|
|
389
|
+
current = registeredTarget;
|
|
390
|
+
}
|
|
391
|
+
return current;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/handle.ts
|
|
395
|
+
var occupancies = /* @__PURE__ */ new WeakMap();
|
|
396
|
+
var { proxyStateMap: proxyStateMap4 } = unstable_getInternalStates();
|
|
397
|
+
var rawTargetOf = (value) => proxyStateMap4.get(value)?.[0] ?? value;
|
|
398
|
+
function registerHandle(target, handle) {
|
|
399
|
+
let occupants = occupancies.get(target);
|
|
400
|
+
if (occupants === void 0) {
|
|
401
|
+
occupants = /* @__PURE__ */ new Set();
|
|
402
|
+
occupancies.set(target, occupants);
|
|
403
|
+
}
|
|
404
|
+
for (const reference of occupants) {
|
|
405
|
+
if (reference.deref() === handle) return;
|
|
406
|
+
}
|
|
407
|
+
occupants.add(new WeakRef(handle));
|
|
408
|
+
}
|
|
409
|
+
var rawOf = (node) => {
|
|
410
|
+
const peeled = peelReadProxy(node);
|
|
411
|
+
return rawTargetOf(typeof peeled === "object" && peeled !== null ? peeled : node);
|
|
412
|
+
};
|
|
413
|
+
function handlesOf(node) {
|
|
414
|
+
const target = rawOf(node);
|
|
415
|
+
const occupants = occupancies.get(target);
|
|
416
|
+
if (occupants === void 0) return [];
|
|
417
|
+
const handles = new Array();
|
|
418
|
+
for (const reference of occupants) {
|
|
419
|
+
const handle = reference.deref();
|
|
420
|
+
if (handle === void 0) {
|
|
421
|
+
occupants.delete(reference);
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
handles.push(handle);
|
|
425
|
+
}
|
|
426
|
+
return handles;
|
|
345
427
|
}
|
|
346
|
-
function
|
|
347
|
-
|
|
428
|
+
function handleOf(node) {
|
|
429
|
+
const target = rawOf(node);
|
|
430
|
+
for (const handle of handlesOf(node)) {
|
|
431
|
+
if (rawTargetOf(handle.proxy.root) === target) return handle;
|
|
432
|
+
}
|
|
433
|
+
return void 0;
|
|
348
434
|
}
|
|
435
|
+
function requireHandle(state, message) {
|
|
436
|
+
const handle = handleOf(state);
|
|
437
|
+
if (handle === void 0) throw new Error(message);
|
|
438
|
+
return handle;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// src/ops/predicates.ts
|
|
442
|
+
var MAX_ARRAY_LENGTH = 4294967295;
|
|
443
|
+
var isObjectLike3 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
444
|
+
var isCanonicalArrayIndex = (segment) => Number.isInteger(segment) && typeof segment === "number" && segment >= 0 && segment < MAX_ARRAY_LENGTH;
|
|
445
|
+
var isCanonicalArrayIndexString = (key) => {
|
|
446
|
+
const index = Number(key);
|
|
447
|
+
return Number.isInteger(index) && index >= 0 && index < MAX_ARRAY_LENGTH && String(index) === key;
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
// src/utils/dataEntries.ts
|
|
451
|
+
var walkDataEntries = (value, includeArrayLength = false) => {
|
|
452
|
+
const entries = new Array();
|
|
453
|
+
for (const key of Object.keys(value)) {
|
|
454
|
+
if (key === "__proto__") continue;
|
|
455
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
456
|
+
if (!descriptor || !("value" in descriptor)) continue;
|
|
457
|
+
entries.push({ key, value: descriptor.value, writable: descriptor.writable === true });
|
|
458
|
+
}
|
|
459
|
+
if (includeArrayLength && Array.isArray(value)) {
|
|
460
|
+
const lengthDescriptor = Reflect.getOwnPropertyDescriptor(value, "length");
|
|
461
|
+
entries.push({
|
|
462
|
+
key: "length",
|
|
463
|
+
value: value.length,
|
|
464
|
+
writable: lengthDescriptor?.writable === true
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
return entries;
|
|
468
|
+
};
|
|
469
|
+
var segmentFor = (parent, key) => Array.isArray(parent) && isCanonicalArrayIndexString(key) ? Number(key) : key;
|
|
470
|
+
var dataEntryValuesOf = (value) => {
|
|
471
|
+
const entries = /* @__PURE__ */ new Map();
|
|
472
|
+
for (const entry of walkDataEntries(value)) {
|
|
473
|
+
entries.set(entry.key, entry.value);
|
|
474
|
+
}
|
|
475
|
+
return entries;
|
|
476
|
+
};
|
|
477
|
+
var carriedOwnKeysOf = (value) => Reflect.ownKeys(value).filter((key) => key !== "__proto__");
|
|
349
478
|
|
|
350
479
|
// src/valtio/classify.ts
|
|
351
|
-
var { refSet: refSet2 } = unstable_getInternalStates();
|
|
352
480
|
var sourceCache = /* @__PURE__ */ new WeakMap();
|
|
481
|
+
var kindCache = /* @__PURE__ */ new WeakMap();
|
|
353
482
|
var readSource = (constructor) => {
|
|
354
483
|
const cached = sourceCache.get(constructor);
|
|
355
484
|
if (cached !== void 0) return cached;
|
|
@@ -357,16 +486,31 @@ var readSource = (constructor) => {
|
|
|
357
486
|
sourceCache.set(constructor, source);
|
|
358
487
|
return source;
|
|
359
488
|
};
|
|
489
|
+
var privateNameAccess = /\.\s*#[A-Za-z_$]/;
|
|
490
|
+
var privateNameDeclaration = new RegExp(
|
|
491
|
+
String.raw`[{;}](?:\s|\/\*[\s\S]*?\*\/|\/\/[^\n]*\n|static\b|async\b|get\b|set\b|\*)*` + String.raw`#[A-Za-z_$][\w$]*` + String.raw`(?:[ \t]*(?:\/\*[\s\S]*?\*\/[ \t]*)*[(=;}]|[ \t]*(?:\/\/[^\n]*|\/\*[\s\S]*?\*\/[ \t]*)?(?:\r?\n|$))`,
|
|
492
|
+
"m"
|
|
493
|
+
);
|
|
494
|
+
var hasPrivateName = (source) => privateNameAccess.test(source) || privateNameDeclaration.test(source);
|
|
360
495
|
var classifyChain = (initialConstructor) => {
|
|
496
|
+
if (typeof initialConstructor !== "function") return "cleanClass";
|
|
497
|
+
const cached = kindCache.get(initialConstructor);
|
|
498
|
+
if (cached !== void 0) return cached;
|
|
361
499
|
let sawNativeSource = false;
|
|
362
500
|
let current = initialConstructor;
|
|
501
|
+
let kind = "cleanClass";
|
|
363
502
|
while (typeof current === "function" && current !== Object && current !== Array && current !== Function.prototype) {
|
|
364
503
|
const source = readSource(current);
|
|
365
|
-
if (source
|
|
504
|
+
if (hasPrivateName(source)) {
|
|
505
|
+
kind = "privateClass";
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
366
508
|
if (source.includes("[native code]")) sawNativeSource = true;
|
|
367
509
|
current = Reflect.getPrototypeOf(current);
|
|
368
510
|
}
|
|
369
|
-
|
|
511
|
+
if (kind !== "privateClass") kind = sawNativeSource ? "nativeClass" : "cleanClass";
|
|
512
|
+
kindCache.set(initialConstructor, kind);
|
|
513
|
+
return kind;
|
|
370
514
|
};
|
|
371
515
|
function classifyValue(value) {
|
|
372
516
|
const prototype = Object.getPrototypeOf(value);
|
|
@@ -375,142 +519,71 @@ function classifyValue(value) {
|
|
|
375
519
|
if (prototype === Object.prototype || prototype === null) return "plain";
|
|
376
520
|
return classifyChain(value.constructor);
|
|
377
521
|
}
|
|
378
|
-
function
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
522
|
+
function unfrozenAdmissionDecision(value) {
|
|
523
|
+
if (typeof value !== "object" || value === null) return { lane: "leaf" };
|
|
524
|
+
const kind = classifyValue(value);
|
|
525
|
+
if (kind === "plain" || kind === "plainArray" || kind === "cleanClass") return { lane: "tracked" };
|
|
526
|
+
return { lane: "dangerous", kind };
|
|
527
|
+
}
|
|
528
|
+
function admissionDecision(value) {
|
|
529
|
+
if (typeof value !== "object" || value === null) return { lane: "leaf" };
|
|
530
|
+
if (Object.isFrozen(value)) return { lane: "untracked" };
|
|
531
|
+
return unfrozenAdmissionDecision(value);
|
|
385
532
|
}
|
|
386
533
|
function admissionLane(value) {
|
|
387
|
-
|
|
388
|
-
if (refSet2.has(value)) return "leaf";
|
|
389
|
-
if (isUnsafeTracked(value)) return "track";
|
|
390
|
-
const kind = classifyValue(value);
|
|
391
|
-
if ((kind === "plain" || kind === "plainArray" || kind === "cleanClass") && Object.isFrozen(value)) return "leaf";
|
|
392
|
-
if (kind === "plain" || kind === "plainArray") return "track";
|
|
393
|
-
if (kind === "cleanClass" && !hasOwnEnumerableFunction(value)) return "track";
|
|
394
|
-
return "reject";
|
|
534
|
+
return admissionDecision(value).lane;
|
|
395
535
|
}
|
|
396
|
-
function
|
|
397
|
-
return
|
|
536
|
+
function unfrozenAdmissionLane(value) {
|
|
537
|
+
return unfrozenAdmissionDecision(value).lane;
|
|
398
538
|
}
|
|
399
539
|
|
|
400
|
-
// src/ops/path.ts
|
|
401
|
-
var createOperationPath = (segments) => Object.freeze([...segments]);
|
|
402
|
-
var appendOperationPath = (path, segment) => Object.freeze([...path, segment]);
|
|
403
|
-
var escapeSegment = (segment) => segment.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
404
|
-
var formatSegment = (segment) => typeof segment === "string" ? escapeSegment(segment) : String(segment);
|
|
405
|
-
var formatOperationPath = (path) => path.length === 0 ? "" : `/${path.map(formatSegment).join("/")}`;
|
|
406
|
-
var assertSafePath = (path) => {
|
|
407
|
-
for (let index = 0; index < path.length; index++) {
|
|
408
|
-
const segment = path[index];
|
|
409
|
-
if (segment === "__proto__" || segment === "prototype" && path[index - 1] === "constructor") {
|
|
410
|
-
throw new Error(`opshot: reserved operation path ${formatOperationPath(path)}`);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
};
|
|
414
|
-
|
|
415
540
|
// src/ops/cloneValue.ts
|
|
416
|
-
var {
|
|
417
|
-
var
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
constructor(path) {
|
|
422
|
-
super(`opshot: cyclic value at ${formatOperationPath(path)}; use ignore() for back-linked structures, or ids`);
|
|
423
|
-
this.name = "CyclicValueError";
|
|
424
|
-
this.path = createOperationPath(path);
|
|
541
|
+
var { proxyStateMap: proxyStateMap5 } = unstable_getInternalStates();
|
|
542
|
+
var MissingOwnDescriptorError = class extends Error {
|
|
543
|
+
constructor() {
|
|
544
|
+
super("opshot: carried own key has no property descriptor");
|
|
545
|
+
this.name = "MissingOwnDescriptorError";
|
|
425
546
|
}
|
|
426
547
|
};
|
|
427
|
-
var
|
|
428
|
-
var
|
|
429
|
-
var
|
|
548
|
+
var isInstrumented = (value) => proxyStateMap5.has(value) || getRegisteredTarget(value) !== void 0;
|
|
549
|
+
var isPlainArray = (value) => Array.isArray(value);
|
|
550
|
+
var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && (admissionLane(value) === "tracked" || isInstrumented(value));
|
|
551
|
+
var isStructurallyCloneableFrozen = (value) => {
|
|
552
|
+
if (!Object.isFrozen(value)) return false;
|
|
553
|
+
if (Array.isArray(value)) return true;
|
|
554
|
+
const prototype = Object.getPrototypeOf(value);
|
|
555
|
+
return prototype === Object.prototype || prototype === null;
|
|
556
|
+
};
|
|
557
|
+
var isCloneable = (value) => typeof value === "object" && value !== null && (admissionLane(value) === "tracked" || isInstrumented(value) || isStructurallyCloneableFrozen(value));
|
|
430
558
|
var cloneValue = (value, memo2, path) => {
|
|
431
559
|
if (!isCloneable(value)) return value;
|
|
432
560
|
const cached = memo2.get(value);
|
|
433
|
-
if (cached === CLONE_IN_PROGRESS) throw cyclicError(path);
|
|
434
561
|
if (cached !== void 0) return cached;
|
|
435
|
-
memo2.set(value, CLONE_IN_PROGRESS);
|
|
436
562
|
const array = isPlainArray(value);
|
|
437
563
|
const clone = array ? [] : {};
|
|
438
564
|
Reflect.setPrototypeOf(clone, Reflect.getPrototypeOf(value));
|
|
439
|
-
|
|
565
|
+
memo2.set(value, clone);
|
|
566
|
+
for (const key of carriedOwnKeysOf(value)) {
|
|
440
567
|
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
441
|
-
if (
|
|
568
|
+
if (descriptor === void 0) throw new MissingOwnDescriptorError();
|
|
442
569
|
if ("value" in descriptor) {
|
|
443
570
|
Object.defineProperty(clone, key, {
|
|
444
571
|
...descriptor,
|
|
445
|
-
value: cloneValue(descriptor.value, memo2
|
|
572
|
+
value: cloneValue(descriptor.value, memo2)
|
|
446
573
|
});
|
|
447
574
|
} else {
|
|
448
575
|
Object.defineProperty(clone, key, descriptor);
|
|
449
576
|
}
|
|
450
577
|
}
|
|
451
|
-
|
|
452
|
-
if (isUnsafeTracked(value)) unsafeTrack(clone);
|
|
578
|
+
if (Object.isFrozen(value)) Object.freeze(clone);
|
|
453
579
|
return clone;
|
|
454
580
|
};
|
|
455
581
|
|
|
456
|
-
// src/
|
|
457
|
-
var
|
|
458
|
-
var
|
|
459
|
-
|
|
460
|
-
}
|
|
461
|
-
var getRegisteredWrapperTarget = (wrapper) => wrapperTargets.get(wrapper);
|
|
462
|
-
|
|
463
|
-
// src/identity.ts
|
|
464
|
-
var isObjectLike = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
465
|
-
var targetRegistry = /* @__PURE__ */ new WeakMap();
|
|
466
|
-
var identityTokenRegistry = /* @__PURE__ */ new WeakMap();
|
|
467
|
-
var { proxyStateMap: proxyStateMap2 } = unstable_getInternalStates();
|
|
468
|
-
function registerSnapshotCopy(copy, target) {
|
|
469
|
-
targetRegistry.set(copy, target);
|
|
470
|
-
}
|
|
471
|
-
function getRegisteredTarget(copy) {
|
|
472
|
-
return targetRegistry.get(copy);
|
|
473
|
-
}
|
|
474
|
-
function peelIdentityLayer(current) {
|
|
475
|
-
const untracked = getUntracked(current);
|
|
476
|
-
if (untracked !== null && untracked !== current) return untracked;
|
|
477
|
-
const wrapperTarget = getRegisteredWrapperTarget(current);
|
|
478
|
-
if (wrapperTarget !== void 0 && wrapperTarget !== current) return wrapperTarget;
|
|
479
|
-
const registeredTarget = targetRegistry.get(current);
|
|
480
|
-
if (registeredTarget !== void 0 && registeredTarget !== current) return registeredTarget;
|
|
481
|
-
return void 0;
|
|
482
|
-
}
|
|
483
|
-
function resolveIdentity(value) {
|
|
484
|
-
let current = value;
|
|
485
|
-
while (isObjectLike(current)) {
|
|
486
|
-
const peeled = peelIdentityLayer(current);
|
|
487
|
-
if (peeled !== void 0) {
|
|
488
|
-
current = peeled;
|
|
489
|
-
continue;
|
|
490
|
-
}
|
|
491
|
-
const proxyState = proxyStateMap2.get(current);
|
|
492
|
-
if (proxyState !== void 0 && proxyState[0] !== current) {
|
|
493
|
-
current = proxyState[0];
|
|
494
|
-
continue;
|
|
495
|
-
}
|
|
496
|
-
break;
|
|
497
|
-
}
|
|
498
|
-
return current;
|
|
499
|
-
}
|
|
500
|
-
function identify(value) {
|
|
501
|
-
const target = resolveIdentity(value);
|
|
502
|
-
if (!isObjectLike(target)) return value;
|
|
503
|
-
const existing = identityTokenRegistry.get(target);
|
|
504
|
-
if (existing !== void 0) return existing;
|
|
505
|
-
const token = Object.freeze({});
|
|
506
|
-
identityTokenRegistry.set(target, token);
|
|
507
|
-
return token;
|
|
508
|
-
}
|
|
509
|
-
function isSameIdentity(first, second) {
|
|
510
|
-
const resolvedFirst = resolveIdentity(first);
|
|
511
|
-
const resolvedSecond = resolveIdentity(second);
|
|
512
|
-
return resolvedFirst === resolvedSecond || resolvedFirst !== resolvedFirst && resolvedSecond !== resolvedSecond;
|
|
513
|
-
}
|
|
582
|
+
// src/ops/path.ts
|
|
583
|
+
var createOperationPath = (segments) => Array.isArray(segments) && Object.isFrozen(segments) ? segments : Object.freeze([...segments]);
|
|
584
|
+
var appendOperationPath = (path, segment) => Object.freeze([...path, segment]);
|
|
585
|
+
var formatSegment = (segment) => String(segment);
|
|
586
|
+
var formatOperationPath = (path) => path.length === 0 ? "/" : `/${path.map(formatSegment).join("/")}`;
|
|
514
587
|
|
|
515
588
|
// src/ops/operation.ts
|
|
516
589
|
var operationBrand = /* @__PURE__ */ Symbol.for("opshot.operation");
|
|
@@ -521,354 +594,1416 @@ var OperationHalf = class {
|
|
|
521
594
|
}
|
|
522
595
|
};
|
|
523
596
|
Object.defineProperty(OperationHalf.prototype, operationBrand, { value: true });
|
|
524
|
-
var
|
|
525
|
-
|
|
526
|
-
return cloneValue(valueOriginals.get(this), /* @__PURE__ */ new WeakMap(), this.path);
|
|
527
|
-
}
|
|
528
|
-
constructor(path, value) {
|
|
597
|
+
var AssignHalf = class extends OperationHalf {
|
|
598
|
+
constructor(path, value, original = value, ids) {
|
|
529
599
|
super(path);
|
|
530
|
-
|
|
531
|
-
|
|
600
|
+
this.verb = "assign";
|
|
601
|
+
valueOriginals.set(this, original);
|
|
602
|
+
this.value = cloneValue(value, /* @__PURE__ */ new WeakMap(), this.path);
|
|
603
|
+
if (ids !== void 0) this.ids = ids;
|
|
532
604
|
}
|
|
533
605
|
};
|
|
534
|
-
var
|
|
606
|
+
var DeleteHalf = class extends OperationHalf {
|
|
535
607
|
constructor() {
|
|
536
608
|
super(...arguments);
|
|
537
|
-
this.
|
|
609
|
+
this.verb = "delete";
|
|
538
610
|
}
|
|
539
611
|
};
|
|
540
|
-
var
|
|
541
|
-
constructor() {
|
|
542
|
-
super(
|
|
543
|
-
this.
|
|
612
|
+
var LinkHalf = class extends OperationHalf {
|
|
613
|
+
constructor(path, ref) {
|
|
614
|
+
super(path);
|
|
615
|
+
this.verb = "link";
|
|
616
|
+
this.ref = ref;
|
|
544
617
|
}
|
|
545
618
|
};
|
|
546
|
-
var
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
619
|
+
var stampOf = (operation) => {
|
|
620
|
+
const value = Object.getOwnPropertyDescriptor(operation, "stamp")?.value;
|
|
621
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
622
|
+
};
|
|
623
|
+
var versionOf = (operation) => {
|
|
624
|
+
const value = Reflect.get(operation, "version");
|
|
625
|
+
return typeof value === "number" && Number.isInteger(value) ? value : void 0;
|
|
551
626
|
};
|
|
552
|
-
var
|
|
627
|
+
var stampOperation = (handle, operation) => {
|
|
628
|
+
handle.version += 1;
|
|
629
|
+
Object.defineProperty(operation, "stamp", { value: handle.stamp, enumerable: false });
|
|
630
|
+
Object.defineProperty(operation, "version", { value: handle.version, enumerable: true });
|
|
631
|
+
};
|
|
632
|
+
var isMutation = (value) => typeof value === "object" && value !== null && operationBrand in value;
|
|
553
633
|
var getValueOriginal = (half) => valueOriginals.get(half);
|
|
554
|
-
var
|
|
555
|
-
var
|
|
556
|
-
var
|
|
634
|
+
var createAssignMutation = (path, value, original = value, ids) => new AssignHalf(path, value, original, ids);
|
|
635
|
+
var createDeleteMutation = (path) => new DeleteHalf(path);
|
|
636
|
+
var createLinkMutation = (path, ref) => new LinkHalf(path, ref);
|
|
557
637
|
|
|
558
|
-
// src/
|
|
559
|
-
var
|
|
560
|
-
var
|
|
561
|
-
var
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
state.weight += amount;
|
|
566
|
-
return state.weight <= state.budget;
|
|
567
|
-
};
|
|
568
|
-
var weigh = (value, state) => {
|
|
569
|
-
if (state.weight > state.budget) return;
|
|
570
|
-
if (typeof value === "string") {
|
|
571
|
-
addWeight(state, LEAF_WEIGHT + CHARACTER_WEIGHT * value.length);
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
575
|
-
addWeight(state, LEAF_WEIGHT);
|
|
576
|
-
return;
|
|
577
|
-
}
|
|
578
|
-
if (state.seen.has(value)) return;
|
|
579
|
-
if (isCloneable(value)) {
|
|
580
|
-
state.seen.add(value);
|
|
581
|
-
if (!addWeight(state, NODE_WEIGHT)) return;
|
|
582
|
-
for (const key of Object.keys(value)) {
|
|
583
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
584
|
-
if (!descriptor || !("value" in descriptor)) continue;
|
|
585
|
-
if (!addWeight(state, KEY_WEIGHT)) return;
|
|
586
|
-
weigh(descriptor.value, state);
|
|
587
|
-
if (state.weight > state.budget) return;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
638
|
+
// src/intern.ts
|
|
639
|
+
var { proxyStateMap: proxyStateMap6, proxyCache: proxyCache2 } = unstable_getInternalStates();
|
|
640
|
+
var rawTargetOf2 = (value) => proxyStateMap6.get(value)?.[0] ?? value;
|
|
641
|
+
var occupancyNodeOf = (node) => {
|
|
642
|
+
const peeled = peelReadProxy(node);
|
|
643
|
+
const object = typeof peeled === "object" && peeled !== null ? peeled : node;
|
|
644
|
+
return rawTargetOf2(getRegisteredTarget(object) ?? object);
|
|
590
645
|
};
|
|
591
|
-
var
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
646
|
+
var liveOfInterned = (raw) => proxyCache2.get(raw) ?? raw;
|
|
647
|
+
var departingNodes = /* @__PURE__ */ new WeakMap();
|
|
648
|
+
var committedIdOf = (handle, raw) => handle.nodes.get(raw)?.id;
|
|
649
|
+
var writeId = (handle, raw, id) => {
|
|
650
|
+
const record = handle.nodes.get(raw);
|
|
651
|
+
if (record === void 0) handle.nodes.set(raw, { edges: [], id });
|
|
652
|
+
else {
|
|
653
|
+
if (record.id !== void 0 && record.id !== id) handle.byId.delete(record.id);
|
|
654
|
+
record.id = id;
|
|
655
|
+
}
|
|
656
|
+
handle.byId.set(id, raw);
|
|
595
657
|
};
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
658
|
+
function internNode(handle, node) {
|
|
659
|
+
const raw = occupancyNodeOf(node);
|
|
660
|
+
const existing = committedIdOf(handle, raw);
|
|
661
|
+
if (existing !== void 0) return existing;
|
|
662
|
+
const id = handle.nextInternId;
|
|
663
|
+
handle.nextInternId += 1;
|
|
664
|
+
writeId(handle, raw, id);
|
|
665
|
+
return id;
|
|
666
|
+
}
|
|
667
|
+
var stagedBindIdOf = (capture, raw) => capture.bindIdByNode.get(raw);
|
|
668
|
+
var stagedMintIdOf = (capture, raw) => capture.mintIdByNode.get(raw);
|
|
669
|
+
var stagedNodeOf = (capture, id) => capture.bindNodeById.get(id) ?? capture.mintNodeById.get(id);
|
|
670
|
+
var nextStagedIdOf = (handle, capture) => Math.max(handle.nextInternId, capture.nextStagedId);
|
|
671
|
+
var stageMint = (capture, raw, id) => {
|
|
672
|
+
capture.mints.push({ node: raw, id });
|
|
673
|
+
capture.mintIdByNode.set(raw, id);
|
|
674
|
+
capture.mintNodeById.set(id, raw);
|
|
675
|
+
if (id + 1 > capture.nextStagedId) capture.nextStagedId = id + 1;
|
|
604
676
|
};
|
|
605
|
-
var
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
do: createRemoveOperation(path),
|
|
611
|
-
undo: createAddOperation(path, before)
|
|
612
|
-
});
|
|
613
|
-
var replacePair = (path, before, after) => ({
|
|
614
|
-
do: createReplaceOperation(path, after),
|
|
615
|
-
undo: createReplaceOperation(path, before)
|
|
616
|
-
});
|
|
617
|
-
var weighCarried = (value) => weighValue(value, UNCAPPED_WEIGHT);
|
|
618
|
-
var pushAdd = (ops, path, after) => {
|
|
619
|
-
ops.push(addPair(path, after));
|
|
620
|
-
return OPERATION_WEIGHT + weighCarried(after);
|
|
621
|
-
};
|
|
622
|
-
var pushRemove = (ops, path, before) => {
|
|
623
|
-
ops.push(removePair(path, before));
|
|
624
|
-
return OPERATION_WEIGHT + weighCarried(before);
|
|
625
|
-
};
|
|
626
|
-
var pushReplace = (ops, path, before, after) => {
|
|
627
|
-
ops.push(replacePair(path, before, after));
|
|
628
|
-
return OPERATION_WEIGHT + weighCarried(before) + weighCarried(after);
|
|
629
|
-
};
|
|
630
|
-
var tryCollapse = (before, after, path, ops, opsStart, atomicWeight) => {
|
|
631
|
-
if (atomicWeight === 0) return 0;
|
|
632
|
-
const beforeWeight = weighValue(before, atomicWeight);
|
|
633
|
-
const afterWeight = weighValue(after, atomicWeight - beforeWeight);
|
|
634
|
-
const collapsedWeight = OPERATION_WEIGHT + beforeWeight + afterWeight;
|
|
635
|
-
if (collapsedWeight < atomicWeight) {
|
|
636
|
-
assertSafeSubtree(before, path);
|
|
637
|
-
assertSafeSubtree(after, path);
|
|
638
|
-
ops.splice(opsStart, ops.length - opsStart, replacePair(path, before, after));
|
|
639
|
-
return collapsedWeight;
|
|
640
|
-
}
|
|
641
|
-
return atomicWeight;
|
|
677
|
+
var stageBind = (capture, raw, id) => {
|
|
678
|
+
capture.binds.push({ node: raw, id });
|
|
679
|
+
capture.bindIdByNode.set(raw, id);
|
|
680
|
+
capture.bindNodeById.set(id, raw);
|
|
681
|
+
if (id + 1 > capture.nextStagedId) capture.nextStagedId = id + 1;
|
|
642
682
|
};
|
|
643
|
-
var
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
afterSet.add(after);
|
|
647
|
-
ancestors.set(before, afterSet);
|
|
683
|
+
var namedRawOf = (handle, id, capture) => {
|
|
684
|
+
const staged = capture === void 0 ? void 0 : stagedNodeOf(capture, id);
|
|
685
|
+
return staged ?? handle.byId.get(id);
|
|
648
686
|
};
|
|
649
|
-
|
|
650
|
-
const
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
687
|
+
function internedIdOf(handle, node, capture) {
|
|
688
|
+
const raw = occupancyNodeOf(node);
|
|
689
|
+
const bound = capture === void 0 ? void 0 : stagedBindIdOf(capture, raw);
|
|
690
|
+
if (bound !== void 0) return bound;
|
|
691
|
+
const committed = committedIdOf(handle, raw);
|
|
692
|
+
if (committed !== void 0) return committed;
|
|
693
|
+
if (capture === void 0) return void 0;
|
|
694
|
+
return stagedMintIdOf(capture, raw);
|
|
695
|
+
}
|
|
696
|
+
function stageVend(handle, capture, node) {
|
|
697
|
+
const raw = occupancyNodeOf(node);
|
|
698
|
+
const bound = stagedBindIdOf(capture, raw);
|
|
699
|
+
if (bound !== void 0) return bound;
|
|
700
|
+
const committed = committedIdOf(handle, raw);
|
|
701
|
+
if (committed !== void 0) return committed;
|
|
702
|
+
const staged = stagedMintIdOf(capture, raw);
|
|
703
|
+
if (staged !== void 0) return staged;
|
|
704
|
+
const id = nextStagedIdOf(handle, capture);
|
|
705
|
+
stageMint(capture, raw, id);
|
|
706
|
+
return id;
|
|
707
|
+
}
|
|
708
|
+
var commitName = (handle, raw, id) => {
|
|
709
|
+
writeId(handle, raw, id);
|
|
710
|
+
if (id >= handle.nextInternId) handle.nextInternId = id + 1;
|
|
654
711
|
};
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
712
|
+
function commitVends(handle, capture) {
|
|
713
|
+
for (const { node, id } of capture.mints) commitName(handle, node, id);
|
|
714
|
+
capture.mints.length = 0;
|
|
715
|
+
for (const { node, id } of capture.binds) commitName(handle, node, id);
|
|
716
|
+
capture.binds.length = 0;
|
|
717
|
+
capture.bindIdByNode.clear();
|
|
718
|
+
capture.bindNodeById.clear();
|
|
719
|
+
capture.mintIdByNode.clear();
|
|
720
|
+
capture.mintNodeById.clear();
|
|
721
|
+
capture.nextStagedId = 0;
|
|
722
|
+
}
|
|
723
|
+
function nodeOfInternedId(handle, id, capture) {
|
|
724
|
+
const raw = namedRawOf(handle, id, capture);
|
|
725
|
+
if (raw === void 0) return void 0;
|
|
726
|
+
return liveOfInterned(raw);
|
|
727
|
+
}
|
|
728
|
+
var walkTracked = (node, visits, chains, resolve, visit) => {
|
|
729
|
+
const walk = (current, currentChains, parent, key) => {
|
|
730
|
+
const raw = occupancyNodeOf(current);
|
|
731
|
+
if (visits.has(raw)) return;
|
|
732
|
+
visits.add(raw);
|
|
733
|
+
if (admissionLane(current) === "untracked") return;
|
|
734
|
+
if (!visit(current, raw, parent, key)) return;
|
|
735
|
+
const source = getRegisteredTarget(current) ?? current;
|
|
736
|
+
for (const entry of walkDataEntries(source)) {
|
|
737
|
+
if (typeof entry.value !== "object" || entry.value === null) continue;
|
|
738
|
+
if (currentChains === void 0 || resolve === void 0) {
|
|
739
|
+
walk(entry.value, currentChains, current, entry.key);
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
const childChains = resolve(source, currentChains, segmentFor(source, entry.key), entry);
|
|
743
|
+
if (childChains === void 0) continue;
|
|
744
|
+
walk(entry.value, childChains, current, entry.key);
|
|
667
745
|
}
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
}
|
|
746
|
+
};
|
|
747
|
+
walk(node, chains);
|
|
671
748
|
};
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
749
|
+
function internSubtree(handle, node, chains, resolve, capture) {
|
|
750
|
+
walkTracked(node, /* @__PURE__ */ new Set(), chains, resolve, (current) => {
|
|
751
|
+
if (capture === void 0) internNode(handle, current);
|
|
752
|
+
else stageVend(handle, capture, current);
|
|
753
|
+
return true;
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
function queueDeparture(handle, node) {
|
|
757
|
+
const raw = occupancyNodeOf(node);
|
|
758
|
+
let queued = departingNodes.get(handle);
|
|
759
|
+
if (queued === void 0) {
|
|
760
|
+
queued = /* @__PURE__ */ new Set();
|
|
761
|
+
departingNodes.set(handle, queued);
|
|
762
|
+
}
|
|
763
|
+
queued.add(raw);
|
|
764
|
+
}
|
|
765
|
+
var parentOfEdge = (parent) => occupancyNodeOf(parent);
|
|
766
|
+
var isOccupiedMember = (handle, node) => {
|
|
767
|
+
const root = rawTargetOf2(handle.proxy.root);
|
|
768
|
+
const raw = occupancyNodeOf(node);
|
|
769
|
+
if (raw === root) return true;
|
|
770
|
+
const seen = /* @__PURE__ */ new Set();
|
|
771
|
+
const walk = (current) => {
|
|
772
|
+
if (current === root) return true;
|
|
773
|
+
if (seen.has(current)) return false;
|
|
774
|
+
seen.add(current);
|
|
775
|
+
const edges = handle.nodes.get(current)?.edges;
|
|
776
|
+
if (edges === void 0) return false;
|
|
777
|
+
for (const edge of edges) {
|
|
778
|
+
if (walk(parentOfEdge(edge.parent))) return true;
|
|
779
|
+
}
|
|
780
|
+
return false;
|
|
781
|
+
};
|
|
782
|
+
return walk(raw);
|
|
675
783
|
};
|
|
676
|
-
var
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
784
|
+
var walkUnoccupiedCluster = (handle, node, visit) => {
|
|
785
|
+
walkTracked(node, /* @__PURE__ */ new Set(), void 0, void 0, (_current, raw) => {
|
|
786
|
+
if (isOccupiedMember(handle, raw)) return false;
|
|
787
|
+
visit(raw, committedIdOf(handle, raw));
|
|
788
|
+
return true;
|
|
789
|
+
});
|
|
790
|
+
};
|
|
791
|
+
var isNamedSlot = (handle, raw, evicted) => handle.nodes.has(raw) || evicted?.has(raw) === true;
|
|
792
|
+
var walkSlots = (carried, node, isTracked, visit) => {
|
|
793
|
+
const visits = /* @__PURE__ */ new Set();
|
|
794
|
+
const walk = (carriedCurrent, current, parent, key) => {
|
|
795
|
+
const raw = occupancyNodeOf(current);
|
|
796
|
+
const looping = visits.has(raw);
|
|
797
|
+
if (!looping) visits.add(raw);
|
|
798
|
+
if (admissionLane(current) === "untracked") return;
|
|
799
|
+
if (!isTracked(raw)) return;
|
|
800
|
+
if (!visit(raw, parent, key) || looping) return;
|
|
801
|
+
for (const entry of walkDataEntries(carriedCurrent)) {
|
|
802
|
+
if (typeof entry.value !== "object" || entry.value === null) continue;
|
|
803
|
+
const child = Reflect.get(current, entry.key);
|
|
804
|
+
if (typeof child !== "object" || child === null) continue;
|
|
805
|
+
walk(entry.value, child, current, entry.key);
|
|
693
806
|
}
|
|
694
|
-
}
|
|
695
|
-
|
|
807
|
+
};
|
|
808
|
+
walk(carried, node);
|
|
696
809
|
};
|
|
697
|
-
|
|
698
|
-
const
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
810
|
+
function evictDepartedClusters(handle) {
|
|
811
|
+
const evicted = /* @__PURE__ */ new Map();
|
|
812
|
+
const queued = departingNodes.get(handle);
|
|
813
|
+
if (queued === void 0) return evicted;
|
|
814
|
+
const ungrounded = new Array();
|
|
815
|
+
for (const node of queued) {
|
|
816
|
+
if (!isOccupiedMember(handle, node)) ungrounded.push(node);
|
|
817
|
+
}
|
|
818
|
+
queued.clear();
|
|
819
|
+
const members = new Array();
|
|
820
|
+
for (const node of ungrounded) {
|
|
821
|
+
walkUnoccupiedCluster(handle, node, (raw, id) => {
|
|
822
|
+
members.push(raw);
|
|
823
|
+
if (id !== void 0) evicted.set(raw, id);
|
|
824
|
+
});
|
|
708
825
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
826
|
+
for (const raw of members) handle.nodes.delete(raw);
|
|
827
|
+
for (const id of evicted.values()) handle.byId.delete(id);
|
|
828
|
+
return evicted;
|
|
829
|
+
}
|
|
830
|
+
function bindVendedIds(handle, node, carried, ids, capture, parent, key) {
|
|
831
|
+
let index = 0;
|
|
832
|
+
walkSlots(
|
|
833
|
+
carried,
|
|
834
|
+
node,
|
|
835
|
+
(raw) => isNamedSlot(handle, raw),
|
|
836
|
+
(raw, walkParent, walkKey) => {
|
|
837
|
+
const id = ids[index];
|
|
838
|
+
if (id === void 0) return true;
|
|
839
|
+
index += 1;
|
|
840
|
+
const held = namedRawOf(handle, id, capture);
|
|
841
|
+
const slotParent = walkParent ?? parent;
|
|
842
|
+
const slotKey = walkKey ?? key;
|
|
843
|
+
if (held !== void 0) {
|
|
844
|
+
if (occupancyNodeOf(held) !== raw && slotParent !== void 0 && slotKey !== void 0) {
|
|
845
|
+
Reflect.set(slotParent, slotKey, liveOfInterned(held));
|
|
846
|
+
}
|
|
847
|
+
return false;
|
|
848
|
+
}
|
|
849
|
+
if (capture === void 0) commitName(handle, raw, id);
|
|
850
|
+
else stageBind(capture, raw, id);
|
|
851
|
+
return true;
|
|
713
852
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
function rewindAdmission(handle, node) {
|
|
856
|
+
const ids = new Array();
|
|
857
|
+
walkUnoccupiedCluster(handle, node, (raw, id) => {
|
|
858
|
+
if (id === void 0) return;
|
|
859
|
+
ids.push(id);
|
|
860
|
+
const record = handle.nodes.get(raw);
|
|
861
|
+
if (record !== void 0) record.id = void 0;
|
|
862
|
+
handle.byId.delete(id);
|
|
863
|
+
});
|
|
864
|
+
return ids;
|
|
865
|
+
}
|
|
866
|
+
function annotateDepartureUndos(handle, ops, evicted) {
|
|
867
|
+
if (evicted.size === 0) return;
|
|
868
|
+
const claimedMembers = /* @__PURE__ */ new Set();
|
|
869
|
+
for (let index = ops.length - 1; index >= 0; index--) {
|
|
870
|
+
const operation = ops[index];
|
|
871
|
+
if (operation === void 0) continue;
|
|
872
|
+
const undo = operation.undo;
|
|
873
|
+
if (undo.verb !== "assign") continue;
|
|
874
|
+
const original = getValueOriginal(undo) ?? undo.value;
|
|
875
|
+
if (typeof original !== "object" || original === null) continue;
|
|
876
|
+
const restoredId = evicted.get(occupancyNodeOf(original));
|
|
877
|
+
if (restoredId === void 0) continue;
|
|
878
|
+
const ids = new Array();
|
|
879
|
+
const claimsBefore = claimedMembers.size;
|
|
880
|
+
walkSlots(
|
|
881
|
+
original,
|
|
882
|
+
original,
|
|
883
|
+
(raw) => isNamedSlot(handle, raw, evicted),
|
|
884
|
+
(raw) => {
|
|
885
|
+
const retiredId = evicted.get(raw);
|
|
886
|
+
const id = retiredId ?? committedIdOf(handle, raw);
|
|
887
|
+
if (id !== void 0) ids.push(id);
|
|
888
|
+
if (retiredId === void 0 || claimedMembers.has(raw)) return false;
|
|
889
|
+
claimedMembers.add(raw);
|
|
890
|
+
return true;
|
|
891
|
+
}
|
|
892
|
+
);
|
|
893
|
+
operation.undo = claimedMembers.size > claimsBefore ? createAssignMutation(undo.path, undo.value, original, ids) : createLinkMutation(undo.path, restoredId);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// src/edges.ts
|
|
898
|
+
var { proxyStateMap: proxyStateMap7 } = unstable_getInternalStates();
|
|
899
|
+
var rawTargetOf3 = (value) => proxyStateMap7.get(value)?.[0] ?? value;
|
|
900
|
+
var rawOf2 = (node) => {
|
|
901
|
+
const peeled = peelReadProxy(node);
|
|
902
|
+
return rawTargetOf3(typeof peeled === "object" && peeled !== null ? peeled : node);
|
|
903
|
+
};
|
|
904
|
+
var occupancyRootOf = (handle) => rawTargetOf3(handle.proxy.root);
|
|
905
|
+
var edgesOf = (handle, node) => handle.nodes.get(node)?.edges;
|
|
906
|
+
var pathHasIgnored = (trie, path) => {
|
|
907
|
+
if (trie.ignored) return true;
|
|
908
|
+
let current = trie;
|
|
909
|
+
for (const key of path) {
|
|
910
|
+
current = declarationChild(current, key);
|
|
911
|
+
if (current === void 0) return false;
|
|
912
|
+
if (current.ignored) return true;
|
|
913
|
+
}
|
|
914
|
+
return false;
|
|
915
|
+
};
|
|
916
|
+
var pathIsTainted = (trie, path) => {
|
|
917
|
+
if (trie.unsafe) return true;
|
|
918
|
+
let current = trie;
|
|
919
|
+
for (const key of path) {
|
|
920
|
+
current = declarationChild(current, key);
|
|
921
|
+
if (current === void 0) return false;
|
|
922
|
+
if (current.unsafe) return true;
|
|
923
|
+
}
|
|
924
|
+
return false;
|
|
925
|
+
};
|
|
926
|
+
var walkGroundedChains = (handle, node, onGround) => {
|
|
927
|
+
const root = occupancyRootOf(handle);
|
|
928
|
+
const walk = (current, reverseKeys, pathVisited) => {
|
|
929
|
+
if (current === root) return onGround([...reverseKeys].reverse());
|
|
930
|
+
if (pathVisited.has(current)) return false;
|
|
931
|
+
pathVisited.add(current);
|
|
932
|
+
const edges = edgesOf(handle, current);
|
|
933
|
+
if (edges !== void 0) {
|
|
934
|
+
for (const edge of edges) {
|
|
935
|
+
if (walk(rawOf2(edge.parent), [...reverseKeys, edge.key], pathVisited)) {
|
|
936
|
+
pathVisited.delete(current);
|
|
937
|
+
return true;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
pathVisited.delete(current);
|
|
942
|
+
return false;
|
|
943
|
+
};
|
|
944
|
+
walk(rawOf2(node), [], /* @__PURE__ */ new Set());
|
|
945
|
+
};
|
|
946
|
+
function addInEdge(handle, node, parent, key) {
|
|
947
|
+
const rawNode = rawOf2(node);
|
|
948
|
+
const rawParent = rawOf2(parent);
|
|
949
|
+
let record = handle.nodes.get(rawNode);
|
|
950
|
+
if (record === void 0) {
|
|
951
|
+
record = { edges: [], id: void 0 };
|
|
952
|
+
handle.nodes.set(rawNode, record);
|
|
953
|
+
}
|
|
954
|
+
if (record.edges.some((edge) => rawOf2(edge.parent) === rawParent && edge.key === key)) return;
|
|
955
|
+
record.edges.push({ parent: rawParent, key });
|
|
956
|
+
registerHandle(rawNode, handle);
|
|
957
|
+
}
|
|
958
|
+
function hasOtherRoutes(handle, node, parent, key) {
|
|
959
|
+
const edges = handle.nodes.get(rawOf2(node))?.edges;
|
|
960
|
+
if (edges === void 0) return false;
|
|
961
|
+
const rawParent = rawOf2(parent);
|
|
962
|
+
return edges.some((edge) => rawOf2(edge.parent) !== rawParent || edge.key !== key);
|
|
963
|
+
}
|
|
964
|
+
function removeInEdge(handle, node, parent, key) {
|
|
965
|
+
const rawNode = rawOf2(node);
|
|
966
|
+
const rawParent = rawOf2(parent);
|
|
967
|
+
const record = handle.nodes.get(rawNode);
|
|
968
|
+
if (record === void 0) return;
|
|
969
|
+
const index = record.edges.findIndex((edge) => rawOf2(edge.parent) === rawParent && edge.key === key);
|
|
970
|
+
if (index === -1) return;
|
|
971
|
+
record.edges.splice(index, 1);
|
|
972
|
+
if (rawNode !== occupancyRootOf(handle)) queueDeparture(handle, rawNode);
|
|
973
|
+
}
|
|
974
|
+
function edgeStatusOf(handle, node) {
|
|
975
|
+
const rawNode = rawOf2(node);
|
|
976
|
+
const root = occupancyRootOf(handle);
|
|
977
|
+
if (rawNode === root) {
|
|
978
|
+
return { occupied: true, unsafe: handle.declarations?.unsafe === true };
|
|
979
|
+
}
|
|
980
|
+
if (handle.declarations === void 0) {
|
|
981
|
+
let occupied = false;
|
|
982
|
+
walkGroundedChains(handle, rawNode, () => {
|
|
983
|
+
occupied = true;
|
|
984
|
+
return true;
|
|
985
|
+
});
|
|
986
|
+
return { occupied, unsafe: false };
|
|
987
|
+
}
|
|
988
|
+
const declarations = handle.declarations;
|
|
989
|
+
const status = { occupied: false, hasClean: false };
|
|
990
|
+
walkGroundedChains(handle, rawNode, (pathFromRoot) => {
|
|
991
|
+
status.occupied = true;
|
|
992
|
+
if (!pathIsTainted(declarations, pathFromRoot)) {
|
|
993
|
+
status.hasClean = true;
|
|
994
|
+
return true;
|
|
995
|
+
}
|
|
996
|
+
return false;
|
|
997
|
+
});
|
|
998
|
+
return { occupied: status.occupied, unsafe: status.occupied && !status.hasClean };
|
|
999
|
+
}
|
|
1000
|
+
function isIgnoredFrontier(handle, parent, key) {
|
|
1001
|
+
const trie = handle.declarations;
|
|
1002
|
+
if (trie === void 0) return false;
|
|
1003
|
+
let hit = false;
|
|
1004
|
+
walkGroundedChains(handle, parent, (pathFromRoot) => {
|
|
1005
|
+
if (pathHasIgnored(trie, [...pathFromRoot, key])) {
|
|
1006
|
+
hit = true;
|
|
1007
|
+
return true;
|
|
1008
|
+
}
|
|
1009
|
+
return false;
|
|
1010
|
+
});
|
|
1011
|
+
return hit;
|
|
1012
|
+
}
|
|
1013
|
+
var uniqueNodeChains = (entries) => {
|
|
1014
|
+
const unique = new Array();
|
|
1015
|
+
const undefinedFlags = /* @__PURE__ */ new Set();
|
|
1016
|
+
const definedFlags = /* @__PURE__ */ new WeakMap();
|
|
1017
|
+
for (const entry of entries) {
|
|
1018
|
+
const flags = `${entry.tainted ? "1" : "0"}${entry.ignored ? "1" : "0"}`;
|
|
1019
|
+
if (entry.residual === void 0) {
|
|
1020
|
+
if (undefinedFlags.has(flags)) continue;
|
|
1021
|
+
undefinedFlags.add(flags);
|
|
1022
|
+
unique.push(entry);
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
1025
|
+
let seen = definedFlags.get(entry.residual);
|
|
1026
|
+
if (seen === void 0) {
|
|
1027
|
+
seen = /* @__PURE__ */ new Set();
|
|
1028
|
+
definedFlags.set(entry.residual, seen);
|
|
1029
|
+
}
|
|
1030
|
+
if (seen.has(flags)) continue;
|
|
1031
|
+
seen.add(flags);
|
|
1032
|
+
unique.push(entry);
|
|
1033
|
+
}
|
|
1034
|
+
return unique;
|
|
1035
|
+
};
|
|
1036
|
+
var uniqueResiduals = (residuals) => {
|
|
1037
|
+
const unique = new Array();
|
|
1038
|
+
let sawUndefined = false;
|
|
1039
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1040
|
+
for (const residual of residuals) {
|
|
1041
|
+
if (residual === void 0) {
|
|
1042
|
+
if (sawUndefined) continue;
|
|
1043
|
+
sawUndefined = true;
|
|
1044
|
+
unique.push(void 0);
|
|
1045
|
+
continue;
|
|
1046
|
+
}
|
|
1047
|
+
if (seen.has(residual)) continue;
|
|
1048
|
+
seen.add(residual);
|
|
1049
|
+
unique.push(residual);
|
|
1050
|
+
}
|
|
1051
|
+
return unique;
|
|
1052
|
+
};
|
|
1053
|
+
var chainsAtNode = (handle, node, memo2, computing) => {
|
|
1054
|
+
const raw = rawOf2(node);
|
|
1055
|
+
const cached = memo2.get(raw);
|
|
1056
|
+
if (cached !== void 0) return cached;
|
|
1057
|
+
if (computing.has(raw)) return { occupied: false, entries: [], cut: true };
|
|
1058
|
+
if (raw === occupancyRootOf(handle)) {
|
|
1059
|
+
const trie = handle.declarations;
|
|
1060
|
+
const result2 = {
|
|
1061
|
+
occupied: true,
|
|
1062
|
+
entries: [
|
|
1063
|
+
{
|
|
1064
|
+
residual: trie,
|
|
1065
|
+
tainted: trie?.unsafe === true,
|
|
1066
|
+
ignored: trie?.ignored === true
|
|
1067
|
+
}
|
|
1068
|
+
],
|
|
1069
|
+
cut: false
|
|
1070
|
+
};
|
|
1071
|
+
memo2.set(raw, result2);
|
|
1072
|
+
return result2;
|
|
1073
|
+
}
|
|
1074
|
+
computing.add(raw);
|
|
1075
|
+
const aggregated = new Array();
|
|
1076
|
+
let occupied = false;
|
|
1077
|
+
let cut = false;
|
|
1078
|
+
const edges = edgesOf(handle, raw);
|
|
1079
|
+
if (edges !== void 0) {
|
|
1080
|
+
for (const edge of edges) {
|
|
1081
|
+
const parent = chainsAtNode(handle, edge.parent, memo2, computing);
|
|
1082
|
+
if (parent.cut) cut = true;
|
|
1083
|
+
if (!parent.occupied) continue;
|
|
1084
|
+
occupied = true;
|
|
1085
|
+
for (const entry of parent.entries) {
|
|
1086
|
+
const child = entry.residual === void 0 ? void 0 : declarationChild(entry.residual, edge.key);
|
|
1087
|
+
aggregated.push({
|
|
1088
|
+
residual: child,
|
|
1089
|
+
tainted: entry.tainted || child?.unsafe === true,
|
|
1090
|
+
ignored: entry.ignored || child?.ignored === true
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
computing.delete(raw);
|
|
1096
|
+
const result = { occupied, entries: uniqueNodeChains(aggregated), cut };
|
|
1097
|
+
if (!cut) memo2.set(raw, result);
|
|
1098
|
+
return result;
|
|
1099
|
+
};
|
|
1100
|
+
function descendChains(chains, key) {
|
|
1101
|
+
const next = new Array();
|
|
1102
|
+
let ignored = false;
|
|
1103
|
+
for (const residual of chains) {
|
|
1104
|
+
if (residual === void 0) {
|
|
1105
|
+
next.push(void 0);
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
const child = declarationChild(residual, key);
|
|
1109
|
+
if (child?.ignored === true) ignored = true;
|
|
1110
|
+
if (child?.unsafe === true) continue;
|
|
1111
|
+
next.push(child);
|
|
1112
|
+
}
|
|
1113
|
+
return {
|
|
1114
|
+
ignored,
|
|
1115
|
+
unsafe: chains.length > 0 && next.length === 0,
|
|
1116
|
+
chains: uniqueResiduals(next)
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
var childChainsOf = (chains, key) => descendChains(chains, key).chains;
|
|
1120
|
+
var isChainsIgnored = (chains) => chains.some((chain) => chain?.ignored === true);
|
|
1121
|
+
var isChainsUnsafe = (chains) => chains.length === 0;
|
|
1122
|
+
var chainsAtRoot = (declarations) => declarations?.unsafe === true ? [] : [declarations];
|
|
1123
|
+
function nodeChainsOf(handle, node) {
|
|
1124
|
+
const nodeChains = chainsAtNode(handle, node, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set());
|
|
1125
|
+
if (!nodeChains.occupied) return void 0;
|
|
1126
|
+
const chains = new Array();
|
|
1127
|
+
for (const entry of nodeChains.entries) {
|
|
1128
|
+
if (entry.tainted) continue;
|
|
1129
|
+
chains.push(entry.residual);
|
|
1130
|
+
}
|
|
1131
|
+
return uniqueResiduals(chains);
|
|
1132
|
+
}
|
|
1133
|
+
function slotStatusOf(handle, parent, key) {
|
|
1134
|
+
const parentChains = chainsAtNode(handle, parent, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set());
|
|
1135
|
+
if (!parentChains.occupied) {
|
|
1136
|
+
return { occupied: false, unsafe: false, ignored: false, chains: [] };
|
|
1137
|
+
}
|
|
1138
|
+
const chains = new Array();
|
|
1139
|
+
let ignored = false;
|
|
1140
|
+
for (const entry of parentChains.entries) {
|
|
1141
|
+
const child = entry.residual === void 0 ? void 0 : declarationChild(entry.residual, key);
|
|
1142
|
+
const slotIgnored = entry.ignored || child?.ignored === true;
|
|
1143
|
+
const tainted = entry.tainted || child?.unsafe === true;
|
|
1144
|
+
if (slotIgnored) ignored = true;
|
|
1145
|
+
if (!tainted) chains.push(child);
|
|
1146
|
+
}
|
|
1147
|
+
return {
|
|
1148
|
+
ignored,
|
|
1149
|
+
occupied: true,
|
|
1150
|
+
unsafe: chains.length === 0,
|
|
1151
|
+
chains: uniqueResiduals(chains)
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
var isTrackedEdge = (entry) => {
|
|
1155
|
+
const value = entry.value;
|
|
1156
|
+
const target = isObjectLike3(value) ? getRegisteredTarget(value) ?? value : value;
|
|
1157
|
+
return entry.writable && admissionLane(target) === "tracked";
|
|
1158
|
+
};
|
|
1159
|
+
var graphNodeOf = (value) => rawOf2(getRegisteredTarget(value) ?? value);
|
|
1160
|
+
function resolveChildChains(handle, parent, parentChains, key, child) {
|
|
1161
|
+
const descended = descendChains(parentChains, key).chains;
|
|
1162
|
+
const ignoredResidual = isChainsIgnored(parentChains) || isChainsIgnored(descended);
|
|
1163
|
+
if (!isObjectLike3(parent) || !isObjectLike3(child)) {
|
|
1164
|
+
if (ignoredResidual) return void 0;
|
|
1165
|
+
return { chains: descended, descended, otherRoutes: false };
|
|
1166
|
+
}
|
|
1167
|
+
const graphParent = graphNodeOf(parent);
|
|
1168
|
+
const graphChild = graphNodeOf(child);
|
|
1169
|
+
const otherRoutes = hasOtherRoutes(handle, graphChild, graphParent, key);
|
|
1170
|
+
const ignored = ignoredResidual || otherRoutes && isIgnoredFrontier(handle, graphParent, key);
|
|
1171
|
+
if (ignored) return void 0;
|
|
1172
|
+
const chains = otherRoutes ? nodeChainsOf(handle, graphChild) ?? descended : descended;
|
|
1173
|
+
return { chains, descended, otherRoutes };
|
|
1174
|
+
}
|
|
1175
|
+
var seedFrom = (handle, node, chains, visits) => {
|
|
1176
|
+
if (isChainsIgnored(chains)) return;
|
|
1177
|
+
const raw = rawOf2(node);
|
|
1178
|
+
if (visits.has(raw)) return;
|
|
1179
|
+
visits.add(raw);
|
|
1180
|
+
for (const entry of walkDataEntries(raw)) {
|
|
1181
|
+
if (!isTrackedEdge(entry)) continue;
|
|
1182
|
+
if (typeof entry.value !== "object" || entry.value === null) continue;
|
|
1183
|
+
const key = segmentFor(raw, entry.key);
|
|
1184
|
+
const resolved = resolveChildChains(handle, raw, chains, key, entry.value);
|
|
1185
|
+
if (resolved === void 0) continue;
|
|
1186
|
+
addInEdge(handle, entry.value, raw, key);
|
|
1187
|
+
seedFrom(handle, entry.value, resolved.chains, visits);
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
function seedInEdges(handle) {
|
|
1191
|
+
seedFrom(handle, handle.proxy.root, chainsAtRoot(handle.declarations), /* @__PURE__ */ new Set());
|
|
1192
|
+
}
|
|
1193
|
+
function seedInEdgesUnder(handle, node, chains) {
|
|
1194
|
+
seedFrom(handle, node, chains, /* @__PURE__ */ new Set());
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
// src/occupancy.ts
|
|
1198
|
+
var { proxyStateMap: proxyStateMap8 } = unstable_getInternalStates();
|
|
1199
|
+
var rawTargetOf4 = (value) => proxyStateMap8.get(value)?.[0] ?? value;
|
|
1200
|
+
var liveOf = (value) => getRegisteredTarget(value) ?? rawTargetOf4(value);
|
|
1201
|
+
var createCaptureTables = () => ({
|
|
1202
|
+
mints: [],
|
|
1203
|
+
binds: [],
|
|
1204
|
+
bindIdByNode: /* @__PURE__ */ new Map(),
|
|
1205
|
+
bindNodeById: /* @__PURE__ */ new Map(),
|
|
1206
|
+
mintIdByNode: /* @__PURE__ */ new Map(),
|
|
1207
|
+
mintNodeById: /* @__PURE__ */ new Map(),
|
|
1208
|
+
nextStagedId: 0
|
|
1209
|
+
});
|
|
1210
|
+
var occupancyKeyOf = (key) => typeof key === "number" ? String(key) : key;
|
|
1211
|
+
function bindVisitedOccupancy(handle, path, parent, key, child, unsafe = false, ignoredFrontier) {
|
|
1212
|
+
if (path.length === 0) return "continue";
|
|
1213
|
+
if (ignoredFrontier ?? isIgnoredFrontier(handle, parent, key)) return "skip";
|
|
1214
|
+
const parentRaw = liveOf(parent);
|
|
1215
|
+
const occupancyKey = occupancyKeyOf(key);
|
|
1216
|
+
const admitted = unsafe || !handle.strict;
|
|
1217
|
+
if (typeof child === "function") {
|
|
1218
|
+
const parentKind = classifyValue(parentRaw);
|
|
1219
|
+
if (parentKind === "plain" || parentKind === "plainArray") return "continue";
|
|
1220
|
+
if (admitted) return "continue";
|
|
1221
|
+
return "skip";
|
|
1222
|
+
}
|
|
1223
|
+
const stored = Reflect.get(parentRaw, occupancyKey);
|
|
1224
|
+
const occupantSource = isObjectLike3(stored) ? stored : child;
|
|
1225
|
+
if (typeof occupantSource !== "object" || occupantSource === null) return "continue";
|
|
1226
|
+
const childLive = liveOf(occupantSource);
|
|
1227
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(parentRaw, occupancyKey);
|
|
1228
|
+
if (descriptor !== void 0 && descriptor.writable !== true && admissionDecision(childLive).lane !== "untracked")
|
|
1229
|
+
return "skip";
|
|
1230
|
+
const decision = admissionDecision(childLive);
|
|
1231
|
+
if (decision.lane === "untracked") return "skip";
|
|
1232
|
+
if (decision.lane === "dangerous") {
|
|
1233
|
+
if (admitted) return "continue";
|
|
1234
|
+
return "skip";
|
|
1235
|
+
}
|
|
1236
|
+
if (!admitted && classifyValue(childLive) === "cleanClass") {
|
|
1237
|
+
for (const entry of walkDataEntries(childLive)) {
|
|
1238
|
+
if (typeof entry.value !== "function") continue;
|
|
1239
|
+
return "skip";
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
return "continue";
|
|
1243
|
+
}
|
|
1244
|
+
function markDirtyPath(dirty, handle, path, parentLive) {
|
|
1245
|
+
let current = handle.proxy.root;
|
|
1246
|
+
if (isObjectLike3(current)) dirty.nodes.add(rawTargetOf4(current));
|
|
1247
|
+
for (const segment of path) {
|
|
1248
|
+
if (!isObjectLike3(current)) break;
|
|
1249
|
+
current = Reflect.get(current, segment);
|
|
1250
|
+
if (isObjectLike3(current)) dirty.nodes.add(rawTargetOf4(current));
|
|
1251
|
+
}
|
|
1252
|
+
if (parentLive === void 0 || path.length === 0) return;
|
|
1253
|
+
const lastSegment = path[path.length - 1];
|
|
1254
|
+
if (lastSegment === void 0) return;
|
|
1255
|
+
const edge = typeof lastSegment === "number" ? String(lastSegment) : lastSegment;
|
|
1256
|
+
const parentRaw = rawTargetOf4(parentLive);
|
|
1257
|
+
let edges = dirty.edges.get(parentRaw);
|
|
1258
|
+
if (edges === void 0) {
|
|
1259
|
+
edges = /* @__PURE__ */ new Set();
|
|
1260
|
+
dirty.edges.set(parentRaw, edges);
|
|
1261
|
+
}
|
|
1262
|
+
edges.add(edge);
|
|
1263
|
+
}
|
|
1264
|
+
var walkLiveOccupancies = (handle, capture) => {
|
|
1265
|
+
const root = handle.proxy.root;
|
|
1266
|
+
const visits = /* @__PURE__ */ new Set();
|
|
1267
|
+
const rootChains = handle.declarations?.unsafe === true ? [] : [handle.declarations];
|
|
1268
|
+
const walk = (node, path, chains) => {
|
|
1269
|
+
if (chains.some((residual) => residual?.ignored === true)) return;
|
|
1270
|
+
stageVend(handle, capture, node);
|
|
1271
|
+
const nodeRaw = rawTargetOf4(node);
|
|
1272
|
+
if (visits.has(nodeRaw)) return;
|
|
1273
|
+
visits.add(nodeRaw);
|
|
1274
|
+
for (const entry of walkDataEntries(node)) {
|
|
1275
|
+
const key = segmentFor(node, entry.key);
|
|
1276
|
+
const childPath = appendOperationPath(path, key);
|
|
1277
|
+
const slot = slotStatusOf(handle, node, key);
|
|
1278
|
+
const descended = descendChains(chains, key);
|
|
1279
|
+
const ignored = slot.ignored || descended.ignored;
|
|
1280
|
+
const unsafe = slot.occupied ? slot.unsafe : descended.unsafe;
|
|
1281
|
+
const childChains = slot.occupied ? slot.chains : descended.chains;
|
|
1282
|
+
if (ignored) continue;
|
|
1283
|
+
const visit = bindVisitedOccupancy(handle, childPath, node, entry.key, entry.value, unsafe);
|
|
1284
|
+
if (visit !== "continue") continue;
|
|
1285
|
+
if (typeof entry.value === "object" && entry.value !== null) walk(entry.value, childPath, childChains);
|
|
717
1286
|
}
|
|
718
|
-
|
|
1287
|
+
};
|
|
1288
|
+
walk(root, createOperationPath([]), rootChains);
|
|
1289
|
+
};
|
|
1290
|
+
function seedOccupancies(handle) {
|
|
1291
|
+
const capture = createCaptureTables();
|
|
1292
|
+
walkLiveOccupancies(handle, capture);
|
|
1293
|
+
commitVends(handle, capture);
|
|
1294
|
+
}
|
|
1295
|
+
function syncHandleTables(handle, capture) {
|
|
1296
|
+
walkLiveOccupancies(handle, capture);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
// src/ops/admission.ts
|
|
1300
|
+
var { proxyStateMap: proxyStateMap9 } = unstable_getInternalStates();
|
|
1301
|
+
var rawTargetOf5 = (value) => proxyStateMap9.get(value)?.[0] ?? value;
|
|
1302
|
+
var MissingDiffParentError = class extends Error {
|
|
1303
|
+
constructor() {
|
|
1304
|
+
super("opshot: admitStep could not resolve a live parent");
|
|
1305
|
+
this.name = "MissingDiffParentError";
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
var admitStep = (handle, dirty, path, liveParent, residual) => {
|
|
1309
|
+
if (path.length === 0) {
|
|
1310
|
+
return { visit: "continue", ignored: isChainsIgnored(residual), liveChild: liveParent, chains: residual };
|
|
1311
|
+
}
|
|
1312
|
+
const key = path[path.length - 1];
|
|
1313
|
+
const liveChild = isObjectLike3(liveParent) && key !== void 0 ? Reflect.get(liveParent, key) : void 0;
|
|
1314
|
+
if (handle === void 0) {
|
|
1315
|
+
const childChains = key === void 0 ? residual : childChainsOf(residual, key);
|
|
1316
|
+
return { visit: "continue", ignored: isChainsIgnored(childChains), liveChild, chains: childChains };
|
|
1317
|
+
}
|
|
1318
|
+
if (key === void 0) {
|
|
1319
|
+
return { visit: "continue", ignored: isChainsIgnored(residual), liveChild: liveParent, chains: residual };
|
|
1320
|
+
}
|
|
1321
|
+
const resolved = resolveChildChains(handle, liveParent, residual, key, liveChild);
|
|
1322
|
+
const ignored = resolved === void 0;
|
|
1323
|
+
const chains = resolved?.chains ?? childChainsOf(residual, key);
|
|
1324
|
+
if (dirty === void 0) return { visit: "continue", ignored, liveChild, chains };
|
|
1325
|
+
if (ignored) return { visit: "skip", ignored, liveChild, chains };
|
|
1326
|
+
if (resolved.otherRoutes) {
|
|
1327
|
+
if (!isObjectLike3(liveParent) || !isObjectLike3(liveChild)) throw new MissingDiffParentError();
|
|
1328
|
+
const slot = slotStatusOf(handle, liveParent, key);
|
|
1329
|
+
let unsafe = slot.occupied ? slot.unsafe : isChainsUnsafe(resolved.descended);
|
|
1330
|
+
const status = edgeStatusOf(handle, liveChild);
|
|
1331
|
+
if (status.occupied) unsafe = status.unsafe;
|
|
1332
|
+
return {
|
|
1333
|
+
visit: bindVisitedOccupancy(handle, path, liveParent, key, liveChild, unsafe, false),
|
|
1334
|
+
ignored,
|
|
1335
|
+
liveChild,
|
|
1336
|
+
chains
|
|
1337
|
+
};
|
|
1338
|
+
}
|
|
1339
|
+
if (!isObjectLike3(liveParent)) throw new MissingDiffParentError();
|
|
1340
|
+
return {
|
|
1341
|
+
visit: bindVisitedOccupancy(handle, path, liveParent, key, liveChild, isChainsUnsafe(resolved.descended), false),
|
|
1342
|
+
ignored,
|
|
1343
|
+
liveChild,
|
|
1344
|
+
chains
|
|
1345
|
+
};
|
|
1346
|
+
};
|
|
1347
|
+
var admitDescendants = (handle, path, visits, residual, liveNode, unsafe = false) => {
|
|
1348
|
+
if (handle === void 0) return;
|
|
1349
|
+
if (!isObjectLike3(liveNode)) return;
|
|
1350
|
+
const nodeKey = rawTargetOf5(liveNode);
|
|
1351
|
+
if (visits.has(nodeKey)) return;
|
|
1352
|
+
visits.add(nodeKey);
|
|
1353
|
+
if (isChainsIgnored(residual)) return;
|
|
1354
|
+
const nodeUnsafe = unsafe || isChainsUnsafe(residual);
|
|
1355
|
+
for (const entry of walkDataEntries(liveNode)) {
|
|
1356
|
+
if (typeof entry.value !== "object" || entry.value === null) continue;
|
|
1357
|
+
const key = segmentFor(liveNode, entry.key);
|
|
1358
|
+
const childPath = appendOperationPath(path, key);
|
|
1359
|
+
const descended = descendChains(residual, key);
|
|
1360
|
+
let ignored;
|
|
1361
|
+
let childChains;
|
|
1362
|
+
let childUnsafe;
|
|
1363
|
+
let ignoredFrontier;
|
|
1364
|
+
if (hasOtherRoutes(handle, entry.value, liveNode, key)) {
|
|
1365
|
+
const slot = slotStatusOf(handle, liveNode, key);
|
|
1366
|
+
ignored = slot.ignored || descended.ignored;
|
|
1367
|
+
childChains = nodeChainsOf(handle, entry.value) ?? descended.chains;
|
|
1368
|
+
childUnsafe = slot.occupied ? slot.unsafe : nodeUnsafe || descended.unsafe;
|
|
1369
|
+
ignoredFrontier = void 0;
|
|
1370
|
+
} else {
|
|
1371
|
+
ignored = descended.ignored || isChainsIgnored(descended.chains);
|
|
1372
|
+
childChains = descended.chains;
|
|
1373
|
+
childUnsafe = nodeUnsafe || descended.unsafe;
|
|
1374
|
+
ignoredFrontier = false;
|
|
1375
|
+
}
|
|
1376
|
+
if (ignored) continue;
|
|
1377
|
+
const visit = bindVisitedOccupancy(
|
|
1378
|
+
handle,
|
|
1379
|
+
childPath,
|
|
1380
|
+
liveNode,
|
|
1381
|
+
entry.key,
|
|
1382
|
+
entry.value,
|
|
1383
|
+
childUnsafe,
|
|
1384
|
+
ignoredFrontier
|
|
1385
|
+
);
|
|
1386
|
+
if (visit !== "continue") continue;
|
|
1387
|
+
admitDescendants(handle, childPath, visits, childChains, Reflect.get(liveNode, key), childUnsafe);
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
var markChangedPath = (handle, dirty, path, liveParent) => {
|
|
1391
|
+
if (handle === void 0 || dirty === void 0 || path.length === 0) return;
|
|
1392
|
+
if (!isObjectLike3(liveParent)) return;
|
|
1393
|
+
markDirtyPath(dirty, handle, path, liveParent);
|
|
1394
|
+
};
|
|
1395
|
+
var emitsSkippedOccupancy = (value) => isObjectLike3(value) && admissionLane(value) === "untracked";
|
|
1396
|
+
|
|
1397
|
+
// src/ops/ancestorPairs.ts
|
|
1398
|
+
var MissingAncestorPairError = class extends Error {
|
|
1399
|
+
constructor() {
|
|
1400
|
+
super("opshot: exitAncestorPair without matching enterAncestorPair");
|
|
1401
|
+
this.name = "MissingAncestorPairError";
|
|
719
1402
|
}
|
|
720
|
-
weight += diffObjectProperties(before, after, path, ops, ancestors, true);
|
|
721
|
-
return weight;
|
|
722
1403
|
};
|
|
723
|
-
var
|
|
724
|
-
|
|
1404
|
+
var hasAncestorPair = (ancestors, before, after) => ancestors.get(before)?.has(after) ?? false;
|
|
1405
|
+
var enterAncestorPair = (ancestors, before, after) => {
|
|
1406
|
+
const afterSet = ancestors.get(before) ?? /* @__PURE__ */ new Set();
|
|
1407
|
+
afterSet.add(after);
|
|
1408
|
+
ancestors.set(before, afterSet);
|
|
1409
|
+
};
|
|
1410
|
+
var exitAncestorPair = (ancestors, before, after) => {
|
|
1411
|
+
const afterSet = ancestors.get(before);
|
|
1412
|
+
if (afterSet === void 0) throw new MissingAncestorPairError();
|
|
1413
|
+
afterSet.delete(after);
|
|
1414
|
+
if (afterSet.size === 0) ancestors.delete(before);
|
|
1415
|
+
};
|
|
1416
|
+
var walkContainer = (ancestors, before, after, walk) => {
|
|
1417
|
+
if (hasAncestorPair(ancestors, before, after)) return;
|
|
725
1418
|
enterAncestorPair(ancestors, before, after);
|
|
726
1419
|
try {
|
|
727
|
-
|
|
728
|
-
walk();
|
|
729
|
-
return 0;
|
|
730
|
-
}
|
|
731
|
-
const opsStart = ops.length;
|
|
732
|
-
const atomicWeight = walk();
|
|
733
|
-
return tryCollapse(before, after, path, ops, opsStart, atomicWeight);
|
|
1420
|
+
walk();
|
|
734
1421
|
} finally {
|
|
735
1422
|
exitAncestorPair(ancestors, before, after);
|
|
736
1423
|
}
|
|
737
1424
|
};
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
1425
|
+
|
|
1426
|
+
// src/ops/internedOccupancy.ts
|
|
1427
|
+
var { proxyStateMap: proxyStateMap10 } = unstable_getInternalStates();
|
|
1428
|
+
var rawTargetOf6 = (value) => proxyStateMap10.get(value)?.[0] ?? value;
|
|
1429
|
+
var liveOf2 = (node) => getRegisteredTarget(node) ?? node;
|
|
1430
|
+
var occupancyNodeOf2 = (node) => rawTargetOf6(liveOf2(node));
|
|
1431
|
+
var internedOccupied = (handle, node, capture) => internedIdOf(handle, node, capture) !== void 0 && edgeStatusOf(handle, occupancyNodeOf2(node)).occupied;
|
|
1432
|
+
|
|
1433
|
+
// src/ops/mintPairs.ts
|
|
1434
|
+
var additionPair = (path, after, ids) => ({
|
|
1435
|
+
do: createAssignMutation(path, after, after, ids),
|
|
1436
|
+
undo: createDeleteMutation(path)
|
|
1437
|
+
});
|
|
1438
|
+
var removalPair = (path, before) => ({
|
|
1439
|
+
do: createDeleteMutation(path),
|
|
1440
|
+
undo: createAssignMutation(path, before)
|
|
1441
|
+
});
|
|
1442
|
+
var linkUndo = (path, before, beforePresent, handle, capture) => {
|
|
1443
|
+
if (!beforePresent) return createDeleteMutation(path);
|
|
1444
|
+
if (handle !== void 0 && isObjectLike3(before) && internedOccupied(handle, before, capture)) {
|
|
1445
|
+
const id = internedIdOf(handle, before, capture);
|
|
1446
|
+
if (id !== void 0) return createLinkMutation(path, id);
|
|
1447
|
+
}
|
|
1448
|
+
return createAssignMutation(path, before);
|
|
1449
|
+
};
|
|
1450
|
+
var linkOperation = (path, ref, before, beforePresent, handle, capture) => ({
|
|
1451
|
+
do: createLinkMutation(path, ref),
|
|
1452
|
+
undo: linkUndo(path, before, beforePresent, handle, capture)
|
|
1453
|
+
});
|
|
1454
|
+
var changePair = (path, before, after, handle, capture, ids) => ({
|
|
1455
|
+
do: createAssignMutation(path, after, after, ids),
|
|
1456
|
+
undo: linkUndo(path, before, true, handle, capture)
|
|
1457
|
+
});
|
|
1458
|
+
|
|
1459
|
+
// src/ops/diff.ts
|
|
1460
|
+
var IncompatibleObjectRootsError = class extends Error {
|
|
1461
|
+
constructor() {
|
|
1462
|
+
super("opshot: diffObjects requires compatible supported object roots");
|
|
1463
|
+
this.name = "IncompatibleObjectRootsError";
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
var commitOperation = (context, pair) => {
|
|
1467
|
+
context.ops.push(pair);
|
|
1468
|
+
};
|
|
1469
|
+
var commitLink = (context, path, ref, before, beforePresent) => {
|
|
1470
|
+
commitOperation(context, linkOperation(path, ref, before, beforePresent, context.handle, context.capture));
|
|
1471
|
+
};
|
|
1472
|
+
var emptyContainerOf = (value) => isPlainArray(value) ? [] : {};
|
|
1473
|
+
var namedArrayEntriesOf = (value) => {
|
|
1474
|
+
const named = /* @__PURE__ */ new Map();
|
|
1475
|
+
for (const key of Object.keys(value)) {
|
|
1476
|
+
if (key === "__proto__" || isCanonicalArrayIndexString(key)) continue;
|
|
1477
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
1478
|
+
if (!descriptor || !("value" in descriptor)) continue;
|
|
1479
|
+
named.set(key, descriptor.value);
|
|
1480
|
+
}
|
|
1481
|
+
return named;
|
|
1482
|
+
};
|
|
1483
|
+
var mintDecomposedContents = (context, path, after, verdict) => {
|
|
1484
|
+
const residual = verdict.chains;
|
|
1485
|
+
const liveNode = verdict.liveChild;
|
|
1486
|
+
if (isPlainArray(after)) {
|
|
1487
|
+
if (after.length > 0)
|
|
1488
|
+
commitOperation(
|
|
1489
|
+
context,
|
|
1490
|
+
changePair(appendOperationPath(path, "length"), 0, after.length, context.handle, context.capture)
|
|
1491
|
+
);
|
|
1492
|
+
for (let index = 0; index < after.length; index++) {
|
|
1493
|
+
if (!Object.hasOwn(after, index)) continue;
|
|
1494
|
+
const nextPath = appendOperationPath(path, index);
|
|
1495
|
+
const childVerdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1496
|
+
pushAddition(context, nextPath, after[index], childVerdict, liveNode);
|
|
1497
|
+
}
|
|
1498
|
+
for (const [key, value] of namedArrayEntriesOf(after)) {
|
|
1499
|
+
const nextPath = appendOperationPath(path, key);
|
|
1500
|
+
const childVerdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1501
|
+
pushAddition(context, nextPath, value, childVerdict, liveNode);
|
|
1502
|
+
}
|
|
1503
|
+
} else {
|
|
1504
|
+
for (const entry of walkDataEntries(after)) {
|
|
1505
|
+
const nextPath = appendOperationPath(path, entry.key);
|
|
1506
|
+
const childVerdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1507
|
+
pushAddition(context, nextPath, entry.value, childVerdict, liveNode);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
var mintDecomposedAddition = (context, path, after, verdict) => {
|
|
1512
|
+
commitOperation(context, {
|
|
1513
|
+
do: createAssignMutation(path, emptyContainerOf(after), after),
|
|
1514
|
+
undo: createDeleteMutation(path)
|
|
1515
|
+
});
|
|
1516
|
+
mintDecomposedContents(context, path, after, verdict);
|
|
1517
|
+
};
|
|
1518
|
+
var mintDecomposedChange = (context, path, before, after, verdict) => {
|
|
1519
|
+
commitOperation(context, {
|
|
1520
|
+
do: createAssignMutation(path, emptyContainerOf(after), after),
|
|
1521
|
+
undo: linkUndo(path, before, true, context.handle, context.capture)
|
|
1522
|
+
});
|
|
1523
|
+
mintDecomposedContents(context, path, after, verdict);
|
|
1524
|
+
};
|
|
1525
|
+
var surveyAssignedSubtree = (handle, capture, node, residual, stopAtInternedOccupied) => {
|
|
1526
|
+
const visits = /* @__PURE__ */ new Set();
|
|
1527
|
+
const pending = new Array();
|
|
1528
|
+
const visit = (current, currentResidual) => {
|
|
1529
|
+
const raw = occupancyNodeOf2(current);
|
|
1530
|
+
if (visits.has(raw)) return false;
|
|
1531
|
+
visits.add(raw);
|
|
1532
|
+
if (admissionLane(current) === "untracked") return false;
|
|
1533
|
+
if (stopAtInternedOccupied) {
|
|
1534
|
+
if (current !== node) pending.push(current);
|
|
1535
|
+
} else stageVend(handle, capture, current);
|
|
1536
|
+
const source = liveOf2(current);
|
|
1537
|
+
for (const entry of walkDataEntries(source)) {
|
|
1538
|
+
if (typeof entry.value !== "object" || entry.value === null) continue;
|
|
1539
|
+
if (!isTrackedEdge(entry)) continue;
|
|
1540
|
+
const key = segmentFor(source, entry.key);
|
|
1541
|
+
const resolved = resolveChildChains(handle, source, currentResidual, key, entry.value);
|
|
1542
|
+
if (resolved === void 0) continue;
|
|
1543
|
+
const child = entry.value;
|
|
1544
|
+
if (stopAtInternedOccupied && internedOccupied(handle, child, capture)) return true;
|
|
1545
|
+
if (visit(child, resolved.chains)) return true;
|
|
1546
|
+
}
|
|
1547
|
+
return false;
|
|
1548
|
+
};
|
|
1549
|
+
if (stopAtInternedOccupied) stageVend(handle, capture, node);
|
|
1550
|
+
const reachesInternedOccupied = visit(node, residual);
|
|
1551
|
+
if (stopAtInternedOccupied && !reachesInternedOccupied) {
|
|
1552
|
+
for (const pendingNode of pending) stageVend(handle, capture, pendingNode);
|
|
1553
|
+
}
|
|
1554
|
+
return { reachesInternedOccupied };
|
|
1555
|
+
};
|
|
1556
|
+
var internIdsOfSubtree = (handle, node, capture) => {
|
|
1557
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1558
|
+
const ids = new Array();
|
|
1559
|
+
const walk = (current) => {
|
|
1560
|
+
const id = internedIdOf(handle, current, capture);
|
|
1561
|
+
if (id === void 0 || seen.has(id)) return;
|
|
1562
|
+
seen.add(id);
|
|
1563
|
+
ids.push(id);
|
|
1564
|
+
for (const entry of walkDataEntries(liveOf2(current))) {
|
|
1565
|
+
if (typeof entry.value === "object" && entry.value !== null) walk(entry.value);
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
walk(node);
|
|
1569
|
+
return ids.length === 0 ? void 0 : ids;
|
|
1570
|
+
};
|
|
1571
|
+
var mintAssignment = (context, path, before, after, beforePresent, verdict) => {
|
|
1572
|
+
if (verdict.ignored) return;
|
|
1573
|
+
const handle = context.handle;
|
|
1574
|
+
if (isObjectLike3(after) && handle !== void 0) {
|
|
1575
|
+
const internedId = internedIdOf(handle, after, context.capture);
|
|
1576
|
+
if (internedId !== void 0 && internedOccupied(handle, after, context.capture)) {
|
|
1577
|
+
const sameOccupant = isObjectLike3(before) && occupancyNodeOf2(before) === occupancyNodeOf2(after);
|
|
1578
|
+
const beforeInterned = isObjectLike3(before) && internedIdOf(handle, before, context.capture) !== void 0;
|
|
1579
|
+
const uninternedTrackedBefore = isObjectLike3(before) && !beforeInterned && admissionLane(before) !== "untracked";
|
|
1580
|
+
if (!sameOccupant && !uninternedTrackedBefore) {
|
|
1581
|
+
commitLink(context, path, internedId, before, beforePresent);
|
|
1582
|
+
return;
|
|
1583
|
+
}
|
|
1584
|
+
surveyAssignedSubtree(handle, context.capture, after, verdict.chains, false);
|
|
1585
|
+
} else if (admissionLane(after) !== "untracked" && (isPlainObject(after) || isPlainArray(after))) {
|
|
1586
|
+
const { reachesInternedOccupied } = surveyAssignedSubtree(
|
|
1587
|
+
handle,
|
|
1588
|
+
context.capture,
|
|
1589
|
+
after,
|
|
1590
|
+
verdict.chains,
|
|
1591
|
+
true
|
|
1592
|
+
);
|
|
1593
|
+
if (reachesInternedOccupied) {
|
|
1594
|
+
if (!beforePresent) {
|
|
1595
|
+
mintDecomposedAddition(context, path, after, verdict);
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1598
|
+
mintDecomposedChange(context, path, before, after, verdict);
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1601
|
+
} else {
|
|
1602
|
+
admitDescendants(handle, path, /* @__PURE__ */ new Set(), verdict.chains, verdict.liveChild);
|
|
1603
|
+
internSubtree(
|
|
1604
|
+
handle,
|
|
1605
|
+
after,
|
|
1606
|
+
verdict.chains,
|
|
1607
|
+
(parent, parentChains, key, entry) => isTrackedEdge(entry) ? resolveChildChains(handle, parent, parentChains, key, entry.value)?.chains : void 0,
|
|
1608
|
+
context.capture
|
|
1609
|
+
);
|
|
1610
|
+
}
|
|
1611
|
+
} else if (isObjectLike3(after)) admitDescendants(context.handle, path, /* @__PURE__ */ new Set(), verdict.chains, verdict.liveChild);
|
|
1612
|
+
const ids = isObjectLike3(after) && handle !== void 0 ? internIdsOfSubtree(handle, after, context.capture) : void 0;
|
|
1613
|
+
if (beforePresent) commitOperation(context, changePair(path, before, after, handle, context.capture, ids));
|
|
1614
|
+
else commitOperation(context, additionPair(path, after, ids));
|
|
1615
|
+
};
|
|
1616
|
+
var pushAddition = (context, path, after, verdict, liveParent) => {
|
|
1617
|
+
const { visit, ignored } = verdict;
|
|
1618
|
+
if (visit === "skip") {
|
|
1619
|
+
if (ignored || !emitsSkippedOccupancy(after)) return;
|
|
1620
|
+
} else if (ignored) return;
|
|
1621
|
+
markChangedPath(context.handle, context.dirty, path, liveParent);
|
|
1622
|
+
mintAssignment(context, path, void 0, after, false, verdict);
|
|
1623
|
+
};
|
|
1624
|
+
var pushRemoval = (context, path, before, verdict, liveParent) => {
|
|
1625
|
+
if (verdict.ignored) return;
|
|
1626
|
+
markChangedPath(context.handle, context.dirty, path, liveParent);
|
|
1627
|
+
const handle = context.handle;
|
|
1628
|
+
if (isObjectLike3(before) && handle !== void 0) {
|
|
1629
|
+
const id = internedIdOf(handle, before, context.capture);
|
|
1630
|
+
if (id !== void 0 && internedOccupied(handle, before, context.capture)) {
|
|
1631
|
+
commitOperation(context, {
|
|
1632
|
+
do: createDeleteMutation(path),
|
|
1633
|
+
undo: createLinkMutation(path, id)
|
|
1634
|
+
});
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
commitOperation(context, removalPair(path, before));
|
|
1639
|
+
};
|
|
1640
|
+
var pushChange = (context, path, before, after, verdict, liveParent) => {
|
|
1641
|
+
markChangedPath(context.handle, context.dirty, path, liveParent);
|
|
1642
|
+
mintAssignment(context, path, before, after, true, verdict);
|
|
1643
|
+
};
|
|
1644
|
+
var sharesStorageIdentity = (before, after) => isObjectLike3(before) && isObjectLike3(after) && isSameIdentity(before, after);
|
|
1645
|
+
var diffCollectedProperties = (context, before, after, path, residual, liveNode, beforeEntries, afterEntries) => {
|
|
1646
|
+
const keys = /* @__PURE__ */ new Set([...beforeEntries.keys(), ...afterEntries.keys()]);
|
|
1647
|
+
for (const key of keys) {
|
|
1648
|
+
const nextPath = appendOperationPath(path, key);
|
|
1649
|
+
const beforePresent = beforeEntries.has(key);
|
|
1650
|
+
const afterPresent = afterEntries.has(key);
|
|
1651
|
+
if (beforePresent && afterPresent) {
|
|
1652
|
+
diffValue(context, beforeEntries.get(key), afterEntries.get(key), nextPath, residual, liveNode);
|
|
1653
|
+
} else if (beforePresent && !Object.hasOwn(after, key)) {
|
|
1654
|
+
const verdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1655
|
+
pushRemoval(context, nextPath, beforeEntries.get(key), verdict, liveNode);
|
|
1656
|
+
} else if (afterPresent && !Object.hasOwn(before, key)) {
|
|
1657
|
+
const verdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1658
|
+
pushAddition(context, nextPath, afterEntries.get(key), verdict, liveNode);
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
};
|
|
1662
|
+
var diffObjectProperties = (context, before, after, path, residual, liveNode) => {
|
|
1663
|
+
diffCollectedProperties(
|
|
1664
|
+
context,
|
|
1665
|
+
before,
|
|
1666
|
+
after,
|
|
1667
|
+
path,
|
|
1668
|
+
residual,
|
|
1669
|
+
liveNode,
|
|
1670
|
+
dataEntryValuesOf(before),
|
|
1671
|
+
dataEntryValuesOf(after)
|
|
1672
|
+
);
|
|
1673
|
+
};
|
|
1674
|
+
var diffArray = (context, before, after, path, residual, liveNode) => {
|
|
1675
|
+
const overlap = Math.min(before.length, after.length);
|
|
1676
|
+
for (let index = 0; index < overlap; index++) {
|
|
1677
|
+
const beforePresent = Object.hasOwn(before, index);
|
|
1678
|
+
const afterPresent = Object.hasOwn(after, index);
|
|
1679
|
+
if (!beforePresent && !afterPresent) continue;
|
|
1680
|
+
const nextPath = appendOperationPath(path, index);
|
|
1681
|
+
if (!beforePresent) {
|
|
1682
|
+
const verdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1683
|
+
pushAddition(context, nextPath, after[index], verdict, liveNode);
|
|
1684
|
+
} else if (!afterPresent) {
|
|
1685
|
+
const verdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1686
|
+
pushRemoval(context, nextPath, before[index], verdict, liveNode);
|
|
1687
|
+
} else diffValue(context, before[index], after[index], nextPath, residual, liveNode);
|
|
1688
|
+
}
|
|
1689
|
+
if (after.length > before.length) {
|
|
1690
|
+
const lengthPath = appendOperationPath(path, "length");
|
|
1691
|
+
const lengthVerdict = admitStep(context.handle, context.dirty, lengthPath, liveNode, residual);
|
|
1692
|
+
pushChange(context, lengthPath, before.length, after.length, lengthVerdict, liveNode);
|
|
1693
|
+
for (let index = before.length; index < after.length; index++) {
|
|
1694
|
+
if (!Object.hasOwn(after, index)) continue;
|
|
1695
|
+
const nextPath = appendOperationPath(path, index);
|
|
1696
|
+
const verdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1697
|
+
pushAddition(context, nextPath, after[index], verdict, liveNode);
|
|
1698
|
+
}
|
|
1699
|
+
} else if (after.length < before.length) {
|
|
1700
|
+
for (let index = after.length; index < before.length; index++) {
|
|
1701
|
+
if (!Object.hasOwn(before, index)) continue;
|
|
1702
|
+
const nextPath = appendOperationPath(path, index);
|
|
1703
|
+
const verdict = admitStep(context.handle, context.dirty, nextPath, liveNode, residual);
|
|
1704
|
+
pushRemoval(context, nextPath, before[index], verdict, liveNode);
|
|
1705
|
+
}
|
|
1706
|
+
const lengthPath = appendOperationPath(path, "length");
|
|
1707
|
+
const lengthVerdict = admitStep(context.handle, context.dirty, lengthPath, liveNode, residual);
|
|
1708
|
+
pushChange(context, lengthPath, before.length, after.length, lengthVerdict, liveNode);
|
|
1709
|
+
}
|
|
1710
|
+
diffCollectedProperties(
|
|
1711
|
+
context,
|
|
1712
|
+
before,
|
|
1713
|
+
after,
|
|
1714
|
+
path,
|
|
1715
|
+
residual,
|
|
1716
|
+
liveNode,
|
|
1717
|
+
namedArrayEntriesOf(before),
|
|
1718
|
+
namedArrayEntriesOf(after)
|
|
1719
|
+
);
|
|
1720
|
+
};
|
|
1721
|
+
var diffValue = (context, before, after, path, residual, liveParent) => {
|
|
1722
|
+
const replacing = path.length > 0 && isObjectLike3(before) && isObjectLike3(after) && !sharesStorageIdentity(before, after);
|
|
1723
|
+
const verdict = admitStep(context.handle, context.dirty, path, liveParent, residual);
|
|
1724
|
+
const { visit, ignored, liveChild, chains } = verdict;
|
|
1725
|
+
if (visit === "skip" || ignored) {
|
|
1726
|
+
if (Object.is(before, after)) return;
|
|
1727
|
+
if (isObjectLike3(before) && isObjectLike3(after) && sharesStorageIdentity(before, after)) return;
|
|
1728
|
+
if (ignored || !emitsSkippedOccupancy(after)) return;
|
|
1729
|
+
pushChange(context, path, before, after, verdict, liveParent);
|
|
1730
|
+
return;
|
|
1731
|
+
}
|
|
1732
|
+
if (Object.is(before, after)) return;
|
|
1733
|
+
if (replacing) {
|
|
1734
|
+
pushChange(context, path, before, after, verdict, liveParent);
|
|
1735
|
+
return;
|
|
744
1736
|
}
|
|
745
1737
|
if (isPlainArray(before) && isPlainArray(after)) {
|
|
746
|
-
|
|
1738
|
+
walkContainer(context.ancestors, before, after, () => diffArray(context, before, after, path, chains, liveChild));
|
|
1739
|
+
return;
|
|
747
1740
|
}
|
|
748
1741
|
if (isPlainObject(before) && isPlainObject(after)) {
|
|
749
|
-
|
|
1742
|
+
walkContainer(
|
|
1743
|
+
context.ancestors,
|
|
750
1744
|
before,
|
|
751
1745
|
after,
|
|
752
|
-
path,
|
|
753
|
-
ops,
|
|
754
|
-
ancestors,
|
|
755
|
-
() => diffObjectProperties(before, after, path, ops, ancestors, false)
|
|
1746
|
+
() => diffObjectProperties(context, before, after, path, chains, liveChild)
|
|
756
1747
|
);
|
|
1748
|
+
return;
|
|
757
1749
|
}
|
|
758
|
-
|
|
759
|
-
assertSafeSubtree(after, path);
|
|
760
|
-
return pushReplace(ops, path, before, after);
|
|
1750
|
+
pushChange(context, path, before, after, verdict, liveParent);
|
|
761
1751
|
};
|
|
762
1752
|
var getRootKind = (value) => {
|
|
763
1753
|
if (isPlainArray(value)) return "plainArray";
|
|
764
1754
|
if (isPlainObject(value)) return "plainObject";
|
|
765
1755
|
return void 0;
|
|
766
1756
|
};
|
|
767
|
-
function
|
|
1757
|
+
function diffObjects(before, after, handle, dirty, capture) {
|
|
768
1758
|
const beforeKind = getRootKind(before);
|
|
769
1759
|
const afterKind = getRootKind(after);
|
|
770
|
-
if (beforeKind === void 0 || beforeKind !== afterKind) throw new
|
|
1760
|
+
if (beforeKind === void 0 || beforeKind !== afterKind) throw new IncompatibleObjectRootsError();
|
|
771
1761
|
const ops = new Array();
|
|
772
|
-
|
|
1762
|
+
const context = {
|
|
1763
|
+
ops,
|
|
1764
|
+
ancestors: /* @__PURE__ */ new Map(),
|
|
1765
|
+
handle,
|
|
1766
|
+
dirty,
|
|
1767
|
+
capture: capture ?? createCaptureTables()
|
|
1768
|
+
};
|
|
1769
|
+
diffValue(
|
|
1770
|
+
context,
|
|
1771
|
+
before,
|
|
1772
|
+
after,
|
|
1773
|
+
createOperationPath([]),
|
|
1774
|
+
handle === void 0 ? [void 0] : chainsAtRoot(handle.declarations),
|
|
1775
|
+
handle?.proxy.root
|
|
1776
|
+
);
|
|
773
1777
|
return ops;
|
|
774
1778
|
}
|
|
775
1779
|
|
|
776
1780
|
// src/emit/emitterDeliver.ts
|
|
777
|
-
var
|
|
778
|
-
const
|
|
779
|
-
for (const
|
|
780
|
-
|
|
781
|
-
|
|
1781
|
+
var collectDeliveries = (handle) => {
|
|
1782
|
+
const deliveries = [];
|
|
1783
|
+
for (const groupListeners of handle.groups ?? []) {
|
|
1784
|
+
for (const byChannel of groupListeners.values()) {
|
|
1785
|
+
for (const deliverToListener of byChannel.values()) {
|
|
1786
|
+
deliveries.push({ kind: "group", deliver: deliverToListener });
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
for (const byChannel of handle.subscribers.values()) {
|
|
1791
|
+
for (const deliverToListener of byChannel.values()) {
|
|
1792
|
+
deliveries.push({ kind: "own", deliver: deliverToListener });
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
return deliveries;
|
|
782
1796
|
};
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
1797
|
+
var runDelivery = (pending, failures) => {
|
|
1798
|
+
const handle = handleOf(pending.writeProxy);
|
|
1799
|
+
if (handle !== void 0) handle.lastDirty = pending.dirty;
|
|
1800
|
+
for (const delivery of pending.deliveries) {
|
|
1801
|
+
try {
|
|
1802
|
+
if (delivery.kind === "group") {
|
|
1803
|
+
delivery.deliver(pending.writeProxy, pending.ops, pending.meta, pending.channelId);
|
|
1804
|
+
} else {
|
|
1805
|
+
delivery.deliver(pending.ops, pending.meta, pending.channelId);
|
|
1806
|
+
}
|
|
1807
|
+
} catch (error) {
|
|
1808
|
+
failures.push(error);
|
|
1809
|
+
}
|
|
794
1810
|
}
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
1811
|
+
};
|
|
1812
|
+
var raiseFailures = (failures) => {
|
|
1813
|
+
if (failures.length === 0) return;
|
|
1814
|
+
if (failures.length > 1) throw new AggregateError(failures, "opshot: listeners failed during delivery");
|
|
1815
|
+
throw failures[0];
|
|
1816
|
+
};
|
|
1817
|
+
var queuedDeliveries = [];
|
|
1818
|
+
var deliveryFailures = [];
|
|
1819
|
+
var isDraining = false;
|
|
1820
|
+
var prepareDelivery = (handle, ops, meta, channelId, dirty) => ({
|
|
1821
|
+
writeProxy: handle.proxy.root,
|
|
1822
|
+
deliveries: collectDeliveries(handle),
|
|
1823
|
+
ops,
|
|
1824
|
+
meta,
|
|
1825
|
+
channelId,
|
|
1826
|
+
dirty
|
|
1827
|
+
});
|
|
1828
|
+
var enqueueDelivery = (pending) => {
|
|
1829
|
+
queuedDeliveries.push(pending);
|
|
1830
|
+
};
|
|
1831
|
+
var drainDeliveries = () => {
|
|
1832
|
+
if (isDraining) return;
|
|
1833
|
+
isDraining = true;
|
|
1834
|
+
let failures = [];
|
|
1835
|
+
try {
|
|
1836
|
+
while (queuedDeliveries.length > 0) {
|
|
1837
|
+
for (const queued of queuedDeliveries.splice(0, queuedDeliveries.length)) {
|
|
1838
|
+
runDelivery(queued, deliveryFailures);
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
} finally {
|
|
1842
|
+
isDraining = false;
|
|
1843
|
+
failures = deliveryFailures.splice(0, deliveryFailures.length);
|
|
1844
|
+
}
|
|
1845
|
+
raiseFailures(failures);
|
|
1846
|
+
};
|
|
798
1847
|
|
|
799
1848
|
// src/emit/emitterRegistry.ts
|
|
800
|
-
var
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
lastReported: snapshot(resolved),
|
|
813
|
-
isMutating: false,
|
|
814
|
-
target: resolved
|
|
1849
|
+
var { proxyStateMap: proxyStateMap11 } = unstable_getInternalStates();
|
|
1850
|
+
var targetOf = (writeProxy) => proxyStateMap11.get(writeProxy)?.[0] ?? writeProxy;
|
|
1851
|
+
|
|
1852
|
+
// src/emit/emitter.ts
|
|
1853
|
+
function scheduleFlush(handle) {
|
|
1854
|
+
if (handle.isFlushScheduled) return;
|
|
1855
|
+
handle.isFlushScheduled = true;
|
|
1856
|
+
const generation = handle.flushGeneration;
|
|
1857
|
+
const run = () => {
|
|
1858
|
+
if (generation !== handle.flushGeneration) return;
|
|
1859
|
+
handle.isFlushScheduled = false;
|
|
1860
|
+
emitWrites(handle);
|
|
815
1861
|
};
|
|
816
|
-
|
|
817
|
-
|
|
1862
|
+
void Promise.resolve().then(() => {
|
|
1863
|
+
const emitOn = handle.emitOn;
|
|
1864
|
+
if (emitOn === void 0) {
|
|
1865
|
+
run();
|
|
1866
|
+
return;
|
|
1867
|
+
}
|
|
1868
|
+
emitOn(run);
|
|
1869
|
+
});
|
|
818
1870
|
}
|
|
819
|
-
function
|
|
820
|
-
|
|
1871
|
+
function armWatch(handle) {
|
|
1872
|
+
handle.disarmWatch = subscribe(
|
|
1873
|
+
handle.proxy.root,
|
|
1874
|
+
() => {
|
|
1875
|
+
handle.hasPendingWrites = true;
|
|
1876
|
+
if (handle.isFlushHeld) return;
|
|
1877
|
+
scheduleFlush(handle);
|
|
1878
|
+
});
|
|
821
1879
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
);
|
|
1880
|
+
var cloneSnapshotNode = (snap) => {
|
|
1881
|
+
const clone = Array.isArray(snap) ? [] : Object.create(Reflect.getPrototypeOf(snap));
|
|
1882
|
+
for (const key of carriedOwnKeysOf(snap)) {
|
|
1883
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(snap, key);
|
|
1884
|
+
if (descriptor !== void 0) Object.defineProperty(clone, key, descriptor);
|
|
1885
|
+
}
|
|
1886
|
+
if (Array.isArray(snap)) clone.length = snap.length;
|
|
1887
|
+
registerSnapshotCopy(clone, getRegisteredTarget(snap) ?? targetOf(snap));
|
|
1888
|
+
return clone;
|
|
830
1889
|
};
|
|
831
|
-
var
|
|
832
|
-
if (
|
|
833
|
-
|
|
1890
|
+
var reconcileUntracked = (snap, live, seen) => {
|
|
1891
|
+
if (seen.has(live)) return snap;
|
|
1892
|
+
seen.add(live);
|
|
1893
|
+
let result;
|
|
1894
|
+
const written = () => {
|
|
1895
|
+
result ??= cloneSnapshotNode(snap);
|
|
1896
|
+
return result;
|
|
1897
|
+
};
|
|
1898
|
+
for (const key of carriedOwnKeysOf(live)) {
|
|
1899
|
+
const liveValue = Reflect.get(live, key);
|
|
1900
|
+
if (typeof liveValue !== "object" || liveValue === null) continue;
|
|
1901
|
+
if (admissionLane(liveValue) === "untracked") {
|
|
1902
|
+
if (Reflect.get(snap, key) === liveValue) continue;
|
|
1903
|
+
const snapChild2 = Reflect.get(snap, key);
|
|
1904
|
+
if (typeof snapChild2 !== "object" || snapChild2 === null) continue;
|
|
1905
|
+
if (getRegisteredTarget(snapChild2) !== targetOf(liveValue)) continue;
|
|
1906
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(live, key);
|
|
1907
|
+
if (descriptor === void 0 || descriptor.get !== void 0 || descriptor.set !== void 0) continue;
|
|
1908
|
+
Object.defineProperty(written(), key, {
|
|
1909
|
+
value: liveValue,
|
|
1910
|
+
enumerable: descriptor.enumerable,
|
|
1911
|
+
configurable: true
|
|
1912
|
+
});
|
|
1913
|
+
continue;
|
|
1914
|
+
}
|
|
1915
|
+
const snapChild = Reflect.get(snap, key);
|
|
1916
|
+
if (typeof snapChild !== "object" || snapChild === null) continue;
|
|
1917
|
+
const reconciled = reconcileUntracked(snapChild, liveValue, seen);
|
|
1918
|
+
if (reconciled === snapChild) continue;
|
|
1919
|
+
Object.defineProperty(written(), key, {
|
|
1920
|
+
value: reconciled,
|
|
1921
|
+
enumerable: true,
|
|
1922
|
+
configurable: true
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1925
|
+
return result ?? snap;
|
|
834
1926
|
};
|
|
835
|
-
var
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
1927
|
+
var captureDiffOf = (handle, from, capture) => {
|
|
1928
|
+
const to = snapshot(handle.proxy.root);
|
|
1929
|
+
const dirty = { edges: /* @__PURE__ */ new WeakMap(), nodes: /* @__PURE__ */ new WeakSet() };
|
|
1930
|
+
if (from === to) {
|
|
1931
|
+
syncHandleTables(handle, capture);
|
|
1932
|
+
return { to, ops: [], dirty, capture };
|
|
1933
|
+
}
|
|
1934
|
+
return {
|
|
1935
|
+
to,
|
|
1936
|
+
ops: diffObjects(reconcileUntracked(from, handle.proxy.root, /* @__PURE__ */ new WeakSet()), to, handle, dirty, capture),
|
|
1937
|
+
dirty,
|
|
1938
|
+
capture
|
|
1939
|
+
};
|
|
841
1940
|
};
|
|
842
|
-
var
|
|
843
|
-
|
|
844
|
-
|
|
1941
|
+
var captureRange = (handle, meta, channelId) => {
|
|
1942
|
+
handle.hasPendingWrites = false;
|
|
1943
|
+
const from = handle.lastSnapshot;
|
|
1944
|
+
const capture = handle.transactionCapture ?? createCaptureTables();
|
|
1945
|
+
const committed = captureDiffOf(handle, from, capture);
|
|
1946
|
+
const ops = committed.ops;
|
|
1947
|
+
commitVends(handle, committed.capture);
|
|
1948
|
+
handle.lastSnapshot = committed.to;
|
|
1949
|
+
const evicted = evictDepartedClusters(handle);
|
|
1950
|
+
if (ops.length > 0) annotateDepartureUndos(handle, ops, evicted);
|
|
1951
|
+
if (ops.length > 0 && !handle.replaying) {
|
|
1952
|
+
for (const operation of ops) stampOperation(handle, operation);
|
|
1953
|
+
}
|
|
1954
|
+
return ops.length > 0 ? prepareDelivery(handle, ops, meta, channelId, committed.dirty) : void 0;
|
|
845
1955
|
};
|
|
846
|
-
|
|
847
|
-
const
|
|
848
|
-
|
|
849
|
-
const previous = record.lastReported;
|
|
850
|
-
record.lastReported = current;
|
|
851
|
-
if (!hasListeners(record)) return;
|
|
852
|
-
try {
|
|
853
|
-
const ops = diffSnapshots(requireObjectSnapshot(previous), requireObjectSnapshot(current));
|
|
854
|
-
if (ops.length === 0) return;
|
|
855
|
-
deliver(record, ops, void 0);
|
|
856
|
-
} catch (error) {
|
|
857
|
-
throw augmentBareCycleError(error) ?? error;
|
|
1956
|
+
function deliverCapturedRanges(ranges) {
|
|
1957
|
+
for (const captured of ranges) {
|
|
1958
|
+
if (captured !== void 0) enqueueDelivery(captured);
|
|
858
1959
|
}
|
|
1960
|
+
drainDeliveries();
|
|
1961
|
+
}
|
|
1962
|
+
var emitRange = (handle, meta, channelId) => {
|
|
1963
|
+
const captured = captureRange(handle, meta, channelId);
|
|
1964
|
+
if (captured !== void 0) enqueueDelivery(captured);
|
|
1965
|
+
drainDeliveries();
|
|
859
1966
|
};
|
|
860
|
-
|
|
861
|
-
|
|
1967
|
+
function captureWrites(handle) {
|
|
1968
|
+
return captureRange(handle, void 0, void 0);
|
|
1969
|
+
}
|
|
1970
|
+
function captureTransactionWrites(handle, meta, channelId) {
|
|
1971
|
+
return captureRange(handle, meta, channelId);
|
|
1972
|
+
}
|
|
1973
|
+
function emitWrites(handle) {
|
|
1974
|
+
emitRange(handle, void 0, void 0);
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
// src/emit/requireObjectSnapshot.ts
|
|
1978
|
+
var ObjectRootSnapshotError = class extends Error {
|
|
1979
|
+
constructor() {
|
|
1980
|
+
super("opshot: state snapshots must have an object root");
|
|
1981
|
+
this.name = "ObjectRootSnapshotError";
|
|
1982
|
+
}
|
|
862
1983
|
};
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
1984
|
+
var requireObjectSnapshot = (value) => {
|
|
1985
|
+
if (value !== null && (typeof value === "object" || typeof value === "function")) return value;
|
|
1986
|
+
throw new ObjectRootSnapshotError();
|
|
1987
|
+
};
|
|
1988
|
+
|
|
1989
|
+
// src/ignore.ts
|
|
1990
|
+
var ignoreMarker = /* @__PURE__ */ Symbol("opshot.ignore");
|
|
1991
|
+
function ignore(value) {
|
|
1992
|
+
return { [ignoreMarker]: value };
|
|
867
1993
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
1994
|
+
|
|
1995
|
+
// src/isState.ts
|
|
1996
|
+
var { proxyStateMap: proxyStateMap12 } = unstable_getInternalStates();
|
|
1997
|
+
function isState(value) {
|
|
1998
|
+
const resolved = peelReadProxy(value);
|
|
1999
|
+
if (typeof resolved !== "object" || resolved === null) return false;
|
|
2000
|
+
return proxyStateMap12.has(resolved);
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
// src/unsafeTrack.ts
|
|
2004
|
+
var unsafeMarker = /* @__PURE__ */ Symbol("opshot.unsafe");
|
|
2005
|
+
function unsafeTrack(value) {
|
|
2006
|
+
return { [unsafeMarker]: value };
|
|
872
2007
|
}
|
|
873
2008
|
|
|
874
2009
|
// src/utils/constructorName.ts
|
|
@@ -880,198 +2015,96 @@ var unsafeTrackDataOption = "unsafeTrack(value) to track its data anyway";
|
|
|
880
2015
|
var unsafeTrackPrivateOption = "unsafeTrack(value) tracks public fields while private methods throw on snapshots and undo drops that state";
|
|
881
2016
|
var unsafeTrackSlotOption = "unsafeTrack(value) tracks public fields while slot methods throw on snapshots and undo drops that state";
|
|
882
2017
|
var unsafeTrackLossyOption = "unsafeTrack(value) to track it lossily";
|
|
883
|
-
var
|
|
884
|
-
|
|
2018
|
+
var locationClause = (path) => path === void 0 || path.length === 0 ? "" : ` at /${path.join("/")}`;
|
|
2019
|
+
var boundaryError = (className, reason, options, path) => new Error(
|
|
2020
|
+
`opshot: ${className}${locationClause(path)} cannot be tracked (${reason}). Options:
|
|
885
2021
|
${options.map((option) => `- ${option}`).join("\n")}`
|
|
886
2022
|
);
|
|
887
|
-
var slotContainerError = (className, trackedName) => boundaryError(
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
ignoreOption
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
2023
|
+
var slotContainerError = (className, trackedName, path) => boundaryError(
|
|
2024
|
+
className,
|
|
2025
|
+
"its state lives in internal slots",
|
|
2026
|
+
[`use ${trackedName} for a tracked equivalent`, unsafeTrackLossyOption, ignoreOption],
|
|
2027
|
+
path
|
|
2028
|
+
);
|
|
2029
|
+
var arraySubclassError = (className, path) => boundaryError(
|
|
2030
|
+
className,
|
|
2031
|
+
"array subclasses lose their prototype in snapshots",
|
|
2032
|
+
[unsafeTrackDataOption, ignoreOption],
|
|
2033
|
+
path
|
|
2034
|
+
);
|
|
2035
|
+
var cleanClassError = (className, path) => boundaryError(className, "arrow-method writes won't be tracked", [unsafeTrackDataOption, ignoreOption], path);
|
|
2036
|
+
var privateClassError = (className, path) => boundaryError(className, "its state is hidden in private fields", [unsafeTrackPrivateOption, ignoreOption], path);
|
|
2037
|
+
var nativeClassError = (className, path) => boundaryError(className, "its state is hidden in internal slots", [unsafeTrackSlotOption, ignoreOption], path);
|
|
2038
|
+
var nonWritablePropertyError = (value, path) => boundaryError(
|
|
2039
|
+
constructorName(value.constructor),
|
|
2040
|
+
"a non-writable property's interior is silently mutable and untracked",
|
|
2041
|
+
["make the property writable", "ignore(value) to declare the escape"],
|
|
2042
|
+
path
|
|
2043
|
+
);
|
|
899
2044
|
var snapshotDonationError = (key) => new Error(
|
|
900
|
-
`opshot: cannot assign a snapshot generation at "${String(key)}": a snapshot generation is a read-view, and assigning it creates a dead region. Clone the value, or replay through
|
|
2045
|
+
`opshot: cannot assign a snapshot generation at "${String(key)}": a snapshot generation is a read-view, and assigning it creates a dead region. Clone the value, or replay through applyOperations.`
|
|
901
2046
|
);
|
|
902
|
-
var reservedDataPathError = (path) => new Error(`opshot: reserved data path /${path.join("/")}`);
|
|
903
2047
|
var inheritsFromPrototype = (value, prototype) => {
|
|
904
2048
|
for (let current = Reflect.getPrototypeOf(value); current !== null; current = Reflect.getPrototypeOf(current))
|
|
905
2049
|
if (current === prototype) return true;
|
|
906
2050
|
return false;
|
|
907
2051
|
};
|
|
908
|
-
var rejectionError = (value, kind) => {
|
|
2052
|
+
var rejectionError = (value, kind, path) => {
|
|
909
2053
|
const className = constructorName(value.constructor);
|
|
910
|
-
if (inheritsFromPrototype(value, Map.prototype)) return slotContainerError(className, "TrackedMap");
|
|
911
|
-
if (inheritsFromPrototype(value, Set.prototype)) return slotContainerError(className, "TrackedSet");
|
|
912
|
-
if (inheritsFromPrototype(value, Date.prototype)) return slotContainerError(className, "TrackedDate");
|
|
2054
|
+
if (inheritsFromPrototype(value, Map.prototype)) return slotContainerError(className, "TrackedMap", path);
|
|
2055
|
+
if (inheritsFromPrototype(value, Set.prototype)) return slotContainerError(className, "TrackedSet", path);
|
|
2056
|
+
if (inheritsFromPrototype(value, Date.prototype)) return slotContainerError(className, "TrackedDate", path);
|
|
913
2057
|
switch (kind) {
|
|
914
2058
|
case "arraySubclass":
|
|
915
|
-
return arraySubclassError(className);
|
|
2059
|
+
return arraySubclassError(className, path);
|
|
916
2060
|
case "cleanClass":
|
|
917
|
-
return cleanClassError(className);
|
|
2061
|
+
return cleanClassError(className, path);
|
|
918
2062
|
case "privateClass":
|
|
919
|
-
return privateClassError(className);
|
|
2063
|
+
return privateClassError(className, path);
|
|
920
2064
|
case "nativeClass":
|
|
921
|
-
return nativeClassError(className);
|
|
2065
|
+
return nativeClassError(className, path);
|
|
922
2066
|
}
|
|
923
2067
|
};
|
|
924
2068
|
|
|
925
|
-
// src/valtio/
|
|
926
|
-
var {
|
|
927
|
-
var
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
var getRawObject = (value) => {
|
|
932
|
-
const resolved = resolveIdentity(value);
|
|
933
|
-
return typeof resolved === "object" && resolved !== null ? resolved : void 0;
|
|
934
|
-
};
|
|
935
|
-
var getTrackedRawObject = (value) => {
|
|
936
|
-
const target = getRawObject(value);
|
|
937
|
-
if (!target || refSet4.has(target) || Object.isFrozen(target)) return void 0;
|
|
938
|
-
return isTrackable(target) ? target : void 0;
|
|
939
|
-
};
|
|
940
|
-
var getEnumerableDataChild = (target, key) => {
|
|
941
|
-
if (typeof key !== "string") return void 0;
|
|
942
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
943
|
-
if (!descriptor?.enumerable || !("value" in descriptor)) return void 0;
|
|
944
|
-
return getTrackedRawObject(descriptor.value);
|
|
945
|
-
};
|
|
946
|
-
var adjustConstructorPathTarget = (target, change) => {
|
|
947
|
-
const next = (constructorPathTargetCounts.get(target) ?? 0) + change;
|
|
948
|
-
if (next > 0) constructorPathTargetCounts.set(target, next);
|
|
949
|
-
else constructorPathTargetCounts.delete(target);
|
|
950
|
-
};
|
|
951
|
-
var constructorPathTargetCount = (target) => constructorPathTargetCounts.get(target) ?? 0;
|
|
952
|
-
var releaseFinalizationState = (state) => {
|
|
953
|
-
if (!state.active) return;
|
|
954
|
-
state.active = false;
|
|
955
|
-
for (const { target, count } of state.constructorTargets) {
|
|
956
|
-
const resolved = target.deref();
|
|
957
|
-
if (resolved) adjustConstructorPathTarget(resolved, -count);
|
|
958
|
-
}
|
|
959
|
-
state.constructorTargets = [];
|
|
960
|
-
};
|
|
961
|
-
var rootGraphFinalizer = new FinalizationRegistry(releaseFinalizationState);
|
|
962
|
-
var getRootGraphReference = (graph) => {
|
|
963
|
-
const existing = rootGraphReferences.get(graph);
|
|
964
|
-
if (existing) return existing;
|
|
965
|
-
const reference = new WeakRef(graph);
|
|
966
|
-
rootGraphReferences.set(graph, reference);
|
|
967
|
-
return reference;
|
|
968
|
-
};
|
|
969
|
-
var releaseRootGraph = (graph) => {
|
|
970
|
-
const reference = getRootGraphReference(graph);
|
|
971
|
-
for (const target of graph.targets) {
|
|
972
|
-
const references = rootGraphsByTarget.get(target);
|
|
973
|
-
references?.delete(reference);
|
|
974
|
-
if (references?.size === 0) rootGraphsByTarget.delete(target);
|
|
975
|
-
}
|
|
976
|
-
const root = graph.root.deref();
|
|
977
|
-
if (root) rootGraphsByRoot.delete(root);
|
|
978
|
-
releaseFinalizationState(graph.finalizationState);
|
|
979
|
-
rootGraphFinalizer.unregister(graph.finalizationState);
|
|
980
|
-
graph.targets.clear();
|
|
981
|
-
graph.constructorTargets.clear();
|
|
982
|
-
};
|
|
983
|
-
var getRootGraphs = (target) => {
|
|
984
|
-
const references = rootGraphsByTarget.get(target);
|
|
985
|
-
if (!references) return [];
|
|
986
|
-
const graphs = new Array();
|
|
987
|
-
for (const reference of references) {
|
|
988
|
-
const graph = reference.deref();
|
|
989
|
-
if (!graph) {
|
|
990
|
-
references.delete(reference);
|
|
991
|
-
continue;
|
|
992
|
-
}
|
|
993
|
-
if (!graph.root.deref()) {
|
|
994
|
-
releaseRootGraph(graph);
|
|
995
|
-
continue;
|
|
996
|
-
}
|
|
997
|
-
graphs.push(graph);
|
|
998
|
-
}
|
|
999
|
-
if (references.size === 0) rootGraphsByTarget.delete(target);
|
|
1000
|
-
return graphs;
|
|
1001
|
-
};
|
|
1002
|
-
var recomputeRootGraph = (graph) => {
|
|
1003
|
-
const root = graph.root.deref();
|
|
1004
|
-
if (!root) {
|
|
1005
|
-
releaseRootGraph(graph);
|
|
1006
|
-
return;
|
|
2069
|
+
// src/valtio/snapshotAccessors.ts
|
|
2070
|
+
var { proxyStateMap: proxyStateMap13, snapCache: snapCache2 } = unstable_getInternalStates();
|
|
2071
|
+
var MissingOwnDescriptorError2 = class extends Error {
|
|
2072
|
+
constructor() {
|
|
2073
|
+
super("opshot: carried own key has no property descriptor");
|
|
2074
|
+
this.name = "MissingOwnDescriptorError";
|
|
1007
2075
|
}
|
|
1008
|
-
const targets = /* @__PURE__ */ new Set();
|
|
1009
|
-
const constructorTargets = /* @__PURE__ */ new Map();
|
|
1010
|
-
const visit = (target) => {
|
|
1011
|
-
if (targets.has(target)) return;
|
|
1012
|
-
targets.add(target);
|
|
1013
|
-
const constructorTarget = getEnumerableDataChild(target, "constructor");
|
|
1014
|
-
if (constructorTarget)
|
|
1015
|
-
constructorTargets.set(constructorTarget, (constructorTargets.get(constructorTarget) ?? 0) + 1);
|
|
1016
|
-
for (const key of Object.keys(target)) {
|
|
1017
|
-
const child = getEnumerableDataChild(target, key);
|
|
1018
|
-
if (child) visit(child);
|
|
1019
|
-
}
|
|
1020
|
-
};
|
|
1021
|
-
visit(root);
|
|
1022
|
-
for (const [target, count] of graph.constructorTargets) adjustConstructorPathTarget(target, -count);
|
|
1023
|
-
for (const [target, count] of constructorTargets) adjustConstructorPathTarget(target, count);
|
|
1024
|
-
for (const target of graph.targets) {
|
|
1025
|
-
if (targets.has(target)) continue;
|
|
1026
|
-
const references = rootGraphsByTarget.get(target);
|
|
1027
|
-
references?.delete(getRootGraphReference(graph));
|
|
1028
|
-
if (references?.size === 0) rootGraphsByTarget.delete(target);
|
|
1029
|
-
}
|
|
1030
|
-
for (const target of targets) {
|
|
1031
|
-
if (graph.targets.has(target)) continue;
|
|
1032
|
-
const references = rootGraphsByTarget.get(target) ?? /* @__PURE__ */ new Set();
|
|
1033
|
-
references.add(getRootGraphReference(graph));
|
|
1034
|
-
rootGraphsByTarget.set(target, references);
|
|
1035
|
-
}
|
|
1036
|
-
graph.targets = targets;
|
|
1037
|
-
graph.constructorTargets = constructorTargets;
|
|
1038
|
-
graph.finalizationState.constructorTargets = [...constructorTargets].map(([target, count]) => ({
|
|
1039
|
-
target: new WeakRef(target),
|
|
1040
|
-
count
|
|
1041
|
-
}));
|
|
1042
|
-
};
|
|
1043
|
-
var registerTrackedRoot = (value) => {
|
|
1044
|
-
const root = getTrackedRawObject(value);
|
|
1045
|
-
if (!root || rootGraphsByRoot.has(root)) return;
|
|
1046
|
-
const finalizationState = { active: true, constructorTargets: [] };
|
|
1047
|
-
const graph = {
|
|
1048
|
-
root: new WeakRef(root),
|
|
1049
|
-
finalizationState,
|
|
1050
|
-
targets: /* @__PURE__ */ new Set(),
|
|
1051
|
-
constructorTargets: /* @__PURE__ */ new Map()
|
|
1052
|
-
};
|
|
1053
|
-
rootGraphsByRoot.set(root, graph);
|
|
1054
|
-
rootGraphFinalizer.register(root, finalizationState, finalizationState);
|
|
1055
|
-
recomputeRootGraph(graph);
|
|
1056
2076
|
};
|
|
1057
|
-
|
|
1058
|
-
// src/valtio/snapshotAccessors.ts
|
|
1059
|
-
var { refSet: refSet5, proxyStateMap: proxyStateMap4, snapCache: snapCache2 } = unstable_getInternalStates();
|
|
1060
2077
|
var createSnapshotPreservingAccessors = (target, version) => {
|
|
1061
2078
|
const cached = snapCache2.get(target);
|
|
1062
2079
|
if (cached?.[0] === version) {
|
|
1063
2080
|
const cachedSnapshot = cached[1];
|
|
1064
|
-
|
|
2081
|
+
for (const key of carriedOwnKeysOf(target)) {
|
|
2082
|
+
const value = Reflect.get(target, key);
|
|
2083
|
+
if (typeof value !== "object" || value === null) continue;
|
|
2084
|
+
if (admissionLane(value) !== "untracked") continue;
|
|
2085
|
+
if (Reflect.get(cachedSnapshot, key) === value) continue;
|
|
2086
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
2087
|
+
if (descriptor === void 0 || descriptor.get !== void 0 || descriptor.set !== void 0) continue;
|
|
2088
|
+
Object.defineProperty(cachedSnapshot, key, {
|
|
2089
|
+
value,
|
|
2090
|
+
enumerable: descriptor.enumerable,
|
|
2091
|
+
configurable: true
|
|
2092
|
+
});
|
|
2093
|
+
markToTrack(value, false);
|
|
2094
|
+
}
|
|
2095
|
+
if (getRegisteredTarget(cachedSnapshot) === void 0) {
|
|
2096
|
+
registerSnapshotCopy(cachedSnapshot, target);
|
|
2097
|
+
}
|
|
1065
2098
|
return cachedSnapshot;
|
|
1066
2099
|
}
|
|
1067
2100
|
const snap = Array.isArray(target) ? [] : Object.create(Reflect.getPrototypeOf(target));
|
|
1068
2101
|
registerSnapshotCopy(snap, target);
|
|
1069
2102
|
markToTrack(snap, true);
|
|
1070
2103
|
snapCache2.set(target, [version, snap]);
|
|
1071
|
-
for (const key of
|
|
2104
|
+
for (const key of carriedOwnKeysOf(target)) {
|
|
1072
2105
|
if (Object.getOwnPropertyDescriptor(snap, key)) continue;
|
|
1073
2106
|
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
1074
|
-
if (
|
|
2107
|
+
if (descriptor === void 0) throw new MissingOwnDescriptorError2();
|
|
1075
2108
|
if (descriptor.get || descriptor.set) {
|
|
1076
2109
|
Object.defineProperty(snap, key, {
|
|
1077
2110
|
get: descriptor.get,
|
|
@@ -1084,10 +2117,10 @@ var createSnapshotPreservingAccessors = (target, version) => {
|
|
|
1084
2117
|
const value = Reflect.get(target, key);
|
|
1085
2118
|
const snapshotDescriptor = { value, enumerable: descriptor.enumerable, configurable: true };
|
|
1086
2119
|
if (typeof value === "object" && value !== null) {
|
|
1087
|
-
if (
|
|
2120
|
+
if (admissionLane(value) === "untracked") {
|
|
1088
2121
|
markToTrack(value, false);
|
|
1089
2122
|
} else {
|
|
1090
|
-
const childState =
|
|
2123
|
+
const childState = proxyStateMap13.get(value);
|
|
1091
2124
|
if (childState)
|
|
1092
2125
|
snapshotDescriptor.value = createSnapshotPreservingAccessors(childState[0], childState[1]());
|
|
1093
2126
|
}
|
|
@@ -1097,96 +2130,320 @@ var createSnapshotPreservingAccessors = (target, version) => {
|
|
|
1097
2130
|
if (Array.isArray(target) && snap.length !== target.length) {
|
|
1098
2131
|
snap.length = target.length;
|
|
1099
2132
|
}
|
|
1100
|
-
if (isUnsafeTracked(target)) unsafeTrack(snap);
|
|
1101
2133
|
return snap;
|
|
1102
2134
|
};
|
|
1103
2135
|
|
|
1104
2136
|
// src/valtio/boundary.ts
|
|
1105
|
-
var
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
2137
|
+
var { proxyStateMap: proxyStateMap14, proxyCache: proxyCache3 } = unstable_getInternalStates();
|
|
2138
|
+
var rawTargetOf7 = (value) => proxyStateMap14.get(value)?.[0] ?? value;
|
|
2139
|
+
var handleOwning = (target) => {
|
|
2140
|
+
const handles = handlesOf(target);
|
|
2141
|
+
const raw = rawTargetOf7(target);
|
|
2142
|
+
for (const handle of handles) {
|
|
2143
|
+
if (rawTargetOf7(handle.proxy.root) === raw) return handle;
|
|
2144
|
+
}
|
|
2145
|
+
return handles[0];
|
|
2146
|
+
};
|
|
2147
|
+
var segmentForProp = (parent, prop) => isPlainArray(parent) && isCanonicalArrayIndexString(prop) ? Number(prop) : prop;
|
|
2148
|
+
var setFrameStack = new Array();
|
|
2149
|
+
var currentSetParentOf = () => setFrameStack[setFrameStack.length - 1]?.target;
|
|
2150
|
+
var currentStatuses = () => setFrameStack[setFrameStack.length - 1]?.statuses;
|
|
2151
|
+
var heldStatusesOf = (target, prop) => {
|
|
2152
|
+
const key = segmentForProp(target, prop);
|
|
2153
|
+
const statuses = new Array();
|
|
2154
|
+
for (const handle of handlesOf(target)) {
|
|
2155
|
+
const slot = slotStatusOf(handle, target, key);
|
|
2156
|
+
if (!slot.occupied) continue;
|
|
2157
|
+
statuses.push({ handle, ignored: slot.ignored, unsafe: slot.unsafe, chains: slot.chains });
|
|
2158
|
+
}
|
|
2159
|
+
return statuses.length === 0 ? void 0 : statuses;
|
|
2160
|
+
};
|
|
2161
|
+
var inheritedStatusesOf = (target, prop) => {
|
|
2162
|
+
const parent = setFrameStack[setFrameStack.length - 1];
|
|
2163
|
+
if (parent?.statuses === void 0) return void 0;
|
|
2164
|
+
const key = segmentForProp(target, prop);
|
|
2165
|
+
return parent.statuses.map((status) => {
|
|
2166
|
+
const descended = descendChains(status.chains, key);
|
|
2167
|
+
return {
|
|
2168
|
+
handle: status.handle,
|
|
2169
|
+
ignored: status.ignored || descended.ignored,
|
|
2170
|
+
unsafe: status.unsafe || descended.unsafe,
|
|
2171
|
+
chains: descended.chains
|
|
2172
|
+
};
|
|
2173
|
+
});
|
|
2174
|
+
};
|
|
2175
|
+
var statusesForFrame = (target, prop, initializing) => {
|
|
2176
|
+
if (typeof prop !== "string") return void 0;
|
|
2177
|
+
if (!initializing) return heldStatusesOf(target, prop);
|
|
2178
|
+
return inheritedStatusesOf(target, prop) ?? heldStatusesOf(target, prop);
|
|
2179
|
+
};
|
|
2180
|
+
var certifyAdmission = (value, path, unsafe = false) => {
|
|
2181
|
+
const decision = admissionDecision(value);
|
|
2182
|
+
if (decision.lane === "dangerous" && !unsafe) throw rejectionError(value, decision.kind, path);
|
|
2183
|
+
return decision.lane;
|
|
2184
|
+
};
|
|
2185
|
+
var peelSnapshotsAndReadProxies = (value) => {
|
|
2186
|
+
let current = value;
|
|
2187
|
+
while (typeof current === "object" && current !== null) {
|
|
2188
|
+
const untracked = getUntracked(current);
|
|
2189
|
+
const next = peelReadProxy(untracked ?? current);
|
|
2190
|
+
if (next === current) break;
|
|
2191
|
+
current = next;
|
|
2192
|
+
}
|
|
2193
|
+
return current;
|
|
2194
|
+
};
|
|
2195
|
+
var walkDataPaths = (value, path, visits, mode, chains, ignored, unsafe) => {
|
|
2196
|
+
const node = mode === "admission" ? rawTargetOf7(value) : value;
|
|
2197
|
+
if (visits.has(node)) return;
|
|
2198
|
+
visits.add(node);
|
|
2199
|
+
if (ignored) return;
|
|
2200
|
+
for (const entry of walkDataEntries(node)) {
|
|
2201
|
+
const childPath = [...path, entry.key];
|
|
2202
|
+
const descended = descendChains(chains, segmentForProp(node, entry.key));
|
|
2203
|
+
const childIgnored = descended.ignored;
|
|
2204
|
+
const childUnsafe = unsafe || descended.unsafe;
|
|
2205
|
+
const childChains = descended.chains;
|
|
2206
|
+
const child = entry.value;
|
|
2207
|
+
if (mode === "admission" && classifyValue(node) === "cleanClass" && !unsafe && typeof child === "function")
|
|
2208
|
+
throw rejectionError(node, "cleanClass", childPath);
|
|
2209
|
+
if (typeof child !== "object" || child === null) continue;
|
|
2210
|
+
if (!entry.writable) {
|
|
2211
|
+
if (mode === "admission" && !childIgnored && !childUnsafe && admissionLane(child) !== "untracked")
|
|
2212
|
+
throw nonWritablePropertyError(child, childPath);
|
|
2213
|
+
continue;
|
|
1115
2214
|
}
|
|
1116
|
-
|
|
1117
|
-
|
|
2215
|
+
if (childIgnored) continue;
|
|
2216
|
+
let childNode = child;
|
|
2217
|
+
if (proxyStateMap14.has(childNode)) {
|
|
2218
|
+
if (mode !== "admission") continue;
|
|
2219
|
+
childNode = rawTargetOf7(childNode);
|
|
2220
|
+
}
|
|
2221
|
+
if (mode === "admission") {
|
|
2222
|
+
if (childUnsafe) {
|
|
2223
|
+
walkDataPaths(childNode, childPath, visits, mode, childChains, childIgnored, childUnsafe);
|
|
2224
|
+
continue;
|
|
2225
|
+
}
|
|
2226
|
+
if (certifyAdmission(childNode, childPath, childUnsafe) === "tracked")
|
|
2227
|
+
walkDataPaths(childNode, childPath, visits, mode, childChains, childIgnored, childUnsafe);
|
|
2228
|
+
continue;
|
|
2229
|
+
}
|
|
2230
|
+
if (admissionLane(childNode) === "untracked") continue;
|
|
2231
|
+
walkDataPaths(childNode, childPath, visits, mode, childChains, childIgnored, childUnsafe);
|
|
1118
2232
|
}
|
|
1119
2233
|
};
|
|
2234
|
+
var assertSafeDataPaths = (value, path, visits, mode = "admission", chains = []) => {
|
|
2235
|
+
walkDataPaths(
|
|
2236
|
+
value,
|
|
2237
|
+
path,
|
|
2238
|
+
visits,
|
|
2239
|
+
mode,
|
|
2240
|
+
chains,
|
|
2241
|
+
chains.some((residual) => residual?.ignored === true),
|
|
2242
|
+
chains.some((residual) => residual?.unsafe === true)
|
|
2243
|
+
);
|
|
2244
|
+
};
|
|
2245
|
+
var certifyCurrentAssignment = (target, prop, resolved) => {
|
|
2246
|
+
if (typeof prop !== "string") return;
|
|
2247
|
+
const assignments = currentStatuses();
|
|
2248
|
+
if (assignments === void 0) return;
|
|
2249
|
+
const path = [prop];
|
|
2250
|
+
for (const assignment of assignments) {
|
|
2251
|
+
if (!assignment.handle.strict || assignment.ignored || assignment.unsafe) continue;
|
|
2252
|
+
if (typeof resolved === "function") {
|
|
2253
|
+
const parentKind = classifyValue(rawTargetOf7(target));
|
|
2254
|
+
if (parentKind !== "plain" && parentKind !== "plainArray")
|
|
2255
|
+
throw rejectionError(rawTargetOf7(target), parentKind, path);
|
|
2256
|
+
continue;
|
|
2257
|
+
}
|
|
2258
|
+
const decision = admissionDecision(resolved);
|
|
2259
|
+
if (decision.lane === "dangerous") throw rejectionError(resolved, decision.kind, path);
|
|
2260
|
+
if (decision.lane === "tracked")
|
|
2261
|
+
walkDataPaths(
|
|
2262
|
+
resolved,
|
|
2263
|
+
path,
|
|
2264
|
+
/* @__PURE__ */ new Set(),
|
|
2265
|
+
"admission",
|
|
2266
|
+
assignment.chains,
|
|
2267
|
+
assignment.ignored,
|
|
2268
|
+
assignment.unsafe
|
|
2269
|
+
);
|
|
2270
|
+
}
|
|
2271
|
+
};
|
|
2272
|
+
var writesThroughAccessor = (target, property) => {
|
|
2273
|
+
let holder = target;
|
|
2274
|
+
while (holder !== null) {
|
|
2275
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(holder, property);
|
|
2276
|
+
if (descriptor !== void 0) return !("value" in descriptor);
|
|
2277
|
+
holder = Reflect.getPrototypeOf(holder);
|
|
2278
|
+
}
|
|
2279
|
+
return false;
|
|
2280
|
+
};
|
|
2281
|
+
var refusesWrite = (target, property, value) => {
|
|
2282
|
+
if (Array.isArray(target)) {
|
|
2283
|
+
if (property === "length") {
|
|
2284
|
+
const coercible = value === null || typeof value !== "object" && typeof value !== "function";
|
|
2285
|
+
const newLength = coercible ? Number(value) : Number.NaN;
|
|
2286
|
+
if (Number.isInteger(newLength) && newLength >= 0 && newLength < target.length) {
|
|
2287
|
+
for (const key of Reflect.ownKeys(target)) {
|
|
2288
|
+
if (typeof key !== "string") continue;
|
|
2289
|
+
const index = Number(key);
|
|
2290
|
+
if (Number.isInteger(index) && index >= newLength && index < 2 ** 32 - 1 && String(index) === key && Reflect.getOwnPropertyDescriptor(target, key)?.configurable !== true)
|
|
2291
|
+
return true;
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
} else if (typeof property === "string") {
|
|
2295
|
+
const index = Number(property);
|
|
2296
|
+
if (Number.isInteger(index) && index >= 0 && index < 2 ** 32 - 1 && String(index) === property && index >= target.length && Reflect.getOwnPropertyDescriptor(target, "length")?.writable === false)
|
|
2297
|
+
return true;
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
let holder = target;
|
|
2301
|
+
while (holder !== null) {
|
|
2302
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(holder, property);
|
|
2303
|
+
if (descriptor !== void 0) {
|
|
2304
|
+
if ("value" in descriptor) {
|
|
2305
|
+
if (descriptor.writable !== true) return true;
|
|
2306
|
+
return holder !== target && !Object.isExtensible(target);
|
|
2307
|
+
}
|
|
2308
|
+
return descriptor.set === void 0;
|
|
2309
|
+
}
|
|
2310
|
+
holder = Reflect.getPrototypeOf(holder);
|
|
2311
|
+
}
|
|
2312
|
+
return !Object.isExtensible(target);
|
|
2313
|
+
};
|
|
2314
|
+
function canProxy2(value, parentTarget, unsafe = false) {
|
|
2315
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2316
|
+
if (admissionLane(value) === "tracked") return true;
|
|
2317
|
+
if (unsafe) return true;
|
|
2318
|
+
if (proxyStateMap14.has(value)) return true;
|
|
2319
|
+
const rootHandle = handleOwning(value);
|
|
2320
|
+
if (rootHandle !== void 0 && rawTargetOf7(rootHandle.proxy.root) === rawTargetOf7(value) && (!rootHandle.strict || rootHandle.declarations?.unsafe === true))
|
|
2321
|
+
return true;
|
|
2322
|
+
if (parentTarget === void 0) return false;
|
|
2323
|
+
const handles = handlesOf(parentTarget);
|
|
2324
|
+
return handles.length === 1 && handles[0]?.strict === false && admissionLane(value) === "dangerous";
|
|
2325
|
+
}
|
|
2326
|
+
var MissingMutationTrapError = class extends Error {
|
|
2327
|
+
constructor() {
|
|
2328
|
+
super("opshot: valtio default handler is missing a mutation trap");
|
|
2329
|
+
this.name = "MissingMutationTrapError";
|
|
2330
|
+
}
|
|
2331
|
+
};
|
|
2332
|
+
var canProxyCurrentAssignment = (value) => {
|
|
2333
|
+
const assignments = currentStatuses();
|
|
2334
|
+
if (assignments === void 0) return canProxy2(value, currentSetParentOf());
|
|
2335
|
+
const judging = assignments.filter((assignment) => !assignment.ignored);
|
|
2336
|
+
if (judging.length === 0) return false;
|
|
2337
|
+
return canProxy2(
|
|
2338
|
+
value,
|
|
2339
|
+
currentSetParentOf(),
|
|
2340
|
+
judging.every((assignment) => assignment.unsafe || !assignment.handle.strict)
|
|
2341
|
+
);
|
|
2342
|
+
};
|
|
2343
|
+
var truncatedOccupantsOf = (target, prop, next) => {
|
|
2344
|
+
if (!Array.isArray(target) || prop !== "length") return void 0;
|
|
2345
|
+
const coercible = next === null || typeof next !== "object" && typeof next !== "function";
|
|
2346
|
+
const newLength = coercible ? Number(next) : Number.NaN;
|
|
2347
|
+
if (!Number.isInteger(newLength) || newLength < 0 || newLength >= target.length) return void 0;
|
|
2348
|
+
const truncated = new Array();
|
|
2349
|
+
for (let index = newLength; index < target.length; index++) {
|
|
2350
|
+
const occupant = Reflect.get(target, index);
|
|
2351
|
+
if (typeof occupant === "object" && occupant !== null) truncated.push({ index, occupant });
|
|
2352
|
+
}
|
|
2353
|
+
return truncated;
|
|
2354
|
+
};
|
|
2355
|
+
var commitSetInEdges = (target, prop, previous, next, truncated) => {
|
|
2356
|
+
const handles = handlesOf(target);
|
|
2357
|
+
if (handles.length === 0) return;
|
|
2358
|
+
if (truncated !== void 0) {
|
|
2359
|
+
for (const { index, occupant } of truncated) {
|
|
2360
|
+
for (const handle of handles) removeInEdge(handle, occupant, target, index);
|
|
2361
|
+
}
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
if (typeof prop !== "string") return;
|
|
2365
|
+
const key = segmentForProp(target, prop);
|
|
2366
|
+
const previousObject = typeof previous === "object" && previous !== null ? previous : void 0;
|
|
2367
|
+
const nextObject = typeof next === "object" && next !== null && admissionLane(next) !== "untracked" ? next : void 0;
|
|
2368
|
+
for (const handle of handles) {
|
|
2369
|
+
if (isIgnoredFrontier(handle, target, key)) {
|
|
2370
|
+
if (previousObject !== void 0) removeInEdge(handle, previousObject, target, key);
|
|
2371
|
+
continue;
|
|
2372
|
+
}
|
|
2373
|
+
if (previousObject !== void 0) removeInEdge(handle, previousObject, target, key);
|
|
2374
|
+
if (nextObject === void 0) continue;
|
|
2375
|
+
const rawNext = rawTargetOf7(nextObject);
|
|
2376
|
+
const wasOccupied = rawNext === rawTargetOf7(handle.proxy.root) || (handle.nodes.get(rawNext)?.edges.length ?? 0) > 0;
|
|
2377
|
+
addInEdge(handle, nextObject, target, key);
|
|
2378
|
+
if (wasOccupied) continue;
|
|
2379
|
+
const slot = slotStatusOf(handle, target, key);
|
|
2380
|
+
seedInEdgesUnder(handle, nextObject, slot.chains);
|
|
2381
|
+
}
|
|
2382
|
+
};
|
|
2383
|
+
var commitDeleteInEdges = (target, prop, previous) => {
|
|
2384
|
+
if (typeof prop !== "string") return;
|
|
2385
|
+
if (typeof previous !== "object" || previous === null) return;
|
|
2386
|
+
const key = segmentForProp(target, prop);
|
|
2387
|
+
for (const handle of handlesOf(target)) removeInEdge(handle, previous, target, key);
|
|
2388
|
+
};
|
|
1120
2389
|
var installed = false;
|
|
1121
2390
|
function installBoundary() {
|
|
1122
2391
|
if (installed) return;
|
|
1123
2392
|
installed = true;
|
|
1124
|
-
unstable_replaceInternalFunction("canProxy", () => (value) =>
|
|
1125
|
-
if (typeof value !== "object" || value === null) return false;
|
|
1126
|
-
const lane = admissionLane(value);
|
|
1127
|
-
if (lane !== "reject") return lane === "track";
|
|
1128
|
-
const kind = classifyValue(value);
|
|
1129
|
-
if (kind === "plain" || kind === "plainArray") return true;
|
|
1130
|
-
throw rejectionError(value, kind);
|
|
1131
|
-
});
|
|
2393
|
+
unstable_replaceInternalFunction("canProxy", () => (value) => canProxyCurrentAssignment(value));
|
|
1132
2394
|
unstable_replaceInternalFunction("createSnapshot", () => createSnapshotPreservingAccessors);
|
|
1133
2395
|
unstable_replaceInternalFunction(
|
|
1134
2396
|
"createHandler",
|
|
1135
2397
|
(createHandler2) => (isInitializing, addPropListener, removePropListener, notifyUpdate) => {
|
|
1136
|
-
let setDepth = 0;
|
|
1137
2398
|
const handler = createHandler2(isInitializing, addPropListener, removePropListener, notifyUpdate);
|
|
1138
2399
|
const defaultDelete = handler.deleteProperty;
|
|
1139
2400
|
const defaultSet = handler.set;
|
|
1140
|
-
if (!defaultDelete || !defaultSet)
|
|
1141
|
-
throw new Error("opshot: valtio default handler is missing a mutation trap");
|
|
2401
|
+
if (!defaultDelete || !defaultSet) throw new MissingMutationTrapError();
|
|
1142
2402
|
return {
|
|
1143
2403
|
...handler,
|
|
1144
|
-
deleteProperty(target, prop) {
|
|
1145
|
-
const rootGraphs = getRootGraphs(target);
|
|
1146
|
-
const previousChild = rootGraphs.length > 0 ? getEnumerableDataChild(target, prop) : void 0;
|
|
1147
|
-
const hadOwn = Object.hasOwn(target, prop);
|
|
1148
|
-
const deleted = defaultDelete(target, prop);
|
|
1149
|
-
if (deleted && hadOwn && previousChild && !Object.hasOwn(target, prop))
|
|
1150
|
-
for (const graph of rootGraphs) recomputeRootGraph(graph);
|
|
1151
|
-
return deleted;
|
|
1152
|
-
},
|
|
1153
2404
|
set(target, prop, value, receiver) {
|
|
1154
2405
|
const assigned = value;
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
if (prototypeDescriptor?.enumerable) throw reservedDataPathError(["constructor", "prototype"]);
|
|
1161
|
-
}
|
|
1162
|
-
assertSafeDataPaths(assigned, typeof prop === "string" ? [prop] : []);
|
|
1163
|
-
if (typeof assigned === "object" && assigned !== null) {
|
|
1164
|
-
const untracked = getUntracked(assigned) ?? assigned;
|
|
1165
|
-
if (getRegisteredTarget(untracked) !== void 0) throw snapshotDonationError(prop);
|
|
1166
|
-
}
|
|
1167
|
-
const rootGraphs = getRootGraphs(target);
|
|
1168
|
-
const previousChild = rootGraphs.length > 0 ? getEnumerableDataChild(target, prop) : void 0;
|
|
1169
|
-
const previousLength = rootGraphs.length > 0 && Array.isArray(target) && prop === "length" ? Reflect.get(target, "length") : void 0;
|
|
1170
|
-
setDepth += 1;
|
|
2406
|
+
const resolved = peelSnapshotsAndReadProxies(assigned);
|
|
2407
|
+
const truncated = truncatedOccupantsOf(target, prop, resolved);
|
|
2408
|
+
const previous = typeof prop === "string" ? Reflect.get(target, prop) : void 0;
|
|
2409
|
+
const initializing = isInitializing();
|
|
2410
|
+
setFrameStack.push({ target, prop, statuses: statusesForFrame(target, prop, initializing) });
|
|
1171
2411
|
try {
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
2412
|
+
if (typeof resolved === "object" && resolved !== null) {
|
|
2413
|
+
if (getRegisteredTarget(resolved) !== void 0) throw snapshotDonationError(prop);
|
|
2414
|
+
if (refusesWrite(target, prop, resolved)) return false;
|
|
2415
|
+
if (!initializing && !writesThroughAccessor(target, prop))
|
|
2416
|
+
certifyCurrentAssignment(target, prop, resolved);
|
|
2417
|
+
const alreadyTracked = proxyStateMap14.has(resolved) || proxyCache3.has(resolved);
|
|
2418
|
+
const instrumented = !alreadyTracked && canProxyCurrentAssignment(resolved) ? proxy(resolved) : resolved;
|
|
2419
|
+
const result2 = defaultSet(target, prop, instrumented, receiver);
|
|
2420
|
+
if (result2 && !initializing) commitSetInEdges(target, prop, previous, instrumented, truncated);
|
|
2421
|
+
return result2;
|
|
2422
|
+
}
|
|
2423
|
+
if (refusesWrite(target, prop, resolved)) return false;
|
|
2424
|
+
if (!initializing && typeof resolved === "function" && !writesThroughAccessor(target, prop))
|
|
2425
|
+
certifyCurrentAssignment(target, prop, resolved);
|
|
2426
|
+
const result = defaultSet(target, prop, resolved, receiver);
|
|
2427
|
+
if (result && !initializing) commitSetInEdges(target, prop, previous, resolved, truncated);
|
|
2428
|
+
return result;
|
|
1178
2429
|
} finally {
|
|
1179
|
-
|
|
2430
|
+
setFrameStack.pop();
|
|
1180
2431
|
}
|
|
1181
2432
|
},
|
|
2433
|
+
deleteProperty(target, prop) {
|
|
2434
|
+
const previous = typeof prop === "string" ? Reflect.get(target, prop) : void 0;
|
|
2435
|
+
const result = defaultDelete(target, prop);
|
|
2436
|
+
if (result && !isInitializing()) commitDeleteInEdges(target, prop, previous);
|
|
2437
|
+
return result;
|
|
2438
|
+
},
|
|
1182
2439
|
defineProperty(target, prop, descriptor) {
|
|
1183
|
-
|
|
1184
|
-
throw new Error(
|
|
1185
|
-
"opshot: defineProperty is not supported on tracked state; define properties in the createMutableState input"
|
|
1186
|
-
);
|
|
2440
|
+
return Reflect.defineProperty(target, prop, descriptor);
|
|
1187
2441
|
},
|
|
1188
|
-
setPrototypeOf() {
|
|
1189
|
-
|
|
2442
|
+
setPrototypeOf(target, proto) {
|
|
2443
|
+
return Reflect.setPrototypeOf(target, proto);
|
|
2444
|
+
},
|
|
2445
|
+
preventExtensions(target) {
|
|
2446
|
+
return Reflect.preventExtensions(target);
|
|
1190
2447
|
}
|
|
1191
2448
|
};
|
|
1192
2449
|
}
|
|
@@ -1194,180 +2451,299 @@ function installBoundary() {
|
|
|
1194
2451
|
}
|
|
1195
2452
|
|
|
1196
2453
|
// src/createMutableState.ts
|
|
1197
|
-
|
|
2454
|
+
var isIgnoredWrapper = (value) => typeof value === "object" && value !== null && Object.hasOwn(value, ignoreMarker);
|
|
2455
|
+
var isUnsafeWrapper = (value) => typeof value === "object" && value !== null && Object.hasOwn(value, unsafeMarker);
|
|
2456
|
+
var consumeMarkerTree = (node, path, walk) => {
|
|
2457
|
+
if (Object.isFrozen(node)) return;
|
|
2458
|
+
const firstPath = walk.firstOccupancyByNode.get(node);
|
|
2459
|
+
if (firstPath !== void 0) {
|
|
2460
|
+
const laterOccupancies = walk.laterOccupanciesByNode.get(node);
|
|
2461
|
+
if (laterOccupancies === void 0) walk.laterOccupanciesByNode.set(node, [path]);
|
|
2462
|
+
else laterOccupancies.push(path);
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2465
|
+
walk.firstOccupancyByNode.set(node, path);
|
|
2466
|
+
for (const entry of walkDataEntries(node)) {
|
|
2467
|
+
const childPath = appendOperationPath(path, segmentFor(node, entry.key));
|
|
2468
|
+
const next = unwrapValue(entry.value, childPath, walk);
|
|
2469
|
+
if (!Object.is(next, entry.value) && entry.writable) Reflect.set(node, entry.key, next);
|
|
2470
|
+
}
|
|
2471
|
+
};
|
|
2472
|
+
var unwrapValue = (value, path, walk) => {
|
|
2473
|
+
let current = value;
|
|
2474
|
+
while (isIgnoredWrapper(current) || isUnsafeWrapper(current)) {
|
|
2475
|
+
const node = declarationAtPath(walk.trie, path);
|
|
2476
|
+
walk.marked = true;
|
|
2477
|
+
if (isIgnoredWrapper(current)) {
|
|
2478
|
+
node.ignored = true;
|
|
2479
|
+
current = current[ignoreMarker];
|
|
2480
|
+
} else {
|
|
2481
|
+
node.unsafe = true;
|
|
2482
|
+
current = current[unsafeMarker];
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
if (typeof current === "object" && current !== null) consumeMarkerTree(current, path, walk);
|
|
2486
|
+
return current;
|
|
2487
|
+
};
|
|
2488
|
+
var trieAtPath = (trie, path) => {
|
|
2489
|
+
let current = trie;
|
|
2490
|
+
for (const segment of path) {
|
|
2491
|
+
current = current.children.get(String(segment));
|
|
2492
|
+
if (current === void 0) return void 0;
|
|
2493
|
+
}
|
|
2494
|
+
return current;
|
|
2495
|
+
};
|
|
2496
|
+
var applyCopiedMarkerPaths = (walk) => {
|
|
2497
|
+
for (const [node, firstPath] of walk.firstOccupancyByNode) {
|
|
2498
|
+
const laterOccupancies = walk.laterOccupanciesByNode.get(node);
|
|
2499
|
+
if (laterOccupancies === void 0) continue;
|
|
2500
|
+
const source = trieAtPath(walk.trie, firstPath);
|
|
2501
|
+
if (source === void 0 || source.children.size === 0) continue;
|
|
2502
|
+
for (const laterPath of laterOccupancies) {
|
|
2503
|
+
graftDeclarationChildren(source, declarationAtPath(walk.trie, laterPath));
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
};
|
|
2507
|
+
function createMutableState(properties, options) {
|
|
1198
2508
|
installBoundary();
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
2509
|
+
const trie = createDeclarationTrie();
|
|
2510
|
+
let marked = false;
|
|
2511
|
+
let root = properties;
|
|
2512
|
+
while (isIgnoredWrapper(root) || isUnsafeWrapper(root)) {
|
|
2513
|
+
if (isIgnoredWrapper(root)) {
|
|
2514
|
+
trie.ignored = true;
|
|
2515
|
+
marked = true;
|
|
2516
|
+
root = root[ignoreMarker];
|
|
2517
|
+
} else {
|
|
2518
|
+
trie.unsafe = true;
|
|
2519
|
+
marked = true;
|
|
2520
|
+
root = root[unsafeMarker];
|
|
2521
|
+
}
|
|
1206
2522
|
}
|
|
1207
|
-
return
|
|
2523
|
+
if (trie.ignored) return root;
|
|
2524
|
+
if (typeof root !== "object" || root === null) return root;
|
|
2525
|
+
if (Object.isFrozen(root)) return root;
|
|
2526
|
+
if (isState(root)) {
|
|
2527
|
+
const peeled = peelReadProxy(root);
|
|
2528
|
+
if (typeof peeled === "object" && peeled !== null) return peeled;
|
|
2529
|
+
}
|
|
2530
|
+
const decision = admissionDecision(root);
|
|
2531
|
+
const strict = options?.strict !== false;
|
|
2532
|
+
if (decision.lane === "leaf") return root;
|
|
2533
|
+
const base = Object.create(Reflect.getPrototypeOf(root));
|
|
2534
|
+
Object.defineProperties(base, Object.getOwnPropertyDescriptors(root));
|
|
2535
|
+
const walk = {
|
|
2536
|
+
trie,
|
|
2537
|
+
marked,
|
|
2538
|
+
firstOccupancyByNode: /* @__PURE__ */ new Map(),
|
|
2539
|
+
laterOccupanciesByNode: /* @__PURE__ */ new Map()
|
|
2540
|
+
};
|
|
2541
|
+
consumeMarkerTree(base, createOperationPath([]), walk);
|
|
2542
|
+
applyCopiedMarkerPaths(walk);
|
|
2543
|
+
const declarations = walk.marked || hasDeclarations(trie) ? trie : void 0;
|
|
2544
|
+
if (decision.lane === "dangerous" && strict && declarations?.unsafe !== true) {
|
|
2545
|
+
throw rejectionError(base, decision.kind);
|
|
2546
|
+
}
|
|
2547
|
+
assertSafeDataPaths(base, [], /* @__PURE__ */ new Set(), strict ? "admission" : "rootsOnly", [declarations]);
|
|
2548
|
+
const handle = {
|
|
2549
|
+
proxy: { root: base },
|
|
2550
|
+
lastSnapshot: base,
|
|
2551
|
+
hasPendingWrites: false,
|
|
2552
|
+
isFlushScheduled: false,
|
|
2553
|
+
isFlushHeld: false,
|
|
2554
|
+
flushGeneration: 0,
|
|
2555
|
+
subscribers: /* @__PURE__ */ new Map(),
|
|
2556
|
+
groups: options?.group !== void 0 ? getGroupChain(options.group) : void 0,
|
|
2557
|
+
emitOn: options?.emitOn,
|
|
2558
|
+
strict,
|
|
2559
|
+
declarations,
|
|
2560
|
+
nodes: /* @__PURE__ */ new WeakMap(),
|
|
2561
|
+
byId: /* @__PURE__ */ new Map(),
|
|
2562
|
+
nextInternId: 1,
|
|
2563
|
+
stamp: {},
|
|
2564
|
+
version: 0,
|
|
2565
|
+
replaying: false
|
|
2566
|
+
};
|
|
2567
|
+
registerHandle(base, handle);
|
|
2568
|
+
handle.nodes.set(base, { edges: [], id: 0 });
|
|
2569
|
+
handle.byId.set(0, base);
|
|
2570
|
+
const instrumented = proxy({ root: base });
|
|
2571
|
+
handle.proxy = instrumented;
|
|
2572
|
+
handle.lastSnapshot = requireObjectSnapshot(snapshot(instrumented.root));
|
|
2573
|
+
seedInEdges(handle);
|
|
2574
|
+
seedOccupancies(handle);
|
|
2575
|
+
armWatch(handle);
|
|
2576
|
+
return instrumented.root;
|
|
1208
2577
|
}
|
|
1209
2578
|
|
|
1210
2579
|
// src/createGroup.ts
|
|
1211
|
-
var
|
|
2580
|
+
var UnknownGroupError = class extends Error {
|
|
2581
|
+
constructor() {
|
|
2582
|
+
super("opshot: unknown group");
|
|
2583
|
+
this.name = "UnknownGroupError";
|
|
2584
|
+
}
|
|
2585
|
+
};
|
|
2586
|
+
var groupChainByGroup = /* @__PURE__ */ new WeakMap();
|
|
1212
2587
|
function isGroup(value) {
|
|
1213
|
-
return typeof value === "object" && value !== null &&
|
|
2588
|
+
return typeof value === "object" && value !== null && groupChainByGroup.has(value);
|
|
1214
2589
|
}
|
|
1215
2590
|
function getGroupListeners(group) {
|
|
1216
|
-
const
|
|
1217
|
-
|
|
2591
|
+
const chain = groupChainByGroup.get(group);
|
|
2592
|
+
const listeners = chain?.at(-1);
|
|
2593
|
+
if (listeners === void 0) throw new UnknownGroupError();
|
|
1218
2594
|
return listeners;
|
|
1219
2595
|
}
|
|
1220
|
-
function
|
|
2596
|
+
function getGroupChain(group) {
|
|
2597
|
+
const chain = groupChainByGroup.get(group);
|
|
2598
|
+
if (chain === void 0) throw new UnknownGroupError();
|
|
2599
|
+
return chain;
|
|
2600
|
+
}
|
|
2601
|
+
function createGroup(parent) {
|
|
2602
|
+
if (parent !== void 0 && !isGroup(parent)) {
|
|
2603
|
+
throw new Error("opshot: parent is not a group");
|
|
2604
|
+
}
|
|
1221
2605
|
const listeners = /* @__PURE__ */ new Map();
|
|
1222
2606
|
const group = {
|
|
1223
|
-
createMutableState(properties) {
|
|
1224
|
-
return createMutableState(properties, group);
|
|
2607
|
+
createMutableState(properties, options) {
|
|
2608
|
+
return createMutableState(properties, { ...options, group });
|
|
1225
2609
|
}
|
|
1226
2610
|
};
|
|
1227
|
-
|
|
2611
|
+
const chain = parent === void 0 ? [listeners] : [...getGroupChain(parent), listeners];
|
|
2612
|
+
groupChainByGroup.set(group, chain);
|
|
1228
2613
|
return group;
|
|
1229
2614
|
}
|
|
1230
2615
|
|
|
1231
2616
|
// src/emit/emitterListeners.ts
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
const
|
|
1235
|
-
if (
|
|
1236
|
-
|
|
2617
|
+
var bindings = /* @__PURE__ */ new WeakMap();
|
|
2618
|
+
var dropListenerChannel = (byListener, listener, channelId, unsubscribe) => {
|
|
2619
|
+
const channels = byListener.get(listener);
|
|
2620
|
+
if (channels?.has(channelId) !== true) {
|
|
2621
|
+
bindings.delete(unsubscribe);
|
|
2622
|
+
return;
|
|
1237
2623
|
}
|
|
1238
|
-
|
|
2624
|
+
channels.delete(channelId);
|
|
2625
|
+
if (channels.size === 0) byListener.delete(listener);
|
|
2626
|
+
bindings.delete(unsubscribe);
|
|
2627
|
+
};
|
|
2628
|
+
function addStateListener(state, listener, channelId, deliver) {
|
|
2629
|
+
const handle = requireHandle(state, "opshot: subscribe requires a state");
|
|
2630
|
+
let byChannel = handle.subscribers.get(listener);
|
|
1239
2631
|
if (byChannel === void 0) {
|
|
1240
2632
|
byChannel = /* @__PURE__ */ new Map();
|
|
1241
|
-
|
|
2633
|
+
handle.subscribers.set(listener, byChannel);
|
|
1242
2634
|
}
|
|
1243
|
-
byChannel.set(channelId,
|
|
1244
|
-
|
|
1245
|
-
const
|
|
1246
|
-
if (
|
|
1247
|
-
|
|
1248
|
-
channels.delete(channelId);
|
|
1249
|
-
if (channels.size === 0) record.listeners.delete(listener);
|
|
1250
|
-
if (record.groupListeners === void 0 && record.listeners.size === 0) {
|
|
1251
|
-
disarmWatchdog(record);
|
|
1252
|
-
deleteEmitter(target);
|
|
1253
|
-
}
|
|
2635
|
+
byChannel.set(channelId, deliver);
|
|
2636
|
+
const unsubscribe = () => {
|
|
2637
|
+
const held = bindings.get(unsubscribe);
|
|
2638
|
+
if (held === void 0) return;
|
|
2639
|
+
dropListenerChannel(held.handle.subscribers, held.listener, held.channelId, unsubscribe);
|
|
1254
2640
|
};
|
|
2641
|
+
bindings.set(unsubscribe, { handle, listener, channelId });
|
|
2642
|
+
return unsubscribe;
|
|
1255
2643
|
}
|
|
1256
|
-
function addGroupListener(groupListeners, listener, channelId,
|
|
2644
|
+
function addGroupListener(groupListeners, listener, channelId, deliver) {
|
|
1257
2645
|
let byChannel = groupListeners.get(listener);
|
|
1258
2646
|
if (byChannel === void 0) {
|
|
1259
2647
|
byChannel = /* @__PURE__ */ new Map();
|
|
1260
2648
|
groupListeners.set(listener, byChannel);
|
|
1261
2649
|
}
|
|
1262
|
-
byChannel.set(channelId,
|
|
1263
|
-
|
|
1264
|
-
const
|
|
1265
|
-
if (
|
|
1266
|
-
|
|
1267
|
-
if (channels.size === 0) groupListeners.delete(listener);
|
|
2650
|
+
byChannel.set(channelId, deliver);
|
|
2651
|
+
const unsubscribe = () => {
|
|
2652
|
+
const held = bindings.get(unsubscribe);
|
|
2653
|
+
if (held === void 0) return;
|
|
2654
|
+
dropListenerChannel(held.listeners, held.listener, held.channelId, unsubscribe);
|
|
1268
2655
|
};
|
|
2656
|
+
bindings.set(unsubscribe, { listeners: groupListeners, listener, channelId });
|
|
2657
|
+
return unsubscribe;
|
|
1269
2658
|
}
|
|
1270
2659
|
|
|
1271
|
-
// src/
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
2660
|
+
// src/emit/resolveWriteProxy.ts
|
|
2661
|
+
var { proxyStateMap: proxyStateMap15 } = unstable_getInternalStates();
|
|
2662
|
+
var ExpectedStateObjectError = class extends Error {
|
|
2663
|
+
constructor() {
|
|
2664
|
+
super("opshot: expected a state object");
|
|
2665
|
+
this.name = "ExpectedStateObjectError";
|
|
1277
2666
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
2667
|
+
};
|
|
2668
|
+
var isObjectLike4 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
2669
|
+
function resolveWriteProxy(state) {
|
|
2670
|
+
let current = state;
|
|
2671
|
+
while (isObjectLike4(current)) {
|
|
2672
|
+
if (proxyStateMap15.has(current)) return current;
|
|
2673
|
+
const peeled = peelIdentityLayer(current);
|
|
2674
|
+
if (peeled === void 0) break;
|
|
2675
|
+
current = peeled;
|
|
1285
2676
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
record.lastReported = after;
|
|
1289
|
-
if (before === after) return;
|
|
1290
|
-
if (!hasListeners(record)) return;
|
|
1291
|
-
const ops = diffSnapshots(requireObjectSnapshot(before), requireObjectSnapshot(after));
|
|
1292
|
-
if (ops.length === 0) return;
|
|
1293
|
-
deliver(record, ops, meta);
|
|
2677
|
+
if (!isObjectLike4(current) || !proxyStateMap15.has(current)) throw new ExpectedStateObjectError();
|
|
2678
|
+
return current;
|
|
1294
2679
|
}
|
|
1295
2680
|
|
|
1296
|
-
// src/
|
|
1297
|
-
var
|
|
1298
|
-
var
|
|
1299
|
-
var
|
|
1300
|
-
|
|
1301
|
-
if (typeof operation === "object" && operation !== null && "do" in operation) {
|
|
1302
|
-
throw new Error("opshot: applyOps applies operation halves; pass op.do or op.undo.");
|
|
1303
|
-
}
|
|
1304
|
-
if (!isOperation(operation)) {
|
|
1305
|
-
throw new Error(
|
|
1306
|
-
"opshot: this op is a copy (spread, JSON, or structuredClone) and has lost its value. Apply the op objects the listener delivered; never copy them."
|
|
1307
|
-
);
|
|
1308
|
-
}
|
|
2681
|
+
// src/transact/nest.ts
|
|
2682
|
+
var transactionOpen = false;
|
|
2683
|
+
var isTransactionOpen = () => transactionOpen;
|
|
2684
|
+
var openTransaction = () => {
|
|
2685
|
+
transactionOpen = true;
|
|
1309
2686
|
};
|
|
1310
|
-
var
|
|
1311
|
-
|
|
1312
|
-
if (isObjectLike4(current) && isObjectLike4(expected)) return sameIdentity(current, expected);
|
|
1313
|
-
return Object.is(current, expected);
|
|
2687
|
+
var closeTransaction = () => {
|
|
2688
|
+
transactionOpen = false;
|
|
1314
2689
|
};
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
2690
|
+
|
|
2691
|
+
// src/ops/applyMutations.ts
|
|
2692
|
+
var ReplayReattachError = class extends Error {
|
|
2693
|
+
constructor(message) {
|
|
2694
|
+
super(message);
|
|
2695
|
+
this.name = "ReplayReattachError";
|
|
1321
2696
|
}
|
|
1322
2697
|
};
|
|
1323
|
-
var
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
var restoreRecordedContent = (attached, recorded, restored) => {
|
|
2698
|
+
var unresolvedError = (path) => new Error(`opshot: ${formatOperationPath(path)} does not resolve to a supported operation address`);
|
|
2699
|
+
var linkError = (path, ref, reason) => new Error(`opshot: link at ${formatOperationPath(path)} with ref ${String(ref)} ${reason}`);
|
|
2700
|
+
var isWritableDataDescriptor = (descriptor) => descriptor !== void 0 && "value" in descriptor && descriptor.writable === true;
|
|
2701
|
+
var restoreRecordedContent = (attached, recorded, restored, identity) => {
|
|
1327
2702
|
if (restored.has(recorded)) return;
|
|
1328
2703
|
restored.add(recorded);
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
for (const key of orderedKeys) {
|
|
1332
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(recorded, key);
|
|
2704
|
+
for (const entry of walkDataEntries(recorded, true)) {
|
|
2705
|
+
const key = entry.key;
|
|
1333
2706
|
const attachedDescriptor = Reflect.getOwnPropertyDescriptor(attached, key);
|
|
1334
|
-
if (
|
|
1335
|
-
const value =
|
|
1336
|
-
if (
|
|
2707
|
+
if (attachedDescriptor !== void 0 && !isWritableDataDescriptor(attachedDescriptor)) continue;
|
|
2708
|
+
const value = entry.value;
|
|
2709
|
+
if (identity === "restore" && isObjectLike3(value)) {
|
|
1337
2710
|
const target = getRegisteredTarget(value);
|
|
1338
2711
|
if (target !== void 0) {
|
|
1339
|
-
|
|
2712
|
+
const present = attachedDescriptor?.value;
|
|
2713
|
+
if (!isObjectLike3(present) || resolveIdentity(present) !== resolveIdentity(target)) {
|
|
2714
|
+
Reflect.set(attached, key, target);
|
|
2715
|
+
}
|
|
1340
2716
|
const child = Reflect.get(attached, key);
|
|
1341
|
-
if (!
|
|
1342
|
-
restoreRecordedContent(child, value, restored);
|
|
2717
|
+
if (!isObjectLike3(child)) throw new ReplayReattachError(`opshot: replay could not reattach ${key}`);
|
|
2718
|
+
restoreRecordedContent(child, value, restored, identity);
|
|
1343
2719
|
continue;
|
|
1344
2720
|
}
|
|
1345
2721
|
}
|
|
1346
|
-
|
|
2722
|
+
Reflect.set(attached, key, value);
|
|
1347
2723
|
}
|
|
1348
|
-
for (const
|
|
1349
|
-
if (
|
|
1350
|
-
|
|
1351
|
-
|
|
2724
|
+
for (const entry of walkDataEntries(attached)) {
|
|
2725
|
+
if (!entry.writable) continue;
|
|
2726
|
+
if (Object.hasOwn(recorded, entry.key)) continue;
|
|
2727
|
+
Reflect.deleteProperty(attached, entry.key);
|
|
1352
2728
|
}
|
|
1353
2729
|
};
|
|
1354
|
-
var getValuePayload = (operation) => {
|
|
1355
|
-
const original = getValueOriginal(operation);
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
}
|
|
1361
|
-
return { recorded: operation.value, fallback: operation.value };
|
|
2730
|
+
var getValuePayload = (operation, identity) => {
|
|
2731
|
+
const original = identity === "restore" ? getValueOriginal(operation) ?? operation.value : operation.value;
|
|
2732
|
+
return {
|
|
2733
|
+
recorded: original,
|
|
2734
|
+
fallback: isObjectLike3(original) ? cloneValue(original, /* @__PURE__ */ new WeakMap(), operation.path) : original
|
|
2735
|
+
};
|
|
1362
2736
|
};
|
|
1363
|
-
var restoreValue = (payload, attach, readAttached) => {
|
|
1364
|
-
if (
|
|
2737
|
+
var restoreValue = (payload, attach, readAttached, identity) => {
|
|
2738
|
+
if (identity === "restore" && isObjectLike3(payload.recorded)) {
|
|
1365
2739
|
const target = getRegisteredTarget(payload.recorded);
|
|
1366
2740
|
if (target !== void 0) {
|
|
1367
2741
|
attach(target);
|
|
1368
2742
|
const attached = readAttached();
|
|
1369
|
-
if (!
|
|
1370
|
-
|
|
2743
|
+
if (!isObjectLike3(attached)) {
|
|
2744
|
+
throw new ReplayReattachError("opshot: replay could not read a reattached target");
|
|
2745
|
+
}
|
|
2746
|
+
restoreRecordedContent(attached, payload.recorded, /* @__PURE__ */ new WeakSet(), identity);
|
|
1371
2747
|
return;
|
|
1372
2748
|
}
|
|
1373
2749
|
}
|
|
@@ -1382,14 +2758,9 @@ var getInheritedDescriptor = (target, key) => {
|
|
|
1382
2758
|
}
|
|
1383
2759
|
return void 0;
|
|
1384
2760
|
};
|
|
1385
|
-
var isCanonicalArrayIndex2 = (segment) => Number.isInteger(segment) && typeof segment === "number" && segment >= 0 && segment < 4294967295;
|
|
1386
|
-
var isCanonicalArrayIndexString = (segment) => {
|
|
1387
|
-
const index = Number(segment);
|
|
1388
|
-
return Number.isInteger(index) && index >= 0 && index < 4294967295 && String(index) === segment;
|
|
1389
|
-
};
|
|
1390
2761
|
var requirePlainSegment = (parent, segment, path) => {
|
|
1391
2762
|
if (Array.isArray(parent)) {
|
|
1392
|
-
if (
|
|
2763
|
+
if (isCanonicalArrayIndex(segment)) return segment;
|
|
1393
2764
|
if (typeof segment === "string" && !isCanonicalArrayIndexString(segment)) return segment;
|
|
1394
2765
|
throw unresolvedError(path);
|
|
1395
2766
|
}
|
|
@@ -1404,152 +2775,365 @@ var requirePlainProperty = (parent, segment, path) => {
|
|
|
1404
2775
|
return Reflect.get(parent, key);
|
|
1405
2776
|
};
|
|
1406
2777
|
var resolveTraversalSegment = (parent, segment, path) => {
|
|
1407
|
-
if (!
|
|
2778
|
+
if (!isObjectLike3(parent)) throw unresolvedError(path);
|
|
1408
2779
|
return requirePlainProperty(parent, segment, path);
|
|
1409
2780
|
};
|
|
1410
2781
|
var resolveTerminal = (root, path) => {
|
|
1411
|
-
|
|
1412
|
-
if (path.length === 0) throw new Error("opshot: root operations are not supported");
|
|
2782
|
+
if (path.length === 0) throw unresolvedError(path);
|
|
1413
2783
|
let parent = root;
|
|
1414
2784
|
for (let index = 0; index < path.length - 1; index++) parent = resolveTraversalSegment(parent, path[index], path);
|
|
1415
|
-
if (!
|
|
2785
|
+
if (!isObjectLike3(parent)) throw unresolvedError(path);
|
|
1416
2786
|
return { parent, segment: path[path.length - 1] };
|
|
1417
2787
|
};
|
|
1418
|
-
var
|
|
2788
|
+
var applyLink = (root, operation, handle) => {
|
|
2789
|
+
const path = operation.path;
|
|
2790
|
+
const ref = operation.ref;
|
|
2791
|
+
if (path.length === 0) throw linkError(path, ref, "does not resolve to a supported operation address");
|
|
2792
|
+
const resolved = nodeOfInternedId(handle, ref, handle.transactionCapture);
|
|
2793
|
+
if (resolved === void 0) throw linkError(path, ref, "does not resolve");
|
|
2794
|
+
const terminal = resolveTerminal(root, path);
|
|
2795
|
+
if (Array.isArray(terminal.parent) && terminal.segment === "length") {
|
|
2796
|
+
throw linkError(path, ref, "cannot address array length");
|
|
2797
|
+
}
|
|
2798
|
+
const key = requirePlainSegment(terminal.parent, terminal.segment, path);
|
|
2799
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(terminal.parent, key);
|
|
2800
|
+
const present = descriptor !== void 0 && descriptor.enumerable && "value" in descriptor;
|
|
2801
|
+
if (descriptor !== void 0 && !present) throw unresolvedError(path);
|
|
2802
|
+
if (!present) {
|
|
2803
|
+
const inheritedDescriptor = getInheritedDescriptor(terminal.parent, key);
|
|
2804
|
+
if (inheritedDescriptor && !("value" in inheritedDescriptor)) {
|
|
2805
|
+
throw new Error(`opshot: ${formatOperationPath(path)} resolves to an inherited accessor`);
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
Reflect.set(terminal.parent, key, resolved);
|
|
2809
|
+
};
|
|
2810
|
+
var applyPlain = (parent, segment, operation, identity, handle) => {
|
|
1419
2811
|
const path = operation.path;
|
|
1420
2812
|
if (Array.isArray(parent) && segment === "length") {
|
|
1421
|
-
if (operation.
|
|
2813
|
+
if (operation.verb !== "assign" || typeof operation.value !== "number" || !Number.isInteger(operation.value) || operation.value < 0 || operation.value > MAX_ARRAY_LENGTH) {
|
|
1422
2814
|
throw unresolvedError(path);
|
|
1423
2815
|
}
|
|
1424
|
-
|
|
2816
|
+
Reflect.set(parent, "length", operation.value);
|
|
1425
2817
|
return;
|
|
1426
2818
|
}
|
|
1427
2819
|
const key = requirePlainSegment(parent, segment, path);
|
|
1428
2820
|
const descriptor = Reflect.getOwnPropertyDescriptor(parent, key);
|
|
1429
2821
|
const present = descriptor !== void 0 && descriptor.enumerable && "value" in descriptor;
|
|
1430
2822
|
if (descriptor !== void 0 && !present) throw unresolvedError(path);
|
|
1431
|
-
if (operation.
|
|
1432
|
-
|
|
1433
|
-
|
|
2823
|
+
if (operation.verb === "delete") {
|
|
2824
|
+
Reflect.deleteProperty(parent, key);
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
if (!present) {
|
|
1434
2828
|
const inheritedDescriptor = getInheritedDescriptor(parent, key);
|
|
1435
2829
|
if (inheritedDescriptor && !("value" in inheritedDescriptor)) {
|
|
1436
2830
|
throw new Error(`opshot: ${formatOperationPath(path)} resolves to an inherited accessor`);
|
|
1437
2831
|
}
|
|
1438
2832
|
}
|
|
1439
|
-
|
|
1440
|
-
deleteOrThrow(parent, key);
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
if (!("value" in operation)) throw unresolvedError(path);
|
|
2833
|
+
const payload = getValuePayload(operation, identity);
|
|
1444
2834
|
restoreValue(
|
|
1445
|
-
|
|
1446
|
-
(value) =>
|
|
1447
|
-
() => Reflect.get(parent, key)
|
|
2835
|
+
payload,
|
|
2836
|
+
(value) => Reflect.set(parent, key, value),
|
|
2837
|
+
() => Reflect.get(parent, key),
|
|
2838
|
+
identity
|
|
1448
2839
|
);
|
|
2840
|
+
const attached = Reflect.get(parent, key);
|
|
2841
|
+
if (!isObjectLike3(attached)) return;
|
|
2842
|
+
if (operation.ids !== void 0) {
|
|
2843
|
+
if (isObjectLike3(payload.recorded)) {
|
|
2844
|
+
bindVendedIds(handle, attached, payload.recorded, operation.ids, handle.transactionCapture, parent, key);
|
|
2845
|
+
}
|
|
2846
|
+
} else {
|
|
2847
|
+
let chains = chainsAtRoot(handle.declarations);
|
|
2848
|
+
for (const segment2 of path) chains = descendChains(chains, segment2).chains;
|
|
2849
|
+
chains = nodeChainsOf(handle, attached) ?? chains;
|
|
2850
|
+
internSubtree(
|
|
2851
|
+
handle,
|
|
2852
|
+
attached,
|
|
2853
|
+
chains,
|
|
2854
|
+
(parent2, parentChains, key2, entry) => isTrackedEdge(entry) ? resolveChildChains(handle, parent2, parentChains, key2, entry.value)?.chains : void 0,
|
|
2855
|
+
handle.transactionCapture
|
|
2856
|
+
);
|
|
2857
|
+
}
|
|
2858
|
+
};
|
|
2859
|
+
var applyMutation = (root, operation, identity, handle) => {
|
|
2860
|
+
if (operation.verb === "link") {
|
|
2861
|
+
applyLink(root, operation, handle);
|
|
2862
|
+
return;
|
|
2863
|
+
}
|
|
2864
|
+
const terminal = resolveTerminal(root, operation.path);
|
|
2865
|
+
applyPlain(terminal.parent, terminal.segment, operation, identity, handle);
|
|
1449
2866
|
};
|
|
1450
|
-
function
|
|
2867
|
+
function applyMutations(root, operations, direction, identity, handle) {
|
|
2868
|
+
if (direction === "do") {
|
|
2869
|
+
for (const operation of operations) applyMutation(root, operation.do, identity, handle);
|
|
2870
|
+
return;
|
|
2871
|
+
}
|
|
2872
|
+
const occupantAt = (path) => {
|
|
2873
|
+
let current = root;
|
|
2874
|
+
for (const segment of path) {
|
|
2875
|
+
if (!isObjectLike3(current)) return void 0;
|
|
2876
|
+
current = Reflect.get(current, segment);
|
|
2877
|
+
}
|
|
2878
|
+
return current;
|
|
2879
|
+
};
|
|
2880
|
+
const admittedRoots = new Array();
|
|
1451
2881
|
for (const operation of operations) {
|
|
1452
|
-
|
|
1453
|
-
|
|
2882
|
+
if (operation.do.verb !== "assign" || !isObjectLike3(operation.do.value)) continue;
|
|
2883
|
+
const occupant = occupantAt(operation.undo.path);
|
|
2884
|
+
if (isObjectLike3(occupant)) admittedRoots.push(occupant);
|
|
2885
|
+
}
|
|
2886
|
+
for (let index = operations.length - 1; index >= 0; index--) {
|
|
2887
|
+
const operation = operations[index];
|
|
2888
|
+
if (operation === void 0) continue;
|
|
2889
|
+
applyMutation(root, operation.undo, identity, handle);
|
|
2890
|
+
}
|
|
2891
|
+
const idSet = /* @__PURE__ */ new Set();
|
|
2892
|
+
for (const node of admittedRoots) {
|
|
2893
|
+
for (const id of rewindAdmission(handle, node)) idSet.add(id);
|
|
2894
|
+
}
|
|
2895
|
+
while (idSet.has(handle.nextInternId - 1)) handle.nextInternId -= 1;
|
|
2896
|
+
}
|
|
2897
|
+
|
|
2898
|
+
// src/transact/rollback.ts
|
|
2899
|
+
var rollbackTransaction = (handle) => {
|
|
2900
|
+
const restoreTarget = handle.lastSnapshot;
|
|
2901
|
+
const operations = diffObjects(snapshot(handle.proxy.root), restoreTarget, handle, void 0, createCaptureTables());
|
|
2902
|
+
if (operations.length > 0) {
|
|
2903
|
+
applyMutations(handle.proxy.root, operations, "do", "restore", handle);
|
|
2904
|
+
}
|
|
2905
|
+
handle.lastSnapshot = restoreTarget;
|
|
2906
|
+
handle.hasPendingWrites = false;
|
|
2907
|
+
};
|
|
2908
|
+
|
|
2909
|
+
// src/transact/transact.ts
|
|
2910
|
+
function transact(state, mutate, meta) {
|
|
2911
|
+
runTransaction(state, mutate, meta, void 0);
|
|
2912
|
+
}
|
|
2913
|
+
var attachRollbackCause = (error, rollbackError) => {
|
|
2914
|
+
if (!(error instanceof Error) || error.cause !== void 0) return;
|
|
2915
|
+
Object.defineProperty(error, "cause", {
|
|
2916
|
+
value: rollbackError,
|
|
2917
|
+
writable: true,
|
|
2918
|
+
enumerable: false,
|
|
2919
|
+
configurable: true
|
|
2920
|
+
});
|
|
2921
|
+
};
|
|
2922
|
+
var flattenDeliveryFailures = (error) => {
|
|
2923
|
+
if (error instanceof AggregateError && error.message === "opshot: listeners failed during delivery") {
|
|
2924
|
+
return error.errors;
|
|
2925
|
+
}
|
|
2926
|
+
return [error];
|
|
2927
|
+
};
|
|
2928
|
+
var releaseUncaught = (failures) => {
|
|
2929
|
+
if (failures.length === 0) return;
|
|
2930
|
+
const error = failures.length === 1 ? failures[0] : new AggregateError(failures, "opshot: listeners failed during delivery");
|
|
2931
|
+
queueMicrotask(() => {
|
|
2932
|
+
throw error;
|
|
2933
|
+
});
|
|
2934
|
+
};
|
|
2935
|
+
function runTransaction(state, mutate, meta, channelId) {
|
|
2936
|
+
if (isTransactionOpen()) {
|
|
2937
|
+
throw new Error(
|
|
2938
|
+
"opshot: transact cannot be nested; a transaction cannot contain another. Mutate inside the callback rather than transacting, run transactions in sequence, or call applyOperations at top level."
|
|
2939
|
+
);
|
|
2940
|
+
}
|
|
2941
|
+
const handle = requireHandle(state, "opshot: transact requires a state");
|
|
2942
|
+
handle.flushGeneration += 1;
|
|
2943
|
+
handle.isFlushScheduled = false;
|
|
2944
|
+
const listenerFailures = new Array();
|
|
2945
|
+
const emitCollectingListeners = (emit) => {
|
|
2946
|
+
const baseline = handle.lastSnapshot;
|
|
2947
|
+
try {
|
|
2948
|
+
emit();
|
|
2949
|
+
} catch (error) {
|
|
2950
|
+
if (handle.lastSnapshot === baseline) throw error;
|
|
2951
|
+
listenerFailures.push(...flattenDeliveryFailures(error));
|
|
2952
|
+
}
|
|
2953
|
+
};
|
|
2954
|
+
const deliverQuietly = (ranges) => {
|
|
2955
|
+
try {
|
|
2956
|
+
deliverCapturedRanges(ranges);
|
|
2957
|
+
} catch (error) {
|
|
2958
|
+
listenerFailures.push(...flattenDeliveryFailures(error));
|
|
2959
|
+
}
|
|
2960
|
+
};
|
|
2961
|
+
try {
|
|
2962
|
+
const starting = captureWrites(handle);
|
|
2963
|
+
const previousHeld = handle.isFlushHeld;
|
|
2964
|
+
handle.isFlushHeld = true;
|
|
2965
|
+
handle.transactionCapture = createCaptureTables();
|
|
2966
|
+
openTransaction();
|
|
2967
|
+
let completed = false;
|
|
2968
|
+
let mutateError;
|
|
2969
|
+
try {
|
|
2970
|
+
mutate();
|
|
2971
|
+
completed = true;
|
|
2972
|
+
} catch (error) {
|
|
2973
|
+
mutateError = error;
|
|
2974
|
+
throw error;
|
|
2975
|
+
} finally {
|
|
2976
|
+
closeTransaction();
|
|
2977
|
+
if (!completed) {
|
|
2978
|
+
try {
|
|
2979
|
+
rollbackTransaction(handle);
|
|
2980
|
+
} catch (rollbackError) {
|
|
2981
|
+
attachRollbackCause(mutateError, rollbackError);
|
|
2982
|
+
}
|
|
2983
|
+
handle.transactionCapture = void 0;
|
|
2984
|
+
handle.isFlushHeld = previousHeld;
|
|
2985
|
+
deliverQuietly([starting]);
|
|
2986
|
+
} else {
|
|
2987
|
+
handle.isFlushHeld = previousHeld;
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
let transaction;
|
|
2991
|
+
try {
|
|
2992
|
+
transaction = captureTransactionWrites(handle, meta, channelId);
|
|
2993
|
+
} catch (error) {
|
|
2994
|
+
try {
|
|
2995
|
+
rollbackTransaction(handle);
|
|
2996
|
+
} catch (rollbackError) {
|
|
2997
|
+
attachRollbackCause(error, rollbackError);
|
|
2998
|
+
}
|
|
2999
|
+
deliverQuietly([starting]);
|
|
3000
|
+
throw error;
|
|
3001
|
+
} finally {
|
|
3002
|
+
handle.transactionCapture = void 0;
|
|
3003
|
+
}
|
|
3004
|
+
deliverQuietly([starting, transaction]);
|
|
3005
|
+
emitCollectingListeners(() => {
|
|
3006
|
+
emitWrites(handle);
|
|
3007
|
+
});
|
|
3008
|
+
} finally {
|
|
3009
|
+
releaseUncaught(listenerFailures);
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
|
|
3013
|
+
// src/ops/applyOperations.ts
|
|
3014
|
+
var originError = () => new Error("opshot: applyOperations applies a state's operations only to that state");
|
|
3015
|
+
var tapeError = () => new Error("opshot: applyOperations applies only the next or previous operations");
|
|
3016
|
+
var isFrozenCopyablePath = (value) => Array.isArray(value) && value.every((segment) => typeof segment === "string" || typeof segment === "number");
|
|
3017
|
+
var isNonNegativeInteger = (value) => typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
3018
|
+
var isWellFormedLinkHalf = (value) => typeof value === "object" && value !== null && "verb" in value && value.verb === "link" && "path" in value && "ref" in value && isFrozenCopyablePath(value.path) && isNonNegativeInteger(value.ref);
|
|
3019
|
+
var isWellFormedDeleteHalf = (value) => typeof value === "object" && value !== null && "verb" in value && value.verb === "delete" && "path" in value && isFrozenCopyablePath(value.path);
|
|
3020
|
+
var isWellFormedIds = (value) => value === void 0 || Array.isArray(value) && value.every((id) => typeof id === "number" && Number.isInteger(id) && id >= 0);
|
|
3021
|
+
var isWellFormedAssignHalf = (value) => typeof value === "object" && value !== null && "verb" in value && value.verb === "assign" && "value" in value && "path" in value && isFrozenCopyablePath(value.path) && (!("ids" in value) || value.ids === void 0 || isWellFormedIds(value.ids));
|
|
3022
|
+
var isApplicableHalf = (value) => isMutation(value) || isWellFormedLinkHalf(value) || isWellFormedDeleteHalf(value) || isWellFormedAssignHalf(value);
|
|
3023
|
+
var assertApplicable = (operation) => {
|
|
3024
|
+
if (isMutation(operation)) {
|
|
3025
|
+
throw new Error("opshot: applyOperations applies operation pairs; pass the operation, with a direction");
|
|
3026
|
+
}
|
|
3027
|
+
if (typeof operation !== "object" || operation === null || !("do" in operation) || !("undo" in operation) || !isApplicableHalf(operation.do) || !isApplicableHalf(operation.undo)) {
|
|
3028
|
+
throw new Error("opshot: applyOperations applies well-formed { do, undo } pairs");
|
|
1454
3029
|
}
|
|
3030
|
+
};
|
|
3031
|
+
function applyOperations(state, operations, direction, meta) {
|
|
3032
|
+
runOperations(state, operations, direction, meta, void 0);
|
|
1455
3033
|
}
|
|
1456
|
-
function
|
|
3034
|
+
function runOperations(state, operations, direction, meta, channelId) {
|
|
1457
3035
|
for (const operation of operations) assertApplicable(operation);
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
(
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
3036
|
+
const appliedDirection = direction;
|
|
3037
|
+
if (appliedDirection !== "do" && appliedDirection !== "undo") {
|
|
3038
|
+
throw new Error('opshot: applyOperations applies a direction of "do" or "undo"');
|
|
3039
|
+
}
|
|
3040
|
+
if (isTransactionOpen()) {
|
|
3041
|
+
throw new Error(
|
|
3042
|
+
"opshot: transact cannot be nested; a transaction cannot contain another. Mutate inside the callback rather than transacting, run transactions in sequence, or call applyOperations at top level."
|
|
3043
|
+
);
|
|
3044
|
+
}
|
|
3045
|
+
const handle = requireHandle(state, "opshot: applyOperations requires a state");
|
|
3046
|
+
emitWrites(handle);
|
|
3047
|
+
let ownedCount = 0;
|
|
3048
|
+
for (const operation of operations) {
|
|
3049
|
+
const stamp = stampOf(operation);
|
|
3050
|
+
if (stamp !== void 0 && stamp !== handle.stamp) throw originError();
|
|
3051
|
+
if (stamp === handle.stamp) ownedCount += 1;
|
|
3052
|
+
}
|
|
3053
|
+
if (ownedCount > 0 && ownedCount < operations.length) throw originError();
|
|
3054
|
+
const owned = operations.length > 0 && ownedCount === operations.length;
|
|
3055
|
+
if (owned) {
|
|
3056
|
+
let index = 0;
|
|
3057
|
+
for (const operation of operations) {
|
|
3058
|
+
const expected = direction === "do" ? handle.version + 1 + index : handle.version - (operations.length - 1 - index);
|
|
3059
|
+
if (versionOf(operation) !== expected) throw tapeError();
|
|
3060
|
+
index += 1;
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
handle.replaying = true;
|
|
3064
|
+
try {
|
|
3065
|
+
runTransaction(
|
|
3066
|
+
state,
|
|
3067
|
+
() => {
|
|
3068
|
+
applyMutations(resolveWriteProxy(state), operations, direction, owned ? "restore" : "construct", handle);
|
|
3069
|
+
if (owned) {
|
|
3070
|
+
handle.version = direction === "do" ? handle.version + operations.length : handle.version - operations.length;
|
|
3071
|
+
}
|
|
3072
|
+
},
|
|
3073
|
+
meta,
|
|
3074
|
+
channelId
|
|
3075
|
+
);
|
|
3076
|
+
} finally {
|
|
3077
|
+
handle.replaying = false;
|
|
3078
|
+
}
|
|
1465
3079
|
}
|
|
1466
3080
|
|
|
1467
3081
|
// src/subscribe.ts
|
|
1468
3082
|
function subscribe2(target, listener) {
|
|
1469
3083
|
if (isGroup(target)) {
|
|
1470
|
-
return addGroupListener(
|
|
1471
|
-
|
|
1472
|
-
|
|
3084
|
+
return addGroupListener(
|
|
3085
|
+
getGroupListeners(target),
|
|
3086
|
+
listener,
|
|
3087
|
+
void 0,
|
|
3088
|
+
(state, ops, meta) => listener(state, ops, meta)
|
|
3089
|
+
);
|
|
1473
3090
|
}
|
|
1474
|
-
return addStateListener(target, listener, void 0, (ops, meta) =>
|
|
1475
|
-
listener(ops, unwrapTransportMeta(meta));
|
|
1476
|
-
});
|
|
1477
|
-
}
|
|
1478
|
-
var channelStampBrand = /* @__PURE__ */ Symbol.for("opshot.channelStamp");
|
|
1479
|
-
function stampChannelMeta(channelId, meta) {
|
|
1480
|
-
return { [channelStampBrand]: channelId, meta };
|
|
1481
|
-
}
|
|
1482
|
-
function isChannelStamp(value) {
|
|
1483
|
-
return typeof value === "object" && value !== null && channelStampBrand in value;
|
|
1484
|
-
}
|
|
1485
|
-
function isOwnChannelStamp(value, channelId) {
|
|
1486
|
-
return isChannelStamp(value) && value[channelStampBrand] === channelId;
|
|
1487
|
-
}
|
|
1488
|
-
function unwrapTransportMeta(meta) {
|
|
1489
|
-
if (isChannelStamp(meta)) return meta.meta;
|
|
1490
|
-
return meta;
|
|
3091
|
+
return addStateListener(target, listener, void 0, (ops, meta) => listener(ops, meta));
|
|
1491
3092
|
}
|
|
1492
|
-
function toChannelContext(channelId, defaults, meta) {
|
|
1493
|
-
if (
|
|
1494
|
-
return {
|
|
3093
|
+
function toChannelContext(channelId, defaults, meta, deliveredChannelId) {
|
|
3094
|
+
if (deliveredChannelId === channelId) {
|
|
3095
|
+
return {
|
|
3096
|
+
isTransaction: true,
|
|
3097
|
+
meta: { ...defaults, ...typeof meta === "object" && meta !== null ? meta : void 0 }
|
|
3098
|
+
};
|
|
1495
3099
|
}
|
|
1496
|
-
return { isTransaction: false, meta
|
|
3100
|
+
return { isTransaction: false, meta };
|
|
1497
3101
|
}
|
|
1498
3102
|
|
|
1499
3103
|
// src/createChannel.ts
|
|
1500
3104
|
function createChannel(defaults) {
|
|
1501
3105
|
const channelId = Object.freeze({});
|
|
1502
3106
|
function transact2(state, mutate, meta) {
|
|
1503
|
-
|
|
3107
|
+
runTransaction(state, mutate, meta, channelId);
|
|
1504
3108
|
}
|
|
1505
3109
|
function subscribe3(target, listener) {
|
|
1506
3110
|
if (isGroup(target)) {
|
|
1507
|
-
return addGroupListener(
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
3111
|
+
return addGroupListener(
|
|
3112
|
+
getGroupListeners(target),
|
|
3113
|
+
listener,
|
|
3114
|
+
channelId,
|
|
3115
|
+
(state, ops, meta, deliveredChannelId) => {
|
|
3116
|
+
listener(
|
|
3117
|
+
state,
|
|
3118
|
+
ops,
|
|
3119
|
+
toChannelContext(channelId, defaults, meta, deliveredChannelId)
|
|
3120
|
+
);
|
|
3121
|
+
}
|
|
3122
|
+
);
|
|
1514
3123
|
}
|
|
1515
|
-
return addStateListener(target, listener, channelId, (ops, meta) => {
|
|
3124
|
+
return addStateListener(target, listener, channelId, (ops, meta, deliveredChannelId) => {
|
|
1516
3125
|
listener(
|
|
1517
3126
|
ops,
|
|
1518
|
-
toChannelContext(channelId, defaults, meta)
|
|
3127
|
+
toChannelContext(channelId, defaults, meta, deliveredChannelId)
|
|
1519
3128
|
);
|
|
1520
3129
|
});
|
|
1521
3130
|
}
|
|
1522
|
-
function
|
|
1523
|
-
|
|
1524
|
-
}
|
|
1525
|
-
return { transact: transact2, subscribe: subscribe3, applyOps: applyOps2 };
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
// src/react/resolveWrapper.ts
|
|
1529
|
-
var { proxyStateMap: proxyStateMap5 } = unstable_getInternalStates();
|
|
1530
|
-
var isObjectLike5 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
1531
|
-
function unwrapWrapper(value) {
|
|
1532
|
-
if (!isObjectLike5(value) || proxyStateMap5.has(value)) return value;
|
|
1533
|
-
let current = value;
|
|
1534
|
-
while (isObjectLike5(current)) {
|
|
1535
|
-
const registeredTarget = getRegisteredWrapperTarget(current);
|
|
1536
|
-
if (registeredTarget === void 0) break;
|
|
1537
|
-
current = registeredTarget;
|
|
3131
|
+
function applyOperations2(state, operations, direction, meta) {
|
|
3132
|
+
runOperations(state, operations, direction, meta, channelId);
|
|
1538
3133
|
}
|
|
1539
|
-
return
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
// src/isState.ts
|
|
1543
|
-
var { proxyStateMap: proxyStateMap6 } = unstable_getInternalStates();
|
|
1544
|
-
function isState(value) {
|
|
1545
|
-
const resolved = unwrapWrapper(value);
|
|
1546
|
-
if (typeof resolved !== "object" || resolved === null) return false;
|
|
1547
|
-
return proxyStateMap6.has(resolved);
|
|
3134
|
+
return { transact: transact2, subscribe: subscribe3, applyOperations: applyOperations2 };
|
|
1548
3135
|
}
|
|
1549
3136
|
|
|
1550
|
-
// src/ignore.ts
|
|
1551
|
-
var ignore = ref;
|
|
1552
|
-
|
|
1553
3137
|
// src/tracked/facadeGuard.ts
|
|
1554
3138
|
var assertMutableFacade = (facade, mutationKey) => {
|
|
1555
3139
|
const facadeSource = getUntracked(facade);
|
|
@@ -1561,11 +3145,17 @@ var assertMutableFacade = (facade, mutationKey) => {
|
|
|
1561
3145
|
};
|
|
1562
3146
|
|
|
1563
3147
|
// src/tracked/trackedDate.ts
|
|
3148
|
+
var DateSetYearError = class extends Error {
|
|
3149
|
+
constructor(message) {
|
|
3150
|
+
super(message);
|
|
3151
|
+
this.name = "DateSetYearError";
|
|
3152
|
+
}
|
|
3153
|
+
};
|
|
1564
3154
|
var setLegacyYear = (date, year) => {
|
|
1565
3155
|
const setYear = Reflect.get(date, "setYear");
|
|
1566
|
-
if (typeof setYear !== "function") throw new
|
|
3156
|
+
if (typeof setYear !== "function") throw new DateSetYearError("opshot: Date.setYear is not available");
|
|
1567
3157
|
const epochMs = Reflect.apply(setYear, date, [year]);
|
|
1568
|
-
if (typeof epochMs !== "number") throw new
|
|
3158
|
+
if (typeof epochMs !== "number") throw new DateSetYearError("opshot: Date.setYear returned a non-number");
|
|
1569
3159
|
return epochMs;
|
|
1570
3160
|
};
|
|
1571
3161
|
var constructDate = (args) => {
|
|
@@ -1588,6 +3178,11 @@ var constructDate = (args) => {
|
|
|
1588
3178
|
return new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
1589
3179
|
}
|
|
1590
3180
|
};
|
|
3181
|
+
var MAX_TIME = 864e13;
|
|
3182
|
+
var clipTime = (epochMs) => {
|
|
3183
|
+
if (!Number.isFinite(epochMs) || Math.abs(epochMs) > MAX_TIME) return Number.NaN;
|
|
3184
|
+
return Math.trunc(epochMs) + 0;
|
|
3185
|
+
};
|
|
1591
3186
|
var TrackedDate = class {
|
|
1592
3187
|
constructor(...args) {
|
|
1593
3188
|
installBoundary();
|
|
@@ -1596,6 +3191,9 @@ var TrackedDate = class {
|
|
|
1596
3191
|
readDate() {
|
|
1597
3192
|
return new Date(this.epochMs);
|
|
1598
3193
|
}
|
|
3194
|
+
readEpochMs() {
|
|
3195
|
+
return clipTime(this.epochMs);
|
|
3196
|
+
}
|
|
1599
3197
|
write(mutate) {
|
|
1600
3198
|
assertMutableFacade(this, "epochMs");
|
|
1601
3199
|
const epochMs = mutate(this.readDate());
|
|
@@ -1621,10 +3219,10 @@ var TrackedDate = class {
|
|
|
1621
3219
|
return this.readDate().toLocaleTimeString(locales, options);
|
|
1622
3220
|
}
|
|
1623
3221
|
valueOf() {
|
|
1624
|
-
return this.
|
|
3222
|
+
return this.readEpochMs();
|
|
1625
3223
|
}
|
|
1626
3224
|
getTime() {
|
|
1627
|
-
return this.
|
|
3225
|
+
return this.readEpochMs();
|
|
1628
3226
|
}
|
|
1629
3227
|
getFullYear() {
|
|
1630
3228
|
return this.readDate().getFullYear();
|
|
@@ -1738,8 +3336,8 @@ var TrackedDate = class {
|
|
|
1738
3336
|
return this.readDate().toISOString();
|
|
1739
3337
|
}
|
|
1740
3338
|
[Symbol.toPrimitive](hint) {
|
|
1741
|
-
|
|
1742
|
-
return
|
|
3339
|
+
if (hint === "number") return this.readEpochMs();
|
|
3340
|
+
return this.readDate()[Symbol.toPrimitive](hint);
|
|
1743
3341
|
}
|
|
1744
3342
|
};
|
|
1745
3343
|
Object.defineProperty(TrackedDate.prototype, Symbol.toStringTag, {
|
|
@@ -1750,19 +3348,11 @@ Object.defineProperty(TrackedDate.prototype, Symbol.toStringTag, {
|
|
|
1750
3348
|
});
|
|
1751
3349
|
|
|
1752
3350
|
// src/tracked/address.ts
|
|
1753
|
-
var
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
if (resolved === null || typeof resolved !== "object" && typeof resolved !== "function" && typeof resolved !== "symbol") {
|
|
1758
|
-
throw new Error("opshot: addressOf interned a non-identity value");
|
|
3351
|
+
var UnsupportedKeyTypeError = class extends Error {
|
|
3352
|
+
constructor(key) {
|
|
3353
|
+
super(`opshot: addressOf received unsupported key type ${typeof key}`);
|
|
3354
|
+
this.name = "UnsupportedKeyTypeError";
|
|
1759
3355
|
}
|
|
1760
|
-
const existing = internTable.get(resolved);
|
|
1761
|
-
if (existing !== void 0) return existing;
|
|
1762
|
-
const id = nextInternId;
|
|
1763
|
-
nextInternId += 1;
|
|
1764
|
-
internTable.set(resolved, id);
|
|
1765
|
-
return id;
|
|
1766
3356
|
};
|
|
1767
3357
|
var addressOf = (key) => {
|
|
1768
3358
|
if (key === null) return "z";
|
|
@@ -1785,10 +3375,59 @@ var addressOf = (key) => {
|
|
|
1785
3375
|
case "function":
|
|
1786
3376
|
return `o${internIdentity(key)}`;
|
|
1787
3377
|
default:
|
|
1788
|
-
throw new
|
|
3378
|
+
throw new UnsupportedKeyTypeError(key);
|
|
1789
3379
|
}
|
|
1790
3380
|
};
|
|
1791
3381
|
|
|
3382
|
+
// src/tracked/slotStore.ts
|
|
3383
|
+
var swapChain = /* @__PURE__ */ new WeakMap();
|
|
3384
|
+
var compactStore = (store, addressOfEntry) => {
|
|
3385
|
+
const retired = store.slots;
|
|
3386
|
+
const slots = new Array();
|
|
3387
|
+
const index = {};
|
|
3388
|
+
for (const entry of retired) {
|
|
3389
|
+
if (entry === null || entry === void 0) continue;
|
|
3390
|
+
index[addressOfEntry(entry)] = slots.length;
|
|
3391
|
+
slots.push(entry);
|
|
3392
|
+
}
|
|
3393
|
+
store.slots = slots;
|
|
3394
|
+
store.index = index;
|
|
3395
|
+
swapChain.set(retired, store.slots);
|
|
3396
|
+
};
|
|
3397
|
+
var translateCursor = (retired, cursor, current) => {
|
|
3398
|
+
let array = retired;
|
|
3399
|
+
let position = cursor;
|
|
3400
|
+
while (array !== current) {
|
|
3401
|
+
const successor = swapChain.get(array);
|
|
3402
|
+
if (successor === void 0) return 0;
|
|
3403
|
+
let survivors = 0;
|
|
3404
|
+
const bound = Math.min(position, array.length);
|
|
3405
|
+
for (let slot = 0; slot < bound; slot += 1) {
|
|
3406
|
+
const entry = array[slot];
|
|
3407
|
+
if (entry !== null && entry !== void 0) survivors += 1;
|
|
3408
|
+
}
|
|
3409
|
+
position = survivors;
|
|
3410
|
+
array = successor;
|
|
3411
|
+
}
|
|
3412
|
+
return position;
|
|
3413
|
+
};
|
|
3414
|
+
var deleteFromStore = (store, addr, addressOfEntry) => {
|
|
3415
|
+
const slot = store.index[addr];
|
|
3416
|
+
if (slot === void 0) return false;
|
|
3417
|
+
store.slots[slot] = null;
|
|
3418
|
+
Reflect.deleteProperty(store.index, addr);
|
|
3419
|
+
store.count -= 1;
|
|
3420
|
+
if (store.slots.length >= 2 * store.count) {
|
|
3421
|
+
compactStore(store, addressOfEntry);
|
|
3422
|
+
}
|
|
3423
|
+
return true;
|
|
3424
|
+
};
|
|
3425
|
+
var clearStore = (store) => {
|
|
3426
|
+
store.slots = [];
|
|
3427
|
+
store.index = {};
|
|
3428
|
+
store.count = 0;
|
|
3429
|
+
};
|
|
3430
|
+
|
|
1792
3431
|
// src/tracked/iterateSlots.ts
|
|
1793
3432
|
function* iterateSlots(getSlots) {
|
|
1794
3433
|
let slots = getSlots();
|
|
@@ -1796,8 +3435,8 @@ function* iterateSlots(getSlots) {
|
|
|
1796
3435
|
for (; ; ) {
|
|
1797
3436
|
const current = getSlots();
|
|
1798
3437
|
if (current !== slots) {
|
|
3438
|
+
index = translateCursor(slots, index, current);
|
|
1799
3439
|
slots = current;
|
|
1800
|
-
index = 0;
|
|
1801
3440
|
}
|
|
1802
3441
|
if (index >= slots.length) return;
|
|
1803
3442
|
const entry = slots[index];
|
|
@@ -1806,22 +3445,18 @@ function* iterateSlots(getSlots) {
|
|
|
1806
3445
|
}
|
|
1807
3446
|
}
|
|
1808
3447
|
|
|
1809
|
-
// src/tracked/
|
|
1810
|
-
var
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
store.count -= 1;
|
|
1816
|
-
return true;
|
|
3448
|
+
// src/tracked/trackedMap.ts
|
|
3449
|
+
var EmptyMapSlotError = class extends Error {
|
|
3450
|
+
constructor() {
|
|
3451
|
+
super("opshot: TrackedMap resolved an empty slot");
|
|
3452
|
+
this.name = "EmptyMapSlotError";
|
|
3453
|
+
}
|
|
1817
3454
|
};
|
|
1818
|
-
var
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
3455
|
+
var isObjectLike5 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
3456
|
+
var isStoredValue = (stored, incoming) => {
|
|
3457
|
+
if (Object.is(stored, incoming)) return true;
|
|
3458
|
+
return isObjectLike5(stored) && isObjectLike5(incoming) && isSameIdentity(stored, incoming);
|
|
1822
3459
|
};
|
|
1823
|
-
|
|
1824
|
-
// src/tracked/trackedMap.ts
|
|
1825
3460
|
var TrackedMap = class {
|
|
1826
3461
|
constructor(entries) {
|
|
1827
3462
|
installBoundary();
|
|
@@ -1844,23 +3479,29 @@ var TrackedMap = class {
|
|
|
1844
3479
|
}
|
|
1845
3480
|
set(key, value) {
|
|
1846
3481
|
assertMutableFacade(this, "count");
|
|
1847
|
-
const
|
|
3482
|
+
const stored = Object.is(key, -0) ? 0 : key;
|
|
3483
|
+
const addr = addressOf(stored);
|
|
1848
3484
|
const slot = this.index[addr];
|
|
1849
3485
|
if (slot === void 0) {
|
|
1850
3486
|
const newSlot = this.slots.length;
|
|
1851
|
-
this.slots.push([
|
|
3487
|
+
this.slots.push([stored, value]);
|
|
1852
3488
|
this.index[addr] = newSlot;
|
|
1853
3489
|
this.count += 1;
|
|
1854
3490
|
} else {
|
|
1855
3491
|
const pair = this.slots[slot];
|
|
1856
|
-
if (pair === null || pair === void 0) throw new
|
|
3492
|
+
if (pair === null || pair === void 0) throw new EmptyMapSlotError();
|
|
3493
|
+
if (isStoredValue(pair[1], value)) return this;
|
|
1857
3494
|
this.slots[slot] = [pair[0], value];
|
|
1858
3495
|
}
|
|
1859
3496
|
return this;
|
|
1860
3497
|
}
|
|
1861
3498
|
delete(key) {
|
|
1862
3499
|
assertMutableFacade(this, "count");
|
|
1863
|
-
return deleteFromStore(
|
|
3500
|
+
return deleteFromStore(
|
|
3501
|
+
this,
|
|
3502
|
+
addressOf(key),
|
|
3503
|
+
(pair) => addressOf(pair[0])
|
|
3504
|
+
);
|
|
1864
3505
|
}
|
|
1865
3506
|
clear() {
|
|
1866
3507
|
assertMutableFacade(this, "count");
|
|
@@ -1915,17 +3556,22 @@ var TrackedSet = class {
|
|
|
1915
3556
|
}
|
|
1916
3557
|
add(value) {
|
|
1917
3558
|
assertMutableFacade(this, "count");
|
|
1918
|
-
const
|
|
3559
|
+
const stored = Object.is(value, -0) ? 0 : value;
|
|
3560
|
+
const addr = addressOf(stored);
|
|
1919
3561
|
if (this.index[addr] !== void 0) return this;
|
|
1920
3562
|
const slot = this.slots.length;
|
|
1921
|
-
this.slots.push([
|
|
3563
|
+
this.slots.push([stored]);
|
|
1922
3564
|
this.index[addr] = slot;
|
|
1923
3565
|
this.count += 1;
|
|
1924
3566
|
return this;
|
|
1925
3567
|
}
|
|
1926
3568
|
delete(value) {
|
|
1927
3569
|
assertMutableFacade(this, "count");
|
|
1928
|
-
return deleteFromStore(
|
|
3570
|
+
return deleteFromStore(
|
|
3571
|
+
this,
|
|
3572
|
+
addressOf(value),
|
|
3573
|
+
(member) => addressOf(member[0])
|
|
3574
|
+
);
|
|
1929
3575
|
}
|
|
1930
3576
|
clear() {
|
|
1931
3577
|
assertMutableFacade(this, "count");
|
|
@@ -1960,15 +3606,195 @@ Object.defineProperty(TrackedSet.prototype, Symbol.toStringTag, {
|
|
|
1960
3606
|
writable: false
|
|
1961
3607
|
});
|
|
1962
3608
|
|
|
1963
|
-
// src/react/
|
|
1964
|
-
var
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
3609
|
+
// src/react/dirtySinceSnapshot.ts
|
|
3610
|
+
var parentLiveOf = (root, path) => {
|
|
3611
|
+
if (path.length === 0) return void 0;
|
|
3612
|
+
let current = root;
|
|
3613
|
+
for (const segment of path.slice(0, -1)) {
|
|
3614
|
+
if (!isObjectLike3(current)) return void 0;
|
|
3615
|
+
current = Reflect.get(current, segment);
|
|
3616
|
+
}
|
|
3617
|
+
return isObjectLike3(current) ? current : void 0;
|
|
3618
|
+
};
|
|
3619
|
+
function dirtySinceSnapshot(handle, from) {
|
|
3620
|
+
const dirty = { edges: /* @__PURE__ */ new WeakMap(), nodes: /* @__PURE__ */ new WeakSet() };
|
|
3621
|
+
for (const operation of diffObjects(from, snapshot(handle.proxy.root))) {
|
|
3622
|
+
const path = operation.do.path;
|
|
3623
|
+
markDirtyPath(dirty, handle, path, parentLiveOf(handle.proxy.root, path));
|
|
3624
|
+
}
|
|
3625
|
+
return dirty;
|
|
3626
|
+
}
|
|
3627
|
+
|
|
3628
|
+
// src/react/propWalk.ts
|
|
3629
|
+
var stateKeysByContainer = /* @__PURE__ */ new WeakMap();
|
|
3630
|
+
var noStateKeys = /* @__PURE__ */ new Set();
|
|
3631
|
+
var isReactOwnNode = (value) => "$$typeof" in value || typeof Node !== "undefined" && value instanceof Node;
|
|
3632
|
+
var childRole = (value, writable, mode) => {
|
|
3633
|
+
if (typeof value !== "object" || value === null) return "skip";
|
|
3634
|
+
if (isReactOwnNode(value)) return "skip";
|
|
3635
|
+
if (mode === "nested" && !writable) return "skip";
|
|
3636
|
+
if (admissionLane(value) === "untracked") return "skip";
|
|
3637
|
+
if (isState(value)) return "state";
|
|
3638
|
+
if (admissionLane(value) === "tracked") return "descend";
|
|
3639
|
+
return "skip";
|
|
3640
|
+
};
|
|
3641
|
+
var readVerdict = (container, pass) => pass.verdicts.get(container) ?? stateKeysByContainer.get(container) ?? noStateKeys;
|
|
3642
|
+
var createDiscoveryPass = () => ({
|
|
3643
|
+
entriesByContainer: /* @__PURE__ */ new Map(),
|
|
3644
|
+
verdicts: /* @__PURE__ */ new Map(),
|
|
3645
|
+
inProgress: /* @__PURE__ */ new Set(),
|
|
3646
|
+
relaxable: /* @__PURE__ */ new Set()
|
|
3647
|
+
});
|
|
3648
|
+
function visitContainer(container, pass, mode) {
|
|
3649
|
+
if (mode === "nested" && stateKeysByContainer.has(container)) return false;
|
|
3650
|
+
if (pass.inProgress.has(container)) return true;
|
|
3651
|
+
if (pass.verdicts.has(container)) return pass.relaxable.has(container);
|
|
3652
|
+
pass.inProgress.add(container);
|
|
3653
|
+
const entries = walkDataEntries(container);
|
|
3654
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3655
|
+
let dependedOnBackEdge = false;
|
|
3656
|
+
pass.entriesByContainer.set(container, entries);
|
|
3657
|
+
for (const entry of entries) {
|
|
3658
|
+
const role = childRole(entry.value, entry.writable, mode);
|
|
3659
|
+
if (role === "state") {
|
|
3660
|
+
keys.add(entry.key);
|
|
3661
|
+
continue;
|
|
3662
|
+
}
|
|
3663
|
+
if (role !== "descend") continue;
|
|
3664
|
+
const child = entry.value;
|
|
3665
|
+
if (typeof child !== "object" || child === null) continue;
|
|
3666
|
+
if (visitContainer(child, pass, "nested")) dependedOnBackEdge = true;
|
|
3667
|
+
if (readVerdict(child, pass).size > 0) keys.add(entry.key);
|
|
3668
|
+
}
|
|
3669
|
+
pass.inProgress.delete(container);
|
|
3670
|
+
pass.verdicts.set(container, keys);
|
|
3671
|
+
if (dependedOnBackEdge) pass.relaxable.add(container);
|
|
3672
|
+
return dependedOnBackEdge;
|
|
3673
|
+
}
|
|
3674
|
+
function relaxVerdicts(pass, entryContainer) {
|
|
3675
|
+
let gained = true;
|
|
3676
|
+
while (gained) {
|
|
3677
|
+
gained = false;
|
|
3678
|
+
for (const container of pass.relaxable) {
|
|
3679
|
+
const keys = pass.verdicts.get(container);
|
|
3680
|
+
const entries = pass.entriesByContainer.get(container);
|
|
3681
|
+
if (keys === void 0 || entries === void 0) continue;
|
|
3682
|
+
for (const entry of entries) {
|
|
3683
|
+
if (keys.has(entry.key)) continue;
|
|
3684
|
+
if (childRole(entry.value, entry.writable, container === entryContainer ? "entry" : "nested") !== "descend")
|
|
3685
|
+
continue;
|
|
3686
|
+
const child = entry.value;
|
|
3687
|
+
if (typeof child !== "object" || child === null) continue;
|
|
3688
|
+
if (readVerdict(child, pass).size === 0) continue;
|
|
3689
|
+
keys.add(entry.key);
|
|
3690
|
+
gained = true;
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
var cacheNestedVerdicts = (pass, skip) => {
|
|
3696
|
+
for (const [visited, keys] of pass.verdicts) {
|
|
3697
|
+
if (visited === skip) continue;
|
|
3698
|
+
stateKeysByContainer.set(visited, keys);
|
|
3699
|
+
}
|
|
3700
|
+
};
|
|
3701
|
+
function discoverStateKeys(container) {
|
|
3702
|
+
const cached = stateKeysByContainer.get(container);
|
|
3703
|
+
if (cached !== void 0) return cached;
|
|
3704
|
+
if (isReactOwnNode(container)) return noStateKeys;
|
|
3705
|
+
if (admissionLane(container) !== "tracked") return noStateKeys;
|
|
3706
|
+
const pass = createDiscoveryPass();
|
|
3707
|
+
visitContainer(container, pass, "nested");
|
|
3708
|
+
relaxVerdicts(pass);
|
|
3709
|
+
cacheNestedVerdicts(pass);
|
|
3710
|
+
return pass.verdicts.get(container) ?? noStateKeys;
|
|
3711
|
+
}
|
|
3712
|
+
function substituteContainer(container, substitution, wrap, mode) {
|
|
3713
|
+
const rebuilt = substitution.rebuiltByContainer.get(container);
|
|
3714
|
+
if (rebuilt !== void 0) return rebuilt;
|
|
3715
|
+
let stateKeys;
|
|
3716
|
+
if (mode === "nested") {
|
|
3717
|
+
stateKeys = discoverStateKeys(container);
|
|
3718
|
+
} else {
|
|
3719
|
+
const pass = createDiscoveryPass();
|
|
3720
|
+
visitContainer(container, pass, "entry");
|
|
3721
|
+
relaxVerdicts(pass, container);
|
|
3722
|
+
cacheNestedVerdicts(pass, container);
|
|
3723
|
+
stateKeys = pass.verdicts.get(container) ?? noStateKeys;
|
|
3724
|
+
}
|
|
3725
|
+
if (stateKeys.size === 0) {
|
|
3726
|
+
substitution.rebuiltByContainer.set(container, container);
|
|
3727
|
+
return container;
|
|
3728
|
+
}
|
|
3729
|
+
const clone = Array.isArray(container) ? [] : {};
|
|
3730
|
+
Reflect.setPrototypeOf(clone, Reflect.getPrototypeOf(container));
|
|
3731
|
+
substitution.rebuiltByContainer.set(container, clone);
|
|
3732
|
+
const descriptors = Object.getOwnPropertyDescriptors(container);
|
|
3733
|
+
for (const key of stateKeys) {
|
|
3734
|
+
const descriptor = descriptors[key];
|
|
3735
|
+
if (descriptor === void 0 || !("value" in descriptor)) continue;
|
|
3736
|
+
const value = descriptor.value;
|
|
3737
|
+
const role = childRole(value, descriptor.writable === true, mode);
|
|
3738
|
+
if (role === "state") {
|
|
3739
|
+
const source = peelReadProxy(value);
|
|
3740
|
+
if (typeof source !== "object" || source === null) continue;
|
|
3741
|
+
if (!substitution.visitedSources.has(source)) {
|
|
3742
|
+
substitution.visitedSources.add(source);
|
|
3743
|
+
substitution.sources.push(source);
|
|
3744
|
+
}
|
|
3745
|
+
descriptors[key] = { ...descriptor, value: wrap(source) };
|
|
3746
|
+
continue;
|
|
3747
|
+
}
|
|
3748
|
+
if (role !== "descend") continue;
|
|
3749
|
+
if (typeof value !== "object" || value === null) continue;
|
|
3750
|
+
descriptors[key] = { ...descriptor, value: substituteContainer(value, substitution, wrap, "nested") };
|
|
3751
|
+
}
|
|
3752
|
+
Object.defineProperties(clone, descriptors);
|
|
3753
|
+
return clone;
|
|
3754
|
+
}
|
|
3755
|
+
function substituteStates(root, wrap) {
|
|
3756
|
+
const substitution = {
|
|
3757
|
+
rebuiltByContainer: /* @__PURE__ */ new Map(),
|
|
3758
|
+
sources: [],
|
|
3759
|
+
visitedSources: /* @__PURE__ */ new Set()
|
|
3760
|
+
};
|
|
3761
|
+
if (isReactOwnNode(root) || unfrozenAdmissionLane(root) !== "tracked") {
|
|
3762
|
+
return { props: root, sources: substitution.sources };
|
|
3763
|
+
}
|
|
3764
|
+
return { props: substituteContainer(root, substitution, wrap, "entry"), sources: substitution.sources };
|
|
3765
|
+
}
|
|
3766
|
+
var NO_SLOT = /* @__PURE__ */ Symbol("opshot.noDispatcherSlot");
|
|
3767
|
+
var readDispatcher = () => {
|
|
3768
|
+
const internals = React;
|
|
3769
|
+
const modern = internals.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
3770
|
+
if (modern !== void 0) return modern.H;
|
|
3771
|
+
const legacy = internals.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?.ReactCurrentDispatcher;
|
|
3772
|
+
if (legacy !== void 0) return legacy.current;
|
|
3773
|
+
return NO_SLOT;
|
|
3774
|
+
};
|
|
3775
|
+
var nonRenderDispatcher;
|
|
3776
|
+
var learnNonRenderDispatcher = () => {
|
|
3777
|
+
const current = readDispatcher();
|
|
3778
|
+
if (current === NO_SLOT || current === null || current === void 0) return;
|
|
3779
|
+
nonRenderDispatcher = current;
|
|
3780
|
+
};
|
|
3781
|
+
var isRendering = () => {
|
|
3782
|
+
if (nonRenderDispatcher === void 0) return false;
|
|
3783
|
+
const current = readDispatcher();
|
|
3784
|
+
if (current === NO_SLOT || current === null || current === void 0) return false;
|
|
3785
|
+
return current !== nonRenderDispatcher;
|
|
3786
|
+
};
|
|
3787
|
+
|
|
3788
|
+
// src/react/readTracker.ts
|
|
3789
|
+
var { proxyStateMap: proxyStateMap16 } = unstable_getInternalStates();
|
|
3790
|
+
var KEYS_PROPERTY = "k";
|
|
3791
|
+
var HAS_KEY_PROPERTY = "h";
|
|
3792
|
+
var HAS_OWN_KEY_PROPERTY = "o";
|
|
3793
|
+
var ALL_OWN_KEYS_PROPERTY = "w";
|
|
1969
3794
|
var isObjectLike6 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
1970
|
-
var isLiveProxy = (value) =>
|
|
1971
|
-
var getProxyTarget = (
|
|
3795
|
+
var isLiveProxy = (value) => proxyStateMap16.has(value);
|
|
3796
|
+
var getProxyTarget = (writeProxy) => proxyStateMap16.get(writeProxy)?.[0] ?? writeProxy;
|
|
3797
|
+
var getProxyVersion = (writeProxy) => getVersion(writeProxy) ?? 0;
|
|
1972
3798
|
var getUsage = (affected, target) => {
|
|
1973
3799
|
let used = affected.get(target);
|
|
1974
3800
|
if (used === void 0) {
|
|
@@ -1997,260 +3823,173 @@ var getPrototypeMethod = (target, prop) => {
|
|
|
1997
3823
|
}
|
|
1998
3824
|
return void 0;
|
|
1999
3825
|
};
|
|
2000
|
-
var
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
methods = /* @__PURE__ */ new WeakMap();
|
|
2005
|
-
wrapperBoundMethods.set(wrapper, methods);
|
|
3826
|
+
var UnregisteredReadTrackerError = class extends Error {
|
|
3827
|
+
constructor() {
|
|
3828
|
+
super("opshot: readsIntersectDirty received an unregistered tracker");
|
|
3829
|
+
this.name = "UnregisteredReadTrackerError";
|
|
2006
3830
|
}
|
|
2007
|
-
const existing = methods.get(method);
|
|
2008
|
-
if (existing !== void 0) return existing;
|
|
2009
|
-
const bound = Function.prototype.bind.call(method, wrapper);
|
|
2010
|
-
methods.set(method, bound);
|
|
2011
|
-
return bound;
|
|
2012
3831
|
};
|
|
2013
|
-
|
|
3832
|
+
var trackerPartitions = /* @__PURE__ */ new WeakMap();
|
|
3833
|
+
var recordedKeysOf = (used) => {
|
|
3834
|
+
const keySets = new Array();
|
|
3835
|
+
if (used[KEYS_PROPERTY] !== void 0) keySets.push(used[KEYS_PROPERTY]);
|
|
3836
|
+
if (used[HAS_KEY_PROPERTY] !== void 0) keySets.push(used[HAS_KEY_PROPERTY]);
|
|
3837
|
+
if (used[HAS_OWN_KEY_PROPERTY] !== void 0) keySets.push(used[HAS_OWN_KEY_PROPERTY]);
|
|
3838
|
+
return keySets;
|
|
3839
|
+
};
|
|
3840
|
+
function readsIntersectDirty(tracker, dirty) {
|
|
3841
|
+
const partitions = trackerPartitions.get(tracker);
|
|
3842
|
+
if (partitions === void 0) throw new UnregisteredReadTrackerError();
|
|
3843
|
+
for (const partition of partitions.values()) {
|
|
3844
|
+
for (const [writeProxy, used] of partition.affected) {
|
|
3845
|
+
const raw = getProxyTarget(writeProxy);
|
|
3846
|
+
const edges = dirty.edges.get(raw);
|
|
3847
|
+
for (const keys of recordedKeysOf(used)) {
|
|
3848
|
+
for (const key of keys) {
|
|
3849
|
+
if (edges?.has(key) === true) return true;
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
if (used[ALL_OWN_KEYS_PROPERTY] === true && dirty.nodes.has(raw)) return true;
|
|
3853
|
+
}
|
|
3854
|
+
for (const writeProxy of partition.identityReads) {
|
|
3855
|
+
if (partition.affected.has(writeProxy)) continue;
|
|
3856
|
+
if (dirty.nodes.has(getProxyTarget(writeProxy))) return true;
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3859
|
+
return false;
|
|
3860
|
+
}
|
|
3861
|
+
function createReadTracker() {
|
|
2014
3862
|
const partitions = /* @__PURE__ */ new Map();
|
|
2015
|
-
const targets = /* @__PURE__ */ new Map();
|
|
2016
3863
|
let afterRender = false;
|
|
2017
|
-
|
|
2018
|
-
|
|
3864
|
+
let releasing = false;
|
|
3865
|
+
const getPartition = (writeProxy) => {
|
|
3866
|
+
let partition = partitions.get(writeProxy);
|
|
2019
3867
|
if (partition === void 0) {
|
|
2020
3868
|
partition = {
|
|
2021
|
-
sourceProxy,
|
|
2022
|
-
previousRootSnapshot: void 0,
|
|
2023
3869
|
affected: /* @__PURE__ */ new Map(),
|
|
2024
|
-
|
|
3870
|
+
identityReads: /* @__PURE__ */ new Set(),
|
|
2025
3871
|
proxyCache: /* @__PURE__ */ new WeakMap()
|
|
2026
3872
|
};
|
|
2027
|
-
partitions.set(
|
|
3873
|
+
partitions.set(writeProxy, partition);
|
|
2028
3874
|
}
|
|
2029
3875
|
return partition;
|
|
2030
3876
|
};
|
|
2031
|
-
const
|
|
2032
|
-
const
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
if (
|
|
2036
|
-
const baseline = snapshot(liveProxy);
|
|
2037
|
-
partition.baselines.set(liveProxy, baseline);
|
|
2038
|
-
return baseline;
|
|
2039
|
-
};
|
|
2040
|
-
const ensureRootBaseline = (partition) => {
|
|
2041
|
-
if (afterRender) return partition.previousRootSnapshot ?? snapshot(partition.sourceProxy);
|
|
2042
|
-
if (partition.previousRootSnapshot === void 0) {
|
|
2043
|
-
partition.previousRootSnapshot = snapshot(partition.sourceProxy);
|
|
2044
|
-
partition.baselines.set(partition.sourceProxy, partition.previousRootSnapshot);
|
|
2045
|
-
}
|
|
2046
|
-
return partition.previousRootSnapshot;
|
|
2047
|
-
};
|
|
2048
|
-
const registerTarget = (liveProxy) => {
|
|
2049
|
-
if (targets.has(liveProxy)) return;
|
|
2050
|
-
targets.set(liveProxy, {
|
|
2051
|
-
lastIdentitySnapshot: snapshot(liveProxy)
|
|
2052
|
-
});
|
|
3877
|
+
const shouldRecord = () => !afterRender || isRendering();
|
|
3878
|
+
const trackUsage = (partition, writeProxy) => shouldRecord() ? getUsage(partition.affected, writeProxy) : {};
|
|
3879
|
+
const recordIdentity = (partition, value) => {
|
|
3880
|
+
if (!shouldRecord()) return;
|
|
3881
|
+
if (isObjectLike6(value) && isLiveProxy(value)) partition.identityReads.add(value);
|
|
2053
3882
|
};
|
|
2054
|
-
const
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
const
|
|
2060
|
-
const
|
|
3883
|
+
const toReadProxy = (writeProxy, partition) => {
|
|
3884
|
+
const currentVersion = getProxyVersion(writeProxy);
|
|
3885
|
+
const cached = partition.proxyCache.get(writeProxy);
|
|
3886
|
+
if (cached?.version === currentVersion) return cached.readProxy;
|
|
3887
|
+
const target = getProxyTarget(writeProxy);
|
|
3888
|
+
const readProxyBox = {};
|
|
3889
|
+
const boundMethods = /* @__PURE__ */ new WeakMap();
|
|
3890
|
+
const bindMethodToReadProxy = (readProxy2, method) => {
|
|
3891
|
+
const existing = boundMethods.get(method);
|
|
3892
|
+
if (existing !== void 0) return existing;
|
|
3893
|
+
const bound = Function.prototype.bind.call(method, readProxy2);
|
|
3894
|
+
boundMethods.set(method, bound);
|
|
3895
|
+
return bound;
|
|
3896
|
+
};
|
|
2061
3897
|
const handler = {
|
|
2062
3898
|
get(_target, prop) {
|
|
2063
|
-
|
|
2064
|
-
const value = Reflect.get(
|
|
2065
|
-
const
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
ensureBaseline(partition, liveProxy);
|
|
3899
|
+
const readProxy2 = readProxyBox.current;
|
|
3900
|
+
const value = Reflect.get(writeProxy, prop, readProxy2 ?? writeProxy);
|
|
3901
|
+
const used = trackUsage(partition, writeProxy);
|
|
3902
|
+
recordKey(used, KEYS_PROPERTY, prop);
|
|
3903
|
+
recordIdentity(partition, value);
|
|
2069
3904
|
if (typeof value === "function") {
|
|
2070
|
-
const method = getPrototypeMethod(
|
|
2071
|
-
if (method !== void 0 && value === method &&
|
|
2072
|
-
return
|
|
3905
|
+
const method = getPrototypeMethod(target, prop);
|
|
3906
|
+
if (method !== void 0 && value === method && readProxy2 !== void 0) {
|
|
3907
|
+
return bindMethodToReadProxy(readProxy2, method);
|
|
2073
3908
|
}
|
|
2074
3909
|
}
|
|
2075
3910
|
if (!isObjectLike6(value)) return value;
|
|
2076
3911
|
if (typeof value === "function") return value;
|
|
2077
|
-
if (refSet6.has(value)) return value;
|
|
2078
3912
|
if (!isLiveProxy(value)) return value;
|
|
2079
|
-
return
|
|
3913
|
+
return toReadProxy(value, partition);
|
|
2080
3914
|
},
|
|
2081
3915
|
has(_target, prop) {
|
|
2082
|
-
const used = trackUsage(partition,
|
|
2083
|
-
recordKey(used,
|
|
2084
|
-
|
|
2085
|
-
return Reflect.has(liveProxy, prop);
|
|
3916
|
+
const used = trackUsage(partition, writeProxy);
|
|
3917
|
+
recordKey(used, HAS_KEY_PROPERTY, prop);
|
|
3918
|
+
return Reflect.has(writeProxy, prop);
|
|
2086
3919
|
},
|
|
2087
3920
|
getOwnPropertyDescriptor(_target, prop) {
|
|
2088
|
-
const used = trackUsage(partition,
|
|
2089
|
-
recordKey(used,
|
|
2090
|
-
|
|
2091
|
-
return Reflect.getOwnPropertyDescriptor(liveProxy, prop);
|
|
3921
|
+
const used = trackUsage(partition, writeProxy);
|
|
3922
|
+
recordKey(used, HAS_OWN_KEY_PROPERTY, prop);
|
|
3923
|
+
return Reflect.getOwnPropertyDescriptor(writeProxy, prop);
|
|
2092
3924
|
},
|
|
2093
3925
|
ownKeys() {
|
|
2094
|
-
const used = trackUsage(partition,
|
|
2095
|
-
used[
|
|
2096
|
-
|
|
2097
|
-
return Reflect.ownKeys(liveProxy);
|
|
3926
|
+
const used = trackUsage(partition, writeProxy);
|
|
3927
|
+
used[ALL_OWN_KEYS_PROPERTY] = true;
|
|
3928
|
+
return Reflect.ownKeys(writeProxy);
|
|
2098
3929
|
},
|
|
2099
3930
|
set(_target, prop, value) {
|
|
2100
|
-
|
|
2101
|
-
return Reflect.set(liveProxy, prop, value, liveProxy);
|
|
3931
|
+
return Reflect.set(writeProxy, prop, value, writeProxy);
|
|
2102
3932
|
},
|
|
2103
3933
|
deleteProperty(_target, prop) {
|
|
2104
|
-
|
|
2105
|
-
return Reflect.deleteProperty(liveProxy, prop);
|
|
3934
|
+
return Reflect.deleteProperty(writeProxy, prop);
|
|
2106
3935
|
}
|
|
2107
3936
|
};
|
|
2108
|
-
const
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
partition.proxyCache.set(
|
|
2112
|
-
return
|
|
3937
|
+
const readProxy = new Proxy(writeProxy, handler);
|
|
3938
|
+
readProxyBox.current = readProxy;
|
|
3939
|
+
registerReadProxyTarget(readProxy, writeProxy);
|
|
3940
|
+
partition.proxyCache.set(writeProxy, { readProxy, version: currentVersion });
|
|
3941
|
+
return readProxy;
|
|
2113
3942
|
};
|
|
2114
|
-
|
|
2115
|
-
wrap(
|
|
2116
|
-
if (!isLiveProxy(
|
|
2117
|
-
throw new Error("opshot:
|
|
2118
|
-
}
|
|
2119
|
-
const partition = getPartition(sourceProxy);
|
|
2120
|
-
ensureRootBaseline(partition);
|
|
2121
|
-
return wrapLive(sourceProxy, partition);
|
|
2122
|
-
},
|
|
2123
|
-
readsChanged(sourceProxy) {
|
|
2124
|
-
const partition = partitions.get(sourceProxy);
|
|
2125
|
-
if (partition?.previousRootSnapshot === void 0) return false;
|
|
2126
|
-
if (partition.affected.size === 0) return false;
|
|
2127
|
-
const translated = /* @__PURE__ */ new WeakMap();
|
|
2128
|
-
for (const [live, usage] of partition.affected) {
|
|
2129
|
-
const baseline = partition.baselines.get(live);
|
|
2130
|
-
if (baseline === void 0) {
|
|
2131
|
-
throw new Error("opshot: missing baseline snapshot for affected live proxy");
|
|
2132
|
-
}
|
|
2133
|
-
translated.set(baseline, usage);
|
|
3943
|
+
const tracker = {
|
|
3944
|
+
wrap(writeProxy) {
|
|
3945
|
+
if (!isLiveProxy(writeProxy)) {
|
|
3946
|
+
throw new Error("opshot: ReadTracker.wrap requires a write proxy");
|
|
2134
3947
|
}
|
|
2135
|
-
const
|
|
2136
|
-
return
|
|
3948
|
+
const partition = getPartition(writeProxy);
|
|
3949
|
+
return toReadProxy(writeProxy, partition);
|
|
2137
3950
|
},
|
|
2138
3951
|
captureReads() {
|
|
3952
|
+
learnNonRenderDispatcher();
|
|
2139
3953
|
afterRender = true;
|
|
2140
3954
|
},
|
|
2141
|
-
evictChangedTargets() {
|
|
2142
|
-
for (const [liveProxy, entry] of targets) {
|
|
2143
|
-
const current = snapshot(liveProxy);
|
|
2144
|
-
if (current !== entry.lastIdentitySnapshot) {
|
|
2145
|
-
for (const partition of partitions.values()) {
|
|
2146
|
-
partition.proxyCache.delete(liveProxy);
|
|
2147
|
-
}
|
|
2148
|
-
}
|
|
2149
|
-
entry.lastIdentitySnapshot = current;
|
|
2150
|
-
}
|
|
2151
|
-
},
|
|
2152
3955
|
resetReads() {
|
|
2153
3956
|
afterRender = false;
|
|
2154
3957
|
for (const partition of partitions.values()) {
|
|
2155
|
-
partition.previousRootSnapshot = void 0;
|
|
2156
3958
|
partition.affected.clear();
|
|
2157
|
-
partition.
|
|
3959
|
+
partition.identityReads.clear();
|
|
2158
3960
|
}
|
|
2159
3961
|
},
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
3962
|
+
retain() {
|
|
3963
|
+
releasing = false;
|
|
3964
|
+
},
|
|
3965
|
+
dispose() {
|
|
3966
|
+
releasing = true;
|
|
3967
|
+
void Promise.resolve().then(() => {
|
|
3968
|
+
if (!releasing) return;
|
|
3969
|
+
releasing = false;
|
|
3970
|
+
partitions.clear();
|
|
3971
|
+
});
|
|
2168
3972
|
}
|
|
2169
3973
|
};
|
|
3974
|
+
trackerPartitions.set(tracker, partitions);
|
|
3975
|
+
return tracker;
|
|
2170
3976
|
}
|
|
3977
|
+
var useCommitEffect = typeof document === "undefined" ? useEffect : useLayoutEffect;
|
|
2171
3978
|
|
|
2172
3979
|
// src/react/scope.tsx
|
|
2173
|
-
var
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
if (kind === "arraySubclass") {
|
|
2183
|
-
throw new Error(
|
|
2184
|
-
`opshot: scope found a state inside ${className}, an array subclass whose prototype can't survive substitution. Move the state to a plain array, or ignore() the ${className}.`
|
|
2185
|
-
);
|
|
2186
|
-
}
|
|
2187
|
-
const hidden = kind === "privateClass" ? "private fields" : "internal slots";
|
|
2188
|
-
throw new Error(
|
|
2189
|
-
`opshot: scope found a state inside ${className}, whose ${hidden} can't survive substitution. Move the state to a plain container, or ignore() the ${className}.`
|
|
2190
|
-
);
|
|
2191
|
-
};
|
|
2192
|
-
function findStatePaths(value, maxDepth, path = [], paths = [], ancestors = /* @__PURE__ */ new Set()) {
|
|
2193
|
-
if (isState(value)) {
|
|
2194
|
-
paths.push(path);
|
|
2195
|
-
return paths;
|
|
2196
|
-
}
|
|
2197
|
-
if (value === null || typeof value !== "object") return paths;
|
|
2198
|
-
if ("$$typeof" in value) return paths;
|
|
2199
|
-
if (ancestors.has(value)) return paths;
|
|
2200
|
-
if (path.length >= maxDepth) return paths;
|
|
2201
|
-
ancestors.add(value);
|
|
2202
|
-
if (Array.isArray(value)) {
|
|
2203
|
-
const foundCount = paths.length;
|
|
2204
|
-
value.forEach((item, index) => {
|
|
2205
|
-
findStatePaths(item, maxDepth, [...path, index], paths, ancestors);
|
|
2206
|
-
});
|
|
2207
|
-
if (paths.length > foundCount) assertSubstitutableContainer(value);
|
|
2208
|
-
} else {
|
|
2209
|
-
const foundCount = paths.length;
|
|
2210
|
-
for (const [key, propertyValue] of Object.entries(value)) {
|
|
2211
|
-
if (key.startsWith("__react")) continue;
|
|
2212
|
-
findStatePaths(propertyValue, maxDepth, [...path, key], paths, ancestors);
|
|
3980
|
+
var sourcesKey = (sources) => `${sources.length}:${sources.map((source) => addressOf(source)).join(",")}`;
|
|
3981
|
+
var uniqueHandlesOf = (nodes) => {
|
|
3982
|
+
const unique = new Array();
|
|
3983
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3984
|
+
for (const node of nodes) {
|
|
3985
|
+
for (const handle of handlesOf(node)) {
|
|
3986
|
+
if (seen.has(handle)) continue;
|
|
3987
|
+
seen.add(handle);
|
|
3988
|
+
unique.push(handle);
|
|
2213
3989
|
}
|
|
2214
|
-
if (paths.length > foundCount) assertSubstitutableContainer(value);
|
|
2215
|
-
}
|
|
2216
|
-
ancestors.delete(value);
|
|
2217
|
-
return paths;
|
|
2218
|
-
}
|
|
2219
|
-
function getAtPath(object, path) {
|
|
2220
|
-
let current = object;
|
|
2221
|
-
for (const segment of path) {
|
|
2222
|
-
if (current === null || current === void 0) return void 0;
|
|
2223
|
-
current = current[segment];
|
|
2224
|
-
}
|
|
2225
|
-
return current;
|
|
2226
|
-
}
|
|
2227
|
-
function setAtPath(object, path, value) {
|
|
2228
|
-
if (path.length === 0) return value;
|
|
2229
|
-
const head = path[0];
|
|
2230
|
-
if (head === void 0) throw new Error("setAtPath: non-empty path yielded no head segment");
|
|
2231
|
-
const tail = path.slice(1);
|
|
2232
|
-
const current = object[head];
|
|
2233
|
-
const updated = setAtPath(current, tail, value);
|
|
2234
|
-
if (Array.isArray(object)) {
|
|
2235
|
-
const clone2 = [...object];
|
|
2236
|
-
clone2[head] = updated;
|
|
2237
|
-
return clone2;
|
|
2238
|
-
}
|
|
2239
|
-
const prototype = Reflect.getPrototypeOf(object);
|
|
2240
|
-
if (prototype === Object.prototype || prototype === null) return { ...object, [head]: updated };
|
|
2241
|
-
const descriptor = Object.getOwnPropertyDescriptor(object, head);
|
|
2242
|
-
if (descriptor?.get !== void 0 || descriptor?.set !== void 0) {
|
|
2243
|
-
const className = constructorName(object.constructor);
|
|
2244
|
-
throw new Error(
|
|
2245
|
-
`opshot: scope found a state behind the accessor "${String(head)}" on ${className}, which can't survive substitution. Move the state to a plain container, or ignore() the ${className}.`
|
|
2246
|
-
);
|
|
2247
3990
|
}
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
clone[head] = updated;
|
|
2251
|
-
return clone;
|
|
2252
|
-
}
|
|
2253
|
-
var sourcesKey = (sources) => `${sources.length}:${sources.map((source) => addressOf(source)).join(",")}`;
|
|
3991
|
+
return unique;
|
|
3992
|
+
};
|
|
2254
3993
|
var arePropsEqual = (previous, next) => {
|
|
2255
3994
|
const previousRecord = previous;
|
|
2256
3995
|
const nextRecord = next;
|
|
@@ -2267,99 +4006,112 @@ var arePropsEqual = (previous, next) => {
|
|
|
2267
4006
|
}
|
|
2268
4007
|
return true;
|
|
2269
4008
|
};
|
|
2270
|
-
function scope(Component
|
|
2271
|
-
const maxDepth = options?.maxDepth ?? 10;
|
|
4009
|
+
function scope(Component) {
|
|
2272
4010
|
const Scoped = (props) => {
|
|
2273
|
-
const
|
|
2274
|
-
|
|
2275
|
-
const
|
|
4011
|
+
const readTrackerRef = useRef(void 0);
|
|
4012
|
+
const currentHandlesRef = useRef([]);
|
|
4013
|
+
const [gapSnapshots] = useState(() => /* @__PURE__ */ new WeakMap());
|
|
4014
|
+
readTrackerRef.current ??= createReadTracker();
|
|
4015
|
+
const readTracker = readTrackerRef.current;
|
|
2276
4016
|
const [, bump] = useReducer((value) => value + 1, 0);
|
|
2277
|
-
|
|
2278
|
-
const
|
|
2279
|
-
const
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
for (const path of paths) {
|
|
2283
|
-
const value = getAtPath(props, path);
|
|
2284
|
-
if (!isState(value)) continue;
|
|
2285
|
-
const source = unwrapWrapper(value);
|
|
2286
|
-
if (typeof source !== "object" || source === null) continue;
|
|
2287
|
-
const wrapped = boundary.wrap(source);
|
|
2288
|
-
if (!sources.includes(source)) sources.push(source);
|
|
2289
|
-
if (wrapped !== value) {
|
|
2290
|
-
nextProps = setAtPath(nextProps, path, wrapped);
|
|
2291
|
-
changed = true;
|
|
2292
|
-
}
|
|
4017
|
+
readTracker.resetReads();
|
|
4018
|
+
const { props: renderedProps, sources } = substituteStates(props, (source) => readTracker.wrap(source));
|
|
4019
|
+
const uniqueHandles = uniqueHandlesOf(sources);
|
|
4020
|
+
for (const handle of uniqueHandles) {
|
|
4021
|
+
gapSnapshots.set(handle, snapshot(handle.proxy.root));
|
|
2293
4022
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
boundary.captureReads();
|
|
4023
|
+
useCommitEffect(() => {
|
|
4024
|
+
currentHandlesRef.current = uniqueHandles;
|
|
4025
|
+
readTracker.captureReads();
|
|
2298
4026
|
});
|
|
2299
4027
|
useEffect(() => {
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
4028
|
+
readTracker.retain();
|
|
4029
|
+
return () => readTracker.dispose();
|
|
4030
|
+
}, [readTracker]);
|
|
4031
|
+
useEffect(() => {
|
|
4032
|
+
let cancelled = false;
|
|
4033
|
+
const subscribedHandles = uniqueHandlesOf(sources);
|
|
4034
|
+
for (const handle of subscribedHandles) {
|
|
4035
|
+
const from = gapSnapshots.get(handle);
|
|
4036
|
+
if (from !== void 0 && readsIntersectDirty(readTracker, dirtySinceSnapshot(handle, from))) bump();
|
|
4037
|
+
}
|
|
4038
|
+
const unsubscribes = subscribedHandles.map(
|
|
4039
|
+
(handle) => subscribe2(handle.proxy.root, () => {
|
|
4040
|
+
if (cancelled) return;
|
|
4041
|
+
const dirty = handle.lastDirty;
|
|
4042
|
+
if (dirty !== void 0 && readsIntersectDirty(readTracker, dirty)) bump();
|
|
4043
|
+
})
|
|
2310
4044
|
);
|
|
2311
4045
|
return () => {
|
|
4046
|
+
cancelled = true;
|
|
4047
|
+
const currentHandles = new Set(currentHandlesRef.current);
|
|
4048
|
+
for (const handle of subscribedHandles) {
|
|
4049
|
+
if (currentHandles.has(handle)) continue;
|
|
4050
|
+
gapSnapshots.set(handle, snapshot(handle.proxy.root));
|
|
4051
|
+
}
|
|
2312
4052
|
for (const unsubscribe of unsubscribes) unsubscribe();
|
|
2313
4053
|
};
|
|
2314
|
-
}, [sourcesKey(sources),
|
|
2315
|
-
useEffect(() => {
|
|
2316
|
-
let shouldBump = false;
|
|
2317
|
-
for (let index = 0; index < sources.length; index += 1) {
|
|
2318
|
-
const source = sources[index];
|
|
2319
|
-
const captured = versionsAtRender[index];
|
|
2320
|
-
if (source === void 0 || captured === void 0) continue;
|
|
2321
|
-
if (getVersion(source) !== captured) {
|
|
2322
|
-
boundary.evictChangedTargets();
|
|
2323
|
-
if (boundary.readsChanged(source)) shouldBump = true;
|
|
2324
|
-
}
|
|
2325
|
-
}
|
|
2326
|
-
if (shouldBump) bump();
|
|
2327
|
-
});
|
|
4054
|
+
}, [sourcesKey(sources), readTracker]);
|
|
2328
4055
|
return createElement(Component, renderedProps);
|
|
2329
4056
|
};
|
|
2330
4057
|
const baseName = Component.displayName ?? Component.name;
|
|
2331
4058
|
Scoped.displayName = `scope(${typeof baseName === "string" && baseName !== "" ? baseName : "Component"})`;
|
|
2332
4059
|
return memo(Scoped, arePropsEqual);
|
|
2333
4060
|
}
|
|
2334
|
-
function useGroup() {
|
|
2335
|
-
return useState(() => createGroup())[0];
|
|
4061
|
+
function useGroup(parent) {
|
|
4062
|
+
return useState(() => createGroup(parent))[0];
|
|
2336
4063
|
}
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
4064
|
+
var isObjectLike7 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
4065
|
+
function useMutableState(properties, options) {
|
|
4066
|
+
const [{ writeProxy, readTracker }] = useState(() => {
|
|
4067
|
+
const initial = typeof properties === "function" ? properties() : properties;
|
|
4068
|
+
return {
|
|
4069
|
+
writeProxy: createMutableState(initial, options),
|
|
4070
|
+
readTracker: createReadTracker()
|
|
4071
|
+
};
|
|
4072
|
+
});
|
|
2342
4073
|
const [, bump] = useReducer((value) => value + 1, 0);
|
|
2343
|
-
const
|
|
2344
|
-
|
|
2345
|
-
const
|
|
2346
|
-
|
|
2347
|
-
|
|
4074
|
+
const currentHandlesRef = useRef([]);
|
|
4075
|
+
const [gapSnapshots] = useState(() => /* @__PURE__ */ new WeakMap());
|
|
4076
|
+
const uniqueHandles = isObjectLike7(writeProxy) ? handlesOf(writeProxy) : [];
|
|
4077
|
+
readTracker.resetReads();
|
|
4078
|
+
const readProxy = isObjectLike7(writeProxy) ? readTracker.wrap(writeProxy) : writeProxy;
|
|
4079
|
+
for (const handle of uniqueHandles) {
|
|
4080
|
+
gapSnapshots.set(handle, snapshot(handle.proxy.root));
|
|
4081
|
+
}
|
|
4082
|
+
useCommitEffect(() => {
|
|
4083
|
+
currentHandlesRef.current = uniqueHandles;
|
|
4084
|
+
readTracker.captureReads();
|
|
2348
4085
|
});
|
|
2349
4086
|
useEffect(() => {
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
else boundary.advanceBaselines();
|
|
2354
|
-
};
|
|
2355
|
-
return subscribe(proxy2, onSignal, true);
|
|
2356
|
-
}, [proxy2, boundary]);
|
|
4087
|
+
readTracker.retain();
|
|
4088
|
+
return () => readTracker.dispose();
|
|
4089
|
+
}, [readTracker]);
|
|
2357
4090
|
useEffect(() => {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
4091
|
+
let cancelled = false;
|
|
4092
|
+
const subscribedHandles = isObjectLike7(writeProxy) ? handlesOf(writeProxy) : [];
|
|
4093
|
+
for (const handle of subscribedHandles) {
|
|
4094
|
+
const from = gapSnapshots.get(handle);
|
|
4095
|
+
if (from !== void 0 && readsIntersectDirty(readTracker, dirtySinceSnapshot(handle, from))) bump();
|
|
4096
|
+
}
|
|
4097
|
+
const unsubscribes = subscribedHandles.map(
|
|
4098
|
+
(handle) => subscribe2(handle.proxy.root, () => {
|
|
4099
|
+
if (cancelled) return;
|
|
4100
|
+
const dirty = handle.lastDirty;
|
|
4101
|
+
if (dirty !== void 0 && readsIntersectDirty(readTracker, dirty)) bump();
|
|
4102
|
+
})
|
|
4103
|
+
);
|
|
4104
|
+
return () => {
|
|
4105
|
+
cancelled = true;
|
|
4106
|
+
const currentHandles = new Set(currentHandlesRef.current);
|
|
4107
|
+
for (const handle of subscribedHandles) {
|
|
4108
|
+
if (currentHandles.has(handle)) continue;
|
|
4109
|
+
gapSnapshots.set(handle, snapshot(handle.proxy.root));
|
|
4110
|
+
}
|
|
4111
|
+
for (const unsubscribe of unsubscribes) unsubscribe();
|
|
4112
|
+
};
|
|
4113
|
+
}, [writeProxy, readTracker]);
|
|
4114
|
+
return readProxy;
|
|
2363
4115
|
}
|
|
2364
4116
|
|
|
2365
|
-
export { TrackedDate, TrackedMap, TrackedSet,
|
|
4117
|
+
export { TrackedDate, TrackedMap, TrackedSet, applyOperations, createChannel, createGroup, createMutableState, diffObjects, identify, ignore, isSameIdentity, isState, scope, subscribe2 as subscribe, transact, unsafeTrack, useGroup, useMutableState };
|