@dxos/client-services 0.8.4-main.937b3ca → 0.8.4-main.9be5663bfe

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 (123) hide show
  1. package/dist/lib/browser/{chunk-UDCUM4WV.mjs → chunk-CK3KJB3B.mjs} +1737 -1199
  2. package/dist/lib/browser/chunk-CK3KJB3B.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +33 -16
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +14 -7
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node-esm/{chunk-Q56HAUWS.mjs → chunk-WHBWCIEN.mjs} +1737 -1199
  9. package/dist/lib/node-esm/chunk-WHBWCIEN.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +33 -16
  11. package/dist/lib/node-esm/index.mjs.map +3 -3
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +14 -7
  14. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  15. package/dist/types/src/index.d.ts +1 -0
  16. package/dist/types/src/index.d.ts.map +1 -1
  17. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
  18. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  19. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  20. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  21. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  22. package/dist/types/src/packlets/identity/identity-manager.d.ts +3 -3
  23. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  24. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +5 -4
  25. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  26. package/dist/types/src/packlets/identity/identity-service.d.ts +1 -6
  27. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  28. package/dist/types/src/packlets/identity/identity.d.ts +6 -9
  29. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  30. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  31. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  32. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
  33. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  34. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  35. package/dist/types/src/packlets/logging/logging-service.d.ts +4 -0
  36. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  37. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  38. package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
  39. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  40. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  41. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  42. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  43. package/dist/types/src/packlets/services/service-context.d.ts +3 -4
  44. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  45. package/dist/types/src/packlets/services/service-host.d.ts +1 -1
  46. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  47. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  48. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  49. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +6 -0
  50. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  51. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  52. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  53. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +17 -10
  54. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  55. package/dist/types/src/packlets/spaces/data-space.d.ts +22 -6
  56. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  57. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  58. package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
  59. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  60. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  61. package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -2
  62. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  63. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  64. package/dist/types/src/packlets/worker/worker-runtime.d.ts +11 -3
  65. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  66. package/dist/types/src/version.d.ts +1 -1
  67. package/dist/types/src/version.d.ts.map +1 -1
  68. package/dist/types/tsconfig.tsbuildinfo +1 -1
  69. package/package.json +43 -43
  70. package/src/index.ts +1 -0
  71. package/src/packlets/agents/edge-agent-manager.ts +8 -5
  72. package/src/packlets/agents/edge-agent-service.ts +2 -1
  73. package/src/packlets/devices/devices-service.test.ts +0 -1
  74. package/src/packlets/devtools/devtools.ts +0 -1
  75. package/src/packlets/identity/contacts-service.ts +0 -1
  76. package/src/packlets/identity/identity-manager.test.ts +5 -5
  77. package/src/packlets/identity/identity-manager.ts +16 -13
  78. package/src/packlets/identity/identity-recovery-manager.ts +20 -16
  79. package/src/packlets/identity/identity-service.test.ts +6 -27
  80. package/src/packlets/identity/identity-service.ts +5 -76
  81. package/src/packlets/identity/identity.test.ts +2 -2
  82. package/src/packlets/identity/identity.ts +7 -30
  83. package/src/packlets/invitations/device-invitation-protocol.ts +0 -1
  84. package/src/packlets/invitations/edge-invitation-handler.ts +4 -3
  85. package/src/packlets/invitations/invitations-handler.test.ts +4 -5
  86. package/src/packlets/invitations/invitations-handler.ts +3 -3
  87. package/src/packlets/invitations/invitations-manager.ts +37 -14
  88. package/src/packlets/invitations/invitations-service.ts +4 -4
  89. package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
  90. package/src/packlets/invitations/space-invitation-protocol.ts +3 -2
  91. package/src/packlets/logging/logging-service.ts +4 -0
  92. package/src/packlets/network/network-service.test.ts +0 -1
  93. package/src/packlets/network/network-service.ts +5 -4
  94. package/src/packlets/services/feed-syncer.test.ts +340 -0
  95. package/src/packlets/services/feed-syncer.ts +337 -0
  96. package/src/packlets/services/platform.ts +7 -1
  97. package/src/packlets/services/service-context.test.ts +3 -2
  98. package/src/packlets/services/service-context.ts +105 -31
  99. package/src/packlets/services/service-host.test.ts +8 -8
  100. package/src/packlets/services/service-host.ts +10 -9
  101. package/src/packlets/services/service-registry.test.ts +0 -1
  102. package/src/packlets/space-export/space-archive-reader.ts +64 -3
  103. package/src/packlets/space-export/space-archive-writer.ts +36 -1
  104. package/src/packlets/space-export/space-archive.test.ts +287 -0
  105. package/src/packlets/spaces/data-space-manager.test.ts +79 -13
  106. package/src/packlets/spaces/data-space-manager.ts +71 -104
  107. package/src/packlets/spaces/data-space.ts +46 -24
  108. package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
  109. package/src/packlets/spaces/edge-feed-replicator.ts +8 -7
  110. package/src/packlets/spaces/epoch-migrations.ts +3 -3
  111. package/src/packlets/spaces/genesis.ts +6 -1
  112. package/src/packlets/spaces/notarization-plugin.ts +2 -1
  113. package/src/packlets/spaces/spaces-service.test.ts +9 -7
  114. package/src/packlets/spaces/spaces-service.ts +30 -9
  115. package/src/packlets/testing/invitation-utils.ts +3 -2
  116. package/src/packlets/worker/worker-runtime.ts +14 -7
  117. package/src/packlets/worker/worker-session.ts +4 -4
  118. package/src/version.ts +1 -1
  119. package/dist/lib/browser/chunk-UDCUM4WV.mjs.map +0 -7
  120. package/dist/lib/node-esm/chunk-Q56HAUWS.mjs.map +0 -7
  121. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  122. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  123. package/src/packlets/identity/default-space-state-machine.ts +0 -44
@@ -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
 
@@ -37,7 +37,7 @@ export const runEpochMigration = async (ctx: Context, context: MigrationContext)
37
37
  switch (context.migration) {
38
38
  case CreateEpochRequest.Migration.INIT_AUTOMERGE: {
39
39
  const document = await context.echoHost.createDoc();
40
- await context.echoHost.flush();
40
+ await context.echoHost.flush(ctx);
41
41
  return { newRoot: document.url };
42
42
  }
43
43
  case CreateEpochRequest.Migration.PRUNE_AUTOMERGE_ROOT_HISTORY: {
@@ -49,7 +49,7 @@ export const runEpochMigration = async (ctx: Context, context: MigrationContext)
49
49
  });
50
50
 
51
51
  const newRoot = await context.echoHost.createDoc(rootHandle.doc());
52
- await context.echoHost.flush();
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
 
@@ -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
 
@@ -8,10 +8,10 @@ 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
13
  import { type ServiceContext } from '../services';
13
14
  import { createServiceContext } from '../testing';
14
-
15
15
  import { SpacesServiceImpl } from './spaces-service';
16
16
 
17
17
  describe('SpacesService', () => {
@@ -33,12 +33,14 @@ describe('SpacesService', () => {
33
33
 
34
34
  describe('createSpace', () => {
35
35
  test('fails if no identity is available', async () => {
36
- await expect(spacesService.createSpace()).rejects.toBeInstanceOf(Error);
36
+ await expect(spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE })).rejects.toBeInstanceOf(
37
+ Error,
38
+ );
37
39
  });
38
40
 
39
41
  test('creates a new space', async () => {
40
42
  await serviceContext.createIdentity();
41
- const space = await spacesService.createSpace();
43
+ const space = await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
42
44
  expect(space).to.exist;
43
45
  expect(space.spaceKey).to.be.instanceof(PublicKey);
44
46
  });
@@ -60,9 +62,9 @@ describe('SpacesService', () => {
60
62
  test('returns list of existing spaces', async () => {
61
63
  await serviceContext.createIdentity();
62
64
  const existingSpaces = [
63
- await spacesService.createSpace(),
64
- await spacesService.createSpace(),
65
- await spacesService.createSpace(),
65
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
66
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
67
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
66
68
  ];
67
69
 
68
70
  const query = spacesService.querySpaces();
@@ -88,7 +90,7 @@ describe('SpacesService', () => {
88
90
  expect(await result.wait()).to.be.length(0);
89
91
 
90
92
  result.reset();
91
- const space = await spacesService.createSpace();
93
+ const space = await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
92
94
  const spaces = await result.wait();
93
95
  expect(spaces).to.be.length(1);
94
96
  expect(spaces?.[0].spaceKey.equals(space.spaceKey)).to.be.true;
@@ -6,6 +6,7 @@ import type { AutomergeUrl } from '@automerge/automerge-repo';
6
6
 
7
7
  import { SubscriptionList, UpdateScheduler, scheduleTask } from '@dxos/async';
8
8
  import { Stream } from '@dxos/codec-protobuf/stream';
9
+ import { Context } from '@dxos/context';
9
10
  import {
10
11
  type CredentialProcessor,
11
12
  createAdmissionCredentials,
@@ -45,6 +46,7 @@ import {
45
46
  type SpacesService,
46
47
  type SubscribeMessagesRequest,
47
48
  type UpdateMemberRoleRequest,
49
+ type CreateSpaceRequest,
48
50
  type UpdateSpaceRequest,
49
51
  type WriteCredentialsRequest,
50
52
  } from '@dxos/protocols/proto/dxos/client/services';
@@ -55,7 +57,6 @@ import { type Provider } from '@dxos/util';
55
57
 
56
58
  import { type IdentityManager } from '../identity';
57
59
  import { SpaceArchiveWriter, extractSpaceArchive } from '../space-export';
58
-
59
60
  import { type DataSpace } from './data-space';
60
61
  import { type DataSpaceManager } from './data-space-manager';
61
62
 
@@ -66,10 +67,13 @@ export class SpacesServiceImpl implements SpacesService {
66
67
  private readonly _getDataSpaceManager: Provider<Promise<DataSpaceManager>>,
67
68
  ) {}
68
69
 
69
- async createSpace(): Promise<Space> {
70
+ async createSpace(request: CreateSpaceRequest): Promise<Space> {
70
71
  this._requireIdentity();
71
72
  const dataSpaceManager = await this._getDataSpaceManager();
72
- const space = await dataSpaceManager.createSpace();
73
+ const space = await dataSpaceManager.createSpace(new Context(), {
74
+ tags: request?.tags,
75
+ membershipPolicy: request?.membershipPolicy,
76
+ });
73
77
  await this._updateMetrics();
74
78
  return this._serializeSpace(space);
75
79
  }
@@ -81,11 +85,11 @@ export class SpacesServiceImpl implements SpacesService {
81
85
  if (state) {
82
86
  switch (state) {
83
87
  case SpaceState.SPACE_ACTIVE:
84
- await space.activate();
88
+ await space.activate(Context.default());
85
89
  break;
86
90
 
87
91
  case SpaceState.SPACE_INACTIVE:
88
- await space.deactivate();
92
+ await space.deactivate(Context.default());
89
93
  break;
90
94
  default:
91
95
  throw new ApiError({ message: 'Invalid space state' });
@@ -93,7 +97,7 @@ export class SpacesServiceImpl implements SpacesService {
93
97
  }
94
98
 
95
99
  if (edgeReplication !== undefined) {
96
- await dataSpaceManager.setSpaceEdgeReplicationSetting(spaceKey, edgeReplication);
100
+ await dataSpaceManager.setSpaceEdgeReplicationSetting(Context.default(), spaceKey, edgeReplication);
97
101
  }
98
102
  }
99
103
 
@@ -264,7 +268,7 @@ export class SpacesServiceImpl implements SpacesService {
264
268
 
265
269
  async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest): Promise<JoinSpaceResponse> {
266
270
  const dataSpaceManager = await this._getDataSpaceManager();
267
- const credential = await dataSpaceManager.requestSpaceAdmissionCredential(spaceKey);
271
+ const credential = await dataSpaceManager.requestSpaceAdmissionCredential(Context.default(), spaceKey);
268
272
  return this._joinByAdmission({ credential });
269
273
  }
270
274
 
@@ -283,6 +287,20 @@ export class SpacesServiceImpl implements SpacesService {
283
287
  await writer.writeDocument(documentId, data);
284
288
  }
285
289
 
290
+ const feeds = await space.getAllFeeds();
291
+ for (const feed of feeds) {
292
+ const archiveBlocks = feed.blocks.map((block) => ({
293
+ actorId: block.actorId,
294
+ sequence: block.sequence,
295
+ prevActorId: block.prevActorId,
296
+ prevSequence: block.prevSequence,
297
+ position: block.position,
298
+ timestamp: block.timestamp,
299
+ data: Buffer.from(block.data).toString('base64'),
300
+ }));
301
+ await writer.writeFeed(feed.feedId, feed.feedNamespace, archiveBlocks);
302
+ }
303
+
286
304
  const archive = await writer.finish();
287
305
  return { archive };
288
306
  }
@@ -291,7 +309,7 @@ export class SpacesServiceImpl implements SpacesService {
291
309
  const dataSpaceManager = await this._getDataSpaceManager();
292
310
  const extracted = await extractSpaceArchive(request.archive);
293
311
  invariant(extracted.metadata.echo?.currentRootUrl, 'Space archive does not contain a root URL');
294
- const space = await dataSpaceManager.createSpace({
312
+ const space = await dataSpaceManager.createSpace(Context.default(), {
295
313
  documents: extracted.documents,
296
314
  rootUrl: extracted.metadata.echo?.currentRootUrl as AutomergeUrl,
297
315
  });
@@ -308,9 +326,10 @@ export class SpacesServiceImpl implements SpacesService {
308
326
  const dataSpaceManager = await this._getDataSpaceManager();
309
327
  let dataSpace = dataSpaceManager.spaces.get(assertion.spaceKey);
310
328
  if (!dataSpace) {
311
- dataSpace = await dataSpaceManager.acceptSpace({
329
+ dataSpace = await dataSpaceManager.acceptSpace(Context.default(), {
312
330
  spaceKey: assertion.spaceKey,
313
331
  genesisFeedKey: assertion.genesisFeedKey,
332
+ tags: assertion.tags,
314
333
  });
315
334
  await myIdentity.controlPipeline.writer.write({ credential: { credential } });
316
335
  }
@@ -363,6 +382,8 @@ export class SpacesServiceImpl implements SpacesService {
363
382
  }),
364
383
  ),
365
384
  creator: space.inner.spaceState.creator?.key,
385
+ tags: space.tags,
386
+ membershipPolicy: space.membershipPolicy,
366
387
  cache: space.cache,
367
388
  metrics: space.metrics,
368
389
  edgeReplication: space.getEdgeReplicationSetting(),
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { Trigger } from '@dxos/async';
6
6
  import { type AuthenticatingInvitation, type CancellableInvitation, InvitationEncoder } from '@dxos/client-protocol';
7
+ import { Context } from '@dxos/context';
7
8
  import { invariant } from '@dxos/invariant';
8
9
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
9
10
  import { type DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
@@ -229,7 +230,7 @@ export const createInvitation = async (
229
230
  };
230
231
 
231
232
  if (host instanceof ServiceContext) {
232
- return host.invitationsManager.createInvitation({
233
+ return host.invitationsManager.createInvitation(new Context(), {
233
234
  kind: Invitation.Kind.SPACE,
234
235
  ...options,
235
236
  });
@@ -246,7 +247,7 @@ export const acceptInvitation = (
246
247
  invitation = sanitizeInvitation(invitation);
247
248
 
248
249
  if (guest instanceof ServiceContext) {
249
- return guest.invitationsManager.acceptInvitation({
250
+ return guest.invitationsManager.acceptInvitation(new Context(), {
250
251
  invitation,
251
252
  deviceProfile: guestDeviceProfile,
252
253
  });
@@ -29,7 +29,6 @@ import * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
29
29
  import { type MaybePromise } from '@dxos/util';
30
30
 
31
31
  import { ClientServicesHost } from '../services';
32
-
33
32
  import { WorkerSession } from './worker-session';
34
33
 
35
34
  // NOTE: Keep as RpcPorts to avoid dependency on @dxos/rpc-tunnel so we don't depend on browser-specific apis.
@@ -37,6 +36,7 @@ export type CreateSessionProps = {
37
36
  appPort: RpcPort;
38
37
  systemPort: RpcPort;
39
38
  shellPort?: RpcPort;
39
+ onClose?: () => Promise<void>;
40
40
  };
41
41
 
42
42
  export type WorkerRuntimeOptions = {
@@ -50,7 +50,11 @@ export type WorkerRuntimeOptions = {
50
50
  */
51
51
  automaticallyConnectWebrtc?: boolean;
52
52
 
53
- enableSqlite?: boolean;
53
+ /**
54
+ * Optional SQLite layer for Effect. Defaults to LocalSqliteOpfsLayer.
55
+ * For testing in Node.js, use `sqliteLayerMemory` from `@dxos/sql-sqlite/platform`.
56
+ */
57
+ sqliteLayer?: Layer.Layer<SqlClient.SqlClient | SqlExport.SqlExport, unknown>;
54
58
  };
55
59
 
56
60
  /**
@@ -87,16 +91,19 @@ export class WorkerRuntime {
87
91
  releaseLock,
88
92
  onStop,
89
93
  automaticallyConnectWebrtc = true,
90
- enableSqlite,
94
+ sqliteLayer,
91
95
  }: WorkerRuntimeOptions) {
92
96
  this._configProvider = configProvider;
93
97
  this._acquireLock = acquireLock;
94
98
  this._releaseLock = releaseLock;
95
99
  this._onStop = onStop;
96
100
  this._channel = channel;
101
+ if (sqliteLayer) {
102
+ log.warn('Using testing SQLite layer');
103
+ }
97
104
  this._runtime = ManagedRuntime.make(
98
105
  SqlTransaction.layer
99
- .pipe(Layer.provideMerge(LocalSqliteOpfsLayer), Layer.provideMerge(Reactivity.layer))
106
+ .pipe(Layer.provideMerge(sqliteLayer ?? LocalSqliteOpfsLayer), Layer.provideMerge(Reactivity.layer))
100
107
  .pipe(Layer.orDie),
101
108
  );
102
109
  this._clientServices = new ClientServicesHost({
@@ -105,7 +112,6 @@ export class WorkerRuntime {
105
112
  },
106
113
  runtime: this._runtime.runtimeEffect,
107
114
  runtimeProps: {
108
- enableSqlite,
109
115
  // Auto-activate spaces that were previously active after leader changeover.
110
116
  autoActivateSpaces: true,
111
117
  },
@@ -169,7 +175,7 @@ export class WorkerRuntime {
169
175
  this._releaseLock();
170
176
  this._broadcastChannel?.close();
171
177
  this._broadcastChannel = undefined;
172
- await this._clientServices.close();
178
+ await this._clientServices.close(Context.default());
173
179
  await this._runtime.dispose();
174
180
  await this._onStop?.();
175
181
  await this._livenessLock.release();
@@ -178,7 +184,7 @@ export class WorkerRuntime {
178
184
  /**
179
185
  * Create a new session.
180
186
  */
181
- async createSession({ appPort, systemPort, shellPort }: CreateSessionProps): Promise<WorkerSession> {
187
+ async createSession({ appPort, systemPort, shellPort, onClose }: CreateSessionProps): Promise<WorkerSession> {
182
188
  const session = new WorkerSession({
183
189
  serviceHost: this._clientServices,
184
190
  appPort,
@@ -198,6 +204,7 @@ export class WorkerRuntime {
198
204
  this._reconnectWebrtc();
199
205
  }
200
206
  }
207
+ await onClose?.();
201
208
  });
202
209
 
203
210
  await session.open();
@@ -119,7 +119,7 @@ export class WorkerSession {
119
119
  }
120
120
 
121
121
  async open(): Promise<void> {
122
- log.info('opening...');
122
+ log('opening...');
123
123
  await Promise.all([this._clientRpc.open(), this._iframeRpc.open(), this._maybeOpenShell()]);
124
124
 
125
125
  // Wait until the worker's RPC service has started.
@@ -130,11 +130,11 @@ export class WorkerSession {
130
130
  void this._afterLockReleases(this.lockKey, () => this.close());
131
131
  }
132
132
 
133
- log.info('opened');
133
+ log('opened');
134
134
  }
135
135
 
136
136
  async close(): Promise<void> {
137
- log.info('closing...');
137
+ log.debug('closing...');
138
138
  try {
139
139
  await this.onClose.callIfSet();
140
140
  } catch (err: any) {
@@ -142,7 +142,7 @@ export class WorkerSession {
142
142
  }
143
143
 
144
144
  await Promise.all([this._clientRpc.close(), this._iframeRpc.close()]);
145
- log.info('closed');
145
+ log.debug('closed');
146
146
  }
147
147
 
148
148
  private async _maybeOpenShell(): Promise<void> {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const DXOS_VERSION = "0.8.4-main.937b3ca";
1
+ export const DXOS_VERSION = "0.8.4-main.9be5663bfe";