Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@statelyai/inspect

Package Overview
Dependencies
Maintainers
3
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@statelyai/inspect - npm Package Compare versions

Comparing version 0.2.2 to 0.2.3

scripts/dev.sh

6

CHANGELOG.md
# @statelyai/inspect
## 0.2.3
### Patch Changes
- [#12](https://github.com/statelyai/inspect/pull/12) [`c878733`](https://github.com/statelyai/inspect/commit/c8787338e100f45649b14eae49f3eddacefd7df9) Thanks [@mellson](https://github.com/mellson)! - Adds `createSkyInspector`, which allows you to inspect machines in Node or the browser. The inspection will send the events to a server backend through websockets and allows you to open and share a live inspection URL.
## 0.2.2

@@ -4,0 +10,0 @@

56

dist/index.d.ts

@@ -98,22 +98,2 @@ import { InspectionEvent, Snapshot, AnyActorRef, AnyEventObject, Observer, Subscribable } from 'xstate';

interface WebSocketInspectorOptions extends InspectorOptions {
url: string;
}
declare class WebSocketAdapter implements Adapter {
private ws;
private status;
private deferredEvents;
private options;
constructor(options?: WebSocketInspectorOptions);
start(): void;
stop(): void;
send(inspectionEvent: StatelyInspectionEvent): void;
}
declare function createWebSocketInspector(options?: WebSocketInspectorOptions): Inspector<WebSocketAdapter>;
interface WebSocketReceiver extends Subscribable<StatelyInspectionEvent> {
}
declare function createWebSocketReceiver(options?: {
server: string;
}): WebSocketReceiver;
interface BrowserReceiver extends Subscribable<StatelyInspectionEvent> {

@@ -126,2 +106,5 @@ }

}
interface OptionalBrowserInspectorOptions {
send?: Adapter['send'];
}
/**

@@ -131,3 +114,3 @@ * Creates a browser-based inspector that sends events to a remote inspector window.

*/
declare function createBrowserInspector(options?: BrowserInspectorOptions): Inspector<BrowserAdapter>;
declare function createBrowserInspector(options?: BrowserInspectorOptions & OptionalBrowserInspectorOptions): Inspector<BrowserAdapter>;
interface BrowserReceiverOptions {

@@ -142,7 +125,7 @@ window?: Window;

declare class BrowserAdapter implements Adapter {
options: Required<BrowserInspectorOptions>;
options: Required<BrowserInspectorOptions> & OptionalBrowserInspectorOptions;
private status;
private deferredEvents;
targetWindow: Window | null;
constructor(options: Required<BrowserInspectorOptions>);
constructor(options: Required<BrowserInspectorOptions> & OptionalBrowserInspectorOptions);
start(): void;

@@ -153,2 +136,27 @@ stop(): void;

export { StatelyActorEvent, StatelyEventEvent, StatelyInspectionEvent, StatelySnapshotEvent, createBrowserInspector, createBrowserReceiver, createInspector, createWebSocketInspector, createWebSocketReceiver };
declare function createSkyInspector(options?: {
apiKey?: string;
onerror?: (error: Error) => void;
} & InspectorOptions): ReturnType<typeof createInspector>;
interface WebSocketInspectorOptions extends InspectorOptions {
url: string;
}
declare class WebSocketAdapter implements Adapter {
private ws;
private status;
private deferredEvents;
private options;
constructor(options?: WebSocketInspectorOptions);
start(): void;
stop(): void;
send(inspectionEvent: StatelyInspectionEvent): void;
}
declare function createWebSocketInspector(options?: WebSocketInspectorOptions): Inspector<WebSocketAdapter>;
interface WebSocketReceiver extends Subscribable<StatelyInspectionEvent> {
}
declare function createWebSocketReceiver(options?: {
server: string;
}): WebSocketReceiver;
export { StatelyActorEvent, StatelyEventEvent, StatelyInspectionEvent, StatelySnapshotEvent, createBrowserInspector, createBrowserReceiver, createInspector, createSkyInspector, createWebSocketInspector, createWebSocketReceiver };

@@ -36,2 +36,3 @@ "use strict";

createInspector: () => createInspector,
createSkyInspector: () => createSkyInspector,
createWebSocketInspector: () => createWebSocketInspector,

@@ -42,2 +43,6 @@ createWebSocketReceiver: () => createWebSocketReceiver

// src/browser.ts
var import_fast_safe_stringify = __toESM(require("fast-safe-stringify"));
var import_xstate = require("xstate");
// src/utils.ts

@@ -50,2 +55,3 @@ function toEventObject(event) {

}
var isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof document === "undefined";

@@ -58,2 +64,3 @@ // package.json

"@types/jsdom": "^21.1.6",
"@types/uuid": "^9.0.8",
jsdom: "^23.0.0",

@@ -66,3 +73,3 @@ tsup: "^7.2.0",

name: "@statelyai/inspect",
version: "0.2.2",
version: "0.2.3",
description: "Inspection utilities for state, actors, workflows, and state machines.",

@@ -74,3 +81,7 @@ main: "dist/index.js",

dependencies: {
"fast-safe-stringify": "^2.1.1",
"isomorphic-ws": "^5.0.0",
partysocket: "^0.0.25",
superjson: "^1",
uuid: "^9.0.1",
"safe-stable-stringify": "^2.4.3"

@@ -88,3 +99,4 @@ },

release: "changeset publish",
version: "changeset version"
version: "changeset version",
dev: "yarn build && ./scripts/dev.sh"
},

@@ -261,104 +273,2 @@ publishConfig: {

// src/webSocket.ts
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
var import_safe_stable_stringify2 = __toESM(require("safe-stable-stringify"));
var import_xstate = require("xstate");
var WebSocketAdapter = class {
ws;
status = "closed";
deferredEvents = [];
options;
constructor(options) {
this.options = {
filter: () => true,
serialize: (inspectionEvent) => JSON.parse((0, import_safe_stable_stringify2.default)(inspectionEvent)),
autoStart: true,
url: "ws://localhost:8080",
...options
};
}
start() {
const start = () => {
this.ws = new import_isomorphic_ws.default(this.options.url);
this.ws.onopen = () => {
console.log("websocket open");
this.status = "open";
this.deferredEvents.forEach((inspectionEvent) => {
const serializedEvent = this.options.serialize(inspectionEvent);
this.ws.send((0, import_safe_stable_stringify2.default)(serializedEvent));
});
};
this.ws.onclose = () => {
console.log("websocket closed");
};
this.ws.onerror = async (event) => {
console.error("websocket error", event);
await new Promise((res) => setTimeout(res, 5e3));
console.warn("restarting");
start();
};
this.ws.onmessage = (event) => {
if (typeof event.data !== "string") {
return;
}
console.log("message", event.data);
};
};
start();
}
stop() {
this.ws.close();
this.status = "closed";
}
send(inspectionEvent) {
if (this.status === "open") {
this.ws.send((0, import_safe_stable_stringify2.default)(inspectionEvent));
} else {
this.deferredEvents.push(inspectionEvent);
}
}
};
function createWebSocketInspector(options) {
const adapter = new WebSocketAdapter(options);
const inspector = createInspector(adapter, options);
return inspector;
}
function createWebSocketReceiver(options) {
const resolvedOptions = {
server: "ws://localhost:8080",
...options
};
const observers = /* @__PURE__ */ new Set();
const ws = new import_isomorphic_ws.default(resolvedOptions.server);
ws.onopen = () => {
console.log("websocket open");
ws.onmessage = (event) => {
if (typeof event.data !== "string") {
return;
}
console.log("message", event.data);
const eventData = JSON.parse(event.data);
observers.forEach((observer) => {
observer.next?.(eventData);
});
};
};
const receiver = {
subscribe(observerOrFn) {
const observer = (0, import_xstate.toObserver)(observerOrFn);
observers.add(observer);
return {
unsubscribe() {
observers.delete(observer);
}
};
}
};
return receiver;
}
// src/browser.ts
var import_xstate2 = require("xstate");
var import_safe_stable_stringify3 = __toESM(require("safe-stable-stringify"));
// src/useless.ts

@@ -393,3 +303,3 @@ var UselessAdapter = class {

filter: () => true,
serialize: (inspectionEvent) => JSON.parse((0, import_safe_stable_stringify3.default)(inspectionEvent)),
serialize: (inspectionEvent) => JSON.parse((0, import_fast_safe_stringify.default)(inspectionEvent)),
autoStart: true,

@@ -427,3 +337,3 @@ iframe: null,

subscribe(observerOrFn) {
const observer = (0, import_xstate2.toObserver)(observerOrFn);
const observer = (0, import_xstate.toObserver)(observerOrFn);
observers.add(observer);

@@ -481,3 +391,5 @@ return {

}
if (this.status === "connected") {
if (this.options.send) {
this.options.send(event);
} else if (this.status === "connected") {
const serializedEvent = this.options.serialize(event);

@@ -489,2 +401,145 @@ this.targetWindow?.postMessage(serializedEvent, "*");

};
// src/createSkyInspector.ts
var import_partysocket = __toESM(require("partysocket"));
var import_superjson = require("superjson");
var import_uuid = require("uuid");
var isDevMode = false;
function createSkyInspector(options = {}) {
const { host, apiBaseURL } = {
host: isDevMode ? "localhost:1999" : "stately-sky-beta.mellson.partykit.dev",
apiBaseURL: isDevMode ? "http://localhost:3000/registry/api/sky" : "https://stately.ai/registry/api/sky"
};
const server = apiBaseURL.replace("/api/sky", "");
const { apiKey, onerror, ...inspectorOptions } = options;
const sessionId = (0, import_uuid.v4)();
const room = `inspect-${sessionId}`;
const socket = new import_partysocket.default({
host,
room,
WebSocket: isNode ? require("isomorphic-ws") : void 0
});
const liveInspectUrl = `${server}/inspect/${sessionId}`;
socket.onerror = onerror ?? console.error;
socket.onopen = () => {
console.log("Connected to Sky, link to your live inspect session:");
console.log(liveInspectUrl);
};
if (isNode) {
return createInspector({
...inspectorOptions,
send(event) {
const skyEvent = apiKey ? { apiKey, ...event } : event;
socket.send((0, import_superjson.stringify)(skyEvent));
}
});
} else {
return createBrowserInspector({
...inspectorOptions,
url: liveInspectUrl,
send(event) {
const skyEvent = apiKey ? { apiKey, ...event } : event;
socket.send((0, import_superjson.stringify)(skyEvent));
}
});
}
}
// src/webSocket.ts
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
var import_safe_stable_stringify2 = __toESM(require("safe-stable-stringify"));
var import_xstate2 = require("xstate");
var WebSocketAdapter = class {
ws;
status = "closed";
deferredEvents = [];
options;
constructor(options) {
this.options = {
filter: () => true,
serialize: (inspectionEvent) => JSON.parse((0, import_safe_stable_stringify2.default)(inspectionEvent)),
autoStart: true,
url: "ws://localhost:8080",
...options
};
}
start() {
const start = () => {
this.ws = new import_isomorphic_ws.default(this.options.url);
this.ws.onopen = () => {
console.log("websocket open");
this.status = "open";
this.deferredEvents.forEach((inspectionEvent) => {
const serializedEvent = this.options.serialize(inspectionEvent);
this.ws.send((0, import_safe_stable_stringify2.default)(serializedEvent));
});
};
this.ws.onclose = () => {
console.log("websocket closed");
};
this.ws.onerror = async (event) => {
console.error("websocket error", event);
await new Promise((res) => setTimeout(res, 5e3));
console.warn("restarting");
start();
};
this.ws.onmessage = (event) => {
if (typeof event.data !== "string") {
return;
}
console.log("message", event.data);
};
};
start();
}
stop() {
this.ws.close();
this.status = "closed";
}
send(inspectionEvent) {
if (this.status === "open") {
this.ws.send((0, import_safe_stable_stringify2.default)(inspectionEvent));
} else {
this.deferredEvents.push(inspectionEvent);
}
}
};
function createWebSocketInspector(options) {
const adapter = new WebSocketAdapter(options);
const inspector = createInspector(adapter, options);
return inspector;
}
function createWebSocketReceiver(options) {
const resolvedOptions = {
server: "ws://localhost:8080",
...options
};
const observers = /* @__PURE__ */ new Set();
const ws = new import_isomorphic_ws.default(resolvedOptions.server);
ws.onopen = () => {
console.log("websocket open");
ws.onmessage = (event) => {
if (typeof event.data !== "string") {
return;
}
console.log("message", event.data);
const eventData = JSON.parse(event.data);
observers.forEach((observer) => {
observer.next?.(eventData);
});
};
};
const receiver = {
subscribe(observerOrFn) {
const observer = (0, import_xstate2.toObserver)(observerOrFn);
observers.add(observer);
return {
unsubscribe() {
observers.delete(observer);
}
};
}
};
return receiver;
}
// Annotate the CommonJS export names for ESM import in node:

@@ -495,4 +550,5 @@ 0 && (module.exports = {

createInspector,
createSkyInspector,
createWebSocketInspector,
createWebSocketReceiver
});

@@ -6,2 +6,3 @@ {

"@types/jsdom": "^21.1.6",
"@types/uuid": "^9.0.8",
"jsdom": "^23.0.0",

@@ -14,3 +15,3 @@ "tsup": "^7.2.0",

"name": "@statelyai/inspect",
"version": "0.2.2",
"version": "0.2.3",
"description": "Inspection utilities for state, actors, workflows, and state machines.",

@@ -22,3 +23,7 @@ "main": "dist/index.js",

"dependencies": {
"fast-safe-stringify": "^2.1.1",
"isomorphic-ws": "^5.0.0",
"partysocket": "^0.0.25",
"superjson": "^1",
"uuid": "^9.0.1",
"safe-stable-stringify": "^2.4.3"

@@ -39,4 +44,5 @@ },

"release": "changeset publish",
"version": "changeset version"
"version": "changeset version",
"dev": "yarn build && ./scripts/dev.sh"
}
}

@@ -0,5 +1,5 @@

import safeStringify from 'fast-safe-stringify';
import { AnyEventObject, Observer, Subscribable, toObserver } from 'xstate';
import { InspectorOptions, createInspector } from './createInspector';
import { Adapter, Inspector, StatelyInspectionEvent } from './types';
import { InspectorOptions, createInspector } from './createInspector';
import safeStringify from 'safe-stable-stringify';
import { UselessAdapter } from './useless';

@@ -36,2 +36,6 @@

interface OptionalBrowserInspectorOptions {
send?: Adapter['send'];
}
/**

@@ -42,3 +46,3 @@ * Creates a browser-based inspector that sends events to a remote inspector window.

export function createBrowserInspector(
options?: BrowserInspectorOptions
options?: BrowserInspectorOptions & OptionalBrowserInspectorOptions
): Inspector<BrowserAdapter> {

@@ -62,3 +66,4 @@ const resolvedWindow =

window: resolvedWindow,
} satisfies Required<BrowserInspectorOptions>;
} satisfies Required<BrowserInspectorOptions> &
OptionalBrowserInspectorOptions;
const adapter = new BrowserAdapter(resolvedOptions);

@@ -143,3 +148,6 @@ const inspector = createInspector(adapter, resolvedOptions);

constructor(public options: Required<BrowserInspectorOptions>) {}
constructor(
public options: Required<BrowserInspectorOptions> &
OptionalBrowserInspectorOptions
) {}
public start() {

@@ -180,8 +188,11 @@ this.targetWindow = this.options.iframe

if (this.status === 'connected') {
if (this.options.send) {
this.options.send(event);
} else if (this.status === 'connected') {
const serializedEvent = this.options.serialize(event);
this.targetWindow?.postMessage(serializedEvent, '*');
}
this.deferredEvents.push(event);
}
}

@@ -0,9 +1,10 @@

export { createBrowserInspector, createBrowserReceiver } from './browser';
export { createInspector } from './createInspector';
export { createWebSocketInspector, createWebSocketReceiver } from './webSocket';
export { createBrowserInspector, createBrowserReceiver } from './browser';
export { createSkyInspector } from './createSkyInspector';
export type {
StatelyActorEvent,
StatelyEventEvent,
StatelyInspectionEvent,
StatelyEventEvent,
StatelySnapshotEvent,
} from './types';
export { createWebSocketInspector, createWebSocketReceiver } from './webSocket';

@@ -1,2 +0,2 @@

import type { AnyEventObject, AnyActorRef } from 'xstate';
import type { AnyActorRef, AnyEventObject } from 'xstate';

@@ -19,1 +19,6 @@ export function toEventObject(event: AnyEventObject | string): AnyEventObject {

}
export const isNode =
typeof process !== 'undefined' &&
typeof process.versions?.node !== 'undefined' &&
typeof document === 'undefined';
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc