@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.
- package/dist/lib/browser/{chunk-CK3KJB3B.mjs → chunk-KW4WMU5R.mjs} +1310 -3084
- package/dist/lib/browser/chunk-KW4WMU5R.mjs.map +7 -0
- package/dist/lib/browser/{chunk-NQSC7HOE.mjs → chunk-XJRPB3GA.mjs} +1 -1
- package/dist/lib/browser/index.mjs +100 -197
- 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 +7 -27
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs → chunk-2DT3MZRL.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-WHBWCIEN.mjs → chunk-NDMKP2CH.mjs} +1310 -3084
- package/dist/lib/node-esm/chunk-NDMKP2CH.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +100 -197
- 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 +7 -27
- package/dist/lib/node-esm/testing/index.mjs.map +2 -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.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +2 -2
- 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 -5
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +1 -2
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +1 -2
- 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.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +1 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
- 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 +1 -2
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +2 -1
- 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.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 +9 -6
- 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 +39 -46
- package/src/packlets/agents/edge-agent-service.ts +3 -2
- package/src/packlets/diagnostics/diagnostics.ts +1 -2
- package/src/packlets/identity/identity-manager.ts +2 -4
- package/src/packlets/identity/identity-service.ts +12 -9
- package/src/packlets/identity/identity.ts +2 -2
- package/src/packlets/invitations/device-invitation-protocol.ts +3 -1
- package/src/packlets/invitations/edge-invitation-handler.ts +5 -2
- 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.ts +64 -12
- package/src/packlets/invitations/invitations-manager.ts +6 -4
- package/src/packlets/invitations/invitations-service.ts +6 -6
- package/src/packlets/invitations/space-invitation-protocol.ts +3 -3
- package/src/packlets/logging/logging-service.ts +15 -15
- package/src/packlets/network/network-service.ts +9 -8
- package/src/packlets/services/client-rpc-server.ts +15 -12
- package/src/packlets/services/service-context.ts +12 -15
- package/src/packlets/services/service-host.ts +8 -19
- 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 +253 -0
- package/src/packlets/space-export/space-archive-writer.ts +2 -1
- package/src/packlets/space-export/space-archive.test.ts +175 -1
- package/src/packlets/spaces/data-space-manager.ts +17 -19
- package/src/packlets/spaces/data-space.ts +9 -7
- package/src/packlets/spaces/edge-feed-replicator.ts +1 -0
- package/src/packlets/spaces/spaces-service.test.ts +9 -4
- package/src/packlets/spaces/spaces-service.ts +91 -16
- package/src/packlets/worker/worker-runtime.ts +38 -4
- package/src/packlets/worker/worker-session.ts +4 -10
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-CK3KJB3B.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WHBWCIEN.mjs.map +0 -7
- /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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Stream } from '@dxos/codec-protobuf
|
|
5
|
+
import { type RequestOptions, Stream } from '@dxos/codec-protobuf';
|
|
6
6
|
import {
|
|
7
7
|
type AcceptInvitationRequest,
|
|
8
8
|
type AuthenticationRequest,
|
|
@@ -27,23 +27,23 @@ export class InvitationsServiceImpl implements InvitationsService {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
createInvitation(
|
|
30
|
+
createInvitation(request: Invitation, options?: RequestOptions): Stream<Invitation> {
|
|
31
31
|
return new Stream<Invitation>(({ ctx, next, close }) => {
|
|
32
32
|
void this._invitationsManager
|
|
33
|
-
.createInvitation(ctx,
|
|
33
|
+
.createInvitation(ctx, request)
|
|
34
34
|
.then((invitation) => {
|
|
35
35
|
trace.metrics.increment('dxos.invitation.created');
|
|
36
36
|
invitation.subscribe(next, close, close);
|
|
37
37
|
})
|
|
38
38
|
.catch(close);
|
|
39
|
-
});
|
|
39
|
+
}, options?.ctx);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
acceptInvitation(request: AcceptInvitationRequest): Stream<Invitation> {
|
|
42
|
+
acceptInvitation(request: AcceptInvitationRequest, options?: RequestOptions): Stream<Invitation> {
|
|
43
43
|
return new Stream<Invitation>(({ ctx, next, close }) => {
|
|
44
44
|
const invitation = this._invitationsManager.acceptInvitation(ctx, request);
|
|
45
45
|
invitation.subscribe(next, close, close);
|
|
46
|
-
});
|
|
46
|
+
}, options?.ctx);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
async authenticate(request: AuthenticationRequest): Promise<void> {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Context } from '@dxos/context';
|
|
5
|
+
import { type Context } from '@dxos/context';
|
|
6
6
|
import {
|
|
7
7
|
createCancelDelegatedSpaceInvitationCredential,
|
|
8
8
|
createDelegatedSpaceInvitationCredential,
|
|
@@ -170,7 +170,7 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
170
170
|
};
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
async accept(response: AdmissionResponse): Promise<Partial<Invitation>> {
|
|
173
|
+
async accept(ctx: Context, response: AdmissionResponse): Promise<Partial<Invitation>> {
|
|
174
174
|
invariant(response.space);
|
|
175
175
|
const { credential, controlTimeframe, dataTimeframe } = response.space;
|
|
176
176
|
const assertion = getCredentialAssertion(credential);
|
|
@@ -182,7 +182,7 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
// Create local space.
|
|
185
|
-
await this._spaceManager.acceptSpace(
|
|
185
|
+
await this._spaceManager.acceptSpace(ctx, {
|
|
186
186
|
spaceKey: assertion.spaceKey,
|
|
187
187
|
genesisFeedKey: assertion.genesisFeedKey,
|
|
188
188
|
controlTimeframe,
|
|
@@ -5,13 +5,7 @@
|
|
|
5
5
|
import { Event } from '@dxos/async';
|
|
6
6
|
import { Stream } from '@dxos/codec-protobuf/stream';
|
|
7
7
|
import { PublicKey } from '@dxos/keys';
|
|
8
|
-
import {
|
|
9
|
-
type LogLevel,
|
|
10
|
-
type LogProcessor,
|
|
11
|
-
type LogEntry as NaturalLogEntry,
|
|
12
|
-
getContextFromEntry,
|
|
13
|
-
log,
|
|
14
|
-
} from '@dxos/log';
|
|
8
|
+
import { type LogLevel, type LogProcessor, type LogEntry as NaturalLogEntry, log } from '@dxos/log';
|
|
15
9
|
import {
|
|
16
10
|
type ControlMetricsRequest,
|
|
17
11
|
type ControlMetricsResponse,
|
|
@@ -22,7 +16,7 @@ import {
|
|
|
22
16
|
type QueryMetricsRequest,
|
|
23
17
|
type QueryMetricsResponse,
|
|
24
18
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
25
|
-
import {
|
|
19
|
+
import { numericalValues, tracer } from '@dxos/util';
|
|
26
20
|
|
|
27
21
|
/**
|
|
28
22
|
* Logging service used to spy on logs of the host.
|
|
@@ -114,19 +108,25 @@ export class LoggingServiceImpl implements LoggingService {
|
|
|
114
108
|
return;
|
|
115
109
|
}
|
|
116
110
|
|
|
111
|
+
const { filename, line, context: scopeName } = entry.computedMeta;
|
|
112
|
+
const recordContext: Record<string, any> = { ...entry.computedContext };
|
|
113
|
+
if (entry.computedError !== undefined) {
|
|
114
|
+
recordContext.error = entry.computedError;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
117
|
const record: LogEntry = {
|
|
118
|
-
|
|
119
|
-
message: entry.message ??
|
|
120
|
-
context:
|
|
121
|
-
timestamp: new Date(),
|
|
118
|
+
level: entry.level,
|
|
119
|
+
message: entry.message ?? entry.computedError ?? '',
|
|
120
|
+
context: recordContext,
|
|
121
|
+
timestamp: new Date(entry.timestamp),
|
|
122
122
|
meta: {
|
|
123
123
|
// TODO(dmaretskyi): Fix proto.
|
|
124
|
-
file:
|
|
125
|
-
line:
|
|
124
|
+
file: filename ?? '',
|
|
125
|
+
line: line ?? 0,
|
|
126
126
|
scope: {
|
|
127
127
|
hostSessionId: this._sessionId,
|
|
128
128
|
uptimeSeconds: (Date.now() - this._started) / 1000,
|
|
129
|
-
name:
|
|
129
|
+
name: scopeName ?? '',
|
|
130
130
|
},
|
|
131
131
|
},
|
|
132
132
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type RequestOptions } from '@dxos/codec-protobuf';
|
|
5
6
|
import { Stream } from '@dxos/codec-protobuf/stream';
|
|
6
7
|
import { Context } from '@dxos/context';
|
|
7
8
|
import { type EdgeConnection } from '@dxos/edge-client';
|
|
@@ -48,16 +49,16 @@ export class NetworkServiceImpl implements NetworkService {
|
|
|
48
49
|
await this.networkManager.setConnectionState(request.swarm);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
async joinSwarm(request: JoinRequest): Promise<void> {
|
|
52
|
-
return this.signalManager.join(Context.default(), request);
|
|
52
|
+
async joinSwarm(request: JoinRequest, options?: RequestOptions): Promise<void> {
|
|
53
|
+
return this.signalManager.join(options?.ctx ?? Context.default(), request);
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
async leaveSwarm(request: LeaveRequest): Promise<void> {
|
|
56
|
-
return this.signalManager.leave(Context.default(), request);
|
|
56
|
+
async leaveSwarm(request: LeaveRequest, options?: RequestOptions): Promise<void> {
|
|
57
|
+
return this.signalManager.leave(options?.ctx ?? Context.default(), request);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
async querySwarm(request: QueryRequest): Promise<SwarmResponse> {
|
|
60
|
-
return this.signalManager.query(Context.default(), request);
|
|
60
|
+
async querySwarm(request: QueryRequest, options?: RequestOptions): Promise<SwarmResponse> {
|
|
61
|
+
return this.signalManager.query(options?.ctx ?? Context.default(), request);
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
subscribeSwarmState(request: SubscribeSwarmStateRequest): Stream<SwarmResponse> {
|
|
@@ -70,8 +71,8 @@ export class NetworkServiceImpl implements NetworkService {
|
|
|
70
71
|
});
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
async sendMessage(message: Message): Promise<void> {
|
|
74
|
-
return this.signalManager.sendMessage(Context.default(), message);
|
|
74
|
+
async sendMessage(message: Message, options?: RequestOptions): Promise<void> {
|
|
75
|
+
return this.signalManager.sendMessage(options?.ctx ?? Context.default(), message);
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
subscribeMessages(peer: Peer): Stream<Message> {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type ClientServices } from '@dxos/client-protocol';
|
|
6
|
-
import { type Any, type ServiceHandler, Stream } from '@dxos/codec-protobuf';
|
|
6
|
+
import { type Any, type RequestOptions, type ServiceHandler, Stream } from '@dxos/codec-protobuf';
|
|
7
7
|
import { raise } from '@dxos/debug';
|
|
8
8
|
import { RpcPeer, type RpcPeerOptions, type ServiceBundle, parseMethodName } from '@dxos/rpc';
|
|
9
9
|
import { MapCounter, trace } from '@dxos/tracing';
|
|
@@ -16,12 +16,14 @@ export type ClientRpcServerProps = {
|
|
|
16
16
|
handleCall?: (
|
|
17
17
|
method: string,
|
|
18
18
|
params: Any,
|
|
19
|
-
handler: (method: string, params: Any) => MaybePromise<Any>,
|
|
19
|
+
handler: (method: string, params: Any, options?: RequestOptions) => MaybePromise<Any>,
|
|
20
|
+
options?: RequestOptions,
|
|
20
21
|
) => Promise<Any>;
|
|
21
22
|
handleStream?: (
|
|
22
23
|
method: string,
|
|
23
24
|
params: Any,
|
|
24
|
-
handler: (method: string, params: Any) => Stream<Any>,
|
|
25
|
+
handler: (method: string, params: Any, options?: RequestOptions) => Stream<Any>,
|
|
26
|
+
options?: RequestOptions,
|
|
25
27
|
) => MaybePromise<Stream<Any>>;
|
|
26
28
|
} & Omit<RpcPeerOptions, 'callHandler' | 'streamHandler'>;
|
|
27
29
|
|
|
@@ -49,32 +51,33 @@ export class ClientRpcServer {
|
|
|
49
51
|
this._serviceRegistry = serviceRegistry;
|
|
50
52
|
this._rpcPeer = new RpcPeer({
|
|
51
53
|
...rpcOptions,
|
|
52
|
-
callHandler: (method, params) => {
|
|
54
|
+
callHandler: (method, params, options) => {
|
|
53
55
|
const [serviceName, methodName] = parseMethodName(method);
|
|
54
|
-
const handler = (method: string, params: Any
|
|
56
|
+
const handler = (method: string, params: Any, handlerOptions?: RequestOptions) =>
|
|
57
|
+
this._getServiceHandler(serviceName).call(method, params, handlerOptions);
|
|
55
58
|
|
|
56
59
|
this._callMetrics.inc(`${serviceName}.${methodName} request`);
|
|
57
60
|
|
|
58
61
|
if (this._handleCall) {
|
|
59
|
-
return this._handleCall(methodName, params, handler);
|
|
62
|
+
return this._handleCall(methodName, params, handler, options);
|
|
60
63
|
} else {
|
|
61
|
-
return handler(methodName, params);
|
|
64
|
+
return handler(methodName, params, options);
|
|
62
65
|
}
|
|
63
66
|
},
|
|
64
|
-
streamHandler: (method, params) => {
|
|
67
|
+
streamHandler: (method, params, options) => {
|
|
65
68
|
const [serviceName, methodName] = parseMethodName(method);
|
|
66
|
-
const handler = (method: string, params: Any) =>
|
|
67
|
-
this._getServiceHandler(serviceName).callStream(method, params);
|
|
69
|
+
const handler = (method: string, params: Any, handlerOptions?: RequestOptions) =>
|
|
70
|
+
this._getServiceHandler(serviceName).callStream(method, params, handlerOptions);
|
|
68
71
|
|
|
69
72
|
this._callMetrics.inc(`${serviceName}.${methodName} request stream`);
|
|
70
73
|
|
|
71
74
|
if (this._handleStream) {
|
|
72
|
-
return Stream.map(Stream.unwrapPromise(this._handleStream(methodName, params, handler)), (data) => {
|
|
75
|
+
return Stream.map(Stream.unwrapPromise(this._handleStream(methodName, params, handler, options)), (data) => {
|
|
73
76
|
this._callMetrics.inc(`${serviceName}.${methodName} response stream`);
|
|
74
77
|
return data;
|
|
75
78
|
});
|
|
76
79
|
} else {
|
|
77
|
-
return handler(methodName, params);
|
|
80
|
+
return handler(methodName, params, options);
|
|
78
81
|
}
|
|
79
82
|
},
|
|
80
83
|
});
|
|
@@ -22,12 +22,12 @@ import { type RuntimeProvider } from '@dxos/effect';
|
|
|
22
22
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
23
23
|
import { invariant } from '@dxos/invariant';
|
|
24
24
|
import { Keyring } from '@dxos/keyring';
|
|
25
|
-
import {
|
|
25
|
+
import { type SpaceId } from '@dxos/keys';
|
|
26
26
|
import { type LevelDB } from '@dxos/kv-store';
|
|
27
27
|
import { log } from '@dxos/log';
|
|
28
28
|
import { type SignalManager } from '@dxos/messaging';
|
|
29
29
|
import { type SwarmNetworkManager } from '@dxos/network-manager';
|
|
30
|
-
import { InvalidStorageVersionError, STORAGE_VERSION
|
|
30
|
+
import { InvalidStorageVersionError, STORAGE_VERSION } from '@dxos/protocols';
|
|
31
31
|
import { FeedProtocol } from '@dxos/protocols';
|
|
32
32
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
33
33
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
@@ -74,7 +74,7 @@ export type ServiceContextRuntimeProps = Pick<
|
|
|
74
74
|
// TODO(burdon): Rename/break-up into smaller components. And/or make members private.
|
|
75
75
|
// TODO(dmaretskyi): Gets duplicated in CJS build between normal and testing bundles.
|
|
76
76
|
@safeInstanceof('dxos.client-services.ServiceContext')
|
|
77
|
-
@Trace.resource()
|
|
77
|
+
@Trace.resource({ lifecycle: true })
|
|
78
78
|
export class ServiceContext extends Resource {
|
|
79
79
|
private readonly _edgeIdentityUpdateMutex = new Mutex();
|
|
80
80
|
|
|
@@ -104,8 +104,6 @@ export class ServiceContext extends Resource {
|
|
|
104
104
|
|
|
105
105
|
private _deviceSpaceSync?: CredentialProcessor;
|
|
106
106
|
|
|
107
|
-
private readonly _instanceId = PublicKey.random().toHex();
|
|
108
|
-
|
|
109
107
|
constructor(
|
|
110
108
|
public readonly storage: Storage,
|
|
111
109
|
public readonly level: LevelDB,
|
|
@@ -224,12 +222,11 @@ export class ServiceContext extends Resource {
|
|
|
224
222
|
}
|
|
225
223
|
}
|
|
226
224
|
|
|
227
|
-
@Trace.span()
|
|
225
|
+
@Trace.span({ op: 'lifecycle' })
|
|
228
226
|
protected override async _open(ctx: Context): Promise<void> {
|
|
229
227
|
await this._checkStorageVersion();
|
|
230
228
|
|
|
231
229
|
log('opening...');
|
|
232
|
-
log.trace('dxos.sdk.service-context.open', trace.begin({ id: this._instanceId }));
|
|
233
230
|
|
|
234
231
|
log('opening identityManager...');
|
|
235
232
|
await this.identityManager.open(ctx);
|
|
@@ -240,11 +237,11 @@ export class ServiceContext extends Resource {
|
|
|
240
237
|
log('network identity set');
|
|
241
238
|
|
|
242
239
|
log('opening edge connection...');
|
|
243
|
-
await this._edgeConnection?.open();
|
|
240
|
+
await this._edgeConnection?.open(ctx);
|
|
244
241
|
log('edge connection opened');
|
|
245
242
|
|
|
246
243
|
log('opening signal manager...');
|
|
247
|
-
await this.signalManager.open();
|
|
244
|
+
await this.signalManager.open(ctx);
|
|
248
245
|
log('signal manager opened');
|
|
249
246
|
|
|
250
247
|
log('opening network manager...');
|
|
@@ -287,14 +284,13 @@ export class ServiceContext extends Resource {
|
|
|
287
284
|
}
|
|
288
285
|
|
|
289
286
|
log('opening feed syncer...');
|
|
290
|
-
await this._feedSyncer?.open();
|
|
287
|
+
await this._feedSyncer?.open(ctx);
|
|
291
288
|
log('feed syncer opened');
|
|
292
289
|
|
|
293
290
|
log('loading persistent invitations...');
|
|
294
291
|
const loadedInvitations = await this.invitationsManager.loadPersistentInvitations(ctx);
|
|
295
292
|
log('loaded persistent invitations', { count: loadedInvitations.invitations?.length });
|
|
296
293
|
|
|
297
|
-
log.trace('dxos.sdk.service-context.open', trace.end({ id: this._instanceId }));
|
|
298
294
|
log('opened');
|
|
299
295
|
}
|
|
300
296
|
|
|
@@ -321,8 +317,8 @@ export class ServiceContext extends Resource {
|
|
|
321
317
|
log('closed');
|
|
322
318
|
}
|
|
323
319
|
|
|
324
|
-
async createIdentity(params: CreateIdentityOptions = {}) {
|
|
325
|
-
|
|
320
|
+
async createIdentity(params: CreateIdentityOptions = {}, ctx?: Context) {
|
|
321
|
+
ctx ??= this._ctx;
|
|
326
322
|
const identity = await this.identityManager.createIdentity(params, ctx);
|
|
327
323
|
await this._setNetworkIdentity({ identity });
|
|
328
324
|
await identity.joinNetwork(ctx);
|
|
@@ -398,7 +394,7 @@ export class ServiceContext extends Resource {
|
|
|
398
394
|
edgeFeatures: this._edgeFeatures,
|
|
399
395
|
});
|
|
400
396
|
log('_initialize: opening DataSpaceManager...');
|
|
401
|
-
await this.dataSpaceManager.open();
|
|
397
|
+
await this.dataSpaceManager.open(ctx);
|
|
402
398
|
log('_initialize: DataSpaceManager opened');
|
|
403
399
|
|
|
404
400
|
this.edgeAgentManager = new EdgeAgentManager(
|
|
@@ -408,7 +404,7 @@ export class ServiceContext extends Resource {
|
|
|
408
404
|
identity,
|
|
409
405
|
);
|
|
410
406
|
log('_initialize: opening EdgeAgentManager...');
|
|
411
|
-
await this.edgeAgentManager.open();
|
|
407
|
+
await this.edgeAgentManager.open(ctx);
|
|
412
408
|
log('_initialize: EdgeAgentManager opened');
|
|
413
409
|
|
|
414
410
|
this._handlerFactories.set(Invitation.Kind.SPACE, (invitation) => {
|
|
@@ -442,6 +438,7 @@ export class ServiceContext extends Resource {
|
|
|
442
438
|
await this.dataSpaceManager.acceptSpace(this._ctx, {
|
|
443
439
|
spaceKey: assertion.spaceKey,
|
|
444
440
|
genesisFeedKey: assertion.genesisFeedKey,
|
|
441
|
+
tags: assertion.tags,
|
|
445
442
|
});
|
|
446
443
|
} catch (err) {
|
|
447
444
|
log.catch(err);
|
|
@@ -7,12 +7,11 @@ import * as Effect from 'effect/Effect';
|
|
|
7
7
|
|
|
8
8
|
import { Event, synchronized } from '@dxos/async';
|
|
9
9
|
import { type ClientServices, clientServiceBundle } from '@dxos/client-protocol';
|
|
10
|
-
import { type Config } from '@dxos/config';
|
|
10
|
+
import { type Config, resolveTelemetryTag } from '@dxos/config';
|
|
11
11
|
import { Context } from '@dxos/context';
|
|
12
12
|
import { EdgeClient, type EdgeConnection, EdgeHttpClient, createStubEdgeIdentity } from '@dxos/edge-client';
|
|
13
13
|
import { RuntimeProvider } from '@dxos/effect';
|
|
14
14
|
import { invariant } from '@dxos/invariant';
|
|
15
|
-
import { PublicKey } from '@dxos/keys';
|
|
16
15
|
import { type LevelDB } from '@dxos/kv-store';
|
|
17
16
|
import { log } from '@dxos/log';
|
|
18
17
|
import { EdgeSignalManager, type SignalManager, WebsocketSignalManager } from '@dxos/messaging';
|
|
@@ -22,12 +21,11 @@ import {
|
|
|
22
21
|
createIceProvider,
|
|
23
22
|
createRtcTransportFactory,
|
|
24
23
|
} from '@dxos/network-manager';
|
|
25
|
-
import { trace } from '@dxos/protocols';
|
|
26
24
|
import { SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
27
25
|
import { type Storage } from '@dxos/random-access-storage';
|
|
28
26
|
import * as SqlExport from '@dxos/sql-sqlite/SqlExport';
|
|
29
27
|
import type * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
|
|
30
|
-
import {
|
|
28
|
+
import { trace as Trace } from '@dxos/tracing';
|
|
31
29
|
import { WebsocketRpcClient } from '@dxos/websocket-rpc';
|
|
32
30
|
|
|
33
31
|
import { EdgeAgentServiceImpl } from '../agents';
|
|
@@ -86,8 +84,6 @@ export class ClientServicesHost {
|
|
|
86
84
|
private readonly _serviceRegistry: ServiceRegistry<ClientServices>;
|
|
87
85
|
private readonly _systemService: SystemServiceImpl;
|
|
88
86
|
private readonly _loggingService: LoggingServiceImpl;
|
|
89
|
-
private readonly _tracingService = TRACE_PROCESSOR.createTraceSender();
|
|
90
|
-
|
|
91
87
|
private readonly _statusUpdate = new Event<void>();
|
|
92
88
|
|
|
93
89
|
private _config?: Config;
|
|
@@ -175,7 +171,6 @@ export class ClientServicesHost {
|
|
|
175
171
|
|
|
176
172
|
this._serviceRegistry = new ServiceRegistry<ClientServices>(clientServiceBundle, {
|
|
177
173
|
SystemService: this._systemService,
|
|
178
|
-
TracingService: this._tracingService,
|
|
179
174
|
});
|
|
180
175
|
}
|
|
181
176
|
|
|
@@ -258,7 +253,7 @@ export class ClientServicesHost {
|
|
|
258
253
|
|
|
259
254
|
const endpoint = config?.get('runtime.services.edge.url');
|
|
260
255
|
if (endpoint) {
|
|
261
|
-
const clientTag = config
|
|
256
|
+
const clientTag = resolveTelemetryTag(config);
|
|
262
257
|
this._edgeConnection = new EdgeClient(createStubEdgeIdentity(), { socketEndpoint: endpoint, clientTag });
|
|
263
258
|
this._edgeHttpClient = new EdgeHttpClient(endpoint, { clientTag });
|
|
264
259
|
}
|
|
@@ -299,8 +294,7 @@ export class ClientServicesHost {
|
|
|
299
294
|
return;
|
|
300
295
|
}
|
|
301
296
|
|
|
302
|
-
|
|
303
|
-
log.trace('dxos.client-services.host.open', trace.begin({ id: traceId }));
|
|
297
|
+
log('opening service host');
|
|
304
298
|
|
|
305
299
|
invariant(this._config, 'config not set');
|
|
306
300
|
invariant(this._storage, 'storage not set');
|
|
@@ -345,7 +339,7 @@ export class ClientServicesHost {
|
|
|
345
339
|
this._serviceContext.identityManager,
|
|
346
340
|
this._serviceContext.recoveryManager,
|
|
347
341
|
this._serviceContext.keyring,
|
|
348
|
-
(params) => this._createIdentity(params),
|
|
342
|
+
(params, ctx) => this._createIdentity(params, ctx),
|
|
349
343
|
(profile) => this._serviceContext.broadcastProfileUpdate(profile),
|
|
350
344
|
);
|
|
351
345
|
|
|
@@ -365,6 +359,7 @@ export class ClientServicesHost {
|
|
|
365
359
|
SpacesService: new SpacesServiceImpl(
|
|
366
360
|
this._serviceContext.identityManager,
|
|
367
361
|
this._serviceContext.spaceManager,
|
|
362
|
+
this._serviceContext.echoHost,
|
|
368
363
|
dataSpaceManagerProvider,
|
|
369
364
|
),
|
|
370
365
|
|
|
@@ -379,7 +374,6 @@ export class ClientServicesHost {
|
|
|
379
374
|
),
|
|
380
375
|
|
|
381
376
|
LoggingService: this._loggingService,
|
|
382
|
-
TracingService: this._tracingService,
|
|
383
377
|
|
|
384
378
|
// TODO(burdon): Move to new protobuf definitions.
|
|
385
379
|
DevtoolsHost: new DevtoolsServiceImpl({
|
|
@@ -416,7 +410,6 @@ export class ClientServicesHost {
|
|
|
416
410
|
this._statusUpdate.emit();
|
|
417
411
|
const deviceKey = this._serviceContext.identityManager.identity?.deviceKey;
|
|
418
412
|
log('opened', { deviceKey });
|
|
419
|
-
log.trace('dxos.client-services.host.open', trace.end({ id: traceId }));
|
|
420
413
|
}
|
|
421
414
|
|
|
422
415
|
@synchronized
|
|
@@ -440,9 +433,6 @@ export class ClientServicesHost {
|
|
|
440
433
|
}
|
|
441
434
|
|
|
442
435
|
async reset(): Promise<void> {
|
|
443
|
-
const traceId = PublicKey.random().toHex();
|
|
444
|
-
log.trace('dxos.sdk.client-services-host.reset', trace.begin({ id: traceId }));
|
|
445
|
-
|
|
446
436
|
log.info('resetting...');
|
|
447
437
|
// Emit this status update immediately so app returns to fallback.
|
|
448
438
|
// This state is never cleared because the app reloads.
|
|
@@ -457,12 +447,11 @@ export class ClientServicesHost {
|
|
|
457
447
|
}
|
|
458
448
|
await this._storage!.reset();
|
|
459
449
|
log.info('reset');
|
|
460
|
-
log.trace('dxos.sdk.client-services-host.reset', trace.end({ id: traceId }));
|
|
461
450
|
await this._callbacks?.onReset?.();
|
|
462
451
|
}
|
|
463
452
|
|
|
464
|
-
private async _createIdentity(params: CreateIdentityOptions) {
|
|
465
|
-
const identity = await this._serviceContext.createIdentity(params);
|
|
453
|
+
private async _createIdentity(params: CreateIdentityOptions, ctx?: Context) {
|
|
454
|
+
const identity = await this._serviceContext.createIdentity(params, ctx);
|
|
466
455
|
await this._serviceContext.initialized.wait();
|
|
467
456
|
return identity;
|
|
468
457
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { SpaceArchive } from '@dxos/protocols/proto/dxos/client/services';
|
|
6
|
+
|
|
7
|
+
const JSON_EXTENSIONS = ['.dx.json', '.dx.json.gz', '.json'];
|
|
8
|
+
const BINARY_EXTENSIONS = ['.tar', '.tar.gz'];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Detect the format of a space archive.
|
|
12
|
+
*
|
|
13
|
+
* Uses filename extension as the primary signal, and falls back to sniffing
|
|
14
|
+
* the first bytes of the archive contents to distinguish JSON from tar.
|
|
15
|
+
*/
|
|
16
|
+
export const detectSpaceArchiveFormat = (archive: Pick<SpaceArchive, 'filename' | 'contents'>): SpaceArchive.Format => {
|
|
17
|
+
const filename = archive.filename?.toLowerCase() ?? '';
|
|
18
|
+
if (JSON_EXTENSIONS.some((ext) => filename.endsWith(ext))) {
|
|
19
|
+
return SpaceArchive.Format.JSON;
|
|
20
|
+
}
|
|
21
|
+
if (BINARY_EXTENSIONS.some((ext) => filename.endsWith(ext))) {
|
|
22
|
+
return SpaceArchive.Format.BINARY;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Fall back to byte sniffing: JSON archives start with '{' (0x7B) or whitespace.
|
|
26
|
+
const bytes = archive.contents;
|
|
27
|
+
if (bytes && bytes.length > 0) {
|
|
28
|
+
for (let i = 0; i < Math.min(bytes.length, 16); i++) {
|
|
29
|
+
const byte = bytes[i];
|
|
30
|
+
// Skip whitespace.
|
|
31
|
+
if (byte === 0x20 || byte === 0x09 || byte === 0x0a || byte === 0x0d) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (byte === 0x7b /* '{' */) {
|
|
35
|
+
return SpaceArchive.Format.JSON;
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return SpaceArchive.Format.BINARY;
|
|
42
|
+
};
|
|
@@ -2,5 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
export * from './
|
|
5
|
+
export * from './archive-format';
|
|
6
|
+
export * from './serialized-space-reader';
|
|
7
|
+
export * from './serialized-space-writer';
|
|
6
8
|
export * from './space-archive-reader';
|
|
9
|
+
export * from './space-archive-writer';
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Obj } from '@dxos/echo';
|
|
6
|
+
import { type SerializedSpace } from '@dxos/echo-db';
|
|
7
|
+
import { type DatabaseDirectory, type ObjectStructure } from '@dxos/echo-protocol';
|
|
8
|
+
import { assertArgument } from '@dxos/invariant';
|
|
9
|
+
import { type SpaceArchive } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
|
+
|
|
11
|
+
const ATTR_TYPE = '@type';
|
|
12
|
+
const ATTR_META = '@meta';
|
|
13
|
+
const ATTR_DELETED = '@deleted';
|
|
14
|
+
const ATTR_PARENT = '@parent';
|
|
15
|
+
const ATTR_RELATION_SOURCE = '@relationSource';
|
|
16
|
+
const ATTR_RELATION_TARGET = '@relationTarget';
|
|
17
|
+
|
|
18
|
+
const INTERNAL_KEYS: ReadonlySet<string> = new Set([
|
|
19
|
+
'id',
|
|
20
|
+
ATTR_TYPE,
|
|
21
|
+
ATTR_META,
|
|
22
|
+
ATTR_DELETED,
|
|
23
|
+
ATTR_PARENT,
|
|
24
|
+
ATTR_RELATION_SOURCE,
|
|
25
|
+
ATTR_RELATION_TARGET,
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Parse a JSON space archive.
|
|
30
|
+
*
|
|
31
|
+
* The archive contents are expected to be the UTF-8 encoding of
|
|
32
|
+
* `JSON.stringify(serializedSpace)`.
|
|
33
|
+
*/
|
|
34
|
+
export const readSerializedSpaceArchive = (archive: SpaceArchive): SerializedSpace => {
|
|
35
|
+
const text = new TextDecoder().decode(archive.contents);
|
|
36
|
+
const parsed = JSON.parse(text) as SerializedSpace;
|
|
37
|
+
assertArgument(typeof parsed === 'object' && parsed !== null, 'archive', 'Invalid JSON archive payload');
|
|
38
|
+
assertArgument(typeof parsed.version === 'number', 'archive', 'Missing SerializedSpace.version');
|
|
39
|
+
assertArgument(Array.isArray(parsed.objects), 'archive', 'Missing SerializedSpace.objects');
|
|
40
|
+
return parsed;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Convert an {@link Obj.JSON} back into an internal {@link ObjectStructure} suitable
|
|
45
|
+
* for embedding into a {@link DatabaseDirectory}.
|
|
46
|
+
*/
|
|
47
|
+
export const objJsonToObjectStructure = (obj: Obj.JSON): ObjectStructure => {
|
|
48
|
+
const data: Record<string, unknown> = {};
|
|
49
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
50
|
+
if (INTERNAL_KEYS.has(key)) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
data[key] = value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const system: NonNullable<ObjectStructure['system']> = {};
|
|
57
|
+
|
|
58
|
+
const type = obj[ATTR_TYPE];
|
|
59
|
+
if (type) {
|
|
60
|
+
system.type = { '/': type as string };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const parent = (obj as any)[ATTR_PARENT];
|
|
64
|
+
if (typeof parent === 'string') {
|
|
65
|
+
system.parent = { '/': parent };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const relationSource = (obj as any)[ATTR_RELATION_SOURCE];
|
|
69
|
+
const relationTarget = (obj as any)[ATTR_RELATION_TARGET];
|
|
70
|
+
if (typeof relationSource === 'string' || typeof relationTarget === 'string') {
|
|
71
|
+
system.kind = 'relation';
|
|
72
|
+
if (typeof relationSource === 'string') {
|
|
73
|
+
system.source = { '/': relationSource };
|
|
74
|
+
}
|
|
75
|
+
if (typeof relationTarget === 'string') {
|
|
76
|
+
system.target = { '/': relationTarget };
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
system.kind = 'object';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if ((obj as any)[ATTR_DELETED]) {
|
|
83
|
+
system.deleted = true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const meta = (obj as any)[ATTR_META];
|
|
87
|
+
return {
|
|
88
|
+
system,
|
|
89
|
+
meta: {
|
|
90
|
+
keys: meta?.keys ?? [],
|
|
91
|
+
...(meta?.tags ? { tags: meta.tags } : {}),
|
|
92
|
+
},
|
|
93
|
+
data,
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Build a new {@link DatabaseDirectory} containing every object from the archive,
|
|
99
|
+
* keyed by object id. The caller is responsible for stamping the `access.spaceKey`
|
|
100
|
+
* and version fields after the document is created.
|
|
101
|
+
*/
|
|
102
|
+
export const buildDatabaseDirectoryFromObjects = (objects: readonly Obj.JSON[]): DatabaseDirectory => {
|
|
103
|
+
const map: Record<string, ObjectStructure> = {};
|
|
104
|
+
for (const obj of objects) {
|
|
105
|
+
map[obj.id] = objJsonToObjectStructure(obj);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
objects: map,
|
|
109
|
+
links: {},
|
|
110
|
+
};
|
|
111
|
+
};
|