@elurjs/kit 2.4.10 → 2.5.1
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 +313 -0
- package/README.md +248 -15
- package/dist/lib/action/index.cjs +1 -1
- package/dist/lib/action/index.js +1 -1
- package/dist/lib/{action-DZHihU3Z.cjs → action-BiE4tEty.cjs} +2 -2
- package/dist/lib/{action-DZHihU3Z.cjs.map → action-BiE4tEty.cjs.map} +1 -1
- package/dist/lib/{action-BB6N5yD-.js → action-CXVk8rWt.js} +3 -3
- package/dist/lib/{action-BB6N5yD-.js.map → action-CXVk8rWt.js.map} +1 -1
- package/dist/lib/adapter-DNsjXvq5.js +160 -0
- package/dist/lib/adapter-DNsjXvq5.js.map +1 -0
- package/dist/lib/adapter-Dz2hzR36.cjs +3 -0
- package/dist/lib/adapter-Dz2hzR36.cjs.map +1 -0
- package/dist/lib/adapters/bun.cjs +2 -2
- package/dist/lib/adapters/bun.cjs.map +1 -1
- package/dist/lib/adapters/bun.js +17 -9
- package/dist/lib/adapters/bun.js.map +1 -1
- package/dist/lib/adapters/index.d.cts +34 -0
- package/dist/lib/adapters/index.d.ts +34 -0
- package/dist/lib/adapters/netlify.cjs +1 -1
- package/dist/lib/adapters/netlify.js +7 -7
- package/dist/lib/adapters/node.cjs +5 -5
- package/dist/lib/adapters/node.cjs.map +1 -1
- package/dist/lib/adapters/node.js +20 -12
- package/dist/lib/adapters/node.js.map +1 -1
- package/dist/lib/adapters/vercel.cjs +1 -1
- package/dist/lib/adapters/vercel.js +8 -8
- package/dist/lib/build/build.d.cts +40 -0
- package/dist/lib/build/build.d.ts +40 -0
- package/dist/lib/build/document-shell.d.cts +47 -1
- package/dist/lib/build/document-shell.d.ts +47 -1
- package/dist/lib/build/vite-build.d.cts +25 -2
- package/dist/lib/build/vite-build.d.ts +25 -2
- package/dist/lib/cache/adapter.d.cts +41 -0
- package/dist/lib/cache/adapter.d.ts +41 -0
- package/dist/lib/cache/index.cjs +2 -0
- package/dist/lib/cache/index.cjs.map +1 -0
- package/dist/lib/cache/index.d.cts +5 -0
- package/dist/lib/cache/index.d.ts +5 -0
- package/dist/lib/cache/index.js +113 -0
- package/dist/lib/cache/index.js.map +1 -0
- package/dist/lib/cache/invalidation.d.cts +36 -0
- package/dist/lib/cache/invalidation.d.ts +36 -0
- package/dist/lib/cache/redis-adapter.d.cts +49 -0
- package/dist/lib/cache/redis-adapter.d.ts +49 -0
- package/dist/lib/cache-DGhTYyqh.js +50 -0
- package/dist/lib/cache-DGhTYyqh.js.map +1 -0
- package/dist/lib/cache-X1n4Ossu.cjs +2 -0
- package/dist/lib/cache-X1n4Ossu.cjs.map +1 -0
- package/dist/lib/cli/output.d.cts +58 -0
- package/dist/lib/cli/output.d.ts +58 -0
- package/dist/lib/cli/ports.d.cts +20 -0
- package/dist/lib/cli/ports.d.ts +20 -0
- package/dist/lib/cli.cjs +2559 -1488
- package/dist/lib/cli.cjs.map +1 -1
- package/dist/lib/cli.d.cts +21 -0
- package/dist/lib/cli.d.ts +21 -0
- package/dist/lib/cli.js +2558 -1488
- package/dist/lib/cli.js.map +1 -1
- package/dist/lib/config/index.cjs +1 -1
- package/dist/lib/config/index.cjs.map +1 -1
- package/dist/lib/config/index.d.cts +79 -0
- package/dist/lib/config/index.d.ts +79 -0
- package/dist/lib/config/index.js +21 -14
- package/dist/lib/config/index.js.map +1 -1
- package/dist/lib/{errors-ePYxDlhU.js → errors-j4cg9VN3.js} +24 -30
- package/dist/lib/{errors-ePYxDlhU.js.map → errors-j4cg9VN3.js.map} +1 -1
- package/dist/lib/errors-kSl9yLkg.cjs +2 -0
- package/dist/lib/{errors-0X7pCFNU.cjs.map → errors-kSl9yLkg.cjs.map} +1 -1
- package/dist/lib/hydrate-BSLuI0Nh.cjs +2 -0
- package/dist/lib/hydrate-BSLuI0Nh.cjs.map +1 -0
- package/dist/lib/hydrate-BaS7-d8C.js +133 -0
- package/dist/lib/hydrate-BaS7-d8C.js.map +1 -0
- package/dist/lib/idiomorph.esm-BOOTOg1r.cjs +2 -0
- package/dist/lib/idiomorph.esm-BOOTOg1r.cjs.map +1 -0
- package/dist/lib/idiomorph.esm-CXuY-EHB.js +371 -0
- package/dist/lib/idiomorph.esm-CXuY-EHB.js.map +1 -0
- package/dist/lib/index.cjs +1 -1
- package/dist/lib/index.cjs.map +1 -1
- package/dist/lib/index.d.cts +8 -6
- package/dist/lib/index.d.ts +8 -6
- package/dist/lib/index.js +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/interpolation-plugin-C0dTd69H.cjs +58 -0
- package/dist/lib/interpolation-plugin-C0dTd69H.cjs.map +1 -0
- package/dist/lib/{interpolation-plugin-Wgb1j4pT.js → interpolation-plugin-K2qE69tF.js} +95 -126
- package/dist/lib/interpolation-plugin-K2qE69tF.js.map +1 -0
- package/dist/lib/invalidation-CFpNQUv6.cjs +2 -0
- package/dist/lib/invalidation-CFpNQUv6.cjs.map +1 -0
- package/dist/lib/invalidation-DXhdE9wj.js +64 -0
- package/dist/lib/invalidation-DXhdE9wj.js.map +1 -0
- package/dist/lib/island/generate-entry.d.cts +40 -2
- package/dist/lib/island/generate-entry.d.ts +40 -2
- package/dist/lib/island/hydrate.d.cts +19 -6
- package/dist/lib/island/hydrate.d.ts +19 -6
- package/dist/lib/island/index.cjs +1 -1
- package/dist/lib/island/index.d.cts +2 -1
- package/dist/lib/island/index.d.ts +2 -1
- package/dist/lib/island/index.js +1 -1
- package/dist/lib/island/island.d.cts +15 -0
- package/dist/lib/island/island.d.ts +15 -0
- package/dist/lib/island-CTBnsOhI.js +59 -0
- package/dist/lib/island-CTBnsOhI.js.map +1 -0
- package/dist/lib/island-kfQEKRe_.cjs +2 -0
- package/dist/lib/island-kfQEKRe_.cjs.map +1 -0
- package/dist/lib/node-http-DVFcYeBS.js +723 -0
- package/dist/lib/node-http-DVFcYeBS.js.map +1 -0
- package/dist/lib/node-http-Uct7DhmN.cjs +13 -0
- package/dist/lib/node-http-Uct7DhmN.cjs.map +1 -0
- package/dist/lib/rolldown-runtime-BIInC43l.cjs +1 -0
- package/dist/lib/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/dist/lib/router/client.cjs +1 -1
- package/dist/lib/router/client.cjs.map +1 -1
- package/dist/lib/router/client.d.cts +55 -8
- package/dist/lib/router/client.d.ts +55 -8
- package/dist/lib/router/client.js +298 -97
- package/dist/lib/router/client.js.map +1 -1
- package/dist/lib/router/redirects.d.cts +34 -0
- package/dist/lib/router/redirects.d.ts +34 -0
- package/dist/lib/runtime/handler.d.cts +59 -0
- package/dist/lib/runtime/handler.d.ts +59 -0
- package/dist/lib/runtime/index.cjs +1 -1
- package/dist/lib/runtime/index.d.cts +2 -1
- package/dist/lib/runtime/index.d.ts +2 -1
- package/dist/lib/runtime/index.js +4 -4
- package/dist/lib/runtime/logger.d.cts +47 -0
- package/dist/lib/runtime/logger.d.ts +47 -0
- package/dist/lib/runtime/node-http.d.cts +11 -1
- package/dist/lib/runtime/node-http.d.ts +11 -1
- package/dist/lib/runtime-ChE4flX3.cjs +2 -0
- package/dist/lib/runtime-ChE4flX3.cjs.map +1 -0
- package/dist/lib/runtime-OMyz5yE-.js +905 -0
- package/dist/lib/runtime-OMyz5yE-.js.map +1 -0
- package/dist/lib/seo/index.cjs +1 -10
- package/dist/lib/seo/index.d.cts +1 -0
- package/dist/lib/seo/index.d.ts +1 -0
- package/dist/lib/seo/index.js +2 -41
- package/dist/lib/seo/sitemap-from-routes.d.cts +24 -0
- package/dist/lib/seo/sitemap-from-routes.d.ts +24 -0
- package/dist/lib/{shared-CfqOLsKj.cjs → shared-CP0Dc3cp.cjs} +72 -47
- package/dist/lib/shared-CP0Dc3cp.cjs.map +1 -0
- package/dist/lib/{shared-DU3iQgr7.js → shared-D8w-neq2.js} +87 -58
- package/dist/lib/shared-D8w-neq2.js.map +1 -0
- package/dist/lib/sitemap-from-routes-CaBoiGvE.js +77 -0
- package/dist/lib/sitemap-from-routes-CaBoiGvE.js.map +1 -0
- package/dist/lib/sitemap-from-routes-DbcLLL4G.cjs +13 -0
- package/dist/lib/sitemap-from-routes-DbcLLL4G.cjs.map +1 -0
- package/dist/lib/ssr/render.d.cts +8 -2
- package/dist/lib/ssr/render.d.ts +8 -2
- package/dist/lib/ssr/server.d.cts +7 -0
- package/dist/lib/ssr/server.d.ts +7 -0
- package/dist/lib/ssr/stream-response.d.cts +30 -0
- package/dist/lib/ssr/stream-response.d.ts +30 -0
- package/dist/lib/ssr/stream.d.cts +16 -1
- package/dist/lib/ssr/stream.d.ts +16 -1
- package/dist/lib/{stream-DmZjYqHm.cjs → stream-Cg-xYG82.cjs} +3 -3
- package/dist/lib/stream-Cg-xYG82.cjs.map +1 -0
- package/dist/lib/stream-D-ytogdu.js +106 -0
- package/dist/lib/stream-D-ytogdu.js.map +1 -0
- package/dist/lib/vite/index.cjs +1 -1
- package/dist/lib/vite/index.cjs.map +1 -1
- package/dist/lib/vite/index.d.cts +11 -0
- package/dist/lib/vite/index.d.ts +11 -0
- package/dist/lib/vite/index.js +101 -94
- package/dist/lib/vite/index.js.map +1 -1
- package/package.json +25 -8
- package/dist/lib/errors-0X7pCFNU.cjs +0 -2
- package/dist/lib/hydrate-CJbUWdXu.js +0 -126
- package/dist/lib/hydrate-CJbUWdXu.js.map +0 -1
- package/dist/lib/hydrate-D6MR24mz.cjs +0 -2
- package/dist/lib/hydrate-D6MR24mz.cjs.map +0 -1
- package/dist/lib/interpolation-plugin-TWDch8nn.cjs +0 -39
- package/dist/lib/interpolation-plugin-TWDch8nn.cjs.map +0 -1
- package/dist/lib/interpolation-plugin-Wgb1j4pT.js.map +0 -1
- package/dist/lib/node-http-DRAUhO0c.js +0 -617
- package/dist/lib/node-http-DRAUhO0c.js.map +0 -1
- package/dist/lib/node-http-DhxguYyz.cjs +0 -13
- package/dist/lib/node-http-DhxguYyz.cjs.map +0 -1
- package/dist/lib/runtime-CrH5X-Es.cjs +0 -2
- package/dist/lib/runtime-CrH5X-Es.cjs.map +0 -1
- package/dist/lib/runtime-Ds2-wH6P.js +0 -520
- package/dist/lib/runtime-Ds2-wH6P.js.map +0 -1
- package/dist/lib/seo/index.cjs.map +0 -1
- package/dist/lib/seo/index.js.map +0 -1
- package/dist/lib/shared-CfqOLsKj.cjs.map +0 -1
- package/dist/lib/shared-DU3iQgr7.js.map +0 -1
- package/dist/lib/stream-CpOG052V.js +0 -104
- package/dist/lib/stream-CpOG052V.js.map +0 -1
- package/dist/lib/stream-DmZjYqHm.cjs.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../integrations-DDqfWjvH.cjs");let t=require("node:fs/promises"),n=require("node:path"),r=require("vite");function i(e){return e}async function a(t={}){let i=(0,n.resolve)(t.root??process.cwd()),a=t.configFile?(0,n.resolve)(i,t.configFile):await
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../integrations-DDqfWjvH.cjs");let t=require("node:fs/promises"),n=require("node:path"),r=require("vite");function i(e){return e}async function a(t={}){let i=(0,n.resolve)(t.root??process.cwd()),a=t.configFile?(0,n.resolve)(i,t.configFile):await d(i),c={};if(a){let e=await(0,r.loadConfigFromFile)({command:t.command===`build`?`build`:`serve`,mode:t.mode??`development`},a,i);if(!e)throw Error(`[elur-kit] Could not load config: ${a}`);c=e.config}let l=s(c,t.overrides??{}),u=(0,n.resolve)(i,l.root??`.`),f=o(u,l,a);return await e.t(f.integrations,`config`,[f,{root:u,command:t.command??`dev`}]),f}function o(e,t,n){t.site&&new URL(t.site);let r=l(t.base??`/`),i=t.images?.quality??80;if(!Number.isFinite(i)||i<1||i>100)throw Error(`[elur-kit] images.quality must be between 1 and 100`);return{root:e,appDir:c(e,t.appDir??`src/app`,`appDir`),islandsDir:c(e,t.islandsDir??`src/islands`,`islandsDir`),contentDir:c(e,t.contentDir??`src/content`,`contentDir`),publicDir:c(e,t.publicDir??`public`,`publicDir`),outDir:c(e,t.outDir??`dist`,`outDir`),site:t.site,base:r,trailingSlash:t.trailingSlash??`ignore`,output:t.output??`static`,adapter:t.adapter,images:{formats:t.images?.formats??[`webp`,`avif`],quality:i,strict:t.images?.strict??!1},cache:{dir:c(e,t.cache?.dir??`.elur/cache`,`cache.dir`),defaultRevalidate:t.cache?.defaultRevalidate,adapter:t.cache?.adapter},security:{allowedOrigins:t.security?.allowedOrigins??[],strictOrigin:t.security?.strictOrigin??!1,bodyLimit:t.security?.bodyLimit??1048576,headers:t.security?.headers===!1?!1:t.security?.headers??{}},router:{enabled:t.router?.enabled??!0,prefetch:t.router?.prefetch??!0,morph:t.router?.morph??!1,speculation:t.router?.speculation,loadingIndicator:t.router?.loadingIndicator??!1},js:t.js??`modern`,logger:{level:t.logger?.level},redirects:t.redirects??[],rewrites:t.rewrites??[],streaming:t.streaming??!1,headers:t.headers??[],integrations:t.integrations??[],configFile:n}}function s(e,t){return{...e,...t,images:{...e.images,...t.images},cache:{...e.cache,...t.cache},security:{...e.security,...t.security},router:{...e.router,...t.router},logger:{...e.logger,...t.logger},redirects:[...t.redirects??[],...e.redirects??[]],rewrites:[...t.rewrites??[],...e.rewrites??[]],headers:[...t.headers??[],...e.headers??[]],integrations:t.integrations??e.integrations}}function c(e,t,r){let i=(0,n.isAbsolute)(t)?(0,n.resolve)(t):(0,n.resolve)(e,t),a=(0,n.relative)(e,i);if(a===`..`||a.startsWith(`..${n.sep}`)||(0,n.isAbsolute)(a))throw Error(`[elur-kit] ${r} must stay inside root: ${i}`);return i}function l(e){if(!e.startsWith(`/`))throw Error(`[elur-kit] base must start with /`);return e===`/`?e:`${e.replace(/\/+$/,``)}/`}var u=[`elur.config.ts`,`elur.config.js`,`elur.config.mjs`];async function d(e){for(let r of u){let i=(0,n.resolve)(e,r);try{return await(0,t.access)(i),i}catch{}}}exports.defineConfig=i,exports.loadElurConfig=a;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/config/index.ts"],"sourcesContent":["import { access } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { loadConfigFromFile } from \"vite\";\nimport type { Adapter } from \"../adapters/index.js\";\nimport type { ImageFormat } from \"../image/index.js\";\nimport type { ElurKitIntegration } from \"../integrations/index.js\";\nimport { runIntegrationHook } from \"../integrations/index.js\";\n\nexport type ElurOutputMode = \"static\" | \"server\" | \"hybrid\";\nexport type TrailingSlashMode = \"always\" | \"never\" | \"ignore\";\n\nexport interface ElurConfig {\n root?: string;\n appDir?: string;\n islandsDir?: string;\n contentDir?: string;\n publicDir?: string;\n outDir?: string;\n site?: string;\n base?: string;\n trailingSlash?: TrailingSlashMode;\n output?: ElurOutputMode;\n adapter?: Adapter;\n images?: {\n formats?: ImageFormat[];\n quality?: number;\n strict?: boolean;\n };\n cache?: {\n dir?: string;\n defaultRevalidate?: number;\n };\n security?: {\n allowedOrigins?: string[];\n strictOrigin?: boolean;\n bodyLimit?: number;\n /** Security response headers. Set to `false` to disable defaults. */\n headers?: SecurityHeadersConfig | false;\n };\n router?: {\n enabled?: boolean;\n prefetch?: boolean;\n };\n integrations?: ElurKitIntegration[];\n}\n\n/** Security headers configuration (runtime-security §14). */\nexport interface SecurityHeadersConfig {\n /** X-Content-Type-Options: nosniff. Default: true. */\n noSniff?: boolean;\n /** Referrer-Policy. Default: \"strict-origin-when-cross-origin\". */\n referrerPolicy?: string;\n /**\n * Content-Security-Policy. Set to a string to enable.\n * Use \"nonce\" placeholder to inject per-request nonces.\n */\n contentSecurityPolicy?: string;\n /** Strict-Transport-Security. Only applied under HTTPS. Default: unset. */\n hsts?: string | true;\n /** X-Frame-Options or CSP frame-ancestors. Default: \"SAMEORIGIN\". */\n frameAncestors?: string;\n /** Permissions-Policy. Default: unset. */\n permissionsPolicy?: string;\n}\n\nexport interface ResolvedElurConfig {\n root: string;\n appDir: string;\n islandsDir: string;\n contentDir: string;\n publicDir: string;\n outDir: string;\n site?: string;\n base: string;\n trailingSlash: TrailingSlashMode;\n output: ElurOutputMode;\n adapter?: Adapter;\n images: {\n formats: ImageFormat[];\n quality: number;\n strict: boolean;\n };\n cache: {\n dir: string;\n defaultRevalidate?: number;\n };\n security: {\n allowedOrigins: string[];\n strictOrigin: boolean;\n bodyLimit: number;\n headers: SecurityHeadersConfig | false;\n };\n router: {\n enabled: boolean;\n prefetch: boolean;\n };\n integrations: ElurKitIntegration[];\n configFile?: string;\n}\n\nexport interface LoadElurConfigOptions {\n root?: string;\n configFile?: string;\n command?: \"dev\" | \"build\" | \"preview\" | \"start\" | \"check\" | \"routes\" | \"doctor\";\n mode?: string;\n overrides?: ElurConfig;\n}\n\nexport function defineConfig(config: ElurConfig): ElurConfig {\n return config;\n}\n\nexport async function loadElurConfig(options: LoadElurConfigOptions = {}): Promise<ResolvedElurConfig> {\n const initialRoot = resolve(options.root ?? process.cwd());\n const configFile = options.configFile\n ? resolve(initialRoot, options.configFile)\n : await findConfigFile(initialRoot);\n let loaded: ElurConfig = {};\n\n if (configFile) {\n const result = await loadConfigFromFile(\n { command: options.command === \"build\" ? \"build\" : \"serve\", mode: options.mode ?? \"development\" },\n configFile,\n initialRoot,\n );\n if (!result) throw new Error(`[elur-kit] Could not load config: ${configFile}`);\n loaded = result.config as ElurConfig;\n }\n\n const merged = mergeConfig(loaded, options.overrides ?? {});\n const root = resolve(initialRoot, merged.root ?? \".\");\n const resolved = resolveConfig(root, merged, configFile);\n await runIntegrationHook(resolved.integrations, \"config\", [\n resolved as unknown as Record<string, unknown>,\n { root, command: options.command ?? \"dev\" },\n ]);\n return resolved;\n}\n\nfunction resolveConfig(root: string, config: ElurConfig, configFile?: string): ResolvedElurConfig {\n if (config.site) new URL(config.site);\n const base = normalizeBase(config.base ?? \"/\");\n const imageQuality = config.images?.quality ?? 80;\n if (!Number.isFinite(imageQuality) || imageQuality < 1 || imageQuality > 100) {\n throw new Error(\"[elur-kit] images.quality must be between 1 and 100\");\n }\n\n return {\n root,\n appDir: resolveInside(root, config.appDir ?? \"src/app\", \"appDir\"),\n islandsDir: resolveInside(root, config.islandsDir ?? \"src/islands\", \"islandsDir\"),\n contentDir: resolveInside(root, config.contentDir ?? \"src/content\", \"contentDir\"),\n publicDir: resolveInside(root, config.publicDir ?? \"public\", \"publicDir\"),\n outDir: resolveInside(root, config.outDir ?? \"dist\", \"outDir\"),\n site: config.site,\n base,\n trailingSlash: config.trailingSlash ?? \"ignore\",\n output: config.output ?? \"static\",\n adapter: config.adapter,\n images: {\n formats: config.images?.formats ?? [\"webp\", \"avif\"],\n quality: imageQuality,\n strict: config.images?.strict ?? false,\n },\n cache: {\n dir: resolveInside(root, config.cache?.dir ?? \".elur/cache\", \"cache.dir\"),\n defaultRevalidate: config.cache?.defaultRevalidate,\n },\n security: {\n allowedOrigins: config.security?.allowedOrigins ?? [],\n strictOrigin: config.security?.strictOrigin ?? false,\n bodyLimit: config.security?.bodyLimit ?? 1_048_576,\n headers: config.security?.headers === false\n ? false\n : config.security?.headers ?? {},\n },\n router: {\n enabled: config.router?.enabled ?? true,\n prefetch: config.router?.prefetch ?? true,\n },\n integrations: config.integrations ?? [],\n configFile,\n };\n}\n\nfunction mergeConfig(base: ElurConfig, override: ElurConfig): ElurConfig {\n return {\n ...base,\n ...override,\n images: { ...base.images, ...override.images },\n cache: { ...base.cache, ...override.cache },\n security: { ...base.security, ...override.security },\n router: { ...base.router, ...override.router },\n integrations: override.integrations ?? base.integrations,\n };\n}\n\nfunction resolveInside(root: string, path: string, name: string): string {\n const resolved = isAbsolute(path) ? resolve(path) : resolve(root, path);\n const rel = relative(root, resolved);\n if (rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {\n throw new Error(`[elur-kit] ${name} must stay inside root: ${resolved}`);\n }\n return resolved;\n}\n\nfunction normalizeBase(base: string): string {\n if (!base.startsWith(\"/\")) throw new Error(\"[elur-kit] base must start with /\");\n return base === \"/\" ? base : `${base.replace(/\\/+$/, \"\")}/`;\n}\n\nconst PREFERRED_CONFIG_FILES = [\"elur.config.ts\", \"elur.config.js\", \"elur.config.mjs\"];\n// Legacy names kept for backward compatibility. Emit a deprecation warning\n// when a project still uses them so authors migrate to `elur.config.*`.\nconst LEGACY_CONFIG_FILES = [\"elur.config.ts\", \"elur.config.js\", \"elur.config.mjs\"];\n\nasync function findConfigFile(root: string): Promise<string | undefined> {\n for (const name of PREFERRED_CONFIG_FILES) {\n const path = resolve(root, name);\n try {\n await access(path);\n return path;\n } catch {\n }\n }\n for (const name of LEGACY_CONFIG_FILES) {\n const path = resolve(root, name);\n try {\n await access(path);\n console.warn(\n `[elur-kit] \"${name}\" is deprecated and will be removed in a future release. ` +\n `Rename it to \"elur.config.${name.split(\".\").slice(1).join(\".\")}\" to keep your config working.`,\n );\n return path;\n } catch {\n }\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/config/index.ts"],"sourcesContent":["import { access } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { loadConfigFromFile } from \"vite\";\nimport type { Adapter } from \"../adapters/index.js\";\nimport type { ImageFormat } from \"../image/index.js\";\nimport type { ElurKitIntegration } from \"../integrations/index.js\";\nimport { runIntegrationHook } from \"../integrations/index.js\";\nimport type { LogLevel } from \"../runtime/logger.js\";\nimport type { CacheAdapter } from \"../cache/adapter.js\";\nimport type { RedirectRule, RewriteRule, RouteHeadersRule } from \"../router/redirects.js\";\n\nexport type ElurOutputMode = \"static\" | \"server\" | \"hybrid\";\nexport type TrailingSlashMode = \"always\" | \"never\" | \"ignore\";\n\nexport interface ElurConfig {\n root?: string;\n appDir?: string;\n islandsDir?: string;\n contentDir?: string;\n publicDir?: string;\n outDir?: string;\n site?: string;\n base?: string;\n trailingSlash?: TrailingSlashMode;\n output?: ElurOutputMode;\n adapter?: Adapter;\n images?: {\n formats?: ImageFormat[];\n quality?: number;\n strict?: boolean;\n };\n cache?: {\n dir?: string;\n defaultRevalidate?: number;\n /**\n * Pluggable ISR cache adapter (programmatic only — not serializable).\n * Default: filesystem adapter rooted at `cache.dir`.\n */\n adapter?: CacheAdapter;\n };\n security?: {\n allowedOrigins?: string[];\n strictOrigin?: boolean;\n bodyLimit?: number;\n /** Security response headers. Set to `false` to disable defaults. */\n headers?: SecurityHeadersConfig | false;\n };\n /**\n * Client-side router options.\n */\n router?: {\n /**\n * Enable the SPA router on the client (default: `true`). When `false`,\n * no router code is generated and pages without islands ship 0 KB of\n * client JavaScript.\n */\n enabled?: boolean;\n /**\n * Enable link prefetching on hover/focus/pointerdown (default: `true`).\n * Prefetch already opts out on Save-Data and 2g-class connections.\n */\n prefetch?: boolean;\n /**\n * Swap `#app` via idiomorph DOM morphing instead of replacing children\n * (default: `false`, experimental). Hydrated islands and\n * `data-elur-persist` nodes are treated as opaque.\n */\n morph?: boolean;\n /**\n * Emit a `<script type=\"speculationrules\">` block on statically built\n * pages (default: off). Chromium-only progressive enhancement; other\n * browsers ignore it.\n */\n speculation?: \"prefetch\" | \"prerender\";\n /**\n * Show a minimal top progress bar on SPA navigations slower than\n * ~200 ms (default: `false`).\n */\n loadingIndicator?: boolean;\n };\n /**\n * Client JavaScript emission mode (default: `\"modern\"`).\n *\n * - `\"modern\"`: per-page gating — pages without islands emit only the\n * router chunk (or nothing when `router.enabled: false`), and split\n * client builds emit `entry-client.js` + `router.js` separately.\n * - `\"legacy\"`: escape hatch restoring the pre-0%-JS behavior — the\n * combined client entry (hydration + router) is emitted unconditionally\n * on every page.\n */\n js?: \"modern\" | \"legacy\";\n logger?: {\n /** Minimum log level. Default: \"info\" in production, \"debug\" otherwise. */\n level?: LogLevel;\n };\n /** Redirect rules (first match wins; default status 308). */\n redirects?: RedirectRule[];\n /**\n * Opt-in streaming SSR (experimental). When `true`, dynamic routes with a\n * `loading` boundary stream the document shell immediately and swap in the\n * resolved content as a follow-up chunk. Streamed pages bypass the ISR\n * cache. Default: `false` (fully buffered rendering).\n */\n streaming?: boolean;\n /** Rewrite rules: transparently change the pathname before routing. */\n rewrites?: RewriteRule[];\n /** Extra response headers applied to matching request paths. */\n headers?: RouteHeadersRule[];\n integrations?: ElurKitIntegration[];\n}\n\n/** Security headers configuration (runtime-security §14). */\nexport interface SecurityHeadersConfig {\n /** X-Content-Type-Options: nosniff. Default: true. */\n noSniff?: boolean;\n /** Referrer-Policy. Default: \"strict-origin-when-cross-origin\". */\n referrerPolicy?: string;\n /**\n * Content-Security-Policy. Set to a string to enable.\n * Use \"nonce\" placeholder to inject per-request nonces.\n */\n contentSecurityPolicy?: string;\n /** Strict-Transport-Security. Only applied under HTTPS. Default: unset. */\n hsts?: string | true;\n /** X-Frame-Options or CSP frame-ancestors. Default: \"SAMEORIGIN\". */\n frameAncestors?: string;\n /** Permissions-Policy. Default: unset. */\n permissionsPolicy?: string;\n}\n\nexport interface ResolvedElurConfig {\n root: string;\n appDir: string;\n islandsDir: string;\n contentDir: string;\n publicDir: string;\n outDir: string;\n site?: string;\n base: string;\n trailingSlash: TrailingSlashMode;\n output: ElurOutputMode;\n adapter?: Adapter;\n images: {\n formats: ImageFormat[];\n quality: number;\n strict: boolean;\n };\n cache: {\n dir: string;\n defaultRevalidate?: number;\n adapter?: CacheAdapter;\n };\n security: {\n allowedOrigins: string[];\n strictOrigin: boolean;\n bodyLimit: number;\n headers: SecurityHeadersConfig | false;\n };\n router: {\n enabled: boolean;\n prefetch: boolean;\n morph: boolean;\n speculation?: \"prefetch\" | \"prerender\";\n loadingIndicator: boolean;\n };\n /** Client JS emission mode: \"modern\" (0% JS gating) or \"legacy\". */\n js: \"modern\" | \"legacy\";\n logger: {\n level?: LogLevel;\n };\n redirects: RedirectRule[];\n rewrites: RewriteRule[];\n /** Opt-in streaming SSR (experimental). Default: `false`. */\n streaming: boolean;\n headers: RouteHeadersRule[];\n integrations: ElurKitIntegration[];\n configFile?: string;\n}\n\nexport interface LoadElurConfigOptions {\n root?: string;\n configFile?: string;\n command?: \"dev\" | \"build\" | \"preview\" | \"start\" | \"check\" | \"routes\" | \"doctor\";\n mode?: string;\n overrides?: ElurConfig;\n}\n\nexport function defineConfig(config: ElurConfig): ElurConfig {\n return config;\n}\n\nexport async function loadElurConfig(options: LoadElurConfigOptions = {}): Promise<ResolvedElurConfig> {\n const initialRoot = resolve(options.root ?? process.cwd());\n const configFile = options.configFile\n ? resolve(initialRoot, options.configFile)\n : await findConfigFile(initialRoot);\n let loaded: ElurConfig = {};\n\n if (configFile) {\n const result = await loadConfigFromFile(\n { command: options.command === \"build\" ? \"build\" : \"serve\", mode: options.mode ?? \"development\" },\n configFile,\n initialRoot,\n );\n if (!result) throw new Error(`[elur-kit] Could not load config: ${configFile}`);\n loaded = result.config as ElurConfig;\n }\n\n const merged = mergeConfig(loaded, options.overrides ?? {});\n const root = resolve(initialRoot, merged.root ?? \".\");\n const resolved = resolveConfig(root, merged, configFile);\n await runIntegrationHook(resolved.integrations, \"config\", [\n resolved as unknown as Record<string, unknown>,\n { root, command: options.command ?? \"dev\" },\n ]);\n return resolved;\n}\n\nfunction resolveConfig(root: string, config: ElurConfig, configFile?: string): ResolvedElurConfig {\n if (config.site) new URL(config.site);\n const base = normalizeBase(config.base ?? \"/\");\n const imageQuality = config.images?.quality ?? 80;\n if (!Number.isFinite(imageQuality) || imageQuality < 1 || imageQuality > 100) {\n throw new Error(\"[elur-kit] images.quality must be between 1 and 100\");\n }\n\n return {\n root,\n appDir: resolveInside(root, config.appDir ?? \"src/app\", \"appDir\"),\n islandsDir: resolveInside(root, config.islandsDir ?? \"src/islands\", \"islandsDir\"),\n contentDir: resolveInside(root, config.contentDir ?? \"src/content\", \"contentDir\"),\n publicDir: resolveInside(root, config.publicDir ?? \"public\", \"publicDir\"),\n outDir: resolveInside(root, config.outDir ?? \"dist\", \"outDir\"),\n site: config.site,\n base,\n trailingSlash: config.trailingSlash ?? \"ignore\",\n output: config.output ?? \"static\",\n adapter: config.adapter,\n images: {\n formats: config.images?.formats ?? [\"webp\", \"avif\"],\n quality: imageQuality,\n strict: config.images?.strict ?? false,\n },\n cache: {\n dir: resolveInside(root, config.cache?.dir ?? \".elur/cache\", \"cache.dir\"),\n defaultRevalidate: config.cache?.defaultRevalidate,\n adapter: config.cache?.adapter,\n },\n security: {\n allowedOrigins: config.security?.allowedOrigins ?? [],\n strictOrigin: config.security?.strictOrigin ?? false,\n bodyLimit: config.security?.bodyLimit ?? 1_048_576,\n headers: config.security?.headers === false\n ? false\n : config.security?.headers ?? {},\n },\n router: {\n enabled: config.router?.enabled ?? true,\n prefetch: config.router?.prefetch ?? true,\n morph: config.router?.morph ?? false,\n speculation: config.router?.speculation,\n loadingIndicator: config.router?.loadingIndicator ?? false,\n },\n js: config.js ?? \"modern\",\n // No forced level: the StructuredLogger defaults to \"info\" in production\n // and \"debug\" in development when `level` is undefined.\n logger: {\n level: config.logger?.level,\n },\n redirects: config.redirects ?? [],\n rewrites: config.rewrites ?? [],\n streaming: config.streaming ?? false,\n headers: config.headers ?? [],\n integrations: config.integrations ?? [],\n configFile,\n };\n}\n\nfunction mergeConfig(base: ElurConfig, override: ElurConfig): ElurConfig {\n return {\n ...base,\n ...override,\n images: { ...base.images, ...override.images },\n cache: { ...base.cache, ...override.cache },\n security: { ...base.security, ...override.security },\n router: { ...base.router, ...override.router },\n logger: { ...base.logger, ...override.logger },\n // Rule arrays match first-match-wins, so override rules go first: they\n // win over base rules for the same path while base keeps the rest.\n redirects: [...(override.redirects ?? []), ...(base.redirects ?? [])],\n rewrites: [...(override.rewrites ?? []), ...(base.rewrites ?? [])],\n headers: [...(override.headers ?? []), ...(base.headers ?? [])],\n integrations: override.integrations ?? base.integrations,\n };\n}\n\nfunction resolveInside(root: string, path: string, name: string): string {\n const resolved = isAbsolute(path) ? resolve(path) : resolve(root, path);\n const rel = relative(root, resolved);\n if (rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {\n throw new Error(`[elur-kit] ${name} must stay inside root: ${resolved}`);\n }\n return resolved;\n}\n\nfunction normalizeBase(base: string): string {\n if (!base.startsWith(\"/\")) throw new Error(\"[elur-kit] base must start with /\");\n return base === \"/\" ? base : `${base.replace(/\\/+$/, \"\")}/`;\n}\n\nconst PREFERRED_CONFIG_FILES = [\"elur.config.ts\", \"elur.config.js\", \"elur.config.mjs\"];\n\nasync function findConfigFile(root: string): Promise<string | undefined> {\n for (const name of PREFERRED_CONFIG_FILES) {\n const path = resolve(root, name);\n try {\n await access(path);\n return path;\n } catch {\n }\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Adapter } from "../adapters/index.js";
|
|
2
2
|
import type { ImageFormat } from "../image/index.js";
|
|
3
3
|
import type { ElurKitIntegration } from "../integrations/index.js";
|
|
4
|
+
import type { LogLevel } from "../runtime/logger.js";
|
|
5
|
+
import type { CacheAdapter } from "../cache/adapter.js";
|
|
6
|
+
import type { RedirectRule, RewriteRule, RouteHeadersRule } from "../router/redirects.js";
|
|
4
7
|
export type ElurOutputMode = "static" | "server" | "hybrid";
|
|
5
8
|
export type TrailingSlashMode = "always" | "never" | "ignore";
|
|
6
9
|
export interface ElurConfig {
|
|
@@ -23,6 +26,11 @@ export interface ElurConfig {
|
|
|
23
26
|
cache?: {
|
|
24
27
|
dir?: string;
|
|
25
28
|
defaultRevalidate?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Pluggable ISR cache adapter (programmatic only — not serializable).
|
|
31
|
+
* Default: filesystem adapter rooted at `cache.dir`.
|
|
32
|
+
*/
|
|
33
|
+
adapter?: CacheAdapter;
|
|
26
34
|
};
|
|
27
35
|
security?: {
|
|
28
36
|
allowedOrigins?: string[];
|
|
@@ -31,10 +39,67 @@ export interface ElurConfig {
|
|
|
31
39
|
/** Security response headers. Set to `false` to disable defaults. */
|
|
32
40
|
headers?: SecurityHeadersConfig | false;
|
|
33
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Client-side router options.
|
|
44
|
+
*/
|
|
34
45
|
router?: {
|
|
46
|
+
/**
|
|
47
|
+
* Enable the SPA router on the client (default: `true`). When `false`,
|
|
48
|
+
* no router code is generated and pages without islands ship 0 KB of
|
|
49
|
+
* client JavaScript.
|
|
50
|
+
*/
|
|
35
51
|
enabled?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Enable link prefetching on hover/focus/pointerdown (default: `true`).
|
|
54
|
+
* Prefetch already opts out on Save-Data and 2g-class connections.
|
|
55
|
+
*/
|
|
36
56
|
prefetch?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Swap `#app` via idiomorph DOM morphing instead of replacing children
|
|
59
|
+
* (default: `false`, experimental). Hydrated islands and
|
|
60
|
+
* `data-elur-persist` nodes are treated as opaque.
|
|
61
|
+
*/
|
|
62
|
+
morph?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Emit a `<script type="speculationrules">` block on statically built
|
|
65
|
+
* pages (default: off). Chromium-only progressive enhancement; other
|
|
66
|
+
* browsers ignore it.
|
|
67
|
+
*/
|
|
68
|
+
speculation?: "prefetch" | "prerender";
|
|
69
|
+
/**
|
|
70
|
+
* Show a minimal top progress bar on SPA navigations slower than
|
|
71
|
+
* ~200 ms (default: `false`).
|
|
72
|
+
*/
|
|
73
|
+
loadingIndicator?: boolean;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Client JavaScript emission mode (default: `"modern"`).
|
|
77
|
+
*
|
|
78
|
+
* - `"modern"`: per-page gating — pages without islands emit only the
|
|
79
|
+
* router chunk (or nothing when `router.enabled: false`), and split
|
|
80
|
+
* client builds emit `entry-client.js` + `router.js` separately.
|
|
81
|
+
* - `"legacy"`: escape hatch restoring the pre-0%-JS behavior — the
|
|
82
|
+
* combined client entry (hydration + router) is emitted unconditionally
|
|
83
|
+
* on every page.
|
|
84
|
+
*/
|
|
85
|
+
js?: "modern" | "legacy";
|
|
86
|
+
logger?: {
|
|
87
|
+
/** Minimum log level. Default: "info" in production, "debug" otherwise. */
|
|
88
|
+
level?: LogLevel;
|
|
37
89
|
};
|
|
90
|
+
/** Redirect rules (first match wins; default status 308). */
|
|
91
|
+
redirects?: RedirectRule[];
|
|
92
|
+
/**
|
|
93
|
+
* Opt-in streaming SSR (experimental). When `true`, dynamic routes with a
|
|
94
|
+
* `loading` boundary stream the document shell immediately and swap in the
|
|
95
|
+
* resolved content as a follow-up chunk. Streamed pages bypass the ISR
|
|
96
|
+
* cache. Default: `false` (fully buffered rendering).
|
|
97
|
+
*/
|
|
98
|
+
streaming?: boolean;
|
|
99
|
+
/** Rewrite rules: transparently change the pathname before routing. */
|
|
100
|
+
rewrites?: RewriteRule[];
|
|
101
|
+
/** Extra response headers applied to matching request paths. */
|
|
102
|
+
headers?: RouteHeadersRule[];
|
|
38
103
|
integrations?: ElurKitIntegration[];
|
|
39
104
|
}
|
|
40
105
|
/** Security headers configuration (runtime-security §14). */
|
|
@@ -75,6 +140,7 @@ export interface ResolvedElurConfig {
|
|
|
75
140
|
cache: {
|
|
76
141
|
dir: string;
|
|
77
142
|
defaultRevalidate?: number;
|
|
143
|
+
adapter?: CacheAdapter;
|
|
78
144
|
};
|
|
79
145
|
security: {
|
|
80
146
|
allowedOrigins: string[];
|
|
@@ -85,7 +151,20 @@ export interface ResolvedElurConfig {
|
|
|
85
151
|
router: {
|
|
86
152
|
enabled: boolean;
|
|
87
153
|
prefetch: boolean;
|
|
154
|
+
morph: boolean;
|
|
155
|
+
speculation?: "prefetch" | "prerender";
|
|
156
|
+
loadingIndicator: boolean;
|
|
157
|
+
};
|
|
158
|
+
/** Client JS emission mode: "modern" (0% JS gating) or "legacy". */
|
|
159
|
+
js: "modern" | "legacy";
|
|
160
|
+
logger: {
|
|
161
|
+
level?: LogLevel;
|
|
88
162
|
};
|
|
163
|
+
redirects: RedirectRule[];
|
|
164
|
+
rewrites: RewriteRule[];
|
|
165
|
+
/** Opt-in streaming SSR (experimental). Default: `false`. */
|
|
166
|
+
streaming: boolean;
|
|
167
|
+
headers: RouteHeadersRule[];
|
|
89
168
|
integrations: ElurKitIntegration[];
|
|
90
169
|
configFile?: string;
|
|
91
170
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Adapter } from "../adapters/index.js";
|
|
2
2
|
import type { ImageFormat } from "../image/index.js";
|
|
3
3
|
import type { ElurKitIntegration } from "../integrations/index.js";
|
|
4
|
+
import type { LogLevel } from "../runtime/logger.js";
|
|
5
|
+
import type { CacheAdapter } from "../cache/adapter.js";
|
|
6
|
+
import type { RedirectRule, RewriteRule, RouteHeadersRule } from "../router/redirects.js";
|
|
4
7
|
export type ElurOutputMode = "static" | "server" | "hybrid";
|
|
5
8
|
export type TrailingSlashMode = "always" | "never" | "ignore";
|
|
6
9
|
export interface ElurConfig {
|
|
@@ -23,6 +26,11 @@ export interface ElurConfig {
|
|
|
23
26
|
cache?: {
|
|
24
27
|
dir?: string;
|
|
25
28
|
defaultRevalidate?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Pluggable ISR cache adapter (programmatic only — not serializable).
|
|
31
|
+
* Default: filesystem adapter rooted at `cache.dir`.
|
|
32
|
+
*/
|
|
33
|
+
adapter?: CacheAdapter;
|
|
26
34
|
};
|
|
27
35
|
security?: {
|
|
28
36
|
allowedOrigins?: string[];
|
|
@@ -31,10 +39,67 @@ export interface ElurConfig {
|
|
|
31
39
|
/** Security response headers. Set to `false` to disable defaults. */
|
|
32
40
|
headers?: SecurityHeadersConfig | false;
|
|
33
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Client-side router options.
|
|
44
|
+
*/
|
|
34
45
|
router?: {
|
|
46
|
+
/**
|
|
47
|
+
* Enable the SPA router on the client (default: `true`). When `false`,
|
|
48
|
+
* no router code is generated and pages without islands ship 0 KB of
|
|
49
|
+
* client JavaScript.
|
|
50
|
+
*/
|
|
35
51
|
enabled?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Enable link prefetching on hover/focus/pointerdown (default: `true`).
|
|
54
|
+
* Prefetch already opts out on Save-Data and 2g-class connections.
|
|
55
|
+
*/
|
|
36
56
|
prefetch?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Swap `#app` via idiomorph DOM morphing instead of replacing children
|
|
59
|
+
* (default: `false`, experimental). Hydrated islands and
|
|
60
|
+
* `data-elur-persist` nodes are treated as opaque.
|
|
61
|
+
*/
|
|
62
|
+
morph?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Emit a `<script type="speculationrules">` block on statically built
|
|
65
|
+
* pages (default: off). Chromium-only progressive enhancement; other
|
|
66
|
+
* browsers ignore it.
|
|
67
|
+
*/
|
|
68
|
+
speculation?: "prefetch" | "prerender";
|
|
69
|
+
/**
|
|
70
|
+
* Show a minimal top progress bar on SPA navigations slower than
|
|
71
|
+
* ~200 ms (default: `false`).
|
|
72
|
+
*/
|
|
73
|
+
loadingIndicator?: boolean;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Client JavaScript emission mode (default: `"modern"`).
|
|
77
|
+
*
|
|
78
|
+
* - `"modern"`: per-page gating — pages without islands emit only the
|
|
79
|
+
* router chunk (or nothing when `router.enabled: false`), and split
|
|
80
|
+
* client builds emit `entry-client.js` + `router.js` separately.
|
|
81
|
+
* - `"legacy"`: escape hatch restoring the pre-0%-JS behavior — the
|
|
82
|
+
* combined client entry (hydration + router) is emitted unconditionally
|
|
83
|
+
* on every page.
|
|
84
|
+
*/
|
|
85
|
+
js?: "modern" | "legacy";
|
|
86
|
+
logger?: {
|
|
87
|
+
/** Minimum log level. Default: "info" in production, "debug" otherwise. */
|
|
88
|
+
level?: LogLevel;
|
|
37
89
|
};
|
|
90
|
+
/** Redirect rules (first match wins; default status 308). */
|
|
91
|
+
redirects?: RedirectRule[];
|
|
92
|
+
/**
|
|
93
|
+
* Opt-in streaming SSR (experimental). When `true`, dynamic routes with a
|
|
94
|
+
* `loading` boundary stream the document shell immediately and swap in the
|
|
95
|
+
* resolved content as a follow-up chunk. Streamed pages bypass the ISR
|
|
96
|
+
* cache. Default: `false` (fully buffered rendering).
|
|
97
|
+
*/
|
|
98
|
+
streaming?: boolean;
|
|
99
|
+
/** Rewrite rules: transparently change the pathname before routing. */
|
|
100
|
+
rewrites?: RewriteRule[];
|
|
101
|
+
/** Extra response headers applied to matching request paths. */
|
|
102
|
+
headers?: RouteHeadersRule[];
|
|
38
103
|
integrations?: ElurKitIntegration[];
|
|
39
104
|
}
|
|
40
105
|
/** Security headers configuration (runtime-security §14). */
|
|
@@ -75,6 +140,7 @@ export interface ResolvedElurConfig {
|
|
|
75
140
|
cache: {
|
|
76
141
|
dir: string;
|
|
77
142
|
defaultRevalidate?: number;
|
|
143
|
+
adapter?: CacheAdapter;
|
|
78
144
|
};
|
|
79
145
|
security: {
|
|
80
146
|
allowedOrigins: string[];
|
|
@@ -85,7 +151,20 @@ export interface ResolvedElurConfig {
|
|
|
85
151
|
router: {
|
|
86
152
|
enabled: boolean;
|
|
87
153
|
prefetch: boolean;
|
|
154
|
+
morph: boolean;
|
|
155
|
+
speculation?: "prefetch" | "prerender";
|
|
156
|
+
loadingIndicator: boolean;
|
|
157
|
+
};
|
|
158
|
+
/** Client JS emission mode: "modern" (0% JS gating) or "legacy". */
|
|
159
|
+
js: "modern" | "legacy";
|
|
160
|
+
logger: {
|
|
161
|
+
level?: LogLevel;
|
|
88
162
|
};
|
|
163
|
+
redirects: RedirectRule[];
|
|
164
|
+
rewrites: RewriteRule[];
|
|
165
|
+
/** Opt-in streaming SSR (experimental). Default: `false`. */
|
|
166
|
+
streaming: boolean;
|
|
167
|
+
headers: RouteHeadersRule[];
|
|
89
168
|
integrations: ElurKitIntegration[];
|
|
90
169
|
configFile?: string;
|
|
91
170
|
}
|
package/dist/lib/config/index.js
CHANGED
|
@@ -7,7 +7,7 @@ function s(e) {
|
|
|
7
7
|
return e;
|
|
8
8
|
}
|
|
9
9
|
async function c(t = {}) {
|
|
10
|
-
let n = i(t.root ?? process.cwd()), r = t.configFile ? i(n, t.configFile) : await
|
|
10
|
+
let n = i(t.root ?? process.cwd()), r = t.configFile ? i(n, t.configFile) : await m(n), a = {};
|
|
11
11
|
if (r) {
|
|
12
12
|
let e = await o({
|
|
13
13
|
command: t.command === "build" ? "build" : "serve",
|
|
@@ -45,7 +45,8 @@ function l(e, t, n) {
|
|
|
45
45
|
},
|
|
46
46
|
cache: {
|
|
47
47
|
dir: d(e, t.cache?.dir ?? ".elur/cache", "cache.dir"),
|
|
48
|
-
defaultRevalidate: t.cache?.defaultRevalidate
|
|
48
|
+
defaultRevalidate: t.cache?.defaultRevalidate,
|
|
49
|
+
adapter: t.cache?.adapter
|
|
49
50
|
},
|
|
50
51
|
security: {
|
|
51
52
|
allowedOrigins: t.security?.allowedOrigins ?? [],
|
|
@@ -55,8 +56,17 @@ function l(e, t, n) {
|
|
|
55
56
|
},
|
|
56
57
|
router: {
|
|
57
58
|
enabled: t.router?.enabled ?? !0,
|
|
58
|
-
prefetch: t.router?.prefetch ?? !0
|
|
59
|
+
prefetch: t.router?.prefetch ?? !0,
|
|
60
|
+
morph: t.router?.morph ?? !1,
|
|
61
|
+
speculation: t.router?.speculation,
|
|
62
|
+
loadingIndicator: t.router?.loadingIndicator ?? !1
|
|
59
63
|
},
|
|
64
|
+
js: t.js ?? "modern",
|
|
65
|
+
logger: { level: t.logger?.level },
|
|
66
|
+
redirects: t.redirects ?? [],
|
|
67
|
+
rewrites: t.rewrites ?? [],
|
|
68
|
+
streaming: t.streaming ?? !1,
|
|
69
|
+
headers: t.headers ?? [],
|
|
60
70
|
integrations: t.integrations ?? [],
|
|
61
71
|
configFile: n
|
|
62
72
|
};
|
|
@@ -81,6 +91,13 @@ function u(e, t) {
|
|
|
81
91
|
...e.router,
|
|
82
92
|
...t.router
|
|
83
93
|
},
|
|
94
|
+
logger: {
|
|
95
|
+
...e.logger,
|
|
96
|
+
...t.logger
|
|
97
|
+
},
|
|
98
|
+
redirects: [...t.redirects ?? [], ...e.redirects ?? []],
|
|
99
|
+
rewrites: [...t.rewrites ?? [], ...e.rewrites ?? []],
|
|
100
|
+
headers: [...t.headers ?? [], ...e.headers ?? []],
|
|
84
101
|
integrations: t.integrations ?? e.integrations
|
|
85
102
|
};
|
|
86
103
|
}
|
|
@@ -97,24 +114,14 @@ var p = [
|
|
|
97
114
|
"elur.config.ts",
|
|
98
115
|
"elur.config.js",
|
|
99
116
|
"elur.config.mjs"
|
|
100
|
-
], m = [
|
|
101
|
-
"elur.config.ts",
|
|
102
|
-
"elur.config.js",
|
|
103
|
-
"elur.config.mjs"
|
|
104
117
|
];
|
|
105
|
-
async function
|
|
118
|
+
async function m(e) {
|
|
106
119
|
for (let n of p) {
|
|
107
120
|
let r = i(e, n);
|
|
108
121
|
try {
|
|
109
122
|
return await t(r), r;
|
|
110
123
|
} catch {}
|
|
111
124
|
}
|
|
112
|
-
for (let n of m) {
|
|
113
|
-
let r = i(e, n);
|
|
114
|
-
try {
|
|
115
|
-
return await t(r), console.warn(`[elur-kit] "${n}" is deprecated and will be removed in a future release. Rename it to "elur.config.${n.split(".").slice(1).join(".")}" to keep your config working.`), r;
|
|
116
|
-
} catch {}
|
|
117
|
-
}
|
|
118
125
|
}
|
|
119
126
|
//#endregion
|
|
120
127
|
export { s as defineConfig, c as loadElurConfig };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/config/index.ts"],"sourcesContent":["import { access } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { loadConfigFromFile } from \"vite\";\nimport type { Adapter } from \"../adapters/index.js\";\nimport type { ImageFormat } from \"../image/index.js\";\nimport type { ElurKitIntegration } from \"../integrations/index.js\";\nimport { runIntegrationHook } from \"../integrations/index.js\";\n\nexport type ElurOutputMode = \"static\" | \"server\" | \"hybrid\";\nexport type TrailingSlashMode = \"always\" | \"never\" | \"ignore\";\n\nexport interface ElurConfig {\n root?: string;\n appDir?: string;\n islandsDir?: string;\n contentDir?: string;\n publicDir?: string;\n outDir?: string;\n site?: string;\n base?: string;\n trailingSlash?: TrailingSlashMode;\n output?: ElurOutputMode;\n adapter?: Adapter;\n images?: {\n formats?: ImageFormat[];\n quality?: number;\n strict?: boolean;\n };\n cache?: {\n dir?: string;\n defaultRevalidate?: number;\n };\n security?: {\n allowedOrigins?: string[];\n strictOrigin?: boolean;\n bodyLimit?: number;\n /** Security response headers. Set to `false` to disable defaults. */\n headers?: SecurityHeadersConfig | false;\n };\n router?: {\n enabled?: boolean;\n prefetch?: boolean;\n };\n integrations?: ElurKitIntegration[];\n}\n\n/** Security headers configuration (runtime-security §14). */\nexport interface SecurityHeadersConfig {\n /** X-Content-Type-Options: nosniff. Default: true. */\n noSniff?: boolean;\n /** Referrer-Policy. Default: \"strict-origin-when-cross-origin\". */\n referrerPolicy?: string;\n /**\n * Content-Security-Policy. Set to a string to enable.\n * Use \"nonce\" placeholder to inject per-request nonces.\n */\n contentSecurityPolicy?: string;\n /** Strict-Transport-Security. Only applied under HTTPS. Default: unset. */\n hsts?: string | true;\n /** X-Frame-Options or CSP frame-ancestors. Default: \"SAMEORIGIN\". */\n frameAncestors?: string;\n /** Permissions-Policy. Default: unset. */\n permissionsPolicy?: string;\n}\n\nexport interface ResolvedElurConfig {\n root: string;\n appDir: string;\n islandsDir: string;\n contentDir: string;\n publicDir: string;\n outDir: string;\n site?: string;\n base: string;\n trailingSlash: TrailingSlashMode;\n output: ElurOutputMode;\n adapter?: Adapter;\n images: {\n formats: ImageFormat[];\n quality: number;\n strict: boolean;\n };\n cache: {\n dir: string;\n defaultRevalidate?: number;\n };\n security: {\n allowedOrigins: string[];\n strictOrigin: boolean;\n bodyLimit: number;\n headers: SecurityHeadersConfig | false;\n };\n router: {\n enabled: boolean;\n prefetch: boolean;\n };\n integrations: ElurKitIntegration[];\n configFile?: string;\n}\n\nexport interface LoadElurConfigOptions {\n root?: string;\n configFile?: string;\n command?: \"dev\" | \"build\" | \"preview\" | \"start\" | \"check\" | \"routes\" | \"doctor\";\n mode?: string;\n overrides?: ElurConfig;\n}\n\nexport function defineConfig(config: ElurConfig): ElurConfig {\n return config;\n}\n\nexport async function loadElurConfig(options: LoadElurConfigOptions = {}): Promise<ResolvedElurConfig> {\n const initialRoot = resolve(options.root ?? process.cwd());\n const configFile = options.configFile\n ? resolve(initialRoot, options.configFile)\n : await findConfigFile(initialRoot);\n let loaded: ElurConfig = {};\n\n if (configFile) {\n const result = await loadConfigFromFile(\n { command: options.command === \"build\" ? \"build\" : \"serve\", mode: options.mode ?? \"development\" },\n configFile,\n initialRoot,\n );\n if (!result) throw new Error(`[elur-kit] Could not load config: ${configFile}`);\n loaded = result.config as ElurConfig;\n }\n\n const merged = mergeConfig(loaded, options.overrides ?? {});\n const root = resolve(initialRoot, merged.root ?? \".\");\n const resolved = resolveConfig(root, merged, configFile);\n await runIntegrationHook(resolved.integrations, \"config\", [\n resolved as unknown as Record<string, unknown>,\n { root, command: options.command ?? \"dev\" },\n ]);\n return resolved;\n}\n\nfunction resolveConfig(root: string, config: ElurConfig, configFile?: string): ResolvedElurConfig {\n if (config.site) new URL(config.site);\n const base = normalizeBase(config.base ?? \"/\");\n const imageQuality = config.images?.quality ?? 80;\n if (!Number.isFinite(imageQuality) || imageQuality < 1 || imageQuality > 100) {\n throw new Error(\"[elur-kit] images.quality must be between 1 and 100\");\n }\n\n return {\n root,\n appDir: resolveInside(root, config.appDir ?? \"src/app\", \"appDir\"),\n islandsDir: resolveInside(root, config.islandsDir ?? \"src/islands\", \"islandsDir\"),\n contentDir: resolveInside(root, config.contentDir ?? \"src/content\", \"contentDir\"),\n publicDir: resolveInside(root, config.publicDir ?? \"public\", \"publicDir\"),\n outDir: resolveInside(root, config.outDir ?? \"dist\", \"outDir\"),\n site: config.site,\n base,\n trailingSlash: config.trailingSlash ?? \"ignore\",\n output: config.output ?? \"static\",\n adapter: config.adapter,\n images: {\n formats: config.images?.formats ?? [\"webp\", \"avif\"],\n quality: imageQuality,\n strict: config.images?.strict ?? false,\n },\n cache: {\n dir: resolveInside(root, config.cache?.dir ?? \".elur/cache\", \"cache.dir\"),\n defaultRevalidate: config.cache?.defaultRevalidate,\n },\n security: {\n allowedOrigins: config.security?.allowedOrigins ?? [],\n strictOrigin: config.security?.strictOrigin ?? false,\n bodyLimit: config.security?.bodyLimit ?? 1_048_576,\n headers: config.security?.headers === false\n ? false\n : config.security?.headers ?? {},\n },\n router: {\n enabled: config.router?.enabled ?? true,\n prefetch: config.router?.prefetch ?? true,\n },\n integrations: config.integrations ?? [],\n configFile,\n };\n}\n\nfunction mergeConfig(base: ElurConfig, override: ElurConfig): ElurConfig {\n return {\n ...base,\n ...override,\n images: { ...base.images, ...override.images },\n cache: { ...base.cache, ...override.cache },\n security: { ...base.security, ...override.security },\n router: { ...base.router, ...override.router },\n integrations: override.integrations ?? base.integrations,\n };\n}\n\nfunction resolveInside(root: string, path: string, name: string): string {\n const resolved = isAbsolute(path) ? resolve(path) : resolve(root, path);\n const rel = relative(root, resolved);\n if (rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {\n throw new Error(`[elur-kit] ${name} must stay inside root: ${resolved}`);\n }\n return resolved;\n}\n\nfunction normalizeBase(base: string): string {\n if (!base.startsWith(\"/\")) throw new Error(\"[elur-kit] base must start with /\");\n return base === \"/\" ? base : `${base.replace(/\\/+$/, \"\")}/`;\n}\n\nconst PREFERRED_CONFIG_FILES = [\"elur.config.ts\", \"elur.config.js\", \"elur.config.mjs\"];\n// Legacy names kept for backward compatibility. Emit a deprecation warning\n// when a project still uses them so authors migrate to `elur.config.*`.\nconst LEGACY_CONFIG_FILES = [\"elur.config.ts\", \"elur.config.js\", \"elur.config.mjs\"];\n\nasync function findConfigFile(root: string): Promise<string | undefined> {\n for (const name of PREFERRED_CONFIG_FILES) {\n const path = resolve(root, name);\n try {\n await access(path);\n return path;\n } catch {\n }\n }\n for (const name of LEGACY_CONFIG_FILES) {\n const path = resolve(root, name);\n try {\n await access(path);\n console.warn(\n `[elur-kit] \"${name}\" is deprecated and will be removed in a future release. ` +\n `Rename it to \"elur.config.${name.split(\".\").slice(1).join(\".\")}\" to keep your config working.`,\n );\n return path;\n } catch {\n }\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/config/index.ts"],"sourcesContent":["import { access } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { loadConfigFromFile } from \"vite\";\nimport type { Adapter } from \"../adapters/index.js\";\nimport type { ImageFormat } from \"../image/index.js\";\nimport type { ElurKitIntegration } from \"../integrations/index.js\";\nimport { runIntegrationHook } from \"../integrations/index.js\";\nimport type { LogLevel } from \"../runtime/logger.js\";\nimport type { CacheAdapter } from \"../cache/adapter.js\";\nimport type { RedirectRule, RewriteRule, RouteHeadersRule } from \"../router/redirects.js\";\n\nexport type ElurOutputMode = \"static\" | \"server\" | \"hybrid\";\nexport type TrailingSlashMode = \"always\" | \"never\" | \"ignore\";\n\nexport interface ElurConfig {\n root?: string;\n appDir?: string;\n islandsDir?: string;\n contentDir?: string;\n publicDir?: string;\n outDir?: string;\n site?: string;\n base?: string;\n trailingSlash?: TrailingSlashMode;\n output?: ElurOutputMode;\n adapter?: Adapter;\n images?: {\n formats?: ImageFormat[];\n quality?: number;\n strict?: boolean;\n };\n cache?: {\n dir?: string;\n defaultRevalidate?: number;\n /**\n * Pluggable ISR cache adapter (programmatic only — not serializable).\n * Default: filesystem adapter rooted at `cache.dir`.\n */\n adapter?: CacheAdapter;\n };\n security?: {\n allowedOrigins?: string[];\n strictOrigin?: boolean;\n bodyLimit?: number;\n /** Security response headers. Set to `false` to disable defaults. */\n headers?: SecurityHeadersConfig | false;\n };\n /**\n * Client-side router options.\n */\n router?: {\n /**\n * Enable the SPA router on the client (default: `true`). When `false`,\n * no router code is generated and pages without islands ship 0 KB of\n * client JavaScript.\n */\n enabled?: boolean;\n /**\n * Enable link prefetching on hover/focus/pointerdown (default: `true`).\n * Prefetch already opts out on Save-Data and 2g-class connections.\n */\n prefetch?: boolean;\n /**\n * Swap `#app` via idiomorph DOM morphing instead of replacing children\n * (default: `false`, experimental). Hydrated islands and\n * `data-elur-persist` nodes are treated as opaque.\n */\n morph?: boolean;\n /**\n * Emit a `<script type=\"speculationrules\">` block on statically built\n * pages (default: off). Chromium-only progressive enhancement; other\n * browsers ignore it.\n */\n speculation?: \"prefetch\" | \"prerender\";\n /**\n * Show a minimal top progress bar on SPA navigations slower than\n * ~200 ms (default: `false`).\n */\n loadingIndicator?: boolean;\n };\n /**\n * Client JavaScript emission mode (default: `\"modern\"`).\n *\n * - `\"modern\"`: per-page gating — pages without islands emit only the\n * router chunk (or nothing when `router.enabled: false`), and split\n * client builds emit `entry-client.js` + `router.js` separately.\n * - `\"legacy\"`: escape hatch restoring the pre-0%-JS behavior — the\n * combined client entry (hydration + router) is emitted unconditionally\n * on every page.\n */\n js?: \"modern\" | \"legacy\";\n logger?: {\n /** Minimum log level. Default: \"info\" in production, \"debug\" otherwise. */\n level?: LogLevel;\n };\n /** Redirect rules (first match wins; default status 308). */\n redirects?: RedirectRule[];\n /**\n * Opt-in streaming SSR (experimental). When `true`, dynamic routes with a\n * `loading` boundary stream the document shell immediately and swap in the\n * resolved content as a follow-up chunk. Streamed pages bypass the ISR\n * cache. Default: `false` (fully buffered rendering).\n */\n streaming?: boolean;\n /** Rewrite rules: transparently change the pathname before routing. */\n rewrites?: RewriteRule[];\n /** Extra response headers applied to matching request paths. */\n headers?: RouteHeadersRule[];\n integrations?: ElurKitIntegration[];\n}\n\n/** Security headers configuration (runtime-security §14). */\nexport interface SecurityHeadersConfig {\n /** X-Content-Type-Options: nosniff. Default: true. */\n noSniff?: boolean;\n /** Referrer-Policy. Default: \"strict-origin-when-cross-origin\". */\n referrerPolicy?: string;\n /**\n * Content-Security-Policy. Set to a string to enable.\n * Use \"nonce\" placeholder to inject per-request nonces.\n */\n contentSecurityPolicy?: string;\n /** Strict-Transport-Security. Only applied under HTTPS. Default: unset. */\n hsts?: string | true;\n /** X-Frame-Options or CSP frame-ancestors. Default: \"SAMEORIGIN\". */\n frameAncestors?: string;\n /** Permissions-Policy. Default: unset. */\n permissionsPolicy?: string;\n}\n\nexport interface ResolvedElurConfig {\n root: string;\n appDir: string;\n islandsDir: string;\n contentDir: string;\n publicDir: string;\n outDir: string;\n site?: string;\n base: string;\n trailingSlash: TrailingSlashMode;\n output: ElurOutputMode;\n adapter?: Adapter;\n images: {\n formats: ImageFormat[];\n quality: number;\n strict: boolean;\n };\n cache: {\n dir: string;\n defaultRevalidate?: number;\n adapter?: CacheAdapter;\n };\n security: {\n allowedOrigins: string[];\n strictOrigin: boolean;\n bodyLimit: number;\n headers: SecurityHeadersConfig | false;\n };\n router: {\n enabled: boolean;\n prefetch: boolean;\n morph: boolean;\n speculation?: \"prefetch\" | \"prerender\";\n loadingIndicator: boolean;\n };\n /** Client JS emission mode: \"modern\" (0% JS gating) or \"legacy\". */\n js: \"modern\" | \"legacy\";\n logger: {\n level?: LogLevel;\n };\n redirects: RedirectRule[];\n rewrites: RewriteRule[];\n /** Opt-in streaming SSR (experimental). Default: `false`. */\n streaming: boolean;\n headers: RouteHeadersRule[];\n integrations: ElurKitIntegration[];\n configFile?: string;\n}\n\nexport interface LoadElurConfigOptions {\n root?: string;\n configFile?: string;\n command?: \"dev\" | \"build\" | \"preview\" | \"start\" | \"check\" | \"routes\" | \"doctor\";\n mode?: string;\n overrides?: ElurConfig;\n}\n\nexport function defineConfig(config: ElurConfig): ElurConfig {\n return config;\n}\n\nexport async function loadElurConfig(options: LoadElurConfigOptions = {}): Promise<ResolvedElurConfig> {\n const initialRoot = resolve(options.root ?? process.cwd());\n const configFile = options.configFile\n ? resolve(initialRoot, options.configFile)\n : await findConfigFile(initialRoot);\n let loaded: ElurConfig = {};\n\n if (configFile) {\n const result = await loadConfigFromFile(\n { command: options.command === \"build\" ? \"build\" : \"serve\", mode: options.mode ?? \"development\" },\n configFile,\n initialRoot,\n );\n if (!result) throw new Error(`[elur-kit] Could not load config: ${configFile}`);\n loaded = result.config as ElurConfig;\n }\n\n const merged = mergeConfig(loaded, options.overrides ?? {});\n const root = resolve(initialRoot, merged.root ?? \".\");\n const resolved = resolveConfig(root, merged, configFile);\n await runIntegrationHook(resolved.integrations, \"config\", [\n resolved as unknown as Record<string, unknown>,\n { root, command: options.command ?? \"dev\" },\n ]);\n return resolved;\n}\n\nfunction resolveConfig(root: string, config: ElurConfig, configFile?: string): ResolvedElurConfig {\n if (config.site) new URL(config.site);\n const base = normalizeBase(config.base ?? \"/\");\n const imageQuality = config.images?.quality ?? 80;\n if (!Number.isFinite(imageQuality) || imageQuality < 1 || imageQuality > 100) {\n throw new Error(\"[elur-kit] images.quality must be between 1 and 100\");\n }\n\n return {\n root,\n appDir: resolveInside(root, config.appDir ?? \"src/app\", \"appDir\"),\n islandsDir: resolveInside(root, config.islandsDir ?? \"src/islands\", \"islandsDir\"),\n contentDir: resolveInside(root, config.contentDir ?? \"src/content\", \"contentDir\"),\n publicDir: resolveInside(root, config.publicDir ?? \"public\", \"publicDir\"),\n outDir: resolveInside(root, config.outDir ?? \"dist\", \"outDir\"),\n site: config.site,\n base,\n trailingSlash: config.trailingSlash ?? \"ignore\",\n output: config.output ?? \"static\",\n adapter: config.adapter,\n images: {\n formats: config.images?.formats ?? [\"webp\", \"avif\"],\n quality: imageQuality,\n strict: config.images?.strict ?? false,\n },\n cache: {\n dir: resolveInside(root, config.cache?.dir ?? \".elur/cache\", \"cache.dir\"),\n defaultRevalidate: config.cache?.defaultRevalidate,\n adapter: config.cache?.adapter,\n },\n security: {\n allowedOrigins: config.security?.allowedOrigins ?? [],\n strictOrigin: config.security?.strictOrigin ?? false,\n bodyLimit: config.security?.bodyLimit ?? 1_048_576,\n headers: config.security?.headers === false\n ? false\n : config.security?.headers ?? {},\n },\n router: {\n enabled: config.router?.enabled ?? true,\n prefetch: config.router?.prefetch ?? true,\n morph: config.router?.morph ?? false,\n speculation: config.router?.speculation,\n loadingIndicator: config.router?.loadingIndicator ?? false,\n },\n js: config.js ?? \"modern\",\n // No forced level: the StructuredLogger defaults to \"info\" in production\n // and \"debug\" in development when `level` is undefined.\n logger: {\n level: config.logger?.level,\n },\n redirects: config.redirects ?? [],\n rewrites: config.rewrites ?? [],\n streaming: config.streaming ?? false,\n headers: config.headers ?? [],\n integrations: config.integrations ?? [],\n configFile,\n };\n}\n\nfunction mergeConfig(base: ElurConfig, override: ElurConfig): ElurConfig {\n return {\n ...base,\n ...override,\n images: { ...base.images, ...override.images },\n cache: { ...base.cache, ...override.cache },\n security: { ...base.security, ...override.security },\n router: { ...base.router, ...override.router },\n logger: { ...base.logger, ...override.logger },\n // Rule arrays match first-match-wins, so override rules go first: they\n // win over base rules for the same path while base keeps the rest.\n redirects: [...(override.redirects ?? []), ...(base.redirects ?? [])],\n rewrites: [...(override.rewrites ?? []), ...(base.rewrites ?? [])],\n headers: [...(override.headers ?? []), ...(base.headers ?? [])],\n integrations: override.integrations ?? base.integrations,\n };\n}\n\nfunction resolveInside(root: string, path: string, name: string): string {\n const resolved = isAbsolute(path) ? resolve(path) : resolve(root, path);\n const rel = relative(root, resolved);\n if (rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {\n throw new Error(`[elur-kit] ${name} must stay inside root: ${resolved}`);\n }\n return resolved;\n}\n\nfunction normalizeBase(base: string): string {\n if (!base.startsWith(\"/\")) throw new Error(\"[elur-kit] base must start with /\");\n return base === \"/\" ? base : `${base.replace(/\\/+$/, \"\")}/`;\n}\n\nconst PREFERRED_CONFIG_FILES = [\"elur.config.ts\", \"elur.config.js\", \"elur.config.mjs\"];\n\nasync function findConfigFile(root: string): Promise<string | undefined> {\n for (const name of PREFERRED_CONFIG_FILES) {\n const path = resolve(root, name);\n try {\n await access(path);\n return path;\n } catch {\n }\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
@@ -1,28 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
isActionFailure: () => s,
|
|
14
|
-
isRedirectResponse: () => c,
|
|
15
|
-
publicErrorResponse: () => u,
|
|
16
|
-
redirect: () => o,
|
|
17
|
-
toPublicErrorInfo: () => l
|
|
18
|
-
}), r = class {
|
|
1
|
+
import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
|
|
2
|
+
//#region src/errors.ts
|
|
3
|
+
var t = /* @__PURE__ */ e({
|
|
4
|
+
ActionFailure: () => n,
|
|
5
|
+
RedirectResponse: () => r,
|
|
6
|
+
fail: () => i,
|
|
7
|
+
isActionFailure: () => o,
|
|
8
|
+
isRedirectResponse: () => s,
|
|
9
|
+
publicErrorResponse: () => l,
|
|
10
|
+
redirect: () => a,
|
|
11
|
+
toPublicErrorInfo: () => c
|
|
12
|
+
}), n = class {
|
|
19
13
|
status;
|
|
20
14
|
data;
|
|
21
15
|
__elur_js_action_failure = !0;
|
|
22
16
|
constructor(e, t) {
|
|
23
17
|
this.status = e, this.data = t;
|
|
24
18
|
}
|
|
25
|
-
},
|
|
19
|
+
}, r = class {
|
|
26
20
|
status;
|
|
27
21
|
location;
|
|
28
22
|
__elur_js_action_redirect = !0;
|
|
@@ -30,19 +24,19 @@ var e = Object.defineProperty, t = (t, n) => {
|
|
|
30
24
|
this.status = e, this.location = t;
|
|
31
25
|
}
|
|
32
26
|
};
|
|
33
|
-
function
|
|
34
|
-
return typeof e == "number" ? new
|
|
27
|
+
function i(e, t) {
|
|
28
|
+
return typeof e == "number" ? new n(e, t) : new n(t ?? 400, e);
|
|
35
29
|
}
|
|
36
|
-
function
|
|
37
|
-
return typeof e == "number" ? new
|
|
30
|
+
function a(e, t) {
|
|
31
|
+
return typeof e == "number" ? new r(e, t) : new r(t ?? 303, e);
|
|
38
32
|
}
|
|
39
|
-
function
|
|
33
|
+
function o(e) {
|
|
40
34
|
return typeof e == "object" && !!e && e.__elur_js_action_failure === !0;
|
|
41
35
|
}
|
|
42
|
-
function
|
|
36
|
+
function s(e) {
|
|
43
37
|
return typeof e == "object" && !!e && e.__elur_js_action_redirect === !0;
|
|
44
38
|
}
|
|
45
|
-
function
|
|
39
|
+
function c(e, t = {}) {
|
|
46
40
|
let n = "INTERNAL_SERVER_ERROR";
|
|
47
41
|
return t.includeDetail && e instanceof Error && e.message ? {
|
|
48
42
|
code: n,
|
|
@@ -54,8 +48,8 @@ function l(e, t = {}) {
|
|
|
54
48
|
message: "Internal Server Error"
|
|
55
49
|
};
|
|
56
50
|
}
|
|
57
|
-
function
|
|
58
|
-
let n =
|
|
51
|
+
function l(e, t = {}) {
|
|
52
|
+
let n = c(e, t), r = {
|
|
59
53
|
"Content-Type": "application/json; charset=utf-8",
|
|
60
54
|
"Cache-Control": "no-store"
|
|
61
55
|
};
|
|
@@ -65,6 +59,6 @@ function u(e, t = {}) {
|
|
|
65
59
|
});
|
|
66
60
|
}
|
|
67
61
|
//#endregion
|
|
68
|
-
export {
|
|
62
|
+
export { o as a, a as c, i, c as l, r as n, s as o, t as r, l as s, n as t };
|
|
69
63
|
|
|
70
|
-
//# sourceMappingURL=errors-
|
|
64
|
+
//# sourceMappingURL=errors-j4cg9VN3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors-
|
|
1
|
+
{"version":3,"file":"errors-j4cg9VN3.js","names":[],"sources":["../../src/errors.ts"],"sourcesContent":["/**\n * Represents a failed action result. Returned by `fail()` from server actions.\n *\n * The `__elur_js_action_failure` marker is set on the instance so the server can\n * detect it even when the value crosses a bundling boundary (e.g. the CLI is\n * bundled separately from the user's action modules).\n */\nexport class ActionFailure<TData = unknown> {\n readonly __elur_js_action_failure = true;\n constructor(\n public status: number,\n public data: TData,\n ) {}\n}\n\n/**\n * Represents a redirect returned by a server action. Returned by `redirect()`.\n */\nexport class RedirectResponse {\n readonly __elur_js_action_redirect = true;\n constructor(\n public status: number,\n public location: string,\n ) {}\n}\n\n/**\n * Helper to return a validation/error response from a server action.\n *\n * Both argument orders are accepted:\n *\n * ```ts\n * return fail(400, { email: \"Invalid email\" });\n * return fail({ email: \"Invalid email\" }, 400);\n * return fail({ email: \"Invalid email\" }); // defaults to status 400\n * ```\n */\nexport function fail<TData>(\n statusOrData: number | TData,\n dataOrStatus?: TData | number,\n): ActionFailure<unknown> {\n if (typeof statusOrData === \"number\") {\n return new ActionFailure(statusOrData, dataOrStatus as TData);\n }\n return new ActionFailure((dataOrStatus as number) ?? 400, statusOrData);\n}\n\n/**\n * Helper to return a redirect from a server action.\n *\n * Both argument orders are accepted:\n *\n * ```ts\n * return redirect(303, \"/login\");\n * return redirect(\"/login\"); // defaults to status 303\n * ```\n */\nexport function redirect(\n statusOrLocation: number | string,\n locationOrStatus?: string | number,\n): RedirectResponse {\n if (typeof statusOrLocation === \"number\") {\n return new RedirectResponse(statusOrLocation, locationOrStatus as string);\n }\n return new RedirectResponse((locationOrStatus as number) ?? 303, statusOrLocation);\n}\n\n/**\n * Type guard for action failures. Uses the marker field so it works across\n * bundling boundaries where `instanceof` fails.\n */\nexport function isActionFailure(value: unknown): value is ActionFailure {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { __elur_js_action_failure?: unknown }).__elur_js_action_failure === true\n );\n}\n\n/**\n * Type guard for redirects. Uses the marker field so it works across bundling\n * boundaries where `instanceof` fails.\n */\nexport function isRedirectResponse(value: unknown): value is RedirectResponse {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { __elur_js_action_redirect?: unknown }).__elur_js_action_redirect === true\n );\n}\n\n// --- Public error sanitization (production-safe 500 responses) ---\n\n/**\n * A stable, publicly safe error description. Never includes stacks, internal\n * paths or messages that could leak secrets or filesystem details.\n */\nexport interface PublicErrorInfo {\n /** Stable machine-readable code for the response body. */\n code: string;\n /** Stable public message. In non-production this may include the raw message. */\n message: string;\n status: number;\n}\n\n/**\n * Maps an arbitrary thrown value to a public-safe error info. By default the\n * public message is generic; `includeDetail` (dev/verbose mode) appends the\n * original `Error.message` for local debugging.\n */\nexport function toPublicErrorInfo(error: unknown, options: { includeDetail?: boolean } = {}): PublicErrorInfo {\n const code = \"INTERNAL_SERVER_ERROR\";\n const status = 500;\n if (options.includeDetail && error instanceof Error && error.message) {\n return { code, status, message: error.message };\n }\n return { code, status, message: \"Internal Server Error\" };\n}\n\n/**\n * Builds a production-safe JSON error Response. Logs the raw error separately\n * (never reflected in the response body) and keeps the request id header.\n */\nexport function publicErrorResponse(\n error: unknown,\n options: { includeDetail?: boolean; requestId?: string } = {},\n): Response {\n const info = toPublicErrorInfo(error, options);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n };\n if (options.requestId) headers[\"X-Request-Id\"] = options.requestId;\n return new Response(JSON.stringify({ error: info }), {\n status: info.status,\n headers,\n });\n}\n\n/** True when the error should be re-thrown as control flow instead of a 500. */\nexport function isFirstClassResponse(error: unknown): error is Response {\n return typeof Response !== \"undefined\" && error instanceof Response;\n}\n"],"mappings":";;;;;;;;;;;IAOa,IAAb,MAA4C;CAGjC;CACA;CAHT,2BAAoC;CACpC,YACE,GACA,GACA;EADO,AADA,KAAA,SAAA,GACA,KAAA,OAAA;CACN;AACL,GAKa,IAAb,MAA8B;CAGnB;CACA;CAHT,4BAAqC;CACrC,YACE,GACA,GACA;EADO,AADA,KAAA,SAAA,GACA,KAAA,WAAA;CACN;AACL;AAaA,SAAgB,EACd,GACA,GACwB;CAIxB,OAHI,OAAO,KAAiB,WACnB,IAAI,EAAc,GAAc,CAAqB,IAEvD,IAAI,EAAe,KAA2B,KAAK,CAAY;AACxE;AAYA,SAAgB,EACd,GACA,GACkB;CAIlB,OAHI,OAAO,KAAqB,WACvB,IAAI,EAAiB,GAAkB,CAA0B,IAEnE,IAAI,EAAkB,KAA+B,KAAK,CAAgB;AACnF;AAMA,SAAgB,EAAgB,GAAwC;CACtE,OACE,OAAO,KAAU,cACjB,KACC,EAAiD,6BAA6B;AAEnF;AAMA,SAAgB,EAAmB,GAA2C;CAC5E,OACE,OAAO,KAAU,cACjB,KACC,EAAkD,8BAA8B;AAErF;AAqBA,SAAgB,EAAkB,GAAgB,IAAuC,CAAC,GAAoB;CAC5G,IAAM,IAAO;CAKb,OAHI,EAAQ,iBAAiB,aAAiB,SAAS,EAAM,UACpD;EAAE;EAAM;EAAQ,SAAS,EAAM;CAAQ,IAEzC;EAAE;EAAM;EAAQ,SAAS;CAAwB;AAC1D;AAMA,SAAgB,EACd,GACA,IAA2D,CAAC,GAClD;CACV,IAAM,IAAO,EAAkB,GAAO,CAAO,GACvC,IAAkC;EACtC,gBAAgB;EAChB,iBAAiB;CACnB;CAEA,OADI,EAAQ,cAAW,EAAQ,kBAAkB,EAAQ,YAClD,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,EAAK,CAAC,GAAG;EACnD,QAAQ,EAAK;EACb;CACF,CAAC;AACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=require("./rolldown-runtime-BIInC43l.cjs").t({ActionFailure:()=>t,RedirectResponse:()=>n,fail:()=>r,isActionFailure:()=>a,isRedirectResponse:()=>o,publicErrorResponse:()=>c,redirect:()=>i,toPublicErrorInfo:()=>s}),t=class{status;data;__elur_js_action_failure=!0;constructor(e,t){this.status=e,this.data=t}},n=class{status;location;__elur_js_action_redirect=!0;constructor(e,t){this.status=e,this.location=t}};function r(e,n){return typeof e==`number`?new t(e,n):new t(n??400,e)}function i(e,t){return typeof e==`number`?new n(e,t):new n(t??303,e)}function a(e){return typeof e==`object`&&!!e&&e.__elur_js_action_failure===!0}function o(e){return typeof e==`object`&&!!e&&e.__elur_js_action_redirect===!0}function s(e,t={}){let n=`INTERNAL_SERVER_ERROR`;return t.includeDetail&&e instanceof Error&&e.message?{code:n,status:500,message:e.message}:{code:n,status:500,message:`Internal Server Error`}}function c(e,t={}){let n=s(e,t),r={"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`};return t.requestId&&(r[`X-Request-Id`]=t.requestId),new Response(JSON.stringify({error:n}),{status:n.status,headers:r})}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return t}});
|
|
2
|
+
//# sourceMappingURL=errors-kSl9yLkg.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors-
|
|
1
|
+
{"version":3,"file":"errors-kSl9yLkg.cjs","names":[],"sources":["../../src/errors.ts"],"sourcesContent":["/**\n * Represents a failed action result. Returned by `fail()` from server actions.\n *\n * The `__elur_js_action_failure` marker is set on the instance so the server can\n * detect it even when the value crosses a bundling boundary (e.g. the CLI is\n * bundled separately from the user's action modules).\n */\nexport class ActionFailure<TData = unknown> {\n readonly __elur_js_action_failure = true;\n constructor(\n public status: number,\n public data: TData,\n ) {}\n}\n\n/**\n * Represents a redirect returned by a server action. Returned by `redirect()`.\n */\nexport class RedirectResponse {\n readonly __elur_js_action_redirect = true;\n constructor(\n public status: number,\n public location: string,\n ) {}\n}\n\n/**\n * Helper to return a validation/error response from a server action.\n *\n * Both argument orders are accepted:\n *\n * ```ts\n * return fail(400, { email: \"Invalid email\" });\n * return fail({ email: \"Invalid email\" }, 400);\n * return fail({ email: \"Invalid email\" }); // defaults to status 400\n * ```\n */\nexport function fail<TData>(\n statusOrData: number | TData,\n dataOrStatus?: TData | number,\n): ActionFailure<unknown> {\n if (typeof statusOrData === \"number\") {\n return new ActionFailure(statusOrData, dataOrStatus as TData);\n }\n return new ActionFailure((dataOrStatus as number) ?? 400, statusOrData);\n}\n\n/**\n * Helper to return a redirect from a server action.\n *\n * Both argument orders are accepted:\n *\n * ```ts\n * return redirect(303, \"/login\");\n * return redirect(\"/login\"); // defaults to status 303\n * ```\n */\nexport function redirect(\n statusOrLocation: number | string,\n locationOrStatus?: string | number,\n): RedirectResponse {\n if (typeof statusOrLocation === \"number\") {\n return new RedirectResponse(statusOrLocation, locationOrStatus as string);\n }\n return new RedirectResponse((locationOrStatus as number) ?? 303, statusOrLocation);\n}\n\n/**\n * Type guard for action failures. Uses the marker field so it works across\n * bundling boundaries where `instanceof` fails.\n */\nexport function isActionFailure(value: unknown): value is ActionFailure {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { __elur_js_action_failure?: unknown }).__elur_js_action_failure === true\n );\n}\n\n/**\n * Type guard for redirects. Uses the marker field so it works across bundling\n * boundaries where `instanceof` fails.\n */\nexport function isRedirectResponse(value: unknown): value is RedirectResponse {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { __elur_js_action_redirect?: unknown }).__elur_js_action_redirect === true\n );\n}\n\n// --- Public error sanitization (production-safe 500 responses) ---\n\n/**\n * A stable, publicly safe error description. Never includes stacks, internal\n * paths or messages that could leak secrets or filesystem details.\n */\nexport interface PublicErrorInfo {\n /** Stable machine-readable code for the response body. */\n code: string;\n /** Stable public message. In non-production this may include the raw message. */\n message: string;\n status: number;\n}\n\n/**\n * Maps an arbitrary thrown value to a public-safe error info. By default the\n * public message is generic; `includeDetail` (dev/verbose mode) appends the\n * original `Error.message` for local debugging.\n */\nexport function toPublicErrorInfo(error: unknown, options: { includeDetail?: boolean } = {}): PublicErrorInfo {\n const code = \"INTERNAL_SERVER_ERROR\";\n const status = 500;\n if (options.includeDetail && error instanceof Error && error.message) {\n return { code, status, message: error.message };\n }\n return { code, status, message: \"Internal Server Error\" };\n}\n\n/**\n * Builds a production-safe JSON error Response. Logs the raw error separately\n * (never reflected in the response body) and keeps the request id header.\n */\nexport function publicErrorResponse(\n error: unknown,\n options: { includeDetail?: boolean; requestId?: string } = {},\n): Response {\n const info = toPublicErrorInfo(error, options);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n };\n if (options.requestId) headers[\"X-Request-Id\"] = options.requestId;\n return new Response(JSON.stringify({ error: info }), {\n status: info.status,\n headers,\n });\n}\n\n/** True when the error should be re-thrown as control flow instead of a 500. */\nexport function isFirstClassResponse(error: unknown): error is Response {\n return typeof Response !== \"undefined\" && error instanceof Response;\n}\n"],"mappings":"4NAOa,EAAb,KAA4C,CAGjC,OACA,KAHT,yBAAoC,GACpC,YACE,EACA,EACA,CAFO,KAAA,OAAA,EACA,KAAA,KAAA,CACN,CACL,EAKa,EAAb,KAA8B,CAGnB,OACA,SAHT,0BAAqC,GACrC,YACE,EACA,EACA,CAFO,KAAA,OAAA,EACA,KAAA,SAAA,CACN,CACL,EAaA,SAAgB,EACd,EACA,EACwB,CAIxB,OAHI,OAAO,GAAiB,SACnB,IAAI,EAAc,EAAc,CAAqB,EAEvD,IAAI,EAAe,GAA2B,IAAK,CAAY,CACxE,CAYA,SAAgB,EACd,EACA,EACkB,CAIlB,OAHI,OAAO,GAAqB,SACvB,IAAI,EAAiB,EAAkB,CAA0B,EAEnE,IAAI,EAAkB,GAA+B,IAAK,CAAgB,CACnF,CAMA,SAAgB,EAAgB,EAAwC,CACtE,OACE,OAAO,GAAU,YACjB,GACC,EAAiD,2BAA6B,EAEnF,CAMA,SAAgB,EAAmB,EAA2C,CAC5E,OACE,OAAO,GAAU,YACjB,GACC,EAAkD,4BAA8B,EAErF,CAqBA,SAAgB,EAAkB,EAAgB,EAAuC,CAAC,EAAoB,CAC5G,IAAM,EAAO,wBAKb,OAHI,EAAQ,eAAiB,aAAiB,OAAS,EAAM,QACpD,CAAE,OAAM,WAAQ,QAAS,EAAM,OAAQ,EAEzC,CAAE,OAAM,WAAQ,QAAS,uBAAwB,CAC1D,CAMA,SAAgB,EACd,EACA,EAA2D,CAAC,EAClD,CACV,IAAM,EAAO,EAAkB,EAAO,CAAO,EACvC,EAAkC,CACtC,eAAgB,kCAChB,gBAAiB,UACnB,EAEA,OADI,EAAQ,YAAW,EAAQ,gBAAkB,EAAQ,WAClD,IAAI,SAAS,KAAK,UAAU,CAAE,MAAO,CAAK,CAAC,EAAG,CACnD,OAAQ,EAAK,OACb,SACF,CAAC,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./island-kfQEKRe_.cjs");let t=require("@elurjs/core/hydrate");var n=new Map,r=new Map;function i(e){return{load:e}}function a(e){return typeof e==`object`&&!!e&&typeof e.load==`function`}function o(e){return typeof e==`function`?e.constructor?.name===`AsyncFunction`||e[Symbol.toStringTag]===`AsyncFunction`:!1}function s(){return Array.from(document.querySelectorAll(`[${e.t}]`)).map(e=>{let t={el:e,name:e.dataset.elurIsland??``,directive:e.dataset.directive??`load`,props:null};if(e.dataset.props)try{t.props=JSON.parse(e.dataset.props)}catch(e){t.propsError=e}return t})}async function c(e,r){try{if(e.propsError){l(e,e.propsError);return}let i=r[e.name];if(!i){console.warn(`[elur-kit] No island registered for "${e.name}". Check that src/islands/${e.name}.ts exists and rebuild so the client entry is regenerated.`);return}let s;if(a(i)){let e=await i.load();s=typeof e==`function`?e:e.default}else if(typeof i==`function`){if(o(i)){let e=await i();s=typeof e==`function`?e:e.default}else s=i}if(typeof s!=`function`){console.warn(`[elur-kit] Island "${e.name}" did not resolve to a component function. Check that the island module exports the component as default export.`);return}let c=s(e.props);if(c===null||c===!1||c===void 0)return;let d=e.el.__elur_js_island_dispose;typeof d==`function`&&d();let f=e.el.innerHTML.includes(`<!--elur-`)?(0,t.hydrate)(c,e.el,{mismatch:`warn-remount`}):u(c,e.el),p=()=>{f.unmount(),n.get(e.el)===p&&n.delete(e.el),delete e.el.__elur_js_island_dispose};e.el.__elur_js_island_dispose=p,n.set(e.el,p)}catch(t){l(e,t)}}function l(e,t){console.error(`[elur-kit] Failed to hydrate island "${e.name}" — the server-rendered HTML was left as-is. Cause:`,t);let n=e.el.ownerDocument.defaultView?.CustomEvent;n&&e.el.dispatchEvent(new n(`elur:island-error`,{bubbles:!0,detail:{name:e.name,error:t}}))}function u(e,t){return t.replaceChildren(),{unmount:e._render(t,null)}}function d(e){let t=e?.except?Array.from(e.except):void 0,i=e=>t?.some(t=>t===e||t.contains(e))??!1;for(let[e,t]of r)i(e)||(r.delete(e),t());for(let[e,t]of n)i(e)||t()}function f(e){if(typeof window>`u`)return;let t=s();for(let n of t){let t=n.el;if(typeof t.__elur_js_island_dispose==`function`){if(t.closest(`[data-elur-persist]`))continue;t.__elur_js_island_dispose()}if(!r.has(n.el)){if(n.directive===`load`||n.directive===`only`){c(n,e);continue}if(n.directive===`idle`){let t=()=>{};if(`requestIdleCallback`in window){let i=window.requestIdleCallback(()=>{r.delete(n.el),c(n,e)});t=()=>window.cancelIdleCallback(i)}else{let i=globalThis.setTimeout(()=>{r.delete(n.el),c(n,e)},0);t=()=>globalThis.clearTimeout(i)}r.set(n.el,t);continue}if(n.directive===`visible`){if(`IntersectionObserver`in window){let t=()=>{},i=new IntersectionObserver(t=>{for(let a of t)a.isIntersecting&&(r.delete(n.el),i.disconnect(),c(n,e))},{rootMargin:`0px`,threshold:0});t=()=>i.disconnect(),r.set(n.el,t),i.observe(n.el)}else c(n,e)}}}}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return d}});
|
|
2
|
+
//# sourceMappingURL=hydrate-BSLuI0Nh.cjs.map
|