toiljs 0.0.14 → 0.0.16

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 (225) hide show
  1. package/.babelrc +13 -13
  2. package/.gitattributes +2 -2
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +90 -90
  5. package/.github/ISSUE_TEMPLATE/config.yml +8 -8
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  7. package/.github/PULL_REQUEST_TEMPLATE.md +43 -43
  8. package/.github/changelog-config.json +45 -45
  9. package/.github/dependabot.yml +27 -27
  10. package/.github/workflows/ci.yml +191 -191
  11. package/.prettierrc.json +11 -11
  12. package/.vscode/settings.json +9 -9
  13. package/CHANGELOG.md +5 -5
  14. package/LICENSE +187 -187
  15. package/README.md +339 -315
  16. package/as-pect.asconfig.json +34 -34
  17. package/as-pect.config.js +65 -65
  18. package/assets/logo.svg +36 -36
  19. package/build/backend/.tsbuildinfo +1 -1
  20. package/build/cli/.tsbuildinfo +1 -1
  21. package/build/cli/index.js +2926 -191
  22. package/build/client/.tsbuildinfo +1 -1
  23. package/build/client/dev/devtools.d.ts +6 -0
  24. package/build/client/dev/devtools.js +442 -0
  25. package/build/client/dev/error-overlay.d.ts +9 -0
  26. package/build/client/dev/error-overlay.js +19 -4
  27. package/build/client/head/metadata.d.ts +3 -1
  28. package/build/client/head/metadata.js +8 -0
  29. package/build/client/index.d.ts +4 -4
  30. package/build/client/index.js +2 -2
  31. package/build/client/navigation/navigation.d.ts +2 -0
  32. package/build/client/navigation/navigation.js +9 -1
  33. package/build/client/navigation/prefetch.d.ts +1 -0
  34. package/build/client/navigation/prefetch.js +35 -0
  35. package/build/client/routing/Router.js +1 -1
  36. package/build/client/routing/hooks.js +6 -2
  37. package/build/client/routing/loader.d.ts +25 -0
  38. package/build/client/routing/loader.js +53 -7
  39. package/build/client/routing/mount.js +4 -3
  40. package/build/compiler/.tsbuildinfo +1 -1
  41. package/build/compiler/config.d.ts +18 -0
  42. package/build/compiler/config.js +8 -0
  43. package/build/compiler/docs.js +16 -16
  44. package/build/compiler/generate.js +3 -0
  45. package/build/compiler/index.d.ts +2 -2
  46. package/build/compiler/index.js +3 -1
  47. package/build/compiler/plugin.js +156 -0
  48. package/build/compiler/prerender.d.ts +1 -0
  49. package/build/compiler/prerender.js +2 -1
  50. package/build/compiler/seo.d.ts +2 -2
  51. package/build/compiler/seo.js +8 -6
  52. package/build/compiler/ssg.d.ts +5 -0
  53. package/build/compiler/ssg.js +121 -0
  54. package/build/io/.tsbuildinfo +1 -1
  55. package/build/logger/.tsbuildinfo +1 -1
  56. package/build/shared/.tsbuildinfo +1 -1
  57. package/eslint.config.js +48 -48
  58. package/examples/basic/client/404.tsx +11 -11
  59. package/examples/basic/client/components/.gitkeep +1 -1
  60. package/examples/basic/client/global-error.tsx +13 -13
  61. package/examples/basic/client/layout.tsx +25 -25
  62. package/examples/basic/client/public/images/.gitkeep +1 -1
  63. package/examples/basic/client/public/images/logo.svg +36 -36
  64. package/examples/basic/client/public/robots.txt +2 -2
  65. package/examples/basic/client/routes/docs/[...slug].tsx +12 -12
  66. package/examples/basic/client/routes/features/error/error.tsx +16 -16
  67. package/examples/basic/client/routes/features/template/b.tsx +14 -14
  68. package/examples/basic/client/routes/files/[[...slug]].tsx +21 -21
  69. package/examples/basic/client/routes/gallery/layout.tsx +13 -13
  70. package/examples/basic/client/routes/io.tsx +24 -24
  71. package/examples/basic/client/routes/loader-demo/loading.tsx +13 -13
  72. package/examples/basic/client/routes/search.tsx +61 -61
  73. package/examples/basic/client/toil.tsx +5 -5
  74. package/package.json +155 -147
  75. package/presets/eslint.js +88 -88
  76. package/presets/no-uint8array-tostring.js +200 -200
  77. package/presets/prettier.json +18 -18
  78. package/presets/tsconfig.json +37 -37
  79. package/src/backend/index.ts +160 -160
  80. package/src/cli/proc.ts +50 -50
  81. package/src/cli/updates.ts +69 -69
  82. package/src/cli/validate.ts +31 -31
  83. package/src/client/channel/channel.ts +146 -146
  84. package/src/client/components/Form.tsx +65 -65
  85. package/src/client/components/Script.tsx +113 -113
  86. package/src/client/components/Slot.tsx +21 -21
  87. package/src/client/dev/devtools.tsx +973 -0
  88. package/src/client/dev/error-overlay.tsx +30 -4
  89. package/src/client/head/head.ts +167 -167
  90. package/src/client/head/metadata.ts +19 -1
  91. package/src/client/index.ts +19 -9
  92. package/src/client/navigation/NavLink.tsx +86 -86
  93. package/src/client/navigation/navigation.ts +25 -5
  94. package/src/client/navigation/prefetch.ts +169 -130
  95. package/src/client/navigation/scroll.ts +53 -53
  96. package/src/client/routing/Router.tsx +8 -2
  97. package/src/client/routing/action.ts +122 -122
  98. package/src/client/routing/error-boundary.tsx +43 -43
  99. package/src/client/routing/hooks.ts +21 -6
  100. package/src/client/routing/loader.ts +325 -225
  101. package/src/client/routing/match.ts +47 -47
  102. package/src/client/routing/mount.tsx +54 -52
  103. package/src/client/routing/params-context.ts +10 -10
  104. package/src/client/routing/slot-context.ts +7 -7
  105. package/src/client/search/search.ts +189 -189
  106. package/src/client/search/use-page-search.ts +73 -73
  107. package/src/client/types.ts +73 -73
  108. package/src/compiler/config.ts +47 -1
  109. package/src/compiler/docs.ts +228 -228
  110. package/src/compiler/generate.ts +394 -391
  111. package/src/compiler/index.ts +64 -54
  112. package/src/compiler/pages.ts +70 -70
  113. package/src/compiler/plugin.ts +170 -2
  114. package/src/compiler/prerender.ts +5 -1
  115. package/src/compiler/seo.ts +23 -7
  116. package/src/compiler/ssg.ts +162 -0
  117. package/src/io/BinaryReader.ts +340 -340
  118. package/src/io/BinaryWriter.ts +385 -385
  119. package/src/io/FastMap.ts +127 -127
  120. package/src/io/index.ts +11 -11
  121. package/src/io/lengths.ts +14 -14
  122. package/src/io/types.ts +18 -18
  123. package/src/logger/index.ts +22 -22
  124. package/src/server/index.ts +10 -10
  125. package/src/server/main.ts +13 -13
  126. package/src/server/tsconfig.json +4 -4
  127. package/src/shared/index.ts +10 -10
  128. package/std/client/index.d.ts +15 -15
  129. package/std/client/package.json +3 -3
  130. package/test/assembly/example.spec.ts +7 -7
  131. package/test/channel.test.ts +21 -21
  132. package/test/dom/Link.test.tsx +47 -47
  133. package/test/dom/NavLink.test.tsx +37 -37
  134. package/test/dom/error-overlay.test.tsx +44 -44
  135. package/test/dom/loader.test.tsx +121 -121
  136. package/test/dom/navigation.test.ts +59 -59
  137. package/test/dom/revalidate.test.tsx +38 -38
  138. package/test/dom/route-head.test.tsx +78 -78
  139. package/test/dom/router-loading.test.tsx +44 -44
  140. package/test/dom/scroll.test.ts +56 -56
  141. package/test/dom/use-metadata.test.tsx +58 -0
  142. package/test/io.test.ts +93 -93
  143. package/test/navlink.test.ts +28 -28
  144. package/test/placeholder.test.ts +9 -9
  145. package/test/routes.test.ts +76 -76
  146. package/test/seo.test.ts +175 -164
  147. package/test/slot-layouts.test.ts +69 -69
  148. package/test/ssg.test.ts +36 -0
  149. package/test/update.test.ts +44 -44
  150. package/test/validate.test.ts +42 -42
  151. package/toil-routes.d.ts +7 -0
  152. package/toilconfig.json +30 -30
  153. package/tsconfig.backend.json +13 -13
  154. package/tsconfig.base.json +35 -35
  155. package/tsconfig.cli.json +13 -13
  156. package/tsconfig.client.json +14 -14
  157. package/tsconfig.compiler.json +13 -13
  158. package/tsconfig.io.json +12 -12
  159. package/tsconfig.json +22 -22
  160. package/tsconfig.logger.json +12 -12
  161. package/tsconfig.server.json +10 -10
  162. package/tsconfig.shared.json +12 -12
  163. package/vitest.config.ts +26 -26
  164. package/.idea/codeStyles/Project.xml +0 -54
  165. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  166. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  167. package/.idea/modules.xml +0 -8
  168. package/.idea/prettier.xml +0 -7
  169. package/.idea/toiljs.iml +0 -8
  170. package/.idea/vcs.xml +0 -6
  171. package/.toil/entry.tsx +0 -9
  172. package/.toil/index.html +0 -12
  173. package/.toil/routes.ts +0 -9
  174. package/build/cli/configure.d.ts +0 -16
  175. package/build/cli/configure.js +0 -272
  176. package/build/cli/create.d.ts +0 -16
  177. package/build/cli/create.js +0 -420
  178. package/build/cli/diagnostics.d.ts +0 -55
  179. package/build/cli/diagnostics.js +0 -333
  180. package/build/cli/doctor.d.ts +0 -6
  181. package/build/cli/doctor.js +0 -249
  182. package/build/cli/features.d.ts +0 -25
  183. package/build/cli/features.js +0 -107
  184. package/build/cli/index.d.ts +0 -2
  185. package/build/cli/proc.d.ts +0 -6
  186. package/build/cli/proc.js +0 -31
  187. package/build/cli/ui.d.ts +0 -9
  188. package/build/cli/ui.js +0 -75
  189. package/build/cli/update.d.ts +0 -7
  190. package/build/cli/update.js +0 -117
  191. package/build/cli/updates.d.ts +0 -10
  192. package/build/cli/updates.js +0 -45
  193. package/build/cli/validate.d.ts +0 -4
  194. package/build/cli/validate.js +0 -19
  195. package/build/client/Link.d.ts +0 -8
  196. package/build/client/Link.js +0 -44
  197. package/build/client/NavLink.d.ts +0 -14
  198. package/build/client/NavLink.js +0 -37
  199. package/build/client/Router.d.ts +0 -7
  200. package/build/client/Router.js +0 -55
  201. package/build/client/channel.d.ts +0 -23
  202. package/build/client/channel.js +0 -94
  203. package/build/client/error-boundary.d.ts +0 -16
  204. package/build/client/error-boundary.js +0 -19
  205. package/build/client/head.d.ts +0 -26
  206. package/build/client/head.js +0 -87
  207. package/build/client/hooks.d.ts +0 -17
  208. package/build/client/hooks.js +0 -48
  209. package/build/client/lazy.d.ts +0 -16
  210. package/build/client/lazy.js +0 -53
  211. package/build/client/match.d.ts +0 -2
  212. package/build/client/match.js +0 -32
  213. package/build/client/mount.d.ts +0 -2
  214. package/build/client/mount.js +0 -13
  215. package/build/client/navigation.d.ts +0 -13
  216. package/build/client/navigation.js +0 -97
  217. package/build/client/params-context.d.ts +0 -2
  218. package/build/client/params-context.js +0 -2
  219. package/build/client/prefetch.d.ts +0 -11
  220. package/build/client/prefetch.js +0 -100
  221. package/build/client/runtime.d.ts +0 -31
  222. package/build/client/runtime.js +0 -112
  223. package/build/client/scroll.d.ts +0 -8
  224. package/build/client/scroll.js +0 -36
  225. package/toil-env.d.ts +0 -16
@@ -1,107 +0,0 @@
1
- export const PREPROCESSORS = ['css', 'sass', 'less', 'stylus'];
2
- export const STYLE_EXT = {
3
- css: 'css',
4
- sass: 'scss',
5
- less: 'less',
6
- stylus: 'styl',
7
- };
8
- export const PREPROCESSOR_PKG = {
9
- css: null,
10
- sass: 'sass',
11
- less: 'less',
12
- stylus: 'stylus',
13
- };
14
- export const TAILWIND_PKGS = ['tailwindcss', '@tailwindcss/vite'];
15
- export const PKG_VERSION = {
16
- sass: '^1.83.0',
17
- less: '^4.2.1',
18
- stylus: '^0.64.0',
19
- tailwindcss: '^4.0.0',
20
- '@tailwindcss/vite': '^4.0.0',
21
- };
22
- export const TAILWIND_ENTRY = 'styles/tailwind.css';
23
- export const TAILWIND_CSS = `@import 'tailwindcss';\n`;
24
- export function styleEntry(p) {
25
- return `styles/main.${STYLE_EXT[p]}`;
26
- }
27
- export function preprocessorForExt(ext) {
28
- const e = ext.replace(/^\./, '');
29
- if (e === 'sass')
30
- return 'sass';
31
- return PREPROCESSORS.find((p) => STYLE_EXT[p] === e) ?? null;
32
- }
33
- export function requiredPackages(f) {
34
- const pkgs = [];
35
- const pp = PREPROCESSOR_PKG[f.preprocessor];
36
- if (pp)
37
- pkgs.push(pp);
38
- if (f.tailwind)
39
- pkgs.push(...TAILWIND_PKGS);
40
- return pkgs;
41
- }
42
- export function packageDiff(from, to) {
43
- const want = new Set(requiredPackages(to));
44
- const had = new Set(requiredPackages(from));
45
- return {
46
- add: [...want].filter((p) => !had.has(p)),
47
- remove: [...had].filter((p) => !want.has(p)),
48
- };
49
- }
50
- export function styleImportLines(f) {
51
- const lines = [];
52
- if (f.tailwind)
53
- lines.push(`import './${TAILWIND_ENTRY}';`);
54
- lines.push(`import './${styleEntry(f.preprocessor)}';`);
55
- return lines;
56
- }
57
- export function setStyleImports(source, f) {
58
- const stripped = source.replace(/^[ \t]*import\s+['"]\.\/styles\/[^'"]+['"];?[ \t]*\r?\n/gm, '');
59
- const block = styleImportLines(f).join('\n') + '\n';
60
- const lines = stripped.split('\n');
61
- const routesIdx = lines.findIndex((l) => /from\s+['"]toiljs\/routes['"]/.test(l));
62
- let insertAt;
63
- if (routesIdx !== -1) {
64
- insertAt = routesIdx + 1;
65
- }
66
- else {
67
- const lastImport = lines.reduce((acc, l, i) => (/^\s*import\s/.test(l) ? i : acc), -1);
68
- insertAt = lastImport + 1;
69
- }
70
- const head = lines.slice(0, insertAt).join('\n');
71
- const tail = lines.slice(insertAt).join('\n');
72
- return `${head}\n\n${block}\n${tail}`.replace(/\n{3,}/g, '\n\n');
73
- }
74
- export function defaultConfigSource(images) {
75
- return ("import { defineConfig } from 'toiljs/compiler';\n\n" +
76
- 'export default defineConfig({\n' +
77
- ' client: {\n' +
78
- ' // Optimize images at build time (resize/compress imported images).\n' +
79
- ` images: ${String(images)},\n` +
80
- ' },\n' +
81
- '});\n');
82
- }
83
- export function setConfigImages(source, enabled) {
84
- const value = String(enabled);
85
- if (/\bimages\s*:\s*(?:true|false)/.test(source)) {
86
- return source.replace(/\bimages\s*:\s*(?:true|false)/, `images: ${value}`);
87
- }
88
- if (/\bclient\s*:\s*\{/.test(source)) {
89
- return source.replace(/\bclient\s*:\s*\{/, `client: {\n images: ${value},`);
90
- }
91
- if (/defineConfig\(\s*\{/.test(source)) {
92
- return source.replace(/defineConfig\(\s*\{/, `defineConfig({\n client: { images: ${value} },`);
93
- }
94
- return null;
95
- }
96
- export function detectPreprocessor(deps) {
97
- if ('sass' in deps)
98
- return 'sass';
99
- if ('less' in deps)
100
- return 'less';
101
- if ('stylus' in deps)
102
- return 'stylus';
103
- return 'css';
104
- }
105
- export function detectTailwind(deps) {
106
- return '@tailwindcss/vite' in deps || 'tailwindcss' in deps;
107
- }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
@@ -1,6 +0,0 @@
1
- export declare function run(cmd: string, args: string[], cwd: string): Promise<void>;
2
- export declare function capture(cmd: string, args: string[], cwd: string): Promise<{
3
- stdout: string;
4
- stderr: string;
5
- code: number;
6
- }>;
package/build/cli/proc.js DELETED
@@ -1,31 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- export function run(cmd, args, cwd) {
3
- return new Promise((resolve, reject) => {
4
- const onWindows = process.platform === 'win32';
5
- const child = onWindows
6
- ? spawn([cmd, ...args].join(' '), { cwd, stdio: 'ignore', shell: true })
7
- : spawn(cmd, args, { cwd, stdio: 'ignore' });
8
- child.on('error', reject);
9
- child.on('close', (code) => code === 0 ? resolve() : reject(new Error(`${cmd} exited with code ${String(code)}`)));
10
- });
11
- }
12
- export function capture(cmd, args, cwd) {
13
- return new Promise((resolve, reject) => {
14
- const onWindows = process.platform === 'win32';
15
- const child = onWindows
16
- ? spawn([cmd, ...args].join(' '), { cwd, shell: true })
17
- : spawn(cmd, args, { cwd });
18
- let stdout = '';
19
- let stderr = '';
20
- child.stdout?.on('data', (d) => {
21
- stdout += d.toString();
22
- });
23
- child.stderr?.on('data', (d) => {
24
- stderr += d.toString();
25
- });
26
- child.on('error', reject);
27
- child.on('close', (code) => {
28
- resolve({ stdout, stderr, code: code ?? 1 });
29
- });
30
- });
31
- }
package/build/cli/ui.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export declare const dim: import("picocolors/types").Formatter;
2
- export declare const bold: import("picocolors/types").Formatter;
3
- export declare function brand(s: string): string;
4
- export declare const accent: typeof brand;
5
- export declare function success(s: string): string;
6
- export declare const danger: import("picocolors/types").Formatter;
7
- export declare const warn: import("picocolors/types").Formatter;
8
- export declare function version(): string;
9
- export declare function banner(): void;
package/build/cli/ui.js DELETED
@@ -1,75 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- import pc from 'picocolors';
5
- const PRIMARY = [37, 99, 255];
6
- const SECONDARY = [124, 58, 237];
7
- const ACCENT = [34, 227, 171];
8
- const GRADIENT = [PRIMARY, SECONDARY, ACCENT];
9
- const ART = [
10
- '████████╗ ██████╗ ██╗ ██╗ ',
11
- '╚══██╔══╝ ██╔═══██╗ ██║ ██║ ',
12
- ' ██║ ██║ ██║ ██║ ██║ ',
13
- ' ██║ ██║ ██║ ██║ ██║ ',
14
- ' ██║ ╚██████╔╝ ██║ ███████╗',
15
- ' ╚═╝ ╚═════╝ ╚═╝ ╚══════╝',
16
- ];
17
- export const dim = pc.dim;
18
- export const bold = pc.bold;
19
- function colorEnabled() {
20
- if (process.env.NO_COLOR)
21
- return false;
22
- if (process.env.FORCE_COLOR)
23
- return true;
24
- return process.stdout.isTTY;
25
- }
26
- function rgb(color, s) {
27
- return colorEnabled() ? `\x1b[38;2;${color[0]};${color[1]};${color[2]}m${s}\x1b[39m` : s;
28
- }
29
- export function brand(s) {
30
- return rgb(PRIMARY, s);
31
- }
32
- export const accent = brand;
33
- export function success(s) {
34
- return rgb(ACCENT, s);
35
- }
36
- export const danger = pc.red;
37
- export const warn = pc.yellow;
38
- function lerp(a, b, t) {
39
- return Math.round(a + (b - a) * t);
40
- }
41
- function gradientAt(t) {
42
- const segments = GRADIENT.length - 1;
43
- const scaled = t * segments;
44
- const i = Math.min(Math.floor(scaled), segments - 1);
45
- const a = GRADIENT[i];
46
- const b = GRADIENT[i + 1];
47
- const localT = scaled - i;
48
- return [lerp(a[0], b[0], localT), lerp(a[1], b[1], localT), lerp(a[2], b[2], localT)];
49
- }
50
- function gradientLine(line) {
51
- const n = line.length;
52
- let out = '';
53
- for (let i = 0; i < n; i++) {
54
- const [r, g, b] = gradientAt(n > 1 ? i / (n - 1) : 0);
55
- out += `\x1b[38;2;${r};${g};${b}m${line[i]}`;
56
- }
57
- return out + '\x1b[39m';
58
- }
59
- export function version() {
60
- try {
61
- const pkgPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'package.json');
62
- const raw = fs.readFileSync(pkgPath, 'utf8');
63
- const match = /"version"\s*:\s*"([^"]+)"/.exec(raw);
64
- if (match && match[1])
65
- return match[1];
66
- }
67
- catch { }
68
- return '0.0.0';
69
- }
70
- export function banner() {
71
- const lines = colorEnabled() ? ART.map(gradientLine) : ART.slice();
72
- const tagline = ` the most performant ${brand('react')} framework`;
73
- const ver = `${dim(' v')}${brand(version())}`;
74
- process.stdout.write('\n' + lines.join('\n') + '\n\n' + tagline + ' ' + ver + '\n\n');
75
- }
@@ -1,7 +0,0 @@
1
- export interface UpdateOptions {
2
- readonly root?: string;
3
- readonly cwd: string;
4
- readonly yes?: boolean;
5
- readonly target?: string;
6
- }
7
- export declare function runUpdate(opts: UpdateOptions): Promise<void>;
@@ -1,117 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { cancel, intro, isCancel, multiselect, note, outro, spinner } from '@clack/prompts';
4
- import { capture, run } from './proc.js';
5
- import { buildRows, parseNcuJson } from './updates.js';
6
- import { accent, danger, dim, success, warn } from './ui.js';
7
- function detectPackageManager(root) {
8
- if (fs.existsSync(path.join(root, 'pnpm-lock.yaml')))
9
- return { name: 'pnpm', ncuName: 'pnpm' };
10
- if (fs.existsSync(path.join(root, 'yarn.lock')))
11
- return { name: 'yarn', ncuName: 'yarn' };
12
- if (fs.existsSync(path.join(root, 'bun.lockb')))
13
- return { name: 'bun', ncuName: 'bun' };
14
- return { name: 'npm', ncuName: 'npm' };
15
- }
16
- function readDependencies(pkgPath) {
17
- const parsed = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
18
- if (typeof parsed !== 'object' || parsed === null)
19
- return {};
20
- const pkg = parsed;
21
- const merge = (v) => {
22
- if (typeof v !== 'object' || v === null)
23
- return {};
24
- const out = {};
25
- for (const [k, val] of Object.entries(v))
26
- if (typeof val === 'string')
27
- out[k] = val;
28
- return out;
29
- };
30
- return { ...merge(pkg.dependencies), ...merge(pkg.devDependencies) };
31
- }
32
- function bumpColor(bump, text) {
33
- if (bump === 'major')
34
- return danger(text);
35
- if (bump === 'minor')
36
- return warn(text);
37
- if (bump === 'patch')
38
- return success(text);
39
- return dim(text);
40
- }
41
- function rowLine(row) {
42
- return `${row.name} ${dim(row.from)} ${dim('->')} ${bumpColor(row.bump, row.to)}`;
43
- }
44
- const TARGETS = new Set(['latest', 'minor', 'patch', 'newest', 'greatest']);
45
- export async function runUpdate(opts) {
46
- const root = path.resolve(opts.root ?? opts.cwd);
47
- const pkgPath = path.join(root, 'package.json');
48
- if (!fs.existsSync(pkgPath)) {
49
- throw new Error('No package.json here. Run from your project root or pass --root <dir>.');
50
- }
51
- const currentDeps = readDependencies(pkgPath);
52
- const pm = detectPackageManager(root);
53
- const target = opts.target && TARGETS.has(opts.target) ? opts.target : 'latest';
54
- const ncuArgs = (extra) => [
55
- '--yes',
56
- 'npm-check-updates',
57
- '--packageManager',
58
- pm.ncuName,
59
- '--target',
60
- target,
61
- ...extra,
62
- ];
63
- intro(accent('toiljs update'));
64
- const s = spinner();
65
- s.start('Checking the registry for updates');
66
- const res = await capture('npx', ncuArgs(['--jsonUpgraded']), root);
67
- if (res.code !== 0 && res.stdout.indexOf('{') === -1) {
68
- s.stop('Could not check for updates');
69
- note(dim(res.stderr.trim() || 'npm-check-updates failed.'), 'Error');
70
- process.exitCode = 1;
71
- return;
72
- }
73
- const rows = buildRows(parseNcuJson(res.stdout), currentDeps);
74
- if (rows.length === 0) {
75
- s.stop('Everything is up to date');
76
- outro(success('Nothing to update.'));
77
- return;
78
- }
79
- s.stop(`${String(rows.length)} update${rows.length === 1 ? '' : 's'} available`);
80
- const counts = { major: 0, minor: 0, patch: 0, other: 0 };
81
- for (const r of rows)
82
- counts[r.bump]++;
83
- note(rows.map(rowLine).join('\n'), `${danger(`${String(counts.major)} major`)} ${warn(`${String(counts.minor)} minor`)} ${success(`${String(counts.patch)} patch`)}`);
84
- let selected;
85
- if (opts.yes) {
86
- selected = rows.map((r) => r.name);
87
- }
88
- else {
89
- const answer = await multiselect({
90
- message: 'Select packages to update (space to toggle, enter to confirm)',
91
- options: rows.map((r) => ({
92
- value: r.name,
93
- label: r.name,
94
- hint: `${r.from} -> ${r.to}`,
95
- })),
96
- initialValues: rows.map((r) => r.name),
97
- required: false,
98
- });
99
- if (isCancel(answer)) {
100
- cancel('Update cancelled.');
101
- return;
102
- }
103
- selected = answer;
104
- }
105
- if (selected.length === 0) {
106
- outro(dim('No packages selected.'));
107
- return;
108
- }
109
- s.start('Updating package.json');
110
- const applyAll = selected.length === rows.length;
111
- await run('npx', ncuArgs(applyAll ? ['-u'] : ['-u', '--filter', selected.join(' ')]), root);
112
- s.stop('package.json updated');
113
- s.start(`Installing with ${pm.name}`);
114
- await run(pm.name, ['install'], root);
115
- s.stop('Dependencies installed');
116
- outro(success(`Updated ${String(selected.length)} package${selected.length === 1 ? '' : 's'}.`));
117
- }
@@ -1,10 +0,0 @@
1
- export type Bump = 'major' | 'minor' | 'patch' | 'other';
2
- export interface UpdateRow {
3
- readonly name: string;
4
- readonly from: string;
5
- readonly to: string;
6
- readonly bump: Bump;
7
- }
8
- export declare function classifyBump(from: string, to: string): Bump;
9
- export declare function parseNcuJson(stdout: string): Record<string, string>;
10
- export declare function buildRows(upgraded: Record<string, string>, currentDeps: Record<string, string>): UpdateRow[];
@@ -1,45 +0,0 @@
1
- function parseVersion(v) {
2
- const m = /(\d+)(?:\.(\d+))?(?:\.(\d+))?/.exec(v);
3
- if (!m)
4
- return [0, 0, 0];
5
- return [Number(m[1]), Number(m[2] ?? 0), Number(m[3] ?? 0)];
6
- }
7
- export function classifyBump(from, to) {
8
- const [fa, fb, fc] = parseVersion(from);
9
- const [ta, tb, tc] = parseVersion(to);
10
- if (ta !== fa)
11
- return 'major';
12
- if (tb !== fb)
13
- return 'minor';
14
- if (tc !== fc)
15
- return 'patch';
16
- return 'other';
17
- }
18
- export function parseNcuJson(stdout) {
19
- const start = stdout.indexOf('{');
20
- const end = stdout.lastIndexOf('}');
21
- if (start === -1 || end <= start)
22
- return {};
23
- try {
24
- const parsed = JSON.parse(stdout.slice(start, end + 1));
25
- if (typeof parsed !== 'object' || parsed === null)
26
- return {};
27
- const out = {};
28
- for (const [k, v] of Object.entries(parsed))
29
- if (typeof v === 'string')
30
- out[k] = v;
31
- return out;
32
- }
33
- catch {
34
- return {};
35
- }
36
- }
37
- const SEVERITY = { major: 0, minor: 1, patch: 2, other: 3 };
38
- export function buildRows(upgraded, currentDeps) {
39
- return Object.entries(upgraded)
40
- .map(([name, to]) => {
41
- const from = currentDeps[name] ?? '?';
42
- return { name, from, to, bump: classifyBump(from, to) };
43
- })
44
- .sort((a, b) => SEVERITY[a.bump] - SEVERITY[b.bump] || a.name.localeCompare(b.name));
45
- }
@@ -1,4 +0,0 @@
1
- export declare const PACKAGE_MANAGERS: string[];
2
- export declare function isValidName(name: string): true | string;
3
- export declare function resolveProjectDir(cwd: string, name: string): string | null;
4
- export declare function isPackageManager(pm: string): boolean;
@@ -1,19 +0,0 @@
1
- import path from 'node:path';
2
- export const PACKAGE_MANAGERS = ['npm', 'pnpm', 'yarn', 'bun'];
3
- export function isValidName(name) {
4
- if (!name.trim())
5
- return 'Please enter a project name.';
6
- if (!/^[a-z0-9._@/-]+$/i.test(name))
7
- return 'Use letters, numbers, dashes, dots or slashes.';
8
- return true;
9
- }
10
- export function resolveProjectDir(cwd, name) {
11
- const target = path.resolve(cwd, name);
12
- const rel = path.relative(cwd, target);
13
- if (rel.startsWith('..') || path.isAbsolute(rel))
14
- return null;
15
- return target;
16
- }
17
- export function isPackageManager(pm) {
18
- return PACKAGE_MANAGERS.includes(pm);
19
- }
@@ -1,8 +0,0 @@
1
- import type { ComponentPropsWithRef, ReactNode } from 'react';
2
- export interface LinkProps extends Omit<ComponentPropsWithRef<'a'>, 'href'> {
3
- href: string;
4
- replace?: boolean;
5
- scroll?: boolean;
6
- prefetch?: boolean;
7
- }
8
- export declare function Link(props: LinkProps): ReactNode;
@@ -1,44 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { navigate } from './navigation.js';
3
- import { prefetch } from './prefetch.js';
4
- function isExternalHref(href) {
5
- try {
6
- return new URL(href, window.location.href).origin !== window.location.origin;
7
- }
8
- catch {
9
- return true;
10
- }
11
- }
12
- export function Link(props) {
13
- const { href, replace = false, scroll = true, prefetch: prefetchProp = true, onClick, onPointerEnter, onFocus, children, ...rest } = props;
14
- const handleClick = (event) => {
15
- onClick?.(event);
16
- if (event.defaultPrevented ||
17
- event.button !== 0 ||
18
- event.metaKey ||
19
- event.ctrlKey ||
20
- event.shiftKey ||
21
- event.altKey ||
22
- (rest.target !== undefined && rest.target !== '_self') ||
23
- rest.download !== undefined ||
24
- href.startsWith('#') ||
25
- isExternalHref(href)) {
26
- return;
27
- }
28
- event.preventDefault();
29
- navigate(href, { replace, scroll });
30
- };
31
- const warm = () => {
32
- if (prefetchProp)
33
- prefetch(href);
34
- };
35
- const handlePointerEnter = (event) => {
36
- onPointerEnter?.(event);
37
- warm();
38
- };
39
- const handleFocus = (event) => {
40
- onFocus?.(event);
41
- warm();
42
- };
43
- return (_jsx("a", { ...rest, ...(prefetchProp ? {} : { 'data-no-prefetch': '' }), href: href, onClick: handleClick, onPointerEnter: handlePointerEnter, onFocus: handleFocus, children: children }));
44
- }
@@ -1,14 +0,0 @@
1
- import type { CSSProperties, ReactNode } from 'react';
2
- import { type LinkProps } from './Link.js';
3
- export interface NavLinkState {
4
- readonly isActive: boolean;
5
- }
6
- export interface NavLinkProps extends Omit<LinkProps, 'className' | 'style' | 'children'> {
7
- className?: string | ((state: NavLinkState) => string | undefined);
8
- style?: CSSProperties | ((state: NavLinkState) => CSSProperties | undefined);
9
- children?: ReactNode | ((state: NavLinkState) => ReactNode);
10
- end?: boolean;
11
- activeClassName?: string;
12
- }
13
- export declare function matchActive(linkPath: string, currentPath: string, end: boolean): boolean;
14
- export declare function NavLink(props: NavLinkProps): ReactNode;
@@ -1,37 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useLocation } from './hooks.js';
3
- import { Link } from './Link.js';
4
- function normalizePath(p) {
5
- return p.length > 1 ? p.replace(/\/+$/, '') : p;
6
- }
7
- export function matchActive(linkPath, currentPath, end) {
8
- const link = normalizePath(linkPath);
9
- const current = normalizePath(currentPath);
10
- if (current === link)
11
- return true;
12
- if (end)
13
- return false;
14
- if (link === '/')
15
- return true;
16
- return current.startsWith(link + '/');
17
- }
18
- export function NavLink(props) {
19
- const { href, className, style, children, end = false, activeClassName = 'active', ...rest } = props;
20
- const pathname = useLocation();
21
- let linkPath = href;
22
- try {
23
- linkPath = new URL(href, window.location.href).pathname;
24
- }
25
- catch {
26
- linkPath = href;
27
- }
28
- const isActive = matchActive(linkPath, pathname, end);
29
- const state = { isActive };
30
- const resolvedClassName = typeof className === 'function'
31
- ? className(state)
32
- : [className, isActive ? activeClassName : undefined].filter(Boolean).join(' ') ||
33
- undefined;
34
- const resolvedStyle = typeof style === 'function' ? style(state) : style;
35
- const resolvedChildren = typeof children === 'function' ? children(state) : children;
36
- return (_jsx(Link, { ...rest, href: href, className: resolvedClassName, style: resolvedStyle, "aria-current": isActive ? 'page' : undefined, children: resolvedChildren }));
37
- }
@@ -1,7 +0,0 @@
1
- import { type ReactNode } from 'react';
2
- import type { LayoutLoader, NotFoundLoader, RouteDef } from './types.js';
3
- export declare function Router(props: {
4
- routes: RouteDef[];
5
- layout?: LayoutLoader;
6
- notFound?: NotFoundLoader;
7
- }): ReactNode;
@@ -1,55 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createElement, Suspense, useLayoutEffect } from 'react';
3
- import { ErrorBoundary } from './error-boundary.js';
4
- import { useLocation } from './hooks.js';
5
- import { errorComponent, loadingComponent, nestedLayout, pageComponent, resolveLayout, resolveNotFound, } from './lazy.js';
6
- import { matchRoute } from './match.js';
7
- import { ParamsContext } from './params-context.js';
8
- import { settleNavigation } from './navigation.js';
9
- import { applyScroll } from './scroll.js';
10
- export function Router(props) {
11
- const { routes, layout = null, notFound = null } = props;
12
- const pathname = useLocation();
13
- useLayoutEffect(() => {
14
- applyScroll();
15
- settleNavigation();
16
- });
17
- let matched;
18
- let params = {};
19
- for (const route of routes) {
20
- const result = matchRoute(route.pattern, pathname);
21
- if (result) {
22
- matched = route;
23
- params = result;
24
- break;
25
- }
26
- }
27
- let content;
28
- if (matched) {
29
- const Page = pageComponent(matched);
30
- const fallback = matched.loading
31
- ? createElement(Suspense, { fallback: null }, createElement(loadingComponent(matched.loading)))
32
- : null;
33
- content = (_jsx(Suspense, { fallback: fallback, children: _jsx(Page, {}) }));
34
- const chain = matched.layouts ?? [];
35
- for (let i = chain.length - 1; i >= 0; i--) {
36
- const NestedLayout = nestedLayout(chain[i]);
37
- content = (_jsx(Suspense, { fallback: null, children: _jsx(NestedLayout, { children: content }) }));
38
- }
39
- if (matched.errorComponent) {
40
- content = (_jsx(ErrorBoundary, { fallback: errorComponent(matched.errorComponent), children: content }));
41
- }
42
- }
43
- else if (notFound) {
44
- const NotFound = resolveNotFound(notFound);
45
- content = (_jsx(Suspense, { fallback: null, children: _jsx(NotFound, {}) }));
46
- }
47
- else {
48
- content = _jsx("div", { style: { padding: 24, fontFamily: 'system-ui' }, children: "404 \u2014 Not found" });
49
- }
50
- if (layout) {
51
- const Layout = resolveLayout(layout);
52
- content = (_jsx(Suspense, { fallback: null, children: _jsx(Layout, { children: content }) }));
53
- }
54
- return _jsx(ParamsContext.Provider, { value: params, children: content });
55
- }
@@ -1,23 +0,0 @@
1
- export type ChannelData = string | ArrayBuffer;
2
- export type SendData = Parameters<WebSocket['send']>[0];
3
- export interface ChannelOptions {
4
- readonly path?: string;
5
- readonly url?: string;
6
- readonly reconnect?: boolean;
7
- readonly reconnectDelay?: number;
8
- }
9
- export interface Channel {
10
- send(data: SendData): void;
11
- close(): void;
12
- }
13
- export declare function resolveChannelUrl(path?: string, location?: {
14
- protocol: string;
15
- host: string;
16
- }): string;
17
- export declare function connectChannel(onMessage: (data: ChannelData) => void, options?: ChannelOptions): Channel;
18
- export interface ChannelHook {
19
- readonly connected: boolean;
20
- readonly messages: ChannelData[];
21
- send: (data: SendData) => void;
22
- }
23
- export declare function useChannel(options?: ChannelOptions): ChannelHook;