Added auto import of services to the composite

This commit is contained in:
Samuel Andert 2023-07-25 11:20:51 +02:00
parent 70fe76279e
commit ab92110970
6 changed files with 101 additions and 13 deletions

View File

@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Composite from './Composite.svelte'; import Composite from './Composite.svelte';
import components from '$lib/componentLoader'; import components from '$lib/componentLoader';
import services from '$lib/servicesLoader';
import { createComponentStore, getComponentStore } from '$lib/stores/componentStores.ts'; import { createComponentStore, getComponentStore } from '$lib/stores/componentStores.ts';
export let componentsData = { export let componentsData = {
@ -9,7 +10,6 @@
}; };
function initializeComponentState(child) { function initializeComponentState(child) {
// This will either retrieve the existing store or create a default one
child.store = createComponentStore(child.id, child.state || {}); child.store = createComponentStore(child.id, child.state || {});
if (child.children) { if (child.children) {
@ -37,11 +37,10 @@
localStore.update((storeValue) => { localStore.update((storeValue) => {
storeValue = storeValue || {}; storeValue = storeValue || {};
if (storeValue[localKey] !== externalState[externalKey]) { if (storeValue[localKey] !== externalState[externalKey]) {
// Only update if there's a change
storeValue[localKey] = externalState[externalKey]; storeValue[localKey] = externalState[externalKey];
return storeValue; return storeValue;
} }
return storeValue; // Return existing state if no change return storeValue;
}); });
} }
}); });
@ -65,14 +64,43 @@
} }
return null; return null;
} }
async function loadService(serviceName) {
if (services[serviceName]) {
const module = await services[serviceName]();
return module.default || module;
}
return null;
}
async function getServiceProps(component) {
const loadedServices = [];
if (component.services) {
for (const serviceName of component.services) {
const loadedService = await loadService(serviceName);
if (loadedService) {
loadedServices.push(loadedService);
}
}
}
return loadedServices;
}
</script> </script>
<div class="grid w-full h-full" style="display: grid; {componentsData.layout || ''}"> <div class="grid w-full h-full" style="display: grid; {componentsData.layout || ''}">
{#each componentsData.children as component (component.id)} {#each componentsData.children as component (component.id)}
{#await getComponent(component.componentName) then Component} {#await Promise.all( [getComponent(component.componentName), getServiceProps(component)] ) then [Component, loadedServices]}
{#if Component} {#if Component}
<div class="w-full h-full overflow-hidden {component.slot}"> <div class="w-full h-full overflow-hidden {component.slot}">
<svelte:component this={Component} id={component.id} {...component.props} /> <svelte:component
this={Component}
id={component.id}
{...component.props}
{...loadedServices.reduce((acc, currFn, idx) => {
acc[component.services[idx]] = currFn;
return acc;
}, {})}
/>
{#if component.actions} {#if component.actions}
<div class="flex justify-end p-4"> <div class="flex justify-end p-4">
@ -88,7 +116,6 @@
</div> </div>
{/if} {/if}
<!-- Recursive rendering of children -->
{#if component.children && component.children.length} {#if component.children && component.children.length}
<Composite componentsData={component} /> <Composite componentsData={component} />
{/if} {/if}

View File

@ -5,7 +5,7 @@
import { ProviderType } from '@lit-protocol/constants'; import { ProviderType } from '@lit-protocol/constants';
import { LitAccessControlConditionResource, LitAbility } from '@lit-protocol/auth-helpers'; import { LitAccessControlConditionResource, LitAbility } from '@lit-protocol/auth-helpers';
import { createMessage } from '$lib/services/messages'; import { createMessage } from '$lib/services/messages';
import { setupLitProvider } from '$lib/services/provider/setupLitProvider'; // import { setupLitProvider } from '$lib/services/provider/setupLitProvider.ts';
const redirectUri = 'http://localhost:5173/'; const redirectUri = 'http://localhost:5173/';
let view = 'sign_in'; let view = 'sign_in';
@ -17,9 +17,12 @@
let sessionSigs; let sessionSigs;
let isLoading = false; let isLoading = false;
export let setupLitProvider;
let provider; let provider;
onMount(async () => { onMount(async () => {
provider = await setupLitProvider.setupLitProvider();
isLoading = true; isLoading = true;
console.log('Component mounted.'); console.log('Component mounted.');
createMessage({ createMessage({
@ -29,9 +32,6 @@
}); });
try { try {
// Globally set the provider during the component's mount
provider = await setupLitProvider();
console.log('Checking if isSignInRedirect...'); console.log('Checking if isSignInRedirect...');
if (!authMethod && isSignInRedirect(redirectUri)) { if (!authMethod && isSignInRedirect(redirectUri)) {
console.log('Redirect detected, handling...'); console.log('Redirect detected, handling...');

View File

@ -2,9 +2,19 @@
export let id; export let id;
import { getComponentStore } from '$lib/stores/componentStores.ts'; import { getComponentStore } from '$lib/stores/componentStores.ts';
import { onMount } from 'svelte';
const store = getComponentStore(id); const store = getComponentStore(id);
$: console.log('store:', $store); $: console.log('store:', $store);
export let setupLitProvider;
let provider;
onMount(async () => {
provider = await setupLitProvider.setupLitProvider();
console.log('provider ' + JSON.stringify(provider));
});
</script> </script>
<div class="p-12 bg-blue-400">Hello Earth {JSON.stringify($store)}</div> <div class="p-12 bg-blue-400">Hello Earth {JSON.stringify($store)}</div>

10
src/lib/servicesLoader.ts Normal file
View File

@ -0,0 +1,10 @@
import serviceNames from 'virtual:services-list';
const services = {};
serviceNames.forEach(path => {
const name = path.split('/').pop().replace('.ts', ''); // Extract just the file name from the path without .ts
services[name] = () => import(/* @vite-ignore */ `/src/lib/services/${path}`);
});
export default services;

View File

@ -6,7 +6,8 @@
grid-template-areas: grid-template-areas:
"auth", "auth",
"login", "login",
"play" "play",
"hello"
grid-template-rows: auto 1fr 1fr; grid-template-rows: auto 1fr 1fr;
`, `,
children: [ children: [
@ -26,9 +27,10 @@
} }
}, },
{ {
id: 'login1', id: 'hello',
componentName: 'GoogleAuth', componentName: 'GoogleAuth',
slot: 'login' slot: 'hello',
services: ['setupLitProvider']
} }
] ]
}; };

View File

@ -19,6 +19,21 @@ function getRecursiveSvelteFiles(dir) {
return files; return files;
} }
function getRecursiveServiceFiles(dir) {
const dirents = fs.readdirSync(dir, { withFileTypes: true });
const files = Array.from(dirents).flatMap((dirent) => {
const res = resolve(dir, dirent.name);
if (dirent.isDirectory()) {
return getRecursiveServiceFiles(res);
} else if (res.endsWith('.ts')) {
return [res];
} else {
return [];
}
});
return files;
}
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
sveltekit(), sveltekit(),
@ -45,6 +60,30 @@ export default defineConfig({
} }
return null; return null;
} }
},
{
name: 'services-resolver',
resolveId(source) {
if (source === 'virtual:services-list') return source;
return null;
},
load(id) {
if (id === 'virtual:services-list') {
const servicesDir = resolve(__dirname, 'src/lib/services');
const serviceFiles = getRecursiveServiceFiles(servicesDir);
const services = serviceFiles.map(file =>
file
.replace(servicesDir, '')
.replace(/\.ts$/, '')
.replace(/\\/g, '/') // Fix Windows path separators
.slice(1) // Remove leading "/"
);
return `export default ${JSON.stringify(services)};`;
}
return null;
}
} }
], ],
test: { test: {