@dxos/client-services 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced

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/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/{chunk-FRMIC6UB.mjs → chunk-KBMYCFTL.mjs} +1636 -3392
  4. package/dist/lib/browser/chunk-KBMYCFTL.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-NQSC7HOE.mjs → chunk-XJRPB3GA.mjs} +1 -1
  6. package/dist/lib/browser/index.mjs +106 -194
  7. package/dist/lib/browser/index.mjs.map +3 -3
  8. package/dist/lib/browser/meta.json +1 -1
  9. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +1 -6
  10. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +2 -2
  11. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +1 -1
  12. package/dist/lib/browser/packlets/locks/browser.mjs +9 -49
  13. package/dist/lib/browser/packlets/locks/browser.mjs.map +2 -2
  14. package/dist/lib/browser/packlets/locks/node.mjs +4 -22
  15. package/dist/lib/browser/packlets/locks/node.mjs.map +2 -2
  16. package/dist/lib/browser/testing/index.mjs +9 -22
  17. package/dist/lib/browser/testing/index.mjs.map +3 -3
  18. package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs → chunk-2DT3MZRL.mjs} +1 -1
  19. package/dist/lib/node-esm/{chunk-6ONWVRY5.mjs → chunk-TCS4PMDH.mjs} +1636 -3392
  20. package/dist/lib/node-esm/chunk-TCS4PMDH.mjs.map +7 -0
  21. package/dist/lib/node-esm/index.mjs +106 -194
  22. package/dist/lib/node-esm/index.mjs.map +3 -3
  23. package/dist/lib/node-esm/meta.json +1 -1
  24. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +1 -6
  25. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +2 -2
  26. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +1 -1
  27. package/dist/lib/node-esm/packlets/locks/browser.mjs +9 -49
  28. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +2 -2
  29. package/dist/lib/node-esm/packlets/locks/node.mjs +4 -22
  30. package/dist/lib/node-esm/packlets/locks/node.mjs.map +2 -2
  31. package/dist/lib/node-esm/testing/index.mjs +9 -22
  32. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  33. package/dist/types/src/index.d.ts +1 -0
  34. package/dist/types/src/index.d.ts.map +1 -1
  35. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
  36. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  37. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
  38. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  39. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  40. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  41. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  42. package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
  43. package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
  44. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  45. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  46. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  47. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  48. package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
  49. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
  50. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  51. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  52. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  53. package/dist/types/src/packlets/identity/identity-manager.d.ts +3 -3
  54. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  55. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +6 -5
  56. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  57. package/dist/types/src/packlets/identity/identity-service.d.ts +6 -10
  58. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  59. package/dist/types/src/packlets/identity/identity.d.ts +6 -9
  60. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  61. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +2 -1
  62. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  63. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
  64. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  65. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  66. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  67. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +5 -1
  68. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  69. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
  70. package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
  71. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  72. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
  73. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  74. package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
  75. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  76. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +2 -1
  77. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  79. package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
  80. package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
  81. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  82. package/dist/types/src/packlets/network/network-service.d.ts +5 -4
  83. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  84. package/dist/types/src/packlets/services/client-rpc-server.d.ts +3 -3
  85. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  86. package/dist/types/src/packlets/services/feed-syncer.d.ts +2 -2
  87. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -1
  88. package/dist/types/src/packlets/services/service-context.d.ts +2 -3
  89. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  90. package/dist/types/src/packlets/services/service-host.d.ts +2 -3
  91. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  92. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  93. package/dist/types/src/packlets/services/util.d.ts.map +1 -1
  94. package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
  95. package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
  96. package/dist/types/src/packlets/space-export/index.d.ts +4 -1
  97. package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
  98. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
  99. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
  100. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
  101. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
  102. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  103. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  104. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
  105. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  106. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  107. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  108. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  109. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +20 -14
  110. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  111. package/dist/types/src/packlets/spaces/data-space.d.ts +24 -7
  112. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  113. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  114. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
  115. package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
  116. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  117. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +1 -4
  118. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  119. package/dist/types/src/packlets/spaces/spaces-service.d.ts +10 -7
  120. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  121. package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
  122. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  123. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  124. package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
  125. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  126. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  127. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
  128. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  129. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  130. package/dist/types/src/packlets/worker/worker-runtime.d.ts +11 -1
  131. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  132. package/dist/types/src/packlets/worker/worker-session.d.ts +0 -2
  133. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  134. package/dist/types/src/testing/setup.d.ts.map +1 -1
  135. package/dist/types/src/version.d.ts +1 -1
  136. package/dist/types/tsconfig.tsbuildinfo +1 -1
  137. package/package.json +43 -50
  138. package/src/index.ts +1 -0
  139. package/src/packlets/agents/edge-agent-manager.ts +8 -5
  140. package/src/packlets/agents/edge-agent-service.ts +4 -2
  141. package/src/packlets/devices/devices-service.test.ts +0 -1
  142. package/src/packlets/devtools/devtools.ts +0 -1
  143. package/src/packlets/diagnostics/diagnostics.ts +1 -2
  144. package/src/packlets/identity/contacts-service.ts +0 -1
  145. package/src/packlets/identity/identity-manager.test.ts +5 -5
  146. package/src/packlets/identity/identity-manager.ts +18 -17
  147. package/src/packlets/identity/identity-recovery-manager.ts +20 -16
  148. package/src/packlets/identity/identity-service.test.ts +6 -27
  149. package/src/packlets/identity/identity-service.ts +13 -81
  150. package/src/packlets/identity/identity.test.ts +2 -2
  151. package/src/packlets/identity/identity.ts +9 -32
  152. package/src/packlets/invitations/device-invitation-protocol.ts +3 -2
  153. package/src/packlets/invitations/edge-invitation-handler.ts +9 -5
  154. package/src/packlets/invitations/invitation-host-extension.ts +7 -10
  155. package/src/packlets/invitations/invitation-protocol.ts +5 -1
  156. package/src/packlets/invitations/invitation-state.ts +1 -15
  157. package/src/packlets/invitations/invitations-handler.test.ts +4 -5
  158. package/src/packlets/invitations/invitations-handler.ts +67 -15
  159. package/src/packlets/invitations/invitations-manager.ts +40 -15
  160. package/src/packlets/invitations/invitations-service.ts +9 -9
  161. package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
  162. package/src/packlets/invitations/space-invitation-protocol.ts +4 -3
  163. package/src/packlets/logging/logging-service.ts +15 -15
  164. package/src/packlets/network/network-service.test.ts +0 -1
  165. package/src/packlets/network/network-service.ts +10 -8
  166. package/src/packlets/services/client-rpc-server.ts +15 -12
  167. package/src/packlets/services/feed-syncer.test.ts +3 -3
  168. package/src/packlets/services/feed-syncer.ts +67 -20
  169. package/src/packlets/services/service-context.test.ts +3 -2
  170. package/src/packlets/services/service-context.ts +51 -43
  171. package/src/packlets/services/service-host.test.ts +8 -8
  172. package/src/packlets/services/service-host.ts +12 -24
  173. package/src/packlets/services/service-registry.test.ts +0 -1
  174. package/src/packlets/space-export/archive-format.ts +42 -0
  175. package/src/packlets/space-export/index.ts +4 -1
  176. package/src/packlets/space-export/serialized-space-reader.ts +111 -0
  177. package/src/packlets/space-export/serialized-space-writer.ts +252 -0
  178. package/src/packlets/space-export/space-archive-reader.ts +64 -3
  179. package/src/packlets/space-export/space-archive-writer.ts +38 -2
  180. package/src/packlets/space-export/space-archive.test.ts +461 -0
  181. package/src/packlets/spaces/data-space-manager.test.ts +79 -13
  182. package/src/packlets/spaces/data-space-manager.ts +80 -115
  183. package/src/packlets/spaces/data-space.ts +55 -31
  184. package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
  185. package/src/packlets/spaces/edge-feed-replicator.ts +9 -7
  186. package/src/packlets/spaces/epoch-migrations.ts +4 -3
  187. package/src/packlets/spaces/genesis.ts +6 -1
  188. package/src/packlets/spaces/notarization-plugin.ts +2 -1
  189. package/src/packlets/spaces/spaces-service.test.ts +18 -11
  190. package/src/packlets/spaces/spaces-service.ts +115 -17
  191. package/src/packlets/testing/invitation-utils.ts +3 -2
  192. package/src/packlets/worker/worker-runtime.ts +39 -6
  193. package/src/packlets/worker/worker-session.ts +4 -10
  194. package/src/version.ts +1 -1
  195. package/dist/lib/browser/chunk-FRMIC6UB.mjs.map +0 -7
  196. package/dist/lib/node-esm/chunk-6ONWVRY5.mjs.map +0 -7
  197. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  198. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  199. package/src/packlets/identity/default-space-state-machine.ts +0 -44
  200. /package/dist/lib/browser/{chunk-NQSC7HOE.mjs.map → chunk-XJRPB3GA.mjs.map} +0 -0
  201. /package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs.map → chunk-2DT3MZRL.mjs.map} +0 -0
@@ -3,7 +3,7 @@
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
9
  import { SpaceProperties } from '@dxos/client-protocol';
@@ -16,13 +16,12 @@ import {
16
16
  getCredentialAssertion,
17
17
  } from '@dxos/credentials';
18
18
  import { Type } from '@dxos/echo';
19
- import { getSchemaDXN } from '@dxos/echo/internal';
20
19
  import {
21
20
  AuthStatus,
22
21
  CredentialServerExtension,
23
22
  DatabaseRoot,
24
- type EchoEdgeReplicator,
25
23
  type EchoHost,
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
- EncodedReference,
37
- type ObjectStructure,
38
- SpaceDocVersion,
39
- createIdFromSpaceKey,
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
- import { ObjectId, PublicKey, type SpaceId } from '@dxos/keys';
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,6 +99,7 @@ export type AdmitMemberOptions = {
102
99
  role: SpaceMember.Role;
103
100
  profile?: ProfileDocument;
104
101
  delegationCredentialId?: PublicKey;
102
+ tags?: string[];
105
103
  };
106
104
 
107
105
  export type DataSpaceManagerProps = {
@@ -115,7 +113,7 @@ export type DataSpaceManagerProps = {
115
113
  edgeConnection?: EdgeConnection;
116
114
  edgeHttpClient?: EdgeHttpClient;
117
115
  meshReplicator?: MeshEchoReplicator;
118
- echoEdgeReplicator?: EchoEdgeReplicator;
116
+ echoEdgeReplicator?: EdgeAutomergeReplicator;
119
117
  runtimeProps?: DataSpaceManagerRuntimeProps;
120
118
  edgeFeatures?: Runtime.Client.EdgeFeatures;
121
119
  };
@@ -135,16 +133,17 @@ export type DataSpaceManagerRuntimeProps = {
135
133
  export type CreateSpaceOptions = {
136
134
  rootUrl?: AutomergeUrl;
137
135
  documents?: Record<DocumentId, Uint8Array>;
136
+ tags?: string[];
137
+ membershipPolicy?: MembershipPolicy;
138
138
  };
139
139
 
140
140
  @trackLeaks('open', 'close')
141
+ @trace.resource({ lifecycle: true })
141
142
  export class DataSpaceManager extends Resource {
142
143
  public readonly updated = new Event();
143
144
 
144
145
  private readonly _spaces = new ComplexMap<PublicKey, DataSpace>(PublicKey.hash);
145
146
 
146
- private readonly _instanceId = PublicKey.random().toHex();
147
-
148
147
  private readonly _spaceManager: SpaceManager;
149
148
  private readonly _metadataStore: MetadataStore;
150
149
  private readonly _keyring: Keyring;
@@ -156,7 +155,7 @@ export class DataSpaceManager extends Resource {
156
155
  private readonly _edgeHttpClient?: EdgeHttpClient = undefined;
157
156
  private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures = undefined;
158
157
  private readonly _meshReplicator?: MeshEchoReplicator = undefined;
159
- private readonly _echoEdgeReplicator?: EchoEdgeReplicator = undefined;
158
+ private readonly _echoEdgeReplicator?: EdgeAutomergeReplicator = undefined;
160
159
  private readonly _runtimeProps?: DataSpaceManagerRuntimeProps = undefined;
161
160
 
162
161
  constructor(params: DataSpaceManagerProps) {
@@ -184,9 +183,8 @@ export class DataSpaceManager extends Resource {
184
183
  Array.from(this._spaces.values()).map(async (space) => {
185
184
  const rootUrl = space.automergeSpaceState.rootUrl;
186
185
  const rootHandle = rootUrl
187
- ? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(Context.default(), rootUrl as AutomergeUrl)
186
+ ? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(this._ctx, rootUrl as AutomergeUrl)
188
187
  : undefined;
189
- await rootHandle?.whenReady();
190
188
  const rootDoc = rootHandle?.doc();
191
189
 
192
190
  const properties = rootDoc && findInlineObjectOfType(rootDoc, Type.getTypename(SpaceProperties));
@@ -217,16 +215,16 @@ export class DataSpaceManager extends Resource {
217
215
  }
218
216
 
219
217
  @synchronized
220
- protected override async _open(): Promise<void> {
218
+ @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
219
+ protected override async _open(ctx: Context): Promise<void> {
221
220
  log('open');
222
- log.trace('dxos.echo.data-space-manager.open', Trace.begin({ id: this._instanceId }));
223
221
  log('metadata loaded', { spaces: this._metadataStore.spaces.length });
224
222
 
225
223
  const spacesToActivate: DataSpace[] = [];
226
224
  await forEachAsync(this._metadataStore.spaces, async (spaceMetadata) => {
227
225
  try {
228
226
  log('load space', { spaceMetadata });
229
- const space = await this._constructSpace(spaceMetadata);
227
+ const space = await this._constructSpace(ctx, spaceMetadata);
230
228
  // Track spaces that were previously active for auto-activation (used in dedicated worker mode).
231
229
  if (this._runtimeProps?.autoActivateSpaces && spaceMetadata.state === SpaceState.SPACE_ACTIVE) {
232
230
  spacesToActivate.push(space);
@@ -239,21 +237,19 @@ export class DataSpaceManager extends Resource {
239
237
  // Auto-activate spaces that were previously active (used in dedicated worker mode after leader changeover).
240
238
  for (const space of spacesToActivate) {
241
239
  log('auto-activating space', { spaceKey: space.key });
242
- space.activate().catch((err) => {
240
+ space.activate(ctx).catch((err) => {
243
241
  log.error('Error auto-activating space', { spaceKey: space.key, err });
244
242
  });
245
243
  }
246
244
 
247
245
  this.updated.emit();
248
-
249
- log.trace('dxos.echo.data-space-manager.open', Trace.end({ id: this._instanceId }));
250
246
  }
251
247
 
252
248
  @synchronized
253
- protected override async _close(): Promise<void> {
249
+ protected override async _close(ctx: Context): Promise<void> {
254
250
  log('close');
255
251
  for (const space of this._spaces.values()) {
256
- await space.close();
252
+ await space.close(ctx);
257
253
  }
258
254
  this._spaces.clear();
259
255
  }
@@ -262,7 +258,8 @@ export class DataSpaceManager extends Resource {
262
258
  * Creates a new space writing the genesis credentials to the control feed.
263
259
  */
264
260
  @synchronized
265
- async createSpace(options: CreateSpaceOptions = {}): Promise<DataSpace> {
261
+ @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
262
+ async createSpace(ctx: Context, options: CreateSpaceOptions = {}): Promise<DataSpace> {
266
263
  assertArgument(
267
264
  !!options.rootUrl === !!options.documents,
268
265
  'options',
@@ -270,6 +267,8 @@ export class DataSpaceManager extends Resource {
270
267
  );
271
268
 
272
269
  assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
270
+
271
+ const tags = options.tags ? Array.from(options.tags) : [];
273
272
  const spaceKey = await this._keyring.createKey();
274
273
  const controlFeedKey = await this._keyring.createKey();
275
274
  const dataFeedKey = await this._keyring.createKey();
@@ -282,6 +281,7 @@ export class DataSpaceManager extends Resource {
282
281
  controlFeedKey,
283
282
  dataFeedKey,
284
283
  state: SpaceState.SPACE_ACTIVE,
284
+ tags,
285
285
  };
286
286
 
287
287
  log('creating space...', { spaceId, spaceKey });
@@ -319,30 +319,38 @@ export class DataSpaceManager extends Resource {
319
319
  let root: DatabaseRoot;
320
320
  if (options.rootUrl) {
321
321
  const newRootDocId = documentIdMapping[interpretAsDocumentId(options.rootUrl)] ?? failedInvariant();
322
- 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.');
323
324
  DatabaseRoot.mapLinks(rootDocHandle, documentIdMapping);
324
325
 
325
- root = await this._echoHost.openSpaceRoot(spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
326
+ root = await this._echoHost.openSpaceRoot(ctx, spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
326
327
  } else {
327
- root = await this._echoHost.createSpaceRoot(spaceKey);
328
+ root = await this._echoHost.createSpaceRoot(ctx, spaceKey);
328
329
  }
329
- await this._echoHost.flush();
330
+ await this._echoHost.flush(ctx);
330
331
 
331
332
  log('constructing space...', { spaceKey });
332
333
 
333
- const space = await this._constructSpace(metadata);
334
- await space.open();
334
+ const space = await this._constructSpace(ctx, metadata);
335
+ await space.open(ctx);
335
336
 
336
337
  log('adding space...', { spaceKey });
337
338
 
338
- 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
+ );
339
347
  await this._metadataStore.addSpace(metadata);
340
348
 
341
349
  const memberCredential = credentials[1];
342
350
  invariant(getCredentialAssertion(memberCredential)['@type'] === 'dxos.halo.credentials.SpaceMember');
343
351
  await this._signingContext.recordCredential(memberCredential);
344
352
 
345
- await space.initializeDataPipeline();
353
+ await space.initializeDataPipeline(ctx);
346
354
 
347
355
  log('space ready.', { spaceId, spaceKey });
348
356
 
@@ -350,86 +358,36 @@ export class DataSpaceManager extends Resource {
350
358
  return space;
351
359
  }
352
360
 
353
- async isDefaultSpace(space: DataSpace): Promise<boolean> {
354
- if (!space.databaseRoot) {
355
- return false;
356
- }
357
- switch (space.databaseRoot.getVersion()) {
358
- case SpaceDocVersion.CURRENT: {
359
- if (!space.databaseRoot.handle.isReady()) {
360
- log.warn('waiting for space root to be ready', { spaceId: space.id });
361
- await space.databaseRoot.handle.whenReady();
362
- }
363
-
364
- const [_, properties] =
365
- findInlineObjectOfType(space.databaseRoot.doc()!, Type.getTypename(SpaceProperties)) ?? [];
366
- return properties?.data?.[DEFAULT_SPACE_KEY] === this._signingContext.identityKey.toHex();
367
- }
368
-
369
- case SpaceDocVersion.LEGACY: {
370
- throw new Error('Legacy space version is not supported');
371
- }
372
-
373
- default:
374
- log.warn('unknown space version', { version: space.databaseRoot.getVersion(), spaceId: space.id });
375
- return false;
376
- }
377
- }
378
-
379
- async createDefaultSpace(): Promise<DataSpace> {
380
- const space = await this.createSpace();
381
- const document = await this._getSpaceRootDocument(space);
382
-
383
- // TODO(dmaretskyi): Better API for low-level data access.
384
- const properties: ObjectStructure = {
385
- system: {
386
- type: EncodedReference.fromDXN(getSchemaDXN(SpaceProperties)!),
387
- },
388
- data: {
389
- [DEFAULT_SPACE_KEY]: this._signingContext.identityKey.toHex(),
390
- },
391
- meta: {
392
- keys: [],
393
- },
394
- };
395
-
396
- const propertiesId = ObjectId.random();
397
- document.change((doc: DatabaseDirectory) => {
398
- setDeep(doc, ['objects', propertiesId], properties);
399
- });
400
-
401
- await this._echoHost.flush();
402
- return space;
403
- }
404
-
405
- private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<DatabaseDirectory>> {
406
- const automergeIndex = space.automergeSpaceState.rootUrl;
407
- invariant(automergeIndex);
408
- const document = await this._echoHost.loadDoc<DatabaseDirectory>(Context.default(), automergeIndex as any, {
409
- fetchFromNetwork: true,
410
- });
411
- await document.whenReady();
412
- return document;
413
- }
414
-
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
+ */
415
366
  // TODO(burdon): Rename join space.
416
367
  @synchronized
417
- async acceptSpace(opts: AcceptSpaceOptions): Promise<DataSpace> {
368
+ @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
369
+ async acceptSpace(ctx: Context, opts: AcceptSpaceOptions): Promise<DataSpace> {
418
370
  log('accept space', { opts });
419
371
  invariant(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
420
372
  invariant(!this._spaces.has(opts.spaceKey), 'Space already exists.');
421
373
 
374
+ const tags = opts.tags ? Array.from(opts.tags) : [];
422
375
  const metadata: SpaceMetadata = {
423
376
  key: opts.spaceKey,
424
377
  genesisFeedKey: opts.genesisFeedKey,
425
378
  controlTimeframe: opts.controlTimeframe,
426
379
  dataTimeframe: opts.dataTimeframe,
380
+ tags,
427
381
  };
428
382
 
429
- const space = await this._constructSpace(metadata);
430
- await space.open();
383
+ const space = await this._constructSpace(ctx, metadata);
384
+ await space.open(ctx);
431
385
  await this._metadataStore.addSpace(metadata);
432
- 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);
433
391
 
434
392
  this.updated.emit();
435
393
  return space;
@@ -453,6 +411,7 @@ export class DataSpaceManager extends Resource {
453
411
  space.spaceState.membershipChainHeads,
454
412
  options.profile,
455
413
  options.delegationCredentialId,
414
+ space.spaceState.tags,
456
415
  );
457
416
 
458
417
  // TODO(dmaretskyi): Refactor.
@@ -479,8 +438,8 @@ export class DataSpaceManager extends Resource {
479
438
  );
480
439
  }
481
440
 
482
- public async requestSpaceAdmissionCredential(spaceKey: PublicKey): Promise<Credential> {
483
- return this._spaceManager.requestSpaceAdmissionCredential({
441
+ public async requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential> {
442
+ return this._spaceManager.requestSpaceAdmissionCredential(ctx, {
484
443
  spaceKey,
485
444
  identityKey: this._signingContext.identityKey,
486
445
  timeout: 15_000,
@@ -493,7 +452,11 @@ export class DataSpaceManager extends Resource {
493
452
  });
494
453
  }
495
454
 
496
- async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void> {
455
+ async setSpaceEdgeReplicationSetting(
456
+ ctx: Context,
457
+ spaceKey: PublicKey,
458
+ setting: EdgeReplicationSetting,
459
+ ): Promise<void> {
497
460
  const space = this._spaces.get(spaceKey);
498
461
  invariant(space, 'Space not found.');
499
462
 
@@ -505,7 +468,7 @@ export class DataSpaceManager extends Resource {
505
468
  await this._echoEdgeReplicator?.disconnectFromSpace(space.id);
506
469
  break;
507
470
  case EdgeReplicationSetting.ENABLED:
508
- await this._echoEdgeReplicator?.connectToSpace(space.id);
471
+ await this._echoEdgeReplicator?.connectToSpace(ctx, space.id);
509
472
  break;
510
473
  }
511
474
  }
@@ -513,7 +476,7 @@ export class DataSpaceManager extends Resource {
513
476
  space.stateUpdate.emit();
514
477
  }
515
478
 
516
- private async _constructSpace(metadata: SpaceMetadata): Promise<DataSpace> {
479
+ private async _constructSpace(ctx: Context, metadata: SpaceMetadata): Promise<DataSpace> {
517
480
  log('construct space', { metadata });
518
481
  const gossip = new Gossip({
519
482
  localPeerId: this._signingContext.deviceKey,
@@ -603,6 +566,7 @@ export class DataSpaceManager extends Resource {
603
566
  },
604
567
  },
605
568
  cache: metadata.cache,
569
+ tags: metadata.tags,
606
570
  edgeConnection: this._edgeConnection,
607
571
  edgeHttpClient: this._edgeHttpClient,
608
572
  edgeFeatures: this._edgeFeatures,
@@ -611,9 +575,10 @@ export class DataSpaceManager extends Resource {
611
575
  dataSpace.postOpen.append(async () => {
612
576
  const setting = dataSpace.getEdgeReplicationSetting();
613
577
  if (!setting || setting === EdgeReplicationSetting.ENABLED) {
614
- 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);
615
580
  } else if (this._echoEdgeReplicator) {
616
- log('not connecting EchoEdgeReplicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
581
+ log('not connecting edge replicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
617
582
  }
618
583
  });
619
584
  dataSpace.preClose.append(async () => {
@@ -708,7 +673,7 @@ export class DataSpaceManager extends Resource {
708
673
  invitations: Array<[PublicKey, DelegateSpaceInvitation]>,
709
674
  ): Promise<void> {
710
675
  const tasks = invitations.map(([credentialId, invitation]) => {
711
- return this._invitationsManager.createInvitation({
676
+ return this._invitationsManager.createInvitation(this._ctx, {
712
677
  type: Invitation.Type.DELEGATED,
713
678
  kind: Invitation.Kind.SPACE,
714
679
  spaceKey: space.key,