diff --git a/packages/svelte/src/internal/client/hydratable.js b/packages/svelte/src/internal/client/hydratable.js index 9628bdb1dd..780bbed37c 100644 --- a/packages/svelte/src/internal/client/hydratable.js +++ b/packages/svelte/src/internal/client/hydratable.js @@ -1,4 +1,4 @@ -/** @import { Parse, Transport } from '#shared' */ +/** @import { Decode, Transport } from '#shared' */ import { hydrating } from './dom/hydration.js'; /** @@ -19,13 +19,13 @@ export function hydratable(key, fn, options = {}) { // something to be synchronously hydratable and then have it not be return fn(); } - return parse(val, options.transport?.parse); + return parse(val, options.transport?.decode); } /** * @template T * @param {string} key - * @param {{ parse?: Parse }} [options] + * @param {{ parse?: Decode }} [options] * @returns {T | undefined} */ export function get_hydratable_value(key, options = {}) { @@ -57,10 +57,10 @@ export function has_hydratable_value(key) { /** * @template T - * @param {string} val - * @param {Parse | undefined} parse + * @param {unknown} val + * @param {Decode | undefined} parse * @returns {T} */ function parse(val, parse) { - return (parse ?? ((val) => new Function(`return (${val})`)()))(val); + return (parse ?? ((val) => /** @type {T} */ (val)))(val); } diff --git a/packages/svelte/src/internal/server/hydratable.js b/packages/svelte/src/internal/server/hydratable.js index d538cfdb32..2d6600a7ae 100644 --- a/packages/svelte/src/internal/server/hydratable.js +++ b/packages/svelte/src/internal/server/hydratable.js @@ -1,4 +1,4 @@ -/** @import { Stringify, Transport } from '#shared' */ +/** @import { Encode, Transport } from '#shared' */ import { get_render_context } from './render-context.js'; @@ -26,14 +26,14 @@ export function hydratable(key, fn, options = {}) { } const result = fn(); - store.hydratables.set(key, { value: result, stringify: options.transport?.stringify }); + store.hydratables.set(key, { value: result, encode: options.transport?.encode }); return result; } /** * @template T * @param {string} key * @param {T} value - * @param {{ stringify?: Stringify }} [options] + * @param {{ encode?: Encode }} [options] */ export function set_hydratable_value(key, value, options = {}) { const store = get_render_context(); @@ -45,6 +45,6 @@ export function set_hydratable_value(key, value, options = {}) { store.hydratables.set(key, { value, - stringify: options.stringify + encode: options.encode }); } diff --git a/packages/svelte/src/internal/server/renderer.js b/packages/svelte/src/internal/server/renderer.js index d4360635c0..5cccbc602b 100644 --- a/packages/svelte/src/internal/server/renderer.js +++ b/packages/svelte/src/internal/server/renderer.js @@ -578,15 +578,15 @@ export class Renderer { /** @type {(value: unknown) => string} */ let default_stringify; - /** @type {[string, string][]} */ + /** @type {[string, unknown][]} */ let entries = []; for (const [k, v] of map) { - const serialize = v.stringify ?? (default_stringify ??= uneval); + const encode = v.encode ?? (default_stringify ??= new MemoizedUneval().uneval); // sequential await is okay here -- all the work is already kicked off - entries.push([k, serialize(await v.value)]); + entries.push([k, encode(await v.value)]); } if (entries.length === 0) return null; - return Renderer.#hydratable_block(JSON.stringify(entries)); + return Renderer.#hydratable_block(entries); } /** @@ -643,23 +643,20 @@ export class Renderer { }; } - /** @param {string} serialized */ + /** @param {[string, unknown][]} serialized */ static #hydratable_block(serialized) { + let entries = ''; + for (const [k, v] of serialized) { + entries += `["${k}",${v}],`; + } // TODO csp? // TODO how can we communicate this error better? Is there a way to not just send it to the console? // (it is probably very rare so... not too worried) return ` `; } diff --git a/packages/svelte/src/internal/server/types.d.ts b/packages/svelte/src/internal/server/types.d.ts index 8eea679069..2cdf2df277 100644 --- a/packages/svelte/src/internal/server/types.d.ts +++ b/packages/svelte/src/internal/server/types.d.ts @@ -1,4 +1,4 @@ -import type { CacheEntry, Stringify } from '#shared'; +import type { CacheEntry, Encode } from '#shared'; import type { Element } from './dev'; import type { Renderer } from './renderer'; @@ -20,7 +20,7 @@ export interface RenderContext { string, { value: unknown; - stringify: Stringify | undefined; + encode: Encode | undefined; } >; cache: Map; diff --git a/packages/svelte/src/internal/shared/types.d.ts b/packages/svelte/src/internal/shared/types.d.ts index f5e3665db6..89cb28f6ec 100644 --- a/packages/svelte/src/internal/shared/types.d.ts +++ b/packages/svelte/src/internal/shared/types.d.ts @@ -11,18 +11,18 @@ export type Snapshot = ReturnType>; export type MaybePromise = T | Promise; -export type Parse = (value: string) => T; +export type Decode = (value: unknown) => T; -export type Stringify = (value: T) => string; +export type Encode = (value: T) => unknown; export type Transport = | { - stringify: Stringify; - parse?: undefined; + encode: Encode; + decode?: undefined; } | { - stringify?: undefined; - parse: Parse; + encode?: undefined; + decode: Decode; }; export type Resource = { diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 5e000126bb..72ec09567e 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -598,18 +598,18 @@ declare module 'svelte' { [K in keyof T]: () => T[K]; }; - type Parse = (value: string) => T; + type Decode = (value: unknown) => T; - type Stringify = (value: T) => string; + type Encode = (value: T) => unknown; type Transport = | { - stringify: Stringify; - parse?: undefined; + encode: Encode; + decode?: undefined; } | { - stringify?: undefined; - parse: Parse; + encode?: undefined; + decode: Decode; }; export {}; @@ -2613,20 +2613,20 @@ declare module 'svelte/server' { type RenderOutput = SyncRenderOutput & PromiseLike; export function setHydratableValue(key: string, value: T, options?: { - stringify?: Stringify; + encode?: Encode; } | undefined): void; - type Stringify = (value: T) => string; + type Encode = (value: T) => unknown; export {}; } declare module 'svelte/client' { export function getHydratableValue(key: string, options?: { - parse?: Parse; + parse?: Decode; } | undefined): T | undefined; export function hasHydratableValue(key: string): boolean; - type Parse = (value: string) => T; + type Decode = (value: unknown) => T; export {}; }