@solidjs/signals 2.0.0-rc.17 → 2.0.0-rc.19
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/dist/dev-shared.js +426 -241
- package/dist/dev.attribution.js +19 -16
- package/dist/dev.js +768 -409
- package/dist/observe/boundaries.js +88 -67
- package/dist/observe/core/action.js +8 -0
- package/dist/observe/core/async.js +183 -138
- package/dist/observe/core/attribution.js +30 -28
- package/dist/observe/core/constants.js +23 -1
- package/dist/observe/core/core.js +185 -157
- package/dist/observe/core/effect.js +34 -37
- package/dist/observe/core/graph.js +8 -8
- package/dist/observe/core/heap.js +5 -5
- package/dist/observe/core/lanes.js +104 -84
- package/dist/observe/core/owner.js +17 -16
- package/dist/observe/core/scheduler.js +61 -47
- package/dist/observe/core/truth.js +6 -6
- package/dist/observe/core/verdict.js +15 -15
- package/dist/observe/deferred.js +40 -38
- package/dist/observe/from.js +248 -0
- package/dist/observe/index.js +4 -2
- package/dist/observe/map.js +22 -22
- package/dist/observe/reveal.js +5 -5
- package/dist/observe/signals.js +57 -15
- package/dist/observe/store/affects.js +1 -1
- package/dist/observe/store/hooks.js +3 -0
- package/dist/observe/store/optimistic.js +11 -11
- package/dist/observe/store/projection.js +34 -21
- package/dist/observe/store/reconcile.js +138 -122
- package/dist/observe/store/store.js +628 -641
- package/dist/observe/store/target.js +1 -5
- package/dist/observe/store/utils.js +7 -2
- package/dist/prod/boundaries.js +153 -132
- package/dist/prod/core/action.js +8 -0
- package/dist/prod/core/async.js +242 -197
- package/dist/prod/core/constants.js +16 -1
- package/dist/prod/core/core.js +166 -138
- package/dist/prod/core/effect.js +31 -34
- package/dist/prod/core/graph.js +5 -5
- package/dist/prod/core/heap.js +12 -12
- package/dist/prod/core/lanes.js +98 -78
- package/dist/prod/core/owner.js +15 -14
- package/dist/prod/core/scheduler.js +64 -50
- package/dist/prod/core/truth.js +6 -6
- package/dist/prod/core/verdict.js +17 -17
- package/dist/prod/deferred.js +40 -38
- package/dist/prod/from.js +248 -0
- package/dist/prod/index.js +4 -2
- package/dist/prod/map.js +14 -14
- package/dist/prod/reveal.js +8 -8
- package/dist/prod/signals.js +46 -4
- package/dist/prod/store/affects.js +1 -1
- package/dist/prod/store/hooks.js +3 -0
- package/dist/prod/store/optimistic.js +16 -16
- package/dist/prod/store/projection.js +22 -9
- package/dist/prod/store/reconcile.js +138 -122
- package/dist/prod/store/store.js +308 -331
- package/dist/prod/store/target.js +13 -17
- package/dist/prod/store/utils.js +2 -0
- package/dist/types/core/action.d.ts +8 -0
- package/dist/types/core/async.d.ts +12 -2
- package/dist/types/core/constants.d.ts +25 -0
- package/dist/types/core/core.d.ts +33 -4
- package/dist/types/core/dev.d.ts +1 -1
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +5 -1
- package/dist/types/core/scheduler.d.ts +17 -3
- package/dist/types/from.d.ts +47 -0
- package/dist/types/index.d.ts +4 -1
- package/dist/types/signals.d.ts +37 -0
- package/dist/types/store/target.d.ts +2 -0
- package/package.json +1 -1
|
@@ -17,31 +17,27 @@ const $OWNER = Symbol(0);
|
|
|
17
17
|
/** raw → target for plain (family-less) stores. Family stores use their own
|
|
18
18
|
* map so one raw can wrap once per family (§7b). */ const storeLookup = new WeakMap;
|
|
19
19
|
|
|
20
|
-
function setLookup(
|
|
21
|
-
(
|
|
20
|
+
function setLookup(o, e) {
|
|
21
|
+
(e.fam?.map ?? storeLookup).set(o, e);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
function isOwned(
|
|
25
|
-
return
|
|
24
|
+
function isOwned(o) {
|
|
25
|
+
return o[$OWNER] !== undefined;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/** The target wrapping `raw` in `fam` (or the plain lookup). An owned raw
|
|
29
|
-
* answers from its stamp; a user raw from the map. */ function lookupTarget(
|
|
30
|
-
const
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function devAssertNeverUserMutation(e) {
|
|
35
|
-
return;
|
|
29
|
+
* answers from its stamp; a user raw from the map. */ function lookupTarget(o, e) {
|
|
30
|
+
const n = o[$OWNER];
|
|
31
|
+
return n !== undefined && n.fam === e ? n : (e?.map ?? storeLookup).get(o);
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
/** Sticky descendants flag up the parent chain (§6d): adoption descends
|
|
39
|
-
* into a changed child pair only where a target with nodes exists below. */ function markDescendants(
|
|
40
|
-
let
|
|
41
|
-
while (
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
* into a changed child pair only where a target with nodes exists below. */ function markDescendants(o) {
|
|
36
|
+
let e = o;
|
|
37
|
+
while (e && !e.d) {
|
|
38
|
+
e.d = true;
|
|
39
|
+
e = e.u;
|
|
44
40
|
}
|
|
45
41
|
}
|
|
46
42
|
|
|
47
|
-
export { $OWNER,
|
|
43
|
+
export { $OWNER, isOwned, lookupTarget, markDescendants, setLookup, storeLookup };
|
package/dist/prod/store/utils.js
CHANGED
|
@@ -921,6 +921,8 @@ const omitTraps = {
|
|
|
921
921
|
f++;
|
|
922
922
|
i = o;
|
|
923
923
|
if (typeof o === "function") {
|
|
924
|
+
// Observe tiers name it and exempt it from UNSTABLE_MEMO_OUTPUT (see
|
|
925
|
+
// CONFIG_KEY_BAG); prod passes no options.
|
|
924
926
|
n[r] = createMemo(o);
|
|
925
927
|
t[r++] = SOURCE_MEMO;
|
|
926
928
|
continue;
|
|
@@ -40,6 +40,14 @@
|
|
|
40
40
|
* yield until(() => todos.some(t => t.id === saved.id));
|
|
41
41
|
* ```
|
|
42
42
|
*
|
|
43
|
+
* The same holds inside an async helper the action yields
|
|
44
|
+
* (`yield (async () => { ... })()`): everything after its first `await` runs
|
|
45
|
+
* outside the transaction. An `await refresh(x)` or `await until(...)` there
|
|
46
|
+
* waits for this action's commit, which waits on the helper, so it hangs
|
|
47
|
+
* whenever `x` re-ran during the action (#4263) and works otherwise. Call
|
|
48
|
+
* `refresh(x)` in the generator once the helper returns; `yield` it only when
|
|
49
|
+
* the action needs the fresh value.
|
|
50
|
+
*
|
|
43
51
|
* (For the same reason, don't call `flush()` inside an action body — it
|
|
44
52
|
* cannot reveal the held writes and is refused.)
|
|
45
53
|
*
|
|
@@ -27,12 +27,22 @@ export declare function settlePendingSource(el: Computed<any>, source?: Computed
|
|
|
27
27
|
export declare function isThenable<T>(value: T | PromiseLike<T>): value is PromiseLike<T>;
|
|
28
28
|
/** Fire and clear a node's iterator-flight cancellation hook (#3122). */
|
|
29
29
|
export declare function releaseFlightTeardown(el: Computed<any>): void;
|
|
30
|
+
/**
|
|
31
|
+
* Internal (not a package export): run `fn` when the current pass's flight
|
|
32
|
+
* is superseded, at the same instant as the iterator close above, instead of
|
|
33
|
+
* when the replacing pass commits (owner cleanups wait for that). Chains onto
|
|
34
|
+
* the node's teardown slot; fires once with it. A no-op unless the ambient
|
|
35
|
+
* owner is a computed in its own pass. `consumeIterator` fills the slot
|
|
36
|
+
* before its first pull, so a source opened in an async generator's body
|
|
37
|
+
* (`for await`) composes after the generator's close.
|
|
38
|
+
*/
|
|
39
|
+
export declare function onSupersede(fn: () => void): void;
|
|
30
40
|
export declare function handleAsync<T>(el: Computed<T>, result: T | PromiseLike<T> | AsyncIterable<T>, setter?: (value: T) => void, onError?: (error: unknown, pending: boolean) => void): T;
|
|
31
41
|
export declare function clearStatus(el: Computed<any>, clearUninitialized?: boolean): void;
|
|
32
|
-
export declare function notifyStatus(el: Computed<any>, status: number, error: any
|
|
42
|
+
export declare function notifyStatus(el: Computed<any>, status: number, error: any): void;
|
|
33
43
|
/** The dependents' half of `notifyStatus`: `el`'s status reaches each
|
|
34
44
|
* subscriber as a propagated mark (or a re-derive). On its own for a store
|
|
35
45
|
* family's leaves, which are not the derive's dependents — the family
|
|
36
46
|
* propagates the derive's status from each leaf to the leaf's readers
|
|
37
47
|
* (store/projection.ts `wakeFamily`), exactly as a memo's would reach its. */
|
|
38
|
-
export declare function propagateStatus(el: Computed<any>, status: number, error: any
|
|
48
|
+
export declare function propagateStatus(el: Computed<any>, status: number, error: any): void;
|
|
@@ -185,10 +185,30 @@ export declare const CONFIG_WIDE: number;
|
|
|
185
185
|
* creation by dev builds only (the observe artifact mangles the option name,
|
|
186
186
|
* as it does `_wide`). */
|
|
187
187
|
export declare const CONFIG_SUPERSEDES: number;
|
|
188
|
+
/** Observe tiers only: the memo `merge()` creates for a function source — a
|
|
189
|
+
* key bag readers consume key by key, built by the framework (a compiled
|
|
190
|
+
* component spread) with options no user can reach. The attribution engine's
|
|
191
|
+
* UNSTABLE_MEMO_OUTPUT skips it: a fresh-but-equal bag is the idiom
|
|
192
|
+
* (`{...(on() ? { a } : {})}`), and the advice (`equals`) cannot be applied
|
|
193
|
+
* (#4256). Set through `_extraConfig` by observe builds only. */
|
|
194
|
+
export declare const CONFIG_KEY_BAG: number;
|
|
195
|
+
/** The frame (rule 3, D-3): a render effect (set at creation, as
|
|
196
|
+
* `EFFECT_RENDER << 23` — keep the two in step), and a boundary's tree and
|
|
197
|
+
* output (boundaries.ts) — structure between the content and the render
|
|
198
|
+
* effect that shows it, not a user derivation of the content. Outside a
|
|
199
|
+
* hold's own flush it reads that hold's values as committed and is
|
|
200
|
+
* re-derived at its landing, and a re-pass of it publishes mainline: it
|
|
201
|
+
* joins nothing, so two mounts under one boundary made in separate flushes
|
|
202
|
+
* keep their holds apart (D-4, S-5 rows 1′–3′, #4283). */
|
|
203
|
+
export declare const CONFIG_FRAME: number;
|
|
188
204
|
export declare const STATUS_NONE = 0;
|
|
189
205
|
export declare const STATUS_PENDING: number;
|
|
190
206
|
export declare const STATUS_ERROR: number;
|
|
191
207
|
export declare const STATUS_UNINITIALIZED: number;
|
|
208
|
+
/** An error that answered a node's first read (no value has ever landed):
|
|
209
|
+
* the error, not UNINITIALIZED, is its status while shown, but a re-ask
|
|
210
|
+
* makes it uninitialized-pending again — it still has no value (#4244). */
|
|
211
|
+
export declare const STATUS_NO_VALUE: number;
|
|
192
212
|
/** `catchHook`'s answer when the catcher is a boundary re-armed by
|
|
193
213
|
* `on` (truthy, as any catch): what it collects is its own, not the hold's. */
|
|
194
214
|
export declare const CAUGHT_REARMED = 2;
|
|
@@ -219,3 +239,8 @@ export declare const $REFRESH: unique symbol;
|
|
|
219
239
|
export type Refreshable<T> = T & {
|
|
220
240
|
readonly [$REFRESH]: any;
|
|
221
241
|
};
|
|
242
|
+
/** `Set` under a module binding. Bundlers mark a bare `new Set()` pure with
|
|
243
|
+
* a `/* @__PURE__ *\/` comment that survives minification (16 bytes a site);
|
|
244
|
+
* a construction through a binding carries none. Same constructor, so the
|
|
245
|
+
* same objects. */
|
|
246
|
+
export declare const NewSet: SetConstructor;
|
|
@@ -20,7 +20,20 @@ export declare let context: Owner | null;
|
|
|
20
20
|
export declare let snapshotCaptureActive: boolean;
|
|
21
21
|
export declare let snapshotSources: Set<any> | null;
|
|
22
22
|
export declare function setSnapshotCapture(active: boolean): void;
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Marks `owner` a snapshot scope: while capture is on, the readers created
|
|
25
|
+
* under it serve each source's snapshot (the value it had when hydration
|
|
26
|
+
* began) and replay at `releaseSnapshotScope`.
|
|
27
|
+
*
|
|
28
|
+
* With `served` (hydration), `owner` is instead a hydrated computed and
|
|
29
|
+
* `served` its server answer — what the server rendered every reader of the
|
|
30
|
+
* node with — landing after the node was created pending (so the creation
|
|
31
|
+
* arm skipped it). It becomes the node's snapshot when it has none, whether
|
|
32
|
+
* the node committed the answer or a client write had already taken its
|
|
33
|
+
* compute over. A claim made later reads the value its markup shows, and
|
|
34
|
+
* replays the node's own value at its release, as for a written signal.
|
|
35
|
+
*/
|
|
36
|
+
export declare function markSnapshotScope(owner: Owner, served?: unknown): void;
|
|
24
37
|
export declare function releaseSnapshotScope(owner: Owner): void;
|
|
25
38
|
export declare function clearSnapshots(): void;
|
|
26
39
|
export declare function recompute(el: Computed<any>, create?: boolean): void;
|
|
@@ -68,13 +81,13 @@ export declare function createEffectNode<T>(fn: (prev?: T) => T, effectFn: (val:
|
|
|
68
81
|
* channel (`_x._notifyStatus`) went with them; effects are the only
|
|
69
82
|
* display consumers.
|
|
70
83
|
*/
|
|
71
|
-
export declare let effectStatusNotify: ((this: any
|
|
84
|
+
export declare let effectStatusNotify: ((this: any) => void) | null;
|
|
72
85
|
export declare function setEffectStatusNotify(fn: NonNullable<typeof effectStatusNotify>): void;
|
|
73
86
|
/** Resolve a node's status notifier: effect nodes (`_type` — EFFECT_PURE is
|
|
74
87
|
* 0, and only effect literals carry the field) get the shared notifier.
|
|
75
88
|
* Presence doubles as the "display consumer" membership test in the status
|
|
76
89
|
* walks, exactly as the per-node field did when every effect carried one. */
|
|
77
|
-
export declare function statusNotifierOf(el: any): ((this: any
|
|
90
|
+
export declare function statusNotifierOf(el: any): ((this: any) => void) | null;
|
|
78
91
|
export declare function signal<T>(v: T, options?: NodeOptions<T>): Signal<T>;
|
|
79
92
|
export declare function isEqual<T>(a: T, b: T): boolean;
|
|
80
93
|
/** A store slot node (CONFIG_SLOT_NODE): the whole node in ONE literal — the
|
|
@@ -128,7 +141,23 @@ export declare let disposalDepth: number;
|
|
|
128
141
|
export declare function enterDisposal(): void;
|
|
129
142
|
export declare function exitDisposal(): void;
|
|
130
143
|
export declare function resetDisposalDepth(): void;
|
|
131
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Dev-only: the DOM event being dispatched when the open strict-read window
|
|
146
|
+
* opened (`globalThis.event`; null between dispatches and off the main
|
|
147
|
+
* thread's Window), or `ANY_EVENT` when the window did not record one. A DOM
|
|
148
|
+
* call made in an effect callback that dispatches events synchronously
|
|
149
|
+
* (`el.focus()`, `el.click()`, `dialog.showModal()`) runs that event's
|
|
150
|
+
* handlers inside the window; a handler is a one-shot snapshot whoever
|
|
151
|
+
* dispatched the event, so a read made while a different event is current is
|
|
152
|
+
* outside the window (#4235). Only queued effect runs record the event, read
|
|
153
|
+
* once per queue (the getter is costly under jsdom); `strictReadActive` is
|
|
154
|
+
* the check.
|
|
155
|
+
*/
|
|
156
|
+
export declare let strictReadEvent: unknown;
|
|
157
|
+
export declare const dispatchingEvent: () => unknown;
|
|
158
|
+
export declare function setStrictRead(v: string | false, event?: unknown): string | false;
|
|
159
|
+
/** Dev-only: is the strict-read window open for a read made now? */
|
|
160
|
+
export declare function strictReadActive(): boolean;
|
|
132
161
|
/**
|
|
133
162
|
* Runs `fn` outside of any reactive tracking — reads inside `fn` will not
|
|
134
163
|
* subscribe the current scope. Returns whatever `fn` returns.
|
package/dist/types/core/dev.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface DevHooks {
|
|
|
16
16
|
* `warn`/`error` as failures unless they opt in to `info`.
|
|
17
17
|
*/
|
|
18
18
|
export type DiagnosticSeverity = "info" | "warn" | "error";
|
|
19
|
-
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "ASYNC_STORE_SETTER" | "STORE_WRITE_OUTSIDE_SETTER" | "ACTION_CALLED_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "SETTLED_CLEANUP_UNOWNED" | "SETTLE_WALK_UNINITIALIZED_SOURCE" | "FLUSH_IN_EFFECT_CALLBACK" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "PRIMITIVE_IN_EFFECT_CALLBACK" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "LOADING_ON_OUTSIDE_HOLD" | "INVALID_REFRESH_TARGET" | "INVALID_AFFECTS_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "UNTRACKED_READ_AFTER_AWAIT" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION" | "HUGE_FAN_OUT" | "HUGE_FAN_IN" | "GRAPH_GROWTH" | "HOT_SCOPE_RERUNS" | "HOT_SCOPE_TIME" | "WIDE_SCOPE_DEPS" | "UNSTABLE_MEMO_OUTPUT" | "WASTED_RECOMPUTE" | "ASYNC_WATERFALL" | "HOT_SCOPE_FANOUT" | "SILENT_HOLD" | "LONG_HOLD" | "UNTRACKED_ASYNC_HANDLER" | "ABANDONED_FLIGHTS" | "FALLBACK_FLASH" | "STACKED_HOLDS" | "OPTIMISTIC_REVERTED" | "EFFECT_WRITES_OWN_SOURCE" | "EFFECT_RELAY_TEAR" | "IMMUTABLE_UPDATE_IN_STORE" | "UNSTABLE_LIST_IDENTITY" | "SSR_RENDER_ERROR_CONTAINED" | "SSR_SUBTREE_ABANDONED" | "SSR_STREAM_ABANDONED" | "SSR_CLIENT_CONTENT_MASKED" | "LATE_HEADER_WRITE" | "SERVER_ERROR_SANITIZED" | "SSR_BOUNDARY_WATERFALL" | "SSR_UNDECLARED_LIVE_SOURCE" | "SSR_LIVE_HOLE_LATCHED" | "SERVER_WRITE" | "REVEAL_IN_RENDER_TO_STRING" | "LAZY_ASSET_UNMAPPED" | "PRELOAD_DESCRIPTOR_INVALID" | "HEAD_TAG_INVALID" | "UNRECOGNIZED_INSERT_VALUE" | "UNSCOPED_HOLE_ALLOCATED_IDS" | "LOWERCASE_EVENT_ATTRIBUTE" | "UNCOMMITTED_INPUT_OVERWRITTEN" | "FRAME_MARKER_CORRUPTED" | "DYNAMIC_ASYNC_COMPONENT";
|
|
19
|
+
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "ASYNC_STORE_SETTER" | "STORE_WRITE_OUTSIDE_SETTER" | "ACTION_CALLED_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "SETTLED_CLEANUP_UNOWNED" | "ON_FLUSH_IN_OWNED_SCOPE" | "SETTLE_WALK_UNINITIALIZED_SOURCE" | "FLUSH_IN_EFFECT_CALLBACK" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "PRIMITIVE_IN_EFFECT_CALLBACK" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "LOADING_ON_OUTSIDE_HOLD" | "INVALID_REFRESH_TARGET" | "INVALID_AFFECTS_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "UNTRACKED_READ_AFTER_AWAIT" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION" | "HUGE_FAN_OUT" | "HUGE_FAN_IN" | "GRAPH_GROWTH" | "HOT_SCOPE_RERUNS" | "HOT_SCOPE_TIME" | "WIDE_SCOPE_DEPS" | "UNSTABLE_MEMO_OUTPUT" | "WASTED_RECOMPUTE" | "ASYNC_WATERFALL" | "HOT_SCOPE_FANOUT" | "SILENT_HOLD" | "LONG_HOLD" | "UNTRACKED_ASYNC_HANDLER" | "ABANDONED_FLIGHTS" | "FALLBACK_FLASH" | "STACKED_HOLDS" | "OPTIMISTIC_REVERTED" | "EFFECT_WRITES_OWN_SOURCE" | "EFFECT_RELAY_TEAR" | "IMMUTABLE_UPDATE_IN_STORE" | "UNSTABLE_LIST_IDENTITY" | "SSR_RENDER_ERROR_CONTAINED" | "SSR_SUBTREE_ABANDONED" | "SSR_STREAM_ABANDONED" | "SSR_CLIENT_CONTENT_MASKED" | "LATE_HEADER_WRITE" | "SERVER_ERROR_SANITIZED" | "SSR_BOUNDARY_WATERFALL" | "SSR_UNDECLARED_LIVE_SOURCE" | "SSR_LIVE_HOLE_LATCHED" | "SERVER_WRITE" | "REVEAL_IN_RENDER_TO_STRING" | "LAZY_ASSET_UNMAPPED" | "PRELOAD_DESCRIPTOR_INVALID" | "HEAD_TAG_INVALID" | "UNRECOGNIZED_INSERT_VALUE" | "UNSCOPED_HOLE_ALLOCATED_IDS" | "LOWERCASE_EVENT_ATTRIBUTE" | "UNCOMMITTED_INPUT_OVERWRITTEN" | "FRAME_MARKER_CORRUPTED" | "DYNAMIC_ASYNC_COMPONENT" | "ASYNC_MEMO_ELEMENT";
|
|
20
20
|
export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner" | "error" | "perf" | "graph"
|
|
21
21
|
/** Perceived responsiveness: the runtime behaved correctly but the user saw no feedback. */
|
|
22
22
|
| "responsiveness"
|
|
@@ -11,7 +11,7 @@ export type { Computed, Disposable, Link, Owner, Root, Signal, NodeOptions } fro
|
|
|
11
11
|
export { effect, trackedEffect, type Effect, type TrackedEffect } from "./effect.js";
|
|
12
12
|
export { flush, GlobalQueue, enforceLoadingBoundary, resetErrorHalt, type IQueue, type QueueCallback } from "./scheduler.js";
|
|
13
13
|
export type { InteractionRef, NavigationRef } from "./attribution-hooks.js";
|
|
14
|
-
export { ROOT_ERROR_HOOK } from "./scheduler.js";
|
|
14
|
+
export { ROOT_ERROR_HOOK, clock } from "./scheduler.js";
|
|
15
15
|
export { configureClientErrors, type ClientErrorContext, type ClientErrorHook, type ClientErrorsConfig } from "./error-hooks.js";
|
|
16
16
|
export { DEV, OBSERVE, setConsoleFooter, type AttributionSlot, type Dev, type Observe, type ServerObserve, type Records, type RecordTypes, type HostRecordTypes, type RecordType, type RecordEvent, type RecordLive, type RecordListener, type RecordSubscribeOptions, type DevHooks, type DiagnosticCapture, type DiagnosticCode, type DiagnosticEvent, type DiagnosticKind, type DiagnosticListener, type Diagnostics, type DiagnosticSeverity, type DiagnosticSubject } from "./dev.js";
|
|
17
17
|
export * from "./constants.js";
|
|
@@ -60,5 +60,9 @@ export declare function supersede(n: Signal<any> | Computed<any>, value: unknown
|
|
|
60
60
|
* has shown, or one the seam has not judged yet (its run waits on the
|
|
61
61
|
* verdict: released if the lane shows, held if it blocks) — and sees the
|
|
62
62
|
* lane's latest. NOT_PENDING falls through: lane work's read of a pending
|
|
63
|
-
* member throws like any.
|
|
63
|
+
* member throws like any. A verdict reader entering a lane the seam has
|
|
64
|
+
* not judged reads ahead of it like a staging read: if the seam holds the
|
|
65
|
+
* lane, the pass re-derives on the screen (`entered`, #4284) — `latest()`
|
|
66
|
+
* beside the lane's nodes tears ahead of the hold however the reads are
|
|
67
|
+
* grouped into effects. */
|
|
64
68
|
export declare function laneRead(c: Computed<any> | null, el: Signal<any> | Computed<any>): unknown;
|
|
@@ -212,7 +212,14 @@ export declare function setQuestion(q: number): void;
|
|
|
212
212
|
export declare function nextQuestion(): number;
|
|
213
213
|
export declare const MAINLINE_QUESTION = 2147483647;
|
|
214
214
|
export declare let inEffectCallback: boolean;
|
|
215
|
-
|
|
215
|
+
/** Dev-only: matches no event, so a window or phase holding it applies
|
|
216
|
+
* whatever event is current (see `strictReadEvent`, core.ts). */
|
|
217
|
+
export declare const ANY_EVENT: {};
|
|
218
|
+
/** Dev-only: the DOM event current when the effect phase was entered. A
|
|
219
|
+
* handler dispatched synchronously from that phase (`el.focus()`) runs under
|
|
220
|
+
* a different event and is not in it (#4235). */
|
|
221
|
+
export declare let effectCallbackEvent: unknown;
|
|
222
|
+
export declare function setEffectCallback(value: boolean, event?: unknown): void;
|
|
216
223
|
export type QueueCallback = (type: number) => void;
|
|
217
224
|
export declare function schedule(): void;
|
|
218
225
|
/**
|
|
@@ -313,13 +320,15 @@ export declare class GlobalQueue implements IQueue {
|
|
|
313
320
|
* or without the held read) owes nothing. A run this transaction stashed
|
|
314
321
|
* for it is void (#3322: an effect has one value slot, and the stale pass
|
|
315
322
|
* overwrote the value that run was for) — the re-derivation's run replaces
|
|
316
|
-
* it. */
|
|
317
|
-
export declare function reruns(u: Transaction):
|
|
323
|
+
* it. Truthy when an effect re-derives (`land`). */
|
|
324
|
+
export declare function reruns(u: Transaction): unknown;
|
|
318
325
|
/** The held runs join this flush's effect phase after its own runs (the
|
|
319
326
|
* landing's re-passes, in height order): the frame's effects run as one
|
|
320
327
|
* pass would have queued them — a shell re-derived at the landing before a
|
|
321
328
|
* boundary swap held since the write (#3540's log order). */
|
|
322
329
|
export declare function releaseQueues(u: Transaction): void;
|
|
330
|
+
/** Nodes staged this flush (`_pendingValue` set), committed at its end. */
|
|
331
|
+
export declare const pendingNodes: Signal<any>[];
|
|
323
332
|
/** Passes that read a staging of this flush as the screen — lane work
|
|
324
333
|
* (core.ts `stagedRead`), a verdict reader before the frame's verdict
|
|
325
334
|
* (verdict.ts): if the frame parks they read a held write — re-derived next
|
|
@@ -383,3 +392,8 @@ export declare const globalQueue: GlobalQueue;
|
|
|
383
392
|
*/
|
|
384
393
|
export declare function flush(): void;
|
|
385
394
|
export declare function flush<T>(fn: () => T): T;
|
|
395
|
+
/** Dev-only: the DOM event current when the running effect queue started,
|
|
396
|
+
* or `ANY_EVENT` outside one. Read once per queue rather than once per
|
|
397
|
+
* effect (the getter is costly under jsdom); no event starts or ends between
|
|
398
|
+
* two effects of one synchronous queue (#4235). */
|
|
399
|
+
export declare let queueEvent: unknown;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** The observer a `subscribe` call receives. */
|
|
2
|
+
type FromObserver<T> = {
|
|
3
|
+
next(value: T): void;
|
|
4
|
+
error(err: unknown): void;
|
|
5
|
+
complete(): void;
|
|
6
|
+
};
|
|
7
|
+
type Teardown = (() => void) | {
|
|
8
|
+
unsubscribe(): void;
|
|
9
|
+
} | void;
|
|
10
|
+
/**
|
|
11
|
+
* Anything `from` accepts: a subscribe function
|
|
12
|
+
* (`(next, error, complete) => unsubscribe`), an object with
|
|
13
|
+
* `subscribe(observer)` (RxJS and TC39 Observables, including
|
|
14
|
+
* `Symbol.observable` / `"@@observable"` interop), or an AsyncIterable.
|
|
15
|
+
*/
|
|
16
|
+
export type FromSource<T> = ((next: (value: T) => void, error: (err: unknown) => void, complete: () => void) => Teardown) | {
|
|
17
|
+
subscribe(observer: FromObserver<T>): Teardown;
|
|
18
|
+
} | AsyncIterable<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Converts a callback subscription, an Observable or an AsyncIterable into an
|
|
21
|
+
* AsyncIterable for a Solid computation. A subscription keeps only the latest
|
|
22
|
+
* value, and a value the source emits during `subscribe` is served without a
|
|
23
|
+
* loading frame; an AsyncIterable streams every value through.
|
|
24
|
+
*
|
|
25
|
+
* The source closes on supersede — the owning computation re-running — and
|
|
26
|
+
* on owner disposal. Inside an async generator memo that holds for a
|
|
27
|
+
* `for await` that starts before the first `await`; one that starts after it
|
|
28
|
+
* has no owner to bind to, so its source closes only when the loop ends.
|
|
29
|
+
* Prefer returning `from(...)` from its own memo, with awaited inputs read
|
|
30
|
+
* from upstream memos and transforms done in a downstream memo.
|
|
31
|
+
*
|
|
32
|
+
* Iterate the result with `for await` or return it from a computation: its
|
|
33
|
+
* `next()` returns an already-buffered value as a bare result, not a promise.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const position = createMemo(() =>
|
|
38
|
+
* from<Position>((next, error) => {
|
|
39
|
+
* const id = navigator.geolocation.watchPosition(next, error);
|
|
40
|
+
* return () => navigator.geolocation.clearWatch(id);
|
|
41
|
+
* })
|
|
42
|
+
* );
|
|
43
|
+
* const ticks = createMemo(() => from(interval$(rate())));
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function from<T>(source: FromSource<T>): AsyncIterable<T>;
|
|
47
|
+
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export { $REFRESH, action, ContextNotFoundError, NoOwnerError, NotReadyError, Ti
|
|
|
5
5
|
* outside dev builds.
|
|
6
6
|
*/
|
|
7
7
|
export { setConsoleFooter } from "./core/index.js";
|
|
8
|
+
/** @internal The flush round counter (scheduler.ts): hydration's served pass tells its own round from a later one. */
|
|
9
|
+
export { clock } from "./core/index.js";
|
|
8
10
|
/** @internal The pre-write hook (`setWriteHook` in core/core.ts); the server-components client's deferred hydration. */
|
|
9
11
|
/** @internal Plain-signal identities and the dev read watch (dependency edges; the server-components client). */
|
|
10
12
|
export { setWriteHook, setSignalIdentities, setReadWatch, signalName } from "./core/index.js";
|
|
@@ -20,12 +22,13 @@ export declare const OBSERVE: Observe | undefined;
|
|
|
20
22
|
/** Dev tier (devtools hooks, graph traversal, console reporting): dev builds only. */
|
|
21
23
|
export declare const DEV: Dev | undefined;
|
|
22
24
|
export type { Owner, Context, ContextRecord, IQueue, ExternalSourceFactory, ExternalSource, ExternalSourceConfig, Refreshable, AttributionSlot, ClientErrorContext, ClientErrorHook, ClientErrorsConfig, InteractionRef, NavigationRef, Dev, Observe, ServerObserve, Records, RecordTypes, HostRecordTypes, RecordType, RecordEvent, RecordLive, RecordListener, RecordSubscribeOptions, DevHooks, DiagnosticCapture, DiagnosticCode, DiagnosticEvent, DiagnosticKind, DiagnosticListener, Diagnostics, DiagnosticSeverity, DiagnosticSubject } from "./core/index.js";
|
|
23
|
-
export { createSignal, createOptimistic, createMemo, createEffect, createRenderEffect, createTrackedEffect, createReaction, refresh, resolve, until, onSettled, onCleanup } from "./signals.js";
|
|
25
|
+
export { createSignal, createOptimistic, createMemo, createEffect, createRenderEffect, createTrackedEffect, createReaction, refresh, resolve, until, onSettled, onFlush, onCleanup } from "./signals.js";
|
|
24
26
|
export type { Truthy, UntilOptions, Accessor, SourceAccessor, Setter, Signal, ComputeFunction, EffectFunction, EffectBundle, EffectOptions, SignalOptions, MemoOptions, NoInfer } from "./signals.js";
|
|
25
27
|
export { mapArray, repeat, type Maybe } from "./map.js";
|
|
26
28
|
export * from "./store/index.js";
|
|
27
29
|
export { affects } from "./affects.js";
|
|
28
30
|
export { createDeferred } from "./deferred.js";
|
|
31
|
+
export { from, type FromSource } from "./from.js";
|
|
29
32
|
export { flatten } from "./flatten.js";
|
|
30
33
|
export { createLoadingBoundary, createErrorBoundary } from "./boundaries.js";
|
|
31
34
|
export { createRevealOrder, type RevealOrder } from "./reveal.js";
|
package/dist/types/signals.d.ts
CHANGED
|
@@ -735,4 +735,41 @@ export declare function until<T>(fn: () => T, options?: UntilOptions): Promise<T
|
|
|
735
735
|
* on owner disposal
|
|
736
736
|
*/
|
|
737
737
|
export declare function onSettled(callback: () => void | (() => void)): void;
|
|
738
|
+
/**
|
|
739
|
+
* Schedules `callback` to run **once**, right after the pending flush
|
|
740
|
+
* finishes, in the same microtask checkpoint (before the browser paints).
|
|
741
|
+
* Unlike `onSettled`, it never waits on async work: if that flush is held by
|
|
742
|
+
* a pending transition, the callback still runs.
|
|
743
|
+
*
|
|
744
|
+
* Its main use is keeping a write out of another update's hold. Writes made
|
|
745
|
+
* in the same synchronous frame are applied together, so when one of them
|
|
746
|
+
* starts async work (a route change, a fetch), the others are held with it
|
|
747
|
+
* until it resolves. A write made in `onFlush` happens after that flush, so
|
|
748
|
+
* it is its own update: it commits on its own unless something it changes
|
|
749
|
+
* also derives from the held work (a memo or `createEffect` reading both),
|
|
750
|
+
* in which case it joins that hold as any later write would.
|
|
751
|
+
*
|
|
752
|
+
* Call it from event handlers and effect callbacks (including
|
|
753
|
+
* `createTrackedEffect` and `onSettled` bodies). In an owned scope such as a
|
|
754
|
+
* component body or a computation it warns in dev: use `onSettled` there.
|
|
755
|
+
*
|
|
756
|
+
* - A write in the callback lands after any write made inline in the same
|
|
757
|
+
* frame. Don't write the same signal both inside and outside it; use a
|
|
758
|
+
* functional setter if the order matters.
|
|
759
|
+
* - Several `onFlush` callbacks run in call order and batch into one flush.
|
|
760
|
+
* - `queueMicrotask` is not a substitute: called before the frame's first
|
|
761
|
+
* write, it runs before that flush and its write joins it.
|
|
762
|
+
*
|
|
763
|
+
* @example
|
|
764
|
+
* ```tsx
|
|
765
|
+
* // A menu closes now even when the consumer's onSelect starts async work.
|
|
766
|
+
* const select = (id: string) => {
|
|
767
|
+
* onFlush(() => setOpen(false));
|
|
768
|
+
* props.onSelect?.(id);
|
|
769
|
+
* };
|
|
770
|
+
* ```
|
|
771
|
+
*
|
|
772
|
+
* @param callback Function to run once after the pending flush
|
|
773
|
+
*/
|
|
774
|
+
export declare function onFlush(callback: () => void): void;
|
|
738
775
|
export {};
|
|
@@ -34,6 +34,8 @@ export interface StoreFamily {
|
|
|
34
34
|
* their readers (A9) — the family's enumerable index, in place of a
|
|
35
35
|
* per-leaf chain; a target leaves it with its last node. */
|
|
36
36
|
live: Set<StoreTarget>;
|
|
37
|
+
/** A source's status reaching the derive by propagation (`familyStatus`). */
|
|
38
|
+
st?: (status: number) => void;
|
|
37
39
|
shallow?: boolean;
|
|
38
40
|
/** Derive run counter (proj R37): the run whose draft is live. */
|
|
39
41
|
run?: number;
|
package/package.json
CHANGED