solid-js 2.0.0-beta.1 → 2.0.0-beta.11

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 (38) hide show
  1. package/CHEATSHEET.md +640 -0
  2. package/README.md +42 -188
  3. package/dist/dev.cjs +446 -291
  4. package/dist/dev.js +426 -293
  5. package/dist/server.cjs +941 -345
  6. package/dist/server.js +897 -299
  7. package/dist/solid.cjs +438 -261
  8. package/dist/solid.js +418 -263
  9. package/package.json +67 -39
  10. package/types/client/component.d.ts +64 -19
  11. package/types/client/core.d.ts +110 -34
  12. package/types/client/flow.d.ts +176 -42
  13. package/types/client/hydration.d.ts +513 -37
  14. package/types/index.d.ts +8 -13
  15. package/types/server/component.d.ts +11 -11
  16. package/types/server/core.d.ts +19 -21
  17. package/types/server/flow.d.ts +76 -21
  18. package/types/server/hydration.d.ts +34 -9
  19. package/types/server/index.d.ts +6 -8
  20. package/types/server/shared.d.ts +10 -2
  21. package/types/server/signals.d.ts +80 -19
  22. package/types/types.d.ts +15 -0
  23. package/types-cjs/client/component.d.cts +120 -0
  24. package/types-cjs/client/core.d.cts +141 -0
  25. package/types-cjs/client/flow.d.cts +234 -0
  26. package/types-cjs/client/hydration.d.cts +568 -0
  27. package/types-cjs/index.d.cts +15 -0
  28. package/types-cjs/package.json +3 -0
  29. package/types-cjs/server/component.d.cts +67 -0
  30. package/types-cjs/server/core.d.cts +42 -0
  31. package/types-cjs/server/flow.d.cts +115 -0
  32. package/types-cjs/server/hydration.d.cts +63 -0
  33. package/types-cjs/server/index.d.cts +10 -0
  34. package/types-cjs/server/shared.d.cts +54 -0
  35. package/types-cjs/server/signals.d.cts +123 -0
  36. package/types-cjs/types.d.cts +15 -0
  37. package/jsx-runtime.d.ts +0 -1
  38. package/types/jsx.d.ts +0 -4129
@@ -1,23 +1,77 @@
1
- import { createErrorBoundary as coreErrorBoundary, createMemo as coreMemo, createSignal as coreSignal, createOptimistic as coreOptimistic, createRenderEffect as coreRenderEffect, createEffect as coreEffect, type ProjectionOptions, type Store, type StoreSetter, type Context } from "@solidjs/signals";
2
- import { JSX } from "../jsx.js";
1
+ import { createErrorBoundary as coreErrorBoundary, createRenderEffect as coreRenderEffect, createEffect as coreEffect, type ComputeFunction, type MemoOptions, type NoInfer, type ProjectionOptions, type Refreshable, type Signal, type SignalOptions, type SourceAccessor, type Store, type StoreSetter, type Context } from "@solidjs/signals";
2
+ import type { Element as SolidElement } from "../types.js";
3
+ type HydrationSsrFields = {
4
+ /**
5
+ * Defer the SSR stream flush until this primitive's first value is
6
+ * resolved. Lets late-resolving sources hold the document open
7
+ * rather than forcing the surrounding `<Loading>` boundary to render
8
+ * its fallback into the HTML. Server-only; ignored on the client.
9
+ */
10
+ deferStream?: boolean;
11
+ /**
12
+ * Hydration policy. Decides what initial value the client uses and
13
+ * whether the compute re-runs.
14
+ *
15
+ * - `"server"` *(default)*: client uses the serialized server value
16
+ * as initial state. Compute does **not** re-run for the initial
17
+ * value — the serialized result is authoritative. Choose this when
18
+ * the compute is deterministic from server-available inputs.
19
+ * - `"hybrid"`: client uses the serialized server value, then
20
+ * re-runs the compute to take over. Choose this for computes that
21
+ * mix server data with client-only signals (e.g. window size,
22
+ * user-locale).
23
+ * - `"client"`: skip the server value entirely. Compute is deferred
24
+ * until hydration completes, then runs as if first-mounted.
25
+ * Choose this for client-only state where serialization is
26
+ * meaningless.
27
+ */
28
+ ssrSource?: "server" | "hybrid" | "client";
29
+ };
3
30
  declare module "@solidjs/signals" {
4
- interface MemoOptions<T> {
5
- deferStream?: boolean;
6
- ssrSource?: "server" | "hybrid" | "initial" | "client";
31
+ interface MemoOptions<T> extends HydrationSsrFields {
32
+ }
33
+ interface SignalOptions<T> extends HydrationSsrFields {
7
34
  }
8
- interface SignalOptions<T> {
9
- deferStream?: boolean;
10
- ssrSource?: "server" | "hybrid" | "initial" | "client";
35
+ interface EffectOptions extends HydrationSsrFields {
11
36
  }
12
- interface EffectOptions {
13
- deferStream?: boolean;
14
- ssrSource?: "server" | "hybrid" | "initial" | "client";
37
+ interface ProjectionOptions extends HydrationSsrFields {
15
38
  }
16
39
  }
17
- export type HydrationProjectionOptions = ProjectionOptions & {
18
- ssrSource?: "server" | "hybrid" | "initial" | "client";
40
+ /**
41
+ * Options for `createProjection`, `createStore(fn, ...)`, and
42
+ * `createOptimisticStore(fn, ...)`.
43
+ *
44
+ * `ssrSource` controls what initial value the client uses and whether
45
+ * the projection's compute re-runs:
46
+ *
47
+ * - `"server"` *(default)*: client uses the serialized server value
48
+ * as initial state.
49
+ * - `"hybrid"`: serialized value first, then re-run the compute on
50
+ * the client to take over.
51
+ * - `"client"`: skip serialization; compute runs only after hydration
52
+ * completes.
53
+ *
54
+ * See {@link HydrationSsrFields} for the fuller explanation.
55
+ */
56
+ type HydrationClientMemoOptions<T> = Omit<MemoOptions<T>, "ssrSource"> & {
57
+ ssrSource: "client";
58
+ };
59
+ type HydrationMemoOptions<T> = Omit<MemoOptions<T>, "ssrSource"> & {
60
+ ssrSource?: "server" | "hybrid";
61
+ };
62
+ type HydrationClientSignalOptions<T> = Omit<SignalOptions<T> & MemoOptions<T>, "ssrSource"> & {
63
+ ssrSource: "client";
64
+ };
65
+ type HydrationSignalOptions<T> = Omit<SignalOptions<T> & MemoOptions<T>, "ssrSource"> & {
66
+ ssrSource?: "server" | "hybrid";
19
67
  };
20
68
  export type HydrationContext = {};
69
+ /**
70
+ * Internal context flag set by `<NoHydration>` to disable hydration for its
71
+ * subtree. Cross-package wiring; not part of the user-facing API.
72
+ *
73
+ * @internal
74
+ */
21
75
  export declare const NoHydrateContext: Context<boolean>;
22
76
  type SharedConfig = {
23
77
  hydrating: boolean;
@@ -28,13 +82,21 @@ type SharedConfig = {
28
82
  has?: (id: string) => boolean;
29
83
  gather?: (key: string) => void;
30
84
  cleanupFragment?: (id: string) => void;
31
- registry?: Map<string, Element>;
32
- completed?: WeakSet<Element> | null;
85
+ loadModuleAssets?: (mapping: Record<string, string>) => Promise<void> | undefined;
86
+ registry?: Map<string, object>;
87
+ completed?: WeakSet<object> | null;
33
88
  events?: any[] | null;
34
89
  verifyHydration?: () => void;
35
90
  done: boolean;
36
91
  getNextContextId(): string;
37
92
  };
93
+ /**
94
+ * Shared hydration coordination object — populated by `enableHydration()` and
95
+ * consumed by the hydration-aware primitive wrappers and SSR streaming
96
+ * runtime. Cross-package wiring; not part of the user-facing API.
97
+ *
98
+ * @internal
99
+ */
38
100
  export declare const sharedConfig: SharedConfig;
39
101
  /**
40
102
  * Registers a callback to run once when all hydration completes
@@ -42,51 +104,465 @@ export declare const sharedConfig: SharedConfig;
42
104
  * complete (or not hydrating), fires via queueMicrotask.
43
105
  */
44
106
  export declare function onHydrationEnd(callback: () => void): void;
107
+ /**
108
+ * Switches the primitive wrappers above (`createMemo`, `createSignal`,
109
+ * `createStore`, etc.) into hydration-aware mode. Called by `hydrate()`
110
+ * before mounting; cross-package wiring not part of the user-facing API.
111
+ *
112
+ * @internal
113
+ */
45
114
  export declare function enableHydration(): void;
46
- export declare const createMemo: typeof coreMemo;
47
- export declare const createSignal: typeof coreSignal;
115
+ /**
116
+ * Creates a readonly derived reactive memoized signal.
117
+ *
118
+ * `compute(prev)` runs reactively — every reactive read inside it is
119
+ * tracked, and the returned value becomes the memo's current value.
120
+ * The memo is cached: it only recomputes when one of its tracked
121
+ * sources changes.
122
+ *
123
+ * ```ts
124
+ * const value = createMemo<T>(compute, options?: MemoOptions<T>);
125
+ * ```
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * const [first, setFirst] = createSignal("Ada");
130
+ * const [last, setLast] = createSignal("Lovelace");
131
+ *
132
+ * const fullName = createMemo(() => `${first()} ${last()}`);
133
+ *
134
+ * fullName(); // "Ada Lovelace"
135
+ * ```
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * // Async memo — reads suspend inside <Loading>
140
+ * const user = createMemo(async () => {
141
+ * const res = await fetch(`/users/${id()}`);
142
+ * return res.json();
143
+ * });
144
+ * ```
145
+ *
146
+ * **Hydration:** `MemoOptions` accepts an `ssrSource` field
147
+ * (`"server"` | `"hybrid"` | `"client"`) that controls what initial
148
+ * value the client uses and whether `compute` re-runs. See
149
+ * {@link HydrationSsrFields}.
150
+ *
151
+ * @param compute receives the previous value, returns the new value
152
+ * @param options `MemoOptions` — `id`, `name`, `equals`, `unobserved`,
153
+ * `lazy`, `transparent`, `ssrSource`
154
+ *
155
+ * @description https://docs.solidjs.com/reference/basic-reactivity/create-memo
156
+ */
157
+ export declare const createMemo: {
158
+ <T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientMemoOptions<T>): SourceAccessor<T | undefined>;
159
+ <T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationMemoOptions<T>): SourceAccessor<T>;
160
+ };
161
+ /**
162
+ * Creates a simple reactive state with a getter and setter.
163
+ *
164
+ * - **Plain form** — `createSignal(value, options?: SignalOptions<T>)`:
165
+ * stores a value; the setter writes a new value or applies an
166
+ * updater `(prev) => next`.
167
+ * - **Function form (writable memo)** —
168
+ * `createSignal(fn, options?: SignalOptions<T> & MemoOptions<T>)`:
169
+ * the value is computed by `fn` like a memo, but the setter can
170
+ * locally override it (useful for optimistic edits over a derived
171
+ * default).
172
+ *
173
+ * ```ts
174
+ * // Plain
175
+ * const [count, setCount] = createSignal(0);
176
+ *
177
+ * count(); // 0
178
+ * setCount(1); // explicit value
179
+ * setCount(c => c + 1); // updater
180
+ *
181
+ * // Writable memo: starts as `fn()`, can be locally overwritten.
182
+ * const [user, setUser] = createSignal(() => fetchUser(userId()));
183
+ * setUser({ ...user(), name: "Alice" }); // optimistic local edit
184
+ * ```
185
+ *
186
+ * **Hydration:** in the function form, `SignalOptions & MemoOptions`
187
+ * accepts an `ssrSource` field (`"server"` | `"hybrid"` | `"client"`)
188
+ * that controls what initial value the client uses and whether `fn`
189
+ * re-runs. See {@link HydrationSsrFields}.
190
+ *
191
+ * @returns `[state: Accessor<T>, setState: Setter<T>]`
192
+ *
193
+ * @description https://docs.solidjs.com/reference/basic-reactivity/create-signal
194
+ */
195
+ export declare const createSignal: {
196
+ <T>(): Signal<T | undefined>;
197
+ <T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
198
+ <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientSignalOptions<T>): Signal<T | undefined>;
199
+ <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationSignalOptions<T>): Signal<T>;
200
+ };
201
+ /**
202
+ * Lower-level primitive that backs the `<Errored>` flow control.
203
+ * Catches errors thrown inside `fn` and renders `fallback(error,
204
+ * reset)` instead. `reset()` recomputes the failing sources so the
205
+ * boundary can attempt to recover.
206
+ *
207
+ * App code should use `<Errored fallback={...}>` directly — reach for
208
+ * this only when authoring a custom boundary component.
209
+ *
210
+ * **Hydration:** if the server serialized an error for this boundary,
211
+ * the client re-throws it on the first hydration pass so `fallback`
212
+ * renders the same content the server emitted.
213
+ *
214
+ * @example
215
+ * ```tsx
216
+ * // Custom boundary built on the primitive — adds telemetry around the
217
+ * // canonical `<Errored>` shape.
218
+ * function TracedErrored(props: {
219
+ * fallback: (e: unknown) => JSX.Element;
220
+ * children: JSX.Element;
221
+ * }): JSX.Element {
222
+ * return createErrorBoundary(
223
+ * () => props.children,
224
+ * (err, reset) => {
225
+ * reportError(err);
226
+ * return props.fallback(err);
227
+ * }
228
+ * ) as unknown as JSX.Element;
229
+ * }
230
+ * ```
231
+ */
48
232
  export declare const createErrorBoundary: typeof coreErrorBoundary;
49
- export declare const createOptimistic: typeof coreOptimistic;
50
- export declare const createProjection: <T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue?: T, options?: HydrationProjectionOptions) => Store<T>;
233
+ /**
234
+ * Creates an optimistic signal a `Signal<T>` whose writes are
235
+ * tentative inside an `action` transition: they show up immediately,
236
+ * then auto-revert (or reconcile to the action's resolved value) once
237
+ * the transition settles.
238
+ *
239
+ * Use this for single-value optimistic state. For collection-shaped
240
+ * state, prefer `createOptimisticStore`.
241
+ *
242
+ * - **Plain form** — `createOptimistic(value, options?: SignalOptions<T>)`.
243
+ * - **Function form** — `createOptimistic(fn, options?: SignalOptions<T> & MemoOptions<T>)`:
244
+ * the authoritative value is recomputed by `fn`; the optimistic
245
+ * overlay reverts after each transition.
246
+ *
247
+ * @example
248
+ * ```ts
249
+ * const [name, setName] = createOptimistic("Ada");
250
+ *
251
+ * const rename = action(function* (next: string) {
252
+ * setName(next); // optimistic
253
+ * yield api.rename(next); // commits or reverts on settle
254
+ * });
255
+ * ```
256
+ *
257
+ * **Hydration:** in the function form, accepts an `ssrSource` field
258
+ * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}.
259
+ *
260
+ * @returns `[state: Accessor<T>, setState: Setter<T>]`
261
+ *
262
+ * @description https://docs.solidjs.com/reference/basic-reactivity/create-optimistic-signal
263
+ */
264
+ export declare const createOptimistic: {
265
+ <T>(): Signal<T | undefined>;
266
+ <T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
267
+ <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientSignalOptions<T>): Signal<T | undefined>;
268
+ <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationSignalOptions<T>): Signal<T>;
269
+ };
270
+ /**
271
+ * Creates a derived (projected) store — `createMemo` for stores. The
272
+ * derive function receives a mutable draft and either mutates it in
273
+ * place (canonical) or returns a new value. Either way the result is
274
+ * reconciled against the previous draft by `options.key` (default
275
+ * `"id"`), so surviving items keep their proxy identity — only
276
+ * added/removed items are created/disposed.
277
+ *
278
+ * Returns the projected store directly (no setter — reads only).
279
+ *
280
+ * Reach for this when you want the structural-sharing / per-property
281
+ * tracking of a store on top of a derived computation. For simple
282
+ * read-only derivations, `createMemo` is lighter.
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * // Mutation form — update individual fields on the draft.
287
+ * const summary = createProjection<{ total: number; active: number }>(
288
+ * draft => {
289
+ * draft.total = users().length;
290
+ * draft.active = users().filter(u => u.active).length;
291
+ * },
292
+ * { total: 0, active: 0 }
293
+ * );
294
+ *
295
+ * // Return form — produce a derived collection. Reconciled by `id`
296
+ * // so each surviving user keeps the same store identity.
297
+ * const activeUsers = createProjection<User[]>(
298
+ * () => allUsers().filter(u => u.active),
299
+ * []
300
+ * );
301
+ * ```
302
+ *
303
+ * **Hydration:** `ProjectionOptions` accepts an `ssrSource` field
304
+ * (`"server"` | `"hybrid"` | `"client"`) for the same client-vs-server
305
+ * tradeoffs as the other primitives. See {@link HydrationSsrFields}.
306
+ */
307
+ export declare const createProjection: <T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: T, options?: ProjectionOptions) => Refreshable<Store<T>>;
51
308
  type NoFn<T> = T extends Function ? never : T;
309
+ /**
310
+ * Creates a deeply-reactive store backed by a Proxy. Reads track each
311
+ * property accessed; only the parts that change trigger updates.
312
+ *
313
+ * Store properties hold **plain values**, not accessors. The proxy
314
+ * already tracks reads per-property — wrapping a value in
315
+ * `() => state.foo` produces a getter that *won't* track when called,
316
+ * which looks like a reactivity bug but is just a category error. If
317
+ * you have a signal-shaped piece of state, make it a property of the
318
+ * store (`{ foo: 1 }`) rather than nesting an accessor inside
319
+ * (`{ foo: () => signal() }`).
320
+ *
321
+ * The setter takes a **draft-mutating** function — mutate the draft
322
+ * in place (canonical). The callback may also return a new value:
323
+ * arrays are replaced by index (length adjusted), objects are
324
+ * shallow-diffed at the top level (keys present in the returned value
325
+ * are written, missing keys deleted). Use the return form for shapes
326
+ * where mutation is awkward — most commonly removing items via
327
+ * `filter`. The setter does **not** do keyed reconciliation; for
328
+ * that, use the derived/projection form (or `createProjection`).
329
+ *
330
+ * - **Plain form** — `createStore(initialValue)`: wraps a value in a
331
+ * reactive proxy.
332
+ * - **Derived form** — `createStore(fn, seed, options?)`: a
333
+ * *projection store* whose contents are computed by `fn(draft)`.
334
+ * `fn` may be sync, async, or an `AsyncIterable`; the projection's
335
+ * result reconciles against the existing store by `options.key`
336
+ * (default `"id"`) for stable identity.
337
+ *
338
+ * @example
339
+ * ```ts
340
+ * const [state, setState] = createStore({
341
+ * user: { name: "Ada", age: 36 },
342
+ * todos: [] as { id: string; text: string; done: boolean }[]
343
+ * });
344
+ *
345
+ * // Canonical: mutate the draft in place.
346
+ * setState(s => { s.user.age = 37; });
347
+ * setState(s => { s.todos.push({ id: "1", text: "x", done: false }); });
348
+ *
349
+ * // Return form: reach for it when mutation is awkward.
350
+ * setState(s => s.todos.filter(t => !t.done)); // remove items
351
+ * setState(s => ({ ...s, user: { name: "Grace", age: 85 } })); // shallow replace
352
+ * ```
353
+ *
354
+ * @example
355
+ * ```ts
356
+ * // Derived store — auto-fetches & reconciles by `id`.
357
+ * const [users] = createStore(
358
+ * async () => fetch("/users").then(r => r.json()),
359
+ * [] as User[]
360
+ * );
361
+ * ```
362
+ *
363
+ * **Hydration:** the derived form accepts `ProjectionOptions`, including
364
+ * an `ssrSource` field
365
+ * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}.
366
+ *
367
+ * @returns `[store: Store<T>, setStore: StoreSetter<T>]`
368
+ */
52
369
  export declare const createStore: {
53
370
  <T extends object = {}>(store: NoFn<T> | Store<NoFn<T>>): [get: Store<T>, set: StoreSetter<T>];
54
- <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store?: NoFn<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions): [get: Store<T>, set: StoreSetter<T>];
371
+ <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
55
372
  };
373
+ /**
374
+ * The store equivalent of `createOptimistic`. Writes inside an
375
+ * `action` transition are tentative — they show up immediately but
376
+ * auto-revert (or reconcile to the action's resolved value) once the
377
+ * transition finishes.
378
+ *
379
+ * Use this for optimistic UI on collection-shaped data. For
380
+ * single-value optimistic state, prefer `createOptimistic`.
381
+ *
382
+ * - **Plain form** — `createOptimisticStore(initialValue)`.
383
+ * - **Derived form** — `createOptimisticStore(fn, seed, options?)`:
384
+ * a projection store whose authoritative value is recomputed by
385
+ * `fn` and whose optimistic overlay reverts after each transition.
386
+ *
387
+ * `options.key` defaults to `"id"`; specify it only when your data
388
+ * uses a different identity field (e.g. `{ key: "uuid" }` or
389
+ * `{ key: t => t.slug }`). Restating the default just adds noise.
390
+ *
391
+ * @example
392
+ * ```ts
393
+ * const [todos, setTodos] = createOptimisticStore<Todo[]>([]);
394
+ *
395
+ * // Mutation: optimistic add, then in-place reconcile to the saved row.
396
+ * const addTodo = action(function* (text: string) {
397
+ * const tempId = crypto.randomUUID();
398
+ * setTodos(t => { t.push({ id: tempId, text, pending: true }); });
399
+ * const saved = yield api.createTodo(text);
400
+ * setTodos(t => {
401
+ * const i = t.findIndex(x => x.id === tempId);
402
+ * if (i >= 0) t[i] = saved;
403
+ * });
404
+ * });
405
+ *
406
+ * // Return form: filter is the natural shape for removal.
407
+ * const removeTodo = action(function* (id: string) {
408
+ * setTodos(t => t.filter(x => x.id !== id));
409
+ * yield api.removeTodo(id);
410
+ * });
411
+ * ```
412
+ *
413
+ * **Hydration:** the derived form accepts `ProjectionOptions`, including
414
+ * an `ssrSource` field
415
+ * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}.
416
+ *
417
+ * @returns `[store: Store<T>, setStore: StoreSetter<T>]`
418
+ */
56
419
  export declare const createOptimisticStore: {
57
420
  <T extends object = {}>(store: NoFn<T> | Store<NoFn<T>>): [get: Store<T>, set: StoreSetter<T>];
58
- <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store?: NoFn<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions): [get: Store<T>, set: StoreSetter<T>];
421
+ <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
59
422
  };
423
+ /**
424
+ * Creates a reactive computation that runs during the render phase as
425
+ * DOM elements are created and updated but not necessarily connected.
426
+ *
427
+ * Same compute/effect split as `createEffect` (`compute(prev)` tracks,
428
+ * `effect(next, prev?)` runs imperatively), but scheduled inside the
429
+ * render queue rather than after it. Reach for this only when
430
+ * authoring renderer plumbing — app code should use `createEffect`.
431
+ *
432
+ * ```ts
433
+ * createRenderEffect<T>(compute, effectFn, options?: EffectOptions);
434
+ * ```
435
+ *
436
+ * **Hydration:** `EffectOptions` accepts an `ssrSource` field
437
+ * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}.
438
+ *
439
+ * @example
440
+ * ```ts
441
+ * // Custom directive: bind an element's textContent to a reactive source
442
+ * // synchronously during render. App code should use `createEffect` for
443
+ * // post-render side effects.
444
+ * function bindText(el: HTMLElement, source: () => string) {
445
+ * createRenderEffect(
446
+ * () => source(),
447
+ * value => { el.textContent = value; }
448
+ * );
449
+ * }
450
+ * ```
451
+ *
452
+ * @description https://docs.solidjs.com/reference/secondary-primitives/create-render-effect
453
+ */
60
454
  export declare const createRenderEffect: typeof coreRenderEffect;
455
+ /**
456
+ * Creates a reactive effect with **separate compute and effect phases**.
457
+ *
458
+ * - `compute(prev)` runs reactively — *put all reactive reads here*.
459
+ * The returned value is passed to `effect` and is also the new
460
+ * "previous" value for the next run.
461
+ * - `effect(next, prev?)` runs imperatively (untracked) after the
462
+ * queue flushes. *Put DOM writes / fetch / logging / subscriptions
463
+ * here.* It may return a cleanup function which runs before the
464
+ * next effect or on disposal.
465
+ *
466
+ * Reactive reads inside `effect` will *not* re-trigger this effect —
467
+ * that's intentional. If you need a single-phase tracked effect, use
468
+ * `createTrackedEffect` (with the tradeoffs noted there).
469
+ *
470
+ * Pass an `EffectBundle` (`{ effect, error }`) instead of a plain
471
+ * function to intercept errors thrown from the compute or effect
472
+ * phases.
473
+ *
474
+ * ```ts
475
+ * createEffect<T>(compute, effectFn | { effect, error }, options?: EffectOptions);
476
+ * ```
477
+ *
478
+ * @example
479
+ * ```ts
480
+ * const [count, setCount] = createSignal(0);
481
+ *
482
+ * createEffect(
483
+ * () => count(), // compute: tracks `count`
484
+ * value => console.log(value) // effect: side effect
485
+ * );
486
+ *
487
+ * setCount(1); // logs 1 after the next flush
488
+ * ```
489
+ *
490
+ * @example
491
+ * ```ts
492
+ * createEffect(
493
+ * () => userId(),
494
+ * id => {
495
+ * const ctrl = new AbortController();
496
+ * fetch(`/users/${id}`, { signal: ctrl.signal });
497
+ * return () => ctrl.abort(); // cleanup before next run / disposal
498
+ * }
499
+ * );
500
+ * ```
501
+ *
502
+ * **Hydration:** `EffectOptions` accepts an `ssrSource` field
503
+ * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}.
504
+ *
505
+ * @description https://docs.solidjs.com/reference/basic-reactivity/create-effect
506
+ */
61
507
  export declare const createEffect: typeof coreEffect;
62
508
  /**
63
- * Tracks all resources inside a component and renders a fallback until they are all resolved
64
- * ```typescript
65
- * const AsyncComponent = lazy(() => import('./component'));
509
+ * Lower-level primitive that backs the `<Loading>` component. Returns a
510
+ * computation that yields `fallback()` while async reads inside `fn` are
511
+ * pending, and `fn()` once they have settled. Most callers should use
512
+ * `<Loading>` directly; this is exposed for renderers and library authors.
66
513
  *
67
- * <Loading fallback={<LoadingIndicator />}>
68
- * <AsyncComponent />
69
- * </Loading>
514
+ * @example
515
+ * ```tsx
516
+ * // Custom boundary component built on the primitive. App code uses
517
+ * // `<Loading fallback={…}>` directly.
518
+ * function MyLoading(props: { fallback: JSX.Element; children: JSX.Element }): JSX.Element {
519
+ * return createLoadingBoundary(
520
+ * () => props.children,
521
+ * () => props.fallback
522
+ * ) as unknown as JSX.Element;
523
+ * }
70
524
  * ```
71
- * @description https://docs.solidjs.com/reference/components/suspense
72
525
  */
73
- export declare function Loading(props: {
74
- fallback?: JSX.Element;
75
- children: JSX.Element;
76
- }): JSX.Element;
526
+ export declare function createLoadingBoundary(fn: () => any, fallback: () => any, options?: {
527
+ on?: () => any;
528
+ }): () => unknown;
77
529
  /**
78
530
  * Disables hydration for its children on the client.
79
531
  * During hydration, skips the subtree entirely (returns undefined so DOM is left untouched).
80
532
  * After hydration, renders children fresh.
533
+ *
534
+ * @example
535
+ * ```tsx
536
+ * // Mount a client-only widget that the server didn't render. The subtree
537
+ * // is left empty during hydration, then renders fresh once hydration ends.
538
+ * <NoHydration>
539
+ * <ClientOnlyMap />
540
+ * </NoHydration>
541
+ * ```
81
542
  */
82
543
  export declare function NoHydration(props: {
83
- children: JSX.Element;
84
- }): JSX.Element;
544
+ children: SolidElement;
545
+ }): SolidElement;
85
546
  /**
86
- * Re-enables hydration within a NoHydration zone (passthrough on client).
547
+ * Re-enables hydration within a `<NoHydration>` zone (passthrough on the
548
+ * client). Use it to opt a subtree back into hydration when the surrounding
549
+ * region was opted out.
550
+ *
551
+ * @example
552
+ * ```tsx
553
+ * // Inside a `<NoHydration>` region, re-enable hydration for one inner
554
+ * // subtree that does need to match a server-rendered fragment.
555
+ * <NoHydration>
556
+ * <ClientOnlyShell>
557
+ * <Hydration>
558
+ * <ServerHydratedWidget />
559
+ * </Hydration>
560
+ * </ClientOnlyShell>
561
+ * </NoHydration>
562
+ * ```
87
563
  */
88
564
  export declare function Hydration(props: {
89
565
  id?: string;
90
- children: JSX.Element;
91
- }): JSX.Element;
566
+ children: SolidElement;
567
+ }): SolidElement;
92
568
  export {};
package/types/index.d.ts CHANGED
@@ -1,20 +1,15 @@
1
- export { $PROXY, $TRACK, action, createOwner, createReaction, createRoot, createTrackedEffect, deep, flatten, flush, getNextChildId, getObserver, getOwner, isEqual, isRefreshing, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, latest, reconcile, refresh, repeat, resolve, NotReadyError, runWithOwner, snapshot, storePath, untrack } from "@solidjs/signals";
2
- export type { Accessor, ComputeFunction, EffectFunction, EffectOptions, Merge, NoInfer, NotWrappable, Omit, Owner, Signal, SignalOptions, Setter, Store, SolidStore, StoreNode, StoreSetter, StorePathRange, ArrayFilterFn, CustomPartial, Part, PathSetter } from "@solidjs/signals";
1
+ export { $PROXY, $REFRESH, $TRACK, action, createOwner, createReaction, createRevealOrder, createRoot, createTrackedEffect, deep, flatten, flush, getNextChildId, getObserver, getOwner, isDisposed, isEqual, isRefreshing, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, latest, reconcile, refresh, repeat, resolve, NotReadyError, runWithOwner, enableExternalSource, enforceLoadingBoundary, snapshot, storePath, untrack } from "@solidjs/signals";
2
+ export type { Accessor, ComputeFunction, EffectBundle, EffectFunction, EffectOptions, ExternalSource, ExternalSourceConfig, ExternalSourceFactory, Merge, MemoOptions, NoInfer, NotWrappable, Omit, Owner, ProjectionOptions, Refreshable, Signal, SignalOptions, SourceAccessor, Setter, Store, StoreOptions, SolidStore, StoreNode, StoreSetter, StorePathRange, ArrayFilterFn, CustomPartial, Part, PathSetter } from "@solidjs/signals";
3
3
  export { $DEVCOMP, children, createContext, useContext } from "./client/core.js";
4
- export type { ChildrenReturn, Context, ContextProviderComponent, ResolvedChildren, ResolvedJSXElement } from "./client/core.js";
4
+ export type { ChildrenReturn, Context, ContextProviderComponent, ResolvedChildren, ResolvedElement } from "./client/core.js";
5
5
  export * from "./client/component.js";
6
6
  export * from "./client/flow.js";
7
- export { sharedConfig, Loading, enableHydration, createMemo, createSignal, createStore, createProjection, createOptimistic, createOptimisticStore, createRenderEffect, createEffect, NoHydration, Hydration, NoHydrateContext } from "./client/hydration.js";
7
+ export type { ArrayElement, Element } from "./types.js";
8
+ export { sharedConfig, enableHydration, createErrorBoundary, createLoadingBoundary, createMemo, createSignal, createStore, createProjection, createOptimistic, createOptimisticStore, createRenderEffect, createEffect, NoHydration, Hydration, NoHydrateContext } from "./client/hydration.js";
9
+ /** @internal */
8
10
  export declare function ssrHandleError(): void;
9
- export declare function ssrRunInScope(): void;
10
- import type { JSX } from "./jsx.js";
11
- type JSXElement = JSX.Element;
12
- export type { JSXElement, JSX };
13
- import { registerGraph } from "./client/core.js";
14
- export declare const DEV: {
15
- readonly hooks: {};
16
- readonly registerGraph: typeof registerGraph;
17
- } | undefined;
11
+ import { type Dev } from "@solidjs/signals";
12
+ export declare const DEV: Dev | undefined;
18
13
  declare global {
19
14
  var Solid$$: boolean;
20
15
  }