Skip to content
This repository was archived by the owner on Nov 9, 2023. It is now read-only.

Commit 4a945da

Browse files
committed
Add loadResourceTree function
1 parent 4a8ecb5 commit 4a945da

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"publishConfig": {
77
"access": "public"
88
},
9-
"version": "0.34.10",
9+
"version": "0.34.11",
1010
"type": "module",
1111
"exports": {
1212
".": {
@@ -45,7 +45,7 @@
4545
},
4646
"packageManager": "pnpm@7.13.3",
4747
"dependencies": {
48-
"@tomic/lib": "^0.34.9",
48+
"@tomic/lib": "^0.34.11",
4949
"eslint": "^8.30.0",
5050
"svelte": "^3.55.0"
5151
},

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export const initStore = (store: Store) => {
88
export { store } from './stores/store';
99
export { getResource } from './stores/getResource';
1010
export { getValue } from './stores/getValue';
11+
export * from './loadResourceTree';

src/loadResourceTree.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { JSONValue, Resource } from '@tomic/lib';
2+
import { get } from 'svelte/store';
3+
import { store as storeStore } from './stores/store';
4+
5+
export interface ResourceTreeTemplate {
6+
[property: string]: true | ResourceTreeTemplate;
7+
}
8+
9+
const normalize = (value: JSONValue): string[] => {
10+
if (typeof value === 'string') {
11+
return [value];
12+
}
13+
14+
if (Array.isArray(value)) {
15+
return value as string[];
16+
}
17+
18+
return [];
19+
};
20+
21+
/**
22+
* Make sure the given tree of resources are available in the store.
23+
* This is only useful for SSR and SSG as the getResource functions don't wait for the resource to be fully available
24+
* causing SvelteKit to render incomplete pages.
25+
*
26+
* **Example**:
27+
* ```ts
28+
* await loadResourceTree('https://myblog.com', {
29+
* [myProperties.blogPostCollection]: {
30+
* [urls.properties.collection.members]: {
31+
* [myProperties.coverImage]: true,
32+
* [myProperties.author]: true,
33+
* }
34+
* });
35+
* ```
36+
*/
37+
export const loadResourceTree = async (
38+
subject: string,
39+
treeTemplate: ResourceTreeTemplate,
40+
): Promise<void> => {
41+
const store = get(storeStore);
42+
43+
const loadResourceTreeInner = async (
44+
resource: Resource,
45+
tree: ResourceTreeTemplate,
46+
) => {
47+
const promises: Promise<unknown>[] = [];
48+
49+
for (const [property, branch] of Object.entries(tree)) {
50+
await store.getResourceAsync(property);
51+
const values = normalize(resource.get(property));
52+
const resources = await Promise.all(
53+
values.map(value => store.getResourceAsync(value)),
54+
);
55+
56+
if (typeof branch === 'boolean') {
57+
continue;
58+
}
59+
60+
for (const res of resources) {
61+
promises.push(loadResourceTreeInner(res, branch));
62+
}
63+
}
64+
65+
return Promise.allSettled(promises.flat());
66+
};
67+
68+
const resource = await store.getResourceAsync(subject);
69+
70+
await loadResourceTreeInner(resource, treeTemplate);
71+
};

0 commit comments

Comments
 (0)