@dxos/plugin-script 0.8.4-main.5ea62a8 → 0.8.4-main.ae835ea

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.
Files changed (275) hide show
  1. package/dist/lib/browser/DeploymentDialog-E5NXT4UQ.mjs +14 -0
  2. package/dist/lib/browser/NotebookContainer-C36N7AFF.mjs +817 -0
  3. package/dist/lib/browser/NotebookContainer-C36N7AFF.mjs.map +7 -0
  4. package/dist/lib/browser/ScriptContainer-4YPRUM3C.mjs +148 -0
  5. package/dist/lib/browser/ScriptContainer-4YPRUM3C.mjs.map +7 -0
  6. package/dist/lib/browser/{app-graph-builder-IABOSTBK.mjs → app-graph-builder-LEOPGBJD.mjs} +10 -8
  7. package/dist/lib/browser/app-graph-builder-LEOPGBJD.mjs.map +7 -0
  8. package/dist/lib/browser/{blueprint-definition-AR7ITBCD.mjs → blueprint-definition-6PZWZM2Y.mjs} +5 -3
  9. package/dist/lib/{node-esm/blueprint-definition-TJY4TX6S.mjs.map → browser/blueprint-definition-6PZWZM2Y.mjs.map} +1 -1
  10. package/dist/lib/browser/chunk-5S5YQNJZ.mjs +304 -0
  11. package/dist/lib/browser/chunk-5S5YQNJZ.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-6CAH7VIE.mjs → chunk-A5K3TXYA.mjs} +20 -34
  13. package/dist/lib/browser/chunk-A5K3TXYA.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-QYAREHGH.mjs → chunk-EB6AXFXO.mjs} +8 -5
  15. package/dist/lib/browser/chunk-EB6AXFXO.mjs.map +7 -0
  16. package/dist/lib/browser/chunk-HCURXADW.mjs +102 -0
  17. package/dist/lib/browser/chunk-HCURXADW.mjs.map +7 -0
  18. package/dist/lib/browser/{chunk-TH7GXPE3.mjs → chunk-HHTOAI2J.mjs} +126 -38
  19. package/dist/lib/browser/chunk-HHTOAI2J.mjs.map +7 -0
  20. package/dist/lib/browser/{chunk-YCZPTTFO.mjs → chunk-IQMYIWHG.mjs} +14 -14
  21. package/dist/lib/browser/chunk-IQMYIWHG.mjs.map +7 -0
  22. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  23. package/dist/lib/browser/chunk-LI4P25M5.mjs +111 -0
  24. package/dist/lib/browser/chunk-LI4P25M5.mjs.map +7 -0
  25. package/dist/lib/browser/{chunk-NXKU3BNX.mjs → chunk-Q2DGRQRN.mjs} +47 -14
  26. package/dist/lib/browser/chunk-Q2DGRQRN.mjs.map +7 -0
  27. package/dist/lib/browser/chunk-ST3ACVUC.mjs +88 -0
  28. package/dist/lib/browser/chunk-ST3ACVUC.mjs.map +7 -0
  29. package/dist/lib/browser/{chunk-5TVBECWH.mjs → chunk-UOQ6NCH3.mjs} +2 -2
  30. package/dist/lib/browser/{compiler-2HJH34GM.mjs → compiler-Q4UY2COU.mjs} +12 -24
  31. package/dist/lib/{node-esm/compiler-7SP27RA6.mjs.map → browser/compiler-Q4UY2COU.mjs.map} +2 -2
  32. package/dist/lib/browser/index.mjs +105 -41
  33. package/dist/lib/browser/index.mjs.map +3 -3
  34. package/dist/lib/browser/{intent-resolver-YMK5SXVC.mjs → intent-resolver-AMMHATM7.mjs} +39 -23
  35. package/dist/lib/browser/intent-resolver-AMMHATM7.mjs.map +7 -0
  36. package/dist/lib/browser/meta.json +1 -1
  37. package/dist/lib/browser/{react-surface-FEM5WWFH.mjs → react-surface-X4NATU6B.mjs} +43 -19
  38. package/dist/lib/browser/react-surface-X4NATU6B.mjs.map +7 -0
  39. package/dist/lib/browser/{settings-KCTBK5TY.mjs → settings-6UXY7F7D.mjs} +10 -8
  40. package/dist/lib/browser/settings-6UXY7F7D.mjs.map +7 -0
  41. package/dist/lib/browser/templates/index.mjs +2 -1
  42. package/dist/lib/browser/types/index.mjs +8 -4
  43. package/dist/lib/node-esm/DeploymentDialog-OSHHSEBH.mjs +15 -0
  44. package/dist/lib/node-esm/DeploymentDialog-OSHHSEBH.mjs.map +7 -0
  45. package/dist/lib/node-esm/NotebookContainer-FOVFGJQR.mjs +818 -0
  46. package/dist/lib/node-esm/NotebookContainer-FOVFGJQR.mjs.map +7 -0
  47. package/dist/lib/node-esm/ScriptContainer-EW24D5II.mjs +149 -0
  48. package/dist/lib/node-esm/ScriptContainer-EW24D5II.mjs.map +7 -0
  49. package/dist/lib/node-esm/{app-graph-builder-CQTTAYHP.mjs → app-graph-builder-XJ3MY5BM.mjs} +10 -8
  50. package/dist/lib/node-esm/app-graph-builder-XJ3MY5BM.mjs.map +7 -0
  51. package/dist/lib/node-esm/{blueprint-definition-TJY4TX6S.mjs → blueprint-definition-5R6YCSZZ.mjs} +4 -3
  52. package/dist/lib/{browser/blueprint-definition-AR7ITBCD.mjs.map → node-esm/blueprint-definition-5R6YCSZZ.mjs.map} +1 -1
  53. package/dist/lib/node-esm/chunk-2GVTWESW.mjs +90 -0
  54. package/dist/lib/node-esm/chunk-2GVTWESW.mjs.map +7 -0
  55. package/dist/lib/node-esm/{chunk-35M3CHYE.mjs → chunk-55JZVM6K.mjs} +2 -2
  56. package/dist/lib/node-esm/chunk-EJLYOSD7.mjs +113 -0
  57. package/dist/lib/node-esm/chunk-EJLYOSD7.mjs.map +7 -0
  58. package/dist/lib/node-esm/{chunk-2GBESIHU.mjs → chunk-GA27XSEY.mjs} +20 -34
  59. package/dist/lib/node-esm/chunk-GA27XSEY.mjs.map +7 -0
  60. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  61. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  62. package/dist/lib/node-esm/{chunk-AHXJ6NQU.mjs → chunk-IBV2DR36.mjs} +8 -5
  63. package/dist/lib/node-esm/chunk-IBV2DR36.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-N2XLVOFB.mjs +103 -0
  65. package/dist/lib/node-esm/chunk-N2XLVOFB.mjs.map +7 -0
  66. package/dist/lib/node-esm/{chunk-M642JUOZ.mjs → chunk-O7HXE72S.mjs} +47 -14
  67. package/dist/lib/node-esm/chunk-O7HXE72S.mjs.map +7 -0
  68. package/dist/lib/node-esm/{chunk-6M2R2FQF.mjs → chunk-OZ6LCME4.mjs} +126 -38
  69. package/dist/lib/node-esm/chunk-OZ6LCME4.mjs.map +7 -0
  70. package/dist/lib/node-esm/chunk-TUGLYZDT.mjs +305 -0
  71. package/dist/lib/node-esm/chunk-TUGLYZDT.mjs.map +7 -0
  72. package/dist/lib/node-esm/{chunk-ZA36GO4T.mjs → chunk-UEGPBCSF.mjs} +14 -14
  73. package/dist/lib/node-esm/chunk-UEGPBCSF.mjs.map +7 -0
  74. package/dist/lib/node-esm/{compiler-7SP27RA6.mjs → compiler-I6A4KE6E.mjs} +12 -24
  75. package/dist/lib/{browser/compiler-2HJH34GM.mjs.map → node-esm/compiler-I6A4KE6E.mjs.map} +2 -2
  76. package/dist/lib/node-esm/index.mjs +105 -41
  77. package/dist/lib/node-esm/index.mjs.map +3 -3
  78. package/dist/lib/node-esm/{intent-resolver-SKRDYQCZ.mjs → intent-resolver-YKLZQR7U.mjs} +39 -23
  79. package/dist/lib/node-esm/intent-resolver-YKLZQR7U.mjs.map +7 -0
  80. package/dist/lib/node-esm/meta.json +1 -1
  81. package/dist/lib/node-esm/{react-surface-AOKMDJR4.mjs → react-surface-LVGLBSTE.mjs} +43 -19
  82. package/dist/lib/node-esm/react-surface-LVGLBSTE.mjs.map +7 -0
  83. package/dist/lib/node-esm/{settings-DXZ334A3.mjs → settings-O4EZPUE3.mjs} +10 -8
  84. package/dist/lib/node-esm/settings-O4EZPUE3.mjs.map +7 -0
  85. package/dist/lib/node-esm/templates/index.mjs +2 -1
  86. package/dist/lib/node-esm/types/index.mjs +8 -4
  87. package/dist/types/src/ScriptPlugin.d.ts +1 -1
  88. package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
  89. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  90. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  91. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  92. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts +1 -1
  93. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts.map +1 -1
  94. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts +110 -7
  95. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts.map +1 -1
  96. package/dist/types/src/components/NotebookContainer.d.ts +10 -0
  97. package/dist/types/src/components/NotebookContainer.d.ts.map +1 -0
  98. package/dist/types/src/components/NotebookContainer.stories.d.ts +251 -0
  99. package/dist/types/src/components/NotebookContainer.stories.d.ts.map +1 -0
  100. package/dist/types/src/components/NotebookStack/NotebookCell.d.ts +15 -0
  101. package/dist/types/src/components/NotebookStack/NotebookCell.d.ts.map +1 -0
  102. package/dist/types/src/components/NotebookStack/NotebookMenu.d.ts +9 -0
  103. package/dist/types/src/components/NotebookStack/NotebookMenu.d.ts.map +1 -0
  104. package/dist/types/src/components/NotebookStack/NotebookStack.d.ts +14 -0
  105. package/dist/types/src/components/NotebookStack/NotebookStack.d.ts.map +1 -0
  106. package/dist/types/src/components/NotebookStack/NotebookStack.stories.d.ts +245 -0
  107. package/dist/types/src/components/NotebookStack/NotebookStack.stories.d.ts.map +1 -0
  108. package/dist/types/src/components/NotebookStack/index.d.ts +3 -0
  109. package/dist/types/src/components/NotebookStack/index.d.ts.map +1 -0
  110. package/dist/types/src/components/ScriptContainer.d.ts +4 -4
  111. package/dist/types/src/components/ScriptContainer.d.ts.map +1 -1
  112. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts +5 -6
  113. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -1
  114. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts +237 -2
  115. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts.map +1 -1
  116. package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts +2 -2
  117. package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts.map +1 -1
  118. package/dist/types/src/components/Settings/ScriptPluginSettings.d.ts +2 -2
  119. package/dist/types/src/components/Settings/ScriptPluginSettings.d.ts.map +1 -1
  120. package/dist/types/src/components/TestPanel/TestContainer.d.ts +2 -2
  121. package/dist/types/src/components/TestPanel/TestContainer.d.ts.map +1 -1
  122. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts +4 -2
  123. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -1
  124. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts +3 -3
  125. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts.map +1 -1
  126. package/dist/types/src/components/index.d.ts +2 -0
  127. package/dist/types/src/components/index.d.ts.map +1 -1
  128. package/dist/types/src/events.d.ts.map +1 -1
  129. package/dist/types/src/hooks/deploy.d.ts +11 -11
  130. package/dist/types/src/hooks/deploy.d.ts.map +1 -1
  131. package/dist/types/src/hooks/format.d.ts +2 -2
  132. package/dist/types/src/hooks/format.d.ts.map +1 -1
  133. package/dist/types/src/hooks/template.d.ts +4 -14
  134. package/dist/types/src/hooks/template.d.ts.map +1 -1
  135. package/dist/types/src/index.d.ts +1 -0
  136. package/dist/types/src/index.d.ts.map +1 -1
  137. package/dist/types/src/meta.d.ts +0 -1
  138. package/dist/types/src/meta.d.ts.map +1 -1
  139. package/dist/types/src/notebook/compute-graph.d.ts +45 -0
  140. package/dist/types/src/notebook/compute-graph.d.ts.map +1 -0
  141. package/dist/types/src/notebook/compute-graph.test.d.ts +2 -0
  142. package/dist/types/src/notebook/compute-graph.test.d.ts.map +1 -0
  143. package/dist/types/src/notebook/eval.d.ts +13 -0
  144. package/dist/types/src/notebook/eval.d.ts.map +1 -0
  145. package/dist/types/src/notebook/index.d.ts +2 -0
  146. package/dist/types/src/notebook/index.d.ts.map +1 -0
  147. package/dist/types/src/notebook/vfs-parser.d.ts +74 -0
  148. package/dist/types/src/notebook/vfs-parser.d.ts.map +1 -0
  149. package/dist/types/src/notebook/vfs-parser.test.d.ts +2 -0
  150. package/dist/types/src/notebook/vfs-parser.test.d.ts.map +1 -0
  151. package/dist/types/src/templates/chess.d.ts.map +1 -1
  152. package/dist/types/src/templates/data-generator.d.ts.map +1 -1
  153. package/dist/types/src/templates/discord.d.ts.map +1 -1
  154. package/dist/types/src/templates/forex-effect.d.ts.map +1 -1
  155. package/dist/types/src/templates/forex.d.ts.map +1 -1
  156. package/dist/types/src/templates/gmail.d.ts.map +1 -1
  157. package/dist/types/src/templates/index.d.ts +43 -1
  158. package/dist/types/src/templates/index.d.ts.map +1 -1
  159. package/dist/types/src/templates/{echo.d.ts → ping.d.ts} +1 -1
  160. package/dist/types/src/templates/ping.d.ts.map +1 -0
  161. package/dist/types/src/testing/data.d.ts +3 -0
  162. package/dist/types/src/testing/data.d.ts.map +1 -0
  163. package/dist/types/src/testing/index.d.ts +2 -0
  164. package/dist/types/src/testing/index.d.ts.map +1 -0
  165. package/dist/types/src/translations.d.ts +29 -5
  166. package/dist/types/src/translations.d.ts.map +1 -1
  167. package/dist/types/src/types/Notebook.d.ts +31 -0
  168. package/dist/types/src/types/Notebook.d.ts.map +1 -0
  169. package/dist/types/src/types/actions.d.ts +54 -0
  170. package/dist/types/src/types/actions.d.ts.map +1 -0
  171. package/dist/types/src/types/index.d.ts +3 -1
  172. package/dist/types/src/types/index.d.ts.map +1 -1
  173. package/dist/types/src/types/types.d.ts +6 -0
  174. package/dist/types/src/types/types.d.ts.map +1 -0
  175. package/dist/types/src/util/deploy.d.ts +4 -4
  176. package/dist/types/src/util/deploy.d.ts.map +1 -1
  177. package/dist/types/src/util/functions.d.ts +6 -3
  178. package/dist/types/src/util/functions.d.ts.map +1 -1
  179. package/dist/types/tsconfig.tsbuildinfo +1 -1
  180. package/package.json +75 -68
  181. package/src/ScriptPlugin.tsx +88 -69
  182. package/src/capabilities/app-graph-builder.ts +7 -6
  183. package/src/capabilities/artifact-definition.ts +1 -1
  184. package/src/capabilities/intent-resolver.ts +20 -11
  185. package/src/capabilities/react-surface.tsx +25 -13
  186. package/src/capabilities/settings.ts +3 -3
  187. package/src/components/DeploymentDialog/DeploymentDialog.stories.tsx +11 -4
  188. package/src/components/DeploymentDialog/DeploymentDialog.tsx +11 -17
  189. package/src/components/NotebookContainer.stories.tsx +83 -0
  190. package/src/components/NotebookContainer.tsx +263 -0
  191. package/src/components/NotebookStack/NotebookCell.tsx +208 -0
  192. package/src/components/NotebookStack/NotebookMenu.tsx +47 -0
  193. package/src/components/NotebookStack/NotebookStack.stories.tsx +54 -0
  194. package/src/components/NotebookStack/NotebookStack.tsx +86 -0
  195. package/src/components/NotebookStack/index.ts +6 -0
  196. package/src/components/ScriptContainer.tsx +5 -5
  197. package/src/components/ScriptToolbar/ScriptToolbar.stories.tsx +22 -10
  198. package/src/components/ScriptToolbar/ScriptToolbar.tsx +24 -27
  199. package/src/components/Settings/ScriptObjectSettings.tsx +95 -11
  200. package/src/components/Settings/ScriptPluginSettings.tsx +4 -19
  201. package/src/components/TestPanel/TestContainer.tsx +2 -2
  202. package/src/components/TestPanel/TestPanel.tsx +7 -7
  203. package/src/components/TypescriptEditor/TypescriptEditor.stories.tsx +71 -16
  204. package/src/components/TypescriptEditor/TypescriptEditor.tsx +36 -34
  205. package/src/components/index.ts +3 -0
  206. package/src/events.ts +2 -2
  207. package/src/hooks/deploy.ts +14 -15
  208. package/src/hooks/format.ts +4 -4
  209. package/src/hooks/template.ts +6 -15
  210. package/src/hooks/useCreateAndDeployScriptTemplates.ts +5 -5
  211. package/src/index.ts +1 -0
  212. package/src/meta.ts +7 -5
  213. package/src/notebook/compute-graph.test.ts +70 -0
  214. package/src/notebook/compute-graph.ts +206 -0
  215. package/src/notebook/eval.ts +105 -0
  216. package/src/notebook/index.ts +5 -0
  217. package/src/notebook/vfs-parser.test.ts +149 -0
  218. package/src/notebook/vfs-parser.ts +451 -0
  219. package/src/templates/chess.ts +2 -0
  220. package/src/templates/data-generator.ts +2 -0
  221. package/src/templates/discord.ts +9 -1
  222. package/src/templates/forex-effect.ts +5 -1
  223. package/src/templates/forex.ts +2 -0
  224. package/src/templates/gmail.ts +21 -9
  225. package/src/templates/index.ts +6 -6
  226. package/src/testing/data.ts +72 -0
  227. package/src/testing/index.ts +5 -0
  228. package/src/translations.ts +32 -7
  229. package/src/types/Notebook.ts +41 -0
  230. package/src/types/actions.ts +53 -0
  231. package/src/types/index.ts +3 -1
  232. package/src/types/types.ts +15 -0
  233. package/src/util/deploy.ts +11 -15
  234. package/src/util/functions.ts +33 -4
  235. package/dist/lib/browser/DeploymentDialog-QZSTVNIS.mjs +0 -12
  236. package/dist/lib/browser/ScriptContainer-JUPCBUCP.mjs +0 -263
  237. package/dist/lib/browser/ScriptContainer-JUPCBUCP.mjs.map +0 -7
  238. package/dist/lib/browser/app-graph-builder-IABOSTBK.mjs.map +0 -7
  239. package/dist/lib/browser/chunk-6CAH7VIE.mjs.map +0 -7
  240. package/dist/lib/browser/chunk-IS4OG2UW.mjs +0 -39
  241. package/dist/lib/browser/chunk-IS4OG2UW.mjs.map +0 -7
  242. package/dist/lib/browser/chunk-NXKU3BNX.mjs.map +0 -7
  243. package/dist/lib/browser/chunk-QYAREHGH.mjs.map +0 -7
  244. package/dist/lib/browser/chunk-RNGIQIEJ.mjs +0 -88
  245. package/dist/lib/browser/chunk-RNGIQIEJ.mjs.map +0 -7
  246. package/dist/lib/browser/chunk-TH7GXPE3.mjs.map +0 -7
  247. package/dist/lib/browser/chunk-YCZPTTFO.mjs.map +0 -7
  248. package/dist/lib/browser/intent-resolver-YMK5SXVC.mjs.map +0 -7
  249. package/dist/lib/browser/react-surface-FEM5WWFH.mjs.map +0 -7
  250. package/dist/lib/browser/settings-KCTBK5TY.mjs.map +0 -7
  251. package/dist/lib/node-esm/DeploymentDialog-G6EHEPXN.mjs +0 -13
  252. package/dist/lib/node-esm/ScriptContainer-UXZUDQF6.mjs +0 -264
  253. package/dist/lib/node-esm/ScriptContainer-UXZUDQF6.mjs.map +0 -7
  254. package/dist/lib/node-esm/app-graph-builder-CQTTAYHP.mjs.map +0 -7
  255. package/dist/lib/node-esm/chunk-2GBESIHU.mjs.map +0 -7
  256. package/dist/lib/node-esm/chunk-6M2R2FQF.mjs.map +0 -7
  257. package/dist/lib/node-esm/chunk-AHXJ6NQU.mjs.map +0 -7
  258. package/dist/lib/node-esm/chunk-GWHLP5LM.mjs +0 -90
  259. package/dist/lib/node-esm/chunk-GWHLP5LM.mjs.map +0 -7
  260. package/dist/lib/node-esm/chunk-JIPFLBYA.mjs +0 -40
  261. package/dist/lib/node-esm/chunk-JIPFLBYA.mjs.map +0 -7
  262. package/dist/lib/node-esm/chunk-M642JUOZ.mjs.map +0 -7
  263. package/dist/lib/node-esm/chunk-ZA36GO4T.mjs.map +0 -7
  264. package/dist/lib/node-esm/intent-resolver-SKRDYQCZ.mjs.map +0 -7
  265. package/dist/lib/node-esm/react-surface-AOKMDJR4.mjs.map +0 -7
  266. package/dist/lib/node-esm/settings-DXZ334A3.mjs.map +0 -7
  267. package/dist/types/src/templates/echo.d.ts.map +0 -1
  268. package/dist/types/src/types/schema.d.ts +0 -38
  269. package/dist/types/src/types/schema.d.ts.map +0 -1
  270. package/src/types/schema.ts +0 -37
  271. /package/dist/lib/browser/{DeploymentDialog-QZSTVNIS.mjs.map → DeploymentDialog-E5NXT4UQ.mjs.map} +0 -0
  272. /package/dist/lib/{node-esm/DeploymentDialog-G6EHEPXN.mjs.map → browser/chunk-J5LGTIGS.mjs.map} +0 -0
  273. /package/dist/lib/browser/{chunk-5TVBECWH.mjs.map → chunk-UOQ6NCH3.mjs.map} +0 -0
  274. /package/dist/lib/node-esm/{chunk-35M3CHYE.mjs.map → chunk-55JZVM6K.mjs.map} +0 -0
  275. /package/src/templates/{echo.ts → ping.ts} +0 -0
@@ -2,36 +2,91 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
- import React, { useMemo } from 'react';
6
+ import React, { useCallback, useMemo, useState } from 'react';
9
7
 
10
- import { createDocAccessor, createObject } from '@dxos/react-client/echo';
8
+ import { createDocAccessor } from '@dxos/react-client/echo';
9
+ import { createObject } from '@dxos/react-client/echo';
10
+ import { Toolbar } from '@dxos/react-ui';
11
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
12
  import { createDataExtensions } from '@dxos/react-ui-editor';
12
- import { withTheme } from '@dxos/storybook-utils';
13
+ import { StackItem } from '@dxos/react-ui-stack';
14
+ import { Json } from '@dxos/react-ui-syntax-highlighter';
15
+ import { trim } from '@dxos/util';
16
+
17
+ import { TypescriptEditor, type TypescriptEditorProps } from './TypescriptEditor';
18
+
19
+ const SCRIPT = trim`
20
+ x * 2
21
+ `;
22
+
23
+ const DefaultStory = (props: TypescriptEditorProps) => {
24
+ const object = useMemo(() => createObject({ content: SCRIPT }), []);
25
+ const [result, setResult] = useState<object | undefined>({});
13
26
 
14
- import { templates } from '../../templates';
27
+ // TODO(burdon): Make this work.
28
+ // const object = useMemo(() => DataType.makeText(templates[1].source), []);
29
+ // const script = useMemo(
30
+ // () =>
31
+ // Obj.make(ScriptType, {
32
+ // source: Ref.make(createObject({ content: templates[0].source })),
33
+ // }),
34
+ // [object],
35
+ // );
15
36
 
16
- import { TypescriptEditor } from './TypescriptEditor';
37
+ const extensions = useMemo(
38
+ () => [createDataExtensions({ id: object.id, text: createDocAccessor(object, ['content']) })],
39
+ [],
40
+ );
17
41
 
18
- const DefaultStory = () => {
19
- const object = useMemo(() => createObject({ content: templates[0].source }), []);
20
- const initialValue = useMemo(() => object.content, [object]);
21
- const accessor = useMemo(() => createDocAccessor(object, ['content']), [object]);
22
- const extensions = useMemo(() => [createDataExtensions({ id: object.id, text: accessor })], [object.id, accessor]);
23
- return <TypescriptEditor id='test' initialValue={initialValue} extensions={extensions} />;
42
+ const handleRun = useCallback(async () => {
43
+ try {
44
+ const definitions: [string, any][] = [['x', 100]];
45
+
46
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
47
+ const result = new Function(...definitions.map(([name]) => name), `return ${object.content.trim()}`)(
48
+ ...definitions.map(([, value]) => value),
49
+ );
50
+
51
+ setResult({
52
+ timestamp: Date.now(),
53
+ result,
54
+ });
55
+ } catch (err) {
56
+ setResult({
57
+ timestamp: Date.now(),
58
+ error: String(err),
59
+ });
60
+ }
61
+ }, [object]);
62
+
63
+ return (
64
+ <StackItem.Content toolbar>
65
+ {/* <ScriptToolbar script={script} state={{}} /> */}
66
+ <Toolbar.Root>
67
+ <Toolbar.Button onClick={handleRun}>Run</Toolbar.Button>
68
+ </Toolbar.Root>
69
+ <div role='none' className='grid grid-rows-[1fr_min-content] bs-full overflow-hidden text-sm'>
70
+ <TypescriptEditor {...props} initialValue={object.content} extensions={extensions} />
71
+ <Json data={result} classNames='shrink-0 p-2 border-t border-subduedSeparator' />
72
+ </div>
73
+ </StackItem.Content>
74
+ );
24
75
  };
25
76
 
26
77
  const meta = {
27
78
  title: 'plugins/plugin-script/TypescriptEditor',
28
- component: TypescriptEditor as any,
79
+ component: TypescriptEditor,
29
80
  render: DefaultStory,
30
- decorators: [withTheme],
81
+ decorators: [withTheme, withLayout({ container: 'column', classNames: 'is-prose' })],
31
82
  } satisfies Meta<typeof DefaultStory>;
32
83
 
33
84
  export default meta;
34
85
 
35
86
  type Story = StoryObj<typeof meta>;
36
87
 
37
- export const Default: Story = {};
88
+ export const Default: Story = {
89
+ args: {
90
+ id: 'test',
91
+ },
92
+ };
@@ -2,11 +2,11 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { autocompletion, completionKeymap } from '@codemirror/autocomplete';
5
6
  import { javascript } from '@codemirror/lang-javascript';
6
- import { defaultHighlightStyle } from '@codemirror/language';
7
+ import { HighlightStyle } from '@codemirror/language';
7
8
  import { lintKeymap } from '@codemirror/lint';
8
9
  import { Prec } from '@codemirror/state';
9
- import { oneDarkHighlightStyle } from '@codemirror/theme-one-dark';
10
10
  import { keymap } from '@codemirror/view';
11
11
  import { tags } from '@lezer/highlight';
12
12
  import { type VirtualTypeScriptEnvironment } from '@typescript/vfs';
@@ -14,15 +14,15 @@ import { continueKeymap } from '@valtown/codemirror-continue';
14
14
  import { type HoverInfo, tsAutocomplete, tsFacet, tsHover, tsLinter, tsSync } from '@valtown/codemirror-ts';
15
15
  import React from 'react';
16
16
 
17
- import { type ThemeMode, type ThemedClassName, useThemeContext } from '@dxos/react-ui';
17
+ import { Domino, type ThemeMode, type ThemedClassName, useThemeContext } from '@dxos/react-ui';
18
18
  import {
19
+ type BasicExtensionsOptions,
19
20
  type EditorInputMode,
20
21
  InputModeExtensions,
21
22
  type UseTextEditorProps,
22
- autocomplete,
23
23
  createBasicExtensions,
24
24
  createThemeExtensions,
25
- folding,
25
+ defaultStyles,
26
26
  useTextEditor,
27
27
  } from '@dxos/react-ui-editor';
28
28
  import { mx } from '@dxos/react-ui-theme';
@@ -31,18 +31,22 @@ import { isNonNullable } from '@dxos/util';
31
31
  export type TypescriptEditorProps = ThemedClassName<
32
32
  {
33
33
  id: string;
34
+ role?: string;
34
35
  inputMode?: EditorInputMode;
35
36
  toolbar?: boolean;
36
37
  env?: VirtualTypeScriptEnvironment;
38
+ options?: BasicExtensionsOptions;
37
39
  } & Pick<UseTextEditorProps, 'initialValue' | 'extensions' | 'scrollTo' | 'selection'>
38
40
  >;
39
41
 
40
42
  export const TypescriptEditor = ({
41
43
  classNames,
42
44
  id,
45
+ role = 'article',
43
46
  inputMode = 'vscode',
44
47
  toolbar,
45
48
  env,
49
+ options,
46
50
  initialValue,
47
51
  extensions,
48
52
  scrollTo,
@@ -62,21 +66,26 @@ export const TypescriptEditor = ({
62
66
  indentWithTab: true,
63
67
  lineNumbers: true,
64
68
  lineWrapping: false,
65
- monospace: true,
66
- scrollPastEnd: true,
69
+ scrollPastEnd: role !== 'section',
67
70
  search: true,
71
+ ...options,
72
+ }),
73
+ createThemeExtensions({
74
+ monospace: true,
75
+ themeMode,
76
+ syntaxHighlighting: true,
68
77
  }),
69
- createThemeExtensions({ themeMode, syntaxHighlighting: true }),
70
78
  InputModeExtensions[inputMode],
71
- folding(),
79
+
80
+ javascript({ typescript: true }),
81
+ autocompletion({ override: env ? [tsAutocomplete()] : undefined }),
82
+
72
83
  // Continues block comments when pressing Enter.
73
84
  Prec.high(keymap.of(continueKeymap)),
85
+ keymap.of(completionKeymap),
86
+ keymap.of(lintKeymap),
74
87
 
75
- // TODO(burdon): Factor out.
76
- javascript({ typescript: true }),
77
88
  // https://github.com/val-town/codemirror-ts
78
- autocomplete({ override: env ? [tsAutocomplete()] : undefined }),
79
- keymap.of(lintKeymap),
80
89
  env && [
81
90
  tsFacet.of({ env, path: `/src/${id}.ts` }),
82
91
  tsSync(),
@@ -88,18 +97,13 @@ export const TypescriptEditor = ({
88
97
  [id, extensions, themeMode, inputMode, selection, scrollTo],
89
98
  );
90
99
 
91
- return (
92
- <div
93
- ref={parentRef}
94
- data-toolbar={toolbar ? 'enabled' : 'disabled'}
95
- className={mx(classNames)}
96
- {...focusAttributes}
97
- />
98
- );
100
+ // TODO(brudon): Use react-ui-editor's Editor component.
101
+ return <div ref={parentRef} className={mx(classNames)} {...focusAttributes} />;
99
102
  };
100
103
 
104
+ // TODO(burdon): Factor out (react-ui-editor).
101
105
  const createTooltipRenderer = (themeMode: ThemeMode) => {
102
- const theme = themeMode === 'dark' ? oneDarkHighlightStyle : defaultHighlightStyle;
106
+ const theme = HighlightStyle.define(themeMode === 'dark' ? defaultStyles.dark : defaultStyles.light);
103
107
 
104
108
  const classFromKind = (_kind: string) => {
105
109
  // E.g., localName, methodName, parameterName, etc.
@@ -118,18 +122,16 @@ const createTooltipRenderer = (themeMode: ThemeMode) => {
118
122
  };
119
123
 
120
124
  return (info: HoverInfo) => {
121
- const div = document.createElement('div');
122
- div.className = 'p-1 rounded border border-separator bg-baseSurface xs:max-w-80 max-w-lg';
123
-
124
- if (info.quickInfo?.displayParts) {
125
- for (const part of info.quickInfo.displayParts) {
126
- const span = div.appendChild(document.createElement('span'));
127
- span.className = classFromKind(part.kind);
128
- span.innerText = part.text;
129
- }
130
- }
131
-
132
- return { dom: div };
125
+ return {
126
+ dom: Domino.of('div')
127
+ .classNames('xs:max-is-80 max-is-lg p-1 bg-baseSurface rounded border border-separator')
128
+ .children(
129
+ ...(info.quickInfo?.displayParts?.map(({ kind, text }) =>
130
+ Domino.of('span').classNames(classFromKind(kind)).text(text),
131
+ ) ?? []),
132
+ )
133
+ .build(),
134
+ };
133
135
  };
134
136
  };
135
137
 
@@ -4,9 +4,12 @@
4
4
 
5
5
  import { lazy } from 'react';
6
6
 
7
+ export * from './NotebookStack';
7
8
  export * from './Settings';
8
9
  export * from './TestPanel';
10
+
9
11
  export { DEPLOYMENT_DIALOG } from './DeploymentDialog';
10
12
 
11
13
  export const ScriptContainer = lazy(() => import('./ScriptContainer'));
12
14
  export const DeploymentDialog = lazy(() => import('./DeploymentDialog'));
15
+ export const NotebookContainer = lazy(() => import('./NotebookContainer'));
package/src/events.ts CHANGED
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { defineEvent } from '@dxos/app-framework';
6
6
 
7
- import { SCRIPT_PLUGIN } from './meta';
7
+ import { meta } from './meta';
8
8
 
9
9
  export namespace ScriptEvents {
10
- export const SetupCompiler = defineEvent(`${SCRIPT_PLUGIN}/event/setup-compiler`);
10
+ export const SetupCompiler = defineEvent(`${meta.id}/event/setup-compiler`);
11
11
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { useEffect, useMemo } from 'react';
6
6
 
7
- import { FunctionType, type ScriptType, getUserFunctionIdInMetadata } from '@dxos/functions';
7
+ import { Function, type Script, getUserFunctionIdInMetadata } from '@dxos/functions';
8
8
  import { log } from '@dxos/log';
9
9
  import { type Client, useClient } from '@dxos/react-client';
10
10
  import { Query, Ref, type Space, getMeta, getSpace, useQuery } from '@dxos/react-client/echo';
@@ -12,7 +12,7 @@ import { type TFunction } from '@dxos/react-ui';
12
12
  import { createMenuAction } from '@dxos/react-ui-menu';
13
13
  import { errorMessageColors } from '@dxos/react-ui-theme';
14
14
 
15
- import { SCRIPT_PLUGIN } from '../meta';
15
+ import { meta } from '../meta';
16
16
  import { deployScript, getFunctionUrl, isScriptDeployed } from '../util';
17
17
 
18
18
  export type DeployActionProperties = { type: 'deploy' } | { type: 'copy' };
@@ -26,8 +26,8 @@ export type DeployState = {
26
26
 
27
27
  export type CreateDeployOptions = {
28
28
  state: Partial<DeployState>;
29
- script: ScriptType;
30
- fn: FunctionType;
29
+ script: Script.Script;
30
+ fn: Function.Function;
31
31
  space?: Space;
32
32
  existingFunctionId?: string;
33
33
  client: Client;
@@ -37,7 +37,7 @@ export type CreateDeployOptions = {
37
37
  export const createDeploy = ({ state, script, space, fn, client, existingFunctionId, t }: CreateDeployOptions) => {
38
38
  // TODO(wittjosiah): Should this be an action?
39
39
  const errorItem = createMenuAction('error', () => {}, {
40
- label: state.error ?? ['no error label', { ns: SCRIPT_PLUGIN }],
40
+ label: state.error ?? ['no error label', { ns: meta.id }],
41
41
  icon: 'ph--warning-circle--regular',
42
42
  hidden: !state.error,
43
43
  classNames: state.error && errorMessageColors,
@@ -64,7 +64,7 @@ export const createDeploy = ({ state, script, space, fn, client, existingFunctio
64
64
  },
65
65
  {
66
66
  type: 'deploy',
67
- label: [state.deploying ? 'pending label' : 'deploy label', { ns: SCRIPT_PLUGIN }],
67
+ label: [state.deploying ? 'publishing label' : 'deploy label', { ns: meta.id }],
68
68
  icon: state.deploying ? 'ph--spinner-gap--regular' : 'ph--cloud-arrow-up--regular',
69
69
  disabled: state.deploying,
70
70
  classNames: state.deploying ? '[&_svg]:animate-spin' : '',
@@ -74,14 +74,13 @@ export const createDeploy = ({ state, script, space, fn, client, existingFunctio
74
74
  const copyAction = createMenuAction<DeployActionProperties>(
75
75
  'copy',
76
76
  async () => {
77
- if (!state.functionUrl) {
78
- return;
77
+ if (state.functionUrl) {
78
+ await navigator.clipboard.writeText(state.functionUrl);
79
79
  }
80
- await navigator.clipboard.writeText(state.functionUrl);
81
80
  },
82
81
  {
83
82
  type: 'copy',
84
- label: ['copy link label', { ns: SCRIPT_PLUGIN }],
83
+ label: ['copy link label', { ns: meta.id }],
85
84
  icon: 'ph--link--regular',
86
85
  disabled: !state.functionUrl,
87
86
  },
@@ -97,7 +96,7 @@ export const createDeploy = ({ state, script, space, fn, client, existingFunctio
97
96
  };
98
97
  };
99
98
 
100
- export const useDeployState = ({ state, script }: { state: Partial<DeployState>; script: ScriptType }) => {
99
+ export const useDeployState = ({ state, script }: { state: Partial<DeployState>; script: Script.Script }) => {
101
100
  const { space, client, fn, existingFunctionId } = useDeployDeps({ script });
102
101
  useEffect(() => {
103
102
  if (!existingFunctionId) {
@@ -116,10 +115,10 @@ export const useDeployState = ({ state, script }: { state: Partial<DeployState>;
116
115
  }, [script.changed, existingFunctionId, fn, script]);
117
116
  };
118
117
 
119
- export const useDeployDeps = ({ script }: { script: ScriptType }) => {
120
- const space = getSpace(script);
121
- const [fn] = useQuery(space, Query.type(FunctionType, { source: Ref.make(script) }));
118
+ export const useDeployDeps = ({ script }: { script: Script.Script }) => {
122
119
  const client = useClient();
120
+ const space = getSpace(script);
121
+ const [fn] = useQuery(space, Query.type(Function.Function, { source: Ref.make(script) }));
123
122
  const existingFunctionId = useMemo(() => fn && getUserFunctionIdInMetadata(getMeta(fn)), [fn]);
124
- return { space, fn, client, existingFunctionId };
123
+ return { client, space, fn, existingFunctionId };
125
124
  };
@@ -6,15 +6,15 @@ import { format } from 'prettier';
6
6
  import prettierPluginEstree from 'prettier/plugins/estree';
7
7
  import prettierPluginTypescript from 'prettier/plugins/typescript';
8
8
 
9
- import { type ScriptType } from '@dxos/functions';
9
+ import { type Script } from '@dxos/functions';
10
10
  import { log } from '@dxos/log';
11
11
  import { createMenuAction } from '@dxos/react-ui-menu';
12
12
 
13
- import { SCRIPT_PLUGIN } from '../meta';
13
+ import { meta } from '../meta';
14
14
 
15
15
  export type FormatActionProperties = { type: 'format' };
16
16
 
17
- export const createFormat = (script: ScriptType) => {
17
+ export const createFormat = (script: Script.Script) => {
18
18
  const formatAction = createMenuAction(
19
19
  'format',
20
20
  async () => {
@@ -35,7 +35,7 @@ export const createFormat = (script: ScriptType) => {
35
35
  }
36
36
  },
37
37
  {
38
- label: ['format label', { ns: SCRIPT_PLUGIN }],
38
+ label: ['format label', { ns: meta.id }],
39
39
  icon: 'ph--magic-wand--regular',
40
40
  },
41
41
  );
@@ -3,22 +3,14 @@
3
3
  //
4
4
 
5
5
  import { Obj } from '@dxos/echo';
6
- import { FUNCTIONS_PRESET_META_KEY, type ScriptType } from '@dxos/functions';
7
- import { createMenuAction, createMenuItemGroup } from '@dxos/react-ui-menu';
6
+ import { FUNCTIONS_PRESET_META_KEY, type Script } from '@dxos/functions';
7
+ import { createMenuAction } from '@dxos/react-ui-menu';
8
8
 
9
- import { SCRIPT_PLUGIN } from '../meta';
10
9
  import { templates } from '../templates';
11
10
 
12
11
  export type TemplateActionProperties = { type: 'template'; value: string };
13
12
 
14
- const createTemplateSelectGroup = () => {
15
- return createMenuItemGroup('template-select', {
16
- label: ['template select group label', { ns: SCRIPT_PLUGIN }],
17
- variant: 'dropdownMenu',
18
- });
19
- };
20
-
21
- const createTemplateSelectActions = (script: ScriptType) => {
13
+ const createTemplateSelectActions = (script: Script.Script) => {
22
14
  return templates.map((template) => {
23
15
  return createMenuAction<TemplateActionProperties>(
24
16
  `template--${template.id}`,
@@ -30,7 +22,7 @@ const createTemplateSelectActions = (script: ScriptType) => {
30
22
  if (oldPresetIndex >= 0) {
31
23
  metaKeys.splice(oldPresetIndex, 1);
32
24
  }
33
- if (template.presetId) {
25
+ if ('presetId' in template) {
34
26
  metaKeys.push({ source: FUNCTIONS_PRESET_META_KEY, id: template.presetId });
35
27
  }
36
28
  },
@@ -43,11 +35,10 @@ const createTemplateSelectActions = (script: ScriptType) => {
43
35
  });
44
36
  };
45
37
 
46
- export const createTemplateSelect = (script: ScriptType) => {
47
- const templateSelectGroup = createTemplateSelectGroup();
38
+ export const createTemplateSelect = (script: Script.Script) => {
48
39
  const templateSelectActions = createTemplateSelectActions(script);
49
40
  return {
50
- nodes: [templateSelectGroup, ...templateSelectActions],
41
+ nodes: [...templateSelectActions],
51
42
  edges: [
52
43
  { source: 'root', target: 'template-select' },
53
44
  ...templateSelectActions.map((action) => ({ source: 'template-select', target: action.id })),
@@ -2,12 +2,12 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { pipe } from 'effect/Function';
5
+ import * as Function from 'effect/Function';
6
6
  import { useCallback, useState } from 'react';
7
7
 
8
8
  import { chain, createIntent, useIntentDispatcher } from '@dxos/app-framework';
9
9
  import { Obj } from '@dxos/echo';
10
- import { ScriptType } from '@dxos/functions';
10
+ import { Script } from '@dxos/functions';
11
11
  import { invariant } from '@dxos/invariant';
12
12
  import { SpaceAction } from '@dxos/plugin-space/types';
13
13
  import { useClient } from '@dxos/react-client';
@@ -40,12 +40,12 @@ export const useCreateAndDeployScriptTemplates = (space: Space | undefined, scri
40
40
  const deploymentResults = await Promise.all(
41
41
  scriptTemplates.map(async (template) => {
42
42
  const result = await dispatch(
43
- pipe(
44
- createIntent(ScriptAction.Create, { space, initialTemplateId: template.id }),
43
+ Function.pipe(
44
+ createIntent(ScriptAction.CreateScript, { space, initialTemplateId: template.id as any }),
45
45
  chain(SpaceAction.AddObject, { target: space }),
46
46
  ),
47
47
  );
48
- invariant(Obj.instanceOf(ScriptType, result.data?.object));
48
+ invariant(Obj.instanceOf(Script.Script, result.data?.object));
49
49
 
50
50
  return deployScript({ space, client, script: result.data.object });
51
51
  }),
package/src/index.ts CHANGED
@@ -5,5 +5,6 @@
5
5
  export { ScriptCapabilities } from './capabilities';
6
6
  export * from './components';
7
7
  export * from './meta';
8
+ export * from './util';
8
9
 
9
10
  export * from './ScriptPlugin';
package/src/meta.ts CHANGED
@@ -3,15 +3,17 @@
3
3
  //
4
4
 
5
5
  import { type PluginMeta } from '@dxos/app-framework';
6
-
7
- export const SCRIPT_PLUGIN = 'dxos.org/plugin/script';
6
+ import { trim } from '@dxos/util';
8
7
 
9
8
  export const meta: PluginMeta = {
10
- id: SCRIPT_PLUGIN,
9
+ id: 'dxos.org/plugin/script',
11
10
  name: 'Scripts',
12
- description:
13
- 'Scripts in Composer allow you to deploy custom functions that run on the edge. These functions can be referenced by your AI agent and called inside of cells in any Sheet. Use scripts to interact with API’s or external data inside of Composer.',
11
+ description: trim`
12
+ Write and deploy custom JavaScript functions that extend your workspace capabilities.
13
+ Create AI agent tools, spreadsheet formulas, and automation scripts that integrate seamlessly with other plugins.
14
+ `,
14
15
  icon: 'ph--code--regular',
16
+ iconHue: 'sky',
15
17
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-explorer',
16
18
  tags: ['labs'],
17
19
  screenshots: ['https://dxos.network/plugin-details-scripts-dark.png'],
@@ -0,0 +1,70 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, test } from 'vitest';
6
+
7
+ import { createNotebook } from '../testing';
8
+
9
+ import { ComputeGraph } from './compute-graph';
10
+
11
+ describe('notebook', () => {
12
+ test('parse dependency graph', async () => {
13
+ const notebook = createNotebook();
14
+ const graph = new ComputeGraph(notebook);
15
+ const result = graph.parse();
16
+
17
+ const getId = (i: number) => notebook.cells[i].id;
18
+
19
+ // Check dependencies.
20
+ expect(result.dependencyGraph).toMatchObject({
21
+ [getId(0)]: [getId(1), getId(2)],
22
+ [getId(3)]: [getId(1)],
23
+ [getId(4)]: [getId(0), getId(3)],
24
+ });
25
+
26
+ // Compute values.
27
+ const values = await graph.evaluate();
28
+ expect(values).toEqual({
29
+ [getId(0)]: 300,
30
+ [getId(2)]: 200,
31
+ [getId(3)]: 200,
32
+ [getId(4)]: 500,
33
+ });
34
+ });
35
+
36
+ test('evalScript blocks access to window and document', async () => {
37
+ const notebook = createNotebook();
38
+ // Replace one of the cells with code that tries to access window/document.
39
+ if (notebook.cells[2].source?.target) {
40
+ notebook.cells[2].source.target.content = 'b = typeof window';
41
+ }
42
+
43
+ const graph = new ComputeGraph(notebook);
44
+ graph.parse();
45
+ const values = await graph.evaluate();
46
+
47
+ // Should evaluate to 'undefined' since window is blocked.
48
+ expect(values[notebook.cells[2].id]).toBe('undefined');
49
+
50
+ // Test document access.
51
+ if (notebook.cells[2].source?.target) {
52
+ notebook.cells[2].source.target.content = 'b = typeof document';
53
+ }
54
+ graph.parse();
55
+ const values2 = await graph.evaluate();
56
+
57
+ // Should evaluate to 'undefined' since document is blocked.
58
+ expect(values2[notebook.cells[2].id]).toBe('undefined');
59
+
60
+ // Test that safe globals still work.
61
+ if (notebook.cells[2].source?.target) {
62
+ notebook.cells[2].source.target.content = 'b = Math.max(100, 200)';
63
+ }
64
+ graph.parse();
65
+ const values3 = await graph.evaluate();
66
+
67
+ // Should evaluate correctly.
68
+ expect(values3[notebook.cells[2].id]).toBe(200);
69
+ });
70
+ });