@dxos/plugin-client 0.10.0 → 0.11.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 (358) hide show
  1. package/dist/lib/ClientPlugin.mjs +65 -0
  2. package/dist/lib/ClientPlugin.mjs.map +1 -0
  3. package/dist/lib/ClientPlugin.node.mjs +904 -0
  4. package/dist/lib/ClientPlugin.node.mjs.map +1 -0
  5. package/dist/lib/ClientPlugin.workerd.mjs +10 -0
  6. package/dist/lib/ClientPlugin.workerd.mjs.map +1 -0
  7. package/dist/lib/capabilities/node.mjs +13 -0
  8. package/dist/lib/capabilities/node.mjs.map +1 -0
  9. package/dist/lib/capabilities.mjs +23 -0
  10. package/dist/lib/capabilities.mjs.map +1 -0
  11. package/dist/lib/chunk-AccountContainer.mjs +190 -0
  12. package/dist/lib/chunk-AccountContainer.mjs.map +1 -0
  13. package/dist/lib/chunk-DevicesContainer.mjs +275 -0
  14. package/dist/lib/chunk-DevicesContainer.mjs.map +1 -0
  15. package/dist/lib/chunk-InvitationsContainer.mjs +149 -0
  16. package/dist/lib/chunk-InvitationsContainer.mjs.map +1 -0
  17. package/dist/lib/chunk-JoinDialog.mjs +35 -0
  18. package/dist/lib/chunk-JoinDialog.mjs.map +1 -0
  19. package/dist/lib/chunk-ProfileContainer.mjs +145 -0
  20. package/dist/lib/chunk-ProfileContainer.mjs.map +1 -0
  21. package/dist/lib/chunk-RecoveryCodeDialog.mjs +72 -0
  22. package/dist/lib/chunk-RecoveryCodeDialog.mjs.map +1 -0
  23. package/dist/lib/chunk-RecoveryCredentialsContainer.mjs +65 -0
  24. package/dist/lib/chunk-RecoveryCredentialsContainer.mjs.map +1 -0
  25. package/dist/lib/chunk-ResetDialog.mjs +47 -0
  26. package/dist/lib/chunk-ResetDialog.mjs.map +1 -0
  27. package/dist/lib/chunk-UsageContainer.mjs +217 -0
  28. package/dist/lib/chunk-UsageContainer.mjs.map +1 -0
  29. package/dist/lib/{neutral/account-cache-YVQKLNV2.mjs → chunk-account-cache.mjs} +10 -12
  30. package/dist/lib/chunk-account-cache.mjs.map +1 -0
  31. package/dist/lib/chunk-app-graph-builder.mjs +111 -0
  32. package/dist/lib/chunk-app-graph-builder.mjs.map +1 -0
  33. package/dist/lib/chunk-client.mjs +90 -0
  34. package/dist/lib/chunk-client.mjs.map +1 -0
  35. package/dist/lib/{neutral/chunk-GSKMAS3S.mjs → chunk-constants.mjs} +5 -8
  36. package/dist/lib/chunk-constants.mjs.map +1 -0
  37. package/dist/lib/chunk-create-agent.mjs +23 -0
  38. package/dist/lib/chunk-create-agent.mjs.map +1 -0
  39. package/dist/lib/chunk-create-identity.mjs +28 -0
  40. package/dist/lib/chunk-create-identity.mjs.map +1 -0
  41. package/dist/lib/chunk-create-passkey.mjs +85 -0
  42. package/dist/lib/chunk-create-passkey.mjs.map +1 -0
  43. package/dist/lib/chunk-create-recovery-code.mjs +31 -0
  44. package/dist/lib/chunk-create-recovery-code.mjs.map +1 -0
  45. package/dist/lib/chunk-hooks.mjs +29 -0
  46. package/dist/lib/chunk-hooks.mjs.map +1 -0
  47. package/dist/lib/chunk-hub-http-client.mjs +14 -0
  48. package/dist/lib/chunk-hub-http-client.mjs.map +1 -0
  49. package/dist/lib/chunk-join-identity.mjs +20 -0
  50. package/dist/lib/chunk-join-identity.mjs.map +1 -0
  51. package/dist/lib/chunk-layer-specs.mjs +107 -0
  52. package/dist/lib/chunk-layer-specs.mjs.map +1 -0
  53. package/dist/lib/{neutral/chunk-6G4KZLBG.mjs → chunk-meta.mjs} +13 -20
  54. package/dist/lib/chunk-meta.mjs.map +1 -0
  55. package/dist/lib/chunk-migrations.mjs +29 -0
  56. package/dist/lib/chunk-migrations.mjs.map +1 -0
  57. package/dist/lib/chunk-navigation-handler.mjs +71 -0
  58. package/dist/lib/chunk-navigation-handler.mjs.map +1 -0
  59. package/dist/lib/chunk-navigation-target-loader.mjs +46 -0
  60. package/dist/lib/chunk-navigation-target-loader.mjs.map +1 -0
  61. package/dist/lib/chunk-open-usage.mjs +14 -0
  62. package/dist/lib/chunk-open-usage.mjs.map +1 -0
  63. package/dist/lib/chunk-operation-handler.mjs +11 -0
  64. package/dist/lib/chunk-operation-handler.mjs.map +1 -0
  65. package/dist/lib/chunk-operations.mjs +212 -0
  66. package/dist/lib/chunk-operations.mjs.map +1 -0
  67. package/dist/lib/chunk-progress.mjs +10 -0
  68. package/dist/lib/chunk-progress.mjs.map +1 -0
  69. package/dist/lib/chunk-react-context.mjs +30 -0
  70. package/dist/lib/chunk-react-context.mjs.map +1 -0
  71. package/dist/lib/chunk-react-surface.mjs +70 -0
  72. package/dist/lib/chunk-react-surface.mjs.map +1 -0
  73. package/dist/lib/chunk-recover-identity.mjs +17 -0
  74. package/dist/lib/chunk-recover-identity.mjs.map +1 -0
  75. package/dist/lib/chunk-redeem-passkey.mjs +72 -0
  76. package/dist/lib/chunk-redeem-passkey.mjs.map +1 -0
  77. package/dist/lib/chunk-redeem-token.mjs +24 -0
  78. package/dist/lib/chunk-redeem-token.mjs.map +1 -0
  79. package/dist/lib/chunk-remote-trace-monitor.mjs +37 -0
  80. package/dist/lib/chunk-remote-trace-monitor.mjs.map +1 -0
  81. package/dist/lib/chunk-reset-storage.mjs +17 -0
  82. package/dist/lib/chunk-reset-storage.mjs.map +1 -0
  83. package/dist/lib/chunk-resolve-navigation-targets.mjs +32 -0
  84. package/dist/lib/chunk-resolve-navigation-targets.mjs.map +1 -0
  85. package/dist/lib/chunk-schema-defs.mjs +53 -0
  86. package/dist/lib/chunk-schema-defs.mjs.map +1 -0
  87. package/dist/lib/chunk-share-identity.mjs +16 -0
  88. package/dist/lib/chunk-share-identity.mjs.map +1 -0
  89. package/dist/lib/chunk-space-replication-progress.mjs +94 -0
  90. package/dist/lib/chunk-space-replication-progress.mjs.map +1 -0
  91. package/dist/lib/chunk-trace-progress.mjs +69 -0
  92. package/dist/lib/chunk-trace-progress.mjs.map +1 -0
  93. package/dist/lib/chunk-update-profile.mjs +15 -0
  94. package/dist/lib/chunk-update-profile.mjs.map +1 -0
  95. package/dist/lib/components.mjs +0 -0
  96. package/dist/lib/containers.mjs +15 -0
  97. package/dist/lib/containers.mjs.map +1 -0
  98. package/dist/lib/index.mjs +27 -0
  99. package/dist/lib/index.mjs.map +1 -0
  100. package/dist/lib/meta.mjs +2 -0
  101. package/dist/lib/operations.mjs +2 -0
  102. package/dist/lib/plugin.mjs +9 -0
  103. package/dist/lib/plugin.mjs.map +1 -0
  104. package/dist/lib/testing.mjs +21 -0
  105. package/dist/lib/testing.mjs.map +1 -0
  106. package/dist/lib/translations.mjs +111 -0
  107. package/dist/lib/translations.mjs.map +1 -0
  108. package/dist/lib/types.mjs +139 -0
  109. package/dist/lib/types.mjs.map +1 -0
  110. package/dist/types/src/ClientPlugin.d.ts.map +1 -1
  111. package/dist/types/src/capabilities/account-cache.d.ts +1 -1
  112. package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
  113. package/dist/types/src/capabilities/client.d.ts +1 -1
  114. package/dist/types/src/capabilities/client.d.ts.map +1 -1
  115. package/dist/types/src/capabilities/hub-http-client.d.ts +1 -1
  116. package/dist/types/src/capabilities/index.d.ts +6 -1
  117. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  118. package/dist/types/src/capabilities/layer-specs.d.ts +1 -1
  119. package/dist/types/src/capabilities/migrations.d.ts +1 -1
  120. package/dist/types/src/capabilities/navigation-handler/navigation-handler.d.ts +3 -1
  121. package/dist/types/src/capabilities/navigation-handler/navigation-handler.d.ts.map +1 -1
  122. package/dist/types/src/capabilities/navigation-target-loader.d.ts +11 -0
  123. package/dist/types/src/capabilities/navigation-target-loader.d.ts.map +1 -0
  124. package/dist/types/src/capabilities/node.d.ts +2 -1
  125. package/dist/types/src/capabilities/node.d.ts.map +1 -1
  126. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  127. package/dist/types/src/capabilities/react-context.d.ts +1 -1
  128. package/dist/types/src/capabilities/react-context.d.ts.map +1 -1
  129. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  130. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  131. package/dist/types/src/capabilities/remote-trace-monitor.d.ts +15 -0
  132. package/dist/types/src/capabilities/remote-trace-monitor.d.ts.map +1 -0
  133. package/dist/types/src/capabilities/schema-defs.d.ts +1 -1
  134. package/dist/types/src/capabilities/space-replication-progress.d.ts +11 -0
  135. package/dist/types/src/capabilities/space-replication-progress.d.ts.map +1 -0
  136. package/dist/types/src/capabilities/trace-progress.d.ts +17 -0
  137. package/dist/types/src/capabilities/trace-progress.d.ts.map +1 -0
  138. package/dist/types/src/commands/account/login/login.d.ts +2 -1
  139. package/dist/types/src/commands/account/login/login.d.ts.map +1 -1
  140. package/dist/types/src/commands/account/logout/logout.d.ts +1 -1
  141. package/dist/types/src/commands/account/logout/logout.d.ts.map +1 -1
  142. package/dist/types/src/commands/halo/index.d.ts.map +1 -1
  143. package/dist/types/src/commands/halo/share/share.d.ts.map +1 -1
  144. package/dist/types/src/commands/profile/create.d.ts.map +1 -1
  145. package/dist/types/src/containers/AccountContainer/AccountContainer.d.ts +4 -1
  146. package/dist/types/src/containers/AccountContainer/AccountContainer.d.ts.map +1 -1
  147. package/dist/types/src/containers/AccountContainer/AccountContainer.stories.d.ts +4 -1
  148. package/dist/types/src/containers/AccountContainer/AccountContainer.stories.d.ts.map +1 -1
  149. package/dist/types/src/containers/DevicesContainer/DevicesContainer.d.ts +4 -1
  150. package/dist/types/src/containers/DevicesContainer/DevicesContainer.d.ts.map +1 -1
  151. package/dist/types/src/containers/DevicesContainer/DevicesContainer.stories.d.ts +4 -1
  152. package/dist/types/src/containers/DevicesContainer/DevicesContainer.stories.d.ts.map +1 -1
  153. package/dist/types/src/containers/InvitationsContainer/InvitationsContainer.d.ts +4 -1
  154. package/dist/types/src/containers/InvitationsContainer/InvitationsContainer.d.ts.map +1 -1
  155. package/dist/types/src/containers/InvitationsContainer/InvitationsContainer.stories.d.ts +4 -1
  156. package/dist/types/src/containers/InvitationsContainer/InvitationsContainer.stories.d.ts.map +1 -1
  157. package/dist/types/src/containers/JoinDialog/JoinDialog.d.ts +4 -1
  158. package/dist/types/src/containers/JoinDialog/JoinDialog.d.ts.map +1 -1
  159. package/dist/types/src/containers/JoinDialog/JoinDialog.stories.d.ts +4 -1
  160. package/dist/types/src/containers/JoinDialog/JoinDialog.stories.d.ts.map +1 -1
  161. package/dist/types/src/containers/ProfileContainer/ProfileContainer.d.ts +4 -1
  162. package/dist/types/src/containers/ProfileContainer/ProfileContainer.d.ts.map +1 -1
  163. package/dist/types/src/containers/ProfileContainer/ProfileContainer.stories.d.ts +4 -1
  164. package/dist/types/src/containers/ProfileContainer/ProfileContainer.stories.d.ts.map +1 -1
  165. package/dist/types/src/containers/RecoveryCodeDialog/RecoveryCodeDialog.d.ts +4 -1
  166. package/dist/types/src/containers/RecoveryCodeDialog/RecoveryCodeDialog.d.ts.map +1 -1
  167. package/dist/types/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.d.ts +4 -1
  168. package/dist/types/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.d.ts.map +1 -1
  169. package/dist/types/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.stories.d.ts +4 -1
  170. package/dist/types/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.stories.d.ts.map +1 -1
  171. package/dist/types/src/containers/ResetDialog/ResetDialog.d.ts +4 -1
  172. package/dist/types/src/containers/ResetDialog/ResetDialog.d.ts.map +1 -1
  173. package/dist/types/src/containers/ResetDialog/ResetDialog.stories.d.ts +4 -1
  174. package/dist/types/src/containers/ResetDialog/ResetDialog.stories.d.ts.map +1 -1
  175. package/dist/types/src/containers/UsageContainer/UsageContainer.d.ts +4 -5
  176. package/dist/types/src/containers/UsageContainer/UsageContainer.d.ts.map +1 -1
  177. package/dist/types/src/containers/UsageContainer/UsageView.d.ts +4 -7
  178. package/dist/types/src/containers/UsageContainer/UsageView.d.ts.map +1 -1
  179. package/dist/types/src/containers/UsageContainer/UsageView.stories.d.ts +4 -2
  180. package/dist/types/src/containers/UsageContainer/UsageView.stories.d.ts.map +1 -1
  181. package/dist/types/src/halo-services-layer.d.ts +19 -0
  182. package/dist/types/src/halo-services-layer.d.ts.map +1 -0
  183. package/dist/types/src/index.d.ts +3 -0
  184. package/dist/types/src/index.d.ts.map +1 -1
  185. package/dist/types/src/operations/definitions.d.ts +9 -1
  186. package/dist/types/src/operations/definitions.d.ts.map +1 -1
  187. package/dist/types/src/operations/errors.d.ts +109 -0
  188. package/dist/types/src/operations/errors.d.ts.map +1 -0
  189. package/dist/types/src/operations/errors.test.d.ts +2 -0
  190. package/dist/types/src/operations/errors.test.d.ts.map +1 -0
  191. package/dist/types/src/operations/index.d.ts +1 -0
  192. package/dist/types/src/operations/index.d.ts.map +1 -1
  193. package/dist/types/src/operations/redeem-passkey.d.ts.map +1 -1
  194. package/dist/types/src/operations/resolve-navigation-targets.d.ts +5 -0
  195. package/dist/types/src/operations/resolve-navigation-targets.d.ts.map +1 -0
  196. package/dist/types/src/operations/update-profile.d.ts +5 -0
  197. package/dist/types/src/operations/update-profile.d.ts.map +1 -0
  198. package/dist/types/src/progress/index.d.ts +2 -0
  199. package/dist/types/src/progress/index.d.ts.map +1 -0
  200. package/dist/types/src/progress/progress-keys.d.ts +6 -0
  201. package/dist/types/src/progress/progress-keys.d.ts.map +1 -0
  202. package/dist/types/src/testing/initializeIdentity.d.ts +5 -1
  203. package/dist/types/src/testing/initializeIdentity.d.ts.map +1 -1
  204. package/dist/types/src/translations.d.ts.map +1 -1
  205. package/dist/types/src/types/capabilities.d.ts +10 -1
  206. package/dist/types/src/types/capabilities.d.ts.map +1 -1
  207. package/dist/types/src/types/schema.d.ts +6 -0
  208. package/dist/types/src/types/schema.d.ts.map +1 -1
  209. package/dist/types/tsconfig.tsbuildinfo +1 -1
  210. package/package.json +60 -55
  211. package/src/ClientPlugin.ts +25 -2
  212. package/src/capabilities/app-graph-builder.ts +1 -1
  213. package/src/capabilities/client.ts +26 -0
  214. package/src/capabilities/index.ts +10 -0
  215. package/src/capabilities/layer-specs.ts +64 -2
  216. package/src/capabilities/migrations.ts +9 -1
  217. package/src/capabilities/navigation-handler/navigation-handler.ts +20 -3
  218. package/src/capabilities/navigation-target-loader.ts +70 -0
  219. package/src/capabilities/react-context.tsx +20 -2
  220. package/src/capabilities/{react-surface.tsx → react-surface.ts} +14 -12
  221. package/src/capabilities/remote-trace-monitor.ts +62 -0
  222. package/src/capabilities/space-replication-progress.ts +143 -0
  223. package/src/capabilities/trace-progress.ts +84 -0
  224. package/src/commands/account/login/login.ts +48 -6
  225. package/src/commands/account/logout/logout.ts +4 -0
  226. package/src/commands/halo/index.ts +6 -2
  227. package/src/commands/halo/share/share.ts +16 -5
  228. package/src/commands/profile/create.ts +23 -40
  229. package/src/containers/AccountContainer/AccountContainer.tsx +6 -5
  230. package/src/containers/DevicesContainer/DevicesContainer.tsx +2 -0
  231. package/src/containers/InvitationsContainer/InvitationsContainer.tsx +2 -0
  232. package/src/containers/JoinDialog/JoinDialog.tsx +2 -0
  233. package/src/containers/ProfileContainer/ProfileContainer.tsx +19 -13
  234. package/src/containers/RecoveryCodeDialog/RecoveryCodeDialog.tsx +2 -0
  235. package/src/containers/RecoveryCredentialsContainer/RecoveryCredentialsContainer.tsx +7 -9
  236. package/src/containers/ResetDialog/ResetDialog.tsx +2 -0
  237. package/src/containers/UsageContainer/UsageContainer.tsx +10 -1
  238. package/src/containers/UsageContainer/UsageView.stories.tsx +0 -12
  239. package/src/containers/UsageContainer/UsageView.tsx +9 -10
  240. package/src/halo-services-layer.ts +29 -0
  241. package/src/index.ts +9 -0
  242. package/src/operations/definitions.ts +9 -1
  243. package/src/operations/errors.test.ts +27 -0
  244. package/src/operations/errors.ts +47 -0
  245. package/src/operations/index.ts +3 -0
  246. package/src/operations/open-usage.ts +3 -3
  247. package/src/operations/redeem-passkey.ts +85 -55
  248. package/src/operations/resolve-navigation-targets.ts +71 -0
  249. package/src/operations/share-identity.ts +3 -3
  250. package/src/operations/update-profile.ts +20 -0
  251. package/src/progress/index.ts +5 -0
  252. package/src/progress/progress-keys.ts +15 -0
  253. package/src/testing/initializeIdentity.ts +10 -2
  254. package/src/translations.ts +2 -0
  255. package/src/types/capabilities.ts +15 -1
  256. package/src/types/schema.ts +7 -0
  257. package/dist/lib/neutral/AccountContainer-7SF53UON.mjs +0 -186
  258. package/dist/lib/neutral/AccountContainer-7SF53UON.mjs.map +0 -7
  259. package/dist/lib/neutral/ClientPlugin.mjs +0 -72
  260. package/dist/lib/neutral/ClientPlugin.mjs.map +0 -7
  261. package/dist/lib/neutral/ClientPlugin.node.mjs +0 -1156
  262. package/dist/lib/neutral/ClientPlugin.node.mjs.map +0 -7
  263. package/dist/lib/neutral/ClientPlugin.workerd.mjs +0 -16
  264. package/dist/lib/neutral/ClientPlugin.workerd.mjs.map +0 -7
  265. package/dist/lib/neutral/DevicesContainer-PRWIN36N.mjs +0 -271
  266. package/dist/lib/neutral/DevicesContainer-PRWIN36N.mjs.map +0 -7
  267. package/dist/lib/neutral/InvitationsContainer-BI5RAWET.mjs +0 -143
  268. package/dist/lib/neutral/InvitationsContainer-BI5RAWET.mjs.map +0 -7
  269. package/dist/lib/neutral/JoinDialog-4BWV4CYB.mjs +0 -53
  270. package/dist/lib/neutral/JoinDialog-4BWV4CYB.mjs.map +0 -7
  271. package/dist/lib/neutral/ProfileContainer-YEAYOTX5.mjs +0 -169
  272. package/dist/lib/neutral/ProfileContainer-YEAYOTX5.mjs.map +0 -7
  273. package/dist/lib/neutral/RecoveryCodeDialog-7EPNKCLB.mjs +0 -59
  274. package/dist/lib/neutral/RecoveryCodeDialog-7EPNKCLB.mjs.map +0 -7
  275. package/dist/lib/neutral/RecoveryCredentialsContainer-6BZ2IWX7.mjs +0 -60
  276. package/dist/lib/neutral/RecoveryCredentialsContainer-6BZ2IWX7.mjs.map +0 -7
  277. package/dist/lib/neutral/ResetDialog-KUWX45JY.mjs +0 -57
  278. package/dist/lib/neutral/ResetDialog-KUWX45JY.mjs.map +0 -7
  279. package/dist/lib/neutral/UsageContainer-2DWCVVE4.mjs +0 -241
  280. package/dist/lib/neutral/UsageContainer-2DWCVVE4.mjs.map +0 -7
  281. package/dist/lib/neutral/account-cache-YVQKLNV2.mjs.map +0 -7
  282. package/dist/lib/neutral/app-graph-builder-RVXTD6OE.mjs +0 -159
  283. package/dist/lib/neutral/app-graph-builder-RVXTD6OE.mjs.map +0 -7
  284. package/dist/lib/neutral/capabilities/index.mjs +0 -34
  285. package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
  286. package/dist/lib/neutral/capabilities/node.mjs +0 -21
  287. package/dist/lib/neutral/capabilities/node.mjs.map +0 -7
  288. package/dist/lib/neutral/chunk-6G4KZLBG.mjs.map +0 -7
  289. package/dist/lib/neutral/chunk-7DEIKHB7.mjs +0 -199
  290. package/dist/lib/neutral/chunk-7DEIKHB7.mjs.map +0 -7
  291. package/dist/lib/neutral/chunk-A7WDDIWY.mjs +0 -162
  292. package/dist/lib/neutral/chunk-A7WDDIWY.mjs.map +0 -7
  293. package/dist/lib/neutral/chunk-GSKMAS3S.mjs.map +0 -7
  294. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
  295. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
  296. package/dist/lib/neutral/chunk-JY35S2CN.mjs +0 -27
  297. package/dist/lib/neutral/chunk-JY35S2CN.mjs.map +0 -7
  298. package/dist/lib/neutral/chunk-ZFABGG2E.mjs +0 -8
  299. package/dist/lib/neutral/chunk-ZFABGG2E.mjs.map +0 -7
  300. package/dist/lib/neutral/client-7I5Y5SOA.mjs +0 -62
  301. package/dist/lib/neutral/client-7I5Y5SOA.mjs.map +0 -7
  302. package/dist/lib/neutral/components/index.mjs +0 -1
  303. package/dist/lib/neutral/components/index.mjs.map +0 -7
  304. package/dist/lib/neutral/containers/index.mjs +0 -25
  305. package/dist/lib/neutral/containers/index.mjs.map +0 -7
  306. package/dist/lib/neutral/create-agent-6UKJMZS5.mjs +0 -26
  307. package/dist/lib/neutral/create-agent-6UKJMZS5.mjs.map +0 -7
  308. package/dist/lib/neutral/create-identity-ULCRB3YH.mjs +0 -42
  309. package/dist/lib/neutral/create-identity-ULCRB3YH.mjs.map +0 -7
  310. package/dist/lib/neutral/create-passkey-I7VDS3AC.mjs +0 -81
  311. package/dist/lib/neutral/create-passkey-I7VDS3AC.mjs.map +0 -7
  312. package/dist/lib/neutral/create-recovery-code-DH2B6EGP.mjs +0 -36
  313. package/dist/lib/neutral/create-recovery-code-DH2B6EGP.mjs.map +0 -7
  314. package/dist/lib/neutral/hub-http-client-WOJUCDKV.mjs +0 -19
  315. package/dist/lib/neutral/hub-http-client-WOJUCDKV.mjs.map +0 -7
  316. package/dist/lib/neutral/index.mjs +0 -25
  317. package/dist/lib/neutral/index.mjs.map +0 -7
  318. package/dist/lib/neutral/join-identity-PJCHDNLH.mjs +0 -27
  319. package/dist/lib/neutral/join-identity-PJCHDNLH.mjs.map +0 -7
  320. package/dist/lib/neutral/layer-specs-YI7BVWKZ.mjs +0 -59
  321. package/dist/lib/neutral/layer-specs-YI7BVWKZ.mjs.map +0 -7
  322. package/dist/lib/neutral/meta.json +0 -1
  323. package/dist/lib/neutral/meta.mjs +0 -8
  324. package/dist/lib/neutral/meta.mjs.map +0 -7
  325. package/dist/lib/neutral/migrations-7FTW55ER.mjs +0 -23
  326. package/dist/lib/neutral/migrations-7FTW55ER.mjs.map +0 -7
  327. package/dist/lib/neutral/navigation-handler-MQ6MZXLX.mjs +0 -46
  328. package/dist/lib/neutral/navigation-handler-MQ6MZXLX.mjs.map +0 -7
  329. package/dist/lib/neutral/open-usage-OJVTPGOY.mjs +0 -27
  330. package/dist/lib/neutral/open-usage-OJVTPGOY.mjs.map +0 -7
  331. package/dist/lib/neutral/operation-handler-E3HB7E2T.mjs +0 -13
  332. package/dist/lib/neutral/operation-handler-E3HB7E2T.mjs.map +0 -7
  333. package/dist/lib/neutral/operations/index.mjs +0 -12
  334. package/dist/lib/neutral/operations/index.mjs.map +0 -7
  335. package/dist/lib/neutral/plugin.mjs +0 -17
  336. package/dist/lib/neutral/plugin.mjs.map +0 -7
  337. package/dist/lib/neutral/react-context-V74T6JOJ.mjs +0 -23
  338. package/dist/lib/neutral/react-context-V74T6JOJ.mjs.map +0 -7
  339. package/dist/lib/neutral/react-surface-HPXRA65U.mjs +0 -75
  340. package/dist/lib/neutral/react-surface-HPXRA65U.mjs.map +0 -7
  341. package/dist/lib/neutral/recover-identity-B7YM2BR4.mjs +0 -26
  342. package/dist/lib/neutral/recover-identity-B7YM2BR4.mjs.map +0 -7
  343. package/dist/lib/neutral/redeem-passkey-TYP4XLHO.mjs +0 -66
  344. package/dist/lib/neutral/redeem-passkey-TYP4XLHO.mjs.map +0 -7
  345. package/dist/lib/neutral/redeem-token-2J33R3PV.mjs +0 -29
  346. package/dist/lib/neutral/redeem-token-2J33R3PV.mjs.map +0 -7
  347. package/dist/lib/neutral/reset-storage-K47HZTGP.mjs +0 -26
  348. package/dist/lib/neutral/reset-storage-K47HZTGP.mjs.map +0 -7
  349. package/dist/lib/neutral/schema-defs-IHBCKTMM.mjs +0 -51
  350. package/dist/lib/neutral/schema-defs-IHBCKTMM.mjs.map +0 -7
  351. package/dist/lib/neutral/share-identity-TOROBLWL.mjs +0 -31
  352. package/dist/lib/neutral/share-identity-TOROBLWL.mjs.map +0 -7
  353. package/dist/lib/neutral/testing/index.mjs +0 -25
  354. package/dist/lib/neutral/testing/index.mjs.map +0 -7
  355. package/dist/lib/neutral/translations.mjs +0 -124
  356. package/dist/lib/neutral/translations.mjs.map +0 -7
  357. package/dist/lib/neutral/types/index.mjs +0 -16
  358. package/dist/lib/neutral/types/index.mjs.map +0 -7
@@ -0,0 +1,275 @@
1
+ import { hexToEmoji } from "@dxos/util";
2
+ import { meta } from "#meta";
3
+ import { ClientOperation } from "#operations";
4
+ import { log } from "@dxos/log";
5
+ import { useCallback, useEffect, useState } from "react";
6
+ import { AuthCode, Centered, DeviceListItem, Emoji, Viewport } from "@dxos/shell/react";
7
+ import { useOperationInvoker } from "@dxos/app-framework/ui";
8
+ import { useClient, useMulticastObservable } from "@dxos/react-client";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { Button, Clipboard, Icon, IconButton, useId, useTranslation } from "@dxos/react-ui";
11
+ import { Form } from "@dxos/react-ui-form";
12
+ import { useDevices } from "@dxos/react-client/halo";
13
+ import { QR } from "react-qr-rounded";
14
+ import { Invitation, InvitationEncoder } from "@dxos/react-client/invitations";
15
+ import { useNetworkStatus } from "@dxos/react-client/mesh";
16
+ import { Listbox } from "@dxos/react-ui-list";
17
+ import { osTranslations } from "@dxos/ui-theme";
18
+ //#region src/containers/DevicesContainer/DevicesContainer.tsx
19
+ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-client/src/containers/DevicesContainer/DevicesContainer.tsx";
20
+ var DevicesContainer = ({ createInvitationUrl }) => {
21
+ const { t } = useTranslation(meta.profile.key);
22
+ const { invokePromise } = useOperationInvoker();
23
+ const devices = useDevices();
24
+ const { swarm: connectionState } = useNetworkStatus();
25
+ const handleResetStorage = useCallback(() => invokePromise(ClientOperation.ResetStorage, {}), [invokePromise]);
26
+ const handleRecover = useCallback(() => invokePromise(ClientOperation.ResetStorage, { mode: "recover" }), [invokePromise]);
27
+ const handleJoinNewIdentity = useCallback(() => invokePromise(ClientOperation.ResetStorage, { mode: "join-new-identity" }), [invokePromise]);
28
+ return /* @__PURE__ */ jsx(Clipboard.Provider, { children: /* @__PURE__ */ jsx(Form.Root, {
29
+ variant: "settings",
30
+ children: /* @__PURE__ */ jsx(Form.Viewport, {
31
+ scroll: true,
32
+ children: /* @__PURE__ */ jsxs(Form.Content, { children: [/* @__PURE__ */ jsx(Form.Section, {
33
+ title: t("devices-verbose.label", { ns: meta.profile.key }),
34
+ description: t("devices.description", { ns: meta.profile.key }),
35
+ children: /* @__PURE__ */ jsxs(Form.Group, { children: [/* @__PURE__ */ jsxs("div", {
36
+ role: "group",
37
+ className: "min-w-0",
38
+ children: [/* @__PURE__ */ jsx("h3", {
39
+ className: "text-lg mb-2",
40
+ children: t("devices.label", { ns: meta.profile.key })
41
+ }), /* @__PURE__ */ jsx(Listbox.Root, { children: /* @__PURE__ */ jsx(Listbox.Content, {
42
+ "aria-label": t("devices.label", { ns: meta.profile.key }),
43
+ children: devices.map((device) => /* @__PURE__ */ jsx(DeviceListItem, {
44
+ device,
45
+ connectionState
46
+ }, device.deviceKey.toHex()))
47
+ }) })]
48
+ }), createInvitationUrl && /* @__PURE__ */ jsxs("div", {
49
+ role: "group",
50
+ className: "min-w-0",
51
+ children: [/* @__PURE__ */ jsx("h3", {
52
+ className: "text-lg mb-2",
53
+ children: t("add-device.label")
54
+ }), /* @__PURE__ */ jsx(DeviceInvitation, { createInvitationUrl })]
55
+ })] })
56
+ }), /* @__PURE__ */ jsxs(Form.Section, {
57
+ title: t("danger-zone.title", { ns: meta.profile.key }),
58
+ description: t("danger-zone.description", { ns: meta.profile.key }),
59
+ children: [
60
+ /* @__PURE__ */ jsx(Form.Row, {
61
+ label: t("reset-device.label"),
62
+ description: t("reset-device.description", { ns: meta.profile.key }),
63
+ children: /* @__PURE__ */ jsx(Button, {
64
+ variant: "destructive",
65
+ onClick: handleResetStorage,
66
+ "data-testid": "devicesContainer.reset",
67
+ children: t("reset-device.label")
68
+ })
69
+ }),
70
+ /* @__PURE__ */ jsx(Form.Row, {
71
+ label: t("recover-identity.label"),
72
+ description: t("recover-identity.description", { ns: meta.profile.key }),
73
+ children: /* @__PURE__ */ jsx(Button, {
74
+ variant: "destructive",
75
+ onClick: handleRecover,
76
+ "data-testid": "devicesContainer.recover",
77
+ children: t("recover-identity.label")
78
+ })
79
+ }),
80
+ /* @__PURE__ */ jsx(Form.Row, {
81
+ label: t("join-new-identity.label"),
82
+ description: t("join-new-identity.description", { ns: meta.profile.key }),
83
+ children: /* @__PURE__ */ jsx(Button, {
84
+ variant: "destructive",
85
+ onClick: handleJoinNewIdentity,
86
+ "data-testid": "devicesContainer.joinExisting",
87
+ children: t("join-new-identity.label")
88
+ })
89
+ })
90
+ ]
91
+ })] })
92
+ })
93
+ }) });
94
+ };
95
+ var DeviceInvitation = (props) => {
96
+ const client = useClient();
97
+ const [invitation, setInvitation] = useState();
98
+ const onInvitationCreate = useCallback(() => {
99
+ const invitation = client.halo.share();
100
+ if (client.config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
101
+ const subscription = invitation.subscribe((invitation) => {
102
+ const invitationCode = InvitationEncoder.encode(invitation);
103
+ if (invitation.state === Invitation.State.CONNECTING) {
104
+ log.info(JSON.stringify({
105
+ invitationCode,
106
+ authCode: invitation.authCode
107
+ }), void 0, {
108
+ "~LogMeta": "~LogMeta",
109
+ F: __dxlog_file,
110
+ L: 135,
111
+ S: void 0
112
+ });
113
+ subscription.unsubscribe();
114
+ }
115
+ });
116
+ }
117
+ setInvitation(invitation);
118
+ }, [client]);
119
+ const onInvitationDone = useCallback(() => {
120
+ setInvitation(void 0);
121
+ }, []);
122
+ if (invitation) return /* @__PURE__ */ jsx(DeviceInvitationImpl, {
123
+ ...props,
124
+ invitation,
125
+ onInvitationCreate,
126
+ onInvitationDone
127
+ });
128
+ else return /* @__PURE__ */ jsx(InvitationSection, {
129
+ ...props,
130
+ onInvitationCreate,
131
+ onInvitationDone
132
+ });
133
+ };
134
+ var DeviceInvitationImpl = ({ invitation: invitationObservable, createInvitationUrl, onInvitationDone, onInvitationCreate }) => {
135
+ const invitation = useMulticastObservable(invitationObservable);
136
+ const url = createInvitationUrl(InvitationEncoder.encode(invitation));
137
+ useEffect(() => {
138
+ if (invitation.state >= Invitation.State.SUCCESS) onInvitationDone();
139
+ }, [invitation.state]);
140
+ return /* @__PURE__ */ jsx(InvitationSection, {
141
+ ...invitation,
142
+ url,
143
+ onInvitationDone,
144
+ onInvitationCreate
145
+ });
146
+ };
147
+ var InvitationSection = ({ state = -1, authCode, invitationId = "never", url = "never", onInvitationDone = () => {}, onInvitationCreate = () => {} }) => {
148
+ const { t } = useTranslation(meta.profile.key);
149
+ const activeView = state < 0 ? "init" : state >= Invitation.State.CANCELLED ? "complete" : state >= Invitation.State.READY_FOR_AUTHENTICATION && authCode ? "auth-code" : "qr-code";
150
+ return activeView === "init" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
151
+ className: "text-description mb-2",
152
+ children: t("add-device.description")
153
+ }), /* @__PURE__ */ jsx(IconButton, {
154
+ icon: "ph--plus--regular",
155
+ label: t("create-device-invitation.label"),
156
+ disabled: state >= 0,
157
+ classNames: "w-full",
158
+ "data-testid": "devicesContainer.createInvitation",
159
+ onClick: onInvitationCreate
160
+ })] }) : /* @__PURE__ */ jsx(Viewport.Root, {
161
+ activeView,
162
+ children: /* @__PURE__ */ jsxs(Viewport.Views, { children: [
163
+ /* @__PURE__ */ jsx(Viewport.View, { id: "init" }),
164
+ /* @__PURE__ */ jsx(Viewport.View, {
165
+ id: "complete",
166
+ children: /* @__PURE__ */ jsx(InvitationComplete, { statusValue: state })
167
+ }),
168
+ /* @__PURE__ */ jsx(Viewport.View, {
169
+ id: "auth-code",
170
+ children: /* @__PURE__ */ jsx(InvitationAuthCode, {
171
+ id: invitationId,
172
+ code: authCode ?? "never",
173
+ onCancel: onInvitationDone
174
+ })
175
+ }),
176
+ /* @__PURE__ */ jsx(Viewport.View, {
177
+ id: "qr-code",
178
+ children: /* @__PURE__ */ jsx(InvitationQR, {
179
+ id: invitationId,
180
+ url,
181
+ onCancel: onInvitationDone
182
+ })
183
+ })
184
+ ] })
185
+ });
186
+ };
187
+ var InvitationQR = ({ id, url, onCancel }) => {
188
+ const { t } = useTranslation(osTranslations);
189
+ const qrLabel = useId("devices-container__qr-code");
190
+ const emoji = hexToEmoji(id);
191
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
192
+ /* @__PURE__ */ jsx("p", {
193
+ className: "text-description",
194
+ children: t("qr-code.description", { ns: meta.profile.key })
195
+ }),
196
+ /* @__PURE__ */ jsxs("div", {
197
+ role: "group",
198
+ className: "grid grid-cols-[1fr_min-content]",
199
+ children: [/* @__PURE__ */ jsx("div", {
200
+ className: "flex justify-center py-4",
201
+ children: /* @__PURE__ */ jsxs("div", {
202
+ className: "w-full md:max-w-80 aspect-square relative text-description",
203
+ children: [/* @__PURE__ */ jsx(QR, {
204
+ rounding: 100,
205
+ backgroundColor: "transparent",
206
+ color: "currentColor",
207
+ "aria-labelledby": qrLabel,
208
+ errorCorrectionLevel: "Q",
209
+ cutout: true,
210
+ children: url ?? "never"
211
+ }), /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(Emoji, { text: emoji }) })]
212
+ })
213
+ }), /* @__PURE__ */ jsx("span", {
214
+ id: qrLabel,
215
+ className: "sr-only",
216
+ children: t("qr.label")
217
+ })]
218
+ }),
219
+ /* @__PURE__ */ jsx("div", {
220
+ className: "flex justify-center",
221
+ children: /* @__PURE__ */ jsxs("div", {
222
+ className: "flex gap-2",
223
+ children: [/* @__PURE__ */ jsx(Clipboard.Button, { value: url ?? "never" }), /* @__PURE__ */ jsx(Button, {
224
+ variant: "ghost",
225
+ onClick: onCancel,
226
+ children: t("cancel.label")
227
+ })]
228
+ })
229
+ })
230
+ ] });
231
+ };
232
+ var InvitationAuthCode = ({ id, code, onCancel }) => {
233
+ const { t } = useTranslation(osTranslations);
234
+ const emoji = hexToEmoji(id);
235
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
236
+ /* @__PURE__ */ jsx("p", {
237
+ className: "text-description",
238
+ children: t("auth-other-device-emoji.message")
239
+ }),
240
+ emoji && /* @__PURE__ */ jsx(Emoji, {
241
+ text: emoji,
242
+ className: "mx-auto my-2 text-center"
243
+ }),
244
+ /* @__PURE__ */ jsx("p", {
245
+ className: "text-description",
246
+ children: t("auth-code.message")
247
+ }),
248
+ /* @__PURE__ */ jsx(AuthCode, {
249
+ code,
250
+ large: true,
251
+ classNames: "mx-auto my-2 text-center grow"
252
+ }),
253
+ /* @__PURE__ */ jsx(Button, {
254
+ variant: "ghost",
255
+ onClick: onCancel,
256
+ children: t("cancel.label")
257
+ })
258
+ ] });
259
+ };
260
+ var InvitationComplete = ({ statusValue }) => {
261
+ return statusValue > 0 ? /* @__PURE__ */ jsx(Icon, {
262
+ icon: "ph--check--regular",
263
+ size: 6,
264
+ classNames: "m-1.5"
265
+ }) : /* @__PURE__ */ jsx(Icon, {
266
+ icon: "ph--x--regular",
267
+ size: 6,
268
+ classNames: "m-1.5"
269
+ });
270
+ };
271
+ DevicesContainer.displayName = "DevicesContainer";
272
+ //#endregion
273
+ export { DevicesContainer as default };
274
+
275
+ //# sourceMappingURL=chunk-DevicesContainer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-DevicesContainer.mjs","names":[],"sources":["../../src/containers/DevicesContainer/DevicesContainer.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { QR } from 'react-qr-rounded';\n\nimport { useOperationInvoker } from '@dxos/app-framework/ui';\nimport { log } from '@dxos/log';\nimport { useClient, useMulticastObservable } from '@dxos/react-client';\nimport { type Device, useDevices } from '@dxos/react-client/halo';\nimport { type CancellableInvitationObservable, Invitation, InvitationEncoder } from '@dxos/react-client/invitations';\nimport { useNetworkStatus } from '@dxos/react-client/mesh';\nimport { Button, Clipboard, Icon, IconButton, useId, useTranslation } from '@dxos/react-ui';\nimport { Form } from '@dxos/react-ui-form';\nimport { Listbox } from '@dxos/react-ui-list';\nimport { AuthCode, Centered, DeviceListItem, Emoji, Viewport } from '@dxos/shell/react';\nimport { osTranslations } from '@dxos/ui-theme';\nimport { hexToEmoji } from '@dxos/util';\n\nimport { meta } from '#meta';\nimport { ClientOperation } from '#operations';\n\nexport type DevicesContainerProps = {\n createInvitationUrl?: (invitationCode: string) => string;\n};\n\nexport const DevicesContainer = ({ createInvitationUrl }: DevicesContainerProps) => {\n const { t } = useTranslation(meta.profile.key);\n const { invokePromise } = useOperationInvoker();\n const devices = useDevices();\n const { swarm: connectionState } = useNetworkStatus();\n\n const handleResetStorage = useCallback(() => invokePromise(ClientOperation.ResetStorage, {}), [invokePromise]);\n\n const handleRecover = useCallback(\n () => invokePromise(ClientOperation.ResetStorage, { mode: 'recover' }),\n [invokePromise],\n );\n\n const handleJoinNewIdentity = useCallback(\n () => invokePromise(ClientOperation.ResetStorage, { mode: 'join-new-identity' }),\n [invokePromise],\n );\n\n return (\n <Clipboard.Provider>\n <Form.Root variant='settings'>\n <Form.Viewport scroll>\n <Form.Content>\n <Form.Section\n title={t('devices-verbose.label', { ns: meta.profile.key })}\n description={t('devices.description', { ns: meta.profile.key })}\n >\n <Form.Group>\n <div role='group' className='min-w-0'>\n <h3 className='text-lg mb-2'>{t('devices.label', { ns: meta.profile.key })}</h3>\n <Listbox.Root>\n <Listbox.Content aria-label={t('devices.label', { ns: meta.profile.key })}>\n {devices.map((device: Device) => (\n <DeviceListItem\n key={device.deviceKey.toHex()}\n device={device}\n connectionState={connectionState}\n />\n ))}\n </Listbox.Content>\n </Listbox.Root>\n </div>\n {createInvitationUrl && (\n <div role='group' className='min-w-0'>\n <h3 className='text-lg mb-2'>{t('add-device.label')}</h3>\n <DeviceInvitation createInvitationUrl={createInvitationUrl} />\n </div>\n )}\n </Form.Group>\n </Form.Section>\n <Form.Section\n title={t('danger-zone.title', { ns: meta.profile.key })}\n description={t('danger-zone.description', { ns: meta.profile.key })}\n >\n <Form.Row\n label={t('reset-device.label')}\n description={t('reset-device.description', { ns: meta.profile.key })}\n >\n <Button variant='destructive' onClick={handleResetStorage} data-testid='devicesContainer.reset'>\n {t('reset-device.label')}\n </Button>\n </Form.Row>\n <Form.Row\n label={t('recover-identity.label')}\n description={t('recover-identity.description', { ns: meta.profile.key })}\n >\n <Button variant='destructive' onClick={handleRecover} data-testid='devicesContainer.recover'>\n {t('recover-identity.label')}\n </Button>\n </Form.Row>\n <Form.Row\n label={t('join-new-identity.label')}\n description={t('join-new-identity.description', { ns: meta.profile.key })}\n >\n <Button\n variant='destructive'\n onClick={handleJoinNewIdentity}\n data-testid='devicesContainer.joinExisting'\n >\n {t('join-new-identity.label')}\n </Button>\n </Form.Row>\n </Form.Section>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n </Clipboard.Provider>\n );\n};\n\ntype DeviceInvitationProps = {\n invitation?: CancellableInvitationObservable;\n createInvitationUrl: (invitationCode: string) => string;\n onInvitationDone: () => void;\n onInvitationCreate: () => void;\n};\n\nconst DeviceInvitation = (props: Pick<DeviceInvitationProps, 'createInvitationUrl'>) => {\n const client = useClient();\n const [invitation, setInvitation] = useState<CancellableInvitationObservable>();\n\n const onInvitationCreate = useCallback(() => {\n const invitation = client.halo.share();\n if (client.config.values.runtime?.app?.env?.DX_ENVIRONMENT !== 'production') {\n const subscription = invitation.subscribe((invitation: Invitation) => {\n const invitationCode = InvitationEncoder.encode(invitation);\n if (invitation.state === Invitation.State.CONNECTING) {\n log.info(JSON.stringify({ invitationCode, authCode: invitation.authCode }));\n subscription.unsubscribe();\n }\n });\n }\n setInvitation(invitation);\n }, [client]);\n\n const onInvitationDone = useCallback(() => {\n setInvitation(undefined);\n }, []);\n\n if (invitation) {\n return <DeviceInvitationImpl {...props} {...{ invitation, onInvitationCreate, onInvitationDone }} />;\n } else {\n return <InvitationSection {...props} {...{ onInvitationCreate, onInvitationDone }} />;\n }\n};\n\nconst DeviceInvitationImpl = ({\n invitation: invitationObservable,\n createInvitationUrl,\n onInvitationDone,\n onInvitationCreate,\n}: DeviceInvitationProps) => {\n const invitation = useMulticastObservable(invitationObservable!);\n const url = createInvitationUrl(InvitationEncoder.encode(invitation));\n\n useEffect(() => {\n if (invitation.state >= Invitation.State.SUCCESS) {\n onInvitationDone();\n }\n }, [invitation.state]);\n\n return <InvitationSection {...invitation} {...{ url, onInvitationDone, onInvitationCreate }} />;\n};\n\ntype InvitationComponentProps = Partial<\n Pick<Invitation, 'authCode' | 'invitationId'> &\n Pick<DeviceInvitationProps, 'onInvitationDone' | 'onInvitationCreate'> & {\n state: number;\n url: string;\n }\n>;\n\nconst InvitationSection = ({\n state = -1,\n authCode,\n invitationId = 'never',\n url = 'never',\n onInvitationDone = () => {},\n onInvitationCreate = () => {},\n}: InvitationComponentProps) => {\n const { t } = useTranslation(meta.profile.key);\n const activeView =\n state < 0\n ? 'init'\n : state >= Invitation.State.CANCELLED\n ? 'complete'\n : state >= Invitation.State.READY_FOR_AUTHENTICATION && authCode\n ? 'auth-code'\n : 'qr-code';\n\n return activeView === 'init' ? (\n <>\n <p className='text-description mb-2'>{t('add-device.description')}</p>\n <IconButton\n icon='ph--plus--regular'\n label={t('create-device-invitation.label')}\n disabled={state >= 0}\n classNames='w-full'\n data-testid='devicesContainer.createInvitation'\n onClick={onInvitationCreate}\n />\n </>\n ) : (\n <Viewport.Root activeView={activeView}>\n <Viewport.Views>\n <Viewport.View id='init'>\n {/* This view intentionally left blank while conditionally rendering the viewport. */}\n </Viewport.View>\n <Viewport.View id='complete'>\n <InvitationComplete statusValue={state} />\n </Viewport.View>\n <Viewport.View id='auth-code'>\n <InvitationAuthCode id={invitationId} code={authCode ?? 'never'} onCancel={onInvitationDone} />\n </Viewport.View>\n <Viewport.View id='qr-code'>\n <InvitationQR id={invitationId} url={url} onCancel={onInvitationDone} />\n </Viewport.View>\n </Viewport.Views>\n </Viewport.Root>\n );\n};\n\nconst InvitationQR = ({ id, url, onCancel }: { id: string; url: string; onCancel: () => void }) => {\n const { t } = useTranslation(osTranslations);\n const qrLabel = useId('devices-container__qr-code');\n const emoji = hexToEmoji(id);\n return (\n <>\n <p className='text-description'>{t('qr-code.description', { ns: meta.profile.key })}</p>\n <div role='group' className='grid grid-cols-[1fr_min-content]'>\n <div className='flex justify-center py-4'>\n <div className='w-full md:max-w-80 aspect-square relative text-description'>\n <QR\n rounding={100}\n backgroundColor='transparent'\n color='currentColor'\n aria-labelledby={qrLabel}\n errorCorrectionLevel='Q'\n cutout={true}\n >\n {url ?? 'never'}\n </QR>\n <Centered>\n <Emoji text={emoji} />\n </Centered>\n </div>\n </div>\n <span id={qrLabel} className='sr-only'>\n {t('qr.label')}\n </span>\n </div>\n {/* TODO(burdon): Factor out button bar */}\n <div className='flex justify-center'>\n <div className='flex gap-2'>\n <Clipboard.Button value={url ?? 'never'} />\n <Button variant='ghost' onClick={onCancel}>\n {t('cancel.label')}\n </Button>\n </div>\n </div>\n </>\n );\n};\n\nconst InvitationAuthCode = ({ id, code, onCancel }: { id: string; code: string; onCancel: () => void }) => {\n const { t } = useTranslation(osTranslations);\n const emoji = hexToEmoji(id);\n\n return (\n <>\n <p className='text-description'>{t('auth-other-device-emoji.message')}</p>\n {emoji && <Emoji text={emoji} className='mx-auto my-2 text-center' />}\n <p className='text-description'>{t('auth-code.message')}</p>\n <AuthCode code={code} large classNames='mx-auto my-2 text-center grow' />\n <Button variant='ghost' onClick={onCancel}>\n {t('cancel.label')}\n </Button>\n </>\n );\n};\n\nconst InvitationComplete = ({ statusValue }: { statusValue: number }) => {\n return statusValue > 0 ? (\n <Icon icon='ph--check--regular' size={6} classNames='m-1.5' />\n ) : (\n <Icon icon='ph--x--regular' size={6} classNames='m-1.5' />\n );\n};\n\nDevicesContainer.displayName = 'DevicesContainer';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA2BA,IAAa,oBAAoB,EAAE,0BAAiD;CAClF,MAAM,EAAE,MAAM,eAAe,KAAK,QAAQ,GAAG;CAC7C,MAAM,EAAE,kBAAkB,oBAAoB;CAC9C,MAAM,UAAU,WAAW;CAC3B,MAAM,EAAE,OAAO,oBAAoB,iBAAiB;CAEpD,MAAM,qBAAqB,kBAAkB,cAAc,gBAAgB,cAAc,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC;CAE7G,MAAM,gBAAgB,kBACd,cAAc,gBAAgB,cAAc,EAAE,MAAM,UAAU,CAAC,GACrE,CAAC,aAAa,CAChB;CAEA,MAAM,wBAAwB,kBACtB,cAAc,gBAAgB,cAAc,EAAE,MAAM,oBAAoB,CAAC,GAC/E,CAAC,aAAa,CAChB;CAEA,OACE,oBAAC,UAAU,UAAX,EAAA,UACE,oBAAC,KAAK,MAAN;EAAW,SAAQ;YACjB,oBAAC,KAAK,UAAN;GAAe,QAAA;aACb,qBAAC,KAAK,SAAN,EAAA,UAAA,CACE,oBAAC,KAAK,SAAN;IACE,OAAO,EAAE,yBAAyB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;IAC1D,aAAa,EAAE,uBAAuB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;cAE9D,qBAAC,KAAK,OAAN,EAAA,UAAA,CACE,qBAAC,OAAD;KAAK,MAAK;KAAQ,WAAU;eAA5B,CACE,oBAAC,MAAD;MAAI,WAAU;gBAAgB,EAAE,iBAAiB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;KAAM,CAAA,GAC/E,oBAAC,QAAQ,MAAT,EAAA,UACE,oBAAC,QAAQ,SAAT;MAAiB,cAAY,EAAE,iBAAiB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;gBACrE,QAAQ,KAAK,WACZ,oBAAC,gBAAD;OAEU;OACS;MAClB,GAHM,OAAO,UAAU,MAAM,CAG7B,CACF;KACc,CAAA,EACL,CAAA,CACX;QACJ,uBACC,qBAAC,OAAD;KAAK,MAAK;KAAQ,WAAU;eAA5B,CACE,oBAAC,MAAD;MAAI,WAAU;gBAAgB,EAAE,kBAAkB;KAAM,CAAA,GACxD,oBAAC,kBAAD,EAAuC,oBAAsB,CAAA,CAC1D;MAEG,EAAA,CAAA;GACA,CAAA,GACd,qBAAC,KAAK,SAAN;IACE,OAAO,EAAE,qBAAqB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;IACtD,aAAa,EAAE,2BAA2B,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;cAFpE;KAIE,oBAAC,KAAK,KAAN;MACE,OAAO,EAAE,oBAAoB;MAC7B,aAAa,EAAE,4BAA4B,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;gBAEnE,oBAAC,QAAD;OAAQ,SAAQ;OAAc,SAAS;OAAoB,eAAY;iBACpE,EAAE,oBAAoB;MACjB,CAAA;KACA,CAAA;KACV,oBAAC,KAAK,KAAN;MACE,OAAO,EAAE,wBAAwB;MACjC,aAAa,EAAE,gCAAgC,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;gBAEvE,oBAAC,QAAD;OAAQ,SAAQ;OAAc,SAAS;OAAe,eAAY;iBAC/D,EAAE,wBAAwB;MACrB,CAAA;KACA,CAAA;KACV,oBAAC,KAAK,KAAN;MACE,OAAO,EAAE,yBAAyB;MAClC,aAAa,EAAE,iCAAiC,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;gBAExE,oBAAC,QAAD;OACE,SAAQ;OACR,SAAS;OACT,eAAY;iBAEX,EAAE,yBAAyB;MACtB,CAAA;KACA,CAAA;IACE;KACF,EAAA,CAAA;EACD,CAAA;CACN,CAAA,EACO,CAAA;AAExB;AASA,IAAM,oBAAoB,UAA8D;CACtF,MAAM,SAAS,UAAU;CACzB,MAAM,CAAC,YAAY,iBAAiB,SAA0C;CAE9E,MAAM,qBAAqB,kBAAkB;EAC3C,MAAM,aAAa,OAAO,KAAK,MAAM;EACrC,IAAI,OAAO,OAAO,OAAO,SAAS,KAAK,KAAK,mBAAmB,cAAc;GAC3E,MAAM,eAAe,WAAW,WAAW,eAA2B;IACpE,MAAM,iBAAiB,kBAAkB,OAAO,UAAU;IAC1D,IAAI,WAAW,UAAU,WAAW,MAAM,YAAY;KACpD,IAAI,KAAK,KAAK,UAAU;MAAE;MAAgB,UAAU,WAAW;KAAS,CAAC,GAAA,KAAA,GAAA;MAAA,YAAA;MAAA,GAAA;MAAA,GAAA;MAAA,GAAA,KAAA;KAAA,CAAC;KAC1E,aAAa,YAAY;IAC3B;GACF,CAAC;EACH;EACA,cAAc,UAAU;CAC1B,GAAG,CAAC,MAAM,CAAC;CAEX,MAAM,mBAAmB,kBAAkB;EACzC,cAAc,KAAA,CAAS;CACzB,GAAG,CAAC,CAAC;CAEL,IAAI,YACF,OAAO,oBAAC,sBAAD;EAAsB,GAAI;EAAa;EAAY;EAAoB;CAAqB,CAAA;MAEnG,OAAO,oBAAC,mBAAD;EAAmB,GAAI;EAAa;EAAoB;CAAqB,CAAA;AAExF;AAEA,IAAM,wBAAwB,EAC5B,YAAY,sBACZ,qBACA,kBACA,yBAC2B;CAC3B,MAAM,aAAa,uBAAuB,oBAAqB;CAC/D,MAAM,MAAM,oBAAoB,kBAAkB,OAAO,UAAU,CAAC;CAEpE,gBAAgB;EACd,IAAI,WAAW,SAAS,WAAW,MAAM,SACvC,iBAAiB;CAErB,GAAG,CAAC,WAAW,KAAK,CAAC;CAErB,OAAO,oBAAC,mBAAD;EAAmB,GAAI;EAAkB;EAAK;EAAkB;CAAuB,CAAA;AAChG;AAUA,IAAM,qBAAqB,EACzB,QAAQ,IACR,UACA,eAAe,SACf,MAAM,SACN,yBAAyB,CAAC,GAC1B,2BAA2B,CAAC,QACE;CAC9B,MAAM,EAAE,MAAM,eAAe,KAAK,QAAQ,GAAG;CAC7C,MAAM,aACJ,QAAQ,IACJ,SACA,SAAS,WAAW,MAAM,YACxB,aACA,SAAS,WAAW,MAAM,4BAA4B,WACpD,cACA;CAEV,OAAO,eAAe,SACpB,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,KAAD;EAAG,WAAU;YAAyB,EAAE,wBAAwB;CAAK,CAAA,GACrE,oBAAC,YAAD;EACE,MAAK;EACL,OAAO,EAAE,gCAAgC;EACzC,UAAU,SAAS;EACnB,YAAW;EACX,eAAY;EACZ,SAAS;CACV,CAAA,CACD,EAAA,CAAA,IAEF,oBAAC,SAAS,MAAV;EAA2B;YACzB,qBAAC,SAAS,OAAV,EAAA,UAAA;GACE,oBAAC,SAAS,MAAV,EAAe,IAAG,OAEH,CAAA;GACf,oBAAC,SAAS,MAAV;IAAe,IAAG;cAChB,oBAAC,oBAAD,EAAoB,aAAa,MAAQ,CAAA;GAC5B,CAAA;GACf,oBAAC,SAAS,MAAV;IAAe,IAAG;cAChB,oBAAC,oBAAD;KAAoB,IAAI;KAAc,MAAM,YAAY;KAAS,UAAU;IAAmB,CAAA;GACjF,CAAA;GACf,oBAAC,SAAS,MAAV;IAAe,IAAG;cAChB,oBAAC,cAAD;KAAc,IAAI;KAAmB;KAAK,UAAU;IAAmB,CAAA;GAC1D,CAAA;EACD,EAAA,CAAA;CACH,CAAA;AAEnB;AAEA,IAAM,gBAAgB,EAAE,IAAI,KAAK,eAAkE;CACjG,MAAM,EAAE,MAAM,eAAe,cAAc;CAC3C,MAAM,UAAU,MAAM,4BAA4B;CAClD,MAAM,QAAQ,WAAW,EAAE;CAC3B,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,KAAD;GAAG,WAAU;aAAoB,EAAE,uBAAuB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;EAAK,CAAA;EACvF,qBAAC,OAAD;GAAK,MAAK;GAAQ,WAAU;aAA5B,CACE,oBAAC,OAAD;IAAK,WAAU;cACb,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,IAAD;MACE,UAAU;MACV,iBAAgB;MAChB,OAAM;MACN,mBAAiB;MACjB,sBAAqB;MACrB,QAAQ;gBAEP,OAAO;KACN,CAAA,GACJ,oBAAC,UAAD,EAAA,UACE,oBAAC,OAAD,EAAO,MAAM,MAAQ,CAAA,EACb,CAAA,CACP;;GACF,CAAA,GACL,oBAAC,QAAD;IAAM,IAAI;IAAS,WAAU;cAC1B,EAAE,UAAU;GACT,CAAA,CACH;;EAEL,oBAAC,OAAD;GAAK,WAAU;aACb,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,UAAU,QAAX,EAAkB,OAAO,OAAO,QAAU,CAAA,GAC1C,oBAAC,QAAD;KAAQ,SAAQ;KAAQ,SAAS;eAC9B,EAAE,cAAc;IACX,CAAA,CACL;;EACF,CAAA;CACL,EAAA,CAAA;AAEN;AAEA,IAAM,sBAAsB,EAAE,IAAI,MAAM,eAAmE;CACzG,MAAM,EAAE,MAAM,eAAe,cAAc;CAC3C,MAAM,QAAQ,WAAW,EAAE;CAE3B,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,KAAD;GAAG,WAAU;aAAoB,EAAE,iCAAiC;EAAK,CAAA;EACxE,SAAS,oBAAC,OAAD;GAAO,MAAM;GAAO,WAAU;EAA4B,CAAA;EACpE,oBAAC,KAAD;GAAG,WAAU;aAAoB,EAAE,mBAAmB;EAAK,CAAA;EAC3D,oBAAC,UAAD;GAAgB;GAAM,OAAA;GAAM,YAAW;EAAiC,CAAA;EACxE,oBAAC,QAAD;GAAQ,SAAQ;GAAQ,SAAS;aAC9B,EAAE,cAAc;EACX,CAAA;CACR,EAAA,CAAA;AAEN;AAEA,IAAM,sBAAsB,EAAE,kBAA2C;CACvE,OAAO,cAAc,IACnB,oBAAC,MAAD;EAAM,MAAK;EAAqB,MAAM;EAAG,YAAW;CAAS,CAAA,IAE7D,oBAAC,MAAD;EAAM,MAAK;EAAiB,MAAM;EAAG,YAAW;CAAS,CAAA;AAE7D;AAEA,iBAAiB,cAAc"}
@@ -0,0 +1,149 @@
1
+ import { t as useHubHttpClient } from "./chunk-hooks.mjs";
2
+ import { meta } from "#meta";
3
+ import { ClientCapabilities } from "#types";
4
+ import { Context } from "@dxos/context";
5
+ import { useCallback, useState } from "react";
6
+ import { useCapability } from "@dxos/app-framework/ui";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { useAtom, useAtomSet } from "@effect-atom/atom-react";
9
+ import { Clipboard, Icon, IconButton, useAsyncEffect, useTranslation } from "@dxos/react-ui";
10
+ import { Form } from "@dxos/react-ui-form";
11
+ import { Listbox } from "@dxos/react-ui-list";
12
+ //#region src/containers/InvitationsContainer/InvitationsContainer.tsx
13
+ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-client/src/containers/InvitationsContainer/InvitationsContainer.tsx";
14
+ var InvitationsContainer = () => {
15
+ const { t } = useTranslation(meta.profile.key);
16
+ const accountCacheAtom = useCapability(ClientCapabilities.AccountCache);
17
+ const [cache] = useAtom(accountCacheAtom);
18
+ const setCache = useAtomSet(accountCacheAtom);
19
+ const [pending, setPending] = useState(false);
20
+ const hubClient = useHubHttpClient();
21
+ useAsyncEffect(async () => {
22
+ if (!hubClient) return;
23
+ try {
24
+ const result = await hubClient.listAccountInvitations(new Context(void 0, {
25
+ "~LogMeta": "~LogMeta",
26
+ F: __dxlog_file,
27
+ L: 35
28
+ }));
29
+ setCache((prev) => ({
30
+ ...prev,
31
+ invitations: result.invitations,
32
+ fetchedAt: Date.now()
33
+ }));
34
+ } catch {}
35
+ }, [hubClient, setCache]);
36
+ const handleIssue = useCallback(async () => {
37
+ if (!hubClient) return;
38
+ setPending(true);
39
+ try {
40
+ const result = await hubClient.issueAccountInvitation(new Context(void 0, {
41
+ "~LogMeta": "~LogMeta",
42
+ F: __dxlog_file,
43
+ L: 48
44
+ }));
45
+ setCache((prev) => ({
46
+ ...prev,
47
+ account: prev.account ? {
48
+ ...prev.account,
49
+ invitationsRemaining: Math.max(0, prev.account.invitationsRemaining - 1)
50
+ } : prev.account,
51
+ invitations: [{
52
+ code: result.code,
53
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
54
+ }, ...prev.invitations ?? []]
55
+ }));
56
+ } finally {
57
+ setPending(false);
58
+ }
59
+ }, [hubClient, setCache]);
60
+ const remaining = cache.account?.invitationsRemaining ?? 0;
61
+ const list = cache.invitations ?? [];
62
+ const available = list.filter((row) => !row.redeemedByIdentityDid);
63
+ const redeemed = list.filter((row) => Boolean(row.redeemedByIdentityDid));
64
+ return /* @__PURE__ */ jsx(Clipboard.Provider, { children: /* @__PURE__ */ jsx(Form.Root, {
65
+ variant: "settings",
66
+ children: /* @__PURE__ */ jsx(Form.Viewport, {
67
+ scroll: true,
68
+ children: /* @__PURE__ */ jsxs(Form.Content, { children: [
69
+ /* @__PURE__ */ jsx(Form.Section, {
70
+ title: t("invitations-section.title"),
71
+ description: t("invitations-section.description"),
72
+ children: /* @__PURE__ */ jsx(Form.Row, {
73
+ label: t("generate-invitation.label"),
74
+ description: t("generate-invitation.description", { count: remaining }),
75
+ children: /* @__PURE__ */ jsx(IconButton, {
76
+ icon: "ph--plus--regular",
77
+ label: t("generate-invitation.label"),
78
+ variant: "primary",
79
+ onClick: handleIssue,
80
+ disabled: pending || remaining <= 0
81
+ })
82
+ })
83
+ }),
84
+ available.length > 0 ? /* @__PURE__ */ jsx(Form.Section, {
85
+ title: t("available-invitations.title"),
86
+ children: /* @__PURE__ */ jsx(Listbox.Root, { children: /* @__PURE__ */ jsx(Listbox.Content, {
87
+ classNames: "gap-1",
88
+ children: available.map((row) => /* @__PURE__ */ jsx(AvailableInvitationItem, { row }, row.code))
89
+ }) })
90
+ }) : null,
91
+ redeemed.length > 0 ? /* @__PURE__ */ jsx(Form.Section, {
92
+ title: t("redeemed-invitations.title"),
93
+ children: /* @__PURE__ */ jsx(Listbox.Root, { children: /* @__PURE__ */ jsx(Listbox.Content, {
94
+ classNames: "gap-1",
95
+ children: redeemed.map((row) => /* @__PURE__ */ jsx(RedeemedInvitationItem, { row }, row.code))
96
+ }) })
97
+ }) : null
98
+ ] })
99
+ })
100
+ }) });
101
+ };
102
+ var AvailableInvitationItem = ({ row }) => /* @__PURE__ */ jsxs(Listbox.Item, {
103
+ id: row.code,
104
+ classNames: "grid grid-cols-[min-content_1fr_min-content] items-center gap-2",
105
+ children: [
106
+ /* @__PURE__ */ jsx(Icon, {
107
+ icon: "ph--paper-plane-tilt--duotone",
108
+ size: 5,
109
+ classNames: "text-description"
110
+ }),
111
+ /* @__PURE__ */ jsxs("div", {
112
+ className: "flex flex-col min-w-0",
113
+ children: [/* @__PURE__ */ jsx("div", {
114
+ className: "font-mono truncate",
115
+ children: row.code
116
+ }), /* @__PURE__ */ jsx("p", {
117
+ className: "text-description text-xs",
118
+ children: new Date(row.createdAt).toLocaleString()
119
+ })]
120
+ }),
121
+ /* @__PURE__ */ jsx(Clipboard.IconButton, { value: row.code })
122
+ ]
123
+ });
124
+ var RedeemedInvitationItem = ({ row }) => {
125
+ const date = row.redeemedAt ?? row.createdAt;
126
+ return /* @__PURE__ */ jsxs(Listbox.Item, {
127
+ id: row.code,
128
+ classNames: "grid grid-cols-[min-content_1fr] items-center gap-2",
129
+ children: [/* @__PURE__ */ jsx(Icon, {
130
+ icon: "ph--check-circle--duotone",
131
+ size: 5,
132
+ classNames: "text-success-text"
133
+ }), /* @__PURE__ */ jsxs("div", {
134
+ className: "flex flex-col min-w-0",
135
+ children: [/* @__PURE__ */ jsx("div", {
136
+ className: "font-mono truncate",
137
+ children: row.code
138
+ }), /* @__PURE__ */ jsx("p", {
139
+ className: "text-description text-xs",
140
+ children: new Date(date).toLocaleString()
141
+ })]
142
+ })]
143
+ });
144
+ };
145
+ InvitationsContainer.displayName = "InvitationsContainer";
146
+ //#endregion
147
+ export { InvitationsContainer as default };
148
+
149
+ //# sourceMappingURL=chunk-InvitationsContainer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-InvitationsContainer.mjs","names":[],"sources":["../../src/containers/InvitationsContainer/InvitationsContainer.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { useAtom, useAtomSet } from '@effect-atom/atom-react';\nimport React, { useCallback, useState } from 'react';\n\nimport { useCapability } from '@dxos/app-framework/ui';\nimport { Context } from '@dxos/context';\nimport { Clipboard, Icon, IconButton, useAsyncEffect, useTranslation } from '@dxos/react-ui';\nimport { Form } from '@dxos/react-ui-form';\nimport { Listbox } from '@dxos/react-ui-list';\n\nimport { meta } from '#meta';\nimport { type AccountCacheInvitation, ClientCapabilities } from '#types';\n\nimport { useHubHttpClient } from '../../hooks';\n\nexport const InvitationsContainer = () => {\n const { t } = useTranslation(meta.profile.key);\n const accountCacheAtom = useCapability(ClientCapabilities.AccountCache);\n const [cache] = useAtom(accountCacheAtom);\n const setCache = useAtomSet(accountCacheAtom);\n const [pending, setPending] = useState(false);\n\n // Account/invitation routes live on hub-service, not the edge worker.\n const hubClient = useHubHttpClient();\n\n useAsyncEffect(async () => {\n if (!hubClient) {\n return;\n }\n\n try {\n const result = await hubClient.listAccountInvitations(new Context());\n setCache((prev) => ({ ...prev, invitations: result.invitations, fetchedAt: Date.now() }));\n } catch {\n // Offline: keep cache.\n }\n }, [hubClient, setCache]);\n\n const handleIssue = useCallback(async () => {\n if (!hubClient) {\n return;\n }\n setPending(true);\n try {\n const result = await hubClient.issueAccountInvitation(new Context());\n // Optimistically push the new code and decrement the remaining quota; the\n // server consumes one slot at issue time. Next refresh reconciles.\n setCache((prev) => ({\n ...prev,\n account: prev.account\n ? { ...prev.account, invitationsRemaining: Math.max(0, prev.account.invitationsRemaining - 1) }\n : prev.account,\n invitations: [{ code: result.code, createdAt: new Date().toISOString() }, ...(prev.invitations ?? [])],\n }));\n } finally {\n setPending(false);\n }\n }, [hubClient, setCache]);\n\n const remaining = cache.account?.invitationsRemaining ?? 0;\n const list = cache.invitations ?? [];\n const available = list.filter((row) => !row.redeemedByIdentityDid);\n const redeemed = list.filter((row) => Boolean(row.redeemedByIdentityDid));\n\n return (\n <Clipboard.Provider>\n <Form.Root variant='settings'>\n <Form.Viewport scroll>\n <Form.Content>\n <Form.Section title={t('invitations-section.title')} description={t('invitations-section.description')}>\n <Form.Row\n label={t('generate-invitation.label')}\n description={t('generate-invitation.description', { count: remaining })}\n >\n <IconButton\n icon='ph--plus--regular'\n label={t('generate-invitation.label')}\n variant='primary'\n onClick={handleIssue}\n disabled={pending || remaining <= 0}\n />\n </Form.Row>\n </Form.Section>\n\n {available.length > 0 ? (\n <Form.Section title={t('available-invitations.title')}>\n <Listbox.Root>\n <Listbox.Content classNames='gap-1'>\n {available.map((row) => (\n <AvailableInvitationItem key={row.code} row={row} />\n ))}\n </Listbox.Content>\n </Listbox.Root>\n </Form.Section>\n ) : null}\n\n {redeemed.length > 0 ? (\n <Form.Section title={t('redeemed-invitations.title')}>\n <Listbox.Root>\n <Listbox.Content classNames='gap-1'>\n {redeemed.map((row) => (\n <RedeemedInvitationItem key={row.code} row={row} />\n ))}\n </Listbox.Content>\n </Listbox.Root>\n </Form.Section>\n ) : null}\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n </Clipboard.Provider>\n );\n};\n\nconst AvailableInvitationItem = ({ row }: { row: AccountCacheInvitation }) => (\n <Listbox.Item id={row.code} classNames='grid grid-cols-[min-content_1fr_min-content] items-center gap-2'>\n <Icon icon='ph--paper-plane-tilt--duotone' size={5} classNames='text-description' />\n <div className='flex flex-col min-w-0'>\n <div className='font-mono truncate'>{row.code}</div>\n <p className='text-description text-xs'>{new Date(row.createdAt).toLocaleString()}</p>\n </div>\n <Clipboard.IconButton value={row.code} />\n </Listbox.Item>\n);\n\nconst RedeemedInvitationItem = ({ row }: { row: AccountCacheInvitation }) => {\n const date = row.redeemedAt ?? row.createdAt;\n return (\n <Listbox.Item id={row.code} classNames='grid grid-cols-[min-content_1fr] items-center gap-2'>\n <Icon icon='ph--check-circle--duotone' size={5} classNames='text-success-text' />\n <div className='flex flex-col min-w-0'>\n <div className='font-mono truncate'>{row.code}</div>\n <p className='text-description text-xs'>{new Date(date).toLocaleString()}</p>\n </div>\n </Listbox.Item>\n );\n};\n\nInvitationsContainer.displayName = 'InvitationsContainer';\n"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { meta } from "#meta";
2
+ import { LayoutOperation } from "@dxos/app-toolkit";
3
+ import { ClientOperation } from "#operations";
4
+ import { useCallback } from "react";
5
+ import { JoinPanel } from "@dxos/shell/react";
6
+ import { useOperationInvoker } from "@dxos/app-framework/ui";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { Dialog, useTranslation } from "@dxos/react-ui";
9
+ import { osTranslations } from "@dxos/ui-theme";
10
+ import { ObservabilityOperation } from "@dxos/plugin-observability";
11
+ //#region src/containers/JoinDialog/JoinDialog.tsx
12
+ var JoinDialog = (props) => {
13
+ const { invokePromise } = useOperationInvoker();
14
+ const { t } = useTranslation(meta.profile.key);
15
+ const handleCancelResetStorage = useCallback(() => invokePromise(ClientOperation.ShareIdentity), [invokePromise]);
16
+ const handleDone = useCallback(async (result) => {
17
+ if (result?.identityKey) await Promise.all([invokePromise(LayoutOperation.UpdateDialog, { state: false }), invokePromise(ObservabilityOperation.SendEvent, { name: props.initialDisposition === "recover-identity" ? "identity.recover" : "identity.join" })]);
18
+ }, [invokePromise]);
19
+ return /* @__PURE__ */ jsxs(Dialog.Content, { children: [/* @__PURE__ */ jsx(Dialog.Header, { children: /* @__PURE__ */ jsx(Dialog.Title, {
20
+ classNames: "sr-only",
21
+ children: t("join-space.label", { ns: osTranslations })
22
+ }) }), /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsx(JoinPanel, {
23
+ ...props,
24
+ mode: "halo-only",
25
+ exitActionParent: /* @__PURE__ */ jsx(Dialog.Close, { asChild: true }),
26
+ doneActionParent: /* @__PURE__ */ jsx(Dialog.Close, { asChild: true }),
27
+ onCancelResetStorage: handleCancelResetStorage,
28
+ onDone: handleDone
29
+ }) })] });
30
+ };
31
+ JoinDialog.displayName = "JoinDialog";
32
+ //#endregion
33
+ export { JoinDialog as default };
34
+
35
+ //# sourceMappingURL=chunk-JoinDialog.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-JoinDialog.mjs","names":[],"sources":["../../src/containers/JoinDialog/JoinDialog.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useCallback } from 'react';\n\nimport { useOperationInvoker } from '@dxos/app-framework/ui';\nimport { LayoutOperation } from '@dxos/app-toolkit';\nimport { ObservabilityOperation } from '@dxos/plugin-observability';\nimport { type InvitationResult } from '@dxos/react-client/invitations';\nimport { Dialog, useTranslation } from '@dxos/react-ui';\nimport { JoinPanel, type JoinPanelProps } from '@dxos/shell/react';\nimport { osTranslations } from '@dxos/ui-theme';\n\nimport { meta } from '#meta';\nimport { ClientOperation } from '#operations';\n\nexport const JoinDialog = (props: JoinPanelProps) => {\n const { invokePromise } = useOperationInvoker();\n const { t } = useTranslation(meta.profile.key);\n\n const handleCancelResetStorage = useCallback(() => invokePromise(ClientOperation.ShareIdentity), [invokePromise]);\n\n const handleDone = useCallback(\n async (result: InvitationResult | null) => {\n if (result?.identityKey) {\n await Promise.all([\n invokePromise(LayoutOperation.UpdateDialog, { state: false }),\n invokePromise(ObservabilityOperation.SendEvent, {\n name: props.initialDisposition === 'recover-identity' ? 'identity.recover' : 'identity.join',\n }),\n ]);\n }\n },\n [invokePromise],\n );\n\n // TODO(burdon): Move JoinHeading into Dialog.Heading.\n return (\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title classNames='sr-only'>{t('join-space.label', { ns: osTranslations })}</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <JoinPanel\n {...props}\n mode='halo-only'\n exitActionParent={<Dialog.Close asChild />}\n doneActionParent={<Dialog.Close asChild />}\n onCancelResetStorage={handleCancelResetStorage}\n onDone={handleDone}\n />\n </Dialog.Body>\n </Dialog.Content>\n );\n};\n\nJoinDialog.displayName = 'JoinDialog';\n"],"mappings":";;;;;;;;;;;AAiBA,IAAa,cAAc,UAA0B;CACnD,MAAM,EAAE,kBAAkB,oBAAoB;CAC9C,MAAM,EAAE,MAAM,eAAe,KAAK,QAAQ,GAAG;CAE7C,MAAM,2BAA2B,kBAAkB,cAAc,gBAAgB,aAAa,GAAG,CAAC,aAAa,CAAC;CAEhH,MAAM,aAAa,YACjB,OAAO,WAAoC;EACzC,IAAI,QAAQ,aACV,MAAM,QAAQ,IAAI,CAChB,cAAc,gBAAgB,cAAc,EAAE,OAAO,MAAM,CAAC,GAC5D,cAAc,uBAAuB,WAAW,EAC9C,MAAM,MAAM,uBAAuB,qBAAqB,qBAAqB,gBAC/E,CAAC,CACH,CAAC;CAEL,GACA,CAAC,aAAa,CAChB;CAGA,OACE,qBAAC,OAAO,SAAR,EAAA,UAAA,CACE,oBAAC,OAAO,QAAR,EAAA,UACE,oBAAC,OAAO,OAAR;EAAc,YAAW;YAAW,EAAE,oBAAoB,EAAE,IAAI,eAAe,CAAC;CAAgB,CAAA,EACnF,CAAA,GACf,oBAAC,OAAO,MAAR,EAAA,UACE,oBAAC,WAAD;EACE,GAAI;EACJ,MAAK;EACL,kBAAkB,oBAAC,OAAO,OAAR,EAAc,SAAA,KAAS,CAAA;EACzC,kBAAkB,oBAAC,OAAO,OAAR,EAAc,SAAA,KAAS,CAAA;EACzC,sBAAsB;EACtB,QAAQ;CACT,CAAA,EACU,CAAA,CACC,EAAA,CAAA;AAEpB;AAEA,WAAW,cAAc"}