@elurjs/kit 2.4.4
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/CHANGELOG.md +874 -0
- package/LICENSE +21 -0
- package/README.md +1330 -0
- package/bin/elur-kit.js +54 -0
- package/dist/lib/action/define.d.cts +72 -0
- package/dist/lib/action/define.d.ts +72 -0
- package/dist/lib/action/error-store.d.cts +29 -0
- package/dist/lib/action/error-store.d.ts +29 -0
- package/dist/lib/action/index.cjs +1 -0
- package/dist/lib/action/index.d.cts +64 -0
- package/dist/lib/action/index.d.ts +64 -0
- package/dist/lib/action/index.js +2 -0
- package/dist/lib/action/origin.d.cts +20 -0
- package/dist/lib/action/origin.d.ts +20 -0
- package/dist/lib/action/scan.d.cts +28 -0
- package/dist/lib/action/scan.d.ts +28 -0
- package/dist/lib/action/server.d.cts +30 -0
- package/dist/lib/action/server.d.ts +30 -0
- package/dist/lib/action-BB6N5yD-.js +111 -0
- package/dist/lib/action-BB6N5yD-.js.map +1 -0
- package/dist/lib/action-DZHihU3Z.cjs +2 -0
- package/dist/lib/action-DZHihU3Z.cjs.map +1 -0
- package/dist/lib/adapters/bun.cjs +30 -0
- package/dist/lib/adapters/bun.cjs.map +1 -0
- package/dist/lib/adapters/bun.d.cts +13 -0
- package/dist/lib/adapters/bun.d.ts +13 -0
- package/dist/lib/adapters/bun.js +65 -0
- package/dist/lib/adapters/bun.js.map +1 -0
- package/dist/lib/adapters/index.cjs +0 -0
- package/dist/lib/adapters/index.d.cts +30 -0
- package/dist/lib/adapters/index.d.ts +30 -0
- package/dist/lib/adapters/index.js +0 -0
- package/dist/lib/adapters/netlify.cjs +10 -0
- package/dist/lib/adapters/netlify.cjs.map +1 -0
- package/dist/lib/adapters/netlify.d.cts +13 -0
- package/dist/lib/adapters/netlify.d.ts +13 -0
- package/dist/lib/adapters/netlify.js +51 -0
- package/dist/lib/adapters/netlify.js.map +1 -0
- package/dist/lib/adapters/node.cjs +46 -0
- package/dist/lib/adapters/node.cjs.map +1 -0
- package/dist/lib/adapters/node.d.cts +13 -0
- package/dist/lib/adapters/node.d.ts +13 -0
- package/dist/lib/adapters/node.js +105 -0
- package/dist/lib/adapters/node.js.map +1 -0
- package/dist/lib/adapters/shared.d.cts +17 -0
- package/dist/lib/adapters/shared.d.ts +17 -0
- package/dist/lib/adapters/vercel.cjs +2 -0
- package/dist/lib/adapters/vercel.cjs.map +1 -0
- package/dist/lib/adapters/vercel.d.cts +9 -0
- package/dist/lib/adapters/vercel.d.ts +9 -0
- package/dist/lib/adapters/vercel.js +62 -0
- package/dist/lib/adapters/vercel.js.map +1 -0
- package/dist/lib/build/build.d.cts +83 -0
- package/dist/lib/build/build.d.ts +83 -0
- package/dist/lib/build/document-shell.d.cts +48 -0
- package/dist/lib/build/document-shell.d.ts +48 -0
- package/dist/lib/build/transform-source.d.cts +26 -0
- package/dist/lib/build/transform-source.d.ts +26 -0
- package/dist/lib/build/vite-build.d.cts +78 -0
- package/dist/lib/build/vite-build.d.ts +78 -0
- package/dist/lib/cache/policy.d.cts +25 -0
- package/dist/lib/cache/policy.d.ts +25 -0
- package/dist/lib/cache.d.cts +13 -0
- package/dist/lib/cache.d.ts +13 -0
- package/dist/lib/capabilities-C0TDQoMY.cjs +2 -0
- package/dist/lib/capabilities-C0TDQoMY.cjs.map +1 -0
- package/dist/lib/capabilities-C7txofmY.js +45 -0
- package/dist/lib/capabilities-C7txofmY.js.map +1 -0
- package/dist/lib/cli/commands.d.cts +15 -0
- package/dist/lib/cli/commands.d.ts +15 -0
- package/dist/lib/cli.cjs +5132 -0
- package/dist/lib/cli.cjs.map +1 -0
- package/dist/lib/cli.d.cts +30 -0
- package/dist/lib/cli.d.ts +30 -0
- package/dist/lib/cli.js +5131 -0
- package/dist/lib/cli.js.map +1 -0
- package/dist/lib/collections-Dbc8aRLf.js +233 -0
- package/dist/lib/collections-Dbc8aRLf.js.map +1 -0
- package/dist/lib/collections-VDy5g9p8.cjs +13 -0
- package/dist/lib/collections-VDy5g9p8.cjs.map +1 -0
- package/dist/lib/config/index.cjs +2 -0
- package/dist/lib/config/index.cjs.map +1 -0
- package/dist/lib/config/index.d.cts +100 -0
- package/dist/lib/config/index.d.ts +100 -0
- package/dist/lib/config/index.js +122 -0
- package/dist/lib/config/index.js.map +1 -0
- package/dist/lib/content/collections.d.cts +69 -0
- package/dist/lib/content/collections.d.ts +69 -0
- package/dist/lib/content/frontmatter.d.cts +20 -0
- package/dist/lib/content/frontmatter.d.ts +20 -0
- package/dist/lib/content/index.cjs +2 -0
- package/dist/lib/content/index.cjs.map +1 -0
- package/dist/lib/content/index.d.cts +5 -0
- package/dist/lib/content/index.d.ts +5 -0
- package/dist/lib/content/index.js +28 -0
- package/dist/lib/content/index.js.map +1 -0
- package/dist/lib/content/markdown.d.cts +6 -0
- package/dist/lib/content/markdown.d.ts +6 -0
- package/dist/lib/content/raw.d.cts +9 -0
- package/dist/lib/content/raw.d.ts +9 -0
- package/dist/lib/content/schema.d.cts +14 -0
- package/dist/lib/content/schema.d.ts +14 -0
- package/dist/lib/errors-0X7pCFNU.cjs +2 -0
- package/dist/lib/errors-0X7pCFNU.cjs.map +1 -0
- package/dist/lib/errors-ePYxDlhU.js +70 -0
- package/dist/lib/errors-ePYxDlhU.js.map +1 -0
- package/dist/lib/errors.d.cts +84 -0
- package/dist/lib/errors.d.ts +84 -0
- package/dist/lib/hydrate-8a3TbQbs.cjs +2 -0
- package/dist/lib/hydrate-8a3TbQbs.cjs.map +1 -0
- package/dist/lib/hydrate-CgZGrTxF.js +126 -0
- package/dist/lib/hydrate-CgZGrTxF.js.map +1 -0
- package/dist/lib/image/index.cjs +2 -0
- package/dist/lib/image/index.cjs.map +1 -0
- package/dist/lib/image/index.d.cts +37 -0
- package/dist/lib/image/index.d.ts +37 -0
- package/dist/lib/image/index.js +49 -0
- package/dist/lib/image/index.js.map +1 -0
- package/dist/lib/image/pipeline.d.cts +37 -0
- package/dist/lib/image/pipeline.d.ts +37 -0
- package/dist/lib/image/registry.cjs +2 -0
- package/dist/lib/image/registry.cjs.map +1 -0
- package/dist/lib/image/registry.d.cts +26 -0
- package/dist/lib/image/registry.d.ts +26 -0
- package/dist/lib/image/registry.js +23 -0
- package/dist/lib/image/registry.js.map +1 -0
- package/dist/lib/image/service.cjs +2 -0
- package/dist/lib/image/service.cjs.map +1 -0
- package/dist/lib/image/service.d.cts +164 -0
- package/dist/lib/image/service.d.ts +164 -0
- package/dist/lib/image/service.js +308 -0
- package/dist/lib/image/service.js.map +1 -0
- package/dist/lib/index.cjs +1 -0
- package/dist/lib/index.cjs.map +1 -0
- package/dist/lib/index.d.cts +38 -0
- package/dist/lib/index.d.ts +38 -0
- package/dist/lib/index.js +1 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/integrations/hooks.d.cts +58 -0
- package/dist/lib/integrations/hooks.d.ts +58 -0
- package/dist/lib/integrations/index.cjs +1 -0
- package/dist/lib/integrations/index.d.cts +18 -0
- package/dist/lib/integrations/index.d.ts +18 -0
- package/dist/lib/integrations/index.js +2 -0
- package/dist/lib/integrations-7dpN1RYB.js +35 -0
- package/dist/lib/integrations-7dpN1RYB.js.map +1 -0
- package/dist/lib/integrations-DDqfWjvH.cjs +2 -0
- package/dist/lib/integrations-DDqfWjvH.cjs.map +1 -0
- package/dist/lib/interpolation-plugin-Bt-KRKVY.js +365 -0
- package/dist/lib/interpolation-plugin-Bt-KRKVY.js.map +1 -0
- package/dist/lib/interpolation-plugin-CMPCDlVJ.cjs +31 -0
- package/dist/lib/interpolation-plugin-CMPCDlVJ.cjs.map +1 -0
- package/dist/lib/island/generate-entry.d.cts +27 -0
- package/dist/lib/island/generate-entry.d.ts +27 -0
- package/dist/lib/island/hydrate.d.cts +33 -0
- package/dist/lib/island/hydrate.d.ts +33 -0
- package/dist/lib/island/index.cjs +1 -0
- package/dist/lib/island/index.d.cts +2 -0
- package/dist/lib/island/index.d.ts +2 -0
- package/dist/lib/island/index.js +1 -0
- package/dist/lib/island/island.d.cts +32 -0
- package/dist/lib/island/island.d.ts +32 -0
- package/dist/lib/island/scan.d.cts +14 -0
- package/dist/lib/island/scan.d.ts +14 -0
- package/dist/lib/manifest/index.cjs +3 -0
- package/dist/lib/manifest/index.cjs.map +1 -0
- package/dist/lib/manifest/index.d.cts +18 -0
- package/dist/lib/manifest/index.d.ts +18 -0
- package/dist/lib/manifest/index.js +110 -0
- package/dist/lib/manifest/index.js.map +1 -0
- package/dist/lib/middleware/index.d.cts +56 -0
- package/dist/lib/middleware/index.d.ts +56 -0
- package/dist/lib/middleware/stream-boundary.d.cts +53 -0
- package/dist/lib/middleware/stream-boundary.d.ts +53 -0
- package/dist/lib/node-http-DRAUhO0c.js +617 -0
- package/dist/lib/node-http-DRAUhO0c.js.map +1 -0
- package/dist/lib/node-http-DhxguYyz.cjs +13 -0
- package/dist/lib/node-http-DhxguYyz.cjs.map +1 -0
- package/dist/lib/render/render-to-string.d.cts +12 -0
- package/dist/lib/render/render-to-string.d.ts +12 -0
- package/dist/lib/render/ssr-flag.d.cts +4 -0
- package/dist/lib/render/ssr-flag.d.ts +4 -0
- package/dist/lib/route-scanner-JY6YrNH5.cjs +2 -0
- package/dist/lib/route-scanner-JY6YrNH5.cjs.map +1 -0
- package/dist/lib/route-scanner-XcLId7lK.js +100 -0
- package/dist/lib/route-scanner-XcLId7lK.js.map +1 -0
- package/dist/lib/router/client.cjs +2 -0
- package/dist/lib/router/client.cjs.map +1 -0
- package/dist/lib/router/client.d.cts +47 -0
- package/dist/lib/router/client.d.ts +47 -0
- package/dist/lib/router/client.js +298 -0
- package/dist/lib/router/client.js.map +1 -0
- package/dist/lib/router/route-scanner.d.cts +50 -0
- package/dist/lib/router/route-scanner.d.ts +50 -0
- package/dist/lib/runtime/capabilities.d.cts +47 -0
- package/dist/lib/runtime/capabilities.d.ts +47 -0
- package/dist/lib/runtime/context.d.cts +140 -0
- package/dist/lib/runtime/context.d.ts +140 -0
- package/dist/lib/runtime/handler.d.cts +39 -0
- package/dist/lib/runtime/handler.d.ts +39 -0
- package/dist/lib/runtime/index.cjs +1 -0
- package/dist/lib/runtime/index.d.cts +6 -0
- package/dist/lib/runtime/index.d.ts +6 -0
- package/dist/lib/runtime/index.js +4 -0
- package/dist/lib/runtime/node-http.d.cts +2 -0
- package/dist/lib/runtime/node-http.d.ts +2 -0
- package/dist/lib/runtime/security-headers.d.cts +13 -0
- package/dist/lib/runtime/security-headers.d.ts +13 -0
- package/dist/lib/runtime/static.d.cts +1 -0
- package/dist/lib/runtime/static.d.ts +1 -0
- package/dist/lib/runtime-CrH5X-Es.cjs +2 -0
- package/dist/lib/runtime-CrH5X-Es.cjs.map +1 -0
- package/dist/lib/runtime-Ds2-wH6P.js +520 -0
- package/dist/lib/runtime-Ds2-wH6P.js.map +1 -0
- package/dist/lib/scan-CY2O9ty6.cjs +2 -0
- package/dist/lib/scan-CY2O9ty6.cjs.map +1 -0
- package/dist/lib/scan-CjMUgnsd.js +22 -0
- package/dist/lib/scan-CjMUgnsd.js.map +1 -0
- package/dist/lib/scan-DXzYtmRQ.cjs +2 -0
- package/dist/lib/scan-DXzYtmRQ.cjs.map +1 -0
- package/dist/lib/scan-Dn93ycXG.js +33 -0
- package/dist/lib/scan-Dn93ycXG.js.map +1 -0
- package/dist/lib/seo/index.cjs +10 -0
- package/dist/lib/seo/index.cjs.map +1 -0
- package/dist/lib/seo/index.d.cts +99 -0
- package/dist/lib/seo/index.d.ts +99 -0
- package/dist/lib/seo/index.js +41 -0
- package/dist/lib/seo/index.js.map +1 -0
- package/dist/lib/shared-CfqOLsKj.cjs +183 -0
- package/dist/lib/shared-CfqOLsKj.cjs.map +1 -0
- package/dist/lib/shared-DU3iQgr7.js +236 -0
- package/dist/lib/shared-DU3iQgr7.js.map +1 -0
- package/dist/lib/ssr/match.d.cts +25 -0
- package/dist/lib/ssr/match.d.ts +25 -0
- package/dist/lib/ssr/render.d.cts +62 -0
- package/dist/lib/ssr/render.d.ts +62 -0
- package/dist/lib/ssr/server.d.cts +41 -0
- package/dist/lib/ssr/server.d.ts +41 -0
- package/dist/lib/ssr/stream.d.cts +48 -0
- package/dist/lib/ssr/stream.d.ts +48 -0
- package/dist/lib/stream-CpOG052V.js +104 -0
- package/dist/lib/stream-CpOG052V.js.map +1 -0
- package/dist/lib/stream-DmZjYqHm.cjs +17 -0
- package/dist/lib/stream-DmZjYqHm.cjs.map +1 -0
- package/dist/lib/types.d.cts +97 -0
- package/dist/lib/types.d.ts +97 -0
- package/dist/lib/vite/index.cjs +2 -0
- package/dist/lib/vite/index.cjs.map +1 -0
- package/dist/lib/vite/index.d.cts +41 -0
- package/dist/lib/vite/index.d.ts +41 -0
- package/dist/lib/vite/index.js +229 -0
- package/dist/lib/vite/index.js.map +1 -0
- package/dist/lib/vite/interpolation-plugin.d.cts +64 -0
- package/dist/lib/vite/interpolation-plugin.d.ts +64 -0
- package/package.json +292 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { o as e } from "./node-http-DRAUhO0c.js";
|
|
2
|
+
import { mkdir as t, writeFile as n } from "node:fs/promises";
|
|
3
|
+
import { dirname as r, relative as i, sep as a } from "node:path";
|
|
4
|
+
import { createRequire as o } from "node:module";
|
|
5
|
+
//#region src/island/generate-entry.ts
|
|
6
|
+
function s(e, t) {
|
|
7
|
+
let n = e.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
8
|
+
return /^[a-zA-Z_$]/.test(n) ? `${n}_${t}` : `_${n}_${t}`;
|
|
9
|
+
}
|
|
10
|
+
function c(e, t, n = "@elurjs/kit/island", r = "@elurjs/kit/router") {
|
|
11
|
+
let i = e.map((e, n) => ({
|
|
12
|
+
ident: s(e.name, n),
|
|
13
|
+
name: e.name,
|
|
14
|
+
spec: l(t, e.filePath)
|
|
15
|
+
})).map((e) => ` ${JSON.stringify(e.name)}: { load: () => import(${JSON.stringify(e.spec)}).then(m => m.default) },`).join("\n"), a = i ? `const registry = {
|
|
16
|
+
${i}
|
|
17
|
+
};
|
|
18
|
+
hydrateIslands(registry);
|
|
19
|
+
document.addEventListener("elur:rendered", () => {
|
|
20
|
+
cleanupHydratedIslands();
|
|
21
|
+
hydrateIslands(registry);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Vite HMR: when an island module (or the entry itself) updates, dispose the
|
|
25
|
+
// current islands and re-hydrate from the updated modules — the registry's
|
|
26
|
+
// dynamic import() resolves to the fresh modules, so no full page reload is
|
|
27
|
+
// needed (progressive enhancement, audit §10.2 / §12.2).
|
|
28
|
+
if (import.meta.hot) {
|
|
29
|
+
import.meta.hot.accept((newModule) => {
|
|
30
|
+
cleanupHydratedIslands();
|
|
31
|
+
hydrateIslands(registry);
|
|
32
|
+
if (newModule) {
|
|
33
|
+
// Re-run the module so its side effects (router, listeners) apply.
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}` : "";
|
|
37
|
+
return `// AUTO-GENERATED by @elurjs/kit. Do not edit.
|
|
38
|
+
import { startClientRouter } from ${JSON.stringify(r)};
|
|
39
|
+
import { hydrateIslands, cleanupHydratedIslands } from ${JSON.stringify(n)};
|
|
40
|
+
|
|
41
|
+
startClientRouter();
|
|
42
|
+
${a}
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
function l(e, t) {
|
|
46
|
+
let n = i(r(e), t).split(a).join("/");
|
|
47
|
+
return n.startsWith(".") || (n = `./${n}`), n;
|
|
48
|
+
}
|
|
49
|
+
async function u(e) {
|
|
50
|
+
let i = c(e.islands, e.outFile, e.hydrateImport, e.routerImport);
|
|
51
|
+
return await t(r(e.outFile), { recursive: !0 }), await n(e.outFile, i, "utf8"), e.outFile;
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/middleware/index.ts
|
|
55
|
+
async function d(e) {
|
|
56
|
+
let t = [`${e}/src/middleware.ts`, `${e}/middleware.ts`];
|
|
57
|
+
for (let e of t) try {
|
|
58
|
+
let t = await import(e), n = t.default ?? t.middleware;
|
|
59
|
+
if (typeof n != "function") continue;
|
|
60
|
+
return {
|
|
61
|
+
handler: n,
|
|
62
|
+
config: t.config ?? {}
|
|
63
|
+
};
|
|
64
|
+
} catch (e) {
|
|
65
|
+
let t = typeof e == "object" && e && "message" in e ? String(e.message) : String(e);
|
|
66
|
+
if (t.includes("Cannot find module") || t.includes("Cannot find package") || t.includes("ENOENT") || t.includes("Module not found")) continue;
|
|
67
|
+
throw Error(`[elur-kit] Error loading middleware: ${t}`, { cause: e });
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
function f(t, n) {
|
|
72
|
+
if (!n.matcher || n.matcher.length === 0) return !0;
|
|
73
|
+
let r = t.split("?")[0];
|
|
74
|
+
for (let t of n.matcher) {
|
|
75
|
+
if (t === r) return !0;
|
|
76
|
+
let n = t.match(/^(.*)\/:[\w]+\*$/);
|
|
77
|
+
if (n && r === n[1] || e(r, [{
|
|
78
|
+
path: t,
|
|
79
|
+
pagePath: "",
|
|
80
|
+
params: [],
|
|
81
|
+
layouts: []
|
|
82
|
+
}])) return !0;
|
|
83
|
+
}
|
|
84
|
+
return !1;
|
|
85
|
+
}
|
|
86
|
+
async function p(e, t, n) {
|
|
87
|
+
let r, i, a, o = [], s = {
|
|
88
|
+
next(e) {
|
|
89
|
+
e?.headers && (r = e.headers), e?.params && (i = e.params), e?.locals && (a = e.locals);
|
|
90
|
+
},
|
|
91
|
+
params: n,
|
|
92
|
+
locals: {}
|
|
93
|
+
};
|
|
94
|
+
try {
|
|
95
|
+
let o = await e.handler(t, s);
|
|
96
|
+
return o instanceof Response ? {
|
|
97
|
+
kind: "response",
|
|
98
|
+
response: o
|
|
99
|
+
} : {
|
|
100
|
+
kind: "continue",
|
|
101
|
+
headers: r,
|
|
102
|
+
params: i ?? n,
|
|
103
|
+
locals: a
|
|
104
|
+
};
|
|
105
|
+
} finally {
|
|
106
|
+
for (let e of o) try {
|
|
107
|
+
await e();
|
|
108
|
+
} catch (e) {
|
|
109
|
+
console.error("[elur-kit] middleware cleanup error:", e);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/vite/interpolation-plugin.ts
|
|
115
|
+
var m = o(import.meta.url), h = !1;
|
|
116
|
+
function g() {
|
|
117
|
+
h || (h = !0, console.warn("[elur-kit] The legacy interpolation transform is deprecated. Install @elurjs/vite-plugin-elur >= 1.1.0 for compile-time partial attribute interpolation. Remove `interpolation: \"legacy\"` once migration is complete."));
|
|
118
|
+
}
|
|
119
|
+
function _() {
|
|
120
|
+
try {
|
|
121
|
+
let [e, t] = (m("@elurjs/vite-plugin-elur/package.json").version ?? "0.0.0").split(".").map(Number);
|
|
122
|
+
return e > 1 || e === 1 && t >= 1;
|
|
123
|
+
} catch {
|
|
124
|
+
return !1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function v() {
|
|
128
|
+
try {
|
|
129
|
+
return m("@elurjs/core")?.templateFeatures?.partialAttributeInterpolation === !0;
|
|
130
|
+
} catch {
|
|
131
|
+
return !1;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function y(e) {
|
|
135
|
+
return e === "off" ? !1 : e === "legacy" ? (g(), !0) : !_() && !v();
|
|
136
|
+
}
|
|
137
|
+
var b = "html", x = "`";
|
|
138
|
+
function S(e, t) {
|
|
139
|
+
let n = 1, r = t + 2;
|
|
140
|
+
for (; r < e.length && n > 0;) {
|
|
141
|
+
let t = e[r];
|
|
142
|
+
if (t === "\\") {
|
|
143
|
+
r += 2;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (t === "\"" || t === "'" || t === "`") {
|
|
147
|
+
let n = t;
|
|
148
|
+
for (r++; r < e.length;) {
|
|
149
|
+
if (e[r] === "\\") {
|
|
150
|
+
r += 2;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (e[r] === n) break;
|
|
154
|
+
r++;
|
|
155
|
+
}
|
|
156
|
+
r++;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
t === "{" ? n++ : t === "}" && n--, r++;
|
|
160
|
+
}
|
|
161
|
+
return r;
|
|
162
|
+
}
|
|
163
|
+
function C(e, t, n) {
|
|
164
|
+
let r = t + 1, i = "", a = !1;
|
|
165
|
+
for (; r < e.length;) {
|
|
166
|
+
let t = e[r];
|
|
167
|
+
if (t === "\\") {
|
|
168
|
+
i += t + (e[r + 1] ?? ""), r += 2;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (t === n) {
|
|
172
|
+
r++;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
if (t === "$" && e[r + 1] === "{") {
|
|
176
|
+
let t = S(e, r);
|
|
177
|
+
i += e.slice(r, t), r = t, a = !0;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
i += t, r++;
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
end: r,
|
|
184
|
+
inside: i,
|
|
185
|
+
hasInterp: a
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function w(e) {
|
|
189
|
+
let t = [], n = 0, r = "", i = () => {
|
|
190
|
+
r &&= (t.push(JSON.stringify(T(r))), "");
|
|
191
|
+
};
|
|
192
|
+
for (; n < e.length;) {
|
|
193
|
+
if (e[n] === "\\") {
|
|
194
|
+
r += e[n] + (e[n + 1] ?? ""), n += 2;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (e[n] === "$" && e[n + 1] === "{") {
|
|
198
|
+
i();
|
|
199
|
+
let r = S(e, n), a = e.slice(n + 2, r - 1).trim();
|
|
200
|
+
a && t.push(`(${a})`), n = r;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
r += e[n], n++;
|
|
204
|
+
}
|
|
205
|
+
return i(), t.length === 0 ? "\"\"" : t.length === 1 ? t[0] : t.join(" + ");
|
|
206
|
+
}
|
|
207
|
+
function T(e) {
|
|
208
|
+
let t = {
|
|
209
|
+
n: "\n",
|
|
210
|
+
t: " ",
|
|
211
|
+
r: "\r"
|
|
212
|
+
}, n = "", r = 0;
|
|
213
|
+
for (; r < e.length;) {
|
|
214
|
+
let i = e[r];
|
|
215
|
+
if (i === "\\" && r + 1 < e.length) {
|
|
216
|
+
let i = e[r + 1];
|
|
217
|
+
if (i in t) {
|
|
218
|
+
n += t[i], r += 2;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
n += i, r += 2;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
n += i, r++;
|
|
225
|
+
}
|
|
226
|
+
return n;
|
|
227
|
+
}
|
|
228
|
+
function E(e) {
|
|
229
|
+
let t = "", n = 0, r = e.length;
|
|
230
|
+
for (; n < r;) {
|
|
231
|
+
let i = e.indexOf("<", n);
|
|
232
|
+
if (i === -1) {
|
|
233
|
+
t += e.slice(n);
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
if (t += e.slice(n, i), n = i, e.startsWith("<!--", n)) {
|
|
237
|
+
let r = e.indexOf("-->", n + 4);
|
|
238
|
+
if (r === -1) {
|
|
239
|
+
t += e.slice(n);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
t += e.slice(n, r + 3), n = r + 3;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (e[n + 1] === "/" || e[n + 1] === "!" || e[n + 1] === "?") {
|
|
246
|
+
let r = e.indexOf(">", n + 1);
|
|
247
|
+
if (r === -1) {
|
|
248
|
+
t += e.slice(n);
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
t += e.slice(n, r + 1), n = r + 1;
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
let a = n + 1;
|
|
255
|
+
for (; a < r && /[a-zA-Z0-9-]/.test(e[a]);) a++;
|
|
256
|
+
for (t += e.slice(n, a), n = a; n < r;) {
|
|
257
|
+
let i = "";
|
|
258
|
+
for (; n < r && /\s/.test(e[n]);) i += e[n], n++;
|
|
259
|
+
if (n >= r) {
|
|
260
|
+
t += i;
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
if (e[n] === ">") {
|
|
264
|
+
t += i + ">", n++;
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
if (e[n] === "/" && e[n + 1] === ">") {
|
|
268
|
+
t += i + "/>", n += 2;
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
if (e[n] === "$" && e[n + 1] === "{") {
|
|
272
|
+
let r = S(e, n);
|
|
273
|
+
t += i + e.slice(n, r), n = r;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
let a = n;
|
|
277
|
+
for (; n < r && !/[\s=/>"'$]/.test(e[n]);) n++;
|
|
278
|
+
let o = e.slice(a, n);
|
|
279
|
+
if (!o) {
|
|
280
|
+
t += i + e[n], n++;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
let s = "";
|
|
284
|
+
for (; n < r && /\s/.test(e[n]);) s += e[n], n++;
|
|
285
|
+
if (e[n] !== "=") {
|
|
286
|
+
t += i + o + s;
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
n++;
|
|
290
|
+
let c = "";
|
|
291
|
+
for (; n < r && /\s/.test(e[n]);) c += e[n], n++;
|
|
292
|
+
let l = e[n];
|
|
293
|
+
if (l === "\"" || l === "'") {
|
|
294
|
+
let { end: r, inside: a, hasInterp: u } = C(e, n, l);
|
|
295
|
+
if (u) {
|
|
296
|
+
let l = S(a, 0);
|
|
297
|
+
if (!(a.startsWith("${") && l === a.length && !a.slice(2, l - 1).includes("${"))) {
|
|
298
|
+
t += i + o + s + "=${" + w(a) + "}", n = r;
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
t += i + o + s + "=" + c + e.slice(n, r);
|
|
302
|
+
} else t += i + o + s + "=" + c + e.slice(n, r);
|
|
303
|
+
n = r;
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
let u = "";
|
|
307
|
+
for (; n < r && !/\s/.test(e[n]) && e[n] !== ">" && (e[n] !== "/" || e[n + 1] !== ">");) u += e[n], n++;
|
|
308
|
+
t += i + o + s + "=" + c + u;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return t;
|
|
312
|
+
}
|
|
313
|
+
function D(e) {
|
|
314
|
+
let t = "", n = 0;
|
|
315
|
+
for (; n < e.length;) {
|
|
316
|
+
let r = e.indexOf(b, n);
|
|
317
|
+
if (r === -1) {
|
|
318
|
+
t += e.slice(n);
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
for (t += e.slice(n, r + 4), n = r + 4; n < e.length && /\s/.test(e[n]);) t += e[n], n++;
|
|
322
|
+
if (n >= e.length || e[n] !== x) continue;
|
|
323
|
+
t += e[n], n++;
|
|
324
|
+
let i = 1, a = "";
|
|
325
|
+
for (; n < e.length && i > 0;) {
|
|
326
|
+
let t = e[n];
|
|
327
|
+
if (t === "\\") {
|
|
328
|
+
a += t + e[n + 1], n += 2;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (t === x && (i--, i === 0)) {
|
|
332
|
+
n++;
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
if (t === "$" && e[n + 1] === "{") {
|
|
336
|
+
let t = S(e, n);
|
|
337
|
+
a += e.slice(n, t), n = t;
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
a += t, n++;
|
|
341
|
+
}
|
|
342
|
+
let o = E(a);
|
|
343
|
+
t += o, t += x;
|
|
344
|
+
}
|
|
345
|
+
return t;
|
|
346
|
+
}
|
|
347
|
+
function O(e = {}) {
|
|
348
|
+
let t = e.appDir ?? "src/app", n = e.islandsDir ?? "src/islands";
|
|
349
|
+
return {
|
|
350
|
+
name: "elur-kit-interpolation",
|
|
351
|
+
enforce: "pre",
|
|
352
|
+
transform(e, r) {
|
|
353
|
+
if (!r.endsWith(".ts") && !r.endsWith(".js") || !r.includes(t) && !r.includes(n) || !e.includes("html`")) return;
|
|
354
|
+
let i = D(e);
|
|
355
|
+
if (i !== e) return {
|
|
356
|
+
code: i,
|
|
357
|
+
map: null
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
//#endregion
|
|
363
|
+
export { f as a, u as c, d as i, O as n, p as o, y as r, c as s, v as t };
|
|
364
|
+
|
|
365
|
+
//# sourceMappingURL=interpolation-plugin-Bt-KRKVY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpolation-plugin-Bt-KRKVY.js","names":[],"sources":["../../src/island/generate-entry.ts","../../src/middleware/index.ts","../../src/vite/interpolation-plugin.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, relative, sep } from \"node:path\";\nimport type { IslandModule } from \"./scan.js\";\n\n// --- Client entry generator ---\n//\n// Turns a list of scanned islands into a client entry module that imports each\n// island and registers it with `hydrateIslands`. This removes the need to hand-\n// maintain `entry-client.ts` as islands are added or removed.\n//\n// The generated file imports island default exports and passes them to\n// `hydrateIslands` keyed by their registry name.\n\n/** Options for generating the client entry module. */\nexport interface GenerateEntryOptions {\n /** Islands to register, from `scanIslands`. */\n islands: IslandModule[];\n /** Absolute path of the entry file to write (e.g. \".elur/entry-client.ts\"). */\n outFile: string;\n /**\n * Import specifier for the kit's client island helpers.\n * Defaults to the published subpath `@elurjs/kit/island`.\n */\n hydrateImport?: string;\n /**\n * Import specifier for the kit's client router.\n * Defaults to the published subpath `@elurjs/kit/router`.\n */\n routerImport?: string;\n}\n\n/** Turns a registry name into a safe JS identifier for the import binding. */\nfunction toIdentifier(name: string, index: number): string {\n const cleaned = name.replace(/[^a-zA-Z0-9_$]/g, \"_\");\n return /^[a-zA-Z_$]/.test(cleaned) ? `${cleaned}_${index}` : `_${cleaned}_${index}`;\n}\n\n/** Builds the source code of the client entry module. */\nexport function buildEntrySource(\n islands: IslandModule[],\n outFile: string,\n hydrateImport = \"@elurjs/kit/island\",\n routerImport = \"@elurjs/kit/router\",\n): string {\n const bindings = islands.map((island, i) => ({\n ident: toIdentifier(island.name, i),\n name: island.name,\n // Relative import specifier from the entry file to the island module.\n spec: toImportSpecifier(outFile, island.filePath),\n }));\n\n // Lazy registry: each island is loaded on-demand via dynamic import().\n // This enables code-splitting — islands not on the current page (or not yet\n // triggered by their directive) stay out of the initial bundle.\n //\n // The registry maps island name → discriminated lazy loader `{ load }`.\n // hydrateIslands() awaits `entry.load()` before hydrating, so the first\n // paint only needs the small entry chunk + the islands on the page. The\n // discriminated form lets the hydrator tell eager components from lazy\n // loaders without executing a probe.\n const registryLines = bindings\n .map((b) => ` ${JSON.stringify(b.name)}: { load: () => import(${JSON.stringify(b.spec)}).then(m => m.default) },`)\n .join(\"\\n\");\n\n const islandHydration = registryLines\n ? `const registry = {\n${registryLines}\n};\nhydrateIslands(registry);\ndocument.addEventListener(\"elur:rendered\", () => {\n cleanupHydratedIslands();\n hydrateIslands(registry);\n});\n\n// Vite HMR: when an island module (or the entry itself) updates, dispose the\n// current islands and re-hydrate from the updated modules — the registry's\n// dynamic import() resolves to the fresh modules, so no full page reload is\n// needed (progressive enhancement, audit §10.2 / §12.2).\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n cleanupHydratedIslands();\n hydrateIslands(registry);\n if (newModule) {\n // Re-run the module so its side effects (router, listeners) apply.\n }\n });\n}`\n : \"\";\n\n return `// AUTO-GENERATED by @elurjs/kit. Do not edit.\nimport { startClientRouter } from ${JSON.stringify(routerImport)};\nimport { hydrateIslands, cleanupHydratedIslands } from ${JSON.stringify(hydrateImport)};\n\nstartClientRouter();\n${islandHydration}\n`;\n}\n\n/** Computes a POSIX-style relative import specifier between two files. */\nfunction toImportSpecifier(fromFile: string, toFile: string): string {\n let spec = relative(dirname(fromFile), toFile).split(sep).join(\"/\");\n if (!spec.startsWith(\".\")) spec = `./${spec}`;\n return spec;\n}\n\n/**\n * Generates and writes the client entry module for the given islands.\n *\n * @param options Generation options.\n * @returns The absolute path of the written entry file.\n */\nexport async function generateClientEntry(\n options: GenerateEntryOptions,\n): Promise<string> {\n const source = buildEntrySource(\n options.islands,\n options.outFile,\n options.hydrateImport,\n options.routerImport,\n );\n await mkdir(dirname(options.outFile), { recursive: true });\n await writeFile(options.outFile, source, \"utf8\");\n return options.outFile;\n}\n","// --- Middleware ---\n//\n// Convention: `src/middleware.ts` in the project root exports a default\n// function and an optional `config` with a `matcher` array.\n//\n// import type { Middleware } from \"@elurjs/kit\";\n//\n// export default function middleware(request: Request) {\n// if (!request.headers.get(\"Cookie\")?.includes(\"session=\")) {\n// return Response.redirect(new URL(\"/login\", request.url), 307);\n// }\n// }\n//\n// export const config = { matcher: [\"/dashboard/:path*\", \"/admin/:path*\"] };\n//\n// The middleware runs before routing. Return a `Response` to short-circuit\n// (redirect, rewrite, 401, etc.). Return `undefined` or nothing to continue.\n// Use `next()` to pass headers to the loader.\n\nimport { matchRoute } from \"../ssr/match.js\";\nimport type { PageRoute } from \"../router/route-scanner.js\";\n\n/** The middleware function signature. */\nexport type Middleware = (request: Request, context: MiddlewareContext) =>\n | Response\n | void\n | Promise<Response | void>;\n\n/** Context passed to the middleware function. */\nexport interface MiddlewareContext {\n /** Helper to continue to the next handler. Can attach headers, params, and locals. */\n next(options?: {\n headers?: Record<string, string>;\n params?: Record<string, string | string[]>;\n locals?: Record<string, unknown>;\n }): void;\n /** Matched route params (only available if the path matches a page route). */\n params?: Record<string, string | string[]>;\n /** Per-request locals (populated by middleware, available to loaders/actions). */\n locals?: Record<string, unknown>;\n}\n\n/** Configuration for the middleware module. */\nexport interface MiddlewareConfig {\n /** Path patterns that trigger the middleware. Supports `:param` and `:param*`. */\n matcher?: string[];\n}\n\nexport interface LoadedMiddleware {\n handler: Middleware;\n config: MiddlewareConfig;\n}\n\n/** Result of running middleware: either a response to short-circuit with, or continue. */\nexport type MiddlewareResult =\n | { kind: \"response\"; response: Response }\n | {\n kind: \"continue\";\n headers?: Record<string, string>;\n params?: Record<string, string | string[]>;\n locals?: Record<string, unknown>;\n };\n\n/**\n * Loads the user's `src/middleware.ts` module. Returns `null` if no middleware\n * file exists. Distinguishes \"file not found\" from \"file has errors\" (§6):\n * an import error is not silently treated as \"no middleware\".\n */\nexport async function loadMiddleware(root: string): Promise<LoadedMiddleware | null> {\n const candidates = [\n `${root}/src/middleware.ts`,\n `${root}/middleware.ts`,\n ];\n\n for (const path of candidates) {\n try {\n const mod = await import(path);\n const handler = (mod.default ?? mod.middleware) as Middleware | undefined;\n if (typeof handler !== \"function\") continue;\n const config = (mod.config ?? {}) as MiddlewareConfig;\n return { handler, config };\n } catch (err) {\n // Distinguish \"module not found\" from actual errors.\n // If the error is a module resolution error for this specific file,\n // it means the file doesn't exist — try the next candidate.\n // If it's a syntax/runtime error, rethrow so the user sees it.\n // Note: Bun's ResolveMessage is not `instanceof Error`, so match on the\n // message property instead of relying on the class hierarchy.\n const msg =\n typeof err === \"object\" && err !== null && \"message\" in err\n ? String((err as { message: unknown }).message)\n : String(err);\n if (\n msg.includes(\"Cannot find module\") ||\n msg.includes(\"Cannot find package\") ||\n msg.includes(\"ENOENT\") ||\n msg.includes(\"Module not found\")\n ) {\n // File doesn't exist — try next candidate.\n continue;\n }\n // Actual error in the middleware file — rethrow (§6).\n throw new Error(`[elur-kit] Error loading middleware: ${msg}`, { cause: err });\n }\n }\n\n return null;\n}\n\n/**\n * Checks if a pathname matches any of the middleware's matcher patterns.\n * If no matcher is configured, the middleware runs for every request.\n *\n * Catch-all patterns (`:param*`) match both the base path and any sub-paths,\n * e.g. `/dashboard/:path*` matches `/dashboard` and `/dashboard/settings/users`.\n */\nexport function matchesMiddleware(pathname: string, config: MiddlewareConfig): boolean {\n if (!config.matcher || config.matcher.length === 0) return true;\n\n const cleanPath = pathname.split(\"?\")[0];\n\n for (const pattern of config.matcher) {\n // Exact match.\n if (pattern === cleanPath) return true;\n\n // Check for catch-all: `/foo/:bar*` should also match `/foo`.\n const catchAllMatch = pattern.match(/^(.*)\\/:[\\w]+\\*$/);\n if (catchAllMatch) {\n const base = catchAllMatch[1];\n if (cleanPath === base) return true;\n }\n\n // Use matchRoute for param matching.\n const pseudoRoutes: PageRoute[] = [{\n path: pattern,\n pagePath: \"\",\n params: [],\n layouts: [],\n }];\n if (matchRoute(cleanPath, pseudoRoutes)) return true;\n }\n\n return false;\n}\n\n/**\n * Runs the middleware for a request. Returns the result indicating whether to\n * short-circuit with a response or continue with propagated headers/params/locals.\n *\n * Per §6: cleanup runs in `finally`, response short-circuits the pipeline,\n * headers/params/locals are propagated to downstream handlers.\n */\nexport async function runMiddleware(\n middleware: LoadedMiddleware,\n request: Request,\n params?: Record<string, string | string[]>,\n): Promise<MiddlewareResult> {\n let nextHeaders: Record<string, string> | undefined;\n let nextParams: Record<string, string | string[]> | undefined;\n let nextLocals: Record<string, unknown> | undefined;\n const cleanups: Array<() => void | Promise<void>> = [];\n\n const context: MiddlewareContext = {\n next(options) {\n if (options?.headers) nextHeaders = options.headers;\n if (options?.params) nextParams = options.params;\n if (options?.locals) nextLocals = options.locals;\n },\n params,\n locals: {},\n };\n\n try {\n const result = await middleware.handler(request, context);\n\n if (result instanceof Response) {\n return { kind: \"response\", response: result };\n }\n\n return {\n kind: \"continue\",\n headers: nextHeaders,\n params: nextParams ?? params,\n locals: nextLocals,\n };\n } finally {\n // Run any cleanup functions (§6). Errors in cleanup are logged but\n // do not propagate to the caller.\n for (const cleanup of cleanups) {\n try {\n await cleanup();\n } catch (err) {\n console.error(\"[elur-kit] middleware cleanup error:\", err);\n }\n }\n }\n}\n","import { createRequire } from \"node:module\";\nimport type { Plugin } from \"vite\";\n\n/**\n * How the legacy interpolation transform is handled relative to the installed\n * Elur core and Vite plugin:\n *\n * - `\"auto\"` (default): the kit's legacy transform is only applied when the\n * Vite plugin (`@elurjs/vite-plugin-elur` >= 1.1.0) is NOT installed.\n * The plugin has a more powerful state-machine lexer and takes precedence.\n * - `\"legacy\"`: always apply the kit's transform (for migrations), with a\n * one-time deprecation warning.\n * - `\"off\"`: never apply the kit's transform. Recommended when the Vite\n * plugin is installed.\n */\nexport type InterpolationMode = \"auto\" | \"legacy\" | \"off\";\n\nconst require = createRequire(import.meta.url);\n\nlet _warnedLegacy = false;\n\nfunction warnLegacyOnce(): void {\n if (_warnedLegacy) return;\n _warnedLegacy = true;\n console.warn(\n \"[elur-kit] The legacy interpolation transform is deprecated. \" +\n \"Install @elurjs/vite-plugin-elur >= 1.1.0 for compile-time \" +\n \"partial attribute interpolation. Remove `interpolation: \\\"legacy\\\"` \" +\n \"once migration is complete.\",\n );\n}\n\n/**\n * Detects whether the Vite plugin (`@elurjs/vite-plugin-elur`) is\n * installed and provides compile-time partial attribute interpolation.\n */\nexport function pluginSupportsPartialInterpolation(): boolean {\n try {\n const pkg = require(\"@elurjs/vite-plugin-elur/package.json\") as {\n version?: string;\n };\n // >= 1.1.0 has the interpolation lexer\n const [major, minor] = (pkg.version ?? \"0.0.0\").split(\".\").map(Number);\n return major > 1 || (major === 1 && minor >= 1);\n } catch {\n return false;\n }\n}\n\n/**\n * Detects whether the installed Elur core supports partial attribute\n * interpolation natively (via the public `templateFeatures` capability).\n * Note: as of core v3.4.0, this is always false — the lexer moved to the\n * Vite plugin.\n */\nexport function coreSupportsPartialInterpolation(): boolean {\n try {\n const core = require(\"@elurjs/core\") as {\n templateFeatures?: { partialAttributeInterpolation?: boolean };\n };\n return core?.templateFeatures?.partialAttributeInterpolation === true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolves whether the kit's legacy transform should be applied.\n *\n * In `\"auto\"` mode, the kit's transform runs only when neither the Vite\n * plugin nor the core provides partial interpolation. When the Vite plugin\n * is installed (>= 1.1.0), it takes precedence and the kit's transform is\n * skipped to avoid double-processing.\n */\nexport function shouldUseLegacyInterpolation(mode: InterpolationMode): boolean {\n if (mode === \"off\") return false;\n if (mode === \"legacy\") {\n warnLegacyOnce();\n return true;\n }\n // auto: skip if the Vite plugin handles it\n if (pluginSupportsPartialInterpolation()) return false;\n // fallback: use legacy if core doesn't support it natively\n return !coreSupportsPartialInterpolation();\n}\n\n/**\n * Transforms Elur `html\\`\\`` templates so that attributes with partial\n * interpolation become a single interpolation expression.\n *\n * Elur requires every dynamic attribute to be a single interpolation covering\n * the whole value. This plugin rewrites patterns such as:\n *\n * html\\`<a href=\"/blog/${slug}\">...</a>\\`\n *\n * into:\n *\n * html\\`<a href=${\"/blog/\" + slug}>...</a>\\`\n *\n * Only files inside the app and islands directories are processed.\n *\n * @deprecated Elur core supports partial attribute interpolation natively.\n * Keep this transform only for migrations against older cores\n * (`interpolation: \"legacy\"`).\n */\nexport interface InterpolationPluginOptions {\n appDir?: string;\n islandsDir?: string;\n}\n\nconst HTML_TAG = \"html\";\nconst TEMPLATE_START = \"`\";\n\n/**\n * Scans a `${...}` interpolation starting at `start` (where content[start] is\n * `$` and content[start + 1] is `{`), honoring nested braces, strings and\n * escape sequences. Returns the index just past the closing `}`.\n */\nfunction scanInterpolation(content: string, start: number): number {\n let depth = 1;\n let i = start + 2;\n while (i < content.length && depth > 0) {\n const c = content[i];\n if (c === \"\\\\\") {\n i += 2;\n continue;\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n const q = c;\n i++;\n while (i < content.length) {\n if (content[i] === \"\\\\\") {\n i += 2;\n continue;\n }\n if (content[i] === q) break;\n i++;\n }\n i++;\n continue;\n }\n if (c === \"{\") depth++;\n else if (c === \"}\") depth--;\n i++;\n }\n return i;\n}\n\n/**\n * Scans a quoted attribute value starting at `start` (where content[start] is\n * the quote character). Handles escapes, `${...}` interpolations with nested\n * braces, and nested quotes. Returns the index just past the closing quote,\n * the raw inner text (escapes preserved as in the source) and whether the\n * value contains at least one interpolation.\n */\nfunction scanQuotedValue(\n content: string,\n start: number,\n quote: string,\n): { end: number; inside: string; hasInterp: boolean } {\n let i = start + 1;\n let inside = \"\";\n let hasInterp = false;\n while (i < content.length) {\n const c = content[i];\n if (c === \"\\\\\") {\n inside += c + (content[i + 1] ?? \"\");\n i += 2;\n continue;\n }\n if (c === quote) {\n i++;\n break;\n }\n if (c === \"$\" && content[i + 1] === \"{\") {\n const end = scanInterpolation(content, i);\n inside += content.slice(i, end);\n i = end;\n hasInterp = true;\n continue;\n }\n inside += c;\n i++;\n }\n return { end: i, inside, hasInterp };\n}\n\n/**\n * Converts the inner text of a quoted attribute value (which may contain\n * `${...}` interpolations) into a JS expression. Literal parts are JSON\n * encoded; interpolations keep their raw expression text.\n *\n * Examples:\n * /blog/${slug} -> \"/blog/\" + (slug)\n * ${slug} -> (slug)\n * tag ${cls({a:1})} -> \"tag \" + (cls({a:1}))\n */\nfunction valueToExpression(value: string): string {\n const parts: string[] = [];\n let i = 0;\n let literal = \"\";\n const flush = () => {\n if (literal) {\n parts.push(JSON.stringify(unescapeAttributeLiteral(literal)));\n literal = \"\";\n }\n };\n\n while (i < value.length) {\n if (value[i] === \"\\\\\") {\n literal += value[i] + (value[i + 1] ?? \"\");\n i += 2;\n continue;\n }\n if (value[i] === \"$\" && value[i + 1] === \"{\") {\n flush();\n const end = scanInterpolation(value, i);\n const expr = value.slice(i + 2, end - 1).trim();\n if (expr) parts.push(`(${expr})`);\n i = end;\n continue;\n }\n literal += value[i];\n i++;\n }\n flush();\n\n if (parts.length === 0) return '\"\"';\n if (parts.length === 1) return parts[0] as string;\n return parts.join(\" + \");\n}\n\n/**\n * Unescapes escape sequences that appear inside a JS template literal so the\n * JSON.stringify output matches the runtime string value.\n */\nfunction unescapeAttributeLiteral(literal: string): string {\n const escapes: Record<string, string> = {\n n: \"\\n\",\n t: \"\\t\",\n r: \"\\r\",\n };\n let out = \"\";\n let i = 0;\n while (i < literal.length) {\n const c = literal[i];\n if (c === \"\\\\\" && i + 1 < literal.length) {\n const next = literal[i + 1];\n if (next in escapes) {\n out += escapes[next];\n i += 2;\n continue;\n }\n out += next;\n i += 2;\n continue;\n }\n out += c;\n i++;\n }\n return out;\n}\n\n/**\n * Rewrites quoted attribute values that contain interpolations inside html``\n * templates, leaving everything else untouched.\n */\nfunction transformTemplateContent(content: string): string {\n let out = \"\";\n let i = 0;\n const n = content.length;\n\n while (i < n) {\n const lt = content.indexOf(\"<\", i);\n if (lt === -1) {\n out += content.slice(i);\n break;\n }\n out += content.slice(i, lt);\n i = lt;\n\n // HTML comments: copy verbatim.\n if (content.startsWith(\"<!--\", i)) {\n const end = content.indexOf(\"-->\", i + 4);\n if (end === -1) {\n out += content.slice(i);\n break;\n }\n out += content.slice(i, end + 3);\n i = end + 3;\n continue;\n }\n\n // Closing tags, doctype, CDATA, processing instructions: copy verbatim.\n if (content[i + 1] === \"/\" || content[i + 1] === \"!\" || content[i + 1] === \"?\") {\n const gt = content.indexOf(\">\", i + 1);\n if (gt === -1) {\n out += content.slice(i);\n break;\n }\n out += content.slice(i, gt + 1);\n i = gt + 1;\n continue;\n }\n\n // Opening tag. Copy the tag name, then walk its attributes.\n let j = i + 1;\n while (j < n && /[a-zA-Z0-9-]/.test(content[j])) j++;\n out += content.slice(i, j);\n i = j;\n\n while (i < n) {\n let ws = \"\";\n while (i < n && /\\s/.test(content[i])) {\n ws += content[i];\n i++;\n }\n if (i >= n) {\n out += ws;\n break;\n }\n if (content[i] === \">\") {\n out += ws + \">\";\n i++;\n break;\n }\n if (content[i] === \"/\" && content[i + 1] === \">\") {\n out += ws + \"/>\";\n i += 2;\n break;\n }\n // Interpolation in the tag body (dynamic attrs/spread): copy verbatim.\n if (content[i] === \"$\" && content[i + 1] === \"{\") {\n const end = scanInterpolation(content, i);\n out += ws + content.slice(i, end);\n i = end;\n continue;\n }\n\n // Attribute name.\n let nameStart = i;\n while (i < n && !/[\\s=/>\"'$]/.test(content[i])) i++;\n const name = content.slice(nameStart, i);\n if (!name) {\n out += ws + content[i];\n i++;\n continue;\n }\n\n let eqWs = \"\";\n while (i < n && /\\s/.test(content[i])) {\n eqWs += content[i];\n i++;\n }\n\n if (content[i] !== \"=\") {\n out += ws + name + eqWs;\n continue;\n }\n\n i++; // consume \"=\"\n let valWs = \"\";\n while (i < n && /\\s/.test(content[i])) {\n valWs += content[i];\n i++;\n }\n\n const quote = content[i];\n if (quote === '\"' || quote === \"'\") {\n const { end, inside, hasInterp } = scanQuotedValue(content, i, quote);\n if (hasInterp) {\n // Skip values that are a single full interpolation: Elur handles\n // `attr=\"${expr}\"` natively, so only partial interpolations need the\n // rewrite.\n const first = scanInterpolation(inside, 0);\n const fullValue =\n inside.startsWith(\"${\") &&\n first === inside.length &&\n !inside.slice(2, first - 1).includes(\"${\");\n if (!fullValue) {\n // Elur needs the interpolation to start right after \"=\" (no space),\n // so the whitespace before the original value is dropped.\n out += ws + name + eqWs + \"=\" + \"${\" + valueToExpression(inside) + \"}\";\n i = end;\n continue;\n }\n out += ws + name + eqWs + \"=\" + valWs + content.slice(i, end);\n } else {\n out += ws + name + eqWs + \"=\" + valWs + content.slice(i, end);\n }\n i = end;\n continue;\n }\n\n // Unquoted value: copy up to whitespace, \">\" or \"/>\".\n let v = \"\";\n while (\n i < n &&\n !/\\s/.test(content[i]) &&\n content[i] !== \">\" &&\n !(content[i] === \"/\" && content[i + 1] === \">\")\n ) {\n v += content[i];\n i++;\n }\n out += ws + name + eqWs + \"=\" + valWs + v;\n }\n }\n\n return out;\n}\n\n/**\n * @deprecated Use the native partial attribute interpolation of Elur core\n * (core >= 3.3). Kept for legacy migrations and direct consumers.\n */\nexport function transformPartialInterpolations(source: string): string {\n let result = \"\";\n let i = 0;\n while (i < source.length) {\n // Find the next html` sequence.\n const htmlIndex = source.indexOf(HTML_TAG, i);\n if (htmlIndex === -1) {\n result += source.slice(i);\n break;\n }\n result += source.slice(i, htmlIndex + HTML_TAG.length);\n i = htmlIndex + HTML_TAG.length;\n\n // Skip whitespace before the backtick.\n while (i < source.length && /\\s/.test(source[i])) {\n result += source[i];\n i++;\n }\n if (i >= source.length || source[i] !== TEMPLATE_START) {\n continue;\n }\n result += source[i];\n i++;\n\n // Parse the template literal until the matching backtick.\n let depth = 1;\n let templateContent = \"\";\n while (i < source.length && depth > 0) {\n const char = source[i];\n if (char === \"\\\\\") {\n templateContent += char + source[i + 1];\n i += 2;\n continue;\n }\n if (char === TEMPLATE_START) {\n depth--;\n if (depth === 0) {\n i++;\n break;\n }\n }\n if (char === \"$\") {\n // Look ahead for ${...}\n if (source[i + 1] === \"{\") {\n const end = scanInterpolation(source, i);\n templateContent += source.slice(i, end);\n i = end;\n continue;\n }\n }\n templateContent += char;\n i++;\n }\n\n const transformed = transformTemplateContent(templateContent);\n result += transformed;\n result += TEMPLATE_START;\n }\n return result;\n}\n\nexport function elurJsInterpolationPlugin(options: InterpolationPluginOptions = {}): Plugin {\n const appDir = options.appDir ?? \"src/app\";\n const islandsDir = options.islandsDir ?? \"src/islands\";\n return {\n name: \"elur-kit-interpolation\",\n enforce: \"pre\",\n transform(code, id) {\n if (!id.endsWith(\".ts\") && !id.endsWith(\".js\")) return;\n if (!id.includes(appDir) && !id.includes(islandsDir)) return;\n if (!code.includes(\"html`\")) return;\n const transformed = transformPartialInterpolations(code);\n if (transformed === code) return;\n return { code: transformed, map: null };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const e=require("./node-http-DhxguYyz.cjs");let t=require("node:fs/promises"),n=require("node:path"),r=require("node:module");function i(e,t){let n=e.replace(/[^a-zA-Z0-9_$]/g,`_`);return/^[a-zA-Z_$]/.test(n)?`${n}_${t}`:`_${n}_${t}`}function a(e,t,n=`@elurjs/kit/island`,r=`@elurjs/kit/router`){let a=e.map((e,n)=>({ident:i(e.name,n),name:e.name,spec:o(t,e.filePath)})).map(e=>` ${JSON.stringify(e.name)}: { load: () => import(${JSON.stringify(e.spec)}).then(m => m.default) },`).join(`
|
|
2
|
+
`),s=a?`const registry = {
|
|
3
|
+
${a}
|
|
4
|
+
};
|
|
5
|
+
hydrateIslands(registry);
|
|
6
|
+
document.addEventListener("elur:rendered", () => {
|
|
7
|
+
cleanupHydratedIslands();
|
|
8
|
+
hydrateIslands(registry);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Vite HMR: when an island module (or the entry itself) updates, dispose the
|
|
12
|
+
// current islands and re-hydrate from the updated modules — the registry's
|
|
13
|
+
// dynamic import() resolves to the fresh modules, so no full page reload is
|
|
14
|
+
// needed (progressive enhancement, audit §10.2 / §12.2).
|
|
15
|
+
if (import.meta.hot) {
|
|
16
|
+
import.meta.hot.accept((newModule) => {
|
|
17
|
+
cleanupHydratedIslands();
|
|
18
|
+
hydrateIslands(registry);
|
|
19
|
+
if (newModule) {
|
|
20
|
+
// Re-run the module so its side effects (router, listeners) apply.
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}`:``;return`// AUTO-GENERATED by @elurjs/kit. Do not edit.
|
|
24
|
+
import { startClientRouter } from ${JSON.stringify(r)};
|
|
25
|
+
import { hydrateIslands, cleanupHydratedIslands } from ${JSON.stringify(n)};
|
|
26
|
+
|
|
27
|
+
startClientRouter();
|
|
28
|
+
${s}
|
|
29
|
+
`}function o(e,t){let r=(0,n.relative)((0,n.dirname)(e),t).split(n.sep).join(`/`);return r.startsWith(`.`)||(r=`./${r}`),r}async function s(e){let r=a(e.islands,e.outFile,e.hydrateImport,e.routerImport);return await(0,t.mkdir)((0,n.dirname)(e.outFile),{recursive:!0}),await(0,t.writeFile)(e.outFile,r,`utf8`),e.outFile}async function c(e){let t=[`${e}/src/middleware.ts`,`${e}/middleware.ts`];for(let e of t)try{let t=await import(e),n=t.default??t.middleware;if(typeof n!=`function`)continue;return{handler:n,config:t.config??{}}}catch(e){let t=typeof e==`object`&&e&&`message`in e?String(e.message):String(e);if(t.includes(`Cannot find module`)||t.includes(`Cannot find package`)||t.includes(`ENOENT`)||t.includes(`Module not found`))continue;throw Error(`[elur-kit] Error loading middleware: ${t}`,{cause:e})}return null}function l(t,n){if(!n.matcher||n.matcher.length===0)return!0;let r=t.split(`?`)[0];for(let t of n.matcher){if(t===r)return!0;let n=t.match(/^(.*)\/:[\w]+\*$/);if(n&&r===n[1]||e.o(r,[{path:t,pagePath:``,params:[],layouts:[]}]))return!0}return!1}async function u(e,t,n){let r,i,a,o=[],s={next(e){e?.headers&&(r=e.headers),e?.params&&(i=e.params),e?.locals&&(a=e.locals)},params:n,locals:{}};try{let o=await e.handler(t,s);return o instanceof Response?{kind:`response`,response:o}:{kind:`continue`,headers:r,params:i??n,locals:a}}finally{for(let e of o)try{await e()}catch(e){console.error(`[elur-kit] middleware cleanup error:`,e)}}}var d=(0,r.createRequire)({}.url),f=!1;function p(){f||(f=!0,console.warn('[elur-kit] The legacy interpolation transform is deprecated. Install @elurjs/vite-plugin-elur >= 1.1.0 for compile-time partial attribute interpolation. Remove `interpolation: "legacy"` once migration is complete.'))}function m(){try{let[e,t]=(d(`@elurjs/vite-plugin-elur/package.json`).version??`0.0.0`).split(`.`).map(Number);return e>1||e===1&&t>=1}catch{return!1}}function h(){try{return d(`@elurjs/core`)?.templateFeatures?.partialAttributeInterpolation===!0}catch{return!1}}function g(e){return e===`off`?!1:e===`legacy`?(p(),!0):!m()&&!h()}var _=`html`,v="`";function y(e,t){let n=1,r=t+2;for(;r<e.length&&n>0;){let t=e[r];if(t===`\\`){r+=2;continue}if(t===`"`||t===`'`||t==="`"){let n=t;for(r++;r<e.length;){if(e[r]===`\\`){r+=2;continue}if(e[r]===n)break;r++}r++;continue}t===`{`?n++:t===`}`&&n--,r++}return r}function b(e,t,n){let r=t+1,i=``,a=!1;for(;r<e.length;){let t=e[r];if(t===`\\`){i+=t+(e[r+1]??``),r+=2;continue}if(t===n){r++;break}if(t===`$`&&e[r+1]===`{`){let t=y(e,r);i+=e.slice(r,t),r=t,a=!0;continue}i+=t,r++}return{end:r,inside:i,hasInterp:a}}function x(e){let t=[],n=0,r=``,i=()=>{r&&=(t.push(JSON.stringify(S(r))),``)};for(;n<e.length;){if(e[n]===`\\`){r+=e[n]+(e[n+1]??``),n+=2;continue}if(e[n]===`$`&&e[n+1]===`{`){i();let r=y(e,n),a=e.slice(n+2,r-1).trim();a&&t.push(`(${a})`),n=r;continue}r+=e[n],n++}return i(),t.length===0?`""`:t.length===1?t[0]:t.join(` + `)}function S(e){let t={n:`
|
|
30
|
+
`,t:` `,r:`\r`},n=``,r=0;for(;r<e.length;){let i=e[r];if(i===`\\`&&r+1<e.length){let i=e[r+1];if(i in t){n+=t[i],r+=2;continue}n+=i,r+=2;continue}n+=i,r++}return n}function C(e){let t=``,n=0,r=e.length;for(;n<r;){let i=e.indexOf(`<`,n);if(i===-1){t+=e.slice(n);break}if(t+=e.slice(n,i),n=i,e.startsWith(`<!--`,n)){let r=e.indexOf(`-->`,n+4);if(r===-1){t+=e.slice(n);break}t+=e.slice(n,r+3),n=r+3;continue}if(e[n+1]===`/`||e[n+1]===`!`||e[n+1]===`?`){let r=e.indexOf(`>`,n+1);if(r===-1){t+=e.slice(n);break}t+=e.slice(n,r+1),n=r+1;continue}let a=n+1;for(;a<r&&/[a-zA-Z0-9-]/.test(e[a]);)a++;for(t+=e.slice(n,a),n=a;n<r;){let i=``;for(;n<r&&/\s/.test(e[n]);)i+=e[n],n++;if(n>=r){t+=i;break}if(e[n]===`>`){t+=i+`>`,n++;break}if(e[n]===`/`&&e[n+1]===`>`){t+=i+`/>`,n+=2;break}if(e[n]===`$`&&e[n+1]===`{`){let r=y(e,n);t+=i+e.slice(n,r),n=r;continue}let a=n;for(;n<r&&!/[\s=/>"'$]/.test(e[n]);)n++;let o=e.slice(a,n);if(!o){t+=i+e[n],n++;continue}let s=``;for(;n<r&&/\s/.test(e[n]);)s+=e[n],n++;if(e[n]!==`=`){t+=i+o+s;continue}n++;let c=``;for(;n<r&&/\s/.test(e[n]);)c+=e[n],n++;let l=e[n];if(l===`"`||l===`'`){let{end:r,inside:a,hasInterp:u}=b(e,n,l);if(u){let l=y(a,0);if(!(a.startsWith("${")&&l===a.length&&!a.slice(2,l-1).includes("${"))){t+=i+o+s+"=${"+x(a)+`}`,n=r;continue}t+=i+o+s+`=`+c+e.slice(n,r)}else t+=i+o+s+`=`+c+e.slice(n,r);n=r;continue}let u=``;for(;n<r&&!/\s/.test(e[n])&&e[n]!==`>`&&(e[n]!==`/`||e[n+1]!==`>`);)u+=e[n],n++;t+=i+o+s+`=`+c+u}}return t}function w(e){let t=``,n=0;for(;n<e.length;){let r=e.indexOf(_,n);if(r===-1){t+=e.slice(n);break}for(t+=e.slice(n,r+4),n=r+4;n<e.length&&/\s/.test(e[n]);)t+=e[n],n++;if(n>=e.length||e[n]!==v)continue;t+=e[n],n++;let i=1,a=``;for(;n<e.length&&i>0;){let t=e[n];if(t===`\\`){a+=t+e[n+1],n+=2;continue}if(t===v&&(i--,i===0)){n++;break}if(t===`$`&&e[n+1]===`{`){let t=y(e,n);a+=e.slice(n,t),n=t;continue}a+=t,n++}let o=C(a);t+=o,t+=v}return t}function T(e={}){let t=e.appDir??`src/app`,n=e.islandsDir??`src/islands`;return{name:`elur-kit-interpolation`,enforce:`pre`,transform(e,r){if(!r.endsWith(`.ts`)&&!r.endsWith(`.js`)||!r.includes(t)&&!r.includes(n)||!e.includes("html`"))return;let i=w(e);if(i!==e)return{code:i,map:null}}}}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return h}});
|
|
31
|
+
//# sourceMappingURL=interpolation-plugin-CMPCDlVJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpolation-plugin-CMPCDlVJ.cjs","names":[],"sources":["../../src/island/generate-entry.ts","../../src/middleware/index.ts","../../src/vite/interpolation-plugin.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, relative, sep } from \"node:path\";\nimport type { IslandModule } from \"./scan.js\";\n\n// --- Client entry generator ---\n//\n// Turns a list of scanned islands into a client entry module that imports each\n// island and registers it with `hydrateIslands`. This removes the need to hand-\n// maintain `entry-client.ts` as islands are added or removed.\n//\n// The generated file imports island default exports and passes them to\n// `hydrateIslands` keyed by their registry name.\n\n/** Options for generating the client entry module. */\nexport interface GenerateEntryOptions {\n /** Islands to register, from `scanIslands`. */\n islands: IslandModule[];\n /** Absolute path of the entry file to write (e.g. \".elur/entry-client.ts\"). */\n outFile: string;\n /**\n * Import specifier for the kit's client island helpers.\n * Defaults to the published subpath `@elurjs/kit/island`.\n */\n hydrateImport?: string;\n /**\n * Import specifier for the kit's client router.\n * Defaults to the published subpath `@elurjs/kit/router`.\n */\n routerImport?: string;\n}\n\n/** Turns a registry name into a safe JS identifier for the import binding. */\nfunction toIdentifier(name: string, index: number): string {\n const cleaned = name.replace(/[^a-zA-Z0-9_$]/g, \"_\");\n return /^[a-zA-Z_$]/.test(cleaned) ? `${cleaned}_${index}` : `_${cleaned}_${index}`;\n}\n\n/** Builds the source code of the client entry module. */\nexport function buildEntrySource(\n islands: IslandModule[],\n outFile: string,\n hydrateImport = \"@elurjs/kit/island\",\n routerImport = \"@elurjs/kit/router\",\n): string {\n const bindings = islands.map((island, i) => ({\n ident: toIdentifier(island.name, i),\n name: island.name,\n // Relative import specifier from the entry file to the island module.\n spec: toImportSpecifier(outFile, island.filePath),\n }));\n\n // Lazy registry: each island is loaded on-demand via dynamic import().\n // This enables code-splitting — islands not on the current page (or not yet\n // triggered by their directive) stay out of the initial bundle.\n //\n // The registry maps island name → discriminated lazy loader `{ load }`.\n // hydrateIslands() awaits `entry.load()` before hydrating, so the first\n // paint only needs the small entry chunk + the islands on the page. The\n // discriminated form lets the hydrator tell eager components from lazy\n // loaders without executing a probe.\n const registryLines = bindings\n .map((b) => ` ${JSON.stringify(b.name)}: { load: () => import(${JSON.stringify(b.spec)}).then(m => m.default) },`)\n .join(\"\\n\");\n\n const islandHydration = registryLines\n ? `const registry = {\n${registryLines}\n};\nhydrateIslands(registry);\ndocument.addEventListener(\"elur:rendered\", () => {\n cleanupHydratedIslands();\n hydrateIslands(registry);\n});\n\n// Vite HMR: when an island module (or the entry itself) updates, dispose the\n// current islands and re-hydrate from the updated modules — the registry's\n// dynamic import() resolves to the fresh modules, so no full page reload is\n// needed (progressive enhancement, audit §10.2 / §12.2).\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n cleanupHydratedIslands();\n hydrateIslands(registry);\n if (newModule) {\n // Re-run the module so its side effects (router, listeners) apply.\n }\n });\n}`\n : \"\";\n\n return `// AUTO-GENERATED by @elurjs/kit. Do not edit.\nimport { startClientRouter } from ${JSON.stringify(routerImport)};\nimport { hydrateIslands, cleanupHydratedIslands } from ${JSON.stringify(hydrateImport)};\n\nstartClientRouter();\n${islandHydration}\n`;\n}\n\n/** Computes a POSIX-style relative import specifier between two files. */\nfunction toImportSpecifier(fromFile: string, toFile: string): string {\n let spec = relative(dirname(fromFile), toFile).split(sep).join(\"/\");\n if (!spec.startsWith(\".\")) spec = `./${spec}`;\n return spec;\n}\n\n/**\n * Generates and writes the client entry module for the given islands.\n *\n * @param options Generation options.\n * @returns The absolute path of the written entry file.\n */\nexport async function generateClientEntry(\n options: GenerateEntryOptions,\n): Promise<string> {\n const source = buildEntrySource(\n options.islands,\n options.outFile,\n options.hydrateImport,\n options.routerImport,\n );\n await mkdir(dirname(options.outFile), { recursive: true });\n await writeFile(options.outFile, source, \"utf8\");\n return options.outFile;\n}\n","// --- Middleware ---\n//\n// Convention: `src/middleware.ts` in the project root exports a default\n// function and an optional `config` with a `matcher` array.\n//\n// import type { Middleware } from \"@elurjs/kit\";\n//\n// export default function middleware(request: Request) {\n// if (!request.headers.get(\"Cookie\")?.includes(\"session=\")) {\n// return Response.redirect(new URL(\"/login\", request.url), 307);\n// }\n// }\n//\n// export const config = { matcher: [\"/dashboard/:path*\", \"/admin/:path*\"] };\n//\n// The middleware runs before routing. Return a `Response` to short-circuit\n// (redirect, rewrite, 401, etc.). Return `undefined` or nothing to continue.\n// Use `next()` to pass headers to the loader.\n\nimport { matchRoute } from \"../ssr/match.js\";\nimport type { PageRoute } from \"../router/route-scanner.js\";\n\n/** The middleware function signature. */\nexport type Middleware = (request: Request, context: MiddlewareContext) =>\n | Response\n | void\n | Promise<Response | void>;\n\n/** Context passed to the middleware function. */\nexport interface MiddlewareContext {\n /** Helper to continue to the next handler. Can attach headers, params, and locals. */\n next(options?: {\n headers?: Record<string, string>;\n params?: Record<string, string | string[]>;\n locals?: Record<string, unknown>;\n }): void;\n /** Matched route params (only available if the path matches a page route). */\n params?: Record<string, string | string[]>;\n /** Per-request locals (populated by middleware, available to loaders/actions). */\n locals?: Record<string, unknown>;\n}\n\n/** Configuration for the middleware module. */\nexport interface MiddlewareConfig {\n /** Path patterns that trigger the middleware. Supports `:param` and `:param*`. */\n matcher?: string[];\n}\n\nexport interface LoadedMiddleware {\n handler: Middleware;\n config: MiddlewareConfig;\n}\n\n/** Result of running middleware: either a response to short-circuit with, or continue. */\nexport type MiddlewareResult =\n | { kind: \"response\"; response: Response }\n | {\n kind: \"continue\";\n headers?: Record<string, string>;\n params?: Record<string, string | string[]>;\n locals?: Record<string, unknown>;\n };\n\n/**\n * Loads the user's `src/middleware.ts` module. Returns `null` if no middleware\n * file exists. Distinguishes \"file not found\" from \"file has errors\" (§6):\n * an import error is not silently treated as \"no middleware\".\n */\nexport async function loadMiddleware(root: string): Promise<LoadedMiddleware | null> {\n const candidates = [\n `${root}/src/middleware.ts`,\n `${root}/middleware.ts`,\n ];\n\n for (const path of candidates) {\n try {\n const mod = await import(path);\n const handler = (mod.default ?? mod.middleware) as Middleware | undefined;\n if (typeof handler !== \"function\") continue;\n const config = (mod.config ?? {}) as MiddlewareConfig;\n return { handler, config };\n } catch (err) {\n // Distinguish \"module not found\" from actual errors.\n // If the error is a module resolution error for this specific file,\n // it means the file doesn't exist — try the next candidate.\n // If it's a syntax/runtime error, rethrow so the user sees it.\n // Note: Bun's ResolveMessage is not `instanceof Error`, so match on the\n // message property instead of relying on the class hierarchy.\n const msg =\n typeof err === \"object\" && err !== null && \"message\" in err\n ? String((err as { message: unknown }).message)\n : String(err);\n if (\n msg.includes(\"Cannot find module\") ||\n msg.includes(\"Cannot find package\") ||\n msg.includes(\"ENOENT\") ||\n msg.includes(\"Module not found\")\n ) {\n // File doesn't exist — try next candidate.\n continue;\n }\n // Actual error in the middleware file — rethrow (§6).\n throw new Error(`[elur-kit] Error loading middleware: ${msg}`, { cause: err });\n }\n }\n\n return null;\n}\n\n/**\n * Checks if a pathname matches any of the middleware's matcher patterns.\n * If no matcher is configured, the middleware runs for every request.\n *\n * Catch-all patterns (`:param*`) match both the base path and any sub-paths,\n * e.g. `/dashboard/:path*` matches `/dashboard` and `/dashboard/settings/users`.\n */\nexport function matchesMiddleware(pathname: string, config: MiddlewareConfig): boolean {\n if (!config.matcher || config.matcher.length === 0) return true;\n\n const cleanPath = pathname.split(\"?\")[0];\n\n for (const pattern of config.matcher) {\n // Exact match.\n if (pattern === cleanPath) return true;\n\n // Check for catch-all: `/foo/:bar*` should also match `/foo`.\n const catchAllMatch = pattern.match(/^(.*)\\/:[\\w]+\\*$/);\n if (catchAllMatch) {\n const base = catchAllMatch[1];\n if (cleanPath === base) return true;\n }\n\n // Use matchRoute for param matching.\n const pseudoRoutes: PageRoute[] = [{\n path: pattern,\n pagePath: \"\",\n params: [],\n layouts: [],\n }];\n if (matchRoute(cleanPath, pseudoRoutes)) return true;\n }\n\n return false;\n}\n\n/**\n * Runs the middleware for a request. Returns the result indicating whether to\n * short-circuit with a response or continue with propagated headers/params/locals.\n *\n * Per §6: cleanup runs in `finally`, response short-circuits the pipeline,\n * headers/params/locals are propagated to downstream handlers.\n */\nexport async function runMiddleware(\n middleware: LoadedMiddleware,\n request: Request,\n params?: Record<string, string | string[]>,\n): Promise<MiddlewareResult> {\n let nextHeaders: Record<string, string> | undefined;\n let nextParams: Record<string, string | string[]> | undefined;\n let nextLocals: Record<string, unknown> | undefined;\n const cleanups: Array<() => void | Promise<void>> = [];\n\n const context: MiddlewareContext = {\n next(options) {\n if (options?.headers) nextHeaders = options.headers;\n if (options?.params) nextParams = options.params;\n if (options?.locals) nextLocals = options.locals;\n },\n params,\n locals: {},\n };\n\n try {\n const result = await middleware.handler(request, context);\n\n if (result instanceof Response) {\n return { kind: \"response\", response: result };\n }\n\n return {\n kind: \"continue\",\n headers: nextHeaders,\n params: nextParams ?? params,\n locals: nextLocals,\n };\n } finally {\n // Run any cleanup functions (§6). Errors in cleanup are logged but\n // do not propagate to the caller.\n for (const cleanup of cleanups) {\n try {\n await cleanup();\n } catch (err) {\n console.error(\"[elur-kit] middleware cleanup error:\", err);\n }\n }\n }\n}\n","import { createRequire } from \"node:module\";\nimport type { Plugin } from \"vite\";\n\n/**\n * How the legacy interpolation transform is handled relative to the installed\n * Elur core and Vite plugin:\n *\n * - `\"auto\"` (default): the kit's legacy transform is only applied when the\n * Vite plugin (`@elurjs/vite-plugin-elur` >= 1.1.0) is NOT installed.\n * The plugin has a more powerful state-machine lexer and takes precedence.\n * - `\"legacy\"`: always apply the kit's transform (for migrations), with a\n * one-time deprecation warning.\n * - `\"off\"`: never apply the kit's transform. Recommended when the Vite\n * plugin is installed.\n */\nexport type InterpolationMode = \"auto\" | \"legacy\" | \"off\";\n\nconst require = createRequire(import.meta.url);\n\nlet _warnedLegacy = false;\n\nfunction warnLegacyOnce(): void {\n if (_warnedLegacy) return;\n _warnedLegacy = true;\n console.warn(\n \"[elur-kit] The legacy interpolation transform is deprecated. \" +\n \"Install @elurjs/vite-plugin-elur >= 1.1.0 for compile-time \" +\n \"partial attribute interpolation. Remove `interpolation: \\\"legacy\\\"` \" +\n \"once migration is complete.\",\n );\n}\n\n/**\n * Detects whether the Vite plugin (`@elurjs/vite-plugin-elur`) is\n * installed and provides compile-time partial attribute interpolation.\n */\nexport function pluginSupportsPartialInterpolation(): boolean {\n try {\n const pkg = require(\"@elurjs/vite-plugin-elur/package.json\") as {\n version?: string;\n };\n // >= 1.1.0 has the interpolation lexer\n const [major, minor] = (pkg.version ?? \"0.0.0\").split(\".\").map(Number);\n return major > 1 || (major === 1 && minor >= 1);\n } catch {\n return false;\n }\n}\n\n/**\n * Detects whether the installed Elur core supports partial attribute\n * interpolation natively (via the public `templateFeatures` capability).\n * Note: as of core v3.4.0, this is always false — the lexer moved to the\n * Vite plugin.\n */\nexport function coreSupportsPartialInterpolation(): boolean {\n try {\n const core = require(\"@elurjs/core\") as {\n templateFeatures?: { partialAttributeInterpolation?: boolean };\n };\n return core?.templateFeatures?.partialAttributeInterpolation === true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolves whether the kit's legacy transform should be applied.\n *\n * In `\"auto\"` mode, the kit's transform runs only when neither the Vite\n * plugin nor the core provides partial interpolation. When the Vite plugin\n * is installed (>= 1.1.0), it takes precedence and the kit's transform is\n * skipped to avoid double-processing.\n */\nexport function shouldUseLegacyInterpolation(mode: InterpolationMode): boolean {\n if (mode === \"off\") return false;\n if (mode === \"legacy\") {\n warnLegacyOnce();\n return true;\n }\n // auto: skip if the Vite plugin handles it\n if (pluginSupportsPartialInterpolation()) return false;\n // fallback: use legacy if core doesn't support it natively\n return !coreSupportsPartialInterpolation();\n}\n\n/**\n * Transforms Elur `html\\`\\`` templates so that attributes with partial\n * interpolation become a single interpolation expression.\n *\n * Elur requires every dynamic attribute to be a single interpolation covering\n * the whole value. This plugin rewrites patterns such as:\n *\n * html\\`<a href=\"/blog/${slug}\">...</a>\\`\n *\n * into:\n *\n * html\\`<a href=${\"/blog/\" + slug}>...</a>\\`\n *\n * Only files inside the app and islands directories are processed.\n *\n * @deprecated Elur core supports partial attribute interpolation natively.\n * Keep this transform only for migrations against older cores\n * (`interpolation: \"legacy\"`).\n */\nexport interface InterpolationPluginOptions {\n appDir?: string;\n islandsDir?: string;\n}\n\nconst HTML_TAG = \"html\";\nconst TEMPLATE_START = \"`\";\n\n/**\n * Scans a `${...}` interpolation starting at `start` (where content[start] is\n * `$` and content[start + 1] is `{`), honoring nested braces, strings and\n * escape sequences. Returns the index just past the closing `}`.\n */\nfunction scanInterpolation(content: string, start: number): number {\n let depth = 1;\n let i = start + 2;\n while (i < content.length && depth > 0) {\n const c = content[i];\n if (c === \"\\\\\") {\n i += 2;\n continue;\n }\n if (c === '\"' || c === \"'\" || c === \"`\") {\n const q = c;\n i++;\n while (i < content.length) {\n if (content[i] === \"\\\\\") {\n i += 2;\n continue;\n }\n if (content[i] === q) break;\n i++;\n }\n i++;\n continue;\n }\n if (c === \"{\") depth++;\n else if (c === \"}\") depth--;\n i++;\n }\n return i;\n}\n\n/**\n * Scans a quoted attribute value starting at `start` (where content[start] is\n * the quote character). Handles escapes, `${...}` interpolations with nested\n * braces, and nested quotes. Returns the index just past the closing quote,\n * the raw inner text (escapes preserved as in the source) and whether the\n * value contains at least one interpolation.\n */\nfunction scanQuotedValue(\n content: string,\n start: number,\n quote: string,\n): { end: number; inside: string; hasInterp: boolean } {\n let i = start + 1;\n let inside = \"\";\n let hasInterp = false;\n while (i < content.length) {\n const c = content[i];\n if (c === \"\\\\\") {\n inside += c + (content[i + 1] ?? \"\");\n i += 2;\n continue;\n }\n if (c === quote) {\n i++;\n break;\n }\n if (c === \"$\" && content[i + 1] === \"{\") {\n const end = scanInterpolation(content, i);\n inside += content.slice(i, end);\n i = end;\n hasInterp = true;\n continue;\n }\n inside += c;\n i++;\n }\n return { end: i, inside, hasInterp };\n}\n\n/**\n * Converts the inner text of a quoted attribute value (which may contain\n * `${...}` interpolations) into a JS expression. Literal parts are JSON\n * encoded; interpolations keep their raw expression text.\n *\n * Examples:\n * /blog/${slug} -> \"/blog/\" + (slug)\n * ${slug} -> (slug)\n * tag ${cls({a:1})} -> \"tag \" + (cls({a:1}))\n */\nfunction valueToExpression(value: string): string {\n const parts: string[] = [];\n let i = 0;\n let literal = \"\";\n const flush = () => {\n if (literal) {\n parts.push(JSON.stringify(unescapeAttributeLiteral(literal)));\n literal = \"\";\n }\n };\n\n while (i < value.length) {\n if (value[i] === \"\\\\\") {\n literal += value[i] + (value[i + 1] ?? \"\");\n i += 2;\n continue;\n }\n if (value[i] === \"$\" && value[i + 1] === \"{\") {\n flush();\n const end = scanInterpolation(value, i);\n const expr = value.slice(i + 2, end - 1).trim();\n if (expr) parts.push(`(${expr})`);\n i = end;\n continue;\n }\n literal += value[i];\n i++;\n }\n flush();\n\n if (parts.length === 0) return '\"\"';\n if (parts.length === 1) return parts[0] as string;\n return parts.join(\" + \");\n}\n\n/**\n * Unescapes escape sequences that appear inside a JS template literal so the\n * JSON.stringify output matches the runtime string value.\n */\nfunction unescapeAttributeLiteral(literal: string): string {\n const escapes: Record<string, string> = {\n n: \"\\n\",\n t: \"\\t\",\n r: \"\\r\",\n };\n let out = \"\";\n let i = 0;\n while (i < literal.length) {\n const c = literal[i];\n if (c === \"\\\\\" && i + 1 < literal.length) {\n const next = literal[i + 1];\n if (next in escapes) {\n out += escapes[next];\n i += 2;\n continue;\n }\n out += next;\n i += 2;\n continue;\n }\n out += c;\n i++;\n }\n return out;\n}\n\n/**\n * Rewrites quoted attribute values that contain interpolations inside html``\n * templates, leaving everything else untouched.\n */\nfunction transformTemplateContent(content: string): string {\n let out = \"\";\n let i = 0;\n const n = content.length;\n\n while (i < n) {\n const lt = content.indexOf(\"<\", i);\n if (lt === -1) {\n out += content.slice(i);\n break;\n }\n out += content.slice(i, lt);\n i = lt;\n\n // HTML comments: copy verbatim.\n if (content.startsWith(\"<!--\", i)) {\n const end = content.indexOf(\"-->\", i + 4);\n if (end === -1) {\n out += content.slice(i);\n break;\n }\n out += content.slice(i, end + 3);\n i = end + 3;\n continue;\n }\n\n // Closing tags, doctype, CDATA, processing instructions: copy verbatim.\n if (content[i + 1] === \"/\" || content[i + 1] === \"!\" || content[i + 1] === \"?\") {\n const gt = content.indexOf(\">\", i + 1);\n if (gt === -1) {\n out += content.slice(i);\n break;\n }\n out += content.slice(i, gt + 1);\n i = gt + 1;\n continue;\n }\n\n // Opening tag. Copy the tag name, then walk its attributes.\n let j = i + 1;\n while (j < n && /[a-zA-Z0-9-]/.test(content[j])) j++;\n out += content.slice(i, j);\n i = j;\n\n while (i < n) {\n let ws = \"\";\n while (i < n && /\\s/.test(content[i])) {\n ws += content[i];\n i++;\n }\n if (i >= n) {\n out += ws;\n break;\n }\n if (content[i] === \">\") {\n out += ws + \">\";\n i++;\n break;\n }\n if (content[i] === \"/\" && content[i + 1] === \">\") {\n out += ws + \"/>\";\n i += 2;\n break;\n }\n // Interpolation in the tag body (dynamic attrs/spread): copy verbatim.\n if (content[i] === \"$\" && content[i + 1] === \"{\") {\n const end = scanInterpolation(content, i);\n out += ws + content.slice(i, end);\n i = end;\n continue;\n }\n\n // Attribute name.\n let nameStart = i;\n while (i < n && !/[\\s=/>\"'$]/.test(content[i])) i++;\n const name = content.slice(nameStart, i);\n if (!name) {\n out += ws + content[i];\n i++;\n continue;\n }\n\n let eqWs = \"\";\n while (i < n && /\\s/.test(content[i])) {\n eqWs += content[i];\n i++;\n }\n\n if (content[i] !== \"=\") {\n out += ws + name + eqWs;\n continue;\n }\n\n i++; // consume \"=\"\n let valWs = \"\";\n while (i < n && /\\s/.test(content[i])) {\n valWs += content[i];\n i++;\n }\n\n const quote = content[i];\n if (quote === '\"' || quote === \"'\") {\n const { end, inside, hasInterp } = scanQuotedValue(content, i, quote);\n if (hasInterp) {\n // Skip values that are a single full interpolation: Elur handles\n // `attr=\"${expr}\"` natively, so only partial interpolations need the\n // rewrite.\n const first = scanInterpolation(inside, 0);\n const fullValue =\n inside.startsWith(\"${\") &&\n first === inside.length &&\n !inside.slice(2, first - 1).includes(\"${\");\n if (!fullValue) {\n // Elur needs the interpolation to start right after \"=\" (no space),\n // so the whitespace before the original value is dropped.\n out += ws + name + eqWs + \"=\" + \"${\" + valueToExpression(inside) + \"}\";\n i = end;\n continue;\n }\n out += ws + name + eqWs + \"=\" + valWs + content.slice(i, end);\n } else {\n out += ws + name + eqWs + \"=\" + valWs + content.slice(i, end);\n }\n i = end;\n continue;\n }\n\n // Unquoted value: copy up to whitespace, \">\" or \"/>\".\n let v = \"\";\n while (\n i < n &&\n !/\\s/.test(content[i]) &&\n content[i] !== \">\" &&\n !(content[i] === \"/\" && content[i + 1] === \">\")\n ) {\n v += content[i];\n i++;\n }\n out += ws + name + eqWs + \"=\" + valWs + v;\n }\n }\n\n return out;\n}\n\n/**\n * @deprecated Use the native partial attribute interpolation of Elur core\n * (core >= 3.3). Kept for legacy migrations and direct consumers.\n */\nexport function transformPartialInterpolations(source: string): string {\n let result = \"\";\n let i = 0;\n while (i < source.length) {\n // Find the next html` sequence.\n const htmlIndex = source.indexOf(HTML_TAG, i);\n if (htmlIndex === -1) {\n result += source.slice(i);\n break;\n }\n result += source.slice(i, htmlIndex + HTML_TAG.length);\n i = htmlIndex + HTML_TAG.length;\n\n // Skip whitespace before the backtick.\n while (i < source.length && /\\s/.test(source[i])) {\n result += source[i];\n i++;\n }\n if (i >= source.length || source[i] !== TEMPLATE_START) {\n continue;\n }\n result += source[i];\n i++;\n\n // Parse the template literal until the matching backtick.\n let depth = 1;\n let templateContent = \"\";\n while (i < source.length && depth > 0) {\n const char = source[i];\n if (char === \"\\\\\") {\n templateContent += char + source[i + 1];\n i += 2;\n continue;\n }\n if (char === TEMPLATE_START) {\n depth--;\n if (depth === 0) {\n i++;\n break;\n }\n }\n if (char === \"$\") {\n // Look ahead for ${...}\n if (source[i + 1] === \"{\") {\n const end = scanInterpolation(source, i);\n templateContent += source.slice(i, end);\n i = end;\n continue;\n }\n }\n templateContent += char;\n i++;\n }\n\n const transformed = transformTemplateContent(templateContent);\n result += transformed;\n result += TEMPLATE_START;\n }\n return result;\n}\n\nexport function elurJsInterpolationPlugin(options: InterpolationPluginOptions = {}): Plugin {\n const appDir = options.appDir ?? \"src/app\";\n const islandsDir = options.islandsDir ?? \"src/islands\";\n return {\n name: \"elur-kit-interpolation\",\n enforce: \"pre\",\n transform(code, id) {\n if (!id.endsWith(\".ts\") && !id.endsWith(\".js\")) return;\n if (!id.includes(appDir) && !id.includes(islandsDir)) return;\n if (!code.includes(\"html`\")) return;\n const transformed = transformPartialInterpolations(code);\n if (transformed === code) return;\n return { code: transformed, map: null };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IslandModule } from "./scan.js";
|
|
2
|
+
/** Options for generating the client entry module. */
|
|
3
|
+
export interface GenerateEntryOptions {
|
|
4
|
+
/** Islands to register, from `scanIslands`. */
|
|
5
|
+
islands: IslandModule[];
|
|
6
|
+
/** Absolute path of the entry file to write (e.g. ".elur/entry-client.ts"). */
|
|
7
|
+
outFile: string;
|
|
8
|
+
/**
|
|
9
|
+
* Import specifier for the kit's client island helpers.
|
|
10
|
+
* Defaults to the published subpath `@elurjs/kit/island`.
|
|
11
|
+
*/
|
|
12
|
+
hydrateImport?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Import specifier for the kit's client router.
|
|
15
|
+
* Defaults to the published subpath `@elurjs/kit/router`.
|
|
16
|
+
*/
|
|
17
|
+
routerImport?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Builds the source code of the client entry module. */
|
|
20
|
+
export declare function buildEntrySource(islands: IslandModule[], outFile: string, hydrateImport?: string, routerImport?: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Generates and writes the client entry module for the given islands.
|
|
23
|
+
*
|
|
24
|
+
* @param options Generation options.
|
|
25
|
+
* @returns The absolute path of the written entry file.
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateClientEntry(options: GenerateEntryOptions): Promise<string>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IslandModule } from "./scan.js";
|
|
2
|
+
/** Options for generating the client entry module. */
|
|
3
|
+
export interface GenerateEntryOptions {
|
|
4
|
+
/** Islands to register, from `scanIslands`. */
|
|
5
|
+
islands: IslandModule[];
|
|
6
|
+
/** Absolute path of the entry file to write (e.g. ".elur/entry-client.ts"). */
|
|
7
|
+
outFile: string;
|
|
8
|
+
/**
|
|
9
|
+
* Import specifier for the kit's client island helpers.
|
|
10
|
+
* Defaults to the published subpath `@elurjs/kit/island`.
|
|
11
|
+
*/
|
|
12
|
+
hydrateImport?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Import specifier for the kit's client router.
|
|
15
|
+
* Defaults to the published subpath `@elurjs/kit/router`.
|
|
16
|
+
*/
|
|
17
|
+
routerImport?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Builds the source code of the client entry module. */
|
|
20
|
+
export declare function buildEntrySource(islands: IslandModule[], outFile: string, hydrateImport?: string, routerImport?: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Generates and writes the client entry module for the given islands.
|
|
23
|
+
*
|
|
24
|
+
* @param options Generation options.
|
|
25
|
+
* @returns The absolute path of the written entry file.
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateClientEntry(options: GenerateEntryOptions): Promise<string>;
|