Added dynamic dataLoader importing and fixing race conditions
This commit is contained in:
parent
a3761140bd
commit
371e42e4ee
@ -26,34 +26,44 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
export let composite: IComposite;
|
export let composite: IComposite;
|
||||||
|
|
||||||
let loadedServices: Record<string, any> = {};
|
let loadedServices: Record<string, any> = {};
|
||||||
|
let layoutStyle = '';
|
||||||
|
|
||||||
// Reactive loading mechanism for services based on composite changes
|
$: {
|
||||||
$: if (composite?.services) {
|
// Create layout style reactively
|
||||||
composite.services.forEach(async (serviceName) => {
|
layoutStyle = computeLayoutStyle(composite?.layout);
|
||||||
|
|
||||||
|
// Load services reactively
|
||||||
|
if (composite?.services) {
|
||||||
|
for (const serviceName of composite.services) {
|
||||||
if (!loadedServices[serviceName]) {
|
if (!loadedServices[serviceName]) {
|
||||||
loadedServices[serviceName] = await loadService(serviceName);
|
// Note: We're ignoring async operation here, you might want to handle it if needed
|
||||||
}
|
loadService(serviceName).then((service) => {
|
||||||
|
loadedServices[serviceName] = service;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$: layoutStyle = composite?.layout
|
// Initialize composite state reactively
|
||||||
? `
|
if (composite?.children) {
|
||||||
grid-template-areas: ${composite.layout.areas};
|
|
||||||
${composite.layout.gap ? `gap: ${composite.layout.gap};` : ''}
|
|
||||||
${composite.layout.columns ? `grid-template-columns: ${composite.layout.columns};` : ''}
|
|
||||||
${composite.layout.rows ? `grid-template-rows: ${composite.layout.rows};` : ''}
|
|
||||||
`
|
|
||||||
: '';
|
|
||||||
|
|
||||||
// Reactive statement to watch changes in the composite prop
|
|
||||||
$: if (composite?.children) {
|
|
||||||
composite.children.forEach((child) => {
|
composite.children.forEach((child) => {
|
||||||
initializeCompositeState(child);
|
initializeCompositeState(child);
|
||||||
mapAndSubscribe(child);
|
mapAndSubscribe(child);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeLayoutStyle(layout?: ICompositeLayout) {
|
||||||
|
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};` : ''}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
function initializeCompositeState(child: IComposite) {
|
function initializeCompositeState(child: IComposite) {
|
||||||
if (child.id) {
|
if (child.id) {
|
||||||
@ -65,6 +75,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let unsubscribers = [];
|
||||||
|
|
||||||
function mapAndSubscribe(component: IComposite) {
|
function mapAndSubscribe(component: IComposite) {
|
||||||
console.log('Mapping and subscribing for:', component.id);
|
console.log('Mapping and subscribing for:', component.id);
|
||||||
|
|
||||||
@ -77,14 +89,13 @@
|
|||||||
if (externalID === 'data') {
|
if (externalID === 'data') {
|
||||||
const unsubscribe = dataStore.subscribe((store) => {
|
const unsubscribe = dataStore.subscribe((store) => {
|
||||||
if (externalKey in store) {
|
if (externalKey in store) {
|
||||||
// Check if the data item is a Svelte store
|
|
||||||
if (store[externalKey] && typeof store[externalKey].subscribe === 'function') {
|
if (store[externalKey] && typeof store[externalKey].subscribe === 'function') {
|
||||||
let innerUnsub = store[externalKey].subscribe((value) => {
|
let innerUnsub = store[externalKey].subscribe((value) => {
|
||||||
localStore.update((storeValue) => {
|
localStore.update((storeValue) => {
|
||||||
return { ...storeValue, [localKey]: value };
|
return { ...storeValue, [localKey]: value };
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
onDestroy(innerUnsub);
|
unsubscribers.push(innerUnsub);
|
||||||
} else {
|
} else {
|
||||||
localStore.update((storeValue) => {
|
localStore.update((storeValue) => {
|
||||||
return { ...storeValue, [localKey]: store[externalKey] };
|
return { ...storeValue, [localKey]: store[externalKey] };
|
||||||
@ -93,7 +104,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(unsubscribe);
|
unsubscribers.push(unsubscribe);
|
||||||
} else {
|
} else {
|
||||||
const externalStore = getCompositeStore(externalID);
|
const externalStore = getCompositeStore(externalID);
|
||||||
if (externalStore) {
|
if (externalStore) {
|
||||||
@ -105,7 +116,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(unsubscribe);
|
unsubscribers.push(unsubscribe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,6 +127,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call all unsubscribe methods when the component is destroyed.
|
||||||
|
onDestroy(() => {
|
||||||
|
unsubscribers.forEach((unsub) => unsub());
|
||||||
|
});
|
||||||
|
|
||||||
async function getComponent(componentName: string) {
|
async function getComponent(componentName: string) {
|
||||||
if (components[componentName]) {
|
if (components[componentName]) {
|
||||||
const module = await components[componentName]();
|
const module = await components[componentName]();
|
||||||
|
@ -1,11 +1,30 @@
|
|||||||
// dataLoader.ts
|
// dataLoader.ts
|
||||||
|
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import { queryMessagesData } from '$lib/data/queryMessages';
|
import dataSources from 'virtual:data-sources-list'; // Import the generated list
|
||||||
import { queryTodosData } from '$lib/data/queryTodos';
|
|
||||||
|
|
||||||
// The store that holds the data sets
|
// The store that holds the data sets
|
||||||
export const dataStore = writable({
|
export const dataStore = writable({});
|
||||||
queryMessages: queryMessagesData,
|
|
||||||
queryTodos: queryTodosData
|
// Dynamically import the data modules and assign them to the store
|
||||||
|
dataSources.forEach(src => {
|
||||||
|
import(`/src/lib/data/${src}.ts`).then(module => {
|
||||||
|
// Here, explicitly extract the required data or function from the module
|
||||||
|
const moduleData = module[src] || module.default;
|
||||||
|
|
||||||
|
dataStore.update(store => ({ ...store, [src]: moduleData }));
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // dataLoader.ts
|
||||||
|
|
||||||
|
// import { writable } from 'svelte/store';
|
||||||
|
// import { queryMessages } from '$lib/data/queryMessages';
|
||||||
|
// import { queryTodos } from '$lib/data/queryTodos';
|
||||||
|
|
||||||
|
// // The store that holds the data sets
|
||||||
|
// export const dataStore = writable({
|
||||||
|
// queryMessages: queryMessages,
|
||||||
|
// queryTodos: queryTodos
|
||||||
|
// });
|
@ -35,4 +35,4 @@ messages.subscribe(currentMessages => {
|
|||||||
setToLocalStorage('chat-messages', currentMessages);
|
setToLocalStorage('chat-messages', currentMessages);
|
||||||
});
|
});
|
||||||
|
|
||||||
export const queryMessagesData = messages;
|
export const queryMessages = messages;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// $lib/data/queryTodos.ts
|
// $lib/data/queryTodos.ts
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
export const queryTodosData = writable([
|
export const queryTodos = writable([
|
||||||
{
|
{
|
||||||
id: "id1",
|
id: "id1",
|
||||||
text: "todo 1"
|
text: "todo 1"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// $lib/services/messages.ts
|
// $lib/services/messages.ts
|
||||||
|
|
||||||
import { queryMessagesData } from '$lib/data/queryMessages';
|
import { queryMessages } from '$lib/data/queryMessages';
|
||||||
|
|
||||||
// The createMessage function now accepts a messageData parameter.
|
// The createMessage function now accepts a messageData parameter.
|
||||||
export function createMessage(messageData) {
|
export function createMessage(messageData) {
|
||||||
@ -15,78 +15,9 @@ export function createMessage(messageData) {
|
|||||||
|
|
||||||
// We use the $ prefix to get the value out of a Svelte store
|
// We use the $ prefix to get the value out of a Svelte store
|
||||||
// and then set the new value back into the store.
|
// and then set the new value back into the store.
|
||||||
queryMessagesData.update(oldMessages => [...oldMessages, newMessageObj]);
|
queryMessages.update(oldMessages => [...oldMessages, newMessageObj]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearMessages() {
|
export function clearMessages() {
|
||||||
queryMessagesData.set([]);
|
queryMessages.set([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// import { writable } from 'svelte/store';
|
|
||||||
|
|
||||||
// // Helper function to determine if we're running on the client side (browser) or server side.
|
|
||||||
// function isClientSide() {
|
|
||||||
// return typeof window !== "undefined";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Safely get item from localStorage
|
|
||||||
// function getFromLocalStorage(key, defaultValue) {
|
|
||||||
// if (isClientSide()) {
|
|
||||||
// return localStorage.getItem(key)
|
|
||||||
// ? JSON.parse(localStorage.getItem(key))
|
|
||||||
// : defaultValue;
|
|
||||||
// }
|
|
||||||
// return defaultValue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Safely set item to localStorage
|
|
||||||
// function setToLocalStorage(key, value) {
|
|
||||||
// if (isClientSide()) {
|
|
||||||
// localStorage.setItem(key, JSON.stringify(value));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Define the updated Message interface
|
|
||||||
// export interface Message {
|
|
||||||
// text: string;
|
|
||||||
// timestamp: string;
|
|
||||||
// sender: string;
|
|
||||||
// type: string;
|
|
||||||
// composite?: object | null; // New field
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// // Load messages from localStorage or set an empty array if not available
|
|
||||||
// const initialMessages = getFromLocalStorage('chat-messages', []);
|
|
||||||
|
|
||||||
// // Convert the array to a writable store
|
|
||||||
// export const messages = writable(initialMessages);
|
|
||||||
|
|
||||||
// // Subscribe to messages store to watch for changes and save them to localStorage
|
|
||||||
// messages.subscribe(currentMessages => {
|
|
||||||
// setToLocalStorage('chat-messages', currentMessages);
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
// export function createMessage(messageData) {
|
|
||||||
// const currentDate = new Date().toLocaleString();
|
|
||||||
// const newMessageObj = {
|
|
||||||
// text: messageData.text,
|
|
||||||
// timestamp: currentDate,
|
|
||||||
// sender: messageData.sender,
|
|
||||||
// type: messageData.type,
|
|
||||||
// composite: messageData.composite || null // New field
|
|
||||||
// };
|
|
||||||
// messages.update(oldMessages => [...oldMessages, newMessageObj]);
|
|
||||||
// }
|
|
||||||
// export function clearMessages() {
|
|
||||||
// messages.set([]);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Dummy messages
|
|
||||||
// export const messagesList: Message[] = [
|
|
||||||
// { text: "Hello there!", timestamp: new Date().toLocaleString(), sender: "John", type: "text" },
|
|
||||||
// { text: "How are you?", timestamp: new Date().toLocaleString(), sender: "Alice", type: "text" },
|
|
||||||
// // Add more dummy messages here with the timestamp and sender properties
|
|
||||||
// ];
|
|
||||||
|
@ -34,6 +34,22 @@ function getRecursiveServiceFiles(dir) {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRecursiveDataFiles(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 getRecursiveDataFiles(res);
|
||||||
|
} else if (res.endsWith('.ts')) {
|
||||||
|
return [res];
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
sveltekit(),
|
sveltekit(),
|
||||||
@ -84,6 +100,30 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'data-sources-resolver',
|
||||||
|
resolveId(source) {
|
||||||
|
if (source === 'virtual:data-sources-list') return source;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
load(id) {
|
||||||
|
if (id === 'virtual:data-sources-list') {
|
||||||
|
const dataDir = resolve(__dirname, 'src/lib/data');
|
||||||
|
const dataFiles = getRecursiveServiceFiles(dataDir); // Use the same function as before
|
||||||
|
|
||||||
|
const dataSources = dataFiles.map(file =>
|
||||||
|
file
|
||||||
|
.replace(dataDir, '')
|
||||||
|
.replace(/\.ts$/, '')
|
||||||
|
.replace(/\\/g, '/') // Fix Windows path separators
|
||||||
|
.slice(1) // Remove leading "/"
|
||||||
|
);
|
||||||
|
|
||||||
|
return `export default ${JSON.stringify(dataSources)};`;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
test: {
|
test: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user