@solidjs/web 2.0.0-experimental.9 → 2.0.0-rc.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.
Files changed (85) hide show
  1. package/README.md +22 -4
  2. package/dist/dev.cjs +1585 -225
  3. package/dist/dev.js +1510 -201
  4. package/dist/server.cjs +2642 -264
  5. package/dist/server.js +2542 -217
  6. package/dist/web.cjs +1523 -218
  7. package/dist/web.js +1448 -194
  8. package/frames/dist/client.cjs +1916 -0
  9. package/frames/dist/client.dev.cjs +1933 -0
  10. package/frames/dist/client.dev.js +1921 -0
  11. package/frames/dist/client.js +1904 -0
  12. package/frames/dist/server.cjs +3667 -0
  13. package/frames/dist/server.js +3654 -0
  14. package/frames/package.json +30 -0
  15. package/package.json +349 -37
  16. package/serialization/decode/package.json +20 -0
  17. package/serialization/dist/decode.cjs +110 -0
  18. package/serialization/dist/decode.js +104 -0
  19. package/serialization/dist/serialization.cjs +232 -0
  20. package/serialization/dist/serialization.js +215 -0
  21. package/serialization/package.json +20 -0
  22. package/serialization/types/index.d.ts +182 -0
  23. package/serialization/types/serializer-decode.d.ts +182 -0
  24. package/serialization/types-cjs/index.d.cts +182 -0
  25. package/serialization/types-cjs/package.json +3 -0
  26. package/serialization/types-cjs/serializer-decode.d.cts +182 -0
  27. package/server-functions/dist/client.cjs +646 -0
  28. package/server-functions/dist/client.js +617 -0
  29. package/server-functions/dist/rich-args.cjs +11 -0
  30. package/server-functions/dist/rich-args.js +9 -0
  31. package/server-functions/dist/server.cjs +1077 -0
  32. package/server-functions/dist/server.dev.cjs +1077 -0
  33. package/server-functions/dist/server.dev.js +1045 -0
  34. package/server-functions/dist/server.js +1045 -0
  35. package/server-functions/package.json +40 -0
  36. package/server-functions/rich-args/package.json +20 -0
  37. package/storage/package.json +8 -3
  38. package/storage/types/index.d.ts +26 -0
  39. package/storage/types-cjs/index.d.cts +28 -0
  40. package/storage/types-cjs/package.json +3 -0
  41. package/types/client.d.ts +290 -27
  42. package/types/cookies.d.ts +93 -0
  43. package/types/core.d.ts +6 -2
  44. package/types/frames/client.d.ts +36 -0
  45. package/types/frames/frame-client.d.ts +338 -0
  46. package/types/frames/frame-sink.d.ts +194 -0
  47. package/types/frames/frame-transport.d.ts +222 -0
  48. package/types/frames/serializer.d.ts +182 -0
  49. package/types/frames/server.d.ts +52 -0
  50. package/types/index.d.ts +209 -24
  51. package/types/jsx-properties.d.ts +93 -0
  52. package/types/jsx.d.ts +4150 -1
  53. package/types/response.d.ts +174 -0
  54. package/types/serializer-decode.d.ts +182 -0
  55. package/types/serializer.d.ts +182 -0
  56. package/types/server-functions/client.d.ts +201 -0
  57. package/types/server-functions/flash.d.ts +38 -0
  58. package/types/server-functions/rich-args.d.ts +10 -0
  59. package/types/server-functions/server.d.ts +588 -0
  60. package/types/server-functions/shared.d.ts +523 -0
  61. package/types/server-mock.d.ts +249 -12
  62. package/types/server.d.ts +424 -51
  63. package/types-cjs/client.d.cts +337 -0
  64. package/types-cjs/cookies.d.cts +93 -0
  65. package/types-cjs/core.d.cts +6 -0
  66. package/types-cjs/frames/client.d.cts +36 -0
  67. package/types-cjs/frames/frame-client.d.cts +338 -0
  68. package/types-cjs/frames/frame-sink.d.cts +194 -0
  69. package/types-cjs/frames/frame-transport.d.cts +222 -0
  70. package/types-cjs/frames/serializer.d.cts +182 -0
  71. package/types-cjs/frames/server.d.cts +52 -0
  72. package/types-cjs/index.d.cts +230 -0
  73. package/types-cjs/jsx-properties.d.cts +93 -0
  74. package/types-cjs/jsx.d.cts +4150 -0
  75. package/types-cjs/package.json +3 -0
  76. package/types-cjs/response.d.cts +174 -0
  77. package/types-cjs/serializer-decode.d.cts +182 -0
  78. package/types-cjs/serializer.d.cts +182 -0
  79. package/types-cjs/server-functions/client.d.cts +201 -0
  80. package/types-cjs/server-functions/flash.d.cts +38 -0
  81. package/types-cjs/server-functions/rich-args.d.cts +10 -0
  82. package/types-cjs/server-functions/server.d.cts +588 -0
  83. package/types-cjs/server-functions/shared.d.cts +523 -0
  84. package/types-cjs/server-mock.d.cts +277 -0
  85. package/types-cjs/server.d.cts +523 -0
@@ -0,0 +1,222 @@
1
+ // EXPERIMENTAL — the frames/server-components surface ships as an
2
+ // experimental preview, excluded from the 2.0 stability guarantee: API
3
+ // shapes and the wire format may change between prereleases (RFC 11).
4
+ // Every export in this module is @experimental.
5
+ import { FrameChunk, FrameHost } from "./frame-client.cjs";
6
+ import { JSONCodecOptions } from "./serializer-decode.cjs";
7
+
8
+ // Structural mirror of server-functions/shared.js's FlightDataConsumer:
9
+ // this file may only reference siblings that ship with it when integrations
10
+ // copy the frames declaration set (solid-web's types build), and the
11
+ // server-functions declarations are copied to a different root.
12
+ type FlightConsumer = (data: unknown, context: { response: Response }) => void | Promise<void>;
13
+
14
+ /**
15
+ * Header tagging a Response as a frame stream; its value is the producing
16
+ * frame's id. Frame-owned wire contract — deliberately not a server-function
17
+ * `BodyFormat` entry, since the body is frame chunks, not a serialized value.
18
+ * @experimental
19
+ */
20
+ export const FRAME_STREAM_HEADER: "X-Frame-Stream";
21
+
22
+ /**
23
+ * Whether a fetch Response carries a frame stream.
24
+ * @experimental
25
+ */
26
+ export function isFrameStreamResponse(response: Response): boolean;
27
+
28
+ /**
29
+ * Options for `applyFrameResponse`.
30
+ * @experimental
31
+ */
32
+ export interface ApplyFrameResponseOptions {
33
+ /**
34
+ * Remap the producer's root frame id onto a local one — the id your
35
+ * insertable/frame registered under — so navigations to the same boundary
36
+ * reuse the same frame regardless of what the server called it. Boundary
37
+ * identity belongs to the client.
38
+ */
39
+ as?: string;
40
+ /**
41
+ * Restamp every chunk of the response with this version (one response IS
42
+ * one version). Versions belong to the client too: the producer cannot
43
+ * know how many streams a boundary has consumed, so pass the Nth-response
44
+ * counter to make policy A's stale-guard real across navigations. A
45
+ * single-flight response addresses several boundaries, each with its own
46
+ * history — pass a function and it is called once per frame in the
47
+ * response.
48
+ */
49
+ version?: number | ((frameId: string) => number);
50
+ /**
51
+ * Receives the payload text of each `outcome` chunk — the response-scoped
52
+ * single-flight envelope, the caller's result rather than anything the
53
+ * host renders.
54
+ */
55
+ onOutcome?(payload: string): void;
56
+ }
57
+
58
+ /**
59
+ * Reads a frame-stream Response to completion, applying every chunk to
60
+ * `host`. Chunks are length-prefixed JSON over the server-function wire
61
+ * framing. Resolves with the id the chunks were applied under once the
62
+ * stream ends; rejects on a malformed or errored stream.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * const response = await getStory(id); // frame-tagged server function result
67
+ * if (isFrameStreamResponse(response)) {
68
+ * await applyFrameResponse(response, host, { as: "story-pane" });
69
+ * }
70
+ * ```
71
+ * @experimental
72
+ */
73
+ export function applyFrameResponse(
74
+ response: Response,
75
+ host: FrameHost,
76
+ options?: ApplyFrameResponseOptions
77
+ ): Promise<string>;
78
+
79
+ /**
80
+ * Brands an inline-rendered server component with its function id.
81
+ * @experimental
82
+ */
83
+ export const SERVER_COMPONENT: unique symbol;
84
+
85
+ /**
86
+ * The unwrapped server component behind an inline-render wrap.
87
+ * @experimental
88
+ */
89
+ export const SERVER_COMPONENT_SOURCE: unique symbol;
90
+
91
+ /**
92
+ * The call's wire address (`frameAddress`), for regions to be emitted under.
93
+ * @experimental
94
+ */
95
+ export const SERVER_COMPONENT_ADDRESS: unique symbol;
96
+
97
+ /**
98
+ * The binding brand on values the transport resolves: `{ component, address }`
99
+ * — the identity split (DR-1). `component` is the mount identity, one per
100
+ * server function; `address` names the call's content store. An equals-gated
101
+ * reader compares `component` across resolutions: same function means "same
102
+ * instance, new binding" — keep the mounted instance and deliver the new
103
+ * address into it; a different function swaps normally. `Symbol.for`, so
104
+ * frameworks can honor it without importing this module.
105
+ * @experimental
106
+ */
107
+ export const COMPONENT_BINDING: unique symbol;
108
+
109
+ /**
110
+ * The value under `COMPONENT_BINDING` on a transport-resolved binding.
111
+ * @experimental
112
+ */
113
+ export interface ComponentBinding<C = unknown> {
114
+ /** The per-function mount component (the equals-gate identity). */
115
+ component: C;
116
+ /** The call's intrinsic (function, arguments) address — its store's key. */
117
+ address: string;
118
+ }
119
+
120
+ /**
121
+ * Seroval plugin for a server component crossing a serialization boundary:
122
+ * a branded component serializes as a REFERENCE — a per-function document
123
+ * placeholder in the hydration serializer, a live-registry lookup by call
124
+ * address in the JSON codec (single-flight envelopes) — its markup never
125
+ * rides as data.
126
+ * @experimental
127
+ */
128
+ export const ServerComponentPlugin: unknown;
129
+
130
+ /**
131
+ * Installs the hydration-serializer registry prefix: given the emitted
132
+ * script's serializer context, returns the expression the next serialized
133
+ * reference reads the `_$SC` registry through (the self-bootstrapping form
134
+ * on a script's first reference, a bare read after). Loaded document-SSR
135
+ * modules install this (see frame-sink); client bundles never carry the
136
+ * bootstrap text.
137
+ * @experimental
138
+ */
139
+ export function setServerComponentBootstrap(resolve: (ctx: unknown) => string): void;
140
+
141
+ /**
142
+ * The codec options for a single-flight envelope: `codec` plus
143
+ * `ServerComponentPlugin` (deduped by tag). Injected by the protocol on both
144
+ * legs; exported for integrations composing their own flight carriers.
145
+ * @experimental
146
+ */
147
+ export function flightCodec(codec?: JSONCodecOptions): JSONCodecOptions;
148
+
149
+ /**
150
+ * Options for `createServerComponentHandler`.
151
+ * @experimental
152
+ */
153
+ export interface ServerComponentHandlerOptions<C = unknown> {
154
+ host: FrameHost;
155
+ /**
156
+ * Builds the framework's mount component for a server FUNCTION. Invoked
157
+ * once per function and cached — this is the equals-gate identity every
158
+ * call of the function resolves through. The component is CALLED (by the
159
+ * binding wrapper or a gated reader), receiving its current address as a
160
+ * second argument (`() => string`); it should (re-)bind its frame's pull
161
+ * to that address's store. Multi-mount fans out per site.
162
+ */
163
+ component(fnId: string): C;
164
+ /**
165
+ * A new response is about to stream into an address: rotate
166
+ * response-scoped state (codec data tables) here. `version` is the
167
+ * client-owned stream counter the chunks will be stamped with.
168
+ */
169
+ onStream?(address: string, version: number, response: Response): void;
170
+ /**
171
+ * Answer a call SYNCHRONOUSLY before any request is made (t = 0 local
172
+ * answers — e.g. a boundary the document already carries). Returning a
173
+ * non-undefined value resolves the call with it; a hydrating consumer
174
+ * never observes a pending beat.
175
+ */
176
+ intercept?(info: { id: string; meta: unknown; args: unknown[] }): C | undefined;
177
+ /**
178
+ * Reads the registered single-flight consumer at delivery time. The
179
+ * consumer is module state in the server-function client's SHARED
180
+ * instance; pass a getter reading that instance when your bundling gives
181
+ * this module a private copy. Defaults to the local copy's reader.
182
+ */
183
+ consumer?(): FlightConsumer | undefined;
184
+ /**
185
+ * Reads the configured codec options at decode time — same instance-
186
+ * identity contract as `consumer`. Defaults to the local copy's reader.
187
+ */
188
+ codec?(): JSONCodecOptions | undefined;
189
+ }
190
+
191
+ /**
192
+ * The client mirror of `frameTransformResult`, shaped for the server-function
193
+ * client's `responseHandler` seam: frame-stream responses resolve the call
194
+ * with a **binding** — a callable wrapper branded `COMPONENT_BINDING` — so
195
+ * an equals-gated consumer (Solid's `dynamic`) never remounts across
196
+ * refetches or argument changes; the response streams into the address's
197
+ * resident store as the only observable effect.
198
+ *
199
+ * The identity split (DR-1): stores are keyed per-ADDRESS — the call's
200
+ * intrinsic (function, arguments) name, one-to-one with a query cache's
201
+ * per-args entries — while mounts are per-SITE, rendering the per-function
202
+ * component and following delivered addresses. An address nothing is bound
203
+ * to warms its store (preload isolation is the default, not a rule).
204
+ * @experimental
205
+ */
206
+ export function createServerComponentHandler<C>(options: ServerComponentHandlerOptions<C>): {
207
+ intercept?(info: { id: string; meta: unknown; args: unknown[] }): unknown;
208
+ handle(
209
+ response: Response,
210
+ ctx: { id: string; meta: unknown; args: unknown[]; context: unknown }
211
+ ): unknown;
212
+ /**
213
+ * Declares that the document is showing a call: hydration-data references
214
+ * carry their call's address (`_$SC.r(id, address)`) but never travel
215
+ * through the transport, so the integration forwards those records here.
216
+ * Mints the call's binding (a post-load refetch then resolves a value
217
+ * whose component matches what the document mounted) and brands the
218
+ * per-function component so cache-seeded readers deliver instead of
219
+ * remounting when their site later switches calls.
220
+ */
221
+ showing(address: string, functionId: string): void;
222
+ };
@@ -0,0 +1,182 @@
1
+ // Serialization surface (published as `@solidjs/web/serialization`): the
2
+ // runtime's Seroval machinery, exposed for the runtime's own entries and
3
+ // for integrations building transports on the same codec. This is
4
+ // INTEGRATION-FACING plumbing, not application API — it is exempt from the
5
+ // 2.0 stability guarantee and may change between releases. Application and
6
+ // router code should configure `codec` on the server-function entries
7
+ // instead of importing from here.
8
+ import type { Serializer } from "seroval";
9
+ import {
10
+ JSONCodecOptions,
11
+ PluginInfo,
12
+ SerializerPlugin,
13
+ SerovalNode
14
+ } from "./serializer-decode.cjs";
15
+
16
+ // The decode half — `SerovalNode`, the plugin TYPES, `DEFAULT_WEB_PLUGINS`,
17
+ // `resolveSerializerPlugins`, `JSONCodecOptions`, `createJSONDeserializer`,
18
+ // `createJSONDataTable` — is declared in serializer-decode.d.ts (published
19
+ // as `@solidjs/web/serialization/decode`, the module lazy client consumers
20
+ // load) and re-exported here so this remains the full surface.
21
+ export * from "./serializer-decode.cjs";
22
+
23
+ // ---- Plugin authoring ----
24
+ //
25
+ // Unlike the rest of this entry, plugin authoring is APPLICATION-FACING —
26
+ // it is the supported way to feed the serializers' `plugins` options and
27
+ // the server-function entries' `codec.plugins`. The values re-export
28
+ // seroval's own (`createPlugin`, `OpaqueReference` — see serializer.js);
29
+ // the plugin TYPES live in serializer-decode.d.ts (hand-declared there —
30
+ // see its banner for why).
31
+
32
+ /**
33
+ * Builds a `SerializerPlugin` — seroval's `createPlugin`, re-exported so
34
+ * plugin authors stay on the exact seroval instance/version the runtime
35
+ * serializes with. Import it from HERE, not from your own `seroval`
36
+ * dependency: a plugin built against a different copy/version would not
37
+ * fail the build — it would emit nodes the other peer can't interpret.
38
+ *
39
+ * Application-facing (see the plugin-authoring banner above).
40
+ */
41
+ export function createPlugin<Value, Info extends PluginInfo>(
42
+ plugin: SerializerPlugin<Value, Info>
43
+ ): SerializerPlugin<Value, Info>;
44
+
45
+ /**
46
+ * Seroval's `OpaqueReference`, re-exported from the runtime's own instance
47
+ * (an `OpaqueReference` from another seroval copy fails the serializer's
48
+ * instanceof check and serializes as a plain value): wraps a value so it
49
+ * crosses the wire as its `replacement` (default `undefined`) while
50
+ * staying readable in-process through `.value`.
51
+ *
52
+ * Application-facing (see the plugin-authoring banner above).
53
+ */
54
+ export class OpaqueReference<V, R = undefined> {
55
+ readonly value: V;
56
+ readonly replacement?: R;
57
+ constructor(value: V, replacement?: R);
58
+ }
59
+
60
+ /**
61
+ * Options for `createSerializer`.
62
+ *
63
+ * Integration-facing; may change (see the entry banner).
64
+ */
65
+ export interface WebSerializerOptions {
66
+ /** Name of the global object the emitted scripts write resolved values into. */
67
+ globalIdentifier: string;
68
+ /** Cross-reference scope id, for isolating multiple streams on one page. */
69
+ scopeId?: string;
70
+ /**
71
+ * Seroval feature bitflags to exclude from output. Defaults to disabling
72
+ * post-ES2017 features (AggregateError, BigInt typed arrays). Outside
73
+ * development, `Error.prototype.stack` is additionally stripped on top of
74
+ * any override — serialized stacks leak server paths to the client.
75
+ */
76
+ disabledFeatures?: number;
77
+ /** Extra plugins, composed ahead of `DEFAULT_WEB_PLUGINS`. */
78
+ plugins?: SerializerPlugin[];
79
+ /** Receives each emitted script chunk. */
80
+ onData: (result: string) => void;
81
+ onError?: (error: unknown) => void;
82
+ /** Fires once all async values have settled. */
83
+ onDone?: () => void;
84
+ }
85
+
86
+ /**
87
+ * Creates a streaming Seroval serializer preconfigured with the web plugin
88
+ * set and the default feature policy. Emits JavaScript chunks (through
89
+ * `onData`) that reconstruct the values under `globalIdentifier` when
90
+ * evaluated — the script-injection form of serialization renderers build
91
+ * on. For a JSON-based wire codec (no eval on the receiving side), use
92
+ * `serializeJSON` / `createJSONDeserializer` instead.
93
+ *
94
+ * Integration-facing; may change (see the entry banner).
95
+ */
96
+ export function createSerializer(options: WebSerializerOptions): Serializer;
97
+
98
+ /**
99
+ * Options for `createHydrationSerializer` — `WebSerializerOptions` minus
100
+ * the knobs hydration pins (`globalIdentifier`, `disabledFeatures`).
101
+ * @internal
102
+ */
103
+ export type HydrationSerializerOptions = Omit<
104
+ WebSerializerOptions,
105
+ "globalIdentifier" | "disabledFeatures"
106
+ >;
107
+
108
+ /**
109
+ * Renderer primitive — the serializer SSR uses for hydration output. Pins
110
+ * the hydration global (`_$HY.r`) and feature policy; only the wiring
111
+ * options (callbacks, scope, extra plugins) are configurable. Not meant
112
+ * for hand-written code — custom serialization should use
113
+ * `createSerializer` or the JSON codec.
114
+ * @internal
115
+ */
116
+ export function createHydrationSerializer(options: HydrationSerializerOptions): Serializer;
117
+
118
+ /**
119
+ * Renderer primitive — returns the cross-reference bootstrap script SSR
120
+ * emits ahead of hydration data for a render scope. Not meant for
121
+ * hand-written code.
122
+ * @internal
123
+ */
124
+ export function getLocalHeaderScript(id?: string): string;
125
+
126
+ // ---- JSON codec (server function transports) ----
127
+ // (`JSONCodecOptions` and the decode half are declared in
128
+ // serializer-decode.d.ts and re-exported above.)
129
+
130
+ /**
131
+ * Options for `serializeJSON`.
132
+ *
133
+ * Integration-facing; may change (see the entry banner).
134
+ */
135
+ export interface JSONSerializeOptions extends JSONCodecOptions {
136
+ /**
137
+ * Receives each serialized node; `initial` is true for the first chunk
138
+ * (the source value itself). Async values produce additional chunks as
139
+ * they resolve.
140
+ */
141
+ onParse: (node: SerovalNode, initial: boolean) => void;
142
+ onError?: (error: unknown) => void;
143
+ /** Fires once all async values have settled. */
144
+ onDone?: () => void;
145
+ }
146
+
147
+ /**
148
+ * Serializes `value` as SerovalNode chunks delivered through `onParse` —
149
+ * the encoding half of the eval-free JSON codec (RPC-style transports;
150
+ * the deserializing peer needs no script evaluation, so CSP-safe). Wire
151
+ * framing of the nodes is the transport's concern. Returns a cancel
152
+ * function that aborts pending async serialization.
153
+ *
154
+ * Integration-facing; may change (see the entry banner).
155
+ */
156
+ export function serializeJSON(value: unknown, options: JSONSerializeOptions): () => void;
157
+
158
+ /** Options for `createJSONSerializer`. */
159
+ export interface JSONSerializerOptions extends JSONCodecOptions {
160
+ /**
161
+ * Receives each keyed record — `initial` is true for a key's first node
162
+ * (the written value itself); async values patch through later records
163
+ * under the same key. The decoding peer is `createJSONDataTable`.
164
+ */
165
+ onData: (record: { key: string; node: SerovalNode; initial: boolean }) => void;
166
+ onError?: (error: unknown) => void;
167
+ /** Fires once `flush()` has been called and every pending value settled. */
168
+ onDone?: () => void;
169
+ }
170
+
171
+ /**
172
+ * The keyed, streaming encoder of the eval-free JSON codec — the render
173
+ * stream's data serializer (frames default to it). Each `write(key, value)`
174
+ * shares one reference space, so cross-record identity holds; `flush()`
175
+ * marks the write set complete (writes after it are dropped, mirroring the
176
+ * hydration serializer); `close()` aborts pending async serialization.
177
+ */
178
+ export function createJSONSerializer(options: JSONSerializerOptions): {
179
+ write(key: string, value: unknown): void;
180
+ flush(): void;
181
+ close(): void;
182
+ };
@@ -0,0 +1,52 @@
1
+ import type { Element as SolidElement } from "solid-js";
2
+ /**
3
+ * A client position in a server component: a prop the server renders (as JSX
4
+ * or by calling it) where client-owned markup belongs. `P` is the client
5
+ * component's own props, so a server component can reference the client
6
+ * component's type directly instead of restating it.
7
+ *
8
+ * Arguments are classified by VALUE, not by name — any prop may carry any of
9
+ * these:
10
+ *
11
+ * - primitives ride the chunk;
12
+ * - server JSX streams as a nested region (html once, never data);
13
+ * - anything else serializes as a data record.
14
+ *
15
+ * Async server JSX in an argument needs its own boundary: the region is
16
+ * emitted as one finished string, so a bare async read has no fallback to
17
+ * show and no fragment to reveal into.
18
+ *
19
+ * `$key` names the occurrence so client state follows an entity across
20
+ * responses rather than being positional — the slot-level analogue of `For`'s
21
+ * `keyed`, for when references can't carry identity because every response
22
+ * re-creates everything. It is occurrence identity, not client data: it is
23
+ * stripped before the client component sees its props. Positional identity is
24
+ * the right default; `$key` matters when a live list reorders.
25
+ * @experimental
26
+ */
27
+ export type Slot<P = {}> = (props: P & {
28
+ $key?: string | number;
29
+ }) => SolidElement;
30
+ /**
31
+ * Types an async value crossing the slot border (DR-2, value tier). What you
32
+ * pass is what ships — the promise / async iterable itself rides the data
33
+ * channel — but the client's prop READ settles: it suspends into the covering
34
+ * boundary until first arrival (a promise's resolution, an iterable's first
35
+ * yield), then reads as the settled value, updating per yield for iterables.
36
+ *
37
+ * `asyncArg` is the type-level statement of that contract: identity at
38
+ * runtime, settled type at the border, so `Slot<P>` keeps the fill's props
39
+ * truthful to what its reads actually return.
40
+ *
41
+ * Slots render as JSX — the compiler wraps each prop in a getter so the read
42
+ * defers to the slot border, where the runtime owns it. A call form
43
+ * (`props.status({ … })`) evaluates its args eagerly in the component body —
44
+ * a top-level read, an error in most cases.
45
+ *
46
+ * ```tsx
47
+ * <props.status progress={asyncArg(gen.progress)} stats={asyncArg(gen.stats)} />
48
+ * ```
49
+ */
50
+ export declare function asyncArg<T>(value: PromiseLike<T> | AsyncIterable<T>): T;
51
+ export { renderToFrameStream, renderServerComponent, serverComponentResponse, frameTransformResult, frameTransformFlightResult, createFrameSink, frameTransformDirectResult, ServerComponentPlugin, SERVER_COMPONENT_BOOTSTRAP } from "./frame-sink.cjs";
52
+ export { FRAME_STREAM_HEADER, isFrameStreamResponse } from "./frame-transport.cjs";
@@ -0,0 +1,230 @@
1
+ import { hydrate as hydrateCore } from "./client.cjs";
2
+ import { Component } from "solid-js";
3
+ import type { JSX } from "./jsx.cjs";
4
+ export * from "./client.cjs";
5
+ export * from "./server-mock.cjs";
6
+ export * from "./response.cjs";
7
+ export type { JSX } from "./jsx.cjs";
8
+ export { For, Show, Switch, Match, Errored, Loading, Repeat, Reveal, NoHydration, Hydration } from "solid-js";
9
+ import { merge } from "solid-js";
10
+ /**
11
+ * Compiler-emitted prop-spread helper. The JSX transform (in
12
+ * `dom-expressions`) emits `mergeProps(...)` calls when compiling prop
13
+ * spreads on components — it is *not* a user-facing API. Application code
14
+ * should import `merge` from `solid-js` directly.
15
+ *
16
+ * @internal
17
+ */
18
+ export declare const mergeProps: typeof merge;
19
+ /**
20
+ * Build-time constant indicating whether code is running on the server. This
21
+ * client entry sets it to `false`; the matching server entry (`@solidjs/web`
22
+ * resolved through the `solid` server export condition) sets it to `true`.
23
+ *
24
+ * Bundlers can dead-code-eliminate branches gated on `isServer`, so guarding
25
+ * browser-only code with `if (!isServer) {…}` keeps it out of the SSR bundle
26
+ * entirely.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { isServer } from "@solidjs/web";
31
+ *
32
+ * if (!isServer) {
33
+ * // Browser-only: tree-shaken out of the SSR bundle.
34
+ * window.addEventListener("resize", onResize);
35
+ * }
36
+ * ```
37
+ */
38
+ export declare const isServer: boolean;
39
+ /**
40
+ * Build-time constant indicating whether code is running in a dev build.
41
+ * Replaced statically (`_SOLID_DEV_`) by the bundler integration, so guards
42
+ * like `if (isDev) {…}` are stripped from production builds.
43
+ *
44
+ * Use this to gate dev-only diagnostics, warnings, or expensive invariants
45
+ * that should never ship to production.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { isDev } from "@solidjs/web";
50
+ *
51
+ * if (isDev) {
52
+ * console.warn("debug-only path");
53
+ * }
54
+ * ```
55
+ */
56
+ export declare const isDev: boolean;
57
+ type MountableElement = Element | Document | ShadowRoot | DocumentFragment | Node;
58
+ export type IntrinsicElement = Extract<keyof JSX.IntrinsicElements, string>;
59
+ export type ValidComponent = IntrinsicElement | Component<any> | (string & {});
60
+ export type ComponentProps<T extends ValidComponent> = T extends Component<infer P> ? P : T extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[T] : Record<string, unknown>;
61
+ export type DynamicProps<T extends ValidComponent, P = ComponentProps<T>> = {
62
+ [K in keyof P]: P[K];
63
+ } & {
64
+ component: T | null | undefined | false;
65
+ };
66
+ /**
67
+ * Renders a component tree into a DOM element. Returns a dispose function
68
+ * that tears the tree down and cleans up reactive scopes when called.
69
+ *
70
+ * @example
71
+ * ```tsx
72
+ * import { render } from "@solidjs/web";
73
+ *
74
+ * const dispose = render(() => <App />, document.getElementById("root")!);
75
+ *
76
+ * // Later, to unmount:
77
+ * dispose();
78
+ * ```
79
+ *
80
+ * @remarks
81
+ * The top-level insert is queued via `insertOptions: { schedule: true }` so
82
+ * its initial DOM attach goes through the effect queue rather than executing
83
+ * inline. This lets the mount participate in transitions: if an uncaught
84
+ * async read surfaces during the initial render (no `Loading` ancestor
85
+ * absorbs it), the mount is held by the transition and attaches atomically
86
+ * once all pending settles. On the no-async happy path the tail `flush()`
87
+ * drains the queued callback so the attach is synchronous by the time
88
+ * `render()` returns. The dev enforcement window scopes
89
+ * `ASYNC_OUTSIDE_LOADING_BOUNDARY` to the initial mount only.
90
+ */
91
+ export declare function render(code: () => JSX.Element, element: MountableElement, init?: unknown, options?: {
92
+ renderId?: string;
93
+ }): () => void;
94
+ /**
95
+ * Resumes a server-rendered tree on the client, attaching event listeners
96
+ * and reactive bindings without reconstructing the DOM. Returns a `dispose`
97
+ * function that tears down reactive scopes (DOM nodes are left in place).
98
+ *
99
+ * Use this when the page HTML was produced by `renderToString` or
100
+ * `renderToStream`. For client-only apps, use `render` instead.
101
+ *
102
+ * Pass `options.renderId` to hydrate one of multiple roots emitted by a
103
+ * server render that used the same id.
104
+ *
105
+ * @example
106
+ * ```tsx
107
+ * import { hydrate } from "@solidjs/web";
108
+ *
109
+ * hydrate(() => <App />, document.getElementById("root")!);
110
+ * ```
111
+ */
112
+ export declare const hydrate: typeof hydrateCore;
113
+ /**
114
+ * Renders its children into a different part of the DOM (modal roots,
115
+ * tooltips, layers that need to escape an `overflow: hidden` ancestor).
116
+ *
117
+ * If `mount` is omitted, the portal attaches to `document.body`. The portal
118
+ * still participates in the parent's reactive scope and disposes when the
119
+ * parent does.
120
+ *
121
+ * Portals are client-only islands: the server renders nothing for them, and
122
+ * under hydration the children render fresh once hydration settles. Async
123
+ * read inside a portal therefore starts on the client — data that should be
124
+ * fetched on the server belongs above the portal (hoist the read, not the
125
+ * render), and async UI inside one wants its own `<Loading>` boundary.
126
+ *
127
+ * @example
128
+ * ```tsx
129
+ * <Portal mount={document.getElementById("modal-root")!}>
130
+ * <Dialog />
131
+ * </Portal>
132
+ * ```
133
+ *
134
+ * @description https://docs.solidjs.com/reference/components/portal
135
+ */
136
+ export declare function Portal(props: {
137
+ mount?: Element;
138
+ children: JSX.Element;
139
+ }): JSX.Element;
140
+ export declare function dynamic<T extends ValidComponent>(source: () => T | Promise<T> | null | undefined | false): Component<ComponentProps<T>>;
141
+ /**
142
+ * Renders an arbitrary custom or native component and forwards the other
143
+ * props. JSX form of `dynamic()` — same primitive, picked at the JSX site.
144
+ *
145
+ * @example
146
+ * ```tsx
147
+ * <Dynamic
148
+ * component={multiline() ? RichTextEditor : "input"}
149
+ * value={value()}
150
+ * onInput={onInput}
151
+ * />
152
+ * ```
153
+ *
154
+ * @description https://docs.solidjs.com/reference/components/dynamic
155
+ */
156
+ export declare function Dynamic<T extends ValidComponent>(props: DynamicProps<T>): JSX.Element;
157
+ /**
158
+ * Wraps a dynamically imported component so it renders only in the browser.
159
+ * The server renders `props.fallback` (and nothing else); the client shows
160
+ * the fallback until the import resolves and the tree has mounted, then
161
+ * swaps the real component in.
162
+ *
163
+ * Unlike `lazy()`, this avoids Suspense entirely and never server-renders
164
+ * the wrapped component — only the fallback — so the component participates
165
+ * in no hydration asset manifest and its code is guaranteed to never run on
166
+ * the server (safe for browser-only libraries touching `window`, DOM
167
+ * measurement, etc.). The mount gate keeps hydration safe: during hydration
168
+ * the fallback is rendered exactly as the server did, and the swap happens
169
+ * only after settle, so there is no mismatch.
170
+ *
171
+ * By default the import starts as soon as `clientOnly` is called (module
172
+ * load); pass `{ lazy: true }` to defer the import to the component's first
173
+ * render.
174
+ *
175
+ * @example
176
+ * ```tsx
177
+ * const Chart = clientOnly(() => import("./Chart.jsx"));
178
+ * // <Chart fallback={<div>Loading chart…</div>} data={data()} />
179
+ * ```
180
+ */
181
+ export declare function clientOnly<T extends Component<any>>(fn: () => Promise<{
182
+ default: T;
183
+ }>, options?: {
184
+ lazy?: boolean;
185
+ }, _moduleUrl?: string): Component<ComponentProps<T> & {
186
+ fallback?: JSX.Element;
187
+ }>;
188
+ /**
189
+ * Declares the HTTP response status (and optional status text) for the
190
+ * lifetime of the current reactive scope during SSR — call it bare in a
191
+ * component or reactive-scope body where the status is decided (a 404
192
+ * route, an error fallback). Client build: a no-op — the response head was
193
+ * sent long ago.
194
+ *
195
+ * Naming note — this is a scope-tied *declaration*, not a mutation: "while
196
+ * this reactive scope is live, the response has this status." Solid
197
+ * reserves `set*` verbs for event-time mutation; like
198
+ * `createSignal`/`onCleanup` this is called in scope bodies and un-declares
199
+ * on scope disposal.
200
+ *
201
+ * Retraction semantics (server): the write snapshots the previous
202
+ * `event.response` status at write time and restores it when the owning
203
+ * scope is disposed — so a boundary that errored, declared a status, and
204
+ * then recovered retracts its write instead of stomping a status a
205
+ * surviving part of the tree legitimately set. Once the integration marks
206
+ * the response head `committed` (head derived/sent), writes and
207
+ * retractions are no-ops.
208
+ */
209
+ export declare function httpStatus(_code: number, _text?: string): void;
210
+ /**
211
+ * Declares an HTTP response header (or with `append`, appends to one) for
212
+ * the lifetime of the current reactive scope during SSR — call it bare in a
213
+ * component or reactive-scope body. Client build: a no-op — the response
214
+ * head was sent long ago.
215
+ *
216
+ * Naming note — this is a scope-tied *declaration*, not a mutation: "while
217
+ * this reactive scope is live, the response has this header." Solid
218
+ * reserves `set*` verbs for event-time mutation; like
219
+ * `createSignal`/`onCleanup` this is called in scope bodies and un-declares
220
+ * on scope disposal.
221
+ *
222
+ * Retraction semantics (server): the header's prior value is snapshotted at
223
+ * write time and restored when the owning scope is disposed (deleted if
224
+ * there was none) — a boundary that errors or recovers retracts its writes.
225
+ * Once the integration marks the response head `committed` (head
226
+ * derived/sent), writes and retractions are no-ops.
227
+ */
228
+ export declare function httpHeader(_name: string, _value: string, _options?: {
229
+ append?: boolean;
230
+ }): void;