@agjs/tsforge 0.5.1 → 0.5.2
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/package.json +1 -1
- package/src/detect-gate.ts +26 -4
package/package.json
CHANGED
package/src/detect-gate.ts
CHANGED
|
@@ -142,6 +142,11 @@ const STRICT_TSCONFIG_OVERLAY = `{
|
|
|
142
142
|
/** The gate overlay's home: tsforge's cache dir + the overlay filename. */
|
|
143
143
|
const GATE_TSCONFIG_DIR = ".tsforge";
|
|
144
144
|
const GATE_TSCONFIG_FILE = "tsconfig.gate.json";
|
|
145
|
+
/** Persistent incremental-typecheck cache (in .tsforge/, git-ignored). Reused
|
|
146
|
+
* across settles so a warm `tsc` only re-checks what changed — tsc stays the
|
|
147
|
+
* authority, just amortized. */
|
|
148
|
+
const GATE_TSBUILDINFO_FILE = "gate.tsbuildinfo";
|
|
149
|
+
const INCREMENTAL_FLAGS = `--incremental --tsBuildInfoFile ${GATE_TSCONFIG_DIR}/${GATE_TSBUILDINFO_FILE}`;
|
|
145
150
|
|
|
146
151
|
// The web-stack scaffolds (Vite + React full-kit, or Vite vanilla) live in the
|
|
147
152
|
// registry; this module just lays them down and builds their gate. shadcn/TanStack
|
|
@@ -780,7 +785,7 @@ async function tscPart(cwd: string): Promise<string | null> {
|
|
|
780
785
|
);
|
|
781
786
|
await ignoreGateArtifact(cwd);
|
|
782
787
|
|
|
783
|
-
return `"${TSC_BIN}" --noEmit -p ${GATE_TSCONFIG_DIR}/${GATE_TSCONFIG_FILE}`;
|
|
788
|
+
return `"${TSC_BIN}" --noEmit ${INCREMENTAL_FLAGS} -p ${GATE_TSCONFIG_DIR}/${GATE_TSCONFIG_FILE}`;
|
|
784
789
|
}
|
|
785
790
|
|
|
786
791
|
// Greenfield: bring a strict tsconfig so tsc can gate — but only when this is
|
|
@@ -788,8 +793,11 @@ async function tscPart(cwd: string): Promise<string | null> {
|
|
|
788
793
|
// Unlike the overlay, a greenfield tsconfig.json is a DURABLE project file.
|
|
789
794
|
if (await Bun.file(join(cwd, "package.json")).exists()) {
|
|
790
795
|
await Bun.write(join(cwd, "tsconfig.json"), STRICT_TSCONFIG);
|
|
796
|
+
// The buildinfo lives in .tsforge/ (git-ignored), NOT next to the durable
|
|
797
|
+
// tsconfig — so incremental never leaks a cache file into the user's tree.
|
|
798
|
+
await ignoreGateArtifact(cwd);
|
|
791
799
|
|
|
792
|
-
return `"${TSC_BIN}" --noEmit -p tsconfig.json`;
|
|
800
|
+
return `"${TSC_BIN}" --noEmit ${INCREMENTAL_FLAGS} -p tsconfig.json`;
|
|
793
801
|
}
|
|
794
802
|
|
|
795
803
|
return null;
|
|
@@ -801,12 +809,26 @@ async function tscPart(cwd: string): Promise<string | null> {
|
|
|
801
809
|
* that intentionally tracks rules.json) is never clobbered. */
|
|
802
810
|
async function ignoreGateArtifact(cwd: string): Promise<void> {
|
|
803
811
|
const ignore = join(cwd, GATE_TSCONFIG_DIR, ".gitignore");
|
|
812
|
+
const entries = [GATE_TSCONFIG_FILE, GATE_TSBUILDINFO_FILE];
|
|
813
|
+
const file = Bun.file(ignore);
|
|
814
|
+
|
|
815
|
+
if (!(await file.exists())) {
|
|
816
|
+
await Bun.write(ignore, `${entries.join("\n")}\n`);
|
|
804
817
|
|
|
805
|
-
if (await Bun.file(ignore).exists()) {
|
|
806
818
|
return;
|
|
807
819
|
}
|
|
808
820
|
|
|
809
|
-
|
|
821
|
+
// Exists (maybe a user's, or an older tsforge one without the buildinfo line):
|
|
822
|
+
// append only the missing entries so we never clobber what's there.
|
|
823
|
+
const current = await file.text();
|
|
824
|
+
const missing = entries.filter((e) => !current.split("\n").includes(e));
|
|
825
|
+
|
|
826
|
+
if (missing.length > 0) {
|
|
827
|
+
await Bun.write(
|
|
828
|
+
ignore,
|
|
829
|
+
`${current.replace(/\n*$/u, "\n")}${missing.join("\n")}\n`
|
|
830
|
+
);
|
|
831
|
+
}
|
|
810
832
|
}
|
|
811
833
|
|
|
812
834
|
/** The syntactic idiom layer — ALWAYS tsforge's bundled strict eslint config
|