summaryrefslogtreecommitdiff
path: root/packages/integrations/solid/src/client.ts
diff options
context:
space:
mode:
authorGravatar Matt Kane <m@mk.gg> 2024-09-18 16:42:44 +0100
committerGravatar Matt Kane <m@mk.gg> 2024-09-18 16:43:14 +0100
commitb0827022afa52a13d49c37c6c549212aecd32cc5 (patch)
tree41e34f22f8fa388ca78e62a2ee802367d7e3cf42 /packages/integrations/solid/src/client.ts
parent837ee3a4aa6b33362bd680d4a7fc786ed8639444 (diff)
parent8d4eb95086ae79339764d02215f84f4f21b96edc (diff)
downloadastro-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.ts67
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 });
+ }
};