@nice-code/action 0.4.3 → 0.4.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 +20 -28
- package/build/devtools/browser/index.js +173 -57
- package/build/devtools/server/index.js +2 -0
- package/build/index.js +303 -165
- package/build/types/ActionDefinition/Action/Payload/ActionPayload.types.d.ts +2 -1
- package/build/types/ActionRuntime/Handler/ExternalClient/ActionExternalClientHandler.d.ts +4 -3
- package/build/types/ActionRuntime/Handler/ExternalClient/ActionExternalClientHandler.types.d.ts +3 -3
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/ConnectionTransportManager.d.ts +2 -2
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Custom/{TransportCustom.d.ts → CustomConnection.d.ts} +2 -2
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Custom/CustomTransport.d.ts +33 -0
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Http/{TransportHttp.d.ts → HttpConnection.d.ts} +2 -2
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Http/HttpTransport.d.ts +28 -0
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Http/TransportHttp.types.d.ts +1 -2
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Transport.d.ts +25 -12
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Transport.types.d.ts +15 -2
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/TransportConnection.d.ts +21 -0
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/{TransportWebSocket.d.ts → WebSocketConnection.d.ts} +2 -2
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/WebSocketTransport.d.ts +32 -0
- package/build/types/ActionRuntime/test/helpers/new_action_test_data.d.ts +2 -2
- package/build/types/devtools/browser/components/HandlerChips.d.ts +11 -0
- package/build/types/devtools/browser/components/Tooltip.d.ts +11 -1
- package/build/types/devtools/browser/devtools_dock.d.ts +7 -0
- package/build/types/devtools/core/ActionDevtools.types.d.ts +5 -0
- package/build/types/index.d.ts +4 -4
- package/package.json +4 -4
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Transport.combined.types.d.ts +0 -4
package/README.md
CHANGED
|
@@ -147,28 +147,18 @@ import {
|
|
|
147
147
|
ActionRuntime,
|
|
148
148
|
ActionExternalClientHandler,
|
|
149
149
|
RuntimeCoordinate,
|
|
150
|
-
|
|
151
|
-
ETransportStatus,
|
|
150
|
+
HttpTransport,
|
|
152
151
|
} from "@nice-code/action";
|
|
153
152
|
|
|
154
153
|
export const clientCoord = RuntimeCoordinate.env("frontend");
|
|
155
154
|
export const serverCoord = RuntimeCoordinate.env("backend");
|
|
156
155
|
|
|
156
|
+
// Transport definitions are plain, reusable objects you construct once.
|
|
157
|
+
const serverHttp = new HttpTransport({ url: "https://api.example.com/resolve_action" });
|
|
158
|
+
|
|
157
159
|
const serverHandler = new ActionExternalClientHandler({
|
|
158
|
-
|
|
159
|
-
transports: [
|
|
160
|
-
{
|
|
161
|
-
type: ETransportType.http,
|
|
162
|
-
initialize: () => ({
|
|
163
|
-
getTransport: () => ({
|
|
164
|
-
status: ETransportStatus.ready,
|
|
165
|
-
readyData: {
|
|
166
|
-
createRequest: () => ({ url: "https://api.example.com/resolve_action" }),
|
|
167
|
-
},
|
|
168
|
-
}),
|
|
169
|
-
}),
|
|
170
|
-
},
|
|
171
|
-
],
|
|
160
|
+
runtimeCoordinate: serverCoord,
|
|
161
|
+
transports: [serverHttp],
|
|
172
162
|
}).forDomain(userDomain);
|
|
173
163
|
|
|
174
164
|
export const clientRuntime = new ActionRuntime(clientCoord)
|
|
@@ -226,20 +216,22 @@ function RenameUser() {
|
|
|
226
216
|
## WebSocket transport
|
|
227
217
|
|
|
228
218
|
```ts
|
|
229
|
-
{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}),
|
|
238
|
-
}),
|
|
239
|
-
}
|
|
219
|
+
import { WebSocketTransport } from "@nice-code/action";
|
|
220
|
+
|
|
221
|
+
const serverWs = new WebSocketTransport({ url: "wss://api.example.com/resolve_action/ws" });
|
|
222
|
+
|
|
223
|
+
const serverHandler = new ActionExternalClientHandler({
|
|
224
|
+
runtimeCoordinate: serverCoord,
|
|
225
|
+
transports: [serverWs, serverHttp], // WebSocket preferred, HTTP as fallback
|
|
226
|
+
}).forDomain(userDomain);
|
|
240
227
|
```
|
|
241
228
|
|
|
242
|
-
|
|
229
|
+
The socket is opened lazily and reused across actions to the same endpoint. Multiple transports can
|
|
230
|
+
be registered; the runtime picks the best available one (WebSocket preferred for lower latency, HTTP
|
|
231
|
+
as fallback). For channels nice-action doesn't model natively, use `CustomTransport`.
|
|
232
|
+
|
|
233
|
+
For advanced cases, `HttpTransport` / `WebSocketTransport` accept functions to derive the URL or
|
|
234
|
+
headers per action (e.g. `new HttpTransport({ url: (input) => \`/api/${input.action.id}\` })`).
|
|
243
235
|
|
|
244
236
|
---
|
|
245
237
|
|
|
@@ -1850,6 +1850,8 @@ function extractRouting(context) {
|
|
|
1850
1850
|
insId: handler.client.insId
|
|
1851
1851
|
} : undefined,
|
|
1852
1852
|
transport: isExternal ? handler.transType : undefined,
|
|
1853
|
+
transportSummary: isExternal ? handler.transInfo?.summary : undefined,
|
|
1854
|
+
transportUrl: isExternal ? handler.transInfo?.url : undefined,
|
|
1853
1855
|
time: item.time
|
|
1854
1856
|
};
|
|
1855
1857
|
});
|
|
@@ -1957,7 +1959,7 @@ class ActionDevtoolsCore {
|
|
|
1957
1959
|
}
|
|
1958
1960
|
}
|
|
1959
1961
|
// src/devtools/browser/NiceActionDevtools.tsx
|
|
1960
|
-
import { useEffect as useEffect4, useId, useMemo as useMemo3, useReducer, useState as
|
|
1962
|
+
import { useEffect as useEffect4, useId, useMemo as useMemo3, useReducer, useState as useState12 } from "react";
|
|
1961
1963
|
|
|
1962
1964
|
// src/devtools/core/devtools_colors.ts
|
|
1963
1965
|
var DEVTOOL_COLOR_SEMANTIC_ERROR = "#FF5C5C";
|
|
@@ -2068,7 +2070,7 @@ var SEMANTIC_COLORS = {
|
|
|
2068
2070
|
};
|
|
2069
2071
|
|
|
2070
2072
|
// src/devtools/browser/components/action_detail/ActionDetailPanel.tsx
|
|
2071
|
-
import { useMemo, useState as
|
|
2073
|
+
import { useMemo, useState as useState8 } from "react";
|
|
2072
2074
|
|
|
2073
2075
|
// src/devtools/browser/ui_util/size.ts
|
|
2074
2076
|
function getSizeValue(size) {
|
|
@@ -3230,10 +3232,11 @@ function ActionErrorDisplay({
|
|
|
3230
3232
|
import { Component } from "lucide-react";
|
|
3231
3233
|
|
|
3232
3234
|
// src/devtools/browser/components/Chip.tsx
|
|
3233
|
-
import { useState as
|
|
3235
|
+
import { useState as useState4 } from "react";
|
|
3234
3236
|
|
|
3235
3237
|
// src/devtools/browser/components/Tooltip.tsx
|
|
3236
|
-
import {
|
|
3238
|
+
import { useState as useState3 } from "react";
|
|
3239
|
+
import { jsxDEV as jsxDEV6, Fragment as Fragment2 } from "react/jsx-dev-runtime";
|
|
3237
3240
|
function Tooltip({
|
|
3238
3241
|
anchor,
|
|
3239
3242
|
config,
|
|
@@ -3312,9 +3315,31 @@ function Tooltip({
|
|
|
3312
3315
|
]
|
|
3313
3316
|
}, undefined, true, undefined, this);
|
|
3314
3317
|
}
|
|
3318
|
+
function HoverTooltip({
|
|
3319
|
+
config,
|
|
3320
|
+
children,
|
|
3321
|
+
style
|
|
3322
|
+
}) {
|
|
3323
|
+
const [anchor, setAnchor] = useState3(null);
|
|
3324
|
+
const enabled = config != null;
|
|
3325
|
+
return /* @__PURE__ */ jsxDEV6(Fragment2, {
|
|
3326
|
+
children: [
|
|
3327
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
3328
|
+
onMouseEnter: enabled ? (e) => setAnchor(e.currentTarget.getBoundingClientRect()) : undefined,
|
|
3329
|
+
onMouseLeave: enabled ? () => setAnchor(null) : undefined,
|
|
3330
|
+
style: { ...style, cursor: enabled ? "default" : style?.cursor },
|
|
3331
|
+
children
|
|
3332
|
+
}, undefined, false, undefined, this),
|
|
3333
|
+
enabled && anchor != null && config != null && /* @__PURE__ */ jsxDEV6(Tooltip, {
|
|
3334
|
+
anchor,
|
|
3335
|
+
config
|
|
3336
|
+
}, undefined, false, undefined, this)
|
|
3337
|
+
]
|
|
3338
|
+
}, undefined, true, undefined, this);
|
|
3339
|
+
}
|
|
3315
3340
|
|
|
3316
3341
|
// src/devtools/browser/components/Chip.tsx
|
|
3317
|
-
import { jsxDEV as jsxDEV7, Fragment as
|
|
3342
|
+
import { jsxDEV as jsxDEV7, Fragment as Fragment3 } from "react/jsx-dev-runtime";
|
|
3318
3343
|
var CHIP_SIZE_STYLES = {
|
|
3319
3344
|
["sm" /* sm */]: { fontSize: "0.8em", padding: "1px 3px" },
|
|
3320
3345
|
["md" /* md */]: { fontSize: "0.9em", padding: "1px 4px" },
|
|
@@ -3328,13 +3353,13 @@ function Chip({
|
|
|
3328
3353
|
tooltip,
|
|
3329
3354
|
children
|
|
3330
3355
|
}) {
|
|
3331
|
-
const [anchor, setAnchor] =
|
|
3356
|
+
const [anchor, setAnchor] = useState4(null);
|
|
3332
3357
|
const hasTooltip = tooltip != null;
|
|
3333
3358
|
const { fontSize, padding } = CHIP_SIZE_STYLES[size];
|
|
3334
3359
|
const colorEntry = SEMANTIC_COLORS[color];
|
|
3335
3360
|
const resolvedColor = subtle ? colorEntry.subtle?.color ?? colorEntry.color : colorEntry.color;
|
|
3336
3361
|
const resolvedBorderColor = subtle ? colorEntry.subtle?.borderColor ?? "transparent" : colorEntry.borderColor;
|
|
3337
|
-
return /* @__PURE__ */ jsxDEV7(
|
|
3362
|
+
return /* @__PURE__ */ jsxDEV7(Fragment3, {
|
|
3338
3363
|
children: [
|
|
3339
3364
|
/* @__PURE__ */ jsxDEV7("span", {
|
|
3340
3365
|
onMouseEnter: hasTooltip ? (e) => setAnchor(e.currentTarget.getBoundingClientRect()) : undefined,
|
|
@@ -3363,8 +3388,8 @@ function Chip({
|
|
|
3363
3388
|
}
|
|
3364
3389
|
|
|
3365
3390
|
// src/devtools/browser/components/Icon.tsx
|
|
3366
|
-
import { useState as
|
|
3367
|
-
import { jsxDEV as jsxDEV8, Fragment as
|
|
3391
|
+
import { useState as useState5 } from "react";
|
|
3392
|
+
import { jsxDEV as jsxDEV8, Fragment as Fragment4 } from "react/jsx-dev-runtime";
|
|
3368
3393
|
var BASE_ICON_SIDE_LENGTH_EM = 1.6;
|
|
3369
3394
|
var ICON_GAP_EM = 0.3;
|
|
3370
3395
|
function Icon({
|
|
@@ -3376,14 +3401,14 @@ function Icon({
|
|
|
3376
3401
|
style,
|
|
3377
3402
|
noBackground = false
|
|
3378
3403
|
}) {
|
|
3379
|
-
const [anchor, setAnchor] =
|
|
3404
|
+
const [anchor, setAnchor] = useState5(null);
|
|
3380
3405
|
const hasTooltip = tooltip != null;
|
|
3381
3406
|
const colorEntry = SEMANTIC_COLORS[color];
|
|
3382
3407
|
const resolvedColor = subtle ? colorEntry.subtle?.color ?? colorEntry.color : colorEntry.color;
|
|
3383
3408
|
const finalIcons = Array.isArray(IconComponent) ? IconComponent : [IconComponent];
|
|
3384
3409
|
const fullIconWidthEm = (finalIcons.length - 1) * ICON_GAP_EM + finalIcons.length * BASE_ICON_SIDE_LENGTH_EM * getSizeValue(size);
|
|
3385
3410
|
const iconSideLengthEm = `${BASE_ICON_SIDE_LENGTH_EM * getSizeValue(size)}em`;
|
|
3386
|
-
return /* @__PURE__ */ jsxDEV8(
|
|
3411
|
+
return /* @__PURE__ */ jsxDEV8(Fragment4, {
|
|
3387
3412
|
children: [
|
|
3388
3413
|
/* @__PURE__ */ jsxDEV8("div", {
|
|
3389
3414
|
onMouseEnter: hasTooltip ? (e) => setAnchor(e.currentTarget.getBoundingClientRect()) : undefined,
|
|
@@ -3419,9 +3444,9 @@ function Icon({
|
|
|
3419
3444
|
}
|
|
3420
3445
|
|
|
3421
3446
|
// src/devtools/browser/components/DomainChip.tsx
|
|
3422
|
-
import { jsxDEV as jsxDEV9, Fragment as
|
|
3447
|
+
import { jsxDEV as jsxDEV9, Fragment as Fragment5 } from "react/jsx-dev-runtime";
|
|
3423
3448
|
function DomainHierarchyContent({ allDomains }) {
|
|
3424
|
-
return /* @__PURE__ */ jsxDEV9(
|
|
3449
|
+
return /* @__PURE__ */ jsxDEV9(Fragment5, {
|
|
3425
3450
|
children: allDomains.map((d, i) => {
|
|
3426
3451
|
const isCurrent = i === allDomains.length - 1;
|
|
3427
3452
|
return /* @__PURE__ */ jsxDEV9("div", {
|
|
@@ -3516,18 +3541,44 @@ function DomainChip({
|
|
|
3516
3541
|
}
|
|
3517
3542
|
|
|
3518
3543
|
// src/devtools/browser/components/HandlerChips.tsx
|
|
3519
|
-
import { jsxDEV as jsxDEV10, Fragment as
|
|
3544
|
+
import { jsxDEV as jsxDEV10, Fragment as Fragment6 } from "react/jsx-dev-runtime";
|
|
3520
3545
|
function getExternalLabel(hop) {
|
|
3521
3546
|
if (hop.handlerType !== "external")
|
|
3522
3547
|
return null;
|
|
3523
3548
|
return hop.handlerClient != null ? `${hop.transport ?? "ext"} → ${hop.handlerClient.envId}` : `→ ${hop.transport ?? "ext"}`;
|
|
3524
3549
|
}
|
|
3550
|
+
function getTransportTooltip(hop) {
|
|
3551
|
+
return getTransportTooltipForHops([hop]);
|
|
3552
|
+
}
|
|
3553
|
+
function getTransportTooltipForHops(hops) {
|
|
3554
|
+
const lines = hops.filter((hop) => hop.handlerType === "external").map((hop) => ({ summary: hop.transportSummary, url: hop.transportUrl })).filter((line) => line.summary != null || line.url != null);
|
|
3555
|
+
if (lines.length === 0)
|
|
3556
|
+
return;
|
|
3557
|
+
return {
|
|
3558
|
+
title: "Transport",
|
|
3559
|
+
content: /* @__PURE__ */ jsxDEV10("div", {
|
|
3560
|
+
style: { display: "flex", flexDirection: "column", gap: "6px", fontSize: "11px" },
|
|
3561
|
+
children: lines.map((line) => /* @__PURE__ */ jsxDEV10("div", {
|
|
3562
|
+
style: { display: "flex", flexDirection: "column", gap: "2px" },
|
|
3563
|
+
children: [
|
|
3564
|
+
line.summary != null && /* @__PURE__ */ jsxDEV10("span", {
|
|
3565
|
+
children: line.summary
|
|
3566
|
+
}, undefined, false, undefined, this),
|
|
3567
|
+
line.url != null && line.url !== line.summary && /* @__PURE__ */ jsxDEV10("span", {
|
|
3568
|
+
style: { color: DEVTOOL_COLOR_TEXT_MUTED, wordBreak: "break-all" },
|
|
3569
|
+
children: line.url
|
|
3570
|
+
}, undefined, false, undefined, this)
|
|
3571
|
+
]
|
|
3572
|
+
}, `${line.summary ?? ""}:${line.url ?? ""}`, true, undefined, this))
|
|
3573
|
+
}, undefined, false, undefined, this)
|
|
3574
|
+
};
|
|
3575
|
+
}
|
|
3525
3576
|
function HandlerChips({ entry, size, subtle }) {
|
|
3526
3577
|
const firstHop = entry.meta.routing[0];
|
|
3527
3578
|
const localEnvId = firstHop != null ? firstHop.runtime.envId : null;
|
|
3528
3579
|
const externalLabel = firstHop != null ? getExternalLabel(firstHop) : null;
|
|
3529
3580
|
const firstHopIsLocal = firstHop != null && firstHop.handlerType === "local";
|
|
3530
|
-
return /* @__PURE__ */ jsxDEV10(
|
|
3581
|
+
return /* @__PURE__ */ jsxDEV10(Fragment6, {
|
|
3531
3582
|
children: [
|
|
3532
3583
|
localEnvId != null && (firstHopIsLocal || externalLabel == null) && /* @__PURE__ */ jsxDEV10(Chip, {
|
|
3533
3584
|
color: "handler_local" /* handler_local */,
|
|
@@ -3539,6 +3590,7 @@ function HandlerChips({ entry, size, subtle }) {
|
|
|
3539
3590
|
color: "handler_external" /* handler_external */,
|
|
3540
3591
|
size,
|
|
3541
3592
|
subtle,
|
|
3593
|
+
tooltip: firstHop != null ? getTransportTooltip(firstHop) : undefined,
|
|
3542
3594
|
children: externalLabel
|
|
3543
3595
|
}, undefined, false, undefined, this)
|
|
3544
3596
|
]
|
|
@@ -3546,15 +3598,15 @@ function HandlerChips({ entry, size, subtle }) {
|
|
|
3546
3598
|
}
|
|
3547
3599
|
|
|
3548
3600
|
// src/devtools/browser/components/RunningTimer.tsx
|
|
3549
|
-
import { useEffect as useEffect2, useState as
|
|
3550
|
-
import { jsxDEV as jsxDEV11, Fragment as
|
|
3601
|
+
import { useEffect as useEffect2, useState as useState6 } from "react";
|
|
3602
|
+
import { jsxDEV as jsxDEV11, Fragment as Fragment7 } from "react/jsx-dev-runtime";
|
|
3551
3603
|
function RunningTimer({ startTime }) {
|
|
3552
|
-
const [elapsed, setElapsed] =
|
|
3604
|
+
const [elapsed, setElapsed] = useState6(() => Date.now() - startTime);
|
|
3553
3605
|
useEffect2(() => {
|
|
3554
3606
|
const interval = setInterval(() => setElapsed(Date.now() - startTime), 100);
|
|
3555
3607
|
return () => clearInterval(interval);
|
|
3556
3608
|
}, [startTime]);
|
|
3557
|
-
return /* @__PURE__ */ jsxDEV11(
|
|
3609
|
+
return /* @__PURE__ */ jsxDEV11(Fragment7, {
|
|
3558
3610
|
children: [
|
|
3559
3611
|
elapsed,
|
|
3560
3612
|
"ms"
|
|
@@ -3563,7 +3615,7 @@ function RunningTimer({ startTime }) {
|
|
|
3563
3615
|
}
|
|
3564
3616
|
function DurationDisplay({ entry }) {
|
|
3565
3617
|
const d = formatDuration(entry);
|
|
3566
|
-
return /* @__PURE__ */ jsxDEV11(
|
|
3618
|
+
return /* @__PURE__ */ jsxDEV11(Fragment7, {
|
|
3567
3619
|
children: d ?? /* @__PURE__ */ jsxDEV11(RunningTimer, {
|
|
3568
3620
|
startTime: entry.startTime
|
|
3569
3621
|
}, undefined, false, undefined, this)
|
|
@@ -3599,6 +3651,8 @@ function CallStackLink({
|
|
|
3599
3651
|
const symbol = STATUS_SYMBOL[entry.status];
|
|
3600
3652
|
const labelColor = entryRole === "caller" ? DEVTOOL_COLOR_TEXT_SECONDARY : getCalledColor(entry);
|
|
3601
3653
|
const label = entryRole === "caller" ? "↑ from" : getCalledLabel(entry);
|
|
3654
|
+
const firstHop = entry.meta.routing[0];
|
|
3655
|
+
const transportTooltip = entryRole === "called" && firstHop != null ? getTransportTooltip(firstHop) : undefined;
|
|
3602
3656
|
return /* @__PURE__ */ jsxDEV12("div", {
|
|
3603
3657
|
onClick,
|
|
3604
3658
|
style: {
|
|
@@ -3620,9 +3674,13 @@ function CallStackLink({
|
|
|
3620
3674
|
style: { color, fontSize: "10px", flexShrink: 0 },
|
|
3621
3675
|
children: symbol
|
|
3622
3676
|
}, undefined, false, undefined, this),
|
|
3623
|
-
/* @__PURE__ */ jsxDEV12(
|
|
3624
|
-
|
|
3625
|
-
|
|
3677
|
+
/* @__PURE__ */ jsxDEV12(HoverTooltip, {
|
|
3678
|
+
config: transportTooltip,
|
|
3679
|
+
style: { flexShrink: 0, display: "flex" },
|
|
3680
|
+
children: /* @__PURE__ */ jsxDEV12("span", {
|
|
3681
|
+
style: { color: labelColor, fontSize: "9px" },
|
|
3682
|
+
children: label
|
|
3683
|
+
}, undefined, false, undefined, this)
|
|
3626
3684
|
}, undefined, false, undefined, this),
|
|
3627
3685
|
/* @__PURE__ */ jsxDEV12("span", {
|
|
3628
3686
|
style: { display: "flex", alignItems: "center", gap: "5px" },
|
|
@@ -3700,10 +3758,11 @@ function ChildDispatchChips({
|
|
|
3700
3758
|
const runtimeId = item.handlerClient?.envId ?? item.transport ?? "ext";
|
|
3701
3759
|
const hasClient = item.handlerClient != null;
|
|
3702
3760
|
if (!groups.has(runtimeId)) {
|
|
3703
|
-
groups.set(runtimeId, { runtimeId, transports: [], hasClient });
|
|
3761
|
+
groups.set(runtimeId, { runtimeId, transports: [], hasClient, hops: [] });
|
|
3704
3762
|
}
|
|
3705
|
-
const transport = item.transport;
|
|
3706
3763
|
const group = groups.get(runtimeId);
|
|
3764
|
+
group.hops.push(item);
|
|
3765
|
+
const transport = item.transport;
|
|
3707
3766
|
if (transport != null && !group.transports.includes(transport)) {
|
|
3708
3767
|
group.transports.push(transport);
|
|
3709
3768
|
}
|
|
@@ -3716,6 +3775,7 @@ function ChildDispatchChips({
|
|
|
3716
3775
|
return /* @__PURE__ */ jsxDEV13(Chip, {
|
|
3717
3776
|
color: "handler_external" /* handler_external */,
|
|
3718
3777
|
size,
|
|
3778
|
+
tooltip: getTransportTooltipForHops(group.hops),
|
|
3719
3779
|
children: label
|
|
3720
3780
|
}, group.runtimeId, false, undefined, this);
|
|
3721
3781
|
})
|
|
@@ -3723,7 +3783,7 @@ function ChildDispatchChips({
|
|
|
3723
3783
|
}
|
|
3724
3784
|
|
|
3725
3785
|
// src/devtools/browser/components/MetaSection.tsx
|
|
3726
|
-
import { useState as
|
|
3786
|
+
import { useState as useState7 } from "react";
|
|
3727
3787
|
import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
|
|
3728
3788
|
function MetaChip({ label, value }) {
|
|
3729
3789
|
return /* @__PURE__ */ jsxDEV14("span", {
|
|
@@ -3744,7 +3804,7 @@ function MetaChip({ label, value }) {
|
|
|
3744
3804
|
}, undefined, true, undefined, this);
|
|
3745
3805
|
}
|
|
3746
3806
|
function MetaSection({ entry }) {
|
|
3747
|
-
const [expanded, setExpanded] =
|
|
3807
|
+
const [expanded, setExpanded] = useState7(false);
|
|
3748
3808
|
const { meta, cuid } = entry;
|
|
3749
3809
|
const expandedRows = [
|
|
3750
3810
|
{ label: "cuid", value: cuid },
|
|
@@ -3869,7 +3929,8 @@ function RoutingSection({
|
|
|
3869
3929
|
const isLocal = hop.handlerType === "local";
|
|
3870
3930
|
const isLast = i === hopCount - 1 && phantomCount === 0;
|
|
3871
3931
|
const badgeColor = isLocal ? DEVTOOL_COLOR_SEMANTIC_SUCCESS : DEVTOOL_COLOR_SEMANTIC_WARNING;
|
|
3872
|
-
const badgeText = isLocal ? "● exec" : `→ ${hop.transport ?? "ext"}`;
|
|
3932
|
+
const badgeText = isLocal ? "● exec" : `→ ${hop.transportSummary ?? hop.transport ?? "ext"}`;
|
|
3933
|
+
const transportTooltip = isLocal ? undefined : getTransportTooltip(hop);
|
|
3873
3934
|
const runtimeTitle = [hop.runtime.perId, hop.runtime.insId].filter(Boolean).join(" · ") || undefined;
|
|
3874
3935
|
return /* @__PURE__ */ jsxDEV15("div", {
|
|
3875
3936
|
style: {
|
|
@@ -3905,9 +3966,20 @@ function RoutingSection({
|
|
|
3905
3966
|
}, undefined, false, undefined, this)
|
|
3906
3967
|
]
|
|
3907
3968
|
}, undefined, true, undefined, this),
|
|
3908
|
-
/* @__PURE__ */ jsxDEV15(
|
|
3909
|
-
|
|
3910
|
-
|
|
3969
|
+
/* @__PURE__ */ jsxDEV15(HoverTooltip, {
|
|
3970
|
+
config: transportTooltip,
|
|
3971
|
+
style: { display: "block", minWidth: 0, overflow: "hidden" },
|
|
3972
|
+
children: /* @__PURE__ */ jsxDEV15("span", {
|
|
3973
|
+
style: {
|
|
3974
|
+
color: badgeColor,
|
|
3975
|
+
fontSize: "10px",
|
|
3976
|
+
whiteSpace: "nowrap",
|
|
3977
|
+
overflow: "hidden",
|
|
3978
|
+
textOverflow: "ellipsis",
|
|
3979
|
+
display: "block"
|
|
3980
|
+
},
|
|
3981
|
+
children: badgeText
|
|
3982
|
+
}, undefined, false, undefined, this)
|
|
3911
3983
|
}, undefined, false, undefined, this),
|
|
3912
3984
|
/* @__PURE__ */ jsxDEV15("span", {
|
|
3913
3985
|
style: {
|
|
@@ -4140,7 +4212,7 @@ function ActionDetailPanel({
|
|
|
4140
4212
|
childEntries,
|
|
4141
4213
|
onSelectEntry
|
|
4142
4214
|
}) {
|
|
4143
|
-
const [focusedChildCuid, setFocusedChildCuid] =
|
|
4215
|
+
const [focusedChildCuid, setFocusedChildCuid] = useState8(null);
|
|
4144
4216
|
const focusedEntry = focusedChildCuid != null ? childEntries.find((e) => e.cuid === focusedChildCuid) ?? entry : entry;
|
|
4145
4217
|
const maxRoutingHops = Math.max(entry.meta.routing.length, ...childEntries.map((e) => e.meta.routing.length), 0);
|
|
4146
4218
|
const maxCallSiteFrames = Math.max(countUserFrames(entry.meta.originClient, entry.callSite), ...childEntries.map((e) => countUserFrames(e.meta.originClient, e.callSite)), 0);
|
|
@@ -4240,13 +4312,14 @@ import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2 } from
|
|
|
4240
4312
|
|
|
4241
4313
|
// src/devtools/browser/components/action_list/ActionEntryRow.tsx
|
|
4242
4314
|
import { CircleX as CircleX3, PackageCheck as PackageCheck2, Variable as Variable2 } from "lucide-react";
|
|
4243
|
-
import { Fragment as
|
|
4315
|
+
import { Fragment as Fragment9, useState as useState10 } from "react";
|
|
4244
4316
|
|
|
4245
4317
|
// src/devtools/browser/components/action_list/ActionInputAndOutputChip.tsx
|
|
4246
4318
|
import { CircleX as CircleX2, PackageCheck, Sparkle, Variable } from "lucide-react";
|
|
4319
|
+
import { useState as useState9 } from "react";
|
|
4247
4320
|
|
|
4248
4321
|
// src/devtools/browser/components/action_list/IoTooltipContent.tsx
|
|
4249
|
-
import { jsxDEV as jsxDEV17, Fragment as
|
|
4322
|
+
import { jsxDEV as jsxDEV17, Fragment as Fragment8 } from "react/jsx-dev-runtime";
|
|
4250
4323
|
var JSON_TOKEN_RE2 = /("(?:\\.|[^"\\])*")(\s*:)?|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b|\bnull\b|\bundefined\b)|([{}[\],])/g;
|
|
4251
4324
|
function renderColoredJson2(text) {
|
|
4252
4325
|
const nodes = [];
|
|
@@ -4333,6 +4406,8 @@ var ActionInputAndOutputChip = ({
|
|
|
4333
4406
|
const firstHopIsLocal = firstHop != null && firstHop.handlerType === "local";
|
|
4334
4407
|
const isLocal = localEnvId != null && (firstHopIsLocal || externalLabel == null);
|
|
4335
4408
|
const color = isLocal ? "handler_local" /* handler_local */ : "handler_external" /* handler_external */;
|
|
4409
|
+
const transportTooltip = firstHop != null ? getTransportTooltip(firstHop) : undefined;
|
|
4410
|
+
const [labelAnchor, setLabelAnchor] = useState9(null);
|
|
4336
4411
|
const isNewInput = breakReasons.includes("new_input" /* new_input */);
|
|
4337
4412
|
const isNewOutput = breakReasons.includes("new_output" /* new_output */);
|
|
4338
4413
|
const hasError = entry.error != null || entry.abortReason != null;
|
|
@@ -4381,9 +4456,15 @@ var ActionInputAndOutputChip = ({
|
|
|
4381
4456
|
children: "→"
|
|
4382
4457
|
}, undefined, false, undefined, this),
|
|
4383
4458
|
/* @__PURE__ */ jsxDEV18("span", {
|
|
4384
|
-
style: { opacity: 0.8 },
|
|
4459
|
+
style: { opacity: 0.8, cursor: transportTooltip != null ? "default" : undefined },
|
|
4460
|
+
onMouseEnter: transportTooltip != null ? (e) => setLabelAnchor(e.currentTarget.getBoundingClientRect()) : undefined,
|
|
4461
|
+
onMouseLeave: transportTooltip != null ? () => setLabelAnchor(null) : undefined,
|
|
4385
4462
|
children: label
|
|
4386
4463
|
}, undefined, false, undefined, this),
|
|
4464
|
+
labelAnchor != null && transportTooltip != null && /* @__PURE__ */ jsxDEV18(Tooltip, {
|
|
4465
|
+
anchor: labelAnchor,
|
|
4466
|
+
config: transportTooltip
|
|
4467
|
+
}, undefined, false, undefined, this),
|
|
4387
4468
|
/* @__PURE__ */ jsxDEV18("span", {
|
|
4388
4469
|
style: { opacity: 0.6 },
|
|
4389
4470
|
color,
|
|
@@ -4420,7 +4501,7 @@ var ActionInputAndOutputChip = ({
|
|
|
4420
4501
|
};
|
|
4421
4502
|
|
|
4422
4503
|
// src/devtools/browser/components/action_list/ActionEntryRow.tsx
|
|
4423
|
-
import { jsxDEV as jsxDEV19, Fragment as
|
|
4504
|
+
import { jsxDEV as jsxDEV19, Fragment as Fragment10 } from "react/jsx-dev-runtime";
|
|
4424
4505
|
function getLatestChipColor(status) {
|
|
4425
4506
|
if (status === "failed")
|
|
4426
4507
|
return "failed" /* failed */;
|
|
@@ -4447,7 +4528,7 @@ function GroupDotTooltip({
|
|
|
4447
4528
|
config: {
|
|
4448
4529
|
align: "center",
|
|
4449
4530
|
maxWidth: 240,
|
|
4450
|
-
content: /* @__PURE__ */ jsxDEV19(
|
|
4531
|
+
content: /* @__PURE__ */ jsxDEV19(Fragment10, {
|
|
4451
4532
|
children: [
|
|
4452
4533
|
/* @__PURE__ */ jsxDEV19("div", {
|
|
4453
4534
|
style: { color: dotColor, marginBottom: "1px" },
|
|
@@ -4489,10 +4570,10 @@ function GroupDot({
|
|
|
4489
4570
|
isActive,
|
|
4490
4571
|
onSelect
|
|
4491
4572
|
}) {
|
|
4492
|
-
const [anchor, setAnchor] =
|
|
4573
|
+
const [anchor, setAnchor] = useState10(null);
|
|
4493
4574
|
const dotColor = STATUS_COLOR[entry.status];
|
|
4494
4575
|
const hovered = anchor != null;
|
|
4495
|
-
return /* @__PURE__ */ jsxDEV19(
|
|
4576
|
+
return /* @__PURE__ */ jsxDEV19(Fragment10, {
|
|
4496
4577
|
children: [
|
|
4497
4578
|
/* @__PURE__ */ jsxDEV19("button", {
|
|
4498
4579
|
"data-cuid": entry.cuid,
|
|
@@ -4541,7 +4622,10 @@ function ActionEntryRow({
|
|
|
4541
4622
|
}) {
|
|
4542
4623
|
const timestamp = formatTimestamp(entry.startTime);
|
|
4543
4624
|
const hasGroup = groupEntries != null && groupEntries.length > 1;
|
|
4544
|
-
const
|
|
4625
|
+
const externalChildEntries = childEntries?.filter((child) => child.meta.routing[0]?.handlerType === "external") ?? [];
|
|
4626
|
+
const nonIoBreakReasons = breakReasons?.filter((r) => r !== "new_input" /* new_input */ && r !== "new_output" /* new_output */) ?? [];
|
|
4627
|
+
const hasBottomError = entry.error != null || entry.abortReason != null;
|
|
4628
|
+
const hasBottomContent = externalChildEntries.length > 0 || nonIoBreakReasons.length > 0;
|
|
4545
4629
|
return /* @__PURE__ */ jsxDEV19("div", {
|
|
4546
4630
|
"data-cuid": entry.cuid,
|
|
4547
4631
|
onClick,
|
|
@@ -4663,7 +4747,7 @@ function ActionEntryRow({
|
|
|
4663
4747
|
}, undefined, true, undefined, this)
|
|
4664
4748
|
]
|
|
4665
4749
|
}, undefined, true, undefined, this),
|
|
4666
|
-
hasBottomContent &&
|
|
4750
|
+
hasBottomContent && /* @__PURE__ */ jsxDEV19("div", {
|
|
4667
4751
|
style: {
|
|
4668
4752
|
display: "flex",
|
|
4669
4753
|
flexWrap: "wrap",
|
|
@@ -4672,7 +4756,7 @@ function ActionEntryRow({
|
|
|
4672
4756
|
paddingLeft: "4.5em"
|
|
4673
4757
|
},
|
|
4674
4758
|
children: [
|
|
4675
|
-
|
|
4759
|
+
externalChildEntries.map((child) => /* @__PURE__ */ jsxDEV19(Fragment9, {
|
|
4676
4760
|
children: [
|
|
4677
4761
|
/* @__PURE__ */ jsxDEV19(Icon, {
|
|
4678
4762
|
size: "sm" /* sm */,
|
|
@@ -4708,12 +4792,12 @@ function ActionEntryRow({
|
|
|
4708
4792
|
}, undefined, false, undefined, this)
|
|
4709
4793
|
]
|
|
4710
4794
|
}, child.actionId, true, undefined, this)),
|
|
4711
|
-
|
|
4795
|
+
nonIoBreakReasons.map((reason) => /* @__PURE__ */ jsxDEV19(Chip, {
|
|
4712
4796
|
color: "default" /* default */,
|
|
4713
4797
|
subtle: true,
|
|
4714
4798
|
children: reason
|
|
4715
4799
|
}, reason, false, undefined, this)),
|
|
4716
|
-
|
|
4800
|
+
externalChildEntries.length > 0 && hasBottomError && /* @__PURE__ */ jsxDEV19(Icon, {
|
|
4717
4801
|
size: "sm" /* sm */,
|
|
4718
4802
|
icon: CircleX3,
|
|
4719
4803
|
color: entry.status === "aborted" ? "aborted" /* aborted */ : "error" /* error */,
|
|
@@ -4874,7 +4958,7 @@ function ActionList({
|
|
|
4874
4958
|
}
|
|
4875
4959
|
|
|
4876
4960
|
// src/devtools/browser/components/PanelChrome.tsx
|
|
4877
|
-
import { useState as
|
|
4961
|
+
import { useState as useState11 } from "react";
|
|
4878
4962
|
import { jsxDEV as jsxDEV21 } from "react/jsx-dev-runtime";
|
|
4879
4963
|
var MONO_FONT = "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace";
|
|
4880
4964
|
var SANS_FONT = "ui-sans-serif, system-ui, sans-serif";
|
|
@@ -5079,7 +5163,7 @@ function SplitHandle({
|
|
|
5079
5163
|
horizontal,
|
|
5080
5164
|
onRatioChange
|
|
5081
5165
|
}) {
|
|
5082
|
-
const [hovered, setHovered] =
|
|
5166
|
+
const [hovered, setHovered] = useState11(false);
|
|
5083
5167
|
const onMouseDown = (e) => {
|
|
5084
5168
|
e.preventDefault();
|
|
5085
5169
|
const container = e.currentTarget.parentElement;
|
|
@@ -5166,7 +5250,7 @@ function DevtoolsLauncher({ items }) {
|
|
|
5166
5250
|
|
|
5167
5251
|
// src/devtools/browser/devtools_dock.ts
|
|
5168
5252
|
var GLOBAL_KEY = "__NICE_DEVTOOLS_DOCK__";
|
|
5169
|
-
var VERSION =
|
|
5253
|
+
var VERSION = 4;
|
|
5170
5254
|
function createCoordinator() {
|
|
5171
5255
|
const panels = new Map;
|
|
5172
5256
|
const listeners = new Set;
|
|
@@ -5226,17 +5310,25 @@ function createCoordinator() {
|
|
|
5226
5310
|
const anyOpen = list.some((p) => p.open);
|
|
5227
5311
|
const firstId = list.length > 0 ? list[0].id : null;
|
|
5228
5312
|
let dockOffset = 0;
|
|
5313
|
+
let stacked = false;
|
|
5229
5314
|
const self = panels.get(id);
|
|
5230
5315
|
if (self != null && self.open) {
|
|
5316
|
+
let seenSelf = false;
|
|
5231
5317
|
for (const panel of list) {
|
|
5232
|
-
if (panel.id === id)
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5318
|
+
if (panel.id === id) {
|
|
5319
|
+
seenSelf = true;
|
|
5320
|
+
continue;
|
|
5321
|
+
}
|
|
5322
|
+
if (panel.open && panel.side === self.side) {
|
|
5323
|
+
stacked = true;
|
|
5324
|
+
if (!seenSelf)
|
|
5325
|
+
dockOffset += panel.size;
|
|
5326
|
+
}
|
|
5236
5327
|
}
|
|
5237
5328
|
}
|
|
5238
5329
|
return {
|
|
5239
5330
|
dockOffset,
|
|
5331
|
+
stacked,
|
|
5240
5332
|
anyOpen,
|
|
5241
5333
|
isPrimary: id === firstId,
|
|
5242
5334
|
devtools: list.map(toRef),
|
|
@@ -5264,7 +5356,7 @@ function getDevtoolsDockCoordinator() {
|
|
|
5264
5356
|
}
|
|
5265
5357
|
|
|
5266
5358
|
// src/devtools/browser/NiceActionDevtools.tsx
|
|
5267
|
-
import { jsxDEV as jsxDEV22, Fragment as
|
|
5359
|
+
import { jsxDEV as jsxDEV22, Fragment as Fragment11 } from "react/jsx-dev-runtime";
|
|
5268
5360
|
if (typeof document !== "undefined" && !document.getElementById("__nice-action-devtools-styles")) {
|
|
5269
5361
|
const style = document.createElement("style");
|
|
5270
5362
|
style.id = "__nice-action-devtools-styles";
|
|
@@ -5375,9 +5467,9 @@ function NiceActionDevtools_Panel({
|
|
|
5375
5467
|
position: defaultPosition = "dock-bottom",
|
|
5376
5468
|
initialOpen = false
|
|
5377
5469
|
}) {
|
|
5378
|
-
const [prefs, setPrefsRaw] =
|
|
5379
|
-
const [entries, setEntries] =
|
|
5380
|
-
const [selectedCuid, setSelectedCuid] =
|
|
5470
|
+
const [prefs, setPrefsRaw] = useState12(() => readPrefs(defaultPosition, initialOpen));
|
|
5471
|
+
const [entries, setEntries] = useState12([]);
|
|
5472
|
+
const [selectedCuid, setSelectedCuid] = useState12(null);
|
|
5381
5473
|
useEffect4(() => core.subscribe(setEntries), [core]);
|
|
5382
5474
|
const groups = useMemo3(() => {
|
|
5383
5475
|
const byCuid = new Map(entries.map((e) => [e.cuid, e]));
|
|
@@ -5468,7 +5560,31 @@ function NiceActionDevtools_Panel({
|
|
|
5468
5560
|
flexDirection: "column",
|
|
5469
5561
|
boxShadow: "0 -4px 24px rgba(0,0,0,0.4)",
|
|
5470
5562
|
overflow: "hidden",
|
|
5471
|
-
...dockSide === "bottom" ? {
|
|
5563
|
+
...dockSide === "bottom" ? {
|
|
5564
|
+
bottom: view.dockOffset,
|
|
5565
|
+
left: 0,
|
|
5566
|
+
right: 0,
|
|
5567
|
+
height: `${dockedSize}px`,
|
|
5568
|
+
borderRadius: view.stacked ? "0" : "8px 8px 0 0"
|
|
5569
|
+
} : dockSide === "top" ? {
|
|
5570
|
+
top: view.dockOffset,
|
|
5571
|
+
left: 0,
|
|
5572
|
+
right: 0,
|
|
5573
|
+
height: `${dockedSize}px`,
|
|
5574
|
+
borderRadius: view.stacked ? "0" : "0 0 8px 8px"
|
|
5575
|
+
} : dockSide === "left" ? {
|
|
5576
|
+
top: 0,
|
|
5577
|
+
left: view.dockOffset,
|
|
5578
|
+
bottom: 0,
|
|
5579
|
+
width: `${dockedSize}px`,
|
|
5580
|
+
borderRadius: view.stacked ? "0" : "0 8px 8px 0"
|
|
5581
|
+
} : {
|
|
5582
|
+
top: 0,
|
|
5583
|
+
right: view.dockOffset,
|
|
5584
|
+
bottom: 0,
|
|
5585
|
+
width: `${dockedSize}px`,
|
|
5586
|
+
borderRadius: view.stacked ? "0" : "8px 0 0 8px"
|
|
5587
|
+
}
|
|
5472
5588
|
};
|
|
5473
5589
|
const selectedEntryParent = selectedEntry?.parentCuid != null ? entries.find((e) => e.cuid === selectedEntry.parentCuid) ?? null : null;
|
|
5474
5590
|
const selectedEntryChildren = selectedEntry != null ? [...entries].filter((e) => e.parentCuid === selectedEntry.cuid).sort((a, b) => a.startTime - b.startTime) : [];
|
|
@@ -5522,7 +5638,7 @@ function NiceActionDevtools_Panel({
|
|
|
5522
5638
|
style: { width: "100%", height: "100%", overflowY: "auto" }
|
|
5523
5639
|
}, undefined, false, undefined, this)
|
|
5524
5640
|
}, undefined, false, undefined, this),
|
|
5525
|
-
selectedEntry != null && /* @__PURE__ */ jsxDEV22(
|
|
5641
|
+
selectedEntry != null && /* @__PURE__ */ jsxDEV22(Fragment11, {
|
|
5526
5642
|
children: [
|
|
5527
5643
|
/* @__PURE__ */ jsxDEV22(SplitHandle, {
|
|
5528
5644
|
horizontal: isHorizDock,
|
|
@@ -151,6 +151,8 @@ function extractRouting(context) {
|
|
|
151
151
|
insId: handler.client.insId
|
|
152
152
|
} : undefined,
|
|
153
153
|
transport: isExternal ? handler.transType : undefined,
|
|
154
|
+
transportSummary: isExternal ? handler.transInfo?.summary : undefined,
|
|
155
|
+
transportUrl: isExternal ? handler.transInfo?.url : undefined,
|
|
154
156
|
time: item.time
|
|
155
157
|
};
|
|
156
158
|
});
|