@solidjs/signals 2.0.0-rc.16 → 2.0.0-rc.18

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 (56) hide show
  1. package/dist/dev-shared.js +1972 -1751
  2. package/dist/dev.attribution.js +16 -16
  3. package/dist/dev.js +672 -319
  4. package/dist/observe/boundaries.js +2 -2
  5. package/dist/observe/core/async.js +151 -116
  6. package/dist/observe/core/constants.js +3 -1
  7. package/dist/observe/core/context.js +2 -0
  8. package/dist/observe/core/core.js +51 -35
  9. package/dist/observe/core/effect.js +29 -30
  10. package/dist/observe/core/graph.js +13 -11
  11. package/dist/observe/core/lanes.js +25 -14
  12. package/dist/observe/core/owner.js +77 -51
  13. package/dist/observe/core/scheduler.js +202 -175
  14. package/dist/observe/core/verdict.js +5 -2
  15. package/dist/observe/deferred.js +16 -13
  16. package/dist/observe/from.js +248 -0
  17. package/dist/observe/index.js +2 -0
  18. package/dist/observe/map.js +2 -2
  19. package/dist/observe/signals.js +6 -1
  20. package/dist/observe/store/affects.js +13 -13
  21. package/dist/observe/store/optimistic.js +112 -71
  22. package/dist/observe/store/reconcile.js +137 -121
  23. package/dist/observe/store/store.js +612 -626
  24. package/dist/observe/store/target.js +1 -5
  25. package/dist/prod/boundaries.js +2 -2
  26. package/dist/prod/core/async.js +211 -176
  27. package/dist/prod/core/constants.js +3 -1
  28. package/dist/prod/core/context.js +2 -0
  29. package/dist/prod/core/core.js +63 -47
  30. package/dist/prod/core/effect.js +24 -25
  31. package/dist/prod/core/graph.js +12 -10
  32. package/dist/prod/core/heap.js +1 -1
  33. package/dist/prod/core/lanes.js +39 -28
  34. package/dist/prod/core/owner.js +70 -44
  35. package/dist/prod/core/scheduler.js +78 -51
  36. package/dist/prod/core/truth.js +4 -4
  37. package/dist/prod/core/verdict.js +11 -8
  38. package/dist/prod/deferred.js +17 -14
  39. package/dist/prod/from.js +248 -0
  40. package/dist/prod/index.js +2 -0
  41. package/dist/prod/map.js +2 -2
  42. package/dist/prod/signals.js +18 -13
  43. package/dist/prod/store/optimistic.js +112 -71
  44. package/dist/prod/store/reconcile.js +137 -121
  45. package/dist/prod/store/store.js +109 -121
  46. package/dist/prod/store/target.js +13 -17
  47. package/dist/types/core/async.d.ts +12 -2
  48. package/dist/types/core/constants.d.ts +5 -0
  49. package/dist/types/core/core.d.ts +29 -6
  50. package/dist/types/core/dev.d.ts +9 -1
  51. package/dist/types/core/error.d.ts +9 -1
  52. package/dist/types/core/owner.d.ts +4 -0
  53. package/dist/types/core/scheduler.d.ts +38 -7
  54. package/dist/types/from.d.ts +47 -0
  55. package/dist/types/index.d.ts +1 -0
  56. package/package.json +1 -1
@@ -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, blockStatus?: boolean): void;
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, downstreamBlockStatus?: boolean): void;
48
+ export declare function propagateStatus(el: Computed<any>, status: number, error: any): void;
@@ -219,3 +219,8 @@ export declare const $REFRESH: unique symbol;
219
219
  export type Refreshable<T> = T & {
220
220
  readonly [$REFRESH]: any;
221
221
  };
222
+ /** `Set` under a module binding. Bundlers mark a bare `new Set()` pure with
223
+ * a `/* @__PURE__ *\/` comment that survives minification (16 bytes a site);
224
+ * a construction through a binding carries none. Same constructor, so the
225
+ * same objects. */
226
+ export declare const NewSet: SetConstructor;
@@ -45,6 +45,9 @@ export declare function ext(el: {
45
45
  * the boundary collects it and shows its fallback, and the pass is the
46
46
  * boundary's, not the tick's (A29's boundary exemption, #3540). */
47
47
  export declare function joinPass(c: Computed<any>, el: Signal<any> | Computed<any>): void;
48
+ /** `joinPass` into the hold `t` (a folded guess's: store/optimistic.ts
49
+ * `foldedRead`, D-34) — a reader is never a render effect there. */
50
+ export declare function joinPassAt(c: Computed<any>, t: Transaction): void;
48
51
  /** A node born into transaction `t`: held by it and never committed (A29,
49
52
  * ruling A) — uninitialized (born held), or a member of the frame one of its
50
53
  * held passes built (CONFIG_HELD_FRAME). Its branch exists only in `t`: it
@@ -65,13 +68,13 @@ export declare function createEffectNode<T>(fn: (prev?: T) => T, effectFn: (val:
65
68
  * channel (`_x._notifyStatus`) went with them; effects are the only
66
69
  * display consumers.
67
70
  */
68
- export declare let effectStatusNotify: ((this: any, status?: number, error?: any) => void) | null;
71
+ export declare let effectStatusNotify: ((this: any) => void) | null;
69
72
  export declare function setEffectStatusNotify(fn: NonNullable<typeof effectStatusNotify>): void;
70
73
  /** Resolve a node's status notifier: effect nodes (`_type` — EFFECT_PURE is
71
74
  * 0, and only effect literals carry the field) get the shared notifier.
72
75
  * Presence doubles as the "display consumer" membership test in the status
73
76
  * walks, exactly as the per-node field did when every effect carried one. */
74
- export declare function statusNotifierOf(el: any): ((this: any, status?: number, error?: any) => void) | undefined;
77
+ export declare function statusNotifierOf(el: any): ((this: any) => void) | null;
75
78
  export declare function signal<T>(v: T, options?: NodeOptions<T>): Signal<T>;
76
79
  export declare function isEqual<T>(a: T, b: T): boolean;
77
80
  /** A store slot node (CONFIG_SLOT_NODE): the whole node in ONE literal — the
@@ -117,14 +120,31 @@ export declare function exitCallback(): void;
117
120
  * its owner (a list pass removing a row, a branch switching away), so its
118
121
  * writes are imperative like an effect callback's (#4165). Kept apart from
119
122
  * `callbackDepth` because its sites cannot use try/finally (the frame would
120
- * survive into prod): a throwing cleanup leaves it raised, and dev.ts resets
121
- * it on the next microtask, which teardown — synchronous — never spans.
123
+ * survive into prod). A throwing cleanup is caught (owner.ts `runCleanup`);
124
+ * anything else escaping a teardown leaves it raised, and dev.ts resets it on
125
+ * the next microtask, which teardown — synchronous — never spans.
122
126
  */
123
127
  export declare let disposalDepth: number;
124
128
  export declare function enterDisposal(): void;
125
129
  export declare function exitDisposal(): void;
126
130
  export declare function resetDisposalDepth(): void;
127
- export declare function setStrictRead(v: string | false): string | false;
131
+ /**
132
+ * Dev-only: the DOM event being dispatched when the open strict-read window
133
+ * opened (`globalThis.event`; null between dispatches and off the main
134
+ * thread's Window), or `ANY_EVENT` when the window did not record one. A DOM
135
+ * call made in an effect callback that dispatches events synchronously
136
+ * (`el.focus()`, `el.click()`, `dialog.showModal()`) runs that event's
137
+ * handlers inside the window; a handler is a one-shot snapshot whoever
138
+ * dispatched the event, so a read made while a different event is current is
139
+ * outside the window (#4235). Only queued effect runs record the event, read
140
+ * once per queue (the getter is costly under jsdom); `strictReadActive` is
141
+ * the check.
142
+ */
143
+ export declare let strictReadEvent: unknown;
144
+ export declare const dispatchingEvent: () => unknown;
145
+ export declare function setStrictRead(v: string | false, event?: unknown): string | false;
146
+ /** Dev-only: is the strict-read window open for a read made now? */
147
+ export declare function strictReadActive(): boolean;
128
148
  /**
129
149
  * Runs `fn` outside of any reactive tracking — reads inside `fn` will not
130
150
  * subscribe the current scope. Returns whatever `fn` returns.
@@ -239,7 +259,10 @@ export declare function read<T>(el: Signal<T> | Computed<T>): T;
239
259
  export declare function serve(el: Signal<any> | Computed<any>, c: Computed<any> | null): unknown;
240
260
  /** A pass read a staging of this flush: it derives from what the flush may
241
261
  * yet hold (REACTIVE_STAGED_READ — the seam decides). Lane work too (plan sec. 28, a
242
- * lane sees the screen plus its own guesses): the staging is the screen if
262
+ * lane sees the screen plus its own guesses) — a folded lane's only before
263
+ * the frame has a transaction (after, it reads the screen like a verdict
264
+ * reader, `stagedScreen` — a list pass never pairs a held length with the
265
+ * guess's rows, D-34): the staging is the screen if
243
266
  * the frame commits — one pass, the common case — and a held write if it
244
267
  * parks, which the seam repairs (`stagedReaders`): the pass re-derives on
245
268
  * the committed world and its lane's runs wait that round, so the held
@@ -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" | "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" | "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" | "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";
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"
@@ -472,6 +472,14 @@ export declare function ownerPath(subject: DiagnosticSubject | null | undefined)
472
472
  * own). Console output is a separate, dev-tier step — see `reportDiagnostic`.
473
473
  */
474
474
  export declare function emitDiagnostic(event: Omit<DiagnosticEvent, "sequence">, subject?: DiagnosticSubject | null | undefined): DiagnosticEvent;
475
+ /**
476
+ * The locating lines of a console report: `\n in <App> › <TodoRow> › effect`
477
+ * (the owner path) and `\n at src/App.tsx:18:3` (see `locationLine`), each
478
+ * when the entry carries it; `""` when it carries neither. Shared by
479
+ * `reportDiagnostic` and the sites that print their own console entry (the
480
+ * halt, which logs its cause beside the message).
481
+ */
482
+ export declare function locationLines(entry: DiagnosticEvent): string;
475
483
  /**
476
484
  * The console face of a diagnostic — ONE entry per finding: the message, the
477
485
  * owner path (`in <App> › <TodoRow> › effect`) so a human can locate it, the
@@ -52,5 +52,13 @@ export declare class NoOwnerError extends Error {
52
52
  constructor();
53
53
  }
54
54
  export declare class ContextNotFoundError extends Error {
55
- constructor();
55
+ /**
56
+ * In dev, a read site passes the context (and whether a provider above set
57
+ * it to `undefined`) so the message can name it and say why it has no
58
+ * value (#4181). Read through `arguments` so production — where the message
59
+ * is empty — keeps the zero-parameter constructor byte for byte.
60
+ */
61
+ constructor(context?: {
62
+ id: symbol;
63
+ }, providedUndefined?: boolean);
56
64
  }
@@ -1,6 +1,10 @@
1
1
  import type { Computed, Disposable, Owner, Root } from "./types.js";
2
2
  export declare function markDisposal(el: Owner): void;
3
3
  export declare function dispose(node: Computed<unknown>): void;
4
+ /** Runs a cleanup or `unobserved` hook; a throw is collected, not raised. @internal */
5
+ export declare function runCleanup(fn: () => void): void;
6
+ /** Rethrows the error `runCleanup` collected, once; `drop` discards it. @internal */
7
+ export declare function rethrowCleanupError(drop?: boolean): void;
4
8
  export declare function disposeChildren(node: Owner, self?: boolean, zombie?: boolean): void;
5
9
  export declare function linkChild(parent: Owner, node: Owner): void;
6
10
  /**
@@ -1,3 +1,4 @@
1
+ import { type DiagnosticSubject } from "./dev.js";
1
2
  import { type Heap } from "./heap.js";
2
3
  import type { Computed, Owner, Signal } from "./types.js";
3
4
  export declare let laneReadHook: ((c: Computed<any> | null, el: Signal<any> | Computed<any>) => unknown) | null;
@@ -79,6 +80,15 @@ export interface Transaction {
79
80
  * leaf reading a held lane that has not shown is a stale reader of it
80
81
  * (#3460); one reading a lane the seam has not judged yet is its work. */
81
82
  _held: boolean;
83
+ /** Lane: a current truth that differs folded beneath one of its keyed
84
+ * guesses (lanes.ts `laneWrite`, D-34) — the store's reader of it: a
85
+ * deriving pass outside the lane, or `latest()` (`c` null), is served
86
+ * the hold's world from its guesses; NOT_PENDING otherwise
87
+ * (store/optimistic.ts `foldedRead`). Unset until then; not
88
+ * `_`-prefixed: a new mangled name shifts every later one
89
+ * (scripts/mangle-props.mjs), which costs the floors bytes for a path
90
+ * only optimistic stores reach. */
91
+ folded?: (c: Computed<any> | null, el: Signal<any> | Computed<any>) => unknown;
82
92
  /** `affects()` marks declared in it (affects.ts): released at the landing.
83
93
  * Not nodes — a mark holds nothing (`blocked` never sees one). */
84
94
  _marks: Signal<any>[] | null;
@@ -202,7 +212,14 @@ export declare function setQuestion(q: number): void;
202
212
  export declare function nextQuestion(): number;
203
213
  export declare const MAINLINE_QUESTION = 2147483647;
204
214
  export declare let inEffectCallback: boolean;
205
- export declare function setEffectCallback(value: boolean): void;
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;
206
223
  export type QueueCallback = (type: number) => void;
207
224
  export declare function schedule(): void;
208
225
  /**
@@ -219,6 +236,13 @@ export declare function schedule(): void;
219
236
  */
220
237
  export declare const ROOT_ERROR_HOOK: unique symbol;
221
238
  export declare function haltReactivity(cause?: unknown): void;
239
+ /**
240
+ * Dev: `haltReactivity`, located at `subject` — the computation the uncaught
241
+ * error escaped from — for the REACTIVITY_HALTED message's owner path. Call
242
+ * sites pick it in dev builds only (`haltReactivity(e)` in production), so
243
+ * production keeps the one-argument halt and its bytes unchanged.
244
+ */
245
+ export declare function haltReactivityAt(cause: unknown, subject: DiagnosticSubject): void;
222
246
  /** @internal Test/dev-reload hook. Revives scheduling after a halt. */
223
247
  export declare function resetErrorHalt(): void;
224
248
  export interface IQueue {
@@ -252,10 +276,12 @@ export declare class GlobalQueue implements IQueue {
252
276
  static _storeWrappable: ((v: unknown) => boolean) | undefined;
253
277
  static _mark: ((node: Signal<any> | Computed<any>) => void) | undefined;
254
278
  static _witnessMark: (() => void) | undefined;
255
- /** An older question's truth was held beneath a guess (lanes.ts
256
- * `laneWrite`): the store re-bases an arrangement guess over it
257
- * (store/optimistic.ts). */
258
- static _laneRebase: ((el: Signal<any>, truth: unknown) => void) | undefined;
279
+ /** A truth landing on a guess (lanes.ts `laneWrite`), `older` when it
280
+ * answers an older question: the store re-bases an arrangement guess over
281
+ * it; a current one differing from a shown keyed arrangement guess folds
282
+ * beneath it instead of voiding it (D-34) — true: the lane stages it
283
+ * beneath (store/optimistic.ts). */
284
+ static _laneRebase: ((el: Signal<any>, truth: unknown, older: boolean) => boolean | void) | undefined;
259
285
  static _verdictLane: ((t: Transaction) => Transaction) | undefined;
260
286
  static _laneGuesses: ((t: Transaction) => Signal<any>[]) | undefined;
261
287
  /** `createDeferred` (deferred.ts): a deferred node with a flight up that
@@ -294,8 +320,8 @@ export declare class GlobalQueue implements IQueue {
294
320
  * or without the held read) owes nothing. A run this transaction stashed
295
321
  * for it is void (#3322: an effect has one value slot, and the stale pass
296
322
  * overwrote the value that run was for) — the re-derivation's run replaces
297
- * it. */
298
- export declare function reruns(u: Transaction): void;
323
+ * it. Truthy when an effect re-derives (`land`). */
324
+ export declare function reruns(u: Transaction): unknown;
299
325
  /** The held runs join this flush's effect phase after its own runs (the
300
326
  * landing's re-passes, in height order): the frame's effects run as one
301
327
  * pass would have queued them — a shell re-derived at the landing before a
@@ -364,3 +390,8 @@ export declare const globalQueue: GlobalQueue;
364
390
  */
365
391
  export declare function flush(): void;
366
392
  export declare function flush<T>(fn: () => T): T;
393
+ /** Dev-only: the DOM event current when the running effect queue started,
394
+ * or `ANY_EVENT` outside one. Read once per queue rather than once per
395
+ * effect (the getter is costly under jsdom); no event starts or ends between
396
+ * two effects of one synchronous queue (#4235). */
397
+ 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 {};
@@ -26,6 +26,7 @@ export { mapArray, repeat, type Maybe } from "./map.js";
26
26
  export * from "./store/index.js";
27
27
  export { affects } from "./affects.js";
28
28
  export { createDeferred } from "./deferred.js";
29
+ export { from, type FromSource } from "./from.js";
29
30
  export { flatten } from "./flatten.js";
30
31
  export { createLoadingBoundary, createErrorBoundary } from "./boundaries.js";
31
32
  export { createRevealOrder, type RevealOrder } from "./reveal.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidjs/signals",
3
- "version": "2.0.0-rc.16",
3
+ "version": "2.0.0-rc.18",
4
4
  "description": "Solid's reactive primitives: signals, memos, effects, stores, and async-aware computations.",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",