@coldtea/pr-lens-schema 0.1.3 → 0.2.1
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/README.md +50 -6
- package/dist/apply.d.ts.map +1 -1
- package/dist/apply.js +15 -0
- package/dist/apply.js.map +1 -1
- package/dist/examples/index.d.ts +138 -0
- package/dist/examples/index.d.ts.map +1 -1
- package/dist/examples/postmark-refactor.d.ts +2 -1
- package/dist/examples/postmark-refactor.d.ts.map +1 -1
- package/dist/examples/postmark-refactor.js +51 -1
- package/dist/examples/postmark-refactor.js.map +1 -1
- package/dist/graph.d.ts +111 -0
- package/dist/graph.d.ts.map +1 -1
- package/dist/graph.js +74 -1
- package/dist/graph.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/integrity.d.ts.map +1 -1
- package/dist/integrity.js +71 -0
- package/dist/integrity.js.map +1 -1
- package/dist/primitives.d.ts +11 -0
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +19 -0
- package/dist/primitives.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/walkthrough.d.ts +39 -0
- package/dist/walkthrough.d.ts.map +1 -0
- package/dist/walkthrough.js +95 -0
- package/dist/walkthrough.js.map +1 -0
- package/examples/broadcast-baseline.graph.json +1 -1
- package/examples/broadcast-baseline.patch.json +1 -1
- package/examples/minimal.graph.json +1 -1
- package/examples/postmark-refactor.graph.json +106 -1
- package/examples/postmark-refactor.render-manifest.json +1 -1
- package/examples/pr-lens.config.json +1 -1
- package/json-schema/config.schema.json +1 -1
- package/json-schema/graph-doc.schema.json +221 -2
- package/json-schema/patch-doc.schema.json +2 -2
- package/json-schema/render-manifest.schema.json +2 -2
- package/package.json +9 -9
- package/src/apply.ts +16 -0
- package/src/examples/postmark-refactor.ts +51 -1
- package/src/graph.ts +99 -1
- package/src/index.ts +8 -0
- package/src/integrity.ts +85 -0
- package/src/primitives.ts +21 -0
- package/src/version.ts +1 -1
- package/src/walkthrough.ts +146 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { assertNever } from "./utils.js";
|
|
2
|
+
const NOTHING = new Set();
|
|
3
|
+
export const indexViews = (views) => new Map(views.flatMap((view) => [[view.id, view], ...indexViews(view.children)]));
|
|
4
|
+
const messageIdsOf = (flows) => new Set(flows.flatMap((flow) => flow.messages.map((message) => message.id)));
|
|
5
|
+
export const stagedMessages = (stage, flows, views) => {
|
|
6
|
+
if (stage === undefined)
|
|
7
|
+
return { kind: "no-stage" };
|
|
8
|
+
switch (stage.kind) {
|
|
9
|
+
case "flow": {
|
|
10
|
+
const flow = flows.find(({ id }) => id === stage.flow);
|
|
11
|
+
return flow === undefined
|
|
12
|
+
? { kind: "unknown-stage" }
|
|
13
|
+
: { kind: "messages", ids: messageIdsOf([flow]) };
|
|
14
|
+
}
|
|
15
|
+
case "view": {
|
|
16
|
+
const view = views.get(stage.view);
|
|
17
|
+
if (view === undefined)
|
|
18
|
+
return { kind: "unknown-stage" };
|
|
19
|
+
switch (view.scope.kind) {
|
|
20
|
+
case "all":
|
|
21
|
+
return { kind: "messages", ids: messageIdsOf(flows) };
|
|
22
|
+
case "selection": {
|
|
23
|
+
const scoped = view.scope.flows;
|
|
24
|
+
return {
|
|
25
|
+
kind: "messages",
|
|
26
|
+
ids: messageIdsOf(flows.filter((flow) => scoped.includes(flow.id))),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
default:
|
|
30
|
+
return assertNever(view.scope, "Unhandled view scope");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
default:
|
|
34
|
+
return assertNever(stage, "Unhandled step stage");
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const stageSurvives = (stage, flows, views) => {
|
|
38
|
+
switch (stage.kind) {
|
|
39
|
+
case "view":
|
|
40
|
+
return views.has(stage.view);
|
|
41
|
+
case "flow":
|
|
42
|
+
return flows.has(stage.flow);
|
|
43
|
+
default:
|
|
44
|
+
return assertNever(stage, "Unhandled step stage");
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const focusable = (staged) => {
|
|
48
|
+
switch (staged.kind) {
|
|
49
|
+
case "messages":
|
|
50
|
+
return staged.ids;
|
|
51
|
+
case "no-stage":
|
|
52
|
+
case "unknown-stage":
|
|
53
|
+
return NOTHING;
|
|
54
|
+
default:
|
|
55
|
+
return assertNever(staged, "Unhandled staged messages");
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* A step that loses the last element it focused is dropped rather than left
|
|
60
|
+
* to widen into a step about everything. A tour of one step is a caption, so
|
|
61
|
+
* a walkthrough cut below two steps goes whole.
|
|
62
|
+
*/
|
|
63
|
+
export const pruneWalkthrough = (walkthrough, subject) => {
|
|
64
|
+
if (walkthrough === undefined)
|
|
65
|
+
return undefined;
|
|
66
|
+
const lanes = new Set(subject.lanes.map((lane) => lane.id));
|
|
67
|
+
const nodes = new Set(subject.nodes.map((node) => node.id));
|
|
68
|
+
const edges = new Set(subject.edges.map((edge) => edge.id));
|
|
69
|
+
const flows = new Set(subject.flows.map((flow) => flow.id));
|
|
70
|
+
const views = indexViews(subject.views);
|
|
71
|
+
const steps = walkthrough.steps.flatMap((step) => {
|
|
72
|
+
if (step.stage !== undefined && !stageSurvives(step.stage, flows, views))
|
|
73
|
+
return [];
|
|
74
|
+
switch (step.focus.kind) {
|
|
75
|
+
case "all":
|
|
76
|
+
return [step];
|
|
77
|
+
case "selection": {
|
|
78
|
+
const onStage = focusable(stagedMessages(step.stage, subject.flows, views));
|
|
79
|
+
const focus = {
|
|
80
|
+
kind: "selection",
|
|
81
|
+
lanes: step.focus.lanes.filter((id) => lanes.has(id)),
|
|
82
|
+
nodes: step.focus.nodes.filter((id) => nodes.has(id)),
|
|
83
|
+
edges: step.focus.edges.filter((id) => edges.has(id)),
|
|
84
|
+
messages: step.focus.messages.filter((id) => onStage.has(id)),
|
|
85
|
+
};
|
|
86
|
+
const focused = focus.lanes.length + focus.nodes.length + focus.edges.length + focus.messages.length;
|
|
87
|
+
return focused === 0 ? [] : [{ ...step, focus }];
|
|
88
|
+
}
|
|
89
|
+
default:
|
|
90
|
+
return assertNever(step.focus, "Unhandled step focus");
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return steps.length < 2 ? undefined : { ...walkthrough, steps };
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=walkthrough.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walkthrough.js","sourceRoot":"","sources":["../src/walkthrough.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion": "0.1.
|
|
2
|
+
"schemaVersion": "0.1.1",
|
|
3
3
|
"kind": "graph",
|
|
4
4
|
"generatedAt": "2026-08-19T18:24:00.000Z",
|
|
5
5
|
"title": "Batch broadcast sending through Postmark",
|
|
@@ -564,6 +564,111 @@
|
|
|
564
564
|
"children": []
|
|
565
565
|
}
|
|
566
566
|
],
|
|
567
|
+
"walkthrough": {
|
|
568
|
+
"steps": [
|
|
569
|
+
{
|
|
570
|
+
"id": "batches-of-500",
|
|
571
|
+
"heading": "sendBroadcastBulk and buildBulkPayload added",
|
|
572
|
+
"body": "Nothing loops over recipients any more. The sender works on a whole batch at a time.",
|
|
573
|
+
"stage": {
|
|
574
|
+
"kind": "view",
|
|
575
|
+
"view": "overview"
|
|
576
|
+
},
|
|
577
|
+
"focus": {
|
|
578
|
+
"kind": "selection",
|
|
579
|
+
"lanes": [],
|
|
580
|
+
"nodes": [
|
|
581
|
+
"send-broadcast-bulk",
|
|
582
|
+
"build-bulk-payload",
|
|
583
|
+
"postmark"
|
|
584
|
+
],
|
|
585
|
+
"edges": [],
|
|
586
|
+
"messages": []
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
"id": "suppression-first",
|
|
591
|
+
"heading": "getSuppressedEmails added before the send",
|
|
592
|
+
"body": "It pulls the blocked addresses once, before any batch is built.",
|
|
593
|
+
"stage": {
|
|
594
|
+
"kind": "view",
|
|
595
|
+
"view": "new-batch-path"
|
|
596
|
+
},
|
|
597
|
+
"focus": {
|
|
598
|
+
"kind": "selection",
|
|
599
|
+
"lanes": [],
|
|
600
|
+
"nodes": [
|
|
601
|
+
"get-suppressed-emails",
|
|
602
|
+
"postmark"
|
|
603
|
+
],
|
|
604
|
+
"edges": [],
|
|
605
|
+
"messages": []
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
"id": "old-path-goes-dark",
|
|
610
|
+
"heading": "processBroadcast and sendSingleEmail removed",
|
|
611
|
+
"body": "sendBroadcastBulk does their job for whole batches.",
|
|
612
|
+
"stage": {
|
|
613
|
+
"kind": "view",
|
|
614
|
+
"view": "overview"
|
|
615
|
+
},
|
|
616
|
+
"focus": {
|
|
617
|
+
"kind": "selection",
|
|
618
|
+
"lanes": [],
|
|
619
|
+
"nodes": [
|
|
620
|
+
"process-broadcast",
|
|
621
|
+
"send-single-email"
|
|
622
|
+
],
|
|
623
|
+
"edges": [],
|
|
624
|
+
"messages": []
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
"id": "sequence-start-to-finish",
|
|
629
|
+
"heading": "The send sequence gained 6 new steps",
|
|
630
|
+
"body": "The queue write is the only step that was there before, and it now stamps the batch size.",
|
|
631
|
+
"stage": {
|
|
632
|
+
"kind": "flow",
|
|
633
|
+
"flow": "send-pipeline"
|
|
634
|
+
},
|
|
635
|
+
"focus": {
|
|
636
|
+
"kind": "all"
|
|
637
|
+
}
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
"id": "four-batch-calls",
|
|
641
|
+
"heading": "Postmark now gets 500 emails per call",
|
|
642
|
+
"body": "One call per batch, and Postmark answers with a result for each message.",
|
|
643
|
+
"stage": {
|
|
644
|
+
"kind": "flow",
|
|
645
|
+
"flow": "send-pipeline"
|
|
646
|
+
},
|
|
647
|
+
"focus": {
|
|
648
|
+
"kind": "selection",
|
|
649
|
+
"lanes": [],
|
|
650
|
+
"nodes": [],
|
|
651
|
+
"edges": [],
|
|
652
|
+
"messages": [
|
|
653
|
+
"batch-post",
|
|
654
|
+
"batch-results"
|
|
655
|
+
]
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
"id": "blast-radius",
|
|
660
|
+
"heading": "4 parts added, 2 removed, across 3 lanes",
|
|
661
|
+
"body": "A 2,000-person broadcast used to make 2,000 calls to Postmark. It now makes 4.",
|
|
662
|
+
"stage": {
|
|
663
|
+
"kind": "view",
|
|
664
|
+
"view": "overview"
|
|
665
|
+
},
|
|
666
|
+
"focus": {
|
|
667
|
+
"kind": "all"
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
]
|
|
671
|
+
},
|
|
567
672
|
"layout": {
|
|
568
673
|
"direction": "right",
|
|
569
674
|
"laneOrder": [
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://raw.githubusercontent.com/coldteadotai/pr-lens/main/packages/schema/json-schema/config.schema.json",
|
|
4
4
|
"title": "PR Lens repository config",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.1",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
8
|
"schemaVersion": {
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://raw.githubusercontent.com/coldteadotai/pr-lens/main/packages/schema/json-schema/graph-doc.schema.json",
|
|
4
4
|
"title": "PR Lens graph document",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.1",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
8
|
"schemaVersion": {
|
|
9
9
|
"type": "string",
|
|
10
10
|
"pattern": "^0\\.1\\.\\d+$",
|
|
11
|
-
"description": "Contract version the document targets. Current: 0.1.
|
|
11
|
+
"description": "Contract version the document targets. Current: 0.1.1."
|
|
12
12
|
},
|
|
13
13
|
"kind": {
|
|
14
14
|
"type": "string",
|
|
@@ -795,6 +795,225 @@
|
|
|
795
795
|
"$ref": "#/$defs/View"
|
|
796
796
|
}
|
|
797
797
|
},
|
|
798
|
+
"walkthrough": {
|
|
799
|
+
"type": "object",
|
|
800
|
+
"properties": {
|
|
801
|
+
"steps": {
|
|
802
|
+
"minItems": 2,
|
|
803
|
+
"maxItems": 12,
|
|
804
|
+
"type": "array",
|
|
805
|
+
"items": {
|
|
806
|
+
"type": "object",
|
|
807
|
+
"properties": {
|
|
808
|
+
"id": {
|
|
809
|
+
"type": "string",
|
|
810
|
+
"minLength": 1,
|
|
811
|
+
"maxLength": 128,
|
|
812
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]*$",
|
|
813
|
+
"description": "Stable identifier, unique within its collection in a document."
|
|
814
|
+
},
|
|
815
|
+
"heading": {
|
|
816
|
+
"type": "string",
|
|
817
|
+
"minLength": 1,
|
|
818
|
+
"maxLength": 48,
|
|
819
|
+
"description": "A step heading. Short enough to read at a glance."
|
|
820
|
+
},
|
|
821
|
+
"body": {
|
|
822
|
+
"type": "string",
|
|
823
|
+
"minLength": 1,
|
|
824
|
+
"maxLength": 140,
|
|
825
|
+
"description": "A single line under a step heading."
|
|
826
|
+
},
|
|
827
|
+
"stage": {
|
|
828
|
+
"oneOf": [
|
|
829
|
+
{
|
|
830
|
+
"type": "object",
|
|
831
|
+
"properties": {
|
|
832
|
+
"kind": {
|
|
833
|
+
"type": "string",
|
|
834
|
+
"const": "view"
|
|
835
|
+
},
|
|
836
|
+
"view": {
|
|
837
|
+
"type": "string",
|
|
838
|
+
"minLength": 1,
|
|
839
|
+
"maxLength": 128,
|
|
840
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]*$",
|
|
841
|
+
"description": "Id of the drill-down view to draw."
|
|
842
|
+
}
|
|
843
|
+
},
|
|
844
|
+
"required": [
|
|
845
|
+
"kind",
|
|
846
|
+
"view"
|
|
847
|
+
],
|
|
848
|
+
"additionalProperties": false
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
"type": "object",
|
|
852
|
+
"properties": {
|
|
853
|
+
"kind": {
|
|
854
|
+
"type": "string",
|
|
855
|
+
"const": "flow"
|
|
856
|
+
},
|
|
857
|
+
"flow": {
|
|
858
|
+
"type": "string",
|
|
859
|
+
"minLength": 1,
|
|
860
|
+
"maxLength": 128,
|
|
861
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]*$",
|
|
862
|
+
"description": "Id of the flow to draw."
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
"required": [
|
|
866
|
+
"kind",
|
|
867
|
+
"flow"
|
|
868
|
+
],
|
|
869
|
+
"additionalProperties": false
|
|
870
|
+
}
|
|
871
|
+
],
|
|
872
|
+
"description": "Which diagram a walkthrough step plays over."
|
|
873
|
+
},
|
|
874
|
+
"focus": {
|
|
875
|
+
"default": {
|
|
876
|
+
"kind": "all"
|
|
877
|
+
},
|
|
878
|
+
"oneOf": [
|
|
879
|
+
{
|
|
880
|
+
"type": "object",
|
|
881
|
+
"properties": {
|
|
882
|
+
"kind": {
|
|
883
|
+
"type": "string",
|
|
884
|
+
"const": "all"
|
|
885
|
+
}
|
|
886
|
+
},
|
|
887
|
+
"required": [
|
|
888
|
+
"kind"
|
|
889
|
+
],
|
|
890
|
+
"additionalProperties": false
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
"type": "object",
|
|
894
|
+
"properties": {
|
|
895
|
+
"kind": {
|
|
896
|
+
"type": "string",
|
|
897
|
+
"const": "selection"
|
|
898
|
+
},
|
|
899
|
+
"lanes": {
|
|
900
|
+
"default": [],
|
|
901
|
+
"maxItems": 64,
|
|
902
|
+
"type": "array",
|
|
903
|
+
"items": {
|
|
904
|
+
"type": "string",
|
|
905
|
+
"minLength": 1,
|
|
906
|
+
"maxLength": 128,
|
|
907
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]*$",
|
|
908
|
+
"description": "Stable identifier, unique within its collection in a document."
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
"nodes": {
|
|
912
|
+
"default": [],
|
|
913
|
+
"maxItems": 256,
|
|
914
|
+
"type": "array",
|
|
915
|
+
"items": {
|
|
916
|
+
"type": "string",
|
|
917
|
+
"minLength": 1,
|
|
918
|
+
"maxLength": 128,
|
|
919
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]*$",
|
|
920
|
+
"description": "Stable identifier, unique within its collection in a document."
|
|
921
|
+
}
|
|
922
|
+
},
|
|
923
|
+
"edges": {
|
|
924
|
+
"default": [],
|
|
925
|
+
"maxItems": 512,
|
|
926
|
+
"type": "array",
|
|
927
|
+
"items": {
|
|
928
|
+
"type": "string",
|
|
929
|
+
"minLength": 1,
|
|
930
|
+
"maxLength": 128,
|
|
931
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]*$",
|
|
932
|
+
"description": "Stable identifier, unique within its collection in a document."
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
"messages": {
|
|
936
|
+
"default": [],
|
|
937
|
+
"description": "Steps of the flow on the stage.",
|
|
938
|
+
"maxItems": 64,
|
|
939
|
+
"type": "array",
|
|
940
|
+
"items": {
|
|
941
|
+
"type": "string",
|
|
942
|
+
"minLength": 1,
|
|
943
|
+
"maxLength": 128,
|
|
944
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]*$",
|
|
945
|
+
"description": "Stable identifier, unique within its collection in a document."
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
},
|
|
949
|
+
"required": [
|
|
950
|
+
"kind"
|
|
951
|
+
],
|
|
952
|
+
"additionalProperties": false,
|
|
953
|
+
"anyOf": [
|
|
954
|
+
{
|
|
955
|
+
"properties": {
|
|
956
|
+
"lanes": {
|
|
957
|
+
"minItems": 1
|
|
958
|
+
}
|
|
959
|
+
},
|
|
960
|
+
"required": [
|
|
961
|
+
"lanes"
|
|
962
|
+
]
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
"properties": {
|
|
966
|
+
"nodes": {
|
|
967
|
+
"minItems": 1
|
|
968
|
+
}
|
|
969
|
+
},
|
|
970
|
+
"required": [
|
|
971
|
+
"nodes"
|
|
972
|
+
]
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
"properties": {
|
|
976
|
+
"edges": {
|
|
977
|
+
"minItems": 1
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
"required": [
|
|
981
|
+
"edges"
|
|
982
|
+
]
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
"properties": {
|
|
986
|
+
"messages": {
|
|
987
|
+
"minItems": 1
|
|
988
|
+
}
|
|
989
|
+
},
|
|
990
|
+
"required": [
|
|
991
|
+
"messages"
|
|
992
|
+
]
|
|
993
|
+
}
|
|
994
|
+
]
|
|
995
|
+
}
|
|
996
|
+
],
|
|
997
|
+
"description": "What stays lit while a walkthrough step plays."
|
|
998
|
+
}
|
|
999
|
+
},
|
|
1000
|
+
"required": [
|
|
1001
|
+
"id",
|
|
1002
|
+
"heading",
|
|
1003
|
+
"body"
|
|
1004
|
+
],
|
|
1005
|
+
"additionalProperties": false,
|
|
1006
|
+
"description": "One stop on the walkthrough: a heading, a line under it, and the part of one diagram it is about."
|
|
1007
|
+
},
|
|
1008
|
+
"description": "Ordered by array position."
|
|
1009
|
+
}
|
|
1010
|
+
},
|
|
1011
|
+
"required": [
|
|
1012
|
+
"steps"
|
|
1013
|
+
],
|
|
1014
|
+
"additionalProperties": false,
|
|
1015
|
+
"description": "An ordered tour of this document's diagrams."
|
|
1016
|
+
},
|
|
798
1017
|
"layout": {
|
|
799
1018
|
"type": "object",
|
|
800
1019
|
"properties": {
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://raw.githubusercontent.com/coldteadotai/pr-lens/main/packages/schema/json-schema/patch-doc.schema.json",
|
|
4
4
|
"title": "PR Lens patch document",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.1",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
8
|
"schemaVersion": {
|
|
9
9
|
"type": "string",
|
|
10
10
|
"pattern": "^0\\.1\\.\\d+$",
|
|
11
|
-
"description": "Contract version the document targets. Current: 0.1.
|
|
11
|
+
"description": "Contract version the document targets. Current: 0.1.1."
|
|
12
12
|
},
|
|
13
13
|
"kind": {
|
|
14
14
|
"type": "string",
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://raw.githubusercontent.com/coldteadotai/pr-lens/main/packages/schema/json-schema/render-manifest.schema.json",
|
|
4
4
|
"title": "PR Lens render manifest",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.1",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
8
|
"schemaVersion": {
|
|
9
9
|
"type": "string",
|
|
10
10
|
"pattern": "^0\\.1\\.\\d+$",
|
|
11
|
-
"description": "Contract version the document targets. Current: 0.1.
|
|
11
|
+
"description": "Contract version the document targets. Current: 0.1.1."
|
|
12
12
|
},
|
|
13
13
|
"kind": {
|
|
14
14
|
"type": "string",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coldtea/pr-lens-schema",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "The PR Lens contract: versioned schemas for architecture / data-flow graph documents, baseline patches, config and render manifests.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Coldtea AI",
|
|
@@ -46,13 +46,6 @@
|
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": ">=20.11"
|
|
48
48
|
},
|
|
49
|
-
"scripts": {
|
|
50
|
-
"build": "rm -rf dist && tsc -p tsconfig.build.json && pnpm run schema:emit",
|
|
51
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
52
|
-
"schema:emit": "tsx scripts/emit-artifacts.ts",
|
|
53
|
-
"test": "vitest run",
|
|
54
|
-
"test:watch": "vitest"
|
|
55
|
-
},
|
|
56
49
|
"dependencies": {
|
|
57
50
|
"zod": "^4.4.3"
|
|
58
51
|
},
|
|
@@ -62,5 +55,12 @@
|
|
|
62
55
|
"tsx": "4.23.12",
|
|
63
56
|
"typescript": "7.0.2",
|
|
64
57
|
"vitest": "4.1.11"
|
|
58
|
+
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && pnpm run schema:emit",
|
|
61
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
62
|
+
"schema:emit": "tsx scripts/emit-artifacts.ts",
|
|
63
|
+
"test": "vitest run",
|
|
64
|
+
"test:watch": "vitest"
|
|
65
65
|
}
|
|
66
|
-
}
|
|
66
|
+
}
|
package/src/apply.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { Flow, GraphDoc, GraphEdge, Lane, View } from "./graph.js";
|
|
|
4
4
|
import { graphSnapshotIssues } from "./integrity.js";
|
|
5
5
|
import { targetDescribesATransition, type PatchDoc, type PatchOp } from "./patch.js";
|
|
6
6
|
import { assertNever } from "./utils.js";
|
|
7
|
+
import { pruneWalkthrough } from "./walkthrough.js";
|
|
7
8
|
|
|
8
9
|
type Collections = {
|
|
9
10
|
lanes: Lane[];
|
|
@@ -298,6 +299,20 @@ export const applyPatch = (graph: GraphDoc, ops: readonly PatchOp[]): Parsed<Gra
|
|
|
298
299
|
}
|
|
299
300
|
}
|
|
300
301
|
|
|
302
|
+
/**
|
|
303
|
+
* The tour is pruned once, against the document the operations produced,
|
|
304
|
+
* rather than alongside each removal. A step names a diagram as well as
|
|
305
|
+
* elements, and an operation that rewrites a flow's steps takes members
|
|
306
|
+
* away without removing anything the other prunes would notice.
|
|
307
|
+
*/
|
|
308
|
+
const walkthrough = pruneWalkthrough(graph.walkthrough, {
|
|
309
|
+
lanes: working.lanes,
|
|
310
|
+
nodes: working.nodes,
|
|
311
|
+
edges: working.edges,
|
|
312
|
+
flows: working.flows,
|
|
313
|
+
views,
|
|
314
|
+
});
|
|
315
|
+
|
|
301
316
|
return safeParseGraphDoc({
|
|
302
317
|
...graph,
|
|
303
318
|
lanes: working.lanes,
|
|
@@ -306,6 +321,7 @@ export const applyPatch = (graph: GraphDoc, ops: readonly PatchOp[]): Parsed<Gra
|
|
|
306
321
|
flows: working.flows,
|
|
307
322
|
stats: working.stats,
|
|
308
323
|
views,
|
|
324
|
+
walkthrough,
|
|
309
325
|
layout,
|
|
310
326
|
});
|
|
311
327
|
};
|