@dxos/app-framework 0.7.4 → 0.7.5-labs.071a3e2

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 (389) hide show
  1. package/dist/lib/browser/app-graph-builder-MOLT4EHG.mjs +137 -0
  2. package/dist/lib/browser/app-graph-builder-MOLT4EHG.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-G3HBVVT5.mjs +1403 -0
  4. package/dist/lib/browser/chunk-G3HBVVT5.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-LDJ3T4V3.mjs +32 -0
  6. package/dist/lib/browser/chunk-LDJ3T4V3.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-TGOF2WQZ.mjs +285 -0
  8. package/dist/lib/browser/chunk-TGOF2WQZ.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +135 -543
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/intent-dispatcher-LJKNIGAM.mjs +11 -0
  12. package/dist/lib/browser/intent-resolver-Z724VAMC.mjs +38 -0
  13. package/dist/lib/browser/intent-resolver-Z724VAMC.mjs.map +7 -0
  14. package/dist/lib/browser/meta.json +1 -1
  15. package/dist/lib/browser/store-NWCY7LAP.mjs +19 -0
  16. package/dist/lib/browser/store-NWCY7LAP.mjs.map +7 -0
  17. package/dist/lib/browser/testing/index.mjs +74 -0
  18. package/dist/lib/browser/testing/index.mjs.map +7 -0
  19. package/dist/lib/browser/worker.mjs +77 -0
  20. package/dist/lib/node/app-graph-builder-G7SRXDFD.cjs +146 -0
  21. package/dist/lib/node/app-graph-builder-G7SRXDFD.cjs.map +7 -0
  22. package/dist/lib/node/chunk-55KIQ6YK.cjs +1437 -0
  23. package/dist/lib/node/chunk-55KIQ6YK.cjs.map +7 -0
  24. package/dist/lib/node/chunk-5GABBW2Q.cjs +308 -0
  25. package/dist/lib/node/chunk-5GABBW2Q.cjs.map +7 -0
  26. package/dist/lib/node/chunk-QLVQ6PND.cjs +58 -0
  27. package/dist/lib/node/chunk-QLVQ6PND.cjs.map +7 -0
  28. package/dist/lib/node/index.cjs +136 -558
  29. package/dist/lib/node/index.cjs.map +4 -4
  30. package/dist/lib/node/{plugin-settings-OZ6IKAE5.cjs → intent-dispatcher-CGUK3BCJ.cjs} +10 -10
  31. package/dist/lib/node/intent-dispatcher-CGUK3BCJ.cjs.map +7 -0
  32. package/dist/lib/node/intent-resolver-7GNKPRWT.cjs +45 -0
  33. package/dist/lib/node/intent-resolver-7GNKPRWT.cjs.map +7 -0
  34. package/dist/lib/node/meta.json +1 -1
  35. package/dist/lib/node/store-WMJSEQPC.cjs +34 -0
  36. package/dist/lib/node/store-WMJSEQPC.cjs.map +7 -0
  37. package/dist/lib/node/testing/index.cjs +98 -0
  38. package/dist/lib/node/testing/index.cjs.map +7 -0
  39. package/dist/lib/node/worker.cjs +99 -0
  40. package/dist/lib/node/worker.cjs.map +7 -0
  41. package/dist/lib/node-esm/app-graph-builder-MKLYH3NE.mjs +138 -0
  42. package/dist/lib/node-esm/app-graph-builder-MKLYH3NE.mjs.map +7 -0
  43. package/dist/lib/node-esm/chunk-47FG42II.mjs +286 -0
  44. package/dist/lib/node-esm/chunk-47FG42II.mjs.map +7 -0
  45. package/dist/lib/node-esm/chunk-CNJYZNSL.mjs +34 -0
  46. package/dist/lib/node-esm/chunk-CNJYZNSL.mjs.map +7 -0
  47. package/dist/lib/node-esm/chunk-ZTB4TA6Q.mjs +1405 -0
  48. package/dist/lib/node-esm/chunk-ZTB4TA6Q.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +135 -543
  50. package/dist/lib/node-esm/index.mjs.map +4 -4
  51. package/dist/lib/node-esm/intent-dispatcher-RZAWA4XD.mjs +12 -0
  52. package/dist/lib/node-esm/intent-resolver-UIU37CKJ.mjs +39 -0
  53. package/dist/lib/node-esm/intent-resolver-UIU37CKJ.mjs.map +7 -0
  54. package/dist/lib/node-esm/meta.json +1 -1
  55. package/dist/lib/node-esm/store-YUWINFBN.mjs +20 -0
  56. package/dist/lib/node-esm/store-YUWINFBN.mjs.map +7 -0
  57. package/dist/lib/node-esm/testing/index.mjs +75 -0
  58. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  59. package/dist/lib/node-esm/worker.mjs +78 -0
  60. package/dist/types/src/App.d.ts +22 -13
  61. package/dist/types/src/App.d.ts.map +1 -1
  62. package/dist/types/src/common/capabilities.d.ts +296 -0
  63. package/dist/types/src/common/capabilities.d.ts.map +1 -0
  64. package/dist/types/src/common/events.d.ts +48 -0
  65. package/dist/types/src/common/events.d.ts.map +1 -0
  66. package/dist/types/src/common/file.d.ts +14 -0
  67. package/dist/types/src/common/file.d.ts.map +1 -0
  68. package/dist/types/src/common/graph.d.ts +21 -0
  69. package/dist/types/src/common/graph.d.ts.map +1 -0
  70. package/dist/types/src/common/index.d.ts +8 -0
  71. package/dist/types/src/common/index.d.ts.map +1 -0
  72. package/dist/types/src/common/layout.d.ts +248 -0
  73. package/dist/types/src/common/layout.d.ts.map +1 -0
  74. package/dist/types/src/common/surface.d.ts +68 -0
  75. package/dist/types/src/common/surface.d.ts.map +1 -0
  76. package/dist/types/src/common/translations.d.ts +11 -0
  77. package/dist/types/src/common/translations.d.ts.map +1 -0
  78. package/dist/types/src/core/capabilities.d.ts +94 -0
  79. package/dist/types/src/core/capabilities.d.ts.map +1 -0
  80. package/dist/types/src/core/capabilities.test.d.ts +2 -0
  81. package/dist/types/src/core/capabilities.test.d.ts.map +1 -0
  82. package/dist/types/src/core/events.d.ts +58 -0
  83. package/dist/types/src/core/events.d.ts.map +1 -0
  84. package/dist/types/src/core/index.d.ts +5 -0
  85. package/dist/types/src/core/index.d.ts.map +1 -0
  86. package/dist/types/src/core/manager.d.ts +119 -0
  87. package/dist/types/src/core/manager.d.ts.map +1 -0
  88. package/dist/types/src/core/manager.test.d.ts +2 -0
  89. package/dist/types/src/core/manager.test.d.ts.map +1 -0
  90. package/dist/types/src/core/plugin.d.ts +97 -0
  91. package/dist/types/src/core/plugin.d.ts.map +1 -0
  92. package/dist/types/src/helpers.d.ts +10 -0
  93. package/dist/types/src/helpers.d.ts.map +1 -0
  94. package/dist/types/src/helpers.test.d.ts +2 -0
  95. package/dist/types/src/helpers.test.d.ts.map +1 -0
  96. package/dist/types/src/index.d.ts +5 -1
  97. package/dist/types/src/index.d.ts.map +1 -1
  98. package/dist/types/src/playground/debug/Debug.d.ts +6 -0
  99. package/dist/types/src/playground/debug/Debug.d.ts.map +1 -0
  100. package/dist/types/src/playground/debug/index.d.ts +2 -0
  101. package/dist/types/src/playground/debug/index.d.ts.map +1 -0
  102. package/dist/types/src/playground/debug/plugin.d.ts +2 -0
  103. package/dist/types/src/playground/debug/plugin.d.ts.map +1 -0
  104. package/dist/types/src/playground/generator/Main.d.ts +6 -0
  105. package/dist/types/src/playground/generator/Main.d.ts.map +1 -0
  106. package/dist/types/src/playground/generator/Toolbar.d.ts +6 -0
  107. package/dist/types/src/playground/generator/Toolbar.d.ts.map +1 -0
  108. package/dist/types/src/playground/generator/generator.d.ts +7 -0
  109. package/dist/types/src/playground/generator/generator.d.ts.map +1 -0
  110. package/dist/types/src/playground/generator/index.d.ts +3 -0
  111. package/dist/types/src/playground/generator/index.d.ts.map +1 -0
  112. package/dist/types/src/playground/generator/plugin.d.ts +2 -0
  113. package/dist/types/src/playground/generator/plugin.d.ts.map +1 -0
  114. package/dist/types/src/playground/layout/Layout.d.ts +8 -0
  115. package/dist/types/src/playground/layout/Layout.d.ts.map +1 -0
  116. package/dist/types/src/playground/layout/index.d.ts +2 -0
  117. package/dist/types/src/playground/layout/index.d.ts.map +1 -0
  118. package/dist/types/src/playground/layout/plugin.d.ts +2 -0
  119. package/dist/types/src/playground/layout/plugin.d.ts.map +1 -0
  120. package/dist/types/src/playground/logger/Toolbar.d.ts +6 -0
  121. package/dist/types/src/playground/logger/Toolbar.d.ts.map +1 -0
  122. package/dist/types/src/playground/logger/index.d.ts +2 -0
  123. package/dist/types/src/playground/logger/index.d.ts.map +1 -0
  124. package/dist/types/src/playground/logger/plugin.d.ts +2 -0
  125. package/dist/types/src/playground/logger/plugin.d.ts.map +1 -0
  126. package/dist/types/src/playground/logger/schema.d.ts +13 -0
  127. package/dist/types/src/playground/logger/schema.d.ts.map +1 -0
  128. package/dist/types/src/playground/playground.stories.d.ts +10 -0
  129. package/dist/types/src/playground/playground.stories.d.ts.map +1 -0
  130. package/dist/types/src/plugin-intent/IntentPlugin.d.ts +2 -0
  131. package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +1 -0
  132. package/dist/types/src/plugin-intent/actions.d.ts +23 -0
  133. package/dist/types/src/plugin-intent/actions.d.ts.map +1 -0
  134. package/dist/types/src/plugin-intent/errors.d.ts +16 -0
  135. package/dist/types/src/plugin-intent/errors.d.ts.map +1 -0
  136. package/dist/types/src/plugin-intent/index.d.ts +5 -0
  137. package/dist/types/src/plugin-intent/index.d.ts.map +1 -0
  138. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +113 -0
  139. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -0
  140. package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts +2 -0
  141. package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts.map +1 -0
  142. package/dist/types/src/plugin-intent/intent.d.ts +68 -0
  143. package/dist/types/src/plugin-intent/intent.d.ts.map +1 -0
  144. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +2 -0
  145. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +1 -0
  146. package/dist/types/src/plugin-settings/actions.d.ts +27 -0
  147. package/dist/types/src/plugin-settings/actions.d.ts.map +1 -0
  148. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +197 -0
  149. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +1 -0
  150. package/dist/types/src/plugin-settings/index.d.ts +3 -0
  151. package/dist/types/src/plugin-settings/index.d.ts.map +1 -0
  152. package/dist/types/src/plugin-settings/intent-resolver.d.ts +4 -0
  153. package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +1 -0
  154. package/dist/types/src/plugin-settings/store.d.ts +5 -0
  155. package/dist/types/src/plugin-settings/store.d.ts.map +1 -0
  156. package/dist/types/src/plugin-settings/translations.d.ts +11 -0
  157. package/dist/types/src/plugin-settings/translations.d.ts.map +1 -0
  158. package/dist/types/src/react/ErrorBoundary.d.ts.map +1 -0
  159. package/dist/types/src/react/IntentContext.d.ts +8 -0
  160. package/dist/types/src/react/IntentContext.d.ts.map +1 -0
  161. package/dist/types/src/react/PluginManagerProvider.d.ts +10 -0
  162. package/dist/types/src/react/PluginManagerProvider.d.ts.map +1 -0
  163. package/dist/types/src/react/Surface.d.ts +12 -0
  164. package/dist/types/src/react/Surface.d.ts.map +1 -0
  165. package/dist/types/src/react/Surface.stories.d.ts +16 -0
  166. package/dist/types/src/react/Surface.stories.d.ts.map +1 -0
  167. package/dist/types/src/react/common.d.ts +12 -0
  168. package/dist/types/src/react/common.d.ts.map +1 -0
  169. package/dist/types/src/react/index.d.ts +7 -0
  170. package/dist/types/src/react/index.d.ts.map +1 -0
  171. package/dist/types/src/react/useCapabilities.d.ts +13 -0
  172. package/dist/types/src/react/useCapabilities.d.ts.map +1 -0
  173. package/dist/types/src/react/useIntentResolver.d.ts +3 -0
  174. package/dist/types/src/react/useIntentResolver.d.ts.map +1 -0
  175. package/dist/types/src/testing/index.d.ts +2 -0
  176. package/dist/types/src/testing/index.d.ts.map +1 -0
  177. package/dist/types/src/testing/withPluginManager.d.ts +10 -0
  178. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -0
  179. package/dist/types/src/testing/withPluginManager.stories.d.ts +5 -0
  180. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -0
  181. package/dist/types/src/worker.d.ts +4 -0
  182. package/dist/types/src/worker.d.ts.map +1 -0
  183. package/dist/types/tsconfig.tsbuildinfo +1 -0
  184. package/package.json +39 -17
  185. package/project.json +4 -3
  186. package/src/App.tsx +139 -34
  187. package/src/common/capabilities.ts +97 -0
  188. package/src/common/events.ts +72 -0
  189. package/src/common/file.ts +22 -0
  190. package/src/common/graph.ts +30 -0
  191. package/src/{plugins/common → common}/index.ts +3 -2
  192. package/src/common/layout.ts +225 -0
  193. package/src/common/surface.ts +81 -0
  194. package/src/common/translations.ts +17 -0
  195. package/src/core/capabilities.test.ts +116 -0
  196. package/src/core/capabilities.ts +222 -0
  197. package/src/core/events.ts +58 -0
  198. package/src/core/index.ts +8 -0
  199. package/src/core/manager.test.ts +516 -0
  200. package/src/core/manager.ts +511 -0
  201. package/src/core/plugin.ts +131 -0
  202. package/src/helpers.test.ts +97 -0
  203. package/src/helpers.ts +45 -0
  204. package/src/index.ts +6 -3
  205. package/src/playground/debug/Debug.tsx +39 -0
  206. package/src/playground/debug/index.ts +5 -0
  207. package/src/playground/debug/plugin.ts +17 -0
  208. package/src/playground/generator/Main.tsx +71 -0
  209. package/src/playground/generator/Toolbar.tsx +46 -0
  210. package/src/playground/generator/generator.ts +48 -0
  211. package/src/playground/generator/index.ts +6 -0
  212. package/src/playground/generator/plugin.ts +23 -0
  213. package/src/playground/layout/Layout.tsx +33 -0
  214. package/src/playground/layout/index.ts +5 -0
  215. package/src/playground/layout/plugin.ts +17 -0
  216. package/src/playground/logger/Toolbar.tsx +29 -0
  217. package/src/playground/logger/index.ts +5 -0
  218. package/src/playground/logger/plugin.ts +36 -0
  219. package/src/playground/logger/schema.ts +12 -0
  220. package/src/playground/playground.stories.tsx +34 -0
  221. package/src/plugin-intent/IntentPlugin.tsx +20 -0
  222. package/src/plugin-intent/actions.ts +22 -0
  223. package/src/plugin-intent/errors.ts +39 -0
  224. package/src/plugin-intent/index.ts +8 -0
  225. package/src/plugin-intent/intent-dispatcher.test.ts +299 -0
  226. package/src/plugin-intent/intent-dispatcher.ts +304 -0
  227. package/src/plugin-intent/intent.ts +146 -0
  228. package/src/plugin-settings/SettingsPlugin.ts +35 -0
  229. package/src/plugin-settings/actions.ts +27 -0
  230. package/src/plugin-settings/app-graph-builder.ts +122 -0
  231. package/src/plugin-settings/index.ts +6 -0
  232. package/src/plugin-settings/intent-resolver.ts +28 -0
  233. package/src/plugin-settings/store.ts +20 -0
  234. package/src/plugin-settings/translations.ts +17 -0
  235. package/src/react/IntentContext.tsx +34 -0
  236. package/src/react/PluginManagerProvider.ts +22 -0
  237. package/src/react/Surface.stories.tsx +96 -0
  238. package/src/react/Surface.tsx +75 -0
  239. package/src/react/common.ts +12 -0
  240. package/src/react/index.ts +10 -0
  241. package/src/react/useCapabilities.ts +40 -0
  242. package/src/react/useIntentResolver.ts +22 -0
  243. package/src/testing/index.ts +5 -0
  244. package/src/testing/withPluginManager.stories.tsx +47 -0
  245. package/src/testing/withPluginManager.tsx +75 -0
  246. package/src/worker.ts +11 -0
  247. package/tsconfig.json +54 -2
  248. package/dist/lib/browser/chunk-3E7RY3CE.mjs +0 -72
  249. package/dist/lib/browser/chunk-3E7RY3CE.mjs.map +0 -7
  250. package/dist/lib/browser/chunk-653Y45CL.mjs +0 -41
  251. package/dist/lib/browser/chunk-653Y45CL.mjs.map +0 -7
  252. package/dist/lib/browser/chunk-FRXJ25VI.mjs +0 -214
  253. package/dist/lib/browser/chunk-FRXJ25VI.mjs.map +0 -7
  254. package/dist/lib/browser/chunk-YXM35XRE.mjs +0 -213
  255. package/dist/lib/browser/chunk-YXM35XRE.mjs.map +0 -7
  256. package/dist/lib/browser/plugin-intent-LU4KL2RO.mjs +0 -22
  257. package/dist/lib/browser/plugin-settings-OM3G2QFY.mjs +0 -11
  258. package/dist/lib/browser/plugin-surface-LECZMKSQ.mjs +0 -24
  259. package/dist/lib/node/chunk-JZ2JVKRY.cjs +0 -58
  260. package/dist/lib/node/chunk-JZ2JVKRY.cjs.map +0 -7
  261. package/dist/lib/node/chunk-QBM42OQ6.cjs +0 -97
  262. package/dist/lib/node/chunk-QBM42OQ6.cjs.map +0 -7
  263. package/dist/lib/node/chunk-QSVP5HOW.cjs +0 -238
  264. package/dist/lib/node/chunk-QSVP5HOW.cjs.map +0 -7
  265. package/dist/lib/node/chunk-SOVLKUWI.cjs +0 -236
  266. package/dist/lib/node/chunk-SOVLKUWI.cjs.map +0 -7
  267. package/dist/lib/node/plugin-intent-FVFR2LKB.cjs +0 -43
  268. package/dist/lib/node/plugin-intent-FVFR2LKB.cjs.map +0 -7
  269. package/dist/lib/node/plugin-settings-OZ6IKAE5.cjs.map +0 -7
  270. package/dist/lib/node/plugin-surface-YWDRXQTD.cjs +0 -45
  271. package/dist/lib/node/plugin-surface-YWDRXQTD.cjs.map +0 -7
  272. package/dist/lib/node-esm/chunk-2R4GVK7O.mjs +0 -215
  273. package/dist/lib/node-esm/chunk-2R4GVK7O.mjs.map +0 -7
  274. package/dist/lib/node-esm/chunk-EYCTSFEJ.mjs +0 -74
  275. package/dist/lib/node-esm/chunk-EYCTSFEJ.mjs.map +0 -7
  276. package/dist/lib/node-esm/chunk-YFMFQBB4.mjs +0 -214
  277. package/dist/lib/node-esm/chunk-YFMFQBB4.mjs.map +0 -7
  278. package/dist/lib/node-esm/chunk-YNU7FTGJ.mjs +0 -43
  279. package/dist/lib/node-esm/chunk-YNU7FTGJ.mjs.map +0 -7
  280. package/dist/lib/node-esm/plugin-intent-V7ER24Y6.mjs +0 -23
  281. package/dist/lib/node-esm/plugin-settings-37UVWF2V.mjs +0 -12
  282. package/dist/lib/node-esm/plugin-settings-37UVWF2V.mjs.map +0 -7
  283. package/dist/lib/node-esm/plugin-surface-TEU42XQN.mjs +0 -25
  284. package/dist/lib/node-esm/plugin-surface-TEU42XQN.mjs.map +0 -7
  285. package/dist/types/src/plugins/common/file.d.ts +0 -22
  286. package/dist/types/src/plugins/common/file.d.ts.map +0 -1
  287. package/dist/types/src/plugins/common/graph.d.ts +0 -51
  288. package/dist/types/src/plugins/common/graph.d.ts.map +0 -1
  289. package/dist/types/src/plugins/common/index.d.ts +0 -7
  290. package/dist/types/src/plugins/common/index.d.ts.map +0 -1
  291. package/dist/types/src/plugins/common/layout.d.ts +0 -202
  292. package/dist/types/src/plugins/common/layout.d.ts.map +0 -1
  293. package/dist/types/src/plugins/common/metadata.d.ts +0 -16
  294. package/dist/types/src/plugins/common/metadata.d.ts.map +0 -1
  295. package/dist/types/src/plugins/common/navigation.d.ts +0 -196
  296. package/dist/types/src/plugins/common/navigation.d.ts.map +0 -1
  297. package/dist/types/src/plugins/common/translations.d.ts +0 -22
  298. package/dist/types/src/plugins/common/translations.d.ts.map +0 -1
  299. package/dist/types/src/plugins/helpers.d.ts +0 -41
  300. package/dist/types/src/plugins/helpers.d.ts.map +0 -1
  301. package/dist/types/src/plugins/index.d.ts +0 -7
  302. package/dist/types/src/plugins/index.d.ts.map +0 -1
  303. package/dist/types/src/plugins/plugin-host/HostPlugin.d.ts +0 -21
  304. package/dist/types/src/plugins/plugin-host/HostPlugin.d.ts.map +0 -1
  305. package/dist/types/src/plugins/plugin-host/PluginContainer.d.ts +0 -14
  306. package/dist/types/src/plugins/plugin-host/PluginContainer.d.ts.map +0 -1
  307. package/dist/types/src/plugins/plugin-host/PluginContext.d.ts +0 -47
  308. package/dist/types/src/plugins/plugin-host/PluginContext.d.ts.map +0 -1
  309. package/dist/types/src/plugins/plugin-host/index.d.ts +0 -4
  310. package/dist/types/src/plugins/plugin-host/index.d.ts.map +0 -1
  311. package/dist/types/src/plugins/plugin-host/plugin.d.ts +0 -98
  312. package/dist/types/src/plugins/plugin-host/plugin.d.ts.map +0 -1
  313. package/dist/types/src/plugins/plugin-host/plugin.test.d.ts +0 -35
  314. package/dist/types/src/plugins/plugin-host/plugin.test.d.ts.map +0 -1
  315. package/dist/types/src/plugins/plugin-intent/IntentContext.d.ts +0 -21
  316. package/dist/types/src/plugins/plugin-intent/IntentContext.d.ts.map +0 -1
  317. package/dist/types/src/plugins/plugin-intent/IntentPlugin.d.ts +0 -8
  318. package/dist/types/src/plugins/plugin-intent/IntentPlugin.d.ts.map +0 -1
  319. package/dist/types/src/plugins/plugin-intent/helpers.d.ts +0 -6
  320. package/dist/types/src/plugins/plugin-intent/helpers.d.ts.map +0 -1
  321. package/dist/types/src/plugins/plugin-intent/index.d.ts +0 -6
  322. package/dist/types/src/plugins/plugin-intent/index.d.ts.map +0 -1
  323. package/dist/types/src/plugins/plugin-intent/intent.d.ts +0 -81
  324. package/dist/types/src/plugins/plugin-intent/intent.d.ts.map +0 -1
  325. package/dist/types/src/plugins/plugin-intent/meta.d.ts +0 -5
  326. package/dist/types/src/plugins/plugin-intent/meta.d.ts.map +0 -1
  327. package/dist/types/src/plugins/plugin-intent/provides.d.ts +0 -20
  328. package/dist/types/src/plugins/plugin-intent/provides.d.ts.map +0 -1
  329. package/dist/types/src/plugins/plugin-settings/SettingsPlugin.d.ts +0 -4
  330. package/dist/types/src/plugins/plugin-settings/SettingsPlugin.d.ts.map +0 -1
  331. package/dist/types/src/plugins/plugin-settings/index.d.ts +0 -4
  332. package/dist/types/src/plugins/plugin-settings/index.d.ts.map +0 -1
  333. package/dist/types/src/plugins/plugin-settings/meta.d.ts +0 -5
  334. package/dist/types/src/plugins/plugin-settings/meta.d.ts.map +0 -1
  335. package/dist/types/src/plugins/plugin-settings/provides.d.ts +0 -13
  336. package/dist/types/src/plugins/plugin-settings/provides.d.ts.map +0 -1
  337. package/dist/types/src/plugins/plugin-surface/ErrorBoundary.d.ts.map +0 -1
  338. package/dist/types/src/plugins/plugin-surface/Surface.d.ts +0 -62
  339. package/dist/types/src/plugins/plugin-surface/Surface.d.ts.map +0 -1
  340. package/dist/types/src/plugins/plugin-surface/SurfacePlugin.d.ts +0 -7
  341. package/dist/types/src/plugins/plugin-surface/SurfacePlugin.d.ts.map +0 -1
  342. package/dist/types/src/plugins/plugin-surface/SurfaceRootContext.d.ts +0 -39
  343. package/dist/types/src/plugins/plugin-surface/SurfaceRootContext.d.ts.map +0 -1
  344. package/dist/types/src/plugins/plugin-surface/helpers.d.ts +0 -21
  345. package/dist/types/src/plugins/plugin-surface/helpers.d.ts.map +0 -1
  346. package/dist/types/src/plugins/plugin-surface/index.d.ts +0 -8
  347. package/dist/types/src/plugins/plugin-surface/index.d.ts.map +0 -1
  348. package/dist/types/src/plugins/plugin-surface/meta.d.ts +0 -5
  349. package/dist/types/src/plugins/plugin-surface/meta.d.ts.map +0 -1
  350. package/dist/types/src/plugins/plugin-surface/provides.d.ts +0 -16
  351. package/dist/types/src/plugins/plugin-surface/provides.d.ts.map +0 -1
  352. package/src/plugins/common/file.ts +0 -36
  353. package/src/plugins/common/graph.ts +0 -70
  354. package/src/plugins/common/layout.ts +0 -155
  355. package/src/plugins/common/metadata.ts +0 -29
  356. package/src/plugins/common/navigation.ts +0 -185
  357. package/src/plugins/common/translations.ts +0 -36
  358. package/src/plugins/helpers.ts +0 -92
  359. package/src/plugins/index.ts +0 -11
  360. package/src/plugins/plugin-host/HostPlugin.tsx +0 -96
  361. package/src/plugins/plugin-host/PluginContainer.tsx +0 -120
  362. package/src/plugins/plugin-host/PluginContext.tsx +0 -79
  363. package/src/plugins/plugin-host/index.ts +0 -8
  364. package/src/plugins/plugin-host/plugin.test.ts +0 -158
  365. package/src/plugins/plugin-host/plugin.ts +0 -126
  366. package/src/plugins/plugin-intent/IntentContext.tsx +0 -49
  367. package/src/plugins/plugin-intent/IntentPlugin.tsx +0 -151
  368. package/src/plugins/plugin-intent/helpers.ts +0 -11
  369. package/src/plugins/plugin-intent/index.ts +0 -12
  370. package/src/plugins/plugin-intent/intent.ts +0 -101
  371. package/src/plugins/plugin-intent/meta.ts +0 -9
  372. package/src/plugins/plugin-intent/provides.ts +0 -38
  373. package/src/plugins/plugin-settings/SettingsPlugin.tsx +0 -22
  374. package/src/plugins/plugin-settings/index.ts +0 -9
  375. package/src/plugins/plugin-settings/meta.ts +0 -9
  376. package/src/plugins/plugin-settings/provides.ts +0 -29
  377. package/src/plugins/plugin-surface/Surface.tsx +0 -195
  378. package/src/plugins/plugin-surface/SurfacePlugin.tsx +0 -33
  379. package/src/plugins/plugin-surface/SurfaceRootContext.tsx +0 -60
  380. package/src/plugins/plugin-surface/helpers.ts +0 -22
  381. package/src/plugins/plugin-surface/index.ts +0 -14
  382. package/src/plugins/plugin-surface/meta.ts +0 -9
  383. package/src/plugins/plugin-surface/provides.ts +0 -26
  384. /package/dist/lib/browser/{plugin-intent-LU4KL2RO.mjs.map → intent-dispatcher-LJKNIGAM.mjs.map} +0 -0
  385. /package/dist/lib/browser/{plugin-settings-OM3G2QFY.mjs.map → worker.mjs.map} +0 -0
  386. /package/dist/lib/{browser/plugin-surface-LECZMKSQ.mjs.map → node-esm/intent-dispatcher-RZAWA4XD.mjs.map} +0 -0
  387. /package/dist/lib/node-esm/{plugin-intent-V7ER24Y6.mjs.map → worker.mjs.map} +0 -0
  388. /package/dist/types/src/{plugins/plugin-surface → react}/ErrorBoundary.d.ts +0 -0
  389. /package/src/{plugins/plugin-surface → react}/ErrorBoundary.tsx +0 -0
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // TODO(wittjosiah): Reconcile with @dxos/protocols. Factor out errors.
6
+
7
+ /**
8
+ * NOTE: Messages should be sentences (Start with a capital letter and end with a period).
9
+ * Errors can optionally include a JSON context object.
10
+ */
11
+ export class BaseError extends Error {
12
+ constructor(
13
+ readonly code: string,
14
+ message?: string,
15
+ readonly context?: Record<string, any>,
16
+ ) {
17
+ // TODO(dmaretskyi): Error.cause.
18
+ super(message ?? code, { cause: context });
19
+ this.name = code;
20
+ // NOTE: Restores prototype chain (https://stackoverflow.com/a/48342359).
21
+ Object.setPrototypeOf(this, new.target.prototype);
22
+ }
23
+ }
24
+
25
+ export class NoResolversError extends BaseError {
26
+ constructor(action: string) {
27
+ super('NO_RESOLVERS', 'No resolvers were found for the action', { action });
28
+ }
29
+ }
30
+
31
+ export class CycleDetectedError extends BaseError {
32
+ constructor(context?: Record<string, any>) {
33
+ super(
34
+ 'CYCLE_DETECTED',
35
+ 'Intent execution limit exceeded. This is likely due to an infinite loop within intent resolvers.',
36
+ context,
37
+ );
38
+ }
39
+ }
@@ -0,0 +1,8 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ export * from './actions';
6
+ export * from './intent';
7
+ export * from './intent-dispatcher';
8
+ export * from './IntentPlugin';
@@ -0,0 +1,299 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { Schema as S } from '@effect/schema';
6
+ import { Effect, Fiber, pipe } from 'effect';
7
+ import { describe, expect, test } from 'vitest';
8
+
9
+ import { chain, createIntent } from './intent';
10
+ import { type AnyIntentResolver, createDispatcher, createResolver } from './intent-dispatcher';
11
+
12
+ describe('Intent dispatcher', () => {
13
+ test('throws error if no resolver found', async () => {
14
+ const { dispatchPromise } = createDispatcher(() => []);
15
+ const { data, error } = await dispatchPromise(createIntent(ToString, { value: 1 }));
16
+
17
+ expect(data).toBe(undefined);
18
+ expect(error).toBeInstanceOf(Error);
19
+ });
20
+
21
+ test('matches intent to resolver and executes', async () => {
22
+ const { dispatchPromise } = createDispatcher(() => [toStringResolver]);
23
+ const { data, error } = await dispatchPromise(createIntent(ToString, { value: 1 }));
24
+
25
+ expect(error).toBe(undefined);
26
+ expect(data?.string).toBe('1');
27
+ });
28
+
29
+ test('update resolvers', async () => {
30
+ const resolvers: AnyIntentResolver[] = [];
31
+ const { dispatchPromise } = createDispatcher(() => resolvers);
32
+ const { error } = await dispatchPromise(createIntent(ToString, { value: 1 }));
33
+
34
+ expect(error).toBeInstanceOf(Error);
35
+
36
+ resolvers.push(toStringResolver);
37
+
38
+ const { data } = await dispatchPromise(createIntent(ToString, { value: 1 }));
39
+
40
+ expect(data?.string).toBe('1');
41
+
42
+ resolvers.splice(resolvers.indexOf(toStringResolver), 1);
43
+
44
+ {
45
+ const { data, error } = await dispatchPromise(createIntent(ToString, { value: 1 }));
46
+
47
+ expect(data).toBe(undefined);
48
+ expect(error).toBeInstanceOf(Error);
49
+ }
50
+ });
51
+
52
+ test('compose intent effects', async () => {
53
+ const { dispatch } = createDispatcher(() => [computeResolver]);
54
+ const program = Effect.gen(function* () {
55
+ const a = yield* dispatch(createIntent(Compute, { value: 1 }));
56
+ const b = yield* dispatch(createIntent(Compute, { value: 2 }));
57
+ return b.value - a.value;
58
+ });
59
+
60
+ expect(await Effect.runPromise(program)).toBe(2);
61
+ });
62
+
63
+ test('concurrent intent effects', async () => {
64
+ const { dispatch } = createDispatcher(() => [computeResolver]);
65
+ const program = Effect.gen(function* () {
66
+ const fiberA = yield* Effect.fork(dispatch(createIntent(Compute, { value: 5 })));
67
+ const fiberB = yield* Effect.fork(dispatch(createIntent(Compute, { value: 2 })));
68
+ const [a, b] = yield* Fiber.join(Fiber.zip(fiberA, fiberB));
69
+ return b.value - a.value;
70
+ });
71
+
72
+ expect(await Effect.runPromise(program)).toBe(-6);
73
+ });
74
+
75
+ test('mix & match intent effects with promises', async () => {
76
+ const { dispatch, dispatchPromise } = createDispatcher(() => [toStringResolver, computeResolver]);
77
+ const program = Effect.gen(function* () {
78
+ const a = yield* dispatch(createIntent(Compute, { value: 2 }));
79
+ const b = yield* dispatch(createIntent(ToString, { value: a.value }));
80
+ return b.string;
81
+ });
82
+
83
+ expect(await Effect.runPromise(program)).toBe('4');
84
+
85
+ const a = await dispatchPromise(createIntent(Compute, { value: 2 }));
86
+ const b = await dispatchPromise(createIntent(ToString, { value: a.data!.value }));
87
+
88
+ expect(b.data?.string).toBe('4');
89
+ });
90
+
91
+ test('undo intent', async () => {
92
+ const { dispatch, undo } = createDispatcher(() => [computeResolver]);
93
+ const program = Effect.gen(function* () {
94
+ const a = yield* dispatch(createIntent(Compute, { value: 2 }));
95
+
96
+ expect(a.value).toBe(4);
97
+
98
+ const b = yield* undo();
99
+
100
+ expect(b.value).toBe(2);
101
+ });
102
+
103
+ await Effect.runPromise(program);
104
+ });
105
+
106
+ test('chain intents', async () => {
107
+ const { dispatch } = createDispatcher(() => [computeResolver, toStringResolver, concatResolver]);
108
+ const intent = pipe(createIntent(Compute, { value: 1 }), chain(ToString, {}), chain(Concat, { plus: '!' }));
109
+
110
+ expect(intent.first.id).toBe(Compute._tag);
111
+ expect(intent.last.id).toBe(Concat._tag);
112
+ expect(intent.all.length).toBe(3);
113
+
114
+ const program = Effect.gen(function* () {
115
+ const data = yield* dispatch(intent);
116
+ return data.string;
117
+ });
118
+
119
+ expect(await Effect.runPromise(program)).toBe('2!');
120
+ });
121
+
122
+ test('undo chained intent', async () => {
123
+ const { dispatch, undo } = createDispatcher(() => [computeResolver, toStringResolver, concatResolver]);
124
+ const intent = pipe(createIntent(Compute, { value: 1 }), chain(Compute, {}), chain(Compute, {}));
125
+ const program = Effect.gen(function* () {
126
+ const a = yield* dispatch(intent);
127
+
128
+ expect(a.value).toBe(8);
129
+
130
+ const b = yield* undo();
131
+
132
+ expect(b.value).toBe(1);
133
+ });
134
+
135
+ await Effect.runPromise(program);
136
+ });
137
+
138
+ test('filter resolvers by plugin', async () => {
139
+ const otherComputeResolver = createResolver({
140
+ intent: Compute,
141
+ resolve: async (data) => ({ data: { value: data?.value * 3 } }),
142
+ });
143
+ const { dispatch } = createDispatcher((module) => (module === 'test' ? [computeResolver] : [otherComputeResolver]));
144
+ const program = Effect.gen(function* () {
145
+ const a = yield* dispatch(createIntent(Compute, { value: 1 }));
146
+
147
+ expect(a.value).toBe(3);
148
+
149
+ const b = yield* dispatch(createIntent(Compute, { value: 1 }, { module: 'test' }));
150
+
151
+ expect(b.value).toBe(2);
152
+ });
153
+
154
+ await Effect.runPromise(program);
155
+ });
156
+
157
+ test('filter resolvers by predicate', async () => {
158
+ const conditionalComputeResolver = createResolver({
159
+ intent: Compute,
160
+ filter: (data): data is { value: number } => data?.value > 1,
161
+ resolve: async (data) => ({ data: { value: data?.value * 3 } }),
162
+ });
163
+ const { dispatch } = createDispatcher(() => [conditionalComputeResolver, computeResolver]);
164
+ const program = Effect.gen(function* () {
165
+ const a = yield* dispatch(createIntent(Compute, { value: 1 }));
166
+
167
+ expect(a.value).toBe(2);
168
+
169
+ const b = yield* dispatch(createIntent(Compute, { value: 2 }));
170
+
171
+ expect(b.value).toBe(6);
172
+ });
173
+
174
+ await Effect.runPromise(program);
175
+ });
176
+
177
+ test('hoist resolvers', async () => {
178
+ const hoistedComputeResolver = createResolver({
179
+ intent: Compute,
180
+ position: 'hoist',
181
+ resolve: async (data) => ({ data: { value: data?.value * 3 } }),
182
+ });
183
+ const { dispatchPromise } = createDispatcher(() => [computeResolver, hoistedComputeResolver]);
184
+ const { data } = await dispatchPromise(createIntent(Compute, { value: 1 }));
185
+ expect(data?.value).toBe(3);
186
+ });
187
+
188
+ test('fallback resolvers', async () => {
189
+ const conditionalComputeResolver = createResolver({
190
+ intent: Compute,
191
+ filter: (data): data is { value: number } => data?.value === 1,
192
+ resolve: async (data) => ({ data: { value: data?.value * 2 } }),
193
+ });
194
+ const fallbackComputeResolver = createResolver({
195
+ intent: Compute,
196
+ position: 'fallback',
197
+ resolve: async (data) => ({ data: { value: data?.value * 3 } }),
198
+ });
199
+ const { dispatch } = createDispatcher(() => [conditionalComputeResolver, fallbackComputeResolver]);
200
+ const program = Effect.gen(function* () {
201
+ const a = yield* dispatch(createIntent(Compute, { value: 1 }));
202
+
203
+ expect(a.value).toBe(2);
204
+
205
+ const b = yield* dispatch(createIntent(Compute, { value: 2 }));
206
+
207
+ expect(b.value).toBe(6);
208
+ });
209
+
210
+ await Effect.runPromise(program);
211
+ });
212
+
213
+ test('non-struct inputs & outputs', async () => {
214
+ const { dispatchPromise } = createDispatcher(() => [addResolver]);
215
+ const { data } = await dispatchPromise(createIntent(Add, [1, 1]));
216
+ expect(data).toBe(2);
217
+ });
218
+
219
+ test('empty inputs & outputs', async () => {
220
+ const { dispatchPromise } = createDispatcher(() => [sideEffectResolver]);
221
+ const { data } = await dispatchPromise(createIntent(SideEffect));
222
+ expect(data).toBe(undefined);
223
+ });
224
+
225
+ test.todo('follow up intents');
226
+ });
227
+
228
+ class ToString extends S.TaggedClass<ToString>()('ToString', {
229
+ input: S.Struct({
230
+ value: S.Number,
231
+ }),
232
+ output: S.Struct({
233
+ string: S.String,
234
+ }),
235
+ }) {}
236
+
237
+ const toStringResolver = createResolver({
238
+ intent: ToString,
239
+ resolve: async (data) => ({ data: { string: data.value.toString() } }),
240
+ });
241
+
242
+ class Compute extends S.TaggedClass<Compute>()('Compute', {
243
+ input: S.Struct({
244
+ value: S.Number,
245
+ }),
246
+ output: S.Struct({
247
+ value: S.Number,
248
+ }),
249
+ }) {}
250
+
251
+ const computeResolver = createResolver({
252
+ intent: Compute,
253
+ resolve: (data, undo) => {
254
+ return Effect.gen(function* () {
255
+ if (undo) {
256
+ return { data: { value: data.value / 2 } };
257
+ }
258
+
259
+ yield* Effect.sleep(data.value * 10);
260
+ const value = data.value * 2;
261
+ return { data: { value }, undoable: { message: 'test', data: { value } } };
262
+ });
263
+ },
264
+ });
265
+
266
+ class Concat extends S.TaggedClass<Concat>()('Concat', {
267
+ input: S.Struct({
268
+ string: S.String,
269
+ plus: S.String,
270
+ }),
271
+ output: S.Struct({
272
+ string: S.String,
273
+ }),
274
+ }) {}
275
+
276
+ const concatResolver = createResolver({
277
+ intent: Concat,
278
+ resolve: async (data) => ({ data: { string: data.string + data.plus } }),
279
+ });
280
+
281
+ class Add extends S.TaggedClass<Add>()('Add', {
282
+ input: S.Tuple(S.Number, S.Number),
283
+ output: S.Number,
284
+ }) {}
285
+
286
+ const addResolver = createResolver({
287
+ intent: Add,
288
+ resolve: async (data) => ({ data: data[0] + data[1] }),
289
+ });
290
+
291
+ class SideEffect extends S.TaggedClass<SideEffect>()('SideEffect', {
292
+ input: S.Void,
293
+ output: S.Void,
294
+ }) {}
295
+
296
+ const sideEffectResolver = createResolver({
297
+ intent: SideEffect,
298
+ resolve: async () => {},
299
+ });
@@ -0,0 +1,304 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { Effect, Option, pipe, Ref } from 'effect';
6
+ import { type Simplify } from 'effect/Types';
7
+
8
+ import { create } from '@dxos/live-object';
9
+ import { byPosition, type MaybePromise, type Position, type GuardedType } from '@dxos/util';
10
+
11
+ import { IntentAction } from './actions';
12
+ import { CycleDetectedError, NoResolversError } from './errors';
13
+ import {
14
+ createIntent,
15
+ type AnyIntent,
16
+ type AnyIntentChain,
17
+ type Intent,
18
+ type IntentChain,
19
+ type IntentData,
20
+ type IntentParams,
21
+ type IntentResultData,
22
+ type IntentSchema,
23
+ type Label,
24
+ } from './intent';
25
+ import { Events, Capabilities } from '../common';
26
+ import { contributes, type PluginsContext } from '../core';
27
+
28
+ const EXECUTION_LIMIT = 100;
29
+ const HISTORY_LIMIT = 100;
30
+
31
+ /**
32
+ * The return value of an intent effect.
33
+ */
34
+ export type IntentEffectResult<Input, Output> = {
35
+ /**
36
+ * The output of the action that was performed.
37
+ *
38
+ * If the intent is apart of a chain of intents, the data will be passed to the next intent.
39
+ */
40
+ data?: Output;
41
+
42
+ /**
43
+ * If provided, the action will be undoable.
44
+ */
45
+ undoable?: {
46
+ /**
47
+ * Message to display to the user when indicating that the action can be undone.
48
+ */
49
+ message: Label;
50
+
51
+ /**
52
+ * Will be merged with the original intent data when firing the undo intent.
53
+ */
54
+ data?: Partial<Input>;
55
+ };
56
+
57
+ /**
58
+ * An error that occurred while performing the action.
59
+ *
60
+ * If the intent is apart of a chain of intents and an error occurs, the chain will be aborted.
61
+ *
62
+ * Return caught error instead of throwing to trigger other intent to be triggered prior to returning the error.
63
+ */
64
+ error?: Error;
65
+
66
+ /**
67
+ * Other intent chains to be triggered.
68
+ */
69
+ intents?: AnyIntentChain[];
70
+ };
71
+
72
+ export type AnyIntentEffectResult = IntentEffectResult<any, any>;
73
+
74
+ /**
75
+ * The result of an intent dispatcher.
76
+ */
77
+ export type IntentDispatcherResult<Input, Output> = Pick<IntentEffectResult<Input, Output>, 'data' | 'error'>;
78
+
79
+ /**
80
+ * The implementation of an intent effect.
81
+ */
82
+ export type IntentEffectDefinition<Input, Output> = (
83
+ data: Input,
84
+ undo: boolean,
85
+ ) => MaybePromise<IntentEffectResult<Input, Output> | void> | Effect.Effect<IntentEffectResult<Input, Output> | void>;
86
+
87
+ /**
88
+ * Intent resolver to match intents to their effects.
89
+ */
90
+ export type IntentResolver<Tag extends string, Fields extends IntentParams, Data = IntentData<Fields>> = Readonly<{
91
+ intent: IntentSchema<Tag, Fields>;
92
+ position?: Position;
93
+ filter?: (data: IntentData<Fields>) => data is Data;
94
+ resolve: IntentEffectDefinition<GuardedType<IntentResolver<Tag, Fields, Data>['filter']>, IntentResultData<Fields>>;
95
+ }>;
96
+
97
+ export type AnyIntentResolver = IntentResolver<any, any, any>;
98
+
99
+ /**
100
+ * Creates an intent resolver to match intents to their effects.
101
+ * @param schema Schema of the intent. Must be a tagged class with input and output schemas.
102
+ * @param effect Effect to be performed when the intent is resolved.
103
+ * @param params.disposition Determines the priority of the resolver when multiple are resolved.
104
+ * @param params.filter Optional filter to determine if the resolver should be used.
105
+ */
106
+ export const createResolver = <Tag extends string, Fields extends IntentParams, Data = IntentData<Fields>>(
107
+ resolver: IntentResolver<Tag, Fields, Data>,
108
+ ) => resolver;
109
+
110
+ /**
111
+ * Invokes intents and returns the result.
112
+ */
113
+ export type PromiseIntentDispatcher = <Fields extends IntentParams>(
114
+ intent: IntentChain<any, any, any, Fields>,
115
+ ) => Promise<Simplify<IntentDispatcherResult<IntentData<Fields>, IntentResultData<Fields>>>>;
116
+
117
+ /**
118
+ * Creates an effect for intents.
119
+ */
120
+ export type IntentDispatcher = <Fields extends IntentParams>(
121
+ intent: IntentChain<any, any, any, Fields>,
122
+ depth?: number,
123
+ ) => Effect.Effect<
124
+ Simplify<Required<IntentDispatcherResult<IntentData<Fields>, IntentResultData<Fields>>>['data']>,
125
+ Error
126
+ >;
127
+
128
+ type IntentResult<Tag extends string, Fields extends IntentParams> = IntentEffectResult<
129
+ IntentData<Fields>,
130
+ IntentResultData<Fields>
131
+ > & {
132
+ _intent: Intent<Tag, Fields>;
133
+ };
134
+
135
+ export type AnyIntentResult = IntentResult<any, any>;
136
+
137
+ /**
138
+ * Invokes the most recent undoable intent with undo flags.
139
+ */
140
+ export type PromiseIntentUndo = () => Promise<IntentDispatcherResult<any, any>>;
141
+
142
+ /**
143
+ * Creates an effect which undoes the last intent.
144
+ */
145
+ export type IntentUndo = () => Effect.Effect<any, Error>;
146
+
147
+ /**
148
+ * Check if a chain of results is undoable.
149
+ */
150
+ const isUndoable = (historyEntry: AnyIntentResult[]): boolean =>
151
+ historyEntry.length > 0 && historyEntry.every(({ undoable }) => !!undoable);
152
+
153
+ export type IntentContext = {
154
+ dispatch: IntentDispatcher;
155
+ dispatchPromise: PromiseIntentDispatcher;
156
+ undo: IntentUndo;
157
+ undoPromise: PromiseIntentUndo;
158
+ };
159
+
160
+ /**
161
+ * Sets of an intent dispatcher.
162
+ *
163
+ * @param getResolvers A function that returns an array of available intent resolvers.
164
+ * @param params.historyLimit The maximum number of intent results to keep in history.
165
+ * @param params.executionLimit The maximum recursion depth of intent chains.
166
+ */
167
+ export const createDispatcher = (
168
+ getResolvers: (module?: string) => AnyIntentResolver[],
169
+ { executionLimit = EXECUTION_LIMIT, historyLimit = HISTORY_LIMIT } = {},
170
+ ): IntentContext => {
171
+ const historyRef = Effect.runSync(Ref.make<AnyIntentResult[][]>([]));
172
+
173
+ const handleIntent = (intent: AnyIntent) =>
174
+ Effect.gen(function* () {
175
+ const candidates = getResolvers(intent.module)
176
+ .filter((r) => r.intent._tag === intent.id)
177
+ .filter((r) => !r.filter || r.filter(intent.data))
178
+ .toSorted(byPosition);
179
+ if (candidates.length === 0) {
180
+ yield* Effect.fail(new NoResolversError(intent.id));
181
+ }
182
+
183
+ const effect = candidates[0].resolve(intent.data, intent.undo ?? false);
184
+ const result = Effect.isEffect(effect) ? yield* effect : yield* Effect.promise(async () => effect);
185
+ return { _intent: intent, ...result } as AnyIntentResult;
186
+ });
187
+
188
+ const dispatch: IntentDispatcher = (intentChain, depth = 0) => {
189
+ return Effect.gen(function* () {
190
+ if (depth > executionLimit) {
191
+ yield* Effect.fail(new CycleDetectedError());
192
+ }
193
+
194
+ const resultsRef = yield* Ref.make<AnyIntentResult[]>([]);
195
+ for (const intent of intentChain.all) {
196
+ const { data: prev } = (yield* resultsRef.get)[0] ?? {};
197
+ const result = yield* handleIntent({ ...intent, data: { ...intent.data, ...prev } });
198
+ yield* Ref.update(resultsRef, (results) => [result, ...results]);
199
+ if (result.intents) {
200
+ for (const intent of result.intents) {
201
+ // Returned intents are dispatched but not yielded into results,
202
+ // as such they cannot be undone.
203
+ // TODO(wittjosiah): Use higher execution concurrency?
204
+ yield* dispatch(intent, depth + 1);
205
+ }
206
+ }
207
+ if (result.error) {
208
+ yield* Effect.fail(result.error);
209
+ }
210
+ }
211
+
212
+ const results = yield* resultsRef.get;
213
+ const result = results[0];
214
+ yield* Ref.update(historyRef, (history) => {
215
+ const next = [...history, results];
216
+ if (next.length > historyLimit) {
217
+ next.splice(0, next.length - historyLimit);
218
+ }
219
+ return next;
220
+ });
221
+
222
+ if (result.undoable && isUndoable(results)) {
223
+ // TODO(wittjosiah): Is there a better way to handle showing undo for chains?
224
+ yield* pipe(
225
+ dispatch(createIntent(IntentAction.ShowUndo, { message: result.undoable.message })),
226
+ Effect.catchSome((err) =>
227
+ err instanceof NoResolversError ? Option.some(Effect.succeed(undefined)) : Option.none(),
228
+ ),
229
+ );
230
+ }
231
+
232
+ return result.data;
233
+ });
234
+ };
235
+
236
+ const dispatchPromise: PromiseIntentDispatcher = (intentChain) => {
237
+ return Effect.runPromise(dispatch(intentChain))
238
+ .then((data) => ({ data }))
239
+ .catch((error) => ({ error }));
240
+ };
241
+
242
+ const undo: IntentUndo = () => {
243
+ return Effect.gen(function* () {
244
+ const history = yield* historyRef.get;
245
+ const last = history.findLastIndex(isUndoable);
246
+ const result = last !== -1 ? history[last] : undefined;
247
+ if (result) {
248
+ const all = result.map(({ _intent, undoable }): AnyIntent => {
249
+ const data = _intent.data;
250
+ const undoData = undoable?.data ?? {};
251
+ return { ..._intent, data: { ...data, ...undoData }, undo: true } satisfies AnyIntent;
252
+ });
253
+ const intent = { first: all[0], last: all.at(-1)!, all } satisfies AnyIntentChain;
254
+ yield* Ref.update(historyRef, (h) => h.filter((_, index) => index !== last));
255
+ return yield* dispatch(intent);
256
+ }
257
+ });
258
+ };
259
+
260
+ const undoPromise: PromiseIntentUndo = () => {
261
+ return Effect.runPromise(undo())
262
+ .then((data) => ({ data }))
263
+ .catch((error) => ({ error }));
264
+ };
265
+
266
+ return { dispatch, dispatchPromise, undo, undoPromise };
267
+ };
268
+
269
+ const defaultEffect = () => Effect.fail(new Error('Intent runtime not ready'));
270
+ const defaultPromise = () => Effect.runPromise(defaultEffect());
271
+
272
+ export default (context: PluginsContext) => {
273
+ const state = create<IntentContext>({
274
+ dispatch: defaultEffect,
275
+ dispatchPromise: defaultPromise,
276
+ undo: defaultEffect,
277
+ undoPromise: defaultPromise,
278
+ });
279
+
280
+ // TODO(wittjosiah): Make getResolver callback async and allow resolvers to be requested on demand.
281
+ const { dispatch, dispatchPromise, undo, undoPromise } = createDispatcher((module) =>
282
+ context
283
+ .requestCapabilities(Capabilities.IntentResolver, (c, moduleId): c is AnyIntentResolver => {
284
+ return module ? moduleId === module : true;
285
+ })
286
+ .flat(),
287
+ );
288
+
289
+ const manager = context.requestCapability(Capabilities.PluginManager);
290
+ state.dispatch = (intentChain, depth) => {
291
+ return Effect.gen(function* () {
292
+ yield* manager._activate(Events.SetupIntents);
293
+ return yield* dispatch(intentChain, depth);
294
+ });
295
+ };
296
+ state.dispatchPromise = async (intentChain) => {
297
+ await manager.activate(Events.SetupIntents);
298
+ return await dispatchPromise(intentChain);
299
+ };
300
+ state.undo = undo;
301
+ state.undoPromise = undoPromise;
302
+
303
+ return contributes(Capabilities.IntentDispatcher, state);
304
+ };