opshot 0.3.4 → 0.5.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 +43 -113
- package/dist/index.d.ts +156 -69
- package/dist/index.js +1105 -1789
- package/package.json +19 -12
package/dist/index.js
CHANGED
|
@@ -1,355 +1,62 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { memo, useState, useReducer, useRef, useEffect, createElement, useLayoutEffect } from 'react';
|
|
2
3
|
|
|
3
|
-
//
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
obj
|
|
4
|
+
// src/utils/constructorName.ts
|
|
5
|
+
var constructorName = (candidate) => typeof candidate === "function" && candidate.name !== "" ? candidate.name : "Object";
|
|
6
|
+
|
|
7
|
+
// src/boundaryErrors.ts
|
|
8
|
+
var ignoreOption = "ignore(value) to store it by reference, untracked";
|
|
9
|
+
var unsafeTrackDataOption = "unsafeTrack(value) to track its data anyway";
|
|
10
|
+
var unsafeTrackPrivateOption = "unsafeTrack(value) tracks public fields while private methods stay untracked";
|
|
11
|
+
var unsafeTrackSlotOption = "unsafeTrack(value) tracks public fields while slot methods stay untracked";
|
|
12
|
+
var unsafeTrackLossyOption = "unsafeTrack(value) to track it lossily";
|
|
13
|
+
var locationClause = (path) => path === void 0 || path.length === 0 ? "" : ` at /${path.join("/")}`;
|
|
14
|
+
var boundaryError = (className, reason, options, path) => new Error(
|
|
15
|
+
`opshot: ${className}${locationClause(path)} cannot be tracked (${reason}). Options:
|
|
16
|
+
${options.map((option) => `- ${option}`).join("\n")}`
|
|
17
17
|
);
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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;
|
|
18
|
+
var slotContainerError = (className, trackedName, path) => boundaryError(
|
|
19
|
+
className,
|
|
20
|
+
"its state lives in internal slots",
|
|
21
|
+
[`use ${trackedName} for a tracked equivalent`, unsafeTrackLossyOption, ignoreOption],
|
|
22
|
+
path
|
|
23
|
+
);
|
|
24
|
+
var arraySubclassError = (className, path) => boundaryError(className, "array subclasses are not plain arrays", [unsafeTrackDataOption, ignoreOption], path);
|
|
25
|
+
var cleanClassError = (className, path) => boundaryError(className, "arrow-method writes won't be tracked", [unsafeTrackDataOption, ignoreOption], path);
|
|
26
|
+
var privateClassError = (className, path) => boundaryError(className, "its state is hidden in private fields", [unsafeTrackPrivateOption, ignoreOption], path);
|
|
27
|
+
var nativeClassError = (className, path) => boundaryError(className, "its state is hidden in internal slots", [unsafeTrackSlotOption, ignoreOption], path);
|
|
28
|
+
var nonWritablePropertyError = (value, path) => boundaryError(
|
|
29
|
+
constructorName(value.constructor),
|
|
30
|
+
"a non-writable property's interior is silently mutable and untracked",
|
|
31
|
+
["make the property writable", "ignore(value) to declare the escape"],
|
|
32
|
+
path
|
|
33
|
+
);
|
|
34
|
+
var inheritsFromPrototype = (value, prototype) => {
|
|
35
|
+
for (let current = Reflect.getPrototypeOf(value); current !== null; current = Reflect.getPrototypeOf(current))
|
|
36
|
+
if (current === prototype) return true;
|
|
37
|
+
return false;
|
|
66
38
|
};
|
|
67
|
-
var
|
|
68
|
-
|
|
69
|
-
|
|
39
|
+
var rejectionError = (value, kind, path) => {
|
|
40
|
+
const className = constructorName(value.constructor);
|
|
41
|
+
if (inheritsFromPrototype(value, Map.prototype)) return slotContainerError(className, "TrackedMap", path);
|
|
42
|
+
if (inheritsFromPrototype(value, Set.prototype)) return slotContainerError(className, "TrackedSet", path);
|
|
43
|
+
if (inheritsFromPrototype(value, Date.prototype)) return slotContainerError(className, "TrackedDate", path);
|
|
44
|
+
switch (kind) {
|
|
45
|
+
case "arraySubclass":
|
|
46
|
+
return arraySubclassError(className, path);
|
|
47
|
+
case "cleanClass":
|
|
48
|
+
return cleanClassError(className, path);
|
|
49
|
+
case "privateClass":
|
|
50
|
+
return privateClassError(className, path);
|
|
51
|
+
case "nativeClass":
|
|
52
|
+
return nativeClassError(className, path);
|
|
70
53
|
}
|
|
71
|
-
return null;
|
|
72
|
-
};
|
|
73
|
-
var markToTrack = (obj, mark = true) => {
|
|
74
|
-
objectsToTrack.set(obj, mark);
|
|
75
54
|
};
|
|
76
55
|
|
|
77
|
-
//
|
|
78
|
-
var
|
|
79
|
-
var canProxyDefault = (x) => isObject2(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
|
-
var createSnapshotDefault = (target, version) => {
|
|
81
|
-
const cache = snapCache.get(target);
|
|
82
|
-
if ((cache == null ? void 0 : cache[0]) === version) {
|
|
83
|
-
return cache[1];
|
|
84
|
-
}
|
|
85
|
-
const snap = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target));
|
|
86
|
-
markToTrack(snap, true);
|
|
87
|
-
snapCache.set(target, [version, snap]);
|
|
88
|
-
Reflect.ownKeys(target).forEach((key) => {
|
|
89
|
-
if (Object.getOwnPropertyDescriptor(snap, key)) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
const value = Reflect.get(target, key);
|
|
93
|
-
const { enumerable } = Reflect.getOwnPropertyDescriptor(
|
|
94
|
-
target,
|
|
95
|
-
key
|
|
96
|
-
);
|
|
97
|
-
const desc = {
|
|
98
|
-
value,
|
|
99
|
-
enumerable,
|
|
100
|
-
// This is intentional to avoid copying with proxy-compare.
|
|
101
|
-
// It's still non-writable, so it avoids assigning a value.
|
|
102
|
-
configurable: true
|
|
103
|
-
};
|
|
104
|
-
if (refSet.has(value)) {
|
|
105
|
-
markToTrack(value, false);
|
|
106
|
-
} else if (proxyStateMap.has(value)) {
|
|
107
|
-
const [target2, ensureVersion] = proxyStateMap.get(
|
|
108
|
-
value
|
|
109
|
-
);
|
|
110
|
-
desc.value = createSnapshotDefault(target2, ensureVersion());
|
|
111
|
-
}
|
|
112
|
-
Object.defineProperty(snap, key, desc);
|
|
113
|
-
});
|
|
114
|
-
return snap;
|
|
115
|
-
};
|
|
116
|
-
var createHandlerDefault = (isInitializing, addPropListener, removePropListener, notifyUpdate) => ({
|
|
117
|
-
deleteProperty(target, prop) {
|
|
118
|
-
Reflect.get(target, prop);
|
|
119
|
-
removePropListener(prop);
|
|
120
|
-
const deleted = Reflect.deleteProperty(target, prop);
|
|
121
|
-
if (deleted) {
|
|
122
|
-
notifyUpdate(void 0 );
|
|
123
|
-
}
|
|
124
|
-
return deleted;
|
|
125
|
-
},
|
|
126
|
-
set(target, prop, value, receiver) {
|
|
127
|
-
const hasPrevValue = !isInitializing() && Reflect.has(target, prop);
|
|
128
|
-
const prevValue = Reflect.get(target, prop, receiver);
|
|
129
|
-
if (hasPrevValue && (objectIs(prevValue, value) || proxyCache.has(value) && objectIs(prevValue, proxyCache.get(value)))) {
|
|
130
|
-
return true;
|
|
131
|
-
}
|
|
132
|
-
removePropListener(prop);
|
|
133
|
-
if (isObject2(value)) {
|
|
134
|
-
value = getUntracked(value) || value;
|
|
135
|
-
}
|
|
136
|
-
const nextValue = !proxyStateMap.has(value) && canProxy(value) ? proxy(value) : value;
|
|
137
|
-
addPropListener(prop, nextValue);
|
|
138
|
-
Reflect.set(target, prop, nextValue, receiver);
|
|
139
|
-
notifyUpdate(void 0 );
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
var proxyStateMap = /* @__PURE__ */ new WeakMap();
|
|
144
|
-
var refSet = /* @__PURE__ */ new WeakSet();
|
|
145
|
-
var snapCache = /* @__PURE__ */ new WeakMap();
|
|
146
|
-
var versionHolder = [1];
|
|
147
|
-
var proxyCache = /* @__PURE__ */ new WeakMap();
|
|
148
|
-
var objectIs = Object.is;
|
|
149
|
-
var newProxy = (target, handler) => new Proxy(target, handler);
|
|
150
|
-
var canProxy = canProxyDefault;
|
|
151
|
-
var createSnapshot = createSnapshotDefault;
|
|
152
|
-
var createHandler = createHandlerDefault;
|
|
153
|
-
function proxy(baseObject = {}) {
|
|
154
|
-
if (!isObject2(baseObject)) {
|
|
155
|
-
throw new Error("object required");
|
|
156
|
-
}
|
|
157
|
-
const found = proxyCache.get(baseObject);
|
|
158
|
-
if (found) {
|
|
159
|
-
return found;
|
|
160
|
-
}
|
|
161
|
-
let version = versionHolder[0];
|
|
162
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
163
|
-
const notifyUpdate = (op, nextVersion = ++versionHolder[0]) => {
|
|
164
|
-
if (version !== nextVersion) {
|
|
165
|
-
checkVersion = version = nextVersion;
|
|
166
|
-
listeners.forEach((listener) => listener(op, nextVersion));
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
let checkVersion = version;
|
|
170
|
-
const ensureVersion = (nextCheckVersion = versionHolder[0]) => {
|
|
171
|
-
if (checkVersion !== nextCheckVersion) {
|
|
172
|
-
checkVersion = nextCheckVersion;
|
|
173
|
-
propProxyStates.forEach(([propProxyState]) => {
|
|
174
|
-
const propVersion = propProxyState[1](nextCheckVersion);
|
|
175
|
-
if (propVersion > version) {
|
|
176
|
-
version = propVersion;
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
return version;
|
|
181
|
-
};
|
|
182
|
-
const createPropListener = (prop) => (op, nextVersion) => {
|
|
183
|
-
let newOp;
|
|
184
|
-
if (op) {
|
|
185
|
-
newOp = [...op];
|
|
186
|
-
newOp[1] = [prop, ...newOp[1]];
|
|
187
|
-
}
|
|
188
|
-
notifyUpdate(newOp, nextVersion);
|
|
189
|
-
};
|
|
190
|
-
const propProxyStates = /* @__PURE__ */ new Map();
|
|
191
|
-
const addPropListener = (prop, propValue) => {
|
|
192
|
-
const propProxyState = !refSet.has(propValue) && proxyStateMap.get(propValue);
|
|
193
|
-
if (propProxyState) {
|
|
194
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && propProxyStates.has(prop)) {
|
|
195
|
-
throw new Error("prop listener already exists");
|
|
196
|
-
}
|
|
197
|
-
if (listeners.size) {
|
|
198
|
-
const remove = propProxyState[2](createPropListener(prop));
|
|
199
|
-
propProxyStates.set(prop, [propProxyState, remove]);
|
|
200
|
-
} else {
|
|
201
|
-
propProxyStates.set(prop, [propProxyState]);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
const removePropListener = (prop) => {
|
|
206
|
-
var _a;
|
|
207
|
-
const entry = propProxyStates.get(prop);
|
|
208
|
-
if (entry) {
|
|
209
|
-
propProxyStates.delete(prop);
|
|
210
|
-
(_a = entry[1]) == null ? void 0 : _a.call(entry);
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
const addListener = (listener) => {
|
|
214
|
-
listeners.add(listener);
|
|
215
|
-
if (listeners.size === 1) {
|
|
216
|
-
propProxyStates.forEach(([propProxyState, prevRemove], prop) => {
|
|
217
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && prevRemove) {
|
|
218
|
-
throw new Error("remove already exists");
|
|
219
|
-
}
|
|
220
|
-
const remove = propProxyState[2](createPropListener(prop));
|
|
221
|
-
propProxyStates.set(prop, [propProxyState, remove]);
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
const removeListener = () => {
|
|
225
|
-
listeners.delete(listener);
|
|
226
|
-
if (listeners.size === 0) {
|
|
227
|
-
propProxyStates.forEach(([propProxyState, remove], prop) => {
|
|
228
|
-
if (remove) {
|
|
229
|
-
remove();
|
|
230
|
-
propProxyStates.set(prop, [propProxyState]);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
return removeListener;
|
|
236
|
-
};
|
|
237
|
-
let initializing = true;
|
|
238
|
-
const handler = createHandler(
|
|
239
|
-
() => initializing,
|
|
240
|
-
addPropListener,
|
|
241
|
-
removePropListener,
|
|
242
|
-
notifyUpdate
|
|
243
|
-
);
|
|
244
|
-
const proxyObject = newProxy(baseObject, handler);
|
|
245
|
-
proxyCache.set(baseObject, proxyObject);
|
|
246
|
-
const proxyState = [baseObject, ensureVersion, addListener];
|
|
247
|
-
proxyStateMap.set(proxyObject, proxyState);
|
|
248
|
-
Reflect.ownKeys(baseObject).forEach((key) => {
|
|
249
|
-
const desc = Object.getOwnPropertyDescriptor(
|
|
250
|
-
baseObject,
|
|
251
|
-
key
|
|
252
|
-
);
|
|
253
|
-
if ("value" in desc && desc.writable) {
|
|
254
|
-
proxyObject[key] = baseObject[key];
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
initializing = false;
|
|
258
|
-
return proxyObject;
|
|
259
|
-
}
|
|
260
|
-
function getVersion(proxyObject) {
|
|
261
|
-
const proxyState = proxyStateMap.get(proxyObject);
|
|
262
|
-
return proxyState == null ? void 0 : proxyState[1]();
|
|
263
|
-
}
|
|
264
|
-
function subscribe(proxyObject, callback, notifyInSync) {
|
|
265
|
-
const proxyState = proxyStateMap.get(proxyObject);
|
|
266
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !proxyState) {
|
|
267
|
-
console.warn("Please use proxy object");
|
|
268
|
-
}
|
|
269
|
-
let promise;
|
|
270
|
-
const ops = [];
|
|
271
|
-
const addListener = proxyState[2];
|
|
272
|
-
let isListenerActive = false;
|
|
273
|
-
const listener = (op) => {
|
|
274
|
-
if (op) {
|
|
275
|
-
ops.push(op);
|
|
276
|
-
}
|
|
277
|
-
if (notifyInSync) {
|
|
278
|
-
callback(ops.splice(0));
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
if (!promise) {
|
|
282
|
-
promise = Promise.resolve().then(() => {
|
|
283
|
-
promise = void 0;
|
|
284
|
-
if (isListenerActive) {
|
|
285
|
-
callback(ops.splice(0));
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
const removeListener = addListener(listener);
|
|
291
|
-
isListenerActive = true;
|
|
292
|
-
return () => {
|
|
293
|
-
isListenerActive = false;
|
|
294
|
-
removeListener();
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
function snapshot(proxyObject) {
|
|
298
|
-
const proxyState = proxyStateMap.get(proxyObject);
|
|
299
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !proxyState) {
|
|
300
|
-
console.warn("Please use proxy object");
|
|
301
|
-
}
|
|
302
|
-
const [target, ensureVersion] = proxyState;
|
|
303
|
-
return createSnapshot(target, ensureVersion());
|
|
304
|
-
}
|
|
305
|
-
function ref(obj) {
|
|
306
|
-
refSet.add(obj);
|
|
307
|
-
return obj;
|
|
308
|
-
}
|
|
309
|
-
function unstable_getInternalStates() {
|
|
310
|
-
return {
|
|
311
|
-
proxyStateMap,
|
|
312
|
-
refSet,
|
|
313
|
-
snapCache,
|
|
314
|
-
versionHolder,
|
|
315
|
-
proxyCache
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
function unstable_replaceInternalFunction(name, fn) {
|
|
319
|
-
switch (name) {
|
|
320
|
-
case "objectIs":
|
|
321
|
-
objectIs = fn(objectIs);
|
|
322
|
-
break;
|
|
323
|
-
case "newProxy":
|
|
324
|
-
newProxy = fn(newProxy);
|
|
325
|
-
break;
|
|
326
|
-
case "canProxy":
|
|
327
|
-
canProxy = fn(canProxy);
|
|
328
|
-
break;
|
|
329
|
-
case "createSnapshot":
|
|
330
|
-
createSnapshot = fn(createSnapshot);
|
|
331
|
-
break;
|
|
332
|
-
case "createHandler":
|
|
333
|
-
createHandler = fn(createHandler);
|
|
334
|
-
break;
|
|
335
|
-
default:
|
|
336
|
-
throw new Error("unknown function");
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// src/unsafeTrack.ts
|
|
341
|
-
var unsafeTrackedSet = /* @__PURE__ */ new WeakSet();
|
|
342
|
-
function unsafeTrack(value) {
|
|
343
|
-
unsafeTrackedSet.add(value);
|
|
344
|
-
return value;
|
|
345
|
-
}
|
|
346
|
-
function isUnsafeTracked(value) {
|
|
347
|
-
return typeof value === "object" && value !== null && unsafeTrackedSet.has(value);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// src/valtio/classify.ts
|
|
351
|
-
var { refSet: refSet2 } = unstable_getInternalStates();
|
|
56
|
+
// src/classify.ts
|
|
57
|
+
var isDangerousKind = (kind) => kind !== "plain" && kind !== "plainArray" && kind !== "cleanClass";
|
|
352
58
|
var sourceCache = /* @__PURE__ */ new WeakMap();
|
|
59
|
+
var kindCache = /* @__PURE__ */ new WeakMap();
|
|
353
60
|
var readSource = (constructor) => {
|
|
354
61
|
const cached = sourceCache.get(constructor);
|
|
355
62
|
if (cached !== void 0) return cached;
|
|
@@ -357,16 +64,31 @@ var readSource = (constructor) => {
|
|
|
357
64
|
sourceCache.set(constructor, source);
|
|
358
65
|
return source;
|
|
359
66
|
};
|
|
67
|
+
var privateNameAccess = /\.\s*#[A-Za-z_$]/;
|
|
68
|
+
var privateNameDeclaration = new RegExp(
|
|
69
|
+
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|$))`,
|
|
70
|
+
"m"
|
|
71
|
+
);
|
|
72
|
+
var hasPrivateName = (source) => privateNameAccess.test(source) || privateNameDeclaration.test(source);
|
|
360
73
|
var classifyChain = (initialConstructor) => {
|
|
74
|
+
if (typeof initialConstructor !== "function") return "cleanClass";
|
|
75
|
+
const cached = kindCache.get(initialConstructor);
|
|
76
|
+
if (cached !== void 0) return cached;
|
|
361
77
|
let sawNativeSource = false;
|
|
362
78
|
let current = initialConstructor;
|
|
79
|
+
let kind = "cleanClass";
|
|
363
80
|
while (typeof current === "function" && current !== Object && current !== Array && current !== Function.prototype) {
|
|
364
81
|
const source = readSource(current);
|
|
365
|
-
if (source
|
|
82
|
+
if (hasPrivateName(source)) {
|
|
83
|
+
kind = "privateClass";
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
366
86
|
if (source.includes("[native code]")) sawNativeSource = true;
|
|
367
87
|
current = Reflect.getPrototypeOf(current);
|
|
368
88
|
}
|
|
369
|
-
|
|
89
|
+
if (kind !== "privateClass") kind = sawNativeSource ? "nativeClass" : "cleanClass";
|
|
90
|
+
kindCache.set(initialConstructor, kind);
|
|
91
|
+
return kind;
|
|
370
92
|
};
|
|
371
93
|
function classifyValue(value) {
|
|
372
94
|
const prototype = Object.getPrototypeOf(value);
|
|
@@ -375,1164 +97,581 @@ function classifyValue(value) {
|
|
|
375
97
|
if (prototype === Object.prototype || prototype === null) return "plain";
|
|
376
98
|
return classifyChain(value.constructor);
|
|
377
99
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
100
|
+
|
|
101
|
+
// src/node.ts
|
|
102
|
+
var byRaw = /* @__PURE__ */ new WeakMap();
|
|
103
|
+
var byProxy = /* @__PURE__ */ new WeakMap();
|
|
104
|
+
var proxyHandler;
|
|
105
|
+
function installProxyHandler(handler2) {
|
|
106
|
+
proxyHandler = handler2;
|
|
385
107
|
}
|
|
386
|
-
function
|
|
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";
|
|
108
|
+
function recordOf(value) {
|
|
109
|
+
return byRaw.get(value) ?? byProxy.get(value);
|
|
395
110
|
}
|
|
396
|
-
function
|
|
397
|
-
return
|
|
111
|
+
function rawOf(value) {
|
|
112
|
+
return recordOf(value)?.raw ?? value;
|
|
398
113
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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
|
-
// src/ops/cloneValue.ts
|
|
416
|
-
var { refSet: refSet3 } = unstable_getInternalStates();
|
|
417
|
-
var isPlainArray = (value) => Array.isArray(value) && !refSet3.has(value);
|
|
418
|
-
var isPlainObject = (value) => isTrackable(value) && !Array.isArray(value);
|
|
419
|
-
var isCloneable = (value) => isTrackable(value);
|
|
420
|
-
var CyclicValueError = class extends Error {
|
|
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);
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
var cyclicError = (path) => new CyclicValueError(path);
|
|
428
|
-
var getCyclicPath = (error) => error instanceof CyclicValueError ? error.path : void 0;
|
|
429
|
-
var CLONE_IN_PROGRESS = /* @__PURE__ */ Symbol("opshot.cloneValue.inProgress");
|
|
430
|
-
var cloneValue = (value, memo2, path) => {
|
|
431
|
-
if (!isCloneable(value)) return value;
|
|
432
|
-
const cached = memo2.get(value);
|
|
433
|
-
if (cached === CLONE_IN_PROGRESS) throw cyclicError(path);
|
|
434
|
-
if (cached !== void 0) return cached;
|
|
435
|
-
memo2.set(value, CLONE_IN_PROGRESS);
|
|
436
|
-
const array = isPlainArray(value);
|
|
437
|
-
const clone = array ? [] : {};
|
|
438
|
-
Reflect.setPrototypeOf(clone, Reflect.getPrototypeOf(value));
|
|
439
|
-
for (const key of Reflect.ownKeys(value)) {
|
|
440
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
441
|
-
if (!descriptor) continue;
|
|
442
|
-
if ("value" in descriptor) {
|
|
443
|
-
Object.defineProperty(clone, key, {
|
|
444
|
-
...descriptor,
|
|
445
|
-
value: cloneValue(descriptor.value, memo2, path)
|
|
446
|
-
});
|
|
447
|
-
} else {
|
|
448
|
-
Object.defineProperty(clone, key, descriptor);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
memo2.set(value, clone);
|
|
452
|
-
if (isUnsafeTracked(value)) unsafeTrack(clone);
|
|
453
|
-
return clone;
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
// src/react/wrapperRegistry.ts
|
|
457
|
-
var wrapperTargets = /* @__PURE__ */ new WeakMap();
|
|
458
|
-
var registerWrapperTarget = (wrapper, target) => {
|
|
459
|
-
wrapperTargets.set(wrapper, target);
|
|
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);
|
|
114
|
+
function proxyOf(raw) {
|
|
115
|
+
const existing = recordOf(raw);
|
|
116
|
+
if (existing !== void 0) return existing.proxy;
|
|
117
|
+
if (proxyHandler === void 0) throw new Error("opshot: proxy handler is not installed");
|
|
118
|
+
const proxy = new Proxy(raw, proxyHandler);
|
|
119
|
+
const record = { raw, proxy, memberships: /* @__PURE__ */ new Map() };
|
|
120
|
+
byRaw.set(raw, record);
|
|
121
|
+
byProxy.set(proxy, record);
|
|
122
|
+
return proxy;
|
|
470
123
|
}
|
|
471
|
-
function
|
|
472
|
-
return
|
|
124
|
+
function handlesOf(node) {
|
|
125
|
+
return membershipsOf(node).map(([handle]) => handle);
|
|
473
126
|
}
|
|
474
|
-
function
|
|
475
|
-
const
|
|
476
|
-
if (
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
return
|
|
127
|
+
function membershipsOf(node) {
|
|
128
|
+
const record = recordOf(rawOf(node));
|
|
129
|
+
if (record === void 0) return [];
|
|
130
|
+
const memberships = new Array();
|
|
131
|
+
for (const [handle, membership] of record.memberships) {
|
|
132
|
+
if (membership.edges > 0) memberships.push([handle, membership]);
|
|
133
|
+
}
|
|
134
|
+
return memberships;
|
|
482
135
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
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;
|
|
136
|
+
|
|
137
|
+
// src/ignore.ts
|
|
138
|
+
var ignored = /* @__PURE__ */ new WeakSet();
|
|
139
|
+
function ignore(value, on = true) {
|
|
140
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") return value;
|
|
141
|
+
if (on) ignored.add(rawOf(value));
|
|
142
|
+
else ignored.delete(rawOf(value));
|
|
143
|
+
return value;
|
|
508
144
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
145
|
+
var isIgnored = (value) => ignored.has(rawOf(value));
|
|
146
|
+
|
|
147
|
+
// src/unsafeTrack.ts
|
|
148
|
+
var unsafeMarked = /* @__PURE__ */ new WeakSet();
|
|
149
|
+
function unsafeTrack(value, on = true) {
|
|
150
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") return value;
|
|
151
|
+
if (on) unsafeMarked.add(rawOf(value));
|
|
152
|
+
else unsafeMarked.delete(rawOf(value));
|
|
153
|
+
return value;
|
|
513
154
|
}
|
|
155
|
+
var isUnsafeMarked = (value) => unsafeMarked.has(rawOf(value));
|
|
514
156
|
|
|
515
|
-
// src/
|
|
516
|
-
var
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
};
|
|
523
|
-
Object.defineProperty(OperationHalf.prototype, operationBrand, { value: true });
|
|
524
|
-
var ValueHalf = class extends OperationHalf {
|
|
525
|
-
get value() {
|
|
526
|
-
return cloneValue(valueOriginals.get(this), /* @__PURE__ */ new WeakMap(), this.path);
|
|
527
|
-
}
|
|
528
|
-
constructor(path, value) {
|
|
529
|
-
super(path);
|
|
530
|
-
valueOriginals.set(this, value);
|
|
531
|
-
if (!isCloneable(value)) Object.defineProperty(this, "value", { value, enumerable: true });
|
|
532
|
-
}
|
|
533
|
-
};
|
|
534
|
-
var AddHalf = class extends ValueHalf {
|
|
535
|
-
constructor() {
|
|
536
|
-
super(...arguments);
|
|
537
|
-
this.op = "add";
|
|
538
|
-
}
|
|
539
|
-
};
|
|
540
|
-
var ReplaceHalf = class extends ValueHalf {
|
|
541
|
-
constructor() {
|
|
542
|
-
super(...arguments);
|
|
543
|
-
this.op = "replace";
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
var RemoveHalf = class extends OperationHalf {
|
|
547
|
-
constructor() {
|
|
548
|
-
super(...arguments);
|
|
549
|
-
this.op = "remove";
|
|
157
|
+
// src/utils/dataEntries.ts
|
|
158
|
+
var walkDataEntries = (value) => {
|
|
159
|
+
const entries = new Array();
|
|
160
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
161
|
+
if (typeof key !== "string" || key === "__proto__") continue;
|
|
162
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
163
|
+
if (descriptor === void 0 || !descriptor.enumerable || !("value" in descriptor)) continue;
|
|
164
|
+
entries.push({ key, value: descriptor.value, writable: descriptor.writable === true });
|
|
550
165
|
}
|
|
166
|
+
return entries;
|
|
551
167
|
};
|
|
552
|
-
var isOperation = (value) => typeof value === "object" && value !== null && operationBrand in value;
|
|
553
|
-
var getValueOriginal = (half) => valueOriginals.get(half);
|
|
554
|
-
var createAddOperation = (path, value) => new AddHalf(path, value);
|
|
555
|
-
var createReplaceOperation = (path, value) => new ReplaceHalf(path, value);
|
|
556
|
-
var createRemoveOperation = (path) => new RemoveHalf(path);
|
|
557
168
|
|
|
558
|
-
// src/
|
|
559
|
-
var
|
|
560
|
-
var
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
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;
|
|
169
|
+
// src/edges.ts
|
|
170
|
+
var isTrackedEntry = (value, writable) => writable && typeof value === "object" && value !== null && !isIgnored(value) && !Object.isFrozen(value);
|
|
171
|
+
var checkNode = (node, entries, route) => {
|
|
172
|
+
const kind = classifyValue(node);
|
|
173
|
+
if (isDangerousKind(kind)) throw rejectionError(node, kind, route);
|
|
174
|
+
for (const entry of entries) {
|
|
175
|
+
if (typeof entry.value === "function") {
|
|
176
|
+
if (kind === "cleanClass") throw rejectionError(node, "cleanClass", [...route, entry.key]);
|
|
177
|
+
continue;
|
|
588
178
|
}
|
|
179
|
+
if (typeof entry.value !== "object" || entry.value === null) continue;
|
|
180
|
+
if (isIgnored(entry.value) || Object.isFrozen(entry.value)) continue;
|
|
181
|
+
if (!entry.writable) throw nonWritablePropertyError(node, [...route, entry.key]);
|
|
589
182
|
}
|
|
590
183
|
};
|
|
591
|
-
var
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
// src/ops/diff.ts
|
|
598
|
-
var UNCAPPED_WEIGHT = Number.MAX_SAFE_INTEGER;
|
|
599
|
-
var IncompatibleSnapshotRootsError = class extends Error {
|
|
600
|
-
constructor() {
|
|
601
|
-
super("opshot: diffSnapshots requires compatible supported object roots");
|
|
602
|
-
this.name = "IncompatibleSnapshotRootsError";
|
|
184
|
+
var descend = (handle, node, route, checked) => {
|
|
185
|
+
const entries = walkDataEntries(node);
|
|
186
|
+
if (checked) checkNode(node, entries, route);
|
|
187
|
+
for (const entry of entries) {
|
|
188
|
+
if (isTrackedEntry(entry.value, entry.writable))
|
|
189
|
+
attach(handle, node, entry.key, entry.value, [...route, entry.key]);
|
|
603
190
|
}
|
|
604
191
|
};
|
|
605
|
-
var
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
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;
|
|
642
|
-
};
|
|
643
|
-
var hasAncestorPair = (ancestors, before, after) => ancestors.get(before)?.has(after) ?? false;
|
|
644
|
-
var enterAncestorPair = (ancestors, before, after) => {
|
|
645
|
-
const afterSet = ancestors.get(before) ?? /* @__PURE__ */ new Set();
|
|
646
|
-
afterSet.add(after);
|
|
647
|
-
ancestors.set(before, afterSet);
|
|
648
|
-
};
|
|
649
|
-
var exitAncestorPair = (ancestors, before, after) => {
|
|
650
|
-
const afterSet = ancestors.get(before);
|
|
651
|
-
if (!afterSet) return;
|
|
652
|
-
afterSet.delete(after);
|
|
653
|
-
if (afterSet.size === 0) ancestors.delete(before);
|
|
654
|
-
};
|
|
655
|
-
var isObjectLike2 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
656
|
-
var sharesStorageIdentity = (before, after) => isObjectLike2(before) && isObjectLike2(after) && isSameIdentity(before, after);
|
|
657
|
-
var assertSafeSubtree = (value, path, activeAncestors = /* @__PURE__ */ new WeakSet()) => {
|
|
658
|
-
if (!isPlainArray(value) && !isPlainObject(value)) return;
|
|
659
|
-
if (activeAncestors.has(value)) return;
|
|
660
|
-
activeAncestors.add(value);
|
|
661
|
-
try {
|
|
662
|
-
for (const key of Object.keys(value)) {
|
|
663
|
-
const nextPath = appendOperationPath(path, key);
|
|
664
|
-
assertSafePath(nextPath);
|
|
665
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
666
|
-
if (descriptor && "value" in descriptor) assertSafeSubtree(descriptor.value, nextPath, activeAncestors);
|
|
667
|
-
}
|
|
668
|
-
} finally {
|
|
669
|
-
activeAncestors.delete(value);
|
|
192
|
+
var flip = (handle, node, route) => {
|
|
193
|
+
const membership = recordOf(node)?.memberships.get(handle);
|
|
194
|
+
if (!membership?.exempt) return;
|
|
195
|
+
membership.exempt = false;
|
|
196
|
+
const entries = walkDataEntries(node);
|
|
197
|
+
checkNode(node, entries, route);
|
|
198
|
+
for (const entry of entries) {
|
|
199
|
+
if (!isTrackedEntry(entry.value, entry.writable)) continue;
|
|
200
|
+
const child = rawOf(entry.value);
|
|
201
|
+
if (recordOf(child)?.memberships.has(handle) === true) flip(handle, child, [...route, entry.key]);
|
|
670
202
|
}
|
|
671
203
|
};
|
|
672
|
-
var
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
return weight;
|
|
696
|
-
};
|
|
697
|
-
var diffArray = (before, after, path, ops, ancestors) => {
|
|
698
|
-
const overlap = Math.min(before.length, after.length);
|
|
699
|
-
let weight = 0;
|
|
700
|
-
for (let index = 0; index < overlap; index++) {
|
|
701
|
-
const beforePresent = Object.hasOwn(before, index);
|
|
702
|
-
const afterPresent = Object.hasOwn(after, index);
|
|
703
|
-
const nextPath = appendOperationPath(path, index);
|
|
704
|
-
if (!beforePresent && !afterPresent) continue;
|
|
705
|
-
if (!beforePresent) weight += pushAdd(ops, nextPath, after[index]);
|
|
706
|
-
else if (!afterPresent) weight += pushRemove(ops, nextPath, before[index]);
|
|
707
|
-
else weight += diffValue(before[index], after[index], nextPath, ops, ancestors);
|
|
708
|
-
}
|
|
709
|
-
if (after.length > before.length) {
|
|
710
|
-
weight += pushReplace(ops, appendOperationPath(path, "length"), before.length, after.length);
|
|
711
|
-
for (let index = before.length; index < after.length; index++) {
|
|
712
|
-
if (Object.hasOwn(after, index)) weight += pushAdd(ops, appendOperationPath(path, index), after[index]);
|
|
713
|
-
}
|
|
714
|
-
} else if (after.length < before.length) {
|
|
715
|
-
for (let index = after.length; index < before.length; index++) {
|
|
716
|
-
if (Object.hasOwn(before, index)) weight += pushRemove(ops, appendOperationPath(path, index), before[index]);
|
|
717
|
-
}
|
|
718
|
-
weight += pushReplace(ops, appendOperationPath(path, "length"), before.length, after.length);
|
|
204
|
+
var cascade = (handle, node, keys) => {
|
|
205
|
+
for (const key of keys) {
|
|
206
|
+
const value = Reflect.get(node, key);
|
|
207
|
+
if (typeof value !== "object" || value === null) continue;
|
|
208
|
+
const child = rawOf(value);
|
|
209
|
+
if (recordOf(child)?.memberships.has(handle) === true) detach(handle, child);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
function attach(handle, parent, key, child, route) {
|
|
213
|
+
const parentMembership = recordOf(parent)?.memberships.get(handle);
|
|
214
|
+
if (parentMembership === void 0) return;
|
|
215
|
+
parentMembership.keys.add(key);
|
|
216
|
+
const rawChild = rawOf(child);
|
|
217
|
+
proxyOf(rawChild);
|
|
218
|
+
const record = recordOf(rawChild);
|
|
219
|
+
if (record === void 0) return;
|
|
220
|
+
const edgeExempt = parentMembership.exempt || isUnsafeMarked(rawChild);
|
|
221
|
+
const membership = record.memberships.get(handle);
|
|
222
|
+
if (membership === void 0) {
|
|
223
|
+
record.memberships.set(handle, { edges: 1, exempt: edgeExempt, keys: /* @__PURE__ */ new Set() });
|
|
224
|
+
descend(handle, rawChild, route, !edgeExempt);
|
|
225
|
+
return;
|
|
719
226
|
}
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
227
|
+
membership.edges += 1;
|
|
228
|
+
if (membership.exempt && !edgeExempt) flip(handle, rawChild, route);
|
|
229
|
+
}
|
|
230
|
+
function attachRoot(handle, root, exempt) {
|
|
231
|
+
const record = recordOf(root);
|
|
232
|
+
if (record === void 0) return;
|
|
233
|
+
record.memberships.set(handle, { edges: 1, exempt, keys: /* @__PURE__ */ new Set() });
|
|
726
234
|
try {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
const opsStart = ops.length;
|
|
732
|
-
const atomicWeight = walk();
|
|
733
|
-
return tryCollapse(before, after, path, ops, opsStart, atomicWeight);
|
|
734
|
-
} finally {
|
|
735
|
-
exitAncestorPair(ancestors, before, after);
|
|
736
|
-
}
|
|
737
|
-
};
|
|
738
|
-
var diffValue = (before, after, path, ops, ancestors) => {
|
|
739
|
-
if (Object.is(before, after)) return 0;
|
|
740
|
-
if (path.length > 0 && isObjectLike2(before) && isObjectLike2(after) && !sharesStorageIdentity(before, after)) {
|
|
741
|
-
assertSafeSubtree(before, path);
|
|
742
|
-
assertSafeSubtree(after, path);
|
|
743
|
-
return pushReplace(ops, path, before, after);
|
|
744
|
-
}
|
|
745
|
-
if (isPlainArray(before) && isPlainArray(after)) {
|
|
746
|
-
return walkContainer(before, after, path, ops, ancestors, () => diffArray(before, after, path, ops, ancestors));
|
|
747
|
-
}
|
|
748
|
-
if (isPlainObject(before) && isPlainObject(after)) {
|
|
749
|
-
return walkContainer(
|
|
750
|
-
before,
|
|
751
|
-
after,
|
|
752
|
-
path,
|
|
753
|
-
ops,
|
|
754
|
-
ancestors,
|
|
755
|
-
() => diffObjectProperties(before, after, path, ops, ancestors, false)
|
|
756
|
-
);
|
|
235
|
+
descend(handle, root, [], !exempt);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
evict(handle, root);
|
|
238
|
+
throw error;
|
|
757
239
|
}
|
|
758
|
-
assertSafeSubtree(before, path);
|
|
759
|
-
assertSafeSubtree(after, path);
|
|
760
|
-
return pushReplace(ops, path, before, after);
|
|
761
|
-
};
|
|
762
|
-
var getRootKind = (value) => {
|
|
763
|
-
if (isPlainArray(value)) return "plainArray";
|
|
764
|
-
if (isPlainObject(value)) return "plainObject";
|
|
765
|
-
return void 0;
|
|
766
|
-
};
|
|
767
|
-
function diffSnapshots(before, after) {
|
|
768
|
-
const beforeKind = getRootKind(before);
|
|
769
|
-
const afterKind = getRootKind(after);
|
|
770
|
-
if (beforeKind === void 0 || beforeKind !== afterKind) throw new IncompatibleSnapshotRootsError();
|
|
771
|
-
const ops = new Array();
|
|
772
|
-
diffValue(before, after, createOperationPath([]), ops, /* @__PURE__ */ new Map());
|
|
773
|
-
return ops;
|
|
774
240
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
// src/emit/resolveEmitterTarget.ts
|
|
785
|
-
var { proxyStateMap: proxyStateMap3 } = unstable_getInternalStates();
|
|
786
|
-
var isObjectLike3 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
787
|
-
function resolveEmitterTarget(state) {
|
|
788
|
-
let current = state;
|
|
789
|
-
while (isObjectLike3(current)) {
|
|
790
|
-
if (proxyStateMap3.has(current)) return current;
|
|
791
|
-
const peeled = peelIdentityLayer(current);
|
|
792
|
-
if (peeled === void 0) break;
|
|
793
|
-
current = peeled;
|
|
794
|
-
}
|
|
795
|
-
if (!isObjectLike3(current) || !proxyStateMap3.has(current)) throw new Error("opshot: expected a state object");
|
|
796
|
-
return current;
|
|
241
|
+
function detach(handle, child) {
|
|
242
|
+
const rawChild = rawOf(child);
|
|
243
|
+
const record = recordOf(rawChild);
|
|
244
|
+
const membership = record?.memberships.get(handle);
|
|
245
|
+
if (record === void 0 || membership === void 0) return;
|
|
246
|
+
membership.edges -= 1;
|
|
247
|
+
if (membership.edges > 0) return;
|
|
248
|
+
record.memberships.delete(handle);
|
|
249
|
+
cascade(handle, rawChild, membership.keys);
|
|
797
250
|
}
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
function getOrCreateEmitter(target, groupListeners) {
|
|
806
|
-
const resolved = resolveEmitterTarget(target);
|
|
807
|
-
const existing = emitters.get(resolved);
|
|
808
|
-
if (existing !== void 0) return existing;
|
|
809
|
-
const record = {
|
|
810
|
-
listeners: /* @__PURE__ */ new Map(),
|
|
811
|
-
groupListeners,
|
|
812
|
-
lastReported: snapshot(resolved),
|
|
813
|
-
isMutating: false,
|
|
814
|
-
target: resolved
|
|
815
|
-
};
|
|
816
|
-
emitters.set(resolved, record);
|
|
817
|
-
return record;
|
|
818
|
-
}
|
|
819
|
-
function deleteEmitter(target) {
|
|
820
|
-
emitters.delete(target);
|
|
251
|
+
function evict(handle, node) {
|
|
252
|
+
const rawNode = rawOf(node);
|
|
253
|
+
const record = recordOf(rawNode);
|
|
254
|
+
const membership = record?.memberships.get(handle);
|
|
255
|
+
if (record === void 0 || membership === void 0) return;
|
|
256
|
+
record.memberships.delete(handle);
|
|
257
|
+
cascade(handle, rawNode, membership.keys);
|
|
821
258
|
}
|
|
822
259
|
|
|
823
|
-
// src/
|
|
824
|
-
|
|
825
|
-
const
|
|
826
|
-
|
|
827
|
-
return
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
};
|
|
831
|
-
var requireObjectSnapshot = (value) => {
|
|
832
|
-
if (value !== null && (typeof value === "object" || typeof value === "function")) return value;
|
|
833
|
-
throw new Error("opshot: state snapshots must have an object root");
|
|
834
|
-
};
|
|
835
|
-
var armWatchdog = (record) => {
|
|
836
|
-
if (record.disarm !== void 0) return;
|
|
837
|
-
record.lastReported = snapshot(record.target);
|
|
838
|
-
record.disarm = subscribe(record.target, () => {
|
|
839
|
-
emitBareFlush(record.target);
|
|
840
|
-
});
|
|
841
|
-
};
|
|
842
|
-
var disarmWatchdog = (record) => {
|
|
843
|
-
record.disarm?.();
|
|
844
|
-
record.disarm = void 0;
|
|
845
|
-
};
|
|
846
|
-
var reportBareDiff = (record) => {
|
|
847
|
-
const current = snapshot(record.target);
|
|
848
|
-
if (current === record.lastReported) return;
|
|
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;
|
|
260
|
+
// src/handle.ts
|
|
261
|
+
function handleOf(state) {
|
|
262
|
+
const raw = rawOf(state);
|
|
263
|
+
const record = recordOf(raw);
|
|
264
|
+
if (record === void 0) return void 0;
|
|
265
|
+
for (const handle of record.memberships.keys()) {
|
|
266
|
+
if (handle.root === raw) return handle;
|
|
858
267
|
}
|
|
859
|
-
|
|
860
|
-
var settlePendingBare = (record) => {
|
|
861
|
-
reportBareDiff(record);
|
|
862
|
-
};
|
|
863
|
-
function emitBareFlush(target) {
|
|
864
|
-
const record = getEmitter(target);
|
|
865
|
-
if (record === void 0) return;
|
|
866
|
-
reportBareDiff(record);
|
|
268
|
+
return void 0;
|
|
867
269
|
}
|
|
868
|
-
function
|
|
869
|
-
const
|
|
870
|
-
|
|
871
|
-
return
|
|
270
|
+
function requireHandle(state, message) {
|
|
271
|
+
const handle = handleOf(state);
|
|
272
|
+
if (handle === void 0) throw new Error(message);
|
|
273
|
+
return handle;
|
|
872
274
|
}
|
|
873
275
|
|
|
874
|
-
// src/
|
|
875
|
-
var
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
${options.map((option) => `- ${option}`).join("\n")}`
|
|
886
|
-
);
|
|
887
|
-
var slotContainerError = (className, trackedName) => boundaryError(className, "its state lives in internal slots", [
|
|
888
|
-
`use ${trackedName} for a tracked equivalent`,
|
|
889
|
-
unsafeTrackLossyOption,
|
|
890
|
-
ignoreOption
|
|
891
|
-
]);
|
|
892
|
-
var arraySubclassError = (className) => boundaryError(className, "array subclasses lose their prototype in snapshots", [
|
|
893
|
-
unsafeTrackDataOption,
|
|
894
|
-
ignoreOption
|
|
895
|
-
]);
|
|
896
|
-
var cleanClassError = (className) => boundaryError(className, "arrow-method writes won't be tracked", [unsafeTrackDataOption, ignoreOption]);
|
|
897
|
-
var privateClassError = (className) => boundaryError(className, "its state is hidden in private fields", [unsafeTrackPrivateOption, ignoreOption]);
|
|
898
|
-
var nativeClassError = (className) => boundaryError(className, "its state is hidden in internal slots", [unsafeTrackSlotOption, ignoreOption]);
|
|
899
|
-
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 applyOps.`
|
|
901
|
-
);
|
|
902
|
-
var reservedDataPathError = (path) => new Error(`opshot: reserved data path /${path.join("/")}`);
|
|
903
|
-
var inheritsFromPrototype = (value, prototype) => {
|
|
904
|
-
for (let current = Reflect.getPrototypeOf(value); current !== null; current = Reflect.getPrototypeOf(current))
|
|
905
|
-
if (current === prototype) return true;
|
|
906
|
-
return false;
|
|
907
|
-
};
|
|
908
|
-
var rejectionError = (value, kind) => {
|
|
909
|
-
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");
|
|
913
|
-
switch (kind) {
|
|
914
|
-
case "arraySubclass":
|
|
915
|
-
return arraySubclassError(className);
|
|
916
|
-
case "cleanClass":
|
|
917
|
-
return cleanClassError(className);
|
|
918
|
-
case "privateClass":
|
|
919
|
-
return privateClassError(className);
|
|
920
|
-
case "nativeClass":
|
|
921
|
-
return nativeClassError(className);
|
|
276
|
+
// src/batch.ts
|
|
277
|
+
var metaStack = [];
|
|
278
|
+
function currentMeta() {
|
|
279
|
+
return metaStack.length === 0 ? void 0 : metaStack[metaStack.length - 1];
|
|
280
|
+
}
|
|
281
|
+
function batch(callback, meta) {
|
|
282
|
+
metaStack.push(meta);
|
|
283
|
+
try {
|
|
284
|
+
callback();
|
|
285
|
+
} finally {
|
|
286
|
+
metaStack.pop();
|
|
922
287
|
}
|
|
923
|
-
}
|
|
288
|
+
}
|
|
924
289
|
|
|
925
|
-
// src/
|
|
926
|
-
var
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
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;
|
|
290
|
+
// src/emit/emitterDeliver.ts
|
|
291
|
+
var runDelivery = (pending, failures) => {
|
|
292
|
+
for (const deliver of pending.deliveries) {
|
|
293
|
+
try {
|
|
294
|
+
deliver(pending.operations);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
failures.push(error);
|
|
996
297
|
}
|
|
997
|
-
graphs.push(graph);
|
|
998
298
|
}
|
|
999
|
-
if (references.size === 0) rootGraphsByTarget.delete(target);
|
|
1000
|
-
return graphs;
|
|
1001
299
|
};
|
|
1002
|
-
var
|
|
1003
|
-
|
|
1004
|
-
if (
|
|
1005
|
-
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
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);
|
|
300
|
+
var raiseFailures = (failures) => {
|
|
301
|
+
if (failures.length === 0) return;
|
|
302
|
+
if (failures.length > 1) throw new AggregateError(failures, "opshot: listeners failed during delivery");
|
|
303
|
+
throw failures[0];
|
|
1056
304
|
};
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
var
|
|
1060
|
-
var
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
}
|
|
1067
|
-
const snap = Array.isArray(target) ? [] : Object.create(Reflect.getPrototypeOf(target));
|
|
1068
|
-
registerSnapshotCopy(snap, target);
|
|
1069
|
-
markToTrack(snap, true);
|
|
1070
|
-
snapCache2.set(target, [version, snap]);
|
|
1071
|
-
for (const key of Reflect.ownKeys(target)) {
|
|
1072
|
-
if (Object.getOwnPropertyDescriptor(snap, key)) continue;
|
|
1073
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
1074
|
-
if (!descriptor) continue;
|
|
1075
|
-
if (descriptor.get || descriptor.set) {
|
|
1076
|
-
Object.defineProperty(snap, key, {
|
|
1077
|
-
get: descriptor.get,
|
|
1078
|
-
set: descriptor.set,
|
|
1079
|
-
enumerable: descriptor.enumerable,
|
|
1080
|
-
configurable: true
|
|
1081
|
-
});
|
|
1082
|
-
continue;
|
|
1083
|
-
}
|
|
1084
|
-
const value = Reflect.get(target, key);
|
|
1085
|
-
const snapshotDescriptor = { value, enumerable: descriptor.enumerable, configurable: true };
|
|
1086
|
-
if (typeof value === "object" && value !== null) {
|
|
1087
|
-
if (refSet5.has(value)) {
|
|
1088
|
-
markToTrack(value, false);
|
|
1089
|
-
} else {
|
|
1090
|
-
const childState = proxyStateMap4.get(value);
|
|
1091
|
-
if (childState)
|
|
1092
|
-
snapshotDescriptor.value = createSnapshotPreservingAccessors(childState[0], childState[1]());
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
Object.defineProperty(snap, key, snapshotDescriptor);
|
|
1096
|
-
}
|
|
1097
|
-
if (Array.isArray(target) && snap.length !== target.length) {
|
|
1098
|
-
snap.length = target.length;
|
|
1099
|
-
}
|
|
1100
|
-
if (isUnsafeTracked(target)) unsafeTrack(snap);
|
|
1101
|
-
return snap;
|
|
305
|
+
var queuedDeliveries = [];
|
|
306
|
+
var deliveryFailures = [];
|
|
307
|
+
var isDraining = false;
|
|
308
|
+
var prepareDelivery = (handle, operations) => ({
|
|
309
|
+
deliveries: [...handle.subscribers.values()],
|
|
310
|
+
operations
|
|
311
|
+
});
|
|
312
|
+
var enqueueDelivery = (pending) => {
|
|
313
|
+
queuedDeliveries.push(pending);
|
|
1102
314
|
};
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
activeAncestors.add(value);
|
|
315
|
+
var drainDeliveries = () => {
|
|
316
|
+
if (isDraining) return;
|
|
317
|
+
isDraining = true;
|
|
318
|
+
let failures = [];
|
|
1108
319
|
try {
|
|
1109
|
-
|
|
1110
|
-
const
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
1114
|
-
if (descriptor && "value" in descriptor) assertSafeDataPaths(descriptor.value, nextPath, activeAncestors);
|
|
320
|
+
while (queuedDeliveries.length > 0) {
|
|
321
|
+
for (const queued of queuedDeliveries.splice(0, queuedDeliveries.length)) {
|
|
322
|
+
runDelivery(queued, deliveryFailures);
|
|
323
|
+
}
|
|
1115
324
|
}
|
|
1116
325
|
} finally {
|
|
1117
|
-
|
|
326
|
+
isDraining = false;
|
|
327
|
+
failures = deliveryFailures.splice(0, deliveryFailures.length);
|
|
1118
328
|
}
|
|
329
|
+
raiseFailures(failures);
|
|
1119
330
|
};
|
|
1120
|
-
var installed = false;
|
|
1121
|
-
function installBoundary() {
|
|
1122
|
-
if (installed) return;
|
|
1123
|
-
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
|
-
});
|
|
1132
|
-
unstable_replaceInternalFunction("createSnapshot", () => createSnapshotPreservingAccessors);
|
|
1133
|
-
unstable_replaceInternalFunction(
|
|
1134
|
-
"createHandler",
|
|
1135
|
-
(createHandler2) => (isInitializing, addPropListener, removePropListener, notifyUpdate) => {
|
|
1136
|
-
let setDepth = 0;
|
|
1137
|
-
const handler = createHandler2(isInitializing, addPropListener, removePropListener, notifyUpdate);
|
|
1138
|
-
const defaultDelete = handler.deleteProperty;
|
|
1139
|
-
const defaultSet = handler.set;
|
|
1140
|
-
if (!defaultDelete || !defaultSet)
|
|
1141
|
-
throw new Error("opshot: valtio default handler is missing a mutation trap");
|
|
1142
|
-
return {
|
|
1143
|
-
...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
|
-
set(target, prop, value, receiver) {
|
|
1154
|
-
const assigned = value;
|
|
1155
|
-
if (prop === "__proto__") throw reservedDataPathError(["__proto__"]);
|
|
1156
|
-
if (prop === "prototype" && constructorPathTargetCount(target) > 0)
|
|
1157
|
-
throw reservedDataPathError(["constructor", "prototype"]);
|
|
1158
|
-
if (prop === "constructor" && typeof assigned === "object" && assigned !== null) {
|
|
1159
|
-
const prototypeDescriptor = Reflect.getOwnPropertyDescriptor(assigned, "prototype");
|
|
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;
|
|
1171
|
-
try {
|
|
1172
|
-
const written = defaultSet(target, prop, value, receiver);
|
|
1173
|
-
const currentChild = rootGraphs.length > 0 ? getEnumerableDataChild(target, prop) : void 0;
|
|
1174
|
-
const currentLength = previousLength === void 0 ? void 0 : Reflect.get(target, "length");
|
|
1175
|
-
if (previousChild !== currentChild || previousLength !== currentLength)
|
|
1176
|
-
for (const graph of rootGraphs) recomputeRootGraph(graph);
|
|
1177
|
-
return written;
|
|
1178
|
-
} finally {
|
|
1179
|
-
setDepth -= 1;
|
|
1180
|
-
}
|
|
1181
|
-
},
|
|
1182
|
-
defineProperty(target, prop, descriptor) {
|
|
1183
|
-
if (setDepth > 0 || isInitializing()) return Reflect.defineProperty(target, prop, descriptor);
|
|
1184
|
-
throw new Error(
|
|
1185
|
-
"opshot: defineProperty is not supported on tracked state; define properties in the createMutableState input"
|
|
1186
|
-
);
|
|
1187
|
-
},
|
|
1188
|
-
setPrototypeOf() {
|
|
1189
|
-
throw new Error("opshot: setPrototypeOf is not supported on tracked state");
|
|
1190
|
-
}
|
|
1191
|
-
};
|
|
1192
|
-
}
|
|
1193
|
-
);
|
|
1194
|
-
}
|
|
1195
331
|
|
|
1196
|
-
// src/
|
|
1197
|
-
function
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
// src/createGroup.ts
|
|
1211
|
-
var groupListenersByGroup = /* @__PURE__ */ new WeakMap();
|
|
1212
|
-
function isGroup(value) {
|
|
1213
|
-
return typeof value === "object" && value !== null && groupListenersByGroup.has(value);
|
|
1214
|
-
}
|
|
1215
|
-
function getGroupListeners(group) {
|
|
1216
|
-
const listeners = groupListenersByGroup.get(group);
|
|
1217
|
-
if (listeners === void 0) throw new Error("opshot: unknown group");
|
|
1218
|
-
return listeners;
|
|
1219
|
-
}
|
|
1220
|
-
function createGroup() {
|
|
1221
|
-
const listeners = /* @__PURE__ */ new Map();
|
|
1222
|
-
const group = {
|
|
1223
|
-
createMutableState(properties) {
|
|
1224
|
-
return createMutableState(properties, group);
|
|
1225
|
-
}
|
|
1226
|
-
};
|
|
1227
|
-
groupListenersByGroup.set(group, listeners);
|
|
1228
|
-
return group;
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
// src/emit/emitterListeners.ts
|
|
1232
|
-
function addStateListener(state, listener, channelId, deliver2) {
|
|
1233
|
-
const target = resolveEmitterTarget(state);
|
|
1234
|
-
const record = getOrCreateEmitter(target);
|
|
1235
|
-
if (record.disarm === void 0 && record.groupListeners === void 0) {
|
|
1236
|
-
armWatchdog(record);
|
|
1237
|
-
}
|
|
1238
|
-
let byChannel = record.listeners.get(listener);
|
|
1239
|
-
if (byChannel === void 0) {
|
|
1240
|
-
byChannel = /* @__PURE__ */ new Map();
|
|
1241
|
-
record.listeners.set(listener, byChannel);
|
|
1242
|
-
}
|
|
1243
|
-
byChannel.set(channelId, deliver2);
|
|
1244
|
-
return () => {
|
|
1245
|
-
const channels = record.listeners.get(listener);
|
|
1246
|
-
if (channels?.has(channelId) !== true) return;
|
|
1247
|
-
settlePendingBare(record);
|
|
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
|
-
}
|
|
1254
|
-
};
|
|
1255
|
-
}
|
|
1256
|
-
function addGroupListener(groupListeners, listener, channelId, deliver2) {
|
|
1257
|
-
let byChannel = groupListeners.get(listener);
|
|
1258
|
-
if (byChannel === void 0) {
|
|
1259
|
-
byChannel = /* @__PURE__ */ new Map();
|
|
1260
|
-
groupListeners.set(listener, byChannel);
|
|
1261
|
-
}
|
|
1262
|
-
byChannel.set(channelId, deliver2);
|
|
1263
|
-
return () => {
|
|
1264
|
-
const channels = groupListeners.get(listener);
|
|
1265
|
-
if (channels?.has(channelId) !== true) return;
|
|
1266
|
-
channels.delete(channelId);
|
|
1267
|
-
if (channels.size === 0) groupListeners.delete(listener);
|
|
1268
|
-
};
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
// src/transact.ts
|
|
1272
|
-
function transact(state, mutate, meta) {
|
|
1273
|
-
const record = getEmitter(state);
|
|
1274
|
-
if (record === void 0) {
|
|
1275
|
-
mutate();
|
|
332
|
+
// src/emit/window.ts
|
|
333
|
+
function recordOperation(handle, raw, pending) {
|
|
334
|
+
let byKey = handle.pendingIndex.get(raw);
|
|
335
|
+
if (byKey === void 0) {
|
|
336
|
+
byKey = /* @__PURE__ */ new Map();
|
|
337
|
+
handle.pendingIndex.set(raw, byKey);
|
|
338
|
+
}
|
|
339
|
+
const index = byKey.get(pending.key);
|
|
340
|
+
const existing = index === void 0 ? void 0 : handle.pending[index];
|
|
341
|
+
if (existing !== void 0 && Object.is(existing.meta, pending.meta)) {
|
|
342
|
+
existing.after = pending.after;
|
|
343
|
+
existing.hasAfter = pending.hasAfter;
|
|
1276
344
|
return;
|
|
1277
345
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
if (!hasListeners(record)) return;
|
|
1291
|
-
const ops = diffSnapshots(requireObjectSnapshot(before), requireObjectSnapshot(after));
|
|
1292
|
-
if (ops.length === 0) return;
|
|
1293
|
-
deliver(record, ops, meta);
|
|
346
|
+
handle.pending.push(pending);
|
|
347
|
+
byKey.set(pending.key, handle.pending.length - 1);
|
|
348
|
+
if (handle.isFlushScheduled) return;
|
|
349
|
+
handle.isFlushScheduled = true;
|
|
350
|
+
const run = () => {
|
|
351
|
+
flush(handle);
|
|
352
|
+
};
|
|
353
|
+
void Promise.resolve().then(() => {
|
|
354
|
+
const emitOn = handle.emitOn;
|
|
355
|
+
if (emitOn === void 0) run();
|
|
356
|
+
else emitOn(run);
|
|
357
|
+
});
|
|
1294
358
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
var unresolvedError = (path) => new Error(`opshot: ${formatOperationPath(path)} does not resolve to a supported operation address`);
|
|
1311
|
-
var matchesAppliedValue = (current, expected) => {
|
|
1312
|
-
if (isObjectLike4(current) && isObjectLike4(expected)) return sameIdentity(current, expected);
|
|
1313
|
-
return Object.is(current, expected);
|
|
1314
|
-
};
|
|
1315
|
-
var setOrThrow = (target, key, value) => {
|
|
1316
|
-
const written = Reflect.set(target, key, value);
|
|
1317
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
1318
|
-
const current = descriptor && "value" in descriptor ? Reflect.get(target, key) : void 0;
|
|
1319
|
-
if (!written || !descriptor || !("value" in descriptor) || !matchesAppliedValue(current, value)) {
|
|
1320
|
-
throw new Error(`opshot: replay could not restore ${String(key)}`);
|
|
1321
|
-
}
|
|
1322
|
-
};
|
|
1323
|
-
var deleteOrThrow = (target, key) => {
|
|
1324
|
-
if (!Reflect.deleteProperty(target, key)) throw new Error(`opshot: replay could not remove ${String(key)}`);
|
|
1325
|
-
};
|
|
1326
|
-
var restoreRecordedContent = (attached, recorded, restored) => {
|
|
1327
|
-
if (restored.has(recorded)) return;
|
|
1328
|
-
restored.add(recorded);
|
|
1329
|
-
const recordedKeys = Reflect.ownKeys(recorded);
|
|
1330
|
-
const orderedKeys = Array.isArray(recorded) ? ["length", ...recordedKeys.filter((key) => key !== "length")] : recordedKeys;
|
|
1331
|
-
for (const key of orderedKeys) {
|
|
1332
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(recorded, key);
|
|
1333
|
-
const attachedDescriptor = Reflect.getOwnPropertyDescriptor(attached, key);
|
|
1334
|
-
if (!descriptor || !("value" in descriptor) || attachedDescriptor && !("value" in attachedDescriptor)) continue;
|
|
1335
|
-
const value = descriptor.value;
|
|
1336
|
-
if (isObjectLike4(value)) {
|
|
1337
|
-
const target = getRegisteredTarget(value);
|
|
1338
|
-
if (target !== void 0) {
|
|
1339
|
-
setOrThrow(attached, key, target);
|
|
1340
|
-
const child = Reflect.get(attached, key);
|
|
1341
|
-
if (!isObjectLike4(child)) throw new Error(`opshot: replay could not reattach ${String(key)}`);
|
|
1342
|
-
restoreRecordedContent(child, value, restored);
|
|
1343
|
-
continue;
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
setOrThrow(attached, key, value);
|
|
1347
|
-
}
|
|
1348
|
-
for (const key of Reflect.ownKeys(attached)) {
|
|
1349
|
-
if (Object.hasOwn(recorded, key)) continue;
|
|
1350
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(attached, key);
|
|
1351
|
-
if (descriptor && "value" in descriptor) deleteOrThrow(attached, key);
|
|
359
|
+
function flush(handle) {
|
|
360
|
+
handle.isFlushScheduled = false;
|
|
361
|
+
const pending = handle.pending.splice(0);
|
|
362
|
+
handle.pendingIndex.clear();
|
|
363
|
+
const operations = new Array();
|
|
364
|
+
for (const item of pending) {
|
|
365
|
+
if (item.hasBefore === item.hasAfter && (!item.hasBefore || Object.is(item.before, item.after))) continue;
|
|
366
|
+
const operation = {
|
|
367
|
+
node: item.node,
|
|
368
|
+
key: item.key,
|
|
369
|
+
meta: item.meta,
|
|
370
|
+
...item.hasBefore ? { before: item.before } : {},
|
|
371
|
+
...item.hasAfter ? { after: item.after } : {}
|
|
372
|
+
};
|
|
373
|
+
operations.push(Object.freeze(operation));
|
|
1352
374
|
}
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
return { recorded: operation.value, fallback: operation.value };
|
|
1362
|
-
};
|
|
1363
|
-
var restoreValue = (payload, attach, readAttached) => {
|
|
1364
|
-
if (isObjectLike4(payload.recorded)) {
|
|
1365
|
-
const target = getRegisteredTarget(payload.recorded);
|
|
1366
|
-
if (target !== void 0) {
|
|
1367
|
-
attach(target);
|
|
1368
|
-
const attached = readAttached();
|
|
1369
|
-
if (!isObjectLike4(attached)) throw new Error("opshot: replay could not read a reattached target");
|
|
1370
|
-
restoreRecordedContent(attached, payload.recorded, /* @__PURE__ */ new WeakSet());
|
|
1371
|
-
return;
|
|
375
|
+
const edges = /* @__PURE__ */ new Map();
|
|
376
|
+
const nodes = /* @__PURE__ */ new Set();
|
|
377
|
+
for (const operation of operations) {
|
|
378
|
+
const raw = rawOf(operation.node);
|
|
379
|
+
let keys = edges.get(raw);
|
|
380
|
+
if (keys === void 0) {
|
|
381
|
+
keys = /* @__PURE__ */ new Set();
|
|
382
|
+
edges.set(raw, keys);
|
|
1372
383
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
384
|
+
keys.add(operation.key);
|
|
385
|
+
nodes.add(raw);
|
|
386
|
+
}
|
|
387
|
+
const dirty = { edges, nodes };
|
|
388
|
+
handle.lastDirty = dirty;
|
|
389
|
+
if (operations.length === 0) return;
|
|
390
|
+
enqueueDelivery(prepareDelivery(handle, operations));
|
|
391
|
+
drainDeliveries();
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/utils/predicates.ts
|
|
395
|
+
var isObjectLike = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
396
|
+
|
|
397
|
+
// src/proxy.ts
|
|
398
|
+
var prototypeFunctionOf = (target, key) => {
|
|
399
|
+
for (let holder = Reflect.getPrototypeOf(target); holder !== null; holder = Reflect.getPrototypeOf(holder)) {
|
|
400
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(holder, key);
|
|
401
|
+
if (descriptor === void 0) continue;
|
|
402
|
+
const method = "value" in descriptor ? descriptor.value : void 0;
|
|
403
|
+
return typeof method === "function" ? method : void 0;
|
|
1382
404
|
}
|
|
1383
405
|
return void 0;
|
|
1384
406
|
};
|
|
1385
|
-
var
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
var requirePlainSegment = (parent, segment, path) => {
|
|
1391
|
-
if (Array.isArray(parent)) {
|
|
1392
|
-
if (isCanonicalArrayIndex2(segment)) return segment;
|
|
1393
|
-
if (typeof segment === "string" && !isCanonicalArrayIndexString(segment)) return segment;
|
|
1394
|
-
throw unresolvedError(path);
|
|
1395
|
-
}
|
|
1396
|
-
if (typeof segment === "string") return segment;
|
|
1397
|
-
throw unresolvedError(path);
|
|
407
|
+
var isRideAlongKey = (target, key) => {
|
|
408
|
+
if (key === "__proto__") return true;
|
|
409
|
+
if (key === "length") return false;
|
|
410
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
411
|
+
return descriptor?.enumerable === false;
|
|
1398
412
|
};
|
|
1399
|
-
var
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
413
|
+
var writesThroughAccessor = (target, property) => {
|
|
414
|
+
let holder = target;
|
|
415
|
+
while (holder !== null) {
|
|
416
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(holder, property);
|
|
417
|
+
if (descriptor !== void 0) return !("value" in descriptor);
|
|
418
|
+
holder = Reflect.getPrototypeOf(holder);
|
|
419
|
+
}
|
|
420
|
+
return false;
|
|
1405
421
|
};
|
|
1406
|
-
var
|
|
1407
|
-
|
|
1408
|
-
|
|
422
|
+
var proxied = (value) => isObjectLike(value) ? recordOf(value)?.proxy ?? value : value;
|
|
423
|
+
var truncatedOwnEntriesOf = (target, next) => {
|
|
424
|
+
if (!Array.isArray(target)) return [];
|
|
425
|
+
const coercible = next === null || typeof next !== "object" && typeof next !== "function";
|
|
426
|
+
const newLength = coercible ? Number(next) : Number.NaN;
|
|
427
|
+
if (!Number.isInteger(newLength) || newLength < 0 || newLength >= target.length) return [];
|
|
428
|
+
const truncated = new Array();
|
|
429
|
+
for (let index = newLength; index < target.length; index += 1) {
|
|
430
|
+
const key = String(index);
|
|
431
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
432
|
+
if (descriptor === void 0 || !("value" in descriptor)) continue;
|
|
433
|
+
truncated.push({
|
|
434
|
+
key,
|
|
435
|
+
value: descriptor.value,
|
|
436
|
+
writable: descriptor.writable === true
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
return truncated;
|
|
1409
440
|
};
|
|
1410
|
-
var
|
|
1411
|
-
|
|
1412
|
-
if (
|
|
1413
|
-
|
|
1414
|
-
for (let index = 0; index < path.length - 1; index++) parent = resolveTraversalSegment(parent, path[index], path);
|
|
1415
|
-
if (!isObjectLike4(parent)) throw unresolvedError(path);
|
|
1416
|
-
return { parent, segment: path[path.length - 1] };
|
|
441
|
+
var ownDataDescriptor = (target, key) => {
|
|
442
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
443
|
+
if (descriptor === void 0 || !("value" in descriptor)) return { hadPrevious: false, previous: void 0 };
|
|
444
|
+
return { hadPrevious: true, previous: descriptor.value };
|
|
1417
445
|
};
|
|
1418
|
-
var
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
446
|
+
var handler = {
|
|
447
|
+
get(target, key, receiver) {
|
|
448
|
+
const value = Reflect.get(target, key, receiver);
|
|
449
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
|
|
450
|
+
const locked = descriptor?.writable === false && descriptor.configurable === false;
|
|
451
|
+
if (locked || !isObjectLike(value)) return value;
|
|
452
|
+
if (typeof value === "function") {
|
|
453
|
+
const method = prototypeFunctionOf(target, key);
|
|
454
|
+
const kind = classifyValue(target);
|
|
455
|
+
if (method !== void 0 && value === method && (kind === "nativeClass" || kind === "privateClass")) {
|
|
456
|
+
const bound = Function.prototype.bind.call(method, target);
|
|
457
|
+
return typeof bound === "function" ? bound : value;
|
|
458
|
+
}
|
|
459
|
+
return value;
|
|
1423
460
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
const present = descriptor !== void 0 && descriptor.enumerable && "value" in descriptor;
|
|
1430
|
-
if (descriptor !== void 0 && !present) throw unresolvedError(path);
|
|
1431
|
-
if (operation.op === "add" && present) throw unresolvedError(path);
|
|
1432
|
-
if (operation.op !== "add" && !present) throw unresolvedError(path);
|
|
1433
|
-
if (operation.op === "add") {
|
|
1434
|
-
const inheritedDescriptor = getInheritedDescriptor(parent, key);
|
|
1435
|
-
if (inheritedDescriptor && !("value" in inheritedDescriptor)) {
|
|
1436
|
-
throw new Error(`opshot: ${formatOperationPath(path)} resolves to an inherited accessor`);
|
|
461
|
+
return recordOf(value)?.proxy ?? value;
|
|
462
|
+
},
|
|
463
|
+
set(target, key, value, receiver) {
|
|
464
|
+
if (typeof key !== "string" || writesThroughAccessor(target, key) || isRideAlongKey(target, key)) {
|
|
465
|
+
return Reflect.set(target, key, value, receiver);
|
|
1437
466
|
}
|
|
467
|
+
const { hadPrevious, previous } = ownDataDescriptor(target, key);
|
|
468
|
+
const resolved = isObjectLike(value) ? rawOf(value) : value;
|
|
469
|
+
const memberships = membershipsOf(target).map(([handle, membership]) => ({
|
|
470
|
+
handle,
|
|
471
|
+
membership,
|
|
472
|
+
hadKey: membership.keys.has(key)
|
|
473
|
+
}));
|
|
474
|
+
const truncated = key === "length" ? truncatedOwnEntriesOf(target, resolved) : [];
|
|
475
|
+
const previousLength = Array.isArray(target) ? target.length : void 0;
|
|
476
|
+
if (typeof resolved === "function" && memberships.some(({ membership }) => !membership.exempt)) {
|
|
477
|
+
const kind = classifyValue(target);
|
|
478
|
+
if (kind !== "plain" && kind !== "plainArray") throw rejectionError(target, kind, [key]);
|
|
479
|
+
}
|
|
480
|
+
const incoming = resolved !== previous && isTrackedEntry(resolved, true) ? resolved : void 0;
|
|
481
|
+
let rollBack;
|
|
482
|
+
if (incoming !== void 0) {
|
|
483
|
+
const started = new Array();
|
|
484
|
+
rollBack = () => {
|
|
485
|
+
for (const { handle, membership, hadKey } of started) {
|
|
486
|
+
detach(handle, incoming);
|
|
487
|
+
if (!hadKey) membership.keys.delete(key);
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
try {
|
|
491
|
+
for (const write of memberships) {
|
|
492
|
+
started.push(write);
|
|
493
|
+
attach(write.handle, target, key, incoming, [key]);
|
|
494
|
+
}
|
|
495
|
+
} catch (error) {
|
|
496
|
+
rollBack();
|
|
497
|
+
throw error;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
const result = Reflect.set(target, key, resolved, receiver);
|
|
501
|
+
if (!result) {
|
|
502
|
+
rollBack?.();
|
|
503
|
+
return result;
|
|
504
|
+
}
|
|
505
|
+
const meta = currentMeta();
|
|
506
|
+
const node = proxyOf(target);
|
|
507
|
+
for (const { handle, membership, hadKey } of memberships) {
|
|
508
|
+
for (const entry of truncated) {
|
|
509
|
+
if (membership.keys.delete(entry.key) && isObjectLike(entry.value)) detach(handle, entry.value);
|
|
510
|
+
recordOperation(handle, target, {
|
|
511
|
+
node,
|
|
512
|
+
key: entry.key,
|
|
513
|
+
meta,
|
|
514
|
+
before: proxied(entry.value),
|
|
515
|
+
hasBefore: true,
|
|
516
|
+
hasAfter: false
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
if (hadKey && previous !== resolved) {
|
|
520
|
+
if (isObjectLike(previous)) detach(handle, previous);
|
|
521
|
+
if (incoming === void 0) membership.keys.delete(key);
|
|
522
|
+
}
|
|
523
|
+
recordOperation(handle, target, {
|
|
524
|
+
node,
|
|
525
|
+
key,
|
|
526
|
+
meta,
|
|
527
|
+
before: proxied(previous),
|
|
528
|
+
after: proxied(resolved),
|
|
529
|
+
hasBefore: hadPrevious,
|
|
530
|
+
hasAfter: true
|
|
531
|
+
});
|
|
532
|
+
if (key !== "length" && Array.isArray(target) && previousLength !== target.length) {
|
|
533
|
+
recordOperation(handle, target, {
|
|
534
|
+
node,
|
|
535
|
+
key: "length",
|
|
536
|
+
meta,
|
|
537
|
+
before: previousLength,
|
|
538
|
+
after: target.length,
|
|
539
|
+
hasBefore: true,
|
|
540
|
+
hasAfter: true
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return result;
|
|
545
|
+
},
|
|
546
|
+
deleteProperty(target, key) {
|
|
547
|
+
if (typeof key !== "string" || isRideAlongKey(target, key)) return Reflect.deleteProperty(target, key);
|
|
548
|
+
const { hadPrevious, previous } = ownDataDescriptor(target, key);
|
|
549
|
+
const result = Reflect.deleteProperty(target, key);
|
|
550
|
+
if (!result || !hadPrevious) return result;
|
|
551
|
+
const meta = currentMeta();
|
|
552
|
+
const node = proxyOf(target);
|
|
553
|
+
for (const [handle, membership] of membershipsOf(target)) {
|
|
554
|
+
if (membership.keys.delete(key) && isObjectLike(previous)) detach(handle, previous);
|
|
555
|
+
recordOperation(handle, target, {
|
|
556
|
+
node,
|
|
557
|
+
key,
|
|
558
|
+
meta,
|
|
559
|
+
before: proxied(previous),
|
|
560
|
+
hasBefore: true,
|
|
561
|
+
hasAfter: false
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
return result;
|
|
565
|
+
},
|
|
566
|
+
preventExtensions(target) {
|
|
567
|
+
for (const [handle] of membershipsOf(target)) evict(handle, target);
|
|
568
|
+
return Reflect.preventExtensions(target);
|
|
569
|
+
},
|
|
570
|
+
defineProperty(target, key, descriptor) {
|
|
571
|
+
return Reflect.defineProperty(target, key, descriptor);
|
|
572
|
+
},
|
|
573
|
+
setPrototypeOf(target, prototype) {
|
|
574
|
+
return Reflect.setPrototypeOf(target, prototype);
|
|
575
|
+
},
|
|
576
|
+
has(target, key) {
|
|
577
|
+
return Reflect.has(target, key);
|
|
578
|
+
},
|
|
579
|
+
ownKeys(target) {
|
|
580
|
+
return Reflect.ownKeys(target);
|
|
581
|
+
},
|
|
582
|
+
getOwnPropertyDescriptor(target, key) {
|
|
583
|
+
return Reflect.getOwnPropertyDescriptor(target, key);
|
|
1438
584
|
}
|
|
1439
|
-
if (operation.op === "remove") {
|
|
1440
|
-
deleteOrThrow(parent, key);
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
if (!("value" in operation)) throw unresolvedError(path);
|
|
1444
|
-
restoreValue(
|
|
1445
|
-
getValuePayload(operation),
|
|
1446
|
-
(value) => setOrThrow(parent, key, value),
|
|
1447
|
-
() => Reflect.get(parent, key)
|
|
1448
|
-
);
|
|
1449
585
|
};
|
|
1450
|
-
function applyOperations(root, operations) {
|
|
1451
|
-
for (const operation of operations) {
|
|
1452
|
-
const terminal = resolveTerminal(root, operation.path);
|
|
1453
|
-
applyPlain(terminal.parent, terminal.segment, operation);
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
function applyOps(state, operations, meta) {
|
|
1457
|
-
for (const operation of operations) assertApplicable(operation);
|
|
1458
|
-
transact(
|
|
1459
|
-
state,
|
|
1460
|
-
() => {
|
|
1461
|
-
applyOperations(resolveEmitterTarget(state), operations);
|
|
1462
|
-
},
|
|
1463
|
-
meta
|
|
1464
|
-
);
|
|
1465
|
-
}
|
|
1466
586
|
|
|
1467
|
-
// src/
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
return meta;
|
|
1491
|
-
}
|
|
1492
|
-
function toChannelContext(channelId, defaults, meta) {
|
|
1493
|
-
if (isOwnChannelStamp(meta, channelId)) {
|
|
1494
|
-
return { isTransaction: true, meta: { ...defaults, ...meta.meta } };
|
|
1495
|
-
}
|
|
1496
|
-
return { isTransaction: false, meta: unwrapTransportMeta(meta) };
|
|
587
|
+
// src/createMutableState.ts
|
|
588
|
+
installProxyHandler(handler);
|
|
589
|
+
function createMutableState(properties, options) {
|
|
590
|
+
const incoming = properties;
|
|
591
|
+
if (typeof incoming !== "object" || incoming === null) return properties;
|
|
592
|
+
if (isIgnored(incoming)) return properties;
|
|
593
|
+
if (Object.isFrozen(incoming)) return properties;
|
|
594
|
+
const root = rawOf(incoming);
|
|
595
|
+
if (handleOf(incoming) !== void 0) return proxyOf(incoming);
|
|
596
|
+
const strict = options?.strict !== false;
|
|
597
|
+
const exempt = !strict || isUnsafeMarked(root);
|
|
598
|
+
const handle = {
|
|
599
|
+
root,
|
|
600
|
+
strict,
|
|
601
|
+
emitOn: options?.emitOn,
|
|
602
|
+
subscribers: /* @__PURE__ */ new Map(),
|
|
603
|
+
pending: [],
|
|
604
|
+
pendingIndex: /* @__PURE__ */ new Map(),
|
|
605
|
+
isFlushScheduled: false
|
|
606
|
+
};
|
|
607
|
+
const proxy = proxyOf(root);
|
|
608
|
+
attachRoot(handle, root, exempt);
|
|
609
|
+
return proxy;
|
|
1497
610
|
}
|
|
1498
611
|
|
|
1499
|
-
// src/
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
612
|
+
// src/identity.ts
|
|
613
|
+
var readProxyTargets = /* @__PURE__ */ new WeakMap();
|
|
614
|
+
var identityRecords = /* @__PURE__ */ new WeakMap();
|
|
615
|
+
var nextInternId = 0;
|
|
616
|
+
var registerReadProxyTarget = (readProxy, target) => {
|
|
617
|
+
readProxyTargets.set(readProxy, target);
|
|
618
|
+
};
|
|
619
|
+
var getRegisteredReadProxyTarget = (readProxy) => readProxyTargets.get(readProxy);
|
|
620
|
+
function resolveIdentity(value) {
|
|
621
|
+
let current = value;
|
|
622
|
+
while (isObjectLike(current)) {
|
|
623
|
+
const readTarget = getRegisteredReadProxyTarget(current);
|
|
624
|
+
if (readTarget !== void 0 && readTarget !== current) {
|
|
625
|
+
current = readTarget;
|
|
626
|
+
continue;
|
|
1514
627
|
}
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
628
|
+
const raw = rawOf(current);
|
|
629
|
+
if (raw !== current) {
|
|
630
|
+
current = raw;
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
break;
|
|
1521
634
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
635
|
+
return current;
|
|
636
|
+
}
|
|
637
|
+
var recordFor = (key) => {
|
|
638
|
+
let record = identityRecords.get(key);
|
|
639
|
+
if (record === void 0) {
|
|
640
|
+
record = {};
|
|
641
|
+
identityRecords.set(key, record);
|
|
1524
642
|
}
|
|
1525
|
-
return
|
|
643
|
+
return record;
|
|
644
|
+
};
|
|
645
|
+
function identify(value) {
|
|
646
|
+
const target = resolveIdentity(value);
|
|
647
|
+
if (!isObjectLike(target)) return value;
|
|
648
|
+
const record = recordFor(target);
|
|
649
|
+
if (record.token !== void 0) return record.token;
|
|
650
|
+
const token = Object.freeze({});
|
|
651
|
+
record.token = token;
|
|
652
|
+
return token;
|
|
653
|
+
}
|
|
654
|
+
var internIdentity = (key) => {
|
|
655
|
+
const resolved = resolveIdentity(key);
|
|
656
|
+
const record = recordFor(resolved);
|
|
657
|
+
if (record.id !== void 0) return record.id;
|
|
658
|
+
const id = nextInternId;
|
|
659
|
+
nextInternId += 1;
|
|
660
|
+
record.id = id;
|
|
661
|
+
return id;
|
|
662
|
+
};
|
|
663
|
+
function isSameIdentity(first, second) {
|
|
664
|
+
const resolvedFirst = resolveIdentity(first);
|
|
665
|
+
const resolvedSecond = resolveIdentity(second);
|
|
666
|
+
return resolvedFirst === resolvedSecond;
|
|
1526
667
|
}
|
|
1527
668
|
|
|
1528
|
-
// src/
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
function unwrapWrapper(value) {
|
|
1532
|
-
if (!isObjectLike5(value) || proxyStateMap5.has(value)) return value;
|
|
669
|
+
// src/peelReadProxy.ts
|
|
670
|
+
function peelReadProxy(value) {
|
|
671
|
+
if (!isObjectLike(value)) return value;
|
|
1533
672
|
let current = value;
|
|
1534
|
-
while (
|
|
1535
|
-
const registeredTarget =
|
|
673
|
+
while (isObjectLike(current)) {
|
|
674
|
+
const registeredTarget = getRegisteredReadProxyTarget(current);
|
|
1536
675
|
if (registeredTarget === void 0) break;
|
|
1537
676
|
current = registeredTarget;
|
|
1538
677
|
}
|
|
@@ -1540,32 +679,32 @@ function unwrapWrapper(value) {
|
|
|
1540
679
|
}
|
|
1541
680
|
|
|
1542
681
|
// src/isState.ts
|
|
1543
|
-
var { proxyStateMap: proxyStateMap6 } = unstable_getInternalStates();
|
|
1544
682
|
function isState(value) {
|
|
1545
|
-
const resolved =
|
|
683
|
+
const resolved = peelReadProxy(value);
|
|
1546
684
|
if (typeof resolved !== "object" || resolved === null) return false;
|
|
1547
|
-
return
|
|
685
|
+
return recordOf(resolved)?.proxy === resolved;
|
|
1548
686
|
}
|
|
1549
687
|
|
|
1550
|
-
// src/ignore.ts
|
|
1551
|
-
var ignore = ref;
|
|
1552
|
-
|
|
1553
688
|
// src/tracked/facadeGuard.ts
|
|
1554
689
|
var assertMutableFacade = (facade, mutationKey) => {
|
|
1555
|
-
const facadeSource = getUntracked(facade);
|
|
1556
|
-
const isRegisteredCopy = getRegisteredTarget(facade) !== void 0 || facadeSource !== null && getRegisteredTarget(facadeSource) !== void 0;
|
|
1557
690
|
const descriptor = Reflect.getOwnPropertyDescriptor(facade, mutationKey);
|
|
1558
|
-
if (
|
|
1559
|
-
throw new Error("opshot: cannot mutate a tracked collection
|
|
691
|
+
if (descriptor !== void 0 && "writable" in descriptor && !descriptor.writable) {
|
|
692
|
+
throw new Error("opshot: cannot mutate a non-writable tracked collection");
|
|
1560
693
|
}
|
|
1561
694
|
};
|
|
1562
695
|
|
|
1563
696
|
// src/tracked/trackedDate.ts
|
|
697
|
+
var DateSetYearError = class extends Error {
|
|
698
|
+
constructor(message) {
|
|
699
|
+
super(message);
|
|
700
|
+
this.name = "DateSetYearError";
|
|
701
|
+
}
|
|
702
|
+
};
|
|
1564
703
|
var setLegacyYear = (date, year) => {
|
|
1565
704
|
const setYear = Reflect.get(date, "setYear");
|
|
1566
|
-
if (typeof setYear !== "function") throw new
|
|
705
|
+
if (typeof setYear !== "function") throw new DateSetYearError("opshot: Date.setYear is not available");
|
|
1567
706
|
const epochMs = Reflect.apply(setYear, date, [year]);
|
|
1568
|
-
if (typeof epochMs !== "number") throw new
|
|
707
|
+
if (typeof epochMs !== "number") throw new DateSetYearError("opshot: Date.setYear returned a non-number");
|
|
1569
708
|
return epochMs;
|
|
1570
709
|
};
|
|
1571
710
|
var constructDate = (args) => {
|
|
@@ -1588,14 +727,21 @@ var constructDate = (args) => {
|
|
|
1588
727
|
return new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
1589
728
|
}
|
|
1590
729
|
};
|
|
730
|
+
var MAX_TIME = 864e13;
|
|
731
|
+
var clipTime = (epochMs) => {
|
|
732
|
+
if (!Number.isFinite(epochMs) || Math.abs(epochMs) > MAX_TIME) return Number.NaN;
|
|
733
|
+
return Math.trunc(epochMs) + 0;
|
|
734
|
+
};
|
|
1591
735
|
var TrackedDate = class {
|
|
1592
736
|
constructor(...args) {
|
|
1593
|
-
installBoundary();
|
|
1594
737
|
this.epochMs = constructDate(args).getTime();
|
|
1595
738
|
}
|
|
1596
739
|
readDate() {
|
|
1597
740
|
return new Date(this.epochMs);
|
|
1598
741
|
}
|
|
742
|
+
readEpochMs() {
|
|
743
|
+
return clipTime(this.epochMs);
|
|
744
|
+
}
|
|
1599
745
|
write(mutate) {
|
|
1600
746
|
assertMutableFacade(this, "epochMs");
|
|
1601
747
|
const epochMs = mutate(this.readDate());
|
|
@@ -1621,10 +767,10 @@ var TrackedDate = class {
|
|
|
1621
767
|
return this.readDate().toLocaleTimeString(locales, options);
|
|
1622
768
|
}
|
|
1623
769
|
valueOf() {
|
|
1624
|
-
return this.
|
|
770
|
+
return this.readEpochMs();
|
|
1625
771
|
}
|
|
1626
772
|
getTime() {
|
|
1627
|
-
return this.
|
|
773
|
+
return this.readEpochMs();
|
|
1628
774
|
}
|
|
1629
775
|
getFullYear() {
|
|
1630
776
|
return this.readDate().getFullYear();
|
|
@@ -1738,8 +884,8 @@ var TrackedDate = class {
|
|
|
1738
884
|
return this.readDate().toISOString();
|
|
1739
885
|
}
|
|
1740
886
|
[Symbol.toPrimitive](hint) {
|
|
1741
|
-
|
|
1742
|
-
return
|
|
887
|
+
if (hint === "number") return this.readEpochMs();
|
|
888
|
+
return this.readDate()[Symbol.toPrimitive](hint);
|
|
1743
889
|
}
|
|
1744
890
|
};
|
|
1745
891
|
Object.defineProperty(TrackedDate.prototype, Symbol.toStringTag, {
|
|
@@ -1750,19 +896,11 @@ Object.defineProperty(TrackedDate.prototype, Symbol.toStringTag, {
|
|
|
1750
896
|
});
|
|
1751
897
|
|
|
1752
898
|
// 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");
|
|
899
|
+
var UnsupportedKeyTypeError = class extends Error {
|
|
900
|
+
constructor(key) {
|
|
901
|
+
super(`opshot: addressOf received unsupported key type ${typeof key}`);
|
|
902
|
+
this.name = "UnsupportedKeyTypeError";
|
|
1759
903
|
}
|
|
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
904
|
};
|
|
1767
905
|
var addressOf = (key) => {
|
|
1768
906
|
if (key === null) return "z";
|
|
@@ -1785,8 +923,57 @@ var addressOf = (key) => {
|
|
|
1785
923
|
case "function":
|
|
1786
924
|
return `o${internIdentity(key)}`;
|
|
1787
925
|
default:
|
|
1788
|
-
throw new
|
|
926
|
+
throw new UnsupportedKeyTypeError(key);
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
// src/tracked/slotStore.ts
|
|
931
|
+
var swapChain = /* @__PURE__ */ new WeakMap();
|
|
932
|
+
var compactStore = (store, addressOfEntry) => {
|
|
933
|
+
const retired = store.slots;
|
|
934
|
+
const slots = new Array();
|
|
935
|
+
const index = {};
|
|
936
|
+
for (const entry of retired) {
|
|
937
|
+
if (entry === null || entry === void 0) continue;
|
|
938
|
+
index[addressOfEntry(entry)] = slots.length;
|
|
939
|
+
slots.push(entry);
|
|
940
|
+
}
|
|
941
|
+
store.slots = slots;
|
|
942
|
+
store.index = index;
|
|
943
|
+
swapChain.set(retired, store.slots);
|
|
944
|
+
};
|
|
945
|
+
var translateCursor = (retired, cursor, current) => {
|
|
946
|
+
let array = retired;
|
|
947
|
+
let position = cursor;
|
|
948
|
+
while (array !== current) {
|
|
949
|
+
const successor = swapChain.get(array);
|
|
950
|
+
if (successor === void 0) return 0;
|
|
951
|
+
let survivors = 0;
|
|
952
|
+
const bound = Math.min(position, array.length);
|
|
953
|
+
for (let slot = 0; slot < bound; slot += 1) {
|
|
954
|
+
const entry = array[slot];
|
|
955
|
+
if (entry !== null && entry !== void 0) survivors += 1;
|
|
956
|
+
}
|
|
957
|
+
position = survivors;
|
|
958
|
+
array = successor;
|
|
959
|
+
}
|
|
960
|
+
return position;
|
|
961
|
+
};
|
|
962
|
+
var deleteFromStore = (store, addr, addressOfEntry) => {
|
|
963
|
+
const slot = store.index[addr];
|
|
964
|
+
if (slot === void 0) return false;
|
|
965
|
+
store.slots[slot] = null;
|
|
966
|
+
Reflect.deleteProperty(store.index, addr);
|
|
967
|
+
store.count -= 1;
|
|
968
|
+
if (store.slots.length >= 2 * store.count) {
|
|
969
|
+
compactStore(store, addressOfEntry);
|
|
1789
970
|
}
|
|
971
|
+
return true;
|
|
972
|
+
};
|
|
973
|
+
var clearStore = (store) => {
|
|
974
|
+
store.slots = [];
|
|
975
|
+
store.index = {};
|
|
976
|
+
store.count = 0;
|
|
1790
977
|
};
|
|
1791
978
|
|
|
1792
979
|
// src/tracked/iterateSlots.ts
|
|
@@ -1796,8 +983,8 @@ function* iterateSlots(getSlots) {
|
|
|
1796
983
|
for (; ; ) {
|
|
1797
984
|
const current = getSlots();
|
|
1798
985
|
if (current !== slots) {
|
|
986
|
+
index = translateCursor(slots, index, current);
|
|
1799
987
|
slots = current;
|
|
1800
|
-
index = 0;
|
|
1801
988
|
}
|
|
1802
989
|
if (index >= slots.length) return;
|
|
1803
990
|
const entry = slots[index];
|
|
@@ -1806,25 +993,20 @@ function* iterateSlots(getSlots) {
|
|
|
1806
993
|
}
|
|
1807
994
|
}
|
|
1808
995
|
|
|
1809
|
-
// src/tracked/
|
|
1810
|
-
var
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
store.count -= 1;
|
|
1816
|
-
return true;
|
|
996
|
+
// src/tracked/trackedMap.ts
|
|
997
|
+
var EmptyMapSlotError = class extends Error {
|
|
998
|
+
constructor() {
|
|
999
|
+
super("opshot: TrackedMap resolved an empty slot");
|
|
1000
|
+
this.name = "EmptyMapSlotError";
|
|
1001
|
+
}
|
|
1817
1002
|
};
|
|
1818
|
-
var
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1003
|
+
var isObjectLike2 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
1004
|
+
var isStoredValue = (stored, incoming) => {
|
|
1005
|
+
if (Object.is(stored, incoming)) return true;
|
|
1006
|
+
return isObjectLike2(stored) && isObjectLike2(incoming) && isSameIdentity(stored, incoming);
|
|
1822
1007
|
};
|
|
1823
|
-
|
|
1824
|
-
// src/tracked/trackedMap.ts
|
|
1825
1008
|
var TrackedMap = class {
|
|
1826
1009
|
constructor(entries) {
|
|
1827
|
-
installBoundary();
|
|
1828
1010
|
this.slots = [];
|
|
1829
1011
|
this.index = {};
|
|
1830
1012
|
this.count = 0;
|
|
@@ -1844,23 +1026,29 @@ var TrackedMap = class {
|
|
|
1844
1026
|
}
|
|
1845
1027
|
set(key, value) {
|
|
1846
1028
|
assertMutableFacade(this, "count");
|
|
1847
|
-
const
|
|
1029
|
+
const stored = Object.is(key, -0) ? 0 : key;
|
|
1030
|
+
const addr = addressOf(stored);
|
|
1848
1031
|
const slot = this.index[addr];
|
|
1849
1032
|
if (slot === void 0) {
|
|
1850
1033
|
const newSlot = this.slots.length;
|
|
1851
|
-
this.slots.push([
|
|
1034
|
+
this.slots.push([stored, value]);
|
|
1852
1035
|
this.index[addr] = newSlot;
|
|
1853
1036
|
this.count += 1;
|
|
1854
1037
|
} else {
|
|
1855
1038
|
const pair = this.slots[slot];
|
|
1856
|
-
if (pair === null || pair === void 0) throw new
|
|
1039
|
+
if (pair === null || pair === void 0) throw new EmptyMapSlotError();
|
|
1040
|
+
if (isStoredValue(pair[1], value)) return this;
|
|
1857
1041
|
this.slots[slot] = [pair[0], value];
|
|
1858
1042
|
}
|
|
1859
1043
|
return this;
|
|
1860
1044
|
}
|
|
1861
1045
|
delete(key) {
|
|
1862
1046
|
assertMutableFacade(this, "count");
|
|
1863
|
-
return deleteFromStore(
|
|
1047
|
+
return deleteFromStore(
|
|
1048
|
+
this,
|
|
1049
|
+
addressOf(key),
|
|
1050
|
+
(pair) => addressOf(pair[0])
|
|
1051
|
+
);
|
|
1864
1052
|
}
|
|
1865
1053
|
clear() {
|
|
1866
1054
|
assertMutableFacade(this, "count");
|
|
@@ -1901,7 +1089,6 @@ Object.defineProperty(TrackedMap.prototype, Symbol.toStringTag, {
|
|
|
1901
1089
|
// src/tracked/trackedSet.ts
|
|
1902
1090
|
var TrackedSet = class {
|
|
1903
1091
|
constructor(values) {
|
|
1904
|
-
installBoundary();
|
|
1905
1092
|
this.slots = [];
|
|
1906
1093
|
this.index = {};
|
|
1907
1094
|
this.count = 0;
|
|
@@ -1915,17 +1102,22 @@ var TrackedSet = class {
|
|
|
1915
1102
|
}
|
|
1916
1103
|
add(value) {
|
|
1917
1104
|
assertMutableFacade(this, "count");
|
|
1918
|
-
const
|
|
1105
|
+
const stored = Object.is(value, -0) ? 0 : value;
|
|
1106
|
+
const addr = addressOf(stored);
|
|
1919
1107
|
if (this.index[addr] !== void 0) return this;
|
|
1920
1108
|
const slot = this.slots.length;
|
|
1921
|
-
this.slots.push([
|
|
1109
|
+
this.slots.push([stored]);
|
|
1922
1110
|
this.index[addr] = slot;
|
|
1923
1111
|
this.count += 1;
|
|
1924
1112
|
return this;
|
|
1925
1113
|
}
|
|
1926
1114
|
delete(value) {
|
|
1927
1115
|
assertMutableFacade(this, "count");
|
|
1928
|
-
return deleteFromStore(
|
|
1116
|
+
return deleteFromStore(
|
|
1117
|
+
this,
|
|
1118
|
+
addressOf(value),
|
|
1119
|
+
(member) => addressOf(member[0])
|
|
1120
|
+
);
|
|
1929
1121
|
}
|
|
1930
1122
|
clear() {
|
|
1931
1123
|
assertMutableFacade(this, "count");
|
|
@@ -1960,15 +1152,192 @@ Object.defineProperty(TrackedSet.prototype, Symbol.toStringTag, {
|
|
|
1960
1152
|
writable: false
|
|
1961
1153
|
});
|
|
1962
1154
|
|
|
1963
|
-
// src/
|
|
1964
|
-
var
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1155
|
+
// src/emit/emitterListeners.ts
|
|
1156
|
+
var bindings = /* @__PURE__ */ new WeakMap();
|
|
1157
|
+
function addStateListener(state, listener, deliver) {
|
|
1158
|
+
const handle = requireHandle(state, "opshot: subscribe requires a state");
|
|
1159
|
+
handle.subscribers.set(listener, deliver);
|
|
1160
|
+
const unsubscribe = () => {
|
|
1161
|
+
const held = bindings.get(unsubscribe);
|
|
1162
|
+
if (held === void 0) return;
|
|
1163
|
+
held.handle.subscribers.delete(held.listener);
|
|
1164
|
+
bindings.delete(unsubscribe);
|
|
1165
|
+
};
|
|
1166
|
+
bindings.set(unsubscribe, { handle, listener });
|
|
1167
|
+
return unsubscribe;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
// src/subscribe.ts
|
|
1171
|
+
function subscribe(state, listener) {
|
|
1172
|
+
return addStateListener(state, listener, listener);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
// src/react/propWalk.ts
|
|
1176
|
+
var stateKeysByContainer = /* @__PURE__ */ new WeakMap();
|
|
1177
|
+
var noStateKeys = /* @__PURE__ */ new Set();
|
|
1178
|
+
var isReactOwnNode = (value) => "$$typeof" in value || typeof Node !== "undefined" && value instanceof Node;
|
|
1179
|
+
var canRebuild = (container) => !isDangerousKind(classifyValue(container));
|
|
1180
|
+
var childRole = (value, writable, mode) => {
|
|
1181
|
+
if (typeof value !== "object" || value === null) return "skip";
|
|
1182
|
+
if (isReactOwnNode(value)) return "skip";
|
|
1183
|
+
if (!isTrackedEntry(value, mode === "entry" || writable)) return "skip";
|
|
1184
|
+
if (isState(value)) return "state";
|
|
1185
|
+
if (canRebuild(value)) return "descend";
|
|
1186
|
+
return "skip";
|
|
1187
|
+
};
|
|
1188
|
+
var readVerdict = (container, pass) => pass.verdicts.get(container) ?? stateKeysByContainer.get(container) ?? noStateKeys;
|
|
1189
|
+
var createDiscoveryPass = () => ({
|
|
1190
|
+
entriesByContainer: /* @__PURE__ */ new Map(),
|
|
1191
|
+
verdicts: /* @__PURE__ */ new Map(),
|
|
1192
|
+
inProgress: /* @__PURE__ */ new Set(),
|
|
1193
|
+
relaxable: /* @__PURE__ */ new Set()
|
|
1194
|
+
});
|
|
1195
|
+
function visitContainer(container, pass, mode) {
|
|
1196
|
+
if (mode === "nested" && stateKeysByContainer.has(container)) return false;
|
|
1197
|
+
if (pass.inProgress.has(container)) return true;
|
|
1198
|
+
if (pass.verdicts.has(container)) return pass.relaxable.has(container);
|
|
1199
|
+
pass.inProgress.add(container);
|
|
1200
|
+
const entries = walkDataEntries(container);
|
|
1201
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1202
|
+
let dependedOnBackEdge = false;
|
|
1203
|
+
pass.entriesByContainer.set(container, entries);
|
|
1204
|
+
for (const entry of entries) {
|
|
1205
|
+
const role = childRole(entry.value, entry.writable, mode);
|
|
1206
|
+
if (role === "state") {
|
|
1207
|
+
keys.add(entry.key);
|
|
1208
|
+
continue;
|
|
1209
|
+
}
|
|
1210
|
+
if (role !== "descend") continue;
|
|
1211
|
+
const child = entry.value;
|
|
1212
|
+
if (typeof child !== "object" || child === null) continue;
|
|
1213
|
+
if (visitContainer(child, pass, "nested")) dependedOnBackEdge = true;
|
|
1214
|
+
if (readVerdict(child, pass).size > 0) keys.add(entry.key);
|
|
1215
|
+
}
|
|
1216
|
+
pass.inProgress.delete(container);
|
|
1217
|
+
pass.verdicts.set(container, keys);
|
|
1218
|
+
if (dependedOnBackEdge) pass.relaxable.add(container);
|
|
1219
|
+
return dependedOnBackEdge;
|
|
1220
|
+
}
|
|
1221
|
+
function relaxVerdicts(pass, entryContainer) {
|
|
1222
|
+
let gained = true;
|
|
1223
|
+
while (gained) {
|
|
1224
|
+
gained = false;
|
|
1225
|
+
for (const container of pass.relaxable) {
|
|
1226
|
+
const keys = pass.verdicts.get(container);
|
|
1227
|
+
const entries = pass.entriesByContainer.get(container);
|
|
1228
|
+
if (keys === void 0 || entries === void 0) continue;
|
|
1229
|
+
for (const entry of entries) {
|
|
1230
|
+
if (keys.has(entry.key)) continue;
|
|
1231
|
+
if (childRole(entry.value, entry.writable, container === entryContainer ? "entry" : "nested") !== "descend")
|
|
1232
|
+
continue;
|
|
1233
|
+
const child = entry.value;
|
|
1234
|
+
if (typeof child !== "object" || child === null) continue;
|
|
1235
|
+
if (readVerdict(child, pass).size === 0) continue;
|
|
1236
|
+
keys.add(entry.key);
|
|
1237
|
+
gained = true;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
var cacheNestedVerdicts = (pass, skip) => {
|
|
1243
|
+
for (const [visited, keys] of pass.verdicts) {
|
|
1244
|
+
if (visited === skip) continue;
|
|
1245
|
+
stateKeysByContainer.set(visited, keys);
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
function discoverStateKeys(container) {
|
|
1249
|
+
const cached = stateKeysByContainer.get(container);
|
|
1250
|
+
if (cached !== void 0) return cached;
|
|
1251
|
+
if (isReactOwnNode(container)) return noStateKeys;
|
|
1252
|
+
if (Object.isFrozen(container) || !canRebuild(container)) return noStateKeys;
|
|
1253
|
+
const pass = createDiscoveryPass();
|
|
1254
|
+
visitContainer(container, pass, "nested");
|
|
1255
|
+
relaxVerdicts(pass);
|
|
1256
|
+
cacheNestedVerdicts(pass);
|
|
1257
|
+
return pass.verdicts.get(container) ?? noStateKeys;
|
|
1258
|
+
}
|
|
1259
|
+
function substituteContainer(container, substitution, wrap, mode) {
|
|
1260
|
+
const rebuilt = substitution.rebuiltByContainer.get(container);
|
|
1261
|
+
if (rebuilt !== void 0) return rebuilt;
|
|
1262
|
+
let stateKeys;
|
|
1263
|
+
if (mode === "nested") {
|
|
1264
|
+
stateKeys = discoverStateKeys(container);
|
|
1265
|
+
} else {
|
|
1266
|
+
const pass = createDiscoveryPass();
|
|
1267
|
+
visitContainer(container, pass, "entry");
|
|
1268
|
+
relaxVerdicts(pass, container);
|
|
1269
|
+
cacheNestedVerdicts(pass, container);
|
|
1270
|
+
stateKeys = pass.verdicts.get(container) ?? noStateKeys;
|
|
1271
|
+
}
|
|
1272
|
+
if (stateKeys.size === 0) {
|
|
1273
|
+
substitution.rebuiltByContainer.set(container, container);
|
|
1274
|
+
return container;
|
|
1275
|
+
}
|
|
1276
|
+
const clone = Array.isArray(container) ? [] : {};
|
|
1277
|
+
Reflect.setPrototypeOf(clone, Reflect.getPrototypeOf(container));
|
|
1278
|
+
substitution.rebuiltByContainer.set(container, clone);
|
|
1279
|
+
const descriptors = Object.getOwnPropertyDescriptors(container);
|
|
1280
|
+
for (const key of stateKeys) {
|
|
1281
|
+
const descriptor = descriptors[key];
|
|
1282
|
+
if (descriptor === void 0 || !("value" in descriptor)) continue;
|
|
1283
|
+
const value = descriptor.value;
|
|
1284
|
+
const role = childRole(value, descriptor.writable === true, mode);
|
|
1285
|
+
if (role === "state") {
|
|
1286
|
+
const source = peelReadProxy(value);
|
|
1287
|
+
if (typeof source !== "object" || source === null) continue;
|
|
1288
|
+
if (!substitution.visitedSources.has(source)) {
|
|
1289
|
+
substitution.visitedSources.add(source);
|
|
1290
|
+
substitution.sources.push(source);
|
|
1291
|
+
}
|
|
1292
|
+
descriptors[key] = { ...descriptor, value: wrap(source) };
|
|
1293
|
+
continue;
|
|
1294
|
+
}
|
|
1295
|
+
if (role !== "descend") continue;
|
|
1296
|
+
if (typeof value !== "object" || value === null) continue;
|
|
1297
|
+
descriptors[key] = { ...descriptor, value: substituteContainer(value, substitution, wrap, "nested") };
|
|
1298
|
+
}
|
|
1299
|
+
Object.defineProperties(clone, descriptors);
|
|
1300
|
+
return clone;
|
|
1301
|
+
}
|
|
1302
|
+
function substituteStates(root, wrap) {
|
|
1303
|
+
const substitution = {
|
|
1304
|
+
rebuiltByContainer: /* @__PURE__ */ new Map(),
|
|
1305
|
+
sources: [],
|
|
1306
|
+
visitedSources: /* @__PURE__ */ new Set()
|
|
1307
|
+
};
|
|
1308
|
+
if (isReactOwnNode(root) || !canRebuild(root)) {
|
|
1309
|
+
return { props: root, sources: substitution.sources };
|
|
1310
|
+
}
|
|
1311
|
+
return { props: substituteContainer(root, substitution, wrap, "entry"), sources: substitution.sources };
|
|
1312
|
+
}
|
|
1313
|
+
var NO_SLOT = /* @__PURE__ */ Symbol("opshot.noDispatcherSlot");
|
|
1314
|
+
var readDispatcher = () => {
|
|
1315
|
+
const internals = React;
|
|
1316
|
+
const modern = internals.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
1317
|
+
if (modern !== void 0) return modern.H;
|
|
1318
|
+
const legacy = internals.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?.ReactCurrentDispatcher;
|
|
1319
|
+
if (legacy !== void 0) return legacy.current;
|
|
1320
|
+
return NO_SLOT;
|
|
1321
|
+
};
|
|
1322
|
+
var nonRenderDispatcher;
|
|
1323
|
+
var learnNonRenderDispatcher = () => {
|
|
1324
|
+
const current = readDispatcher();
|
|
1325
|
+
if (current === NO_SLOT || current === null || current === void 0) return;
|
|
1326
|
+
nonRenderDispatcher = current;
|
|
1327
|
+
};
|
|
1328
|
+
var isRendering = () => {
|
|
1329
|
+
if (nonRenderDispatcher === void 0) return false;
|
|
1330
|
+
const current = readDispatcher();
|
|
1331
|
+
if (current === NO_SLOT || current === null || current === void 0) return false;
|
|
1332
|
+
return current !== nonRenderDispatcher;
|
|
1333
|
+
};
|
|
1334
|
+
|
|
1335
|
+
// src/react/readTracker.ts
|
|
1336
|
+
var KEYS_PROPERTY = "k";
|
|
1337
|
+
var HAS_KEY_PROPERTY = "h";
|
|
1338
|
+
var HAS_OWN_KEY_PROPERTY = "o";
|
|
1339
|
+
var ALL_OWN_KEYS_PROPERTY = "w";
|
|
1340
|
+
var isWriteProxy = (value) => recordOf(value)?.proxy === value;
|
|
1972
1341
|
var getUsage = (affected, target) => {
|
|
1973
1342
|
let used = affected.get(target);
|
|
1974
1343
|
if (used === void 0) {
|
|
@@ -1977,13 +1346,19 @@ var getUsage = (affected, target) => {
|
|
|
1977
1346
|
}
|
|
1978
1347
|
return used;
|
|
1979
1348
|
};
|
|
1980
|
-
var
|
|
1981
|
-
|
|
1982
|
-
if (set
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1349
|
+
var recordIn = (slot, key, value) => {
|
|
1350
|
+
const map = slot ?? /* @__PURE__ */ new Map();
|
|
1351
|
+
if (!map.has(key)) map.set(key, value);
|
|
1352
|
+
return map;
|
|
1353
|
+
};
|
|
1354
|
+
var recordGet = (used, key, value) => {
|
|
1355
|
+
used[KEYS_PROPERTY] = recordIn(used[KEYS_PROPERTY], key, value);
|
|
1356
|
+
};
|
|
1357
|
+
var recordHas = (used, key, value) => {
|
|
1358
|
+
used[HAS_KEY_PROPERTY] = recordIn(used[HAS_KEY_PROPERTY], key, value);
|
|
1359
|
+
};
|
|
1360
|
+
var recordOwn = (used, key, value) => {
|
|
1361
|
+
used[HAS_OWN_KEY_PROPERTY] = recordIn(used[HAS_OWN_KEY_PROPERTY], key, value);
|
|
1987
1362
|
};
|
|
1988
1363
|
var getPrototypeMethod = (target, prop) => {
|
|
1989
1364
|
let prototype = Reflect.getPrototypeOf(target);
|
|
@@ -1997,260 +1372,215 @@ var getPrototypeMethod = (target, prop) => {
|
|
|
1997
1372
|
}
|
|
1998
1373
|
return void 0;
|
|
1999
1374
|
};
|
|
2000
|
-
var
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
1375
|
+
var UnregisteredReadTrackerError = class extends Error {
|
|
1376
|
+
constructor() {
|
|
1377
|
+
super("opshot: readsIntersectDirty received an unregistered tracker");
|
|
1378
|
+
this.name = "UnregisteredReadTrackerError";
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1381
|
+
var trackerPartitions = /* @__PURE__ */ new WeakMap();
|
|
1382
|
+
var partitionsOf = (tracker) => {
|
|
1383
|
+
const partitions = trackerPartitions.get(tracker);
|
|
1384
|
+
if (partitions === void 0) throw new UnregisteredReadTrackerError();
|
|
1385
|
+
return partitions;
|
|
1386
|
+
};
|
|
1387
|
+
var recordedKeysOf = (used) => {
|
|
1388
|
+
const keyMaps = new Array();
|
|
1389
|
+
if (used[KEYS_PROPERTY] !== void 0) keyMaps.push(used[KEYS_PROPERTY]);
|
|
1390
|
+
if (used[HAS_KEY_PROPERTY] !== void 0) keyMaps.push(used[HAS_KEY_PROPERTY]);
|
|
1391
|
+
if (used[HAS_OWN_KEY_PROPERTY] !== void 0) keyMaps.push(used[HAS_OWN_KEY_PROPERTY]);
|
|
1392
|
+
return keyMaps;
|
|
1393
|
+
};
|
|
1394
|
+
function readsIntersectDirty(tracker, dirty) {
|
|
1395
|
+
for (const partition of partitionsOf(tracker).values()) {
|
|
1396
|
+
for (const [writeProxy, used] of partition.affected) {
|
|
1397
|
+
const raw = rawOf(writeProxy);
|
|
1398
|
+
const edges = dirty.edges.get(raw);
|
|
1399
|
+
for (const keys of recordedKeysOf(used)) {
|
|
1400
|
+
for (const key of keys.keys()) {
|
|
1401
|
+
if (typeof key === "symbol") continue;
|
|
1402
|
+
if (edges?.has(key) === true) return true;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
if (used[ALL_OWN_KEYS_PROPERTY] !== void 0 && dirty.nodes.has(raw)) return true;
|
|
1406
|
+
}
|
|
1407
|
+
for (const writeProxy of partition.identityReads) {
|
|
1408
|
+
if (partition.affected.has(writeProxy)) continue;
|
|
1409
|
+
if (dirty.nodes.has(rawOf(writeProxy))) return true;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
return false;
|
|
1413
|
+
}
|
|
1414
|
+
function readsChanged(tracker) {
|
|
1415
|
+
for (const partition of partitionsOf(tracker).values()) {
|
|
1416
|
+
for (const [writeProxy, used] of partition.affected) {
|
|
1417
|
+
const gets = used[KEYS_PROPERTY];
|
|
1418
|
+
if (gets !== void 0) {
|
|
1419
|
+
for (const [key, stored] of gets) {
|
|
1420
|
+
if (!Object.is(Reflect.get(writeProxy, key, writeProxy), stored)) return true;
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
const hasKeys = used[HAS_KEY_PROPERTY];
|
|
1424
|
+
if (hasKeys !== void 0) {
|
|
1425
|
+
for (const [key, stored] of hasKeys) {
|
|
1426
|
+
if (!Object.is(Reflect.has(writeProxy, key), stored)) return true;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
const ownKeys = used[HAS_OWN_KEY_PROPERTY];
|
|
1430
|
+
if (ownKeys !== void 0) {
|
|
1431
|
+
for (const [key, stored] of ownKeys) {
|
|
1432
|
+
const present = Reflect.getOwnPropertyDescriptor(writeProxy, key) !== void 0;
|
|
1433
|
+
if (!Object.is(present, stored)) return true;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
const listed = used[ALL_OWN_KEYS_PROPERTY];
|
|
1437
|
+
if (listed !== void 0) {
|
|
1438
|
+
const current = Reflect.ownKeys(writeProxy);
|
|
1439
|
+
if (current.length !== listed.length) return true;
|
|
1440
|
+
for (let index = 0; index < listed.length; index += 1) {
|
|
1441
|
+
if (!Object.is(current[index], listed[index])) return true;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
return false;
|
|
1447
|
+
}
|
|
1448
|
+
function createReadTracker() {
|
|
2014
1449
|
const partitions = /* @__PURE__ */ new Map();
|
|
2015
|
-
const targets = /* @__PURE__ */ new Map();
|
|
2016
1450
|
let afterRender = false;
|
|
2017
|
-
|
|
2018
|
-
|
|
1451
|
+
let releasing = false;
|
|
1452
|
+
const getPartition = (writeProxy) => {
|
|
1453
|
+
let partition = partitions.get(writeProxy);
|
|
2019
1454
|
if (partition === void 0) {
|
|
2020
1455
|
partition = {
|
|
2021
|
-
sourceProxy,
|
|
2022
|
-
previousRootSnapshot: void 0,
|
|
2023
1456
|
affected: /* @__PURE__ */ new Map(),
|
|
2024
|
-
|
|
1457
|
+
identityReads: /* @__PURE__ */ new Set(),
|
|
2025
1458
|
proxyCache: /* @__PURE__ */ new WeakMap()
|
|
2026
1459
|
};
|
|
2027
|
-
partitions.set(
|
|
1460
|
+
partitions.set(writeProxy, partition);
|
|
2028
1461
|
}
|
|
2029
1462
|
return partition;
|
|
2030
1463
|
};
|
|
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
|
-
});
|
|
1464
|
+
const shouldRecord = () => !afterRender || isRendering();
|
|
1465
|
+
const trackUsage = (partition, writeProxy) => shouldRecord() ? getUsage(partition.affected, writeProxy) : {};
|
|
1466
|
+
const recordIdentity = (partition, value) => {
|
|
1467
|
+
if (!shouldRecord()) return;
|
|
1468
|
+
if (isObjectLike(value) && isWriteProxy(value)) partition.identityReads.add(value);
|
|
2053
1469
|
};
|
|
2054
|
-
const
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
const cached = partition.proxyCache.get(liveProxy);
|
|
1470
|
+
const toReadProxy = (writeProxy, partition) => {
|
|
1471
|
+
const raw = rawOf(writeProxy);
|
|
1472
|
+
const cached = partition.proxyCache.get(raw);
|
|
2058
1473
|
if (cached !== void 0) return cached;
|
|
2059
|
-
const
|
|
2060
|
-
const
|
|
2061
|
-
const
|
|
1474
|
+
const target = raw;
|
|
1475
|
+
const readProxyBox = {};
|
|
1476
|
+
const boundMethods = /* @__PURE__ */ new WeakMap();
|
|
1477
|
+
const bindMethodToReadProxy = (readProxy2, method) => {
|
|
1478
|
+
const existing = boundMethods.get(method);
|
|
1479
|
+
if (existing !== void 0) return existing;
|
|
1480
|
+
const bound = Function.prototype.bind.call(method, readProxy2);
|
|
1481
|
+
boundMethods.set(method, bound);
|
|
1482
|
+
return bound;
|
|
1483
|
+
};
|
|
1484
|
+
const handler2 = {
|
|
2062
1485
|
get(_target, prop) {
|
|
2063
|
-
|
|
2064
|
-
const value = Reflect.get(
|
|
2065
|
-
const
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
ensureBaseline(partition, liveProxy);
|
|
1486
|
+
const readProxy2 = readProxyBox.current;
|
|
1487
|
+
const value = Reflect.get(writeProxy, prop, readProxy2 ?? writeProxy);
|
|
1488
|
+
const used = trackUsage(partition, writeProxy);
|
|
1489
|
+
recordGet(used, prop, value);
|
|
1490
|
+
recordIdentity(partition, value);
|
|
2069
1491
|
if (typeof value === "function") {
|
|
2070
|
-
const method = getPrototypeMethod(
|
|
2071
|
-
if (method !== void 0 && value === method &&
|
|
2072
|
-
return
|
|
1492
|
+
const method = getPrototypeMethod(target, prop);
|
|
1493
|
+
if (method !== void 0 && value === method && readProxy2 !== void 0) {
|
|
1494
|
+
return bindMethodToReadProxy(readProxy2, method);
|
|
2073
1495
|
}
|
|
2074
1496
|
}
|
|
2075
|
-
if (!
|
|
1497
|
+
if (!isObjectLike(value)) return value;
|
|
2076
1498
|
if (typeof value === "function") return value;
|
|
2077
|
-
if (
|
|
2078
|
-
|
|
2079
|
-
return wrapLive(value, partition);
|
|
1499
|
+
if (!isWriteProxy(value)) return value;
|
|
1500
|
+
return toReadProxy(value, partition);
|
|
2080
1501
|
},
|
|
2081
1502
|
has(_target, prop) {
|
|
2082
|
-
const used = trackUsage(partition,
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
return
|
|
1503
|
+
const used = trackUsage(partition, writeProxy);
|
|
1504
|
+
const result = Reflect.has(writeProxy, prop);
|
|
1505
|
+
recordHas(used, prop, result);
|
|
1506
|
+
return result;
|
|
2086
1507
|
},
|
|
2087
1508
|
getOwnPropertyDescriptor(_target, prop) {
|
|
2088
|
-
const used = trackUsage(partition,
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
return
|
|
1509
|
+
const used = trackUsage(partition, writeProxy);
|
|
1510
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(writeProxy, prop);
|
|
1511
|
+
recordOwn(used, prop, descriptor !== void 0);
|
|
1512
|
+
return descriptor;
|
|
2092
1513
|
},
|
|
2093
1514
|
ownKeys() {
|
|
2094
|
-
const used = trackUsage(partition,
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
return
|
|
1515
|
+
const used = trackUsage(partition, writeProxy);
|
|
1516
|
+
const keys = Reflect.ownKeys(writeProxy);
|
|
1517
|
+
used[ALL_OWN_KEYS_PROPERTY] ??= keys;
|
|
1518
|
+
return keys;
|
|
2098
1519
|
},
|
|
2099
1520
|
set(_target, prop, value) {
|
|
2100
|
-
|
|
2101
|
-
return Reflect.set(liveProxy, prop, value, liveProxy);
|
|
1521
|
+
return Reflect.set(writeProxy, prop, value, writeProxy);
|
|
2102
1522
|
},
|
|
2103
1523
|
deleteProperty(_target, prop) {
|
|
2104
|
-
|
|
2105
|
-
return Reflect.deleteProperty(liveProxy, prop);
|
|
1524
|
+
return Reflect.deleteProperty(writeProxy, prop);
|
|
2106
1525
|
}
|
|
2107
1526
|
};
|
|
2108
|
-
const
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
partition.proxyCache.set(
|
|
2112
|
-
return
|
|
1527
|
+
const readProxy = new Proxy(writeProxy, handler2);
|
|
1528
|
+
readProxyBox.current = readProxy;
|
|
1529
|
+
registerReadProxyTarget(readProxy, writeProxy);
|
|
1530
|
+
partition.proxyCache.set(raw, readProxy);
|
|
1531
|
+
return readProxy;
|
|
2113
1532
|
};
|
|
2114
|
-
|
|
2115
|
-
wrap(
|
|
2116
|
-
if (!
|
|
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);
|
|
1533
|
+
const tracker = {
|
|
1534
|
+
wrap(writeProxy) {
|
|
1535
|
+
if (!isWriteProxy(writeProxy)) {
|
|
1536
|
+
throw new Error("opshot: ReadTracker.wrap requires a write proxy");
|
|
2134
1537
|
}
|
|
2135
|
-
const
|
|
2136
|
-
return
|
|
1538
|
+
const partition = getPartition(writeProxy);
|
|
1539
|
+
return toReadProxy(writeProxy, partition);
|
|
2137
1540
|
},
|
|
2138
1541
|
captureReads() {
|
|
1542
|
+
learnNonRenderDispatcher();
|
|
2139
1543
|
afterRender = true;
|
|
2140
1544
|
},
|
|
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
1545
|
resetReads() {
|
|
2153
1546
|
afterRender = false;
|
|
2154
1547
|
for (const partition of partitions.values()) {
|
|
2155
|
-
partition.previousRootSnapshot = void 0;
|
|
2156
1548
|
partition.affected.clear();
|
|
2157
|
-
partition.
|
|
1549
|
+
partition.identityReads.clear();
|
|
1550
|
+
partition.proxyCache = /* @__PURE__ */ new WeakMap();
|
|
2158
1551
|
}
|
|
2159
1552
|
},
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
1553
|
+
retain() {
|
|
1554
|
+
releasing = false;
|
|
1555
|
+
},
|
|
1556
|
+
dispose() {
|
|
1557
|
+
releasing = true;
|
|
1558
|
+
void Promise.resolve().then(() => {
|
|
1559
|
+
if (!releasing) return;
|
|
1560
|
+
releasing = false;
|
|
1561
|
+
partitions.clear();
|
|
1562
|
+
});
|
|
2168
1563
|
}
|
|
2169
1564
|
};
|
|
1565
|
+
trackerPartitions.set(tracker, partitions);
|
|
1566
|
+
return tracker;
|
|
2170
1567
|
}
|
|
1568
|
+
var useCommitEffect = typeof document === "undefined" ? useEffect : useLayoutEffect;
|
|
2171
1569
|
|
|
2172
1570
|
// 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);
|
|
1571
|
+
var sourcesKey = (sources) => `${sources.length}:${sources.map((source) => addressOf(source)).join(",")}`;
|
|
1572
|
+
var uniqueHandlesOf = (nodes) => {
|
|
1573
|
+
const unique = new Array();
|
|
1574
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1575
|
+
for (const node of nodes) {
|
|
1576
|
+
for (const handle of handlesOf(node)) {
|
|
1577
|
+
if (seen.has(handle)) continue;
|
|
1578
|
+
seen.add(handle);
|
|
1579
|
+
unique.push(handle);
|
|
2213
1580
|
}
|
|
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
1581
|
}
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
clone[head] = updated;
|
|
2251
|
-
return clone;
|
|
2252
|
-
}
|
|
2253
|
-
var sourcesKey = (sources) => `${sources.length}:${sources.map((source) => addressOf(source)).join(",")}`;
|
|
1582
|
+
return unique;
|
|
1583
|
+
};
|
|
2254
1584
|
var arePropsEqual = (previous, next) => {
|
|
2255
1585
|
const previousRecord = previous;
|
|
2256
1586
|
const nextRecord = next;
|
|
@@ -2267,99 +1597,85 @@ var arePropsEqual = (previous, next) => {
|
|
|
2267
1597
|
}
|
|
2268
1598
|
return true;
|
|
2269
1599
|
};
|
|
2270
|
-
function scope(Component
|
|
2271
|
-
const maxDepth = options?.maxDepth ?? 10;
|
|
1600
|
+
function scope(Component) {
|
|
2272
1601
|
const Scoped = (props) => {
|
|
2273
|
-
const
|
|
2274
|
-
|
|
2275
|
-
|
|
1602
|
+
const readTrackerRef = useRef(void 0);
|
|
1603
|
+
const currentHandlesRef = useRef([]);
|
|
1604
|
+
readTrackerRef.current ??= createReadTracker();
|
|
1605
|
+
const readTracker = readTrackerRef.current;
|
|
2276
1606
|
const [, bump] = useReducer((value) => value + 1, 0);
|
|
2277
|
-
|
|
2278
|
-
const
|
|
2279
|
-
const
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
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
|
-
}
|
|
2293
|
-
}
|
|
2294
|
-
const renderedProps = changed ? nextProps : props;
|
|
2295
|
-
const versionsAtRender = sources.map((source) => getVersion(source));
|
|
2296
|
-
useEffect(() => {
|
|
2297
|
-
boundary.captureReads();
|
|
1607
|
+
readTracker.resetReads();
|
|
1608
|
+
const { props: renderedProps, sources } = substituteStates(props, (source) => readTracker.wrap(source));
|
|
1609
|
+
const uniqueHandles = uniqueHandlesOf(sources);
|
|
1610
|
+
useCommitEffect(() => {
|
|
1611
|
+
currentHandlesRef.current = uniqueHandles;
|
|
1612
|
+
readTracker.captureReads();
|
|
2298
1613
|
});
|
|
2299
1614
|
useEffect(() => {
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
1615
|
+
readTracker.retain();
|
|
1616
|
+
return () => readTracker.dispose();
|
|
1617
|
+
}, [readTracker]);
|
|
1618
|
+
useEffect(() => {
|
|
1619
|
+
let cancelled = false;
|
|
1620
|
+
const subscribedHandles = uniqueHandlesOf(sources);
|
|
1621
|
+
const unsubscribes = subscribedHandles.map(
|
|
1622
|
+
(handle) => subscribe(proxyOf(handle.root), () => {
|
|
1623
|
+
if (cancelled) return;
|
|
1624
|
+
const dirty = handle.lastDirty;
|
|
1625
|
+
if (dirty !== void 0 && readsIntersectDirty(readTracker, dirty)) bump();
|
|
1626
|
+
})
|
|
2310
1627
|
);
|
|
1628
|
+
if (readsChanged(readTracker)) bump();
|
|
2311
1629
|
return () => {
|
|
1630
|
+
cancelled = true;
|
|
2312
1631
|
for (const unsubscribe of unsubscribes) unsubscribe();
|
|
2313
1632
|
};
|
|
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
|
-
});
|
|
1633
|
+
}, [sourcesKey(sources), readTracker]);
|
|
2328
1634
|
return createElement(Component, renderedProps);
|
|
2329
1635
|
};
|
|
2330
1636
|
const baseName = Component.displayName ?? Component.name;
|
|
2331
1637
|
Scoped.displayName = `scope(${typeof baseName === "string" && baseName !== "" ? baseName : "Component"})`;
|
|
2332
1638
|
return memo(Scoped, arePropsEqual);
|
|
2333
1639
|
}
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
}
|
|
2337
|
-
function
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
1640
|
+
var isObjectLike3 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
1641
|
+
function useMutableState(properties, options) {
|
|
1642
|
+
const [{ writeProxy, readTracker }] = useState(() => {
|
|
1643
|
+
const initial = typeof properties === "function" ? properties() : properties;
|
|
1644
|
+
return {
|
|
1645
|
+
writeProxy: createMutableState(initial, options),
|
|
1646
|
+
readTracker: createReadTracker()
|
|
1647
|
+
};
|
|
1648
|
+
});
|
|
2342
1649
|
const [, bump] = useReducer((value) => value + 1, 0);
|
|
2343
|
-
const
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
1650
|
+
const currentHandlesRef = useRef([]);
|
|
1651
|
+
const uniqueHandles = isObjectLike3(writeProxy) ? handlesOf(writeProxy) : [];
|
|
1652
|
+
readTracker.resetReads();
|
|
1653
|
+
const readProxy = isObjectLike3(writeProxy) ? readTracker.wrap(writeProxy) : writeProxy;
|
|
1654
|
+
useCommitEffect(() => {
|
|
1655
|
+
currentHandlesRef.current = uniqueHandles;
|
|
1656
|
+
readTracker.captureReads();
|
|
2348
1657
|
});
|
|
2349
1658
|
useEffect(() => {
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
else boundary.advanceBaselines();
|
|
2354
|
-
};
|
|
2355
|
-
return subscribe(proxy2, onSignal, true);
|
|
2356
|
-
}, [proxy2, boundary]);
|
|
1659
|
+
readTracker.retain();
|
|
1660
|
+
return () => readTracker.dispose();
|
|
1661
|
+
}, [readTracker]);
|
|
2357
1662
|
useEffect(() => {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
1663
|
+
let cancelled = false;
|
|
1664
|
+
const subscribedHandles = isObjectLike3(writeProxy) ? handlesOf(writeProxy) : [];
|
|
1665
|
+
const unsubscribes = subscribedHandles.map(
|
|
1666
|
+
(handle) => subscribe(proxyOf(handle.root), () => {
|
|
1667
|
+
if (cancelled) return;
|
|
1668
|
+
const dirty = handle.lastDirty;
|
|
1669
|
+
if (dirty !== void 0 && readsIntersectDirty(readTracker, dirty)) bump();
|
|
1670
|
+
})
|
|
1671
|
+
);
|
|
1672
|
+
if (readsChanged(readTracker)) bump();
|
|
1673
|
+
return () => {
|
|
1674
|
+
cancelled = true;
|
|
1675
|
+
for (const unsubscribe of unsubscribes) unsubscribe();
|
|
1676
|
+
};
|
|
1677
|
+
}, [writeProxy, readTracker]);
|
|
1678
|
+
return readProxy;
|
|
2363
1679
|
}
|
|
2364
1680
|
|
|
2365
|
-
export { TrackedDate, TrackedMap, TrackedSet,
|
|
1681
|
+
export { TrackedDate, TrackedMap, TrackedSet, batch, createMutableState, identify, ignore, isSameIdentity, isState, scope, subscribe, unsafeTrack, useMutableState };
|