waku 0.23.4 → 0.23.5
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/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/lib/middleware/handler.js +4 -1
- package/dist/lib/middleware/handler.js.map +1 -1
- package/dist/lib/plugins/vite-plugin-rsc-env.js +2 -1
- package/dist/lib/plugins/vite-plugin-rsc-env.js.map +1 -1
- package/dist/lib/renderers/html.js +1 -1
- package/dist/lib/renderers/html.js.map +1 -1
- package/dist/lib/types.d.ts +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/router/client.js +8 -6
- package/dist/router/client.js.map +1 -1
- package/dist/router/create-pages.d.ts +15 -1
- package/dist/router/create-pages.js +38 -2
- package/dist/router/create-pages.js.map +1 -1
- package/dist/router/define-router.d.ts +1 -1
- package/dist/router/define-router.js +30 -7
- package/dist/router/define-router.js.map +1 -1
- package/package.json +8 -8
- package/dist/lib/middleware/fallback.d.ts +0 -2
- package/dist/lib/middleware/fallback.js +0 -26
- package/dist/lib/middleware/fallback.js.map +0 -1
- package/dist/middleware/fallback.d.ts +0 -1
- package/dist/middleware/fallback.js +0 -3
- package/dist/middleware/fallback.js.map +0 -1
package/dist/cli.js
CHANGED
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import path from 'node:path';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { pathToFileURL } from 'node:url';\nimport { parseArgs } from 'node:util';\nimport { createRequire } from 'node:module';\nimport process from 'node:process';\nimport { Hono } from 'hono';\nimport { compress } from 'hono/compress';\nimport { serve } from '@hono/node-server';\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport * as dotenv from 'dotenv';\n\nimport type { Config } from './config.js';\nimport { serverEngine } from './lib/hono/engine.js';\nimport { build } from './lib/builder/build.js';\nimport { DIST_SERVER_ENTRY_JS, DIST_PUBLIC } from './lib/builder/constants.js';\n\nconst require = createRequire(new URL('.', import.meta.url));\n\ndotenv.config({ path: ['.env.local', '.env'] });\n\nconst CONFIG_FILE = 'waku.config.ts'; // XXX only ts extension\n\nconst { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n allowPositionals: true,\n options: {\n 'with-vercel': {\n type: 'boolean',\n },\n 'with-vercel-static': {\n type: 'boolean',\n },\n 'with-netlify': {\n type: 'boolean',\n },\n 'with-netlify-static': {\n type: 'boolean',\n },\n 'with-cloudflare': {\n type: 'boolean',\n },\n 'with-partykit': {\n type: 'boolean',\n },\n 'with-deno': {\n type: 'boolean',\n },\n 'with-aws-lambda': {\n type: 'boolean',\n },\n 'experimental-partial': {\n type: 'boolean',\n },\n 'experimental-compress': {\n type: 'boolean',\n },\n port: {\n type: 'string',\n short: 'p',\n },\n version: {\n type: 'boolean',\n short: 'v',\n },\n help: {\n type: 'boolean',\n short: 'h',\n },\n },\n});\n\nconst cmd = positionals[0];\n\nif (values.version) {\n const { version } = require('../package.json');\n console.log(version);\n} else if (values.help) {\n displayUsage();\n} else {\n switch (cmd) {\n case 'dev':\n await runDev();\n break;\n case 'build':\n await runBuild();\n break;\n case 'start':\n await runStart();\n break;\n default:\n if (cmd) {\n console.error('Unknown command:', cmd);\n }\n displayUsage();\n break;\n }\n}\n\nasync function runDev() {\n const config = await loadConfig();\n const honoEnhancer: HonoEnhancer = config.unstable_honoEnhancer\n ? await loadHonoEnhancer(config.unstable_honoEnhancer)\n : (fn) => fn;\n const createApp = (app: Hono) => {\n if (values['experimental-compress']) {\n app.use(compress());\n }\n app.use(\n serverEngine({\n cmd: 'dev',\n config,\n env: process.env as any,\n unstable_onError: new Set(),\n }),\n );\n app.notFound((c) => {\n // FIXME can we avoid hardcoding the public path?\n const file = path.join('public', '404.html');\n if (existsSync(file)) {\n return c.html(readFileSync(file, 'utf8'), 404);\n }\n return c.text('404 Not Found', 404);\n });\n return app;\n };\n const port = parseInt(values.port || '3000', 10);\n await startServer(honoEnhancer(createApp)(new Hono()), port);\n}\n\nasync function runBuild() {\n const config = await loadConfig();\n process.env.NODE_ENV = 'production';\n await build({\n config,\n env: process.env as any,\n partial: !!values['experimental-partial'],\n deploy:\n ((values['with-vercel'] ?? !!process.env.VERCEL)\n ? values['with-vercel-static']\n ? 'vercel-static'\n : 'vercel-serverless'\n : undefined) ||\n ((values['with-netlify'] ?? !!process.env.NETLIFY)\n ? values['with-netlify-static']\n ? 'netlify-static'\n : 'netlify-functions'\n : undefined) ||\n (values['with-cloudflare'] ? 'cloudflare' : undefined) ||\n (values['with-partykit'] ? 'partykit' : undefined) ||\n (values['with-deno'] ? 'deno' : undefined) ||\n (values['with-aws-lambda'] ? 'aws-lambda' : undefined),\n });\n}\n\nasync function runStart() {\n const config = await loadConfig();\n const { distDir = 'dist' } = config;\n const honoEnhancer: HonoEnhancer = config.unstable_honoEnhancer\n ? await loadHonoEnhancer(config.unstable_honoEnhancer)\n : (fn) => fn;\n const loadEntries = () =>\n import(\n pathToFileURL(path.resolve(distDir, DIST_SERVER_ENTRY_JS)).toString()\n );\n const createApp = (app: Hono) => {\n if (values['experimental-compress']) {\n app.use(compress());\n }\n app.use(serveStatic({ root: path.join(distDir, DIST_PUBLIC) }));\n app.use(\n serverEngine({\n cmd: 'start',\n loadEntries,\n env: process.env as any,\n unstable_onError: new Set(),\n }),\n );\n app.notFound((c) => {\n // FIXME better implementation using node stream?\n const file = path.join(distDir, DIST_PUBLIC, '404.html');\n if (existsSync(file)) {\n return c.html(readFileSync(file, 'utf8'), 404);\n }\n return c.text('404 Not Found', 404);\n });\n return app;\n };\n const port = parseInt(values.port || '8080', 10);\n await startServer(honoEnhancer(createApp)(new Hono()), port);\n}\n\nfunction startServer(app: Hono, port: number) {\n return new Promise<void>((resolve, reject) => {\n const server = serve({ ...app, port }, () => {\n console.log(`ready: Listening on http://localhost:${port}/`);\n resolve();\n });\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log(\n `warn: Port ${port} is in use, trying ${port + 1} instead.`,\n );\n startServer(app, port + 1)\n .then(resolve)\n .catch(reject);\n } else {\n console.error(`Failed to start server: ${err.message}`);\n }\n });\n });\n}\n\nfunction displayUsage() {\n console.log(`\nUsage: waku [options] <command>\n\nCommands:\n dev Start the development server\n build Build the application for production\n start Start the production server\n\nOptions:\n --with-vercel Output for Vercel on build\n --with-netlify Output for Netlify on build\n --with-cloudflare Output for Cloudflare on build\n --with-partykit Output for PartyKit on build\n --with-deno Output for Deno on build\n --with-aws-lambda Output for AWS Lambda on build\n -p, --port Port number for the server\n -v, --version Display the version number\n -h, --help Display this help message\n`);\n}\n\nasync function loadConfig(): Promise<Config> {\n if (!existsSync(CONFIG_FILE)) {\n return {};\n }\n const { loadServerModule } = await import('./lib/utils/vite-loader.js');\n const file = pathToFileURL(path.resolve(CONFIG_FILE)).toString();\n return (await loadServerModule<{ default: Config }>(file)).default;\n}\n\ntype HonoEnhancer = <Hono>(fn: (app: Hono) => Hono) => (app: Hono) => Hono;\n\nasync function loadHonoEnhancer(file: string): Promise<HonoEnhancer> {\n const { loadServerModule } = await import('./lib/utils/vite-loader.js');\n const fileUrl = pathToFileURL(\n path.resolve(CONFIG_FILE, '..', file),\n ).toString();\n return (await loadServerModule<{ default: HonoEnhancer }>(fileUrl)).default;\n}\n"],"names":["path","existsSync","readFileSync","pathToFileURL","parseArgs","createRequire","process","Hono","compress","serve","serveStatic","dotenv","serverEngine","build","DIST_SERVER_ENTRY_JS","DIST_PUBLIC","require","URL","url","config","CONFIG_FILE","values","positionals","args","argv","slice","allowPositionals","options","type","port","short","version","help","cmd","console","log","displayUsage","runDev","runBuild","runStart","error","loadConfig","honoEnhancer","unstable_honoEnhancer","loadHonoEnhancer","fn","createApp","app","use","env","unstable_onError","Set","notFound","c","file","join","html","text","parseInt","startServer","NODE_ENV","partial","deploy","VERCEL","undefined","NETLIFY","distDir","loadEntries","resolve","toString","root","Promise","reject","server","on","err","code","then","catch","message","loadServerModule","default","fileUrl"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import path from 'node:path';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { pathToFileURL } from 'node:url';\nimport { parseArgs } from 'node:util';\nimport { createRequire } from 'node:module';\nimport process from 'node:process';\nimport { Hono } from 'hono';\nimport { compress } from 'hono/compress';\nimport { serve } from '@hono/node-server';\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport * as dotenv from 'dotenv';\n\nimport type { Config } from './config.js';\nimport { serverEngine } from './lib/hono/engine.js';\nimport { build } from './lib/builder/build.js';\nimport { DIST_SERVER_ENTRY_JS, DIST_PUBLIC } from './lib/builder/constants.js';\n\nconst require = createRequire(new URL('.', import.meta.url));\n\ndotenv.config({ path: ['.env.local', '.env'], quiet: true });\n\nconst CONFIG_FILE = 'waku.config.ts'; // XXX only ts extension\n\nconst { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n allowPositionals: true,\n options: {\n 'with-vercel': {\n type: 'boolean',\n },\n 'with-vercel-static': {\n type: 'boolean',\n },\n 'with-netlify': {\n type: 'boolean',\n },\n 'with-netlify-static': {\n type: 'boolean',\n },\n 'with-cloudflare': {\n type: 'boolean',\n },\n 'with-partykit': {\n type: 'boolean',\n },\n 'with-deno': {\n type: 'boolean',\n },\n 'with-aws-lambda': {\n type: 'boolean',\n },\n 'experimental-partial': {\n type: 'boolean',\n },\n 'experimental-compress': {\n type: 'boolean',\n },\n port: {\n type: 'string',\n short: 'p',\n },\n version: {\n type: 'boolean',\n short: 'v',\n },\n help: {\n type: 'boolean',\n short: 'h',\n },\n },\n});\n\nconst cmd = positionals[0];\n\nif (values.version) {\n const { version } = require('../package.json');\n console.log(version);\n} else if (values.help) {\n displayUsage();\n} else {\n switch (cmd) {\n case 'dev':\n await runDev();\n break;\n case 'build':\n await runBuild();\n break;\n case 'start':\n await runStart();\n break;\n default:\n if (cmd) {\n console.error('Unknown command:', cmd);\n }\n displayUsage();\n break;\n }\n}\n\nasync function runDev() {\n const config = await loadConfig();\n const honoEnhancer: HonoEnhancer = config.unstable_honoEnhancer\n ? await loadHonoEnhancer(config.unstable_honoEnhancer)\n : (fn) => fn;\n const createApp = (app: Hono) => {\n if (values['experimental-compress']) {\n app.use(compress());\n }\n app.use(\n serverEngine({\n cmd: 'dev',\n config,\n env: process.env as any,\n unstable_onError: new Set(),\n }),\n );\n app.notFound((c) => {\n // FIXME can we avoid hardcoding the public path?\n const file = path.join('public', '404.html');\n if (existsSync(file)) {\n return c.html(readFileSync(file, 'utf8'), 404);\n }\n return c.text('404 Not Found', 404);\n });\n return app;\n };\n const port = parseInt(values.port || '3000', 10);\n await startServer(honoEnhancer(createApp)(new Hono()), port);\n}\n\nasync function runBuild() {\n const config = await loadConfig();\n process.env.NODE_ENV = 'production';\n await build({\n config,\n env: process.env as any,\n partial: !!values['experimental-partial'],\n deploy:\n ((values['with-vercel'] ?? !!process.env.VERCEL)\n ? values['with-vercel-static']\n ? 'vercel-static'\n : 'vercel-serverless'\n : undefined) ||\n ((values['with-netlify'] ?? !!process.env.NETLIFY)\n ? values['with-netlify-static']\n ? 'netlify-static'\n : 'netlify-functions'\n : undefined) ||\n (values['with-cloudflare'] ? 'cloudflare' : undefined) ||\n (values['with-partykit'] ? 'partykit' : undefined) ||\n (values['with-deno'] ? 'deno' : undefined) ||\n (values['with-aws-lambda'] ? 'aws-lambda' : undefined),\n });\n}\n\nasync function runStart() {\n const config = await loadConfig();\n const { distDir = 'dist' } = config;\n const honoEnhancer: HonoEnhancer = config.unstable_honoEnhancer\n ? await loadHonoEnhancer(config.unstable_honoEnhancer)\n : (fn) => fn;\n const loadEntries = () =>\n import(\n pathToFileURL(path.resolve(distDir, DIST_SERVER_ENTRY_JS)).toString()\n );\n const createApp = (app: Hono) => {\n if (values['experimental-compress']) {\n app.use(compress());\n }\n app.use(serveStatic({ root: path.join(distDir, DIST_PUBLIC) }));\n app.use(\n serverEngine({\n cmd: 'start',\n loadEntries,\n env: process.env as any,\n unstable_onError: new Set(),\n }),\n );\n app.notFound((c) => {\n // FIXME better implementation using node stream?\n const file = path.join(distDir, DIST_PUBLIC, '404.html');\n if (existsSync(file)) {\n return c.html(readFileSync(file, 'utf8'), 404);\n }\n return c.text('404 Not Found', 404);\n });\n return app;\n };\n const port = parseInt(values.port || '8080', 10);\n await startServer(honoEnhancer(createApp)(new Hono()), port);\n}\n\nfunction startServer(app: Hono, port: number) {\n return new Promise<void>((resolve, reject) => {\n const server = serve({ ...app, port }, () => {\n console.log(`ready: Listening on http://localhost:${port}/`);\n resolve();\n });\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log(\n `warn: Port ${port} is in use, trying ${port + 1} instead.`,\n );\n startServer(app, port + 1)\n .then(resolve)\n .catch(reject);\n } else {\n console.error(`Failed to start server: ${err.message}`);\n }\n });\n });\n}\n\nfunction displayUsage() {\n console.log(`\nUsage: waku [options] <command>\n\nCommands:\n dev Start the development server\n build Build the application for production\n start Start the production server\n\nOptions:\n --with-vercel Output for Vercel on build\n --with-netlify Output for Netlify on build\n --with-cloudflare Output for Cloudflare on build\n --with-partykit Output for PartyKit on build\n --with-deno Output for Deno on build\n --with-aws-lambda Output for AWS Lambda on build\n -p, --port Port number for the server\n -v, --version Display the version number\n -h, --help Display this help message\n`);\n}\n\nasync function loadConfig(): Promise<Config> {\n if (!existsSync(CONFIG_FILE)) {\n return {};\n }\n const { loadServerModule } = await import('./lib/utils/vite-loader.js');\n const file = pathToFileURL(path.resolve(CONFIG_FILE)).toString();\n return (await loadServerModule<{ default: Config }>(file)).default;\n}\n\ntype HonoEnhancer = <Hono>(fn: (app: Hono) => Hono) => (app: Hono) => Hono;\n\nasync function loadHonoEnhancer(file: string): Promise<HonoEnhancer> {\n const { loadServerModule } = await import('./lib/utils/vite-loader.js');\n const fileUrl = pathToFileURL(\n path.resolve(CONFIG_FILE, '..', file),\n ).toString();\n return (await loadServerModule<{ default: HonoEnhancer }>(fileUrl)).default;\n}\n"],"names":["path","existsSync","readFileSync","pathToFileURL","parseArgs","createRequire","process","Hono","compress","serve","serveStatic","dotenv","serverEngine","build","DIST_SERVER_ENTRY_JS","DIST_PUBLIC","require","URL","url","config","quiet","CONFIG_FILE","values","positionals","args","argv","slice","allowPositionals","options","type","port","short","version","help","cmd","console","log","displayUsage","runDev","runBuild","runStart","error","loadConfig","honoEnhancer","unstable_honoEnhancer","loadHonoEnhancer","fn","createApp","app","use","env","unstable_onError","Set","notFound","c","file","join","html","text","parseInt","startServer","NODE_ENV","partial","deploy","VERCEL","undefined","NETLIFY","distDir","loadEntries","resolve","toString","root","Promise","reject","server","on","err","code","then","catch","message","loadServerModule","default","fileUrl"],"mappings":"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"}
|
|
@@ -129,7 +129,10 @@ export const handler = (options)=>{
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
if (res
|
|
132
|
+
if (res === 'fallback') {
|
|
133
|
+
const newUrl = new URL(config.basePath, ctx.req.url);
|
|
134
|
+
ctx.req.url.pathname = newUrl.pathname;
|
|
135
|
+
} else if (res instanceof ReadableStream) {
|
|
133
136
|
ctx.res.body = res;
|
|
134
137
|
} else if (res) {
|
|
135
138
|
if (res.body) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/middleware/handler.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { resolveConfigDev } from '../config.js';\nimport type { ConfigPrd } from '../config.js';\nimport {\n INTERNAL_setAllEnv,\n INTERNAL_setPlatformDataLoader,\n} from '../../server.js';\nimport type { HandleRequest, HandlerRes } from '../types.js';\nimport type { Middleware, HandlerContext } from './types.js';\nimport { renderRsc, decodeBody, decodePostAction } from '../renderers/rsc.js';\nimport { renderHtml } from '../renderers/html.js';\nimport { decodeRscPath, decodeFuncId } from '../renderers/utils.js';\nimport { filePathToFileURL, getPathMapping } from '../utils/path.js';\nimport { getErrorInfo } from '../utils/custom-errors.js';\nimport { stringToStream } from '../utils/stream.js';\n\nexport const SERVER_MODULE_MAP = {\n 'rsdw-server': 'react-server-dom-webpack/server.edge',\n} as const;\nexport const CLIENT_MODULE_MAP = {\n 'rd-server': 'react-dom/server.edge',\n 'rsdw-client': 'react-server-dom-webpack/client.edge',\n 'waku-minimal-client': 'waku/minimal/client',\n} as const;\nexport const CLIENT_PREFIX = 'client/';\n\nconst getInput = async (\n config: ConfigPrd,\n ctx: HandlerContext,\n loadServerModule: (fileId: string) => Promise<unknown>,\n): Promise<Parameters<HandleRequest>[0] | null> => {\n if (!ctx.req.url.pathname.startsWith(config.basePath)) {\n return null;\n }\n const basePrefix = config.basePath + config.rscBase + '/';\n if (ctx.req.url.pathname.startsWith(basePrefix)) {\n const rscPath = decodeRscPath(\n decodeURI(ctx.req.url.pathname.slice(basePrefix.length)),\n );\n const decodedBody = await decodeBody(ctx);\n const funcId = decodeFuncId(rscPath);\n if (funcId) {\n const args = Array.isArray(decodedBody)\n ? decodedBody\n : decodedBody instanceof URLSearchParams\n ? [decodedBody]\n : [];\n const [fileId, name] = funcId.split('#') as [string, string];\n const mod: any = await loadServerModule(fileId);\n return { type: 'function', fn: mod[name], args, req: ctx.req };\n }\n return { type: 'component', rscPath, rscParams: decodedBody, req: ctx.req };\n }\n if (ctx.req.method === 'POST') {\n const postAction = await decodePostAction(ctx);\n if (postAction) {\n return {\n type: 'action',\n fn: postAction,\n pathname:\n '/' + decodeURI(ctx.req.url.pathname.slice(config.basePath.length)),\n req: ctx.req,\n };\n }\n }\n return {\n type: 'custom',\n pathname:\n '/' + decodeURI(ctx.req.url.pathname.slice(config.basePath.length)),\n req: ctx.req,\n };\n};\n\nexport const handler: Middleware = (options) => {\n const env = options.env;\n INTERNAL_setAllEnv(env);\n const entriesPrdPromise =\n options.cmd === 'start' ? options.loadEntries() : null;\n entriesPrdPromise\n ?.then((entries) => {\n if (entries.loadPlatformData) {\n INTERNAL_setPlatformDataLoader(entries.loadPlatformData);\n }\n })\n .catch(() => {});\n const configDevPromise =\n options.cmd === 'dev' ? resolveConfigDev(options.config) : null;\n\n return async (ctx, next) => {\n const { unstable_devServer: devServer } = ctx;\n const entriesPrd = await entriesPrdPromise!;\n const config = devServer ? await configDevPromise! : entriesPrd.configPrd;\n const entries = devServer\n ? await devServer.loadEntriesDev(await configDevPromise!)\n : entriesPrd;\n const rsdwServer = devServer\n ? await devServer.loadServerModuleRsc(SERVER_MODULE_MAP['rsdw-server'])\n : await entriesPrd.loadModule('rsdw-server');\n const rdServer = devServer\n ? await devServer.loadServerModuleMain(CLIENT_MODULE_MAP['rd-server'])\n : await entriesPrd.loadModule(CLIENT_PREFIX + 'rd-server');\n const rsdwClient = devServer\n ? await devServer.loadServerModuleMain(CLIENT_MODULE_MAP['rsdw-client'])\n : await entriesPrd.loadModule(CLIENT_PREFIX + 'rsdw-client');\n const wakuMinimalClient = devServer\n ? await devServer.loadServerModuleMain(\n CLIENT_MODULE_MAP['waku-minimal-client'],\n )\n : await entriesPrd.loadModule(CLIENT_PREFIX + 'waku-minimal-client');\n ctx.unstable_modules = {\n rsdwServer,\n rdServer,\n rsdwClient,\n wakuMinimalClient,\n };\n const loadServerModule = (fileId: string) => {\n if (devServer) {\n return devServer.loadServerModuleRsc(filePathToFileURL(fileId));\n } else {\n return entriesPrd.loadModule(fileId + '.js');\n }\n };\n const htmlHead = devServer\n ? ''\n : entriesPrd.dynamicHtmlPaths.find(([pathSpec]) =>\n getPathMapping(pathSpec, ctx.req.url.pathname),\n )?.[1] || entriesPrd.defaultHtmlHead;\n const transformIndexHtml =\n devServer && (await devServer.transformIndexHtml(ctx.req.url.pathname));\n const utils = {\n renderRsc: (elements: Record<string, unknown>) =>\n renderRsc(config, ctx, elements, options.unstable_onError),\n renderHtml: async (\n elements: Record<string, unknown>,\n html: ReactNode,\n opts: { rscPath: string; actionResult?: unknown },\n ) => {\n const readable = await renderHtml(\n config,\n ctx,\n htmlHead,\n elements,\n options.unstable_onError,\n html,\n opts.rscPath,\n opts.actionResult,\n );\n const headers = { 'content-type': 'text/html; charset=utf-8' };\n let body = readable;\n if (transformIndexHtml) {\n body = readable.pipeThrough(transformIndexHtml) as never;\n body.allReady = readable.allReady;\n }\n return { body, headers };\n },\n };\n const input = await getInput(config, ctx, loadServerModule);\n if (input) {\n let res: ReadableStream | HandlerRes | null | undefined;\n try {\n res = await entries.default.handleRequest(input, utils);\n } catch (e) {\n options.unstable_onError.forEach((fn) => fn(e, ctx, 'handler'));\n const info = getErrorInfo(e);\n if (info?.status !== 404) {\n ctx.res.status = info?.status || 500;\n ctx.res.body = stringToStream(\n (e as { message?: string } | undefined)?.message || String(e),\n );\n if (info?.location) {\n (ctx.res.headers ||= {}).location = info.location;\n }\n }\n }\n if (res instanceof ReadableStream) {\n ctx.res.body = res;\n } else if (res) {\n if (res.body) {\n ctx.res.body = res.body;\n }\n if (res.status) {\n ctx.res.status = res.status;\n }\n if (res.headers) {\n Object.assign((ctx.res.headers ||= {}), res.headers);\n }\n }\n if (ctx.res.body || ctx.res.status) {\n return;\n }\n }\n\n await next();\n };\n};\n"],"names":["resolveConfigDev","INTERNAL_setAllEnv","INTERNAL_setPlatformDataLoader","renderRsc","decodeBody","decodePostAction","renderHtml","decodeRscPath","decodeFuncId","filePathToFileURL","getPathMapping","getErrorInfo","stringToStream","SERVER_MODULE_MAP","CLIENT_MODULE_MAP","CLIENT_PREFIX","getInput","config","ctx","loadServerModule","req","url","pathname","startsWith","basePath","basePrefix","rscBase","rscPath","decodeURI","slice","length","decodedBody","funcId","args","Array","isArray","URLSearchParams","fileId","name","split","mod","type","fn","rscParams","method","postAction","handler","options","env","entriesPrdPromise","cmd","loadEntries","then","entries","loadPlatformData","catch","configDevPromise","next","unstable_devServer","devServer","entriesPrd","configPrd","loadEntriesDev","rsdwServer","loadServerModuleRsc","loadModule","rdServer","loadServerModuleMain","rsdwClient","wakuMinimalClient","unstable_modules","htmlHead","dynamicHtmlPaths","find","pathSpec","defaultHtmlHead","transformIndexHtml","utils","elements","unstable_onError","html","opts","readable","actionResult","headers","body","pipeThrough","allReady","input","res","default","handleRequest","e","forEach","info","status","message","String","location","ReadableStream","Object","assign"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/middleware/handler.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { resolveConfigDev } from '../config.js';\nimport type { ConfigPrd } from '../config.js';\nimport {\n INTERNAL_setAllEnv,\n INTERNAL_setPlatformDataLoader,\n} from '../../server.js';\nimport type { HandleRequest, HandlerRes } from '../types.js';\nimport type { Middleware, HandlerContext } from './types.js';\nimport { renderRsc, decodeBody, decodePostAction } from '../renderers/rsc.js';\nimport { renderHtml } from '../renderers/html.js';\nimport { decodeRscPath, decodeFuncId } from '../renderers/utils.js';\nimport { filePathToFileURL, getPathMapping } from '../utils/path.js';\nimport { getErrorInfo } from '../utils/custom-errors.js';\nimport { stringToStream } from '../utils/stream.js';\n\nexport const SERVER_MODULE_MAP = {\n 'rsdw-server': 'react-server-dom-webpack/server.edge',\n} as const;\nexport const CLIENT_MODULE_MAP = {\n 'rd-server': 'react-dom/server.edge',\n 'rsdw-client': 'react-server-dom-webpack/client.edge',\n 'waku-minimal-client': 'waku/minimal/client',\n} as const;\nexport const CLIENT_PREFIX = 'client/';\n\nconst getInput = async (\n config: ConfigPrd,\n ctx: HandlerContext,\n loadServerModule: (fileId: string) => Promise<unknown>,\n): Promise<Parameters<HandleRequest>[0] | null> => {\n if (!ctx.req.url.pathname.startsWith(config.basePath)) {\n return null;\n }\n const basePrefix = config.basePath + config.rscBase + '/';\n if (ctx.req.url.pathname.startsWith(basePrefix)) {\n const rscPath = decodeRscPath(\n decodeURI(ctx.req.url.pathname.slice(basePrefix.length)),\n );\n const decodedBody = await decodeBody(ctx);\n const funcId = decodeFuncId(rscPath);\n if (funcId) {\n const args = Array.isArray(decodedBody)\n ? decodedBody\n : decodedBody instanceof URLSearchParams\n ? [decodedBody]\n : [];\n const [fileId, name] = funcId.split('#') as [string, string];\n const mod: any = await loadServerModule(fileId);\n return { type: 'function', fn: mod[name], args, req: ctx.req };\n }\n return { type: 'component', rscPath, rscParams: decodedBody, req: ctx.req };\n }\n if (ctx.req.method === 'POST') {\n const postAction = await decodePostAction(ctx);\n if (postAction) {\n return {\n type: 'action',\n fn: postAction,\n pathname:\n '/' + decodeURI(ctx.req.url.pathname.slice(config.basePath.length)),\n req: ctx.req,\n };\n }\n }\n return {\n type: 'custom',\n pathname:\n '/' + decodeURI(ctx.req.url.pathname.slice(config.basePath.length)),\n req: ctx.req,\n };\n};\n\nexport const handler: Middleware = (options) => {\n const env = options.env;\n INTERNAL_setAllEnv(env);\n const entriesPrdPromise =\n options.cmd === 'start' ? options.loadEntries() : null;\n entriesPrdPromise\n ?.then((entries) => {\n if (entries.loadPlatformData) {\n INTERNAL_setPlatformDataLoader(entries.loadPlatformData);\n }\n })\n .catch(() => {});\n const configDevPromise =\n options.cmd === 'dev' ? resolveConfigDev(options.config) : null;\n\n return async (ctx, next) => {\n const { unstable_devServer: devServer } = ctx;\n const entriesPrd = await entriesPrdPromise!;\n const config = devServer ? await configDevPromise! : entriesPrd.configPrd;\n const entries = devServer\n ? await devServer.loadEntriesDev(await configDevPromise!)\n : entriesPrd;\n const rsdwServer = devServer\n ? await devServer.loadServerModuleRsc(SERVER_MODULE_MAP['rsdw-server'])\n : await entriesPrd.loadModule('rsdw-server');\n const rdServer = devServer\n ? await devServer.loadServerModuleMain(CLIENT_MODULE_MAP['rd-server'])\n : await entriesPrd.loadModule(CLIENT_PREFIX + 'rd-server');\n const rsdwClient = devServer\n ? await devServer.loadServerModuleMain(CLIENT_MODULE_MAP['rsdw-client'])\n : await entriesPrd.loadModule(CLIENT_PREFIX + 'rsdw-client');\n const wakuMinimalClient = devServer\n ? await devServer.loadServerModuleMain(\n CLIENT_MODULE_MAP['waku-minimal-client'],\n )\n : await entriesPrd.loadModule(CLIENT_PREFIX + 'waku-minimal-client');\n ctx.unstable_modules = {\n rsdwServer,\n rdServer,\n rsdwClient,\n wakuMinimalClient,\n };\n const loadServerModule = (fileId: string) => {\n if (devServer) {\n return devServer.loadServerModuleRsc(filePathToFileURL(fileId));\n } else {\n return entriesPrd.loadModule(fileId + '.js');\n }\n };\n const htmlHead = devServer\n ? ''\n : entriesPrd.dynamicHtmlPaths.find(([pathSpec]) =>\n getPathMapping(pathSpec, ctx.req.url.pathname),\n )?.[1] || entriesPrd.defaultHtmlHead;\n const transformIndexHtml =\n devServer && (await devServer.transformIndexHtml(ctx.req.url.pathname));\n const utils = {\n renderRsc: (elements: Record<string, unknown>) =>\n renderRsc(config, ctx, elements, options.unstable_onError),\n renderHtml: async (\n elements: Record<string, unknown>,\n html: ReactNode,\n opts: { rscPath: string; actionResult?: unknown },\n ) => {\n const readable = await renderHtml(\n config,\n ctx,\n htmlHead,\n elements,\n options.unstable_onError,\n html,\n opts.rscPath,\n opts.actionResult,\n );\n const headers = { 'content-type': 'text/html; charset=utf-8' };\n let body = readable;\n if (transformIndexHtml) {\n body = readable.pipeThrough(transformIndexHtml) as never;\n body.allReady = readable.allReady;\n }\n return { body, headers };\n },\n };\n const input = await getInput(config, ctx, loadServerModule);\n if (input) {\n let res: ReadableStream | HandlerRes | 'fallback' | null | undefined;\n try {\n res = await entries.default.handleRequest(input, utils);\n } catch (e) {\n options.unstable_onError.forEach((fn) => fn(e, ctx, 'handler'));\n const info = getErrorInfo(e);\n if (info?.status !== 404) {\n ctx.res.status = info?.status || 500;\n ctx.res.body = stringToStream(\n (e as { message?: string } | undefined)?.message || String(e),\n );\n if (info?.location) {\n (ctx.res.headers ||= {}).location = info.location;\n }\n }\n }\n if (res === 'fallback') {\n const newUrl = new URL(config.basePath, ctx.req.url);\n ctx.req.url.pathname = newUrl.pathname;\n } else if (res instanceof ReadableStream) {\n ctx.res.body = res;\n } else if (res) {\n if (res.body) {\n ctx.res.body = res.body;\n }\n if (res.status) {\n ctx.res.status = res.status;\n }\n if (res.headers) {\n Object.assign((ctx.res.headers ||= {}), res.headers);\n }\n }\n if (ctx.res.body || ctx.res.status) {\n return;\n }\n }\n\n await next();\n };\n};\n"],"names":["resolveConfigDev","INTERNAL_setAllEnv","INTERNAL_setPlatformDataLoader","renderRsc","decodeBody","decodePostAction","renderHtml","decodeRscPath","decodeFuncId","filePathToFileURL","getPathMapping","getErrorInfo","stringToStream","SERVER_MODULE_MAP","CLIENT_MODULE_MAP","CLIENT_PREFIX","getInput","config","ctx","loadServerModule","req","url","pathname","startsWith","basePath","basePrefix","rscBase","rscPath","decodeURI","slice","length","decodedBody","funcId","args","Array","isArray","URLSearchParams","fileId","name","split","mod","type","fn","rscParams","method","postAction","handler","options","env","entriesPrdPromise","cmd","loadEntries","then","entries","loadPlatformData","catch","configDevPromise","next","unstable_devServer","devServer","entriesPrd","configPrd","loadEntriesDev","rsdwServer","loadServerModuleRsc","loadModule","rdServer","loadServerModuleMain","rsdwClient","wakuMinimalClient","unstable_modules","htmlHead","dynamicHtmlPaths","find","pathSpec","defaultHtmlHead","transformIndexHtml","utils","elements","unstable_onError","html","opts","readable","actionResult","headers","body","pipeThrough","allReady","input","res","default","handleRequest","e","forEach","info","status","message","String","location","newUrl","URL","ReadableStream","Object","assign"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/plugins/vite-plugin-rsc-env.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport * as dotenv from 'dotenv';\n\nexport function rscEnvPlugin({\n isDev,\n env,\n config,\n}: {\n isDev: boolean;\n env: Record<string, string>;\n config?: {\n basePath: string;\n rscBase: string;\n };\n}): Plugin {\n return {\n name: 'rsc-env-plugin',\n config(viteConfig) {\n if (isDev) {\n dotenv.config({\n path: ['.env.local', '.env'],\n processEnv: env,\n override: true,\n });\n }\n\n viteConfig.define = {\n ...viteConfig.define,\n ...Object.fromEntries([\n ...(config\n ? [\n [\n 'import.meta.env.WAKU_CONFIG_BASE_PATH',\n JSON.stringify(config.basePath),\n ],\n [\n 'import.meta.env.WAKU_CONFIG_RSC_BASE',\n JSON.stringify(config.rscBase),\n ],\n ]\n : []),\n ...Object.entries(env).flatMap(([k, v]) =>\n k.startsWith('WAKU_PUBLIC_')\n ? [[`import.meta.env.${k}`, JSON.stringify(v)]]\n : [],\n ),\n // Node style `process.env` for traditional compatibility\n ...Object.entries(env).flatMap(([k, v]) =>\n k.startsWith('WAKU_PUBLIC_')\n ? [[`process.env.${k}`, JSON.stringify(v)]]\n : [],\n ),\n ]),\n };\n },\n };\n}\n"],"names":["dotenv","rscEnvPlugin","isDev","env","config","name","viteConfig","path","processEnv","override","define","Object","fromEntries","JSON","stringify","basePath","rscBase","entries","flatMap","k","v","startsWith"],"mappings":"AACA,YAAYA,YAAY,SAAS;AAEjC,OAAO,SAASC,aAAa,EAC3BC,KAAK,EACLC,GAAG,EACHC,MAAM,EAQP;IACC,OAAO;QACLC,MAAM;QACND,QAAOE,UAAU;YACf,IAAIJ,OAAO;gBACTF,OAAOI,MAAM,CAAC;oBACZG,MAAM;wBAAC;wBAAc;qBAAO;oBAC5BC,YAAYL;oBACZM,UAAU;
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/plugins/vite-plugin-rsc-env.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport * as dotenv from 'dotenv';\n\nexport function rscEnvPlugin({\n isDev,\n env,\n config,\n}: {\n isDev: boolean;\n env: Record<string, string>;\n config?: {\n basePath: string;\n rscBase: string;\n };\n}): Plugin {\n return {\n name: 'rsc-env-plugin',\n config(viteConfig) {\n if (isDev) {\n dotenv.config({\n path: ['.env.local', '.env'],\n processEnv: env,\n override: true,\n quiet: true,\n });\n }\n\n viteConfig.define = {\n ...viteConfig.define,\n ...Object.fromEntries([\n ...(config\n ? [\n [\n 'import.meta.env.WAKU_CONFIG_BASE_PATH',\n JSON.stringify(config.basePath),\n ],\n [\n 'import.meta.env.WAKU_CONFIG_RSC_BASE',\n JSON.stringify(config.rscBase),\n ],\n ]\n : []),\n ...Object.entries(env).flatMap(([k, v]) =>\n k.startsWith('WAKU_PUBLIC_')\n ? [[`import.meta.env.${k}`, JSON.stringify(v)]]\n : [],\n ),\n // Node style `process.env` for traditional compatibility\n ...Object.entries(env).flatMap(([k, v]) =>\n k.startsWith('WAKU_PUBLIC_')\n ? [[`process.env.${k}`, JSON.stringify(v)]]\n : [],\n ),\n ]),\n };\n },\n };\n}\n"],"names":["dotenv","rscEnvPlugin","isDev","env","config","name","viteConfig","path","processEnv","override","quiet","define","Object","fromEntries","JSON","stringify","basePath","rscBase","entries","flatMap","k","v","startsWith"],"mappings":"AACA,YAAYA,YAAY,SAAS;AAEjC,OAAO,SAASC,aAAa,EAC3BC,KAAK,EACLC,GAAG,EACHC,MAAM,EAQP;IACC,OAAO;QACLC,MAAM;QACND,QAAOE,UAAU;YACf,IAAIJ,OAAO;gBACTF,OAAOI,MAAM,CAAC;oBACZG,MAAM;wBAAC;wBAAc;qBAAO;oBAC5BC,YAAYL;oBACZM,UAAU;oBACVC,OAAO;gBACT;YACF;YAEAJ,WAAWK,MAAM,GAAG;gBAClB,GAAGL,WAAWK,MAAM;gBACpB,GAAGC,OAAOC,WAAW,CAAC;uBAChBT,SACA;wBACE;4BACE;4BACAU,KAAKC,SAAS,CAACX,OAAOY,QAAQ;yBAC/B;wBACD;4BACE;4BACAF,KAAKC,SAAS,CAACX,OAAOa,OAAO;yBAC9B;qBACF,GACD,EAAE;uBACHL,OAAOM,OAAO,CAACf,KAAKgB,OAAO,CAAC,CAAC,CAACC,GAAGC,EAAE,GACpCD,EAAEE,UAAU,CAAC,kBACT;4BAAC;gCAAC,CAAC,gBAAgB,EAAEF,GAAG;gCAAEN,KAAKC,SAAS,CAACM;6BAAG;yBAAC,GAC7C,EAAE;oBAER,yDAAyD;uBACtDT,OAAOM,OAAO,CAACf,KAAKgB,OAAO,CAAC,CAAC,CAACC,GAAGC,EAAE,GACpCD,EAAEE,UAAU,CAAC,kBACT;4BAAC;gCAAC,CAAC,YAAY,EAAEF,GAAG;gCAAEN,KAAKC,SAAS,CAACM;6BAAG;yBAAC,GACzC,EAAE;iBAET,CAAC;YACJ;QACF;IACF;AACF"}
|
|
@@ -126,7 +126,7 @@ export async function renderHtml(config, ctx, htmlHead, elements, onError, html,
|
|
|
126
126
|
try {
|
|
127
127
|
const readable = await renderToReadableStream(createElement(INTERNAL_ServerRoot, {
|
|
128
128
|
elementsPromise
|
|
129
|
-
}, ...headElements
|
|
129
|
+
}, htmlNode, ...headElements), {
|
|
130
130
|
bootstrapScriptContent: headCode,
|
|
131
131
|
bootstrapModules: headModules,
|
|
132
132
|
formState: actionResult === undefined ? null : await getExtractFormState(ctx)(actionResult),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/renderers/html.ts"],"sourcesContent":["import { createElement } from 'react';\nimport type {\n ReactElement,\n ReactNode,\n FunctionComponent,\n ComponentProps,\n} from 'react';\nimport type * as RDServerType from 'react-dom/server.edge';\nimport type { default as RSDWClientType } from 'react-server-dom-webpack/client.edge';\nimport { injectRSCPayload } from 'rsc-html-stream/server';\n\nimport type * as WakuMinimalClientType from '../../minimal/client.js';\nimport type { ConfigDev, ConfigPrd } from '../config.js';\nimport { SRC_CLIENT_ENTRY } from '../builder/constants.js';\nimport { filePathToFileURL } from '../utils/path.js';\nimport { parseHtml } from '../utils/html-parser.js';\nimport { renderRsc, renderRscElement, getExtractFormState } from './rsc.js';\nimport type { HandlerContext, ErrorCallback } from '../middleware/types.js';\n\ntype Elements = Record<string, unknown>;\n\n// This is exported for vite-rsc. https://github.com/wakujs/waku/pull/1493\nexport const fakeFetchCode = `\nPromise.resolve(new Response(new ReadableStream({\n start(c) {\n const d = (self.__FLIGHT_DATA ||= []);\n const t = new TextEncoder();\n const f = (s) => c.enqueue(typeof s === 'string' ? t.encode(s) : s);\n d.forEach(f);\n d.push = f;\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => c.close());\n } else {\n c.close();\n }\n }\n})))\n`\n .split('\\n')\n .map((line) => line.trim())\n .join('');\n\n// TODO(daishi) I think we should be able to remove `parseHtml` completely,\n// by changing the string based `htmlHead`. Will be BREAKING CHANGE.\nconst parseHtmlHead = (\n rscPathForFakeFetch: string,\n htmlHead: string,\n mainJsPath: string, // for DEV only, pass `''` for PRD\n) => {\n htmlHead = htmlHead.replace(\n // HACK This is brittle\n /\\nglobalThis\\.__WAKU_PREFETCHED__ = {\\n.*?\\n};/s,\n '',\n );\n let headCode = `\nglobalThis.__WAKU_HYDRATE__ = true;\n`;\n headCode += `globalThis.__WAKU_PREFETCHED__ = {\n '${rscPathForFakeFetch}': ${fakeFetchCode},\n};\n`;\n const arr = parseHtml(htmlHead) as ReactElement<any>[];\n const headModules: string[] = [];\n const headElements: ReactElement[] = [];\n for (const item of arr) {\n if (item.type === 'script') {\n if (item.props?.src) {\n headModules.push(item.props.src);\n continue;\n } else if (typeof item.props?.children === 'string') {\n headCode += item.props.children;\n continue;\n } else if (\n typeof item.props?.dangerouslySetInnerHTML?.__html === 'string' &&\n !item.props?.dangerouslySetInnerHTML?.__html.includes(\n '__WAKU_CLIENT_IMPORT__',\n )\n ) {\n headCode += item.props.dangerouslySetInnerHTML.__html;\n continue;\n }\n }\n headElements.push(item);\n }\n if (mainJsPath) {\n headModules.push(mainJsPath);\n }\n return { headCode, headModules, headElements };\n};\n\n// FIXME Why does it error on the first and second time?\nlet hackToIgnoreFirstTwoErrors = 2;\n\nexport async function renderHtml(\n config: ConfigDev | ConfigPrd,\n ctx: Pick<HandlerContext, 'unstable_modules' | 'unstable_devServer'>,\n htmlHead: string,\n elements: Elements,\n onError: Set<ErrorCallback>,\n html: ReactNode,\n rscPath: string,\n actionResult?: unknown,\n): Promise<ReadableStream & { allReady: Promise<void> }> {\n const modules = ctx.unstable_modules;\n if (!modules) {\n throw new Error('handler middleware required (missing modules)');\n }\n const {\n default: { renderToReadableStream },\n } = modules.rdServer as { default: typeof RDServerType };\n const {\n default: { createFromReadableStream },\n } = modules.rsdwClient as { default: typeof RSDWClientType };\n const { INTERNAL_ServerRoot } =\n modules.wakuMinimalClient as typeof WakuMinimalClientType;\n\n const stream = await renderRsc(config, ctx, elements, onError);\n const htmlStream = renderRscElement(config, ctx, html, onError);\n const isDev = !!ctx.unstable_devServer;\n const moduleMap = new Proxy(\n {} as Record<string, Record<string, ImportManifestEntry>>,\n {\n get(_target, filePath: string) {\n return new Proxy(\n {},\n {\n get(_target, name: string) {\n if (isDev) {\n let id = filePath.slice(config.basePath.length);\n if (id.startsWith('@id/')) {\n id = id.slice('@id/'.length);\n } else if (id.startsWith('@fs/')) {\n id = filePathToFileURL(id.slice('@fs'.length));\n } else {\n id = filePathToFileURL(id);\n }\n (globalThis as any).__WAKU_CLIENT_CHUNK_LOAD__(id);\n return { id, chunks: [id], name };\n }\n // !isDev\n const id = filePath.slice(config.basePath.length);\n (globalThis as any).__WAKU_CLIENT_CHUNK_LOAD__(id);\n return { id, chunks: [id], name };\n },\n },\n );\n },\n },\n );\n const [stream1, stream2] = stream.tee();\n const elementsPromise: Promise<Elements> = createFromReadableStream(stream1, {\n serverConsumerManifest: { moduleMap, moduleLoading: null },\n });\n const htmlNode: Promise<ReactNode> = createFromReadableStream(htmlStream, {\n serverConsumerManifest: { moduleMap, moduleLoading: null },\n });\n const { headCode, headModules, headElements } = parseHtmlHead(\n rscPath,\n htmlHead,\n isDev\n ? `${config.basePath}${(config as ConfigDev).srcDir}/${SRC_CLIENT_ENTRY}`\n : '',\n );\n try {\n const readable = await renderToReadableStream(\n createElement(\n INTERNAL_ServerRoot as FunctionComponent<\n Omit<ComponentProps<typeof INTERNAL_ServerRoot>, 'children'>\n >,\n { elementsPromise },\n ...headElements,\n htmlNode as any,\n ),\n {\n bootstrapScriptContent: headCode,\n bootstrapModules: headModules,\n formState:\n actionResult === undefined\n ? null\n : await getExtractFormState(ctx)(actionResult),\n onError(err) {\n if (hackToIgnoreFirstTwoErrors) {\n return;\n }\n console.error(err);\n onError.forEach((fn) => fn(err, ctx as HandlerContext, 'html'));\n if (typeof (err as any)?.digest === 'string') {\n return (err as { digest: string }).digest;\n }\n },\n },\n );\n const injected: ReadableStream & { allReady?: Promise<void> } =\n readable.pipeThrough(injectRSCPayload(stream2));\n injected.allReady = readable.allReady;\n return injected as never;\n } catch (e) {\n if (hackToIgnoreFirstTwoErrors) {\n hackToIgnoreFirstTwoErrors--;\n return renderHtml(\n config,\n ctx,\n htmlHead,\n elements,\n onError,\n html,\n rscPath,\n actionResult,\n );\n }\n throw e;\n }\n}\n"],"names":["createElement","injectRSCPayload","SRC_CLIENT_ENTRY","filePathToFileURL","parseHtml","renderRsc","renderRscElement","getExtractFormState","fakeFetchCode","split","map","line","trim","join","parseHtmlHead","rscPathForFakeFetch","htmlHead","mainJsPath","replace","headCode","arr","headModules","headElements","item","type","props","src","push","children","dangerouslySetInnerHTML","__html","includes","hackToIgnoreFirstTwoErrors","renderHtml","config","ctx","elements","onError","html","rscPath","actionResult","modules","unstable_modules","Error","default","renderToReadableStream","rdServer","createFromReadableStream","rsdwClient","INTERNAL_ServerRoot","wakuMinimalClient","stream","htmlStream","isDev","unstable_devServer","moduleMap","Proxy","get","_target","filePath","name","id","slice","basePath","length","startsWith","globalThis","__WAKU_CLIENT_CHUNK_LOAD__","chunks","stream1","stream2","tee","elementsPromise","serverConsumerManifest","moduleLoading","htmlNode","srcDir","readable","bootstrapScriptContent","bootstrapModules","formState","undefined","err","console","error","forEach","fn","digest","injected","pipeThrough","allReady","e"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/renderers/html.ts"],"sourcesContent":["import { createElement } from 'react';\nimport type {\n ReactElement,\n ReactNode,\n FunctionComponent,\n ComponentProps,\n} from 'react';\nimport type * as RDServerType from 'react-dom/server.edge';\nimport type { default as RSDWClientType } from 'react-server-dom-webpack/client.edge';\nimport { injectRSCPayload } from 'rsc-html-stream/server';\n\nimport type * as WakuMinimalClientType from '../../minimal/client.js';\nimport type { ConfigDev, ConfigPrd } from '../config.js';\nimport { SRC_CLIENT_ENTRY } from '../builder/constants.js';\nimport { filePathToFileURL } from '../utils/path.js';\nimport { parseHtml } from '../utils/html-parser.js';\nimport { renderRsc, renderRscElement, getExtractFormState } from './rsc.js';\nimport type { HandlerContext, ErrorCallback } from '../middleware/types.js';\n\ntype Elements = Record<string, unknown>;\n\n// This is exported for vite-rsc. https://github.com/wakujs/waku/pull/1493\nexport const fakeFetchCode = `\nPromise.resolve(new Response(new ReadableStream({\n start(c) {\n const d = (self.__FLIGHT_DATA ||= []);\n const t = new TextEncoder();\n const f = (s) => c.enqueue(typeof s === 'string' ? t.encode(s) : s);\n d.forEach(f);\n d.push = f;\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => c.close());\n } else {\n c.close();\n }\n }\n})))\n`\n .split('\\n')\n .map((line) => line.trim())\n .join('');\n\n// TODO(daishi) I think we should be able to remove `parseHtml` completely,\n// by changing the string based `htmlHead`. Will be BREAKING CHANGE.\nconst parseHtmlHead = (\n rscPathForFakeFetch: string,\n htmlHead: string,\n mainJsPath: string, // for DEV only, pass `''` for PRD\n) => {\n htmlHead = htmlHead.replace(\n // HACK This is brittle\n /\\nglobalThis\\.__WAKU_PREFETCHED__ = {\\n.*?\\n};/s,\n '',\n );\n let headCode = `\nglobalThis.__WAKU_HYDRATE__ = true;\n`;\n headCode += `globalThis.__WAKU_PREFETCHED__ = {\n '${rscPathForFakeFetch}': ${fakeFetchCode},\n};\n`;\n const arr = parseHtml(htmlHead) as ReactElement<any>[];\n const headModules: string[] = [];\n const headElements: ReactElement[] = [];\n for (const item of arr) {\n if (item.type === 'script') {\n if (item.props?.src) {\n headModules.push(item.props.src);\n continue;\n } else if (typeof item.props?.children === 'string') {\n headCode += item.props.children;\n continue;\n } else if (\n typeof item.props?.dangerouslySetInnerHTML?.__html === 'string' &&\n !item.props?.dangerouslySetInnerHTML?.__html.includes(\n '__WAKU_CLIENT_IMPORT__',\n )\n ) {\n headCode += item.props.dangerouslySetInnerHTML.__html;\n continue;\n }\n }\n headElements.push(item);\n }\n if (mainJsPath) {\n headModules.push(mainJsPath);\n }\n return { headCode, headModules, headElements };\n};\n\n// FIXME Why does it error on the first and second time?\nlet hackToIgnoreFirstTwoErrors = 2;\n\nexport async function renderHtml(\n config: ConfigDev | ConfigPrd,\n ctx: Pick<HandlerContext, 'unstable_modules' | 'unstable_devServer'>,\n htmlHead: string,\n elements: Elements,\n onError: Set<ErrorCallback>,\n html: ReactNode,\n rscPath: string,\n actionResult?: unknown,\n): Promise<ReadableStream & { allReady: Promise<void> }> {\n const modules = ctx.unstable_modules;\n if (!modules) {\n throw new Error('handler middleware required (missing modules)');\n }\n const {\n default: { renderToReadableStream },\n } = modules.rdServer as { default: typeof RDServerType };\n const {\n default: { createFromReadableStream },\n } = modules.rsdwClient as { default: typeof RSDWClientType };\n const { INTERNAL_ServerRoot } =\n modules.wakuMinimalClient as typeof WakuMinimalClientType;\n\n const stream = await renderRsc(config, ctx, elements, onError);\n const htmlStream = renderRscElement(config, ctx, html, onError);\n const isDev = !!ctx.unstable_devServer;\n const moduleMap = new Proxy(\n {} as Record<string, Record<string, ImportManifestEntry>>,\n {\n get(_target, filePath: string) {\n return new Proxy(\n {},\n {\n get(_target, name: string) {\n if (isDev) {\n let id = filePath.slice(config.basePath.length);\n if (id.startsWith('@id/')) {\n id = id.slice('@id/'.length);\n } else if (id.startsWith('@fs/')) {\n id = filePathToFileURL(id.slice('@fs'.length));\n } else {\n id = filePathToFileURL(id);\n }\n (globalThis as any).__WAKU_CLIENT_CHUNK_LOAD__(id);\n return { id, chunks: [id], name };\n }\n // !isDev\n const id = filePath.slice(config.basePath.length);\n (globalThis as any).__WAKU_CLIENT_CHUNK_LOAD__(id);\n return { id, chunks: [id], name };\n },\n },\n );\n },\n },\n );\n const [stream1, stream2] = stream.tee();\n const elementsPromise: Promise<Elements> = createFromReadableStream(stream1, {\n serverConsumerManifest: { moduleMap, moduleLoading: null },\n });\n const htmlNode: Promise<ReactNode> = createFromReadableStream(htmlStream, {\n serverConsumerManifest: { moduleMap, moduleLoading: null },\n });\n const { headCode, headModules, headElements } = parseHtmlHead(\n rscPath,\n htmlHead,\n isDev\n ? `${config.basePath}${(config as ConfigDev).srcDir}/${SRC_CLIENT_ENTRY}`\n : '',\n );\n try {\n const readable = await renderToReadableStream(\n createElement(\n INTERNAL_ServerRoot as FunctionComponent<\n Omit<ComponentProps<typeof INTERNAL_ServerRoot>, 'children'>\n >,\n { elementsPromise },\n htmlNode as any,\n ...headElements,\n ),\n {\n bootstrapScriptContent: headCode,\n bootstrapModules: headModules,\n formState:\n actionResult === undefined\n ? null\n : await getExtractFormState(ctx)(actionResult),\n onError(err) {\n if (hackToIgnoreFirstTwoErrors) {\n return;\n }\n console.error(err);\n onError.forEach((fn) => fn(err, ctx as HandlerContext, 'html'));\n if (typeof (err as any)?.digest === 'string') {\n return (err as { digest: string }).digest;\n }\n },\n },\n );\n const injected: ReadableStream & { allReady?: Promise<void> } =\n readable.pipeThrough(injectRSCPayload(stream2));\n injected.allReady = readable.allReady;\n return injected as never;\n } catch (e) {\n if (hackToIgnoreFirstTwoErrors) {\n hackToIgnoreFirstTwoErrors--;\n return renderHtml(\n config,\n ctx,\n htmlHead,\n elements,\n onError,\n html,\n rscPath,\n actionResult,\n );\n }\n throw e;\n }\n}\n"],"names":["createElement","injectRSCPayload","SRC_CLIENT_ENTRY","filePathToFileURL","parseHtml","renderRsc","renderRscElement","getExtractFormState","fakeFetchCode","split","map","line","trim","join","parseHtmlHead","rscPathForFakeFetch","htmlHead","mainJsPath","replace","headCode","arr","headModules","headElements","item","type","props","src","push","children","dangerouslySetInnerHTML","__html","includes","hackToIgnoreFirstTwoErrors","renderHtml","config","ctx","elements","onError","html","rscPath","actionResult","modules","unstable_modules","Error","default","renderToReadableStream","rdServer","createFromReadableStream","rsdwClient","INTERNAL_ServerRoot","wakuMinimalClient","stream","htmlStream","isDev","unstable_devServer","moduleMap","Proxy","get","_target","filePath","name","id","slice","basePath","length","startsWith","globalThis","__WAKU_CLIENT_CHUNK_LOAD__","chunks","stream1","stream2","tee","elementsPromise","serverConsumerManifest","moduleLoading","htmlNode","srcDir","readable","bootstrapScriptContent","bootstrapModules","formState","undefined","err","console","error","forEach","fn","digest","injected","pipeThrough","allReady","e"],"mappings":"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"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export type HandleRequest = (input: ({
|
|
|
33
33
|
}, utils: {
|
|
34
34
|
renderRsc: RenderRsc;
|
|
35
35
|
renderHtml: RenderHtml;
|
|
36
|
-
}) => Promise<ReadableStream | HandlerRes | null | undefined>;
|
|
36
|
+
}) => Promise<ReadableStream | HandlerRes | 'fallback' | null | undefined>;
|
|
37
37
|
type BuildConfig = {
|
|
38
38
|
type: 'file';
|
|
39
39
|
pathname: string;
|
package/dist/lib/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport type { Middleware } from '../config.js';\nimport type { ConfigPrd } from '../lib/config.js';\nimport type { PathSpec } from '../lib/utils/path.js';\n\ntype Elements = Record<string, unknown>;\n\ntype RenderRsc<Opts = unknown> = (\n elements: Record<string, unknown>,\n options?: Opts,\n) => Promise<ReadableStream>;\n\ntype RenderHtml<Opts = unknown> = (\n elements: Elements,\n html: ReactNode,\n options: { rscPath: string; actionResult?: unknown } & Opts,\n) => Promise<{\n body: ReadableStream & { allReady: Promise<void> };\n headers: Record<'content-type', string>;\n}>;\n\n// This API is still unstable\nexport type HandleRequest = (\n input: (\n | { type: 'component'; rscPath: string; rscParams: unknown }\n | {\n type: 'function';\n fn: (...args: unknown[]) => Promise<unknown>;\n args: unknown[];\n }\n | {\n type: 'action';\n fn: () => Promise<unknown>;\n pathname: string;\n }\n | { type: 'custom'; pathname: string }\n ) & {\n req: HandlerReq;\n },\n utils: {\n renderRsc: RenderRsc;\n renderHtml: RenderHtml;\n },\n) => Promise<ReadableStream | HandlerRes | null | undefined>;\n\n// needs better name (it's not just config)\ntype BuildConfig =\n | {\n type: 'file';\n pathname: string;\n body: Promise<ReadableStream>;\n }\n | {\n type: 'htmlHead';\n pathSpec: PathSpec;\n head?: string;\n }\n | {\n type: 'defaultHtml';\n pathname: string;\n head?: string;\n };\n\n// This API is still unstable\nexport type HandleBuild = (utils: {\n renderRsc: RenderRsc<{ moduleIdCallback?: (id: string) => void }>;\n renderHtml: RenderHtml<{ htmlHead?: string }>;\n rscPath2pathname: (rscPath: string) => string;\n unstable_generatePrefetchCode: (\n rscPaths: Iterable<string>,\n moduleIds: Iterable<string>,\n ) => string;\n unstable_collectClientModules: (elements: Elements) => Promise<string[]>;\n}) => AsyncIterable<BuildConfig> | null;\n\nexport type EntriesDev = {\n default: {\n handleRequest: HandleRequest;\n handleBuild: HandleBuild;\n };\n};\n\nexport type EntriesPrd = EntriesDev & {\n configPrd: ConfigPrd;\n loadMiddleware: () => Promise<{ default: Middleware }[]>;\n loadModule: (id: string) => Promise<unknown>;\n defaultHtmlHead: string;\n dynamicHtmlPaths: [pathSpec: PathSpec, htmlHead: string][];\n publicIndexHtml: string;\n loadPlatformData?: (key: string) => Promise<unknown>;\n};\n\nexport type HandlerReq = {\n body: ReadableStream | null;\n url: URL;\n method: string;\n headers: Readonly<Record<string, string>>;\n};\n\nexport type HandlerRes = {\n body?: ReadableStream;\n headers?: Record<string, string | string[]>;\n status?: number;\n};\n"],"names":[],"mappings":"AAoGA,WAIE"}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport type { Middleware } from '../config.js';\nimport type { ConfigPrd } from '../lib/config.js';\nimport type { PathSpec } from '../lib/utils/path.js';\n\ntype Elements = Record<string, unknown>;\n\ntype RenderRsc<Opts = unknown> = (\n elements: Record<string, unknown>,\n options?: Opts,\n) => Promise<ReadableStream>;\n\ntype RenderHtml<Opts = unknown> = (\n elements: Elements,\n html: ReactNode,\n options: { rscPath: string; actionResult?: unknown } & Opts,\n) => Promise<{\n body: ReadableStream & { allReady: Promise<void> };\n headers: Record<'content-type', string>;\n}>;\n\n// This API is still unstable\nexport type HandleRequest = (\n input: (\n | { type: 'component'; rscPath: string; rscParams: unknown }\n | {\n type: 'function';\n fn: (...args: unknown[]) => Promise<unknown>;\n args: unknown[];\n }\n | {\n type: 'action';\n fn: () => Promise<unknown>;\n pathname: string;\n }\n | { type: 'custom'; pathname: string }\n ) & {\n req: HandlerReq;\n },\n utils: {\n renderRsc: RenderRsc;\n renderHtml: RenderHtml;\n },\n) => Promise<ReadableStream | HandlerRes | 'fallback' | null | undefined>;\n\n// needs better name (it's not just config)\ntype BuildConfig =\n | {\n type: 'file';\n pathname: string;\n body: Promise<ReadableStream>;\n }\n | {\n type: 'htmlHead';\n pathSpec: PathSpec;\n head?: string;\n }\n | {\n type: 'defaultHtml';\n pathname: string;\n head?: string;\n };\n\n// This API is still unstable\nexport type HandleBuild = (utils: {\n renderRsc: RenderRsc<{ moduleIdCallback?: (id: string) => void }>;\n renderHtml: RenderHtml<{ htmlHead?: string }>;\n rscPath2pathname: (rscPath: string) => string;\n unstable_generatePrefetchCode: (\n rscPaths: Iterable<string>,\n moduleIds: Iterable<string>,\n ) => string;\n unstable_collectClientModules: (elements: Elements) => Promise<string[]>;\n}) => AsyncIterable<BuildConfig> | null;\n\nexport type EntriesDev = {\n default: {\n handleRequest: HandleRequest;\n handleBuild: HandleBuild;\n };\n};\n\nexport type EntriesPrd = EntriesDev & {\n configPrd: ConfigPrd;\n loadMiddleware: () => Promise<{ default: Middleware }[]>;\n loadModule: (id: string) => Promise<unknown>;\n defaultHtmlHead: string;\n dynamicHtmlPaths: [pathSpec: PathSpec, htmlHead: string][];\n publicIndexHtml: string;\n loadPlatformData?: (key: string) => Promise<unknown>;\n};\n\nexport type HandlerReq = {\n body: ReadableStream | null;\n url: URL;\n method: string;\n headers: Readonly<Record<string, string>>;\n};\n\nexport type HandlerRes = {\n body?: ReadableStream;\n headers?: Record<string, string | string[]>;\n status?: number;\n};\n"],"names":[],"mappings":"AAoGA,WAIE"}
|
package/dist/router/client.js
CHANGED
|
@@ -297,20 +297,19 @@ const NotFound = ({ has404, reset })=>{
|
|
|
297
297
|
]);
|
|
298
298
|
return has404 ? null : createElement('h1', null, 'Not Found');
|
|
299
299
|
};
|
|
300
|
-
const Redirect = ({ error, to, reset })=>{
|
|
300
|
+
const Redirect = ({ error, to, reset, handledErrorSet })=>{
|
|
301
301
|
const router = useContext(RouterContext);
|
|
302
302
|
if (!router) {
|
|
303
303
|
throw new Error('Missing Router');
|
|
304
304
|
}
|
|
305
305
|
const { changeRoute } = router;
|
|
306
|
-
const handledErrorSet = useRef(new WeakSet());
|
|
307
306
|
useEffect(()=>{
|
|
308
307
|
// ensure single re-fetch per server redirection error on StrictMode
|
|
309
308
|
// https://github.com/wakujs/waku/pull/1512
|
|
310
|
-
if (handledErrorSet.
|
|
309
|
+
if (handledErrorSet.has(error)) {
|
|
311
310
|
return;
|
|
312
311
|
}
|
|
313
|
-
handledErrorSet.
|
|
312
|
+
handledErrorSet.add(error);
|
|
314
313
|
const url = new URL(to, window.location.href);
|
|
315
314
|
// FIXME this condition seems too naive
|
|
316
315
|
if (url.hostname !== window.location.hostname) {
|
|
@@ -340,11 +339,13 @@ const Redirect = ({ error, to, reset })=>{
|
|
|
340
339
|
error,
|
|
341
340
|
to,
|
|
342
341
|
reset,
|
|
343
|
-
changeRoute
|
|
342
|
+
changeRoute,
|
|
343
|
+
handledErrorSet
|
|
344
344
|
]);
|
|
345
345
|
return null;
|
|
346
346
|
};
|
|
347
347
|
class CustomErrorHandler extends Component {
|
|
348
|
+
handledErrorSet = new WeakSet();
|
|
348
349
|
constructor(props){
|
|
349
350
|
super(props);
|
|
350
351
|
this.state = {
|
|
@@ -376,7 +377,8 @@ class CustomErrorHandler extends Component {
|
|
|
376
377
|
return createElement(Redirect, {
|
|
377
378
|
error,
|
|
378
379
|
to: info.location,
|
|
379
|
-
reset: this.reset
|
|
380
|
+
reset: this.reset,
|
|
381
|
+
handledErrorSet: this.handledErrorSet
|
|
380
382
|
});
|
|
381
383
|
}
|
|
382
384
|
throw error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/router/client.ts"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n createElement,\n startTransition,\n use,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n useTransition,\n Fragment,\n Component,\n} from 'react';\nimport type {\n ComponentProps,\n FunctionComponent,\n ReactNode,\n AnchorHTMLAttributes,\n ReactElement,\n MouseEvent,\n TransitionFunction,\n RefObject,\n Ref,\n} from 'react';\n\nimport {\n prefetchRsc,\n Root,\n Slot,\n useElementsPromise_UNSTABLE as useElementsPromise,\n useRefetch,\n useEnhanceFetchRscInternal_UNSTABLE as useEnhanceFetchRscInternal,\n} from '../minimal/client.js';\nimport {\n encodeRoutePath,\n encodeSliceId,\n ROUTE_ID,\n IS_STATIC_ID,\n HAS404_ID,\n SKIP_HEADER,\n} from './common.js';\nimport type { RouteProps } from './common.js';\nimport type { RouteConfig } from './base-types.js';\nimport { getErrorInfo } from '../lib/utils/custom-errors.js';\n\ntype AllowPathDecorators<Path extends string> = Path extends unknown\n ? Path | `${Path}?${string}` | `${Path}#${string}`\n : never;\n\ntype InferredPaths = RouteConfig extends {\n paths: infer UserPaths extends string;\n}\n ? AllowPathDecorators<UserPaths>\n : string;\n\nconst normalizeRoutePath = (path: string) => {\n for (const suffix of ['/', '/index.html']) {\n if (path.endsWith(suffix)) {\n return path.slice(0, -suffix.length) || '/';\n }\n }\n return path;\n};\n\nconst parseRoute = (url: URL): RouteProps => {\n const { pathname, searchParams, hash } = url;\n return {\n path: normalizeRoutePath(pathname),\n query: searchParams.toString(),\n hash,\n };\n};\n\nconst parseRouteFromLocation = (): RouteProps => {\n const httpStatusMeta = document.querySelector('meta[name=\"httpstatus\"]');\n if (\n httpStatusMeta &&\n 'content' in httpStatusMeta &&\n httpStatusMeta.content === '404'\n ) {\n return { path: '/404', query: '', hash: '' };\n }\n return parseRoute(new URL(window.location.href));\n};\n\nconst isAltClick = (event: MouseEvent<HTMLAnchorElement>) =>\n event.button !== 0 ||\n !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);\n\nlet savedRscParams: [query: string, rscParams: URLSearchParams] | undefined;\n\nconst createRscParams = (query: string): URLSearchParams => {\n if (savedRscParams && savedRscParams[0] === query) {\n return savedRscParams[1];\n }\n const rscParams = new URLSearchParams({ query });\n savedRscParams = [query, rscParams];\n return rscParams;\n};\n\ntype ChangeRoute = (\n route: RouteProps,\n options: {\n shouldScroll: boolean;\n skipRefetch?: boolean;\n unstable_startTransition?: ((fn: TransitionFunction) => void) | undefined;\n },\n) => Promise<void>;\n\ntype ChangeRouteEvent = 'start' | 'complete';\n\ntype ChangeRouteCallback = (route: RouteProps) => void;\n\ntype PrefetchRoute = (route: RouteProps) => void;\n\ntype SliceId = string;\n\n// This is an internal thing, not a public API\nconst RouterContext = createContext<{\n route: RouteProps;\n changeRoute: ChangeRoute;\n prefetchRoute: PrefetchRoute;\n routeChangeEvents: Record<\n 'on' | 'off',\n (event: ChangeRouteEvent, handler: ChangeRouteCallback) => void\n >;\n fetchingSlices: Set<SliceId>;\n} | null>(null);\n\nexport function useRouter() {\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('Missing Router');\n }\n\n const { route, changeRoute, prefetchRoute } = router;\n const push = useCallback(\n async (\n to: InferredPaths,\n options?: {\n /**\n * indicates if the link should scroll or not on navigation\n * - `true`: always scroll\n * - `false`: never scroll\n * - `undefined`: scroll on path change (not on searchParams change)\n */\n scroll?: boolean;\n },\n ) => {\n const url = new URL(to, window.location.href);\n const currentPath = window.location.pathname;\n const newPath = url.pathname !== currentPath;\n await changeRoute(parseRoute(url), {\n shouldScroll: options?.scroll ?? newPath,\n });\n if (window.location.pathname === currentPath) {\n window.history.pushState(\n {\n ...window.history.state,\n waku_new_path: newPath,\n },\n '',\n url,\n );\n }\n },\n [changeRoute],\n );\n const replace = useCallback(\n async (\n to: InferredPaths,\n options?: {\n /**\n * indicates if the link should scroll or not on navigation\n * - `true`: always scroll\n * - `false`: never scroll\n * - `undefined`: scroll on path change (not on searchParams change)\n */\n scroll?: boolean;\n },\n ) => {\n const url = new URL(to, window.location.href);\n const currentPath = window.location.pathname;\n const newPath = url.pathname !== currentPath;\n await changeRoute(parseRoute(url), {\n shouldScroll: options?.scroll ?? newPath,\n });\n if (window.location.pathname === currentPath) {\n window.history.replaceState(window.history.state, '', url);\n }\n },\n [changeRoute],\n );\n const reload = useCallback(async () => {\n const url = new URL(window.location.href);\n await changeRoute(parseRoute(url), { shouldScroll: true });\n }, [changeRoute]);\n const back = useCallback(() => {\n // FIXME is this correct?\n window.history.back();\n }, []);\n const forward = useCallback(() => {\n // FIXME is this correct?\n window.history.forward();\n }, []);\n const prefetch = useCallback(\n (to: string) => {\n const url = new URL(to, window.location.href);\n prefetchRoute(parseRoute(url));\n },\n [prefetchRoute],\n );\n return {\n ...route,\n push,\n replace,\n reload,\n back,\n forward,\n prefetch,\n unstable_events: router.routeChangeEvents,\n };\n}\n\nfunction useSharedRef<T>(\n ref: Ref<T | null> | undefined,\n): [RefObject<T | null>, (node: T | null) => void | (() => void)] {\n const managedRef = useRef<T>(null);\n\n const handleRef = useCallback(\n (node: T | null): void | (() => void) => {\n managedRef.current = node;\n const isRefCallback = typeof ref === 'function';\n let cleanup: void | (() => void);\n if (isRefCallback) {\n cleanup = ref(node);\n } else if (ref) {\n ref.current = node;\n }\n return () => {\n managedRef.current = null;\n if (isRefCallback) {\n if (cleanup) {\n cleanup();\n } else {\n ref(null);\n }\n } else if (ref) {\n ref.current = null;\n }\n };\n },\n [ref],\n );\n\n return [managedRef, handleRef];\n}\n\nexport type LinkProps = {\n to: InferredPaths;\n children: ReactNode;\n /**\n * indicates if the link should scroll or not on navigation\n * - `true`: always scroll\n * - `false`: never scroll\n * - `undefined`: scroll on path change (not on searchParams change)\n */\n scroll?: boolean;\n unstable_pending?: ReactNode;\n unstable_notPending?: ReactNode;\n unstable_prefetchOnEnter?: boolean;\n unstable_prefetchOnView?: boolean;\n unstable_startTransition?: ((fn: TransitionFunction) => void) | undefined;\n ref?: Ref<HTMLAnchorElement> | undefined;\n} & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>;\n\nexport function Link({\n to,\n children,\n scroll,\n unstable_pending,\n unstable_notPending,\n unstable_prefetchOnEnter,\n unstable_prefetchOnView,\n unstable_startTransition,\n ref: refProp,\n ...props\n}: LinkProps): ReactElement {\n const router = useContext(RouterContext);\n const changeRoute = router\n ? router.changeRoute\n : () => {\n throw new Error('Missing Router');\n };\n const prefetchRoute = router\n ? router.prefetchRoute\n : () => {\n throw new Error('Missing Router');\n };\n const [isPending, startTransition] = useTransition();\n const startTransitionFn =\n unstable_startTransition ||\n ((unstable_pending || unstable_notPending) && startTransition) ||\n ((fn: TransitionFunction) => fn());\n const [ref, setRef] = useSharedRef<HTMLAnchorElement>(refProp);\n\n useEffect(() => {\n if (unstable_prefetchOnView && ref.current) {\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const url = new URL(to, window.location.href);\n if (router && url.href !== window.location.href) {\n const route = parseRoute(url);\n router.prefetchRoute(route);\n }\n }\n });\n },\n { threshold: 0.1 },\n );\n\n observer.observe(ref.current);\n\n return () => {\n observer.disconnect();\n };\n }\n }, [unstable_prefetchOnView, router, to, ref]);\n const internalOnClick = () => {\n const url = new URL(to, window.location.href);\n if (url.href !== window.location.href) {\n const route = parseRoute(url);\n prefetchRoute(route);\n startTransitionFn(async () => {\n const currentPath = window.location.pathname;\n const newPath = url.pathname !== currentPath;\n try {\n await changeRoute(route, {\n shouldScroll: scroll ?? newPath,\n unstable_startTransition: startTransitionFn,\n });\n } finally {\n if (window.location.pathname === currentPath) {\n // Update history if it wasn't already updated\n window.history.pushState(\n {\n ...window.history.state,\n waku_new_path: newPath,\n },\n '',\n url,\n );\n }\n }\n });\n }\n };\n const onClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (props.onClick) {\n props.onClick(event);\n }\n if (!event.defaultPrevented && !isAltClick(event)) {\n event.preventDefault();\n internalOnClick();\n }\n };\n const onMouseEnter = unstable_prefetchOnEnter\n ? (event: MouseEvent<HTMLAnchorElement>) => {\n const url = new URL(to, window.location.href);\n if (url.href !== window.location.href) {\n const route = parseRoute(url);\n prefetchRoute(route);\n }\n props.onMouseEnter?.(event);\n }\n : props.onMouseEnter;\n const ele = createElement(\n 'a',\n { ...props, href: to, onClick, onMouseEnter, ref: setRef },\n children,\n );\n if (isPending && unstable_pending !== undefined) {\n return createElement(Fragment, null, ele, unstable_pending);\n }\n if (!isPending && unstable_notPending !== undefined) {\n return createElement(Fragment, null, ele, unstable_notPending);\n }\n return ele;\n}\n\nconst notAvailableInServer = (name: string) => () => {\n throw new Error(`${name} is not in the server`);\n};\n\nfunction renderError(message: string) {\n return createElement(\n 'html',\n null,\n createElement('body', null, createElement('h1', null, message)),\n );\n}\n\nexport class ErrorBoundary extends Component<\n { children: ReactNode },\n { error?: unknown }\n> {\n constructor(props: { children: ReactNode }) {\n super(props);\n this.state = {};\n }\n static getDerivedStateFromError(error: unknown) {\n return { error };\n }\n render() {\n if ('error' in this.state) {\n if (this.state.error instanceof Error) {\n return renderError(this.state.error.message);\n }\n return renderError(String(this.state.error));\n }\n return this.props.children;\n }\n}\n\nconst NotFound = ({\n has404,\n reset,\n}: {\n has404: boolean;\n reset: () => void;\n}) => {\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('Missing Router');\n }\n const { changeRoute } = router;\n useEffect(() => {\n if (has404) {\n const url = new URL('/404', window.location.href);\n changeRoute(parseRoute(url), { shouldScroll: true })\n .then(() => {\n // HACK: This timeout is required for canary-ci to work\n // FIXME: As we understand it, we should have a proper solution.\n setTimeout(() => {\n reset();\n }, 1);\n })\n .catch((err) => {\n console.log('Error while navigating to 404:', err);\n });\n }\n }, [has404, reset, changeRoute]);\n return has404 ? null : createElement('h1', null, 'Not Found');\n};\n\nconst Redirect = ({\n error,\n to,\n reset,\n}: {\n error: unknown;\n to: string;\n reset: () => void;\n}) => {\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('Missing Router');\n }\n const { changeRoute } = router;\n const handledErrorSet = useRef(new WeakSet());\n useEffect(() => {\n // ensure single re-fetch per server redirection error on StrictMode\n // https://github.com/wakujs/waku/pull/1512\n if (handledErrorSet.current.has(error as object)) {\n return;\n }\n handledErrorSet.current.add(error as object);\n\n const url = new URL(to, window.location.href);\n // FIXME this condition seems too naive\n if (url.hostname !== window.location.hostname) {\n window.location.replace(to);\n return;\n }\n const currentPath = window.location.pathname;\n const newPath = url.pathname !== currentPath;\n changeRoute(parseRoute(url), { shouldScroll: newPath })\n .then(() => {\n // FIXME: As we understand it, we should have a proper solution.\n setTimeout(() => {\n reset();\n }, 1);\n })\n .catch((err) => {\n console.log('Error while navigating to redirect:', err);\n })\n .finally(() => {\n if (window.location.pathname === currentPath) {\n window.history.replaceState(\n {\n ...window.history.state,\n waku_new_path: newPath,\n },\n '',\n url,\n );\n }\n });\n }, [error, to, reset, changeRoute]);\n return null;\n};\n\nclass CustomErrorHandler extends Component<\n { has404: boolean; children?: ReactNode },\n { error: unknown | null }\n> {\n constructor(props: { has404: boolean; children?: ReactNode }) {\n super(props);\n this.state = { error: null };\n this.reset = this.reset.bind(this);\n }\n static getDerivedStateFromError(error: unknown) {\n return { error };\n }\n reset() {\n this.setState({ error: null });\n }\n render() {\n const { error } = this.state;\n if (error !== null) {\n const info = getErrorInfo(error);\n if (info?.status === 404) {\n return createElement(NotFound, {\n has404: this.props.has404,\n reset: this.reset,\n });\n }\n if (info?.location) {\n return createElement(Redirect, {\n error,\n to: info.location,\n reset: this.reset,\n });\n }\n throw error;\n }\n return this.props.children;\n }\n}\n\nconst ThrowError = ({ error }: { error: unknown }) => {\n throw error;\n};\n\nconst getRouteSlotId = (path: string) => 'route:' + decodeURI(path);\nconst getSliceSlotId = (id: SliceId) => 'slice:' + id;\n\nexport function Slice({\n id,\n children,\n ...props\n}: {\n id: SliceId;\n children?: ReactNode;\n} & (\n | {\n delayed?: false;\n }\n | {\n delayed: true;\n fallback: ReactNode;\n }\n)) {\n if (\n typeof window !== 'undefined' &&\n !import.meta.env?.VITE_EXPERIMENTAL_WAKU_ROUTER\n ) {\n throw new Error('Slice is still experimental');\n }\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('Missing Router');\n }\n const { fetchingSlices } = router;\n const refetch = useRefetch();\n const slotId = getSliceSlotId(id);\n const elementsPromise = useElementsPromise();\n const elements = use(elementsPromise);\n const needsToFetchSlice =\n props.delayed &&\n (!(slotId in elements) ||\n // FIXME: hard-coded for now\n elements[IS_STATIC_ID + ':' + slotId] !== true);\n useEffect(() => {\n // FIXME this works because of subtle timing behavior.\n if (needsToFetchSlice && !fetchingSlices.has(id)) {\n fetchingSlices.add(id);\n const rscPath = encodeSliceId(id);\n refetch(rscPath)\n .catch((e) => {\n console.error('Failed to fetch slice:', e);\n })\n .finally(() => {\n fetchingSlices.delete(id);\n });\n }\n }, [fetchingSlices, refetch, id, needsToFetchSlice]);\n if (props.delayed && !(slotId in elements)) {\n // FIXME the fallback doesn't show on refetch after the first one.\n return props.fallback;\n }\n return createElement(Slot, { id: slotId }, children);\n}\n\nconst handleScroll = () => {\n const { hash } = window.location;\n const { state } = window.history;\n const element = hash && document.getElementById(hash.slice(1));\n window.scrollTo({\n left: 0,\n top: element ? element.getBoundingClientRect().top + window.scrollY : 0,\n behavior: state?.waku_new_path ? 'instant' : 'auto',\n });\n};\n\nconst InnerRouter = ({ initialRoute }: { initialRoute: RouteProps }) => {\n const elementsPromise = useElementsPromise();\n const [has404, setHas404] = useState(false);\n const requestedRouteRef = useRef<RouteProps>(initialRoute);\n const staticPathSetRef = useRef(new Set<string>());\n const cachedIdSetRef = useRef(new Set<string>());\n useEffect(() => {\n elementsPromise.then(\n (elements) => {\n const {\n [ROUTE_ID]: routeData,\n [IS_STATIC_ID]: isStatic,\n [HAS404_ID]: has404FromElements,\n ...rest\n } = elements;\n if (has404FromElements) {\n setHas404(true);\n }\n if (routeData) {\n const [path, _query] = routeData as [string, string];\n if (isStatic) {\n staticPathSetRef.current.add(path);\n }\n }\n cachedIdSetRef.current = new Set(Object.keys(rest));\n },\n () => {},\n );\n }, [elementsPromise]);\n\n const enhanceFetchRscInternal = useEnhanceFetchRscInternal();\n const locationListenersRef = useRef(\n new Set<(path: string, query: string) => void>(),\n );\n const locationListeners = locationListenersRef.current;\n useEffect(() => {\n const enhanceFetch =\n (fetchFn: typeof fetch) =>\n (input: RequestInfo | URL, init: RequestInit = {}) => {\n const skipStr = JSON.stringify(Array.from(cachedIdSetRef.current));\n const headers = (init.headers ||= {});\n if (Array.isArray(headers)) {\n headers.push([SKIP_HEADER, skipStr]);\n } else {\n (headers as Record<string, string>)[SKIP_HEADER] = skipStr;\n }\n return fetchFn(input, init);\n };\n return enhanceFetchRscInternal(\n (fetchRscInternal) =>\n (\n rscPath: string,\n rscParams: unknown,\n prefetchOnly,\n fetchFn = fetch,\n ) => {\n const enhancedFetch = enhanceFetch(fetchFn);\n type Elements = Record<string, unknown>;\n const elementsPromise = fetchRscInternal(\n rscPath,\n rscParams,\n prefetchOnly as undefined,\n enhancedFetch,\n ) as Promise<Elements> | undefined;\n Promise.resolve(elementsPromise)\n .then((elements = {}) => {\n const { [ROUTE_ID]: routeData, [IS_STATIC_ID]: isStatic } =\n elements;\n if (routeData) {\n const [path, query] = routeData as [string, string];\n if (\n requestedRouteRef.current.path !== path ||\n (!isStatic && requestedRouteRef.current.query !== query)\n ) {\n locationListeners.forEach((listener) =>\n listener(path, query),\n );\n }\n }\n })\n .catch(() => {});\n return elementsPromise as never;\n },\n );\n }, [enhanceFetchRscInternal, locationListeners]);\n const refetch = useRefetch();\n const [route, setRoute] = useState(() => ({\n // This is the first initialization of the route, and it has\n // to ignore the hash, because on server side there is none.\n // Otherwise there will be a hydration error.\n // The client side route, including the hash, will be updated in the effect below.\n ...initialRoute,\n hash: '',\n }));\n const routeChangeListenersRef =\n useRef<\n [\n Record<\n 'on' | 'off',\n (event: ChangeRouteEvent, handler: ChangeRouteCallback) => void\n >,\n (\n eventType: ChangeRouteEvent,\n eventRoute: Parameters<ChangeRouteCallback>[0],\n ) => void,\n ]\n >(null);\n if (routeChangeListenersRef.current === null) {\n const listeners: Record<ChangeRouteEvent, Set<ChangeRouteCallback>> = {\n start: new Set(),\n complete: new Set(),\n };\n const executeListeners = (\n eventType: ChangeRouteEvent,\n eventRoute: Parameters<ChangeRouteCallback>[0],\n ) => {\n const eventListenersSet = listeners[eventType];\n if (!eventListenersSet.size) {\n return;\n }\n for (const listener of eventListenersSet) {\n listener(eventRoute);\n }\n };\n const events = (() => {\n const on = (event: ChangeRouteEvent, handler: ChangeRouteCallback) => {\n listeners[event].add(handler);\n };\n const off = (event: ChangeRouteEvent, handler: ChangeRouteCallback) => {\n listeners[event].delete(handler);\n };\n return { on, off };\n })();\n\n routeChangeListenersRef.current = [events, executeListeners];\n }\n // Update the route post-load to include the current hash.\n useEffect(() => {\n setRoute((prev) => {\n if (\n prev.path === initialRoute.path &&\n prev.query === initialRoute.query &&\n prev.hash === initialRoute.hash\n ) {\n return prev;\n }\n return initialRoute;\n });\n }, [initialRoute]);\n\n const [routeChangeEvents, executeListeners] = routeChangeListenersRef.current;\n const [err, setErr] = useState<unknown>(null);\n // FIXME this \"refetching\" hack doesn't seem ideal.\n const refetching = useRef<[onFinish?: () => void] | null>(null);\n const changeRoute: ChangeRoute = useCallback(\n async (route, options) => {\n requestedRouteRef.current = route;\n executeListeners('start', route);\n const startTransitionFn =\n options.unstable_startTransition || ((fn: TransitionFunction) => fn());\n refetching.current = [];\n setErr(null);\n const { skipRefetch } = options || {};\n if (!staticPathSetRef.current.has(route.path) && !skipRefetch) {\n const rscPath = encodeRoutePath(route.path);\n const rscParams = createRscParams(route.query);\n try {\n await refetch(rscPath, rscParams);\n } catch (e) {\n refetching.current = null;\n setErr(e);\n throw e;\n }\n }\n startTransitionFn(() => {\n if (options.shouldScroll) {\n handleScroll();\n }\n setRoute(route);\n refetching.current![0]?.();\n refetching.current = null;\n executeListeners('complete', route);\n });\n },\n [executeListeners, refetch],\n );\n\n const prefetchRoute: PrefetchRoute = useCallback((route) => {\n if (staticPathSetRef.current.has(route.path)) {\n return;\n }\n const rscPath = encodeRoutePath(route.path);\n const rscParams = createRscParams(route.query);\n prefetchRsc(rscPath, rscParams);\n (globalThis as any).__WAKU_ROUTER_PREFETCH__?.(route.path);\n }, []);\n\n useEffect(() => {\n const callback = () => {\n const route = parseRoute(new URL(window.location.href));\n changeRoute(route, { shouldScroll: true }).catch((err) => {\n console.log('Error while navigating back:', err);\n });\n };\n window.addEventListener('popstate', callback);\n return () => {\n window.removeEventListener('popstate', callback);\n };\n }, [changeRoute]);\n\n useEffect(() => {\n const callback = (path: string, query: string) => {\n const fn = () => {\n const url = new URL(window.location.href);\n url.pathname = path;\n url.search = query;\n url.hash = '';\n changeRoute(parseRoute(url), {\n skipRefetch: true,\n shouldScroll: false,\n })\n .catch((err) => {\n console.log('Error while handling location listeners:', err);\n })\n .finally(() => {\n if (path !== '/404') {\n window.history.pushState(\n {\n ...window.history.state,\n waku_new_path: url.pathname !== window.location.pathname,\n },\n '',\n url,\n );\n }\n });\n };\n if (refetching.current) {\n refetching.current.push(fn);\n } else {\n startTransition(fn);\n }\n };\n locationListeners.add(callback);\n return () => {\n locationListeners.delete(callback);\n };\n }, [changeRoute, locationListeners]);\n\n const routeElement =\n err !== null\n ? createElement(ThrowError, { error: err })\n : createElement(Slot, { id: getRouteSlotId(route.path) });\n const rootElement = createElement(\n Slot,\n { id: 'root' },\n createElement(CustomErrorHandler, { has404 }, routeElement),\n );\n return createElement(\n RouterContext,\n {\n value: {\n route,\n changeRoute,\n prefetchRoute,\n routeChangeEvents,\n fetchingSlices: useRef(new Set<SliceId>()).current,\n },\n },\n rootElement,\n );\n};\n\nexport function Router({\n initialRoute = parseRouteFromLocation(),\n}: {\n initialRoute?: RouteProps;\n}) {\n const initialRscPath = encodeRoutePath(initialRoute.path);\n const initialRscParams = createRscParams(initialRoute.query);\n return createElement(\n Root as FunctionComponent<Omit<ComponentProps<typeof Root>, 'children'>>,\n {\n initialRscPath,\n initialRscParams,\n },\n createElement(InnerRouter, { initialRoute }),\n );\n}\n\nconst MOCK_ROUTE_CHANGE_LISTENER: Record<\n 'on' | 'off',\n (event: ChangeRouteEvent, handler: ChangeRouteCallback) => void\n> = {\n on: () => notAvailableInServer('routeChange:on'),\n off: () => notAvailableInServer('routeChange:off'),\n};\n\n/**\n * ServerRouter for SSR\n * This is not a public API.\n */\nexport function INTERNAL_ServerRouter({\n route,\n httpstatus,\n}: {\n route: RouteProps;\n httpstatus: number;\n}) {\n const routeElement = createElement(Slot, { id: getRouteSlotId(route.path) });\n const rootElement = createElement(\n Slot,\n { id: 'root' },\n createElement('meta', { name: 'httpstatus', content: `${httpstatus}` }),\n routeElement,\n );\n return createElement(\n Fragment,\n null,\n createElement(\n RouterContext,\n {\n value: {\n route,\n changeRoute: notAvailableInServer('changeRoute'),\n prefetchRoute: notAvailableInServer('prefetchRoute'),\n routeChangeEvents: MOCK_ROUTE_CHANGE_LISTENER,\n fetchingSlices: new Set<SliceId>(),\n },\n },\n rootElement,\n ),\n );\n}\n"],"names":["createContext","createElement","startTransition","use","useCallback","useContext","useEffect","useRef","useState","useTransition","Fragment","Component","prefetchRsc","Root","Slot","useElementsPromise_UNSTABLE","useElementsPromise","useRefetch","useEnhanceFetchRscInternal_UNSTABLE","useEnhanceFetchRscInternal","encodeRoutePath","encodeSliceId","ROUTE_ID","IS_STATIC_ID","HAS404_ID","SKIP_HEADER","getErrorInfo","normalizeRoutePath","path","suffix","endsWith","slice","length","parseRoute","url","pathname","searchParams","hash","query","toString","parseRouteFromLocation","httpStatusMeta","document","querySelector","content","URL","window","location","href","isAltClick","event","button","metaKey","altKey","ctrlKey","shiftKey","savedRscParams","createRscParams","rscParams","URLSearchParams","RouterContext","useRouter","router","Error","route","changeRoute","prefetchRoute","push","to","options","currentPath","newPath","shouldScroll","scroll","history","pushState","state","waku_new_path","replace","replaceState","reload","back","forward","prefetch","unstable_events","routeChangeEvents","useSharedRef","ref","managedRef","handleRef","node","current","isRefCallback","cleanup","Link","children","unstable_pending","unstable_notPending","unstable_prefetchOnEnter","unstable_prefetchOnView","unstable_startTransition","refProp","props","isPending","startTransitionFn","fn","setRef","observer","IntersectionObserver","entries","forEach","entry","isIntersecting","threshold","observe","disconnect","internalOnClick","onClick","defaultPrevented","preventDefault","onMouseEnter","ele","undefined","notAvailableInServer","name","renderError","message","ErrorBoundary","getDerivedStateFromError","error","render","String","NotFound","has404","reset","then","setTimeout","catch","err","console","log","Redirect","handledErrorSet","WeakSet","has","add","hostname","finally","CustomErrorHandler","bind","setState","info","status","ThrowError","getRouteSlotId","decodeURI","getSliceSlotId","id","Slice","env","VITE_EXPERIMENTAL_WAKU_ROUTER","fetchingSlices","refetch","slotId","elementsPromise","elements","needsToFetchSlice","delayed","rscPath","e","delete","fallback","handleScroll","element","getElementById","scrollTo","left","top","getBoundingClientRect","scrollY","behavior","InnerRouter","initialRoute","setHas404","requestedRouteRef","staticPathSetRef","Set","cachedIdSetRef","routeData","isStatic","has404FromElements","rest","_query","Object","keys","enhanceFetchRscInternal","locationListenersRef","locationListeners","enhanceFetch","fetchFn","input","init","skipStr","JSON","stringify","Array","from","headers","isArray","fetchRscInternal","prefetchOnly","fetch","enhancedFetch","Promise","resolve","listener","setRoute","routeChangeListenersRef","listeners","start","complete","executeListeners","eventType","eventRoute","eventListenersSet","size","events","on","handler","off","prev","setErr","refetching","skipRefetch","globalThis","__WAKU_ROUTER_PREFETCH__","callback","addEventListener","removeEventListener","search","routeElement","rootElement","value","Router","initialRscPath","initialRscParams","MOCK_ROUTE_CHANGE_LISTENER","INTERNAL_ServerRouter","httpstatus"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/router/client.ts"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n createElement,\n startTransition,\n use,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n useTransition,\n Fragment,\n Component,\n} from 'react';\nimport type {\n ComponentProps,\n FunctionComponent,\n ReactNode,\n AnchorHTMLAttributes,\n ReactElement,\n MouseEvent,\n TransitionFunction,\n RefObject,\n Ref,\n} from 'react';\n\nimport {\n prefetchRsc,\n Root,\n Slot,\n useElementsPromise_UNSTABLE as useElementsPromise,\n useRefetch,\n useEnhanceFetchRscInternal_UNSTABLE as useEnhanceFetchRscInternal,\n} from '../minimal/client.js';\nimport {\n encodeRoutePath,\n encodeSliceId,\n ROUTE_ID,\n IS_STATIC_ID,\n HAS404_ID,\n SKIP_HEADER,\n} from './common.js';\nimport type { RouteProps } from './common.js';\nimport type { RouteConfig } from './base-types.js';\nimport { getErrorInfo } from '../lib/utils/custom-errors.js';\n\ntype AllowPathDecorators<Path extends string> = Path extends unknown\n ? Path | `${Path}?${string}` | `${Path}#${string}`\n : never;\n\ntype InferredPaths = RouteConfig extends {\n paths: infer UserPaths extends string;\n}\n ? AllowPathDecorators<UserPaths>\n : string;\n\nconst normalizeRoutePath = (path: string) => {\n for (const suffix of ['/', '/index.html']) {\n if (path.endsWith(suffix)) {\n return path.slice(0, -suffix.length) || '/';\n }\n }\n return path;\n};\n\nconst parseRoute = (url: URL): RouteProps => {\n const { pathname, searchParams, hash } = url;\n return {\n path: normalizeRoutePath(pathname),\n query: searchParams.toString(),\n hash,\n };\n};\n\nconst parseRouteFromLocation = (): RouteProps => {\n const httpStatusMeta = document.querySelector('meta[name=\"httpstatus\"]');\n if (\n httpStatusMeta &&\n 'content' in httpStatusMeta &&\n httpStatusMeta.content === '404'\n ) {\n return { path: '/404', query: '', hash: '' };\n }\n return parseRoute(new URL(window.location.href));\n};\n\nconst isAltClick = (event: MouseEvent<HTMLAnchorElement>) =>\n event.button !== 0 ||\n !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);\n\nlet savedRscParams: [query: string, rscParams: URLSearchParams] | undefined;\n\nconst createRscParams = (query: string): URLSearchParams => {\n if (savedRscParams && savedRscParams[0] === query) {\n return savedRscParams[1];\n }\n const rscParams = new URLSearchParams({ query });\n savedRscParams = [query, rscParams];\n return rscParams;\n};\n\ntype ChangeRoute = (\n route: RouteProps,\n options: {\n shouldScroll: boolean;\n skipRefetch?: boolean;\n unstable_startTransition?: ((fn: TransitionFunction) => void) | undefined;\n },\n) => Promise<void>;\n\ntype ChangeRouteEvent = 'start' | 'complete';\n\ntype ChangeRouteCallback = (route: RouteProps) => void;\n\ntype PrefetchRoute = (route: RouteProps) => void;\n\ntype SliceId = string;\n\n// This is an internal thing, not a public API\nconst RouterContext = createContext<{\n route: RouteProps;\n changeRoute: ChangeRoute;\n prefetchRoute: PrefetchRoute;\n routeChangeEvents: Record<\n 'on' | 'off',\n (event: ChangeRouteEvent, handler: ChangeRouteCallback) => void\n >;\n fetchingSlices: Set<SliceId>;\n} | null>(null);\n\nexport function useRouter() {\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('Missing Router');\n }\n\n const { route, changeRoute, prefetchRoute } = router;\n const push = useCallback(\n async (\n to: InferredPaths,\n options?: {\n /**\n * indicates if the link should scroll or not on navigation\n * - `true`: always scroll\n * - `false`: never scroll\n * - `undefined`: scroll on path change (not on searchParams change)\n */\n scroll?: boolean;\n },\n ) => {\n const url = new URL(to, window.location.href);\n const currentPath = window.location.pathname;\n const newPath = url.pathname !== currentPath;\n await changeRoute(parseRoute(url), {\n shouldScroll: options?.scroll ?? newPath,\n });\n if (window.location.pathname === currentPath) {\n window.history.pushState(\n {\n ...window.history.state,\n waku_new_path: newPath,\n },\n '',\n url,\n );\n }\n },\n [changeRoute],\n );\n const replace = useCallback(\n async (\n to: InferredPaths,\n options?: {\n /**\n * indicates if the link should scroll or not on navigation\n * - `true`: always scroll\n * - `false`: never scroll\n * - `undefined`: scroll on path change (not on searchParams change)\n */\n scroll?: boolean;\n },\n ) => {\n const url = new URL(to, window.location.href);\n const currentPath = window.location.pathname;\n const newPath = url.pathname !== currentPath;\n await changeRoute(parseRoute(url), {\n shouldScroll: options?.scroll ?? newPath,\n });\n if (window.location.pathname === currentPath) {\n window.history.replaceState(window.history.state, '', url);\n }\n },\n [changeRoute],\n );\n const reload = useCallback(async () => {\n const url = new URL(window.location.href);\n await changeRoute(parseRoute(url), { shouldScroll: true });\n }, [changeRoute]);\n const back = useCallback(() => {\n // FIXME is this correct?\n window.history.back();\n }, []);\n const forward = useCallback(() => {\n // FIXME is this correct?\n window.history.forward();\n }, []);\n const prefetch = useCallback(\n (to: string) => {\n const url = new URL(to, window.location.href);\n prefetchRoute(parseRoute(url));\n },\n [prefetchRoute],\n );\n return {\n ...route,\n push,\n replace,\n reload,\n back,\n forward,\n prefetch,\n unstable_events: router.routeChangeEvents,\n };\n}\n\nfunction useSharedRef<T>(\n ref: Ref<T | null> | undefined,\n): [RefObject<T | null>, (node: T | null) => void | (() => void)] {\n const managedRef = useRef<T>(null);\n\n const handleRef = useCallback(\n (node: T | null): void | (() => void) => {\n managedRef.current = node;\n const isRefCallback = typeof ref === 'function';\n let cleanup: void | (() => void);\n if (isRefCallback) {\n cleanup = ref(node);\n } else if (ref) {\n ref.current = node;\n }\n return () => {\n managedRef.current = null;\n if (isRefCallback) {\n if (cleanup) {\n cleanup();\n } else {\n ref(null);\n }\n } else if (ref) {\n ref.current = null;\n }\n };\n },\n [ref],\n );\n\n return [managedRef, handleRef];\n}\n\nexport type LinkProps = {\n to: InferredPaths;\n children: ReactNode;\n /**\n * indicates if the link should scroll or not on navigation\n * - `true`: always scroll\n * - `false`: never scroll\n * - `undefined`: scroll on path change (not on searchParams change)\n */\n scroll?: boolean;\n unstable_pending?: ReactNode;\n unstable_notPending?: ReactNode;\n unstable_prefetchOnEnter?: boolean;\n unstable_prefetchOnView?: boolean;\n unstable_startTransition?: ((fn: TransitionFunction) => void) | undefined;\n ref?: Ref<HTMLAnchorElement> | undefined;\n} & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>;\n\nexport function Link({\n to,\n children,\n scroll,\n unstable_pending,\n unstable_notPending,\n unstable_prefetchOnEnter,\n unstable_prefetchOnView,\n unstable_startTransition,\n ref: refProp,\n ...props\n}: LinkProps): ReactElement {\n const router = useContext(RouterContext);\n const changeRoute = router\n ? router.changeRoute\n : () => {\n throw new Error('Missing Router');\n };\n const prefetchRoute = router\n ? router.prefetchRoute\n : () => {\n throw new Error('Missing Router');\n };\n const [isPending, startTransition] = useTransition();\n const startTransitionFn =\n unstable_startTransition ||\n ((unstable_pending || unstable_notPending) && startTransition) ||\n ((fn: TransitionFunction) => fn());\n const [ref, setRef] = useSharedRef<HTMLAnchorElement>(refProp);\n\n useEffect(() => {\n if (unstable_prefetchOnView && ref.current) {\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const url = new URL(to, window.location.href);\n if (router && url.href !== window.location.href) {\n const route = parseRoute(url);\n router.prefetchRoute(route);\n }\n }\n });\n },\n { threshold: 0.1 },\n );\n\n observer.observe(ref.current);\n\n return () => {\n observer.disconnect();\n };\n }\n }, [unstable_prefetchOnView, router, to, ref]);\n const internalOnClick = () => {\n const url = new URL(to, window.location.href);\n if (url.href !== window.location.href) {\n const route = parseRoute(url);\n prefetchRoute(route);\n startTransitionFn(async () => {\n const currentPath = window.location.pathname;\n const newPath = url.pathname !== currentPath;\n try {\n await changeRoute(route, {\n shouldScroll: scroll ?? newPath,\n unstable_startTransition: startTransitionFn,\n });\n } finally {\n if (window.location.pathname === currentPath) {\n // Update history if it wasn't already updated\n window.history.pushState(\n {\n ...window.history.state,\n waku_new_path: newPath,\n },\n '',\n url,\n );\n }\n }\n });\n }\n };\n const onClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (props.onClick) {\n props.onClick(event);\n }\n if (!event.defaultPrevented && !isAltClick(event)) {\n event.preventDefault();\n internalOnClick();\n }\n };\n const onMouseEnter = unstable_prefetchOnEnter\n ? (event: MouseEvent<HTMLAnchorElement>) => {\n const url = new URL(to, window.location.href);\n if (url.href !== window.location.href) {\n const route = parseRoute(url);\n prefetchRoute(route);\n }\n props.onMouseEnter?.(event);\n }\n : props.onMouseEnter;\n const ele = createElement(\n 'a',\n { ...props, href: to, onClick, onMouseEnter, ref: setRef },\n children,\n );\n if (isPending && unstable_pending !== undefined) {\n return createElement(Fragment, null, ele, unstable_pending);\n }\n if (!isPending && unstable_notPending !== undefined) {\n return createElement(Fragment, null, ele, unstable_notPending);\n }\n return ele;\n}\n\nconst notAvailableInServer = (name: string) => () => {\n throw new Error(`${name} is not in the server`);\n};\n\nfunction renderError(message: string) {\n return createElement(\n 'html',\n null,\n createElement('body', null, createElement('h1', null, message)),\n );\n}\n\nexport class ErrorBoundary extends Component<\n { children: ReactNode },\n { error?: unknown }\n> {\n constructor(props: { children: ReactNode }) {\n super(props);\n this.state = {};\n }\n static getDerivedStateFromError(error: unknown) {\n return { error };\n }\n render() {\n if ('error' in this.state) {\n if (this.state.error instanceof Error) {\n return renderError(this.state.error.message);\n }\n return renderError(String(this.state.error));\n }\n return this.props.children;\n }\n}\n\nconst NotFound = ({\n has404,\n reset,\n}: {\n has404: boolean;\n reset: () => void;\n}) => {\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('Missing Router');\n }\n const { changeRoute } = router;\n useEffect(() => {\n if (has404) {\n const url = new URL('/404', window.location.href);\n changeRoute(parseRoute(url), { shouldScroll: true })\n .then(() => {\n // HACK: This timeout is required for canary-ci to work\n // FIXME: As we understand it, we should have a proper solution.\n setTimeout(() => {\n reset();\n }, 1);\n })\n .catch((err) => {\n console.log('Error while navigating to 404:', err);\n });\n }\n }, [has404, reset, changeRoute]);\n return has404 ? null : createElement('h1', null, 'Not Found');\n};\n\nconst Redirect = ({\n error,\n to,\n reset,\n handledErrorSet,\n}: {\n error: unknown;\n to: string;\n reset: () => void;\n handledErrorSet: WeakSet<object>;\n}) => {\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('Missing Router');\n }\n const { changeRoute } = router;\n useEffect(() => {\n // ensure single re-fetch per server redirection error on StrictMode\n // https://github.com/wakujs/waku/pull/1512\n if (handledErrorSet.has(error as object)) {\n return;\n }\n handledErrorSet.add(error as object);\n\n const url = new URL(to, window.location.href);\n // FIXME this condition seems too naive\n if (url.hostname !== window.location.hostname) {\n window.location.replace(to);\n return;\n }\n const currentPath = window.location.pathname;\n const newPath = url.pathname !== currentPath;\n changeRoute(parseRoute(url), { shouldScroll: newPath })\n .then(() => {\n // FIXME: As we understand it, we should have a proper solution.\n setTimeout(() => {\n reset();\n }, 1);\n })\n .catch((err) => {\n console.log('Error while navigating to redirect:', err);\n })\n .finally(() => {\n if (window.location.pathname === currentPath) {\n window.history.replaceState(\n {\n ...window.history.state,\n waku_new_path: newPath,\n },\n '',\n url,\n );\n }\n });\n }, [error, to, reset, changeRoute, handledErrorSet]);\n return null;\n};\n\nclass CustomErrorHandler extends Component<\n { has404: boolean; children?: ReactNode },\n { error: unknown | null }\n> {\n private handledErrorSet = new WeakSet();\n constructor(props: { has404: boolean; children?: ReactNode }) {\n super(props);\n this.state = { error: null };\n this.reset = this.reset.bind(this);\n }\n static getDerivedStateFromError(error: unknown) {\n return { error };\n }\n reset() {\n this.setState({ error: null });\n }\n render() {\n const { error } = this.state;\n if (error !== null) {\n const info = getErrorInfo(error);\n if (info?.status === 404) {\n return createElement(NotFound, {\n has404: this.props.has404,\n reset: this.reset,\n });\n }\n if (info?.location) {\n return createElement(Redirect, {\n error,\n to: info.location,\n reset: this.reset,\n handledErrorSet: this.handledErrorSet,\n });\n }\n throw error;\n }\n return this.props.children;\n }\n}\n\nconst ThrowError = ({ error }: { error: unknown }) => {\n throw error;\n};\n\nconst getRouteSlotId = (path: string) => 'route:' + decodeURI(path);\nconst getSliceSlotId = (id: SliceId) => 'slice:' + id;\n\nexport function Slice({\n id,\n children,\n ...props\n}: {\n id: SliceId;\n children?: ReactNode;\n} & (\n | {\n delayed?: false;\n }\n | {\n delayed: true;\n fallback: ReactNode;\n }\n)) {\n if (\n typeof window !== 'undefined' &&\n !import.meta.env?.VITE_EXPERIMENTAL_WAKU_ROUTER\n ) {\n throw new Error('Slice is still experimental');\n }\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('Missing Router');\n }\n const { fetchingSlices } = router;\n const refetch = useRefetch();\n const slotId = getSliceSlotId(id);\n const elementsPromise = useElementsPromise();\n const elements = use(elementsPromise);\n const needsToFetchSlice =\n props.delayed &&\n (!(slotId in elements) ||\n // FIXME: hard-coded for now\n elements[IS_STATIC_ID + ':' + slotId] !== true);\n useEffect(() => {\n // FIXME this works because of subtle timing behavior.\n if (needsToFetchSlice && !fetchingSlices.has(id)) {\n fetchingSlices.add(id);\n const rscPath = encodeSliceId(id);\n refetch(rscPath)\n .catch((e) => {\n console.error('Failed to fetch slice:', e);\n })\n .finally(() => {\n fetchingSlices.delete(id);\n });\n }\n }, [fetchingSlices, refetch, id, needsToFetchSlice]);\n if (props.delayed && !(slotId in elements)) {\n // FIXME the fallback doesn't show on refetch after the first one.\n return props.fallback;\n }\n return createElement(Slot, { id: slotId }, children);\n}\n\nconst handleScroll = () => {\n const { hash } = window.location;\n const { state } = window.history;\n const element = hash && document.getElementById(hash.slice(1));\n window.scrollTo({\n left: 0,\n top: element ? element.getBoundingClientRect().top + window.scrollY : 0,\n behavior: state?.waku_new_path ? 'instant' : 'auto',\n });\n};\n\nconst InnerRouter = ({ initialRoute }: { initialRoute: RouteProps }) => {\n const elementsPromise = useElementsPromise();\n const [has404, setHas404] = useState(false);\n const requestedRouteRef = useRef<RouteProps>(initialRoute);\n const staticPathSetRef = useRef(new Set<string>());\n const cachedIdSetRef = useRef(new Set<string>());\n useEffect(() => {\n elementsPromise.then(\n (elements) => {\n const {\n [ROUTE_ID]: routeData,\n [IS_STATIC_ID]: isStatic,\n [HAS404_ID]: has404FromElements,\n ...rest\n } = elements;\n if (has404FromElements) {\n setHas404(true);\n }\n if (routeData) {\n const [path, _query] = routeData as [string, string];\n if (isStatic) {\n staticPathSetRef.current.add(path);\n }\n }\n cachedIdSetRef.current = new Set(Object.keys(rest));\n },\n () => {},\n );\n }, [elementsPromise]);\n\n const enhanceFetchRscInternal = useEnhanceFetchRscInternal();\n const locationListenersRef = useRef(\n new Set<(path: string, query: string) => void>(),\n );\n const locationListeners = locationListenersRef.current;\n useEffect(() => {\n const enhanceFetch =\n (fetchFn: typeof fetch) =>\n (input: RequestInfo | URL, init: RequestInit = {}) => {\n const skipStr = JSON.stringify(Array.from(cachedIdSetRef.current));\n const headers = (init.headers ||= {});\n if (Array.isArray(headers)) {\n headers.push([SKIP_HEADER, skipStr]);\n } else {\n (headers as Record<string, string>)[SKIP_HEADER] = skipStr;\n }\n return fetchFn(input, init);\n };\n return enhanceFetchRscInternal(\n (fetchRscInternal) =>\n (\n rscPath: string,\n rscParams: unknown,\n prefetchOnly,\n fetchFn = fetch,\n ) => {\n const enhancedFetch = enhanceFetch(fetchFn);\n type Elements = Record<string, unknown>;\n const elementsPromise = fetchRscInternal(\n rscPath,\n rscParams,\n prefetchOnly as undefined,\n enhancedFetch,\n ) as Promise<Elements> | undefined;\n Promise.resolve(elementsPromise)\n .then((elements = {}) => {\n const { [ROUTE_ID]: routeData, [IS_STATIC_ID]: isStatic } =\n elements;\n if (routeData) {\n const [path, query] = routeData as [string, string];\n if (\n requestedRouteRef.current.path !== path ||\n (!isStatic && requestedRouteRef.current.query !== query)\n ) {\n locationListeners.forEach((listener) =>\n listener(path, query),\n );\n }\n }\n })\n .catch(() => {});\n return elementsPromise as never;\n },\n );\n }, [enhanceFetchRscInternal, locationListeners]);\n const refetch = useRefetch();\n const [route, setRoute] = useState(() => ({\n // This is the first initialization of the route, and it has\n // to ignore the hash, because on server side there is none.\n // Otherwise there will be a hydration error.\n // The client side route, including the hash, will be updated in the effect below.\n ...initialRoute,\n hash: '',\n }));\n const routeChangeListenersRef =\n useRef<\n [\n Record<\n 'on' | 'off',\n (event: ChangeRouteEvent, handler: ChangeRouteCallback) => void\n >,\n (\n eventType: ChangeRouteEvent,\n eventRoute: Parameters<ChangeRouteCallback>[0],\n ) => void,\n ]\n >(null);\n if (routeChangeListenersRef.current === null) {\n const listeners: Record<ChangeRouteEvent, Set<ChangeRouteCallback>> = {\n start: new Set(),\n complete: new Set(),\n };\n const executeListeners = (\n eventType: ChangeRouteEvent,\n eventRoute: Parameters<ChangeRouteCallback>[0],\n ) => {\n const eventListenersSet = listeners[eventType];\n if (!eventListenersSet.size) {\n return;\n }\n for (const listener of eventListenersSet) {\n listener(eventRoute);\n }\n };\n const events = (() => {\n const on = (event: ChangeRouteEvent, handler: ChangeRouteCallback) => {\n listeners[event].add(handler);\n };\n const off = (event: ChangeRouteEvent, handler: ChangeRouteCallback) => {\n listeners[event].delete(handler);\n };\n return { on, off };\n })();\n\n routeChangeListenersRef.current = [events, executeListeners];\n }\n // Update the route post-load to include the current hash.\n useEffect(() => {\n setRoute((prev) => {\n if (\n prev.path === initialRoute.path &&\n prev.query === initialRoute.query &&\n prev.hash === initialRoute.hash\n ) {\n return prev;\n }\n return initialRoute;\n });\n }, [initialRoute]);\n\n const [routeChangeEvents, executeListeners] = routeChangeListenersRef.current;\n const [err, setErr] = useState<unknown>(null);\n // FIXME this \"refetching\" hack doesn't seem ideal.\n const refetching = useRef<[onFinish?: () => void] | null>(null);\n const changeRoute: ChangeRoute = useCallback(\n async (route, options) => {\n requestedRouteRef.current = route;\n executeListeners('start', route);\n const startTransitionFn =\n options.unstable_startTransition || ((fn: TransitionFunction) => fn());\n refetching.current = [];\n setErr(null);\n const { skipRefetch } = options || {};\n if (!staticPathSetRef.current.has(route.path) && !skipRefetch) {\n const rscPath = encodeRoutePath(route.path);\n const rscParams = createRscParams(route.query);\n try {\n await refetch(rscPath, rscParams);\n } catch (e) {\n refetching.current = null;\n setErr(e);\n throw e;\n }\n }\n startTransitionFn(() => {\n if (options.shouldScroll) {\n handleScroll();\n }\n setRoute(route);\n refetching.current![0]?.();\n refetching.current = null;\n executeListeners('complete', route);\n });\n },\n [executeListeners, refetch],\n );\n\n const prefetchRoute: PrefetchRoute = useCallback((route) => {\n if (staticPathSetRef.current.has(route.path)) {\n return;\n }\n const rscPath = encodeRoutePath(route.path);\n const rscParams = createRscParams(route.query);\n prefetchRsc(rscPath, rscParams);\n (globalThis as any).__WAKU_ROUTER_PREFETCH__?.(route.path);\n }, []);\n\n useEffect(() => {\n const callback = () => {\n const route = parseRoute(new URL(window.location.href));\n changeRoute(route, { shouldScroll: true }).catch((err) => {\n console.log('Error while navigating back:', err);\n });\n };\n window.addEventListener('popstate', callback);\n return () => {\n window.removeEventListener('popstate', callback);\n };\n }, [changeRoute]);\n\n useEffect(() => {\n const callback = (path: string, query: string) => {\n const fn = () => {\n const url = new URL(window.location.href);\n url.pathname = path;\n url.search = query;\n url.hash = '';\n changeRoute(parseRoute(url), {\n skipRefetch: true,\n shouldScroll: false,\n })\n .catch((err) => {\n console.log('Error while handling location listeners:', err);\n })\n .finally(() => {\n if (path !== '/404') {\n window.history.pushState(\n {\n ...window.history.state,\n waku_new_path: url.pathname !== window.location.pathname,\n },\n '',\n url,\n );\n }\n });\n };\n if (refetching.current) {\n refetching.current.push(fn);\n } else {\n startTransition(fn);\n }\n };\n locationListeners.add(callback);\n return () => {\n locationListeners.delete(callback);\n };\n }, [changeRoute, locationListeners]);\n\n const routeElement =\n err !== null\n ? createElement(ThrowError, { error: err })\n : createElement(Slot, { id: getRouteSlotId(route.path) });\n const rootElement = createElement(\n Slot,\n { id: 'root' },\n createElement(CustomErrorHandler, { has404 }, routeElement),\n );\n return createElement(\n RouterContext,\n {\n value: {\n route,\n changeRoute,\n prefetchRoute,\n routeChangeEvents,\n fetchingSlices: useRef(new Set<SliceId>()).current,\n },\n },\n rootElement,\n );\n};\n\nexport function Router({\n initialRoute = parseRouteFromLocation(),\n}: {\n initialRoute?: RouteProps;\n}) {\n const initialRscPath = encodeRoutePath(initialRoute.path);\n const initialRscParams = createRscParams(initialRoute.query);\n return createElement(\n Root as FunctionComponent<Omit<ComponentProps<typeof Root>, 'children'>>,\n {\n initialRscPath,\n initialRscParams,\n },\n createElement(InnerRouter, { initialRoute }),\n );\n}\n\nconst MOCK_ROUTE_CHANGE_LISTENER: Record<\n 'on' | 'off',\n (event: ChangeRouteEvent, handler: ChangeRouteCallback) => void\n> = {\n on: () => notAvailableInServer('routeChange:on'),\n off: () => notAvailableInServer('routeChange:off'),\n};\n\n/**\n * ServerRouter for SSR\n * This is not a public API.\n */\nexport function INTERNAL_ServerRouter({\n route,\n httpstatus,\n}: {\n route: RouteProps;\n httpstatus: number;\n}) {\n const routeElement = createElement(Slot, { id: getRouteSlotId(route.path) });\n const rootElement = createElement(\n Slot,\n { id: 'root' },\n createElement('meta', { name: 'httpstatus', content: `${httpstatus}` }),\n routeElement,\n );\n return createElement(\n Fragment,\n null,\n createElement(\n RouterContext,\n {\n value: {\n route,\n changeRoute: notAvailableInServer('changeRoute'),\n prefetchRoute: notAvailableInServer('prefetchRoute'),\n routeChangeEvents: MOCK_ROUTE_CHANGE_LISTENER,\n fetchingSlices: new Set<SliceId>(),\n },\n },\n rootElement,\n ),\n );\n}\n"],"names":["createContext","createElement","startTransition","use","useCallback","useContext","useEffect","useRef","useState","useTransition","Fragment","Component","prefetchRsc","Root","Slot","useElementsPromise_UNSTABLE","useElementsPromise","useRefetch","useEnhanceFetchRscInternal_UNSTABLE","useEnhanceFetchRscInternal","encodeRoutePath","encodeSliceId","ROUTE_ID","IS_STATIC_ID","HAS404_ID","SKIP_HEADER","getErrorInfo","normalizeRoutePath","path","suffix","endsWith","slice","length","parseRoute","url","pathname","searchParams","hash","query","toString","parseRouteFromLocation","httpStatusMeta","document","querySelector","content","URL","window","location","href","isAltClick","event","button","metaKey","altKey","ctrlKey","shiftKey","savedRscParams","createRscParams","rscParams","URLSearchParams","RouterContext","useRouter","router","Error","route","changeRoute","prefetchRoute","push","to","options","currentPath","newPath","shouldScroll","scroll","history","pushState","state","waku_new_path","replace","replaceState","reload","back","forward","prefetch","unstable_events","routeChangeEvents","useSharedRef","ref","managedRef","handleRef","node","current","isRefCallback","cleanup","Link","children","unstable_pending","unstable_notPending","unstable_prefetchOnEnter","unstable_prefetchOnView","unstable_startTransition","refProp","props","isPending","startTransitionFn","fn","setRef","observer","IntersectionObserver","entries","forEach","entry","isIntersecting","threshold","observe","disconnect","internalOnClick","onClick","defaultPrevented","preventDefault","onMouseEnter","ele","undefined","notAvailableInServer","name","renderError","message","ErrorBoundary","getDerivedStateFromError","error","render","String","NotFound","has404","reset","then","setTimeout","catch","err","console","log","Redirect","handledErrorSet","has","add","hostname","finally","CustomErrorHandler","WeakSet","bind","setState","info","status","ThrowError","getRouteSlotId","decodeURI","getSliceSlotId","id","Slice","env","VITE_EXPERIMENTAL_WAKU_ROUTER","fetchingSlices","refetch","slotId","elementsPromise","elements","needsToFetchSlice","delayed","rscPath","e","delete","fallback","handleScroll","element","getElementById","scrollTo","left","top","getBoundingClientRect","scrollY","behavior","InnerRouter","initialRoute","setHas404","requestedRouteRef","staticPathSetRef","Set","cachedIdSetRef","routeData","isStatic","has404FromElements","rest","_query","Object","keys","enhanceFetchRscInternal","locationListenersRef","locationListeners","enhanceFetch","fetchFn","input","init","skipStr","JSON","stringify","Array","from","headers","isArray","fetchRscInternal","prefetchOnly","fetch","enhancedFetch","Promise","resolve","listener","setRoute","routeChangeListenersRef","listeners","start","complete","executeListeners","eventType","eventRoute","eventListenersSet","size","events","on","handler","off","prev","setErr","refetching","skipRefetch","globalThis","__WAKU_ROUTER_PREFETCH__","callback","addEventListener","removeEventListener","search","routeElement","rootElement","value","Router","initialRscPath","initialRscParams","MOCK_ROUTE_CHANGE_LISTENER","INTERNAL_ServerRouter","httpstatus"],"mappings":"AAAA;AAEA,SACEA,aAAa,EACbC,aAAa,EACbC,eAAe,EACfC,GAAG,EACHC,WAAW,EACXC,UAAU,EACVC,SAAS,EACTC,MAAM,EACNC,QAAQ,EACRC,aAAa,EACbC,QAAQ,EACRC,SAAS,QACJ,QAAQ;AAaf,SACEC,WAAW,EACXC,IAAI,EACJC,IAAI,EACJC,+BAA+BC,kBAAkB,EACjDC,UAAU,EACVC,uCAAuCC,0BAA0B,QAC5D,uBAAuB;AAC9B,SACEC,eAAe,EACfC,aAAa,EACbC,QAAQ,EACRC,YAAY,EACZC,SAAS,EACTC,WAAW,QACN,cAAc;AAGrB,SAASC,YAAY,QAAQ,gCAAgC;AAY7D,MAAMC,qBAAqB,CAACC;IAC1B,KAAK,MAAMC,UAAU;QAAC;QAAK;KAAc,CAAE;QACzC,IAAID,KAAKE,QAAQ,CAACD,SAAS;YACzB,OAAOD,KAAKG,KAAK,CAAC,GAAG,CAACF,OAAOG,MAAM,KAAK;QAC1C;IACF;IACA,OAAOJ;AACT;AAEA,MAAMK,aAAa,CAACC;IAClB,MAAM,EAAEC,QAAQ,EAAEC,YAAY,EAAEC,IAAI,EAAE,GAAGH;IACzC,OAAO;QACLN,MAAMD,mBAAmBQ;QACzBG,OAAOF,aAAaG,QAAQ;QAC5BF;IACF;AACF;AAEA,MAAMG,yBAAyB;IAC7B,MAAMC,iBAAiBC,SAASC,aAAa,CAAC;IAC9C,IACEF,kBACA,aAAaA,kBACbA,eAAeG,OAAO,KAAK,OAC3B;QACA,OAAO;YAAEhB,MAAM;YAAQU,OAAO;YAAID,MAAM;QAAG;IAC7C;IACA,OAAOJ,WAAW,IAAIY,IAAIC,OAAOC,QAAQ,CAACC,IAAI;AAChD;AAEA,MAAMC,aAAa,CAACC,QAClBA,MAAMC,MAAM,KAAK,KACjB,CAAC,CAAED,CAAAA,MAAME,OAAO,IAAIF,MAAMG,MAAM,IAAIH,MAAMI,OAAO,IAAIJ,MAAMK,QAAQ,AAAD;AAEpE,IAAIC;AAEJ,MAAMC,kBAAkB,CAACnB;IACvB,IAAIkB,kBAAkBA,cAAc,CAAC,EAAE,KAAKlB,OAAO;QACjD,OAAOkB,cAAc,CAAC,EAAE;IAC1B;IACA,MAAME,YAAY,IAAIC,gBAAgB;QAAErB;IAAM;IAC9CkB,iBAAiB;QAAClB;QAAOoB;KAAU;IACnC,OAAOA;AACT;AAmBA,8CAA8C;AAC9C,MAAME,gBAAgB5D,cASZ;AAEV,OAAO,SAAS6D;IACd,MAAMC,SAASzD,WAAWuD;IAC1B,IAAI,CAACE,QAAQ;QACX,MAAM,IAAIC,MAAM;IAClB;IAEA,MAAM,EAAEC,KAAK,EAAEC,WAAW,EAAEC,aAAa,EAAE,GAAGJ;IAC9C,MAAMK,OAAO/D,YACX,OACEgE,IACAC;QAUA,MAAMnC,MAAM,IAAIW,IAAIuB,IAAItB,OAAOC,QAAQ,CAACC,IAAI;QAC5C,MAAMsB,cAAcxB,OAAOC,QAAQ,CAACZ,QAAQ;QAC5C,MAAMoC,UAAUrC,IAAIC,QAAQ,KAAKmC;QACjC,MAAML,YAAYhC,WAAWC,MAAM;YACjCsC,cAAcH,SAASI,UAAUF;QACnC;QACA,IAAIzB,OAAOC,QAAQ,CAACZ,QAAQ,KAAKmC,aAAa;YAC5CxB,OAAO4B,OAAO,CAACC,SAAS,CACtB;gBACE,GAAG7B,OAAO4B,OAAO,CAACE,KAAK;gBACvBC,eAAeN;YACjB,GACA,IACArC;QAEJ;IACF,GACA;QAAC+B;KAAY;IAEf,MAAMa,UAAU1E,YACd,OACEgE,IACAC;QAUA,MAAMnC,MAAM,IAAIW,IAAIuB,IAAItB,OAAOC,QAAQ,CAACC,IAAI;QAC5C,MAAMsB,cAAcxB,OAAOC,QAAQ,CAACZ,QAAQ;QAC5C,MAAMoC,UAAUrC,IAAIC,QAAQ,KAAKmC;QACjC,MAAML,YAAYhC,WAAWC,MAAM;YACjCsC,cAAcH,SAASI,UAAUF;QACnC;QACA,IAAIzB,OAAOC,QAAQ,CAACZ,QAAQ,KAAKmC,aAAa;YAC5CxB,OAAO4B,OAAO,CAACK,YAAY,CAACjC,OAAO4B,OAAO,CAACE,KAAK,EAAE,IAAI1C;QACxD;IACF,GACA;QAAC+B;KAAY;IAEf,MAAMe,SAAS5E,YAAY;QACzB,MAAM8B,MAAM,IAAIW,IAAIC,OAAOC,QAAQ,CAACC,IAAI;QACxC,MAAMiB,YAAYhC,WAAWC,MAAM;YAAEsC,cAAc;QAAK;IAC1D,GAAG;QAACP;KAAY;IAChB,MAAMgB,OAAO7E,YAAY;QACvB,yBAAyB;QACzB0C,OAAO4B,OAAO,CAACO,IAAI;IACrB,GAAG,EAAE;IACL,MAAMC,UAAU9E,YAAY;QAC1B,yBAAyB;QACzB0C,OAAO4B,OAAO,CAACQ,OAAO;IACxB,GAAG,EAAE;IACL,MAAMC,WAAW/E,YACf,CAACgE;QACC,MAAMlC,MAAM,IAAIW,IAAIuB,IAAItB,OAAOC,QAAQ,CAACC,IAAI;QAC5CkB,cAAcjC,WAAWC;IAC3B,GACA;QAACgC;KAAc;IAEjB,OAAO;QACL,GAAGF,KAAK;QACRG;QACAW;QACAE;QACAC;QACAC;QACAC;QACAC,iBAAiBtB,OAAOuB,iBAAiB;IAC3C;AACF;AAEA,SAASC,aACPC,GAA8B;IAE9B,MAAMC,aAAajF,OAAU;IAE7B,MAAMkF,YAAYrF,YAChB,CAACsF;QACCF,WAAWG,OAAO,GAAGD;QACrB,MAAME,gBAAgB,OAAOL,QAAQ;QACrC,IAAIM;QACJ,IAAID,eAAe;YACjBC,UAAUN,IAAIG;QAChB,OAAO,IAAIH,KAAK;YACdA,IAAII,OAAO,GAAGD;QAChB;QACA,OAAO;YACLF,WAAWG,OAAO,GAAG;YACrB,IAAIC,eAAe;gBACjB,IAAIC,SAAS;oBACXA;gBACF,OAAO;oBACLN,IAAI;gBACN;YACF,OAAO,IAAIA,KAAK;gBACdA,IAAII,OAAO,GAAG;YAChB;QACF;IACF,GACA;QAACJ;KAAI;IAGP,OAAO;QAACC;QAAYC;KAAU;AAChC;AAoBA,OAAO,SAASK,KAAK,EACnB1B,EAAE,EACF2B,QAAQ,EACRtB,MAAM,EACNuB,gBAAgB,EAChBC,mBAAmB,EACnBC,wBAAwB,EACxBC,uBAAuB,EACvBC,wBAAwB,EACxBb,KAAKc,OAAO,EACZ,GAAGC,OACO;IACV,MAAMxC,SAASzD,WAAWuD;IAC1B,MAAMK,cAAcH,SAChBA,OAAOG,WAAW,GAClB;QACE,MAAM,IAAIF,MAAM;IAClB;IACJ,MAAMG,gBAAgBJ,SAClBA,OAAOI,aAAa,GACpB;QACE,MAAM,IAAIH,MAAM;IAClB;IACJ,MAAM,CAACwC,WAAWrG,gBAAgB,GAAGO;IACrC,MAAM+F,oBACJJ,4BACC,AAACJ,CAAAA,oBAAoBC,mBAAkB,KAAM/F,mBAC7C,CAAA,CAACuG,KAA2BA,IAAG;IAClC,MAAM,CAAClB,KAAKmB,OAAO,GAAGpB,aAAgCe;IAEtD/F,UAAU;QACR,IAAI6F,2BAA2BZ,IAAII,OAAO,EAAE;YAC1C,MAAMgB,WAAW,IAAIC,qBACnB,CAACC;gBACCA,QAAQC,OAAO,CAAC,CAACC;oBACf,IAAIA,MAAMC,cAAc,EAAE;wBACxB,MAAM9E,MAAM,IAAIW,IAAIuB,IAAItB,OAAOC,QAAQ,CAACC,IAAI;wBAC5C,IAAIc,UAAU5B,IAAIc,IAAI,KAAKF,OAAOC,QAAQ,CAACC,IAAI,EAAE;4BAC/C,MAAMgB,QAAQ/B,WAAWC;4BACzB4B,OAAOI,aAAa,CAACF;wBACvB;oBACF;gBACF;YACF,GACA;gBAAEiD,WAAW;YAAI;YAGnBN,SAASO,OAAO,CAAC3B,IAAII,OAAO;YAE5B,OAAO;gBACLgB,SAASQ,UAAU;YACrB;QACF;IACF,GAAG;QAAChB;QAAyBrC;QAAQM;QAAImB;KAAI;IAC7C,MAAM6B,kBAAkB;QACtB,MAAMlF,MAAM,IAAIW,IAAIuB,IAAItB,OAAOC,QAAQ,CAACC,IAAI;QAC5C,IAAId,IAAIc,IAAI,KAAKF,OAAOC,QAAQ,CAACC,IAAI,EAAE;YACrC,MAAMgB,QAAQ/B,WAAWC;YACzBgC,cAAcF;YACdwC,kBAAkB;gBAChB,MAAMlC,cAAcxB,OAAOC,QAAQ,CAACZ,QAAQ;gBAC5C,MAAMoC,UAAUrC,IAAIC,QAAQ,KAAKmC;gBACjC,IAAI;oBACF,MAAML,YAAYD,OAAO;wBACvBQ,cAAcC,UAAUF;wBACxB6B,0BAA0BI;oBAC5B;gBACF,SAAU;oBACR,IAAI1D,OAAOC,QAAQ,CAACZ,QAAQ,KAAKmC,aAAa;wBAC5C,8CAA8C;wBAC9CxB,OAAO4B,OAAO,CAACC,SAAS,CACtB;4BACE,GAAG7B,OAAO4B,OAAO,CAACE,KAAK;4BACvBC,eAAeN;wBACjB,GACA,IACArC;oBAEJ;gBACF;YACF;QACF;IACF;IACA,MAAMmF,UAAU,CAACnE;QACf,IAAIoD,MAAMe,OAAO,EAAE;YACjBf,MAAMe,OAAO,CAACnE;QAChB;QACA,IAAI,CAACA,MAAMoE,gBAAgB,IAAI,CAACrE,WAAWC,QAAQ;YACjDA,MAAMqE,cAAc;YACpBH;QACF;IACF;IACA,MAAMI,eAAetB,2BACjB,CAAChD;QACC,MAAMhB,MAAM,IAAIW,IAAIuB,IAAItB,OAAOC,QAAQ,CAACC,IAAI;QAC5C,IAAId,IAAIc,IAAI,KAAKF,OAAOC,QAAQ,CAACC,IAAI,EAAE;YACrC,MAAMgB,QAAQ/B,WAAWC;YACzBgC,cAAcF;QAChB;QACAsC,MAAMkB,YAAY,GAAGtE;IACvB,IACAoD,MAAMkB,YAAY;IACtB,MAAMC,MAAMxH,cACV,KACA;QAAE,GAAGqG,KAAK;QAAEtD,MAAMoB;QAAIiD;QAASG;QAAcjC,KAAKmB;IAAO,GACzDX;IAEF,IAAIQ,aAAaP,qBAAqB0B,WAAW;QAC/C,OAAOzH,cAAcS,UAAU,MAAM+G,KAAKzB;IAC5C;IACA,IAAI,CAACO,aAAaN,wBAAwByB,WAAW;QACnD,OAAOzH,cAAcS,UAAU,MAAM+G,KAAKxB;IAC5C;IACA,OAAOwB;AACT;AAEA,MAAME,uBAAuB,CAACC,OAAiB;QAC7C,MAAM,IAAI7D,MAAM,GAAG6D,KAAK,qBAAqB,CAAC;IAChD;AAEA,SAASC,YAAYC,OAAe;IAClC,OAAO7H,cACL,QACA,MACAA,cAAc,QAAQ,MAAMA,cAAc,MAAM,MAAM6H;AAE1D;AAEA,OAAO,MAAMC,sBAAsBpH;IAIjC,YAAY2F,KAA8B,CAAE;QAC1C,KAAK,CAACA;QACN,IAAI,CAAC1B,KAAK,GAAG,CAAC;IAChB;IACA,OAAOoD,yBAAyBC,KAAc,EAAE;QAC9C,OAAO;YAAEA;QAAM;IACjB;IACAC,SAAS;QACP,IAAI,WAAW,IAAI,CAACtD,KAAK,EAAE;YACzB,IAAI,IAAI,CAACA,KAAK,CAACqD,KAAK,YAAYlE,OAAO;gBACrC,OAAO8D,YAAY,IAAI,CAACjD,KAAK,CAACqD,KAAK,CAACH,OAAO;YAC7C;YACA,OAAOD,YAAYM,OAAO,IAAI,CAACvD,KAAK,CAACqD,KAAK;QAC5C;QACA,OAAO,IAAI,CAAC3B,KAAK,CAACP,QAAQ;IAC5B;AACF;AAEA,MAAMqC,WAAW,CAAC,EAChBC,MAAM,EACNC,KAAK,EAIN;IACC,MAAMxE,SAASzD,WAAWuD;IAC1B,IAAI,CAACE,QAAQ;QACX,MAAM,IAAIC,MAAM;IAClB;IACA,MAAM,EAAEE,WAAW,EAAE,GAAGH;IACxBxD,UAAU;QACR,IAAI+H,QAAQ;YACV,MAAMnG,MAAM,IAAIW,IAAI,QAAQC,OAAOC,QAAQ,CAACC,IAAI;YAChDiB,YAAYhC,WAAWC,MAAM;gBAAEsC,cAAc;YAAK,GAC/C+D,IAAI,CAAC;gBACJ,uDAAuD;gBACvD,gEAAgE;gBAChEC,WAAW;oBACTF;gBACF,GAAG;YACL,GACCG,KAAK,CAAC,CAACC;gBACNC,QAAQC,GAAG,CAAC,kCAAkCF;YAChD;QACJ;IACF,GAAG;QAACL;QAAQC;QAAOrE;KAAY;IAC/B,OAAOoE,SAAS,OAAOpI,cAAc,MAAM,MAAM;AACnD;AAEA,MAAM4I,WAAW,CAAC,EAChBZ,KAAK,EACL7D,EAAE,EACFkE,KAAK,EACLQ,eAAe,EAMhB;IACC,MAAMhF,SAASzD,WAAWuD;IAC1B,IAAI,CAACE,QAAQ;QACX,MAAM,IAAIC,MAAM;IAClB;IACA,MAAM,EAAEE,WAAW,EAAE,GAAGH;IACxBxD,UAAU;QACR,oEAAoE;QACpE,2CAA2C;QAC3C,IAAIwI,gBAAgBC,GAAG,CAACd,QAAkB;YACxC;QACF;QACAa,gBAAgBE,GAAG,CAACf;QAEpB,MAAM/F,MAAM,IAAIW,IAAIuB,IAAItB,OAAOC,QAAQ,CAACC,IAAI;QAC5C,uCAAuC;QACvC,IAAId,IAAI+G,QAAQ,KAAKnG,OAAOC,QAAQ,CAACkG,QAAQ,EAAE;YAC7CnG,OAAOC,QAAQ,CAAC+B,OAAO,CAACV;YACxB;QACF;QACA,MAAME,cAAcxB,OAAOC,QAAQ,CAACZ,QAAQ;QAC5C,MAAMoC,UAAUrC,IAAIC,QAAQ,KAAKmC;QACjCL,YAAYhC,WAAWC,MAAM;YAAEsC,cAAcD;QAAQ,GAClDgE,IAAI,CAAC;YACJ,gEAAgE;YAChEC,WAAW;gBACTF;YACF,GAAG;QACL,GACCG,KAAK,CAAC,CAACC;YACNC,QAAQC,GAAG,CAAC,uCAAuCF;QACrD,GACCQ,OAAO,CAAC;YACP,IAAIpG,OAAOC,QAAQ,CAACZ,QAAQ,KAAKmC,aAAa;gBAC5CxB,OAAO4B,OAAO,CAACK,YAAY,CACzB;oBACE,GAAGjC,OAAO4B,OAAO,CAACE,KAAK;oBACvBC,eAAeN;gBACjB,GACA,IACArC;YAEJ;QACF;IACJ,GAAG;QAAC+F;QAAO7D;QAAIkE;QAAOrE;QAAa6E;KAAgB;IACnD,OAAO;AACT;AAEA,MAAMK,2BAA2BxI;IAIvBmI,kBAAkB,IAAIM,UAAU;IACxC,YAAY9C,KAAgD,CAAE;QAC5D,KAAK,CAACA;QACN,IAAI,CAAC1B,KAAK,GAAG;YAAEqD,OAAO;QAAK;QAC3B,IAAI,CAACK,KAAK,GAAG,IAAI,CAACA,KAAK,CAACe,IAAI,CAAC,IAAI;IACnC;IACA,OAAOrB,yBAAyBC,KAAc,EAAE;QAC9C,OAAO;YAAEA;QAAM;IACjB;IACAK,QAAQ;QACN,IAAI,CAACgB,QAAQ,CAAC;YAAErB,OAAO;QAAK;IAC9B;IACAC,SAAS;QACP,MAAM,EAAED,KAAK,EAAE,GAAG,IAAI,CAACrD,KAAK;QAC5B,IAAIqD,UAAU,MAAM;YAClB,MAAMsB,OAAO7H,aAAauG;YAC1B,IAAIsB,MAAMC,WAAW,KAAK;gBACxB,OAAOvJ,cAAcmI,UAAU;oBAC7BC,QAAQ,IAAI,CAAC/B,KAAK,CAAC+B,MAAM;oBACzBC,OAAO,IAAI,CAACA,KAAK;gBACnB;YACF;YACA,IAAIiB,MAAMxG,UAAU;gBAClB,OAAO9C,cAAc4I,UAAU;oBAC7BZ;oBACA7D,IAAImF,KAAKxG,QAAQ;oBACjBuF,OAAO,IAAI,CAACA,KAAK;oBACjBQ,iBAAiB,IAAI,CAACA,eAAe;gBACvC;YACF;YACA,MAAMb;QACR;QACA,OAAO,IAAI,CAAC3B,KAAK,CAACP,QAAQ;IAC5B;AACF;AAEA,MAAM0D,aAAa,CAAC,EAAExB,KAAK,EAAsB;IAC/C,MAAMA;AACR;AAEA,MAAMyB,iBAAiB,CAAC9H,OAAiB,WAAW+H,UAAU/H;AAC9D,MAAMgI,iBAAiB,CAACC,KAAgB,WAAWA;AAEnD,OAAO,SAASC,MAAM,EACpBD,EAAE,EACF9D,QAAQ,EACR,GAAGO,OAYJ;IACC,IACE,OAAOxD,WAAW,eAClB,CAAC,YAAYiH,GAAG,EAAEC,+BAClB;QACA,MAAM,IAAIjG,MAAM;IAClB;IACA,MAAMD,SAASzD,WAAWuD;IAC1B,IAAI,CAACE,QAAQ;QACX,MAAM,IAAIC,MAAM;IAClB;IACA,MAAM,EAAEkG,cAAc,EAAE,GAAGnG;IAC3B,MAAMoG,UAAUjJ;IAChB,MAAMkJ,SAASP,eAAeC;IAC9B,MAAMO,kBAAkBpJ;IACxB,MAAMqJ,WAAWlK,IAAIiK;IACrB,MAAME,oBACJhE,MAAMiE,OAAO,IACZ,CAAA,CAAEJ,CAAAA,UAAUE,QAAO,KAClB,4BAA4B;IAC5BA,QAAQ,CAAC9I,eAAe,MAAM4I,OAAO,KAAK,IAAG;IACjD7J,UAAU;QACR,sDAAsD;QACtD,IAAIgK,qBAAqB,CAACL,eAAelB,GAAG,CAACc,KAAK;YAChDI,eAAejB,GAAG,CAACa;YACnB,MAAMW,UAAUnJ,cAAcwI;YAC9BK,QAAQM,SACL/B,KAAK,CAAC,CAACgC;gBACN9B,QAAQV,KAAK,CAAC,0BAA0BwC;YAC1C,GACCvB,OAAO,CAAC;gBACPe,eAAeS,MAAM,CAACb;YACxB;QACJ;IACF,GAAG;QAACI;QAAgBC;QAASL;QAAIS;KAAkB;IACnD,IAAIhE,MAAMiE,OAAO,IAAI,CAAEJ,CAAAA,UAAUE,QAAO,GAAI;QAC1C,kEAAkE;QAClE,OAAO/D,MAAMqE,QAAQ;IACvB;IACA,OAAO1K,cAAca,MAAM;QAAE+I,IAAIM;IAAO,GAAGpE;AAC7C;AAEA,MAAM6E,eAAe;IACnB,MAAM,EAAEvI,IAAI,EAAE,GAAGS,OAAOC,QAAQ;IAChC,MAAM,EAAE6B,KAAK,EAAE,GAAG9B,OAAO4B,OAAO;IAChC,MAAMmG,UAAUxI,QAAQK,SAASoI,cAAc,CAACzI,KAAKN,KAAK,CAAC;IAC3De,OAAOiI,QAAQ,CAAC;QACdC,MAAM;QACNC,KAAKJ,UAAUA,QAAQK,qBAAqB,GAAGD,GAAG,GAAGnI,OAAOqI,OAAO,GAAG;QACtEC,UAAUxG,OAAOC,gBAAgB,YAAY;IAC/C;AACF;AAEA,MAAMwG,cAAc,CAAC,EAAEC,YAAY,EAAgC;IACjE,MAAMlB,kBAAkBpJ;IACxB,MAAM,CAACqH,QAAQkD,UAAU,GAAG/K,SAAS;IACrC,MAAMgL,oBAAoBjL,OAAmB+K;IAC7C,MAAMG,mBAAmBlL,OAAO,IAAImL;IACpC,MAAMC,iBAAiBpL,OAAO,IAAImL;IAClCpL,UAAU;QACR8J,gBAAgB7B,IAAI,CAClB,CAAC8B;YACC,MAAM,EACJ,CAAC/I,SAAS,EAAEsK,SAAS,EACrB,CAACrK,aAAa,EAAEsK,QAAQ,EACxB,CAACrK,UAAU,EAAEsK,kBAAkB,EAC/B,GAAGC,MACJ,GAAG1B;YACJ,IAAIyB,oBAAoB;gBACtBP,UAAU;YACZ;YACA,IAAIK,WAAW;gBACb,MAAM,CAAChK,MAAMoK,OAAO,GAAGJ;gBACvB,IAAIC,UAAU;oBACZJ,iBAAiB9F,OAAO,CAACqD,GAAG,CAACpH;gBAC/B;YACF;YACA+J,eAAehG,OAAO,GAAG,IAAI+F,IAAIO,OAAOC,IAAI,CAACH;QAC/C,GACA,KAAO;IAEX,GAAG;QAAC3B;KAAgB;IAEpB,MAAM+B,0BAA0BhL;IAChC,MAAMiL,uBAAuB7L,OAC3B,IAAImL;IAEN,MAAMW,oBAAoBD,qBAAqBzG,OAAO;IACtDrF,UAAU;QACR,MAAMgM,eACJ,CAACC,UACD,CAACC,OAA0BC,OAAoB,CAAC,CAAC;gBAC/C,MAAMC,UAAUC,KAAKC,SAAS,CAACC,MAAMC,IAAI,CAACnB,eAAehG,OAAO;gBAChE,MAAMoH,UAAWN,KAAKM,OAAO,KAAK,CAAC;gBACnC,IAAIF,MAAMG,OAAO,CAACD,UAAU;oBAC1BA,QAAQ5I,IAAI,CAAC;wBAAC1C;wBAAaiL;qBAAQ;gBACrC,OAAO;oBACJK,OAAkC,CAACtL,YAAY,GAAGiL;gBACrD;gBACA,OAAOH,QAAQC,OAAOC;YACxB;QACF,OAAON,wBACL,CAACc,mBACC,CACEzC,SACA9G,WACAwJ,cACAX,UAAUY,KAAK;gBAEf,MAAMC,gBAAgBd,aAAaC;gBAEnC,MAAMnC,kBAAkB6C,iBACtBzC,SACA9G,WACAwJ,cACAE;gBAEFC,QAAQC,OAAO,CAAClD,iBACb7B,IAAI,CAAC,CAAC8B,WAAW,CAAC,CAAC;oBAClB,MAAM,EAAE,CAAC/I,SAAS,EAAEsK,SAAS,EAAE,CAACrK,aAAa,EAAEsK,QAAQ,EAAE,GACvDxB;oBACF,IAAIuB,WAAW;wBACb,MAAM,CAAChK,MAAMU,MAAM,GAAGsJ;wBACtB,IACEJ,kBAAkB7F,OAAO,CAAC/D,IAAI,KAAKA,QAClC,CAACiK,YAAYL,kBAAkB7F,OAAO,CAACrD,KAAK,KAAKA,OAClD;4BACA+J,kBAAkBvF,OAAO,CAAC,CAACyG,WACzBA,SAAS3L,MAAMU;wBAEnB;oBACF;gBACF,GACCmG,KAAK,CAAC,KAAO;gBAChB,OAAO2B;YACT;IAEN,GAAG;QAAC+B;QAAyBE;KAAkB;IAC/C,MAAMnC,UAAUjJ;IAChB,MAAM,CAAC+C,OAAOwJ,SAAS,GAAGhN,SAAS,IAAO,CAAA;YACxC,4DAA4D;YAC5D,4DAA4D;YAC5D,6CAA6C;YAC7C,kFAAkF;YAClF,GAAG8K,YAAY;YACfjJ,MAAM;QACR,CAAA;IACA,MAAMoL,0BACJlN,OAWE;IACJ,IAAIkN,wBAAwB9H,OAAO,KAAK,MAAM;QAC5C,MAAM+H,YAAgE;YACpEC,OAAO,IAAIjC;YACXkC,UAAU,IAAIlC;QAChB;QACA,MAAMmC,mBAAmB,CACvBC,WACAC;YAEA,MAAMC,oBAAoBN,SAAS,CAACI,UAAU;YAC9C,IAAI,CAACE,kBAAkBC,IAAI,EAAE;gBAC3B;YACF;YACA,KAAK,MAAMV,YAAYS,kBAAmB;gBACxCT,SAASQ;YACX;QACF;QACA,MAAMG,SAAS,AAAC,CAAA;YACd,MAAMC,KAAK,CAACjL,OAAyBkL;gBACnCV,SAAS,CAACxK,MAAM,CAAC8F,GAAG,CAACoF;YACvB;YACA,MAAMC,MAAM,CAACnL,OAAyBkL;gBACpCV,SAAS,CAACxK,MAAM,CAACwH,MAAM,CAAC0D;YAC1B;YACA,OAAO;gBAAED;gBAAIE;YAAI;QACnB,CAAA;QAEAZ,wBAAwB9H,OAAO,GAAG;YAACuI;YAAQL;SAAiB;IAC9D;IACA,0DAA0D;IAC1DvN,UAAU;QACRkN,SAAS,CAACc;YACR,IACEA,KAAK1M,IAAI,KAAK0J,aAAa1J,IAAI,IAC/B0M,KAAKhM,KAAK,KAAKgJ,aAAahJ,KAAK,IACjCgM,KAAKjM,IAAI,KAAKiJ,aAAajJ,IAAI,EAC/B;gBACA,OAAOiM;YACT;YACA,OAAOhD;QACT;IACF,GAAG;QAACA;KAAa;IAEjB,MAAM,CAACjG,mBAAmBwI,iBAAiB,GAAGJ,wBAAwB9H,OAAO;IAC7E,MAAM,CAAC+C,KAAK6F,OAAO,GAAG/N,SAAkB;IACxC,mDAAmD;IACnD,MAAMgO,aAAajO,OAAuC;IAC1D,MAAM0D,cAA2B7D,YAC/B,OAAO4D,OAAOK;QACZmH,kBAAkB7F,OAAO,GAAG3B;QAC5B6J,iBAAiB,SAAS7J;QAC1B,MAAMwC,oBACJnC,QAAQ+B,wBAAwB,IAAK,CAAA,CAACK,KAA2BA,IAAG;QACtE+H,WAAW7I,OAAO,GAAG,EAAE;QACvB4I,OAAO;QACP,MAAM,EAAEE,WAAW,EAAE,GAAGpK,WAAW,CAAC;QACpC,IAAI,CAACoH,iBAAiB9F,OAAO,CAACoD,GAAG,CAAC/E,MAAMpC,IAAI,KAAK,CAAC6M,aAAa;YAC7D,MAAMjE,UAAUpJ,gBAAgB4C,MAAMpC,IAAI;YAC1C,MAAM8B,YAAYD,gBAAgBO,MAAM1B,KAAK;YAC7C,IAAI;gBACF,MAAM4H,QAAQM,SAAS9G;YACzB,EAAE,OAAO+G,GAAG;gBACV+D,WAAW7I,OAAO,GAAG;gBACrB4I,OAAO9D;gBACP,MAAMA;YACR;QACF;QACAjE,kBAAkB;YAChB,IAAInC,QAAQG,YAAY,EAAE;gBACxBoG;YACF;YACA4C,SAASxJ;YACTwK,WAAW7I,OAAO,AAAC,CAAC,EAAE;YACtB6I,WAAW7I,OAAO,GAAG;YACrBkI,iBAAiB,YAAY7J;QAC/B;IACF,GACA;QAAC6J;QAAkB3D;KAAQ;IAG7B,MAAMhG,gBAA+B9D,YAAY,CAAC4D;QAChD,IAAIyH,iBAAiB9F,OAAO,CAACoD,GAAG,CAAC/E,MAAMpC,IAAI,GAAG;YAC5C;QACF;QACA,MAAM4I,UAAUpJ,gBAAgB4C,MAAMpC,IAAI;QAC1C,MAAM8B,YAAYD,gBAAgBO,MAAM1B,KAAK;QAC7C1B,YAAY4J,SAAS9G;QACpBgL,WAAmBC,wBAAwB,GAAG3K,MAAMpC,IAAI;IAC3D,GAAG,EAAE;IAELtB,UAAU;QACR,MAAMsO,WAAW;YACf,MAAM5K,QAAQ/B,WAAW,IAAIY,IAAIC,OAAOC,QAAQ,CAACC,IAAI;YACrDiB,YAAYD,OAAO;gBAAEQ,cAAc;YAAK,GAAGiE,KAAK,CAAC,CAACC;gBAChDC,QAAQC,GAAG,CAAC,gCAAgCF;YAC9C;QACF;QACA5F,OAAO+L,gBAAgB,CAAC,YAAYD;QACpC,OAAO;YACL9L,OAAOgM,mBAAmB,CAAC,YAAYF;QACzC;IACF,GAAG;QAAC3K;KAAY;IAEhB3D,UAAU;QACR,MAAMsO,WAAW,CAAChN,MAAcU;YAC9B,MAAMmE,KAAK;gBACT,MAAMvE,MAAM,IAAIW,IAAIC,OAAOC,QAAQ,CAACC,IAAI;gBACxCd,IAAIC,QAAQ,GAAGP;gBACfM,IAAI6M,MAAM,GAAGzM;gBACbJ,IAAIG,IAAI,GAAG;gBACX4B,YAAYhC,WAAWC,MAAM;oBAC3BuM,aAAa;oBACbjK,cAAc;gBAChB,GACGiE,KAAK,CAAC,CAACC;oBACNC,QAAQC,GAAG,CAAC,4CAA4CF;gBAC1D,GACCQ,OAAO,CAAC;oBACP,IAAItH,SAAS,QAAQ;wBACnBkB,OAAO4B,OAAO,CAACC,SAAS,CACtB;4BACE,GAAG7B,OAAO4B,OAAO,CAACE,KAAK;4BACvBC,eAAe3C,IAAIC,QAAQ,KAAKW,OAAOC,QAAQ,CAACZ,QAAQ;wBAC1D,GACA,IACAD;oBAEJ;gBACF;YACJ;YACA,IAAIsM,WAAW7I,OAAO,EAAE;gBACtB6I,WAAW7I,OAAO,CAACxB,IAAI,CAACsC;YAC1B,OAAO;gBACLvG,gBAAgBuG;YAClB;QACF;QACA4F,kBAAkBrD,GAAG,CAAC4F;QACtB,OAAO;YACLvC,kBAAkB3B,MAAM,CAACkE;QAC3B;IACF,GAAG;QAAC3K;QAAaoI;KAAkB;IAEnC,MAAM2C,eACJtG,QAAQ,OACJzI,cAAcwJ,YAAY;QAAExB,OAAOS;IAAI,KACvCzI,cAAca,MAAM;QAAE+I,IAAIH,eAAe1F,MAAMpC,IAAI;IAAE;IAC3D,MAAMqN,cAAchP,cAClBa,MACA;QAAE+I,IAAI;IAAO,GACb5J,cAAckJ,oBAAoB;QAAEd;IAAO,GAAG2G;IAEhD,OAAO/O,cACL2D,eACA;QACEsL,OAAO;YACLlL;YACAC;YACAC;YACAmB;YACA4E,gBAAgB1J,OAAO,IAAImL,OAAgB/F,OAAO;QACpD;IACF,GACAsJ;AAEJ;AAEA,OAAO,SAASE,OAAO,EACrB7D,eAAe9I,wBAAwB,EAGxC;IACC,MAAM4M,iBAAiBhO,gBAAgBkK,aAAa1J,IAAI;IACxD,MAAMyN,mBAAmB5L,gBAAgB6H,aAAahJ,KAAK;IAC3D,OAAOrC,cACLY,MACA;QACEuO;QACAC;IACF,GACApP,cAAcoL,aAAa;QAAEC;IAAa;AAE9C;AAEA,MAAMgE,6BAGF;IACFnB,IAAI,IAAMxG,qBAAqB;IAC/B0G,KAAK,IAAM1G,qBAAqB;AAClC;AAEA;;;CAGC,GACD,OAAO,SAAS4H,sBAAsB,EACpCvL,KAAK,EACLwL,UAAU,EAIX;IACC,MAAMR,eAAe/O,cAAca,MAAM;QAAE+I,IAAIH,eAAe1F,MAAMpC,IAAI;IAAE;IAC1E,MAAMqN,cAAchP,cAClBa,MACA;QAAE+I,IAAI;IAAO,GACb5J,cAAc,QAAQ;QAAE2H,MAAM;QAAchF,SAAS,GAAG4M,YAAY;IAAC,IACrER;IAEF,OAAO/O,cACLS,UACA,MACAT,cACE2D,eACA;QACEsL,OAAO;YACLlL;YACAC,aAAa0D,qBAAqB;YAClCzD,eAAeyD,qBAAqB;YACpCtC,mBAAmBiK;YACnBrF,gBAAgB,IAAIyB;QACtB;IACF,GACAuD;AAGN"}
|