@xstate-devtools/adapter 0.1.4 → 0.1.5
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 +22 -1
- package/dist/chunk-QLRTDBT5.js +300 -0
- package/dist/chunk-QLRTDBT5.js.map +1 -0
- package/dist/chunk-SUDAY5H3.js +34 -0
- package/dist/chunk-SUDAY5H3.js.map +1 -0
- package/dist/index.cjs +168 -569
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -10
- package/dist/index.d.ts +2 -10
- package/dist/index.js +2 -2
- package/dist/react.cjs +223 -588
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +31 -5
- package/dist/react.d.ts +31 -5
- package/dist/react.js +61 -13
- package/dist/react.js.map +1 -1
- package/dist/server.cjs +236 -679
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +10 -7
- package/dist/server.d.ts +10 -7
- package/dist/server.js +75 -146
- package/dist/server.js.map +1 -1
- package/package.json +12 -3
- package/dist/chunk-3GM2SFT4.js +0 -680
- package/dist/chunk-3GM2SFT4.js.map +0 -1
- package/dist/chunk-MHHRMHW5.js +0 -62
- package/dist/chunk-MHHRMHW5.js.map +0 -1
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ npm install @xstate-devtools/adapter
|
|
|
18
18
|
import { createAdapter } from '@xstate-devtools/adapter'
|
|
19
19
|
|
|
20
20
|
export const adapter = createAdapter()
|
|
21
|
+
// pass adapter.inspect to XState's inspect option:
|
|
21
22
|
useMachine(machine, { inspect: adapter.inspect })
|
|
22
23
|
```
|
|
23
24
|
|
|
@@ -41,9 +42,29 @@ createActor(machine, { inspect: adapter.inspect }).start()
|
|
|
41
42
|
Requires `react` and `@xstate/react`.
|
|
42
43
|
|
|
43
44
|
```tsx
|
|
44
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
InspectorProvider,
|
|
47
|
+
useInspectedMachine,
|
|
48
|
+
useRestorableInspectedMachine,
|
|
49
|
+
} from '@xstate-devtools/adapter/react'
|
|
50
|
+
|
|
51
|
+
function App() {
|
|
52
|
+
return (
|
|
53
|
+
<InspectorProvider>
|
|
54
|
+
<Player />
|
|
55
|
+
</InspectorProvider>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function Player() {
|
|
60
|
+
const [state, send] = useInspectedMachine(playerMachine)
|
|
61
|
+
// ...
|
|
62
|
+
}
|
|
45
63
|
```
|
|
46
64
|
|
|
65
|
+
`useRestorableInspectedMachine` additionally wires the actor for snapshot
|
|
66
|
+
restore from the debugger.
|
|
67
|
+
|
|
47
68
|
## License
|
|
48
69
|
|
|
49
70
|
MIT
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
// src/serialize.ts
|
|
2
|
+
function serializeGuard(guard) {
|
|
3
|
+
if (!guard) return void 0;
|
|
4
|
+
if (typeof guard === "string") return guard;
|
|
5
|
+
if (typeof guard === "function") return guard.name || "(inline)";
|
|
6
|
+
if (typeof guard === "object" && guard !== null) {
|
|
7
|
+
const g = guard;
|
|
8
|
+
return g.type ?? g.name ?? "(inline)";
|
|
9
|
+
}
|
|
10
|
+
return "(inline)";
|
|
11
|
+
}
|
|
12
|
+
function serializeAction(action) {
|
|
13
|
+
if (typeof action === "string") return action;
|
|
14
|
+
if (typeof action === "function") return action.name || "(anonymous)";
|
|
15
|
+
if (typeof action === "object" && action !== null) {
|
|
16
|
+
const a = action;
|
|
17
|
+
return a.type ?? a.name ?? String(action);
|
|
18
|
+
}
|
|
19
|
+
return String(action);
|
|
20
|
+
}
|
|
21
|
+
function serializeTransitionList(transitions) {
|
|
22
|
+
return transitions.map((t) => ({
|
|
23
|
+
eventType: t.eventType ?? "",
|
|
24
|
+
targets: (t.target ?? []).map((n) => n?.id ?? String(n)).filter(Boolean),
|
|
25
|
+
guard: serializeGuard(t.guard),
|
|
26
|
+
actions: (t.actions ?? []).map(serializeAction).filter(Boolean)
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
function serializeInvokes(node) {
|
|
30
|
+
return node.invoke.map((inv) => ({
|
|
31
|
+
id: inv.id ?? "(unknown)",
|
|
32
|
+
src: typeof inv.src === "string" ? inv.src : inv.src?.id ?? inv.src?.name ?? "(inline)"
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
function serializeNode(node) {
|
|
36
|
+
const allTransitions = [];
|
|
37
|
+
if (node.transitions instanceof Map) {
|
|
38
|
+
for (const [, tList] of node.transitions) {
|
|
39
|
+
allTransitions.push(...serializeTransitionList(tList));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const always = Array.isArray(node.always) ? serializeTransitionList(node.always) : [];
|
|
43
|
+
return {
|
|
44
|
+
id: node.id,
|
|
45
|
+
key: node.key,
|
|
46
|
+
type: node.type,
|
|
47
|
+
initial: node.initial?.target?.[0]?.key,
|
|
48
|
+
states: Object.fromEntries(
|
|
49
|
+
Object.entries(node.states ?? {}).map(([k, v]) => [k, serializeNode(v)])
|
|
50
|
+
),
|
|
51
|
+
on: allTransitions,
|
|
52
|
+
always,
|
|
53
|
+
entry: (node.entry ?? []).map(serializeAction).filter(Boolean),
|
|
54
|
+
exit: (node.exit ?? []).map(serializeAction).filter(Boolean),
|
|
55
|
+
invoke: serializeInvokes(node)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function serializeMachine(machine, sourceLocation) {
|
|
59
|
+
return {
|
|
60
|
+
id: machine.id,
|
|
61
|
+
root: serializeNode(machine.root),
|
|
62
|
+
sourceLocation
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/sanitize.ts
|
|
67
|
+
var MAX_DEPTH = 10;
|
|
68
|
+
var MAX_STRING_LENGTH = 500;
|
|
69
|
+
var MAX_ARRAY_LENGTH = 100;
|
|
70
|
+
var MAX_NODES = 1e4;
|
|
71
|
+
function sanitizeInner(value, ctx) {
|
|
72
|
+
if (ctx.depth > MAX_DEPTH) return "[MaxDepth]";
|
|
73
|
+
if (++ctx.budget.n > MAX_NODES) return "[Truncated]";
|
|
74
|
+
if (value === null || value === void 0) return value;
|
|
75
|
+
if (typeof value === "boolean" || typeof value === "number") return value;
|
|
76
|
+
if (typeof value === "string") {
|
|
77
|
+
return value.length > MAX_STRING_LENGTH ? value.slice(0, MAX_STRING_LENGTH) + "\u2026" : value;
|
|
78
|
+
}
|
|
79
|
+
if (typeof value === "function") return `[Function: ${value.name || "(anonymous)"}]`;
|
|
80
|
+
if (typeof value === "symbol") return `[Symbol: ${value.description ?? ""}]`;
|
|
81
|
+
if (typeof value === "bigint") return `[BigInt: ${value}]`;
|
|
82
|
+
if (value instanceof Error) return { __type: "Error", name: value.name, message: value.message };
|
|
83
|
+
if (value instanceof Date) return { __type: "Date", iso: value.toISOString() };
|
|
84
|
+
if (value instanceof RegExp) return { __type: "RegExp", source: value.source, flags: value.flags };
|
|
85
|
+
if (value instanceof Promise) return "[Promise]";
|
|
86
|
+
if (value instanceof WeakMap || value instanceof WeakSet) return "[WeakCollection]";
|
|
87
|
+
if (ArrayBuffer.isView(value)) return `[TypedArray: ${value.constructor.name}]`;
|
|
88
|
+
if (typeof Node !== "undefined" && value instanceof Node) {
|
|
89
|
+
return `[DOMNode: ${value.tagName ?? value.nodeName}]`;
|
|
90
|
+
}
|
|
91
|
+
if (ctx.seen.has(value)) return "[Circular]";
|
|
92
|
+
ctx.seen.add(value);
|
|
93
|
+
const child = { ...ctx, depth: ctx.depth + 1 };
|
|
94
|
+
if (value instanceof Map) {
|
|
95
|
+
const entries = [];
|
|
96
|
+
for (const [k, v] of value) {
|
|
97
|
+
if (entries.length >= MAX_ARRAY_LENGTH) break;
|
|
98
|
+
entries.push([sanitizeInner(k, child), sanitizeInner(v, child)]);
|
|
99
|
+
}
|
|
100
|
+
return { __type: "Map", entries };
|
|
101
|
+
}
|
|
102
|
+
if (value instanceof Set) {
|
|
103
|
+
const values = [];
|
|
104
|
+
for (const v of value) {
|
|
105
|
+
if (values.length >= MAX_ARRAY_LENGTH) break;
|
|
106
|
+
values.push(sanitizeInner(v, child));
|
|
107
|
+
}
|
|
108
|
+
return { __type: "Set", values };
|
|
109
|
+
}
|
|
110
|
+
if (Array.isArray(value)) {
|
|
111
|
+
const sliced = value.slice(0, MAX_ARRAY_LENGTH);
|
|
112
|
+
const result = sliced.map((v) => sanitizeInner(v, child));
|
|
113
|
+
if (value.length > MAX_ARRAY_LENGTH) result.push(`[\u2026${value.length - MAX_ARRAY_LENGTH} more]`);
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
if (typeof value === "object") {
|
|
117
|
+
const result = {};
|
|
118
|
+
let count = 0;
|
|
119
|
+
for (const [k, v] of Object.entries(value)) {
|
|
120
|
+
if (count++ >= MAX_ARRAY_LENGTH) {
|
|
121
|
+
result["\u2026"] = "[truncated]";
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
result[k] = sanitizeInner(v, child);
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
return String(value);
|
|
129
|
+
}
|
|
130
|
+
function sanitize(value) {
|
|
131
|
+
return sanitizeInner(value, { depth: 0, budget: { n: 0 }, seen: /* @__PURE__ */ new WeakSet() });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/core.ts
|
|
135
|
+
function getSourceLocation() {
|
|
136
|
+
try {
|
|
137
|
+
const lines = new Error().stack?.split("\n") ?? [];
|
|
138
|
+
const callerLine = lines.find(
|
|
139
|
+
(l, i) => i > 3 && !l.includes("xstate") && !l.includes("adapter")
|
|
140
|
+
);
|
|
141
|
+
return callerLine?.trim().replace(/^at\s+/, "");
|
|
142
|
+
} catch {
|
|
143
|
+
return void 0;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function serializeSnapshot(snapshot) {
|
|
147
|
+
return {
|
|
148
|
+
value: sanitize(snapshot?.value ?? null),
|
|
149
|
+
context: sanitize(snapshot?.context),
|
|
150
|
+
status: snapshot?.status ?? "active",
|
|
151
|
+
error: snapshot?.error ? sanitize(snapshot.error) : void 0
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function safeSerializeSnapshot(actorRef) {
|
|
155
|
+
try {
|
|
156
|
+
return serializeSnapshot(actorRef.getSnapshot());
|
|
157
|
+
} catch {
|
|
158
|
+
return { value: null, context: void 0, status: "active" };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function safePersistedSnapshot(actorRef) {
|
|
162
|
+
const getPersisted = actorRef.getPersistedSnapshot;
|
|
163
|
+
if (typeof getPersisted !== "function") {
|
|
164
|
+
return { error: "Actor does not support getPersistedSnapshot." };
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
const raw = getPersisted.call(actorRef);
|
|
168
|
+
if (raw === void 0) return { error: "No persisted snapshot available." };
|
|
169
|
+
return { persisted: JSON.parse(JSON.stringify(raw)) };
|
|
170
|
+
} catch (e) {
|
|
171
|
+
return { error: `Snapshot is not JSON-serializable: ${e.message}` };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
var SEQ_KEY = "__xstate_devtools_global_seq__";
|
|
175
|
+
function nextSeq() {
|
|
176
|
+
const g = globalThis;
|
|
177
|
+
const cur = g[SEQ_KEY] ?? 0;
|
|
178
|
+
const next = cur + 1;
|
|
179
|
+
g[SEQ_KEY] = next;
|
|
180
|
+
return next;
|
|
181
|
+
}
|
|
182
|
+
function createInspector(transport, source) {
|
|
183
|
+
const actorRefs = /* @__PURE__ */ new Map();
|
|
184
|
+
const restoreHandlers = /* @__PURE__ */ new Map();
|
|
185
|
+
const prefix = source + ":";
|
|
186
|
+
const tag = (sessionId) => prefix + sessionId;
|
|
187
|
+
const tagOptional = (id) => id ? prefix + id : void 0;
|
|
188
|
+
const stripIfMine = (id) => id.startsWith(prefix) ? id.slice(prefix.length) : null;
|
|
189
|
+
function checkAndNotifyStop(actorRef) {
|
|
190
|
+
let snap;
|
|
191
|
+
try {
|
|
192
|
+
snap = actorRef.getSnapshot();
|
|
193
|
+
} catch {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (snap?.status !== "active") {
|
|
197
|
+
transport.send({ type: "XSTATE_ACTOR_STOPPED", sessionId: tag(actorRef.sessionId) });
|
|
198
|
+
actorRefs.delete(actorRef.sessionId);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const unsubscribe = transport.subscribe((message) => {
|
|
202
|
+
if (message.type === "XSTATE_DISPATCH") {
|
|
203
|
+
const local = stripIfMine(message.sessionId);
|
|
204
|
+
if (local === null) return;
|
|
205
|
+
const ref = actorRefs.get(local);
|
|
206
|
+
if (ref) {
|
|
207
|
+
try {
|
|
208
|
+
ref.send(message.event);
|
|
209
|
+
} catch (e) {
|
|
210
|
+
console.warn("[xstate-devtools] dispatch error:", e);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
} else if (message.type === "XSTATE_REQUEST_PERSISTED") {
|
|
214
|
+
const local = stripIfMine(message.sessionId);
|
|
215
|
+
if (local === null) return;
|
|
216
|
+
const ref = actorRefs.get(local);
|
|
217
|
+
if (!ref) return;
|
|
218
|
+
const { persisted, error } = safePersistedSnapshot(ref);
|
|
219
|
+
transport.send({
|
|
220
|
+
type: "XSTATE_PERSISTED_SNAPSHOT",
|
|
221
|
+
sessionId: tag(local),
|
|
222
|
+
persisted,
|
|
223
|
+
error,
|
|
224
|
+
timestamp: Date.now()
|
|
225
|
+
});
|
|
226
|
+
} else if (message.type === "XSTATE_RESTORE") {
|
|
227
|
+
const local = stripIfMine(message.sessionId);
|
|
228
|
+
if (local === null) return;
|
|
229
|
+
const handler = restoreHandlers.get(local);
|
|
230
|
+
if (handler) {
|
|
231
|
+
try {
|
|
232
|
+
handler(message.persisted);
|
|
233
|
+
} catch (e) {
|
|
234
|
+
console.warn("[xstate-devtools] restore error:", e);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
const inspect = (inspectionEvent) => {
|
|
240
|
+
try {
|
|
241
|
+
if (inspectionEvent.type === "@xstate.actor") {
|
|
242
|
+
const actorRef = inspectionEvent.actorRef;
|
|
243
|
+
const sessionId = actorRef.sessionId;
|
|
244
|
+
actorRefs.set(sessionId, actorRef);
|
|
245
|
+
const logic = actorRef.logic;
|
|
246
|
+
const machine = logic?.root ? serializeMachine(logic, getSourceLocation()) : null;
|
|
247
|
+
transport.send({
|
|
248
|
+
type: "XSTATE_ACTOR_REGISTERED",
|
|
249
|
+
sessionId: tag(sessionId),
|
|
250
|
+
parentSessionId: tagOptional(actorRef._parent?.sessionId),
|
|
251
|
+
// actorRef.id is the invoke `id` for invoked actors — lets the debugger
|
|
252
|
+
// nest non-machine actors (promise/callback) under their state.
|
|
253
|
+
actorId: actorRef.id,
|
|
254
|
+
machine,
|
|
255
|
+
snapshot: safeSerializeSnapshot(actorRef),
|
|
256
|
+
globalSeq: nextSeq(),
|
|
257
|
+
timestamp: Date.now()
|
|
258
|
+
});
|
|
259
|
+
} else if (inspectionEvent.type === "@xstate.snapshot") {
|
|
260
|
+
transport.send({
|
|
261
|
+
type: "XSTATE_SNAPSHOT",
|
|
262
|
+
sessionId: tag(inspectionEvent.actorRef.sessionId),
|
|
263
|
+
snapshot: serializeSnapshot(inspectionEvent.snapshot),
|
|
264
|
+
timestamp: Date.now(),
|
|
265
|
+
globalSeq: nextSeq()
|
|
266
|
+
});
|
|
267
|
+
checkAndNotifyStop(inspectionEvent.actorRef);
|
|
268
|
+
} else if (inspectionEvent.type === "@xstate.event") {
|
|
269
|
+
transport.send({
|
|
270
|
+
type: "XSTATE_EVENT",
|
|
271
|
+
sessionId: tag(inspectionEvent.actorRef.sessionId),
|
|
272
|
+
event: inspectionEvent.event,
|
|
273
|
+
snapshotAfter: safeSerializeSnapshot(inspectionEvent.actorRef),
|
|
274
|
+
timestamp: Date.now(),
|
|
275
|
+
globalSeq: nextSeq()
|
|
276
|
+
});
|
|
277
|
+
checkAndNotifyStop(inspectionEvent.actorRef);
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
console.warn("[xstate-devtools] inspection failed, dropping event:", e.message);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
function registerRestore(sessionId, handler) {
|
|
284
|
+
restoreHandlers.set(sessionId, handler);
|
|
285
|
+
return () => {
|
|
286
|
+
if (restoreHandlers.get(sessionId) === handler) restoreHandlers.delete(sessionId);
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function dispose() {
|
|
290
|
+
unsubscribe();
|
|
291
|
+
actorRefs.clear();
|
|
292
|
+
restoreHandlers.clear();
|
|
293
|
+
}
|
|
294
|
+
return { inspect, dispose, registerRestore };
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export {
|
|
298
|
+
createInspector
|
|
299
|
+
};
|
|
300
|
+
//# sourceMappingURL=chunk-QLRTDBT5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/serialize.ts","../src/sanitize.ts","../src/core.ts"],"sourcesContent":["// packages/adapter/src/serialize.ts\nimport type { AnyStateMachine } from 'xstate'\nimport type { SerializedMachine, SerializedStateNode, SerializedTransition, SerializedInvoke } from '@xstate-devtools/protocol'\n\nfunction serializeGuard(guard: unknown): string | undefined {\n if (!guard) return undefined\n if (typeof guard === 'string') return guard\n if (typeof guard === 'function') return (guard as Function).name || '(inline)'\n if (typeof guard === 'object' && guard !== null) {\n const g = guard as any\n return g.type ?? g.name ?? '(inline)'\n }\n return '(inline)'\n}\n\nfunction serializeAction(action: unknown): string {\n if (typeof action === 'string') return action\n if (typeof action === 'function') return (action as Function).name || '(anonymous)'\n if (typeof action === 'object' && action !== null) {\n const a = action as any\n return a.type ?? a.name ?? String(action)\n }\n return String(action)\n}\n\nfunction serializeTransitionList(transitions: any[]): SerializedTransition[] {\n return transitions.map((t: any) => ({\n eventType: t.eventType ?? '',\n targets: (t.target ?? []).map((n: any) => n?.id ?? String(n)).filter(Boolean),\n guard: serializeGuard(t.guard),\n actions: (t.actions ?? []).map(serializeAction).filter(Boolean),\n }))\n}\n\nfunction serializeInvokes(node: any): SerializedInvoke[] {\n return (node.invoke as any[]).map((inv: any) => ({\n id: inv.id ?? '(unknown)',\n src: typeof inv.src === 'string'\n ? inv.src\n : inv.src?.id ?? inv.src?.name ?? '(inline)',\n }))\n}\n\nfunction serializeNode(node: any): SerializedStateNode {\n const allTransitions: SerializedTransition[] = []\n if (node.transitions instanceof Map) {\n for (const [, tList] of node.transitions) {\n allTransitions.push(...serializeTransitionList(tList))\n }\n }\n\n const always = Array.isArray(node.always) ? serializeTransitionList(node.always) : []\n\n return {\n id: node.id,\n key: node.key,\n type: node.type,\n initial: node.initial?.target?.[0]?.key,\n states: Object.fromEntries(\n Object.entries(node.states ?? {}).map(([k, v]) => [k, serializeNode(v)])\n ),\n on: allTransitions,\n always,\n entry: (node.entry ?? []).map(serializeAction).filter(Boolean),\n exit: (node.exit ?? []).map(serializeAction).filter(Boolean),\n invoke: serializeInvokes(node),\n }\n}\n\nexport function serializeMachine(machine: AnyStateMachine, sourceLocation?: string): SerializedMachine {\n return {\n id: machine.id,\n root: serializeNode(machine.root),\n sourceLocation,\n }\n}\n","// packages/adapter/src/sanitize.ts\n\nconst MAX_DEPTH = 10\nconst MAX_STRING_LENGTH = 500\nconst MAX_ARRAY_LENGTH = 100\n// Hard ceiling on total nodes across the whole tree. The per-level caps above\n// still allow multiplicative blow-up (100^depth) on wide+deep or cross-linked\n// objects, which can produce a string too large for JSON.stringify to handle.\n// This bounds the output regardless of shape.\nconst MAX_NODES = 10000\n\ninterface Ctx {\n depth: number\n /** Shared mutable node counter — the global budget. */\n budget: { n: number }\n /** Objects/arrays seen on the current path + elsewhere, to break cycles and DAGs. */\n seen: WeakSet<object>\n}\n\nfunction sanitizeInner(value: unknown, ctx: Ctx): unknown {\n if (ctx.depth > MAX_DEPTH) return '[MaxDepth]'\n if (++ctx.budget.n > MAX_NODES) return '[Truncated]'\n if (value === null || value === undefined) return value\n if (typeof value === 'boolean' || typeof value === 'number') return value\n if (typeof value === 'string') {\n return value.length > MAX_STRING_LENGTH ? value.slice(0, MAX_STRING_LENGTH) + '…' : value\n }\n if (typeof value === 'function') return `[Function: ${value.name || '(anonymous)'}]`\n if (typeof value === 'symbol') return `[Symbol: ${value.description ?? ''}]`\n if (typeof value === 'bigint') return `[BigInt: ${value}]`\n if (value instanceof Error) return { __type: 'Error', name: value.name, message: value.message }\n if (value instanceof Date) return { __type: 'Date', iso: value.toISOString() }\n if (value instanceof RegExp) return { __type: 'RegExp', source: value.source, flags: value.flags }\n if (value instanceof Promise) return '[Promise]'\n if (value instanceof WeakMap || value instanceof WeakSet) return '[WeakCollection]'\n if (ArrayBuffer.isView(value)) return `[TypedArray: ${(value as any).constructor.name}]`\n // Detect DOM nodes (works in browser and is safe to check)\n if (typeof Node !== 'undefined' && value instanceof Node) {\n return `[DOMNode: ${(value as Element).tagName ?? value.nodeName}]`\n }\n\n // From here on we recurse into containers — guard against shared/circular refs.\n if (ctx.seen.has(value as object)) return '[Circular]'\n ctx.seen.add(value as object)\n const child = { ...ctx, depth: ctx.depth + 1 }\n\n if (value instanceof Map) {\n const entries: [unknown, unknown][] = []\n for (const [k, v] of value as Map<unknown, unknown>) {\n if (entries.length >= MAX_ARRAY_LENGTH) break\n entries.push([sanitizeInner(k, child), sanitizeInner(v, child)])\n }\n return { __type: 'Map', entries }\n }\n if (value instanceof Set) {\n const values: unknown[] = []\n for (const v of value as Set<unknown>) {\n if (values.length >= MAX_ARRAY_LENGTH) break\n values.push(sanitizeInner(v, child))\n }\n return { __type: 'Set', values }\n }\n if (Array.isArray(value)) {\n const sliced = value.slice(0, MAX_ARRAY_LENGTH)\n const result = sliced.map((v) => sanitizeInner(v, child))\n if (value.length > MAX_ARRAY_LENGTH) result.push(`[…${value.length - MAX_ARRAY_LENGTH} more]`)\n return result\n }\n if (typeof value === 'object') {\n const result: Record<string, unknown> = {}\n let count = 0\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (count++ >= MAX_ARRAY_LENGTH) { result['…'] = '[truncated]'; break }\n result[k] = sanitizeInner(v, child)\n }\n return result\n }\n return String(value)\n}\n\nexport function sanitize(value: unknown): unknown {\n return sanitizeInner(value, { depth: 0, budget: { n: 0 }, seen: new WeakSet() })\n}\n","// Transport-agnostic XState inspection core.\n// Browser and server entrypoints supply their own transports.\nimport type { AnyActorRef } from 'xstate'\nimport type {\n ExtensionToPageMessage, PageToExtensionMessage, SerializedSnapshot,\n} from '@xstate-devtools/protocol'\nimport { serializeMachine } from './serialize.js'\nimport { sanitize } from './sanitize.js'\n\nexport type Source = 'web' | 'srv'\n\nexport interface Transport {\n /** Send a protocol message outbound (toward the panel). */\n send: (message: PageToExtensionMessage) => void\n /** Subscribe to inbound dispatch messages from the panel. Returns a teardown. */\n subscribe: (handler: (message: ExtensionToPageMessage) => void) => () => void\n}\n\nfunction getSourceLocation(): string | undefined {\n try {\n const lines = new Error().stack?.split('\\n') ?? []\n const callerLine = lines.find(\n (l, i) => i > 3 && !l.includes('xstate') && !l.includes('adapter')\n )\n return callerLine?.trim().replace(/^at\\s+/, '')\n } catch {\n return undefined\n }\n}\n\nfunction serializeSnapshot(snapshot: any): SerializedSnapshot {\n return {\n value: sanitize(snapshot?.value ?? null) as SerializedSnapshot['value'],\n context: sanitize(snapshot?.context),\n status: snapshot?.status ?? 'active',\n error: snapshot?.error ? sanitize(snapshot.error) : undefined,\n }\n}\n\nfunction safeSerializeSnapshot(actorRef: AnyActorRef): SerializedSnapshot {\n try {\n return serializeSnapshot(actorRef.getSnapshot())\n } catch {\n return { value: null, context: undefined, status: 'active' }\n }\n}\n\n/**\n * Capture XState's persisted snapshot for an actor. Unlike the display snapshot,\n * this is meant to be restorable. We JSON round-trip it to guarantee it survives\n * the transport (and stays serializable); a throw here means the snapshot isn't\n * cleanly persistable, which we report as an error rather than silently dropping.\n */\nfunction safePersistedSnapshot(actorRef: AnyActorRef): { persisted?: unknown; error?: string } {\n const getPersisted = (actorRef as any).getPersistedSnapshot\n if (typeof getPersisted !== 'function') {\n return { error: 'Actor does not support getPersistedSnapshot.' }\n }\n try {\n const raw = getPersisted.call(actorRef)\n if (raw === undefined) return { error: 'No persisted snapshot available.' }\n return { persisted: JSON.parse(JSON.stringify(raw)) }\n } catch (e) {\n return { error: `Snapshot is not JSON-serializable: ${(e as Error).message}` }\n }\n}\n\n// Cached on globalThis so HMR re-evaluating this module doesn't reset the\n// monotonic seq counter mid-session. The panel re-numbers messages on ingest\n// to merge multiple sources, but keeping a stable per-process seq still helps\n// when the panel reconnects to an already-running adapter.\nconst SEQ_KEY = '__xstate_devtools_global_seq__'\nfunction nextSeq(): number {\n const g = globalThis as Record<string, unknown>\n const cur = (g[SEQ_KEY] as number | undefined) ?? 0\n const next = cur + 1\n g[SEQ_KEY] = next\n return next\n}\n\nexport function createInspector(transport: Transport, source: Source) {\n const actorRefs = new Map<string, AnyActorRef>()\n // Owner-registered restore handlers, keyed by local (un-prefixed) sessionId.\n // Populated by useRestorableInspectedMachine; an actor without a handler\n // simply can't be restored (live rewind is opt-in).\n const restoreHandlers = new Map<string, (persisted: unknown) => void>()\n const prefix = source + ':'\n const tag = (sessionId: string) => prefix + sessionId\n const tagOptional = (id: string | undefined) => (id ? prefix + id : undefined)\n const stripIfMine = (id: string): string | null =>\n id.startsWith(prefix) ? id.slice(prefix.length) : null\n\n function checkAndNotifyStop(actorRef: AnyActorRef) {\n let snap: any\n try { snap = actorRef.getSnapshot() } catch { return }\n if (snap?.status !== 'active') {\n transport.send({ type: 'XSTATE_ACTOR_STOPPED', sessionId: tag(actorRef.sessionId) })\n actorRefs.delete(actorRef.sessionId)\n }\n }\n\n const unsubscribe = transport.subscribe((message) => {\n if (message.type === 'XSTATE_DISPATCH') {\n const local = stripIfMine(message.sessionId)\n if (local === null) return // not for this transport source\n const ref = actorRefs.get(local)\n if (ref) {\n try { ref.send(message.event) } catch (e) {\n console.warn('[xstate-devtools] dispatch error:', e)\n }\n }\n } else if (message.type === 'XSTATE_REQUEST_PERSISTED') {\n const local = stripIfMine(message.sessionId)\n if (local === null) return // not for this transport source\n const ref = actorRefs.get(local)\n if (!ref) return\n const { persisted, error } = safePersistedSnapshot(ref)\n transport.send({\n type: 'XSTATE_PERSISTED_SNAPSHOT',\n sessionId: tag(local),\n persisted,\n error,\n timestamp: Date.now(),\n })\n } else if (message.type === 'XSTATE_RESTORE') {\n const local = stripIfMine(message.sessionId)\n if (local === null) return // not for this transport source\n const handler = restoreHandlers.get(local)\n if (handler) {\n try { handler(message.persisted) } catch (e) {\n console.warn('[xstate-devtools] restore error:', e)\n }\n }\n }\n })\n\n const inspect = (inspectionEvent: any) => {\n try {\n if (inspectionEvent.type === '@xstate.actor') {\n const actorRef: AnyActorRef = inspectionEvent.actorRef\n const sessionId: string = actorRef.sessionId\n actorRefs.set(sessionId, actorRef)\n\n // `logic` is internal and not on the public AnyActorRef type.\n const logic = (actorRef as any).logic\n const machine = logic?.root\n ? serializeMachine(logic, getSourceLocation())\n : null\n\n transport.send({\n type: 'XSTATE_ACTOR_REGISTERED',\n sessionId: tag(sessionId),\n parentSessionId: tagOptional((actorRef as any)._parent?.sessionId),\n // actorRef.id is the invoke `id` for invoked actors — lets the debugger\n // nest non-machine actors (promise/callback) under their state.\n actorId: (actorRef as any).id,\n machine,\n snapshot: safeSerializeSnapshot(actorRef),\n globalSeq: nextSeq(),\n timestamp: Date.now(),\n })\n } else if (inspectionEvent.type === '@xstate.snapshot') {\n transport.send({\n type: 'XSTATE_SNAPSHOT',\n sessionId: tag(inspectionEvent.actorRef.sessionId),\n snapshot: serializeSnapshot(inspectionEvent.snapshot),\n timestamp: Date.now(),\n globalSeq: nextSeq(),\n })\n checkAndNotifyStop(inspectionEvent.actorRef)\n } else if (inspectionEvent.type === '@xstate.event') {\n transport.send({\n type: 'XSTATE_EVENT',\n sessionId: tag(inspectionEvent.actorRef.sessionId),\n event: inspectionEvent.event,\n snapshotAfter: safeSerializeSnapshot(inspectionEvent.actorRef),\n timestamp: Date.now(),\n globalSeq: nextSeq(),\n })\n checkAndNotifyStop(inspectionEvent.actorRef)\n }\n } catch (e) {\n // Never let an inspection failure (e.g. an un-serializable snapshot too large\n // for JSON.stringify) propagate back into XState's synchronous inspection\n // callback — that would crash the host actor's start(). Drop the event.\n console.warn('[xstate-devtools] inspection failed, dropping event:', (e as Error).message)\n }\n }\n\n /**\n * Register an owner-side restore handler for an actor. Called by\n * useRestorableInspectedMachine. Returns an unregister function.\n */\n function registerRestore(sessionId: string, handler: (persisted: unknown) => void) {\n restoreHandlers.set(sessionId, handler)\n return () => {\n if (restoreHandlers.get(sessionId) === handler) restoreHandlers.delete(sessionId)\n }\n }\n\n function dispose() {\n unsubscribe()\n actorRefs.clear()\n restoreHandlers.clear()\n }\n\n return { inspect, dispose, registerRestore }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createInspector
|
|
3
|
+
} from "./chunk-QLRTDBT5.js";
|
|
4
|
+
|
|
5
|
+
// src/index.ts
|
|
6
|
+
function createAdapter() {
|
|
7
|
+
if (typeof window === "undefined") {
|
|
8
|
+
return { inspect: () => {
|
|
9
|
+
}, dispose: () => {
|
|
10
|
+
}, registerRestore: () => () => {
|
|
11
|
+
} };
|
|
12
|
+
}
|
|
13
|
+
const transport = {
|
|
14
|
+
send(message) {
|
|
15
|
+
window.__XSTATE_DEVTOOLS__?.send({ ...message, __xstateDevtools: true });
|
|
16
|
+
},
|
|
17
|
+
subscribe(handler) {
|
|
18
|
+
const onMessage = (evt) => {
|
|
19
|
+
if (evt.source !== window) return;
|
|
20
|
+
const data = evt.data;
|
|
21
|
+
if (!data?.__xstateDevtools) return;
|
|
22
|
+
handler(data);
|
|
23
|
+
};
|
|
24
|
+
window.addEventListener("message", onMessage);
|
|
25
|
+
return () => window.removeEventListener("message", onMessage);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return createInspector(transport, "web");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
createAdapter
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=chunk-SUDAY5H3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Browser entrypoint — uses window.postMessage via the extension's injected bridge.\nimport type { ExtensionToPageMessage, PageToExtensionMessage } from '@xstate-devtools/protocol'\nimport { createInspector, type Transport } from './core.js'\n\ndeclare global {\n interface Window {\n __XSTATE_DEVTOOLS__?: {\n send: (message: unknown) => void\n }\n }\n}\n\nexport function createAdapter() {\n if (typeof window === 'undefined') {\n // Non-browser env (SSR/SSG/server) — return a no-op so importing this module is safe.\n return { inspect: () => {}, dispose: () => {}, registerRestore: () => () => {} }\n }\n\n const transport: Transport = {\n send(message: PageToExtensionMessage) {\n window.__XSTATE_DEVTOOLS__?.send({ ...message, __xstateDevtools: true })\n },\n subscribe(handler) {\n const onMessage = (evt: MessageEvent) => {\n if (evt.source !== window) return\n const data = evt.data\n if (!data?.__xstateDevtools) return\n handler(data as ExtensionToPageMessage)\n }\n window.addEventListener('message', onMessage)\n return () => window.removeEventListener('message', onMessage)\n },\n }\n\n return createInspector(transport, 'web')\n}\n"],"mappings":";;;;;AAYO,SAAS,gBAAgB;AAC9B,MAAI,OAAO,WAAW,aAAa;AAEjC,WAAO,EAAE,SAAS,MAAM;AAAA,IAAC,GAAG,SAAS,MAAM;AAAA,IAAC,GAAG,iBAAiB,MAAM,MAAM;AAAA,IAAC,EAAE;AAAA,EACjF;AAEA,QAAM,YAAuB;AAAA,IAC3B,KAAK,SAAiC;AACpC,aAAO,qBAAqB,KAAK,EAAE,GAAG,SAAS,kBAAkB,KAAK,CAAC;AAAA,IACzE;AAAA,IACA,UAAU,SAAS;AACjB,YAAM,YAAY,CAAC,QAAsB;AACvC,YAAI,IAAI,WAAW,OAAQ;AAC3B,cAAM,OAAO,IAAI;AACjB,YAAI,CAAC,MAAM,iBAAkB;AAC7B,gBAAQ,IAA8B;AAAA,MACxC;AACA,aAAO,iBAAiB,WAAW,SAAS;AAC5C,aAAO,MAAM,OAAO,oBAAoB,WAAW,SAAS;AAAA,IAC9D;AAAA,EACF;AAEA,SAAO,gBAAgB,WAAW,KAAK;AACzC;","names":[]}
|