@dxos/plugin-script 0.8.4-main.28f8d3d → 0.8.4-main.406dc2a

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 (269) hide show
  1. package/dist/lib/browser/DeploymentDialog-65TWT6S5.mjs +13 -0
  2. package/dist/lib/browser/NotebookContainer-LVGRPFY3.mjs +683 -0
  3. package/dist/lib/browser/NotebookContainer-LVGRPFY3.mjs.map +7 -0
  4. package/dist/lib/browser/ScriptContainer-LRTRN7JW.mjs +149 -0
  5. package/dist/lib/browser/ScriptContainer-LRTRN7JW.mjs.map +7 -0
  6. package/dist/lib/browser/{app-graph-builder-IABOSTBK.mjs → app-graph-builder-DPYULSME.mjs} +8 -7
  7. package/dist/lib/browser/app-graph-builder-DPYULSME.mjs.map +7 -0
  8. package/dist/lib/browser/blueprint-definition-ET5KZ46I.mjs +28 -0
  9. package/dist/lib/browser/blueprint-definition-ET5KZ46I.mjs.map +7 -0
  10. package/dist/lib/browser/chunk-5CYLWXRH.mjs +89 -0
  11. package/dist/lib/browser/chunk-5CYLWXRH.mjs.map +7 -0
  12. package/dist/lib/browser/chunk-75LH4EUR.mjs +326 -0
  13. package/dist/lib/browser/chunk-75LH4EUR.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-MWZDJNCQ.mjs → chunk-E7DXDICD.mjs} +27 -28
  15. package/dist/lib/browser/chunk-E7DXDICD.mjs.map +7 -0
  16. package/dist/lib/browser/{chunk-QYAREHGH.mjs → chunk-EZVXV6DA.mjs} +3 -5
  17. package/dist/lib/browser/chunk-EZVXV6DA.mjs.map +7 -0
  18. package/dist/lib/browser/{chunk-OULPWKXN.mjs → chunk-I3QSGUFJ.mjs} +157 -66
  19. package/dist/lib/browser/chunk-I3QSGUFJ.mjs.map +7 -0
  20. package/dist/lib/browser/{chunk-SUOLJH55.mjs → chunk-JO2O7W6J.mjs} +71 -50
  21. package/dist/lib/browser/chunk-JO2O7W6J.mjs.map +7 -0
  22. package/dist/lib/browser/chunk-N6M34EUC.mjs +112 -0
  23. package/dist/lib/browser/chunk-N6M34EUC.mjs.map +7 -0
  24. package/dist/lib/browser/{chunk-OAVS36Q3.mjs → chunk-NM4WQS4F.mjs} +14 -14
  25. package/dist/lib/browser/chunk-NM4WQS4F.mjs.map +7 -0
  26. package/dist/lib/browser/{chunk-5TVBECWH.mjs → chunk-OKXN2N7M.mjs} +2 -2
  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/{compiler-RIWQVBPX.mjs → compiler-G2N2CG63.mjs} +24 -11
  30. package/dist/lib/browser/{compiler-RIWQVBPX.mjs.map → compiler-G2N2CG63.mjs.map} +2 -2
  31. package/dist/lib/browser/index.mjs +113 -37
  32. package/dist/lib/browser/index.mjs.map +3 -3
  33. package/dist/lib/browser/{intent-resolver-SAL2TM7U.mjs → intent-resolver-JLU7DVLQ.mjs} +31 -15
  34. package/dist/lib/browser/intent-resolver-JLU7DVLQ.mjs.map +7 -0
  35. package/dist/lib/browser/meta.json +1 -1
  36. package/dist/lib/browser/{react-surface-E3SXU6ON.mjs → react-surface-76SDTUYG.mjs} +38 -15
  37. package/dist/lib/browser/react-surface-76SDTUYG.mjs.map +7 -0
  38. package/dist/lib/browser/{settings-KCTBK5TY.mjs → settings-ERFKVNUK.mjs} +9 -8
  39. package/dist/lib/browser/settings-ERFKVNUK.mjs.map +7 -0
  40. package/dist/lib/browser/templates/index.mjs +1 -1
  41. package/dist/lib/browser/types/index.mjs +7 -4
  42. package/dist/lib/node-esm/{DeploymentDialog-O2XZVRLU.mjs → DeploymentDialog-I63ZC2HH.mjs} +6 -5
  43. package/dist/lib/node-esm/NotebookContainer-QY5NJGJI.mjs +684 -0
  44. package/dist/lib/node-esm/NotebookContainer-QY5NJGJI.mjs.map +7 -0
  45. package/dist/lib/node-esm/ScriptContainer-SVXCSLNH.mjs +150 -0
  46. package/dist/lib/node-esm/ScriptContainer-SVXCSLNH.mjs.map +7 -0
  47. package/dist/lib/node-esm/{app-graph-builder-CQTTAYHP.mjs → app-graph-builder-UXJGHXSL.mjs} +8 -7
  48. package/dist/lib/node-esm/app-graph-builder-UXJGHXSL.mjs.map +7 -0
  49. package/dist/lib/node-esm/blueprint-definition-AIYFOT7Q.mjs +30 -0
  50. package/dist/lib/node-esm/blueprint-definition-AIYFOT7Q.mjs.map +7 -0
  51. package/dist/lib/node-esm/chunk-2GVTWESW.mjs +90 -0
  52. package/dist/lib/node-esm/chunk-2GVTWESW.mjs.map +7 -0
  53. package/dist/lib/node-esm/chunk-4X375PGY.mjs +90 -0
  54. package/dist/lib/node-esm/chunk-4X375PGY.mjs.map +7 -0
  55. package/dist/lib/node-esm/chunk-67OVZHI3.mjs +327 -0
  56. package/dist/lib/node-esm/chunk-67OVZHI3.mjs.map +7 -0
  57. package/dist/lib/node-esm/{chunk-IO6T72KY.mjs → chunk-C2ORIPKH.mjs} +14 -14
  58. package/dist/lib/node-esm/chunk-C2ORIPKH.mjs.map +7 -0
  59. package/dist/lib/node-esm/{chunk-35M3CHYE.mjs → chunk-NUXZQQ6P.mjs} +2 -2
  60. package/dist/lib/node-esm/{chunk-AHXJ6NQU.mjs → chunk-OG2SIKHE.mjs} +3 -5
  61. package/dist/lib/node-esm/chunk-OG2SIKHE.mjs.map +7 -0
  62. package/dist/lib/node-esm/{chunk-6WMFL3JL.mjs → chunk-SMFPSKQT.mjs} +157 -66
  63. package/dist/lib/node-esm/chunk-SMFPSKQT.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-VRSDE4CI.mjs +114 -0
  65. package/dist/lib/node-esm/chunk-VRSDE4CI.mjs.map +7 -0
  66. package/dist/lib/node-esm/{chunk-7L4JDSXJ.mjs → chunk-VZAFGLD7.mjs} +27 -28
  67. package/dist/lib/node-esm/chunk-VZAFGLD7.mjs.map +7 -0
  68. package/dist/lib/node-esm/{chunk-PACUN7RS.mjs → chunk-YW36TZ7K.mjs} +71 -50
  69. package/dist/lib/node-esm/chunk-YW36TZ7K.mjs.map +7 -0
  70. package/dist/lib/node-esm/{compiler-S52P5P3F.mjs → compiler-PLDAZ5GJ.mjs} +24 -11
  71. package/dist/lib/node-esm/{compiler-S52P5P3F.mjs.map → compiler-PLDAZ5GJ.mjs.map} +2 -2
  72. package/dist/lib/node-esm/index.mjs +113 -37
  73. package/dist/lib/node-esm/index.mjs.map +3 -3
  74. package/dist/lib/node-esm/{intent-resolver-GO53JOPL.mjs → intent-resolver-SFGTIFOG.mjs} +31 -15
  75. package/dist/lib/node-esm/intent-resolver-SFGTIFOG.mjs.map +7 -0
  76. package/dist/lib/node-esm/meta.json +1 -1
  77. package/dist/lib/node-esm/{react-surface-W3NRCS5O.mjs → react-surface-SHEBNW4R.mjs} +38 -15
  78. package/dist/lib/node-esm/react-surface-SHEBNW4R.mjs.map +7 -0
  79. package/dist/lib/node-esm/{settings-DXZ334A3.mjs → settings-5TYXQ42N.mjs} +9 -8
  80. package/dist/lib/node-esm/settings-5TYXQ42N.mjs.map +7 -0
  81. package/dist/lib/node-esm/templates/index.mjs +1 -1
  82. package/dist/lib/node-esm/types/index.mjs +7 -4
  83. package/dist/types/src/ScriptPlugin.d.ts +1 -1
  84. package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
  85. package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
  86. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  87. package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -0
  88. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  89. package/dist/types/src/capabilities/compiler.d.ts +1 -1
  90. package/dist/types/src/capabilities/index.d.ts +6 -5
  91. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  92. package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
  93. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  94. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  95. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  96. package/dist/types/src/capabilities/settings.d.ts +1 -1
  97. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts +2 -2
  98. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts.map +1 -1
  99. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts +246 -13
  100. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts.map +1 -1
  101. package/dist/types/src/components/FrameContainer/FrameContainer.d.ts.map +1 -1
  102. package/dist/types/src/components/NotebookContainer.d.ts +10 -0
  103. package/dist/types/src/components/NotebookContainer.d.ts.map +1 -0
  104. package/dist/types/src/components/NotebookContainer.stories.d.ts +248 -0
  105. package/dist/types/src/components/NotebookContainer.stories.d.ts.map +1 -0
  106. package/dist/types/src/components/NotebookStack/NotebookCell.d.ts +14 -0
  107. package/dist/types/src/components/NotebookStack/NotebookCell.d.ts.map +1 -0
  108. package/dist/types/src/components/NotebookStack/NotebookMenu.d.ts +9 -0
  109. package/dist/types/src/components/NotebookStack/NotebookMenu.d.ts.map +1 -0
  110. package/dist/types/src/components/NotebookStack/NotebookStack.d.ts +14 -0
  111. package/dist/types/src/components/NotebookStack/NotebookStack.d.ts.map +1 -0
  112. package/dist/types/src/components/NotebookStack/NotebookStack.stories.d.ts +248 -0
  113. package/dist/types/src/components/NotebookStack/NotebookStack.stories.d.ts.map +1 -0
  114. package/dist/types/src/components/NotebookStack/index.d.ts +3 -0
  115. package/dist/types/src/components/NotebookStack/index.d.ts.map +1 -0
  116. package/dist/types/src/components/ScriptContainer.d.ts +2 -2
  117. package/dist/types/src/components/ScriptContainer.d.ts.map +1 -1
  118. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -1
  119. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts +245 -10
  120. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts.map +1 -1
  121. package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts.map +1 -1
  122. package/dist/types/src/components/Settings/ScriptPluginSettings.d.ts +2 -2
  123. package/dist/types/src/components/Settings/ScriptPluginSettings.d.ts.map +1 -1
  124. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts +4 -2
  125. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -1
  126. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts +11 -4
  127. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts.map +1 -1
  128. package/dist/types/src/components/index.d.ts +3 -4
  129. package/dist/types/src/components/index.d.ts.map +1 -1
  130. package/dist/types/src/events.d.ts.map +1 -1
  131. package/dist/types/src/hooks/deploy.d.ts +12 -11
  132. package/dist/types/src/hooks/deploy.d.ts.map +1 -1
  133. package/dist/types/src/hooks/template.d.ts.map +1 -1
  134. package/dist/types/src/index.d.ts +1 -0
  135. package/dist/types/src/index.d.ts.map +1 -1
  136. package/dist/types/src/meta.d.ts +0 -1
  137. package/dist/types/src/meta.d.ts.map +1 -1
  138. package/dist/types/src/notebook/eval.d.ts +13 -0
  139. package/dist/types/src/notebook/eval.d.ts.map +1 -0
  140. package/dist/types/src/notebook/index.d.ts +2 -0
  141. package/dist/types/src/notebook/index.d.ts.map +1 -0
  142. package/dist/types/src/notebook/notebook.d.ts +35 -0
  143. package/dist/types/src/notebook/notebook.d.ts.map +1 -0
  144. package/dist/types/src/notebook/notebook.test.d.ts +2 -0
  145. package/dist/types/src/notebook/notebook.test.d.ts.map +1 -0
  146. package/dist/types/src/notebook/vfs-parser.d.ts +74 -0
  147. package/dist/types/src/notebook/vfs-parser.d.ts.map +1 -0
  148. package/dist/types/src/notebook/vfs-parser.test.d.ts +2 -0
  149. package/dist/types/src/notebook/vfs-parser.test.d.ts.map +1 -0
  150. package/dist/types/src/templates/chess.d.ts.map +1 -1
  151. package/dist/types/src/templates/data-generator.d.ts.map +1 -1
  152. package/dist/types/src/templates/discord.d.ts.map +1 -1
  153. package/dist/types/src/templates/forex-effect.d.ts.map +1 -1
  154. package/dist/types/src/templates/forex.d.ts.map +1 -1
  155. package/dist/types/src/templates/gmail.d.ts.map +1 -1
  156. package/dist/types/src/templates/index.d.ts +43 -1
  157. package/dist/types/src/templates/index.d.ts.map +1 -1
  158. package/dist/types/src/templates/{echo.d.ts → ping.d.ts} +1 -1
  159. package/dist/types/src/templates/ping.d.ts.map +1 -0
  160. package/dist/types/src/testing/data.d.ts +19 -0
  161. package/dist/types/src/testing/data.d.ts.map +1 -0
  162. package/dist/types/src/testing/index.d.ts +2 -0
  163. package/dist/types/src/testing/index.d.ts.map +1 -0
  164. package/dist/types/src/translations.d.ts +28 -2
  165. package/dist/types/src/translations.d.ts.map +1 -1
  166. package/dist/types/src/types/actions.d.ts +66 -0
  167. package/dist/types/src/types/actions.d.ts.map +1 -0
  168. package/dist/types/src/types/index.d.ts +1 -0
  169. package/dist/types/src/types/index.d.ts.map +1 -1
  170. package/dist/types/src/types/schema.d.ts +54 -31
  171. package/dist/types/src/types/schema.d.ts.map +1 -1
  172. package/dist/types/src/util/deploy.d.ts +3 -3
  173. package/dist/types/src/util/deploy.d.ts.map +1 -1
  174. package/dist/types/src/util/functions.d.ts +5 -2
  175. package/dist/types/src/util/functions.d.ts.map +1 -1
  176. package/dist/types/tsconfig.tsbuildinfo +1 -1
  177. package/package.json +72 -68
  178. package/src/ScriptPlugin.tsx +99 -64
  179. package/src/capabilities/app-graph-builder.ts +4 -3
  180. package/src/capabilities/artifact-definition.ts +1 -1
  181. package/src/capabilities/blueprint-definition.ts +30 -0
  182. package/src/capabilities/index.ts +1 -0
  183. package/src/capabilities/intent-resolver.ts +14 -4
  184. package/src/capabilities/react-surface.tsx +17 -5
  185. package/src/capabilities/settings.ts +3 -3
  186. package/src/components/DeploymentDialog/DeploymentDialog.stories.tsx +34 -20
  187. package/src/components/DeploymentDialog/DeploymentDialog.tsx +12 -18
  188. package/src/components/FrameContainer/FrameContainer.tsx +3 -2
  189. package/src/components/NotebookContainer.stories.tsx +32 -0
  190. package/src/components/NotebookContainer.tsx +124 -0
  191. package/src/components/NotebookStack/NotebookCell.tsx +217 -0
  192. package/src/components/NotebookStack/NotebookMenu.tsx +47 -0
  193. package/src/components/NotebookStack/NotebookStack.stories.tsx +32 -0
  194. package/src/components/NotebookStack/NotebookStack.tsx +79 -0
  195. package/src/components/NotebookStack/index.ts +6 -0
  196. package/src/components/ScriptContainer.tsx +2 -2
  197. package/src/components/ScriptToolbar/ScriptToolbar.stories.tsx +34 -18
  198. package/src/components/ScriptToolbar/ScriptToolbar.tsx +29 -22
  199. package/src/components/Settings/ScriptObjectSettings.tsx +109 -29
  200. package/src/components/Settings/ScriptPluginSettings.tsx +37 -47
  201. package/src/components/TestPanel/TestPanel.tsx +6 -6
  202. package/src/components/TypescriptEditor/TypescriptEditor.stories.tsx +74 -27
  203. package/src/components/TypescriptEditor/TypescriptEditor.tsx +30 -24
  204. package/src/components/index.ts +3 -0
  205. package/src/events.ts +2 -2
  206. package/src/hooks/deploy.ts +17 -18
  207. package/src/hooks/format.ts +2 -2
  208. package/src/hooks/template.ts +4 -3
  209. package/src/hooks/useCreateAndDeployScriptTemplates.ts +3 -3
  210. package/src/index.ts +1 -0
  211. package/src/meta.ts +2 -4
  212. package/src/notebook/eval.ts +105 -0
  213. package/src/notebook/index.ts +5 -0
  214. package/src/notebook/notebook.test.ts +70 -0
  215. package/src/notebook/notebook.ts +183 -0
  216. package/src/notebook/vfs-parser.test.ts +149 -0
  217. package/src/notebook/vfs-parser.ts +451 -0
  218. package/src/templates/chess.ts +2 -0
  219. package/src/templates/data-generator.ts +2 -0
  220. package/src/templates/discord.ts +11 -3
  221. package/src/templates/forex-effect.ts +6 -2
  222. package/src/templates/forex.ts +2 -0
  223. package/src/templates/gmail.ts +31 -60
  224. package/src/templates/index.ts +6 -6
  225. package/src/testing/data.ts +47 -0
  226. package/src/testing/index.ts +5 -0
  227. package/src/translations.ts +31 -4
  228. package/src/types/actions.ts +53 -0
  229. package/src/types/index.ts +1 -0
  230. package/src/types/schema.ts +30 -19
  231. package/src/util/deploy.ts +20 -33
  232. package/src/util/functions.ts +35 -6
  233. package/dist/lib/browser/DeploymentDialog-C3XH2Z56.mjs +0 -12
  234. package/dist/lib/browser/ScriptContainer-FUBR4OZE.mjs +0 -263
  235. package/dist/lib/browser/ScriptContainer-FUBR4OZE.mjs.map +0 -7
  236. package/dist/lib/browser/app-graph-builder-IABOSTBK.mjs.map +0 -7
  237. package/dist/lib/browser/chunk-G4A2MGAL.mjs +0 -88
  238. package/dist/lib/browser/chunk-G4A2MGAL.mjs.map +0 -7
  239. package/dist/lib/browser/chunk-IS4OG2UW.mjs +0 -39
  240. package/dist/lib/browser/chunk-IS4OG2UW.mjs.map +0 -7
  241. package/dist/lib/browser/chunk-MWZDJNCQ.mjs.map +0 -7
  242. package/dist/lib/browser/chunk-OAVS36Q3.mjs.map +0 -7
  243. package/dist/lib/browser/chunk-OULPWKXN.mjs.map +0 -7
  244. package/dist/lib/browser/chunk-QYAREHGH.mjs.map +0 -7
  245. package/dist/lib/browser/chunk-SUOLJH55.mjs.map +0 -7
  246. package/dist/lib/browser/intent-resolver-SAL2TM7U.mjs.map +0 -7
  247. package/dist/lib/browser/react-surface-E3SXU6ON.mjs.map +0 -7
  248. package/dist/lib/browser/settings-KCTBK5TY.mjs.map +0 -7
  249. package/dist/lib/node-esm/ScriptContainer-VJ75TM24.mjs +0 -264
  250. package/dist/lib/node-esm/ScriptContainer-VJ75TM24.mjs.map +0 -7
  251. package/dist/lib/node-esm/app-graph-builder-CQTTAYHP.mjs.map +0 -7
  252. package/dist/lib/node-esm/chunk-3BBEM2U7.mjs +0 -90
  253. package/dist/lib/node-esm/chunk-3BBEM2U7.mjs.map +0 -7
  254. package/dist/lib/node-esm/chunk-6WMFL3JL.mjs.map +0 -7
  255. package/dist/lib/node-esm/chunk-7L4JDSXJ.mjs.map +0 -7
  256. package/dist/lib/node-esm/chunk-AHXJ6NQU.mjs.map +0 -7
  257. package/dist/lib/node-esm/chunk-IO6T72KY.mjs.map +0 -7
  258. package/dist/lib/node-esm/chunk-JIPFLBYA.mjs +0 -40
  259. package/dist/lib/node-esm/chunk-JIPFLBYA.mjs.map +0 -7
  260. package/dist/lib/node-esm/chunk-PACUN7RS.mjs.map +0 -7
  261. package/dist/lib/node-esm/intent-resolver-GO53JOPL.mjs.map +0 -7
  262. package/dist/lib/node-esm/react-surface-W3NRCS5O.mjs.map +0 -7
  263. package/dist/lib/node-esm/settings-DXZ334A3.mjs.map +0 -7
  264. package/dist/types/src/templates/echo.d.ts.map +0 -1
  265. /package/dist/lib/browser/{DeploymentDialog-C3XH2Z56.mjs.map → DeploymentDialog-65TWT6S5.mjs.map} +0 -0
  266. /package/dist/lib/browser/{chunk-5TVBECWH.mjs.map → chunk-OKXN2N7M.mjs.map} +0 -0
  267. /package/dist/lib/node-esm/{DeploymentDialog-O2XZVRLU.mjs.map → DeploymentDialog-I63ZC2HH.mjs.map} +0 -0
  268. /package/dist/lib/node-esm/{chunk-35M3CHYE.mjs.map → chunk-NUXZQQ6P.mjs.map} +0 -0
  269. /package/src/templates/{echo.ts → ping.ts} +0 -0
@@ -0,0 +1,183 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Signal, signal } from '@preact/signals-core';
6
+
7
+ import { log } from '@dxos/log';
8
+
9
+ import { type Notebook } from '../types';
10
+
11
+ import { evalScript } from './eval';
12
+ import { type ParsedExpression, VirtualTypeScriptParser } from './vfs-parser';
13
+
14
+ /**
15
+ * Compute graph that evaluates the notebook cells.
16
+ */
17
+ export class ComputeGraph {
18
+ private readonly _parser = new VirtualTypeScriptParser();
19
+
20
+ private _expressions = signal<Record<string, ParsedExpression>>({});
21
+ private _values = signal<Record<string, any>>({});
22
+
23
+ constructor(private readonly _notebook: Notebook.Notebook) {}
24
+
25
+ /**
26
+ * Parsed expressions by cell ID.
27
+ */
28
+ get expressions(): Signal<Record<string, ParsedExpression>> {
29
+ return this._expressions;
30
+ }
31
+
32
+ /**
33
+ * Computed values by cell ID.
34
+ */
35
+ get values(): Signal<Record<string, any>> {
36
+ return this._values;
37
+ }
38
+
39
+ /**
40
+ * Compute values.
41
+ */
42
+ evaluate() {
43
+ // Parse expressions.
44
+ const { expressions, dependencyGraph } = this.parse();
45
+ this._values.value = {};
46
+
47
+ // Create a map of cell IDs to expressions for easy lookup.
48
+ const cellExpressions = new Map<string, ParsedExpression>();
49
+ Object.entries(expressions).forEach(([id, expr]) => {
50
+ cellExpressions.set(id, expr);
51
+ });
52
+
53
+ // Topological sort to determine evaluation order.
54
+ const evaluationOrder = this.topologicalSort(Object.keys(expressions), dependencyGraph);
55
+
56
+ // Values by reference name.
57
+ const valuesByName: Record<string, any> = {};
58
+ const valuesByCellId: Record<string, any> = {};
59
+
60
+ // Evaluate cells in dependency order.
61
+ for (const cellId of evaluationOrder) {
62
+ const expr = cellExpressions.get(cellId);
63
+ if (!expr) {
64
+ log.error('no expression for cell', { cellId });
65
+ continue;
66
+ }
67
+
68
+ const cellSource = this._notebook.cells.find((cell) => cell.id === cellId)?.script?.target?.content;
69
+ if (!cellSource) {
70
+ log.error('no source for cell', { cellId });
71
+ continue;
72
+ }
73
+
74
+ try {
75
+ // For assignments or declarations, evaluate and store the value.
76
+ if (expr.name && expr.value !== undefined) {
77
+ // If the parser extracted a literal value, use it directly.
78
+ valuesByName[expr.name] = expr.value;
79
+ valuesByCellId[cellId] = expr.value;
80
+ } else if (expr.name) {
81
+ // For non-literal assignments, we need to evaluate the expression.
82
+ // The parser identifies it's an assignment, so we can extract the RHS.
83
+ const equalIndex = cellSource.indexOf('=');
84
+ if (equalIndex !== -1) {
85
+ // Find the actual assignment operator (not in strings or other contexts).
86
+ let rhs = cellSource.substring(equalIndex + 1).trim();
87
+
88
+ // Handle semicolon at the end.
89
+ if (rhs.endsWith(';')) {
90
+ rhs = rhs.slice(0, -1).trim();
91
+ }
92
+
93
+ const result = evalScript(rhs, valuesByName);
94
+ valuesByName[expr.name] = result;
95
+ if (typeof result !== 'function') {
96
+ valuesByCellId[cellId] = result;
97
+ }
98
+ }
99
+ } else {
100
+ // For expressions without assignment, just evaluate.
101
+ const result = evalScript(cellSource, valuesByName);
102
+ valuesByCellId[cellId] = result;
103
+ }
104
+ } catch (error) {
105
+ log.error('error evaluating cell', { cellId, error });
106
+ }
107
+ }
108
+
109
+ this._values.value = valuesByCellId;
110
+ return valuesByCellId;
111
+ }
112
+
113
+ /**
114
+ * Parse expressions.
115
+ */
116
+ parse() {
117
+ const expressions = this._notebook.cells
118
+ .filter((cell) => cell.type === 'script')
119
+ .reduce<Record<string, ParsedExpression>>((acc, cell) => {
120
+ const text = cell.script?.target?.content.trim();
121
+ if (text) {
122
+ const parsed = this._parser.parseExpression(text);
123
+ acc[cell.id] = parsed;
124
+ }
125
+
126
+ return acc;
127
+ }, {});
128
+
129
+ // Build dependency graph.
130
+ const dependencyGraph = this.buildDependencyGraph(expressions);
131
+ this._expressions.value = expressions;
132
+ return { expressions, dependencyGraph };
133
+ }
134
+
135
+ private topologicalSort(nodes: string[], dependencies: Record<string, string[]>): string[] {
136
+ const visited = new Set<string>();
137
+ const result: string[] = [];
138
+
139
+ const visit = (node: string) => {
140
+ if (visited.has(node)) {
141
+ return;
142
+ }
143
+
144
+ visited.add(node);
145
+
146
+ // Visit dependencies first.
147
+ const deps = dependencies[node] || [];
148
+ deps.forEach((dep) => visit(dep));
149
+ result.push(node);
150
+ };
151
+
152
+ // Visit all nodes.
153
+ nodes.forEach((node) => visit(node));
154
+ return result;
155
+ }
156
+
157
+ private buildDependencyGraph(expressions: Record<string, ParsedExpression>): Record<string, string[]> {
158
+ // Create a map of variable names to their cell IDs.
159
+ const nameToCellId = new Map<string, string>();
160
+ Object.entries(expressions).forEach(([id, expr]) => {
161
+ if (expr.name) {
162
+ nameToCellId.set(expr.name, id);
163
+ }
164
+ });
165
+
166
+ // Build the dependency graph using cell IDs.
167
+ const graph: Record<string, string[]> = {};
168
+ Object.entries(expressions).forEach(([id, expr]) => {
169
+ if (expr.references && expr.references.length > 0) {
170
+ // Map variable references to cell IDs.
171
+ const dependencyCellIds = expr.references
172
+ .map((ref) => nameToCellId.get(ref))
173
+ .filter((cellId): cellId is string => cellId !== undefined && cellId !== id);
174
+
175
+ if (dependencyCellIds.length > 0) {
176
+ graph[id] = dependencyCellIds;
177
+ }
178
+ }
179
+ });
180
+
181
+ return graph;
182
+ }
183
+ }
@@ -0,0 +1,149 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, test } from 'vitest';
6
+
7
+ import { NotebookVirtualParser, VirtualTypeScriptParser } from './vfs-parser';
8
+
9
+ describe('vfs-parser', () => {
10
+ test('parse simple assignments', () => {
11
+ const parser = new VirtualTypeScriptParser();
12
+
13
+ const tests = [
14
+ {
15
+ input: 'const a = 1',
16
+ expected: {
17
+ name: 'a',
18
+ type: 'variable',
19
+ },
20
+ },
21
+ {
22
+ input: 'a = 1',
23
+ expected: {
24
+ name: 'a',
25
+ type: 'variable',
26
+ },
27
+ },
28
+ ];
29
+
30
+ tests.forEach(({ input, expected }) => {
31
+ const result = parser.parseExpression(input);
32
+ expect(result, input).toMatchObject(expected);
33
+ });
34
+ });
35
+
36
+ test('parse variable with references', () => {
37
+ const parser = new VirtualTypeScriptParser();
38
+
39
+ const tests = [
40
+ {
41
+ input: 'const y = x * 2',
42
+ expected: {
43
+ name: 'y',
44
+ type: 'variable',
45
+ references: ['x'],
46
+ },
47
+ },
48
+ {
49
+ input: 'y = x * 2',
50
+ expected: {
51
+ name: 'y',
52
+ type: 'variable',
53
+ references: ['x'],
54
+ },
55
+ },
56
+ ];
57
+
58
+ tests.forEach(({ input, expected }) => {
59
+ const result = parser.parseExpression(input);
60
+ expect(result, input).toMatchObject(expected);
61
+ });
62
+ });
63
+
64
+ test('parse simple expression with references', () => {
65
+ const parser = new VirtualTypeScriptParser();
66
+
67
+ const result = parser.parseExpression('(a + b) * c');
68
+ expect(result).toMatchObject({
69
+ references: ['a', 'b', 'c'],
70
+ });
71
+ });
72
+
73
+ test('parse single expression', () => {
74
+ const parser = new VirtualTypeScriptParser();
75
+
76
+ const result = parser.parseExpression('const add = (a: number, b: number): number => a + b;');
77
+ expect(result).toMatchObject({
78
+ name: 'add',
79
+ type: 'function',
80
+ valueType: expect.stringContaining('(a: number, b: number) => number'),
81
+ returnType: 'number',
82
+ parameters: [
83
+ { name: 'a', type: 'number' },
84
+ { name: 'b', type: 'number' },
85
+ ],
86
+ });
87
+ });
88
+
89
+ test('analyze multiple files', () => {
90
+ const parser = new VirtualTypeScriptParser();
91
+
92
+ const files = [
93
+ {
94
+ filename: '/test.ts',
95
+ content: 'export const PI = 3.14159;\nexport function square(x: number): number { return x * x; }',
96
+ },
97
+ ];
98
+
99
+ const results = parser.analyzeFiles(files);
100
+ expect(results).toHaveLength(2);
101
+ expect(results[0]).toMatchObject({
102
+ name: 'PI',
103
+ type: 'variable',
104
+ valueType: '3.14159',
105
+ });
106
+ expect(results[1]).toMatchObject({
107
+ name: 'square',
108
+ type: 'function',
109
+ returnType: 'number',
110
+ parameters: [{ name: 'x', type: 'number' }],
111
+ });
112
+ });
113
+
114
+ test('notebook cell analysis', () => {
115
+ const parser = new NotebookVirtualParser();
116
+
117
+ const cells = [
118
+ { id: 'cell1', code: 'const x: number = 10;' },
119
+ { id: 'cell2', code: 'const y = x * 2;' },
120
+ { id: 'cell3', code: 'console.log(y);' },
121
+ ];
122
+
123
+ const analysis = parser.analyzeNotebook(cells);
124
+
125
+ // Cell 1 exports x.
126
+ const cell1 = analysis.get('cell1');
127
+ expect(cell1?.exports).toHaveLength(1);
128
+ expect(cell1?.exports[0]).toMatchObject({
129
+ name: 'x',
130
+ type: 'variable',
131
+ valueType: 'number',
132
+ });
133
+ expect(cell1?.imports).toHaveLength(0);
134
+
135
+ // Cell 2 imports x and exports y.
136
+ const cell2 = analysis.get('cell2');
137
+ expect(cell2?.exports).toHaveLength(1);
138
+ expect(cell2?.exports[0]).toMatchObject({
139
+ name: 'y',
140
+ type: 'variable',
141
+ });
142
+ expect(cell2?.imports).toContain('x');
143
+
144
+ // Cell 3 imports y.
145
+ const cell3 = analysis.get('cell3');
146
+ expect(cell3?.exports).toHaveLength(0);
147
+ expect(cell3?.imports).toContain('y');
148
+ });
149
+ });