@dxos/client-services 0.8.4-main.b97322e → 0.8.4-main.bcb3aa67d6

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 (222) hide show
  1. package/dist/lib/browser/{chunk-WKKP35EC.mjs → chunk-5A3KX2RY.mjs} +4406 -3958
  2. package/dist/lib/browser/chunk-5A3KX2RY.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-NQSC7HOE.mjs +22 -0
  4. package/dist/lib/browser/chunk-NQSC7HOE.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/index.mjs +481 -78
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
  11. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  12. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  13. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  14. package/dist/lib/browser/packlets/locks/browser.mjs +126 -0
  15. package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
  16. package/dist/lib/browser/packlets/locks/node.mjs +66 -0
  17. package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
  18. package/dist/lib/browser/testing/index.mjs +45 -26
  19. package/dist/lib/browser/testing/index.mjs.map +3 -3
  20. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
  21. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
  22. package/dist/lib/node-esm/{chunk-ZE2HYS56.mjs → chunk-FNPO5UMU.mjs} +4302 -3722
  23. package/dist/lib/node-esm/chunk-FNPO5UMU.mjs.map +7 -0
  24. package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs +22 -0
  25. package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs.map +7 -0
  26. package/dist/lib/node-esm/index.mjs +481 -78
  27. package/dist/lib/node-esm/index.mjs.map +4 -4
  28. package/dist/lib/node-esm/meta.json +1 -1
  29. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
  30. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  31. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  32. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  33. package/dist/lib/node-esm/packlets/locks/browser.mjs +126 -0
  34. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
  35. package/dist/lib/node-esm/packlets/locks/node.mjs +66 -0
  36. package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
  37. package/dist/lib/node-esm/testing/index.mjs +45 -26
  38. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  39. package/dist/types/src/index.d.ts +1 -0
  40. package/dist/types/src/index.d.ts.map +1 -1
  41. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
  42. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  43. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +1 -1
  44. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  45. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  46. package/dist/types/src/packlets/devtools/devtools.d.ts +20 -20
  47. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  48. package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
  49. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  50. package/dist/types/src/packlets/devtools/network.d.ts +1 -1
  51. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  52. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts +1 -1
  53. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  54. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +1 -1
  55. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  56. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +1 -1
  57. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  58. package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
  59. package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
  60. package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
  61. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  62. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  63. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  64. package/dist/types/src/packlets/identity/identity-manager.d.ts +7 -7
  65. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  66. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +7 -6
  67. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  68. package/dist/types/src/packlets/identity/identity-service.d.ts +1 -6
  69. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  70. package/dist/types/src/packlets/identity/identity.d.ts +9 -12
  71. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  72. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +4 -4
  73. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  74. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
  75. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  76. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  77. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +3 -4
  79. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  80. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
  81. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  82. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
  83. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  84. package/dist/types/src/packlets/invitations/invitations-service.d.ts +1 -1
  85. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  86. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +3 -3
  87. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  88. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  89. package/dist/types/src/packlets/locks/index.d.ts +1 -1
  90. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  91. package/dist/types/src/packlets/logging/logging-service.d.ts +5 -1
  92. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  93. package/dist/types/src/packlets/network/network-service.d.ts +2 -2
  94. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  95. package/dist/types/src/packlets/services/client-rpc-server.d.ts +2 -2
  96. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  97. package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
  98. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  99. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  100. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  101. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  102. package/dist/types/src/packlets/services/service-context.d.ts +14 -9
  103. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  104. package/dist/types/src/packlets/services/service-host.d.ts +20 -6
  105. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  106. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  107. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  108. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
  109. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  110. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  111. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  112. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts +1 -1
  113. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  114. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +28 -16
  115. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  116. package/dist/types/src/packlets/spaces/data-space.d.ts +28 -12
  117. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  118. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  119. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  120. package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
  121. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  122. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -6
  123. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  124. package/dist/types/src/packlets/spaces/spaces-service.d.ts +3 -3
  125. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  126. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  127. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  128. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  129. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  130. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  131. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  132. package/dist/types/src/packlets/testing/test-builder.d.ts +8 -7
  133. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  134. package/dist/types/src/packlets/worker/worker-runtime.d.ts +31 -4
  135. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  136. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -2
  137. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  138. package/dist/types/src/version.d.ts +1 -1
  139. package/dist/types/src/version.d.ts.map +1 -1
  140. package/dist/types/tsconfig.tsbuildinfo +1 -1
  141. package/package.json +72 -48
  142. package/src/index.ts +1 -0
  143. package/src/packlets/agents/edge-agent-manager.ts +10 -7
  144. package/src/packlets/agents/edge-agent-service.ts +15 -5
  145. package/src/packlets/devices/devices-service.test.ts +4 -3
  146. package/src/packlets/devices/devices-service.ts +2 -2
  147. package/src/packlets/devtools/devtools.ts +30 -29
  148. package/src/packlets/devtools/feeds.ts +2 -2
  149. package/src/packlets/devtools/network.ts +1 -1
  150. package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +1 -1
  151. package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -1
  152. package/src/packlets/diagnostics/diagnostics-collector.ts +1 -1
  153. package/src/packlets/diagnostics/diagnostics.ts +1 -1
  154. package/src/packlets/diagnostics/index.ts +1 -1
  155. package/src/packlets/identity/authenticator.node.test.ts +1 -1
  156. package/src/packlets/identity/authenticator.ts +3 -3
  157. package/src/packlets/identity/contacts-service.ts +3 -2
  158. package/src/packlets/identity/identity-manager.test.ts +8 -8
  159. package/src/packlets/identity/identity-manager.ts +23 -20
  160. package/src/packlets/identity/identity-recovery-manager.ts +22 -18
  161. package/src/packlets/identity/identity-service.test.ts +9 -28
  162. package/src/packlets/identity/identity-service.ts +5 -75
  163. package/src/packlets/identity/identity.test.ts +11 -11
  164. package/src/packlets/identity/identity.ts +16 -37
  165. package/src/packlets/invitations/device-invitation-protocol.test.ts +1 -1
  166. package/src/packlets/invitations/device-invitation-protocol.ts +6 -5
  167. package/src/packlets/invitations/edge-invitation-handler.ts +5 -4
  168. package/src/packlets/invitations/invitation-guest-extenstion.ts +7 -5
  169. package/src/packlets/invitations/invitation-host-extension.ts +8 -6
  170. package/src/packlets/invitations/invitation-protocol.ts +3 -4
  171. package/src/packlets/invitations/invitations-handler.test.ts +8 -7
  172. package/src/packlets/invitations/invitations-handler.ts +13 -13
  173. package/src/packlets/invitations/invitations-manager.ts +40 -17
  174. package/src/packlets/invitations/invitations-service.ts +5 -5
  175. package/src/packlets/invitations/space-invitation-protocol.test.ts +19 -18
  176. package/src/packlets/invitations/space-invitation-protocol.ts +13 -16
  177. package/src/packlets/invitations/utils.ts +1 -1
  178. package/src/packlets/locks/browser.ts +1 -1
  179. package/src/packlets/locks/index.ts +1 -1
  180. package/src/packlets/logging/logging-service.ts +7 -3
  181. package/src/packlets/logging/logging.test.ts +1 -1
  182. package/src/packlets/network/network-service.test.ts +4 -3
  183. package/src/packlets/network/network-service.ts +7 -6
  184. package/src/packlets/services/client-rpc-server.ts +5 -5
  185. package/src/packlets/services/feed-syncer.test.ts +340 -0
  186. package/src/packlets/services/feed-syncer.ts +337 -0
  187. package/src/packlets/services/platform.ts +7 -1
  188. package/src/packlets/services/service-context.test.ts +4 -3
  189. package/src/packlets/services/service-context.ts +139 -52
  190. package/src/packlets/services/service-host.test.ts +11 -9
  191. package/src/packlets/services/service-host.ts +78 -28
  192. package/src/packlets/services/service-registry.test.ts +2 -1
  193. package/src/packlets/space-export/space-archive-reader.ts +65 -4
  194. package/src/packlets/space-export/space-archive-writer.ts +42 -5
  195. package/src/packlets/space-export/space-archive.test.ts +287 -0
  196. package/src/packlets/space-export/tar.test.ts +1 -1
  197. package/src/packlets/spaces/automerge-space-state.ts +1 -1
  198. package/src/packlets/spaces/data-space-manager.test.ts +79 -13
  199. package/src/packlets/spaces/data-space-manager.ts +124 -116
  200. package/src/packlets/spaces/data-space.ts +60 -35
  201. package/src/packlets/spaces/edge-feed-replicator.test.ts +4 -4
  202. package/src/packlets/spaces/edge-feed-replicator.ts +12 -11
  203. package/src/packlets/spaces/epoch-migrations.ts +5 -5
  204. package/src/packlets/spaces/genesis.ts +6 -1
  205. package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
  206. package/src/packlets/spaces/notarization-plugin.ts +13 -12
  207. package/src/packlets/spaces/spaces-service.test.ts +12 -8
  208. package/src/packlets/spaces/spaces-service.ts +57 -31
  209. package/src/packlets/storage/profile-archive.ts +1 -1
  210. package/src/packlets/storage/storage.ts +7 -8
  211. package/src/packlets/system/system-service.test.ts +1 -1
  212. package/src/packlets/system/system-service.ts +4 -4
  213. package/src/packlets/testing/invitation-utils.ts +11 -7
  214. package/src/packlets/testing/test-builder.ts +39 -13
  215. package/src/packlets/worker/worker-runtime.ts +152 -13
  216. package/src/packlets/worker/worker-session.ts +11 -11
  217. package/src/version.ts +1 -1
  218. package/dist/lib/browser/chunk-WKKP35EC.mjs.map +0 -7
  219. package/dist/lib/node-esm/chunk-ZE2HYS56.mjs.map +0 -7
  220. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  221. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  222. package/src/packlets/identity/default-space-state-machine.ts +0 -44
@@ -2,39 +2,43 @@
2
2
  // Copyright 2021 DXOS.org
3
3
  //
4
4
 
5
+ import * as SqlClient from '@effect/sql/SqlClient';
6
+ import * as Effect from 'effect/Effect';
7
+
5
8
  import { Event, synchronized } from '@dxos/async';
6
- import { clientServiceBundle, type ClientServices } from '@dxos/client-protocol';
9
+ import { type ClientServices, clientServiceBundle } from '@dxos/client-protocol';
7
10
  import { type Config } from '@dxos/config';
8
11
  import { Context } from '@dxos/context';
9
- import { EdgeClient, EdgeHttpClient, createStubEdgeIdentity, type EdgeConnection } from '@dxos/edge-client';
12
+ import { EdgeClient, type EdgeConnection, EdgeHttpClient, createStubEdgeIdentity } from '@dxos/edge-client';
13
+ import { RuntimeProvider } from '@dxos/effect';
10
14
  import { invariant } from '@dxos/invariant';
11
15
  import { PublicKey } from '@dxos/keys';
12
16
  import { type LevelDB } from '@dxos/kv-store';
13
17
  import { log } from '@dxos/log';
14
- import { EdgeSignalManager, WebsocketSignalManager, type SignalManager } from '@dxos/messaging';
18
+ import { EdgeSignalManager, type SignalManager, WebsocketSignalManager } from '@dxos/messaging';
15
19
  import {
16
20
  SwarmNetworkManager,
21
+ type TransportFactory,
17
22
  createIceProvider,
18
23
  createRtcTransportFactory,
19
- type TransportFactory,
20
24
  } from '@dxos/network-manager';
21
25
  import { trace } from '@dxos/protocols';
22
26
  import { SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
23
27
  import { type Storage } from '@dxos/random-access-storage';
28
+ import * as SqlExport from '@dxos/sql-sqlite/SqlExport';
29
+ import type * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
24
30
  import { TRACE_PROCESSOR, trace as Trace } from '@dxos/tracing';
25
31
  import { WebsocketRpcClient } from '@dxos/websocket-rpc';
26
32
 
27
- import { ServiceContext, type ServiceContextRuntimeParams } from './service-context';
28
- import { ServiceRegistry } from './service-registry';
29
33
  import { EdgeAgentServiceImpl } from '../agents';
30
34
  import { DevicesServiceImpl } from '../devices';
31
35
  import { DevtoolsHostEvents, DevtoolsServiceImpl } from '../devtools';
32
36
  import {
37
+ type CollectDiagnosticsBroadcastHandler,
33
38
  createCollectDiagnosticsBroadcastHandler,
34
39
  createDiagnostics,
35
- type CollectDiagnosticsBroadcastHandler,
36
40
  } from '../diagnostics';
37
- import { IdentityServiceImpl, type CreateIdentityOptions } from '../identity';
41
+ import { type CreateIdentityOptions, IdentityServiceImpl } from '../identity';
38
42
  import { ContactsServiceImpl } from '../identity/contacts-service';
39
43
  import { InvitationsServiceImpl } from '../invitations';
40
44
  import { Lock, type ResourceLock } from '../locks';
@@ -44,7 +48,10 @@ import { SpacesServiceImpl } from '../spaces';
44
48
  import { createLevel, createStorageObjects } from '../storage';
45
49
  import { SystemServiceImpl } from '../system';
46
50
 
47
- export type ClientServicesHostParams = {
51
+ import { ServiceContext, type ServiceContextRuntimeProps } from './service-context';
52
+ import { ServiceRegistry } from './service-registry';
53
+
54
+ export type ClientServicesHostProps = {
48
55
  /**
49
56
  * Can be omitted if `initialize` is later called.
50
57
  */
@@ -56,7 +63,8 @@ export type ClientServicesHostParams = {
56
63
  level?: LevelDB;
57
64
  lockKey?: string;
58
65
  callbacks?: ClientServicesHostCallbacks;
59
- runtimeParams?: ServiceContextRuntimeParams;
66
+ runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlExport.SqlExport | SqlTransaction.SqlTransaction>;
67
+ runtimeProps?: ServiceContextRuntimeProps;
60
68
  };
61
69
 
62
70
  export type ClientServicesHostCallbacks = {
@@ -94,7 +102,10 @@ export class ClientServicesHost {
94
102
  private _edgeHttpClient?: EdgeHttpClient = undefined;
95
103
 
96
104
  private _serviceContext!: ServiceContext;
97
- private readonly _runtimeParams: ServiceContextRuntimeParams;
105
+ private readonly _runtime: RuntimeProvider.RuntimeProvider<
106
+ SqlClient.SqlClient | SqlExport.SqlExport | SqlTransaction.SqlTransaction
107
+ >;
108
+ private readonly _runtimeProps: ServiceContextRuntimeProps;
98
109
  private diagnosticsBroadcastHandler: CollectDiagnosticsBroadcastHandler;
99
110
 
100
111
  @Trace.info()
@@ -115,20 +126,14 @@ export class ClientServicesHost {
115
126
  // TODO(wittjosiah): Turn this on by default.
116
127
  lockKey,
117
128
  callbacks,
118
- runtimeParams,
119
- }: ClientServicesHostParams = {}) {
129
+ runtime,
130
+ runtimeProps,
131
+ }: ClientServicesHostProps) {
120
132
  this._storage = storage;
121
133
  this._level = level;
122
134
  this._callbacks = callbacks;
123
- this._runtimeParams = runtimeParams ?? {};
124
-
125
- if (this._runtimeParams.disableP2pReplication === undefined) {
126
- this._runtimeParams.disableP2pReplication = config?.get('runtime.client.disableP2pReplication', false);
127
- }
128
-
129
- if (this._runtimeParams.enableVectorIndexing === undefined) {
130
- this._runtimeParams.enableVectorIndexing = config?.get('runtime.client.enableVectorIndexing', false);
131
- }
135
+ this._runtime = runtime;
136
+ this._runtimeProps = runtimeProps ?? {};
132
137
 
133
138
  if (config) {
134
139
  this.initialize({ config, transportFactory, signalManager });
@@ -142,7 +147,7 @@ export class ClientServicesHost {
142
147
  void this.open(new Context());
143
148
  }
144
149
  },
145
- onRelease: () => this.close(),
150
+ onRelease: () => this.close(Context.default()),
146
151
  });
147
152
  }
148
153
 
@@ -199,6 +204,30 @@ export class ClientServicesHost {
199
204
  return this._serviceRegistry.services;
200
205
  }
201
206
 
207
+ /**
208
+ * Debugging util.
209
+ */
210
+ async exportSqliteDatabase(): Promise<Uint8Array> {
211
+ return await RuntimeProvider.runPromise(this._runtime)(
212
+ Effect.gen(function* () {
213
+ const sql = yield* SqlExport.SqlExport;
214
+ return yield* sql.export;
215
+ }),
216
+ );
217
+ }
218
+
219
+ /**
220
+ * Debugging util.
221
+ */
222
+ async runSqliteQuery(query: string, params?: any[]): Promise<readonly Record<string, unknown>[]> {
223
+ return await RuntimeProvider.runPromise(this._runtime)(
224
+ Effect.gen(function* () {
225
+ const sql = yield* SqlClient.SqlClient;
226
+ return yield* sql`${sql.unsafe(query, params)}`;
227
+ }),
228
+ );
229
+ }
230
+
202
231
  /**
203
232
  * Initialize the service host with the config.
204
233
  * Config can also be provided in the constructor.
@@ -209,6 +238,13 @@ export class ClientServicesHost {
209
238
  log('initializing...');
210
239
 
211
240
  if (config) {
241
+ if (this._runtimeProps.disableP2pReplication === undefined) {
242
+ this._runtimeProps.disableP2pReplication = config?.get('runtime.client.disableP2pReplication', false);
243
+ }
244
+ if (this._runtimeProps.enableVectorIndexing === undefined) {
245
+ this._runtimeProps.enableVectorIndexing = config?.get('runtime.client.enableVectorIndexing', false);
246
+ }
247
+
212
248
  invariant(!this._config, 'config already set');
213
249
  this._config = config;
214
250
  if (!this._storage) {
@@ -216,14 +252,16 @@ export class ClientServicesHost {
216
252
  }
217
253
  }
218
254
 
255
+ // TODO(wittjosiah): This is quite noisy during tests. Make configurable? Remove?
219
256
  if (!options.signalManager) {
220
- log.warn('running signaling without telemetry metadata.');
257
+ // log.warn('running signaling without telemetry metadata.');
221
258
  }
222
259
 
223
260
  const endpoint = config?.get('runtime.services.edge.url');
224
261
  if (endpoint) {
262
+ const clientTag = config?.get('runtime.app.env.DX_EDGE_CLIENT_TAG');
225
263
  this._edgeConnection = new EdgeClient(createStubEdgeIdentity(), { socketEndpoint: endpoint });
226
- this._edgeHttpClient = new EdgeHttpClient(endpoint);
264
+ this._edgeHttpClient = new EdgeHttpClient(endpoint, { clientTag });
227
265
  }
228
266
 
229
267
  const {
@@ -289,7 +327,8 @@ export class ClientServicesHost {
289
327
  this._signalManager,
290
328
  this._edgeConnection,
291
329
  this._edgeHttpClient,
292
- this._runtimeParams,
330
+ this._runtime,
331
+ this._runtimeProps,
293
332
  this._config.get('runtime.client.edgeFeatures'),
294
333
  );
295
334
 
@@ -307,7 +346,6 @@ export class ClientServicesHost {
307
346
  this._serviceContext.identityManager,
308
347
  this._serviceContext.recoveryManager,
309
348
  this._serviceContext.keyring,
310
- () => this._serviceContext.dataSpaceManager!,
311
349
  (params) => this._createIdentity(params),
312
350
  (profile) => this._serviceContext.broadcastProfileUpdate(profile),
313
351
  );
@@ -333,6 +371,7 @@ export class ClientServicesHost {
333
371
 
334
372
  DataService: this._serviceContext.echoHost.dataService,
335
373
  QueryService: this._serviceContext.echoHost.queryService,
374
+ QueueService: this._serviceContext.echoHost.queuesService,
336
375
 
337
376
  NetworkService: new NetworkServiceImpl(
338
377
  this._serviceContext.networkManager,
@@ -353,8 +392,13 @@ export class ClientServicesHost {
353
392
  EdgeAgentService: new EdgeAgentServiceImpl(agentManagerProvider, this._edgeConnection),
354
393
  });
355
394
 
395
+ log('service-host: opening service context...');
356
396
  await this._serviceContext.open(ctx);
397
+ log('service-host: service context opened');
398
+
399
+ log('service-host: opening identity service...');
357
400
  await identityService.open();
401
+ log('service-host: identity service opened');
358
402
 
359
403
  const devtoolsProxy = this._config?.get('runtime.client.devtoolsProxy');
360
404
  if (devtoolsProxy) {
@@ -378,7 +422,7 @@ export class ClientServicesHost {
378
422
 
379
423
  @synchronized
380
424
  @Trace.span()
381
- async close(): Promise<void> {
425
+ async close(ctx: Context): Promise<void> {
382
426
  if (!this._open) {
383
427
  return;
384
428
  }
@@ -406,6 +450,12 @@ export class ClientServicesHost {
406
450
  this._resetting = true;
407
451
  this._statusUpdate.emit();
408
452
  await this._serviceContext?.close();
453
+ // Clear LevelDB contents to remove all persisted Echo/Automerge/index data.
454
+ try {
455
+ await this._level!.clear();
456
+ } catch (err) {
457
+ log.warn('failed to clear leveldb during reset', { err });
458
+ }
409
459
  await this._storage!.reset();
410
460
  log.info('reset');
411
461
  log.trace('dxos.sdk.client-services-host.reset', trace.end({ id: traceId }));
@@ -13,10 +13,11 @@ import { schema } from '@dxos/protocols/proto';
13
13
  import { type SystemService, SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
14
14
  import { createLinkedPorts, createProtoRpcPeer, createServiceBundle } from '@dxos/rpc';
15
15
 
16
- import { ServiceRegistry } from './service-registry';
17
16
  import { SystemServiceImpl } from '../system';
18
17
  import { createServiceContext } from '../testing';
19
18
 
19
+ import { ServiceRegistry } from './service-registry';
20
+
20
21
  // TODO(burdon): Create TestService (that doesn't require peers).
21
22
 
22
23
  type TestServices = {
@@ -6,19 +6,33 @@ import type { DocumentId } from '@automerge/automerge-repo';
6
6
 
7
7
  import { assertArgument, failedInvariant, invariant } from '@dxos/invariant';
8
8
  import { log } from '@dxos/log';
9
- import { SpaceArchiveFileStructure, type SpaceArchiveMetadata } from '@dxos/protocols';
9
+ import {
10
+ type FeedArchiveBlock,
11
+ type FeedArchiveMetadata,
12
+ SpaceArchiveFileStructure,
13
+ type SpaceArchiveMetadata,
14
+ } from '@dxos/protocols';
10
15
  import type { SpaceArchive } from '@dxos/protocols/proto/dxos/client/services';
11
16
 
17
+ /**
18
+ * Extracted feed data from the archive.
19
+ */
20
+ export type ExtractedFeed = {
21
+ metadata: FeedArchiveMetadata;
22
+ blocks: FeedArchiveBlock[];
23
+ };
24
+
12
25
  export type ExtractedSpaceArchive = {
13
26
  metadata: SpaceArchiveMetadata;
14
27
  documents: Record<DocumentId, Uint8Array>;
28
+ feeds: Record<string, ExtractedFeed>;
15
29
  };
16
30
 
17
31
  export const extractSpaceArchive = async (archive: SpaceArchive): Promise<ExtractedSpaceArchive> => {
18
32
  const { Archive } = await import('@obsidize/tar-browserify');
19
33
  const { entries } = await Archive.extract(archive.contents);
20
34
  const metadataEntry = entries.find((entry) => entry.fileName === SpaceArchiveFileStructure.metadata);
21
- assertArgument(metadataEntry, 'Metadata entry not found');
35
+ assertArgument(metadataEntry, 'metadataEntry', 'Metadata entry not found');
22
36
  const metadata = JSON.parse(metadataEntry.getContentAsText());
23
37
  const documents: Record<DocumentId, Uint8Array> = {};
24
38
  for (const entry of entries.filter((entry) => entry.fileName.startsWith(`${SpaceArchiveFileStructure.documents}/`))) {
@@ -29,6 +43,53 @@ export const extractSpaceArchive = async (archive: SpaceArchive): Promise<Extrac
29
43
  documents[documentId] = entry.content ?? failedInvariant();
30
44
  }
31
45
 
32
- log.info('extracted space archive', { metadata, documents });
33
- return { metadata, documents };
46
+ const feeds: Record<string, ExtractedFeed> = {};
47
+ const feedsPrefix = `${SpaceArchiveFileStructure.feeds}/`;
48
+ const feedEntries = entries.filter((entry) => entry.fileName.startsWith(feedsPrefix));
49
+
50
+ const feedMetadataByFeedId = new Map<string, FeedArchiveMetadata>();
51
+ const feedBlocksByFeedId = new Map<string, Map<number, FeedArchiveBlock[]>>();
52
+
53
+ for (const entry of feedEntries) {
54
+ const relativePath = entry.fileName.slice(feedsPrefix.length);
55
+ const pathParts = relativePath.split('/');
56
+ if (pathParts.length !== 2) {
57
+ continue;
58
+ }
59
+
60
+ const [feedId, fileName] = pathParts;
61
+ invariant(feedId, 'Feed ID is required');
62
+ invariant(fileName, 'File name is required');
63
+
64
+ if (fileName === SpaceArchiveFileStructure.feedMetadata) {
65
+ const feedMetadata = JSON.parse(entry.getContentAsText()) as FeedArchiveMetadata;
66
+ feedMetadataByFeedId.set(feedId, feedMetadata);
67
+ } else if (fileName.startsWith(SpaceArchiveFileStructure.feedBlocksPrefix) && fileName.endsWith('.json')) {
68
+ const chunkIndexStr = fileName.slice(SpaceArchiveFileStructure.feedBlocksPrefix.length).replace(/\.json$/, '');
69
+ const chunkIndex = parseInt(chunkIndexStr, 10);
70
+ invariant(!isNaN(chunkIndex), `Invalid chunk index: ${chunkIndexStr}`);
71
+
72
+ const blocks = JSON.parse(entry.getContentAsText()) as FeedArchiveBlock[];
73
+ if (!feedBlocksByFeedId.has(feedId)) {
74
+ feedBlocksByFeedId.set(feedId, new Map());
75
+ }
76
+ feedBlocksByFeedId.get(feedId)!.set(chunkIndex, blocks);
77
+ }
78
+ }
79
+
80
+ for (const [feedId, feedMetadata] of feedMetadataByFeedId) {
81
+ const blockChunks = feedBlocksByFeedId.get(feedId) ?? new Map<number, FeedArchiveBlock[]>();
82
+ const sortedChunkIndices = Array.from(blockChunks.keys()).sort((a, b) => a - b);
83
+ const allBlocks: FeedArchiveBlock[] = [];
84
+ for (const chunkIndex of sortedChunkIndices) {
85
+ allBlocks.push(...blockChunks.get(chunkIndex)!);
86
+ }
87
+ feeds[feedId] = {
88
+ metadata: feedMetadata,
89
+ blocks: allBlocks,
90
+ };
91
+ }
92
+
93
+ log('extracted space archive', { metadata, documents, feedCount: Object.keys(feeds).length });
94
+ return { metadata, documents, feeds };
34
95
  };
@@ -4,11 +4,19 @@
4
4
 
5
5
  import type * as tar from '@obsidize/tar-browserify';
6
6
 
7
- import { Resource, type Context } from '@dxos/context';
7
+ import { type Context, Resource } from '@dxos/context';
8
8
  import { assertArgument, assertState } from '@dxos/invariant';
9
9
  import type { IdentityDid, SpaceId } from '@dxos/keys';
10
- import { SpaceArchiveFileStructure, SpaceArchiveVersion, type SpaceArchiveMetadata } from '@dxos/protocols';
10
+ import {
11
+ FEED_ARCHIVE_BLOCKS_PER_CHUNK,
12
+ type FeedArchiveBlock,
13
+ type FeedArchiveMetadata,
14
+ SpaceArchiveFileStructure,
15
+ type SpaceArchiveMetadata,
16
+ SpaceArchiveVersion,
17
+ } from '@dxos/protocols';
11
18
  import type { SpaceArchive } from '@dxos/protocols/proto/dxos/client/services';
19
+ import { createFilename } from '@dxos/util';
12
20
 
13
21
  export type SpaceArchiveBeginProps = {
14
22
  spaceId?: SpaceId;
@@ -44,21 +52,50 @@ export class SpaceArchiveWriter extends Resource {
44
52
  }
45
53
 
46
54
  async setCurrentRootUrl(url: string): Promise<void> {
47
- assertArgument(url.startsWith('automerge:'), 'Invalid root URL');
55
+ assertArgument(url.startsWith('automerge:'), 'url', 'Invalid root URL');
48
56
  assertState(this._tar, 'Not open');
49
57
  assertState(this._meta, 'Not started');
50
58
  this._currentRootUrl = url;
51
59
  }
52
60
 
53
61
  async writeDocument(documentId: string, data: Uint8Array): Promise<void> {
54
- assertArgument(!documentId.startsWith('automerge:'), 'Invalid document ID');
62
+ assertArgument(!documentId.startsWith('automerge:'), 'documentId', 'Invalid document ID');
55
63
  assertState(this._archive, 'Not open');
56
64
  this._archive.addBinaryFile(`${SpaceArchiveFileStructure.documents}/${documentId}.bin`, data);
57
65
  }
58
66
 
67
+ /**
68
+ * Writes a feed with its metadata and blocks to the archive.
69
+ * Blocks are written in chunks of {@link FEED_ARCHIVE_BLOCKS_PER_CHUNK}.
70
+ */
71
+ async writeFeed(feedId: string, namespace: string, blocks: FeedArchiveBlock[]): Promise<void> {
72
+ assertArgument(feedId, 'feedId', 'Feed ID is required');
73
+ assertArgument(namespace, 'namespace', 'Namespace is required');
74
+ assertState(this._archive, 'Not open');
75
+
76
+ const feedPath = `${SpaceArchiveFileStructure.feeds}/${feedId}`;
77
+
78
+ const metadata: FeedArchiveMetadata = {
79
+ id: feedId,
80
+ namespace,
81
+ };
82
+ this._archive.addTextFile(`${feedPath}/${SpaceArchiveFileStructure.feedMetadata}`, JSON.stringify(metadata));
83
+
84
+ for (let chunkIndex = 0; chunkIndex * FEED_ARCHIVE_BLOCKS_PER_CHUNK < blocks.length; chunkIndex++) {
85
+ const start = chunkIndex * FEED_ARCHIVE_BLOCKS_PER_CHUNK;
86
+ const end = Math.min(start + FEED_ARCHIVE_BLOCKS_PER_CHUNK, blocks.length);
87
+ const chunk = blocks.slice(start, end);
88
+ this._archive.addTextFile(
89
+ `${feedPath}/${SpaceArchiveFileStructure.feedBlocksPrefix}${chunkIndex}.json`,
90
+ JSON.stringify(chunk),
91
+ );
92
+ }
93
+ }
94
+
59
95
  async finish(): Promise<SpaceArchive> {
60
96
  assertState(this._archive, 'Not open');
61
97
  assertState(this._meta, 'Not started');
98
+ assertState(this._meta.spaceId, 'No space ID set');
62
99
  assertState(this._currentRootUrl, 'No root URL set');
63
100
 
64
101
  const metadata: SpaceArchiveMetadata = {
@@ -76,7 +113,7 @@ export class SpaceArchiveWriter extends Resource {
76
113
  const binary = this._archive.toUint8Array();
77
114
 
78
115
  return {
79
- filename: `${this._meta.spaceId}.tar`,
116
+ filename: createFilename({ parts: [this._meta.spaceId], ext: 'tar' }),
80
117
  contents: binary,
81
118
  };
82
119
  }