@xstate/inspect
Advanced tools
Comparing version 0.5.2 to 0.6.0
# @xstate/inspect | ||
## 0.6.0 | ||
### Minor Changes | ||
- [#2640](https://github.com/statelyai/xstate/pull/2640) [`c73dfd655`](https://github.com/statelyai/xstate/commit/c73dfd655525546e59f00d0be88b80ab71239427) Thanks [@davidkpiano](https://github.com/davidkpiano)! - A serializer can now be specified as an option for `inspect(...)` in the `.serialize` property. It should be a [replacer function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_replacer_parameter): | ||
```js | ||
// ... | ||
inspect({ | ||
// ... | ||
serialize: (key, value) => { | ||
if (value instanceof Map) { | ||
return 'map'; | ||
} | ||
return value; | ||
} | ||
}); | ||
// ... | ||
// Will be inspected as: | ||
// { | ||
// type: 'EVENT_WITH_MAP', | ||
// map: 'map' | ||
// } | ||
someService.send({ | ||
type: 'EVENT_WITH_MAP', | ||
map: new Map() | ||
}); | ||
``` | ||
* [#2894](https://github.com/statelyai/xstate/pull/2894) [`8435c5b84`](https://github.com/statelyai/xstate/commit/8435c5b841e318c5d35dfea65242246dfb4b34f8) Thanks [@Andarist](https://github.com/Andarist)! - The package has been upgraded to be compatible with `ws@8.x`. The WS server created server-side has to be of a compatible version now. | ||
## 0.5.2 | ||
@@ -4,0 +39,0 @@ |
@@ -27,2 +27,14 @@ /*! ***************************************************************************** | ||
export { __assign }; | ||
function __values(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
} | ||
export { __assign, __values }; |
@@ -9,5 +9,5 @@ import { Interpreter, EventObject } from 'xstate'; | ||
export declare function createDevTools(): XStateDevInterface; | ||
export declare function inspect(options?: Partial<InspectorOptions>): Inspector | undefined; | ||
export declare function inspect(options?: InspectorOptions): Inspector | undefined; | ||
export declare function createWindowReceiver(options?: Partial<WindowReceiverOptions>): InspectReceiver; | ||
export declare function createWebSocketReceiver(options: WebSocketReceiverOptions): InspectReceiver; | ||
//# sourceMappingURL=browser.d.ts.map |
@@ -5,2 +5,3 @@ import { __assign } from './_virtual/_tslib.js'; | ||
import { getLazy, stringify, isReceiverEvent, parseReceiverEvent } from './utils.js'; | ||
import { stringifyMachine, stringifyState } from './serialize.js'; | ||
import { createInspectMachine } from './inspectMachine.js'; | ||
@@ -47,3 +48,4 @@ | ||
return devTools; | ||
} | ||
}, | ||
serialize: undefined | ||
}; | ||
@@ -60,3 +62,3 @@ var getFinalOptions = function (options) { | ||
} | ||
var inspectMachine = createInspectMachine(devTools); | ||
var inspectMachine = createInspectMachine(devTools, options); | ||
var inspectService = interpret(inspectMachine).start(); | ||
@@ -91,8 +93,12 @@ var listeners = new Set(); | ||
}); | ||
var stringifyWithSerializer = function (value) { | ||
return stringify(value, options === null || options === void 0 ? void 0 : options.serialize); | ||
}; | ||
devTools.onRegister(function (service) { | ||
var _a; | ||
var state = service.state || service.initialState; | ||
inspectService.send({ | ||
type: 'service.register', | ||
machine: stringify(service.machine), | ||
state: stringify(service.state || service.initialState), | ||
machine: stringifyMachine(service.machine, options === null || options === void 0 ? void 0 : options.serialize), | ||
state: stringifyState(state, options === null || options === void 0 ? void 0 : options.serialize), | ||
sessionId: service.sessionId, | ||
@@ -104,3 +110,3 @@ id: service.id, | ||
type: 'service.event', | ||
event: stringify((service.state || service.initialState)._event), | ||
event: stringifyWithSerializer(state._event), | ||
sessionId: service.sessionId | ||
@@ -115,3 +121,3 @@ }); | ||
type: 'service.event', | ||
event: stringify(toSCXMLEvent(toEventObject(event, payload))), | ||
event: stringifyWithSerializer(toSCXMLEvent(toEventObject(event, payload))), | ||
sessionId: service.sessionId | ||
@@ -122,3 +128,4 @@ }); | ||
service.subscribe(function (state) { | ||
// filter out synchronous notification from within `.start()` call when the `service.state` has not yet been assigned | ||
// filter out synchronous notification from within `.start()` call | ||
// when the `service.state` has not yet been assigned | ||
if (state === undefined) { | ||
@@ -129,3 +136,4 @@ return; | ||
type: 'service.state', | ||
state: stringify(state), | ||
// TODO: investigate usage of structuredClone in browsers if available | ||
state: stringifyState(state, options === null || options === void 0 ? void 0 : options.serialize), | ||
sessionId: service.sessionId | ||
@@ -221,3 +229,3 @@ }); | ||
send: function (event) { | ||
ws.send(JSON.stringify(event)); | ||
ws.send(stringify(event, options.serialize)); | ||
}, | ||
@@ -224,0 +232,0 @@ subscribe: function (next, onError, onComplete) { |
import { ActorRef } from 'xstate'; | ||
import { XStateDevInterface } from 'xstate/lib/devTools'; | ||
import { ReceiverEvent } from './types'; | ||
import { ReceiverEvent, Replacer } from './types'; | ||
export declare type InspectMachineEvent = ReceiverEvent | { | ||
@@ -16,3 +16,5 @@ type: 'unload'; | ||
}; | ||
export declare function createInspectMachine(devTools?: XStateDevInterface): import("xstate").StateMachine<{ | ||
export declare function createInspectMachine(devTools?: XStateDevInterface, options?: { | ||
serialize?: Replacer | undefined; | ||
}): import("xstate").StateMachine<{ | ||
client?: Pick<ActorRef<any, any>, "send"> | undefined; | ||
@@ -19,0 +21,0 @@ }, any, InspectMachineEvent, { |
import { createMachine, assign } from 'xstate'; | ||
import { stringify } from './utils.js'; | ||
import { stringifyMachine, stringifyState } from './serialize.js'; | ||
function createInspectMachine(devTools) { | ||
function createInspectMachine(devTools, options) { | ||
if (devTools === void 0) { devTools = globalThis.__xstate__; } | ||
@@ -68,4 +68,4 @@ var serviceMap = new Map(); | ||
type: 'service.register', | ||
machine: stringify(service.machine), | ||
state: stringify(service.state || service.initialState), | ||
machine: stringifyMachine(service.machine, options === null || options === void 0 ? void 0 : options.serialize), | ||
state: stringifyState(service.state || service.initialState, options === null || options === void 0 ? void 0 : options.serialize), | ||
sessionId: service.sessionId | ||
@@ -72,0 +72,0 @@ }); |
@@ -1,5 +0,6 @@ | ||
import * as WebSocket from 'ws'; | ||
import { Inspector } from './types'; | ||
import { WebSocketServer } from 'ws'; | ||
import { Inspector, Replacer } from './types'; | ||
interface ServerInspectorOptions { | ||
server: WebSocket.Server; | ||
server: WebSocketServer; | ||
serialize?: Replacer | undefined; | ||
} | ||
@@ -6,0 +7,0 @@ export declare function inspect(options: ServerInspectorOptions): Inspector; |
@@ -6,8 +6,10 @@ import type { ActorRef, Interpreter, SCXML, State, StateMachine } from 'xstate'; | ||
export declare type ServiceListener = (service: Interpreter<any>) => void; | ||
export declare type Replacer = (key: string, value: any) => any; | ||
export interface InspectorOptions { | ||
url: string; | ||
iframe: MaybeLazy<HTMLIFrameElement | null | false>; | ||
devTools: MaybeLazy<XStateDevInterface>; | ||
url?: string; | ||
iframe?: MaybeLazy<HTMLIFrameElement | null | false>; | ||
devTools?: MaybeLazy<XStateDevInterface>; | ||
serialize?: Replacer | undefined; | ||
} | ||
export interface Inspector extends ActorRef<InspectMachineEvent, any> { | ||
export interface Inspector extends ActorRef<InspectMachineEvent, State<any, any, any>> { | ||
/** | ||
@@ -79,3 +81,4 @@ * Disconnects the inspector. | ||
protocol?: 'ws' | 'wss'; | ||
serialize: Replacer | undefined; | ||
} | ||
//# sourceMappingURL=types.d.ts.map |
import { State } from 'xstate'; | ||
import { MaybeLazy, ParsedReceiverEvent, ReceiverEvent } from './types'; | ||
export declare function getLazy<T>(value: MaybeLazy<T>): T; | ||
export declare function stringify(value: any): string; | ||
import { ParsedReceiverEvent, ReceiverEvent } from './types'; | ||
export declare function getLazy<T>(value: T): T extends () => infer R ? R : T; | ||
export declare function stringify(value: any, replacer?: (key: string, value: any) => any): string; | ||
export declare function isReceiverEvent(event: any): event is ReceiverEvent; | ||
@@ -6,0 +6,0 @@ export declare function parseState(stateJSON: string): State<any, any>; |
@@ -8,8 +8,8 @@ import { __assign } from './_virtual/_tslib.js'; | ||
} | ||
function stringify(value) { | ||
function stringify(value, replacer) { | ||
try { | ||
return JSON.stringify(value); | ||
return JSON.stringify(value, replacer); | ||
} | ||
catch (e) { | ||
return safeStringify(value); | ||
return safeStringify(value, replacer); | ||
} | ||
@@ -16,0 +16,0 @@ } |
@@ -30,1 +30,15 @@ 'use strict'; | ||
}; | ||
function __values(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
} | ||
exports.__values = __values; |
@@ -9,5 +9,5 @@ import { Interpreter, EventObject } from 'xstate'; | ||
export declare function createDevTools(): XStateDevInterface; | ||
export declare function inspect(options?: Partial<InspectorOptions>): Inspector | undefined; | ||
export declare function inspect(options?: InspectorOptions): Inspector | undefined; | ||
export declare function createWindowReceiver(options?: Partial<WindowReceiverOptions>): InspectReceiver; | ||
export declare function createWebSocketReceiver(options: WebSocketReceiverOptions): InspectReceiver; | ||
//# sourceMappingURL=browser.d.ts.map |
@@ -9,2 +9,3 @@ 'use strict'; | ||
var utils = require('./utils.js'); | ||
var serialize = require('./serialize.js'); | ||
var inspectMachine = require('./inspectMachine.js'); | ||
@@ -51,3 +52,4 @@ | ||
return devTools; | ||
} | ||
}, | ||
serialize: undefined | ||
}; | ||
@@ -64,3 +66,3 @@ var getFinalOptions = function (options) { | ||
} | ||
var inspectMachine$1 = inspectMachine.createInspectMachine(devTools); | ||
var inspectMachine$1 = inspectMachine.createInspectMachine(devTools, options); | ||
var inspectService = xstate.interpret(inspectMachine$1).start(); | ||
@@ -95,8 +97,12 @@ var listeners = new Set(); | ||
}); | ||
var stringifyWithSerializer = function (value) { | ||
return utils.stringify(value, options === null || options === void 0 ? void 0 : options.serialize); | ||
}; | ||
devTools.onRegister(function (service) { | ||
var _a; | ||
var state = service.state || service.initialState; | ||
inspectService.send({ | ||
type: 'service.register', | ||
machine: utils.stringify(service.machine), | ||
state: utils.stringify(service.state || service.initialState), | ||
machine: serialize.stringifyMachine(service.machine, options === null || options === void 0 ? void 0 : options.serialize), | ||
state: serialize.stringifyState(state, options === null || options === void 0 ? void 0 : options.serialize), | ||
sessionId: service.sessionId, | ||
@@ -108,3 +114,3 @@ id: service.id, | ||
type: 'service.event', | ||
event: utils.stringify((service.state || service.initialState)._event), | ||
event: stringifyWithSerializer(state._event), | ||
sessionId: service.sessionId | ||
@@ -119,3 +125,3 @@ }); | ||
type: 'service.event', | ||
event: utils.stringify(utils$1.toSCXMLEvent(utils$1.toEventObject(event, payload))), | ||
event: stringifyWithSerializer(utils$1.toSCXMLEvent(utils$1.toEventObject(event, payload))), | ||
sessionId: service.sessionId | ||
@@ -126,3 +132,4 @@ }); | ||
service.subscribe(function (state) { | ||
// filter out synchronous notification from within `.start()` call when the `service.state` has not yet been assigned | ||
// filter out synchronous notification from within `.start()` call | ||
// when the `service.state` has not yet been assigned | ||
if (state === undefined) { | ||
@@ -133,3 +140,4 @@ return; | ||
type: 'service.state', | ||
state: utils.stringify(state), | ||
// TODO: investigate usage of structuredClone in browsers if available | ||
state: serialize.stringifyState(state, options === null || options === void 0 ? void 0 : options.serialize), | ||
sessionId: service.sessionId | ||
@@ -225,3 +233,3 @@ }); | ||
send: function (event) { | ||
ws.send(JSON.stringify(event)); | ||
ws.send(utils.stringify(event, options.serialize)); | ||
}, | ||
@@ -228,0 +236,0 @@ subscribe: function (next, onError, onComplete) { |
import { ActorRef } from 'xstate'; | ||
import { XStateDevInterface } from 'xstate/lib/devTools'; | ||
import { ReceiverEvent } from './types'; | ||
import { ReceiverEvent, Replacer } from './types'; | ||
export declare type InspectMachineEvent = ReceiverEvent | { | ||
@@ -16,3 +16,5 @@ type: 'unload'; | ||
}; | ||
export declare function createInspectMachine(devTools?: XStateDevInterface): import("xstate").StateMachine<{ | ||
export declare function createInspectMachine(devTools?: XStateDevInterface, options?: { | ||
serialize?: Replacer | undefined; | ||
}): import("xstate").StateMachine<{ | ||
client?: Pick<ActorRef<any, any>, "send"> | undefined; | ||
@@ -19,0 +21,0 @@ }, any, InspectMachineEvent, { |
@@ -6,5 +6,5 @@ 'use strict'; | ||
var xstate = require('xstate'); | ||
var utils = require('./utils.js'); | ||
var serialize = require('./serialize.js'); | ||
function createInspectMachine(devTools) { | ||
function createInspectMachine(devTools, options) { | ||
if (devTools === void 0) { devTools = globalThis.__xstate__; } | ||
@@ -73,4 +73,4 @@ var serviceMap = new Map(); | ||
type: 'service.register', | ||
machine: utils.stringify(service.machine), | ||
state: utils.stringify(service.state || service.initialState), | ||
machine: serialize.stringifyMachine(service.machine, options === null || options === void 0 ? void 0 : options.serialize), | ||
state: serialize.stringifyState(service.state || service.initialState, options === null || options === void 0 ? void 0 : options.serialize), | ||
sessionId: service.sessionId | ||
@@ -77,0 +77,0 @@ }); |
@@ -1,5 +0,6 @@ | ||
import * as WebSocket from 'ws'; | ||
import { Inspector } from './types'; | ||
import { WebSocketServer } from 'ws'; | ||
import { Inspector, Replacer } from './types'; | ||
interface ServerInspectorOptions { | ||
server: WebSocket.Server; | ||
server: WebSocketServer; | ||
serialize?: Replacer | undefined; | ||
} | ||
@@ -6,0 +7,0 @@ export declare function inspect(options: ServerInspectorOptions): Inspector; |
@@ -40,31 +40,23 @@ 'use strict'; | ||
createDevTools(); | ||
var inspectService = xstate.interpret(inspectMachine.createInspectMachine(globalThis.__xstate__)).start(); | ||
var client; | ||
server.on('connection', function connection(wss) { | ||
client = { | ||
id: '@@xstate/ws-client', | ||
send: function (event) { | ||
server.clients.forEach(function (ws) { | ||
if (ws.readyState === ws.OPEN) { | ||
ws.send(JSON.stringify(event)); | ||
} | ||
}); | ||
}, | ||
subscribe: function () { | ||
return { unsubscribe: function () { return void 0; } }; | ||
}, | ||
getSnapshot: function () { return undefined; } | ||
}; | ||
wss.on('message', function incoming(message) { | ||
var msg; | ||
if (typeof message === 'string') { | ||
msg = message; | ||
} | ||
else if (message instanceof Buffer) { | ||
msg = message.toString('utf8'); | ||
} | ||
else { | ||
var inspectService = xstate.interpret(inspectMachine.createInspectMachine(globalThis.__xstate__, options)).start(); | ||
var client = { | ||
id: '@@xstate/ws-client', | ||
send: function (event) { | ||
server.clients.forEach(function (wsClient) { | ||
if (wsClient.readyState === wsClient.OPEN) { | ||
wsClient.send(JSON.stringify(event)); | ||
} | ||
}); | ||
}, | ||
subscribe: function () { | ||
return { unsubscribe: function () { return void 0; } }; | ||
}, | ||
getSnapshot: function () { return undefined; } | ||
}; | ||
server.on('connection', function connection(wsClient) { | ||
wsClient.on('message', function incoming(data, isBinary) { | ||
if (isBinary) { | ||
return; | ||
} | ||
var jsonMessage = JSON.parse(msg); | ||
var jsonMessage = JSON.parse(data.toString()); | ||
inspectService.send(_tslib.__assign(_tslib.__assign({}, jsonMessage), { client: client })); | ||
@@ -137,2 +129,3 @@ }); | ||
inspectService.stop(); | ||
server.clients.forEach(function (client) { return client.terminate(); }); | ||
}); | ||
@@ -139,0 +132,0 @@ return inspector; |
@@ -6,8 +6,10 @@ import type { ActorRef, Interpreter, SCXML, State, StateMachine } from 'xstate'; | ||
export declare type ServiceListener = (service: Interpreter<any>) => void; | ||
export declare type Replacer = (key: string, value: any) => any; | ||
export interface InspectorOptions { | ||
url: string; | ||
iframe: MaybeLazy<HTMLIFrameElement | null | false>; | ||
devTools: MaybeLazy<XStateDevInterface>; | ||
url?: string; | ||
iframe?: MaybeLazy<HTMLIFrameElement | null | false>; | ||
devTools?: MaybeLazy<XStateDevInterface>; | ||
serialize?: Replacer | undefined; | ||
} | ||
export interface Inspector extends ActorRef<InspectMachineEvent, any> { | ||
export interface Inspector extends ActorRef<InspectMachineEvent, State<any, any, any>> { | ||
/** | ||
@@ -79,3 +81,4 @@ * Disconnects the inspector. | ||
protocol?: 'ws' | 'wss'; | ||
serialize: Replacer | undefined; | ||
} | ||
//# sourceMappingURL=types.d.ts.map |
import { State } from 'xstate'; | ||
import { MaybeLazy, ParsedReceiverEvent, ReceiverEvent } from './types'; | ||
export declare function getLazy<T>(value: MaybeLazy<T>): T; | ||
export declare function stringify(value: any): string; | ||
import { ParsedReceiverEvent, ReceiverEvent } from './types'; | ||
export declare function getLazy<T>(value: T): T extends () => infer R ? R : T; | ||
export declare function stringify(value: any, replacer?: (key: string, value: any) => any): string; | ||
export declare function isReceiverEvent(event: any): event is ReceiverEvent; | ||
@@ -6,0 +6,0 @@ export declare function parseState(stateJSON: string): State<any, any>; |
@@ -16,8 +16,8 @@ 'use strict'; | ||
} | ||
function stringify(value) { | ||
function stringify(value, replacer) { | ||
try { | ||
return JSON.stringify(value); | ||
return JSON.stringify(value, replacer); | ||
} | ||
catch (e) { | ||
return safeStringify__default['default'](value); | ||
return safeStringify__default['default'](value, replacer); | ||
} | ||
@@ -24,0 +24,0 @@ } |
{ | ||
"name": "@xstate/inspect", | ||
"version": "0.5.2", | ||
"version": "0.6.0", | ||
"description": "XState inspection utilities", | ||
@@ -33,3 +33,3 @@ "keywords": [ | ||
"clean": "rm -rf dist lib es tsconfig.tsbuildinfo", | ||
"test": "jest --passWithNoTests", | ||
"test": "jest", | ||
"build": "rollup -c", | ||
@@ -42,12 +42,18 @@ "prepublish": "npm run build" | ||
"devDependencies": { | ||
"@types/ws": "^7.2.6", | ||
"@types/ws": "^8.2.2", | ||
"rollup": "^2.35.1", | ||
"rollup-plugin-typescript2": "^0.30.0", | ||
"typescript": "^4.5.2", | ||
"ws": "^7.3.1", | ||
"ws": "^8.4.0", | ||
"xstate": "*" | ||
}, | ||
"peerDependencies": { | ||
"ws": "^7.3.1" | ||
"@types/ws": "^8.0.0", | ||
"ws": "^8.0.0" | ||
}, | ||
"peerDependenciesMeta": { | ||
"@types/ws": { | ||
"optional": true | ||
} | ||
}, | ||
"dependencies": { | ||
@@ -54,0 +60,0 @@ "fast-safe-stringify": "^2.0.7" |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
62033
30
1347
0
3