toiljs 0.0.16 → 0.0.20

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.
Files changed (100) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +313 -128
  3. package/as-pect.config.js +1 -1
  4. package/build/backend/.tsbuildinfo +1 -1
  5. package/build/backend/index.d.ts +1 -0
  6. package/build/backend/index.js +20 -1
  7. package/build/cli/.tsbuildinfo +1 -1
  8. package/build/cli/index.js +1320 -697
  9. package/build/client/.tsbuildinfo +1 -1
  10. package/build/client/dev/devtools.js +42 -5
  11. package/build/client/errors.d.ts +1 -0
  12. package/build/client/errors.js +3 -0
  13. package/build/client/index.d.ts +2 -0
  14. package/build/client/index.js +2 -0
  15. package/build/client/rpc.d.ts +1 -0
  16. package/build/client/rpc.js +37 -0
  17. package/build/compiler/.tsbuildinfo +1 -1
  18. package/build/compiler/config.js +3 -1
  19. package/build/compiler/docs.js +69 -7
  20. package/build/compiler/generate.js +5 -4
  21. package/build/compiler/index.d.ts +1 -0
  22. package/build/compiler/index.js +30 -1
  23. package/build/compiler/plugin.js +80 -8
  24. package/build/compiler/seo.js +15 -1
  25. package/build/compiler/ssg.js +7 -1
  26. package/build/compiler/vite.js +25 -0
  27. package/build/io/.tsbuildinfo +1 -1
  28. package/build/io/codec.d.ts +54 -0
  29. package/build/io/codec.js +143 -0
  30. package/build/io/index.d.ts +1 -2
  31. package/build/io/index.js +1 -2
  32. package/eslint.config.js +1 -1
  33. package/examples/basic/client/routes/features/index.tsx +1 -1
  34. package/examples/basic/client/routes/io.tsx +6 -7
  35. package/examples/basic/client/routes/rest.tsx +84 -0
  36. package/examples/basic/client/routes/rpc.tsx +43 -0
  37. package/package.json +19 -7
  38. package/presets/prettier-plugin.js +51 -0
  39. package/presets/prettier.json +1 -0
  40. package/server/runtime/README.md +97 -0
  41. package/server/runtime/abort/abort.ts +27 -0
  42. package/server/runtime/env/Server.ts +61 -0
  43. package/server/runtime/envelope.ts +191 -0
  44. package/server/runtime/exports/index.ts +52 -0
  45. package/server/runtime/handlers/ToilHandler.ts +34 -0
  46. package/server/runtime/index.ts +26 -0
  47. package/server/runtime/lang/Potential.ts +5 -0
  48. package/server/runtime/memory.ts +81 -0
  49. package/server/runtime/request.ts +55 -0
  50. package/server/runtime/response.ts +86 -0
  51. package/server/runtime/rest/Rest.ts +39 -0
  52. package/server/runtime/rest/RestHandler.ts +20 -0
  53. package/server/runtime/rest/RouteContext.ts +82 -0
  54. package/server/runtime/rest/match.ts +48 -0
  55. package/server/runtime/tsconfig.json +7 -0
  56. package/src/backend/index.ts +45 -3
  57. package/src/cli/create.ts +16 -6
  58. package/src/cli/diagnostics.ts +81 -0
  59. package/src/cli/doctor.ts +384 -7
  60. package/src/cli/index.ts +11 -2
  61. package/src/client/dev/devtools.tsx +49 -4
  62. package/src/client/errors.ts +11 -0
  63. package/src/client/index.ts +2 -0
  64. package/src/client/rpc.ts +64 -0
  65. package/src/compiler/config.ts +3 -1
  66. package/src/compiler/docs.ts +69 -7
  67. package/src/compiler/generate.ts +6 -5
  68. package/src/compiler/index.ts +50 -1
  69. package/src/compiler/plugin.ts +99 -11
  70. package/src/compiler/seo.ts +23 -3
  71. package/src/compiler/ssg.ts +10 -1
  72. package/src/compiler/vite.ts +34 -0
  73. package/src/io/FastMap.ts +24 -0
  74. package/src/io/FastSet.ts +15 -1
  75. package/src/io/codec.ts +217 -0
  76. package/src/io/index.ts +1 -2
  77. package/src/io/types.ts +2 -1
  78. package/test/assembly/example.spec.ts +14 -4
  79. package/test/doctor.test.ts +65 -0
  80. package/test/errors.test.ts +21 -0
  81. package/test/io.test.ts +65 -41
  82. package/test/prettier-plugin.test.ts +46 -0
  83. package/test/rpc.test.ts +50 -0
  84. package/tests/data-parity/generated-parity.ts +99 -0
  85. package/tests/data-parity/parity.ts +80 -0
  86. package/tests/data-parity/spec.ts +46 -0
  87. package/tsconfig.json +1 -1
  88. package/tsconfig.server.json +1 -1
  89. package/build/io/BinaryReader.d.ts +0 -44
  90. package/build/io/BinaryReader.js +0 -244
  91. package/build/io/BinaryWriter.d.ts +0 -44
  92. package/build/io/BinaryWriter.js +0 -297
  93. package/build/server/release.wasm +0 -0
  94. package/build/server/release.wat +0 -9
  95. package/src/io/BinaryReader.ts +0 -340
  96. package/src/io/BinaryWriter.ts +0 -385
  97. package/src/server/index.ts +0 -10
  98. package/src/server/main.ts +0 -13
  99. package/src/server/tsconfig.json +0 -4
  100. package/toilconfig.json +0 -30
package/README.md CHANGED
@@ -4,16 +4,23 @@
4
4
 
5
5
  # ToilJS
6
6
 
7
- ### Everything React forgot to ship.
7
+ ### The fullstack React framework, built for hyperscale.
8
8
 
9
- <sub>Fast by design. Architecture chosen for hyper scale: 50 Gbit/s on commodity hardware.</sub>
9
+ #### The first universal client and server framework.
10
+
11
+ <sub>Nothing to configure: routing, data, SEO, top-tier tooling, and full AI support, all built in.</sub>
12
+
13
+ <br/>
14
+
15
+ **⚡ First-class WebTransport over HTTP/3**, with automatic WebSocket fallback.
10
16
 
11
17
  <br/>
12
18
 
13
19
  [![npm](https://img.shields.io/npm/v/toiljs.svg?color=2563ff&label=npm&labelColor=0e1520)](https://www.npmjs.com/package/toiljs)
14
20
  [![types](https://img.shields.io/badge/types-included-2563ff.svg?labelColor=0e1520)](https://www.typescriptlang.org/)
15
21
  [![react](https://img.shields.io/badge/react-19-22e3ab.svg?labelColor=0e1520)](https://react.dev/)
16
- [![server](https://img.shields.io/badge/server-WebAssembly-7c3aed.svg?labelColor=0e1520)](#built-for-scale)
22
+ [![server](https://img.shields.io/badge/server-WebAssembly-7c3aed.svg?labelColor=0e1520)](#the-server-toilscript--webassembly)
23
+ [![webtransport](https://img.shields.io/badge/WebTransport-coming-654ff0.svg?labelColor=0e1520)](#realtime)
17
24
  [![license](https://img.shields.io/badge/license-Apache--2.0-8b9ab4.svg?labelColor=0e1520)](./LICENSE)
18
25
 
19
26
  <br/>
@@ -22,12 +29,15 @@
22
29
  <img src="https://img.shields.io/badge/TypeScript-3178c6?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript" />
23
30
  <img src="https://img.shields.io/badge/Vite-646cff?style=for-the-badge&logo=vite&logoColor=white" alt="Vite" />
24
31
  <img src="https://img.shields.io/badge/WebAssembly-654ff0?style=for-the-badge&logo=webassembly&logoColor=white" alt="WebAssembly" />
32
+ <img src="https://img.shields.io/badge/ToilScript-cb9820?style=for-the-badge&logoColor=white" alt="ToilScript" />
25
33
 
26
34
  </div>
27
35
 
28
36
  ---
29
37
 
30
- React gives you a renderer and leaves the rest to you: a router, a bundler, data fetching, SEO, an image pipeline, a server. ToilJS is all of it, already wired.
38
+ **ToilJS is a fullstack React framework built for hyperscale.** That is the whole point. Most React frameworks are built for convenience and start to buckle the moment real traffic arrives. Toil is built the other way around: for scale that serves the millionth request as easily as the first. Your client ships as a static bundle to the edge, and your server compiles to a single portable module designed to run at line rate, so the app you write on your laptop is shaped from day one to take serious load instead of folding under it.
39
+
40
+ And it is the entire stack, already wired and configured: routing, data, caching, SEO, site search, an image and font pipeline, realtime, a dev toolbar with AI, and a strict toolchain. One command scaffolds it, then you build your app, not your stack. Nothing to assemble, nothing to glue, nothing to configure.
31
41
 
32
42
  ```bash
33
43
  npx toiljs create my-app
@@ -35,93 +45,68 @@ cd my-app
35
45
  npm run dev
36
46
  ```
37
47
 
38
- Drop a `.tsx` file in `client/routes/` and it is a route: typed, code-split, prefetched, data loaded before render. The `server/` compiles to WebAssembly and self-hosts on uWebSockets. You configured nothing.
39
-
40
- ## Built for scale
41
-
42
- The backend is the point. `server/` is [ToilScript](https://www.npmjs.com/package/toilscript) compiled to a single WebAssembly module (Binaryen), and `toiljs start` self-hosts the app on [hyper-express](https://github.com/kartikk221/hyper-express), backed by [uWebSockets.js](https://github.com/uNetworking/uWebSockets.js), the same core that serves millions of HTTP requests per second.
48
+ Drop a `.tsx` file in `client/routes/` and it is a route: typed, code-split, prefetched, with its data loaded before render. Your `server/` is written in **ToilScript** (TypeScript syntax) and compiles to a single WebAssembly module. You configured nothing.
43
49
 
44
50
  <div align="center">
45
51
 
46
- ![throughput](https://img.shields.io/badge/throughput-50_Gbit%2Fs-2563ff?style=for-the-badge)
47
- ![requests](https://img.shields.io/badge/requests-millions%2Fsec-7c3aed?style=for-the-badge)
48
- ![compute](https://img.shields.io/badge/compute-native_WASM-22e3ab?style=for-the-badge)
49
- ![transport](https://img.shields.io/badge/transport-HTTP%2F3_+_WebTransport-654ff0?style=for-the-badge)
50
-
51
- </div>
52
-
53
- - **WebAssembly compute.** Your server logic runs as native-speed WASM, not interpreted JS.
54
- - **Binary on the wire.** The client and server share `BinaryWriter` / `BinaryReader` and `FastMap` / `FastSet`, so you move bytes, not JSON.
55
- - **HTTP/3 and WebTransport** over QUIC, low-latency streaming without the TCP head-of-line tax.
56
- - **Built for 50 Gbit/s on commodity hardware** and millions of requests per second, not toy demos.
57
-
58
- ```ts
59
- // server/index.ts
60
- export function add(a: i32, b: i32): i32 {
61
- return a + b;
62
- }
63
52
  ```
64
-
65
- ## On by default
66
-
67
- Every one of these works the moment you run `create`. No plugins to install, no config to write:
68
-
69
- - **Build-time SEO for an SPA**: prerendered `<head>`, `robots.txt`, `sitemap.xml`, `llms.txt`
70
- - **AI-crawler rules**: per-bot `robots.txt` plus `llms.txt`, one switch
71
- - **Image optimization on**: imports and plain `<img>` become resized webp
72
- - **Fonts preloaded** at build
73
- - **Typed routes**: `href` and `params` checked against your real files
74
- - **Loaders and mutations** with caching and revalidation, no data library, no `useEffect` fetching
75
- - **Parallel and intercepting routes** for modals and dashboards
76
- - **Instant navigation** and **animated view transitions**
77
- - **WebAssembly backend** on uWebSockets, with **binary IO** on both sides
78
-
79
- Anywhere else, that is a dozen packages and their config. Most teams wire three and ship the rest half-done.
80
-
81
- ## AI-ready
82
-
83
- ToilJS treats AI crawlers as first-class. Turn on SEO and the build emits an `llms.txt` describing your site for LLMs, and a `robots.txt` with explicit rules for the AI bots, allow or block GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, anthropic-ai, Google-Extended, PerplexityBot, CCBot, Applebot-Extended, Bytespider, Amazonbot, and Meta-ExternalAgent, with one switch.
84
-
85
- ```ts
86
- seo: { llms: { instructions: 'Docs live at /docs.' }, robots: { ai: 'disallow' } }
53
+ your app
54
+ ┌──────────────────────┬──────────────────────┐
55
+ │ client/ │ server/ │
56
+ │ React + TSX │ ToilScript (.ts) │
57
+ │ static SPA bundle │ ──▶ WebAssembly │
58
+ └──────────┬───────────┴───────────┬───────────┘
59
+ │ │
60
+ CDN / static host WASM edge runtime
61
+ (typed RPC between them)
87
62
  ```
88
63
 
89
- That one line produces a real `robots.txt`:
64
+ </div>
65
+
66
+ The client is fully static (host it anywhere). The server is a portable compiled module. The two are separated by design and joined by a typed contract, so the frontend can ship to a CDN while the backend runs wherever it is deployed.
90
67
 
91
- ```
92
- User-agent: *
93
- Allow: /
68
+ ## Built for scale
94
69
 
95
- User-agent: GPTBot
96
- Disallow: /
70
+ Toil's architecture is the scaling story. There is no monolith to keep warm and nothing re-rendering your pages on every request.
97
71
 
98
- User-agent: ClaudeBot
99
- Disallow: /
72
+ - **The client is static.** `build` emits a plain SPA bundle with each route's HTML already prerendered. It has no runtime server dependency, so it ships to any CDN or edge network and is cached and served close to every user.
73
+ - **The server is one portable module.** Your ToilScript backend compiles to a single self-contained module: no Node runtime to boot, no framework cold start, no per-request bootstrap. It is small, it starts instantly, and it runs the same everywhere.
74
+ - **Client and server are decoupled.** They are separate artifacts joined only by a typed contract, so the frontend scales as static files while the backend scales as stateless compute. Neither one bottlenecks the other.
75
+ - **Shaped for the edge.** That compiled module is exactly the unit a hyperscale edge runtime is built to serve: isolated per tenant, replicated across regions, run at line rate.
100
76
 
101
- User-agent: Google-Extended
102
- Disallow: /
77
+ That is the platform Toil is being built toward. The architecture above ships today; this is the stack that runs it at planetary scale:
103
78
 
104
- Sitemap: https://example.com/sitemap.xml
105
- ```
79
+ - **First-class WebTransport** *(coming)*: realtime over HTTP/3, multiplexed bidirectional streams and datagrams over QUIC with no head-of-line blocking. Toil is built to be the **first framework to ship first-class WebTransport**, and it falls back to WebSocket automatically, so the same channel API simply runs on the fastest transport available. WebSocket channels work today.
80
+ - **A purpose-built edge runtime** *(coming)*: your compiled server runs as an isolated tenant at line rate, replicated across regions, instead of on a general-purpose Node process.
81
+ - **ToilDB, edge-replicated typed data** *(coming)*: typed collections where the method name tells you the cost, local-fast reads, CRDT writes that merge everywhere, owner-routed writes, and rare global claims that are explicitly slow.
82
+ - **Post-quantum-ready transport** *(coming)*: forward-looking encryption as the QUIC layer lands.
83
+ - **Dacely Cloud** *(coming)*: managed hosting for the whole stack, push the app and the client goes to the edge while the server runs on the runtime.
106
84
 
107
- The `toiljs create` wizard can also scaffold assistant files (CLAUDE.md, AGENTS.md, Cursor and Copilot configs) so your repo is ready for coding agents on day one.
85
+ The same app runs on your laptop and is shaped, from the first commit, to fan out across the edge without a rewrite. Full architecture and status in [The road to hyperscale](#the-road-to-hyperscale).
108
86
 
109
87
  ## Everything, at a glance
110
88
 
89
+ This is the full surface area. Every row works the moment `create` finishes, no plugins to install, no config to write.
90
+
111
91
  | | |
112
92
  | --- | --- |
113
- | **Routing** | File-based. Dynamic, catch-all, optional catch-all, route groups, nested layouts, templates, parallel slots, and intercepting routes. Every `href` and `params` is typed. |
114
- | **Data** | A `loader` resolves before render. `useAction` / `<Form>` write then revalidate. Per-route caching. No fetch waterfalls. |
115
- | **SEO** | Per-route metadata baked into static HTML, plus `robots.txt`, `sitemap.xml`, `llms.txt`, OpenGraph, Twitter, JSON-LD, canonical, theme-color, early hints. |
116
- | **Assets** | Imported images compressed to webp and resized. Fonts preloaded. React split for caching. Build logs what it saved. |
117
- | **Realtime** | Built-in WebSocket channels: `connectChannel` / `useChannel`. WebTransport over HTTP/3. |
118
- | **DX** | HMR, instant navigation, view transitions, typed routes, and a dev error overlay. |
119
- | **Server** | ToilScript compiled to WebAssembly, self-hosted on uWebSockets with HTTP/3. Binary IO built in. |
120
- | **Tooling** | Strict TypeScript, ESLint, and Prettier, configured and enforced out of the box. Tailwind v4 optional. |
93
+ | **Zero config** | One command scaffolds a working app. You never write an `index.html`, a `main.tsx`, a router, or a Vite / build config. The framework generates and owns all of it. |
94
+ | **Routing** | File-based. Dynamic, catch-all, optional catch-all, route groups, nested layouts, templates, loading and error boundaries, parallel slots, and intercepting routes. Every `href` and `params` is typed against your real files. |
95
+ | **Navigation** | `Link` / `NavLink`, programmatic `navigate` / `back` / `forward` / `refresh`, hover and viewport prefetch, scroll restoration, instant back/forward, and animated view transitions. |
96
+ | **Data** | A `loader` resolves before render. `useAction` / `<Form>` write then revalidate. An LRU loader cache with per-route `revalidate`. No fetch waterfalls, no `useEffect` data fetching. |
97
+ | **Rendering + SEO** | Per-route `<head>` baked into static HTML at build, plus `sitemap.xml`, `robots.txt`, `llms.txt`, OpenGraph, Twitter, JSON-LD, canonical, theme-color, early hints. SSG via `generateStaticParams`. |
98
+ | **Search** | Built-in site search over a compiler-baked metadata index, ranked, with a `usePageSearch` hook. Plus `llms.txt` so AI crawlers can read your site. |
99
+ | **Assets** | Imported images compressed to webp and resized via Vite + sharp. Fonts preloaded. React split into its own long-lived chunk. The build logs what it saved. |
100
+ | **Components** | Drop-in `Image` (no layout shift, lazy, blur), `Script` (load strategies, dedupe), `Form`, `Slot`, `Head`, all on a typed `Toil` global, zero imports. |
101
+ | **Realtime** | Typed channels: `connectChannel` / `useChannel`, reconnect built in, text or binary frames. WebSocket today, with first-class WebTransport over HTTP/3 coming (automatic WebSocket fallback). |
102
+ | **Server** | A typed ToilScript server compiled to a portable, native-speed module. `Request` / `Response` REST handlers, binary IO on both sides, and a typed RPC surface generated from your server. |
103
+ | **Agentic DX** | A dev toolbar with a live AI tab (hand off page context to Claude or ChatGPT), a Cmd+K palette, and scaffolded agent files (CLAUDE.md, AGENTS.md, Cursor, Copilot). |
104
+ | **Toolkit** | Strict TypeScript, ESLint, and Prettier shipped as presets, plus optional git init. Tailwind v4, Sass, Less, and Stylus a flag away. |
105
+ | **CLI** | `create`, `dev`, `build`, `start`, `configure`, `doctor` (with `--json` for CI), and `update`. |
121
106
 
122
107
  ## Routing
123
108
 
124
- The filesystem is the router.
109
+ The filesystem is the router. Every convention below is implemented.
125
110
 
126
111
  | File or folder | Route |
127
112
  | --- | --- |
@@ -144,14 +129,14 @@ Navigation comes with it:
144
129
 
145
130
  - **`<Toil.Link>`** and **`<Toil.NavLink>`** (active class + `aria-current`), with `href` checked against your real routes.
146
131
  - **`navigate` / `back` / `forward` / `refresh`**, plus **`useRouter`**, **`useNavigate`**, **`useLocation`**, **`usePathname`**, **`useParams`**, **`useSearchParams`**, **`useNavigationPending`**.
147
- - **Hover and viewport prefetching**, so chunks are warm before you click.
132
+ - **Hover and viewport prefetching**, so chunks (and data) are warm before you click. Respects `saveData` and `data-no-prefetch`.
148
133
  - **Scroll restoration** on back/forward, scroll-to-`#hash`, and scroll-to-top on new routes.
149
134
  - **Instant navigation**: visited pages render synchronously, no flash.
150
135
  - **View transitions** (`client.viewTransitions: true`) for animated page changes, respecting `prefers-reduced-motion`.
151
136
 
152
- ## Data
137
+ ## Data and caching
153
138
 
154
- Read with a `loader`, write with an action. Both keep the UI in sync without manual refetching.
139
+ Read with a `loader`, write with an action. Both keep the UI in sync without manual refetching, and the client caches loader results so repeat navigations are instant.
155
140
 
156
141
  ```tsx
157
142
  export const loader = async ({ params }: Toil.LoaderArgs) => fetchPost(params.id);
@@ -169,20 +154,10 @@ function SaveButton({ title }: { title: string }) {
169
154
 
170
155
  - **`loader`** resolves in parallel with the route chunk; the page suspends until ready (its `loading.tsx` shows).
171
156
  - **`useLoaderData(loader)`** is typed straight from the loader, no generics.
172
- - **`revalidate`** sets the cache policy per route; **`router.revalidate()`** / **`revalidate(href)`** bust it after a mutation.
173
- - **`useAction`** and **`<Toil.Form>`** track pending and error state and revalidate on success.
174
-
175
- ## Components
176
-
177
- Zero-import, on the `Toil` global:
157
+ - **Client cache**: an LRU of loader results keyed by path + search, with `revalidate` set per route (seconds, `false` for forever, or per-navigation). Prefetched entries are reused on commit.
158
+ - **`useAction`** and **`<Toil.Form>`** track pending and error state and revalidate the routes you name on success. `router.revalidate()` / `revalidate(href)` bust the cache after a mutation.
178
159
 
179
- - **`Image`** drops in for `<img>`: reserves space (no layout shift), lazy-loads, async-decodes, `priority` for the LCP image, `fill` + `objectFit`, optional blur placeholder.
180
- - **`Script`** loads external or inline scripts with a `strategy` (`afterInteractive` / `lazyOnload` / `beforeInteractive`), deduplicated so a script never runs twice.
181
- - **`Form`** submits to an action without a reload, revalidates on success, exposes pending state, optionally resets fields.
182
- - **`Slot`** renders a parallel `@slot` route, the basis for modal overlays.
183
- - **`Head`** / **`useHead`** / **`useTitle`** set the title and `<meta>` / `<link>` tags imperatively and compose across the tree.
184
-
185
- ## Head and SEO
160
+ ## Rendering and SEO
186
161
 
187
162
  A single-page app serves an empty shell. ToilJS pre-renders each route's `<head>` at build, so Google, Facebook, Discord, Slack, and the AI crawlers see real per-page tags without running your JavaScript.
188
163
 
@@ -205,14 +180,23 @@ export default defineConfig({
205
180
  ```
206
181
 
207
182
  - **Per-route `metadata`** (or `generateMetadata` derived from the loader's data) wins per page over layout defaults.
208
- - **Static prerender** writes a `<route>/index.html` for every static route with that route's head baked in.
183
+ - **Static prerender** writes a `<route>/index.html` for every static route with that route's head baked in. **SSG** enumerates dynamic routes via `generateStaticParams` and bakes per-URL HTML.
209
184
  - **`robots.txt`**, **`sitemap.xml`**, and **`llms.txt`** generated together.
210
- - Full **OpenGraph** (image alt/width/height/type, locale), **Twitter card**, **`fb:app_id`**, **JSON-LD**, **canonical**, **theme-color**, and **`preconnect` / `dns-prefetch`** early hints.
211
- - Output is **XSS-hardened**: attribute values and inline JSON-LD are escaped so injected data can't break out.
185
+ - Full **OpenGraph**, **Twitter card**, **JSON-LD**, **canonical**, **theme-color**, and **`preconnect` / `dns-prefetch`** early hints. Output is XSS-hardened.
212
186
 
213
- ## Build and assets
187
+ ### AI search, on by default
214
188
 
215
- ToilJS owns Vite and does the boring optimization for you. The build tells you what it did:
189
+ Turn on SEO and the build emits an `llms.txt` describing your site for language models, plus a `robots.txt` with explicit per-bot rules. Allow or block GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, anthropic-ai, Google-Extended, PerplexityBot, CCBot, Applebot-Extended, Bytespider, Amazonbot, and Meta-ExternalAgent with one switch:
190
+
191
+ ```ts
192
+ seo: { llms: { instructions: 'Docs live at /docs.' }, robots: { ai: 'disallow' } }
193
+ ```
194
+
195
+ Your users get search too. The compiler bakes a static index of every page's title, description, and keywords, and `Toil.usePageSearch` (or the pure `searchPages`) returns ranked, navigable results.
196
+
197
+ ## Assets and the Vite build
198
+
199
+ ToilJS owns Vite, for the dev server and for the ahead-of-time production build, and does the boring optimization for you. The build tells you what it did:
216
200
 
217
201
  ```
218
202
  $ npm run build
@@ -223,47 +207,59 @@ $ npm run build
223
207
  → fonts/inter-latin.woff2 24.10 kB
224
208
  ```
225
209
 
226
- - **Images** (`vite-imagetools` + `sharp`): every imported raster is compressed to webp, resize and reformat with `?w=400;800&format=webp&as=srcset`. The build logs the savings.
210
+ - **Images** (Vite imagetools + sharp): every imported raster is compressed to webp, with resize and reformat via `?w=400;800&format=webp&as=srcset`. The build logs the savings.
227
211
  - **Fonts**: bundled `@font-face` fonts get a `<link rel="preload">` so text paints sooner, also logged.
228
212
  - **Chunking**: React is split into its own long-lived chunk; assets land in tidy `images/`, `fonts/`, and `css/` folders.
229
213
  - **Node polyfills** (`Buffer`, `global`, `process`) for libraries that expect them.
230
214
  - **Styling**: plain CSS out of the box, with Sass, Less, Stylus, and Tailwind v4 a `toiljs configure` away.
231
215
 
216
+ You never write an `index.html`, a `main.tsx`, or a Vite config. The framework generates and owns them.
217
+
218
+ ## Components
219
+
220
+ Zero-import, on the `Toil` global:
221
+
222
+ - **`Image`** drops in for `<img>`: reserves space (no layout shift), lazy-loads, async-decodes, `priority` for the LCP image, `fill` + `objectFit`, optional blur placeholder.
223
+ - **`Script`** loads external or inline scripts with a `strategy` (`afterInteractive` / `lazyOnload` / `beforeInteractive`), deduplicated so a script never runs twice.
224
+ - **`Form`** submits to an action without a reload, revalidates on success, exposes pending state, optionally resets fields.
225
+ - **`Slot`** renders a parallel `@slot` route, the basis for modal overlays.
226
+ - **`Head`** / **`useHead`** / **`useTitle`** set the title and `<meta>` / `<link>` tags imperatively and compose across the tree.
227
+
232
228
  ## Realtime
233
229
 
234
- A typed WebSocket channel to the server, built in.
230
+ One typed channel API for live data in both directions.
235
231
 
236
232
  ```tsx
237
233
  const messages = Toil.useChannel<Message>('/chat');
238
234
  ```
239
235
 
240
- `connectChannel` / `useChannel` / `resolveChannelUrl` handle connection, reconnection, and message decoding.
236
+ `connectChannel` / `useChannel` / `resolveChannelUrl` handle connection, reconnection, and message decoding, text or binary frames. Today the channel runs over WebSocket. Next it rides **WebTransport** over HTTP/3: multiplexed bidirectional streams and datagrams over QUIC with no head-of-line blocking. Toil is built to be the **first framework to ship first-class WebTransport**, with automatic WebSocket fallback, so the same `useChannel` quietly upgrades to the fastest transport the client and network support, with no code change.
241
237
 
242
- ## Binary IO
238
+ ## The server: ToilScript + WebAssembly
243
239
 
244
- The same primitives on both sides of the wire, available as globals (and `toiljs/io`): `BinaryWriter`, `BinaryReader`, `FastMap`, `FastSet`. Move structured data without the JSON tax.
240
+ Your backend is written in **ToilScript**, a TypeScript-syntax language that compiles to WebAssembly. You write request handlers; the compiler produces a single portable `.wasm` module.
245
241
 
246
- ## Tooling is the standard
247
-
248
- ToilJS sets the toolchain so nobody argues about it. Strict TypeScript, ESLint, and Prettier come configured and enforced from the first commit. New apps are wired automatically, nothing to set up, nothing to copy, nothing to bikeshed. This is the standard, not a suggestion.
242
+ ```ts
243
+ // server/HelloHandler.ts
244
+ export class HelloHandler extends ToilHandler {
245
+ handle(req: Request): Response {
246
+ if (req.path == '/api/hello') return Response.json('{"hello":"world"}');
247
+ return Response.notFound();
248
+ }
249
+ }
250
+ ```
249
251
 
250
- ## CLI
252
+ - **REST handlers**: `Request` (method, path, headers, body) in, `Response` out, with `text` / `html` / `json` / `notFound` / `badRequest` / `internalError` helpers and the full set of HTTP methods.
253
+ - **Binary IO on both sides**: `DataWriter`, `DataReader`, `FastMap`, and `FastSet` are shared client and server globals (and `toiljs/io`), so you can move structured bytes instead of paying the JSON tax.
254
+ - **Typed RPC (preview)**: tag a server function and the compiler generates a typed `Server.*` surface on the client, end to end, no hand-written glue. The typed pipeline is in place today; the network transport is landing next.
251
255
 
252
- ```
253
- toiljs create [name] scaffold a new app (styling, AI files, package manager)
254
- toiljs dev dev server with HMR
255
- toiljs build production build
256
- toiljs start self-host the build (hyper-express / uWebSockets)
257
- toiljs configure toggle styling, image, font, and SEO features
258
- toiljs doctor diagnose project setup and dependencies (--json for CI)
259
- toiljs update check for and apply dependency updates (-y to apply all)
260
- ```
256
+ `toiljs start` self-hosts the built client and a WebSocket channel on [hyper-express](https://github.com/kartikk221/hyper-express) (backed by uWebSockets.js) for local and small deployments. For where this is headed at scale, see [The road to hyperscale](#the-road-to-hyperscale).
261
257
 
262
- ## Dev toolbar
258
+ ## Agentic tooling
263
259
 
264
- `toiljs dev` injects a floating toolbar (bottom corner) that surfaces the framework's live state and is stripped from production builds entirely, no flag, no leftover bytes. It reads the matched route, params, and active slots; the loader cache (with revalidate and clear buttons); the live `<head>` with an OpenGraph preview and an SEO checklist; resolved config flags and versions; a captured error log; and live toggles for view and loader transitions. Click a route to navigate, or open its file in your editor.
260
+ `toiljs dev` injects a floating toolbar (stripped from production builds entirely, no flag, no leftover bytes) that surfaces the framework's live state: the matched route, params, and active slots; the loader cache with revalidate and clear buttons; the live `<head>` with an OpenGraph preview and an SEO checklist; resolved config flags and versions; a captured error log; and toggles for view and loader transitions. Press **Cmd/Ctrl+K** for a command palette to jump to any route or run a dev action.
265
261
 
266
- It also ships an **AI tab**: hand off the current page's context to Claude or ChatGPT in one click, or wire a provider for inline answers. The key is read server-side and never reaches the browser.
262
+ It also ships an **AI tab**: hand off the current page's context (and its source) to Claude or ChatGPT in one click, or wire a provider for inline answers. The API key is read server-side only and never reaches the browser.
267
263
 
268
264
  ```ts
269
265
  import { defineConfig, AiProvider } from 'toiljs/compiler';
@@ -281,24 +277,61 @@ export default defineConfig({
281
277
  });
282
278
  ```
283
279
 
284
- `devtools: false` turns it off; the hand-off links work with no config at all. Press `cmd`/`ctrl`+`K` for a command palette to jump to any route or run a dev action.
280
+ And the `toiljs create` wizard scaffolds assistant files (CLAUDE.md, AGENTS.md, Cursor, and Copilot configs) so your repo is ready for coding agents on day one.
285
281
 
286
- ## Tech
282
+ ## The toolkit is the standard
287
283
 
288
- <div align="center">
284
+ ToilJS sets the toolchain so nobody argues about it. Strict TypeScript, ESLint (typescript-eslint, react-hooks, react-refresh, @eslint-react), and Prettier come configured and enforced from the first commit, shipped as `toiljs/tsconfig`, `toiljs/eslint`, and `toiljs/prettier`. New apps extend them automatically and can init git in the same step. Opt in to as much as you want, nothing to copy, nothing to bikeshed.
289
285
 
290
- <img src="https://img.shields.io/badge/React_19-20232a?style=for-the-badge&logo=react&logoColor=61dafb" alt="React 19" />
291
- <img src="https://img.shields.io/badge/TypeScript-3178c6?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript" />
292
- <img src="https://img.shields.io/badge/Vite-646cff?style=for-the-badge&logo=vite&logoColor=white" alt="Vite" />
293
- <img src="https://img.shields.io/badge/WebAssembly-654ff0?style=for-the-badge&logo=webassembly&logoColor=white" alt="WebAssembly" />
294
- <img src="https://img.shields.io/badge/sharp-99cc00?style=for-the-badge&logo=sharp&logoColor=white" alt="sharp" />
295
- <img src="https://img.shields.io/badge/ESLint-4b32c3?style=for-the-badge&logo=eslint&logoColor=white" alt="ESLint" />
296
- <img src="https://img.shields.io/badge/Prettier-f7b93e?style=for-the-badge&logo=prettier&logoColor=black" alt="Prettier" />
297
- <img src="https://img.shields.io/badge/Tailwind_v4-06b6d4?style=for-the-badge&logo=tailwindcss&logoColor=white" alt="Tailwind v4" />
286
+ ## Configuration
298
287
 
299
- </div>
288
+ One file, `toil.config.ts`, typed with `defineConfig`. Every option has a sensible default, so most apps only set `seo`.
300
289
 
301
- React 19, TypeScript, Vite, ToilScript (compiles to WebAssembly, on Binaryen), hyper-express + uWebSockets.js, vite-imagetools + sharp, ESLint (typescript-eslint, react-hooks, react-refresh, @eslint-react), Prettier, Tailwind v4 (optional).
290
+ ```ts
291
+ import { defineConfig } from 'toiljs/compiler';
292
+
293
+ export default defineConfig({
294
+ client: {
295
+ srcDir: 'client', // source root (default: client)
296
+ routesDir: 'routes', // route folder (default: routes)
297
+ base: '/', // base path (default: /)
298
+ port: 3000, // dev / start port (default: 3000)
299
+ images: true, // webp + resize pipeline (default: true)
300
+ fonts: true, // preload bundled fonts (default: true)
301
+ viewTransitions: false, // animated navigation (default: false)
302
+ transitions: false, // keep page during load (default: false)
303
+ devtools: true, // dev toolbar, or { ai } (default: true)
304
+ seo: {
305
+ // url, title, openGraph, twitter, jsonLd, robots, themeColor, ...
306
+ },
307
+ vite: {
308
+ // escape hatch: a full Vite InlineConfig, merged on top
309
+ },
310
+ },
311
+ });
312
+ ```
313
+
314
+ Set any feature to `false` to turn it off. `client.vite` is merged into the generated Vite config for the rare case you need to reach the bundler directly.
315
+
316
+ ## CLI
317
+
318
+ ```
319
+ toiljs create [name] scaffold a new app
320
+ toiljs dev dev server with HMR
321
+ toiljs build ahead-of-time production build
322
+ toiljs start self-host the built client + realtime channel
323
+ toiljs configure toggle styling and asset features on an existing app
324
+ toiljs doctor diagnose project setup and dependencies
325
+ toiljs update check for and apply dependency updates
326
+ ```
327
+
328
+ - **`create [name]`** runs an interactive wizard: template (`app` or `minimal`), CSS flavor (`css` / `sass` / `less` / `stylus`), Tailwind, which AI assistant files to scaffold, image optimization, git init, and package manager (`npm` / `pnpm` / `yarn` / `bun`). Every prompt has a flag (`--template`, `--style`, `--tailwind`, `--ai`, `--images`, `--git`, `--install`, `--pm`), and `--yes` runs it non-interactively.
329
+ - **`dev`** starts the Vite dev server with HMR and regenerates the route table as you add or remove files. `--port` to override.
330
+ - **`build`** produces the optimized static client: prerendered HTML, `sitemap.xml`, `robots.txt`, `llms.txt`, and compressed images and fonts.
331
+ - **`start`** self-hosts the build and a realtime channel at `/_toil` on hyper-express. `--port` (default 3000), `--host` (pass `0.0.0.0` to expose on the network).
332
+ - **`configure`** edits an existing app: switch CSS preprocessor, toggle Tailwind or image optimization, and sync dependencies.
333
+ - **`doctor`** runs read-only checks across environment, routing, config, assets, and the server build, with a fix hint on each. `--json` for CI; it exits non-zero when a check fails.
334
+ - **`update`** checks the registry and groups available updates by major / minor / patch; pick what to apply or pass `-y` for all (`--target` sets the strategy).
302
335
 
303
336
  ## One file does a lot
304
337
 
@@ -328,12 +361,164 @@ export default function PostPage() {
328
361
 
329
362
  No imports. `Toil` is a fully-typed global, tree-shaken at build. The page renders with its data already loaded.
330
363
 
364
+ ## Architecture
365
+
366
+ One pipeline, from your editor to planetary scale. The build pipeline and the React client ship today; the edge runtime, the ToilDB data layer, and Dacely Cloud are the roadmap (marked in purple).
367
+
368
+ ```mermaid
369
+ flowchart TB
370
+ classDef today fill:#0e1520,stroke:#2563ff,stroke-width:2px,color:#cfe0ff;
371
+ classDef soon fill:#160f1f,stroke:#7c3aed,stroke-width:2px,color:#ead7ff,stroke-dasharray:6 4;
372
+
373
+ subgraph BUILD["BUILD, toiljs CLI, shipping today"]
374
+ direction TB
375
+ TSX["client/ &nbsp; React + TSX routes"] --> VITE["Vite<br/>HMR + ahead-of-time build"] --> ART["static client<br/>prerendered HTML<br/>sitemap, robots, llms<br/>optimized images + fonts"]
376
+ TS["server/ &nbsp; ToilScript .ts"] --> TSC["toilscript compiler"] --> WASM["one .wasm module"]
377
+ TOOL["toolkit: TypeScript, ESLint, Prettier, git<br/>dev toolbar: routes, loader cache, head/OG, errors<br/>AI tab to Claude / ChatGPT, Cmd-K palette<br/>typed RPC surface Server.*"]
378
+ end
379
+
380
+ CLIENTS["CLIENTS<br/>browsers, mobile, API clients, AI crawlers / LLMs"]
381
+
382
+ subgraph EDGE["EDGE, anycast, multi-region POPs, scale-out, roadmap"]
383
+ direction LR
384
+ SC["STATIC CLIENT<br/>React SPA + baked HTML<br/>images, fonts, css<br/>served from CDN / edge"]
385
+ RT["WASM EDGE RUNTIME<br/>your ToilScript server as one .wasm<br/>isolated per-core tenant at line rate<br/>Request to handler to Response<br/>realtime channels, binary IO<br/>x many tenants x many POPs"]
386
+ SC <-->|"typed RPC&nbsp; Server.*"| RT
387
+ end
388
+
389
+ subgraph DATA["ToilDB, edge-replicated typed data, roadmap"]
390
+ direction LR
391
+ MODES["collections<br/>owned, eventLog, counter, set<br/>unique, escrow, snapshot<br/>local reads fast, CRDT writes merge everywhere<br/>owned writes fast at owner, global claims slow"]
392
+ DUR["durable store<br/>structured records"]
393
+ BLOB["blob store<br/>large objects"]
394
+ MODES --> DUR
395
+ MODES --> BLOB
396
+ end
397
+
398
+ CTRL["DACELY CLOUD, control plane, roadmap<br/>deploy, distribute, scale<br/>client to the edge, .wasm to the runtime, data replicated"]
399
+
400
+ ART -->|deploys| SC
401
+ WASM -->|deploys| RT
402
+ CLIENTS -->|"HTTP/1.1 + WebSocket today<br/>HTTP/3, QUIC, WebTransport roadmap<br/>TLS today, post-quantum roadmap"| EDGE
403
+ RT -->|"region-replicated"| DATA
404
+ CTRL -. orchestrates .-> EDGE
405
+ CTRL -. orchestrates .-> DATA
406
+
407
+ class TSX,VITE,ART,TS,TSC,WASM,TOOL,CLIENTS today;
408
+ class SC,RT,MODES,DUR,BLOB,CTRL soon;
409
+ ```
410
+
411
+ <details>
412
+ <summary>Same diagram as plain ASCII (for npm and text-only views)</summary>
413
+
414
+ ```
415
+ ┌──────────────────────────────────────────────────────────────────────────┐
416
+ │ BUILD toiljs CLI [today] │
417
+ │ │
418
+ │ client/ React + TSX routes ──▶ Vite (HMR ahead-of-time build) ──┐ │
419
+ │ server/ ToilScript (.ts) ──▶ toilscript compiler ──▶ one .wasm │ │
420
+ │ │ │
421
+ │ toolkit TypeScript ESLint Prettier git (opt-in presets) │ │
422
+ │ dev toolbar: routes loader cache head/OG errors │ │
423
+ │ AI tab → Claude / ChatGPT ⌘K palette │ │
424
+ │ emits static client prerendered HTML sitemap robots llms │ │
425
+ │ optimized images / fonts typed RPC surface (Server.*) │ │
426
+ └───────────────────────────────────────────────────────────────┬─────┬───┘
427
+ deploys ▼ │ │ ▼
428
+ ┌──────────────────────────────────────────────────────────────────────────┐
429
+ │ CLIENTS │
430
+ │ browsers mobile webviews API clients AI crawlers/LLMs │
431
+ └───────────────────────────────────┬──────────────────────────────────────┘
432
+ HTTP/1.1 + WebSocket [today] │ HTTP/3 QUIC WebTransport [soon]
433
+ TLS [today] │ post-quantum transport [soon]
434
+
435
+ ╔══════════════════════════════════════════════════════════════════════════╗
436
+ ║ EDGE anycast multi-region POPs scale-out [soon] ║
437
+ ║ ║
438
+ ║ ┌─────────────────────────┐ ┌─────────────────────────────────┐ ║
439
+ ║ │ STATIC CLIENT │ │ WASM EDGE RUNTIME │ ║
440
+ ║ │ React SPA + baked HTML │ │ your ToilScript server as one │ ║
441
+ ║ │ images fonts css │ typed│ .wasm, run as an isolated │ ║
442
+ ║ │ served from CDN / edge │◀──RPC─▶│ per-core tenant at line rate │ ║
443
+ ║ │ │ Server.* Request ▶ handler ▶ Response │ ║
444
+ ║ │ llms robots sitemap │ │ realtime channels binary IO │ ║
445
+ ║ └─────────────────────────┘ └───────────────┬─────────────────┘ ║
446
+ ║ instant, cacheable × many tenants × many POPs ║
447
+ ╚═══════════════════════════════════════════════════════╪══════════════════╝
448
+ ▼ region-replicated
449
+ ╔══════════════════════════════════════════════════════════════════════════╗
450
+ ║ ToilDB edge-replicated, typed data layer [soon] ║
451
+ ║ ║
452
+ ║ collections: owned eventLog counter set unique escrow ║
453
+ ║ snapshot (the method name tells you the cost) ║
454
+ ║ local reads fast CRDT writes merge everywhere ║
455
+ ║ owned writes fast at the owner global claims explicitly slow ║
456
+ ║ ║
457
+ ║ ┌──────────────────────┐ ┌──────────────────────┐ ║
458
+ ║ │ durable store │ │ blob store │ ║
459
+ ║ │ structured records │ │ large objects │ ║
460
+ ║ └──────────────────────┘ └──────────────────────┘ ║
461
+ ╚═══════════════════════════════════════════════════════╪══════════════════╝
462
+
463
+ ╔══════════════════════════════════════════════════════════════════════════╗
464
+ ║ DACELY CLOUD control plane: deploy distribute scale [soon] ║
465
+ ║ push your app ─▶ client to the edge, .wasm to the runtime, data replicated ║
466
+ ╚══════════════════════════════════════════════════════════════════════════╝
467
+
468
+ [today] shipping now [soon] architecture + roadmap, not yet GA
469
+ ```
470
+
471
+ </details>
472
+
473
+ ---
474
+
475
+ ## The road to hyperscale
476
+
477
+ > **Architecture and roadmap.** This section is where Toil is going, not what ships in the box today. The framework above is real and usable now; the platform below is the design it is being built toward.
478
+
479
+ The reason the client is static and the server is WebAssembly is that the WebAssembly runs on a runtime engineered from scratch for the edge. Toil's backend treats your compiled server as an isolated tenant and is built to serve it at line rate, so the same app that runs on your laptop is designed to scale out across the edge without a rewrite.
480
+
481
+ <div align="center">
482
+
483
+ ![runtime](https://img.shields.io/badge/runtime-WASM_edge-2563ff?style=for-the-badge)
484
+ ![transport](https://img.shields.io/badge/transport-HTTP%2F3_+_WebTransport-654ff0?style=for-the-badge)
485
+ ![data](https://img.shields.io/badge/data-edge_replicated-22e3ab?style=for-the-badge)
486
+ ![security](https://img.shields.io/badge/security-post--quantum-7c3aed?style=for-the-badge)
487
+
488
+ </div>
489
+
490
+ - **A purpose-built WebAssembly edge runtime.** Your server runs as an isolated WebAssembly tenant on a runtime engineered for line-rate, multi-gigabit throughput and per-tenant isolation, not on a general-purpose Node process.
491
+ - **HTTP/3 and WebTransport.** Bidirectional streams and datagrams over QUIC for interactive, multiplexed realtime, beyond the WebSocket channel that ships today.
492
+ - **ToilDB, an edge-replicated data layer.** Typed collections declared in ToilScript, where the method name tells you the cost: local reads are fast, appends and CRDT counters/sets merge everywhere, owned writes are fast at the owner, and rare global claims are explicitly slow. Hyperscale data, without a per-query consistency knob to get wrong.
493
+ - **Post-quantum-ready transport.** Forward-looking encryption for the edge as the QUIC layer lands.
494
+ - **Dacely Cloud.** Managed hosting for the whole stack: push your app, the static client goes to the edge and your WebAssembly server runs on the runtime above.
495
+
496
+ This is the spine the framework was shaped around. Today you write a typed, file-based React app with a WebAssembly server; the roadmap is the platform that runs it at planetary scale.
497
+
498
+ ## Tech
499
+
500
+ <div align="center">
501
+
502
+ <img src="https://img.shields.io/badge/React_19-20232a?style=for-the-badge&logo=react&logoColor=61dafb" alt="React 19" />
503
+ <img src="https://img.shields.io/badge/TypeScript-3178c6?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript" />
504
+ <img src="https://img.shields.io/badge/Vite-646cff?style=for-the-badge&logo=vite&logoColor=white" alt="Vite" />
505
+ <img src="https://img.shields.io/badge/WebAssembly-654ff0?style=for-the-badge&logo=webassembly&logoColor=white" alt="WebAssembly" />
506
+ <img src="https://img.shields.io/badge/ToilScript-cb9820?style=for-the-badge&logoColor=white" alt="ToilScript" />
507
+ <img src="https://img.shields.io/badge/sharp-99cc00?style=for-the-badge&logo=sharp&logoColor=white" alt="sharp" />
508
+ <img src="https://img.shields.io/badge/ESLint-4b32c3?style=for-the-badge&logo=eslint&logoColor=white" alt="ESLint" />
509
+ <img src="https://img.shields.io/badge/Prettier-f7b93e?style=for-the-badge&logo=prettier&logoColor=black" alt="Prettier" />
510
+ <img src="https://img.shields.io/badge/Tailwind_v4-06b6d4?style=for-the-badge&logo=tailwindcss&logoColor=white" alt="Tailwind v4" />
511
+
512
+ </div>
513
+
514
+ React 19, TypeScript, Vite, [ToilScript](https://www.npmjs.com/package/toilscript) (TypeScript syntax, compiles to WebAssembly), Vite imagetools + sharp, ESLint (typescript-eslint, react-hooks, react-refresh, @eslint-react), Prettier, Tailwind v4 (optional).
515
+
331
516
  ## Start
332
517
 
333
518
  ```bash
334
519
  npx toiljs create my-app
335
520
  ```
336
521
 
337
- Everything in this README is already on. You just build the app.
522
+ Everything in the framework half of this README is already on. You just build the app.
338
523
 
339
- <div align="center"><br/><sub>Apache-2.0</sub></div>
524
+ <div align="center"><br/><sub>Apache-2.0, <a href="https://toil.org">toil.org</a></sub></div>
package/as-pect.config.js CHANGED
@@ -56,7 +56,7 @@ export default {
56
56
  },
57
57
 
58
58
  /** Enable code coverage. */
59
- coverage: ['src/server/**/*.ts', 'src/server/*.ts'],
59
+ coverage: ['server/**/*.ts', 'server/*.ts'],
60
60
 
61
61
  /**
62
62
  * Specify if the binary wasm file should be written to the file system.