diff --git a/documentation/docs/98-reference/.generated/client-errors.md b/documentation/docs/98-reference/.generated/client-errors.md index c17dd843f9..8601a728a7 100644 --- a/documentation/docs/98-reference/.generated/client-errors.md +++ b/documentation/docs/98-reference/.generated/client-errors.md @@ -158,15 +158,17 @@ Cannot create a fork inside an effect or when state changes are pending `getAbortSignal()` can only be called inside an effect or derived ``` -### hydratable_missing_but_expected_e +### hydratable_missing_but_required ``` Expected to find a hydratable with key `%key%` during hydration, but did not. +``` + This can happen if you render a hydratable on the client that was not rendered on the server, and means that it was forced to fall back to running its function blockingly during hydration. This is bad for performance, as it blocks hydration until the asynchronous work completes. + ```svelte `; } - /** @param {[string, string][]} serialized_entries */ - static #used_hydratables(serialized_entries) { + /** @param {HydratableContext['lookup']} lookup */ + static #used_hydratables(lookup) { let entries = []; - for (const [k, v] of serialized_entries) { - entries.push(`[${JSON.stringify(k)},${v}]`); + for (const [k, v] of lookup) { + entries.push(`[${JSON.stringify(k)},${v.root_index}]`); } return ` const store = sv.h ??= new Map(); - for (const [k,v] of [${entries.join(',')}]) { - store.set(k, v); + for (const [k,i] of [${entries.join(',')}]) { + store.set(k, d(i)); }`; } diff --git a/packages/svelte/src/internal/server/types.d.ts b/packages/svelte/src/internal/server/types.d.ts index bd0b41268a..73b2c45182 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 { Encode } from '#shared'; +import type { MaybePromise } from '#shared'; import type { Element } from './dev'; import type { Renderer } from './renderer'; @@ -15,16 +15,19 @@ export interface SSRContext { element?: Element; } -export interface HydratableEntry { +export interface HydratableLookupEntry { value: unknown; - encode: Encode | undefined; - stack?: string; - dev_competing_entries?: Omit[]; + root_index: number; +} + +export interface HydratableContext { + lookup: Map; + values: MaybePromise[]; + unresolved_promises: Map, string>; } export interface RenderContext { - hydratables: Map; - cache: Map>; + hydratable: HydratableContext; } export interface SyncRenderOutput { diff --git a/packages/svelte/src/internal/shared/types.d.ts b/packages/svelte/src/internal/shared/types.d.ts index 21f3f8704d..3374d7bc16 100644 --- a/packages/svelte/src/internal/shared/types.d.ts +++ b/packages/svelte/src/internal/shared/types.d.ts @@ -10,26 +10,3 @@ export type Getters = { export type Snapshot = ReturnType>; export type MaybePromise = T | Promise; - -/** Decode a value. The value will be whatever the evaluated JavaScript emitted by the corresponding {@link Encode} function evaluates to. */ -export type Decode = (value: any) => T; - -/** Encode a value as a string. The string should be _valid JavaScript code_ -- for example, the output of `devalue`'s `uneval` function. */ -export type Encode = (value: T) => string; - -/** - * Custom encode and decode options. This must be used in combination with an environment variable to enable treeshaking, eg: - * ```ts - * import { BROWSER } from 'esm-env'; - * const transport: Transport = BROWSER ? { decode: myDecodeFunction } : { encode: myEncodeFunction }; - * ``` - */ -export type Transport = - | { - encode: Encode; - decode?: undefined; - } - | { - encode?: undefined; - decode: Decode; - }; diff --git a/packages/svelte/tests/runtime-legacy/shared.ts b/packages/svelte/tests/runtime-legacy/shared.ts index b2d33cf922..19483f2e1d 100644 --- a/packages/svelte/tests/runtime-legacy/shared.ts +++ b/packages/svelte/tests/runtime-legacy/shared.ts @@ -105,7 +105,7 @@ export interface RuntimeTest = Record; + h?: Map unknown>; uh?: Set; } | undefined; diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index e7146c03a0..f0200d09fe 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -450,33 +450,7 @@ declare module 'svelte' { * @deprecated Use [`$effect`](https://svelte.dev/docs/svelte/$effect) instead * */ export function afterUpdate(fn: () => void): void; - type Getters = { - [K in keyof T]: () => T[K]; - }; - - /** Decode a value. The value will be whatever the evaluated JavaScript emitted by the corresponding {@link Encode} function evaluates to. */ - export type Decode = (value: any) => T; - - /** Encode a value as a string. The string should be _valid JavaScript code_ -- for example, the output of `devalue`'s `uneval` function. */ - export type Encode = (value: T) => string; - - /** - * Custom encode and decode options. This must be used in combination with an environment variable to enable treeshaking, eg: - * ```ts - * import { BROWSER } from 'esm-env'; - * const transport: Transport = BROWSER ? { decode: myDecodeFunction } : { encode: myEncodeFunction }; - * ``` - */ - export type Transport = - | { - encode: Encode; - decode?: undefined; - } - | { - encode?: undefined; - decode: Decode; - }; - export function hydratable(key: string, fn: () => T, transport?: Transport | undefined): T; + export function hydratable(key: string, fn: () => T): T; /** * Create a snippet programmatically * */ @@ -618,6 +592,9 @@ declare module 'svelte' { * ``` * */ export function untrack(fn: () => T): T; + type Getters = { + [K in keyof T]: () => T[K]; + }; export {}; }