@ersbeth/picoflow 2.3.1 → 3.0.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.
Files changed (70) hide show
  1. package/README.md +37 -12
  2. package/SKILL.md +130 -16
  3. package/dist/index.d.ts +767 -0
  4. package/dist/index.js +544 -0
  5. package/dist/inspect.d.ts +252 -0
  6. package/dist/inspect.js +300 -0
  7. package/dist/shared.d.ts +361 -0
  8. package/dist/shared.js +1496 -0
  9. package/dist/shared2.d.ts +93 -0
  10. package/dist/shared2.js +59 -0
  11. package/dist/shared3.d.ts +54 -0
  12. package/dist/shared3.js +17 -0
  13. package/dist/{types/converters/solid.d.ts → solid.d.ts} +10 -8
  14. package/dist/solid.js +63 -0
  15. package/package.json +38 -34
  16. package/dist/picoflow.js +0 -1283
  17. package/dist/types/api/base/flowConfig.d.ts +0 -17
  18. package/dist/types/api/base/flowDisposable.d.ts +0 -40
  19. package/dist/types/api/base/flowErrors.d.ts +0 -1
  20. package/dist/types/api/base/flowObservable.d.ts +0 -26
  21. package/dist/types/api/base/flowPrimitiveOptions.d.ts +0 -14
  22. package/dist/types/api/base/flowSubscribable.d.ts +0 -78
  23. package/dist/types/api/base/flowTracker.d.ts +0 -7
  24. package/dist/types/api/base/index.d.ts +0 -7
  25. package/dist/types/api/index.d.ts +0 -2
  26. package/dist/types/api/nodes/async/flowConstantAsync.d.ts +0 -32
  27. package/dist/types/api/nodes/async/flowDerivationAsync.d.ts +0 -37
  28. package/dist/types/api/nodes/async/flowStateAsync.d.ts +0 -42
  29. package/dist/types/api/nodes/async/flowWritableDerivationAsync.d.ts +0 -31
  30. package/dist/types/api/nodes/async/index.d.ts +0 -4
  31. package/dist/types/api/nodes/collections/flowArray.d.ts +0 -138
  32. package/dist/types/api/nodes/collections/flowMap.d.ts +0 -100
  33. package/dist/types/api/nodes/collections/index.d.ts +0 -2
  34. package/dist/types/api/nodes/flowEffect.d.ts +0 -28
  35. package/dist/types/api/nodes/flowSignal.d.ts +0 -26
  36. package/dist/types/api/nodes/flowValue.d.ts +0 -35
  37. package/dist/types/api/nodes/index.d.ts +0 -7
  38. package/dist/types/api/nodes/sync/flowConstant.d.ts +0 -30
  39. package/dist/types/api/nodes/sync/flowDerivation.d.ts +0 -37
  40. package/dist/types/api/nodes/sync/flowState.d.ts +0 -40
  41. package/dist/types/api/nodes/sync/flowWritableDerivation.d.ts +0 -29
  42. package/dist/types/api/nodes/sync/index.d.ts +0 -4
  43. package/dist/types/api/nodes/utils.d.ts +0 -22
  44. package/dist/types/base/dependenciesRegistry.d.ts +0 -1
  45. package/dist/types/base/dependentsRegistry.d.ts +0 -1
  46. package/dist/types/base/disposable.d.ts +0 -15
  47. package/dist/types/base/errors.d.ts +0 -31
  48. package/dist/types/base/executionStack.d.ts +0 -31
  49. package/dist/types/base/index.d.ts +0 -8
  50. package/dist/types/base/node.d.ts +0 -27
  51. package/dist/types/base/observable.d.ts +0 -34
  52. package/dist/types/base/observer.d.ts +0 -33
  53. package/dist/types/converters/index.d.ts +0 -1
  54. package/dist/types/index.d.ts +0 -2
  55. package/dist/types/nodes/actionNode.d.ts +0 -1
  56. package/dist/types/nodes/arrayNode.d.ts +0 -1
  57. package/dist/types/nodes/effectNode.d.ts +0 -1
  58. package/dist/types/nodes/index.d.ts +0 -8
  59. package/dist/types/nodes/mapNode.d.ts +0 -1
  60. package/dist/types/nodes/signalNode.d.ts +0 -1
  61. package/dist/types/nodes/valueAsyncNode.d.ts +0 -1
  62. package/dist/types/nodes/valueNode.d.ts +0 -1
  63. package/dist/types/nodes/valueSyncNode.d.ts +0 -1
  64. package/dist/types/schedulers/asyncResolver.d.ts +0 -1
  65. package/dist/types/schedulers/asyncScheduler.d.ts +0 -1
  66. package/dist/types/schedulers/index.d.ts +0 -4
  67. package/dist/types/schedulers/pendingError.d.ts +0 -1
  68. package/dist/types/schedulers/scheduler.d.ts +0 -1
  69. package/dist/types/schedulers/syncResolver.d.ts +0 -1
  70. package/dist/types/schedulers/syncScheduler.d.ts +0 -1
@@ -0,0 +1,767 @@
1
+ /// <reference lib="esnext.disposable" preserve="true" />
2
+ import { _ as isDisposable, a as FlowOnDataListener, c as FlowSubscribable, d as FlowEffect, f as FlowEffectOptions, g as FlowDisposable, h as ObserverStatus, i as FlowDataTracker, l as FlowTracker, m as ObservableStatus, n as FlowValue, o as FlowOnErrorListener, p as subscribe, r as FlowObservable, s as FlowOnPendingListener, t as FlowSnapshot, u as tracker } from "./shared.js";
3
+ import { i as FlowPrimitiveOptions, n as signal, r as FlowEquals, t as FlowSignal } from "./shared2.js";
4
+ import { n as NotPromise, r as PromiseNotAllowed, t as FlowReadonly } from "./shared3.js";
5
+ //#region src/core/api/base/flowConfig.d.ts
6
+ /**
7
+ * Installs a global handler for errors that escape the reactive flush.
8
+ *
9
+ * All reactive work — recomputing derivations, running effects — happens inside an
10
+ * asynchronous flush. Without this hook, an error escaping the flush (an effect callback
11
+ * that throws with no `onError`, or a feedback loop between two effects) becomes an
12
+ * uncaught exception, which terminates a Node process. Installing a handler here makes
13
+ * that error catchable instead.
14
+ *
15
+ * Defaults to `console.error`. The handler replaces any previously installed handler —
16
+ * it is not additive.
17
+ *
18
+ * @param handler - Called with the error that escaped the flush.
19
+ *
20
+ * @public
21
+ */
22
+ export declare function onFlushError(handler: (error: unknown) => void): void;
23
+ /**
24
+ * Returns the scheduler to its just-started state: both queues emptied, any scheduled flush
25
+ * cancelled, and the flush error handler back to its `console.error` default.
26
+ *
27
+ * Scheduling is process-global, so reactive work left over from one test can still be waiting when
28
+ * the next one starts, and a handler installed with {@link onFlushError} stays installed. Calling
29
+ * this from an `afterEach` gives each test a clean scheduler. It is the supported alternative to
30
+ * reaching into internals, and applications testing their own code need it for the same reason
31
+ * PicoFlow's own suite does.
32
+ *
33
+ * Queued work is **discarded, not run** — this cancels pending reactivity rather than flushing it.
34
+ * Primitives created before the call stay usable, but any recomputation that was waiting is lost:
35
+ * those nodes only recompute once something notifies them again. To let pending work complete
36
+ * instead, `await` a value with `pick()`.
37
+ *
38
+ * @public
39
+ */
40
+ export declare function reset(): void;
41
+ //#endregion
42
+ //#region src/core/base/errors.d.ts
43
+ /**
44
+ * Base class for picoflow's typed errors, so a consumer can `catch` one with a single
45
+ * `instanceof PicoFlowError` check instead of matching on message text. Every throw the library
46
+ * raises is one of its subclasses, and every message carries the `[PicoFlow]` prefix.
47
+ *
48
+ * It is never thrown directly: catch it to handle any picoflow failure, and narrow to a subclass to
49
+ * tell one kind from another.
50
+ * @public
51
+ */
52
+ export declare class PicoFlowError extends Error {
53
+ constructor(message: string);
54
+ }
55
+ /**
56
+ * Thrown when a disposed primitive (or its underlying scheduler) is read, written, or otherwise
57
+ * used after `dispose()`.
58
+ * @public
59
+ */
60
+ export declare class PicoFlowDisposedError extends PicoFlowError {
61
+ constructor(message: string);
62
+ }
63
+ /**
64
+ * Thrown when the reactive flush detects a feedback loop that exceeds the maximum step guard.
65
+ * @public
66
+ */
67
+ export declare class PicoFlowCycleError extends PicoFlowError {
68
+ constructor(message: string);
69
+ }
70
+ /**
71
+ * Thrown when a node reaches a state its own implementation considers unreachable. Reaching this
72
+ * indicates a picoflow bug rather than a misuse of the public API.
73
+ * @public
74
+ */
75
+ export declare class PicoFlowInternalError extends PicoFlowError {
76
+ constructor(message: string);
77
+ }
78
+ /**
79
+ * Thrown when a documented precondition of a public method is violated by the caller: a collection
80
+ * operation naming an entry that does not exist (or, for `add`, one that already does), and
81
+ * `from()`'s check on the value it was handed. Reaching this indicates a misuse of the API rather
82
+ * than a picoflow bug, and the call had no effect (#123).
83
+ * @public
84
+ */
85
+ export declare class PicoFlowPreconditionError extends PicoFlowError {
86
+ constructor(message: string);
87
+ }
88
+ //#endregion
89
+ //#region src/core/api/nodes/async/flowConstantAsync.d.ts
90
+ /**
91
+ * Function that produces a value asynchronously, the first time it is needed.
92
+ *
93
+ * The async counterpart of {@link InitFunction}: it takes no arguments, registers no dependency and
94
+ * runs once. While the promise is in flight the primitive's status is `"pending"`.
95
+ *
96
+ * @public
97
+ */
98
+ export type InitFunctionAsync<T> = () => Promise<T>;
99
+ /**
100
+ * Read-only reactive value that resolves once from a promise or async initializer.
101
+ *
102
+ * Async constants provide lazy initialization for asynchronous values. The promise or async initializer
103
+ * runs once on first access, and the resolved value is cached forever. While pending, accessing the value
104
+ * throws PendingError. Use for async operations that only need to run once, such as loading remote configuration,
105
+ * fetching initial data, or computing expensive async resources.
106
+ *
107
+ * @public
108
+ */
109
+ export interface FlowConstantAsync<T> extends FlowValue<T> {}
110
+ /**
111
+ * Creates a constant reactive value from a promise or async initializer that resolves once and never recomputes.
112
+ *
113
+ * The promise or async initializer executes once on first access, and the resolved value is cached permanently.
114
+ * While the promise is pending, any reactive computation that accesses the value will receive PendingError and
115
+ * automatically retry once the promise resolves. Use for one-time async operations that don't depend on other
116
+ * reactive values, such as loading configuration or fetching initial data.
117
+ *
118
+ * @param value - Promise to resolve, or async function that returns a promise on first access
119
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the default `===` change detection
120
+ * @returns A FlowConstantAsync that provides read-only access to the resolved value
121
+ *
122
+ * @public
123
+ */
124
+ export declare function constantAsync<T>(value: Promise<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowConstantAsync<T>;
125
+ export declare function constantAsync<T>(initializer: InitFunctionAsync<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowConstantAsync<T>;
126
+ //#endregion
127
+ //#region src/core/api/nodes/async/flowDerivationAsync.d.ts
128
+ /**
129
+ * Function that derives a value asynchronously from its dependencies, and optionally from the value
130
+ * it last produced.
131
+ *
132
+ * The async counterpart of {@link DerivationFunction}, with the same tracking rules. Read every
133
+ * dependency through the `tracker` *before* the first `await`: reads after it happen outside the
134
+ * tracked turn and register nothing.
135
+ *
136
+ * @public
137
+ */
138
+ export type DerivationFunctionAsync<T> = (tracker: FlowTracker, previous?: NotPromise<T>) => Promise<T>;
139
+ /**
140
+ * Read-only reactive value that recomputes asynchronously when dependencies change.
141
+ *
142
+ * Async derivations track reactive values accessed during computation and automatically recompute when any
143
+ * tracked dependency changes. The compute function returns a promise, and the resolved value is cached until
144
+ * dependencies change. While recomputing, accessing the value throws PendingError. Use for values derived from
145
+ * async operations like API calls, database queries, or any computation that depends on reactive state and
146
+ * requires async work.
147
+ *
148
+ * @public
149
+ */
150
+ export interface FlowDerivationAsync<T> extends FlowValue<T> {
151
+ /**
152
+ * Forces the derivation to recompute even if dependencies haven't changed.
153
+ */
154
+ refresh(): void;
155
+ }
156
+ /**
157
+ * Creates an async derived value that automatically recomputes when dependencies change.
158
+ *
159
+ * The async compute function tracks dependencies and returns a promise. When any tracked dependency changes,
160
+ * the function runs again and returns a new promise. The resolved value is cached until the next change.
161
+ * While the promise is pending, reactive computations that access this value receive PendingError and automatically
162
+ * retry once resolved. Use for derived data from async sources like filtered API results or computed database queries.
163
+ *
164
+ * @param compute - Async function that accesses dependencies and returns a promise of the derived value
165
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the
166
+ * default `===` change detection, `eager` recomputes on dirty instead of on read (#118)
167
+ * @returns A FlowDerivationAsync that provides read-only access to the resolved computed value
168
+ *
169
+ * @public
170
+ */
171
+ export declare function derivationAsync<T>(compute: DerivationFunctionAsync<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowDerivationAsync<T>;
172
+ //#endregion
173
+ //#region src/core/api/nodes/async/flowStateAsync.d.ts
174
+ /**
175
+ * Function that derives the next value asynchronously from the current one, for {@link FlowStateAsync.update}.
176
+ *
177
+ * `previous` is always a real value: `update()` waits for the node to settle before calling it, and
178
+ * never calls it while the node holds an error (A2-TYPE-1, #43).
179
+ *
180
+ * @public
181
+ */
182
+ export type UpdateFunctionAsync<T> = (previous: NotPromise<T>) => Promise<T>;
183
+ /**
184
+ * Writable reactive value that resolves promises and can be updated with new promises.
185
+ *
186
+ * Async state is the async equivalent of regular state. Unlike sync state, it accepts promises instead of
187
+ * direct values. Set new promises or async updater functions to update the state. While a promise is pending,
188
+ * accessing the value throws PendingError. Use for async data that changes imperatively, such as user-triggered
189
+ * API calls, async form submissions, or any async operation that updates based on user actions.
190
+ *
191
+ * @public
192
+ */
193
+ export interface FlowStateAsync<T> extends FlowValue<T> {
194
+ /**
195
+ * Replaces the value with a new promise and notifies all dependents immediately (they receive
196
+ * PendingError until it resolves).
197
+ *
198
+ * A replacement never looks at the current value: it applies while the node holds an error
199
+ * (`set()` is how an errored state is recovered) and while a previous promise is still in
200
+ * flight, which is then discarded. The one case where it is held back is a node waiting on a
201
+ * pending dependency (an async writable derivation mid-flight): it is then applied once that
202
+ * computation settles, so the settling computation cannot overwrite it afterwards.
203
+ *
204
+ * @param promise - New promise to resolve
205
+ */
206
+ set(promise: Promise<T>): void;
207
+ /**
208
+ * Derives the next value from the current one and notifies all dependents immediately (they
209
+ * receive PendingError until the updater's promise resolves).
210
+ *
211
+ * The updater receives the *stabilised* current value: if the node has not computed yet it is
212
+ * computed first; if a computation or a previous `set()` is in flight, the updater waits for it
213
+ * and applies on its result — dependents never observe the intermediate value. Several queued
214
+ * updates compose in call order, and a later `set()` discards updates queued before it.
215
+ *
216
+ * An errored node is left in error and the updater is never called — deriving from a value that
217
+ * does not exist propagates the error; use `set()` to recover.
218
+ *
219
+ * An updater that throws does not throw back at the caller, whatever the node's status when the
220
+ * call was made: it fails the node with that error, which then surfaces on the next read and in
221
+ * `subscribe`'s `onError`. The previous value is still what `latest` reports, and a `set()`
222
+ * recovers the node as it does from any other failure.
223
+ *
224
+ * @param updater - Async function that receives the current value and returns a promise of the next one
225
+ */
226
+ update(updater: UpdateFunctionAsync<T>): void;
227
+ /**
228
+ * Notifies all dependents without changing the value.
229
+ *
230
+ * Every dependent is queued for the next flush and re-runs, even though `===` change detection
231
+ * would have found nothing to report. It is the escape hatch for a change the reactive system
232
+ * cannot see — a value mutated in place, or an external source the graph does not model — and
233
+ * `signal()` is usually the better answer to both.
234
+ *
235
+ * Declared on the writable primitives only: forcing a subtree to re-run is a write, whatever it
236
+ * leaves the value at, so `constant()` and `derivation()` do not carry it (A3-ARCH-1, #132). On a
237
+ * derivation, `refresh()` is the read-side counterpart — it recomputes, and notifies only if the
238
+ * result actually changed.
239
+ */
240
+ trigger(): void;
241
+ }
242
+ /**
243
+ * Creates a mutable async reactive state that resolves promises and can be updated imperatively.
244
+ *
245
+ * State can be initialized with a direct promise or a lazy async initializer function. Update the state by
246
+ * calling `set()` with a new promise or an async updater function. Changes propagate automatically to all
247
+ * reactive computations that depend on this state. Use for async data that changes through user actions or
248
+ * application logic, such as loading user profiles, fetching search results, or any async state updates.
249
+ *
250
+ * @param value - Initial promise to resolve, or lazy async initializer function
251
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the default `===` change detection
252
+ * @returns A FlowStateAsync that can be read and modified with promises
253
+ *
254
+ * @public
255
+ */
256
+ export declare function stateAsync<T>(value: Promise<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowStateAsync<T>;
257
+ export declare function stateAsync<T>(initializer: InitFunctionAsync<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowStateAsync<T>;
258
+ //#endregion
259
+ //#region src/core/api/nodes/async/flowWritableDerivationAsync.d.ts
260
+ /**
261
+ * Writable reactive value that recomputes asynchronously when dependencies change, but can be manually overridden.
262
+ *
263
+ * Async writable derivations combine reactive async computation with manual control. They track dependencies and
264
+ * recompute asynchronously like regular async derivations, but you can also call `set()` to override the computed
265
+ * value with a new promise. While recomputing or pending, accessing the value throws PendingError. Use for computed
266
+ * async values that users can edit, such as formatted async fields, calculated async totals that can be adjusted,
267
+ * or any async value that is usually derived but sometimes needs manual correction.
268
+ *
269
+ * @public
270
+ */
271
+ export interface FlowWritableDerivationAsync<T> extends FlowStateAsync<T>, FlowDerivationAsync<T> {}
272
+ /**
273
+ * Creates an async derived value that recomputes automatically but can also be manually overridden.
274
+ *
275
+ * The async compute function tracks dependencies and returns a promise. When any tracked dependency changes,
276
+ * the function runs again and returns a new promise. However, you can also call `set()` to override the computed
277
+ * value with a new promise. Use for async values that are normally derived but need occasional manual adjustments,
278
+ * such as editable async calculated fields or user-correctable async totals.
279
+ *
280
+ * @param compute - Async function that accesses dependencies and returns a promise of the derived value
281
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the
282
+ * default `===` change detection, `eager` recomputes on dirty instead of on read (#118)
283
+ * @returns A FlowWritableDerivationAsync that provides both reactive async computation and manual control
284
+ *
285
+ * @public
286
+ */
287
+ export declare function writableDerivationAsync<T>(compute: DerivationFunctionAsync<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowWritableDerivationAsync<T>;
288
+ //#endregion
289
+ //#region src/core/api/nodes/sync/flowConstant.d.ts
290
+ /**
291
+ * Function that produces a value the first time it is needed.
292
+ *
293
+ * Takes no arguments: an initializer is not a computation, so it registers no dependency and never
294
+ * re-runs. Use `derivation()` for a value that has to follow its sources.
295
+ *
296
+ * @public
297
+ */
298
+ export type InitFunction<T> = () => NotPromise<T>;
299
+ /**
300
+ * Read-only reactive value that computes once on initialization and never changes.
301
+ *
302
+ * Constants provide lazy initialization - the value isn't computed until first accessed via `get()` or `pick()`.
303
+ * Once computed, the value is cached forever. Use constants for expensive computations that only need to run once,
304
+ * such as loading configuration, computing static lookups, or initializing resources.
305
+ *
306
+ * @public
307
+ */
308
+ export interface FlowConstant<T> extends FlowValue<T> {}
309
+ /**
310
+ * Creates a constant reactive value that initializes lazily and never recomputes.
311
+ *
312
+ * The initializer function runs once on first access, and the result is cached permanently.
313
+ * Unlike state or derivations, constants never react to changes - they represent immutable values
314
+ * in the reactive graph. Useful for expensive one-time computations or static configuration.
315
+ *
316
+ * @param initializer - Function that computes the constant value on first access
317
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the default `===` change detection
318
+ * @returns A FlowConstant that provides read-only access to the cached value
319
+ *
320
+ * @public
321
+ */
322
+ export declare function constant<T>(initializer: InitFunction<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowConstant<T>;
323
+ //#endregion
324
+ //#region src/core/api/nodes/sync/flowState.d.ts
325
+ /**
326
+ * Function that derives the next value from the current one, for {@link FlowState.update}.
327
+ *
328
+ * `previous` is always a real value: `update()` waits for the node to settle before calling it, and
329
+ * never calls it while the node holds an error (A2-TYPE-1, #43).
330
+ *
331
+ * @public
332
+ */
333
+ export type UpdateFunction<T> = (previous: NotPromise<T>) => NotPromise<T>;
334
+ /**
335
+ * Writable reactive value that can be updated manually and notifies dependents on changes.
336
+ *
337
+ * State is the simplest writable reactive primitive. Unlike derivations, it has no dependencies and never
338
+ * recomputes automatically - changes only occur when you explicitly call `set()`. Use state for user input,
339
+ * application state, or any data that changes imperatively. Changes propagate automatically to all dependents.
340
+ *
341
+ * @public
342
+ */
343
+ export interface FlowState<T> extends FlowValue<T> {
344
+ /**
345
+ * Replaces the value and notifies all dependents.
346
+ *
347
+ * A replacement never looks at the current value, so it applies even while the node holds an
348
+ * error — `set()` is how an errored state is recovered. It applies immediately, except when the
349
+ * node is waiting on a pending dependency (a writable derivation mid-flight): it is then held
350
+ * until that computation settles, so the settling computation cannot overwrite it afterwards.
351
+ * On a writable derivation that was never read, the computation runs first so its dependencies
352
+ * are tracked; the override still applies, until the next dependency change (#109).
353
+ *
354
+ * @param value - New value to set
355
+ */
356
+ set(value: NotPromise<T>): void;
357
+ /**
358
+ * Derives the next value from the current one and notifies all dependents.
359
+ *
360
+ * The updater receives the *stabilised* current value: if the node has not computed yet (a lazy
361
+ * initializer, a derivation never read) it is computed first; if a computation or a previous
362
+ * `set()` is in flight, the updater waits for it and applies on its result. Several queued
363
+ * updates compose in call order, and a later `set()` discards updates queued before it.
364
+ *
365
+ * An errored node is left in error and the updater is never called — deriving from a value that
366
+ * does not exist propagates the error; use `set()` to recover.
367
+ *
368
+ * An updater that throws does not throw back at the caller, whatever the node's status when the
369
+ * call was made: it fails the node with that error, which then surfaces on the next read and in
370
+ * `subscribe`'s `onError`. The previous value is still what `latest` reports, and a `set()`
371
+ * recovers the node as it does from any other failure.
372
+ *
373
+ * @param updater - Function that receives the current value and returns the next one
374
+ */
375
+ update(updater: UpdateFunction<T>): void;
376
+ /**
377
+ * Notifies all dependents without changing the value.
378
+ *
379
+ * Every dependent is queued for the next flush and re-runs, even though `===` change detection
380
+ * would have found nothing to report. It is the escape hatch for a change the reactive system
381
+ * cannot see — a value mutated in place, or an external source the graph does not model — and
382
+ * `signal()` is usually the better answer to both.
383
+ *
384
+ * Declared on the writable primitives only: forcing a subtree to re-run is a write, whatever it
385
+ * leaves the value at, so `constant()` and `derivation()` do not carry it (A3-ARCH-1, #132). On a
386
+ * derivation, `refresh()` is the read-side counterpart — it recomputes, and notifies only if the
387
+ * result actually changed.
388
+ */
389
+ trigger(): void;
390
+ }
391
+ /**
392
+ * Creates a mutable reactive state that can be read and updated imperatively.
393
+ *
394
+ * State can be initialized with a direct value or a lazy initializer function. Changes propagate
395
+ * automatically to all reactive computations that depend on this state. Use state for data that
396
+ * changes through user actions, external events, or application logic rather than derived computations.
397
+ *
398
+ * @param value - Initial value for the state, or lazy initializer function
399
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the default `===` change detection
400
+ * @returns A FlowState that can be read and modified
401
+ *
402
+ * @public
403
+ */
404
+ export declare function state<T>(value: NotPromise<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowState<T>;
405
+ export declare function state<T>(initializer: InitFunction<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowState<T>;
406
+ //#endregion
407
+ //#region src/core/api/nodes/collections/flowArray.d.ts
408
+ /**
409
+ * Discriminated union representing all possible array mutation operations.
410
+ *
411
+ * Each mutation on a FlowArray emits an action describing what changed. This enables fine-grained
412
+ * reactive tracking - you can observe the array itself or subscribe to `$lastAction` to react only
413
+ * to specific mutations. Use this for optimized rendering, undo/redo systems, or any scenario where
414
+ * you need to know exactly what changed rather than just that something changed.
415
+ *
416
+ * @public
417
+ */
418
+ export type FlowArrayAction<T> = {
419
+ type: "set";
420
+ setItems: T[];
421
+ clearedItems: T[];
422
+ } | {
423
+ type: "setAt";
424
+ index: number;
425
+ setItem: T;
426
+ clearedItem: T | undefined;
427
+ } | {
428
+ type: "push";
429
+ addedItem: T;
430
+ } | {
431
+ type: "pop";
432
+ removedItem: T | undefined;
433
+ } | {
434
+ type: "unshift";
435
+ addedItem: T;
436
+ } | {
437
+ type: "shift";
438
+ removedItem: T | undefined;
439
+ } | {
440
+ type: "splice";
441
+ /**
442
+ * The index the mutation started at. `splice()` rejects a `start` it would otherwise have to
443
+ * coerce or clamp, so this is both the argument it was called with and the position the store
444
+ * actually moved at — the two can never disagree (A3-SEC-2).
445
+ */
446
+ start: number;
447
+ /** How many items were removed — for the same reason, exactly the number the call asked for. */
448
+ deleteCount: number;
449
+ addedItems: T[];
450
+ removedItems: T[];
451
+ } | {
452
+ type: "clear";
453
+ clearedItems: T[];
454
+ };
455
+ /**
456
+ * Reactive array with standard mutation methods and fine-grained change tracking.
457
+ *
458
+ * FlowArray behaves like a regular array but notifies dependents on mutations. It provides all standard
459
+ * array mutation methods (push, pop, splice, etc.) and tracks each operation via `$lastAction`, a `FlowState` holding the most recent one.
460
+ * Every read returns the live backing array as `readonly T[]` — a view, not a copy — so mutate it
461
+ * through these methods only, and spread it (`[...items]`) when you need an array of your own.
462
+ * This enables both coarse-grained reactivity (reacting to any change) and fine-grained reactivity (reacting
463
+ * only to specific mutations). Use for lists that need reactive updates, such as todo lists, data tables,
464
+ * or any collection that changes over time.
465
+ *
466
+ * Methods that remove entries return what they removed (`pop`, `shift`, `splice`, `clear`);
467
+ * methods that write return nothing. `setAt` throws when the index does not exist, while `pop` and
468
+ * `shift` on an empty array return `undefined`.
469
+ *
470
+ * @public
471
+ */
472
+ export interface FlowArray<T> extends Omit<FlowState<readonly T[]>, "update" | "set"> {
473
+ /**
474
+ * Replaces the whole array.
475
+ * Emits a "set" action to $lastAction.
476
+ *
477
+ * The array is stored by reference and mutated in place by the other methods, which is why it
478
+ * must be a mutable array: do not keep using it yourself afterwards.
479
+ *
480
+ * @param items - The new items
481
+ */
482
+ set(items: T[]): void;
483
+ /**
484
+ * Replaces the item at a specific index.
485
+ * Emits a "setAt" action to $lastAction, which carries the previous item as `clearedItem`.
486
+ *
487
+ * @param index - The index of the item to replace (must exist)
488
+ * @param item - The new item
489
+ */
490
+ setAt(index: number, item: T): void;
491
+ /**
492
+ * Appends an item to the end of the array.
493
+ * Emits a "push" action to $lastAction.
494
+ *
495
+ * @param item - The item to append
496
+ */
497
+ push(item: T): void;
498
+ /**
499
+ * Removes and returns the last item from the array.
500
+ * Emits a "pop" action to $lastAction when an item is removed.
501
+ * If the array is already empty, returns undefined without notifying dependents or updating $lastAction.
502
+ *
503
+ * @returns The removed item, or undefined if the array was empty
504
+ */
505
+ pop(): T | undefined;
506
+ /**
507
+ * Inserts an item at the beginning of the array.
508
+ * Emits an "unshift" action to $lastAction.
509
+ *
510
+ * @param item - The item to insert
511
+ */
512
+ unshift(item: T): void;
513
+ /**
514
+ * Removes and returns the first item from the array.
515
+ * Emits a "shift" action to $lastAction when an item is removed.
516
+ * If the array is already empty, returns undefined without notifying dependents or updating $lastAction.
517
+ *
518
+ * @returns The removed item, or undefined if the array was empty
519
+ */
520
+ shift(): T | undefined;
521
+ /**
522
+ * Changes the content of the array by removing, replacing, or adding items.
523
+ * Emits a "splice" action to $lastAction, carrying the arguments it was called with.
524
+ *
525
+ * Both bounds must address the array as it stands, and are not coerced or clamped the way
526
+ * `Array.prototype.splice` coerces and clamps them: a fractional, negative or overrunning argument
527
+ * throws `PicoFlowPreconditionError` rather than mutating at some other index. So `splice(-1, 1)`
528
+ * does not count from the end — pass `items.length - 1` — and deleting to the end is
529
+ * `splice(start, items.length - start, …)`, not `splice(start, Infinity)`.
530
+ *
531
+ * @param start - Where to splice: an integer from 0 to the array's length inclusive (the length
532
+ * itself inserts at the end)
533
+ * @param deleteCount - Number of items to remove: an integer from 0 to the number of items left
534
+ * after `start`
535
+ * @param newItems - New items to add at the start position
536
+ * @returns Array of removed items
537
+ */
538
+ splice(start: number, deleteCount: number, ...newItems: T[]): T[];
539
+ /**
540
+ * Removes all items from the array.
541
+ * Emits a "clear" action to $lastAction.
542
+ *
543
+ * @returns Array of all removed items
544
+ */
545
+ clear(): T[];
546
+ /**
547
+ * Reactive state containing the last mutation operation performed on the array.
548
+ * `.subscribe()` invokes its callback once per mutation (including several in the same tick).
549
+ * `get()` / `pick()` expose only the latest action snapshot.
550
+ */
551
+ readonly $lastAction: FlowState<FlowArrayAction<T>>;
552
+ }
553
+ /**
554
+ * Creates a reactive array with mutation methods and fine-grained action tracking.
555
+ *
556
+ * The array starts with the provided initial items (or empty if none provided). All mutation methods
557
+ * (push, pop, splice, etc.) notify dependents and emit detailed action information to `$lastAction`.
558
+ * Use the array itself for coarse-grained reactivity, or subscribe to `$lastAction` for fine-grained
559
+ * reactivity to specific mutation types. Useful for reactive lists, collections, or any data that
560
+ * needs array-like operations with automatic change propagation.
561
+ *
562
+ * @param initial - Optional initial array of items
563
+ * @param options - Optional settings; `name` identifies this primitive in error messages
564
+ * @returns A FlowArray with reactive mutation methods
565
+ *
566
+ * @public
567
+ */
568
+ export declare function array<T>(initial?: T[], options?: FlowPrimitiveOptions): FlowArray<T>;
569
+ //#endregion
570
+ //#region src/core/api/nodes/collections/flowMap.d.ts
571
+ /**
572
+ * Discriminated union representing all possible map mutation operations.
573
+ *
574
+ * Each mutation on a FlowMap emits an action describing what changed. This enables fine-grained
575
+ * reactive tracking - you can observe the map itself or subscribe to `$lastAction` to react only
576
+ * to specific mutations. Use this for optimized updates, undo/redo systems, or any scenario where
577
+ * you need to know exactly what changed rather than just that something changed.
578
+ *
579
+ * @public
580
+ */
581
+ export type FlowMapAction<K, V> = {
582
+ type: "set";
583
+ setMap: Map<K, V>;
584
+ clearedMap: Map<K, V>;
585
+ } | {
586
+ type: "add";
587
+ key: K;
588
+ addedValue: V;
589
+ } | {
590
+ type: "setAt";
591
+ key: K;
592
+ setValue: V;
593
+ clearedValue: V;
594
+ } | {
595
+ type: "delete";
596
+ key: K;
597
+ removedValue: V;
598
+ } | {
599
+ type: "clear";
600
+ clearedMap: Map<K, V>;
601
+ };
602
+ /**
603
+ * Reactive map with standard mutation methods and fine-grained change tracking.
604
+ *
605
+ * FlowMap behaves like a regular Map but notifies dependents on mutations. It provides standard
606
+ * map operations (add, setAt, delete) and tracks each operation via `$lastAction`, a `FlowState` holding the most recent one.
607
+ * Every read returns the live backing map as `ReadonlyMap<K, V>` — a view, not a copy — so mutate it
608
+ * through these methods only, and copy it (`new Map(entries)`) when you need a map of your own.
609
+ * This enables both coarse-grained reactivity (reacting to any change) and fine-grained reactivity
610
+ * (reacting only to specific mutations). Use for key-value collections that need reactive updates,
611
+ * such as entity stores, lookup tables, or any map-based data that changes over time.
612
+ *
613
+ * Methods that remove entries return what they removed (`delete`, `clear`); methods that write
614
+ * return nothing. `add`, `setAt` and `delete` each name a key and throw when it does not exist
615
+ * (or, for `add`, already exists).
616
+ *
617
+ * @public
618
+ */
619
+ export interface FlowMap<K, V> extends Omit<FlowState<ReadonlyMap<K, V>>, "update" | "set"> {
620
+ /**
621
+ * Replaces the whole map.
622
+ * Emits a "set" action to $lastAction.
623
+ *
624
+ * The map is stored by reference and mutated in place by the other methods, which is why it
625
+ * must be a mutable map: do not keep using it yourself afterwards.
626
+ *
627
+ * @param entries - The new entries
628
+ */
629
+ set(entries: Map<K, V>): void;
630
+ /**
631
+ * Removes a key-value pair from the map.
632
+ * Emits a "delete" action to $lastAction.
633
+ *
634
+ * @param key - The key to delete
635
+ * @returns The deleted value
636
+ */
637
+ delete(key: K): V;
638
+ /**
639
+ * Replaces the value of an existing key.
640
+ * Emits a "setAt" action to $lastAction, which carries the previous value as `clearedValue`.
641
+ *
642
+ * @param key - The key to replace the value of (must exist)
643
+ * @param value - The new value
644
+ */
645
+ setAt(key: K, value: V): void;
646
+ /**
647
+ * Adds a new key-value pair to the map.
648
+ * Emits an "add" action to $lastAction.
649
+ *
650
+ * @param key - The key to add (must not exist)
651
+ * @param value - The value to associate with the key
652
+ */
653
+ add(key: K, value: V): void;
654
+ /**
655
+ * Removes all entries from the map.
656
+ * Emits a "clear" action to $lastAction.
657
+ *
658
+ * @returns Map of all removed entries
659
+ */
660
+ clear(): Map<K, V>;
661
+ /**
662
+ * Reactive state containing the last mutation operation performed on the map.
663
+ * `.subscribe()` invokes its callback once per mutation (including several in the same tick).
664
+ * `get()` / `pick()` expose only the latest action snapshot.
665
+ */
666
+ readonly $lastAction: FlowState<FlowMapAction<K, V>>;
667
+ }
668
+ /**
669
+ * Creates a reactive map with mutation methods and fine-grained action tracking.
670
+ *
671
+ * The map starts with the provided initial entries (or empty if none provided). All mutation methods
672
+ * (add, setAt, delete) notify dependents and emit detailed action information to `$lastAction`.
673
+ * Use the map itself for coarse-grained reactivity, or subscribe to `$lastAction` for fine-grained
674
+ * reactivity to specific mutation types. Useful for entity stores, lookup tables, or any key-value
675
+ * data that needs reactive updates.
676
+ *
677
+ * The initial entries come either as a `Map`, whose keys are copied as they are whatever their type,
678
+ * or as a `Record`, which is read with `Object.entries` and therefore always yields string keys —
679
+ * which is why that form is constrained to `K extends string` (#124). Seed from a `Map` when the
680
+ * keys are numbers or symbols.
681
+ *
682
+ * @param initial - Optional initial entries: a `Map` with keys of any type, or a `Record` with
683
+ * string keys
684
+ * @param options - Optional settings; `name` identifies this primitive in error messages
685
+ * @returns A FlowMap with reactive mutation methods
686
+ *
687
+ * @public
688
+ */
689
+ export declare function map<K extends string | number | symbol, V>(initial?: Map<K, V>, options?: FlowPrimitiveOptions): FlowMap<K, V>;
690
+ export declare function map<K extends string, V>(initial: Record<K, V>, options?: FlowPrimitiveOptions): FlowMap<K, V>;
691
+ //#endregion
692
+ //#region src/core/api/nodes/sync/flowDerivation.d.ts
693
+ /**
694
+ * Function that derives a value from its dependencies, and optionally from the value it last
695
+ * produced.
696
+ *
697
+ * Reads through the `tracker` are what register a dependency, so the set is rebuilt on every run — a
698
+ * source read behind a branch that did not execute is not a dependency of that run. `previous` is
699
+ * `undefined` on the first run, and carries the last resolved value afterwards, which is what makes
700
+ * a derivation the place to release a resource it created (close the previous socket before opening
701
+ * the next).
702
+ *
703
+ * @public
704
+ */
705
+ export type DerivationFunction<T> = (tracker: FlowTracker, previous?: NotPromise<T>) => NotPromise<T>;
706
+ /**
707
+ * Read-only reactive value that recomputes automatically when dependencies change.
708
+ *
709
+ * Derivations track reactive values accessed during computation and automatically recompute when any
710
+ * tracked dependency changes. The computed value is cached until dependencies change, avoiding unnecessary
711
+ * recomputations. Use derivations for values derived from other reactive state, such as filtered lists,
712
+ * computed properties, or aggregated data.
713
+ *
714
+ * @public
715
+ */
716
+ export interface FlowDerivation<T> extends FlowValue<T> {
717
+ /**
718
+ * Forces the derivation to recompute even if dependencies haven't changed.
719
+ */
720
+ refresh(): void;
721
+ }
722
+ /**
723
+ * Creates a derived reactive value that automatically recomputes when dependencies change.
724
+ *
725
+ * The compute function runs when any tracked dependency changes, and the result is cached until the next change.
726
+ * Access reactive values within the compute function to establish dependencies automatically. The derivation
727
+ * computes lazily on first access and then reactively thereafter. Use for derived data that should stay
728
+ * synchronized with source state.
729
+ *
730
+ * @param compute - Function that accesses dependencies and computes the derived value
731
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the
732
+ * default `===` change detection, `eager` recomputes on dirty instead of on read (#118)
733
+ * @returns A FlowDerivation that provides read-only access to the computed value
734
+ *
735
+ * @public
736
+ */
737
+ export declare function derivation<T>(compute: DerivationFunction<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowDerivation<T>;
738
+ //#endregion
739
+ //#region src/core/api/nodes/sync/flowWritableDerivation.d.ts
740
+ /**
741
+ * Writable reactive value that recomputes automatically when dependencies change, but can be manually overridden.
742
+ *
743
+ * Writable derivations combine reactive computation with manual control. They track dependencies and recompute
744
+ * like regular derivations, but you can also call `set()` to override the computed value temporarily. Use this
745
+ * for computed values that users can edit, such as formatted fields, calculated totals that can be adjusted,
746
+ * or any value that is usually derived but sometimes needs manual correction.
747
+ *
748
+ * @public
749
+ */
750
+ export interface FlowWritableDerivation<T> extends FlowState<T>, FlowDerivation<T> {}
751
+ /**
752
+ * Creates a derived value that recomputes automatically but can also be manually overridden.
753
+ *
754
+ * The compute function tracks dependencies and recomputes when they change, just like a regular derivation.
755
+ * However, you can also call `set()` to override the computed value. Use this for values that are normally
756
+ * derived but need occasional manual adjustments, such as editable calculated fields or user-correctable totals.
757
+ *
758
+ * @param compute - Function that accesses dependencies and computes the derived value
759
+ * @param options - Optional settings; `name` identifies this primitive in error messages, `equals` overrides the
760
+ * default `===` change detection, `eager` recomputes on dirty instead of on read (#118)
761
+ * @returns A FlowWritableDerivation that provides both reactive computation and manual control
762
+ *
763
+ * @public
764
+ */
765
+ export declare function writableDerivation<T>(compute: DerivationFunction<T>, options?: FlowPrimitiveOptions<NotPromise<T>>): FlowWritableDerivation<T>;
766
+ //#endregion
767
+ export { FlowDataTracker, FlowDisposable, FlowEffect, FlowEffectOptions, FlowEquals, FlowObservable, FlowOnDataListener, FlowOnErrorListener, FlowOnPendingListener, FlowPrimitiveOptions, FlowReadonly, FlowSignal, FlowSnapshot, FlowSubscribable, FlowTracker, FlowValue, NotPromise, type ObservableStatus, type ObserverStatus, PromiseNotAllowed, isDisposable, signal, subscribe, tracker };