toiljs 0.0.113 → 0.0.115
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/CHANGELOG.md +18 -0
- package/build/backend/.tsbuildinfo +1 -1
- package/build/cli/.tsbuildinfo +1 -1
- package/build/cli/index.js +198 -41
- package/build/client/.tsbuildinfo +1 -1
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/compiler/index.js +1 -1
- package/build/compiler/pages.js +1 -13
- package/build/compiler/prerender.d.ts +1 -0
- package/build/compiler/prerender.js +39 -2
- package/build/compiler/toil-docs.generated.js +3 -3
- package/build/devserver/.tsbuildinfo +1 -1
- package/build/devserver/daemon/host.d.ts +2 -1
- package/build/devserver/daemon/host.js +12 -12
- package/build/devserver/daemon/index.js +3 -3
- package/build/io/.tsbuildinfo +1 -1
- package/build/logger/.tsbuildinfo +1 -1
- package/build/shared/.tsbuildinfo +1 -1
- package/docs/background/daemons.md +49 -3
- package/docs/cli/README.md +4 -2
- package/docs/getting-started/installation.md +18 -0
- package/package.json +15 -15
- package/src/cli/create.ts +171 -25
- package/src/cli/diagnostics.ts +74 -0
- package/src/cli/doctor.ts +105 -27
- package/src/cli/features.ts +7 -3
- package/src/cli/index.ts +2 -2
- package/src/cli/update.ts +30 -3
- package/src/cli/updates.ts +23 -0
- package/src/compiler/index.ts +11 -2
- package/src/compiler/pages.ts +1 -22
- package/src/compiler/prerender.ts +57 -3
- package/src/compiler/toil-docs.generated.ts +3 -3
- package/src/devserver/daemon/host.ts +29 -19
- package/src/devserver/daemon/index.ts +12 -5
- package/test/daemon-emulation.test.ts +44 -2
- package/test/doctor.test.ts +28 -0
- package/test/fixtures/daemon-app.ts +9 -4
- package/test/prerender.test.ts +64 -2
- package/test/update.test.ts +15 -1
- package/tsconfig.base.json +0 -1
package/src/cli/updates.ts
CHANGED
|
@@ -50,6 +50,29 @@ export function parseNcuJson(stdout: string): Record<string, string> {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Majors `toiljs update` refuses to upgrade into, by package. TypeScript 7 is the native (Go) port:
|
|
55
|
+
* it ships `tsc` but no JavaScript compiler API, which toiljs's route-metadata extractor, the eslint
|
|
56
|
+
* preset, and typedoc all load. Upgrading into it silently stops SEO metadata being baked into the
|
|
57
|
+
* built HTML and hard-crashes typescript-eslint, so the upgrade is withheld until the ecosystem
|
|
58
|
+
* catches up. Bumps *within* the supported major are still offered.
|
|
59
|
+
*/
|
|
60
|
+
export const UNSUPPORTED_MAJOR: Readonly<Record<string, number>> = { typescript: 7 };
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The names ncu wants to upgrade into a major toiljs does not support (see {@link UNSUPPORTED_MAJOR}).
|
|
64
|
+
* These are dropped from the picker and passed to ncu's `--reject`, so `-u` cannot apply them either.
|
|
65
|
+
*/
|
|
66
|
+
export function withheldUpgrades(upgraded: Record<string, string>): string[] {
|
|
67
|
+
return Object.entries(upgraded)
|
|
68
|
+
.filter(([name, to]) => {
|
|
69
|
+
const ceiling = UNSUPPORTED_MAJOR[name];
|
|
70
|
+
return ceiling !== undefined && parseVersion(to)[0] >= ceiling;
|
|
71
|
+
})
|
|
72
|
+
.map(([name]) => name)
|
|
73
|
+
.sort();
|
|
74
|
+
}
|
|
75
|
+
|
|
53
76
|
const SEVERITY: Record<Bump, number> = { major: 0, minor: 1, patch: 2, other: 3 };
|
|
54
77
|
|
|
55
78
|
/**
|
package/src/compiler/index.ts
CHANGED
|
@@ -308,9 +308,18 @@ export async function buildServer(root: string, auth: boolean = false): Promise<
|
|
|
308
308
|
return;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
-
// Default request-only single-artifact path (no daemon/stream surface).
|
|
311
|
+
// Default request-only single-artifact path (no daemon/stream surface). Declare `hot` rather
|
|
312
|
+
// than leaving --targetMode off: with no explicit mode toilscript treats a source tree that
|
|
313
|
+
// declares no surface decorator as a plain AssemblyScript compile and omits `toil.surface`
|
|
314
|
+
// (to keep an ordinary AS build byte-identical). A toiljs server IS a Toil request artifact
|
|
315
|
+
// even before it grows its first `@rest`/`@data`, and the host refuses to load an artifact
|
|
316
|
+
// without that section, so a freshly scaffolded app would never deploy. `hot` is the mode the
|
|
317
|
+
// section already records for the default request artifact, so the bytes are unchanged for a
|
|
318
|
+
// project that has a surface; it only stops the section from going missing for one that
|
|
319
|
+
// doesn't. (`@daemon`/`@scheduled` are the only decorators `hot` rejects, and this branch runs
|
|
320
|
+
// exactly when the tree has neither.)
|
|
312
321
|
await runToilscriptPass(root, binJs, files, {
|
|
313
|
-
mode:
|
|
322
|
+
mode: 'hot',
|
|
314
323
|
outFile: null,
|
|
315
324
|
withRpc: true,
|
|
316
325
|
authUser: authOn,
|
package/src/compiler/pages.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
|
|
4
|
-
import type * as TS from 'typescript';
|
|
5
|
-
|
|
6
|
-
import { extractStaticExports } from './prerender.js';
|
|
1
|
+
import { extractStaticExports, loadTypeScriptSync } from './prerender.js';
|
|
7
2
|
import type { ScannedRoute } from './routes.js';
|
|
8
3
|
|
|
9
|
-
type Ts = typeof TS;
|
|
10
|
-
|
|
11
4
|
/**
|
|
12
5
|
* A page in the build-time search index: its URL pattern, whether it's dynamic, and the
|
|
13
6
|
* statically-extracted `metadata` literal (the searchable subset; dynamic `generateMetadata` and
|
|
@@ -20,20 +13,6 @@ export interface PageIndexEntry {
|
|
|
20
13
|
readonly metadata: Record<string, unknown>;
|
|
21
14
|
}
|
|
22
15
|
|
|
23
|
-
/**
|
|
24
|
-
* Loads the project's TypeScript synchronously (so {@link buildPageIndex} can run inside the sync
|
|
25
|
-
* `generate()`), or `null` if it isn't installed, in which case pages are indexed by path only.
|
|
26
|
-
*/
|
|
27
|
-
function loadTypeScriptSync(root: string): Ts | null {
|
|
28
|
-
try {
|
|
29
|
-
const require = createRequire(path.join(root, 'package.json'));
|
|
30
|
-
const mod = require('typescript') as { default?: Ts } & Ts;
|
|
31
|
-
return mod.default ?? mod;
|
|
32
|
-
} catch {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
16
|
/** True when a route pattern has dynamic (`:param` / `*catch-all`) segments. */
|
|
38
17
|
function isDynamic(pattern: string): boolean {
|
|
39
18
|
return /[:*]/.test(pattern);
|
|
@@ -12,15 +12,69 @@ import { injectSeoHtml, routeSeo } from './seo.js';
|
|
|
12
12
|
|
|
13
13
|
type Ts = typeof TS;
|
|
14
14
|
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* True when `mod` exposes the classic TypeScript compiler API the static extractor drives.
|
|
17
|
+
*
|
|
18
|
+
* Resolving `typescript` is not enough to know it can parse: TypeScript 7 (the native port) moved
|
|
19
|
+
* the compiler API off the package's main entry, which now exports only `version`. That module is a
|
|
20
|
+
* perfectly good object, so a truthy check passes and the first `ts.ScriptTarget.Latest` then dies
|
|
21
|
+
* with `Cannot read properties of undefined (reading 'Latest')`. Probe the members we actually use.
|
|
22
|
+
*/
|
|
23
|
+
function isCompilerApi(mod: unknown): mod is Ts {
|
|
24
|
+
const ts = mod as Partial<Ts> | null | undefined;
|
|
25
|
+
return (
|
|
26
|
+
typeof ts?.createSourceFile === 'function' &&
|
|
27
|
+
typeof ts.isVariableStatement === 'function' &&
|
|
28
|
+
typeof ts.ScriptTarget === 'object' &&
|
|
29
|
+
typeof ts.ScriptKind === 'object' &&
|
|
30
|
+
typeof ts.SyntaxKind === 'object'
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Warn once per process: an unusable TypeScript silently costs baked metadata, so say so. */
|
|
35
|
+
let warnedUnusable = false;
|
|
36
|
+
function warnUnusableTypeScript(mod: unknown): void {
|
|
37
|
+
if (warnedUnusable) return;
|
|
38
|
+
warnedUnusable = true;
|
|
39
|
+
const version = (mod as { version?: string } | null)?.version;
|
|
40
|
+
process.stderr.write(
|
|
41
|
+
` toil: typescript${version ? `@${version}` : ''} does not expose the compiler API ` +
|
|
42
|
+
`(TypeScript 7 moved it to 'typescript/unstable/*').\n` +
|
|
43
|
+
` toil: route metadata will NOT be baked into the built HTML. Install typescript ^6 to restore it.\n`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Resolves the project's TypeScript, used to read each route's static `metadata`. Returns `null`
|
|
49
|
+
* when it isn't installed (callers then index pages by path only) *or* when the resolved version
|
|
50
|
+
* doesn't expose the compiler API, which is warned about rather than crashing the build.
|
|
51
|
+
*/
|
|
16
52
|
export async function loadTypeScript(root: string): Promise<Ts | null> {
|
|
53
|
+
let mod: unknown;
|
|
17
54
|
try {
|
|
18
55
|
const resolved = createRequire(path.join(root, 'package.json')).resolve('typescript');
|
|
19
|
-
const
|
|
20
|
-
|
|
56
|
+
const ns = (await import(pathToFileURL(resolved).href)) as { default?: Ts } & Ts;
|
|
57
|
+
mod = ns.default ?? ns;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
if (isCompilerApi(mod)) return mod;
|
|
62
|
+
warnUnusableTypeScript(mod);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The sync twin of {@link loadTypeScript}, for callers that can't await (e.g. `buildPageIndex`). */
|
|
67
|
+
export function loadTypeScriptSync(root: string): Ts | null {
|
|
68
|
+
let mod: unknown;
|
|
69
|
+
try {
|
|
70
|
+
mod = createRequire(path.join(root, 'package.json'))('typescript');
|
|
21
71
|
} catch {
|
|
22
72
|
return null;
|
|
23
73
|
}
|
|
74
|
+
const ts = (mod as { default?: Ts })?.default ?? mod;
|
|
75
|
+
if (isCompilerApi(ts)) return ts;
|
|
76
|
+
warnUnusableTypeScript(ts);
|
|
77
|
+
return null;
|
|
24
78
|
}
|
|
25
79
|
|
|
26
80
|
/** Marks an AST node that isn't a static literal (so its value can't be baked at build). */
|