storion 0.5.0 → 0.7.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 +318 -25
- package/dist/async/async.d.ts +49 -0
- package/dist/async/async.d.ts.map +1 -1
- package/dist/async/index.js +50 -0
- package/dist/collection.d.ts +13 -21
- package/dist/collection.d.ts.map +1 -1
- package/dist/core/container.d.ts.map +1 -1
- package/dist/core/createResolver.d.ts.map +1 -1
- package/dist/core/disposable.d.ts +18 -0
- package/dist/core/disposable.d.ts.map +1 -0
- package/dist/core/effect.d.ts +20 -0
- package/dist/core/effect.d.ts.map +1 -1
- package/dist/core/storeContext.d.ts.map +1 -1
- package/dist/devtools/index.js +2 -1
- package/dist/effect-DPAYSuW3.js +294 -0
- package/dist/emitter-BA44OHdL.js +228 -0
- package/dist/react/index.js +27 -20
- package/dist/react/useStore.d.ts.map +1 -1
- package/dist/{store-CwA4YTVb.js → store-BroaE7p4.js} +46 -241
- package/dist/storion.js +32 -304
- package/dist/test/util.d.ts +2 -0
- package/dist/test/util.d.ts.map +1 -0
- package/dist/types.d.ts +63 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { e as emitter, w as withHooks, h as hasReadHook, t as trackRead, a as hasWriteHook, c as trackWrite, s as scheduleNotification, b as batch } from "./emitter-BA44OHdL.js";
|
|
1
2
|
const STORION_TYPE = Symbol("STORION");
|
|
2
3
|
function is$1(value, kind) {
|
|
3
4
|
return value !== null && (typeof value === "object" || typeof value === "function") && STORION_TYPE in value && value[STORION_TYPE] === kind;
|
|
@@ -1729,6 +1730,28 @@ function resolveEquality(e) {
|
|
|
1729
1730
|
function equality(shorthand) {
|
|
1730
1731
|
return resolveEquality(shorthand);
|
|
1731
1732
|
}
|
|
1733
|
+
function tryDispose(value) {
|
|
1734
|
+
if (isDisposable(value)) {
|
|
1735
|
+
const dispose = value.dispose;
|
|
1736
|
+
if (Array.isArray(dispose)) {
|
|
1737
|
+
for (const item of dispose) {
|
|
1738
|
+
if (typeof item === "function") {
|
|
1739
|
+
item();
|
|
1740
|
+
} else {
|
|
1741
|
+
tryDispose(item);
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
} else if (typeof dispose === "function") {
|
|
1745
|
+
dispose();
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
function isDisposable(value) {
|
|
1750
|
+
return (typeof value === "object" || typeof value === "function") && !!value && "dispose" in value;
|
|
1751
|
+
}
|
|
1752
|
+
function willDispose(value) {
|
|
1753
|
+
return () => tryDispose(value);
|
|
1754
|
+
}
|
|
1732
1755
|
function getAtPath(obj, segments) {
|
|
1733
1756
|
let current2 = obj;
|
|
1734
1757
|
for (const key of segments) {
|
|
@@ -1864,18 +1887,16 @@ function createStoreContext(options) {
|
|
|
1864
1887
|
actions: instance.actions
|
|
1865
1888
|
});
|
|
1866
1889
|
},
|
|
1867
|
-
// Implementation handles
|
|
1868
|
-
create(specOrFactory) {
|
|
1890
|
+
// Implementation handles StoreSpec, Factory, and parameterized Factory overloads
|
|
1891
|
+
create(specOrFactory, ...args) {
|
|
1869
1892
|
if (!isSetupPhase()) {
|
|
1870
1893
|
throw new Error(
|
|
1871
1894
|
`create() can only be called during setup phase. Do not call create() inside actions or async callbacks. Declare all child stores at the top of your setup function.`
|
|
1872
1895
|
);
|
|
1873
1896
|
}
|
|
1874
1897
|
if (!isSpec(specOrFactory)) {
|
|
1875
|
-
const instance2 = specOrFactory(resolver);
|
|
1876
|
-
|
|
1877
|
-
onDispose == null ? void 0 : onDispose(instance2.dispose);
|
|
1878
|
-
}
|
|
1898
|
+
const instance2 = specOrFactory(resolver, ...args);
|
|
1899
|
+
onDispose == null ? void 0 : onDispose(willDispose(instance2));
|
|
1879
1900
|
return instance2;
|
|
1880
1901
|
}
|
|
1881
1902
|
const childSpec = specOrFactory;
|
|
@@ -1888,7 +1909,7 @@ function createStoreContext(options) {
|
|
|
1888
1909
|
);
|
|
1889
1910
|
}
|
|
1890
1911
|
const instance = resolver.create(childSpec);
|
|
1891
|
-
onDispose == null ? void 0 : onDispose(instance
|
|
1912
|
+
onDispose == null ? void 0 : onDispose(willDispose(instance));
|
|
1892
1913
|
return instance;
|
|
1893
1914
|
},
|
|
1894
1915
|
update: createUpdateFn(update),
|
|
@@ -1910,6 +1931,11 @@ function createStoreContext(options) {
|
|
|
1910
1931
|
return mixin(ctx, ...args);
|
|
1911
1932
|
},
|
|
1912
1933
|
focus(path, options2) {
|
|
1934
|
+
if (!isSetupPhase()) {
|
|
1935
|
+
throw new Error(
|
|
1936
|
+
`focus() can only be called during setup phase. Do not call focus() inside actions or async callbacks. Use the .to() method on an existing focus for dynamic sub-paths.`
|
|
1937
|
+
);
|
|
1938
|
+
}
|
|
1913
1939
|
const focusCtx = {
|
|
1914
1940
|
getState: getMutableState,
|
|
1915
1941
|
update: (updater) => {
|
|
@@ -1922,75 +1948,6 @@ function createStoreContext(options) {
|
|
|
1922
1948
|
};
|
|
1923
1949
|
return ctx;
|
|
1924
1950
|
}
|
|
1925
|
-
let globalHooks = {
|
|
1926
|
-
scheduleNotification(notify) {
|
|
1927
|
-
notify();
|
|
1928
|
-
},
|
|
1929
|
-
scheduleEffect(runEffect) {
|
|
1930
|
-
runEffect();
|
|
1931
|
-
}
|
|
1932
|
-
};
|
|
1933
|
-
function getHooks() {
|
|
1934
|
-
return globalHooks;
|
|
1935
|
-
}
|
|
1936
|
-
function hasReadHook() {
|
|
1937
|
-
return globalHooks.onRead !== void 0;
|
|
1938
|
-
}
|
|
1939
|
-
function hasWriteHook() {
|
|
1940
|
-
return globalHooks.onWrite !== void 0;
|
|
1941
|
-
}
|
|
1942
|
-
function withHooks(hooksOrSetup, fn, onFinish) {
|
|
1943
|
-
const prev = globalHooks;
|
|
1944
|
-
if (typeof hooksOrSetup === "function") {
|
|
1945
|
-
globalHooks = {
|
|
1946
|
-
...globalHooks,
|
|
1947
|
-
...hooksOrSetup(prev)
|
|
1948
|
-
};
|
|
1949
|
-
} else {
|
|
1950
|
-
globalHooks = { ...prev, ...hooksOrSetup };
|
|
1951
|
-
}
|
|
1952
|
-
try {
|
|
1953
|
-
return fn();
|
|
1954
|
-
} finally {
|
|
1955
|
-
globalHooks = prev;
|
|
1956
|
-
onFinish == null ? void 0 : onFinish();
|
|
1957
|
-
}
|
|
1958
|
-
}
|
|
1959
|
-
function trackRead(storeId, prop, value, subscribe) {
|
|
1960
|
-
var _a;
|
|
1961
|
-
const key = `${storeId}.${prop}`;
|
|
1962
|
-
(_a = globalHooks.onRead) == null ? void 0 : _a.call(globalHooks, { key, value, subscribe });
|
|
1963
|
-
}
|
|
1964
|
-
function trackWrite(storeId, prop, next, prev) {
|
|
1965
|
-
var _a;
|
|
1966
|
-
const key = `${storeId}.${prop}`;
|
|
1967
|
-
(_a = globalHooks.onWrite) == null ? void 0 : _a.call(globalHooks, { key, next, prev });
|
|
1968
|
-
}
|
|
1969
|
-
function untrack(fn) {
|
|
1970
|
-
return withHooks({ onRead: void 0, onWrite: void 0 }, fn);
|
|
1971
|
-
}
|
|
1972
|
-
function scheduleNotification(notify, key) {
|
|
1973
|
-
globalHooks.scheduleNotification(notify, key);
|
|
1974
|
-
}
|
|
1975
|
-
function batch(fn) {
|
|
1976
|
-
const pending = /* @__PURE__ */ new Map();
|
|
1977
|
-
return withHooks(
|
|
1978
|
-
(current2) => ({
|
|
1979
|
-
...current2,
|
|
1980
|
-
scheduleNotification: (notify, key) => {
|
|
1981
|
-
const actualKey = key ?? notify;
|
|
1982
|
-
pending.set(actualKey, notify);
|
|
1983
|
-
}
|
|
1984
|
-
}),
|
|
1985
|
-
fn,
|
|
1986
|
-
// Flush on finish
|
|
1987
|
-
() => {
|
|
1988
|
-
for (const notify of pending.values()) {
|
|
1989
|
-
notify();
|
|
1990
|
-
}
|
|
1991
|
-
}
|
|
1992
|
-
);
|
|
1993
|
-
}
|
|
1994
1951
|
let specIdCounter = 0;
|
|
1995
1952
|
function generateSpecName() {
|
|
1996
1953
|
return `spec-${++specIdCounter}`;
|
|
@@ -2012,153 +1969,6 @@ function unwrapFn(fn) {
|
|
|
2012
1969
|
function isWrappedFn(fn) {
|
|
2013
1970
|
return ORIGINAL_FN in fn;
|
|
2014
1971
|
}
|
|
2015
|
-
function emitter(initialListeners) {
|
|
2016
|
-
const listeners = /* @__PURE__ */ new Set([]);
|
|
2017
|
-
let settledPayload;
|
|
2018
|
-
let isSettled = false;
|
|
2019
|
-
const noop = () => {
|
|
2020
|
-
};
|
|
2021
|
-
const doEmit = (payload, clear, lifo = false) => {
|
|
2022
|
-
const copy = Array.from(listeners);
|
|
2023
|
-
if (clear) {
|
|
2024
|
-
listeners.clear();
|
|
2025
|
-
}
|
|
2026
|
-
const len = copy.length;
|
|
2027
|
-
if (lifo) {
|
|
2028
|
-
for (let i = len - 1; i >= 0; i--) {
|
|
2029
|
-
copy[i](payload);
|
|
2030
|
-
}
|
|
2031
|
-
} else {
|
|
2032
|
-
for (let i = 0; i < len; i++) {
|
|
2033
|
-
copy[i](payload);
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
|
-
};
|
|
2037
|
-
return {
|
|
2038
|
-
get size() {
|
|
2039
|
-
return listeners.size;
|
|
2040
|
-
},
|
|
2041
|
-
get settled() {
|
|
2042
|
-
return isSettled;
|
|
2043
|
-
},
|
|
2044
|
-
/**
|
|
2045
|
-
* Adds one or more listeners to the emitter.
|
|
2046
|
-
*
|
|
2047
|
-
* The listener(s) will be called whenever `emit()` is called.
|
|
2048
|
-
* Returns an unsubscribe function that removes the listener(s).
|
|
2049
|
-
*
|
|
2050
|
-
* **Important**: The unsubscribe function is idempotent - calling it multiple
|
|
2051
|
-
* times is safe and won't cause errors. If the same listener is added multiple
|
|
2052
|
-
* times, it will only be called once per emit (Set deduplication).
|
|
2053
|
-
*
|
|
2054
|
-
* **Settled behavior**: If the emitter is settled, listeners are called
|
|
2055
|
-
* immediately with the settled payload and a no-op unsubscribe is returned.
|
|
2056
|
-
*
|
|
2057
|
-
* @param newListeners - Single listener or array of listeners to add
|
|
2058
|
-
* @returns An unsubscribe function that removes the listener(s)
|
|
2059
|
-
*/
|
|
2060
|
-
on(...args) {
|
|
2061
|
-
let newListeners = [];
|
|
2062
|
-
if (args.length < 2) {
|
|
2063
|
-
newListeners = Array.isArray(args[0]) ? args[0] : [args[0]];
|
|
2064
|
-
} else {
|
|
2065
|
-
const map = args[0];
|
|
2066
|
-
const sourceListeners = Array.isArray(args[1]) ? args[1] : [args[1]];
|
|
2067
|
-
newListeners = [
|
|
2068
|
-
(value) => {
|
|
2069
|
-
const mappedValue = map(value);
|
|
2070
|
-
if (mappedValue) {
|
|
2071
|
-
for (const listener of sourceListeners) {
|
|
2072
|
-
listener(mappedValue.value);
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
];
|
|
2077
|
-
}
|
|
2078
|
-
if (isSettled) {
|
|
2079
|
-
for (const listener of newListeners) {
|
|
2080
|
-
listener(settledPayload);
|
|
2081
|
-
}
|
|
2082
|
-
return noop;
|
|
2083
|
-
}
|
|
2084
|
-
for (const listener of newListeners) {
|
|
2085
|
-
listeners.add(listener);
|
|
2086
|
-
}
|
|
2087
|
-
return () => {
|
|
2088
|
-
for (const listener of newListeners) {
|
|
2089
|
-
listeners.delete(listener);
|
|
2090
|
-
}
|
|
2091
|
-
};
|
|
2092
|
-
},
|
|
2093
|
-
/**
|
|
2094
|
-
* Emits an event to all registered listeners.
|
|
2095
|
-
*
|
|
2096
|
-
* **Important**: Creates a snapshot of listeners before iterating to ensure
|
|
2097
|
-
* that modifications during emission (adding/removing listeners) don't affect
|
|
2098
|
-
* the current emission cycle. This prevents:
|
|
2099
|
-
* - New listeners added during emission from being called immediately
|
|
2100
|
-
* - Issues with listeners that unsubscribe during emission
|
|
2101
|
-
*
|
|
2102
|
-
* Performance: For typical use cases (< 20 listeners), Array.from() overhead
|
|
2103
|
-
* is negligible compared to calling the listener functions themselves.
|
|
2104
|
-
*
|
|
2105
|
-
* **Settled behavior**: After `settle()` is called, `emit()` becomes a no-op.
|
|
2106
|
-
*
|
|
2107
|
-
* @param payload - The value to pass to all listeners
|
|
2108
|
-
*/
|
|
2109
|
-
emit(payload) {
|
|
2110
|
-
if (isSettled) return;
|
|
2111
|
-
doEmit(payload, false);
|
|
2112
|
-
},
|
|
2113
|
-
emitLifo(payload) {
|
|
2114
|
-
if (isSettled) return;
|
|
2115
|
-
doEmit(payload, false, true);
|
|
2116
|
-
},
|
|
2117
|
-
/**
|
|
2118
|
-
* Removes all registered listeners.
|
|
2119
|
-
*
|
|
2120
|
-
* After calling `clear()`, no listeners will be notified until new ones
|
|
2121
|
-
* are added via `on()`.
|
|
2122
|
-
*/
|
|
2123
|
-
clear() {
|
|
2124
|
-
listeners.clear();
|
|
2125
|
-
},
|
|
2126
|
-
/**
|
|
2127
|
-
* Emits an event to all registered listeners and then clears all listeners.
|
|
2128
|
-
*
|
|
2129
|
-
* **Settled behavior**: After `settle()` is called, `emitAndClear()` becomes a no-op.
|
|
2130
|
-
*
|
|
2131
|
-
* @param payload - The value to pass to all listeners
|
|
2132
|
-
*/
|
|
2133
|
-
emitAndClear(payload) {
|
|
2134
|
-
if (isSettled) return;
|
|
2135
|
-
doEmit(payload, true);
|
|
2136
|
-
},
|
|
2137
|
-
emitAndClearLifo(payload) {
|
|
2138
|
-
if (isSettled) return;
|
|
2139
|
-
doEmit(payload, true, true);
|
|
2140
|
-
},
|
|
2141
|
-
/**
|
|
2142
|
-
* Emit to all listeners, clear, and "settle" the emitter.
|
|
2143
|
-
*
|
|
2144
|
-
* After settling:
|
|
2145
|
-
* - Any new `on()` call immediately invokes the listener with the settled payload
|
|
2146
|
-
* - Returns a no-op unsubscribe function
|
|
2147
|
-
* - `emit()` and `emitAndClear()` become no-ops
|
|
2148
|
-
*
|
|
2149
|
-
* **Important**: `isSettled` is set BEFORE emitting so that listeners
|
|
2150
|
-
* added during emission see the settled state and get called immediately.
|
|
2151
|
-
*
|
|
2152
|
-
* @param payload - The final value to pass to all listeners
|
|
2153
|
-
*/
|
|
2154
|
-
settle(payload) {
|
|
2155
|
-
if (isSettled) return;
|
|
2156
|
-
settledPayload = payload;
|
|
2157
|
-
isSettled = true;
|
|
2158
|
-
doEmit(payload, true);
|
|
2159
|
-
}
|
|
2160
|
-
};
|
|
2161
|
-
}
|
|
2162
1972
|
function collection(createItem, initialItems) {
|
|
2163
1973
|
const map = /* @__PURE__ */ new Map([]);
|
|
2164
1974
|
return {
|
|
@@ -2640,26 +2450,21 @@ export {
|
|
|
2640
2450
|
isStorion as b,
|
|
2641
2451
|
createStoreInstance as c,
|
|
2642
2452
|
isContainer as d,
|
|
2643
|
-
|
|
2644
|
-
|
|
2453
|
+
isStore as e,
|
|
2454
|
+
isFocus as f,
|
|
2645
2455
|
getKind as g,
|
|
2646
|
-
|
|
2456
|
+
isAction as h,
|
|
2647
2457
|
isSpec as i,
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
strictEqual as q,
|
|
2458
|
+
isStoreContext as j,
|
|
2459
|
+
isSelectorContext as k,
|
|
2460
|
+
equality as l,
|
|
2461
|
+
shallowEqual as m,
|
|
2462
|
+
deepEqual as n,
|
|
2463
|
+
strictEqual as o,
|
|
2464
|
+
isWrappedFn as p,
|
|
2656
2465
|
resolveEquality as r,
|
|
2657
2466
|
store as s,
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
withHooks as w,
|
|
2662
|
-
isWrappedFn as x,
|
|
2663
|
-
getHooks as y,
|
|
2664
|
-
scheduleNotification as z
|
|
2467
|
+
tryDispose as t,
|
|
2468
|
+
unwrapFn as u,
|
|
2469
|
+
wrapFn as w
|
|
2665
2470
|
};
|