toiljs 0.0.3 → 0.0.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/.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 +169 -56
- 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/error-boundary.d.ts +16 -0
- package/build/client/error-boundary.js +19 -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 +14 -2
- package/build/client/index.js +8 -1
- 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.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/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 +4 -1
- package/build/compiler/docs.d.ts +10 -0
- package/build/compiler/docs.js +59 -0
- package/build/compiler/generate.d.ts +1 -0
- package/build/compiler/generate.js +139 -21
- package/build/compiler/index.d.ts +5 -2
- package/build/compiler/index.js +5 -3
- package/build/compiler/plugin.js +2 -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/layout.tsx +39 -26
- 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 +15 -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 +1 -1
- 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 +228 -67
- 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/Link.tsx +99 -0
- package/src/client/NavLink.tsx +86 -0
- package/src/client/Router.tsx +95 -0
- package/src/client/error-boundary.tsx +43 -0
- package/src/client/head.ts +140 -0
- package/src/client/hooks.ts +115 -0
- package/src/client/index.ts +35 -5
- package/src/client/lazy.ts +93 -0
- package/src/client/match.ts +11 -3
- package/src/client/mount.tsx +28 -0
- package/src/client/navigation.ts +142 -0
- package/src/client/params-context.ts +10 -0
- package/src/client/prefetch.ts +130 -0
- package/src/client/scroll.ts +53 -0
- package/src/client/types.ts +36 -0
- package/src/compiler/config.ts +15 -8
- package/src/compiler/docs.ts +87 -0
- package/src/compiler/generate.ts +180 -33
- package/src/compiler/index.ts +7 -4
- package/src/compiler/plugin.ts +3 -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/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 +15 -0
- 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
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public router types shared across the client runtime. Kept dependency-free (type-only React
|
|
3
|
+
* imports) so any module can import them without pulling in component or DOM code.
|
|
4
|
+
*/
|
|
5
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
6
|
+
|
|
7
|
+
/** Lazy loader for a layout component (wraps children). */
|
|
8
|
+
export type LayoutComponentLoader = () => Promise<{
|
|
9
|
+
default: ComponentType<{ children?: ReactNode }>;
|
|
10
|
+
}>;
|
|
11
|
+
|
|
12
|
+
/** Props passed to an `error.tsx` component: the thrown error and a function to retry rendering. */
|
|
13
|
+
export interface RouteErrorProps {
|
|
14
|
+
readonly error: Error;
|
|
15
|
+
readonly reset: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A route entry produced by the compiler: a URL pattern, a lazy loader for its page component, and
|
|
20
|
+
* the chain of nested layout loaders (shallowest → deepest, from nested `layout.tsx` files) that wrap it.
|
|
21
|
+
*/
|
|
22
|
+
export interface RouteDef {
|
|
23
|
+
readonly pattern: string;
|
|
24
|
+
readonly load: () => Promise<{ default: ComponentType }>;
|
|
25
|
+
readonly layouts?: readonly LayoutComponentLoader[];
|
|
26
|
+
/** Nearest `loading.tsx` — shown as the Suspense fallback while this route loads. */
|
|
27
|
+
readonly loading?: () => Promise<{ default: ComponentType }>;
|
|
28
|
+
/** Nearest `error.tsx` — rendered by an error boundary around this route. */
|
|
29
|
+
readonly errorComponent?: () => Promise<{ default: ComponentType<RouteErrorProps> }>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Optional root layout loader (wraps every page). `null` when the project defines no layout. */
|
|
33
|
+
export type LayoutLoader = LayoutComponentLoader | null;
|
|
34
|
+
|
|
35
|
+
/** Optional custom not-found (404) page loader, rendered when no route matches. */
|
|
36
|
+
export type NotFoundLoader = (() => Promise<{ default: ComponentType }>) | null;
|
package/src/compiler/config.ts
CHANGED
|
@@ -12,7 +12,13 @@ export interface ClientConfig {
|
|
|
12
12
|
readonly srcDir?: string;
|
|
13
13
|
/** Routes directory, relative to `srcDir`. Default `routes`. */
|
|
14
14
|
readonly routesDir?: string;
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Static assets directory, relative to root. Default `<srcDir>/public` (e.g. `client/public`).
|
|
17
|
+
* Holds the `index.html` template (owned and edited by you) plus any files served as-is at the
|
|
18
|
+
* base path (favicons, images, …).
|
|
19
|
+
*/
|
|
20
|
+
readonly publicDir?: string;
|
|
21
|
+
/** Production output directory, relative to root. Default `build/client`. */
|
|
16
22
|
readonly outDir?: string;
|
|
17
23
|
/** Public base path. Default `/`. */
|
|
18
24
|
readonly base?: string;
|
|
@@ -27,7 +33,7 @@ export interface ClientConfig {
|
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
/**
|
|
30
|
-
* Server-side (
|
|
36
|
+
* Server-side (toilscript → WASM) configuration. Reserved: the compiler does not yet
|
|
31
37
|
* build the server target via `toil build`; today it is compiled by `toilscript` directly.
|
|
32
38
|
*/
|
|
33
39
|
export interface ServerConfig {
|
|
@@ -46,7 +52,7 @@ export interface ToilConfig {
|
|
|
46
52
|
readonly root?: string;
|
|
47
53
|
/** Client (TSX/React/Vite) configuration. */
|
|
48
54
|
readonly client?: ClientConfig;
|
|
49
|
-
/** Server (
|
|
55
|
+
/** Server (toilscript/WASM) configuration. */
|
|
50
56
|
readonly server?: ServerConfig;
|
|
51
57
|
}
|
|
52
58
|
|
|
@@ -56,6 +62,8 @@ export interface ResolvedToilConfig {
|
|
|
56
62
|
readonly srcDir: string;
|
|
57
63
|
readonly clientAbsDir: string;
|
|
58
64
|
readonly routesAbsDir: string;
|
|
65
|
+
/** Absolute path to the static-assets dir (holds the `index.html` template). */
|
|
66
|
+
readonly publicDir: string;
|
|
59
67
|
readonly toilDir: string;
|
|
60
68
|
readonly outDir: string;
|
|
61
69
|
readonly base: string;
|
|
@@ -87,10 +95,6 @@ export async function loadConfig(
|
|
|
87
95
|
for (const name of CONFIG_NAMES) {
|
|
88
96
|
const candidate = path.join(root, name);
|
|
89
97
|
if (fs.existsSync(candidate)) {
|
|
90
|
-
// Native ESM import (Node strips types from .ts/.mts). This keeps config loading
|
|
91
|
-
// independent of the project's tsconfig — which may `extends` a not-yet-installed
|
|
92
|
-
// package and would otherwise throw TSCONFIG_ERROR — and a file URL imports absolute
|
|
93
|
-
// paths correctly on Windows.
|
|
94
98
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- dynamic import() is typed `any`
|
|
95
99
|
const loaded: { default?: ToilConfig } = await import(pathToFileURL(candidate).href);
|
|
96
100
|
if (loaded.default) user = loaded.default;
|
|
@@ -108,8 +112,11 @@ export async function loadConfig(
|
|
|
108
112
|
srcDir,
|
|
109
113
|
clientAbsDir,
|
|
110
114
|
routesAbsDir: path.join(clientAbsDir, routesDir),
|
|
115
|
+
publicDir: client.publicDir
|
|
116
|
+
? path.resolve(root, client.publicDir)
|
|
117
|
+
: path.join(clientAbsDir, 'public'),
|
|
111
118
|
toilDir: path.join(root, '.toil'),
|
|
112
|
-
outDir: client.outDir ?? '
|
|
119
|
+
outDir: client.outDir ?? 'build/client',
|
|
113
120
|
base: client.base ?? '/',
|
|
114
121
|
port: opts.port ?? client.port ?? 3000,
|
|
115
122
|
runtimePath: resolveRuntimePath(),
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI-assistant helper files. `toiljs create` writes a small pointer file for each tool at the
|
|
3
|
+
* project root (committed, yours to edit); the real documentation lives under `.toil/docs/`,
|
|
4
|
+
* regenerated on every `toiljs dev` / `toiljs build` so it stays in sync with the installed
|
|
5
|
+
* toiljs version. The pointer files just tell the agent to read `.toil/docs/`.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
|
|
10
|
+
/** Shared body for the per-tool pointer files. */
|
|
11
|
+
const POINTER_BODY = `# toiljs · AI assistant guide
|
|
12
|
+
|
|
13
|
+
This is a **toiljs** project — a full-stack React framework (React + Vite client, file-based
|
|
14
|
+
routing, and a toilscript→WebAssembly server).
|
|
15
|
+
|
|
16
|
+
**Before editing this project, read the generated documentation in \`.toil/docs/\`.** It describes
|
|
17
|
+
the conventions you must follow:
|
|
18
|
+
|
|
19
|
+
- \`.toil/docs/index.md\` — overview and project layout
|
|
20
|
+
- \`.toil/docs/routing.md\` — file-based routing, nested layouts, loading / error files
|
|
21
|
+
- \`.toil/docs/client.md\` — the \`Toil\` global, Link / NavLink, router hooks
|
|
22
|
+
- \`.toil/docs/styling.md\` — CSS / Sass / Less / Stylus / Tailwind (via \`toiljs configure\`)
|
|
23
|
+
- \`.toil/docs/server.md\` — the toilscript server target
|
|
24
|
+
- \`.toil/docs/cli.md\` — toiljs CLI commands
|
|
25
|
+
|
|
26
|
+
\`.toil/docs/\` is regenerated by toiljs; do not edit it by hand. This pointer file is yours to edit.
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
/** A selectable AI coding-tool helper: its id, label, and the root pointer file(s) it scaffolds. */
|
|
30
|
+
export interface AiHelper {
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly label: string;
|
|
33
|
+
readonly files: Record<string, string>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Per-tool pointer files, individually selectable in `toiljs create`. Each tool reads its own
|
|
38
|
+
* conventional file: Claude Code → CLAUDE.md, Codex / others → AGENTS.md, Cursor → .cursor/rules,
|
|
39
|
+
* GitHub Copilot → .github/copilot-instructions.md. Written once by `create`; not regenerated.
|
|
40
|
+
*/
|
|
41
|
+
export const AI_HELPERS: readonly AiHelper[] = [
|
|
42
|
+
{ id: 'claude', label: 'Claude Code (CLAUDE.md)', files: { 'CLAUDE.md': POINTER_BODY } },
|
|
43
|
+
{ id: 'codex', label: 'Codex / AGENTS.md', files: { 'AGENTS.md': POINTER_BODY } },
|
|
44
|
+
{
|
|
45
|
+
id: 'cursor',
|
|
46
|
+
label: 'Cursor (.cursor/rules)',
|
|
47
|
+
files: {
|
|
48
|
+
'.cursor/rules/toiljs.mdc': `---\ndescription: toiljs project conventions\nalwaysApply: true\n---\n\n${POINTER_BODY}`,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'copilot',
|
|
53
|
+
label: 'GitHub Copilot (.github/copilot-instructions.md)',
|
|
54
|
+
files: { '.github/copilot-instructions.md': POINTER_BODY },
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
/** All AI helper ids (the default selection). */
|
|
59
|
+
export const AI_HELPER_IDS: readonly string[] = AI_HELPERS.map((h) => h.id);
|
|
60
|
+
|
|
61
|
+
/** Merges the pointer files for the given helper ids into one path → content map. */
|
|
62
|
+
export function aiHelperFiles(ids: readonly string[]): Record<string, string> {
|
|
63
|
+
const out: Record<string, string> = {};
|
|
64
|
+
for (const helper of AI_HELPERS) {
|
|
65
|
+
if (ids.includes(helper.id)) Object.assign(out, helper.files);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The framework docs written into `.toil/docs/` (placeholders for now), keyed by filename. */
|
|
71
|
+
export const TOIL_DOCS: Record<string, string> = {
|
|
72
|
+
'index.md': '# toiljs\n\n<!-- TODO: overview and project layout -->\n',
|
|
73
|
+
'routing.md': '# Routing\n\n<!-- TODO: file-based routing, nested layouts, loading / error -->\n',
|
|
74
|
+
'client.md': '# Client runtime\n\n<!-- TODO: Toil global, Link / NavLink, router hooks -->\n',
|
|
75
|
+
'styling.md': '# Styling\n\n<!-- TODO: CSS / preprocessors / Tailwind via `toiljs configure` -->\n',
|
|
76
|
+
'server.md': '# Server (toilscript → WebAssembly)\n\n<!-- TODO -->\n',
|
|
77
|
+
'cli.md': '# CLI\n\n<!-- TODO: create / dev / build / start / configure -->\n',
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/** Writes the framework docs into `<toilDir>/docs/`. Called by `generate` each dev/build. */
|
|
81
|
+
export function writeDocs(toilDir: string): void {
|
|
82
|
+
const dir = path.join(toilDir, 'docs');
|
|
83
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
84
|
+
for (const [name, content] of Object.entries(TOIL_DOCS)) {
|
|
85
|
+
fs.writeFileSync(path.join(dir, name), content);
|
|
86
|
+
}
|
|
87
|
+
}
|
package/src/compiler/generate.ts
CHANGED
|
@@ -2,11 +2,47 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { type ResolvedToilConfig } from './config.js';
|
|
5
|
+
import { writeDocs } from './docs.js';
|
|
5
6
|
import { scanRoutes, type ScannedRoute } from './routes.js';
|
|
6
7
|
|
|
7
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Contents of the root `toil-env.d.ts`: ambient global types so `new BinaryWriter()` etc. resolve
|
|
10
|
+
* in the IDE without an import. Script-mode declaration (no top-level import/export → the
|
|
11
|
+
* `declare const`s are truly global, and it's not a module that could confuse ESLint's project
|
|
12
|
+
* service); the inline `import('toiljs/io')` type only needs the normal `toiljs/io` export.
|
|
13
|
+
* Lives at the project root because TypeScript's `include` globs skip dot-directories.
|
|
14
|
+
* Exported so `toiljs create` can write it during scaffolding, before the first dev/build.
|
|
15
|
+
*/
|
|
16
|
+
export const TOIL_ENV_DTS =
|
|
17
|
+
`// AUTO-GENERATED by toil — do not edit.\n` +
|
|
18
|
+
`declare const Toil: typeof import('toiljs/client');\n` +
|
|
19
|
+
`declare const BinaryWriter: typeof import('toiljs/io').BinaryWriter;\n` +
|
|
20
|
+
`declare const BinaryReader: typeof import('toiljs/io').BinaryReader;\n` +
|
|
21
|
+
`declare const FastMap: typeof import('toiljs/io').FastMap;\n` +
|
|
22
|
+
`declare const FastSet: typeof import('toiljs/io').FastSet;\n` +
|
|
23
|
+
`\n` +
|
|
24
|
+
`declare module '*.css' {}\n` +
|
|
25
|
+
`declare module '*.scss' {}\n` +
|
|
26
|
+
`declare module '*.sass' {}\n` +
|
|
27
|
+
`declare module '*.less' {}\n` +
|
|
28
|
+
`declare module '*.styl' {}\n` +
|
|
29
|
+
`declare module '*.stylus' {}\n` +
|
|
30
|
+
`declare module '*.pcss' {}\n` +
|
|
31
|
+
`declare module '*.sss' {}\n` +
|
|
32
|
+
`\n` +
|
|
33
|
+
`declare module 'toiljs/routes' {\n` +
|
|
34
|
+
` export const routes: import('toiljs/client').RouteDef[];\n` +
|
|
35
|
+
` export const layout: import('toiljs/client').LayoutLoader;\n` +
|
|
36
|
+
` export const notFound: import('toiljs/client').NotFoundLoader;\n` +
|
|
37
|
+
`}\n`;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns a `./`-prefixed, **extensionless** POSIX module specifier from `.toil` to `abs`, for use
|
|
41
|
+
* in generated `import(...)` calls. Extensionless so TypeScript doesn't demand
|
|
42
|
+
* `allowImportingTsExtensions` (TS5097) when the generated files are checked; Vite still resolves it.
|
|
43
|
+
*/
|
|
8
44
|
function relFromToil(cfg: ResolvedToilConfig, abs: string): string {
|
|
9
|
-
let rel = path.relative(cfg.toilDir, abs).replace(/\\/g, '/');
|
|
45
|
+
let rel = path.relative(cfg.toilDir, abs).replace(/\\/g, '/').replace(/\.(tsx|jsx)$/, '');
|
|
10
46
|
if (!rel.startsWith('.')) rel = './' + rel;
|
|
11
47
|
return rel;
|
|
12
48
|
}
|
|
@@ -24,8 +60,57 @@ function findNotFound(cfg: ResolvedToilConfig): string | undefined {
|
|
|
24
60
|
.find((p) => fs.existsSync(p));
|
|
25
61
|
}
|
|
26
62
|
|
|
63
|
+
/** Finds the user-owned app entry at `client/toil.{tsx,jsx}` (where `mount` is called). */
|
|
64
|
+
function findEntry(cfg: ResolvedToilConfig): string | undefined {
|
|
65
|
+
return ['toil.tsx', 'toil.jsx']
|
|
66
|
+
.map((name) => path.join(cfg.clientAbsDir, name))
|
|
67
|
+
.find((p) => fs.existsSync(p));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** A `layout.{tsx,jsx}` in `dir`, or undefined. */
|
|
71
|
+
function layoutIn(dir: string): string | undefined {
|
|
72
|
+
return ['layout.tsx', 'layout.jsx']
|
|
73
|
+
.map((name) => path.join(dir, name))
|
|
74
|
+
.find((p) => fs.existsSync(p));
|
|
75
|
+
}
|
|
76
|
+
|
|
27
77
|
/**
|
|
28
|
-
*
|
|
78
|
+
* Nested layout chain for a route file: `layout.{tsx,jsx}` at the routes root and each ancestor
|
|
79
|
+
* directory down to the file's own, shallowest → deepest. (The project root `client/layout.tsx`
|
|
80
|
+
* is handled separately as the top-level layout.)
|
|
81
|
+
*/
|
|
82
|
+
function findLayoutChain(cfg: ResolvedToilConfig, routeFile: string): string[] {
|
|
83
|
+
const relDir = path.dirname(path.relative(cfg.routesAbsDir, routeFile));
|
|
84
|
+
const segments = relDir === '.' ? [] : relDir.split(path.sep);
|
|
85
|
+
const chain: string[] = [];
|
|
86
|
+
let dir = cfg.routesAbsDir;
|
|
87
|
+
for (let i = 0; i <= segments.length; i++) {
|
|
88
|
+
if (i > 0) dir = path.join(dir, segments[i - 1]);
|
|
89
|
+
const layout = layoutIn(dir);
|
|
90
|
+
if (layout) chain.push(layout);
|
|
91
|
+
}
|
|
92
|
+
return chain;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Nearest special file named `base` (e.g. `loading`/`error`) from the route's dir up to the routes root. */
|
|
96
|
+
function findNearest(cfg: ResolvedToilConfig, routeFile: string, base: string): string | undefined {
|
|
97
|
+
const root = path.resolve(cfg.routesAbsDir);
|
|
98
|
+
let dir = path.dirname(routeFile);
|
|
99
|
+
for (;;) {
|
|
100
|
+
const found = [`${base}.tsx`, `${base}.jsx`]
|
|
101
|
+
.map((name) => path.join(dir, name))
|
|
102
|
+
.find((p) => fs.existsSync(p));
|
|
103
|
+
if (found) return found;
|
|
104
|
+
if (path.resolve(dir) === root) return undefined;
|
|
105
|
+
const parent = path.dirname(dir);
|
|
106
|
+
if (parent === dir) return undefined;
|
|
107
|
+
dir = parent;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Generates the `.toil/` working dir (routes table, mount entry, the HTML entry built from the
|
|
113
|
+
* project's `public/index.html` template, and mirrored `public/` assets) and returns the scanned
|
|
29
114
|
* routes. Called before every dev/build and on route add/remove during dev.
|
|
30
115
|
*/
|
|
31
116
|
export function generate(cfg: ResolvedToilConfig): ScannedRoute[] {
|
|
@@ -35,49 +120,111 @@ export function generate(cfg: ResolvedToilConfig): ScannedRoute[] {
|
|
|
35
120
|
const layoutFile = findLayout(cfg);
|
|
36
121
|
const notFoundFile = findNotFound(cfg);
|
|
37
122
|
const routesSrc =
|
|
123
|
+
`// @ts-nocheck\n` +
|
|
38
124
|
`// AUTO-GENERATED by toil — do not edit.\n` +
|
|
39
125
|
`import type { RouteDef, LayoutLoader, NotFoundLoader } from 'toiljs/client';\n\n` +
|
|
40
126
|
`export const routes: RouteDef[] = [\n` +
|
|
41
127
|
routes
|
|
42
|
-
.map(
|
|
43
|
-
(
|
|
44
|
-
|
|
45
|
-
|
|
128
|
+
.map((r) => {
|
|
129
|
+
const imp = (f: string): string => `() => import(${JSON.stringify(relFromToil(cfg, f))})`;
|
|
130
|
+
const layouts = findLayoutChain(cfg, r.file).map(imp).join(', ');
|
|
131
|
+
const parts = [
|
|
132
|
+
`pattern: ${JSON.stringify(r.pattern)}`,
|
|
133
|
+
`load: ${imp(r.file)}`,
|
|
134
|
+
`layouts: [${layouts}]`,
|
|
135
|
+
];
|
|
136
|
+
const loadingFile = findNearest(cfg, r.file, 'loading');
|
|
137
|
+
if (loadingFile) parts.push(`loading: ${imp(loadingFile)}`);
|
|
138
|
+
const errorFile = findNearest(cfg, r.file, 'error');
|
|
139
|
+
if (errorFile) parts.push(`errorComponent: ${imp(errorFile)}`);
|
|
140
|
+
return ` { ${parts.join(', ')} },`;
|
|
141
|
+
})
|
|
46
142
|
.join('\n') +
|
|
47
143
|
`\n];\n\n` +
|
|
48
144
|
`export const layout: LayoutLoader = ${layoutFile ? `() => import(${JSON.stringify(relFromToil(cfg, layoutFile))})` : 'null'};\n` +
|
|
49
145
|
`export const notFound: NotFoundLoader = ${notFoundFile ? `() => import(${JSON.stringify(relFromToil(cfg, notFoundFile))})` : 'null'};\n`;
|
|
50
146
|
fs.writeFileSync(path.join(cfg.toilDir, 'routes.ts'), routesSrc);
|
|
51
147
|
|
|
52
|
-
const
|
|
148
|
+
const globalsSrc =
|
|
149
|
+
`// @ts-nocheck\n` +
|
|
53
150
|
`// AUTO-GENERATED by toil — do not edit.\n` +
|
|
54
|
-
`import
|
|
55
|
-
`import { BinaryWriter, BinaryReader, FastMap, FastSet } from 'toiljs/io';\n` +
|
|
56
|
-
`
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
151
|
+
`import * as Toil from 'toiljs/client';\n` +
|
|
152
|
+
`import { BinaryWriter, BinaryReader, FastMap, FastSet } from 'toiljs/io';\n\n` +
|
|
153
|
+
`Object.assign(globalThis, { Toil, BinaryWriter, BinaryReader, FastMap, FastSet });\n`;
|
|
154
|
+
fs.writeFileSync(path.join(cfg.toilDir, 'globals.ts'), globalsSrc);
|
|
155
|
+
|
|
156
|
+
const entryFile = findEntry(cfg);
|
|
157
|
+
const entrySrc = entryFile
|
|
158
|
+
? `// @ts-nocheck\n` +
|
|
159
|
+
`// AUTO-GENERATED by toil — do not edit.\n` +
|
|
160
|
+
`import './globals';\n` +
|
|
161
|
+
`import ${JSON.stringify(relFromToil(cfg, entryFile))};\n`
|
|
162
|
+
: `// @ts-nocheck\n` +
|
|
163
|
+
`// AUTO-GENERATED by toil — do not edit.\n` +
|
|
164
|
+
`import './globals';\n` +
|
|
165
|
+
`import { mount } from 'toiljs/client';\n` +
|
|
166
|
+
`import { routes, layout, notFound } from './routes';\n\n` +
|
|
167
|
+
`mount(routes, layout, notFound);\n`;
|
|
60
168
|
fs.writeFileSync(path.join(cfg.toilDir, 'entry.tsx'), entrySrc);
|
|
61
169
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const envSrc =
|
|
68
|
-
`// AUTO-GENERATED by toil — do not edit.\n` +
|
|
69
|
-
`declare const BinaryWriter: typeof import('toiljs/io').BinaryWriter;\n` +
|
|
70
|
-
`declare const BinaryReader: typeof import('toiljs/io').BinaryReader;\n` +
|
|
71
|
-
`declare const FastMap: typeof import('toiljs/io').FastMap;\n` +
|
|
72
|
-
`declare const FastSet: typeof import('toiljs/io').FastSet;\n`;
|
|
73
|
-
fs.writeFileSync(path.join(cfg.root, 'toil-env.d.ts'), envSrc);
|
|
74
|
-
|
|
75
|
-
const htmlSrc =
|
|
76
|
-
`<!doctype html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n` +
|
|
77
|
-
` <meta name="viewport" content="width=device-width, initial-scale=1" />\n` +
|
|
78
|
-
` <title>Toil App</title>\n </head>\n <body>\n <div id="root"></div>\n` +
|
|
79
|
-
` <script type="module" src="./entry.tsx"></script>\n </body>\n</html>\n`;
|
|
80
|
-
fs.writeFileSync(path.join(cfg.toilDir, 'index.html'), htmlSrc);
|
|
170
|
+
fs.writeFileSync(path.join(cfg.root, 'toil-env.d.ts'), TOIL_ENV_DTS);
|
|
171
|
+
|
|
172
|
+
fs.writeFileSync(path.join(cfg.toilDir, 'index.html'), buildHtml(cfg));
|
|
173
|
+
syncPublicAssets(cfg);
|
|
174
|
+
writeDocs(cfg.toilDir);
|
|
81
175
|
|
|
82
176
|
return routes;
|
|
83
177
|
}
|
|
178
|
+
|
|
179
|
+
/** Fallback HTML when the project has no `public/index.html` template. The entry script is added
|
|
180
|
+
* by {@link buildHtml}. */
|
|
181
|
+
const DEFAULT_HTML =
|
|
182
|
+
`<!doctype html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n` +
|
|
183
|
+
` <meta name="viewport" content="width=device-width, initial-scale=1" />\n` +
|
|
184
|
+
` <meta name="description" content="" />\n` +
|
|
185
|
+
` <title>Toil App</title>\n </head>\n <body>\n <div id="root"></div>\n` +
|
|
186
|
+
` </body>\n</html>\n`;
|
|
187
|
+
|
|
188
|
+
/** The module entry that boots the app, injected into the HTML (resolved relative to `.toil`). */
|
|
189
|
+
const ENTRY_SCRIPT = `<script type="module" src="./entry.tsx"></script>`;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Produces the `.toil/index.html` Vite entry from the project's `public/index.html` template (or
|
|
193
|
+
* the built-in default if absent), ensuring the generated module entry script is present. Users
|
|
194
|
+
* own the template — toil only guarantees the entry is wired, so it stays the SPA root.
|
|
195
|
+
*/
|
|
196
|
+
function buildHtml(cfg: ResolvedToilConfig): string {
|
|
197
|
+
const templatePath = path.join(cfg.publicDir, 'index.html');
|
|
198
|
+
let html = fs.existsSync(templatePath)
|
|
199
|
+
? fs.readFileSync(templatePath, 'utf8')
|
|
200
|
+
: DEFAULT_HTML;
|
|
201
|
+
// Inject the entry only if the template doesn't already reference it as a module script
|
|
202
|
+
// (matching the literal filename anywhere in the file would be too eager).
|
|
203
|
+
if (!/src=["']\.\/entry\.tsx["']/.test(html)) {
|
|
204
|
+
html = html.includes('</body>')
|
|
205
|
+
? html.replace('</body>', ` ${ENTRY_SCRIPT}\n </body>`)
|
|
206
|
+
: `${html}\n${ENTRY_SCRIPT}\n`;
|
|
207
|
+
}
|
|
208
|
+
return html;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Mirrors the project's `public/` assets into `.toil/public/` (Vite's publicDir under the `.toil`
|
|
213
|
+
* root), excluding the `index.html` template — that is processed into the entry above, and copying
|
|
214
|
+
* it here would clobber the built, asset-hashed page. Cleared each run so deletions propagate.
|
|
215
|
+
*/
|
|
216
|
+
function syncPublicAssets(cfg: ResolvedToilConfig): void {
|
|
217
|
+
const dest = path.join(cfg.toilDir, 'public');
|
|
218
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
219
|
+
if (!fs.existsSync(cfg.publicDir)) return;
|
|
220
|
+
|
|
221
|
+
let copied = 0;
|
|
222
|
+
for (const entry of fs.readdirSync(cfg.publicDir, { withFileTypes: true })) {
|
|
223
|
+
if (entry.name === 'index.html') continue;
|
|
224
|
+
fs.cpSync(path.join(cfg.publicDir, entry.name), path.join(dest, entry.name), {
|
|
225
|
+
recursive: true,
|
|
226
|
+
});
|
|
227
|
+
copied++;
|
|
228
|
+
}
|
|
229
|
+
if (copied === 0) fs.rmSync(dest, { recursive: true, force: true });
|
|
230
|
+
}
|
package/src/compiler/index.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface ToilCommandOptions {
|
|
|
17
17
|
export async function dev(opts: ToilCommandOptions = {}): Promise<ViteDevServer> {
|
|
18
18
|
const cfg = await loadConfig(opts);
|
|
19
19
|
generate(cfg);
|
|
20
|
-
const server = await createServer(createViteConfig(cfg));
|
|
20
|
+
const server = await createServer(await createViteConfig(cfg));
|
|
21
21
|
await server.listen();
|
|
22
22
|
server.printUrls();
|
|
23
23
|
return server;
|
|
@@ -27,7 +27,7 @@ export async function dev(opts: ToilCommandOptions = {}): Promise<ViteDevServer>
|
|
|
27
27
|
export async function build(opts: ToilCommandOptions = {}): Promise<void> {
|
|
28
28
|
const cfg = await loadConfig(opts);
|
|
29
29
|
generate(cfg);
|
|
30
|
-
await viteBuild(createViteConfig(cfg));
|
|
30
|
+
await viteBuild(await createViteConfig(cfg));
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
@@ -44,6 +44,9 @@ export async function start(opts: ToilCommandOptions = {}): Promise<RunningBacke
|
|
|
44
44
|
return startBackend({ root: outDir, port: cfg.port });
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
export { defineConfig } from './config.js';
|
|
48
|
-
export
|
|
47
|
+
export { defineConfig, loadConfig } from './config.js';
|
|
48
|
+
export { TOIL_ENV_DTS } from './generate.js';
|
|
49
|
+
export { AI_HELPERS, AI_HELPER_IDS, aiHelperFiles, TOIL_DOCS } from './docs.js';
|
|
50
|
+
export type { AiHelper } from './docs.js';
|
|
51
|
+
export type { ToilConfig, ResolvedToilConfig } from './config.js';
|
|
49
52
|
export type { RunningBackend, BackendOptions } from 'toiljs/backend';
|
package/src/compiler/plugin.ts
CHANGED
|
@@ -12,8 +12,10 @@ export function toilPlugin(cfg: ResolvedToilConfig): Plugin {
|
|
|
12
12
|
return {
|
|
13
13
|
name: 'toil',
|
|
14
14
|
configureServer(server) {
|
|
15
|
+
// Trailing slash so a sibling like `routes-extra/` doesn't match the `routes/` prefix.
|
|
16
|
+
const routesPrefix = cfg.routesAbsDir.replace(/\\/g, '/').replace(/\/?$/, '/');
|
|
15
17
|
const onChange = (file: string): void => {
|
|
16
|
-
if (file.replace(/\\/g, '/').startsWith(
|
|
18
|
+
if (file.replace(/\\/g, '/').startsWith(routesPrefix)) {
|
|
17
19
|
generate(cfg);
|
|
18
20
|
server.ws.send({ type: 'full-reload' });
|
|
19
21
|
}
|
package/src/compiler/routes.ts
CHANGED
|
@@ -8,14 +8,18 @@ export interface ScannedRoute {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const ROUTE_EXT = /\.(tsx|jsx)$/;
|
|
11
|
+
/** Special files that live alongside routes but are not themselves pages. */
|
|
12
|
+
const SPECIAL_FILE = /^(layout|loading|error|404|not-found)\.(tsx|jsx)$/;
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Derives a route pattern from a route file path (relative to the routes dir).
|
|
14
16
|
* index.tsx -> /
|
|
15
17
|
* about.tsx -> /about
|
|
16
18
|
* blog/index.tsx -> /blog
|
|
17
|
-
* blog/[id].tsx
|
|
18
|
-
* docs/[...slug].tsx
|
|
19
|
+
* blog/[id].tsx -> /blog/:id
|
|
20
|
+
* docs/[...slug].tsx -> /docs/*slug (catch-all)
|
|
21
|
+
* docs/[[...slug]].tsx -> /docs/**slug (optional catch-all)
|
|
22
|
+
* (marketing)/about.tsx -> /about (route group: parens add no URL segment)
|
|
19
23
|
*/
|
|
20
24
|
export function filePathToRoute(relPath: string): string {
|
|
21
25
|
const withoutExt = relPath.replace(/\\/g, '/').replace(ROUTE_EXT, '');
|
|
@@ -23,11 +27,13 @@ export function filePathToRoute(relPath: string): string {
|
|
|
23
27
|
const out: string[] = [];
|
|
24
28
|
for (let i = 0; i < segments.length; i++) {
|
|
25
29
|
const segment = segments[i];
|
|
30
|
+
if (/^\(.+\)$/.test(segment)) continue;
|
|
26
31
|
if (segment === 'index' && i === segments.length - 1) continue;
|
|
27
32
|
out.push(
|
|
28
33
|
segment
|
|
29
|
-
.replace(/^\[\.\.\.(.+)\]$/, '
|
|
30
|
-
.replace(/^\[(.+)\]$/, '
|
|
34
|
+
.replace(/^\[\[\.\.\.(.+)\]\]$/, '**$1')
|
|
35
|
+
.replace(/^\[\.\.\.(.+)\]$/, '*$1')
|
|
36
|
+
.replace(/^\[(.+)\]$/, ':$1'),
|
|
31
37
|
);
|
|
32
38
|
}
|
|
33
39
|
return '/' + out.join('/');
|
|
@@ -41,8 +47,8 @@ function specificity(pattern: string): number {
|
|
|
41
47
|
const segments = pattern.split('/').filter(Boolean);
|
|
42
48
|
let score = segments.length * 10;
|
|
43
49
|
for (const segment of segments) {
|
|
44
|
-
if (segment.startsWith('*')) score -= 5;
|
|
45
|
-
else if (!segment.startsWith(':')) score += 5;
|
|
50
|
+
if (segment.startsWith('*')) score -= 5;
|
|
51
|
+
else if (!segment.startsWith(':')) score += 5;
|
|
46
52
|
}
|
|
47
53
|
return score;
|
|
48
54
|
}
|
|
@@ -56,7 +62,7 @@ export function scanRoutes(routesDir: string): ScannedRoute[] {
|
|
|
56
62
|
const full = path.join(dir, entry.name);
|
|
57
63
|
if (entry.isDirectory()) {
|
|
58
64
|
walk(full);
|
|
59
|
-
} else if (ROUTE_EXT.test(entry.name)) {
|
|
65
|
+
} else if (ROUTE_EXT.test(entry.name) && !SPECIAL_FILE.test(entry.name)) {
|
|
60
66
|
found.push({
|
|
61
67
|
file: full,
|
|
62
68
|
pattern: filePathToRoute(path.relative(routesDir, full)),
|
package/src/compiler/vite.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
1
2
|
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
2
4
|
|
|
3
5
|
import react from '@vitejs/plugin-react';
|
|
4
6
|
import { nodePolyfills } from 'vite-plugin-node-polyfills';
|
|
5
|
-
import { mergeConfig, type InlineConfig } from 'vite';
|
|
7
|
+
import { mergeConfig, type InlineConfig, type PluginOption } from 'vite';
|
|
6
8
|
|
|
7
9
|
import { type ResolvedToilConfig } from './config.js';
|
|
8
10
|
import { toilPlugin } from './plugin.js';
|
|
@@ -21,6 +23,23 @@ function assetFileName(name: string): string {
|
|
|
21
23
|
return 'assets/[name][extname]';
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Loads the Tailwind v4 Vite plugin if the project has `@tailwindcss/vite` installed (added by
|
|
28
|
+
* `toiljs create`/`configure` when Tailwind is enabled). Resolved from the project root so it picks
|
|
29
|
+
* up the project's copy; returns `undefined` when Tailwind is off, so the plugin simply isn't added.
|
|
30
|
+
*/
|
|
31
|
+
async function tailwindPlugin(root: string): Promise<PluginOption | undefined> {
|
|
32
|
+
let resolved: string;
|
|
33
|
+
try {
|
|
34
|
+
resolved = createRequire(path.join(root, 'package.json')).resolve('@tailwindcss/vite');
|
|
35
|
+
} catch {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- dynamic import() is typed any
|
|
39
|
+
const mod: { default?: () => PluginOption } = await import(pathToFileURL(resolved).href);
|
|
40
|
+
return mod.default?.();
|
|
41
|
+
}
|
|
42
|
+
|
|
24
43
|
/** Splits React's runtime into its own long-lived chunk for better caching. */
|
|
25
44
|
function manualChunks(id: string): string | undefined {
|
|
26
45
|
if (!id.includes('node_modules')) return undefined;
|
|
@@ -36,21 +55,24 @@ function manualChunks(id: string): string | undefined {
|
|
|
36
55
|
|
|
37
56
|
/**
|
|
38
57
|
* Builds the framework-owned Vite config. Vite's `root` is the generated `.toil` dir so its
|
|
39
|
-
* `index.html`
|
|
40
|
-
*
|
|
58
|
+
* `index.html` (built from the project's `public/index.html` template) emits at the output root
|
|
59
|
+
* with assets resolving correctly; static `public/` assets are mirrored to `.toil/public` and
|
|
60
|
+
* picked up via Vite's default publicDir. `fs.allow` opens the project (for `client/`) and the
|
|
61
|
+
* framework runtime. The opinionated default — Node polyfills
|
|
41
62
|
* (Buffer/global/process), React plugin, toil route plugin, typed asset folders, React chunk
|
|
42
63
|
* splitting and tuned build options — is applied here; `toiljs/client` is aliased to the
|
|
43
64
|
* runtime, and the user's `client.vite` overrides deep-merge on top.
|
|
44
65
|
*/
|
|
45
|
-
export function createViteConfig(cfg: ResolvedToilConfig): InlineConfig {
|
|
46
|
-
// .../build/client/index.js -> framework package root (covers build/ + node_modules in dev)
|
|
66
|
+
export async function createViteConfig(cfg: ResolvedToilConfig): Promise<InlineConfig> {
|
|
47
67
|
const frameworkRoot = path.resolve(path.dirname(cfg.runtimePath), '..', '..');
|
|
68
|
+
const tailwind = await tailwindPlugin(cfg.root);
|
|
48
69
|
|
|
49
70
|
const base: InlineConfig = {
|
|
50
71
|
root: cfg.toilDir,
|
|
51
72
|
base: cfg.base,
|
|
52
73
|
configFile: false,
|
|
53
74
|
plugins: [
|
|
75
|
+
tailwind,
|
|
54
76
|
nodePolyfills({ globals: { Buffer: true, global: true, process: true } }),
|
|
55
77
|
react(),
|
|
56
78
|
toilPlugin(cfg),
|
|
@@ -58,6 +80,7 @@ export function createViteConfig(cfg: ResolvedToilConfig): InlineConfig {
|
|
|
58
80
|
resolve: {
|
|
59
81
|
alias: {
|
|
60
82
|
'toiljs/client': cfg.runtimePath,
|
|
83
|
+
'toiljs/routes': path.join(cfg.toilDir, 'routes.ts'),
|
|
61
84
|
},
|
|
62
85
|
dedupe: ['react', 'react-dom'],
|
|
63
86
|
},
|
package/src/io/BinaryReader.ts
CHANGED
|
@@ -25,7 +25,6 @@ export class BinaryReader {
|
|
|
25
25
|
return this.buffer.byteLength;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
// Helpers for comparisons; unchanged
|
|
29
28
|
public static stringCompare(a: string, b: string): number {
|
|
30
29
|
return a.localeCompare(b);
|
|
31
30
|
}
|
|
@@ -123,7 +122,6 @@ export class BinaryReader {
|
|
|
123
122
|
public readU128(be: boolean = true): bigint {
|
|
124
123
|
const raw = this.readBytes(U128_BYTE_LENGTH);
|
|
125
124
|
let bytes = raw;
|
|
126
|
-
// If data was written in little-endian, we reverse before interpreting
|
|
127
125
|
if (!be) {
|
|
128
126
|
bytes = this.reverseBytes(raw);
|
|
129
127
|
}
|
|
@@ -150,10 +148,8 @@ export class BinaryReader {
|
|
|
150
148
|
bytes = this.reverseBytes(raw);
|
|
151
149
|
}
|
|
152
150
|
|
|
153
|
-
// Construct as a 128-bit two's complement
|
|
154
151
|
let value = BigInt('0x' + this.toHexString(bytes));
|
|
155
152
|
|
|
156
|
-
// If the top bit is set (sign bit in big-endian), interpret negative
|
|
157
153
|
const signBitMask = 0x80;
|
|
158
154
|
if ((bytes[0] as number) & signBitMask) {
|
|
159
155
|
const twoTo128 = BigInt(1) << BigInt(128);
|
|
@@ -281,7 +277,7 @@ export class BinaryReader {
|
|
|
281
277
|
}
|
|
282
278
|
|
|
283
279
|
public readU8Array(): u8[] {
|
|
284
|
-
const length = this.readU16(true);
|
|
280
|
+
const length = this.readU16(true);
|
|
285
281
|
const result: u8[] = new Array<u8>(length);
|
|
286
282
|
for (let i = 0; i < length; i++) {
|
|
287
283
|
result[i] = this.readU8();
|