-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat: allow serialization/deserialization of custom data types #13125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 16 commits
9c5aa14
d20bf5d
71abcac
c74e6af
5a08ec0
1e78784
c3eea41
79617ca
6c31b80
3b4fa6d
97e1bb2
65324a6
64db6fe
c478485
005222c
755886c
750d3b7
bae67b0
1f7b31a
8389b7b
66e6b2e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -322,11 +322,17 @@ export async function render_response({ | |
| })`); | ||
|
|
||
| properties.push(`resolve: ({ id, data, error }) => { | ||
| const { fulfil, reject } = deferred.get(id); | ||
| deferred.delete(id); | ||
|
|
||
| if (error) reject(error); | ||
| else fulfil(data); | ||
| const try_to_resolve = () => { | ||
| if (!deferred.has(id)) { | ||
| setTimeout(try_to_resolve, 0); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. was is necessary after all due to the dynamic imports? If so we should add a comment here stating why this is necessary.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this feels suuuuuper hacky, surely we can find another approach? |
||
| return; | ||
| } | ||
| const { fulfil, reject } = deferred.get(id); | ||
| deferred.delete(id); | ||
| if (error) reject(error); | ||
| else fulfil(data); | ||
| } | ||
| try_to_resolve(); | ||
| }`); | ||
| } | ||
|
|
||
|
|
@@ -342,12 +348,11 @@ export async function render_response({ | |
| if (page_config.ssr) { | ||
| const serialized = { form: 'null', error: 'null' }; | ||
|
|
||
| blocks.push(`const data = ${data};`); | ||
|
|
||
| if (form_value) { | ||
| serialized.form = uneval_action_response( | ||
| form_value, | ||
| /** @type {string} */ (event.route.id) | ||
| /** @type {string} */ (event.route.id), | ||
| options.hooks.serialize | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -357,7 +362,7 @@ export async function render_response({ | |
|
|
||
| const hydrate = [ | ||
| `node_ids: [${branch.map(({ node }) => node.index).join(', ')}]`, | ||
| 'data', | ||
| `data: ${data}`, | ||
| `form: ${serialized.form}`, | ||
| `error: ${serialized.error}` | ||
| ]; | ||
|
|
@@ -532,6 +537,7 @@ function get_data(event, options, nodes, csp, global) { | |
| let count = 0; | ||
|
|
||
| const { iterator, push, done } = create_async_iterator(); | ||
| const serializers = options.hooks.serialize; | ||
|
|
||
| /** @param {any} thing */ | ||
| function replacer(thing) { | ||
|
|
@@ -573,6 +579,13 @@ function get_data(event, options, nodes, csp, global) { | |
| ); | ||
|
|
||
| return `${global}.defer(${id})`; | ||
| } else { | ||
| for (const key in serializers) { | ||
| const serialized = serializers[key](thing); | ||
| if (serialized) { | ||
| return `app.deserialize('${key}', ${devalue.uneval(serialized, replacer)})`; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| export class Foo { | ||
| bar() { | ||
| return 'It works!'; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import { Foo } from '../../lib'; | ||
|
|
||
| export function load() { | ||
| return { foo: new Foo() }; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| <script lang="ts"> | ||
| import type { PageData } from './$types'; | ||
|
|
||
| let { data }: { data: PageData } = $props(); | ||
| </script> | ||
|
|
||
| <h1>{data.foo.bar()}</h1> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { Foo } from '../../lib'; | ||
|
|
||
| /** @satisfies {import('./$types').Actions} */ | ||
| export const actions = { | ||
| default: async () => { | ||
| return { foo: new Foo() }; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <script lang="ts"> | ||
| let { form } = $props(); | ||
| </script> | ||
|
|
||
| <form method="POST"> | ||
| <button type="submit">submit</button> | ||
| </form> | ||
|
|
||
| <h1>{form?.foo?.bar()}</h1> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { Foo } from '../../lib'; | ||
|
|
||
| /** @satisfies {import('./$types').Actions} */ | ||
| export const actions = { | ||
| default: async () => { | ||
| return { foo: new Foo() }; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <script lang="ts"> | ||
| import { enhance } from '$app/forms'; | ||
|
|
||
| let { form } = $props(); | ||
| </script> | ||
|
|
||
| <form method="POST" use:enhance> | ||
| <button type="submit">submit</button> | ||
| </form> | ||
|
|
||
| {#if form} | ||
| <h1>{form?.foo?.bar()}</h1> | ||
| {/if} |
Uh oh!
There was an error while loading. Please reload this page.