toiljs 0.0.115 → 0.0.117

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 (326) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +16 -7
  3. package/TYPESCRIPT_LAW.md +1946 -2073
  4. package/build/backend/.tsbuildinfo +1 -1
  5. package/build/cli/.tsbuildinfo +1 -1
  6. package/build/cli/index.js +2375 -258
  7. package/build/client/.tsbuildinfo +1 -1
  8. package/build/client/dev/devtools.js +1 -1
  9. package/build/client/dev/error-overlay.js +1 -1
  10. package/build/client/routing/mount.js +1 -1
  11. package/build/compiler/.tsbuildinfo +1 -1
  12. package/build/compiler/auth-emails.js +7 -3
  13. package/build/compiler/emails.js +1 -1
  14. package/build/compiler/index.d.ts +1 -0
  15. package/build/compiler/index.js +25 -4
  16. package/build/compiler/pages.js +2 -3
  17. package/build/compiler/prerender.d.ts +3 -8
  18. package/build/compiler/prerender.js +88 -127
  19. package/build/compiler/ssg.js +3 -4
  20. package/build/compiler/template-build.js +3 -4
  21. package/build/compiler/toil-docs.generated.js +6 -5
  22. package/build/compiler/vite.js +3 -6
  23. package/build/devserver/.tsbuildinfo +1 -1
  24. package/build/devserver/db/database.js +7 -3
  25. package/build/devserver/db/types.js +1 -1
  26. package/build/devserver/production.js +4 -3
  27. package/build/devserver/runtime/crypto.d.ts +1 -1
  28. package/build/io/.tsbuildinfo +1 -1
  29. package/build/logger/.tsbuildinfo +1 -1
  30. package/build/shared/.tsbuildinfo +1 -1
  31. package/examples/basic/client/routes/analytics.tsx +7 -5
  32. package/examples/basic/server/tsconfig.json +1 -3
  33. package/package.json +45 -44
  34. package/presets/no-uint8array-tostring.js +120 -153
  35. package/presets/oxlint.d.ts +5 -0
  36. package/presets/oxlint.js +224 -0
  37. package/server/runtime/tsconfig.json +1 -3
  38. package/tsconfig.json +2 -11
  39. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  40. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -90
  41. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  42. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  43. package/.github/PULL_REQUEST_TEMPLATE.md +0 -43
  44. package/.github/changelog-config.json +0 -45
  45. package/.github/dependabot.yml +0 -27
  46. package/.github/workflows/ci.yml +0 -222
  47. package/.vscode/settings.json +0 -10
  48. package/docs/README.md +0 -107
  49. package/docs/auth/README.md +0 -104
  50. package/docs/auth/configuration.md +0 -105
  51. package/docs/auth/emails.md +0 -92
  52. package/docs/auth/extending.md +0 -202
  53. package/docs/auth/how-it-works.md +0 -138
  54. package/docs/auth/usage.md +0 -188
  55. package/docs/backend/README.md +0 -143
  56. package/docs/backend/data.md +0 -351
  57. package/docs/backend/rest.md +0 -402
  58. package/docs/backend/rpc.md +0 -226
  59. package/docs/background/README.md +0 -114
  60. package/docs/background/daemons.md +0 -276
  61. package/docs/background/derive.md +0 -179
  62. package/docs/cli/README.md +0 -379
  63. package/docs/concepts/ai-guide.md +0 -132
  64. package/docs/concepts/config.md +0 -416
  65. package/docs/concepts/decorators.md +0 -127
  66. package/docs/concepts/security.md +0 -108
  67. package/docs/concepts/tiers.md +0 -166
  68. package/docs/concepts/types.md +0 -216
  69. package/docs/database/README.md +0 -143
  70. package/docs/database/capacity.md +0 -350
  71. package/docs/database/counters.md +0 -174
  72. package/docs/database/documents.md +0 -277
  73. package/docs/database/events.md +0 -307
  74. package/docs/database/membership.md +0 -246
  75. package/docs/database/setup.md +0 -155
  76. package/docs/database/unique.md +0 -216
  77. package/docs/database/views.md +0 -246
  78. package/docs/frontend/README.md +0 -104
  79. package/docs/frontend/components.md +0 -286
  80. package/docs/frontend/data-fetching.md +0 -260
  81. package/docs/frontend/images.md +0 -148
  82. package/docs/frontend/metadata.md +0 -344
  83. package/docs/frontend/navigation.md +0 -296
  84. package/docs/frontend/rendering.md +0 -236
  85. package/docs/frontend/routing.md +0 -346
  86. package/docs/frontend/scripts.md +0 -118
  87. package/docs/frontend/search.md +0 -191
  88. package/docs/frontend/styling.md +0 -147
  89. package/docs/frontend/toil-global.md +0 -216
  90. package/docs/getting-started/README.md +0 -81
  91. package/docs/getting-started/create-project.md +0 -131
  92. package/docs/getting-started/deploy.md +0 -101
  93. package/docs/getting-started/first-app.md +0 -215
  94. package/docs/getting-started/installation.md +0 -124
  95. package/docs/getting-started/migrating.md +0 -125
  96. package/docs/getting-started/project-structure.md +0 -163
  97. package/docs/introduction/README.md +0 -66
  98. package/docs/introduction/design-principles.md +0 -81
  99. package/docs/introduction/distributed.md +0 -91
  100. package/docs/introduction/how-it-works.md +0 -121
  101. package/docs/introduction/hyperscale.md +0 -70
  102. package/docs/introduction/modern-stack.md +0 -85
  103. package/docs/introduction/vs-other-frameworks.md +0 -64
  104. package/docs/introduction/why-toil.md +0 -99
  105. package/docs/llms.txt +0 -95
  106. package/docs/realtime/README.md +0 -102
  107. package/docs/realtime/channels.md +0 -211
  108. package/docs/realtime/streams.md +0 -369
  109. package/docs/services/README.md +0 -60
  110. package/docs/services/analytics.md +0 -279
  111. package/docs/services/caching.md +0 -175
  112. package/docs/services/cookies.md +0 -235
  113. package/docs/services/crypto.md +0 -209
  114. package/docs/services/email.md +0 -289
  115. package/docs/services/environment.md +0 -141
  116. package/docs/services/ratelimit.md +0 -174
  117. package/docs/services/time.md +0 -85
  118. package/eslint.config.js +0 -57
  119. package/examples/basic/client/routes/docs/[...slug].tsx +0 -12
  120. package/presets/eslint.js +0 -88
  121. package/src/backend/index.ts +0 -204
  122. package/src/cli/configure.ts +0 -363
  123. package/src/cli/create.ts +0 -924
  124. package/src/cli/db.ts +0 -158
  125. package/src/cli/diagnostics.ts +0 -665
  126. package/src/cli/doctor.ts +0 -982
  127. package/src/cli/features.ts +0 -170
  128. package/src/cli/index.ts +0 -326
  129. package/src/cli/notify.ts +0 -120
  130. package/src/cli/proc.ts +0 -56
  131. package/src/cli/ui.ts +0 -169
  132. package/src/cli/update.ts +0 -248
  133. package/src/cli/updates.ts +0 -92
  134. package/src/cli/validate.ts +0 -31
  135. package/src/cli/version-check.ts +0 -125
  136. package/src/client/auth.ts +0 -869
  137. package/src/client/channel/channel.ts +0 -146
  138. package/src/client/components/Form.tsx +0 -65
  139. package/src/client/components/Image.tsx +0 -160
  140. package/src/client/components/Script.tsx +0 -113
  141. package/src/client/components/Slot.tsx +0 -21
  142. package/src/client/dev/devtools.tsx +0 -1089
  143. package/src/client/dev/error-overlay.tsx +0 -225
  144. package/src/client/errors.ts +0 -11
  145. package/src/client/head/head.ts +0 -182
  146. package/src/client/head/metadata.ts +0 -110
  147. package/src/client/index.ts +0 -130
  148. package/src/client/navigation/Link.tsx +0 -108
  149. package/src/client/navigation/NavLink.tsx +0 -86
  150. package/src/client/navigation/navigation.ts +0 -235
  151. package/src/client/navigation/prefetch.ts +0 -169
  152. package/src/client/navigation/scroll.ts +0 -53
  153. package/src/client/routing/Router.tsx +0 -216
  154. package/src/client/routing/action.ts +0 -122
  155. package/src/client/routing/error-boundary.tsx +0 -43
  156. package/src/client/routing/hooks.ts +0 -140
  157. package/src/client/routing/lazy.ts +0 -77
  158. package/src/client/routing/loader.ts +0 -381
  159. package/src/client/routing/match.ts +0 -47
  160. package/src/client/routing/mount.tsx +0 -90
  161. package/src/client/routing/params-context.ts +0 -10
  162. package/src/client/routing/slot-context.ts +0 -7
  163. package/src/client/rpc.ts +0 -97
  164. package/src/client/search/search.ts +0 -189
  165. package/src/client/search/use-page-search.ts +0 -73
  166. package/src/client/ssr/markers.tsx +0 -172
  167. package/src/client/stream/client.ts +0 -237
  168. package/src/client/types.ts +0 -73
  169. package/src/compiler/auth-emails.ts +0 -312
  170. package/src/compiler/config.ts +0 -369
  171. package/src/compiler/docs.ts +0 -127
  172. package/src/compiler/email-preview.ts +0 -314
  173. package/src/compiler/emails.ts +0 -404
  174. package/src/compiler/fonts.ts +0 -89
  175. package/src/compiler/generate.ts +0 -471
  176. package/src/compiler/image-blur.ts +0 -42
  177. package/src/compiler/image-report.ts +0 -88
  178. package/src/compiler/index.ts +0 -1362
  179. package/src/compiler/pages.ts +0 -49
  180. package/src/compiler/plugin.ts +0 -391
  181. package/src/compiler/prerender.ts +0 -263
  182. package/src/compiler/routes.ts +0 -170
  183. package/src/compiler/seo.ts +0 -415
  184. package/src/compiler/sri.ts +0 -144
  185. package/src/compiler/ssg.ts +0 -177
  186. package/src/compiler/ssr-codegen.ts +0 -85
  187. package/src/compiler/template-build.ts +0 -676
  188. package/src/compiler/template.ts +0 -262
  189. package/src/compiler/toil-docs.generated.ts +0 -77
  190. package/src/compiler/vite.ts +0 -245
  191. package/src/devserver/analytics/index.ts +0 -317
  192. package/src/devserver/config/dotenv.ts +0 -102
  193. package/src/devserver/config/env.ts +0 -30
  194. package/src/devserver/config/ratelimit.ts +0 -123
  195. package/src/devserver/daemon/catalog.ts +0 -120
  196. package/src/devserver/daemon/cron.ts +0 -87
  197. package/src/devserver/daemon/host.ts +0 -134
  198. package/src/devserver/daemon/index.ts +0 -369
  199. package/src/devserver/daemon/runtime.ts +0 -48
  200. package/src/devserver/db/catalog.ts +0 -109
  201. package/src/devserver/db/database.ts +0 -1834
  202. package/src/devserver/db/derives.ts +0 -121
  203. package/src/devserver/db/index.ts +0 -20
  204. package/src/devserver/db/routeKinds.ts +0 -191
  205. package/src/devserver/db/types.ts +0 -168
  206. package/src/devserver/email/caps.ts +0 -0
  207. package/src/devserver/email/config.ts +0 -141
  208. package/src/devserver/email/console.ts +0 -348
  209. package/src/devserver/email/index.ts +0 -155
  210. package/src/devserver/email/providers.ts +0 -131
  211. package/src/devserver/email/status.ts +0 -23
  212. package/src/devserver/email/validate.ts +0 -37
  213. package/src/devserver/email/wire.ts +0 -55
  214. package/src/devserver/http/cache.ts +0 -0
  215. package/src/devserver/http/envelope.ts +0 -157
  216. package/src/devserver/http/proxy.ts +0 -172
  217. package/src/devserver/http/runtime.ts +0 -387
  218. package/src/devserver/index.ts +0 -43
  219. package/src/devserver/production-ipc.ts +0 -63
  220. package/src/devserver/production-worker.ts +0 -83
  221. package/src/devserver/production.ts +0 -718
  222. package/src/devserver/runtime/crypto.ts +0 -587
  223. package/src/devserver/runtime/host.ts +0 -427
  224. package/src/devserver/runtime/module.ts +0 -442
  225. package/src/devserver/server.ts +0 -251
  226. package/src/devserver/ssr.ts +0 -208
  227. package/src/devserver/stream/catalog.ts +0 -106
  228. package/src/devserver/stream/host.ts +0 -42
  229. package/src/devserver/stream/index.ts +0 -301
  230. package/src/devserver/stream/manager.ts +0 -167
  231. package/src/devserver/stream/router.ts +0 -101
  232. package/src/devserver/stream/wire.ts +0 -58
  233. package/src/devserver/stream/ws.ts +0 -78
  234. package/src/devserver/wasm/sections.ts +0 -59
  235. package/src/devserver/wasm/surface.ts +0 -115
  236. package/src/io/FastMap.ts +0 -151
  237. package/src/io/FastSet.ts +0 -113
  238. package/src/io/codec.ts +0 -362
  239. package/src/io/index.ts +0 -10
  240. package/src/io/lengths.ts +0 -14
  241. package/src/io/types.ts +0 -19
  242. package/src/logger/index.ts +0 -22
  243. package/src/shared/index.ts +0 -46
  244. package/test/analytics-dev.test.ts +0 -113
  245. package/test/assembly/aspect-shim.ts +0 -33
  246. package/test/assembly/cookie.spec.ts +0 -303
  247. package/test/assembly/example.spec.ts +0 -22
  248. package/test/assembly/ssr.spec.ts +0 -95
  249. package/test/assembly.test.ts +0 -59
  250. package/test/auth-emails.test.ts +0 -118
  251. package/test/built-ssr.test.ts +0 -148
  252. package/test/channel.test.ts +0 -21
  253. package/test/config-host-port.test.ts +0 -59
  254. package/test/configure.test.ts +0 -94
  255. package/test/daemon-build.test.ts +0 -278
  256. package/test/daemon-catalog.test.ts +0 -349
  257. package/test/daemon-emulation.test.ts +0 -256
  258. package/test/db.test.ts +0 -0
  259. package/test/devserver-database.test.ts +0 -1102
  260. package/test/devserver-email.test.ts +0 -306
  261. package/test/devserver-pqauth.test.ts +0 -93
  262. package/test/devserver-secrets.test.ts +0 -63
  263. package/test/devserver.test.ts +0 -259
  264. package/test/doctor.test.ts +0 -298
  265. package/test/dom/Image.test.tsx +0 -144
  266. package/test/dom/Link.test.tsx +0 -67
  267. package/test/dom/NavLink.test.tsx +0 -37
  268. package/test/dom/Script.test.tsx +0 -48
  269. package/test/dom/action.test.tsx +0 -146
  270. package/test/dom/error-overlay.test.tsx +0 -44
  271. package/test/dom/loader.test.tsx +0 -121
  272. package/test/dom/navigation.test.ts +0 -59
  273. package/test/dom/revalidate.test.tsx +0 -38
  274. package/test/dom/route-head.test.tsx +0 -56
  275. package/test/dom/router-loading.test.tsx +0 -44
  276. package/test/dom/scroll.test.ts +0 -56
  277. package/test/dom/slot.test.tsx +0 -131
  278. package/test/dom/use-metadata.test.tsx +0 -58
  279. package/test/dom/view-transitions.test.tsx +0 -53
  280. package/test/dynamic-routing.test.ts +0 -132
  281. package/test/email-console.test.ts +0 -86
  282. package/test/email-preview.test.ts +0 -73
  283. package/test/emails.test.ts +0 -58
  284. package/test/errors.test.ts +0 -21
  285. package/test/example-guestbook.test.ts +0 -123
  286. package/test/features.test.ts +0 -149
  287. package/test/fixtures/bignum-wire/spec.ts +0 -25
  288. package/test/fixtures/daemon-app.ts +0 -65
  289. package/test/fixtures/stream-echo.ts +0 -26
  290. package/test/fixtures/stream-gate.ts +0 -28
  291. package/test/fixtures/stream-trap.ts +0 -18
  292. package/test/fixtures/stream-typed.ts +0 -41
  293. package/test/fonts.test.ts +0 -28
  294. package/test/global-setup.ts +0 -17
  295. package/test/head.test.ts +0 -42
  296. package/test/image-blur.test.ts +0 -50
  297. package/test/io.test.ts +0 -117
  298. package/test/metadata.test.ts +0 -40
  299. package/test/navlink.test.ts +0 -28
  300. package/test/pages.test.ts +0 -105
  301. package/test/placeholder.test.ts +0 -9
  302. package/test/pqauth-e2e.test.ts +0 -216
  303. package/test/pqauth-email.test.ts +0 -801
  304. package/test/prerender.test.ts +0 -116
  305. package/test/prettier-plugin.test.ts +0 -46
  306. package/test/routes.test.ts +0 -76
  307. package/test/rpc-bignum-wire.test.ts +0 -164
  308. package/test/rpc-dispatch.test.ts +0 -132
  309. package/test/rpc-kinds.test.ts +0 -18
  310. package/test/rpc.test.ts +0 -66
  311. package/test/search.test.ts +0 -114
  312. package/test/seo.test.ts +0 -175
  313. package/test/slot-layouts.test.ts +0 -69
  314. package/test/sri.test.ts +0 -129
  315. package/test/ssg.test.ts +0 -36
  316. package/test/ssr-hydration.test.tsx +0 -122
  317. package/test/ssr-render.test.ts +0 -197
  318. package/test/ssr-template.test.tsx +0 -482
  319. package/test/stream-emulation.test.ts +0 -479
  320. package/test/ui.test.ts +0 -40
  321. package/test/update.test.ts +0 -58
  322. package/test/validate.test.ts +0 -42
  323. package/test/version-check.test.ts +0 -130
  324. package/tests/data-parity/generated-parity.ts +0 -99
  325. package/tests/data-parity/parity.ts +0 -80
  326. package/tests/data-parity/spec.ts +0 -46
@@ -1,225 +0,0 @@
1
- /**
2
- * Development-only error overlay. In dev, surfaces errors that would otherwise leave a blank page or
3
- * live only in the console: uncaught render errors (incl. those thrown by a loader during render),
4
- * plus `window` `error` / `unhandledrejection` events. Shows the message, stack, and (for render
5
- * errors) the React component stack, with Dismiss / Reload. Inert in production builds.
6
- */
7
- import {
8
- Component,
9
- type CSSProperties,
10
- type ErrorInfo,
11
- type ReactNode,
12
- useSyncExternalStore,
13
- } from 'react';
14
-
15
- /** A captured dev error. */
16
- export interface DevError {
17
- readonly error: Error;
18
- readonly componentStack?: string;
19
- /** Where it came from, a render boundary, a window `error`, or an unhandled rejection. */
20
- readonly source: 'render' | 'window' | 'unhandledrejection';
21
- /** Capture time (ms epoch). */
22
- readonly time: number;
23
- }
24
-
25
- let current: DevError | null = null;
26
- const listeners = new Set<() => void>();
27
- /**
28
- * Bounded history of captured errors, for the dev toolbar's Errors tab. Reassigned to a new array
29
- * on each change (never mutated in place) so `getErrorLog` is a stable useSyncExternalStore snapshot:
30
- * the reference changes only when the log changes, so React re-renders on new errors but not in a loop.
31
- */
32
- let errorLog: readonly DevError[] = [];
33
- const MAX_LOG = 50;
34
-
35
- function emit(): void {
36
- for (const listener of listeners) listener();
37
- }
38
- function setDevError(next: DevError | null): void {
39
- current = next;
40
- if (next) {
41
- errorLog = [...errorLog, next].slice(-MAX_LOG);
42
- }
43
- emit();
44
- }
45
- function subscribe(listener: () => void): () => void {
46
- listeners.add(listener);
47
- return () => {
48
- listeners.delete(listener);
49
- };
50
- }
51
-
52
- /** The captured-error history (most recent last). Subscribe via {@link subscribeErrors}. */
53
- export function getErrorLog(): readonly DevError[] {
54
- return errorLog;
55
- }
56
- /** Subscribes to error captures (fires whenever a new error is recorded or dismissed). */
57
- export const subscribeErrors = subscribe;
58
-
59
- /** True when running under Vite's dev server (replaced at build time; falsy in production). */
60
- export function isDevMode(): boolean {
61
- try {
62
- return Boolean((import.meta as { env?: { DEV?: boolean } }).env?.DEV);
63
- } catch {
64
- return false;
65
- }
66
- }
67
-
68
- let windowBound = false;
69
- /** Wires `window` error / unhandledrejection into the overlay (idempotent; dev only). */
70
- export function initDevErrorOverlay(): void {
71
- if (windowBound || typeof window === 'undefined') return;
72
- windowBound = true;
73
- window.addEventListener('error', (event) => {
74
- if (event.error instanceof Error) {
75
- setDevError({ error: event.error, source: 'window', time: Date.now() });
76
- }
77
- });
78
- window.addEventListener('unhandledrejection', (event) => {
79
- const reason: unknown = event.reason;
80
- const error = reason instanceof Error ? reason : new Error(String(reason));
81
- setDevError({ error, source: 'unhandledrejection', time: Date.now() });
82
- });
83
- }
84
-
85
- interface BoundaryProps {
86
- readonly children: ReactNode;
87
- }
88
- interface BoundaryState {
89
- readonly crashed: boolean;
90
- }
91
-
92
- /**
93
- * Catches render errors in its subtree and reports them to the overlay. While crashed it renders
94
- * nothing (the subtree threw); it recovers when the overlay is dismissed. Class component because
95
- * React error boundaries have no hook equivalent.
96
- */
97
- export class DevErrorBoundary extends Component<BoundaryProps, BoundaryState> {
98
- public state: BoundaryState = { crashed: false };
99
- private unsubscribe: (() => void) | undefined;
100
-
101
- public static getDerivedStateFromError(): BoundaryState {
102
- return { crashed: true };
103
- }
104
-
105
- public override componentDidCatch(error: Error, info: ErrorInfo): void {
106
- setDevError({
107
- error,
108
- componentStack: info.componentStack ?? undefined,
109
- source: 'render',
110
- time: Date.now(),
111
- });
112
- }
113
-
114
- public override componentDidMount(): void {
115
- // Recover (re-render children) once the error is dismissed from the overlay.
116
- this.unsubscribe = subscribe(() => {
117
- if (current === null && this.state.crashed) this.setState({ crashed: false });
118
- });
119
- }
120
-
121
- public override componentWillUnmount(): void {
122
- this.unsubscribe?.();
123
- }
124
-
125
- public override render(): ReactNode {
126
- return this.state.crashed ? null : this.props.children;
127
- }
128
- }
129
-
130
- const overlayStyle: CSSProperties = {
131
- position: 'fixed',
132
- inset: 0,
133
- zIndex: 2147483647,
134
- background: 'rgba(8, 8, 12, 0.88)',
135
- color: '#f5f6fa',
136
- font: '13px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace',
137
- padding: '2rem',
138
- overflow: 'auto',
139
- display: 'flex',
140
- justifyContent: 'center',
141
- alignItems: 'flex-start',
142
- };
143
- const panelStyle: CSSProperties = {
144
- maxWidth: 900,
145
- width: '100%',
146
- background: '#15151c',
147
- border: '1px solid #ef4444',
148
- borderRadius: 10,
149
- padding: '1.25rem 1.5rem',
150
- boxShadow: '0 12px 48px rgba(0,0,0,0.5)',
151
- };
152
- const titleStyle: CSSProperties = {
153
- margin: 0,
154
- color: '#ff6b6b',
155
- fontSize: '1rem',
156
- fontWeight: 700,
157
- wordBreak: 'break-word',
158
- };
159
- const preStyle: CSSProperties = {
160
- whiteSpace: 'pre-wrap',
161
- wordBreak: 'break-word',
162
- margin: '0.75rem 0 0',
163
- color: '#c8cee0',
164
- };
165
- const buttonStyle: CSSProperties = {
166
- font: 'inherit',
167
- color: '#f5f6fa',
168
- background: '#2a2a36',
169
- border: '1px solid #3a3a48',
170
- borderRadius: 6,
171
- padding: '0.4em 1em',
172
- cursor: 'pointer',
173
- marginRight: '0.5rem',
174
- };
175
-
176
- const SOURCE_LABEL: Record<DevError['source'], string> = {
177
- render: 'Render error',
178
- window: 'Uncaught error',
179
- unhandledrejection: 'Unhandled promise rejection',
180
- };
181
-
182
- /** Renders the overlay when a dev error is captured. Mount once at the app root (dev only). */
183
- export function DevErrorOverlay(): ReactNode {
184
- const devError = useSyncExternalStore(
185
- subscribe,
186
- () => current,
187
- () => null,
188
- );
189
- if (!devError) return null;
190
- return (
191
- <div
192
- style={overlayStyle}
193
- role="alert">
194
- <div style={panelStyle}>
195
- <p style={titleStyle}>
196
- {SOURCE_LABEL[devError.source]}, {devError.error.name}: {devError.error.message}
197
- </p>
198
- {devError.error.stack !== undefined && (
199
- <pre style={preStyle}>{devError.error.stack}</pre>
200
- )}
201
- {devError.componentStack !== undefined && (
202
- <pre style={{ ...preStyle, color: '#8b9ab4' }}>{devError.componentStack}</pre>
203
- )}
204
- <div style={{ marginTop: '1.25rem' }}>
205
- <button
206
- type="button"
207
- style={buttonStyle}
208
- onClick={() => {
209
- setDevError(null);
210
- }}>
211
- Dismiss
212
- </button>
213
- <button
214
- type="button"
215
- style={buttonStyle}
216
- onClick={() => {
217
- window.location.reload();
218
- }}>
219
- Reload
220
- </button>
221
- </div>
222
- </div>
223
- </div>
224
- );
225
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Extracts a human-readable message from an unknown thrown value. Handy in `catch`
3
- * blocks where the caught value is typed `unknown`. Exposed as a global `parseError`
4
- * (no import) alongside the other toiljs globals.
5
- *
6
- * @param err - the caught value (an `Error`, a string, or anything else).
7
- * @returns the `Error.message` when `err` is an `Error`, otherwise `String(err)`.
8
- */
9
- export function parseError(err: unknown): string {
10
- return err instanceof Error ? err.message : String(err);
11
- }
@@ -1,182 +0,0 @@
1
- /**
2
- * Client-side document `<head>` management. `useHead` / `useTitle` / `<Head>` let any component
3
- * (layout or page) set the title and `<meta>` / `<link>` tags; entries compose across the tree
4
- * (later/deeper entries win per key) and are reverted when the component unmounts. Pure
5
- * `mergeHead` resolves the active entries; the manager reconciles `document.head`.
6
- */
7
- import { useEffect, useLayoutEffect } from 'react';
8
-
9
- import { __isSsrBuild } from '../ssr/markers';
10
-
11
- /** A `<meta>` tag. Use `name` or `property` (OpenGraph) as the dedup key; extra attrs pass through. */
12
- export interface MetaTag {
13
- readonly name?: string;
14
- readonly property?: string;
15
- readonly content: string;
16
- readonly [attr: string]: string | undefined;
17
- }
18
-
19
- /** A `<link>` tag (deduped by `rel` + `href`); extra attrs pass through. */
20
- export interface LinkTag {
21
- readonly rel: string;
22
- readonly href: string;
23
- readonly [attr: string]: string | undefined;
24
- }
25
-
26
- /** A head contribution from one component. */
27
- export interface HeadSpec {
28
- /** Document title. */
29
- readonly title?: string;
30
- readonly meta?: readonly MetaTag[];
31
- readonly link?: readonly LinkTag[];
32
- }
33
-
34
- /** The resolved head after merging all active specs. */
35
- export interface ResolvedHead {
36
- readonly title?: string;
37
- readonly meta: MetaTag[];
38
- readonly link: LinkTag[];
39
- }
40
-
41
- function metaKey(m: MetaTag): string {
42
- if (m.name !== undefined) return `name:${m.name}`;
43
- if (m.property !== undefined) return `property:${m.property}`;
44
- return `meta:${JSON.stringify(m)}`;
45
- }
46
-
47
- /**
48
- * Merges head specs in order: the last `title` wins, `meta` dedupes by name/property and `link` by
49
- * rel+href (last wins).
50
- */
51
- export function mergeHead(specs: readonly HeadSpec[]): ResolvedHead {
52
- let title: string | undefined;
53
- const meta = new Map<string, MetaTag>();
54
- const link = new Map<string, LinkTag>();
55
- for (const spec of specs) {
56
- if (spec.title !== undefined) title = spec.title;
57
- for (const m of spec.meta ?? []) meta.set(metaKey(m), m);
58
- for (const l of spec.link ?? []) link.set(`${l.rel}:${l.href}`, l);
59
- }
60
- return { title, meta: [...meta.values()], link: [...link.values()] };
61
- }
62
-
63
- const entries = new Map<number, HeadSpec>();
64
- let order: number[] = [];
65
- let seq = 0;
66
- let baseTitle: string | null = null;
67
- // The current route's resolved `metadata` export. Merged LAST (highest priority), so a route's
68
- // metadata wins over a layout's `useHead`/`<Head>` defaults (e.g. a site-wide title) for
69
- // the keys it sets, while the layout still fills everything the route leaves unset. Set by the router
70
- // via `setRouteHead` on each navigation.
71
- let routeHead: HeadSpec | null = null;
72
-
73
- // Component-level head (`useHead`/`useTitle`/<Head>) collected during the build's SSR extraction.
74
- // renderToString doesn't run effects, so specs are pushed during render (see `useHead`); the template
75
- // extractor drains them with `__drainSsrHead` after each route renders, to bake the route's
76
- // component-level head into the server HTML (not just its static `metadata` export).
77
- let ssrHeadSink: HeadSpec[] = [];
78
-
79
- function setAttrs(el: Element, attrs: Record<string, string | undefined>): void {
80
- el.setAttribute('data-toil-head', '');
81
- for (const [key, value] of Object.entries(attrs)) {
82
- if (value !== undefined) el.setAttribute(key, value);
83
- }
84
- }
85
-
86
- /** Reconciles `document.head` with the merged active specs. */
87
- function apply(): void {
88
- if (typeof document === 'undefined') return;
89
- if (baseTitle === null) baseTitle = document.title;
90
-
91
- const specs = [...order.map((id) => entries.get(id)), routeHead];
92
- const resolved = mergeHead(specs.filter((s): s is HeadSpec => !!s));
93
-
94
- document.title = resolved.title ?? baseTitle;
95
-
96
- for (const stale of document.head.querySelectorAll('[data-toil-head]')) stale.remove();
97
- for (const m of resolved.meta) {
98
- const el = document.createElement('meta');
99
- setAttrs(el, m);
100
- document.head.appendChild(el);
101
- }
102
- for (const l of resolved.link) {
103
- const el = document.createElement('link');
104
- setAttrs(el, l);
105
- document.head.appendChild(el);
106
- }
107
- }
108
-
109
- function addHead(spec: HeadSpec): number {
110
- const id = ++seq;
111
- entries.set(id, spec);
112
- order.push(id);
113
- apply();
114
- return id;
115
- }
116
-
117
- function removeHead(id: number): void {
118
- entries.delete(id);
119
- order = order.filter((x) => x !== id);
120
- apply();
121
- }
122
-
123
- /**
124
- * Applies a head contribution for the lifetime of the calling component: title, `<meta>`, `<link>`.
125
- * Reverts on unmount. Compose freely, a root layout can set defaults a page overrides.
126
- */
127
- export function useHead(spec: HeadSpec): void {
128
- // During the build's SSR extraction (no document, effects don't run), collect the spec so the
129
- // route's component-level head reaches the server HTML. A no-op in the browser bundle.
130
- if (__isSsrBuild()) ssrHeadSink.push(spec);
131
- const json = JSON.stringify(spec);
132
- useEffect(() => {
133
- const id = addHead(JSON.parse(json) as HeadSpec);
134
- return () => {
135
- removeHead(id);
136
- };
137
- }, [json]);
138
- }
139
-
140
- /** Sets `document.title` for the calling component's lifetime. */
141
- export function useTitle(title: string): void {
142
- useHead({ title });
143
- }
144
-
145
- /** Declarative form of {@link useHead}: `<Head title="…" meta={[…]} />`. Renders nothing. */
146
- export function Head(props: HeadSpec): null {
147
- useHead(props);
148
- return null;
149
- }
150
-
151
- /** Sets the current route's baseline head (lowest priority). Pass `null` to clear it. */
152
- export function setRouteHead(spec: HeadSpec | null): void {
153
- routeHead = spec;
154
- apply();
155
- }
156
-
157
- /**
158
- * Applies a route's resolved `metadata` as the baseline head for the calling route's lifetime, and
159
- * clears it on unmount. Used internally by the router; a layout-effect so the title updates before
160
- * paint (no flicker).
161
- */
162
- export function useRouteHead(spec: HeadSpec | undefined): void {
163
- const json = spec ? JSON.stringify(spec) : '';
164
- useLayoutEffect(() => {
165
- setRouteHead(json ? (JSON.parse(json) as HeadSpec) : null);
166
- return () => {
167
- setRouteHead(null);
168
- };
169
- }, [json]);
170
- }
171
-
172
- /**
173
- * Drains the component-level head (`useHead`/`useTitle`/<Head>) collected during ONE route's SSR-build
174
- * render and resolves it, then resets the sink for the next route. Called by the build's template
175
- * extractor right after `renderToString`, so the server HTML carries the same component head the client
176
- * computes — not just the route's static `metadata` export. (Build-only; unused in the browser.)
177
- */
178
- export function __drainSsrHead(): ResolvedHead {
179
- const resolved = mergeHead(ssrHeadSink);
180
- ssrHeadSink = [];
181
- return resolved;
182
- }
@@ -1,110 +0,0 @@
1
- /**
2
- * Route metadata, the declarative SEO counterpart to `useHead`/`<Head>`. A route file may
3
- * `export const metadata` (static) or `export const generateMetadata` (dynamic, using its loader
4
- * data); the compiler-driven loader resolves it to a {@link HeadSpec} that the router applies as the
5
- * route's baseline head (component-level `useHead`/`<Head>` still compose on top and can override).
6
- */
7
- import { type HeadSpec, type LinkTag, type MetaTag, useHead } from './head.js';
8
- import type { RouteParams } from '../routing/match.js';
9
-
10
- /** OpenGraph fields, expanded to `og:*` meta tags. */
11
- export interface OpenGraph {
12
- readonly title?: string;
13
- readonly description?: string;
14
- readonly type?: string;
15
- readonly url?: string;
16
- readonly image?: string;
17
- readonly siteName?: string;
18
- }
19
-
20
- /** A route's metadata. Convenience fields expand to the right `<meta>`/`<link>` tags. */
21
- export interface Metadata {
22
- /** Document title. */
23
- readonly title?: string;
24
- /** `<meta name="description">`. */
25
- readonly description?: string;
26
- /** `<meta name="keywords">`, joined with `, ` if an array. */
27
- readonly keywords?: string | readonly string[];
28
- /** `<link rel="canonical">`. */
29
- readonly canonical?: string;
30
- /** `<meta name="robots">`, e.g. `'noindex, nofollow'`. */
31
- readonly robots?: string;
32
- /** `<meta name="theme-color">`. */
33
- readonly themeColor?: string;
34
- /** OpenGraph (`og:*`) tags. */
35
- readonly openGraph?: OpenGraph;
36
- /** Escape hatch: extra raw `<meta>` tags. */
37
- readonly meta?: readonly MetaTag[];
38
- /** Escape hatch: extra raw `<link>` tags. */
39
- readonly link?: readonly LinkTag[];
40
- }
41
-
42
- /** Arguments passed to {@link GenerateMetadata}: route params, query, and the loader's data. */
43
- export interface GenerateMetadataArgs<T = unknown> {
44
- readonly params: RouteParams;
45
- readonly searchParams: URLSearchParams;
46
- readonly data: T;
47
- }
48
-
49
- /** A route's `export const generateMetadata`, dynamic metadata derived from params/query/loader data. */
50
- export type GenerateMetadata<T = unknown> = (
51
- args: GenerateMetadataArgs<T>,
52
- ) => Metadata | Promise<Metadata>;
53
-
54
- /** Expands a {@link Metadata} into a {@link HeadSpec} (title + concrete meta/link tags). */
55
- export function resolveMetadata(metadata: Metadata): HeadSpec {
56
- const meta: MetaTag[] = [];
57
- if (metadata.description !== undefined) {
58
- meta.push({ name: 'description', content: metadata.description });
59
- }
60
- if (metadata.keywords !== undefined) {
61
- const content =
62
- typeof metadata.keywords === 'string'
63
- ? metadata.keywords
64
- : metadata.keywords.join(', ');
65
- meta.push({ name: 'keywords', content });
66
- }
67
- if (metadata.robots !== undefined) meta.push({ name: 'robots', content: metadata.robots });
68
- if (metadata.themeColor !== undefined) {
69
- meta.push({ name: 'theme-color', content: metadata.themeColor });
70
- }
71
- const og = metadata.openGraph;
72
- if (og) {
73
- const pairs: readonly [string, string | undefined][] = [
74
- ['og:title', og.title],
75
- ['og:description', og.description],
76
- ['og:type', og.type],
77
- ['og:url', og.url],
78
- ['og:image', og.image],
79
- ['og:site_name', og.siteName],
80
- ];
81
- for (const [property, content] of pairs) {
82
- if (content !== undefined) meta.push({ property, content });
83
- }
84
- }
85
- if (metadata.meta) meta.push(...metadata.meta);
86
-
87
- const link: LinkTag[] = [];
88
- if (metadata.canonical !== undefined) link.push({ rel: 'canonical', href: metadata.canonical });
89
- if (metadata.link) link.push(...metadata.link);
90
-
91
- return { title: metadata.title, meta, link };
92
- }
93
-
94
- /**
95
- * Applies a route-style {@link Metadata} object from inside any component for that component's
96
- * lifetime, reverting on unmount. The runtime counterpart of a route's `metadata` export, for
97
- * content that isn't itself a route file (a rendered article, a widget, ...). Composes through the
98
- * head manager like {@link useHead}; a route's own `metadata` (applied last) still wins for keys it
99
- * sets, so this fills in for routes that declare none. Resolved fresh each render, the head manager
100
- * dedupes by value, so passing a computed object is fine.
101
- */
102
- export function useMetadata(metadata: Metadata): void {
103
- useHead(resolveMetadata(metadata));
104
- }
105
-
106
- /** Declarative form of {@link useMetadata}: `<Metadata title="…" openGraph={…} />`. Renders nothing. */
107
- export function Metadata(props: Metadata): null {
108
- useMetadata(props);
109
- return null;
110
- }
@@ -1,130 +0,0 @@
1
- /**
2
- * toiljs client runtime, published as `toiljs/client`. Re-exports the router (mount/Router/Link),
3
- * navigation hooks, prefetching, and the route types consumed by the compiler-generated entry.
4
- * Zero imports needed in user route files beyond this package.
5
- *
6
- * Internals are split by concern: route `types`, history-based `navigation`, the params
7
- * `params-context` + `hooks`, `lazy` component resolution, the `Link`/`Router` components,
8
- * `mount`, `match` (pure matcher), `prefetch` (link prefetcher), and `channel` (WebSocket helper).
9
- */
10
-
11
- export { mount } from './routing/mount.js';
12
- export { Router } from './routing/Router.js';
13
- export {
14
- Auth,
15
- register as authRegister,
16
- login as authLogin,
17
- buildLoginMessage,
18
- LOGIN_CONTEXT,
19
- // Typed auth errors + the discriminant enum: catch `AuthError` (or a specific
20
- // subclass) and branch on `err.code === AuthErrorCode.*`, never on `err.name`.
21
- AuthError,
22
- AuthErrorCode,
23
- UsernameTakenError,
24
- EmailInUseError,
25
- InvalidCredentialsError,
26
- EmailNotConfirmedError,
27
- TwoFactorRequiredError,
28
- ServerAuthFailedError,
29
- TwoFactorCodeError,
30
- ConfirmationInvalidError,
31
- PasswordResetInvalidError,
32
- WeakPasswordError,
33
- InvalidEmailError,
34
- InvalidUsernameError,
35
- checkPassword,
36
- isValidEmail,
37
- isValidUsername,
38
- DEFAULT_PASSWORD_POLICY,
39
- PASSWORD_RULE_LABELS,
40
- } from './auth.js';
41
- export type { KdfParams, AuthOptions, PasswordPolicy, PasswordRule } from './auth.js';
42
- export { Link } from './navigation/Link.js';
43
- export type { LinkProps } from './navigation/Link.js';
44
- export { NavLink, matchActive } from './navigation/NavLink.js';
45
- export type { NavLinkProps, NavLinkState } from './navigation/NavLink.js';
46
- export {
47
- navigate,
48
- back,
49
- forward,
50
- refresh,
51
- setViewTransitions,
52
- setTransitions,
53
- href,
54
- } from './navigation/navigation.js';
55
- export type { NavigateOptions } from './navigation/navigation.js';
56
- export {
57
- useParams,
58
- useNavigate,
59
- useLocation,
60
- usePathname,
61
- useSearchParams,
62
- useRouter,
63
- useNavigationPending,
64
- __setSsrLocation,
65
- } from './routing/hooks.js';
66
- export type { RouterInstance } from './routing/hooks.js';
67
- export {
68
- useLoaderData,
69
- revalidate,
70
- invalidateLoaderData,
71
- LoaderDataContext,
72
- } from './routing/loader.js';
73
- export type {
74
- LoaderArgs,
75
- LoaderFunction,
76
- LoaderData,
77
- Revalidate,
78
- StaticParams,
79
- GenerateStaticParams,
80
- } from './routing/loader.js';
81
- export { useAction } from './routing/action.js';
82
- export type {
83
- UseActionOptions,
84
- ActionState,
85
- ActionHandle,
86
- RevalidateTarget,
87
- } from './routing/action.js';
88
- export { prefetch } from './navigation/prefetch.js';
89
- export type {
90
- RouteDef,
91
- LayoutLoader,
92
- LayoutComponentLoader,
93
- NotFoundLoader,
94
- RouteErrorProps,
95
- Register,
96
- RoutePath,
97
- Href,
98
- } from './types.js';
99
- export { matchRoute } from './routing/match.js';
100
- export type { RouteParams } from './routing/match.js';
101
- export { connectChannel, useChannel, resolveChannelUrl } from './channel/channel.js';
102
- export type { Channel, ChannelOptions, ChannelHook, ChannelData } from './channel/channel.js';
103
- export { makeStreamClient } from './stream/client.js';
104
- export type { StreamChannel, StreamConnectable, StreamClient } from './stream/client.js';
105
- export { useHead, useTitle, Head, mergeHead, __drainSsrHead } from './head/head.js';
106
- export type { HeadSpec, MetaTag, LinkTag, ResolvedHead } from './head/head.js';
107
- export { resolveMetadata, useMetadata, Metadata } from './head/metadata.js';
108
- export type { GenerateMetadata, GenerateMetadataArgs, OpenGraph } from './head/metadata.js';
109
- export { searchPages, registerPages, getPages, pagePath } from './search/search.js';
110
- export type {
111
- PageMeta,
112
- PageSearchResult,
113
- PageSearchOptions,
114
- SearchField,
115
- SearchHints,
116
- } from './search/search.js';
117
- export { usePageSearch } from './search/use-page-search.js';
118
- export type { PageSearch } from './search/use-page-search.js';
119
- export { Image } from './components/Image.js';
120
- export type { ImageProps, ToilImageSource } from './components/Image.js';
121
- export { Script } from './components/Script.js';
122
- export type { ScriptProps, ScriptStrategy } from './components/Script.js';
123
- export { Form } from './components/Form.js';
124
- export type { FormProps } from './components/Form.js';
125
- export { Slot } from './components/Slot.js';
126
- export type { SlotProps } from './components/Slot.js';
127
- export { Server } from './rpc.js';
128
- export { parseError } from './errors.js';
129
- export { Hole, RawHtml, Repeat, Island, attr, __setSsrBuild, __isSsrBuild } from './ssr/markers.js';
130
- export type { HoleProps, RawHtmlProps, RepeatProps, IslandProps } from './ssr/markers.js';