r-state-tree 0.6.0 → 0.6.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/README.md CHANGED
@@ -355,66 +355,45 @@ class ListStore extends Store {
355
355
  - Models: model fields are shallow-reactive, but values are not auto-wrapped. For raw `@state` arrays/objects, prefer **reassignment** (immutability) so snapshots stay up to date. If you want in-place mutation (`push`, `splice`, `set`, etc.) to trigger updates and snapshot invalidation, store an `observable()` container (or `signal()`) in `@state`.
356
356
  - Stores: store fields are shallow-reactive. Use `observable()` containers (or `signal()`) when you want in-place mutations of nested values/collections to trigger updates.
357
357
 
358
- ## Observable classes
358
+ ### `Observable` base class
359
359
 
360
- For reactive class instances outside the Model/Store system, wrap state with `observable()`:
360
+ For class instances that need to be reactive, extending the `Observable` base class is the supported pattern. This ensures compatibility with ES `#private` fields and built-in brand checks because the observable is created in the base constructor, allowing derived field initializers (including `#private`) to run on the observable.
361
361
 
362
362
  ```ts
363
- import { observable, computed, effect } from "r-state-tree";
363
+ import { Observable, effect } from "r-state-tree";
364
364
 
365
- class Counter {
366
- state = observable({ count: 0, step: 1 });
365
+ class Counter extends Observable {
366
+ count = 0; // Public fields are automatically reactive
367
+ #internal = 0; // Private fields also work perfectly
367
368
 
368
- @computed get doubled() {
369
- return this.state.count * 2;
369
+ get total() {
370
+ return this.count + this.#internal;
370
371
  }
371
372
 
372
373
  increment() {
373
- this.state.count += this.state.step;
374
+ this.count++;
375
+ this.#internal++;
374
376
  }
375
377
  }
376
378
 
377
379
  const counter = new Counter();
378
380
 
381
+ // Use an effect to track and react to property changes
379
382
  effect(() => {
380
- console.log("Count:", counter.state.count, "Doubled:", counter.doubled);
383
+ console.log(`Visible: ${counter.count}, Total: ${counter.total}`);
381
384
  });
382
385
 
383
- counter.increment(); // Triggers the effect
384
- ```
385
-
386
- ### `Observable` base class
387
-
388
- For class instances that need to be reactive, extending the `Observable` base class is the supported pattern. This ensures compatibility with ES `#private` fields and built-in brand checks because the Proxy is created in the base constructor, allowing derived field initializers (including `#private`) to run on the Proxy.
389
-
390
- ```ts
391
- import { Observable, effect } from "r-state-tree";
392
-
393
- class Counter extends Observable {
394
- #count = 0; // Correctly works with #private
395
-
396
- get count() {
397
- return this.#count;
398
- }
399
-
400
- increment() {
401
- this.#count++;
402
- }
403
- }
404
-
405
- const counter = new Counter();
406
- effect(() => console.log(counter.count));
407
386
  counter.increment();
408
387
  ```
409
388
 
410
389
  > [!IMPORTANT] > **Why `extends Observable`?**
411
- > ES `#private` fields are brand-checked. If you proxy a class instance _after_ it has been created (post-hoc proxying), or if you return a proxy from a standard constructor, the private state is installed on the original `this`, but methods run with the Proxy as `this`, causing `TypeError: Cannot read private member`.
390
+ > ES `#private` fields are brand-checked. If you wrap a class instance with `observable()` _after_ it has been created (post-hoc wrapping), or if you return an observable from a standard constructor, the private state is installed on the original `this`, but methods run with the observable as `this`, causing `TypeError: Cannot read private member`.
412
391
  >
413
- > `extends Observable` solves this by returning the Proxy from `super()`, so derived classes initialize their private fields directly on the Proxy receiver.
392
+ > `extends Observable` solves this by returning the observable from `super()`, so derived classes initialize their private fields directly on the observable receiver.
414
393
 
415
394
  ### Limitations of `observable(instance)`
416
395
 
417
- The `observable()` function is selective about what it proxies. It wraps **supported containers** only:
396
+ The `observable()` function is selective about what it makes observable. It wraps **supported containers** only:
418
397
 
419
398
  - Plain objects
420
399
  - Arrays
@@ -425,10 +404,10 @@ The `observable()` function is selective about what it proxies. It wraps **suppo
425
404
 
426
405
  If you pass an arbitrary class instance, built-in (like `URL`, `RegExp`, `Promise`, or DOM objects), or frozen object to `observable()`, it will **return the object unchanged** and emit a warning in development mode.
427
406
 
428
- This design prevents “silent failure” where a proxied object appears to work but throws `TypeError` when accessing private members or internal slots. For your own classes, use `extends Observable`. For third-party or built-in objects, use composition:
407
+ This design prevents “silent failure” where an observable object appears to work but throws `TypeError` when accessing private members or internal slots. For your own classes, use `extends Observable`. For third-party or built-in objects, use composition:
429
408
 
430
409
  ```ts
431
- // ❌ Post-hoc proxying - returns raw URL, not a proxy
410
+ // ❌ Post-hoc wrapping - returns raw URL, not an observable
432
411
  const url = observable(new URL("..."));
433
412
 
434
413
  // ✅ Composition - wrap a container instead
@@ -520,19 +499,19 @@ Create reactive structures outside Stores/Models. Supported: Objects, Arrays, Ma
520
499
 
521
500
  - Track reads with `effect`/`reaction`. Observables are **shallow**: reads are tracked on the observable container, but nested object mutations do **not** trigger unless you explicitly wrap nested values with `observable()` (or use signals).
522
501
  - Access backing values via `source(value)`; check if something is reactive with `isObservable(value)`.
523
- - Rule of thumb: `source(...)` returns the backing data, **not** a sanitizer—it's only proxy-free if you didn't manually seed proxies into the backing source.
502
+ - Rule of thumb: `source(...)` returns the backing data, **not** a sanitizer—it's only observable-free if you didn't manually seed observables into the backing source.
524
503
  - Arrays: reading specific indices (`arr[i]`) or `length` tracks those; common mutators (`push/pop/shift/unshift/splice/reverse/sort/fill`) are reactive; non-index and symbol keys are not reactive.
525
504
 
526
505
  ### `source()` and structuredClone
527
506
 
528
- `source(x)` returns the backing value behind an observable proxy/container. It is **not** a “proxy stripper”.
507
+ `source(x)` returns the backing value behind an observable. It is **not** a “observable stripper”.
529
508
 
530
509
  **One-way rule (important):**
531
510
 
532
511
  - If you mutate through the observable wrapper (e.g. `obj.prop = observable(child)`), r-state-tree stores the **raw backing value** in `source(obj).prop` (unwrap-on-write).
533
- - If you manually mutate backing sources yourself (e.g. `source(obj).prop = observable(child)`), r-state-tree does **not** sanitize or rewrite your data. In that case, `source(...)` may contain proxies.
512
+ - If you manually mutate backing sources yourself (e.g. `source(obj).prop = observable(child)`), r-state-tree does **not** sanitize or rewrite your data. In that case, `source(...)` may contain observables.
534
513
 
535
- If you need to pass values to APIs that require cloneable data (e.g. `structuredClone`, `postMessage`), avoid seeding observable proxies into backing sources. Prefer reading via `source(...)` and keep your stored values plain/cloneable.
514
+ If you need to pass values to APIs that require cloneable data (e.g. `structuredClone`, `postMessage`), avoid seeding observables into backing sources. Prefer reading via `source(...)` and keep your stored values plain/cloneable.
536
515
 
537
516
  ```ts
538
517
  import { observable, effect, computed, reaction } from "r-state-tree";
@@ -586,7 +565,7 @@ state.count++;
586
565
  Native methods that return copies of a collection—such as `Array.prototype.slice`, `filter`, and `concat`, or `Set.prototype.union` and `intersection`—behave according to the **Explicit Architecture**:
587
566
 
588
567
  - **Raw Return**: The returned container is a plain JavaScript object (raw, non-observable).
589
- - **Identity Preservation**: Each element in the returned container maintains the same identity it had in the observable source. If an element was a proxy (because it was explicitly owned), it remains a proxy in the raw result.
568
+ - **Identity Preservation**: Each element in the returned container maintains the same identity it had in the observable source. If an element was an observable (because it was explicitly owned), it remains an observable in the raw result.
590
569
 
591
570
  This ensures that "derived" state is not automatically made reactive, while still allowing observers to maintain reference stability with existing objects in your state tree.
592
571
 
@@ -599,7 +578,7 @@ const sliced = arr.slice();
599
578
  isObservable(sliced); // false
600
579
 
601
580
  // Identity is preserved
602
- sliced[0] === item; // true (same proxy identity)
581
+ sliced[0] === item; // true (same observable identity)
603
582
 
604
583
  // If you want the result to be reactive, wrap it explicitly
605
584
  const reactiveSlice = observable(arr.slice());
@@ -634,8 +613,8 @@ tree.user.tags[0] = "superadmin"; // triggers
634
613
  tree.newProp = { foo: 1 };
635
614
  isObservable(tree.newProp); // false — not wrapped
636
615
 
637
- // Source is proxy-free and clonable *as long as you don't manually seed proxies*
638
- // into backing data structures. r-state-tree unwraps proxies on writes performed
616
+ // Source is observable-free and clonable *as long as you don't manually seed observables*
617
+ // into backing data structures. r-state-tree unwraps observables on writes performed
639
618
  // through observable containers, but it does not sanitize user-mutated backing sources.
640
619
  const snapshot = structuredClone(source(tree));
641
620
  ```
@@ -1127,7 +1106,7 @@ const off = onSnapshot(m, (snap) =>
1127
1106
  - Forgetting stable keys for `@child` arrays causes identity churn.
1128
1107
  - Assuming **deep** reactivity: nested plain objects/arrays are not reactive unless you explicitly wrap them (or use `toObservableTree` for initial hydration).
1129
1108
  - Mutating raw `@state` arrays/objects in place (`push`, `obj.x = 1`) and expecting snapshots to update. Snapshots are memoized; use reassignment or store `observable()` containers / `signal()` values in `@state`.
1130
- - Passing observable proxies to third‑party APIs that expect cloneable/serializable values (e.g. `structuredClone`). Use `source(value)` to get the backing value. It will be proxy-free for values written via r-state-tree’s observable APIs (unwrap-on-write), but `source(...)` is **not** guaranteed proxy-free if you manually seed proxies into backing sources.
1109
+ - Passing observables to third‑party APIs that expect cloneable/serializable values (e.g. `structuredClone`). Use `source(value)` to get the backing value. It will be observable-free for values written via r-state-tree’s observable APIs (unwrap-on-write), but `source(...)` is **not** guaranteed observable-free if you manually seed observables into backing sources.
1131
1110
  - Creating child stores in constructors: `@child` must be on getters so identity and lifecycle can be managed by the framework.
1132
1111
  - Passing `models` into child stores during mount can create a recursive mount loop. If a child needs parent models, create the child store/model inside `storeDidMount` instead of wiring it through `models` during the mount cycle.
1133
1112
 
@@ -16,11 +16,9 @@ export declare class ModelAdministration extends PreactObjectAdministration<any>
16
16
  private modelsTraceUnsub;
17
17
  private writeInProgress;
18
18
  private computedSnapshot;
19
- private snapshotAtom;
20
19
  private snapshotMap;
21
20
  private contextCache;
22
21
  parentName: PropertyKey | null;
23
- private observeSnapshotValue;
24
22
  get parent(): ModelAdministration | null;
25
23
  set parent(value: ModelAdministration | null);
26
24
  setConfiguration(configurationGetter: () => ModelConfiguration<any>): void;
@@ -4,8 +4,9 @@ import { SignalMap } from "./internal/NodeMap";
4
4
  export declare class ArrayAdministration<T> extends Administration<T[]> {
5
5
  valuesMap: SignalMap<number>;
6
6
  keysAtom: AtomNode;
7
- private explicitObservables;
8
- private syncExplicitObservablesFromSource;
7
+ private observableSources;
8
+ private rawSources;
9
+ private trackValue;
9
10
  static proxyTraps: ProxyHandler<Array<unknown>>;
10
11
  static methods: Partial<{
11
12
  [K in keyof typeof Array.prototype as (typeof Array.prototype)[K] extends Function ? K : never]: (typeof Array.prototype)[K];
@@ -315,9 +315,7 @@ class ObjectAdministration extends Administration {
315
315
  return Reflect.get(this.source, key, this.proxy);
316
316
  }
317
317
  set(key, value) {
318
- return signalsCore.batch(() => {
319
- return Reflect.set(this.source, key, value, this.proxy);
320
- });
318
+ return signalsCore.batch(() => Reflect.set(this.source, key, value, this.proxy));
321
319
  }
322
320
  getComputed(key) {
323
321
  if (!this.computedMap) this.computedMap = /* @__PURE__ */ new Map();
@@ -683,17 +681,7 @@ class CollectionAdministration extends Administration {
683
681
  return collectionMethods[name];
684
682
  }
685
683
  if (typeof val === "function") {
686
- return function() {
687
- if (process.env.NODE_ENV !== "production") {
688
- console.warn(
689
- `r-state-tree: Calling uninstrumented collection method "${String(
690
- name
691
- )}". Reactivity is not guaranteed for this call.`
692
- );
693
- }
694
- const result = val.apply(adm.source, arguments);
695
- return result === adm.source ? adm.proxy : result;
696
- };
684
+ return val;
697
685
  }
698
686
  return val;
699
687
  }
@@ -819,9 +807,6 @@ class CollectionAdministration extends Administration {
819
807
  const target = getSource(value);
820
808
  if (isObservable(value)) {
821
809
  this.trackExplicitObservable(target);
822
- } else {
823
- this.untrackExplicitObservable(target);
824
- this.untrackExplicitObservable(value);
825
810
  }
826
811
  if (!this.hasEntry(value)) {
827
812
  this.source.add(target);
@@ -1054,15 +1039,40 @@ function isArrayIndexKey(key) {
1054
1039
  return Number.isInteger(num) && num >= 0 && num < 4294967295 && // 2^32 - 1
1055
1040
  String(num) === keyStr;
1056
1041
  }
1042
+ function reportConflict() {
1043
+ if (process.env.NODE_ENV !== "production") {
1044
+ throw new Error(
1045
+ "r-state-tree: Cannot assign the same object as both observable and raw source in the same array. The value will be treated as observable."
1046
+ );
1047
+ }
1048
+ }
1057
1049
  class ArrayAdministration extends Administration {
1058
1050
  valuesMap;
1059
1051
  keysAtom;
1060
- explicitObservables = /* @__PURE__ */ new Set();
1061
- syncExplicitObservablesFromSource() {
1062
- for (let i = 0; i < this.source.length; i++) {
1063
- const value = this.source[i];
1052
+ /**
1053
+ * Parent-based ownership tracking: sources assigned as observable.
1054
+ * Unlike index-based tracking, this doesn't require updates on reorder ops.
1055
+ */
1056
+ observableSources = /* @__PURE__ */ new WeakSet();
1057
+ rawSources = /* @__PURE__ */ new WeakSet();
1058
+ /**
1059
+ * Track a value being assigned to this array.
1060
+ * Detects conflicts if same source is assigned as both observable and raw.
1061
+ */
1062
+ trackValue(value) {
1063
+ if (value && typeof value === "object") {
1064
+ const source2 = getSource(value);
1064
1065
  if (isObservable(value)) {
1065
- this.explicitObservables.add(i);
1066
+ if (this.rawSources.has(source2)) {
1067
+ reportConflict();
1068
+ }
1069
+ this.observableSources.add(source2);
1070
+ } else {
1071
+ if (this.observableSources.has(source2)) {
1072
+ reportConflict();
1073
+ } else {
1074
+ this.rawSources.add(source2);
1075
+ }
1066
1076
  }
1067
1077
  }
1068
1078
  }
@@ -1119,7 +1129,6 @@ class ArrayAdministration extends Administration {
1119
1129
  if (result && had && isIndex) {
1120
1130
  const index = Number(name);
1121
1131
  adm.onArrayChanged(true, index, 1);
1122
- adm.explicitObservables.delete(index);
1123
1132
  }
1124
1133
  return result;
1125
1134
  },
@@ -1145,16 +1154,12 @@ class ArrayAdministration extends Administration {
1145
1154
  static methods = {
1146
1155
  fill(value, start, end) {
1147
1156
  const adm = getAdministration(this);
1148
- const shouldTrack = isObservable(value);
1157
+ adm.trackValue(value);
1149
1158
  const targetValue = getSource(value);
1150
1159
  adm.source.fill(targetValue, start, end);
1151
1160
  const length = adm.source.length;
1152
1161
  const from = start == null ? 0 : start < 0 ? Math.max(length + start, 0) : start;
1153
1162
  const to = end == null ? length : end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
1154
- for (let i = from; i < to; i++) {
1155
- if (shouldTrack) adm.explicitObservables.add(i);
1156
- else adm.explicitObservables.delete(i);
1157
- }
1158
1163
  if (from < to) {
1159
1164
  adm.onArrayChanged(false, from, to - from);
1160
1165
  }
@@ -1193,41 +1198,24 @@ class ArrayAdministration extends Administration {
1193
1198
  },
1194
1199
  reverse() {
1195
1200
  const adm = getAdministration(this);
1196
- adm.syncExplicitObservablesFromSource();
1197
- const flags = new Array(adm.source.length);
1198
- for (let i = 0; i < flags.length; i++) {
1199
- flags[i] = adm.explicitObservables.has(i);
1200
- }
1201
1201
  adm.source.reverse();
1202
- flags.reverse();
1203
- adm.explicitObservables.clear();
1204
- for (let i = 0; i < flags.length; i++) {
1205
- if (flags[i]) adm.explicitObservables.add(i);
1206
- }
1207
1202
  adm.onArrayChanged(false, 0, adm.source.length);
1208
1203
  return this;
1209
1204
  },
1210
1205
  sort(compareFn) {
1211
1206
  const adm = getAdministration(this);
1212
- adm.syncExplicitObservablesFromSource();
1213
- const pairs = new Array(adm.source.length);
1214
- for (let i = 0; i < adm.source.length; i++) {
1215
- pairs[i] = {
1216
- value: this[i],
1217
- stored: adm.source[i],
1218
- observed: adm.explicitObservables.has(i)
1219
- };
1220
- }
1207
+ const pairs = adm.source.map((stored, i) => ({
1208
+ value: this[i],
1209
+ stored
1210
+ }));
1221
1211
  const comparator = compareFn ?? ((a, b) => {
1222
1212
  const as = String(a);
1223
1213
  const bs = String(b);
1224
1214
  return as < bs ? -1 : as > bs ? 1 : 0;
1225
1215
  });
1226
1216
  pairs.sort((a, b) => comparator(a.value, b.value));
1227
- adm.explicitObservables.clear();
1228
1217
  for (let i = 0; i < pairs.length; i++) {
1229
1218
  adm.source[i] = pairs[i].stored;
1230
- if (pairs[i].observed) adm.explicitObservables.add(i);
1231
1219
  }
1232
1220
  adm.onArrayChanged(false, 0, adm.source.length);
1233
1221
  return this;
@@ -1243,17 +1231,7 @@ class ArrayAdministration extends Administration {
1243
1231
  flat: createCopyMethod("flat"),
1244
1232
  copyWithin(target, start, end) {
1245
1233
  const adm = getAdministration(this);
1246
- adm.syncExplicitObservablesFromSource();
1247
- const flags = new Array(adm.source.length);
1248
- for (let i = 0; i < flags.length; i++) {
1249
- flags[i] = adm.explicitObservables.has(i);
1250
- }
1251
1234
  adm.source.copyWithin(target, start, end);
1252
- flags.copyWithin(target, start, end);
1253
- adm.explicitObservables.clear();
1254
- for (let i = 0; i < flags.length; i++) {
1255
- if (flags[i]) adm.explicitObservables.add(i);
1256
- }
1257
1235
  adm.onArrayChanged(false, 0, adm.source.length);
1258
1236
  return this;
1259
1237
  },
@@ -1287,23 +1265,20 @@ class ArrayAdministration extends Administration {
1287
1265
  _getEffectiveValue(index) {
1288
1266
  const value = this.source[index];
1289
1267
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
1290
- if (this.explicitObservables.has(index)) {
1291
- const existingAdm = getAdministration(value);
1292
- if (existingAdm) {
1293
- if (existingAdm.proxy !== value) {
1294
- const desc = Object.getOwnPropertyDescriptor(this.source, index);
1295
- if (desc && !desc.configurable && !desc.writable) {
1296
- if (process.env.NODE_ENV !== "production") {
1297
- console.warn(
1298
- `r-state-tree: cannot return an observable proxy for arr[${index}] because it is a non-configurable, non-writable data property; returning the raw value to uphold Proxy invariants.`
1299
- );
1300
- }
1301
- this.explicitObservables.delete(index);
1302
- return value;
1268
+ if (this.observableSources.has(value)) {
1269
+ const adm = getAdministration(value);
1270
+ if (adm.proxy !== value) {
1271
+ const desc = Object.getOwnPropertyDescriptor(this.source, index);
1272
+ if (desc && !desc.configurable && !desc.writable) {
1273
+ if (process.env.NODE_ENV !== "production") {
1274
+ console.warn(
1275
+ `r-state-tree: cannot return an observable proxy for arr[${index}] because it is a non-configurable, non-writable data property; returning the raw value to uphold Proxy invariants.`
1276
+ );
1303
1277
  }
1278
+ return value;
1304
1279
  }
1305
- return existingAdm.proxy;
1306
1280
  }
1281
+ return adm.proxy;
1307
1282
  }
1308
1283
  }
1309
1284
  return value;
@@ -1312,23 +1287,17 @@ class ArrayAdministration extends Administration {
1312
1287
  const values = this.source;
1313
1288
  const targetValue = getSource(newValue);
1314
1289
  const oldLength = values.length;
1290
+ this.trackValue(newValue);
1315
1291
  let changed = true;
1316
1292
  if (index < oldLength) {
1317
1293
  const oldValue = values[index];
1318
- const oldExplicit = this.explicitObservables.has(index);
1319
- const newExplicit = isObservable(newValue);
1320
- changed = !isObservable(oldValue) && oldExplicit !== newExplicit || (isObservable(oldValue) ? newValue !== oldValue : targetValue !== oldValue);
1294
+ changed = targetValue !== oldValue;
1321
1295
  }
1322
1296
  if (!changed) return true;
1323
1297
  const result = Reflect.set(values, index, targetValue);
1324
1298
  if (!result) return false;
1325
1299
  const newLength = values.length;
1326
1300
  const lengthChanged = newLength !== oldLength;
1327
- if (isObservable(newValue)) {
1328
- this.explicitObservables.add(index);
1329
- } else {
1330
- this.explicitObservables.delete(index);
1331
- }
1332
1301
  this.onArrayChanged(lengthChanged, index, 1);
1333
1302
  return true;
1334
1303
  }
@@ -1349,15 +1318,6 @@ class ArrayAdministration extends Administration {
1349
1318
  const result = Reflect.set(this.source, "length", newLength);
1350
1319
  if (!result) return false;
1351
1320
  if (newLength < currentLength) {
1352
- const toRemove = [];
1353
- for (const index of this.explicitObservables) {
1354
- if (index >= newLength) {
1355
- toRemove.push(index);
1356
- }
1357
- }
1358
- for (const index of toRemove) {
1359
- this.explicitObservables.delete(index);
1360
- }
1361
1321
  this.onArrayChanged(true, newLength, currentLength - newLength);
1362
1322
  } else {
1363
1323
  this.onArrayChanged(true, currentLength, newLength - currentLength);
@@ -1367,13 +1327,10 @@ class ArrayAdministration extends Administration {
1367
1327
  spliceWithArray(index, deleteCount, newItems) {
1368
1328
  const length = this.source.length;
1369
1329
  const newTargetItems = [];
1370
- const newObservableIndices = [];
1371
1330
  if (newItems) {
1372
1331
  for (let i = 0; i < newItems.length; i++) {
1373
1332
  newTargetItems[i] = getSource(newItems[i]);
1374
- if (isObservable(newItems[i])) {
1375
- newObservableIndices.push(i);
1376
- }
1333
+ this.trackValue(newItems[i]);
1377
1334
  }
1378
1335
  }
1379
1336
  if (index === void 0) index = 0;
@@ -1386,31 +1343,10 @@ class ArrayAdministration extends Administration {
1386
1343
  for (let i = index; i < index + deleteCount; i++) {
1387
1344
  removedItems.push(this._getEffectiveValue(i));
1388
1345
  }
1389
- for (let i = index; i < index + deleteCount; i++) {
1390
- this.explicitObservables.delete(i);
1391
- }
1392
- const shift = (newItems?.length ?? 0) - deleteCount;
1393
- if (shift !== 0) {
1394
- const newExplicitObservables = /* @__PURE__ */ new Set();
1395
- for (const idx of this.explicitObservables) {
1396
- if (idx < index) {
1397
- newExplicitObservables.add(idx);
1398
- } else if (idx >= index + deleteCount) {
1399
- newExplicitObservables.add(idx + shift);
1400
- }
1401
- }
1402
- this.explicitObservables.clear();
1403
- for (const idx of newExplicitObservables) {
1404
- this.explicitObservables.add(idx);
1405
- }
1406
- }
1407
- for (const relativeIdx of newObservableIndices) {
1408
- this.explicitObservables.add(index + relativeIdx);
1409
- }
1410
1346
  this.spliceItemsIntoValues(index, deleteCount, newTargetItems);
1411
1347
  if (deleteCount !== 0 || newTargetItems.length !== 0) {
1412
- const shift2 = (newItems?.length ?? 0) - deleteCount;
1413
- const reindexing = shift2 !== 0 && index + deleteCount < length;
1348
+ const shift = (newItems?.length ?? 0) - deleteCount;
1349
+ const reindexing = shift !== 0 && index + deleteCount < length;
1414
1350
  const count = reindexing ? Number.POSITIVE_INFINITY : Math.max(deleteCount ?? 0, newItems?.length ?? 0);
1415
1351
  this.onArrayChanged(length !== this.source.length, index, count);
1416
1352
  }
@@ -2437,19 +2373,7 @@ function getIdKey(Ctor) {
2437
2373
  function getModelRefSnapshot(modelRef2) {
2438
2374
  const Ctor = Object.getPrototypeOf(modelRef2).constructor;
2439
2375
  const idKey = getIdKey(Ctor);
2440
- if (!idKey) return null;
2441
- let id2 = getIdentifier(modelRef2);
2442
- if (id2 === void 0) {
2443
- const source2 = getSource(modelRef2);
2444
- id2 = getIdentifier(source2);
2445
- if (id2 === void 0) {
2446
- const adm = getAdministration(modelRef2);
2447
- if (adm && adm.proxy !== modelRef2) {
2448
- id2 = getIdentifier(adm.proxy);
2449
- }
2450
- }
2451
- }
2452
- return { [idKey]: id2 };
2376
+ return idKey ? { [idKey]: getIdentifier(modelRef2) } : null;
2453
2377
  }
2454
2378
  function getSnapshotId(snapshot, Ctor) {
2455
2379
  const idKey = getIdKey(Ctor);
@@ -2573,60 +2497,9 @@ class ModelAdministration extends PreactObjectAdministration {
2573
2497
  modelsTraceUnsub = /* @__PURE__ */ new Map();
2574
2498
  writeInProgress = /* @__PURE__ */ new Set();
2575
2499
  computedSnapshot;
2576
- snapshotAtom = createAtom();
2577
2500
  snapshotMap = /* @__PURE__ */ new Map();
2578
2501
  contextCache = /* @__PURE__ */ new Map();
2579
2502
  parentName = null;
2580
- /**
2581
- * `@state` fields are shallow-reactive (property-level assignment triggers reactivity)
2582
- * and participate in snapshots. Values stored in `@state` are not deep-wrapped.
2583
- *
2584
- * This helper walks a value and:
2585
- * - observes any observable containers found (proxy or source) so in-place mutations
2586
- * invalidate `getSnapshot()` / `toSnapshot()`
2587
- * - avoids proxy traversal by preferring `getSource(...)`
2588
- * - guards against cycles via `WeakSet`
2589
- */
2590
- observeSnapshotValue(value, seen) {
2591
- if (value == null) return;
2592
- if (typeof value !== "object") return;
2593
- if (!seen) seen = /* @__PURE__ */ new WeakSet();
2594
- const obj = value;
2595
- if (seen.has(obj)) return;
2596
- seen.add(obj);
2597
- const adm = getAdministration(obj);
2598
- if (adm) {
2599
- adm.reportObserved();
2600
- }
2601
- const src = getSource(value);
2602
- if (src && typeof src === "object" && src !== value) {
2603
- this.observeSnapshotValue(src, seen);
2604
- return;
2605
- }
2606
- if (Array.isArray(value)) {
2607
- for (let i = 0; i < value.length; i++) {
2608
- this.observeSnapshotValue(value[i], seen);
2609
- }
2610
- return;
2611
- }
2612
- if (value instanceof Map) {
2613
- value.forEach((v, k) => {
2614
- this.observeSnapshotValue(k, seen);
2615
- this.observeSnapshotValue(v, seen);
2616
- });
2617
- return;
2618
- }
2619
- if (value instanceof Set) {
2620
- value.forEach((v) => this.observeSnapshotValue(v, seen));
2621
- return;
2622
- }
2623
- if (value instanceof Date) {
2624
- return;
2625
- }
2626
- for (const key of Object.keys(value)) {
2627
- this.observeSnapshotValue(value[key], seen);
2628
- }
2629
- }
2630
2503
  get parent() {
2631
2504
  this.parentAtom.reportObserved();
2632
2505
  return this._parent;
@@ -2662,7 +2535,6 @@ class ModelAdministration extends PreactObjectAdministration {
2662
2535
  value,
2663
2536
  this.proxy
2664
2537
  );
2665
- this.snapshotAtom.reportChanged();
2666
2538
  });
2667
2539
  }
2668
2540
  }
@@ -2858,9 +2730,7 @@ class ModelAdministration extends PreactObjectAdministration {
2858
2730
  return Object.keys(this.configuration).reduce((json, key) => {
2859
2731
  switch (this.configuration[key].type) {
2860
2732
  case ModelCfgTypes.state: {
2861
- const value = this.proxy[key];
2862
- this.observeSnapshotValue(value);
2863
- json[key] = clone(getSource(value), key);
2733
+ json[key] = clone(this.proxy[key], key);
2864
2734
  break;
2865
2735
  }
2866
2736
  case ModelCfgTypes.id:
@@ -3003,7 +2873,6 @@ class ModelAdministration extends PreactObjectAdministration {
3003
2873
  getSnapshot() {
3004
2874
  if (!this.computedSnapshot) {
3005
2875
  this.computedSnapshot = createComputed(() => {
3006
- this.snapshotAtom.reportObserved();
3007
2876
  const json = this.toJSON();
3008
2877
  configMap.set(json, this.configuration);
3009
2878
  return json;
@@ -314,9 +314,7 @@ class ObjectAdministration extends Administration {
314
314
  return Reflect.get(this.source, key, this.proxy);
315
315
  }
316
316
  set(key, value) {
317
- return batch(() => {
318
- return Reflect.set(this.source, key, value, this.proxy);
319
- });
317
+ return batch(() => Reflect.set(this.source, key, value, this.proxy));
320
318
  }
321
319
  getComputed(key) {
322
320
  if (!this.computedMap) this.computedMap = /* @__PURE__ */ new Map();
@@ -682,17 +680,7 @@ class CollectionAdministration extends Administration {
682
680
  return collectionMethods[name];
683
681
  }
684
682
  if (typeof val === "function") {
685
- return function() {
686
- if (process.env.NODE_ENV !== "production") {
687
- console.warn(
688
- `r-state-tree: Calling uninstrumented collection method "${String(
689
- name
690
- )}". Reactivity is not guaranteed for this call.`
691
- );
692
- }
693
- const result = val.apply(adm.source, arguments);
694
- return result === adm.source ? adm.proxy : result;
695
- };
683
+ return val;
696
684
  }
697
685
  return val;
698
686
  }
@@ -818,9 +806,6 @@ class CollectionAdministration extends Administration {
818
806
  const target = getSource(value);
819
807
  if (isObservable(value)) {
820
808
  this.trackExplicitObservable(target);
821
- } else {
822
- this.untrackExplicitObservable(target);
823
- this.untrackExplicitObservable(value);
824
809
  }
825
810
  if (!this.hasEntry(value)) {
826
811
  this.source.add(target);
@@ -1053,15 +1038,40 @@ function isArrayIndexKey(key) {
1053
1038
  return Number.isInteger(num) && num >= 0 && num < 4294967295 && // 2^32 - 1
1054
1039
  String(num) === keyStr;
1055
1040
  }
1041
+ function reportConflict() {
1042
+ if (process.env.NODE_ENV !== "production") {
1043
+ throw new Error(
1044
+ "r-state-tree: Cannot assign the same object as both observable and raw source in the same array. The value will be treated as observable."
1045
+ );
1046
+ }
1047
+ }
1056
1048
  class ArrayAdministration extends Administration {
1057
1049
  valuesMap;
1058
1050
  keysAtom;
1059
- explicitObservables = /* @__PURE__ */ new Set();
1060
- syncExplicitObservablesFromSource() {
1061
- for (let i = 0; i < this.source.length; i++) {
1062
- const value = this.source[i];
1051
+ /**
1052
+ * Parent-based ownership tracking: sources assigned as observable.
1053
+ * Unlike index-based tracking, this doesn't require updates on reorder ops.
1054
+ */
1055
+ observableSources = /* @__PURE__ */ new WeakSet();
1056
+ rawSources = /* @__PURE__ */ new WeakSet();
1057
+ /**
1058
+ * Track a value being assigned to this array.
1059
+ * Detects conflicts if same source is assigned as both observable and raw.
1060
+ */
1061
+ trackValue(value) {
1062
+ if (value && typeof value === "object") {
1063
+ const source2 = getSource(value);
1063
1064
  if (isObservable(value)) {
1064
- this.explicitObservables.add(i);
1065
+ if (this.rawSources.has(source2)) {
1066
+ reportConflict();
1067
+ }
1068
+ this.observableSources.add(source2);
1069
+ } else {
1070
+ if (this.observableSources.has(source2)) {
1071
+ reportConflict();
1072
+ } else {
1073
+ this.rawSources.add(source2);
1074
+ }
1065
1075
  }
1066
1076
  }
1067
1077
  }
@@ -1118,7 +1128,6 @@ class ArrayAdministration extends Administration {
1118
1128
  if (result && had && isIndex) {
1119
1129
  const index = Number(name);
1120
1130
  adm.onArrayChanged(true, index, 1);
1121
- adm.explicitObservables.delete(index);
1122
1131
  }
1123
1132
  return result;
1124
1133
  },
@@ -1144,16 +1153,12 @@ class ArrayAdministration extends Administration {
1144
1153
  static methods = {
1145
1154
  fill(value, start, end) {
1146
1155
  const adm = getAdministration(this);
1147
- const shouldTrack = isObservable(value);
1156
+ adm.trackValue(value);
1148
1157
  const targetValue = getSource(value);
1149
1158
  adm.source.fill(targetValue, start, end);
1150
1159
  const length = adm.source.length;
1151
1160
  const from = start == null ? 0 : start < 0 ? Math.max(length + start, 0) : start;
1152
1161
  const to = end == null ? length : end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
1153
- for (let i = from; i < to; i++) {
1154
- if (shouldTrack) adm.explicitObservables.add(i);
1155
- else adm.explicitObservables.delete(i);
1156
- }
1157
1162
  if (from < to) {
1158
1163
  adm.onArrayChanged(false, from, to - from);
1159
1164
  }
@@ -1192,41 +1197,24 @@ class ArrayAdministration extends Administration {
1192
1197
  },
1193
1198
  reverse() {
1194
1199
  const adm = getAdministration(this);
1195
- adm.syncExplicitObservablesFromSource();
1196
- const flags = new Array(adm.source.length);
1197
- for (let i = 0; i < flags.length; i++) {
1198
- flags[i] = adm.explicitObservables.has(i);
1199
- }
1200
1200
  adm.source.reverse();
1201
- flags.reverse();
1202
- adm.explicitObservables.clear();
1203
- for (let i = 0; i < flags.length; i++) {
1204
- if (flags[i]) adm.explicitObservables.add(i);
1205
- }
1206
1201
  adm.onArrayChanged(false, 0, adm.source.length);
1207
1202
  return this;
1208
1203
  },
1209
1204
  sort(compareFn) {
1210
1205
  const adm = getAdministration(this);
1211
- adm.syncExplicitObservablesFromSource();
1212
- const pairs = new Array(adm.source.length);
1213
- for (let i = 0; i < adm.source.length; i++) {
1214
- pairs[i] = {
1215
- value: this[i],
1216
- stored: adm.source[i],
1217
- observed: adm.explicitObservables.has(i)
1218
- };
1219
- }
1206
+ const pairs = adm.source.map((stored, i) => ({
1207
+ value: this[i],
1208
+ stored
1209
+ }));
1220
1210
  const comparator = compareFn ?? ((a, b) => {
1221
1211
  const as = String(a);
1222
1212
  const bs = String(b);
1223
1213
  return as < bs ? -1 : as > bs ? 1 : 0;
1224
1214
  });
1225
1215
  pairs.sort((a, b) => comparator(a.value, b.value));
1226
- adm.explicitObservables.clear();
1227
1216
  for (let i = 0; i < pairs.length; i++) {
1228
1217
  adm.source[i] = pairs[i].stored;
1229
- if (pairs[i].observed) adm.explicitObservables.add(i);
1230
1218
  }
1231
1219
  adm.onArrayChanged(false, 0, adm.source.length);
1232
1220
  return this;
@@ -1242,17 +1230,7 @@ class ArrayAdministration extends Administration {
1242
1230
  flat: createCopyMethod("flat"),
1243
1231
  copyWithin(target, start, end) {
1244
1232
  const adm = getAdministration(this);
1245
- adm.syncExplicitObservablesFromSource();
1246
- const flags = new Array(adm.source.length);
1247
- for (let i = 0; i < flags.length; i++) {
1248
- flags[i] = adm.explicitObservables.has(i);
1249
- }
1250
1233
  adm.source.copyWithin(target, start, end);
1251
- flags.copyWithin(target, start, end);
1252
- adm.explicitObservables.clear();
1253
- for (let i = 0; i < flags.length; i++) {
1254
- if (flags[i]) adm.explicitObservables.add(i);
1255
- }
1256
1234
  adm.onArrayChanged(false, 0, adm.source.length);
1257
1235
  return this;
1258
1236
  },
@@ -1286,23 +1264,20 @@ class ArrayAdministration extends Administration {
1286
1264
  _getEffectiveValue(index) {
1287
1265
  const value = this.source[index];
1288
1266
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
1289
- if (this.explicitObservables.has(index)) {
1290
- const existingAdm = getAdministration(value);
1291
- if (existingAdm) {
1292
- if (existingAdm.proxy !== value) {
1293
- const desc = Object.getOwnPropertyDescriptor(this.source, index);
1294
- if (desc && !desc.configurable && !desc.writable) {
1295
- if (process.env.NODE_ENV !== "production") {
1296
- console.warn(
1297
- `r-state-tree: cannot return an observable proxy for arr[${index}] because it is a non-configurable, non-writable data property; returning the raw value to uphold Proxy invariants.`
1298
- );
1299
- }
1300
- this.explicitObservables.delete(index);
1301
- return value;
1267
+ if (this.observableSources.has(value)) {
1268
+ const adm = getAdministration(value);
1269
+ if (adm.proxy !== value) {
1270
+ const desc = Object.getOwnPropertyDescriptor(this.source, index);
1271
+ if (desc && !desc.configurable && !desc.writable) {
1272
+ if (process.env.NODE_ENV !== "production") {
1273
+ console.warn(
1274
+ `r-state-tree: cannot return an observable proxy for arr[${index}] because it is a non-configurable, non-writable data property; returning the raw value to uphold Proxy invariants.`
1275
+ );
1302
1276
  }
1277
+ return value;
1303
1278
  }
1304
- return existingAdm.proxy;
1305
1279
  }
1280
+ return adm.proxy;
1306
1281
  }
1307
1282
  }
1308
1283
  return value;
@@ -1311,23 +1286,17 @@ class ArrayAdministration extends Administration {
1311
1286
  const values = this.source;
1312
1287
  const targetValue = getSource(newValue);
1313
1288
  const oldLength = values.length;
1289
+ this.trackValue(newValue);
1314
1290
  let changed = true;
1315
1291
  if (index < oldLength) {
1316
1292
  const oldValue = values[index];
1317
- const oldExplicit = this.explicitObservables.has(index);
1318
- const newExplicit = isObservable(newValue);
1319
- changed = !isObservable(oldValue) && oldExplicit !== newExplicit || (isObservable(oldValue) ? newValue !== oldValue : targetValue !== oldValue);
1293
+ changed = targetValue !== oldValue;
1320
1294
  }
1321
1295
  if (!changed) return true;
1322
1296
  const result = Reflect.set(values, index, targetValue);
1323
1297
  if (!result) return false;
1324
1298
  const newLength = values.length;
1325
1299
  const lengthChanged = newLength !== oldLength;
1326
- if (isObservable(newValue)) {
1327
- this.explicitObservables.add(index);
1328
- } else {
1329
- this.explicitObservables.delete(index);
1330
- }
1331
1300
  this.onArrayChanged(lengthChanged, index, 1);
1332
1301
  return true;
1333
1302
  }
@@ -1348,15 +1317,6 @@ class ArrayAdministration extends Administration {
1348
1317
  const result = Reflect.set(this.source, "length", newLength);
1349
1318
  if (!result) return false;
1350
1319
  if (newLength < currentLength) {
1351
- const toRemove = [];
1352
- for (const index of this.explicitObservables) {
1353
- if (index >= newLength) {
1354
- toRemove.push(index);
1355
- }
1356
- }
1357
- for (const index of toRemove) {
1358
- this.explicitObservables.delete(index);
1359
- }
1360
1320
  this.onArrayChanged(true, newLength, currentLength - newLength);
1361
1321
  } else {
1362
1322
  this.onArrayChanged(true, currentLength, newLength - currentLength);
@@ -1366,13 +1326,10 @@ class ArrayAdministration extends Administration {
1366
1326
  spliceWithArray(index, deleteCount, newItems) {
1367
1327
  const length = this.source.length;
1368
1328
  const newTargetItems = [];
1369
- const newObservableIndices = [];
1370
1329
  if (newItems) {
1371
1330
  for (let i = 0; i < newItems.length; i++) {
1372
1331
  newTargetItems[i] = getSource(newItems[i]);
1373
- if (isObservable(newItems[i])) {
1374
- newObservableIndices.push(i);
1375
- }
1332
+ this.trackValue(newItems[i]);
1376
1333
  }
1377
1334
  }
1378
1335
  if (index === void 0) index = 0;
@@ -1385,31 +1342,10 @@ class ArrayAdministration extends Administration {
1385
1342
  for (let i = index; i < index + deleteCount; i++) {
1386
1343
  removedItems.push(this._getEffectiveValue(i));
1387
1344
  }
1388
- for (let i = index; i < index + deleteCount; i++) {
1389
- this.explicitObservables.delete(i);
1390
- }
1391
- const shift = (newItems?.length ?? 0) - deleteCount;
1392
- if (shift !== 0) {
1393
- const newExplicitObservables = /* @__PURE__ */ new Set();
1394
- for (const idx of this.explicitObservables) {
1395
- if (idx < index) {
1396
- newExplicitObservables.add(idx);
1397
- } else if (idx >= index + deleteCount) {
1398
- newExplicitObservables.add(idx + shift);
1399
- }
1400
- }
1401
- this.explicitObservables.clear();
1402
- for (const idx of newExplicitObservables) {
1403
- this.explicitObservables.add(idx);
1404
- }
1405
- }
1406
- for (const relativeIdx of newObservableIndices) {
1407
- this.explicitObservables.add(index + relativeIdx);
1408
- }
1409
1345
  this.spliceItemsIntoValues(index, deleteCount, newTargetItems);
1410
1346
  if (deleteCount !== 0 || newTargetItems.length !== 0) {
1411
- const shift2 = (newItems?.length ?? 0) - deleteCount;
1412
- const reindexing = shift2 !== 0 && index + deleteCount < length;
1347
+ const shift = (newItems?.length ?? 0) - deleteCount;
1348
+ const reindexing = shift !== 0 && index + deleteCount < length;
1413
1349
  const count = reindexing ? Number.POSITIVE_INFINITY : Math.max(deleteCount ?? 0, newItems?.length ?? 0);
1414
1350
  this.onArrayChanged(length !== this.source.length, index, count);
1415
1351
  }
@@ -2436,19 +2372,7 @@ function getIdKey(Ctor) {
2436
2372
  function getModelRefSnapshot(modelRef2) {
2437
2373
  const Ctor = Object.getPrototypeOf(modelRef2).constructor;
2438
2374
  const idKey = getIdKey(Ctor);
2439
- if (!idKey) return null;
2440
- let id2 = getIdentifier(modelRef2);
2441
- if (id2 === void 0) {
2442
- const source2 = getSource(modelRef2);
2443
- id2 = getIdentifier(source2);
2444
- if (id2 === void 0) {
2445
- const adm = getAdministration(modelRef2);
2446
- if (adm && adm.proxy !== modelRef2) {
2447
- id2 = getIdentifier(adm.proxy);
2448
- }
2449
- }
2450
- }
2451
- return { [idKey]: id2 };
2375
+ return idKey ? { [idKey]: getIdentifier(modelRef2) } : null;
2452
2376
  }
2453
2377
  function getSnapshotId(snapshot, Ctor) {
2454
2378
  const idKey = getIdKey(Ctor);
@@ -2572,60 +2496,9 @@ class ModelAdministration extends PreactObjectAdministration {
2572
2496
  modelsTraceUnsub = /* @__PURE__ */ new Map();
2573
2497
  writeInProgress = /* @__PURE__ */ new Set();
2574
2498
  computedSnapshot;
2575
- snapshotAtom = createAtom();
2576
2499
  snapshotMap = /* @__PURE__ */ new Map();
2577
2500
  contextCache = /* @__PURE__ */ new Map();
2578
2501
  parentName = null;
2579
- /**
2580
- * `@state` fields are shallow-reactive (property-level assignment triggers reactivity)
2581
- * and participate in snapshots. Values stored in `@state` are not deep-wrapped.
2582
- *
2583
- * This helper walks a value and:
2584
- * - observes any observable containers found (proxy or source) so in-place mutations
2585
- * invalidate `getSnapshot()` / `toSnapshot()`
2586
- * - avoids proxy traversal by preferring `getSource(...)`
2587
- * - guards against cycles via `WeakSet`
2588
- */
2589
- observeSnapshotValue(value, seen) {
2590
- if (value == null) return;
2591
- if (typeof value !== "object") return;
2592
- if (!seen) seen = /* @__PURE__ */ new WeakSet();
2593
- const obj = value;
2594
- if (seen.has(obj)) return;
2595
- seen.add(obj);
2596
- const adm = getAdministration(obj);
2597
- if (adm) {
2598
- adm.reportObserved();
2599
- }
2600
- const src = getSource(value);
2601
- if (src && typeof src === "object" && src !== value) {
2602
- this.observeSnapshotValue(src, seen);
2603
- return;
2604
- }
2605
- if (Array.isArray(value)) {
2606
- for (let i = 0; i < value.length; i++) {
2607
- this.observeSnapshotValue(value[i], seen);
2608
- }
2609
- return;
2610
- }
2611
- if (value instanceof Map) {
2612
- value.forEach((v, k) => {
2613
- this.observeSnapshotValue(k, seen);
2614
- this.observeSnapshotValue(v, seen);
2615
- });
2616
- return;
2617
- }
2618
- if (value instanceof Set) {
2619
- value.forEach((v) => this.observeSnapshotValue(v, seen));
2620
- return;
2621
- }
2622
- if (value instanceof Date) {
2623
- return;
2624
- }
2625
- for (const key of Object.keys(value)) {
2626
- this.observeSnapshotValue(value[key], seen);
2627
- }
2628
- }
2629
2502
  get parent() {
2630
2503
  this.parentAtom.reportObserved();
2631
2504
  return this._parent;
@@ -2661,7 +2534,6 @@ class ModelAdministration extends PreactObjectAdministration {
2661
2534
  value,
2662
2535
  this.proxy
2663
2536
  );
2664
- this.snapshotAtom.reportChanged();
2665
2537
  });
2666
2538
  }
2667
2539
  }
@@ -2857,9 +2729,7 @@ class ModelAdministration extends PreactObjectAdministration {
2857
2729
  return Object.keys(this.configuration).reduce((json, key) => {
2858
2730
  switch (this.configuration[key].type) {
2859
2731
  case ModelCfgTypes.state: {
2860
- const value = this.proxy[key];
2861
- this.observeSnapshotValue(value);
2862
- json[key] = clone(getSource(value), key);
2732
+ json[key] = clone(this.proxy[key], key);
2863
2733
  break;
2864
2734
  }
2865
2735
  case ModelCfgTypes.id:
@@ -3002,7 +2872,6 @@ class ModelAdministration extends PreactObjectAdministration {
3002
2872
  getSnapshot() {
3003
2873
  if (!this.computedSnapshot) {
3004
2874
  this.computedSnapshot = createComputed(() => {
3005
- this.snapshotAtom.reportObserved();
3006
2875
  const json = this.toJSON();
3007
2876
  configMap.set(json, this.configuration);
3008
2877
  return json;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "r-state-tree",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "reactive state management library",
5
5
  "main": "dist/r-state-tree.cjs",
6
6
  "module": "dist/r-state-tree.js",
@@ -1,2 +0,0 @@
1
- import type { ComputedNode } from "./observables";
2
- export default function <T extends Record<PropertyKey, any>>(computed: ComputedNode<T>): T;