@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 useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState6 } from "react";
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 { fn: matchFn[1], file, raw, isInternal: isInternalFrame(file) };
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 { file, raw, isInternal: isInternalFrame(file) };
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
- }, `${frame.fn ?? "anon"}@${frame.file ?? "unknown"}`, true, undefined, this);
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
- useEffect2(() => core.subscribe(setEntries), [core]);
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
- useEffect2(() => {
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
- useEffect2(() => {
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 = new Error().stack;
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: () => action.request(input).runToOutput(),
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
  });
@@ -0,0 +1,6 @@
1
+ export interface IResolvedSourcePosition {
2
+ file: string;
3
+ line: number;
4
+ col: number;
5
+ }
6
+ export declare function resolveCompiledPosition(fileUrl: string, line: number, col: number): Promise<IResolvedSourcePosition | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nice-code/action",
3
- "version": "0.2.14",
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.14",
48
- "@nice-code/error": "0.2.14",
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": {