@dxos/client-services 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (230) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  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-KPYVJG6G.mjs → chunk-TUCJORVO.mjs} +2153 -3654
  6. package/dist/lib/browser/chunk-TUCJORVO.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-XJRPB3GA.mjs +22 -0
  8. package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +424 -137
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
  13. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  14. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  15. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  16. package/dist/lib/browser/packlets/locks/browser.mjs +86 -0
  17. package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
  18. package/dist/lib/browser/packlets/locks/node.mjs +48 -0
  19. package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
  20. package/dist/lib/browser/testing/index.mjs +28 -29
  21. package/dist/lib/browser/testing/index.mjs.map +3 -3
  22. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +22 -0
  23. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +7 -0
  24. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
  25. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
  26. package/dist/lib/node-esm/{chunk-BBBSS6UL.mjs → chunk-IQLAKNSR.mjs} +2099 -3469
  27. package/dist/lib/node-esm/chunk-IQLAKNSR.mjs.map +7 -0
  28. package/dist/lib/node-esm/index.mjs +424 -137
  29. package/dist/lib/node-esm/index.mjs.map +4 -4
  30. package/dist/lib/node-esm/meta.json +1 -1
  31. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
  32. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  33. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  34. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  35. package/dist/lib/node-esm/packlets/locks/browser.mjs +86 -0
  36. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
  37. package/dist/lib/node-esm/packlets/locks/node.mjs +48 -0
  38. package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
  39. package/dist/lib/node-esm/testing/index.mjs +28 -29
  40. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  41. package/dist/types/src/index.d.ts +1 -0
  42. package/dist/types/src/index.d.ts.map +1 -1
  43. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
  44. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  45. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
  46. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  47. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  48. package/dist/types/src/packlets/devtools/devtools.d.ts +2 -2
  49. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  50. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  51. package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
  52. package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
  53. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  54. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  55. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  56. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  57. package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
  58. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
  59. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  60. package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
  61. package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
  62. package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
  63. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  64. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  65. package/dist/types/src/packlets/identity/identity-manager.d.ts +6 -6
  66. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  67. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +8 -7
  68. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  69. package/dist/types/src/packlets/identity/identity-service.d.ts +6 -10
  70. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  71. package/dist/types/src/packlets/identity/identity.d.ts +8 -11
  72. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  73. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +6 -5
  74. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  75. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
  76. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  77. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  79. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +7 -4
  80. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  81. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
  82. package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
  83. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
  84. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  85. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
  86. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  87. package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
  88. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  89. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +4 -3
  90. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  91. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  92. package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
  93. package/dist/types/src/packlets/locks/index.d.ts +1 -1
  94. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  95. package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
  96. package/dist/types/src/packlets/logging/logging-service.d.ts +4 -0
  97. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  98. package/dist/types/src/packlets/network/network-service.d.ts +5 -4
  99. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  100. package/dist/types/src/packlets/services/client-rpc-server.d.ts +5 -5
  101. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  102. package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
  103. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  104. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  105. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  106. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  107. package/dist/types/src/packlets/services/service-context.d.ts +13 -9
  108. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  109. package/dist/types/src/packlets/services/service-host.d.ts +20 -7
  110. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  111. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  112. package/dist/types/src/packlets/services/util.d.ts.map +1 -1
  113. package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
  114. package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
  115. package/dist/types/src/packlets/space-export/index.d.ts +4 -1
  116. package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
  117. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
  118. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
  119. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
  120. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
  121. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  122. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  123. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
  124. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  125. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  126. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  127. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  128. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +30 -19
  129. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  130. package/dist/types/src/packlets/spaces/data-space.d.ts +26 -9
  131. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  132. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  133. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  134. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
  135. package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
  136. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  137. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -9
  138. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  139. package/dist/types/src/packlets/spaces/spaces-service.d.ts +10 -7
  140. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  141. package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
  142. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  143. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  144. package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
  145. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  146. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  147. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
  148. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  149. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  150. package/dist/types/src/packlets/testing/test-builder.d.ts +6 -5
  151. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  152. package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -4
  153. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  154. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -4
  155. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  156. package/dist/types/src/testing/setup.d.ts.map +1 -1
  157. package/dist/types/src/version.d.ts +1 -1
  158. package/dist/types/src/version.d.ts.map +1 -1
  159. package/dist/types/tsconfig.tsbuildinfo +1 -1
  160. package/package.json +71 -56
  161. package/src/index.ts +1 -0
  162. package/src/packlets/agents/edge-agent-manager.ts +8 -5
  163. package/src/packlets/agents/edge-agent-service.ts +4 -2
  164. package/src/packlets/devices/devices-service.test.ts +0 -1
  165. package/src/packlets/devtools/devtools.ts +2 -3
  166. package/src/packlets/diagnostics/diagnostics.ts +1 -2
  167. package/src/packlets/diagnostics/index.ts +1 -1
  168. package/src/packlets/identity/authenticator.ts +2 -2
  169. package/src/packlets/identity/contacts-service.ts +0 -1
  170. package/src/packlets/identity/identity-manager.test.ts +5 -5
  171. package/src/packlets/identity/identity-manager.ts +23 -22
  172. package/src/packlets/identity/identity-recovery-manager.ts +22 -18
  173. package/src/packlets/identity/identity-service.test.ts +6 -27
  174. package/src/packlets/identity/identity-service.ts +13 -81
  175. package/src/packlets/identity/identity.test.ts +2 -2
  176. package/src/packlets/identity/identity.ts +11 -34
  177. package/src/packlets/invitations/device-invitation-protocol.ts +8 -7
  178. package/src/packlets/invitations/edge-invitation-handler.ts +9 -5
  179. package/src/packlets/invitations/invitation-guest-extenstion.ts +6 -4
  180. package/src/packlets/invitations/invitation-host-extension.ts +13 -14
  181. package/src/packlets/invitations/invitation-protocol.ts +7 -4
  182. package/src/packlets/invitations/invitation-state.ts +1 -15
  183. package/src/packlets/invitations/invitations-handler.test.ts +4 -5
  184. package/src/packlets/invitations/invitations-handler.ts +74 -22
  185. package/src/packlets/invitations/invitations-manager.ts +40 -15
  186. package/src/packlets/invitations/invitations-service.ts +9 -9
  187. package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
  188. package/src/packlets/invitations/space-invitation-protocol.ts +11 -16
  189. package/src/packlets/locks/index.ts +1 -1
  190. package/src/packlets/logging/logging-service.ts +20 -16
  191. package/src/packlets/network/network-service.test.ts +0 -1
  192. package/src/packlets/network/network-service.ts +10 -8
  193. package/src/packlets/services/client-rpc-server.ts +19 -16
  194. package/src/packlets/services/feed-syncer.test.ts +340 -0
  195. package/src/packlets/services/feed-syncer.ts +377 -0
  196. package/src/packlets/services/platform.ts +7 -1
  197. package/src/packlets/services/service-context.test.ts +3 -2
  198. package/src/packlets/services/service-context.ts +153 -61
  199. package/src/packlets/services/service-host.test.ts +8 -8
  200. package/src/packlets/services/service-host.ts +70 -40
  201. package/src/packlets/services/service-registry.test.ts +0 -1
  202. package/src/packlets/space-export/archive-format.ts +42 -0
  203. package/src/packlets/space-export/index.ts +4 -1
  204. package/src/packlets/space-export/serialized-space-reader.ts +111 -0
  205. package/src/packlets/space-export/serialized-space-writer.ts +252 -0
  206. package/src/packlets/space-export/space-archive-reader.ts +64 -3
  207. package/src/packlets/space-export/space-archive-writer.ts +41 -3
  208. package/src/packlets/space-export/space-archive.test.ts +461 -0
  209. package/src/packlets/spaces/data-space-manager.test.ts +79 -13
  210. package/src/packlets/spaces/data-space-manager.ts +108 -120
  211. package/src/packlets/spaces/data-space.ts +64 -36
  212. package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
  213. package/src/packlets/spaces/edge-feed-replicator.ts +11 -9
  214. package/src/packlets/spaces/epoch-migrations.ts +6 -5
  215. package/src/packlets/spaces/genesis.ts +6 -1
  216. package/src/packlets/spaces/notarization-plugin.test.ts +2 -2
  217. package/src/packlets/spaces/notarization-plugin.ts +10 -9
  218. package/src/packlets/spaces/spaces-service.test.ts +18 -11
  219. package/src/packlets/spaces/spaces-service.ts +124 -24
  220. package/src/packlets/storage/storage.ts +4 -4
  221. package/src/packlets/testing/invitation-utils.ts +10 -6
  222. package/src/packlets/testing/test-builder.ts +36 -10
  223. package/src/packlets/worker/worker-runtime.ts +188 -17
  224. package/src/packlets/worker/worker-session.ts +12 -18
  225. package/src/version.ts +1 -1
  226. package/dist/lib/browser/chunk-KPYVJG6G.mjs.map +0 -7
  227. package/dist/lib/node-esm/chunk-BBBSS6UL.mjs.map +0 -7
  228. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  229. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  230. package/src/packlets/identity/default-space-state-machine.ts +0 -44
@@ -3,10 +3,10 @@
3
3
  //
4
4
 
5
5
  import { type Doc } from '@automerge/automerge';
6
- import { type AutomergeUrl, type DocHandle, type DocumentId, interpretAsDocumentId } from '@automerge/automerge-repo';
6
+ import { type AutomergeUrl, 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
12
  type CredentialSigner,
@@ -15,14 +15,13 @@ import {
15
15
  createAdmissionCredentials,
16
16
  getCredentialAssertion,
17
17
  } from '@dxos/credentials';
18
- import { ObjectId, getTypeReference } from '@dxos/echo/internal';
18
+ import { Type } from '@dxos/echo';
19
19
  import {
20
20
  AuthStatus,
21
21
  CredentialServerExtension,
22
22
  DatabaseRoot,
23
- type EchoEdgeReplicator,
24
23
  type EchoHost,
25
- FIND_PARAMS,
24
+ type EdgeAutomergeReplicator,
26
25
  type MeshEchoReplicator,
27
26
  type MetadataStore,
28
27
  type Space,
@@ -31,45 +30,40 @@ import {
31
30
  type SpaceProtocolSession,
32
31
  findInlineObjectOfType,
33
32
  } from '@dxos/echo-pipeline';
34
- import {
35
- type DatabaseDirectory,
36
- type ObjectStructure,
37
- SpaceDocVersion,
38
- createIdFromSpaceKey,
39
- encodeReference,
40
- } from '@dxos/echo-protocol';
33
+ import { type DatabaseDirectory, createIdFromSpaceKey } from '@dxos/echo-protocol';
41
34
  import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
42
35
  import { type FeedStore, writeMessages } from '@dxos/feed-store';
43
36
  import { assertArgument, assertState, failedInvariant, invariant } from '@dxos/invariant';
44
37
  import { type Keyring } from '@dxos/keyring';
45
38
  import { PublicKey, type SpaceId } from '@dxos/keys';
46
39
  import { log } from '@dxos/log';
47
- import { AlreadyJoinedError, trace as Trace } from '@dxos/protocols';
40
+ import { AlreadyJoinedError } from '@dxos/protocols';
48
41
  import { Invitation, SpaceState } from '@dxos/protocols/proto/dxos/client/services';
49
42
  import { type Runtime } from '@dxos/protocols/proto/dxos/config';
50
43
  import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
51
44
  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';
45
+ import {
46
+ type Credential,
47
+ MembershipPolicy,
48
+ type ProfileDocument,
49
+ SpaceMember,
50
+ } from '@dxos/protocols/proto/dxos/halo/credentials';
53
51
  import { type DelegateSpaceInvitation } from '@dxos/protocols/proto/dxos/halo/invitations';
54
52
  import { type PeerState } from '@dxos/protocols/proto/dxos/mesh/presence';
55
53
  import { type Teleport } from '@dxos/teleport';
56
54
  import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
57
55
  import { type Timeframe } from '@dxos/timeframe';
58
56
  import { trace } from '@dxos/tracing';
59
- import { ComplexMap, deferFunction, forEachAsync, setDeep } from '@dxos/util';
57
+ import { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';
60
58
 
61
59
  import { createAuthProvider } from '../identity';
62
60
  import { type InvitationsManager } from '../invitations';
63
-
64
61
  import { DataSpace } from './data-space';
65
62
  import { spaceGenesis } from './genesis';
66
63
 
67
64
  const PRESENCE_ANNOUNCE_INTERVAL = 10_000;
68
65
  const PRESENCE_OFFLINE_TIMEOUT = 20_000;
69
66
 
70
- // Space properties key for default metadata.
71
- const DEFAULT_SPACE_KEY = '__DEFAULT__';
72
-
73
67
  export interface SigningContext {
74
68
  identityKey: PublicKey;
75
69
  deviceKey: PublicKey;
@@ -94,6 +88,9 @@ export type AcceptSpaceOptions = {
94
88
  * We will try to catch up to this timeframe before initializing the database.
95
89
  */
96
90
  dataTimeframe?: Timeframe;
91
+
92
+ /** Tags assigned to the space member. */
93
+ tags?: string[];
97
94
  };
98
95
 
99
96
  export type AdmitMemberOptions = {
@@ -102,9 +99,10 @@ export type AdmitMemberOptions = {
102
99
  role: SpaceMember.Role;
103
100
  profile?: ProfileDocument;
104
101
  delegationCredentialId?: PublicKey;
102
+ tags?: string[];
105
103
  };
106
104
 
107
- export type DataSpaceManagerParams = {
105
+ export type DataSpaceManagerProps = {
108
106
  spaceManager: SpaceManager;
109
107
  metadataStore: MetadataStore;
110
108
  keyring: Keyring;
@@ -115,31 +113,37 @@ export type DataSpaceManagerParams = {
115
113
  edgeConnection?: EdgeConnection;
116
114
  edgeHttpClient?: EdgeHttpClient;
117
115
  meshReplicator?: MeshEchoReplicator;
118
- echoEdgeReplicator?: EchoEdgeReplicator;
119
- runtimeParams?: DataSpaceManagerRuntimeParams;
116
+ echoEdgeReplicator?: EdgeAutomergeReplicator;
117
+ runtimeProps?: DataSpaceManagerRuntimeProps;
120
118
  edgeFeatures?: Runtime.Client.EdgeFeatures;
121
119
  };
122
120
 
123
- export type DataSpaceManagerRuntimeParams = {
121
+ export type DataSpaceManagerRuntimeProps = {
124
122
  spaceMemberPresenceAnnounceInterval?: number;
125
123
  spaceMemberPresenceOfflineTimeout?: number;
126
124
  activeEdgeNotarizationPollingInterval?: number;
127
125
  disableP2pReplication?: boolean;
126
+ /**
127
+ * If true, spaces that were previously SPACE_ACTIVE will be automatically activated on startup.
128
+ * This is used in dedicated worker mode to restore space state after leader changeover.
129
+ */
130
+ autoActivateSpaces?: boolean;
128
131
  };
129
132
 
130
133
  export type CreateSpaceOptions = {
131
134
  rootUrl?: AutomergeUrl;
132
135
  documents?: Record<DocumentId, Uint8Array>;
136
+ tags?: string[];
137
+ membershipPolicy?: MembershipPolicy;
133
138
  };
134
139
 
135
140
  @trackLeaks('open', 'close')
141
+ @trace.resource({ lifecycle: true })
136
142
  export class DataSpaceManager extends Resource {
137
143
  public readonly updated = new Event();
138
144
 
139
145
  private readonly _spaces = new ComplexMap<PublicKey, DataSpace>(PublicKey.hash);
140
146
 
141
- private readonly _instanceId = PublicKey.random().toHex();
142
-
143
147
  private readonly _spaceManager: SpaceManager;
144
148
  private readonly _metadataStore: MetadataStore;
145
149
  private readonly _keyring: Keyring;
@@ -151,10 +155,10 @@ export class DataSpaceManager extends Resource {
151
155
  private readonly _edgeHttpClient?: EdgeHttpClient = undefined;
152
156
  private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures = undefined;
153
157
  private readonly _meshReplicator?: MeshEchoReplicator = undefined;
154
- private readonly _echoEdgeReplicator?: EchoEdgeReplicator = undefined;
155
- private readonly _runtimeParams?: DataSpaceManagerRuntimeParams = undefined;
158
+ private readonly _echoEdgeReplicator?: EdgeAutomergeReplicator = undefined;
159
+ private readonly _runtimeProps?: DataSpaceManagerRuntimeProps = undefined;
156
160
 
157
- constructor(params: DataSpaceManagerParams) {
161
+ constructor(params: DataSpaceManagerProps) {
158
162
  super();
159
163
 
160
164
  this._spaceManager = params.spaceManager;
@@ -169,7 +173,7 @@ export class DataSpaceManager extends Resource {
169
173
  this._edgeFeatures = params.edgeFeatures;
170
174
  this._echoEdgeReplicator = params.echoEdgeReplicator;
171
175
  this._edgeHttpClient = params.edgeHttpClient;
172
- this._runtimeParams = params.runtimeParams;
176
+ this._runtimeProps = params.runtimeProps;
173
177
 
174
178
  trace.diagnostic({
175
179
  id: 'spaces',
@@ -179,12 +183,11 @@ export class DataSpaceManager extends Resource {
179
183
  Array.from(this._spaces.values()).map(async (space) => {
180
184
  const rootUrl = space.automergeSpaceState.rootUrl;
181
185
  const rootHandle = rootUrl
182
- ? await this._echoHost.automergeRepo.find<Doc<DatabaseDirectory>>(rootUrl as AutomergeUrl, FIND_PARAMS)
186
+ ? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(this._ctx, rootUrl as AutomergeUrl)
183
187
  : undefined;
184
- await rootHandle?.whenReady();
185
188
  const rootDoc = rootHandle?.doc();
186
189
 
187
- const properties = rootDoc && findInlineObjectOfType(rootDoc, TYPE_PROPERTIES);
190
+ const properties = rootDoc && findInlineObjectOfType(rootDoc, Type.getTypename(SpaceProperties));
188
191
 
189
192
  return {
190
193
  key: space.key.toHex(),
@@ -212,30 +215,41 @@ export class DataSpaceManager extends Resource {
212
215
  }
213
216
 
214
217
  @synchronized
215
- protected override async _open(): Promise<void> {
218
+ @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
219
+ protected override async _open(ctx: Context): Promise<void> {
216
220
  log('open');
217
- log.trace('dxos.echo.data-space-manager.open', Trace.begin({ id: this._instanceId }));
218
221
  log('metadata loaded', { spaces: this._metadataStore.spaces.length });
219
222
 
223
+ const spacesToActivate: DataSpace[] = [];
220
224
  await forEachAsync(this._metadataStore.spaces, async (spaceMetadata) => {
221
225
  try {
222
226
  log('load space', { spaceMetadata });
223
- await this._constructSpace(spaceMetadata);
227
+ const space = await this._constructSpace(ctx, spaceMetadata);
228
+ // Track spaces that were previously active for auto-activation (used in dedicated worker mode).
229
+ if (this._runtimeProps?.autoActivateSpaces && spaceMetadata.state === SpaceState.SPACE_ACTIVE) {
230
+ spacesToActivate.push(space);
231
+ }
224
232
  } catch (err) {
225
233
  log.error('Error loading space', { spaceMetadata, err });
226
234
  }
227
235
  });
228
236
 
229
- this.updated.emit();
237
+ // Auto-activate spaces that were previously active (used in dedicated worker mode after leader changeover).
238
+ for (const space of spacesToActivate) {
239
+ log('auto-activating space', { spaceKey: space.key });
240
+ space.activate(ctx).catch((err) => {
241
+ log.error('Error auto-activating space', { spaceKey: space.key, err });
242
+ });
243
+ }
230
244
 
231
- log.trace('dxos.echo.data-space-manager.open', Trace.end({ id: this._instanceId }));
245
+ this.updated.emit();
232
246
  }
233
247
 
234
248
  @synchronized
235
- protected override async _close(): Promise<void> {
249
+ protected override async _close(ctx: Context): Promise<void> {
236
250
  log('close');
237
251
  for (const space of this._spaces.values()) {
238
- await space.close();
252
+ await space.close(ctx);
239
253
  }
240
254
  this._spaces.clear();
241
255
  }
@@ -244,7 +258,8 @@ export class DataSpaceManager extends Resource {
244
258
  * Creates a new space writing the genesis credentials to the control feed.
245
259
  */
246
260
  @synchronized
247
- async createSpace(options: CreateSpaceOptions = {}): Promise<DataSpace> {
261
+ @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
262
+ async createSpace(ctx: Context, options: CreateSpaceOptions = {}): Promise<DataSpace> {
248
263
  assertArgument(
249
264
  !!options.rootUrl === !!options.documents,
250
265
  'options',
@@ -252,6 +267,8 @@ export class DataSpaceManager extends Resource {
252
267
  );
253
268
 
254
269
  assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
270
+
271
+ const tags = options.tags ? Array.from(options.tags) : [];
255
272
  const spaceKey = await this._keyring.createKey();
256
273
  const controlFeedKey = await this._keyring.createKey();
257
274
  const dataFeedKey = await this._keyring.createKey();
@@ -264,6 +281,7 @@ export class DataSpaceManager extends Resource {
264
281
  controlFeedKey,
265
282
  dataFeedKey,
266
283
  state: SpaceState.SPACE_ACTIVE,
284
+ tags,
267
285
  };
268
286
 
269
287
  log('creating space...', { spaceId, spaceKey });
@@ -301,30 +319,38 @@ export class DataSpaceManager extends Resource {
301
319
  let root: DatabaseRoot;
302
320
  if (options.rootUrl) {
303
321
  const newRootDocId = documentIdMapping[interpretAsDocumentId(options.rootUrl)] ?? failedInvariant();
304
- const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(Context.default(), newRootDocId);
322
+ const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(ctx, newRootDocId);
323
+ invariant(rootDocHandle, 'Root document must be available after import.');
305
324
  DatabaseRoot.mapLinks(rootDocHandle, documentIdMapping);
306
325
 
307
- root = await this._echoHost.openSpaceRoot(spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
326
+ root = await this._echoHost.openSpaceRoot(ctx, spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
308
327
  } else {
309
- root = await this._echoHost.createSpaceRoot(spaceKey);
328
+ root = await this._echoHost.createSpaceRoot(ctx, spaceKey);
310
329
  }
311
- await this._echoHost.flush();
330
+ await this._echoHost.flush(ctx);
312
331
 
313
332
  log('constructing space...', { spaceKey });
314
333
 
315
- const space = await this._constructSpace(metadata);
316
- await space.open();
334
+ const space = await this._constructSpace(ctx, metadata);
335
+ await space.open(ctx);
317
336
 
318
337
  log('adding space...', { spaceKey });
319
338
 
320
- const credentials = await spaceGenesis(this._keyring, this._signingContext, space.inner, root.url);
339
+ const credentials = await spaceGenesis(
340
+ this._keyring,
341
+ this._signingContext,
342
+ space.inner,
343
+ root.url,
344
+ tags,
345
+ options.membershipPolicy,
346
+ );
321
347
  await this._metadataStore.addSpace(metadata);
322
348
 
323
349
  const memberCredential = credentials[1];
324
350
  invariant(getCredentialAssertion(memberCredential)['@type'] === 'dxos.halo.credentials.SpaceMember');
325
351
  await this._signingContext.recordCredential(memberCredential);
326
352
 
327
- await space.initializeDataPipeline();
353
+ await space.initializeDataPipeline(ctx);
328
354
 
329
355
  log('space ready.', { spaceId, spaceKey });
330
356
 
@@ -332,81 +358,36 @@ export class DataSpaceManager extends Resource {
332
358
  return space;
333
359
  }
334
360
 
335
- async isDefaultSpace(space: DataSpace): Promise<boolean> {
336
- if (!space.databaseRoot) {
337
- return false;
338
- }
339
- switch (space.databaseRoot.getVersion()) {
340
- case SpaceDocVersion.CURRENT: {
341
- if (!space.databaseRoot.handle.isReady()) {
342
- log.warn('waiting for space root to be ready', { spaceId: space.id });
343
- await space.databaseRoot.handle.whenReady();
344
- }
345
- const [_, properties] = findInlineObjectOfType(space.databaseRoot.doc()!, TYPE_PROPERTIES) ?? [];
346
- return properties?.data?.[DEFAULT_SPACE_KEY] === this._signingContext.identityKey.toHex();
347
- }
348
- case SpaceDocVersion.LEGACY: {
349
- throw new Error('Legacy space version is not supported');
350
- }
351
-
352
- default:
353
- log.warn('unknown space version', { version: space.databaseRoot.getVersion(), spaceId: space.id });
354
- return false;
355
- }
356
- }
357
-
358
- async createDefaultSpace(): Promise<DataSpace> {
359
- const space = await this.createSpace();
360
- const document = await this._getSpaceRootDocument(space);
361
-
362
- // TODO(dmaretskyi): Better API for low-level data access.
363
- const properties: ObjectStructure = {
364
- system: {
365
- type: encodeReference(getTypeReference(PropertiesType)!),
366
- },
367
- data: {
368
- [DEFAULT_SPACE_KEY]: this._signingContext.identityKey.toHex(),
369
- },
370
- meta: {
371
- keys: [],
372
- },
373
- };
374
-
375
- const propertiesId = ObjectId.random();
376
- document.change((doc: DatabaseDirectory) => {
377
- setDeep(doc, ['objects', propertiesId], properties);
378
- });
379
-
380
- await this._echoHost.flush();
381
- return space;
382
- }
383
-
384
- private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<DatabaseDirectory>> {
385
- const automergeIndex = space.automergeSpaceState.rootUrl;
386
- invariant(automergeIndex);
387
- const document = await this._echoHost.automergeRepo.find<DatabaseDirectory>(automergeIndex as any, FIND_PARAMS);
388
- await document.whenReady();
389
- return document;
390
- }
391
-
361
+ /**
362
+ * Accepts an existing space by joining its swarm and initializing the data pipeline.
363
+ * @param ctx - Caller context for cancellation and tracing.
364
+ * @param opts - Space keys and optional timeframes for catch-up.
365
+ */
392
366
  // TODO(burdon): Rename join space.
393
367
  @synchronized
394
- async acceptSpace(opts: AcceptSpaceOptions): Promise<DataSpace> {
368
+ @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
369
+ async acceptSpace(ctx: Context, opts: AcceptSpaceOptions): Promise<DataSpace> {
395
370
  log('accept space', { opts });
396
371
  invariant(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
397
372
  invariant(!this._spaces.has(opts.spaceKey), 'Space already exists.');
398
373
 
374
+ const tags = opts.tags ? Array.from(opts.tags) : [];
399
375
  const metadata: SpaceMetadata = {
400
376
  key: opts.spaceKey,
401
377
  genesisFeedKey: opts.genesisFeedKey,
402
378
  controlTimeframe: opts.controlTimeframe,
403
379
  dataTimeframe: opts.dataTimeframe,
380
+ tags,
404
381
  };
405
382
 
406
- const space = await this._constructSpace(metadata);
407
- await space.open();
383
+ const space = await this._constructSpace(ctx, metadata);
384
+ await space.open(ctx);
408
385
  await this._metadataStore.addSpace(metadata);
409
- space.initializeDataPipelineAsync();
386
+ // Use DSM lifecycle ctx: the invitation accept flow disposes `ctx` as soon as
387
+ // `acceptSpace` returns (guardedState.complete -> ctx.dispose). Detached data-pipeline
388
+ // initialization must outlive the invitation flow, and its span must be parented to a
389
+ // long-lived context.
390
+ space.initializeDataPipelineAsync(this._ctx);
410
391
 
411
392
  this.updated.emit();
412
393
  return space;
@@ -430,6 +411,7 @@ export class DataSpaceManager extends Resource {
430
411
  space.spaceState.membershipChainHeads,
431
412
  options.profile,
432
413
  options.delegationCredentialId,
414
+ space.spaceState.tags,
433
415
  );
434
416
 
435
417
  // TODO(dmaretskyi): Refactor.
@@ -456,8 +438,8 @@ export class DataSpaceManager extends Resource {
456
438
  );
457
439
  }
458
440
 
459
- public async requestSpaceAdmissionCredential(spaceKey: PublicKey): Promise<Credential> {
460
- return this._spaceManager.requestSpaceAdmissionCredential({
441
+ public async requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential> {
442
+ return this._spaceManager.requestSpaceAdmissionCredential(ctx, {
461
443
  spaceKey,
462
444
  identityKey: this._signingContext.identityKey,
463
445
  timeout: 15_000,
@@ -470,7 +452,11 @@ export class DataSpaceManager extends Resource {
470
452
  });
471
453
  }
472
454
 
473
- async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void> {
455
+ async setSpaceEdgeReplicationSetting(
456
+ ctx: Context,
457
+ spaceKey: PublicKey,
458
+ setting: EdgeReplicationSetting,
459
+ ): Promise<void> {
474
460
  const space = this._spaces.get(spaceKey);
475
461
  invariant(space, 'Space not found.');
476
462
 
@@ -482,7 +468,7 @@ export class DataSpaceManager extends Resource {
482
468
  await this._echoEdgeReplicator?.disconnectFromSpace(space.id);
483
469
  break;
484
470
  case EdgeReplicationSetting.ENABLED:
485
- await this._echoEdgeReplicator?.connectToSpace(space.id);
471
+ await this._echoEdgeReplicator?.connectToSpace(ctx, space.id);
486
472
  break;
487
473
  }
488
474
  }
@@ -490,14 +476,14 @@ export class DataSpaceManager extends Resource {
490
476
  space.stateUpdate.emit();
491
477
  }
492
478
 
493
- private async _constructSpace(metadata: SpaceMetadata): Promise<DataSpace> {
479
+ private async _constructSpace(ctx: Context, metadata: SpaceMetadata): Promise<DataSpace> {
494
480
  log('construct space', { metadata });
495
481
  const gossip = new Gossip({
496
482
  localPeerId: this._signingContext.deviceKey,
497
483
  });
498
484
  const presence = new Presence({
499
- announceInterval: this._runtimeParams?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,
500
- offlineTimeout: this._runtimeParams?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,
485
+ announceInterval: this._runtimeProps?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,
486
+ offlineTimeout: this._runtimeProps?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,
501
487
  identityKey: this._signingContext.identityKey,
502
488
  gossip,
503
489
  });
@@ -580,17 +566,19 @@ export class DataSpaceManager extends Resource {
580
566
  },
581
567
  },
582
568
  cache: metadata.cache,
569
+ tags: metadata.tags,
583
570
  edgeConnection: this._edgeConnection,
584
571
  edgeHttpClient: this._edgeHttpClient,
585
572
  edgeFeatures: this._edgeFeatures,
586
- activeEdgeNotarizationPollingInterval: this._runtimeParams?.activeEdgeNotarizationPollingInterval,
573
+ activeEdgeNotarizationPollingInterval: this._runtimeProps?.activeEdgeNotarizationPollingInterval,
587
574
  });
588
575
  dataSpace.postOpen.append(async () => {
589
576
  const setting = dataSpace.getEdgeReplicationSetting();
590
577
  if (!setting || setting === EdgeReplicationSetting.ENABLED) {
591
- await this._echoEdgeReplicator?.connectToSpace(dataSpace.id);
578
+ // Use lifecycle ctx: the caller ctx from _constructSpace may be disposed by the time postOpen fires.
579
+ await this._echoEdgeReplicator?.connectToSpace(this._ctx, dataSpace.id);
592
580
  } else if (this._echoEdgeReplicator) {
593
- log('not connecting EchoEdgeReplicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
581
+ log('not connecting edge replicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
594
582
  }
595
583
  });
596
584
  dataSpace.preClose.append(async () => {
@@ -685,7 +673,7 @@ export class DataSpaceManager extends Resource {
685
673
  invitations: Array<[PublicKey, DelegateSpaceInvitation]>,
686
674
  ): Promise<void> {
687
675
  const tasks = invitations.map(([credentialId, invitation]) => {
688
- return this._invitationsManager.createInvitation({
676
+ return this._invitationsManager.createInvitation(this._ctx, {
689
677
  type: Invitation.Type.DELEGATED,
690
678
  kind: Invitation.Kind.SPACE,
691
679
  spaceKey: space.key,