@prisma-next/migration-tools 0.11.0-dev.47 → 0.11.0-dev.49
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/dist/exports/aggregate.d.mts +6 -6
- package/dist/exports/aggregate.mjs +1 -1
- package/dist/exports/enumerate-migration-spaces.d.mts +1 -1
- package/dist/exports/graph.d.mts +1 -1
- package/dist/exports/hash.d.mts +2 -2
- package/dist/exports/invariants.d.mts +1 -1
- package/dist/exports/io.d.mts +1 -1
- package/dist/exports/metadata.d.mts +1 -1
- package/dist/exports/migration-graph.d.mts +2 -2
- package/dist/exports/migration-list-graph-topology.d.mts +13 -2
- package/dist/exports/migration-list-graph-topology.d.mts.map +1 -0
- package/dist/exports/migration-list-graph-topology.mjs +104 -1
- package/dist/exports/migration-list-graph-topology.mjs.map +1 -0
- package/dist/exports/migration-list-types.d.mts +1 -1
- package/dist/exports/migration.d.mts +1 -1
- package/dist/exports/package.d.mts +1 -1
- package/dist/exports/ref-resolution.d.mts +2 -2
- package/dist/exports/refs.d.mts +1 -1
- package/dist/exports/spaces.d.mts +2 -2
- package/dist/exports/spaces.mjs +1 -1
- package/dist/{graph-3dLMZp5l.d.mts → graph-BUZuUeBC.d.mts} +1 -1
- package/dist/{graph-3dLMZp5l.d.mts.map → graph-BUZuUeBC.d.mts.map} +1 -1
- package/dist/{io-BH4G3F-i.d.mts → io-nqFXSSTN.d.mts} +2 -2
- package/dist/{io-BH4G3F-i.d.mts.map → io-nqFXSSTN.d.mts.map} +1 -1
- package/dist/{migration-graph-CWEM2SLR.d.mts → migration-graph-DtNT-cqc.d.mts} +3 -3
- package/dist/{migration-graph-CWEM2SLR.d.mts.map → migration-graph-DtNT-cqc.d.mts.map} +1 -1
- package/dist/{migration-list-types-0YjFETIv.d.mts → migration-list-types-BRTuXR8i.d.mts} +1 -1
- package/dist/{migration-list-types-0YjFETIv.d.mts.map → migration-list-types-BRTuXR8i.d.mts.map} +1 -1
- package/dist/{package-Ca-J_z_0.d.mts → package-DIttKL7X.d.mts} +1 -1
- package/dist/{package-Ca-J_z_0.d.mts.map → package-DIttKL7X.d.mts.map} +1 -1
- package/dist/{read-contract-space-contract-7-OB-ykY.mjs → read-contract-space-contract-BS5Oxbgw.mjs} +1 -1
- package/dist/{read-contract-space-contract-7-OB-ykY.mjs.map → read-contract-space-contract-BS5Oxbgw.mjs.map} +1 -1
- package/dist/{refs-B33AsTjk.d.mts → refs-C8f2IGM8.d.mts} +1 -1
- package/dist/{refs-B33AsTjk.d.mts.map → refs-C8f2IGM8.d.mts.map} +1 -1
- package/dist/{verify-contract-spaces-BdysZdQk.d.mts → verify-contract-spaces-T0aiJlBS.d.mts} +1 -1
- package/dist/{verify-contract-spaces-BdysZdQk.d.mts.map → verify-contract-spaces-T0aiJlBS.d.mts.map} +1 -1
- package/package.json +6 -10
- package/src/exports/migration-list-graph-topology.ts +4 -1
- package/src/migration-list-graph-topology.ts +8 -6
- package/dist/exports/migration-list-graph-layout.d.mts +0 -34
- package/dist/exports/migration-list-graph-layout.d.mts.map +0 -1
- package/dist/exports/migration-list-graph-layout.mjs +0 -170
- package/dist/exports/migration-list-graph-layout.mjs.map +0 -1
- package/dist/migration-list-graph-topology-Be1d8Y89.d.mts +0 -13
- package/dist/migration-list-graph-topology-Be1d8Y89.d.mts.map +0 -1
- package/dist/migration-list-graph-topology-BtFzbZ9L.mjs +0 -103
- package/dist/migration-list-graph-topology-BtFzbZ9L.mjs.map +0 -1
- package/src/exports/migration-list-graph-layout.ts +0 -9
- package/src/migration-list-graph-layout.ts +0 -256
- /package/dist/{metadata-CGkJF4L6.d.mts → metadata-Bp9X04gM.d.mts} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { n as OnDiskMigrationPackage } from "../package-
|
|
2
|
-
import { n as RefLoadProblem, r as Refs } from "../refs-
|
|
3
|
-
import { t as ContractSpaceHeadRecord } from "../verify-contract-spaces-
|
|
4
|
-
import { n as MigrationGraph } from "../graph-
|
|
5
|
-
import { t as PackageLoadProblem } from "../io-
|
|
6
|
-
import { t as PathDecision } from "../migration-graph-
|
|
1
|
+
import { n as OnDiskMigrationPackage } from "../package-DIttKL7X.mjs";
|
|
2
|
+
import { n as RefLoadProblem, r as Refs } from "../refs-C8f2IGM8.mjs";
|
|
3
|
+
import { t as ContractSpaceHeadRecord } from "../verify-contract-spaces-T0aiJlBS.mjs";
|
|
4
|
+
import { n as MigrationGraph } from "../graph-BUZuUeBC.mjs";
|
|
5
|
+
import { t as PackageLoadProblem } from "../io-nqFXSSTN.mjs";
|
|
6
|
+
import { t as PathDecision } from "../migration-graph-DtNT-cqc.mjs";
|
|
7
7
|
import { ControlFamilyInstance, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlannerConflict, TargetMigrationsCapability } from "@prisma-next/framework-components/control";
|
|
8
8
|
import { Result } from "@prisma-next/utils/result";
|
|
9
9
|
import { Contract } from "@prisma-next/contract/types";
|
|
@@ -4,7 +4,7 @@ import { t as EMPTY_CONTRACT_HASH } from "../constants-DWV9_o2Z.mjs";
|
|
|
4
4
|
import { l as reconstructGraph, o as findPathWithDecision } from "../migration-graph-kGBkIZDa.mjs";
|
|
5
5
|
import { a as readRefsTolerant, t as HEAD_REF_NAME } from "../refs-BBKNL45K.mjs";
|
|
6
6
|
import { c as spaceMigrationDirectory, i as RESERVED_SPACE_SUBDIR_NAMES, l as spaceRefsDirectory, r as APP_SPACE_ID, s as isValidSpaceId, t as listContractSpaceDirectories } from "../verify-contract-spaces-BJX5gqtD.mjs";
|
|
7
|
-
import { n as readContractSpaceHeadRef, t as readContractSpaceContract } from "../read-contract-space-contract-
|
|
7
|
+
import { n as readContractSpaceHeadRef, t as readContractSpaceContract } from "../read-contract-space-contract-BS5Oxbgw.mjs";
|
|
8
8
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
9
9
|
//#region src/aggregate/aggregate.ts
|
|
10
10
|
/**
|
package/dist/exports/graph.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as MigrationGraph, t as MigrationEdge } from "../graph-
|
|
1
|
+
import { n as MigrationGraph, t as MigrationEdge } from "../graph-BUZuUeBC.mjs";
|
|
2
2
|
export { type MigrationEdge, type MigrationGraph };
|
package/dist/exports/hash.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as OnDiskMigrationPackage, t as MigrationOps } from "../package-
|
|
2
|
-
import { t as MigrationMetadata } from "../metadata-
|
|
1
|
+
import { n as OnDiskMigrationPackage, t as MigrationOps } from "../package-DIttKL7X.mjs";
|
|
2
|
+
import { t as MigrationMetadata } from "../metadata-Bp9X04gM.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/hash.d.ts
|
|
5
5
|
interface VerifyResult {
|
package/dist/exports/io.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as materialiseExtensionMigrationPackageIfMissing, c as readMigrationsDir, d as writeMigrationPackage, i as formatMigrationDirName, l as writeMigrationMetadata, n as ReadMigrationsDirResult, o as materialiseMigrationPackage, r as copyFilesWithRename, s as readMigrationPackage, t as PackageLoadProblem, u as writeMigrationOps } from "../io-
|
|
1
|
+
import { a as materialiseExtensionMigrationPackageIfMissing, c as readMigrationsDir, d as writeMigrationPackage, i as formatMigrationDirName, l as writeMigrationMetadata, n as ReadMigrationsDirResult, o as materialiseMigrationPackage, r as copyFilesWithRename, s as readMigrationPackage, t as PackageLoadProblem, u as writeMigrationOps } from "../io-nqFXSSTN.mjs";
|
|
2
2
|
export { type PackageLoadProblem, type ReadMigrationsDirResult, copyFilesWithRename, formatMigrationDirName, materialiseExtensionMigrationPackageIfMissing, materialiseMigrationPackage, readMigrationPackage, readMigrationsDir, writeMigrationMetadata, writeMigrationOps, writeMigrationPackage };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as MigrationMetadata } from "../metadata-
|
|
1
|
+
import { t as MigrationMetadata } from "../metadata-Bp9X04gM.mjs";
|
|
2
2
|
export { type MigrationMetadata };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as MigrationGraph } from "../graph-
|
|
2
|
-
import { a as findLeaf, c as findPathWithInvariants, i as findLatestMigration, l as findReachableLeaves, n as detectCycles, o as findPath, r as detectOrphans, s as findPathWithDecision, t as PathDecision, u as reconstructGraph } from "../migration-graph-
|
|
1
|
+
import { n as MigrationGraph } from "../graph-BUZuUeBC.mjs";
|
|
2
|
+
import { a as findLeaf, c as findPathWithInvariants, i as findLatestMigration, l as findReachableLeaves, n as detectCycles, o as findPath, r as detectOrphans, s as findPathWithDecision, t as PathDecision, u as reconstructGraph } from "../migration-graph-DtNT-cqc.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/graph-membership.d.ts
|
|
5
5
|
declare function isGraphNode(hash: string, graph: MigrationGraph): boolean;
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { t as MigrationListEntry } from "../migration-list-types-BRTuXR8i.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/migration-list-graph-topology.d.ts
|
|
4
|
+
type MigrationEdgeKind = 'forward' | 'rollback' | 'self';
|
|
5
|
+
interface MigrationListGraphTopology {
|
|
6
|
+
readonly kindByMigrationHash: ReadonlyMap<string, MigrationEdgeKind>;
|
|
7
|
+
readonly forwardInDegree: ReadonlyMap<string, number>;
|
|
8
|
+
readonly forwardOutDegree: ReadonlyMap<string, number>;
|
|
9
|
+
}
|
|
10
|
+
declare function classifyMigrationListGraphTopology(entries: readonly MigrationListEntry[]): MigrationListGraphTopology;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { type MigrationEdgeKind, type MigrationListGraphTopology, classifyMigrationListGraphTopology };
|
|
13
|
+
//# sourceMappingURL=migration-list-graph-topology.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-list-graph-topology.d.mts","names":[],"sources":["../../src/migration-list-graph-topology.ts"],"mappings":";;;KAGY,iBAAA;AAAA,UAEK,0BAAA;EAAA,SACN,mBAAA,EAAqB,WAAA,SAAoB,iBAAA;EAAA,SACzC,eAAA,EAAiB,WAAA;EAAA,SACjB,gBAAA,EAAkB,WAAA;AAAA;AAAA,iBAqBb,kCAAA,CACd,OAAA,WAAkB,kBAAA,KACjB,0BAA0B"}
|
|
@@ -1,2 +1,105 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../constants-DWV9_o2Z.mjs";
|
|
2
|
+
//#region src/migration-list-graph-topology.ts
|
|
3
|
+
function canonicalFrom(from) {
|
|
4
|
+
return from ?? "sha256:empty";
|
|
5
|
+
}
|
|
6
|
+
function compareDirNameDesc(a, b) {
|
|
7
|
+
return b.dirName.localeCompare(a.dirName);
|
|
8
|
+
}
|
|
9
|
+
function bumpDegree(map, key) {
|
|
10
|
+
map.set(key, (map.get(key) ?? 0) + 1);
|
|
11
|
+
}
|
|
12
|
+
function classifyMigrationListGraphTopology(entries) {
|
|
13
|
+
const nodes = /* @__PURE__ */ new Set();
|
|
14
|
+
const kindByMigrationHash = /* @__PURE__ */ new Map();
|
|
15
|
+
const outgoingByFrom = /* @__PURE__ */ new Map();
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
const from = canonicalFrom(entry.from);
|
|
18
|
+
const to = entry.to;
|
|
19
|
+
nodes.add(from);
|
|
20
|
+
nodes.add(to);
|
|
21
|
+
if (from === to) {
|
|
22
|
+
kindByMigrationHash.set(entry.migrationHash, "self");
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const bucket = outgoingByFrom.get(from);
|
|
26
|
+
const edge = {
|
|
27
|
+
entry,
|
|
28
|
+
from,
|
|
29
|
+
to
|
|
30
|
+
};
|
|
31
|
+
if (bucket) bucket.push(edge);
|
|
32
|
+
else outgoingByFrom.set(from, [edge]);
|
|
33
|
+
}
|
|
34
|
+
for (const bucket of outgoingByFrom.values()) bucket.sort((a, b) => compareDirNameDesc(a.entry, b.entry));
|
|
35
|
+
const nonSelfInDegree = /* @__PURE__ */ new Map();
|
|
36
|
+
for (const node of nodes) nonSelfInDegree.set(node, 0);
|
|
37
|
+
for (const bucket of outgoingByFrom.values()) for (const edge of bucket) bumpDegree(nonSelfInDegree, edge.to);
|
|
38
|
+
const dfsRoots = [];
|
|
39
|
+
for (const node of nodes) if ((nonSelfInDegree.get(node) ?? 0) === 0) dfsRoots.push(node);
|
|
40
|
+
dfsRoots.sort((a, b) => {
|
|
41
|
+
if (a === "sha256:empty") return -1;
|
|
42
|
+
if (b === "sha256:empty") return 1;
|
|
43
|
+
return a.localeCompare(b);
|
|
44
|
+
});
|
|
45
|
+
if (dfsRoots.length === 0) dfsRoots.push(...[...nodes].sort((a, b) => a.localeCompare(b)));
|
|
46
|
+
const WHITE = 0;
|
|
47
|
+
const GRAY = 1;
|
|
48
|
+
const BLACK = 2;
|
|
49
|
+
const color = /* @__PURE__ */ new Map();
|
|
50
|
+
for (const node of nodes) color.set(node, WHITE);
|
|
51
|
+
const stack = [];
|
|
52
|
+
function pushFrame(node) {
|
|
53
|
+
color.set(node, GRAY);
|
|
54
|
+
stack.push({
|
|
55
|
+
node,
|
|
56
|
+
outgoing: outgoingByFrom.get(node) ?? [],
|
|
57
|
+
index: 0
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function runDfsFrom(root) {
|
|
61
|
+
if (color.get(root) !== WHITE) return;
|
|
62
|
+
pushFrame(root);
|
|
63
|
+
while (stack.length > 0) {
|
|
64
|
+
const frame = stack[stack.length - 1];
|
|
65
|
+
if (frame === void 0) break;
|
|
66
|
+
if (frame.index >= frame.outgoing.length) {
|
|
67
|
+
color.set(frame.node, BLACK);
|
|
68
|
+
stack.pop();
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const edge = frame.outgoing[frame.index];
|
|
72
|
+
frame.index += 1;
|
|
73
|
+
if (edge === void 0) continue;
|
|
74
|
+
const v = edge.to;
|
|
75
|
+
const vColor = color.get(v);
|
|
76
|
+
if (vColor === GRAY) kindByMigrationHash.set(edge.entry.migrationHash, "rollback");
|
|
77
|
+
else {
|
|
78
|
+
kindByMigrationHash.set(edge.entry.migrationHash, "forward");
|
|
79
|
+
if (vColor === WHITE) pushFrame(v);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const root of dfsRoots) runDfsFrom(root);
|
|
84
|
+
const remainingWhite = [...nodes].filter((node) => color.get(node) === WHITE);
|
|
85
|
+
remainingWhite.sort((a, b) => a.localeCompare(b));
|
|
86
|
+
for (const root of remainingWhite) runDfsFrom(root);
|
|
87
|
+
const forwardInDegree = /* @__PURE__ */ new Map();
|
|
88
|
+
const forwardOutDegree = /* @__PURE__ */ new Map();
|
|
89
|
+
for (const entry of entries) {
|
|
90
|
+
if (kindByMigrationHash.get(entry.migrationHash) !== "forward") continue;
|
|
91
|
+
const from = canonicalFrom(entry.from);
|
|
92
|
+
const to = entry.to;
|
|
93
|
+
bumpDegree(forwardOutDegree, from);
|
|
94
|
+
bumpDegree(forwardInDegree, to);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
kindByMigrationHash,
|
|
98
|
+
forwardInDegree,
|
|
99
|
+
forwardOutDegree
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
2
103
|
export { classifyMigrationListGraphTopology };
|
|
104
|
+
|
|
105
|
+
//# sourceMappingURL=migration-list-graph-topology.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-list-graph-topology.mjs","names":[],"sources":["../../src/migration-list-graph-topology.ts"],"sourcesContent":["import { EMPTY_CONTRACT_HASH } from './constants';\nimport type { MigrationListEntry } from './migration-list-types';\n\nexport type MigrationEdgeKind = 'forward' | 'rollback' | 'self';\n\nexport interface MigrationListGraphTopology {\n readonly kindByMigrationHash: ReadonlyMap<string, MigrationEdgeKind>;\n readonly forwardInDegree: ReadonlyMap<string, number>;\n readonly forwardOutDegree: ReadonlyMap<string, number>;\n}\n\ninterface NonSelfEdge {\n readonly entry: MigrationListEntry;\n readonly from: string;\n readonly to: string;\n}\n\nfunction canonicalFrom(from: string | null): string {\n return from ?? EMPTY_CONTRACT_HASH;\n}\n\nfunction compareDirNameDesc(a: MigrationListEntry, b: MigrationListEntry): number {\n return b.dirName.localeCompare(a.dirName);\n}\n\nfunction bumpDegree(map: Map<string, number>, key: string): void {\n map.set(key, (map.get(key) ?? 0) + 1);\n}\n\nexport function classifyMigrationListGraphTopology(\n entries: readonly MigrationListEntry[],\n): MigrationListGraphTopology {\n const nodes = new Set<string>();\n const kindByMigrationHash = new Map<string, MigrationEdgeKind>();\n const outgoingByFrom = new Map<string, NonSelfEdge[]>();\n\n for (const entry of entries) {\n const from = canonicalFrom(entry.from);\n const to = entry.to;\n nodes.add(from);\n nodes.add(to);\n\n if (from === to) {\n kindByMigrationHash.set(entry.migrationHash, 'self');\n continue;\n }\n\n const bucket = outgoingByFrom.get(from);\n const edge: NonSelfEdge = { entry, from, to };\n if (bucket) bucket.push(edge);\n else outgoingByFrom.set(from, [edge]);\n }\n\n for (const bucket of outgoingByFrom.values()) {\n bucket.sort((a, b) => compareDirNameDesc(a.entry, b.entry));\n }\n\n const nonSelfInDegree = new Map<string, number>();\n for (const node of nodes) {\n nonSelfInDegree.set(node, 0);\n }\n for (const bucket of outgoingByFrom.values()) {\n for (const edge of bucket) {\n bumpDegree(nonSelfInDegree, edge.to);\n }\n }\n\n const dfsRoots: string[] = [];\n for (const node of nodes) {\n if ((nonSelfInDegree.get(node) ?? 0) === 0) {\n dfsRoots.push(node);\n }\n }\n dfsRoots.sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n if (dfsRoots.length === 0) {\n dfsRoots.push(...[...nodes].sort((a, b) => a.localeCompare(b)));\n }\n\n const WHITE = 0;\n const GRAY = 1;\n const BLACK = 2;\n const color = new Map<string, number>();\n for (const node of nodes) {\n color.set(node, WHITE);\n }\n\n interface Frame {\n node: string;\n outgoing: readonly NonSelfEdge[];\n index: number;\n }\n const stack: Frame[] = [];\n\n function pushFrame(node: string): void {\n color.set(node, GRAY);\n stack.push({ node, outgoing: outgoingByFrom.get(node) ?? [], index: 0 });\n }\n\n function runDfsFrom(root: string): void {\n if (color.get(root) !== WHITE) return;\n pushFrame(root);\n\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n if (frame === undefined) break;\n if (frame.index >= frame.outgoing.length) {\n color.set(frame.node, BLACK);\n stack.pop();\n continue;\n }\n\n const edge = frame.outgoing[frame.index];\n frame.index += 1;\n if (edge === undefined) continue;\n\n const v = edge.to;\n const vColor = color.get(v);\n if (vColor === GRAY) {\n kindByMigrationHash.set(edge.entry.migrationHash, 'rollback');\n } else {\n kindByMigrationHash.set(edge.entry.migrationHash, 'forward');\n if (vColor === WHITE) {\n pushFrame(v);\n }\n }\n }\n }\n\n for (const root of dfsRoots) {\n runDfsFrom(root);\n }\n const remainingWhite = [...nodes].filter((node) => color.get(node) === WHITE);\n remainingWhite.sort((a, b) => a.localeCompare(b));\n for (const root of remainingWhite) {\n runDfsFrom(root);\n }\n\n const forwardInDegree = new Map<string, number>();\n const forwardOutDegree = new Map<string, number>();\n\n for (const entry of entries) {\n if (kindByMigrationHash.get(entry.migrationHash) !== 'forward') continue;\n const from = canonicalFrom(entry.from);\n const to = entry.to;\n bumpDegree(forwardOutDegree, from);\n bumpDegree(forwardInDegree, to);\n }\n\n return {\n kindByMigrationHash,\n forwardInDegree,\n forwardOutDegree,\n };\n}\n"],"mappings":";;AAiBA,SAAS,cAAc,MAA6B;CAClD,OAAO,QAAA;AACT;AAEA,SAAS,mBAAmB,GAAuB,GAA+B;CAChF,OAAO,EAAE,QAAQ,cAAc,EAAE,OAAO;AAC1C;AAEA,SAAS,WAAW,KAA0B,KAAmB;CAC/D,IAAI,IAAI,MAAM,IAAI,IAAI,GAAG,KAAK,KAAK,CAAC;AACtC;AAEA,SAAgB,mCACd,SAC4B;CAC5B,MAAM,wBAAQ,IAAI,IAAY;CAC9B,MAAM,sCAAsB,IAAI,IAA+B;CAC/D,MAAM,iCAAiB,IAAI,IAA2B;CAEtD,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,OAAO,cAAc,MAAM,IAAI;EACrC,MAAM,KAAK,MAAM;EACjB,MAAM,IAAI,IAAI;EACd,MAAM,IAAI,EAAE;EAEZ,IAAI,SAAS,IAAI;GACf,oBAAoB,IAAI,MAAM,eAAe,MAAM;GACnD;EACF;EAEA,MAAM,SAAS,eAAe,IAAI,IAAI;EACtC,MAAM,OAAoB;GAAE;GAAO;GAAM;EAAG;EAC5C,IAAI,QAAQ,OAAO,KAAK,IAAI;OACvB,eAAe,IAAI,MAAM,CAAC,IAAI,CAAC;CACtC;CAEA,KAAK,MAAM,UAAU,eAAe,OAAO,GACzC,OAAO,MAAM,GAAG,MAAM,mBAAmB,EAAE,OAAO,EAAE,KAAK,CAAC;CAG5D,MAAM,kCAAkB,IAAI,IAAoB;CAChD,KAAK,MAAM,QAAQ,OACjB,gBAAgB,IAAI,MAAM,CAAC;CAE7B,KAAK,MAAM,UAAU,eAAe,OAAO,GACzC,KAAK,MAAM,QAAQ,QACjB,WAAW,iBAAiB,KAAK,EAAE;CAIvC,MAAM,WAAqB,CAAC;CAC5B,KAAK,MAAM,QAAQ,OACjB,KAAK,gBAAgB,IAAI,IAAI,KAAK,OAAO,GACvC,SAAS,KAAK,IAAI;CAGtB,SAAS,MAAM,GAAG,MAAM;EACtB,IAAI,MAAA,gBAA2B,OAAO;EACtC,IAAI,MAAA,gBAA2B,OAAO;EACtC,OAAO,EAAE,cAAc,CAAC;CAC1B,CAAC;CACD,IAAI,SAAS,WAAW,GACtB,SAAS,KAAK,GAAG,CAAC,GAAG,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;CAGhE,MAAM,QAAQ;CACd,MAAM,OAAO;CACb,MAAM,QAAQ;CACd,MAAM,wBAAQ,IAAI,IAAoB;CACtC,KAAK,MAAM,QAAQ,OACjB,MAAM,IAAI,MAAM,KAAK;CAQvB,MAAM,QAAiB,CAAC;CAExB,SAAS,UAAU,MAAoB;EACrC,MAAM,IAAI,MAAM,IAAI;EACpB,MAAM,KAAK;GAAE;GAAM,UAAU,eAAe,IAAI,IAAI,KAAK,CAAC;GAAG,OAAO;EAAE,CAAC;CACzE;CAEA,SAAS,WAAW,MAAoB;EACtC,IAAI,MAAM,IAAI,IAAI,MAAM,OAAO;EAC/B,UAAU,IAAI;EAEd,OAAO,MAAM,SAAS,GAAG;GACvB,MAAM,QAAQ,MAAM,MAAM,SAAS;GACnC,IAAI,UAAU,KAAA,GAAW;GACzB,IAAI,MAAM,SAAS,MAAM,SAAS,QAAQ;IACxC,MAAM,IAAI,MAAM,MAAM,KAAK;IAC3B,MAAM,IAAI;IACV;GACF;GAEA,MAAM,OAAO,MAAM,SAAS,MAAM;GAClC,MAAM,SAAS;GACf,IAAI,SAAS,KAAA,GAAW;GAExB,MAAM,IAAI,KAAK;GACf,MAAM,SAAS,MAAM,IAAI,CAAC;GAC1B,IAAI,WAAW,MACb,oBAAoB,IAAI,KAAK,MAAM,eAAe,UAAU;QACvD;IACL,oBAAoB,IAAI,KAAK,MAAM,eAAe,SAAS;IAC3D,IAAI,WAAW,OACb,UAAU,CAAC;GAEf;EACF;CACF;CAEA,KAAK,MAAM,QAAQ,UACjB,WAAW,IAAI;CAEjB,MAAM,iBAAiB,CAAC,GAAG,KAAK,EAAE,QAAQ,SAAS,MAAM,IAAI,IAAI,MAAM,KAAK;CAC5E,eAAe,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;CAChD,KAAK,MAAM,QAAQ,gBACjB,WAAW,IAAI;CAGjB,MAAM,kCAAkB,IAAI,IAAoB;CAChD,MAAM,mCAAmB,IAAI,IAAoB;CAEjD,KAAK,MAAM,SAAS,SAAS;EAC3B,IAAI,oBAAoB,IAAI,MAAM,aAAa,MAAM,WAAW;EAChE,MAAM,OAAO,cAAc,MAAM,IAAI;EACrC,MAAM,KAAK,MAAM;EACjB,WAAW,kBAAkB,IAAI;EACjC,WAAW,iBAAiB,EAAE;CAChC;CAEA,OAAO;EACL;EACA;EACA;CACF;AACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as MigrationListResult, r as MigrationSpaceListEntry, t as MigrationListEntry } from "../migration-list-types-
|
|
1
|
+
import { n as MigrationListResult, r as MigrationSpaceListEntry, t as MigrationListEntry } from "../migration-list-types-BRTuXR8i.mjs";
|
|
2
2
|
export { type MigrationListEntry, type MigrationListResult, type MigrationSpaceListEntry };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as MigrationMetadata$1 } from "../metadata-
|
|
1
|
+
import { t as MigrationMetadata$1 } from "../metadata-Bp9X04gM.mjs";
|
|
2
2
|
import { ControlStack, MigrationPlan, MigrationPlanOperation } from "@prisma-next/framework-components/control";
|
|
3
3
|
|
|
4
4
|
//#region src/migration-base.d.ts
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as OnDiskMigrationPackage, t as MigrationOps } from "../package-
|
|
1
|
+
import { n as OnDiskMigrationPackage, t as MigrationOps } from "../package-DIttKL7X.mjs";
|
|
2
2
|
import { MigrationPackage } from "@prisma-next/framework-components/control";
|
|
3
3
|
export { type MigrationOps, type MigrationPackage, type OnDiskMigrationPackage };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as Refs } from "../refs-
|
|
2
|
-
import { n as MigrationGraph, t as MigrationEdge } from "../graph-
|
|
1
|
+
import { r as Refs } from "../refs-C8f2IGM8.mjs";
|
|
2
|
+
import { n as MigrationGraph, t as MigrationEdge } from "../graph-BUZuUeBC.mjs";
|
|
3
3
|
import { Result } from "@prisma-next/utils/result";
|
|
4
4
|
|
|
5
5
|
//#region src/refs/types.d.ts
|
package/dist/exports/refs.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as readRef, c as validateRefName, i as deleteRef, l as validateRefValue, o as readRefs, r as Refs, s as resolveRef, t as RefEntry, u as writeRef } from "../refs-
|
|
1
|
+
import { a as readRef, c as validateRefName, i as deleteRef, l as validateRefValue, o as readRefs, r as Refs, s as resolveRef, t as RefEntry, u as writeRef } from "../refs-C8f2IGM8.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/refs/snapshot.d.ts
|
|
4
4
|
interface ContractIR {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as MigrationOps } from "../package-
|
|
2
|
-
import { a as VerifyContractSpacesResult, i as VerifyContractSpacesInputs, n as SpaceMarkerRecord, o as listContractSpaceDirectories, r as SpaceVerifierViolation, s as verifyContractSpaces, t as ContractSpaceHeadRecord } from "../verify-contract-spaces-
|
|
1
|
+
import { t as MigrationOps } from "../package-DIttKL7X.mjs";
|
|
2
|
+
import { a as VerifyContractSpacesResult, i as VerifyContractSpacesInputs, n as SpaceMarkerRecord, o as listContractSpaceDirectories, r as SpaceVerifierViolation, s as verifyContractSpaces, t as ContractSpaceHeadRecord } from "../verify-contract-spaces-T0aiJlBS.mjs";
|
|
3
3
|
import { APP_SPACE_ID, ContractSpace, ContractSpaceHeadRef, ContractSpaceHeadRef as ContractSpaceHeadRef$1 } from "@prisma-next/framework-components/control";
|
|
4
4
|
import { Contract } from "@prisma-next/contract/types";
|
|
5
5
|
|
package/dist/exports/spaces.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { s as readMigrationsDir } from "../io-BHl0amF0.mjs";
|
|
|
3
3
|
import "../constants-DWV9_o2Z.mjs";
|
|
4
4
|
import { l as reconstructGraph, o as findPathWithDecision } from "../migration-graph-kGBkIZDa.mjs";
|
|
5
5
|
import { a as SPACE_REFS_DIRNAME, c as spaceMigrationDirectory, i as RESERVED_SPACE_SUBDIR_NAMES, l as spaceRefsDirectory, n as verifyContractSpaces, o as assertValidSpaceId, r as APP_SPACE_ID, s as isValidSpaceId, t as listContractSpaceDirectories } from "../verify-contract-spaces-BJX5gqtD.mjs";
|
|
6
|
-
import { n as readContractSpaceHeadRef, t as readContractSpaceContract } from "../read-contract-space-contract-
|
|
6
|
+
import { n as readContractSpaceHeadRef, t as readContractSpaceContract } from "../read-contract-space-contract-BS5Oxbgw.mjs";
|
|
7
7
|
import { join } from "pathe";
|
|
8
8
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
9
9
|
import { canonicalizeJson } from "@prisma-next/framework-components/utils";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-
|
|
1
|
+
{"version":3,"file":"graph-BUZuUeBC.d.mts","names":[],"sources":["../src/graph.ts"],"mappings":";;AAIA;;;UAAiB,aAAA;EAAA,SACN,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,OAAA;EAAA,SACA,SAAA;EAMA;;AAAU;AAGrB;;EAHW,SAAA,UAAA;AAAA;AAAA,UAGM,cAAA;EAAA,SACN,KAAA,EAAO,WAAA;EAAA,SACP,YAAA,EAAc,WAAA,kBAA6B,aAAA;EAAA,SAC3C,YAAA,EAAc,WAAA,kBAA6B,aAAA;EAAA,SAC3C,eAAA,EAAiB,WAAA,SAAoB,aAAA;AAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as OnDiskMigrationPackage, t as MigrationOps } from "./package-
|
|
1
|
+
import { n as OnDiskMigrationPackage, t as MigrationOps } from "./package-DIttKL7X.mjs";
|
|
2
2
|
import { MigrationMetadata, MigrationPackage } from "@prisma-next/framework-components/control";
|
|
3
3
|
|
|
4
4
|
//#region src/io.d.ts
|
|
@@ -121,4 +121,4 @@ declare function readMigrationsDir(migrationsRoot: string): Promise<ReadMigratio
|
|
|
121
121
|
declare function formatMigrationDirName(timestamp: Date, slug: string): string;
|
|
122
122
|
//#endregion
|
|
123
123
|
export { materialiseExtensionMigrationPackageIfMissing as a, readMigrationsDir as c, writeMigrationPackage as d, formatMigrationDirName as i, writeMigrationMetadata as l, ReadMigrationsDirResult as n, materialiseMigrationPackage as o, copyFilesWithRename as r, readMigrationPackage as s, PackageLoadProblem as t, writeMigrationOps as u };
|
|
124
|
-
//# sourceMappingURL=io-
|
|
124
|
+
//# sourceMappingURL=io-nqFXSSTN.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io-
|
|
1
|
+
{"version":3,"file":"io-nqFXSSTN.d.mts","names":[],"sources":["../src/io.ts"],"mappings":";;;;iBAwCsB,qBAAA,CACpB,GAAA,UACA,QAAA,EAAU,iBAAA,EACV,GAAA,EAAK,YAAA,GACJ,OAAA;AAJH;;;;;;;;;;;;;;;AAIU;AAgDV;;;;;;;;;AAGU;AA2BV;;;;AAlFA,iBAoDsB,2BAAA,CACpB,SAAA,UACA,GAAA,EAAK,gBAAA,GACJ,OAAO;;;;;;AA8BmB;AA6B7B;;;;;;;;;;AAGU;AAUV;;;;iBA7CsB,6CAAA,CACpB,SAAA,UACA,GAAA,EAAK,gBAAA,GACJ,OAAO;EAAA,SAAY,OAAA;AAAA;;;AA6CZ;AAIV;;;;;;;;iBApBsB,mBAAA,CACpB,OAAA,UACA,KAAA;EAAA,SAA2B,UAAA;EAAA,SAA6B,QAAA;AAAA,MACvD,OAAO;AAAA,iBAUY,sBAAA,CACpB,GAAA,UACA,QAAA,EAAU,iBAAA,GACT,OAAO;AAAA,iBAIY,iBAAA,CAAkB,GAAA,UAAa,GAAA,EAAK,YAAA,GAAe,OAAO;AAAA,iBAI1D,oBAAA,CAAqB,GAAA,WAAc,OAAO,CAAC,sBAAA;;;;AAAsB;AAsKvF;;;;;;;;;;;KAAY,kBAAA;EAAA,SAEG,IAAA;EAAA,SACA,OAAA;EAAA,SACA,MAAA;EAAA,SACA,QAAA;AAAA;EAAA,SAEA,IAAA;EAAA,SAA6C,OAAA;AAAA;EAAA,SAC7C,IAAA;EAAA,SAAoC,OAAA;EAAA,SAA0B,MAAA;AAAA;AAa7B;AAShD;;;;;;;;AATgD,UAF/B,uBAAA;EAAA,SACN,QAAA,WAAmB,sBAAA;EAAA,SACnB,QAAA,WAAmB,kBAAkB;AAAA;AAAA,iBAS1B,iBAAA,CAAkB,cAAA,WAAyB,OAAO,CAAC,uBAAA;AAAA,iBAkEzD,sBAAA,CAAuB,SAAA,EAAW,IAAI,EAAE,IAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as OnDiskMigrationPackage } from "./package-
|
|
2
|
-
import { n as MigrationGraph, t as MigrationEdge } from "./graph-
|
|
1
|
+
import { n as OnDiskMigrationPackage } from "./package-DIttKL7X.mjs";
|
|
2
|
+
import { n as MigrationGraph, t as MigrationEdge } from "./graph-BUZuUeBC.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/migration-graph.d.ts
|
|
5
5
|
declare function reconstructGraph(packages: readonly OnDiskMigrationPackage[]): MigrationGraph;
|
|
@@ -121,4 +121,4 @@ declare function detectCycles(graph: MigrationGraph): readonly string[][];
|
|
|
121
121
|
declare function detectOrphans(graph: MigrationGraph): readonly MigrationEdge[];
|
|
122
122
|
//#endregion
|
|
123
123
|
export { findLeaf as a, findPathWithInvariants as c, findLatestMigration as i, findReachableLeaves as l, detectCycles as n, findPath as o, detectOrphans as r, findPathWithDecision as s, PathDecision as t, reconstructGraph as u };
|
|
124
|
-
//# sourceMappingURL=migration-graph-
|
|
124
|
+
//# sourceMappingURL=migration-graph-DtNT-cqc.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-graph-
|
|
1
|
+
{"version":3,"file":"migration-graph-DtNT-cqc.d.mts","names":[],"sources":["../src/migration-graph.ts"],"mappings":";;;;iBAgCgB,gBAAA,CAAiB,QAAA,WAAmB,sBAAA,KAA2B,cAAc;;AAA7F;;;;;;;iBA+DgB,QAAA,CACd,KAAA,EAAO,cAAA,EACP,QAAA,UACA,MAAA,oBACU,aAAa;AAnEoE;AA+D7F;;;;;;;;;;AAIyB;AA4CzB;;;;;;;AA/G6F,iBA+G7E,sBAAA,CACd,KAAA,EAAO,cAAA,EACP,QAAA,UACA,MAAA,UACA,QAAA,EAAU,WAAA,oBACA,aAAA;AAAA,UAsFK,YAAA;EAAA,SACN,YAAA,WAAuB,aAAa;EAAA,SACpC,QAAA;EAAA,SACA,MAAA;EAAA,SACA,gBAAA;EAAA,SACA,eAAA;EAAA,SACA,OAAA;EA5Fc;EAAA,SA8Fd,kBAAA;EARM;;;;;EAAA,SAcN,mBAAA;AAAA;;;;;;;;AAAmB;AAoB9B;;;;;;;;;KAAY,eAAA;EAAA,SACG,IAAA;EAAA,SAAqB,QAAA,EAAU,YAAA;AAAA;EAAA,SAC/B,IAAA;AAAA;EAAA,SAEA,IAAA;EAAA,SACA,cAAA,WAAyB,aAAa;EAAA,SACtC,OAAA;AAAA;;;;AAYkB;AAajC;;;UAfiB,2BAAA;EAAA,SACN,OAAA;EAAA,SACA,QAAA,GAAW,WAAW;AAAA;;;;;;;;;;AAkBf;iBALF,oBAAA,CACd,KAAA,EAAO,cAAA,EACP,QAAA,UACA,MAAA,UACA,OAAA,GAAS,2BAAA,GACR,eAAA;;;;;iBAqLa,mBAAA,CAAoB,KAAA,EAAO,cAAc,EAAE,QAAA;;;AAAgB;AAkB3E;;;;AAA8C;iBAA9B,QAAA,CAAS,KAAqB,EAAd,cAAc;;;;;;iBAwC9B,mBAAA,CAAoB,KAAA,EAAO,cAAA,GAAiB,aAAa;AAAA,iBAQzD,YAAA,CAAa,KAAqB,EAAd,cAAc;AAAA,iBA8DlC,aAAA,CAAc,KAAA,EAAO,cAAA,YAA0B,aAAa"}
|
|
@@ -20,4 +20,4 @@ interface MigrationListResult {
|
|
|
20
20
|
}
|
|
21
21
|
//#endregion
|
|
22
22
|
export { MigrationListResult as n, MigrationSpaceListEntry as r, MigrationListEntry as t };
|
|
23
|
-
//# sourceMappingURL=migration-list-types-
|
|
23
|
+
//# sourceMappingURL=migration-list-types-BRTuXR8i.d.mts.map
|
package/dist/{migration-list-types-0YjFETIv.d.mts.map → migration-list-types-BRTuXR8i.d.mts.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-list-types-
|
|
1
|
+
{"version":3,"file":"migration-list-types-BRTuXR8i.d.mts","names":[],"sources":["../src/migration-list-types.ts"],"mappings":";UAAiB,kBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,cAAA;EAAA,SACA,SAAA;EAAA,SACA,IAAA;EAAA,SACA,kBAAA;AAAA;AAAA,UAGM,uBAAA;EAAA,SACN,OAAA;EAAA,SACA,UAAA,WAAqB,kBAAkB;AAAA;AAAA,UAGjC,mBAAA;EAAA,SACN,EAAA;EAAA,SACA,MAAA,WAAiB,uBAAuB;EAAA,SACxC,OAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-
|
|
1
|
+
{"version":3,"file":"package-DIttKL7X.d.mts","names":[],"sources":["../src/package.ts"],"mappings":";;;KAKY,YAAA,YAAwB,sBAAsB;;AAA1D;;;;AAA0D;AAa1D;;;;AACkB;UADD,sBAAA,SAA+B,gBAAgB;EAAA,SACrD,OAAO;AAAA"}
|
package/dist/{read-contract-space-contract-7-OB-ykY.mjs → read-contract-space-contract-BS5Oxbgw.mjs}
RENAMED
|
@@ -79,4 +79,4 @@ async function readContractSpaceContract(projectMigrationsDir, spaceId) {
|
|
|
79
79
|
//#endregion
|
|
80
80
|
export { readContractSpaceHeadRef as n, readContractSpaceContract as t };
|
|
81
81
|
|
|
82
|
-
//# sourceMappingURL=read-contract-space-contract-
|
|
82
|
+
//# sourceMappingURL=read-contract-space-contract-BS5Oxbgw.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-contract-space-contract-
|
|
1
|
+
{"version":3,"file":"read-contract-space-contract-BS5Oxbgw.mjs","names":["hasErrnoCode"],"sources":["../src/read-contract-space-head-ref.ts","../src/read-contract-space-contract.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { ContractSpaceHeadRef } from '@prisma-next/framework-components/control';\nimport { join } from 'pathe';\nimport { errorInvalidJson, errorInvalidRefFile } from './errors';\nimport { assertValidSpaceId, spaceMigrationDirectory, spaceRefsDirectory } from './space-layout';\n\nexport type { ContractSpaceHeadRef };\n\nfunction hasErrnoCode(error: unknown, code: string): boolean {\n return error instanceof Error && (error as { code?: string }).code === code;\n}\n\n/**\n * Read the head ref (`hash` + `invariants`) for a contract space from\n * `<projectMigrationsDir>/<spaceId>/refs/head.json`.\n *\n * Returns `null` when the file does not exist (first emit). Surfaces\n * `MIGRATION.INVALID_JSON` / `MIGRATION.INVALID_REF_FILE` on a corrupt\n * `refs/head.json` so callers can distinguish \"no head ref on disk\"\n * (returns `null`) from \"head ref present but unreadable\" (throws).\n *\n * Validates the space id against `[a-z][a-z0-9_-]{0,63}` for the same\n * filesystem-safety reasons as the rest of the per-space helpers. The\n * helper is uniform across the app and extension spaces.\n */\nexport async function readContractSpaceHeadRef(\n projectMigrationsDir: string,\n spaceId: string,\n): Promise<ContractSpaceHeadRef | null> {\n assertValidSpaceId(spaceId);\n\n const filePath = join(\n spaceRefsDirectory(spaceMigrationDirectory(projectMigrationsDir, spaceId)),\n 'head.json',\n );\n\n let raw: string;\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch (error) {\n if (hasErrnoCode(error, 'ENOENT')) {\n return null;\n }\n throw error;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n throw errorInvalidJson(filePath, e instanceof Error ? e.message : String(e));\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw errorInvalidRefFile(filePath, 'expected an object');\n }\n const obj = parsed as { hash?: unknown; invariants?: unknown };\n if (typeof obj.hash !== 'string') {\n throw errorInvalidRefFile(filePath, 'expected an object with a string `hash` field');\n }\n if (!Array.isArray(obj.invariants) || obj.invariants.some((value) => typeof value !== 'string')) {\n throw errorInvalidRefFile(filePath, 'expected an object with an `invariants` array of strings');\n }\n\n return { hash: obj.hash, invariants: obj.invariants as readonly string[] };\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'pathe';\nimport { errorInvalidJson, errorMissingFile } from './errors';\nimport { assertValidSpaceId } from './space-layout';\n\nfunction hasErrnoCode(error: unknown, code: string): boolean {\n return error instanceof Error && (error as { code?: string }).code === code;\n}\n\n/**\n * Read the on-disk contract value for a contract space\n * (`<projectMigrationsDir>/<spaceId>/contract.json`). Returns the parsed\n * JSON value as `unknown` — callers that need a typed contract validate\n * via their family's `deserializeContract` to surface schema issues.\n *\n * Companion to {@link import('./read-contract-space-head-ref').readContractSpaceHeadRef}\n * — same ENOENT-throws / corrupt-file-error semantics. Returns the\n * canonical-JSON value the framework wrote during emit, so re-running\n * this helper across machines / runs yields a byte-identical value.\n */\nexport async function readContractSpaceContract(\n projectMigrationsDir: string,\n spaceId: string,\n): Promise<unknown> {\n assertValidSpaceId(spaceId);\n\n const filePath = join(projectMigrationsDir, spaceId, 'contract.json');\n\n let raw: string;\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch (error) {\n if (hasErrnoCode(error, 'ENOENT')) {\n throw errorMissingFile('contract.json', join(projectMigrationsDir, spaceId));\n }\n throw error;\n }\n\n try {\n return JSON.parse(raw);\n } catch (e) {\n throw errorInvalidJson(filePath, e instanceof Error ? e.message : String(e));\n }\n}\n"],"mappings":";;;;;AAQA,SAASA,eAAa,OAAgB,MAAuB;CAC3D,OAAO,iBAAiB,SAAU,MAA4B,SAAS;AACzE;;;;;;;;;;;;;;AAeA,eAAsB,yBACpB,sBACA,SACsC;CACtC,mBAAmB,OAAO;CAE1B,MAAM,WAAW,KACf,mBAAmB,wBAAwB,sBAAsB,OAAO,CAAC,GACzE,WACF;CAEA,IAAI;CACJ,IAAI;EACF,MAAM,MAAM,SAAS,UAAU,OAAO;CACxC,SAAS,OAAO;EACd,IAAIA,eAAa,OAAO,QAAQ,GAC9B,OAAO;EAET,MAAM;CACR;CAEA,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,GAAG;CACzB,SAAS,GAAG;EACV,MAAM,iBAAiB,UAAU,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;CAC7E;CAEA,IAAI,OAAO,WAAW,YAAY,WAAW,MAC3C,MAAM,oBAAoB,UAAU,oBAAoB;CAE1D,MAAM,MAAM;CACZ,IAAI,OAAO,IAAI,SAAS,UACtB,MAAM,oBAAoB,UAAU,+CAA+C;CAErF,IAAI,CAAC,MAAM,QAAQ,IAAI,UAAU,KAAK,IAAI,WAAW,MAAM,UAAU,OAAO,UAAU,QAAQ,GAC5F,MAAM,oBAAoB,UAAU,0DAA0D;CAGhG,OAAO;EAAE,MAAM,IAAI;EAAM,YAAY,IAAI;CAAgC;AAC3E;;;AC5DA,SAAS,aAAa,OAAgB,MAAuB;CAC3D,OAAO,iBAAiB,SAAU,MAA4B,SAAS;AACzE;;;;;;;;;;;;AAaA,eAAsB,0BACpB,sBACA,SACkB;CAClB,mBAAmB,OAAO;CAE1B,MAAM,WAAW,KAAK,sBAAsB,SAAS,eAAe;CAEpE,IAAI;CACJ,IAAI;EACF,MAAM,MAAM,SAAS,UAAU,OAAO;CACxC,SAAS,OAAO;EACd,IAAI,aAAa,OAAO,QAAQ,GAC9B,MAAM,iBAAiB,iBAAiB,KAAK,sBAAsB,OAAO,CAAC;EAE7E,MAAM;CACR;CAEA,IAAI;EACF,OAAO,KAAK,MAAM,GAAG;CACvB,SAAS,GAAG;EACV,MAAM,iBAAiB,UAAU,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;CAC7E;AACF"}
|
|
@@ -23,4 +23,4 @@ declare function deleteRef(refsDir: string, name: string): Promise<void>;
|
|
|
23
23
|
declare function resolveRef(refs: Refs, name: string): RefEntry;
|
|
24
24
|
//#endregion
|
|
25
25
|
export { readRef as a, validateRefName as c, deleteRef as i, validateRefValue as l, RefLoadProblem as n, readRefs as o, Refs as r, resolveRef as s, RefEntry as t, writeRef as u };
|
|
26
|
-
//# sourceMappingURL=refs-
|
|
26
|
+
//# sourceMappingURL=refs-C8f2IGM8.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refs-
|
|
1
|
+
{"version":3,"file":"refs-C8f2IGM8.d.mts","names":[],"sources":["../src/refs.ts"],"mappings":";UAUiB,QAAA;EAAA,SACN,IAAA;EAAA,SACA,UAAU;AAAA;AAAA,KAGT,IAAA,GAAO,QAAA,CAAS,MAAA,SAAe,QAAA;;;;;;;UAe1B,cAAA;EAAA,SACN,OAAA;EAAA,SACA,MAAM;AAAA;AAAA,iBAWD,eAAA,CAAgB,IAAY;AAAA,iBAQ5B,gBAAA,CAAiB,KAAa;AAAA,iBAsBxB,OAAA,CAAQ,OAAA,UAAiB,IAAA,WAAe,OAAO,CAAC,QAAA;AAAA,iBAmChD,QAAA,CAAS,OAAA,WAAkB,OAAO,CAAC,IAAA;AAAA,iBA4HnC,QAAA,CAAS,OAAA,UAAiB,IAAA,UAAc,KAAA,EAAO,QAAA,GAAW,OAAO;AAAA,iBAoBjE,SAAA,CAAU,OAAA,UAAiB,IAAA,WAAe,OAAO;AAAA,iBAsCvD,UAAA,CAAW,IAAA,EAAM,IAAA,EAAM,IAAA,WAAe,QAAQ"}
|
package/dist/{verify-contract-spaces-BdysZdQk.d.mts → verify-contract-spaces-T0aiJlBS.d.mts}
RENAMED
|
@@ -129,4 +129,4 @@ type VerifyContractSpacesResult = {
|
|
|
129
129
|
declare function verifyContractSpaces(inputs: VerifyContractSpacesInputs): VerifyContractSpacesResult;
|
|
130
130
|
//#endregion
|
|
131
131
|
export { VerifyContractSpacesResult as a, VerifyContractSpacesInputs as i, SpaceMarkerRecord as n, listContractSpaceDirectories as o, SpaceVerifierViolation as r, verifyContractSpaces as s, ContractSpaceHeadRecord as t };
|
|
132
|
-
//# sourceMappingURL=verify-contract-spaces-
|
|
132
|
+
//# sourceMappingURL=verify-contract-spaces-T0aiJlBS.d.mts.map
|
package/dist/{verify-contract-spaces-BdysZdQk.d.mts.map → verify-contract-spaces-T0aiJlBS.d.mts.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-contract-spaces-
|
|
1
|
+
{"version":3,"file":"verify-contract-spaces-T0aiJlBS.d.mts","names":[],"sources":["../src/verify-contract-spaces.ts"],"mappings":";;AAyBA;;;;AAEU;AAyCV;;;;AAEqB;AAQrB;;;;AAEqB;iBAvDC,4BAAA,CACpB,oBAAA,WACC,OAAO;;;;;;;UAyCO,uBAAA;EAAA,SACN,IAAA;EAAA,SACA,UAAU;AAAA;;;;;;UAQJ,iBAAA;EAAA,SACN,IAAA;EAAA,SACA,UAAU;AAAA;AAAA,UAGJ,0BAAA;EAiCL;;;;;;;EAAA,SAzBD,YAAA,EAAc,WAAA;EAiCV;;;;;EAAA,SA1BJ,eAAA;EAoCI;;;;;;;EAAA,SA3BJ,eAAA,EAAiB,WAAA,SAAoB,uBAAA;EAqCjC;;AAAW;AAG1B;EAHe,SA/BJ,iBAAA,EAAmB,WAAA,SAAoB,iBAAA;AAAA;AAAA,KAGtC,sBAAA;EAAA,SAEG,IAAA;EAAA,SACA,OAAA;EAAA,SACA,WAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,WAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,WAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,aAAA;EAAA,SACA,UAAA;EAAA,SACA,WAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,gBAAA;EAAA,SACA,gBAAA;EAAA,SACA,WAAA;AAAA;AAAA,KAGH,0BAAA;EAAA,SACG,EAAA;AAAA;EAAA,SACA,EAAA;EAAA,SAAoB,UAAA,WAAqB,sBAAsB;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiC9D,oBAAA,CACd,MAAA,EAAQ,0BAAA,GACP,0BAA0B"}
|
package/package.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/migration-tools",
|
|
3
|
-
"version": "0.11.0-dev.
|
|
3
|
+
"version": "0.11.0-dev.49",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "On-disk migration persistence, hash verification, and chain reconstruction for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/contract": "0.11.0-dev.
|
|
10
|
-
"@prisma-next/framework-components": "0.11.0-dev.
|
|
11
|
-
"@prisma-next/utils": "0.11.0-dev.
|
|
9
|
+
"@prisma-next/contract": "0.11.0-dev.49",
|
|
10
|
+
"@prisma-next/framework-components": "0.11.0-dev.49",
|
|
11
|
+
"@prisma-next/utils": "0.11.0-dev.49",
|
|
12
12
|
"arktype": "^2.2.0",
|
|
13
13
|
"pathe": "^2.0.3",
|
|
14
14
|
"prettier": "^3.8.3"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@prisma-next/tsconfig": "0.11.0-dev.
|
|
18
|
-
"@prisma-next/tsdown": "0.11.0-dev.
|
|
17
|
+
"@prisma-next/tsconfig": "0.11.0-dev.49",
|
|
18
|
+
"@prisma-next/tsdown": "0.11.0-dev.49",
|
|
19
19
|
"tsdown": "0.22.0",
|
|
20
20
|
"typescript": "5.9.3",
|
|
21
21
|
"vitest": "4.1.6"
|
|
@@ -72,10 +72,6 @@
|
|
|
72
72
|
"types": "./dist/exports/migration-list-graph-topology.d.mts",
|
|
73
73
|
"import": "./dist/exports/migration-list-graph-topology.mjs"
|
|
74
74
|
},
|
|
75
|
-
"./migration-list-graph-layout": {
|
|
76
|
-
"types": "./dist/exports/migration-list-graph-layout.d.mts",
|
|
77
|
-
"import": "./dist/exports/migration-list-graph-layout.mjs"
|
|
78
|
-
},
|
|
79
75
|
"./refs": {
|
|
80
76
|
"types": "./dist/exports/refs.d.mts",
|
|
81
77
|
"import": "./dist/exports/refs.mjs"
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type {
|
|
2
|
+
MigrationEdgeKind,
|
|
3
|
+
MigrationListGraphTopology,
|
|
4
|
+
} from '../migration-list-graph-topology';
|
|
2
5
|
export { classifyMigrationListGraphTopology } from '../migration-list-graph-topology';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { EMPTY_CONTRACT_HASH } from './constants';
|
|
2
2
|
import type { MigrationListEntry } from './migration-list-types';
|
|
3
3
|
|
|
4
|
-
export type
|
|
4
|
+
export type MigrationEdgeKind = 'forward' | 'rollback' | 'self';
|
|
5
5
|
|
|
6
|
-
export interface
|
|
7
|
-
readonly kindByMigrationHash: ReadonlyMap<string,
|
|
6
|
+
export interface MigrationListGraphTopology {
|
|
7
|
+
readonly kindByMigrationHash: ReadonlyMap<string, MigrationEdgeKind>;
|
|
8
8
|
readonly forwardInDegree: ReadonlyMap<string, number>;
|
|
9
9
|
readonly forwardOutDegree: ReadonlyMap<string, number>;
|
|
10
10
|
}
|
|
@@ -29,9 +29,9 @@ function bumpDegree(map: Map<string, number>, key: string): void {
|
|
|
29
29
|
|
|
30
30
|
export function classifyMigrationListGraphTopology(
|
|
31
31
|
entries: readonly MigrationListEntry[],
|
|
32
|
-
):
|
|
32
|
+
): MigrationListGraphTopology {
|
|
33
33
|
const nodes = new Set<string>();
|
|
34
|
-
const kindByMigrationHash = new Map<string,
|
|
34
|
+
const kindByMigrationHash = new Map<string, MigrationEdgeKind>();
|
|
35
35
|
const outgoingByFrom = new Map<string, NonSelfEdge[]>();
|
|
36
36
|
|
|
37
37
|
for (const entry of entries) {
|
|
@@ -133,7 +133,9 @@ export function classifyMigrationListGraphTopology(
|
|
|
133
133
|
for (const root of dfsRoots) {
|
|
134
134
|
runDfsFrom(root);
|
|
135
135
|
}
|
|
136
|
-
|
|
136
|
+
const remainingWhite = [...nodes].filter((node) => color.get(node) === WHITE);
|
|
137
|
+
remainingWhite.sort((a, b) => a.localeCompare(b));
|
|
138
|
+
for (const root of remainingWhite) {
|
|
137
139
|
runDfsFrom(root);
|
|
138
140
|
}
|
|
139
141
|
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { t as MigrationListEntry } from "../migration-list-types-0YjFETIv.mjs";
|
|
2
|
-
import { t as EdgeKind } from "../migration-list-graph-topology-Be1d8Y89.mjs";
|
|
3
|
-
|
|
4
|
-
//#region src/migration-list-graph-layout.d.ts
|
|
5
|
-
type ConnectorKind = 'fanBelow' | 'joinBelow';
|
|
6
|
-
interface MigrationLayoutRow {
|
|
7
|
-
readonly kind: 'migration';
|
|
8
|
-
readonly entry: MigrationListEntry;
|
|
9
|
-
readonly edgeKind: EdgeKind;
|
|
10
|
-
readonly laneIndex: number;
|
|
11
|
-
readonly passThroughLanes: readonly number[];
|
|
12
|
-
readonly woven: boolean;
|
|
13
|
-
}
|
|
14
|
-
interface NodeLineLayoutRow {
|
|
15
|
-
readonly kind: 'nodeLine';
|
|
16
|
-
readonly contractHash: string;
|
|
17
|
-
readonly laneIndex: number;
|
|
18
|
-
}
|
|
19
|
-
interface ConnectorLayoutRow {
|
|
20
|
-
readonly kind: 'connector';
|
|
21
|
-
readonly connectorKind: ConnectorKind;
|
|
22
|
-
readonly contractHash: string;
|
|
23
|
-
readonly startLane: number;
|
|
24
|
-
readonly endLane: number;
|
|
25
|
-
readonly branchCount: number;
|
|
26
|
-
}
|
|
27
|
-
type LayoutRow = MigrationLayoutRow | NodeLineLayoutRow | ConnectorLayoutRow;
|
|
28
|
-
interface MigrationListGraphLayout {
|
|
29
|
-
readonly rows: readonly LayoutRow[];
|
|
30
|
-
}
|
|
31
|
-
declare function computeMigrationListGraphLayout(entries: readonly MigrationListEntry[]): MigrationListGraphLayout;
|
|
32
|
-
//#endregion
|
|
33
|
-
export { type ConnectorKind, type ConnectorLayoutRow, type LayoutRow, type MigrationLayoutRow, type MigrationListGraphLayout, type NodeLineLayoutRow, computeMigrationListGraphLayout };
|
|
34
|
-
//# sourceMappingURL=migration-list-graph-layout.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migration-list-graph-layout.d.mts","names":[],"sources":["../../src/migration-list-graph-layout.ts"],"mappings":";;;;KAIY,aAAA;AAAA,UAEK,kBAAA;EAAA,SACN,IAAA;EAAA,SACA,KAAA,EAAO,kBAAA;EAAA,SACP,QAAA,EAAU,QAAQ;EAAA,SAClB,SAAA;EAAA,SACA,gBAAA;EAAA,SACA,KAAA;AAAA;AAAA,UAGM,iBAAA;EAAA,SACN,IAAA;EAAA,SACA,YAAA;EAAA,SACA,SAAA;AAAA;AAAA,UAGM,kBAAA;EAAA,SACN,IAAA;EAAA,SACA,aAAA,EAAe,aAAa;EAAA,SAC5B,YAAA;EAAA,SACA,SAAA;EAAA,SACA,OAAA;EAAA,SACA,WAAA;AAAA;AAAA,KAGC,SAAA,GAAY,kBAAA,GAAqB,iBAAA,GAAoB,kBAAA;AAAA,UAEhD,wBAAA;EAAA,SACN,IAAA,WAAe,SAAS;AAAA;AAAA,iBAoDnB,+BAAA,CACd,OAAA,WAAkB,kBAAA,KACjB,wBAAwB"}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import "../constants-DWV9_o2Z.mjs";
|
|
2
|
-
import { t as classifyMigrationListGraphTopology } from "../migration-list-graph-topology-BtFzbZ9L.mjs";
|
|
3
|
-
//#region src/migration-list-graph-layout.ts
|
|
4
|
-
function canonicalFrom(from) {
|
|
5
|
-
return from ?? "sha256:empty";
|
|
6
|
-
}
|
|
7
|
-
function canonicalTo(entry) {
|
|
8
|
-
return entry.to;
|
|
9
|
-
}
|
|
10
|
-
function forwardInDegree(topology, hash) {
|
|
11
|
-
return topology.forwardInDegree.get(hash) ?? 0;
|
|
12
|
-
}
|
|
13
|
-
function forwardOutDegree(topology, hash) {
|
|
14
|
-
return topology.forwardOutDegree.get(hash) ?? 0;
|
|
15
|
-
}
|
|
16
|
-
function buildForwardProducersByTo(entries, kindByMigrationHash) {
|
|
17
|
-
const byTo = /* @__PURE__ */ new Map();
|
|
18
|
-
for (const entry of entries) {
|
|
19
|
-
if (kindByMigrationHash.get(entry.migrationHash) !== "forward") continue;
|
|
20
|
-
const to = canonicalTo(entry);
|
|
21
|
-
const bucket = byTo.get(to);
|
|
22
|
-
if (bucket) bucket.push(entry);
|
|
23
|
-
else byTo.set(to, [entry]);
|
|
24
|
-
}
|
|
25
|
-
return byTo;
|
|
26
|
-
}
|
|
27
|
-
function countForwardProducersTo(forwardProducersByTo, contract) {
|
|
28
|
-
return forwardProducersByTo.get(contract)?.length ?? 0;
|
|
29
|
-
}
|
|
30
|
-
function computeMigrationListGraphLayout(entries) {
|
|
31
|
-
const topology = classifyMigrationListGraphTopology(entries);
|
|
32
|
-
const { kindByMigrationHash } = topology;
|
|
33
|
-
const forwardProducersByTo = buildForwardProducersByTo(entries, kindByMigrationHash);
|
|
34
|
-
const convergencesEmitted = /* @__PURE__ */ new Set();
|
|
35
|
-
const producerLaneByHash = /* @__PURE__ */ new Map();
|
|
36
|
-
const lanes = [];
|
|
37
|
-
const rows = [];
|
|
38
|
-
function emitNodeLine(contractHash) {
|
|
39
|
-
rows.push({
|
|
40
|
-
kind: "nodeLine",
|
|
41
|
-
contractHash,
|
|
42
|
-
laneIndex: 0
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
function emitConnector(connectorKind, contractHash, startLane, endLane, branchCount) {
|
|
46
|
-
rows.push({
|
|
47
|
-
kind: "connector",
|
|
48
|
-
connectorKind,
|
|
49
|
-
contractHash,
|
|
50
|
-
startLane,
|
|
51
|
-
endLane,
|
|
52
|
-
branchCount
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
function activeLaneIndices() {
|
|
56
|
-
const indices = [];
|
|
57
|
-
for (let index = 0; index < lanes.length; index++) if (lanes[index]?.active) indices.push(index);
|
|
58
|
-
return indices;
|
|
59
|
-
}
|
|
60
|
-
function lanesWanting(contract) {
|
|
61
|
-
const indices = [];
|
|
62
|
-
for (let index = 0; index < lanes.length; index++) {
|
|
63
|
-
const lane = lanes[index];
|
|
64
|
-
if (lane?.active && lane.want === contract) indices.push(index);
|
|
65
|
-
}
|
|
66
|
-
return indices;
|
|
67
|
-
}
|
|
68
|
-
function ensureLane(index) {
|
|
69
|
-
while (lanes.length <= index) lanes.push({
|
|
70
|
-
want: "",
|
|
71
|
-
active: false
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
function openLaneAtRight(want) {
|
|
75
|
-
const index = lanes.length;
|
|
76
|
-
lanes.push({
|
|
77
|
-
want,
|
|
78
|
-
active: true
|
|
79
|
-
});
|
|
80
|
-
return index;
|
|
81
|
-
}
|
|
82
|
-
function closeLane(index) {
|
|
83
|
-
ensureLane(index);
|
|
84
|
-
const lane = lanes[index];
|
|
85
|
-
if (lane) lane.active = false;
|
|
86
|
-
}
|
|
87
|
-
function emitJoinBelow(contractHash, laneIndices) {
|
|
88
|
-
if (laneIndices.length < 2) return;
|
|
89
|
-
const startLane = Math.min(...laneIndices);
|
|
90
|
-
emitConnector("joinBelow", contractHash, startLane, Math.max(...laneIndices), laneIndices.length);
|
|
91
|
-
for (const index of laneIndices) if (index !== startLane) closeLane(index);
|
|
92
|
-
}
|
|
93
|
-
function emitConvergencePreamble(contract) {
|
|
94
|
-
if (convergencesEmitted.has(contract)) return;
|
|
95
|
-
if (forwardInDegree(topology, contract) < 2) return;
|
|
96
|
-
const consumersWanting = lanesWanting(contract);
|
|
97
|
-
if (forwardOutDegree(topology, contract) >= 2 && consumersWanting.length >= 2) emitJoinBelow(contract, consumersWanting);
|
|
98
|
-
emitNodeLine(contract);
|
|
99
|
-
const producers = forwardProducersByTo.get(contract) ?? [];
|
|
100
|
-
if (producers.length >= 2) emitConnector("fanBelow", contract, 0, producers.length - 1, producers.length);
|
|
101
|
-
for (const [producerIndex, producer] of producers.entries()) {
|
|
102
|
-
ensureLane(producerIndex);
|
|
103
|
-
lanes[producerIndex] = {
|
|
104
|
-
want: canonicalFrom(producer.from),
|
|
105
|
-
active: true
|
|
106
|
-
};
|
|
107
|
-
producerLaneByHash.set(producer.migrationHash, producerIndex);
|
|
108
|
-
}
|
|
109
|
-
convergencesEmitted.add(contract);
|
|
110
|
-
}
|
|
111
|
-
function assignProducerLane(entry) {
|
|
112
|
-
const preset = producerLaneByHash.get(entry.migrationHash);
|
|
113
|
-
if (preset !== void 0) return preset;
|
|
114
|
-
}
|
|
115
|
-
function placeWoven(entry, edgeKind, laneIndex) {
|
|
116
|
-
const passThroughLanes = activeLaneIndices().filter((index) => index !== laneIndex);
|
|
117
|
-
rows.push({
|
|
118
|
-
kind: "migration",
|
|
119
|
-
entry,
|
|
120
|
-
edgeKind,
|
|
121
|
-
laneIndex,
|
|
122
|
-
passThroughLanes,
|
|
123
|
-
woven: true
|
|
124
|
-
});
|
|
125
|
-
ensureLane(laneIndex);
|
|
126
|
-
lanes[laneIndex] = {
|
|
127
|
-
want: canonicalFrom(entry.from),
|
|
128
|
-
active: true
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
function placeUnwoven(entry, edgeKind) {
|
|
132
|
-
const passThroughLanes = activeLaneIndices();
|
|
133
|
-
const laneIndex = passThroughLanes.length === 0 ? 0 : Math.max(...passThroughLanes) + 1;
|
|
134
|
-
rows.push({
|
|
135
|
-
kind: "migration",
|
|
136
|
-
entry,
|
|
137
|
-
edgeKind,
|
|
138
|
-
laneIndex,
|
|
139
|
-
passThroughLanes,
|
|
140
|
-
woven: false
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
for (const entry of entries) {
|
|
144
|
-
const edgeKind = kindByMigrationHash.get(entry.migrationHash) ?? "forward";
|
|
145
|
-
const to = canonicalTo(entry);
|
|
146
|
-
if (edgeKind !== "forward") {
|
|
147
|
-
placeUnwoven(entry, edgeKind);
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
if (forwardInDegree(topology, to) >= 2 && !convergencesEmitted.has(to)) emitConvergencePreamble(to);
|
|
151
|
-
const presetLane = assignProducerLane(entry);
|
|
152
|
-
const wantingTo = lanesWanting(to);
|
|
153
|
-
if (wantingTo.length >= 2 && countForwardProducersTo(forwardProducersByTo, to) === 1) emitJoinBelow(to, wantingTo);
|
|
154
|
-
if (presetLane !== void 0) {
|
|
155
|
-
placeWoven(entry, edgeKind, presetLane);
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
const firstWanting = wantingTo[0];
|
|
159
|
-
if (firstWanting !== void 0) {
|
|
160
|
-
placeWoven(entry, edgeKind, firstWanting);
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
placeWoven(entry, edgeKind, openLaneAtRight(canonicalFrom(entry.from)));
|
|
164
|
-
}
|
|
165
|
-
return { rows };
|
|
166
|
-
}
|
|
167
|
-
//#endregion
|
|
168
|
-
export { computeMigrationListGraphLayout };
|
|
169
|
-
|
|
170
|
-
//# sourceMappingURL=migration-list-graph-layout.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migration-list-graph-layout.mjs","names":[],"sources":["../../src/migration-list-graph-layout.ts"],"sourcesContent":["import { EMPTY_CONTRACT_HASH } from './constants';\nimport { classifyMigrationListGraphTopology, type EdgeKind } from './migration-list-graph-topology';\nimport type { MigrationListEntry } from './migration-list-types';\n\nexport type ConnectorKind = 'fanBelow' | 'joinBelow';\n\nexport interface MigrationLayoutRow {\n readonly kind: 'migration';\n readonly entry: MigrationListEntry;\n readonly edgeKind: EdgeKind;\n readonly laneIndex: number;\n readonly passThroughLanes: readonly number[];\n readonly woven: boolean;\n}\n\nexport interface NodeLineLayoutRow {\n readonly kind: 'nodeLine';\n readonly contractHash: string;\n readonly laneIndex: number;\n}\n\nexport interface ConnectorLayoutRow {\n readonly kind: 'connector';\n readonly connectorKind: ConnectorKind;\n readonly contractHash: string;\n readonly startLane: number;\n readonly endLane: number;\n readonly branchCount: number;\n}\n\nexport type LayoutRow = MigrationLayoutRow | NodeLineLayoutRow | ConnectorLayoutRow;\n\nexport interface MigrationListGraphLayout {\n readonly rows: readonly LayoutRow[];\n}\n\ninterface LaneState {\n want: string;\n active: boolean;\n}\n\nfunction canonicalFrom(from: string | null): string {\n return from ?? EMPTY_CONTRACT_HASH;\n}\n\nfunction canonicalTo(entry: MigrationListEntry): string {\n return entry.to;\n}\n\nfunction forwardInDegree(\n topology: ReturnType<typeof classifyMigrationListGraphTopology>,\n hash: string,\n): number {\n return topology.forwardInDegree.get(hash) ?? 0;\n}\n\nfunction forwardOutDegree(\n topology: ReturnType<typeof classifyMigrationListGraphTopology>,\n hash: string,\n): number {\n return topology.forwardOutDegree.get(hash) ?? 0;\n}\n\nfunction buildForwardProducersByTo(\n entries: readonly MigrationListEntry[],\n kindByMigrationHash: ReadonlyMap<string, EdgeKind>,\n): Map<string, MigrationListEntry[]> {\n const byTo = new Map<string, MigrationListEntry[]>();\n for (const entry of entries) {\n if (kindByMigrationHash.get(entry.migrationHash) !== 'forward') continue;\n const to = canonicalTo(entry);\n const bucket = byTo.get(to);\n if (bucket) bucket.push(entry);\n else byTo.set(to, [entry]);\n }\n return byTo;\n}\n\nfunction countForwardProducersTo(\n forwardProducersByTo: Map<string, MigrationListEntry[]>,\n contract: string,\n): number {\n return forwardProducersByTo.get(contract)?.length ?? 0;\n}\n\nexport function computeMigrationListGraphLayout(\n entries: readonly MigrationListEntry[],\n): MigrationListGraphLayout {\n const topology = classifyMigrationListGraphTopology(entries);\n const { kindByMigrationHash } = topology;\n const forwardProducersByTo = buildForwardProducersByTo(entries, kindByMigrationHash);\n const convergencesEmitted = new Set<string>();\n const producerLaneByHash = new Map<string, number>();\n const lanes: LaneState[] = [];\n const rows: LayoutRow[] = [];\n\n function emitNodeLine(contractHash: string): void {\n rows.push({ kind: 'nodeLine', contractHash, laneIndex: 0 });\n }\n\n function emitConnector(\n connectorKind: ConnectorKind,\n contractHash: string,\n startLane: number,\n endLane: number,\n branchCount: number,\n ): void {\n rows.push({\n kind: 'connector',\n connectorKind,\n contractHash,\n startLane,\n endLane,\n branchCount,\n });\n }\n\n function activeLaneIndices(): number[] {\n const indices: number[] = [];\n for (let index = 0; index < lanes.length; index++) {\n if (lanes[index]?.active) indices.push(index);\n }\n return indices;\n }\n\n function lanesWanting(contract: string): number[] {\n const indices: number[] = [];\n for (let index = 0; index < lanes.length; index++) {\n const lane = lanes[index];\n if (lane?.active && lane.want === contract) indices.push(index);\n }\n return indices;\n }\n\n function ensureLane(index: number): void {\n while (lanes.length <= index) {\n lanes.push({ want: '', active: false });\n }\n }\n\n function openLaneAtRight(want: string): number {\n const index = lanes.length;\n lanes.push({ want, active: true });\n return index;\n }\n\n function closeLane(index: number): void {\n ensureLane(index);\n const lane = lanes[index];\n if (lane) lane.active = false;\n }\n\n function emitJoinBelow(contractHash: string, laneIndices: readonly number[]): void {\n if (laneIndices.length < 2) return;\n const startLane = Math.min(...laneIndices);\n const endLane = Math.max(...laneIndices);\n emitConnector('joinBelow', contractHash, startLane, endLane, laneIndices.length);\n for (const index of laneIndices) {\n if (index !== startLane) closeLane(index);\n }\n }\n\n function emitConvergencePreamble(contract: string): void {\n if (convergencesEmitted.has(contract)) return;\n if (forwardInDegree(topology, contract) < 2) return;\n\n const consumersWanting = lanesWanting(contract);\n if (forwardOutDegree(topology, contract) >= 2 && consumersWanting.length >= 2) {\n emitJoinBelow(contract, consumersWanting);\n }\n\n emitNodeLine(contract);\n const producers = forwardProducersByTo.get(contract) ?? [];\n if (producers.length >= 2) {\n emitConnector('fanBelow', contract, 0, producers.length - 1, producers.length);\n }\n\n for (const [producerIndex, producer] of producers.entries()) {\n ensureLane(producerIndex);\n lanes[producerIndex] = { want: canonicalFrom(producer.from), active: true };\n producerLaneByHash.set(producer.migrationHash, producerIndex);\n }\n\n convergencesEmitted.add(contract);\n }\n\n function assignProducerLane(entry: MigrationListEntry): number | undefined {\n const preset = producerLaneByHash.get(entry.migrationHash);\n if (preset !== undefined) return preset;\n return undefined;\n }\n\n function placeWoven(entry: MigrationListEntry, edgeKind: EdgeKind, laneIndex: number): void {\n const passThroughLanes = activeLaneIndices().filter((index) => index !== laneIndex);\n rows.push({\n kind: 'migration',\n entry,\n edgeKind,\n laneIndex,\n passThroughLanes,\n woven: true,\n });\n ensureLane(laneIndex);\n lanes[laneIndex] = { want: canonicalFrom(entry.from), active: true };\n }\n\n function placeUnwoven(entry: MigrationListEntry, edgeKind: EdgeKind): void {\n const passThroughLanes = activeLaneIndices();\n const laneIndex = passThroughLanes.length === 0 ? 0 : Math.max(...passThroughLanes) + 1;\n rows.push({\n kind: 'migration',\n entry,\n edgeKind,\n laneIndex,\n passThroughLanes,\n woven: false,\n });\n }\n\n for (const entry of entries) {\n const edgeKind = kindByMigrationHash.get(entry.migrationHash) ?? 'forward';\n const to = canonicalTo(entry);\n\n if (edgeKind !== 'forward') {\n placeUnwoven(entry, edgeKind);\n continue;\n }\n\n if (forwardInDegree(topology, to) >= 2 && !convergencesEmitted.has(to)) {\n emitConvergencePreamble(to);\n }\n\n const presetLane = assignProducerLane(entry);\n const wantingTo = lanesWanting(to);\n\n if (wantingTo.length >= 2 && countForwardProducersTo(forwardProducersByTo, to) === 1) {\n emitJoinBelow(to, wantingTo);\n }\n\n if (presetLane !== undefined) {\n placeWoven(entry, edgeKind, presetLane);\n continue;\n }\n\n const firstWanting = wantingTo[0];\n if (firstWanting !== undefined) {\n placeWoven(entry, edgeKind, firstWanting);\n continue;\n }\n\n const tipLaneIndex = openLaneAtRight(canonicalFrom(entry.from));\n placeWoven(entry, edgeKind, tipLaneIndex);\n }\n\n return { rows };\n}\n"],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { t as MigrationListEntry } from "./migration-list-types-0YjFETIv.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/migration-list-graph-topology.d.ts
|
|
4
|
-
type EdgeKind = 'forward' | 'rollback' | 'self';
|
|
5
|
-
interface MigrationGraphTopology {
|
|
6
|
-
readonly kindByMigrationHash: ReadonlyMap<string, EdgeKind>;
|
|
7
|
-
readonly forwardInDegree: ReadonlyMap<string, number>;
|
|
8
|
-
readonly forwardOutDegree: ReadonlyMap<string, number>;
|
|
9
|
-
}
|
|
10
|
-
declare function classifyMigrationListGraphTopology(entries: readonly MigrationListEntry[]): MigrationGraphTopology;
|
|
11
|
-
//#endregion
|
|
12
|
-
export { MigrationGraphTopology as n, classifyMigrationListGraphTopology as r, EdgeKind as t };
|
|
13
|
-
//# sourceMappingURL=migration-list-graph-topology-Be1d8Y89.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migration-list-graph-topology-Be1d8Y89.d.mts","names":[],"sources":["../src/migration-list-graph-topology.ts"],"mappings":";;;KAGY,QAAA;AAAA,UAEK,sBAAA;EAAA,SACN,mBAAA,EAAqB,WAAA,SAAoB,QAAA;EAAA,SACzC,eAAA,EAAiB,WAAA;EAAA,SACjB,gBAAA,EAAkB,WAAA;AAAA;AAAA,iBAqBb,kCAAA,CACd,OAAA,WAAkB,kBAAA,KACjB,sBAAsB"}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import "./constants-DWV9_o2Z.mjs";
|
|
2
|
-
//#region src/migration-list-graph-topology.ts
|
|
3
|
-
function canonicalFrom(from) {
|
|
4
|
-
return from ?? "sha256:empty";
|
|
5
|
-
}
|
|
6
|
-
function compareDirNameDesc(a, b) {
|
|
7
|
-
return b.dirName.localeCompare(a.dirName);
|
|
8
|
-
}
|
|
9
|
-
function bumpDegree(map, key) {
|
|
10
|
-
map.set(key, (map.get(key) ?? 0) + 1);
|
|
11
|
-
}
|
|
12
|
-
function classifyMigrationListGraphTopology(entries) {
|
|
13
|
-
const nodes = /* @__PURE__ */ new Set();
|
|
14
|
-
const kindByMigrationHash = /* @__PURE__ */ new Map();
|
|
15
|
-
const outgoingByFrom = /* @__PURE__ */ new Map();
|
|
16
|
-
for (const entry of entries) {
|
|
17
|
-
const from = canonicalFrom(entry.from);
|
|
18
|
-
const to = entry.to;
|
|
19
|
-
nodes.add(from);
|
|
20
|
-
nodes.add(to);
|
|
21
|
-
if (from === to) {
|
|
22
|
-
kindByMigrationHash.set(entry.migrationHash, "self");
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
const bucket = outgoingByFrom.get(from);
|
|
26
|
-
const edge = {
|
|
27
|
-
entry,
|
|
28
|
-
from,
|
|
29
|
-
to
|
|
30
|
-
};
|
|
31
|
-
if (bucket) bucket.push(edge);
|
|
32
|
-
else outgoingByFrom.set(from, [edge]);
|
|
33
|
-
}
|
|
34
|
-
for (const bucket of outgoingByFrom.values()) bucket.sort((a, b) => compareDirNameDesc(a.entry, b.entry));
|
|
35
|
-
const nonSelfInDegree = /* @__PURE__ */ new Map();
|
|
36
|
-
for (const node of nodes) nonSelfInDegree.set(node, 0);
|
|
37
|
-
for (const bucket of outgoingByFrom.values()) for (const edge of bucket) bumpDegree(nonSelfInDegree, edge.to);
|
|
38
|
-
const dfsRoots = [];
|
|
39
|
-
for (const node of nodes) if ((nonSelfInDegree.get(node) ?? 0) === 0) dfsRoots.push(node);
|
|
40
|
-
dfsRoots.sort((a, b) => {
|
|
41
|
-
if (a === "sha256:empty") return -1;
|
|
42
|
-
if (b === "sha256:empty") return 1;
|
|
43
|
-
return a.localeCompare(b);
|
|
44
|
-
});
|
|
45
|
-
if (dfsRoots.length === 0) dfsRoots.push(...[...nodes].sort((a, b) => a.localeCompare(b)));
|
|
46
|
-
const WHITE = 0;
|
|
47
|
-
const GRAY = 1;
|
|
48
|
-
const BLACK = 2;
|
|
49
|
-
const color = /* @__PURE__ */ new Map();
|
|
50
|
-
for (const node of nodes) color.set(node, WHITE);
|
|
51
|
-
const stack = [];
|
|
52
|
-
function pushFrame(node) {
|
|
53
|
-
color.set(node, GRAY);
|
|
54
|
-
stack.push({
|
|
55
|
-
node,
|
|
56
|
-
outgoing: outgoingByFrom.get(node) ?? [],
|
|
57
|
-
index: 0
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
function runDfsFrom(root) {
|
|
61
|
-
if (color.get(root) !== WHITE) return;
|
|
62
|
-
pushFrame(root);
|
|
63
|
-
while (stack.length > 0) {
|
|
64
|
-
const frame = stack[stack.length - 1];
|
|
65
|
-
if (frame === void 0) break;
|
|
66
|
-
if (frame.index >= frame.outgoing.length) {
|
|
67
|
-
color.set(frame.node, BLACK);
|
|
68
|
-
stack.pop();
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
const edge = frame.outgoing[frame.index];
|
|
72
|
-
frame.index += 1;
|
|
73
|
-
if (edge === void 0) continue;
|
|
74
|
-
const v = edge.to;
|
|
75
|
-
const vColor = color.get(v);
|
|
76
|
-
if (vColor === GRAY) kindByMigrationHash.set(edge.entry.migrationHash, "rollback");
|
|
77
|
-
else {
|
|
78
|
-
kindByMigrationHash.set(edge.entry.migrationHash, "forward");
|
|
79
|
-
if (vColor === WHITE) pushFrame(v);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
for (const root of dfsRoots) runDfsFrom(root);
|
|
84
|
-
for (const root of nodes) runDfsFrom(root);
|
|
85
|
-
const forwardInDegree = /* @__PURE__ */ new Map();
|
|
86
|
-
const forwardOutDegree = /* @__PURE__ */ new Map();
|
|
87
|
-
for (const entry of entries) {
|
|
88
|
-
if (kindByMigrationHash.get(entry.migrationHash) !== "forward") continue;
|
|
89
|
-
const from = canonicalFrom(entry.from);
|
|
90
|
-
const to = entry.to;
|
|
91
|
-
bumpDegree(forwardOutDegree, from);
|
|
92
|
-
bumpDegree(forwardInDegree, to);
|
|
93
|
-
}
|
|
94
|
-
return {
|
|
95
|
-
kindByMigrationHash,
|
|
96
|
-
forwardInDegree,
|
|
97
|
-
forwardOutDegree
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
//#endregion
|
|
101
|
-
export { classifyMigrationListGraphTopology as t };
|
|
102
|
-
|
|
103
|
-
//# sourceMappingURL=migration-list-graph-topology-BtFzbZ9L.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migration-list-graph-topology-BtFzbZ9L.mjs","names":[],"sources":["../src/migration-list-graph-topology.ts"],"sourcesContent":["import { EMPTY_CONTRACT_HASH } from './constants';\nimport type { MigrationListEntry } from './migration-list-types';\n\nexport type EdgeKind = 'forward' | 'rollback' | 'self';\n\nexport interface MigrationGraphTopology {\n readonly kindByMigrationHash: ReadonlyMap<string, EdgeKind>;\n readonly forwardInDegree: ReadonlyMap<string, number>;\n readonly forwardOutDegree: ReadonlyMap<string, number>;\n}\n\ninterface NonSelfEdge {\n readonly entry: MigrationListEntry;\n readonly from: string;\n readonly to: string;\n}\n\nfunction canonicalFrom(from: string | null): string {\n return from ?? EMPTY_CONTRACT_HASH;\n}\n\nfunction compareDirNameDesc(a: MigrationListEntry, b: MigrationListEntry): number {\n return b.dirName.localeCompare(a.dirName);\n}\n\nfunction bumpDegree(map: Map<string, number>, key: string): void {\n map.set(key, (map.get(key) ?? 0) + 1);\n}\n\nexport function classifyMigrationListGraphTopology(\n entries: readonly MigrationListEntry[],\n): MigrationGraphTopology {\n const nodes = new Set<string>();\n const kindByMigrationHash = new Map<string, EdgeKind>();\n const outgoingByFrom = new Map<string, NonSelfEdge[]>();\n\n for (const entry of entries) {\n const from = canonicalFrom(entry.from);\n const to = entry.to;\n nodes.add(from);\n nodes.add(to);\n\n if (from === to) {\n kindByMigrationHash.set(entry.migrationHash, 'self');\n continue;\n }\n\n const bucket = outgoingByFrom.get(from);\n const edge: NonSelfEdge = { entry, from, to };\n if (bucket) bucket.push(edge);\n else outgoingByFrom.set(from, [edge]);\n }\n\n for (const bucket of outgoingByFrom.values()) {\n bucket.sort((a, b) => compareDirNameDesc(a.entry, b.entry));\n }\n\n const nonSelfInDegree = new Map<string, number>();\n for (const node of nodes) {\n nonSelfInDegree.set(node, 0);\n }\n for (const bucket of outgoingByFrom.values()) {\n for (const edge of bucket) {\n bumpDegree(nonSelfInDegree, edge.to);\n }\n }\n\n const dfsRoots: string[] = [];\n for (const node of nodes) {\n if ((nonSelfInDegree.get(node) ?? 0) === 0) {\n dfsRoots.push(node);\n }\n }\n dfsRoots.sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n if (dfsRoots.length === 0) {\n dfsRoots.push(...[...nodes].sort((a, b) => a.localeCompare(b)));\n }\n\n const WHITE = 0;\n const GRAY = 1;\n const BLACK = 2;\n const color = new Map<string, number>();\n for (const node of nodes) {\n color.set(node, WHITE);\n }\n\n interface Frame {\n node: string;\n outgoing: readonly NonSelfEdge[];\n index: number;\n }\n const stack: Frame[] = [];\n\n function pushFrame(node: string): void {\n color.set(node, GRAY);\n stack.push({ node, outgoing: outgoingByFrom.get(node) ?? [], index: 0 });\n }\n\n function runDfsFrom(root: string): void {\n if (color.get(root) !== WHITE) return;\n pushFrame(root);\n\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n if (frame === undefined) break;\n if (frame.index >= frame.outgoing.length) {\n color.set(frame.node, BLACK);\n stack.pop();\n continue;\n }\n\n const edge = frame.outgoing[frame.index];\n frame.index += 1;\n if (edge === undefined) continue;\n\n const v = edge.to;\n const vColor = color.get(v);\n if (vColor === GRAY) {\n kindByMigrationHash.set(edge.entry.migrationHash, 'rollback');\n } else {\n kindByMigrationHash.set(edge.entry.migrationHash, 'forward');\n if (vColor === WHITE) {\n pushFrame(v);\n }\n }\n }\n }\n\n for (const root of dfsRoots) {\n runDfsFrom(root);\n }\n for (const root of nodes) {\n runDfsFrom(root);\n }\n\n const forwardInDegree = new Map<string, number>();\n const forwardOutDegree = new Map<string, number>();\n\n for (const entry of entries) {\n if (kindByMigrationHash.get(entry.migrationHash) !== 'forward') continue;\n const from = canonicalFrom(entry.from);\n const to = entry.to;\n bumpDegree(forwardOutDegree, from);\n bumpDegree(forwardInDegree, to);\n }\n\n return {\n kindByMigrationHash,\n forwardInDegree,\n forwardOutDegree,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { EMPTY_CONTRACT_HASH } from './constants';
|
|
2
|
-
import { classifyMigrationListGraphTopology, type EdgeKind } from './migration-list-graph-topology';
|
|
3
|
-
import type { MigrationListEntry } from './migration-list-types';
|
|
4
|
-
|
|
5
|
-
export type ConnectorKind = 'fanBelow' | 'joinBelow';
|
|
6
|
-
|
|
7
|
-
export interface MigrationLayoutRow {
|
|
8
|
-
readonly kind: 'migration';
|
|
9
|
-
readonly entry: MigrationListEntry;
|
|
10
|
-
readonly edgeKind: EdgeKind;
|
|
11
|
-
readonly laneIndex: number;
|
|
12
|
-
readonly passThroughLanes: readonly number[];
|
|
13
|
-
readonly woven: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface NodeLineLayoutRow {
|
|
17
|
-
readonly kind: 'nodeLine';
|
|
18
|
-
readonly contractHash: string;
|
|
19
|
-
readonly laneIndex: number;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface ConnectorLayoutRow {
|
|
23
|
-
readonly kind: 'connector';
|
|
24
|
-
readonly connectorKind: ConnectorKind;
|
|
25
|
-
readonly contractHash: string;
|
|
26
|
-
readonly startLane: number;
|
|
27
|
-
readonly endLane: number;
|
|
28
|
-
readonly branchCount: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type LayoutRow = MigrationLayoutRow | NodeLineLayoutRow | ConnectorLayoutRow;
|
|
32
|
-
|
|
33
|
-
export interface MigrationListGraphLayout {
|
|
34
|
-
readonly rows: readonly LayoutRow[];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface LaneState {
|
|
38
|
-
want: string;
|
|
39
|
-
active: boolean;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function canonicalFrom(from: string | null): string {
|
|
43
|
-
return from ?? EMPTY_CONTRACT_HASH;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function canonicalTo(entry: MigrationListEntry): string {
|
|
47
|
-
return entry.to;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function forwardInDegree(
|
|
51
|
-
topology: ReturnType<typeof classifyMigrationListGraphTopology>,
|
|
52
|
-
hash: string,
|
|
53
|
-
): number {
|
|
54
|
-
return topology.forwardInDegree.get(hash) ?? 0;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function forwardOutDegree(
|
|
58
|
-
topology: ReturnType<typeof classifyMigrationListGraphTopology>,
|
|
59
|
-
hash: string,
|
|
60
|
-
): number {
|
|
61
|
-
return topology.forwardOutDegree.get(hash) ?? 0;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function buildForwardProducersByTo(
|
|
65
|
-
entries: readonly MigrationListEntry[],
|
|
66
|
-
kindByMigrationHash: ReadonlyMap<string, EdgeKind>,
|
|
67
|
-
): Map<string, MigrationListEntry[]> {
|
|
68
|
-
const byTo = new Map<string, MigrationListEntry[]>();
|
|
69
|
-
for (const entry of entries) {
|
|
70
|
-
if (kindByMigrationHash.get(entry.migrationHash) !== 'forward') continue;
|
|
71
|
-
const to = canonicalTo(entry);
|
|
72
|
-
const bucket = byTo.get(to);
|
|
73
|
-
if (bucket) bucket.push(entry);
|
|
74
|
-
else byTo.set(to, [entry]);
|
|
75
|
-
}
|
|
76
|
-
return byTo;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function countForwardProducersTo(
|
|
80
|
-
forwardProducersByTo: Map<string, MigrationListEntry[]>,
|
|
81
|
-
contract: string,
|
|
82
|
-
): number {
|
|
83
|
-
return forwardProducersByTo.get(contract)?.length ?? 0;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function computeMigrationListGraphLayout(
|
|
87
|
-
entries: readonly MigrationListEntry[],
|
|
88
|
-
): MigrationListGraphLayout {
|
|
89
|
-
const topology = classifyMigrationListGraphTopology(entries);
|
|
90
|
-
const { kindByMigrationHash } = topology;
|
|
91
|
-
const forwardProducersByTo = buildForwardProducersByTo(entries, kindByMigrationHash);
|
|
92
|
-
const convergencesEmitted = new Set<string>();
|
|
93
|
-
const producerLaneByHash = new Map<string, number>();
|
|
94
|
-
const lanes: LaneState[] = [];
|
|
95
|
-
const rows: LayoutRow[] = [];
|
|
96
|
-
|
|
97
|
-
function emitNodeLine(contractHash: string): void {
|
|
98
|
-
rows.push({ kind: 'nodeLine', contractHash, laneIndex: 0 });
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function emitConnector(
|
|
102
|
-
connectorKind: ConnectorKind,
|
|
103
|
-
contractHash: string,
|
|
104
|
-
startLane: number,
|
|
105
|
-
endLane: number,
|
|
106
|
-
branchCount: number,
|
|
107
|
-
): void {
|
|
108
|
-
rows.push({
|
|
109
|
-
kind: 'connector',
|
|
110
|
-
connectorKind,
|
|
111
|
-
contractHash,
|
|
112
|
-
startLane,
|
|
113
|
-
endLane,
|
|
114
|
-
branchCount,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function activeLaneIndices(): number[] {
|
|
119
|
-
const indices: number[] = [];
|
|
120
|
-
for (let index = 0; index < lanes.length; index++) {
|
|
121
|
-
if (lanes[index]?.active) indices.push(index);
|
|
122
|
-
}
|
|
123
|
-
return indices;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function lanesWanting(contract: string): number[] {
|
|
127
|
-
const indices: number[] = [];
|
|
128
|
-
for (let index = 0; index < lanes.length; index++) {
|
|
129
|
-
const lane = lanes[index];
|
|
130
|
-
if (lane?.active && lane.want === contract) indices.push(index);
|
|
131
|
-
}
|
|
132
|
-
return indices;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function ensureLane(index: number): void {
|
|
136
|
-
while (lanes.length <= index) {
|
|
137
|
-
lanes.push({ want: '', active: false });
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function openLaneAtRight(want: string): number {
|
|
142
|
-
const index = lanes.length;
|
|
143
|
-
lanes.push({ want, active: true });
|
|
144
|
-
return index;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function closeLane(index: number): void {
|
|
148
|
-
ensureLane(index);
|
|
149
|
-
const lane = lanes[index];
|
|
150
|
-
if (lane) lane.active = false;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function emitJoinBelow(contractHash: string, laneIndices: readonly number[]): void {
|
|
154
|
-
if (laneIndices.length < 2) return;
|
|
155
|
-
const startLane = Math.min(...laneIndices);
|
|
156
|
-
const endLane = Math.max(...laneIndices);
|
|
157
|
-
emitConnector('joinBelow', contractHash, startLane, endLane, laneIndices.length);
|
|
158
|
-
for (const index of laneIndices) {
|
|
159
|
-
if (index !== startLane) closeLane(index);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function emitConvergencePreamble(contract: string): void {
|
|
164
|
-
if (convergencesEmitted.has(contract)) return;
|
|
165
|
-
if (forwardInDegree(topology, contract) < 2) return;
|
|
166
|
-
|
|
167
|
-
const consumersWanting = lanesWanting(contract);
|
|
168
|
-
if (forwardOutDegree(topology, contract) >= 2 && consumersWanting.length >= 2) {
|
|
169
|
-
emitJoinBelow(contract, consumersWanting);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
emitNodeLine(contract);
|
|
173
|
-
const producers = forwardProducersByTo.get(contract) ?? [];
|
|
174
|
-
if (producers.length >= 2) {
|
|
175
|
-
emitConnector('fanBelow', contract, 0, producers.length - 1, producers.length);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
for (const [producerIndex, producer] of producers.entries()) {
|
|
179
|
-
ensureLane(producerIndex);
|
|
180
|
-
lanes[producerIndex] = { want: canonicalFrom(producer.from), active: true };
|
|
181
|
-
producerLaneByHash.set(producer.migrationHash, producerIndex);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
convergencesEmitted.add(contract);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function assignProducerLane(entry: MigrationListEntry): number | undefined {
|
|
188
|
-
const preset = producerLaneByHash.get(entry.migrationHash);
|
|
189
|
-
if (preset !== undefined) return preset;
|
|
190
|
-
return undefined;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function placeWoven(entry: MigrationListEntry, edgeKind: EdgeKind, laneIndex: number): void {
|
|
194
|
-
const passThroughLanes = activeLaneIndices().filter((index) => index !== laneIndex);
|
|
195
|
-
rows.push({
|
|
196
|
-
kind: 'migration',
|
|
197
|
-
entry,
|
|
198
|
-
edgeKind,
|
|
199
|
-
laneIndex,
|
|
200
|
-
passThroughLanes,
|
|
201
|
-
woven: true,
|
|
202
|
-
});
|
|
203
|
-
ensureLane(laneIndex);
|
|
204
|
-
lanes[laneIndex] = { want: canonicalFrom(entry.from), active: true };
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function placeUnwoven(entry: MigrationListEntry, edgeKind: EdgeKind): void {
|
|
208
|
-
const passThroughLanes = activeLaneIndices();
|
|
209
|
-
const laneIndex = passThroughLanes.length === 0 ? 0 : Math.max(...passThroughLanes) + 1;
|
|
210
|
-
rows.push({
|
|
211
|
-
kind: 'migration',
|
|
212
|
-
entry,
|
|
213
|
-
edgeKind,
|
|
214
|
-
laneIndex,
|
|
215
|
-
passThroughLanes,
|
|
216
|
-
woven: false,
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
for (const entry of entries) {
|
|
221
|
-
const edgeKind = kindByMigrationHash.get(entry.migrationHash) ?? 'forward';
|
|
222
|
-
const to = canonicalTo(entry);
|
|
223
|
-
|
|
224
|
-
if (edgeKind !== 'forward') {
|
|
225
|
-
placeUnwoven(entry, edgeKind);
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (forwardInDegree(topology, to) >= 2 && !convergencesEmitted.has(to)) {
|
|
230
|
-
emitConvergencePreamble(to);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const presetLane = assignProducerLane(entry);
|
|
234
|
-
const wantingTo = lanesWanting(to);
|
|
235
|
-
|
|
236
|
-
if (wantingTo.length >= 2 && countForwardProducersTo(forwardProducersByTo, to) === 1) {
|
|
237
|
-
emitJoinBelow(to, wantingTo);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (presetLane !== undefined) {
|
|
241
|
-
placeWoven(entry, edgeKind, presetLane);
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const firstWanting = wantingTo[0];
|
|
246
|
-
if (firstWanting !== undefined) {
|
|
247
|
-
placeWoven(entry, edgeKind, firstWanting);
|
|
248
|
-
continue;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const tipLaneIndex = openLaneAtRight(canonicalFrom(entry.from));
|
|
252
|
-
placeWoven(entry, edgeKind, tipLaneIndex);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return { rows };
|
|
256
|
-
}
|
|
File without changes
|