@edenapp/sdk 0.1.0

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 (432) hide show
  1. package/apps/com/eden/editor/dist/assets/css-DQU6DXDx.js +3 -0
  2. package/apps/com/eden/editor/dist/assets/editor-BRA9licV.css +1 -0
  3. package/apps/com/eden/editor/dist/assets/editor.main-DAsyVptA.js +677 -0
  4. package/apps/com/eden/editor/dist/assets/editor.worker-B4pQIWZD.js +12 -0
  5. package/apps/com/eden/editor/dist/assets/html-CTBLac3N.js +1 -0
  6. package/apps/com/eden/editor/dist/assets/index-B7GgDQ9I.css +1 -0
  7. package/apps/com/eden/editor/dist/assets/index-BWJI9cyM.js +2 -0
  8. package/apps/com/eden/editor/dist/assets/ini-BvajGCUy.js +1 -0
  9. package/apps/com/eden/editor/dist/assets/javascript-DJ6Ya8pi.js +1 -0
  10. package/apps/com/eden/editor/dist/assets/jsonMode-BA0kYRDI.js +10 -0
  11. package/apps/com/eden/editor/dist/assets/less-GGFNNJHn.js +2 -0
  12. package/apps/com/eden/editor/dist/assets/markdown-B811l8j2.js +1 -0
  13. package/apps/com/eden/editor/dist/assets/shell-CsDZo4DB.js +1 -0
  14. package/apps/com/eden/editor/dist/assets/typescript-C7BsmV0J.js +1 -0
  15. package/apps/com/eden/editor/dist/assets/yaml-QL02lm_B.js +1 -0
  16. package/apps/com/eden/editor/dist/index.html +13 -0
  17. package/apps/com/eden/editor/icon.svg +22 -0
  18. package/apps/com/eden/editor/index.html +12 -0
  19. package/apps/com/eden/editor/manifest.json +58 -0
  20. package/apps/com/eden/editor/node_modules/.bin/browserslist +21 -0
  21. package/apps/com/eden/editor/node_modules/.bin/tsc +21 -0
  22. package/apps/com/eden/editor/node_modules/.bin/tsserver +21 -0
  23. package/apps/com/eden/editor/node_modules/.bin/vite +21 -0
  24. package/apps/com/eden/editor/package.json +21 -0
  25. package/apps/com/eden/editor/src/App.tsx +212 -0
  26. package/apps/com/eden/editor/src/components/ErrorBanner.tsx +13 -0
  27. package/apps/com/eden/editor/src/components/LazyMonacoEditor.tsx +154 -0
  28. package/apps/com/eden/editor/src/components/TabBar.tsx +36 -0
  29. package/apps/com/eden/editor/src/components/Toolbar.tsx +39 -0
  30. package/apps/com/eden/editor/src/components/WelcomeScreen.tsx +49 -0
  31. package/apps/com/eden/editor/src/components/index.ts +11 -0
  32. package/apps/com/eden/editor/src/index.tsx +10 -0
  33. package/apps/com/eden/editor/src/styles.css +319 -0
  34. package/apps/com/eden/editor/src/types.ts +69 -0
  35. package/apps/com/eden/editor/tsconfig.json +24 -0
  36. package/apps/com/eden/editor/vite.config.mts +67 -0
  37. package/apps/com/eden/eveshell/assets/apps-grid-icon.svg +17 -0
  38. package/apps/com/eden/eveshell/assets/default-icon.svg +17 -0
  39. package/apps/com/eden/eveshell/dist/assets/index-BS2yCXxK.css +1 -0
  40. package/apps/com/eden/eveshell/dist/assets/index-De0NEh_d.js +1 -0
  41. package/apps/com/eden/eveshell/dist/index.html +13 -0
  42. package/apps/com/eden/eveshell/index.html +12 -0
  43. package/apps/com/eden/eveshell/manifest.json +28 -0
  44. package/apps/com/eden/eveshell/node_modules/.bin/tsc +21 -0
  45. package/apps/com/eden/eveshell/node_modules/.bin/tsserver +21 -0
  46. package/apps/com/eden/eveshell/node_modules/.bin/vite +21 -0
  47. package/apps/com/eden/eveshell/package.json +20 -0
  48. package/apps/com/eden/eveshell/src/components/AllApps.tsx +228 -0
  49. package/apps/com/eden/eveshell/src/components/AppContextMenu.tsx +125 -0
  50. package/apps/com/eden/eveshell/src/components/AppIcon.tsx +40 -0
  51. package/apps/com/eden/eveshell/src/components/Clock.tsx +35 -0
  52. package/apps/com/eden/eveshell/src/components/Dock.tsx +147 -0
  53. package/apps/com/eden/eveshell/src/components/ShellOverlay.tsx +343 -0
  54. package/apps/com/eden/eveshell/src/icon-cache.ts +38 -0
  55. package/apps/com/eden/eveshell/src/index.tsx +11 -0
  56. package/apps/com/eden/eveshell/src/styles.css +409 -0
  57. package/apps/com/eden/eveshell/src/types.ts +5 -0
  58. package/apps/com/eden/eveshell/tsconfig.json +37 -0
  59. package/apps/com/eden/eveshell/vite.config.mts +23 -0
  60. package/apps/com/eden/example/appbus/client-a/app.js +239 -0
  61. package/apps/com/eden/example/appbus/client-a/index.html +48 -0
  62. package/apps/com/eden/example/appbus/client-a/manifest.json +27 -0
  63. package/apps/com/eden/example/appbus/client-a/styles.css +52 -0
  64. package/apps/com/eden/example/appbus/client-b/app.js +130 -0
  65. package/apps/com/eden/example/appbus/client-b/index.html +35 -0
  66. package/apps/com/eden/example/appbus/client-b/manifest.json +27 -0
  67. package/apps/com/eden/example/appbus/client-b/styles.css +48 -0
  68. package/apps/com/eden/example/appbus/hub/README.md +18 -0
  69. package/apps/com/eden/example/appbus/hub/backend.js +121 -0
  70. package/apps/com/eden/example/appbus/hub/manifest.json +17 -0
  71. package/apps/com/eden/example/appbus/isolated/app.js +107 -0
  72. package/apps/com/eden/example/appbus/isolated/index.html +35 -0
  73. package/apps/com/eden/example/appbus/isolated/manifest.json +27 -0
  74. package/apps/com/eden/example/appbus/isolated/styles.css +52 -0
  75. package/apps/com/eden/example/calculator/.dev-manifest.json +5 -0
  76. package/apps/com/eden/example/calculator/app.js +95 -0
  77. package/apps/com/eden/example/calculator/icon.svg +19 -0
  78. package/apps/com/eden/example/calculator/index.html +39 -0
  79. package/apps/com/eden/example/calculator/manifest.json +30 -0
  80. package/apps/com/eden/example/calculator/styles.css +83 -0
  81. package/apps/com/eden/example/hello/README.md +3 -0
  82. package/apps/com/eden/example/hello/backend/dist/backend.js +47 -0
  83. package/apps/com/eden/example/hello/backend/node_modules/.bin/tsc +21 -0
  84. package/apps/com/eden/example/hello/backend/node_modules/.bin/tsserver +21 -0
  85. package/apps/com/eden/example/hello/backend/package.json +13 -0
  86. package/apps/com/eden/example/hello/backend/src/backend.ts +58 -0
  87. package/apps/com/eden/example/hello/backend/tsconfig.json +19 -0
  88. package/apps/com/eden/example/hello/frontend/dist/assets/index-D2WAwW3g.css +1 -0
  89. package/apps/com/eden/example/hello/frontend/dist/assets/index-D4bTq3-Q.js +1 -0
  90. package/apps/com/eden/example/hello/frontend/dist/index.html +59 -0
  91. package/apps/com/eden/example/hello/frontend/index.html +59 -0
  92. package/apps/com/eden/example/hello/frontend/node_modules/.bin/tsc +21 -0
  93. package/apps/com/eden/example/hello/frontend/node_modules/.bin/tsserver +21 -0
  94. package/apps/com/eden/example/hello/frontend/node_modules/.bin/vite +21 -0
  95. package/apps/com/eden/example/hello/frontend/package.json +15 -0
  96. package/apps/com/eden/example/hello/frontend/src/App.ts +191 -0
  97. package/apps/com/eden/example/hello/frontend/styles.css +96 -0
  98. package/apps/com/eden/example/hello/frontend/tsconfig.json +16 -0
  99. package/apps/com/eden/example/hello/frontend/vite.config.mts +21 -0
  100. package/apps/com/eden/example/hello/manifest.json +34 -0
  101. package/apps/com/eden/example/hello/shared/protocol.d.ts +38 -0
  102. package/apps/com/eden/example/showcase/app.js +186 -0
  103. package/apps/com/eden/example/showcase/index.html +637 -0
  104. package/apps/com/eden/example/showcase/manifest.json +24 -0
  105. package/apps/com/eden/example/showcase/styles.css +195 -0
  106. package/apps/com/eden/files/.dev-manifest.json +5 -0
  107. package/apps/com/eden/files/dist/assets/index-BOw4ESi3.js +1 -0
  108. package/apps/com/eden/files/dist/assets/index-BPH5FvSW.css +1 -0
  109. package/apps/com/eden/files/dist/index.html +13 -0
  110. package/apps/com/eden/files/icon.svg +15 -0
  111. package/apps/com/eden/files/index.html +12 -0
  112. package/apps/com/eden/files/manifest.json +28 -0
  113. package/apps/com/eden/files/node_modules/.bin/tsc +21 -0
  114. package/apps/com/eden/files/node_modules/.bin/tsserver +21 -0
  115. package/apps/com/eden/files/node_modules/.bin/vite +21 -0
  116. package/apps/com/eden/files/node_modules/.vite/deps/_metadata.json +46 -0
  117. package/apps/com/eden/files/node_modules/.vite/deps/chunk-5W77UGHT.js +1253 -0
  118. package/apps/com/eden/files/node_modules/.vite/deps/chunk-5W77UGHT.js.map +7 -0
  119. package/apps/com/eden/files/node_modules/.vite/deps/chunk-K4SCX2FD.js +1809 -0
  120. package/apps/com/eden/files/node_modules/.vite/deps/chunk-K4SCX2FD.js.map +7 -0
  121. package/apps/com/eden/files/node_modules/.vite/deps/package.json +3 -0
  122. package/apps/com/eden/files/node_modules/.vite/deps/solid-js.js +112 -0
  123. package/apps/com/eden/files/node_modules/.vite/deps/solid-js.js.map +7 -0
  124. package/apps/com/eden/files/node_modules/.vite/deps/solid-js_h.js +122 -0
  125. package/apps/com/eden/files/node_modules/.vite/deps/solid-js_h.js.map +7 -0
  126. package/apps/com/eden/files/node_modules/.vite/deps/solid-js_html.js +606 -0
  127. package/apps/com/eden/files/node_modules/.vite/deps/solid-js_html.js.map +7 -0
  128. package/apps/com/eden/files/node_modules/.vite/deps/solid-js_store.js +455 -0
  129. package/apps/com/eden/files/node_modules/.vite/deps/solid-js_store.js.map +7 -0
  130. package/apps/com/eden/files/node_modules/.vite/deps/solid-js_web.js +147 -0
  131. package/apps/com/eden/files/node_modules/.vite/deps/solid-js_web.js.map +7 -0
  132. package/apps/com/eden/files/package-lock.json +1754 -0
  133. package/apps/com/eden/files/package.json +20 -0
  134. package/apps/com/eden/files/src/App.tsx +387 -0
  135. package/apps/com/eden/files/src/components/FileExplorerHeader.tsx +90 -0
  136. package/apps/com/eden/files/src/components/FileItem.tsx +70 -0
  137. package/apps/com/eden/files/src/components/FileList.tsx +77 -0
  138. package/apps/com/eden/files/src/components/Modal.tsx +48 -0
  139. package/apps/com/eden/files/src/components/Omnibox.tsx +241 -0
  140. package/apps/com/eden/files/src/dialogs/CreateFileDialog.tsx +71 -0
  141. package/apps/com/eden/files/src/dialogs/CreateFolderDialog.tsx +68 -0
  142. package/apps/com/eden/files/src/dialogs/DeleteConfirmDialog.tsx +35 -0
  143. package/apps/com/eden/files/src/dialogs/DisplayOptionsModal.tsx +122 -0
  144. package/apps/com/eden/files/src/dialogs/ErrorDialog.tsx +28 -0
  145. package/apps/com/eden/files/src/index.tsx +9 -0
  146. package/apps/com/eden/files/src/styles.css +595 -0
  147. package/apps/com/eden/files/src/types.ts +20 -0
  148. package/apps/com/eden/files/src/utils.ts +44 -0
  149. package/apps/com/eden/files/tsconfig.json +27 -0
  150. package/apps/com/eden/files/vite.config.mts +23 -0
  151. package/apps/com/eden/settings/dist/assets/index-CTkJneTg.js +1 -0
  152. package/apps/com/eden/settings/dist/assets/index-GIMJANTM.css +1 -0
  153. package/apps/com/eden/settings/dist/index.html +13 -0
  154. package/apps/com/eden/settings/icon.svg +15 -0
  155. package/apps/com/eden/settings/index.html +12 -0
  156. package/apps/com/eden/settings/manifest.json +28 -0
  157. package/apps/com/eden/settings/node_modules/.bin/tsc +21 -0
  158. package/apps/com/eden/settings/node_modules/.bin/tsserver +21 -0
  159. package/apps/com/eden/settings/node_modules/.bin/vite +21 -0
  160. package/apps/com/eden/settings/package.json +21 -0
  161. package/apps/com/eden/settings/src/App.css +168 -0
  162. package/apps/com/eden/settings/src/App.tsx +301 -0
  163. package/apps/com/eden/settings/src/components/SettingInput.tsx +131 -0
  164. package/apps/com/eden/settings/src/index.tsx +9 -0
  165. package/apps/com/eden/settings/tsconfig.json +21 -0
  166. package/apps/com/eden/settings/vite.config.mts +22 -0
  167. package/apps/com/eden/toaster/README.md +89 -0
  168. package/apps/com/eden/toaster/dist/assets/index-8JMcmBCJ.css +1 -0
  169. package/apps/com/eden/toaster/dist/assets/index-C4cVyh7j.js +16 -0
  170. package/apps/com/eden/toaster/dist/index.html +16 -0
  171. package/apps/com/eden/toaster/index.html +16 -0
  172. package/apps/com/eden/toaster/manifest.json +28 -0
  173. package/apps/com/eden/toaster/node_modules/.bin/vite +21 -0
  174. package/apps/com/eden/toaster/package.json +15 -0
  175. package/apps/com/eden/toaster/src/styles.css +159 -0
  176. package/apps/com/eden/toaster/src/toaster.ts +470 -0
  177. package/apps/com/eden/toaster/tsconfig.json +28 -0
  178. package/apps/com/eden/toaster/vite.config.mts +18 -0
  179. package/apps/com/eden/webbrowser/.dev-manifest.json +5 -0
  180. package/apps/com/eden/webbrowser/icon.svg +20 -0
  181. package/apps/com/eden/webbrowser/index.html +141 -0
  182. package/apps/com/eden/webbrowser/manifest.json +23 -0
  183. package/apps/com/eden/webbrowser/node_modules/.bin/vite +21 -0
  184. package/apps/com/eden/webbrowser/node_modules/.vite/deps/_metadata.json +8 -0
  185. package/apps/com/eden/webbrowser/node_modules/.vite/deps/package.json +3 -0
  186. package/apps/com/eden/webbrowser/package.json +13 -0
  187. package/apps/com/eden/webbrowser/vite.config.mts +11 -0
  188. package/dist/Eden.d.ts +40 -0
  189. package/dist/Eden.d.ts.map +1 -0
  190. package/dist/Eden.js +186 -0
  191. package/dist/Eden.js.map +1 -0
  192. package/dist/SystemHandler.d.ts +11 -0
  193. package/dist/SystemHandler.d.ts.map +1 -0
  194. package/dist/SystemHandler.js +53 -0
  195. package/dist/SystemHandler.js.map +1 -0
  196. package/dist/app-frame/frame-injector.js +19 -0
  197. package/dist/app-frame/frame-injector.js.map +7 -0
  198. package/dist/app-frame/frame.css +186 -0
  199. package/dist/app-runtime/app-preload.js +2 -0
  200. package/dist/app-runtime/app-preload.js.map +7 -0
  201. package/dist/app-runtime/backend-preload.js +2 -0
  202. package/dist/app-runtime/backend-preload.js.map +7 -0
  203. package/dist/appbus/AppChannelHandler.d.ts +65 -0
  204. package/dist/appbus/AppChannelHandler.d.ts.map +1 -0
  205. package/dist/appbus/AppChannelHandler.js +120 -0
  206. package/dist/appbus/AppChannelHandler.js.map +1 -0
  207. package/dist/appbus/AppChannelManager.d.ts +80 -0
  208. package/dist/appbus/AppChannelManager.d.ts.map +1 -0
  209. package/dist/appbus/AppChannelManager.js +312 -0
  210. package/dist/appbus/AppChannelManager.js.map +1 -0
  211. package/dist/appbus/index.d.ts +2 -0
  212. package/dist/appbus/index.d.ts.map +1 -0
  213. package/dist/appbus/index.js +18 -0
  214. package/dist/appbus/index.js.map +1 -0
  215. package/dist/db/DbHandler.d.ts +119 -0
  216. package/dist/db/DbHandler.d.ts.map +1 -0
  217. package/dist/db/DbHandler.js +204 -0
  218. package/dist/db/DbHandler.js.map +1 -0
  219. package/dist/db/DbManager.d.ts +49 -0
  220. package/dist/db/DbManager.d.ts.map +1 -0
  221. package/dist/db/DbManager.js +172 -0
  222. package/dist/db/DbManager.js.map +1 -0
  223. package/dist/db/index.d.ts +3 -0
  224. package/dist/db/index.d.ts.map +1 -0
  225. package/dist/db/index.js +8 -0
  226. package/dist/db/index.js.map +1 -0
  227. package/dist/edencss/eden-tokens.css +1 -0
  228. package/dist/edencss/eden.css +1 -0
  229. package/dist/file-open/FileOpenHandler.d.ts +59 -0
  230. package/dist/file-open/FileOpenHandler.d.ts.map +1 -0
  231. package/dist/file-open/FileOpenHandler.js +122 -0
  232. package/dist/file-open/FileOpenHandler.js.map +1 -0
  233. package/dist/file-open/FileOpenManager.d.ts +91 -0
  234. package/dist/file-open/FileOpenManager.d.ts.map +1 -0
  235. package/dist/file-open/FileOpenManager.js +411 -0
  236. package/dist/file-open/FileOpenManager.js.map +1 -0
  237. package/dist/file-open/index.d.ts +3 -0
  238. package/dist/file-open/index.d.ts.map +1 -0
  239. package/dist/file-open/index.js +8 -0
  240. package/dist/file-open/index.js.map +1 -0
  241. package/dist/filesystem/FilesystemHandler.d.ts +65 -0
  242. package/dist/filesystem/FilesystemHandler.d.ts.map +1 -0
  243. package/dist/filesystem/FilesystemHandler.js +134 -0
  244. package/dist/filesystem/FilesystemHandler.js.map +1 -0
  245. package/dist/filesystem/FilesystemManager.d.ts +70 -0
  246. package/dist/filesystem/FilesystemManager.d.ts.map +1 -0
  247. package/dist/filesystem/FilesystemManager.js +236 -0
  248. package/dist/filesystem/FilesystemManager.js.map +1 -0
  249. package/dist/filesystem/index.d.ts +3 -0
  250. package/dist/filesystem/index.d.ts.map +1 -0
  251. package/dist/filesystem/index.js +8 -0
  252. package/dist/filesystem/index.js.map +1 -0
  253. package/dist/foundation/foundation-preload.js +15 -0
  254. package/dist/foundation/foundation.css +40 -0
  255. package/dist/foundation/foundation.html +22 -0
  256. package/dist/foundation/foundation.js +69 -0
  257. package/dist/hotreload-config.d.ts +8 -0
  258. package/dist/hotreload-config.d.ts.map +1 -0
  259. package/dist/hotreload-config.js +73 -0
  260. package/dist/hotreload-config.js.map +1 -0
  261. package/dist/index.d.ts +7 -0
  262. package/dist/index.d.ts.map +1 -0
  263. package/dist/index.js +20 -0
  264. package/dist/index.js.map +1 -0
  265. package/dist/ipc/CommandDecorators.d.ts +72 -0
  266. package/dist/ipc/CommandDecorators.d.ts.map +1 -0
  267. package/dist/ipc/CommandDecorators.js +49 -0
  268. package/dist/ipc/CommandDecorators.js.map +1 -0
  269. package/dist/ipc/CommandRegistry.d.ts +77 -0
  270. package/dist/ipc/CommandRegistry.d.ts.map +1 -0
  271. package/dist/ipc/CommandRegistry.js +175 -0
  272. package/dist/ipc/CommandRegistry.js.map +1 -0
  273. package/dist/ipc/EdenEmitter.d.ts +54 -0
  274. package/dist/ipc/EdenEmitter.d.ts.map +1 -0
  275. package/dist/ipc/EdenEmitter.js +81 -0
  276. package/dist/ipc/EdenEmitter.js.map +1 -0
  277. package/dist/ipc/EventHandler.d.ts +21 -0
  278. package/dist/ipc/EventHandler.d.ts.map +1 -0
  279. package/dist/ipc/EventHandler.js +87 -0
  280. package/dist/ipc/EventHandler.js.map +1 -0
  281. package/dist/ipc/EventSubscriberManager.d.ts +67 -0
  282. package/dist/ipc/EventSubscriberManager.d.ts.map +1 -0
  283. package/dist/ipc/EventSubscriberManager.js +204 -0
  284. package/dist/ipc/EventSubscriberManager.js.map +1 -0
  285. package/dist/ipc/IPCBridge.d.ts +60 -0
  286. package/dist/ipc/IPCBridge.d.ts.map +1 -0
  287. package/dist/ipc/IPCBridge.js +186 -0
  288. package/dist/ipc/IPCBridge.js.map +1 -0
  289. package/dist/ipc/PermissionRegistry.d.ts +52 -0
  290. package/dist/ipc/PermissionRegistry.d.ts.map +1 -0
  291. package/dist/ipc/PermissionRegistry.js +120 -0
  292. package/dist/ipc/PermissionRegistry.js.map +1 -0
  293. package/dist/ipc/index.d.ts +7 -0
  294. package/dist/ipc/index.d.ts.map +1 -0
  295. package/dist/ipc/index.js +23 -0
  296. package/dist/ipc/index.js.map +1 -0
  297. package/dist/main.d.ts +2 -0
  298. package/dist/main.d.ts.map +1 -0
  299. package/dist/main.js +15 -0
  300. package/dist/main.js.map +1 -0
  301. package/dist/notification/NotificationHandler.d.ts +16 -0
  302. package/dist/notification/NotificationHandler.d.ts.map +1 -0
  303. package/dist/notification/NotificationHandler.js +39 -0
  304. package/dist/notification/NotificationHandler.js.map +1 -0
  305. package/dist/notification/NotificationManager.d.ts +32 -0
  306. package/dist/notification/NotificationManager.d.ts.map +1 -0
  307. package/dist/notification/NotificationManager.js +66 -0
  308. package/dist/notification/NotificationManager.js.map +1 -0
  309. package/dist/notification/index.d.ts +3 -0
  310. package/dist/notification/index.d.ts.map +1 -0
  311. package/dist/notification/index.js +19 -0
  312. package/dist/notification/index.js.map +1 -0
  313. package/dist/package-manager/PackageHandler.d.ts +50 -0
  314. package/dist/package-manager/PackageHandler.d.ts.map +1 -0
  315. package/dist/package-manager/PackageHandler.js +107 -0
  316. package/dist/package-manager/PackageHandler.js.map +1 -0
  317. package/dist/package-manager/PackageManager.d.ts +73 -0
  318. package/dist/package-manager/PackageManager.d.ts.map +1 -0
  319. package/dist/package-manager/PackageManager.js +373 -0
  320. package/dist/package-manager/PackageManager.js.map +1 -0
  321. package/dist/package-manager/index.d.ts +3 -0
  322. package/dist/package-manager/index.d.ts.map +1 -0
  323. package/dist/package-manager/index.js +8 -0
  324. package/dist/package-manager/index.js.map +1 -0
  325. package/dist/process-manager/AutostartManager.d.ts +15 -0
  326. package/dist/process-manager/AutostartManager.d.ts.map +1 -0
  327. package/dist/process-manager/AutostartManager.js +56 -0
  328. package/dist/process-manager/AutostartManager.js.map +1 -0
  329. package/dist/process-manager/BackendManager.d.ts +63 -0
  330. package/dist/process-manager/BackendManager.d.ts.map +1 -0
  331. package/dist/process-manager/BackendManager.js +272 -0
  332. package/dist/process-manager/BackendManager.js.map +1 -0
  333. package/dist/process-manager/ProcessHandler.d.ts +29 -0
  334. package/dist/process-manager/ProcessHandler.d.ts.map +1 -0
  335. package/dist/process-manager/ProcessHandler.js +66 -0
  336. package/dist/process-manager/ProcessHandler.js.map +1 -0
  337. package/dist/process-manager/ProcessManager.d.ts +94 -0
  338. package/dist/process-manager/ProcessManager.d.ts.map +1 -0
  339. package/dist/process-manager/ProcessManager.js +286 -0
  340. package/dist/process-manager/ProcessManager.js.map +1 -0
  341. package/dist/process-manager/index.d.ts +5 -0
  342. package/dist/process-manager/index.d.ts.map +1 -0
  343. package/dist/process-manager/index.js +12 -0
  344. package/dist/process-manager/index.js.map +1 -0
  345. package/dist/settings/EdenSettings.d.ts +8 -0
  346. package/dist/settings/EdenSettings.d.ts.map +1 -0
  347. package/dist/settings/EdenSettings.js +148 -0
  348. package/dist/settings/EdenSettings.js.map +1 -0
  349. package/dist/settings/SettingsHandler.d.ts +117 -0
  350. package/dist/settings/SettingsHandler.d.ts.map +1 -0
  351. package/dist/settings/SettingsHandler.js +199 -0
  352. package/dist/settings/SettingsHandler.js.map +1 -0
  353. package/dist/settings/SettingsManager.d.ts +64 -0
  354. package/dist/settings/SettingsManager.d.ts.map +1 -0
  355. package/dist/settings/SettingsManager.js +221 -0
  356. package/dist/settings/SettingsManager.js.map +1 -0
  357. package/dist/settings/index.d.ts +4 -0
  358. package/dist/settings/index.d.ts.map +1 -0
  359. package/dist/settings/index.js +11 -0
  360. package/dist/settings/index.js.map +1 -0
  361. package/dist/utils/cachedFileReader.d.ts +46 -0
  362. package/dist/utils/cachedFileReader.d.ts.map +1 -0
  363. package/dist/utils/cachedFileReader.js +100 -0
  364. package/dist/utils/cachedFileReader.js.map +1 -0
  365. package/dist/view-manager/DevToolsManager.d.ts +29 -0
  366. package/dist/view-manager/DevToolsManager.d.ts.map +1 -0
  367. package/dist/view-manager/DevToolsManager.js +88 -0
  368. package/dist/view-manager/DevToolsManager.js.map +1 -0
  369. package/dist/view-manager/FloatingWindowController.d.ts +44 -0
  370. package/dist/view-manager/FloatingWindowController.d.ts.map +1 -0
  371. package/dist/view-manager/FloatingWindowController.js +124 -0
  372. package/dist/view-manager/FloatingWindowController.js.map +1 -0
  373. package/dist/view-manager/LayoutCalculator.d.ts +49 -0
  374. package/dist/view-manager/LayoutCalculator.d.ts.map +1 -0
  375. package/dist/view-manager/LayoutCalculator.js +94 -0
  376. package/dist/view-manager/LayoutCalculator.js.map +1 -0
  377. package/dist/view-manager/MouseTracker.d.ts +65 -0
  378. package/dist/view-manager/MouseTracker.d.ts.map +1 -0
  379. package/dist/view-manager/MouseTracker.js +114 -0
  380. package/dist/view-manager/MouseTracker.js.map +1 -0
  381. package/dist/view-manager/TilingManager.d.ts +61 -0
  382. package/dist/view-manager/TilingManager.d.ts.map +1 -0
  383. package/dist/view-manager/TilingManager.js +142 -0
  384. package/dist/view-manager/TilingManager.js.map +1 -0
  385. package/dist/view-manager/ViewCreator.d.ts +72 -0
  386. package/dist/view-manager/ViewCreator.d.ts.map +1 -0
  387. package/dist/view-manager/ViewCreator.js +277 -0
  388. package/dist/view-manager/ViewCreator.js.map +1 -0
  389. package/dist/view-manager/ViewHandler.d.ts +112 -0
  390. package/dist/view-manager/ViewHandler.d.ts.map +1 -0
  391. package/dist/view-manager/ViewHandler.js +307 -0
  392. package/dist/view-manager/ViewHandler.js.map +1 -0
  393. package/dist/view-manager/ViewLifecycle.d.ts +66 -0
  394. package/dist/view-manager/ViewLifecycle.d.ts.map +1 -0
  395. package/dist/view-manager/ViewLifecycle.js +142 -0
  396. package/dist/view-manager/ViewLifecycle.js.map +1 -0
  397. package/dist/view-manager/ViewManager.d.ts +112 -0
  398. package/dist/view-manager/ViewManager.d.ts.map +1 -0
  399. package/dist/view-manager/ViewManager.js +422 -0
  400. package/dist/view-manager/ViewManager.js.map +1 -0
  401. package/dist/view-manager/index.d.ts +11 -0
  402. package/dist/view-manager/index.d.ts.map +1 -0
  403. package/dist/view-manager/index.js +23 -0
  404. package/dist/view-manager/index.js.map +1 -0
  405. package/dist/view-manager/types.d.ts +24 -0
  406. package/dist/view-manager/types.d.ts.map +1 -0
  407. package/dist/view-manager/types.js +11 -0
  408. package/dist/view-manager/types.js.map +1 -0
  409. package/edencss/README.md +214 -0
  410. package/edencss/components/badges.css +180 -0
  411. package/edencss/components/buttons.css +221 -0
  412. package/edencss/components/cards.css +201 -0
  413. package/edencss/components/inputs.css +424 -0
  414. package/edencss/components/lists.css +242 -0
  415. package/edencss/components/modals.css +207 -0
  416. package/edencss/components/progress.css +186 -0
  417. package/edencss/components/sidebar.css +232 -0
  418. package/edencss/components/tabs.css +189 -0
  419. package/edencss/eden.css +16 -0
  420. package/edencss/index.ts +11 -0
  421. package/edencss/style-dictionary.config.mjs +75 -0
  422. package/edencss/tokens-pink.json +163 -0
  423. package/edencss/tokens.css +121 -0
  424. package/edencss/tokens.d.ts +111 -0
  425. package/edencss/tokens.json +369 -0
  426. package/edencss/tokens.ts +125 -0
  427. package/edencss/utilities.css +423 -0
  428. package/foundation/foundation-preload.js +15 -0
  429. package/foundation/foundation.css +40 -0
  430. package/foundation/foundation.html +22 -0
  431. package/foundation/foundation.js +69 -0
  432. package/package.json +55 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/app-frame/ui-builder.ts", "../../src/app-frame/button-handlers.ts", "../../src/app-frame/utils.ts", "../../src/app-frame/window-dragging.ts", "../../src/app-frame/window-resizing.ts", "../../src/app-frame/frame-injector.ts"],
4
+ "sourcesContent": ["/**\n * App Frame UI Builder\n * \n * Functions for creating and managing the app frame overlay UI\n */\n\n/**\n * Create the app frame overlay element\n * @param windowConfig - Window configuration from manifest\n * @returns The overlay element\n */\nexport function createOverlay(windowConfig: NonNullable<Window['edenFrame']>['_internal']['config']): HTMLElement {\n const overlay = document.createElement('div');\n overlay.id = 'eden-app-frame-overlay';\n\n const supportsToggle = windowConfig.mode === 'both';\n const showTitle = windowConfig.showTitle !== false; // Default to true if not specified\n\n // Create toggle button HTML if supported\n const toggleButtonHtml = supportsToggle\n ? `<button class=\"eden-app-frame-button toggle-mode\" id=\"eden-toggle-mode-btn\" title=\"Toggle Window Mode\">\u229E</button>`\n : '';\n\n // Create title HTML if showTitle is true\n const titleHtml = showTitle\n ? `<div id=\"eden-app-frame-title\">App</div>`\n : '';\n\n overlay.innerHTML = `\n ${titleHtml}\n <div id=\"eden-app-frame-controls\">\n ${toggleButtonHtml}\n <button class=\"eden-app-frame-button minimize\" id=\"eden-minimize-btn\" title=\"Minimize\">\u2212</button>\n <button class=\"eden-app-frame-button close\" id=\"eden-close-btn\" title=\"Close\">\u00D7</button>\n </div>\n `;\n\n return overlay;\n}\n\n/**\n * Inject the overlay into the DOM when ready\n * @param overlay - The overlay element to inject\n * @param callback - Called after injection\n */\nexport function injectOverlay(overlay: HTMLElement, callback?: () => void): void {\n const inject = () => {\n console.log('[Eden Frame] injectOverlay called, body exists:', !!document.body);\n if (document.body) {\n document.body.insertBefore(overlay, document.body.firstChild);\n document.body.classList.add('eden-framed');\n console.log('[Eden Frame] Overlay injected into body');\n\n if (callback) {\n callback();\n }\n } else {\n console.log('[Eden Frame] Body not ready, retrying...');\n setTimeout(inject, 10);\n }\n };\n\n // Inject when DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', inject);\n } else {\n inject();\n }\n}\n\n/**\n * Setup dark mode detection and updates\n * @param overlay - The overlay element\n */\nexport function setupDarkMode(overlay: HTMLElement): void {\n const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');\n\n const updateTheme = (e: MediaQueryListEvent | MediaQueryList) => {\n if (e.matches) {\n overlay.classList.add('dark');\n } else {\n overlay.classList.remove('dark');\n }\n };\n\n updateTheme(prefersDark);\n prefersDark.addEventListener('change', updateTheme);\n}\n\n/**\n * Set the title bar text\n * @param title - The title to display\n */\nexport function setTitle(title: string): void {\n const titleEl = document.getElementById('eden-app-frame-title');\n if (titleEl) {\n titleEl.textContent = title;\n }\n}\n\n/**\n * Extract a readable name from app ID\n * @param appId - The app ID (e.g., 'com.example.myapp')\n * @returns Readable name (e.g., 'Myapp')\n */\nexport function getAppName(appId: string): string {\n const parts = appId.split('.');\n const name = parts[parts.length - 1] || appId;\n // Capitalize first letter\n return name.charAt(0).toUpperCase() + name.slice(1);\n}\n", "/**\n * App Frame Button Handlers\n *\n * Event handlers for frame control buttons (close, minimize, toggle mode)\n */\n\n/**\n * Setup close button handler\n */\nexport function setupCloseButton(): void {\n const closeBtn = document.getElementById(\"eden-close-btn\");\n if (!closeBtn) return;\n\n closeBtn.addEventListener(\"click\", () => {\n // Wait for edenFrame to be available\n const stopApp = () => {\n const appId = window.edenFrame?._internal.appId;\n console.log(\"[Eden Frame] Stopping app:\", appId);\n\n if (appId) {\n window.edenAPI\n .shellCommand(\"process/stop\", { appId })\n .catch(console.error);\n } else {\n // Retry if API or appId not yet available\n setTimeout(stopApp, 100);\n }\n };\n stopApp();\n });\n}\n\n/**\n * Setup minimize button handler\n */\nexport function setupMinimizeButton(): void {\n const minBtn = document.getElementById(\"eden-minimize-btn\");\n if (!minBtn) return;\n\n minBtn.addEventListener(\"click\", () => {\n const minimize = () => {\n const appId = window.edenFrame?._internal.appId;\n\n if (appId) {\n window.edenAPI\n .shellCommand(\"view/set-view-visibility\", {\n appId,\n visible: false,\n })\n .catch(console.error);\n } else {\n setTimeout(minimize, 100);\n }\n };\n minimize();\n });\n}\n\n/**\n * Setup toggle mode button handler (for apps that support both tiled and floating)\n */\nexport function setupToggleModeButton(): void {\n const toggleBtn = document.getElementById(\"eden-toggle-mode-btn\");\n if (!toggleBtn) return;\n\n toggleBtn.addEventListener(\"click\", () => {\n const toggleMode = () => {\n const appId = window.edenFrame?._internal.appId;\n\n if (appId) {\n window.edenAPI\n .shellCommand(\"view/toggle-view-mode\", {\n appId,\n })\n .then(() => {\n console.log(\"[Eden Frame] View mode toggled\");\n })\n .catch(console.error);\n } else {\n setTimeout(toggleMode, 100);\n }\n };\n toggleMode();\n });\n}\n", "/**\n * App Frame Utilities\n *\n * Shared utility functions for the app frame\n */\n\n/**\n * Get screen coordinates from mouse or touch event\n * @param e - The event\n * @returns Screen coordinates\n */\nexport function getScreenCoords(e: MouseEvent | TouchEvent): {\n x: number;\n y: number;\n} {\n // For mouse events, use screenX/screenY directly\n if (\"screenX\" in e && e.screenX !== undefined && e.screenY !== undefined) {\n return { x: e.screenX, y: e.screenY };\n }\n\n // For touch events, calculate screen coordinates from client coordinates\n if (\"touches\" in e && e.touches && e.touches[0]) {\n const touch = e.touches[0];\n // Try touch.screenX/screenY first (if available)\n if (touch.screenX !== undefined && touch.screenY !== undefined) {\n return { x: touch.screenX, y: touch.screenY };\n }\n // Fallback: calculate from clientX/clientY + view bounds position\n // Use currentBounds which has the actual view position\n const currentBounds = window.edenFrame?._internal.bounds;\n if (currentBounds) {\n return {\n x: currentBounds.x + touch.clientX,\n y: currentBounds.y + touch.clientY,\n };\n }\n // Last resort: use window.screenX/screenY\n return {\n x: touch.clientX + (window.screenX || 0),\n y: touch.clientY + (window.screenY || 0),\n };\n }\n\n return { x: 0, y: 0 };\n}\n", "/**\n * Window Dragging\n *\n * Handles dragging for floating windows\n */\n\nimport { getScreenCoords } from \"./utils\";\n\n/**\n * Setup window dragging for floating windows\n * @param overlay - The title bar overlay element\n * @param currentBoundsRef - Reference object containing current bounds\n */\nexport function setupWindowDragging(\n overlay: HTMLElement,\n currentBoundsRef: {\n current: { x: number; y: number; width: number; height: number } | null;\n }\n): void {\n let isDragging = false;\n let startX = 0;\n let startY = 0;\n let dragStartBounds: {\n x: number;\n y: number;\n width: number;\n height: number;\n } | null = null;\n let isTouch = false;\n let rafId: number | null = null;\n let pendingBounds: {\n x: number;\n y: number;\n width: number;\n height: number;\n } | null = null;\n\n // Animation frame update function - throttles IPC to 60fps\n const updatePosition = () => {\n const appId = window.edenFrame?._internal.appId;\n if (pendingBounds && appId) {\n window.edenAPI\n .shellCommand(\"view/update-view-bounds\", {\n appId,\n bounds: pendingBounds,\n })\n .catch(console.error);\n\n pendingBounds = null;\n }\n\n if (isDragging) {\n rafId = requestAnimationFrame(updatePosition);\n }\n };\n\n const startDrag = (e: MouseEvent | TouchEvent) => {\n // Only drag on the title bar itself, not on buttons\n if ((e.target as HTMLElement).closest(\".eden-app-frame-button\")) {\n return;\n }\n\n console.log(\"[Eden Frame] startDrag called, event type:\", e.type);\n console.log(\n \"[Eden Frame] currentBounds before refresh:\",\n currentBoundsRef.current\n );\n\n // ALWAYS refresh currentBounds at start to handle case where mouse drag updated position\n const initialBounds = window.edenFrame?._internal.bounds;\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n console.log(\n \"[Eden Frame] Refreshed currentBounds from edenFrame._internal.bounds:\",\n currentBoundsRef.current\n );\n } else if (!currentBoundsRef.current) {\n console.warn(\n \"[Eden Frame] Cannot start drag - currentBounds not initialized!\"\n );\n return;\n }\n\n isDragging = true;\n isTouch = e.type.startsWith(\"touch\");\n\n // Get screen coordinates\n const coords = getScreenCoords(e);\n startX = coords.x;\n startY = coords.y;\n dragStartBounds = { ...currentBoundsRef.current };\n\n console.log(\"[Eden Frame] Drag started at:\", coords, \"isTouch:\", isTouch);\n\n // IMPORTANT: Prevent default FIRST to stop touch from being canceled\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n // Start animation frame loop for smooth updates\n if (isTouch) {\n rafId = requestAnimationFrame(updatePosition);\n }\n\n const appId = window.edenFrame?._internal.appId;\n\n // Bring window to front - but ONLY for mouse events\n // For touch, calling focus-app during the touch causes view reordering which triggers touchcancel\n // Touch users need to tap elsewhere to focus, then tap title bar to drag\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/focus-app\", { appId })\n .catch(console.error);\n }\n\n // For mouse events, use global tracking in main process\n // For touch events, we'll handle updates in touchmove\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/start-drag\", {\n appId,\n startX: coords.x,\n startY: coords.y,\n })\n .catch(console.error);\n }\n\n // Add mouseup listener when drag starts (removed when drag ends)\n if (!isTouch) {\n window.addEventListener(\"mouseup\", endDrag);\n }\n };\n\n const moveDrag = (e: MouseEvent | TouchEvent) => {\n // Prevent default immediately\n e.preventDefault();\n e.stopPropagation();\n\n if (!isDragging || !dragStartBounds) {\n return;\n }\n\n // Get current coordinates\n const coords = getScreenCoords(e);\n const deltaX = coords.x - startX;\n const deltaY = coords.y - startY;\n\n const newBounds = {\n x: dragStartBounds.x + deltaX,\n y: dragStartBounds.y + deltaY,\n width: dragStartBounds.width,\n height: dragStartBounds.height,\n };\n\n // Update tracked bounds immediately for next move calculation\n currentBoundsRef.current = newBounds;\n\n // Store pending update for next animation frame\n pendingBounds = newBounds;\n };\n\n const endDrag = (e: MouseEvent | TouchEvent) => {\n // For touch events, only end if there are no remaining touches\n if (\n e.type.startsWith(\"touch\") &&\n (e as TouchEvent).touches &&\n (e as TouchEvent).touches.length > 0\n ) {\n return;\n }\n\n if (!isDragging) {\n return;\n }\n\n console.log(\n \"[Eden Frame] Drag ended, final currentBounds:\",\n currentBoundsRef.current\n );\n isDragging = false;\n dragStartBounds = null;\n\n // Remove mouseup listener since drag is done\n window.removeEventListener(\"mouseup\", endDrag);\n\n const appId = window.edenFrame?._internal.appId;\n\n // Cancel animation frame and send final position\n if (rafId) {\n cancelAnimationFrame(rafId);\n rafId = null;\n\n // Send final pending bounds immediately\n if (pendingBounds && appId) {\n window.edenAPI\n .shellCommand(\"view/update-view-bounds\", {\n appId,\n bounds: pendingBounds,\n })\n .catch(console.error);\n\n // Update edenFrame._internal.bounds so next interaction starts from correct position\n window.edenFrame!._internal.bounds = { ...pendingBounds };\n pendingBounds = null;\n }\n }\n\n // For touch drag, ensure edenFrame._internal.bounds is updated with final position\n if (isTouch && currentBoundsRef.current) {\n window.edenFrame!._internal.bounds = { ...currentBoundsRef.current };\n console.log(\n \"[Eden Frame] Updated edenFrame._internal.bounds after touch drag:\",\n window.edenFrame?._internal.bounds\n );\n }\n\n // Stop global drag tracking in main process (for mouse events)\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/end-drag\", { appId })\n .catch(console.error);\n }\n };\n\n // Mouse events\n overlay.addEventListener(\"mousedown\", startDrag);\n\n // Touch events - don't use capture for start, do use for move\n overlay.addEventListener(\"touchstart\", startDrag, { passive: false });\n\n // Move events for touch (mouse uses main process tracking)\n // Use capture for move to ensure we get it\n document.addEventListener(\"touchmove\", moveDrag as EventListener, {\n passive: false,\n capture: true,\n });\n\n // Touch end/cancel events (mouseup is added dynamically when drag starts)\n document.addEventListener(\"touchend\", endDrag, { passive: false });\n document.addEventListener(\"touchcancel\", endDrag, { passive: false });\n\n console.log(\"[Eden Frame] Drag event listeners registered\");\n}\n", "/**\n * Window Resizing\n *\n * Handles resizing for floating windows\n */\n\nimport { getScreenCoords } from \"./utils.js\";\n\ninterface Bounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ninterface BoundsRef {\n current: Bounds | null;\n}\n\n/**\n * Setup window resizing for floating windows\n */\n/**\n * Setup window resizing for floating windows\n */\nexport function setupWindowResizing(\n windowConfig: NonNullable<Window[\"edenFrame\"]>[\"_internal\"][\"config\"],\n currentBoundsRef: BoundsRef\n): void {\n // Create resize handle in bottom-right corner\n const resizeHandle = document.createElement(\"div\");\n resizeHandle.id = \"eden-resize-handle\";\n resizeHandle.style.cssText = `\n position: fixed;\n bottom: 0;\n right: 0;\n width: 20px;\n height: 20px;\n cursor: nwse-resize;\n z-index: 2147483647;\n -webkit-app-region: no-drag;\n touch-action: none;\n `;\n\n document.body.appendChild(resizeHandle);\n\n let isResizing = false;\n let startX = 0;\n let startY = 0;\n let resizeStartBounds: Bounds | null = null;\n let isTouch = false;\n let rafId: number | null = null;\n let pendingBounds: Bounds | null = null;\n\n // Animation frame update function - throttles IPC to 60fps\n const updateResizePosition = () => {\n const appId = window.edenFrame?._internal.appId;\n if (pendingBounds && appId) {\n window.edenAPI\n .shellCommand(\"view/update-view-bounds\", {\n appId,\n bounds: pendingBounds,\n })\n .catch(console.error);\n\n pendingBounds = null;\n }\n\n if (isResizing) {\n rafId = requestAnimationFrame(updateResizePosition);\n }\n };\n\n const startResize = (e: MouseEvent | TouchEvent): void => {\n console.log(\"[Eden Frame] startResize called, event type:\", e.type);\n\n // Initialize current bounds if not set\n if (!currentBoundsRef.current) {\n const initialBounds = window.edenFrame?._internal.bounds;\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n console.log(\n \"[Eden Frame] Initialized currentBounds from edenFrame._internal.bounds:\",\n currentBoundsRef.current\n );\n } else {\n console.warn(\n \"[Eden Frame] Cannot start resize - currentBounds not initialized!\"\n );\n return;\n }\n }\n\n isResizing = true;\n isTouch = e.type.startsWith(\"touch\");\n\n // Get screen coordinates\n const coords = getScreenCoords(e);\n startX = coords.x;\n startY = coords.y;\n resizeStartBounds = { ...currentBoundsRef.current };\n\n console.log(\"[Eden Frame] Resize started at:\", coords, \"isTouch:\", isTouch);\n\n e.preventDefault();\n e.stopPropagation();\n\n // Start animation frame loop for smooth updates\n if (isTouch) {\n rafId = requestAnimationFrame(updateResizePosition);\n }\n\n const appId = window.edenFrame?._internal.appId;\n\n // Bring window to front - but ONLY for mouse events\n // For touch, calling focus-app during the touch causes view reordering which triggers touchcancel\n // Touch users need to tap elsewhere to focus, then tap resize handle\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/focus-app\", { appId })\n .catch(console.error);\n }\n\n // For mouse events, use global tracking in main process\n // For touch events, we'll handle updates in touchmove\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/start-resize\", {\n appId,\n startX: coords.x,\n startY: coords.y,\n })\n .catch(console.error);\n }\n\n // Add mouseup listener when resize starts (removed when resize ends)\n if (!isTouch) {\n window.addEventListener(\"mouseup\", endResize);\n }\n };\n\n const moveResize = (e: MouseEvent | TouchEvent): void => {\n console.log(\n \"[Eden Frame] moveResize called, isResizing:\",\n isResizing,\n \"event type:\",\n e.type\n );\n\n e.preventDefault();\n e.stopPropagation();\n\n if (!isResizing || !resizeStartBounds) {\n console.log(\n \"[Eden Frame] moveResize returning early - isResizing:\",\n isResizing,\n \"resizeStartBounds:\",\n resizeStartBounds\n );\n return;\n }\n\n // Get current coordinates\n const coords = getScreenCoords(e);\n const deltaX = coords.x - startX;\n const deltaY = coords.y - startY;\n\n console.log(\"[Eden Frame] moveResize coords:\", coords, \"delta:\", {\n deltaX,\n deltaY,\n });\n\n let newWidth = resizeStartBounds.width + deltaX;\n let newHeight = resizeStartBounds.height + deltaY;\n\n // Apply min/max constraints\n if (windowConfig.minSize) {\n newWidth = Math.max(newWidth, windowConfig.minSize.width || 200);\n newHeight = Math.max(newHeight, windowConfig.minSize.height || 200);\n } else {\n newWidth = Math.max(newWidth, 200);\n newHeight = Math.max(newHeight, 200);\n }\n\n if (windowConfig.maxSize) {\n newWidth = Math.min(newWidth, windowConfig.maxSize.width || 2000);\n newHeight = Math.min(newHeight, windowConfig.maxSize.height || 2000);\n }\n\n const newBounds = {\n x: resizeStartBounds.x,\n y: resizeStartBounds.y,\n width: Math.round(newWidth),\n height: Math.round(newHeight),\n };\n\n console.log(\"[Eden Frame] moveResize newBounds:\", newBounds);\n\n // Update tracked bounds immediately for next move calculation\n currentBoundsRef.current = newBounds;\n\n // Store pending update for next animation frame\n pendingBounds = newBounds;\n };\n\n const endResize = (e?: MouseEvent | TouchEvent): void => {\n if (!isResizing) {\n return;\n }\n\n console.log(\n \"[Eden Frame] Resize ended, final currentBounds:\",\n currentBoundsRef.current\n );\n isResizing = false;\n resizeStartBounds = null;\n\n // Remove mouseup listener since resize is done\n window.removeEventListener(\"mouseup\", endResize);\n\n const appId = window.edenFrame?._internal.appId;\n\n // Cancel animation frame and send final position\n if (rafId) {\n cancelAnimationFrame(rafId);\n rafId = null;\n\n // Send final pending bounds immediately\n if (pendingBounds && appId) {\n window.edenAPI\n .shellCommand(\"view/update-view-bounds\", {\n appId,\n bounds: pendingBounds,\n })\n .catch(console.error);\n\n // Update edenFrame._internal.bounds so next interaction starts from correct position\n window.edenFrame!._internal.bounds = { ...pendingBounds };\n pendingBounds = null;\n }\n }\n\n // For touch resize, ensure edenFrame._internal.bounds is updated with final position\n if (isTouch && currentBoundsRef.current) {\n window.edenFrame!._internal.bounds = { ...currentBoundsRef.current };\n console.log(\n \"[Eden Frame] Updated edenFrame._internal.bounds after touch resize:\",\n window.edenFrame?._internal.bounds\n );\n }\n\n // Stop global resize tracking in main process (for mouse events)\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/end-resize\", { appId })\n .catch(console.error);\n }\n };\n\n // Mouse events\n resizeHandle.addEventListener(\"mousedown\", startResize);\n\n // Touch events\n resizeHandle.addEventListener(\"touchstart\", startResize, { passive: false });\n\n // Move events for touch (mouse uses main process tracking)\n // Use document and capture to ensure we get all touch moves\n document.addEventListener(\"touchmove\", moveResize, {\n passive: false,\n capture: true,\n });\n\n // Touch end/cancel events (mouseup is added dynamically when resize starts)\n document.addEventListener(\"touchend\", endResize, { passive: false });\n document.addEventListener(\"touchcancel\", endResize, { passive: false });\n\n console.log(\"[Eden Frame] Resize event listeners registered\");\n}\n", "/**\n * Eden App Frame Injector\n *\n * Main orchestrator for the app frame system.\n * This script is injected into every app to add a title bar with controls.\n */\n\nimport {\n createOverlay,\n injectOverlay,\n setupDarkMode,\n setTitle,\n getAppName,\n} from \"./ui-builder.js\";\nimport {\n setupCloseButton,\n setupMinimizeButton,\n setupToggleModeButton,\n} from \"./button-handlers.js\";\nimport { setupWindowDragging } from \"./window-dragging.js\";\nimport { setupWindowResizing } from \"./window-resizing.js\";\n\n(function () {\n console.log(\"[Eden Frame] Injection script started\");\n\n // Initialize edenFrame object if not exists\n if (!window.edenFrame) {\n window.edenFrame = {\n setTitle: (title: string) => {\n /* will be set later */\n },\n _internal: {\n appId: \"\",\n injected: false,\n config: {},\n currentMode: \"tiled\",\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n },\n };\n }\n\n // Check if already injected\n if (window.edenFrame._internal.injected) {\n console.log(\"[Eden Frame] Already injected, skipping\");\n return;\n }\n window.edenFrame._internal.injected = true;\n\n let appId: string | null = null;\n let appName: string = \"App\";\n\n // Track current window bounds for floating windows\n // Using an object reference so we can update it and have the change reflected in all modules\n const currentBoundsRef: {\n current: { x: number; y: number; width: number; height: number } | null;\n } = { current: null };\n\n // Create the overlay\n const overlay = createOverlay(window.edenFrame._internal.config);\n\n // Setup handlers after overlay is injected\n const setupHandlers = (): void => {\n // Get appId from injected config\n if (window.edenFrame && window.edenFrame._internal.appId) {\n appId = window.edenFrame._internal.appId;\n appName = getAppName(appId);\n setTitle(appName);\n }\n\n // Setup button handlers\n setupCloseButton();\n setupMinimizeButton();\n setupToggleModeButton();\n\n // Setup floating window controls\n setupFloatingWindowControls();\n\n window.edenAPI.subscribe(\n \"view/mode-changed\",\n (data: { mode: \"tiled\" | \"floating\"; bounds: any }) => {\n const { mode, bounds } = data;\n console.log(\n \"[Eden Frame] View mode changed to:\",\n mode,\n \"with bounds:\",\n bounds\n );\n\n // Update window mode and bounds\n window.edenFrame!._internal.currentMode = mode;\n if (bounds && bounds.x !== undefined) {\n window.edenFrame!._internal.bounds = bounds;\n currentBoundsRef.current = { ...bounds };\n }\n\n // Re-setup controls for new mode\n setupFloatingWindowControls();\n }\n );\n console.log(\"[Eden Frame] Subscribed to view/mode-changed\");\n };\n\n const setupFloatingWindowControls = (): void => {\n const windowMode = window.edenFrame!._internal.currentMode;\n const windowConfig = window.edenFrame!._internal.config;\n const initialBounds = window.edenFrame!._internal.bounds;\n\n console.log(\n \"[Eden Frame] Window mode:\",\n windowMode,\n \"Config:\",\n windowConfig,\n \"Initial bounds:\",\n initialBounds\n );\n\n // Only enable dragging/resizing for floating windows\n if (windowMode !== \"floating\") {\n return;\n }\n\n // Initialize current bounds from the actual bounds set by ViewManager\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n console.log(\n \"[Eden Frame] Initialized bounds from backend:\",\n currentBoundsRef.current\n );\n } else if (windowConfig.defaultSize) {\n // Fallback to config if no initial bounds provided\n const workspaceX = 0;\n const workspaceY = 0;\n\n const x = windowConfig.defaultPosition?.x || 0;\n const y = windowConfig.defaultPosition?.y || 0;\n\n currentBoundsRef.current = {\n x: workspaceX + x,\n y: workspaceY + y,\n width: windowConfig.defaultSize.width || 800,\n height: windowConfig.defaultSize.height || 600,\n };\n\n console.log(\n \"[Eden Frame] Initialized bounds from config:\",\n currentBoundsRef.current\n );\n }\n\n // Check if dragging is allowed\n const isMovable = windowConfig.movable !== false; // default true\n const isResizable = windowConfig.resizable !== false; // default true\n\n console.log(\"[Eden Frame] Movable:\", isMovable, \"Resizable:\", isResizable);\n\n // Setup window dragging\n if (isMovable) {\n setupWindowDragging(overlay, currentBoundsRef);\n }\n\n // Setup window resizing\n if (isResizable) {\n setupWindowResizing(windowConfig, currentBoundsRef);\n }\n };\n\n // Listen for bounds updates from main process (during mouse drag/resize)\n // This keeps currentBounds in sync even when main process is controlling movement\n window.edenAPI.subscribe(\"view/bounds-updated\", (newBounds) => {\n currentBoundsRef.current = { ...newBounds };\n window.edenFrame!._internal.bounds = { ...newBounds };\n });\n console.log(\"[Eden Frame] Subscribed to view/bounds-updated\");\n\n // Add global touch handler to diagnose issues\n document.addEventListener(\n \"touchstart\",\n (e) => {\n console.log(\"[Eden Frame] Global touchstart on:\", e.target);\n },\n { passive: false, capture: true }\n );\n\n document.addEventListener(\n \"touchcancel\",\n (e) => {\n console.log(\"[Eden Frame] Global touchcancel on:\", e.target);\n console.log(\"[Eden Frame] Stack trace:\", new Error().stack);\n },\n { capture: true }\n );\n\n // Inject overlay and setup handlers\n injectOverlay(overlay, () => {\n setupDarkMode(overlay);\n setupHandlers();\n });\n\n // Expose API for apps to update the title\n window.edenFrame.setTitle = (title: string) => {\n setTitle(title);\n };\n})();\n"],
5
+ "mappings": "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",
6
+ "names": ["createOverlay", "windowConfig", "overlay", "supportsToggle", "showTitle", "toggleButtonHtml", "titleHtml", "injectOverlay", "callback", "inject", "setupDarkMode", "prefersDark", "updateTheme", "e", "setTitle", "title", "titleEl", "getAppName", "appId", "parts", "name", "setupCloseButton", "closeBtn", "stopApp", "appId", "setupMinimizeButton", "minBtn", "minimize", "setupToggleModeButton", "toggleBtn", "toggleMode", "getScreenCoords", "e", "touch", "currentBounds", "setupWindowDragging", "overlay", "currentBoundsRef", "isDragging", "startX", "startY", "dragStartBounds", "isTouch", "rafId", "pendingBounds", "updatePosition", "appId", "startDrag", "e", "initialBounds", "coords", "getScreenCoords", "endDrag", "moveDrag", "deltaX", "deltaY", "newBounds", "setupWindowResizing", "windowConfig", "currentBoundsRef", "resizeHandle", "isResizing", "startX", "startY", "resizeStartBounds", "isTouch", "rafId", "pendingBounds", "updateResizePosition", "appId", "startResize", "e", "initialBounds", "coords", "getScreenCoords", "endResize", "moveResize", "deltaX", "deltaY", "newWidth", "newHeight", "newBounds", "title", "appId", "appName", "currentBoundsRef", "overlay", "createOverlay", "setupHandlers", "getAppName", "setTitle", "setupCloseButton", "setupMinimizeButton", "setupToggleModeButton", "setupFloatingWindowControls", "data", "mode", "bounds", "windowMode", "windowConfig", "initialBounds", "x", "y", "isMovable", "isResizable", "setupWindowDragging", "setupWindowResizing", "newBounds", "e", "injectOverlay", "setupDarkMode"]
7
+ }
@@ -0,0 +1,186 @@
1
+ /* Eden App Frame Styles */
2
+
3
+ /* Squircle container styling */
4
+ html {
5
+ background: transparent !important;
6
+ overflow: hidden;
7
+ }
8
+
9
+ html,
10
+ body {
11
+ border-radius: 20px;
12
+ clip-path: inset(0 round 20px);
13
+ margin: 0;
14
+ padding: 0;
15
+ height: 100%;
16
+ }
17
+
18
+ body {
19
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15),
20
+ inset 0 0 0 1px rgba(0, 0, 0, 0.08);
21
+ overflow-y: auto;
22
+ overflow-x: hidden;
23
+ }
24
+
25
+ #eden-app-frame-overlay#eden-app-frame-overlay {
26
+ all: revert;
27
+ /* Now only set what we actually need */
28
+ position: fixed;
29
+ top: 0;
30
+ left: 0;
31
+ right: 0;
32
+ height: 40px;
33
+ background: transparent;
34
+ border-bottom: none;
35
+ border-radius: 20px 20px 0 0;
36
+ display: flex;
37
+ align-items: center;
38
+ justify-content: flex-end;
39
+ padding: 0 16px;
40
+ user-select: none;
41
+ z-index: 2147483647;
42
+ -webkit-app-region: no-drag;
43
+ touch-action: none;
44
+ -webkit-touch-callout: none;
45
+ -webkit-user-select: none;
46
+ pointer-events: auto;
47
+ will-change: transform;
48
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
49
+ box-sizing: border-box;
50
+ }
51
+
52
+ #eden-app-frame-overlay.dark#eden-app-frame-overlay.dark {
53
+ background: transparent;
54
+ border-bottom: none;
55
+ color: #cccccc;
56
+ }
57
+
58
+ #eden-app-frame-overlay #eden-app-frame-title {
59
+ all: revert;
60
+ /* Now only set what we actually need */
61
+ position: absolute;
62
+ left: 50%;
63
+ transform: translateX(-50%);
64
+ font-size: 14px;
65
+ font-weight: 600;
66
+ color: #333;
67
+ overflow: hidden;
68
+ text-overflow: ellipsis;
69
+ white-space: nowrap;
70
+ max-width: calc(100% - 200px);
71
+ text-align: center;
72
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
73
+ line-height: 1;
74
+ letter-spacing: -0.3px;
75
+ pointer-events: none;
76
+ background: rgba(255, 255, 255, 0.7);
77
+ backdrop-filter: blur(20px) saturate(180%);
78
+ padding: 8px 16px;
79
+ border-radius: 10px;
80
+ height: 32px;
81
+ display: flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ box-sizing: border-box;
85
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1),
86
+ inset 0 1px 0 rgba(255, 255, 255, 0.5);
87
+ }
88
+
89
+ #eden-app-frame-overlay.dark #eden-app-frame-title {
90
+ color: #ffffff;
91
+ background: rgba(40, 40, 40, 0.7);
92
+ backdrop-filter: blur(20px) saturate(180%);
93
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3),
94
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
95
+ }
96
+
97
+ #eden-app-frame-overlay #eden-app-frame-controls {
98
+ all: revert;
99
+ /* Now only set what we actually need */
100
+ display: flex;
101
+ gap: 8px;
102
+ -webkit-app-region: no-drag;
103
+ align-items: center;
104
+ background: rgba(255, 255, 255, 0.7);
105
+ backdrop-filter: blur(20px) saturate(180%);
106
+ padding: 4px;
107
+ border-radius: 10px;
108
+ height: 32px;
109
+ box-sizing: border-box;
110
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1),
111
+ inset 0 1px 0 rgba(255, 255, 255, 0.5);
112
+ }
113
+
114
+ #eden-app-frame-overlay.dark #eden-app-frame-controls {
115
+ background: rgba(40, 40, 40, 0.7);
116
+ backdrop-filter: blur(20px) saturate(180%);
117
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3),
118
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
119
+ }
120
+
121
+ #eden-app-frame-overlay .eden-app-frame-button {
122
+ all: revert;
123
+ /* Now only set what we actually need */
124
+ width: 24px;
125
+ height: 24px;
126
+ min-width: 24px;
127
+ min-height: 24px;
128
+ max-width: 24px;
129
+ max-height: 24px;
130
+ border: none;
131
+ border-radius: 6px;
132
+ background: transparent;
133
+ cursor: pointer;
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+ font-size: 16px;
138
+ transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
139
+ color: #666;
140
+ line-height: 1;
141
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
142
+ font-weight: 400;
143
+ padding: 0;
144
+ margin: 0;
145
+ box-sizing: border-box;
146
+ flex-shrink: 0;
147
+ }
148
+
149
+ #eden-app-frame-overlay.dark .eden-app-frame-button {
150
+ color: #aaa;
151
+ }
152
+
153
+ #eden-app-frame-overlay .eden-app-frame-button:hover {
154
+ background: rgba(0, 0, 0, 0.08);
155
+ transform: scale(1.05);
156
+ }
157
+
158
+ #eden-app-frame-overlay.dark .eden-app-frame-button:hover {
159
+ background: rgba(255, 255, 255, 0.12);
160
+ transform: scale(1.05);
161
+ }
162
+
163
+ #eden-app-frame-overlay .eden-app-frame-button.close:hover {
164
+ background: #e81123;
165
+ color: white;
166
+ transform: scale(1.05);
167
+ }
168
+
169
+ #eden-app-frame-overlay .eden-app-frame-button:active {
170
+ transform: scale(0.95);
171
+ }
172
+
173
+ #eden-app-frame-overlay .eden-app-frame-button.minimize {
174
+ font-size: 20px;
175
+ font-weight: 300;
176
+ }
177
+
178
+ #eden-app-frame-overlay .eden-app-frame-button.close {
179
+ font-size: 20px;
180
+ font-weight: 400;
181
+ }
182
+
183
+ /* Adjust body to account for title bar */
184
+ body.eden-framed.eden-framed {
185
+ padding-top: 41px;
186
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var f=require("electron");function y(e){let t=new Map,r=new Set;return{postMessage:n=>e.postMessage(n),on:((n,i)=>{if(n==="message"){let o=p=>i({data:p.data});t.set(i,o),e.addEventListener("message",o)}else n==="close"&&r.add(i)}),off:((n,i)=>{if(n==="message"){let o=t.get(i);o&&(e.removeEventListener("message",o),t.delete(i))}else n==="close"&&r.delete(i)}),start:()=>e.start(),close:()=>{e.close(),r.forEach(n=>{try{n()}catch(i){console.error("[IPCPort] Error in close listener:",i)}}),r.clear()}}}function m(e="msg"){let t=0;return()=>`${e}-${Date.now()}-${++t}`}function I(e="appbus"){return{registeredServices:new Map,connectedPorts:new Map,pendingRequests:new Map,pendingPortArrivals:new Map,messageIdGenerator:m(e)}}function h(e,t,r=5e3){let n=t.connectedPorts.get(e);return n?Promise.resolve(n):new Promise((i,o)=>{let p=setTimeout(()=>{t.pendingPortArrivals.delete(e),o(new Error(`Port for connection ${e} not received within ${r}ms`))},r);t.pendingPortArrivals.set(e,{resolve:s=>{clearTimeout(p),i(s)},reject:s=>{clearTimeout(p),o(s)}})})}function R(e){let{port:t,connectionId:r,portStore:n,pendingRequests:i,pendingPortArrivals:o}=e;if(n.set(r,t),o){let p=o.get(r);p&&(o.delete(r),p.resolve(t))}t.on("message",p=>{let{type:s,messageId:a,payload:l,error:d}=p.data;if(s==="response"&&a){let c=i.get(a);c&&(i.delete(a),d?c.reject(new Error(d)):c.resolve(l))}}),t.start()}function v(e,t,r,n,i){let o=new Map,p=new Map;return r.set(t,e),e.on("message",s=>{let{type:a,method:l,payload:d,messageId:c}=s.data;if(a==="message"){let g=o.get(l);g&&g.forEach(u=>{try{u(d)}catch(P){console.error(`[PortConnection] Error in on('${l}') listener:`,P)}})}else if(a==="request"){let g=p.get(l);if(g)try{let u=g(d);Promise.resolve(u).then(P=>{e.postMessage({type:"response",messageId:c,payload:P})}).catch(P=>{e.postMessage({type:"response",messageId:c,error:P instanceof Error?P.message:String(P)})})}catch(u){e.postMessage({type:"response",messageId:c,error:u instanceof Error?u.message:String(u)})}else e.postMessage({type:"response",messageId:c,error:`No handler registered for method '${l}'`})}else if(a==="response"&&c){let g=n.get(c);g&&(n.delete(c),s.data.error?g.reject(new Error(s.data.error)):g.resolve(d))}}),e.start(),{send:(s,a)=>{e.postMessage({type:"message",method:s,payload:a})},on:(s,a)=>{if(typeof a!="function")throw new Error("Callback must be a function");o.has(s)||o.set(s,new Set),o.get(s).add(a)},once:(s,a)=>{if(typeof a!="function")throw new Error("Callback must be a function");let l=d=>{let c=o.get(s);c&&(c.delete(l),c.size===0&&o.delete(s)),a(d)};o.has(s)||o.set(s,new Set),o.get(s).add(l)},off:(s,a)=>{let l=o.get(s);l&&(l.delete(a),l.size===0&&o.delete(s))},request:(s,a,l=3e4)=>new Promise((d,c)=>{let g=i(),u=setTimeout(()=>{n.has(g)&&(n.delete(g),c(new Error(`Request '${s}' timed out`)))},l);n.set(g,{resolve:P=>{clearTimeout(u),d(P)},reject:P=>{clearTimeout(u),c(P)}}),e.postMessage({type:"request",method:s,payload:a,messageId:g})}),handle:(s,a)=>{if(typeof a!="function")throw new Error("Handler must be a function");if(p.has(s))throw new Error(`Handler already registered for method '${s}'`);p.set(s,a)},removeHandler:s=>{p.delete(s)},isConnected:()=>r.has(t),onClose:s=>{e.on("close",s)},close:()=>{r.delete(t),o.clear(),p.clear(),e.close()}}}function M(e,t,r,n="[AppBus]"){let{connectionId:i,role:o,serviceName:p,targetAppId:s,sourceAppId:a}=t;if(o==="service"){console.log(`${n} Received connection from ${a} for service ${p}`);let l=r.registeredServices.get(p);if(!l){console.error(`${n} No onConnect callback registered for service "${p}"`);return}let d=v(e,i,r.connectedPorts,r.pendingRequests,r.messageIdGenerator);try{l(d,{appId:a||"unknown"})}catch(c){console.error(`${n} Error in onConnect callback for service "${p}":`,c)}}else o==="client"&&(console.log(`${n} Connected to ${s}/${p}`),R({port:e,connectionId:i,portStore:r.connectedPorts,pendingRequests:r.pendingRequests,pendingPortArrivals:r.pendingPortArrivals}))}function b(e,t){let r=e.connectedPorts.get(t);r&&(r.close(),e.connectedPorts.delete(t))}function S(e,t,r){return{shellCommand:(n,i)=>e.exec(n,i),subscribe:async(n,i)=>{if(typeof i!="function")throw new Error("Callback must be a function");await e.exec("event/subscribe",{eventName:n}),t.has(n)||t.set(n,new Set),t.get(n).add(i)},unsubscribe:async(n,i)=>{let o=t.get(n);o&&(o.delete(i),o.size===0&&(t.delete(n),await e.exec("event/unsubscribe",{eventName:n})))},isEventSupported:n=>e.exec("event/exists",{eventName:n}),getLaunchArgs:()=>r!=null&&r.getLaunchArgs?r.getLaunchArgs():[]}}function x(e,t){let{transport:r,isBackend:n}=e,{registeredServices:i,connectedPorts:o,pendingRequests:p,messageIdGenerator:s}=t;return{exposeService:async(a,l,d)=>{if(typeof l!="function")throw new Error("onConnect callback must be a function");i.set(a,l);let c=await r.exec("appbus/register",{serviceName:a,description:d==null?void 0:d.description,allowedClients:d==null?void 0:d.allowedClients,isBackend:n});return c.success||i.delete(a),c},unexposeService:async a=>(i.delete(a),r.exec("appbus/unregister",{serviceName:a})),connect:async(a,l)=>{let d=await r.exec("appbus/connect",{targetAppId:a,serviceName:l,isBackend:n});if(!d.success)return{error:d.error||"Connection failed"};let{connectionId:c}=d,g;try{g=await h(c,t,5e3)}catch(u){return{error:u instanceof Error?u.message:"MessagePort not received"}}return v(g,c,o,p,s)},listServices:async()=>r.exec("appbus/list",{}),listServicesByApp:async a=>r.exec("appbus/list-by-app",{appId:a})}}var A=null,T=null,C=null,L=new Map,_=m("backend"),k=new Map,B=process.argv.find(e=>e.startsWith("--app-id="));B?(A=B.split("=")[1],console.log(`[AppPreload] Initialized for app: ${A}`)):console.warn("[AppPreload] No app ID found in arguments");var $=[],E=process.argv.find(e=>e.startsWith("--launch-args="));if(E)try{let e=E.split("=").slice(1).join("=");$=JSON.parse(e)}catch(e){console.error("[AppPreload] Failed to parse launch args:",e)}f.ipcRenderer.on("backend-port",e=>{let[t]=e.ports;if(!t){console.error("[AppPreload] Received backend-port event without port");return}T=t,console.log(`[AppPreload] Backend port received for app ${A}`);let r=y(t);C=v(r,"__backend__",new Map([["__backend__",r]]),L,_)});f.ipcRenderer.on("shell-message",(e,t)=>{let{type:r,payload:n}=t,i=k.get(r);i&&i.forEach(o=>{try{o(n)}catch(p){console.error(`Error in event listener for ${r}:`,p)}})});f.contextBridge.exposeInMainWorld("getAppAPI",()=>{if(!C)throw new Error("AppAPI not available: Backend not connected. This could mean the app has no backend, or the connection is not yet established.");return C});var q={exec:(e,t)=>f.ipcRenderer.invoke("shell-command",e,t)};f.contextBridge.exposeInMainWorld("edenAPI",S(q,k,{getLaunchArgs:()=>$}));var w=I("appbus");f.ipcRenderer.on("appbus-port",(e,t)=>{let[r]=e.ports;if(!r){console.error("[AppBus] Received appbus-port event without port");return}let n=y(r);M(n,t,w,"[AppBus]")});f.ipcRenderer.on("appbus-port-closed",(e,t)=>{b(w,t.connectionId)});f.contextBridge.exposeInMainWorld("appBus",x({transport:q},w));console.log("Universal app preload loaded");
2
+ //# sourceMappingURL=app-preload.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/app-runtime/app-preload.ts", "../../src/app-runtime/common/ipc-port.ts", "../../src/app-runtime/common/port-channel.ts", "../../src/app-runtime/common/api-factory.ts"],
4
+ "sourcesContent": ["import { contextBridge, ipcRenderer } from \"electron\";\nimport type {\n AppBusConnection,\n ServiceConnectCallback,\n} from \"@edenapp/types/ipc/appbus\";\nimport {\n type PendingRequest,\n type IPCPort,\n createMessageIdGenerator,\n handleAppBusPort,\n createPortConnection,\n createAppBusState,\n wrapDOMPort,\n handlePortClosed,\n} from \"./common/port-channel\";\nimport {\n createEdenAPI,\n createAppBusAPI,\n type ShellTransport,\n} from \"./common/api-factory\";\n\n// Per-app state\nlet appId: string | null = null;\n\n// MessagePort for direct frontend<->backend communication\nlet backendPort: MessagePort | null = null;\nlet backendConnection: AppBusConnection | null = null;\n\n// Pending requests waiting for responses (for backend communication)\nconst pendingBackendRequests: Map<string, PendingRequest> = new Map();\n\n// Message ID generator for backend communication\nconst generateBackendMessageId = createMessageIdGenerator(\"backend\");\n\n// Event subscription system\nconst eventSubscriptions: Map<string, Set<Function>> = new Map();\n\n// Extract appId from process arguments\n// Arguments are passed as --app-id=com.example.app\nconst appIdArg = process.argv.find((arg) => arg.startsWith(\"--app-id=\"));\nif (appIdArg) {\n appId = appIdArg.split(\"=\")[1];\n console.log(`[AppPreload] Initialized for app: ${appId}`);\n} else {\n console.warn(\"[AppPreload] No app ID found in arguments\");\n}\n\n// Extract launch args\nlet launchArgs: string[] = [];\nconst launchArgsArg = process.argv.find((arg) =>\n arg.startsWith(\"--launch-args=\")\n);\nif (launchArgsArg) {\n try {\n const jsonStr = launchArgsArg.split(\"=\").slice(1).join(\"=\");\n launchArgs = JSON.parse(jsonStr);\n } catch (e) {\n console.error(\"[AppPreload] Failed to parse launch args:\", e);\n }\n}\n\n// Handle receiving the backend MessagePort\nipcRenderer.on(\"backend-port\", (event: any) => {\n const [port] = event.ports as MessagePort[];\n if (!port) {\n console.error(\"[AppPreload] Received backend-port event without port\");\n return;\n }\n\n backendPort = port;\n console.log(`[AppPreload] Backend port received for app ${appId}`);\n\n // Wrap DOM MessagePort to IPCPort interface\n const wrappedPort = wrapDOMPort(port);\n\n // Create connection object - handles all message routing internally\n backendConnection = createPortConnection(\n wrappedPort,\n \"__backend__\",\n new Map([[\"__backend__\", wrappedPort]]), // Dummy map since we won't close this\n pendingBackendRequests,\n generateBackendMessageId\n );\n});\n\n// Set up unified message listener for shell-message channel\nipcRenderer.on(\"shell-message\", (_event: any, message: any) => {\n const { type, payload } = message;\n const callbacks = eventSubscriptions.get(type);\n\n if (callbacks) {\n callbacks.forEach((callback) => {\n try {\n callback(payload);\n } catch (err) {\n console.error(`Error in event listener for ${type}:`, err);\n }\n });\n }\n});\n\n// Expose safe API to the app\ncontextBridge.exposeInMainWorld(\"getAppAPI\", () => {\n if (!backendConnection) {\n throw new Error(\n \"AppAPI not available: Backend not connected. \" +\n \"This could mean the app has no backend, or the connection is not yet established.\"\n );\n }\n return backendConnection;\n});\n\n// ===================================================================\n// Shared API Implementation\n// ===================================================================\n\n// Shell transport implementation using ipcRenderer\nconst shellTransport: ShellTransport = {\n exec: (command: string, args: any) => {\n return ipcRenderer.invoke(\"shell-command\", command, args);\n },\n};\n\n// Expose edenAPI for shell commands and event subscriptions\ncontextBridge.exposeInMainWorld(\n \"edenAPI\",\n createEdenAPI(shellTransport, eventSubscriptions, {\n getLaunchArgs: () => launchArgs,\n })\n);\n\n// ===================================================================\n// AppBus - App-to-App Communication System\n// ===================================================================\n\nconst appBusState = createAppBusState(\"appbus\");\n\n// Handle incoming MessagePorts for peer-to-peer channels\nipcRenderer.on(\"appbus-port\", (event: any, data: any) => {\n const [port] = event.ports as MessagePort[];\n if (!port) {\n console.error(\"[AppBus] Received appbus-port event without port\");\n return;\n }\n\n // Wrap DOM MessagePort to IPCPort interface\n const wrappedPort = wrapDOMPort(port);\n\n handleAppBusPort(wrappedPort, data, appBusState, \"[AppBus]\");\n});\n\n// Handle port closed notification\nipcRenderer.on(\n \"appbus-port-closed\",\n (_event: any, data: { connectionId: string }) => {\n handlePortClosed(appBusState, data.connectionId);\n }\n);\n\n// Expose appBus API for app-to-app communication\ncontextBridge.exposeInMainWorld(\n \"appBus\",\n createAppBusAPI({ transport: shellTransport }, appBusState)\n);\n\nconsole.log(\"Universal app preload loaded\");\n", "/**\n * IPC Port - Unified interface for MessagePort communication\n *\n * Provides a common interface for both:\n * - DOM MessagePort (frontend/preload)\n * - Electron MessagePortMain (backend utility process)\n */\n\n/**\n * Unified interface for both DOM MessagePort and Electron MessagePortMain\n */\nexport interface IPCPort {\n postMessage(message: any): void;\n on(event: \"message\", listener: (event: { data: any }) => void): void;\n on(event: \"close\", listener: () => void): void;\n off(event: \"message\", listener: (event: { data: any }) => void): void;\n off(event: \"close\", listener: () => void): void;\n start(): void;\n close(): void;\n}\n\n/**\n * Wrap a DOM MessagePort to conform to IPCPort interface\n */\nexport function wrapDOMPort(port: MessagePort): IPCPort {\n const messageListeners = new Map<\n (event: { data: any }) => void,\n (event: MessageEvent) => void\n >();\n const closeListeners = new Set<() => void>();\n\n return {\n postMessage: (message: any) => port.postMessage(message),\n\n on: ((event: string, listener: any) => {\n if (event === \"message\") {\n // Create a wrapper that extracts data from MessageEvent\n const wrapper = (e: MessageEvent) => listener({ data: e.data });\n messageListeners.set(listener, wrapper);\n port.addEventListener(\"message\", wrapper);\n } else if (event === \"close\") {\n closeListeners.add(listener);\n }\n }) as IPCPort[\"on\"],\n\n off: ((event: string, listener: any) => {\n if (event === \"message\") {\n const wrapper = messageListeners.get(listener);\n if (wrapper) {\n port.removeEventListener(\"message\", wrapper);\n messageListeners.delete(listener);\n }\n } else if (event === \"close\") {\n closeListeners.delete(listener);\n }\n }) as IPCPort[\"off\"],\n\n start: () => port.start(),\n close: () => {\n port.close();\n // Manually trigger close listeners as DOM MessagePort doesn't emit 'close'\n closeListeners.forEach((listener) => {\n try {\n listener();\n } catch (e) {\n console.error(\"[IPCPort] Error in close listener:\", e);\n }\n });\n closeListeners.clear();\n },\n };\n}\n\n/**\n * Wrap an Electron MessagePortMain to conform to IPCPort interface\n * (MessagePortMain already uses the EventEmitter pattern)\n */\nexport function wrapElectronPort(port: Electron.MessagePortMain): IPCPort {\n return port as unknown as IPCPort;\n}\n", "/**\n * Port Channel - Shared utilities for MessagePort communication\n *\n * This module provides reusable utilities for setting up MessagePort-based\n * communication channels between frontend, backend, and AppBus connections.\n *\n * Used by:\n * - app-preload.ts (frontend)\n * - backend-preload.ts (backend)\n */\n\n// Re-export IPCPort types and wrappers\nexport { wrapDOMPort, wrapElectronPort } from \"./ipc-port\";\nexport type { IPCPort } from \"./ipc-port\";\nimport type { IPCPort } from \"./ipc-port\";\n\nimport type {\n AppBusConnection,\n ServiceConnectCallback,\n} from \"@edenapp/types/ipc/appbus\";\n\n/**\n * Pending request tracking\n */\nexport interface PendingRequest {\n resolve: (value: any) => void;\n reject: (reason: any) => void;\n}\n\n/**\n * Pending port arrival tracking\n */\nexport interface PendingPortArrival {\n resolve: (port: IPCPort) => void;\n reject: (reason: Error) => void;\n}\n\n/**\n * Options for setting up a client port\n */\nexport interface ClientPortOptions {\n port: IPCPort;\n connectionId: string;\n portStore: Map<string, IPCPort>;\n pendingRequests: Map<string, PendingRequest>;\n pendingPortArrivals?: Map<string, PendingPortArrival>;\n logPrefix?: string;\n}\n\n/**\n * Message ID generator factory\n */\nexport function createMessageIdGenerator(prefix: string = \"msg\"): () => string {\n let counter = 0;\n return () => `${prefix}-${Date.now()}-${++counter}`;\n}\n\n/**\n * AppBus state for an app\n */\nexport interface AppBusState {\n registeredServices: Map<string, ServiceConnectCallback>;\n connectedPorts: Map<string, IPCPort>;\n pendingRequests: Map<string, PendingRequest>;\n pendingPortArrivals: Map<string, PendingPortArrival>;\n messageIdGenerator: () => string;\n}\n\n/**\n * Create AppBus state for an app\n */\nexport function createAppBusState(prefix: string = \"appbus\"): AppBusState {\n return {\n registeredServices: new Map(),\n connectedPorts: new Map(),\n pendingRequests: new Map(),\n pendingPortArrivals: new Map(),\n messageIdGenerator: createMessageIdGenerator(prefix),\n };\n}\n\n/**\n * Wait for a port to arrive for a given connection ID\n *\n * @param connectionId The connection ID to wait for\n * @param state AppBus state containing connectedPorts and pendingPortArrivals\n * @param timeoutMs Timeout in milliseconds (default: 5000)\n * @returns Promise that resolves with the port or rejects on timeout\n */\nexport function waitForPort(\n connectionId: string,\n state: AppBusState,\n timeoutMs: number = 5000\n): Promise<IPCPort> {\n // Check if port is already available\n const existing = state.connectedPorts.get(connectionId);\n if (existing) {\n return Promise.resolve(existing);\n }\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n state.pendingPortArrivals.delete(connectionId);\n reject(\n new Error(\n `Port for connection ${connectionId} not received within ${timeoutMs}ms`\n )\n );\n }, timeoutMs);\n\n state.pendingPortArrivals.set(connectionId, {\n resolve: (port: IPCPort) => {\n clearTimeout(timeout);\n resolve(port);\n },\n reject: (reason: Error) => {\n clearTimeout(timeout);\n reject(reason);\n },\n });\n });\n}\n\n/**\n * Set up a MessagePort as a client (sends requests, receives responses)\n *\n * @param options Configuration for the client port\n */\nexport function setupClientPort(options: ClientPortOptions): void {\n const {\n port,\n connectionId,\n portStore,\n pendingRequests,\n pendingPortArrivals,\n } = options;\n\n // Store the port for later use\n portStore.set(connectionId, port);\n\n // Resolve any pending port arrivals waiting for this connection\n if (pendingPortArrivals) {\n const pending = pendingPortArrivals.get(connectionId);\n if (pending) {\n pendingPortArrivals.delete(connectionId);\n pending.resolve(port);\n }\n }\n\n // Set up response handler\n port.on(\"message\", (event) => {\n const { type, messageId, payload, error } = event.data;\n\n if (type === \"response\" && messageId) {\n const pending = pendingRequests.get(messageId);\n if (pending) {\n pendingRequests.delete(messageId);\n if (error) {\n pending.reject(new Error(error));\n } else {\n pending.resolve(payload);\n }\n }\n }\n });\n\n port.start();\n}\n\n/**\n * Create a connection object for a port (Electron IPC style)\n *\n * @param port The IPCPort to wrap\n * @param connectionId The connection ID\n * @param portStore The Map storing ports\n * @param pendingRequests The Map tracking pending requests for outgoing requests\n * @param generateMessageId Function to generate unique message IDs\n * @returns Connection object with send/on/off, request/handle/removeHandler, and close methods\n */\nexport function createPortConnection(\n port: IPCPort,\n connectionId: string,\n portStore: Map<string, IPCPort>,\n pendingRequests: Map<string, PendingRequest>,\n generateMessageId: () => string\n): AppBusConnection {\n // Method-specific listeners for fire-and-forget messages (send \u2192 on)\n const messageListeners: Map<string, Set<(args: any) => void>> = new Map();\n\n // Method-specific handlers for request/response (request \u2192 handle)\n const requestHandlers: Map<string, (args: any) => any | Promise<any>> =\n new Map();\n\n // Store the port for later use (cleanup, connectivity checks)\n portStore.set(connectionId, port);\n\n // Set up incoming message handler\n port.on(\"message\", (event) => {\n const { type, method, payload, messageId } = event.data;\n\n if (type === \"message\") {\n // Fire-and-forget message - dispatch to on() listeners\n const listeners = messageListeners.get(method);\n if (listeners) {\n listeners.forEach((callback) => {\n try {\n callback(payload);\n } catch (err) {\n console.error(\n `[PortConnection] Error in on('${method}') listener:`,\n err\n );\n }\n });\n }\n } else if (type === \"request\") {\n // Request expecting response - dispatch to handle() handler\n const handler = requestHandlers.get(method);\n if (handler) {\n try {\n const result = handler(payload);\n Promise.resolve(result)\n .then((response) => {\n port.postMessage({\n type: \"response\",\n messageId,\n payload: response,\n });\n })\n .catch((err) => {\n port.postMessage({\n type: \"response\",\n messageId,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n } catch (err) {\n port.postMessage({\n type: \"response\",\n messageId,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n } else {\n port.postMessage({\n type: \"response\",\n messageId,\n error: `No handler registered for method '${method}'`,\n });\n }\n } else if (type === \"response\" && messageId) {\n // Response to our outgoing request\n const pending = pendingRequests.get(messageId);\n if (pending) {\n pendingRequests.delete(messageId);\n if (event.data.error) {\n pending.reject(new Error(event.data.error));\n } else {\n pending.resolve(payload);\n }\n }\n }\n });\n\n port.start();\n\n return {\n // Fire-and-forget messaging\n send: (method: string, args?: any) => {\n port.postMessage({ type: \"message\", method, payload: args });\n },\n\n on: (method: string, callback: (args: any) => void) => {\n if (typeof callback !== \"function\") {\n throw new Error(\"Callback must be a function\");\n }\n if (!messageListeners.has(method)) {\n messageListeners.set(method, new Set());\n }\n messageListeners.get(method)!.add(callback);\n },\n\n once: (method: string, callback: (args: any) => void) => {\n if (typeof callback !== \"function\") {\n throw new Error(\"Callback must be a function\");\n }\n const wrapper = (args: any) => {\n // Remove before calling to prevent issues if callback throws\n const listeners = messageListeners.get(method);\n if (listeners) {\n listeners.delete(wrapper);\n if (listeners.size === 0) {\n messageListeners.delete(method);\n }\n }\n callback(args);\n };\n if (!messageListeners.has(method)) {\n messageListeners.set(method, new Set());\n }\n messageListeners.get(method)!.add(wrapper);\n },\n\n off: (method: string, callback: (args: any) => void) => {\n const listeners = messageListeners.get(method);\n if (listeners) {\n listeners.delete(callback);\n if (listeners.size === 0) {\n messageListeners.delete(method);\n }\n }\n },\n\n // Request/response\n request: (\n method: string,\n args?: any,\n timeout: number = 30000\n ): Promise<any> => {\n return new Promise((resolve, reject) => {\n const messageId = generateMessageId();\n\n // Timeout after specified duration\n const timeoutId = setTimeout(() => {\n if (pendingRequests.has(messageId)) {\n pendingRequests.delete(messageId);\n reject(new Error(`Request '${method}' timed out`));\n }\n }, timeout);\n\n pendingRequests.set(messageId, {\n resolve: (value) => {\n clearTimeout(timeoutId);\n resolve(value);\n },\n reject: (reason) => {\n clearTimeout(timeoutId);\n reject(reason);\n },\n });\n\n port.postMessage({\n type: \"request\",\n method,\n payload: args,\n messageId,\n });\n });\n },\n\n handle: (method: string, handler: (args: any) => any | Promise<any>) => {\n if (typeof handler !== \"function\") {\n throw new Error(\"Handler must be a function\");\n }\n if (requestHandlers.has(method)) {\n throw new Error(`Handler already registered for method '${method}'`);\n }\n requestHandlers.set(method, handler);\n },\n\n removeHandler: (method: string) => {\n requestHandlers.delete(method);\n },\n\n // Connection management\n isConnected: () => {\n return portStore.has(connectionId);\n },\n\n onClose: (callback: () => void) => {\n port.on(\"close\", callback);\n },\n\n close: () => {\n portStore.delete(connectionId);\n messageListeners.clear();\n requestHandlers.clear();\n port.close();\n },\n };\n}\n\n/**\n * Handle an incoming AppBus port (can be service or client role)\n *\n * @param port The MessagePort received\n * @param data Connection metadata\n * @param state AppBus state (services, ports, pending requests)\n * @param logPrefix Prefix for log messages\n */\nexport function handleAppBusPort(\n port: IPCPort,\n data: {\n connectionId: string;\n role: \"service\" | \"client\";\n serviceName: string;\n targetAppId?: string;\n sourceAppId?: string;\n },\n state: AppBusState,\n logPrefix: string = \"[AppBus]\"\n): void {\n const { connectionId, role, serviceName, targetAppId, sourceAppId } = data;\n\n if (role === \"service\") {\n // A client is connecting to our service\n console.log(\n `${logPrefix} Received connection from ${sourceAppId} for service ${serviceName}`\n );\n\n const onConnect = state.registeredServices.get(serviceName);\n if (!onConnect) {\n console.error(\n `${logPrefix} No onConnect callback registered for service \"${serviceName}\"`\n );\n return;\n }\n\n // Create a bidirectional AppBusConnection for the service to use\n const connection = createPortConnection(\n port,\n connectionId,\n state.connectedPorts,\n state.pendingRequests,\n state.messageIdGenerator\n );\n\n // Call the onConnect callback with the connection and client info\n try {\n onConnect(connection, { appId: sourceAppId || \"unknown\" });\n } catch (err) {\n console.error(\n `${logPrefix} Error in onConnect callback for service \"${serviceName}\":`,\n err\n );\n }\n } else if (role === \"client\") {\n // We're connecting to another app's service\n console.log(`${logPrefix} Connected to ${targetAppId}/${serviceName}`);\n\n setupClientPort({\n port,\n connectionId,\n portStore: state.connectedPorts,\n pendingRequests: state.pendingRequests,\n pendingPortArrivals: state.pendingPortArrivals,\n });\n }\n}\n/**\n * Handle a port being closed from the other side\n * Triggered by a notification from the main process\n *\n * @param state AppBus state\n * @param connectionId The ID of the closed connection\n */\nexport function handlePortClosed(\n state: AppBusState,\n connectionId: string\n): void {\n const port = state.connectedPorts.get(connectionId);\n if (port) {\n port.close();\n state.connectedPorts.delete(connectionId);\n }\n}\n", "import type {\n EdenAPI,\n AppBusAPI,\n AppBusConnection,\n ServiceInfo,\n ServiceConnectCallback,\n} from \"@edenapp/types\";\nimport type { PendingRequest, IPCPort, AppBusState } from \"./port-channel\";\nimport { createPortConnection, waitForPort } from \"./port-channel\";\n\n/**\n * Interface for sending shell commands to the main process\n */\nexport interface ShellTransport {\n exec(command: string, args: any): Promise<any>;\n}\n\n/**\n * Configuration for AppBus API\n */\nexport interface AppBusConfig {\n transport: ShellTransport;\n isBackend?: boolean;\n}\n\n/**\n * Create the EdenAPI object\n */\nexport function createEdenAPI(\n transport: ShellTransport,\n eventSubscriptions: Map<string, Set<Function>>,\n options?: { getLaunchArgs?: () => string[] }\n): EdenAPI {\n return {\n shellCommand: (command: string, args: any) => {\n return transport.exec(command, args);\n },\n\n subscribe: async (eventName: string, callback: Function) => {\n if (typeof callback !== \"function\") {\n throw new Error(\"Callback must be a function\");\n }\n\n // Register with backend/main\n await transport.exec(\"event/subscribe\", { eventName });\n\n // Register callback locally\n if (!eventSubscriptions.has(eventName)) {\n eventSubscriptions.set(eventName, new Set());\n }\n eventSubscriptions.get(eventName)!.add(callback);\n },\n\n unsubscribe: async (eventName: string, callback: Function) => {\n const callbacks = eventSubscriptions.get(eventName);\n if (callbacks) {\n callbacks.delete(callback);\n\n // If no more callbacks, unregister from backend/main\n if (callbacks.size === 0) {\n eventSubscriptions.delete(eventName);\n await transport.exec(\"event/unsubscribe\", { eventName });\n }\n }\n },\n\n isEventSupported: (eventName: string) => {\n return transport.exec(\"event/exists\", { eventName });\n },\n\n getLaunchArgs: (): string[] => {\n if (options?.getLaunchArgs) {\n return options.getLaunchArgs();\n }\n return [];\n },\n };\n}\n\n/**\n * Create the AppBusAPI object\n */\nexport function createAppBusAPI(\n config: AppBusConfig,\n state: AppBusState\n): AppBusAPI {\n const { transport, isBackend } = config;\n const {\n registeredServices,\n connectedPorts,\n pendingRequests,\n messageIdGenerator,\n } = state;\n\n return {\n exposeService: async (\n serviceName: string,\n onConnect: ServiceConnectCallback,\n options?: {\n description?: string;\n allowedClients?: string[];\n }\n ): Promise<{ success: boolean; error?: string }> => {\n if (typeof onConnect !== \"function\") {\n throw new Error(\"onConnect callback must be a function\");\n }\n\n // Store the onConnect callback locally\n // When a client connects, handleAppBusPort will call this with the connection\n registeredServices.set(serviceName, onConnect);\n\n // Register with main process\n const result = await transport.exec(\"appbus/register\", {\n serviceName,\n description: options?.description,\n allowedClients: options?.allowedClients,\n isBackend,\n });\n\n if (!result.success) {\n registeredServices.delete(serviceName);\n }\n\n return result;\n },\n\n unexposeService: async (\n serviceName: string\n ): Promise<{ success: boolean }> => {\n registeredServices.delete(serviceName);\n return transport.exec(\"appbus/unregister\", {\n serviceName,\n });\n },\n\n connect: async (\n targetAppId: string,\n serviceName: string\n ): Promise<AppBusConnection | { error: string }> => {\n // Request connection through shell command\n const result = await transport.exec(\"appbus/connect\", {\n targetAppId,\n serviceName,\n isBackend,\n });\n\n if (!result.success) {\n return { error: result.error || \"Connection failed\" };\n }\n\n const { connectionId } = result;\n\n // Wait for the port to be received via handleAppBusPort\n let port: IPCPort;\n try {\n port = await waitForPort(connectionId, state, 5000);\n } catch (err) {\n return {\n error:\n err instanceof Error ? err.message : \"MessagePort not received\",\n };\n }\n\n // Use shared utility to create connection object\n return createPortConnection(\n port,\n connectionId,\n connectedPorts,\n pendingRequests,\n messageIdGenerator\n );\n },\n\n listServices: async (): Promise<{ services: ServiceInfo[] }> => {\n return transport.exec(\"appbus/list\", {});\n },\n\n listServicesByApp: async (\n appId: string\n ): Promise<{ services: ServiceInfo[] }> => {\n return transport.exec(\"appbus/list-by-app\", { appId });\n },\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_electron", "wrapDOMPort", "port", "messageListeners", "closeListeners", "message", "event", "listener", "wrapper", "e", "createMessageIdGenerator", "prefix", "counter", "createAppBusState", "waitForPort", "connectionId", "state", "timeoutMs", "existing", "resolve", "reject", "timeout", "port", "reason", "setupClientPort", "options", "portStore", "pendingRequests", "pendingPortArrivals", "pending", "event", "type", "messageId", "payload", "error", "createPortConnection", "generateMessageId", "messageListeners", "requestHandlers", "method", "listeners", "callback", "err", "handler", "result", "response", "args", "wrapper", "timeoutId", "value", "handleAppBusPort", "data", "logPrefix", "role", "serviceName", "targetAppId", "sourceAppId", "onConnect", "connection", "handlePortClosed", "createEdenAPI", "transport", "eventSubscriptions", "options", "command", "args", "eventName", "callback", "callbacks", "createAppBusAPI", "config", "state", "isBackend", "registeredServices", "connectedPorts", "pendingRequests", "messageIdGenerator", "serviceName", "onConnect", "result", "targetAppId", "connectionId", "port", "waitForPort", "err", "createPortConnection", "appId", "appId", "backendPort", "backendConnection", "pendingBackendRequests", "generateBackendMessageId", "createMessageIdGenerator", "eventSubscriptions", "appIdArg", "arg", "launchArgs", "launchArgsArg", "jsonStr", "event", "port", "wrappedPort", "wrapDOMPort", "createPortConnection", "_event", "message", "type", "payload", "callbacks", "callback", "err", "shellTransport", "command", "args", "createEdenAPI", "appBusState", "createAppBusState", "data", "handleAppBusPort", "handlePortClosed", "createAppBusAPI"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";function A(e="msg"){let r=0;return()=>`${e}-${Date.now()}-${++r}`}function I(e="appbus"){return{registeredServices:new Map,connectedPorts:new Map,pendingRequests:new Map,pendingPortArrivals:new Map,messageIdGenerator:A(e)}}function E(e,r,n=5e3){let t=r.connectedPorts.get(e);return t?Promise.resolve(t):new Promise((i,a)=>{let c=setTimeout(()=>{r.pendingPortArrivals.delete(e),a(new Error(`Port for connection ${e} not received within ${n}ms`))},n);r.pendingPortArrivals.set(e,{resolve:s=>{clearTimeout(c),i(s)},reject:s=>{clearTimeout(c),a(s)}})})}function _(e){let{port:r,connectionId:n,portStore:t,pendingRequests:i,pendingPortArrivals:a}=e;if(t.set(n,r),a){let c=a.get(n);c&&(a.delete(n),c.resolve(r))}r.on("message",c=>{let{type:s,messageId:o,payload:l,error:d}=c.data;if(s==="response"&&o){let p=i.get(o);p&&(i.delete(o),d?p.reject(new Error(d)):p.resolve(l))}}),r.start()}function y(e,r,n,t,i){let a=new Map,c=new Map;return n.set(r,e),e.on("message",s=>{let{type:o,method:l,payload:d,messageId:p}=s.data;if(o==="message"){let g=a.get(l);g&&g.forEach(u=>{try{u(d)}catch(f){console.error(`[PortConnection] Error in on('${l}') listener:`,f)}})}else if(o==="request"){let g=c.get(l);if(g)try{let u=g(d);Promise.resolve(u).then(f=>{e.postMessage({type:"response",messageId:p,payload:f})}).catch(f=>{e.postMessage({type:"response",messageId:p,error:f instanceof Error?f.message:String(f)})})}catch(u){e.postMessage({type:"response",messageId:p,error:u instanceof Error?u.message:String(u)})}else e.postMessage({type:"response",messageId:p,error:`No handler registered for method '${l}'`})}else if(o==="response"&&p){let g=t.get(p);g&&(t.delete(p),s.data.error?g.reject(new Error(s.data.error)):g.resolve(d))}}),e.start(),{send:(s,o)=>{e.postMessage({type:"message",method:s,payload:o})},on:(s,o)=>{if(typeof o!="function")throw new Error("Callback must be a function");a.has(s)||a.set(s,new Set),a.get(s).add(o)},once:(s,o)=>{if(typeof o!="function")throw new Error("Callback must be a function");let l=d=>{let p=a.get(s);p&&(p.delete(l),p.size===0&&a.delete(s)),o(d)};a.has(s)||a.set(s,new Set),a.get(s).add(l)},off:(s,o)=>{let l=a.get(s);l&&(l.delete(o),l.size===0&&a.delete(s))},request:(s,o,l=3e4)=>new Promise((d,p)=>{let g=i(),u=setTimeout(()=>{t.has(g)&&(t.delete(g),p(new Error(`Request '${s}' timed out`)))},l);t.set(g,{resolve:f=>{clearTimeout(u),d(f)},reject:f=>{clearTimeout(u),p(f)}}),e.postMessage({type:"request",method:s,payload:o,messageId:g})}),handle:(s,o)=>{if(typeof o!="function")throw new Error("Handler must be a function");if(c.has(s))throw new Error(`Handler already registered for method '${s}'`);c.set(s,o)},removeHandler:s=>{c.delete(s)},isConnected:()=>n.has(r),onClose:s=>{e.on("close",s)},close:()=>{n.delete(r),a.clear(),c.clear(),e.close()}}}function h(e,r,n,t="[AppBus]"){let{connectionId:i,role:a,serviceName:c,targetAppId:s,sourceAppId:o}=r;if(a==="service"){console.log(`${t} Received connection from ${o} for service ${c}`);let l=n.registeredServices.get(c);if(!l){console.error(`${t} No onConnect callback registered for service "${c}"`);return}let d=y(e,i,n.connectedPorts,n.pendingRequests,n.messageIdGenerator);try{l(d,{appId:o||"unknown"})}catch(p){console.error(`${t} Error in onConnect callback for service "${c}":`,p)}}else a==="client"&&(console.log(`${t} Connected to ${s}/${c}`),_({port:e,connectionId:i,portStore:n.connectedPorts,pendingRequests:n.pendingRequests,pendingPortArrivals:n.pendingPortArrivals}))}function M(e,r){let n=e.connectedPorts.get(r);n&&(n.close(),e.connectedPorts.delete(r))}function b(e,r,n){return{shellCommand:(t,i)=>e.exec(t,i),subscribe:async(t,i)=>{if(typeof i!="function")throw new Error("Callback must be a function");await e.exec("event/subscribe",{eventName:t}),r.has(t)||r.set(t,new Set),r.get(t).add(i)},unsubscribe:async(t,i)=>{let a=r.get(t);a&&(a.delete(i),a.size===0&&(r.delete(t),await e.exec("event/unsubscribe",{eventName:t})))},isEventSupported:t=>e.exec("event/exists",{eventName:t}),getLaunchArgs:()=>n!=null&&n.getLaunchArgs?n.getLaunchArgs():[]}}function B(e,r){let{transport:n,isBackend:t}=e,{registeredServices:i,connectedPorts:a,pendingRequests:c,messageIdGenerator:s}=r;return{exposeService:async(o,l,d)=>{if(typeof l!="function")throw new Error("onConnect callback must be a function");i.set(o,l);let p=await n.exec("appbus/register",{serviceName:o,description:d==null?void 0:d.description,allowedClients:d==null?void 0:d.allowedClients,isBackend:t});return p.success||i.delete(o),p},unexposeService:async o=>(i.delete(o),n.exec("appbus/unregister",{serviceName:o})),connect:async(o,l)=>{let d=await n.exec("appbus/connect",{targetAppId:o,serviceName:l,isBackend:t});if(!d.success)return{error:d.error||"Connection failed"};let{connectionId:p}=d,g;try{g=await E(p,r,5e3)}catch(u){return{error:u instanceof Error?u.message:"MessagePort not received"}}return y(g,p,a,c,s)},listServices:async()=>n.exec("appbus/list",{}),listServicesByApp:async o=>n.exec("appbus/list-by-app",{appId:o})}}var P=process.env.EDEN_APP_ID,S=process.env.EDEN_BACKEND_ENTRY,F=JSON.parse(process.env.EDEN_MANIFEST||"{}"),$=[],k=process.argv.find(e=>e.startsWith("--launch-args="));if(k)try{let e=k.split("=").slice(1).join("=");$=JSON.parse(e)}catch(e){console.error("[Backend Runtime] Failed to parse launch args:",e)}var L=null,m=process.parentPort;m||(console.error("[Backend Runtime] Not running in utility process - parentPort not available"),process.exit(1));var T=new Map,v=new Map,j=0,C=I("backend-appbus");function D(){return`cmd-${P}-${Date.now()}-${++j}`}async function G(e,r){return new Promise((n,t)=>{let i=D(),a=setTimeout(()=>{v.delete(i),t(new Error(`Shell command '${e}' timed out`))},3e4);v.set(i,{resolve:c=>{clearTimeout(a),n(c)},reject:c=>{clearTimeout(a),t(c)}}),m.postMessage({type:"shell-command",commandId:i,command:e,args:{...r,_callerAppId:P}})})}var q={exec:(e,r)=>G(e,r)},N=b(q,T,{getLaunchArgs:()=>$}),O=B({transport:q,isBackend:!0},C),w=null,x,z=!!((x=F.frontend)!=null&&x.entry);m.on("message",e=>{let r=e.data;if(r.type==="shell-command-response"){let n=v.get(r.commandId);n&&(v.delete(r.commandId),r.error?n.reject(new Error(r.error)):n.resolve(r.result))}else if(r.type==="shell-event"){let{eventName:n,payload:t}=r,i=T.get(n);i&&i.forEach(a=>{try{a(t)}catch(c){console.error(`[Backend ${P}] Error in event callback for ${n}:`,c)}})}else if(r.type==="appbus-port"){let[n]=e.ports;n&&W(n,r)}else r.type==="appbus-port-closed"?M(C,r.connectionId):r.type==="shutdown"&&(console.log(`[Backend ${P}] Shutdown requested`),process.exit(0))});function H(e){let r=e;w=y(r,"__frontend__",new Map([["__frontend__",r]]),new Map,A("backend-to-frontend"))}function W(e,r){let n=e;h(n,r,C,`[Backend ${P}]`)}async function J(){try{console.log(`[Backend ${P}] Loading backend entry: ${S}`),await import(S),console.log(`[Backend ${P}] Backend loaded successfully`),m.postMessage({type:"backend-ready"})}catch(e){console.error(`[Backend ${P}] Failed to load backend:`,e),m.postMessage({type:"backend-error",error:e instanceof Error?e.message:String(e)}),process.exit(1)}}async function K(){z&&await new Promise(e=>{let r=n=>{if(n.data.type==="init-port"){let[t]=n.ports;t&&(L=t,H(t),console.log(`[Backend ${P}] Frontend port initialized`)),m.removeListener("message",r),e()}};m.on("message",r)}),await J()}function Y(){if(!w)throw new Error("AppAPI not available: This app has no frontend connection. Ensure 'frontend.entry' is defined in manifest.json if you need frontend communication.");return w}globalThis.worker={edenAPI:N,appBus:O,getAppAPI:Y};K();
2
+ //# sourceMappingURL=backend-preload.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/app-runtime/common/port-channel.ts", "../../src/app-runtime/common/api-factory.ts", "../../src/app-runtime/backend-preload.ts"],
4
+ "sourcesContent": ["/**\n * Port Channel - Shared utilities for MessagePort communication\n *\n * This module provides reusable utilities for setting up MessagePort-based\n * communication channels between frontend, backend, and AppBus connections.\n *\n * Used by:\n * - app-preload.ts (frontend)\n * - backend-preload.ts (backend)\n */\n\n// Re-export IPCPort types and wrappers\nexport { wrapDOMPort, wrapElectronPort } from \"./ipc-port\";\nexport type { IPCPort } from \"./ipc-port\";\nimport type { IPCPort } from \"./ipc-port\";\n\nimport type {\n AppBusConnection,\n ServiceConnectCallback,\n} from \"@edenapp/types/ipc/appbus\";\n\n/**\n * Pending request tracking\n */\nexport interface PendingRequest {\n resolve: (value: any) => void;\n reject: (reason: any) => void;\n}\n\n/**\n * Pending port arrival tracking\n */\nexport interface PendingPortArrival {\n resolve: (port: IPCPort) => void;\n reject: (reason: Error) => void;\n}\n\n/**\n * Options for setting up a client port\n */\nexport interface ClientPortOptions {\n port: IPCPort;\n connectionId: string;\n portStore: Map<string, IPCPort>;\n pendingRequests: Map<string, PendingRequest>;\n pendingPortArrivals?: Map<string, PendingPortArrival>;\n logPrefix?: string;\n}\n\n/**\n * Message ID generator factory\n */\nexport function createMessageIdGenerator(prefix: string = \"msg\"): () => string {\n let counter = 0;\n return () => `${prefix}-${Date.now()}-${++counter}`;\n}\n\n/**\n * AppBus state for an app\n */\nexport interface AppBusState {\n registeredServices: Map<string, ServiceConnectCallback>;\n connectedPorts: Map<string, IPCPort>;\n pendingRequests: Map<string, PendingRequest>;\n pendingPortArrivals: Map<string, PendingPortArrival>;\n messageIdGenerator: () => string;\n}\n\n/**\n * Create AppBus state for an app\n */\nexport function createAppBusState(prefix: string = \"appbus\"): AppBusState {\n return {\n registeredServices: new Map(),\n connectedPorts: new Map(),\n pendingRequests: new Map(),\n pendingPortArrivals: new Map(),\n messageIdGenerator: createMessageIdGenerator(prefix),\n };\n}\n\n/**\n * Wait for a port to arrive for a given connection ID\n *\n * @param connectionId The connection ID to wait for\n * @param state AppBus state containing connectedPorts and pendingPortArrivals\n * @param timeoutMs Timeout in milliseconds (default: 5000)\n * @returns Promise that resolves with the port or rejects on timeout\n */\nexport function waitForPort(\n connectionId: string,\n state: AppBusState,\n timeoutMs: number = 5000\n): Promise<IPCPort> {\n // Check if port is already available\n const existing = state.connectedPorts.get(connectionId);\n if (existing) {\n return Promise.resolve(existing);\n }\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n state.pendingPortArrivals.delete(connectionId);\n reject(\n new Error(\n `Port for connection ${connectionId} not received within ${timeoutMs}ms`\n )\n );\n }, timeoutMs);\n\n state.pendingPortArrivals.set(connectionId, {\n resolve: (port: IPCPort) => {\n clearTimeout(timeout);\n resolve(port);\n },\n reject: (reason: Error) => {\n clearTimeout(timeout);\n reject(reason);\n },\n });\n });\n}\n\n/**\n * Set up a MessagePort as a client (sends requests, receives responses)\n *\n * @param options Configuration for the client port\n */\nexport function setupClientPort(options: ClientPortOptions): void {\n const {\n port,\n connectionId,\n portStore,\n pendingRequests,\n pendingPortArrivals,\n } = options;\n\n // Store the port for later use\n portStore.set(connectionId, port);\n\n // Resolve any pending port arrivals waiting for this connection\n if (pendingPortArrivals) {\n const pending = pendingPortArrivals.get(connectionId);\n if (pending) {\n pendingPortArrivals.delete(connectionId);\n pending.resolve(port);\n }\n }\n\n // Set up response handler\n port.on(\"message\", (event) => {\n const { type, messageId, payload, error } = event.data;\n\n if (type === \"response\" && messageId) {\n const pending = pendingRequests.get(messageId);\n if (pending) {\n pendingRequests.delete(messageId);\n if (error) {\n pending.reject(new Error(error));\n } else {\n pending.resolve(payload);\n }\n }\n }\n });\n\n port.start();\n}\n\n/**\n * Create a connection object for a port (Electron IPC style)\n *\n * @param port The IPCPort to wrap\n * @param connectionId The connection ID\n * @param portStore The Map storing ports\n * @param pendingRequests The Map tracking pending requests for outgoing requests\n * @param generateMessageId Function to generate unique message IDs\n * @returns Connection object with send/on/off, request/handle/removeHandler, and close methods\n */\nexport function createPortConnection(\n port: IPCPort,\n connectionId: string,\n portStore: Map<string, IPCPort>,\n pendingRequests: Map<string, PendingRequest>,\n generateMessageId: () => string\n): AppBusConnection {\n // Method-specific listeners for fire-and-forget messages (send \u2192 on)\n const messageListeners: Map<string, Set<(args: any) => void>> = new Map();\n\n // Method-specific handlers for request/response (request \u2192 handle)\n const requestHandlers: Map<string, (args: any) => any | Promise<any>> =\n new Map();\n\n // Store the port for later use (cleanup, connectivity checks)\n portStore.set(connectionId, port);\n\n // Set up incoming message handler\n port.on(\"message\", (event) => {\n const { type, method, payload, messageId } = event.data;\n\n if (type === \"message\") {\n // Fire-and-forget message - dispatch to on() listeners\n const listeners = messageListeners.get(method);\n if (listeners) {\n listeners.forEach((callback) => {\n try {\n callback(payload);\n } catch (err) {\n console.error(\n `[PortConnection] Error in on('${method}') listener:`,\n err\n );\n }\n });\n }\n } else if (type === \"request\") {\n // Request expecting response - dispatch to handle() handler\n const handler = requestHandlers.get(method);\n if (handler) {\n try {\n const result = handler(payload);\n Promise.resolve(result)\n .then((response) => {\n port.postMessage({\n type: \"response\",\n messageId,\n payload: response,\n });\n })\n .catch((err) => {\n port.postMessage({\n type: \"response\",\n messageId,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n } catch (err) {\n port.postMessage({\n type: \"response\",\n messageId,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n } else {\n port.postMessage({\n type: \"response\",\n messageId,\n error: `No handler registered for method '${method}'`,\n });\n }\n } else if (type === \"response\" && messageId) {\n // Response to our outgoing request\n const pending = pendingRequests.get(messageId);\n if (pending) {\n pendingRequests.delete(messageId);\n if (event.data.error) {\n pending.reject(new Error(event.data.error));\n } else {\n pending.resolve(payload);\n }\n }\n }\n });\n\n port.start();\n\n return {\n // Fire-and-forget messaging\n send: (method: string, args?: any) => {\n port.postMessage({ type: \"message\", method, payload: args });\n },\n\n on: (method: string, callback: (args: any) => void) => {\n if (typeof callback !== \"function\") {\n throw new Error(\"Callback must be a function\");\n }\n if (!messageListeners.has(method)) {\n messageListeners.set(method, new Set());\n }\n messageListeners.get(method)!.add(callback);\n },\n\n once: (method: string, callback: (args: any) => void) => {\n if (typeof callback !== \"function\") {\n throw new Error(\"Callback must be a function\");\n }\n const wrapper = (args: any) => {\n // Remove before calling to prevent issues if callback throws\n const listeners = messageListeners.get(method);\n if (listeners) {\n listeners.delete(wrapper);\n if (listeners.size === 0) {\n messageListeners.delete(method);\n }\n }\n callback(args);\n };\n if (!messageListeners.has(method)) {\n messageListeners.set(method, new Set());\n }\n messageListeners.get(method)!.add(wrapper);\n },\n\n off: (method: string, callback: (args: any) => void) => {\n const listeners = messageListeners.get(method);\n if (listeners) {\n listeners.delete(callback);\n if (listeners.size === 0) {\n messageListeners.delete(method);\n }\n }\n },\n\n // Request/response\n request: (\n method: string,\n args?: any,\n timeout: number = 30000\n ): Promise<any> => {\n return new Promise((resolve, reject) => {\n const messageId = generateMessageId();\n\n // Timeout after specified duration\n const timeoutId = setTimeout(() => {\n if (pendingRequests.has(messageId)) {\n pendingRequests.delete(messageId);\n reject(new Error(`Request '${method}' timed out`));\n }\n }, timeout);\n\n pendingRequests.set(messageId, {\n resolve: (value) => {\n clearTimeout(timeoutId);\n resolve(value);\n },\n reject: (reason) => {\n clearTimeout(timeoutId);\n reject(reason);\n },\n });\n\n port.postMessage({\n type: \"request\",\n method,\n payload: args,\n messageId,\n });\n });\n },\n\n handle: (method: string, handler: (args: any) => any | Promise<any>) => {\n if (typeof handler !== \"function\") {\n throw new Error(\"Handler must be a function\");\n }\n if (requestHandlers.has(method)) {\n throw new Error(`Handler already registered for method '${method}'`);\n }\n requestHandlers.set(method, handler);\n },\n\n removeHandler: (method: string) => {\n requestHandlers.delete(method);\n },\n\n // Connection management\n isConnected: () => {\n return portStore.has(connectionId);\n },\n\n onClose: (callback: () => void) => {\n port.on(\"close\", callback);\n },\n\n close: () => {\n portStore.delete(connectionId);\n messageListeners.clear();\n requestHandlers.clear();\n port.close();\n },\n };\n}\n\n/**\n * Handle an incoming AppBus port (can be service or client role)\n *\n * @param port The MessagePort received\n * @param data Connection metadata\n * @param state AppBus state (services, ports, pending requests)\n * @param logPrefix Prefix for log messages\n */\nexport function handleAppBusPort(\n port: IPCPort,\n data: {\n connectionId: string;\n role: \"service\" | \"client\";\n serviceName: string;\n targetAppId?: string;\n sourceAppId?: string;\n },\n state: AppBusState,\n logPrefix: string = \"[AppBus]\"\n): void {\n const { connectionId, role, serviceName, targetAppId, sourceAppId } = data;\n\n if (role === \"service\") {\n // A client is connecting to our service\n console.log(\n `${logPrefix} Received connection from ${sourceAppId} for service ${serviceName}`\n );\n\n const onConnect = state.registeredServices.get(serviceName);\n if (!onConnect) {\n console.error(\n `${logPrefix} No onConnect callback registered for service \"${serviceName}\"`\n );\n return;\n }\n\n // Create a bidirectional AppBusConnection for the service to use\n const connection = createPortConnection(\n port,\n connectionId,\n state.connectedPorts,\n state.pendingRequests,\n state.messageIdGenerator\n );\n\n // Call the onConnect callback with the connection and client info\n try {\n onConnect(connection, { appId: sourceAppId || \"unknown\" });\n } catch (err) {\n console.error(\n `${logPrefix} Error in onConnect callback for service \"${serviceName}\":`,\n err\n );\n }\n } else if (role === \"client\") {\n // We're connecting to another app's service\n console.log(`${logPrefix} Connected to ${targetAppId}/${serviceName}`);\n\n setupClientPort({\n port,\n connectionId,\n portStore: state.connectedPorts,\n pendingRequests: state.pendingRequests,\n pendingPortArrivals: state.pendingPortArrivals,\n });\n }\n}\n/**\n * Handle a port being closed from the other side\n * Triggered by a notification from the main process\n *\n * @param state AppBus state\n * @param connectionId The ID of the closed connection\n */\nexport function handlePortClosed(\n state: AppBusState,\n connectionId: string\n): void {\n const port = state.connectedPorts.get(connectionId);\n if (port) {\n port.close();\n state.connectedPorts.delete(connectionId);\n }\n}\n", "import type {\n EdenAPI,\n AppBusAPI,\n AppBusConnection,\n ServiceInfo,\n ServiceConnectCallback,\n} from \"@edenapp/types\";\nimport type { PendingRequest, IPCPort, AppBusState } from \"./port-channel\";\nimport { createPortConnection, waitForPort } from \"./port-channel\";\n\n/**\n * Interface for sending shell commands to the main process\n */\nexport interface ShellTransport {\n exec(command: string, args: any): Promise<any>;\n}\n\n/**\n * Configuration for AppBus API\n */\nexport interface AppBusConfig {\n transport: ShellTransport;\n isBackend?: boolean;\n}\n\n/**\n * Create the EdenAPI object\n */\nexport function createEdenAPI(\n transport: ShellTransport,\n eventSubscriptions: Map<string, Set<Function>>,\n options?: { getLaunchArgs?: () => string[] }\n): EdenAPI {\n return {\n shellCommand: (command: string, args: any) => {\n return transport.exec(command, args);\n },\n\n subscribe: async (eventName: string, callback: Function) => {\n if (typeof callback !== \"function\") {\n throw new Error(\"Callback must be a function\");\n }\n\n // Register with backend/main\n await transport.exec(\"event/subscribe\", { eventName });\n\n // Register callback locally\n if (!eventSubscriptions.has(eventName)) {\n eventSubscriptions.set(eventName, new Set());\n }\n eventSubscriptions.get(eventName)!.add(callback);\n },\n\n unsubscribe: async (eventName: string, callback: Function) => {\n const callbacks = eventSubscriptions.get(eventName);\n if (callbacks) {\n callbacks.delete(callback);\n\n // If no more callbacks, unregister from backend/main\n if (callbacks.size === 0) {\n eventSubscriptions.delete(eventName);\n await transport.exec(\"event/unsubscribe\", { eventName });\n }\n }\n },\n\n isEventSupported: (eventName: string) => {\n return transport.exec(\"event/exists\", { eventName });\n },\n\n getLaunchArgs: (): string[] => {\n if (options?.getLaunchArgs) {\n return options.getLaunchArgs();\n }\n return [];\n },\n };\n}\n\n/**\n * Create the AppBusAPI object\n */\nexport function createAppBusAPI(\n config: AppBusConfig,\n state: AppBusState\n): AppBusAPI {\n const { transport, isBackend } = config;\n const {\n registeredServices,\n connectedPorts,\n pendingRequests,\n messageIdGenerator,\n } = state;\n\n return {\n exposeService: async (\n serviceName: string,\n onConnect: ServiceConnectCallback,\n options?: {\n description?: string;\n allowedClients?: string[];\n }\n ): Promise<{ success: boolean; error?: string }> => {\n if (typeof onConnect !== \"function\") {\n throw new Error(\"onConnect callback must be a function\");\n }\n\n // Store the onConnect callback locally\n // When a client connects, handleAppBusPort will call this with the connection\n registeredServices.set(serviceName, onConnect);\n\n // Register with main process\n const result = await transport.exec(\"appbus/register\", {\n serviceName,\n description: options?.description,\n allowedClients: options?.allowedClients,\n isBackend,\n });\n\n if (!result.success) {\n registeredServices.delete(serviceName);\n }\n\n return result;\n },\n\n unexposeService: async (\n serviceName: string\n ): Promise<{ success: boolean }> => {\n registeredServices.delete(serviceName);\n return transport.exec(\"appbus/unregister\", {\n serviceName,\n });\n },\n\n connect: async (\n targetAppId: string,\n serviceName: string\n ): Promise<AppBusConnection | { error: string }> => {\n // Request connection through shell command\n const result = await transport.exec(\"appbus/connect\", {\n targetAppId,\n serviceName,\n isBackend,\n });\n\n if (!result.success) {\n return { error: result.error || \"Connection failed\" };\n }\n\n const { connectionId } = result;\n\n // Wait for the port to be received via handleAppBusPort\n let port: IPCPort;\n try {\n port = await waitForPort(connectionId, state, 5000);\n } catch (err) {\n return {\n error:\n err instanceof Error ? err.message : \"MessagePort not received\",\n };\n }\n\n // Use shared utility to create connection object\n return createPortConnection(\n port,\n connectionId,\n connectedPorts,\n pendingRequests,\n messageIdGenerator\n );\n },\n\n listServices: async (): Promise<{ services: ServiceInfo[] }> => {\n return transport.exec(\"appbus/list\", {});\n },\n\n listServicesByApp: async (\n appId: string\n ): Promise<{ services: ServiceInfo[] }> => {\n return transport.exec(\"appbus/list-by-app\", { appId });\n },\n };\n}\n", "/**\n * Backend Runtime\n *\n * This module runs inside Electron's utility process (forked by BackendManager).\n * It provides the global `worker` object with `edenAPI` and `appBus` APIs,\n * mirroring the frontend's `window.edenAPI` and `window.appBus`.\n *\n * Environment variables expected:\n * - EDEN_APP_ID: The app's identifier\n * - EDEN_BACKEND_ENTRY: Path to the actual backend entry point\n * - EDEN_INSTALL_PATH: Path to the app's installation directory\n * - EDEN_MANIFEST: JSON-stringified app manifest\n */\n\nimport type { EdenAPI, AppBusAPI, AppBusConnection } from \"@edenapp/types\";\n\nimport type { WorkerGlobal } from \"@edenapp/types/worker\";\n\nimport {\n createMessageIdGenerator,\n handleAppBusPort as handlePortSetup,\n createPortConnection,\n createAppBusState,\n wrapElectronPort,\n handlePortClosed,\n} from \"./common/port-channel\";\n\nimport {\n createEdenAPI,\n createAppBusAPI,\n type ShellTransport,\n} from \"./common/api-factory\";\n\n// Electron utility process extends the Node process with parentPort\n// This is available when running inside utilityProcess.fork()\n// We use Electron's types which should be available\n\n// Get app info from environment\nconst appId = process.env.EDEN_APP_ID!;\nconst backendEntry = process.env.EDEN_BACKEND_ENTRY!;\nconst manifest = JSON.parse(process.env.EDEN_MANIFEST || \"{}\");\n\n// Extract launch args\nlet launchArgs: string[] = [];\nconst launchArgsArg = process.argv.find((arg) =>\n arg.startsWith(\"--launch-args=\")\n);\nif (launchArgsArg) {\n try {\n const jsonStr = launchArgsArg.split(\"=\").slice(1).join(\"=\");\n launchArgs = JSON.parse(jsonStr);\n } catch (e) {\n console.error(\"[Backend Runtime] Failed to parse launch args:\", e);\n }\n}\n\n// Port for direct frontend<->backend communication (received from main)\nlet frontendPort: Electron.MessagePortMain | null = null;\n\n// Port for IPC with main process (process.parentPort)\nconst parentPort = process.parentPort;\nif (!parentPort) {\n console.error(\n \"[Backend Runtime] Not running in utility process - parentPort not available\"\n );\n process.exit(1);\n}\n\n// Event subscriptions\nconst eventSubscriptions: Map<string, Set<Function>> = new Map();\n\n// Pending shell command requests\nconst pendingCommands: Map<\n string,\n { resolve: (value: any) => void; reject: (reason: any) => void }\n> = new Map();\nlet commandIdCounter = 0;\n\n// AppBus state\nconst appBusState = createAppBusState(\"backend-appbus\");\n\n/**\n * Generate unique command ID\n */\nfunction generateCommandId(): string {\n return `cmd-${appId}-${Date.now()}-${++commandIdCounter}`;\n}\n\n/**\n * Send a shell command to main process and wait for response\n */\nasync function shellCommand(command: string, args: any): Promise<any> {\n return new Promise((resolve, reject) => {\n const commandId = generateCommandId();\n\n // Set timeout\n const timeout = setTimeout(() => {\n pendingCommands.delete(commandId);\n reject(new Error(`Shell command '${command}' timed out`));\n }, 30000);\n\n pendingCommands.set(commandId, {\n resolve: (value) => {\n clearTimeout(timeout);\n resolve(value);\n },\n reject: (reason) => {\n clearTimeout(timeout);\n reject(reason);\n },\n });\n\n parentPort!.postMessage({\n type: \"shell-command\",\n commandId,\n command,\n args: { ...args, _callerAppId: appId },\n });\n });\n}\n\n// ===================================================================\n// Shared API Implementation\n// ===================================================================\n\n// Shell transport implementation using internal shellCommand\nconst shellTransport: ShellTransport = {\n exec: (command: string, args: any) => {\n return shellCommand(command, args);\n },\n};\n\n/**\n * Eden API implementation for utility process\n */\nconst edenAPI: EdenAPI = createEdenAPI(shellTransport, eventSubscriptions, {\n getLaunchArgs: () => launchArgs,\n});\n\n/**\n * AppBus API implementation for utility process\n */\nconst appBus: AppBusAPI = createAppBusAPI(\n { transport: shellTransport, isBackend: true },\n appBusState\n);\n\n// Frontend communication state\nlet frontendConnection: AppBusConnection | null = null;\n\n// Check if this app has a frontend (from manifest)\nconst hasFrontend = !!manifest.frontend?.entry;\n\n// appAPI will be set after frontend port is received (for apps with frontend)\n// For backend-only apps, worker.appAPI will be undefined\n\n/**\n * Handle messages from main process (via parentPort)\n */\nparentPort.on(\"message\", (event: Electron.MessageEvent) => {\n const message = event.data;\n\n if (message.type === \"shell-command-response\") {\n // Response to a shell command we sent\n const pending = pendingCommands.get(message.commandId);\n if (pending) {\n pendingCommands.delete(message.commandId);\n if (message.error) {\n pending.reject(new Error(message.error));\n } else {\n pending.resolve(message.result);\n }\n }\n } else if (message.type === \"shell-event\") {\n // Event notification from main\n const { eventName, payload } = message;\n const callbacks = eventSubscriptions.get(eventName);\n if (callbacks) {\n callbacks.forEach((callback) => {\n try {\n callback(payload);\n } catch (err) {\n console.error(\n `[Backend ${appId}] Error in event callback for ${eventName}:`,\n err\n );\n }\n });\n }\n } else if (message.type === \"appbus-port\") {\n // AppBus connection port\n const [port] = event.ports;\n if (port) {\n handleAppBusPort(port, message);\n }\n } else if (message.type === \"appbus-port-closed\") {\n // AppBus connection closed\n handlePortClosed(appBusState, message.connectionId);\n } else if (message.type === \"shutdown\") {\n // Graceful shutdown request\n console.log(`[Backend ${appId}] Shutdown requested`);\n process.exit(0);\n }\n});\n\n/**\n * Set up frontend port using createPortConnection\n */\nfunction setupFrontendPort(port: Electron.MessagePortMain): void {\n const wrappedPort = wrapElectronPort(port);\n\n // Create connection using shared utility\n frontendConnection = createPortConnection(\n wrappedPort,\n \"__frontend__\",\n new Map([[\"__frontend__\", wrappedPort]]),\n new Map(),\n createMessageIdGenerator(\"backend-to-frontend\")\n );\n}\n\n/**\n * Handle AppBus port connections (using shared utility)\n */\nfunction handleAppBusPort(port: Electron.MessagePortMain, data: any): void {\n // Wrap Electron MessagePortMain to IPCPort interface\n const wrappedPort = wrapElectronPort(port);\n\n handlePortSetup(wrappedPort, data, appBusState, `[Backend ${appId}]`);\n}\n\n/**\n * Load and execute the actual backend entry point\n */\nasync function loadBackendEntry(): Promise<void> {\n try {\n console.log(`[Backend ${appId}] Loading backend entry: ${backendEntry}`);\n await import(backendEntry);\n console.log(`[Backend ${appId}] Backend loaded successfully`);\n\n // Signal to main that we're ready\n parentPort!.postMessage({ type: \"backend-ready\" });\n } catch (error) {\n console.error(`[Backend ${appId}] Failed to load backend:`, error);\n parentPort!.postMessage({\n type: \"backend-error\",\n error: error instanceof Error ? error.message : String(error),\n });\n process.exit(1);\n }\n}\n\n/**\n * Wait for frontend port (if app has frontend) then load backend\n */\nasync function initializeBackend(): Promise<void> {\n if (hasFrontend) {\n // Wait for init-port message before loading backend\n await new Promise<void>((resolve) => {\n const handler = (event: Electron.MessageEvent) => {\n if (event.data.type === \"init-port\") {\n const [port] = event.ports;\n if (port) {\n frontendPort = port;\n setupFrontendPort(port);\n console.log(`[Backend ${appId}] Frontend port initialized`);\n }\n parentPort.removeListener(\"message\", handler);\n resolve();\n }\n };\n parentPort.on(\"message\", handler);\n });\n }\n\n // Now load backend - worker.appAPI is ready (for apps with frontend)\n await loadBackendEntry();\n}\n\n/**\n * Get AppAPI connection\n * Throws if app has no frontend\n */\nfunction getAppAPI(): AppBusConnection {\n if (!frontendConnection) {\n throw new Error(\n \"AppAPI not available: This app has no frontend connection. \" +\n \"Ensure 'frontend.entry' is defined in manifest.json if you need frontend communication.\"\n );\n }\n return frontendConnection;\n}\n\n/**\n * Set up the global worker object\n */\n// For apps with frontend, appAPI will be set in initializeBackend after port is received\n((globalThis as any).worker as WorkerGlobal) = {\n edenAPI,\n appBus,\n getAppAPI,\n};\n\n// Start initialization\ninitializeBackend();\n"],
5
+ "mappings": "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",
6
+ "names": ["createMessageIdGenerator", "prefix", "counter", "createAppBusState", "waitForPort", "connectionId", "state", "timeoutMs", "existing", "resolve", "reject", "timeout", "port", "reason", "setupClientPort", "options", "portStore", "pendingRequests", "pendingPortArrivals", "pending", "event", "type", "messageId", "payload", "error", "createPortConnection", "generateMessageId", "messageListeners", "requestHandlers", "method", "listeners", "callback", "err", "handler", "result", "response", "args", "wrapper", "timeoutId", "value", "handleAppBusPort", "data", "logPrefix", "role", "serviceName", "targetAppId", "sourceAppId", "onConnect", "connection", "handlePortClosed", "createEdenAPI", "transport", "eventSubscriptions", "options", "command", "args", "eventName", "callback", "callbacks", "createAppBusAPI", "config", "state", "isBackend", "registeredServices", "connectedPorts", "pendingRequests", "messageIdGenerator", "serviceName", "onConnect", "result", "targetAppId", "connectionId", "port", "waitForPort", "err", "createPortConnection", "appId", "appId", "backendEntry", "manifest", "launchArgs", "launchArgsArg", "arg", "jsonStr", "frontendPort", "parentPort", "eventSubscriptions", "pendingCommands", "commandIdCounter", "appBusState", "createAppBusState", "generateCommandId", "shellCommand", "command", "args", "resolve", "reject", "commandId", "timeout", "value", "reason", "shellTransport", "edenAPI", "createEdenAPI", "appBus", "createAppBusAPI", "frontendConnection", "_a", "hasFrontend", "event", "message", "pending", "eventName", "payload", "callbacks", "callback", "err", "port", "handleAppBusPort", "handlePortClosed", "setupFrontendPort", "wrappedPort", "createPortConnection", "createMessageIdGenerator", "data", "loadBackendEntry", "error", "initializeBackend", "handler", "getAppAPI"]
7
+ }
@@ -0,0 +1,65 @@
1
+ import type { AppChannelManager } from "./AppChannelManager";
2
+ import type { ServiceInfo, ConnectResult } from "@edenapp/types";
3
+ /**
4
+ * AppChannelHandler
5
+ *
6
+ * IPC handler for AppBus operations.
7
+ * Exposes service registration and channel connection
8
+ * via Eden's decorator-based IPC system.
9
+ */
10
+ export declare class AppChannelHandler {
11
+ private channelManager;
12
+ constructor(channelManager: AppChannelManager);
13
+ /**
14
+ * Register a service that this app exposes
15
+ * Requires "appbus/expose" permission
16
+ */
17
+ handleRegister(args: {
18
+ serviceName: string;
19
+ description?: string;
20
+ allowedClients?: string[];
21
+ _callerAppId: string;
22
+ _callerWebContentsId: number;
23
+ }): Promise<{
24
+ success: boolean;
25
+ error?: string;
26
+ }>;
27
+ /**
28
+ * Unregister a service
29
+ * Requires "appbus/expose" permission
30
+ */
31
+ handleUnregister(args: {
32
+ serviceName: string;
33
+ _callerAppId: string;
34
+ }): Promise<{
35
+ success: boolean;
36
+ }>;
37
+ /**
38
+ * List all available services
39
+ * No permission required
40
+ */
41
+ handleList(): Promise<{
42
+ services: ServiceInfo[];
43
+ }>;
44
+ /**
45
+ * List services by app ID
46
+ * No permission required
47
+ */
48
+ handleListByApp(args: {
49
+ appId: string;
50
+ }): Promise<{
51
+ services: ServiceInfo[];
52
+ }>;
53
+ /**
54
+ * Connect to another app's service
55
+ * Creates MessageChannel and transfers ports directly to both apps
56
+ * Requires "appbus/connect" permission
57
+ */
58
+ handleConnect(args: {
59
+ targetAppId: string;
60
+ serviceName: string;
61
+ _callerAppId: string;
62
+ _callerWebContentsId: number;
63
+ }): Promise<ConnectResult>;
64
+ }
65
+ //# sourceMappingURL=AppChannelHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppChannelHandler.d.ts","sourceRoot":"","sources":["../../src/appbus/AppChannelHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;;;;;GAMG;AACH,qBACa,iBAAiB;IAChB,OAAO,CAAC,cAAc;gBAAd,cAAc,EAAE,iBAAiB;IAMrD;;;OAGG;IAEG,cAAc,CAAC,IAAI,EAAE;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,oBAAoB,EAAE,MAAM,CAAC;KAC9B,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAoBjD;;;OAGG;IAEG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAYjC;;;OAGG;IAEG,UAAU,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;IAIxD;;;OAGG;IAEG,eAAe,CAAC,IAAI,EAAE;QAC1B,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;IAQxC;;;;OAIG;IAEG,aAAa,CAAC,IAAI,EAAE;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,oBAAoB,EAAE,MAAM,CAAC;KAC9B,GAAG,OAAO,CAAC,aAAa,CAAC;CAQ3B"}