@torpor/view 1.0.2 → 1.1.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 (33) hide show
  1. package/dist/{fromWebSocket-DeB35Q4w.d.cts → AsyncOptions-BtMe2PAd.d.cts} +21 -2
  2. package/dist/AsyncOptions-BtMe2PAd.d.cts.map +1 -0
  3. package/dist/{fromWebSocket-B52kN3-W.d.mts → AsyncOptions-ClS1_ERX.d.mts} +21 -2
  4. package/dist/AsyncOptions-ClS1_ERX.d.mts.map +1 -0
  5. package/dist/{Effect-BTKurOpr.d.mts → Effect-DazmAdyC.d.mts} +3 -3
  6. package/dist/{Effect-BTKurOpr.d.mts.map → Effect-DazmAdyC.d.mts.map} +1 -1
  7. package/dist/{Effect-COl3aRJV.d.cts → Effect-Dewn7MLc.d.cts} +3 -3
  8. package/dist/{Effect-COl3aRJV.d.cts.map → Effect-Dewn7MLc.d.cts.map} +1 -1
  9. package/dist/compile.cjs +284 -224
  10. package/dist/compile.mjs +284 -224
  11. package/dist/compile.mjs.map +1 -1
  12. package/dist/dev.d.cts +1 -1
  13. package/dist/dev.d.mts +1 -1
  14. package/dist/{fromWebSocket-Dxc_uwm1.mjs → fromWebSocket-CFGoMkV2.mjs} +9 -7
  15. package/dist/{fromWebSocket-Dxc_uwm1.mjs.map → fromWebSocket-CFGoMkV2.mjs.map} +1 -1
  16. package/dist/{fromWebSocket-1QOjcrHE.cjs → fromWebSocket-DrN-IduP.cjs} +8 -6
  17. package/dist/index.cjs +121 -41
  18. package/dist/index.d.cts +33 -7
  19. package/dist/index.d.cts.map +1 -1
  20. package/dist/index.d.mts +33 -7
  21. package/dist/index.d.mts.map +1 -1
  22. package/dist/index.mjs +121 -42
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/ssr.cjs +293 -5
  25. package/dist/ssr.d.cts +108 -9
  26. package/dist/ssr.d.cts.map +1 -1
  27. package/dist/ssr.d.mts +108 -9
  28. package/dist/ssr.d.mts.map +1 -1
  29. package/dist/ssr.mjs +292 -6
  30. package/dist/ssr.mjs.map +1 -1
  31. package/package.json +3 -3
  32. package/dist/fromWebSocket-B52kN3-W.d.mts.map +0 -1
  33. package/dist/fromWebSocket-DeB35Q4w.d.cts.map +0 -1
package/dist/dev.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as ProxySignal, n as Region, r as Computed, t as Effect } from "./Effect-COl3aRJV.cjs";
1
+ import { i as ProxySignal, n as Region, r as Computed, t as Effect } from "./Effect-Dewn7MLc.cjs";
2
2
  //#region src/types/ProxyData.d.ts
3
3
  interface ProxyData {
4
4
  target: Record<PropertyKey, any>;
package/dist/dev.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as ProxySignal, n as Region, r as Computed, t as Effect } from "./Effect-BTKurOpr.mjs";
1
+ import { i as ProxySignal, n as Region, r as Computed, t as Effect } from "./Effect-DazmAdyC.mjs";
2
2
  //#region src/types/ProxyData.d.ts
3
3
  interface ProxyData {
4
4
  target: Record<PropertyKey, any>;
@@ -43,13 +43,15 @@ function buildStyles(value) {
43
43
  }
44
44
  }
45
45
  function gatherStyles(value, styles) {
46
- if (value) if (Array.isArray(value)) for (let v of value) gatherStyles(v, styles);
47
- else if (typeof value === "object") for (let [n, v] of Object.entries(value)) {
48
- if (v === null || v === void 0) continue;
49
- const key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? "-" : "") + char.toLowerCase());
50
- styles.push(`${key}: ${v}`);
46
+ if (value) {
47
+ if (Array.isArray(value)) for (let v of value) gatherStyles(v, styles);
48
+ else if (typeof value === "object") for (let [n, v] of Object.entries(value)) {
49
+ if (v === null || v === void 0) continue;
50
+ const key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? "-" : "") + char.toLowerCase());
51
+ styles.push(`${key}: ${v}`);
52
+ }
53
+ else styles.push(String(value));
51
54
  }
52
- else styles.push(String(value));
53
55
  }
54
56
  //#endregion
55
57
  //#region src/render/formatText.ts
@@ -134,4 +136,4 @@ function fromWebSocket(url) {
134
136
  //#endregion
135
137
  export { buildStyles as a, proxyDataSymbol as c, formatText as i, fromServer as n, buildClasses as o, fromElement as r, $unwrap as s, fromWebSocket as t };
136
138
 
137
- //# sourceMappingURL=fromWebSocket-Dxc_uwm1.mjs.map
139
+ //# sourceMappingURL=fromWebSocket-CFGoMkV2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fromWebSocket-Dxc_uwm1.mjs","names":[],"sources":["../src/watch/symbols.ts","../src/watch/$unwrap.ts","../src/render/buildClasses.ts","../src/render/buildStyles.ts","../src/render/formatText.ts","../src/stream/fromElement.ts","../src/stream/fromServer.ts","../src/stream/fromWebSocket.ts"],"sourcesContent":["const proxyDataSymbol: unique symbol = Symbol.for(\"torp.ProxyData\");\n\nexport { proxyDataSymbol };\n","import { proxyDataSymbol } from \"./symbols\";\n\n/**\n * Returns the target object of a proxy\n *\n * @param object The proxy object\n */\nexport default function $unwrap<T extends Record<PropertyKey, any>>(object: T): T {\n\treturn object !== undefined && object !== null && object[proxyDataSymbol] !== undefined\n\t\t? (object[proxyDataSymbol].target ?? object)\n\t\t: object;\n}\n","import ClassValue from \"../types/ClassValue\";\nimport $unwrap from \"../watch/$unwrap\";\n\nexport default function buildClasses(value: ClassValue, styleHash?: string): string {\n\tif (typeof value === \"string\") {\n\t\tif (styleHash !== undefined) {\n\t\t\tvalue += \" \" + styleHash;\n\t\t}\n\t\treturn value;\n\t} else {\n\t\tlet classes: string[] = [];\n\t\tgatherClasses(\"\", value, classes);\n\t\tif (styleHash !== undefined) {\n\t\t\tclasses.push(styleHash);\n\t\t}\n\t\treturn classes.join(\" \");\n\t}\n}\n\nfunction gatherClasses(name: string, value: unknown, classes: string[]) {\n\tif (value) {\n\t\t// Unwrap watched values before iterating: component props are\n\t\t// deep-wrapped, and iterating a watched array disables the active\n\t\t// effect (see the array iterator in proxyGet), which would break\n\t\t// tracking of reads later in the same effect. Per-element tracking is\n\t\t// unnecessary here anyway -- the caller has already subscribed to the\n\t\t// property read that produced the value\n\t\tvalue = $unwrap(value as Record<PropertyKey, any>);\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (let v of value) {\n\t\t\t\tgatherClasses(v as string, v, classes);\n\t\t\t}\n\t\t} else if (typeof value === \"object\") {\n\t\t\t// Use `for-in` instead of `Object.entries(value)`. The entries\n\t\t\t// call allocates a new array (plus a [k, v] pair per entry) on\n\t\t\t// every invocation; `for-in` allocates nothing. Object literals\n\t\t\t// (the dominant case — e.g. `{ danger: bool }` in the row\n\t\t\t// template) have no inherited enumerable properties, so the two\n\t\t\t// are equivalent for our usage. This is on the per-effect re-run\n\t\t\t// hot path: a `select` op re-runs every row effect, each calling\n\t\t\t// `buildClasses({ danger: ... })`.\n\t\t\tfor (const n in value) {\n\t\t\t\tgatherClasses(n, (value as Record<string, unknown>)[n], classes);\n\t\t\t}\n\t\t} else {\n\t\t\tclasses.push(name);\n\t\t}\n\t}\n}\n","import type StyleValue from \"../types/StyleValue\";\n\nconst CAMEL_TO_DASH = /[A-Z]+(?![a-z])|[A-Z]/g;\n\nexport default function buildStyles(value: StyleValue): string {\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t} else {\n\t\tlet styles: string[] = [];\n\t\tgatherStyles(value, styles);\n\t\treturn styles.join(\"; \");\n\t}\n}\n\nfunction gatherStyles(value: unknown, styles: string[]) {\n\tif (value) {\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (let v of value) {\n\t\t\t\tgatherStyles(v, styles);\n\t\t\t}\n\t\t} else if (typeof value === \"object\") {\n\t\t\tfor (let [n, v] of Object.entries(value)) {\n\t\t\t\tif (v === null || v === undefined) continue;\n\t\t\t\tconst key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? \"-\" : \"\") + char.toLowerCase());\n\t\t\t\tstyles.push(`${key}: ${v}`);\n\t\t\t}\n\t\t} else {\n\t\t\t// oxlint-disable-next-line typescript/no-base-to-string\n\t\t\tstyles.push(String(value));\n\t\t}\n\t}\n}\n","import $unwrap from \"../watch/$unwrap\";\n\nexport default function formatText(value: any): string {\n\t// We could have anything in value, so we need to\n\t// - use String(...) because Symbols can't be implicitly converted\n\t// - use $unwrap because Proxies can't be converted to a string\n\tif (value === undefined || value === null) {\n\t\treturn \"\";\n\t}\n\t// Fast path: strings already satisfy both concerns above. Skipping the\n\t// `String($unwrap(value))` pair saves two function calls per text\n\t// interpolation on the dominant `typeof value === \"string\"` branch —\n\t// e.g. row labels in js-framework-bench hit this on every effect run.\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t}\n\treturn String($unwrap(value));\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * The element to listen on, or a getter returning it. Use a getter for\n * `&ref`-bound variables — they are only assigned once the element is\n * created, and subscriptions start at mount time:\n *\n * ```torp\n * let saveButton: HTMLButtonElement;\n *\n * $stream(fromElement(() => saveButton, \"click\"), () => save());\n * ```\n */\ntype EventTargetInput = HTMLElement | (() => HTMLElement | null | undefined);\n\n/**\n * Creates a StreamSource that pushes DOM events of the given type from an\n * element.\n *\n * ```torp\n * $stream(fromElement(() => saveButton, \"click\"), (e) => {\n * \t$state.clicks.push(e);\n * });\n * ```\n */\nexport default function fromElement<E extends Event = Event>(\n\ttarget: EventTargetInput,\n\ttype: string,\n): StreamSource<E> {\n\treturn (push) => {\n\t\tconst el = typeof target === \"function\" ? target() : target;\n\t\tif (!el) {\n\t\t\tthrow new Error(\n\t\t\t\t'fromElement: element not found. When passing a &ref variable, wrap it in a getter: fromElement(() => buttonEl, \"click\")',\n\t\t\t);\n\t\t}\n\t\tconst listener = push as EventListener;\n\t\tel.addEventListener(type, listener);\n\t\treturn () => {\n\t\t\tel.removeEventListener(type, listener);\n\t\t};\n\t};\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * Creates a StreamSource that receives `message` events from a server-sent\n * events endpoint. The URL may be a getter, so reactive state can be read\n * inside it — when it changes, the connection is closed and re-opened:\n *\n * ```torp\n * $stream(fromServer(`/sse/${$props.id}`), (e) => {\n * \t$state.messages.push(e.data);\n * });\n * ```\n *\n * Reconnection is handled by `EventSource` itself; errors are not pushed —\n * a source that can fail should surface errors as values.\n */\nexport default function fromServer(url: string | (() => string)): StreamSource<MessageEvent> {\n\treturn (push) => {\n\t\tconst eventSource = new EventSource(typeof url === \"function\" ? url() : url);\n\t\teventSource.onmessage = push;\n\t\treturn () => {\n\t\t\teventSource.close();\n\t\t};\n\t};\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * Creates a StreamSource that receives `message` events from a WebSocket.\n * The URL may be a getter, so reactive state can be read inside it — when\n * it changes, the socket is closed and re-opened:\n *\n * ```torp\n * $stream(fromWebSocket(`/ws/${$props.id}`), (e) => {\n * \t$state.inbox.push(e.data);\n * });\n * ```\n *\n * Errors are not pushed — a source that can fail should surface errors as\n * values and own its own reconnection.\n */\nexport default function fromWebSocket(url: string | (() => string)): StreamSource<MessageEvent> {\n\treturn (push) => {\n\t\tconst socket = new WebSocket(typeof url === \"function\" ? url() : url);\n\t\tsocket.onmessage = push;\n\t\treturn () => {\n\t\t\tsocket.close();\n\t\t};\n\t};\n}\n"],"mappings":";AAAA,MAAM,kBAAiC,OAAO,IAAI,gBAAgB;;;;;;;;ACOlE,SAAwB,QAA4C,QAAc;CACjF,OAAO,WAAW,KAAA,KAAa,WAAW,QAAQ,OAAO,qBAAqB,KAAA,IAC1E,OAAO,gBAAgB,CAAC,UAAU,SACnC;AACJ;;;ACRA,SAAwB,aAAa,OAAmB,WAA4B;CACnF,IAAI,OAAO,UAAU,UAAU;EAC9B,IAAI,cAAc,KAAA,GACjB,SAAS,MAAM;EAEhB,OAAO;CACR,OAAO;EACN,IAAI,UAAoB,CAAC;EACzB,cAAc,IAAI,OAAO,OAAO;EAChC,IAAI,cAAc,KAAA,GACjB,QAAQ,KAAK,SAAS;EAEvB,OAAO,QAAQ,KAAK,GAAG;CACxB;AACD;AAEA,SAAS,cAAc,MAAc,OAAgB,SAAmB;CACvE,IAAI,OAAO;EAOV,QAAQ,QAAQ,KAAiC;EACjD,IAAI,MAAM,QAAQ,KAAK,GACtB,KAAK,IAAI,KAAK,OACb,cAAc,GAAa,GAAG,OAAO;OAEhC,IAAI,OAAO,UAAU,UAS3B,KAAK,MAAM,KAAK,OACf,cAAc,GAAI,MAAkC,IAAI,OAAO;OAGhE,QAAQ,KAAK,IAAI;CAEnB;AACD;;;AC9CA,MAAM,gBAAgB;AAEtB,SAAwB,YAAY,OAA2B;CAC9D,IAAI,OAAO,UAAU,UACpB,OAAO;MACD;EACN,IAAI,SAAmB,CAAC;EACxB,aAAa,OAAO,MAAM;EAC1B,OAAO,OAAO,KAAK,IAAI;CACxB;AACD;AAEA,SAAS,aAAa,OAAgB,QAAkB;CACvD,IAAI,OACH,IAAI,MAAM,QAAQ,KAAK,GACtB,KAAK,IAAI,KAAK,OACb,aAAa,GAAG,MAAM;MAEjB,IAAI,OAAO,UAAU,UAC3B,KAAK,IAAI,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,GAAG;EACzC,IAAI,MAAM,QAAQ,MAAM,KAAA,GAAW;EACnC,MAAM,MAAM,EAAE,QAAQ,gBAAgB,MAAM,OAAO,IAAI,IAAI,MAAM,MAAM,KAAK,YAAY,CAAC;EACzF,OAAO,KAAK,GAAG,IAAI,IAAI,GAAG;CAC3B;MAGA,OAAO,KAAK,OAAO,KAAK,CAAC;AAG5B;;;AC7BA,SAAwB,WAAW,OAAoB;CAItD,IAAI,UAAU,KAAA,KAAa,UAAU,MACpC,OAAO;CAMR,IAAI,OAAO,UAAU,UACpB,OAAO;CAER,OAAO,OAAO,QAAQ,KAAK,CAAC;AAC7B;;;;;;;;;;;;;ACQA,SAAwB,YACvB,QACA,MACkB;CAClB,QAAQ,SAAS;EAChB,MAAM,KAAK,OAAO,WAAW,aAAa,OAAO,IAAI;EACrD,IAAI,CAAC,IACJ,MAAM,IAAI,MACT,2HACD;EAED,MAAM,WAAW;EACjB,GAAG,iBAAiB,MAAM,QAAQ;EAClC,aAAa;GACZ,GAAG,oBAAoB,MAAM,QAAQ;EACtC;CACD;AACD;;;;;;;;;;;;;;;;;AC1BA,SAAwB,WAAW,KAA0D;CAC5F,QAAQ,SAAS;EAChB,MAAM,cAAc,IAAI,YAAY,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAG;EAC3E,YAAY,YAAY;EACxB,aAAa;GACZ,YAAY,MAAM;EACnB;CACD;AACD;;;;;;;;;;;;;;;;;ACRA,SAAwB,cAAc,KAA0D;CAC/F,QAAQ,SAAS;EAChB,MAAM,SAAS,IAAI,UAAU,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAG;EACpE,OAAO,YAAY;EACnB,aAAa;GACZ,OAAO,MAAM;EACd;CACD;AACD"}
1
+ {"version":3,"file":"fromWebSocket-CFGoMkV2.mjs","names":[],"sources":["../src/watch/symbols.ts","../src/watch/$unwrap.ts","../src/render/buildClasses.ts","../src/render/buildStyles.ts","../src/render/formatText.ts","../src/stream/fromElement.ts","../src/stream/fromServer.ts","../src/stream/fromWebSocket.ts"],"sourcesContent":["const proxyDataSymbol: unique symbol = Symbol.for(\"torp.ProxyData\");\n\nexport { proxyDataSymbol };\n","import { proxyDataSymbol } from \"./symbols\";\n\n/**\n * Returns the target object of a proxy\n *\n * @param object The proxy object\n */\nexport default function $unwrap<T extends Record<PropertyKey, any>>(object: T): T {\n\treturn object !== undefined && object !== null && object[proxyDataSymbol] !== undefined\n\t\t? (object[proxyDataSymbol].target ?? object)\n\t\t: object;\n}\n","import ClassValue from \"../types/ClassValue\";\nimport $unwrap from \"../watch/$unwrap\";\n\nexport default function buildClasses(value: ClassValue, styleHash?: string): string {\n\tif (typeof value === \"string\") {\n\t\tif (styleHash !== undefined) {\n\t\t\tvalue += \" \" + styleHash;\n\t\t}\n\t\treturn value;\n\t} else {\n\t\tlet classes: string[] = [];\n\t\tgatherClasses(\"\", value, classes);\n\t\tif (styleHash !== undefined) {\n\t\t\tclasses.push(styleHash);\n\t\t}\n\t\treturn classes.join(\" \");\n\t}\n}\n\nfunction gatherClasses(name: string, value: unknown, classes: string[]) {\n\tif (value) {\n\t\t// Unwrap watched values before iterating: component props are\n\t\t// deep-wrapped, and iterating a watched array disables the active\n\t\t// effect (see the array iterator in proxyGet), which would break\n\t\t// tracking of reads later in the same effect. Per-element tracking is\n\t\t// unnecessary here anyway -- the caller has already subscribed to the\n\t\t// property read that produced the value\n\t\tvalue = $unwrap(value as Record<PropertyKey, any>);\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (let v of value) {\n\t\t\t\tgatherClasses(v as string, v, classes);\n\t\t\t}\n\t\t} else if (typeof value === \"object\") {\n\t\t\t// Use `for-in` instead of `Object.entries(value)`. The entries\n\t\t\t// call allocates a new array (plus a [k, v] pair per entry) on\n\t\t\t// every invocation; `for-in` allocates nothing. Object literals\n\t\t\t// (the dominant case — e.g. `{ danger: bool }` in the row\n\t\t\t// template) have no inherited enumerable properties, so the two\n\t\t\t// are equivalent for our usage. This is on the per-effect re-run\n\t\t\t// hot path: a `select` op re-runs every row effect, each calling\n\t\t\t// `buildClasses({ danger: ... })`.\n\t\t\tfor (const n in value) {\n\t\t\t\tgatherClasses(n, (value as Record<string, unknown>)[n], classes);\n\t\t\t}\n\t\t} else {\n\t\t\tclasses.push(name);\n\t\t}\n\t}\n}\n","import type StyleValue from \"../types/StyleValue\";\n\nconst CAMEL_TO_DASH = /[A-Z]+(?![a-z])|[A-Z]/g;\n\nexport default function buildStyles(value: StyleValue): string {\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t} else {\n\t\tlet styles: string[] = [];\n\t\tgatherStyles(value, styles);\n\t\treturn styles.join(\"; \");\n\t}\n}\n\nfunction gatherStyles(value: unknown, styles: string[]) {\n\tif (value) {\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (let v of value) {\n\t\t\t\tgatherStyles(v, styles);\n\t\t\t}\n\t\t} else if (typeof value === \"object\") {\n\t\t\tfor (let [n, v] of Object.entries(value)) {\n\t\t\t\tif (v === null || v === undefined) continue;\n\t\t\t\tconst key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? \"-\" : \"\") + char.toLowerCase());\n\t\t\t\tstyles.push(`${key}: ${v}`);\n\t\t\t}\n\t\t} else {\n\t\t\t// oxlint-disable-next-line typescript/no-base-to-string\n\t\t\tstyles.push(String(value));\n\t\t}\n\t}\n}\n","import $unwrap from \"../watch/$unwrap\";\n\nexport default function formatText(value: any): string {\n\t// We could have anything in value, so we need to\n\t// - use String(...) because Symbols can't be implicitly converted\n\t// - use $unwrap because Proxies can't be converted to a string\n\tif (value === undefined || value === null) {\n\t\treturn \"\";\n\t}\n\t// Fast path: strings already satisfy both concerns above. Skipping the\n\t// `String($unwrap(value))` pair saves two function calls per text\n\t// interpolation on the dominant `typeof value === \"string\"` branch —\n\t// e.g. row labels in js-framework-bench hit this on every effect run.\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t}\n\treturn String($unwrap(value));\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * The element to listen on, or a getter returning it. Use a getter for\n * `&ref`-bound variables — they are only assigned once the element is\n * created, and subscriptions start at mount time:\n *\n * ```torp\n * let saveButton: HTMLButtonElement;\n *\n * $stream(fromElement(() => saveButton, \"click\"), () => save());\n * ```\n */\ntype EventTargetInput = HTMLElement | (() => HTMLElement | null | undefined);\n\n/**\n * Creates a StreamSource that pushes DOM events of the given type from an\n * element.\n *\n * ```torp\n * $stream(fromElement(() => saveButton, \"click\"), (e) => {\n * \t$state.clicks.push(e);\n * });\n * ```\n */\nexport default function fromElement<E extends Event = Event>(\n\ttarget: EventTargetInput,\n\ttype: string,\n): StreamSource<E> {\n\treturn (push) => {\n\t\tconst el = typeof target === \"function\" ? target() : target;\n\t\tif (!el) {\n\t\t\tthrow new Error(\n\t\t\t\t'fromElement: element not found. When passing a &ref variable, wrap it in a getter: fromElement(() => buttonEl, \"click\")',\n\t\t\t);\n\t\t}\n\t\tconst listener = push as EventListener;\n\t\tel.addEventListener(type, listener);\n\t\treturn () => {\n\t\t\tel.removeEventListener(type, listener);\n\t\t};\n\t};\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * Creates a StreamSource that receives `message` events from a server-sent\n * events endpoint. The URL may be a getter, so reactive state can be read\n * inside it — when it changes, the connection is closed and re-opened:\n *\n * ```torp\n * $stream(fromServer(`/sse/${$props.id}`), (e) => {\n * \t$state.messages.push(e.data);\n * });\n * ```\n *\n * Reconnection is handled by `EventSource` itself; errors are not pushed —\n * a source that can fail should surface errors as values.\n */\nexport default function fromServer(url: string | (() => string)): StreamSource<MessageEvent> {\n\treturn (push) => {\n\t\tconst eventSource = new EventSource(typeof url === \"function\" ? url() : url);\n\t\teventSource.onmessage = push;\n\t\treturn () => {\n\t\t\teventSource.close();\n\t\t};\n\t};\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * Creates a StreamSource that receives `message` events from a WebSocket.\n * The URL may be a getter, so reactive state can be read inside it — when\n * it changes, the socket is closed and re-opened:\n *\n * ```torp\n * $stream(fromWebSocket(`/ws/${$props.id}`), (e) => {\n * \t$state.inbox.push(e.data);\n * });\n * ```\n *\n * Errors are not pushed — a source that can fail should surface errors as\n * values and own its own reconnection.\n */\nexport default function fromWebSocket(url: string | (() => string)): StreamSource<MessageEvent> {\n\treturn (push) => {\n\t\tconst socket = new WebSocket(typeof url === \"function\" ? url() : url);\n\t\tsocket.onmessage = push;\n\t\treturn () => {\n\t\t\tsocket.close();\n\t\t};\n\t};\n}\n"],"mappings":";AAAA,MAAM,kBAAiC,OAAO,IAAI,gBAAgB;;;;;;;;ACOlE,SAAwB,QAA4C,QAAc;CACjF,OAAO,WAAW,KAAA,KAAa,WAAW,QAAQ,OAAO,qBAAqB,KAAA,IAC1E,OAAO,gBAAgB,CAAC,UAAU,SACnC;AACJ;;;ACRA,SAAwB,aAAa,OAAmB,WAA4B;CACnF,IAAI,OAAO,UAAU,UAAU;EAC9B,IAAI,cAAc,KAAA,GACjB,SAAS,MAAM;EAEhB,OAAO;CACR,OAAO;EACN,IAAI,UAAoB,CAAC;EACzB,cAAc,IAAI,OAAO,OAAO;EAChC,IAAI,cAAc,KAAA,GACjB,QAAQ,KAAK,SAAS;EAEvB,OAAO,QAAQ,KAAK,GAAG;CACxB;AACD;AAEA,SAAS,cAAc,MAAc,OAAgB,SAAmB;CACvE,IAAI,OAAO;EAOV,QAAQ,QAAQ,KAAiC;EACjD,IAAI,MAAM,QAAQ,KAAK,GACtB,KAAK,IAAI,KAAK,OACb,cAAc,GAAa,GAAG,OAAO;OAEhC,IAAI,OAAO,UAAU,UAS3B,KAAK,MAAM,KAAK,OACf,cAAc,GAAI,MAAkC,IAAI,OAAO;OAGhE,QAAQ,KAAK,IAAI;CAEnB;AACD;;;AC9CA,MAAM,gBAAgB;AAEtB,SAAwB,YAAY,OAA2B;CAC9D,IAAI,OAAO,UAAU,UACpB,OAAO;MACD;EACN,IAAI,SAAmB,CAAC;EACxB,aAAa,OAAO,MAAM;EAC1B,OAAO,OAAO,KAAK,IAAI;CACxB;AACD;AAEA,SAAS,aAAa,OAAgB,QAAkB;CACvD,IAAI,OAAO;EACV,IAAI,MAAM,QAAQ,KAAK,GACtB,KAAK,IAAI,KAAK,OACb,aAAa,GAAG,MAAM;OAEjB,IAAI,OAAO,UAAU,UAC3B,KAAK,IAAI,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,GAAG;GACzC,IAAI,MAAM,QAAQ,MAAM,KAAA,GAAW;GACnC,MAAM,MAAM,EAAE,QAAQ,gBAAgB,MAAM,OAAO,IAAI,IAAI,MAAM,MAAM,KAAK,YAAY,CAAC;GACzF,OAAO,KAAK,GAAG,IAAI,IAAI,GAAG;EAC3B;OAGA,OAAO,KAAK,OAAO,KAAK,CAAC;CAE3B;AACD;;;AC7BA,SAAwB,WAAW,OAAoB;CAItD,IAAI,UAAU,KAAA,KAAa,UAAU,MACpC,OAAO;CAMR,IAAI,OAAO,UAAU,UACpB,OAAO;CAER,OAAO,OAAO,QAAQ,KAAK,CAAC;AAC7B;;;;;;;;;;;;;ACQA,SAAwB,YACvB,QACA,MACkB;CAClB,QAAQ,SAAS;EAChB,MAAM,KAAK,OAAO,WAAW,aAAa,OAAO,IAAI;EACrD,IAAI,CAAC,IACJ,MAAM,IAAI,MACT,2HACD;EAED,MAAM,WAAW;EACjB,GAAG,iBAAiB,MAAM,QAAQ;EAClC,aAAa;GACZ,GAAG,oBAAoB,MAAM,QAAQ;EACtC;CACD;AACD;;;;;;;;;;;;;;;;;AC1BA,SAAwB,WAAW,KAA0D;CAC5F,QAAQ,SAAS;EAChB,MAAM,cAAc,IAAI,YAAY,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAG;EAC3E,YAAY,YAAY;EACxB,aAAa;GACZ,YAAY,MAAM;EACnB;CACD;AACD;;;;;;;;;;;;;;;;;ACRA,SAAwB,cAAc,KAA0D;CAC/F,QAAQ,SAAS;EAChB,MAAM,SAAS,IAAI,UAAU,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAG;EACpE,OAAO,YAAY;EACnB,aAAa;GACZ,OAAO,MAAM;EACd;CACD;AACD"}
@@ -43,13 +43,15 @@ function buildStyles(value) {
43
43
  }
44
44
  }
45
45
  function gatherStyles(value, styles) {
46
- if (value) if (Array.isArray(value)) for (let v of value) gatherStyles(v, styles);
47
- else if (typeof value === "object") for (let [n, v] of Object.entries(value)) {
48
- if (v === null || v === void 0) continue;
49
- const key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? "-" : "") + char.toLowerCase());
50
- styles.push(`${key}: ${v}`);
46
+ if (value) {
47
+ if (Array.isArray(value)) for (let v of value) gatherStyles(v, styles);
48
+ else if (typeof value === "object") for (let [n, v] of Object.entries(value)) {
49
+ if (v === null || v === void 0) continue;
50
+ const key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? "-" : "") + char.toLowerCase());
51
+ styles.push(`${key}: ${v}`);
52
+ }
53
+ else styles.push(String(value));
51
54
  }
52
- else styles.push(String(value));
53
55
  }
54
56
  //#endregion
55
57
  //#region src/render/formatText.ts
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_devContext = require("./devContext-BulTn3U5.cjs");
3
- const require_fromWebSocket = require("./fromWebSocket-1QOjcrHE.cjs");
3
+ const require_fromWebSocket = require("./fromWebSocket-DrN-IduP.cjs");
4
4
  //#region src/render/context.ts
5
5
  const CONTEXT_SYMBOL = Symbol.for("torp.Context");
6
6
  const context = globalThis[CONTEXT_SYMBOL] ??= {
@@ -24,7 +24,8 @@ const context = globalThis[CONTEXT_SYMBOL] ??= {
24
24
  mountEffects: [],
25
25
  stashedEvents: [],
26
26
  stashedAnimations: [],
27
- hydrationNode: null
27
+ hydrationNode: null,
28
+ serverValues: null
28
29
  };
29
30
  //#endregion
30
31
  //#region src/render/addAnimation.ts
@@ -151,9 +152,11 @@ function checkComputed(computed) {
151
152
  */
152
153
  function checkSources(target) {
153
154
  let haveComputed = false;
154
- for (let sourceSub = target.firstSource; sourceSub !== null; sourceSub = sourceSub.nextSource) if (sourceSub.recalc) if (sourceSub.source.type === 0) return true;
155
- else if (sourceSub.source.recalc) haveComputed = true;
156
- else return true;
155
+ for (let sourceSub = target.firstSource; sourceSub !== null; sourceSub = sourceSub.nextSource) if (sourceSub.recalc) {
156
+ if (sourceSub.source.type === 0) return true;
157
+ else if (sourceSub.source.recalc) haveComputed = true;
158
+ else return true;
159
+ }
157
160
  if (haveComputed) {
158
161
  for (let sourceSub = target.firstSource; sourceSub !== null; sourceSub = sourceSub.nextSource) if (sourceSub.recalc && sourceSub.source.type === 1 && sourceSub.source.recalc) {
159
162
  const oldActiveTarget = context.activeTarget;
@@ -729,13 +732,15 @@ function addFragment(fragment, parent, before, endNode, startNode) {
729
732
  //#region src/render/applyProps.ts
730
733
  function applyProps(el, props, propNamesUsed) {
731
734
  if (props !== void 0) {
732
- for (let [name, value] of Object.entries(props)) if (!propNamesUsed.includes(name)) if (name.startsWith("on")) {
733
- const eventName = name.substring(2);
734
- if (isDelegatedEventType(eventName)) attachDelegatedEvent(el, eventName, value);
735
- else el.addEventListener(eventName, value);
736
- } else $run(function setAttribute() {
737
- el.setAttribute(name, value);
738
- });
735
+ for (let [name, value] of Object.entries(props)) if (!propNamesUsed.includes(name)) {
736
+ if (name.startsWith("on")) {
737
+ const eventName = name.substring(2);
738
+ if (isDelegatedEventType(eventName)) attachDelegatedEvent(el, eventName, value);
739
+ else el.addEventListener(eventName, value);
740
+ } else $run(function setAttribute() {
741
+ el.setAttribute(name, value);
742
+ });
743
+ }
739
744
  }
740
745
  }
741
746
  //#endregion
@@ -931,16 +936,18 @@ function firstInsideNode(anchor) {
931
936
  //#endregion
932
937
  //#region src/render/getFragment.ts
933
938
  function getFragment(document, array, index, html, ns) {
934
- if (array[index] === void 0) if (ns === true) {
935
- const template = document.createElementNS("http://www.w3.org/2000/svg", "template");
936
- template.innerHTML = html;
937
- const fragment = new DocumentFragment();
938
- fragment.append(...template.childNodes);
939
- array[index] = fragment;
940
- } else {
941
- const template = document.createElement("template");
942
- template.innerHTML = html;
943
- array[index] = template.content;
939
+ if (array[index] === void 0) {
940
+ if (ns === true) {
941
+ const template = document.createElementNS("http://www.w3.org/2000/svg", "template");
942
+ template.innerHTML = html;
943
+ const fragment = new DocumentFragment();
944
+ fragment.append(...template.childNodes);
945
+ array[index] = fragment;
946
+ } else {
947
+ const template = document.createElement("template");
948
+ template.innerHTML = html;
949
+ array[index] = template.content;
950
+ }
944
951
  }
945
952
  return array[index].cloneNode(true);
946
953
  }
@@ -971,14 +978,16 @@ function getFragment(document, array, index, html, ns) {
971
978
  * `firstElementChild` is then an SVG element).
972
979
  */
973
980
  function getElementFragment(document, array, index, html, ns) {
974
- if (array[index] === void 0) if (ns === true) {
975
- const template = document.createElementNS("http://www.w3.org/2000/svg", "template");
976
- template.innerHTML = html;
977
- array[index] = template.firstElementChild;
978
- } else {
979
- const template = document.createElement("template");
980
- template.innerHTML = html;
981
- array[index] = template.content.firstElementChild;
981
+ if (array[index] === void 0) {
982
+ if (ns === true) {
983
+ const template = document.createElementNS("http://www.w3.org/2000/svg", "template");
984
+ template.innerHTML = html;
985
+ array[index] = template.firstElementChild;
986
+ } else {
987
+ const template = document.createElement("template");
988
+ template.innerHTML = html;
989
+ array[index] = template.content.firstElementChild;
990
+ }
982
991
  }
983
992
  return array[index].cloneNode(true);
984
993
  }
@@ -1539,7 +1548,7 @@ function trackProxySignal(data, key) {
1539
1548
  * suspend up the cache chain by tainting the active reader, and notifies the
1540
1549
  * nearest `@await` boundary.
1541
1550
  *
1542
- * Return value (stale-while-revalidate, ASYNC.md §6.2): on a refresh suspend
1551
+ * Return value (ASYNC.md → "Stale-while-revalidate"): on a refresh suspend
1543
1552
  * (the computed has resolved before) returns the previously resolved value
1544
1553
  * held in `staleValue`, so readers keep displaying the old content instead of
1545
1554
  * a placeholder — an `@await` boundary thus keeps its content mounted
@@ -2249,10 +2258,23 @@ function runList(region, parent, anchor, buildItems, create, update, noWatch) {
2249
2258
  //#endregion
2250
2259
  //#region src/render/runAwait.ts
2251
2260
  /**
2261
+ * Comment prefix marking the embedded `source: "server"` values that the
2262
+ * server writes after a resolved boundary's anchor (`<!--t-await:[...]-->`,
2263
+ * see ASYNC.md → "Server rendering").
2264
+ */
2265
+ const SERVER_VALUES_PREFIX = "t-await:";
2266
+ /**
2252
2267
  * Renders an `@await` boundary. On the first run, content is rendered
2253
2268
  * speculatively; if any read inside suspends (`didSuspend`), the boundary
2254
2269
  * discards the partial render and shows the `with` branch instead.
2255
2270
  *
2271
+ * Hydration of a server-resolved boundary (ASYNC.md → "Server rendering"): when the server
2272
+ * shipped resolved content, its values ride in a payload comment after the
2273
+ * anchor. The boundary renders the content branch *with* hydration enabled
2274
+ * and `$async` seeds its computeds from the payload, so the server's HTML is
2275
+ * adopted directly — no speculative render, no `with`-branch dance, no
2276
+ * fallback flash.
2277
+ *
2256
2278
  * Fine-grained updates: on subsequent runs the boundary only decides whether
2257
2279
  * to SWITCH branches. It does so from its `pending` set — the suspended
2258
2280
  * computeds recorded by `suspendRead` — dropping entries that resolved and
@@ -2262,7 +2284,7 @@ function runList(region, parent, anchor, buildItems, create, update, noWatch) {
2262
2284
  * non-suspend dependency changes inside content are left to the child
2263
2285
  * effects that read them — the boundary isn't re-run by them at all.
2264
2286
  *
2265
- * Stale-while-revalidate (ASYNC.md §6.2): once content has been produced
2287
+ * Stale-while-revalidate (ASYNC.md): once content has been produced
2266
2288
  * (`hasContent`), a subsequent suspend during a refresh does NOT switch to
2267
2289
  * the `with` branch — the boundary keeps the stale content mounted. `$async`
2268
2290
  * retains the previous resolved value (`Computed.staleValue`) and
@@ -2284,6 +2306,18 @@ function runAwait(region, anchor, renderContent, renderWith, name) {
2284
2306
  let first = true;
2285
2307
  let hasContent = false;
2286
2308
  let theEffect = null;
2309
+ let serverValues = null;
2310
+ if (context.hydrationNode !== null && anchor !== null) {
2311
+ const next = anchor.nextSibling;
2312
+ if (next !== null && isCommentNode(next) && next.data.startsWith(SERVER_VALUES_PREFIX)) {
2313
+ try {
2314
+ serverValues = JSON.parse(next.data.substring(8));
2315
+ } catch {
2316
+ serverValues = null;
2317
+ }
2318
+ next.remove();
2319
+ }
2320
+ }
2287
2321
  const gen = region.generation = (region.generation ?? 0) + 1;
2288
2322
  $run(function runAwait() {
2289
2323
  if (region.generation !== gen) return;
@@ -2304,9 +2338,15 @@ function runAwait(region, anchor, renderContent, renderWith, name) {
2304
2338
  context.awaitBoundary = boundary;
2305
2339
  boundary.suspended = false;
2306
2340
  const savedHydration = context.hydrationNode;
2307
- if (savedHydration !== null) context.hydrationNode = null;
2341
+ const savedServerValues = context.serverValues;
2342
+ if (serverValues !== null && savedHydration !== null) context.serverValues = {
2343
+ values: serverValues,
2344
+ index: 0
2345
+ };
2346
+ else if (savedHydration !== null) context.hydrationNode = null;
2308
2347
  renderBranch(0, renderContent);
2309
- if (savedHydration !== null) context.hydrationNode = savedHydration;
2348
+ context.hydrationNode = savedHydration;
2349
+ context.serverValues = savedServerValues;
2310
2350
  context.awaitBoundary = oldBoundary;
2311
2351
  if (boundary.suspended && renderWith !== null) renderBranch(1, renderWith);
2312
2352
  else if (!boundary.suspended) hasContent = true;
@@ -2321,10 +2361,12 @@ function runAwait(region, anchor, renderContent, renderWith, name) {
2321
2361
  const targetIndex = suspended ? 1 : 0;
2322
2362
  if (targetIndex !== index) {
2323
2363
  if (targetIndex === 0) attemptContent();
2324
- else if (!hasContent) if (renderWith !== null) renderBranch(1, renderWith);
2325
- else {
2326
- runControlBranch(region, index, 1);
2327
- index = 1;
2364
+ else if (!hasContent) {
2365
+ if (renderWith !== null) renderBranch(1, renderWith);
2366
+ else {
2367
+ runControlBranch(region, index, 1);
2368
+ index = 1;
2369
+ }
2328
2370
  }
2329
2371
  }
2330
2372
  }
@@ -2446,6 +2488,23 @@ function runTry(region, anchor, renderTry, renderCatch, name) {
2446
2488
  }, name);
2447
2489
  }
2448
2490
  //#endregion
2491
+ //#region src/render/headElement.ts
2492
+ /**
2493
+ * Gets an element from the document head matching the selector, creating and
2494
+ * appending a new one if there isn't a match. Used by the code generated for
2495
+ * a @head block, so that elements which were server rendered (or rendered by
2496
+ * a previously visited page) are adopted rather than duplicated.
2497
+ */
2498
+ function headElement(tagName, selector) {
2499
+ if (selector) {
2500
+ const existing = document.head.querySelector(selector);
2501
+ if (existing) return existing;
2502
+ }
2503
+ const element = document.createElement(tagName);
2504
+ document.head.appendChild(element);
2505
+ return element;
2506
+ }
2507
+ //#endregion
2449
2508
  //#region src/render/setAttribute.ts
2450
2509
  function setAttribute(el, name, value) {
2451
2510
  if (value === false || value === void 0 || value === null) el.removeAttribute(name);
@@ -2491,10 +2550,20 @@ function $batch(fn) {
2491
2550
  * over the computed object), so they fire on both the initial run and every
2492
2551
  * recalculation — `runComputed` and `checkComputed` are unchanged.
2493
2552
  *
2553
+ * Hydration seeding (ASYNC.md → "Server rendering"): while hydrating the content branch of
2554
+ * a boundary whose server HTML embedded resolved `source: "server"` values,
2555
+ * `context.serverValues` is set, and this read consumes the value at the
2556
+ * current position instead of suspending. The thunk still runs — once, in
2557
+ * the background — so the getter's dependencies are tracked and later
2558
+ * dependency changes re-fetch; the embedded value wins the generation race,
2559
+ * so there's no re-fetch wait and no fallback flash.
2560
+ *
2494
2561
  * @param fn A thunk returning the Promise to await. Signal reads inside `fn`
2495
2562
  * are tracked, so the fetch re-runs when dependencies change.
2563
+ * @param _options Accepted so the same getter source compiles into client and
2564
+ * server builds (`source: "server"` fetches during SSR); ignored here.
2496
2565
  */
2497
- function $async(fn) {
2566
+ function $async(fn, _options) {
2498
2567
  if (context.registerComputed === null) throw new Error("$async must be used in a getter");
2499
2568
  const computed = {
2500
2569
  type: 1,
@@ -2547,6 +2616,16 @@ function $async(fn) {
2547
2616
  };
2548
2617
  context.registerComputed(computed);
2549
2618
  runComputed(computed);
2619
+ const serverValues = context.serverValues;
2620
+ if (serverValues !== null && serverValues.index < serverValues.values.length) {
2621
+ computed.generation++;
2622
+ computed.didSuspend = false;
2623
+ computed.didError = false;
2624
+ computed.hasResolved = true;
2625
+ computed.lastErrored = false;
2626
+ computed.value = serverValues.values[serverValues.index++];
2627
+ computed.staleValue = computed.value;
2628
+ }
2550
2629
  return computed.value;
2551
2630
  }
2552
2631
  //#endregion
@@ -2676,7 +2755,7 @@ function $onmount(fn) {
2676
2755
  * subscription but don't propagate taint or notify a `@await` boundary.
2677
2756
  * This lets `$pending` return a plain boolean without itself suspending.
2678
2757
  *
2679
- * Quiet-on-refresh semantics (ASYNC.md §7.4): a suspend is *quiet* — and
2758
+ * Quiet-on-refresh semantics (ASYNC.md → "Loud vs quiet"): a suspend is *quiet* — and
2680
2759
  * therefore `$pending` returns `false` for it — when the computed has resolved
2681
2760
  * before and the re-fetch was a *silent* `$refresh(fn, { silent: true })` (a
2682
2761
  * bare refresh with no tracked dependency change, used for background
@@ -2703,7 +2782,7 @@ function $pending(fn) {
2703
2782
  //#region src/watch/$refresh.ts
2704
2783
  /**
2705
2784
  * Re-fetches the `$async` getters read inside `fn` without changing a
2706
- * dependency. A companion to `$pending` (ASYNC.md §6.2): pull-to-refresh,
2785
+ * dependency. A companion to `$pending` (ASYNC.md): pull-to-refresh,
2707
2786
  * refresh buttons, refetch-on-focus, polling, retry-after-error.
2708
2787
  *
2709
2788
  * `fn` is run in a tracking context that collects every `$async` computed it
@@ -2875,6 +2954,7 @@ exports.t_first_inside = firstInsideNode;
2875
2954
  exports.t_fmt = require_fromWebSocket.formatText;
2876
2955
  exports.t_fragment = getFragment;
2877
2956
  exports.t_fragment_el = getElementFragment;
2957
+ exports.t_head_element = headElement;
2878
2958
  exports.t_list_item = newListItem;
2879
2959
  exports.t_next = nodeNext;
2880
2960
  exports.t_pop_region = popRegion;
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as SlotRender, t as Component } from "./Component-0MH0zd-m.cjs";
2
2
  import { t as Cleanup } from "./Cleanup-D0wvGW5d.cjs";
3
- import { n as Region, t as Effect } from "./Effect-COl3aRJV.cjs";
4
- import { a as buildStyles, c as ClassValue, i as StreamSource, n as fromServer, o as StyleValue, r as fromElement, s as buildClasses, t as fromWebSocket } from "./fromWebSocket-DeB35Q4w.cjs";
3
+ import { n as Region, t as Effect } from "./Effect-Dewn7MLc.cjs";
4
+ import { a as StreamSource, c as buildClasses, i as fromElement, l as ClassValue, n as fromWebSocket, o as buildStyles, r as fromServer, s as StyleValue, t as AsyncOptions } from "./AsyncOptions-BtMe2PAd.cjs";
5
5
  //#region src/types/Animation.d.ts
6
6
  interface Animation {
7
7
  keyframes: Keyframe[] | PropertyIndexedKeyframes;
@@ -345,6 +345,13 @@ declare function runList(region: Region, parent: ParentNode, anchor: Node | null
345
345
  * speculatively; if any read inside suspends (`didSuspend`), the boundary
346
346
  * discards the partial render and shows the `with` branch instead.
347
347
  *
348
+ * Hydration of a server-resolved boundary (ASYNC.md → "Server rendering"): when the server
349
+ * shipped resolved content, its values ride in a payload comment after the
350
+ * anchor. The boundary renders the content branch *with* hydration enabled
351
+ * and `$async` seeds its computeds from the payload, so the server's HTML is
352
+ * adopted directly — no speculative render, no `with`-branch dance, no
353
+ * fallback flash.
354
+ *
348
355
  * Fine-grained updates: on subsequent runs the boundary only decides whether
349
356
  * to SWITCH branches. It does so from its `pending` set — the suspended
350
357
  * computeds recorded by `suspendRead` — dropping entries that resolved and
@@ -354,7 +361,7 @@ declare function runList(region: Region, parent: ParentNode, anchor: Node | null
354
361
  * non-suspend dependency changes inside content are left to the child
355
362
  * effects that read them — the boundary isn't re-run by them at all.
356
363
  *
357
- * Stale-while-revalidate (ASYNC.md §6.2): once content has been produced
364
+ * Stale-while-revalidate (ASYNC.md): once content has been produced
358
365
  * (`hasContent`), a subsequent suspend during a refresh does NOT switch to
359
366
  * the `with` branch — the boundary keeps the stale content mounted. `$async`
360
367
  * retains the previous resolved value (`Computed.staleValue`) and
@@ -424,6 +431,15 @@ declare function runTry(region: Region, anchor: Node | null, renderTry: (anchor:
424
431
  */
425
432
  declare function saveHydration(): ChildNode | null;
426
433
  //#endregion
434
+ //#region src/render/headElement.d.ts
435
+ /**
436
+ * Gets an element from the document head matching the selector, creating and
437
+ * appending a new one if there isn't a match. Used by the code generated for
438
+ * a @head block, so that elements which were server rendered (or rendered by
439
+ * a previously visited page) are adopted rather than duplicated.
440
+ */
441
+ declare function headElement(tagName: string, selector: string): Element;
442
+ //#endregion
427
443
  //#region src/render/setAttribute.d.ts
428
444
  declare function setAttribute(el: Element, name: string, value: any): void;
429
445
  //#endregion
@@ -469,10 +485,20 @@ declare function $batch<T>(fn: () => T): T;
469
485
  * over the computed object), so they fire on both the initial run and every
470
486
  * recalculation — `runComputed` and `checkComputed` are unchanged.
471
487
  *
488
+ * Hydration seeding (ASYNC.md → "Server rendering"): while hydrating the content branch of
489
+ * a boundary whose server HTML embedded resolved `source: "server"` values,
490
+ * `context.serverValues` is set, and this read consumes the value at the
491
+ * current position instead of suspending. The thunk still runs — once, in
492
+ * the background — so the getter's dependencies are tracked and later
493
+ * dependency changes re-fetch; the embedded value wins the generation race,
494
+ * so there's no re-fetch wait and no fallback flash.
495
+ *
472
496
  * @param fn A thunk returning the Promise to await. Signal reads inside `fn`
473
497
  * are tracked, so the fetch re-runs when dependencies change.
498
+ * @param _options Accepted so the same getter source compiles into client and
499
+ * server builds (`source: "server"` fetches during SSR); ignored here.
474
500
  */
475
- declare function $async<T>(fn: () => Promise<T>): T;
501
+ declare function $async<T>(fn: () => Promise<T>, _options?: AsyncOptions): T;
476
502
  //#endregion
477
503
  //#region src/watch/$bind.d.ts
478
504
  /**
@@ -564,7 +590,7 @@ declare function $peek<T>(fn: () => T): T;
564
590
  * subscription but don't propagate taint or notify a `@await` boundary.
565
591
  * This lets `$pending` return a plain boolean without itself suspending.
566
592
  *
567
- * Quiet-on-refresh semantics (ASYNC.md §7.4): a suspend is *quiet* — and
593
+ * Quiet-on-refresh semantics (ASYNC.md → "Loud vs quiet"): a suspend is *quiet* — and
568
594
  * therefore `$pending` returns `false` for it — when the computed has resolved
569
595
  * before and the re-fetch was a *silent* `$refresh(fn, { silent: true })` (a
570
596
  * bare refresh with no tracked dependency change, used for background
@@ -594,7 +620,7 @@ interface RefreshOptions {
594
620
  }
595
621
  /**
596
622
  * Re-fetches the `$async` getters read inside `fn` without changing a
597
- * dependency. A companion to `$pending` (ASYNC.md §6.2): pull-to-refresh,
623
+ * dependency. A companion to `$pending` (ASYNC.md): pull-to-refresh,
598
624
  * refresh buttons, refetch-on-focus, polling, retry-after-error.
599
625
  *
600
626
  * `fn` is run in a tracking context that collects every `$async` computed it
@@ -718,5 +744,5 @@ interface WatchOptions {
718
744
  */
719
745
  declare function $watch<T extends object>(object: T, options?: WatchOptions): T;
720
746
  //#endregion
721
- export { $async, $batch, $bind, $cache, $onmount, $peek, $pending, $refresh, $run, $stream, $unwrap, $watch, type Animation, type Bindable, type ClassValue, type Component, type ListItem, type ListItemSpec, type SlotRender, type StreamSource, type StyleValue, clearLayoutSlot, fillLayoutSlot, fromElement, fromServer, fromWebSocket, hydrate, mount, addElement as t_add_element, addFragment as t_add_fragment, nodeAnchor as t_anchor, addAnimation as t_animate, applyProps as t_apply_props, setAttribute as t_attribute, nodeChild as t_child, buildClasses as t_class, setDynamicElement as t_dynamic, addEvent as t_event, firstInsideNode as t_first_inside, formatText as t_fmt, getFragment as t_fragment, getElementFragment as t_fragment_el, newListItem as t_list_item, nodeNext as t_next, popRegion as t_pop_region, pushRegion as t_push_region, newRegion as t_region, rerunRegionEffects as t_rerun_region_effects, restoreHydration as t_restore_hydration, nodeRoot as t_root, nodeRootElement as t_root_el, runAwait as t_run_await, runControlBranch as t_run_branch, runControl as t_run_control, runList as t_run_list, runTry as t_run_try, saveHydration as t_save_hydration, nodeSkip as t_skip, buildStyles as t_style, unmount };
747
+ export { $async, $batch, $bind, $cache, $onmount, $peek, $pending, $refresh, $run, $stream, $unwrap, $watch, type Animation, type Bindable, type ClassValue, type Component, type ListItem, type ListItemSpec, type SlotRender, type StreamSource, type StyleValue, clearLayoutSlot, fillLayoutSlot, fromElement, fromServer, fromWebSocket, hydrate, mount, addElement as t_add_element, addFragment as t_add_fragment, nodeAnchor as t_anchor, addAnimation as t_animate, applyProps as t_apply_props, setAttribute as t_attribute, nodeChild as t_child, buildClasses as t_class, setDynamicElement as t_dynamic, addEvent as t_event, firstInsideNode as t_first_inside, formatText as t_fmt, getFragment as t_fragment, getElementFragment as t_fragment_el, headElement as t_head_element, newListItem as t_list_item, nodeNext as t_next, popRegion as t_pop_region, pushRegion as t_push_region, newRegion as t_region, rerunRegionEffects as t_rerun_region_effects, restoreHydration as t_restore_hydration, nodeRoot as t_root, nodeRootElement as t_root_el, runAwait as t_run_await, runControlBranch as t_run_branch, runControl as t_run_control, runList as t_run_list, runTry as t_run_try, saveHydration as t_save_hydration, nodeSkip as t_skip, buildStyles as t_style, unmount };
722
748
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types/Animation.ts","../src/render/addAnimation.ts","../src/render/addEvent.ts","../src/render/addElement.ts","../src/render/addFragment.ts","../src/render/applyProps.ts","../src/render/clearLayoutSlot.ts","../src/render/fillLayoutSlot.ts","../src/render/formatText.ts","../src/render/firstInsideNode.ts","../src/render/getFragment.ts","../src/render/getElementFragment.ts","../src/render/hydrate.ts","../src/render/mount.ts","../src/render/unmount.ts","../src/types/ListItemSpec.ts","../src/types/ListItem.ts","../src/render/newListItem.ts","../src/render/newRegion.ts","../src/render/nodeAnchor.ts","../src/render/nodeChild.ts","../src/render/nodeNext.ts","../src/render/nodeRootElement.ts","../src/render/nodeRoot.ts","../src/render/nodeSkip.ts","../src/render/popRegion.ts","../src/render/pushRegion.ts","../src/render/rerunRegionEffects.ts","../src/render/restoreHydration.ts","../src/render/runControl.ts","../src/render/runControlBranch.ts","../src/render/runList.ts","../src/render/runAwait.ts","../src/render/runTry.ts","../src/render/saveHydration.ts","../src/render/setAttribute.ts","../src/render/setDynamicElement.ts","../src/types/Bindable.ts","../src/watch/$batch.ts","../src/watch/$async.ts","../src/watch/$bind.ts","../src/watch/$cache.ts","../src/watch/$onmount.ts","../src/watch/$peek.ts","../src/watch/$pending.ts","../src/watch/$refresh.ts","../src/watch/$run.ts","../src/watch/$stream.ts","../src/watch/$unwrap.ts","../src/types/WatchOptions.ts","../src/watch/$watch.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types/Animation.ts","../src/render/addAnimation.ts","../src/render/addEvent.ts","../src/render/addElement.ts","../src/render/addFragment.ts","../src/render/applyProps.ts","../src/render/clearLayoutSlot.ts","../src/render/fillLayoutSlot.ts","../src/render/formatText.ts","../src/render/firstInsideNode.ts","../src/render/getFragment.ts","../src/render/getElementFragment.ts","../src/render/hydrate.ts","../src/render/mount.ts","../src/render/unmount.ts","../src/types/ListItemSpec.ts","../src/types/ListItem.ts","../src/render/newListItem.ts","../src/render/newRegion.ts","../src/render/nodeAnchor.ts","../src/render/nodeChild.ts","../src/render/nodeNext.ts","../src/render/nodeRootElement.ts","../src/render/nodeRoot.ts","../src/render/nodeSkip.ts","../src/render/popRegion.ts","../src/render/pushRegion.ts","../src/render/rerunRegionEffects.ts","../src/render/restoreHydration.ts","../src/render/runControl.ts","../src/render/runControlBranch.ts","../src/render/runList.ts","../src/render/runAwait.ts","../src/render/runTry.ts","../src/render/saveHydration.ts","../src/render/headElement.ts","../src/render/setAttribute.ts","../src/render/setDynamicElement.ts","../src/types/Bindable.ts","../src/watch/$batch.ts","../src/watch/$async.ts","../src/watch/$bind.ts","../src/watch/$cache.ts","../src/watch/$onmount.ts","../src/watch/$peek.ts","../src/watch/$pending.ts","../src/watch/$refresh.ts","../src/watch/$run.ts","../src/watch/$stream.ts","../src/watch/$unwrap.ts","../src/types/WatchOptions.ts","../src/watch/$watch.ts"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as SlotRender, t as Component } from "./Component-0MH0zd-m.mjs";
2
2
  import { t as Cleanup } from "./Cleanup-D0wvGW5d.mjs";
3
- import { n as Region, t as Effect } from "./Effect-BTKurOpr.mjs";
4
- import { a as buildStyles, c as ClassValue, i as StreamSource, n as fromServer, o as StyleValue, r as fromElement, s as buildClasses, t as fromWebSocket } from "./fromWebSocket-B52kN3-W.mjs";
3
+ import { n as Region, t as Effect } from "./Effect-DazmAdyC.mjs";
4
+ import { a as StreamSource, c as buildClasses, i as fromElement, l as ClassValue, n as fromWebSocket, o as buildStyles, r as fromServer, s as StyleValue, t as AsyncOptions } from "./AsyncOptions-ClS1_ERX.mjs";
5
5
  //#region src/types/Animation.d.ts
6
6
  interface Animation {
7
7
  keyframes: Keyframe[] | PropertyIndexedKeyframes;
@@ -345,6 +345,13 @@ declare function runList(region: Region, parent: ParentNode, anchor: Node | null
345
345
  * speculatively; if any read inside suspends (`didSuspend`), the boundary
346
346
  * discards the partial render and shows the `with` branch instead.
347
347
  *
348
+ * Hydration of a server-resolved boundary (ASYNC.md → "Server rendering"): when the server
349
+ * shipped resolved content, its values ride in a payload comment after the
350
+ * anchor. The boundary renders the content branch *with* hydration enabled
351
+ * and `$async` seeds its computeds from the payload, so the server's HTML is
352
+ * adopted directly — no speculative render, no `with`-branch dance, no
353
+ * fallback flash.
354
+ *
348
355
  * Fine-grained updates: on subsequent runs the boundary only decides whether
349
356
  * to SWITCH branches. It does so from its `pending` set — the suspended
350
357
  * computeds recorded by `suspendRead` — dropping entries that resolved and
@@ -354,7 +361,7 @@ declare function runList(region: Region, parent: ParentNode, anchor: Node | null
354
361
  * non-suspend dependency changes inside content are left to the child
355
362
  * effects that read them — the boundary isn't re-run by them at all.
356
363
  *
357
- * Stale-while-revalidate (ASYNC.md §6.2): once content has been produced
364
+ * Stale-while-revalidate (ASYNC.md): once content has been produced
358
365
  * (`hasContent`), a subsequent suspend during a refresh does NOT switch to
359
366
  * the `with` branch — the boundary keeps the stale content mounted. `$async`
360
367
  * retains the previous resolved value (`Computed.staleValue`) and
@@ -424,6 +431,15 @@ declare function runTry(region: Region, anchor: Node | null, renderTry: (anchor:
424
431
  */
425
432
  declare function saveHydration(): ChildNode | null;
426
433
  //#endregion
434
+ //#region src/render/headElement.d.ts
435
+ /**
436
+ * Gets an element from the document head matching the selector, creating and
437
+ * appending a new one if there isn't a match. Used by the code generated for
438
+ * a @head block, so that elements which were server rendered (or rendered by
439
+ * a previously visited page) are adopted rather than duplicated.
440
+ */
441
+ declare function headElement(tagName: string, selector: string): Element;
442
+ //#endregion
427
443
  //#region src/render/setAttribute.d.ts
428
444
  declare function setAttribute(el: Element, name: string, value: any): void;
429
445
  //#endregion
@@ -469,10 +485,20 @@ declare function $batch<T>(fn: () => T): T;
469
485
  * over the computed object), so they fire on both the initial run and every
470
486
  * recalculation — `runComputed` and `checkComputed` are unchanged.
471
487
  *
488
+ * Hydration seeding (ASYNC.md → "Server rendering"): while hydrating the content branch of
489
+ * a boundary whose server HTML embedded resolved `source: "server"` values,
490
+ * `context.serverValues` is set, and this read consumes the value at the
491
+ * current position instead of suspending. The thunk still runs — once, in
492
+ * the background — so the getter's dependencies are tracked and later
493
+ * dependency changes re-fetch; the embedded value wins the generation race,
494
+ * so there's no re-fetch wait and no fallback flash.
495
+ *
472
496
  * @param fn A thunk returning the Promise to await. Signal reads inside `fn`
473
497
  * are tracked, so the fetch re-runs when dependencies change.
498
+ * @param _options Accepted so the same getter source compiles into client and
499
+ * server builds (`source: "server"` fetches during SSR); ignored here.
474
500
  */
475
- declare function $async<T>(fn: () => Promise<T>): T;
501
+ declare function $async<T>(fn: () => Promise<T>, _options?: AsyncOptions): T;
476
502
  //#endregion
477
503
  //#region src/watch/$bind.d.ts
478
504
  /**
@@ -564,7 +590,7 @@ declare function $peek<T>(fn: () => T): T;
564
590
  * subscription but don't propagate taint or notify a `@await` boundary.
565
591
  * This lets `$pending` return a plain boolean without itself suspending.
566
592
  *
567
- * Quiet-on-refresh semantics (ASYNC.md §7.4): a suspend is *quiet* — and
593
+ * Quiet-on-refresh semantics (ASYNC.md → "Loud vs quiet"): a suspend is *quiet* — and
568
594
  * therefore `$pending` returns `false` for it — when the computed has resolved
569
595
  * before and the re-fetch was a *silent* `$refresh(fn, { silent: true })` (a
570
596
  * bare refresh with no tracked dependency change, used for background
@@ -594,7 +620,7 @@ interface RefreshOptions {
594
620
  }
595
621
  /**
596
622
  * Re-fetches the `$async` getters read inside `fn` without changing a
597
- * dependency. A companion to `$pending` (ASYNC.md §6.2): pull-to-refresh,
623
+ * dependency. A companion to `$pending` (ASYNC.md): pull-to-refresh,
598
624
  * refresh buttons, refetch-on-focus, polling, retry-after-error.
599
625
  *
600
626
  * `fn` is run in a tracking context that collects every `$async` computed it
@@ -718,5 +744,5 @@ interface WatchOptions {
718
744
  */
719
745
  declare function $watch<T extends object>(object: T, options?: WatchOptions): T;
720
746
  //#endregion
721
- export { $async, $batch, $bind, $cache, $onmount, $peek, $pending, $refresh, $run, $stream, $unwrap, $watch, type Animation, type Bindable, type ClassValue, type Component, type ListItem, type ListItemSpec, type SlotRender, type StreamSource, type StyleValue, clearLayoutSlot, fillLayoutSlot, fromElement, fromServer, fromWebSocket, hydrate, mount, addElement as t_add_element, addFragment as t_add_fragment, nodeAnchor as t_anchor, addAnimation as t_animate, applyProps as t_apply_props, setAttribute as t_attribute, nodeChild as t_child, buildClasses as t_class, setDynamicElement as t_dynamic, addEvent as t_event, firstInsideNode as t_first_inside, formatText as t_fmt, getFragment as t_fragment, getElementFragment as t_fragment_el, newListItem as t_list_item, nodeNext as t_next, popRegion as t_pop_region, pushRegion as t_push_region, newRegion as t_region, rerunRegionEffects as t_rerun_region_effects, restoreHydration as t_restore_hydration, nodeRoot as t_root, nodeRootElement as t_root_el, runAwait as t_run_await, runControlBranch as t_run_branch, runControl as t_run_control, runList as t_run_list, runTry as t_run_try, saveHydration as t_save_hydration, nodeSkip as t_skip, buildStyles as t_style, unmount };
747
+ export { $async, $batch, $bind, $cache, $onmount, $peek, $pending, $refresh, $run, $stream, $unwrap, $watch, type Animation, type Bindable, type ClassValue, type Component, type ListItem, type ListItemSpec, type SlotRender, type StreamSource, type StyleValue, clearLayoutSlot, fillLayoutSlot, fromElement, fromServer, fromWebSocket, hydrate, mount, addElement as t_add_element, addFragment as t_add_fragment, nodeAnchor as t_anchor, addAnimation as t_animate, applyProps as t_apply_props, setAttribute as t_attribute, nodeChild as t_child, buildClasses as t_class, setDynamicElement as t_dynamic, addEvent as t_event, firstInsideNode as t_first_inside, formatText as t_fmt, getFragment as t_fragment, getElementFragment as t_fragment_el, headElement as t_head_element, newListItem as t_list_item, nodeNext as t_next, popRegion as t_pop_region, pushRegion as t_push_region, newRegion as t_region, rerunRegionEffects as t_rerun_region_effects, restoreHydration as t_restore_hydration, nodeRoot as t_root, nodeRootElement as t_root_el, runAwait as t_run_await, runControlBranch as t_run_branch, runControl as t_run_control, runList as t_run_list, runTry as t_run_try, saveHydration as t_save_hydration, nodeSkip as t_skip, buildStyles as t_style, unmount };
722
748
  //# sourceMappingURL=index.d.mts.map