@solidjs/web 2.0.0-beta.30 → 2.0.0-beta.32

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 (66) hide show
  1. package/README.md +1 -6
  2. package/dist/dev.cjs +284 -82
  3. package/dist/dev.js +271 -79
  4. package/dist/server.cjs +555 -135
  5. package/dist/server.js +544 -132
  6. package/dist/web.cjs +281 -79
  7. package/dist/web.js +268 -76
  8. package/frames/dist/client.cjs +413 -360
  9. package/frames/dist/client.dev.cjs +413 -360
  10. package/frames/dist/client.dev.js +414 -361
  11. package/frames/dist/client.js +414 -361
  12. package/frames/dist/server.cjs +604 -199
  13. package/frames/dist/server.js +605 -201
  14. package/package.json +56 -6
  15. package/serialization/dist/serialization.cjs +8 -0
  16. package/serialization/dist/serialization.js +1 -0
  17. package/serialization/types/index.d.ts +173 -6
  18. package/serialization/types-cjs/index.d.cts +173 -6
  19. package/server-functions/dist/client.cjs +46 -9
  20. package/server-functions/dist/client.js +47 -11
  21. package/server-functions/dist/rich-args.cjs +11 -0
  22. package/server-functions/dist/rich-args.js +9 -0
  23. package/server-functions/dist/server.cjs +275 -126
  24. package/server-functions/dist/server.dev.cjs +1053 -0
  25. package/server-functions/dist/server.dev.js +1021 -0
  26. package/server-functions/dist/server.js +273 -127
  27. package/server-functions/package.json +10 -0
  28. package/server-functions/rich-args/package.json +20 -0
  29. package/storage/types/index.d.ts +1 -1
  30. package/storage/types-cjs/index.d.cts +1 -1
  31. package/types/client.d.ts +134 -11
  32. package/types/core.d.ts +3 -1
  33. package/types/frames/client.d.ts +24 -8
  34. package/types/frames/frame-client.d.ts +49 -7
  35. package/types/frames/frame-sink.d.ts +32 -6
  36. package/types/frames/frame-transport.d.ts +88 -62
  37. package/types/frames/serializer.d.ts +173 -6
  38. package/types/frames/server.d.ts +22 -0
  39. package/types/index.d.ts +2 -3
  40. package/types/jsx.d.ts +3 -3
  41. package/types/response.d.ts +45 -0
  42. package/types/serializer.d.ts +173 -6
  43. package/types/server-functions/client.d.ts +1 -0
  44. package/types/server-functions/rich-args.d.ts +10 -0
  45. package/types/server-functions/server.d.ts +98 -0
  46. package/types/server-functions/shared.d.ts +22 -0
  47. package/types/server-mock.d.ts +171 -59
  48. package/types/server.d.ts +196 -42
  49. package/types-cjs/client.d.cts +134 -11
  50. package/types-cjs/core.d.cts +3 -1
  51. package/types-cjs/frames/client.d.cts +24 -8
  52. package/types-cjs/frames/frame-client.d.cts +49 -7
  53. package/types-cjs/frames/frame-sink.d.cts +32 -6
  54. package/types-cjs/frames/frame-transport.d.cts +88 -62
  55. package/types-cjs/frames/serializer.d.cts +173 -6
  56. package/types-cjs/frames/server.d.cts +22 -0
  57. package/types-cjs/index.d.cts +2 -3
  58. package/types-cjs/jsx.d.cts +3 -3
  59. package/types-cjs/response.d.cts +45 -0
  60. package/types-cjs/serializer.d.cts +173 -6
  61. package/types-cjs/server-functions/client.d.cts +1 -0
  62. package/types-cjs/server-functions/rich-args.d.cts +10 -0
  63. package/types-cjs/server-functions/server.d.cts +98 -0
  64. package/types-cjs/server-functions/shared.d.cts +22 -0
  65. package/types-cjs/server-mock.d.cts +171 -59
  66. package/types-cjs/server.d.cts +196 -42
@@ -1,12 +1,24 @@
1
1
  import { JSX } from "./jsx.cjs";
2
+ import type { RequestEventLocals } from "./server.cjs";
3
+ // Element/property classification tables consumed by the JSX compiler and
4
+ // custom renderers. Compiler/tooling surface; not for hand-written code.
5
+ /** Compiler/tooling table; not for hand-written code. @internal */
2
6
  export const DOMWithState: Record<string, Record<string, 1 | 2>>;
7
+ /** Compiler/tooling table; not for hand-written code. @internal */
3
8
  export const ChildProperties: Set<string>;
9
+ /** Compiler/tooling table; not for hand-written code. @internal */
4
10
  export const DelegatedEvents: Set<string>;
11
+ /** Compiler/tooling table; not for hand-written code. @internal */
5
12
  export const DOMElements: Set<string>;
13
+ /** Compiler/tooling table; not for hand-written code. @internal */
6
14
  export const SVGElements: Set<string>;
15
+ /** Compiler/tooling table; not for hand-written code. @internal */
7
16
  export const MathMLElements: Set<string>;
17
+ /** Compiler/tooling table; not for hand-written code. @internal */
8
18
  export const VoidElements: Set<string>;
19
+ /** Compiler/tooling table; not for hand-written code. @internal */
9
20
  export const RawTextElements: Set<string>;
21
+ /** Compiler/tooling table; not for hand-written code. @internal */
10
22
  export const Namespaces: Record<string, string>;
11
23
 
12
24
  type MountableElement = Element | Document | ShadowRoot | DocumentFragment | Node;
@@ -17,16 +29,30 @@ export function render(
17
29
  options?: { owner?: unknown }
18
30
  ): () => void;
19
31
  /**
32
+ * Compiler-emitted primitive; not for hand-written code.
20
33
  * @param flag
21
34
  * - `undefined` — clone the template as-is (uses `cloneNode`).
22
35
  * - `1` — use `document.importNode` instead of `cloneNode`.
23
36
  * - `2` — the template html is wrapped; the outer tag is stripped at clone time.
37
+ * @internal
24
38
  */
25
39
  export function template(html: string, flag?: 1 | 2): () => Element;
40
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
26
41
  export function scope<T extends () => any>(fn: T): T;
42
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
27
43
  export function effect<T>(fn: (prev?: T) => T, effect: (value: T, prev?: T) => void): void;
44
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
28
45
  export function memo<T>(fn: () => T, equal: boolean): () => T;
46
+ /**
47
+ * Compiler-emitted primitive; not for hand-written code — import `untrack`
48
+ * from `solid-js` instead.
49
+ * @internal
50
+ */
29
51
  export function untrack<T>(fn: () => T): T;
52
+ /**
53
+ * Compiler-emitted primitive; not for hand-written code.
54
+ * @internal
55
+ */
30
56
  export function insert<T>(
31
57
  parent: MountableElement,
32
58
  accessor: (() => T) | T,
@@ -43,20 +69,29 @@ export function insert<T>(
43
69
  schedule?: boolean;
44
70
  }
45
71
  ): JSX.Element;
72
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
46
73
  export function createComponent<T>(Comp: (props: T) => JSX.Element, props: T): JSX.Element;
74
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
47
75
  export function delegateEvents(eventNames: string[]): void;
76
+ /** Event-delegation plumbing (Portal/custom-root wiring). Integration plumbing. @internal */
48
77
  export function registerDelegatedRoot(root: MountableElement): void;
78
+ /** Event-delegation plumbing (Portal/custom-root wiring). Integration plumbing. @internal */
49
79
  export function unregisterDelegatedRoot(root: MountableElement): void;
80
+ /** Event-delegation plumbing (Portal/custom-root wiring). Integration plumbing. @internal */
50
81
  export function registerDelegatedContainer(
51
82
  container: MountableElement,
52
83
  owner?: MountableElement
53
84
  ): void;
85
+ /** Event-delegation plumbing (Portal/custom-root wiring). Integration plumbing. @internal */
54
86
  export function unregisterDelegatedContainer(
55
87
  container: MountableElement,
56
88
  owner?: MountableElement
57
89
  ): void;
90
+ /** Event-delegation plumbing (Portal/custom-root wiring). Integration plumbing. @internal */
58
91
  export function getDelegatedRoot(node: MountableElement): MountableElement | undefined;
92
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
59
93
  export function spread<T>(node: Element, accessor: T, skipChildren?: Boolean): void;
94
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
60
95
  export function assign(
61
96
  node: Element,
62
97
  props: any,
@@ -64,7 +99,9 @@ export function assign(
64
99
  prevProps?: any,
65
100
  skipRef?: Boolean
66
101
  ): void;
102
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
67
103
  export function setAttribute(node: Element, name: string, value: string): void;
104
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
68
105
  export function setAttributeNS(node: Element, namespace: string, name: string, value: string): void;
69
106
  /**
70
107
  * Register a consumer for compiler-emitted element claims. Compiled DOM
@@ -77,11 +114,16 @@ export function setAttributeNS(node: Element, namespace: string, name: string, v
77
114
  * cleanup through your own reactive system. Dormant until registered —
78
115
  * without a handler the emitted claims are null checks. Returns an
79
116
  * unregister function.
117
+ *
118
+ * Integration plumbing (routers register the consumer); not meant for
119
+ * application code.
120
+ * @internal
80
121
  */
81
122
  export function registerElementClaim(handler: (element: Element) => void): () => void;
82
123
  /**
83
124
  * Claim `node` for registered consumers (see `registerElementClaim`).
84
125
  * Emitted by the compiler at element creation; idempotent by contract.
126
+ * @internal
85
127
  */
86
128
  export function claimElement<T extends Element>(node: T): T;
87
129
  /**
@@ -90,29 +132,50 @@ export function claimElement<T extends Element>(node: T): T;
90
132
  * compiled output emits, for content that becomes live DOM without compiled
91
133
  * creation code (frame streams, adopted SSR ranges). Dormant without a
92
134
  * registered consumer.
135
+ *
136
+ * Integration plumbing; not meant for application code.
137
+ * @internal
93
138
  */
94
139
  export function claimElementTree<T extends Node>(root: T): T;
140
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
95
141
  export function className(node: Element, value: JSX.ClassValue, prev?: JSX.ClassValue): void;
142
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
96
143
  export function setProperty(node: Element, name: string, value: any): void;
144
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
97
145
  export function setStyleProperty(node: Element, name: string, value: any): void;
146
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
98
147
  export function addEvent(
99
148
  node: Element,
100
149
  name: string,
101
150
  handler: EventListener | EventListenerObject | (EventListenerObject & AddEventListenerOptions),
102
151
  delegate: boolean
103
152
  ): void;
153
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
104
154
  export function style(
105
155
  node: Element,
106
156
  value: { [k: string]: string },
107
157
  prev?: { [k: string]: string }
108
158
  ): void;
159
+ /**
160
+ * Compiler-emitted primitive; not for hand-written code — import `getOwner`
161
+ * from `solid-js` instead.
162
+ * @internal
163
+ */
109
164
  export function getOwner(): unknown;
165
+ /**
166
+ * Compiler-emitted prop-spread helper; not for hand-written code — import
167
+ * `merge` from `solid-js` instead.
168
+ * @internal
169
+ */
110
170
  export function mergeProps(...sources: unknown[]): unknown;
171
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
111
172
  export function dynamicProperty(props: unknown, key: string): unknown;
173
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
112
174
  export function applyRef<T extends Element = Element>(
113
175
  r: ((element: NoInfer<T>) => void) | ((element: NoInfer<T>) => void)[],
114
176
  element: T
115
177
  ): void;
178
+ /** Compiler-emitted primitive; not for hand-written code. @internal */
116
179
  export function ref(
117
180
  fn: () => ((element: Element) => void) | ((element: Element) => void)[],
118
181
  element: Element
@@ -123,18 +186,25 @@ export function hydrate(
123
186
  node: MountableElement,
124
187
  options?: { renderId?: string; owner?: unknown }
125
188
  ): () => void;
189
+ /** Hydration-walk primitive; not for hand-written code. @internal */
126
190
  export function getHydrationKey(): string | undefined;
191
+ /** Hydration-walk primitive; not for hand-written code. @internal */
127
192
  export function getNextElement(template?: () => Element): Element;
193
+ /** Hydration-walk primitive; not for hand-written code. @internal */
128
194
  export function getNextMatch(start: Node, elementName: string): Element;
195
+ /** Hydration-walk primitive; not for hand-written code. @internal */
129
196
  export function getNextMarker(start: Node): [Node, Array<Node>];
130
- /** @deprecated Use `useHead` — removed before `0.50.0` stable. */
131
- export function useAssets(fn: () => JSX.Element): void;
132
- /** @deprecated Use `useHead` — removed before `0.50.0` stable. */
133
- export function getAssets(): string;
134
197
  /**
135
198
  * A head tag descriptor. Props values may be getters (reactive on the
136
199
  * client); `children` is the text body. `key` overrides the built-in dedupe
137
200
  * identity (`title` is a hard singleton that `key` cannot fork).
201
+ *
202
+ * Getters must be plain reads: they evaluate inside registry-owned
203
+ * computations here and at flush time on the server, so a getter that
204
+ * allocates a reactive owner (`createMemo`, a `children()` helper) consumes
205
+ * a hydration id slot on one side only and desyncs every id allocated after
206
+ * the `useHead` call. Create such helpers eagerly at component position and
207
+ * read them from the getter. See docs/head-management-rfc.md.
138
208
  */
139
209
  export type HeadTag = {
140
210
  tag: "title" | "meta" | "link" | "style" | "script" | "base";
@@ -143,12 +213,14 @@ export type HeadTag = {
143
213
  };
144
214
  /**
145
215
  * Registers head tags with the ambient head registry under the current
146
- * owner. An array is a group — one replacement set. Resolution is
147
- * last-committed group per identity; disposal restores the previous winner.
148
- * During hydration the server-flushed head state stays authoritative until
149
- * hydration completes. See docs/head-management-rfc.md.
216
+ * owner. An array is a group — one replacement set; a function is a
217
+ * reactive group whose membership is tracked and re-read on change.
218
+ * Resolution is last-committed group per identity (reactive updates keep
219
+ * the registration's original commit position); disposal restores the
220
+ * previous winner. During hydration the server-flushed head state stays
221
+ * authoritative until hydration completes. See docs/head-management-rfc.md.
150
222
  */
151
- export function useHead(tag: HeadTag | HeadTag[]): void;
223
+ export function useHead(tag: HeadTag | HeadTag[] | (() => HeadTag | HeadTag[])): void;
152
224
  export type AssetDescriptor =
153
225
  | { type: "style"; href: string; attrs?: Record<string, string> }
154
226
  | { type: "inline-style"; id: string; content?: string; attrs?: Record<string, string> }
@@ -161,13 +233,41 @@ export interface ExclusiveAssetDescriptor<T> {
161
233
  get(): T;
162
234
  set(value: T): void;
163
235
  }
236
+ /**
237
+ * @internal Ref-counted client asset ownership: acquire adopts or mounts the
238
+ * asset, the returned release follows the owner (with a grace period for
239
+ * back-and-forth navigation). Internal machinery, not a public CSS-lifecycle
240
+ * API — per the head-management RFC (docs/head-management-rfc.md), ambient
241
+ * bundler-injected CSS is never lifecycle-managed, and the head registry
242
+ * owns the lifecycle of directly-mounted stylesheets outright. This keeps
243
+ * its non-head roles (exclusive slots, owner-following DOM ownership).
244
+ */
164
245
  export function acquireAsset(descriptor: AssetDescriptor): () => void;
246
+ /**
247
+ * Registry entry returned by `warmAsset`. Stylesheet entries carry load
248
+ * tracking for the client reveal gate (docs/client-css-reveal-gating.md):
249
+ * `loadPromise` resolves on load OR error (never rejects) — an errored
250
+ * sheet releases the gate, parity with the server gate.
251
+ */
252
+ export interface AssetEntry {
253
+ loadState?: "pending" | "loaded" | "errored";
254
+ loadPromise?: Promise<void>;
255
+ }
256
+ /**
257
+ * @internal Warm half of `acquireAsset`: idempotent and refcount-free,
258
+ * callable from a compute phase so the fetch starts at discovery and
259
+ * overlaps a transition's data wait. Stylesheets warm as
260
+ * `rel="preload" as="style"` and are flipped live by `acquireAsset` at
261
+ * commit — a branch superseded before it commits leaks only an inert
262
+ * preload, never an applied sheet. Only link-backed descriptors warm;
263
+ * inline styles and exclusive slots return `undefined`.
264
+ */
265
+ export function warmAsset(descriptor: AssetDescriptor): AssetEntry | undefined;
165
266
  export function HydrationScript(props?: { nonce?: string; eventNames?: string[] }): JSX.Element;
166
267
  export function generateHydrationScript(options?: {
167
268
  nonce?: string;
168
269
  eventNames?: string[];
169
270
  }): string;
170
- export function Assets(props: { children?: JSX.Element }): JSX.Element;
171
271
  /**
172
272
  * See the server entry's `ResponseStub` — the shape of the mutable response
173
273
  * head integrations expose as `event.response` via module augmentation.
@@ -183,10 +283,33 @@ export interface ResponseStub {
183
283
  */
184
284
  committed?: boolean;
185
285
  }
286
+ /**
287
+ * See the server entry's `RequestEventLocals` — the augmentable type of
288
+ * `RequestEvent.locals`. Re-exported (not re-declared) so both entries
289
+ * share ONE interface identity and a single augmentation reaches every
290
+ * `locals`, whichever entry typed the event.
291
+ */
292
+ export type { RequestEventLocals } from "./server.cjs";
186
293
  export interface RequestEvent {
187
294
  request: Request;
188
- locals: Record<string | number | symbol, any>;
295
+ locals: RequestEventLocals;
189
296
  }
297
+ /**
298
+ * Registered symbol (`Symbol.for("solid.RequestContext")`) naming the global
299
+ * slot where `provideRequestEvent` parks the AsyncLocalStorage scoping
300
+ * request events. Integration plumbing — read the event through
301
+ * `getRequestEvent()` instead.
302
+ * @internal
303
+ */
190
304
  export declare const RequestContext: unique symbol;
191
305
  export function getRequestEvent(): RequestEvent | undefined;
306
+ /**
307
+ * The cookie codec (the platform-gap primitives — see cookies.d.ts for the
308
+ * blessed patterns): the real implementation on both entries, never a
309
+ * stub — a pure value transformer has legitimate browser uses
310
+ * (`document.cookie`). Tree-shakes away when unused.
311
+ */
312
+ export { parseCookieHeader, serializeCookie } from "./cookies.cjs";
313
+ export type { CookieOptions } from "./cookies.cjs";
314
+ /** Hydration-walk primitive; not for hand-written code. @internal */
192
315
  export function runHydrationEvents(): void;
@@ -1,4 +1,6 @@
1
1
  export { getOwner, runWithOwner, createComponent, createRoot as root, sharedConfig, untrack, merge as mergeProps, flatten, ssrHandleError, ssrScope, NoHydration, Hydration, runInServerComponentScope } from "solid-js";
2
- export declare const effect: (fn: any, effectFn: any, options: any) => void;
2
+ export declare const effect: (fn: any, effectFn: any, options?: any) => void;
3
3
  export declare const memo: (fn: any) => import("solid-js").SourceAccessor<any>;
4
4
  export declare const runWithHydrationScope: (id: any, fn: any) => unknown;
5
+ export declare const ssrAsyncValue: (value: any) => import("solid-js").SourceAccessor<any>;
6
+ export declare const waitAsset: (promise: any) => void;
@@ -1,20 +1,36 @@
1
1
  export { createFrame, createFrameHost, createFrameElement, FRAME_APPLIED_EVENT } from "./frame-client.cjs";
2
2
  export { FRAME_STREAM_HEADER, applyFrameResponse, isFrameStreamResponse, createServerComponentHandler } from "./frame-transport.cjs";
3
- export { createJSONDataTable } from "./serializer.cjs";
4
3
  export type { Slot } from "./server.cjs";
4
+ /**
5
+ * Client-condition twin of the server face's `asyncArg` (DR-2 value tier):
6
+ * the identity that types an async value crossing the slot border as its
7
+ * settled value. Server component modules are authored in universal code and
8
+ * may resolve under the browser condition at typecheck/bundle time — the
9
+ * call never runs here (the `"use server"` body executes server-side), but
10
+ * the symbol must exist.
11
+ */
12
+ export declare function asyncArg<T>(value: PromiseLike<T> | AsyncIterable<T>): T;
13
+ /**
14
+ * The app-wide shared frame host (created lazily): one chunk router with
15
+ * per-response codec data tables.
16
+ * @experimental
17
+ */
5
18
  export declare function getFrameHost(): any;
6
19
  /**
7
20
  * Installs the server-component transport policy on the server-function
8
- * client: boundary identity is the call's intrinsic (function, arguments)
9
- * address — per-args, exactly like the query cache, so a cached component
10
- * always mounts the boundary showing the call it was cached for. Repeat
11
- * calls for the same args resolve the identical component (refetches morph
12
- * in place, cache hits pass `dynamic`'s equals-gate); a source switching
13
- * args swaps boundaries, re-materialized instantly from the host's
14
- * retained state.
21
+ * client the identity split (DR-1): CONTENT is keyed by the call's
22
+ * intrinsic (function, arguments) address — per-args, exactly like the
23
+ * query cache, so a cached resolution always names the content it was
24
+ * cached for — while the MOUNT belongs to the call site. Every call of a
25
+ * function resolves a binding wrapping the same per-function component
26
+ * (the document placeholder), so `dynamic` keeps its instance across both
27
+ * refetches AND argument changes; the instance follows delivered addresses
28
+ * by re-binding its frame's pull, and a preload for unshown args only ever
29
+ * warms that address's resident store.
15
30
  *
16
31
  * Call once in the client entry (an explicit call — the package is
17
32
  * `sideEffects: false`, so a bare import would be tree-shaken away);
18
33
  * call again to rebind to a custom host.
34
+ * @experimental
19
35
  */
20
36
  export declare function installServerComponents(host?: any): void;
@@ -6,9 +6,17 @@
6
6
  * inside the boundary are preserved across server updates — the
7
7
  * version is a stale-guard only ("policy A"): newer content morphs in
8
8
  * place, and teardown is `dispose()`, never a version bump.
9
+ *
10
+ * EXPERIMENTAL — the frames/server-components surface ships as an
11
+ * experimental preview, excluded from the 2.0 stability guarantee: API
12
+ * shapes and the wire format may change between prereleases (RFC 11).
13
+ * Every export in this module is `@experimental`.
9
14
  */
10
15
 
11
- /** One transport chunk of a frame stream, addressed by frame `id`. */
16
+ /**
17
+ * One transport chunk of a frame stream, addressed by frame `id`.
18
+ * @experimental
19
+ */
12
20
  export type FrameChunk =
13
21
  | { type: "start"; id: string; version: number }
14
22
  | { type: "html"; id: string; version: number; html: string }
@@ -48,6 +56,7 @@ export type FrameChunk =
48
56
  * Maps a wire chunk onto resident-store record writes. `data` chunks map to
49
57
  * no records — they are response-scoped and the host applies them through
50
58
  * its data hook.
59
+ * @experimental
51
60
  */
52
61
  export function chunkToRecords(chunk: FrameChunk): Record<string, unknown>;
53
62
 
@@ -55,13 +64,17 @@ export function chunkToRecords(chunk: FrameChunk): Record<string, unknown>;
55
64
  * One store write applied to a frame: `r` maps record keys to values
56
65
  * (`chunkToRecords` produces these from wire chunks) and `version` is the
57
66
  * stream stamp — an older version than the frame's current one is ignored.
67
+ * @experimental
58
68
  */
59
69
  export interface FrameWrite {
60
70
  version: number;
61
71
  r: Record<string, unknown>;
62
72
  }
63
73
 
64
- /** Context passed to a slot callback. */
74
+ /**
75
+ * Context passed to a slot callback.
76
+ * @experimental
77
+ */
65
78
  export interface SlotContext {
66
79
  /**
67
80
  * True only for the hydration-attach invocation of an adopted
@@ -117,9 +130,11 @@ export interface SlotContext {
117
130
  * resolved args (primitives literal, `{$ref}` data resolved through the
118
131
  * host, `{$frame}` regions as marker-range fragments). Return nodes to fill
119
132
  * the range, or `undefined` to claim `ctx.existing` untouched.
133
+ * @experimental
120
134
  */
121
135
  export type Slot = (props: Record<string, unknown>, ctx: SlotContext) => Node | Node[] | undefined;
122
136
 
137
+ /** @experimental */
123
138
  export interface Frame {
124
139
  /** Merge a write into the store and flush (morph/reveal/slot sync). */
125
140
  apply(write: FrameWrite): void;
@@ -159,6 +174,7 @@ export interface Frame {
159
174
  * An id may have several frames (the same server component mounted more
160
175
  * than once): chunks fan out to all of them, and a frame registering after
161
176
  * delivery is seeded from a sibling's store.
177
+ * @experimental
162
178
  */
163
179
  export interface FrameHost {
164
180
  register(id: string, frame: Frame): void;
@@ -180,10 +196,14 @@ export interface FrameHost {
180
196
  * boundary (nested region frames dispatch too); use it to re-apply
181
197
  * client-owned decorations on server-owned markup (router affordance
182
198
  * reflection, e.g. `aria-current`) without a MutationObserver.
199
+ * @experimental
183
200
  */
184
201
  export const FRAME_APPLIED_EVENT: "frame:applied";
185
202
 
186
- /** Options for `createFrameHost`. */
203
+ /**
204
+ * Options for `createFrameHost`.
205
+ * @experimental
206
+ */
187
207
  export interface FrameHostOptions {
188
208
  /**
189
209
  * Backs `{$ref}` slot args (typically a codec data table's `resolve`).
@@ -201,9 +221,13 @@ export interface FrameHostOptions {
201
221
  applyData?(chunk: Extract<FrameChunk, { type: "data" }>): void;
202
222
  }
203
223
 
224
+ /** @experimental */
204
225
  export function createFrameHost(options?: FrameHostOptions): FrameHost;
205
226
 
206
- /** Options for `createFrame` / `createFrameElement`. */
227
+ /**
228
+ * Options for `createFrame` / `createFrameElement`.
229
+ * @experimental
230
+ */
207
231
  export interface FrameOptions {
208
232
  /** Register with this host under `id`, receiving routed/buffered chunks. */
209
233
  host?: FrameHost;
@@ -217,7 +241,7 @@ export interface FrameOptions {
217
241
  */
218
242
  adopt?: boolean;
219
243
  /** Called after each apply flush (tests/telemetry). */
220
- onApply?(info: { version: number; reason: "materialize" | "morph" | "reveal" }): void;
244
+ onApply?(info: { version: number; reason: "materialize" | "morph" | "reveal" | "error" }): void;
221
245
  /**
222
246
  * Wraps element-claim sweeps (`a[href]`/`form[action]` in materialized
223
247
  * server content — and only those) so claim consumers register their
@@ -239,6 +263,18 @@ export interface FrameOptions {
239
263
  * for the framework-agnostic imperative swap (no reactive reveal).
240
264
  */
241
265
  reveal?(seam: { before: Node; fallback: Node[]; content: () => Node | DocumentFragment }): void;
266
+ /**
267
+ * Document-face record-race guard (adopt path only — solidjs/solid#2968).
268
+ * Nothing on the wire formally orders an occurrence's args-record data
269
+ * script before the event that triggers adoption, so a recordless
270
+ * occurrence is ambiguous while this returns true: the frame defers its
271
+ * mount one macrotask (all currently parsed scripts run first), calls
272
+ * `drainRecords`, and classifies with whatever is then resolvable. Return
273
+ * false once the document can run no further data scripts.
274
+ */
275
+ recordsPending?(): boolean;
276
+ /** Re-absorb the document's arrived-by-now records (idempotent per key). */
277
+ drainRecords?(): void;
242
278
  }
243
279
 
244
280
  /**
@@ -247,12 +283,17 @@ export interface FrameOptions {
247
283
  * so the first apply morphs against it and slots sync immediately (hydration
248
284
  * attach), claiming their server-rendered DOM — a document boot needs no
249
285
  * chunk.
286
+ * @experimental
250
287
  */
251
288
  export function createFrame(boundary: Element, options?: FrameOptions): Frame;
252
289
 
253
- /** The default boundary/region element tag and its id attribute — the DOM
254
- * contract the producer emits at t=0 and the consumer creates/adopts. */
290
+ /**
291
+ * The default boundary/region element tag and its id attribute — the DOM
292
+ * contract the producer emits at t=0 and the consumer creates/adopts.
293
+ * @experimental
294
+ */
255
295
  export const FRAME_TAG: "dx-frame";
296
+ /** @experimental */
256
297
  export const FRAME_ID_ATTR: "data-fid";
257
298
 
258
299
  /**
@@ -262,6 +303,7 @@ export const FRAME_ID_ATTR: "data-fid";
262
303
  * returned `element` in any position — single, array, or fragment — with no
263
304
  * special-casing. One frame per element; lifecycle belongs to the creator via
264
305
  * `dispose()` (register it with your owner's cleanup).
306
+ * @experimental
265
307
  */
266
308
  export function createFrameElement(options: FrameOptions): {
267
309
  readonly element: Element;
@@ -1,6 +1,13 @@
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.
1
5
  import { FrameChunk } from "./frame-client.cjs";
2
6
 
3
- /** Addresses a frame stream: the boundary id and this response's version. */
7
+ /**
8
+ * Addresses a frame stream: the boundary id and this response's version.
9
+ * @experimental
10
+ */
4
11
  export interface FrameAddress {
5
12
  id: string;
6
13
  version: number;
@@ -12,13 +19,17 @@ export interface FrameAddress {
12
19
  * method emits transport-agnostic chunks; `emit` is the envelope boundary.
13
20
  * @internal Compiler/renderer wiring — use `renderToFrameStream` or
14
21
  * `renderServerComponent` instead.
22
+ * @experimental
15
23
  */
16
24
  export function createFrameSink(
17
25
  emit: (chunk: FrameChunk) => void,
18
26
  frame: FrameAddress
19
27
  ): Record<string, (...args: any[]) => void>;
20
28
 
21
- /** Options shared by the frame producers. */
29
+ /**
30
+ * Options shared by the frame producers.
31
+ * @experimental
32
+ */
22
33
  export interface FrameStreamOptions {
23
34
  /** Boundary address; defaults to `{ id: "", version: 1 }`. */
24
35
  frame?: { id?: string; version?: number };
@@ -26,7 +37,10 @@ export interface FrameStreamOptions {
26
37
  [key: string]: unknown;
27
38
  }
28
39
 
29
- /** A produced frame stream: pipe chunks, or await the collected array. */
40
+ /**
41
+ * A produced frame stream: pipe chunks, or await the collected array.
42
+ * @experimental
43
+ */
30
44
  export interface FrameStream extends PromiseLike<FrameChunk[]> {
31
45
  pipe(writable: { write(chunk: FrameChunk): void; end?(): void }): void;
32
46
  }
@@ -37,6 +51,7 @@ export interface FrameStream extends PromiseLike<FrameChunk[]> {
37
51
  * by a chunk envelope (`start` up front, `complete` at stream end). Data
38
52
  * records default to the keyed JSON codec (decode with
39
53
  * `createJSONDataTable`).
54
+ * @experimental
40
55
  */
41
56
  export function renderToFrameStream(code: () => unknown, options?: FrameStreamOptions): FrameStream;
42
57
 
@@ -57,6 +72,7 @@ export function renderToFrameStream(code: () => unknown, options?: FrameStreamOp
57
72
  *
58
73
  * The props a *client* passes never reach the server — server inputs are the
59
74
  * function's arguments.
75
+ * @experimental
60
76
  */
61
77
  export function renderServerComponent(
62
78
  component: (props: Record<string, any>) => unknown,
@@ -70,6 +86,7 @@ export function renderServerComponent(
70
86
  * the live render context, so it must only be used during the frame's
71
87
  * render.
72
88
  * @internal Exposed for framework bindings composing their own producers.
89
+ * @experimental
73
90
  */
74
91
  export function createSlotProps(
75
92
  sink: ReturnType<typeof createFrameSink>,
@@ -82,6 +99,7 @@ export function createSlotProps(
82
99
  * the client and `X-Content-Raw` so the server-function handler forwards it
83
100
  * untouched. `init` (headers/status, e.g. from a `respond()` envelope)
84
101
  * merges in; the frame tags win on conflict.
102
+ * @experimental
85
103
  */
86
104
  export function serverComponentResponse(
87
105
  component: (props: Record<string, any>) => unknown,
@@ -103,6 +121,7 @@ export function serverComponentResponse(
103
121
  * provideEvent
104
122
  * });
105
123
  * ```
124
+ * @experimental
106
125
  */
107
126
  export function frameTransformResult(event: unknown, result: unknown): unknown;
108
127
 
@@ -115,6 +134,7 @@ export function frameTransformResult(event: unknown, result: unknown): unknown;
115
134
  * positions (the one hydration-time exception), wrapped in the same marker
116
135
  * dialect the chunk producer emits so the adopting client binds slots and
117
136
  * regions onto the server-rendered ranges.
137
+ * @experimental
118
138
  */
119
139
  export function createDocumentSlotProps(
120
140
  clientProps: Record<string, unknown>,
@@ -128,6 +148,7 @@ export function createDocumentSlotProps(
128
148
  * as an inline-renderable server component (frame markers + document
129
149
  * slot props), branded with its function id and the call's wire address.
130
150
  * Non-function results pass through.
151
+ * @experimental
131
152
  */
132
153
  export function frameTransformDirectResult<T>(
133
154
  value: T,
@@ -143,6 +164,7 @@ export function frameTransformDirectResult<T>(
143
164
  * component entries serialized as flight references. Returns `undefined`
144
165
  * when nothing invalidated is markup (the response stays the plain
145
166
  * single-flight envelope).
167
+ * @experimental
146
168
  */
147
169
  export function frameTransformFlightResult(
148
170
  event: unknown,
@@ -161,8 +183,12 @@ export {
161
183
  } from "./frame-transport.cjs";
162
184
 
163
185
  /**
164
- * Inline bootstrap for the document shell: installs the `self._$SC`
165
- * placeholder registry the hydration references resolve through; the client
166
- * upgrades it via `installServerComponents()`.
186
+ * Statement form of the `self._$SC` placeholder-registry bootstrap
187
+ * (idempotent first definition wins). No longer required in the document
188
+ * shell: each hydration script's first serialized server-component reference
189
+ * self-bootstraps the registry. Kept for integrations still installing it
190
+ * document-wide; the client upgrades the registry via
191
+ * `installServerComponents()`.
192
+ * @experimental
167
193
  */
168
194
  export const SERVER_COMPONENT_BOOTSTRAP: string;