New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.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.0.10 to 0.0.11

src/webSocket.ts

42

dist/index.d.ts

@@ -33,4 +33,6 @@ import { InspectionEvent, Snapshot, AnyActorRef, AnyEventObject, Observer, Subscribable } from 'xstate';

interface InspectedSnapshot {
status: Snapshot<unknown>['status'];
status?: Snapshot<unknown>['status'];
context?: any;
value?: any;
output?: any;
}

@@ -94,6 +96,12 @@ interface Inspector<TAdapter extends Adapter> {

serialize?: (event: StatelyInspectionEvent) => StatelyInspectionEvent;
/**
* Whether to automatically start the inspector.
*
* @default true
*/
autoStart?: boolean;
}
declare function createInspector<TAdapter extends Adapter>(adapter: TAdapter): Inspector<TAdapter>;
interface WebSocketAdapterOptions extends InspectorOptions {
interface WebSocketInspectorOptions extends InspectorOptions {
url: string;

@@ -106,3 +114,3 @@ }

private options;
constructor(options: WebSocketAdapterOptions);
constructor(options?: WebSocketInspectorOptions);
start(): void;

@@ -112,14 +120,8 @@ stop(): void;

}
declare function createWebSocketInspector(url: string): Inspector<WebSocketAdapter>;
declare class BrowserAdapter implements Adapter {
private status;
private deferredEvents;
targetWindow: Window | null;
private options;
constructor(options?: BrowserInspectorOptions);
start(): void;
stop(): void;
send(event: StatelyInspectionEvent): void;
declare function createWebSocketInspector(options?: WebSocketInspectorOptions): Inspector<WebSocketAdapter>;
interface WebSocketReceiver extends Subscribable<StatelyInspectionEvent> {
}
declare function createWebSocketReceiver(options?: {
server: string;
}): WebSocketReceiver;

@@ -146,3 +148,13 @@ interface BrowserReceiver extends Subscribable<StatelyInspectionEvent> {

declare function createBrowserReceiver(options?: BrowserReceiverOptions): BrowserReceiver;
declare class BrowserAdapter implements Adapter {
options: Required<BrowserInspectorOptions>;
private status;
private deferredEvents;
targetWindow: Window | null;
constructor(options: Required<BrowserInspectorOptions>);
start(): void;
stop(): void;
send(event: StatelyInspectionEvent): void;
}
export { StatelyActorEvent, StatelyEventEvent, StatelyInspectionEvent, StatelySnapshotEvent, createBrowserInspector, createBrowserReceiver, createInspector, createWebSocketInspector };
export { StatelyActorEvent, StatelyEventEvent, StatelyInspectionEvent, StatelySnapshotEvent, createBrowserInspector, createBrowserReceiver, createInspector, createWebSocketInspector, createWebSocketReceiver };

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

createInspector: () => createInspector,
createWebSocketInspector: () => createWebSocketInspector
createWebSocketInspector: () => createWebSocketInspector,
createWebSocketReceiver: () => createWebSocketReceiver
});

@@ -60,3 +61,3 @@ module.exports = __toCommonJS(src_exports);

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

@@ -144,4 +145,7 @@ main: "dist/index.js",

type: "@xstate.snapshot",
snapshot: info.snapshot,
event: info.event ?? null,
snapshot: {
status: "active",
...info.snapshot
},
event: info.event ?? { type: "" },
sessionId,

@@ -235,5 +239,6 @@ id: null,

// src/webSocketAdapter.ts
// src/webSocket.ts
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
var import_fast_safe_stringify = __toESM(require("fast-safe-stringify"));
var import_xstate = require("xstate");
var WebSocketAdapter = class {

@@ -248,2 +253,4 @@ ws;

serialize: (event) => JSON.parse((0, import_fast_safe_stringify.default)(event)),
autoStart: true,
url: "ws://localhost:8080",
...options

@@ -292,65 +299,44 @@ };

};
function createWebSocketInspector(url) {
const adapter = new WebSocketAdapter({ url });
function createWebSocketInspector(options) {
const adapter = new WebSocketAdapter(options);
const inspector = createInspector(adapter);
return inspector;
}
// src/browser.ts
var import_xstate = require("xstate");
// src/BrowserAdapter.ts
var import_fast_safe_stringify2 = __toESM(require("fast-safe-stringify"));
var BrowserAdapter = class {
status = "disconnected";
deferredEvents = [];
targetWindow = null;
options;
constructor(options = {}) {
const resolvedOptions = {
url: "https://stately.ai/registry/inspect",
filter: () => true,
serialize: (event) => JSON.parse((0, import_fast_safe_stringify2.default)(event)),
iframe: null,
...options,
window: options.window ?? window
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);
});
};
this.options = resolvedOptions;
}
start() {
this.targetWindow = this.options.iframe ? null : this.options.window.open(String(this.options.url), "xstateinspector");
if (this.options.iframe) {
this.options.iframe.addEventListener("load", () => {
this.targetWindow = this.options.iframe?.contentWindow ?? null;
});
this.options.iframe?.setAttribute("src", String(this.options.url));
};
const receiver = {
subscribe(observerOrFn) {
const observer = (0, import_xstate.toObserver)(observerOrFn);
observers.add(observer);
return {
unsubscribe() {
observers.delete(observer);
}
};
}
this.options.window.addEventListener("message", (event) => {
if (isEventObject(event.data) && event.data.type === "@statelyai.connected") {
this.status = "connected";
this.deferredEvents.forEach((event2) => {
const serializedEvent = this.options.serialize(event2);
this.targetWindow?.postMessage(serializedEvent, "*");
});
}
});
}
stop() {
this.targetWindow?.postMessage({ type: "@statelyai.disconnected" }, "*");
this.status = "disconnected";
}
send(event) {
const shouldSendEvent = this.options.filter(event);
if (!shouldSendEvent) {
return;
}
if (this.status === "connected") {
const serializedEvent = this.options.serialize(event);
this.targetWindow?.postMessage(serializedEvent, "*");
}
this.deferredEvents.push(event);
}
};
};
return receiver;
}
// src/browser.ts
var import_xstate2 = require("xstate");
var import_fast_safe_stringify2 = __toESM(require("fast-safe-stringify"));
var CONNECTION_EVENT = "@statelyai.connected";

@@ -364,5 +350,16 @@ function isEventObject(event) {

function createBrowserInspector(options) {
const adapter = new BrowserAdapter(options);
const resolvedOptions = {
url: "https://stately.ai/inspect",
filter: () => true,
serialize: (event) => JSON.parse((0, import_fast_safe_stringify2.default)(event)),
autoStart: true,
iframe: null,
...options,
window: options?.window ?? window
};
const adapter = new BrowserAdapter(resolvedOptions);
const inspector = createInspector(adapter);
inspector.start();
if (resolvedOptions.autoStart) {
inspector.start();
}
return inspector;

@@ -390,3 +387,3 @@ }

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

@@ -410,2 +407,43 @@ return {

}
var BrowserAdapter = class {
constructor(options) {
this.options = options;
}
status = "disconnected";
deferredEvents = [];
targetWindow = null;
start() {
this.targetWindow = this.options.iframe ? null : this.options.window.open(String(this.options.url), "xstateinspector");
if (this.options.iframe) {
this.options.iframe.addEventListener("load", () => {
this.targetWindow = this.options.iframe?.contentWindow ?? null;
});
this.options.iframe?.setAttribute("src", String(this.options.url));
}
this.options.window.addEventListener("message", (event) => {
if (isEventObject(event.data) && event.data.type === "@statelyai.connected") {
this.status = "connected";
this.deferredEvents.forEach((event2) => {
const serializedEvent = this.options.serialize(event2);
this.targetWindow?.postMessage(serializedEvent, "*");
});
}
});
}
stop() {
this.targetWindow?.postMessage({ type: "@statelyai.disconnected" }, "*");
this.status = "disconnected";
}
send(event) {
const shouldSendEvent = this.options.filter(event);
if (!shouldSendEvent) {
return;
}
if (this.status === "connected") {
const serializedEvent = this.options.serialize(event);
this.targetWindow?.postMessage(serializedEvent, "*");
}
this.deferredEvents.push(event);
}
};
// Annotate the CommonJS export names for ESM import in node:

@@ -416,3 +454,4 @@ 0 && (module.exports = {

createInspector,
createWebSocketInspector
createWebSocketInspector,
createWebSocketReceiver
});

@@ -11,3 +11,3 @@ {

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

@@ -14,0 +14,0 @@ "main": "dist/index.js",

@@ -7,3 +7,3 @@ import { expect, test } from 'vitest';

test('Inspector observes a state machine', async () => {
test('inspector observes a state machine', async () => {
const dom = new JSDOM();

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

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

@@ -42,7 +42,18 @@ interface BrowserReceiver extends Subscribable<StatelyInspectionEvent> {}

): Inspector<BrowserAdapter> {
const adapter = new BrowserAdapter(options);
const resolvedOptions = {
url: 'https://stately.ai/inspect',
filter: () => true,
serialize: (event) => JSON.parse(safeStringify(event)),
autoStart: true,
iframe: null,
...options,
window: options?.window ?? window,
} satisfies Required<BrowserInspectorOptions>;
const adapter = new BrowserAdapter(resolvedOptions);
const inspector = createInspector(adapter);
// Start immediately
inspector.start();
if (resolvedOptions.autoStart) {
inspector.start();
}

@@ -94,11 +105,5 @@ return inspector;

observers.add(observer);
// const listener = (event: MessageEvent) => {
// observer.next?.(event.data);
// };
// window.addEventListener('message', listener);
return {
unsubscribe() {
// window.removeEventListener('message', listener);
observers.delete(observer);

@@ -121,1 +126,50 @@ },

}
export class BrowserAdapter implements Adapter {
private status = 'disconnected' as 'disconnected' | 'connected';
private deferredEvents: StatelyInspectionEvent[] = [];
public targetWindow: Window | null = null;
constructor(public options: Required<BrowserInspectorOptions>) {}
public start() {
this.targetWindow = this.options.iframe
? null
: this.options.window.open(String(this.options.url), 'xstateinspector');
if (this.options.iframe) {
this.options.iframe.addEventListener('load', () => {
this.targetWindow = this.options.iframe?.contentWindow ?? null;
});
this.options.iframe?.setAttribute('src', String(this.options.url));
}
this.options.window.addEventListener('message', (event) => {
if (
isEventObject(event.data) &&
event.data.type === '@statelyai.connected'
) {
this.status = 'connected';
this.deferredEvents.forEach((event) => {
const serializedEvent = this.options.serialize(event);
this.targetWindow?.postMessage(serializedEvent, '*');
});
}
});
}
public stop() {
this.targetWindow?.postMessage({ type: '@statelyai.disconnected' }, '*');
this.status = 'disconnected';
}
public send(event: StatelyInspectionEvent) {
const shouldSendEvent = this.options.filter(event);
if (!shouldSendEvent) {
return;
}
if (this.status === 'connected') {
const serializedEvent = this.options.serialize(event);
this.targetWindow?.postMessage(serializedEvent, '*');
}
this.deferredEvents.push(event);
}
}

@@ -36,2 +36,8 @@ import {

serialize?: (event: StatelyInspectionEvent) => StatelyInspectionEvent;
/**
* Whether to automatically start the inspector.
*
* @default true
*/
autoStart?: boolean;
}

@@ -42,2 +48,3 @@

serialize: (event) => event,
autoStart: true,
};

@@ -105,4 +112,7 @@

type: '@xstate.snapshot',
snapshot: info.snapshot as unknown as Snapshot<unknown>,
event: info.event ?? (null as any),
snapshot: {
status: 'active',
...info.snapshot,
} as unknown as Snapshot<unknown>,
event: info.event ?? { type: '' },
sessionId,

@@ -109,0 +119,0 @@ id: null as any,

export { createInspector } from './createInspector';
export { createWebSocketInspector } from './webSocketAdapter';
export { createWebSocketInspector, createWebSocketReceiver } from './webSocket';
export { createBrowserInspector, createBrowserReceiver } from './browser';

@@ -4,0 +4,0 @@ export type {

@@ -54,4 +54,6 @@ import {

export interface InspectedSnapshot {
status: Snapshot<unknown>['status'];
status?: Snapshot<unknown>['status'];
context?: any;
value?: any;
output?: any;
}

@@ -58,0 +60,0 @@

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