11import { Provider , useAtom , useAtomValue , useSetAtom } from "jotai" ;
2- import { useCallback , useContext } from "react" ;
3- import { clone , merge } from "lodash-es" ;
2+ import { useCallback , useContext , useEffect } from "react" ;
3+ import { clone , isEmpty , merge } from "lodash-es" ;
44import { useHydrateAtoms } from "jotai/utils" ;
55import {
66 appAtom ,
@@ -30,6 +30,24 @@ interface ScreenContextProps {
3030
3131type ScreenContextProviderProps = React . PropsWithChildren < ScreenContextProps > ;
3232
33+ const transformScriptContent = ( scriptContent : string ) : string => {
34+ if ( isEmpty ( scriptContent . trim ( ) ) ) {
35+ return "" ;
36+ }
37+ let transformed = scriptContent ;
38+ // 1. Replace 'const VAR = ...' and 'let VAR = ...' with 'window.VAR = ...'
39+ transformed = transformed . replace (
40+ / ( ^ | \n ) ( c o n s t | l e t ) \s + ( [ a - z A - Z _ $ ] [ a - z A - Z 0 - 9 _ $ ] * ) \s * = / g,
41+ "$1window.$3 =" ,
42+ ) ;
43+ // 2. Replace 'function FUNC_NAME(...){...}' with 'window.FUNC_NAME = function(...){...}'
44+ transformed = transformed . replace (
45+ / ( ^ | \n ) f u n c t i o n \s + ( [ a - z A - Z _ $ ] [ a - z A - Z 0 - 9 _ $ ] * ) \s * ( \( [ ^ ) ] * \) ) \s * \{ / g,
46+ "$1window.$2 = function$3 {" ,
47+ ) ;
48+ return transformed ;
49+ } ;
50+
3351export const ScreenContextProvider : React . FC < ScreenContextProviderProps > = ( {
3452 screen,
3553 context,
@@ -42,6 +60,37 @@ export const ScreenContextProvider: React.FC<ScreenContextProviderProps> = ({
4260 throw new Error ( "Missing application context for screen!" ) ;
4361 }
4462
63+ useEffect ( ( ) => {
64+ const screenInstanceId = screen . name || screen . id || "anonymous-screen" ;
65+ const scriptId = `ensemble-screen-script-${ screenInstanceId . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, "-" ) } ` ;
66+ let existingScript = document . getElementById ( scriptId ) ;
67+
68+ const globalScriptContent = screen . global || "" ;
69+ const importedScriptContent = screen . importedScripts || "" ;
70+ let fullScriptContent = `${ importedScriptContent } \n\n${ globalScriptContent } ` ;
71+
72+ fullScriptContent = transformScriptContent ( fullScriptContent ) ;
73+
74+ if ( ! isEmpty ( fullScriptContent . trim ( ) ) ) {
75+ if ( existingScript ) {
76+ existingScript . remove ( ) ;
77+ }
78+
79+ const scriptElement = document . createElement ( "script" ) ;
80+ scriptElement . id = scriptId ;
81+ scriptElement . textContent = fullScriptContent ;
82+ document . head . appendChild ( scriptElement ) ;
83+
84+ existingScript = scriptElement ;
85+ }
86+
87+ return ( ) => {
88+ if ( existingScript ) {
89+ existingScript . remove ( ) ;
90+ }
91+ } ;
92+ } , [ screen . global , screen . importedScripts , screen . name , screen . id ] ) ;
93+
4594 return (
4695 < Provider key = { screen . name } >
4796 < HydrateAtoms
0 commit comments