@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,244 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Activity as VisualizationActivity,
|
|
3
|
+
Branch as VisualizationBranch,
|
|
4
|
+
MachineDocument as VisualizationDocument,
|
|
5
|
+
State as VisualizationState,
|
|
6
|
+
Transition as VisualizationTransition
|
|
7
|
+
} from "../../MachineDocument.js"
|
|
8
|
+
import { type InputField, projectInputSchema } from "./input-form.js"
|
|
9
|
+
import { stateLabel, triggerLabel } from "./visualizer-model.js"
|
|
10
|
+
|
|
11
|
+
export interface ChartField {
|
|
12
|
+
readonly key: string
|
|
13
|
+
readonly label: string
|
|
14
|
+
readonly type: string
|
|
15
|
+
readonly required: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ChartActivity {
|
|
19
|
+
readonly id: string
|
|
20
|
+
readonly kind: VisualizationActivity["type"]
|
|
21
|
+
readonly label: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ChartNode {
|
|
25
|
+
readonly path: string
|
|
26
|
+
readonly label: string
|
|
27
|
+
readonly type: VisualizationState["type"]
|
|
28
|
+
readonly parent: string | null
|
|
29
|
+
readonly children: ReadonlyArray<string>
|
|
30
|
+
readonly active: boolean
|
|
31
|
+
readonly initial: boolean
|
|
32
|
+
readonly fields: ReadonlyArray<ChartField>
|
|
33
|
+
readonly activities: ReadonlyArray<ChartActivity>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ChartEdge {
|
|
37
|
+
readonly id: string
|
|
38
|
+
readonly transitionId: string
|
|
39
|
+
readonly branchIds: ReadonlyArray<string>
|
|
40
|
+
readonly kind: "target" | "targetless" | "runtime"
|
|
41
|
+
readonly source: string
|
|
42
|
+
readonly target: string | null
|
|
43
|
+
readonly label: string
|
|
44
|
+
readonly trigger: VisualizationTransition["trigger"]
|
|
45
|
+
readonly activityKind: ChartActivity["kind"] | null
|
|
46
|
+
readonly reenter: boolean
|
|
47
|
+
readonly acceptance: VisualizationTransition["acceptance"]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ChartRuntimeTarget {
|
|
51
|
+
readonly id: string
|
|
52
|
+
readonly edgeId: string
|
|
53
|
+
readonly parent: string | null
|
|
54
|
+
readonly label: string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface ChartInitial {
|
|
58
|
+
readonly id: string
|
|
59
|
+
readonly target: string
|
|
60
|
+
readonly parent: string | null
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ChartModel {
|
|
64
|
+
readonly machineId: string
|
|
65
|
+
readonly roots: ReadonlyArray<string>
|
|
66
|
+
readonly nodes: ReadonlyArray<ChartNode>
|
|
67
|
+
readonly edges: ReadonlyArray<ChartEdge>
|
|
68
|
+
readonly runtimeTargets: ReadonlyArray<ChartRuntimeTarget>
|
|
69
|
+
readonly initials: ReadonlyArray<ChartInitial>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const literalType = (value: string | number | boolean | null): string =>
|
|
73
|
+
typeof value === "string" ? JSON.stringify(value) : String(value)
|
|
74
|
+
|
|
75
|
+
const fieldType = (field: InputField): string => {
|
|
76
|
+
switch (field._tag) {
|
|
77
|
+
case "String":
|
|
78
|
+
return field.format ?? "string"
|
|
79
|
+
case "Number":
|
|
80
|
+
return field.integer ? "integer" : "number"
|
|
81
|
+
case "Boolean":
|
|
82
|
+
return "boolean"
|
|
83
|
+
case "Enum":
|
|
84
|
+
return field.values.map(literalType).join(" | ")
|
|
85
|
+
case "Literal":
|
|
86
|
+
return literalType(field.value)
|
|
87
|
+
case "Object":
|
|
88
|
+
return "object"
|
|
89
|
+
case "Array":
|
|
90
|
+
return `${fieldType(field.item)}[]`
|
|
91
|
+
case "Union":
|
|
92
|
+
return field.alternatives.map(fieldType).join(" | ")
|
|
93
|
+
case "Unsupported":
|
|
94
|
+
return "unknown"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const stateFields = (state: VisualizationState): ReadonlyArray<ChartField> => {
|
|
99
|
+
if (state.valueSchema === null) return []
|
|
100
|
+
const projected = projectInputSchema(state.valueSchema)
|
|
101
|
+
if (projected._tag !== "Object") {
|
|
102
|
+
return [{
|
|
103
|
+
key: "value",
|
|
104
|
+
label: projected.title ?? "value",
|
|
105
|
+
type: fieldType(projected),
|
|
106
|
+
required: true
|
|
107
|
+
}]
|
|
108
|
+
}
|
|
109
|
+
return projected.fields
|
|
110
|
+
.filter(({ key }) => key !== "_tag")
|
|
111
|
+
.map(({ field, key, required }) => ({
|
|
112
|
+
key,
|
|
113
|
+
label: field.title ?? key,
|
|
114
|
+
type: fieldType(field),
|
|
115
|
+
required
|
|
116
|
+
}))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const activityLabel = (activity: VisualizationActivity): string => {
|
|
120
|
+
switch (activity.type) {
|
|
121
|
+
case "machine":
|
|
122
|
+
return `${activity.lifecycleId} → ${activity.child.machineId ?? activity.child.id}`
|
|
123
|
+
case "timer":
|
|
124
|
+
return `${activity.lifecycleId} · ${activity.duration}`
|
|
125
|
+
case "process":
|
|
126
|
+
case "effect":
|
|
127
|
+
case "stream":
|
|
128
|
+
return activity.lifecycleId
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const transitionLabel = (transition: VisualizationTransition, branch: VisualizationBranch): string => {
|
|
133
|
+
const trigger = triggerLabel(transition)
|
|
134
|
+
return branch.type === "branch" ? `${trigger} · ${branch.title}` : trigger
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
interface EdgeGroup {
|
|
138
|
+
readonly kind: ChartEdge["kind"]
|
|
139
|
+
readonly target: string | null
|
|
140
|
+
readonly branches: Array<VisualizationBranch>
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const edgeGroup = (
|
|
144
|
+
branch: VisualizationBranch,
|
|
145
|
+
states: ReadonlyMap<string, VisualizationState>
|
|
146
|
+
): { readonly key: string; readonly kind: ChartEdge["kind"]; readonly target: string | null } => {
|
|
147
|
+
if (branch.target !== null && states.has(branch.target)) {
|
|
148
|
+
return { key: `target:${branch.target}`, kind: "target", target: branch.target }
|
|
149
|
+
}
|
|
150
|
+
if (branch.selection.kind === "none" || branch.selection.kind === "update") {
|
|
151
|
+
return { key: "targetless", kind: "targetless", target: null }
|
|
152
|
+
}
|
|
153
|
+
return { key: "runtime", kind: "runtime", target: null }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export const makeChartModel = (document: VisualizationDocument): ChartModel => {
|
|
157
|
+
const active = new Set(document.snapshot?.activePaths ?? [])
|
|
158
|
+
const initialPaths = new Set([document.initial.target])
|
|
159
|
+
const activities = new Map(document.activities.map((activity) => [activity.id, activity]))
|
|
160
|
+
const activitiesBySource = new Map<string, Map<string, ChartActivity["kind"]>>()
|
|
161
|
+
for (const activity of document.activities) {
|
|
162
|
+
const sourceActivities = activitiesBySource.get(activity.source) ?? new Map()
|
|
163
|
+
sourceActivities.set(activity.lifecycleId, activity.type)
|
|
164
|
+
activitiesBySource.set(activity.source, sourceActivities)
|
|
165
|
+
}
|
|
166
|
+
const states = new Map(document.states.map((state) => [state.path, state]))
|
|
167
|
+
|
|
168
|
+
for (const state of document.states) {
|
|
169
|
+
if (state.initial !== null) initialPaths.add(state.initial)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const nodes = document.states.map((state): ChartNode => ({
|
|
173
|
+
path: state.path,
|
|
174
|
+
label: stateLabel(state),
|
|
175
|
+
type: state.type,
|
|
176
|
+
parent: state.parent,
|
|
177
|
+
children: [...state.children],
|
|
178
|
+
active: active.has(state.path),
|
|
179
|
+
initial: initialPaths.has(state.path),
|
|
180
|
+
fields: stateFields(state),
|
|
181
|
+
activities: state.activityIds.flatMap((id): ReadonlyArray<ChartActivity> => {
|
|
182
|
+
const activity = activities.get(id)
|
|
183
|
+
return activity === undefined ? [] : [{ id, kind: activity.type, label: activityLabel(activity) }]
|
|
184
|
+
})
|
|
185
|
+
}))
|
|
186
|
+
|
|
187
|
+
const edges = document.transitions.flatMap((transition): ReadonlyArray<ChartEdge> => {
|
|
188
|
+
if (!states.has(transition.source)) return []
|
|
189
|
+
const groups = new Map<string, EdgeGroup>()
|
|
190
|
+
for (const branch of transition.branches) {
|
|
191
|
+
const group = edgeGroup(branch, states)
|
|
192
|
+
const current = groups.get(group.key)
|
|
193
|
+
if (current === undefined) {
|
|
194
|
+
groups.set(group.key, { kind: group.kind, target: group.target, branches: [branch] })
|
|
195
|
+
} else {
|
|
196
|
+
current.branches.push(branch)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return [...groups].map(([key, { branches, kind, target }]): ChartEdge => ({
|
|
200
|
+
id: branches.length === 1 ? branches[0]!.id : `${transition.id}:${key}`,
|
|
201
|
+
transitionId: transition.id,
|
|
202
|
+
branchIds: branches.map(({ id }) => id),
|
|
203
|
+
kind,
|
|
204
|
+
source: transition.source,
|
|
205
|
+
target,
|
|
206
|
+
label: branches.length === 1
|
|
207
|
+
? transitionLabel(transition, branches[0]!)
|
|
208
|
+
: `${triggerLabel(transition)} · ${branches.length} branches`,
|
|
209
|
+
trigger: transition.trigger,
|
|
210
|
+
activityKind: transition.trigger.type === "invoke"
|
|
211
|
+
? activitiesBySource.get(transition.source)?.get(transition.trigger.id) ?? null
|
|
212
|
+
: null,
|
|
213
|
+
reenter: transition.reenter,
|
|
214
|
+
acceptance: transition.acceptance
|
|
215
|
+
}))
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
const runtimeTargets = edges.flatMap((edge): ReadonlyArray<ChartRuntimeTarget> => {
|
|
219
|
+
if (edge.kind !== "runtime") return []
|
|
220
|
+
const source = states.get(edge.source)
|
|
221
|
+
return source === undefined
|
|
222
|
+
? []
|
|
223
|
+
: [{
|
|
224
|
+
id: `runtime:${edge.id}`,
|
|
225
|
+
edgeId: edge.id,
|
|
226
|
+
parent: source.parent,
|
|
227
|
+
label: "runtime target"
|
|
228
|
+
}]
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
const initials = [...initialPaths].flatMap((target): ReadonlyArray<ChartInitial> => {
|
|
232
|
+
const state = states.get(target)
|
|
233
|
+
return state === undefined ? [] : [{ id: `initial:${target}`, target, parent: state.parent }]
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
machineId: document.machineId,
|
|
238
|
+
roots: [...document.roots],
|
|
239
|
+
nodes,
|
|
240
|
+
edges,
|
|
241
|
+
runtimeTargets,
|
|
242
|
+
initials
|
|
243
|
+
}
|
|
244
|
+
}
|