diff options
author | 2024-09-18 16:42:44 +0100 | |
---|---|---|
committer | 2024-09-18 16:43:14 +0100 | |
commit | b0827022afa52a13d49c37c6c549212aecd32cc5 (patch) | |
tree | 41e34f22f8fa388ca78e62a2ee802367d7e3cf42 /packages/integrations/solid/src/client.ts | |
parent | 837ee3a4aa6b33362bd680d4a7fc786ed8639444 (diff) | |
parent | 8d4eb95086ae79339764d02215f84f4f21b96edc (diff) | |
download | astro-b0827022afa52a13d49c37c6c549212aecd32cc5.tar.gz astro-b0827022afa52a13d49c37c6c549212aecd32cc5.tar.zst astro-b0827022afa52a13d49c37c6c549212aecd32cc5.zip |
Merge branch 'main' into next
Diffstat (limited to 'packages/integrations/solid/src/client.ts')
-rw-r--r-- | packages/integrations/solid/src/client.ts | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/packages/integrations/solid/src/client.ts b/packages/integrations/solid/src/client.ts index a47c5310d..f2020bb56 100644 --- a/packages/integrations/solid/src/client.ts +++ b/packages/integrations/solid/src/client.ts @@ -1,10 +1,12 @@ import { Suspense } from 'solid-js'; +import { createStore, reconcile } from 'solid-js/store'; import { createComponent, hydrate, render } from 'solid-js/web'; +const alreadyInitializedElements = new WeakMap<Element, any>(); + export default (element: HTMLElement) => (Component: any, props: any, slotted: any, { client }: { client: string }) => { if (!element.hasAttribute('ssr')) return; - const isHydrate = client !== 'only'; const bootstrap = isHydrate ? hydrate : render; @@ -32,31 +34,44 @@ export default (element: HTMLElement) => const { default: children, ...slots } = _slots; const renderId = element.dataset.solidRenderId; + if (alreadyInitializedElements.has(element)) { + // update the mounted component + alreadyInitializedElements.get(element)!( + // reconcile will make sure to apply as little updates as possible, and also remove missing values w/o breaking reactivity + reconcile({ + ...props, + ...slots, + children, + }), + ); + } else { + const [store, setStore] = createStore({ + ...props, + ...slots, + children, + }); + // store the function to update the current mounted component + alreadyInitializedElements.set(element, setStore); - const dispose = bootstrap( - () => { - const inner = () => - createComponent(Component, { - ...props, - ...slots, - children, - }); + const dispose = bootstrap( + () => { + const inner = () => createComponent(Component, store); - if (isHydrate) { - return createComponent(Suspense, { - get children() { - return inner(); - }, - }); - } else { - return inner(); - } - }, - element, - { - renderId, - }, - ); - - element.addEventListener('astro:unmount', () => dispose(), { once: true }); + if (isHydrate) { + return createComponent(Suspense, { + get children() { + return inner(); + }, + }); + } else { + return inner(); + } + }, + element, + { + renderId, + }, + ); + element.addEventListener('astro:unmount', () => dispose(), { once: true }); + } }; |