toiljs 0.0.116 → 0.0.118

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 (337) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +16 -7
  3. package/build/backend/.tsbuildinfo +1 -1
  4. package/build/cli/.tsbuildinfo +1 -1
  5. package/build/cli/index.js +2375 -258
  6. package/build/client/.tsbuildinfo +1 -1
  7. package/build/client/auth.d.ts +3 -0
  8. package/build/client/auth.js +19 -10
  9. package/build/client/dev/devtools.js +1 -1
  10. package/build/client/dev/error-overlay.js +1 -1
  11. package/build/client/index.d.ts +1 -1
  12. package/build/client/index.js +1 -1
  13. package/build/client/navigation/navigation.js +28 -3
  14. package/build/client/routing/Router.js +5 -2
  15. package/build/client/routing/mount.js +1 -1
  16. package/build/compiler/.tsbuildinfo +1 -1
  17. package/build/compiler/auth-emails.js +7 -3
  18. package/build/compiler/emails.js +1 -1
  19. package/build/compiler/index.d.ts +1 -0
  20. package/build/compiler/index.js +26 -5
  21. package/build/compiler/pages.js +2 -3
  22. package/build/compiler/prerender.d.ts +3 -8
  23. package/build/compiler/prerender.js +88 -127
  24. package/build/compiler/ssg.js +3 -4
  25. package/build/compiler/template-build.js +3 -4
  26. package/build/compiler/toil-docs.generated.js +8 -7
  27. package/build/compiler/vite.js +4 -6
  28. package/build/devserver/.tsbuildinfo +1 -1
  29. package/build/devserver/db/database.js +7 -3
  30. package/build/devserver/db/types.js +1 -1
  31. package/build/devserver/production.js +4 -3
  32. package/build/devserver/runtime/crypto.d.ts +1 -1
  33. package/build/io/.tsbuildinfo +1 -1
  34. package/build/logger/.tsbuildinfo +1 -1
  35. package/build/shared/.tsbuildinfo +1 -1
  36. package/examples/basic/client/routes/analytics.tsx +7 -5
  37. package/examples/basic/client/routes/pq.tsx +2 -1
  38. package/examples/basic/server/tsconfig.json +1 -3
  39. package/package.json +45 -44
  40. package/presets/no-uint8array-tostring.js +120 -153
  41. package/presets/oxlint.d.ts +5 -0
  42. package/presets/oxlint.js +224 -0
  43. package/server/auth/AuthController.ts +53 -14
  44. package/server/auth/FactorSettings.ts +41 -0
  45. package/server/auth/SessionEpochs.ts +58 -0
  46. package/server/auth/SessionRevocations.ts +13 -0
  47. package/server/globals/auth.ts +27 -2
  48. package/server/runtime/tsconfig.json +1 -3
  49. package/tsconfig.json +2 -11
  50. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  51. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -90
  52. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  53. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  54. package/.github/PULL_REQUEST_TEMPLATE.md +0 -43
  55. package/.github/changelog-config.json +0 -45
  56. package/.github/dependabot.yml +0 -27
  57. package/.github/workflows/ci.yml +0 -222
  58. package/.vscode/settings.json +0 -10
  59. package/docs/README.md +0 -107
  60. package/docs/auth/README.md +0 -104
  61. package/docs/auth/configuration.md +0 -105
  62. package/docs/auth/emails.md +0 -92
  63. package/docs/auth/extending.md +0 -202
  64. package/docs/auth/how-it-works.md +0 -138
  65. package/docs/auth/usage.md +0 -188
  66. package/docs/backend/README.md +0 -143
  67. package/docs/backend/data.md +0 -351
  68. package/docs/backend/rest.md +0 -402
  69. package/docs/backend/rpc.md +0 -226
  70. package/docs/background/README.md +0 -114
  71. package/docs/background/daemons.md +0 -276
  72. package/docs/background/derive.md +0 -179
  73. package/docs/cli/README.md +0 -379
  74. package/docs/concepts/ai-guide.md +0 -132
  75. package/docs/concepts/config.md +0 -416
  76. package/docs/concepts/decorators.md +0 -127
  77. package/docs/concepts/security.md +0 -108
  78. package/docs/concepts/tiers.md +0 -166
  79. package/docs/concepts/types.md +0 -216
  80. package/docs/database/README.md +0 -143
  81. package/docs/database/capacity.md +0 -350
  82. package/docs/database/counters.md +0 -174
  83. package/docs/database/documents.md +0 -277
  84. package/docs/database/events.md +0 -307
  85. package/docs/database/membership.md +0 -246
  86. package/docs/database/setup.md +0 -155
  87. package/docs/database/unique.md +0 -216
  88. package/docs/database/views.md +0 -246
  89. package/docs/frontend/README.md +0 -104
  90. package/docs/frontend/components.md +0 -286
  91. package/docs/frontend/data-fetching.md +0 -260
  92. package/docs/frontend/images.md +0 -148
  93. package/docs/frontend/metadata.md +0 -344
  94. package/docs/frontend/navigation.md +0 -296
  95. package/docs/frontend/rendering.md +0 -236
  96. package/docs/frontend/routing.md +0 -346
  97. package/docs/frontend/scripts.md +0 -118
  98. package/docs/frontend/search.md +0 -191
  99. package/docs/frontend/styling.md +0 -147
  100. package/docs/frontend/toil-global.md +0 -216
  101. package/docs/getting-started/README.md +0 -81
  102. package/docs/getting-started/create-project.md +0 -131
  103. package/docs/getting-started/deploy.md +0 -101
  104. package/docs/getting-started/first-app.md +0 -215
  105. package/docs/getting-started/installation.md +0 -124
  106. package/docs/getting-started/migrating.md +0 -125
  107. package/docs/getting-started/project-structure.md +0 -163
  108. package/docs/introduction/README.md +0 -66
  109. package/docs/introduction/design-principles.md +0 -81
  110. package/docs/introduction/distributed.md +0 -91
  111. package/docs/introduction/how-it-works.md +0 -121
  112. package/docs/introduction/hyperscale.md +0 -70
  113. package/docs/introduction/modern-stack.md +0 -85
  114. package/docs/introduction/vs-other-frameworks.md +0 -64
  115. package/docs/introduction/why-toil.md +0 -99
  116. package/docs/llms.txt +0 -95
  117. package/docs/realtime/README.md +0 -102
  118. package/docs/realtime/channels.md +0 -211
  119. package/docs/realtime/streams.md +0 -369
  120. package/docs/services/README.md +0 -60
  121. package/docs/services/analytics.md +0 -279
  122. package/docs/services/caching.md +0 -175
  123. package/docs/services/cookies.md +0 -235
  124. package/docs/services/crypto.md +0 -209
  125. package/docs/services/email.md +0 -289
  126. package/docs/services/environment.md +0 -141
  127. package/docs/services/ratelimit.md +0 -174
  128. package/docs/services/time.md +0 -85
  129. package/eslint.config.js +0 -57
  130. package/examples/basic/client/routes/docs/[...slug].tsx +0 -12
  131. package/presets/eslint.js +0 -88
  132. package/src/backend/index.ts +0 -204
  133. package/src/cli/configure.ts +0 -363
  134. package/src/cli/create.ts +0 -924
  135. package/src/cli/db.ts +0 -158
  136. package/src/cli/diagnostics.ts +0 -665
  137. package/src/cli/doctor.ts +0 -982
  138. package/src/cli/features.ts +0 -170
  139. package/src/cli/index.ts +0 -326
  140. package/src/cli/notify.ts +0 -120
  141. package/src/cli/proc.ts +0 -56
  142. package/src/cli/ui.ts +0 -169
  143. package/src/cli/update.ts +0 -248
  144. package/src/cli/updates.ts +0 -92
  145. package/src/cli/validate.ts +0 -31
  146. package/src/cli/version-check.ts +0 -125
  147. package/src/client/auth.ts +0 -869
  148. package/src/client/channel/channel.ts +0 -146
  149. package/src/client/components/Form.tsx +0 -65
  150. package/src/client/components/Image.tsx +0 -160
  151. package/src/client/components/Script.tsx +0 -113
  152. package/src/client/components/Slot.tsx +0 -21
  153. package/src/client/dev/devtools.tsx +0 -1089
  154. package/src/client/dev/error-overlay.tsx +0 -225
  155. package/src/client/errors.ts +0 -11
  156. package/src/client/head/head.ts +0 -182
  157. package/src/client/head/metadata.ts +0 -110
  158. package/src/client/index.ts +0 -130
  159. package/src/client/navigation/Link.tsx +0 -108
  160. package/src/client/navigation/NavLink.tsx +0 -86
  161. package/src/client/navigation/navigation.ts +0 -235
  162. package/src/client/navigation/prefetch.ts +0 -169
  163. package/src/client/navigation/scroll.ts +0 -53
  164. package/src/client/routing/Router.tsx +0 -216
  165. package/src/client/routing/action.ts +0 -122
  166. package/src/client/routing/error-boundary.tsx +0 -43
  167. package/src/client/routing/hooks.ts +0 -140
  168. package/src/client/routing/lazy.ts +0 -77
  169. package/src/client/routing/loader.ts +0 -381
  170. package/src/client/routing/match.ts +0 -47
  171. package/src/client/routing/mount.tsx +0 -90
  172. package/src/client/routing/params-context.ts +0 -10
  173. package/src/client/routing/slot-context.ts +0 -7
  174. package/src/client/rpc.ts +0 -97
  175. package/src/client/search/search.ts +0 -189
  176. package/src/client/search/use-page-search.ts +0 -73
  177. package/src/client/ssr/markers.tsx +0 -172
  178. package/src/client/stream/client.ts +0 -237
  179. package/src/client/types.ts +0 -73
  180. package/src/compiler/auth-emails.ts +0 -312
  181. package/src/compiler/config.ts +0 -369
  182. package/src/compiler/docs.ts +0 -127
  183. package/src/compiler/email-preview.ts +0 -314
  184. package/src/compiler/emails.ts +0 -404
  185. package/src/compiler/fonts.ts +0 -89
  186. package/src/compiler/generate.ts +0 -471
  187. package/src/compiler/image-blur.ts +0 -42
  188. package/src/compiler/image-report.ts +0 -88
  189. package/src/compiler/index.ts +0 -1362
  190. package/src/compiler/pages.ts +0 -49
  191. package/src/compiler/plugin.ts +0 -391
  192. package/src/compiler/prerender.ts +0 -263
  193. package/src/compiler/routes.ts +0 -170
  194. package/src/compiler/seo.ts +0 -415
  195. package/src/compiler/sri.ts +0 -144
  196. package/src/compiler/ssg.ts +0 -177
  197. package/src/compiler/ssr-codegen.ts +0 -85
  198. package/src/compiler/template-build.ts +0 -676
  199. package/src/compiler/template.ts +0 -262
  200. package/src/compiler/toil-docs.generated.ts +0 -77
  201. package/src/compiler/vite.ts +0 -245
  202. package/src/devserver/analytics/index.ts +0 -317
  203. package/src/devserver/config/dotenv.ts +0 -102
  204. package/src/devserver/config/env.ts +0 -30
  205. package/src/devserver/config/ratelimit.ts +0 -123
  206. package/src/devserver/daemon/catalog.ts +0 -120
  207. package/src/devserver/daemon/cron.ts +0 -87
  208. package/src/devserver/daemon/host.ts +0 -134
  209. package/src/devserver/daemon/index.ts +0 -369
  210. package/src/devserver/daemon/runtime.ts +0 -48
  211. package/src/devserver/db/catalog.ts +0 -109
  212. package/src/devserver/db/database.ts +0 -1834
  213. package/src/devserver/db/derives.ts +0 -121
  214. package/src/devserver/db/index.ts +0 -20
  215. package/src/devserver/db/routeKinds.ts +0 -191
  216. package/src/devserver/db/types.ts +0 -168
  217. package/src/devserver/email/caps.ts +0 -0
  218. package/src/devserver/email/config.ts +0 -141
  219. package/src/devserver/email/console.ts +0 -348
  220. package/src/devserver/email/index.ts +0 -155
  221. package/src/devserver/email/providers.ts +0 -131
  222. package/src/devserver/email/status.ts +0 -23
  223. package/src/devserver/email/validate.ts +0 -37
  224. package/src/devserver/email/wire.ts +0 -55
  225. package/src/devserver/http/cache.ts +0 -0
  226. package/src/devserver/http/envelope.ts +0 -157
  227. package/src/devserver/http/proxy.ts +0 -172
  228. package/src/devserver/http/runtime.ts +0 -387
  229. package/src/devserver/index.ts +0 -43
  230. package/src/devserver/production-ipc.ts +0 -63
  231. package/src/devserver/production-worker.ts +0 -83
  232. package/src/devserver/production.ts +0 -718
  233. package/src/devserver/runtime/crypto.ts +0 -587
  234. package/src/devserver/runtime/host.ts +0 -427
  235. package/src/devserver/runtime/module.ts +0 -442
  236. package/src/devserver/server.ts +0 -251
  237. package/src/devserver/ssr.ts +0 -208
  238. package/src/devserver/stream/catalog.ts +0 -106
  239. package/src/devserver/stream/host.ts +0 -42
  240. package/src/devserver/stream/index.ts +0 -301
  241. package/src/devserver/stream/manager.ts +0 -167
  242. package/src/devserver/stream/router.ts +0 -101
  243. package/src/devserver/stream/wire.ts +0 -58
  244. package/src/devserver/stream/ws.ts +0 -78
  245. package/src/devserver/wasm/sections.ts +0 -59
  246. package/src/devserver/wasm/surface.ts +0 -115
  247. package/src/io/FastMap.ts +0 -151
  248. package/src/io/FastSet.ts +0 -113
  249. package/src/io/codec.ts +0 -362
  250. package/src/io/index.ts +0 -10
  251. package/src/io/lengths.ts +0 -14
  252. package/src/io/types.ts +0 -19
  253. package/src/logger/index.ts +0 -22
  254. package/src/shared/index.ts +0 -46
  255. package/test/analytics-dev.test.ts +0 -113
  256. package/test/assembly/aspect-shim.ts +0 -33
  257. package/test/assembly/cookie.spec.ts +0 -303
  258. package/test/assembly/example.spec.ts +0 -22
  259. package/test/assembly/ssr.spec.ts +0 -95
  260. package/test/assembly.test.ts +0 -59
  261. package/test/auth-emails.test.ts +0 -118
  262. package/test/built-ssr.test.ts +0 -148
  263. package/test/channel.test.ts +0 -21
  264. package/test/config-host-port.test.ts +0 -59
  265. package/test/configure.test.ts +0 -94
  266. package/test/daemon-build.test.ts +0 -278
  267. package/test/daemon-catalog.test.ts +0 -349
  268. package/test/daemon-emulation.test.ts +0 -256
  269. package/test/db.test.ts +0 -0
  270. package/test/devserver-database.test.ts +0 -1102
  271. package/test/devserver-email.test.ts +0 -306
  272. package/test/devserver-pqauth.test.ts +0 -93
  273. package/test/devserver-secrets.test.ts +0 -63
  274. package/test/devserver.test.ts +0 -259
  275. package/test/doctor.test.ts +0 -298
  276. package/test/dom/Image.test.tsx +0 -144
  277. package/test/dom/Link.test.tsx +0 -67
  278. package/test/dom/NavLink.test.tsx +0 -37
  279. package/test/dom/Script.test.tsx +0 -48
  280. package/test/dom/action.test.tsx +0 -146
  281. package/test/dom/error-overlay.test.tsx +0 -44
  282. package/test/dom/loader.test.tsx +0 -121
  283. package/test/dom/navigation.test.ts +0 -59
  284. package/test/dom/revalidate.test.tsx +0 -38
  285. package/test/dom/route-head.test.tsx +0 -56
  286. package/test/dom/router-loading.test.tsx +0 -44
  287. package/test/dom/scroll.test.ts +0 -56
  288. package/test/dom/slot.test.tsx +0 -131
  289. package/test/dom/use-metadata.test.tsx +0 -58
  290. package/test/dom/view-transitions.test.tsx +0 -53
  291. package/test/dynamic-routing.test.ts +0 -132
  292. package/test/email-console.test.ts +0 -86
  293. package/test/email-preview.test.ts +0 -73
  294. package/test/emails.test.ts +0 -58
  295. package/test/errors.test.ts +0 -21
  296. package/test/example-guestbook.test.ts +0 -123
  297. package/test/features.test.ts +0 -149
  298. package/test/fixtures/bignum-wire/spec.ts +0 -25
  299. package/test/fixtures/daemon-app.ts +0 -65
  300. package/test/fixtures/stream-echo.ts +0 -26
  301. package/test/fixtures/stream-gate.ts +0 -28
  302. package/test/fixtures/stream-trap.ts +0 -18
  303. package/test/fixtures/stream-typed.ts +0 -41
  304. package/test/fonts.test.ts +0 -28
  305. package/test/global-setup.ts +0 -17
  306. package/test/head.test.ts +0 -42
  307. package/test/image-blur.test.ts +0 -50
  308. package/test/io.test.ts +0 -117
  309. package/test/metadata.test.ts +0 -40
  310. package/test/navlink.test.ts +0 -28
  311. package/test/pages.test.ts +0 -105
  312. package/test/placeholder.test.ts +0 -9
  313. package/test/pqauth-e2e.test.ts +0 -216
  314. package/test/pqauth-email.test.ts +0 -801
  315. package/test/prerender.test.ts +0 -116
  316. package/test/prettier-plugin.test.ts +0 -46
  317. package/test/routes.test.ts +0 -76
  318. package/test/rpc-bignum-wire.test.ts +0 -164
  319. package/test/rpc-dispatch.test.ts +0 -132
  320. package/test/rpc-kinds.test.ts +0 -18
  321. package/test/rpc.test.ts +0 -66
  322. package/test/search.test.ts +0 -114
  323. package/test/seo.test.ts +0 -175
  324. package/test/slot-layouts.test.ts +0 -69
  325. package/test/sri.test.ts +0 -129
  326. package/test/ssg.test.ts +0 -36
  327. package/test/ssr-hydration.test.tsx +0 -122
  328. package/test/ssr-render.test.ts +0 -197
  329. package/test/ssr-template.test.tsx +0 -482
  330. package/test/stream-emulation.test.ts +0 -479
  331. package/test/ui.test.ts +0 -40
  332. package/test/update.test.ts +0 -58
  333. package/test/validate.test.ts +0 -42
  334. package/test/version-check.test.ts +0 -130
  335. package/tests/data-parity/generated-parity.ts +0 -99
  336. package/tests/data-parity/parity.ts +0 -80
  337. package/tests/data-parity/spec.ts +0 -46
@@ -1,216 +0,0 @@
1
- # The Toil global (reference)
2
-
3
- Almost the entire toiljs client API hangs off one global object, `Toil`, so your route files need no imports for the everyday things. This page is the full index: every `Toil.*` member, its TypeScript signature, and a one-line description, grouped by area. Reach for it when you know roughly what you want and just need the exact name or shape; the deeper guides (linked per section) explain the concepts.
4
-
5
- `Toil` is not a hand-written object. It is the module namespace of the `toiljs/client` package, exposed as a global. The compiler writes a `toil-env.d.ts` at your project root containing `declare const Toil: typeof import('toiljs/client')`, so `Toil` is typed as the whole package and every member autocompletes with no import. Put another way: anything you could `import { X } from 'toiljs/client'` is reachable as `Toil.X`.
6
-
7
- A few members are also bare globals, handed to you the same way. `Server` (the typed backend client) and `parseError` are global on their own and additionally live under `Toil` (so `Server` and `Toil.Server` are the same value, likewise `parseError`). `FastMap`, `FastSet`, `DataWriter`, and `DataReader` (the fast collections and compact binary codec from `toiljs/io`, see [Data types](../backend/data.md)) are bare globals only: they are not under `Toil`, so write `new DataWriter()`, never `new Toil.DataWriter()`.
8
-
9
- ## Components (JSX)
10
-
11
- Drop-in components you render in JSX. See [Images](./images.md), [Scripts](./scripts.md), [Fetching data](./data-fetching.md), and [Metadata and SEO](./metadata.md) for the detail.
12
-
13
- | Member | Signature | Description |
14
- | --- | --- | --- |
15
- | `Toil.Image` | `Image(props: ImageProps): ReactNode` | A drop-in `<img>` that reserves space (no layout shift), lazy-loads, and can fade in from a blur placeholder. See [Images](./images.md). |
16
- | `Toil.Script` | `Script(props: ScriptProps): ReactNode` | Loads an external or inline `<script>` with a load `strategy`, deduplicated so it runs at most once. Renders nothing. See [Scripts](./scripts.md). |
17
- | `Toil.Form` | `Form(props: FormProps): ReactNode` | A `<form>` that runs an action on submit (no reload) and revalidates loader data on success. See [Fetching data](./data-fetching.md). |
18
- | `Toil.Slot` | `Slot(props: SlotProps): ReactNode` | Renders the parallel-route slot named `props.name` (`{ name: string; fallback?: ReactNode }`) for the current URL. See [Routing](./routing.md). |
19
- | `Toil.Head` | `Head(props: HeadSpec): null` | Declarative form of `useHead`: `<Toil.Head title="..." meta={[...]} />`. Renders nothing. See [Metadata and SEO](./metadata.md). |
20
- | `Toil.Metadata` | `Metadata(props: Metadata): null` | Declarative form of `useMetadata`: `<Toil.Metadata title="..." openGraph={...} />`. Renders nothing. See [Metadata and SEO](./metadata.md). |
21
- | `Toil.Router` | `Router(props: { routes; layout?; notFound?; globalError?; slots? }): ReactNode` | The app router element. `Toil.mount` renders this for you, so you rarely use it directly. |
22
-
23
- ## SSR marker primitives
24
-
25
- These mark a route's dynamic bits so the edge can server-render it (the compiler's template extractor finds them deterministically). They are transparent at runtime: in the browser they render exactly the normal tree. See [Components](./components.md) and [Rendering and SSR](./rendering.md).
26
-
27
- | Member | Signature | Description |
28
- | --- | --- | --- |
29
- | `Toil.Hole` | `Hole(props: HoleProps): ReactNode` | A scalar text hole (`{ id: string; children?: ReactNode }`); renders `children` in the browser, a text insertion point under the SSR extractor. |
30
- | `Toil.Repeat` | `Repeat<T>(props: RepeatProps<T>): ReactNode` | A repeat region (`{ id; each: readonly T[]; children: (item: T, index: number) => ReactNode }`); `each.map(children)` in the browser. |
31
- | `Toil.RawHtml` | `RawHtml(props: RawHtmlProps): ReactNode` | A raw-HTML block hole (`{ id; html; as? }`); wraps `dangerouslySetInnerHTML` in a host element (default `div`). |
32
- | `Toil.attr` | `attr(id: string, value: string): string` | An attribute-value hole, used in attribute position (`href={Toil.attr('u', d.url)}`); returns `value` unchanged in the browser. |
33
- | `Toil.Island` | `Island(props: IslandProps): ReactNode` | A client-only escape hatch (`{ children? }`); renders nothing on the server and first paint, then reveals `children` after mount (so no SSR / SEO, by design). |
34
-
35
- ## Navigation
36
-
37
- Client-side links and imperative navigation. Detailed guide: [Navigation](./navigation.md).
38
-
39
- | Member | Signature | Description |
40
- | --- | --- | --- |
41
- | `Toil.Link` | `Link(props: LinkProps): ReactNode` | A client-side navigation `<a>`: no full reload, prefetches on hover/focus, falls through to the browser for external / `target` / `download` / `#hash` links. |
42
- | `Toil.NavLink` | `NavLink(props: NavLinkProps): ReactNode` | A `Link` that adds an active class (default `"active"`) and `aria-current="page"` when it points at the current page. |
43
- | `Toil.matchActive` | `matchActive(linkPath: string, currentPath: string, end: boolean): boolean` | Whether a link to `linkPath` is active for `currentPath` (the pure rule behind `NavLink`). |
44
- | `Toil.navigate` | `navigate(href: Href, options?: NavigateOptions): void` | Navigate in code (no hook needed), pushing history or replacing with `{ replace: true }`. |
45
- | `Toil.back` | `back(): void` | Go back one history entry. |
46
- | `Toil.forward` | `forward(): void` | Go forward one history entry. |
47
- | `Toil.refresh` | `refresh(): void` | Re-render the current route and re-run its loader (its `loading.tsx` shows while it re-fetches). |
48
- | `Toil.href` | `href(path: string): Href` | Assert a runtime-built string is a valid `Href`. Escape hatch for a path assembled from data. |
49
- | `Toil.prefetch` | `prefetch(href: string): void` | Warm a route's chunk ahead of navigation; a no-op for external, unknown, or already-warmed targets. |
50
- | `Toil.setViewTransitions` | `setViewTransitions(enabled: boolean): void` | Enable animated View Transitions for navigation (normally set once from `client.viewTransitions`). |
51
- | `Toil.setTransitions` | `setTransitions(enabled: boolean): void` | Keep the current page visible until the next route is ready (normally set once from `client.transitions`). |
52
-
53
- ## Routing and location hooks
54
-
55
- Hooks a component uses to read where it is and to get a router handle.
56
-
57
- | Member | Signature | Description |
58
- | --- | --- | --- |
59
- | `Toil.useParams` | `useParams<T extends RouteParams = RouteParams>(): T` | Read the dynamic route params, e.g. `{ id }` for `/blog/[id]`. Values are always strings. |
60
- | `Toil.useNavigate` | `useNavigate(): (href: Href, options?: NavigateOptions) => void` | Returns the bare `navigate` function. |
61
- | `Toil.useRouter` | `useRouter(): RouterInstance` | Returns the router handle (`push` / `replace` / `back` / `forward` / `refresh` / `revalidate` / `prefetch`). |
62
- | `Toil.useLocation` | `useLocation(): string` | The current pathname, re-read on each navigation (an alias of `usePathname`). |
63
- | `Toil.usePathname` | `usePathname(): string` | The current pathname, e.g. `"/blog/42"`. |
64
- | `Toil.useSearchParams` | `useSearchParams(): URLSearchParams` | The query string as a `URLSearchParams`, re-read on each navigation. |
65
- | `Toil.useNavigationPending` | `useNavigationPending(): boolean` | `true` while a navigation is in flight (drives a top loading bar). |
66
- | `Toil.matchRoute` | `matchRoute(pattern: string, pathname: string): RouteParams \| null` | Pure route matcher: extract params, or `null` if the pattern does not match. |
67
-
68
- ## Route data and mutations
69
-
70
- Loaders read data on navigation, actions write it. See [Fetching data](./data-fetching.md).
71
-
72
- | Member | Signature | Description |
73
- | --- | --- | --- |
74
- | `Toil.useLoaderData` | `useLoaderData<L extends LoaderFunction>(loader: L): Awaited<ReturnType<L>>` | Read the data the current route's `loader` returned. Passing `loader` infers the type; the no-arg `useLoaderData<T>()` returns `unknown` unless you supply `T`. |
75
- | `Toil.revalidate` | `revalidate(href?: string): void` | Invalidate loader data and re-render so the active route (or a given href) re-fetches. Call after a mutation; usable outside React. |
76
- | `Toil.invalidateLoaderData` | `invalidateLoaderData(href?: string): void` | Drop cached loader data (all routes, or one href) without re-rendering. |
77
- | `Toil.useAction` | `useAction<TInput = void, TData = unknown>(fn: (input: TInput) => TData \| Promise<TData>, options?: UseActionOptions<TData>): ActionHandle<TInput, TData>` | Run a mutation with pending / error / result tracking; revalidates loader data on success. |
78
-
79
- ## Head and metadata
80
-
81
- Set the document `<head>` from a component or resolve a route's metadata. See [Metadata and SEO](./metadata.md).
82
-
83
- | Member | Signature | Description |
84
- | --- | --- | --- |
85
- | `Toil.useHead` | `useHead(spec: HeadSpec): void` | Apply a title / `<meta>` / `<link>` contribution for the component's lifetime (reverts on unmount, composes across the tree). |
86
- | `Toil.useTitle` | `useTitle(title: string): void` | Set `document.title` for the component's lifetime. |
87
- | `Toil.mergeHead` | `mergeHead(specs: readonly HeadSpec[]): ResolvedHead` | Merge head specs in order: the last `title` wins, `meta` dedupes by name/property, `link` by rel+href. |
88
- | `Toil.useMetadata` | `useMetadata(metadata: Metadata): void` | Apply a route-style `Metadata` object from inside any component (the runtime counterpart of a route's `metadata` export). |
89
- | `Toil.resolveMetadata` | `resolveMetadata(metadata: Metadata): HeadSpec` | Expand a `Metadata` object into a title plus concrete `<meta>` / `<link>` tags. |
90
-
91
- ## Page search
92
-
93
- Query the statically-baked index of your pages' metadata. See [Search](./search.md).
94
-
95
- | Member | Signature | Description |
96
- | --- | --- | --- |
97
- | `Toil.searchPages` | `searchPages(query: string, options?: PageSearchOptions): PageSearchResult[]` | Rank the registered page index against a query (pure, framework-agnostic; AND semantics across terms). |
98
- | `Toil.usePageSearch` | `usePageSearch(query: string, options?: PageSearchOptions): PageSearch` | React binding for `searchPages`, memoized, with a `goTo` helper that navigates to a match. |
99
- | `Toil.registerPages` | `registerPages(pages: readonly PageMeta[]): void` | Replace the live page index. Called once at startup by the generated bundle; rarely called by user code. |
100
- | `Toil.getPages` | `getPages(): readonly PageMeta[]` | The registered page index (every page, including dynamic ones). Empty before registration. |
101
- | `Toil.pagePath` | `pagePath(target: string \| PageMeta \| PageSearchResult): string` | Normalize a result / page / raw path to its route path string. |
102
-
103
- ## Realtime
104
-
105
- Open a channel or a typed stream to the backend. See [Channels](../realtime/channels.md) and [Streams](../realtime/streams.md).
106
-
107
- | Member | Signature | Description |
108
- | --- | --- | --- |
109
- | `Toil.connectChannel` | `connectChannel(onMessage: (data: ChannelData) => void, options?: ChannelOptions): Channel` | Open a WebSocket channel to the backend, invoking `onMessage` per frame; returns `send` / `close`. |
110
- | `Toil.useChannel` | `useChannel(options?: ChannelOptions): ChannelHook` | React hook over `connectChannel`: connects on mount, tracks `connected` + `messages`, exposes `send`. |
111
- | `Toil.resolveChannelUrl` | `resolveChannelUrl(path?: string, location?: { protocol: string; host: string }): string` | Derive the channel's `ws(s)://` URL from the current page location. |
112
- | `Toil.makeStreamClient` | `makeStreamClient(routes: Record<string, string>, origin?: string, encoders?: Record<string, (msg: never) => Uint8Array>): StreamClient` | Build the `Server.Stream` client from the generated route map. Used by generated code; rarely called directly. |
113
-
114
- ## Backend client, errors, bootstrap
115
-
116
- | Member | Signature | Description |
117
- | --- | --- | --- |
118
- | `Toil.Server` | `Server.REST.<controller>.<route>(args)` / `Server.Stream.<class>.connect(path?)` / `Server.<service>.<method>(args)` | The typed backend surface. Its shape is generated into `shared/server.ts`; this global is the runtime behind it. See [Fetching data](./data-fetching.md). |
119
- | `Toil.parseError` | `parseError(err: unknown): string` | Extract a human-readable message from an unknown thrown value: `Error.message`, else `String(err)`. |
120
- | `Toil.mount` | `mount(routes: RouteDef[], layout?: LayoutLoader, notFound?: NotFoundLoader, globalError?: ErrorComponentLoader, slots?: Record<string, RouteDef[]>): void` | Boot the app into `#root` and start idle link prefetching. Called by the generated entry file; you rarely call it yourself. |
121
-
122
- ## Auth
123
-
124
- The whole password-auth client lives under `Toil.Auth`, and its error family is exposed on `Toil.*` (and mirrored under `Toil.Auth.*`) so you can branch on it. The password never leaves the browser. See [Auth](../auth/README.md).
125
-
126
- | Member | Signature | Description |
127
- | --- | --- | --- |
128
- | `Toil.Auth.register` | `register(username: string, password: string, email: string, opts?: AuthOptions): Promise<void>` | Create an account (only a derived public key is ever sent). Throws `UsernameTakenError` / `EmailInUseError` on conflict. |
129
- | `Toil.Auth.login` | `login(username: string, password: string, opts?: AuthOptions): Promise<Uint8Array>` | Log in with mutual authentication; resolves to the opaque session token. |
130
- | `Toil.Auth.confirmEmail` | `confirmEmail(token: string, opts?: AuthOptions): Promise<void>` | Confirm an account from the one-time token in the emailed link. |
131
- | `Toil.Auth.resendConfirmation` | `resendConfirmation(email: string, opts?: AuthOptions): Promise<void>` | Ask the server to re-send the confirmation email (never reveals whether the address exists). |
132
- | `Toil.Auth.requestPasswordReset` | `requestPasswordReset(email: string, opts?: AuthOptions): Promise<void>` | Begin a password reset by emailing a link (anti-enumeration: always resolves). |
133
- | `Toil.Auth.resetPassword` | `resetPassword(token: string, newPassword: string, opts?: AuthOptions): Promise<void>` | Complete a reset from the token plus a new password. |
134
- | `Toil.Auth.verifyTwoFactor` | `verifyTwoFactor(twoFaId: string, code: string, opts?: AuthOptions): Promise<Uint8Array>` | Finish a 2FA login by submitting the code for `twoFaId`; resolves to the session token. |
135
- | `Toil.Auth.setupTwoFactor` | `setupTwoFactor(method: number, opts?: AuthOptions): Promise<void>` | Begin enabling or disabling 2FA for the current session user (pass a `TwoFactorMethod` value). |
136
- | `Toil.Auth.confirmTwoFactorSetup` | `confirmTwoFactorSetup(code: string, opts?: AuthOptions): Promise<void>` | Confirm a pending `setupTwoFactor` with the delivered code. |
137
- | `Toil.Auth.twoFactorStatus` | `twoFactorStatus(opts?: AuthOptions): Promise<number>` | The current user's 2FA method (a `TwoFactorMethod` value; `0` means off). |
138
- | `Toil.Auth.TwoFactorMethod` | `{ None: 0, Email: 1 }` | The 2FA method values, mirroring the server enum. |
139
-
140
- The typed error surface (each error carries a stable `code`, and every subclass maps 1:1 to an `AuthErrorCode`):
141
-
142
- | Member | Signature | Description |
143
- | --- | --- | --- |
144
- | `Toil.AuthError` | `class AuthError extends Error { readonly code: AuthErrorCode }` | Base class for every auth error. `err instanceof Toil.AuthError` narrows the whole family; `err.code` discriminates within it. |
145
- | `Toil.AuthErrorCode` | `enum AuthErrorCode` (string values) | The stable, machine-readable discriminant carried as `err.code`. Branch on this, never on `err.message` or `err.name`. |
146
- | `Toil.UsernameTakenError` | `class UsernameTakenError extends AuthError` | register: the username is already registered (`AuthErrorCode.UsernameTaken`). |
147
- | `Toil.EmailInUseError` | `class EmailInUseError extends AuthError` | register: the email is already in use (`AuthErrorCode.EmailInUse`). |
148
- | `Toil.InvalidCredentialsError` | `class InvalidCredentialsError extends AuthError` | login: wrong username or password (`AuthErrorCode.InvalidCredentials`). |
149
- | `Toil.EmailNotConfirmedError` | `class EmailNotConfirmedError extends AuthError` | login: valid credential, but the email is not confirmed (`AuthErrorCode.EmailNotConfirmed`). |
150
- | `Toil.TwoFactorRequiredError` | `class TwoFactorRequiredError extends AuthError { readonly twoFaId: string }` | login: a second factor is required; echo `err.twoFaId` to `verifyTwoFactor` (`AuthErrorCode.TwoFactorRequired`). |
151
- | `Toil.ServerAuthFailedError` | `class ServerAuthFailedError extends AuthError` | login/2fa: the server failed to prove its identity, possible MITM (`AuthErrorCode.ServerAuthFailed`). |
152
- | `Toil.TwoFactorCodeError` | `class TwoFactorCodeError extends AuthError` | 2fa: the code was wrong, expired, or already used (`AuthErrorCode.TwoFactorCodeInvalid`). |
153
- | `Toil.ConfirmationInvalidError` | `class ConfirmationInvalidError extends AuthError` | confirm: the confirmation link was invalid or expired (`AuthErrorCode.ConfirmationInvalid`). |
154
- | `Toil.PasswordResetInvalidError` | `class PasswordResetInvalidError extends AuthError` | reset: the reset link was invalid or expired (`AuthErrorCode.PasswordResetInvalid`). |
155
-
156
- The `AuthErrorCode` string values:
157
-
158
- ```ts
159
- enum AuthErrorCode {
160
- RequestFailed = 'request_failed',
161
- ProtocolError = 'protocol_error',
162
- UsernameTaken = 'username_taken',
163
- EmailInUse = 'email_in_use',
164
- RegistrationRejected = 'registration_rejected',
165
- InvalidCredentials = 'invalid_credentials',
166
- EmailNotConfirmed = 'email_not_confirmed',
167
- TwoFactorRequired = 'two_factor_required',
168
- ServerAuthFailed = 'server_auth_failed',
169
- TwoFactorCodeInvalid = 'two_factor_code_invalid',
170
- TwoFactorSetupFailed = 'two_factor_setup_failed',
171
- ConfirmationInvalid = 'confirmation_invalid',
172
- PasswordResetInvalid = 'password_reset_invalid',
173
- }
174
- ```
175
-
176
- Catch by class for the common branches, or on `err.code` for a precise check:
177
-
178
- ```tsx
179
- try {
180
- const token = await Toil.Auth.login(username, password);
181
- // ... persist the session token and redirect
182
- } catch (err) {
183
- if (err instanceof Toil.EmailNotConfirmedError) return promptEmailConfirmation();
184
- if (err instanceof Toil.TwoFactorRequiredError) return promptTwoFactorCode(err.twoFaId);
185
- if (err instanceof Toil.AuthError && err.code === Toil.AuthErrorCode.InvalidCredentials) {
186
- return setError('Incorrect username or password.');
187
- }
188
- throw err;
189
- }
190
- ```
191
-
192
- ## A note on types
193
-
194
- Every member above is a value, and values on `Toil.*` need no import: `Toil.Link`, `Toil.useParams`, `Toil.Auth.login`. Types are different. In type position, only a small set are namespaced as `Toil.<Type>`, because the generated `toil-env.d.ts` aliases exactly these under a `declare namespace Toil` block:
195
-
196
- `LoaderArgs`, `LoaderFunction`, `Revalidate`, `Metadata`, `GenerateMetadata`, `GenerateStaticParams`, `StaticParams`, `RouteErrorProps`, `Href`, `RoutePath`, `PageMeta`, `SearchHints`.
197
-
198
- So a loader can annotate its argument with no import:
199
-
200
- ```tsx
201
- export const loader = async ({ params }: Toil.LoaderArgs) => { /* ... */ };
202
- ```
203
-
204
- Every other exported type (for example `LinkProps`, `NavLinkState`, `NavigateOptions`, `RouterInstance`, `ImageProps`, `ScriptProps`, `FormProps`, `ActionState`) is not in that namespace, so it must be imported from the package:
205
-
206
- ```tsx
207
- import type { ImageProps } from 'toiljs/client';
208
- ```
209
-
210
- ## Related
211
-
212
- - [Navigation](./navigation.md): links, active state, and navigating in code.
213
- - [Components](./components.md): the built-in components and the SSR marker primitives.
214
- - [Fetching data](./data-fetching.md): the `Server` client, loaders, actions, and forms.
215
- - [Metadata and SEO](./metadata.md): titles, descriptions, and social-share tags per route.
216
- - [Auth](../auth/README.md): the full password-auth client and its error handling.
@@ -1,81 +0,0 @@
1
- # Getting started
2
-
3
- toiljs is a full-stack web framework: you write a React frontend and a TypeScript backend in one project, and toiljs ships both together. This section takes you from "nothing installed" to "a small feature running end to end."
4
-
5
- ## What toiljs is
6
-
7
- Think of a normal web app as two programs that have to agree with each other:
8
-
9
- - A **frontend**: the React code that runs in your user's browser.
10
- - A **backend**: the code that runs on a server, answers requests, and talks to a database.
11
-
12
- Normally these live in separate projects, speak to each other over hand-written HTTP calls, and drift apart until something breaks at runtime. toiljs puts both in one repository and wires them together with types, so a change on one side shows up as a compile error on the other side instead of a bug in production.
13
-
14
- The twist is what your backend becomes. You write it in TypeScript, but toiljs does not run it in Node.js. Instead, a compiler called **toilscript** turns your backend into **WebAssembly** (often shortened to "Wasm"): a small, fast, sandboxed program that runs at the **edge**. "Edge" just means servers spread all over the world, close to your users, so requests do not have to travel to one far-away data center. A worldwide database called **ToilDB** is built in, so you can store and read data without setting up or connecting to a database yourself.
15
-
16
- New terms, defined once:
17
-
18
- - **WebAssembly / Wasm**: a compact binary format that runs code in a locked-down sandbox at near-native speed. Your backend compiles to a single `.wasm` file.
19
- - **toilscript**: the compiler that turns your TypeScript backend into that `.wasm` file. It accepts a strict subset of TypeScript (more on that below).
20
- - **Dacely edge**: the global network of servers that runs your `.wasm` backend.
21
- - **ToilDB**: the built-in database that lives on the edge next to your code.
22
-
23
- ## The client / server / shared mental model
24
-
25
- Every toiljs project is organized into three folders. The most important thing to learn first is **where each piece of code actually runs**.
26
-
27
- ```mermaid
28
- flowchart LR
29
- A["Your project<br/>(one repo)"] -->|toiljs build| B["client bundle<br/>React + JS"]
30
- A -->|toilscript compiles| C["server.wasm<br/>your backend"]
31
- B --> U["User's browser"]
32
- C --> E["Dacely edge<br/>(worldwide servers)"]
33
- E --> D[("ToilDB<br/>global database")]
34
- U <-->|"HTTP / realtime"| E
35
- ```
36
-
37
- - **`client/`** is your React app: pages, components, and styles. It is bundled by [Vite](https://vitejs.dev) and runs **in the browser**.
38
- - **`server/`** is your backend: HTTP routes, database access, auth. It is compiled by toilscript to `build/server/release.wasm` and runs **on the edge** (and locally when you run the dev server).
39
- - **`shared/`** holds a file that toiljs **generates for you** (`shared/server.ts`). It is a fully typed client: the browser calls your backend through a `Server` object, and TypeScript checks every call. You do not write this file by hand.
40
-
41
- Here is the loop in one picture:
42
-
43
- ```mermaid
44
- flowchart TD
45
- W["client/routes/page.tsx<br/>(browser)"] -->|"Server.REST.likes.like()"| G["shared/server.ts<br/>(generated typed client)"]
46
- G -->|"HTTP request"| S["server/routes/Likes.ts<br/>(your @rest route, in wasm)"]
47
- S -->|"read / write"| DB[("ToilDB")]
48
- S -->|"typed response"| W
49
- ```
50
-
51
- You write both ends in TypeScript, and the generated `shared/server.ts` in the middle keeps them in sync.
52
-
53
- ## Two rules to keep in mind
54
-
55
- These two facts explain most of how toiljs backends behave. They are covered in depth later, but it helps to meet them now.
56
-
57
- 1. **The server runs one fresh instance per request.** Every request gets a brand-new copy of your `.wasm`, and its memory is wiped when the request ends. So a normal variable you set in one request is gone by the next request. Anything that must survive (accounts, counters, posts) has to go into **ToilDB** or another store. Nothing in a plain module-level variable persists.
58
-
59
- 2. **The server is not Node.js.** toilscript compiles a strict subset of TypeScript, so you cannot `import` an arbitrary npm package into `server/` or use Node APIs like `fs`. Instead, toiljs gives you built-in globals for the common needs: `crypto`, cookies, email, the database, and more. See [Types](../concepts/types.md) and [Decorators](../concepts/decorators.md) for the details.
60
-
61
- The client side, by contrast, is normal React. You can use React libraries and browser APIs there as usual.
62
-
63
- ## The getting-started path
64
-
65
- Work through these pages in order:
66
-
67
- 1. **[Installation](./installation.md)**: check your Node.js version and install the toiljs command-line tool.
68
- 2. **[Create a project](./create-project.md)**: scaffold a new app and see what you get.
69
- 3. **[Project structure](./project-structure.md)**: a tour of every folder and file, and where each one runs.
70
- 4. **[Your first app](./first-app.md)**: build a tiny feature end to end, a page that calls a backend route and reads and writes one piece of ToilDB data.
71
- 5. **[Migrating an existing app](./migrating.md)**: bring a React app you already have into toiljs.
72
- 6. **[Deploy](./deploy.md)**: build for production and self-host it, and how the managed edge fits in.
73
-
74
- ## Related
75
-
76
- - [Documentation home](../README.md)
77
- - [The CLI reference](../cli/README.md)
78
- - [Frontend overview](../frontend/README.md)
79
- - [Backend overview](../backend/README.md)
80
- - [Database overview](../database/README.md)
81
- - [Compute tiers (where code runs)](../concepts/tiers.md)
@@ -1,131 +0,0 @@
1
- # Create a project
2
-
3
- Scaffold a brand-new toiljs app with one command. The CLI asks a few questions, writes the files, and (optionally) installs dependencies for you.
4
-
5
- ## Why and when
6
-
7
- `toiljs create` is how every project starts. It wires up the enforced toiljs presets (TypeScript, ESLint, and Prettier config), the file-based routing, and a working client and server, so you get a project that builds and runs on the first try. Use it for a new app. To bring an **existing** React app into toiljs instead, see [Migrating](./migrating.md).
8
-
9
- ## The command
10
-
11
- ```sh
12
- toiljs create my-app
13
- ```
14
-
15
- Replace `my-app` with your project name (it becomes the folder name). If you leave the name off, the wizard asks for one.
16
-
17
- By default this runs an interactive wizard. To skip every question and accept the defaults (handy for scripts and CI), add `--yes`:
18
-
19
- ```sh
20
- toiljs create my-app --yes
21
- ```
22
-
23
- ## What the wizard asks
24
-
25
- Running `toiljs create` walks you through these prompts. Each one has a flag you can pass instead, so you can answer some or all of them up front.
26
-
27
- | Prompt | What it decides | Flag | Default |
28
- | --- | --- | --- | --- |
29
- | Project name | The folder and package name | (the first argument) | `my-toil-app` |
30
- | Which template? | How much starter code you get | `-t, --template <app\|minimal>` | `app` |
31
- | Styling | The CSS flavor for `client/` | `--style <css\|sass\|less\|stylus>` | `css` |
32
- | Add Tailwind CSS? | Adds Tailwind on top of the styling | `--tailwind` / `--no-tailwind` | off |
33
- | AI assistant files | Editor hint files for Claude, Cursor, Codex, Copilot | `--no-ai` (to skip) | all |
34
- | Optimize images at build time? | Resize and compress imported images | `--images` / `--no-images` | on |
35
- | Initialize a git repository? | Runs `git init` and stages the files | `--git` / `--no-git` | on |
36
- | Install dependencies now? | Runs your package manager's install | `--install` / `--no-install` | on |
37
-
38
- Two more flags do not have a prompt:
39
-
40
- - `--pm <npm\|pnpm\|yarn\|bun>` picks the package manager to install with (default `npm`).
41
- - `-y, --yes` accepts every default and runs without any prompts.
42
-
43
- ### The two templates
44
-
45
- - **`app`** (default) is the full starter: a landing page, a shared layout, styles, and a set of demo routes that show off HTTP routes, typed RPC, cookies, auth, and a ToilDB-backed guestbook. Great for learning by reading real, working code.
46
- - **`minimal`** is the bare minimum: a layout, a single home page, and a tiny server handler with one example endpoint. Great when you want a clean slate.
47
-
48
- A fully non-interactive example:
49
-
50
- ```sh
51
- toiljs create my-app --yes --template minimal --style css --no-tailwind --pm pnpm
52
- ```
53
-
54
- ## What gets scaffolded
55
-
56
- Here is the shape of a new **`app`** project. The exact set of demo routes may grow over time, so this is trimmed for readability.
57
-
58
- ```text
59
- my-app/
60
- package.json scripts + dependencies (toiljs, react, toilscript, ...)
61
- toil.config.ts client/build config (SEO, images, page transitions)
62
- toilconfig.json server (wasm) build config for toilscript
63
- tsconfig.json TypeScript config for the client
64
- eslint.config.js linting preset
65
- .prettierrc formatting preset
66
- .gitignore ignores build output, generated files, and .env files
67
- toil-env.d.ts generated editor types for client globals (Toil.*)
68
- toil-routes.d.ts generated typed-route names (filled in on first build)
69
- README.md
70
- CLAUDE.md / AGENTS.md AI assistant hint files (if you kept them)
71
-
72
- client/ your React app (runs in the browser)
73
- toil.tsx the client entry: mounts routes + layout
74
- layout.tsx the root layout that wraps every page
75
- 404.tsx the not-found page
76
- global-error.tsx the top-level error page
77
- routes/ file-based pages (index.tsx = "/", about.tsx = "/about", ...)
78
- components/ shared React components
79
- styles/main.css global styles
80
- public/ static files served as-is (favicon, robots.txt, images)
81
-
82
- server/ your backend (compiled to wasm, runs on the edge)
83
- main.ts the entry: wires the handler + imports your surface modules
84
- tsconfig.json server-only TS config (loads the toilscript editor plugin)
85
- toil-server-env.d.ts generated editor types for server globals (Cookie, crypto, ...)
86
- core/ your top-level request handler and shared logic
87
- models/ @data classes (the typed wire types)
88
- routes/ @rest controllers (HTTP endpoints)
89
- services/ @service classes and @remote functions (typed RPC)
90
- migrations/ ToilDB schema migrations (README explains the convention)
91
- scheduled/ reserved for scheduled tasks
92
-
93
- shared/ (created by the build)
94
- server.ts GENERATED typed client: the Server proxy + @data codecs
95
- ```
96
-
97
- The **`minimal`** template is the same layout with far fewer files: `client/` has just `layout.tsx`, `routes/index.tsx`, and `styles/main.css`; `server/` has `main.ts` and `core/AppHandler.ts` with a single example endpoint.
98
-
99
- A few files are worth calling out now, and the next page ([Project structure](./project-structure.md)) walks through all of them:
100
-
101
- - **`shared/server.ts` does not exist yet** in a fresh project. It is generated the first time you run `toiljs dev` or `toiljs build`. That is normal and expected.
102
- - **`toil-routes.d.ts`** starts as a stub and gets filled in with your real route names on the first build, which is what makes `Toil.Link` route names type-check.
103
- - **`.env` and `.env.secrets` are not created** for you. You add them yourself when you need local environment variables or secrets. They are already listed in `.gitignore` so you never commit them. See [Environment and secrets](../services/environment.md).
104
-
105
- ## Run it
106
-
107
- Once scaffolding (and install) finishes, the CLI prints your next steps:
108
-
109
- ```sh
110
- cd my-app
111
- npm run dev
112
- ```
113
-
114
- `npm run dev` runs `toiljs dev`, which builds your server to wasm, generates `shared/server.ts`, and starts the dev server with hot reload. Open the printed URL (by default `http://localhost:3000`) and you have a live app.
115
-
116
- If you told the wizard **not** to install dependencies, run `npm install` first.
117
-
118
- ## Gotchas and notes
119
-
120
- - **Scaffolding into a non-empty folder** asks for confirmation in interactive mode, and fails in `--yes` mode. Create into a fresh, empty directory.
121
- - **The project name must be a valid package name** and must stay inside the current directory (no `..`, no absolute paths).
122
- - **Git init is best-effort.** If `git` is not installed, the CLI skips that step and keeps going.
123
- - **You do not run `toilscript` yourself.** It is added as a dependency and driven by `toiljs dev` / `toiljs build`.
124
-
125
- ## Related
126
-
127
- - [Project structure](./project-structure.md)
128
- - [Your first app](./first-app.md)
129
- - [The CLI reference](../cli/README.md)
130
- - [Configuration](../concepts/config.md)
131
- - [Styling](../frontend/styling.md)
@@ -1,101 +0,0 @@
1
- # Deploying a toiljs app
2
-
3
- This page is an honest look at how you get a toiljs app in front of real users. There are two paths, and it helps to be clear about which one exists today.
4
-
5
- - **Self-host it yourself.** You build the app and run it on a machine you control, with `toiljs build` then `toiljs start`. This works right now, on your laptop, a VPS, or any server that can run Node.js.
6
- - **Run it on the managed Dacely edge.** This is the platform toiljs is built for: a worldwide fleet of servers that runs your compiled backend close to every user. It is the target the whole framework is designed around.
7
-
8
- One thing up front, so you do not go looking for it: **there is no `toiljs deploy` command.** The CLI can build and self-host; pushing a build onto the managed edge is a platform step, not a CLI subcommand. The rest of this page covers what you can do today (self-hosting) and what the managed edge gives you.
9
-
10
- ## The one build powers both
11
-
12
- Both paths serve the exact same artifacts. `toiljs build` produces them once:
13
-
14
- ```mermaid
15
- flowchart LR
16
- A["Your project"] -->|toiljs build| B["build/client/<br/>(HTML, JS, CSS, assets)"]
17
- A -->|toiljs build| C["build/server/release.wasm<br/>(your backend)"]
18
- B --> H["toiljs start<br/>(self-host)"]
19
- C --> H
20
- B --> E["managed Dacely edge<br/>(worldwide)"]
21
- C --> E
22
- ```
23
-
24
- So you never build differently for the two targets. You build once, then either run it yourself or hand the same output to the edge.
25
-
26
- ## Self-hosting with `toiljs start`
27
-
28
- `toiljs start` runs your built app on a fast production HTTP server. It serves your static client, dispatches dynamic requests into your `release.wasm`, does server-side rendering, runs daemons, and exposes a `/_toil` websocket channel. Use it to put your app on your own machine or server instead of the managed edge.
29
-
30
- ### Step 1: build
31
-
32
- `start` serves whatever is in `build/`, so you must build first. If there is no build, `start` exits with an error (it looks for `build/client/index.html`).
33
-
34
- ```bash
35
- npm run build
36
- ```
37
-
38
- ### Step 2: start
39
-
40
- ```bash
41
- # Serve on http://127.0.0.1:3000 (loopback only, one worker per CPU).
42
- npx toiljs start
43
-
44
- # Accept outside connections, on port 8080, with 4 worker processes.
45
- npx toiljs start --host 0.0.0.0 --port 8080 --threads 4
46
- ```
47
-
48
- ### start flags
49
-
50
- | Flag | Meaning |
51
- | --- | --- |
52
- | `--port <n>` | Port to listen on. Default `3000` (or `client.port` from your config). |
53
- | `--host <host>` | Address to bind. Default `127.0.0.1`, which is **loopback only** (reachable just from the same machine). Pass `0.0.0.0` to accept connections from other machines. |
54
- | `--threads <n>` | Number of HTTP worker processes. Default is automatic (one per available CPU). Pass `1` to disable the worker pool. `--workers` is an accepted alias, and you can also set `server.threads` in your config or the `TOILJS_THREADS` environment variable. |
55
- | `--root <dir>` | Run against a project in another directory instead of the current one. |
56
-
57
- These flags are verified against the CLI. Note that `--host` and `--threads` are `start`-only: `toiljs dev` always binds locally and does not take them. For the full command reference, see [the CLI](../cli/README.md#toiljs-start).
58
-
59
- ### A realistic self-host
60
-
61
- On a small server (say a VPS), a minimal run looks like this:
62
-
63
- ```bash
64
- # Install and build.
65
- npm ci
66
- npm run build
67
-
68
- # Bind on all interfaces so a reverse proxy or the public can reach it.
69
- npx toiljs start --host 0.0.0.0 --port 8080 --threads 4
70
- ```
71
-
72
- Then put a reverse proxy (nginx, Caddy) in front for TLS and a real hostname, pointing it at `http://127.0.0.1:8080`. Keep the process alive with your usual tool (systemd, pm2, a container restart policy).
73
-
74
- ### Self-host gotchas
75
-
76
- - **`start` needs a fresh build.** It serves `build/`, not your source. After any code change, run `toiljs build` again before restarting.
77
- - **The default bind is loopback.** With no `--host`, only the same machine can reach it. Set `--host 0.0.0.0` (usually behind a reverse proxy) to serve real traffic.
78
- - **Self-host is one place, not the whole world.** You get one server (or however many you run yourself). The latency and worldwide reach of the managed edge is exactly the thing self-hosting does not give you.
79
- - **The database is different.** Self-hosting runs the built server, but ToilDB's worldwide data layer is an edge feature. Treat self-host as a way to run and test your build, not as a substitute for the managed edge's global database.
80
-
81
- ## The managed Dacely edge
82
-
83
- The managed **Dacely edge** is the platform toiljs targets: a fleet of servers in many cities that runs your compiled backend as close to each user as possible, backed by the worldwide **ToilDB** database. You write one project, and the build already decides which part of your code belongs to which layer of the edge.
84
-
85
- Your backend runs across four **compute tiers**, from a per-request handler at the very edge up to a single worldwide coordinator:
86
-
87
- | Tier | Name | Where it runs | Typical code |
88
- | --- | --- | --- | --- |
89
- | **L1** | Hot / edge | The node nearest the user, fresh per request | `@rest`, `@service` / `@remote` |
90
- | **L2** | Regional | One box per connection, per region | `@stream` (Regional) |
91
- | **L3** | Continental | One box per connection, per continent | `@stream` (Continental) |
92
- | **L4** | Global / daemon | Exactly one leader worldwide | `@daemon`, `@scheduled` |
93
-
94
- Because the same `toiljs build` output feeds the edge, everything you built and tested with `toiljs dev` and `toiljs start` is what runs there. The edge decides each server's role for you; you do not configure tiers by hand. For the full picture of what each tier means and how to write for it, see [Compute tiers (L1 to L4)](../concepts/tiers.md).
95
-
96
- ## Related
97
-
98
- - [The CLI](../cli/README.md): the full reference for `build` and `start` and every flag.
99
- - [Configuration (`toil.config.ts`)](../concepts/config.md): `server.threads` and the other self-host knobs.
100
- - [Compute tiers (L1 to L4)](../concepts/tiers.md): how your code maps onto the managed edge.
101
- - [Getting started](./README.md): the path from install to a running feature.