opshot 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,155 +1,2297 @@
1
- import { unstable_getInternalStates, ref, proxy, snapshot } from 'valtio/vanilla';
2
- export { ref } from 'valtio/vanilla';
3
-
4
- // src/index.ts
5
- var { refSet } = unstable_getInternalStates();
6
- var isPlainArray = (value) => Array.isArray(value) && !refSet.has(value);
7
- var isPlainObject = (value) => {
8
- if (typeof value !== "object" || value === null || Array.isArray(value) || refSet.has(value)) return false;
9
- const prototype = Object.getPrototypeOf(value);
10
- return prototype === Object.prototype || prototype === null;
1
+ import { memo, useState, useReducer, useEffect, useRef, createElement } from 'react';
2
+
3
+ // node_modules/proxy-compare/dist/index.js
4
+ var GET_ORIGINAL_SYMBOL = /* @__PURE__ */ Symbol();
5
+ var HAS_KEY_PROPERTY = "h";
6
+ var ALL_OWN_KEYS_PROPERTY = "w";
7
+ var HAS_OWN_KEY_PROPERTY = "o";
8
+ var KEYS_PROPERTY = "k";
9
+ var getProto = Object.getPrototypeOf;
10
+ var objectsToTrack = /* @__PURE__ */ new WeakMap();
11
+ var isObjectToTrack = (obj) => obj && (objectsToTrack.has(obj) ? objectsToTrack.get(obj) : getProto(obj) === Object.prototype || getProto(obj) === Array.prototype);
12
+ var isObject = (x) => typeof x === "object" && x !== null;
13
+ var getOriginalObject = (obj) => (
14
+ // unwrap proxy
15
+ obj[GET_ORIGINAL_SYMBOL] || // otherwise
16
+ obj
17
+ );
18
+ var isAllOwnKeysChanged = (prevObj, nextObj) => {
19
+ const prevKeys = Reflect.ownKeys(prevObj);
20
+ const nextKeys = Reflect.ownKeys(nextObj);
21
+ return prevKeys.length !== nextKeys.length || prevKeys.some((k, i) => k !== nextKeys[i]);
11
22
  };
12
- var isCloneable = (value) => isPlainObject(value) || isPlainArray(value);
13
- var cloneValue = (value) => {
14
- if (isPlainArray(value)) return value.map(cloneValue);
15
- if (isPlainObject(value)) {
16
- return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, cloneValue(child)]));
23
+ var isChanged = (prevObj, nextObj, affected, cache, isEqual = Object.is) => {
24
+ if (isEqual(prevObj, nextObj)) {
25
+ return false;
17
26
  }
18
- return value;
27
+ if (!isObject(prevObj) || !isObject(nextObj))
28
+ return true;
29
+ const used = affected.get(getOriginalObject(prevObj));
30
+ if (!used)
31
+ return true;
32
+ if (cache) {
33
+ const hit = cache.get(prevObj);
34
+ if (hit === nextObj) {
35
+ return false;
36
+ }
37
+ cache.set(prevObj, nextObj);
38
+ }
39
+ let changed = null;
40
+ for (const key of used[HAS_KEY_PROPERTY] || []) {
41
+ changed = Reflect.has(prevObj, key) !== Reflect.has(nextObj, key);
42
+ if (changed)
43
+ return changed;
44
+ }
45
+ if (used[ALL_OWN_KEYS_PROPERTY] === true) {
46
+ changed = isAllOwnKeysChanged(prevObj, nextObj);
47
+ if (changed)
48
+ return changed;
49
+ } else {
50
+ for (const key of used[HAS_OWN_KEY_PROPERTY] || []) {
51
+ const hasPrev = !!Reflect.getOwnPropertyDescriptor(prevObj, key);
52
+ const hasNext = !!Reflect.getOwnPropertyDescriptor(nextObj, key);
53
+ changed = hasPrev !== hasNext;
54
+ if (changed)
55
+ return changed;
56
+ }
57
+ }
58
+ for (const key of used[KEYS_PROPERTY] || []) {
59
+ changed = isChanged(prevObj[key], nextObj[key], affected, cache, isEqual);
60
+ if (changed)
61
+ return changed;
62
+ }
63
+ if (changed === null)
64
+ throw new Error("invalid used");
65
+ return changed;
19
66
  };
20
- var toPointer = (path) => {
21
- if (path.length === 0) return "";
22
- return `/${path.map((segment) => String(segment).replaceAll("~", "~0").replaceAll("/", "~1")).join("/")}`;
67
+ var getUntracked = (obj) => {
68
+ if (isObjectToTrack(obj)) {
69
+ return obj[GET_ORIGINAL_SYMBOL] || null;
70
+ }
71
+ return null;
23
72
  };
24
- var removing = (pointer) => ({ op: "remove", path: pointer });
25
- var carrying = (op, pointer, value) => {
26
- if (!isCloneable(value)) return { op, path: pointer, value };
27
- return {
28
- op,
29
- path: pointer,
30
- get value() {
31
- return cloneValue(value);
73
+ var markToTrack = (obj, mark = true) => {
74
+ objectsToTrack.set(obj, mark);
75
+ };
76
+
77
+ // node_modules/valtio/esm/vanilla.mjs
78
+ var isObject2 = (x) => typeof x === "object" && x !== null;
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;
32
91
  }
33
- };
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;
34
115
  };
35
- var addPair = (pointer, after) => ({ do: carrying("add", pointer, after), undo: removing(pointer) });
36
- var removePair = (pointer, before) => ({ do: removing(pointer), undo: carrying("add", pointer, before) });
37
- var replacePair = (pointer, before, after) => ({
38
- do: carrying("replace", pointer, after),
39
- undo: carrying("replace", pointer, before)
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
+ }
40
142
  });
41
- var diffValue = (before, after, path, ops) => {
42
- if (Object.is(before, after)) return;
43
- if (isPlainArray(before) && isPlainArray(after)) {
44
- if (before.length !== after.length) {
45
- ops.push(replacePair(toPointer(path), before, after));
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));
46
279
  return;
47
280
  }
48
- for (let index = 0; index < after.length; index++) diffValue(before[index], after[index], [...path, index], ops);
49
- return;
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");
50
301
  }
51
- if (isPlainObject(before) && isPlainObject(after)) {
52
- for (const key of /* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])) {
53
- if (!Object.hasOwn(before, key)) ops.push(addPair(toPointer([...path, key]), after[key]));
54
- else if (!Object.hasOwn(after, key)) ops.push(removePair(toPointer([...path, key]), before[key]));
55
- else diffValue(before[key], after[key], [...path, key], ops);
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/react/wrapperRegistry.ts
341
+ var wrapperTargets = /* @__PURE__ */ new WeakMap();
342
+ var registerWrapperTarget = (wrapper, target) => {
343
+ wrapperTargets.set(wrapper, target);
344
+ };
345
+ var getRegisteredWrapperTarget = (wrapper) => wrapperTargets.get(wrapper);
346
+
347
+ // src/identity.ts
348
+ var isObjectLike = (value) => value !== null && (typeof value === "object" || typeof value === "function");
349
+ var targetRegistry = /* @__PURE__ */ new WeakMap();
350
+ var identityTokenRegistry = /* @__PURE__ */ new WeakMap();
351
+ var { proxyStateMap: proxyStateMap2 } = unstable_getInternalStates();
352
+ function registerSnapshotCopy(copy, target) {
353
+ targetRegistry.set(copy, target);
354
+ }
355
+ function getRegisteredTarget(copy) {
356
+ return targetRegistry.get(copy);
357
+ }
358
+ function peelIdentityLayer(current) {
359
+ const untracked = getUntracked(current);
360
+ if (untracked !== null && untracked !== current) return untracked;
361
+ const wrapperTarget = getRegisteredWrapperTarget(current);
362
+ if (wrapperTarget !== void 0 && wrapperTarget !== current) return wrapperTarget;
363
+ const registeredTarget = targetRegistry.get(current);
364
+ if (registeredTarget !== void 0 && registeredTarget !== current) return registeredTarget;
365
+ return void 0;
366
+ }
367
+ function resolveIdentity(value) {
368
+ let current = value;
369
+ while (isObjectLike(current)) {
370
+ const peeled = peelIdentityLayer(current);
371
+ if (peeled !== void 0) {
372
+ current = peeled;
373
+ continue;
374
+ }
375
+ const proxyState = proxyStateMap2.get(current);
376
+ if (proxyState !== void 0 && proxyState[0] !== current) {
377
+ current = proxyState[0];
378
+ continue;
379
+ }
380
+ break;
381
+ }
382
+ return current;
383
+ }
384
+ function identify(value) {
385
+ const target = resolveIdentity(value);
386
+ if (!isObjectLike(target)) return value;
387
+ const existing = identityTokenRegistry.get(target);
388
+ if (existing !== void 0) return existing;
389
+ const token = Object.freeze({});
390
+ identityTokenRegistry.set(target, token);
391
+ return token;
392
+ }
393
+ function isSameIdentity(first, second) {
394
+ const resolvedFirst = resolveIdentity(first);
395
+ const resolvedSecond = resolveIdentity(second);
396
+ return resolvedFirst === resolvedSecond || resolvedFirst !== resolvedFirst && resolvedSecond !== resolvedSecond;
397
+ }
398
+
399
+ // src/unsafeTrack.ts
400
+ var unsafeTrackedSet = /* @__PURE__ */ new WeakSet();
401
+ function unsafeTrack(value) {
402
+ unsafeTrackedSet.add(value);
403
+ return value;
404
+ }
405
+ function isUnsafeTracked(value) {
406
+ return typeof value === "object" && value !== null && unsafeTrackedSet.has(value);
407
+ }
408
+
409
+ // src/valtio/classify.ts
410
+ var { refSet: refSet2 } = unstable_getInternalStates();
411
+ var sourceCache = /* @__PURE__ */ new WeakMap();
412
+ var readSource = (constructor) => {
413
+ const cached = sourceCache.get(constructor);
414
+ if (cached !== void 0) return cached;
415
+ const source = Function.prototype.toString.call(constructor);
416
+ sourceCache.set(constructor, source);
417
+ return source;
418
+ };
419
+ var classifyChain = (initialConstructor) => {
420
+ let sawNativeSource = false;
421
+ let current = initialConstructor;
422
+ while (typeof current === "function" && current !== Object && current !== Array && current !== Function.prototype) {
423
+ const source = readSource(current);
424
+ if (source.includes("#")) return "privateClass";
425
+ if (source.includes("[native code]")) sawNativeSource = true;
426
+ current = Reflect.getPrototypeOf(current);
427
+ }
428
+ return sawNativeSource ? "nativeClass" : "cleanClass";
429
+ };
430
+ function classifyValue(value) {
431
+ const prototype = Object.getPrototypeOf(value);
432
+ if (Array.isArray(value))
433
+ return prototype === Array.prototype || prototype === null ? "plainArray" : "arraySubclass";
434
+ if (prototype === Object.prototype || prototype === null) return "plain";
435
+ return classifyChain(value.constructor);
436
+ }
437
+ function hasOwnEnumerableFunction(value) {
438
+ for (const key of Reflect.ownKeys(value)) {
439
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
440
+ if (!descriptor?.enumerable || !("value" in descriptor)) continue;
441
+ if (typeof descriptor.value === "function") return true;
442
+ }
443
+ return false;
444
+ }
445
+ function admissionLane(value) {
446
+ if (typeof value !== "object" || value === null) return "leaf";
447
+ if (refSet2.has(value)) return "leaf";
448
+ if (isUnsafeTracked(value)) return "track";
449
+ const kind = classifyValue(value);
450
+ if ((kind === "plain" || kind === "plainArray" || kind === "cleanClass") && Object.isFrozen(value)) return "leaf";
451
+ if (kind === "plain" || kind === "plainArray") return "track";
452
+ if (kind === "cleanClass" && !hasOwnEnumerableFunction(value)) return "track";
453
+ return "reject";
454
+ }
455
+ function isTrackable(value) {
456
+ return admissionLane(value) === "track";
457
+ }
458
+
459
+ // src/ops/path.ts
460
+ var createOperationPath = (segments) => Object.freeze([...segments]);
461
+ var appendOperationPath = (path, segment) => Object.freeze([...path, segment]);
462
+ var escapeSegment = (segment) => segment.replaceAll("~", "~0").replaceAll("/", "~1");
463
+ var formatSegment = (segment) => typeof segment === "string" ? escapeSegment(segment) : String(segment);
464
+ var formatOperationPath = (path) => path.length === 0 ? "" : `/${path.map(formatSegment).join("/")}`;
465
+ var assertSafePath = (path) => {
466
+ for (let index = 0; index < path.length; index++) {
467
+ const segment = path[index];
468
+ if (segment === "__proto__" || segment === "prototype" && path[index - 1] === "constructor") {
469
+ throw new Error(`opshot: reserved operation path ${formatOperationPath(path)}`);
470
+ }
471
+ }
472
+ };
473
+
474
+ // src/ops/cloneValue.ts
475
+ var { refSet: refSet3 } = unstable_getInternalStates();
476
+ var isPlainArray = (value) => Array.isArray(value) && !refSet3.has(value);
477
+ var isPlainObject = (value) => isTrackable(value) && !Array.isArray(value);
478
+ var isCloneable = (value) => isTrackable(value);
479
+ var CyclicValueError = class extends Error {
480
+ constructor(path) {
481
+ super(`opshot: cyclic value at ${formatOperationPath(path)}; use ignore() for back-linked structures, or ids`);
482
+ this.name = "CyclicValueError";
483
+ this.path = createOperationPath(path);
484
+ }
485
+ };
486
+ var cyclicError = (path) => new CyclicValueError(path);
487
+ var getCyclicPath = (error) => error instanceof CyclicValueError ? error.path : void 0;
488
+ var CLONE_IN_PROGRESS = /* @__PURE__ */ Symbol("opshot.cloneValue.inProgress");
489
+ var cloneValue = (value, memo2, path) => {
490
+ if (!isCloneable(value)) return value;
491
+ const cached = memo2.get(value);
492
+ if (cached === CLONE_IN_PROGRESS) throw cyclicError(path);
493
+ if (cached !== void 0) return cached;
494
+ memo2.set(value, CLONE_IN_PROGRESS);
495
+ const array = isPlainArray(value);
496
+ const clone = array ? [] : {};
497
+ Reflect.setPrototypeOf(clone, Reflect.getPrototypeOf(value));
498
+ for (const key of Reflect.ownKeys(value)) {
499
+ const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
500
+ if (!descriptor) continue;
501
+ if ("value" in descriptor) {
502
+ Object.defineProperty(clone, key, {
503
+ ...descriptor,
504
+ value: cloneValue(descriptor.value, memo2, path)
505
+ });
506
+ } else {
507
+ Object.defineProperty(clone, key, descriptor);
56
508
  }
509
+ }
510
+ memo2.set(value, clone);
511
+ if (isUnsafeTracked(value)) unsafeTrack(clone);
512
+ return clone;
513
+ };
514
+
515
+ // src/ops/operation.ts
516
+ var operationBrand = /* @__PURE__ */ Symbol.for("opshot.operation");
517
+ var valueOriginals = /* @__PURE__ */ new WeakMap();
518
+ var OperationHalf = class {
519
+ constructor(path) {
520
+ this.path = createOperationPath(path);
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";
550
+ }
551
+ };
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
+
558
+ // src/ops/weight.ts
559
+ var NODE_WEIGHT = 32;
560
+ var KEY_WEIGHT = 16;
561
+ var CHARACTER_WEIGHT = 2;
562
+ var LEAF_WEIGHT = 16;
563
+ var OPERATION_WEIGHT = 512;
564
+ var addWeight = (state, amount) => {
565
+ state.weight += amount;
566
+ return state.weight <= state.budget;
567
+ };
568
+ var weigh = (value, state) => {
569
+ if (state.weight > state.budget) return;
570
+ if (typeof value === "string") {
571
+ addWeight(state, LEAF_WEIGHT + CHARACTER_WEIGHT * value.length);
57
572
  return;
58
573
  }
59
- ops.push(replacePair(toPointer(path), before, after));
574
+ if (value === null || typeof value !== "object" && typeof value !== "function") {
575
+ addWeight(state, LEAF_WEIGHT);
576
+ return;
577
+ }
578
+ if (state.seen.has(value)) return;
579
+ if (isCloneable(value)) {
580
+ state.seen.add(value);
581
+ if (!addWeight(state, NODE_WEIGHT)) return;
582
+ for (const key of Object.keys(value)) {
583
+ const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
584
+ if (!descriptor || !("value" in descriptor)) continue;
585
+ if (!addWeight(state, KEY_WEIGHT)) return;
586
+ weigh(descriptor.value, state);
587
+ if (state.weight > state.budget) return;
588
+ }
589
+ }
590
+ };
591
+ var weighValue = (value, budget) => {
592
+ const state = { weight: 0, budget, seen: /* @__PURE__ */ new WeakSet() };
593
+ weigh(value, state);
594
+ return state.weight;
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";
603
+ }
604
+ };
605
+ var addPair = (path, after) => ({
606
+ do: createAddOperation(path, after),
607
+ undo: createRemoveOperation(path)
608
+ });
609
+ var removePair = (path, before) => ({
610
+ do: createRemoveOperation(path),
611
+ undo: createAddOperation(path, before)
612
+ });
613
+ var replacePair = (path, before, after) => ({
614
+ do: createReplaceOperation(path, after),
615
+ undo: createReplaceOperation(path, before)
616
+ });
617
+ var weighCarried = (value) => weighValue(value, UNCAPPED_WEIGHT);
618
+ var pushAdd = (ops, path, after) => {
619
+ ops.push(addPair(path, after));
620
+ return OPERATION_WEIGHT + weighCarried(after);
621
+ };
622
+ var pushRemove = (ops, path, before) => {
623
+ ops.push(removePair(path, before));
624
+ return OPERATION_WEIGHT + weighCarried(before);
625
+ };
626
+ var pushReplace = (ops, path, before, after) => {
627
+ ops.push(replacePair(path, before, after));
628
+ return OPERATION_WEIGHT + weighCarried(before) + weighCarried(after);
629
+ };
630
+ var tryCollapse = (before, after, path, ops, opsStart, atomicWeight) => {
631
+ if (atomicWeight === 0) return 0;
632
+ const beforeWeight = weighValue(before, atomicWeight);
633
+ const afterWeight = weighValue(after, atomicWeight - beforeWeight);
634
+ const collapsedWeight = OPERATION_WEIGHT + beforeWeight + afterWeight;
635
+ if (collapsedWeight < atomicWeight) {
636
+ assertSafeSubtree(before, path);
637
+ assertSafeSubtree(after, path);
638
+ ops.splice(opsStart, ops.length - opsStart, replacePair(path, before, after));
639
+ return collapsedWeight;
640
+ }
641
+ return atomicWeight;
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);
670
+ }
671
+ };
672
+ var isCanonicalArrayIndex = (key) => {
673
+ const index = Number(key);
674
+ return Number.isInteger(index) && index >= 0 && index < 4294967295 && String(index) === key;
675
+ };
676
+ var diffObjectProperties = (before, after, path, ops, ancestors, ignoreArrayIndexes) => {
677
+ let weight = 0;
678
+ for (const key of /* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])) {
679
+ if (ignoreArrayIndexes && isCanonicalArrayIndex(key)) continue;
680
+ const nextPath = appendOperationPath(path, key);
681
+ assertSafePath(nextPath);
682
+ const beforeDescriptor = Reflect.getOwnPropertyDescriptor(before, key);
683
+ const afterDescriptor = Reflect.getOwnPropertyDescriptor(after, key);
684
+ if (beforeDescriptor?.get || afterDescriptor?.get) continue;
685
+ if (!beforeDescriptor) {
686
+ assertSafeSubtree(Reflect.get(after, key), nextPath);
687
+ weight += pushAdd(ops, nextPath, Reflect.get(after, key));
688
+ } else if (!afterDescriptor) {
689
+ assertSafeSubtree(Reflect.get(before, key), nextPath);
690
+ weight += pushRemove(ops, nextPath, Reflect.get(before, key));
691
+ } else {
692
+ weight += diffValue(Reflect.get(before, key), Reflect.get(after, key), nextPath, ops, ancestors);
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);
719
+ }
720
+ weight += diffObjectProperties(before, after, path, ops, ancestors, true);
721
+ return weight;
722
+ };
723
+ var walkContainer = (before, after, path, ops, ancestors, walk) => {
724
+ if (hasAncestorPair(ancestors, before, after)) throw cyclicError(path);
725
+ enterAncestorPair(ancestors, before, after);
726
+ try {
727
+ if (path.length === 0) {
728
+ walk();
729
+ return 0;
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
+ );
757
+ }
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;
60
766
  };
61
767
  function diffSnapshots(before, after) {
62
- const ops = [];
63
- diffValue(before, after, [], ops);
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());
64
773
  return ops;
65
774
  }
66
775
 
67
- // src/createState.ts
68
- var stateBrand = /* @__PURE__ */ Symbol.for("opshot.state");
69
- var metaBrand = /* @__PURE__ */ Symbol.for("opshot.meta");
70
- var hasOwn = (value, key) => Object.hasOwn(value, key);
71
- function createMeta(defaults) {
72
- const token = defaults === void 0 ? { [metaBrand]: true } : { defaults, [metaBrand]: true };
73
- return token;
776
+ // src/emitter.ts
777
+ var emitters = /* @__PURE__ */ new WeakMap();
778
+ var { proxyStateMap: proxyStateMap3 } = unstable_getInternalStates();
779
+ var isObjectLike3 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
780
+ var augmentBareCycleError = (error) => {
781
+ const path = getCyclicPath(error);
782
+ if (path === void 0) return void 0;
783
+ return new Error(
784
+ `opshot: a bare write created a cyclic value at ${formatOperationPath(path)}. Cycles cannot be tracked. This surfaced asynchronously because the write was not inside transact. Use transact for catchable cycle errors, ignore() for back-linked structures, or ids.`
785
+ );
786
+ };
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;
74
797
  }
75
- function createState(define, meta) {
76
- return createGroupState(define, void 0, meta);
798
+ function getEmitter(state) {
799
+ return emitters.get(resolveEmitterTarget(state));
77
800
  }
78
- function createGroupState(define, groupListeners, metaToken) {
79
- const callback = typeof define === "function" ? define : () => define;
80
- const listeners = /* @__PURE__ */ new Set();
81
- const created = {};
82
- const requireProxy = () => {
83
- const { proxied } = created;
84
- if (!proxied) throw new Error("opshot: called during createState definition");
85
- return proxied;
86
- };
87
- const get = () => snapshot(requireProxy());
88
- const mutate = (callback2, ...metaArgs) => {
89
- const [meta] = metaArgs;
90
- const proxied = requireProxy();
91
- if (handle.isMutating) throw new Error("opshot: nested mutate on the same state");
92
- handle.isMutating = true;
93
- const before = snapshot(proxied);
94
- try {
95
- callback2(proxied);
96
- } finally {
97
- handle.isMutating = false;
98
- }
99
- const after = snapshot(proxied);
100
- if (before === after) return;
101
- if (listeners.size === 0 && (groupListeners?.size ?? 0) === 0) return;
102
- const ops = diffSnapshots(before, after);
801
+ var hasListeners = (record) => record.listeners.size > 0 || (record.groupListeners?.size ?? 0) > 0;
802
+ var armWatchdog = (record) => {
803
+ if (record.disarm !== void 0) return;
804
+ record.lastReported = snapshot(record.target);
805
+ record.disarm = subscribe(record.target, () => {
806
+ emitBareFlush(record.target);
807
+ });
808
+ };
809
+ var disarmWatchdog = (record) => {
810
+ record.disarm?.();
811
+ record.disarm = void 0;
812
+ };
813
+ var deliver = (record, ops, meta) => {
814
+ for (const listener of [...record.groupListeners ?? []]) listener(record.target, ops, meta);
815
+ for (const listener of [...record.listeners]) listener(ops, meta);
816
+ };
817
+ var requireObjectSnapshot = (value) => {
818
+ if (value !== null && (typeof value === "object" || typeof value === "function")) return value;
819
+ throw new Error("opshot: state snapshots must have an object root");
820
+ };
821
+ var reportBareDiff = (record) => {
822
+ const current = snapshot(record.target);
823
+ if (current === record.lastReported) return;
824
+ const previous = record.lastReported;
825
+ record.lastReported = current;
826
+ if (!hasListeners(record)) return;
827
+ try {
828
+ const ops = diffSnapshots(requireObjectSnapshot(previous), requireObjectSnapshot(current));
103
829
  if (ops.length === 0) return;
104
- const emittedMeta = metaToken?.defaults !== void 0 ? { ...metaToken.defaults, ...meta } : meta ?? {};
105
- for (const listener of [...groupListeners ?? []]) listener(after, ops, emittedMeta);
106
- for (const listener of [...listeners]) listener(after, ops, emittedMeta);
830
+ deliver(record, ops, void 0);
831
+ } catch (error) {
832
+ throw augmentBareCycleError(error) ?? error;
833
+ }
834
+ };
835
+ var settlePendingBare = (record) => {
836
+ reportBareDiff(record);
837
+ };
838
+ function getOrCreateEmitter(target, groupListeners) {
839
+ const resolved = resolveEmitterTarget(target);
840
+ const existing = emitters.get(resolved);
841
+ if (existing !== void 0) return existing;
842
+ const record = {
843
+ listeners: /* @__PURE__ */ new Set(),
844
+ groupListeners,
845
+ lastReported: snapshot(resolved),
846
+ isMutating: false,
847
+ target: resolved
107
848
  };
108
- const subscribe = (listener) => {
109
- listeners.add(listener);
110
- return () => {
111
- listeners.delete(listener);
112
- };
849
+ emitters.set(resolved, record);
850
+ return record;
851
+ }
852
+ function mintGroupedEmitter(target, groupListeners) {
853
+ const record = getOrCreateEmitter(target, groupListeners);
854
+ armWatchdog(record);
855
+ return record;
856
+ }
857
+ function emitBareFlush(target) {
858
+ const record = getEmitter(target);
859
+ if (record === void 0) return;
860
+ reportBareDiff(record);
861
+ }
862
+ function addStateListener(state, listener) {
863
+ const target = resolveEmitterTarget(state);
864
+ let record = emitters.get(target);
865
+ if (record === void 0) {
866
+ record = getOrCreateEmitter(target);
867
+ armWatchdog(record);
868
+ } else if (record.disarm === void 0 && record.groupListeners === void 0) {
869
+ armWatchdog(record);
870
+ }
871
+ record.listeners.add(listener);
872
+ return () => {
873
+ if (!record.listeners.delete(listener)) return;
874
+ if (record.groupListeners === void 0 && record.listeners.size === 0) {
875
+ disarmWatchdog(record);
876
+ emitters.delete(target);
877
+ }
113
878
  };
114
- const isSameState = (other) => isState(other) && other.op === handle;
115
- const unwrap = () => {
116
- const { op, mutate: mutate2, ...rest } = get();
117
- return rest;
879
+ }
880
+ function addGroupListener(groupListeners, listener) {
881
+ groupListeners.add(listener);
882
+ return () => {
883
+ groupListeners.delete(listener);
118
884
  };
119
- const literal = callback(mutate, get);
120
- for (const key of ["op", "mutate"]) {
121
- if (Object.hasOwn(literal, key)) throw new Error(`opshot: "${key}" is a reserved key on a state`);
885
+ }
886
+
887
+ // src/utils/constructorName.ts
888
+ var constructorName = (candidate) => typeof candidate === "function" && candidate.name !== "" ? candidate.name : "Object";
889
+
890
+ // src/valtio/boundaryErrors.ts
891
+ var ignoreOption = "ignore(value) to store it by reference, untracked";
892
+ var unsafeTrackDataOption = "unsafeTrack(value) to track its data anyway";
893
+ var unsafeTrackPrivateOption = "unsafeTrack(value) tracks public fields while private methods throw on snapshots and undo drops that state";
894
+ var unsafeTrackSlotOption = "unsafeTrack(value) tracks public fields while slot methods throw on snapshots and undo drops that state";
895
+ var unsafeTrackLossyOption = "unsafeTrack(value) to track it lossily";
896
+ var boundaryError = (className, reason, options) => new Error(
897
+ `opshot: ${className} cannot be tracked (${reason}). Options:
898
+ ${options.map((option) => `- ${option}`).join("\n")}`
899
+ );
900
+ var slotContainerError = (className, trackedName) => boundaryError(className, "its state lives in internal slots", [
901
+ `use ${trackedName} for a tracked equivalent`,
902
+ unsafeTrackLossyOption,
903
+ ignoreOption
904
+ ]);
905
+ var arraySubclassError = (className) => boundaryError(className, "array subclasses lose their prototype in snapshots", [
906
+ unsafeTrackDataOption,
907
+ ignoreOption
908
+ ]);
909
+ var cleanClassError = (className) => boundaryError(className, "arrow-method writes won't be tracked", [unsafeTrackDataOption, ignoreOption]);
910
+ var privateClassError = (className) => boundaryError(className, "its state is hidden in private fields", [unsafeTrackPrivateOption, ignoreOption]);
911
+ var nativeClassError = (className) => boundaryError(className, "its state is hidden in internal slots", [unsafeTrackSlotOption, ignoreOption]);
912
+ var snapshotDonationError = (key) => new Error(
913
+ `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.`
914
+ );
915
+ var reservedDataPathError = (path) => new Error(`opshot: reserved data path /${path.join("/")}`);
916
+ var inheritsFromPrototype = (value, prototype) => {
917
+ for (let current = Reflect.getPrototypeOf(value); current !== null; current = Reflect.getPrototypeOf(current))
918
+ if (current === prototype) return true;
919
+ return false;
920
+ };
921
+ var rejectionError = (value, kind) => {
922
+ const className = constructorName(value.constructor);
923
+ if (inheritsFromPrototype(value, Map.prototype)) return slotContainerError(className, "TrackedMap");
924
+ if (inheritsFromPrototype(value, Set.prototype)) return slotContainerError(className, "TrackedSet");
925
+ if (inheritsFromPrototype(value, Date.prototype)) return slotContainerError(className, "TrackedDate");
926
+ switch (kind) {
927
+ case "arraySubclass":
928
+ return arraySubclassError(className);
929
+ case "cleanClass":
930
+ return cleanClassError(className);
931
+ case "privateClass":
932
+ return privateClassError(className);
933
+ case "nativeClass":
934
+ return nativeClassError(className);
122
935
  }
123
- const base = Object.create(Reflect.getPrototypeOf(literal));
124
- Object.defineProperties(base, Object.getOwnPropertyDescriptors(literal));
125
- const handle = { unsafeMutable: base, isMutating: false, subscribe, isSameState, unwrap, [stateBrand]: true };
126
- Object.defineProperty(base, "op", { value: ref(handle), enumerable: true, writable: false, configurable: false });
127
- Object.defineProperty(base, "mutate", { value: mutate, enumerable: true, writable: false, configurable: false });
128
- created.proxied = proxy(base);
129
- handle.unsafeMutable = created.proxied;
130
- return get();
936
+ };
937
+
938
+ // src/valtio/constructorPathGuard.ts
939
+ var { refSet: refSet4 } = unstable_getInternalStates();
940
+ var constructorPathTargetCounts = /* @__PURE__ */ new WeakMap();
941
+ var rootGraphsByRoot = /* @__PURE__ */ new WeakMap();
942
+ var rootGraphReferences = /* @__PURE__ */ new WeakMap();
943
+ var rootGraphsByTarget = /* @__PURE__ */ new WeakMap();
944
+ var getRawObject = (value) => {
945
+ const resolved = resolveIdentity(value);
946
+ return typeof resolved === "object" && resolved !== null ? resolved : void 0;
947
+ };
948
+ var getTrackedRawObject = (value) => {
949
+ const target = getRawObject(value);
950
+ if (!target || refSet4.has(target) || Object.isFrozen(target)) return void 0;
951
+ return isTrackable(target) ? target : void 0;
952
+ };
953
+ var getEnumerableDataChild = (target, key) => {
954
+ if (typeof key !== "string") return void 0;
955
+ const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
956
+ if (!descriptor?.enumerable || !("value" in descriptor)) return void 0;
957
+ return getTrackedRawObject(descriptor.value);
958
+ };
959
+ var adjustConstructorPathTarget = (target, change) => {
960
+ const next = (constructorPathTargetCounts.get(target) ?? 0) + change;
961
+ if (next > 0) constructorPathTargetCounts.set(target, next);
962
+ else constructorPathTargetCounts.delete(target);
963
+ };
964
+ var constructorPathTargetCount = (target) => constructorPathTargetCounts.get(target) ?? 0;
965
+ var releaseFinalizationState = (state) => {
966
+ if (!state.active) return;
967
+ state.active = false;
968
+ for (const { target, count } of state.constructorTargets) {
969
+ const resolved = target.deref();
970
+ if (resolved) adjustConstructorPathTarget(resolved, -count);
971
+ }
972
+ state.constructorTargets = [];
973
+ };
974
+ var rootGraphFinalizer = new FinalizationRegistry(releaseFinalizationState);
975
+ var getRootGraphReference = (graph) => {
976
+ const existing = rootGraphReferences.get(graph);
977
+ if (existing) return existing;
978
+ const reference = new WeakRef(graph);
979
+ rootGraphReferences.set(graph, reference);
980
+ return reference;
981
+ };
982
+ var releaseRootGraph = (graph) => {
983
+ const reference = getRootGraphReference(graph);
984
+ for (const target of graph.targets) {
985
+ const references = rootGraphsByTarget.get(target);
986
+ references?.delete(reference);
987
+ if (references?.size === 0) rootGraphsByTarget.delete(target);
988
+ }
989
+ const root = graph.root.deref();
990
+ if (root) rootGraphsByRoot.delete(root);
991
+ releaseFinalizationState(graph.finalizationState);
992
+ rootGraphFinalizer.unregister(graph.finalizationState);
993
+ graph.targets.clear();
994
+ graph.constructorTargets.clear();
995
+ };
996
+ var getRootGraphs = (target) => {
997
+ const references = rootGraphsByTarget.get(target);
998
+ if (!references) return [];
999
+ const graphs = new Array();
1000
+ for (const reference of references) {
1001
+ const graph = reference.deref();
1002
+ if (!graph) {
1003
+ references.delete(reference);
1004
+ continue;
1005
+ }
1006
+ if (!graph.root.deref()) {
1007
+ releaseRootGraph(graph);
1008
+ continue;
1009
+ }
1010
+ graphs.push(graph);
1011
+ }
1012
+ if (references.size === 0) rootGraphsByTarget.delete(target);
1013
+ return graphs;
1014
+ };
1015
+ var recomputeRootGraph = (graph) => {
1016
+ const root = graph.root.deref();
1017
+ if (!root) {
1018
+ releaseRootGraph(graph);
1019
+ return;
1020
+ }
1021
+ const targets = /* @__PURE__ */ new Set();
1022
+ const constructorTargets = /* @__PURE__ */ new Map();
1023
+ const visit = (target) => {
1024
+ if (targets.has(target)) return;
1025
+ targets.add(target);
1026
+ const constructorTarget = getEnumerableDataChild(target, "constructor");
1027
+ if (constructorTarget)
1028
+ constructorTargets.set(constructorTarget, (constructorTargets.get(constructorTarget) ?? 0) + 1);
1029
+ for (const key of Object.keys(target)) {
1030
+ const child = getEnumerableDataChild(target, key);
1031
+ if (child) visit(child);
1032
+ }
1033
+ };
1034
+ visit(root);
1035
+ for (const [target, count] of graph.constructorTargets) adjustConstructorPathTarget(target, -count);
1036
+ for (const [target, count] of constructorTargets) adjustConstructorPathTarget(target, count);
1037
+ for (const target of graph.targets) {
1038
+ if (targets.has(target)) continue;
1039
+ const references = rootGraphsByTarget.get(target);
1040
+ references?.delete(getRootGraphReference(graph));
1041
+ if (references?.size === 0) rootGraphsByTarget.delete(target);
1042
+ }
1043
+ for (const target of targets) {
1044
+ if (graph.targets.has(target)) continue;
1045
+ const references = rootGraphsByTarget.get(target) ?? /* @__PURE__ */ new Set();
1046
+ references.add(getRootGraphReference(graph));
1047
+ rootGraphsByTarget.set(target, references);
1048
+ }
1049
+ graph.targets = targets;
1050
+ graph.constructorTargets = constructorTargets;
1051
+ graph.finalizationState.constructorTargets = [...constructorTargets].map(([target, count]) => ({
1052
+ target: new WeakRef(target),
1053
+ count
1054
+ }));
1055
+ };
1056
+ var registerTrackedRoot = (value) => {
1057
+ const root = getTrackedRawObject(value);
1058
+ if (!root || rootGraphsByRoot.has(root)) return;
1059
+ const finalizationState = { active: true, constructorTargets: [] };
1060
+ const graph = {
1061
+ root: new WeakRef(root),
1062
+ finalizationState,
1063
+ targets: /* @__PURE__ */ new Set(),
1064
+ constructorTargets: /* @__PURE__ */ new Map()
1065
+ };
1066
+ rootGraphsByRoot.set(root, graph);
1067
+ rootGraphFinalizer.register(root, finalizationState, finalizationState);
1068
+ recomputeRootGraph(graph);
1069
+ };
1070
+
1071
+ // src/valtio/snapshotAccessors.ts
1072
+ var { refSet: refSet5, proxyStateMap: proxyStateMap4, snapCache: snapCache2 } = unstable_getInternalStates();
1073
+ var createSnapshotPreservingAccessors = (target, version) => {
1074
+ const cached = snapCache2.get(target);
1075
+ if (cached?.[0] === version) {
1076
+ const cachedSnapshot = cached[1];
1077
+ registerSnapshotCopy(cachedSnapshot, target);
1078
+ return cachedSnapshot;
1079
+ }
1080
+ const snap = Array.isArray(target) ? [] : Object.create(Reflect.getPrototypeOf(target));
1081
+ registerSnapshotCopy(snap, target);
1082
+ markToTrack(snap, true);
1083
+ snapCache2.set(target, [version, snap]);
1084
+ for (const key of Reflect.ownKeys(target)) {
1085
+ if (Object.getOwnPropertyDescriptor(snap, key)) continue;
1086
+ const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
1087
+ if (!descriptor) continue;
1088
+ if (descriptor.get || descriptor.set) {
1089
+ Object.defineProperty(snap, key, {
1090
+ get: descriptor.get,
1091
+ set: descriptor.set,
1092
+ enumerable: descriptor.enumerable,
1093
+ configurable: true
1094
+ });
1095
+ continue;
1096
+ }
1097
+ const value = Reflect.get(target, key);
1098
+ const snapshotDescriptor = { value, enumerable: descriptor.enumerable, configurable: true };
1099
+ if (typeof value === "object" && value !== null) {
1100
+ if (refSet5.has(value)) {
1101
+ markToTrack(value, false);
1102
+ } else {
1103
+ const childState = proxyStateMap4.get(value);
1104
+ if (childState)
1105
+ snapshotDescriptor.value = createSnapshotPreservingAccessors(childState[0], childState[1]());
1106
+ }
1107
+ }
1108
+ Object.defineProperty(snap, key, snapshotDescriptor);
1109
+ }
1110
+ if (Array.isArray(target) && snap.length !== target.length) {
1111
+ snap.length = target.length;
1112
+ }
1113
+ if (isUnsafeTracked(target)) unsafeTrack(snap);
1114
+ return snap;
1115
+ };
1116
+
1117
+ // src/valtio/boundary.ts
1118
+ var assertSafeDataPaths = (value, path = new Array(), activeAncestors = /* @__PURE__ */ new WeakSet()) => {
1119
+ if (typeof value !== "object" || value === null || activeAncestors.has(value)) return;
1120
+ activeAncestors.add(value);
1121
+ try {
1122
+ for (const key of Object.keys(value)) {
1123
+ const nextPath = [...path, key];
1124
+ if (key === "__proto__" || key === "prototype" && path[path.length - 1] === "constructor")
1125
+ throw reservedDataPathError(nextPath);
1126
+ const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
1127
+ if (descriptor && "value" in descriptor) assertSafeDataPaths(descriptor.value, nextPath, activeAncestors);
1128
+ }
1129
+ } finally {
1130
+ activeAncestors.delete(value);
1131
+ }
1132
+ };
1133
+ var installed = false;
1134
+ function installBoundary() {
1135
+ if (installed) return;
1136
+ installed = true;
1137
+ unstable_replaceInternalFunction("canProxy", () => (value) => {
1138
+ if (typeof value !== "object" || value === null) return false;
1139
+ const lane = admissionLane(value);
1140
+ if (lane !== "reject") return lane === "track";
1141
+ const kind = classifyValue(value);
1142
+ if (kind === "plain" || kind === "plainArray") return true;
1143
+ throw rejectionError(value, kind);
1144
+ });
1145
+ unstable_replaceInternalFunction("createSnapshot", () => createSnapshotPreservingAccessors);
1146
+ unstable_replaceInternalFunction(
1147
+ "createHandler",
1148
+ (createHandler2) => (isInitializing, addPropListener, removePropListener, notifyUpdate) => {
1149
+ let setDepth = 0;
1150
+ const handler = createHandler2(isInitializing, addPropListener, removePropListener, notifyUpdate);
1151
+ const defaultDelete = handler.deleteProperty;
1152
+ const defaultSet = handler.set;
1153
+ if (!defaultDelete || !defaultSet)
1154
+ throw new Error("opshot: valtio default handler is missing a mutation trap");
1155
+ return {
1156
+ ...handler,
1157
+ deleteProperty(target, prop) {
1158
+ const rootGraphs = getRootGraphs(target);
1159
+ const previousChild = rootGraphs.length > 0 ? getEnumerableDataChild(target, prop) : void 0;
1160
+ const hadOwn = Object.hasOwn(target, prop);
1161
+ const deleted = defaultDelete(target, prop);
1162
+ if (deleted && hadOwn && previousChild && !Object.hasOwn(target, prop))
1163
+ for (const graph of rootGraphs) recomputeRootGraph(graph);
1164
+ return deleted;
1165
+ },
1166
+ set(target, prop, value, receiver) {
1167
+ const assigned = value;
1168
+ if (prop === "__proto__") throw reservedDataPathError(["__proto__"]);
1169
+ if (prop === "prototype" && constructorPathTargetCount(target) > 0)
1170
+ throw reservedDataPathError(["constructor", "prototype"]);
1171
+ if (prop === "constructor" && typeof assigned === "object" && assigned !== null) {
1172
+ const prototypeDescriptor = Reflect.getOwnPropertyDescriptor(assigned, "prototype");
1173
+ if (prototypeDescriptor?.enumerable) throw reservedDataPathError(["constructor", "prototype"]);
1174
+ }
1175
+ assertSafeDataPaths(assigned, typeof prop === "string" ? [prop] : []);
1176
+ if (typeof assigned === "object" && assigned !== null) {
1177
+ const untracked = getUntracked(assigned) ?? assigned;
1178
+ if (getRegisteredTarget(untracked) !== void 0) throw snapshotDonationError(prop);
1179
+ }
1180
+ const rootGraphs = getRootGraphs(target);
1181
+ const previousChild = rootGraphs.length > 0 ? getEnumerableDataChild(target, prop) : void 0;
1182
+ const previousLength = rootGraphs.length > 0 && Array.isArray(target) && prop === "length" ? Reflect.get(target, "length") : void 0;
1183
+ setDepth += 1;
1184
+ try {
1185
+ const written = defaultSet(target, prop, value, receiver);
1186
+ const currentChild = rootGraphs.length > 0 ? getEnumerableDataChild(target, prop) : void 0;
1187
+ const currentLength = previousLength === void 0 ? void 0 : Reflect.get(target, "length");
1188
+ if (previousChild !== currentChild || previousLength !== currentLength)
1189
+ for (const graph of rootGraphs) recomputeRootGraph(graph);
1190
+ return written;
1191
+ } finally {
1192
+ setDepth -= 1;
1193
+ }
1194
+ },
1195
+ defineProperty(target, prop, descriptor) {
1196
+ if (setDepth > 0 || isInitializing()) return Reflect.defineProperty(target, prop, descriptor);
1197
+ throw new Error(
1198
+ "opshot: defineProperty is not supported on tracked state; define properties in the createMutableState input"
1199
+ );
1200
+ },
1201
+ setPrototypeOf() {
1202
+ throw new Error("opshot: setPrototypeOf is not supported on tracked state");
1203
+ }
1204
+ };
1205
+ }
1206
+ );
131
1207
  }
132
- function isState(value) {
133
- if (typeof value !== "object" || value === null || !hasOwn(value, "op")) return false;
134
- const handle = value.op;
135
- if (typeof handle !== "object" || handle === null || !hasOwn(handle, stateBrand)) return false;
136
- return handle[stateBrand] === true;
1208
+
1209
+ // src/createMutableState.ts
1210
+ function createMutableState(properties, group) {
1211
+ installBoundary();
1212
+ assertSafeDataPaths(properties);
1213
+ const base = Object.create(Reflect.getPrototypeOf(properties));
1214
+ Object.defineProperties(base, Object.getOwnPropertyDescriptors(properties));
1215
+ const proxied = proxy(base);
1216
+ registerTrackedRoot(base);
1217
+ if (group !== void 0) {
1218
+ mintGroupedEmitter(proxied, getGroupListeners(group));
1219
+ }
1220
+ return proxied;
137
1221
  }
138
1222
 
139
1223
  // src/createGroup.ts
140
- function createGroup(meta) {
1224
+ var groupListenersByGroup = /* @__PURE__ */ new WeakMap();
1225
+ function isGroup(value) {
1226
+ return typeof value === "object" && value !== null && groupListenersByGroup.has(value);
1227
+ }
1228
+ function getGroupListeners(group) {
1229
+ const listeners = groupListenersByGroup.get(group);
1230
+ if (listeners === void 0) throw new Error("opshot: unknown group");
1231
+ return listeners;
1232
+ }
1233
+ function createGroup() {
141
1234
  const listeners = /* @__PURE__ */ new Set();
1235
+ const group = {
1236
+ createMutableState(properties) {
1237
+ return createMutableState(properties, group);
1238
+ }
1239
+ };
1240
+ groupListenersByGroup.set(group, listeners);
1241
+ return group;
1242
+ }
1243
+
1244
+ // src/transact.ts
1245
+ function transact(state, mutate, meta) {
1246
+ const record = getEmitter(state);
1247
+ if (record === void 0) {
1248
+ mutate();
1249
+ return;
1250
+ }
1251
+ if (record.isMutating) throw new Error("opshot: nested transact on the same state");
1252
+ settlePendingBare(record);
1253
+ record.isMutating = true;
1254
+ try {
1255
+ mutate();
1256
+ } finally {
1257
+ record.isMutating = false;
1258
+ }
1259
+ const after = snapshot(record.target);
1260
+ const before = record.lastReported;
1261
+ record.lastReported = after;
1262
+ if (before === after) return;
1263
+ if (!hasListeners(record)) return;
1264
+ const ops = diffSnapshots(requireObjectSnapshot(before), requireObjectSnapshot(after));
1265
+ if (ops.length === 0) return;
1266
+ deliver(record, ops, meta);
1267
+ }
1268
+
1269
+ // src/ops/applyOps.ts
1270
+ var isObjectLike4 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
1271
+ var sameValueZero = (first, second) => first === second || first !== first && second !== second;
1272
+ var sameIdentity = (first, second) => sameValueZero(resolveIdentity(first), resolveIdentity(second));
1273
+ var assertApplicable = (operation) => {
1274
+ if (typeof operation === "object" && operation !== null && "do" in operation) {
1275
+ throw new Error("opshot: applyOps applies operation halves; pass op.do or op.undo.");
1276
+ }
1277
+ if (!isOperation(operation)) {
1278
+ throw new Error(
1279
+ "opshot: this op is a copy (spread, JSON, or structuredClone) and has lost its value. Apply the op objects the listener delivered; never copy them."
1280
+ );
1281
+ }
1282
+ };
1283
+ var unresolvedError = (path) => new Error(`opshot: ${formatOperationPath(path)} does not resolve to a supported operation address`);
1284
+ var matchesAppliedValue = (current, expected) => {
1285
+ if (isObjectLike4(current) && isObjectLike4(expected)) return sameIdentity(current, expected);
1286
+ return Object.is(current, expected);
1287
+ };
1288
+ var setOrThrow = (target, key, value) => {
1289
+ const written = Reflect.set(target, key, value);
1290
+ const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
1291
+ const current = descriptor && "value" in descriptor ? Reflect.get(target, key) : void 0;
1292
+ if (!written || !descriptor || !("value" in descriptor) || !matchesAppliedValue(current, value)) {
1293
+ throw new Error(`opshot: replay could not restore ${String(key)}`);
1294
+ }
1295
+ };
1296
+ var deleteOrThrow = (target, key) => {
1297
+ if (!Reflect.deleteProperty(target, key)) throw new Error(`opshot: replay could not remove ${String(key)}`);
1298
+ };
1299
+ var restoreRecordedContent = (attached, recorded, restored) => {
1300
+ if (restored.has(recorded)) return;
1301
+ restored.add(recorded);
1302
+ const recordedKeys = Reflect.ownKeys(recorded);
1303
+ const orderedKeys = Array.isArray(recorded) ? ["length", ...recordedKeys.filter((key) => key !== "length")] : recordedKeys;
1304
+ for (const key of orderedKeys) {
1305
+ const descriptor = Reflect.getOwnPropertyDescriptor(recorded, key);
1306
+ const attachedDescriptor = Reflect.getOwnPropertyDescriptor(attached, key);
1307
+ if (!descriptor || !("value" in descriptor) || attachedDescriptor && !("value" in attachedDescriptor)) continue;
1308
+ const value = descriptor.value;
1309
+ if (isObjectLike4(value)) {
1310
+ const target = getRegisteredTarget(value);
1311
+ if (target !== void 0) {
1312
+ setOrThrow(attached, key, target);
1313
+ const child = Reflect.get(attached, key);
1314
+ if (!isObjectLike4(child)) throw new Error(`opshot: replay could not reattach ${String(key)}`);
1315
+ restoreRecordedContent(child, value, restored);
1316
+ continue;
1317
+ }
1318
+ }
1319
+ setOrThrow(attached, key, value);
1320
+ }
1321
+ for (const key of Reflect.ownKeys(attached)) {
1322
+ if (Object.hasOwn(recorded, key)) continue;
1323
+ const descriptor = Reflect.getOwnPropertyDescriptor(attached, key);
1324
+ if (descriptor && "value" in descriptor) deleteOrThrow(attached, key);
1325
+ }
1326
+ };
1327
+ var getValuePayload = (operation) => {
1328
+ const original = getValueOriginal(operation);
1329
+ if (original !== void 0) {
1330
+ if (isObjectLike4(original) && getRegisteredTarget(original) !== void 0)
1331
+ return { recorded: original, fallback: void 0 };
1332
+ return { recorded: original, fallback: operation.value };
1333
+ }
1334
+ return { recorded: operation.value, fallback: operation.value };
1335
+ };
1336
+ var restoreValue = (payload, attach, readAttached) => {
1337
+ if (isObjectLike4(payload.recorded)) {
1338
+ const target = getRegisteredTarget(payload.recorded);
1339
+ if (target !== void 0) {
1340
+ attach(target);
1341
+ const attached = readAttached();
1342
+ if (!isObjectLike4(attached)) throw new Error("opshot: replay could not read a reattached target");
1343
+ restoreRecordedContent(attached, payload.recorded, /* @__PURE__ */ new WeakSet());
1344
+ return;
1345
+ }
1346
+ }
1347
+ attach(payload.fallback);
1348
+ };
1349
+ var getInheritedDescriptor = (target, key) => {
1350
+ let prototype = Reflect.getPrototypeOf(target);
1351
+ while (prototype !== null) {
1352
+ const descriptor = Reflect.getOwnPropertyDescriptor(prototype, key);
1353
+ if (descriptor) return descriptor;
1354
+ prototype = Reflect.getPrototypeOf(prototype);
1355
+ }
1356
+ return void 0;
1357
+ };
1358
+ var isCanonicalArrayIndex2 = (segment) => Number.isInteger(segment) && typeof segment === "number" && segment >= 0 && segment < 4294967295;
1359
+ var isCanonicalArrayIndexString = (segment) => {
1360
+ const index = Number(segment);
1361
+ return Number.isInteger(index) && index >= 0 && index < 4294967295 && String(index) === segment;
1362
+ };
1363
+ var requirePlainSegment = (parent, segment, path) => {
1364
+ if (Array.isArray(parent)) {
1365
+ if (isCanonicalArrayIndex2(segment)) return segment;
1366
+ if (typeof segment === "string" && !isCanonicalArrayIndexString(segment)) return segment;
1367
+ throw unresolvedError(path);
1368
+ }
1369
+ if (typeof segment === "string") return segment;
1370
+ throw unresolvedError(path);
1371
+ };
1372
+ var requirePlainProperty = (parent, segment, path) => {
1373
+ if (Array.isArray(parent) && segment === "length") return parent.length;
1374
+ const key = requirePlainSegment(parent, segment, path);
1375
+ const descriptor = Reflect.getOwnPropertyDescriptor(parent, key);
1376
+ if (!descriptor || !descriptor.enumerable || !("value" in descriptor)) throw unresolvedError(path);
1377
+ return Reflect.get(parent, key);
1378
+ };
1379
+ var resolveTraversalSegment = (parent, segment, path) => {
1380
+ if (!isObjectLike4(parent)) throw unresolvedError(path);
1381
+ return requirePlainProperty(parent, segment, path);
1382
+ };
1383
+ var resolveTerminal = (root, path) => {
1384
+ assertSafePath(path);
1385
+ if (path.length === 0) throw new Error("opshot: root operations are not supported");
1386
+ let parent = root;
1387
+ for (let index = 0; index < path.length - 1; index++) parent = resolveTraversalSegment(parent, path[index], path);
1388
+ if (!isObjectLike4(parent)) throw unresolvedError(path);
1389
+ return { parent, segment: path[path.length - 1] };
1390
+ };
1391
+ var applyPlain = (parent, segment, operation) => {
1392
+ const path = operation.path;
1393
+ if (Array.isArray(parent) && segment === "length") {
1394
+ if (operation.op !== "replace" || typeof operation.value !== "number" || !Number.isInteger(operation.value) || operation.value < 0 || operation.value > 4294967295) {
1395
+ throw unresolvedError(path);
1396
+ }
1397
+ setOrThrow(parent, "length", operation.value);
1398
+ return;
1399
+ }
1400
+ const key = requirePlainSegment(parent, segment, path);
1401
+ const descriptor = Reflect.getOwnPropertyDescriptor(parent, key);
1402
+ const present = descriptor !== void 0 && descriptor.enumerable && "value" in descriptor;
1403
+ if (descriptor !== void 0 && !present) throw unresolvedError(path);
1404
+ if (operation.op === "add" && present) throw unresolvedError(path);
1405
+ if (operation.op !== "add" && !present) throw unresolvedError(path);
1406
+ if (operation.op === "add") {
1407
+ const inheritedDescriptor = getInheritedDescriptor(parent, key);
1408
+ if (inheritedDescriptor && !("value" in inheritedDescriptor)) {
1409
+ throw new Error(`opshot: ${formatOperationPath(path)} resolves to an inherited accessor`);
1410
+ }
1411
+ }
1412
+ if (operation.op === "remove") {
1413
+ deleteOrThrow(parent, key);
1414
+ return;
1415
+ }
1416
+ if (!("value" in operation)) throw unresolvedError(path);
1417
+ restoreValue(
1418
+ getValuePayload(operation),
1419
+ (value) => setOrThrow(parent, key, value),
1420
+ () => Reflect.get(parent, key)
1421
+ );
1422
+ };
1423
+ function applyOperations(root, operations) {
1424
+ for (const operation of operations) {
1425
+ const terminal = resolveTerminal(root, operation.path);
1426
+ applyPlain(terminal.parent, terminal.segment, operation);
1427
+ }
1428
+ }
1429
+ function applyOps(state, operations, meta) {
1430
+ for (const operation of operations) assertApplicable(operation);
1431
+ transact(
1432
+ state,
1433
+ () => {
1434
+ applyOperations(resolveEmitterTarget(state), operations);
1435
+ },
1436
+ meta
1437
+ );
1438
+ }
1439
+
1440
+ // src/subscribe.ts
1441
+ function subscribe2(target, listener) {
1442
+ if (isGroup(target)) {
1443
+ return addGroupListener(getGroupListeners(target), (state, ops, meta) => {
1444
+ listener(state, ops, unwrapTransportMeta(meta));
1445
+ });
1446
+ }
1447
+ return addStateListener(target, (ops, meta) => {
1448
+ listener(ops, unwrapTransportMeta(meta));
1449
+ });
1450
+ }
1451
+ var channelStampBrand = /* @__PURE__ */ Symbol.for("opshot.channelStamp");
1452
+ function stampChannelMeta(channelId, meta) {
1453
+ return { [channelStampBrand]: channelId, meta };
1454
+ }
1455
+ function isChannelStamp(value) {
1456
+ return typeof value === "object" && value !== null && channelStampBrand in value;
1457
+ }
1458
+ function isOwnChannelStamp(value, channelId) {
1459
+ return isChannelStamp(value) && value[channelStampBrand] === channelId;
1460
+ }
1461
+ function unwrapTransportMeta(meta) {
1462
+ if (isChannelStamp(meta)) return meta.meta;
1463
+ return meta;
1464
+ }
1465
+ function toChannelContext(channelId, defaults, meta) {
1466
+ if (isOwnChannelStamp(meta, channelId)) {
1467
+ return { isTransaction: true, meta: { ...defaults, ...meta.meta } };
1468
+ }
1469
+ return { isTransaction: false, meta: unwrapTransportMeta(meta) };
1470
+ }
1471
+
1472
+ // src/createChannel.ts
1473
+ function createChannel(defaults) {
1474
+ const channelId = Object.freeze({});
1475
+ function transact2(state, mutate, meta) {
1476
+ transact(state, mutate, stampChannelMeta(channelId, meta));
1477
+ }
1478
+ function subscribe3(target, listener) {
1479
+ if (isGroup(target)) {
1480
+ return addGroupListener(getGroupListeners(target), (state, ops, meta) => {
1481
+ listener(
1482
+ state,
1483
+ ops,
1484
+ toChannelContext(channelId, defaults, meta)
1485
+ );
1486
+ });
1487
+ }
1488
+ return addStateListener(target, (ops, meta) => {
1489
+ listener(
1490
+ ops,
1491
+ toChannelContext(channelId, defaults, meta)
1492
+ );
1493
+ });
1494
+ }
1495
+ function applyOps2(state, operations, meta) {
1496
+ applyOps(state, operations, stampChannelMeta(channelId, meta));
1497
+ }
1498
+ return { transact: transact2, subscribe: subscribe3, applyOps: applyOps2 };
1499
+ }
1500
+
1501
+ // src/react/resolveWrapper.ts
1502
+ var { proxyStateMap: proxyStateMap5 } = unstable_getInternalStates();
1503
+ var isObjectLike5 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
1504
+ function unwrapWrapper(value) {
1505
+ if (!isObjectLike5(value) || proxyStateMap5.has(value)) return value;
1506
+ let current = value;
1507
+ while (isObjectLike5(current)) {
1508
+ const registeredTarget = getRegisteredWrapperTarget(current);
1509
+ if (registeredTarget === void 0) break;
1510
+ current = registeredTarget;
1511
+ }
1512
+ return current;
1513
+ }
1514
+
1515
+ // src/isState.ts
1516
+ var { proxyStateMap: proxyStateMap6 } = unstable_getInternalStates();
1517
+ function isState(value) {
1518
+ const resolved = unwrapWrapper(value);
1519
+ if (typeof resolved !== "object" || resolved === null) return false;
1520
+ return proxyStateMap6.has(resolved);
1521
+ }
1522
+
1523
+ // src/ignore.ts
1524
+ var ignore = ref;
1525
+
1526
+ // src/tracked/facadeGuard.ts
1527
+ var assertMutableFacade = (facade, mutationKey) => {
1528
+ const facadeSource = getUntracked(facade);
1529
+ const isRegisteredCopy = getRegisteredTarget(facade) !== void 0 || facadeSource !== null && getRegisteredTarget(facadeSource) !== void 0;
1530
+ const descriptor = Reflect.getOwnPropertyDescriptor(facade, mutationKey);
1531
+ if (isRegisteredCopy || descriptor !== void 0 && "writable" in descriptor && !descriptor.writable) {
1532
+ throw new Error("opshot: cannot mutate a tracked collection snapshot");
1533
+ }
1534
+ };
1535
+
1536
+ // src/tracked/trackedDate.ts
1537
+ var setLegacyYear = (date, year) => {
1538
+ const setYear = Reflect.get(date, "setYear");
1539
+ if (typeof setYear !== "function") throw new Error("opshot: Date.setYear is not available");
1540
+ const epochMs = Reflect.apply(setYear, date, [year]);
1541
+ if (typeof epochMs !== "number") throw new Error("opshot: Date.setYear returned a non-number");
1542
+ return epochMs;
1543
+ };
1544
+ var constructDate = (args) => {
1545
+ switch (args.length) {
1546
+ case 0:
1547
+ return /* @__PURE__ */ new Date();
1548
+ case 1:
1549
+ return new Date(args[0]);
1550
+ case 2:
1551
+ return new Date(args[0], args[1]);
1552
+ case 3:
1553
+ return new Date(args[0], args[1], args[2]);
1554
+ case 4:
1555
+ return new Date(args[0], args[1], args[2], args[3]);
1556
+ case 5:
1557
+ return new Date(args[0], args[1], args[2], args[3], args[4]);
1558
+ case 6:
1559
+ return new Date(args[0], args[1], args[2], args[3], args[4], args[5]);
1560
+ case 7:
1561
+ return new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
1562
+ }
1563
+ };
1564
+ var TrackedDate = class {
1565
+ constructor(...args) {
1566
+ installBoundary();
1567
+ this.epochMs = constructDate(args).getTime();
1568
+ }
1569
+ readDate() {
1570
+ return new Date(this.epochMs);
1571
+ }
1572
+ write(mutate) {
1573
+ assertMutableFacade(this, "epochMs");
1574
+ const epochMs = mutate(this.readDate());
1575
+ this.epochMs = epochMs;
1576
+ return epochMs;
1577
+ }
1578
+ toString() {
1579
+ return this.readDate().toString();
1580
+ }
1581
+ toDateString() {
1582
+ return this.readDate().toDateString();
1583
+ }
1584
+ toTimeString() {
1585
+ return this.readDate().toTimeString();
1586
+ }
1587
+ toLocaleString(locales, options) {
1588
+ return this.readDate().toLocaleString(locales, options);
1589
+ }
1590
+ toLocaleDateString(locales, options) {
1591
+ return this.readDate().toLocaleDateString(locales, options);
1592
+ }
1593
+ toLocaleTimeString(locales, options) {
1594
+ return this.readDate().toLocaleTimeString(locales, options);
1595
+ }
1596
+ valueOf() {
1597
+ return this.readDate().valueOf();
1598
+ }
1599
+ getTime() {
1600
+ return this.readDate().getTime();
1601
+ }
1602
+ getFullYear() {
1603
+ return this.readDate().getFullYear();
1604
+ }
1605
+ getYear() {
1606
+ return this.readDate().getFullYear() - 1900;
1607
+ }
1608
+ getUTCFullYear() {
1609
+ return this.readDate().getUTCFullYear();
1610
+ }
1611
+ getMonth() {
1612
+ return this.readDate().getMonth();
1613
+ }
1614
+ getUTCMonth() {
1615
+ return this.readDate().getUTCMonth();
1616
+ }
1617
+ getDate() {
1618
+ return this.readDate().getDate();
1619
+ }
1620
+ getUTCDate() {
1621
+ return this.readDate().getUTCDate();
1622
+ }
1623
+ getDay() {
1624
+ return this.readDate().getDay();
1625
+ }
1626
+ getUTCDay() {
1627
+ return this.readDate().getUTCDay();
1628
+ }
1629
+ getHours() {
1630
+ return this.readDate().getHours();
1631
+ }
1632
+ getUTCHours() {
1633
+ return this.readDate().getUTCHours();
1634
+ }
1635
+ getMinutes() {
1636
+ return this.readDate().getMinutes();
1637
+ }
1638
+ getUTCMinutes() {
1639
+ return this.readDate().getUTCMinutes();
1640
+ }
1641
+ getSeconds() {
1642
+ return this.readDate().getSeconds();
1643
+ }
1644
+ getUTCSeconds() {
1645
+ return this.readDate().getUTCSeconds();
1646
+ }
1647
+ getMilliseconds() {
1648
+ return this.readDate().getMilliseconds();
1649
+ }
1650
+ getUTCMilliseconds() {
1651
+ return this.readDate().getUTCMilliseconds();
1652
+ }
1653
+ getTimezoneOffset() {
1654
+ return this.readDate().getTimezoneOffset();
1655
+ }
1656
+ setYear(year) {
1657
+ return this.write((date) => setLegacyYear(date, year));
1658
+ }
1659
+ setTime(...args) {
1660
+ return this.write((date) => date.setTime(...args));
1661
+ }
1662
+ setMilliseconds(...args) {
1663
+ return this.write((date) => date.setMilliseconds(...args));
1664
+ }
1665
+ setUTCMilliseconds(...args) {
1666
+ return this.write((date) => date.setUTCMilliseconds(...args));
1667
+ }
1668
+ setSeconds(...args) {
1669
+ return this.write((date) => date.setSeconds(...args));
1670
+ }
1671
+ setUTCSeconds(...args) {
1672
+ return this.write((date) => date.setUTCSeconds(...args));
1673
+ }
1674
+ setMinutes(...args) {
1675
+ return this.write((date) => date.setMinutes(...args));
1676
+ }
1677
+ setUTCMinutes(...args) {
1678
+ return this.write((date) => date.setUTCMinutes(...args));
1679
+ }
1680
+ setHours(...args) {
1681
+ return this.write((date) => date.setHours(...args));
1682
+ }
1683
+ setUTCHours(...args) {
1684
+ return this.write((date) => date.setUTCHours(...args));
1685
+ }
1686
+ setDate(...args) {
1687
+ return this.write((date) => date.setDate(...args));
1688
+ }
1689
+ setUTCDate(...args) {
1690
+ return this.write((date) => date.setUTCDate(...args));
1691
+ }
1692
+ setMonth(...args) {
1693
+ return this.write((date) => date.setMonth(...args));
1694
+ }
1695
+ setUTCMonth(...args) {
1696
+ return this.write((date) => date.setUTCMonth(...args));
1697
+ }
1698
+ setFullYear(...args) {
1699
+ return this.write((date) => date.setFullYear(...args));
1700
+ }
1701
+ setUTCFullYear(...args) {
1702
+ return this.write((date) => date.setUTCFullYear(...args));
1703
+ }
1704
+ toUTCString() {
1705
+ return this.readDate().toUTCString();
1706
+ }
1707
+ toGMTString() {
1708
+ return this.readDate().toUTCString();
1709
+ }
1710
+ toISOString() {
1711
+ return this.readDate().toISOString();
1712
+ }
1713
+ [Symbol.toPrimitive](hint) {
1714
+ const date = this.readDate();
1715
+ return hint === "number" ? date[Symbol.toPrimitive]("number") : date[Symbol.toPrimitive](hint);
1716
+ }
1717
+ };
1718
+ Object.defineProperty(TrackedDate.prototype, Symbol.toStringTag, {
1719
+ value: "TrackedDate",
1720
+ enumerable: false,
1721
+ configurable: false,
1722
+ writable: false
1723
+ });
1724
+
1725
+ // src/tracked/address.ts
1726
+ var internTable = /* @__PURE__ */ new WeakMap();
1727
+ var nextInternId = 0;
1728
+ var internIdentity = (key) => {
1729
+ const resolved = resolveIdentity(key);
1730
+ if (resolved === null || typeof resolved !== "object" && typeof resolved !== "function" && typeof resolved !== "symbol") {
1731
+ throw new Error("opshot: addressOf interned a non-identity value");
1732
+ }
1733
+ const existing = internTable.get(resolved);
1734
+ if (existing !== void 0) return existing;
1735
+ const id = nextInternId;
1736
+ nextInternId += 1;
1737
+ internTable.set(resolved, id);
1738
+ return id;
1739
+ };
1740
+ var addressOf = (key) => {
1741
+ if (key === null) return "z";
1742
+ if (key === void 0) return "u";
1743
+ switch (typeof key) {
1744
+ case "string":
1745
+ return `s${key}`;
1746
+ case "number":
1747
+ return `n${String(key)}`;
1748
+ case "bigint":
1749
+ return `i${String(key)}`;
1750
+ case "boolean":
1751
+ return key ? "b1" : "b0";
1752
+ case "symbol": {
1753
+ const registered = Symbol.keyFor(key);
1754
+ if (registered !== void 0) return `r${registered}`;
1755
+ return `o${internIdentity(key)}`;
1756
+ }
1757
+ case "object":
1758
+ case "function":
1759
+ return `o${internIdentity(key)}`;
1760
+ default:
1761
+ throw new Error(`opshot: addressOf received unsupported key type ${typeof key}`);
1762
+ }
1763
+ };
1764
+
1765
+ // src/tracked/iterateSlots.ts
1766
+ function* iterateSlots(getSlots) {
1767
+ let slots = getSlots();
1768
+ let index = 0;
1769
+ for (; ; ) {
1770
+ const current = getSlots();
1771
+ if (current !== slots) {
1772
+ slots = current;
1773
+ index = 0;
1774
+ }
1775
+ if (index >= slots.length) return;
1776
+ const entry = slots[index];
1777
+ index += 1;
1778
+ if (entry !== null && entry !== void 0) yield entry;
1779
+ }
1780
+ }
1781
+
1782
+ // src/tracked/slotStore.ts
1783
+ var deleteFromStore = (store, addr) => {
1784
+ const slot = store.index[addr];
1785
+ if (slot === void 0) return false;
1786
+ store.slots[slot] = null;
1787
+ Reflect.deleteProperty(store.index, addr);
1788
+ store.count -= 1;
1789
+ return true;
1790
+ };
1791
+ var clearStore = (store) => {
1792
+ store.slots = [];
1793
+ store.index = {};
1794
+ store.count = 0;
1795
+ };
1796
+
1797
+ // src/tracked/trackedMap.ts
1798
+ var TrackedMap = class {
1799
+ constructor(entries) {
1800
+ installBoundary();
1801
+ this.slots = [];
1802
+ this.index = {};
1803
+ this.count = 0;
1804
+ if (entries !== void 0) for (const [key, value] of entries) this.set(key, value);
1805
+ }
1806
+ get size() {
1807
+ return this.count;
1808
+ }
1809
+ has(key) {
1810
+ return this.index[addressOf(key)] !== void 0;
1811
+ }
1812
+ get(key) {
1813
+ const slot = this.index[addressOf(key)];
1814
+ if (slot === void 0) return void 0;
1815
+ const pair = this.slots[slot];
1816
+ return pair === null || pair === void 0 ? void 0 : pair[1];
1817
+ }
1818
+ set(key, value) {
1819
+ assertMutableFacade(this, "count");
1820
+ const addr = addressOf(key);
1821
+ const slot = this.index[addr];
1822
+ if (slot === void 0) {
1823
+ const newSlot = this.slots.length;
1824
+ this.slots.push([key, value]);
1825
+ this.index[addr] = newSlot;
1826
+ this.count += 1;
1827
+ } else {
1828
+ const pair = this.slots[slot];
1829
+ if (pair === null || pair === void 0) throw new Error("opshot: TrackedMap resolved an empty slot");
1830
+ this.slots[slot] = [pair[0], value];
1831
+ }
1832
+ return this;
1833
+ }
1834
+ delete(key) {
1835
+ assertMutableFacade(this, "count");
1836
+ return deleteFromStore(this, addressOf(key));
1837
+ }
1838
+ clear() {
1839
+ assertMutableFacade(this, "count");
1840
+ clearStore(this);
1841
+ }
1842
+ entries() {
1843
+ const pairs = iterateSlots(() => this.slots);
1844
+ return (function* () {
1845
+ for (const pair of pairs) yield [pair[0], pair[1]];
1846
+ })();
1847
+ }
1848
+ keys() {
1849
+ const pairs = iterateSlots(() => this.slots);
1850
+ return (function* () {
1851
+ for (const pair of pairs) yield pair[0];
1852
+ })();
1853
+ }
1854
+ values() {
1855
+ const pairs = iterateSlots(() => this.slots);
1856
+ return (function* () {
1857
+ for (const pair of pairs) yield pair[1];
1858
+ })();
1859
+ }
1860
+ forEach(callback) {
1861
+ for (const pair of iterateSlots(() => this.slots)) callback(pair[1], pair[0], this);
1862
+ }
1863
+ [Symbol.iterator]() {
1864
+ return this.entries();
1865
+ }
1866
+ };
1867
+ Object.defineProperty(TrackedMap.prototype, Symbol.toStringTag, {
1868
+ value: "TrackedMap",
1869
+ enumerable: false,
1870
+ configurable: false,
1871
+ writable: false
1872
+ });
1873
+
1874
+ // src/tracked/trackedSet.ts
1875
+ var TrackedSet = class {
1876
+ constructor(values) {
1877
+ installBoundary();
1878
+ this.slots = [];
1879
+ this.index = {};
1880
+ this.count = 0;
1881
+ if (values !== void 0) for (const value of values) this.add(value);
1882
+ }
1883
+ get size() {
1884
+ return this.count;
1885
+ }
1886
+ has(value) {
1887
+ return this.index[addressOf(value)] !== void 0;
1888
+ }
1889
+ add(value) {
1890
+ assertMutableFacade(this, "count");
1891
+ const addr = addressOf(value);
1892
+ if (this.index[addr] !== void 0) return this;
1893
+ const slot = this.slots.length;
1894
+ this.slots.push([value]);
1895
+ this.index[addr] = slot;
1896
+ this.count += 1;
1897
+ return this;
1898
+ }
1899
+ delete(value) {
1900
+ assertMutableFacade(this, "count");
1901
+ return deleteFromStore(this, addressOf(value));
1902
+ }
1903
+ clear() {
1904
+ assertMutableFacade(this, "count");
1905
+ clearStore(this);
1906
+ }
1907
+ entries() {
1908
+ const members = iterateSlots(() => this.slots);
1909
+ return (function* () {
1910
+ for (const member of members) yield [member[0], member[0]];
1911
+ })();
1912
+ }
1913
+ keys() {
1914
+ return this.values();
1915
+ }
1916
+ values() {
1917
+ const members = iterateSlots(() => this.slots);
1918
+ return (function* () {
1919
+ for (const member of members) yield member[0];
1920
+ })();
1921
+ }
1922
+ forEach(callback) {
1923
+ for (const member of iterateSlots(() => this.slots)) callback(member[0], member[0], this);
1924
+ }
1925
+ [Symbol.iterator]() {
1926
+ return this.values();
1927
+ }
1928
+ };
1929
+ Object.defineProperty(TrackedSet.prototype, Symbol.toStringTag, {
1930
+ value: "TrackedSet",
1931
+ enumerable: false,
1932
+ configurable: false,
1933
+ writable: false
1934
+ });
1935
+
1936
+ // src/react/boundary.ts
1937
+ var { refSet: refSet6, proxyStateMap: proxyStateMap7 } = unstable_getInternalStates();
1938
+ var KEYS_PROPERTY2 = "k";
1939
+ var HAS_KEY_PROPERTY2 = "h";
1940
+ var HAS_OWN_KEY_PROPERTY2 = "o";
1941
+ var ALL_OWN_KEYS_PROPERTY2 = "w";
1942
+ var isObjectLike6 = (value) => value !== null && (typeof value === "object" || typeof value === "function");
1943
+ var isLiveProxy = (value) => proxyStateMap7.has(value);
1944
+ var getProxyTarget = (liveProxy) => proxyStateMap7.get(liveProxy)?.[0] ?? liveProxy;
1945
+ var getUsage = (affected, target) => {
1946
+ let used = affected.get(target);
1947
+ if (used === void 0) {
1948
+ used = {};
1949
+ affected.set(target, used);
1950
+ }
1951
+ return used;
1952
+ };
1953
+ var recordKey = (used, type, key) => {
1954
+ let set = used[type];
1955
+ if (set === void 0) {
1956
+ set = /* @__PURE__ */ new Set();
1957
+ used[type] = set;
1958
+ }
1959
+ set.add(key);
1960
+ };
1961
+ var getPrototypeMethod = (target, prop) => {
1962
+ let prototype = Reflect.getPrototypeOf(target);
1963
+ while (prototype !== null) {
1964
+ const descriptor = Reflect.getOwnPropertyDescriptor(prototype, prop);
1965
+ if (descriptor !== void 0) {
1966
+ const descriptorValue = "value" in descriptor ? descriptor.value : void 0;
1967
+ return typeof descriptorValue === "function" ? descriptorValue : void 0;
1968
+ }
1969
+ prototype = Reflect.getPrototypeOf(prototype);
1970
+ }
1971
+ return void 0;
1972
+ };
1973
+ var wrapperBoundMethods = /* @__PURE__ */ new WeakMap();
1974
+ var bindMethodToWrapper = (wrapper, method) => {
1975
+ let methods = wrapperBoundMethods.get(wrapper);
1976
+ if (methods === void 0) {
1977
+ methods = /* @__PURE__ */ new WeakMap();
1978
+ wrapperBoundMethods.set(wrapper, methods);
1979
+ }
1980
+ const existing = methods.get(method);
1981
+ if (existing !== void 0) return existing;
1982
+ const bound = Function.prototype.bind.call(method, wrapper);
1983
+ methods.set(method, bound);
1984
+ return bound;
1985
+ };
1986
+ function createBoundary() {
1987
+ const partitions = /* @__PURE__ */ new Map();
1988
+ const targets = /* @__PURE__ */ new Map();
1989
+ const getPartition = (sourceProxy) => {
1990
+ let partition = partitions.get(sourceProxy);
1991
+ if (partition === void 0) {
1992
+ partition = {
1993
+ sourceProxy,
1994
+ previousRootSnapshot: void 0,
1995
+ affected: /* @__PURE__ */ new Map(),
1996
+ baselines: /* @__PURE__ */ new Map(),
1997
+ proxyCache: /* @__PURE__ */ new WeakMap()
1998
+ };
1999
+ partitions.set(sourceProxy, partition);
2000
+ }
2001
+ return partition;
2002
+ };
2003
+ const ensureBaseline = (partition, liveProxy) => {
2004
+ const existing = partition.baselines.get(liveProxy);
2005
+ if (existing !== void 0) return existing;
2006
+ const baseline = snapshot(liveProxy);
2007
+ partition.baselines.set(liveProxy, baseline);
2008
+ return baseline;
2009
+ };
2010
+ const ensureRootBaseline = (partition) => {
2011
+ if (partition.previousRootSnapshot === void 0) {
2012
+ partition.previousRootSnapshot = snapshot(partition.sourceProxy);
2013
+ partition.baselines.set(partition.sourceProxy, partition.previousRootSnapshot);
2014
+ }
2015
+ return partition.previousRootSnapshot;
2016
+ };
2017
+ const registerTarget = (liveProxy) => {
2018
+ if (targets.has(liveProxy)) return;
2019
+ targets.set(liveProxy, {
2020
+ lastIdentitySnapshot: snapshot(liveProxy)
2021
+ });
2022
+ };
2023
+ const wrapLive = (liveProxy, partition) => {
2024
+ ensureBaseline(partition, liveProxy);
2025
+ registerTarget(liveProxy);
2026
+ const cached = partition.proxyCache.get(liveProxy);
2027
+ if (cached !== void 0) return cached;
2028
+ const storageTarget = getProxyTarget(liveProxy);
2029
+ const wrapperBox = {};
2030
+ const handler = {
2031
+ get(_target, prop) {
2032
+ ensureRootBaseline(partition);
2033
+ const value = Reflect.get(liveProxy, prop, liveProxy);
2034
+ const wrapper2 = wrapperBox.current;
2035
+ const used = getUsage(partition.affected, liveProxy);
2036
+ recordKey(used, KEYS_PROPERTY2, prop);
2037
+ ensureBaseline(partition, liveProxy);
2038
+ if (typeof value === "function") {
2039
+ const method = getPrototypeMethod(storageTarget, prop);
2040
+ if (method !== void 0 && value === method && wrapper2 !== void 0) {
2041
+ return bindMethodToWrapper(wrapper2, method);
2042
+ }
2043
+ }
2044
+ if (!isObjectLike6(value)) return value;
2045
+ if (typeof value === "function") return value;
2046
+ if (refSet6.has(value)) return value;
2047
+ if (!isLiveProxy(value)) return value;
2048
+ return wrapLive(value, partition);
2049
+ },
2050
+ has(_target, prop) {
2051
+ const used = getUsage(partition.affected, liveProxy);
2052
+ recordKey(used, HAS_KEY_PROPERTY2, prop);
2053
+ ensureBaseline(partition, liveProxy);
2054
+ return Reflect.has(liveProxy, prop);
2055
+ },
2056
+ getOwnPropertyDescriptor(_target, prop) {
2057
+ const used = getUsage(partition.affected, liveProxy);
2058
+ recordKey(used, HAS_OWN_KEY_PROPERTY2, prop);
2059
+ ensureBaseline(partition, liveProxy);
2060
+ return Reflect.getOwnPropertyDescriptor(liveProxy, prop);
2061
+ },
2062
+ ownKeys() {
2063
+ const used = getUsage(partition.affected, liveProxy);
2064
+ used[ALL_OWN_KEYS_PROPERTY2] = true;
2065
+ ensureBaseline(partition, liveProxy);
2066
+ return Reflect.ownKeys(liveProxy);
2067
+ },
2068
+ set(_target, prop, value) {
2069
+ ensureRootBaseline(partition);
2070
+ return Reflect.set(liveProxy, prop, value, liveProxy);
2071
+ },
2072
+ deleteProperty(_target, prop) {
2073
+ ensureRootBaseline(partition);
2074
+ return Reflect.deleteProperty(liveProxy, prop);
2075
+ }
2076
+ };
2077
+ const wrapper = new Proxy(/* @__PURE__ */ Object.create(null), handler);
2078
+ wrapperBox.current = wrapper;
2079
+ registerWrapperTarget(wrapper, liveProxy);
2080
+ partition.proxyCache.set(liveProxy, wrapper);
2081
+ return wrapper;
2082
+ };
142
2083
  return {
143
- createState(define) {
144
- return createGroupState(define, listeners, meta);
2084
+ wrap(sourceProxy) {
2085
+ if (!isLiveProxy(sourceProxy)) {
2086
+ throw new Error("opshot: Boundary.wrap requires a live Valtio proxy");
2087
+ }
2088
+ const partition = getPartition(sourceProxy);
2089
+ ensureRootBaseline(partition);
2090
+ return wrapLive(sourceProxy, partition);
2091
+ },
2092
+ readsChanged(sourceProxy) {
2093
+ const partition = partitions.get(sourceProxy);
2094
+ if (partition?.previousRootSnapshot === void 0) return false;
2095
+ if (partition.affected.size === 0) return false;
2096
+ const translated = /* @__PURE__ */ new WeakMap();
2097
+ for (const [live, usage] of partition.affected) {
2098
+ const baseline = partition.baselines.get(live);
2099
+ if (baseline === void 0) {
2100
+ throw new Error("opshot: missing baseline snapshot for affected live proxy");
2101
+ }
2102
+ translated.set(baseline, usage);
2103
+ }
2104
+ const nextRoot = snapshot(sourceProxy);
2105
+ return isChanged(partition.previousRootSnapshot, nextRoot, translated, /* @__PURE__ */ new WeakMap());
2106
+ },
2107
+ evictChangedTargets() {
2108
+ for (const [liveProxy, entry] of targets) {
2109
+ const current = snapshot(liveProxy);
2110
+ if (current !== entry.lastIdentitySnapshot) {
2111
+ for (const partition of partitions.values()) {
2112
+ partition.proxyCache.delete(liveProxy);
2113
+ }
2114
+ }
2115
+ entry.lastIdentitySnapshot = current;
2116
+ }
145
2117
  },
146
- subscribe(listener) {
147
- listeners.add(listener);
2118
+ resetReads() {
2119
+ for (const partition of partitions.values()) {
2120
+ partition.previousRootSnapshot = void 0;
2121
+ partition.affected.clear();
2122
+ partition.baselines.clear();
2123
+ }
2124
+ }
2125
+ };
2126
+ }
2127
+
2128
+ // src/react/scope.tsx
2129
+ var isPlainPrototype = (value) => {
2130
+ const prototype = Reflect.getPrototypeOf(value);
2131
+ return prototype === Object.prototype || prototype === null;
2132
+ };
2133
+ var assertSubstitutableContainer = (container) => {
2134
+ if (isPlainPrototype(container)) return;
2135
+ const kind = classifyValue(container);
2136
+ if (kind === "plain" || kind === "plainArray" || kind === "cleanClass") return;
2137
+ const className = constructorName(container.constructor);
2138
+ if (kind === "arraySubclass") {
2139
+ throw new Error(
2140
+ `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}.`
2141
+ );
2142
+ }
2143
+ const hidden = kind === "privateClass" ? "private fields" : "internal slots";
2144
+ throw new Error(
2145
+ `opshot: scope found a state inside ${className}, whose ${hidden} can't survive substitution. Move the state to a plain container, or ignore() the ${className}.`
2146
+ );
2147
+ };
2148
+ function findStatePaths(value, maxDepth, path = [], paths = [], ancestors = /* @__PURE__ */ new Set()) {
2149
+ if (isState(value)) {
2150
+ paths.push(path);
2151
+ return paths;
2152
+ }
2153
+ if (value === null || typeof value !== "object") return paths;
2154
+ if ("$$typeof" in value) return paths;
2155
+ if (ancestors.has(value)) return paths;
2156
+ if (path.length >= maxDepth) return paths;
2157
+ ancestors.add(value);
2158
+ if (Array.isArray(value)) {
2159
+ const foundCount = paths.length;
2160
+ value.forEach((item, index) => {
2161
+ findStatePaths(item, maxDepth, [...path, index], paths, ancestors);
2162
+ });
2163
+ if (paths.length > foundCount) assertSubstitutableContainer(value);
2164
+ } else {
2165
+ const foundCount = paths.length;
2166
+ for (const [key, propertyValue] of Object.entries(value)) {
2167
+ if (key.startsWith("__react")) continue;
2168
+ findStatePaths(propertyValue, maxDepth, [...path, key], paths, ancestors);
2169
+ }
2170
+ if (paths.length > foundCount) assertSubstitutableContainer(value);
2171
+ }
2172
+ ancestors.delete(value);
2173
+ return paths;
2174
+ }
2175
+ function getAtPath(object, path) {
2176
+ let current = object;
2177
+ for (const segment of path) {
2178
+ if (current === null || current === void 0) return void 0;
2179
+ current = current[segment];
2180
+ }
2181
+ return current;
2182
+ }
2183
+ function setAtPath(object, path, value) {
2184
+ if (path.length === 0) return value;
2185
+ const head = path[0];
2186
+ if (head === void 0) throw new Error("setAtPath: non-empty path yielded no head segment");
2187
+ const tail = path.slice(1);
2188
+ const current = object[head];
2189
+ const updated = setAtPath(current, tail, value);
2190
+ if (Array.isArray(object)) {
2191
+ const clone2 = [...object];
2192
+ clone2[head] = updated;
2193
+ return clone2;
2194
+ }
2195
+ const prototype = Reflect.getPrototypeOf(object);
2196
+ if (prototype === Object.prototype || prototype === null) return { ...object, [head]: updated };
2197
+ const descriptor = Object.getOwnPropertyDescriptor(object, head);
2198
+ if (descriptor?.get !== void 0 || descriptor?.set !== void 0) {
2199
+ const className = constructorName(object.constructor);
2200
+ throw new Error(
2201
+ `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}.`
2202
+ );
2203
+ }
2204
+ const clone = Object.create(prototype);
2205
+ Object.defineProperties(clone, Object.getOwnPropertyDescriptors(object));
2206
+ clone[head] = updated;
2207
+ return clone;
2208
+ }
2209
+ var sourcesKey = (sources) => `${sources.length}:${sources.map((source) => addressOf(source)).join(",")}`;
2210
+ function scope(Component, options) {
2211
+ const maxDepth = options?.maxDepth ?? 10;
2212
+ const Scoped = (props) => {
2213
+ const boundaryRef = useRef(void 0);
2214
+ boundaryRef.current ?? (boundaryRef.current = createBoundary());
2215
+ const boundary = boundaryRef.current;
2216
+ const [, bump] = useReducer((value) => value + 1, 0);
2217
+ boundary.resetReads();
2218
+ const paths = findStatePaths(props, maxDepth);
2219
+ const sources = [];
2220
+ let nextProps = props;
2221
+ let changed = false;
2222
+ for (const path of paths) {
2223
+ const value = getAtPath(props, path);
2224
+ if (!isState(value)) continue;
2225
+ const source = unwrapWrapper(value);
2226
+ if (typeof source !== "object" || source === null) continue;
2227
+ const wrapped = boundary.wrap(source);
2228
+ if (!sources.includes(source)) sources.push(source);
2229
+ if (wrapped !== value) {
2230
+ nextProps = setAtPath(nextProps, path, wrapped);
2231
+ changed = true;
2232
+ }
2233
+ }
2234
+ const renderedProps = changed ? nextProps : props;
2235
+ const versionsAtRender = sources.map((source) => getVersion(source));
2236
+ useEffect(() => {
2237
+ const unsubscribes = sources.map(
2238
+ (source) => subscribe(
2239
+ source,
2240
+ () => {
2241
+ boundary.evictChangedTargets();
2242
+ if (boundary.readsChanged(source)) bump();
2243
+ },
2244
+ true
2245
+ )
2246
+ );
148
2247
  return () => {
149
- listeners.delete(listener);
2248
+ for (const unsubscribe of unsubscribes) unsubscribe();
150
2249
  };
151
- }
2250
+ }, [sourcesKey(sources), boundary]);
2251
+ useEffect(() => {
2252
+ let shouldBump = false;
2253
+ for (let index = 0; index < sources.length; index += 1) {
2254
+ const source = sources[index];
2255
+ const captured = versionsAtRender[index];
2256
+ if (source === void 0 || captured === void 0) continue;
2257
+ if (getVersion(source) !== captured) {
2258
+ boundary.evictChangedTargets();
2259
+ if (boundary.readsChanged(source)) shouldBump = true;
2260
+ }
2261
+ }
2262
+ if (shouldBump) bump();
2263
+ });
2264
+ return createElement(Component, renderedProps);
152
2265
  };
2266
+ const baseName = Component.displayName ?? Component.name;
2267
+ Scoped.displayName = `scope(${typeof baseName === "string" && baseName !== "" ? baseName : "Component"})`;
2268
+ return memo(Scoped);
2269
+ }
2270
+ function useGroup() {
2271
+ return useState(() => createGroup())[0];
2272
+ }
2273
+ function useMutableState(properties, group) {
2274
+ const [{ proxy: proxy2, boundary }] = useState(() => ({
2275
+ proxy: createMutableState(properties, group),
2276
+ boundary: createBoundary()
2277
+ }));
2278
+ const [, bump] = useReducer((value) => value + 1, 0);
2279
+ const versionAtRender = getVersion(proxy2);
2280
+ boundary.resetReads();
2281
+ const wrapper = boundary.wrap(proxy2);
2282
+ useEffect(() => {
2283
+ const onSignal = () => {
2284
+ boundary.evictChangedTargets();
2285
+ if (boundary.readsChanged(proxy2)) bump();
2286
+ };
2287
+ return subscribe(proxy2, onSignal, true);
2288
+ }, [proxy2, boundary]);
2289
+ useEffect(() => {
2290
+ if (getVersion(proxy2) === versionAtRender) return;
2291
+ boundary.evictChangedTargets();
2292
+ if (boundary.readsChanged(proxy2)) bump();
2293
+ });
2294
+ return wrapper;
153
2295
  }
154
2296
 
155
- export { createGroup, createMeta, createState, diffSnapshots, isState };
2297
+ export { TrackedDate, TrackedMap, TrackedSet, applyOps, createChannel, createGroup, createMutableState, diffSnapshots, identify, ignore, isSameIdentity, isState, scope, subscribe2 as subscribe, transact, unsafeTrack, useGroup, useMutableState };