r-state-tree 0.7.0 → 0.8.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 +97 -51
- package/dist/api.d.ts +2 -2
- package/dist/decorators.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/model/Model.d.ts +5 -9
- package/dist/model/ModelAdministration.d.ts +11 -0
- package/dist/model/idMap.d.ts +4 -4
- package/dist/observables/preact.d.ts +1 -1
- package/dist/r-state-tree.cjs +460 -267
- package/dist/r-state-tree.js +460 -267
- package/dist/store/Store.d.ts +5 -4
- package/dist/store/StoreAdministration.d.ts +10 -5
- package/package.json +1 -1
package/dist/r-state-tree.cjs
CHANGED
|
@@ -85,7 +85,15 @@ function makeChildDecorator(typeObj) {
|
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
87
|
const child = makeChildDecorator(childType);
|
|
88
|
-
const
|
|
88
|
+
const modelRefDecorator = makeChildDecorator(modelRefType);
|
|
89
|
+
function modelRef(childCtor, context) {
|
|
90
|
+
if (context !== void 0) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"r-state-tree: @modelRef requires a model constructor, for example `@modelRef(User)`"
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return modelRefDecorator(childCtor);
|
|
96
|
+
}
|
|
89
97
|
const model = makeDecorator(modelType);
|
|
90
98
|
const id = makeDecorator(idType);
|
|
91
99
|
const state = makeDecorator(stateType);
|
|
@@ -103,7 +111,11 @@ function normalizeEntry(entry) {
|
|
|
103
111
|
if (entry === state) return stateType;
|
|
104
112
|
if (entry === model) return modelType;
|
|
105
113
|
if (entry === child) return childType;
|
|
106
|
-
if (entry === modelRef)
|
|
114
|
+
if (entry === modelRef) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
"r-state-tree: modelRef requires a model constructor, for example `modelRef(User)`"
|
|
117
|
+
);
|
|
118
|
+
}
|
|
107
119
|
return void 0;
|
|
108
120
|
}
|
|
109
121
|
return void 0;
|
|
@@ -669,9 +681,10 @@ function reaction(fn, callback) {
|
|
|
669
681
|
if (Object.is(currentValue, nextValue)) {
|
|
670
682
|
return;
|
|
671
683
|
}
|
|
684
|
+
const previousValue = currentValue;
|
|
672
685
|
currentValue = nextValue;
|
|
673
686
|
signalsCore.untracked(() => {
|
|
674
|
-
callback(nextValue);
|
|
687
|
+
callback(nextValue, previousValue);
|
|
675
688
|
});
|
|
676
689
|
});
|
|
677
690
|
}
|
|
@@ -1926,7 +1939,7 @@ function createCircularMountError(frame) {
|
|
|
1926
1939
|
const chain = formatMountChain(frame);
|
|
1927
1940
|
const models = frame.modelsKeys.length === 0 ? "no models provided" : `models: ${frame.modelsKeys.join(", ")}`;
|
|
1928
1941
|
return new Error(
|
|
1929
|
-
`r-state-tree: detected circular store/model creation while mounting ${chain} (using ${models}). Passing models into child stores during mount can create recursive wiring.
|
|
1942
|
+
`r-state-tree: detected circular store/model creation while mounting ${chain} (using ${models}). Passing models into child stores during mount can create recursive wiring. Break the ownership cycle.`
|
|
1930
1943
|
);
|
|
1931
1944
|
}
|
|
1932
1945
|
function updateProps(props, newProps) {
|
|
@@ -1985,8 +1998,8 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
1985
1998
|
PreactObjectAdministration.proxyTraps,
|
|
1986
1999
|
{
|
|
1987
2000
|
get(target, name) {
|
|
1988
|
-
if (name === "key") {
|
|
1989
|
-
return target
|
|
2001
|
+
if (name === "key" || name === Symbol.dispose) {
|
|
2002
|
+
return Reflect.get(target, name);
|
|
1990
2003
|
}
|
|
1991
2004
|
const adm = getAdministration(target);
|
|
1992
2005
|
switch (getConfigType(adm.configuration[name])) {
|
|
@@ -2019,10 +2032,11 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2019
2032
|
}
|
|
2020
2033
|
);
|
|
2021
2034
|
parent = null;
|
|
2022
|
-
|
|
2035
|
+
mountedSignal = createSignal(false);
|
|
2036
|
+
disposed = false;
|
|
2023
2037
|
contextCache = /* @__PURE__ */ new Map();
|
|
2024
2038
|
childStoreDataMap = /* @__PURE__ */ new Map();
|
|
2025
|
-
|
|
2039
|
+
reactiveRegistrations = /* @__PURE__ */ new Set();
|
|
2026
2040
|
configurationGetter;
|
|
2027
2041
|
setConfiguration(configurationGetter) {
|
|
2028
2042
|
this.configurationGetter = configurationGetter;
|
|
@@ -2046,7 +2060,9 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2046
2060
|
}
|
|
2047
2061
|
});
|
|
2048
2062
|
childStoreData.value.set(stores);
|
|
2049
|
-
|
|
2063
|
+
if (this.isMounted) {
|
|
2064
|
+
stores.forEach((s) => getStoreAdm(s).mount(this, name));
|
|
2065
|
+
}
|
|
2050
2066
|
return stores;
|
|
2051
2067
|
}
|
|
2052
2068
|
const newStores = /* @__PURE__ */ new Set();
|
|
@@ -2096,8 +2112,10 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2096
2112
|
if (newStores.size || removedStores.size || keyedIndexChanged) {
|
|
2097
2113
|
signalsCore.batch(() => childStoreData.value.set(stores));
|
|
2098
2114
|
}
|
|
2099
|
-
removedStores.forEach((s) => getStoreAdm(s).
|
|
2100
|
-
|
|
2115
|
+
removedStores.forEach((s) => getStoreAdm(s).dispose(true));
|
|
2116
|
+
if (this.isMounted) {
|
|
2117
|
+
newStores.forEach((s) => getStoreAdm(s).mount(this, name));
|
|
2118
|
+
}
|
|
2101
2119
|
return stores;
|
|
2102
2120
|
}
|
|
2103
2121
|
setSingleStore(name, element) {
|
|
@@ -2107,16 +2125,18 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2107
2125
|
);
|
|
2108
2126
|
const { key, Type, props } = element || {};
|
|
2109
2127
|
if (!element) {
|
|
2110
|
-
oldStore && getStoreAdm(oldStore).
|
|
2128
|
+
oldStore && getStoreAdm(oldStore).dispose(true);
|
|
2111
2129
|
signalsCore.batch(() => childStoreData.value.set(null));
|
|
2112
2130
|
return null;
|
|
2113
2131
|
} else if (!oldStore || oldStore.props.key !== key || !(oldStore instanceof Type)) {
|
|
2114
2132
|
if (oldStore) {
|
|
2115
|
-
getStoreAdm(oldStore).
|
|
2133
|
+
getStoreAdm(oldStore).dispose(true);
|
|
2116
2134
|
}
|
|
2117
2135
|
const childStore = this.createChildStore(element);
|
|
2118
2136
|
signalsCore.batch(() => childStoreData.value.set(childStore));
|
|
2119
|
-
|
|
2137
|
+
if (this.isMounted) {
|
|
2138
|
+
getStoreAdm(childStore).mount(this, name);
|
|
2139
|
+
}
|
|
2120
2140
|
return childStore;
|
|
2121
2141
|
} else {
|
|
2122
2142
|
signalsCore.batch(() => updateProps(oldStore.props, props));
|
|
@@ -2156,7 +2176,8 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2156
2176
|
getStore(name) {
|
|
2157
2177
|
const childStoreData = this.childStoreDataMap.get(name);
|
|
2158
2178
|
if (!childStoreData) {
|
|
2159
|
-
|
|
2179
|
+
signalsCore.untracked(() => this.initializeStore(name));
|
|
2180
|
+
return this.childStoreDataMap.get(name).value.get();
|
|
2160
2181
|
} else {
|
|
2161
2182
|
const storeElement = signalsCore.untracked(() => childStoreData.computed.get());
|
|
2162
2183
|
validateStoreChildValue(storeElement, name);
|
|
@@ -2172,6 +2193,9 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2172
2193
|
isRoot() {
|
|
2173
2194
|
return !this.parent;
|
|
2174
2195
|
}
|
|
2196
|
+
get isMounted() {
|
|
2197
|
+
return this.mountedSignal.get();
|
|
2198
|
+
}
|
|
2175
2199
|
getContextValue(contextId, provideSymbol, defaultValue, hasDefault) {
|
|
2176
2200
|
let computed2 = this.contextCache.get(contextId);
|
|
2177
2201
|
if (!computed2) {
|
|
@@ -2205,12 +2229,43 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2205
2229
|
}
|
|
2206
2230
|
return void 0;
|
|
2207
2231
|
}
|
|
2232
|
+
register(start) {
|
|
2233
|
+
if (this.disposed) {
|
|
2234
|
+
throw new Error(
|
|
2235
|
+
"r-state-tree: cannot register reactive resources on a disposed store"
|
|
2236
|
+
);
|
|
2237
|
+
}
|
|
2238
|
+
const registration = { start, disposed: false };
|
|
2239
|
+
this.reactiveRegistrations.add(registration);
|
|
2240
|
+
if (this.isMounted) registration.stop = registration.start();
|
|
2241
|
+
return () => {
|
|
2242
|
+
if (registration.disposed) return;
|
|
2243
|
+
registration.disposed = true;
|
|
2244
|
+
this.reactiveRegistrations.delete(registration);
|
|
2245
|
+
registration.stop?.();
|
|
2246
|
+
registration.stop = void 0;
|
|
2247
|
+
};
|
|
2248
|
+
}
|
|
2249
|
+
startReactiveRegistrations() {
|
|
2250
|
+
this.reactiveRegistrations.forEach((registration) => {
|
|
2251
|
+
if (!registration.disposed && !registration.stop) {
|
|
2252
|
+
registration.stop = registration.start();
|
|
2253
|
+
}
|
|
2254
|
+
});
|
|
2255
|
+
}
|
|
2208
2256
|
reaction(track, callback) {
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2257
|
+
return this.register(() => reaction(track, callback));
|
|
2258
|
+
}
|
|
2259
|
+
effect(callback) {
|
|
2260
|
+
return this.register(() => signalsCore.effect(callback));
|
|
2212
2261
|
}
|
|
2213
|
-
mount(parent = null, childName) {
|
|
2262
|
+
mount(parent = null, childName, activationQueue) {
|
|
2263
|
+
if (this.disposed) {
|
|
2264
|
+
throw new Error("r-state-tree: cannot mount a disposed store");
|
|
2265
|
+
}
|
|
2266
|
+
if (this.isMounted) {
|
|
2267
|
+
throw new Error("r-state-tree: store is already mounted");
|
|
2268
|
+
}
|
|
2214
2269
|
const frame = {
|
|
2215
2270
|
storeName: this.proxy.constructor.name || "Store",
|
|
2216
2271
|
childName,
|
|
@@ -2220,20 +2275,31 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2220
2275
|
throw createCircularMountError(frame);
|
|
2221
2276
|
}
|
|
2222
2277
|
mountingStack.push(frame);
|
|
2278
|
+
const isOutermostMount = activationQueue === void 0;
|
|
2279
|
+
const registrationsToStart = activationQueue ?? [];
|
|
2223
2280
|
try {
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2281
|
+
signalsCore.batch(() => {
|
|
2282
|
+
this.parent = parent || null;
|
|
2283
|
+
this.childStoreDataMap.forEach(({ value }, name) => {
|
|
2284
|
+
const stores = value.get();
|
|
2285
|
+
if (Array.isArray(stores)) {
|
|
2286
|
+
stores?.forEach(
|
|
2287
|
+
(s) => getStoreAdm(s)?.mount(this, name, registrationsToStart)
|
|
2288
|
+
);
|
|
2289
|
+
} else if (stores) {
|
|
2290
|
+
getStoreAdm(stores)?.mount(this, name, registrationsToStart);
|
|
2291
|
+
}
|
|
2292
|
+
});
|
|
2293
|
+
this.mountedSignal.set(true);
|
|
2294
|
+
registrationsToStart.push(this);
|
|
2232
2295
|
});
|
|
2233
|
-
|
|
2234
|
-
|
|
2296
|
+
if (isOutermostMount) {
|
|
2297
|
+
registrationsToStart.forEach(
|
|
2298
|
+
(store) => store.startReactiveRegistrations()
|
|
2299
|
+
);
|
|
2300
|
+
}
|
|
2235
2301
|
} catch (error) {
|
|
2236
|
-
if (error instanceof RangeError && /call stack/i.test(error.message)) {
|
|
2302
|
+
if (error instanceof Error && (error instanceof RangeError && /call stack/i.test(error.message) || /cycle detected/i.test(error.message))) {
|
|
2237
2303
|
throw createCircularMountError(frame);
|
|
2238
2304
|
}
|
|
2239
2305
|
throw error;
|
|
@@ -2241,25 +2307,36 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2241
2307
|
mountingStack.pop();
|
|
2242
2308
|
}
|
|
2243
2309
|
}
|
|
2244
|
-
|
|
2245
|
-
this.
|
|
2246
|
-
this.
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2310
|
+
dispose(internal = false) {
|
|
2311
|
+
if (this.disposed) return;
|
|
2312
|
+
if (!internal && !this.isRoot()) {
|
|
2313
|
+
throw new Error("r-state-tree: can only dispose root stores");
|
|
2314
|
+
}
|
|
2315
|
+
signalsCore.batch(() => {
|
|
2316
|
+
this.childStoreDataMap.forEach((data) => {
|
|
2317
|
+
const { value, computed: computed2, listener } = data;
|
|
2318
|
+
const stores = value.get();
|
|
2319
|
+
if (Array.isArray(stores)) {
|
|
2320
|
+
stores?.forEach((s) => getStoreAdm(s)?.dispose(true));
|
|
2321
|
+
} else if (stores) {
|
|
2322
|
+
getStoreAdm(stores)?.dispose(true);
|
|
2323
|
+
}
|
|
2324
|
+
computed2.clear();
|
|
2325
|
+
listener.dispose();
|
|
2326
|
+
});
|
|
2327
|
+
this.childStoreDataMap.clear();
|
|
2328
|
+
this.contextCache.forEach((computed2) => computed2.clear());
|
|
2329
|
+
this.contextCache.clear();
|
|
2330
|
+
this.parent = null;
|
|
2257
2331
|
});
|
|
2258
|
-
this.
|
|
2259
|
-
this.
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2332
|
+
this.disposed = true;
|
|
2333
|
+
this.reactiveRegistrations.forEach((registration) => {
|
|
2334
|
+
registration.disposed = true;
|
|
2335
|
+
registration.stop?.();
|
|
2336
|
+
registration.stop = void 0;
|
|
2337
|
+
});
|
|
2338
|
+
this.reactiveRegistrations.clear();
|
|
2339
|
+
this.mountedSignal.set(false);
|
|
2263
2340
|
}
|
|
2264
2341
|
}
|
|
2265
2342
|
let initEnabled$1 = false;
|
|
@@ -2305,141 +2382,109 @@ class Store {
|
|
|
2305
2382
|
get key() {
|
|
2306
2383
|
return this.props.key;
|
|
2307
2384
|
}
|
|
2385
|
+
get isMounted() {
|
|
2386
|
+
return getStoreAdm(this).isMounted;
|
|
2387
|
+
}
|
|
2308
2388
|
reaction(track, callback) {
|
|
2309
2389
|
return getStoreAdm(this).reaction(track, callback);
|
|
2310
2390
|
}
|
|
2311
|
-
|
|
2312
|
-
|
|
2391
|
+
effect(callback) {
|
|
2392
|
+
return getStoreAdm(this).effect(callback);
|
|
2313
2393
|
}
|
|
2314
|
-
|
|
2315
|
-
|
|
2394
|
+
[Symbol.dispose]() {
|
|
2395
|
+
getStoreAdm(this).dispose();
|
|
2316
2396
|
}
|
|
2317
2397
|
}
|
|
2318
2398
|
const attachedIdMap = /* @__PURE__ */ new WeakMap();
|
|
2319
2399
|
const idMap = /* @__PURE__ */ new WeakMap();
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
throw new Error(
|
|
2343
|
-
"r-state-tree duplicate ids detected after snapshot was loaded"
|
|
2344
|
-
);
|
|
2345
|
-
}
|
|
2346
|
-
set.add(id2);
|
|
2347
|
-
}
|
|
2348
|
-
});
|
|
2349
|
-
} finally {
|
|
2350
|
-
potentialDups.clear();
|
|
2351
|
-
}
|
|
2400
|
+
function getModelType(model2) {
|
|
2401
|
+
return Object.getPrototypeOf(model2).constructor;
|
|
2402
|
+
}
|
|
2403
|
+
function entriesFor(model2) {
|
|
2404
|
+
const entries = [];
|
|
2405
|
+
attachedIdMap.get(model2)?.forEach((ids, Type) => {
|
|
2406
|
+
ids.forEach((value, id22) => {
|
|
2407
|
+
if (value) entries.push([Type, id22, value]);
|
|
2408
|
+
});
|
|
2409
|
+
});
|
|
2410
|
+
const id2 = idMap.get(model2);
|
|
2411
|
+
if (id2 != null) entries.push([getModelType(model2), id2, model2]);
|
|
2412
|
+
return entries;
|
|
2413
|
+
}
|
|
2414
|
+
function assertAvailable(node, entries) {
|
|
2415
|
+
const map = attachedIdMap.get(node);
|
|
2416
|
+
for (const [Type, id2, model2] of entries) {
|
|
2417
|
+
const existing = map?.get(Type)?.get(id2);
|
|
2418
|
+
if (existing && existing !== model2) {
|
|
2419
|
+
throw new Error(
|
|
2420
|
+
`r-state-tree: id: ${id2} is already assigned to another model`
|
|
2421
|
+
);
|
|
2352
2422
|
}
|
|
2353
2423
|
}
|
|
2354
2424
|
}
|
|
2425
|
+
function bucket(node, Type) {
|
|
2426
|
+
let map = attachedIdMap.get(node);
|
|
2427
|
+
if (!map) {
|
|
2428
|
+
map = observable(/* @__PURE__ */ new Map());
|
|
2429
|
+
attachedIdMap.set(node, map);
|
|
2430
|
+
}
|
|
2431
|
+
let ids = map.get(Type);
|
|
2432
|
+
if (!ids) {
|
|
2433
|
+
ids = observable(/* @__PURE__ */ new Map());
|
|
2434
|
+
map.set(Type, ids);
|
|
2435
|
+
}
|
|
2436
|
+
return ids;
|
|
2437
|
+
}
|
|
2355
2438
|
function setIdentifier(model2, id2) {
|
|
2356
|
-
const
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2439
|
+
const previousId = idMap.get(model2);
|
|
2440
|
+
if (previousId === id2) return;
|
|
2441
|
+
const Type = getModelType(model2);
|
|
2442
|
+
const ancestors = [];
|
|
2443
|
+
let node = model2.parent;
|
|
2444
|
+
while (node) {
|
|
2445
|
+
assertAvailable(node, [[Type, id2, model2]]);
|
|
2446
|
+
ancestors.push(node);
|
|
2447
|
+
node = node.parent;
|
|
2364
2448
|
}
|
|
2449
|
+
for (const ancestor of ancestors) {
|
|
2450
|
+
const ids = bucket(ancestor, Type);
|
|
2451
|
+
if (previousId != null && ids.get(previousId) === model2)
|
|
2452
|
+
ids.delete(previousId);
|
|
2453
|
+
ids.set(id2, model2);
|
|
2454
|
+
}
|
|
2455
|
+
idMap.set(model2, id2);
|
|
2365
2456
|
}
|
|
2366
2457
|
function getIdentifier(model2) {
|
|
2367
2458
|
return idMap.get(model2);
|
|
2368
2459
|
}
|
|
2369
|
-
function getModelById(root, id2) {
|
|
2370
|
-
|
|
2371
|
-
return map?.get(id2);
|
|
2460
|
+
function getModelById(root, Type, id2) {
|
|
2461
|
+
return attachedIdMap.get(root)?.get(Type)?.get(id2);
|
|
2372
2462
|
}
|
|
2373
|
-
function
|
|
2374
|
-
const
|
|
2463
|
+
function onModelAttached(model2) {
|
|
2464
|
+
const entries = entriesFor(model2);
|
|
2465
|
+
if (!entries.length) return;
|
|
2466
|
+
const ancestors = [];
|
|
2375
2467
|
let node = model2.parent;
|
|
2376
2468
|
while (node) {
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
map.set(id2, model2);
|
|
2380
|
-
}
|
|
2469
|
+
assertAvailable(node, entries);
|
|
2470
|
+
ancestors.push(node);
|
|
2381
2471
|
node = node.parent;
|
|
2382
2472
|
}
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
const id2 = idMap.get(model2);
|
|
2387
|
-
if (attachedMap || id2 != null) {
|
|
2388
|
-
const id22 = idMap.get(model2);
|
|
2389
|
-
let node = model2.parent;
|
|
2390
|
-
while (node) {
|
|
2391
|
-
let map = attachedIdMap.get(node);
|
|
2392
|
-
if (!map) {
|
|
2393
|
-
map = observable(/* @__PURE__ */ new Map());
|
|
2394
|
-
attachedIdMap.set(node, map);
|
|
2395
|
-
}
|
|
2396
|
-
attachedMap?.forEach((value, key) => {
|
|
2397
|
-
if (map.has(key)) {
|
|
2398
|
-
if (loadingSnapshot) {
|
|
2399
|
-
potentialDups.add(model2);
|
|
2400
|
-
potentialDups.add(map.get(key));
|
|
2401
|
-
} else {
|
|
2402
|
-
throw new Error(
|
|
2403
|
-
`r-state-tree: id: ${key} is already assigned to another model`
|
|
2404
|
-
);
|
|
2405
|
-
}
|
|
2406
|
-
}
|
|
2407
|
-
map.set(key, value);
|
|
2408
|
-
});
|
|
2409
|
-
if (id22 != null) {
|
|
2410
|
-
if (map.has(id22)) {
|
|
2411
|
-
if (loadingSnapshot) {
|
|
2412
|
-
potentialDups.add(model2);
|
|
2413
|
-
potentialDups.add(map.get(id22));
|
|
2414
|
-
} else {
|
|
2415
|
-
throw new Error(
|
|
2416
|
-
`r-state-tree: id: ${id22} is already assigned to another model`
|
|
2417
|
-
);
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
map.set(id22, model2);
|
|
2421
|
-
}
|
|
2422
|
-
node = node.parent;
|
|
2423
|
-
}
|
|
2473
|
+
for (const ancestor of ancestors) {
|
|
2474
|
+
for (const [Type, id2, value] of entries)
|
|
2475
|
+
bucket(ancestor, Type).set(id2, value);
|
|
2424
2476
|
}
|
|
2425
2477
|
}
|
|
2426
2478
|
function onModelDetached(model2) {
|
|
2427
|
-
const
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
const
|
|
2433
|
-
if (
|
|
2434
|
-
attachedMap?.forEach((value, key) => {
|
|
2435
|
-
map.delete(key);
|
|
2436
|
-
});
|
|
2437
|
-
if (id2 != null) {
|
|
2438
|
-
map.delete(id2);
|
|
2439
|
-
}
|
|
2440
|
-
}
|
|
2441
|
-
node = node.parent;
|
|
2479
|
+
const entries = entriesFor(model2);
|
|
2480
|
+
let node = model2.parent;
|
|
2481
|
+
while (node) {
|
|
2482
|
+
const map = attachedIdMap.get(node);
|
|
2483
|
+
for (const [Type, id2, value] of entries) {
|
|
2484
|
+
const ids = map?.get(Type);
|
|
2485
|
+
if (ids?.get(id2) === value) ids.delete(id2);
|
|
2442
2486
|
}
|
|
2487
|
+
node = node.parent;
|
|
2443
2488
|
}
|
|
2444
2489
|
}
|
|
2445
2490
|
const listenerMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -2495,19 +2540,28 @@ class ObservableListener {
|
|
|
2495
2540
|
notify(ev) {
|
|
2496
2541
|
if (!this.listeners) return;
|
|
2497
2542
|
this.notifying = true;
|
|
2498
|
-
|
|
2499
|
-
this.listeners
|
|
2543
|
+
try {
|
|
2544
|
+
for (let i = 0; i < this.listeners.length; i++) {
|
|
2545
|
+
this.listeners[i](ev);
|
|
2546
|
+
}
|
|
2547
|
+
} finally {
|
|
2548
|
+
this.notifying = false;
|
|
2500
2549
|
}
|
|
2501
|
-
this.notifying = false;
|
|
2502
2550
|
}
|
|
2503
2551
|
}
|
|
2504
2552
|
class ChildModelsAdministration extends ArrayAdministration {
|
|
2505
2553
|
set(index, newValue) {
|
|
2506
2554
|
return signalsCore.batch(() => {
|
|
2555
|
+
const oldValue = this.source[index];
|
|
2507
2556
|
const result = super.set(index, newValue);
|
|
2508
2557
|
const sourceValue = getSource(newValue);
|
|
2509
|
-
if (
|
|
2510
|
-
|
|
2558
|
+
if (oldValue !== sourceValue) {
|
|
2559
|
+
try {
|
|
2560
|
+
notifyArrayUpdate(this.proxy, index, oldValue, sourceValue);
|
|
2561
|
+
} catch (error) {
|
|
2562
|
+
super.set(index, oldValue);
|
|
2563
|
+
throw error;
|
|
2564
|
+
}
|
|
2511
2565
|
}
|
|
2512
2566
|
return result;
|
|
2513
2567
|
});
|
|
@@ -2516,7 +2570,12 @@ class ChildModelsAdministration extends ArrayAdministration {
|
|
|
2516
2570
|
return signalsCore.batch(() => {
|
|
2517
2571
|
const deleted = super.spliceWithArray(index, deleteCount, newItems);
|
|
2518
2572
|
if (deleteCount || newItems?.length) {
|
|
2519
|
-
|
|
2573
|
+
try {
|
|
2574
|
+
notifySpliceArray(this.proxy, index, newItems ?? [], deleted);
|
|
2575
|
+
} catch (error) {
|
|
2576
|
+
super.spliceWithArray(index, newItems?.length ?? 0, deleted);
|
|
2577
|
+
throw error;
|
|
2578
|
+
}
|
|
2520
2579
|
}
|
|
2521
2580
|
return deleted;
|
|
2522
2581
|
});
|
|
@@ -2595,6 +2654,9 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2595
2654
|
{
|
|
2596
2655
|
get(target, prop, proxy) {
|
|
2597
2656
|
const adm = getAdministration(target);
|
|
2657
|
+
if (prop === Symbol.dispose) {
|
|
2658
|
+
return Reflect.get(target, prop, proxy);
|
|
2659
|
+
}
|
|
2598
2660
|
if (prop === "parent") {
|
|
2599
2661
|
return target.parent;
|
|
2600
2662
|
}
|
|
@@ -2613,6 +2675,7 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2613
2675
|
},
|
|
2614
2676
|
set(target, name, value) {
|
|
2615
2677
|
const adm = getAdministration(target);
|
|
2678
|
+
adm.assertUsable();
|
|
2616
2679
|
adm.writeInProgress.add(name);
|
|
2617
2680
|
try {
|
|
2618
2681
|
switch (adm.getCfgType(name)) {
|
|
@@ -2675,6 +2738,8 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2675
2738
|
computedSnapshot;
|
|
2676
2739
|
snapshotMap = /* @__PURE__ */ new Map();
|
|
2677
2740
|
contextCache = /* @__PURE__ */ new Map();
|
|
2741
|
+
ownedDisposers = /* @__PURE__ */ new Set();
|
|
2742
|
+
disposed = false;
|
|
2678
2743
|
parentName = null;
|
|
2679
2744
|
get parent() {
|
|
2680
2745
|
this.parentAtom.reportObserved();
|
|
@@ -2689,6 +2754,29 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2689
2754
|
setConfiguration(configurationGetter) {
|
|
2690
2755
|
this.configurationGetter = configurationGetter;
|
|
2691
2756
|
}
|
|
2757
|
+
assertUsable() {
|
|
2758
|
+
if (this.disposed) {
|
|
2759
|
+
throw new Error("r-state-tree: cannot use a disposed model");
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
own(disposer) {
|
|
2763
|
+
this.assertUsable();
|
|
2764
|
+
let active = true;
|
|
2765
|
+
const wrapped = () => {
|
|
2766
|
+
if (!active) return;
|
|
2767
|
+
active = false;
|
|
2768
|
+
this.ownedDisposers.delete(wrapped);
|
|
2769
|
+
disposer();
|
|
2770
|
+
};
|
|
2771
|
+
this.ownedDisposers.add(wrapped);
|
|
2772
|
+
return wrapped;
|
|
2773
|
+
}
|
|
2774
|
+
reaction(track, callback) {
|
|
2775
|
+
return this.own(reaction(track, callback));
|
|
2776
|
+
}
|
|
2777
|
+
effect(callback) {
|
|
2778
|
+
return this.own(signalsCore.effect(callback));
|
|
2779
|
+
}
|
|
2692
2780
|
get configuration() {
|
|
2693
2781
|
return this.configurationGetter?.() ?? {};
|
|
2694
2782
|
}
|
|
@@ -2758,8 +2846,8 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2758
2846
|
);
|
|
2759
2847
|
}
|
|
2760
2848
|
if (v !== void 0) {
|
|
2761
|
-
this.source[name] = v;
|
|
2762
2849
|
setIdentifier(this.proxy, v);
|
|
2850
|
+
this.source[name] = v;
|
|
2763
2851
|
}
|
|
2764
2852
|
}
|
|
2765
2853
|
setModel(name, newModel) {
|
|
@@ -2814,11 +2902,30 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2814
2902
|
name,
|
|
2815
2903
|
observe(this.proxy[name], (event) => {
|
|
2816
2904
|
if (event.type === "updateArray") {
|
|
2817
|
-
getModelAdm(event.oldValue)
|
|
2818
|
-
getModelAdm(event.newValue)
|
|
2905
|
+
const oldAdm = getModelAdm(event.oldValue);
|
|
2906
|
+
const newAdm = getModelAdm(event.newValue);
|
|
2907
|
+
oldAdm.detach();
|
|
2908
|
+
try {
|
|
2909
|
+
newAdm.attach(this, name);
|
|
2910
|
+
} catch (error) {
|
|
2911
|
+
oldAdm.attach(this, name);
|
|
2912
|
+
throw error;
|
|
2913
|
+
}
|
|
2819
2914
|
} else if (event.type === "spliceArray") {
|
|
2915
|
+
const attached = [];
|
|
2820
2916
|
event.removed.forEach((model2) => getModelAdm(model2).detach());
|
|
2821
|
-
|
|
2917
|
+
try {
|
|
2918
|
+
event.added.forEach((model2) => {
|
|
2919
|
+
getModelAdm(model2).attach(this, name);
|
|
2920
|
+
attached.push(model2);
|
|
2921
|
+
});
|
|
2922
|
+
} catch (error) {
|
|
2923
|
+
attached.forEach((model2) => getModelAdm(model2).detach());
|
|
2924
|
+
event.removed.forEach(
|
|
2925
|
+
(model2) => getModelAdm(model2).attach(this, name)
|
|
2926
|
+
);
|
|
2927
|
+
throw error;
|
|
2928
|
+
}
|
|
2822
2929
|
}
|
|
2823
2930
|
})
|
|
2824
2931
|
);
|
|
@@ -2833,7 +2940,9 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2833
2940
|
getModelRef(name) {
|
|
2834
2941
|
const a = this.getReferencedAtom(name);
|
|
2835
2942
|
a.reportObserved();
|
|
2836
|
-
|
|
2943
|
+
const Type = this.getRequiredModelRefType(name);
|
|
2944
|
+
const root = this.getReactiveRoot().proxy;
|
|
2945
|
+
return this.source[name] != null ? getModelById(root, Type, this.source[name]) : void 0;
|
|
2837
2946
|
}
|
|
2838
2947
|
getModelRefs(name) {
|
|
2839
2948
|
const a = this.getReferencedAtom(name);
|
|
@@ -2842,7 +2951,9 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2842
2951
|
if (!this.referencedModels) this.referencedModels = /* @__PURE__ */ new Map();
|
|
2843
2952
|
c = createComputed(() => {
|
|
2844
2953
|
a.reportObserved();
|
|
2845
|
-
const
|
|
2954
|
+
const Type = this.getRequiredModelRefType(name);
|
|
2955
|
+
const root = this.getReactiveRoot().proxy;
|
|
2956
|
+
const models = (this.source[name] || []).map((id2) => getModelById(root, Type, id2)).filter((m) => !!m);
|
|
2846
2957
|
return models;
|
|
2847
2958
|
});
|
|
2848
2959
|
this.referencedModels.set(name, c);
|
|
@@ -2852,6 +2963,7 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2852
2963
|
setModelRef(name, modelValue) {
|
|
2853
2964
|
let id2 = void 0;
|
|
2854
2965
|
if (modelValue) {
|
|
2966
|
+
this.assertModelRefType(name, modelValue);
|
|
2855
2967
|
id2 = getIdentifier(modelValue);
|
|
2856
2968
|
if (id2 == null) {
|
|
2857
2969
|
throw new Error(
|
|
@@ -2864,6 +2976,7 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2864
2976
|
}
|
|
2865
2977
|
setModelRefs(name, modelValue) {
|
|
2866
2978
|
const ids = modelValue.map((model2) => {
|
|
2979
|
+
this.assertModelRefType(name, model2);
|
|
2867
2980
|
const id2 = getIdentifier(model2);
|
|
2868
2981
|
if (id2 == null) {
|
|
2869
2982
|
throw new Error(
|
|
@@ -2875,31 +2988,87 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2875
2988
|
this.source[name] = ids;
|
|
2876
2989
|
this.referencedAtoms?.get(name)?.reportChanged();
|
|
2877
2990
|
}
|
|
2991
|
+
getRequiredModelRefType(name) {
|
|
2992
|
+
const Type = this.getCfgChildType(name);
|
|
2993
|
+
if (!Type) {
|
|
2994
|
+
throw new Error(
|
|
2995
|
+
`r-state-tree: modelRef '${String(name)}' requires a model constructor`
|
|
2996
|
+
);
|
|
2997
|
+
}
|
|
2998
|
+
return Type;
|
|
2999
|
+
}
|
|
3000
|
+
assertModelRefType(name, model2) {
|
|
3001
|
+
const Type = this.getRequiredModelRefType(name);
|
|
3002
|
+
if (!(model2 instanceof Type)) {
|
|
3003
|
+
throw new Error(
|
|
3004
|
+
`r-state-tree: modelRef '${String(name)}' must reference ${Type.name}`
|
|
3005
|
+
);
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
2878
3008
|
attach(parent = null, parentName = null) {
|
|
3009
|
+
this.assertUsable();
|
|
2879
3010
|
if (this.parent) {
|
|
2880
3011
|
throw new Error(
|
|
2881
3012
|
"r-state-tree: child model already attached to a parent. Did you mean to use modelRef?"
|
|
2882
3013
|
);
|
|
2883
3014
|
}
|
|
2884
|
-
if (parent) {
|
|
2885
|
-
this.parent = parent;
|
|
2886
|
-
this.root = parent.root;
|
|
2887
|
-
this.parentName = parentName;
|
|
2888
|
-
}
|
|
2889
3015
|
signalsCore.batch(() => {
|
|
2890
|
-
|
|
2891
|
-
|
|
3016
|
+
if (parent) {
|
|
3017
|
+
this.parent = parent;
|
|
3018
|
+
this.root = parent.root;
|
|
3019
|
+
this.parentName = parentName;
|
|
3020
|
+
}
|
|
3021
|
+
try {
|
|
3022
|
+
onModelAttached(this.proxy);
|
|
3023
|
+
} catch (error) {
|
|
3024
|
+
this.parent = null;
|
|
3025
|
+
this.root = this;
|
|
3026
|
+
this.parentName = null;
|
|
3027
|
+
throw error;
|
|
3028
|
+
}
|
|
2892
3029
|
});
|
|
2893
3030
|
}
|
|
3031
|
+
getReactiveRoot() {
|
|
3032
|
+
const parent = this.parent;
|
|
3033
|
+
return parent ? parent.getReactiveRoot() : this;
|
|
3034
|
+
}
|
|
2894
3035
|
detach() {
|
|
2895
3036
|
signalsCore.batch(() => {
|
|
2896
|
-
this.proxy.modelWillDetach();
|
|
2897
3037
|
onModelDetached(this.proxy);
|
|
3038
|
+
this.contextCache.forEach((computed2) => computed2.clear());
|
|
3039
|
+
this.contextCache.clear();
|
|
3040
|
+
this.parent = null;
|
|
3041
|
+
this.parentName = null;
|
|
3042
|
+
this.root = this;
|
|
2898
3043
|
});
|
|
3044
|
+
}
|
|
3045
|
+
dispose(internal = false) {
|
|
3046
|
+
if (this.disposed) return;
|
|
3047
|
+
if (!internal && this.parent) {
|
|
3048
|
+
throw new Error(
|
|
3049
|
+
"r-state-tree: cannot directly dispose an attached child model"
|
|
3050
|
+
);
|
|
3051
|
+
}
|
|
3052
|
+
signalsCore.batch(() => {
|
|
3053
|
+
this.activeModels.forEach((name) => {
|
|
3054
|
+
const child2 = this.proxy[name];
|
|
3055
|
+
if (Array.isArray(child2)) {
|
|
3056
|
+
child2.forEach((model2) => getModelAdm(model2).dispose(true));
|
|
3057
|
+
} else if (child2) {
|
|
3058
|
+
getModelAdm(child2).dispose(true);
|
|
3059
|
+
}
|
|
3060
|
+
});
|
|
3061
|
+
if (this.parent) onModelDetached(this.proxy);
|
|
3062
|
+
this.parent = null;
|
|
3063
|
+
this.parentName = null;
|
|
3064
|
+
this.root = this;
|
|
3065
|
+
});
|
|
3066
|
+
this.disposed = true;
|
|
3067
|
+
this.modelsTraceUnsub.forEach((dispose) => dispose());
|
|
3068
|
+
this.modelsTraceUnsub.clear();
|
|
2899
3069
|
this.contextCache.forEach((computed2) => computed2.clear());
|
|
2900
3070
|
this.contextCache.clear();
|
|
2901
|
-
this.
|
|
2902
|
-
this.root = this;
|
|
3071
|
+
Array.from(this.ownedDisposers).forEach((dispose) => dispose());
|
|
2903
3072
|
}
|
|
2904
3073
|
getContextValue(contextId, provideSymbol, defaultValue, hasDefault) {
|
|
2905
3074
|
let computed2 = this.contextCache.get(contextId);
|
|
@@ -3002,85 +3171,94 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
3002
3171
|
}
|
|
3003
3172
|
return true;
|
|
3004
3173
|
};
|
|
3005
|
-
|
|
3006
|
-
signalsCore.
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
if (
|
|
3018
|
-
if (value?.[0] instanceof Model) {
|
|
3019
|
-
this.proxy[key] = value;
|
|
3020
|
-
} else {
|
|
3021
|
-
this.source[key] = value.map(
|
|
3022
|
-
(snapshot2) => getSnapshotRefId(snapshot2)
|
|
3023
|
-
);
|
|
3024
|
-
this.referencedAtoms?.get(key)?.reportChanged();
|
|
3025
|
-
}
|
|
3026
|
-
break;
|
|
3027
|
-
} else if (value instanceof Model) {
|
|
3174
|
+
signalsCore.untracked(() => {
|
|
3175
|
+
signalsCore.batch(() => {
|
|
3176
|
+
Object.keys(snapshot).forEach((key) => {
|
|
3177
|
+
const type = this.getCfgType(key);
|
|
3178
|
+
const childType2 = this.getCfgChildType(key);
|
|
3179
|
+
const value = snapshot[key];
|
|
3180
|
+
switch (type) {
|
|
3181
|
+
case ModelCfgTypes.state:
|
|
3182
|
+
this.proxy[key] = this.hydrateStateValue(this.proxy[key], value);
|
|
3183
|
+
break;
|
|
3184
|
+
case ModelCfgTypes.modelRef:
|
|
3185
|
+
if (Array.isArray(value)) {
|
|
3186
|
+
if (value?.[0] instanceof Model) {
|
|
3028
3187
|
this.proxy[key] = value;
|
|
3029
3188
|
} else {
|
|
3030
|
-
this.source[key] =
|
|
3189
|
+
this.source[key] = value.map(
|
|
3190
|
+
(snapshot2) => getSnapshotRefId(snapshot2)
|
|
3191
|
+
);
|
|
3031
3192
|
this.referencedAtoms?.get(key)?.reportChanged();
|
|
3032
3193
|
}
|
|
3033
3194
|
break;
|
|
3034
|
-
|
|
3035
|
-
this.
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3195
|
+
} else if (value instanceof Model) {
|
|
3196
|
+
this.proxy[key] = value;
|
|
3197
|
+
} else {
|
|
3198
|
+
this.source[key] = getSnapshotRefId(value);
|
|
3199
|
+
this.referencedAtoms?.get(key)?.reportChanged();
|
|
3200
|
+
}
|
|
3201
|
+
break;
|
|
3202
|
+
case ModelCfgTypes.id:
|
|
3203
|
+
this.setId(key, value);
|
|
3204
|
+
break;
|
|
3205
|
+
case CommonCfgTypes.child:
|
|
3206
|
+
let model2;
|
|
3207
|
+
if (Array.isArray(value)) {
|
|
3208
|
+
const Ctor = childType2;
|
|
3209
|
+
const snapshotIds = /* @__PURE__ */ new Set();
|
|
3210
|
+
for (const childSnapshot of value) {
|
|
3211
|
+
if (childSnapshot instanceof Model) continue;
|
|
3212
|
+
const snapshotId = childType2 ? getSnapshotId(childSnapshot ?? {}, Ctor) : null;
|
|
3213
|
+
if (snapshotId != null && snapshotIds.has(snapshotId)) {
|
|
3214
|
+
throw new Error(
|
|
3215
|
+
"r-state-tree duplicate ids detected after snapshot was loaded"
|
|
3216
|
+
);
|
|
3217
|
+
}
|
|
3218
|
+
if (snapshotId != null) snapshotIds.add(snapshotId);
|
|
3219
|
+
}
|
|
3220
|
+
this.proxy[key] = value?.map(
|
|
3221
|
+
(snapshot2, index) => {
|
|
3222
|
+
snapshot2 = snapshot2 ?? {};
|
|
3223
|
+
let model22;
|
|
3224
|
+
if (snapshot2 instanceof Model) {
|
|
3225
|
+
model22 = snapshot2;
|
|
3226
|
+
} else {
|
|
3227
|
+
ensureChildTypes(key);
|
|
3228
|
+
const id2 = childType2 && getSnapshotId(snapshot2, Ctor);
|
|
3229
|
+
const foundModel = id2 != null ? getModelById(this.root.proxy, Ctor, id2) : this.proxy[key][index];
|
|
3230
|
+
const adm = foundModel && getModelAdm(foundModel);
|
|
3231
|
+
if (adm && foundModel.parent === this.proxy && adm?.parentName === key) {
|
|
3232
|
+
adm.loadSnapshot(snapshot2);
|
|
3233
|
+
model22 = foundModel;
|
|
3047
3234
|
} else {
|
|
3048
|
-
|
|
3049
|
-
const id2 = childType2 && getSnapshotId(snapshot2, Ctor);
|
|
3050
|
-
const foundModel = id2 != null ? getModelById(this.root.proxy, id2) : this.proxy[key][index];
|
|
3051
|
-
const adm = foundModel && getModelAdm(foundModel);
|
|
3052
|
-
if (adm && foundModel.parent === this.proxy && adm?.parentName === key) {
|
|
3053
|
-
adm.loadSnapshot(snapshot2);
|
|
3054
|
-
model22 = foundModel;
|
|
3055
|
-
} else {
|
|
3056
|
-
model22 = Ctor.create(snapshot2);
|
|
3057
|
-
}
|
|
3235
|
+
model22 = Ctor.create(snapshot2);
|
|
3058
3236
|
}
|
|
3059
|
-
return model22;
|
|
3060
3237
|
}
|
|
3061
|
-
|
|
3062
|
-
break;
|
|
3063
|
-
} else if (value instanceof Model) {
|
|
3064
|
-
model2 = value;
|
|
3065
|
-
} else {
|
|
3066
|
-
ensureChildTypes(key);
|
|
3067
|
-
const id2 = childType2 && getSnapshotId(value, childType2);
|
|
3068
|
-
if (id2 != null && this.proxy[key] && id2 === getIdentifier(this.proxy[key])) {
|
|
3069
|
-
const adm = getModelAdm(this.proxy[key]);
|
|
3070
|
-
adm.loadSnapshot(value);
|
|
3071
|
-
model2 = this.proxy[key];
|
|
3072
|
-
} else {
|
|
3073
|
-
model2 = childType2.create(value);
|
|
3238
|
+
return model22;
|
|
3074
3239
|
}
|
|
3075
|
-
}
|
|
3076
|
-
this.proxy[key] = model2;
|
|
3077
|
-
break;
|
|
3078
|
-
default:
|
|
3079
|
-
console.warn(
|
|
3080
|
-
`r-state-tree: invalid key '${key}' found in snapshot, ignored.`
|
|
3081
3240
|
);
|
|
3082
|
-
|
|
3083
|
-
|
|
3241
|
+
break;
|
|
3242
|
+
} else if (value instanceof Model) {
|
|
3243
|
+
model2 = value;
|
|
3244
|
+
} else {
|
|
3245
|
+
ensureChildTypes(key);
|
|
3246
|
+
const id2 = childType2 && getSnapshotId(value, childType2);
|
|
3247
|
+
if (id2 != null && this.proxy[key] && this.proxy[key] instanceof childType2 && id2 === getIdentifier(this.proxy[key])) {
|
|
3248
|
+
const adm = getModelAdm(this.proxy[key]);
|
|
3249
|
+
adm.loadSnapshot(value);
|
|
3250
|
+
model2 = this.proxy[key];
|
|
3251
|
+
} else {
|
|
3252
|
+
model2 = childType2.create(value);
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
this.proxy[key] = model2;
|
|
3256
|
+
break;
|
|
3257
|
+
default:
|
|
3258
|
+
console.warn(
|
|
3259
|
+
`r-state-tree: invalid key '${key}' found in snapshot, ignored.`
|
|
3260
|
+
);
|
|
3261
|
+
}
|
|
3084
3262
|
});
|
|
3085
3263
|
});
|
|
3086
3264
|
});
|
|
@@ -3095,11 +3273,14 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
3095
3273
|
}
|
|
3096
3274
|
return this.computedSnapshot.get();
|
|
3097
3275
|
}
|
|
3276
|
+
getSnapshotForRollback() {
|
|
3277
|
+
return this.toJSON();
|
|
3278
|
+
}
|
|
3098
3279
|
}
|
|
3099
3280
|
let initEnabled = false;
|
|
3100
3281
|
class Model {
|
|
3101
3282
|
static childTypes = {};
|
|
3102
|
-
static create(snapshot
|
|
3283
|
+
static create(snapshot) {
|
|
3103
3284
|
let instance;
|
|
3104
3285
|
try {
|
|
3105
3286
|
initEnabled = true;
|
|
@@ -3108,8 +3289,12 @@ class Model {
|
|
|
3108
3289
|
initEnabled = false;
|
|
3109
3290
|
}
|
|
3110
3291
|
const adm = getModelAdm(instance);
|
|
3111
|
-
|
|
3112
|
-
|
|
3292
|
+
try {
|
|
3293
|
+
snapshot && adm.loadSnapshot(snapshot);
|
|
3294
|
+
} catch (error) {
|
|
3295
|
+
adm.dispose(true);
|
|
3296
|
+
throw error;
|
|
3297
|
+
}
|
|
3113
3298
|
return instance;
|
|
3114
3299
|
}
|
|
3115
3300
|
constructor() {
|
|
@@ -3133,31 +3318,33 @@ class Model {
|
|
|
3133
3318
|
get parent() {
|
|
3134
3319
|
return getModelAdm(this).parent?.proxy ?? null;
|
|
3135
3320
|
}
|
|
3136
|
-
|
|
3137
|
-
|
|
3321
|
+
reaction(track, callback) {
|
|
3322
|
+
return getModelAdm(this).reaction(track, callback);
|
|
3138
3323
|
}
|
|
3139
|
-
|
|
3140
|
-
|
|
3324
|
+
effect(callback) {
|
|
3325
|
+
return getModelAdm(this).effect(callback);
|
|
3141
3326
|
}
|
|
3142
|
-
|
|
3143
|
-
|
|
3327
|
+
[Symbol.dispose]() {
|
|
3328
|
+
getModelAdm(this).dispose();
|
|
3144
3329
|
}
|
|
3145
3330
|
}
|
|
3331
|
+
function findModelById(root, ModelType, id2) {
|
|
3332
|
+
return getModelById(getModelAdm(root).root.proxy, ModelType, id2);
|
|
3333
|
+
}
|
|
3146
3334
|
function mount(container) {
|
|
3147
3335
|
return allowNewStore(() => {
|
|
3148
3336
|
const element = container;
|
|
3149
3337
|
const s = new element.Type(element.props);
|
|
3150
|
-
getStoreAdm(s)
|
|
3338
|
+
const adm = getStoreAdm(s);
|
|
3339
|
+
try {
|
|
3340
|
+
adm.mount();
|
|
3341
|
+
} catch (error) {
|
|
3342
|
+
adm.dispose(true);
|
|
3343
|
+
throw error;
|
|
3344
|
+
}
|
|
3151
3345
|
return s;
|
|
3152
3346
|
});
|
|
3153
3347
|
}
|
|
3154
|
-
function unmount(container) {
|
|
3155
|
-
const internalStore = getStoreAdm(container);
|
|
3156
|
-
if (!internalStore.isRoot()) {
|
|
3157
|
-
throw new Error("r-state-tree: can only unmount root stores");
|
|
3158
|
-
}
|
|
3159
|
-
internalStore.unmount();
|
|
3160
|
-
}
|
|
3161
3348
|
function toSnapshot(model2) {
|
|
3162
3349
|
return getModelAdm(model2).getSnapshot();
|
|
3163
3350
|
}
|
|
@@ -3177,7 +3364,13 @@ function onSnapshotDiff(model2, callback) {
|
|
|
3177
3364
|
}
|
|
3178
3365
|
function applySnapshot(model2, snapshot) {
|
|
3179
3366
|
const adm = getModelAdm(model2);
|
|
3180
|
-
adm.
|
|
3367
|
+
const previousSnapshot = adm.getSnapshotForRollback();
|
|
3368
|
+
try {
|
|
3369
|
+
adm.loadSnapshot(snapshot);
|
|
3370
|
+
} catch (error) {
|
|
3371
|
+
adm.loadSnapshot(previousSnapshot);
|
|
3372
|
+
throw error;
|
|
3373
|
+
}
|
|
3181
3374
|
return model2;
|
|
3182
3375
|
}
|
|
3183
3376
|
const CONTEXT_SYMBOL = Symbol("context");
|
|
@@ -3296,6 +3489,7 @@ exports.child = child;
|
|
|
3296
3489
|
exports.computed = computed;
|
|
3297
3490
|
exports.createContext = createContext;
|
|
3298
3491
|
exports.createStore = createStore;
|
|
3492
|
+
exports.findModelById = findModelById;
|
|
3299
3493
|
exports.getSignal = getSignal;
|
|
3300
3494
|
exports.id = id;
|
|
3301
3495
|
exports.isObservable = isObservable;
|
|
@@ -3313,5 +3507,4 @@ exports.source = source;
|
|
|
3313
3507
|
exports.state = state;
|
|
3314
3508
|
exports.toObservableTree = toObservableTree;
|
|
3315
3509
|
exports.toSnapshot = toSnapshot;
|
|
3316
|
-
exports.unmount = unmount;
|
|
3317
3510
|
exports.updateStore = updateStore;
|