1+ /* eslint-disable @typescript-eslint/ban-ts-comment */
12import type { FilesMap } from "@codesandbox/nodebox" ;
23import type { FileContent } from "static-browser-server" ;
34import { PreviewController } from "static-browser-server" ;
@@ -8,9 +9,12 @@ import type {
89 SandboxSetup ,
910 UnsubscribeFunction ,
1011} from "../.." ;
12+ // get the bundled file, which contains all dependencies
13+ // @ts -ignore
14+ import consoleHook from "../../inject-scripts/dist/consoleHook.js" ;
1115import { SandpackClient } from "../base" ;
1216import { EventEmitter } from "../event-emitter" ;
13- import { fromBundlerFilesToFS } from "../node/client.utils" ;
17+ import { fromBundlerFilesToFS , generateRandomId } from "../node/client.utils" ;
1418import type { SandpackNodeMessage } from "../node/types" ;
1519
1620import { insertHtmlAfterRegex , readBuffer , validateHtml } from "./utils" ;
@@ -52,6 +56,10 @@ export class SandpackStatic extends SandpackClient {
5256 content ,
5357 options . externalResources
5458 ) ;
59+ content = this . injectScriptIntoHead ( content , {
60+ script : consoleHook ,
61+ scope : { channelId : generateRandomId ( ) } ,
62+ } ) ;
5563 } catch ( err ) {
5664 console . error ( "Runtime injection failed" , err ) ;
5765 }
@@ -82,6 +90,11 @@ export class SandpackStatic extends SandpackClient {
8290 ) ;
8391 }
8492
93+ this . eventListener = this . eventListener . bind ( this ) ;
94+ if ( typeof window !== "undefined" ) {
95+ window . addEventListener ( "message" , this . eventListener ) ;
96+ }
97+
8598 // Dispatch very first compile action
8699 this . updateSandbox ( ) ;
87100 }
@@ -139,6 +152,25 @@ export class SandpackStatic extends SandpackClient {
139152 return this . injectContentIntoHead ( content , tagsToInsert ) ;
140153 }
141154
155+ private injectScriptIntoHead (
156+ content : FileContent ,
157+ opts : {
158+ script : string ;
159+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
160+ scope ?: { channelId : string } & Record < string , any > ;
161+ }
162+ ) : FileContent {
163+ const { script, scope = { } } = opts ;
164+ const scriptToInsert = `
165+ <script>
166+ const scope = ${ JSON . stringify ( scope ) } ;
167+ ${ script }
168+ </script>
169+ ` . trim ( ) ;
170+
171+ return this . injectContentIntoHead ( content , scriptToInsert ) ;
172+ }
173+
142174 public updateSandbox (
143175 setup = this . sandboxSetup ,
144176 _isInitializationCompile ?: boolean
@@ -172,6 +204,21 @@ export class SandpackStatic extends SandpackClient {
172204 } ) ;
173205 }
174206
207+ // Handles message windows coming from iframes
208+ private eventListener ( evt : MessageEvent ) : void {
209+ // skip events originating from different iframes
210+ if ( evt . source !== this . iframe . contentWindow ) {
211+ return ;
212+ }
213+
214+ const message = evt . data ;
215+ if ( ! message . codesandbox ) {
216+ return ;
217+ }
218+
219+ this . dispatch ( message ) ;
220+ }
221+
175222 /**
176223 * Bundler communication
177224 */
@@ -193,5 +240,8 @@ export class SandpackStatic extends SandpackClient {
193240
194241 public destroy ( ) : void {
195242 this . emitter . cleanup ( ) ;
243+ if ( typeof window !== "undefined" ) {
244+ window . removeEventListener ( "message" , this . eventListener ) ;
245+ }
196246 }
197247}
0 commit comments