@shivaedev/build 0.0.0-stage → 0.1.0
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 +9 -0
- package/LICENSE +21 -0
- package/README.md +216 -2
- package/dist/BuildFailure.d.ts +9 -0
- package/dist/BuildFailure.d.ts.map +1 -0
- package/dist/BuildFailure.js +4 -0
- package/dist/BuildFailure.js.map +1 -0
- package/dist/adapters/appTestConfig.d.ts +4 -0
- package/dist/adapters/appTestConfig.d.ts.map +1 -0
- package/dist/adapters/appTestConfig.js +17 -0
- package/dist/adapters/appTestConfig.js.map +1 -0
- package/dist/adapters/appViteConfig.d.ts +26 -0
- package/dist/adapters/appViteConfig.d.ts.map +1 -0
- package/dist/adapters/appViteConfig.js +18 -0
- package/dist/adapters/appViteConfig.js.map +1 -0
- package/dist/adapters/bundleCheck.d.ts +3 -0
- package/dist/adapters/bundleCheck.d.ts.map +1 -0
- package/dist/adapters/bundleCheck.js +53 -0
- package/dist/adapters/bundleCheck.js.map +1 -0
- package/dist/adapters/copiedCode.d.ts +9 -0
- package/dist/adapters/copiedCode.d.ts.map +1 -0
- package/dist/adapters/copiedCode.js +84 -0
- package/dist/adapters/copiedCode.js.map +1 -0
- package/dist/adapters/failuresOf.d.ts +5 -0
- package/dist/adapters/failuresOf.d.ts.map +1 -0
- package/dist/adapters/failuresOf.js +29 -0
- package/dist/adapters/failuresOf.js.map +1 -0
- package/dist/adapters/isReadonlyProperty.d.ts +10 -0
- package/dist/adapters/isReadonlyProperty.d.ts.map +1 -0
- package/dist/adapters/isReadonlyProperty.js +7 -0
- package/dist/adapters/isReadonlyProperty.js.map +1 -0
- package/dist/adapters/moduleCalls.d.ts +10 -0
- package/dist/adapters/moduleCalls.d.ts.map +1 -0
- package/dist/adapters/moduleCalls.js +47 -0
- package/dist/adapters/moduleCalls.js.map +1 -0
- package/dist/adapters/moduleFacts.d.ts +4 -0
- package/dist/adapters/moduleFacts.d.ts.map +1 -0
- package/dist/adapters/moduleFacts.js +63 -0
- package/dist/adapters/moduleFacts.js.map +1 -0
- package/dist/adapters/objectForm.d.ts +8 -0
- package/dist/adapters/objectForm.d.ts.map +1 -0
- package/dist/adapters/objectForm.js +66 -0
- package/dist/adapters/objectForm.js.map +1 -0
- package/dist/adapters/operationFacts.d.ts +10 -0
- package/dist/adapters/operationFacts.d.ts.map +1 -0
- package/dist/adapters/operationFacts.js +72 -0
- package/dist/adapters/operationFacts.js.map +1 -0
- package/dist/adapters/runNode.d.ts +6 -0
- package/dist/adapters/runNode.d.ts.map +1 -0
- package/dist/adapters/runNode.js +14 -0
- package/dist/adapters/runNode.js.map +1 -0
- package/dist/adapters/typeReading.d.ts +15 -0
- package/dist/adapters/typeReading.d.ts.map +1 -0
- package/dist/adapters/typeReading.js +46 -0
- package/dist/adapters/typeReading.js.map +1 -0
- package/dist/adapters/typeScript.d.ts +15 -0
- package/dist/adapters/typeScript.d.ts.map +1 -0
- package/dist/adapters/typeScript.js +81 -0
- package/dist/adapters/typeScript.js.map +1 -0
- package/dist/adapters/unionForm.d.ts +7 -0
- package/dist/adapters/unionForm.d.ts.map +1 -0
- package/dist/adapters/unionForm.js +78 -0
- package/dist/adapters/unionForm.js.map +1 -0
- package/dist/adapters/vitePlugin.d.ts +7 -0
- package/dist/adapters/vitePlugin.d.ts.map +1 -0
- package/dist/adapters/vitePlugin.js +88 -0
- package/dist/adapters/vitePlugin.js.map +1 -0
- package/dist/adapters/vitePort.d.ts +2 -0
- package/dist/adapters/vitePort.d.ts.map +1 -0
- package/dist/adapters/vitePort.js +5 -0
- package/dist/adapters/vitePort.js.map +1 -0
- package/dist/adapters/vitest/setup.d.ts +3 -0
- package/dist/adapters/vitest/setup.d.ts.map +1 -0
- package/dist/adapters/vitest/setup.js +11 -0
- package/dist/adapters/vitest/setup.js.map +1 -0
- package/dist/adapters/wireForm.d.ts +5 -0
- package/dist/adapters/wireForm.d.ts.map +1 -0
- package/dist/adapters/wireForm.js +91 -0
- package/dist/adapters/wireForm.js.map +1 -0
- package/dist/byText.d.ts +2 -0
- package/dist/byText.d.ts.map +1 -0
- package/dist/byText.js +8 -0
- package/dist/byText.js.map +1 -0
- package/dist/cache.d.ts +4 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +19 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/code.d.ts +11 -0
- package/dist/code.d.ts.map +1 -0
- package/dist/code.js +11 -0
- package/dist/code.js.map +1 -0
- package/dist/command.d.ts +6 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +28 -0
- package/dist/command.js.map +1 -0
- package/dist/emit.d.ts +23 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +69 -0
- package/dist/emit.js.map +1 -0
- package/dist/facts.d.ts +92 -0
- package/dist/facts.d.ts.map +1 -0
- package/dist/facts.js +3 -0
- package/dist/facts.js.map +1 -0
- package/dist/files.d.ts +4 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +15 -0
- package/dist/files.js.map +1 -0
- package/dist/formCode.d.ts +6 -0
- package/dist/formCode.d.ts.map +1 -0
- package/dist/formCode.js +46 -0
- package/dist/formCode.js.map +1 -0
- package/dist/generate.d.ts +7 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +69 -0
- package/dist/generate.js.map +1 -0
- package/dist/generateRound.d.ts +14 -0
- package/dist/generateRound.d.ts.map +1 -0
- package/dist/generateRound.js +44 -0
- package/dist/generateRound.js.map +1 -0
- package/dist/importNames.d.ts +7 -0
- package/dist/importNames.d.ts.map +1 -0
- package/dist/importNames.js +57 -0
- package/dist/importNames.js.map +1 -0
- package/dist/inputs.d.ts +15 -0
- package/dist/inputs.d.ts.map +1 -0
- package/dist/inputs.js +64 -0
- package/dist/inputs.js.map +1 -0
- package/dist/ownerOf.d.ts +7 -0
- package/dist/ownerOf.d.ts.map +1 -0
- package/dist/ownerOf.js +30 -0
- package/dist/ownerOf.js.map +1 -0
- package/dist/packageScope.d.ts +13 -0
- package/dist/packageScope.d.ts.map +1 -0
- package/dist/packageScope.js +28 -0
- package/dist/packageScope.js.map +1 -0
- package/dist/plan.d.ts +12 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +115 -0
- package/dist/plan.js.map +1 -0
- package/dist/project.d.ts +11 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +24 -0
- package/dist/project.js.map +1 -0
- package/dist/rejections.d.ts +11 -0
- package/dist/rejections.d.ts.map +1 -0
- package/dist/rejections.js +46 -0
- package/dist/rejections.js.map +1 -0
- package/dist/report.d.ts +22 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +20 -0
- package/dist/report.js.map +1 -0
- package/dist/serverCode.d.ts +20 -0
- package/dist/serverCode.d.ts.map +1 -0
- package/dist/serverCode.js +90 -0
- package/dist/serverCode.js.map +1 -0
- package/dist/settleOrphans.d.ts +5 -0
- package/dist/settleOrphans.d.ts.map +1 -0
- package/dist/settleOrphans.js +43 -0
- package/dist/settleOrphans.js.map +1 -0
- package/dist/specifiers.d.ts +4 -0
- package/dist/specifiers.d.ts.map +1 -0
- package/dist/specifiers.js +52 -0
- package/dist/specifiers.js.map +1 -0
- package/package.json +89 -3
- package/src/BuildFailure.ts +5 -0
- package/src/adapters/appTestConfig.ts +18 -0
- package/src/adapters/appViteConfig.ts +31 -0
- package/src/adapters/bundleCheck.ts +57 -0
- package/src/adapters/copiedCode.ts +103 -0
- package/src/adapters/failuresOf.ts +31 -0
- package/src/adapters/isReadonlyProperty.ts +21 -0
- package/src/adapters/moduleCalls.ts +58 -0
- package/src/adapters/moduleFacts.ts +66 -0
- package/src/adapters/objectForm.ts +74 -0
- package/src/adapters/operationFacts.ts +85 -0
- package/src/adapters/runNode.ts +15 -0
- package/src/adapters/typeReading.ts +63 -0
- package/src/adapters/typeScript.ts +101 -0
- package/src/adapters/unionForm.ts +88 -0
- package/src/adapters/vitePlugin.ts +103 -0
- package/src/adapters/vitePort.ts +5 -0
- package/src/adapters/vitest/setup.ts +12 -0
- package/src/adapters/wireForm.ts +98 -0
- package/src/byText.ts +7 -0
- package/src/cache.ts +28 -0
- package/src/cli.ts +16 -0
- package/src/code.ts +23 -0
- package/src/command.ts +42 -0
- package/src/emit.ts +117 -0
- package/src/facts.ts +70 -0
- package/src/files.ts +19 -0
- package/src/formCode.ts +59 -0
- package/src/generate.ts +86 -0
- package/src/generateRound.ts +60 -0
- package/src/importNames.ts +61 -0
- package/src/inputs.ts +82 -0
- package/src/ownerOf.ts +40 -0
- package/src/packageScope.ts +35 -0
- package/src/plan.ts +138 -0
- package/src/project.ts +30 -0
- package/src/rejections.ts +57 -0
- package/src/report.ts +39 -0
- package/src/serverCode.ts +139 -0
- package/src/settleOrphans.ts +58 -0
- package/src/specifiers.ts +55 -0
package/dist/emit.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { code, joined } from "#code.ts";
|
|
2
|
+
import { importNames } from "#importNames.ts";
|
|
3
|
+
const CLIENT_CONTRACT = {
|
|
4
|
+
name: "clientContract",
|
|
5
|
+
preferred: "clientContract",
|
|
6
|
+
specifier: "@shivaedev/contract/clientContract.ts",
|
|
7
|
+
typeOnly: false,
|
|
8
|
+
};
|
|
9
|
+
const MATCHES = {
|
|
10
|
+
name: "ClientMatchesModule",
|
|
11
|
+
preferred: "ClientMatchesModule",
|
|
12
|
+
specifier: "@shivaedev/contract/clientMatchesModule.ts",
|
|
13
|
+
typeOnly: true,
|
|
14
|
+
};
|
|
15
|
+
const IDENTIFIER = /^[A-Za-z_$][\w$]*$/u;
|
|
16
|
+
const HEADER = /^\/\/ Generated by @shivaedev\/build from (?<source>.+)\. Do not edit or commit this file; run `pnpm generate` to write it again\.$/u;
|
|
17
|
+
function headerOf(source) {
|
|
18
|
+
return `// Generated by @shivaedev/build from ${source}. Do not edit or commit this file; run \`pnpm generate\` to write it again.`;
|
|
19
|
+
}
|
|
20
|
+
// The module a file was generated from, read from its first line, so generate tells its own files from others under src/generated.
|
|
21
|
+
export function generatedFrom(text) {
|
|
22
|
+
return HEADER.exec(text.split("\n", 1)[0] ?? "")?.groups?.source;
|
|
23
|
+
}
|
|
24
|
+
function keyOf(name) {
|
|
25
|
+
return IDENTIFIER.test(name) ? name : JSON.stringify(name);
|
|
26
|
+
}
|
|
27
|
+
export function identifierOf(name) {
|
|
28
|
+
const words = name.split(/[^A-Za-z0-9_$]+/u).filter((word) => word !== "");
|
|
29
|
+
const camel = words.map((word, index) => (index === 0 ? word : `${word.charAt(0).toUpperCase()}${word.slice(1)}`)).join("");
|
|
30
|
+
return /^[0-9]/u.test(camel) || camel === "" ? `_${camel}` : camel;
|
|
31
|
+
}
|
|
32
|
+
function entries(lines) {
|
|
33
|
+
return code("{\n", ...lines.map((line) => code("\t\t", line, ",\n")), "\t}");
|
|
34
|
+
}
|
|
35
|
+
function field(name, value) {
|
|
36
|
+
return value === undefined ? [] : [code(`\t${name}: `, value, ",\n")];
|
|
37
|
+
}
|
|
38
|
+
export function emit(planned) {
|
|
39
|
+
const operations = planned.operations;
|
|
40
|
+
const base = identifierOf(planned.name);
|
|
41
|
+
const wireName = `${base}Wire`;
|
|
42
|
+
const matchName = `${base}MatchModule`;
|
|
43
|
+
const moduleType = { ...planned.module, preferred: `${planned.exportName}Module` };
|
|
44
|
+
function client(kind) {
|
|
45
|
+
const chosen = operations.filter((operation) => operation.kind === kind);
|
|
46
|
+
return chosen.length === 0
|
|
47
|
+
? undefined
|
|
48
|
+
: entries(chosen.map((operation) => operation.members.length === 0
|
|
49
|
+
? code(`${keyOf(operation.name)}: {}`)
|
|
50
|
+
: code(`${keyOf(operation.name)}: { `, joined(operation.members, ", "), " }")));
|
|
51
|
+
}
|
|
52
|
+
const payloads = operations.flatMap((operation) => operation.payload === undefined ? [] : [code(`${keyOf(operation.name)}: `, operation.payload)]);
|
|
53
|
+
const contract = code(...field("commands", client("command")), ...field("keyScope", planned.keyScope), ...field("middleware", planned.middleware), `\tname: ${JSON.stringify(planned.name)},\n`, ...field("payloads", payloads.length === 0 ? undefined : entries(payloads)), ...field("queries", client("query")), ...field("subject", planned.subject), `\twire: ${wireName},\n`);
|
|
54
|
+
const all = code(contract, CLIENT_CONTRACT, MATCHES, moduleType, ...operations.flatMap((operation) => [operation.success, ...operation.rejections.map(([, ref]) => ref)]));
|
|
55
|
+
const names = importNames(all, new Set([wireName, matchName, planned.exportName]));
|
|
56
|
+
const wire = operations.map((operation) => {
|
|
57
|
+
const rejections = operation.rejections.map(([tag, ref]) => (names.local(ref) === tag ? tag : `${keyOf(tag)}: ${names.local(ref)}`));
|
|
58
|
+
const listed = rejections.length === 0 ? "{}" : `{ ${rejections.join(", ")} }`;
|
|
59
|
+
return `\t${keyOf(operation.name)}: { rejections: ${listed}, success: ${names.text(operation.success)} },\n`;
|
|
60
|
+
});
|
|
61
|
+
return [
|
|
62
|
+
`${headerOf(planned.source)}\n`,
|
|
63
|
+
...names.lines.map((line) => `${line}\n`),
|
|
64
|
+
`\nexport const ${wireName} = {\n${wire.join("")}} as const;\n`,
|
|
65
|
+
`\nexport const ${planned.exportName} = ${names.local(CLIENT_CONTRACT)}({\n${names.text(contract)}});\n`,
|
|
66
|
+
`\nexport const ${matchName}: ${names.local(MATCHES)}<typeof ${planned.exportName}, typeof ${names.local(moduleType)}> = true;\n`,
|
|
67
|
+
].join("");
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=emit.js.map
|
package/dist/emit.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../src/emit.ts"],"names":[],"mappings":"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"}
|
package/dist/facts.d.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export interface ImportFact {
|
|
2
|
+
readonly local: string;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly specifier: string;
|
|
5
|
+
readonly target: string | undefined;
|
|
6
|
+
readonly typeOnly: boolean;
|
|
7
|
+
readonly writtenIn: string;
|
|
8
|
+
}
|
|
9
|
+
export type CodePart = string | ImportFact;
|
|
10
|
+
export interface DeclaredClass {
|
|
11
|
+
readonly className: string;
|
|
12
|
+
readonly exportName: string | undefined;
|
|
13
|
+
readonly file: string;
|
|
14
|
+
}
|
|
15
|
+
export type Literal = string | number | boolean;
|
|
16
|
+
export type Primitive = "BigInt" | "Boolean" | "Date" | "DateTimeUtc" | "Null" | "Number" | "String" | "Undefined" | "Void";
|
|
17
|
+
export interface Field {
|
|
18
|
+
readonly form: WireForm;
|
|
19
|
+
readonly mutable: boolean;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly optional: boolean;
|
|
22
|
+
}
|
|
23
|
+
export type WireForm = {
|
|
24
|
+
readonly form: "primitive";
|
|
25
|
+
readonly primitive: Primitive;
|
|
26
|
+
} | {
|
|
27
|
+
readonly form: "literals";
|
|
28
|
+
readonly values: readonly Literal[];
|
|
29
|
+
} | {
|
|
30
|
+
readonly form: "array";
|
|
31
|
+
readonly item: WireForm;
|
|
32
|
+
readonly mutable: boolean;
|
|
33
|
+
} | {
|
|
34
|
+
readonly form: "tuple";
|
|
35
|
+
readonly elements: readonly WireForm[];
|
|
36
|
+
readonly mutable: boolean;
|
|
37
|
+
} | {
|
|
38
|
+
readonly form: "struct";
|
|
39
|
+
readonly fields: readonly Field[];
|
|
40
|
+
} | {
|
|
41
|
+
readonly form: "record";
|
|
42
|
+
readonly value: WireForm;
|
|
43
|
+
readonly mutable: boolean;
|
|
44
|
+
} | {
|
|
45
|
+
readonly form: "union";
|
|
46
|
+
readonly members: readonly WireForm[];
|
|
47
|
+
} | {
|
|
48
|
+
readonly form: "nullOr";
|
|
49
|
+
readonly inner: WireForm;
|
|
50
|
+
} | {
|
|
51
|
+
readonly form: "option";
|
|
52
|
+
readonly inner: WireForm;
|
|
53
|
+
} | {
|
|
54
|
+
readonly form: "class";
|
|
55
|
+
readonly declared: DeclaredClass;
|
|
56
|
+
};
|
|
57
|
+
export type Failure = {
|
|
58
|
+
readonly kind: "retryable";
|
|
59
|
+
} | {
|
|
60
|
+
readonly kind: "class";
|
|
61
|
+
readonly declared: DeclaredClass;
|
|
62
|
+
readonly schema: boolean;
|
|
63
|
+
readonly tag: string;
|
|
64
|
+
} | {
|
|
65
|
+
readonly kind: "unexported";
|
|
66
|
+
readonly tag: string;
|
|
67
|
+
readonly text: string;
|
|
68
|
+
} | {
|
|
69
|
+
readonly kind: "untagged";
|
|
70
|
+
readonly text: string;
|
|
71
|
+
};
|
|
72
|
+
export interface OperationFacts {
|
|
73
|
+
readonly failures: readonly Failure[];
|
|
74
|
+
readonly invalidates: readonly CodePart[] | undefined;
|
|
75
|
+
readonly kind: "command" | "query";
|
|
76
|
+
readonly name: string;
|
|
77
|
+
readonly payload: readonly CodePart[] | undefined;
|
|
78
|
+
readonly reads: readonly CodePart[] | undefined;
|
|
79
|
+
readonly readsCollections: readonly CodePart[] | undefined;
|
|
80
|
+
readonly success: WireForm | undefined;
|
|
81
|
+
}
|
|
82
|
+
export interface ModuleFacts {
|
|
83
|
+
readonly exportName: string;
|
|
84
|
+
readonly file: string;
|
|
85
|
+
readonly keyScope: readonly CodePart[] | undefined;
|
|
86
|
+
readonly middleware: readonly CodePart[] | undefined;
|
|
87
|
+
readonly name: string;
|
|
88
|
+
readonly operations: readonly OperationFacts[];
|
|
89
|
+
readonly refusals: readonly string[];
|
|
90
|
+
readonly subject: readonly CodePart[] | undefined;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=facts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facts.d.ts","sourceRoot":"","sources":["../src/facts.ts"],"names":[],"mappings":"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"}
|
package/dist/facts.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facts.js","sourceRoot":"","sources":["../src/facts.ts"],"names":[],"mappings":"AAAA,2HAA2H"}
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Effect, FileSystem, Option, Path } from "effect";
|
|
2
|
+
export declare const readIfPresent: (file: string) => Effect.Effect<Option.Option<string>, import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
|
|
3
|
+
export declare const writeAtomically: (file: string, text: string) => Effect.Effect<void, import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
|
|
4
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE1D,eAAO,MAAM,aAAa,6HAMxB,CAAC;AAGH,eAAO,MAAM,eAAe,sIAO1B,CAAC"}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Effect, FileSystem, Option, Path } from "effect";
|
|
2
|
+
export const readIfPresent = Effect.fn("Build.readIfPresent")(function* (file) {
|
|
3
|
+
const fs = yield* FileSystem.FileSystem;
|
|
4
|
+
return yield* fs.readFileString(file).pipe(Effect.map(Option.some), Effect.catchReason("PlatformError", "NotFound", () => Effect.succeed(Option.none())));
|
|
5
|
+
});
|
|
6
|
+
// A reader never sees half a file: the text goes to a fresh file beside the target, which then replaces it in one rename.
|
|
7
|
+
export const writeAtomically = Effect.fn("Build.writeAtomically")(function* (file, text) {
|
|
8
|
+
const fs = yield* FileSystem.FileSystem;
|
|
9
|
+
const path = yield* Path.Path;
|
|
10
|
+
yield* fs.makeDirectory(path.dirname(file), { recursive: true });
|
|
11
|
+
const draft = yield* fs.makeTempFile({ directory: path.dirname(file), prefix: `.${path.basename(file)}.` });
|
|
12
|
+
yield* fs.writeFileString(draft, text);
|
|
13
|
+
yield* fs.rename(draft, file);
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE1D,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAY;IACpF,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CACzC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EACvB,MAAM,CAAC,WAAW,CAAC,eAAe,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAU,CAAC,CAAC,CAC5F,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,0HAA0H;AAC1H,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAY,EAAE,IAAY;IACtG,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9B,KAAK,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5G,KAAK,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACvC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Code, type ImportRef } from "#code.ts";
|
|
2
|
+
import type { WireForm } from "#facts.ts";
|
|
3
|
+
export declare function formCode(form: WireForm, classRef: (form: Extract<WireForm, {
|
|
4
|
+
form: "class";
|
|
5
|
+
}>) => ImportRef): Code;
|
|
6
|
+
//# sourceMappingURL=formCode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formCode.d.ts","sourceRoot":"","sources":["../src/formCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAQ,KAAK,SAAS,EAAkB,MAAM,UAAU,CAAC;AAC3E,OAAO,KAAK,EAAS,QAAQ,EAAE,MAAM,WAAW,CAAC;AAmBjD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,KAAK,SAAS,GAAG,IAAI,CAsClH"}
|
package/dist/formCode.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { code, joined, SCHEMA } from "#code.ts";
|
|
2
|
+
const IDENTIFIER = /^[A-Za-z_$][\w$]*$/u;
|
|
3
|
+
function schema(member, ...inner) {
|
|
4
|
+
return inner.length === 0 ? code(SCHEMA, `.${member}`) : code(SCHEMA, `.${member}(`, ...inner, ")");
|
|
5
|
+
}
|
|
6
|
+
function mutableWhen(mutable, inner) {
|
|
7
|
+
return mutable ? schema("mutable", inner) : inner;
|
|
8
|
+
}
|
|
9
|
+
function fieldCode(field, classRef) {
|
|
10
|
+
const value = formCode(field.form, classRef);
|
|
11
|
+
const optional = field.optional ? schema("optionalKey", value) : value;
|
|
12
|
+
const key = IDENTIFIER.test(field.name) ? field.name : JSON.stringify(field.name);
|
|
13
|
+
return code(`${key}: `, field.mutable ? schema("mutableKey", optional) : optional);
|
|
14
|
+
}
|
|
15
|
+
export function formCode(form, classRef) {
|
|
16
|
+
function inner(each) {
|
|
17
|
+
return formCode(each, classRef);
|
|
18
|
+
}
|
|
19
|
+
switch (form.form) {
|
|
20
|
+
case "primitive":
|
|
21
|
+
return schema(form.primitive);
|
|
22
|
+
case "literals":
|
|
23
|
+
return form.values.length === 1
|
|
24
|
+
? schema("Literal", JSON.stringify(form.values[0]))
|
|
25
|
+
: schema("Literals", `[${form.values.map((value) => JSON.stringify(value)).join(", ")}]`);
|
|
26
|
+
case "array":
|
|
27
|
+
return mutableWhen(form.mutable, schema("Array", inner(form.item)));
|
|
28
|
+
case "tuple":
|
|
29
|
+
return mutableWhen(form.mutable, schema("Tuple", "[", joined(form.elements.map(inner), ", "), "]"));
|
|
30
|
+
case "struct":
|
|
31
|
+
return form.fields.length === 0
|
|
32
|
+
? schema("Struct", "{}")
|
|
33
|
+
: schema("Struct", "{ ", joined(form.fields.map((field) => fieldCode(field, classRef)), ", "), " }");
|
|
34
|
+
case "record":
|
|
35
|
+
return schema("Record", schema("String"), ", ", form.mutable ? schema("mutableKey", inner(form.value)) : inner(form.value));
|
|
36
|
+
case "union":
|
|
37
|
+
return schema("Union", "[", joined(form.members.map(inner), ", "), "]");
|
|
38
|
+
case "nullOr":
|
|
39
|
+
return schema("NullOr", inner(form.inner));
|
|
40
|
+
case "option":
|
|
41
|
+
return schema("Option", inner(form.inner));
|
|
42
|
+
case "class":
|
|
43
|
+
return code(classRef(form));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=formCode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formCode.js","sourceRoot":"","sources":["../src/formCode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { GenerateFailed, type GenerateReport } from "#report.ts";
|
|
3
|
+
export interface GenerateOptions {
|
|
4
|
+
readonly check: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const generate: (directory: string, options: GenerateOptions) => Effect.Effect<GenerateReport, import("effect/PlatformError").BadArgument | import("./BuildFailure.ts").BuildFailure | GenerateFailed | import("@shivaedev/heavy-lock/error.ts").HeavyLockError | import("effect/PlatformError").PlatformError | import("effect/Schema").SchemaError, import("effect/crypto/Digest").Digest | import("@shivaedev/heavy-lock/acquire.ts").HeavyLockServices>;
|
|
7
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAU9C,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAiC,MAAM,YAAY,CAAC;AAGhG,MAAM,WAAW,eAAe;IAE/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACxB;AAcD,eAAO,MAAM,QAAQ,6aAuDnB,CAAC"}
|
package/dist/generate.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Effect, Option, Path } from "effect";
|
|
2
|
+
import { withHeavyLock } from "@shivaedev/heavy-lock/withHeavyLock.ts";
|
|
3
|
+
import { deriveModules } from "#adapters/typeScript.ts";
|
|
4
|
+
import { byText } from "#byText.ts";
|
|
5
|
+
import { cachedOutput, recordOutput } from "#cache.ts";
|
|
6
|
+
import { emit } from "#emit.ts";
|
|
7
|
+
import { readIfPresent, writeAtomically } from "#files.ts";
|
|
8
|
+
import { inputKey } from "#inputs.ts";
|
|
9
|
+
import { plan } from "#plan.ts";
|
|
10
|
+
import { moduleFiles, openProject } from "#project.ts";
|
|
11
|
+
import { GenerateFailed, problemOf } from "#report.ts";
|
|
12
|
+
import { settleOrphans } from "#settleOrphans.ts";
|
|
13
|
+
const settle = Effect.fn("Build.settle")(function* (options, output, content, fromCache) {
|
|
14
|
+
const existing = yield* readIfPresent(output);
|
|
15
|
+
if (Option.contains(existing, content)) {
|
|
16
|
+
return fromCache ? "unchanged" : "current";
|
|
17
|
+
}
|
|
18
|
+
if (options.check) {
|
|
19
|
+
return Option.isNone(existing) ? "missing" : "stale";
|
|
20
|
+
}
|
|
21
|
+
yield* writeAtomically(output, content);
|
|
22
|
+
return "written";
|
|
23
|
+
});
|
|
24
|
+
export const generate = Effect.fn("Build.generate")(function* (directory, options) {
|
|
25
|
+
const path = yield* Path.Path;
|
|
26
|
+
const project = yield* openProject(directory);
|
|
27
|
+
const files = yield* moduleFiles(project);
|
|
28
|
+
const refusals = files.flatMap(({ module, underSource }) => underSource
|
|
29
|
+
? []
|
|
30
|
+
: [
|
|
31
|
+
`${path.relative(project.root, module)}: defines a module outside src; move it under src, since its generated file goes to src/generated/<its path under src>`,
|
|
32
|
+
]);
|
|
33
|
+
const placed = files.filter(({ underSource }) => underSource);
|
|
34
|
+
const keyed = yield* Effect.forEach(placed, (file) => Effect.gen(function* () {
|
|
35
|
+
const { files: inputs, key } = yield* inputKey(project, file.module);
|
|
36
|
+
return { ...file, cached: yield* cachedOutput(project.root, file.module, key), inputs, key };
|
|
37
|
+
}));
|
|
38
|
+
const pending = keyed.filter(({ cached }) => Option.isNone(cached));
|
|
39
|
+
const facts = pending.length === 0
|
|
40
|
+
? []
|
|
41
|
+
: yield* withHeavyLock(deriveModules(project.config, pending.map(({ module }) => module)), { command: "shivaedev-build generate" });
|
|
42
|
+
const outcomes = [];
|
|
43
|
+
for (const file of keyed) {
|
|
44
|
+
const relative = { module: path.relative(project.root, file.module), output: path.relative(project.root, file.output) };
|
|
45
|
+
const derived = facts.find((each) => each.file === file.module);
|
|
46
|
+
const planned = derived === undefined ? undefined : yield* plan({ output: file.output, root: project.root }, derived);
|
|
47
|
+
if (planned !== undefined && planned.refusals.length > 0) {
|
|
48
|
+
refusals.push(...planned.refusals);
|
|
49
|
+
outcomes.push({ ...relative, status: "refused" });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const content = Option.getOrElse(file.cached, () => (planned === undefined ? "" : emit(planned.planned)));
|
|
53
|
+
const status = yield* settle(options, file.output, content, Option.isSome(file.cached));
|
|
54
|
+
if (!options.check && Option.isNone(file.cached)) {
|
|
55
|
+
yield* recordOutput(project.root, file.module, file.key, content);
|
|
56
|
+
}
|
|
57
|
+
outcomes.push({ ...relative, status });
|
|
58
|
+
}
|
|
59
|
+
outcomes.push(...(yield* settleOrphans(project, options.check)));
|
|
60
|
+
const inputs = [...new Set(keyed.flatMap((file) => file.inputs))].sort(byText);
|
|
61
|
+
const report = { inputs, modules: outcomes, programBuilt: pending.length > 0 };
|
|
62
|
+
const lines = outcomes.flatMap((outcome) => problemOf(outcome) ?? []);
|
|
63
|
+
if (refusals.length > 0 || lines.length > 0) {
|
|
64
|
+
const problems = [...refusals, ...lines].map((problem) => problem.replaceAll(`${project.root}${path.sep}`, ""));
|
|
65
|
+
return yield* new GenerateFailed({ problems, report });
|
|
66
|
+
}
|
|
67
|
+
return report;
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Effect, FileSystem, Option, Path } from "effect";
|
|
2
|
+
export interface GenerateRound {
|
|
3
|
+
readonly changed: readonly string[];
|
|
4
|
+
readonly inputs: readonly string[];
|
|
5
|
+
readonly outputs: readonly string[];
|
|
6
|
+
readonly refusal: Option.Option<string>;
|
|
7
|
+
}
|
|
8
|
+
export declare const generateRound: (directory: string) => Effect.Effect<GenerateRound, import("effect/PlatformError").BadArgument | import("./BuildFailure.ts").BuildFailure | import("@shivaedev/heavy-lock/error.ts").HeavyLockError | import("effect/PlatformError").PlatformError | import("effect/Schema").SchemaError, import("effect/crypto/Digest").Digest | import("@shivaedev/heavy-lock/acquire.ts").HeavyLockServices>;
|
|
9
|
+
export declare const watchedGeneration: (directory: string) => Effect.Effect<{
|
|
10
|
+
changed: (file: string) => Effect.Effect<Option.Option<GenerateRound>, import("effect/PlatformError").BadArgument | import("./BuildFailure.ts").BuildFailure | import("@shivaedev/heavy-lock/error.ts").HeavyLockError | import("effect/PlatformError").PlatformError | import("effect/Schema").SchemaError, import("effect/crypto/Digest").Digest | import("@shivaedev/heavy-lock/acquire.ts").HeavyLockServices>;
|
|
11
|
+
run: Effect.Effect<GenerateRound, import("effect/PlatformError").BadArgument | import("./BuildFailure.ts").BuildFailure | import("@shivaedev/heavy-lock/error.ts").HeavyLockError | import("effect/PlatformError").PlatformError | import("effect/Schema").SchemaError, import("effect/crypto/Digest").Digest | import("@shivaedev/heavy-lock/acquire.ts").HeavyLockServices>;
|
|
12
|
+
}, import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
|
|
13
|
+
export type WatchedGeneration = Effect.Success<ReturnType<typeof watchedGeneration>>;
|
|
14
|
+
//# sourceMappingURL=generateRound.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateRound.d.ts","sourceRoot":"","sources":["../src/generateRound.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAkB,MAAM,QAAQ,CAAC;AAM1E,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAEpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CACxC;AAaD,eAAO,MAAM,aAAa,iYAOxB,CAAC;AAIH,eAAO,MAAM,iBAAiB;;;mFAqB5B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Effect, FileSystem, Option, Path, Ref, Semaphore } from "effect";
|
|
2
|
+
import { definesModule } from "#adapters/typeScript.ts";
|
|
3
|
+
import { readIfPresent } from "#files.ts";
|
|
4
|
+
import { generate } from "#generate.ts";
|
|
5
|
+
const roundOf = Effect.fn("Build.roundOf")(function* (root, report, refusal) {
|
|
6
|
+
const path = yield* Path.Path;
|
|
7
|
+
const round = {
|
|
8
|
+
changed: report.modules.filter(({ status }) => status === "written" || status === "removed").map(({ output }) => path.join(root, output)),
|
|
9
|
+
inputs: report.inputs,
|
|
10
|
+
outputs: report.modules.map(({ output }) => path.join(root, output)),
|
|
11
|
+
refusal,
|
|
12
|
+
};
|
|
13
|
+
return round;
|
|
14
|
+
});
|
|
15
|
+
export const generateRound = Effect.fn("Build.generateRound")(function* (directory) {
|
|
16
|
+
const fs = yield* FileSystem.FileSystem;
|
|
17
|
+
const root = yield* fs.realPath(directory);
|
|
18
|
+
return yield* generate(root, { check: false }).pipe(Effect.flatMap((report) => roundOf(root, report, Option.none())), Effect.catchTag("GenerateFailed", (failed) => roundOf(root, failed.report, Option.some(failed.problems.join("\n")))));
|
|
19
|
+
});
|
|
20
|
+
// A dev server's generator: one run at a time, and a changed file starts a run only when some module's last run read it or it
|
|
21
|
+
// is a module file under src that no run has seen yet.
|
|
22
|
+
export const watchedGeneration = Effect.fn("Build.watchedGeneration")(function* (directory) {
|
|
23
|
+
const fs = yield* FileSystem.FileSystem;
|
|
24
|
+
const path = yield* Path.Path;
|
|
25
|
+
const root = yield* fs.realPath(directory);
|
|
26
|
+
const sources = `${path.join(root, "src")}${path.sep}`;
|
|
27
|
+
const generated = `${path.join(sources, "generated")}${path.sep}`;
|
|
28
|
+
const inputs = yield* Ref.make(new Set());
|
|
29
|
+
const serial = yield* Semaphore.make(1);
|
|
30
|
+
const run = serial.withPermits(1)(Effect.tap(generateRound(root), (round) => Ref.set(inputs, new Set(round.inputs))));
|
|
31
|
+
const newModule = Effect.fn("Build.newModule")(function* (file) {
|
|
32
|
+
if (!(file.startsWith(sources) && (file.endsWith(".ts") || file.endsWith(".tsx"))) || file.startsWith(generated)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return Option.exists(yield* readIfPresent(file), (text) => definesModule(file, text));
|
|
36
|
+
});
|
|
37
|
+
const changed = Effect.fn("Build.changed")(function* (file) {
|
|
38
|
+
const real = yield* fs.realPath(file).pipe(Effect.catchReason("PlatformError", "NotFound", () => Effect.succeed(file)));
|
|
39
|
+
const known = (yield* Ref.get(inputs)).has(real);
|
|
40
|
+
return known || (yield* newModule(real)) ? Option.some(yield* run) : Option.none();
|
|
41
|
+
});
|
|
42
|
+
return { changed, run };
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=generateRound.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateRound.js","sourceRoot":"","sources":["../src/generateRound.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Code, ImportRef } from "#code.ts";
|
|
2
|
+
export declare function importNames(code: Code, reserved: ReadonlySet<string>): {
|
|
3
|
+
lines: string[];
|
|
4
|
+
local: (ref: ImportRef) => string;
|
|
5
|
+
text: (written: Code) => string;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=importNames.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importNames.d.ts","sourceRoot":"","sources":["../src/importNames.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAyBhD,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC;;iBA0BhD,SAAS;oBAMZ,IAAI;EAErB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { byText } from "#byText.ts";
|
|
2
|
+
function keyOf(ref) {
|
|
3
|
+
return `${ref.specifier}\u0000${ref.name}`;
|
|
4
|
+
}
|
|
5
|
+
function sorted(values) {
|
|
6
|
+
return [...values].sort(byText);
|
|
7
|
+
}
|
|
8
|
+
function importLine(specifier, entries) {
|
|
9
|
+
const named = entries.filter(([ref]) => ref.name !== "*" && ref.name !== "default");
|
|
10
|
+
const whole = entries.filter(([ref]) => ref.name === "*" || ref.name === "default");
|
|
11
|
+
const allTypes = named.every(([, , typeOnly]) => typeOnly);
|
|
12
|
+
const names = named.map(([ref, local, typeOnly]) => {
|
|
13
|
+
const renamed = ref.name === local ? local : `${ref.name} as ${local}`;
|
|
14
|
+
return typeOnly && !allTypes ? `type ${renamed}` : renamed;
|
|
15
|
+
});
|
|
16
|
+
return [
|
|
17
|
+
...(named.length === 0 ? [] : [`import ${allTypes ? "type " : ""}{ ${sorted(names).join(", ")} } from "${specifier}";`]),
|
|
18
|
+
...whole.map(([ref, local, typeOnly]) => `import ${typeOnly ? "type " : ""}${ref.name === "*" ? `* as ${local}` : local} from "${specifier}";`),
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
// Gives every distinct import one local name, so two classes both called NotFound from different files both fit.
|
|
22
|
+
export function importNames(code, reserved) {
|
|
23
|
+
const refs = new Map();
|
|
24
|
+
for (const part of code) {
|
|
25
|
+
if (typeof part !== "string") {
|
|
26
|
+
refs.set(keyOf(part), [...(refs.get(keyOf(part)) ?? []), part]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const taken = new Set(reserved);
|
|
30
|
+
const locals = new Map();
|
|
31
|
+
for (const key of sorted([...refs.keys()])) {
|
|
32
|
+
const preferred = sorted((refs.get(key) ?? []).map((ref) => ref.preferred))[0] ?? "imported";
|
|
33
|
+
let chosen = preferred;
|
|
34
|
+
for (let suffix = 2; taken.has(chosen); suffix += 1) {
|
|
35
|
+
chosen = `${preferred}${suffix}`;
|
|
36
|
+
}
|
|
37
|
+
taken.add(chosen);
|
|
38
|
+
locals.set(key, chosen);
|
|
39
|
+
}
|
|
40
|
+
const bySpecifier = new Map();
|
|
41
|
+
for (const [key, uses] of refs) {
|
|
42
|
+
const [first] = uses;
|
|
43
|
+
if (first !== undefined) {
|
|
44
|
+
const entry = [first, locals.get(key) ?? first.preferred, uses.every((use) => use.typeOnly)];
|
|
45
|
+
bySpecifier.set(first.specifier, [...(bySpecifier.get(first.specifier) ?? []), entry]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function local(ref) {
|
|
49
|
+
return locals.get(keyOf(ref)) ?? ref.preferred;
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
lines: sorted([...bySpecifier.keys()]).flatMap((specifier) => importLine(specifier, bySpecifier.get(specifier) ?? [])),
|
|
53
|
+
local,
|
|
54
|
+
text: (written) => written.map((part) => (typeof part === "string" ? part : local(part))).join(""),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=importNames.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importNames.js","sourceRoot":"","sources":["../src/importNames.ts"],"names":[],"mappings":"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"}
|
package/dist/inputs.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Effect, FileSystem, Path } from "effect";
|
|
2
|
+
import { Digest } from "effect/crypto";
|
|
3
|
+
import { type ProjectConfig } from "#adapters/typeScript.ts";
|
|
4
|
+
export interface Project {
|
|
5
|
+
readonly config: ProjectConfig;
|
|
6
|
+
readonly generated: string;
|
|
7
|
+
readonly generator: string;
|
|
8
|
+
readonly root: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const generatorFingerprint: () => Effect.Effect<string, import("effect/PlatformError").BadArgument | import("effect/PlatformError").PlatformError, Digest.Digest | FileSystem.FileSystem | Path.Path>;
|
|
11
|
+
export declare const inputKey: (project: Project, module: string) => Effect.Effect<{
|
|
12
|
+
files: string[];
|
|
13
|
+
key: string;
|
|
14
|
+
}, import("effect/PlatformError").PlatformError, Digest.Digest | FileSystem.FileSystem | Path.Path>;
|
|
15
|
+
//# sourceMappingURL=inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../src/inputs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAU,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,yBAAyB,CAAC;AAM9E,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAkBD,eAAO,MAAM,oBAAoB,2KAe/B,CAAC;AAkBH,eAAO,MAAM,QAAQ;;;mGAiBnB,CAAC"}
|
package/dist/inputs.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Effect, FileSystem, Option, Path } from "effect";
|
|
2
|
+
import { Digest } from "effect/crypto";
|
|
3
|
+
import { resolvedImports } from "#adapters/typeScript.ts";
|
|
4
|
+
import { byText } from "#byText.ts";
|
|
5
|
+
import packageInfo from "#package.json" with { type: "json" };
|
|
6
|
+
const LOCKFILES = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
7
|
+
const lockfileOf = Effect.fn("Build.lockfileOf")(function* (root) {
|
|
8
|
+
const fs = yield* FileSystem.FileSystem;
|
|
9
|
+
const path = yield* Path.Path;
|
|
10
|
+
for (let directory = root;; directory = path.dirname(directory)) {
|
|
11
|
+
for (const name of LOCKFILES) {
|
|
12
|
+
if (yield* fs.exists(path.join(directory, name))) {
|
|
13
|
+
return Option.some(path.join(directory, name));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (path.dirname(directory) === directory) {
|
|
17
|
+
return Option.none();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
// The generator's own code, so a changed generator rewrites every file even before its version changes.
|
|
22
|
+
export const generatorFingerprint = Effect.fn("Build.generatorFingerprint")(function* () {
|
|
23
|
+
const fs = yield* FileSystem.FileSystem;
|
|
24
|
+
const path = yield* Path.Path;
|
|
25
|
+
const digest = yield* Digest.Digest;
|
|
26
|
+
const directory = yield* path.fromFileUrl(new URL(".", import.meta.url));
|
|
27
|
+
const files = (yield* fs.readDirectory(directory, { recursive: true })).sort();
|
|
28
|
+
const texts = yield* Effect.forEach(files, (file) => Effect.gen(function* () {
|
|
29
|
+
const full = path.join(directory, file);
|
|
30
|
+
const info = yield* fs.stat(full);
|
|
31
|
+
return info.type === "File" ? `${file}\u0000${yield* fs.readFileString(full)}` : "";
|
|
32
|
+
}));
|
|
33
|
+
const version = `@shivaedev/build ${packageInfo.version}`;
|
|
34
|
+
return yield* digest.digestHex(Digest.sha256, new TextEncoder().encode([version, ...texts].join("\u0001")));
|
|
35
|
+
});
|
|
36
|
+
// Installed packages are covered by the lockfile and the generator's output by its own inputs, so the walk stops at both.
|
|
37
|
+
const importGraph = Effect.fn("Build.importGraph")(function* (project, module) {
|
|
38
|
+
const fs = yield* FileSystem.FileSystem;
|
|
39
|
+
const seen = new Map();
|
|
40
|
+
const pending = [module];
|
|
41
|
+
for (let file = pending.pop(); file !== undefined; file = pending.pop()) {
|
|
42
|
+
if (!seen.has(file)) {
|
|
43
|
+
const text = yield* fs.readFileString(file);
|
|
44
|
+
seen.set(file, text);
|
|
45
|
+
const imports = yield* resolvedImports(project.config, file, text);
|
|
46
|
+
pending.push(...imports.filter((imported) => !(imported.includes("/node_modules/") || imported.startsWith(project.generated))));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return seen;
|
|
50
|
+
});
|
|
51
|
+
export const inputKey = Effect.fn("Build.inputKey")(function* (project, module) {
|
|
52
|
+
const fs = yield* FileSystem.FileSystem;
|
|
53
|
+
const path = yield* Path.Path;
|
|
54
|
+
const digest = yield* Digest.Digest;
|
|
55
|
+
const graph = yield* importGraph(project, module);
|
|
56
|
+
const lockfile = yield* lockfileOf(project.root);
|
|
57
|
+
const chain = yield* Effect.forEach([...project.config.chain, ...project.config.declarations], (file) => Effect.map(fs.readFileString(file), (text) => [file, text]));
|
|
58
|
+
const lock = Option.isSome(lockfile) ? [[lockfile.value, yield* fs.readFileString(lockfile.value)]] : [];
|
|
59
|
+
const inputs = [...graph, ...chain, ...lock];
|
|
60
|
+
const entries = inputs.map(([file, text]) => `${path.relative(project.root, file)}\u0000${text}`).sort(byText);
|
|
61
|
+
const key = yield* digest.digestHex(Digest.sha256, new TextEncoder().encode([project.generator, `typescript ${project.config.typeScriptVersion}`, ...entries].join("\u0001")));
|
|
62
|
+
return { files: inputs.map(([file]) => file), key };
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=inputs.js.map
|