@forgebook/sveltekit 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +145 -2
- package/dist/src/app/env.d.ts +8 -0
- package/dist/src/app/env.js +15 -0
- package/dist/src/app/forms.d.ts +68 -0
- package/dist/src/app/forms.js +125 -0
- package/dist/src/app/manifest.d.ts +21 -0
- package/dist/src/app/manifest.js +17 -0
- package/dist/src/app/navigation.d.ts +97 -0
- package/dist/src/app/navigation.js +147 -0
- package/dist/src/app/paths.d.ts +32 -0
- package/dist/src/app/paths.js +56 -0
- package/dist/src/app/state.d.ts +27 -0
- package/dist/src/app/state.js +60 -0
- package/dist/src/app/stores.d.ts +31 -0
- package/dist/src/app/stores.js +36 -0
- package/dist/src/appSettings.d.ts +44 -0
- package/dist/src/appSettings.js +55 -0
- package/dist/src/kitParameters.d.ts +272 -0
- package/dist/src/kitParameters.js +291 -0
- package/dist/src/kitRenderer.d.ts +3 -0
- package/dist/src/kitRenderer.js +254 -0
- package/dist/src/kitStore.d.ts +90 -0
- package/dist/src/kitStore.js +301 -0
- package/dist/src/mountFrame.d.ts +14 -0
- package/dist/src/mountFrame.js +15 -0
- package/dist/src/routeIds.d.ts +44 -0
- package/dist/src/routeIds.js +150 -0
- package/dist/src/routeOrder.d.ts +18 -0
- package/dist/src/routeOrder.js +187 -0
- package/dist/src/stories.d.ts +48 -0
- package/dist/src/stories.js +11 -0
- package/dist/src/storyCode.d.ts +3 -0
- package/dist/src/storyCode.js +9 -0
- package/dist/src/storyPage.d.ts +35 -0
- package/dist/src/storyPage.js +19 -0
- package/dist/src/vite/envModules.d.ts +67 -0
- package/dist/src/vite/envModules.js +181 -0
- package/dist/src/vite/extractDocs.d.ts +14 -0
- package/dist/src/vite/extractDocs.js +20 -0
- package/dist/src/vite/kitPlugin.d.ts +28 -0
- package/dist/src/vite/kitPlugin.js +241 -0
- package/dist/src/vite/kitProject.d.ts +27 -0
- package/dist/src/vite/kitProject.js +176 -0
- package/dist/src/vite/projectFiles.d.ts +14 -0
- package/dist/src/vite/projectFiles.js +70 -0
- package/dist/src/vite/sveltekit.d.ts +26 -0
- package/dist/src/vite/sveltekit.js +39 -0
- package/package.json +113 -3
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `$app/navigation` in a catalogue: `goto` and a link move the story's page (its address, route, params and data),
|
|
3
|
+
* the navigation callbacks run as in the app, and every call is listed among the story's events.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* A story that gives a callback of its own (`parameters.sveltekit.navigation.goto`, as Storybook's SvelteKit names it)
|
|
7
|
+
* has it called with the call's arguments too. The frame's address and history are never touched: they name the story.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { onMount } from "svelte";
|
|
12
|
+
import { currentStore } from "../kitStore.js";
|
|
13
|
+
/**
|
|
14
|
+
* Records a call and hands it to the story's own callback, when it gives one.
|
|
15
|
+
*
|
|
16
|
+
* @param store - the story's page.
|
|
17
|
+
* @param name - the function's name.
|
|
18
|
+
* @param values - what it was called with.
|
|
19
|
+
*/
|
|
20
|
+
const called = (store, name, values) => {
|
|
21
|
+
store.record(name, values);
|
|
22
|
+
const callback = store.kit.navigation[name];
|
|
23
|
+
if (typeof callback === "function")
|
|
24
|
+
Reflect.apply(callback, undefined, values);
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Goes to an address, as a story's page: its route, params and data follow, the navigation callbacks run.
|
|
28
|
+
*
|
|
29
|
+
* @param url - where to go, from the page's address.
|
|
30
|
+
* @param options - the new page's state; the page's data is loaded again at every move.
|
|
31
|
+
* @returns resolves once the page moved; rejects for an address outside the app, as SvelteKit does.
|
|
32
|
+
*/
|
|
33
|
+
export const goto = async (url, options) => {
|
|
34
|
+
const store = currentStore();
|
|
35
|
+
called(store, "goto", options === undefined ? [String(url)] : [String(url), options]);
|
|
36
|
+
const read = options ?? {};
|
|
37
|
+
const moved = await store.navigate("goto", url, read.state === undefined ? {} : { state: read.state });
|
|
38
|
+
if (!moved && new URL(url, store.page().url).origin !== store.page().url.origin)
|
|
39
|
+
throw new Error(`goto cannot go to an address outside the app (${String(url)}): use window.location instead`);
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Loads the page's data again, as when something it depends on changed.
|
|
43
|
+
*
|
|
44
|
+
* @param resource - what changed: an address, a dependency's name, or a test of an address.
|
|
45
|
+
*/
|
|
46
|
+
export const invalidate = async (resource) => {
|
|
47
|
+
const store = currentStore();
|
|
48
|
+
called(store, "invalidate", [typeof resource === "function" ? "(url) => …" : String(resource)]);
|
|
49
|
+
await store.reload();
|
|
50
|
+
};
|
|
51
|
+
/** Loads the page's data again (SvelteKit 2). */
|
|
52
|
+
export const invalidateAll = async () => {
|
|
53
|
+
const store = currentStore();
|
|
54
|
+
called(store, "invalidateAll", []);
|
|
55
|
+
await store.reload();
|
|
56
|
+
};
|
|
57
|
+
/** Loads the page's data again, keeping its state (SvelteKit 3). */
|
|
58
|
+
export const refreshAll = async () => {
|
|
59
|
+
const store = currentStore();
|
|
60
|
+
called(store, "refreshAll", []);
|
|
61
|
+
await store.reload();
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Loads an address's data without going there.
|
|
65
|
+
*
|
|
66
|
+
* @param href - the address.
|
|
67
|
+
*/
|
|
68
|
+
export const preloadData = async (href) => {
|
|
69
|
+
const store = currentStore();
|
|
70
|
+
called(store, "preloadData", [href]);
|
|
71
|
+
try {
|
|
72
|
+
return { type: "loaded", status: 200, data: await store.dataAt(href) };
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
return { type: "error", error };
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Loads a route's code: a story's code is loaded already.
|
|
80
|
+
*
|
|
81
|
+
* @param pathnames - the routes.
|
|
82
|
+
*/
|
|
83
|
+
export const preloadCode = async (...pathnames) => {
|
|
84
|
+
called(currentStore(), "preloadCode", pathnames);
|
|
85
|
+
await Promise.resolve();
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Sets the page's state without a navigation (shallow routing).
|
|
89
|
+
*
|
|
90
|
+
* @param url - the address the state belongs to; recorded.
|
|
91
|
+
* @param state - the page's new state.
|
|
92
|
+
*/
|
|
93
|
+
export const pushState = (url, state) => {
|
|
94
|
+
const store = currentStore();
|
|
95
|
+
called(store, "pushState", [String(url), state]);
|
|
96
|
+
store.setPage({ state });
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Replaces the page's state without a navigation (shallow routing).
|
|
100
|
+
*
|
|
101
|
+
* @param url - the address the state belongs to; recorded.
|
|
102
|
+
* @param state - the page's new state.
|
|
103
|
+
*/
|
|
104
|
+
export const replaceState = (url, state) => {
|
|
105
|
+
const store = currentStore();
|
|
106
|
+
called(store, "replaceState", [String(url), state]);
|
|
107
|
+
store.setPage({ state });
|
|
108
|
+
};
|
|
109
|
+
/** Leaves the scroll as it is after a navigation: a story's page never scrolls on its own. */
|
|
110
|
+
export const disableScrollHandling = () => undefined;
|
|
111
|
+
/**
|
|
112
|
+
* Captures and restores a component's state across the history (SvelteKit 3): a story's history is its own, so there
|
|
113
|
+
* is nothing to restore.
|
|
114
|
+
*/
|
|
115
|
+
export const snapshot = () => undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Runs a callback when the component is drawn, with the page's first navigation, and after every navigation of the
|
|
118
|
+
* story's page. Called while a component is set up.
|
|
119
|
+
*
|
|
120
|
+
* @param callback - the callback.
|
|
121
|
+
*/
|
|
122
|
+
export const afterNavigate = (callback) => {
|
|
123
|
+
const store = currentStore();
|
|
124
|
+
onMount(() => {
|
|
125
|
+
callback(store.enter());
|
|
126
|
+
return store.afterNavigate(callback);
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Runs a callback before every navigation of the story's page, which it may cancel. Called while a component is set up.
|
|
131
|
+
*
|
|
132
|
+
* @param callback - the callback.
|
|
133
|
+
*/
|
|
134
|
+
export const beforeNavigate = (callback) => {
|
|
135
|
+
const store = currentStore();
|
|
136
|
+
onMount(() => store.beforeNavigate(callback));
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Runs a callback as every navigation of the story's page starts; a function it returns runs once it is done. Called
|
|
140
|
+
* while a component is set up.
|
|
141
|
+
*
|
|
142
|
+
* @param callback - the callback.
|
|
143
|
+
*/
|
|
144
|
+
export const onNavigate = (callback) => {
|
|
145
|
+
const store = currentStore();
|
|
146
|
+
onMount(() => store.onNavigate(callback));
|
|
147
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type RouteMatch, type RouteParams } from "../routeIds.ts";
|
|
2
|
+
/** What SvelteKit puts before every path of the app (`paths.base`); empty by default. */
|
|
3
|
+
export declare const base: string;
|
|
4
|
+
/** Where the static files are served from (`paths.assets`), or the base path. */
|
|
5
|
+
export declare const assets: string;
|
|
6
|
+
/**
|
|
7
|
+
* The address of a static file.
|
|
8
|
+
*
|
|
9
|
+
* @param file - the file, from the `static` folder (`favicon.png`).
|
|
10
|
+
*/
|
|
11
|
+
export declare const asset: (file: string) => string;
|
|
12
|
+
/**
|
|
13
|
+
* A route id or a path written as the app's path: a route's params filled in, the base path before it.
|
|
14
|
+
*
|
|
15
|
+
* @param target - a route id (`/blog/[slug]`) or a path, with a search or a hash.
|
|
16
|
+
* @param params - the route's params.
|
|
17
|
+
*/
|
|
18
|
+
export declare const resolve: (target: string, params?: RouteParams) => string;
|
|
19
|
+
/**
|
|
20
|
+
* A route id written as the app's path (SvelteKit 2).
|
|
21
|
+
*
|
|
22
|
+
* @param id - the route id.
|
|
23
|
+
* @param params - its params.
|
|
24
|
+
*/
|
|
25
|
+
export declare const resolveRoute: (id: string, params?: RouteParams) => string;
|
|
26
|
+
/**
|
|
27
|
+
* The project's route an address matches, with its params.
|
|
28
|
+
*
|
|
29
|
+
* @param url - the address, or a path.
|
|
30
|
+
* @returns the route, or `null` when none matches.
|
|
31
|
+
*/
|
|
32
|
+
export declare const match: (url: URL | string) => Promise<RouteMatch | null>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `$app/paths` in a catalogue: the project's base path and assets' path, and the paths SvelteKit writes from them, for
|
|
3
|
+
* SvelteKit 2 (`base`, `assets`, `resolveRoute`) and 3 (`asset`, `resolve`, `match`).
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { appSettings, pageRouteIds } from "../appSettings.js";
|
|
8
|
+
import { PAGE_ORIGIN, routePath } from "../kitParameters.js";
|
|
9
|
+
import { filledRoute, isRouteId, matchRoute } from "../routeIds.js";
|
|
10
|
+
/** What SvelteKit puts before every path of the app (`paths.base`); empty by default. */
|
|
11
|
+
export const base = appSettings().base;
|
|
12
|
+
/** Where the static files are served from (`paths.assets`), or the base path. */
|
|
13
|
+
export const assets = appSettings().assets === "" ? appSettings().base : appSettings().assets;
|
|
14
|
+
/**
|
|
15
|
+
* A path with one leading slash, as a base path is joined to it.
|
|
16
|
+
*
|
|
17
|
+
* @param path - a path, with or without its leading slash (SvelteKit 3 writes none).
|
|
18
|
+
*/
|
|
19
|
+
const rooted = (path) => (path.startsWith("/") ? path : `/${path}`);
|
|
20
|
+
/**
|
|
21
|
+
* The address of a static file.
|
|
22
|
+
*
|
|
23
|
+
* @param file - the file, from the `static` folder (`favicon.png`).
|
|
24
|
+
*/
|
|
25
|
+
export const asset = (file) => `${assets}${rooted(file)}`;
|
|
26
|
+
/**
|
|
27
|
+
* A route id or a path written as the app's path: a route's params filled in, the base path before it.
|
|
28
|
+
*
|
|
29
|
+
* @param target - a route id (`/blog/[slug]`) or a path, with a search or a hash.
|
|
30
|
+
* @param params - the route's params.
|
|
31
|
+
*/
|
|
32
|
+
export const resolve = (target, params = {}) => {
|
|
33
|
+
const end = target.search(/[?#]/);
|
|
34
|
+
const path = end === -1 ? target : target.slice(0, end);
|
|
35
|
+
const rest = end === -1 ? "" : target.slice(end);
|
|
36
|
+
const filled = isRouteId(path) ? filledRoute(path, params) : rooted(path);
|
|
37
|
+
return `${base}${filled}${rest}`;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A route id written as the app's path (SvelteKit 2).
|
|
41
|
+
*
|
|
42
|
+
* @param id - the route id.
|
|
43
|
+
* @param params - its params.
|
|
44
|
+
*/
|
|
45
|
+
export const resolveRoute = (id, params = {}) => resolve(id, params);
|
|
46
|
+
/**
|
|
47
|
+
* The project's route an address matches, with its params.
|
|
48
|
+
*
|
|
49
|
+
* @param url - the address, or a path.
|
|
50
|
+
* @returns the route, or `null` when none matches.
|
|
51
|
+
*/
|
|
52
|
+
export const match = async (url) => {
|
|
53
|
+
await Promise.resolve();
|
|
54
|
+
const address = new URL(url, PAGE_ORIGIN);
|
|
55
|
+
return matchRoute(pageRouteIds(), routePath(address.pathname, base)) ?? null;
|
|
56
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `$app/state` in a catalogue: the page, the navigation under way and whether a new version is out, read from the
|
|
3
|
+
* story's page (`parameters.sveltekit`) and followed by Svelte as SvelteKit's own are.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Each field is read when it is read, from the frame's current story, so a component reading `page.url.pathname`
|
|
7
|
+
* in its markup follows a link the story clicked.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import type { KitNavigation, KitPage } from "../kitParameters.ts";
|
|
12
|
+
/** The page, as `page` from `$app/state` gives it. */
|
|
13
|
+
export declare const page: KitPage;
|
|
14
|
+
/** The navigation under way, as `navigating` from `$app/state` gives it: every field `null` when there is none. */
|
|
15
|
+
export declare const navigating: {
|
|
16
|
+
readonly from: KitNavigation["from"] | null;
|
|
17
|
+
readonly to: KitNavigation["to"] | null;
|
|
18
|
+
readonly type: KitNavigation["type"] | null;
|
|
19
|
+
readonly willUnload: boolean | null;
|
|
20
|
+
readonly delta: number | null;
|
|
21
|
+
readonly complete: Promise<void> | null;
|
|
22
|
+
};
|
|
23
|
+
/** Whether a new version of the app is out: the story's `updated`. */
|
|
24
|
+
export declare const updated: {
|
|
25
|
+
readonly current: boolean;
|
|
26
|
+
check: () => Promise<boolean>;
|
|
27
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { currentStore } from "../kitStore.js";
|
|
2
|
+
/** The page, as `page` from `$app/state` gives it. */
|
|
3
|
+
export const page = {
|
|
4
|
+
get url() {
|
|
5
|
+
return currentStore().page().url;
|
|
6
|
+
},
|
|
7
|
+
get params() {
|
|
8
|
+
return currentStore().page().params;
|
|
9
|
+
},
|
|
10
|
+
get route() {
|
|
11
|
+
return currentStore().page().route;
|
|
12
|
+
},
|
|
13
|
+
get status() {
|
|
14
|
+
return currentStore().page().status;
|
|
15
|
+
},
|
|
16
|
+
get error() {
|
|
17
|
+
return currentStore().page().error;
|
|
18
|
+
},
|
|
19
|
+
get data() {
|
|
20
|
+
return currentStore().page().data;
|
|
21
|
+
},
|
|
22
|
+
get state() {
|
|
23
|
+
return currentStore().page().state;
|
|
24
|
+
},
|
|
25
|
+
get form() {
|
|
26
|
+
return currentStore().page().form;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/** The navigation under way, as `navigating` from `$app/state` gives it: every field `null` when there is none. */
|
|
30
|
+
export const navigating = {
|
|
31
|
+
get from() {
|
|
32
|
+
return currentStore().navigating()?.from ?? null;
|
|
33
|
+
},
|
|
34
|
+
get to() {
|
|
35
|
+
return currentStore().navigating()?.to ?? null;
|
|
36
|
+
},
|
|
37
|
+
get type() {
|
|
38
|
+
return currentStore().navigating()?.type ?? null;
|
|
39
|
+
},
|
|
40
|
+
get willUnload() {
|
|
41
|
+
return currentStore().navigating()?.willUnload ?? null;
|
|
42
|
+
},
|
|
43
|
+
get delta() {
|
|
44
|
+
return currentStore().navigating()?.delta ?? null;
|
|
45
|
+
},
|
|
46
|
+
get complete() {
|
|
47
|
+
return currentStore().navigating()?.complete ?? null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/** Whether a new version of the app is out: the story's `updated`. */
|
|
51
|
+
export const updated = {
|
|
52
|
+
get current() {
|
|
53
|
+
return currentStore().updated();
|
|
54
|
+
},
|
|
55
|
+
check: () => {
|
|
56
|
+
const store = currentStore();
|
|
57
|
+
store.record("updated.check", []);
|
|
58
|
+
return Promise.resolve(store.updated());
|
|
59
|
+
}
|
|
60
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `$app/stores` in a catalogue, for a project on SvelteKit 2: the page, the navigation and the version as Svelte stores,
|
|
3
|
+
* over the same story page as `$app/state`.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* SvelteKit 3 removed the module; a project on SvelteKit 2 still imports it, so the catalogue gives it either way.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import type { KitNavigation, KitPage } from "../kitParameters.ts";
|
|
11
|
+
/** A store a component subscribes to with `$name`. */
|
|
12
|
+
export type Readable<TValue> = {
|
|
13
|
+
/** Calls `run` with the value now and at each change; returns what stops it. */
|
|
14
|
+
readonly subscribe: (run: (value: TValue) => void) => () => void;
|
|
15
|
+
};
|
|
16
|
+
/** The page, as `$page` reads it. */
|
|
17
|
+
export declare const page: Readable<KitPage>;
|
|
18
|
+
/** The navigation under way, or `null`, as `$navigating` reads it. */
|
|
19
|
+
export declare const navigating: Readable<Partial<KitNavigation> | null>;
|
|
20
|
+
/** Whether a new version is out, as `$updated` reads it; `updated.check()` resolves with the same. */
|
|
21
|
+
export declare const updated: Readable<boolean> & {
|
|
22
|
+
readonly check: () => Promise<boolean>;
|
|
23
|
+
};
|
|
24
|
+
/** The three stores, as `getStores()` returns them. */
|
|
25
|
+
export declare const getStores: () => {
|
|
26
|
+
readonly page: Readable<KitPage>;
|
|
27
|
+
readonly navigating: Readable<Partial<KitNavigation> | null>;
|
|
28
|
+
readonly updated: Readable<boolean> & {
|
|
29
|
+
readonly check: () => Promise<boolean>;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { currentStore } from "../kitStore.js";
|
|
2
|
+
/**
|
|
3
|
+
* A store over a value of the story's page.
|
|
4
|
+
*
|
|
5
|
+
* @param read - reads the value from the frame's current story.
|
|
6
|
+
*/
|
|
7
|
+
const readable = (read) => ({
|
|
8
|
+
subscribe: (run) => {
|
|
9
|
+
const store = currentStore();
|
|
10
|
+
let last = read();
|
|
11
|
+
run(last);
|
|
12
|
+
// the page changes alone, the navigation alone: each store runs only for its own value
|
|
13
|
+
return store.subscribe(() => {
|
|
14
|
+
const value = read();
|
|
15
|
+
if (value === last)
|
|
16
|
+
return;
|
|
17
|
+
last = value;
|
|
18
|
+
run(value);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
/** The page, as `$page` reads it. */
|
|
23
|
+
export const page = readable(() => currentStore().page());
|
|
24
|
+
/** The navigation under way, or `null`, as `$navigating` reads it. */
|
|
25
|
+
export const navigating = readable(() => currentStore().navigating());
|
|
26
|
+
/** Whether a new version is out, as `$updated` reads it; `updated.check()` resolves with the same. */
|
|
27
|
+
export const updated = {
|
|
28
|
+
...readable(() => currentStore().updated()),
|
|
29
|
+
check: () => {
|
|
30
|
+
const store = currentStore();
|
|
31
|
+
store.record("updated.check", []);
|
|
32
|
+
return Promise.resolve(store.updated());
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
/** The three stores, as `getStores()` returns them. */
|
|
36
|
+
export const getStores = () => ({ page, navigating, updated });
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the SvelteKit project gives the page: its base path, its assets' path, its version and its routes, read by the
|
|
3
|
+
* Vite plugin and written in the frame's page before any module runs.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Written in the page, not compiled into a module, so a stand-in pre-bundled by Vite reads the same values as the
|
|
7
|
+
* project's own code. A server render has no page: there the plugin writes the same settings into the code it
|
|
8
|
+
* compiles (`SETTINGS_CONSTANT`). Only what SvelteKit itself sends to the browser is there: no environment variable
|
|
9
|
+
* (the public ones are modules of their own, `$env/static/public` and `$app/env/public`).
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
/** The key the frame's page writes the settings under, on `globalThis`. */
|
|
14
|
+
export declare const APP_SETTINGS_KEY = "forgebook.sveltekit.app";
|
|
15
|
+
/** The name the plugin replaces with the settings in the code it compiles (Vite's `define`), for a server render. */
|
|
16
|
+
export declare const SETTINGS_CONSTANT = "__FORGEBOOK_SVELTEKIT_SETTINGS__";
|
|
17
|
+
/** A route of the project, as `$app/manifest` lists it. */
|
|
18
|
+
export type AppRoute = {
|
|
19
|
+
/** The route's id (`/blog/[slug]`). */
|
|
20
|
+
readonly id: string;
|
|
21
|
+
/** Whether it has a page (`+page.svelte`). */
|
|
22
|
+
readonly page: boolean;
|
|
23
|
+
/** Whether it has an endpoint (`+server.ts`). */
|
|
24
|
+
readonly endpoint: boolean;
|
|
25
|
+
};
|
|
26
|
+
/** What the project's configuration and folders give the page. */
|
|
27
|
+
export type KitAppSettings = {
|
|
28
|
+
/** `paths.base`: what SvelteKit puts before every path of the app (`/docs`); empty by default. */
|
|
29
|
+
readonly base: string;
|
|
30
|
+
/** `paths.assets`: where the static files are served from, an absolute URL; empty for the base path. */
|
|
31
|
+
readonly assets: string;
|
|
32
|
+
/** `version.name`, as `$app/env` gives it. */
|
|
33
|
+
readonly version: string;
|
|
34
|
+
/** The project's routes, from `src/routes`. */
|
|
35
|
+
readonly routes: readonly AppRoute[];
|
|
36
|
+
/** The project's static files, from `static`, as paths without their leading slash. */
|
|
37
|
+
readonly staticFiles: readonly string[];
|
|
38
|
+
};
|
|
39
|
+
/** The settings of a page the plugin did not write (a test's): no base path, no routes. */
|
|
40
|
+
export declare const NO_SETTINGS: KitAppSettings;
|
|
41
|
+
/** The settings the frame's page holds, or those the plugin compiled in. */
|
|
42
|
+
export declare const appSettings: () => KitAppSettings;
|
|
43
|
+
/** The ids of the project's routes that have a page: where a link or `goto` can land. */
|
|
44
|
+
export declare const pageRouteIds: () => string[];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the SvelteKit project gives the page: its base path, its assets' path, its version and its routes, read by the
|
|
3
|
+
* Vite plugin and written in the frame's page before any module runs.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Written in the page, not compiled into a module, so a stand-in pre-bundled by Vite reads the same values as the
|
|
7
|
+
* project's own code. A server render has no page: there the plugin writes the same settings into the code it
|
|
8
|
+
* compiles (`SETTINGS_CONSTANT`). Only what SvelteKit itself sends to the browser is there: no environment variable
|
|
9
|
+
* (the public ones are modules of their own, `$env/static/public` and `$app/env/public`).
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
/** The key the frame's page writes the settings under, on `globalThis`. */
|
|
14
|
+
export const APP_SETTINGS_KEY = "forgebook.sveltekit.app";
|
|
15
|
+
/** The name the plugin replaces with the settings in the code it compiles (Vite's `define`), for a server render. */
|
|
16
|
+
export const SETTINGS_CONSTANT = "__FORGEBOOK_SVELTEKIT_SETTINGS__";
|
|
17
|
+
/** The settings of a page the plugin did not write (a test's): no base path, no routes. */
|
|
18
|
+
export const NO_SETTINGS = { base: "", assets: "", version: "", routes: [], staticFiles: [] };
|
|
19
|
+
/** Whether a value is a plain object. */
|
|
20
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21
|
+
/**
|
|
22
|
+
* A text read from the settings, or empty.
|
|
23
|
+
*
|
|
24
|
+
* @param value - the value.
|
|
25
|
+
*/
|
|
26
|
+
const textOf = (value) => (typeof value === "string" ? value : "");
|
|
27
|
+
/**
|
|
28
|
+
* A route read from the settings, or none.
|
|
29
|
+
*
|
|
30
|
+
* @param value - the value.
|
|
31
|
+
*/
|
|
32
|
+
const routeOf = (value) => isRecord(value) && typeof value["id"] === "string"
|
|
33
|
+
? [{ id: value["id"], page: value["page"] === true, endpoint: value["endpoint"] === true }]
|
|
34
|
+
: [];
|
|
35
|
+
/** The settings the frame's page holds, or those the plugin compiled in. */
|
|
36
|
+
export const appSettings = () => {
|
|
37
|
+
const inPage = Reflect.get(globalThis, Symbol.for(APP_SETTINGS_KEY));
|
|
38
|
+
const settings = inPage === undefined && typeof __FORGEBOOK_SVELTEKIT_SETTINGS__ !== "undefined"
|
|
39
|
+
? __FORGEBOOK_SVELTEKIT_SETTINGS__
|
|
40
|
+
: inPage;
|
|
41
|
+
if (!isRecord(settings))
|
|
42
|
+
return NO_SETTINGS;
|
|
43
|
+
const { routes, staticFiles } = settings;
|
|
44
|
+
return {
|
|
45
|
+
base: textOf(settings["base"]),
|
|
46
|
+
assets: textOf(settings["assets"]),
|
|
47
|
+
version: textOf(settings["version"]),
|
|
48
|
+
routes: Array.isArray(routes) ? routes.flatMap(routeOf) : [],
|
|
49
|
+
staticFiles: Array.isArray(staticFiles) ? staticFiles.filter((file) => typeof file === "string") : []
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
/** The ids of the project's routes that have a page: where a link or `goto` can land. */
|
|
53
|
+
export const pageRouteIds = () => appSettings()
|
|
54
|
+
.routes.filter((route) => route.page)
|
|
55
|
+
.map((route) => route.id);
|