@kuratchi/js 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 (65) hide show
  1. package/README.md +135 -68
  2. package/dist/cli.js +80 -47
  3. package/dist/compiler/api-route-pipeline.d.ts +8 -0
  4. package/dist/compiler/api-route-pipeline.js +23 -0
  5. package/dist/compiler/asset-pipeline.d.ts +7 -0
  6. package/dist/compiler/asset-pipeline.js +33 -0
  7. package/dist/compiler/client-module-pipeline.d.ts +25 -0
  8. package/dist/compiler/client-module-pipeline.js +257 -0
  9. package/dist/compiler/compiler-shared.d.ts +55 -0
  10. package/dist/compiler/compiler-shared.js +4 -0
  11. package/dist/compiler/component-pipeline.d.ts +15 -0
  12. package/dist/compiler/component-pipeline.js +163 -0
  13. package/dist/compiler/config-reading.d.ts +11 -0
  14. package/dist/compiler/config-reading.js +323 -0
  15. package/dist/compiler/convention-discovery.d.ts +9 -0
  16. package/dist/compiler/convention-discovery.js +83 -0
  17. package/dist/compiler/durable-object-pipeline.d.ts +9 -0
  18. package/dist/compiler/durable-object-pipeline.js +255 -0
  19. package/dist/compiler/error-page-pipeline.d.ts +1 -0
  20. package/dist/compiler/error-page-pipeline.js +16 -0
  21. package/dist/compiler/import-linking.d.ts +36 -0
  22. package/dist/compiler/import-linking.js +139 -0
  23. package/dist/compiler/index.d.ts +3 -3
  24. package/dist/compiler/index.js +137 -3265
  25. package/dist/compiler/layout-pipeline.d.ts +31 -0
  26. package/dist/compiler/layout-pipeline.js +155 -0
  27. package/dist/compiler/page-route-pipeline.d.ts +16 -0
  28. package/dist/compiler/page-route-pipeline.js +62 -0
  29. package/dist/compiler/parser.d.ts +4 -0
  30. package/dist/compiler/parser.js +433 -51
  31. package/dist/compiler/root-layout-pipeline.d.ts +10 -0
  32. package/dist/compiler/root-layout-pipeline.js +517 -0
  33. package/dist/compiler/route-discovery.d.ts +7 -0
  34. package/dist/compiler/route-discovery.js +87 -0
  35. package/dist/compiler/route-pipeline.d.ts +57 -0
  36. package/dist/compiler/route-pipeline.js +296 -0
  37. package/dist/compiler/route-state-pipeline.d.ts +25 -0
  38. package/dist/compiler/route-state-pipeline.js +139 -0
  39. package/dist/compiler/routes-module-feature-blocks.d.ts +2 -0
  40. package/dist/compiler/routes-module-feature-blocks.js +330 -0
  41. package/dist/compiler/routes-module-pipeline.d.ts +2 -0
  42. package/dist/compiler/routes-module-pipeline.js +6 -0
  43. package/dist/compiler/routes-module-runtime-shell.d.ts +2 -0
  44. package/dist/compiler/routes-module-runtime-shell.js +81 -0
  45. package/dist/compiler/routes-module-types.d.ts +44 -0
  46. package/dist/compiler/routes-module-types.js +1 -0
  47. package/dist/compiler/script-transform.d.ts +16 -0
  48. package/dist/compiler/script-transform.js +218 -0
  49. package/dist/compiler/server-module-pipeline.d.ts +13 -0
  50. package/dist/compiler/server-module-pipeline.js +124 -0
  51. package/dist/compiler/template.d.ts +13 -1
  52. package/dist/compiler/template.js +323 -60
  53. package/dist/compiler/worker-output-pipeline.d.ts +13 -0
  54. package/dist/compiler/worker-output-pipeline.js +37 -0
  55. package/dist/compiler/wrangler-sync.d.ts +14 -0
  56. package/dist/compiler/wrangler-sync.js +185 -0
  57. package/dist/runtime/app.js +15 -3
  58. package/dist/runtime/generated-worker.d.ts +33 -0
  59. package/dist/runtime/generated-worker.js +412 -0
  60. package/dist/runtime/index.d.ts +2 -1
  61. package/dist/runtime/index.js +1 -0
  62. package/dist/runtime/router.d.ts +2 -1
  63. package/dist/runtime/router.js +12 -3
  64. package/dist/runtime/types.d.ts +8 -2
  65. package/package.json +5 -1
@@ -0,0 +1,16 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { compileTemplate } from './template.js';
4
+ export function compileErrorPages(routesDir) {
5
+ const compiledErrorPages = new Map();
6
+ for (const file of fs.readdirSync(routesDir)) {
7
+ const match = file.match(/^(\d{3})\.html$/);
8
+ if (!match)
9
+ continue;
10
+ const status = parseInt(match[1], 10);
11
+ const source = fs.readFileSync(path.join(routesDir, file), 'utf-8');
12
+ const body = compileTemplate(source);
13
+ compiledErrorPages.set(status, `function __error_${status}(error) {\n ${body}\n return __html;\n}`);
14
+ }
15
+ return compiledErrorPages;
16
+ }
@@ -0,0 +1,36 @@
1
+ export interface ImportBinding {
2
+ imported: string;
3
+ local: string;
4
+ }
5
+ export interface ParsedImportStatement {
6
+ bindings: ImportBinding[];
7
+ moduleSpecifier: string | null;
8
+ namespaceImport: string | null;
9
+ }
10
+ export interface RouteImportEntry {
11
+ line: string;
12
+ importerDir: string;
13
+ }
14
+ interface RouteQueryReference {
15
+ fnName: string;
16
+ }
17
+ export declare function parseImportStatement(source: string): ParsedImportStatement;
18
+ export declare function collectReferencedIdentifiers(source: string): Set<string>;
19
+ export declare function parseNamedImportBindings(line: string): ImportBinding[];
20
+ export declare function filterImportsByNeededBindings(imports: string[], neededBindings: Set<string>): string[];
21
+ export declare function linkRouteServerImports(opts: {
22
+ routeServerImportEntries: RouteImportEntry[];
23
+ routeClientImportEntries: RouteImportEntry[];
24
+ actionFunctions: string[];
25
+ pollFunctions: string[];
26
+ dataGetQueries: RouteQueryReference[];
27
+ routeScriptReferenceSource: string;
28
+ resolveCompiledImportPath: (origPath: string, importerDir: string, outFileDir: string) => string;
29
+ outFileDir: string;
30
+ allocateModuleId: () => string;
31
+ }): {
32
+ fnToModule: Record<string, string>;
33
+ routeImportDecls: string[];
34
+ importStatements: string[];
35
+ };
36
+ export {};
@@ -0,0 +1,139 @@
1
+ import ts from 'typescript';
2
+ export function parseImportStatement(source) {
3
+ const sourceFile = ts.createSourceFile('kuratchi-import.ts', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
4
+ const statement = sourceFile.statements.find(ts.isImportDeclaration);
5
+ if (!statement || !ts.isStringLiteral(statement.moduleSpecifier)) {
6
+ return { bindings: [], moduleSpecifier: null, namespaceImport: null };
7
+ }
8
+ const bindings = [];
9
+ let namespaceImport = null;
10
+ const clause = statement.importClause;
11
+ if (clause) {
12
+ if (clause.name) {
13
+ bindings.push({ imported: 'default', local: clause.name.text });
14
+ }
15
+ if (clause.namedBindings) {
16
+ if (ts.isNamedImports(clause.namedBindings)) {
17
+ for (const element of clause.namedBindings.elements) {
18
+ bindings.push({
19
+ imported: element.propertyName?.text || element.name.text,
20
+ local: element.name.text,
21
+ });
22
+ }
23
+ }
24
+ else if (ts.isNamespaceImport(clause.namedBindings)) {
25
+ namespaceImport = clause.namedBindings.name.text;
26
+ }
27
+ }
28
+ }
29
+ return {
30
+ bindings,
31
+ moduleSpecifier: statement.moduleSpecifier.text,
32
+ namespaceImport,
33
+ };
34
+ }
35
+ function isTypePosition(node) {
36
+ for (let current = node; current; current = current.parent) {
37
+ if (ts.isTypeNode(current))
38
+ return true;
39
+ }
40
+ return false;
41
+ }
42
+ function isReferenceIdentifier(node) {
43
+ const parent = node.parent;
44
+ if (!parent)
45
+ return false;
46
+ if (isTypePosition(node))
47
+ return false;
48
+ if (ts.isImportClause(parent) || ts.isImportSpecifier(parent) || ts.isNamespaceImport(parent) || ts.isNamedImports(parent))
49
+ return false;
50
+ if (ts.isExportSpecifier(parent))
51
+ return false;
52
+ if (ts.isBindingElement(parent) || ts.isParameter(parent) || ts.isVariableDeclaration(parent) || ts.isFunctionDeclaration(parent) || ts.isClassDeclaration(parent)) {
53
+ return parent.name !== node;
54
+ }
55
+ if (ts.isPropertyAssignment(parent) && parent.name === node)
56
+ return false;
57
+ if (ts.isShorthandPropertyAssignment(parent) && parent.name === node)
58
+ return true;
59
+ if (ts.isPropertyAccessExpression(parent) && parent.name === node)
60
+ return false;
61
+ if (ts.isQualifiedName(parent) && parent.right === node)
62
+ return false;
63
+ if (ts.isPropertyDeclaration(parent) || ts.isMethodDeclaration(parent) || ts.isGetAccessorDeclaration(parent) || ts.isSetAccessorDeclaration(parent)) {
64
+ return parent.name !== node;
65
+ }
66
+ if (ts.isLabeledStatement(parent) || ts.isBreakStatement(parent) || ts.isContinueStatement(parent))
67
+ return false;
68
+ return true;
69
+ }
70
+ export function collectReferencedIdentifiers(source) {
71
+ const refs = new Set();
72
+ const sourceFile = ts.createSourceFile('kuratchi-ref.ts', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
73
+ const visit = (node) => {
74
+ if (ts.isIdentifier(node) && isReferenceIdentifier(node)) {
75
+ refs.add(node.text);
76
+ }
77
+ ts.forEachChild(node, visit);
78
+ };
79
+ visit(sourceFile);
80
+ return refs;
81
+ }
82
+ export function parseNamedImportBindings(line) {
83
+ return parseImportStatement(line).bindings.filter((binding) => binding.imported !== 'default');
84
+ }
85
+ export function filterImportsByNeededBindings(imports, neededBindings) {
86
+ const selected = [];
87
+ for (const line of imports) {
88
+ const parsed = parseImportStatement(line);
89
+ const hasNeededBinding = parsed.bindings.some((binding) => neededBindings.has(binding.local))
90
+ || (parsed.namespaceImport ? neededBindings.has(parsed.namespaceImport) : false);
91
+ if (hasNeededBinding)
92
+ selected.push(line);
93
+ }
94
+ return selected;
95
+ }
96
+ export function linkRouteServerImports(opts) {
97
+ const fnToModule = {};
98
+ const routeImportDeclMap = new Map();
99
+ const importStatements = [];
100
+ const neededServerFns = new Set([
101
+ ...opts.actionFunctions,
102
+ ...opts.pollFunctions,
103
+ ...opts.dataGetQueries.map((query) => query.fnName),
104
+ ]);
105
+ const routeServerImports = opts.routeServerImportEntries.length > 0
106
+ ? opts.routeServerImportEntries
107
+ : opts.routeClientImportEntries.filter((entry) => (filterImportsByNeededBindings([entry.line], neededServerFns).length > 0));
108
+ for (const entry of routeServerImports) {
109
+ const parsed = parseImportStatement(entry.line);
110
+ if (!parsed.moduleSpecifier)
111
+ continue;
112
+ const isWorkerEnvModule = parsed.moduleSpecifier === 'cloudflare:workers';
113
+ const isKuratchiEnvModule = parsed.moduleSpecifier === '@kuratchi/js/environment';
114
+ const importPath = opts.resolveCompiledImportPath(parsed.moduleSpecifier, entry.importerDir, opts.outFileDir);
115
+ const moduleId = opts.allocateModuleId();
116
+ importStatements.push(`import * as ${moduleId} from '${importPath}';`);
117
+ for (const binding of parsed.bindings) {
118
+ if ((isWorkerEnvModule && binding.imported === 'env') || (isKuratchiEnvModule && binding.imported === 'dev')) {
119
+ continue;
120
+ }
121
+ fnToModule[binding.local] = moduleId;
122
+ if (!routeImportDeclMap.has(binding.local)) {
123
+ const accessExpr = binding.imported === 'default' ? `${moduleId}.default` : `${moduleId}.${binding.imported}`;
124
+ routeImportDeclMap.set(binding.local, `const ${binding.local} = ${accessExpr};`);
125
+ }
126
+ }
127
+ if (parsed.namespaceImport) {
128
+ fnToModule[parsed.namespaceImport] = moduleId;
129
+ if (!routeImportDeclMap.has(parsed.namespaceImport)) {
130
+ routeImportDeclMap.set(parsed.namespaceImport, `const ${parsed.namespaceImport} = ${moduleId};`);
131
+ }
132
+ }
133
+ }
134
+ return {
135
+ fnToModule,
136
+ routeImportDecls: Array.from(routeImportDeclMap.values()),
137
+ importStatements,
138
+ };
139
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Compiler " scans a project's routes/ directory, parses .html files,
2
+ * Compiler ?" scans a project's routes/ directory, parses .html files,
3
3
  * and generates a single Worker entry point.
4
4
  */
5
5
  export { parseFile } from './parser.js';
@@ -27,9 +27,9 @@ export interface CompiledRoute {
27
27
  /**
28
28
  * Compile a project's src/routes/ into .kuratchi/routes.js
29
29
  *
30
- * The generated module exports { app } " an object with a fetch() method
30
+ * The generated module exports { app } ?" an object with a fetch() method
31
31
  * that handles routing, load functions, form actions, and rendering.
32
- * Returns the path to .kuratchi/worker.js the stable wrangler entry point that
32
+ * Returns the path to .kuratchi/worker.js ? the stable wrangler entry point that
33
33
  * re-exports everything from routes.js (default fetch handler + named DO class exports).
34
34
  * No src/index.ts is needed in user projects.
35
35
  */