;
+ }
+);
diff --git a/packages/svelte/src/internal/shared/utils.js b/packages/svelte/src/internal/shared/utils.js
index 10f8597520..659cd10040 100644
--- a/packages/svelte/src/internal/shared/utils.js
+++ b/packages/svelte/src/internal/shared/utils.js
@@ -48,7 +48,7 @@ export function run_all(arr) {
/**
* TODO replace with Promise.withResolvers once supported widely enough
- * @template T
+ * @template [T=void]
*/
export function deferred() {
/** @type {(value: T) => void} */
diff --git a/packages/svelte/tests/runtime-runes/samples/hydratables/_config.js b/packages/svelte/tests/runtime-runes/samples/hydratables/_config.js
new file mode 100644
index 0000000000..b7622279e3
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/hydratables/_config.js
@@ -0,0 +1,19 @@
+import { tick } from 'svelte';
+import { ok, test } from '../../test';
+
+export default test({
+ skip_mode: ['server'],
+
+ server_props: { environment: 'server' },
+ ssrHtml: 'The current environment is: server
',
+
+ props: { environment: 'browser' },
+ html: 'The current environment is: server
',
+
+ async test({ assert, target }) {
+ await tick();
+ const p = target.querySelector('p');
+ ok(p);
+ assert.htmlEqual(p.outerHTML, 'The current environment is: server
');
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/hydratables/main.svelte b/packages/svelte/tests/runtime-runes/samples/hydratables/main.svelte
new file mode 100644
index 0000000000..53b9c24f91
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/hydratables/main.svelte
@@ -0,0 +1,9 @@
+
+
+The current environment is: {value}
diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts
index 5e3ca77eb5..fcefe8e309 100644
--- a/packages/svelte/types/index.d.ts
+++ b/packages/svelte/types/index.d.ts
@@ -450,6 +450,7 @@ declare module 'svelte' {
* @deprecated Use [`$effect`](https://svelte.dev/docs/svelte/$effect) instead
* */
export function afterUpdate(fn: () => void): void;
+ export const hydratable: Hydratable;
/**
* Create a snippet programmatically
* */
@@ -595,6 +596,27 @@ declare module 'svelte' {
[K in keyof T]: () => T[K];
};
+ type Decode = (value: any) => T;
+
+ type Encode = (value: T) => string;
+
+ type Transport =
+ | {
+ encode: Encode;
+ decode?: undefined;
+ }
+ | {
+ encode?: undefined;
+ decode: Decode;
+ };
+
+ type Hydratable = {
+ (key: string, fn: () => T, options?: { transport?: Transport }): T;
+ get: (key: string, options?: { decode?: Decode }) => T | undefined;
+ has: (key: string) => boolean;
+ set: (key: string, value: T, options?: { encode?: Encode }) => void;
+ };
+
export {};
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0afaef0ceb..0b1f57213d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -89,6 +89,9 @@ importers:
clsx:
specifier: ^2.1.1
version: 2.1.1
+ devalue:
+ specifier: ^5.5.0
+ version: 5.5.0
esm-env:
specifier: ^1.2.1
version: 1.2.1
@@ -1515,6 +1518,9 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
+ devalue@5.5.0:
+ resolution: {integrity: sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==}
+
dir-glob@3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
@@ -3990,6 +3996,8 @@ snapshots:
detect-libc@1.0.3:
optional: true
+ devalue@5.5.0: {}
+
dir-glob@3.0.1:
dependencies:
path-type: 4.0.0