@ersbeth/picoflow 0.0.1

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 (90) hide show
  1. package/.vscode/settings.json +5 -0
  2. package/README.md +151 -0
  3. package/api/doc/index.md +31 -0
  4. package/api/doc/picoflow.derivation.md +55 -0
  5. package/api/doc/picoflow.effect.md +55 -0
  6. package/api/doc/picoflow.flowderivation._constructor_.md +49 -0
  7. package/api/doc/picoflow.flowderivation.get.md +23 -0
  8. package/api/doc/picoflow.flowderivation.md +86 -0
  9. package/api/doc/picoflow.flowdisposer.md +13 -0
  10. package/api/doc/picoflow.floweffect._constructor_.md +49 -0
  11. package/api/doc/picoflow.floweffect.dispose.md +21 -0
  12. package/api/doc/picoflow.floweffect.disposed.md +13 -0
  13. package/api/doc/picoflow.floweffect.md +131 -0
  14. package/api/doc/picoflow.flowgetter.md +15 -0
  15. package/api/doc/picoflow.flowmap._lastdeleted.md +21 -0
  16. package/api/doc/picoflow.flowmap._lastset.md +21 -0
  17. package/api/doc/picoflow.flowmap.delete.md +57 -0
  18. package/api/doc/picoflow.flowmap.md +135 -0
  19. package/api/doc/picoflow.flowmap.setat.md +73 -0
  20. package/api/doc/picoflow.flowobservable.get.md +19 -0
  21. package/api/doc/picoflow.flowobservable.md +54 -0
  22. package/api/doc/picoflow.flowresource._constructor_.md +65 -0
  23. package/api/doc/picoflow.flowresource.fetch.md +27 -0
  24. package/api/doc/picoflow.flowresource.get.md +23 -0
  25. package/api/doc/picoflow.flowresource.md +100 -0
  26. package/api/doc/picoflow.flowsetter.md +13 -0
  27. package/api/doc/picoflow.flowsignal.dispose.md +25 -0
  28. package/api/doc/picoflow.flowsignal.disposed.md +18 -0
  29. package/api/doc/picoflow.flowsignal.md +111 -0
  30. package/api/doc/picoflow.flowsignal.trigger.md +25 -0
  31. package/api/doc/picoflow.flowstate._constructor_.md +49 -0
  32. package/api/doc/picoflow.flowstate.get.md +23 -0
  33. package/api/doc/picoflow.flowstate.md +100 -0
  34. package/api/doc/picoflow.flowstate.set.md +61 -0
  35. package/api/doc/picoflow.flowstream._constructor_.md +65 -0
  36. package/api/doc/picoflow.flowstream.dispose.md +21 -0
  37. package/api/doc/picoflow.flowstream.get.md +23 -0
  38. package/api/doc/picoflow.flowstream.md +100 -0
  39. package/api/doc/picoflow.flowupdater.md +19 -0
  40. package/api/doc/picoflow.flowwatcher.md +15 -0
  41. package/api/doc/picoflow.map.md +59 -0
  42. package/api/doc/picoflow.md +287 -0
  43. package/api/doc/picoflow.resource.md +71 -0
  44. package/api/doc/picoflow.signal.md +19 -0
  45. package/api/doc/picoflow.state.md +55 -0
  46. package/api/doc/picoflow.stream.md +71 -0
  47. package/api/picoflow.api.md +145 -0
  48. package/api-extractor.json +60 -0
  49. package/biome.json +34 -0
  50. package/dist/picoflow.js +572 -0
  51. package/dist/types/creators.d.ts +70 -0
  52. package/dist/types/creators.d.ts.map +1 -0
  53. package/dist/types/derivation.d.ts +58 -0
  54. package/dist/types/derivation.d.ts.map +1 -0
  55. package/dist/types/effect.d.ts +108 -0
  56. package/dist/types/effect.d.ts.map +1 -0
  57. package/dist/types/index.d.ts +18 -0
  58. package/dist/types/index.d.ts.map +1 -0
  59. package/dist/types/map.d.ts +75 -0
  60. package/dist/types/map.d.ts.map +1 -0
  61. package/dist/types/observable.d.ts +40 -0
  62. package/dist/types/observable.d.ts.map +1 -0
  63. package/dist/types/resource.d.ts +46 -0
  64. package/dist/types/resource.d.ts.map +1 -0
  65. package/dist/types/signal.d.ts +111 -0
  66. package/dist/types/signal.d.ts.map +1 -0
  67. package/dist/types/state.d.ts +39 -0
  68. package/dist/types/state.d.ts.map +1 -0
  69. package/dist/types/stream.d.ts +71 -0
  70. package/dist/types/stream.d.ts.map +1 -0
  71. package/package.json +40 -0
  72. package/src/creators.ts +101 -0
  73. package/src/derivation.ts +96 -0
  74. package/src/effect.ts +152 -0
  75. package/src/index.ts +30 -0
  76. package/src/map.ts +83 -0
  77. package/src/observable.ts +50 -0
  78. package/src/resource.ts +64 -0
  79. package/src/signal.ts +166 -0
  80. package/src/state.ts +52 -0
  81. package/src/stream.ts +99 -0
  82. package/test/derivation.test.ts +422 -0
  83. package/test/map.test.ts +106 -0
  84. package/test/resource.test.ts +127 -0
  85. package/test/signal.test.ts +59 -0
  86. package/test/state.test.ts +89 -0
  87. package/test/stream.test.ts +171 -0
  88. package/tsconfig.json +22 -0
  89. package/vite.config.ts +26 -0
  90. package/vitest.config.ts +11 -0
package/biome.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3
+ "files": {
4
+ "ignore": [
5
+ "dist",
6
+ "node_modules",
7
+ "doc/.vitepress/dist",
8
+ "doc/.vitepress/cache"
9
+ ]
10
+ },
11
+ "organizeImports": {
12
+ "enabled": true
13
+ },
14
+ "formatter": {
15
+ "enabled": true,
16
+ "indentStyle": "space",
17
+ "indentWidth": 4,
18
+ "lineEnding": "lf"
19
+ },
20
+ "linter": {
21
+ "rules": {
22
+ "suspicious": {
23
+ "noExplicitAny": "off",
24
+ "useIsArray": "off"
25
+ },
26
+ "complexity": {
27
+ "noForEach": "off"
28
+ },
29
+ "style": {
30
+ "noNonNullAssertion": "off"
31
+ }
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,572 @@
1
+ class FlowSignal {
2
+ /* API ---------------------------------------------------------------------- */
3
+ /**
4
+ * Triggers the signal.
5
+ * @remarks
6
+ * This method notifies all registered listeners and causes associated effects to execute.
7
+ * @throws Error if the signal is disposed.
8
+ * @public
9
+ */
10
+ trigger() {
11
+ if (this._disposed) throw new Error("Signal is disposed");
12
+ this._notify();
13
+ }
14
+ /**
15
+ * Disposes the signal.
16
+ * @remarks
17
+ * Disposing a signal will dispose all registered effects and listeners,
18
+ * and unregister all dependencies. Once disposed, any further calls to the signal
19
+ * will throw an error.
20
+ * @throws Error if the signal is already disposed.
21
+ * @public
22
+ */
23
+ dispose() {
24
+ if (this._disposed) throw new Error("Signal is disposed");
25
+ Array.from(this._effects).forEach((effect) => effect.dispose());
26
+ Array.from(this._listeners).forEach((listener) => listener.dispose());
27
+ Array.from(this._dependencies).forEach((dependency) => {
28
+ this._unregisterDependency(dependency);
29
+ });
30
+ this._disposed = true;
31
+ }
32
+ /**
33
+ * Indicates whether the signal has been disposed.
34
+ * @remarks
35
+ * Once disposed, the signal should not be used.
36
+ * @public
37
+ */
38
+ get disposed() {
39
+ return this._disposed;
40
+ }
41
+ /* INTERNAL ------------------------------------------------------------- */
42
+ /**
43
+ * @internal
44
+ */
45
+ _disposed = false;
46
+ /**
47
+ * @internal
48
+ */
49
+ _dependencies = /* @__PURE__ */ new Set();
50
+ /**
51
+ * @internal
52
+ */
53
+ _listeners = /* @__PURE__ */ new Set();
54
+ /**
55
+ * @internal
56
+ */
57
+ _effects = /* @__PURE__ */ new Set();
58
+ /**
59
+ * @internal
60
+ * Internal method to watch the signal.
61
+ * @throws Error if the signal is disposed.
62
+ */
63
+ _watch() {
64
+ if (this._disposed) throw new Error("Signal is disposed");
65
+ }
66
+ /**
67
+ * @internal
68
+ * Notifies all listeners and executes all registered effects.
69
+ */
70
+ _notify() {
71
+ this._listeners.forEach((listener) => listener._notify());
72
+ this._effects.forEach((effect) => effect._exec());
73
+ }
74
+ /**
75
+ * @internal
76
+ * Registers a dependency from the given listener and watches the signal.
77
+ * @param listener - A FlowSignal or FlowEffect that will depend on this signal.
78
+ */
79
+ _watchFrom(listener) {
80
+ listener._registerDependency(this);
81
+ this._watch();
82
+ }
83
+ /**
84
+ * @internal
85
+ * Registers a dependency with the given FlowSignal.
86
+ * @param dependency - The FlowSignal to register as a dependency.
87
+ */
88
+ _registerDependency(dependency) {
89
+ this._dependencies.add(dependency);
90
+ dependency._registerListener(this);
91
+ }
92
+ /**
93
+ * @internal
94
+ * Unregisters the given dependency.
95
+ * @param dependency - The FlowSignal to unregister.
96
+ */
97
+ _unregisterDependency(dependency) {
98
+ this._dependencies.delete(dependency);
99
+ dependency._unregisterListener(this);
100
+ }
101
+ /**
102
+ * @internal
103
+ * Registers a listener (another FlowSignal) to this signal.
104
+ * @param signal - The FlowSignal to register as a listener.
105
+ */
106
+ _registerListener(signal) {
107
+ this._listeners.add(signal);
108
+ }
109
+ /**
110
+ * @internal
111
+ * Unregisters the given listener.
112
+ * @param signal - The FlowSignal to unregister.
113
+ */
114
+ _unregisterListener(signal) {
115
+ this._listeners.delete(signal);
116
+ }
117
+ /**
118
+ * @internal
119
+ * Registers a FlowEffect to this signal.
120
+ * @param effect - The FlowEffect to register.
121
+ */
122
+ _registerEffect(effect) {
123
+ this._effects.add(effect);
124
+ }
125
+ /**
126
+ * @internal
127
+ * Unregisters the given FlowEffect.
128
+ * @param effect - The FlowEffect to unregister.
129
+ */
130
+ _unregisterEffect(effect) {
131
+ this._effects.delete(effect);
132
+ }
133
+ }
134
+
135
+ class FlowObservable extends FlowSignal {
136
+ /* INTERNAL -------------------------------------------*/
137
+ /**
138
+ * @internal
139
+ * Internal storage for the observable's value.
140
+ */
141
+ _value;
142
+ /**
143
+ * @internal
144
+ * Retrieves the current value from the observable and registers a dependency
145
+ * from the provided listener.
146
+ * @param listener - The FlowObservable or FlowEffect that is accessing this observable.
147
+ * @returns The current value, as returned by {@link FlowObservable.get}.
148
+ */
149
+ _getFrom(listener) {
150
+ listener._registerDependency(this);
151
+ return this.get();
152
+ }
153
+ }
154
+
155
+ class FlowDerivation extends FlowObservable {
156
+ /**
157
+ * Creates a new FlowDerivation.
158
+ * @param compute - A function that computes the derived value. It is provided with a getter
159
+ * and a watcher function to access observables and signals dependencies.
160
+ * @public
161
+ */
162
+ constructor(compute) {
163
+ super();
164
+ this._trackedExec = () => compute(this._trackedGet, this._trackedWatch);
165
+ this._untrackedExec = () => compute(this._untrackedGet, this._untrackedWatch);
166
+ }
167
+ /**
168
+ * Gets the current derived value.
169
+ * @returns The current computed value.
170
+ * @remarks
171
+ * This method ensures that the derivation is up-to-date before returning the value.
172
+ * @public
173
+ */
174
+ get() {
175
+ this._exec();
176
+ return this._value;
177
+ }
178
+ /* INTERNAL MEMBERS AND METHODS */
179
+ /** @internal */
180
+ _initialized = false;
181
+ /** @internal */
182
+ _dirty = true;
183
+ /** @internal */
184
+ _trackedGet = (observable) => observable._getFrom(this);
185
+ /** @internal */
186
+ _trackedWatch = (signal) => signal._watchFrom(this);
187
+ /** @internal */
188
+ _untrackedGet = (observable) => observable.get();
189
+ /** @internal */
190
+ _untrackedWatch = (signal) => signal._watch();
191
+ /** @internal */
192
+ _trackedExec;
193
+ /** @internal */
194
+ _untrackedExec;
195
+ /**
196
+ * @internal
197
+ * Executes the compute function if necessary to update the derived value.
198
+ */
199
+ _exec() {
200
+ if (this._disposed) throw new Error("Effect is disposed");
201
+ if (this._dirty) {
202
+ if (this._initialized) this._value = this._untrackedExec();
203
+ else {
204
+ this._value = this._trackedExec();
205
+ this._initialized = true;
206
+ }
207
+ this._dirty = false;
208
+ }
209
+ }
210
+ /**
211
+ * @internal
212
+ * Marks the derivation as dirty and notifies downstream dependencies.
213
+ */
214
+ _notify() {
215
+ this._dirty = true;
216
+ super._notify();
217
+ }
218
+ /**
219
+ * @internal
220
+ * Ensures that the derivation is up-to-date when it is watched.
221
+ */
222
+ _watch() {
223
+ this._exec();
224
+ }
225
+ }
226
+
227
+ class FlowEffect {
228
+ /* API --------------------------------------------------- */
229
+ /**
230
+ * Creates a new FlowEffect.
231
+ *
232
+ * @param apply - A function that performs the side effect. It receives a getter and a watcher
233
+ * function to access and register dependencies on reactive observables and signals.
234
+ *
235
+ * @public
236
+ */
237
+ constructor(apply) {
238
+ this._trackedExec = () => apply(this._trackedGet, this._trackedWatch);
239
+ this._untrackedExec = () => apply(this._untrackedGet, this._untrackedWatch);
240
+ this._exec();
241
+ }
242
+ /**
243
+ * Disposes the effect, unregistering all its dependencies.
244
+ *
245
+ * @remarks
246
+ * After disposal, the effect should no longer be used. Calling this method on an already
247
+ * disposed effect will throw an error.
248
+ *
249
+ * @public
250
+ */
251
+ dispose() {
252
+ if (this._disposed) throw new Error("Effect is disposed");
253
+ Array.from(this._dependencies).forEach((dependency) => {
254
+ this._unregisterDependency(dependency);
255
+ });
256
+ this._disposed = true;
257
+ }
258
+ /**
259
+ * Indicates whether this effect has been disposed.
260
+ *
261
+ * @returns A boolean value indicating if the effect is disposed.
262
+ *
263
+ * @public
264
+ */
265
+ get disposed() {
266
+ return this._disposed;
267
+ }
268
+ /* INTERNAL ------------------------------------------------------------ */
269
+ /**
270
+ * @internal
271
+ */
272
+ _disposed = false;
273
+ /**
274
+ * @internal
275
+ */
276
+ _initialized = false;
277
+ /**
278
+ * @internal
279
+ */
280
+ _dependencies = /* @__PURE__ */ new Set();
281
+ /**
282
+ * @internal
283
+ * A tracked getter that registers a dependency when accessing an observable.
284
+ */
285
+ _trackedGet = (observable) => observable._getFrom(this);
286
+ /**
287
+ * @internal
288
+ * A tracked watcher that registers a dependency when watching a signal.
289
+ */
290
+ _trackedWatch = (signal) => signal._watchFrom(this);
291
+ /**
292
+ * @internal
293
+ * An untracked getter that simply retrieves the current value from an observable.
294
+ */
295
+ _untrackedGet = (observable) => observable.get();
296
+ /**
297
+ * @internal
298
+ * An untracked watcher that calls the default watch on a signal.
299
+ */
300
+ _untrackedWatch = (signal) => signal._watch();
301
+ /**
302
+ * @internal
303
+ * Execution function used during initialization (tracked mode).
304
+ */
305
+ _trackedExec;
306
+ /**
307
+ * @internal
308
+ * Execution function used after initialization (untracked mode).
309
+ */
310
+ _untrackedExec;
311
+ /**
312
+ * @internal
313
+ * Executes the effect. If the effect has not been initialized, it runs in tracked mode;
314
+ * otherwise, it runs in untracked mode.
315
+ *
316
+ * @throws Error if the effect has been disposed.
317
+ */
318
+ _exec() {
319
+ if (this._disposed) throw new Error("Effect is disposed");
320
+ if (this._initialized) this._untrackedExec();
321
+ else {
322
+ this._trackedExec();
323
+ this._initialized = true;
324
+ }
325
+ }
326
+ /**
327
+ * @internal
328
+ * Registers a dependency on the given signal.
329
+ *
330
+ * @param dependency - The FlowSignal to register as a dependency.
331
+ */
332
+ _registerDependency(dependency) {
333
+ this._dependencies.add(dependency);
334
+ dependency._registerEffect(this);
335
+ }
336
+ /**
337
+ * @internal
338
+ * Unregisters the given dependency.
339
+ *
340
+ * @param dependency - The FlowSignal to unregister.
341
+ */
342
+ _unregisterDependency(dependency) {
343
+ this._dependencies.delete(dependency);
344
+ dependency._unregisterEffect(this);
345
+ }
346
+ }
347
+
348
+ class FlowResource extends FlowObservable {
349
+ /**
350
+ * Creates a new FlowResource.
351
+ * @param fetch - An asynchronous function that retrieves the resource's value.
352
+ * @param initial - The initial value of the resource.
353
+ * @public
354
+ */
355
+ constructor(fetch, initial) {
356
+ super();
357
+ this._value = initial;
358
+ this._fetch = fetch;
359
+ }
360
+ /**
361
+ * Retrieves the current resource value.
362
+ * @returns The current value.
363
+ * @throws Error if the resource is disposed.
364
+ * @public
365
+ */
366
+ get() {
367
+ if (this._disposed) throw new Error("Resource is disposed");
368
+ return this._value;
369
+ }
370
+ /**
371
+ * Asynchronously fetches a new value for the resource.
372
+ * @remarks
373
+ * Executes the internal fetch function. If the fetched value differs from the current one,
374
+ * updates the resource's value and notifies subscribers.
375
+ * @returns A Promise that resolves when the fetch operation is complete.
376
+ * @throws Error if the resource is disposed.
377
+ * @public
378
+ */
379
+ async fetch() {
380
+ if (this._disposed) throw new Error("Resource is disposed");
381
+ const value = await this._fetch();
382
+ if (value === this._value) return;
383
+ this._value = value;
384
+ this._notify();
385
+ }
386
+ /* INTERNAL ------------------------------------------------ */
387
+ /**
388
+ * @internal
389
+ * The asynchronous function used to fetch the resource value.
390
+ */
391
+ _fetch;
392
+ }
393
+
394
+ class FlowState extends FlowObservable {
395
+ /**
396
+ * Creates a new FlowState with the given initial value.
397
+ * @param value - The initial value for the state.
398
+ * @public
399
+ */
400
+ constructor(value) {
401
+ super();
402
+ this._value = value;
403
+ }
404
+ /**
405
+ * Retrieves the current state value.
406
+ * @returns The current value of the state.
407
+ * @throws Error if the state has been disposed.
408
+ * @public
409
+ */
410
+ get() {
411
+ if (this._disposed) throw new Error("State is disposed");
412
+ return this._value;
413
+ }
414
+ /**
415
+ * Updates the state with a new value.
416
+ * @param value - The new value to set.
417
+ * @remarks
418
+ * If the new value is identical to the current value, no update or notification occurs.
419
+ * Otherwise, the state is updated and all subscribers are notified.
420
+ * @throws Error if the state has been disposed.
421
+ * @public
422
+ */
423
+ set(value) {
424
+ if (this._disposed) throw new Error("State is disposed");
425
+ if (value === this._value) return;
426
+ this._value = value;
427
+ this._notify();
428
+ }
429
+ }
430
+
431
+ class FlowMap extends FlowState {
432
+ /**
433
+ * A reactive state that holds the most recent key and value that were set.
434
+ *
435
+ * @remarks
436
+ * When a key is set via {@link FlowMap.setAt}, this state is updated with
437
+ * the corresponding key and value.
438
+ *
439
+ * @public
440
+ */
441
+ $lastSet = new FlowState({});
442
+ /**
443
+ * A reactive state that holds the most recent key and value that were deleted.
444
+ *
445
+ * @remarks
446
+ * When a key is deleted via {@link FlowMap.delete}, this state is updated with
447
+ * the corresponding key and its last known value.
448
+ *
449
+ * @public
450
+ */
451
+ $lastDeleted = new FlowState({});
452
+ /**
453
+ * Sets a value at the specified key in the underlying map.
454
+ *
455
+ * @param key - The key at which to set the value.
456
+ * @param value - The value to set.
457
+ *
458
+ * @remarks
459
+ * This method updates the internal map with the given key and value, emits the new
460
+ * key-value pair via {@link FlowMap.$lastSet}, and notifies subscribers of the change.
461
+ *
462
+ * @public
463
+ */
464
+ setAt(key, value) {
465
+ if (this._disposed) throw new Error("StateMap is disposed");
466
+ this._value.set(key, value);
467
+ this.$lastSet.set({ key, value });
468
+ this._notify();
469
+ }
470
+ /**
471
+ * Deletes the value at the specified key from the underlying map.
472
+ *
473
+ * @param key - The key to delete.
474
+ *
475
+ * @remarks
476
+ * This method removes the key from the internal map, emits the deleted key and its
477
+ * corresponding value via {@link FlowMap.$lastDeleted}, and notifies subscribers
478
+ * of the change.
479
+ *
480
+ * @public
481
+ */
482
+ delete(key) {
483
+ if (this._disposed) throw new Error("StateMap is disposed");
484
+ const value = this._value.get(key);
485
+ this._value.delete(key);
486
+ this.$lastDeleted.set({ key, value });
487
+ this._notify();
488
+ }
489
+ }
490
+
491
+ class FlowStream extends FlowObservable {
492
+ /* API -------------------------------------------------------- */
493
+ /**
494
+ * Creates a new FlowStream.
495
+ * @param updater - A function that receives a setter to update the stream's value.
496
+ * It should return a disposer function that will be called upon disposal.
497
+ * @param initial - The initial value of the stream.
498
+ * @public
499
+ */
500
+ constructor(updater, initial) {
501
+ super();
502
+ this._value = initial;
503
+ this._disposer = updater((value) => {
504
+ this._set(value);
505
+ });
506
+ }
507
+ /**
508
+ * Retrieves the current value of the stream.
509
+ * @returns The current value.
510
+ * @throws Error if the stream is disposed.
511
+ * @public
512
+ */
513
+ get() {
514
+ if (this._disposed) throw new Error("Stream is disposed");
515
+ return this._value;
516
+ }
517
+ /**
518
+ * Disposes the stream, releasing all resources.
519
+ * @remarks
520
+ * In addition to disposing the underlying observable, this method calls the disposer
521
+ * returned by the updater.
522
+ * @public
523
+ */
524
+ dispose() {
525
+ super.dispose();
526
+ this._disposer();
527
+ }
528
+ /* INTERNAL ------------------------------------------------------ */
529
+ /**
530
+ * @internal
531
+ * The disposer function returned by the updater.
532
+ */
533
+ _disposer;
534
+ /**
535
+ * @internal
536
+ * Updates the stream's value and notifies subscribers if the value changes.
537
+ * @param value - The new value to set.
538
+ * @internal
539
+ */
540
+ _set(value) {
541
+ if (this._disposed) throw new Error("Stream is disposed");
542
+ if (value === this._value) return;
543
+ this._value = value;
544
+ this._notify();
545
+ }
546
+ }
547
+
548
+ function signal() {
549
+ return new FlowSignal();
550
+ }
551
+ function state(value) {
552
+ return new FlowState(value);
553
+ }
554
+ function resource(fn, initial) {
555
+ return new FlowResource(fn, initial);
556
+ }
557
+ function stream(updater, initial) {
558
+ return new FlowStream(updater, initial);
559
+ }
560
+ function derivation(fn) {
561
+ return new FlowDerivation(fn);
562
+ }
563
+ function effect(fn) {
564
+ return new FlowEffect(fn);
565
+ }
566
+ function map(initial) {
567
+ return new FlowMap(
568
+ new Map(initial ? Object.entries(initial) : [])
569
+ );
570
+ }
571
+
572
+ export { derivation, effect, map, resource, signal, state, stream };
@@ -0,0 +1,70 @@
1
+ import { FlowDerivation } from './derivation';
2
+ import { FlowEffect } from './effect';
3
+ import { FlowGetter } from './observable';
4
+ import { FlowResource } from './resource';
5
+ import { FlowSignal, FlowWatcher } from './signal';
6
+ import { FlowState } from './state';
7
+ import { FlowMap } from './map';
8
+ import { FlowStream } from './stream';
9
+ /**
10
+ * Creates a new reactive signal.
11
+ * @returns A new instance of {@link FlowSignal}.
12
+ * @public
13
+ */
14
+ export declare function signal(): FlowSignal;
15
+ /**
16
+ * Creates a new reactive state holding a value.
17
+ * @typeparam T - The type of the state value.
18
+ * @param value - The initial value for the state.
19
+ * @returns A new instance of {@link FlowState}.
20
+ * @public
21
+ */
22
+ export declare function state<T>(value: T): FlowState<T>;
23
+ /**
24
+ * Creates a new reactive resource that asynchronously fetches its value.
25
+ * @typeparam T - The type of the resource value.
26
+ * @param fn - An asynchronous function that fetches the resource value.
27
+ * @param initial - The initial value of the resource.
28
+ * @returns A new instance of {@link FlowResource}.
29
+ * @public
30
+ */
31
+ export declare function resource<T>(fn: () => Promise<T>, initial: T): FlowResource<T>;
32
+ /**
33
+ * Creates a new reactive stream.
34
+ * @typeparam T - The type of the stream value.
35
+ * @param updater - A function that receives a setter to update the stream's value.
36
+ * It should return a disposer function to clean up resources.
37
+ * @param initial - The initial value of the stream.
38
+ * @returns A new instance of {@link FlowStream}.
39
+ * @public
40
+ */
41
+ export declare function stream<T>(updater: (set: (value: T) => void) => () => void, initial: T): FlowStream<T>;
42
+ /**
43
+ * Creates a new reactive derivation whose value is computed based on other reactive signals.
44
+ * @typeparam T - The type of the derived value.
45
+ * @param fn - A function that computes the derived value. It receives a getter and a watcher
46
+ * function to access and register dependencies.
47
+ * @returns A new instance of {@link FlowDerivation}.
48
+ * @public
49
+ */
50
+ export declare function derivation<T>(fn: (get: FlowGetter, watch: FlowWatcher) => T): FlowDerivation<T>;
51
+ /**
52
+ * Creates a new reactive effect that executes a side-effect function based on its dependencies.
53
+ * @param fn - A function that performs side effects. It receives a getter and a watcher
54
+ * function for tracking reactive dependencies.
55
+ * @returns A new instance of {@link FlowEffect}.
56
+ * @public
57
+ */
58
+ export declare function effect(fn: (get: FlowGetter, watch: FlowWatcher) => void): FlowEffect;
59
+ /**
60
+ * Creates a new reactive map state.
61
+ * @typeparam K - The type of the keys.
62
+ * @typeparam V - The type of the values.
63
+ * @param initial - An optional record of key-value pairs to initialize the map.
64
+ * @returns A new instance of {@link FlowMap}.
65
+ * @remarks
66
+ * The initial record is converted to a native Map before being used.
67
+ * @public
68
+ */
69
+ export declare function map<K extends string | number | symbol, V>(initial?: Record<K, V>): FlowMap<K, V>;
70
+ //# sourceMappingURL=creators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"creators.d.ts","sourceRoot":"","sources":["../../src/creators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;GAIG;AACH,wBAAgB,MAAM,IAAI,UAAU,CAEnC;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAE/C;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAE7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,CAAC,EACpB,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,EAChD,OAAO,EAAE,CAAC,GACX,UAAU,CAAC,CAAC,CAAC,CAEf;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,KAAK,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAE/F;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,UAAU,CAEpF;AAED;;;;;;;;;GASG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,EACrD,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAIf"}