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">
import Composite from './Composite.svelte';
import components from '$lib/componentLoader';
import services from '$lib/servicesLoader';
import { createComponentStore, getComponentStore } from '$lib/stores/componentStores.ts';
export let componentsData = {
@ -9,7 +10,6 @@
};
function initializeComponentState(child) {
// This will either retrieve the existing store or create a default one
child.store = createComponentStore(child.id, child.state || {});
if (child.children) {
@ -37,11 +37,10 @@
localStore.update((storeValue) => {
storeValue = storeValue || {};
if (storeValue[localKey] !== externalState[externalKey]) {
// Only update if there's a change
storeValue[localKey] = externalState[externalKey];
return storeValue;
}
return storeValue; // Return existing state if no change
return storeValue;
});
}
});
@ -65,14 +64,43 @@
}
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>
<div class="grid w-full h-full" style="display: grid; {componentsData.layout || ''}">
{#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}
<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}
<div class="flex justify-end p-4">
@ -88,7 +116,6 @@
</div>
{/if}
<!-- Recursive rendering of children -->
{#if component.children && component.children.length}
<Composite componentsData={component} />
{/if}

View File

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

View File

@ -2,9 +2,19 @@
export let id;
import { getComponentStore } from '$lib/stores/componentStores.ts';
import { onMount } from 'svelte';
const store = getComponentStore(id);
$: console.log('store:', $store);
export let setupLitProvider;
let provider;
onMount(async () => {
provider = await setupLitProvider.setupLitProvider();
console.log('provider ' + JSON.stringify(provider));
});
</script>
<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:
"auth",
"login",
"play"
"play",
"hello"
grid-template-rows: auto 1fr 1fr;
`,
children: [
@ -26,9 +27,10 @@
}
},
{
id: 'login1',
id: 'hello',
componentName: 'GoogleAuth',
slot: 'login'
slot: 'hello',
services: ['setupLitProvider']
}
]
};

View File

@ -19,6 +19,21 @@ function getRecursiveSvelteFiles(dir) {
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({
plugins: [
sveltekit(),
@ -45,6 +60,30 @@ export default defineConfig({
}
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: {