@dxos/client-services 0.8.3 → 0.8.4-main.1068cf700f
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-NQSC7HOE.mjs +22 -0
- package/dist/lib/browser/chunk-NQSC7HOE.mjs.map +7 -0
- package/dist/lib/browser/{chunk-LBG3C332.mjs → chunk-OZGICTH7.mjs} +3864 -3786
- package/dist/lib/browser/chunk-OZGICTH7.mjs.map +7 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +474 -80
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/browser.mjs +126 -0
- package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/node.mjs +66 -0
- package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +39 -27
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs +22 -0
- package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SKGQLRKS.mjs → chunk-RXHISBCS.mjs} +3551 -3341
- package/dist/lib/node-esm/chunk-RXHISBCS.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +474 -80
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs +126 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs +66 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +39 -27
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +1 -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 +20 -20
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts +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 +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +3 -3
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +5 -5
- 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 +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +3 -3
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +4 -4
- 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/index.d.ts +1 -1
- package/dist/types/src/packlets/invitations/index.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 +3 -4
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +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 +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +3 -3
- 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/index.d.ts +2 -2
- package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts +5 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts +2 -2
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts +2 -2
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/feed-syncer.d.ts +41 -0
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
- package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +14 -8
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +20 -6
- package/dist/types/src/packlets/services/service-host.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 +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 +12 -7
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +6 -6
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -6
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -2
- package/dist/types/src/packlets/spaces/spaces-service.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/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/invitation-utils.d.ts +6 -3
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +8 -7
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts +31 -4
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-session.d.ts +2 -2
- package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +72 -48
- package/src/packlets/agents/edge-agent-manager.ts +2 -2
- package/src/packlets/agents/edge-agent-service.ts +13 -3
- package/src/packlets/devices/devices-service.test.ts +4 -3
- package/src/packlets/devices/devices-service.ts +2 -2
- package/src/packlets/devtools/devtools.ts +30 -29
- package/src/packlets/devtools/feeds.ts +2 -2
- package/src/packlets/devtools/network.ts +1 -1
- package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +1 -1
- package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -1
- package/src/packlets/diagnostics/diagnostics-collector.ts +1 -1
- package/src/packlets/diagnostics/diagnostics.ts +1 -1
- package/src/packlets/diagnostics/index.ts +1 -1
- package/src/packlets/identity/authenticator.node.test.ts +1 -1
- package/src/packlets/identity/authenticator.ts +3 -3
- package/src/packlets/identity/contacts-service.ts +3 -2
- package/src/packlets/identity/default-space-state-machine.ts +3 -3
- package/src/packlets/identity/identity-manager.test.ts +3 -3
- package/src/packlets/identity/identity-manager.ts +9 -9
- package/src/packlets/identity/identity-recovery-manager.ts +2 -2
- package/src/packlets/identity/identity-service.test.ts +3 -2
- package/src/packlets/identity/identity-service.ts +2 -1
- package/src/packlets/identity/identity.test.ts +9 -9
- package/src/packlets/identity/identity.ts +9 -8
- package/src/packlets/invitations/device-invitation-protocol.test.ts +4 -4
- package/src/packlets/invitations/device-invitation-protocol.ts +6 -5
- package/src/packlets/invitations/edge-invitation-handler.ts +1 -1
- package/src/packlets/invitations/index.ts +1 -1
- package/src/packlets/invitations/invitation-guest-extenstion.ts +7 -5
- package/src/packlets/invitations/invitation-host-extension.ts +8 -6
- package/src/packlets/invitations/invitation-protocol.ts +3 -4
- package/src/packlets/invitations/invitations-handler.test.ts +302 -292
- package/src/packlets/invitations/invitations-handler.ts +10 -10
- package/src/packlets/invitations/invitations-manager.ts +3 -3
- package/src/packlets/invitations/invitations-service.ts +1 -1
- package/src/packlets/invitations/space-invitation-protocol.test.ts +9 -9
- package/src/packlets/invitations/space-invitation-protocol.ts +10 -15
- package/src/packlets/invitations/utils.ts +1 -1
- package/src/packlets/locks/browser.ts +1 -1
- package/src/packlets/locks/index.ts +2 -2
- package/src/packlets/logging/logging-service.ts +8 -3
- package/src/packlets/logging/logging.test.ts +1 -1
- package/src/packlets/network/network-service.test.ts +4 -3
- package/src/packlets/network/network-service.ts +2 -2
- package/src/packlets/services/client-rpc-server.ts +5 -5
- package/src/packlets/services/feed-syncer.ts +227 -0
- package/src/packlets/services/platform.ts +7 -1
- package/src/packlets/services/service-context.test.ts +1 -1
- package/src/packlets/services/service-context.ts +56 -29
- package/src/packlets/services/service-host.test.ts +3 -2
- package/src/packlets/services/service-host.ts +78 -29
- package/src/packlets/services/service-registry.test.ts +2 -1
- package/src/packlets/space-export/space-archive-reader.ts +2 -2
- package/src/packlets/space-export/space-archive-writer.ts +7 -5
- package/src/packlets/space-export/tar.test.ts +1 -1
- package/src/packlets/spaces/automerge-space-state.ts +1 -1
- package/src/packlets/spaces/data-space-manager.ts +76 -36
- package/src/packlets/spaces/data-space.ts +18 -13
- package/src/packlets/spaces/edge-feed-replicator.test.ts +3 -3
- package/src/packlets/spaces/edge-feed-replicator.ts +4 -4
- package/src/packlets/spaces/epoch-migrations.ts +2 -2
- package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
- package/src/packlets/spaces/notarization-plugin.ts +11 -11
- package/src/packlets/spaces/spaces-service.test.ts +3 -2
- package/src/packlets/spaces/spaces-service.ts +27 -23
- package/src/packlets/storage/profile-archive.ts +1 -1
- package/src/packlets/storage/storage.ts +7 -8
- package/src/packlets/system/system-service.test.ts +1 -1
- package/src/packlets/system/system-service.ts +4 -4
- package/src/packlets/testing/invitation-utils.ts +8 -5
- package/src/packlets/testing/test-builder.ts +39 -13
- package/src/packlets/worker/worker-runtime.ts +151 -12
- package/src/packlets/worker/worker-session.ts +7 -7
- package/src/version.ts +1 -5
- package/README.yml +0 -5
- package/dist/lib/browser/chunk-LBG3C332.mjs.map +0 -7
- package/dist/lib/node/chunk-LMGLGOUU.cjs +0 -9311
- package/dist/lib/node/chunk-LMGLGOUU.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -437
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/testing/index.cjs +0 -452
- package/dist/lib/node/testing/index.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-SKGQLRKS.mjs.map +0 -7
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type PushStream,
|
|
5
|
+
import { type PushStream, TimeoutError, type Trigger, scheduleTask } from '@dxos/async';
|
|
6
6
|
import { INVITATION_TIMEOUT, getExpirationTime } from '@dxos/client-protocol';
|
|
7
7
|
import { type Context, ContextDisposedError } from '@dxos/context';
|
|
8
8
|
import { createKeyPair, sign } from '@dxos/crypto';
|
|
@@ -10,19 +10,19 @@ import { type EdgeHttpClient } from '@dxos/edge-client';
|
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { PublicKey } from '@dxos/keys';
|
|
12
12
|
import { log } from '@dxos/log';
|
|
13
|
-
import {
|
|
13
|
+
import { type SwarmConnection, type SwarmNetworkManager, createTeleportProtocolFactory } from '@dxos/network-manager';
|
|
14
14
|
import { InvalidInvitationError, InvalidInvitationExtensionRoleError, trace } from '@dxos/protocols';
|
|
15
15
|
import { type AdmissionKeypair, Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
16
16
|
import { type DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
17
17
|
import { AuthenticationResponse, type IntroductionResponse } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
18
18
|
import { InvitationOptions } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
19
|
-
import { type ExtensionContext, type TeleportExtension, type
|
|
19
|
+
import { type ExtensionContext, type TeleportExtension, type TeleportProps } from '@dxos/teleport';
|
|
20
20
|
import { trace as _trace } from '@dxos/tracing';
|
|
21
21
|
import { ComplexSet } from '@dxos/util';
|
|
22
22
|
|
|
23
23
|
import { type EdgeInvitationConfig, EdgeInvitationHandler } from './edge-invitation-handler';
|
|
24
24
|
import { InvitationGuestExtension } from './invitation-guest-extenstion';
|
|
25
|
-
import { InvitationHostExtension,
|
|
25
|
+
import { InvitationHostExtension, MAX_OTP_ATTEMPTS, isAuthenticationRequired } from './invitation-host-extension';
|
|
26
26
|
import { type InvitationProtocol } from './invitation-protocol';
|
|
27
27
|
import { createGuardedInvitationState } from './invitation-state';
|
|
28
28
|
import { InvitationTopology } from './invitation-topology';
|
|
@@ -31,8 +31,8 @@ const metrics = _trace.metrics;
|
|
|
31
31
|
|
|
32
32
|
const MAX_DELEGATED_INVITATION_HOST_TRIES = 3;
|
|
33
33
|
|
|
34
|
-
export type
|
|
35
|
-
teleport: Partial<
|
|
34
|
+
export type InvitationConnectionProps = {
|
|
35
|
+
teleport: Partial<TeleportProps>;
|
|
36
36
|
edgeInvitations?: EdgeInvitationConfig;
|
|
37
37
|
};
|
|
38
38
|
|
|
@@ -71,7 +71,7 @@ export class InvitationsHandler {
|
|
|
71
71
|
constructor(
|
|
72
72
|
private readonly _networkManager: SwarmNetworkManager,
|
|
73
73
|
private readonly _edgeClient?: EdgeHttpClient,
|
|
74
|
-
private readonly
|
|
74
|
+
private readonly _connectionProps?: InvitationConnectionProps,
|
|
75
75
|
) {}
|
|
76
76
|
|
|
77
77
|
handleInvitationFlow(
|
|
@@ -388,7 +388,7 @@ export class InvitationsHandler {
|
|
|
388
388
|
return extension;
|
|
389
389
|
};
|
|
390
390
|
|
|
391
|
-
const edgeInvitationHandler = new EdgeInvitationHandler(this.
|
|
391
|
+
const edgeInvitationHandler = new EdgeInvitationHandler(this._connectionProps?.edgeInvitations, this._edgeClient, {
|
|
392
392
|
onInvitationSuccess: async (admissionResponse, admissionRequest) => {
|
|
393
393
|
const result = await protocol.accept(admissionResponse, admissionRequest);
|
|
394
394
|
log.info('admitted by edge', { ...protocol.toJSON() });
|
|
@@ -440,7 +440,7 @@ export class InvitationsHandler {
|
|
|
440
440
|
topic: invitation.swarmKey,
|
|
441
441
|
protocolProvider: createTeleportProtocolFactory(async (teleport) => {
|
|
442
442
|
teleport.addExtension('dxos.halo.invitations', extensionFactory());
|
|
443
|
-
}, this.
|
|
443
|
+
}, this._connectionProps?.teleport),
|
|
444
444
|
topology: new InvitationTopology(role),
|
|
445
445
|
label,
|
|
446
446
|
});
|
|
@@ -503,7 +503,7 @@ export class InvitationsHandler {
|
|
|
503
503
|
const checkInvitation = (protocol: InvitationProtocol, invitation: Partial<Invitation>) => {
|
|
504
504
|
const expiresOn = getExpirationTime(invitation);
|
|
505
505
|
if (expiresOn && expiresOn.getTime() < Date.now()) {
|
|
506
|
-
return new InvalidInvitationError('Invitation already expired.');
|
|
506
|
+
return new InvalidInvitationError({ message: 'Invitation already expired.' });
|
|
507
507
|
}
|
|
508
508
|
return protocol.checkInvitation(invitation);
|
|
509
509
|
};
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
import { Event, PushStream, TimeoutError, Trigger } from '@dxos/async';
|
|
6
6
|
import {
|
|
7
|
-
AuthenticatingInvitation,
|
|
8
7
|
AUTHENTICATION_CODE_LENGTH,
|
|
8
|
+
AuthenticatingInvitation,
|
|
9
9
|
CancellableInvitation,
|
|
10
10
|
INVITATION_TIMEOUT,
|
|
11
11
|
} from '@dxos/client-protocol';
|
|
12
12
|
import { Context } from '@dxos/context';
|
|
13
13
|
import { generatePasscode } from '@dxos/credentials';
|
|
14
|
-
import {
|
|
14
|
+
import { type MetadataStore, hasInvitationExpired } from '@dxos/echo-pipeline';
|
|
15
15
|
import { invariant } from '@dxos/invariant';
|
|
16
16
|
import { PublicKey } from '@dxos/keys';
|
|
17
17
|
import { log } from '@dxos/log';
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
import { SpaceMember } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
24
24
|
|
|
25
25
|
import type { InvitationProtocol } from './invitation-protocol';
|
|
26
|
-
import {
|
|
26
|
+
import { type InvitationsHandler, createAdmissionKeypair } from './invitations-handler';
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Entry point for creating and accepting invitations, keeps track of existing invitation set and
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { describe, expect, onTestFinished, test } from 'vitest';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Trigger, chain } from '@dxos/async';
|
|
8
8
|
import { raise } from '@dxos/debug';
|
|
9
9
|
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
10
10
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -22,7 +22,7 @@ const closeAfterTest = async (peer: ServiceContext) => {
|
|
|
22
22
|
|
|
23
23
|
describe('services/space-invitations-protocol', () => {
|
|
24
24
|
test('genesis', async () => {
|
|
25
|
-
const [peer] = await
|
|
25
|
+
const [peer] = await chain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(1));
|
|
26
26
|
|
|
27
27
|
const space = await peer.dataSpaceManager!.createSpace();
|
|
28
28
|
expect(peer.dataSpaceManager!.spaces.has(space.key)).to.be.true;
|
|
@@ -31,7 +31,7 @@ describe('services/space-invitations-protocol', () => {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
test('genesis & ready', async () => {
|
|
34
|
-
const [peer] = await
|
|
34
|
+
const [peer] = await chain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(1));
|
|
35
35
|
|
|
36
36
|
const space = await peer.dataSpaceManager!.createSpace();
|
|
37
37
|
expect(peer.dataSpaceManager!.spaces.has(space.key)).to.be.true;
|
|
@@ -41,7 +41,7 @@ describe('services/space-invitations-protocol', () => {
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
test('invitation with no auth', async () => {
|
|
44
|
-
const [host, guest] = await
|
|
44
|
+
const [host, guest] = await chain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
45
45
|
|
|
46
46
|
const space1 = await host.dataSpaceManager!.createSpace();
|
|
47
47
|
const spaceKey = space1.key;
|
|
@@ -65,7 +65,7 @@ describe('services/space-invitations-protocol', () => {
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
test('invitation when already joined', async () => {
|
|
68
|
-
const [host, guest] = await
|
|
68
|
+
const [host, guest] = await chain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
69
69
|
|
|
70
70
|
const space1 = await host.dataSpaceManager!.createSpace();
|
|
71
71
|
const spaceKey = space1.key;
|
|
@@ -92,7 +92,7 @@ describe('services/space-invitations-protocol', () => {
|
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
test('creates and accepts invitation with retry', async () => {
|
|
95
|
-
const [host, guest] = await
|
|
95
|
+
const [host, guest] = await chain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
96
96
|
|
|
97
97
|
let attempt = 0;
|
|
98
98
|
|
|
@@ -153,7 +153,7 @@ describe('services/space-invitations-protocol', () => {
|
|
|
153
153
|
});
|
|
154
154
|
|
|
155
155
|
test('timeout', async () => {
|
|
156
|
-
const [host, guest] = await
|
|
156
|
+
const [host, guest] = await chain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
157
157
|
const space = await host.dataSpaceManager!.createSpace();
|
|
158
158
|
const hostInvitation = await createInvitation(host, {
|
|
159
159
|
kind: Invitation.Kind.SPACE,
|
|
@@ -175,7 +175,7 @@ describe('services/space-invitations-protocol', () => {
|
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
test('cancels invitation', async () => {
|
|
178
|
-
const [host, guest] = await
|
|
178
|
+
const [host, guest] = await chain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
179
179
|
|
|
180
180
|
const hostConnected = new Trigger<Invitation>();
|
|
181
181
|
const guestConnected = new Trigger<Invitation>();
|
|
@@ -12,24 +12,19 @@ import { invariant } from '@dxos/invariant';
|
|
|
12
12
|
import { type Keyring } from '@dxos/keyring';
|
|
13
13
|
import { type PublicKey } from '@dxos/keys';
|
|
14
14
|
import { log } from '@dxos/log';
|
|
15
|
-
import {
|
|
16
|
-
AlreadyJoinedError,
|
|
17
|
-
type ApiError,
|
|
18
|
-
AuthorizationError,
|
|
19
|
-
InvalidInvitationError,
|
|
20
|
-
SpaceNotFoundError,
|
|
21
|
-
} from '@dxos/protocols';
|
|
15
|
+
import { AlreadyJoinedError, AuthorizationError, InvalidInvitationError, SpaceNotFoundError } from '@dxos/protocols';
|
|
22
16
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
23
|
-
import {
|
|
17
|
+
import { type ProfileDocument, SpaceMember } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
24
18
|
import {
|
|
25
19
|
type AdmissionRequest,
|
|
26
20
|
type AdmissionResponse,
|
|
27
21
|
type IntroductionRequest,
|
|
28
22
|
} from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
29
23
|
|
|
24
|
+
import { type DataSpaceManager, type SigningContext } from '../spaces';
|
|
25
|
+
|
|
30
26
|
import { type InvitationProtocol } from './invitation-protocol';
|
|
31
27
|
import { computeExpirationTime } from './utils';
|
|
32
|
-
import { type DataSpaceManager, type SigningContext } from '../spaces';
|
|
33
28
|
|
|
34
29
|
export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
35
30
|
constructor(
|
|
@@ -47,16 +42,16 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
47
42
|
};
|
|
48
43
|
}
|
|
49
44
|
|
|
50
|
-
checkCanInviteNewMembers():
|
|
45
|
+
checkCanInviteNewMembers(): Error | undefined {
|
|
51
46
|
if (this._spaceKey == null) {
|
|
52
|
-
return new InvalidInvitationError('No spaceKey was provided for a space invitation.');
|
|
47
|
+
return new InvalidInvitationError({ message: 'No spaceKey was provided for a space invitation.' });
|
|
53
48
|
}
|
|
54
49
|
const space = this._spaceManager.spaces.get(this._spaceKey);
|
|
55
50
|
if (space == null) {
|
|
56
51
|
return new SpaceNotFoundError(this._spaceKey);
|
|
57
52
|
}
|
|
58
53
|
if (!space?.inner.spaceState.hasMembershipManagementPermission(this._signingContext.identityKey)) {
|
|
59
|
-
return new AuthorizationError('No member management permission.');
|
|
54
|
+
return new AuthorizationError({ message: 'No member management permission.' });
|
|
60
55
|
}
|
|
61
56
|
return undefined;
|
|
62
57
|
}
|
|
@@ -147,10 +142,10 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
147
142
|
|
|
148
143
|
checkInvitation(invitation: Partial<Invitation>): InvalidInvitationError | AlreadyJoinedError | undefined {
|
|
149
144
|
if (invitation.spaceKey == null) {
|
|
150
|
-
return new InvalidInvitationError('No spaceKey was provided for a space invitation.');
|
|
145
|
+
return new InvalidInvitationError({ message: 'No spaceKey was provided for a space invitation.' });
|
|
151
146
|
}
|
|
152
147
|
if (this._spaceManager.spaces.has(invitation.spaceKey)) {
|
|
153
|
-
return new AlreadyJoinedError('Already joined space.');
|
|
148
|
+
return new AlreadyJoinedError({ message: 'Already joined space.' });
|
|
154
149
|
}
|
|
155
150
|
}
|
|
156
151
|
|
|
@@ -183,7 +178,7 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
183
178
|
invariant(credential.subject.id.equals(this._signingContext.identityKey));
|
|
184
179
|
|
|
185
180
|
if (this._spaceManager.spaces.has(assertion.spaceKey)) {
|
|
186
|
-
throw new AlreadyJoinedError('Already joined space.');
|
|
181
|
+
throw new AlreadyJoinedError({ message: 'Already joined space.' });
|
|
187
182
|
}
|
|
188
183
|
|
|
189
184
|
// Create local space.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Mutex, type MutexGuard } from '@dxos/async';
|
|
6
|
-
import {
|
|
6
|
+
import { type Context, ContextDisposedError, cancelWithContext } from '@dxos/context';
|
|
7
7
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
8
8
|
|
|
9
9
|
export const stateToString = (state: Invitation.State): string => {
|
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
log,
|
|
14
14
|
} from '@dxos/log';
|
|
15
15
|
import {
|
|
16
|
+
type ControlMetricsRequest,
|
|
17
|
+
type ControlMetricsResponse,
|
|
16
18
|
type LogEntry,
|
|
17
19
|
type LoggingService,
|
|
18
20
|
type Metrics,
|
|
19
21
|
QueryLogsRequest,
|
|
20
|
-
type ControlMetricsRequest,
|
|
21
|
-
type ControlMetricsResponse,
|
|
22
22
|
type QueryMetricsRequest,
|
|
23
23
|
type QueryMetricsResponse,
|
|
24
24
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -26,6 +26,10 @@ import { getDebugName, jsonify, numericalValues, tracer } from '@dxos/util';
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Logging service used to spy on logs of the host.
|
|
29
|
+
*
|
|
30
|
+
* @deprecated This was created so that logs from the shared worker (WorkerClientServices) could be
|
|
31
|
+
* seen in the main window console without opening the shared worker DevTools. Shared worker client
|
|
32
|
+
* services is deprecated; dedicated worker logs already show in the main window console.
|
|
29
33
|
*/
|
|
30
34
|
export class LoggingServiceImpl implements LoggingService {
|
|
31
35
|
private readonly _logs = new Event<NaturalLogEntry>();
|
|
@@ -37,7 +41,7 @@ export class LoggingServiceImpl implements LoggingService {
|
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
async close(): Promise<void> {
|
|
40
|
-
const index = log.runtimeConfig.processors.findIndex((processor) => processor === this._logProcessor);
|
|
44
|
+
const index = log.runtimeConfig.processors.findIndex((processor: LogProcessor) => processor === this._logProcessor);
|
|
41
45
|
log.runtimeConfig.processors.splice(index, 1);
|
|
42
46
|
}
|
|
43
47
|
|
|
@@ -112,6 +116,7 @@ export class LoggingServiceImpl implements LoggingService {
|
|
|
112
116
|
|
|
113
117
|
const record: LogEntry = {
|
|
114
118
|
...entry,
|
|
119
|
+
message: entry.message ?? (entry.error ? (entry.error.message ?? String(entry.error)) : ''),
|
|
115
120
|
context: jsonify(getContextFromEntry(entry)),
|
|
116
121
|
timestamp: new Date(),
|
|
117
122
|
meta: {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
|
-
import {
|
|
8
|
+
import { LogLevel, log } from '@dxos/log';
|
|
9
9
|
import { type LogEntry } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
10
|
|
|
11
11
|
import { LoggingServiceImpl } from './logging-service';
|
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { afterEach,
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, onTestFinished, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
|
-
import { type NetworkService
|
|
9
|
+
import { ConnectionState, type NetworkService } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
10
|
|
|
11
|
-
import { NetworkServiceImpl } from './network-service';
|
|
12
11
|
import { type ServiceContext } from '../services';
|
|
13
12
|
import { createServiceContext } from '../testing';
|
|
14
13
|
|
|
14
|
+
import { NetworkServiceImpl } from './network-service';
|
|
15
|
+
|
|
15
16
|
describe('NetworkService', () => {
|
|
16
17
|
let serviceContext: ServiceContext;
|
|
17
18
|
let networkService: NetworkService;
|
|
@@ -7,15 +7,15 @@ import { type EdgeConnection } from '@dxos/edge-client';
|
|
|
7
7
|
import { type SignalManager } from '@dxos/messaging';
|
|
8
8
|
import { type SwarmNetworkManager } from '@dxos/network-manager';
|
|
9
9
|
import {
|
|
10
|
-
type SubscribeSwarmStateRequest,
|
|
11
10
|
type NetworkService,
|
|
12
11
|
type NetworkStatus,
|
|
12
|
+
type SubscribeSwarmStateRequest,
|
|
13
13
|
type UpdateConfigRequest,
|
|
14
14
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
15
15
|
import { type Peer, type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
|
|
16
16
|
import {
|
|
17
|
-
type LeaveRequest,
|
|
18
17
|
type JoinRequest,
|
|
18
|
+
type LeaveRequest,
|
|
19
19
|
type Message,
|
|
20
20
|
type QueryRequest,
|
|
21
21
|
} from '@dxos/protocols/proto/dxos/edge/signal';
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
import { type ClientServices } from '@dxos/client-protocol';
|
|
6
6
|
import { type Any, type ServiceHandler, Stream } from '@dxos/codec-protobuf';
|
|
7
7
|
import { raise } from '@dxos/debug';
|
|
8
|
-
import {
|
|
8
|
+
import { RpcPeer, type RpcPeerOptions, type ServiceBundle, parseMethodName } from '@dxos/rpc';
|
|
9
9
|
import { MapCounter, trace } from '@dxos/tracing';
|
|
10
10
|
import { type MaybePromise } from '@dxos/util';
|
|
11
11
|
|
|
12
12
|
import { type ServiceRegistry } from './service-registry';
|
|
13
13
|
|
|
14
|
-
export type
|
|
14
|
+
export type ClientRpcServerProps = {
|
|
15
15
|
serviceRegistry: ServiceRegistry<ClientServices>;
|
|
16
16
|
handleCall?: (
|
|
17
17
|
method: string,
|
|
@@ -30,8 +30,8 @@ export class ClientRpcServer {
|
|
|
30
30
|
private readonly _serviceRegistry: ServiceRegistry<ClientServices>;
|
|
31
31
|
private readonly _rpcPeer: RpcPeer;
|
|
32
32
|
private readonly _handlerCache = new Map<string, ServiceHandler<any>>();
|
|
33
|
-
private readonly _handleCall:
|
|
34
|
-
private readonly _handleStream:
|
|
33
|
+
private readonly _handleCall: ClientRpcServerProps['handleCall'];
|
|
34
|
+
private readonly _handleStream: ClientRpcServerProps['handleStream'];
|
|
35
35
|
|
|
36
36
|
@trace.metricsCounter()
|
|
37
37
|
private readonly _callMetrics = new MapCounter();
|
|
@@ -41,7 +41,7 @@ export class ClientRpcServer {
|
|
|
41
41
|
return Object.keys(this._serviceRegistry.services);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
constructor(params:
|
|
44
|
+
constructor(params: ClientRpcServerProps) {
|
|
45
45
|
const { serviceRegistry, handleCall, handleStream, ...rpcOptions } = params;
|
|
46
46
|
this._handleCall = handleCall;
|
|
47
47
|
this._handleStream = handleStream;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import type * as SqlClient from '@effect/sql/SqlClient';
|
|
6
|
+
import { Encoder, decode as cborXdecode } from 'cbor-x';
|
|
7
|
+
import * as Effect from 'effect/Effect';
|
|
8
|
+
import * as Schema from 'effect/Schema';
|
|
9
|
+
|
|
10
|
+
import { AsyncTask, scheduleTask } from '@dxos/async';
|
|
11
|
+
import { Resource } from '@dxos/context';
|
|
12
|
+
import { type EdgeConnection, MessageSchema } from '@dxos/edge-client';
|
|
13
|
+
import { RuntimeProvider } from '@dxos/effect';
|
|
14
|
+
import { type FeedStore, SyncClient } from '@dxos/feed';
|
|
15
|
+
import { type SpaceId } from '@dxos/keys';
|
|
16
|
+
import { FeedProtocol } from '@dxos/protocols';
|
|
17
|
+
import { EdgeService } from '@dxos/protocols';
|
|
18
|
+
import { createBuf } from '@dxos/protocols/buf';
|
|
19
|
+
import { type Message as RouterMessage } from '@dxos/protocols/buf/dxos/edge/messenger_pb';
|
|
20
|
+
import type { SqlTransaction } from '@dxos/sql-sqlite';
|
|
21
|
+
import { bufferToArray } from '@dxos/util';
|
|
22
|
+
|
|
23
|
+
const encoder = new Encoder({ tagUint8Array: false, useRecords: false });
|
|
24
|
+
|
|
25
|
+
const DEFAULT_MESSAGE_BLOCKS_LIMIT = 50;
|
|
26
|
+
const DEFAULT_SYNC_CONCURRENCY = 5;
|
|
27
|
+
const DEFAULT_POLLING_INTERVAL = 10_000;
|
|
28
|
+
|
|
29
|
+
interface FeedSyncerOptions {
|
|
30
|
+
runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlTransaction.SqlTransaction>;
|
|
31
|
+
feedStore: FeedStore;
|
|
32
|
+
edgeClient: EdgeConnection;
|
|
33
|
+
peerId: string;
|
|
34
|
+
getSpaceIds: () => SpaceId[];
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Namespace to sync.
|
|
38
|
+
*/
|
|
39
|
+
// TODO(dmaretskyi): Syncing only one namespace is supported.
|
|
40
|
+
syncNamespace: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Maximum number of blocks to sync in a single message.
|
|
44
|
+
* @default 50
|
|
45
|
+
*/
|
|
46
|
+
messageBlocksLimit?: number;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Maximum number of spaces to sync concurrently.
|
|
50
|
+
* @default 5
|
|
51
|
+
*/
|
|
52
|
+
syncConcurrency?: number;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Interval between full polls.
|
|
56
|
+
* @default 10 seconds
|
|
57
|
+
*/
|
|
58
|
+
pollingInterval?: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class FeedSyncer extends Resource {
|
|
62
|
+
readonly #syncNamespace: string;
|
|
63
|
+
readonly #messageBlocksLimit: number;
|
|
64
|
+
readonly #syncConcurrency: number;
|
|
65
|
+
readonly #pollingInterval: number;
|
|
66
|
+
|
|
67
|
+
readonly #runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlTransaction.SqlTransaction>;
|
|
68
|
+
readonly #feedStore: FeedStore;
|
|
69
|
+
readonly #edgeClient: EdgeConnection;
|
|
70
|
+
readonly #syncClient: SyncClient;
|
|
71
|
+
readonly #getSpaceIds: () => SpaceId[];
|
|
72
|
+
|
|
73
|
+
#spacesToPoll = new Set<SpaceId>();
|
|
74
|
+
/** Last time full poll was completed. */
|
|
75
|
+
#lastFullPoll: number | null = null;
|
|
76
|
+
|
|
77
|
+
constructor(options: FeedSyncerOptions) {
|
|
78
|
+
super();
|
|
79
|
+
this.#runtime = options.runtime;
|
|
80
|
+
this.#feedStore = options.feedStore;
|
|
81
|
+
this.#edgeClient = options.edgeClient;
|
|
82
|
+
this.#syncClient = new SyncClient({
|
|
83
|
+
peerId: options.peerId,
|
|
84
|
+
feedStore: options.feedStore,
|
|
85
|
+
sendMessage: this.#sendMessage.bind(this),
|
|
86
|
+
});
|
|
87
|
+
this.#getSpaceIds = options.getSpaceIds;
|
|
88
|
+
this.#syncNamespace = options.syncNamespace;
|
|
89
|
+
this.#messageBlocksLimit = options.messageBlocksLimit ?? DEFAULT_MESSAGE_BLOCKS_LIMIT;
|
|
90
|
+
this.#syncConcurrency = options.syncConcurrency ?? DEFAULT_SYNC_CONCURRENCY;
|
|
91
|
+
this.#pollingInterval = options.pollingInterval ?? DEFAULT_POLLING_INTERVAL;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
protected override async _open(): Promise<void> {
|
|
95
|
+
this._ctx.onDispose(
|
|
96
|
+
this.#edgeClient.onMessage((msg: RouterMessage) => {
|
|
97
|
+
if (!msg.serviceId) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const service = msg.serviceId.split(':')[0];
|
|
101
|
+
if (service !== EdgeService.QUEUE_REPLICATOR) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const handleMessageEffect = Effect.gen(this, function* () {
|
|
105
|
+
const decoded = yield* Effect.try({
|
|
106
|
+
try: () => cborXdecode(msg.payload!.value),
|
|
107
|
+
catch: (error) => new Error(`Failed to decode feed sync message: ${error}`),
|
|
108
|
+
});
|
|
109
|
+
const payload = yield* Schema.decodeUnknown(FeedProtocol.ProtocolMessage)(decoded);
|
|
110
|
+
yield* this.#syncClient.handleMessage(payload);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
void RuntimeProvider.runPromise(this.#runtime)(handleMessageEffect);
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
this._ctx.onDispose(
|
|
118
|
+
// NOTE: This will fire immediately if the connection is already open.
|
|
119
|
+
this.#edgeClient.onReconnected(async () => {}),
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
this.#feedStore.onNewBlocks.on(this._ctx, () => {
|
|
123
|
+
this.#pushTask.schedule();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
await this.#pollTask.open();
|
|
127
|
+
await this.#pushTask.open();
|
|
128
|
+
|
|
129
|
+
this.#resetSpacesToPoll();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
protected override async _close(): Promise<void> {
|
|
133
|
+
await this.#pollTask.close();
|
|
134
|
+
await this.#pushTask.close();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
#resetSpacesToPoll(): void {
|
|
138
|
+
this.#spacesToPoll.clear();
|
|
139
|
+
this.#getSpaceIds().forEach((spaceId) => {
|
|
140
|
+
this.#spacesToPoll.add(spaceId);
|
|
141
|
+
});
|
|
142
|
+
this.#lastFullPoll = Date.now();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
#sendMessage(message: FeedProtocol.QueryRequest | FeedProtocol.AppendRequest): Effect.Effect<void, unknown, never> {
|
|
146
|
+
return Effect.gen(this, function* () {
|
|
147
|
+
const encoded = encoder.encode(message);
|
|
148
|
+
yield* Effect.tryPromise(async () =>
|
|
149
|
+
this.#edgeClient.send(
|
|
150
|
+
createBuf(MessageSchema, {
|
|
151
|
+
source: {
|
|
152
|
+
identityKey: this.#edgeClient.identityKey,
|
|
153
|
+
peerKey: this.#edgeClient.peerKey,
|
|
154
|
+
},
|
|
155
|
+
serviceId: this.#getTargetServiceId(message),
|
|
156
|
+
payload: { value: bufferToArray(encoded) },
|
|
157
|
+
}),
|
|
158
|
+
),
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#getTargetServiceId(message: FeedProtocol.QueryRequest | FeedProtocol.AppendRequest): string {
|
|
164
|
+
// TODO(dmaretskyi): Perhaps in the future we will want to include the queue namespace here as well.
|
|
165
|
+
// This would require putting it at the top level of the message.
|
|
166
|
+
// For now, we let the edge router handle it.
|
|
167
|
+
return FeedProtocol.encodeServiceId(message.feedNamespace, message.spaceId as SpaceId);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
readonly #pollTask = new AsyncTask(async () =>
|
|
171
|
+
Effect.gen(this, function* () {
|
|
172
|
+
yield* Effect.forEach(
|
|
173
|
+
this.#spacesToPoll,
|
|
174
|
+
(spaceId) =>
|
|
175
|
+
Effect.gen(this, function* () {
|
|
176
|
+
const { done } = yield* this.#syncClient.pull({
|
|
177
|
+
spaceId,
|
|
178
|
+
feedNamespace: this.#syncNamespace,
|
|
179
|
+
limit: this.#messageBlocksLimit,
|
|
180
|
+
});
|
|
181
|
+
if (done) {
|
|
182
|
+
this.#spacesToPoll.delete(spaceId);
|
|
183
|
+
}
|
|
184
|
+
}),
|
|
185
|
+
{ concurrency: this.#syncConcurrency },
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// If its time to do a full poll, reset the spaces to poll and schedule the next poll immediately.
|
|
189
|
+
if (this.#lastFullPoll == null || Date.now() - this.#lastFullPoll > this.#pollingInterval) {
|
|
190
|
+
this.#resetSpacesToPoll();
|
|
191
|
+
this.#pollTask.schedule();
|
|
192
|
+
} else if (this.#spacesToPoll.size > 0) {
|
|
193
|
+
// If there are some spaces still syncing, poll them immediately.
|
|
194
|
+
this.#pollTask.schedule();
|
|
195
|
+
} else {
|
|
196
|
+
// All spaces sync, and there's time before the next full poll, schedule it later.
|
|
197
|
+
this.#resetSpacesToPoll();
|
|
198
|
+
scheduleTask(
|
|
199
|
+
this._ctx,
|
|
200
|
+
() => this.#pollTask.schedule(),
|
|
201
|
+
Math.max(this.#pollingInterval - (Date.now() - (this.#lastFullPoll ?? 0)), 0),
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}).pipe(RuntimeProvider.runPromise(this.#runtime)),
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
readonly #pushTask = new AsyncTask(async () =>
|
|
208
|
+
Effect.gen(this, function* () {
|
|
209
|
+
yield* Effect.forEach(
|
|
210
|
+
this.#getSpaceIds(),
|
|
211
|
+
(spaceId) =>
|
|
212
|
+
Effect.gen(this, function* () {
|
|
213
|
+
const { done } = yield* this.#syncClient.push({
|
|
214
|
+
spaceId,
|
|
215
|
+
feedNamespace: this.#syncNamespace,
|
|
216
|
+
limit: this.#messageBlocksLimit,
|
|
217
|
+
});
|
|
218
|
+
if (!done) {
|
|
219
|
+
// Keep pushing until all blocks are pushed.
|
|
220
|
+
this.#pushTask.schedule();
|
|
221
|
+
}
|
|
222
|
+
}),
|
|
223
|
+
{ concurrency: this.#syncConcurrency },
|
|
224
|
+
);
|
|
225
|
+
}).pipe(RuntimeProvider.runPromise(this.#runtime)),
|
|
226
|
+
);
|
|
227
|
+
}
|
|
@@ -14,12 +14,18 @@ export const getPlatform = (): Platform => {
|
|
|
14
14
|
userAgent,
|
|
15
15
|
uptime: Math.floor((Date.now() - window.performance.timeOrigin) / 1_000),
|
|
16
16
|
};
|
|
17
|
-
} else {
|
|
17
|
+
} else if (typeof SharedWorkerGlobalScope !== 'undefined') {
|
|
18
18
|
// Shared worker.
|
|
19
19
|
return {
|
|
20
20
|
type: Platform.PLATFORM_TYPE.SHARED_WORKER,
|
|
21
21
|
uptime: Math.floor((Date.now() - performance.timeOrigin) / 1_000),
|
|
22
22
|
};
|
|
23
|
+
} else {
|
|
24
|
+
// Dedicated worker.
|
|
25
|
+
return {
|
|
26
|
+
type: Platform.PLATFORM_TYPE.DEDICATED_WORKER,
|
|
27
|
+
uptime: Math.floor((Date.now() - performance.timeOrigin) / 1_000),
|
|
28
|
+
};
|
|
23
29
|
}
|
|
24
30
|
} else {
|
|
25
31
|
// Node.
|