Added dynamic dataLoader importing and fixing race conditions
This commit is contained in:
parent
a3761140bd
commit
371e42e4ee
@ -26,33 +26,43 @@
|
||||
}
|
||||
|
||||
export let composite: IComposite;
|
||||
|
||||
let loadedServices: Record<string, any> = {};
|
||||
let layoutStyle = '';
|
||||
|
||||
// Reactive loading mechanism for services based on composite changes
|
||||
$: if (composite?.services) {
|
||||
composite.services.forEach(async (serviceName) => {
|
||||
if (!loadedServices[serviceName]) {
|
||||
loadedServices[serviceName] = await loadService(serviceName);
|
||||
$: {
|
||||
// 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize composite state reactively
|
||||
if (composite?.children) {
|
||||
composite.children.forEach((child) => {
|
||||
initializeCompositeState(child);
|
||||
mapAndSubscribe(child);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$: layoutStyle = composite?.layout
|
||||
? `
|
||||
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};` : ''}
|
||||
`
|
||||
: '';
|
||||
function computeLayoutStyle(layout?: ICompositeLayout) {
|
||||
if (!layout) return '';
|
||||
|
||||
// Reactive statement to watch changes in the composite prop
|
||||
$: if (composite?.children) {
|
||||
composite.children.forEach((child) => {
|
||||
initializeCompositeState(child);
|
||||
mapAndSubscribe(child);
|
||||
});
|
||||
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) {
|
||||
@ -65,6 +75,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
let unsubscribers = [];
|
||||
|
||||
function mapAndSubscribe(component: IComposite) {
|
||||
console.log('Mapping and subscribing for:', component.id);
|
||||
|
||||
@ -77,14 +89,13 @@
|
||||
if (externalID === 'data') {
|
||||
const unsubscribe = dataStore.subscribe((store) => {
|
||||
if (externalKey in store) {
|
||||
// Check if the data item is a Svelte store
|
||||
if (store[externalKey] && typeof store[externalKey].subscribe === 'function') {
|
||||
let innerUnsub = store[externalKey].subscribe((value) => {
|
||||
localStore.update((storeValue) => {
|
||||
return { ...storeValue, [localKey]: value };
|
||||
});
|
||||
});
|
||||
onDestroy(innerUnsub);
|
||||
unsubscribers.push(innerUnsub);
|
||||
} else {
|
||||
localStore.update((storeValue) => {
|
||||
return { ...storeValue, [localKey]: store[externalKey] };
|
||||
@ -93,7 +104,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
onDestroy(unsubscribe);
|
||||
unsubscribers.push(unsubscribe);
|
||||
} else {
|
||||
const externalStore = getCompositeStore(externalID);
|
||||
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) {
|
||||
if (components[componentName]) {
|
||||
const module = await components[componentName]();
|
||||
|
@ -1,11 +1,30 @@
|
||||
// dataLoader.ts
|
||||
|
||||
import { writable } from 'svelte/store';
|
||||
import { queryMessagesData } from '$lib/data/queryMessages';
|
||||
import { queryTodosData } from '$lib/data/queryTodos';
|
||||
import dataSources from 'virtual:data-sources-list'; // Import the generated list
|
||||
|
||||
// The store that holds the data sets
|
||||
export const dataStore = writable({
|
||||
queryMessages: queryMessagesData,
|
||||
queryTodos: queryTodosData
|
||||
});
|
||||
export const dataStore = writable({});
|
||||
|
||||
// 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);
|
||||
});
|
||||
|
||||
export const queryMessagesData = messages;
|
||||
export const queryMessages = messages;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// $lib/data/queryTodos.ts
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export const queryTodosData = writable([
|
||||
export const queryTodos = writable([
|
||||
{
|
||||
id: "id1",
|
||||
text: "todo 1"
|
||||
|
@ -1,6 +1,6 @@
|
||||
// $lib/services/messages.ts
|
||||
|
||||
import { queryMessagesData } from '$lib/data/queryMessages';
|
||||
import { queryMessages } from '$lib/data/queryMessages';
|
||||
|
||||
// The createMessage function now accepts a messageData parameter.
|
||||
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
|
||||
// and then set the new value back into the store.
|
||||
queryMessagesData.update(oldMessages => [...oldMessages, newMessageObj]);
|
||||
queryMessages.update(oldMessages => [...oldMessages, newMessageObj]);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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({
|
||||
plugins: [
|
||||
sveltekit(),
|
||||
@ -84,6 +100,30 @@ export default defineConfig({
|
||||
}
|
||||
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: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user