@nice-code/action 0.4.5 → 0.4.6

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.
@@ -4502,6 +4502,7 @@ var ActionInputAndOutputChip = ({
4502
4502
 
4503
4503
  // src/devtools/browser/components/action_list/ActionEntryRow.tsx
4504
4504
  import { jsxDEV as jsxDEV19, Fragment as Fragment10 } from "react/jsx-dev-runtime";
4505
+ var MAX_GROUP_DOTS = 5;
4505
4506
  function getLatestChipColor(status) {
4506
4507
  if (status === "failed")
4507
4508
  return "failed" /* failed */;
@@ -4822,15 +4823,29 @@ function ActionEntryRow({
4822
4823
  paddingLeft: "4.6em",
4823
4824
  paddingBottom: "2px"
4824
4825
  },
4825
- children: groupEntries.map((e, i) => /* @__PURE__ */ jsxDEV19(GroupDot, {
4826
- entry: e,
4827
- index: i,
4828
- total: groupEntries.length,
4829
- refTime: groupEntries[0].startTime,
4830
- isActive: selectedGroupCuid === e.cuid,
4831
- onSelect: () => onSelectGroupEntry?.(e.cuid)
4832
- }, e.cuid, false, undefined, this))
4833
- }, undefined, false, undefined, this)
4826
+ children: [
4827
+ groupEntries.slice(0, MAX_GROUP_DOTS).map((e, i) => /* @__PURE__ */ jsxDEV19(GroupDot, {
4828
+ entry: e,
4829
+ index: i,
4830
+ total: groupEntries.length,
4831
+ refTime: groupEntries[0].startTime,
4832
+ isActive: selectedGroupCuid === e.cuid,
4833
+ onSelect: () => onSelectGroupEntry?.(e.cuid)
4834
+ }, e.cuid, false, undefined, this)),
4835
+ groupEntries.length > MAX_GROUP_DOTS && /* @__PURE__ */ jsxDEV19("span", {
4836
+ style: {
4837
+ fontSize: "0.7em",
4838
+ opacity: 0.5,
4839
+ flexShrink: 0,
4840
+ lineHeight: 1
4841
+ },
4842
+ children: [
4843
+ "+ ",
4844
+ groupEntries.length - MAX_GROUP_DOTS
4845
+ ]
4846
+ }, undefined, true, undefined, this)
4847
+ ]
4848
+ }, undefined, true, undefined, this)
4834
4849
  ]
4835
4850
  }, undefined, true, undefined, this);
4836
4851
  }
package/build/index.js CHANGED
@@ -1993,7 +1993,7 @@ class ActionExternalClientHandler extends ActionHandler {
1993
1993
  client: this.externalClient,
1994
1994
  transOrd: transport.transOrd,
1995
1995
  transType: transport.type,
1996
- transInfo: transport.definition?.getRouteInfo(input)
1996
+ transInfo: transport.getRouteInfo(input)
1997
1997
  };
1998
1998
  }
1999
1999
  clearTransportCache() {
@@ -2053,6 +2053,9 @@ class TransportConnection {
2053
2053
  this.type = def.type;
2054
2054
  this.initialized = def.initialize();
2055
2055
  }
2056
+ getRouteInfo(input) {
2057
+ return this.definition?.getRouteInfo(input);
2058
+ }
2056
2059
  _getCacheKey(input) {
2057
2060
  const parts = this.initialized.getTransportCacheKey?.(input);
2058
2061
  if (parts == null)
@@ -2339,10 +2342,21 @@ var createUnsetTransportResolvers = (type) => ({
2339
2342
  }
2340
2343
  });
2341
2344
 
2345
+ // src/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/ws_util.ts
2346
+ function shortWs(url) {
2347
+ try {
2348
+ const u = new URL(url);
2349
+ return `${u.host}${u.pathname}`;
2350
+ } catch {
2351
+ return url;
2352
+ }
2353
+ }
2354
+
2342
2355
  // src/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/WebSocketConnection.ts
2343
2356
  class WebSocketConnection extends TransportConnection {
2344
2357
  resolvers;
2345
2358
  _abortSet = new Set;
2359
+ _liveSocketUrl;
2346
2360
  constructor(def, resolvers) {
2347
2361
  super({ ...def, type: "ws" /* ws */ });
2348
2362
  this.resolvers = resolvers ?? createUnsetTransportResolvers("ws" /* ws */);
@@ -2403,9 +2417,22 @@ class WebSocketConnection extends TransportConnection {
2403
2417
  readyData: this._finalizeTransportMethods(transportStatusInfo.readyData)
2404
2418
  };
2405
2419
  }
2420
+ getRouteInfo(input) {
2421
+ const base = this.definition?.getRouteInfo(input);
2422
+ if (base?.url != null || this._liveSocketUrl == null)
2423
+ return base;
2424
+ return {
2425
+ type: "ws" /* ws */,
2426
+ ...base,
2427
+ url: this._liveSocketUrl,
2428
+ summary: `ws ${shortWs(this._liveSocketUrl)}`
2429
+ };
2430
+ }
2406
2431
  _finalizeTransportMethods(wsData) {
2407
2432
  const ws = wsData.ws;
2408
2433
  const disconnectListeners = [];
2434
+ if (ws.url != null && ws.url !== "")
2435
+ this._liveSocketUrl = ws.url;
2409
2436
  const sendActionData = (inputs) => {
2410
2437
  const { action, runningAction, timeout } = inputs;
2411
2438
  if (action.type === "request" /* request */) {
@@ -2478,14 +2505,6 @@ class WebSocketConnection extends TransportConnection {
2478
2505
  function resolveMaybe2(value, input) {
2479
2506
  return typeof value === "function" ? value(input) : value;
2480
2507
  }
2481
- function shortWs(url) {
2482
- try {
2483
- const u = new URL(url);
2484
- return `${u.host}${u.pathname}`;
2485
- } catch {
2486
- return url;
2487
- }
2488
- }
2489
2508
 
2490
2509
  class WebSocketTransport extends Transport {
2491
2510
  options;
@@ -2497,29 +2516,35 @@ class WebSocketTransport extends Transport {
2497
2516
  _createSocket(input) {
2498
2517
  if (this.options.createWebSocket != null)
2499
2518
  return this.options.createWebSocket(input);
2519
+ if (this.options.url == null) {
2520
+ throw new Error("WebSocketTransport requires `url` or `createWebSocket` when not using `getTransport`.");
2521
+ }
2500
2522
  return new WebSocket(resolveMaybe2(this.options.url, input));
2501
2523
  }
2502
2524
  _createConnection(ctx) {
2525
+ const { url, getTransportCacheKey, getTransport } = this.options;
2503
2526
  return new WebSocketConnection({
2504
2527
  initialize: () => ({
2505
- getTransportCacheKey: this.options.getTransportCacheKey ?? ((input) => [resolveMaybe2(this.options.url, input)]),
2506
- getTransport: (input) => ({
2528
+ getTransportCacheKey: getTransportCacheKey ?? (url != null ? (input) => [resolveMaybe2(url, input)] : undefined),
2529
+ getTransport: getTransport ?? ((input) => ({
2507
2530
  status: "ready" /* ready */,
2508
2531
  readyData: {
2509
2532
  ws: this._createSocket(input),
2510
2533
  formatMessage: this.options.formatMessage,
2511
2534
  updateRunConfig: this.options.updateRunConfig
2512
2535
  }
2513
- })
2536
+ }))
2514
2537
  })
2515
2538
  }, ctx.resolvers);
2516
2539
  }
2517
2540
  getRouteInfo(input) {
2518
- const url = resolveMaybe2(this.options.url, input);
2541
+ if (this.options.getRouteInfo != null)
2542
+ return this.options.getRouteInfo(input);
2543
+ const url = this.options.url != null ? resolveMaybe2(this.options.url, input) : undefined;
2519
2544
  return {
2520
2545
  type: "ws" /* ws */,
2521
2546
  url,
2522
- summary: `ws ${shortWs(url)}`
2547
+ summary: url != null ? `ws ${shortWs(url)}` : "ws"
2523
2548
  };
2524
2549
  }
2525
2550
  }
@@ -1,5 +1,5 @@
1
- import { TransportConnection } from "../TransportConnection";
2
1
  import { ETransportType, type IActionTransportReadyData_Methods, type ITransportRouteActionParams } from "../Transport.types";
2
+ import { TransportConnection } from "../TransportConnection";
3
3
  import type { IActionTransportDef_Custom, IActionTransportInitialized_Custom, IActionTransportReadyData_Custom, TActionTransportDef_Custom_NoType } from "./TransportCustom.types";
4
4
  export declare class CustomConnection extends TransportConnection<ETransportType.custom, ITransportRouteActionParams, IActionTransportReadyData_Custom, IActionTransportInitialized_Custom, IActionTransportDef_Custom> {
5
5
  constructor(def: TActionTransportDef_Custom_NoType);
@@ -1,4 +1,4 @@
1
- import { Transport, type ITransportConnectionContext } from "../Transport";
1
+ import { type ITransportConnectionContext, Transport } from "../Transport";
2
2
  import { ETransportType, type ITransportMethod_SendActionData_Input, type ITransportRouteActionParams, type ITransportRouteInfo, type TSendReturnDataMethod, type TUpdateActionRunConfig } from "../Transport.types";
3
3
  import { CustomConnection } from "./CustomConnection";
4
4
  import type { IActionTransportInitialized_Custom } from "./TransportCustom.types";
@@ -1,5 +1,5 @@
1
- import { TransportConnection } from "../TransportConnection";
2
1
  import { ETransportType, type IActionTransportReadyData_Methods, type ITransportDispatchAction, type ITransportRouteActionParams } from "../Transport.types";
2
+ import { TransportConnection } from "../TransportConnection";
3
3
  import type { IActionTransportDef_Http, IActionTransportInitialized_Http, IActionTransportReadyData_Http, IActionTransportReadyParams_Http } from "./TransportHttp.types";
4
4
  export declare class HttpConnection extends TransportConnection<ETransportType.http, ITransportRouteActionParams, IActionTransportReadyData_Http, IActionTransportInitialized_Http, IActionTransportDef_Http> {
5
5
  constructor(def: Omit<IActionTransportDef_Http, "type">);
@@ -1,4 +1,4 @@
1
- import { Transport, type ITransportConnectionContext } from "../Transport";
1
+ import { type ITransportConnectionContext, Transport } from "../Transport";
2
2
  import { ETransportType, type ITransportRouteActionParams, type ITransportRouteInfo, type TUpdateActionRunConfig } from "../Transport.types";
3
3
  import { HttpConnection } from "./HttpConnection";
4
4
  import type { IHttpRequestParams } from "./TransportHttp.types";
@@ -1,5 +1,5 @@
1
1
  import type { Transport } from "./Transport";
2
- import { type ETransportType, type IActionTransportDef, type IActionTransportInitialized, type IActionTransportReadyData_Base, type IActionTransportReadyData_Methods, type ITransportRouteActionParams, type TTransportStatusInfo } from "./Transport.types";
2
+ import { type ETransportType, type IActionTransportDef, type IActionTransportInitialized, type IActionTransportReadyData_Base, type IActionTransportReadyData_Methods, type ITransportRouteActionParams, type ITransportRouteInfo, type TTransportStatusInfo } from "./Transport.types";
3
3
  /**
4
4
  * Live, per-handler transport runtime built from a reusable {@link Transport} definition. Holds the
5
5
  * connection-scoped state (ordinal, initialized config, sockets / abort sets) that must not be shared
@@ -13,6 +13,12 @@ export declare abstract class TransportConnection<T extends ETransportType = ETr
13
13
  /** Backref to the public definition that created this connection (used for devtools route info). */
14
14
  definition?: Transport<T>;
15
15
  constructor(def: DEF);
16
+ /**
17
+ * Devtools route info for an action routed through this live connection. Defaults to the stateless
18
+ * {@link definition}'s info; connections override to enrich it from live state (e.g. the actual
19
+ * resolved socket URL) when the definition couldn't resolve it on its own.
20
+ */
21
+ getRouteInfo(input: RP): ITransportRouteInfo | undefined;
16
22
  protected abstract _finalizeTransportMethods(inputs: RD): IActionTransportReadyData_Methods;
17
23
  protected _getCacheKey(input: RP): string | null;
18
24
  getCacheKey(input: RP): string | null;
@@ -1,12 +1,15 @@
1
+ import { ETransportType, type IActionTransportReadyData_Methods, type IActionTransportResolvers, type ITransportRouteActionParams, type ITransportRouteInfo, type TTransportStatusInfo } from "../Transport.types";
1
2
  import { TransportConnection } from "../TransportConnection";
2
- import { ETransportType, type IActionTransportReadyData_Methods, type IActionTransportResolvers, type ITransportRouteActionParams, type TTransportStatusInfo } from "../Transport.types";
3
3
  import type { IActionTransportDef_Ws, IActionTransportInitialized_Ws, IActionTransportReadyData_Ws } from "./TransportWebSocket.types";
4
4
  export declare class WebSocketConnection extends TransportConnection<ETransportType.ws, ITransportRouteActionParams, IActionTransportReadyData_Ws, IActionTransportInitialized_Ws, IActionTransportDef_Ws> {
5
5
  private resolvers;
6
6
  private _abortSet;
7
+ /** URL of the most recently resolved live socket — surfaced to devtools when the definition can't. */
8
+ private _liveSocketUrl?;
7
9
  constructor(def: Omit<IActionTransportDef_Ws, "type">, resolvers?: IActionTransportResolvers);
8
10
  protected _getCacheKey(_input: ITransportRouteActionParams): string;
9
11
  protected _processTransportStatus(input: ITransportRouteActionParams): TTransportStatusInfo<IActionTransportReadyData_Methods>;
12
+ getRouteInfo(input: ITransportRouteActionParams): ITransportRouteInfo | undefined;
10
13
  _finalizeTransportMethods(wsData: IActionTransportReadyData_Ws): IActionTransportReadyData_Methods;
11
14
  private _parseActionMessage;
12
15
  private _abortAll;
@@ -1,11 +1,11 @@
1
- import { Transport, type ITransportConnectionContext } from "../Transport";
1
+ import { type ITransportConnectionContext, Transport } from "../Transport";
2
2
  import { ETransportType, type ITransportRouteActionParams, type ITransportRouteInfo, type TUpdateActionRunConfig } from "../Transport.types";
3
- import type { IActionTransportReadyData_Ws } from "./TransportWebSocket.types";
3
+ import type { IActionTransportInitialized_Ws, IActionTransportReadyData_Ws } from "./TransportWebSocket.types";
4
4
  import { WebSocketConnection } from "./WebSocketConnection";
5
5
  type TMaybeResolved<T> = T | ((input: ITransportRouteActionParams) => T);
6
6
  export interface IWebSocketTransportOptions {
7
- /** WebSocket endpoint URL, either static or derived per action. */
8
- url: TMaybeResolved<string>;
7
+ /** WebSocket endpoint URL, either static or derived per action. Optional when `getTransport` is used. */
8
+ url?: TMaybeResolved<string>;
9
9
  /** Advanced escape hatch — provide your own socket (e.g. with sub-protocols). Overrides `url`. */
10
10
  createWebSocket?: (input: ITransportRouteActionParams) => WebSocket;
11
11
  /** Custom (de)serialization of action payloads on the wire. */
@@ -16,6 +16,15 @@ export interface IWebSocketTransportOptions {
16
16
  * across actions to the same endpoint instead of opening one per action.
17
17
  */
18
18
  getTransportCacheKey?: (input: ITransportRouteActionParams) => string[];
19
+ /**
20
+ * Advanced escape hatch — full control over readiness/initialization. Use this for contextual
21
+ * support detection (return `{ status: ETransportStatus.unsupported }` when the socket shouldn't be
22
+ * used) or async URL building (return `{ status: ETransportStatus.initializing, initializationPromise }`
23
+ * that resolves to a `ready` socket). When provided, `url` / `createWebSocket` are ignored.
24
+ */
25
+ getTransport?: IActionTransportInitialized_Ws["getTransport"];
26
+ /** Override the devtools route info for a specific action (useful alongside `getTransport`). */
27
+ getRouteInfo?: (input: ITransportRouteActionParams) => ITransportRouteInfo;
19
28
  }
20
29
  /**
21
30
  * Reusable WebSocket transport definition. Common case is just `new WebSocketTransport({ url })`. The
@@ -0,0 +1,2 @@
1
+ /** Compact a WebSocket URL to `host/pathname` for devtools display, falling back to the raw url. */
2
+ export declare function shortWs(url: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nice-code/action",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -44,9 +44,9 @@
44
44
  "build-types": "tsc --project tsconfig.build.json"
45
45
  },
46
46
  "dependencies": {
47
- "@nice-code/common-errors": "0.4.5",
48
- "@nice-code/error": "0.4.5",
49
- "@nice-code/util": "0.4.5",
47
+ "@nice-code/common-errors": "0.4.6",
48
+ "@nice-code/error": "0.4.6",
49
+ "@nice-code/util": "0.4.6",
50
50
  "@standard-schema/spec": "^1.1.0",
51
51
  "@tanstack/react-virtual": "^3.13.26",
52
52
  "http-status-codes": "^2.3.0",