@dxos/client-services 0.8.4-main.84f28bd → 0.8.4-main.8baae0fced
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/{chunk-OCFDRCSN.mjs → chunk-KBMYCFTL.mjs} +3177 -4457
- package/dist/lib/browser/chunk-KBMYCFTL.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/chunk-XJRPB3GA.mjs +22 -0
- package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +451 -145
- 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 +88 -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 +86 -0
- package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/node.mjs +48 -0
- package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +35 -36
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +22 -0
- package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +7 -0
- 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-D7F3FYZS.mjs → chunk-TCS4PMDH.mjs} +3056 -4204
- package/dist/lib/node-esm/chunk-TCS4PMDH.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +451 -145
- 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 +88 -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 +86 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs +48 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +35 -36
- 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 +3 -2
- 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/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 +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 +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-collector.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +3 -4
- 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/identity-manager.d.ts +7 -7
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +8 -7
- 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 +9 -12
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +6 -5
- 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 +2 -2
- 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 +8 -5
- 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 +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 +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 +4 -4
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +5 -4
- 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/index.d.ts +2 -2
- package/dist/types/src/packlets/locks/index.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 +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 +7 -6
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts +5 -5
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
- package/dist/types/src/packlets/services/feed-syncer.test.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 -10
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +21 -8
- 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 +8 -2
- 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 +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 +31 -20
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +30 -13
- 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/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 +6 -9
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +11 -8
- 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 +2 -2
- 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 +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 +41 -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 -4
- 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/src/version.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +73 -56
- package/src/index.ts +1 -0
- package/src/packlets/agents/edge-agent-manager.ts +10 -7
- package/src/packlets/agents/edge-agent-service.ts +17 -5
- package/src/packlets/devices/devices-service.test.ts +3 -3
- package/src/packlets/devices/devices-service.ts +2 -2
- package/src/packlets/devtools/devtools.ts +29 -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 +2 -3
- 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 +2 -2
- package/src/packlets/identity/identity-manager.test.ts +8 -8
- package/src/packlets/identity/identity-manager.ts +25 -24
- package/src/packlets/identity/identity-recovery-manager.ts +22 -18
- package/src/packlets/identity/identity-service.test.ts +8 -28
- package/src/packlets/identity/identity-service.ts +13 -80
- package/src/packlets/identity/identity.test.ts +11 -11
- package/src/packlets/identity/identity.ts +17 -39
- package/src/packlets/invitations/device-invitation-protocol.test.ts +4 -4
- package/src/packlets/invitations/device-invitation-protocol.ts +8 -6
- package/src/packlets/invitations/edge-invitation-handler.ts +10 -6
- 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 +15 -16
- package/src/packlets/invitations/invitation-protocol.ts +8 -5
- package/src/packlets/invitations/invitation-state.ts +1 -15
- package/src/packlets/invitations/invitations-handler.test.ts +301 -292
- package/src/packlets/invitations/invitations-handler.ts +77 -25
- package/src/packlets/invitations/invitations-manager.ts +43 -18
- package/src/packlets/invitations/invitations-service.ts +10 -10
- package/src/packlets/invitations/space-invitation-protocol.test.ts +26 -25
- package/src/packlets/invitations/space-invitation-protocol.ts +13 -17
- 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 +22 -17
- package/src/packlets/logging/logging.test.ts +1 -1
- package/src/packlets/network/network-service.test.ts +3 -3
- package/src/packlets/network/network-service.ts +12 -10
- package/src/packlets/services/client-rpc-server.ts +20 -17
- package/src/packlets/services/feed-syncer.test.ts +340 -0
- package/src/packlets/services/feed-syncer.ts +377 -0
- package/src/packlets/services/platform.ts +7 -1
- package/src/packlets/services/service-context.test.ts +4 -3
- package/src/packlets/services/service-context.ts +160 -67
- package/src/packlets/services/service-host.test.ts +10 -9
- package/src/packlets/services/service-host.ts +86 -47
- package/src/packlets/services/service-registry.test.ts +1 -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 +65 -4
- package/src/packlets/space-export/space-archive-writer.ts +44 -6
- package/src/packlets/space-export/space-archive.test.ts +461 -0
- 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.test.ts +79 -13
- package/src/packlets/spaces/data-space-manager.ts +134 -129
- package/src/packlets/spaces/data-space.ts +71 -42
- package/src/packlets/spaces/edge-feed-replicator.test.ts +4 -4
- package/src/packlets/spaces/edge-feed-replicator.ts +13 -11
- package/src/packlets/spaces/epoch-migrations.ts +6 -5
- package/src/packlets/spaces/genesis.ts +6 -1
- package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
- package/src/packlets/spaces/notarization-plugin.ts +13 -12
- package/src/packlets/spaces/spaces-service.test.ts +20 -12
- package/src/packlets/spaces/spaces-service.ts +140 -38
- 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 +11 -7
- package/src/packlets/testing/test-builder.ts +39 -13
- package/src/packlets/worker/worker-runtime.ts +189 -17
- package/src/packlets/worker/worker-session.ts +15 -21
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-OCFDRCSN.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-D7F3FYZS.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
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { save } from '@automerge/automerge';
|
|
6
|
-
import { type DocHandle } from '@automerge/automerge-repo';
|
|
6
|
+
import { type AutomergeUrl, type DocHandle } from '@automerge/automerge-repo';
|
|
7
7
|
|
|
8
8
|
import { Event, Mutex, scheduleTask, sleep, synchronized, trackLeaks } from '@dxos/async';
|
|
9
9
|
import { AUTH_TIMEOUT } from '@dxos/client-protocol';
|
|
@@ -11,48 +11,48 @@ import { Context, ContextDisposedError, cancelWithContext } from '@dxos/context'
|
|
|
11
11
|
import type { SpecificCredential } from '@dxos/credentials';
|
|
12
12
|
import { timed, warnAfterTimeout } from '@dxos/debug';
|
|
13
13
|
import {
|
|
14
|
-
type EchoHost,
|
|
15
14
|
type DatabaseRoot,
|
|
16
|
-
|
|
15
|
+
type EchoHost,
|
|
17
16
|
type MetadataStore,
|
|
18
17
|
type Space,
|
|
19
|
-
|
|
18
|
+
createMappedFeedWriter,
|
|
20
19
|
} from '@dxos/echo-pipeline';
|
|
21
|
-
import {
|
|
20
|
+
import { type DatabaseDirectory, SpaceDocVersion } from '@dxos/echo-protocol';
|
|
22
21
|
import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
|
|
23
22
|
import { type FeedStore, type FeedWrapper } from '@dxos/feed-store';
|
|
24
23
|
import { failedInvariant, invariant } from '@dxos/invariant';
|
|
25
24
|
import { type Keyring } from '@dxos/keyring';
|
|
26
25
|
import { PublicKey } from '@dxos/keys';
|
|
27
26
|
import { log } from '@dxos/log';
|
|
28
|
-
import { CancelledError, SystemError } from '@dxos/protocols';
|
|
27
|
+
import { CancelledError, type FeedProtocol, SystemError } from '@dxos/protocols';
|
|
29
28
|
import {
|
|
30
29
|
type CreateEpochRequest,
|
|
31
|
-
SpaceState,
|
|
32
30
|
type Space as SpaceProto,
|
|
31
|
+
SpaceState,
|
|
33
32
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
34
33
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
35
34
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
36
35
|
import { type SpaceCache } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
37
36
|
import {
|
|
38
37
|
AdmittedFeed,
|
|
39
|
-
SpaceMember,
|
|
40
38
|
type Credential,
|
|
41
39
|
type Epoch,
|
|
40
|
+
MembershipPolicy,
|
|
42
41
|
type ProfileDocument,
|
|
42
|
+
SpaceMember,
|
|
43
43
|
} from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
44
44
|
import { type GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
|
|
45
45
|
import { type Gossip, type Presence } from '@dxos/teleport-extension-gossip';
|
|
46
46
|
import { Timeframe } from '@dxos/timeframe';
|
|
47
47
|
import { trace } from '@dxos/tracing';
|
|
48
|
-
import { CallbackCollection, ComplexSet
|
|
48
|
+
import { type AsyncCallback, CallbackCollection, ComplexSet } from '@dxos/util';
|
|
49
49
|
|
|
50
|
+
import { TrustedKeySetAuthVerifier } from '../identity';
|
|
50
51
|
import { AutomergeSpaceState } from './automerge-space-state';
|
|
51
52
|
import { type SigningContext } from './data-space-manager';
|
|
52
53
|
import { EdgeFeedReplicator } from './edge-feed-replicator';
|
|
53
54
|
import { runEpochMigration } from './epoch-migrations';
|
|
54
55
|
import { NotarizationPlugin } from './notarization-plugin';
|
|
55
|
-
import { TrustedKeySetAuthVerifier } from '../identity';
|
|
56
56
|
|
|
57
57
|
export type DataSpaceCallbacks = {
|
|
58
58
|
/**
|
|
@@ -71,7 +71,7 @@ export type DataSpaceCallbacks = {
|
|
|
71
71
|
beforeClose?: () => Promise<void>;
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
export type
|
|
74
|
+
export type DataSpaceProps = {
|
|
75
75
|
initialState: SpaceState;
|
|
76
76
|
inner: Space;
|
|
77
77
|
metadataStore: MetadataStore;
|
|
@@ -83,6 +83,7 @@ export type DataSpaceParams = {
|
|
|
83
83
|
signingContext: SigningContext;
|
|
84
84
|
callbacks?: DataSpaceCallbacks;
|
|
85
85
|
cache?: SpaceCache;
|
|
86
|
+
tags?: string[];
|
|
86
87
|
edgeConnection?: EdgeConnection;
|
|
87
88
|
edgeHttpClient?: EdgeHttpClient;
|
|
88
89
|
edgeFeatures?: Runtime.Client.EdgeFeatures;
|
|
@@ -120,6 +121,9 @@ export class DataSpace {
|
|
|
120
121
|
|
|
121
122
|
private _state = SpaceState.SPACE_CLOSED;
|
|
122
123
|
|
|
124
|
+
/** Immutable tags from space metadata, available immediately. */
|
|
125
|
+
readonly tags: string[];
|
|
126
|
+
|
|
123
127
|
private _databaseRoot: DatabaseRoot | null = null;
|
|
124
128
|
|
|
125
129
|
/**
|
|
@@ -135,7 +139,7 @@ export class DataSpace {
|
|
|
135
139
|
|
|
136
140
|
public metrics: SpaceProto.Metrics = {};
|
|
137
141
|
|
|
138
|
-
constructor(params:
|
|
142
|
+
constructor(params: DataSpaceProps) {
|
|
139
143
|
this._inner = params.inner;
|
|
140
144
|
this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());
|
|
141
145
|
|
|
@@ -167,6 +171,7 @@ export class DataSpace {
|
|
|
167
171
|
});
|
|
168
172
|
|
|
169
173
|
this._cache = params.cache;
|
|
174
|
+
this.tags = params.tags ?? [];
|
|
170
175
|
|
|
171
176
|
if (params.edgeConnection && params.edgeFeatures?.feedReplicator) {
|
|
172
177
|
this._edgeFeedReplicator = new EdgeFeedReplicator({ messenger: params.edgeConnection, spaceId: this.id });
|
|
@@ -212,6 +217,11 @@ export class DataSpace {
|
|
|
212
217
|
return this._cache;
|
|
213
218
|
}
|
|
214
219
|
|
|
220
|
+
/** Membership policy from the genesis credential, defaults to INVITE. */
|
|
221
|
+
get membershipPolicy(): MembershipPolicy {
|
|
222
|
+
return this._inner.spaceState.genesisCredential ? this._inner.spaceState.membershipPolicy : MembershipPolicy.INVITE;
|
|
223
|
+
}
|
|
224
|
+
|
|
215
225
|
get automergeSpaceState() {
|
|
216
226
|
return this._automergeSpaceState;
|
|
217
227
|
}
|
|
@@ -229,13 +239,14 @@ export class DataSpace {
|
|
|
229
239
|
}
|
|
230
240
|
|
|
231
241
|
@synchronized
|
|
232
|
-
|
|
242
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
243
|
+
async open(ctx: Context): Promise<void> {
|
|
233
244
|
if (this._state === SpaceState.SPACE_CLOSED) {
|
|
234
|
-
await this._open();
|
|
245
|
+
await this._open(ctx);
|
|
235
246
|
}
|
|
236
247
|
}
|
|
237
248
|
|
|
238
|
-
private async _open(): Promise<void> {
|
|
249
|
+
private async _open(ctx: Context): Promise<void> {
|
|
239
250
|
await this._presence.open();
|
|
240
251
|
await this._gossip.open();
|
|
241
252
|
await this._notarizationPlugin.open();
|
|
@@ -247,8 +258,8 @@ export class DataSpace {
|
|
|
247
258
|
this.inner.protocol.feedAdded.append(this._onFeedAdded);
|
|
248
259
|
}
|
|
249
260
|
|
|
250
|
-
await this._inner.open(
|
|
251
|
-
await this._inner.startProtocol();
|
|
261
|
+
await this._inner.open(ctx);
|
|
262
|
+
await this._inner.startProtocol(ctx);
|
|
252
263
|
|
|
253
264
|
await this._edgeFeedReplicator?.open();
|
|
254
265
|
|
|
@@ -262,11 +273,12 @@ export class DataSpace {
|
|
|
262
273
|
}
|
|
263
274
|
|
|
264
275
|
@synchronized
|
|
265
|
-
|
|
266
|
-
|
|
276
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
277
|
+
async close(ctx: Context): Promise<void> {
|
|
278
|
+
await this._close(ctx);
|
|
267
279
|
}
|
|
268
280
|
|
|
269
|
-
private async _close(): Promise<void> {
|
|
281
|
+
private async _close(ctx: Context): Promise<void> {
|
|
270
282
|
await this._callbacks.beforeClose?.();
|
|
271
283
|
|
|
272
284
|
await this.preClose.callSerial();
|
|
@@ -284,7 +296,7 @@ export class DataSpace {
|
|
|
284
296
|
|
|
285
297
|
await this.authVerifier.close();
|
|
286
298
|
|
|
287
|
-
await this._inner.close();
|
|
299
|
+
await this._inner.close(ctx);
|
|
288
300
|
await this._inner.spaceState.removeCredentialProcessor(this._automergeSpaceState);
|
|
289
301
|
await this._automergeSpaceState.close();
|
|
290
302
|
await this._inner.spaceState.removeCredentialProcessor(this._notarizationPlugin);
|
|
@@ -304,12 +316,14 @@ export class DataSpace {
|
|
|
304
316
|
|
|
305
317
|
/**
|
|
306
318
|
* Initialize the data pipeline in a separate task.
|
|
319
|
+
* @param callerCtx - Trace context from the caller (e.g., activate or createSpace) for span parenting.
|
|
307
320
|
*/
|
|
308
|
-
initializeDataPipelineAsync(): void {
|
|
321
|
+
initializeDataPipelineAsync(callerCtx?: Context): void {
|
|
322
|
+
const traceCtx = callerCtx ?? this._ctx;
|
|
309
323
|
scheduleTask(this._ctx, async () => {
|
|
310
324
|
try {
|
|
311
325
|
this.metrics.pipelineInitBegin = new Date();
|
|
312
|
-
await this.initializeDataPipeline();
|
|
326
|
+
await this.initializeDataPipeline(traceCtx);
|
|
313
327
|
} catch (err) {
|
|
314
328
|
if (err instanceof CancelledError || err instanceof ContextDisposedError) {
|
|
315
329
|
log('data pipeline initialization cancelled', err);
|
|
@@ -327,17 +341,17 @@ export class DataSpace {
|
|
|
327
341
|
});
|
|
328
342
|
}
|
|
329
343
|
|
|
330
|
-
@trace.span({ showInBrowserTimeline: true })
|
|
331
|
-
async initializeDataPipeline(): Promise<void> {
|
|
344
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
345
|
+
async initializeDataPipeline(ctx: Context): Promise<void> {
|
|
332
346
|
if (this._state !== SpaceState.SPACE_CONTROL_ONLY) {
|
|
333
|
-
throw new SystemError('Invalid operation');
|
|
347
|
+
throw new SystemError({ message: 'Invalid operation' });
|
|
334
348
|
}
|
|
335
349
|
|
|
336
350
|
this._state = SpaceState.SPACE_INITIALIZING;
|
|
337
351
|
log('new state', { state: SpaceState[this._state] });
|
|
338
352
|
|
|
339
353
|
log('initializing control pipeline');
|
|
340
|
-
await this._initializeAndReadControlPipeline();
|
|
354
|
+
await this._initializeAndReadControlPipeline(ctx);
|
|
341
355
|
|
|
342
356
|
// Allow other tasks to run before loading the data pipeline.
|
|
343
357
|
await sleep(1);
|
|
@@ -360,11 +374,19 @@ export class DataSpace {
|
|
|
360
374
|
yield [this._databaseRoot.documentId, root];
|
|
361
375
|
|
|
362
376
|
for (const documentUrl of this._databaseRoot.getAllLinkedDocuments()) {
|
|
363
|
-
const data = await this._echoHost.exportDoc(
|
|
377
|
+
const data = await this._echoHost.exportDoc(documentUrl);
|
|
364
378
|
yield [documentUrl.replace(/^automerge:/, ''), data];
|
|
365
379
|
}
|
|
366
380
|
}
|
|
367
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Get all feeds and their blocks for this space.
|
|
384
|
+
* Used for space archive export.
|
|
385
|
+
*/
|
|
386
|
+
async getAllFeeds(): Promise<Array<{ feedId: string; feedNamespace: string; blocks: FeedProtocol.Block[] }>> {
|
|
387
|
+
return this._echoHost.getAllFeedsForSpace(this.id);
|
|
388
|
+
}
|
|
389
|
+
|
|
368
390
|
private async _enterReadyState(): Promise<void> {
|
|
369
391
|
await this._callbacks.beforeReady?.();
|
|
370
392
|
|
|
@@ -375,10 +397,10 @@ export class DataSpace {
|
|
|
375
397
|
await this._callbacks.afterReady?.();
|
|
376
398
|
}
|
|
377
399
|
|
|
378
|
-
@trace.span({ showInBrowserTimeline: true })
|
|
379
|
-
private async _initializeAndReadControlPipeline(): Promise<void> {
|
|
400
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
401
|
+
private async _initializeAndReadControlPipeline(ctx: Context): Promise<void> {
|
|
380
402
|
await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
|
|
381
|
-
ctx
|
|
403
|
+
ctx,
|
|
382
404
|
timeout: 10_000,
|
|
383
405
|
breakOnStall: false,
|
|
384
406
|
});
|
|
@@ -450,6 +472,9 @@ export class DataSpace {
|
|
|
450
472
|
|
|
451
473
|
log('credentials notarized');
|
|
452
474
|
} catch (err) {
|
|
475
|
+
if (err instanceof ContextDisposedError) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
453
478
|
log.error('error notarizing credentials for feed admission', err);
|
|
454
479
|
throw err;
|
|
455
480
|
}
|
|
@@ -462,7 +487,7 @@ export class DataSpace {
|
|
|
462
487
|
private _onNewAutomergeRoot(rootUrl: string): void {
|
|
463
488
|
log('loading automerge root doc for space', { space: this.key, rootUrl });
|
|
464
489
|
|
|
465
|
-
let handle: DocHandle<DatabaseDirectory
|
|
490
|
+
let handle: DocHandle<DatabaseDirectory> | null = null;
|
|
466
491
|
|
|
467
492
|
// TODO(dmaretskyi): Make this single-threaded (but doc loading should still be parallel to not block epoch processing).
|
|
468
493
|
queueMicrotask(async () => {
|
|
@@ -470,19 +495,24 @@ export class DataSpace {
|
|
|
470
495
|
await warnAfterTimeout(5_000, 'Automerge root doc load timeout (DataSpace)', async () => {
|
|
471
496
|
handle = await cancelWithContext(
|
|
472
497
|
this._ctx,
|
|
473
|
-
this._echoHost.
|
|
498
|
+
this._echoHost.loadDoc<DatabaseDirectory>(this._ctx, rootUrl as AutomergeUrl, {
|
|
499
|
+
fetchFromNetwork: true,
|
|
500
|
+
}),
|
|
474
501
|
);
|
|
475
|
-
await cancelWithContext(this._ctx, handle.whenReady());
|
|
476
502
|
});
|
|
477
503
|
if (this._ctx.disposed) {
|
|
478
504
|
return;
|
|
479
505
|
}
|
|
506
|
+
if (!handle) {
|
|
507
|
+
log.warn('automerge root doc not available yet', { space: this.key, rootUrl });
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
480
510
|
|
|
481
511
|
// Ensure only one root is processed at a time.
|
|
482
512
|
using _guard = await this._epochProcessingMutex.acquire();
|
|
483
513
|
|
|
484
514
|
// Attaching space keys to legacy documents.
|
|
485
|
-
const doc = handle.doc()
|
|
515
|
+
const doc = handle.doc();
|
|
486
516
|
if (!doc.access?.spaceKey) {
|
|
487
517
|
handle.change((doc: any) => {
|
|
488
518
|
doc.access = { spaceKey: this.key.toHex() };
|
|
@@ -491,7 +521,7 @@ export class DataSpace {
|
|
|
491
521
|
|
|
492
522
|
// TODO(dmaretskyi): Close roots.
|
|
493
523
|
// TODO(dmaretskyi): How do we handle changing to the next EPOCH?
|
|
494
|
-
const root = await this._echoHost.openSpaceRoot(this.id, handle.url);
|
|
524
|
+
const root = await this._echoHost.openSpaceRoot(this._ctx, this.id, handle.url);
|
|
495
525
|
|
|
496
526
|
// NOTE: Make sure this assignment happens synchronously together with the state change.
|
|
497
527
|
this._databaseRoot = root;
|
|
@@ -568,25 +598,24 @@ export class DataSpace {
|
|
|
568
598
|
}
|
|
569
599
|
|
|
570
600
|
@synchronized
|
|
571
|
-
async activate(): Promise<void> {
|
|
601
|
+
async activate(ctx: Context): Promise<void> {
|
|
572
602
|
if (![SpaceState.SPACE_CLOSED, SpaceState.SPACE_INACTIVE].includes(this._state)) {
|
|
573
603
|
return;
|
|
574
604
|
}
|
|
575
605
|
|
|
576
606
|
await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_ACTIVE);
|
|
577
|
-
await this._open();
|
|
578
|
-
this.initializeDataPipelineAsync();
|
|
607
|
+
await this._open(ctx);
|
|
608
|
+
this.initializeDataPipelineAsync(ctx);
|
|
579
609
|
}
|
|
580
610
|
|
|
581
611
|
@synchronized
|
|
582
|
-
async deactivate(): Promise<void> {
|
|
612
|
+
async deactivate(ctx: Context): Promise<void> {
|
|
583
613
|
if (this._state === SpaceState.SPACE_INACTIVE) {
|
|
584
614
|
return;
|
|
585
615
|
}
|
|
586
|
-
// Unregister from data service.
|
|
587
616
|
await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_INACTIVE);
|
|
588
617
|
if (this._state !== SpaceState.SPACE_CLOSED) {
|
|
589
|
-
await this._close();
|
|
618
|
+
await this._close(ctx);
|
|
590
619
|
}
|
|
591
620
|
this._state = SpaceState.SPACE_INACTIVE;
|
|
592
621
|
log('new state', { state: SpaceState[this._state] });
|
|
@@ -6,10 +6,10 @@ import { decode as decodeCbor, encode as encodeCbor } from 'cbor-x';
|
|
|
6
6
|
import { getPort } from 'get-port-please';
|
|
7
7
|
import { describe, expect, onTestFinished, test, vi } from 'vitest';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { Trigger, sleep } from '@dxos/async';
|
|
10
10
|
import { Context } from '@dxos/context';
|
|
11
11
|
import { valueEncoding } from '@dxos/echo-pipeline';
|
|
12
|
-
import {
|
|
12
|
+
import { EdgeClient, EdgeIdentityChangedError, createEphemeralEdgeIdentity } from '@dxos/edge-client';
|
|
13
13
|
import { createTestEdgeWsServer } from '@dxos/edge-client/testing';
|
|
14
14
|
import { FeedFactory, FeedStore, type FeedWrapper } from '@dxos/feed-store';
|
|
15
15
|
import { Keyring } from '@dxos/keyring';
|
|
@@ -45,7 +45,7 @@ describe('EdgeFeedReplicator', () => {
|
|
|
45
45
|
const { endpoint, admitConnection, messageSink } = await createEdge();
|
|
46
46
|
const { messenger } = await createClient(endpoint);
|
|
47
47
|
admitConnection.wake();
|
|
48
|
-
await expect.poll(() => messenger.status).toBe(EdgeStatus.CONNECTED);
|
|
48
|
+
await expect.poll(() => messenger.status.state).toBe(EdgeStatus.ConnectionState.CONNECTED);
|
|
49
49
|
|
|
50
50
|
await attachReplicator(messenger);
|
|
51
51
|
await expect.poll(() => messageSink.length).toEqual(1);
|
|
@@ -107,7 +107,7 @@ describe('EdgeFeedReplicator', () => {
|
|
|
107
107
|
const { feed } = await attachReplicator(messenger);
|
|
108
108
|
await appendMessage(feed);
|
|
109
109
|
|
|
110
|
-
sendSpy.mockImplementationOnce(async (request: any) => {
|
|
110
|
+
sendSpy.mockImplementationOnce(async (_ctx: any, request: any) => {
|
|
111
111
|
sendResponseMessage(request, encodeCbor({ type: 'metadata', feedKey: feed.key.toHex(), length: 0 }));
|
|
112
112
|
return Promise.resolve();
|
|
113
113
|
});
|
|
@@ -15,14 +15,14 @@ import { log, logInfo } from '@dxos/log';
|
|
|
15
15
|
import { EdgeService } from '@dxos/protocols';
|
|
16
16
|
import { buf } from '@dxos/protocols/buf';
|
|
17
17
|
import {
|
|
18
|
-
MessageSchema as RouterMessageSchema,
|
|
19
18
|
type Message as RouterMessage,
|
|
19
|
+
MessageSchema as RouterMessageSchema,
|
|
20
20
|
} from '@dxos/protocols/buf/dxos/edge/messenger_pb';
|
|
21
21
|
import type { FeedBlock, ProtocolMessage } from '@dxos/protocols/feed-replication';
|
|
22
22
|
import { EdgeStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
23
23
|
import { ComplexMap, arrayToBuffer, bufferToArray, defaultMap, rangeFromTo } from '@dxos/util';
|
|
24
24
|
|
|
25
|
-
export type
|
|
25
|
+
export type EdgeFeedReplicatorProps = {
|
|
26
26
|
messenger: EdgeConnection;
|
|
27
27
|
spaceId: SpaceId;
|
|
28
28
|
};
|
|
@@ -47,7 +47,7 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
47
47
|
*/
|
|
48
48
|
private _pushMutex = new ComplexMap<PublicKey, Mutex>(PublicKey.hash);
|
|
49
49
|
|
|
50
|
-
constructor({ messenger, spaceId }:
|
|
50
|
+
constructor({ messenger, spaceId }: EdgeFeedReplicatorProps) {
|
|
51
51
|
super();
|
|
52
52
|
this._messenger = messenger;
|
|
53
53
|
this._spaceId = spaceId;
|
|
@@ -87,7 +87,7 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
87
87
|
|
|
88
88
|
private async _handleReconnect(): Promise<void> {
|
|
89
89
|
await this._resetConnection();
|
|
90
|
-
if (this._messenger.status === EdgeStatus.CONNECTED) {
|
|
90
|
+
if (this._messenger.status.state === EdgeStatus.ConnectionState.CONNECTED) {
|
|
91
91
|
this._startReplication();
|
|
92
92
|
}
|
|
93
93
|
}
|
|
@@ -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;
|
|
@@ -36,8 +36,8 @@ const LOAD_DOC_TIMEOUT = 10_000;
|
|
|
36
36
|
export const runEpochMigration = async (ctx: Context, context: MigrationContext): Promise<MigrationResult> => {
|
|
37
37
|
switch (context.migration) {
|
|
38
38
|
case CreateEpochRequest.Migration.INIT_AUTOMERGE: {
|
|
39
|
-
const document = context.echoHost.createDoc();
|
|
40
|
-
await context.echoHost.flush();
|
|
39
|
+
const document = await context.echoHost.createDoc();
|
|
40
|
+
await context.echoHost.flush(ctx);
|
|
41
41
|
return { newRoot: document.url };
|
|
42
42
|
}
|
|
43
43
|
case CreateEpochRequest.Migration.PRUNE_AUTOMERGE_ROOT_HISTORY: {
|
|
@@ -47,9 +47,10 @@ export const runEpochMigration = async (ctx: Context, context: MigrationContext)
|
|
|
47
47
|
const rootHandle = await context.echoHost.loadDoc(ctx, context.currentRoot as AutomergeUrl, {
|
|
48
48
|
timeout: LOAD_DOC_TIMEOUT,
|
|
49
49
|
});
|
|
50
|
+
invariant(rootHandle, 'Automerge root document must load for history prune migration.');
|
|
50
51
|
|
|
51
|
-
const newRoot = context.echoHost.createDoc(rootHandle.doc());
|
|
52
|
-
await context.echoHost.flush();
|
|
52
|
+
const newRoot = await context.echoHost.createDoc(rootHandle.doc());
|
|
53
|
+
await context.echoHost.flush(ctx);
|
|
53
54
|
return { newRoot: newRoot.url };
|
|
54
55
|
}
|
|
55
56
|
case CreateEpochRequest.Migration.FRAGMENT_AUTOMERGE_ROOT: {
|
|
@@ -63,7 +64,7 @@ export const runEpochMigration = async (ctx: Context, context: MigrationContext)
|
|
|
63
64
|
invariant(context.newAutomergeRoot);
|
|
64
65
|
|
|
65
66
|
// Defensive programming - it should be the responsibility of the caller to flush the new root.
|
|
66
|
-
await context.echoHost.flush();
|
|
67
|
+
await context.echoHost.flush(ctx);
|
|
67
68
|
return {
|
|
68
69
|
newRoot: context.newAutomergeRoot,
|
|
69
70
|
};
|
|
@@ -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
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { describe, expect, onTestFinished, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { Context } from '@dxos/context';
|
|
8
8
|
import { CredentialGenerator } from '@dxos/credentials';
|
|
@@ -13,7 +13,7 @@ import { log } from '@dxos/log';
|
|
|
13
13
|
import { AdmittedFeed, type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
14
14
|
import { TestBuilder, type TestConnection, TestPeer } from '@dxos/teleport/testing';
|
|
15
15
|
|
|
16
|
-
import { NotarizationPlugin, type
|
|
16
|
+
import { NotarizationPlugin, type NotarizationPluginProps } from './notarization-plugin';
|
|
17
17
|
|
|
18
18
|
class TestAgent extends TestPeer {
|
|
19
19
|
private readonly _ctx = new Context();
|
|
@@ -21,7 +21,7 @@ class TestAgent extends TestPeer {
|
|
|
21
21
|
feed = new MockFeedWriter<Credential>();
|
|
22
22
|
notarizationPlugin: NotarizationPlugin;
|
|
23
23
|
|
|
24
|
-
constructor(params:
|
|
24
|
+
constructor(params: NotarizationPluginProps) {
|
|
25
25
|
super();
|
|
26
26
|
this.notarizationPlugin = new NotarizationPlugin(params);
|
|
27
27
|
this.feed.written.on(this._ctx, async ([credential]) => {
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { DeferredTask, Event,
|
|
6
|
-
import { type Context,
|
|
5
|
+
import { DeferredTask, Event, TimeoutError, Trigger, scheduleMicroTask, scheduleTask, sleep } from '@dxos/async';
|
|
6
|
+
import { type Context, Resource, rejectOnDispose } from '@dxos/context';
|
|
7
7
|
import { type CredentialProcessor, verifyCredential } from '@dxos/credentials';
|
|
8
8
|
import { type EdgeHttpClient } from '@dxos/edge-client';
|
|
9
9
|
import { type FeedWriter } from '@dxos/feed-store';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { PublicKey } from '@dxos/keys';
|
|
12
12
|
import { type SpaceId } from '@dxos/keys';
|
|
13
|
-
import {
|
|
13
|
+
import { log, logInfo } from '@dxos/log';
|
|
14
14
|
import { EdgeCallFailedError } from '@dxos/protocols';
|
|
15
15
|
import { schema } from '@dxos/protocols/proto';
|
|
16
16
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
@@ -33,14 +33,14 @@ const WRITER_NOT_SET_ERROR_CODE = 'WRITER_NOT_SET';
|
|
|
33
33
|
|
|
34
34
|
const credentialCodec = schema.getCodecForType('dxos.halo.credentials.Credential');
|
|
35
35
|
|
|
36
|
-
export type
|
|
36
|
+
export type NotarizationPluginProps = {
|
|
37
37
|
spaceId: SpaceId;
|
|
38
38
|
edgeClient?: EdgeHttpClient;
|
|
39
39
|
edgeFeatures?: Runtime.Client.EdgeFeatures;
|
|
40
40
|
activeEdgePollingInterval?: number;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
export type
|
|
43
|
+
export type NotarizeProps = {
|
|
44
44
|
/**
|
|
45
45
|
* For cancellation.
|
|
46
46
|
*/
|
|
@@ -97,7 +97,7 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
|
|
|
97
97
|
|
|
98
98
|
private readonly _edgeClient: EdgeHttpClient | undefined;
|
|
99
99
|
|
|
100
|
-
constructor(params:
|
|
100
|
+
constructor(params: NotarizationPluginProps) {
|
|
101
101
|
super();
|
|
102
102
|
this._spaceId = params.spaceId;
|
|
103
103
|
this._activeEdgePollingInterval = params.activeEdgePollingInterval ?? DEFAULT_ACTIVE_EDGE_POLLING_INTERVAL;
|
|
@@ -149,7 +149,7 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
|
|
|
149
149
|
retryTimeout = DEFAULT_RETRY_TIMEOUT,
|
|
150
150
|
successDelay = DEFAULT_SUCCESS_DELAY,
|
|
151
151
|
edgeRetryJitter,
|
|
152
|
-
}:
|
|
152
|
+
}: NotarizeProps): Promise<void> {
|
|
153
153
|
log('notarize', { credentials });
|
|
154
154
|
invariant(
|
|
155
155
|
credentials.every((credential) => credential.id),
|
|
@@ -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
|
|
|
@@ -392,21 +393,21 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
|
|
|
392
393
|
}
|
|
393
394
|
|
|
394
395
|
const handleEdgeError = (error: any) => {
|
|
395
|
-
if (!(error instanceof EdgeCallFailedError) || error.
|
|
396
|
+
if (!(error instanceof EdgeCallFailedError) || error.data) {
|
|
396
397
|
log.catch(error);
|
|
397
398
|
} else {
|
|
398
|
-
log.info('Edge notarization failure', {
|
|
399
|
+
log.info('Edge notarization failure', { message: error.message });
|
|
399
400
|
}
|
|
400
401
|
};
|
|
401
402
|
|
|
402
|
-
export type
|
|
403
|
+
export type NotarizationTeleportExtensionProps = {
|
|
403
404
|
onOpen: () => Promise<void>;
|
|
404
405
|
onClose: () => Promise<void>;
|
|
405
406
|
onNotarize: (request: NotarizeRequest) => Promise<void>;
|
|
406
407
|
};
|
|
407
408
|
|
|
408
409
|
export class NotarizationTeleportExtension extends RpcExtension<Services, Services> {
|
|
409
|
-
constructor(private readonly _params:
|
|
410
|
+
constructor(private readonly _params: NotarizationTeleportExtensionProps) {
|
|
410
411
|
super({
|
|
411
412
|
requested: {
|
|
412
413
|
NotarizationService: schema.getService('dxos.mesh.teleport.notarization.NotarizationService'),
|