Solution (tested and working)
Basically, I created an array of objects with the instance id and data. Use update() instead of set(). I filter the new instance object from the array before adding the same instance's new data.
Code(typescript)
package.json
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
"@tsconfig/svelte": "^2.0.1",
"autoprefixer": "^10.4.7",
"cssnano": "^5.1.10",
"postcss": "^8.4.14",
"svelte": "^3.44.0",
"svelte-check": "^2.2.7",
"svelte-preprocess": "^4.9.8",
"tailwindcss": "^3.0.24",
"tslib": "^2.3.1",
"typescript": "^4.5.4",
"vite": "^2.9.9"
},
"dependencies": {
"swiper": "^8.2.2"
}
Index.html
<body>
<custom-element
id="id_custom_element_987654321"
videoid="987654321"
size="7"
></custom-element>
<script type="module" src="/src/main.ts"></script>
<custom-element
id="id_custom_element_123456789"
videoid="123456789"
size="3"
></custom-element>
<script type="module" src="/src/main.ts"></script>
</body>
main.ts
const embedElements = document.querySelectorAll(
"custom-element"
);
const app = embedElements.forEach((each) => {
// @ts-ignore
const elementId = each.attributes.id;
// @ts-ignore
const videoid = each.attributes.videoid;
if (elementId && videoid) {
return new App({
target: each,
props: {
embedElementId: elementId.value,
embedVideoid: videoid.value,
},
});
}
});
export default app;
helpers.ts
// Svelte helpers
export type CustomStoreFormatType<K> = {
videoid: string;
data: K;
};
export type StoreKeyType<L> = Writable<CustomStoreFormatType<L>[]>;
export const custom_updateStore = <T>(
storeKey: StoreKeyType<T>,
updateValue: CustomStoreFormatType<T>
) => {
storeKey.update((old) => [
...old.filter(
(e) => e.videoid !== updateValue.videoid
),
{ ...updateValue },
]);
};
export const custom_getStore = <T>(
storeKey: CustomStoreFormatType<T>[],
videoid: string
) => storeKey.find((e) => e.videoid === videoid);
store.ts
type CommonCustomStoreFormatType<T> = Array<CustomStoreFormatType<T>>;
export const store_videoComments = writable<
CommonCustomStoreFormatType<Array<VideoCommentsType>>
>([]);
App.svelte
// passed props
export let embedElementId: string;
export let embedVideoid: string;
setContext("contxt_videoid", embedVideoid);
let videoComments = fetchvideoComments(embedVideoid);
videoComments.then(({ data }) => {
custom_updateStore<VideoCommentsType[]>(store_videoComments, {
videoId: data.id,
data: data.comments,
});
});
</script>
<main>
{#await videoData}
<LoaderCircular --color="green" />
{:then { data }}
<Video />
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
</main>
any other component (get store instance value)
import { store_videoComments } from "./store";
const videoId = getContext("contxt_videoId");
let { data } = custom_getStore(
$store_videoComments,
videoId as string
);
Output - logging $store_videoComments
[
{
"videoId": "987654321",
"data": "[data1,data2,data3]"
},
{
"videoId": "123456789",
"data": "[data63,data74,data88]"
}
]
As you can see from the log, all app instance's values are stored. Let me know in the comments if you've found any issues with the above method OR know/used a better alternative for all this.
Note:
- I wanted to keep the build size as low as possible so didn't search/include any 3rd party packages to tackle the issue.
- I have not used SvelteKit
- same posted on github-svelte-discussion