@nice-code/action 0.2.14 → 0.2.15
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.
|
@@ -128,7 +128,7 @@ class ActionDevtoolsCore {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
// src/devtools/browser/NiceActionDevtools.tsx
|
|
131
|
-
import { useCallback, useEffect as
|
|
131
|
+
import { useCallback, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState6 } from "react";
|
|
132
132
|
|
|
133
133
|
// src/devtools/browser/components/ActionDetailPanel.tsx
|
|
134
134
|
import { useMemo, useState as useState5 } from "react";
|
|
@@ -825,7 +825,65 @@ function RoutingSection({
|
|
|
825
825
|
}
|
|
826
826
|
|
|
827
827
|
// src/devtools/browser/components/StackTraceSection.tsx
|
|
828
|
-
import { useState as useState4 } from "react";
|
|
828
|
+
import { useEffect as useEffect2, useState as useState4 } from "react";
|
|
829
|
+
|
|
830
|
+
// src/devtools/browser/components/sourceMapResolver.ts
|
|
831
|
+
import { SourceMapConsumer } from "source-map-js";
|
|
832
|
+
var consumerCache = new Map;
|
|
833
|
+
async function loadConsumer(fileUrl) {
|
|
834
|
+
try {
|
|
835
|
+
if (!fileUrl.startsWith("http://") && !fileUrl.startsWith("https://"))
|
|
836
|
+
return null;
|
|
837
|
+
const resp = await fetch(fileUrl);
|
|
838
|
+
if (!resp.ok)
|
|
839
|
+
return null;
|
|
840
|
+
const text = await resp.text();
|
|
841
|
+
const match = text.match(/\/\/[#@] sourceMappingURL=(\S+)/);
|
|
842
|
+
if (match == null)
|
|
843
|
+
return null;
|
|
844
|
+
const mapRef = match[1];
|
|
845
|
+
let mapJson;
|
|
846
|
+
if (mapRef.startsWith("data:")) {
|
|
847
|
+
const commaIdx = mapRef.indexOf(",");
|
|
848
|
+
if (commaIdx === -1)
|
|
849
|
+
return null;
|
|
850
|
+
const header = mapRef.slice(5, commaIdx);
|
|
851
|
+
const payload = mapRef.slice(commaIdx + 1);
|
|
852
|
+
mapJson = header.includes("base64") ? atob(payload) : decodeURIComponent(payload);
|
|
853
|
+
} else {
|
|
854
|
+
const mapUrl = new URL(mapRef, fileUrl).href;
|
|
855
|
+
const mapResp = await fetch(mapUrl);
|
|
856
|
+
if (!mapResp.ok)
|
|
857
|
+
return null;
|
|
858
|
+
mapJson = await mapResp.text();
|
|
859
|
+
}
|
|
860
|
+
return new SourceMapConsumer(JSON.parse(mapJson));
|
|
861
|
+
} catch {
|
|
862
|
+
return null;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
function getConsumer(fileUrl) {
|
|
866
|
+
const key = fileUrl.split("?")[0] ?? fileUrl;
|
|
867
|
+
if (!consumerCache.has(key)) {
|
|
868
|
+
consumerCache.set(key, loadConsumer(fileUrl));
|
|
869
|
+
}
|
|
870
|
+
return consumerCache.get(key);
|
|
871
|
+
}
|
|
872
|
+
async function resolveCompiledPosition(fileUrl, line, col) {
|
|
873
|
+
try {
|
|
874
|
+
const consumer = await getConsumer(fileUrl);
|
|
875
|
+
if (consumer == null)
|
|
876
|
+
return null;
|
|
877
|
+
const pos = consumer.originalPositionFor({ line, column: col });
|
|
878
|
+
if (pos.source == null || pos.line == null)
|
|
879
|
+
return null;
|
|
880
|
+
return { file: pos.source, line: pos.line, col: pos.column ?? 0 };
|
|
881
|
+
} catch {
|
|
882
|
+
return null;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// src/devtools/browser/components/StackTraceSection.tsx
|
|
829
887
|
import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
|
|
830
888
|
var INTERNAL_PATTERNS = [
|
|
831
889
|
"/nice-action/",
|
|
@@ -846,16 +904,39 @@ function parseStackFrames(stack) {
|
|
|
846
904
|
const matchFn = raw.match(/^at (.+?) \((.+):(\d+):(\d+)\)$/);
|
|
847
905
|
if (matchFn != null) {
|
|
848
906
|
const file = matchFn[2];
|
|
849
|
-
return {
|
|
907
|
+
return {
|
|
908
|
+
fn: matchFn[1],
|
|
909
|
+
file,
|
|
910
|
+
line: parseInt(matchFn[3], 10),
|
|
911
|
+
col: parseInt(matchFn[4], 10),
|
|
912
|
+
raw,
|
|
913
|
+
isInternal: isInternalFrame(file)
|
|
914
|
+
};
|
|
850
915
|
}
|
|
851
916
|
const matchUrl = raw.match(/^at (.+):(\d+):(\d+)$/);
|
|
852
917
|
if (matchUrl != null) {
|
|
853
918
|
const file = matchUrl[1];
|
|
854
|
-
return {
|
|
919
|
+
return {
|
|
920
|
+
file,
|
|
921
|
+
line: parseInt(matchUrl[2], 10),
|
|
922
|
+
col: parseInt(matchUrl[3], 10),
|
|
923
|
+
raw,
|
|
924
|
+
isInternal: isInternalFrame(file)
|
|
925
|
+
};
|
|
855
926
|
}
|
|
856
927
|
return { raw, isInternal: true };
|
|
857
928
|
}).filter((f) => f != null);
|
|
858
929
|
}
|
|
930
|
+
async function resolveSourceMapPositions(frames) {
|
|
931
|
+
return Promise.all(frames.map(async (frame) => {
|
|
932
|
+
if (frame.isInternal || frame.file == null || frame.line == null)
|
|
933
|
+
return frame;
|
|
934
|
+
const resolved = await resolveCompiledPosition(frame.file, frame.line, frame.col ?? 0);
|
|
935
|
+
if (resolved == null)
|
|
936
|
+
return frame;
|
|
937
|
+
return { ...frame, file: resolved.file, line: resolved.line, col: resolved.col };
|
|
938
|
+
}));
|
|
939
|
+
}
|
|
859
940
|
function formatFrameFile(file) {
|
|
860
941
|
if (file == null)
|
|
861
942
|
return "?";
|
|
@@ -877,9 +958,24 @@ function StackTraceSection({
|
|
|
877
958
|
color = "#60a5fa"
|
|
878
959
|
}) {
|
|
879
960
|
const [showAll, setShowAll] = useState4(false);
|
|
961
|
+
const [resolvedFrames, setResolvedFrames] = useState4(null);
|
|
962
|
+
useEffect2(() => {
|
|
963
|
+
if (stack == null)
|
|
964
|
+
return;
|
|
965
|
+
setResolvedFrames(null);
|
|
966
|
+
const parsed = parseStackFrames(stack);
|
|
967
|
+
let cancelled = false;
|
|
968
|
+
resolveSourceMapPositions(parsed).then((frames) => {
|
|
969
|
+
if (!cancelled)
|
|
970
|
+
setResolvedFrames(frames);
|
|
971
|
+
});
|
|
972
|
+
return () => {
|
|
973
|
+
cancelled = true;
|
|
974
|
+
};
|
|
975
|
+
}, [stack]);
|
|
880
976
|
if (stack == null)
|
|
881
977
|
return null;
|
|
882
|
-
const allFrames = parseStackFrames(stack);
|
|
978
|
+
const allFrames = resolvedFrames ?? parseStackFrames(stack);
|
|
883
979
|
const userFrames = allFrames.filter((f) => !f.isInternal);
|
|
884
980
|
const hasInternalFrames = allFrames.length > userFrames.length;
|
|
885
981
|
const displayFrames = showAll ? allFrames : userFrames;
|
|
@@ -985,13 +1081,26 @@ function StackTraceSection({
|
|
|
985
1081
|
flexShrink: 0
|
|
986
1082
|
},
|
|
987
1083
|
children: bareFilename
|
|
988
|
-
}, undefined, false, undefined, this)
|
|
1084
|
+
}, undefined, false, undefined, this),
|
|
1085
|
+
frame.line != null && /* @__PURE__ */ jsxDEV10("span", {
|
|
1086
|
+
style: {
|
|
1087
|
+
color: isUser ? "#4a7fa8" : "#2d4a63",
|
|
1088
|
+
fontSize: "10px",
|
|
1089
|
+
whiteSpace: "nowrap",
|
|
1090
|
+
flexShrink: 0,
|
|
1091
|
+
fontVariantNumeric: "tabular-nums"
|
|
1092
|
+
},
|
|
1093
|
+
children: [
|
|
1094
|
+
":",
|
|
1095
|
+
frame.line
|
|
1096
|
+
]
|
|
1097
|
+
}, undefined, true, undefined, this)
|
|
989
1098
|
]
|
|
990
1099
|
}, undefined, true, undefined, this)
|
|
991
1100
|
]
|
|
992
1101
|
}, undefined, true, undefined, this)
|
|
993
1102
|
]
|
|
994
|
-
},
|
|
1103
|
+
}, frame.raw, true, undefined, this);
|
|
995
1104
|
})
|
|
996
1105
|
}, undefined, false, undefined, this)
|
|
997
1106
|
]
|
|
@@ -1702,7 +1811,7 @@ function NiceActionDevtools_Panel({
|
|
|
1702
1811
|
const showDomainTooltip = useCallback((rect, allDomains) => setDomainTooltip({ rect, allDomains }), []);
|
|
1703
1812
|
const hideDomainTooltip = useCallback(() => setDomainTooltip(null), []);
|
|
1704
1813
|
const domainTooltipCtx = useMemo2(() => ({ show: showDomainTooltip, hide: hideDomainTooltip }), [showDomainTooltip, hideDomainTooltip]);
|
|
1705
|
-
|
|
1814
|
+
useEffect3(() => core.subscribe(setEntries), [core]);
|
|
1706
1815
|
const groups = useMemo2(() => {
|
|
1707
1816
|
const byCuid = new Map(entries.map((e) => [e.cuid, e]));
|
|
1708
1817
|
const roots = entries.filter((e) => e.status !== "running" && (e.parentCuid == null || !byCuid.has(e.parentCuid)));
|
|
@@ -1754,7 +1863,7 @@ function NiceActionDevtools_Panel({
|
|
|
1754
1863
|
const dockedSize = isHorizDock ? dockedHeight : dockedWidth;
|
|
1755
1864
|
const selectedEntry = selectedCuid != null ? entries.find((e) => e.cuid === selectedCuid) : null;
|
|
1756
1865
|
const runningCount = entries.filter((e) => e.status === "running").length;
|
|
1757
|
-
|
|
1866
|
+
useEffect3(() => {
|
|
1758
1867
|
const sides = ["top", "bottom", "left", "right"];
|
|
1759
1868
|
const clearAll = () => {
|
|
1760
1869
|
sides.forEach((s) => {
|
|
@@ -2021,7 +2130,7 @@ function ActionList({
|
|
|
2021
2130
|
return result;
|
|
2022
2131
|
}, [groups, expandedGroupCuids, selectedCuid]);
|
|
2023
2132
|
const prevSelectedRef = useRef2(selectedCuid);
|
|
2024
|
-
|
|
2133
|
+
useEffect3(() => {
|
|
2025
2134
|
if (selectedCuid === prevSelectedRef.current)
|
|
2026
2135
|
return;
|
|
2027
2136
|
prevSelectedRef.current = selectedCuid;
|
package/build/index.js
CHANGED
|
@@ -311,7 +311,9 @@ class ActionPayload_Request extends ActionPayload {
|
|
|
311
311
|
return value.waitForResultPayload();
|
|
312
312
|
}
|
|
313
313
|
async run(options) {
|
|
314
|
-
this._callSite
|
|
314
|
+
if (this._callSite == null) {
|
|
315
|
+
this._callSite = new Error().stack;
|
|
316
|
+
}
|
|
315
317
|
return this._domain.runAction(this, options);
|
|
316
318
|
}
|
|
317
319
|
}
|
|
@@ -13,6 +13,7 @@ function useActionMutation(action, options) {
|
|
|
13
13
|
import {
|
|
14
14
|
useQuery
|
|
15
15
|
} from "@tanstack/react-query";
|
|
16
|
+
import { useRef } from "react";
|
|
16
17
|
function actionQueryKey(action, input) {
|
|
17
18
|
if (input === undefined) {
|
|
18
19
|
return ["nice-action", action.domain, action.allDomains, action.id];
|
|
@@ -29,9 +30,14 @@ function useActionQuery(action, ...args) {
|
|
|
29
30
|
[options] = args;
|
|
30
31
|
}
|
|
31
32
|
const { enabled, ...queryOptions } = options ?? {};
|
|
33
|
+
const callSiteRef = useRef(new Error().stack);
|
|
32
34
|
return useQuery({
|
|
33
35
|
queryKey: input != null ? actionQueryKey(action, input) : actionQueryKey(action),
|
|
34
|
-
queryFn: () =>
|
|
36
|
+
queryFn: () => {
|
|
37
|
+
const req = action.request(input);
|
|
38
|
+
req._callSite = callSiteRef.current;
|
|
39
|
+
return req.runToOutput();
|
|
40
|
+
},
|
|
35
41
|
enabled: hasInputSchema ? input != null && (enabled ?? true) : enabled ?? true,
|
|
36
42
|
...queryOptions
|
|
37
43
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nice-code/action",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -44,12 +44,13 @@
|
|
|
44
44
|
"build-types": "tsc --project tsconfig.build.json"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@nice-code/common-errors": "0.2.
|
|
48
|
-
"@nice-code/error": "0.2.
|
|
47
|
+
"@nice-code/common-errors": "0.2.15",
|
|
48
|
+
"@nice-code/error": "0.2.15",
|
|
49
49
|
"@standard-schema/spec": "^1.1.0",
|
|
50
50
|
"@tanstack/react-virtual": "^3.13.26",
|
|
51
51
|
"http-status-codes": "^2.3.0",
|
|
52
52
|
"nanoid": "^5.1.9",
|
|
53
|
+
"source-map-js": "^1.2.1",
|
|
53
54
|
"std-env": "^4.1.0"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|