@pyreon/reactivity 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/lib/analysis/index.js.html +5406 -0
- package/lib/index.js +838 -0
- package/lib/index.js.map +1 -0
- package/lib/types/index.d.ts +725 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index2.d.ts +342 -0
- package/lib/types/index2.d.ts.map +1 -0
- package/package.json +40 -0
- package/src/batch.ts +44 -0
- package/src/cell.ts +71 -0
- package/src/computed.ts +71 -0
- package/src/createSelector.ts +56 -0
- package/src/debug.ts +134 -0
- package/src/effect.ts +152 -0
- package/src/index.ts +15 -0
- package/src/reconcile.ts +98 -0
- package/src/resource.ts +66 -0
- package/src/scope.ts +80 -0
- package/src/signal.ts +125 -0
- package/src/store.ts +139 -0
- package/src/tests/batch.test.ts +69 -0
- package/src/tests/bind.test.ts +84 -0
- package/src/tests/branches.test.ts +343 -0
- package/src/tests/cell.test.ts +111 -0
- package/src/tests/computed.test.ts +146 -0
- package/src/tests/createSelector.test.ts +119 -0
- package/src/tests/debug.test.ts +196 -0
- package/src/tests/effect.test.ts +256 -0
- package/src/tests/resource.test.ts +133 -0
- package/src/tests/scope.test.ts +202 -0
- package/src/tests/signal.test.ts +120 -0
- package/src/tests/store.test.ts +136 -0
- package/src/tests/tracking.test.ts +158 -0
- package/src/tests/watch.test.ts +146 -0
- package/src/tracking.ts +103 -0
- package/src/watch.ts +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/batch.ts","../../src/cell.ts","../../src/scope.ts","../../src/tracking.ts","../../src/computed.ts","../../src/effect.ts","../../src/createSelector.ts","../../src/debug.ts","../../src/signal.ts","../../src/store.ts","../../src/reconcile.ts","../../src/resource.ts","../../src/watch.ts"],"mappings":"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"}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
//#region src/batch.d.ts
|
|
2
|
+
declare function batch(fn: () => void): void;
|
|
3
|
+
/**
|
|
4
|
+
* Returns a Promise that resolves after all currently-pending microtasks have flushed.
|
|
5
|
+
* Useful when you need to read the DOM after a batch of signal updates has settled.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* count.set(1); count.set(2)
|
|
9
|
+
* await nextTick()
|
|
10
|
+
* // DOM is now up-to-date
|
|
11
|
+
*/
|
|
12
|
+
declare function nextTick(): Promise<void>;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/cell.d.ts
|
|
15
|
+
/**
|
|
16
|
+
* Lightweight reactive cell — class-based alternative to signal().
|
|
17
|
+
*
|
|
18
|
+
* - 1 object allocation vs signal()'s 6 closures
|
|
19
|
+
* - Same API surface: peek(), set(), update(), subscribe(), listen()
|
|
20
|
+
* - NOT callable as a getter (no effect tracking) — use for fixed subscriptions
|
|
21
|
+
* - Methods on prototype, shared across all instances
|
|
22
|
+
* - Single-listener fast path: no Set allocated when ≤1 subscriber
|
|
23
|
+
*
|
|
24
|
+
* Use when you need reactive state but don't need automatic effect dependency tracking.
|
|
25
|
+
* Ideal for list item labels in keyed reconcilers where subscribe() is used directly.
|
|
26
|
+
*/
|
|
27
|
+
declare class Cell<T> {
|
|
28
|
+
/** @internal */
|
|
29
|
+
_v: T;
|
|
30
|
+
/** @internal */
|
|
31
|
+
_l: (() => void) | null;
|
|
32
|
+
/** @internal */
|
|
33
|
+
_s: Set<() => void> | null;
|
|
34
|
+
constructor(value: T);
|
|
35
|
+
peek(): T;
|
|
36
|
+
set(value: T): void;
|
|
37
|
+
update(fn: (current: T) => T): void;
|
|
38
|
+
/**
|
|
39
|
+
* Fire-and-forget subscription — no unsubscribe returned.
|
|
40
|
+
* Use when the listener's lifetime matches the cell's (e.g., list rows).
|
|
41
|
+
* Saves 1 closure allocation per call vs subscribe().
|
|
42
|
+
*/
|
|
43
|
+
listen(listener: () => void): void;
|
|
44
|
+
subscribe(listener: () => void): () => void;
|
|
45
|
+
}
|
|
46
|
+
declare function cell<T>(value: T): Cell<T>;
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/computed.d.ts
|
|
49
|
+
interface Computed<T> {
|
|
50
|
+
(): T;
|
|
51
|
+
/** Remove this computed from all its reactive dependencies. */
|
|
52
|
+
dispose(): void;
|
|
53
|
+
}
|
|
54
|
+
interface ComputedOptions<T> {
|
|
55
|
+
/**
|
|
56
|
+
* Custom equality function. When provided, the computed eagerly re-evaluates
|
|
57
|
+
* on dependency change and only notifies downstream if `equals(prev, next)`
|
|
58
|
+
* returns false. Useful for derived objects/arrays to skip spurious updates.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* const sorted = computed(() => items().slice().sort(), {
|
|
62
|
+
* equals: (a, b) => a.length === b.length && a.every((v, i) => v === b[i])
|
|
63
|
+
* })
|
|
64
|
+
*/
|
|
65
|
+
equals?: (prev: T, next: T) => boolean;
|
|
66
|
+
}
|
|
67
|
+
declare function computed<T>(fn: () => T, options?: ComputedOptions<T>): Computed<T>;
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/createSelector.d.ts
|
|
70
|
+
/**
|
|
71
|
+
* Create an equality selector — returns a reactive predicate that is true
|
|
72
|
+
* only for the currently selected value.
|
|
73
|
+
*
|
|
74
|
+
* Unlike a plain `() => source() === value`, this only triggers the TWO
|
|
75
|
+
* affected subscribers (deselected + newly selected) instead of ALL
|
|
76
|
+
* subscribers, making selection O(1) regardless of list size.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* const isSelected = createSelector(selectedId)
|
|
80
|
+
* // In each row:
|
|
81
|
+
* class: () => (isSelected(row.id) ? "selected" : "")
|
|
82
|
+
*/
|
|
83
|
+
declare function createSelector<T>(source: () => T): (value: T) => boolean;
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/signal.d.ts
|
|
86
|
+
interface SignalDebugInfo<T> {
|
|
87
|
+
/** Signal name (set via options or inferred) */
|
|
88
|
+
name: string | undefined;
|
|
89
|
+
/** Current value (same as peek()) */
|
|
90
|
+
value: T;
|
|
91
|
+
/** Number of active subscribers */
|
|
92
|
+
subscriberCount: number;
|
|
93
|
+
}
|
|
94
|
+
interface Signal<T> {
|
|
95
|
+
(): T;
|
|
96
|
+
/** Read the current value WITHOUT registering a reactive dependency. */
|
|
97
|
+
peek(): T;
|
|
98
|
+
set(value: T): void;
|
|
99
|
+
update(fn: (current: T) => T): void;
|
|
100
|
+
/**
|
|
101
|
+
* Subscribe a static listener directly — no effect overhead (no withTracking,
|
|
102
|
+
* no cleanupEffect, no effectDeps WeakMap). Use when the dependency is fixed
|
|
103
|
+
* and dynamic re-tracking is not needed.
|
|
104
|
+
* Returns a disposer that removes the subscription.
|
|
105
|
+
*/
|
|
106
|
+
subscribe(listener: () => void): () => void;
|
|
107
|
+
/** Debug name — useful for devtools and logging. */
|
|
108
|
+
label: string | undefined;
|
|
109
|
+
/** Returns a snapshot of the signal's debug info (value, name, subscriber count). */
|
|
110
|
+
debug(): SignalDebugInfo<T>;
|
|
111
|
+
}
|
|
112
|
+
interface SignalOptions {
|
|
113
|
+
/** Debug name for this signal — shows up in devtools and debug() output. */
|
|
114
|
+
name?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Create a reactive signal.
|
|
118
|
+
*
|
|
119
|
+
* Only 1 closure is allocated (the read function). State is stored as
|
|
120
|
+
* properties on the function object (_v, _s) and methods (peek, set,
|
|
121
|
+
* update, subscribe) are shared across all signals — not per-signal closures.
|
|
122
|
+
*/
|
|
123
|
+
declare function signal<T>(initialValue: T, options?: SignalOptions): Signal<T>;
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/debug.d.ts
|
|
126
|
+
interface SignalUpdateEvent {
|
|
127
|
+
/** The signal that changed */
|
|
128
|
+
signal: Signal<unknown>;
|
|
129
|
+
/** Signal name (from options or label) */
|
|
130
|
+
name: string | undefined;
|
|
131
|
+
/** Previous value */
|
|
132
|
+
prev: unknown;
|
|
133
|
+
/** New value */
|
|
134
|
+
next: unknown;
|
|
135
|
+
/** Stack trace at the point of the .set() / .update() call */
|
|
136
|
+
stack: string;
|
|
137
|
+
/** Timestamp */
|
|
138
|
+
timestamp: number;
|
|
139
|
+
}
|
|
140
|
+
type SignalUpdateListener = (event: SignalUpdateEvent) => void;
|
|
141
|
+
/**
|
|
142
|
+
* Register a listener that fires on every signal write.
|
|
143
|
+
* Returns a dispose function.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* const dispose = onSignalUpdate(e => {
|
|
147
|
+
* console.log(`${e.name ?? 'anonymous'}: ${e.prev} → ${e.next}`)
|
|
148
|
+
* })
|
|
149
|
+
*/
|
|
150
|
+
declare function onSignalUpdate(listener: SignalUpdateListener): () => void;
|
|
151
|
+
/**
|
|
152
|
+
* Trace the next signal update. Logs which signals fire and what changed.
|
|
153
|
+
* Call before triggering a state change to see what updates and why.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* why()
|
|
157
|
+
* count.set(5)
|
|
158
|
+
* // Console: [pyreon:why] "count": 3 → 5 (2 subscribers)
|
|
159
|
+
*/
|
|
160
|
+
declare function why(): void;
|
|
161
|
+
/**
|
|
162
|
+
* Print a signal's current state to the console in a readable format.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* const count = signal(42, { name: "count" })
|
|
166
|
+
* inspectSignal(count)
|
|
167
|
+
* // Console:
|
|
168
|
+
* // 🔍 Signal "count"
|
|
169
|
+
* // value: 42
|
|
170
|
+
* // subscribers: 3
|
|
171
|
+
*/
|
|
172
|
+
declare function inspectSignal<T>(sig: Signal<T>): SignalDebugInfo<T>;
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/effect.d.ts
|
|
175
|
+
interface Effect {
|
|
176
|
+
dispose(): void;
|
|
177
|
+
}
|
|
178
|
+
declare function setErrorHandler(fn: (err: unknown) => void): void;
|
|
179
|
+
declare function effect(fn: () => (() => void) | void): Effect;
|
|
180
|
+
/**
|
|
181
|
+
* Lightweight effect for DOM render bindings.
|
|
182
|
+
*
|
|
183
|
+
* Differences from `effect()`:
|
|
184
|
+
* - No EffectScope registration (caller owns the dispose lifecycle)
|
|
185
|
+
* - No error handler (errors propagate naturally)
|
|
186
|
+
* - No onUpdate notification
|
|
187
|
+
* - Deps stored in a local array instead of the global WeakMap — faster
|
|
188
|
+
* creation and disposal (~200ns saved per effect vs WeakMap path)
|
|
189
|
+
*
|
|
190
|
+
* Returns a dispose function (not an Effect object — saves 1 allocation).
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* Static-dep binding — compiler helper for template expressions.
|
|
194
|
+
*
|
|
195
|
+
* Like renderEffect but assumes dependencies never change (true for all
|
|
196
|
+
* compiler-emitted template bindings like `_tpl()` text/attribute updates).
|
|
197
|
+
*
|
|
198
|
+
* Tracks dependencies only on the first run. Re-runs skip cleanup, re-tracking,
|
|
199
|
+
* and tracking context save/restore entirely — just calls `fn()` directly.
|
|
200
|
+
*
|
|
201
|
+
* Per re-run savings vs renderEffect:
|
|
202
|
+
* - No deps iteration + Set.delete (cleanup)
|
|
203
|
+
* - No setDepsCollector + withTracking (re-registration)
|
|
204
|
+
* - Signal reads hit `if (activeEffect)` null check → instant return
|
|
205
|
+
*/
|
|
206
|
+
declare function _bind(fn: () => void): () => void;
|
|
207
|
+
declare function renderEffect(fn: () => void): () => void;
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/reconcile.d.ts
|
|
210
|
+
/**
|
|
211
|
+
* reconcile — surgically diff new state into an existing createStore proxy.
|
|
212
|
+
*
|
|
213
|
+
* Instead of replacing the store root (which would trigger all downstream effects),
|
|
214
|
+
* reconcile walks both the new value and the store in parallel and only calls
|
|
215
|
+
* `.set()` on signals whose value actually changed.
|
|
216
|
+
*
|
|
217
|
+
* Ideal for applying API responses to a long-lived store:
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* const state = createStore({ user: { name: "Alice", age: 30 }, items: [] })
|
|
221
|
+
*
|
|
222
|
+
* // API response arrives:
|
|
223
|
+
* reconcile({ user: { name: "Alice", age: 31 }, items: [{ id: 1 }] }, state)
|
|
224
|
+
* // → only state.user.age signal fires (name unchanged)
|
|
225
|
+
* // → state.items[0] is newly created
|
|
226
|
+
*
|
|
227
|
+
* Arrays are reconciled by index — elements at the same index are recursively
|
|
228
|
+
* diffed rather than replaced wholesale. Excess old elements are removed.
|
|
229
|
+
*/
|
|
230
|
+
declare function reconcile<T extends object>(source: T, target: T): void;
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/resource.d.ts
|
|
233
|
+
interface Resource<T> {
|
|
234
|
+
/** The latest resolved value (undefined while loading or on error). */
|
|
235
|
+
data: Signal<T | undefined>;
|
|
236
|
+
/** True while a fetch is in flight. */
|
|
237
|
+
loading: Signal<boolean>;
|
|
238
|
+
/** The last error thrown by the fetcher, or undefined. */
|
|
239
|
+
error: Signal<unknown>;
|
|
240
|
+
/** Re-run the fetcher with the current source value. */
|
|
241
|
+
refetch(): void;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Async data primitive. Fetches data reactively whenever `source()` changes.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* const userId = signal(1)
|
|
248
|
+
* const user = createResource(userId, (id) => fetchUser(id))
|
|
249
|
+
* // user.data() — the fetched user (undefined while loading)
|
|
250
|
+
* // user.loading() — true while in flight
|
|
251
|
+
* // user.error() — last error
|
|
252
|
+
*/
|
|
253
|
+
declare function createResource<T, P>(source: () => P, fetcher: (param: P) => Promise<T>): Resource<T>;
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/scope.d.ts
|
|
256
|
+
declare class EffectScope {
|
|
257
|
+
private _effects;
|
|
258
|
+
private _active;
|
|
259
|
+
private _updateHooks;
|
|
260
|
+
private _updatePending;
|
|
261
|
+
/** Register an effect/computed to be disposed when this scope stops. */
|
|
262
|
+
add(e: {
|
|
263
|
+
dispose(): void;
|
|
264
|
+
}): void;
|
|
265
|
+
/**
|
|
266
|
+
* Temporarily re-activate this scope so effects created inside `fn` are
|
|
267
|
+
* auto-tracked and will be disposed when the scope stops.
|
|
268
|
+
* Used to ensure effects created in `onMount` callbacks belong to their
|
|
269
|
+
* component's scope rather than leaking as global effects.
|
|
270
|
+
*/
|
|
271
|
+
runInScope<T>(fn: () => T): T;
|
|
272
|
+
/** Register a callback to run after any reactive update in this scope. */
|
|
273
|
+
addUpdateHook(fn: () => void): void;
|
|
274
|
+
/**
|
|
275
|
+
* Called by effects after each non-initial re-run.
|
|
276
|
+
* Schedules onUpdate hooks via microtask so all synchronous effects settle first.
|
|
277
|
+
*/
|
|
278
|
+
notifyEffectRan(): void;
|
|
279
|
+
/** Dispose all tracked effects. */
|
|
280
|
+
stop(): void;
|
|
281
|
+
}
|
|
282
|
+
declare function getCurrentScope(): EffectScope | null;
|
|
283
|
+
declare function setCurrentScope(scope: EffectScope | null): void;
|
|
284
|
+
/** Create a new EffectScope. */
|
|
285
|
+
declare function effectScope(): EffectScope;
|
|
286
|
+
//#endregion
|
|
287
|
+
//#region src/store.d.ts
|
|
288
|
+
/**
|
|
289
|
+
* createStore — deep reactive Proxy store.
|
|
290
|
+
*
|
|
291
|
+
* Wraps a plain object/array in a Proxy that creates a fine-grained signal for
|
|
292
|
+
* every property. Direct mutations (`store.count++`, `store.items[0].label = "x"`)
|
|
293
|
+
* trigger only the signals for the mutated properties — not the whole tree.
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* const state = createStore({ count: 0, items: [{ id: 1, text: "hello" }] })
|
|
297
|
+
*
|
|
298
|
+
* effect(() => console.log(state.count)) // tracks state.count only
|
|
299
|
+
* state.count++ // only the count effect re-runs
|
|
300
|
+
* state.items[0].text = "world" // only text-tracking effects re-run
|
|
301
|
+
*/
|
|
302
|
+
/** Returns true if the value is a createStore proxy. */
|
|
303
|
+
declare function isStore(value: unknown): boolean;
|
|
304
|
+
/**
|
|
305
|
+
* Create a deep reactive store from a plain object or array.
|
|
306
|
+
* Returns a proxy — mutations to the proxy trigger fine-grained reactive updates.
|
|
307
|
+
*/
|
|
308
|
+
declare function createStore<T extends object>(initial: T): T;
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/tracking.d.ts
|
|
311
|
+
declare function runUntracked<T>(fn: () => T): T;
|
|
312
|
+
//#endregion
|
|
313
|
+
//#region src/watch.d.ts
|
|
314
|
+
interface WatchOptions {
|
|
315
|
+
/** If true, call the callback immediately with the current value on setup. Default: false. */
|
|
316
|
+
immediate?: boolean;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Watch a reactive source and run a callback whenever it changes.
|
|
320
|
+
*
|
|
321
|
+
* Returns a stop function that disposes the watcher.
|
|
322
|
+
*
|
|
323
|
+
* The callback receives (newValue, oldValue). On the first call (when
|
|
324
|
+
* `immediate` is true) oldValue is `undefined`.
|
|
325
|
+
*
|
|
326
|
+
* The callback may return a cleanup function that is called before each
|
|
327
|
+
* re-run and on stop — useful for cancelling async work.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* const stop = watch(
|
|
331
|
+
* () => userId(),
|
|
332
|
+
* async (id, prev) => {
|
|
333
|
+
* const data = await fetch(`/api/user/${id}`)
|
|
334
|
+
* setUser(await data.json())
|
|
335
|
+
* },
|
|
336
|
+
* )
|
|
337
|
+
* // Later: stop()
|
|
338
|
+
*/
|
|
339
|
+
declare function watch<T>(source: () => T, callback: (newVal: T, oldVal: T | undefined) => void | (() => void), opts?: WatchOptions): () => void;
|
|
340
|
+
//#endregion
|
|
341
|
+
export { Cell, type Computed, type ComputedOptions, type Effect, EffectScope, type Resource, type Signal, type SignalDebugInfo, type SignalOptions, type WatchOptions, _bind, batch, cell, computed, createResource, createSelector, createStore, effect, effectScope, getCurrentScope, inspectSignal, isStore, nextTick, onSignalUpdate, reconcile, renderEffect, runUntracked, setCurrentScope, setErrorHandler, signal, watch, why };
|
|
342
|
+
//# sourceMappingURL=index2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/batch.ts","../../src/cell.ts","../../src/computed.ts","../../src/createSelector.ts","../../src/signal.ts","../../src/debug.ts","../../src/effect.ts","../../src/reconcile.ts","../../src/resource.ts","../../src/scope.ts","../../src/store.ts","../../src/tracking.ts","../../src/watch.ts"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pyreon/reactivity",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Signals-based reactivity system for Pyreon",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/pyreon/pyreon.git",
|
|
9
|
+
"directory": "packages/reactivity"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/reactivity#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/pyreon/pyreon/issues"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"lib",
|
|
17
|
+
"src",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./lib/index.js",
|
|
24
|
+
"module": "./lib/index.js",
|
|
25
|
+
"types": "./lib/types/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"bun": "./src/index.ts",
|
|
29
|
+
"import": "./lib/index.js",
|
|
30
|
+
"types": "./lib/types/index.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "vl_rolldown_build",
|
|
35
|
+
"dev": "vl_rolldown_build-watch",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"prepublishOnly": "bun run build"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/batch.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Batch multiple signal updates into a single notification pass.
|
|
2
|
+
// Uses a Set so the same subscriber is never flushed more than once per batch,
|
|
3
|
+
// even if multiple signals it depends on change within the same batch.
|
|
4
|
+
|
|
5
|
+
let batchDepth = 0
|
|
6
|
+
let pendingNotifications = new Set<() => void>()
|
|
7
|
+
|
|
8
|
+
export function batch(fn: () => void): void {
|
|
9
|
+
batchDepth++
|
|
10
|
+
try {
|
|
11
|
+
fn()
|
|
12
|
+
} finally {
|
|
13
|
+
batchDepth--
|
|
14
|
+
if (batchDepth === 0) {
|
|
15
|
+
// Swap to a fresh Set before flushing so new enqueues during notification
|
|
16
|
+
// (e.g. from nested batch() calls) land in the new Set and are handled in
|
|
17
|
+
// the next flush pass, not mixed into the current iteration.
|
|
18
|
+
const flush = pendingNotifications
|
|
19
|
+
pendingNotifications = new Set()
|
|
20
|
+
for (const notify of flush) notify()
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function isBatching(): boolean {
|
|
26
|
+
return batchDepth > 0
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function enqueuePendingNotification(notify: () => void): void {
|
|
30
|
+
pendingNotifications.add(notify)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns a Promise that resolves after all currently-pending microtasks have flushed.
|
|
35
|
+
* Useful when you need to read the DOM after a batch of signal updates has settled.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* count.set(1); count.set(2)
|
|
39
|
+
* await nextTick()
|
|
40
|
+
* // DOM is now up-to-date
|
|
41
|
+
*/
|
|
42
|
+
export function nextTick(): Promise<void> {
|
|
43
|
+
return new Promise((resolve) => queueMicrotask(resolve))
|
|
44
|
+
}
|
package/src/cell.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight reactive cell — class-based alternative to signal().
|
|
3
|
+
*
|
|
4
|
+
* - 1 object allocation vs signal()'s 6 closures
|
|
5
|
+
* - Same API surface: peek(), set(), update(), subscribe(), listen()
|
|
6
|
+
* - NOT callable as a getter (no effect tracking) — use for fixed subscriptions
|
|
7
|
+
* - Methods on prototype, shared across all instances
|
|
8
|
+
* - Single-listener fast path: no Set allocated when ≤1 subscriber
|
|
9
|
+
*
|
|
10
|
+
* Use when you need reactive state but don't need automatic effect dependency tracking.
|
|
11
|
+
* Ideal for list item labels in keyed reconcilers where subscribe() is used directly.
|
|
12
|
+
*/
|
|
13
|
+
export class Cell<T> {
|
|
14
|
+
/** @internal */ _v: T
|
|
15
|
+
/** @internal */ _l: (() => void) | null = null // single-listener fast path
|
|
16
|
+
/** @internal */ _s: Set<() => void> | null = null // multi-listener fallback
|
|
17
|
+
|
|
18
|
+
constructor(value: T) {
|
|
19
|
+
this._v = value
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
peek(): T {
|
|
23
|
+
return this._v
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
set(value: T): void {
|
|
27
|
+
if (Object.is(this._v, value)) return
|
|
28
|
+
this._v = value
|
|
29
|
+
if (this._l) this._l()
|
|
30
|
+
else if (this._s) for (const fn of this._s) fn()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
update(fn: (current: T) => T): void {
|
|
34
|
+
this.set(fn(this._v))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Fire-and-forget subscription — no unsubscribe returned.
|
|
39
|
+
* Use when the listener's lifetime matches the cell's (e.g., list rows).
|
|
40
|
+
* Saves 1 closure allocation per call vs subscribe().
|
|
41
|
+
*/
|
|
42
|
+
listen(listener: () => void): void {
|
|
43
|
+
if (!this._l && !this._s) {
|
|
44
|
+
this._l = listener
|
|
45
|
+
} else {
|
|
46
|
+
// Promote to Set
|
|
47
|
+
if (!this._s) {
|
|
48
|
+
this._s = new Set()
|
|
49
|
+
if (this._l) {
|
|
50
|
+
this._s.add(this._l)
|
|
51
|
+
this._l = null
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
this._s.add(listener)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
subscribe(listener: () => void): () => void {
|
|
59
|
+
this.listen(listener)
|
|
60
|
+
if (this._l === listener) {
|
|
61
|
+
return () => {
|
|
62
|
+
if (this._l === listener) this._l = null
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return () => this._s?.delete(listener)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function cell<T>(value: T): Cell<T> {
|
|
70
|
+
return new Cell(value)
|
|
71
|
+
}
|
package/src/computed.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { getCurrentScope } from "./scope"
|
|
2
|
+
import { cleanupEffect, notifySubscribers, trackSubscriber, withTracking } from "./tracking"
|
|
3
|
+
|
|
4
|
+
export interface Computed<T> {
|
|
5
|
+
(): T
|
|
6
|
+
/** Remove this computed from all its reactive dependencies. */
|
|
7
|
+
dispose(): void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ComputedOptions<T> {
|
|
11
|
+
/**
|
|
12
|
+
* Custom equality function. When provided, the computed eagerly re-evaluates
|
|
13
|
+
* on dependency change and only notifies downstream if `equals(prev, next)`
|
|
14
|
+
* returns false. Useful for derived objects/arrays to skip spurious updates.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const sorted = computed(() => items().slice().sort(), {
|
|
18
|
+
* equals: (a, b) => a.length === b.length && a.every((v, i) => v === b[i])
|
|
19
|
+
* })
|
|
20
|
+
*/
|
|
21
|
+
equals?: (prev: T, next: T) => boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function computed<T>(fn: () => T, options?: ComputedOptions<T>): Computed<T> {
|
|
25
|
+
let value: T
|
|
26
|
+
let dirty = true
|
|
27
|
+
let initialized = false
|
|
28
|
+
let disposed = false
|
|
29
|
+
const customEquals = options?.equals
|
|
30
|
+
|
|
31
|
+
// SubscriberHost — _s is lazily allocated by trackSubscriber
|
|
32
|
+
const host: { _s: Set<() => void> | null } = { _s: null }
|
|
33
|
+
|
|
34
|
+
const recompute = () => {
|
|
35
|
+
if (disposed) return
|
|
36
|
+
// Remove from all current deps before re-evaluating (dynamic deps support)
|
|
37
|
+
cleanupEffect(recompute)
|
|
38
|
+
if (customEquals) {
|
|
39
|
+
// Eager evaluation: only notify downstream if the value actually changed
|
|
40
|
+
const next = withTracking(recompute, fn)
|
|
41
|
+
if (initialized && customEquals(value as T, next)) return
|
|
42
|
+
value = next
|
|
43
|
+
dirty = false
|
|
44
|
+
initialized = true
|
|
45
|
+
if (host._s) notifySubscribers(host._s)
|
|
46
|
+
} else {
|
|
47
|
+
dirty = true
|
|
48
|
+
if (host._s) notifySubscribers(host._s)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const read = (): T => {
|
|
53
|
+
trackSubscriber(host)
|
|
54
|
+
if (dirty) {
|
|
55
|
+
value = withTracking(recompute, fn)
|
|
56
|
+
dirty = false
|
|
57
|
+
initialized = true
|
|
58
|
+
}
|
|
59
|
+
return value as T
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
read.dispose = () => {
|
|
63
|
+
disposed = true
|
|
64
|
+
cleanupEffect(recompute)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Auto-register with the active EffectScope (if any)
|
|
68
|
+
getCurrentScope()?.add({ dispose: read.dispose })
|
|
69
|
+
|
|
70
|
+
return read
|
|
71
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { effect } from "./effect"
|
|
2
|
+
import { trackSubscriber } from "./tracking"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create an equality selector — returns a reactive predicate that is true
|
|
6
|
+
* only for the currently selected value.
|
|
7
|
+
*
|
|
8
|
+
* Unlike a plain `() => source() === value`, this only triggers the TWO
|
|
9
|
+
* affected subscribers (deselected + newly selected) instead of ALL
|
|
10
|
+
* subscribers, making selection O(1) regardless of list size.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const isSelected = createSelector(selectedId)
|
|
14
|
+
* // In each row:
|
|
15
|
+
* class: () => (isSelected(row.id) ? "selected" : "")
|
|
16
|
+
*/
|
|
17
|
+
export function createSelector<T>(source: () => T): (value: T) => boolean {
|
|
18
|
+
const subs = new Map<T, Set<() => void>>()
|
|
19
|
+
let current: T
|
|
20
|
+
let initialized = false
|
|
21
|
+
|
|
22
|
+
effect(() => {
|
|
23
|
+
const next = source()
|
|
24
|
+
if (!initialized) {
|
|
25
|
+
initialized = true
|
|
26
|
+
current = next
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
if (Object.is(next, current)) return
|
|
30
|
+
const old = current
|
|
31
|
+
current = next
|
|
32
|
+
// Only notify the two affected buckets — O(1) regardless of list size
|
|
33
|
+
const oldBucket = subs.get(old)
|
|
34
|
+
const newBucket = subs.get(next)
|
|
35
|
+
if (oldBucket) for (const fn of [...oldBucket]) fn()
|
|
36
|
+
if (newBucket) for (const fn of [...newBucket]) fn()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
// Reusable hosts per value — avoids allocating a closure per trackSubscriber call
|
|
40
|
+
const hosts = new Map<T, { _s: Set<() => void> | null }>()
|
|
41
|
+
|
|
42
|
+
return (value: T): boolean => {
|
|
43
|
+
let host = hosts.get(value)
|
|
44
|
+
if (!host) {
|
|
45
|
+
let bucket = subs.get(value)
|
|
46
|
+
if (!bucket) {
|
|
47
|
+
bucket = new Set()
|
|
48
|
+
subs.set(value, bucket)
|
|
49
|
+
}
|
|
50
|
+
host = { _s: bucket }
|
|
51
|
+
hosts.set(value, host)
|
|
52
|
+
}
|
|
53
|
+
trackSubscriber(host)
|
|
54
|
+
return Object.is(current, value)
|
|
55
|
+
}
|
|
56
|
+
}
|