feat(components): Initialize component state and enable property mapping
- Ensure every component has an initialized state, defaulting to empty. - Implement property mapping to synchronize states between parent and child components.
This commit is contained in:
parent
5b7c49fd58
commit
e12f6bcf05
@ -1,17 +1,67 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Composite from './Composite.svelte'; // Recursive import
|
import Composite from './Composite.svelte';
|
||||||
import components from '$lib/componentLoader';
|
import components from '$lib/componentLoader';
|
||||||
import { getContextStore } from '$lib/stores/contextStore.ts';
|
import { createComponentStore, getComponentStore } from '$lib/stores/componentStores.ts';
|
||||||
|
|
||||||
export let componentsData = {
|
export let componentsData = {
|
||||||
layout: '',
|
layout: '',
|
||||||
children: []
|
children: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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) {
|
||||||
|
child.children.forEach(initializeComponentState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$: if (componentsData && componentsData.children) {
|
$: if (componentsData && componentsData.children) {
|
||||||
componentsData.children.forEach((child) => {
|
componentsData.children.forEach(initializeComponentState);
|
||||||
child.store = getContextStore(child.componentName);
|
}
|
||||||
});
|
|
||||||
|
function mapAndSubscribe(component) {
|
||||||
|
console.log('Mapping and subscribing for:', component.id); // Debug line
|
||||||
|
|
||||||
|
if (component.map) {
|
||||||
|
const localStore = getComponentStore(component.id);
|
||||||
|
|
||||||
|
// Use the subscribe method to log and work with the store's value
|
||||||
|
localStore.subscribe((localStoreValue) => {
|
||||||
|
console.log('Local store before mapping:', localStoreValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [localKey, external] of Object.entries(component.map)) {
|
||||||
|
const [externalID, externalKey] = external.split('.').map((item) => item.trim());
|
||||||
|
const externalStore = getComponentStore(externalID);
|
||||||
|
if (externalStore) {
|
||||||
|
externalStore.subscribe((externalState) => {
|
||||||
|
console.log('External state:', externalState); // Debug line
|
||||||
|
if (externalState && externalKey in externalState) {
|
||||||
|
localStore.update((storeValue) => {
|
||||||
|
storeValue = storeValue || {};
|
||||||
|
storeValue[localKey] = externalState[externalKey];
|
||||||
|
return storeValue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the subscribe method again if you want to log after mapping
|
||||||
|
localStore.subscribe((localStoreValue) => {
|
||||||
|
console.log('Local store after mapping:', localStoreValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.children) {
|
||||||
|
component.children.forEach(mapAndSubscribe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if (componentsData && componentsData.children) {
|
||||||
|
componentsData.children.forEach(mapAndSubscribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getComponent(componentName) {
|
async function getComponent(componentName) {
|
||||||
@ -23,12 +73,14 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- Rest of the component markup remains unchanged -->
|
||||||
|
|
||||||
<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 getComponent(component.componentName) then Component}
|
||||||
{#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} {...component.props} />
|
<svelte:component this={Component} id={component.id} {...component.props} />
|
||||||
|
|
||||||
{#if component.actions}
|
{#if component.actions}
|
||||||
<div class="flex justify-end p-4">
|
<div class="flex justify-end p-4">
|
||||||
|
@ -1 +1,10 @@
|
|||||||
<div class="p-12 bg-blue-400">Hello Earth</div>
|
<script>
|
||||||
|
export let id;
|
||||||
|
|
||||||
|
import { getComponentStore } from '$lib/stores/componentStores.ts';
|
||||||
|
|
||||||
|
const store = getComponentStore(id);
|
||||||
|
$: console.log('store:', $store);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="p-12 bg-blue-400">Hello Earth {JSON.stringify($store)}</div>
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { connectWallet } from '$lib/services/wallet/wallet';
|
import { connectWallet } from '$lib/services/wallet/wallet';
|
||||||
|
|
||||||
|
import { getComponentStore } from '$lib/stores/componentStores.ts';
|
||||||
|
|
||||||
|
// please abstract this.
|
||||||
|
export let id;
|
||||||
|
const store = getComponentStore(id);
|
||||||
|
|
||||||
let pkpWallet = null;
|
let pkpWallet = null;
|
||||||
|
|
||||||
const pkpPubKey =
|
|
||||||
'046da3ba67065fd1e2726242ca01cd4601524893f4aa4b0042578fa6cbec28fa8c9a28eb9f7893932fc09717edc9e1db57e157a21eed346247c1db5a722a01f571';
|
|
||||||
|
|
||||||
// Specify your RPC URL here
|
|
||||||
const rpcURL = 'https://rpc.gnosischain.com/';
|
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
pkpWallet = await connectWallet(pkpPubKey, rpcURL);
|
pkpWallet = await connectWallet($store.pkpPubKey, $store.rpcURL);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
0
src/lib/services/authWithGoogle.ts
Normal file
0
src/lib/services/authWithGoogle.ts
Normal file
16
src/lib/stores/componentStores.ts
Normal file
16
src/lib/stores/componentStores.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
|
const componentStores = new Map();
|
||||||
|
|
||||||
|
// Create or retrieve a component store
|
||||||
|
export function createComponentStore(componentId, initialState = {}) {
|
||||||
|
if (!componentStores.has(componentId)) {
|
||||||
|
componentStores.set(componentId, writable(initialState));
|
||||||
|
}
|
||||||
|
return componentStores.get(componentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get component store or create a default empty one if not exists
|
||||||
|
export function getComponentStore(componentId) {
|
||||||
|
return componentStores.get(componentId) || createComponentStore(componentId);
|
||||||
|
}
|
@ -11,14 +11,24 @@
|
|||||||
`,
|
`,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 'login1',
|
||||||
componentName: 'Login',
|
componentName: 'Login',
|
||||||
props: {},
|
|
||||||
slot: 'login',
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 5,
|
id: 'wallet1',
|
||||||
componentName: 'Wallet'
|
componentName: 'Wallet',
|
||||||
|
state: {
|
||||||
|
rpcURL: 'https://rpc.gnosischain.com/',
|
||||||
|
pkpPubKey:
|
||||||
|
'046da3ba67065fd1e2726242ca01cd4601524893f4aa4b0042578fa6cbec28fa8c9a28eb9f7893932fc09717edc9e1db57e157a21eed346247c1db5a722a01f571'
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'HelloEarth1',
|
||||||
|
componentName: 'HelloEarth',
|
||||||
|
map: { pkp: 'wallet1.pkpPubKey', rpcURL: 'wallet1.rpcURL' }
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user