@solidjs/web 2.0.0-beta.7 → 2.0.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/web.js CHANGED
@@ -1,6 +1,5 @@
1
- import { createRenderEffect, createMemo as createMemo$1, sharedConfig, untrack, runWithOwner, flatten, createRoot, omit, enableHydration } from 'solid-js';
1
+ import { createRenderEffect, createMemo, sharedConfig, untrack, runWithOwner, flatten, createRoot, createComponent, omit, enableHydration, flush } from 'solid-js';
2
2
  export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Reveal, Show, Switch, createComponent, getOwner, merge as mergeProps, untrack } from 'solid-js';
3
- import { createMemo } from '@solidjs/signals';
4
3
 
5
4
  const DOMWithState = {
6
5
  INPUT: {
@@ -44,16 +43,20 @@ const Namespaces = {
44
43
  xlink: "http://www.w3.org/1999/xlink",
45
44
  xml: "http://www.w3.org/XML/1998/namespace"
46
45
  };
46
+ const VoidElements = /*#__PURE__*/new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
47
+ const RawTextElements = /*#__PURE__*/new Set(["style", "script", "noscript", "template", "textarea", "title"]);
47
48
  const DOMElements = /*#__PURE__*/new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input", "h1", "h2", "h3", "h4", "h5", "h6",
48
49
  "webview",
49
50
  "isindex", "listing", "multicol", "nextid", "noindex", "search"]);
50
51
 
51
- const effect = (fn, effectFn) => createRenderEffect(fn, effectFn, {
52
+ const transparentOptions = {
52
53
  transparent: true
53
- });
54
- const memo = (fn, transparent) => transparent ? fn.$r ? fn : createMemo(() => fn(), {
55
- transparent: true
56
- }) : createMemo$1(() => fn());
54
+ };
55
+ const effect = (fn, effectFn, options) => createRenderEffect(fn, effectFn, options ? {
56
+ transparent: true,
57
+ ...options
58
+ } : transparentOptions);
59
+ const memo = fn => createMemo(() => fn());
57
60
 
58
61
  function reconcileArrays(parentNode, a, b) {
59
62
  let bLength = b.length,
@@ -113,12 +116,18 @@ function reconcileArrays(parentNode, a, b) {
113
116
  }
114
117
 
115
118
  const $$EVENTS = "_$DX_DELEGATE";
119
+ const INNER_OWNED = {};
116
120
  function render$1(code, element, init, options = {}) {
117
121
  const renderRoot = getChildRoot(element);
118
122
  let disposer;
119
123
  createRoot(dispose => {
120
124
  disposer = dispose;
121
- element === document ? flatten(code) : insert(element, code(), renderRoot.firstChild ? null : undefined, init);
125
+ if (element === document) {
126
+ flatten(code);
127
+ } else {
128
+ const tree = code();
129
+ insert(element, () => tree, renderRoot.firstChild ? null : undefined, init, options.insertOptions);
130
+ }
122
131
  }, {
123
132
  id: options.renderId
124
133
  });
@@ -163,7 +172,7 @@ function setAttribute(node, name, value) {
163
172
  }
164
173
  function setAttributeNS(node, namespace, name, value) {
165
174
  if (isHydrating(node)) return;
166
- if (value == null || value === false) node.removeAttributeNS(namespace, name);else node.setAttributeNS(namespace, name, value === true ? "" : value);
175
+ if (value == null || value === false) node.removeAttributeNS(namespace, name.indexOf(":") > -1 ? name.split(":").pop() : name);else node.setAttributeNS(namespace, name, value === true ? "" : value);
167
176
  }
168
177
  function className(node, value, prev) {
169
178
  if (isHydrating(node)) return;
@@ -215,7 +224,6 @@ function style(node, value, prev) {
215
224
  if (typeof value === "string") return nodeStyle.cssText = value;
216
225
  typeof prev === "string" && (nodeStyle.cssText = prev = undefined);
217
226
  prev || (prev = {});
218
- value || (value = {});
219
227
  let v, s;
220
228
  for (s in value) {
221
229
  v = value[s];
@@ -261,7 +269,7 @@ function ref(fn, element) {
261
269
  const resolved = untrack(fn);
262
270
  runWithOwner(null, () => applyRef(resolved, element));
263
271
  }
264
- function insert(parent, accessor, marker, initial) {
272
+ function insert(parent, accessor, marker, initial, options) {
265
273
  const childRoot = getChildRoot(parent);
266
274
  const multi = marker !== undefined;
267
275
  if (multi && !initial) initial = [];
@@ -279,13 +287,25 @@ function insert(parent, accessor, marker, initial) {
279
287
  accessor = normalize(accessor, initial, multi, true);
280
288
  if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker);
281
289
  }
282
- accessor = memo(accessor, true);
283
290
  if (multi && initial.length === 0) {
284
291
  const placeholder = document.createTextNode("");
285
292
  childRoot.insertBefore(placeholder, marker);
286
293
  initial = [placeholder];
287
294
  }
288
- effect((prev = initial) => normalize(accessor, prev, multi), (value, current = initial) => insertExpression(parent, value, current, marker));
295
+ let current = initial;
296
+ effect(() => {
297
+ const value = normalize(accessor(), current, multi, true);
298
+ if (typeof value !== "function") return value;
299
+ effect(() => normalize(value, current, multi), inner => {
300
+ insertExpression(parent, inner, current, marker);
301
+ current = inner;
302
+ }, options);
303
+ return INNER_OWNED;
304
+ }, value => {
305
+ if (value === INNER_OWNED) return;
306
+ insertExpression(parent, value, current, marker);
307
+ current = value;
308
+ }, options);
289
309
  }
290
310
  function assign(node, props, skipChildren, prevProps = {}, skipRef = false) {
291
311
  const nodeName = node.nodeName;
@@ -653,16 +673,20 @@ function ssrHydrationKey() {}
653
673
  function resolveSSRNode(node) {}
654
674
  function escape(html) {}
655
675
 
656
- function render(...args) {
657
- const result = render$1(...args);
658
- return result;
659
- }
660
676
  const isServer = false;
661
677
  const isDev = false;
662
- function createElement(tagName, is = undefined) {
663
- return SVGElements.has(tagName) ? document.createElementNS(Namespaces.svg, tagName) : MathMLElements.has(tagName) ? document.createElementNS(Namespaces.mathml, tagName) : document.createElement(tagName, {
664
- is
665
- });
678
+ function render(code, element, init, options = {}) {
679
+ try {
680
+ const dispose = render$1(code, element, init, {
681
+ ...options,
682
+ insertOptions: {
683
+ schedule: true
684
+ }
685
+ });
686
+ flush();
687
+ return dispose;
688
+ } finally {
689
+ }
666
690
  }
667
691
  const hydrate = (...args) => {
668
692
  enableHydration();
@@ -673,7 +697,7 @@ function Portal(props) {
673
697
  startMarker = document.createTextNode(""),
674
698
  endMarker = document.createTextNode(""),
675
699
  mount = () => createElementProxy(props.mount || document.body, treeMarker);
676
- let content = createMemo$1(() => [startMarker, props.children]);
700
+ let content = createMemo(() => [startMarker, props.children]);
677
701
  createRenderEffect(() => [mount(), content()], ([m, c]) => {
678
702
  m.appendChild(endMarker);
679
703
  insert(m, c, endMarker);
@@ -688,6 +712,33 @@ function Portal(props) {
688
712
  });
689
713
  return treeMarker;
690
714
  }
715
+ function dynamic(source) {
716
+ const cached = createMemo(source, {
717
+ lazy: true
718
+ });
719
+ return props => {
720
+ return createMemo(() => {
721
+ const component = cached();
722
+ switch (typeof component) {
723
+ case "function":
724
+ return untrack(() => component(props));
725
+ case "string":
726
+ const el = sharedConfig.hydrating ? getNextElement() : createElement(component, untrack(() => props.is));
727
+ spread(el, props);
728
+ return el;
729
+ }
730
+ });
731
+ };
732
+ }
733
+ function Dynamic(props) {
734
+ const Comp = dynamic(() => props.component);
735
+ return createComponent(Comp, omit(props, "component"));
736
+ }
737
+ function createElement(tagName, is = undefined) {
738
+ return SVGElements.has(tagName) ? document.createElementNS(Namespaces.svg, tagName) : MathMLElements.has(tagName) ? document.createElementNS(Namespaces.mathml, tagName) : document.createElement(tagName, {
739
+ is
740
+ });
741
+ }
691
742
  function createElementProxy(el, marker) {
692
743
  return new Proxy(el, {
693
744
  get(target, prop) {
@@ -705,23 +756,5 @@ function createElementProxy(el, marker) {
705
756
  }
706
757
  });
707
758
  }
708
- function createDynamic(component, props) {
709
- const cached = createMemo$1(component);
710
- return createMemo$1(() => {
711
- const component = cached();
712
- switch (typeof component) {
713
- case "function":
714
- return untrack(() => component(props));
715
- case "string":
716
- const el = sharedConfig.hydrating ? getNextElement() : createElement(component, untrack(() => props.is));
717
- spread(el, props);
718
- return el;
719
- }
720
- });
721
- }
722
- function Dynamic(props) {
723
- const others = omit(props, "component");
724
- return createDynamic(() => props.component, others);
725
- }
726
759
 
727
- export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RequestContext, SVGElements, addEventListener, applyRef, assign, className, clearDelegatedEvents, createDynamic, delegateEvents, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, isDev, isServer, memo, ref, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, voidFn as useAssets };
760
+ export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, addEventListener, applyRef, assign, className, clearDelegatedEvents, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, isDev, isServer, memo, ref, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, voidFn as useAssets };
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@solidjs/web",
3
- "description": "Solid's web runtime for the browser and the server",
4
- "version": "2.0.0-beta.7",
3
+ "description": "Solid's web runtime: client rendering, hydration, SSR, and DOM-specific control flow (Portal, Dynamic).",
4
+ "version": "2.0.0-beta.9",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/solidjs/solid-web"
10
+ "url": "git+https://github.com/solidjs/solid.git",
11
+ "directory": "packages/solid-web"
11
12
  },
12
13
  "publishConfig": {
13
14
  "access": "public"
@@ -116,12 +117,10 @@
116
117
  "seroval-plugins": "^1.1.0"
117
118
  },
118
119
  "peerDependencies": {
119
- "@solidjs/signals": "^2.0.0-beta.7",
120
- "solid-js": "^2.0.0-beta.7"
120
+ "solid-js": "^2.0.0-beta.9"
121
121
  },
122
122
  "devDependencies": {
123
- "@solidjs/signals": "2.0.0-beta.7",
124
- "solid-js": "2.0.0-beta.7"
123
+ "solid-js": "2.0.0-beta.9"
125
124
  },
126
125
  "scripts": {
127
126
  "build": "npm-run-all -nl build:*",
@@ -1,16 +1,78 @@
1
- import { hydrate as hydrateCore, render as renderCore } from "./client.js";
2
- import { JSX, ComponentProps, ValidComponent } from "solid-js";
1
+ import { hydrate as hydrateCore } from "./client.js";
2
+ import { JSX, Component, ComponentProps, ValidComponent } from "solid-js";
3
3
  export * from "./client.js";
4
- export declare function render(...args: Parameters<typeof renderCore>): ReturnType<typeof renderCore>;
5
- export { For, Show, Switch, Match, Errored, Loading, Repeat, Reveal, NoHydration, Hydration, merge as mergeProps } from "solid-js";
6
4
  export * from "./server-mock.js";
5
+ export { For, Show, Switch, Match, Errored, Loading, Repeat, Reveal, NoHydration, Hydration, merge as mergeProps } from "solid-js";
7
6
  export declare const isServer: boolean;
8
7
  export declare const isDev: boolean;
8
+ type MountableElement = Element | Document | ShadowRoot | DocumentFragment | Node;
9
+ export type DynamicProps<T extends ValidComponent, P = ComponentProps<T>> = {
10
+ [K in keyof P]: P[K];
11
+ } & {
12
+ component: T | null | undefined | false;
13
+ };
14
+ /**
15
+ * Renders a component tree into a DOM element. Returns a dispose function
16
+ * that tears the tree down and cleans up reactive scopes when called.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { render } from "@solidjs/web";
21
+ *
22
+ * const dispose = render(() => <App />, document.getElementById("root")!);
23
+ *
24
+ * // Later, to unmount:
25
+ * dispose();
26
+ * ```
27
+ *
28
+ * @remarks
29
+ * The top-level insert is queued via `insertOptions: { schedule: true }` so
30
+ * its initial DOM attach goes through the effect queue rather than executing
31
+ * inline. This lets the mount participate in transitions: if an uncaught
32
+ * async read surfaces during the initial render (no `Loading` ancestor
33
+ * absorbs it), the mount is held by the transition and attaches atomically
34
+ * once all pending settles. On the no-async happy path the tail `flush()`
35
+ * drains the queued callback so the attach is synchronous by the time
36
+ * `render()` returns. The dev enforcement window scopes
37
+ * `ASYNC_OUTSIDE_LOADING_BOUNDARY` to the initial mount only.
38
+ */
39
+ export declare function render(code: () => JSX.Element, element: MountableElement, init?: unknown, options?: {
40
+ renderId?: string;
41
+ }): () => void;
42
+ /**
43
+ * Resumes a server-rendered tree on the client, attaching event listeners
44
+ * and reactive bindings without reconstructing the DOM. Returns a `dispose`
45
+ * function that tears down reactive scopes (DOM nodes are left in place).
46
+ *
47
+ * Use this when the page HTML was produced by `renderToString`,
48
+ * `renderToStringAsync`, or `renderToStream`. For client-only apps, use
49
+ * `render` instead.
50
+ *
51
+ * Pass `options.renderId` to hydrate one of multiple roots emitted by a
52
+ * server render that used the same id.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * import { hydrate } from "@solidjs/web";
57
+ *
58
+ * hydrate(() => <App />, document.getElementById("root")!);
59
+ * ```
60
+ */
9
61
  export declare const hydrate: typeof hydrateCore;
10
62
  /**
11
- * Renders components somewhere else in the DOM
63
+ * Renders its children into a different part of the DOM (modal roots,
64
+ * tooltips, layers that need to escape an `overflow: hidden` ancestor).
65
+ *
66
+ * If `mount` is omitted, the portal attaches to `document.body`. The portal
67
+ * still participates in the parent's reactive scope and disposes when the
68
+ * parent does.
12
69
  *
13
- * Useful for inserting modals and tooltips outside of an cropping layout. If no mount point is given, the portal is inserted in document.body; it is wrapped in a `<div>` unless the target is document.head or `isSVG` is true. setting `useShadow` to true places the element in a shadow root to isolate styles.
70
+ * @example
71
+ * ```tsx
72
+ * <Portal mount={document.getElementById("modal-root")!}>
73
+ * <Dialog />
74
+ * </Portal>
75
+ * ```
14
76
  *
15
77
  * @description https://docs.solidjs.com/reference/components/portal
16
78
  */
@@ -18,24 +80,25 @@ export declare function Portal<T extends boolean = false, S extends boolean = fa
18
80
  mount?: Element;
19
81
  children: JSX.Element;
20
82
  }): Text;
21
- export type DynamicProps<T extends ValidComponent, P = ComponentProps<T>> = {
22
- [K in keyof P]: P[K];
23
- } & {
24
- component: T | undefined;
25
- };
26
83
  /**
27
- * Renders an arbitrary component or element with the given props
84
+ * Returns a stable `Component` whose identity is driven by a reactive (and
85
+ * optionally async) `source`. The returned component can be used anywhere a
86
+ * normal component is used; children and props flow through JSX as usual.
87
+ *
88
+ * `source` may return a component, a native tag name (`'input'`, `'textarea'`,
89
+ * etc.), `undefined`, or a `Promise` of any of the above. A pending promise
90
+ * propagates as `NotReadyError` through the surrounding reactive scope, so
91
+ * async swaps compose with `Loading`/Suspense boundaries the same way as
92
+ * `lazy`.
28
93
  *
29
- * This is a lower level version of the `Dynamic` component, useful for
30
- * performance optimizations in libraries. Do not use this unless you know
31
- * what you are doing.
32
94
  * ```typescript
33
- * const element = () => multiline() ? 'textarea' : 'input';
34
- * createDynamic(element, { value: value() });
95
+ * const User = dynamic(() => getUserComp(props.id));
96
+ * return <User>client content</User>;
35
97
  * ```
98
+ *
36
99
  * @description https://docs.solidjs.com/reference/components/dynamic
37
100
  */
38
- export declare function createDynamic<T extends ValidComponent>(component: () => T | undefined, props: ComponentProps<T>): JSX.Element;
101
+ export declare function dynamic<T extends ValidComponent>(source: () => T | Promise<T> | null | undefined | false): Component<ComponentProps<T>>;
39
102
  /**
40
103
  * Renders an arbitrary custom or native component and passes the other props
41
104
  * ```typescript
@@ -1,3 +1,18 @@
1
+ /**
2
+ * Renders a component tree synchronously to an HTML string. Async reads inside
3
+ * `<Loading>` boundaries emit their `fallback` content; for full-graph
4
+ * resolution use `renderToStringAsync` instead.
5
+ *
6
+ * Pair the returned HTML with `hydrate()` on the client.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { renderToString } from "@solidjs/web";
11
+ *
12
+ * const html = renderToString(() => <App />);
13
+ * res.send(`<!doctype html><html><body><div id="root">${html}</div></body></html>`);
14
+ * ```
15
+ */
1
16
  export declare function renderToString<T>(fn: () => T, options?: {
2
17
  nonce?: string;
3
18
  renderId?: string;
@@ -12,6 +27,21 @@ export declare function renderToString<T>(fn: () => T, options?: {
12
27
  }>;
13
28
  onError?: (err: any) => void;
14
29
  }): string;
30
+ /**
31
+ * Renders a component tree to an HTML string and awaits all async reads in the
32
+ * subtree before resolving. The returned HTML reflects the fully-settled state
33
+ * — no `<Loading>` fallbacks appear in the output.
34
+ *
35
+ * Use this when you want a complete page in one round-trip. For incremental
36
+ * streaming with progressive boundary resolution, use `renderToStream`.
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * import { renderToStringAsync } from "@solidjs/web";
41
+ *
42
+ * const html = await renderToStringAsync(() => <App />);
43
+ * ```
44
+ */
15
45
  export declare function renderToStringAsync<T>(fn: () => T, options?: {
16
46
  timeoutMs?: number;
17
47
  nonce?: string;
@@ -27,6 +57,25 @@ export declare function renderToStringAsync<T>(fn: () => T, options?: {
27
57
  }>;
28
58
  onError?: (err: any) => void;
29
59
  }): Promise<string>;
60
+ /**
61
+ * Streams an HTML response, flushing the synchronous shell first and then
62
+ * progressively emitting async-resolved fragments as their `<Loading>`
63
+ * boundaries settle. Good for time-to-first-byte sensitive pages.
64
+ *
65
+ * Returns an object with `pipe`/`pipeTo` for piping to a Node `Writable` or
66
+ * a Web `WritableStream`, plus a `then` for awaiting full completion.
67
+ *
68
+ * @example
69
+ * ```tsx
70
+ * import { renderToStream } from "@solidjs/web";
71
+ *
72
+ * // Node:
73
+ * renderToStream(() => <App />).pipe(res);
74
+ *
75
+ * // Web (Workers / Deno):
76
+ * await renderToStream(() => <App />).pipeTo(stream.writable);
77
+ * ```
78
+ */
30
79
  export declare function renderToStream<T>(fn: () => T, options?: {
31
80
  nonce?: string;
32
81
  renderId?: string;
@@ -54,19 +103,27 @@ export declare function renderToStream<T>(fn: () => T, options?: {
54
103
  }) => void;
55
104
  pipeTo: (writable: WritableStream) => Promise<void>;
56
105
  };
106
+ /** Compiler primitive — emitted by JSX-DOM-Expressions for tagged-template SSR output. Not meant for hand-written code. */
57
107
  export declare function ssr(template: string[] | string, ...nodes: any[]): {
58
108
  t: string;
59
109
  };
110
+ /** Compiler primitive — emitted by JSX-DOM-Expressions for SSR element output. Not meant for hand-written code. */
60
111
  export declare function ssrElement(name: string, props: any, children: any, needsId: boolean): {
61
112
  t: string;
62
113
  };
114
+ /** Compiler primitive — serializes a classList object for SSR output. Not meant for hand-written code. */
63
115
  export declare function ssrClassList(value: {
64
116
  [k: string]: boolean;
65
117
  }): string;
118
+ /** Compiler primitive — serializes a style object for SSR output. Not meant for hand-written code. */
66
119
  export declare function ssrStyle(value: {
67
120
  [k: string]: string;
68
121
  }): string;
122
+ /** Compiler primitive — serializes a boolean attribute for SSR output. Not meant for hand-written code. */
69
123
  export declare function ssrAttribute(key: string, value: boolean): string;
124
+ /** Compiler primitive — generates the hydration-key attribute for SSR output. Not meant for hand-written code. */
70
125
  export declare function ssrHydrationKey(): string;
126
+ /** Compiler primitive — collapses an SSR-shaped node into its HTML string. Not meant for hand-written code. */
71
127
  export declare function resolveSSRNode(node: any): string;
128
+ /** Escapes a string for safe inclusion in HTML output. Useful when constructing SSR fragments by hand. */
72
129
  export declare function escape(html: string): string;
@@ -1,16 +1,78 @@
1
- import { hydrate as hydrateCore, render as renderCore } from "./client.cjs";
2
- import { JSX, ComponentProps, ValidComponent } from "solid-js";
1
+ import { hydrate as hydrateCore } from "./client.cjs";
2
+ import { JSX, Component, ComponentProps, ValidComponent } from "solid-js";
3
3
  export * from "./client.cjs";
4
- export declare function render(...args: Parameters<typeof renderCore>): ReturnType<typeof renderCore>;
5
- export { For, Show, Switch, Match, Errored, Loading, Repeat, Reveal, NoHydration, Hydration, merge as mergeProps } from "solid-js";
6
4
  export * from "./server-mock.cjs";
5
+ export { For, Show, Switch, Match, Errored, Loading, Repeat, Reveal, NoHydration, Hydration, merge as mergeProps } from "solid-js";
7
6
  export declare const isServer: boolean;
8
7
  export declare const isDev: boolean;
8
+ type MountableElement = Element | Document | ShadowRoot | DocumentFragment | Node;
9
+ export type DynamicProps<T extends ValidComponent, P = ComponentProps<T>> = {
10
+ [K in keyof P]: P[K];
11
+ } & {
12
+ component: T | null | undefined | false;
13
+ };
14
+ /**
15
+ * Renders a component tree into a DOM element. Returns a dispose function
16
+ * that tears the tree down and cleans up reactive scopes when called.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { render } from "@solidjs/web";
21
+ *
22
+ * const dispose = render(() => <App />, document.getElementById("root")!);
23
+ *
24
+ * // Later, to unmount:
25
+ * dispose();
26
+ * ```
27
+ *
28
+ * @remarks
29
+ * The top-level insert is queued via `insertOptions: { schedule: true }` so
30
+ * its initial DOM attach goes through the effect queue rather than executing
31
+ * inline. This lets the mount participate in transitions: if an uncaught
32
+ * async read surfaces during the initial render (no `Loading` ancestor
33
+ * absorbs it), the mount is held by the transition and attaches atomically
34
+ * once all pending settles. On the no-async happy path the tail `flush()`
35
+ * drains the queued callback so the attach is synchronous by the time
36
+ * `render()` returns. The dev enforcement window scopes
37
+ * `ASYNC_OUTSIDE_LOADING_BOUNDARY` to the initial mount only.
38
+ */
39
+ export declare function render(code: () => JSX.Element, element: MountableElement, init?: unknown, options?: {
40
+ renderId?: string;
41
+ }): () => void;
42
+ /**
43
+ * Resumes a server-rendered tree on the client, attaching event listeners
44
+ * and reactive bindings without reconstructing the DOM. Returns a `dispose`
45
+ * function that tears down reactive scopes (DOM nodes are left in place).
46
+ *
47
+ * Use this when the page HTML was produced by `renderToString`,
48
+ * `renderToStringAsync`, or `renderToStream`. For client-only apps, use
49
+ * `render` instead.
50
+ *
51
+ * Pass `options.renderId` to hydrate one of multiple roots emitted by a
52
+ * server render that used the same id.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * import { hydrate } from "@solidjs/web";
57
+ *
58
+ * hydrate(() => <App />, document.getElementById("root")!);
59
+ * ```
60
+ */
9
61
  export declare const hydrate: typeof hydrateCore;
10
62
  /**
11
- * Renders components somewhere else in the DOM
63
+ * Renders its children into a different part of the DOM (modal roots,
64
+ * tooltips, layers that need to escape an `overflow: hidden` ancestor).
65
+ *
66
+ * If `mount` is omitted, the portal attaches to `document.body`. The portal
67
+ * still participates in the parent's reactive scope and disposes when the
68
+ * parent does.
12
69
  *
13
- * Useful for inserting modals and tooltips outside of an cropping layout. If no mount point is given, the portal is inserted in document.body; it is wrapped in a `<div>` unless the target is document.head or `isSVG` is true. setting `useShadow` to true places the element in a shadow root to isolate styles.
70
+ * @example
71
+ * ```tsx
72
+ * <Portal mount={document.getElementById("modal-root")!}>
73
+ * <Dialog />
74
+ * </Portal>
75
+ * ```
14
76
  *
15
77
  * @description https://docs.solidjs.com/reference/components/portal
16
78
  */
@@ -18,24 +80,25 @@ export declare function Portal<T extends boolean = false, S extends boolean = fa
18
80
  mount?: Element;
19
81
  children: JSX.Element;
20
82
  }): Text;
21
- export type DynamicProps<T extends ValidComponent, P = ComponentProps<T>> = {
22
- [K in keyof P]: P[K];
23
- } & {
24
- component: T | undefined;
25
- };
26
83
  /**
27
- * Renders an arbitrary component or element with the given props
84
+ * Returns a stable `Component` whose identity is driven by a reactive (and
85
+ * optionally async) `source`. The returned component can be used anywhere a
86
+ * normal component is used; children and props flow through JSX as usual.
87
+ *
88
+ * `source` may return a component, a native tag name (`'input'`, `'textarea'`,
89
+ * etc.), `undefined`, or a `Promise` of any of the above. A pending promise
90
+ * propagates as `NotReadyError` through the surrounding reactive scope, so
91
+ * async swaps compose with `Loading`/Suspense boundaries the same way as
92
+ * `lazy`.
28
93
  *
29
- * This is a lower level version of the `Dynamic` component, useful for
30
- * performance optimizations in libraries. Do not use this unless you know
31
- * what you are doing.
32
94
  * ```typescript
33
- * const element = () => multiline() ? 'textarea' : 'input';
34
- * createDynamic(element, { value: value() });
95
+ * const User = dynamic(() => getUserComp(props.id));
96
+ * return <User>client content</User>;
35
97
  * ```
98
+ *
36
99
  * @description https://docs.solidjs.com/reference/components/dynamic
37
100
  */
38
- export declare function createDynamic<T extends ValidComponent>(component: () => T | undefined, props: ComponentProps<T>): JSX.Element;
101
+ export declare function dynamic<T extends ValidComponent>(source: () => T | Promise<T> | null | undefined | false): Component<ComponentProps<T>>;
39
102
  /**
40
103
  * Renders an arbitrary custom or native component and passes the other props
41
104
  * ```typescript