@dxos/client-services 0.8.4-main.fffef41 → 0.8.4-staging.60fe92afc8

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 (253) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/{chunk-I2RGLVJF.mjs → chunk-HPR4MJ4W.mjs} +2870 -3767
  4. package/dist/lib/browser/chunk-HPR4MJ4W.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
  6. package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-XJRPB3GA.mjs +22 -0
  8. package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +576 -139
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
  13. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  14. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  15. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  16. package/dist/lib/browser/packlets/locks/browser.mjs +86 -0
  17. package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
  18. package/dist/lib/browser/packlets/locks/node.mjs +48 -0
  19. package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
  20. package/dist/lib/browser/testing/index.mjs +58 -53
  21. package/dist/lib/browser/testing/index.mjs.map +3 -3
  22. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +22 -0
  23. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +7 -0
  24. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
  25. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
  26. package/dist/lib/node-esm/{chunk-QTUURCR4.mjs → chunk-JW6QHPRJ.mjs} +2810 -3576
  27. package/dist/lib/node-esm/chunk-JW6QHPRJ.mjs.map +7 -0
  28. package/dist/lib/node-esm/index.mjs +576 -139
  29. package/dist/lib/node-esm/index.mjs.map +4 -4
  30. package/dist/lib/node-esm/meta.json +1 -1
  31. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
  32. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  33. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  34. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  35. package/dist/lib/node-esm/packlets/locks/browser.mjs +86 -0
  36. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
  37. package/dist/lib/node-esm/packlets/locks/node.mjs +48 -0
  38. package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
  39. package/dist/lib/node-esm/testing/index.mjs +58 -53
  40. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  41. package/dist/types/src/index.d.ts +1 -0
  42. package/dist/types/src/index.d.ts.map +1 -1
  43. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
  44. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  45. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
  46. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  47. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  48. package/dist/types/src/packlets/devtools/devtools.d.ts +7 -3
  49. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  50. package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
  51. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  52. package/dist/types/src/packlets/devtools/keys.d.ts +2 -2
  53. package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
  54. package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
  55. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  56. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  57. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  58. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  59. package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
  60. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
  61. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  62. package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
  63. package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
  64. package/dist/types/src/packlets/identity/authenticator.d.ts +3 -3
  65. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  66. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  67. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  68. package/dist/types/src/packlets/identity/identity-manager.d.ts +10 -10
  69. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  70. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +14 -9
  71. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  72. package/dist/types/src/packlets/identity/identity-service.d.ts +7 -11
  73. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  74. package/dist/types/src/packlets/identity/identity.d.ts +10 -13
  75. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  76. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +7 -6
  77. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
  79. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  80. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  81. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  82. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +7 -4
  83. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  84. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
  85. package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
  86. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
  87. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  88. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +5 -5
  89. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  90. package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
  91. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  92. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +6 -5
  93. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  94. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  95. package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
  96. package/dist/types/src/packlets/locks/index.d.ts +1 -1
  97. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  98. package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
  99. package/dist/types/src/packlets/logging/logging-service.d.ts +4 -0
  100. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  101. package/dist/types/src/packlets/network/network-service.d.ts +5 -4
  102. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  103. package/dist/types/src/packlets/services/client-rpc-server.d.ts +5 -5
  104. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  105. package/dist/types/src/packlets/services/feed-syncer.d.ts +75 -0
  106. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  107. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  108. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  109. package/dist/types/src/packlets/services/index.d.ts +1 -0
  110. package/dist/types/src/packlets/services/index.d.ts.map +1 -1
  111. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  112. package/dist/types/src/packlets/services/service-context.d.ts +22 -19
  113. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  114. package/dist/types/src/packlets/services/service-host.d.ts +20 -13
  115. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  116. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  117. package/dist/types/src/packlets/services/sqlite-storage.d.ts +27 -0
  118. package/dist/types/src/packlets/services/sqlite-storage.d.ts.map +1 -0
  119. package/dist/types/src/packlets/services/util.d.ts.map +1 -1
  120. package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
  121. package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
  122. package/dist/types/src/packlets/space-export/index.d.ts +4 -1
  123. package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
  124. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
  125. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
  126. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
  127. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
  128. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  129. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  130. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
  131. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  132. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  133. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  134. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  135. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +49 -22
  136. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  137. package/dist/types/src/packlets/spaces/data-space.d.ts +38 -13
  138. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  139. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  140. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  141. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts +1 -1
  142. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
  143. package/dist/types/src/packlets/spaces/genesis.d.ts +4 -3
  144. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  145. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -9
  146. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  147. package/dist/types/src/packlets/spaces/spaces-service.d.ts +10 -7
  148. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  149. package/dist/types/src/packlets/storage/index.d.ts +1 -0
  150. package/dist/types/src/packlets/storage/index.d.ts.map +1 -1
  151. package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
  152. package/dist/types/src/packlets/storage/profile-archive-sqlite.d.ts +24 -0
  153. package/dist/types/src/packlets/storage/profile-archive-sqlite.d.ts.map +1 -0
  154. package/dist/types/src/packlets/storage/profile-archive-sqlite.test.d.ts +2 -0
  155. package/dist/types/src/packlets/storage/profile-archive-sqlite.test.d.ts.map +1 -0
  156. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  157. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  158. package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
  159. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  160. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  161. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
  162. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  163. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  164. package/dist/types/src/packlets/testing/test-builder.d.ts +20 -22
  165. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  166. package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -4
  167. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  168. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -4
  169. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  170. package/dist/types/src/testing/setup.d.ts.map +1 -1
  171. package/dist/types/src/version.d.ts +1 -1
  172. package/dist/types/src/version.d.ts.map +1 -1
  173. package/dist/types/tsconfig.tsbuildinfo +1 -1
  174. package/package.json +71 -57
  175. package/src/index.ts +1 -0
  176. package/src/packlets/agents/edge-agent-manager.ts +8 -5
  177. package/src/packlets/agents/edge-agent-service.ts +4 -2
  178. package/src/packlets/devices/devices-service.test.ts +0 -1
  179. package/src/packlets/devtools/devtools.ts +28 -7
  180. package/src/packlets/devtools/feeds.ts +1 -1
  181. package/src/packlets/devtools/keys.ts +2 -2
  182. package/src/packlets/devtools/spaces.ts +1 -1
  183. package/src/packlets/diagnostics/diagnostics.ts +1 -2
  184. package/src/packlets/diagnostics/index.ts +1 -1
  185. package/src/packlets/identity/authenticator.ts +3 -3
  186. package/src/packlets/identity/contacts-service.ts +1 -2
  187. package/src/packlets/identity/identity-manager.test.ts +6 -6
  188. package/src/packlets/identity/identity-manager.ts +29 -28
  189. package/src/packlets/identity/identity-recovery-manager.ts +31 -22
  190. package/src/packlets/identity/identity-service.test.ts +6 -27
  191. package/src/packlets/identity/identity-service.ts +17 -83
  192. package/src/packlets/identity/identity.test.ts +3 -3
  193. package/src/packlets/identity/identity.ts +12 -35
  194. package/src/packlets/invitations/device-invitation-protocol.ts +10 -9
  195. package/src/packlets/invitations/edge-invitation-handler.ts +9 -5
  196. package/src/packlets/invitations/invitation-guest-extenstion.ts +6 -4
  197. package/src/packlets/invitations/invitation-host-extension.ts +13 -14
  198. package/src/packlets/invitations/invitation-protocol.ts +7 -4
  199. package/src/packlets/invitations/invitation-state.ts +1 -15
  200. package/src/packlets/invitations/invitations-handler.test.ts +4 -5
  201. package/src/packlets/invitations/invitations-handler.ts +74 -22
  202. package/src/packlets/invitations/invitations-manager.ts +42 -17
  203. package/src/packlets/invitations/invitations-service.ts +9 -9
  204. package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
  205. package/src/packlets/invitations/space-invitation-protocol.ts +13 -18
  206. package/src/packlets/locks/index.ts +1 -1
  207. package/src/packlets/logging/logging-service.ts +19 -15
  208. package/src/packlets/network/network-service.test.ts +0 -1
  209. package/src/packlets/network/network-service.ts +10 -8
  210. package/src/packlets/services/client-rpc-server.ts +19 -16
  211. package/src/packlets/services/feed-syncer.test.ts +376 -0
  212. package/src/packlets/services/feed-syncer.ts +536 -0
  213. package/src/packlets/services/index.ts +1 -0
  214. package/src/packlets/services/platform.ts +7 -1
  215. package/src/packlets/services/service-context.test.ts +3 -2
  216. package/src/packlets/services/service-context.ts +215 -78
  217. package/src/packlets/services/service-host.test.ts +8 -10
  218. package/src/packlets/services/service-host.ts +102 -70
  219. package/src/packlets/services/service-registry.test.ts +0 -1
  220. package/src/packlets/services/sqlite-storage.ts +390 -0
  221. package/src/packlets/space-export/archive-format.ts +42 -0
  222. package/src/packlets/space-export/index.ts +4 -1
  223. package/src/packlets/space-export/serialized-space-reader.ts +129 -0
  224. package/src/packlets/space-export/serialized-space-writer.ts +260 -0
  225. package/src/packlets/space-export/space-archive-reader.ts +64 -3
  226. package/src/packlets/space-export/space-archive-writer.ts +41 -4
  227. package/src/packlets/space-export/space-archive.test.ts +482 -0
  228. package/src/packlets/spaces/data-space-manager.test.ts +169 -14
  229. package/src/packlets/spaces/data-space-manager.ts +192 -127
  230. package/src/packlets/spaces/data-space.ts +89 -43
  231. package/src/packlets/spaces/edge-feed-replicator.test.ts +2 -2
  232. package/src/packlets/spaces/edge-feed-replicator.ts +11 -9
  233. package/src/packlets/spaces/epoch-migrations.ts +7 -6
  234. package/src/packlets/spaces/genesis.ts +9 -4
  235. package/src/packlets/spaces/notarization-plugin.test.ts +2 -2
  236. package/src/packlets/spaces/notarization-plugin.ts +10 -9
  237. package/src/packlets/spaces/spaces-service.test.ts +18 -11
  238. package/src/packlets/spaces/spaces-service.ts +130 -24
  239. package/src/packlets/storage/index.ts +1 -0
  240. package/src/packlets/storage/profile-archive-sqlite.test.ts +79 -0
  241. package/src/packlets/storage/profile-archive-sqlite.ts +100 -0
  242. package/src/packlets/storage/profile-archive.ts +3 -0
  243. package/src/packlets/storage/storage.ts +4 -4
  244. package/src/packlets/testing/invitation-utils.ts +10 -6
  245. package/src/packlets/testing/test-builder.ts +59 -40
  246. package/src/packlets/worker/worker-runtime.ts +173 -17
  247. package/src/packlets/worker/worker-session.ts +12 -18
  248. package/src/version.ts +1 -1
  249. package/dist/lib/browser/chunk-I2RGLVJF.mjs.map +0 -7
  250. package/dist/lib/node-esm/chunk-QTUURCR4.mjs.map +0 -7
  251. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  252. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  253. package/src/packlets/identity/default-space-state-machine.ts +0 -44
@@ -2,24 +2,32 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
+ import * as Reactivity from '@effect/experimental/Reactivity';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+ import * as ManagedRuntime from 'effect/ManagedRuntime';
9
+
5
10
  import { type Config } from '@dxos/config';
6
11
  import { Context } from '@dxos/context';
7
12
  import { CredentialGenerator, createCredentialSignerWithChain } from '@dxos/credentials';
8
13
  import { failUndefined } from '@dxos/debug';
9
- import { EchoHost, MeshEchoReplicator, MetadataStore, SpaceManager, valueEncoding } from '@dxos/echo-pipeline';
14
+ import { EchoHost, MeshEchoReplicator, SpaceManager, valueEncoding } from '@dxos/echo-host';
15
+ import { SqliteMetadataStore } from '@dxos/echo-host';
16
+ import { RuntimeProvider } from '@dxos/effect';
10
17
  import { FeedFactory, FeedStore } from '@dxos/feed-store';
11
- import { Keyring } from '@dxos/keyring';
12
- import { type LevelDB } from '@dxos/kv-store';
13
- import { createTestLevel } from '@dxos/kv-store/testing';
18
+ import { SqliteKeyring } from '@dxos/keyring';
14
19
  import { MemorySignalManager, MemorySignalManagerContext, type SignalManager } from '@dxos/messaging';
15
20
  import { MemoryTransportFactory, SwarmNetworkManager } from '@dxos/network-manager';
16
21
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
17
- import { type Storage, StorageType, createStorage } from '@dxos/random-access-storage';
18
- import { BlobStore } from '@dxos/teleport-extension-object-sync';
22
+ import { StorageType } from '@dxos/random-access-storage';
23
+ import { layerMemory as sqliteLayerMemory } from '@dxos/sql-sqlite/platform';
24
+ import * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
25
+ import { SqliteBlobStore } from '@dxos/teleport-extension-object-sync';
19
26
 
20
27
  import { InvitationsHandler, InvitationsManager, SpaceInvitationProtocol } from '../invitations';
21
- import { ClientServicesHost, ServiceContext, type ServiceContextRuntimeParams } from '../services';
22
- import { DataSpaceManager, type DataSpaceManagerRuntimeParams, type SigningContext } from '../spaces';
28
+ import { ClientServicesHost, ServiceContext, type ServiceContextRuntimeProps } from '../services';
29
+ import { SqliteStorage } from '../services/sqlite-storage';
30
+ import { DataSpaceManager, type DataSpaceManagerRuntimeProps, type SigningContext } from '../spaces';
23
31
 
24
32
  //
25
33
  // TODO(burdon): Replace with test builder.
@@ -30,6 +38,11 @@ export const createServiceHost = (config: Config, signalManagerContext: MemorySi
30
38
  config,
31
39
  signalManager: new MemorySignalManager(signalManagerContext),
32
40
  transportFactory: MemoryTransportFactory,
41
+ runtime: ManagedRuntime.make(
42
+ SqlTransaction.layer
43
+ .pipe(Layer.provideMerge(sqliteLayerMemory), Layer.provideMerge(Reactivity.layer))
44
+ .pipe(Layer.orDie),
45
+ ).runtimeEffect,
33
46
  });
34
47
  };
35
48
 
@@ -38,24 +51,26 @@ export const createServiceContext = async ({
38
51
  const signalContext = new MemorySignalManagerContext();
39
52
  return new MemorySignalManager(signalContext);
40
53
  },
41
- storage = createStorage({ type: StorageType.RAM }),
42
- runtimeParams,
54
+ runtimeProps,
43
55
  }: {
44
56
  signalManagerFactory?: () => Promise<SignalManager>;
45
- storage?: Storage;
46
- runtimeParams?: ServiceContextRuntimeParams;
57
+ runtimeProps?: ServiceContextRuntimeProps;
47
58
  } = {}) => {
48
59
  const signalManager = await signalManagerFactory();
49
60
  const networkManager = new SwarmNetworkManager({
50
61
  signalManager,
51
62
  transportFactory: MemoryTransportFactory,
52
63
  });
53
- const level = createTestLevel();
54
- await level.open();
55
64
 
56
- return new ServiceContext(storage, level, networkManager, signalManager, undefined, undefined, {
57
- invitationConnectionDefaultParams: { teleport: { controlHeartbeatInterval: 200 } },
58
- ...runtimeParams,
65
+ const runtime = ManagedRuntime.make(
66
+ SqlTransaction.layer
67
+ .pipe(Layer.provideMerge(sqliteLayerMemory), Layer.provideMerge(Reactivity.layer))
68
+ .pipe(Layer.orDie),
69
+ ).runtimeEffect;
70
+
71
+ return new ServiceContext(networkManager, signalManager, undefined, undefined, runtime, {
72
+ invitationConnectionDefaultProps: { teleport: { controlHeartbeatInterval: 200 } },
73
+ ...runtimeProps,
59
74
  });
60
75
  };
61
76
 
@@ -95,20 +110,18 @@ export class TestBuilder {
95
110
 
96
111
  export type TestPeerOpts = {
97
112
  dataStore?: StorageType;
98
- dataSpaceParams?: DataSpaceManagerRuntimeParams;
113
+ dataSpaceProps?: DataSpaceManagerRuntimeProps;
99
114
  };
100
115
 
101
116
  export type TestPeerProps = {
102
- storage?: Storage;
103
- level?: LevelDB;
104
117
  feedStore?: FeedStore<any>;
105
- metadataStore?: MetadataStore;
106
- keyring?: Keyring;
118
+ metadataStore?: SqliteMetadataStore;
119
+ keyring?: SqliteKeyring;
107
120
  networkManager?: SwarmNetworkManager;
108
121
  spaceManager?: SpaceManager;
109
122
  dataSpaceManager?: DataSpaceManager;
110
123
  signingContext?: SigningContext;
111
- blobStore?: BlobStore;
124
+ blobStore?: SqliteBlobStore;
112
125
  echoHost?: EchoHost;
113
126
  meshEchoReplicator?: MeshEchoReplicator;
114
127
  invitationsManager?: InvitationsManager;
@@ -116,6 +129,12 @@ export type TestPeerProps = {
116
129
 
117
130
  export class TestPeer {
118
131
  private _props: TestPeerProps = {};
132
+ private readonly _runtime = ManagedRuntime.make(
133
+ SqlTransaction.layer
134
+ .pipe(Layer.provideMerge(sqliteLayerMemory), Layer.provideMerge(Reactivity.layer))
135
+ .pipe(Layer.orDie),
136
+ );
137
+ private readonly _feedStorage = new SqliteStorage({ runtime: this._runtime.runtimeEffect });
119
138
 
120
139
  constructor(
121
140
  private readonly _signalContext: MemorySignalManagerContext,
@@ -126,22 +145,14 @@ export class TestPeer {
126
145
  return this._props;
127
146
  }
128
147
 
129
- get storage() {
130
- return (this._props.storage ??= createStorage({ type: this._opts.dataStore }));
131
- }
132
-
133
148
  get keyring() {
134
- return (this._props.keyring ??= new Keyring(this.storage.createDirectory('keyring')));
135
- }
136
-
137
- get level() {
138
- return (this._props.level ??= createTestLevel());
149
+ return (this._props.keyring ??= new SqliteKeyring({ runtime: this._runtime.runtimeEffect }));
139
150
  }
140
151
 
141
152
  get feedStore() {
142
153
  return (this._props.feedStore ??= new FeedStore({
143
154
  factory: new FeedFactory({
144
- root: this.storage.createDirectory('feeds'),
155
+ root: this._feedStorage.createDirectory('feeds'),
145
156
  signer: this.keyring,
146
157
  hypercore: {
147
158
  valueEncoding,
@@ -151,11 +162,11 @@ export class TestPeer {
151
162
  }
152
163
 
153
164
  get metadataStore() {
154
- return (this._props.metadataStore ??= new MetadataStore(this.storage.createDirectory('metadata')));
165
+ return (this._props.metadataStore ??= new SqliteMetadataStore({ runtime: this._runtime.runtimeEffect }));
155
166
  }
156
167
 
157
168
  get blobStore() {
158
- return (this._props.blobStore ??= new BlobStore(this.storage.createDirectory('blobs')));
169
+ return (this._props.blobStore ??= new SqliteBlobStore({ runtime: this._runtime.runtimeEffect }));
159
170
  }
160
171
 
161
172
  get networkManager() {
@@ -179,7 +190,9 @@ export class TestPeer {
179
190
  }
180
191
 
181
192
  get echoHost() {
182
- return (this._props.echoHost ??= new EchoHost({ kv: this.level }));
193
+ return (this._props.echoHost ??= new EchoHost({
194
+ runtime: this._runtime.runtimeEffect,
195
+ }));
183
196
  }
184
197
 
185
198
  get meshEchoReplicator() {
@@ -198,7 +211,7 @@ export class TestPeer {
198
211
  edgeConnection: undefined,
199
212
  meshReplicator: this.meshEchoReplicator,
200
213
  echoEdgeReplicator: undefined,
201
- runtimeParams: this._opts.dataSpaceParams,
214
+ runtimeProps: this._opts.dataSpaceProps,
202
215
  }));
203
216
  }
204
217
 
@@ -217,6 +230,7 @@ export class TestPeer {
217
230
  }
218
231
 
219
232
  async createIdentity(): Promise<void> {
233
+ await this.migrate();
220
234
  this._props.signingContext ??= await createSigningContext(this.keyring);
221
235
  this.networkManager.setPeerInfo({
222
236
  identityKey: this._props.signingContext.identityKey.toHex(),
@@ -224,13 +238,18 @@ export class TestPeer {
224
238
  });
225
239
  }
226
240
 
241
+ async migrate(): Promise<void> {
242
+ await RuntimeProvider.runPromise(this._runtime.runtimeEffect)(
243
+ Effect.all([this.metadataStore.migrate, this.blobStore.migrate, this.keyring.migrate, this._feedStorage.migrate]),
244
+ );
245
+ }
246
+
227
247
  async destroy(): Promise<void> {
228
- await this.level.close();
229
- await this.storage.reset();
248
+ await this._runtime.dispose();
230
249
  }
231
250
  }
232
251
 
233
- export const createSigningContext = async (keyring: Keyring): Promise<SigningContext> => {
252
+ export const createSigningContext = async (keyring: SqliteKeyring): Promise<SigningContext> => {
234
253
  const identityKey = await keyring.createKey();
235
254
  const deviceKey = await keyring.createKey();
236
255
 
@@ -2,6 +2,12 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
+ import * as Reactivity from '@effect/experimental/Reactivity';
6
+ import type * as SqlClient from '@effect/sql/SqlClient';
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Layer from 'effect/Layer';
9
+ import * as ManagedRuntime from 'effect/ManagedRuntime';
10
+
5
11
  import { Trigger } from '@dxos/async';
6
12
  import { DEFAULT_WORKER_BROADCAST_CHANNEL } from '@dxos/client-protocol';
7
13
  import { type Config } from '@dxos/config';
@@ -16,17 +22,20 @@ import {
16
22
  } from '@dxos/messaging';
17
23
  import { RtcTransportProxyFactory } from '@dxos/network-manager';
18
24
  import { type RpcPort } from '@dxos/rpc';
25
+ import * as SqlExport from '@dxos/sql-sqlite/SqlExport';
26
+ import * as SqliteClient from '@dxos/sql-sqlite/SqliteClient';
27
+ import * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
19
28
  import { type MaybePromise } from '@dxos/util';
20
29
 
21
30
  import { ClientServicesHost } from '../services';
22
-
23
31
  import { WorkerSession } from './worker-session';
24
32
 
25
33
  // NOTE: Keep as RpcPorts to avoid dependency on @dxos/rpc-tunnel so we don't depend on browser-specific apis.
26
- export type CreateSessionParams = {
34
+ export type CreateSessionProps = {
27
35
  appPort: RpcPort;
28
36
  systemPort: RpcPort;
29
37
  shellPort?: RpcPort;
38
+ onClose?: () => Promise<void>;
30
39
  };
31
40
 
32
41
  export type WorkerRuntimeOptions = {
@@ -35,10 +44,20 @@ export type WorkerRuntimeOptions = {
35
44
  acquireLock: () => Promise<void>;
36
45
  releaseLock: () => void;
37
46
  onStop?: () => Promise<void>;
47
+ /**
48
+ * @default true
49
+ */
50
+ automaticallyConnectWebrtc?: boolean;
51
+
52
+ /**
53
+ * Optional SQLite layer for Effect. Defaults to LocalSqliteOpfsLayer.
54
+ * For testing in Node.js, use `sqliteLayerMemory` from `@dxos/sql-sqlite/platform`.
55
+ */
56
+ sqliteLayer?: Layer.Layer<SqlClient.SqlClient | SqlExport.SqlExport, unknown>;
38
57
  };
39
58
 
40
59
  /**
41
- * Runtime for the shared worker.
60
+ * Runtime for the shared and dedciated worker.
42
61
  * Manages connections from proxies (in tabs).
43
62
  * Tabs make requests to the `ClientServicesHost`, and provide a WebRTC gateway.
44
63
  */
@@ -52,11 +71,17 @@ export class WorkerRuntime {
52
71
  private readonly _sessions = new Set<WorkerSession>();
53
72
  private readonly _clientServices!: ClientServicesHost;
54
73
  private readonly _channel: string;
74
+ private readonly _automaticallyConnectWebrtc: boolean;
75
+ private readonly _livenessLock = new WebLockWrapper(`@dxos/client-services/WorkerRuntime/${crypto.randomUUID()}`);
55
76
  private _broadcastChannel?: BroadcastChannel;
56
77
  private _sessionForNetworking?: WorkerSession; // TODO(burdon): Expose to client QueryStatusResponse.
57
78
  private _config!: Config;
58
79
  private _signalMetadataTags: any = { runtime: 'worker-runtime' };
59
80
  private _signalTelemetryEnabled: boolean = false;
81
+ private _runtime!: ManagedRuntime.ManagedRuntime<
82
+ SqlTransaction.SqlTransaction | SqlClient.SqlClient | SqlExport.SqlExport,
83
+ never
84
+ >;
60
85
 
61
86
  constructor({
62
87
  channel = DEFAULT_WORKER_BROADCAST_CHANNEL,
@@ -64,37 +89,72 @@ export class WorkerRuntime {
64
89
  acquireLock,
65
90
  releaseLock,
66
91
  onStop,
92
+ automaticallyConnectWebrtc = true,
93
+ sqliteLayer,
67
94
  }: WorkerRuntimeOptions) {
68
95
  this._configProvider = configProvider;
69
96
  this._acquireLock = acquireLock;
70
97
  this._releaseLock = releaseLock;
71
98
  this._onStop = onStop;
72
99
  this._channel = channel;
100
+ if (sqliteLayer) {
101
+ log.warn('Using testing SQLite layer');
102
+ }
103
+ this._runtime = ManagedRuntime.make(
104
+ SqlTransaction.layer
105
+ .pipe(Layer.provideMerge(sqliteLayer ?? LocalSqliteOpfsLayer), Layer.provideMerge(Reactivity.layer))
106
+ .pipe(Layer.orDie),
107
+ );
73
108
  this._clientServices = new ClientServicesHost({
74
109
  callbacks: {
75
110
  onReset: async () => this.stop(),
76
111
  },
112
+ runtime: this._runtime.runtimeEffect,
113
+ runtimeProps: {
114
+ // Auto-activate spaces that were previously active after leader changeover.
115
+ autoActivateSpaces: true,
116
+ },
77
117
  });
118
+ this._automaticallyConnectWebrtc = automaticallyConnectWebrtc;
78
119
  }
79
120
 
80
121
  get host() {
81
122
  return this._clientServices;
82
123
  }
83
124
 
125
+ get livenessLockKey(): string {
126
+ return this._livenessLock.key;
127
+ }
128
+
84
129
  async start(): Promise<void> {
85
130
  log('starting...');
86
131
  try {
132
+ log('worker-runtime: acquiring liveness lock (background)');
133
+ void this._livenessLock.acquire();
134
+
135
+ // Steal the lock from the other worker.
136
+ log('worker-runtime: broadcasting stop to displace previous worker');
87
137
  this._broadcastChannel = new BroadcastChannel(this._channel);
88
138
  this._broadcastChannel.postMessage({ action: 'stop' });
89
139
  this._broadcastChannel.onmessage = async (event) => {
90
140
  if (event.data?.action === 'stop') {
141
+ log('worker-runtime: received stop broadcast');
91
142
  await this.stop();
92
143
  }
93
144
  };
94
145
 
146
+ log('worker-runtime: acquiring storage lock');
95
147
  await this._acquireLock();
148
+ log('worker-runtime: storage lock acquired, resolving config');
96
149
  this._config = await this._configProvider();
150
+ log('worker-runtime: config resolved');
151
+ this._signalTelemetryEnabled = this._config.get('runtime.client.signalTelemetryEnabled') ?? false;
152
+ const observabilityGroup = this._config.get('runtime.client.observabilityGroup');
153
+ if (observabilityGroup) {
154
+ this._signalMetadataTags.group = observabilityGroup;
155
+ }
97
156
  const signals = this._config.get('runtime.services.signaling');
157
+ log('worker-runtime: initializing client services host');
98
158
  this._clientServices.initialize({
99
159
  config: this._config,
100
160
  signalManager: this._config.get('runtime.client.edgeFeatures')?.signaling
@@ -104,8 +164,10 @@ export class WorkerRuntime {
104
164
  : new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
105
165
  transportFactory: this._transportFactory,
106
166
  });
167
+ log('worker-runtime: client services host initialized, opening');
107
168
 
108
169
  await this._clientServices.open(new Context());
170
+ log('worker-runtime: client services host opened, signalling ready');
109
171
  this._ready.wake(undefined);
110
172
  log('started');
111
173
  setIdentityTags({
@@ -126,14 +188,40 @@ export class WorkerRuntime {
126
188
  this._releaseLock();
127
189
  this._broadcastChannel?.close();
128
190
  this._broadcastChannel = undefined;
129
- await this._clientServices.close();
191
+ await this._clientServices.close(Context.default());
192
+ await this._runtime.dispose();
130
193
  await this._onStop?.();
194
+ await this._livenessLock.release();
195
+ }
196
+
197
+ /**
198
+ * Update signaling telemetry tags from a client-supplied config overlay.
199
+ *
200
+ * The worker services outlive individual client connections, so the first client seeds the
201
+ * worker's core config (storage, signaling, edge features). For fields that can legitimately
202
+ * differ per tab — `observabilityGroup` and `signalTelemetryEnabled` — this method lets later
203
+ * connections refresh the signal metadata the worker attaches to its signaling requests
204
+ * (last-writer-wins, matching the pre-DX-930 per-session RPC behaviour).
205
+ */
206
+ updateSignalMetadata(config: Config): void {
207
+ const observabilityGroup = config.get('runtime.client.observabilityGroup');
208
+ if (observabilityGroup) {
209
+ this._signalMetadataTags.group = observabilityGroup;
210
+ } else {
211
+ // Clear stale group so a later config that removes observabilityGroup stops attributing
212
+ // telemetry to the previous client's group (last-writer-wins).
213
+ delete this._signalMetadataTags.group;
214
+ }
215
+ const signalTelemetryEnabled = config.get('runtime.client.signalTelemetryEnabled');
216
+ if (signalTelemetryEnabled !== undefined) {
217
+ this._signalTelemetryEnabled = signalTelemetryEnabled;
218
+ }
131
219
  }
132
220
 
133
221
  /**
134
222
  * Create a new session.
135
223
  */
136
- async createSession({ appPort, systemPort, shellPort }: CreateSessionParams): Promise<void> {
224
+ async createSession({ appPort, systemPort, shellPort, onClose }: CreateSessionProps): Promise<WorkerSession> {
137
225
  const session = new WorkerSession({
138
226
  serviceHost: this._clientServices,
139
227
  appPort,
@@ -149,8 +237,11 @@ export class WorkerRuntime {
149
237
  // Terminate the worker when all sessions are closed.
150
238
  await this.stop();
151
239
  } else {
152
- this._reconnectWebrtc();
240
+ if (this._automaticallyConnectWebrtc) {
241
+ this._reconnectWebrtc();
242
+ }
153
243
  }
244
+ await onClose?.();
154
245
  });
155
246
 
156
247
  await session.open();
@@ -159,14 +250,27 @@ export class WorkerRuntime {
159
250
  !this._signalMetadataTags.origin || this._signalMetadataTags.origin === session.origin,
160
251
  `worker origin changed from ${this._signalMetadataTags.origin} to ${session.origin}?`,
161
252
  );
162
- if (session.observabilityGroup) {
163
- this._signalMetadataTags.group = session.observabilityGroup;
164
- }
165
- this._signalTelemetryEnabled = session.signalTelemetryEnabled ?? false;
166
253
  this._signalMetadataTags.origin = session.origin;
167
254
  this._sessions.add(session);
168
255
 
169
- this._reconnectWebrtc();
256
+ if (this._automaticallyConnectWebrtc) {
257
+ this._reconnectWebrtc();
258
+ }
259
+
260
+ return session;
261
+ }
262
+
263
+ /**
264
+ * Connects the WebRTC bridge to the specified session.
265
+ * If no session is provided, disconnects the WebRTC bridge.
266
+ *
267
+ * Called automatically if `automaticallyConnectWebrtc` is true.
268
+ *
269
+ * @param session The session to connect the WebRTC bridge to.
270
+ */
271
+ connectWebrtcBridge(session: WorkerSession | undefined): void {
272
+ this._sessionForNetworking = session;
273
+ this._transportFactory.setBridgeService(session?.bridgeService);
170
274
  }
171
275
 
172
276
  /**
@@ -184,12 +288,64 @@ export class WorkerRuntime {
184
288
  // Select existing session.
185
289
  if (!this._sessionForNetworking) {
186
290
  const selected = Array.from(this._sessions).find((session) => session.bridgeService);
187
- if (selected) {
188
- this._sessionForNetworking = selected;
189
- this._transportFactory.setBridgeService(selected.bridgeService);
190
- } else {
191
- this._transportFactory.setBridgeService(undefined);
192
- }
291
+ this.connectWebrtcBridge(selected);
193
292
  }
194
293
  }
195
294
  }
295
+
296
+ const DB_NAME = 'DXOS';
297
+
298
+ /**
299
+ * SqlExport layer that wraps SqliteClient to provide export functionality.
300
+ */
301
+ const SqlExportLayer: Layer.Layer<SqlExport.SqlExport, never, SqliteClient.SqliteClient> = Layer.effect(
302
+ SqlExport.SqlExport,
303
+ Effect.gen(function* () {
304
+ const sql = yield* SqliteClient.SqliteClient;
305
+ return {
306
+ export: sql.export,
307
+ } satisfies SqlExport.Service;
308
+ }),
309
+ );
310
+
311
+ /**
312
+ * Local SQLite layer for the worker.
313
+ * Uses in-process OPFS via {@link SqliteClient.layerOpfs} (no MessagePort).
314
+ * NOTE: Only usable within a worker.
315
+ */
316
+ const LocalSqliteOpfsLayer = SqlExportLayer.pipe(
317
+ Layer.provideMerge(SqliteClient.layerOpfs({ dbName: DB_NAME })),
318
+ Layer.provideMerge(Reactivity.layer),
319
+ );
320
+
321
+ // TODO(wittjosiah): Factor out to a separate module.
322
+ class WebLockWrapper {
323
+ readonly #key: string;
324
+ #release?: () => void;
325
+
326
+ constructor(key: string) {
327
+ this.#key = key;
328
+ }
329
+
330
+ get key(): string {
331
+ return this.#key;
332
+ }
333
+
334
+ acquire(options: LockOptions = {}) {
335
+ return navigator.locks.request(this.#key, options, async () => {
336
+ await new Promise<void>((resolve) => {
337
+ this.#release = resolve;
338
+ }); // Blocks for the duration of the worker's lifetime.
339
+ this.#release = undefined;
340
+ });
341
+ }
342
+
343
+ release() {
344
+ this.#release?.();
345
+ this.#release = undefined;
346
+ }
347
+
348
+ [Symbol.dispose]() {
349
+ this.release();
350
+ }
351
+ }
@@ -15,9 +15,9 @@ import { type BridgeService } from '@dxos/protocols/proto/dxos/mesh/bridge';
15
15
  import { type ProtoRpcPeer, type RpcPort, createProtoRpcPeer } from '@dxos/rpc';
16
16
  import { Callback, type MaybePromise } from '@dxos/util';
17
17
 
18
- import { ClientRpcServer, type ClientRpcServerParams, type ClientServicesHost } from '../services';
18
+ import { ClientRpcServer, type ClientRpcServerProps, type ClientServicesHost } from '../services';
19
19
 
20
- export type WorkerSessionParams = {
20
+ export type WorkerSessionProps = {
21
21
  serviceHost: ClientServicesHost;
22
22
  systemPort: RpcPort;
23
23
  appPort: RpcPort;
@@ -41,35 +41,31 @@ export class WorkerSession {
41
41
  @logInfo
42
42
  public origin?: string;
43
43
 
44
- // TODO(nf): factor out?
45
- public observabilityGroup?: string;
46
- public signalTelemetryEnabled?: boolean;
47
-
48
44
  @logInfo
49
45
  public lockKey?: string;
50
46
 
51
47
  public bridgeService?: BridgeService;
52
48
 
53
- constructor({ serviceHost, systemPort, appPort, shellPort, readySignal }: WorkerSessionParams) {
49
+ constructor({ serviceHost, systemPort, appPort, shellPort, readySignal }: WorkerSessionProps) {
54
50
  invariant(serviceHost);
55
51
  this._serviceHost = serviceHost;
56
52
 
57
- const middleware: Pick<ClientRpcServerParams, 'handleCall' | 'handleStream'> = {
58
- handleCall: async (method, params, handler) => {
53
+ const middleware: Pick<ClientRpcServerProps, 'handleCall' | 'handleStream'> = {
54
+ handleCall: async (method, params, handler, options) => {
59
55
  const error = await readySignal.wait({ timeout: PROXY_CONNECTION_TIMEOUT });
60
56
  if (error) {
61
57
  throw error;
62
58
  }
63
59
 
64
- return handler(method, params);
60
+ return handler(method, params, options);
65
61
  },
66
- handleStream: async (method, params, handler) => {
62
+ handleStream: async (method, params, handler, options) => {
67
63
  const error = await readySignal.wait({ timeout: PROXY_CONNECTION_TIMEOUT });
68
64
  if (error) {
69
65
  throw error;
70
66
  }
71
67
 
72
- return handler(method, params);
68
+ return handler(method, params, options);
73
69
  },
74
70
  };
75
71
 
@@ -95,8 +91,6 @@ export class WorkerSession {
95
91
  start: async (request) => {
96
92
  this.origin = request.origin;
97
93
  this.lockKey = request.lockKey;
98
- this.observabilityGroup = request.observabilityGroup;
99
- this.signalTelemetryEnabled = request.signalTelemetryEnabled;
100
94
  this._startTrigger.wake();
101
95
  },
102
96
 
@@ -119,7 +113,7 @@ export class WorkerSession {
119
113
  }
120
114
 
121
115
  async open(): Promise<void> {
122
- log.info('opening...');
116
+ log('opening...');
123
117
  await Promise.all([this._clientRpc.open(), this._iframeRpc.open(), this._maybeOpenShell()]);
124
118
 
125
119
  // Wait until the worker's RPC service has started.
@@ -130,11 +124,11 @@ export class WorkerSession {
130
124
  void this._afterLockReleases(this.lockKey, () => this.close());
131
125
  }
132
126
 
133
- log.info('opened');
127
+ log('opened');
134
128
  }
135
129
 
136
130
  async close(): Promise<void> {
137
- log.info('closing...');
131
+ log.debug('closing...');
138
132
  try {
139
133
  await this.onClose.callIfSet();
140
134
  } catch (err: any) {
@@ -142,7 +136,7 @@ export class WorkerSession {
142
136
  }
143
137
 
144
138
  await Promise.all([this._clientRpc.close(), this._iframeRpc.close()]);
145
- log.info('closed');
139
+ log.debug('closed');
146
140
  }
147
141
 
148
142
  private async _maybeOpenShell(): Promise<void> {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const DXOS_VERSION = "0.8.4-main.fffef41";
1
+ export const DXOS_VERSION = "0.8.4-staging.60fe92afc8";