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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/dist/lib/browser/{chunk-WKKP35EC.mjs → chunk-5A3KX2RY.mjs} +4406 -3958
  2. package/dist/lib/browser/chunk-5A3KX2RY.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-NQSC7HOE.mjs +22 -0
  4. package/dist/lib/browser/chunk-NQSC7HOE.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
  6. package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +481 -78
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
  11. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  12. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  13. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  14. package/dist/lib/browser/packlets/locks/browser.mjs +126 -0
  15. package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
  16. package/dist/lib/browser/packlets/locks/node.mjs +66 -0
  17. package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
  18. package/dist/lib/browser/testing/index.mjs +45 -26
  19. package/dist/lib/browser/testing/index.mjs.map +3 -3
  20. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
  21. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
  22. package/dist/lib/node-esm/{chunk-ZE2HYS56.mjs → chunk-FNPO5UMU.mjs} +4302 -3722
  23. package/dist/lib/node-esm/chunk-FNPO5UMU.mjs.map +7 -0
  24. package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs +22 -0
  25. package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs.map +7 -0
  26. package/dist/lib/node-esm/index.mjs +481 -78
  27. package/dist/lib/node-esm/index.mjs.map +4 -4
  28. package/dist/lib/node-esm/meta.json +1 -1
  29. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
  30. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  31. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  32. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  33. package/dist/lib/node-esm/packlets/locks/browser.mjs +126 -0
  34. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
  35. package/dist/lib/node-esm/packlets/locks/node.mjs +66 -0
  36. package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
  37. package/dist/lib/node-esm/testing/index.mjs +45 -26
  38. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  39. package/dist/types/src/index.d.ts +1 -0
  40. package/dist/types/src/index.d.ts.map +1 -1
  41. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
  42. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  43. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +1 -1
  44. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  45. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  46. package/dist/types/src/packlets/devtools/devtools.d.ts +20 -20
  47. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  48. package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
  49. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  50. package/dist/types/src/packlets/devtools/network.d.ts +1 -1
  51. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  52. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts +1 -1
  53. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  54. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +1 -1
  55. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  56. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +1 -1
  57. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  58. package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
  59. package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
  60. package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
  61. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  62. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  63. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  64. package/dist/types/src/packlets/identity/identity-manager.d.ts +7 -7
  65. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  66. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +7 -6
  67. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  68. package/dist/types/src/packlets/identity/identity-service.d.ts +1 -6
  69. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  70. package/dist/types/src/packlets/identity/identity.d.ts +9 -12
  71. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  72. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +4 -4
  73. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  74. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
  75. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  76. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  77. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +3 -4
  79. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  80. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
  81. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  82. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
  83. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  84. package/dist/types/src/packlets/invitations/invitations-service.d.ts +1 -1
  85. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  86. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +3 -3
  87. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  88. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  89. package/dist/types/src/packlets/locks/index.d.ts +1 -1
  90. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  91. package/dist/types/src/packlets/logging/logging-service.d.ts +5 -1
  92. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  93. package/dist/types/src/packlets/network/network-service.d.ts +2 -2
  94. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  95. package/dist/types/src/packlets/services/client-rpc-server.d.ts +2 -2
  96. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  97. package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
  98. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  99. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  100. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  101. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  102. package/dist/types/src/packlets/services/service-context.d.ts +14 -9
  103. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  104. package/dist/types/src/packlets/services/service-host.d.ts +20 -6
  105. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  106. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  107. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  108. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
  109. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  110. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  111. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  112. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts +1 -1
  113. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  114. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +28 -16
  115. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  116. package/dist/types/src/packlets/spaces/data-space.d.ts +28 -12
  117. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  118. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  119. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  120. package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
  121. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  122. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -6
  123. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  124. package/dist/types/src/packlets/spaces/spaces-service.d.ts +3 -3
  125. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  126. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  127. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  128. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  129. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  130. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  131. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  132. package/dist/types/src/packlets/testing/test-builder.d.ts +8 -7
  133. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  134. package/dist/types/src/packlets/worker/worker-runtime.d.ts +31 -4
  135. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  136. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -2
  137. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  138. package/dist/types/src/version.d.ts +1 -1
  139. package/dist/types/src/version.d.ts.map +1 -1
  140. package/dist/types/tsconfig.tsbuildinfo +1 -1
  141. package/package.json +72 -48
  142. package/src/index.ts +1 -0
  143. package/src/packlets/agents/edge-agent-manager.ts +10 -7
  144. package/src/packlets/agents/edge-agent-service.ts +15 -5
  145. package/src/packlets/devices/devices-service.test.ts +4 -3
  146. package/src/packlets/devices/devices-service.ts +2 -2
  147. package/src/packlets/devtools/devtools.ts +30 -29
  148. package/src/packlets/devtools/feeds.ts +2 -2
  149. package/src/packlets/devtools/network.ts +1 -1
  150. package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +1 -1
  151. package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -1
  152. package/src/packlets/diagnostics/diagnostics-collector.ts +1 -1
  153. package/src/packlets/diagnostics/diagnostics.ts +1 -1
  154. package/src/packlets/diagnostics/index.ts +1 -1
  155. package/src/packlets/identity/authenticator.node.test.ts +1 -1
  156. package/src/packlets/identity/authenticator.ts +3 -3
  157. package/src/packlets/identity/contacts-service.ts +3 -2
  158. package/src/packlets/identity/identity-manager.test.ts +8 -8
  159. package/src/packlets/identity/identity-manager.ts +23 -20
  160. package/src/packlets/identity/identity-recovery-manager.ts +22 -18
  161. package/src/packlets/identity/identity-service.test.ts +9 -28
  162. package/src/packlets/identity/identity-service.ts +5 -75
  163. package/src/packlets/identity/identity.test.ts +11 -11
  164. package/src/packlets/identity/identity.ts +16 -37
  165. package/src/packlets/invitations/device-invitation-protocol.test.ts +1 -1
  166. package/src/packlets/invitations/device-invitation-protocol.ts +6 -5
  167. package/src/packlets/invitations/edge-invitation-handler.ts +5 -4
  168. package/src/packlets/invitations/invitation-guest-extenstion.ts +7 -5
  169. package/src/packlets/invitations/invitation-host-extension.ts +8 -6
  170. package/src/packlets/invitations/invitation-protocol.ts +3 -4
  171. package/src/packlets/invitations/invitations-handler.test.ts +8 -7
  172. package/src/packlets/invitations/invitations-handler.ts +13 -13
  173. package/src/packlets/invitations/invitations-manager.ts +40 -17
  174. package/src/packlets/invitations/invitations-service.ts +5 -5
  175. package/src/packlets/invitations/space-invitation-protocol.test.ts +19 -18
  176. package/src/packlets/invitations/space-invitation-protocol.ts +13 -16
  177. package/src/packlets/invitations/utils.ts +1 -1
  178. package/src/packlets/locks/browser.ts +1 -1
  179. package/src/packlets/locks/index.ts +1 -1
  180. package/src/packlets/logging/logging-service.ts +7 -3
  181. package/src/packlets/logging/logging.test.ts +1 -1
  182. package/src/packlets/network/network-service.test.ts +4 -3
  183. package/src/packlets/network/network-service.ts +7 -6
  184. package/src/packlets/services/client-rpc-server.ts +5 -5
  185. package/src/packlets/services/feed-syncer.test.ts +340 -0
  186. package/src/packlets/services/feed-syncer.ts +337 -0
  187. package/src/packlets/services/platform.ts +7 -1
  188. package/src/packlets/services/service-context.test.ts +4 -3
  189. package/src/packlets/services/service-context.ts +139 -52
  190. package/src/packlets/services/service-host.test.ts +11 -9
  191. package/src/packlets/services/service-host.ts +78 -28
  192. package/src/packlets/services/service-registry.test.ts +2 -1
  193. package/src/packlets/space-export/space-archive-reader.ts +65 -4
  194. package/src/packlets/space-export/space-archive-writer.ts +42 -5
  195. package/src/packlets/space-export/space-archive.test.ts +287 -0
  196. package/src/packlets/space-export/tar.test.ts +1 -1
  197. package/src/packlets/spaces/automerge-space-state.ts +1 -1
  198. package/src/packlets/spaces/data-space-manager.test.ts +79 -13
  199. package/src/packlets/spaces/data-space-manager.ts +124 -116
  200. package/src/packlets/spaces/data-space.ts +60 -35
  201. package/src/packlets/spaces/edge-feed-replicator.test.ts +4 -4
  202. package/src/packlets/spaces/edge-feed-replicator.ts +12 -11
  203. package/src/packlets/spaces/epoch-migrations.ts +5 -5
  204. package/src/packlets/spaces/genesis.ts +6 -1
  205. package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
  206. package/src/packlets/spaces/notarization-plugin.ts +13 -12
  207. package/src/packlets/spaces/spaces-service.test.ts +12 -8
  208. package/src/packlets/spaces/spaces-service.ts +57 -31
  209. package/src/packlets/storage/profile-archive.ts +1 -1
  210. package/src/packlets/storage/storage.ts +7 -8
  211. package/src/packlets/system/system-service.test.ts +1 -1
  212. package/src/packlets/system/system-service.ts +4 -4
  213. package/src/packlets/testing/invitation-utils.ts +11 -7
  214. package/src/packlets/testing/test-builder.ts +39 -13
  215. package/src/packlets/worker/worker-runtime.ts +152 -13
  216. package/src/packlets/worker/worker-session.ts +11 -11
  217. package/src/version.ts +1 -1
  218. package/dist/lib/browser/chunk-WKKP35EC.mjs.map +0 -7
  219. package/dist/lib/node-esm/chunk-ZE2HYS56.mjs.map +0 -7
  220. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  221. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  222. package/src/packlets/identity/default-space-state-machine.ts +0 -44
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { save } from '@automerge/automerge';
6
- import { type DocHandle } from '@automerge/automerge-repo';
6
+ import { type AutomergeUrl, type DocHandle } from '@automerge/automerge-repo';
7
7
 
8
8
  import { Event, Mutex, scheduleTask, sleep, synchronized, trackLeaks } from '@dxos/async';
9
9
  import { AUTH_TIMEOUT } from '@dxos/client-protocol';
@@ -11,48 +11,49 @@ import { Context, ContextDisposedError, cancelWithContext } from '@dxos/context'
11
11
  import type { SpecificCredential } from '@dxos/credentials';
12
12
  import { timed, warnAfterTimeout } from '@dxos/debug';
13
13
  import {
14
- type EchoHost,
15
14
  type DatabaseRoot,
16
- createMappedFeedWriter,
15
+ type EchoHost,
17
16
  type MetadataStore,
18
17
  type Space,
19
- FIND_PARAMS,
18
+ createMappedFeedWriter,
20
19
  } from '@dxos/echo-pipeline';
21
- import { SpaceDocVersion, type DatabaseDirectory } from '@dxos/echo-protocol';
20
+ import { type DatabaseDirectory, SpaceDocVersion } from '@dxos/echo-protocol';
22
21
  import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
23
22
  import { type FeedStore, type FeedWrapper } from '@dxos/feed-store';
24
23
  import { failedInvariant, invariant } from '@dxos/invariant';
25
24
  import { type Keyring } from '@dxos/keyring';
26
25
  import { PublicKey } from '@dxos/keys';
27
26
  import { log } from '@dxos/log';
28
- import { CancelledError, SystemError } from '@dxos/protocols';
27
+ import { CancelledError, type FeedProtocol, SystemError } from '@dxos/protocols';
29
28
  import {
30
29
  type CreateEpochRequest,
31
- SpaceState,
32
30
  type Space as SpaceProto,
31
+ SpaceState,
33
32
  } from '@dxos/protocols/proto/dxos/client/services';
34
33
  import { type Runtime } from '@dxos/protocols/proto/dxos/config';
35
34
  import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
36
35
  import { type SpaceCache } from '@dxos/protocols/proto/dxos/echo/metadata';
37
36
  import {
38
37
  AdmittedFeed,
39
- SpaceMember,
40
38
  type Credential,
41
39
  type Epoch,
40
+ MembershipPolicy,
42
41
  type ProfileDocument,
42
+ SpaceMember,
43
43
  } from '@dxos/protocols/proto/dxos/halo/credentials';
44
44
  import { type GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
45
45
  import { type Gossip, type Presence } from '@dxos/teleport-extension-gossip';
46
46
  import { Timeframe } from '@dxos/timeframe';
47
47
  import { trace } from '@dxos/tracing';
48
- import { CallbackCollection, ComplexSet, type AsyncCallback } from '@dxos/util';
48
+ import { type AsyncCallback, CallbackCollection, ComplexSet } from '@dxos/util';
49
+
50
+ import { TrustedKeySetAuthVerifier } from '../identity';
49
51
 
50
52
  import { AutomergeSpaceState } from './automerge-space-state';
51
53
  import { type SigningContext } from './data-space-manager';
52
54
  import { EdgeFeedReplicator } from './edge-feed-replicator';
53
55
  import { runEpochMigration } from './epoch-migrations';
54
56
  import { NotarizationPlugin } from './notarization-plugin';
55
- import { TrustedKeySetAuthVerifier } from '../identity';
56
57
 
57
58
  export type DataSpaceCallbacks = {
58
59
  /**
@@ -71,7 +72,7 @@ export type DataSpaceCallbacks = {
71
72
  beforeClose?: () => Promise<void>;
72
73
  };
73
74
 
74
- export type DataSpaceParams = {
75
+ export type DataSpaceProps = {
75
76
  initialState: SpaceState;
76
77
  inner: Space;
77
78
  metadataStore: MetadataStore;
@@ -83,6 +84,7 @@ export type DataSpaceParams = {
83
84
  signingContext: SigningContext;
84
85
  callbacks?: DataSpaceCallbacks;
85
86
  cache?: SpaceCache;
87
+ tags?: string[];
86
88
  edgeConnection?: EdgeConnection;
87
89
  edgeHttpClient?: EdgeHttpClient;
88
90
  edgeFeatures?: Runtime.Client.EdgeFeatures;
@@ -120,6 +122,9 @@ export class DataSpace {
120
122
 
121
123
  private _state = SpaceState.SPACE_CLOSED;
122
124
 
125
+ /** Immutable tags from space metadata, available immediately. */
126
+ readonly tags: string[];
127
+
123
128
  private _databaseRoot: DatabaseRoot | null = null;
124
129
 
125
130
  /**
@@ -135,7 +140,7 @@ export class DataSpace {
135
140
 
136
141
  public metrics: SpaceProto.Metrics = {};
137
142
 
138
- constructor(params: DataSpaceParams) {
143
+ constructor(params: DataSpaceProps) {
139
144
  this._inner = params.inner;
140
145
  this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());
141
146
 
@@ -167,6 +172,7 @@ export class DataSpace {
167
172
  });
168
173
 
169
174
  this._cache = params.cache;
175
+ this.tags = params.tags ?? [];
170
176
 
171
177
  if (params.edgeConnection && params.edgeFeatures?.feedReplicator) {
172
178
  this._edgeFeedReplicator = new EdgeFeedReplicator({ messenger: params.edgeConnection, spaceId: this.id });
@@ -212,6 +218,11 @@ export class DataSpace {
212
218
  return this._cache;
213
219
  }
214
220
 
221
+ /** Membership policy from the genesis credential, defaults to INVITE. */
222
+ get membershipPolicy(): MembershipPolicy {
223
+ return this._inner.spaceState.genesisCredential ? this._inner.spaceState.membershipPolicy : MembershipPolicy.INVITE;
224
+ }
225
+
215
226
  get automergeSpaceState() {
216
227
  return this._automergeSpaceState;
217
228
  }
@@ -229,13 +240,14 @@ export class DataSpace {
229
240
  }
230
241
 
231
242
  @synchronized
232
- async open(): Promise<void> {
243
+ @trace.span({ showInBrowserTimeline: true })
244
+ async open(ctx: Context): Promise<void> {
233
245
  if (this._state === SpaceState.SPACE_CLOSED) {
234
- await this._open();
246
+ await this._open(ctx);
235
247
  }
236
248
  }
237
249
 
238
- private async _open(): Promise<void> {
250
+ private async _open(ctx: Context): Promise<void> {
239
251
  await this._presence.open();
240
252
  await this._gossip.open();
241
253
  await this._notarizationPlugin.open();
@@ -247,8 +259,8 @@ export class DataSpace {
247
259
  this.inner.protocol.feedAdded.append(this._onFeedAdded);
248
260
  }
249
261
 
250
- await this._inner.open(new Context());
251
- await this._inner.startProtocol();
262
+ await this._inner.open(ctx);
263
+ await this._inner.startProtocol(ctx);
252
264
 
253
265
  await this._edgeFeedReplicator?.open();
254
266
 
@@ -262,11 +274,12 @@ export class DataSpace {
262
274
  }
263
275
 
264
276
  @synchronized
265
- async close(): Promise<void> {
266
- await this._close();
277
+ @trace.span({ showInBrowserTimeline: true })
278
+ async close(ctx: Context): Promise<void> {
279
+ await this._close(ctx);
267
280
  }
268
281
 
269
- private async _close(): Promise<void> {
282
+ private async _close(ctx: Context): Promise<void> {
270
283
  await this._callbacks.beforeClose?.();
271
284
 
272
285
  await this.preClose.callSerial();
@@ -284,7 +297,7 @@ export class DataSpace {
284
297
 
285
298
  await this.authVerifier.close();
286
299
 
287
- await this._inner.close();
300
+ await this._inner.close(ctx);
288
301
  await this._inner.spaceState.removeCredentialProcessor(this._automergeSpaceState);
289
302
  await this._automergeSpaceState.close();
290
303
  await this._inner.spaceState.removeCredentialProcessor(this._notarizationPlugin);
@@ -309,7 +322,7 @@ export class DataSpace {
309
322
  scheduleTask(this._ctx, async () => {
310
323
  try {
311
324
  this.metrics.pipelineInitBegin = new Date();
312
- await this.initializeDataPipeline();
325
+ await this.initializeDataPipeline(this._ctx);
313
326
  } catch (err) {
314
327
  if (err instanceof CancelledError || err instanceof ContextDisposedError) {
315
328
  log('data pipeline initialization cancelled', err);
@@ -328,16 +341,16 @@ export class DataSpace {
328
341
  }
329
342
 
330
343
  @trace.span({ showInBrowserTimeline: true })
331
- async initializeDataPipeline(): Promise<void> {
344
+ async initializeDataPipeline(ctx: Context): Promise<void> {
332
345
  if (this._state !== SpaceState.SPACE_CONTROL_ONLY) {
333
- throw new SystemError('Invalid operation');
346
+ throw new SystemError({ message: 'Invalid operation' });
334
347
  }
335
348
 
336
349
  this._state = SpaceState.SPACE_INITIALIZING;
337
350
  log('new state', { state: SpaceState[this._state] });
338
351
 
339
352
  log('initializing control pipeline');
340
- await this._initializeAndReadControlPipeline();
353
+ await this._initializeAndReadControlPipeline(ctx);
341
354
 
342
355
  // Allow other tasks to run before loading the data pipeline.
343
356
  await sleep(1);
@@ -360,11 +373,19 @@ export class DataSpace {
360
373
  yield [this._databaseRoot.documentId, root];
361
374
 
362
375
  for (const documentUrl of this._databaseRoot.getAllLinkedDocuments()) {
363
- const data = await this._echoHost.exportDoc(Context.default(), documentUrl);
376
+ const data = await this._echoHost.exportDoc(documentUrl);
364
377
  yield [documentUrl.replace(/^automerge:/, ''), data];
365
378
  }
366
379
  }
367
380
 
381
+ /**
382
+ * Get all feeds and their blocks for this space.
383
+ * Used for space archive export.
384
+ */
385
+ async getAllFeeds(): Promise<Array<{ feedId: string; feedNamespace: string; blocks: FeedProtocol.Block[] }>> {
386
+ return this._echoHost.getAllFeedsForSpace(this.id);
387
+ }
388
+
368
389
  private async _enterReadyState(): Promise<void> {
369
390
  await this._callbacks.beforeReady?.();
370
391
 
@@ -376,9 +397,9 @@ export class DataSpace {
376
397
  }
377
398
 
378
399
  @trace.span({ showInBrowserTimeline: true })
379
- private async _initializeAndReadControlPipeline(): Promise<void> {
400
+ private async _initializeAndReadControlPipeline(ctx: Context): Promise<void> {
380
401
  await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
381
- ctx: this._ctx,
402
+ ctx,
382
403
  timeout: 10_000,
383
404
  breakOnStall: false,
384
405
  });
@@ -450,6 +471,9 @@ export class DataSpace {
450
471
 
451
472
  log('credentials notarized');
452
473
  } catch (err) {
474
+ if (err instanceof ContextDisposedError) {
475
+ return;
476
+ }
453
477
  log.error('error notarizing credentials for feed admission', err);
454
478
  throw err;
455
479
  }
@@ -470,7 +494,9 @@ export class DataSpace {
470
494
  await warnAfterTimeout(5_000, 'Automerge root doc load timeout (DataSpace)', async () => {
471
495
  handle = await cancelWithContext(
472
496
  this._ctx,
473
- this._echoHost.automergeRepo.find<DatabaseDirectory>(rootUrl as any, FIND_PARAMS),
497
+ this._echoHost.loadDoc<DatabaseDirectory>(this._ctx, rootUrl as AutomergeUrl, {
498
+ fetchFromNetwork: true,
499
+ }),
474
500
  );
475
501
  await cancelWithContext(this._ctx, handle.whenReady());
476
502
  });
@@ -491,7 +517,7 @@ export class DataSpace {
491
517
 
492
518
  // TODO(dmaretskyi): Close roots.
493
519
  // TODO(dmaretskyi): How do we handle changing to the next EPOCH?
494
- const root = await this._echoHost.openSpaceRoot(this.id, handle.url);
520
+ const root = await this._echoHost.openSpaceRoot(this._ctx, this.id, handle.url);
495
521
 
496
522
  // NOTE: Make sure this assignment happens synchronously together with the state change.
497
523
  this._databaseRoot = root;
@@ -568,25 +594,24 @@ export class DataSpace {
568
594
  }
569
595
 
570
596
  @synchronized
571
- async activate(): Promise<void> {
597
+ async activate(ctx: Context): Promise<void> {
572
598
  if (![SpaceState.SPACE_CLOSED, SpaceState.SPACE_INACTIVE].includes(this._state)) {
573
599
  return;
574
600
  }
575
601
 
576
602
  await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_ACTIVE);
577
- await this._open();
603
+ await this._open(ctx);
578
604
  this.initializeDataPipelineAsync();
579
605
  }
580
606
 
581
607
  @synchronized
582
- async deactivate(): Promise<void> {
608
+ async deactivate(ctx: Context): Promise<void> {
583
609
  if (this._state === SpaceState.SPACE_INACTIVE) {
584
610
  return;
585
611
  }
586
- // Unregister from data service.
587
612
  await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_INACTIVE);
588
613
  if (this._state !== SpaceState.SPACE_CLOSED) {
589
- await this._close();
614
+ await this._close(ctx);
590
615
  }
591
616
  this._state = SpaceState.SPACE_INACTIVE;
592
617
  log('new state', { state: SpaceState[this._state] });
@@ -6,10 +6,10 @@ import { decode as decodeCbor, encode as encodeCbor } from 'cbor-x';
6
6
  import { getPort } from 'get-port-please';
7
7
  import { describe, expect, onTestFinished, test, vi } from 'vitest';
8
8
 
9
- import { sleep, Trigger } from '@dxos/async';
9
+ import { Trigger, sleep } from '@dxos/async';
10
10
  import { Context } from '@dxos/context';
11
11
  import { valueEncoding } from '@dxos/echo-pipeline';
12
- import { createEphemeralEdgeIdentity, EdgeClient, EdgeIdentityChangedError } from '@dxos/edge-client';
12
+ import { EdgeClient, EdgeIdentityChangedError, createEphemeralEdgeIdentity } from '@dxos/edge-client';
13
13
  import { createTestEdgeWsServer } from '@dxos/edge-client/testing';
14
14
  import { FeedFactory, FeedStore, type FeedWrapper } from '@dxos/feed-store';
15
15
  import { Keyring } from '@dxos/keyring';
@@ -45,7 +45,7 @@ describe('EdgeFeedReplicator', () => {
45
45
  const { endpoint, admitConnection, messageSink } = await createEdge();
46
46
  const { messenger } = await createClient(endpoint);
47
47
  admitConnection.wake();
48
- await expect.poll(() => messenger.status).toBe(EdgeStatus.CONNECTED);
48
+ await expect.poll(() => messenger.status.state).toBe(EdgeStatus.ConnectionState.CONNECTED);
49
49
 
50
50
  await attachReplicator(messenger);
51
51
  await expect.poll(() => messageSink.length).toEqual(1);
@@ -107,7 +107,7 @@ describe('EdgeFeedReplicator', () => {
107
107
  const { feed } = await attachReplicator(messenger);
108
108
  await appendMessage(feed);
109
109
 
110
- sendSpy.mockImplementationOnce(async (request: any) => {
110
+ sendSpy.mockImplementationOnce(async (_ctx: any, request: any) => {
111
111
  sendResponseMessage(request, encodeCbor({ type: 'metadata', feedKey: feed.key.toHex(), length: 0 }));
112
112
  return Promise.resolve();
113
113
  });
@@ -15,14 +15,14 @@ import { log, logInfo } from '@dxos/log';
15
15
  import { EdgeService } from '@dxos/protocols';
16
16
  import { buf } from '@dxos/protocols/buf';
17
17
  import {
18
- MessageSchema as RouterMessageSchema,
19
18
  type Message as RouterMessage,
19
+ MessageSchema as RouterMessageSchema,
20
20
  } from '@dxos/protocols/buf/dxos/edge/messenger_pb';
21
21
  import type { FeedBlock, ProtocolMessage } from '@dxos/protocols/feed-replication';
22
22
  import { EdgeStatus } from '@dxos/protocols/proto/dxos/client/services';
23
23
  import { ComplexMap, arrayToBuffer, bufferToArray, defaultMap, rangeFromTo } from '@dxos/util';
24
24
 
25
- export type EdgeFeedReplicatorParams = {
25
+ export type EdgeFeedReplicatorProps = {
26
26
  messenger: EdgeConnection;
27
27
  spaceId: SpaceId;
28
28
  };
@@ -47,7 +47,7 @@ export class EdgeFeedReplicator extends Resource {
47
47
  */
48
48
  private _pushMutex = new ComplexMap<PublicKey, Mutex>(PublicKey.hash);
49
49
 
50
- constructor({ messenger, spaceId }: EdgeFeedReplicatorParams) {
50
+ constructor({ messenger, spaceId }: EdgeFeedReplicatorProps) {
51
51
  super();
52
52
  this._messenger = messenger;
53
53
  this._spaceId = spaceId;
@@ -87,7 +87,7 @@ export class EdgeFeedReplicator extends Resource {
87
87
 
88
88
  private async _handleReconnect(): Promise<void> {
89
89
  await this._resetConnection();
90
- if (this._messenger.status === EdgeStatus.CONNECTED) {
90
+ if (this._messenger.status.state === EdgeStatus.ConnectionState.CONNECTED) {
91
91
  this._startReplication();
92
92
  }
93
93
  }
@@ -132,7 +132,7 @@ export class EdgeFeedReplicator extends Resource {
132
132
 
133
133
  private async _replicateFeed(ctx: Context, feed: FeedWrapper<any>): Promise<void> {
134
134
  log('replicateFeed', { key: feed.key });
135
- await this._sendMessage({
135
+ await this._sendMessage(ctx, {
136
136
  type: 'get-metadata',
137
137
  feedKey: feed.key.toHex(),
138
138
  });
@@ -142,7 +142,7 @@ export class EdgeFeedReplicator extends Resource {
142
142
  });
143
143
  }
144
144
 
145
- private async _sendMessage(message: ProtocolMessage): Promise<void> {
145
+ private async _sendMessage(ctx: Context, message: ProtocolMessage): Promise<void> {
146
146
  if (!this._connectionCtx) {
147
147
  log('message dropped because connection was disposed');
148
148
  return;
@@ -160,6 +160,7 @@ export class EdgeFeedReplicator extends Resource {
160
160
 
161
161
  log('send', { type: message.type });
162
162
  await this._messenger.send(
163
+ ctx,
163
164
  buf.create(RouterMessageSchema, {
164
165
  source: {
165
166
  identityKey: this._messenger.identityKey,
@@ -194,7 +195,7 @@ export class EdgeFeedReplicator extends Resource {
194
195
  if (message.length > feed.length) {
195
196
  log('requesting missing blocks', logMeta);
196
197
 
197
- await this._sendMessage({
198
+ await this._sendMessage(this._connectionCtx!, {
198
199
  type: 'request',
199
200
  feedKey: feedKey.toHex(),
200
201
  range: { from: feed.length, to: message.length },
@@ -202,7 +203,7 @@ export class EdgeFeedReplicator extends Resource {
202
203
  } else if (message.length < feed.length) {
203
204
  log('pushing blocks to remote', logMeta);
204
205
 
205
- await this._pushBlocks(feed, message.length, feed.length);
206
+ await this._pushBlocks(this._connectionCtx!, feed, message.length, feed.length);
206
207
  }
207
208
 
208
209
  break;
@@ -229,7 +230,7 @@ export class EdgeFeedReplicator extends Resource {
229
230
  });
230
231
  }
231
232
 
232
- private async _pushBlocks(feed: FeedWrapper<any>, from: number, to: number): Promise<void> {
233
+ private async _pushBlocks(ctx: Context, feed: FeedWrapper<any>, from: number, to: number): Promise<void> {
233
234
  log('pushing blocks', { feed: feed.key.toHex(), from, to });
234
235
 
235
236
  const blocks: FeedBlock[] = await Promise.all(
@@ -247,7 +248,7 @@ export class EdgeFeedReplicator extends Resource {
247
248
  }),
248
249
  );
249
250
 
250
- await this._sendMessage({
251
+ await this._sendMessage(ctx, {
251
252
  type: 'data',
252
253
  feedKey: feed.key.toHex(),
253
254
  blocks,
@@ -283,7 +284,7 @@ export class EdgeFeedReplicator extends Resource {
283
284
 
284
285
  const remoteLength = this._remoteLength.get(feed.key)!;
285
286
  if (remoteLength < feed.length) {
286
- await this._pushBlocks(feed, remoteLength, feed.length);
287
+ await this._pushBlocks(this._connectionCtx!, feed, remoteLength, feed.length);
287
288
  }
288
289
  }
289
290
 
@@ -36,8 +36,8 @@ const LOAD_DOC_TIMEOUT = 10_000;
36
36
  export const runEpochMigration = async (ctx: Context, context: MigrationContext): Promise<MigrationResult> => {
37
37
  switch (context.migration) {
38
38
  case CreateEpochRequest.Migration.INIT_AUTOMERGE: {
39
- const document = context.echoHost.createDoc();
40
- await context.echoHost.flush();
39
+ const document = await context.echoHost.createDoc();
40
+ await context.echoHost.flush(ctx);
41
41
  return { newRoot: document.url };
42
42
  }
43
43
  case CreateEpochRequest.Migration.PRUNE_AUTOMERGE_ROOT_HISTORY: {
@@ -48,8 +48,8 @@ export const runEpochMigration = async (ctx: Context, context: MigrationContext)
48
48
  timeout: LOAD_DOC_TIMEOUT,
49
49
  });
50
50
 
51
- const newRoot = context.echoHost.createDoc(rootHandle.doc());
52
- await context.echoHost.flush();
51
+ const newRoot = await context.echoHost.createDoc(rootHandle.doc());
52
+ await context.echoHost.flush(ctx);
53
53
  return { newRoot: newRoot.url };
54
54
  }
55
55
  case CreateEpochRequest.Migration.FRAGMENT_AUTOMERGE_ROOT: {
@@ -63,7 +63,7 @@ export const runEpochMigration = async (ctx: Context, context: MigrationContext)
63
63
  invariant(context.newAutomergeRoot);
64
64
 
65
65
  // Defensive programming - it should be the responsibility of the caller to flush the new root.
66
- await context.echoHost.flush();
66
+ await context.echoHost.flush(ctx);
67
67
  return {
68
68
  newRoot: context.newAutomergeRoot,
69
69
  };
@@ -6,7 +6,7 @@ import { createCredential } from '@dxos/credentials';
6
6
  import { failUndefined } from '@dxos/debug';
7
7
  import { type Space } from '@dxos/echo-pipeline';
8
8
  import { type Keyring } from '@dxos/keyring';
9
- import { AdmittedFeed, SpaceMember } from '@dxos/protocols/proto/dxos/halo/credentials';
9
+ import { AdmittedFeed, MembershipPolicy, SpaceMember } from '@dxos/protocols/proto/dxos/halo/credentials';
10
10
  import { Timeframe } from '@dxos/timeframe';
11
11
 
12
12
  import { type SigningContext } from './data-space-manager';
@@ -16,6 +16,8 @@ export const spaceGenesis = async (
16
16
  signingContext: SigningContext,
17
17
  space: Space,
18
18
  automergeRoot?: string,
19
+ tags?: string[],
20
+ membershipPolicy?: MembershipPolicy,
19
21
  ) => {
20
22
  // TODO(dmaretskyi): Find a way to reconcile with credential generator.
21
23
  const credentials = [
@@ -26,6 +28,8 @@ export const spaceGenesis = async (
26
28
  assertion: {
27
29
  '@type': 'dxos.halo.credentials.SpaceGenesis',
28
30
  spaceKey: space.key,
31
+ tags: tags ?? [],
32
+ membershipPolicy: membershipPolicy ?? MembershipPolicy.INVITE,
29
33
  },
30
34
  }),
31
35
 
@@ -39,6 +43,7 @@ export const spaceGenesis = async (
39
43
  role: SpaceMember.Role.OWNER,
40
44
  profile: signingContext.getProfile(),
41
45
  genesisFeedKey: space.controlFeedKey ?? failUndefined(),
46
+ tags: tags ?? [],
42
47
  },
43
48
  }),
44
49
 
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { onTestFinished, describe, expect, test } from 'vitest';
5
+ import { describe, expect, onTestFinished, test } from 'vitest';
6
6
 
7
7
  import { Context } from '@dxos/context';
8
8
  import { CredentialGenerator } from '@dxos/credentials';
@@ -13,7 +13,7 @@ import { log } from '@dxos/log';
13
13
  import { AdmittedFeed, type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
14
14
  import { TestBuilder, type TestConnection, TestPeer } from '@dxos/teleport/testing';
15
15
 
16
- import { NotarizationPlugin, type NotarizationPluginParams } from './notarization-plugin';
16
+ import { NotarizationPlugin, type NotarizationPluginProps } from './notarization-plugin';
17
17
 
18
18
  class TestAgent extends TestPeer {
19
19
  private readonly _ctx = new Context();
@@ -21,7 +21,7 @@ class TestAgent extends TestPeer {
21
21
  feed = new MockFeedWriter<Credential>();
22
22
  notarizationPlugin: NotarizationPlugin;
23
23
 
24
- constructor(params: NotarizationPluginParams) {
24
+ constructor(params: NotarizationPluginProps) {
25
25
  super();
26
26
  this.notarizationPlugin = new NotarizationPlugin(params);
27
27
  this.feed.written.on(this._ctx, async ([credential]) => {
@@ -2,15 +2,15 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { DeferredTask, Event, scheduleTask, sleep, TimeoutError, Trigger, scheduleMicroTask } from '@dxos/async';
6
- import { type Context, rejectOnDispose, Resource } from '@dxos/context';
5
+ import { DeferredTask, Event, TimeoutError, Trigger, scheduleMicroTask, scheduleTask, sleep } from '@dxos/async';
6
+ import { type Context, Resource, rejectOnDispose } from '@dxos/context';
7
7
  import { type CredentialProcessor, verifyCredential } from '@dxos/credentials';
8
8
  import { type EdgeHttpClient } from '@dxos/edge-client';
9
9
  import { type FeedWriter } from '@dxos/feed-store';
10
10
  import { invariant } from '@dxos/invariant';
11
11
  import { PublicKey } from '@dxos/keys';
12
12
  import { type SpaceId } from '@dxos/keys';
13
- import { logInfo, log } from '@dxos/log';
13
+ import { log, logInfo } from '@dxos/log';
14
14
  import { EdgeCallFailedError } from '@dxos/protocols';
15
15
  import { schema } from '@dxos/protocols/proto';
16
16
  import { type Runtime } from '@dxos/protocols/proto/dxos/config';
@@ -33,14 +33,14 @@ const WRITER_NOT_SET_ERROR_CODE = 'WRITER_NOT_SET';
33
33
 
34
34
  const credentialCodec = schema.getCodecForType('dxos.halo.credentials.Credential');
35
35
 
36
- export type NotarizationPluginParams = {
36
+ export type NotarizationPluginProps = {
37
37
  spaceId: SpaceId;
38
38
  edgeClient?: EdgeHttpClient;
39
39
  edgeFeatures?: Runtime.Client.EdgeFeatures;
40
40
  activeEdgePollingInterval?: number;
41
41
  };
42
42
 
43
- export type NotarizeParams = {
43
+ export type NotarizeProps = {
44
44
  /**
45
45
  * For cancellation.
46
46
  */
@@ -97,7 +97,7 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
97
97
 
98
98
  private readonly _edgeClient: EdgeHttpClient | undefined;
99
99
 
100
- constructor(params: NotarizationPluginParams) {
100
+ constructor(params: NotarizationPluginProps) {
101
101
  super();
102
102
  this._spaceId = params.spaceId;
103
103
  this._activeEdgePollingInterval = params.activeEdgePollingInterval ?? DEFAULT_ACTIVE_EDGE_POLLING_INTERVAL;
@@ -149,7 +149,7 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
149
149
  retryTimeout = DEFAULT_RETRY_TIMEOUT,
150
150
  successDelay = DEFAULT_SUCCESS_DELAY,
151
151
  edgeRetryJitter,
152
- }: NotarizeParams): Promise<void> {
152
+ }: NotarizeProps): Promise<void> {
153
153
  log('notarize', { credentials });
154
154
  invariant(
155
155
  credentials.every((credential) => credential.id),
@@ -246,6 +246,7 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
246
246
  scheduleTask(ctx, async () => {
247
247
  try {
248
248
  await client.notarizeCredentials(
249
+ ctx,
249
250
  this._spaceId,
250
251
  { credentials: encodedCredentials },
251
252
  { retry: { count: MAX_EDGE_RETRIES, timeout: timeouts.retryTimeout, jitter: timeouts.jitter } },
@@ -302,7 +303,7 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
302
303
  private _notarizePendingEdgeCredentials(client: EdgeHttpClient, writer: FeedWriter<Credential>): void {
303
304
  scheduleMicroTask(this._ctx, async () => {
304
305
  try {
305
- const response = await client.getCredentialsForNotarization(this._spaceId, {
306
+ const response = await client.getCredentialsForNotarization(this._ctx, this._spaceId, {
306
307
  retry: { count: MAX_EDGE_RETRIES },
307
308
  });
308
309
 
@@ -392,21 +393,21 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
392
393
  }
393
394
 
394
395
  const handleEdgeError = (error: any) => {
395
- if (!(error instanceof EdgeCallFailedError) || error.errorData) {
396
+ if (!(error instanceof EdgeCallFailedError) || error.data) {
396
397
  log.catch(error);
397
398
  } else {
398
- log.info('Edge notarization failure', { reason: error.reason });
399
+ log.info('Edge notarization failure', { message: error.message });
399
400
  }
400
401
  };
401
402
 
402
- export type NotarizationTeleportExtensionParams = {
403
+ export type NotarizationTeleportExtensionProps = {
403
404
  onOpen: () => Promise<void>;
404
405
  onClose: () => Promise<void>;
405
406
  onNotarize: (request: NotarizeRequest) => Promise<void>;
406
407
  };
407
408
 
408
409
  export class NotarizationTeleportExtension extends RpcExtension<Services, Services> {
409
- constructor(private readonly _params: NotarizationTeleportExtensionParams) {
410
+ constructor(private readonly _params: NotarizationTeleportExtensionProps) {
410
411
  super({
411
412
  requested: {
412
413
  NotarizationService: schema.getService('dxos.mesh.teleport.notarization.NotarizationService'),
@@ -2,17 +2,19 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { afterEach, onTestFinished, beforeEach, describe, expect, test } from 'vitest';
5
+ import { afterEach, beforeEach, describe, expect, onTestFinished, test } from 'vitest';
6
6
 
7
7
  import { Trigger } from '@dxos/async';
8
8
  import { Context } from '@dxos/context';
9
9
  import { PublicKey } from '@dxos/keys';
10
10
  import { type Space, type SpacesService } from '@dxos/protocols/proto/dxos/client/services';
11
+ import { MembershipPolicy } from '@dxos/protocols/proto/dxos/halo/credentials';
11
12
 
12
- import { SpacesServiceImpl } from './spaces-service';
13
13
  import { type ServiceContext } from '../services';
14
14
  import { createServiceContext } from '../testing';
15
15
 
16
+ import { SpacesServiceImpl } from './spaces-service';
17
+
16
18
  describe('SpacesService', () => {
17
19
  let serviceContext: ServiceContext;
18
20
  let spacesService: SpacesService;
@@ -32,12 +34,14 @@ describe('SpacesService', () => {
32
34
 
33
35
  describe('createSpace', () => {
34
36
  test('fails if no identity is available', async () => {
35
- await expect(spacesService.createSpace()).rejects.toBeInstanceOf(Error);
37
+ await expect(spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE })).rejects.toBeInstanceOf(
38
+ Error,
39
+ );
36
40
  });
37
41
 
38
42
  test('creates a new space', async () => {
39
43
  await serviceContext.createIdentity();
40
- const space = await spacesService.createSpace();
44
+ const space = await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
41
45
  expect(space).to.exist;
42
46
  expect(space.spaceKey).to.be.instanceof(PublicKey);
43
47
  });
@@ -59,9 +63,9 @@ describe('SpacesService', () => {
59
63
  test('returns list of existing spaces', async () => {
60
64
  await serviceContext.createIdentity();
61
65
  const existingSpaces = [
62
- await spacesService.createSpace(),
63
- await spacesService.createSpace(),
64
- await spacesService.createSpace(),
66
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
67
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
68
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
65
69
  ];
66
70
 
67
71
  const query = spacesService.querySpaces();
@@ -87,7 +91,7 @@ describe('SpacesService', () => {
87
91
  expect(await result.wait()).to.be.length(0);
88
92
 
89
93
  result.reset();
90
- const space = await spacesService.createSpace();
94
+ const space = await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
91
95
  const spaces = await result.wait();
92
96
  expect(spaces).to.be.length(1);
93
97
  expect(spaces?.[0].spaceKey.equals(space.spaceKey)).to.be.true;