@dxos/client-services 0.8.4-main.84f28bd → 0.8.4-main.937b3ca

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 (201) hide show
  1. package/dist/lib/browser/chunk-NQSC7HOE.mjs +22 -0
  2. package/dist/lib/browser/chunk-NQSC7HOE.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
  4. package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-OCFDRCSN.mjs → chunk-UDCUM4WV.mjs} +3626 -3714
  6. package/dist/lib/browser/chunk-UDCUM4WV.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +462 -76
  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 +34 -22
  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-PKEGMOQ4.mjs +22 -0
  23. package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs.map +7 -0
  24. package/dist/lib/node-esm/{chunk-D7F3FYZS.mjs → chunk-Q56HAUWS.mjs} +2636 -2592
  25. package/dist/lib/node-esm/chunk-Q56HAUWS.mjs.map +7 -0
  26. package/dist/lib/node-esm/index.mjs +462 -76
  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 +34 -22
  38. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  39. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +1 -1
  40. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  41. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  42. package/dist/types/src/packlets/devtools/devtools.d.ts +20 -20
  43. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  44. package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
  45. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  46. package/dist/types/src/packlets/devtools/network.d.ts +1 -1
  47. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  48. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts +1 -1
  49. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  50. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +1 -1
  51. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  52. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +1 -1
  53. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  54. package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
  55. package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
  56. package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
  57. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  58. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  59. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  60. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +3 -3
  61. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +1 -1
  62. package/dist/types/src/packlets/identity/identity-manager.d.ts +5 -5
  63. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  64. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +2 -2
  65. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  66. package/dist/types/src/packlets/identity/identity-service.d.ts +1 -1
  67. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  68. package/dist/types/src/packlets/identity/identity.d.ts +3 -3
  69. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  70. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +4 -4
  71. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  72. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
  73. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  74. package/dist/types/src/packlets/invitations/index.d.ts +1 -1
  75. package/dist/types/src/packlets/invitations/index.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.map +1 -1
  83. package/dist/types/src/packlets/invitations/invitations-service.d.ts +1 -1
  84. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  85. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +3 -3
  86. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  87. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  88. package/dist/types/src/packlets/locks/index.d.ts +2 -2
  89. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  90. package/dist/types/src/packlets/logging/logging-service.d.ts +1 -1
  91. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  92. package/dist/types/src/packlets/network/network-service.d.ts +2 -2
  93. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  94. package/dist/types/src/packlets/services/client-rpc-server.d.ts +2 -2
  95. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  96. package/dist/types/src/packlets/services/service-context.d.ts +14 -8
  97. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  98. package/dist/types/src/packlets/services/service-host.d.ts +20 -6
  99. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  100. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +1 -1
  101. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  102. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts +1 -1
  103. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  104. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +12 -7
  105. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  106. package/dist/types/src/packlets/spaces/data-space.d.ts +6 -6
  107. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  108. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  109. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  110. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -6
  111. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  112. package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -2
  113. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  114. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  115. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  116. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  117. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  118. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  119. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  120. package/dist/types/src/packlets/testing/test-builder.d.ts +8 -7
  121. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  122. package/dist/types/src/packlets/worker/worker-runtime.d.ts +23 -4
  123. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  124. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -2
  125. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  126. package/dist/types/src/version.d.ts +1 -1
  127. package/dist/types/tsconfig.tsbuildinfo +1 -1
  128. package/package.json +72 -48
  129. package/src/packlets/agents/edge-agent-manager.ts +2 -2
  130. package/src/packlets/agents/edge-agent-service.ts +13 -3
  131. package/src/packlets/devices/devices-service.test.ts +4 -3
  132. package/src/packlets/devices/devices-service.ts +2 -2
  133. package/src/packlets/devtools/devtools.ts +30 -29
  134. package/src/packlets/devtools/feeds.ts +2 -2
  135. package/src/packlets/devtools/network.ts +1 -1
  136. package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +1 -1
  137. package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -1
  138. package/src/packlets/diagnostics/diagnostics-collector.ts +1 -1
  139. package/src/packlets/diagnostics/diagnostics.ts +1 -1
  140. package/src/packlets/diagnostics/index.ts +1 -1
  141. package/src/packlets/identity/authenticator.node.test.ts +1 -1
  142. package/src/packlets/identity/authenticator.ts +3 -3
  143. package/src/packlets/identity/contacts-service.ts +3 -2
  144. package/src/packlets/identity/default-space-state-machine.ts +3 -3
  145. package/src/packlets/identity/identity-manager.test.ts +3 -3
  146. package/src/packlets/identity/identity-manager.ts +9 -9
  147. package/src/packlets/identity/identity-recovery-manager.ts +2 -2
  148. package/src/packlets/identity/identity-service.test.ts +3 -2
  149. package/src/packlets/identity/identity-service.ts +2 -1
  150. package/src/packlets/identity/identity.test.ts +9 -9
  151. package/src/packlets/identity/identity.ts +9 -8
  152. package/src/packlets/invitations/device-invitation-protocol.test.ts +4 -4
  153. package/src/packlets/invitations/device-invitation-protocol.ts +6 -5
  154. package/src/packlets/invitations/edge-invitation-handler.ts +1 -1
  155. package/src/packlets/invitations/index.ts +1 -1
  156. package/src/packlets/invitations/invitation-guest-extenstion.ts +7 -5
  157. package/src/packlets/invitations/invitation-host-extension.ts +8 -6
  158. package/src/packlets/invitations/invitation-protocol.ts +3 -4
  159. package/src/packlets/invitations/invitations-handler.test.ts +302 -292
  160. package/src/packlets/invitations/invitations-handler.ts +10 -10
  161. package/src/packlets/invitations/invitations-manager.ts +3 -3
  162. package/src/packlets/invitations/invitations-service.ts +1 -1
  163. package/src/packlets/invitations/space-invitation-protocol.test.ts +9 -9
  164. package/src/packlets/invitations/space-invitation-protocol.ts +10 -15
  165. package/src/packlets/invitations/utils.ts +1 -1
  166. package/src/packlets/locks/browser.ts +1 -1
  167. package/src/packlets/locks/index.ts +2 -2
  168. package/src/packlets/logging/logging-service.ts +4 -3
  169. package/src/packlets/logging/logging.test.ts +1 -1
  170. package/src/packlets/network/network-service.test.ts +4 -3
  171. package/src/packlets/network/network-service.ts +2 -2
  172. package/src/packlets/services/client-rpc-server.ts +5 -5
  173. package/src/packlets/services/service-context.test.ts +1 -1
  174. package/src/packlets/services/service-context.ts +39 -27
  175. package/src/packlets/services/service-host.test.ts +3 -2
  176. package/src/packlets/services/service-host.ts +74 -25
  177. package/src/packlets/services/service-registry.test.ts +2 -1
  178. package/src/packlets/space-export/space-archive-reader.ts +2 -2
  179. package/src/packlets/space-export/space-archive-writer.ts +7 -5
  180. package/src/packlets/space-export/tar.test.ts +1 -1
  181. package/src/packlets/spaces/automerge-space-state.ts +1 -1
  182. package/src/packlets/spaces/data-space-manager.ts +76 -36
  183. package/src/packlets/spaces/data-space.ts +15 -13
  184. package/src/packlets/spaces/edge-feed-replicator.test.ts +3 -3
  185. package/src/packlets/spaces/edge-feed-replicator.ts +4 -4
  186. package/src/packlets/spaces/epoch-migrations.ts +2 -2
  187. package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
  188. package/src/packlets/spaces/notarization-plugin.ts +11 -11
  189. package/src/packlets/spaces/spaces-service.test.ts +3 -2
  190. package/src/packlets/spaces/spaces-service.ts +27 -23
  191. package/src/packlets/storage/profile-archive.ts +1 -1
  192. package/src/packlets/storage/storage.ts +7 -8
  193. package/src/packlets/system/system-service.test.ts +1 -1
  194. package/src/packlets/system/system-service.ts +4 -4
  195. package/src/packlets/testing/invitation-utils.ts +8 -5
  196. package/src/packlets/testing/test-builder.ts +39 -13
  197. package/src/packlets/worker/worker-runtime.ts +143 -12
  198. package/src/packlets/worker/worker-session.ts +7 -7
  199. package/src/version.ts +1 -1
  200. package/dist/lib/browser/chunk-OCFDRCSN.mjs.map +0 -7
  201. package/dist/lib/node-esm/chunk-D7F3FYZS.mjs.map +0 -7
@@ -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 = {
@@ -81,8 +89,9 @@ export class ClientServicesHost {
81
89
  private readonly _loggingService: LoggingServiceImpl;
82
90
  private readonly _tracingService = TRACE_PROCESSOR.createTraceSender();
83
91
 
84
- private _config?: Config;
85
92
  private readonly _statusUpdate = new Event<void>();
93
+
94
+ private _config?: Config;
86
95
  private _signalManager?: SignalManager;
87
96
  private _networkManager?: SwarmNetworkManager;
88
97
  private _storage?: Storage;
@@ -93,7 +102,10 @@ export class ClientServicesHost {
93
102
  private _edgeHttpClient?: EdgeHttpClient = undefined;
94
103
 
95
104
  private _serviceContext!: ServiceContext;
96
- private readonly _runtimeParams: ServiceContextRuntimeParams;
105
+ private readonly _runtime: RuntimeProvider.RuntimeProvider<
106
+ SqlClient.SqlClient | SqlExport.SqlExport | SqlTransaction.SqlTransaction
107
+ >;
108
+ private readonly _runtimeProps: ServiceContextRuntimeProps;
97
109
  private diagnosticsBroadcastHandler: CollectDiagnosticsBroadcastHandler;
98
110
 
99
111
  @Trace.info()
@@ -114,20 +126,14 @@ export class ClientServicesHost {
114
126
  // TODO(wittjosiah): Turn this on by default.
115
127
  lockKey,
116
128
  callbacks,
117
- runtimeParams,
118
- }: ClientServicesHostParams = {}) {
129
+ runtime,
130
+ runtimeProps,
131
+ }: ClientServicesHostProps) {
119
132
  this._storage = storage;
120
133
  this._level = level;
121
134
  this._callbacks = callbacks;
122
- this._runtimeParams = runtimeParams ?? {};
123
-
124
- if (this._runtimeParams.disableP2pReplication === undefined) {
125
- this._runtimeParams.disableP2pReplication = config?.get('runtime.client.disableP2pReplication', false);
126
- }
127
-
128
- if (this._runtimeParams.enableVectorIndexing === undefined) {
129
- this._runtimeParams.enableVectorIndexing = config?.get('runtime.client.enableVectorIndexing', false);
130
- }
135
+ this._runtime = runtime;
136
+ this._runtimeProps = runtimeProps ?? {};
131
137
 
132
138
  if (config) {
133
139
  this.initialize({ config, transportFactory, signalManager });
@@ -198,6 +204,30 @@ export class ClientServicesHost {
198
204
  return this._serviceRegistry.services;
199
205
  }
200
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
+
201
231
  /**
202
232
  * Initialize the service host with the config.
203
233
  * Config can also be provided in the constructor.
@@ -208,6 +238,16 @@ export class ClientServicesHost {
208
238
  log('initializing...');
209
239
 
210
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
+ if (this._runtimeProps.enableLocalQueues === undefined) {
248
+ this._runtimeProps.enableLocalQueues = config?.get('runtime.client.enableLocalQueues', false);
249
+ }
250
+
211
251
  invariant(!this._config, 'config already set');
212
252
  this._config = config;
213
253
  if (!this._storage) {
@@ -215,8 +255,9 @@ export class ClientServicesHost {
215
255
  }
216
256
  }
217
257
 
258
+ // TODO(wittjosiah): This is quite noisy during tests. Make configurable? Remove?
218
259
  if (!options.signalManager) {
219
- log.warn('running signaling without telemetry metadata.');
260
+ // log.warn('running signaling without telemetry metadata.');
220
261
  }
221
262
 
222
263
  const endpoint = config?.get('runtime.services.edge.url');
@@ -288,7 +329,8 @@ export class ClientServicesHost {
288
329
  this._signalManager,
289
330
  this._edgeConnection,
290
331
  this._edgeHttpClient,
291
- this._runtimeParams,
332
+ this._runtime,
333
+ this._runtimeProps,
292
334
  this._config.get('runtime.client.edgeFeatures'),
293
335
  );
294
336
 
@@ -332,6 +374,7 @@ export class ClientServicesHost {
332
374
 
333
375
  DataService: this._serviceContext.echoHost.dataService,
334
376
  QueryService: this._serviceContext.echoHost.queryService,
377
+ QueueService: this._serviceContext.echoHost.queuesService,
335
378
 
336
379
  NetworkService: new NetworkServiceImpl(
337
380
  this._serviceContext.networkManager,
@@ -405,6 +448,12 @@ export class ClientServicesHost {
405
448
  this._resetting = true;
406
449
  this._statusUpdate.emit();
407
450
  await this._serviceContext?.close();
451
+ // Clear LevelDB contents to remove all persisted Echo/Automerge/index data.
452
+ try {
453
+ await this._level!.clear();
454
+ } catch (err) {
455
+ log.warn('failed to clear leveldb during reset', { err });
456
+ }
408
457
  await this._storage!.reset();
409
458
  log.info('reset');
410
459
  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 = {
@@ -18,7 +18,7 @@ export const extractSpaceArchive = async (archive: SpaceArchive): Promise<Extrac
18
18
  const { Archive } = await import('@obsidize/tar-browserify');
19
19
  const { entries } = await Archive.extract(archive.contents);
20
20
  const metadataEntry = entries.find((entry) => entry.fileName === SpaceArchiveFileStructure.metadata);
21
- assertArgument(metadataEntry, 'Metadata entry not found');
21
+ assertArgument(metadataEntry, 'metadataEntry', 'Metadata entry not found');
22
22
  const metadata = JSON.parse(metadataEntry.getContentAsText());
23
23
  const documents: Record<DocumentId, Uint8Array> = {};
24
24
  for (const entry of entries.filter((entry) => entry.fileName.startsWith(`${SpaceArchiveFileStructure.documents}/`))) {
@@ -29,6 +29,6 @@ export const extractSpaceArchive = async (archive: SpaceArchive): Promise<Extrac
29
29
  documents[documentId] = entry.content ?? failedInvariant();
30
30
  }
31
31
 
32
- log.info('extracted space archive', { metadata, documents });
32
+ log('extracted space archive', { metadata, documents });
33
33
  return { metadata, documents };
34
34
  };
@@ -4,11 +4,12 @@
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 { SpaceArchiveFileStructure, type SpaceArchiveMetadata, SpaceArchiveVersion } from '@dxos/protocols';
11
11
  import type { SpaceArchive } from '@dxos/protocols/proto/dxos/client/services';
12
+ import { createFilename } from '@dxos/util';
12
13
 
13
14
  export type SpaceArchiveBeginProps = {
14
15
  spaceId?: SpaceId;
@@ -44,14 +45,14 @@ export class SpaceArchiveWriter extends Resource {
44
45
  }
45
46
 
46
47
  async setCurrentRootUrl(url: string): Promise<void> {
47
- assertArgument(url.startsWith('automerge:'), 'Invalid root URL');
48
+ assertArgument(url.startsWith('automerge:'), 'url', 'Invalid root URL');
48
49
  assertState(this._tar, 'Not open');
49
50
  assertState(this._meta, 'Not started');
50
51
  this._currentRootUrl = url;
51
52
  }
52
53
 
53
54
  async writeDocument(documentId: string, data: Uint8Array): Promise<void> {
54
- assertArgument(!documentId.startsWith('automerge:'), 'Invalid document ID');
55
+ assertArgument(!documentId.startsWith('automerge:'), 'documentId', 'Invalid document ID');
55
56
  assertState(this._archive, 'Not open');
56
57
  this._archive.addBinaryFile(`${SpaceArchiveFileStructure.documents}/${documentId}.bin`, data);
57
58
  }
@@ -59,6 +60,7 @@ export class SpaceArchiveWriter extends Resource {
59
60
  async finish(): Promise<SpaceArchive> {
60
61
  assertState(this._archive, 'Not open');
61
62
  assertState(this._meta, 'Not started');
63
+ assertState(this._meta.spaceId, 'No space ID set');
62
64
  assertState(this._currentRootUrl, 'No root URL set');
63
65
 
64
66
  const metadata: SpaceArchiveMetadata = {
@@ -76,7 +78,7 @@ export class SpaceArchiveWriter extends Resource {
76
78
  const binary = this._archive.toUint8Array();
77
79
 
78
80
  return {
79
- filename: `${this._meta.spaceId}.tar`,
81
+ filename: createFilename({ parts: [this._meta.spaceId], ext: 'tar' }),
80
82
  contents: binary,
81
83
  };
82
84
  }
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Archive } from '@obsidize/tar-browserify';
6
- import { describe, it, expect } from 'vitest';
6
+ import { describe, expect, it } from 'vitest';
7
7
 
8
8
  describe('tar', () => {
9
9
  it('should create a tar archive', async () => {
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Event } from '@dxos/async';
6
- import { Resource, type Context } from '@dxos/context';
6
+ import { type Context, Resource } from '@dxos/context';
7
7
  import { type CredentialProcessor, type SpecificCredential, checkCredentialType } from '@dxos/credentials';
8
8
  import { type Credential, type Epoch } from '@dxos/protocols/proto/dxos/halo/credentials';
9
9
 
@@ -3,66 +3,67 @@
3
3
  //
4
4
 
5
5
  import { type Doc } from '@automerge/automerge';
6
- import { interpretAsDocumentId, type AutomergeUrl, type DocHandle, type DocumentId } from '@automerge/automerge-repo';
6
+ import { type AutomergeUrl, type DocHandle, type DocumentId, interpretAsDocumentId } from '@automerge/automerge-repo';
7
7
 
8
8
  import { Event, synchronized, trackLeaks } from '@dxos/async';
9
- import { PropertiesType, TYPE_PROPERTIES } from '@dxos/client-protocol';
9
+ import { SpaceProperties } from '@dxos/client-protocol';
10
10
  import { Context, LifecycleState, Resource, cancelWithContext } from '@dxos/context';
11
11
  import {
12
- createAdmissionCredentials,
13
- getCredentialAssertion,
14
12
  type CredentialSigner,
15
13
  type DelegateInvitationCredential,
16
14
  type MemberInfo,
15
+ createAdmissionCredentials,
16
+ getCredentialAssertion,
17
17
  } from '@dxos/credentials';
18
+ import { Type } from '@dxos/echo';
19
+ import { getSchemaDXN } from '@dxos/echo/internal';
18
20
  import {
21
+ AuthStatus,
22
+ CredentialServerExtension,
19
23
  DatabaseRoot,
20
- findInlineObjectOfType,
21
24
  type EchoEdgeReplicator,
22
25
  type EchoHost,
23
- AuthStatus,
24
- CredentialServerExtension,
25
26
  type MeshEchoReplicator,
26
27
  type MetadataStore,
27
28
  type Space,
28
29
  type SpaceManager,
29
30
  type SpaceProtocol,
30
31
  type SpaceProtocolSession,
31
- FIND_PARAMS,
32
+ findInlineObjectOfType,
32
33
  } from '@dxos/echo-pipeline';
33
34
  import {
35
+ type DatabaseDirectory,
36
+ EncodedReference,
37
+ type ObjectStructure,
34
38
  SpaceDocVersion,
35
39
  createIdFromSpaceKey,
36
- encodeReference,
37
- type ObjectStructure,
38
- type DatabaseDirectory,
39
40
  } from '@dxos/echo-protocol';
40
- import { ObjectId, getTypeReference } from '@dxos/echo-schema';
41
41
  import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
42
- import { writeMessages, type FeedStore } from '@dxos/feed-store';
42
+ import { type FeedStore, writeMessages } from '@dxos/feed-store';
43
43
  import { assertArgument, assertState, failedInvariant, invariant } from '@dxos/invariant';
44
44
  import { type Keyring } from '@dxos/keyring';
45
- import { PublicKey, type SpaceId } from '@dxos/keys';
45
+ import { ObjectId, PublicKey, type SpaceId } from '@dxos/keys';
46
46
  import { log } from '@dxos/log';
47
47
  import { AlreadyJoinedError, trace as Trace } from '@dxos/protocols';
48
48
  import { Invitation, SpaceState } from '@dxos/protocols/proto/dxos/client/services';
49
49
  import { type Runtime } from '@dxos/protocols/proto/dxos/config';
50
50
  import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
51
- import { type SpaceMetadata, EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
52
- import { SpaceMember, type Credential, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
51
+ import { EdgeReplicationSetting, type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
52
+ import { type Credential, type ProfileDocument, SpaceMember } from '@dxos/protocols/proto/dxos/halo/credentials';
53
53
  import { type DelegateSpaceInvitation } from '@dxos/protocols/proto/dxos/halo/invitations';
54
54
  import { type PeerState } from '@dxos/protocols/proto/dxos/mesh/presence';
55
55
  import { type Teleport } from '@dxos/teleport';
56
56
  import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
57
57
  import { type Timeframe } from '@dxos/timeframe';
58
58
  import { trace } from '@dxos/tracing';
59
- import { ComplexMap, setDeep, deferFunction, forEachAsync } from '@dxos/util';
59
+ import { ComplexMap, deferFunction, forEachAsync, setDeep } from '@dxos/util';
60
60
 
61
- import { DataSpace } from './data-space';
62
- import { spaceGenesis } from './genesis';
63
61
  import { createAuthProvider } from '../identity';
64
62
  import { type InvitationsManager } from '../invitations';
65
63
 
64
+ import { DataSpace } from './data-space';
65
+ import { spaceGenesis } from './genesis';
66
+
66
67
  const PRESENCE_ANNOUNCE_INTERVAL = 10_000;
67
68
  const PRESENCE_OFFLINE_TIMEOUT = 20_000;
68
69
 
@@ -103,7 +104,7 @@ export type AdmitMemberOptions = {
103
104
  delegationCredentialId?: PublicKey;
104
105
  };
105
106
 
106
- export type DataSpaceManagerParams = {
107
+ export type DataSpaceManagerProps = {
107
108
  spaceManager: SpaceManager;
108
109
  metadataStore: MetadataStore;
109
110
  keyring: Keyring;
@@ -115,15 +116,20 @@ export type DataSpaceManagerParams = {
115
116
  edgeHttpClient?: EdgeHttpClient;
116
117
  meshReplicator?: MeshEchoReplicator;
117
118
  echoEdgeReplicator?: EchoEdgeReplicator;
118
- runtimeParams?: DataSpaceManagerRuntimeParams;
119
+ runtimeProps?: DataSpaceManagerRuntimeProps;
119
120
  edgeFeatures?: Runtime.Client.EdgeFeatures;
120
121
  };
121
122
 
122
- export type DataSpaceManagerRuntimeParams = {
123
+ export type DataSpaceManagerRuntimeProps = {
123
124
  spaceMemberPresenceAnnounceInterval?: number;
124
125
  spaceMemberPresenceOfflineTimeout?: number;
125
126
  activeEdgeNotarizationPollingInterval?: number;
126
127
  disableP2pReplication?: boolean;
128
+ /**
129
+ * If true, spaces that were previously SPACE_ACTIVE will be automatically activated on startup.
130
+ * This is used in dedicated worker mode to restore space state after leader changeover.
131
+ */
132
+ autoActivateSpaces?: boolean;
127
133
  };
128
134
 
129
135
  export type CreateSpaceOptions = {
@@ -151,9 +157,9 @@ export class DataSpaceManager extends Resource {
151
157
  private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures = undefined;
152
158
  private readonly _meshReplicator?: MeshEchoReplicator = undefined;
153
159
  private readonly _echoEdgeReplicator?: EchoEdgeReplicator = undefined;
154
- private readonly _runtimeParams?: DataSpaceManagerRuntimeParams = undefined;
160
+ private readonly _runtimeProps?: DataSpaceManagerRuntimeProps = undefined;
155
161
 
156
- constructor(params: DataSpaceManagerParams) {
162
+ constructor(params: DataSpaceManagerProps) {
157
163
  super();
158
164
 
159
165
  this._spaceManager = params.spaceManager;
@@ -168,7 +174,7 @@ export class DataSpaceManager extends Resource {
168
174
  this._edgeFeatures = params.edgeFeatures;
169
175
  this._echoEdgeReplicator = params.echoEdgeReplicator;
170
176
  this._edgeHttpClient = params.edgeHttpClient;
171
- this._runtimeParams = params.runtimeParams;
177
+ this._runtimeProps = params.runtimeProps;
172
178
 
173
179
  trace.diagnostic({
174
180
  id: 'spaces',
@@ -178,12 +184,12 @@ export class DataSpaceManager extends Resource {
178
184
  Array.from(this._spaces.values()).map(async (space) => {
179
185
  const rootUrl = space.automergeSpaceState.rootUrl;
180
186
  const rootHandle = rootUrl
181
- ? await this._echoHost.automergeRepo.find<Doc<DatabaseDirectory>>(rootUrl as AutomergeUrl, FIND_PARAMS)
187
+ ? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(Context.default(), rootUrl as AutomergeUrl)
182
188
  : undefined;
183
189
  await rootHandle?.whenReady();
184
190
  const rootDoc = rootHandle?.doc();
185
191
 
186
- const properties = rootDoc && findInlineObjectOfType(rootDoc, TYPE_PROPERTIES);
192
+ const properties = rootDoc && findInlineObjectOfType(rootDoc, Type.getTypename(SpaceProperties));
187
193
 
188
194
  return {
189
195
  key: space.key.toHex(),
@@ -216,15 +222,28 @@ export class DataSpaceManager extends Resource {
216
222
  log.trace('dxos.echo.data-space-manager.open', Trace.begin({ id: this._instanceId }));
217
223
  log('metadata loaded', { spaces: this._metadataStore.spaces.length });
218
224
 
225
+ const spacesToActivate: DataSpace[] = [];
219
226
  await forEachAsync(this._metadataStore.spaces, async (spaceMetadata) => {
220
227
  try {
221
228
  log('load space', { spaceMetadata });
222
- await this._constructSpace(spaceMetadata);
229
+ const space = await this._constructSpace(spaceMetadata);
230
+ // Track spaces that were previously active for auto-activation (used in dedicated worker mode).
231
+ if (this._runtimeProps?.autoActivateSpaces && spaceMetadata.state === SpaceState.SPACE_ACTIVE) {
232
+ spacesToActivate.push(space);
233
+ }
223
234
  } catch (err) {
224
235
  log.error('Error loading space', { spaceMetadata, err });
225
236
  }
226
237
  });
227
238
 
239
+ // Auto-activate spaces that were previously active (used in dedicated worker mode after leader changeover).
240
+ for (const space of spacesToActivate) {
241
+ log('auto-activating space', { spaceKey: space.key });
242
+ space.activate().catch((err) => {
243
+ log.error('Error auto-activating space', { spaceKey: space.key, err });
244
+ });
245
+ }
246
+
228
247
  this.updated.emit();
229
248
 
230
249
  log.trace('dxos.echo.data-space-manager.open', Trace.end({ id: this._instanceId }));
@@ -244,7 +263,11 @@ export class DataSpaceManager extends Resource {
244
263
  */
245
264
  @synchronized
246
265
  async createSpace(options: CreateSpaceOptions = {}): Promise<DataSpace> {
247
- assertArgument(!!options.rootUrl === !!options.documents, 'root url must be required when providing documents');
266
+ assertArgument(
267
+ !!options.rootUrl === !!options.documents,
268
+ 'options',
269
+ 'root url must be required when providing documents',
270
+ );
248
271
 
249
272
  assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
250
273
  const spaceKey = await this._keyring.createKey();
@@ -274,7 +297,18 @@ export class DataSpaceManager extends Resource {
274
297
  await Promise.all(
275
298
  Object.entries(options.documents).map(async ([documentId, data]) => {
276
299
  log('creating document...', { documentId });
277
- const newDoc = await this._echoHost.createDoc(data, { preserveHistory: true });
300
+ // TODO(dmaretskyi): Broken types -- the bytes get interpreted as CRDT data.
301
+ const newDoc = await this._echoHost.createDoc(data as any as DatabaseDirectory, {
302
+ preserveHistory: true,
303
+ });
304
+
305
+ // The archived documents might have the spaceKey from the space they were expored from, we need to update it to the new spaceKey.
306
+ if (newDoc.doc().access !== undefined && newDoc.doc().access!.spaceKey !== spaceKey.toHex()) {
307
+ newDoc.change((doc) => {
308
+ doc.access!.spaceKey = spaceKey.toHex();
309
+ });
310
+ }
311
+
278
312
  documentIdMapping[documentId as DocumentId] = newDoc.documentId;
279
313
  }),
280
314
  );
@@ -292,6 +326,7 @@ export class DataSpaceManager extends Resource {
292
326
  } else {
293
327
  root = await this._echoHost.createSpaceRoot(spaceKey);
294
328
  }
329
+ await this._echoHost.flush();
295
330
 
296
331
  log('constructing space...', { spaceKey });
297
332
 
@@ -325,9 +360,12 @@ export class DataSpaceManager extends Resource {
325
360
  log.warn('waiting for space root to be ready', { spaceId: space.id });
326
361
  await space.databaseRoot.handle.whenReady();
327
362
  }
328
- const [_, properties] = findInlineObjectOfType(space.databaseRoot.doc()!, TYPE_PROPERTIES) ?? [];
363
+
364
+ const [_, properties] =
365
+ findInlineObjectOfType(space.databaseRoot.doc()!, Type.getTypename(SpaceProperties)) ?? [];
329
366
  return properties?.data?.[DEFAULT_SPACE_KEY] === this._signingContext.identityKey.toHex();
330
367
  }
368
+
331
369
  case SpaceDocVersion.LEGACY: {
332
370
  throw new Error('Legacy space version is not supported');
333
371
  }
@@ -345,7 +383,7 @@ export class DataSpaceManager extends Resource {
345
383
  // TODO(dmaretskyi): Better API for low-level data access.
346
384
  const properties: ObjectStructure = {
347
385
  system: {
348
- type: encodeReference(getTypeReference(PropertiesType)!),
386
+ type: EncodedReference.fromDXN(getSchemaDXN(SpaceProperties)!),
349
387
  },
350
388
  data: {
351
389
  [DEFAULT_SPACE_KEY]: this._signingContext.identityKey.toHex(),
@@ -367,7 +405,9 @@ export class DataSpaceManager extends Resource {
367
405
  private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<DatabaseDirectory>> {
368
406
  const automergeIndex = space.automergeSpaceState.rootUrl;
369
407
  invariant(automergeIndex);
370
- const document = await this._echoHost.automergeRepo.find<DatabaseDirectory>(automergeIndex as any, FIND_PARAMS);
408
+ const document = await this._echoHost.loadDoc<DatabaseDirectory>(Context.default(), automergeIndex as any, {
409
+ fetchFromNetwork: true,
410
+ });
371
411
  await document.whenReady();
372
412
  return document;
373
413
  }
@@ -479,8 +519,8 @@ export class DataSpaceManager extends Resource {
479
519
  localPeerId: this._signingContext.deviceKey,
480
520
  });
481
521
  const presence = new Presence({
482
- announceInterval: this._runtimeParams?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,
483
- offlineTimeout: this._runtimeParams?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,
522
+ announceInterval: this._runtimeProps?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,
523
+ offlineTimeout: this._runtimeProps?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,
484
524
  identityKey: this._signingContext.identityKey,
485
525
  gossip,
486
526
  });
@@ -566,7 +606,7 @@ export class DataSpaceManager extends Resource {
566
606
  edgeConnection: this._edgeConnection,
567
607
  edgeHttpClient: this._edgeHttpClient,
568
608
  edgeFeatures: this._edgeFeatures,
569
- activeEdgeNotarizationPollingInterval: this._runtimeParams?.activeEdgeNotarizationPollingInterval,
609
+ activeEdgeNotarizationPollingInterval: this._runtimeProps?.activeEdgeNotarizationPollingInterval,
570
610
  });
571
611
  dataSpace.postOpen.append(async () => {
572
612
  const setting = dataSpace.getEdgeReplicationSetting();