@dxos/client-services 0.8.4-main.c85a9c8dae → 0.8.4-main.cb12b3f963
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.
- package/dist/lib/browser/{chunk-MQ6PWJ76.mjs → chunk-TZQLGPMV.mjs} +1596 -3099
- package/dist/lib/browser/chunk-TZQLGPMV.mjs.map +7 -0
- package/dist/lib/browser/{chunk-NQSC7HOE.mjs → chunk-XJRPB3GA.mjs} +1 -1
- package/dist/lib/browser/index.mjs +106 -194
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +1 -6
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +2 -2
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +1 -1
- package/dist/lib/browser/packlets/locks/browser.mjs +9 -49
- package/dist/lib/browser/packlets/locks/browser.mjs.map +2 -2
- package/dist/lib/browser/packlets/locks/node.mjs +4 -22
- package/dist/lib/browser/packlets/locks/node.mjs.map +2 -2
- package/dist/lib/browser/testing/index.mjs +9 -22
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs → chunk-2DT3MZRL.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-GUAL4U7S.mjs → chunk-6DX3BNLB.mjs} +1596 -3099
- package/dist/lib/node-esm/chunk-6DX3BNLB.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +106 -194
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +1 -6
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +2 -2
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +1 -1
- package/dist/lib/node-esm/packlets/locks/browser.mjs +9 -49
- package/dist/lib/node-esm/packlets/locks/browser.mjs.map +2 -2
- package/dist/lib/node-esm/packlets/locks/node.mjs +4 -22
- package/dist/lib/node-esm/packlets/locks/node.mjs.map +2 -2
- package/dist/lib/node-esm/testing/index.mjs +9 -22
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +3 -3
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +6 -5
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +6 -10
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +6 -9
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +2 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +5 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +2 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts +5 -4
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts +3 -3
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/feed-syncer.d.ts +2 -2
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +2 -3
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +2 -3
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
- package/dist/types/src/packlets/services/util.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
- package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/index.d.ts +4 -1
- package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
- package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
- package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +18 -12
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +24 -7
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +1 -4
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +10 -7
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts +11 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-session.d.ts +0 -2
- package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
- package/dist/types/src/testing/setup.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -49
- package/src/index.ts +1 -0
- package/src/packlets/agents/edge-agent-manager.ts +8 -5
- package/src/packlets/agents/edge-agent-service.ts +4 -2
- package/src/packlets/devices/devices-service.test.ts +0 -1
- package/src/packlets/devtools/devtools.ts +0 -1
- package/src/packlets/diagnostics/diagnostics.ts +1 -2
- package/src/packlets/identity/contacts-service.ts +0 -1
- package/src/packlets/identity/identity-manager.test.ts +5 -5
- package/src/packlets/identity/identity-manager.ts +18 -17
- package/src/packlets/identity/identity-recovery-manager.ts +20 -16
- package/src/packlets/identity/identity-service.test.ts +6 -27
- package/src/packlets/identity/identity-service.ts +13 -81
- package/src/packlets/identity/identity.test.ts +2 -2
- package/src/packlets/identity/identity.ts +9 -32
- package/src/packlets/invitations/device-invitation-protocol.ts +3 -2
- package/src/packlets/invitations/edge-invitation-handler.ts +9 -5
- package/src/packlets/invitations/invitation-host-extension.ts +7 -10
- package/src/packlets/invitations/invitation-protocol.ts +5 -1
- package/src/packlets/invitations/invitation-state.ts +1 -15
- package/src/packlets/invitations/invitations-handler.test.ts +4 -5
- package/src/packlets/invitations/invitations-handler.ts +67 -15
- package/src/packlets/invitations/invitations-manager.ts +40 -15
- package/src/packlets/invitations/invitations-service.ts +9 -9
- package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
- package/src/packlets/invitations/space-invitation-protocol.ts +4 -3
- package/src/packlets/logging/logging-service.ts +15 -15
- package/src/packlets/network/network-service.test.ts +0 -1
- package/src/packlets/network/network-service.ts +10 -8
- package/src/packlets/services/client-rpc-server.ts +15 -12
- package/src/packlets/services/feed-syncer.test.ts +3 -3
- package/src/packlets/services/feed-syncer.ts +24 -17
- package/src/packlets/services/service-context.test.ts +3 -2
- package/src/packlets/services/service-context.ts +91 -40
- package/src/packlets/services/service-host.test.ts +8 -8
- package/src/packlets/services/service-host.ts +17 -24
- package/src/packlets/services/service-registry.test.ts +0 -1
- package/src/packlets/space-export/archive-format.ts +42 -0
- package/src/packlets/space-export/index.ts +4 -1
- package/src/packlets/space-export/serialized-space-reader.ts +111 -0
- package/src/packlets/space-export/serialized-space-writer.ts +252 -0
- package/src/packlets/space-export/space-archive-reader.ts +64 -3
- package/src/packlets/space-export/space-archive-writer.ts +38 -2
- package/src/packlets/space-export/space-archive.test.ts +461 -0
- package/src/packlets/spaces/data-space-manager.test.ts +79 -13
- package/src/packlets/spaces/data-space-manager.ts +75 -111
- package/src/packlets/spaces/data-space.ts +49 -29
- package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
- package/src/packlets/spaces/edge-feed-replicator.ts +9 -7
- package/src/packlets/spaces/epoch-migrations.ts +3 -3
- package/src/packlets/spaces/genesis.ts +6 -1
- package/src/packlets/spaces/notarization-plugin.ts +2 -1
- package/src/packlets/spaces/spaces-service.test.ts +18 -11
- package/src/packlets/spaces/spaces-service.ts +113 -17
- package/src/packlets/testing/invitation-utils.ts +3 -2
- package/src/packlets/worker/worker-runtime.ts +39 -6
- package/src/packlets/worker/worker-session.ts +4 -10
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-MQ6PWJ76.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-GUAL4U7S.mjs.map +0 -7
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
- package/src/packlets/identity/default-space-state-machine.ts +0 -44
- /package/dist/lib/browser/{chunk-NQSC7HOE.mjs.map → chunk-XJRPB3GA.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs.map → chunk-2DT3MZRL.mjs.map} +0 -0
|
@@ -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,12 +284,13 @@ 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
|
|
|
290
291
|
private _createConnectionContext(): Context {
|
|
291
292
|
const connectionCtx = new Context({
|
|
293
|
+
parent: this._ctx,
|
|
292
294
|
onError: async (err: any) => {
|
|
293
295
|
if (connectionCtx !== this._connectionCtx) {
|
|
294
296
|
return;
|
|
@@ -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', () => {
|
|
@@ -21,10 +21,15 @@ describe('SpacesService', () => {
|
|
|
21
21
|
beforeEach(async () => {
|
|
22
22
|
serviceContext = await createServiceContext();
|
|
23
23
|
await serviceContext.open(new Context());
|
|
24
|
-
spacesService = new SpacesServiceImpl(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
spacesService = new SpacesServiceImpl(
|
|
25
|
+
serviceContext.identityManager,
|
|
26
|
+
serviceContext.spaceManager,
|
|
27
|
+
serviceContext.echoHost,
|
|
28
|
+
async () => {
|
|
29
|
+
await serviceContext.initialized.wait();
|
|
30
|
+
return serviceContext.dataSpaceManager!;
|
|
31
|
+
},
|
|
32
|
+
);
|
|
28
33
|
});
|
|
29
34
|
|
|
30
35
|
afterEach(async () => {
|
|
@@ -33,12 +38,14 @@ describe('SpacesService', () => {
|
|
|
33
38
|
|
|
34
39
|
describe('createSpace', () => {
|
|
35
40
|
test('fails if no identity is available', async () => {
|
|
36
|
-
await expect(spacesService.createSpace()).rejects.toBeInstanceOf(
|
|
41
|
+
await expect(spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE })).rejects.toBeInstanceOf(
|
|
42
|
+
Error,
|
|
43
|
+
);
|
|
37
44
|
});
|
|
38
45
|
|
|
39
46
|
test('creates a new space', async () => {
|
|
40
47
|
await serviceContext.createIdentity();
|
|
41
|
-
const space = await spacesService.createSpace();
|
|
48
|
+
const space = await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
|
|
42
49
|
expect(space).to.exist;
|
|
43
50
|
expect(space.spaceKey).to.be.instanceof(PublicKey);
|
|
44
51
|
});
|
|
@@ -60,9 +67,9 @@ describe('SpacesService', () => {
|
|
|
60
67
|
test('returns list of existing spaces', async () => {
|
|
61
68
|
await serviceContext.createIdentity();
|
|
62
69
|
const existingSpaces = [
|
|
63
|
-
await spacesService.createSpace(),
|
|
64
|
-
await spacesService.createSpace(),
|
|
65
|
-
await spacesService.createSpace(),
|
|
70
|
+
await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
|
|
71
|
+
await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
|
|
72
|
+
await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
|
|
66
73
|
];
|
|
67
74
|
|
|
68
75
|
const query = spacesService.querySpaces();
|
|
@@ -88,7 +95,7 @@ describe('SpacesService', () => {
|
|
|
88
95
|
expect(await result.wait()).to.be.length(0);
|
|
89
96
|
|
|
90
97
|
result.reset();
|
|
91
|
-
const space = await spacesService.createSpace();
|
|
98
|
+
const space = await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
|
|
92
99
|
const spaces = await result.wait();
|
|
93
100
|
expect(spaces).to.be.length(1);
|
|
94
101
|
expect(spaces?.[0].spaceKey.equals(space.spaceKey)).to.be.true;
|
|
@@ -5,7 +5,9 @@
|
|
|
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';
|
|
10
|
+
import { Context } from '@dxos/context';
|
|
9
11
|
import {
|
|
10
12
|
type CredentialProcessor,
|
|
11
13
|
createAdmissionCredentials,
|
|
@@ -13,7 +15,8 @@ import {
|
|
|
13
15
|
getCredentialAssertion,
|
|
14
16
|
} from '@dxos/credentials';
|
|
15
17
|
import { raise } from '@dxos/debug';
|
|
16
|
-
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';
|
|
17
20
|
import { writeMessages } from '@dxos/feed-store';
|
|
18
21
|
import { assertArgument, assertState, invariant } from '@dxos/invariant';
|
|
19
22
|
import { SpaceId } from '@dxos/keys';
|
|
@@ -21,6 +24,7 @@ import { log } from '@dxos/log';
|
|
|
21
24
|
import {
|
|
22
25
|
ApiError,
|
|
23
26
|
AuthorizationError,
|
|
27
|
+
FeedProtocol,
|
|
24
28
|
IdentityNotInitializedError,
|
|
25
29
|
SpaceNotFoundError,
|
|
26
30
|
encodeError,
|
|
@@ -40,11 +44,13 @@ import {
|
|
|
40
44
|
type QueryCredentialsRequest,
|
|
41
45
|
type QuerySpacesResponse,
|
|
42
46
|
type Space,
|
|
47
|
+
SpaceArchive,
|
|
43
48
|
SpaceMember,
|
|
44
49
|
SpaceState,
|
|
45
50
|
type SpacesService,
|
|
46
51
|
type SubscribeMessagesRequest,
|
|
47
52
|
type UpdateMemberRoleRequest,
|
|
53
|
+
type CreateSpaceRequest,
|
|
48
54
|
type UpdateSpaceRequest,
|
|
49
55
|
type WriteCredentialsRequest,
|
|
50
56
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -54,8 +60,14 @@ import { trace } from '@dxos/tracing';
|
|
|
54
60
|
import { type Provider } from '@dxos/util';
|
|
55
61
|
|
|
56
62
|
import { type IdentityManager } from '../identity';
|
|
57
|
-
import {
|
|
58
|
-
|
|
63
|
+
import {
|
|
64
|
+
SpaceArchiveWriter,
|
|
65
|
+
detectSpaceArchiveFormat,
|
|
66
|
+
extractSpaceArchive,
|
|
67
|
+
readSerializedSpaceArchive,
|
|
68
|
+
writeSerializedSpaceArchive,
|
|
69
|
+
objJsonToObjectStructure,
|
|
70
|
+
} from '../space-export';
|
|
59
71
|
import { type DataSpace } from './data-space';
|
|
60
72
|
import { type DataSpaceManager } from './data-space-manager';
|
|
61
73
|
|
|
@@ -63,29 +75,35 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
63
75
|
constructor(
|
|
64
76
|
private readonly _identityManager: IdentityManager,
|
|
65
77
|
private readonly _spaceManager: SpaceManager,
|
|
78
|
+
private readonly _echoHost: EchoHost,
|
|
66
79
|
private readonly _getDataSpaceManager: Provider<Promise<DataSpaceManager>>,
|
|
67
80
|
) {}
|
|
68
81
|
|
|
69
|
-
async createSpace(): Promise<Space> {
|
|
82
|
+
async createSpace(request: CreateSpaceRequest, options?: RequestOptions): Promise<Space> {
|
|
70
83
|
this._requireIdentity();
|
|
84
|
+
const ctx = options?.ctx ?? new Context();
|
|
71
85
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
72
|
-
const space = await dataSpaceManager.createSpace(
|
|
86
|
+
const space = await dataSpaceManager.createSpace(ctx, {
|
|
87
|
+
tags: request?.tags,
|
|
88
|
+
membershipPolicy: request?.membershipPolicy,
|
|
89
|
+
});
|
|
73
90
|
await this._updateMetrics();
|
|
74
91
|
return this._serializeSpace(space);
|
|
75
92
|
}
|
|
76
93
|
|
|
77
|
-
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();
|
|
78
96
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
79
97
|
const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
|
|
80
98
|
|
|
81
99
|
if (state) {
|
|
82
100
|
switch (state) {
|
|
83
101
|
case SpaceState.SPACE_ACTIVE:
|
|
84
|
-
await space.activate();
|
|
102
|
+
await space.activate(ctx);
|
|
85
103
|
break;
|
|
86
104
|
|
|
87
105
|
case SpaceState.SPACE_INACTIVE:
|
|
88
|
-
await space.deactivate();
|
|
106
|
+
await space.deactivate(ctx);
|
|
89
107
|
break;
|
|
90
108
|
default:
|
|
91
109
|
throw new ApiError({ message: 'Invalid space state' });
|
|
@@ -93,7 +111,7 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
93
111
|
}
|
|
94
112
|
|
|
95
113
|
if (edgeReplication !== undefined) {
|
|
96
|
-
await dataSpaceManager.setSpaceEdgeReplicationSetting(spaceKey, edgeReplication);
|
|
114
|
+
await dataSpaceManager.setSpaceEdgeReplicationSetting(ctx, spaceKey, edgeReplication);
|
|
97
115
|
}
|
|
98
116
|
}
|
|
99
117
|
|
|
@@ -262,18 +280,26 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
262
280
|
});
|
|
263
281
|
}
|
|
264
282
|
|
|
265
|
-
async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest): Promise<JoinSpaceResponse> {
|
|
283
|
+
async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest, options?: RequestOptions): Promise<JoinSpaceResponse> {
|
|
284
|
+
const ctx = options?.ctx ?? Context.default();
|
|
266
285
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
267
|
-
const credential = await dataSpaceManager.requestSpaceAdmissionCredential(spaceKey);
|
|
268
|
-
return this._joinByAdmission({ credential });
|
|
286
|
+
const credential = await dataSpaceManager.requestSpaceAdmissionCredential(ctx, spaceKey);
|
|
287
|
+
return this._joinByAdmission(ctx, { credential });
|
|
269
288
|
}
|
|
270
289
|
|
|
271
290
|
async exportSpace(request: ExportSpaceRequest): Promise<ExportSpaceResponse> {
|
|
272
|
-
await using writer = await new SpaceArchiveWriter().open();
|
|
273
291
|
assertArgument(SpaceId.isValid(request.spaceId), 'spaceId', 'Invalid space ID');
|
|
274
292
|
|
|
275
293
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
276
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();
|
|
277
303
|
await writer.begin({ spaceId: space.id });
|
|
278
304
|
const rootUrl = space.automergeSpaceState.lastEpoch?.subject.assertion.automergeRoot;
|
|
279
305
|
assertState(rootUrl, 'Space does not have a root URL');
|
|
@@ -283,15 +309,40 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
283
309
|
await writer.writeDocument(documentId, data);
|
|
284
310
|
}
|
|
285
311
|
|
|
312
|
+
const feeds = await space.getAllFeeds();
|
|
313
|
+
for (const feed of feeds) {
|
|
314
|
+
const archiveBlocks = feed.blocks.map((block) => ({
|
|
315
|
+
actorId: block.actorId,
|
|
316
|
+
sequence: block.sequence,
|
|
317
|
+
prevActorId: block.prevActorId,
|
|
318
|
+
prevSequence: block.prevSequence,
|
|
319
|
+
position: block.position,
|
|
320
|
+
timestamp: block.timestamp,
|
|
321
|
+
data: Buffer.from(block.data).toString('base64'),
|
|
322
|
+
}));
|
|
323
|
+
await writer.writeFeed(feed.feedId, feed.feedNamespace, archiveBlocks);
|
|
324
|
+
}
|
|
325
|
+
|
|
286
326
|
const archive = await writer.finish();
|
|
287
327
|
return { archive };
|
|
288
328
|
}
|
|
289
329
|
|
|
290
|
-
async importSpace(request: ImportSpaceRequest): Promise<ImportSpaceResponse> {
|
|
330
|
+
async importSpace(request: ImportSpaceRequest, options?: RequestOptions): Promise<ImportSpaceResponse> {
|
|
331
|
+
const ctx = options?.ctx ?? Context.default();
|
|
291
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
|
+
|
|
292
343
|
const extracted = await extractSpaceArchive(request.archive);
|
|
293
344
|
invariant(extracted.metadata.echo?.currentRootUrl, 'Space archive does not contain a root URL');
|
|
294
|
-
const space = await dataSpaceManager.createSpace({
|
|
345
|
+
const space = await dataSpaceManager.createSpace(ctx, {
|
|
295
346
|
documents: extracted.documents,
|
|
296
347
|
rootUrl: extracted.metadata.echo?.currentRootUrl as AutomergeUrl,
|
|
297
348
|
});
|
|
@@ -299,7 +350,49 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
299
350
|
return { newSpaceId: space.id };
|
|
300
351
|
}
|
|
301
352
|
|
|
302
|
-
|
|
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> {
|
|
303
396
|
const assertion = getCredentialAssertion(credential);
|
|
304
397
|
invariant(assertion['@type'] === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');
|
|
305
398
|
const myIdentity = this._identityManager.identity;
|
|
@@ -308,9 +401,10 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
308
401
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
309
402
|
let dataSpace = dataSpaceManager.spaces.get(assertion.spaceKey);
|
|
310
403
|
if (!dataSpace) {
|
|
311
|
-
dataSpace = await dataSpaceManager.acceptSpace({
|
|
404
|
+
dataSpace = await dataSpaceManager.acceptSpace(ctx, {
|
|
312
405
|
spaceKey: assertion.spaceKey,
|
|
313
406
|
genesisFeedKey: assertion.genesisFeedKey,
|
|
407
|
+
tags: assertion.tags,
|
|
314
408
|
});
|
|
315
409
|
await myIdentity.controlPipeline.writer.write({ credential: { credential } });
|
|
316
410
|
}
|
|
@@ -363,6 +457,8 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
363
457
|
}),
|
|
364
458
|
),
|
|
365
459
|
creator: space.inner.spaceState.creator?.key,
|
|
460
|
+
tags: space.tags,
|
|
461
|
+
membershipPolicy: space.membershipPolicy,
|
|
366
462
|
cache: space.cache,
|
|
367
463
|
metrics: space.metrics,
|
|
368
464
|
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.
|
|
@@ -131,20 +130,32 @@ export class WorkerRuntime {
|
|
|
131
130
|
async start(): Promise<void> {
|
|
132
131
|
log('starting...');
|
|
133
132
|
try {
|
|
133
|
+
log('worker-runtime: acquiring liveness lock (background)');
|
|
134
134
|
void this._livenessLock.acquire();
|
|
135
135
|
|
|
136
136
|
// Steal the lock from the other worker.
|
|
137
|
+
log('worker-runtime: broadcasting stop to displace previous worker');
|
|
137
138
|
this._broadcastChannel = new BroadcastChannel(this._channel);
|
|
138
139
|
this._broadcastChannel.postMessage({ action: 'stop' });
|
|
139
140
|
this._broadcastChannel.onmessage = async (event) => {
|
|
140
141
|
if (event.data?.action === 'stop') {
|
|
142
|
+
log('worker-runtime: received stop broadcast');
|
|
141
143
|
await this.stop();
|
|
142
144
|
}
|
|
143
145
|
};
|
|
144
146
|
|
|
147
|
+
log('worker-runtime: acquiring storage lock');
|
|
145
148
|
await this._acquireLock();
|
|
149
|
+
log('worker-runtime: storage lock acquired, resolving config');
|
|
146
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
|
+
}
|
|
147
157
|
const signals = this._config.get('runtime.services.signaling');
|
|
158
|
+
log('worker-runtime: initializing client services host');
|
|
148
159
|
this._clientServices.initialize({
|
|
149
160
|
config: this._config,
|
|
150
161
|
signalManager: this._config.get('runtime.client.edgeFeatures')?.signaling
|
|
@@ -154,8 +165,10 @@ export class WorkerRuntime {
|
|
|
154
165
|
: new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
|
|
155
166
|
transportFactory: this._transportFactory,
|
|
156
167
|
});
|
|
168
|
+
log('worker-runtime: client services host initialized, opening');
|
|
157
169
|
|
|
158
170
|
await this._clientServices.open(new Context());
|
|
171
|
+
log('worker-runtime: client services host opened, signalling ready');
|
|
159
172
|
this._ready.wake(undefined);
|
|
160
173
|
log('started');
|
|
161
174
|
setIdentityTags({
|
|
@@ -176,12 +189,36 @@ export class WorkerRuntime {
|
|
|
176
189
|
this._releaseLock();
|
|
177
190
|
this._broadcastChannel?.close();
|
|
178
191
|
this._broadcastChannel = undefined;
|
|
179
|
-
await this._clientServices.close();
|
|
192
|
+
await this._clientServices.close(Context.default());
|
|
180
193
|
await this._runtime.dispose();
|
|
181
194
|
await this._onStop?.();
|
|
182
195
|
await this._livenessLock.release();
|
|
183
196
|
}
|
|
184
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
|
+
|
|
185
222
|
/**
|
|
186
223
|
* Create a new session.
|
|
187
224
|
*/
|
|
@@ -214,10 +251,6 @@ export class WorkerRuntime {
|
|
|
214
251
|
!this._signalMetadataTags.origin || this._signalMetadataTags.origin === session.origin,
|
|
215
252
|
`worker origin changed from ${this._signalMetadataTags.origin} to ${session.origin}?`,
|
|
216
253
|
);
|
|
217
|
-
if (session.observabilityGroup) {
|
|
218
|
-
this._signalMetadataTags.group = session.observabilityGroup;
|
|
219
|
-
}
|
|
220
|
-
this._signalTelemetryEnabled = session.signalTelemetryEnabled ?? false;
|
|
221
254
|
this._signalMetadataTags.origin = session.origin;
|
|
222
255
|
this._sessions.add(session);
|
|
223
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.
|
|
1
|
+
export const DXOS_VERSION = "0.8.4-main.cb12b3f963";
|