@bluewombat/integrator 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.
Files changed (51) hide show
  1. package/README.md +92 -0
  2. package/SPECS.md +381 -0
  3. package/dist/args/parse-args.d.ts +6 -0
  4. package/dist/args/parse-args.d.ts.map +1 -0
  5. package/dist/args/parse-args.js +222 -0
  6. package/dist/args/parse-args.js.map +1 -0
  7. package/dist/child/run-child.d.ts +41 -0
  8. package/dist/child/run-child.d.ts.map +1 -0
  9. package/dist/child/run-child.js +145 -0
  10. package/dist/child/run-child.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +99 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/fold/backend.d.ts +32 -0
  16. package/dist/fold/backend.d.ts.map +1 -0
  17. package/dist/fold/backend.js +2 -0
  18. package/dist/fold/backend.js.map +1 -0
  19. package/dist/fold/fold.d.ts +32 -0
  20. package/dist/fold/fold.d.ts.map +1 -0
  21. package/dist/fold/fold.js +49 -0
  22. package/dist/fold/fold.js.map +1 -0
  23. package/dist/fold/working-files.d.ts +28 -0
  24. package/dist/fold/working-files.d.ts.map +1 -0
  25. package/dist/fold/working-files.js +122 -0
  26. package/dist/fold/working-files.js.map +1 -0
  27. package/dist/index.d.ts +17 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +12 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/progress/emit.d.ts +5 -0
  32. package/dist/progress/emit.d.ts.map +1 -0
  33. package/dist/progress/emit.js +17 -0
  34. package/dist/progress/emit.js.map +1 -0
  35. package/dist/run/run-integrator.d.ts +35 -0
  36. package/dist/run/run-integrator.d.ts.map +1 -0
  37. package/dist/run/run-integrator.js +172 -0
  38. package/dist/run/run-integrator.js.map +1 -0
  39. package/dist/status/announce.d.ts +14 -0
  40. package/dist/status/announce.d.ts.map +1 -0
  41. package/dist/status/announce.js +28 -0
  42. package/dist/status/announce.js.map +1 -0
  43. package/dist/status/make-status.d.ts +7 -0
  44. package/dist/status/make-status.d.ts.map +1 -0
  45. package/dist/status/make-status.js +19 -0
  46. package/dist/status/make-status.js.map +1 -0
  47. package/dist/types.d.ts +32 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +3 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +46 -0
@@ -0,0 +1,49 @@
1
+ import { removeSnapshot, restoreWorkingFiles, snapshotWorkingFiles, } from "./working-files.js";
2
+ /**
3
+ * Fold Child working files into Parent through the injected backend.
4
+ * Parent is restored unless the fold completes.
5
+ */
6
+ export async function fold(input) {
7
+ const { parent, child, backend, id, subject, mergeSubject, deadlineMs, now, shouldInterrupt } = input;
8
+ const backup = await snapshotWorkingFiles(parent);
9
+ const shouldStop = () => {
10
+ if (shouldInterrupt()) {
11
+ return "interrupt";
12
+ }
13
+ if (now() >= deadlineMs) {
14
+ return "clock";
15
+ }
16
+ return undefined;
17
+ };
18
+ const fail = async (result) => {
19
+ await restoreWorkingFiles(parent, backup);
20
+ await removeSnapshot(backup);
21
+ return result;
22
+ };
23
+ try {
24
+ const result = await backend.fold({
25
+ parent,
26
+ child,
27
+ ...(id === undefined ? {} : { id }),
28
+ ...(subject === undefined ? {} : { subject }),
29
+ ...(mergeSubject === undefined ? {} : { mergeSubject }),
30
+ deadlineMs,
31
+ now,
32
+ shouldInterrupt,
33
+ shouldStop,
34
+ });
35
+ if (result.ok) {
36
+ await removeSnapshot(backup);
37
+ return result;
38
+ }
39
+ return fail(result);
40
+ }
41
+ catch (error) {
42
+ const detail = error instanceof Error ? error.message : String(error);
43
+ return fail({
44
+ ok: false,
45
+ detail: `Integration could not complete: ${detail}`,
46
+ });
47
+ }
48
+ }
49
+ //# sourceMappingURL=fold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.js","sourceRoot":"","sources":["../../src/fold/fold.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,cAAc,EACd,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAQ5B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,KAW1B;IACC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,eAAe,EAAE,GAC3F,KAAK,CAAC;IACR,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAElD,MAAM,UAAU,GAAG,GAAyB,EAAE;QAC5C,IAAI,eAAe,EAAE,EAAE,CAAC;YACtB,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,IAAI,GAAG,EAAE,IAAI,UAAU,EAAE,CAAC;YACxB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,KAAK,EAAE,MAAkB,EAAuB,EAAE;QAC7D,MAAM,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,MAAM;YACN,KAAK;YACL,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;YACnC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7C,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC;YACvD,UAAU;YACV,GAAG;YACH,eAAe;YACf,UAAU;SACX,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;YAC7B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;YACV,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,mCAAmC,MAAM,EAAE;SACpD,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ export type FoldStop = "clock" | "interrupt";
2
+ export type PathKind = "file" | "directory" | "symlink" | "missing";
3
+ export declare class IntegrationStoppedError extends Error {
4
+ readonly stop: FoldStop;
5
+ constructor(stop: FoldStop);
6
+ }
7
+ export declare function throwIfStopped(shouldStop: () => FoldStop | undefined): Promise<void>;
8
+ export declare function direntKind(entry: {
9
+ isSymbolicLink(): boolean;
10
+ isDirectory(): boolean;
11
+ isFile(): boolean;
12
+ }): PathKind | "other";
13
+ export declare function pathKind(path: string): Promise<PathKind | "other">;
14
+ /**
15
+ * Copy working files from `from` into an existing `to` directory.
16
+ * Skips `.git` only at the root of `from` when `skipGitAtRoot` is set.
17
+ */
18
+ export declare function copyWorkingFiles(input: {
19
+ from: string;
20
+ to: string;
21
+ skipGitAtRoot: boolean;
22
+ shouldStop: () => FoldStop | undefined;
23
+ }): Promise<void>;
24
+ export declare function wipeWorkingFiles(directory: string, shouldStop: () => FoldStop | undefined): Promise<void>;
25
+ export declare function snapshotWorkingFiles(directory: string): Promise<string>;
26
+ export declare function restoreWorkingFiles(directory: string, backup: string): Promise<void>;
27
+ export declare function removeSnapshot(backup: string): Promise<void>;
28
+ //# sourceMappingURL=working-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"working-files.d.ts","sourceRoot":"","sources":["../../src/fold/working-files.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,WAAW,CAAC;AAE7C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpE,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;gBAEZ,IAAI,EAAE,QAAQ;CAS3B;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1F;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,cAAc,IAAI,OAAO,CAAC;IAC1B,WAAW,IAAI,OAAO,CAAC;IACvB,MAAM,IAAI,OAAO,CAAC;CACnB,GAAG,QAAQ,GAAG,OAAO,CAWrB;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,CAmBxE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAC;CACxC,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhB;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,QAAQ,GAAG,SAAS,GACrC,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS7E;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ1F;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAElE"}
@@ -0,0 +1,122 @@
1
+ import { copyFile, lstat, mkdir, mkdtemp, readdir, readlink, rm, symlink } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ export class IntegrationStoppedError extends Error {
5
+ stop;
6
+ constructor(stop) {
7
+ super(stop === "clock"
8
+ ? "The Integration clock fired."
9
+ : "A stop signal arrived before Integration completed.");
10
+ this.name = "IntegrationStoppedError";
11
+ this.stop = stop;
12
+ }
13
+ }
14
+ export async function throwIfStopped(shouldStop) {
15
+ const stop = shouldStop();
16
+ if (stop !== undefined) {
17
+ throw new IntegrationStoppedError(stop);
18
+ }
19
+ }
20
+ export function direntKind(entry) {
21
+ if (entry.isSymbolicLink()) {
22
+ return "symlink";
23
+ }
24
+ if (entry.isDirectory()) {
25
+ return "directory";
26
+ }
27
+ if (entry.isFile()) {
28
+ return "file";
29
+ }
30
+ return "other";
31
+ }
32
+ export async function pathKind(path) {
33
+ try {
34
+ const stats = await lstat(path);
35
+ if (stats.isSymbolicLink()) {
36
+ return "symlink";
37
+ }
38
+ if (stats.isDirectory()) {
39
+ return "directory";
40
+ }
41
+ if (stats.isFile()) {
42
+ return "file";
43
+ }
44
+ return "other";
45
+ }
46
+ catch (error) {
47
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
48
+ return "missing";
49
+ }
50
+ throw error;
51
+ }
52
+ }
53
+ /**
54
+ * Copy working files from `from` into an existing `to` directory.
55
+ * Skips `.git` only at the root of `from` when `skipGitAtRoot` is set.
56
+ */
57
+ export async function copyWorkingFiles(input) {
58
+ await copyDir(input.from, input.to, true, input.skipGitAtRoot, input.shouldStop);
59
+ }
60
+ export async function wipeWorkingFiles(directory, shouldStop) {
61
+ await throwIfStopped(shouldStop);
62
+ const entries = await readdir(directory);
63
+ for (const name of entries) {
64
+ await throwIfStopped(shouldStop);
65
+ if (name === ".git") {
66
+ continue;
67
+ }
68
+ await rm(join(directory, name), { recursive: true, force: true });
69
+ }
70
+ }
71
+ export async function snapshotWorkingFiles(directory) {
72
+ const backup = await mkdtemp(join(tmpdir(), "integrator-parent-"));
73
+ await copyWorkingFiles({
74
+ from: directory,
75
+ to: backup,
76
+ skipGitAtRoot: true,
77
+ shouldStop: () => undefined,
78
+ });
79
+ return backup;
80
+ }
81
+ export async function restoreWorkingFiles(directory, backup) {
82
+ await wipeWorkingFiles(directory, () => undefined);
83
+ await copyWorkingFiles({
84
+ from: backup,
85
+ to: directory,
86
+ skipGitAtRoot: true,
87
+ shouldStop: () => undefined,
88
+ });
89
+ }
90
+ export async function removeSnapshot(backup) {
91
+ await rm(backup, { recursive: true, force: true });
92
+ }
93
+ async function copyDir(from, to, isRoot, skipGitAtRoot, shouldStop) {
94
+ await throwIfStopped(shouldStop);
95
+ if (!isRoot) {
96
+ await mkdir(to);
97
+ }
98
+ const entries = await readdir(from, { withFileTypes: true });
99
+ for (const entry of entries) {
100
+ await throwIfStopped(shouldStop);
101
+ if (isRoot && skipGitAtRoot && entry.name === ".git") {
102
+ continue;
103
+ }
104
+ const src = join(from, entry.name);
105
+ const dest = join(to, entry.name);
106
+ if (entry.isDirectory()) {
107
+ await copyDir(src, dest, false, false, shouldStop);
108
+ continue;
109
+ }
110
+ if (entry.isSymbolicLink()) {
111
+ const target = await readlink(src);
112
+ await symlink(target, dest);
113
+ continue;
114
+ }
115
+ if (entry.isFile()) {
116
+ await copyFile(src, dest);
117
+ continue;
118
+ }
119
+ throw new Error(`Cannot fold "${src}": unsupported file type.`);
120
+ }
121
+ }
122
+ //# sourceMappingURL=working-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"working-files.js","sourceRoot":"","sources":["../../src/fold/working-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Import entry point for this Transformer.
3
+ *
4
+ * The Transformer is a function. `cli.ts` is a thin adapter over this surface: it
5
+ * reads argv and stdin, calls runIntegrator, and maps the outcome to an exit code.
6
+ * Everything a caller needs in process is reachable from here.
7
+ *
8
+ * Isolation strategies (git, copy, …) live under `packages/plugins/isolation-*`.
9
+ */
10
+ export type { FoldBackend } from "./fold/backend.js";
11
+ export type { FoldStop } from "./fold/working-files.js";
12
+ export { IntegrationStoppedError, throwIfStopped } from "./fold/working-files.js";
13
+ export type { ProgressWriter } from "./progress/emit.js";
14
+ export type { RunOptions, RunResult } from "./run/run-integrator.js";
15
+ export { runIntegrator } from "./run/run-integrator.js";
16
+ export type * from "./types.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAClF,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,mBAAmB,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Import entry point for this Transformer.
3
+ *
4
+ * The Transformer is a function. `cli.ts` is a thin adapter over this surface: it
5
+ * reads argv and stdin, calls runIntegrator, and maps the outcome to an exit code.
6
+ * Everything a caller needs in process is reachable from here.
7
+ *
8
+ * Isolation strategies (git, copy, …) live under `packages/plugins/isolation-*`.
9
+ */
10
+ export { IntegrationStoppedError, throwIfStopped } from "./fold/working-files.js";
11
+ export { runIntegrator } from "./run/run-integrator.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGlF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Status } from "../types.js";
2
+ export type ProgressWriter = (line: Record<string, unknown>) => void;
3
+ export declare function createStdoutProgressWriter(): ProgressWriter;
4
+ export declare function emitStatusEvent(write: ProgressWriter, status: Status): void;
5
+ //# sourceMappingURL=emit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/progress/emit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAErE,wBAAgB,0BAA0B,IAAI,cAAc,CAI3D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAU3E"}
@@ -0,0 +1,17 @@
1
+ export function createStdoutProgressWriter() {
2
+ return (line) => {
3
+ process.stdout.write(`${JSON.stringify(line)}\n`);
4
+ };
5
+ }
6
+ export function emitStatusEvent(write, status) {
7
+ const line = {
8
+ event: "status",
9
+ phase: status.phase,
10
+ label: status.label,
11
+ };
12
+ if (status.id !== undefined) {
13
+ line.id = status.id;
14
+ }
15
+ write(line);
16
+ }
17
+ //# sourceMappingURL=emit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/progress/emit.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,0BAA0B;IACxC,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,MAAc;IACnE,MAAM,IAAI,GAA4B;QACpC,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC;IACF,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;IACtB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,CAAC;AACd,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { FoldBackend } from "../fold/backend.js";
2
+ import type { ProgressWriter } from "../progress/emit.js";
3
+ import type { IntegrationOutcome, Invocation } from "../types.js";
4
+ export type RunResult = {
5
+ outcome: IntegrationOutcome;
6
+ parent?: string;
7
+ report?: string;
8
+ exitCode: number;
9
+ };
10
+ export type RunOptions = {
11
+ invocation: Invocation;
12
+ /** How Integrator folds. Required; Integrator does not sniff `.git`. */
13
+ backend: FoldBackend;
14
+ write?: ProgressWriter;
15
+ /** Injectable clock for tests. */
16
+ now?: () => number;
17
+ /** When set, polled for interrupt; otherwise process signals are used. */
18
+ interruptFlag?: {
19
+ interrupted: boolean;
20
+ };
21
+ /** Working directory for spawned children. Undefined lets them inherit. */
22
+ cwd?: string;
23
+ };
24
+ /**
25
+ * Run one Integrator invocation to an Integration outcome.
26
+ */
27
+ export declare function runIntegrator(options: RunOptions): Promise<RunResult>;
28
+ export declare function invalidInvocationResult(input: {
29
+ id: string | undefined;
30
+ onStatusArgv: string[] | undefined;
31
+ write: ProgressWriter;
32
+ reason: string;
33
+ cwd: string | undefined;
34
+ }): Promise<RunResult>;
35
+ //# sourceMappingURL=run-integrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-integrator.d.ts","sourceRoot":"","sources":["../../src/run/run-integrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAElE,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,wEAAwE;IACxE,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,0EAA0E;IAC1E,aAAa,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IACzC,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAwBF;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAgB3E;AAuID,wBAAsB,uBAAuB,CAAC,KAAK,EAAE;IACnD,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACnC,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACzB,GAAG,OAAO,CAAC,SAAS,CAAC,CA0BrB"}
@@ -0,0 +1,172 @@
1
+ import { fold } from "../fold/fold.js";
2
+ import { announceStatus } from "../status/announce.js";
3
+ import { makeStatus } from "../status/make-status.js";
4
+ function exitCodeFor(outcome) {
5
+ switch (outcome) {
6
+ case "integrated":
7
+ return 0;
8
+ case "conflict":
9
+ return 1;
10
+ case "invalid-invocation":
11
+ return 2;
12
+ case "failed":
13
+ return 3;
14
+ case "interrupted":
15
+ return 130;
16
+ }
17
+ }
18
+ function withId(id, line) {
19
+ if (id !== undefined) {
20
+ line.id = id;
21
+ }
22
+ return line;
23
+ }
24
+ /**
25
+ * Run one Integrator invocation to an Integration outcome.
26
+ */
27
+ export async function runIntegrator(options) {
28
+ const { invocation, backend } = options;
29
+ const write = options.write ?? (() => { });
30
+ const now = options.now ?? (() => Date.now());
31
+ const interruptState = options.interruptFlag ?? { interrupted: false };
32
+ const shouldInterrupt = () => interruptState.interrupted;
33
+ return await runIntegration({
34
+ invocation,
35
+ backend,
36
+ write,
37
+ now,
38
+ shouldInterrupt,
39
+ cwd: options.cwd,
40
+ });
41
+ }
42
+ async function runIntegration(input) {
43
+ const { invocation, backend, write, now, shouldInterrupt } = input;
44
+ await announceStatus({
45
+ onStatusArgv: invocation.onStatusArgv,
46
+ status: makeStatus({ phase: "integrating", id: invocation.id }),
47
+ write,
48
+ shouldInterrupt,
49
+ cwd: input.cwd,
50
+ });
51
+ write(withId(invocation.id, {
52
+ event: "integration-started",
53
+ }));
54
+ const deadlineMs = now() + invocation.durationMs;
55
+ const folded = await fold({
56
+ parent: invocation.parent,
57
+ child: invocation.child,
58
+ backend,
59
+ ...(invocation.id === undefined ? {} : { id: invocation.id }),
60
+ ...(invocation.subject === undefined ? {} : { subject: invocation.subject }),
61
+ ...(invocation.mergeSubject === undefined ? {} : { mergeSubject: invocation.mergeSubject }),
62
+ deadlineMs,
63
+ now,
64
+ shouldInterrupt,
65
+ });
66
+ if (folded.ok) {
67
+ // A stop signal racing a just-completed fold uses integrated.
68
+ return finishIntegration({
69
+ cwd: input.cwd,
70
+ invocation,
71
+ write,
72
+ outcome: "integrated",
73
+ parent: invocation.parent,
74
+ });
75
+ }
76
+ if ("stop" in folded && folded.stop === "interrupt") {
77
+ return finishIntegration({ cwd: input.cwd, invocation, write, outcome: "interrupted" });
78
+ }
79
+ if ("stop" in folded && folded.stop === "clock") {
80
+ if (shouldInterrupt()) {
81
+ return finishIntegration({ cwd: input.cwd, invocation, write, outcome: "interrupted" });
82
+ }
83
+ return finishIntegration({
84
+ cwd: input.cwd,
85
+ invocation,
86
+ write,
87
+ outcome: "failed",
88
+ report: "The Integration clock fired.",
89
+ });
90
+ }
91
+ if ("conflict" in folded && folded.conflict) {
92
+ if (shouldInterrupt()) {
93
+ return finishIntegration({ cwd: input.cwd, invocation, write, outcome: "interrupted" });
94
+ }
95
+ return finishIntegration({
96
+ cwd: input.cwd,
97
+ invocation,
98
+ write,
99
+ outcome: "conflict",
100
+ report: folded.report,
101
+ });
102
+ }
103
+ const detail = "detail" in folded ? folded.detail : "Integration could not complete.";
104
+ if (shouldInterrupt()) {
105
+ return finishIntegration({ cwd: input.cwd, invocation, write, outcome: "interrupted" });
106
+ }
107
+ return finishIntegration({
108
+ cwd: input.cwd,
109
+ invocation,
110
+ write,
111
+ outcome: "failed",
112
+ report: detail,
113
+ });
114
+ }
115
+ async function finishIntegration(input) {
116
+ const { invocation, write, outcome } = input;
117
+ await announceStatus({
118
+ onStatusArgv: invocation.onStatusArgv,
119
+ status: makeStatus({ phase: outcome, id: invocation.id }),
120
+ write,
121
+ shouldInterrupt: () => false,
122
+ cwd: input.cwd,
123
+ });
124
+ const finished = {
125
+ event: "integration-finished",
126
+ outcome,
127
+ };
128
+ if (outcome === "integrated" && input.parent !== undefined) {
129
+ finished.parent = input.parent;
130
+ }
131
+ if ((outcome === "conflict" || outcome === "failed") && input.report !== undefined) {
132
+ finished.report = input.report;
133
+ }
134
+ write(withId(invocation.id, finished));
135
+ const result = {
136
+ outcome,
137
+ exitCode: exitCodeFor(outcome),
138
+ };
139
+ if (input.parent !== undefined) {
140
+ result.parent = input.parent;
141
+ }
142
+ if (input.report !== undefined) {
143
+ result.report = input.report;
144
+ }
145
+ return result;
146
+ }
147
+ export async function invalidInvocationResult(input) {
148
+ const statusInput = { phase: "invalid" };
149
+ if (input.id !== undefined) {
150
+ statusInput.id = input.id;
151
+ }
152
+ const status = makeStatus(statusInput);
153
+ await announceStatus({
154
+ onStatusArgv: input.onStatusArgv,
155
+ status,
156
+ write: input.write,
157
+ shouldInterrupt: () => false,
158
+ cwd: input.cwd,
159
+ });
160
+ input.write(withId(input.id, {
161
+ event: "integration-finished",
162
+ outcome: "invalid-invocation",
163
+ report: input.reason,
164
+ }));
165
+ const result = {
166
+ outcome: "invalid-invocation",
167
+ report: input.reason,
168
+ exitCode: exitCodeFor("invalid-invocation"),
169
+ };
170
+ return result;
171
+ }
172
+ //# sourceMappingURL=run-integrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-integrator.js","sourceRoot":"","sources":["../../src/run/run-integrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ProgressWriter } from "../progress/emit.js";
2
+ import type { Status } from "../types.js";
3
+ /**
4
+ * Announce Status on stdout (and optionally via --on-status).
5
+ * --on-status never affects the Integration outcome.
6
+ */
7
+ export declare function announceStatus(input: {
8
+ onStatusArgv: string[] | undefined;
9
+ status: Status;
10
+ write: ProgressWriter;
11
+ shouldInterrupt: () => boolean;
12
+ cwd: string | undefined;
13
+ }): Promise<void>;
14
+ //# sourceMappingURL=announce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"announce.d.ts","sourceRoot":"","sources":["../../src/status/announce.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC1C,YAAY,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,cAAc,CAAC;IACtB,eAAe,EAAE,MAAM,OAAO,CAAC;IAC/B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACzB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBhB"}
@@ -0,0 +1,28 @@
1
+ import { runChild } from "../child/run-child.js";
2
+ import { emitStatusEvent } from "../progress/emit.js";
3
+ /**
4
+ * Announce Status on stdout (and optionally via --on-status).
5
+ * --on-status never affects the Integration outcome.
6
+ */
7
+ export async function announceStatus(input) {
8
+ const { status, write, shouldInterrupt, cwd } = input;
9
+ emitStatusEvent(write, status);
10
+ const onStatus = input.onStatusArgv;
11
+ if (onStatus === undefined) {
12
+ return;
13
+ }
14
+ const argv = [...onStatus];
15
+ if (status.id !== undefined) {
16
+ argv.push("--id", status.id);
17
+ }
18
+ argv.push("--label", status.label, "--phase", status.phase);
19
+ // Soft cap only: a hang or non-zero exit must not change the Integration outcome.
20
+ await runChild({
21
+ argv,
22
+ cwd,
23
+ timeoutMs: 5_000,
24
+ timeoutClock: "integration",
25
+ shouldInterrupt,
26
+ });
27
+ }
28
+ //# sourceMappingURL=announce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"announce.js","sourceRoot":"","sources":["../../src/status/announce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAMpC;IACC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IACtD,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE/B,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC;IACpC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC3B,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAE5D,kFAAkF;IAClF,MAAM,QAAQ,CAAC;QACb,IAAI;QACJ,GAAG;QACH,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,aAAa;QAC3B,eAAe;KAChB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Status, StatusPhase } from "../types.js";
2
+ export declare function buildStatusLabel(phase: StatusPhase, id: string | undefined): string;
3
+ export declare function makeStatus(input: {
4
+ phase: StatusPhase;
5
+ id?: string;
6
+ }): Status;
7
+ //# sourceMappingURL=make-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-status.d.ts","sourceRoot":"","sources":["../../src/status/make-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEvD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAQnF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQ7E"}
@@ -0,0 +1,19 @@
1
+ export function buildStatusLabel(phase, id) {
2
+ if (phase === "invalid") {
3
+ return "invalid";
4
+ }
5
+ if (id === undefined) {
6
+ throw new Error(`Status phase "${phase}" requires id.`);
7
+ }
8
+ return `${phase}:${id}`;
9
+ }
10
+ export function makeStatus(input) {
11
+ const { phase, id } = input;
12
+ const label = buildStatusLabel(phase, id);
13
+ const status = { phase, label };
14
+ if (id !== undefined) {
15
+ status.id = id;
16
+ }
17
+ return status;
18
+ }
19
+ //# sourceMappingURL=make-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-status.js","sourceRoot":"","sources":["../../src/status/make-status.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,KAAkB,EAAE,EAAsB;IACzE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,gBAAgB,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,GAAG,KAAK,IAAI,EAAE,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAA0C;IACnE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IAC5B,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAW,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACxC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** Domain types owned by Integrator. Names match the Transformer perimeter only. */
2
+ export type IntegrationOutcome = "invalid-invocation" | "integrated" | "conflict" | "failed" | "interrupted";
3
+ export type StatusPhase = "integrating" | "integrated" | "conflict" | "failed" | "interrupted" | "invalid";
4
+ export type ClockName = "integration";
5
+ export type Status = {
6
+ phase: StatusPhase;
7
+ id?: string;
8
+ label: string;
9
+ };
10
+ export type Invocation = {
11
+ id: string;
12
+ parent: string;
13
+ child: string;
14
+ durationMs: number;
15
+ /** What the folded work is, for whoever reads the history it leaves. */
16
+ subject?: string;
17
+ /** What the fold itself is, when it has to leave a merge of its own. */
18
+ mergeSubject?: string;
19
+ onStatusArgv?: string[];
20
+ };
21
+ export type ParseFailure = {
22
+ ok: false;
23
+ reason: string;
24
+ id?: string;
25
+ onStatusArgv?: string[];
26
+ };
27
+ export type ParseResult = {
28
+ ok: true;
29
+ invocation: Invocation;
30
+ strategy: string;
31
+ } | ParseFailure;
32
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAEpF,MAAM,MAAM,kBAAkB,GAC1B,oBAAoB,GACpB,YAAY,GACZ,UAAU,GACV,QAAQ,GACR,aAAa,CAAC;AAElB,MAAM,MAAM,WAAW,GACnB,aAAa,GACb,YAAY,GACZ,UAAU,GACV,QAAQ,GACR,aAAa,GACb,SAAS,CAAC;AAEd,MAAM,MAAM,SAAS,GAAG,aAAa,CAAC;AAEtC,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ /** Domain types owned by Integrator. Names match the Transformer perimeter only. */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map