@nice-code/action 0.5.5 → 0.6.1
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 +35 -0
- package/build/devtools/browser/index.js +45 -9
- package/build/devtools/server/index.js +132 -114
- package/build/index.js +1107 -46
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/Transport.types.d.ts +7 -1
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/TransportWebSocket.types.d.ts +31 -3
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/WebSocketConnection.d.ts +18 -1
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/WebSocketTransport.d.ts +12 -1
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/actionFrameCrypto.d.ts +31 -0
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/actionWireCodec.d.ts +41 -0
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/actionWsHandshake.d.ts +187 -0
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/createBinaryWsAdapter.d.ts +20 -0
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/createBinaryWsSessionFactory.d.ts +31 -0
- package/build/types/ActionRuntime/Handler/ExternalClient/Transport/WebSocket/ws_util.d.ts +9 -0
- package/build/types/ActionRuntime/Handler/Server/ActionServerHandler.d.ts +191 -0
- package/build/types/devtools/browser/components/SectionLabel.d.ts +1 -1
- package/build/types/devtools/server/index.d.ts +2 -2
- package/build/types/index.d.ts +7 -0
- package/build/types/utils/decodeActionFrame.d.ts +17 -0
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -215,6 +215,41 @@ function RenameUser() {
|
|
|
215
215
|
|
|
216
216
|
---
|
|
217
217
|
|
|
218
|
+
## Devtools
|
|
219
|
+
|
|
220
|
+
### Browser panel — `@nice-code/action/devtools/browser`
|
|
221
|
+
|
|
222
|
+
A dockable in-app panel showing every action run: status, timing, input/output, routing, errors, and call stacks. Renders only when `NODE_ENV === "development"` (or with `forceEnable`).
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
import { ActionDevtoolsCore, NiceActionDevtools } from "@nice-code/action/devtools/browser";
|
|
226
|
+
|
|
227
|
+
const devtoolsCore = new ActionDevtoolsCore();
|
|
228
|
+
devtoolsCore.attachToDomain(appRoot);
|
|
229
|
+
|
|
230
|
+
function App() {
|
|
231
|
+
return (
|
|
232
|
+
<>
|
|
233
|
+
<MyApp />
|
|
234
|
+
<NiceActionDevtools core={devtoolsCore} position="dock-bottom" />
|
|
235
|
+
</>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Server logger — `@nice-code/action/devtools/server`
|
|
241
|
+
|
|
242
|
+
Logs action lifecycle (started / progress / success / error) with timings — pretty lines or newline-delimited JSON.
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
import { ActionServerDevtools } from "@nice-code/action/devtools/server";
|
|
246
|
+
|
|
247
|
+
const devtools = new ActionServerDevtools({ format: "json", logPayloads: false });
|
|
248
|
+
devtools.attachToDomain(appRoot);
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
218
253
|
## WebSocket transport
|
|
219
254
|
|
|
220
255
|
```ts
|
|
@@ -1899,11 +1899,13 @@ class ActionDevtoolsCore {
|
|
|
1899
1899
|
}));
|
|
1900
1900
|
} else if (type === "finished" /* finished */) {
|
|
1901
1901
|
this._updateEntry(runningAction.cuid, (e) => {
|
|
1902
|
-
const
|
|
1902
|
+
const responseRouting = extractRouting(update.response?.context);
|
|
1903
|
+
const localRouting = extractRouting(runningAction.context);
|
|
1904
|
+
const routing = responseRouting.length >= localRouting.length ? responseRouting : localRouting;
|
|
1903
1905
|
const base = {
|
|
1904
1906
|
...e,
|
|
1905
1907
|
endTime: time,
|
|
1906
|
-
meta: { ...e.meta, routing
|
|
1908
|
+
meta: { ...e.meta, routing }
|
|
1907
1909
|
};
|
|
1908
1910
|
const finishType = update.finishType;
|
|
1909
1911
|
if (finishType === "success" /* success */) {
|
|
@@ -1925,11 +1927,21 @@ class ActionDevtoolsCore {
|
|
|
1925
1927
|
if (finishType === "failed" /* failed */) {
|
|
1926
1928
|
const rawError = update.error;
|
|
1927
1929
|
const errorStack2 = rawError instanceof Error ? rawError.stack : undefined;
|
|
1928
|
-
return {
|
|
1930
|
+
return {
|
|
1931
|
+
...base,
|
|
1932
|
+
status: "failed",
|
|
1933
|
+
error: serializeErrorForDisplay(rawError),
|
|
1934
|
+
errorStack: errorStack2
|
|
1935
|
+
};
|
|
1929
1936
|
}
|
|
1930
1937
|
const abortReason = update.reason;
|
|
1931
1938
|
const errorStack = abortReason instanceof Error ? abortReason.stack : undefined;
|
|
1932
|
-
return {
|
|
1939
|
+
return {
|
|
1940
|
+
...base,
|
|
1941
|
+
status: "aborted",
|
|
1942
|
+
abortReason: serializeErrorForDisplay(abortReason),
|
|
1943
|
+
errorStack
|
|
1944
|
+
};
|
|
1933
1945
|
});
|
|
1934
1946
|
}
|
|
1935
1947
|
});
|
|
@@ -2091,7 +2103,10 @@ import { useState } from "react";
|
|
|
2091
2103
|
|
|
2092
2104
|
// src/devtools/browser/components/SectionLabel.tsx
|
|
2093
2105
|
import { jsx } from "react/jsx-runtime";
|
|
2094
|
-
function SectionLabel({
|
|
2106
|
+
function SectionLabel({
|
|
2107
|
+
label,
|
|
2108
|
+
color = DEVTOOL_COLOR_SEMANTIC_SYSTEM
|
|
2109
|
+
}) {
|
|
2095
2110
|
return /* @__PURE__ */ jsx("div", {
|
|
2096
2111
|
style: {
|
|
2097
2112
|
color,
|
|
@@ -2518,7 +2533,13 @@ async function resolveSourceMapPositions(frames) {
|
|
|
2518
2533
|
const resolved = await resolveCompiledPosition(frame.file, frame.line, frame.col ?? 0);
|
|
2519
2534
|
if (resolved == null)
|
|
2520
2535
|
return frame;
|
|
2521
|
-
return {
|
|
2536
|
+
return {
|
|
2537
|
+
...frame,
|
|
2538
|
+
originalFile: frame.file,
|
|
2539
|
+
file: resolved.file,
|
|
2540
|
+
line: resolved.line,
|
|
2541
|
+
col: resolved.col
|
|
2542
|
+
};
|
|
2522
2543
|
}));
|
|
2523
2544
|
}
|
|
2524
2545
|
function formatFrameFile(file) {
|
|
@@ -3859,7 +3880,12 @@ function MetaSection({ entry }) {
|
|
|
3859
3880
|
},
|
|
3860
3881
|
children: [
|
|
3861
3882
|
/* @__PURE__ */ jsx14("span", {
|
|
3862
|
-
style: {
|
|
3883
|
+
style: {
|
|
3884
|
+
textAlign: "left",
|
|
3885
|
+
color: DEVTOOL_COLOR_TEXT_MUTED,
|
|
3886
|
+
fontSize: "10px",
|
|
3887
|
+
paddingTop: "1px"
|
|
3888
|
+
},
|
|
3863
3889
|
children: label
|
|
3864
3890
|
}),
|
|
3865
3891
|
/* @__PURE__ */ jsx14("span", {
|
|
@@ -3952,7 +3978,12 @@ function RoutingSection({
|
|
|
3952
3978
|
style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "10px" },
|
|
3953
3979
|
children: [
|
|
3954
3980
|
/* @__PURE__ */ jsx15("span", {
|
|
3955
|
-
style: {
|
|
3981
|
+
style: {
|
|
3982
|
+
color: DEVTOOL_COLOR_TEXT_FAINT,
|
|
3983
|
+
fontSize: "10px",
|
|
3984
|
+
width: "16px",
|
|
3985
|
+
textAlign: "right"
|
|
3986
|
+
},
|
|
3956
3987
|
children: i + 1
|
|
3957
3988
|
}),
|
|
3958
3989
|
/* @__PURE__ */ jsx15("span", {
|
|
@@ -4004,7 +4035,12 @@ function RoutingSection({
|
|
|
4004
4035
|
children: hop.handlerClient != null ? `↳ ${hop.handlerClient.envId}` : ""
|
|
4005
4036
|
}),
|
|
4006
4037
|
/* @__PURE__ */ jsxs13("span", {
|
|
4007
|
-
style: {
|
|
4038
|
+
style: {
|
|
4039
|
+
color: DEVTOOL_COLOR_TEXT_FAINT,
|
|
4040
|
+
fontSize: "10px",
|
|
4041
|
+
flexShrink: 0,
|
|
4042
|
+
marginLeft: "auto"
|
|
4043
|
+
},
|
|
4008
4044
|
children: [
|
|
4009
4045
|
"+",
|
|
4010
4046
|
hop.time - startTime,
|
|
@@ -1,113 +1,3 @@
|
|
|
1
|
-
// src/devtools/server/NiceActionServerDevtools.ts
|
|
2
|
-
class ActionServerDevtools {
|
|
3
|
-
_options;
|
|
4
|
-
_inFlight = new Map;
|
|
5
|
-
constructor(options = {}) {
|
|
6
|
-
const defaultEnabled = typeof process !== "undefined" ? process["env"]["NODE_ENV"] !== "production" : true;
|
|
7
|
-
this._options = {
|
|
8
|
-
logger: options.logger ?? defaultConsoleLogger,
|
|
9
|
-
format: options.format ?? "pretty",
|
|
10
|
-
logPayloads: options.logPayloads ?? true,
|
|
11
|
-
enabled: options.enabled ?? defaultEnabled
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
attachToDomain(domain) {
|
|
15
|
-
if (!this._options.enabled) {
|
|
16
|
-
return () => {};
|
|
17
|
-
}
|
|
18
|
-
return domain.addActionListener((update) => {
|
|
19
|
-
const { runningAction, type, time } = update;
|
|
20
|
-
const actionPath = [...runningAction.allDomains, runningAction.id].join(".");
|
|
21
|
-
if (type === "started" /* started */) {
|
|
22
|
-
this._inFlight.set(runningAction.cuid, { startTime: time });
|
|
23
|
-
this._log("started", actionPath, runningAction.cuid, {
|
|
24
|
-
...this._options.logPayloads ? { input: runningAction.state?.request?.input } : {}
|
|
25
|
-
});
|
|
26
|
-
} else if (type === "progress" /* progress */) {
|
|
27
|
-
this._log("progress", actionPath, runningAction.cuid, { progress: update.progress });
|
|
28
|
-
} else if (type === "finished" /* finished */) {
|
|
29
|
-
const timing = this._inFlight.get(runningAction.cuid);
|
|
30
|
-
const duration = timing != null ? time - timing.startTime : undefined;
|
|
31
|
-
this._inFlight.delete(runningAction.cuid);
|
|
32
|
-
const finishType = update.finishType;
|
|
33
|
-
if (finishType === "success" /* success */) {
|
|
34
|
-
const result = update.response?.result;
|
|
35
|
-
if (result != null && !result.ok) {
|
|
36
|
-
this._log("action-error", actionPath, runningAction.cuid, {
|
|
37
|
-
...duration != null ? { duration: `${duration}ms` } : {},
|
|
38
|
-
error: serializeError(result.error)
|
|
39
|
-
});
|
|
40
|
-
} else {
|
|
41
|
-
this._log("success", actionPath, runningAction.cuid, {
|
|
42
|
-
...duration != null ? { duration: `${duration}ms` } : {},
|
|
43
|
-
...this._options.logPayloads ? { output: result?.output } : {}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
} else if (finishType === "failed" /* failed */) {
|
|
47
|
-
this._log("failed", actionPath, runningAction.cuid, {
|
|
48
|
-
...duration != null ? { duration: `${duration}ms` } : {},
|
|
49
|
-
error: serializeError(update.error)
|
|
50
|
-
});
|
|
51
|
-
} else {
|
|
52
|
-
this._log("aborted", actionPath, runningAction.cuid, {
|
|
53
|
-
...duration != null ? { duration: `${duration}ms` } : {},
|
|
54
|
-
...update.reason != null ? { reason: String(update.reason) } : {}
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
_log(event, actionPath, cuid, data) {
|
|
61
|
-
const { logger, format } = this._options;
|
|
62
|
-
if (format === "json") {
|
|
63
|
-
logger(JSON.stringify({ time: new Date().toISOString(), event, action: actionPath, cuid, ...data }));
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const prefix = PRETTY_PREFIX[event] ?? `[${event}]`;
|
|
67
|
-
const suffix = Object.keys(data).length > 0 ? ` ${formatPrettyData(data)}` : "";
|
|
68
|
-
logger(`${prefix} ${actionPath} cuid=${cuid}${suffix}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
var PRETTY_PREFIX = {
|
|
72
|
-
started: "[nice-action] ►",
|
|
73
|
-
progress: "[nice-action] ",
|
|
74
|
-
success: "[nice-action] ✓",
|
|
75
|
-
failed: "[nice-action] ✗",
|
|
76
|
-
aborted: "[nice-action] ○"
|
|
77
|
-
};
|
|
78
|
-
function formatPrettyData(data) {
|
|
79
|
-
return Object.entries(data).map(([k, v]) => `${k}=${safeStringify(v)}`).join(" ");
|
|
80
|
-
}
|
|
81
|
-
function safeStringify(value) {
|
|
82
|
-
if (value === undefined)
|
|
83
|
-
return "undefined";
|
|
84
|
-
if (value === null)
|
|
85
|
-
return "null";
|
|
86
|
-
if (typeof value === "string")
|
|
87
|
-
return `"${value}"`;
|
|
88
|
-
try {
|
|
89
|
-
return JSON.stringify(value);
|
|
90
|
-
} catch {
|
|
91
|
-
return String(value);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
function serializeError(err) {
|
|
95
|
-
if (err == null)
|
|
96
|
-
return err;
|
|
97
|
-
if (err instanceof Error)
|
|
98
|
-
return { message: err.message, name: err.name, stack: err.stack };
|
|
99
|
-
if (typeof err === "object") {
|
|
100
|
-
try {
|
|
101
|
-
return JSON.parse(JSON.stringify(err));
|
|
102
|
-
} catch {
|
|
103
|
-
return String(err);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return err;
|
|
107
|
-
}
|
|
108
|
-
function defaultConsoleLogger(message) {
|
|
109
|
-
console.log(message);
|
|
110
|
-
}
|
|
111
1
|
// src/devtools/core/ActionDevtoolsCore.ts
|
|
112
2
|
function serializeErrorForDisplay(error) {
|
|
113
3
|
if (error != null && typeof error === "object" && error.name === "NiceError" && typeof error.toJsonObject === "function") {
|
|
@@ -181,11 +71,13 @@ class ActionDevtoolsCore {
|
|
|
181
71
|
}));
|
|
182
72
|
} else if (type === "finished" /* finished */) {
|
|
183
73
|
this._updateEntry(runningAction.cuid, (e) => {
|
|
184
|
-
const
|
|
74
|
+
const responseRouting = extractRouting(update.response?.context);
|
|
75
|
+
const localRouting = extractRouting(runningAction.context);
|
|
76
|
+
const routing = responseRouting.length >= localRouting.length ? responseRouting : localRouting;
|
|
185
77
|
const base = {
|
|
186
78
|
...e,
|
|
187
79
|
endTime: time,
|
|
188
|
-
meta: { ...e.meta, routing
|
|
80
|
+
meta: { ...e.meta, routing }
|
|
189
81
|
};
|
|
190
82
|
const finishType = update.finishType;
|
|
191
83
|
if (finishType === "success" /* success */) {
|
|
@@ -207,11 +99,21 @@ class ActionDevtoolsCore {
|
|
|
207
99
|
if (finishType === "failed" /* failed */) {
|
|
208
100
|
const rawError = update.error;
|
|
209
101
|
const errorStack2 = rawError instanceof Error ? rawError.stack : undefined;
|
|
210
|
-
return {
|
|
102
|
+
return {
|
|
103
|
+
...base,
|
|
104
|
+
status: "failed",
|
|
105
|
+
error: serializeErrorForDisplay(rawError),
|
|
106
|
+
errorStack: errorStack2
|
|
107
|
+
};
|
|
211
108
|
}
|
|
212
109
|
const abortReason = update.reason;
|
|
213
110
|
const errorStack = abortReason instanceof Error ? abortReason.stack : undefined;
|
|
214
|
-
return {
|
|
111
|
+
return {
|
|
112
|
+
...base,
|
|
113
|
+
status: "aborted",
|
|
114
|
+
abortReason: serializeErrorForDisplay(abortReason),
|
|
115
|
+
errorStack
|
|
116
|
+
};
|
|
215
117
|
});
|
|
216
118
|
}
|
|
217
119
|
});
|
|
@@ -240,6 +142,122 @@ class ActionDevtoolsCore {
|
|
|
240
142
|
listener(snapshot);
|
|
241
143
|
}
|
|
242
144
|
}
|
|
145
|
+
// src/devtools/server/NiceActionServerDevtools.ts
|
|
146
|
+
class ActionServerDevtools {
|
|
147
|
+
_options;
|
|
148
|
+
_inFlight = new Map;
|
|
149
|
+
constructor(options = {}) {
|
|
150
|
+
const defaultEnabled = typeof process !== "undefined" ? process["env"]["NODE_ENV"] !== "production" : true;
|
|
151
|
+
this._options = {
|
|
152
|
+
logger: options.logger ?? defaultConsoleLogger,
|
|
153
|
+
format: options.format ?? "pretty",
|
|
154
|
+
logPayloads: options.logPayloads ?? true,
|
|
155
|
+
enabled: options.enabled ?? defaultEnabled
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
attachToDomain(domain) {
|
|
159
|
+
if (!this._options.enabled) {
|
|
160
|
+
return () => {};
|
|
161
|
+
}
|
|
162
|
+
return domain.addActionListener((update) => {
|
|
163
|
+
const { runningAction, type, time } = update;
|
|
164
|
+
const actionPath = [...runningAction.allDomains, runningAction.id].join(".");
|
|
165
|
+
if (type === "started" /* started */) {
|
|
166
|
+
this._inFlight.set(runningAction.cuid, { startTime: time });
|
|
167
|
+
this._log("started", actionPath, runningAction.cuid, {
|
|
168
|
+
...this._options.logPayloads ? { input: runningAction.state?.request?.input } : {}
|
|
169
|
+
});
|
|
170
|
+
} else if (type === "progress" /* progress */) {
|
|
171
|
+
this._log("progress", actionPath, runningAction.cuid, { progress: update.progress });
|
|
172
|
+
} else if (type === "finished" /* finished */) {
|
|
173
|
+
const timing = this._inFlight.get(runningAction.cuid);
|
|
174
|
+
const duration = timing != null ? time - timing.startTime : undefined;
|
|
175
|
+
this._inFlight.delete(runningAction.cuid);
|
|
176
|
+
const finishType = update.finishType;
|
|
177
|
+
if (finishType === "success" /* success */) {
|
|
178
|
+
const result = update.response?.result;
|
|
179
|
+
if (result != null && !result.ok) {
|
|
180
|
+
this._log("action-error", actionPath, runningAction.cuid, {
|
|
181
|
+
...duration != null ? { duration: `${duration}ms` } : {},
|
|
182
|
+
error: serializeError(result.error)
|
|
183
|
+
});
|
|
184
|
+
} else {
|
|
185
|
+
this._log("success", actionPath, runningAction.cuid, {
|
|
186
|
+
...duration != null ? { duration: `${duration}ms` } : {},
|
|
187
|
+
...this._options.logPayloads ? { output: result?.output } : {}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
} else if (finishType === "failed" /* failed */) {
|
|
191
|
+
this._log("failed", actionPath, runningAction.cuid, {
|
|
192
|
+
...duration != null ? { duration: `${duration}ms` } : {},
|
|
193
|
+
error: serializeError(update.error)
|
|
194
|
+
});
|
|
195
|
+
} else {
|
|
196
|
+
this._log("aborted", actionPath, runningAction.cuid, {
|
|
197
|
+
...duration != null ? { duration: `${duration}ms` } : {},
|
|
198
|
+
...update.reason != null ? { reason: String(update.reason) } : {}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
_log(event, actionPath, cuid, data) {
|
|
205
|
+
const { logger, format } = this._options;
|
|
206
|
+
if (format === "json") {
|
|
207
|
+
logger(JSON.stringify({
|
|
208
|
+
time: new Date().toISOString(),
|
|
209
|
+
event,
|
|
210
|
+
action: actionPath,
|
|
211
|
+
cuid,
|
|
212
|
+
...data
|
|
213
|
+
}));
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const prefix = PRETTY_PREFIX[event] ?? `[${event}]`;
|
|
217
|
+
const suffix = Object.keys(data).length > 0 ? ` ${formatPrettyData(data)}` : "";
|
|
218
|
+
logger(`${prefix} ${actionPath} cuid=${cuid}${suffix}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
var PRETTY_PREFIX = {
|
|
222
|
+
started: "[nice-action] ►",
|
|
223
|
+
progress: "[nice-action] ",
|
|
224
|
+
success: "[nice-action] ✓",
|
|
225
|
+
failed: "[nice-action] ✗",
|
|
226
|
+
aborted: "[nice-action] ○"
|
|
227
|
+
};
|
|
228
|
+
function formatPrettyData(data) {
|
|
229
|
+
return Object.entries(data).map(([k, v]) => `${k}=${safeStringify(v)}`).join(" ");
|
|
230
|
+
}
|
|
231
|
+
function safeStringify(value) {
|
|
232
|
+
if (value === undefined)
|
|
233
|
+
return "undefined";
|
|
234
|
+
if (value === null)
|
|
235
|
+
return "null";
|
|
236
|
+
if (typeof value === "string")
|
|
237
|
+
return `"${value}"`;
|
|
238
|
+
try {
|
|
239
|
+
return JSON.stringify(value);
|
|
240
|
+
} catch {
|
|
241
|
+
return String(value);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function serializeError(err) {
|
|
245
|
+
if (err == null)
|
|
246
|
+
return err;
|
|
247
|
+
if (err instanceof Error)
|
|
248
|
+
return { message: err.message, name: err.name, stack: err.stack };
|
|
249
|
+
if (typeof err === "object") {
|
|
250
|
+
try {
|
|
251
|
+
return JSON.parse(JSON.stringify(err));
|
|
252
|
+
} catch {
|
|
253
|
+
return String(err);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return err;
|
|
257
|
+
}
|
|
258
|
+
function defaultConsoleLogger(message) {
|
|
259
|
+
console.log(message);
|
|
260
|
+
}
|
|
243
261
|
export {
|
|
244
262
|
ActionServerDevtools,
|
|
245
263
|
ActionDevtoolsCore
|