@kasperrt/smolter 0.3.0 → 0.3.2
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/.generated/client/deployment-check.ts +70 -0
- package/.generated/client/deployment.ts +124 -0
- package/.generated/client/index.ts +9 -1
- package/.generated/core/responses.ts +8 -3
- package/.generated/core/router.ts +32 -0
- package/.generated/core/types.ts +2 -0
- package/.generated/preact/client.tsx +48 -6
- package/.generated/preact/document.tsx +4 -2
- package/.generated/preact/lazy-route.ts +2 -0
- package/.generated/preact/root-context.ts +2 -0
- package/.generated/preact/route-types.ts +1 -0
- package/.generated/preact/router.tsx +9 -3
- package/.generated/server/application.tsx +83 -19
- package/.generated/server/handler.ts +8 -2
- package/.generated/server/http.ts +24 -2
- package/.generated/server/index.ts +17 -5
- package/.generated/server/preact.ts +1 -0
- package/.generated/server/private-response.ts +11 -0
- package/.generated/server/stream-document.ts +121 -0
- package/.generated/vite/application/lazy-files.ts +10 -2
- package/.generated/vite/application/vite.ts +9 -3
- package/.generated/vite/deployment.ts +46 -0
- package/.generated/vite/index.ts +15 -6
- package/.generated/vite/preact.ts +5 -0
- package/.generated/vite/react.ts +5 -0
- package/.generated/vite/transport.ts +4 -1
- package/CHANGELOG.md +19 -0
- package/README.md +79 -11
- package/dist/client/deployment-check.d.ts +6 -0
- package/dist/client/deployment-check.js +51 -0
- package/dist/client/deployment.d.ts +14 -0
- package/dist/client/deployment.js +74 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.js +3 -2
- package/dist/core/responses.d.ts +1 -1
- package/dist/core/responses.js +3 -3
- package/dist/core/router.js +16 -0
- package/dist/core/types.d.ts +2 -0
- package/dist/preact/client.d.ts +6 -1
- package/dist/preact/client.js +27 -7
- package/dist/preact/document.js +4 -2
- package/dist/preact/lazy-route.d.ts +1 -0
- package/dist/preact/lazy-route.js +2 -1
- package/dist/preact/root-context.d.ts +2 -0
- package/dist/preact/route-types.d.ts +1 -0
- package/dist/preact/router.d.ts +1 -1
- package/dist/preact/router.js +3 -3
- package/dist/server/application.d.ts +4 -1
- package/dist/server/application.js +47 -13
- package/dist/server/handler.d.ts +3 -1
- package/dist/server/handler.js +5 -3
- package/dist/server/http.d.ts +5 -1
- package/dist/server/http.js +10 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +12 -2
- package/dist/server/preact.d.ts +1 -1
- package/dist/server/private-response.d.ts +2 -0
- package/dist/server/private-response.js +13 -0
- package/dist/server/stream-document.d.ts +9 -0
- package/dist/server/stream-document.js +78 -0
- package/dist/vite/application/lazy-files.d.ts +1 -1
- package/dist/vite/application/lazy-files.js +6 -2
- package/dist/vite/application/vite.d.ts +2 -1
- package/dist/vite/application/vite.js +7 -4
- package/dist/vite/deployment.d.ts +8 -0
- package/dist/vite/deployment.js +36 -0
- package/dist/vite/index.d.ts +2 -1
- package/dist/vite/index.js +15 -7
- package/dist/vite/preact.d.ts +1 -0
- package/dist/vite/preact.js +2 -1
- package/dist/vite/react.d.ts +1 -0
- package/dist/vite/react.js +2 -1
- package/dist/vite/transport.d.ts +1 -1
- package/dist/vite/transport.js +3 -2
- package/jsr.json +1 -1
- package/package.json +3 -3
package/dist/server/index.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ import { type Route, type Router } from "../core/index.ts";
|
|
|
6
6
|
/** Create one router per server request, await this, then render the provider. */
|
|
7
7
|
export declare function loadRouter(routes: readonly Route[], input: string | Request): Promise<Router>;
|
|
8
8
|
export { serialize } from "../core/index.ts";
|
|
9
|
-
/** Dispatch
|
|
9
|
+
/** Dispatch a server data request with an explicit private cache policy. */
|
|
10
10
|
export declare function handleRequest(routes: readonly Route[], request: Request): Promise<Response>;
|
package/dist/server/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { safeWrapAsync } from "../core/errors.js";
|
|
|
2
2
|
import { matchRoutes } from "../core/match.js";
|
|
3
3
|
import { createDataRouter } from "../core/router.js";
|
|
4
4
|
import { serialize } from "../core/serialize.js";
|
|
5
|
+
import { privateResponse } from "./private-response.js";
|
|
5
6
|
//#region .generated/server/index.ts
|
|
6
7
|
/**
|
|
7
8
|
* Request-scoped server rendering and HTTP data dispatch.
|
|
@@ -46,7 +47,7 @@ async function loadRouter(routes, input) {
|
|
|
46
47
|
return router;
|
|
47
48
|
}
|
|
48
49
|
/** Dispatch an HTTP data request to a registered server loader or action. */
|
|
49
|
-
async function
|
|
50
|
+
async function dispatchRequest(routes, request) {
|
|
50
51
|
const match = matchRoutes(routes, new URL(request.url).pathname);
|
|
51
52
|
const reading = request.method === "GET";
|
|
52
53
|
if (!match) return Response.json({ error: "No route" }, { status: 404 });
|
|
@@ -67,10 +68,19 @@ async function handleRequest(routes, request) {
|
|
|
67
68
|
if (error) return Response.json({ error: error.message }, { status: 500 });
|
|
68
69
|
if (result.data instanceof Response) {
|
|
69
70
|
const location = result.data.headers.get("Location");
|
|
70
|
-
if (location)
|
|
71
|
+
if (location) {
|
|
72
|
+
const headers = new Headers(result.data.headers);
|
|
73
|
+
headers.delete("Location");
|
|
74
|
+
headers.set("X-Smolter-Redirect", location);
|
|
75
|
+
return new Response(null, { headers });
|
|
76
|
+
}
|
|
71
77
|
return result.data;
|
|
72
78
|
}
|
|
73
79
|
return Response.json(result.data ?? null, { headers: { "Cache-Control": "no-store" } });
|
|
74
80
|
}
|
|
81
|
+
/** Dispatch a server data request with an explicit private cache policy. */
|
|
82
|
+
async function handleRequest(routes, request) {
|
|
83
|
+
return privateResponse(await dispatchRequest(routes, request));
|
|
84
|
+
}
|
|
75
85
|
//#endregion
|
|
76
86
|
export { handleRequest, loadRouter, serialize };
|
package/dist/server/preact.d.ts
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region .generated/server/private-response.ts
|
|
2
|
+
/** Transport data must not be cached by shared intermediaries or the browser. */
|
|
3
|
+
function privateResponse(response) {
|
|
4
|
+
const headers = new Headers(response.headers);
|
|
5
|
+
headers.set("Cache-Control", "private, no-store");
|
|
6
|
+
return new Response(response.body, {
|
|
7
|
+
status: response.status,
|
|
8
|
+
statusText: response.statusText,
|
|
9
|
+
headers
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { privateResponse };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function resolveHydration(value: unknown): Promise<unknown>;
|
|
2
|
+
export interface StreamDocumentOptions {
|
|
3
|
+
hydration: Promise<unknown>;
|
|
4
|
+
nonce?: string;
|
|
5
|
+
signal: AbortSignal;
|
|
6
|
+
dispose: () => void;
|
|
7
|
+
}
|
|
8
|
+
/** Stream the shell immediately, then finalize the JSON snapshot before module scripts execute. */
|
|
9
|
+
export declare function streamDocument(source: ReadableStream<Uint8Array>, options: StreamDocumentOptions): ReadableStream<Uint8Array>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { serializeData } from "../core/serialize.js";
|
|
2
|
+
//#region .generated/server/stream-document.ts
|
|
3
|
+
async function resolveHydration(value) {
|
|
4
|
+
if (value instanceof Promise) return value.then(resolveHydration, (error) => ({ __smolterRejected: { message: error instanceof Error ? error.message : String(error) } }));
|
|
5
|
+
if (Array.isArray(value)) return Promise.all(value.map(resolveHydration));
|
|
6
|
+
if (value && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) {
|
|
7
|
+
const entries = await Promise.all(Object.entries(value).map(async ([key, field]) => [key, await resolveHydration(field)]));
|
|
8
|
+
return Object.fromEntries(entries);
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
/** Stream the shell immediately, then finalize the JSON snapshot before module scripts execute. */
|
|
13
|
+
function streamDocument(source, options) {
|
|
14
|
+
const reader = source.getReader();
|
|
15
|
+
const encoder = new TextEncoder();
|
|
16
|
+
const decoder = new TextDecoder();
|
|
17
|
+
let suffix = "";
|
|
18
|
+
let first = true;
|
|
19
|
+
let cancelled = false;
|
|
20
|
+
let finish;
|
|
21
|
+
const interrupted = new Promise((resolve) => {
|
|
22
|
+
finish = resolve;
|
|
23
|
+
});
|
|
24
|
+
const abort = () => {
|
|
25
|
+
finish();
|
|
26
|
+
reader.cancel().catch(() => {});
|
|
27
|
+
};
|
|
28
|
+
options.signal.addEventListener("abort", abort, { once: true });
|
|
29
|
+
if (options.signal.aborted) abort();
|
|
30
|
+
function dispose() {
|
|
31
|
+
options.signal.removeEventListener("abort", abort);
|
|
32
|
+
options.dispose();
|
|
33
|
+
}
|
|
34
|
+
return new ReadableStream({
|
|
35
|
+
async pull(controller) {
|
|
36
|
+
const result = await reader.read().catch((error) => ({ error }));
|
|
37
|
+
if ("error" in result) {
|
|
38
|
+
dispose();
|
|
39
|
+
controller.error(result.error);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (result.done) {
|
|
43
|
+
if (!options.signal.aborted) {
|
|
44
|
+
const value = await Promise.race([options.hydration, interrupted]);
|
|
45
|
+
if (cancelled) return;
|
|
46
|
+
if (options.signal.aborted) {
|
|
47
|
+
dispose();
|
|
48
|
+
controller.close();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const hydration = serializeData(value);
|
|
52
|
+
const nonce = options.nonce ? ` nonce="${options.nonce.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<")}"` : "";
|
|
53
|
+
controller.enqueue(encoder.encode(`<script type="application/json"${nonce}>${hydration}<\/script><script${nonce}>(function(){var script=document.currentScript,payload=script.previousElementSibling,data=document.getElementById("smolter-data");if(data)data.textContent=payload.textContent;payload.remove();script.remove()})()<\/script>${suffix}`));
|
|
54
|
+
}
|
|
55
|
+
dispose();
|
|
56
|
+
controller.close();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
let chunk = decoder.decode(result.value, { stream: true });
|
|
60
|
+
if (first && !/^<!doctype/i.test(chunk)) chunk = `<!doctype html>${chunk}`;
|
|
61
|
+
first = false;
|
|
62
|
+
const closing = chunk.lastIndexOf("</body>");
|
|
63
|
+
if (closing !== -1) {
|
|
64
|
+
suffix = chunk.slice(closing);
|
|
65
|
+
chunk = chunk.slice(0, closing);
|
|
66
|
+
}
|
|
67
|
+
controller.enqueue(encoder.encode(chunk));
|
|
68
|
+
},
|
|
69
|
+
async cancel() {
|
|
70
|
+
cancelled = true;
|
|
71
|
+
finish();
|
|
72
|
+
dispose();
|
|
73
|
+
await reader.cancel();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
export { resolveHydration, streamDocument };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type Plugin } from "vite";
|
|
2
|
-
export declare function lazyFiles(directory: string): Plugin;
|
|
2
|
+
export declare function lazyFiles(directory: string, dataEndpoint?: string): Plugin;
|
|
@@ -3,7 +3,7 @@ import { readFile } from "node:fs/promises";
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { transformWithOxc } from "vite";
|
|
5
5
|
//#region .generated/vite/application/lazy-files.ts
|
|
6
|
-
function lazyFiles(directory) {
|
|
6
|
+
function lazyFiles(directory, dataEndpoint = "/_smolter") {
|
|
7
7
|
let root;
|
|
8
8
|
const modules = /* @__PURE__ */ new Map();
|
|
9
9
|
return {
|
|
@@ -45,13 +45,17 @@ function lazyFiles(directory) {
|
|
|
45
45
|
if (id !== "\0virtual:smolter/routes" || options?.ssr) return;
|
|
46
46
|
const routes = await flatRoutes(root);
|
|
47
47
|
if (routes instanceof Error) return this.error(routes.message);
|
|
48
|
+
modules.clear();
|
|
48
49
|
const definitions = [];
|
|
49
50
|
for (const route of routes) {
|
|
50
51
|
this.addWatchFile(route.file);
|
|
51
52
|
const source = await readFile(route.file, "utf8");
|
|
52
53
|
const transformed = await transformWithOxc(source, route.file);
|
|
53
54
|
const ast = this.parse(transformed.code);
|
|
54
|
-
const fields = {
|
|
55
|
+
const fields = {
|
|
56
|
+
path: route.path,
|
|
57
|
+
dataEndpoint
|
|
58
|
+
};
|
|
55
59
|
for (const statement of ast.body) {
|
|
56
60
|
if (statement.type === "ExportDefaultDeclaration") {
|
|
57
61
|
fields.default = true;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { Plugin, UserConfig } from "vite";
|
|
2
2
|
export interface ApplicationOptions {
|
|
3
3
|
directory?: string;
|
|
4
|
+
dataEndpoint?: string;
|
|
4
5
|
ssr?: boolean;
|
|
5
6
|
splitRoutes?: boolean;
|
|
6
7
|
resourceRequest?: (url: string) => boolean;
|
|
7
8
|
}
|
|
8
9
|
export declare const preactConfig: UserConfig;
|
|
9
|
-
export declare function applicationPlugins({ directory, ssr, splitRoutes, resourceRequest, }?: ApplicationOptions): Plugin[];
|
|
10
|
+
export declare function applicationPlugins({ directory, dataEndpoint, ssr, splitRoutes, resourceRequest, }?: ApplicationOptions): Plugin[];
|
|
@@ -43,7 +43,7 @@ var preactConfig = {
|
|
|
43
43
|
"@kasperrt/smolter/preact/lazy-route"
|
|
44
44
|
] }
|
|
45
45
|
};
|
|
46
|
-
function applicationPlugins({ directory = "src/routes", ssr = true, splitRoutes = true, resourceRequest } = {}) {
|
|
46
|
+
function applicationPlugins({ directory = "src/routes", dataEndpoint = "/_smolter", ssr = true, splitRoutes = true, resourceRequest } = {}) {
|
|
47
47
|
return [
|
|
48
48
|
{
|
|
49
49
|
name: "smolter-application",
|
|
@@ -60,7 +60,8 @@ function applicationPlugins({ directory = "src/routes", ssr = true, splitRoutes
|
|
|
60
60
|
},
|
|
61
61
|
configureServer(server) {
|
|
62
62
|
server.middlewares.use((incoming, outgoing, next) => {
|
|
63
|
-
if (!incoming.url?.startsWith(
|
|
63
|
+
if (!incoming.url?.startsWith(`${dataEndpoint}?`)) return next();
|
|
64
|
+
outgoing.setHeader("Cache-Control", "private, no-store");
|
|
64
65
|
const run = async () => {
|
|
65
66
|
const target = new URL(incoming.url, "http://local").searchParams.get("url");
|
|
66
67
|
if (!target?.startsWith("/") || target.startsWith("//")) return send(new Response("Invalid route URL", { status: 400 }), outgoing);
|
|
@@ -74,6 +75,7 @@ function applicationPlugins({ directory = "src/routes", ssr = true, splitRoutes
|
|
|
74
75
|
return () => {
|
|
75
76
|
server.middlewares.use((incoming, outgoing, next) => {
|
|
76
77
|
if (!incoming.headers.accept?.includes("text/html") && !resourceRequest?.(incoming.originalUrl ?? incoming.url ?? "")) return next();
|
|
78
|
+
outgoing.setHeader("Cache-Control", "private, no-store");
|
|
77
79
|
const run = async () => {
|
|
78
80
|
const request = await webRequest(incoming, outgoing);
|
|
79
81
|
const response = await (await server.ssrLoadModule("/src/entry.server.tsx")).default(request, "/src/entry.client.tsx");
|
|
@@ -90,10 +92,11 @@ function applicationPlugins({ directory = "src/routes", ssr = true, splitRoutes
|
|
|
90
92
|
}
|
|
91
93
|
},
|
|
92
94
|
browserBoundary(),
|
|
93
|
-
...splitRoutes ? [lazyFiles(directory)] : [],
|
|
95
|
+
...splitRoutes ? [lazyFiles(directory, dataEndpoint)] : [],
|
|
94
96
|
routerPlugin({
|
|
95
97
|
directory,
|
|
96
|
-
framework: "preact"
|
|
98
|
+
framework: "preact",
|
|
99
|
+
dataEndpoint
|
|
97
100
|
})
|
|
98
101
|
];
|
|
99
102
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
/** Deployment manifest configuration. Serve the emitted file with Cache-Control: no-store. */
|
|
3
|
+
export interface DeploymentPluginOptions {
|
|
4
|
+
/** Public URL, optionally on an asset host. Defaults to Vite base + smolter-manifest.json. */
|
|
5
|
+
manifestURL?: string;
|
|
6
|
+
}
|
|
7
|
+
/** Emit a build manifest and expose its identity through virtual:smolter/deployment. */
|
|
8
|
+
export declare function deploymentPlugin(options?: DeploymentPluginOptions): Plugin;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
//#region .generated/vite/deployment.ts
|
|
3
|
+
/** Emit a build manifest and expose its identity through virtual:smolter/deployment. */
|
|
4
|
+
function deploymentPlugin(options = {}) {
|
|
5
|
+
const version = randomUUID();
|
|
6
|
+
const virtualId = "\0virtual:smolter/deployment";
|
|
7
|
+
let enabled = false;
|
|
8
|
+
let manifestURL = "";
|
|
9
|
+
return {
|
|
10
|
+
name: "smolter-deployment",
|
|
11
|
+
configResolved(config) {
|
|
12
|
+
enabled = config.command === "build" && !config.build.ssr;
|
|
13
|
+
manifestURL = options.manifestURL ?? `${config.base}smolter-manifest.json`;
|
|
14
|
+
},
|
|
15
|
+
resolveId(id) {
|
|
16
|
+
if (id === "virtual:smolter/deployment") return virtualId;
|
|
17
|
+
},
|
|
18
|
+
load(id) {
|
|
19
|
+
if (id !== virtualId) return;
|
|
20
|
+
return `export default ${JSON.stringify(enabled ? {
|
|
21
|
+
version,
|
|
22
|
+
manifestURL
|
|
23
|
+
} : null)};`;
|
|
24
|
+
},
|
|
25
|
+
generateBundle() {
|
|
26
|
+
if (!enabled) return;
|
|
27
|
+
this.emitFile({
|
|
28
|
+
type: "asset",
|
|
29
|
+
fileName: "smolter-manifest.json",
|
|
30
|
+
source: JSON.stringify({ version })
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { deploymentPlugin };
|
package/dist/vite/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type Plugin } from "vite";
|
|
2
2
|
export interface FileRouterOptions {
|
|
3
3
|
directory?: string;
|
|
4
|
+
dataEndpoint?: string;
|
|
4
5
|
clientRoutes?: string;
|
|
5
6
|
serverRoutes?: string;
|
|
6
7
|
framework?: "react" | "preact";
|
|
7
8
|
}
|
|
8
9
|
/** Build-time flat route discovery and the optional server data transport. */
|
|
9
|
-
export declare function routerPlugin({ directory, clientRoutes, serverRoutes, framework, }?: FileRouterOptions): Plugin;
|
|
10
|
+
export declare function routerPlugin({ directory, dataEndpoint, clientRoutes, serverRoutes, framework, }?: FileRouterOptions): Plugin;
|
|
10
11
|
/** File routing is the default; this alias keeps configuration explicit. */
|
|
11
12
|
export declare const fileRouter: typeof routerPlugin;
|
package/dist/vite/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { flatRoutes } from "../files/index.js";
|
|
2
2
|
import { configureTransport } from "./transport.js";
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
|
-
import { resolve } from "node:path";
|
|
4
|
+
import { relative, resolve } from "node:path";
|
|
5
5
|
import { transformWithOxc } from "vite";
|
|
6
6
|
//#region .generated/vite/index.ts
|
|
7
7
|
/** Build-time flat route discovery and the optional server data transport. */
|
|
8
|
-
function routerPlugin({ directory = "src/routes", clientRoutes, serverRoutes, framework = "react" } = {}) {
|
|
8
|
+
function routerPlugin({ directory = "src/routes", dataEndpoint = "/_smolter", clientRoutes, serverRoutes, framework = "react" } = {}) {
|
|
9
9
|
let root;
|
|
10
10
|
let projectRoot;
|
|
11
11
|
const publicId = "virtual:smolter/routes";
|
|
@@ -75,7 +75,10 @@ function routerPlugin({ directory = "src/routes", clientRoutes, serverRoutes, fr
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
imports.push(`import * as route${index} from ${JSON.stringify(file + (options?.ssr ? "" : suffix))};`);
|
|
78
|
-
definitions.push(options?.ssr || !Object.keys(handlers).length ? `{ ...route${index}, path: ${JSON.stringify(route.path)} }` : `serverRoute(${JSON.stringify(route.path)}, route${index}, ${JSON.stringify(
|
|
78
|
+
definitions.push(options?.ssr || !Object.keys(handlers).length ? `{ ...route${index}, path: ${JSON.stringify(route.path)} }` : `serverRoute(${JSON.stringify(route.path)}, route${index}, ${JSON.stringify({
|
|
79
|
+
...handlers,
|
|
80
|
+
dataEndpoint
|
|
81
|
+
})})`);
|
|
79
82
|
}
|
|
80
83
|
if (!options?.ssr && definitions.some((definition) => definition.startsWith("serverRoute("))) imports.unshift(`import { serverRoute } from "@kasperrt/smolter/${framework}/client";`);
|
|
81
84
|
return `${imports.join("\n")}\nexport default [${definitions.join(",\n")}];\n`;
|
|
@@ -83,9 +86,14 @@ function routerPlugin({ directory = "src/routes", clientRoutes, serverRoutes, fr
|
|
|
83
86
|
configureServer(server) {
|
|
84
87
|
server.watcher.add(root);
|
|
85
88
|
const refresh = (file) => {
|
|
86
|
-
if (
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
+
if (clientRoutes || serverRoutes) return;
|
|
90
|
+
const path = relative(root, file).replaceAll("\\", "/");
|
|
91
|
+
if (!/^(?:[^/]+\.[jt]sx?|[^/]+\/route\.[jt]sx?)$/.test(path)) return;
|
|
92
|
+
if (path.endsWith(".d.ts")) return;
|
|
93
|
+
for (const environment of Object.values(server.environments)) {
|
|
94
|
+
const module = environment.moduleGraph.getModuleById(virtualId);
|
|
95
|
+
if (module) environment.moduleGraph.invalidateModule(module);
|
|
96
|
+
}
|
|
89
97
|
server.ws.send({ type: "full-reload" });
|
|
90
98
|
};
|
|
91
99
|
server.watcher.on("add", refresh);
|
|
@@ -96,7 +104,7 @@ function routerPlugin({ directory = "src/routes", clientRoutes, serverRoutes, fr
|
|
|
96
104
|
server.watcher.off("change", refresh);
|
|
97
105
|
server.watcher.off("unlink", refresh);
|
|
98
106
|
});
|
|
99
|
-
configureTransport(server, publicId, framework);
|
|
107
|
+
configureTransport(server, publicId, framework, dataEndpoint);
|
|
100
108
|
}
|
|
101
109
|
};
|
|
102
110
|
}
|
package/dist/vite/preact.d.ts
CHANGED
|
@@ -9,3 +9,4 @@ export declare function routerPlugin(options?: FileRouterOptions): Plugin;
|
|
|
9
9
|
export declare const fileRouter: typeof routerPlugin;
|
|
10
10
|
export type { ApplicationOptions } from "./application/vite.ts";
|
|
11
11
|
export { applicationPlugins, preactConfig, } from "./application/vite.ts";
|
|
12
|
+
export { type DeploymentPluginOptions, deploymentPlugin, } from "./deployment.ts";
|
package/dist/vite/preact.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { flatRoutes } from "../files/index.js";
|
|
2
2
|
import { routerPlugin as routerPlugin$1 } from "./index.js";
|
|
3
|
+
import { deploymentPlugin } from "./deployment.js";
|
|
3
4
|
import { applicationPlugins, preactConfig } from "./application/vite.js";
|
|
4
5
|
//#region .generated/vite/preact.ts
|
|
5
6
|
/** Configure flat routes and server transport for Preact. */
|
|
@@ -12,4 +13,4 @@ function routerPlugin(options = {}) {
|
|
|
12
13
|
/** File routing is the default; this alias keeps configuration explicit. */
|
|
13
14
|
var fileRouter = routerPlugin;
|
|
14
15
|
//#endregion
|
|
15
|
-
export { applicationPlugins, fileRouter, flatRoutes, preactConfig, routerPlugin };
|
|
16
|
+
export { applicationPlugins, deploymentPlugin, fileRouter, flatRoutes, preactConfig, routerPlugin };
|
package/dist/vite/react.d.ts
CHANGED
|
@@ -7,3 +7,4 @@ export type { FileRouterOptions } from "./index.ts";
|
|
|
7
7
|
export declare function routerPlugin(options?: FileRouterOptions): Plugin;
|
|
8
8
|
/** File routing is the default; this alias keeps configuration explicit. */
|
|
9
9
|
export declare const fileRouter: typeof routerPlugin;
|
|
10
|
+
export { type DeploymentPluginOptions, deploymentPlugin, } from "./deployment.ts";
|
package/dist/vite/react.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { flatRoutes } from "../files/index.js";
|
|
2
2
|
import { routerPlugin as routerPlugin$1 } from "./index.js";
|
|
3
|
+
import { deploymentPlugin } from "./deployment.js";
|
|
3
4
|
//#region .generated/vite/react.ts
|
|
4
5
|
/** Configure flat routes and server transport for React. */
|
|
5
6
|
function routerPlugin(options = {}) {
|
|
@@ -11,4 +12,4 @@ function routerPlugin(options = {}) {
|
|
|
11
12
|
/** File routing is the default; this alias keeps configuration explicit. */
|
|
12
13
|
var fileRouter = routerPlugin;
|
|
13
14
|
//#endregion
|
|
14
|
-
export { fileRouter, flatRoutes, routerPlugin };
|
|
15
|
+
export { deploymentPlugin, fileRouter, flatRoutes, routerPlugin };
|
package/dist/vite/transport.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { ViteDevServer } from "vite";
|
|
2
|
-
export declare function configureTransport(server: ViteDevServer, publicId: string, framework?: "react" | "preact"): void;
|
|
2
|
+
export declare function configureTransport(server: ViteDevServer, publicId: string, framework?: "react" | "preact", dataEndpoint?: string): void;
|
package/dist/vite/transport.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
//#region .generated/vite/transport.ts
|
|
2
|
-
function configureTransport(server, publicId, framework = "react") {
|
|
2
|
+
function configureTransport(server, publicId, framework = "react", dataEndpoint = "/_smolter") {
|
|
3
3
|
server.middlewares.use((incoming, outgoing, next) => {
|
|
4
|
-
if (!incoming.url?.startsWith(
|
|
4
|
+
if (!incoming.url?.startsWith(`${dataEndpoint}?`)) return next();
|
|
5
|
+
outgoing.setHeader("Cache-Control", "private, no-store");
|
|
5
6
|
const dispatch = async () => {
|
|
6
7
|
const origin = `http://${incoming.headers.host}`;
|
|
7
8
|
const target = new URL(incoming.url, origin).searchParams.get("url");
|
package/jsr.json
CHANGED
package/package.json
CHANGED
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"wouter": "3.13.0",
|
|
57
57
|
"wouter-preact": "3.13.0"
|
|
58
58
|
},
|
|
59
|
-
"version": "0.3.
|
|
59
|
+
"version": "0.3.2",
|
|
60
60
|
"description": "A tiny typed data router for React and Preact.",
|
|
61
61
|
"sideEffects": false,
|
|
62
62
|
"license": "MIT",
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
"react": ">=18",
|
|
139
139
|
"preact": ">=11.0.1",
|
|
140
140
|
"vite": ">=8",
|
|
141
|
-
"preact-render-to-string": ">=6"
|
|
141
|
+
"preact-render-to-string": ">=6.8.1"
|
|
142
142
|
},
|
|
143
143
|
"peerDependenciesMeta": {
|
|
144
144
|
"react": {
|
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
"optional": true
|
|
155
155
|
}
|
|
156
156
|
},
|
|
157
|
-
"author": "Kasper Rynning-
|
|
157
|
+
"author": "Kasper Rynning-Tønnesen <kasperrt@users.noreply.github.com> (https://github.com/kasperrt)",
|
|
158
158
|
"homepage": "https://kasperrt.github.io/smolter/",
|
|
159
159
|
"bugs": {
|
|
160
160
|
"url": "https://github.com/kasperrt/smolter/issues"
|