From e2ea57e89f203d41163e888a5d83bfccf6930163 Mon Sep 17 00:00:00 2001 From: Samuel Andert Date: Thu, 27 Jul 2023 10:51:52 +0200 Subject: [PATCH] fixed the racecondition of the composite services renderer --- src/lib/components/GoogleAuth.svelte | 2 +- .../components/HelloEarth/HelloEarth.svelte | 1 + src/lib/core/Composite.svelte | 143 +++++++++--------- src/routes/+layout.svelte | 4 + 4 files changed, 77 insertions(+), 73 deletions(-) diff --git a/src/lib/components/GoogleAuth.svelte b/src/lib/components/GoogleAuth.svelte index 037aa92..3ea2e88 100644 --- a/src/lib/components/GoogleAuth.svelte +++ b/src/lib/components/GoogleAuth.svelte @@ -6,7 +6,7 @@ import { createMessage } from '$lib/services/messages/messages'; import { createLitSession } from '$lib/services/createLitSession/createLitSession'; - const redirectUri = 'http://localhost:5173/login'; + const redirectUri = 'http://localhost:5173/login/'; export let services; diff --git a/src/lib/components/HelloEarth/HelloEarth.svelte b/src/lib/components/HelloEarth/HelloEarth.svelte index 86c66a5..fc2a6d2 100644 --- a/src/lib/components/HelloEarth/HelloEarth.svelte +++ b/src/lib/components/HelloEarth/HelloEarth.svelte @@ -3,6 +3,7 @@ export let store; let isStoreLoaded = false; + $: console.log('store: ' + JSON.stringify($store)); $: if (services && services.helloEarthAlert) { // services.helloEarthAlert.alertMe(); diff --git a/src/lib/core/Composite.svelte b/src/lib/core/Composite.svelte index f65114a..dbc072b 100644 --- a/src/lib/core/Composite.svelte +++ b/src/lib/core/Composite.svelte @@ -6,6 +6,14 @@ import { dataStore } from '$lib/core/dataLoader'; import { createCompositeStore, getCompositeStore } from '$lib/core/compositeStores'; + interface ICompositeLayout { + areas: string; + columns?: string; + rows?: string; + gap?: string; + tailwindClasses?: string; + } + interface IComposite { layout?: ICompositeLayout; id: string; @@ -15,14 +23,7 @@ map?: Record; store?: Record; children?: IComposite[]; - } - - interface ICompositeLayout { - areas: string; - columns?: string; - rows?: string; - gap?: string; - tailwindClasses?: string; + servicesLoaded?: boolean; } export let composite: IComposite; @@ -30,39 +31,49 @@ let layoutStyle = ''; $: { - // Create layout style reactively layoutStyle = computeLayoutStyle(composite?.layout); - // Load services reactively - if (composite?.services) { - for (const serviceName of composite.services) { - if (!loadedServices[serviceName]) { - // Note: We're ignoring async operation here, you might want to handle it if needed - loadService(serviceName).then((service) => { - loadedServices[serviceName] = service; - }); - } - } - } + initializeAndLoadServices(composite); + initializeCompositeState(composite); + mapAndSubscribe(composite); - // Initialize composite state reactively if (composite?.children) { composite.children.forEach((child) => { - initializeCompositeState(child); + initializeAndLoadServices(child); mapAndSubscribe(child); }); } } - function computeLayoutStyle(layout?: ICompositeLayout) { + function computeLayoutStyle(layout?: ICompositeLayout): string { if (!layout) return ''; - return ` - grid-template-areas: ${layout.areas}; - ${layout.gap ? `gap: ${layout.gap};` : ''} - ${layout.columns ? `grid-template-columns: ${layout.columns};` : ''} - ${layout.rows ? `grid-template-rows: ${layout.rows};` : ''} - `; + grid-template-areas: ${layout.areas}; + ${layout.gap ? `gap: ${layout.gap};` : ''} + ${layout.columns ? `grid-template-columns: ${layout.columns};` : ''} + ${layout.rows ? `grid-template-rows: ${layout.rows};` : ''} + `; + } + + function initializeAndLoadServices(component: IComposite) { + if (!component) return; + + if (component.services) { + let servicePromises = component.services.map((serviceName) => + loadedServices[serviceName] + ? Promise.resolve(loadedServices[serviceName]) + : loadService(serviceName) + ); + + Promise.all(servicePromises).then((loaded) => { + loaded.forEach((service, index) => { + loadedServices[component.services[index]] = service; + }); + component.servicesLoaded = true; + }); + } else { + component.servicesLoaded = true; + } } function initializeCompositeState(child: IComposite) { @@ -78,8 +89,6 @@ let unsubscribers = []; function mapAndSubscribe(component: IComposite) { - console.log('Mapping and subscribing for:', component.id); - if (component.map) { const localStore = getCompositeStore(component.id); @@ -91,15 +100,14 @@ if (externalKey in store) { if (store[externalKey] && typeof store[externalKey].subscribe === 'function') { let innerUnsub = store[externalKey].subscribe((value) => { - localStore.update((storeValue) => { - return { ...storeValue, [localKey]: value }; - }); + localStore.update((storeValue) => ({ ...storeValue, [localKey]: value })); }); unsubscribers.push(innerUnsub); } else { - localStore.update((storeValue) => { - return { ...storeValue, [localKey]: store[externalKey] }; - }); + localStore.update((storeValue) => ({ + ...storeValue, + [localKey]: store[externalKey] + })); } } }); @@ -110,9 +118,10 @@ if (externalStore) { const unsubscribe = externalStore.subscribe((externalState) => { if (externalState && externalKey in externalState) { - localStore.update((storeValue) => { - return { ...storeValue, [localKey]: externalState[externalKey] }; - }); + localStore.update((storeValue) => ({ + ...storeValue, + [localKey]: externalState[externalKey] + })); } }); @@ -127,7 +136,6 @@ } } - // Call all unsubscribe methods when the component is destroyed. onDestroy(() => { unsubscribers.forEach((unsub) => unsub()); }); @@ -148,27 +156,14 @@ return null; } - async function getServiceProps(component: IComposite) { - const loadedServices = {}; - if (component.services) { - for (const serviceName of component.services) { - const loadedService = await loadService(serviceName); - if (loadedService) { - loadedServices[serviceName] = loadedService; - } - } - } - return loadedServices; - } - async function loadComponentAndService(component: IComposite) { - return await Promise.all([getComponent(component.component), getServiceProps(component)]); + return await getComponent(component.component); }
- {#if composite && 'component' in composite} - {#await loadComponentAndService(composite) then [Component]} + {#if composite?.servicesLoaded} + {#await loadComponentAndService(composite) then Component} {#if Component} - {:else if composite.component} + {:else}

Component {composite.component} not found.

{/if} {/await} @@ -185,21 +180,25 @@ {#if composite?.children} {#each composite.children as child (child.id)}
- {#await loadComponentAndService(child) then [ChildComponent]} - {#if ChildComponent} - - {#if child.children && child.children.length} - + {#if child.servicesLoaded} + {#await loadComponentAndService(child) then ChildComponent} + {#if ChildComponent} + + {#if child.children && child.children.length} + + {/if} + {:else} +

Component {child.component} not found.

{/if} - {:else if child.component} -

Component {child.component} not found.

- {/if} - {/await} + {/await} + {:else} +

Loading services for child {child.id}...

+ {/if}
{/each} {/if} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index b09788e..751287e 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -10,6 +10,10 @@ import { Drawer, drawerStore } from '@skeletonlabs/skeleton'; import Composite from '$lib/core/Composite.svelte'; + const providerData = { + walletConnectId: import.meta.env.VITE_WALLETCONNECT_ID + }; + onMount(() => { initChainProvider(providerData); });