toiljs 0.0.4 → 0.0.6
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/.idea/prettier.xml +1 -0
- package/as-pect.config.js +1 -1
- package/build/backend/.tsbuildinfo +1 -1
- package/build/backend/index.js +1 -2
- package/build/cli/.tsbuildinfo +1 -1
- package/build/cli/configure.d.ts +15 -0
- package/build/cli/configure.js +201 -0
- package/build/cli/create.d.ts +4 -0
- package/build/cli/create.js +193 -68
- package/build/cli/features.d.ts +23 -0
- package/build/cli/features.js +85 -0
- package/build/cli/index.js +42 -2
- package/build/cli/proc.d.ts +1 -0
- package/build/cli/proc.js +11 -0
- package/build/cli/ui.js +1 -2
- package/build/cli/validate.d.ts +4 -0
- package/build/cli/validate.js +19 -0
- package/build/client/.tsbuildinfo +1 -1
- package/build/client/Link.d.ts +8 -0
- package/build/client/Link.js +44 -0
- package/build/client/NavLink.d.ts +14 -0
- package/build/client/NavLink.js +37 -0
- package/build/client/Router.d.ts +7 -0
- package/build/client/Router.js +55 -0
- package/build/client/channel/channel.d.ts +23 -0
- package/build/client/channel/channel.js +94 -0
- package/build/client/error-boundary.d.ts +16 -0
- package/build/client/error-boundary.js +19 -0
- package/build/client/head/head.d.ts +26 -0
- package/build/client/head/head.js +87 -0
- package/build/client/head.d.ts +26 -0
- package/build/client/head.js +87 -0
- package/build/client/hooks.d.ts +17 -0
- package/build/client/hooks.js +48 -0
- package/build/client/index.d.ts +18 -6
- package/build/client/index.js +10 -3
- package/build/client/lazy.d.ts +16 -0
- package/build/client/lazy.js +53 -0
- package/build/client/match.js +7 -0
- package/build/client/mount.d.ts +2 -0
- package/build/client/mount.js +13 -0
- package/build/client/navigation/Link.d.ts +8 -0
- package/build/client/navigation/Link.js +44 -0
- package/build/client/navigation/NavLink.d.ts +14 -0
- package/build/client/navigation/NavLink.js +37 -0
- package/build/client/navigation/navigation.d.ts +13 -0
- package/build/client/navigation/navigation.js +97 -0
- package/build/client/navigation/prefetch.d.ts +11 -0
- package/build/client/navigation/prefetch.js +100 -0
- package/build/client/navigation/scroll.d.ts +8 -0
- package/build/client/navigation/scroll.js +36 -0
- package/build/client/navigation.d.ts +13 -0
- package/build/client/navigation.js +97 -0
- package/build/client/params-context.d.ts +2 -0
- package/build/client/params-context.js +2 -0
- package/build/client/prefetch.d.ts +11 -0
- package/build/client/prefetch.js +100 -0
- package/build/client/routing/Router.d.ts +7 -0
- package/build/client/routing/Router.js +55 -0
- package/build/client/routing/error-boundary.d.ts +16 -0
- package/build/client/routing/error-boundary.js +19 -0
- package/build/client/routing/hooks.d.ts +17 -0
- package/build/client/routing/hooks.js +48 -0
- package/build/client/routing/lazy.d.ts +16 -0
- package/build/client/routing/lazy.js +53 -0
- package/build/client/routing/match.d.ts +2 -0
- package/build/client/routing/match.js +32 -0
- package/build/client/routing/mount.d.ts +2 -0
- package/build/client/routing/mount.js +13 -0
- package/build/client/routing/params-context.d.ts +2 -0
- package/build/client/routing/params-context.js +2 -0
- package/build/client/scroll.d.ts +8 -0
- package/build/client/scroll.js +36 -0
- package/build/client/types.d.ts +27 -0
- package/build/client/types.js +1 -0
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/compiler/config.d.ts +2 -0
- package/build/compiler/config.js +14 -2
- package/build/compiler/docs.d.ts +10 -0
- package/build/compiler/docs.js +59 -0
- package/build/compiler/generate.js +144 -16
- package/build/compiler/index.d.ts +4 -2
- package/build/compiler/index.js +4 -3
- package/build/compiler/plugin.js +16 -1
- package/build/compiler/routes.js +5 -1
- package/build/compiler/vite.d.ts +1 -1
- package/build/compiler/vite.js +17 -1
- package/build/io/.tsbuildinfo +1 -1
- package/build/io/BinaryWriter.js +2 -2
- package/eslint.config.js +1 -1
- package/examples/basic/.toil/docs/cli.md +3 -0
- package/examples/basic/.toil/docs/client.md +3 -0
- package/examples/basic/.toil/docs/index.md +3 -0
- package/examples/basic/.toil/docs/routing.md +3 -0
- package/examples/basic/.toil/docs/server.md +3 -0
- package/examples/basic/.toil/docs/styling.md +3 -0
- package/examples/basic/.toil/entry.tsx +3 -8
- package/examples/basic/.toil/globals.ts +6 -0
- package/examples/basic/.toil/index.html +16 -12
- package/examples/basic/.toil/public/images/.gitkeep +1 -0
- package/examples/basic/.toil/public/images/logo.svg +37 -0
- package/examples/basic/.toil/public/robots.txt +2 -0
- package/examples/basic/.toil/routes.ts +9 -7
- package/examples/basic/build/client/assets/404-Bq0jNTUo.js +1 -0
- package/examples/basic/build/client/assets/_...slug_-CXKf6qnB.js +1 -0
- package/examples/basic/build/client/assets/_id_-BadAyQnb.js +1 -0
- package/examples/basic/build/client/assets/about-BOhoEcEO.js +1 -0
- package/examples/basic/build/client/assets/get-started-BIXpcjkT.js +9 -0
- package/examples/basic/build/client/assets/index-BmqcTaBB.js +1 -0
- package/examples/basic/build/client/assets/io-DEVjjaJj.js +1 -0
- package/examples/basic/build/client/assets/layout-DJegirdz.js +1 -0
- package/examples/basic/build/client/assets/react-DEQrz1q7.js +9 -0
- package/examples/basic/build/client/assets/rolldown-runtime-KL5VtC6j.js +1 -0
- package/examples/basic/build/client/assets/routes-BYWn6TxK.js +1 -0
- package/examples/basic/build/client/css/style.css +2 -0
- package/examples/basic/build/client/images/.gitkeep +1 -0
- package/examples/basic/build/client/images/logo.svg +37 -0
- package/examples/basic/build/client/index.html +17 -0
- package/examples/basic/build/client/robots.txt +2 -0
- package/examples/basic/client/404.tsx +2 -5
- package/examples/basic/client/components/.gitkeep +1 -0
- package/examples/basic/client/components/Footer.tsx +8 -0
- package/examples/basic/client/components/HoneycombBackground.tsx +162 -0
- package/examples/basic/client/layout.tsx +43 -26
- package/examples/basic/client/public/favicon.ico +0 -0
- package/examples/basic/client/public/images/.gitkeep +1 -0
- package/examples/basic/client/public/images/logo.svg +37 -0
- package/examples/basic/client/public/index.html +16 -0
- package/examples/basic/client/public/robots.txt +2 -0
- package/examples/basic/client/routes/about.tsx +1 -3
- package/examples/basic/client/routes/blog/[id].tsx +2 -4
- package/examples/basic/client/routes/docs/[...slug].tsx +3 -6
- package/examples/basic/client/routes/get-started.tsx +84 -0
- package/examples/basic/client/routes/index.tsx +74 -7
- package/examples/basic/client/routes/io.tsx +3 -7
- package/examples/basic/client/styles/main.css +461 -0
- package/examples/basic/client/toil.tsx +7 -0
- package/examples/basic/node_modules/.bin/toilinit +16 -0
- package/examples/basic/node_modules/.bin/toilinit.cmd +17 -0
- package/examples/basic/node_modules/.bin/toilinit.ps1 +28 -0
- package/examples/basic/node_modules/.bin/toilscript +16 -0
- package/examples/basic/node_modules/.bin/toilscript.cmd +17 -0
- package/examples/basic/node_modules/.bin/toilscript.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-as +16 -0
- package/examples/basic/node_modules/.bin/wasm-as.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-as.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-ctor-eval +16 -0
- package/examples/basic/node_modules/.bin/wasm-ctor-eval.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-ctor-eval.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-dis +16 -0
- package/examples/basic/node_modules/.bin/wasm-dis.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-dis.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-merge +16 -0
- package/examples/basic/node_modules/.bin/wasm-merge.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-merge.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-metadce +16 -0
- package/examples/basic/node_modules/.bin/wasm-metadce.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-metadce.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-opt +16 -0
- package/examples/basic/node_modules/.bin/wasm-opt.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-opt.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-reduce +16 -0
- package/examples/basic/node_modules/.bin/wasm-reduce.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-reduce.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-shell +16 -0
- package/examples/basic/node_modules/.bin/wasm-shell.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-shell.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm2js +16 -0
- package/examples/basic/node_modules/.bin/wasm2js.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm2js.ps1 +28 -0
- package/examples/basic/node_modules/.package-lock.json +49 -1
- package/examples/basic/node_modules/.vite/deps/_metadata.json +9 -9
- package/examples/basic/node_modules/binaryen/LICENSE +201 -0
- package/examples/basic/node_modules/binaryen/README.md +1362 -0
- package/examples/basic/node_modules/binaryen/bin/package.json +3 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-as +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-ctor-eval +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-dis +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-merge +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-metadce +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-opt +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-reduce +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-shell +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm2js +0 -0
- package/examples/basic/node_modules/binaryen/index.d.ts +2371 -0
- package/examples/basic/node_modules/binaryen/index.js +30552 -0
- package/examples/basic/node_modules/binaryen/package.json +50 -0
- package/examples/basic/node_modules/long/LICENSE +202 -0
- package/examples/basic/node_modules/long/README.md +286 -0
- package/examples/basic/node_modules/long/index.d.ts +2 -0
- package/examples/basic/node_modules/long/index.js +1581 -0
- package/examples/basic/node_modules/long/package.json +58 -0
- package/examples/basic/node_modules/long/types.d.ts +474 -0
- package/examples/basic/node_modules/long/umd/index.d.ts +3 -0
- package/examples/basic/node_modules/long/umd/index.js +1622 -0
- package/examples/basic/node_modules/long/umd/package.json +3 -0
- package/examples/basic/node_modules/long/umd/types.d.ts +474 -0
- package/examples/basic/node_modules/toilscript/LICENSE +201 -0
- package/examples/basic/node_modules/toilscript/NOTICE +94 -0
- package/examples/basic/node_modules/toilscript/README.md +66 -0
- package/examples/basic/node_modules/toilscript/bin/toilinit.js +468 -0
- package/examples/basic/node_modules/toilscript/bin/toilscript.js +35 -0
- package/examples/basic/node_modules/toilscript/dist/cli.d.ts +4 -0
- package/examples/basic/node_modules/toilscript/dist/cli.generated.d.ts +10027 -0
- package/examples/basic/node_modules/toilscript/dist/cli.js +24474 -0
- package/examples/basic/node_modules/toilscript/dist/cli.js.map +7 -0
- package/examples/basic/node_modules/toilscript/dist/importmap.json +9 -0
- package/examples/basic/node_modules/toilscript/dist/toilscript.d.ts +4 -0
- package/examples/basic/node_modules/toilscript/dist/toilscript.generated.d.ts +11242 -0
- package/examples/basic/node_modules/toilscript/dist/toilscript.js +337 -0
- package/examples/basic/node_modules/toilscript/dist/toilscript.js.map +7 -0
- package/examples/basic/node_modules/toilscript/dist/transform.cjs +1 -0
- package/examples/basic/node_modules/toilscript/dist/transform.d.ts +1 -0
- package/examples/basic/node_modules/toilscript/dist/transform.js +1 -0
- package/examples/basic/node_modules/toilscript/dist/web.js +22 -0
- package/examples/basic/node_modules/toilscript/lib/binaryen.d.ts +2 -0
- package/examples/basic/node_modules/toilscript/lib/binaryen.js +2 -0
- package/examples/basic/node_modules/toilscript/package.json +115 -0
- package/examples/basic/node_modules/toilscript/std/README.md +6 -0
- package/examples/basic/node_modules/toilscript/std/assembly/array.ts +550 -0
- package/examples/basic/node_modules/toilscript/std/assembly/arraybuffer.ts +77 -0
- package/examples/basic/node_modules/toilscript/std/assembly/atomics.ts +127 -0
- package/examples/basic/node_modules/toilscript/std/assembly/bindings/asyncify.ts +16 -0
- package/examples/basic/node_modules/toilscript/std/assembly/bindings/dom.ts +291 -0
- package/examples/basic/node_modules/toilscript/std/assembly/bindings/node.ts +6 -0
- package/examples/basic/node_modules/toilscript/std/assembly/bitflags.ts +53 -0
- package/examples/basic/node_modules/toilscript/std/assembly/builtins.ts +2650 -0
- package/examples/basic/node_modules/toilscript/std/assembly/byteslice.ts +177 -0
- package/examples/basic/node_modules/toilscript/std/assembly/compat.ts +2 -0
- package/examples/basic/node_modules/toilscript/std/assembly/console.ts +42 -0
- package/examples/basic/node_modules/toilscript/std/assembly/crypto.ts +9 -0
- package/examples/basic/node_modules/toilscript/std/assembly/dataview.ts +181 -0
- package/examples/basic/node_modules/toilscript/std/assembly/date.ts +375 -0
- package/examples/basic/node_modules/toilscript/std/assembly/diagnostics.ts +11 -0
- package/examples/basic/node_modules/toilscript/std/assembly/encoding.ts +151 -0
- package/examples/basic/node_modules/toilscript/std/assembly/endian.ts +45 -0
- package/examples/basic/node_modules/toilscript/std/assembly/error.ts +44 -0
- package/examples/basic/node_modules/toilscript/std/assembly/fixedarray.ts +173 -0
- package/examples/basic/node_modules/toilscript/std/assembly/fixedmap.ts +326 -0
- package/examples/basic/node_modules/toilscript/std/assembly/fixedset.ts +275 -0
- package/examples/basic/node_modules/toilscript/std/assembly/function.ts +42 -0
- package/examples/basic/node_modules/toilscript/std/assembly/index.d.ts +2892 -0
- package/examples/basic/node_modules/toilscript/std/assembly/iterator.ts +35 -0
- package/examples/basic/node_modules/toilscript/std/assembly/map.ts +269 -0
- package/examples/basic/node_modules/toilscript/std/assembly/math.ts +3289 -0
- package/examples/basic/node_modules/toilscript/std/assembly/memory.ts +123 -0
- package/examples/basic/node_modules/toilscript/std/assembly/number.ts +388 -0
- package/examples/basic/node_modules/toilscript/std/assembly/object.ts +36 -0
- package/examples/basic/node_modules/toilscript/std/assembly/performance.ts +9 -0
- package/examples/basic/node_modules/toilscript/std/assembly/pointer.ts +80 -0
- package/examples/basic/node_modules/toilscript/std/assembly/polyfills.ts +27 -0
- package/examples/basic/node_modules/toilscript/std/assembly/process.ts +50 -0
- package/examples/basic/node_modules/toilscript/std/assembly/reference.ts +48 -0
- package/examples/basic/node_modules/toilscript/std/assembly/regexp.ts +12 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/README.md +83 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/common.ts +81 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index-incremental.ts +2 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index-memory.ts +1 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index-minimal.ts +2 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index-stub.ts +1 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index.d.ts +37 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/itcms.ts +419 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/memory-runtime.ts +94 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/rtrace.ts +15 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/stub.ts +133 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/tcms.ts +254 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/tlsf.ts +592 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt.ts +90 -0
- package/examples/basic/node_modules/toilscript/std/assembly/set.ts +225 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/feature.ts +68 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/runtime.ts +13 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/target.ts +11 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/tsconfig.json +11 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/typeinfo.ts +72 -0
- package/examples/basic/node_modules/toilscript/std/assembly/staticarray.ts +423 -0
- package/examples/basic/node_modules/toilscript/std/assembly/string.ts +850 -0
- package/examples/basic/node_modules/toilscript/std/assembly/symbol.ts +114 -0
- package/examples/basic/node_modules/toilscript/std/assembly/table.ts +16 -0
- package/examples/basic/node_modules/toilscript/std/assembly/toilscript.ts +16 -0
- package/examples/basic/node_modules/toilscript/std/assembly/tsconfig.json +6 -0
- package/examples/basic/node_modules/toilscript/std/assembly/typedarray.ts +1954 -0
- package/examples/basic/node_modules/toilscript/std/assembly/uri.ts +17 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/bytes.ts +107 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/casemap.ts +497 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/error.ts +58 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/hash.ts +117 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/math.ts +1922 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/memory.ts +290 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/number.ts +873 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/sort.ts +313 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/string.ts +1202 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/uri.ts +275 -0
- package/examples/basic/node_modules/toilscript/std/assembly/vector.ts +4 -0
- package/examples/basic/node_modules/toilscript/std/assembly.json +16 -0
- package/examples/basic/node_modules/toilscript/std/portable/index.d.ts +461 -0
- package/examples/basic/node_modules/toilscript/std/portable/index.js +416 -0
- package/examples/basic/node_modules/toilscript/std/portable.json +11 -0
- package/examples/basic/node_modules/toilscript/std/types/assembly/index.d.ts +1 -0
- package/examples/basic/node_modules/toilscript/std/types/assembly/package.json +3 -0
- package/examples/basic/node_modules/toilscript/std/types/portable/index.d.ts +1 -0
- package/examples/basic/node_modules/toilscript/std/types/portable/package.json +3 -0
- package/examples/basic/node_modules/toilscript/tsconfig-base.json +13 -0
- package/examples/basic/node_modules/toilscript/util/README.md +23 -0
- package/examples/basic/node_modules/toilscript/util/browser/fs.js +1 -0
- package/examples/basic/node_modules/toilscript/util/browser/module.js +5 -0
- package/examples/basic/node_modules/toilscript/util/browser/path.js +520 -0
- package/examples/basic/node_modules/toilscript/util/browser/process.js +59 -0
- package/examples/basic/node_modules/toilscript/util/browser/url.js +23 -0
- package/examples/basic/node_modules/toilscript/util/cpu.d.ts +9 -0
- package/examples/basic/node_modules/toilscript/util/cpu.js +42 -0
- package/examples/basic/node_modules/toilscript/util/find.d.ts +6 -0
- package/examples/basic/node_modules/toilscript/util/find.js +20 -0
- package/examples/basic/node_modules/toilscript/util/node.d.ts +21 -0
- package/examples/basic/node_modules/toilscript/util/node.js +34 -0
- package/examples/basic/node_modules/toilscript/util/options.d.ts +70 -0
- package/examples/basic/node_modules/toilscript/util/options.js +262 -0
- package/examples/basic/node_modules/toilscript/util/terminal.d.ts +52 -0
- package/examples/basic/node_modules/toilscript/util/terminal.js +35 -0
- package/examples/basic/node_modules/toilscript/util/text.d.ts +26 -0
- package/examples/basic/node_modules/toilscript/util/text.js +114 -0
- package/examples/basic/node_modules/toilscript/util/tsconfig.json +9 -0
- package/examples/basic/node_modules/toilscript/util/web.d.ts +11 -0
- package/examples/basic/node_modules/toilscript/util/web.js +33 -0
- package/examples/basic/package-lock.json +50 -1
- package/examples/basic/package.json +5 -2
- package/examples/basic/server/index.ts +3 -0
- package/examples/basic/server/main.ts +6 -0
- package/examples/basic/server/tsconfig.json +7 -0
- package/examples/basic/toil-env.d.ts +20 -1
- package/examples/basic/toil.config.ts +2 -5
- package/examples/basic/toilconfig.json +30 -0
- package/package.json +2 -2
- package/presets/eslint.js +2 -7
- package/presets/no-uint8array-tostring.js +4 -5
- package/presets/prettier.json +8 -1
- package/src/backend/index.ts +11 -18
- package/src/cli/configure.ts +272 -0
- package/src/cli/create.ts +267 -82
- package/src/cli/features.ts +128 -0
- package/src/cli/index.ts +44 -3
- package/src/cli/proc.ts +20 -0
- package/src/cli/ui.ts +4 -6
- package/src/cli/validate.ts +31 -0
- package/src/client/head/head.ts +140 -0
- package/src/client/index.ts +39 -9
- package/src/client/navigation/Link.tsx +99 -0
- package/src/client/navigation/NavLink.tsx +86 -0
- package/src/client/navigation/navigation.ts +142 -0
- package/src/client/navigation/prefetch.ts +130 -0
- package/src/client/navigation/scroll.ts +53 -0
- package/src/client/routing/Router.tsx +95 -0
- package/src/client/routing/error-boundary.tsx +43 -0
- package/src/client/routing/hooks.ts +115 -0
- package/src/client/routing/lazy.ts +93 -0
- package/src/client/{match.ts → routing/match.ts} +11 -3
- package/src/client/routing/mount.tsx +28 -0
- package/src/client/routing/params-context.ts +10 -0
- package/src/client/types.ts +36 -0
- package/src/compiler/config.ts +26 -10
- package/src/compiler/docs.ts +87 -0
- package/src/compiler/generate.ts +180 -23
- package/src/compiler/index.ts +6 -4
- package/src/compiler/plugin.ts +22 -1
- package/src/compiler/routes.ts +13 -7
- package/src/compiler/vite.ts +28 -5
- package/src/io/BinaryReader.ts +1 -5
- package/src/io/BinaryWriter.ts +3 -3
- package/src/server/index.ts +3 -4
- package/src/server/tsconfig.json +4 -0
- package/templates/app/client/404.tsx +11 -0
- package/templates/app/client/components/.gitkeep +1 -0
- package/templates/app/client/components/Footer.tsx +8 -0
- package/templates/app/client/components/HoneycombBackground.tsx +162 -0
- package/templates/app/client/layout.tsx +53 -0
- package/templates/app/client/public/favicon.ico +0 -0
- package/templates/app/client/public/images/.gitkeep +1 -0
- package/templates/app/client/public/images/logo.svg +37 -0
- package/templates/app/client/public/index.html +16 -0
- package/templates/app/client/public/robots.txt +2 -0
- package/templates/app/client/routes/about.tsx +11 -0
- package/templates/app/client/routes/blog/[id].tsx +12 -0
- package/templates/app/client/routes/docs/[...slug].tsx +12 -0
- package/templates/app/client/routes/get-started.tsx +84 -0
- package/templates/app/client/routes/index.tsx +80 -0
- package/templates/app/client/routes/io.tsx +24 -0
- package/templates/app/client/styles/main.css +461 -0
- package/templates/app/client/toil.tsx +7 -0
- package/test/channel.test.ts +1 -1
- package/test/configure.test.ts +90 -0
- package/test/features.test.ts +111 -0
- package/test/head.test.ts +35 -0
- package/test/io.test.ts +8 -0
- package/test/navlink.test.ts +28 -0
- package/test/routes.test.ts +16 -1
- package/test/validate.test.ts +42 -0
- package/vitest.config.ts +1 -1
- package/examples/basic/dist/assets/404-D1bS2aH_.js +0 -1
- package/examples/basic/dist/assets/_...slug_-wR3shlWn.js +0 -1
- package/examples/basic/dist/assets/_id_-EWYvHfi2.js +0 -1
- package/examples/basic/dist/assets/about-Ddvj1tjF.js +0 -1
- package/examples/basic/dist/assets/index-CdG0me90.js +0 -1
- package/examples/basic/dist/assets/io-CODNJU57.js +0 -1
- package/examples/basic/dist/assets/layout-C15ZTPYI.js +0 -1
- package/examples/basic/dist/assets/react-JbAfoxYe.js +0 -9
- package/examples/basic/dist/assets/rolldown-runtime-1VNLd2iN.js +0 -1
- package/examples/basic/dist/assets/routes-GoydenoY.js +0 -1
- package/examples/basic/dist/index.html +0 -12
- package/src/client/runtime.tsx +0 -190
- /package/src/client/{channel.ts → channel/channel.ts} +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
function metaKey(m) {
|
|
3
|
+
if (m.name !== undefined)
|
|
4
|
+
return `name:${m.name}`;
|
|
5
|
+
if (m.property !== undefined)
|
|
6
|
+
return `property:${m.property}`;
|
|
7
|
+
return `meta:${JSON.stringify(m)}`;
|
|
8
|
+
}
|
|
9
|
+
export function mergeHead(specs) {
|
|
10
|
+
let title;
|
|
11
|
+
let titleTemplate;
|
|
12
|
+
const meta = new Map();
|
|
13
|
+
const link = new Map();
|
|
14
|
+
for (const spec of specs) {
|
|
15
|
+
if (spec.title !== undefined)
|
|
16
|
+
title = spec.title;
|
|
17
|
+
if (spec.titleTemplate !== undefined)
|
|
18
|
+
titleTemplate = spec.titleTemplate;
|
|
19
|
+
for (const m of spec.meta ?? [])
|
|
20
|
+
meta.set(metaKey(m), m);
|
|
21
|
+
for (const l of spec.link ?? [])
|
|
22
|
+
link.set(`${l.rel}:${l.href}`, l);
|
|
23
|
+
}
|
|
24
|
+
const resolvedTitle = title !== undefined && titleTemplate !== undefined
|
|
25
|
+
? titleTemplate.replace('%s', title)
|
|
26
|
+
: title;
|
|
27
|
+
return { title: resolvedTitle, meta: [...meta.values()], link: [...link.values()] };
|
|
28
|
+
}
|
|
29
|
+
const entries = new Map();
|
|
30
|
+
let order = [];
|
|
31
|
+
let seq = 0;
|
|
32
|
+
let baseTitle = null;
|
|
33
|
+
function setAttrs(el, attrs) {
|
|
34
|
+
el.setAttribute('data-toil-head', '');
|
|
35
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
36
|
+
if (value !== undefined)
|
|
37
|
+
el.setAttribute(key, value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function apply() {
|
|
41
|
+
if (typeof document === 'undefined')
|
|
42
|
+
return;
|
|
43
|
+
if (baseTitle === null)
|
|
44
|
+
baseTitle = document.title;
|
|
45
|
+
const resolved = mergeHead(order.map((id) => entries.get(id)).filter((s) => !!s));
|
|
46
|
+
document.title = resolved.title ?? baseTitle;
|
|
47
|
+
for (const stale of document.head.querySelectorAll('[data-toil-head]'))
|
|
48
|
+
stale.remove();
|
|
49
|
+
for (const m of resolved.meta) {
|
|
50
|
+
const el = document.createElement('meta');
|
|
51
|
+
setAttrs(el, m);
|
|
52
|
+
document.head.appendChild(el);
|
|
53
|
+
}
|
|
54
|
+
for (const l of resolved.link) {
|
|
55
|
+
const el = document.createElement('link');
|
|
56
|
+
setAttrs(el, l);
|
|
57
|
+
document.head.appendChild(el);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function addHead(spec) {
|
|
61
|
+
const id = ++seq;
|
|
62
|
+
entries.set(id, spec);
|
|
63
|
+
order.push(id);
|
|
64
|
+
apply();
|
|
65
|
+
return id;
|
|
66
|
+
}
|
|
67
|
+
function removeHead(id) {
|
|
68
|
+
entries.delete(id);
|
|
69
|
+
order = order.filter((x) => x !== id);
|
|
70
|
+
apply();
|
|
71
|
+
}
|
|
72
|
+
export function useHead(spec) {
|
|
73
|
+
const json = JSON.stringify(spec);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const id = addHead(JSON.parse(json));
|
|
76
|
+
return () => {
|
|
77
|
+
removeHead(id);
|
|
78
|
+
};
|
|
79
|
+
}, [json]);
|
|
80
|
+
}
|
|
81
|
+
export function useTitle(title) {
|
|
82
|
+
useHead({ title });
|
|
83
|
+
}
|
|
84
|
+
export function Head(props) {
|
|
85
|
+
useHead(props);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RouteParams } from './match.js';
|
|
2
|
+
import { navigate, type NavigateOptions } from './navigation.js';
|
|
3
|
+
export interface RouterInstance {
|
|
4
|
+
push(href: string, options?: NavigateOptions): void;
|
|
5
|
+
replace(href: string): void;
|
|
6
|
+
back(): void;
|
|
7
|
+
forward(): void;
|
|
8
|
+
refresh(): void;
|
|
9
|
+
prefetch(href: string): void;
|
|
10
|
+
}
|
|
11
|
+
export declare function useParams(): RouteParams;
|
|
12
|
+
export declare function useNavigate(): typeof navigate;
|
|
13
|
+
export declare function useRouter(): RouterInstance;
|
|
14
|
+
export declare function useLocation(): string;
|
|
15
|
+
export declare function usePathname(): string;
|
|
16
|
+
export declare function useSearchParams(): URLSearchParams;
|
|
17
|
+
export declare function useNavigationPending(): boolean;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { startTransition, useContext, useEffect, useMemo, useReducer, useSyncExternalStore, } from 'react';
|
|
2
|
+
import { back, forward, isNavigationPending, navigate, refresh, subscribeLocation, subscribePending, } from './navigation.js';
|
|
3
|
+
import { ParamsContext } from './params-context.js';
|
|
4
|
+
import { prefetch } from './prefetch.js';
|
|
5
|
+
const ROUTER = {
|
|
6
|
+
push: (href, options) => {
|
|
7
|
+
navigate(href, options);
|
|
8
|
+
},
|
|
9
|
+
replace: (href) => {
|
|
10
|
+
navigate(href, { replace: true });
|
|
11
|
+
},
|
|
12
|
+
back,
|
|
13
|
+
forward,
|
|
14
|
+
refresh,
|
|
15
|
+
prefetch,
|
|
16
|
+
};
|
|
17
|
+
export function useParams() {
|
|
18
|
+
return useContext(ParamsContext);
|
|
19
|
+
}
|
|
20
|
+
export function useNavigate() {
|
|
21
|
+
return navigate;
|
|
22
|
+
}
|
|
23
|
+
export function useRouter() {
|
|
24
|
+
return ROUTER;
|
|
25
|
+
}
|
|
26
|
+
function useLocationSubscription() {
|
|
27
|
+
const [, forceUpdate] = useReducer((n) => n + 1, 0);
|
|
28
|
+
useEffect(() => subscribeLocation(() => {
|
|
29
|
+
startTransition(() => {
|
|
30
|
+
forceUpdate();
|
|
31
|
+
});
|
|
32
|
+
}), []);
|
|
33
|
+
}
|
|
34
|
+
export function useLocation() {
|
|
35
|
+
useLocationSubscription();
|
|
36
|
+
return window.location.pathname;
|
|
37
|
+
}
|
|
38
|
+
export function usePathname() {
|
|
39
|
+
return useLocation();
|
|
40
|
+
}
|
|
41
|
+
export function useSearchParams() {
|
|
42
|
+
useLocationSubscription();
|
|
43
|
+
const search = window.location.search;
|
|
44
|
+
return useMemo(() => new URLSearchParams(search), [search]);
|
|
45
|
+
}
|
|
46
|
+
export function useNavigationPending() {
|
|
47
|
+
return useSyncExternalStore(subscribePending, isNavigationPending, () => false);
|
|
48
|
+
}
|
package/build/client/index.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
export { mount
|
|
2
|
-
export
|
|
3
|
-
export {
|
|
4
|
-
export type {
|
|
5
|
-
export {
|
|
6
|
-
export type {
|
|
1
|
+
export { mount } from './routing/mount.js';
|
|
2
|
+
export { Router } from './routing/Router.js';
|
|
3
|
+
export { Link } from './navigation/Link.js';
|
|
4
|
+
export type { LinkProps } from './navigation/Link.js';
|
|
5
|
+
export { NavLink, matchActive } from './navigation/NavLink.js';
|
|
6
|
+
export type { NavLinkProps, NavLinkState } from './navigation/NavLink.js';
|
|
7
|
+
export { navigate, back, forward, refresh } from './navigation/navigation.js';
|
|
8
|
+
export type { NavigateOptions } from './navigation/navigation.js';
|
|
9
|
+
export { useParams, useNavigate, useLocation, usePathname, useSearchParams, useRouter, useNavigationPending, } from './routing/hooks.js';
|
|
10
|
+
export type { RouterInstance } from './routing/hooks.js';
|
|
11
|
+
export { prefetch } from './navigation/prefetch.js';
|
|
12
|
+
export type { RouteDef, LayoutLoader, LayoutComponentLoader, NotFoundLoader, RouteErrorProps, } from './types.js';
|
|
13
|
+
export { matchRoute } from './routing/match.js';
|
|
14
|
+
export type { RouteParams } from './routing/match.js';
|
|
15
|
+
export { connectChannel, useChannel, resolveChannelUrl } from './channel/channel.js';
|
|
16
|
+
export type { Channel, ChannelOptions, ChannelHook, ChannelData } from './channel/channel.js';
|
|
17
|
+
export { useHead, useTitle, Head, mergeHead } from './head/head.js';
|
|
18
|
+
export type { HeadSpec, MetaTag, LinkTag, ResolvedHead } from './head/head.js';
|
package/build/client/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
export { mount
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
1
|
+
export { mount } from './routing/mount.js';
|
|
2
|
+
export { Router } from './routing/Router.js';
|
|
3
|
+
export { Link } from './navigation/Link.js';
|
|
4
|
+
export { NavLink, matchActive } from './navigation/NavLink.js';
|
|
5
|
+
export { navigate, back, forward, refresh } from './navigation/navigation.js';
|
|
6
|
+
export { useParams, useNavigate, useLocation, usePathname, useSearchParams, useRouter, useNavigationPending, } from './routing/hooks.js';
|
|
7
|
+
export { prefetch } from './navigation/prefetch.js';
|
|
8
|
+
export { matchRoute } from './routing/match.js';
|
|
9
|
+
export { connectChannel, useChannel, resolveChannelUrl } from './channel/channel.js';
|
|
10
|
+
export { useHead, useTitle, Head, mergeHead } from './head/head.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ComponentType, type ReactNode } from 'react';
|
|
2
|
+
import type { LayoutComponentLoader, LayoutLoader, NotFoundLoader, RouteDef, RouteErrorProps } from './types.js';
|
|
3
|
+
type Loader<P> = () => Promise<{
|
|
4
|
+
default: ComponentType<P>;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function loadingComponent(loader: Loader<object>): ComponentType<object>;
|
|
7
|
+
export declare function errorComponent(loader: Loader<RouteErrorProps>): ComponentType<RouteErrorProps>;
|
|
8
|
+
export declare function pageComponent(route: RouteDef): ComponentType;
|
|
9
|
+
export declare function resolveLayout(loader: NonNullable<LayoutLoader>): ComponentType<{
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function nestedLayout(loader: LayoutComponentLoader): ComponentType<{
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function resolveNotFound(loader: NonNullable<NotFoundLoader>): ComponentType;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { lazy } from 'react';
|
|
2
|
+
function memoLazy(cache, loader) {
|
|
3
|
+
let component = cache.get(loader);
|
|
4
|
+
if (!component) {
|
|
5
|
+
component = lazy(loader);
|
|
6
|
+
cache.set(loader, component);
|
|
7
|
+
}
|
|
8
|
+
return component;
|
|
9
|
+
}
|
|
10
|
+
const loadingCache = new Map();
|
|
11
|
+
export function loadingComponent(loader) {
|
|
12
|
+
return memoLazy(loadingCache, loader);
|
|
13
|
+
}
|
|
14
|
+
const errorCache = new Map();
|
|
15
|
+
export function errorComponent(loader) {
|
|
16
|
+
return memoLazy(errorCache, loader);
|
|
17
|
+
}
|
|
18
|
+
const pageCache = new Map();
|
|
19
|
+
export function pageComponent(route) {
|
|
20
|
+
let component = pageCache.get(route);
|
|
21
|
+
if (!component) {
|
|
22
|
+
component = lazy(route.load);
|
|
23
|
+
pageCache.set(route, component);
|
|
24
|
+
}
|
|
25
|
+
return component;
|
|
26
|
+
}
|
|
27
|
+
let layoutComponent = null;
|
|
28
|
+
let layoutLoader = null;
|
|
29
|
+
export function resolveLayout(loader) {
|
|
30
|
+
if (layoutLoader !== loader || !layoutComponent) {
|
|
31
|
+
layoutComponent = lazy(loader);
|
|
32
|
+
layoutLoader = loader;
|
|
33
|
+
}
|
|
34
|
+
return layoutComponent;
|
|
35
|
+
}
|
|
36
|
+
const nestedLayoutCache = new Map();
|
|
37
|
+
export function nestedLayout(loader) {
|
|
38
|
+
let component = nestedLayoutCache.get(loader);
|
|
39
|
+
if (!component) {
|
|
40
|
+
component = lazy(loader);
|
|
41
|
+
nestedLayoutCache.set(loader, component);
|
|
42
|
+
}
|
|
43
|
+
return component;
|
|
44
|
+
}
|
|
45
|
+
let notFoundComponent = null;
|
|
46
|
+
let notFoundLoader = null;
|
|
47
|
+
export function resolveNotFound(loader) {
|
|
48
|
+
if (notFoundLoader !== loader || !notFoundComponent) {
|
|
49
|
+
notFoundComponent = lazy(loader);
|
|
50
|
+
notFoundLoader = loader;
|
|
51
|
+
}
|
|
52
|
+
return notFoundComponent;
|
|
53
|
+
}
|
package/build/client/match.js
CHANGED
|
@@ -4,6 +4,13 @@ export function matchRoute(pattern, pathname) {
|
|
|
4
4
|
const params = {};
|
|
5
5
|
for (let i = 0; i < patternSegs.length; i++) {
|
|
6
6
|
const p = patternSegs[i];
|
|
7
|
+
if (p.startsWith('**')) {
|
|
8
|
+
params[p.slice(2)] = pathSegs
|
|
9
|
+
.slice(i)
|
|
10
|
+
.map((s) => decodeURIComponent(s))
|
|
11
|
+
.join('/');
|
|
12
|
+
return params;
|
|
13
|
+
}
|
|
7
14
|
if (p.startsWith('*')) {
|
|
8
15
|
const rest = pathSegs.slice(i);
|
|
9
16
|
if (rest.length === 0)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import { initNavigation } from './navigation.js';
|
|
4
|
+
import { startPrefetcher } from './prefetch.js';
|
|
5
|
+
import { Router } from './Router.js';
|
|
6
|
+
export function mount(routes, layout = null, notFound = null) {
|
|
7
|
+
const el = document.getElementById('root');
|
|
8
|
+
if (!el)
|
|
9
|
+
throw new Error('toil: #root element not found');
|
|
10
|
+
initNavigation();
|
|
11
|
+
createRoot(el).render(_jsx(Router, { routes: routes, layout: layout, notFound: notFound }));
|
|
12
|
+
startPrefetcher(routes);
|
|
13
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
+
export interface LinkProps extends Omit<ComponentPropsWithRef<'a'>, 'href'> {
|
|
3
|
+
href: string;
|
|
4
|
+
replace?: boolean;
|
|
5
|
+
scroll?: boolean;
|
|
6
|
+
prefetch?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function Link(props: LinkProps): ReactNode;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { navigate } from './navigation.js';
|
|
3
|
+
import { prefetch } from './prefetch.js';
|
|
4
|
+
function isExternalHref(href) {
|
|
5
|
+
try {
|
|
6
|
+
return new URL(href, window.location.href).origin !== window.location.origin;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function Link(props) {
|
|
13
|
+
const { href, replace = false, scroll = true, prefetch: prefetchProp = true, onClick, onPointerEnter, onFocus, children, ...rest } = props;
|
|
14
|
+
const handleClick = (event) => {
|
|
15
|
+
onClick?.(event);
|
|
16
|
+
if (event.defaultPrevented ||
|
|
17
|
+
event.button !== 0 ||
|
|
18
|
+
event.metaKey ||
|
|
19
|
+
event.ctrlKey ||
|
|
20
|
+
event.shiftKey ||
|
|
21
|
+
event.altKey ||
|
|
22
|
+
(rest.target !== undefined && rest.target !== '_self') ||
|
|
23
|
+
rest.download !== undefined ||
|
|
24
|
+
href.startsWith('#') ||
|
|
25
|
+
isExternalHref(href)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
navigate(href, { replace, scroll });
|
|
30
|
+
};
|
|
31
|
+
const warm = () => {
|
|
32
|
+
if (prefetchProp)
|
|
33
|
+
prefetch(href);
|
|
34
|
+
};
|
|
35
|
+
const handlePointerEnter = (event) => {
|
|
36
|
+
onPointerEnter?.(event);
|
|
37
|
+
warm();
|
|
38
|
+
};
|
|
39
|
+
const handleFocus = (event) => {
|
|
40
|
+
onFocus?.(event);
|
|
41
|
+
warm();
|
|
42
|
+
};
|
|
43
|
+
return (_jsx("a", { ...rest, ...(prefetchProp ? {} : { 'data-no-prefetch': '' }), href: href, onClick: handleClick, onPointerEnter: handlePointerEnter, onFocus: handleFocus, children: children }));
|
|
44
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { type LinkProps } from './Link.js';
|
|
3
|
+
export interface NavLinkState {
|
|
4
|
+
readonly isActive: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface NavLinkProps extends Omit<LinkProps, 'className' | 'style' | 'children'> {
|
|
7
|
+
className?: string | ((state: NavLinkState) => string | undefined);
|
|
8
|
+
style?: CSSProperties | ((state: NavLinkState) => CSSProperties | undefined);
|
|
9
|
+
children?: ReactNode | ((state: NavLinkState) => ReactNode);
|
|
10
|
+
end?: boolean;
|
|
11
|
+
activeClassName?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function matchActive(linkPath: string, currentPath: string, end: boolean): boolean;
|
|
14
|
+
export declare function NavLink(props: NavLinkProps): ReactNode;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLocation } from '../routing/hooks.js';
|
|
3
|
+
import { Link } from './Link.js';
|
|
4
|
+
function normalizePath(p) {
|
|
5
|
+
return p.length > 1 ? p.replace(/\/+$/, '') : p;
|
|
6
|
+
}
|
|
7
|
+
export function matchActive(linkPath, currentPath, end) {
|
|
8
|
+
const link = normalizePath(linkPath);
|
|
9
|
+
const current = normalizePath(currentPath);
|
|
10
|
+
if (current === link)
|
|
11
|
+
return true;
|
|
12
|
+
if (end)
|
|
13
|
+
return false;
|
|
14
|
+
if (link === '/')
|
|
15
|
+
return true;
|
|
16
|
+
return current.startsWith(link + '/');
|
|
17
|
+
}
|
|
18
|
+
export function NavLink(props) {
|
|
19
|
+
const { href, className, style, children, end = false, activeClassName = 'active', ...rest } = props;
|
|
20
|
+
const pathname = useLocation();
|
|
21
|
+
let linkPath = href;
|
|
22
|
+
try {
|
|
23
|
+
linkPath = new URL(href, window.location.href).pathname;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
linkPath = href;
|
|
27
|
+
}
|
|
28
|
+
const isActive = matchActive(linkPath, pathname, end);
|
|
29
|
+
const state = { isActive };
|
|
30
|
+
const resolvedClassName = typeof className === 'function'
|
|
31
|
+
? className(state)
|
|
32
|
+
: [className, isActive ? activeClassName : undefined].filter(Boolean).join(' ') ||
|
|
33
|
+
undefined;
|
|
34
|
+
const resolvedStyle = typeof style === 'function' ? style(state) : style;
|
|
35
|
+
const resolvedChildren = typeof children === 'function' ? children(state) : children;
|
|
36
|
+
return (_jsx(Link, { ...rest, href: href, className: resolvedClassName, style: resolvedStyle, "aria-current": isActive ? 'page' : undefined, children: resolvedChildren }));
|
|
37
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function settleNavigation(): void;
|
|
2
|
+
export declare function isNavigationPending(): boolean;
|
|
3
|
+
export declare function subscribePending(listener: () => void): () => void;
|
|
4
|
+
export interface NavigateOptions {
|
|
5
|
+
readonly replace?: boolean;
|
|
6
|
+
readonly scroll?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function initNavigation(): void;
|
|
9
|
+
export declare function navigate(href: string, options?: NavigateOptions): void;
|
|
10
|
+
export declare function back(): void;
|
|
11
|
+
export declare function forward(): void;
|
|
12
|
+
export declare function refresh(): void;
|
|
13
|
+
export declare function subscribeLocation(listener: () => void): () => void;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { enableManualScrollRestoration, planScroll, rememberScroll, } from './scroll.js';
|
|
2
|
+
const listeners = new Set();
|
|
3
|
+
let popstateBound = false;
|
|
4
|
+
let keyCounter = 0;
|
|
5
|
+
let currentKey = 'initial';
|
|
6
|
+
function nextKey() {
|
|
7
|
+
keyCounter += 1;
|
|
8
|
+
return `t${String(keyCounter)}`;
|
|
9
|
+
}
|
|
10
|
+
function notify() {
|
|
11
|
+
for (const listener of listeners)
|
|
12
|
+
listener();
|
|
13
|
+
}
|
|
14
|
+
let startedTick = 0;
|
|
15
|
+
let committedTick = 0;
|
|
16
|
+
const pendingListeners = new Set();
|
|
17
|
+
function emitPending() {
|
|
18
|
+
for (const listener of pendingListeners)
|
|
19
|
+
listener();
|
|
20
|
+
}
|
|
21
|
+
function beginNavigation() {
|
|
22
|
+
startedTick += 1;
|
|
23
|
+
emitPending();
|
|
24
|
+
}
|
|
25
|
+
export function settleNavigation() {
|
|
26
|
+
if (committedTick !== startedTick) {
|
|
27
|
+
committedTick = startedTick;
|
|
28
|
+
emitPending();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function isNavigationPending() {
|
|
32
|
+
return startedTick !== committedTick;
|
|
33
|
+
}
|
|
34
|
+
export function subscribePending(listener) {
|
|
35
|
+
pendingListeners.add(listener);
|
|
36
|
+
return () => {
|
|
37
|
+
pendingListeners.delete(listener);
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function initNavigation() {
|
|
41
|
+
enableManualScrollRestoration();
|
|
42
|
+
const state = window.history.state;
|
|
43
|
+
if (state?.__toilKey) {
|
|
44
|
+
currentKey = state.__toilKey;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
currentKey = nextKey();
|
|
48
|
+
window.history.replaceState({ ...state, __toilKey: currentKey }, '');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function navigate(href, options) {
|
|
52
|
+
beginNavigation();
|
|
53
|
+
rememberScroll(currentKey);
|
|
54
|
+
let hash = '';
|
|
55
|
+
try {
|
|
56
|
+
hash = new URL(href, window.location.href).hash;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
hash = '';
|
|
60
|
+
}
|
|
61
|
+
if (options?.replace) {
|
|
62
|
+
window.history.replaceState({ __toilKey: currentKey }, '', href);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
currentKey = nextKey();
|
|
66
|
+
window.history.pushState({ __toilKey: currentKey }, '', href);
|
|
67
|
+
}
|
|
68
|
+
planScroll({ hash, toTop: options?.scroll !== false });
|
|
69
|
+
notify();
|
|
70
|
+
}
|
|
71
|
+
export function back() {
|
|
72
|
+
window.history.back();
|
|
73
|
+
}
|
|
74
|
+
export function forward() {
|
|
75
|
+
window.history.forward();
|
|
76
|
+
}
|
|
77
|
+
export function refresh() {
|
|
78
|
+
notify();
|
|
79
|
+
}
|
|
80
|
+
function handlePopState(event) {
|
|
81
|
+
beginNavigation();
|
|
82
|
+
rememberScroll(currentKey);
|
|
83
|
+
const state = event.state;
|
|
84
|
+
currentKey = state?.__toilKey ?? 'initial';
|
|
85
|
+
planScroll({ restoreKey: currentKey, hash: window.location.hash, toTop: false });
|
|
86
|
+
notify();
|
|
87
|
+
}
|
|
88
|
+
export function subscribeLocation(listener) {
|
|
89
|
+
if (!popstateBound) {
|
|
90
|
+
window.addEventListener('popstate', handlePopState);
|
|
91
|
+
popstateBound = true;
|
|
92
|
+
}
|
|
93
|
+
listeners.add(listener);
|
|
94
|
+
return () => {
|
|
95
|
+
listeners.delete(listener);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RouteDef } from '../types.js';
|
|
2
|
+
declare global {
|
|
3
|
+
interface Navigator {
|
|
4
|
+
readonly connection?: {
|
|
5
|
+
readonly saveData?: boolean;
|
|
6
|
+
readonly effectiveType?: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export declare function prefetch(href: string): void;
|
|
11
|
+
export declare function startPrefetcher(routes: RouteDef[]): void;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { matchRoute } from '../routing/match.js';
|
|
2
|
+
let routeTable = [];
|
|
3
|
+
const warmed = new WeakSet();
|
|
4
|
+
let io = null;
|
|
5
|
+
let mo = null;
|
|
6
|
+
function routeForHref(href) {
|
|
7
|
+
let url;
|
|
8
|
+
try {
|
|
9
|
+
url = new URL(href, window.location.href);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
if (url.origin !== window.location.origin)
|
|
15
|
+
return null;
|
|
16
|
+
for (const route of routeTable) {
|
|
17
|
+
if (matchRoute(route.pattern, url.pathname))
|
|
18
|
+
return route;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
function warm(route) {
|
|
23
|
+
if (warmed.has(route))
|
|
24
|
+
return;
|
|
25
|
+
warmed.add(route);
|
|
26
|
+
void route.load().catch(() => {
|
|
27
|
+
warmed.delete(route);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export function prefetch(href) {
|
|
31
|
+
const route = routeForHref(href);
|
|
32
|
+
if (route)
|
|
33
|
+
warm(route);
|
|
34
|
+
}
|
|
35
|
+
function isPrefetchable(a) {
|
|
36
|
+
if (a.target && a.target !== '_self')
|
|
37
|
+
return false;
|
|
38
|
+
if (a.hasAttribute('download'))
|
|
39
|
+
return false;
|
|
40
|
+
if (a.dataset.noPrefetch !== undefined)
|
|
41
|
+
return false;
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
function observeAnchor(a) {
|
|
45
|
+
if (!io || !isPrefetchable(a) || !routeForHref(a.href))
|
|
46
|
+
return;
|
|
47
|
+
io.observe(a);
|
|
48
|
+
}
|
|
49
|
+
function scan(root) {
|
|
50
|
+
root.querySelectorAll('a[href]').forEach((el) => {
|
|
51
|
+
if (el instanceof HTMLAnchorElement)
|
|
52
|
+
observeAnchor(el);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function shouldSkipForConnection() {
|
|
56
|
+
const c = navigator.connection;
|
|
57
|
+
if (!c)
|
|
58
|
+
return false;
|
|
59
|
+
return c.saveData === true || c.effectiveType === 'slow-2g' || c.effectiveType === '2g';
|
|
60
|
+
}
|
|
61
|
+
export function startPrefetcher(routes) {
|
|
62
|
+
routeTable = routes;
|
|
63
|
+
if (typeof window === 'undefined' ||
|
|
64
|
+
typeof IntersectionObserver === 'undefined' ||
|
|
65
|
+
typeof MutationObserver === 'undefined' ||
|
|
66
|
+
io) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (shouldSkipForConnection())
|
|
70
|
+
return;
|
|
71
|
+
io = new IntersectionObserver((entries) => {
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
if (!entry.isIntersecting)
|
|
74
|
+
continue;
|
|
75
|
+
const a = entry.target;
|
|
76
|
+
if (a instanceof HTMLAnchorElement) {
|
|
77
|
+
io?.unobserve(a);
|
|
78
|
+
prefetch(a.href);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}, { rootMargin: '200px' });
|
|
82
|
+
mo = new MutationObserver((mutations) => {
|
|
83
|
+
for (const m of mutations) {
|
|
84
|
+
for (const node of m.addedNodes) {
|
|
85
|
+
if (node instanceof HTMLAnchorElement)
|
|
86
|
+
observeAnchor(node);
|
|
87
|
+
else if (node instanceof Element)
|
|
88
|
+
scan(node);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
const begin = () => {
|
|
93
|
+
scan(document);
|
|
94
|
+
mo?.observe(document.body, { childList: true, subtree: true });
|
|
95
|
+
};
|
|
96
|
+
if (typeof requestIdleCallback === 'function')
|
|
97
|
+
requestIdleCallback(begin);
|
|
98
|
+
else
|
|
99
|
+
setTimeout(begin, 200);
|
|
100
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function enableManualScrollRestoration(): void;
|
|
2
|
+
export declare function rememberScroll(key: string): void;
|
|
3
|
+
export declare function planScroll(opts: {
|
|
4
|
+
restoreKey?: string;
|
|
5
|
+
hash: string;
|
|
6
|
+
toTop: boolean;
|
|
7
|
+
}): void;
|
|
8
|
+
export declare function applyScroll(): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const positions = new Map();
|
|
2
|
+
let plan = null;
|
|
3
|
+
export function enableManualScrollRestoration() {
|
|
4
|
+
if (typeof window !== 'undefined' && 'scrollRestoration' in window.history) {
|
|
5
|
+
window.history.scrollRestoration = 'manual';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export function rememberScroll(key) {
|
|
9
|
+
positions.set(key, window.scrollY);
|
|
10
|
+
}
|
|
11
|
+
export function planScroll(opts) {
|
|
12
|
+
plan = {
|
|
13
|
+
restore: opts.restoreKey !== undefined ? (positions.get(opts.restoreKey) ?? 0) : null,
|
|
14
|
+
hash: opts.hash,
|
|
15
|
+
toTop: opts.toTop,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function applyScroll() {
|
|
19
|
+
const current = plan;
|
|
20
|
+
plan = null;
|
|
21
|
+
if (!current)
|
|
22
|
+
return;
|
|
23
|
+
if (current.hash) {
|
|
24
|
+
const el = document.getElementById(decodeURIComponent(current.hash.slice(1)));
|
|
25
|
+
if (el) {
|
|
26
|
+
el.scrollIntoView();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (current.restore !== null) {
|
|
31
|
+
window.scrollTo(0, current.restore);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (current.toTop)
|
|
35
|
+
window.scrollTo(0, 0);
|
|
36
|
+
}
|