@dxos/client-services 0.5.9-main.2dbe289 → 0.5.9-main.405fda7

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 (41) hide show
  1. package/dist/lib/browser/{chunk-QWL2M4EU.mjs → chunk-NBUF5LMA.mjs} +743 -605
  2. package/dist/lib/browser/chunk-NBUF5LMA.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1 -1
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/packlets/testing/index.mjs +11 -11
  6. package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
  7. package/dist/lib/node/{chunk-NPYJIVOX.cjs → chunk-CMHCDXY6.cjs} +959 -825
  8. package/dist/lib/node/chunk-CMHCDXY6.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +42 -42
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/packlets/testing/index.cjs +17 -17
  12. package/dist/lib/node/packlets/testing/index.cjs.map +3 -3
  13. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +19 -0
  14. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +1 -0
  15. package/dist/types/src/packlets/identity/identity-service.d.ts +14 -7
  16. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  17. package/dist/types/src/packlets/identity/identity.d.ts +4 -1
  18. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  19. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  20. package/dist/types/src/packlets/services/service-host.d.ts +1 -1
  21. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  22. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +5 -3
  23. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  24. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  25. package/dist/types/src/packlets/testing/test-builder.d.ts +8 -6
  26. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  27. package/dist/types/src/version.d.ts +1 -1
  28. package/package.json +36 -36
  29. package/src/packlets/identity/default-space-state-machine.ts +44 -0
  30. package/src/packlets/identity/identity-service.test.ts +35 -5
  31. package/src/packlets/identity/identity-service.ts +50 -8
  32. package/src/packlets/identity/identity.ts +25 -2
  33. package/src/packlets/services/service-context.ts +1 -4
  34. package/src/packlets/services/service-host.ts +13 -40
  35. package/src/packlets/spaces/data-space-manager.test.ts +46 -1
  36. package/src/packlets/spaces/data-space-manager.ts +54 -25
  37. package/src/packlets/spaces/data-space.ts +9 -5
  38. package/src/packlets/testing/test-builder.ts +12 -10
  39. package/src/version.ts +1 -1
  40. package/dist/lib/browser/chunk-QWL2M4EU.mjs.map +0 -7
  41. package/dist/lib/node/chunk-NPYJIVOX.cjs.map +0 -7
@@ -4,7 +4,8 @@
4
4
 
5
5
  import { Event, synchronized, trackLeaks } from '@dxos/async';
6
6
  import { type Doc } from '@dxos/automerge/automerge';
7
- import { type AutomergeUrl } from '@dxos/automerge/automerge-repo';
7
+ import { type DocHandle, type AutomergeUrl } from '@dxos/automerge/automerge-repo';
8
+ import { PropertiesType } from '@dxos/client-protocol';
8
9
  import { cancelWithContext, Context } from '@dxos/context';
9
10
  import {
10
11
  type CredentialSigner,
@@ -21,7 +22,8 @@ import {
21
22
  type SpaceProtocol,
22
23
  type SpaceProtocolSession,
23
24
  } from '@dxos/echo-pipeline';
24
- import { type SpaceDoc } from '@dxos/echo-protocol';
25
+ import { encodeReference, type ObjectStructure, type SpaceDoc } from '@dxos/echo-protocol';
26
+ import { generateEchoId, getTypeReference } from '@dxos/echo-schema';
25
27
  import { type FeedStore } from '@dxos/feed-store';
26
28
  import { invariant } from '@dxos/invariant';
27
29
  import { type Keyring } from '@dxos/keyring';
@@ -37,7 +39,7 @@ import { type PeerState } from '@dxos/protocols/proto/dxos/mesh/presence';
37
39
  import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
38
40
  import { type Timeframe } from '@dxos/timeframe';
39
41
  import { trace } from '@dxos/tracing';
40
- import { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';
42
+ import { assignDeep, ComplexMap, deferFunction, forEachAsync } from '@dxos/util';
41
43
 
42
44
  import { DataSpace, findPropertiesObject } from './data-space';
43
45
  import { spaceGenesis } from './genesis';
@@ -47,6 +49,9 @@ import { type InvitationsManager } from '../invitations';
47
49
  const PRESENCE_ANNOUNCE_INTERVAL = 10_000;
48
50
  const PRESENCE_OFFLINE_TIMEOUT = 20_000;
49
51
 
52
+ // Space properties key for default metadata.
53
+ const DEFAULT_SPACE_KEY = '__DEFAULT__';
54
+
50
55
  export interface SigningContext {
51
56
  identityKey: PublicKey;
52
57
  deviceKey: PublicKey;
@@ -88,8 +93,6 @@ export class DataSpaceManager {
88
93
 
89
94
  private _isOpen = false;
90
95
  private readonly _instanceId = PublicKey.random().toHex();
91
- private readonly _spaceMemberPresenceAnnounceInterval: number;
92
- private readonly _spaceMemberPresenceOfflineTimeout: number;
93
96
 
94
97
  constructor(
95
98
  private readonly _spaceManager: SpaceManager,
@@ -99,15 +102,8 @@ export class DataSpaceManager {
99
102
  private readonly _feedStore: FeedStore<FeedMessage>,
100
103
  private readonly _echoHost: EchoHost,
101
104
  private readonly _invitationsManager: InvitationsManager,
102
- params?: DataSpaceManagerRuntimeParams,
105
+ private readonly _params?: DataSpaceManagerRuntimeParams,
103
106
  ) {
104
- const {
105
- spaceMemberPresenceAnnounceInterval = PRESENCE_ANNOUNCE_INTERVAL,
106
- spaceMemberPresenceOfflineTimeout = PRESENCE_OFFLINE_TIMEOUT,
107
- } = params ?? {};
108
- this._spaceMemberPresenceAnnounceInterval = spaceMemberPresenceAnnounceInterval;
109
- this._spaceMemberPresenceOfflineTimeout = spaceMemberPresenceOfflineTimeout;
110
-
111
107
  trace.diagnostic({
112
108
  id: 'spaces',
113
109
  name: 'Spaces',
@@ -157,12 +153,6 @@ export class DataSpaceManager {
157
153
  this._isOpen = true;
158
154
  this.updated.emit();
159
155
 
160
- for (const space of this._spaces.values()) {
161
- if (space.state !== SpaceState.INACTIVE) {
162
- space.initializeDataPipelineAsync();
163
- }
164
- }
165
-
166
156
  log.trace('dxos.echo.data-space-manager.open', Trace.end({ id: this._instanceId }));
167
157
  }
168
158
 
@@ -174,6 +164,7 @@ export class DataSpaceManager {
174
164
  for (const space of this._spaces.values()) {
175
165
  await space.close();
176
166
  }
167
+ this._spaces.clear();
177
168
  }
178
169
 
179
170
  /**
@@ -197,6 +188,7 @@ export class DataSpaceManager {
197
188
 
198
189
  const root = await this._echoHost.createSpaceRoot(spaceKey);
199
190
  const space = await this._constructSpace(metadata);
191
+ await space.open();
200
192
 
201
193
  const credentials = await spaceGenesis(this._keyring, this._signingContext, space.inner, root.url);
202
194
  await this._metadataStore.addSpace(metadata);
@@ -211,6 +203,46 @@ export class DataSpaceManager {
211
203
  return space;
212
204
  }
213
205
 
206
+ async isDefaultSpace(space: DataSpace): Promise<boolean> {
207
+ const rootDoc = await this._getSpaceRootDocument(space);
208
+ const [_, properties] = findPropertiesObject(rootDoc.docSync()) ?? [];
209
+ return properties?.data?.[DEFAULT_SPACE_KEY] === this._signingContext.identityKey.toHex();
210
+ }
211
+
212
+ async createDefaultSpace() {
213
+ const space = await this.createSpace();
214
+ const document = await this._getSpaceRootDocument(space);
215
+
216
+ // TODO(dmaretskyi): Better API for low-level data access.
217
+ const properties: ObjectStructure = {
218
+ system: {
219
+ type: encodeReference(getTypeReference(PropertiesType)!),
220
+ },
221
+ data: {
222
+ [DEFAULT_SPACE_KEY]: this._signingContext.identityKey.toHex(),
223
+ },
224
+ meta: {
225
+ keys: [],
226
+ },
227
+ };
228
+
229
+ const propertiesId = generateEchoId();
230
+ document.change((doc: SpaceDoc) => {
231
+ assignDeep(doc, ['objects', propertiesId], properties);
232
+ });
233
+
234
+ await this._echoHost.flush();
235
+ return space;
236
+ }
237
+
238
+ private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<SpaceDoc>> {
239
+ const automergeIndex = space.automergeSpaceState.rootUrl;
240
+ invariant(automergeIndex);
241
+ const document = this._echoHost.automergeRepo.find<SpaceDoc>(automergeIndex as any);
242
+ await document.whenReady();
243
+ return document;
244
+ }
245
+
214
246
  // TODO(burdon): Rename join space.
215
247
  @synchronized
216
248
  async acceptSpace(opts: AcceptSpaceOptions): Promise<DataSpace> {
@@ -226,6 +258,7 @@ export class DataSpaceManager {
226
258
  };
227
259
 
228
260
  const space = await this._constructSpace(metadata);
261
+ await space.open();
229
262
  await this._metadataStore.addSpace(metadata);
230
263
  space.initializeDataPipelineAsync();
231
264
 
@@ -254,8 +287,8 @@ export class DataSpaceManager {
254
287
  localPeerId: this._signingContext.deviceKey,
255
288
  });
256
289
  const presence = new Presence({
257
- announceInterval: this._spaceMemberPresenceAnnounceInterval,
258
- offlineTimeout: this._spaceMemberPresenceOfflineTimeout,
290
+ announceInterval: this._params?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,
291
+ offlineTimeout: this._params?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,
259
292
  identityKey: this._signingContext.identityKey,
260
293
  gossip,
261
294
  });
@@ -336,10 +369,6 @@ export class DataSpaceManager {
336
369
  }
337
370
  });
338
371
 
339
- if (metadata.state !== SpaceState.INACTIVE) {
340
- await dataSpace.open();
341
- }
342
-
343
372
  if (metadata.controlTimeframe) {
344
373
  dataSpace.inner.controlPipeline.state.setTargetTimeframe(metadata.controlTimeframe);
345
374
  }
@@ -193,10 +193,13 @@ export class DataSpace {
193
193
 
194
194
  @synchronized
195
195
  async open() {
196
- await this._open();
196
+ if (this._state === SpaceState.CLOSED) {
197
+ await this._open();
198
+ }
197
199
  }
198
200
 
199
201
  private async _open() {
202
+ await this._presence.open();
200
203
  await this._gossip.open();
201
204
  await this._notarizationPlugin.open();
202
205
  await this._inner.spaceState.addCredentialProcessor(this._notarizationPlugin);
@@ -228,7 +231,7 @@ export class DataSpace {
228
231
  await this._inner.spaceState.removeCredentialProcessor(this._notarizationPlugin);
229
232
  await this._notarizationPlugin.close();
230
233
 
231
- await this._presence.destroy();
234
+ await this._presence.close();
232
235
  await this._gossip.close();
233
236
  }
234
237
 
@@ -545,7 +548,7 @@ export class DataSpace {
545
548
 
546
549
  @synchronized
547
550
  async activate() {
548
- if (this._state !== SpaceState.INACTIVE) {
551
+ if (![SpaceState.CLOSED, SpaceState.INACTIVE].includes(this._state)) {
549
552
  return;
550
553
  }
551
554
 
@@ -559,10 +562,11 @@ export class DataSpace {
559
562
  if (this._state === SpaceState.INACTIVE) {
560
563
  return;
561
564
  }
562
-
563
565
  // Unregister from data service.
564
566
  await this._metadataStore.setSpaceState(this.key, SpaceState.INACTIVE);
565
- await this._close();
567
+ if (this._state !== SpaceState.CLOSED) {
568
+ await this._close();
569
+ }
566
570
  this._state = SpaceState.INACTIVE;
567
571
  log('new state', { state: SpaceState[this._state] });
568
572
  this.stateUpdate.emit();
@@ -19,8 +19,8 @@ import { createStorage, StorageType, type Storage } from '@dxos/random-access-st
19
19
  import { BlobStore } from '@dxos/teleport-extension-object-sync';
20
20
 
21
21
  import { InvitationsHandler, InvitationsManager, SpaceInvitationProtocol } from '../invitations';
22
- import { ClientServicesHost, ServiceContext } from '../services';
23
- import { DataSpaceManager, type SigningContext } from '../spaces';
22
+ import { ClientServicesHost, ServiceContext, type ServiceContextRuntimeParams } from '../services';
23
+ import { DataSpaceManager, type DataSpaceManagerRuntimeParams, type SigningContext } from '../spaces';
24
24
 
25
25
  //
26
26
  // TODO(burdon): Replace with test builder.
@@ -37,9 +37,11 @@ export const createServiceHost = (config: Config, signalManagerContext: MemorySi
37
37
  export const createServiceContext = async ({
38
38
  signalContext = new MemorySignalManagerContext(),
39
39
  storage = createStorage({ type: StorageType.RAM }),
40
+ runtimeParams,
40
41
  }: {
41
42
  signalContext?: MemorySignalManagerContext;
42
43
  storage?: Storage;
44
+ runtimeParams?: ServiceContextRuntimeParams;
43
45
  } = {}) => {
44
46
  const signalManager = new MemorySignalManager(signalContext);
45
47
  const networkManager = new SwarmNetworkManager({
@@ -51,6 +53,7 @@ export const createServiceContext = async ({
51
53
 
52
54
  return new ServiceContext(storage, level, networkManager, signalManager, {
53
55
  invitationConnectionDefaultParams: { controlHeartbeatInterval: 200 },
56
+ ...runtimeParams,
54
57
  });
55
58
  };
56
59
 
@@ -88,6 +91,7 @@ export class TestBuilder {
88
91
 
89
92
  export type TestPeerOpts = {
90
93
  dataStore?: StorageType;
94
+ dataSpaceParams?: DataSpaceManagerRuntimeParams;
91
95
  };
92
96
 
93
97
  export type TestPeerProps = {
@@ -110,8 +114,8 @@ export class TestPeer {
110
114
  private _props: TestPeerProps = {};
111
115
 
112
116
  constructor(
113
- private readonly signalContext: MemorySignalManagerContext,
114
- private readonly opts: TestPeerOpts = { dataStore: StorageType.RAM },
117
+ private readonly _signalContext: MemorySignalManagerContext,
118
+ private readonly _opts: TestPeerOpts = { dataStore: StorageType.RAM },
115
119
  ) {}
116
120
 
117
121
  get props() {
@@ -119,7 +123,7 @@ export class TestPeer {
119
123
  }
120
124
 
121
125
  get storage() {
122
- return (this._props.storage ??= createStorage({ type: this.opts.dataStore }));
126
+ return (this._props.storage ??= createStorage({ type: this._opts.dataStore }));
123
127
  }
124
128
 
125
129
  get keyring() {
@@ -156,7 +160,7 @@ export class TestPeer {
156
160
 
157
161
  get networkManager() {
158
162
  return (this._props.networkManager ??= new SwarmNetworkManager({
159
- signalManager: new MemorySignalManager(this.signalContext),
163
+ signalManager: new MemorySignalManager(this._signalContext),
160
164
  transportFactory: MemoryTransportFactory,
161
165
  }));
162
166
  }
@@ -176,10 +180,7 @@ export class TestPeer {
176
180
  }
177
181
 
178
182
  get echoHost() {
179
- return (this._props.echoHost ??= new EchoHost({
180
- kv: this.level,
181
- storage: this.storage,
182
- }));
183
+ return (this._props.echoHost ??= new EchoHost({ kv: this.level }));
183
184
  }
184
185
 
185
186
  get dataSpaceManager(): DataSpaceManager {
@@ -191,6 +192,7 @@ export class TestPeer {
191
192
  this.feedStore,
192
193
  this.echoHost,
193
194
  this.invitationsManager,
195
+ this._opts.dataSpaceParams,
194
196
  ));
195
197
  }
196
198
 
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const DXOS_VERSION = "0.5.9-main.2dbe289";
1
+ export const DXOS_VERSION = "0.5.9-main.405fda7";