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

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 (163) hide show
  1. package/dist/lib/browser/{chunk-CK3KJB3B.mjs → chunk-KW4WMU5R.mjs} +1310 -3084
  2. package/dist/lib/browser/chunk-KW4WMU5R.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-NQSC7HOE.mjs → chunk-XJRPB3GA.mjs} +1 -1
  4. package/dist/lib/browser/index.mjs +100 -197
  5. package/dist/lib/browser/index.mjs.map +3 -3
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +1 -6
  8. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +2 -2
  9. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +1 -1
  10. package/dist/lib/browser/packlets/locks/browser.mjs +9 -49
  11. package/dist/lib/browser/packlets/locks/browser.mjs.map +2 -2
  12. package/dist/lib/browser/packlets/locks/node.mjs +4 -22
  13. package/dist/lib/browser/packlets/locks/node.mjs.map +2 -2
  14. package/dist/lib/browser/testing/index.mjs +7 -27
  15. package/dist/lib/browser/testing/index.mjs.map +2 -2
  16. package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs → chunk-2DT3MZRL.mjs} +1 -1
  17. package/dist/lib/node-esm/{chunk-WHBWCIEN.mjs → chunk-NDMKP2CH.mjs} +1310 -3084
  18. package/dist/lib/node-esm/chunk-NDMKP2CH.mjs.map +7 -0
  19. package/dist/lib/node-esm/index.mjs +100 -197
  20. package/dist/lib/node-esm/index.mjs.map +3 -3
  21. package/dist/lib/node-esm/meta.json +1 -1
  22. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +1 -6
  23. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +2 -2
  24. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +1 -1
  25. package/dist/lib/node-esm/packlets/locks/browser.mjs +9 -49
  26. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +2 -2
  27. package/dist/lib/node-esm/packlets/locks/node.mjs +4 -22
  28. package/dist/lib/node-esm/packlets/locks/node.mjs.map +2 -2
  29. package/dist/lib/node-esm/testing/index.mjs +7 -27
  30. package/dist/lib/node-esm/testing/index.mjs.map +2 -2
  31. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  32. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
  33. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  34. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  35. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  36. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  37. package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
  38. package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
  39. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  40. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  41. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  42. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  43. package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
  44. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
  45. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  46. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  47. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  48. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  49. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +2 -2
  50. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  51. package/dist/types/src/packlets/identity/identity-service.d.ts +6 -5
  52. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  53. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  54. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +2 -1
  55. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  56. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
  57. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  58. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  59. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  60. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +5 -1
  61. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  62. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
  63. package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
  64. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  65. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +1 -1
  66. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  67. package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
  68. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  69. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +2 -1
  70. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  71. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  72. package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
  73. package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
  74. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  75. package/dist/types/src/packlets/network/network-service.d.ts +5 -4
  76. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  77. package/dist/types/src/packlets/services/client-rpc-server.d.ts +3 -3
  78. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  79. package/dist/types/src/packlets/services/feed-syncer.d.ts +1 -1
  80. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -1
  81. package/dist/types/src/packlets/services/service-context.d.ts +1 -2
  82. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  83. package/dist/types/src/packlets/services/service-host.d.ts +1 -2
  84. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  85. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  86. package/dist/types/src/packlets/services/util.d.ts.map +1 -1
  87. package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
  88. package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
  89. package/dist/types/src/packlets/space-export/index.d.ts +4 -1
  90. package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
  91. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
  92. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
  93. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
  94. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
  95. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  96. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +1 -1
  97. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  98. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  99. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +1 -2
  100. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  101. package/dist/types/src/packlets/spaces/data-space.d.ts +2 -1
  102. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  103. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  104. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
  105. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  106. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +1 -4
  107. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  108. package/dist/types/src/packlets/spaces/spaces-service.d.ts +9 -6
  109. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  110. package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
  111. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  112. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  113. package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
  114. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  115. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  116. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
  117. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  118. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  119. package/dist/types/src/packlets/worker/worker-runtime.d.ts +11 -1
  120. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  121. package/dist/types/src/packlets/worker/worker-session.d.ts +0 -2
  122. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  123. package/dist/types/src/testing/setup.d.ts.map +1 -1
  124. package/dist/types/src/version.d.ts +1 -1
  125. package/dist/types/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +39 -46
  127. package/src/packlets/agents/edge-agent-service.ts +3 -2
  128. package/src/packlets/diagnostics/diagnostics.ts +1 -2
  129. package/src/packlets/identity/identity-manager.ts +2 -4
  130. package/src/packlets/identity/identity-service.ts +12 -9
  131. package/src/packlets/identity/identity.ts +2 -2
  132. package/src/packlets/invitations/device-invitation-protocol.ts +3 -1
  133. package/src/packlets/invitations/edge-invitation-handler.ts +5 -2
  134. package/src/packlets/invitations/invitation-host-extension.ts +7 -10
  135. package/src/packlets/invitations/invitation-protocol.ts +5 -1
  136. package/src/packlets/invitations/invitation-state.ts +1 -15
  137. package/src/packlets/invitations/invitations-handler.ts +64 -12
  138. package/src/packlets/invitations/invitations-manager.ts +6 -4
  139. package/src/packlets/invitations/invitations-service.ts +6 -6
  140. package/src/packlets/invitations/space-invitation-protocol.ts +3 -3
  141. package/src/packlets/logging/logging-service.ts +15 -15
  142. package/src/packlets/network/network-service.ts +9 -8
  143. package/src/packlets/services/client-rpc-server.ts +15 -12
  144. package/src/packlets/services/service-context.ts +12 -15
  145. package/src/packlets/services/service-host.ts +8 -19
  146. package/src/packlets/space-export/archive-format.ts +42 -0
  147. package/src/packlets/space-export/index.ts +4 -1
  148. package/src/packlets/space-export/serialized-space-reader.ts +111 -0
  149. package/src/packlets/space-export/serialized-space-writer.ts +253 -0
  150. package/src/packlets/space-export/space-archive-writer.ts +2 -1
  151. package/src/packlets/space-export/space-archive.test.ts +175 -1
  152. package/src/packlets/spaces/data-space-manager.ts +17 -19
  153. package/src/packlets/spaces/data-space.ts +9 -7
  154. package/src/packlets/spaces/edge-feed-replicator.ts +1 -0
  155. package/src/packlets/spaces/spaces-service.test.ts +9 -4
  156. package/src/packlets/spaces/spaces-service.ts +91 -16
  157. package/src/packlets/worker/worker-runtime.ts +38 -4
  158. package/src/packlets/worker/worker-session.ts +4 -10
  159. package/src/version.ts +1 -1
  160. package/dist/lib/browser/chunk-CK3KJB3B.mjs.map +0 -7
  161. package/dist/lib/node-esm/chunk-WHBWCIEN.mjs.map +0 -7
  162. /package/dist/lib/browser/{chunk-NQSC7HOE.mjs.map → chunk-XJRPB3GA.mjs.map} +0 -0
  163. /package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs.map → chunk-2DT3MZRL.mjs.map} +0 -0
@@ -5,6 +5,7 @@
5
5
  import type { AutomergeUrl } from '@automerge/automerge-repo';
6
6
 
7
7
  import { SubscriptionList, UpdateScheduler, scheduleTask } from '@dxos/async';
8
+ import { type RequestOptions } from '@dxos/codec-protobuf';
8
9
  import { Stream } from '@dxos/codec-protobuf/stream';
9
10
  import { Context } from '@dxos/context';
10
11
  import {
@@ -14,7 +15,8 @@ import {
14
15
  getCredentialAssertion,
15
16
  } from '@dxos/credentials';
16
17
  import { raise } from '@dxos/debug';
17
- import { type SpaceManager } from '@dxos/echo-pipeline';
18
+ import { type EchoHost, type SpaceManager } from '@dxos/echo-pipeline';
19
+ import { type DatabaseDirectory } from '@dxos/echo-protocol';
18
20
  import { writeMessages } from '@dxos/feed-store';
19
21
  import { assertArgument, assertState, invariant } from '@dxos/invariant';
20
22
  import { SpaceId } from '@dxos/keys';
@@ -22,6 +24,7 @@ import { log } from '@dxos/log';
22
24
  import {
23
25
  ApiError,
24
26
  AuthorizationError,
27
+ FeedProtocol,
25
28
  IdentityNotInitializedError,
26
29
  SpaceNotFoundError,
27
30
  encodeError,
@@ -41,6 +44,7 @@ import {
41
44
  type QueryCredentialsRequest,
42
45
  type QuerySpacesResponse,
43
46
  type Space,
47
+ SpaceArchive,
44
48
  SpaceMember,
45
49
  SpaceState,
46
50
  type SpacesService,
@@ -56,7 +60,14 @@ import { trace } from '@dxos/tracing';
56
60
  import { type Provider } from '@dxos/util';
57
61
 
58
62
  import { type IdentityManager } from '../identity';
59
- import { SpaceArchiveWriter, extractSpaceArchive } from '../space-export';
63
+ import {
64
+ SpaceArchiveWriter,
65
+ detectSpaceArchiveFormat,
66
+ extractSpaceArchive,
67
+ readSerializedSpaceArchive,
68
+ writeSerializedSpaceArchive,
69
+ objJsonToObjectStructure,
70
+ } from '../space-export';
60
71
  import { type DataSpace } from './data-space';
61
72
  import { type DataSpaceManager } from './data-space-manager';
62
73
 
@@ -64,13 +75,15 @@ export class SpacesServiceImpl implements SpacesService {
64
75
  constructor(
65
76
  private readonly _identityManager: IdentityManager,
66
77
  private readonly _spaceManager: SpaceManager,
78
+ private readonly _echoHost: EchoHost,
67
79
  private readonly _getDataSpaceManager: Provider<Promise<DataSpaceManager>>,
68
80
  ) {}
69
81
 
70
- async createSpace(request: CreateSpaceRequest): Promise<Space> {
82
+ async createSpace(request: CreateSpaceRequest, options?: RequestOptions): Promise<Space> {
71
83
  this._requireIdentity();
84
+ const ctx = options?.ctx ?? new Context();
72
85
  const dataSpaceManager = await this._getDataSpaceManager();
73
- const space = await dataSpaceManager.createSpace(new Context(), {
86
+ const space = await dataSpaceManager.createSpace(ctx, {
74
87
  tags: request?.tags,
75
88
  membershipPolicy: request?.membershipPolicy,
76
89
  });
@@ -78,18 +91,19 @@ export class SpacesServiceImpl implements SpacesService {
78
91
  return this._serializeSpace(space);
79
92
  }
80
93
 
81
- async updateSpace({ spaceKey, state, edgeReplication }: UpdateSpaceRequest): Promise<void> {
94
+ async updateSpace({ spaceKey, state, edgeReplication }: UpdateSpaceRequest, options?: RequestOptions): Promise<void> {
95
+ const ctx = options?.ctx ?? Context.default();
82
96
  const dataSpaceManager = await this._getDataSpaceManager();
83
97
  const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
84
98
 
85
99
  if (state) {
86
100
  switch (state) {
87
101
  case SpaceState.SPACE_ACTIVE:
88
- await space.activate(Context.default());
102
+ await space.activate(ctx);
89
103
  break;
90
104
 
91
105
  case SpaceState.SPACE_INACTIVE:
92
- await space.deactivate(Context.default());
106
+ await space.deactivate(ctx);
93
107
  break;
94
108
  default:
95
109
  throw new ApiError({ message: 'Invalid space state' });
@@ -97,7 +111,7 @@ export class SpacesServiceImpl implements SpacesService {
97
111
  }
98
112
 
99
113
  if (edgeReplication !== undefined) {
100
- await dataSpaceManager.setSpaceEdgeReplicationSetting(Context.default(), spaceKey, edgeReplication);
114
+ await dataSpaceManager.setSpaceEdgeReplicationSetting(ctx, spaceKey, edgeReplication);
101
115
  }
102
116
  }
103
117
 
@@ -266,18 +280,26 @@ export class SpacesServiceImpl implements SpacesService {
266
280
  });
267
281
  }
268
282
 
269
- async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest): Promise<JoinSpaceResponse> {
283
+ async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest, options?: RequestOptions): Promise<JoinSpaceResponse> {
284
+ const ctx = options?.ctx ?? Context.default();
270
285
  const dataSpaceManager = await this._getDataSpaceManager();
271
- const credential = await dataSpaceManager.requestSpaceAdmissionCredential(Context.default(), spaceKey);
272
- return this._joinByAdmission({ credential });
286
+ const credential = await dataSpaceManager.requestSpaceAdmissionCredential(ctx, spaceKey);
287
+ return this._joinByAdmission(ctx, { credential });
273
288
  }
274
289
 
275
290
  async exportSpace(request: ExportSpaceRequest): Promise<ExportSpaceResponse> {
276
- await using writer = await new SpaceArchiveWriter().open();
277
291
  assertArgument(SpaceId.isValid(request.spaceId), 'spaceId', 'Invalid space ID');
278
292
 
279
293
  const dataSpaceManager = await this._getDataSpaceManager();
280
294
  const space = dataSpaceManager.getSpaceById(request.spaceId) ?? raise(new Error('Space not found'));
295
+
296
+ const format = request.format ?? SpaceArchive.Format.BINARY;
297
+ if (format === SpaceArchive.Format.JSON) {
298
+ const archive = await writeSerializedSpaceArchive({ space, echoHost: this._echoHost });
299
+ return { archive };
300
+ }
301
+
302
+ await using writer = await new SpaceArchiveWriter().open();
281
303
  await writer.begin({ spaceId: space.id });
282
304
  const rootUrl = space.automergeSpaceState.lastEpoch?.subject.assertion.automergeRoot;
283
305
  assertState(rootUrl, 'Space does not have a root URL');
@@ -305,11 +327,22 @@ export class SpacesServiceImpl implements SpacesService {
305
327
  return { archive };
306
328
  }
307
329
 
308
- async importSpace(request: ImportSpaceRequest): Promise<ImportSpaceResponse> {
330
+ async importSpace(request: ImportSpaceRequest, options?: RequestOptions): Promise<ImportSpaceResponse> {
331
+ const ctx = options?.ctx ?? Context.default();
309
332
  const dataSpaceManager = await this._getDataSpaceManager();
333
+
334
+ const format = request.archive.format ?? detectSpaceArchiveFormat(request.archive);
335
+ if (format === SpaceArchive.Format.JSON) {
336
+ const serialized = readSerializedSpaceArchive(request.archive);
337
+ const space = await dataSpaceManager.createSpace(ctx);
338
+ await this._hydrateSpaceFromSerialized(space, serialized);
339
+ await this._updateMetrics();
340
+ return { newSpaceId: space.id };
341
+ }
342
+
310
343
  const extracted = await extractSpaceArchive(request.archive);
311
344
  invariant(extracted.metadata.echo?.currentRootUrl, 'Space archive does not contain a root URL');
312
- const space = await dataSpaceManager.createSpace(Context.default(), {
345
+ const space = await dataSpaceManager.createSpace(ctx, {
313
346
  documents: extracted.documents,
314
347
  rootUrl: extracted.metadata.echo?.currentRootUrl as AutomergeUrl,
315
348
  });
@@ -317,7 +350,49 @@ export class SpacesServiceImpl implements SpacesService {
317
350
  return { newSpaceId: space.id };
318
351
  }
319
352
 
320
- private async _joinByAdmission({ credential }: ContactAdmission): Promise<JoinSpaceResponse> {
353
+ /**
354
+ * Populate a freshly-created space with the objects and feed messages described in a {@link SerializedSpace}.
355
+ *
356
+ * Objects are written directly into the space's automerge root document as inline
357
+ * {@link ObjectStructure} entries; feed messages are appended to the appropriate queue
358
+ * via {@link EchoHost.queuesService}.
359
+ */
360
+ private async _hydrateSpaceFromSerialized(
361
+ space: DataSpace,
362
+ serialized: ReturnType<typeof readSerializedSpaceArchive>,
363
+ ): Promise<void> {
364
+ const databaseRoot = space.databaseRoot;
365
+ assertState(databaseRoot, 'Space database root is not ready');
366
+
367
+ databaseRoot.handle.change((doc: DatabaseDirectory) => {
368
+ if (!doc.objects) {
369
+ doc.objects = {};
370
+ }
371
+ for (const obj of serialized.objects) {
372
+ doc.objects[obj.id] = objJsonToObjectStructure(obj);
373
+ }
374
+ });
375
+
376
+ for (const feed of serialized.feeds ?? []) {
377
+ if (feed.messages.length === 0) {
378
+ continue;
379
+ }
380
+ const namespace =
381
+ feed.namespace === 'trace' ? FeedProtocol.WellKnownNamespaces.trace : FeedProtocol.WellKnownNamespaces.data;
382
+ try {
383
+ await this._echoHost.queuesService.insertIntoQueue({
384
+ spaceId: space.id,
385
+ queueId: feed.feedObjectId,
386
+ subspaceTag: namespace,
387
+ objects: feed.messages.map((message) => JSON.stringify(message)),
388
+ });
389
+ } catch (err) {
390
+ log.warn('failed to import feed data', { feedObjectId: feed.feedObjectId, error: err });
391
+ }
392
+ }
393
+ }
394
+
395
+ private async _joinByAdmission(ctx: Context, { credential }: ContactAdmission): Promise<JoinSpaceResponse> {
321
396
  const assertion = getCredentialAssertion(credential);
322
397
  invariant(assertion['@type'] === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');
323
398
  const myIdentity = this._identityManager.identity;
@@ -326,7 +401,7 @@ export class SpacesServiceImpl implements SpacesService {
326
401
  const dataSpaceManager = await this._getDataSpaceManager();
327
402
  let dataSpace = dataSpaceManager.spaces.get(assertion.spaceKey);
328
403
  if (!dataSpace) {
329
- dataSpace = await dataSpaceManager.acceptSpace(Context.default(), {
404
+ dataSpace = await dataSpaceManager.acceptSpace(ctx, {
330
405
  spaceKey: assertion.spaceKey,
331
406
  genesisFeedKey: assertion.genesisFeedKey,
332
407
  tags: assertion.tags,
@@ -130,20 +130,32 @@ export class WorkerRuntime {
130
130
  async start(): Promise<void> {
131
131
  log('starting...');
132
132
  try {
133
+ log('worker-runtime: acquiring liveness lock (background)');
133
134
  void this._livenessLock.acquire();
134
135
 
135
136
  // Steal the lock from the other worker.
137
+ log('worker-runtime: broadcasting stop to displace previous worker');
136
138
  this._broadcastChannel = new BroadcastChannel(this._channel);
137
139
  this._broadcastChannel.postMessage({ action: 'stop' });
138
140
  this._broadcastChannel.onmessage = async (event) => {
139
141
  if (event.data?.action === 'stop') {
142
+ log('worker-runtime: received stop broadcast');
140
143
  await this.stop();
141
144
  }
142
145
  };
143
146
 
147
+ log('worker-runtime: acquiring storage lock');
144
148
  await this._acquireLock();
149
+ log('worker-runtime: storage lock acquired, resolving config');
145
150
  this._config = await this._configProvider();
151
+ log('worker-runtime: config resolved');
152
+ this._signalTelemetryEnabled = this._config.get('runtime.client.signalTelemetryEnabled') ?? false;
153
+ const observabilityGroup = this._config.get('runtime.client.observabilityGroup');
154
+ if (observabilityGroup) {
155
+ this._signalMetadataTags.group = observabilityGroup;
156
+ }
146
157
  const signals = this._config.get('runtime.services.signaling');
158
+ log('worker-runtime: initializing client services host');
147
159
  this._clientServices.initialize({
148
160
  config: this._config,
149
161
  signalManager: this._config.get('runtime.client.edgeFeatures')?.signaling
@@ -153,8 +165,10 @@ export class WorkerRuntime {
153
165
  : new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
154
166
  transportFactory: this._transportFactory,
155
167
  });
168
+ log('worker-runtime: client services host initialized, opening');
156
169
 
157
170
  await this._clientServices.open(new Context());
171
+ log('worker-runtime: client services host opened, signalling ready');
158
172
  this._ready.wake(undefined);
159
173
  log('started');
160
174
  setIdentityTags({
@@ -181,6 +195,30 @@ export class WorkerRuntime {
181
195
  await this._livenessLock.release();
182
196
  }
183
197
 
198
+ /**
199
+ * Update signaling telemetry tags from a client-supplied config overlay.
200
+ *
201
+ * The worker services outlive individual client connections, so the first client seeds the
202
+ * worker's core config (storage, signaling, edge features). For fields that can legitimately
203
+ * differ per tab — `observabilityGroup` and `signalTelemetryEnabled` — this method lets later
204
+ * connections refresh the signal metadata the worker attaches to its signaling requests
205
+ * (last-writer-wins, matching the pre-DX-930 per-session RPC behaviour).
206
+ */
207
+ updateSignalMetadata(config: Config): void {
208
+ const observabilityGroup = config.get('runtime.client.observabilityGroup');
209
+ if (observabilityGroup) {
210
+ this._signalMetadataTags.group = observabilityGroup;
211
+ } else {
212
+ // Clear stale group so a later config that removes observabilityGroup stops attributing
213
+ // telemetry to the previous client's group (last-writer-wins).
214
+ delete this._signalMetadataTags.group;
215
+ }
216
+ const signalTelemetryEnabled = config.get('runtime.client.signalTelemetryEnabled');
217
+ if (signalTelemetryEnabled !== undefined) {
218
+ this._signalTelemetryEnabled = signalTelemetryEnabled;
219
+ }
220
+ }
221
+
184
222
  /**
185
223
  * Create a new session.
186
224
  */
@@ -213,10 +251,6 @@ export class WorkerRuntime {
213
251
  !this._signalMetadataTags.origin || this._signalMetadataTags.origin === session.origin,
214
252
  `worker origin changed from ${this._signalMetadataTags.origin} to ${session.origin}?`,
215
253
  );
216
- if (session.observabilityGroup) {
217
- this._signalMetadataTags.group = session.observabilityGroup;
218
- }
219
- this._signalTelemetryEnabled = session.signalTelemetryEnabled ?? false;
220
254
  this._signalMetadataTags.origin = session.origin;
221
255
  this._sessions.add(session);
222
256
 
@@ -41,10 +41,6 @@ export class WorkerSession {
41
41
  @logInfo
42
42
  public origin?: string;
43
43
 
44
- // TODO(nf): factor out?
45
- public observabilityGroup?: string;
46
- public signalTelemetryEnabled?: boolean;
47
-
48
44
  @logInfo
49
45
  public lockKey?: string;
50
46
 
@@ -55,21 +51,21 @@ export class WorkerSession {
55
51
  this._serviceHost = serviceHost;
56
52
 
57
53
  const middleware: Pick<ClientRpcServerProps, 'handleCall' | 'handleStream'> = {
58
- handleCall: async (method, params, handler) => {
54
+ handleCall: async (method, params, handler, options) => {
59
55
  const error = await readySignal.wait({ timeout: PROXY_CONNECTION_TIMEOUT });
60
56
  if (error) {
61
57
  throw error;
62
58
  }
63
59
 
64
- return handler(method, params);
60
+ return handler(method, params, options);
65
61
  },
66
- handleStream: async (method, params, handler) => {
62
+ handleStream: async (method, params, handler, options) => {
67
63
  const error = await readySignal.wait({ timeout: PROXY_CONNECTION_TIMEOUT });
68
64
  if (error) {
69
65
  throw error;
70
66
  }
71
67
 
72
- return handler(method, params);
68
+ return handler(method, params, options);
73
69
  },
74
70
  };
75
71
 
@@ -95,8 +91,6 @@ export class WorkerSession {
95
91
  start: async (request) => {
96
92
  this.origin = request.origin;
97
93
  this.lockKey = request.lockKey;
98
- this.observabilityGroup = request.observabilityGroup;
99
- this.signalTelemetryEnabled = request.signalTelemetryEnabled;
100
94
  this._startTrigger.wake();
101
95
  },
102
96
 
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const DXOS_VERSION = "0.8.4-main.9be5663bfe";
1
+ export const DXOS_VERSION = "0.8.4-main.abd8ff62ef";