Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sandpack-client/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import pkg from "./package.json";

const configs = [
{
input: "src/clients/node/inject-scripts/consoleHook.ts",
input: "src/inject-scripts/consoleHook.ts",
output: {
file: "src/clients/node/inject-scripts/dist/consoleHook.js",
file: "src/inject-scripts/dist/consoleHook.js",
format: "es",
},
plugins: [
Expand Down
3 changes: 2 additions & 1 deletion sandpack-client/src/clients/node/inject-scripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { INJECT_MESSAGE_TYPE } from "@codesandbox/nodebox";

// get the bundled file, which contains all dependencies
// @ts-ignore
import consoleHook from "./dist/consoleHook.js";
import consoleHook from "../../../inject-scripts/dist/consoleHook.js";

import { setupHistoryListeners } from "./historyListener";

const scripts = [
Expand Down
4 changes: 2 additions & 2 deletions sandpack-client/src/clients/node/taskManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ type Token =
| { type: TokenType.OR | TokenType.AND | TokenType.PIPE }
| {
type: TokenType.Command | TokenType.Argument | TokenType.String;
value: string;
value?: string;
}
| {
type: TokenType.EnvVar;
value: Record<string, string>;
};

const operators = new Map<string, { type: TokenType }>([
const operators = new Map<string, Token>([
["&&", { type: TokenType.AND }],
["||", { type: TokenType.OR }],
["|", { type: TokenType.PIPE }],
Expand Down
52 changes: 51 additions & 1 deletion sandpack-client/src/clients/static/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import type { FilesMap } from "@codesandbox/nodebox";
import type { FileContent } from "static-browser-server";
import { PreviewController } from "static-browser-server";
Expand All @@ -8,9 +9,12 @@ import type {
SandboxSetup,
UnsubscribeFunction,
} from "../..";
// get the bundled file, which contains all dependencies
// @ts-ignore
import consoleHook from "../../inject-scripts/dist/consoleHook.js";
import { SandpackClient } from "../base";
import { EventEmitter } from "../event-emitter";
import { fromBundlerFilesToFS } from "../node/client.utils";
import { fromBundlerFilesToFS, generateRandomId } from "../node/client.utils";
import type { SandpackNodeMessage } from "../node/types";

import { insertHtmlAfterRegex, readBuffer, validateHtml } from "./utils";
Expand Down Expand Up @@ -50,6 +54,10 @@ export class SandpackStatic extends SandpackClient {
content,
options.externalResources
);
content = this.injectScriptIntoHead(content, {
script: consoleHook,
scope: { channelId: generateRandomId() },
});
} catch (err) {
console.error("Runtime injection failed", err);
}
Expand Down Expand Up @@ -80,6 +88,11 @@ export class SandpackStatic extends SandpackClient {
);
}

this.eventListener = this.eventListener.bind(this);
if (typeof window !== "undefined") {
window.addEventListener("message", this.eventListener);
}

// Dispatch very first compile action
this.updateSandbox();
}
Expand Down Expand Up @@ -137,6 +150,25 @@ export class SandpackStatic extends SandpackClient {
return this.injectContentIntoHead(content, tagsToInsert);
}

private injectScriptIntoHead(
content: FileContent,
opts: {
script: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
scope?: { channelId: string } & Record<string, any>;
}
): FileContent {
const { script, scope = {} } = opts;
const scriptToInsert = `
<script>
const scope = ${JSON.stringify(scope)};
${script}
</script>
`.trim();

return this.injectContentIntoHead(content, scriptToInsert);
}

public updateSandbox(
setup = this.sandboxSetup,
_isInitializationCompile?: boolean
Expand Down Expand Up @@ -169,6 +201,21 @@ export class SandpackStatic extends SandpackClient {
});
}

// Handles message windows coming from iframes
private eventListener(evt: MessageEvent): void {
// skip events originating from different iframes
if (evt.source !== this.iframe.contentWindow) {
return;
}

const message = evt.data;
if (!message.codesandbox) {
return;
}

this.dispatch(message);
}

/**
* Bundler communication
*/
Expand All @@ -190,5 +237,8 @@ export class SandpackStatic extends SandpackClient {

public destroy(): void {
this.emitter.cleanup();
if (typeof window !== "undefined") {
window.removeEventListener("message", this.eventListener);
}
}
}
54 changes: 54 additions & 0 deletions sandpack-react/src/components/Console/Console.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,57 @@ export const MaxMessageCount = () => {
</>
);
};

export const StaticTemplate: React.FC = () => {
return (
<Sandpack
files={{
"index.html": `<!DOCTYPE html>
<html>

<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="/styles.css" />
<script>
console.log("fooo")
</script>
</head>

<body>
<h1>Hello world</h1>
<button onclick="console.log(document.querySelectorAll('button'))">Log</button>
<button onclick="console.log(document.querySelectorAll('button'))">Log</button>
</body>

</html>`,
}}
options={{ showConsole: true }}
template="static"
/>
);
};

export const NodeTemplate: React.FC = () => {
return <Sandpack options={{ showConsole: true }} template="node" />;
};

export const ReactTemplate: React.FC = () => {
return (
<Sandpack
options={{ showConsole: true }}
files={{
"App.js": `import { useState } from "react"
export default function App() {
const foo = useState("")
console.log(foo)
return (
<>
</>
)
}`,
}}
template="react"
/>
);
};
1 change: 0 additions & 1 deletion sandpack-react/src/components/Console/ConsoleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export const ConsoleList: React.FC<{ data: SandpackConsoleData }> = ({
data,
}) => {
const classNames = useClassNames();

return (
<>
{data.map(({ data, id, method }, logIndex, references) => {
Expand Down
1 change: 1 addition & 0 deletions sandpack-react/src/components/Console/utils/constraints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const CLEAR_LOG = {
};

export const TRANSFORMED_TYPE_KEY = "@t";
export const TRANSFORMED_TYPE_KEY_ALTERNATE = "#@t";
export const CIRCULAR_REF_KEY = "@r";

export const MAX_LENGTH_STRING = 10000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,73 @@ const cases: Array<[Message, string]> = [
{ constructor: { name: "CustomThing" } },
'CustomThing { constructor: { name: "CustomThing" } }',
],
[
{
"0": {
"#@t": "HTMLElement",
data: {
tagName: "button",
attributes: {},
innerHTML: "Test",
},
},
"1": {
"#@t": "HTMLElement",
data: {
tagName: "button",
attributes: {
onclick: "console.log(document.querySelectorAll('button'))",
},
innerHTML: "Log",
},
},
entries: {
"#@t": "Function",
data: {
name: "entries",
body: "",
proto: "Function",
},
},
keys: {
"#@t": "Function",
data: {
name: "keys",
body: "",
proto: "Function",
},
},
values: {
"#@t": "Function",
data: {
name: "values",
body: "",
proto: "Function",
},
},
forEach: {
"#@t": "Function",
data: {
name: "forEach",
body: "",
proto: "Function",
},
},
length: 2,
item: {
"#@t": "Function",
data: {
name: "item",
body: "",
proto: "Function",
},
},
constructor: {
name: "NodeList",
},
},
`NodeList(2)[<button>Test</button>,<button onclick="console.log(document.querySelectorAll('button'))">Log</button>]`,
],

/**
* Function
Expand Down
29 changes: 29 additions & 0 deletions sandpack-react/src/components/Console/utils/fromConsoleToString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import {
TRANSFORMED_TYPE_KEY,
TRANSFORMED_TYPE_KEY_ALTERNATE,
MAX_NEST_LEVEL,
MAX_KEYS,
MAX_LENGTH_STRING,
Expand Down Expand Up @@ -48,6 +49,25 @@ const formatSymbols = (message: Message): any => {
const transform = transformers[type];

return transform(message.data);
} else if (
typeof message == "object" &&
TRANSFORMED_TYPE_KEY_ALTERNATE in message
) {
const type = message[TRANSFORMED_TYPE_KEY_ALTERNATE] as TransformsTypes;
const transform = transformers[type];

return transform(message.data);
} else if (
typeof message == "object" &&
message.constructor?.name === "NodeList"
) {
const NodeList = {};
Object.entries(message).forEach(([key, value]) => {
// @ts-ignore
NodeList[key] = formatSymbols(value);
});

return NodeList;
}

return message;
Expand Down Expand Up @@ -163,6 +183,15 @@ export const fromConsoleToString = (
return fromConsoleToString(newMessage, references, level + 1);
}

if (output.constructor?.name === "NodeList") {
const length = output.length;
const nodes = new Array(length).fill(null).map((_, index) => {
return fromConsoleToString(output[index], references);
});

return `NodeList(${output.length})[${nodes}]`;
}

return objectToString(output, references, level + 1);
}
} catch {
Expand Down