valdres 0.2.0-alpha.47 → 0.2.0-alpha.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +65 -23
- package/dist/types/src/lib/getState.d.ts +3 -3
- package/dist/types/src/lib/initSelector.d.ts +1 -2
- package/dist/types/src/lib/transaction.d.ts +1 -1
- package/dist/types/src/types/TransactionFn.d.ts +1 -1
- package/dist/types/src/types/TransactionInterface.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -194,22 +194,22 @@ var initAtom = (atom, data) => {
|
|
|
194
194
|
};
|
|
195
195
|
|
|
196
196
|
// src/lib/getState.ts
|
|
197
|
-
function getState(state, data) {
|
|
197
|
+
function getState(state, data, circularDependencySet) {
|
|
198
198
|
if (data.values.has(state))
|
|
199
199
|
return data.values.get(state);
|
|
200
200
|
if (isAtom(state)) {
|
|
201
201
|
if ("parent" in data)
|
|
202
|
-
return getState(state, data.parent);
|
|
202
|
+
return getState(state, data.parent, circularDependencySet);
|
|
203
203
|
return initAtom(state, data);
|
|
204
204
|
}
|
|
205
205
|
if (isSelector(state))
|
|
206
|
-
return initSelector(state, data);
|
|
206
|
+
return initSelector(state, data, circularDependencySet);
|
|
207
207
|
if (isAtomFamily(state)) {
|
|
208
208
|
if ("parent" in data) {
|
|
209
209
|
const closestData = findClosestStoreWithAtomInitialized(state.__keysAtom, data);
|
|
210
|
-
return getState(state.__keysSelector, closestData);
|
|
210
|
+
return getState(state.__keysSelector, closestData, circularDependencySet);
|
|
211
211
|
}
|
|
212
|
-
return getState(state.__keysSelector, data);
|
|
212
|
+
return getState(state.__keysSelector, data, circularDependencySet);
|
|
213
213
|
}
|
|
214
214
|
if (isSelectorFamily(state)) {
|
|
215
215
|
const array = Array.from(state.__valdresSelectorFamilyMap.keys());
|
|
@@ -236,6 +236,36 @@ class SuspendAndWaitForResolveError extends Error {
|
|
|
236
236
|
this.promise = promise;
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
|
+
var generateSelectorTrace = (selectors) => {
|
|
240
|
+
const lastIndex = selectors.length - 1;
|
|
241
|
+
return selectors.map((selector, index) => {
|
|
242
|
+
const name = selector.name ?? "Anonymous Selector";
|
|
243
|
+
if (index === 0) {
|
|
244
|
+
return `[START] ${name}`;
|
|
245
|
+
} else if (index === lastIndex) {
|
|
246
|
+
return `[CRASH] ${name}`;
|
|
247
|
+
} else {
|
|
248
|
+
return ` ${" ".repeat(index)}${name}`;
|
|
249
|
+
}
|
|
250
|
+
}).join(`
|
|
251
|
+
`);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
class CircularDependencyError extends Error {
|
|
255
|
+
selectors;
|
|
256
|
+
constructor() {
|
|
257
|
+
super();
|
|
258
|
+
this.selectors = [];
|
|
259
|
+
}
|
|
260
|
+
track(selector) {
|
|
261
|
+
this.selectors.push(selector);
|
|
262
|
+
}
|
|
263
|
+
get message() {
|
|
264
|
+
const firstSelectorName = this.selectors[0].name ?? "Anonymous Selector";
|
|
265
|
+
return `Circular dependency detected in '${firstSelectorName}'
|
|
266
|
+
${generateSelectorTrace(this.selectors)}`;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
239
269
|
var getOrInitConsumersSet = (state, data) => {
|
|
240
270
|
const set = data.stateConsumers.get(state);
|
|
241
271
|
if (set)
|
|
@@ -244,12 +274,16 @@ var getOrInitConsumersSet = (state, data) => {
|
|
|
244
274
|
data.stateConsumers.set(state, newSet);
|
|
245
275
|
return newSet;
|
|
246
276
|
};
|
|
247
|
-
var evaluateSelector = (selector, data) => {
|
|
277
|
+
var evaluateSelector = (selector, data, circularDependencyMap = new WeakSet) => {
|
|
248
278
|
const updatedDependencies = new Set;
|
|
279
|
+
if (circularDependencyMap.has(selector)) {
|
|
280
|
+
throw new CircularDependencyError;
|
|
281
|
+
}
|
|
282
|
+
circularDependencyMap.add(selector);
|
|
249
283
|
let result;
|
|
250
284
|
try {
|
|
251
285
|
result = selector.get((state) => {
|
|
252
|
-
const value = getState(state, data);
|
|
286
|
+
const value = getState(state, data, circularDependencyMap);
|
|
253
287
|
updatedDependencies.add(state);
|
|
254
288
|
if (isPromiseLike(value))
|
|
255
289
|
throw new SuspendAndWaitForResolveError(value);
|
|
@@ -291,8 +325,15 @@ var handleSelectorResult = (value, selector, data) => {
|
|
|
291
325
|
return value;
|
|
292
326
|
}
|
|
293
327
|
};
|
|
294
|
-
var initSelector = (selector, data) => {
|
|
295
|
-
|
|
328
|
+
var initSelector = (selector, data, circularDependencySet = new WeakSet) => {
|
|
329
|
+
let tmpValue;
|
|
330
|
+
try {
|
|
331
|
+
tmpValue = evaluateSelector(selector, data, circularDependencySet);
|
|
332
|
+
} catch (e) {
|
|
333
|
+
if (e instanceof CircularDependencyError)
|
|
334
|
+
e.track(selector);
|
|
335
|
+
throw e;
|
|
336
|
+
}
|
|
296
337
|
const value = handleSelectorResult(tmpValue, selector, data);
|
|
297
338
|
if (data.expiredValues.has(selector)) {
|
|
298
339
|
const expiredValue = data.expiredValues.get(selector);
|
|
@@ -566,6 +607,13 @@ var recursivlyResetTxnSelectorCache = (state, txnSubscribers, txnSelectorCache)
|
|
|
566
607
|
}
|
|
567
608
|
}
|
|
568
609
|
};
|
|
610
|
+
var captureScopedTransaction = (scopedData) => {
|
|
611
|
+
let txn;
|
|
612
|
+
transaction((scopedTxn) => {
|
|
613
|
+
txn = scopedTxn;
|
|
614
|
+
}, scopedData, false);
|
|
615
|
+
return txn;
|
|
616
|
+
};
|
|
569
617
|
var transaction = (callback, data, autoCommit = true) => {
|
|
570
618
|
let txnAtomMap = new Map;
|
|
571
619
|
let txnSelectorCache = new Map;
|
|
@@ -624,7 +672,7 @@ var transaction = (callback, data, autoCommit = true) => {
|
|
|
624
672
|
dirtySelectors.clear();
|
|
625
673
|
if (scopedTransactions) {
|
|
626
674
|
for (const scopedTxn of Object.values(scopedTransactions)) {
|
|
627
|
-
scopedTxn
|
|
675
|
+
scopedTxn.commit();
|
|
628
676
|
}
|
|
629
677
|
}
|
|
630
678
|
};
|
|
@@ -636,19 +684,13 @@ var transaction = (callback, data, autoCommit = true) => {
|
|
|
636
684
|
scope: (scopeId, callback2) => {
|
|
637
685
|
if (scopeId in data.scopes) {
|
|
638
686
|
const scopedData = data.scopes[scopeId];
|
|
639
|
-
if (scopedTransactions
|
|
640
|
-
scopedTransactions
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
get,
|
|
645
|
-
reset,
|
|
646
|
-
commit2,
|
|
647
|
-
scope
|
|
648
|
-
];
|
|
649
|
-
}, scopedData, false);
|
|
687
|
+
if (scopedTransactions === undefined) {
|
|
688
|
+
scopedTransactions = {};
|
|
689
|
+
}
|
|
690
|
+
if (scopedTransactions[scopeId] === undefined) {
|
|
691
|
+
scopedTransactions[scopeId] = captureScopedTransaction(scopedData);
|
|
650
692
|
}
|
|
651
|
-
callback2(
|
|
693
|
+
return callback2(scopedTransactions[scopeId]);
|
|
652
694
|
} else {
|
|
653
695
|
throw new Error(`Scope '${scopeId}' not found. Registered scopes: ${Object.keys(data.scopes).join(", ")}`);
|
|
654
696
|
}
|
|
@@ -727,7 +769,7 @@ var store = (id) => {
|
|
|
727
769
|
return storeFromStoreData(data);
|
|
728
770
|
};
|
|
729
771
|
// package.json
|
|
730
|
-
var version = "0.2.0-alpha.
|
|
772
|
+
var version = "0.2.0-alpha.48";
|
|
731
773
|
|
|
732
774
|
// src/globalStore.ts
|
|
733
775
|
if (globalThis.__valdres__) {
|
|
@@ -2,6 +2,6 @@ import type { Atom } from "../types/Atom";
|
|
|
2
2
|
import type { AtomFamily } from "../types/AtomFamily";
|
|
3
3
|
import type { Selector } from "../types/Selector";
|
|
4
4
|
import type { StoreData } from "../types/StoreData";
|
|
5
|
-
export declare function getState<V, K>(atom: Atom<V>, data: StoreData): V;
|
|
6
|
-
export declare function getState<V, K>(selector: Selector<V>, data: StoreData): V;
|
|
7
|
-
export declare function getState<V, K>(family: AtomFamily<V, K>, data: StoreData): K[];
|
|
5
|
+
export declare function getState<V, K>(atom: Atom<V>, data: StoreData, circularDependencySet?: WeakSet<Selector>): V;
|
|
6
|
+
export declare function getState<V, K>(selector: Selector<V>, data: StoreData, circularDependencySet?: WeakSet<Selector>): V;
|
|
7
|
+
export declare function getState<V, K>(family: AtomFamily<V, K>, data: StoreData, circularDependencySet?: WeakSet<Selector>): K[];
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import type { StoreData } from "../types/StoreData";
|
|
2
2
|
import type { Selector } from "../types/Selector";
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const initSelector: <V>(selector: Selector<V>, data: StoreData) => V | Promise<V>;
|
|
3
|
+
export declare const initSelector: <V>(selector: Selector<V>, data: StoreData, circularDependencySet?: WeakSet<WeakKey>) => V | Promise<V>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { StoreData } from "../types/StoreData";
|
|
2
2
|
import type { TransactionFn } from "../types/TransactionFn";
|
|
3
|
-
export declare const transaction: (callback: TransactionFn, data: StoreData, autoCommit?: boolean) =>
|
|
3
|
+
export declare const transaction: (callback: TransactionFn, data: StoreData, autoCommit?: boolean) => any;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { TransactionInterface } from "./TransactionInterface";
|
|
2
|
-
export type TransactionFn = (args: TransactionInterface) =>
|
|
2
|
+
export type TransactionFn = (args: TransactionInterface) => any;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valdres",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.49",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Eigil Sagafos"
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"access": "public",
|
|
37
37
|
"registry": "https://registry.npmjs.org/"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "1aa6c47faaaf0158c7ff7ed18e3b20648c183e24"
|
|
40
40
|
}
|