r-state-tree 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -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 +428 -262
- package/dist/r-state-tree.js +428 -262
- package/dist/store/Store.d.ts +5 -4
- package/dist/store/StoreAdministration.d.ts +8 -4
- 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
|
+
ownedDisposers = /* @__PURE__ */ new Set();
|
|
2026
2040
|
configurationGetter;
|
|
2027
2041
|
setConfiguration(configurationGetter) {
|
|
2028
2042
|
this.configurationGetter = configurationGetter;
|
|
@@ -2096,7 +2110,7 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2096
2110
|
if (newStores.size || removedStores.size || keyedIndexChanged) {
|
|
2097
2111
|
signalsCore.batch(() => childStoreData.value.set(stores));
|
|
2098
2112
|
}
|
|
2099
|
-
removedStores.forEach((s) => getStoreAdm(s).
|
|
2113
|
+
removedStores.forEach((s) => getStoreAdm(s).dispose(true));
|
|
2100
2114
|
newStores.forEach((s) => getStoreAdm(s).mount(this, name));
|
|
2101
2115
|
return stores;
|
|
2102
2116
|
}
|
|
@@ -2107,12 +2121,12 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2107
2121
|
);
|
|
2108
2122
|
const { key, Type, props } = element || {};
|
|
2109
2123
|
if (!element) {
|
|
2110
|
-
oldStore && getStoreAdm(oldStore).
|
|
2124
|
+
oldStore && getStoreAdm(oldStore).dispose(true);
|
|
2111
2125
|
signalsCore.batch(() => childStoreData.value.set(null));
|
|
2112
2126
|
return null;
|
|
2113
2127
|
} else if (!oldStore || oldStore.props.key !== key || !(oldStore instanceof Type)) {
|
|
2114
2128
|
if (oldStore) {
|
|
2115
|
-
getStoreAdm(oldStore).
|
|
2129
|
+
getStoreAdm(oldStore).dispose(true);
|
|
2116
2130
|
}
|
|
2117
2131
|
const childStore = this.createChildStore(element);
|
|
2118
2132
|
signalsCore.batch(() => childStoreData.value.set(childStore));
|
|
@@ -2156,7 +2170,8 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2156
2170
|
getStore(name) {
|
|
2157
2171
|
const childStoreData = this.childStoreDataMap.get(name);
|
|
2158
2172
|
if (!childStoreData) {
|
|
2159
|
-
|
|
2173
|
+
signalsCore.untracked(() => this.initializeStore(name));
|
|
2174
|
+
return this.childStoreDataMap.get(name).value.get();
|
|
2160
2175
|
} else {
|
|
2161
2176
|
const storeElement = signalsCore.untracked(() => childStoreData.computed.get());
|
|
2162
2177
|
validateStoreChildValue(storeElement, name);
|
|
@@ -2172,6 +2187,9 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2172
2187
|
isRoot() {
|
|
2173
2188
|
return !this.parent;
|
|
2174
2189
|
}
|
|
2190
|
+
get isMounted() {
|
|
2191
|
+
return this.mountedSignal.get();
|
|
2192
|
+
}
|
|
2175
2193
|
getContextValue(contextId, provideSymbol, defaultValue, hasDefault) {
|
|
2176
2194
|
let computed2 = this.contextCache.get(contextId);
|
|
2177
2195
|
if (!computed2) {
|
|
@@ -2205,12 +2223,37 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2205
2223
|
}
|
|
2206
2224
|
return void 0;
|
|
2207
2225
|
}
|
|
2226
|
+
own(disposer) {
|
|
2227
|
+
if (this.disposed) {
|
|
2228
|
+
disposer();
|
|
2229
|
+
throw new Error(
|
|
2230
|
+
"r-state-tree: cannot register reactive resources on a disposed store"
|
|
2231
|
+
);
|
|
2232
|
+
}
|
|
2233
|
+
let active = true;
|
|
2234
|
+
const wrapped = () => {
|
|
2235
|
+
if (!active) return;
|
|
2236
|
+
active = false;
|
|
2237
|
+
this.ownedDisposers.delete(wrapped);
|
|
2238
|
+
disposer();
|
|
2239
|
+
};
|
|
2240
|
+
this.ownedDisposers.add(wrapped);
|
|
2241
|
+
return wrapped;
|
|
2242
|
+
}
|
|
2208
2243
|
reaction(track, callback) {
|
|
2209
2244
|
const unsub = reaction(track, callback);
|
|
2210
|
-
this.
|
|
2211
|
-
|
|
2245
|
+
return this.own(unsub);
|
|
2246
|
+
}
|
|
2247
|
+
effect(callback) {
|
|
2248
|
+
return this.own(signalsCore.effect(callback));
|
|
2212
2249
|
}
|
|
2213
2250
|
mount(parent = null, childName) {
|
|
2251
|
+
if (this.disposed) {
|
|
2252
|
+
throw new Error("r-state-tree: cannot mount a disposed store");
|
|
2253
|
+
}
|
|
2254
|
+
if (this.isMounted) {
|
|
2255
|
+
throw new Error("r-state-tree: store is already mounted");
|
|
2256
|
+
}
|
|
2214
2257
|
const frame = {
|
|
2215
2258
|
storeName: this.proxy.constructor.name || "Store",
|
|
2216
2259
|
childName,
|
|
@@ -2221,19 +2264,20 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2221
2264
|
}
|
|
2222
2265
|
mountingStack.push(frame);
|
|
2223
2266
|
try {
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2267
|
+
signalsCore.batch(() => {
|
|
2268
|
+
this.parent = parent || null;
|
|
2269
|
+
this.childStoreDataMap.forEach(({ value }, name) => {
|
|
2270
|
+
const stores = value.get();
|
|
2271
|
+
if (Array.isArray(stores)) {
|
|
2272
|
+
stores?.forEach((s) => getStoreAdm(s)?.mount(this, name));
|
|
2273
|
+
} else if (stores) {
|
|
2274
|
+
getStoreAdm(stores)?.mount(this, name);
|
|
2275
|
+
}
|
|
2276
|
+
});
|
|
2277
|
+
this.mountedSignal.set(true);
|
|
2232
2278
|
});
|
|
2233
|
-
this.mounted = true;
|
|
2234
|
-
signalsCore.batch(() => this.proxy.storeDidMount?.());
|
|
2235
2279
|
} catch (error) {
|
|
2236
|
-
if (error instanceof RangeError && /call stack/i.test(error.message)) {
|
|
2280
|
+
if (error instanceof Error && (error instanceof RangeError && /call stack/i.test(error.message) || /cycle detected/i.test(error.message))) {
|
|
2237
2281
|
throw createCircularMountError(frame);
|
|
2238
2282
|
}
|
|
2239
2283
|
throw error;
|
|
@@ -2241,25 +2285,31 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
2241
2285
|
mountingStack.pop();
|
|
2242
2286
|
}
|
|
2243
2287
|
}
|
|
2244
|
-
|
|
2245
|
-
this.
|
|
2246
|
-
this.
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2288
|
+
dispose(internal = false) {
|
|
2289
|
+
if (this.disposed) return;
|
|
2290
|
+
if (!internal && !this.isRoot()) {
|
|
2291
|
+
throw new Error("r-state-tree: can only dispose root stores");
|
|
2292
|
+
}
|
|
2293
|
+
signalsCore.batch(() => {
|
|
2294
|
+
this.childStoreDataMap.forEach((data) => {
|
|
2295
|
+
const { value, computed: computed2, listener } = data;
|
|
2296
|
+
const stores = value.get();
|
|
2297
|
+
if (Array.isArray(stores)) {
|
|
2298
|
+
stores?.forEach((s) => getStoreAdm(s)?.dispose(true));
|
|
2299
|
+
} else if (stores) {
|
|
2300
|
+
getStoreAdm(stores)?.dispose(true);
|
|
2301
|
+
}
|
|
2302
|
+
computed2.clear();
|
|
2303
|
+
listener.dispose();
|
|
2304
|
+
});
|
|
2305
|
+
this.childStoreDataMap.clear();
|
|
2306
|
+
this.contextCache.forEach((computed2) => computed2.clear());
|
|
2307
|
+
this.contextCache.clear();
|
|
2308
|
+
this.parent = null;
|
|
2257
2309
|
});
|
|
2258
|
-
this.
|
|
2259
|
-
this.
|
|
2260
|
-
this.
|
|
2261
|
-
this.reactionsUnsub.forEach((u) => u());
|
|
2262
|
-
this.parent = null;
|
|
2310
|
+
this.mountedSignal.set(false);
|
|
2311
|
+
this.disposed = true;
|
|
2312
|
+
Array.from(this.ownedDisposers).forEach((dispose) => dispose());
|
|
2263
2313
|
}
|
|
2264
2314
|
}
|
|
2265
2315
|
let initEnabled$1 = false;
|
|
@@ -2305,141 +2355,109 @@ class Store {
|
|
|
2305
2355
|
get key() {
|
|
2306
2356
|
return this.props.key;
|
|
2307
2357
|
}
|
|
2358
|
+
get isMounted() {
|
|
2359
|
+
return getStoreAdm(this).isMounted;
|
|
2360
|
+
}
|
|
2308
2361
|
reaction(track, callback) {
|
|
2309
2362
|
return getStoreAdm(this).reaction(track, callback);
|
|
2310
2363
|
}
|
|
2311
|
-
|
|
2312
|
-
|
|
2364
|
+
effect(callback) {
|
|
2365
|
+
return getStoreAdm(this).effect(callback);
|
|
2313
2366
|
}
|
|
2314
|
-
|
|
2315
|
-
|
|
2367
|
+
[Symbol.dispose]() {
|
|
2368
|
+
getStoreAdm(this).dispose();
|
|
2316
2369
|
}
|
|
2317
2370
|
}
|
|
2318
2371
|
const attachedIdMap = /* @__PURE__ */ new WeakMap();
|
|
2319
2372
|
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
|
-
}
|
|
2373
|
+
function getModelType(model2) {
|
|
2374
|
+
return Object.getPrototypeOf(model2).constructor;
|
|
2375
|
+
}
|
|
2376
|
+
function entriesFor(model2) {
|
|
2377
|
+
const entries = [];
|
|
2378
|
+
attachedIdMap.get(model2)?.forEach((ids, Type) => {
|
|
2379
|
+
ids.forEach((value, id22) => {
|
|
2380
|
+
if (value) entries.push([Type, id22, value]);
|
|
2381
|
+
});
|
|
2382
|
+
});
|
|
2383
|
+
const id2 = idMap.get(model2);
|
|
2384
|
+
if (id2 != null) entries.push([getModelType(model2), id2, model2]);
|
|
2385
|
+
return entries;
|
|
2386
|
+
}
|
|
2387
|
+
function assertAvailable(node, entries) {
|
|
2388
|
+
const map = attachedIdMap.get(node);
|
|
2389
|
+
for (const [Type, id2, model2] of entries) {
|
|
2390
|
+
const existing = map?.get(Type)?.get(id2);
|
|
2391
|
+
if (existing && existing !== model2) {
|
|
2392
|
+
throw new Error(
|
|
2393
|
+
`r-state-tree: id: ${id2} is already assigned to another model`
|
|
2394
|
+
);
|
|
2352
2395
|
}
|
|
2353
2396
|
}
|
|
2354
2397
|
}
|
|
2398
|
+
function bucket(node, Type) {
|
|
2399
|
+
let map = attachedIdMap.get(node);
|
|
2400
|
+
if (!map) {
|
|
2401
|
+
map = observable(/* @__PURE__ */ new Map());
|
|
2402
|
+
attachedIdMap.set(node, map);
|
|
2403
|
+
}
|
|
2404
|
+
let ids = map.get(Type);
|
|
2405
|
+
if (!ids) {
|
|
2406
|
+
ids = observable(/* @__PURE__ */ new Map());
|
|
2407
|
+
map.set(Type, ids);
|
|
2408
|
+
}
|
|
2409
|
+
return ids;
|
|
2410
|
+
}
|
|
2355
2411
|
function setIdentifier(model2, id2) {
|
|
2356
|
-
const
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2412
|
+
const previousId = idMap.get(model2);
|
|
2413
|
+
if (previousId === id2) return;
|
|
2414
|
+
const Type = getModelType(model2);
|
|
2415
|
+
const ancestors = [];
|
|
2416
|
+
let node = model2.parent;
|
|
2417
|
+
while (node) {
|
|
2418
|
+
assertAvailable(node, [[Type, id2, model2]]);
|
|
2419
|
+
ancestors.push(node);
|
|
2420
|
+
node = node.parent;
|
|
2421
|
+
}
|
|
2422
|
+
for (const ancestor of ancestors) {
|
|
2423
|
+
const ids = bucket(ancestor, Type);
|
|
2424
|
+
if (previousId != null && ids.get(previousId) === model2)
|
|
2425
|
+
ids.delete(previousId);
|
|
2426
|
+
ids.set(id2, model2);
|
|
2364
2427
|
}
|
|
2428
|
+
idMap.set(model2, id2);
|
|
2365
2429
|
}
|
|
2366
2430
|
function getIdentifier(model2) {
|
|
2367
2431
|
return idMap.get(model2);
|
|
2368
2432
|
}
|
|
2369
|
-
function getModelById(root, id2) {
|
|
2370
|
-
|
|
2371
|
-
return map?.get(id2);
|
|
2433
|
+
function getModelById(root, Type, id2) {
|
|
2434
|
+
return attachedIdMap.get(root)?.get(Type)?.get(id2);
|
|
2372
2435
|
}
|
|
2373
|
-
function
|
|
2374
|
-
const
|
|
2436
|
+
function onModelAttached(model2) {
|
|
2437
|
+
const entries = entriesFor(model2);
|
|
2438
|
+
if (!entries.length) return;
|
|
2439
|
+
const ancestors = [];
|
|
2375
2440
|
let node = model2.parent;
|
|
2376
2441
|
while (node) {
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
map.set(id2, model2);
|
|
2380
|
-
}
|
|
2442
|
+
assertAvailable(node, entries);
|
|
2443
|
+
ancestors.push(node);
|
|
2381
2444
|
node = node.parent;
|
|
2382
2445
|
}
|
|
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
|
-
}
|
|
2446
|
+
for (const ancestor of ancestors) {
|
|
2447
|
+
for (const [Type, id2, value] of entries)
|
|
2448
|
+
bucket(ancestor, Type).set(id2, value);
|
|
2424
2449
|
}
|
|
2425
2450
|
}
|
|
2426
2451
|
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;
|
|
2452
|
+
const entries = entriesFor(model2);
|
|
2453
|
+
let node = model2.parent;
|
|
2454
|
+
while (node) {
|
|
2455
|
+
const map = attachedIdMap.get(node);
|
|
2456
|
+
for (const [Type, id2, value] of entries) {
|
|
2457
|
+
const ids = map?.get(Type);
|
|
2458
|
+
if (ids?.get(id2) === value) ids.delete(id2);
|
|
2442
2459
|
}
|
|
2460
|
+
node = node.parent;
|
|
2443
2461
|
}
|
|
2444
2462
|
}
|
|
2445
2463
|
const listenerMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -2495,19 +2513,28 @@ class ObservableListener {
|
|
|
2495
2513
|
notify(ev) {
|
|
2496
2514
|
if (!this.listeners) return;
|
|
2497
2515
|
this.notifying = true;
|
|
2498
|
-
|
|
2499
|
-
this.listeners
|
|
2516
|
+
try {
|
|
2517
|
+
for (let i = 0; i < this.listeners.length; i++) {
|
|
2518
|
+
this.listeners[i](ev);
|
|
2519
|
+
}
|
|
2520
|
+
} finally {
|
|
2521
|
+
this.notifying = false;
|
|
2500
2522
|
}
|
|
2501
|
-
this.notifying = false;
|
|
2502
2523
|
}
|
|
2503
2524
|
}
|
|
2504
2525
|
class ChildModelsAdministration extends ArrayAdministration {
|
|
2505
2526
|
set(index, newValue) {
|
|
2506
2527
|
return signalsCore.batch(() => {
|
|
2528
|
+
const oldValue = this.source[index];
|
|
2507
2529
|
const result = super.set(index, newValue);
|
|
2508
2530
|
const sourceValue = getSource(newValue);
|
|
2509
|
-
if (
|
|
2510
|
-
|
|
2531
|
+
if (oldValue !== sourceValue) {
|
|
2532
|
+
try {
|
|
2533
|
+
notifyArrayUpdate(this.proxy, index, oldValue, sourceValue);
|
|
2534
|
+
} catch (error) {
|
|
2535
|
+
super.set(index, oldValue);
|
|
2536
|
+
throw error;
|
|
2537
|
+
}
|
|
2511
2538
|
}
|
|
2512
2539
|
return result;
|
|
2513
2540
|
});
|
|
@@ -2516,7 +2543,12 @@ class ChildModelsAdministration extends ArrayAdministration {
|
|
|
2516
2543
|
return signalsCore.batch(() => {
|
|
2517
2544
|
const deleted = super.spliceWithArray(index, deleteCount, newItems);
|
|
2518
2545
|
if (deleteCount || newItems?.length) {
|
|
2519
|
-
|
|
2546
|
+
try {
|
|
2547
|
+
notifySpliceArray(this.proxy, index, newItems ?? [], deleted);
|
|
2548
|
+
} catch (error) {
|
|
2549
|
+
super.spliceWithArray(index, newItems?.length ?? 0, deleted);
|
|
2550
|
+
throw error;
|
|
2551
|
+
}
|
|
2520
2552
|
}
|
|
2521
2553
|
return deleted;
|
|
2522
2554
|
});
|
|
@@ -2595,6 +2627,9 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2595
2627
|
{
|
|
2596
2628
|
get(target, prop, proxy) {
|
|
2597
2629
|
const adm = getAdministration(target);
|
|
2630
|
+
if (prop === Symbol.dispose) {
|
|
2631
|
+
return Reflect.get(target, prop, proxy);
|
|
2632
|
+
}
|
|
2598
2633
|
if (prop === "parent") {
|
|
2599
2634
|
return target.parent;
|
|
2600
2635
|
}
|
|
@@ -2613,6 +2648,7 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2613
2648
|
},
|
|
2614
2649
|
set(target, name, value) {
|
|
2615
2650
|
const adm = getAdministration(target);
|
|
2651
|
+
adm.assertUsable();
|
|
2616
2652
|
adm.writeInProgress.add(name);
|
|
2617
2653
|
try {
|
|
2618
2654
|
switch (adm.getCfgType(name)) {
|
|
@@ -2675,6 +2711,8 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2675
2711
|
computedSnapshot;
|
|
2676
2712
|
snapshotMap = /* @__PURE__ */ new Map();
|
|
2677
2713
|
contextCache = /* @__PURE__ */ new Map();
|
|
2714
|
+
ownedDisposers = /* @__PURE__ */ new Set();
|
|
2715
|
+
disposed = false;
|
|
2678
2716
|
parentName = null;
|
|
2679
2717
|
get parent() {
|
|
2680
2718
|
this.parentAtom.reportObserved();
|
|
@@ -2689,6 +2727,29 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2689
2727
|
setConfiguration(configurationGetter) {
|
|
2690
2728
|
this.configurationGetter = configurationGetter;
|
|
2691
2729
|
}
|
|
2730
|
+
assertUsable() {
|
|
2731
|
+
if (this.disposed) {
|
|
2732
|
+
throw new Error("r-state-tree: cannot use a disposed model");
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
own(disposer) {
|
|
2736
|
+
this.assertUsable();
|
|
2737
|
+
let active = true;
|
|
2738
|
+
const wrapped = () => {
|
|
2739
|
+
if (!active) return;
|
|
2740
|
+
active = false;
|
|
2741
|
+
this.ownedDisposers.delete(wrapped);
|
|
2742
|
+
disposer();
|
|
2743
|
+
};
|
|
2744
|
+
this.ownedDisposers.add(wrapped);
|
|
2745
|
+
return wrapped;
|
|
2746
|
+
}
|
|
2747
|
+
reaction(track, callback) {
|
|
2748
|
+
return this.own(reaction(track, callback));
|
|
2749
|
+
}
|
|
2750
|
+
effect(callback) {
|
|
2751
|
+
return this.own(signalsCore.effect(callback));
|
|
2752
|
+
}
|
|
2692
2753
|
get configuration() {
|
|
2693
2754
|
return this.configurationGetter?.() ?? {};
|
|
2694
2755
|
}
|
|
@@ -2758,8 +2819,8 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2758
2819
|
);
|
|
2759
2820
|
}
|
|
2760
2821
|
if (v !== void 0) {
|
|
2761
|
-
this.source[name] = v;
|
|
2762
2822
|
setIdentifier(this.proxy, v);
|
|
2823
|
+
this.source[name] = v;
|
|
2763
2824
|
}
|
|
2764
2825
|
}
|
|
2765
2826
|
setModel(name, newModel) {
|
|
@@ -2814,11 +2875,30 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2814
2875
|
name,
|
|
2815
2876
|
observe(this.proxy[name], (event) => {
|
|
2816
2877
|
if (event.type === "updateArray") {
|
|
2817
|
-
getModelAdm(event.oldValue)
|
|
2818
|
-
getModelAdm(event.newValue)
|
|
2878
|
+
const oldAdm = getModelAdm(event.oldValue);
|
|
2879
|
+
const newAdm = getModelAdm(event.newValue);
|
|
2880
|
+
oldAdm.detach();
|
|
2881
|
+
try {
|
|
2882
|
+
newAdm.attach(this, name);
|
|
2883
|
+
} catch (error) {
|
|
2884
|
+
oldAdm.attach(this, name);
|
|
2885
|
+
throw error;
|
|
2886
|
+
}
|
|
2819
2887
|
} else if (event.type === "spliceArray") {
|
|
2888
|
+
const attached = [];
|
|
2820
2889
|
event.removed.forEach((model2) => getModelAdm(model2).detach());
|
|
2821
|
-
|
|
2890
|
+
try {
|
|
2891
|
+
event.added.forEach((model2) => {
|
|
2892
|
+
getModelAdm(model2).attach(this, name);
|
|
2893
|
+
attached.push(model2);
|
|
2894
|
+
});
|
|
2895
|
+
} catch (error) {
|
|
2896
|
+
attached.forEach((model2) => getModelAdm(model2).detach());
|
|
2897
|
+
event.removed.forEach(
|
|
2898
|
+
(model2) => getModelAdm(model2).attach(this, name)
|
|
2899
|
+
);
|
|
2900
|
+
throw error;
|
|
2901
|
+
}
|
|
2822
2902
|
}
|
|
2823
2903
|
})
|
|
2824
2904
|
);
|
|
@@ -2833,7 +2913,9 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2833
2913
|
getModelRef(name) {
|
|
2834
2914
|
const a = this.getReferencedAtom(name);
|
|
2835
2915
|
a.reportObserved();
|
|
2836
|
-
|
|
2916
|
+
const Type = this.getRequiredModelRefType(name);
|
|
2917
|
+
const root = this.getReactiveRoot().proxy;
|
|
2918
|
+
return this.source[name] != null ? getModelById(root, Type, this.source[name]) : void 0;
|
|
2837
2919
|
}
|
|
2838
2920
|
getModelRefs(name) {
|
|
2839
2921
|
const a = this.getReferencedAtom(name);
|
|
@@ -2842,7 +2924,9 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2842
2924
|
if (!this.referencedModels) this.referencedModels = /* @__PURE__ */ new Map();
|
|
2843
2925
|
c = createComputed(() => {
|
|
2844
2926
|
a.reportObserved();
|
|
2845
|
-
const
|
|
2927
|
+
const Type = this.getRequiredModelRefType(name);
|
|
2928
|
+
const root = this.getReactiveRoot().proxy;
|
|
2929
|
+
const models = (this.source[name] || []).map((id2) => getModelById(root, Type, id2)).filter((m) => !!m);
|
|
2846
2930
|
return models;
|
|
2847
2931
|
});
|
|
2848
2932
|
this.referencedModels.set(name, c);
|
|
@@ -2852,6 +2936,7 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2852
2936
|
setModelRef(name, modelValue) {
|
|
2853
2937
|
let id2 = void 0;
|
|
2854
2938
|
if (modelValue) {
|
|
2939
|
+
this.assertModelRefType(name, modelValue);
|
|
2855
2940
|
id2 = getIdentifier(modelValue);
|
|
2856
2941
|
if (id2 == null) {
|
|
2857
2942
|
throw new Error(
|
|
@@ -2864,6 +2949,7 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2864
2949
|
}
|
|
2865
2950
|
setModelRefs(name, modelValue) {
|
|
2866
2951
|
const ids = modelValue.map((model2) => {
|
|
2952
|
+
this.assertModelRefType(name, model2);
|
|
2867
2953
|
const id2 = getIdentifier(model2);
|
|
2868
2954
|
if (id2 == null) {
|
|
2869
2955
|
throw new Error(
|
|
@@ -2875,31 +2961,87 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2875
2961
|
this.source[name] = ids;
|
|
2876
2962
|
this.referencedAtoms?.get(name)?.reportChanged();
|
|
2877
2963
|
}
|
|
2964
|
+
getRequiredModelRefType(name) {
|
|
2965
|
+
const Type = this.getCfgChildType(name);
|
|
2966
|
+
if (!Type) {
|
|
2967
|
+
throw new Error(
|
|
2968
|
+
`r-state-tree: modelRef '${String(name)}' requires a model constructor`
|
|
2969
|
+
);
|
|
2970
|
+
}
|
|
2971
|
+
return Type;
|
|
2972
|
+
}
|
|
2973
|
+
assertModelRefType(name, model2) {
|
|
2974
|
+
const Type = this.getRequiredModelRefType(name);
|
|
2975
|
+
if (!(model2 instanceof Type)) {
|
|
2976
|
+
throw new Error(
|
|
2977
|
+
`r-state-tree: modelRef '${String(name)}' must reference ${Type.name}`
|
|
2978
|
+
);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2878
2981
|
attach(parent = null, parentName = null) {
|
|
2982
|
+
this.assertUsable();
|
|
2879
2983
|
if (this.parent) {
|
|
2880
2984
|
throw new Error(
|
|
2881
2985
|
"r-state-tree: child model already attached to a parent. Did you mean to use modelRef?"
|
|
2882
2986
|
);
|
|
2883
2987
|
}
|
|
2884
|
-
if (parent) {
|
|
2885
|
-
this.parent = parent;
|
|
2886
|
-
this.root = parent.root;
|
|
2887
|
-
this.parentName = parentName;
|
|
2888
|
-
}
|
|
2889
2988
|
signalsCore.batch(() => {
|
|
2890
|
-
|
|
2891
|
-
|
|
2989
|
+
if (parent) {
|
|
2990
|
+
this.parent = parent;
|
|
2991
|
+
this.root = parent.root;
|
|
2992
|
+
this.parentName = parentName;
|
|
2993
|
+
}
|
|
2994
|
+
try {
|
|
2995
|
+
onModelAttached(this.proxy);
|
|
2996
|
+
} catch (error) {
|
|
2997
|
+
this.parent = null;
|
|
2998
|
+
this.root = this;
|
|
2999
|
+
this.parentName = null;
|
|
3000
|
+
throw error;
|
|
3001
|
+
}
|
|
2892
3002
|
});
|
|
2893
3003
|
}
|
|
3004
|
+
getReactiveRoot() {
|
|
3005
|
+
const parent = this.parent;
|
|
3006
|
+
return parent ? parent.getReactiveRoot() : this;
|
|
3007
|
+
}
|
|
2894
3008
|
detach() {
|
|
2895
3009
|
signalsCore.batch(() => {
|
|
2896
|
-
this.proxy.modelWillDetach();
|
|
2897
3010
|
onModelDetached(this.proxy);
|
|
3011
|
+
this.contextCache.forEach((computed2) => computed2.clear());
|
|
3012
|
+
this.contextCache.clear();
|
|
3013
|
+
this.parent = null;
|
|
3014
|
+
this.parentName = null;
|
|
3015
|
+
this.root = this;
|
|
3016
|
+
});
|
|
3017
|
+
}
|
|
3018
|
+
dispose(internal = false) {
|
|
3019
|
+
if (this.disposed) return;
|
|
3020
|
+
if (!internal && this.parent) {
|
|
3021
|
+
throw new Error(
|
|
3022
|
+
"r-state-tree: cannot directly dispose an attached child model"
|
|
3023
|
+
);
|
|
3024
|
+
}
|
|
3025
|
+
signalsCore.batch(() => {
|
|
3026
|
+
this.activeModels.forEach((name) => {
|
|
3027
|
+
const child2 = this.proxy[name];
|
|
3028
|
+
if (Array.isArray(child2)) {
|
|
3029
|
+
child2.forEach((model2) => getModelAdm(model2).dispose(true));
|
|
3030
|
+
} else if (child2) {
|
|
3031
|
+
getModelAdm(child2).dispose(true);
|
|
3032
|
+
}
|
|
3033
|
+
});
|
|
3034
|
+
if (this.parent) onModelDetached(this.proxy);
|
|
3035
|
+
this.parent = null;
|
|
3036
|
+
this.parentName = null;
|
|
3037
|
+
this.root = this;
|
|
2898
3038
|
});
|
|
3039
|
+
this.disposed = true;
|
|
3040
|
+
this.modelsTraceUnsub.forEach((dispose) => dispose());
|
|
3041
|
+
this.modelsTraceUnsub.clear();
|
|
2899
3042
|
this.contextCache.forEach((computed2) => computed2.clear());
|
|
2900
3043
|
this.contextCache.clear();
|
|
2901
|
-
this.
|
|
2902
|
-
this.root = this;
|
|
3044
|
+
Array.from(this.ownedDisposers).forEach((dispose) => dispose());
|
|
2903
3045
|
}
|
|
2904
3046
|
getContextValue(contextId, provideSymbol, defaultValue, hasDefault) {
|
|
2905
3047
|
let computed2 = this.contextCache.get(contextId);
|
|
@@ -3002,85 +3144,94 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
3002
3144
|
}
|
|
3003
3145
|
return true;
|
|
3004
3146
|
};
|
|
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) {
|
|
3147
|
+
signalsCore.untracked(() => {
|
|
3148
|
+
signalsCore.batch(() => {
|
|
3149
|
+
Object.keys(snapshot).forEach((key) => {
|
|
3150
|
+
const type = this.getCfgType(key);
|
|
3151
|
+
const childType2 = this.getCfgChildType(key);
|
|
3152
|
+
const value = snapshot[key];
|
|
3153
|
+
switch (type) {
|
|
3154
|
+
case ModelCfgTypes.state:
|
|
3155
|
+
this.proxy[key] = this.hydrateStateValue(this.proxy[key], value);
|
|
3156
|
+
break;
|
|
3157
|
+
case ModelCfgTypes.modelRef:
|
|
3158
|
+
if (Array.isArray(value)) {
|
|
3159
|
+
if (value?.[0] instanceof Model) {
|
|
3028
3160
|
this.proxy[key] = value;
|
|
3029
3161
|
} else {
|
|
3030
|
-
this.source[key] =
|
|
3162
|
+
this.source[key] = value.map(
|
|
3163
|
+
(snapshot2) => getSnapshotRefId(snapshot2)
|
|
3164
|
+
);
|
|
3031
3165
|
this.referencedAtoms?.get(key)?.reportChanged();
|
|
3032
3166
|
}
|
|
3033
3167
|
break;
|
|
3034
|
-
|
|
3035
|
-
this.
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3168
|
+
} else if (value instanceof Model) {
|
|
3169
|
+
this.proxy[key] = value;
|
|
3170
|
+
} else {
|
|
3171
|
+
this.source[key] = getSnapshotRefId(value);
|
|
3172
|
+
this.referencedAtoms?.get(key)?.reportChanged();
|
|
3173
|
+
}
|
|
3174
|
+
break;
|
|
3175
|
+
case ModelCfgTypes.id:
|
|
3176
|
+
this.setId(key, value);
|
|
3177
|
+
break;
|
|
3178
|
+
case CommonCfgTypes.child:
|
|
3179
|
+
let model2;
|
|
3180
|
+
if (Array.isArray(value)) {
|
|
3181
|
+
const Ctor = childType2;
|
|
3182
|
+
const snapshotIds = /* @__PURE__ */ new Set();
|
|
3183
|
+
for (const childSnapshot of value) {
|
|
3184
|
+
if (childSnapshot instanceof Model) continue;
|
|
3185
|
+
const snapshotId = childType2 ? getSnapshotId(childSnapshot ?? {}, Ctor) : null;
|
|
3186
|
+
if (snapshotId != null && snapshotIds.has(snapshotId)) {
|
|
3187
|
+
throw new Error(
|
|
3188
|
+
"r-state-tree duplicate ids detected after snapshot was loaded"
|
|
3189
|
+
);
|
|
3190
|
+
}
|
|
3191
|
+
if (snapshotId != null) snapshotIds.add(snapshotId);
|
|
3192
|
+
}
|
|
3193
|
+
this.proxy[key] = value?.map(
|
|
3194
|
+
(snapshot2, index) => {
|
|
3195
|
+
snapshot2 = snapshot2 ?? {};
|
|
3196
|
+
let model22;
|
|
3197
|
+
if (snapshot2 instanceof Model) {
|
|
3198
|
+
model22 = snapshot2;
|
|
3199
|
+
} else {
|
|
3200
|
+
ensureChildTypes(key);
|
|
3201
|
+
const id2 = childType2 && getSnapshotId(snapshot2, Ctor);
|
|
3202
|
+
const foundModel = id2 != null ? getModelById(this.root.proxy, Ctor, id2) : this.proxy[key][index];
|
|
3203
|
+
const adm = foundModel && getModelAdm(foundModel);
|
|
3204
|
+
if (adm && foundModel.parent === this.proxy && adm?.parentName === key) {
|
|
3205
|
+
adm.loadSnapshot(snapshot2);
|
|
3206
|
+
model22 = foundModel;
|
|
3047
3207
|
} 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
|
-
}
|
|
3208
|
+
model22 = Ctor.create(snapshot2);
|
|
3058
3209
|
}
|
|
3059
|
-
return model22;
|
|
3060
3210
|
}
|
|
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);
|
|
3211
|
+
return model22;
|
|
3074
3212
|
}
|
|
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
3213
|
);
|
|
3082
|
-
|
|
3083
|
-
|
|
3214
|
+
break;
|
|
3215
|
+
} else if (value instanceof Model) {
|
|
3216
|
+
model2 = value;
|
|
3217
|
+
} else {
|
|
3218
|
+
ensureChildTypes(key);
|
|
3219
|
+
const id2 = childType2 && getSnapshotId(value, childType2);
|
|
3220
|
+
if (id2 != null && this.proxy[key] && this.proxy[key] instanceof childType2 && id2 === getIdentifier(this.proxy[key])) {
|
|
3221
|
+
const adm = getModelAdm(this.proxy[key]);
|
|
3222
|
+
adm.loadSnapshot(value);
|
|
3223
|
+
model2 = this.proxy[key];
|
|
3224
|
+
} else {
|
|
3225
|
+
model2 = childType2.create(value);
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
this.proxy[key] = model2;
|
|
3229
|
+
break;
|
|
3230
|
+
default:
|
|
3231
|
+
console.warn(
|
|
3232
|
+
`r-state-tree: invalid key '${key}' found in snapshot, ignored.`
|
|
3233
|
+
);
|
|
3234
|
+
}
|
|
3084
3235
|
});
|
|
3085
3236
|
});
|
|
3086
3237
|
});
|
|
@@ -3095,11 +3246,14 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
3095
3246
|
}
|
|
3096
3247
|
return this.computedSnapshot.get();
|
|
3097
3248
|
}
|
|
3249
|
+
getSnapshotForRollback() {
|
|
3250
|
+
return this.toJSON();
|
|
3251
|
+
}
|
|
3098
3252
|
}
|
|
3099
3253
|
let initEnabled = false;
|
|
3100
3254
|
class Model {
|
|
3101
3255
|
static childTypes = {};
|
|
3102
|
-
static create(snapshot
|
|
3256
|
+
static create(snapshot) {
|
|
3103
3257
|
let instance;
|
|
3104
3258
|
try {
|
|
3105
3259
|
initEnabled = true;
|
|
@@ -3108,8 +3262,12 @@ class Model {
|
|
|
3108
3262
|
initEnabled = false;
|
|
3109
3263
|
}
|
|
3110
3264
|
const adm = getModelAdm(instance);
|
|
3111
|
-
|
|
3112
|
-
|
|
3265
|
+
try {
|
|
3266
|
+
snapshot && adm.loadSnapshot(snapshot);
|
|
3267
|
+
} catch (error) {
|
|
3268
|
+
adm.dispose(true);
|
|
3269
|
+
throw error;
|
|
3270
|
+
}
|
|
3113
3271
|
return instance;
|
|
3114
3272
|
}
|
|
3115
3273
|
constructor() {
|
|
@@ -3133,31 +3291,33 @@ class Model {
|
|
|
3133
3291
|
get parent() {
|
|
3134
3292
|
return getModelAdm(this).parent?.proxy ?? null;
|
|
3135
3293
|
}
|
|
3136
|
-
|
|
3137
|
-
|
|
3294
|
+
reaction(track, callback) {
|
|
3295
|
+
return getModelAdm(this).reaction(track, callback);
|
|
3138
3296
|
}
|
|
3139
|
-
|
|
3140
|
-
|
|
3297
|
+
effect(callback) {
|
|
3298
|
+
return getModelAdm(this).effect(callback);
|
|
3141
3299
|
}
|
|
3142
|
-
|
|
3143
|
-
|
|
3300
|
+
[Symbol.dispose]() {
|
|
3301
|
+
getModelAdm(this).dispose();
|
|
3144
3302
|
}
|
|
3145
3303
|
}
|
|
3304
|
+
function findModelById(root, ModelType, id2) {
|
|
3305
|
+
return getModelById(getModelAdm(root).root.proxy, ModelType, id2);
|
|
3306
|
+
}
|
|
3146
3307
|
function mount(container) {
|
|
3147
3308
|
return allowNewStore(() => {
|
|
3148
3309
|
const element = container;
|
|
3149
3310
|
const s = new element.Type(element.props);
|
|
3150
|
-
getStoreAdm(s)
|
|
3311
|
+
const adm = getStoreAdm(s);
|
|
3312
|
+
try {
|
|
3313
|
+
adm.mount();
|
|
3314
|
+
} catch (error) {
|
|
3315
|
+
adm.dispose(true);
|
|
3316
|
+
throw error;
|
|
3317
|
+
}
|
|
3151
3318
|
return s;
|
|
3152
3319
|
});
|
|
3153
3320
|
}
|
|
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
3321
|
function toSnapshot(model2) {
|
|
3162
3322
|
return getModelAdm(model2).getSnapshot();
|
|
3163
3323
|
}
|
|
@@ -3177,7 +3337,13 @@ function onSnapshotDiff(model2, callback) {
|
|
|
3177
3337
|
}
|
|
3178
3338
|
function applySnapshot(model2, snapshot) {
|
|
3179
3339
|
const adm = getModelAdm(model2);
|
|
3180
|
-
adm.
|
|
3340
|
+
const previousSnapshot = adm.getSnapshotForRollback();
|
|
3341
|
+
try {
|
|
3342
|
+
adm.loadSnapshot(snapshot);
|
|
3343
|
+
} catch (error) {
|
|
3344
|
+
adm.loadSnapshot(previousSnapshot);
|
|
3345
|
+
throw error;
|
|
3346
|
+
}
|
|
3181
3347
|
return model2;
|
|
3182
3348
|
}
|
|
3183
3349
|
const CONTEXT_SYMBOL = Symbol("context");
|
|
@@ -3296,6 +3462,7 @@ exports.child = child;
|
|
|
3296
3462
|
exports.computed = computed;
|
|
3297
3463
|
exports.createContext = createContext;
|
|
3298
3464
|
exports.createStore = createStore;
|
|
3465
|
+
exports.findModelById = findModelById;
|
|
3299
3466
|
exports.getSignal = getSignal;
|
|
3300
3467
|
exports.id = id;
|
|
3301
3468
|
exports.isObservable = isObservable;
|
|
@@ -3313,5 +3480,4 @@ exports.source = source;
|
|
|
3313
3480
|
exports.state = state;
|
|
3314
3481
|
exports.toObservableTree = toObservableTree;
|
|
3315
3482
|
exports.toSnapshot = toSnapshot;
|
|
3316
|
-
exports.unmount = unmount;
|
|
3317
3483
|
exports.updateStore = updateStore;
|