storion 0.10.1 → 0.11.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.
@@ -0,0 +1,167 @@
1
+ import { Focus, PickEquality } from '../types';
2
+ import { FocusAutoDispose } from './disposalGroup';
3
+
4
+ /**
5
+ * Options for the list helper.
6
+ */
7
+ export interface ListOptions<T> {
8
+ /**
9
+ * Auto-dispose items when removed.
10
+ *
11
+ * - `false` / `undefined`: No auto-disposal (default)
12
+ * - `true`: Dispose immediately via microtask
13
+ * - `number`: Grace period in ms (e.g., `100` = 100ms delay)
14
+ * - `string`: Named disposal group (shared across collections)
15
+ * - `DisposalGroup`: Direct group instance
16
+ * - `{ group, gracePeriodMs }`: Full options
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // Simple auto-dispose
21
+ * list({ autoDispose: true })
22
+ *
23
+ * // With 100ms grace period
24
+ * list({ autoDispose: 100 })
25
+ *
26
+ * // Named group - items moving between lists with same group name won't be disposed
27
+ * list({ autoDispose: "todos" })
28
+ *
29
+ * // Named group with grace period
30
+ * list({ autoDispose: { group: "todos", gracePeriodMs: 100 } })
31
+ *
32
+ * // Direct group instance
33
+ * const group = disposalGroup();
34
+ * list({ autoDispose: group })
35
+ * ```
36
+ */
37
+ autoDispose?: FocusAutoDispose;
38
+ /**
39
+ * Called when item(s) are added to the list.
40
+ */
41
+ onAdded?: (item: T, index: number) => void;
42
+ /**
43
+ * Called when item(s) are removed from the list.
44
+ */
45
+ onRemoved?: (item: T, index: number) => void;
46
+ }
47
+ /**
48
+ * List API returned by the list() helper.
49
+ */
50
+ export interface FocusList<T> {
51
+ /** Get the current array (returns empty array if undefined/null) */
52
+ get(): T[];
53
+ /** Get item at index */
54
+ at(index: number): T | undefined;
55
+ /** Get the length of the array */
56
+ length(): number;
57
+ /** Check if array is empty */
58
+ isEmpty(): boolean;
59
+ /** Get the first item */
60
+ first(): T | undefined;
61
+ /** Get the last item */
62
+ last(): T | undefined;
63
+ /** Push item(s) to the end */
64
+ push(...items: T[]): void;
65
+ /** Add item(s) to the beginning */
66
+ unshift(...items: T[]): void;
67
+ /** Remove and return the last item (auto-disposes if enabled) */
68
+ pop(): T | undefined;
69
+ /** Remove and return the first item (auto-disposes if enabled) */
70
+ shift(): T | undefined;
71
+ /** Remove item(s) by reference (auto-disposes if enabled) */
72
+ remove(...items: T[]): number;
73
+ /** Remove item at index (auto-disposes if enabled) */
74
+ removeAt(index: number): T | undefined;
75
+ /** Remove items matching predicate (auto-disposes if enabled) */
76
+ removeWhere(predicate: (item: T, index: number) => boolean): number;
77
+ /** Insert item at index */
78
+ insert(index: number, ...items: T[]): void;
79
+ /**
80
+ * Set item at index (auto-disposes old item if enabled).
81
+ * Accepts direct value, reducer, or immer-style updater.
82
+ *
83
+ * @example
84
+ * items.set(0, newItem); // Direct value
85
+ * items.set(0, prev => ({ ...prev, done: true })); // Reducer
86
+ * items.set(0, draft => { draft.done = true }); // Updater (mutates draft)
87
+ */
88
+ set(index: number, itemOrReducerOrUpdater: T | ((prev: T) => T | void)): void;
89
+ /**
90
+ * Get item at index, or create it if it doesn't exist.
91
+ *
92
+ * @example
93
+ * const item = items.tryGet(5, () => ({ id: 5, name: 'New' }));
94
+ */
95
+ tryGet(index: number, create: () => T): T;
96
+ /**
97
+ * Swap items at two indices.
98
+ *
99
+ * @example
100
+ * items.swap(0, 2); // Swap first and third items
101
+ */
102
+ swap(indexA: number, indexB: number): void;
103
+ /** Clear all items (auto-disposes all if enabled) */
104
+ clear(): void;
105
+ /** Replace entire array (auto-disposes old items if enabled) */
106
+ replace(items: T[]): void;
107
+ /** Find item matching predicate */
108
+ find(predicate: (item: T, index: number) => boolean): T | undefined;
109
+ /** Find index of item matching predicate */
110
+ findIndex(predicate: (item: T, index: number) => boolean): number;
111
+ /** Check if item exists */
112
+ includes(item: T): boolean;
113
+ /** Map items (read-only, doesn't mutate) */
114
+ map<U>(fn: (item: T, index: number) => U): U[];
115
+ /** Filter items (read-only, doesn't mutate) */
116
+ filter(predicate: (item: T, index: number) => boolean): T[];
117
+ /** Create a pick selector for fine-grained reactivity */
118
+ pick(equality?: PickEquality<T[] | undefined | null>): T[];
119
+ }
120
+ /**
121
+ * Create a list helper for array focus.
122
+ * Handles undefined/null arrays gracefully.
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * const todoStore = store({
127
+ * name: 'todos',
128
+ * state: { items: [] as TodoItem[] },
129
+ * setup({ focus }) {
130
+ * const items = focus('items').as(list());
131
+ * return {
132
+ * addTodo: (text: string) => items.push({ id: Date.now(), text, done: false }),
133
+ * removeTodo: (todo: TodoItem) => items.remove(todo),
134
+ * clearDone: () => items.removeWhere(item => item.done),
135
+ * clearAll: () => items.clear(),
136
+ * };
137
+ * },
138
+ * });
139
+ * ```
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * // With named disposal group for cross-collection moves
144
+ * const todoStore = store({
145
+ * name: 'todos',
146
+ * state: {
147
+ * active: [] as TodoItem[],
148
+ * completed: [] as TodoItem[],
149
+ * },
150
+ * setup({ focus }) {
151
+ * // Same group name = items moving between won't be disposed
152
+ * const active = focus('active').as(list({ autoDispose: "todos" }));
153
+ * const completed = focus('completed').as(list({ autoDispose: "todos" }));
154
+ *
155
+ * return {
156
+ * complete: (todo: TodoItem) => {
157
+ * active.remove(todo); // Schedules disposal
158
+ * completed.push(todo); // Cancels disposal - same group!
159
+ * },
160
+ * };
161
+ * },
162
+ * });
163
+ * ```
164
+ */
165
+ export declare function list<T>(options?: ListOptions<T>): (focus: Focus<T[] | undefined | null> | Focus<T[] | undefined> | Focus<T[] | null> | Focus<T[]>) => FocusList<T>;
166
+ export { disposalGroup, getNamedGroup, type DisposalGroup, type FocusAutoDispose, type FocusAutoDisposeOptions, } from './disposalGroup';
167
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/core/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ import { Focus, PickEquality } from '../types';
2
+ import { FocusAutoDispose } from './disposalGroup';
3
+
4
+ /**
5
+ * Options for the map helper.
6
+ */
7
+ export interface MapOptions<T> {
8
+ /**
9
+ * Auto-dispose values when removed.
10
+ *
11
+ * - `false` / `undefined`: No auto-disposal (default)
12
+ * - `true`: Dispose immediately via microtask
13
+ * - `number`: Grace period in ms (e.g., `100` = 100ms delay)
14
+ * - `string`: Named disposal group (shared across collections)
15
+ * - `DisposalGroup`: Direct group instance
16
+ * - `{ group, gracePeriodMs }`: Full options
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // Simple auto-dispose
21
+ * map({ autoDispose: true })
22
+ *
23
+ * // With 100ms grace period
24
+ * map({ autoDispose: 100 })
25
+ *
26
+ * // Named group - values moving between maps with same group name won't be disposed
27
+ * map({ autoDispose: "cache" })
28
+ *
29
+ * // Named group with grace period
30
+ * map({ autoDispose: { group: "cache", gracePeriodMs: 100 } })
31
+ *
32
+ * // Direct group instance
33
+ * const group = disposalGroup();
34
+ * map({ autoDispose: group })
35
+ * ```
36
+ */
37
+ autoDispose?: FocusAutoDispose;
38
+ /**
39
+ * Called when value is added to the map.
40
+ */
41
+ onAdded?: (value: T, key: string) => void;
42
+ /**
43
+ * Called when value is removed from the map.
44
+ */
45
+ onRemoved?: (value: T, key: string) => void;
46
+ }
47
+ /**
48
+ * Map API returned by the map() helper.
49
+ */
50
+ export interface FocusMap<T> {
51
+ /** Get the current record (returns empty object if undefined/null) */
52
+ get(): Record<string, T>;
53
+ /** Get value by key */
54
+ at(key: string): T | undefined;
55
+ /** Get number of entries */
56
+ size(): number;
57
+ /** Check if record is empty */
58
+ isEmpty(): boolean;
59
+ /** Check if key exists */
60
+ has(key: string): boolean;
61
+ /**
62
+ * Set value at key (auto-disposes old value if enabled).
63
+ * Accepts direct value, reducer, or immer-style updater.
64
+ *
65
+ * @example
66
+ * cache.set('count', 10); // Direct value
67
+ * cache.set('count', prev => prev + 1); // Reducer (returns new value)
68
+ * cache.set('user', draft => { draft.age++ }); // Updater (mutates draft)
69
+ */
70
+ set(key: string, valueOrReducerOrUpdater: T | ((prev: T) => T | void)): void;
71
+ /**
72
+ * Get value at key, or create it if it doesn't exist.
73
+ *
74
+ * @example
75
+ * const user = users.tryGet('user-123', () => ({ id: 'user-123', name: 'New' }));
76
+ */
77
+ tryGet(key: string, create: () => T): T;
78
+ /**
79
+ * Swap values at two keys.
80
+ *
81
+ * @example
82
+ * cache.swap('a', 'b'); // Swap values at keys 'a' and 'b'
83
+ */
84
+ swap(keyA: string, keyB: string): void;
85
+ /** Delete key(s) (auto-disposes values if enabled) */
86
+ delete(...keys: string[]): number;
87
+ /** Delete keys matching predicate (auto-disposes values if enabled) */
88
+ deleteWhere(predicate: (value: T, key: string) => boolean): number;
89
+ /** Clear all entries (auto-disposes all values if enabled) */
90
+ clear(): void;
91
+ /** Replace entire record (auto-disposes old values if enabled) */
92
+ replace(record: Record<string, T>): void;
93
+ /** Get all keys */
94
+ keys(): string[];
95
+ /** Get all values */
96
+ values(): T[];
97
+ /** Get all entries */
98
+ entries(): [string, T][];
99
+ /** Create a pick selector for fine-grained reactivity */
100
+ pick(equality?: PickEquality<Record<string, T> | undefined | null>): Record<string, T>;
101
+ }
102
+ /**
103
+ * Create a map helper for object/record focus.
104
+ * Handles undefined/null records gracefully.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const cacheStore = store({
109
+ * name: 'cache',
110
+ * state: { users: {} as Record<string, User> },
111
+ * setup({ focus }) {
112
+ * const users = focus('users').as(map());
113
+ * return {
114
+ * setUser: (id: string, user: User) => users.set(id, user),
115
+ * getUser: (id: string) => users.at(id),
116
+ * removeUser: (id: string) => users.delete(id),
117
+ * hasUser: (id: string) => users.has(id),
118
+ * clearUsers: () => users.clear(),
119
+ * };
120
+ * },
121
+ * });
122
+ * ```
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * // With named disposal group for cross-collection moves
127
+ * const cacheStore = store({
128
+ * name: 'cache',
129
+ * state: {
130
+ * active: {} as Record<string, Session>,
131
+ * archived: {} as Record<string, Session>,
132
+ * },
133
+ * setup({ focus }) {
134
+ * // Same group name = values moving between won't be disposed
135
+ * const active = focus('active').as(map({ autoDispose: "sessions" }));
136
+ * const archived = focus('archived').as(map({ autoDispose: "sessions" }));
137
+ *
138
+ * return {
139
+ * archiveSession: (id: string) => {
140
+ * const session = active.at(id);
141
+ * if (session) {
142
+ * active.delete(id); // Schedules disposal
143
+ * archived.set(id, session); // Cancels disposal - same group!
144
+ * }
145
+ * },
146
+ * };
147
+ * },
148
+ * });
149
+ * ```
150
+ */
151
+ export declare function map<T>(options?: MapOptions<T>): (focus: Focus<Record<string, T> | undefined | null> | Focus<Record<string, T> | undefined> | Focus<Record<string, T> | null> | Focus<Record<string, T>>) => FocusMap<T>;
152
+ export { disposalGroup, getNamedGroup, type DisposalGroup, type FocusAutoDispose, type FocusAutoDisposeOptions, } from './disposalGroup';
153
+ //# sourceMappingURL=map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/core/map.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAOzB;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAE/B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,sEAAsE;IACtE,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEzB,uBAAuB;IACvB,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;IAE/B,4BAA4B;IAC5B,IAAI,IAAI,MAAM,CAAC;IAEf,+BAA+B;IAC/B,OAAO,IAAI,OAAO,CAAC;IAEnB,0BAA0B;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAE1B;;;;;;;;OAQG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAE7E;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAExC;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvC,sDAAsD;IACtD,MAAM,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAElC,uEAAuE;IACvE,WAAW,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC;IAEnE,8DAA8D;IAC9D,KAAK,IAAI,IAAI,CAAC;IAEd,kEAAkE;IAClE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAEzC,mBAAmB;IACnB,IAAI,IAAI,MAAM,EAAE,CAAC;IAEjB,qBAAqB;IACrB,MAAM,IAAI,CAAC,EAAE,CAAC;IAEd,sBAAsB;IACtB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;IAEzB,yDAAyD;IACzD,IAAI,CACF,QAAQ,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,GAC5D,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,GAAG,CAAC,CAAC,EACnB,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GACtB,CACD,KAAK,EACD,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,GAC3C,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,GACpC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAC/B,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KACzB,QAAQ,CAAC,CAAC,CAAC,CAuPf;AAGD,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAC"}
package/dist/dev.d.ts CHANGED
@@ -1,47 +1,52 @@
1
1
  /**
2
2
  * Development-only utilities.
3
3
  *
4
- * These use the __DEV__ flag which should be defined by the consuming application's bundler.
4
+ * Uses `process.env.NODE_ENV` which bundlers (Vite, Webpack, Rollup) replace at build time.
5
+ * In production builds, all code inside `if (process.env.NODE_ENV !== 'production')` blocks
6
+ * is completely removed via dead code elimination.
7
+ *
8
+ * **How it works:**
9
+ * 1. Bundler replaces `process.env.NODE_ENV` with `"production"` or `"development"`
10
+ * 2. Condition becomes `if ("production" !== 'production')` → `if (false)`
11
+ * 3. Minifier removes the entire dead code block
5
12
  *
6
- * **For consuming applications:**
7
- * Add this to your Vite config:
13
+ * @example
8
14
  * ```ts
9
- * export default defineConfig({
10
- * define: {
11
- * __DEV__: JSON.stringify(process.env.NODE_ENV !== 'production'),
12
- * },
13
- * });
15
+ * // Development build (after bundling):
16
+ * if ("development" !== 'production') {
17
+ * console.warn('Warning'); // ✅ Included
18
+ * }
19
+ *
20
+ * // Production build (after bundling + minification):
21
+ * // The entire block is removed - zero runtime cost
14
22
  * ```
23
+ */
24
+ /**
25
+ * Check if running in development mode.
15
26
  *
16
- * In production builds with __DEV__ = false, all code inside `if (__DEV__)` blocks
17
- * is completely removed via dead code elimination.
27
+ * **Note:** For tree-shaking to work, use the inline pattern directly:
28
+ * ```ts
29
+ * if (process.env.NODE_ENV !== 'production') {
30
+ * // dev-only code
31
+ * }
32
+ * ```
18
33
  *
19
- * If __DEV__ is not defined, these utilities fall back to checking process.env.NODE_ENV.
34
+ * @returns `true` if in development mode, `false` in production
20
35
  */
36
+ export declare function isDev(): boolean;
21
37
  /**
22
38
  * Development utilities namespace.
23
39
  *
24
- * **Usage:**
40
+ * **Important:** For optimal tree-shaking, prefer using inline checks:
25
41
  * ```ts
26
- * // Check if in dev mode
27
- * if (dev()) {
28
- * // dev code
42
+ * if (process.env.NODE_ENV !== 'production') {
43
+ * console.warn('[storion] Warning message');
29
44
  * }
30
- *
31
- * // Run function only in dev
32
- * dev(() => {
33
- * validateSignalGraph();
34
- * });
35
- *
36
- * // Logging
37
- * dev.log("Signal created:", signal);
38
- * dev.warn("Deprecated API used");
39
- * dev.error("Invalid config:", config);
40
- *
41
- * // Assertions
42
- * dev.assert(value !== undefined, "Value cannot be undefined");
43
45
  * ```
44
46
  *
47
+ * The `dev.*` utilities are convenient but require the bundler to inline
48
+ * the `process.env.NODE_ENV` check within the function body.
49
+ *
45
50
  * @example
46
51
  * ```ts
47
52
  * // Check dev mode
@@ -68,7 +73,6 @@ export declare function dev(fn?: () => void): boolean;
68
73
  export declare namespace dev {
69
74
  /**
70
75
  * Log a message only in development.
71
- * If __DEV__ is defined and is false, this is removed via dead code elimination.
72
76
  *
73
77
  * @param message - Message to log
74
78
  * @param args - Additional arguments
@@ -76,14 +80,13 @@ export declare namespace dev {
76
80
  * @example
77
81
  * ```ts
78
82
  * dev.log("Signal created:", signal);
79
- * // Production (with __DEV__ defined): removed entirely
80
- * // Development: console.log("[rextive] Signal created:", signal)
83
+ * // Production: removed entirely
84
+ * // Development: console.log("[storion] Signal created:", signal)
81
85
  * ```
82
86
  */
83
87
  function log(message: string, ...args: any[]): void;
84
88
  /**
85
89
  * Log a warning only in development.
86
- * If __DEV__ is defined and is false, this is removed via dead code elimination.
87
90
  *
88
91
  * @param message - Warning message
89
92
  * @param args - Additional arguments
@@ -91,14 +94,13 @@ export declare namespace dev {
91
94
  * @example
92
95
  * ```ts
93
96
  * dev.warn("Deprecated API used");
94
- * // Production (with __DEV__ defined): removed entirely
95
- * // Development: console.warn("[rextive] Deprecated API used")
97
+ * // Production: removed entirely
98
+ * // Development: console.warn("[storion] Deprecated API used")
96
99
  * ```
97
100
  */
98
101
  function warn(message: string, ...args: any[]): void;
99
102
  /**
100
103
  * Log an error only in development.
101
- * If __DEV__ is defined and is false, this is removed via dead code elimination.
102
104
  *
103
105
  * @param message - Error message
104
106
  * @param args - Additional arguments
@@ -106,14 +108,13 @@ export declare namespace dev {
106
108
  * @example
107
109
  * ```ts
108
110
  * dev.error("Invalid configuration:", config);
109
- * // Production (with __DEV__ defined): removed entirely
110
- * // Development: console.error("[rextive] Invalid configuration:", config)
111
+ * // Production: removed entirely
112
+ * // Development: console.error("[storion] Invalid configuration:", config)
111
113
  * ```
112
114
  */
113
115
  function error(message: string, ...args: any[]): void;
114
116
  /**
115
117
  * Assert a condition only in development.
116
- * If __DEV__ is defined and is false, this is removed via dead code elimination.
117
118
  *
118
119
  * @param condition - Condition to assert
119
120
  * @param message - Error message if assertion fails
@@ -121,7 +122,7 @@ export declare namespace dev {
121
122
  * @example
122
123
  * ```ts
123
124
  * dev.assert(signal !== undefined, "Signal cannot be undefined");
124
- * // Production (with __DEV__ defined): removed entirely
125
+ * // Production: removed entirely
125
126
  * // Development: throws if condition is false
126
127
  * ```
127
128
  */
package/dist/dev.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAmCH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAW5C;AAED;;GAEG;AACH,yBAAiB,GAAG,CAAC;IACnB;;;;;;;;;;;;;OAaG;IACH,SAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAIzD;IAED;;;;;;;;;;;;;OAaG;IACH,SAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAI1D;IAED;;;;;;;;;;;;;OAaG;IACH,SAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAI3D;IAED;;;;;;;;;;;;;OAaG;IACH,SAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMhE;CACF"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAYH;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,IAAI,OAAO,CAE/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAU5C;AAED;;GAEG;AACH,yBAAiB,GAAG,CAAC;IACnB;;;;;;;;;;;;OAYG;IACH,SAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAIzD;IAED;;;;;;;;;;;;OAYG;IACH,SAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAI1D;IAED;;;;;;;;;;;;OAYG;IACH,SAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAI3D;IAED;;;;;;;;;;;;OAYG;IACH,SAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMhE;CACF"}
@@ -1985,53 +1985,38 @@ function pick(selector, equality2) {
1985
1985
  });
1986
1986
  return currentValue;
1987
1987
  }
1988
- function checkIsDev() {
1989
- var _a;
1990
- if (typeof __DEV__ !== "undefined") {
1991
- return __DEV__;
1992
- }
1993
- try {
1994
- const p = globalThis.process;
1995
- if ((_a = p == null ? void 0 : p.env) == null ? void 0 : _a.NODE_ENV) {
1996
- return p.env.NODE_ENV !== "production";
1997
- }
1998
- } catch {
1999
- }
2000
- return false;
2001
- }
2002
1988
  function dev(fn) {
2003
- const isDev = checkIsDev();
1989
+ if (process.env.NODE_ENV === "production") {
1990
+ return false;
1991
+ }
2004
1992
  if (fn) {
2005
- if (isDev) {
2006
- fn();
2007
- }
2008
- return isDev;
1993
+ fn();
2009
1994
  }
2010
- return isDev;
1995
+ return true;
2011
1996
  }
2012
1997
  ((dev2) => {
2013
1998
  function log(message, ...args) {
2014
- if (checkIsDev()) {
2015
- console.log(`[rextive] ${message}`, ...args);
1999
+ if (process.env.NODE_ENV !== "production") {
2000
+ console.log(`[storion] ${message}`, ...args);
2016
2001
  }
2017
2002
  }
2018
2003
  dev2.log = log;
2019
2004
  function warn(message, ...args) {
2020
- if (checkIsDev()) {
2021
- console.warn(`[rextive] ${message}`, ...args);
2005
+ if (process.env.NODE_ENV !== "production") {
2006
+ console.warn(`[storion] ${message}`, ...args);
2022
2007
  }
2023
2008
  }
2024
2009
  dev2.warn = warn;
2025
2010
  function error(message, ...args) {
2026
- if (checkIsDev()) {
2027
- console.error(`[rextive] ${message}`, ...args);
2011
+ if (process.env.NODE_ENV !== "production") {
2012
+ console.error(`[storion] ${message}`, ...args);
2028
2013
  }
2029
2014
  }
2030
2015
  dev2.error = error;
2031
2016
  function assert(condition, message) {
2032
- if (checkIsDev()) {
2017
+ if (process.env.NODE_ENV !== "production") {
2033
2018
  if (!condition) {
2034
- throw new Error(`[rextive] Assertion failed: ${message}`);
2019
+ throw new Error(`[storion] Assertion failed: ${message}`);
2035
2020
  }
2036
2021
  }
2037
2022
  }
@@ -2962,7 +2947,8 @@ function createAbortableContext(controller, pauseState, takeState, setStatus) {
2962
2947
  race: baseSafe.race,
2963
2948
  settled: baseSafe.settled,
2964
2949
  any: baseSafe.any,
2965
- callback: baseSafe.callback
2950
+ callback: baseSafe.callback,
2951
+ delay: baseSafe.delay
2966
2952
  });
2967
2953
  const take = (key) => {
2968
2954
  const takeKey = String(key ?? "__checkpoint__");
@@ -3311,12 +3297,24 @@ function createSafe(getSignal, isCancelled) {
3311
3297
  cb(...args);
3312
3298
  };
3313
3299
  };
3300
+ const delay = (ms, resolved) => {
3301
+ if (isCancelled()) {
3302
+ return new Promise(() => {
3303
+ });
3304
+ }
3305
+ return wrapPromise(
3306
+ new Promise((resolve) => {
3307
+ setTimeout(() => resolve(resolved), ms);
3308
+ })
3309
+ );
3310
+ };
3314
3311
  return Object.assign(safe, {
3315
3312
  all,
3316
3313
  race,
3317
3314
  settled,
3318
3315
  any,
3319
- callback
3316
+ callback,
3317
+ delay
3320
3318
  });
3321
3319
  }
3322
3320
  const retryStrategy = {
@@ -3615,10 +3613,11 @@ function effect(fn, options) {
3615
3613
  }
3616
3614
  export {
3617
3615
  AsyncNotReadyError as A,
3618
- pool as B,
3619
- tryDispose as C,
3620
- unwrapFn as D,
3616
+ LocalStoreDependencyError as B,
3617
+ pool as C,
3618
+ tryDispose as D,
3621
3619
  EffectRefreshError as E,
3620
+ unwrapFn as F,
3622
3621
  HooksContextError as H,
3623
3622
  InvalidActionError as I,
3624
3623
  LifetimeMismatchError as L,
@@ -3635,19 +3634,19 @@ export {
3635
3634
  isSpec as i,
3636
3635
  ScopedOutsideSelectorError as j,
3637
3636
  STORION_TYPE as k,
3638
- resolveEquality as l,
3639
- is$1 as m,
3640
- batch as n,
3641
- equality as o,
3637
+ dev as l,
3638
+ resolveEquality as m,
3639
+ is$1 as n,
3640
+ batch as o,
3642
3641
  pick as p,
3643
- shallowEqual as q,
3642
+ equality as q,
3644
3643
  retryStrategy as r,
3645
3644
  storeTuple as s,
3646
3645
  tryStabilize as t,
3647
3646
  untrack as u,
3648
- deepEqual as v,
3647
+ shallowEqual as v,
3649
3648
  withHooks as w,
3650
- StorionError as x,
3651
- StoreDisposedError as y,
3652
- LocalStoreDependencyError as z
3649
+ deepEqual as x,
3650
+ StorionError as y,
3651
+ StoreDisposedError as z
3653
3652
  };
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { container } from './core/container';
10
10
  export { batch, untrack } from './core/tracking';
11
11
  export { createResolver as resolver } from './core/createResolver';
12
12
  export { pick } from './core/pick';
13
- export { list, map, toggle, increment, decrement, multiply, divide, clamp, append, prepend, merge, reset, type ListOptions, type MapOptions, type FocusList, type FocusMap, } from './core/focusHelpers';
13
+ export { list, map, disposalGroup, getNamedGroup, toggle, increment, decrement, multiply, divide, clamp, append, prepend, merge, reset, type ListOptions, type MapOptions, type FocusList, type FocusMap, type DisposalGroup, type FocusAutoDispose, type FocusAutoDisposeOptions, } from './core/focusHelpers';
14
14
  export { effect, type EffectFn, type EffectContext, type EffectOptions, type EffectErrorStrategy, type EffectErrorContext, type EffectRetryConfig, } from './core/effect';
15
15
  export { applyFor, applyExcept, forStores, type SpecPattern, type MiddlewareMap, } from './core/middleware';
16
16
  export { equality, shallowEqual, deepEqual, strictEqual, } from './core/equality';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAG1B,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGnE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGnC,OAAO,EACL,IAAI,EACJ,GAAG,EAEH,MAAM,EACN,SAAS,EACT,SAAS,EACT,QAAQ,EACR,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,EACL,KAAK,EAEL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,QAAQ,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,MAAM,EACN,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAGzD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAG1B,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGnE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGnC,OAAO,EACL,IAAI,EACJ,GAAG,EACH,aAAa,EACb,aAAa,EAEb,MAAM,EACN,SAAS,EACT,SAAS,EACT,QAAQ,EACR,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,EACL,KAAK,EAEL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,MAAM,EACN,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAGzD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}