@volynets/reflex-store 0.0.1 → 0.0.2

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  # Reflex Store
2
2
 
3
3
  Structured state, derived views and keyed collections with a compiler for static
4
- store shapes. The library distribution keeps the Reflex host and reactive kernel
5
- as external imports. `@volynets/reflex`, `@volynets/reflex-runtime` and
4
+ store shapes. The library distribution uses the shared reactive kernel and
5
+ lifecycle primitives. `@volynets/reflex-runtime` and
6
6
  `@volynets/reflex-framework` are peer dependencies. Framework supplies the
7
7
  shared lifecycle primitives, while Store, DOM and Async share the application's
8
8
  kernel module identity.
9
9
  The distribution includes the portable SWC WebAssembly compiler and Vite plugin.
10
10
 
11
11
  ```sh
12
- pnpm add @volynets/reflex-store @volynets/reflex @volynets/reflex-runtime @volynets/reflex-framework
12
+ pnpm add @volynets/reflex-store @volynets/reflex-runtime@^1.0.1 @volynets/reflex-framework
13
13
  ```
14
14
 
15
15
  Requires Node.js 20.19 or newer for the compiler and Vite plugin. Published
@@ -23,7 +23,6 @@ Start with `createStore`, `derive`, `selector`, `reactiveMap`, `action` and
23
23
  restoring compiled data.
24
24
 
25
25
  ```ts
26
- import { createRuntime, effect } from "@volynets/reflex-store/runtime";
27
26
  import {
28
27
  createStore,
29
28
  leaf,
@@ -35,8 +34,6 @@ import {
35
34
  hydrate,
36
35
  } from "@volynets/reflex-store";
37
36
 
38
- createRuntime({ effectStrategy: "flush" });
39
-
40
37
  export function createBoard() {
41
38
  const board = createStore(
42
39
  {
@@ -108,9 +105,10 @@ export default defineConfig({
108
105
  ```
109
106
 
110
107
  The plugin transforms stores while preserving application package resolution.
111
- It does not redirect host or kernel imports. `@volynets/reflex-store/runtime`,
112
- `/runtime/core` and `/runtime/internal` re-export the shared peer APIs; they do not
113
- contain a private host or kernel.
108
+ `@volynets/reflex-store/runtime` exports the compiler's cell, scope and owned
109
+ computed primitives. `/runtime/core` and `/runtime/internal` re-export the shared
110
+ kernel. Application runtime setup and effect scheduling belong to the consumer;
111
+ the task-board example includes explicit kernel/scheduler wiring.
114
112
 
115
113
  The standalone compiler is exported from `@volynets/reflex-store/store`.
116
114
  It includes its portable WASM asset; installing a platform-specific native SWC
@@ -129,27 +127,27 @@ and exposes disposal through `dispose()` and `Symbol.dispose`. Cells are created
129
127
  and owned during setup; a failed initializer disposes earlier cells before
130
128
  rethrowing its original error. Computed getter resources share the same lifetime.
131
129
 
132
- Store compilation uses neither `createModel` nor `defineModel`. Models remain an
133
- optional way for application code to own a store alongside other resources.
130
+ Store compilation uses store scopes for ownership and disposal.
134
131
 
135
- Use the shared host's model ownership to dispose resources together:
132
+ Use a store scope to dispose resources together:
136
133
 
137
134
  ```ts
138
- import { createModel, own, signal } from "@volynets/reflex-store/runtime";
135
+ import {
136
+ createStoreScope,
137
+ createStoreCell,
138
+ } from "@volynets/reflex-store/runtime";
139
139
  import { derive, reactiveMap, selector } from "@volynets/reflex-store";
140
140
 
141
- const createPanel = createModel((ctx) => {
142
- const tasks = own(ctx, reactiveMap<string, { done: boolean }>());
143
- const selectedId = signal("");
144
- return {
145
- tasks,
146
- selected: own(ctx, selector(selectedId)),
147
- summary: own(
148
- ctx,
149
- derive(() => ({ total: tasks.size })),
150
- ),
151
- };
152
- });
141
+ const createPanel = () =>
142
+ createStoreScope((ctx) => {
143
+ const tasks = ctx.own(reactiveMap<string, { done: boolean }>());
144
+ const selectedId = ctx.own(createStoreCell(""));
145
+ return {
146
+ tasks,
147
+ selected: ctx.own(selector(selectedId)),
148
+ summary: ctx.own(derive(() => ({ total: tasks.size }))),
149
+ };
150
+ });
153
151
  ```
154
152
 
155
153
  Maps, sets, selectors, keyed projections, structured views and compiled stores
@@ -1,5 +1,4 @@
1
1
  /// <reference lib="esnext.disposable" />
2
- import type { Destructor, Accessor } from "./runtime/types.js";
3
2
  export { C as CompiledStore, S as StoreData, a as StoreOptions, b as StoreShape, c as createStore, l as leaf } from './types/createStore-BJ66-pfq.js';
4
3
  export { action, derive, hydrate } from './index.js';
5
4
  export { A as Accessor, D as Destructor, a as DisposableAccessor, S as StoreDisposable, c as createKeyedProjection, b as createSelector, b as selector } from './types/keyed-CdSYzIOc.js';
package/dist/advanced.js CHANGED
@@ -1,9 +1,10 @@
1
1
  export { createProjection } from './selectors/index.js';
2
- export { R as ReactiveMap, b as ReactiveSet, d as createKeyedProjection, c as createReactiveMap, a as createSelector, e as createStoreProjection, c as reactiveMap, r as reactiveSet, a as selector, t as transaction } from './chunks/keyed-C-QvvUv4.js';
3
- export { g as getStoreName } from './chunks/names-BF36AyM3.js';
4
- export { c as collectStore, d as deep, a as disposeStore, o as opaque, r as raw, b as ref, e as shallow, s as snapshot } from './chunks/shared-BHHficW8.js';
2
+ export { R as ReactiveMap, a as ReactiveSet, c as createReactiveMap, c as reactiveMap, r as reactiveSet, t as transaction } from './chunks/collections-yHy0wH0f.js';
3
+ export { g as getStoreName } from './chunks/names-Cx4YcvsH.js';
4
+ export { c as collectStore, d as deep, a as disposeStore, o as opaque, r as raw, b as ref, e as shallow, s as snapshot } from './chunks/values-DCB6zyMz.js';
5
5
  export { createStoreCell } from './runtime/internal.js';
6
- export { a as action, d as derive, h as hydrate, l as leaf } from './chunks/hydrate-Bdtl9XyA.js';
6
+ export { a as action, d as derive, h as hydrate, l as leaf } from './chunks/hydrate-DMnHCI5q.js';
7
+ export { a as createKeyedProjection, c as createSelector, b as createStoreProjection, c as selector } from './chunks/keyed-CQKtL8a7.js';
7
8
  export { c as createStore } from './chunks/createStore-DHj16Ehk.js';
8
9
  import '@volynets/reflex-runtime/internal';
9
- import '@volynets/reflex';
10
+ import './selectors/shared.js';
@@ -0,0 +1,268 @@
1
+ import { untracked, currentConsumer, readProducer, createProducer, disposeNode, getActiveRuntimeContext, enterReactiveBatch, leaveReactiveBatch, writeProducer } from '@volynets/reflex-runtime/internal';
2
+ import { g as storeControls } from './values-DCB6zyMz.js';
3
+ import { s as setStoreName } from './names-Cx4YcvsH.js';
4
+
5
+ let transactionContext;
6
+ /** Publish a synchronous logical action at one runtime batch boundary. */ function transaction(action) {
7
+ if (transactionContext !== undefined && transactionContext === getActiveRuntimeContext()) return action();
8
+ const previous = transactionContext;
9
+ transactionContext = getActiveRuntimeContext();
10
+ enterReactiveBatch();
11
+ try {
12
+ return action();
13
+ } finally{
14
+ transactionContext = previous;
15
+ leaveReactiveBatch();
16
+ }
17
+ }
18
+ class Cells {
19
+ read(key, value) {
20
+ if (currentConsumer === null) return value;
21
+ let entry = this.nodes.get(key);
22
+ if (!entry) {
23
+ entry = {
24
+ node: createProducer(0),
25
+ value
26
+ };
27
+ this.nodes.set(key, entry);
28
+ }
29
+ readProducer(entry.node);
30
+ return value;
31
+ }
32
+ write(key, value) {
33
+ const entry = this.nodes.get(key);
34
+ if (!entry || Object.is(entry.value, value)) return;
35
+ entry.value = value;
36
+ writeProducer(entry.node, entry.node.payload + 1);
37
+ }
38
+ clear(value) {
39
+ for (const entry of this.nodes.values()){
40
+ if (Object.is(entry.value, value)) continue;
41
+ entry.value = value;
42
+ writeProducer(entry.node, entry.node.payload + 1);
43
+ }
44
+ }
45
+ collect() {
46
+ for (const [key, { node }] of this.nodes){
47
+ if (node.firstOut !== null) continue;
48
+ this.nodes.delete(key);
49
+ disposeNode(node);
50
+ }
51
+ }
52
+ dispose() {
53
+ for (const { node } of this.nodes.values())disposeNode(node);
54
+ this.nodes.clear();
55
+ }
56
+ constructor(){
57
+ // Values live outside producer payloads so foreign objects remain valid even
58
+ // when runtime dev validation accepts only primitive/plain payloads.
59
+ this.nodes = new Map();
60
+ }
61
+ }
62
+ class ReactiveMap {
63
+ constructor(initial, options = {}){
64
+ this.initial = initial;
65
+ this.options = options;
66
+ this.disposed = false;
67
+ this.valuesByKey = new Cells();
68
+ this.existsByKey = new Cells();
69
+ setStoreName(this, options.name);
70
+ storeControls.set(this, {
71
+ raw: ()=>this.backing(),
72
+ collect: ()=>this.collect(),
73
+ dispose: ()=>this.dispose()
74
+ });
75
+ }
76
+ backing() {
77
+ if (this.disposed) throw new Error("Cannot use a disposed reactive map");
78
+ if (!this.data) {
79
+ this.data = untracked(()=>new Map(typeof this.initial === "function" ? this.initial() : this.initial));
80
+ this.initial = undefined;
81
+ }
82
+ return this.data;
83
+ }
84
+ get size() {
85
+ const size = this.backing().size;
86
+ if (currentConsumer !== null) readProducer(this.sizeNode ??= createProducer(size));
87
+ return size;
88
+ }
89
+ get [Symbol.toStringTag]() {
90
+ return "ReactiveMap";
91
+ }
92
+ get(key) {
93
+ return this.valuesByKey.read(key, this.backing().get(key));
94
+ }
95
+ has(key) {
96
+ return this.existsByKey.read(key, this.backing().has(key));
97
+ }
98
+ set(key, value) {
99
+ const data = this.backing();
100
+ const previous = data.get(key);
101
+ const existed = previous !== undefined || data.has(key);
102
+ if (existed) {
103
+ const equals = this.options.equals;
104
+ if (equals == null || equals === Object.is ? Object.is(previous, value) : untracked(()=>equals(previous, value))) return this;
105
+ }
106
+ this.commitSet(data, key, value, existed);
107
+ return this;
108
+ }
109
+ commitSet(data, key, value, existed) {
110
+ transaction(()=>{
111
+ data.set(key, value);
112
+ this.valuesByKey.write(key, value);
113
+ if (!existed) {
114
+ this.existsByKey.write(key, true);
115
+ if (this.sizeNode) writeProducer(this.sizeNode, data.size);
116
+ if (this.keysNode) writeProducer(this.keysNode, this.keysNode.payload + 1);
117
+ }
118
+ if (this.valuesNode) writeProducer(this.valuesNode, this.valuesNode.payload + 1);
119
+ });
120
+ }
121
+ delete(key) {
122
+ const data = this.backing();
123
+ if (!data.has(key)) return false;
124
+ transaction(()=>{
125
+ data.delete(key);
126
+ this.valuesByKey.write(key, undefined);
127
+ this.existsByKey.write(key, false);
128
+ if (this.sizeNode) writeProducer(this.sizeNode, data.size);
129
+ if (this.keysNode) writeProducer(this.keysNode, this.keysNode.payload + 1);
130
+ if (this.valuesNode) writeProducer(this.valuesNode, this.valuesNode.payload + 1);
131
+ });
132
+ return true;
133
+ }
134
+ clear() {
135
+ const data = this.backing();
136
+ if (data.size === 0) return;
137
+ transaction(()=>{
138
+ data.clear();
139
+ // Only materialized semantic locations need invalidation, even for a large map.
140
+ this.valuesByKey.clear(undefined);
141
+ this.existsByKey.clear(false);
142
+ if (this.sizeNode) writeProducer(this.sizeNode, 0);
143
+ if (this.keysNode) writeProducer(this.keysNode, this.keysNode.payload + 1);
144
+ if (this.valuesNode) writeProducer(this.valuesNode, this.valuesNode.payload + 1);
145
+ });
146
+ }
147
+ keys() {
148
+ const data = this.backing();
149
+ if (currentConsumer !== null) readProducer(this.keysNode ??= createProducer(0));
150
+ return data.keys();
151
+ }
152
+ values() {
153
+ const data = this.backing();
154
+ if (currentConsumer !== null) readProducer(this.valuesNode ??= createProducer(0));
155
+ return data.values();
156
+ }
157
+ entries() {
158
+ const data = this.backing();
159
+ if (currentConsumer !== null) readProducer(this.valuesNode ??= createProducer(0));
160
+ return data.entries();
161
+ }
162
+ [Symbol.iterator]() {
163
+ return this.entries();
164
+ }
165
+ forEach(callback, thisArg) {
166
+ const data = this.backing();
167
+ if (currentConsumer !== null) readProducer(this.valuesNode ??= createProducer(0));
168
+ data.forEach((value, key)=>callback.call(thisArg, value, key, this));
169
+ }
170
+ collect() {
171
+ this.valuesByKey.collect();
172
+ this.existsByKey.collect();
173
+ if (this.sizeNode?.firstOut === null) {
174
+ disposeNode(this.sizeNode);
175
+ this.sizeNode = undefined;
176
+ }
177
+ if (this.keysNode?.firstOut === null) {
178
+ disposeNode(this.keysNode);
179
+ this.keysNode = undefined;
180
+ }
181
+ if (this.valuesNode?.firstOut === null) {
182
+ disposeNode(this.valuesNode);
183
+ this.valuesNode = undefined;
184
+ }
185
+ }
186
+ [Symbol.dispose]() {
187
+ this.dispose();
188
+ }
189
+ dispose() {
190
+ this.disposed = true;
191
+ this.valuesByKey.dispose();
192
+ this.existsByKey.dispose();
193
+ if (this.sizeNode) disposeNode(this.sizeNode);
194
+ if (this.keysNode) disposeNode(this.keysNode);
195
+ if (this.valuesNode) disposeNode(this.valuesNode);
196
+ this.sizeNode = this.keysNode = this.valuesNode = undefined;
197
+ this.data = undefined;
198
+ this.initial = undefined;
199
+ }
200
+ }
201
+ /** A native Set-shaped membership collection over keyed reactive observations. */ class ReactiveSet {
202
+ constructor(initial, options = {}){
203
+ this.members = new ReactiveMap(()=>Array.from(typeof initial === "function" ? initial() : initial ?? [], (value)=>[
204
+ value,
205
+ true
206
+ ]));
207
+ setStoreName(this, options.name);
208
+ storeControls.set(this, {
209
+ raw: ()=>new Set(this.members.keys()),
210
+ collect: ()=>this.collect(),
211
+ dispose: ()=>this.dispose()
212
+ });
213
+ }
214
+ get size() {
215
+ return this.members.size;
216
+ }
217
+ get [Symbol.toStringTag]() {
218
+ return "ReactiveSet";
219
+ }
220
+ has(value) {
221
+ return this.members.has(value);
222
+ }
223
+ add(value) {
224
+ this.members.set(value, true);
225
+ return this;
226
+ }
227
+ delete(value) {
228
+ return this.members.delete(value);
229
+ }
230
+ clear() {
231
+ this.members.clear();
232
+ }
233
+ values() {
234
+ return this.members.keys();
235
+ }
236
+ keys() {
237
+ return this.values();
238
+ }
239
+ *entries() {
240
+ for (const value of this.values())yield [
241
+ value,
242
+ value
243
+ ];
244
+ }
245
+ [Symbol.iterator]() {
246
+ return this.values();
247
+ }
248
+ forEach(callback, thisArg) {
249
+ for (const value of this.values())callback.call(thisArg, value, value, this);
250
+ }
251
+ collect() {
252
+ this.members.collect();
253
+ }
254
+ dispose() {
255
+ this.members.dispose();
256
+ }
257
+ [Symbol.dispose]() {
258
+ this.dispose();
259
+ }
260
+ }
261
+ function reactiveSet(initial, options) {
262
+ return new ReactiveSet(initial, options);
263
+ }
264
+ function createReactiveMap(initial, options) {
265
+ return new ReactiveMap(initial, options);
266
+ }
267
+
268
+ export { ReactiveMap as R, ReactiveSet as a, createReactiveMap as c, reactiveSet as r, transaction as t };
@@ -1160,10 +1160,7 @@ function scanUnsupportedStoreSyntax(program, state) {
1160
1160
  }
1161
1161
  const intrinsicNames = new Map();
1162
1162
  for (const item of program.body){
1163
- if (item.type !== "ImportDeclaration" || !STORE_MODULES$1.has(item.source.value) && ![
1164
- "@volynets/reflex",
1165
- "@volynets/reflex-store/runtime"
1166
- ].includes(item.source.value)) continue;
1163
+ if (item.type !== "ImportDeclaration" || !STORE_MODULES$1.has(item.source.value)) continue;
1167
1164
  for (const specifier of item.specifiers){
1168
1165
  if (specifier.type !== "ImportSpecifier" || specifier.isTypeOnly) continue;
1169
1166
  const imported = specifier.imported?.value ?? specifier.local.value;
@@ -1175,13 +1172,6 @@ function scanUnsupportedStoreSyntax(program, state) {
1175
1172
  arity: imported === "hydrate" ? 2 : 1,
1176
1173
  rootIndex: 0
1177
1174
  });
1178
- if (imported === "own" && [
1179
- "@volynets/reflex",
1180
- "@volynets/reflex-store/runtime"
1181
- ].includes(item.source.value)) intrinsicNames.set(bindingKey(specifier.local), {
1182
- arity: 2,
1183
- rootIndex: 1
1184
- });
1185
1175
  }
1186
1176
  }
1187
1177
  const returnRoots = new Set();
@@ -1,6 +1,7 @@
1
- import { f as createDerivedProjection, t as transaction } from './keyed-C-QvvUv4.js';
2
- import { i as isPlain, g as getStoreControl, f as depthOf } from './shared-BHHficW8.js';
1
+ import { d as createDerivedProjection } from './keyed-CQKtL8a7.js';
2
+ import { i as isPlain, h as getStoreControl, j as depthOf } from './values-DCB6zyMz.js';
3
3
  import { untracked } from '@volynets/reflex-runtime/internal';
4
+ import { t as transaction } from './collections-yHy0wH0f.js';
4
5
 
5
6
  /** Marks one compiled store value as a replaceable leaf. */ function leaf(value) {
6
7
  return value;
@@ -1,7 +1,8 @@
1
- import { setCurrentConsumer, currentConsumer, createConsumer, readConsumerLazy, disposeNode, untracked, unlinkAllSources, CONSUMER_INITIAL_STATE, createProducer, readProducer, getActiveRuntimeContext, enterReactiveBatch, leaveReactiveBatch, writeProducer, disposeWatcher, createWatcher, runWatcher, Both } from '@volynets/reflex-runtime/internal';
2
- import { h as cloneValue, j as readProjectionPath, k as storeControls, f as depthOf, l as isStructural } from './shared-BHHficW8.js';
3
- import { s as storeName, a as setStoreName } from './names-BF36AyM3.js';
4
- import { batch } from '@volynets/reflex';
1
+ import { setCurrentConsumer, currentConsumer, createConsumer, readConsumerLazy, disposeNode, untracked, unlinkAllSources, CONSUMER_INITIAL_STATE, createProducer, disposeWatcher, createWatcher, runWatcher, Both, readProducer, writeProducer } from '@volynets/reflex-runtime/internal';
2
+ import { f as cloneValue, g as storeControls, j as depthOf, k as isStructural } from './values-DCB6zyMz.js';
3
+ import { a as storeName, s as setStoreName } from './names-Cx4YcvsH.js';
4
+ import { readProjectionPath } from '../selectors/shared.js';
5
+ import { t as transaction } from './collections-yHy0wH0f.js';
5
6
 
6
7
  /** A memo with owner-controlled suspension; no node exists until its first read. */ class Demand {
7
8
  constructor(compute){
@@ -265,271 +266,6 @@ function createSignalNode(payload) {
265
266
  return createProducer(payload);
266
267
  }
267
268
 
268
- let transactionContext;
269
- /** Publish a synchronous logical action at one runtime batch boundary. */ function transaction(action) {
270
- if (transactionContext !== undefined && transactionContext === getActiveRuntimeContext()) return action();
271
- return batch(()=>{
272
- const previous = transactionContext;
273
- transactionContext = getActiveRuntimeContext();
274
- enterReactiveBatch();
275
- try {
276
- return action();
277
- } finally{
278
- transactionContext = previous;
279
- leaveReactiveBatch();
280
- }
281
- });
282
- }
283
- class Cells {
284
- read(key, value) {
285
- if (currentConsumer === null) return value;
286
- let entry = this.nodes.get(key);
287
- if (!entry) {
288
- entry = {
289
- node: createProducer(0),
290
- value
291
- };
292
- this.nodes.set(key, entry);
293
- }
294
- readProducer(entry.node);
295
- return value;
296
- }
297
- write(key, value) {
298
- const entry = this.nodes.get(key);
299
- if (!entry || Object.is(entry.value, value)) return;
300
- entry.value = value;
301
- writeProducer(entry.node, entry.node.payload + 1);
302
- }
303
- clear(value) {
304
- for (const entry of this.nodes.values()){
305
- if (Object.is(entry.value, value)) continue;
306
- entry.value = value;
307
- writeProducer(entry.node, entry.node.payload + 1);
308
- }
309
- }
310
- collect() {
311
- for (const [key, { node }] of this.nodes){
312
- if (node.firstOut !== null) continue;
313
- this.nodes.delete(key);
314
- disposeNode(node);
315
- }
316
- }
317
- dispose() {
318
- for (const { node } of this.nodes.values())disposeNode(node);
319
- this.nodes.clear();
320
- }
321
- constructor(){
322
- // Values live outside producer payloads so foreign objects remain valid even
323
- // when runtime dev validation accepts only primitive/plain payloads.
324
- this.nodes = new Map();
325
- }
326
- }
327
- class ReactiveMap {
328
- constructor(initial, options = {}){
329
- this.initial = initial;
330
- this.options = options;
331
- this.disposed = false;
332
- this.valuesByKey = new Cells();
333
- this.existsByKey = new Cells();
334
- setStoreName(this, options.name);
335
- storeControls.set(this, {
336
- raw: ()=>this.backing(),
337
- collect: ()=>this.collect(),
338
- dispose: ()=>this.dispose()
339
- });
340
- }
341
- backing() {
342
- if (this.disposed) throw new Error("Cannot use a disposed reactive map");
343
- if (!this.data) {
344
- this.data = untracked(()=>new Map(typeof this.initial === "function" ? this.initial() : this.initial));
345
- this.initial = undefined;
346
- }
347
- return this.data;
348
- }
349
- get size() {
350
- const size = this.backing().size;
351
- if (currentConsumer !== null) readProducer(this.sizeNode ??= createProducer(size));
352
- return size;
353
- }
354
- get [Symbol.toStringTag]() {
355
- return "ReactiveMap";
356
- }
357
- get(key) {
358
- return this.valuesByKey.read(key, this.backing().get(key));
359
- }
360
- has(key) {
361
- return this.existsByKey.read(key, this.backing().has(key));
362
- }
363
- set(key, value) {
364
- const data = this.backing();
365
- const previous = data.get(key);
366
- const existed = previous !== undefined || data.has(key);
367
- if (existed) {
368
- const equals = this.options.equals;
369
- if (equals == null || equals === Object.is ? Object.is(previous, value) : untracked(()=>equals(previous, value))) return this;
370
- }
371
- this.commitSet(data, key, value, existed);
372
- return this;
373
- }
374
- commitSet(data, key, value, existed) {
375
- transaction(()=>{
376
- data.set(key, value);
377
- this.valuesByKey.write(key, value);
378
- if (!existed) {
379
- this.existsByKey.write(key, true);
380
- if (this.sizeNode) writeProducer(this.sizeNode, data.size);
381
- if (this.keysNode) writeProducer(this.keysNode, this.keysNode.payload + 1);
382
- }
383
- if (this.valuesNode) writeProducer(this.valuesNode, this.valuesNode.payload + 1);
384
- });
385
- }
386
- delete(key) {
387
- const data = this.backing();
388
- if (!data.has(key)) return false;
389
- transaction(()=>{
390
- data.delete(key);
391
- this.valuesByKey.write(key, undefined);
392
- this.existsByKey.write(key, false);
393
- if (this.sizeNode) writeProducer(this.sizeNode, data.size);
394
- if (this.keysNode) writeProducer(this.keysNode, this.keysNode.payload + 1);
395
- if (this.valuesNode) writeProducer(this.valuesNode, this.valuesNode.payload + 1);
396
- });
397
- return true;
398
- }
399
- clear() {
400
- const data = this.backing();
401
- if (data.size === 0) return;
402
- transaction(()=>{
403
- data.clear();
404
- // Only materialized semantic locations need invalidation, even for a large map.
405
- this.valuesByKey.clear(undefined);
406
- this.existsByKey.clear(false);
407
- if (this.sizeNode) writeProducer(this.sizeNode, 0);
408
- if (this.keysNode) writeProducer(this.keysNode, this.keysNode.payload + 1);
409
- if (this.valuesNode) writeProducer(this.valuesNode, this.valuesNode.payload + 1);
410
- });
411
- }
412
- keys() {
413
- const data = this.backing();
414
- if (currentConsumer !== null) readProducer(this.keysNode ??= createProducer(0));
415
- return data.keys();
416
- }
417
- values() {
418
- const data = this.backing();
419
- if (currentConsumer !== null) readProducer(this.valuesNode ??= createProducer(0));
420
- return data.values();
421
- }
422
- entries() {
423
- const data = this.backing();
424
- if (currentConsumer !== null) readProducer(this.valuesNode ??= createProducer(0));
425
- return data.entries();
426
- }
427
- [Symbol.iterator]() {
428
- return this.entries();
429
- }
430
- forEach(callback, thisArg) {
431
- const data = this.backing();
432
- if (currentConsumer !== null) readProducer(this.valuesNode ??= createProducer(0));
433
- data.forEach((value, key)=>callback.call(thisArg, value, key, this));
434
- }
435
- collect() {
436
- this.valuesByKey.collect();
437
- this.existsByKey.collect();
438
- if (this.sizeNode?.firstOut === null) {
439
- disposeNode(this.sizeNode);
440
- this.sizeNode = undefined;
441
- }
442
- if (this.keysNode?.firstOut === null) {
443
- disposeNode(this.keysNode);
444
- this.keysNode = undefined;
445
- }
446
- if (this.valuesNode?.firstOut === null) {
447
- disposeNode(this.valuesNode);
448
- this.valuesNode = undefined;
449
- }
450
- }
451
- [Symbol.dispose]() {
452
- this.dispose();
453
- }
454
- dispose() {
455
- this.disposed = true;
456
- this.valuesByKey.dispose();
457
- this.existsByKey.dispose();
458
- if (this.sizeNode) disposeNode(this.sizeNode);
459
- if (this.keysNode) disposeNode(this.keysNode);
460
- if (this.valuesNode) disposeNode(this.valuesNode);
461
- this.sizeNode = this.keysNode = this.valuesNode = undefined;
462
- this.data = undefined;
463
- this.initial = undefined;
464
- }
465
- }
466
- /** A native Set-shaped membership collection over keyed reactive observations. */ class ReactiveSet {
467
- constructor(initial, options = {}){
468
- this.members = new ReactiveMap(()=>Array.from(typeof initial === "function" ? initial() : initial ?? [], (value)=>[
469
- value,
470
- true
471
- ]));
472
- setStoreName(this, options.name);
473
- storeControls.set(this, {
474
- raw: ()=>new Set(this.members.keys()),
475
- collect: ()=>this.collect(),
476
- dispose: ()=>this.dispose()
477
- });
478
- }
479
- get size() {
480
- return this.members.size;
481
- }
482
- get [Symbol.toStringTag]() {
483
- return "ReactiveSet";
484
- }
485
- has(value) {
486
- return this.members.has(value);
487
- }
488
- add(value) {
489
- this.members.set(value, true);
490
- return this;
491
- }
492
- delete(value) {
493
- return this.members.delete(value);
494
- }
495
- clear() {
496
- this.members.clear();
497
- }
498
- values() {
499
- return this.members.keys();
500
- }
501
- keys() {
502
- return this.values();
503
- }
504
- *entries() {
505
- for (const value of this.values())yield [
506
- value,
507
- value
508
- ];
509
- }
510
- [Symbol.iterator]() {
511
- return this.values();
512
- }
513
- forEach(callback, thisArg) {
514
- for (const value of this.values())callback.call(thisArg, value, value, this);
515
- }
516
- collect() {
517
- this.members.collect();
518
- }
519
- dispose() {
520
- this.members.dispose();
521
- }
522
- [Symbol.dispose]() {
523
- this.dispose();
524
- }
525
- }
526
- function reactiveSet(initial, options) {
527
- return new ReactiveSet(initial, options);
528
- }
529
- function createReactiveMap(initial, options) {
530
- return new ReactiveMap(initial, options);
531
- }
532
-
533
269
  /// <reference lib="esnext.disposable" />
534
270
  function withDispose(resource, name) {
535
271
  setStoreName(resource, name);
@@ -644,4 +380,4 @@ function createKeyedProjection(source, keyOf, project, options = {}) {
644
380
  }), options.name);
645
381
  }
646
382
 
647
- export { ReactiveMap as R, createSelector as a, ReactiveSet as b, createReactiveMap as c, createKeyedProjection as d, createStoreProjection as e, createDerivedProjection as f, reactiveSet as r, transaction as t };
383
+ export { createKeyedProjection as a, createStoreProjection as b, createSelector as c, createDerivedProjection as d };
@@ -8,4 +8,4 @@ function setStoreName(resource, name) {
8
8
  });
9
9
  }
10
10
 
11
- export { setStoreName as a, getStoreName as g, storeName as s };
11
+ export { storeName as a, getStoreName as g, setStoreName as s };
@@ -139,64 +139,4 @@ function disposeStore(store) {
139
139
  control.collect();
140
140
  }
141
141
 
142
- const MISSING = Symbol("selector.missing");
143
- function sameValue(prev, next) {
144
- return Object.is(prev, next);
145
- }
146
- function getMissing() {
147
- return MISSING;
148
- }
149
- function isObject(value) {
150
- return typeof value === "object" && value !== null;
151
- }
152
- function readProjectionPath(value, path) {
153
- let current = value;
154
- for(let index = 0; index < path.length; ++index){
155
- if (!isObject(current)) return undefined;
156
- current = current[path[index]];
157
- }
158
- return current;
159
- }
160
- function createStoreReaderProxy(readState, path = []) {
161
- return new Proxy(Object.create(null), {
162
- get (_target, prop) {
163
- if (prop === Symbol.toStringTag) return "ProjectionStore";
164
- const value = readProjectionPath(readState(), [
165
- ...path,
166
- prop
167
- ]);
168
- return isObject(value) ? createStoreReaderProxy(readState, [
169
- ...path,
170
- prop
171
- ]) : value;
172
- },
173
- has (_target, prop) {
174
- const parent = readProjectionPath(readState(), path);
175
- return isObject(parent) && prop in parent;
176
- },
177
- ownKeys () {
178
- const value = readProjectionPath(readState(), path);
179
- return isObject(value) ? Reflect.ownKeys(value) : [];
180
- },
181
- getOwnPropertyDescriptor (_target, prop) {
182
- const parent = readProjectionPath(readState(), path);
183
- if (!isObject(parent) || !(prop in parent)) {
184
- return undefined;
185
- }
186
- return {
187
- configurable: true,
188
- enumerable: true,
189
- value: parent[prop],
190
- writable: false
191
- };
192
- },
193
- set () {
194
- return false;
195
- },
196
- deleteProperty () {
197
- return false;
198
- }
199
- });
200
- }
201
-
202
- export { disposeStore as a, ref as b, collectStore as c, deep as d, shallow as e, depthOf as f, getStoreControl as g, cloneValue as h, isPlain as i, readProjectionPath as j, storeControls as k, isStructural as l, createStoreReaderProxy as m, getMissing as n, opaque as o, isObject as p, sameValue as q, raw as r, snapshot as s };
142
+ export { disposeStore as a, ref as b, collectStore as c, deep as d, shallow as e, cloneValue as f, storeControls as g, getStoreControl as h, isPlain as i, depthOf as j, isStructural as k, opaque as o, raw as r, snapshot as s };
@@ -1,4 +1,4 @@
1
1
  export { c as createStore } from './chunks/createStore-DHj16Ehk.js';
2
- export { C as CompiledStoreTransformError, c as compileStore, t as transformCompiledStore } from './chunks/compiler-CW_P8WsZ.js';
2
+ export { C as CompiledStoreTransformError, c as compileStore, t as transformCompiledStore } from './chunks/compiler-Dsb3E2ck.js';
3
3
  import 'util';
4
4
  import 'fs';
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  export { c as createStore } from './chunks/createStore-DHj16Ehk.js';
2
- export { a as action, d as derive, h as hydrate, l as leaf } from './chunks/hydrate-Bdtl9XyA.js';
3
- export { c as reactiveMap, a as selector } from './chunks/keyed-C-QvvUv4.js';
4
- export { o as opaque, s as snapshot } from './chunks/shared-BHHficW8.js';
2
+ export { a as action, d as derive, h as hydrate, l as leaf } from './chunks/hydrate-DMnHCI5q.js';
3
+ export { c as selector } from './chunks/keyed-CQKtL8a7.js';
4
+ export { c as reactiveMap } from './chunks/collections-yHy0wH0f.js';
5
+ export { o as opaque, s as snapshot } from './chunks/values-DCB6zyMz.js';
5
6
  import '@volynets/reflex-runtime/internal';
6
- import './chunks/names-BF36AyM3.js';
7
- import '@volynets/reflex';
7
+ import './chunks/names-Cx4YcvsH.js';
8
+ import './selectors/shared.js';
@@ -1,6 +1,6 @@
1
1
  import { currentConsumer, readProducer, createProducer, writeProducer, disposeNode } from '@volynets/reflex-runtime/internal';
2
2
  export * from '@volynets/reflex-runtime/internal';
3
- import { a as setStoreName } from '../chunks/names-BF36AyM3.js';
3
+ import { s as setStoreName } from '../chunks/names-Cx4YcvsH.js';
4
4
 
5
5
  /** Compiler target: a direct leaf address, materialized only by a tracked read. */ function createStoreCell(initial, options) {
6
6
  let value = initial;
package/dist/runtime.d.ts CHANGED
@@ -1,12 +1,16 @@
1
1
  /// <reference lib="esnext.disposable" />
2
- import type { Destructor, Accessor, AnyFn, EffectFn, EffectOptions, DirectValue, Updater, SetInput, Setter, ValueReadable, Writable, Disposable, SymbolDisposable, Readable, WritableReadable, Signal, Computed, Memo, Derived, Effect, Scan, Realtime, Stream, ReadableLike, WritableLike, ValueOf } from "./runtime/types.js";
3
- export * from '@volynets/reflex';
4
- export { Accessor, AnyFn, Computed, Derived, Destructor, DirectValue, Disposable, Effect, EffectFn, EffectOptions, Memo, Readable, ReadableLike, Realtime, Scan, SetInput, Setter, Signal, Stream, SymbolDisposable, Updater, ValueOf, ValueReadable, Writable, WritableLike, WritableReadable } from './runtime/types.js';
5
2
  import { S as StoreCell } from './types/internal-BIzJSPwN.js';
6
3
  export { c as createStoreCell } from './types/internal-BIzJSPwN.js';
7
4
  import { DisposableResource, Synchronous } from '@volynets/reflex-framework';
8
5
  import '@volynets/reflex-runtime/internal';
9
6
 
7
+ interface DisposableComputed<T> {
8
+ readonly read: () => T;
9
+ dispose(): void;
10
+ }
11
+ /** Owned lazy getter used by the store compiler. */
12
+ declare function createDisposableComputed<T>(fn: () => T): DisposableComputed<T>;
13
+
10
14
  type AnyFunction = (...args: never[]) => unknown;
11
15
  interface StoreScope {
12
16
  readonly disposed: boolean;
@@ -21,5 +25,5 @@ type StoreScopeValue<T extends object> = T & DisposableResource & {
21
25
  /** Compiler lifetime and mutation boundary over the shared framework lifecycle. */
22
26
  declare function createStoreScope<T extends object>(setup: (scope: StoreScope) => T): StoreScopeValue<T>;
23
27
 
24
- export { createStoreScope };
25
- export type { StoreScope, StoreScopeValue };
28
+ export { createDisposableComputed, createStoreScope };
29
+ export type { DisposableComputed, StoreScope, StoreScopeValue };
package/dist/runtime.js CHANGED
@@ -1,12 +1,22 @@
1
- import { batch } from '@volynets/reflex';
2
- export * from '@volynets/reflex';
3
1
  export { createStoreCell } from './runtime/internal.js';
2
+ import { createConsumer, disposeNode, readConsumerLazy, untracked, setCurrentConsumer, currentConsumer } from '@volynets/reflex-runtime/internal';
4
3
  import { LifecycleScope } from '@volynets/reflex-framework';
5
- import { untracked, setCurrentConsumer, currentConsumer } from '@volynets/reflex-runtime/internal';
6
- import './chunks/names-BF36AyM3.js';
4
+ import { t as transaction } from './chunks/collections-yHy0wH0f.js';
5
+ import './chunks/names-Cx4YcvsH.js';
6
+ import './chunks/values-DCB6zyMz.js';
7
+
8
+ /** Owned lazy getter used by the store compiler. */ function createDisposableComputed(fn) {
9
+ const node = createConsumer(fn);
10
+ return {
11
+ read: readConsumerLazy.bind(node),
12
+ dispose () {
13
+ disposeNode(node);
14
+ }
15
+ };
16
+ }
7
17
 
8
18
  /** Compiler lifetime and mutation boundary over the shared framework lifecycle. */ function createStoreScope(setup) {
9
- const lifecycle = new LifecycleScope((fn)=>batch(()=>untracked(fn)));
19
+ const lifecycle = new LifecycleScope((fn)=>transaction(()=>untracked(fn)));
10
20
  const assertOpen = ()=>{
11
21
  if (lifecycle.disposed) throw new Error("Cannot use a disposed compiled store scope");
12
22
  };
@@ -39,7 +49,7 @@ import './chunks/names-BF36AyM3.js';
39
49
  const previous = pending;
40
50
  pending = value;
41
51
  try {
42
- batch(commit);
52
+ transaction(commit);
43
53
  return value;
44
54
  } finally{
45
55
  pending = previous;
@@ -51,7 +61,7 @@ import './chunks/names-BF36AyM3.js';
51
61
  if (Object.prototype.toString.call(callback) === "[object AsyncFunction]") throw new TypeError("Store actions require a synchronous callback");
52
62
  return function(...args) {
53
63
  assertOpen();
54
- return batch(()=>untracked(()=>{
64
+ return transaction(()=>untracked(()=>{
55
65
  const result = Reflect.apply(callback, this, args);
56
66
  if (result !== null && (typeof result === "object" || typeof result === "function") && typeof Reflect.get(result, "then") === "function") throw new TypeError("Store actions cannot return a promise");
57
67
  return result;
@@ -75,4 +85,4 @@ import './chunks/names-BF36AyM3.js';
75
85
  }
76
86
  }
77
87
 
78
- export { createStoreScope };
88
+ export { createDisposableComputed, createStoreScope };
@@ -1,9 +1,10 @@
1
- import { d as createKeyedProjection, e as createStoreProjection } from '../chunks/keyed-C-QvvUv4.js';
2
- export { a as createSelector } from '../chunks/keyed-C-QvvUv4.js';
1
+ import { a as createKeyedProjection, b as createStoreProjection } from '../chunks/keyed-CQKtL8a7.js';
2
+ export { c as createSelector } from '../chunks/keyed-CQKtL8a7.js';
3
3
  import '@volynets/reflex-runtime/internal';
4
- import '../chunks/shared-BHHficW8.js';
5
- import '../chunks/names-BF36AyM3.js';
6
- import '@volynets/reflex';
4
+ import '../chunks/values-DCB6zyMz.js';
5
+ import '../chunks/names-Cx4YcvsH.js';
6
+ import './shared.js';
7
+ import '../chunks/collections-yHy0wH0f.js';
7
8
 
8
9
  function createProjection(sourceOrProject, keyOrSeed, projectOrOptions, options) {
9
10
  if (typeof keyOrSeed === "function" && typeof projectOrOptions === "function") {
@@ -1,2 +1,64 @@
1
- export { h as cloneProjectionValue, m as createStoreReaderProxy, n as getMissing, p as isObject, j as readProjectionPath, q as sameValue } from '../chunks/shared-BHHficW8.js';
1
+ export { f as cloneProjectionValue } from '../chunks/values-DCB6zyMz.js';
2
2
  import '@volynets/reflex-runtime/internal';
3
+
4
+ const MISSING = Symbol("selector.missing");
5
+ function sameValue(prev, next) {
6
+ return Object.is(prev, next);
7
+ }
8
+ function getMissing() {
9
+ return MISSING;
10
+ }
11
+ function isObject(value) {
12
+ return typeof value === "object" && value !== null;
13
+ }
14
+ function readProjectionPath(value, path) {
15
+ let current = value;
16
+ for(let index = 0; index < path.length; ++index){
17
+ if (!isObject(current)) return undefined;
18
+ current = current[path[index]];
19
+ }
20
+ return current;
21
+ }
22
+ function createStoreReaderProxy(readState, path = []) {
23
+ return new Proxy(Object.create(null), {
24
+ get (_target, prop) {
25
+ if (prop === Symbol.toStringTag) return "ProjectionStore";
26
+ const value = readProjectionPath(readState(), [
27
+ ...path,
28
+ prop
29
+ ]);
30
+ return isObject(value) ? createStoreReaderProxy(readState, [
31
+ ...path,
32
+ prop
33
+ ]) : value;
34
+ },
35
+ has (_target, prop) {
36
+ const parent = readProjectionPath(readState(), path);
37
+ return isObject(parent) && prop in parent;
38
+ },
39
+ ownKeys () {
40
+ const value = readProjectionPath(readState(), path);
41
+ return isObject(value) ? Reflect.ownKeys(value) : [];
42
+ },
43
+ getOwnPropertyDescriptor (_target, prop) {
44
+ const parent = readProjectionPath(readState(), path);
45
+ if (!isObject(parent) || !(prop in parent)) {
46
+ return undefined;
47
+ }
48
+ return {
49
+ configurable: true,
50
+ enumerable: true,
51
+ value: parent[prop],
52
+ writable: false
53
+ };
54
+ },
55
+ set () {
56
+ return false;
57
+ },
58
+ deleteProperty () {
59
+ return false;
60
+ }
61
+ });
62
+ }
63
+
64
+ export { createStoreReaderProxy, getMissing, isObject, readProjectionPath, sameValue };
package/dist/store.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { c as createStore } from './chunks/createStore-DHj16Ehk.js';
2
- export { C as CompiledStoreTransformError, c as compileStore, t as transformCompiledStore } from './chunks/compiler-CW_P8WsZ.js';
2
+ export { C as CompiledStoreTransformError, c as compileStore, t as transformCompiledStore } from './chunks/compiler-Dsb3E2ck.js';
3
3
  import 'util';
4
4
  import 'fs';
package/dist/vite.d.ts CHANGED
@@ -39,7 +39,7 @@ interface ReflexStoreVitePluginOptions {
39
39
  /**
40
40
  * Runtime module used by generated code.
41
41
  *
42
- * @default "@volynets/reflex"
42
+ * @default "@volynets/reflex-store/runtime"
43
43
  */
44
44
  runtimeModule?: string;
45
45
  eraseFacade?: boolean;
package/dist/vite.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as compileStore, C as CompiledStoreTransformError } from './chunks/compiler-CW_P8WsZ.js';
1
+ import { c as compileStore, C as CompiledStoreTransformError } from './chunks/compiler-Dsb3E2ck.js';
2
2
  import 'util';
3
3
  import 'fs';
4
4
 
@@ -0,0 +1,33 @@
1
+ // Application wiring for this example; the store does not own a host runtime.
2
+ import {
3
+ createRuntimeContext,
4
+ createWatcher,
5
+ disposeWatcher,
6
+ runWatcher,
7
+ switchRuntimeContext,
8
+ } from "@volynets/reflex-runtime/internal";
9
+ import {
10
+ createRuntimeSchedulerBinding,
11
+ resolveEffectSchedulerMode,
12
+ type EffectStrategy,
13
+ } from "@volynets/reflex-scheduler";
14
+
15
+ export function createRuntime({
16
+ effectStrategy = "eager",
17
+ }: { effectStrategy?: EffectStrategy } = {}) {
18
+ const context = createRuntimeContext();
19
+ const scheduler = createRuntimeSchedulerBinding(
20
+ resolveEffectSchedulerMode(effectStrategy),
21
+ context,
22
+ );
23
+ context.nodeInvalidatedHook = scheduler.onNodeInvalidated;
24
+ context.hostFlushHook = scheduler.onHostFlush;
25
+ switchRuntimeContext(context);
26
+ return { flush: scheduler.flush };
27
+ }
28
+
29
+ export function effect(callback: () => void | (() => void)): () => void {
30
+ const node = createWatcher(callback);
31
+ runWatcher(node);
32
+ return () => disposeWatcher(node);
33
+ }
@@ -1,4 +1,4 @@
1
- import { createRuntime, effect } from "@volynets/reflex-store/runtime";
1
+ import { createRuntime, effect } from "./reactivity";
2
2
  import {
3
3
  action,
4
4
  createStore,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volynets/reflex-store",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "description": "State management primitives for Reflex",
6
6
  "license": "MIT",
@@ -47,10 +47,6 @@
47
47
  "./runtime/core": {
48
48
  "types": "./dist/runtime/core.d.ts",
49
49
  "import": "./dist/runtime/core.js"
50
- },
51
- "./runtime/types": {
52
- "types": "./dist/runtime/types.d.ts",
53
- "import": "./dist/runtime/types.js"
54
50
  }
55
51
  },
56
52
  "files": [
@@ -79,7 +75,7 @@
79
75
  "test:dev": "vitest run --config vite.dev.config.ts",
80
76
  "test:differential": "vitest run --config vite.config.ts tests/compiler.differential.test.ts tests/runtime.differential.test.ts",
81
77
  "test:integration": "vitest run --config vite.config.ts tests/store.integration.test.ts tests/vite-user-dx.test.ts tests/task-board",
82
- "test:packed-runtime": "pnpm --filter @volynets/reflex build:all && pnpm --filter @volynets/reflex-framework build && pnpm build && node scripts/packed-runtime-identity.mjs",
78
+ "test:packed-runtime": "pnpm build:all && node scripts/packed-runtime-identity.mjs",
83
79
  "build:all": "node ../../tooling/build/run.mjs @volynets/reflex-store",
84
80
  "check:artifacts": "node ../../tooling/build/verify-artifacts.mjs --directory .",
85
81
  "prepack": "pnpm build && pnpm check:artifacts"
@@ -92,7 +88,6 @@
92
88
  "@swc/core": "^1.15.18",
93
89
  "@swc/wasm": "^1.16.13",
94
90
  "@types/node": "^26.1.2",
95
- "@volynets/reflex": "workspace:^",
96
91
  "@volynets/reflex-runtime": "workspace:*",
97
92
  "@volynets/reflex-scheduler": "workspace:^",
98
93
  "rollup": "^4.54.0",
@@ -119,9 +114,8 @@
119
114
  "node": ">=20.19.0"
120
115
  },
121
116
  "peerDependencies": {
122
- "@volynets/reflex": "^1.0.0",
123
- "@volynets/reflex-runtime": "^1.0.0",
124
- "@volynets/reflex-framework": "^0.1.3"
117
+ "@volynets/reflex-runtime": "^1.0.1",
118
+ "@volynets/reflex-framework": "^0.1.4"
125
119
  },
126
120
  "private": false
127
121
  }
@@ -1,45 +0,0 @@
1
- type Destructor = () => void;
2
- type Accessor<T> = () => T;
3
- type AnyFn = (...args: never[]) => unknown;
4
- type EffectFn = () => void | Destructor;
5
- interface EffectOptions {
6
- priority?: number;
7
- }
8
- type DirectValue<T> = T extends AnyFn ? never : T;
9
- type Updater<T> = (previous: T) => T;
10
- type SetInput<T> = DirectValue<T> | Updater<T>;
11
- type Setter<T> = undefined extends T ? {
12
- (): T;
13
- (input: SetInput<T>): T;
14
- } : {
15
- (input: SetInput<T>): T;
16
- };
17
- interface ValueReadable<T> {
18
- readonly value: T;
19
- }
20
- interface Writable<T> {
21
- set: Setter<T>;
22
- }
23
- interface Disposable {
24
- (): void;
25
- }
26
- interface SymbolDisposable {
27
- [Symbol.dispose](): void;
28
- }
29
- type Readable<T> = Accessor<T> & ValueReadable<T>;
30
- type WritableReadable<T> = Readable<T> & Writable<T>;
31
- type Signal<T> = Accessor<T> & Writable<T>;
32
- type Computed<T> = Readable<T>;
33
- type Memo<T> = Readable<T>;
34
- type Derived<T> = Readable<T>;
35
- type Effect<T = void> = Readable<T> & Disposable & Partial<SymbolDisposable>;
36
- type Scan<T> = Readable<T> & Disposable & Partial<SymbolDisposable>;
37
- type Realtime<T> = WritableReadable<T> & {
38
- subscribe(callback: () => void): () => void;
39
- };
40
- type Stream<T> = WritableReadable<T> & AsyncIterable<T>;
41
- type ReadableLike<T> = Signal<T> | Computed<T> | Memo<T> | Derived<T> | Realtime<T> | Stream<T>;
42
- type WritableLike<T> = Signal<T> | Realtime<T> | Stream<T>;
43
- type ValueOf<T> = T extends Accessor<infer V> ? V : T extends ValueReadable<infer V> ? V : never;
44
-
45
- export type { Accessor, AnyFn, Computed, Derived, Destructor, DirectValue, Disposable, Effect, EffectFn, EffectOptions, Memo, Readable, ReadableLike, Realtime, Scan, SetInput, Setter, Signal, Stream, SymbolDisposable, Updater, ValueOf, ValueReadable, Writable, WritableLike, WritableReadable };
@@ -1 +0,0 @@
1
-