toiljs 0.0.15 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +13 -13
- package/.gitattributes +2 -2
- package/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
- package/.github/ISSUE_TEMPLATE/bug_report.yml +90 -90
- package/.github/ISSUE_TEMPLATE/config.yml +8 -8
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
- package/.github/PULL_REQUEST_TEMPLATE.md +43 -43
- package/.github/changelog-config.json +45 -45
- package/.github/dependabot.yml +27 -27
- package/.github/workflows/ci.yml +191 -191
- package/.prettierrc.json +11 -11
- package/.vscode/settings.json +9 -9
- package/CHANGELOG.md +116 -5
- package/LICENSE +187 -187
- package/README.md +524 -315
- package/as-pect.asconfig.json +34 -34
- package/as-pect.config.js +65 -65
- package/assets/logo.svg +36 -36
- package/build/backend/.tsbuildinfo +1 -1
- package/build/backend/index.d.ts +1 -0
- package/build/backend/index.js +20 -1
- package/build/cli/.tsbuildinfo +1 -1
- package/build/cli/index.js +1320 -696
- package/build/client/.tsbuildinfo +1 -1
- package/build/client/dev/devtools.d.ts +6 -0
- package/build/client/dev/devtools.js +479 -0
- package/build/client/dev/error-overlay.d.ts +9 -0
- package/build/client/dev/error-overlay.js +19 -4
- package/build/client/errors.d.ts +1 -0
- package/build/client/errors.js +3 -0
- package/build/client/index.d.ts +2 -0
- package/build/client/index.js +2 -0
- package/build/client/navigation/prefetch.d.ts +1 -0
- package/build/client/navigation/prefetch.js +35 -0
- package/build/client/routing/Router.js +1 -1
- package/build/client/routing/hooks.js +6 -2
- package/build/client/routing/loader.d.ts +23 -0
- package/build/client/routing/loader.js +53 -7
- package/build/client/routing/mount.js +4 -3
- package/build/client/rpc.d.ts +1 -0
- package/build/client/rpc.js +37 -0
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/compiler/config.d.ts +16 -0
- package/build/compiler/config.js +9 -0
- package/build/compiler/docs.js +78 -21
- package/build/compiler/generate.js +5 -4
- package/build/compiler/index.d.ts +3 -2
- package/build/compiler/index.js +2 -2
- package/build/compiler/plugin.js +228 -0
- package/build/compiler/prerender.d.ts +1 -0
- package/build/compiler/prerender.js +1 -1
- package/build/compiler/seo.d.ts +1 -1
- package/build/compiler/seo.js +20 -5
- package/build/compiler/ssg.js +39 -2
- package/build/compiler/vite.js +25 -0
- package/build/io/.tsbuildinfo +1 -1
- package/build/io/codec.d.ts +54 -0
- package/build/io/codec.js +143 -0
- package/build/io/index.d.ts +1 -2
- package/build/io/index.js +1 -2
- package/build/logger/.tsbuildinfo +1 -1
- package/build/shared/.tsbuildinfo +1 -1
- package/eslint.config.js +48 -48
- package/examples/basic/client/404.tsx +11 -11
- package/examples/basic/client/components/.gitkeep +1 -1
- package/examples/basic/client/global-error.tsx +13 -13
- package/examples/basic/client/layout.tsx +25 -25
- package/examples/basic/client/public/images/.gitkeep +1 -1
- package/examples/basic/client/public/images/logo.svg +36 -36
- package/examples/basic/client/public/robots.txt +2 -2
- package/examples/basic/client/routes/docs/[...slug].tsx +12 -12
- package/examples/basic/client/routes/features/error/error.tsx +16 -16
- package/examples/basic/client/routes/features/index.tsx +1 -1
- package/examples/basic/client/routes/features/template/b.tsx +14 -14
- package/examples/basic/client/routes/files/[[...slug]].tsx +21 -21
- package/examples/basic/client/routes/gallery/layout.tsx +13 -13
- package/examples/basic/client/routes/io.tsx +23 -24
- package/examples/basic/client/routes/loader-demo/loading.tsx +13 -13
- package/examples/basic/client/routes/rest.tsx +74 -0
- package/examples/basic/client/routes/rpc.tsx +43 -0
- package/examples/basic/client/routes/search.tsx +61 -61
- package/examples/basic/client/toil.tsx +5 -5
- package/package.json +167 -148
- package/presets/eslint.js +88 -88
- package/presets/no-uint8array-tostring.js +200 -200
- package/presets/prettier-plugin.js +51 -0
- package/presets/prettier.json +19 -18
- package/presets/tsconfig.json +37 -37
- package/server/runtime/README.md +97 -0
- package/server/runtime/abort/abort.ts +27 -0
- package/server/runtime/env/Server.ts +61 -0
- package/server/runtime/envelope.ts +191 -0
- package/server/runtime/exports/index.ts +52 -0
- package/server/runtime/handlers/ToilHandler.ts +34 -0
- package/server/runtime/index.ts +26 -0
- package/server/runtime/lang/Potential.ts +5 -0
- package/server/runtime/memory.ts +81 -0
- package/server/runtime/request.ts +55 -0
- package/server/runtime/response.ts +86 -0
- package/server/runtime/rest/Rest.ts +39 -0
- package/server/runtime/rest/RestHandler.ts +20 -0
- package/server/runtime/rest/RouteContext.ts +82 -0
- package/server/runtime/rest/match.ts +48 -0
- package/server/runtime/tsconfig.json +7 -0
- package/src/backend/index.ts +202 -160
- package/src/cli/create.ts +15 -5
- package/src/cli/diagnostics.ts +81 -0
- package/src/cli/doctor.ts +384 -7
- package/src/cli/index.ts +11 -2
- package/src/cli/proc.ts +50 -50
- package/src/cli/updates.ts +69 -69
- package/src/cli/validate.ts +31 -31
- package/src/client/channel/channel.ts +146 -146
- package/src/client/components/Form.tsx +65 -65
- package/src/client/components/Script.tsx +113 -113
- package/src/client/components/Slot.tsx +21 -21
- package/src/client/dev/devtools.tsx +1018 -0
- package/src/client/dev/error-overlay.tsx +30 -4
- package/src/client/errors.ts +11 -0
- package/src/client/head/head.ts +167 -167
- package/src/client/head/metadata.ts +112 -112
- package/src/client/index.ts +91 -89
- package/src/client/navigation/NavLink.tsx +86 -86
- package/src/client/navigation/navigation.ts +235 -235
- package/src/client/navigation/prefetch.ts +169 -130
- package/src/client/navigation/scroll.ts +53 -53
- package/src/client/routing/Router.tsx +8 -2
- package/src/client/routing/action.ts +122 -122
- package/src/client/routing/error-boundary.tsx +43 -43
- package/src/client/routing/hooks.ts +21 -6
- package/src/client/routing/loader.ts +325 -235
- package/src/client/routing/match.ts +47 -47
- package/src/client/routing/mount.tsx +54 -52
- package/src/client/routing/params-context.ts +10 -10
- package/src/client/routing/slot-context.ts +7 -7
- package/src/client/rpc.ts +64 -0
- package/src/client/search/search.ts +189 -189
- package/src/client/search/use-page-search.ts +73 -73
- package/src/client/types.ts +73 -73
- package/src/compiler/config.ts +221 -182
- package/src/compiler/docs.ts +285 -228
- package/src/compiler/generate.ts +395 -394
- package/src/compiler/index.ts +66 -57
- package/src/compiler/pages.ts +70 -70
- package/src/compiler/plugin.ts +258 -2
- package/src/compiler/prerender.ts +156 -156
- package/src/compiler/seo.ts +417 -390
- package/src/compiler/ssg.ts +171 -126
- package/src/compiler/vite.ts +34 -0
- package/src/io/FastMap.ts +151 -127
- package/src/io/FastSet.ts +15 -1
- package/src/io/codec.ts +217 -0
- package/src/io/index.ts +10 -11
- package/src/io/lengths.ts +14 -14
- package/src/io/types.ts +19 -18
- package/src/logger/index.ts +22 -22
- package/src/shared/index.ts +10 -10
- package/std/client/index.d.ts +15 -15
- package/std/client/package.json +3 -3
- package/test/assembly/example.spec.ts +17 -7
- package/test/channel.test.ts +21 -21
- package/test/doctor.test.ts +65 -0
- package/test/dom/Link.test.tsx +47 -47
- package/test/dom/NavLink.test.tsx +37 -37
- package/test/dom/error-overlay.test.tsx +44 -44
- package/test/dom/loader.test.tsx +121 -121
- package/test/dom/navigation.test.ts +59 -59
- package/test/dom/revalidate.test.tsx +38 -38
- package/test/dom/route-head.test.tsx +78 -78
- package/test/dom/router-loading.test.tsx +44 -44
- package/test/dom/scroll.test.ts +56 -56
- package/test/dom/use-metadata.test.tsx +58 -58
- package/test/errors.test.ts +21 -0
- package/test/io.test.ts +117 -93
- package/test/navlink.test.ts +28 -28
- package/test/placeholder.test.ts +9 -9
- package/test/prettier-plugin.test.ts +46 -0
- package/test/routes.test.ts +76 -76
- package/test/rpc.test.ts +50 -0
- package/test/seo.test.ts +175 -164
- package/test/slot-layouts.test.ts +69 -69
- package/test/ssg.test.ts +36 -36
- package/test/update.test.ts +44 -44
- package/test/validate.test.ts +42 -42
- package/tests/data-parity/generated-parity.ts +99 -0
- package/tests/data-parity/parity.ts +80 -0
- package/tests/data-parity/spec.ts +46 -0
- package/toil-routes.d.ts +7 -0
- package/tsconfig.backend.json +13 -13
- package/tsconfig.base.json +35 -35
- package/tsconfig.cli.json +13 -13
- package/tsconfig.client.json +14 -14
- package/tsconfig.compiler.json +13 -13
- package/tsconfig.io.json +12 -12
- package/tsconfig.json +22 -22
- package/tsconfig.logger.json +12 -12
- package/tsconfig.server.json +10 -10
- package/tsconfig.shared.json +12 -12
- package/vitest.config.ts +26 -26
- package/.idea/codeStyles/Project.xml +0 -54
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/prettier.xml +0 -7
- package/.idea/toiljs.iml +0 -8
- package/.idea/vcs.xml +0 -6
- package/.toil/entry.tsx +0 -9
- package/.toil/index.html +0 -12
- package/.toil/routes.ts +0 -9
- package/build/cli/configure.d.ts +0 -16
- package/build/cli/configure.js +0 -272
- package/build/cli/create.d.ts +0 -16
- package/build/cli/create.js +0 -420
- package/build/cli/diagnostics.d.ts +0 -55
- package/build/cli/diagnostics.js +0 -333
- package/build/cli/doctor.d.ts +0 -6
- package/build/cli/doctor.js +0 -249
- package/build/cli/features.d.ts +0 -25
- package/build/cli/features.js +0 -107
- package/build/cli/index.d.ts +0 -2
- package/build/cli/proc.d.ts +0 -6
- package/build/cli/proc.js +0 -31
- package/build/cli/ui.d.ts +0 -9
- package/build/cli/ui.js +0 -75
- package/build/cli/update.d.ts +0 -7
- package/build/cli/update.js +0 -117
- package/build/cli/updates.d.ts +0 -10
- package/build/cli/updates.js +0 -45
- package/build/cli/validate.d.ts +0 -4
- package/build/cli/validate.js +0 -19
- package/build/client/Link.d.ts +0 -8
- package/build/client/Link.js +0 -44
- package/build/client/NavLink.d.ts +0 -14
- package/build/client/NavLink.js +0 -37
- package/build/client/Router.d.ts +0 -7
- package/build/client/Router.js +0 -55
- package/build/client/channel.d.ts +0 -23
- package/build/client/channel.js +0 -94
- package/build/client/error-boundary.d.ts +0 -16
- package/build/client/error-boundary.js +0 -19
- package/build/client/head.d.ts +0 -26
- package/build/client/head.js +0 -87
- package/build/client/hooks.d.ts +0 -17
- package/build/client/hooks.js +0 -48
- package/build/client/lazy.d.ts +0 -16
- package/build/client/lazy.js +0 -53
- package/build/client/match.d.ts +0 -2
- package/build/client/match.js +0 -32
- package/build/client/mount.d.ts +0 -2
- package/build/client/mount.js +0 -13
- package/build/client/navigation.d.ts +0 -13
- package/build/client/navigation.js +0 -97
- package/build/client/params-context.d.ts +0 -2
- package/build/client/params-context.js +0 -2
- package/build/client/prefetch.d.ts +0 -11
- package/build/client/prefetch.js +0 -100
- package/build/client/runtime.d.ts +0 -31
- package/build/client/runtime.js +0 -112
- package/build/client/scroll.d.ts +0 -8
- package/build/client/scroll.js +0 -36
- package/build/io/BinaryReader.d.ts +0 -44
- package/build/io/BinaryReader.js +0 -244
- package/build/io/BinaryWriter.d.ts +0 -44
- package/build/io/BinaryWriter.js +0 -297
- package/build/server/release.wasm +0 -0
- package/build/server/release.wat +0 -9
- package/src/io/BinaryReader.ts +0 -340
- package/src/io/BinaryWriter.ts +0 -385
- package/src/server/index.ts +0 -10
- package/src/server/main.ts +0 -13
- package/src/server/tsconfig.json +0 -4
- package/toil-env.d.ts +0 -16
- package/toilconfig.json +0 -30
package/src/client/types.ts
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Public router types shared across the client runtime. Kept dependency-free (type-only React
|
|
3
|
-
* imports) so any module can import them without pulling in component or DOM code.
|
|
4
|
-
*/
|
|
5
|
-
import type { ComponentType, ReactNode } from 'react';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Augmentation point for the project's generated route types. The compiler emits (into
|
|
9
|
-
* `toil-routes.d.ts`) `declare module 'toiljs/client' { interface Register { routePath: <union> } }`,
|
|
10
|
-
* which narrows {@link RoutePath} from `string` to the project's actual routes.
|
|
11
|
-
*/
|
|
12
|
-
export interface Register {}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Union of the project's route paths, static routes as literals, dynamic/catch-all as
|
|
16
|
-
* `` `…/${string}` `` templates. Falls back to `string` before the types are generated.
|
|
17
|
-
*/
|
|
18
|
-
export type RoutePath = Register extends { routePath: infer P }
|
|
19
|
-
? P extends string
|
|
20
|
-
? P
|
|
21
|
-
: string
|
|
22
|
-
: string;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* An href accepted by `Link` / `NavLink` / `navigate`: a known {@link RoutePath} (optionally with
|
|
26
|
-
* `?query` or `#hash`), or an absolute/protocol URL (`https:`, `mailto:`, …). When routes haven't
|
|
27
|
-
* been generated yet, this is just `string`.
|
|
28
|
-
*/
|
|
29
|
-
export type Href =
|
|
30
|
-
| RoutePath
|
|
31
|
-
| `${RoutePath}?${string}`
|
|
32
|
-
| `${RoutePath}#${string}`
|
|
33
|
-
| `${string}:${string}`;
|
|
34
|
-
|
|
35
|
-
/** Lazy loader for a layout component (wraps children). */
|
|
36
|
-
export type LayoutComponentLoader = () => Promise<{
|
|
37
|
-
default: ComponentType<{ children?: ReactNode }>;
|
|
38
|
-
}>;
|
|
39
|
-
|
|
40
|
-
/** Props passed to an `error.tsx` / `global-error.tsx` component. */
|
|
41
|
-
export interface RouteErrorProps {
|
|
42
|
-
readonly error: Error;
|
|
43
|
-
readonly reset: () => void;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Lazy loader for an error component (`error.tsx` / `global-error.tsx`), or `null` if none. */
|
|
47
|
-
export type ErrorComponentLoader =
|
|
48
|
-
| (() => Promise<{ default: ComponentType<RouteErrorProps> }>)
|
|
49
|
-
| null;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* A route entry produced by the compiler: a URL pattern, a lazy loader for its page component, and
|
|
53
|
-
* the chain of nested layout loaders (shallowest → deepest, from nested `layout.tsx` files) that wrap it.
|
|
54
|
-
*/
|
|
55
|
-
export interface RouteDef {
|
|
56
|
-
readonly pattern: string;
|
|
57
|
-
readonly load: () => Promise<{ default: ComponentType }>;
|
|
58
|
-
readonly layouts?: readonly LayoutComponentLoader[];
|
|
59
|
-
/** `template.tsx` chain (root → nested), like layouts, but re-mounted on each navigation. */
|
|
60
|
-
readonly templates?: readonly LayoutComponentLoader[];
|
|
61
|
-
/** Nearest `loading.tsx`, shown as the Suspense fallback while this route loads. */
|
|
62
|
-
readonly loading?: () => Promise<{ default: ComponentType }>;
|
|
63
|
-
/** Nearest `error.tsx`, rendered by an error boundary around this route. */
|
|
64
|
-
readonly errorComponent?: () => Promise<{ default: ComponentType<RouteErrorProps> }>;
|
|
65
|
-
/** Intercepting route (`(.)`/`(..)`/`(...)`), matched in its slot only on soft navigation. */
|
|
66
|
-
readonly intercept?: boolean;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** Optional root layout loader (wraps every page). `null` when the project defines no layout. */
|
|
70
|
-
export type LayoutLoader = LayoutComponentLoader | null;
|
|
71
|
-
|
|
72
|
-
/** Optional custom not-found (404) page loader, rendered when no route matches. */
|
|
73
|
-
export type NotFoundLoader = (() => Promise<{ default: ComponentType }>) | null;
|
|
1
|
+
/**
|
|
2
|
+
* Public router types shared across the client runtime. Kept dependency-free (type-only React
|
|
3
|
+
* imports) so any module can import them without pulling in component or DOM code.
|
|
4
|
+
*/
|
|
5
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Augmentation point for the project's generated route types. The compiler emits (into
|
|
9
|
+
* `toil-routes.d.ts`) `declare module 'toiljs/client' { interface Register { routePath: <union> } }`,
|
|
10
|
+
* which narrows {@link RoutePath} from `string` to the project's actual routes.
|
|
11
|
+
*/
|
|
12
|
+
export interface Register {}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Union of the project's route paths, static routes as literals, dynamic/catch-all as
|
|
16
|
+
* `` `…/${string}` `` templates. Falls back to `string` before the types are generated.
|
|
17
|
+
*/
|
|
18
|
+
export type RoutePath = Register extends { routePath: infer P }
|
|
19
|
+
? P extends string
|
|
20
|
+
? P
|
|
21
|
+
: string
|
|
22
|
+
: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* An href accepted by `Link` / `NavLink` / `navigate`: a known {@link RoutePath} (optionally with
|
|
26
|
+
* `?query` or `#hash`), or an absolute/protocol URL (`https:`, `mailto:`, …). When routes haven't
|
|
27
|
+
* been generated yet, this is just `string`.
|
|
28
|
+
*/
|
|
29
|
+
export type Href =
|
|
30
|
+
| RoutePath
|
|
31
|
+
| `${RoutePath}?${string}`
|
|
32
|
+
| `${RoutePath}#${string}`
|
|
33
|
+
| `${string}:${string}`;
|
|
34
|
+
|
|
35
|
+
/** Lazy loader for a layout component (wraps children). */
|
|
36
|
+
export type LayoutComponentLoader = () => Promise<{
|
|
37
|
+
default: ComponentType<{ children?: ReactNode }>;
|
|
38
|
+
}>;
|
|
39
|
+
|
|
40
|
+
/** Props passed to an `error.tsx` / `global-error.tsx` component. */
|
|
41
|
+
export interface RouteErrorProps {
|
|
42
|
+
readonly error: Error;
|
|
43
|
+
readonly reset: () => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Lazy loader for an error component (`error.tsx` / `global-error.tsx`), or `null` if none. */
|
|
47
|
+
export type ErrorComponentLoader =
|
|
48
|
+
| (() => Promise<{ default: ComponentType<RouteErrorProps> }>)
|
|
49
|
+
| null;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* A route entry produced by the compiler: a URL pattern, a lazy loader for its page component, and
|
|
53
|
+
* the chain of nested layout loaders (shallowest → deepest, from nested `layout.tsx` files) that wrap it.
|
|
54
|
+
*/
|
|
55
|
+
export interface RouteDef {
|
|
56
|
+
readonly pattern: string;
|
|
57
|
+
readonly load: () => Promise<{ default: ComponentType }>;
|
|
58
|
+
readonly layouts?: readonly LayoutComponentLoader[];
|
|
59
|
+
/** `template.tsx` chain (root → nested), like layouts, but re-mounted on each navigation. */
|
|
60
|
+
readonly templates?: readonly LayoutComponentLoader[];
|
|
61
|
+
/** Nearest `loading.tsx`, shown as the Suspense fallback while this route loads. */
|
|
62
|
+
readonly loading?: () => Promise<{ default: ComponentType }>;
|
|
63
|
+
/** Nearest `error.tsx`, rendered by an error boundary around this route. */
|
|
64
|
+
readonly errorComponent?: () => Promise<{ default: ComponentType<RouteErrorProps> }>;
|
|
65
|
+
/** Intercepting route (`(.)`/`(..)`/`(...)`), matched in its slot only on soft navigation. */
|
|
66
|
+
readonly intercept?: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Optional root layout loader (wraps every page). `null` when the project defines no layout. */
|
|
70
|
+
export type LayoutLoader = LayoutComponentLoader | null;
|
|
71
|
+
|
|
72
|
+
/** Optional custom not-found (404) page loader, rendered when no route matches. */
|
|
73
|
+
export type NotFoundLoader = (() => Promise<{ default: ComponentType }>) | null;
|
package/src/compiler/config.ts
CHANGED
|
@@ -1,182 +1,221 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
|
-
|
|
5
|
-
import { type InlineConfig } from 'vite';
|
|
6
|
-
|
|
7
|
-
import { type SeoConfig } from './seo.js';
|
|
8
|
-
|
|
9
|
-
export type { SeoConfig } from './seo.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
readonly
|
|
25
|
-
/**
|
|
26
|
-
readonly
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
readonly
|
|
42
|
-
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*/
|
|
47
|
-
readonly
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
readonly
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*/
|
|
64
|
-
readonly
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
readonly
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
readonly
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
readonly
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
|
+
|
|
5
|
+
import { type InlineConfig } from 'vite';
|
|
6
|
+
|
|
7
|
+
import { type SeoConfig } from './seo.js';
|
|
8
|
+
|
|
9
|
+
export type { SeoConfig } from './seo.js';
|
|
10
|
+
|
|
11
|
+
/** Built-in AI providers the dev toolbar can proxy to. */
|
|
12
|
+
export enum AiProvider {
|
|
13
|
+
Anthropic = 'anthropic',
|
|
14
|
+
OpenAI = 'openai',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Dev toolbar AI integration (dev only; the key stays server-side). */
|
|
18
|
+
export interface DevtoolsAiConfig {
|
|
19
|
+
/** Built-in provider. With `endpoint` set, that takes precedence. */
|
|
20
|
+
readonly provider?: AiProvider;
|
|
21
|
+
/** Model id (e.g. `claude-sonnet-4-6`, `gpt-4o`). */
|
|
22
|
+
readonly model?: string;
|
|
23
|
+
/** Name of the env var holding the API key (read by the dev server, never sent to the client). */
|
|
24
|
+
readonly apiKeyEnv?: string;
|
|
25
|
+
/** Custom POST endpoint (`{ prompt }` in, `{ text }` out); overrides `provider`. */
|
|
26
|
+
readonly endpoint?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Dev toolbar configuration. */
|
|
30
|
+
export interface DevtoolsConfig {
|
|
31
|
+
readonly ai?: DevtoolsAiConfig;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Client-side (TSX/React/Vite) configuration. All fields optional; sensible defaults applied.
|
|
36
|
+
*/
|
|
37
|
+
export interface ClientConfig {
|
|
38
|
+
/** Client source directory, relative to root. Default `client`. */
|
|
39
|
+
readonly srcDir?: string;
|
|
40
|
+
/** Routes directory, relative to `srcDir`. Default `routes`. */
|
|
41
|
+
readonly routesDir?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Static assets directory, relative to root. Default `<srcDir>/public` (e.g. `client/public`).
|
|
44
|
+
* Holds the `index.html` template (owned and edited by you) plus any files served as-is at the
|
|
45
|
+
* base path (favicons, images, and the like).
|
|
46
|
+
*/
|
|
47
|
+
readonly publicDir?: string;
|
|
48
|
+
/** Production output directory, relative to root. Default `build/client`. */
|
|
49
|
+
readonly outDir?: string;
|
|
50
|
+
/** Public base path. Default `/`. */
|
|
51
|
+
readonly base?: string;
|
|
52
|
+
/** Dev server port. Default `3000`. */
|
|
53
|
+
readonly port?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Optimize imported images at build time (resize/convert via `vite-imagetools` + sharp): an
|
|
56
|
+
* import like `logo.png?w=400;800&format=webp&as=srcset` emits resized, compressed variants.
|
|
57
|
+
* Default `true`. Set `false` to disable the pipeline (images are then served as-is).
|
|
58
|
+
*/
|
|
59
|
+
readonly images?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Preload bundled fonts at build time: injects `<link rel="preload" as="font">` for each
|
|
62
|
+
* `@font-face` font so it loads in parallel with the CSS (faster text paint). Default `true`.
|
|
63
|
+
*/
|
|
64
|
+
readonly fonts?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Animate cross-page navigations with the browser View Transitions API (a crossfade by default;
|
|
67
|
+
* add `view-transition-name` in CSS for shared-element transitions). Respects
|
|
68
|
+
* `prefers-reduced-motion`. Default `false`.
|
|
69
|
+
*/
|
|
70
|
+
readonly viewTransitions?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Wrap client navigations in a React transition, keeping the current page visible while the next
|
|
73
|
+
* route's loader runs instead of showing its `loading.tsx` right away. Default `false` (a
|
|
74
|
+
* navigation commits eagerly, so the loading state appears immediately).
|
|
75
|
+
*/
|
|
76
|
+
readonly transitions?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* The dev toolbar (a floating panel in `toiljs dev` with route/build info, errors, and live
|
|
79
|
+
* controls). `true` (default) / `false` to disable, or an object to configure its AI integration.
|
|
80
|
+
* Never included in production builds. The AI key is read server-side from `apiKeyEnv` and never
|
|
81
|
+
* reaches the browser; the toolbar always offers Claude/ChatGPT hand-off links regardless.
|
|
82
|
+
*/
|
|
83
|
+
readonly devtools?: boolean | DevtoolsConfig;
|
|
84
|
+
/**
|
|
85
|
+
* Build-time SEO: bakes site-level metadata into the HTML `<head>` (so JS-less crawlers and AI
|
|
86
|
+
* bots see real tags) and generates `robots.txt`, `sitemap.xml`, and `llms.txt`. Omit to skip.
|
|
87
|
+
*/
|
|
88
|
+
readonly seo?: SeoConfig;
|
|
89
|
+
/**
|
|
90
|
+
* Raw Vite escape hatch, deep-merged over the framework's opinionated config.
|
|
91
|
+
* This is NOT the client config itself, toil owns the Vite setup; use this only
|
|
92
|
+
* to override specific Vite options.
|
|
93
|
+
*/
|
|
94
|
+
readonly vite?: InlineConfig;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Server-side (toilscript → WASM) configuration. Reserved: the compiler does not yet
|
|
99
|
+
* build the server target via `toil build`; today it is compiled by `toilscript` directly.
|
|
100
|
+
*/
|
|
101
|
+
export interface ServerConfig {
|
|
102
|
+
/** Server source directory, relative to root. Default `server`. */
|
|
103
|
+
readonly srcDir?: string;
|
|
104
|
+
/** Server build output directory, relative to root. Default `build/server`. */
|
|
105
|
+
readonly outDir?: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* The `toil.config` schema. All fields optional; sensible defaults applied.
|
|
110
|
+
* Client and server are configured in separate sections.
|
|
111
|
+
*/
|
|
112
|
+
export interface ToilConfig {
|
|
113
|
+
/** Project root. Defaults to the current working directory. */
|
|
114
|
+
readonly root?: string;
|
|
115
|
+
/** Client (TSX/React/Vite) configuration. */
|
|
116
|
+
readonly client?: ClientConfig;
|
|
117
|
+
/** Server (toilscript/WASM) configuration. */
|
|
118
|
+
readonly server?: ServerConfig;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Fully-resolved config with absolute paths, used internally by the compiler. */
|
|
122
|
+
export interface ResolvedToilConfig {
|
|
123
|
+
readonly root: string;
|
|
124
|
+
readonly srcDir: string;
|
|
125
|
+
readonly clientAbsDir: string;
|
|
126
|
+
readonly routesAbsDir: string;
|
|
127
|
+
/** Absolute path to the static-assets dir (holds the `index.html` template). */
|
|
128
|
+
readonly publicDir: string;
|
|
129
|
+
readonly toilDir: string;
|
|
130
|
+
readonly outDir: string;
|
|
131
|
+
readonly base: string;
|
|
132
|
+
readonly port: number;
|
|
133
|
+
/** Whether build-time image optimization (`vite-imagetools`) is enabled. */
|
|
134
|
+
readonly images: boolean;
|
|
135
|
+
/** Whether build-time font preloading is enabled. */
|
|
136
|
+
readonly fonts: boolean;
|
|
137
|
+
/** Whether animated View Transitions are enabled for navigation. */
|
|
138
|
+
readonly viewTransitions: boolean;
|
|
139
|
+
/** Whether navigations are wrapped in a React transition (keep current page while loading). */
|
|
140
|
+
readonly transitions: boolean;
|
|
141
|
+
/** Whether the dev toolbar is enabled (dev only). */
|
|
142
|
+
readonly devtools: boolean;
|
|
143
|
+
/** Dev toolbar AI config (dev only), or `null` when not configured. */
|
|
144
|
+
readonly devtoolsAi: DevtoolsAiConfig | null;
|
|
145
|
+
/** Build-time SEO config, or `null` when not configured. */
|
|
146
|
+
readonly seo: SeoConfig | null;
|
|
147
|
+
/** Absolute path to the framework client runtime (`toiljs/client`). */
|
|
148
|
+
readonly runtimePath: string;
|
|
149
|
+
readonly vite: InlineConfig;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Identity helper for typed config files: `export default defineConfig({ ... })`. */
|
|
153
|
+
export function defineConfig(config: ToilConfig): ToilConfig {
|
|
154
|
+
return config;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const CONFIG_NAMES = [
|
|
158
|
+
'toil.config.ts',
|
|
159
|
+
'toil.config.mts',
|
|
160
|
+
'toil.config.js',
|
|
161
|
+
'toil.config.mjs',
|
|
162
|
+
'toiljs.config.ts',
|
|
163
|
+
'toiljs.config.mts',
|
|
164
|
+
'toiljs.config.js',
|
|
165
|
+
'toiljs.config.mjs',
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
/** Path to the built client runtime (`build/client/index.js`), sibling to `build/compiler`. */
|
|
169
|
+
function resolveRuntimePath(): string {
|
|
170
|
+
return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../client/index.js');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Finds and loads `toil.config.*` or `toiljs.config.*` from `root`, then resolves defaults. */
|
|
174
|
+
export async function loadConfig(
|
|
175
|
+
opts: { root?: string; port?: number } = {},
|
|
176
|
+
): Promise<ResolvedToilConfig> {
|
|
177
|
+
const root = path.resolve(opts.root ?? process.cwd());
|
|
178
|
+
|
|
179
|
+
let user: ToilConfig = {};
|
|
180
|
+
for (const name of CONFIG_NAMES) {
|
|
181
|
+
const candidate = path.join(root, name);
|
|
182
|
+
if (fs.existsSync(candidate)) {
|
|
183
|
+
const loaded = (await import(pathToFileURL(candidate).href)) as {
|
|
184
|
+
default?: ToilConfig;
|
|
185
|
+
};
|
|
186
|
+
if (loaded.default) user = loaded.default;
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const client = user.client ?? {};
|
|
192
|
+
const srcDir = client.srcDir ?? 'client';
|
|
193
|
+
const routesDir = client.routesDir ?? 'routes';
|
|
194
|
+
const clientAbsDir = path.join(root, srcDir);
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
root,
|
|
198
|
+
srcDir,
|
|
199
|
+
clientAbsDir,
|
|
200
|
+
routesAbsDir: path.join(clientAbsDir, routesDir),
|
|
201
|
+
publicDir: client.publicDir
|
|
202
|
+
? path.resolve(root, client.publicDir)
|
|
203
|
+
: path.join(clientAbsDir, 'public'),
|
|
204
|
+
toilDir: path.join(root, '.toil'),
|
|
205
|
+
outDir: client.outDir ?? 'build/client',
|
|
206
|
+
base: client.base ?? '/',
|
|
207
|
+
port: opts.port ?? client.port ?? 3000,
|
|
208
|
+
images: client.images ?? true,
|
|
209
|
+
fonts: client.fonts ?? true,
|
|
210
|
+
viewTransitions: client.viewTransitions ?? false,
|
|
211
|
+
transitions: client.transitions ?? false,
|
|
212
|
+
devtools: client.devtools !== false,
|
|
213
|
+
devtoolsAi:
|
|
214
|
+
client.devtools != null && typeof client.devtools === 'object'
|
|
215
|
+
? (client.devtools.ai ?? null)
|
|
216
|
+
: null,
|
|
217
|
+
seo: client.seo ?? null,
|
|
218
|
+
runtimePath: resolveRuntimePath(),
|
|
219
|
+
vite: client.vite ?? {},
|
|
220
|
+
};
|
|
221
|
+
}
|