@typeonce/effect-machine-devtools 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +4 -0
- package/README.md +13 -13
- package/dist/DevToolsProtocol.d.ts +66 -630
- package/dist/DevToolsProtocol.d.ts.map +1 -1
- package/dist/DevToolsProtocol.js +0 -190
- package/dist/DevToolsProtocol.js.map +1 -1
- package/dist/MachineDocument.d.ts +38 -18
- package/dist/MachineDocument.d.ts.map +1 -1
- package/dist/MachineDocument.js +14 -12
- package/dist/MachineDocument.js.map +1 -1
- package/dist/MachineRegistry.d.ts +22 -2
- package/dist/MachineRegistry.d.ts.map +1 -1
- package/dist/MachineWalkthrough.d.ts +171 -0
- package/dist/MachineWalkthrough.d.ts.map +1 -0
- package/dist/MachineWalkthrough.js +98 -0
- package/dist/MachineWalkthrough.js.map +1 -0
- package/dist/ProjectInspector.d.ts +0 -2
- package/dist/ProjectInspector.d.ts.map +1 -1
- package/dist/ProjectInspector.js.map +1 -1
- package/dist/client/assets/index-BsorPSDS.css +1 -0
- package/dist/client/assets/index-eiptehRd.js +37 -0
- package/dist/client/index.html +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/internal/devServer.d.ts.map +1 -1
- package/dist/internal/devServer.js +4 -64
- package/dist/internal/devServer.js.map +1 -1
- package/dist/internal/evaluationWorker.d.ts.map +1 -1
- package/dist/internal/evaluationWorker.js +7 -263
- package/dist/internal/evaluationWorker.js.map +1 -1
- package/dist/internal/machineDocument.d.ts.map +1 -1
- package/dist/internal/machineDocument.js +3 -1
- package/dist/internal/machineDocument.js.map +1 -1
- package/dist/internal/machineWalkthrough.d.ts +26 -0
- package/dist/internal/machineWalkthrough.d.ts.map +1 -0
- package/dist/internal/machineWalkthrough.js +256 -0
- package/dist/internal/machineWalkthrough.js.map +1 -0
- package/dist/internal/projectInspector.d.ts.map +1 -1
- package/dist/internal/projectInspector.js +1 -11
- package/dist/internal/projectInspector.js.map +1 -1
- package/index.html +2 -2
- package/package.json +8 -7
- package/src/DevToolsProtocol.ts +0 -285
- package/src/MachineDocument.ts +21 -19
- package/src/MachineWalkthrough.ts +199 -0
- package/src/ProjectInspector.ts +0 -5
- package/src/index.ts +2 -2
- package/src/internal/browser/chart-layout-policy.ts +206 -0
- package/src/internal/browser/chart-layout.ts +686 -0
- package/src/internal/browser/chart-model.ts +244 -0
- package/src/internal/browser/chart-renderer.ts +774 -0
- package/src/internal/browser/example-machine.ts +15 -6
- package/src/internal/browser/input-form.ts +1 -418
- package/src/internal/browser/invoke-outcomes-example.ts +231 -0
- package/src/internal/browser/parallel-completion-example.ts +199 -0
- package/src/internal/browser/planner-example.ts +2 -0
- package/src/internal/browser/protocol-events-example.ts +200 -0
- package/src/internal/browser/styles.css +974 -342
- package/src/internal/browser/transition-semantics-example.ts +245 -0
- package/src/internal/browser/visualizer-analysis.ts +52 -0
- package/src/internal/browser/visualizer-app.ts +874 -706
- package/src/internal/browser/visualizer-model.ts +104 -0
- package/src/internal/devServer.ts +4 -82
- package/src/internal/evaluationWorker.ts +7 -371
- package/src/internal/machineDocument.ts +3 -1
- package/src/internal/machineWalkthrough.ts +355 -0
- package/src/internal/projectInspector.ts +3 -31
- package/dist/MachineSimulator.d.ts +0 -169
- package/dist/MachineSimulator.d.ts.map +0 -1
- package/dist/MachineSimulator.js +0 -98
- package/dist/MachineSimulator.js.map +0 -1
- package/dist/client/assets/index-B49Tjawc.js +0 -14
- package/dist/client/assets/index-BKH0cOG2.css +0 -1
- package/dist/internal/machineSimulator.d.ts +0 -5
- package/dist/internal/machineSimulator.d.ts.map +0 -1
- package/dist/internal/machineSimulator.js +0 -156
- package/dist/internal/machineSimulator.js.map +0 -1
- package/src/MachineSimulator.ts +0 -154
- package/src/internal/browser/simulation-client.ts +0 -20
- package/src/internal/machineSimulator.ts +0 -199
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type { ChartEdge, ChartModel, ChartNode } from "./chart-model.js"
|
|
2
|
+
|
|
3
|
+
export type ChartPortSide = "NORTH" | "EAST" | "SOUTH" | "WEST"
|
|
4
|
+
|
|
5
|
+
export interface ChartNodeLayoutPolicy {
|
|
6
|
+
readonly reachable: boolean
|
|
7
|
+
readonly staticPath: boolean
|
|
8
|
+
readonly rank: number | null
|
|
9
|
+
readonly order: number
|
|
10
|
+
readonly layerConstraint: "LAST" | null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ChartEdgeLayoutPolicy {
|
|
14
|
+
readonly direction: "forward" | "backward" | "self"
|
|
15
|
+
readonly sourceSide: ChartPortSide
|
|
16
|
+
readonly targetSide: ChartPortSide
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ChartLayoutPolicy {
|
|
20
|
+
readonly children: (parent: string | null) => ReadonlyArray<ChartNode>
|
|
21
|
+
readonly node: (path: string) => ChartNodeLayoutPolicy
|
|
22
|
+
readonly edge: (edge: ChartEdge) => ChartEdgeLayoutPolicy
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const unreachableNode: ChartNodeLayoutPolicy = {
|
|
26
|
+
reachable: false,
|
|
27
|
+
staticPath: false,
|
|
28
|
+
rank: null,
|
|
29
|
+
order: Number.MAX_SAFE_INTEGER,
|
|
30
|
+
layerConstraint: null
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const directChild = (
|
|
34
|
+
path: string,
|
|
35
|
+
parent: string | null,
|
|
36
|
+
nodes: ReadonlyMap<string, ChartNode>
|
|
37
|
+
): string | null => {
|
|
38
|
+
let current = nodes.get(path)
|
|
39
|
+
while (current !== undefined && current.parent !== parent) {
|
|
40
|
+
current = current.parent === null ? undefined : nodes.get(current.parent)
|
|
41
|
+
}
|
|
42
|
+
return current?.path ?? null
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const lineage = (path: string, nodes: ReadonlyMap<string, ChartNode>): ReadonlyArray<string> => {
|
|
46
|
+
const result: Array<string> = []
|
|
47
|
+
let current = nodes.get(path)
|
|
48
|
+
while (current !== undefined) {
|
|
49
|
+
result.push(current.path)
|
|
50
|
+
current = current.parent === null ? undefined : nodes.get(current.parent)
|
|
51
|
+
}
|
|
52
|
+
return result.reverse()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const makeChartLayoutPolicy = (model: ChartModel): ChartLayoutPolicy => {
|
|
56
|
+
const nodes = new Map(model.nodes.map((node) => [node.path, node]))
|
|
57
|
+
const declarationOrder = new Map(model.nodes.map((node, index) => [node.path, index]))
|
|
58
|
+
const childrenByParent = new Map<string | null, Array<ChartNode>>()
|
|
59
|
+
for (const node of model.nodes) {
|
|
60
|
+
const children = childrenByParent.get(node.parent) ?? []
|
|
61
|
+
children.push(node)
|
|
62
|
+
childrenByParent.set(node.parent, children)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const nodePolicies = new Map<string, ChartNodeLayoutPolicy>()
|
|
66
|
+
const orderedChildren = new Map<string | null, ReadonlyArray<ChartNode>>()
|
|
67
|
+
|
|
68
|
+
const initialsByParent = new Map<string | null, Array<string>>()
|
|
69
|
+
for (const initial of model.initials) {
|
|
70
|
+
const initials = initialsByParent.get(initial.parent) ?? []
|
|
71
|
+
initials.push(initial.target)
|
|
72
|
+
initialsByParent.set(initial.parent, initials)
|
|
73
|
+
}
|
|
74
|
+
const outgoing = new Map<string, Array<string>>()
|
|
75
|
+
for (const edge of model.edges) {
|
|
76
|
+
if (edge.kind !== "target" || edge.target === null) continue
|
|
77
|
+
const targets = outgoing.get(edge.source) ?? []
|
|
78
|
+
targets.push(edge.target)
|
|
79
|
+
outgoing.set(edge.source, targets)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const staticPaths = new Set<string>()
|
|
83
|
+
const entered = new Set<string>()
|
|
84
|
+
const queue: Array<string> = []
|
|
85
|
+
const markReachable = (path: string): void => {
|
|
86
|
+
let current = nodes.get(path)
|
|
87
|
+
while (current !== undefined) {
|
|
88
|
+
if (!staticPaths.has(current.path)) {
|
|
89
|
+
staticPaths.add(current.path)
|
|
90
|
+
queue.push(current.path)
|
|
91
|
+
}
|
|
92
|
+
current = current.parent === null ? undefined : nodes.get(current.parent)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const enter = (path: string): void => {
|
|
96
|
+
const node = nodes.get(path)
|
|
97
|
+
if (node === undefined) return
|
|
98
|
+
markReachable(path)
|
|
99
|
+
if (entered.has(path)) return
|
|
100
|
+
entered.add(path)
|
|
101
|
+
if (node.type === "parallel") {
|
|
102
|
+
for (const child of node.children) enter(child)
|
|
103
|
+
} else if (node.type === "compound") {
|
|
104
|
+
for (const initial of initialsByParent.get(node.path) ?? []) enter(initial)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (const initial of initialsByParent.get(null) ?? []) enter(initial)
|
|
108
|
+
for (let index = 0; index < queue.length; index++) {
|
|
109
|
+
for (const target of outgoing.get(queue[index]!) ?? []) enter(target)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const [parent, children] of childrenByParent) {
|
|
113
|
+
const childPaths = new Set(children.map(({ path }) => path))
|
|
114
|
+
const adjacency = new Map(children.map(({ path }) => [path, new Set<string>()]))
|
|
115
|
+
for (const edge of model.edges) {
|
|
116
|
+
if (edge.kind !== "target" || edge.target === null) continue
|
|
117
|
+
const source = directChild(edge.source, parent, nodes)
|
|
118
|
+
const target = directChild(edge.target, parent, nodes)
|
|
119
|
+
if (source !== null && target !== null && source !== target && childPaths.has(source) && childPaths.has(target)) {
|
|
120
|
+
adjacency.get(source)?.add(target)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const ranks = new Map<string, number>()
|
|
125
|
+
const queue: Array<string> = []
|
|
126
|
+
for (const initial of model.initials) {
|
|
127
|
+
if (initial.parent !== parent) continue
|
|
128
|
+
const target = directChild(initial.target, parent, nodes)
|
|
129
|
+
if (target !== null && childPaths.has(target) && !ranks.has(target)) {
|
|
130
|
+
ranks.set(target, 0)
|
|
131
|
+
queue.push(target)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
for (let index = 0; index < queue.length; index++) {
|
|
135
|
+
const source = queue[index]!
|
|
136
|
+
const nextRank = ranks.get(source)! + 1
|
|
137
|
+
for (const target of adjacency.get(source) ?? []) {
|
|
138
|
+
const current = ranks.get(target)
|
|
139
|
+
if (current === undefined || nextRank < current) {
|
|
140
|
+
ranks.set(target, nextRank)
|
|
141
|
+
queue.push(target)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const ordered = [...children].sort((left, right) => {
|
|
147
|
+
const leftRank = ranks.get(left.path)
|
|
148
|
+
const rightRank = ranks.get(right.path)
|
|
149
|
+
if (leftRank !== undefined && rightRank === undefined) return -1
|
|
150
|
+
if (leftRank === undefined && rightRank !== undefined) return 1
|
|
151
|
+
if (leftRank !== undefined && rightRank !== undefined && leftRank !== rightRank) return leftRank - rightRank
|
|
152
|
+
return declarationOrder.get(left.path)! - declarationOrder.get(right.path)!
|
|
153
|
+
})
|
|
154
|
+
orderedChildren.set(parent, ordered)
|
|
155
|
+
ordered.forEach((node, order) => {
|
|
156
|
+
const rank = ranks.get(node.path) ?? null
|
|
157
|
+
nodePolicies.set(node.path, {
|
|
158
|
+
reachable: rank !== null,
|
|
159
|
+
staticPath: staticPaths.has(node.path),
|
|
160
|
+
rank,
|
|
161
|
+
order,
|
|
162
|
+
layerConstraint: node.type === "final" ? "LAST" : null
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const edgePolicy = (edge: ChartEdge): ChartEdgeLayoutPolicy => {
|
|
168
|
+
if (edge.kind === "targetless" || edge.target === edge.source) {
|
|
169
|
+
return { direction: "self", sourceSide: "SOUTH", targetSide: "SOUTH" }
|
|
170
|
+
}
|
|
171
|
+
if (edge.target === null) {
|
|
172
|
+
return { direction: "forward", sourceSide: "EAST", targetSide: "WEST" }
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const sourceLineage = lineage(edge.source, nodes)
|
|
176
|
+
const targetLineage = lineage(edge.target, nodes)
|
|
177
|
+
let differentAt = 0
|
|
178
|
+
while (
|
|
179
|
+
differentAt < sourceLineage.length && differentAt < targetLineage.length &&
|
|
180
|
+
sourceLineage[differentAt] === targetLineage[differentAt]
|
|
181
|
+
) {
|
|
182
|
+
differentAt++
|
|
183
|
+
}
|
|
184
|
+
if (differentAt === sourceLineage.length) {
|
|
185
|
+
return { direction: "forward", sourceSide: "EAST", targetSide: "WEST" }
|
|
186
|
+
}
|
|
187
|
+
if (differentAt === targetLineage.length) {
|
|
188
|
+
return { direction: "backward", sourceSide: "WEST", targetSide: "EAST" }
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const source = nodePolicies.get(sourceLineage[differentAt]!) ?? unreachableNode
|
|
192
|
+
const target = nodePolicies.get(targetLineage[differentAt]!) ?? unreachableNode
|
|
193
|
+
const backward = source.rank !== null && target.rank !== null
|
|
194
|
+
? target.rank < source.rank || target.rank === source.rank && target.order < source.order
|
|
195
|
+
: target.order < source.order
|
|
196
|
+
return backward
|
|
197
|
+
? { direction: "backward", sourceSide: "WEST", targetSide: "EAST" }
|
|
198
|
+
: { direction: "forward", sourceSide: "EAST", targetSide: "WEST" }
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
children: (parent) => orderedChildren.get(parent) ?? [],
|
|
203
|
+
node: (path) => nodePolicies.get(path) ?? unreachableNode,
|
|
204
|
+
edge: edgePolicy
|
|
205
|
+
}
|
|
206
|
+
}
|