toiljs 0.0.14 → 0.0.15

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.
@@ -1,173 +1,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
- /**
12
- * Client-side (TSX/React/Vite) configuration. All fields optional; sensible defaults applied.
13
- */
14
- export interface ClientConfig {
15
- /** Client source directory, relative to root. Default `client`. */
16
- readonly srcDir?: string;
17
- /** Routes directory, relative to `srcDir`. Default `routes`. */
18
- readonly routesDir?: string;
19
- /**
20
- * Static assets directory, relative to root. Default `<srcDir>/public` (e.g. `client/public`).
21
- * Holds the `index.html` template (owned and edited by you) plus any files served as-is at the
22
- * base path (favicons, images, …).
23
- */
24
- readonly publicDir?: string;
25
- /** Production output directory, relative to root. Default `build/client`. */
26
- readonly outDir?: string;
27
- /** Public base path. Default `/`. */
28
- readonly base?: string;
29
- /** Dev server port. Default `3000`. */
30
- readonly port?: number;
31
- /**
32
- * Optimize imported images at build time (resize/convert via `vite-imagetools` + sharp): an
33
- * import like `logo.png?w=400;800&format=webp&as=srcset` emits resized, compressed variants.
34
- * Default `true`. Set `false` to disable the pipeline (images are then served as-is).
35
- */
36
- readonly images?: boolean;
37
- /**
38
- * Preload bundled fonts at build time: injects `<link rel="preload" as="font">` for each
39
- * `@font-face` font so it loads in parallel with the CSS (faster text paint). Default `true`.
40
- */
41
- readonly fonts?: boolean;
42
- /**
43
- * Animate cross-page navigations with the browser View Transitions API (a crossfade by default;
44
- * add `view-transition-name` in CSS for shared-element transitions). Respects
45
- * `prefers-reduced-motion`. Default `false`.
46
- */
47
- readonly viewTransitions?: boolean;
48
- /**
49
- * Build-time SEO: bakes site-level metadata into the HTML `<head>` (so JS-less crawlers and AI
50
- * bots see real tags) and generates `robots.txt`, `sitemap.xml`, and `llms.txt`. Omit to skip.
51
- */
52
- readonly seo?: SeoConfig;
53
- /**
54
- * Raw Vite escape hatch, deep-merged over the framework's opinionated config.
55
- * This is NOT the client config itself, toil owns the Vite setup; use this only
56
- * to override specific Vite options.
57
- */
58
- readonly vite?: InlineConfig;
59
- }
60
-
61
- /**
62
- * Server-side (toilscript WASM) configuration. Reserved: the compiler does not yet
63
- * build the server target via `toil build`; today it is compiled by `toilscript` directly.
64
- */
65
- export interface ServerConfig {
66
- /** Server source directory, relative to root. Default `server`. */
67
- readonly srcDir?: string;
68
- /** Server build output directory, relative to root. Default `build/server`. */
69
- readonly outDir?: string;
70
- }
71
-
72
- /**
73
- * The `toil.config` schema. All fields optional; sensible defaults applied.
74
- * Client and server are configured in separate sections.
75
- */
76
- export interface ToilConfig {
77
- /** Project root. Defaults to the current working directory. */
78
- readonly root?: string;
79
- /** Client (TSX/React/Vite) configuration. */
80
- readonly client?: ClientConfig;
81
- /** Server (toilscript/WASM) configuration. */
82
- readonly server?: ServerConfig;
83
- }
84
-
85
- /** Fully-resolved config with absolute paths, used internally by the compiler. */
86
- export interface ResolvedToilConfig {
87
- readonly root: string;
88
- readonly srcDir: string;
89
- readonly clientAbsDir: string;
90
- readonly routesAbsDir: string;
91
- /** Absolute path to the static-assets dir (holds the `index.html` template). */
92
- readonly publicDir: string;
93
- readonly toilDir: string;
94
- readonly outDir: string;
95
- readonly base: string;
96
- readonly port: number;
97
- /** Whether build-time image optimization (`vite-imagetools`) is enabled. */
98
- readonly images: boolean;
99
- /** Whether build-time font preloading is enabled. */
100
- readonly fonts: boolean;
101
- /** Whether animated View Transitions are enabled for navigation. */
102
- readonly viewTransitions: boolean;
103
- /** Build-time SEO config, or `null` when not configured. */
104
- readonly seo: SeoConfig | null;
105
- /** Absolute path to the framework client runtime (`toiljs/client`). */
106
- readonly runtimePath: string;
107
- readonly vite: InlineConfig;
108
- }
109
-
110
- /** Identity helper for typed config files: `export default defineConfig({ ... })`. */
111
- export function defineConfig(config: ToilConfig): ToilConfig {
112
- return config;
113
- }
114
-
115
- const CONFIG_NAMES = [
116
- 'toil.config.ts',
117
- 'toil.config.mts',
118
- 'toil.config.js',
119
- 'toil.config.mjs',
120
- 'toiljs.config.ts',
121
- 'toiljs.config.mts',
122
- 'toiljs.config.js',
123
- 'toiljs.config.mjs',
124
- ];
125
-
126
- /** Path to the built client runtime (`build/client/index.js`), sibling to `build/compiler`. */
127
- function resolveRuntimePath(): string {
128
- return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../client/index.js');
129
- }
130
-
131
- /** Finds and loads `toil.config.*` or `toiljs.config.*` from `root`, then resolves defaults. */
132
- export async function loadConfig(
133
- opts: { root?: string; port?: number } = {},
134
- ): Promise<ResolvedToilConfig> {
135
- const root = path.resolve(opts.root ?? process.cwd());
136
-
137
- let user: ToilConfig = {};
138
- for (const name of CONFIG_NAMES) {
139
- const candidate = path.join(root, name);
140
- if (fs.existsSync(candidate)) {
141
- const loaded = (await import(pathToFileURL(candidate).href)) as {
142
- default?: ToilConfig;
143
- };
144
- if (loaded.default) user = loaded.default;
145
- break;
146
- }
147
- }
148
-
149
- const client = user.client ?? {};
150
- const srcDir = client.srcDir ?? 'client';
151
- const routesDir = client.routesDir ?? 'routes';
152
- const clientAbsDir = path.join(root, srcDir);
153
-
154
- return {
155
- root,
156
- srcDir,
157
- clientAbsDir,
158
- routesAbsDir: path.join(clientAbsDir, routesDir),
159
- publicDir: client.publicDir
160
- ? path.resolve(root, client.publicDir)
161
- : path.join(clientAbsDir, 'public'),
162
- toilDir: path.join(root, '.toil'),
163
- outDir: client.outDir ?? 'build/client',
164
- base: client.base ?? '/',
165
- port: opts.port ?? client.port ?? 3000,
166
- images: client.images ?? true,
167
- fonts: client.fonts ?? true,
168
- viewTransitions: client.viewTransitions ?? false,
169
- seo: client.seo ?? null,
170
- runtimePath: resolveRuntimePath(),
171
- vite: client.vite ?? {},
172
- };
173
- }
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
+ * Client-side (TSX/React/Vite) configuration. All fields optional; sensible defaults applied.
13
+ */
14
+ export interface ClientConfig {
15
+ /** Client source directory, relative to root. Default `client`. */
16
+ readonly srcDir?: string;
17
+ /** Routes directory, relative to `srcDir`. Default `routes`. */
18
+ readonly routesDir?: string;
19
+ /**
20
+ * Static assets directory, relative to root. Default `<srcDir>/public` (e.g. `client/public`).
21
+ * Holds the `index.html` template (owned and edited by you) plus any files served as-is at the
22
+ * base path (favicons, images, …).
23
+ */
24
+ readonly publicDir?: string;
25
+ /** Production output directory, relative to root. Default `build/client`. */
26
+ readonly outDir?: string;
27
+ /** Public base path. Default `/`. */
28
+ readonly base?: string;
29
+ /** Dev server port. Default `3000`. */
30
+ readonly port?: number;
31
+ /**
32
+ * Optimize imported images at build time (resize/convert via `vite-imagetools` + sharp): an
33
+ * import like `logo.png?w=400;800&format=webp&as=srcset` emits resized, compressed variants.
34
+ * Default `true`. Set `false` to disable the pipeline (images are then served as-is).
35
+ */
36
+ readonly images?: boolean;
37
+ /**
38
+ * Preload bundled fonts at build time: injects `<link rel="preload" as="font">` for each
39
+ * `@font-face` font so it loads in parallel with the CSS (faster text paint). Default `true`.
40
+ */
41
+ readonly fonts?: boolean;
42
+ /**
43
+ * Animate cross-page navigations with the browser View Transitions API (a crossfade by default;
44
+ * add `view-transition-name` in CSS for shared-element transitions). Respects
45
+ * `prefers-reduced-motion`. Default `false`.
46
+ */
47
+ readonly viewTransitions?: boolean;
48
+ /**
49
+ * Wrap client navigations in a React transition, keeping the current page visible while the next
50
+ * route's loader runs instead of showing its `loading.tsx` right away. Default `false` (a
51
+ * navigation commits eagerly, so the loading state appears immediately).
52
+ */
53
+ readonly transitions?: boolean;
54
+ /**
55
+ * Build-time SEO: bakes site-level metadata into the HTML `<head>` (so JS-less crawlers and AI
56
+ * bots see real tags) and generates `robots.txt`, `sitemap.xml`, and `llms.txt`. Omit to skip.
57
+ */
58
+ readonly seo?: SeoConfig;
59
+ /**
60
+ * Raw Vite escape hatch, deep-merged over the framework's opinionated config.
61
+ * This is NOT the client config itself, toil owns the Vite setup; use this only
62
+ * to override specific Vite options.
63
+ */
64
+ readonly vite?: InlineConfig;
65
+ }
66
+
67
+ /**
68
+ * Server-side (toilscript WASM) configuration. Reserved: the compiler does not yet
69
+ * build the server target via `toil build`; today it is compiled by `toilscript` directly.
70
+ */
71
+ export interface ServerConfig {
72
+ /** Server source directory, relative to root. Default `server`. */
73
+ readonly srcDir?: string;
74
+ /** Server build output directory, relative to root. Default `build/server`. */
75
+ readonly outDir?: string;
76
+ }
77
+
78
+ /**
79
+ * The `toil.config` schema. All fields optional; sensible defaults applied.
80
+ * Client and server are configured in separate sections.
81
+ */
82
+ export interface ToilConfig {
83
+ /** Project root. Defaults to the current working directory. */
84
+ readonly root?: string;
85
+ /** Client (TSX/React/Vite) configuration. */
86
+ readonly client?: ClientConfig;
87
+ /** Server (toilscript/WASM) configuration. */
88
+ readonly server?: ServerConfig;
89
+ }
90
+
91
+ /** Fully-resolved config with absolute paths, used internally by the compiler. */
92
+ export interface ResolvedToilConfig {
93
+ readonly root: string;
94
+ readonly srcDir: string;
95
+ readonly clientAbsDir: string;
96
+ readonly routesAbsDir: string;
97
+ /** Absolute path to the static-assets dir (holds the `index.html` template). */
98
+ readonly publicDir: string;
99
+ readonly toilDir: string;
100
+ readonly outDir: string;
101
+ readonly base: string;
102
+ readonly port: number;
103
+ /** Whether build-time image optimization (`vite-imagetools`) is enabled. */
104
+ readonly images: boolean;
105
+ /** Whether build-time font preloading is enabled. */
106
+ readonly fonts: boolean;
107
+ /** Whether animated View Transitions are enabled for navigation. */
108
+ readonly viewTransitions: boolean;
109
+ /** Whether navigations are wrapped in a React transition (keep current page while loading). */
110
+ readonly transitions: boolean;
111
+ /** Build-time SEO config, or `null` when not configured. */
112
+ readonly seo: SeoConfig | null;
113
+ /** Absolute path to the framework client runtime (`toiljs/client`). */
114
+ readonly runtimePath: string;
115
+ readonly vite: InlineConfig;
116
+ }
117
+
118
+ /** Identity helper for typed config files: `export default defineConfig({ ... })`. */
119
+ export function defineConfig(config: ToilConfig): ToilConfig {
120
+ return config;
121
+ }
122
+
123
+ const CONFIG_NAMES = [
124
+ 'toil.config.ts',
125
+ 'toil.config.mts',
126
+ 'toil.config.js',
127
+ 'toil.config.mjs',
128
+ 'toiljs.config.ts',
129
+ 'toiljs.config.mts',
130
+ 'toiljs.config.js',
131
+ 'toiljs.config.mjs',
132
+ ];
133
+
134
+ /** Path to the built client runtime (`build/client/index.js`), sibling to `build/compiler`. */
135
+ function resolveRuntimePath(): string {
136
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../client/index.js');
137
+ }
138
+
139
+ /** Finds and loads `toil.config.*` or `toiljs.config.*` from `root`, then resolves defaults. */
140
+ export async function loadConfig(
141
+ opts: { root?: string; port?: number } = {},
142
+ ): Promise<ResolvedToilConfig> {
143
+ const root = path.resolve(opts.root ?? process.cwd());
144
+
145
+ let user: ToilConfig = {};
146
+ for (const name of CONFIG_NAMES) {
147
+ const candidate = path.join(root, name);
148
+ if (fs.existsSync(candidate)) {
149
+ const loaded = (await import(pathToFileURL(candidate).href)) as {
150
+ default?: ToilConfig;
151
+ };
152
+ if (loaded.default) user = loaded.default;
153
+ break;
154
+ }
155
+ }
156
+
157
+ const client = user.client ?? {};
158
+ const srcDir = client.srcDir ?? 'client';
159
+ const routesDir = client.routesDir ?? 'routes';
160
+ const clientAbsDir = path.join(root, srcDir);
161
+
162
+ return {
163
+ root,
164
+ srcDir,
165
+ clientAbsDir,
166
+ routesAbsDir: path.join(clientAbsDir, routesDir),
167
+ publicDir: client.publicDir
168
+ ? path.resolve(root, client.publicDir)
169
+ : path.join(clientAbsDir, 'public'),
170
+ toilDir: path.join(root, '.toil'),
171
+ outDir: client.outDir ?? 'build/client',
172
+ base: client.base ?? '/',
173
+ port: opts.port ?? client.port ?? 3000,
174
+ images: client.images ?? true,
175
+ fonts: client.fonts ?? true,
176
+ viewTransitions: client.viewTransitions ?? false,
177
+ transitions: client.transitions ?? false,
178
+ seo: client.seo ?? null,
179
+ runtimePath: resolveRuntimePath(),
180
+ vite: client.vite ?? {},
181
+ };
182
+ }
@@ -47,6 +47,8 @@ export const TOIL_ENV_DTS =
47
47
  ` type Revalidate = import('toiljs/client').Revalidate;\n` +
48
48
  ` type Metadata = import('toiljs/client').Metadata;\n` +
49
49
  ` type GenerateMetadata<T = unknown> = import('toiljs/client').GenerateMetadata<T>;\n` +
50
+ ` type GenerateStaticParams = import('toiljs/client').GenerateStaticParams;\n` +
51
+ ` type StaticParams = import('toiljs/client').StaticParams;\n` +
50
52
  ` type RouteErrorProps = import('toiljs/client').RouteErrorProps;\n` +
51
53
  ` type Href = import('toiljs/client').Href;\n` +
52
54
  ` type RoutePath = import('toiljs/client').RoutePath;\n` +
@@ -292,6 +294,7 @@ export function generate(cfg: ResolvedToilConfig): ScannedRoute[] {
292
294
  `import { pages } from './routes';\n\n` +
293
295
  `Object.assign(globalThis, { Toil, BinaryWriter, BinaryReader, FastMap, FastSet });\n` +
294
296
  `Toil.setViewTransitions(${String(cfg.viewTransitions)});\n` +
297
+ `Toil.setTransitions(${String(cfg.transitions)});\n` +
295
298
  `Toil.registerPages(pages);\n`;
296
299
  fs.writeFileSync(path.join(cfg.toilDir, 'globals.ts'), globalsSrc);
297
300
 
@@ -6,6 +6,7 @@ import { startBackend, type RunningBackend } from 'toiljs/backend';
6
6
 
7
7
  import { loadConfig } from './config.js';
8
8
  import { generate } from './generate.js';
9
+ import { prerenderStaticParams } from './ssg.js';
9
10
  import { createViteConfig } from './vite.js';
10
11
 
11
12
  export interface ToilCommandOptions {
@@ -28,6 +29,8 @@ export async function build(opts: ToilCommandOptions = {}): Promise<void> {
28
29
  const cfg = await loadConfig(opts);
29
30
  generate(cfg);
30
31
  await viteBuild(await createViteConfig(cfg));
32
+ // SSG: bake per-URL HTML + sitemap for dynamic routes that opt in via `generateStaticParams`.
33
+ await prerenderStaticParams(cfg);
31
34
  }
32
35
 
33
36
  /**