@dxos/client-services 0.8.4-main.c1de068 → 0.8.4-main.c85a9c8dae

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 (207) hide show
  1. package/dist/lib/browser/{chunk-Q7DAO5CH.mjs → chunk-MQ6PWJ76.mjs} +3614 -3438
  2. package/dist/lib/browser/chunk-MQ6PWJ76.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 +471 -77
  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-LBKPPVZO.mjs → chunk-GUAL4U7S.mjs} +3573 -3265
  23. package/dist/lib/node-esm/chunk-GUAL4U7S.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 +471 -77
  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/invitation-guest-extenstion.d.ts.map +1 -1
  75. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  76. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +3 -4
  77. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
  79. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  80. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  81. package/dist/types/src/packlets/invitations/invitations-service.d.ts +1 -1
  82. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  83. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +3 -3
  84. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  85. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  86. package/dist/types/src/packlets/locks/index.d.ts +1 -1
  87. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  88. package/dist/types/src/packlets/logging/logging-service.d.ts +5 -1
  89. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  90. package/dist/types/src/packlets/network/network-service.d.ts +2 -2
  91. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  92. package/dist/types/src/packlets/services/client-rpc-server.d.ts +2 -2
  93. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  94. package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
  95. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  96. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  97. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  98. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  99. package/dist/types/src/packlets/services/service-context.d.ts +13 -8
  100. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  101. package/dist/types/src/packlets/services/service-host.d.ts +19 -5
  102. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  103. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +1 -1
  104. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  105. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts +1 -1
  106. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  107. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +12 -7
  108. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  109. package/dist/types/src/packlets/spaces/data-space.d.ts +6 -6
  110. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  111. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  112. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  113. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -6
  114. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  115. package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -2
  116. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  117. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  118. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  119. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  120. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  121. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  122. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  123. package/dist/types/src/packlets/testing/test-builder.d.ts +8 -7
  124. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  125. package/dist/types/src/packlets/worker/worker-runtime.d.ts +31 -4
  126. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  127. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -2
  128. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  129. package/dist/types/src/version.d.ts +1 -1
  130. package/dist/types/src/version.d.ts.map +1 -1
  131. package/dist/types/tsconfig.tsbuildinfo +1 -1
  132. package/package.json +72 -48
  133. package/src/packlets/agents/edge-agent-manager.ts +2 -2
  134. package/src/packlets/agents/edge-agent-service.ts +13 -3
  135. package/src/packlets/devices/devices-service.test.ts +4 -3
  136. package/src/packlets/devices/devices-service.ts +2 -2
  137. package/src/packlets/devtools/devtools.ts +30 -29
  138. package/src/packlets/devtools/feeds.ts +2 -2
  139. package/src/packlets/devtools/network.ts +1 -1
  140. package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +1 -1
  141. package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -1
  142. package/src/packlets/diagnostics/diagnostics-collector.ts +1 -1
  143. package/src/packlets/diagnostics/diagnostics.ts +1 -1
  144. package/src/packlets/diagnostics/index.ts +1 -1
  145. package/src/packlets/identity/authenticator.node.test.ts +1 -1
  146. package/src/packlets/identity/authenticator.ts +3 -3
  147. package/src/packlets/identity/contacts-service.ts +3 -2
  148. package/src/packlets/identity/default-space-state-machine.ts +3 -3
  149. package/src/packlets/identity/identity-manager.test.ts +3 -3
  150. package/src/packlets/identity/identity-manager.ts +9 -9
  151. package/src/packlets/identity/identity-recovery-manager.ts +2 -2
  152. package/src/packlets/identity/identity-service.test.ts +3 -2
  153. package/src/packlets/identity/identity-service.ts +2 -1
  154. package/src/packlets/identity/identity.test.ts +9 -9
  155. package/src/packlets/identity/identity.ts +9 -8
  156. package/src/packlets/invitations/device-invitation-protocol.test.ts +1 -1
  157. package/src/packlets/invitations/device-invitation-protocol.ts +6 -5
  158. package/src/packlets/invitations/edge-invitation-handler.ts +1 -1
  159. package/src/packlets/invitations/invitation-guest-extenstion.ts +7 -5
  160. package/src/packlets/invitations/invitation-host-extension.ts +8 -6
  161. package/src/packlets/invitations/invitation-protocol.ts +3 -4
  162. package/src/packlets/invitations/invitations-handler.test.ts +4 -3
  163. package/src/packlets/invitations/invitations-handler.ts +10 -10
  164. package/src/packlets/invitations/invitations-manager.ts +3 -3
  165. package/src/packlets/invitations/invitations-service.ts +1 -1
  166. package/src/packlets/invitations/space-invitation-protocol.test.ts +2 -2
  167. package/src/packlets/invitations/space-invitation-protocol.ts +10 -15
  168. package/src/packlets/invitations/utils.ts +1 -1
  169. package/src/packlets/locks/browser.ts +1 -1
  170. package/src/packlets/locks/index.ts +1 -1
  171. package/src/packlets/logging/logging-service.ts +7 -3
  172. package/src/packlets/logging/logging.test.ts +1 -1
  173. package/src/packlets/network/network-service.test.ts +4 -3
  174. package/src/packlets/network/network-service.ts +2 -2
  175. package/src/packlets/services/client-rpc-server.ts +5 -5
  176. package/src/packlets/services/feed-syncer.test.ts +340 -0
  177. package/src/packlets/services/feed-syncer.ts +330 -0
  178. package/src/packlets/services/platform.ts +7 -1
  179. package/src/packlets/services/service-context.test.ts +1 -1
  180. package/src/packlets/services/service-context.ts +62 -29
  181. package/src/packlets/services/service-host.test.ts +3 -2
  182. package/src/packlets/services/service-host.ts +69 -24
  183. package/src/packlets/services/service-registry.test.ts +2 -1
  184. package/src/packlets/space-export/space-archive-reader.ts +2 -2
  185. package/src/packlets/space-export/space-archive-writer.ts +7 -5
  186. package/src/packlets/space-export/tar.test.ts +1 -1
  187. package/src/packlets/spaces/automerge-space-state.ts +1 -1
  188. package/src/packlets/spaces/data-space-manager.ts +76 -36
  189. package/src/packlets/spaces/data-space.ts +18 -13
  190. package/src/packlets/spaces/edge-feed-replicator.test.ts +3 -3
  191. package/src/packlets/spaces/edge-feed-replicator.ts +4 -4
  192. package/src/packlets/spaces/epoch-migrations.ts +2 -2
  193. package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
  194. package/src/packlets/spaces/notarization-plugin.ts +11 -11
  195. package/src/packlets/spaces/spaces-service.test.ts +3 -2
  196. package/src/packlets/spaces/spaces-service.ts +27 -23
  197. package/src/packlets/storage/profile-archive.ts +1 -1
  198. package/src/packlets/storage/storage.ts +7 -8
  199. package/src/packlets/system/system-service.test.ts +1 -1
  200. package/src/packlets/system/system-service.ts +4 -4
  201. package/src/packlets/testing/invitation-utils.ts +8 -5
  202. package/src/packlets/testing/test-builder.ts +39 -13
  203. package/src/packlets/worker/worker-runtime.ts +151 -12
  204. package/src/packlets/worker/worker-session.ts +11 -11
  205. package/src/version.ts +1 -1
  206. package/dist/lib/browser/chunk-Q7DAO5CH.mjs.map +0 -7
  207. package/dist/lib/node-esm/chunk-LBKPPVZO.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 = {
@@ -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 });
@@ -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,8 +252,9 @@ 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');
@@ -289,7 +326,8 @@ export class ClientServicesHost {
289
326
  this._signalManager,
290
327
  this._edgeConnection,
291
328
  this._edgeHttpClient,
292
- this._runtimeParams,
329
+ this._runtime,
330
+ this._runtimeProps,
293
331
  this._config.get('runtime.client.edgeFeatures'),
294
332
  );
295
333
 
@@ -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,
@@ -406,6 +445,12 @@ export class ClientServicesHost {
406
445
  this._resetting = true;
407
446
  this._statusUpdate.emit();
408
447
  await this._serviceContext?.close();
448
+ // Clear LevelDB contents to remove all persisted Echo/Automerge/index data.
449
+ try {
450
+ await this._level!.clear();
451
+ } catch (err) {
452
+ log.warn('failed to clear leveldb during reset', { err });
453
+ }
409
454
  await this._storage!.reset();
410
455
  log.info('reset');
411
456
  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();