-
Notifications
You must be signed in to change notification settings - Fork 471
Expand file tree
/
Copy pathuseSandpackConsole.ts
More file actions
90 lines (74 loc) · 2.54 KB
/
useSandpackConsole.ts
File metadata and controls
90 lines (74 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import * as React from "react";
import { useSandpack } from "../../hooks/useSandpack";
import {
CLEAR_LOG,
MAX_MESSAGE_COUNT,
SYNTAX_ERROR_PATTERN,
} from "./utils/constraints";
import type { SandpackConsoleData } from "./utils/getType";
/**
* It provides an interface to consume the logs from a sandpack client.
*
* @category Hooks
*/
export const useSandpackConsole = ({
clientId,
maxMessageCount = MAX_MESSAGE_COUNT,
showSyntaxError = false,
resetOnPreviewRestart = false,
}: {
clientId?: string;
maxMessageCount?: number;
showSyntaxError?: boolean;
resetOnPreviewRestart: boolean;
}): { logs: SandpackConsoleData; reset: () => void } => {
const [logs, setLogs] = React.useState<SandpackConsoleData>([]);
const { listen, dispatch } = useSandpack();
React.useEffect(() => {
dispatch({ type: "console/register" }, clientId);
return () => {
dispatch({ type: "console/unregister" }, clientId);
};
}, [dispatch, clientId]);
React.useEffect(() => {
const unsubscribe = listen((message) => {
if (resetOnPreviewRestart && message.type === "start") {
setLogs([]);
} else if (message.type === "console" && message.codesandbox) {
const payloadLog = Array.isArray(message.log)
? message.log
: [message.log];
if (payloadLog.find(({ method }) => method === "clear")) {
return setLogs([CLEAR_LOG]);
}
const logsMessages = showSyntaxError
? payloadLog
: payloadLog.filter((messageItem) => {
const messagesWithoutSyntaxErrors =
messageItem?.data?.filter?.((dataItem) => {
if (typeof dataItem !== "string") return true;
const matches = SYNTAX_ERROR_PATTERN.filter((lookFor) =>
dataItem.startsWith(lookFor)
);
return matches.length === 0;
}) ?? [];
return messagesWithoutSyntaxErrors.length > 0;
});
if (!logsMessages) return;
setLogs((prev) => {
const messages = [...prev, ...logsMessages].filter(
(value, index, self) => {
return index === self.findIndex((s) => s.id === value.id);
}
);
while (messages.length > maxMessageCount) {
messages.shift();
}
return messages;
});
}
}, clientId);
return unsubscribe;
}, [showSyntaxError, maxMessageCount, clientId, resetOnPreviewRestart]);
return { logs, reset: (): void => setLogs([]) };
};