@dxos/client-services 0.13.0 → 0.14.0
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/chunk-client-services-stack.mjs +43 -40
- package/dist/lib/chunk-client-services-stack.mjs.map +1 -1
- package/dist/types/src/internal/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +40 -40
- package/src/internal/invitations/invitations-handler.ts +7 -1
- package/src/version.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-client-services-stack.mjs","names":[],"sources":["../../src/contracts/identity.ts","../../src/contracts/spaces.ts","../../src/Events.ts","../../src/internal/agents/edge-agent-manager.ts","../../src/Readiness.ts","../../src/internal/agents/edge-agent-service.ts","../../src/contracts/invitations.ts","../../src/Auth.ts","../../src/CredentialsDocument.ts","../../src/internal/metadata/metadata-store.ts","../../src/migrations/metadata/index.ts","../../src/internal/metadata/sqlite-metadata-store.ts","../../src/internal/space/auth.ts","../../src/internal/pipeline/feeds.ts","../../src/internal/pipeline/message-selector.ts","../../src/internal/pipeline/timeframe-clock.ts","../../src/internal/pipeline/pipeline.ts","../../src/internal/pipeline/codec.ts","../../src/internal/space/control-pipeline.ts","../../src/internal/space/space.ts","../../src/internal/space/admission-discovery-extension.ts","../../src/internal/space/space-protocol.ts","../../src/internal/space/space-manager.ts","../../src/internal/devtools/feeds.ts","../../src/internal/devtools/keys.ts","../../src/internal/devtools/metadata.ts","../../src/internal/devtools/network.ts","../../src/internal/devtools/spaces.ts","../../src/internal/devtools/devtools.ts","../../src/PlatformInfo.ts","../../src/version.ts","../../src/internal/diagnostics/diagnostics.ts","../../src/Replication.ts","../../src/Identity.ts","../../src/internal/identity/contacts-service.ts","../../src/internal/identity/identity-recovery-manager.ts","../../src/internal/identity/identity-lifecycle.ts","../../src/internal/identity/identity-manager.ts","../../src/migrations/hypercore/index.ts","../../src/SqliteStorage.ts","../../src/internal/identity/identity-service.ts","../../src/internal/identity/inbox-service.ts","../../src/internal/invitations/device-invitation-protocol.ts","../../src/internal/invitations/utils.ts","../../src/internal/invitations/space-invitation-protocol.ts","../../src/internal/invitations/invitation-factories.ts","../../src/internal/invitations/edge-invitation-handler.ts","../../src/internal/invitations/invitation-guest-extenstion.ts","../../src/internal/invitations/invitation-host-extension.ts","../../src/internal/invitations/invitation-state.ts","../../src/internal/invitations/invitation-topology.ts","../../src/internal/invitations/invitations-handler.ts","../../src/internal/invitations/invitations-service.ts","../../src/internal/invitations/invitations-manager.ts","../../src/internal/services/client-platform.ts","../../src/internal/devices/devices-service.ts","../../src/internal/logging/logging-service.ts","../../src/internal/network/network-service.ts","../../src/internal/spaces/automerge-space-state.ts","../../src/internal/spaces/epoch-migrations.ts","../../src/internal/spaces/notarization-plugin.ts","../../src/internal/spaces/data-space.ts","../../src/internal/spaces/genesis.ts","../../src/internal/spaces/data-space-manager.ts","../../src/internal/space-export/archive-format.ts","../../src/internal/space-export/serialized-space-reader.ts","../../src/internal/space-export/serialized-space-writer.ts","../../src/internal/space-export/space-archive-reader.ts","../../src/internal/space-export/space-archive-writer.ts","../../src/internal/spaces/spaces-service.ts","../../src/internal/sql/sql-service.ts","../../src/internal/system/system-service.ts","../../src/internal/services/cross-device-space-synchronizer.ts","../../src/internal/services/feed-syncer.ts","../../src/internal/services/network-lifecycle.ts","../../src/internal/services/service-stack.ts","../../src/internal/services/layer-specs.ts","../../src/internal/services/client-services-stack.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\n\nimport { type Event } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { type EchoHost } from '@dxos/echo-host';\nimport { type PublicKey } from '@dxos/keys';\nimport { type Device } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type IdentityRecord } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport {\n type Credential,\n type DeviceProfileDocument,\n type ProfileDocument,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type Timeframe } from '@dxos/timeframe';\n\nimport { type Identity } from '../Identity.ts';\n\n//\n// The identity subsystem's contract: the interfaces its consumers depend on and the tags that carry\n// them. Nothing here imports an implementation, so depending on the contract cannot drag one in —\n// which a tag typed against an implementation class silently does, even through a type-only import.\n//\n\nexport type JoinIdentityProps = {\n identityKey: PublicKey;\n deviceKey: PublicKey;\n haloSpaceKey: PublicKey;\n haloGenesisFeedKey: PublicKey;\n controlFeedKey: PublicKey;\n dataFeedKey: PublicKey;\n authorizedDeviceCredential: Credential;\n /**\n * Automerge URL of the host's halo space root, when it has one. The joining device adopts it rather\n * than minting a second root over the same space.\n */\n haloSpaceRootUrl?: string;\n /**\n * Latest known timeframe for the control pipeline.\n * We will try to catch up to this timeframe before starting the data pipeline.\n */\n controlTimeframe?: Timeframe;\n /** Custom device profile, merged with defaults, applied once the identity is accepted. */\n deviceProfile?: DeviceProfileDocument;\n};\n\nexport type CreateIdentityOptions = {\n profile?: ProfileDocument;\n /** Device profile for the device creating the identity. */\n deviceProfile?: DeviceProfileDocument;\n};\n\n/**\n * The peer's identity state machine, as its consumers use it.\n */\nexport interface Manager {\n readonly stateUpdate: Event;\n readonly identity: Identity | undefined;\n open(ctx: Context): Promise<void>;\n close(ctx: Context): Promise<void>;\n deleteIdentity(ctx: Context): Promise<void>;\n updateProfile(profile: ProfileDocument): Promise<ProfileDocument>;\n updateDeviceProfile(profile: DeviceProfileDocument): Promise<Device>;\n setEchoHost(echoHost: EchoHost): Promise<void>;\n createIdentity(options?: CreateIdentityOptions, ctx?: Context): Promise<Identity>;\n prepareIdentity(\n params: JoinIdentityProps,\n ctx?: Context,\n ): Promise<{ identity: Identity; identityRecord: IdentityRecord }>;\n acceptIdentity(identity: Identity, identityRecord: IdentityRecord, profile?: DeviceProfileDocument): Promise<void>;\n}\n\n/**\n * Resolves the active identity when it becomes available.\n */\nexport type Provider = () => Identity;\n\n/**\n * Brings a new identity into the running stack: binds it to the network, joins, and announces it so\n * the identity-bound services open. The persisted identity on boot goes through the same events\n * from the host's open sequence.\n */\nexport interface Lifecycle {\n /** Creates a fresh identity and resolves once its identity-bound services are open. */\n createIdentity(params?: CreateIdentityOptions, ctx?: Context): Promise<Identity>;\n /** Adopts an identity admitted by another device and resolves once its services are open. */\n acceptIdentity(params: JoinIdentityProps): Promise<Identity>;\n}\n\n/** Effect service tag for {@link Manager}. */\nexport class ManagerService extends EffectContext.Service<ManagerService, Manager>()(\n '@dxos/client-services/IdentityManager',\n) {}\n\n/** Effect service tag for {@link Provider}. */\nexport class ProviderService extends EffectContext.Service<ProviderService, Provider>()(\n '@dxos/client-services/IdentityProvider',\n) {}\n\n/** Effect service tag for {@link Lifecycle}. */\nexport class LifecycleService extends EffectContext.Service<LifecycleService, Lifecycle>()(\n '@dxos/client-services/IdentityLifecycle',\n) {}\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type AutomergeUrl, type DocumentId } from '@automerge/automerge-repo';\nimport * as EffectContext from 'effect/Context';\n\nimport { type Event } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { type CredentialSigner } from '@dxos/credentials';\nimport { type SpaceRootRefs } from '@dxos/echo-host';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { type EdgeReplicationSetting } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport {\n type Credential,\n type MembershipPolicy,\n type ProfileDocument,\n type SpaceMember_Role,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type Timeframe } from '@dxos/timeframe';\nimport { type ComplexMap } from '@dxos/util';\n\n// The manager is a service, so it gets an interface; `DataSpace` is an aggregate its consumers use\n// as a rich object, so an interface over it would duplicate the class rather than abstract it.\n// `DataSpace` is an aggregate its consumers use as a rich object, so an interface over it would\n// duplicate the class rather than abstract it; it is the one implementation type the contract names.\nimport { type DataSpace } from '../internal/spaces/data-space.ts';\n\n//\n// The data-space subsystem's contract. See `contracts/identity.ts` for why the tags live with the\n// interfaces rather than with the implementations.\n//\n\n/** What a space needs from the identity to sign and record credentials on its behalf. */\nexport interface SigningContext {\n identityKey: PublicKey;\n deviceKey: PublicKey;\n credentialSigner: CredentialSigner;\n recordCredential: (credential: Credential) => Promise<void>;\n getProfile: () => ProfileDocument | undefined;\n}\n\nexport type SigningContextProvider = () => SigningContext;\n\nexport type AcceptSpaceOptions = {\n spaceKey: PublicKey;\n genesisFeedKey: PublicKey;\n\n /** From the admitting `SpaceMember` credential; absent for a space still on its control feed. */\n spaceRootUrl?: string;\n\n /**\n * Latest known timeframe for the control pipeline.\n * We will try to catch up to this timeframe before starting the data pipeline.\n */\n controlTimeframe?: Timeframe;\n\n /**\n * Latest known timeframe for the data pipeline.\n * We will try to catch up to this timeframe before initializing the database.\n */\n dataTimeframe?: Timeframe;\n\n /** Tags assigned to the space member. */\n tags?: string[];\n};\n\nexport type AdmitMemberOptions = {\n spaceKey: PublicKey;\n identityKey: PublicKey;\n role: SpaceMember_Role;\n profile?: ProfileDocument;\n delegationCredentialId?: PublicKey;\n tags?: string[];\n\n /** Successor to `genesisFeedKey`: what lets the admitted member replicate from this credential alone. */\n spaceRootUrl?: string;\n};\n\nexport type CreateSpaceOptions = {\n /**\n * Anchor the space on a space root document, taking its id from that document instead of from the\n * space key. Defaults to the `automergeCredentials` runtime flag, which is off — so a space is\n * key-derived unless the flag opts in. Ignored for an imported space, which brings its own root.\n */\n useSpaceRootDocument?: boolean;\n\n rootUrl?: AutomergeUrl;\n documents?: Record<DocumentId, Uint8Array>;\n tags?: string[];\n membershipPolicy?: MembershipPolicy;\n};\n\n/**\n * The open data spaces, as its consumers use it.\n */\nexport interface Manager {\n readonly updated: Event;\n open(ctx?: Context): Promise<unknown>;\n close(ctx?: Context): Promise<unknown>;\n waitUntilSpaceReady(spaceKey: PublicKey): Promise<void>;\n readonly spaces: ComplexMap<PublicKey, DataSpace>;\n getSpaceById(spaceId: SpaceId): DataSpace | undefined;\n isSpaceDeleted(spaceKey: PublicKey): boolean;\n createSpace(ctx: Context, options?: CreateSpaceOptions): Promise<DataSpace>;\n acceptSpace(ctx: Context, options: AcceptSpaceOptions): Promise<DataSpace>;\n migrateSpaceToRootDocument(ctx: Context, spaceKey: PublicKey): Promise<SpaceRootRefs>;\n markSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void>;\n deleteAllSpaces(ctx: Context): Promise<void>;\n handleRemoteSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void>;\n admitMember(options: AdmitMemberOptions): Promise<Credential>;\n requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential>;\n setSpaceEdgeReplicationSetting(ctx: Context, spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void>;\n}\n\n/** Effect service tag for {@link Manager}. */\nexport class ManagerService extends EffectContext.Service<ManagerService, Manager>()(\n '@dxos/client-services/DataSpaceManager',\n) {}\n\n/** Effect service tag for {@link SigningContextProvider}. */\nexport class SigningContextProviderService extends EffectContext.Service<\n SigningContextProviderService,\n SigningContextProvider\n>()('@dxos/client-services/SigningContextProvider') {}\n","//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Hook from '@dxos/effect/Hook';\nimport { type Credential, type ProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nimport { type Identity } from './Identity.ts';\n\n//\n// Lifecycle events of the client stack. Boot order is the chain of these events, each layer\n// subscribing to the fact it needs and emitting the fact it establishes:\n//\n// Opening → StorageReady → IdentityLoaded → NetworkReady (host emits Opening, then cascades).\n// IdentityBound (a created or accepted identity).\n// IdentityAvailable → DataSpacesAvailable (identity-bound services).\n// StackOpened (host, once the cascade is done).\n// NetworkingEnabled (auto-connect, or the embedder).\n//\n// Teardown has no events: each layer closes its component in its layer finalizer, so runtime\n// disposal unwinds the stack in reverse build order. A reset is the embedder's concern and runs on\n// the embedder's controller, which outlives the stack:\n//\n// Closing → WipingStorage → Reset (system service; the embedder handles).\n//\n// Payloads carry facts only. Cancellation and tracing ride on the Effect: a layer that needs a DXOS\n// `Context` for a component takes one from its scope (`EffectEx.contextFromScope`), and the host\n// emits under its open context (`EffectEx.withContext`) so handler spans nest under it.\n//\n\n/** The host is opening; nothing has been touched yet. */\nexport const Opening = Hook.make<void>()('client-services/Opening');\n\n/** Storage has been migrated, version-checked, and loaded. */\nexport const StorageReady = Hook.make<void>()('client-services/StorageReady');\n\n/** The identity manager is open; `identity` is the persisted identity, if there is one. */\nexport const IdentityLoaded = Hook.make<{ identity?: Identity }>()('client-services/IdentityLoaded');\n\n/** Edge, signaling, and swarm networking are open with the current network identity. */\nexport const NetworkReady = Hook.make<void>()('client-services/NetworkReady');\n\n/**\n * A new identity must be bound to the network before it joins; `deviceCredential` is present when\n * the identity was admitted by another device.\n */\nexport const IdentityBound = Hook.make<{ identity: Identity; deviceCredential?: Credential }>()(\n 'client-services/IdentityBound',\n);\n\n/** An identity has joined the network; identity-bound services may open. */\nexport const IdentityAvailable = Hook.make<{ identity: Identity }>()('client-services/IdentityAvailable');\n\n/** The data space manager is open. */\nexport const DataSpacesAvailable = Hook.make<{ identity: Identity }>()('client-services/DataSpacesAvailable');\n\n/** The open sequence has completed, with or without an identity. */\nexport const StackOpened = Hook.make<void>()('client-services/StackOpened');\n\n/** Outbound networking may begin; emitted on `StackOpened` when auto-connecting, else by the embedder. */\nexport const NetworkingEnabled = Hook.make<void>()('client-services/NetworkingEnabled');\n\n/** A reset began: the embedder disposes the stack. */\nexport const Closing = Hook.make<void>()('client-services/Closing');\n\n/** The stack is gone: the embedder wipes persisted storage so the next open starts fresh. */\nexport const WipingStorage = Hook.make<void>()('client-services/WipingStorage');\n\n/** Storage is wiped; the embedder typically reloads. */\nexport const Reset = Hook.make<void>()('client-services/Reset');\n\n/** The local profile changed and should be broadcast to every open space. */\nexport const ProfileUpdated = Hook.make<{ profile: ProfileDocument }>()('client-services/ProfileUpdated');\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { DeferredTask, Event, scheduleTask, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { Resource } from '@dxos/context';\nimport { type EdgeHttpClient, EdgeHttpClientService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { EdgeAgentStatus, EdgeCallFailedError } from '@dxos/protocols';\nimport { fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport { SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { EdgeReplicationSetting } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { DeviceAdmissionRequestSchema } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type IdentityProvider } from '../identity/index.ts';\n\nconst AGENT_STATUS_QUERY_RETRY_INTERVAL = 5000;\nconst AGENT_STATUS_QUERY_RETRY_JITTER = 1000;\nconst AGENT_FEED_ADDED_CHECK_INTERVAL_MS = 3000;\n\nexport type EdgeAgentManagerConfig = {};\n\n/**\n * Effect service tag for {@link EdgeAgentManager}.\n */\nexport class EdgeAgentManagerService extends EffectContext.Service<EdgeAgentManagerService, EdgeAgentManager>()(\n '@dxos/client-services/EdgeAgentManager',\n) {}\n\nexport class EdgeAgentManager extends Resource {\n public agentStatusChanged = new Event<EdgeAgentStatus>();\n\n private _agentDeviceKey: PublicKey | undefined;\n private _agentStatus: EdgeAgentStatus | undefined;\n\n private _lastKnownDeviceCount = 0;\n\n private _fetchAgentStatusTask: DeferredTask | undefined;\n\n constructor(\n private readonly _edgeFeatures: Runtime_Client_EdgeFeatures | undefined,\n private readonly _edgeHttpClient: EdgeHttpClient | undefined,\n private readonly _dataSpaceManager: SpacesContract.Manager,\n private readonly _identityProvider: IdentityProvider,\n ) {\n super();\n }\n\n private get identity(): Identity {\n return this._identityProvider();\n }\n\n public get agentStatus(): EdgeAgentStatus | undefined {\n return this._agentStatus;\n }\n\n public get agentExists() {\n return this._agentStatus && this._agentStatus !== EdgeAgentStatus.NOT_FOUND;\n }\n\n @synchronized\n public async createAgent(ctx: Context): Promise<void> {\n invariant(this.isOpen);\n invariant(this._edgeHttpClient);\n invariant(this._edgeFeatures?.agents);\n\n const response = await this._edgeHttpClient.createAgent(ctx, {\n identityDid: this.identity.did,\n haloSpaceId: this.identity.haloSpaceId,\n haloSpaceKey: this.identity.haloSpaceKey.toHex(),\n });\n\n const deviceKey = PublicKey.fromHex(response.deviceKey);\n\n if (await this.identity.authorizedDeviceKeys.has(deviceKey)) {\n log.info('agent was already added to HALO, ignoring response', { response });\n this._updateStatus(EdgeAgentStatus.ACTIVE, deviceKey);\n return;\n }\n\n await this.identity.admitDevice(\n create(DeviceAdmissionRequestSchema, {\n deviceKey: fromPublicKey(deviceKey),\n controlFeedKey: fromPublicKey(PublicKey.fromHex(response.feedKey)),\n // TODO: agents don't have data feed, should be removed\n dataFeedKey: fromPublicKey(PublicKey.random()),\n }),\n );\n\n log('agent created', response);\n\n this._updateStatus(EdgeAgentStatus.ACTIVE, deviceKey);\n }\n\n protected override async _open(): Promise<void> {\n const isEnabled = this._edgeHttpClient && this._edgeFeatures?.agents;\n\n log('edge agent manager open', { isEnabled });\n\n if (!isEnabled) {\n return;\n }\n\n this._lastKnownDeviceCount = this.identity.authorizedDeviceKeys.size;\n this._fetchAgentStatusTask = new DeferredTask(this._ctx, async () => {\n await this._fetchAgentStatus(this._ctx);\n });\n this._fetchAgentStatusTask.schedule();\n\n this._dataSpaceManager.updated.on(this._ctx, () => {\n if (this._agentDeviceKey) {\n this._ensureAgentIsInSpaces(this._agentDeviceKey);\n }\n });\n\n this.identity.stateUpdate.on(this._ctx, () => {\n const maybeAgentWasCreated = this.identity.authorizedDeviceKeys.size > this._lastKnownDeviceCount;\n if (this.agentExists || !maybeAgentWasCreated) {\n return;\n }\n this._lastKnownDeviceCount = this.identity.authorizedDeviceKeys.size;\n this._fetchAgentStatusTask?.schedule();\n });\n }\n\n protected override async _close(): Promise<void> {\n this._fetchAgentStatusTask = undefined;\n this._lastKnownDeviceCount = 0;\n this._agentStatus = undefined;\n this._agentDeviceKey = undefined;\n }\n\n protected async _fetchAgentStatus(ctx: Context): Promise<void> {\n invariant(this._edgeHttpClient);\n try {\n log('fetching agent status');\n const { agent } = await this._edgeHttpClient.getAgentStatus(ctx, {\n ownerIdentityDid: this.identity.did,\n });\n const wasAgentCreatedDuringQuery = this._agentStatus === EdgeAgentStatus.ACTIVE;\n if (!wasAgentCreatedDuringQuery) {\n const deviceKey = agent.deviceKey ? PublicKey.fromHex(agent.deviceKey) : undefined;\n this._updateStatus(agent.status, deviceKey);\n }\n } catch (err) {\n if (err instanceof EdgeCallFailedError) {\n if (!err.isRetryable) {\n log.warn('non retryable error on agent status fetch attempt', { err });\n return;\n }\n }\n const retryAfterMs = AGENT_STATUS_QUERY_RETRY_INTERVAL + Math.random() * AGENT_STATUS_QUERY_RETRY_JITTER;\n log.info('agent status fetching failed', { err, retryAfterMs });\n scheduleTask(this._ctx, () => this._fetchAgentStatusTask?.schedule(), retryAfterMs);\n }\n }\n\n /**\n * We don't want notarization plugin to always actively poll edge looking for credentials to notarize,\n * because most of the time we'll be getting an empty response.\n * Instead, we stay in active polling mode while there are spaces where we don't see our agent's feed.\n */\n protected _ensureAgentIsInSpaces(agentDeviceKey: PublicKey): void {\n let activePollingEnabled = false;\n for (const space of this._dataSpaceManager.spaces.values()) {\n if (space.getEdgeReplicationSetting() === EdgeReplicationSetting.DISABLED) {\n space.notarizationPlugin.setActiveEdgePollingEnabled(false);\n continue;\n }\n if ([SpaceState.SPACE_INACTIVE, SpaceState.SPACE_CLOSED].includes(space.state)) {\n space.notarizationPlugin.setActiveEdgePollingEnabled(false);\n continue;\n }\n const agentFeedNeedsNotarization = ![...space.inner.spaceState.feeds.values()].some((feed) =>\n requirePublicKey(feed.assertion.deviceKey).equals(agentDeviceKey),\n );\n space.notarizationPlugin.setActiveEdgePollingEnabled(agentFeedNeedsNotarization);\n activePollingEnabled = activePollingEnabled || agentFeedNeedsNotarization;\n\n log.verbose('set active edge polling', { enabled: agentFeedNeedsNotarization, spaceId: space.id });\n }\n\n if (activePollingEnabled) {\n // Check again to see if active edge polling can be disabled (agent feed is notarized in all the spaces)\n scheduleTask(this._ctx, () => this._ensureAgentIsInSpaces(agentDeviceKey), AGENT_FEED_ADDED_CHECK_INTERVAL_MS);\n }\n }\n\n private _updateStatus(status: EdgeAgentStatus, deviceKey: PublicKey | undefined): void {\n this._agentStatus = status;\n this._agentDeviceKey = deviceKey;\n this.agentStatusChanged.emit(status);\n if (deviceKey) {\n this._ensureAgentIsInSpaces(deviceKey);\n }\n log.verbose('agent status update', { status });\n }\n}\n\nexport type EdgeAgentManagerLayerOptions = {\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n};\n\n/**\n * Effect Layer constructing a dormant {@link EdgeAgentManager}.\n */\nexport const EdgeAgentManagerLayer = (\n options: EdgeAgentManagerLayerOptions = {},\n): Layer.Layer<\n EdgeAgentManagerService,\n never,\n Hook.Controller | SpacesContract.ManagerService | IdentityContract.ProviderService\n> =>\n Layer.effect(\n EdgeAgentManagerService,\n Effect.gen(function* () {\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const identityProvider = yield* IdentityContract.ProviderService;\n const edgeHttpClient = yield* Effect.serviceOption(EdgeHttpClientService);\n const edgeAgentManager = new EdgeAgentManager(\n options.edgeFeatures,\n Option.getOrUndefined(edgeHttpClient),\n dataSpaceManager,\n identityProvider,\n );\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(() => edgeAgentManager.close()));\n yield* Hook.on(\n Events.DataSpacesAvailable,\n Effect.fn('EdgeAgentManager.onDataSpacesAvailable')(function* () {\n // Rebound on every identity, so an identity deleted in place does not leave its agent's\n // status (and the subscriptions on its HALO) standing in for the next one's.\n yield* Effect.promise(() => edgeAgentManager.close());\n yield* Effect.promise(() => edgeAgentManager.open(ctx));\n }),\n );\n return edgeAgentManager;\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { Trigger } from '@dxos/async';\nimport * as Hook from '@dxos/effect/Hook';\n\nimport * as Events from './Events.ts';\n\n/**\n * Readiness gate for the identity-bound services: `initialized` wakes once the data spaces are\n * open, whether the identity was persisted, created, or accepted.\n */\nexport interface StackReadiness {\n readonly initialized: Trigger;\n}\n\nexport class StackReadinessService extends EffectContext.Service<StackReadinessService, StackReadiness>()(\n '@dxos/client-services/StackReadiness',\n) {}\n\nexport const StackReadinessLayer: Layer.Layer<StackReadinessService, never, Hook.Controller> = Layer.effect(\n StackReadinessService,\n Effect.gen(function* () {\n const initialized = new Trigger();\n yield* Hook.on(\n Events.DataSpacesAvailable,\n Effect.fn('StackReadiness.onDataSpacesAvailable')(function* () {\n initialized.wake();\n }),\n );\n return { initialized };\n }),\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { EdgeAgentStatus, toServiceError } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport {\n type QueryAgentStatusResponse,\n QueryAgentStatusResponse_AgentStatus,\n QueryAgentStatusResponseSchema,\n type QueryEdgeStatusResponse,\n QueryEdgeStatusResponseSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { EdgeAgentService } from '@dxos/protocols/rpc';\n\nimport * as Readiness from '../../Readiness.ts';\nimport { type EdgeAgentManager, EdgeAgentManagerService } from './edge-agent-manager.ts';\n\n// TODO(wittjosiah): This service is not currently exposed on the client api, it must be called directly.\nexport class EdgeAgentServiceImpl implements EdgeAgentService.Handlers {\n 'constructor'(\n private readonly _agentManagerProvider: () => Promise<EdgeAgentManager>,\n private readonly _edgeConnection?: EdgeConnection,\n ) {}\n\n // TODO(mykola): Reconcile with NetworkService.queryStatus.\n ['EdgeAgentService.queryEdgeStatus'](): EffectStream.Stream<QueryEdgeStatusResponse, Error> {\n return EffectEx.streamFromEmitter<QueryEdgeStatusResponse, Error>((emit) => {\n const ctx = Context.default();\n const update = () => {\n void emit.single(buf.create(QueryEdgeStatusResponseSchema, { status: this._edgeConnection?.status }));\n };\n\n this._edgeConnection?.statusChanged.on(ctx, update);\n update();\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['EdgeAgentService.createAgent'](): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => (await this._agentManagerProvider()).createAgent(Context.default()),\n catch: toServiceError,\n });\n }\n\n ['EdgeAgentService.queryAgentStatus'](): EffectStream.Stream<QueryAgentStatusResponse, Error> {\n return EffectEx.streamFromEmitter<QueryAgentStatusResponse, Error>((emit) => {\n const ctx = Context.default();\n void emit.single(\n buf.create(QueryAgentStatusResponseSchema, { status: QueryAgentStatusResponse_AgentStatus.UNKNOWN }),\n );\n void this._agentManagerProvider().then((agentManager) => {\n void emit.single(buf.create(QueryAgentStatusResponseSchema, { status: mapStatus(agentManager.agentStatus) }));\n agentManager.agentStatusChanged.on(ctx, (newStatus) => {\n void emit.single(buf.create(QueryAgentStatusResponseSchema, { status: mapStatus(newStatus) }));\n });\n });\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n}\n\nconst mapStatus = (agentStatus: EdgeAgentStatus | undefined): QueryAgentStatusResponse_AgentStatus => {\n switch (agentStatus) {\n case EdgeAgentStatus.ACTIVE:\n return QueryAgentStatusResponse_AgentStatus.ACTIVE;\n case EdgeAgentStatus.INACTIVE:\n return QueryAgentStatusResponse_AgentStatus.INACTIVE;\n case EdgeAgentStatus.NOT_FOUND:\n return QueryAgentStatusResponse_AgentStatus.NOT_FOUND;\n case undefined:\n return QueryAgentStatusResponse_AgentStatus.UNKNOWN;\n }\n};\n\nexport const EdgeAgentServiceLayer: Layer.Layer<\n EdgeAgentService.Tag,\n never,\n Readiness.StackReadinessService | EdgeAgentManagerService\n> = Layer.effect(\n EdgeAgentService.Tag,\n Effect.gen(function* () {\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n const readiness = yield* Readiness.StackReadinessService;\n const edgeAgentManager = yield* EdgeAgentManagerService;\n return new EdgeAgentServiceImpl(() => readiness.initialized.wait().then(() => edgeAgentManager), edgeConnection);\n }),\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\n\nimport { type Event } from '@dxos/async';\nimport { type AuthenticatingInvitation, type CancellableInvitation } from '@dxos/client-protocol';\nimport { type Context } from '@dxos/context';\nimport { type Invitation } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nimport { type InvitationProtocol } from './invitation-protocol.ts';\n\n//\n// The invitations subsystem's contract. See `contracts/identity.ts` for why the tags live with the\n// interfaces rather than with the implementations.\n//\n\n/**\n * Creates and tracks the in-flight invitations, as its consumers use it.\n */\nexport interface Manager {\n readonly invitationCreated: Event<Invitation>;\n readonly invitationAccepted: Event<Invitation>;\n readonly removedCreated: Event<Invitation>;\n readonly removedAccepted: Event<Invitation>;\n readonly saved: Event<Invitation>;\n getCreatedInvitations(): Invitation[];\n getAcceptedInvitations(): Invitation[];\n loadPersistentInvitations(ctx: Context): Promise<{ invitations: Invitation[] }>;\n onPersistentInvitationsLoaded(ctx: Context, callback: () => void): void;\n authenticate(request: { invitationId: string; authCode: string }): Promise<void>;\n setInvitationHandlerFactory(\n getHandler: (invitation: Partial<Invitation> & Pick<Invitation, 'kind'>) => InvitationProtocol,\n ): void;\n getInvitationHandler(invitation: Partial<Invitation> & Pick<Invitation, 'kind'>): InvitationProtocol;\n createInvitation(\n ctx: Context,\n options: Partial<Invitation> & Pick<Invitation, 'kind'>,\n ): Promise<CancellableInvitation>;\n cancelInvitation(request: { invitationId: string }): Promise<void>;\n acceptInvitation(\n ctx: Context,\n request: {\n invitation: Partial<Invitation> & Pick<Invitation, 'invitationId'>;\n deviceProfile?: DeviceProfileDocument;\n },\n ): AuthenticatingInvitation;\n}\n\n/** Effect service tag for {@link Manager}. */\nexport class ManagerService extends EffectContext.Service<ManagerService, Manager>()(\n '@dxos/client-services/InvitationsManager',\n) {}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create, fromBinary, toBinary } from '@bufbuild/protobuf';\n\nimport { type Event, Trigger } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type CredentialSigner, verifyCredential } from '@dxos/credentials';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport { AuthSchema, CredentialSchema } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type ComplexSet, arraysEqual } from '@dxos/util';\n\n// @import-as-namespace\n\n/** Produces a credential proving the peer may join the space, for the given nonce. */\nexport type AuthProvider = (nonce: Uint8Array) => Promise<Uint8Array | undefined>;\n\n/** Verifies a credential produced by an {@link AuthProvider}. */\nexport type AuthVerifier = (nonce: Uint8Array, credential: Uint8Array) => Promise<boolean>;\n\nexport const createAuthProvider =\n (signer: CredentialSigner): AuthProvider =>\n async (nonce) => {\n const credential = await signer.createCredential({\n assertion: create(AuthSchema, {}),\n subject: signer.getIssuer(),\n nonce,\n });\n\n return toBinary(CredentialSchema, credential);\n };\n\nexport type TrustedKeySetAuthVerifierProps = {\n // TODO(dmaretskyi): Change to `isTrusted: (key) => bool`.\n trustedKeysProvider: () => ComplexSet<PublicKey>;\n update: Event<void>;\n /**\n * Timeout to wait for the device key to be added to the trusted set.\n */\n authTimeout: number;\n};\n\n/**\n * Verifies credentials of another member in the space based on a set of trusted key.\n * Will wait up to `authTimeout` for the key to be added to the trusted set.\n */\nexport class TrustedKeySetAuthVerifier {\n private _ctx = new Context();\n\n constructor(private readonly _params: TrustedKeySetAuthVerifierProps) {}\n\n async close(): Promise<void> {\n await this._ctx.dispose();\n }\n\n get verifier(): AuthVerifier {\n return async (nonce, auth) => {\n const credential = fromBinary(CredentialSchema, auth);\n log('authenticating...', { credential });\n\n const result = await verifyCredential(credential);\n if (result.kind === 'fail') {\n log('Invalid credential', { result });\n return false;\n }\n\n const proofNonce = credential.proof?.nonce;\n // Compared as bytes: the browser `buffer` polyfill's `equals` rejects a plain `Uint8Array`,\n // which is what protobuf decoding yields for the nonce.\n if (!proofNonce?.length || !arraysEqual(nonce, proofNonce)) {\n log('Invalid nonce', { nonce, credential });\n return false;\n }\n\n const issuer = requirePublicKey(credential.issuer);\n if (this._isTrustedKey(issuer)) {\n log('key is trusted -- auth success', { key: issuer });\n return true;\n }\n\n const trigger = new Trigger<boolean>();\n this._ctx.onDispose(() => {\n trigger.wake(false);\n });\n\n const clear = this._params.update.on(this._ctx, () => {\n if (this._isTrustedKey(issuer)) {\n log('auth success', { key: issuer });\n trigger.wake(true);\n } else {\n log('key is not currently in trusted set, waiting...', {\n key: issuer,\n trusted: [...this._params.trustedKeysProvider()],\n });\n }\n });\n\n try {\n return await trigger.wait({ timeout: this._params.authTimeout });\n } catch {\n return false;\n } finally {\n clear();\n }\n };\n }\n\n private _isTrustedKey(deviceKey: PublicKey): boolean {\n const deviceSet = this._params.trustedKeysProvider();\n return deviceSet.has(deviceKey);\n }\n}\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type AutomergeUrl } from '@automerge/automerge-repo';\nimport { toBinary } from '@bufbuild/protobuf';\n\nimport { scheduleMicroTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport {\n CREDENTIALS_DOCUMENT_TYPE,\n type CredentialsDocument,\n type OrderedCredential,\n orderCredentials,\n} from '@dxos/credentials';\nimport { AddOnlySet } from '@dxos/echo-doc';\nimport { type DocumentLease, type EchoHost } from '@dxos/echo-host';\nimport { invariant } from '@dxos/invariant';\nimport { type SpaceId } from '@dxos/keys';\nimport { toPublicKey } from '@dxos/protocols/buf';\nimport { type Credential, CredentialSchema } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nconst CREDENTIALS_PATH = ['credentials'];\n\n/**\n * Read/write access to a space's credentials document, the successor to its control feed.\n */\nexport class CredentialsDocumentStore implements Disposable {\n readonly #lease: DocumentLease<CredentialsDocument>;\n\n constructor(lease: DocumentLease<CredentialsDocument>) {\n this.#lease = lease;\n }\n\n get url(): AutomergeUrl {\n return this.#lease.url;\n }\n\n /** Releases the credentials document; the store cannot be read or written after this. */\n [Symbol.dispose](): void {\n this.#lease[Symbol.dispose]();\n }\n\n /**\n * Credentials in the order the state machine must process them.\n *\n * Read from the change history rather than the current state: a member who can write to the\n * document must not be able to revoke another by deleting their credential.\n */\n read(): OrderedCredential[] {\n const doc = this.#lease.doc();\n return doc ? orderCredentials(AddOnlySet.read(doc, CREDENTIALS_PATH)) : [];\n }\n\n /**\n * Replays the document into `process` and keeps doing so as it changes. Ordering is recomputed on\n * every change because a late-arriving parent can reorder credentials that already arrived.\n */\n subscribe(ctx: Context, process: (credential: Credential) => Promise<boolean>): void {\n const replay = () => {\n scheduleMicroTask(ctx, async () => {\n for (const { credential } of this.read()) {\n await process(credential);\n }\n });\n };\n\n this.#lease.on('change', replay);\n ctx.onDispose(() => this.#lease.off('change', replay));\n replay();\n }\n\n /**\n * Appends a credential, keyed by its id so that re-appending one — which the migration backfill and\n * a second device both do — converges instead of duplicating it.\n */\n append(credential: Credential): void {\n const id = toPublicKey(credential.id)?.toHex();\n invariant(id, 'Credential has no id.');\n if (this.#lease.doc()?.credentials?.[id]) {\n return;\n }\n\n this.#lease.change((doc: CredentialsDocument) => {\n doc.credentials ??= {};\n AddOnlySet.add(doc.credentials, id, toBinary(CredentialSchema, credential));\n });\n }\n}\n\n/**\n * Opens the space's credentials document, creating and linking it from the space root on first use.\n */\nexport const openCredentialsDocument = async (\n ctx: Context,\n echoHost: EchoHost,\n spaceId: SpaceId,\n): Promise<CredentialsDocumentStore> => {\n const open = async (url: AutomergeUrl): Promise<CredentialsDocumentStore> => {\n // The lease is held by the store: it writes credentials for as long as the space is open.\n const lease = await echoHost.loadDoc<CredentialsDocument>(ctx, url);\n invariant(lease, 'Credentials document must load.');\n return store(lease);\n };\n\n // Disposed with the caller's context, which is what bounds the store's lifetime — the lease would\n // otherwise keep the document resident for the session.\n const store = (lease: DocumentLease<CredentialsDocument>): CredentialsDocumentStore => {\n const opened = new CredentialsDocumentStore(lease);\n ctx.onDispose(() => opened[Symbol.dispose]());\n return opened;\n };\n\n const existing = echoHost.getSpaceRootRefs(spaceId)?.credentialsDocUrl;\n if (existing) {\n return open(existing);\n }\n\n // The creating lease becomes the store's, so the document is never released between being created\n // and being read back — a fresh document exists only in memory until it is saved.\n const created = await echoHost.createDoc<CredentialsDocument>({\n type: CREDENTIALS_DOCUMENT_TYPE,\n spaceId,\n credentials: {},\n });\n // The link is what the space root records, and a concurrent call may have won it: the store must\n // follow the linked document, since writes to an unlinked one would never be read back.\n const linked = await echoHost.setCredentialsDocument(ctx, spaceId, created.url);\n if (linked !== created.url) {\n created[Symbol.dispose]();\n return open(linked);\n }\n return store(created);\n};\n","//\n// Copyright 2021 DXOS.org\n//\n\nimport { type Message, create, fromBinary, toBinary } from '@bufbuild/protobuf';\nimport { type GenMessage } from '@bufbuild/protobuf/codegenv2';\nimport CRC32 from 'crc-32';\nimport * as EffectContext from 'effect/Context';\n\nimport { Event, scheduleTaskInterval, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { DataCorruptionError, STORAGE_VERSION } from '@dxos/protocols';\nimport { fromDate, fromPublicKey, fromTimeframe, requirePublicKey, toDate } from '@dxos/protocols/buf';\nimport { type Invitation, Invitation_Type, SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n type ControlPipelineSnapshot,\n type EchoMetadata,\n EchoMetadataSchema,\n type EdgeReplicationSetting,\n type IdentityRecord,\n type LargeSpaceMetadata,\n LargeSpaceMetadataSchema,\n type SpaceMetadata,\n} from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { type Directory, type File } from '@dxos/random-access-storage';\nimport { type Timeframe } from '@dxos/timeframe';\nimport { ComplexMap, arrayToBuffer, forEachAsync, isNonNullable } from '@dxos/util';\n\nconst EXPIRED_INVITATION_CLEANUP_INTERVAL = 60 * 60 * 1000; // 1 hour\n\n/**\n * Shared interface for file-based and SQLite-backed metadata stores.\n */\nexport interface IMetadataStore {\n readonly update: Event<EchoMetadata>;\n readonly metadata: EchoMetadata;\n readonly version: number;\n readonly spaces: SpaceMetadata[];\n\n load(): Promise<void>;\n close(): Promise<void>;\n flush(): Promise<void>;\n clear(): Promise<void>;\n hasSpace(spaceKey: PublicKey): boolean;\n\n getIdentityRecord(): IdentityRecord | undefined;\n setIdentityRecord(record: IdentityRecord): Promise<void>;\n\n getInvitations(): Invitation[];\n addInvitation(invitation: Invitation): Promise<void>;\n removeInvitation(invitationId: string): Promise<void>;\n\n addSpace(record: SpaceMetadata): Promise<void>;\n setSpaceDataLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void>;\n setSpaceControlLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void>;\n setWritableFeedKeys(spaceKey: PublicKey, controlFeedKey: PublicKey, dataFeedKey: PublicKey): Promise<void>;\n setSpaceState(spaceKey: PublicKey, state: SpaceState): Promise<void>;\n\n getSpaceControlPipelineSnapshot(spaceKey: PublicKey): ControlPipelineSnapshot | undefined;\n setSpaceControlPipelineSnapshot(spaceKey: PublicKey, snapshot: ControlPipelineSnapshot): Promise<void>;\n\n getSpaceEdgeReplicationSetting(spaceKey: PublicKey): EdgeReplicationSetting | undefined;\n setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void>;\n\n readonly deletedSpaces: PublicKey[];\n addDeletedSpace(spaceKey: PublicKey): Promise<void>;\n}\n\n/**\n * Effect service tag for {@link IMetadataStore}.\n */\nexport class IMetadataStoreService extends EffectContext.Service<IMetadataStoreService, IMetadataStore>()(\n '@dxos/client-services/IMetadataStore',\n) {}\n\nexport interface AddSpaceOptions {\n key: PublicKey;\n genesisFeed: PublicKey;\n}\n\nconst emptyEchoMetadata = (): EchoMetadata =>\n create(EchoMetadataSchema, {\n version: STORAGE_VERSION,\n spaces: [],\n created: fromDate(new Date()),\n updated: fromDate(new Date()),\n });\n\nconst emptyLargeSpaceMetadata = (): LargeSpaceMetadata => create(LargeSpaceMetadataSchema, {});\n\nexport class MetadataStore implements IMetadataStore {\n private _metadata: EchoMetadata = emptyEchoMetadata();\n private _spaceLargeMetadata = new ComplexMap<PublicKey, LargeSpaceMetadata>(PublicKey.hash);\n\n private _metadataFile?: File = undefined;\n\n public readonly update = new Event<EchoMetadata>();\n private readonly _invitationCleanupCtx = new Context();\n\n /**\n * @internal\n */\n readonly _directory: Directory;\n\n constructor(directory: Directory) {\n this._directory = directory;\n }\n\n get metadata(): EchoMetadata {\n return this._metadata;\n }\n\n get version(): number {\n return this._metadata.version ?? 0;\n }\n\n /**\n * Returns a list of currently saved spaces. The list and objects in it can be modified addSpace and\n * addSpaceFeed functions.\n */\n get spaces(): SpaceMetadata[] {\n return this._metadata.spaces ?? [];\n }\n\n /**\n * Returns the keys of spaces that have been tombstoned (soft-deleted).\n */\n get deletedSpaces(): PublicKey[] {\n return (this._metadata.deletedSpaces ?? []).map(requirePublicKey);\n }\n\n private async _readFile<T extends Message>(file: File, schema: GenMessage<T>): Promise<T | undefined> {\n try {\n const { size: fileLength } = await file.stat();\n if (fileLength < 8) {\n return;\n }\n // Loading file size from first 4 bytes.\n const dataSize = (await file.read(0, 4)).readInt32LE(0);\n const checksum = (await file.read(4, 4)).readInt32LE(0);\n log('loaded', { size: dataSize, checksum, name: file.filename });\n\n if (fileLength < dataSize + 8) {\n throw new DataCorruptionError({\n message: 'Metadata size is smaller than expected.',\n context: { fileLength, dataSize },\n });\n }\n\n const data = await file.read(8, dataSize);\n\n const calculatedChecksum = CRC32.buf(data);\n if (calculatedChecksum !== checksum) {\n throw new DataCorruptionError({ message: 'Metadata checksum is invalid.' });\n }\n\n return fromBinary(schema, data);\n } finally {\n await file.close();\n }\n }\n\n /**\n * @internal\n */\n async _writeFile<T extends Message>(file: File, schema: GenMessage<T>, data: T): Promise<void> {\n const encoded = arrayToBuffer(toBinary(schema, data));\n const checksum = CRC32.buf(encoded);\n\n const result = Buffer.alloc(8 + encoded.length);\n\n result.writeInt32LE(encoded.length, 0);\n result.writeInt32LE(checksum, 4);\n encoded.copy(result, 8);\n\n // NOTE: This must be done in one write operation, otherwise the file can be corrupted.\n await file.write(0, result);\n\n log('saved', { size: encoded.length, checksum });\n }\n\n async close(): Promise<void> {\n await this._invitationCleanupCtx.dispose();\n await this.flush();\n await this._metadataFile?.close();\n this._metadataFile = undefined;\n this._metadata = emptyEchoMetadata();\n this._spaceLargeMetadata.clear();\n }\n\n /**\n * Loads metadata from persistent storage.\n */\n @synchronized\n async load(): Promise<void> {\n if (!this._metadataFile || this._metadataFile.closed) {\n this._metadataFile = this._directory.getOrCreateFile('EchoMetadata');\n }\n\n try {\n const metadata = await this._readFile(this._metadataFile, EchoMetadataSchema);\n if (metadata) {\n this._metadata = metadata;\n }\n\n // post-processing\n // proto3 omits the zero enum, so a record written before `state` existed reads back as unset.\n this._metadata.spaces?.forEach((space) => {\n if (!space.state) {\n space.state = SpaceState.SPACE_ACTIVE;\n }\n });\n } catch (err: any) {\n log.error('failed to load metadata', { err });\n this._metadata = emptyEchoMetadata();\n }\n\n await forEachAsync(\n [this._metadata.identity?.haloSpace?.key, ...(this._metadata.spaces?.map((space) => space.key) ?? [])]\n .filter(isNonNullable)\n .map(requirePublicKey),\n async (key) => {\n try {\n await this._loadSpaceLargeMetadata(key);\n } catch (err: any) {\n log.error('failed to load space large metadata', { err });\n }\n },\n );\n\n // Cleanup expired persistent invitations.\n scheduleTaskInterval(\n this._invitationCleanupCtx,\n async () => {\n for (const invitation of this._metadata.invitations ?? []) {\n if (hasInvitationExpired(invitation) || isLegacyInvitationFormat(invitation)) {\n await this.removeInvitation(invitation.invitationId);\n }\n }\n },\n EXPIRED_INVITATION_CLEANUP_INTERVAL,\n );\n }\n\n @synchronized\n private async _save(): Promise<void> {\n const data: EchoMetadata = create(EchoMetadataSchema, {\n ...this._metadata,\n version: STORAGE_VERSION,\n created: this._metadata.created ?? fromDate(new Date()),\n updated: fromDate(new Date()),\n });\n this.update.emit(data);\n\n const file = this._directory.getOrCreateFile('EchoMetadata');\n\n await this._writeFile(file, EchoMetadataSchema, data);\n }\n\n private async _loadSpaceLargeMetadata(key: PublicKey): Promise<void> {\n const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);\n try {\n const metadata = await this._readFile(file, LargeSpaceMetadataSchema);\n if (metadata) {\n this._spaceLargeMetadata.set(key, metadata);\n }\n } catch (err: any) {\n log.error('failed to load space large metadata', { err });\n }\n }\n\n @synchronized\n private async _saveSpaceLargeMetadata(key: PublicKey): Promise<void> {\n const data = this._getLargeSpaceMetadata(key);\n const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);\n await this._writeFile(file, LargeSpaceMetadataSchema, data);\n }\n\n async flush(): Promise<void> {\n await this._directory.flush();\n }\n\n _getSpace(spaceKey: PublicKey): SpaceMetadata {\n const haloSpace = this._metadata.identity?.haloSpace;\n if (haloSpace?.key && requirePublicKey(haloSpace.key).equals(spaceKey)) {\n // Check if the space is the identity space.\n return haloSpace;\n }\n\n const space = this.spaces.find((space) => space.key && requirePublicKey(space.key).equals(spaceKey));\n invariant(space, 'Space not found');\n return space;\n }\n\n hasSpace(spaceKey: PublicKey): boolean {\n const haloSpace = this._metadata.identity?.haloSpace;\n if (haloSpace?.key && requirePublicKey(haloSpace.key).equals(spaceKey)) {\n // Check if the space is the identity space.\n return true;\n }\n\n return !!this.spaces.find((space) => space.key && requirePublicKey(space.key).equals(spaceKey));\n }\n\n private _getLargeSpaceMetadata(key: PublicKey): LargeSpaceMetadata {\n let entry = this._spaceLargeMetadata.get(key);\n if (entry) {\n return entry;\n }\n\n entry = emptyLargeSpaceMetadata();\n this._spaceLargeMetadata.set(key, entry);\n return entry;\n }\n\n /**\n * Clears storage - doesn't work for now.\n */\n async clear(): Promise<void> {\n log('clearing all metadata');\n await this._directory.delete();\n this._metadata = emptyEchoMetadata();\n }\n\n getIdentityRecord(): IdentityRecord | undefined {\n return this._metadata.identity;\n }\n\n async setIdentityRecord(record: IdentityRecord): Promise<void> {\n invariant(!this._metadata.identity, 'Cannot overwrite existing identity in metadata');\n\n this._metadata.identity = record;\n await this._save();\n await this.flush();\n }\n\n getInvitations(): Invitation[] {\n return this._metadata.invitations ?? [];\n }\n\n async addInvitation(invitation: Invitation): Promise<void> {\n if (this._metadata.invitations?.find((i) => i.invitationId === invitation.invitationId)) {\n return;\n }\n\n (this._metadata.invitations ??= []).push(invitation);\n await this._save();\n await this.flush();\n }\n\n async removeInvitation(invitationId: string): Promise<void> {\n this._metadata.invitations = (this._metadata.invitations ?? []).filter((i) => i.invitationId !== invitationId);\n await this._save();\n await this.flush();\n }\n\n /**\n * Records a space as tombstoned (soft-deleted) so it is never re-accepted or auto-opened.\n */\n async addDeletedSpace(spaceKey: PublicKey): Promise<void> {\n if (this.deletedSpaces.some((key) => key.equals(spaceKey))) {\n return;\n }\n\n (this._metadata.deletedSpaces ??= []).push(fromPublicKey(spaceKey));\n await this._save();\n await this.flush();\n }\n\n async addSpace(record: SpaceMetadata): Promise<void> {\n invariant(record.key, 'Space metadata has no key.');\n invariant(!this.hasSpace(requirePublicKey(record.key)), 'Cannot overwrite existing space in metadata');\n\n (this._metadata.spaces ??= []).push(record);\n await this._save();\n await this.flush();\n }\n\n async setSpaceDataLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void> {\n this._getSpace(spaceKey).dataTimeframe = fromTimeframe(timeframe);\n await this._save();\n }\n\n async setSpaceControlLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void> {\n this._getSpace(spaceKey).controlTimeframe = fromTimeframe(timeframe);\n await this._save();\n await this.flush();\n }\n\n async setWritableFeedKeys(spaceKey: PublicKey, controlFeedKey: PublicKey, dataFeedKey: PublicKey): Promise<void> {\n const space = this._getSpace(spaceKey);\n space.controlFeedKey = fromPublicKey(controlFeedKey);\n space.dataFeedKey = fromPublicKey(dataFeedKey);\n await this._save();\n await this.flush();\n }\n\n async setSpaceState(spaceKey: PublicKey, state: SpaceState): Promise<void> {\n this._getSpace(spaceKey).state = state;\n await this._save();\n await this.flush();\n }\n\n getSpaceControlPipelineSnapshot(spaceKey: PublicKey): ControlPipelineSnapshot | undefined {\n return this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot;\n }\n\n async setSpaceControlPipelineSnapshot(spaceKey: PublicKey, snapshot: ControlPipelineSnapshot): Promise<void> {\n this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot = snapshot;\n await this._saveSpaceLargeMetadata(spaceKey);\n await this.flush();\n }\n\n getSpaceEdgeReplicationSetting(spaceKey: PublicKey): EdgeReplicationSetting | undefined {\n return this.hasSpace(spaceKey) ? this._getSpace(spaceKey).edgeReplication : undefined;\n }\n\n async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void> {\n this._getSpace(spaceKey).edgeReplication = setting;\n await this._save();\n await this.flush();\n }\n}\n\nexport const hasInvitationExpired = (invitation: Invitation): boolean => {\n const created = toDate(invitation.created);\n return Boolean(created && invitation.lifetime && created.getTime() + invitation.lifetime * 1000 < Date.now());\n};\n\n// TODO: remove once \"multiuse\" type invitations get removed from local metadata of existing profiles\nconst isLegacyInvitationFormat = (invitation: Invitation): boolean => {\n return invitation.type === Invitation_Type.MULTIUSE;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as SqlMigrations from '@dxos/sql-sqlite/SqlMigrations';\n\nimport init from './0001_init.sql?raw';\n\n/**\n * Space metadata migrations, keyed `<id>_<name>` as `Migrator.fromRecord` expects. Ids must only ever increase,\n * and an applied migration must never be edited — nothing verifies its contents.\n */\nexport const MIGRATIONS = {\n '0001_init': SqlMigrations.apply(init),\n};\n\n/** Own history table per store, since many stores share the client database. */\nexport const MIGRATIONS_TABLE = 'metadata_migrations';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Message, clone, create, equals, fromBinary, toBinary } from '@bufbuild/protobuf';\nimport { type GenMessage } from '@bufbuild/protobuf/codegenv2';\nimport CRC32 from 'crc-32';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Migrator from 'effect/sql/Migrator';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport type * as SqlError from 'effect/sql/SqlError';\n\nimport { Event, scheduleTaskInterval, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { DataCorruptionError, STORAGE_VERSION } from '@dxos/protocols';\nimport { fromDate, fromPublicKey, fromTimeframe, requirePublicKey } from '@dxos/protocols/buf';\nimport { type Invitation, Invitation_Type, SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n type ControlPipelineSnapshot,\n type EchoMetadata,\n EchoMetadataSchema,\n type EdgeReplicationSetting,\n type IdentityRecord,\n type LargeSpaceMetadata,\n LargeSpaceMetadataSchema,\n type SpaceMetadata,\n} from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { type Timeframe } from '@dxos/timeframe';\nimport { ComplexMap, arrayToBuffer, forEachAsync, isNonNullable } from '@dxos/util';\n\nimport { MIGRATIONS, MIGRATIONS_TABLE } from '../../migrations/metadata/index.ts';\nimport { type IMetadataStore, IMetadataStoreService, hasInvitationExpired } from './metadata-store.ts';\n\nconst EXPIRED_INVITATION_CLEANUP_INTERVAL = 60 * 60 * 1000; // 1 hour\n\nconst emptyEchoMetadata = (): EchoMetadata =>\n create(EchoMetadataSchema, {\n version: STORAGE_VERSION,\n spaces: [],\n created: fromDate(new Date()),\n updated: fromDate(new Date()),\n });\n\nconst emptyLargeSpaceMetadata = (): LargeSpaceMetadata => create(LargeSpaceMetadataSchema, {});\n\n/** A deep copy, so later in-place edits to the live record cannot alter what it is compared against. */\nconst withoutUpdated = (metadata: EchoMetadata): EchoMetadata => {\n const copy = clone(EchoMetadataSchema, metadata);\n copy.updated = undefined;\n return copy;\n};\n\nconst MAIN_KEY = 'main';\nconst largeKey = (spaceKey: PublicKey) => `large:${spaceKey.toHex()}`;\n\n// Legacy invitation type detection.\nconst isLegacyInvitationFormat = (invitation: Invitation): boolean => invitation.type === Invitation_Type.MULTIUSE;\n\nexport type SqliteMetadataStoreProps = {\n runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n};\n\n/**\n * SQLite-backed replacement for MetadataStore.\n * Stores EchoMetadata as a single protobuf blob and LargeSpaceMetadata as per-space blobs.\n */\nexport class SqliteMetadataStore implements IMetadataStore {\n readonly #runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n\n #metadata: EchoMetadata = emptyEchoMetadata();\n /** The stored record, minus its `updated` stamp — a save that would only bump the stamp writes nothing. */\n #persisted: EchoMetadata | undefined;\n #loaded = false;\n readonly #spaceLargeMetadata = new ComplexMap<PublicKey, LargeSpaceMetadata>(PublicKey.hash);\n\n readonly update = new Event<EchoMetadata>();\n readonly #invitationCleanupCtx = new Context();\n\n constructor({ runtime }: SqliteMetadataStoreProps) {\n this.#runtime = runtime;\n }\n\n /**\n * Applies any migrations this database has not recorded yet.\n */\n readonly migrate: Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient> = Migrator.make({})({\n loader: Migrator.fromRecord(MIGRATIONS),\n table: MIGRATIONS_TABLE,\n }).pipe(\n // A malformed bundled manifest is a defect, not something a caller can recover from.\n Effect.catchTag('MigrationError', (error) => Effect.die(error)),\n Effect.asVoid,\n Effect.withSpan('SqliteMetadataStore.migrate'),\n );\n\n get metadata(): EchoMetadata {\n return this.#metadata;\n }\n\n get version(): number {\n return this.#metadata.version ?? 0;\n }\n\n get spaces(): SpaceMetadata[] {\n return this.#metadata.spaces ?? [];\n }\n\n async close(): Promise<void> {\n await this.#invitationCleanupCtx.dispose();\n // A store that never loaded holds empty metadata; saving it would wipe the persisted record.\n if (this.#loaded) {\n await this._save();\n }\n this.#loaded = false;\n this.#metadata = emptyEchoMetadata();\n this.#persisted = undefined;\n this.#spaceLargeMetadata.clear();\n }\n\n /**\n * Loads metadata from SQLite.\n */\n @synchronized\n async load(): Promise<void> {\n const rows = await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql<{ value: Uint8Array }>`SELECT value FROM space_metadata WHERE key = ${MAIN_KEY}`;\n }),\n );\n\n if (rows.length > 0) {\n try {\n this.#metadata = this.#decodeWithCrc(rows[0].value, EchoMetadataSchema) ?? emptyEchoMetadata();\n // proto3 omits the zero enum, so a record written before `state` existed reads back as unset.\n this.#metadata.spaces?.forEach((space) => {\n if (!space.state) {\n space.state = SpaceState.SPACE_ACTIVE;\n }\n });\n this.#persisted = withoutUpdated(this.#metadata);\n } catch (err: any) {\n log.error('failed to load metadata from SQLite', { err });\n this.#metadata = emptyEchoMetadata();\n }\n }\n\n // Load large metadata for all known spaces.\n const spaceKeys = [this.#metadata.identity?.haloSpace?.key, ...(this.#metadata.spaces?.map((s) => s.key) ?? [])]\n .filter(isNonNullable)\n .map(requirePublicKey);\n\n await forEachAsync(spaceKeys, async (key) => {\n try {\n await this.#loadSpaceLargeMetadata(key);\n } catch (err: any) {\n log.error('failed to load large space metadata', { err });\n }\n });\n\n scheduleTaskInterval(\n this.#invitationCleanupCtx,\n async () => {\n for (const invitation of this.#metadata.invitations ?? []) {\n if (hasInvitationExpired(invitation) || isLegacyInvitationFormat(invitation)) {\n await this.removeInvitation(invitation.invitationId);\n }\n }\n },\n EXPIRED_INVITATION_CLEANUP_INTERVAL,\n );\n\n // Set last: a throw above (SQL error, a row failing to decode) must leave the store unloaded, or\n // `close()` would save the empty metadata it still holds over the persisted record.\n this.#loaded = true;\n }\n\n async flush(): Promise<void> {\n // No-op: SQLite writes are immediate.\n }\n\n hasSpace(spaceKey: PublicKey): boolean {\n const haloSpace = this.#metadata.identity?.haloSpace;\n if (haloSpace?.key && requirePublicKey(haloSpace.key).equals(spaceKey)) {\n return true;\n }\n return !!this.spaces.find((space) => space.key && requirePublicKey(space.key).equals(spaceKey));\n }\n\n getIdentityRecord(): IdentityRecord | undefined {\n return this.#metadata.identity;\n }\n\n async setIdentityRecord(record: IdentityRecord): Promise<void> {\n invariant(!this.#metadata.identity, 'Cannot overwrite existing identity in metadata');\n this.#metadata.identity = record;\n await this._save();\n }\n\n getInvitations(): Invitation[] {\n return this.#metadata.invitations ?? [];\n }\n\n async addInvitation(invitation: Invitation): Promise<void> {\n if (this.#metadata.invitations?.find((i) => i.invitationId === invitation.invitationId)) {\n return;\n }\n (this.#metadata.invitations ??= []).push(invitation);\n await this._save();\n }\n\n async removeInvitation(invitationId: string): Promise<void> {\n this.#metadata.invitations = (this.#metadata.invitations ?? []).filter((i) => i.invitationId !== invitationId);\n await this._save();\n }\n\n async addSpace(record: SpaceMetadata): Promise<void> {\n invariant(record.key, 'Space metadata has no key.');\n invariant(!this.hasSpace(requirePublicKey(record.key)), 'Cannot overwrite existing space in metadata');\n (this.#metadata.spaces ??= []).push(record);\n await this._save();\n }\n\n async setSpaceDataLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void> {\n this.#getSpace(spaceKey).dataTimeframe = fromTimeframe(timeframe);\n await this._save();\n }\n\n async setSpaceControlLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void> {\n this.#getSpace(spaceKey).controlTimeframe = fromTimeframe(timeframe);\n await this._save();\n }\n\n async setWritableFeedKeys(spaceKey: PublicKey, controlFeedKey: PublicKey, dataFeedKey: PublicKey): Promise<void> {\n const space = this.#getSpace(spaceKey);\n space.controlFeedKey = fromPublicKey(controlFeedKey);\n space.dataFeedKey = fromPublicKey(dataFeedKey);\n await this._save();\n }\n\n async setSpaceState(spaceKey: PublicKey, state: SpaceState): Promise<void> {\n this.#getSpace(spaceKey).state = state;\n await this._save();\n }\n\n getSpaceControlPipelineSnapshot(spaceKey: PublicKey): ControlPipelineSnapshot | undefined {\n return this.#getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot;\n }\n\n async setSpaceControlPipelineSnapshot(spaceKey: PublicKey, snapshot: ControlPipelineSnapshot): Promise<void> {\n this.#getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot = snapshot;\n await this._saveSpaceLargeMetadata(spaceKey);\n }\n\n getSpaceEdgeReplicationSetting(spaceKey: PublicKey): EdgeReplicationSetting | undefined {\n return this.hasSpace(spaceKey) ? this.#getSpace(spaceKey).edgeReplication : undefined;\n }\n\n async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void> {\n this.#getSpace(spaceKey).edgeReplication = setting;\n await this._save();\n }\n\n get deletedSpaces(): PublicKey[] {\n return (this.#metadata.deletedSpaces ?? []).map(requirePublicKey);\n }\n\n async addDeletedSpace(spaceKey: PublicKey): Promise<void> {\n if (this.deletedSpaces.some((key) => key.equals(spaceKey))) {\n return;\n }\n (this.#metadata.deletedSpaces ??= []).push(fromPublicKey(spaceKey));\n await this._save();\n }\n\n async clear(): Promise<void> {\n log('clearing all metadata');\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`DELETE FROM space_metadata`;\n yield* sql`DELETE FROM space_large`;\n }),\n );\n this.#metadata = emptyEchoMetadata();\n this.#persisted = undefined;\n this.#spaceLargeMetadata.clear();\n }\n\n #getSpace(spaceKey: PublicKey): SpaceMetadata {\n const haloSpace = this.#metadata.identity?.haloSpace;\n if (haloSpace?.key && requirePublicKey(haloSpace.key).equals(spaceKey)) {\n return haloSpace;\n }\n const space = this.spaces.find((space) => space.key && requirePublicKey(space.key).equals(spaceKey));\n invariant(space, 'Space not found');\n return space;\n }\n\n #getLargeSpaceMetadata(key: PublicKey): LargeSpaceMetadata {\n let entry = this.#spaceLargeMetadata.get(key);\n if (!entry) {\n entry = emptyLargeSpaceMetadata();\n this.#spaceLargeMetadata.set(key, entry);\n }\n return entry;\n }\n\n @synchronized\n private async _save(): Promise<void> {\n const data: EchoMetadata = create(EchoMetadataSchema, {\n ...this.#metadata,\n version: STORAGE_VERSION,\n created: this.#metadata.created ?? fromDate(new Date()),\n updated: fromDate(new Date()),\n });\n this.update.emit(data);\n const content = withoutUpdated(data);\n if (this.#persisted && equals(EchoMetadataSchema, content, this.#persisted)) {\n return;\n }\n const encoded = this.#encodeWithCrc(EchoMetadataSchema, data);\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`INSERT OR REPLACE INTO space_metadata (key, value) VALUES (${MAIN_KEY}, ${encoded})`;\n }),\n );\n this.#persisted = content;\n }\n\n async #loadSpaceLargeMetadata(key: PublicKey): Promise<void> {\n const keyStr = largeKey(key);\n const rows = await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql<{ value: Uint8Array }>`SELECT value FROM space_large WHERE space_key = ${keyStr}`;\n }),\n );\n if (rows.length > 0) {\n try {\n const meta = this.#decodeWithCrc(rows[0].value, LargeSpaceMetadataSchema);\n if (meta) {\n this.#spaceLargeMetadata.set(key, meta);\n }\n } catch (err: any) {\n log.error('failed to decode large space metadata', { err });\n }\n }\n }\n\n @synchronized\n private async _saveSpaceLargeMetadata(key: PublicKey): Promise<void> {\n const data = this.#getLargeSpaceMetadata(key);\n const keyStr = largeKey(key);\n const encoded = this.#encodeWithCrc(LargeSpaceMetadataSchema, data);\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`INSERT OR REPLACE INTO space_large (space_key, value) VALUES (${keyStr}, ${encoded})`;\n }),\n );\n }\n\n /** Serialize with CRC32 checksum prefix for integrity checking (matches MetadataStore format). */\n #encodeWithCrc<T extends Message>(schema: GenMessage<T>, data: T): Buffer {\n const encoded = arrayToBuffer(toBinary(schema, data));\n const checksum = CRC32.buf(encoded);\n const result = Buffer.alloc(8 + encoded.length);\n result.writeInt32LE(encoded.length, 0);\n result.writeInt32LE(checksum, 4);\n encoded.copy(result, 8);\n return result;\n }\n\n /** Deserialize with CRC32 integrity check (matches MetadataStore format). */\n #decodeWithCrc<T extends Message>(data: Uint8Array, schema: GenMessage<T>): T | undefined {\n const buf = Buffer.from(data);\n if (buf.length < 8) {\n return undefined;\n }\n const dataSize = buf.readInt32LE(0);\n const checksum = buf.readInt32LE(4);\n if (dataSize < 0 || dataSize > buf.length - 8) {\n throw new DataCorruptionError({\n message: 'Metadata size header is invalid.',\n context: { fileLength: buf.length, dataSize },\n });\n }\n if (buf.length !== dataSize + 8) {\n throw new DataCorruptionError({\n message: 'Metadata payload length does not match framing header.',\n context: { fileLength: buf.length, dataSize },\n });\n }\n const payload = buf.subarray(8, dataSize + 8);\n const calculated = CRC32.buf(payload);\n if (calculated !== checksum) {\n throw new DataCorruptionError({ message: 'Metadata checksum is invalid.' });\n }\n return fromBinary(schema, payload);\n }\n}\n\n/**\n * Effect Layer constructing a {@link SqliteMetadataStore} from the ambient SQL runtime.\n */\nexport const SqliteMetadataStoreLayer = (): Layer.Layer<IMetadataStoreService, never, SqlClient.SqlClient> =>\n Layer.effect(\n IMetadataStoreService,\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n const store = new SqliteMetadataStore({ runtime });\n yield* Effect.addFinalizer(() => Effect.promise(() => store.close()));\n return store;\n }),\n );\n","//\n// Copyright 2019 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { runInContext, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { randomBytes } from '@dxos/crypto';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport {\n AuthenticateRequestSchema,\n AuthenticateResponseSchema,\n AuthService as AuthServiceDesc,\n} from '@dxos/protocols/buf/dxos/mesh/teleport/auth_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\n\nimport * as Auth from '../../Auth.ts';\n\ntype AuthService = BufService<typeof AuthServiceDesc>;\n\nexport type AuthExtensionProps = {\n provider: Auth.AuthProvider;\n verifier: Auth.AuthVerifier;\n onAuthSuccess: () => void;\n onAuthFailure: () => void;\n};\n\nexport class AuthExtension extends RpcExtension<Services, Services> {\n private readonly _ctx = new Context({\n onError: (err) => {\n log.catch(err);\n },\n });\n\n constructor(private readonly _authProps: AuthExtensionProps) {\n super({\n requested: {\n AuthService: getBufService<AuthService>('dxos.mesh.teleport.auth.AuthService'),\n },\n exposed: {\n AuthService: getBufService<AuthService>('dxos.mesh.teleport.auth.AuthService'),\n },\n timeout: 60 * 1000, // Long timeout because auth can wait for sync in certain cases.\n });\n }\n\n protected async getHandlers(): Promise<Services> {\n return {\n AuthService: {\n authenticate: async ({ challenge }) => {\n try {\n const credential = await this._authProps.provider(challenge);\n if (!credential) {\n throw new Error('auth rejected');\n }\n return create(AuthenticateResponseSchema, { credential });\n } catch (err) {\n log.error('failed to generate auth credentials', err);\n throw new Error('auth rejected');\n }\n },\n },\n };\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n await super.onOpen(context);\n scheduleTask(this._ctx, async () => {\n try {\n const challenge = randomBytes(32);\n const { credential } = await this.rpc.AuthService.authenticate(\n create(AuthenticateRequestSchema, { challenge }),\n );\n invariant(credential.length > 0, 'invalid credential');\n const success = await this._authProps.verifier(challenge, credential);\n invariant(success, 'credential not verified');\n runInContext(this._ctx, () => this._authProps.onAuthSuccess());\n } catch (err) {\n log('auth failed', err);\n this.close();\n this._authProps.onAuthFailure();\n }\n });\n }\n\n override async onClose(): Promise<void> {\n await this._ctx.dispose();\n await super.onClose();\n }\n\n override async onAbort(): Promise<void> {\n await this._ctx.dispose();\n await super.onAbort();\n }\n}\n\ntype Services = { AuthService: AuthService };\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { type HypercoreWriter } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type MaybePromise } from '@dxos/util';\n\n/**\n * Maps the written arguments onto a different message type.\n */\nexport const createMappedFeedWriter = <Source extends {}, Target extends {}>(\n mapper: (arg: Source) => MaybePromise<Target>,\n writer: HypercoreWriter<Target>,\n): HypercoreWriter<Source> => {\n invariant(mapper);\n invariant(writer);\n\n return {\n write: async (data: Source, options) => await writer.write(await mapper(data), options),\n };\n};\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { type HypercoreBlock, type HypercoreBlockSelector } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { toTimeframe } from '@dxos/protocols/buf';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\n\nimport { type TimeframeClock } from './timeframe-clock.ts';\n\n/**\n * The MessageSelector makes sure that we read in a trusted order.\n * The first message we wish to process is the SpaceGenesis, which will admit a Feed.\n * As we encounter and process FeedAdmit messages those are added to the Space's trust,\n * and we begin processing messages from them as well.\n */\nexport const createMessageSelector = (timeframeClock: TimeframeClock): HypercoreBlockSelector<FeedMessage> => {\n return (messages: HypercoreBlock<FeedMessage>[]) => {\n // Pick the first candidate with a valid timeframe that has no gaps.\n for (let i = 0; i < messages.length; i++) {\n const {\n data: { timeframe },\n } = messages[i];\n invariant(timeframe);\n\n if (!timeframeClock.hasGaps(toTimeframe(timeframe))) {\n return i;\n }\n }\n\n // Not ready for this message yet.\n log('Skipping...');\n };\n};\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { timed } from '@dxos/debug';\nimport { type HypercoreIndex } from '@dxos/feed-store';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { Timeframe } from '@dxos/timeframe';\n\nexport const mapTimeframeToFeedIndexes = (timeframe: Timeframe): HypercoreIndex[] =>\n timeframe.frames().map(([feedKey, index]) => ({ feedKey, index }));\n\nexport const mapFeedIndexesToTimeframe = (indexes: HypercoreIndex[]): Timeframe =>\n new Timeframe(indexes.map(({ feedKey, index }) => [feedKey, index]));\n\nexport const startAfter = (timeframe: Timeframe): HypercoreIndex[] =>\n timeframe.frames().map(([feedKey, index]) => ({ feedKey, index: index + 1 }));\n\n/**\n * Keeps state of the last timeframe that was processed by ECHO.\n */\nexport class TimeframeClock {\n readonly update = new Event<Timeframe>();\n\n private _pendingTimeframe: Timeframe;\n\n constructor(private _timeframe = new Timeframe()) {\n this._pendingTimeframe = _timeframe;\n }\n\n /**\n * Timeframe that was processed by ECHO.\n */\n get timeframe() {\n return this._timeframe;\n }\n\n /**\n * Timeframe that is currently being processed by ECHO.\n * Will be equal to `timeframe` after the processing is complete.\n */\n get pendingTimeframe() {\n return this._pendingTimeframe;\n }\n\n setTimeframe(timeframe: Timeframe): void {\n this._timeframe = timeframe;\n this._pendingTimeframe = timeframe;\n this.update.emit(this._timeframe);\n }\n\n updatePendingTimeframe(key: PublicKey, seq: number): void {\n this._pendingTimeframe = Timeframe.merge(this._pendingTimeframe, new Timeframe([[key, seq]]));\n }\n\n updateTimeframe(): void {\n this._timeframe = this._pendingTimeframe;\n this.update.emit(this._timeframe);\n }\n\n hasGaps(timeframe: Timeframe): boolean {\n const gaps = Timeframe.dependencies(timeframe, this._timeframe);\n return !gaps.isEmpty();\n }\n\n @timed(5_000)\n async waitUntilReached(target: Timeframe): Promise<void> {\n log('waitUntilReached', { target, current: this._timeframe });\n await this.update.waitForCondition(() => {\n log('check if reached', {\n target,\n current: this._timeframe,\n deps: Timeframe.dependencies(target, this._timeframe),\n });\n\n return Timeframe.dependencies(target, this._timeframe).isEmpty();\n });\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { Event, Trigger, sleepWithContext, synchronized } from '@dxos/async';\nimport { Context, rejectOnDispose } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { HypercoreSetIterator, type HypercoreWrapper, type HypercoreWriter } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type FeedMessageBlock } from '@dxos/protocols';\nimport { fromTimeframe } from '@dxos/protocols/buf';\nimport { type FeedMessage, type FeedMessage_Payload, FeedMessageSchema } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { Timeframe } from '@dxos/timeframe';\nimport { ComplexMap } from '@dxos/util';\n\nimport { createMappedFeedWriter } from './feeds.ts';\nimport { createMessageSelector } from './message-selector.ts';\nimport { TimeframeClock, mapFeedIndexesToTimeframe, startAfter } from './timeframe-clock.ts';\n\nexport type WaitUntilReachedTargetProps = {\n /**\n * For cancellation.\n */\n ctx?: Context;\n timeout?: number;\n\n /**\n * @default true\n */\n breakOnStall?: boolean;\n};\n\n/**\n * External state accessor.\n */\nexport class PipelineState {\n /**\n * @internal\n */\n _ctx = new Context();\n\n // TODO(dmaretskyi): Remove?. Avoid accessing `_timeframeClock` before constructor initialization.\n public get timeframeUpdate() {\n return this._timeframeClock.update;\n }\n\n public readonly stalled = new Event();\n\n /**\n * @internal\n */\n _startTimeframe: Timeframe = new Timeframe();\n\n /**\n * Target timeframe we are waiting to reach.\n */\n private _targetTimeframe: Timeframe | undefined;\n\n /**\n * @internal\n */\n _reachedTargetPromise: Promise<void> | undefined;\n\n /**\n * @internal\n */\n _reachedTarget: boolean = false;\n\n constructor(\n private _feeds: ComplexMap<PublicKey, HypercoreWrapper<FeedMessage>>,\n private _timeframeClock: TimeframeClock,\n ) {}\n\n /**\n * Latest theoretical timeframe based on the last mutation in each feed.\n * NOTE: This might never be reached if the mutation dependencies\n */\n // TODO(dmaretskyi): Rename `totalTimeframe`? or `lastTimeframe`.\n get endTimeframe() {\n return mapFeedIndexesToTimeframe(\n Array.from(this._feeds.values())\n .filter((feed) => feed.length > 0)\n .map((feed) => ({\n feedKey: feed.key,\n index: feed.length - 1,\n })),\n );\n }\n\n get startTimeframe() {\n return this._startTimeframe;\n }\n\n get timeframe() {\n return this._timeframeClock.timeframe;\n }\n\n get pendingTimeframe() {\n return this._timeframeClock.pendingTimeframe;\n }\n\n get targetTimeframe() {\n return this._targetTimeframe ? this._targetTimeframe : new Timeframe();\n }\n\n get reachedTarget() {\n return this._reachedTarget;\n }\n\n get feeds() {\n return Array.from(this._feeds.values());\n }\n\n async waitUntilTimeframe(target: Timeframe): Promise<void> {\n await this._timeframeClock.waitUntilReached(target);\n }\n\n setTargetTimeframe(target: Timeframe): void {\n this._targetTimeframe = target;\n }\n\n /**\n * Wait until the pipeline processes all messages in the feed and reaches the target timeframe if that is set.\n *\n * This function will resolve immediately if the pipeline is stalled.\n *\n * @param timeout Timeout in milliseconds to specify the maximum wait time.\n */\n async waitUntilReachedTargetTimeframe({\n ctx = new Context(),\n timeout,\n breakOnStall = true,\n }: WaitUntilReachedTargetProps = {}): Promise<void> {\n log('waitUntilReachedTargetTimeframe', {\n timeout,\n current: this.timeframe,\n target: this.targetTimeframe,\n });\n\n this._reachedTargetPromise ??= Promise.race([\n this._timeframeClock.update.waitForCondition(() => {\n return Timeframe.dependencies(this.targetTimeframe, this.timeframe).isEmpty();\n }),\n ...(breakOnStall ? [this.stalled.discardParameter().waitForCount(1)] : []),\n ]);\n\n let done = false;\n\n if (timeout) {\n return Promise.race([\n rejectOnDispose(ctx),\n rejectOnDispose(this._ctx),\n this._reachedTargetPromise.then(() => {\n done = true;\n this._reachedTarget = true;\n }),\n sleepWithContext(this._ctx, timeout).then(() => {\n if (done) {\n return;\n }\n\n log.warn('waitUntilReachedTargetTimeframe timed out', {\n timeout,\n current: this.timeframe,\n target: this.targetTimeframe,\n dependencies: Timeframe.dependencies(this.targetTimeframe, this.timeframe),\n });\n }),\n ]);\n } else {\n return this._reachedTargetPromise;\n }\n }\n}\n\n// TODO(mykola): Extract to `@dxos/echo-protocol`\nexport interface PipelineAccessor {\n state: PipelineState;\n writer: HypercoreWriter<FeedMessage_Payload>;\n}\n\n/**\n * A multi-reader pipeline that operates on feeds.\n * Might have a single writable feed.\n * Has a timeframe clock to handle message ordering.\n *\n * NOTE:\n * - Feeds passed in must have value encoding consistent with the type expected by the iterator/writer.\n *\n * # Usage examples\n *\n * ## Create a new space.\n *\n * 1. Generate space key, genesis feed key.\n * 2. Create and open pipeline reading from {}.\n * 3. Create and add the writable genesis feed.\n * 4. Write the initial sequence of control and credential messages.\n *\n * ## Load an existing space from storage\n *\n * 1. Load space key, genesis feed key, get starting timeframe from saved snapshot.\n * 2. Create and open pipeline reading from the initial timeframe.\n * 3. Open and add the genesis feed.\n * 4. Once the writable feed is added, the pipeline becomes writable.\n *\n * ## Join an existing space created by another agent/device.\n *\n * 1. Get the space key, genesis feed key from another agent.\n * 2. (optionally) Download the snapshot from another agent.\n * 3. Create and open pipeline.\n * 4. Generate the writable feed key.\n * 5. Wait for the writable feed to be added.\n */\nexport class Pipeline implements PipelineAccessor {\n private readonly _timeframeClock = new TimeframeClock(new Timeframe());\n private readonly _feeds = new ComplexMap<PublicKey, HypercoreWrapper<FeedMessage>>(PublicKey.hash);\n\n // External state accessor.\n private readonly _state: PipelineState = new PipelineState(this._feeds, this._timeframeClock);\n\n // Waits for the message consumer to process the message and yield control back to the pipeline.\n private readonly _processingTrigger = new Trigger().wake();\n private readonly _pauseTrigger = new Trigger().wake();\n\n // Pending downloads.\n private readonly _downloads = new ComplexMap<HypercoreWrapper<FeedMessage>, any>((value) =>\n PublicKey.hash(value.key),\n );\n\n // Inbound feed stream.\n private _feedSetIterator?: HypercoreSetIterator<FeedMessage>;\n\n // Woken (and re-armed) each time `_initIterator` swaps the iterator, so a consumer parked on a\n // finished generator of the previous instance can move to the new one.\n private _iteratorChanged = new Trigger();\n\n // Outbound feed writer.\n private _writer: HypercoreWriter<FeedMessage_Payload> | undefined;\n\n private _isStopping = false;\n private _isStarted = false;\n private _isBeingConsumed = false;\n private _isPaused = false;\n\n get state() {\n return this._state;\n }\n\n get writer(): HypercoreWriter<FeedMessage_Payload> {\n invariant(this._writer, 'Writer not set.');\n return this._writer;\n }\n\n /**\n * Whether the hypercore is part of this pipeline.\n */\n hasHypercore(feedKey: PublicKey): boolean {\n return this._feeds.has(feedKey);\n }\n\n getFeeds(): HypercoreWrapper<FeedMessage>[] {\n return this._feedSetIterator!.feeds;\n }\n\n // NOTE: This cannot be synchronized with `stop` because stop waits for the mutation processing to complete,\n // which might be opening feeds during the mutation processing, which w\n async addHypercore(feed: HypercoreWrapper<FeedMessage>): Promise<void> {\n this._feeds.set(feed.key, feed);\n\n if (this._feedSetIterator && !this._feedSetIterator.hasHypercore(feed.key)) {\n await this._feedSetIterator.addHypercore(feed);\n }\n\n if (this._isStarted && !this._isPaused) {\n this._setFeedDownloadState(feed);\n }\n }\n\n setWriteFeed(feed: HypercoreWrapper<FeedMessage>): void {\n invariant(!this._writer, 'Writer already set.');\n invariant(feed.properties.writable, 'Feed must be writable.');\n\n this._writer = createMappedFeedWriter<FeedMessage_Payload, FeedMessage>(\n (payload: FeedMessage_Payload) =>\n create(FeedMessageSchema, { timeframe: fromTimeframe(this._timeframeClock.timeframe), payload }),\n feed.createHypercoreWriter(),\n );\n }\n\n @synchronized\n async start(): Promise<void> {\n invariant(!this._isStarted, 'Pipeline is already started.');\n log('starting...');\n await this._initIterator();\n await this._feedSetIterator!.open();\n this._isStarted = true;\n log('started');\n\n if (!this._isPaused) {\n for (const feed of this._feeds.values()) {\n this._setFeedDownloadState(feed);\n }\n }\n }\n\n @synchronized\n async stop(): Promise<void> {\n log('stopping...');\n this._isStopping = true;\n for (const [feed, handle] of this._downloads.entries()) {\n feed.undownload(handle);\n }\n this._downloads.clear();\n await this._feedSetIterator?.close();\n await this._processingTrigger.wait(); // Wait for the in-flight message to be processed.\n await this._state._ctx.dispose();\n this._state._ctx = new Context();\n this._state._reachedTargetPromise = undefined;\n this._state._reachedTarget = false;\n this._isStarted = false;\n log('stopped');\n }\n\n /**\n * @param timeframe Timeframe of already processed messages.\n * The pipeline will start processing messages AFTER this timeframe.\n */\n @synchronized\n async setCursor(timeframe: Timeframe): Promise<void> {\n invariant(!this._isStarted || this._isPaused, 'Invalid state.');\n\n this._state._startTimeframe = timeframe;\n this._timeframeClock.setTimeframe(timeframe);\n\n // Cancel downloads of mutations before the cursor.\n if (this._feedSetIterator) {\n await this._feedSetIterator.close();\n await this._initIterator();\n await this._feedSetIterator.open();\n }\n }\n\n /**\n * Calling pause while processing will cause a deadlock.\n */\n @synchronized\n async pause(): Promise<void> {\n if (this._isPaused) {\n return;\n }\n\n this._pauseTrigger.reset();\n await this._processingTrigger.wait();\n this._isPaused = true;\n }\n\n @synchronized\n async unpause(): Promise<void> {\n invariant(this._isPaused, 'Pipeline is not paused.');\n\n this._pauseTrigger.wake();\n this._isPaused = false;\n\n for (const feed of this._feeds.values()) {\n this._setFeedDownloadState(feed);\n }\n }\n\n /**\n * Starts to iterate over the ordered messages from the added feeds.\n * Updates the timeframe clock after the message has bee processed.\n */\n async *consume(): AsyncIterable<FeedMessageBlock> {\n invariant(!this._isBeingConsumed, 'Pipeline is already being consumed.');\n this._isBeingConsumed = true;\n\n invariant(this._feedSetIterator, 'Iterator not initialized.');\n let lastFeedSetIterator = this._feedSetIterator;\n let iterable = lastFeedSetIterator[Symbol.asyncIterator]();\n\n // Iteration counter to make a busy loop visible in debug logs.\n let iteration = 0;\n while (!this._isStopping) {\n iteration += 1;\n log('consume iteration', { iteration });\n await this._pauseTrigger.wait();\n\n // Iterator might have been changed while we were waiting for the processing to complete.\n if (lastFeedSetIterator !== this._feedSetIterator) {\n log('consume: iterator changed while paused', { iteration });\n invariant(this._feedSetIterator, 'Iterator not initialized.');\n lastFeedSetIterator = this._feedSetIterator;\n iterable = lastFeedSetIterator[Symbol.asyncIterator]();\n }\n\n // Will be canceled when the iterator gets closed.\n const { done, value } = await iterable.next();\n if (!done) {\n const block = value ?? failUndefined();\n log('consume block', { iteration, feedKey: PublicKey.from(block.feedKey).truncate(), seq: block.seq });\n this._processingTrigger.reset();\n this._timeframeClock.updatePendingTimeframe(PublicKey.from(block.feedKey), block.seq);\n yield block;\n this._processingTrigger.wake();\n this._timeframeClock.updateTimeframe();\n } else if (!this._isStopping) {\n // The generator ended while the pipeline is not stopping: it was obtained before `start()`\n // set the iterator running, or the iterator is being swapped by `setCursor`. Polling the\n // finished generator would spin the microtask queue forever (starving the whole thread),\n // so wait for the iterator to (re)start or be replaced, then take a fresh generator.\n log('consume: generator ended; waiting for iterator restart or swap', { iteration });\n if (lastFeedSetIterator === this._feedSetIterator) {\n await Promise.race([lastFeedSetIterator.waitUntilRunning(), this._iteratorChanged.wait()]);\n }\n invariant(this._feedSetIterator, 'Iterator not initialized.');\n lastFeedSetIterator = this._feedSetIterator;\n iterable = lastFeedSetIterator[Symbol.asyncIterator]();\n log('consume: resuming with fresh generator', { iteration });\n }\n }\n log('consume: stopped', { iteration });\n\n // TODO(burdon): Test re-entrant?\n this._isBeingConsumed = false;\n }\n\n private _setFeedDownloadState(feed: HypercoreWrapper<FeedMessage>): void {\n let handle = this._downloads.get(feed); // TODO(burdon): Always undefined?\n if (handle) {\n feed.undownload(handle);\n }\n\n const timeframe = this._state._startTimeframe;\n const seq = timeframe.get(feed.key) ?? -1;\n log('download', { feed: feed.key.truncate(), seq, length: feed.length });\n handle = feed.download({ start: seq + 1, linear: true }, (err: any, data: any) => {\n if (err) {\n // log.warn(err); // TODO(burdon): Feed is closed/Download was cancelled.\n } else {\n log('downloaded', { data }); // TODO(burdon): Never called.\n }\n });\n\n this._downloads.set(feed, handle);\n }\n\n private async _initIterator(): Promise<void> {\n this._feedSetIterator = new HypercoreSetIterator<FeedMessage>(createMessageSelector(this._timeframeClock), {\n start: startAfter(this._timeframeClock.timeframe),\n stallTimeout: 1000,\n });\n\n {\n // Wake consumers parked on the previous iterator's finished generator; re-arm for the next swap.\n const changed = this._iteratorChanged;\n this._iteratorChanged = new Trigger();\n changed.wake();\n }\n\n this._feedSetIterator.stalled.on((iterator) => {\n log.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, {\n currentTimeframe: this._timeframeClock.timeframe,\n targetTimeframe: this._state.targetTimeframe,\n });\n this._state.stalled.emit();\n });\n\n for (const feed of this._feeds.values()) {\n // A concurrent `addHypercore` (e.g. a feed admission processed during startup) may have already\n // registered this feed on the new iterator, whose `addHypercore` throws on duplicates.\n if (!this._feedSetIterator.hasHypercore(feed.key)) {\n await this._feedSetIterator.addHypercore(feed);\n }\n }\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { fromBinary, toBinary } from '@bufbuild/protobuf';\n\nimport { type ValueCodec, createCodecEncoding } from '@dxos/hypercore';\nimport { type FeedMessage, FeedMessageSchema } from '@dxos/protocols/buf/dxos/echo/feed_pb';\n\n/**\n * Codec for feed messages.\n */\nexport const codec: ValueCodec<FeedMessage> = {\n encode: (value) => toBinary(FeedMessageSchema, value),\n decode: (buffer) => fromBinary(FeedMessageSchema, buffer),\n};\n\n/**\n * Value encoding used by feed store.\n */\nexport const valueEncoding = createCodecEncoding(codec);\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { DeferredTask, scheduleMicroTask, sleepWithContext, trackLeaks } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport {\n type DelegateInvitationCredential,\n type FeedInfo,\n type MemberInfo,\n type SpaceState,\n SpaceStateMachine,\n} from '@dxos/credentials';\nimport { type HypercoreWrapper } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type FeedMessageBlock } from '@dxos/protocols';\nimport { fromPublicKey, fromTimeframe, requirePublicKey, toTimeframe } from '@dxos/protocols/buf';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport {\n type ControlPipelineSnapshot,\n ControlPipelineSnapshot_ControlMessageSchema,\n ControlPipelineSnapshotSchema,\n} from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { AdmittedFeed_Designation, type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { Timeframe } from '@dxos/timeframe';\nimport { trace } from '@dxos/tracing';\nimport { type AsyncCallback, Callback, tracer } from '@dxos/util';\n\nimport { type IMetadataStore } from '../metadata/index.ts';\nimport { Pipeline, type PipelineAccessor } from '../pipeline/index.ts';\n\nexport type ControlPipelineProps = {\n spaceKey: PublicKey;\n genesisFeed: HypercoreWrapper<FeedMessage>;\n feedProvider: (feedKey: PublicKey) => Promise<HypercoreWrapper<FeedMessage>>;\n metadataStore: IMetadataStore;\n};\n\nconst TIMEFRAME_SAVE_DEBOUNCE_INTERVAL = 500;\n\nconst CONTROL_PIPELINE_SNAPSHOT_DELAY = 10_000;\n\nconst USE_SNAPSHOTS = true;\n\n/**\n * Processes HALO credentials, which include genesis and invitations.\n */\n@trackLeaks('start', 'stop')\nexport class ControlPipeline {\n private readonly _ctx = new Context();\n private readonly _pipeline: Pipeline;\n private readonly _spaceStateMachine: SpaceStateMachine;\n\n private readonly _spaceKey: PublicKey;\n private readonly _metadata: IMetadataStore;\n private _targetTimeframe?: Timeframe;\n private _lastTimeframeSaveTime: number = Date.now();\n\n public readonly onFeedAdmitted = new Callback<AsyncCallback<FeedInfo>>();\n public readonly onMemberRoleChanged: Callback<AsyncCallback<MemberInfo[]>>;\n public readonly onCredentialProcessed: Callback<AsyncCallback<Credential>>;\n public readonly onDelegatedInvitation: Callback<AsyncCallback<DelegateInvitationCredential>>;\n public readonly onDelegatedInvitationRemoved: Callback<AsyncCallback<DelegateInvitationCredential>>;\n\n private _snapshotTask = new DeferredTask(this._ctx, async () => {\n await sleepWithContext(this._ctx, CONTROL_PIPELINE_SNAPSHOT_DELAY);\n await this._saveSnapshot();\n });\n\n constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }: ControlPipelineProps) {\n this._spaceKey = spaceKey;\n this._metadata = metadataStore;\n this._pipeline = new Pipeline();\n void this._pipeline.addHypercore(genesisFeed); // TODO(burdon): Require async open/close?\n\n this._spaceStateMachine = new SpaceStateMachine(spaceKey);\n this._spaceStateMachine.onFeedAdmitted.set(async (info) => {\n // log('feed admitted', { info });\n log('feed admitted', { key: info.key });\n\n // TODO(burdon): Check not stopping.\n if (info.assertion.designation === AdmittedFeed_Designation.CONTROL && !info.key.equals(genesisFeed.key)) {\n scheduleMicroTask(this._ctx, async () => {\n try {\n const feed = await feedProvider(info.key);\n if (this._ctx.disposed) {\n return;\n }\n if (!this._pipeline.hasHypercore(feed.key)) {\n await this._pipeline.addHypercore(feed);\n }\n } catch (err: any) {\n log.catch(err);\n }\n });\n }\n\n await this.onFeedAdmitted.callIfSet(info);\n });\n\n this.onMemberRoleChanged = this._spaceStateMachine.onMemberRoleChanged;\n this.onCredentialProcessed = this._spaceStateMachine.onCredentialProcessed;\n this.onDelegatedInvitation = this._spaceStateMachine.onDelegatedInvitation;\n this.onDelegatedInvitationRemoved = this._spaceStateMachine.onDelegatedInvitationRemoved;\n }\n\n get spaceState(): SpaceState {\n return this._spaceStateMachine;\n }\n\n /**\n * Feeds a credential that came from the space's credentials document rather than a feed. Processing\n * is idempotent by credential id, so a credential the feed already delivered is a no-op — which is\n * what lets both sources run during the migration window.\n */\n async processDocumentCredential(credential: Credential): Promise<boolean> {\n return this._spaceStateMachine.process(credential, {});\n }\n\n get pipeline(): PipelineAccessor {\n return this._pipeline;\n }\n\n async setWriteFeed(feed: HypercoreWrapper<FeedMessage>): Promise<void> {\n await this._pipeline.addHypercore(feed);\n this._pipeline.setWriteFeed(feed);\n }\n\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async start(ctx: Context): Promise<void> {\n const snapshot = this._metadata.getSpaceControlPipelineSnapshot(this._spaceKey);\n log('load snapshot', { key: this._spaceKey, present: !!snapshot, tf: snapshot?.timeframe });\n if (USE_SNAPSHOTS && snapshot) {\n await this._processSnapshot(snapshot);\n }\n\n log('starting...');\n await this._pipeline.start();\n // Started strictly after `pipeline.start()`: a consumer that races the start can obtain the\n // iterator's generator before it is running — the generator then finishes immediately and\n // polling it spins the microtask queue, starving the thread (boot wedge).\n setTimeout(async () => {\n void this._consumePipeline(ctx);\n });\n log('started');\n }\n\n private async _processSnapshot(snapshot: ControlPipelineSnapshot): Promise<void> {\n await this._pipeline.setCursor(toTimeframe(snapshot.timeframe));\n\n for (const message of snapshot.messages ?? []) {\n invariant(message.credential, 'Snapshot entry carries no credential.');\n const result = await this._spaceStateMachine.process(message.credential, {\n sourceFeed: requirePublicKey(message.feedKey),\n skipVerification: true,\n });\n\n if (!result) {\n log.warn('credential processing failed from snapshot', { message });\n }\n }\n }\n\n private async _saveSnapshot(): Promise<void> {\n await this._pipeline.pause();\n const snapshot: ControlPipelineSnapshot = create(ControlPipelineSnapshotSchema, {\n timeframe: fromTimeframe(this._pipeline.state.timeframe),\n // A snapshot replays into the feed pipeline, so an entry with no source feed has no place in it.\n messages: this._spaceStateMachine.credentialEntries.flatMap((entry) =>\n entry.sourceFeed\n ? [\n create(ControlPipelineSnapshot_ControlMessageSchema, {\n feedKey: fromPublicKey(entry.sourceFeed),\n credential: entry.credential,\n }),\n ]\n : [],\n ),\n });\n await this._pipeline.unpause();\n\n log('save snapshot', { key: this._spaceKey, snapshot: getSnapshotLoggerContext(snapshot) });\n await this._metadata.setSpaceControlPipelineSnapshot(this._spaceKey, snapshot);\n }\n\n private async _consumePipeline(ctx: Context): Promise<void> {\n for await (const msg of this._pipeline.consume()) {\n try {\n await this._processMessage(ctx, msg);\n } catch (err: any) {\n log.catch(err);\n }\n }\n }\n\n @trace.span({ showInBrowserTimeline: true, showInRemoteTracing: false })\n private async _processMessage(ctx: Context, msg: FeedMessageBlock): Promise<void> {\n log('processing', { key: msg.feedKey, seq: msg.seq });\n if (msg.data.payload?.payload.case === 'credential') {\n const credential = msg.data.payload.payload.value.credential;\n invariant(credential, 'Credentials message is empty.');\n const timer = tracer.mark('dxos.echo.pipeline.control');\n const result = await this._spaceStateMachine.process(credential, {\n sourceFeed: PublicKey.from(msg.feedKey),\n });\n\n timer.end();\n if (!result) {\n log.warn('processing failed', { msg });\n } else {\n await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);\n }\n\n this._snapshotTask.schedule();\n }\n }\n\n private async _noteTargetStateIfNeeded(timeframe: Timeframe): Promise<void> {\n // TODO(dmaretskyi): Replace this with a proper debounce/throttle.\n\n if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL) {\n this._lastTimeframeSaveTime = Date.now();\n\n await this._saveTargetTimeframe(timeframe);\n }\n }\n\n async stop(): Promise<void> {\n log('stopping...');\n await this._ctx.dispose();\n await this._pipeline.stop();\n await this._saveTargetTimeframe(this._pipeline.state.timeframe);\n log('stopped');\n }\n\n private async _saveTargetTimeframe(timeframe: Timeframe): Promise<void> {\n try {\n const newTimeframe = Timeframe.merge(this._targetTimeframe ?? new Timeframe(), timeframe);\n await this._metadata.setSpaceControlLatestTimeframe(this._spaceKey, newTimeframe);\n this._targetTimeframe = newTimeframe;\n } catch (err: any) {\n log(err);\n }\n }\n}\n\nconst getSnapshotLoggerContext = (snapshot: ControlPipelineSnapshot) => {\n return snapshot.messages?.map((msg) => ({\n issuer: msg.credential?.issuer,\n subject: msg.credential?.subject?.id,\n type: msg.credential?.subject?.assertion?.typeUrl,\n }));\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { Event, scheduleMicroTask, synchronized, trackLeaks } from '@dxos/async';\nimport { type Context, Resource } from '@dxos/context';\nimport { type DelegateInvitationCredential, type FeedInfo, type MemberInfo } from '@dxos/credentials';\nimport { type HypercoreCreateOptions, type HypercoreWrapper } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { AdmittedFeed_Designation, type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type Timeframe } from '@dxos/timeframe';\nimport { trace } from '@dxos/tracing';\nimport { type AsyncCallback, Callback } from '@dxos/util';\n\nimport { type IMetadataStore } from '../metadata/index.ts';\nimport { type PipelineAccessor } from '../pipeline/index.ts';\nimport { ControlPipeline } from './control-pipeline.ts';\nimport { type SpaceProtocol } from './space-protocol.ts';\n\n// TODO(burdon): Factor out?\ntype FeedProvider = (feedKey: PublicKey, opts?: HypercoreCreateOptions) => Promise<HypercoreWrapper<FeedMessage>>;\n\nexport type SpaceProps = {\n id: SpaceId;\n spaceKey: PublicKey;\n protocol: SpaceProtocol;\n genesisFeed: HypercoreWrapper<FeedMessage>;\n feedProvider: FeedProvider;\n metadataStore: IMetadataStore;\n memberKey: PublicKey;\n\n // TODO(dmaretskyi): Superseded by epochs.\n snapshotId?: string | undefined;\n\n onDelegatedInvitationStatusChange: (invitation: DelegateInvitationCredential, isActive: boolean) => Promise<void>;\n onMemberRolesChanged: (member: MemberInfo[]) => Promise<void>;\n};\n\nexport type CreatePipelineProps = {\n start: Timeframe;\n // designation: AdmittedFeed.Designation;\n};\n\n/**\n * Spaces are globally addressable databases with access control.\n */\n// TODO(dmaretskyi): Extract database stuff.\n// TODO(dmaretskyi): Rename HaloGraph move to HALO.\n@trackLeaks('open', 'close')\nexport class Space extends Resource {\n public readonly onCredentialProcessed = new Callback<AsyncCallback<Credential>>();\n\n /** Multi-subscriber counterpart to {@link onCredentialProcessed}, which holds a single handler. */\n public readonly credentialProcessed = new Event<Credential>();\n public readonly stateUpdate = new Event();\n public readonly protocol: SpaceProtocol;\n\n private readonly _id: SpaceId;\n private readonly _key: PublicKey;\n private readonly _genesisFeedKey: PublicKey;\n private readonly _feedProvider: FeedProvider;\n private readonly _controlPipeline: ControlPipeline;\n\n private _controlFeed?: HypercoreWrapper<FeedMessage>;\n private _dataFeed?: HypercoreWrapper<FeedMessage>;\n\n constructor(params: SpaceProps) {\n super();\n invariant(params.spaceKey && params.feedProvider);\n this._id = params.id;\n this._key = params.spaceKey;\n this._genesisFeedKey = params.genesisFeed.key;\n this._feedProvider = params.feedProvider;\n\n this._controlPipeline = new ControlPipeline({\n spaceKey: params.spaceKey,\n genesisFeed: params.genesisFeed,\n feedProvider: params.feedProvider,\n metadataStore: params.metadataStore,\n });\n\n // TODO(dmaretskyi): Feed set abstraction.\n this._controlPipeline.onFeedAdmitted.set(async (info) => {\n // Enable sparse replication to not download mutations covered by prior epochs.\n const sparse = info.assertion.designation === AdmittedFeed_Designation.DATA;\n\n if (!info.key.equals(params.genesisFeed.key)) {\n scheduleMicroTask(this._ctx, async () => {\n await this.protocol.addHypercore(await params.feedProvider(info.key, { sparse }));\n });\n }\n });\n\n this._controlPipeline.onCredentialProcessed.set(async (credential) => {\n await this.onCredentialProcessed.callIfSet(credential);\n this.credentialProcessed.emit(credential);\n log('onCredentialProcessed', { credential });\n this.stateUpdate.emit();\n });\n this._controlPipeline.onDelegatedInvitation.set(async (invitation) => {\n log('onDelegatedInvitation', { invitation });\n await params.onDelegatedInvitationStatusChange(invitation, true);\n });\n this._controlPipeline.onDelegatedInvitationRemoved.set(async (invitation) => {\n log('onDelegatedInvitationRemoved', { invitation });\n await params.onDelegatedInvitationStatusChange(invitation, false);\n });\n this._controlPipeline.onMemberRoleChanged.set(async (changedMembers) => {\n log('onMemberRoleChanged', () => ({ changedMembers: changedMembers.map((m) => [m.key, m.role]) }));\n await params.onMemberRolesChanged(changedMembers);\n });\n\n // Start replicating the genesis feed.\n this.protocol = params.protocol;\n }\n\n @logInfo\n get id() {\n return this._id;\n }\n\n @logInfo\n get key() {\n return this._key;\n }\n\n get genesisFeedKey(): PublicKey {\n return this._genesisFeedKey;\n }\n\n get controlFeedKey() {\n return this._controlFeed?.key;\n }\n\n get dataFeedKey() {\n return this._dataFeed?.key;\n }\n\n get spaceState() {\n return this._controlPipeline.spaceState;\n }\n\n /** @see ControlPipeline.processDocumentCredential */\n async processDocumentCredential(credential: Credential): Promise<boolean> {\n return this._controlPipeline.processDocumentCredential(credential);\n }\n\n /**\n * @test-only\n */\n get controlPipeline(): PipelineAccessor {\n return this._controlPipeline.pipeline;\n }\n\n async setControlFeed(feed: HypercoreWrapper<FeedMessage>): Promise<this> {\n invariant(!this._controlFeed, 'Control feed already set.');\n this._controlFeed = feed;\n await this._controlPipeline.setWriteFeed(feed);\n return this;\n }\n\n async setDataFeed(feed: HypercoreWrapper<FeedMessage>): Promise<this> {\n invariant(!this._dataFeed, 'Data feed already set.');\n this._dataFeed = feed;\n return this;\n }\n\n /**\n * Use for diagnostics.\n */\n getControlFeeds(): FeedInfo[] {\n return Array.from(this._controlPipeline.spaceState.feeds.values());\n }\n\n @trace.span({ op: 'lifecycle' })\n protected override async _open(ctx: Context): Promise<void> {\n log('opening...');\n\n // Order is important.\n await this._controlPipeline.start(ctx);\n\n log('opened');\n }\n\n @synchronized\n public async startProtocol(ctx: Context): Promise<void> {\n invariant(this.isOpen);\n await this.protocol.start(ctx);\n await this.protocol.addHypercore(await this._feedProvider(this._genesisFeedKey));\n }\n\n @synchronized\n protected override async _close(ctx: Context): Promise<void> {\n log('closing...', { key: this._key });\n\n // Closes in reverse order to open.\n await this.protocol.stop(ctx);\n await this._controlPipeline.stop();\n\n log('closed');\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { type Trigger, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { ProtocolError } from '@dxos/protocols';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport { type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n AdmissionDiscoveryService as AdmissionDiscoveryServiceDesc,\n type GetAdmissionCredentialRequest,\n type GetAdmissionCredentialResponse,\n GetAdmissionCredentialResponseSchema,\n} from '@dxos/protocols/buf/dxos/mesh/teleport/admission-discovery_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\n\ntype AdmissionDiscoveryService = BufService<typeof AdmissionDiscoveryServiceDesc>;\n\nimport { type Space } from './space.ts';\n\n/**\n * Guest's side for a connection to a concrete peer in p2p network during invitation.\n */\nexport class CredentialRetrieverExtension extends RpcExtension<\n { AdmissionDiscoveryService: AdmissionDiscoveryService },\n {}\n> {\n private _ctx = new Context();\n\n constructor(\n private readonly _request: GetAdmissionCredentialRequest,\n private readonly _onResult: Trigger<Credential>,\n ) {\n super({\n requested: {\n AdmissionDiscoveryService: getBufService<AdmissionDiscoveryService>(\n 'dxos.mesh.teleport.AdmissionDiscoveryService',\n ),\n },\n });\n }\n\n protected override async getHandlers(): Promise<{}> {\n return {};\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n await super.onOpen(context);\n scheduleTask(this._ctx, async () => {\n try {\n const result = await this.rpc.AdmissionDiscoveryService.getAdmissionCredential(this._request);\n invariant(result.admissionCredential, 'Admission response carries no credential.');\n this._onResult.wake(result.admissionCredential);\n } catch (err: any) {\n context.close(err);\n }\n });\n }\n\n override async onClose(): Promise<void> {\n await this._ctx.dispose();\n }\n\n override async onAbort(): Promise<void> {\n await this._ctx.dispose();\n }\n}\n\nexport class CredentialServerExtension extends RpcExtension<\n {},\n { AdmissionDiscoveryService: AdmissionDiscoveryService }\n> {\n constructor(private readonly _space: Space) {\n super({\n exposed: {\n AdmissionDiscoveryService: getBufService<AdmissionDiscoveryService>(\n 'dxos.mesh.teleport.AdmissionDiscoveryService',\n ),\n },\n });\n }\n\n protected override async getHandlers(): Promise<{ AdmissionDiscoveryService: AdmissionDiscoveryService }> {\n return {\n AdmissionDiscoveryService: {\n getAdmissionCredential: async (\n request: GetAdmissionCredentialRequest,\n ): Promise<GetAdmissionCredentialResponse> => {\n const memberInfo = this._space.spaceState.members.get(requirePublicKey(request.memberKey));\n if (!memberInfo?.credential) {\n throw new ProtocolError({ message: 'Space member not found.', context: { ...request } });\n }\n return create(GetAdmissionCredentialResponseSchema, { admissionCredential: memberInfo.credential });\n },\n },\n };\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { type Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { createIdFromSpaceKey } from '@dxos/echo-protocol';\nimport { type HypercoreWrapper } from '@dxos/feed-store';\nimport { PublicKey, SpaceId } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport {\n MMSTTopology,\n type SwarmConnection,\n type SwarmNetworkManager,\n type WireProtocol,\n type WireProtocolProps,\n type WireProtocolProvider,\n} from '@dxos/network-manager';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { type MuxerStats, Teleport } from '@dxos/teleport';\nimport { ReplicatorExtension } from '@dxos/teleport-extension-replicator';\nimport { type AsyncCallback, CallbackCollection, ComplexMap } from '@dxos/util';\n\nimport * as Auth from '../../Auth.ts';\nimport { AuthExtension } from './auth.ts';\n\nexport const MOCK_AUTH_PROVIDER: Auth.AuthProvider = async (nonce: Uint8Array) => Buffer.from('mock');\nexport const MOCK_AUTH_VERIFIER: Auth.AuthVerifier = async (nonce: Uint8Array, credential: Uint8Array) => true;\n\n// TODO(burdon): Reconcile with SigningContext (define types together).\nexport interface SwarmIdentity {\n peerKey: PublicKey;\n identityKey: PublicKey;\n credentialProvider: Auth.AuthProvider;\n credentialAuthenticator: Auth.AuthVerifier;\n}\n\nexport type SpaceProtocolOptions = {\n topic: PublicKey; // TODO(burdon): Rename?\n swarmIdentity: SwarmIdentity;\n networkManager: SwarmNetworkManager;\n\n onFeed?: (feed: HypercoreWrapper<FeedMessage>) => Promise<void>;\n\n /**\n * Called when new session is authenticated.\n * Additional extensions can be added here.\n */\n onSessionAuth?: (session: Teleport) => void;\n onAuthFailure?: (session: Teleport) => void;\n\n disableP2pReplication?: boolean;\n};\n\n/**\n * Manages Teleport protocol stream creation and joining swarms with replication and presence extensions.\n */\nexport class SpaceProtocol {\n private readonly _networkManager: SwarmNetworkManager;\n private readonly _swarmIdentity: SwarmIdentity;\n private readonly _onSessionAuth?: (session: Teleport) => void;\n private readonly _onAuthFailure?: (session: Teleport) => void;\n\n private readonly _disableP2pReplication: boolean;\n\n @logInfo\n private readonly _topic: Promise<PublicKey>;\n\n private readonly _spaceKey: PublicKey;\n\n private readonly _feeds = new Set<HypercoreWrapper<FeedMessage>>();\n private readonly _sessions = new ComplexMap<PublicKey, SpaceProtocolSession>(PublicKey.hash);\n // TODO(burdon): Move to config (with sensible defaults).\n private readonly _topology = new MMSTTopology({\n originateConnections: 4,\n maxPeers: 10,\n sampleSize: 20,\n });\n\n private _connection?: SwarmConnection;\n\n public readonly feedAdded = new CallbackCollection<AsyncCallback<HypercoreWrapper<FeedMessage>>>();\n\n get sessions(): ReadonlyMap<PublicKey, SpaceProtocolSession> {\n return this._sessions;\n }\n\n get feeds(): ReadonlySet<HypercoreWrapper<FeedMessage>> {\n return this._feeds;\n }\n\n @logInfo\n private get _ownPeerKey() {\n return this._swarmIdentity.peerKey;\n }\n\n constructor({\n topic,\n swarmIdentity,\n networkManager,\n onSessionAuth,\n onAuthFailure,\n disableP2pReplication,\n }: SpaceProtocolOptions) {\n this._spaceKey = topic;\n this._networkManager = networkManager;\n this._swarmIdentity = swarmIdentity;\n this._onSessionAuth = onSessionAuth;\n this._onAuthFailure = onAuthFailure;\n\n // Space swarm topic contract (DX-1125): the SpaceId bytes (first 20 bytes of SHA-256(spaceKey)).\n // Both peers and the edge must derive the identical swarm key; SpaceId is the only derivation\n // computable on workerd (pure subtle-crypto — the previous hypercore `discoveryKey` needs keyed\n // BLAKE2b, unavailable there). Edge counterpart: `TraceFeedWriter.getSpaceSwarmKey`.\n this._topic = createIdFromSpaceKey(topic).then((spaceId) => PublicKey.from(SpaceId.decode(spaceId)));\n\n this._disableP2pReplication = disableP2pReplication ?? false;\n }\n\n // TODO(burdon): Create abstraction for Space (e.g., add keys and have provider).\n async addHypercore(feed: HypercoreWrapper<FeedMessage>): Promise<void> {\n log('addHypercore', { key: feed.key });\n\n this._feeds.add(feed);\n for (const session of this._sessions.values()) {\n session.replicator.addHypercore(feed);\n }\n\n await this.feedAdded.callSerial(feed);\n }\n\n // TODO(burdon): Rename open? Common open/close interfaces for all services?\n async start(ctx: Context): Promise<void> {\n if (this._connection) {\n return;\n }\n\n // TODO(burdon): Document why empty buffer.\n const credentials = await this._swarmIdentity.credentialProvider(Buffer.from(''));\n\n log('starting...');\n const topic = await this._topic;\n this._connection = await this._networkManager.joinSwarm(ctx, {\n protocolProvider: this._createProtocolProvider(credentials),\n topic,\n topology: this._topology,\n label: `swarm ${topic.truncate()} for space ${this._spaceKey.truncate()}`,\n });\n\n log('started');\n }\n\n public updateTopology(): void {\n this._topology.forceUpdate();\n }\n\n async stop(ctx: Context): Promise<void> {\n if (this._connection) {\n log('stopping...');\n await this._connection.close(ctx);\n log('stopped');\n }\n }\n\n private _createProtocolProvider(credentials: Uint8Array | undefined): WireProtocolProvider {\n return (wireProps) => {\n const session = new SpaceProtocolSession({\n wireProps,\n swarmIdentity: this._swarmIdentity,\n onSessionAuth: this._onSessionAuth,\n onAuthFailure: this._onAuthFailure,\n disableP2pReplication: this._disableP2pReplication,\n });\n this._sessions.set(wireProps.remotePeerId, session);\n\n for (const feed of this._feeds) {\n session.replicator.addHypercore(feed);\n }\n\n return session;\n };\n }\n}\n\nexport type SpaceProtocolSessionProps = {\n wireProps: WireProtocolProps;\n swarmIdentity: SwarmIdentity;\n\n /**\n * Called when new session is authenticated.\n * Additional extensions can be added here.\n */\n onSessionAuth?: (session: Teleport) => void;\n\n onAuthFailure?: (session: Teleport) => void;\n\n disableP2pReplication?: boolean;\n};\n\nexport enum AuthStatus {\n INITIAL = 'INITIAL',\n SUCCESS = 'SUCCESS',\n FAILURE = 'FAILURE',\n}\n\n// TODO(dmaretskyi): Move to a separate file.\n/**\n * Represents a single connection to a remote peer\n */\nexport class SpaceProtocolSession implements WireProtocol {\n @logInfo\n private readonly _wireProps: WireProtocolProps;\n\n private readonly _disableP2pReplication: boolean;\n\n private readonly _onSessionAuth?: (session: Teleport) => void;\n private readonly _onAuthFailure?: (session: Teleport) => void;\n private readonly _swarmIdentity: SwarmIdentity;\n\n private readonly _teleport: Teleport;\n\n // TODO(dmaretskyi): Start with upload=false when switching it on the fly works.\n public readonly replicator = new ReplicatorExtension().setOptions({ upload: true });\n\n private _authStatus = AuthStatus.INITIAL;\n\n @logInfo\n get authStatus() {\n return this._authStatus;\n }\n\n get stats(): Event<MuxerStats> {\n return this._teleport.stats;\n }\n\n // TODO(dmaretskyi): Allow to pass in extra extensions.\n constructor({\n wireProps,\n swarmIdentity,\n onSessionAuth,\n onAuthFailure,\n disableP2pReplication,\n }: SpaceProtocolSessionProps) {\n this._wireProps = wireProps;\n this._swarmIdentity = swarmIdentity;\n this._onSessionAuth = onSessionAuth;\n this._onAuthFailure = onAuthFailure;\n\n this._teleport = new Teleport(wireProps);\n\n this._disableP2pReplication = disableP2pReplication ?? false;\n }\n\n get stream() {\n return this._teleport.stream;\n }\n\n get closed() {\n return this._teleport.closed;\n }\n\n async open(sessionId?: PublicKey): Promise<void> {\n await this._teleport.open(sessionId);\n this._teleport.addExtension(\n 'dxos.mesh.teleport.auth',\n new AuthExtension({\n provider: this._swarmIdentity.credentialProvider,\n verifier: this._swarmIdentity.credentialAuthenticator,\n onAuthSuccess: () => {\n log('Peer authenticated');\n this._authStatus = AuthStatus.SUCCESS;\n this._onSessionAuth?.(this._teleport);\n // TODO(dmaretskyi): Configure replicator to upload.\n },\n onAuthFailure: () => {\n this._authStatus = AuthStatus.FAILURE;\n this._onAuthFailure?.(this._teleport);\n },\n }),\n );\n\n if (!this._disableP2pReplication) {\n this._teleport.addExtension('dxos.mesh.teleport.replicator', this.replicator);\n }\n }\n\n async close(): Promise<void> {\n log('close');\n await this._teleport.close();\n }\n\n async abort(): Promise<void> {\n await this._teleport.abort();\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { type AutomergeUrl, parseAutomergeUrl } from '@automerge/automerge-repo';\nimport { create } from '@bufbuild/protobuf';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { Trigger, synchronized, trackLeaks } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type DelegateInvitationCredential, type MemberInfo, getCredentialAssertion } from '@dxos/credentials';\nimport { createIdFromSpaceKey } from '@dxos/echo-protocol';\nimport * as Hook from '@dxos/effect/Hook';\nimport { type HypercoreStore, HypercoreStoreService } from '@dxos/feed-store';\nimport { PublicKey, SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type SwarmNetworkManager, SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { type SpaceMetadata } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport type { Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { GetAdmissionCredentialRequestSchema } from '@dxos/protocols/buf/dxos/mesh/teleport/admission-discovery_pb';\nimport { type Teleport } from '@dxos/teleport';\nimport { ComplexMap } from '@dxos/util';\n\nimport * as Events from '../../Events.ts';\nimport { type IMetadataStore, IMetadataStoreService } from '../metadata/index.ts';\nimport { CredentialRetrieverExtension } from './admission-discovery-extension.ts';\nimport { SpaceProtocol, type SwarmIdentity } from './space-protocol.ts';\nimport { Space } from './space.ts';\n\nexport type SpaceManagerProps = {\n hypercoreStore: HypercoreStore<FeedMessage>;\n networkManager: SwarmNetworkManager;\n metadataStore: IMetadataStore;\n\n disableP2pReplication?: boolean;\n};\n\nexport type ConstructSpaceProps = {\n metadata: SpaceMetadata;\n swarmIdentity: SwarmIdentity;\n memberKey: PublicKey;\n /**\n * Called when connection auth passed successful.\n */\n onAuthorizedConnection: (session: Teleport) => void;\n onAuthFailure?: (session: Teleport) => void;\n onDelegatedInvitationStatusChange: (invitation: DelegateInvitationCredential, isActive: boolean) => Promise<void>;\n onMemberRolesChanged: (member: MemberInfo[]) => Promise<void>;\n};\n\nexport type RequestSpaceAdmissionCredentialProps = {\n spaceKey: PublicKey;\n identityKey: PublicKey;\n swarmIdentity: SwarmIdentity;\n timeout: number;\n};\n\n/**\n * Effect service tag for {@link SpaceManager}.\n */\nexport class SpaceManagerService extends EffectContext.Service<SpaceManagerService, SpaceManager>()(\n '@dxos/client-services/SpaceManager',\n) {}\n\n/**\n * Manages a collection of ECHO (Data) Spaces.\n */\n@trackLeaks('open', 'close')\nexport class SpaceManager {\n private readonly _spaces = new ComplexMap<PublicKey, Space>(PublicKey.hash);\n private readonly _hypercoreStore: HypercoreStore<FeedMessage>;\n private readonly _networkManager: SwarmNetworkManager;\n private readonly _metadataStore: IMetadataStore;\n private readonly _disableP2pReplication: boolean;\n\n constructor({ hypercoreStore, networkManager, metadataStore, disableP2pReplication }: SpaceManagerProps) {\n // TODO(burdon): Assert.\n this._hypercoreStore = hypercoreStore;\n this._networkManager = networkManager;\n this._metadataStore = metadataStore;\n this._disableP2pReplication = disableP2pReplication ?? false;\n }\n\n // TODO(burdon): Remove.\n get spaces() {\n return this._spaces;\n }\n\n @synchronized\n async open(): Promise<void> {}\n\n @synchronized\n async close(): Promise<void> {\n await Promise.all([...this._spaces.values()].map((space) => space.close()));\n }\n\n async constructSpace({\n metadata,\n swarmIdentity,\n onAuthorizedConnection,\n onAuthFailure,\n onDelegatedInvitationStatusChange,\n onMemberRolesChanged,\n memberKey,\n }: ConstructSpaceProps): Promise<Space> {\n log('constructing space...', { spaceKey: metadata.genesisFeedKey });\n\n // The genesis feed will be the same as the control feed if the space was created by the local agent.\n const genesisFeed = await this._hypercoreStore.openHypercore(requirePublicKey(metadata.genesisFeedKey));\n\n const spaceKey = requirePublicKey(metadata.key);\n // The carried id is primary; derive only for a space recorded before the field existed.\n const spaceId = metadata.spaceId ? SpaceId.make(metadata.spaceId) : await createIdFromSpaceKey(spaceKey);\n const protocol = new SpaceProtocol({\n topic: spaceKey,\n swarmIdentity,\n networkManager: this._networkManager,\n onSessionAuth: onAuthorizedConnection,\n onAuthFailure,\n disableP2pReplication: this._disableP2pReplication,\n });\n\n const space = new Space({\n id: spaceId,\n spaceKey,\n protocol,\n genesisFeed,\n feedProvider: (feedKey, opts) => this._hypercoreStore.openHypercore(feedKey, opts),\n metadataStore: this._metadataStore,\n memberKey,\n onDelegatedInvitationStatusChange,\n onMemberRolesChanged,\n });\n this._spaces.set(space.key, space);\n\n return space;\n }\n\n public async requestSpaceAdmissionCredential(\n ctx: Context,\n params: RequestSpaceAdmissionCredentialProps,\n ): Promise<Credential> {\n log('requesting space admission credential...', { spaceKey: params.spaceKey });\n\n const onCredentialResolved = new Trigger<Credential>();\n const protocol = new SpaceProtocol({\n topic: params.spaceKey,\n swarmIdentity: params.swarmIdentity,\n networkManager: this._networkManager,\n onSessionAuth: (session: Teleport) => {\n session.addExtension(\n 'dxos.mesh.teleport.admission-discovery',\n new CredentialRetrieverExtension(\n create(GetAdmissionCredentialRequestSchema, {\n spaceKey: fromPublicKey(params.spaceKey),\n memberKey: fromPublicKey(params.identityKey),\n }),\n onCredentialResolved,\n ),\n );\n },\n onAuthFailure: (session: Teleport) => session.close(),\n disableP2pReplication: this._disableP2pReplication,\n });\n\n try {\n await protocol.start(ctx);\n const credential = await onCredentialResolved.wait({ timeout: params.timeout });\n return credential;\n } catch (err: any) {\n throw err;\n } finally {\n await protocol.stop(ctx);\n }\n }\n\n public findSpaceByRootDocumentId(documentId: string): Space | undefined {\n return [...this._spaces.values()].find((space) => {\n return space.spaceState.credentials.some((credential) => {\n const assertion = getCredentialAssertion(credential);\n if (assertion.$typeName !== 'dxos.halo.credentials.Epoch' || !assertion.automergeRoot) {\n return false;\n }\n return parseAutomergeUrl(assertion.automergeRoot as AutomergeUrl).documentId === documentId;\n });\n });\n }\n}\n\nexport type SpaceManagerLayerOptions = Pick<SpaceManagerProps, 'disableP2pReplication'>;\n\n/**\n * Effect Layer constructing a {@link SpaceManager} from ambient service dependencies.\n */\nexport const SpaceManagerLayer = (\n options: SpaceManagerLayerOptions = {},\n): Layer.Layer<\n SpaceManagerService,\n never,\n Hook.Controller | HypercoreStoreService | SwarmNetworkManagerService | IMetadataStoreService\n> =>\n Layer.effect(\n SpaceManagerService,\n Effect.gen(function* () {\n const hypercoreStore = yield* HypercoreStoreService;\n const networkManager = yield* SwarmNetworkManagerService;\n const metadataStore = yield* IMetadataStoreService;\n const spaceManager = new SpaceManager({\n hypercoreStore,\n networkManager,\n metadataStore,\n disableP2pReplication: options.disableP2pReplication,\n });\n\n yield* Effect.addFinalizer(() => Effect.promise(() => spaceManager.close()));\n yield* Events.NetworkReady.pipe(\n Hook.handler(() => Effect.promise(() => spaceManager.open())),\n Hook.subscribe,\n );\n return spaceManager;\n }),\n );\n","//\n// Copyright 2021 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { SubscriptionList } from '@dxos/async';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { HypercoreIterator, type HypercoreStore, type HypercoreWrapper } from '@dxos/feed-store';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type FeedMessageBlock } from '@dxos/protocols';\nimport { buf, fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport {\n type SubscribeToFeedBlocksResponse,\n SubscribeToFeedBlocksResponse_BlockSchema,\n SubscribeToFeedBlocksResponseSchema,\n} from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { type FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { type DevtoolsHost } from '@dxos/protocols/rpc';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type SpaceManager } from '../space/index.ts';\n\n/** Feed blocks come off the iterator in the protobuf.js shape, which crosses as the shared wire bytes. */\n/** The feed's blocks as the devtools RPC message; the iterator yields the domain block shape. */\nconst toBufResponse = (blocks: FeedMessageBlock[]): SubscribeToFeedBlocksResponse =>\n buf.create(SubscribeToFeedBlocksResponseSchema, {\n blocks: blocks.map((block) =>\n buf.create(SubscribeToFeedBlocksResponse_BlockSchema, {\n feedKey: fromPublicKey(block.feedKey),\n seq: block.seq,\n data: block.data,\n }),\n ),\n });\n\ntype FeedInfo = {\n feed: HypercoreWrapper<FeedMessage>;\n owner?: DevtoolsHost.SubscribeToFeedsResponse.FeedOwner;\n};\n\nexport const subscribeToFeeds = (\n { hypercoreStore, spaceManager }: { hypercoreStore: HypercoreStore<FeedMessage>; spaceManager: SpaceManager },\n { feedKeys }: DevtoolsHost.SubscribeToFeedsRequest,\n): EffectStream.Stream<DevtoolsHost.SubscribeToFeedsResponse, Error> => {\n return EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToFeedsResponse, Error>((emit) => {\n const subscriptions = new SubscriptionList();\n const feedMap = new ComplexMap<PublicKey, FeedInfo>(PublicKey.hash);\n\n const update = () => {\n const { feeds } = hypercoreStore;\n feeds\n .filter((feed) => !feedKeys?.length || feedKeys.some((feedKey) => feedKey.equals(feed.key)))\n .forEach((feed) => {\n if (!feedMap.has(feed.key)) {\n feedMap.set(feed.key, { feed });\n feed.on('close', update);\n subscriptions.add(() => feed.off('close', update));\n }\n if (!feedMap.get(feed.key)?.owner) {\n feedMap.get(feed.key)!.owner = findFeedOwner(spaceManager, feed.key);\n }\n });\n\n emit.single({\n feeds: Array.from(feedMap.values()).map(({ feed, owner }) => ({\n feedKey: feed.key,\n length: feed.properties.length,\n bytes: feed.core.byteLength,\n downloaded: feed.core.bitfield?.data.toBuffer() ?? new Uint8Array(),\n owner,\n })),\n });\n };\n\n subscriptions.add(hypercoreStore.feedOpened.on(update));\n update();\n\n return Effect.sync(() => {\n subscriptions.clear();\n });\n });\n};\n\nconst findFeedOwner = (\n spaceManager: SpaceManager,\n feedKey: PublicKey,\n): DevtoolsHost.SubscribeToFeedsResponse.FeedOwner | undefined => {\n const feedInfo = [...spaceManager.spaces.values()]\n .flatMap((space) => [...space.spaceState.feeds.values()])\n .find((feed) => feed.key.equals(feedKey));\n log('feeds', { feedInfo, key: feedKey.truncate(), allSpaces: spaceManager.spaces.size });\n if (!feedInfo) {\n return undefined;\n }\n return {\n identity: requirePublicKey(feedInfo.assertion.identityKey),\n device: requirePublicKey(feedInfo.assertion.deviceKey),\n };\n};\n\nexport const subscribeToFeedBlocks = (\n { hypercoreStore }: { hypercoreStore: HypercoreStore<FeedMessage> },\n { feedKey, maxBlocks = 10 }: DevtoolsHost.SubscribeToFeedBlocksRequest,\n): EffectStream.Stream<SubscribeToFeedBlocksResponse, Error> => {\n return EffectEx.streamFromEmitter<SubscribeToFeedBlocksResponse, Error>((emit) => {\n if (!feedKey) {\n return;\n }\n\n const subscriptions = new SubscriptionList();\n\n const timeout = setTimeout(async () => {\n const feed = hypercoreStore.getHypercore(feedKey);\n if (!feed) {\n return;\n }\n\n const update = async () => {\n if (!feed.properties.length) {\n emit.single(toBufResponse([]));\n return;\n }\n\n const iterator = new HypercoreIterator(feed);\n await iterator.open();\n const blocks = [];\n for await (const block of iterator) {\n blocks.push(block);\n if (blocks.length >= feed.properties.length) {\n break;\n }\n }\n\n emit.single(toBufResponse(blocks.slice(-maxBlocks)));\n\n await iterator.close();\n };\n\n feed.on('append', update);\n subscriptions.add(() => feed.off('append', update));\n\n feed.on('truncate', update);\n subscriptions.add(() => feed.off('truncate', update));\n await update();\n });\n\n return Effect.sync(() => {\n subscriptions.clear();\n clearTimeout(timeout);\n });\n });\n};\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { type DevtoolsHost } from '@dxos/protocols/rpc';\n\nexport const subscribeToKeyringKeys = ({\n keyring,\n}: {\n keyring: KeyringApi;\n}): EffectStream.Stream<DevtoolsHost.SubscribeToKeyringKeysResponse, Error> =>\n EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToKeyringKeysResponse, Error>((emit) => {\n const ctx = Context.default();\n const update = async () => {\n try {\n emit.single({\n keys: await keyring.list(),\n });\n } catch (err: any) {\n emit.fail(err);\n }\n };\n keyring.keysUpdate.on(ctx, update);\n scheduleTask(ctx, update);\n\n return Effect.promise(() => ctx.dispose());\n });\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { buf } from '@dxos/protocols/buf';\nimport {\n type SubscribeToMetadataResponse,\n SubscribeToMetadataResponseSchema,\n} from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { type EchoMetadata } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\n\nimport { type IMetadataStore } from '../metadata/index.ts';\n\nconst toBufResponse = (metadata: EchoMetadata): SubscribeToMetadataResponse =>\n buf.create(SubscribeToMetadataResponseSchema, { metadata });\n\nexport const subscribeToMetadata = ({\n metadataStore,\n}: {\n metadataStore: IMetadataStore;\n}): EffectStream.Stream<SubscribeToMetadataResponse, Error> =>\n EffectEx.streamFromEmitter<SubscribeToMetadataResponse, Error>((emit) => {\n const ctx = Context.default();\n metadataStore.update.on(ctx, (data) => emit.single(toBufResponse(data)));\n emit.single(toBufResponse(metadataStore.metadata));\n\n return Effect.promise(() => ctx.dispose());\n });\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { type MessageInitShape, create } from '@bufbuild/protobuf';\nimport { AnySchema, timestampFromDate } from '@bufbuild/protobuf/wkt';\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type PeerInfo, type SignalManager, type UnsubscribeCallback } from '@dxos/messaging';\nimport { type SwarmNetworkManager } from '@dxos/network-manager';\nimport { requirePublicKey, toDate } from '@dxos/protocols/buf';\nimport { type SignalResponse, SignalResponseSchema } from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { type ConnectionInfo, type SwarmInfo } from '@dxos/protocols/buf/dxos/devtools/swarm_pb';\nimport { SwarmEventSchema } from '@dxos/protocols/buf/dxos/mesh/signal_pb';\nimport { type DevtoolsHost } from '@dxos/protocols/rpc';\n\nexport const subscribeToNetworkStatus = ({\n signalManager,\n}: {\n signalManager: SignalManager;\n}): EffectStream.Stream<DevtoolsHost.SubscribeToSignalStatusResponse, Error> =>\n EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToSignalStatusResponse, Error>((emit) => {\n const update = () => {\n try {\n const status = signalManager.getStatus?.();\n emit.single({ servers: status });\n } catch (err: any) {\n emit.fail(err);\n }\n };\n\n const unsubscribe = signalManager.statusChanged?.on(() => update());\n update();\n\n return Effect.sync(() => unsubscribe?.());\n });\n\nexport const subscribeToSignal = ({\n signalManager,\n networkManager,\n}: {\n signalManager: SignalManager;\n networkManager: SwarmNetworkManager;\n}): EffectStream.Stream<SignalResponse, Error> =>\n EffectEx.streamFromEmitter<SignalResponse, Error>((emit) => {\n const ctx = new Context();\n\n // Observe point-to-point messages delivered to this node's own peer. The subscription owns its\n // routing and teardown (DX-1125); with no local peer yet there is nothing to observe.\n let unsubscribe: UnsubscribeCallback | undefined;\n const peer = networkManager.getPeerInfo();\n if (peer) {\n void signalManager\n .subscribeMessages({\n peer,\n onMessage: (message) => {\n emit.single(\n create(SignalResponseSchema, {\n data: {\n case: 'message',\n value: {\n author: peerKeyBytes(message.author),\n recipient: peerKeyBytes(message.recipient),\n // Messaging keeps payloads packed and dispatches on `typeUrl`, so this is a\n // field map — the payload is never resolved here.\n payload: create(AnySchema, {\n typeUrl: message.payload?.typeUrl,\n value: message.payload?.value,\n }),\n },\n },\n receivedAt: timestampFromDate(new Date()),\n }),\n );\n },\n })\n .then((unsub) => {\n if (ctx.disposed) {\n void unsub();\n } else {\n unsubscribe = unsub;\n }\n })\n .catch((err) => log.catch(err));\n }\n\n signalManager.swarmEvent.on(ctx, (swarmEvent) => {\n const event: MessageInitShape<typeof SwarmEventSchema>['event'] =\n swarmEvent.event.case === 'peerAvailable'\n ? {\n case: 'peerAvailable',\n value: {\n peer: peerKeyBytes(swarmEvent.event.value.peer),\n since: swarmEvent.event.value.since,\n },\n }\n : swarmEvent.event.case === 'peerLeft'\n ? { case: 'peerLeft', value: { peer: peerKeyBytes(swarmEvent.event.value.peer) } }\n : { case: undefined };\n\n emit.single(\n create(SignalResponseSchema, {\n data: { case: 'swarmEvent', value: create(SwarmEventSchema, { event }) },\n topic: swarmEvent.topic?.data,\n receivedAt: timestampFromDate(new Date()),\n }),\n );\n });\n\n return Effect.promise(async () => {\n await unsubscribe?.();\n await ctx.dispose();\n });\n });\n\nexport const subscribeToNetworkTopics = ({\n networkManager,\n}: {\n networkManager: SwarmNetworkManager;\n}): EffectStream.Stream<DevtoolsHost.SubscribeToNetworkTopicsResponse, Error> =>\n EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToNetworkTopicsResponse, Error>((emit) => {\n const update = () => {\n try {\n const topics = networkManager.topics;\n const labeledTopics = topics.map((topic) => ({\n topic,\n label: networkManager.getSwarm(topic)?.label ?? topic.toHex(),\n }));\n emit.single({ topics: labeledTopics });\n } catch (err: any) {\n emit.fail(err);\n }\n };\n const unsubscribe = networkManager.topicsUpdated.on(update);\n\n update();\n\n return Effect.sync(() => unsubscribe());\n });\n\nexport const subscribeToSwarmInfo = ({\n networkManager,\n}: {\n networkManager: SwarmNetworkManager;\n}): EffectStream.Stream<DevtoolsHost.SubscribeToSwarmInfoResponse, Error> =>\n EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToSwarmInfoResponse, Error>((emit) => {\n const update = () => {\n const info = networkManager.connectionLog?.swarms;\n if (info) {\n emit.single({ data: info.map(toSwarmInfo) });\n }\n };\n const unsubscribe = networkManager.connectionLog?.update.on(update);\n update();\n\n return Effect.sync(() => unsubscribe?.());\n });\n\nexport const getNetworkPeers = (\n { networkManager }: { networkManager: SwarmNetworkManager },\n request: DevtoolsHost.GetNetworkPeersRequest,\n): DevtoolsHost.GetNetworkPeersResponse => {\n if (!request.topic) {\n throw new Error('Expected a network topic');\n }\n\n const map = networkManager.getSwarmMap(PublicKey.from(request.topic));\n return {\n peers: map?.peers.map((peer) => ({\n ...peer,\n connections: peer.connections.map((connection) => connection.asUint8Array()),\n })),\n };\n};\n\n/** The peer's key as the raw bytes the devtools swarm event carries. */\nconst peerKeyBytes = (peer: PeerInfo | undefined): Uint8Array =>\n peer ? PublicKey.from(peer.peerKey).asUint8Array() : new Uint8Array();\n\n/**\n * Reads the connection log's message as the devtools RPC shape.\n *\n * The log holds the generated message; the devtools panels are keyed by the domain `PublicKey`, so\n * the keys and timestamps convert at this one boundary.\n */\nconst toSwarmInfo = (swarm: SwarmInfo): DevtoolsHost.SwarmInfo => ({\n id: requirePublicKey(swarm.id),\n topic: requirePublicKey(swarm.topic),\n label: swarm.label,\n isActive: swarm.isActive,\n connections: swarm.connections.map(toConnectionInfo),\n});\n\nconst toConnectionInfo = (connection: ConnectionInfo): DevtoolsHost.ConnectionInfo => ({\n state: connection.state,\n sessionId: requirePublicKey(connection.sessionId),\n remotePeerId: requirePublicKey(connection.remotePeerId),\n transport: connection.transport,\n protocolExtensions: connection.protocolExtensions,\n events: connection.events.map((event) => ({ type: event.type, newState: event.newState, error: event.error })),\n streams: connection.streams,\n closeReason: connection.closeReason,\n identity: connection.identity,\n readBufferSize: connection.readBufferSize,\n writeBufferSize: connection.writeBufferSize,\n lastUpdate: toDate(connection.lastUpdate),\n transportDetails: connection.transportDetails,\n transportBytesSent: connection.transportBytesSent,\n transportBytesReceived: connection.transportBytesReceived,\n transportPacketsSent: connection.transportPacketsSent,\n transportPacketsReceived: connection.transportPacketsReceived,\n});\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { type Trigger } from '@dxos/async';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport {\n type SubscribeToSpacesResponse,\n type SubscribeToSpacesResponse_SpaceInfo,\n SubscribeToSpacesResponse_SpaceInfoSchema,\n SubscribeToSpacesResponseSchema,\n} from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { type SpaceMetadata } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { type DevtoolsHost } from '@dxos/protocols/rpc';\n\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport { type IMetadataStore } from '../metadata/index.ts';\nimport { type Space, type SpaceManager } from '../space/index.ts';\n\nexport const subscribeToSpaces = (\n {\n spaceManager,\n metadataStore,\n dataSpaceManager,\n initialized,\n }: {\n spaceManager: SpaceManager;\n metadataStore: IMetadataStore;\n dataSpaceManager: SpacesContract.Manager;\n initialized: Trigger;\n },\n { spaceKeys = [] }: DevtoolsHost.SubscribeToSpacesRequest,\n): EffectStream.Stream<SubscribeToSpacesResponse, Error> => {\n return EffectEx.streamFromEmitter<SubscribeToSpacesResponse, Error>((emit) => {\n let unsubscribe: () => void;\n\n const update = async () => {\n const spaces: Space[] = [...spaceManager.spaces.values()];\n const filteredSpaces = spaces.filter(\n (space) => !spaceKeys?.length || spaceKeys.some((spaceKey) => spaceKey.equals(space.key)),\n );\n\n emit.single(\n create(SubscribeToSpacesResponseSchema, {\n spaces: filteredSpaces.map((space): SubscribeToSpacesResponse_SpaceInfo => {\n const spaceMetadata = metadataStore.spaces.find(\n (spaceMetadata: SpaceMetadata) =>\n spaceMetadata.key && requirePublicKey(spaceMetadata.key).equals(space.key),\n );\n\n return create(SubscribeToSpacesResponse_SpaceInfoSchema, {\n key: fromPublicKey(space.key),\n isOpen: space.isOpen,\n timeframe: spaceMetadata?.dataTimeframe,\n genesisFeed: fromPublicKey(space.genesisFeedKey),\n // The write feeds are absent until the space is opened for writing; buf makes that\n // presence explicit where the protobuf.js shape let it pass as a non-null assertion.\n controlFeed: space.controlFeedKey && fromPublicKey(space.controlFeedKey),\n dataFeed: space.dataFeedKey && fromPublicKey(space.dataFeedKey),\n });\n }),\n }),\n );\n };\n\n const timeout = setTimeout(async () => {\n await initialized.wait();\n unsubscribe = dataSpaceManager.updated.on(() => update());\n\n // Send initial spaces.\n await update();\n });\n\n return Effect.sync(() => {\n unsubscribe?.();\n clearTimeout(timeout);\n });\n });\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Event as AsyncEvent, type Trigger } from '@dxos/async';\nimport { type Config, ConfigService } from '@dxos/config';\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { NotImplementedError } from '@dxos/errors';\nimport { type HypercoreStore, HypercoreStoreService } from '@dxos/feed-store';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { type SignalManager, SignalManagerService } from '@dxos/messaging';\nimport { type SwarmNetworkManager, SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { toServiceError } from '@dxos/protocols';\nimport {\n type GetSpaceSnapshotResponse,\n type SaveSpaceSnapshotResponse,\n type SignalResponse,\n type SubscribeToFeedBlocksResponse,\n type SubscribeToMetadataResponse,\n type SubscribeToSpacesResponse,\n} from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { DevtoolsHost } from '@dxos/protocols/rpc';\nimport * as SqlExport from '@dxos/sql-sqlite/SqlExport';\n\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Readiness from '../../Readiness.ts';\nimport { type IMetadataStore, IMetadataStoreService } from '../metadata/index.ts';\nimport { type SpaceManager, SpaceManagerService } from '../space/index.ts';\nimport { subscribeToFeedBlocks, subscribeToFeeds } from './feeds.ts';\nimport { subscribeToKeyringKeys } from './keys.ts';\nimport { subscribeToMetadata } from './metadata.ts';\nimport { subscribeToNetworkStatus, subscribeToSignal, subscribeToSwarmInfo } from './network.ts';\nimport { subscribeToSpaces } from './spaces.ts';\n\nexport class DevtoolsHostEvents {\n readonly ready = new AsyncEvent();\n}\n\nexport type DevtoolsServiceProps = {\n events: DevtoolsHostEvents;\n config: Config;\n keyring: KeyringApi;\n hypercoreStore: HypercoreStore<any>;\n spaceManager: SpaceManager;\n metadataStore: IMetadataStore;\n dataSpaceManager: SpacesContract.Manager;\n initialized: Trigger;\n signalManager: SignalManager;\n networkManager: SwarmNetworkManager;\n sql: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlExport.SqlExport>;\n};\n\n/**\n * @deprecated\n */\nexport class DevtoolsServiceImpl implements DevtoolsHost.Handlers {\n 'constructor'(private readonly params: DevtoolsServiceProps) {}\n\n /**\n * Debugging util.\n */\n async 'exportSqliteDatabase'(): Promise<Uint8Array> {\n return RuntimeProvider.runPromise(this.params.sql)(\n Effect.gen(function* () {\n const sql = yield* SqlExport.SqlExport;\n return yield* sql.export;\n }),\n );\n }\n\n /**\n * Debugging util.\n */\n async 'runSqliteQuery'(query: string, params?: unknown[]): Promise<readonly Record<string, unknown>[]> {\n return RuntimeProvider.runPromise(this.params.sql)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql`${sql.unsafe(query, params)}`;\n }),\n );\n }\n\n ['DevtoolsHost.events'](): EffectStream.Stream<DevtoolsHost.Event, Error> {\n return EffectEx.streamFromEmitter<DevtoolsHost.Event, Error>((emit) => {\n const ctx = Context.default();\n this.params.events.ready.on(ctx, () => {\n void emit.single({ ready: {} });\n });\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['DevtoolsHost.getConfig'](): Effect.Effect<DevtoolsHost.GetConfigResponse, Error> {\n return Effect.sync(() => ({ config: JSON.stringify(this.params.config.values) }));\n }\n\n ['DevtoolsHost.getStorageInfo'](): Effect.Effect<DevtoolsHost.StorageInfo, Error> {\n return Effect.tryPromise({\n try: async () => {\n const navigatorInfo = typeof navigator === 'object' ? await navigator.storage.estimate() : undefined;\n\n return {\n type: 'sqlite',\n storageUsage: navigatorInfo?.usage ?? 0,\n originUsage: navigatorInfo?.usage ?? 0,\n usageQuota: navigatorInfo?.quota ?? 0,\n };\n },\n catch: toServiceError,\n });\n }\n\n ['DevtoolsHost.getSnapshots'](): Effect.Effect<DevtoolsHost.GetSnapshotsResponse, Error> {\n return Effect.sync(() => ({\n snapshots: [],\n }));\n }\n\n ['DevtoolsHost.resetStorage'](_request: DevtoolsHost.ResetStorageRequest): Effect.Effect<void, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.resetStorage is not implemented.' }));\n }\n\n ['DevtoolsHost.enableDebugLogging'](\n _request: DevtoolsHost.EnableDebugLoggingRequest,\n ): Effect.Effect<DevtoolsHost.EnableDebugLoggingResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.enableDebugLogging is not implemented.' }));\n }\n\n ['DevtoolsHost.disableDebugLogging'](\n _request: DevtoolsHost.EnableDebugLoggingRequest,\n ): Effect.Effect<DevtoolsHost.EnableDebugLoggingResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.disableDebugLogging is not implemented.' }));\n }\n\n ['DevtoolsHost.subscribeToKeyringKeys'](\n _request: DevtoolsHost.SubscribeToKeyringKeysRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToKeyringKeysResponse, Error> {\n return subscribeToKeyringKeys({ keyring: this.params.keyring });\n }\n\n ['DevtoolsHost.subscribeToCredentialMessages'](\n _request: DevtoolsHost.SubscribeToCredentialMessagesRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToCredentialMessagesResponse, Error> {\n return EffectStream.fail(new Error());\n }\n\n ['DevtoolsHost.subscribeToSpaces'](\n request: DevtoolsHost.SubscribeToSpacesRequest,\n ): EffectStream.Stream<SubscribeToSpacesResponse, Error> {\n return subscribeToSpaces(this.params, request);\n }\n\n ['DevtoolsHost.subscribeToItems'](\n _request: DevtoolsHost.SubscribeToItemsRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToItemsResponse, Error> {\n return EffectStream.fail(new Error());\n }\n\n ['DevtoolsHost.subscribeToFeeds'](\n request: DevtoolsHost.SubscribeToFeedsRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToFeedsResponse, Error> {\n return subscribeToFeeds(this.params, request);\n }\n\n ['DevtoolsHost.subscribeToFeedBlocks'](\n request: DevtoolsHost.SubscribeToFeedBlocksRequest,\n ): EffectStream.Stream<SubscribeToFeedBlocksResponse, Error> {\n return subscribeToFeedBlocks({ hypercoreStore: this.params.hypercoreStore }, request);\n }\n\n ['DevtoolsHost.subscribeToMetadata'](): EffectStream.Stream<SubscribeToMetadataResponse, Error> {\n return subscribeToMetadata({ metadataStore: this.params.metadataStore });\n }\n\n ['DevtoolsHost.getSpaceSnapshot'](\n _request: DevtoolsHost.GetSpaceSnapshotRequest,\n ): Effect.Effect<GetSpaceSnapshotResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.getSpaceSnapshot is not implemented.' }));\n }\n\n ['DevtoolsHost.saveSpaceSnapshot'](\n _request: DevtoolsHost.SaveSpaceSnapshotRequest,\n ): Effect.Effect<SaveSpaceSnapshotResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.saveSpaceSnapshot is not implemented.' }));\n }\n\n ['DevtoolsHost.clearSnapshots'](\n _request: DevtoolsHost.ClearSnapshotsRequest,\n ): Effect.Effect<void, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.clearSnapshots is not implemented.' }));\n }\n\n ['DevtoolsHost.getNetworkPeers'](\n _request: DevtoolsHost.GetNetworkPeersRequest,\n ): Effect.Effect<DevtoolsHost.GetNetworkPeersResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.getNetworkPeers is not implemented.' }));\n }\n\n ['DevtoolsHost.subscribeToNetworkTopics'](): EffectStream.Stream<\n DevtoolsHost.SubscribeToNetworkTopicsResponse,\n Error\n > {\n return EffectStream.fail(new Error());\n }\n\n ['DevtoolsHost.subscribeToSignalStatus'](): EffectStream.Stream<DevtoolsHost.SubscribeToSignalStatusResponse, Error> {\n return subscribeToNetworkStatus({ signalManager: this.params.signalManager });\n }\n\n ['DevtoolsHost.subscribeToSignal'](): EffectStream.Stream<SignalResponse, Error> {\n return subscribeToSignal({\n signalManager: this.params.signalManager,\n networkManager: this.params.networkManager,\n });\n }\n\n ['DevtoolsHost.subscribeToSwarmInfo'](\n _request: DevtoolsHost.SubscribeToSwarmInfoRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToSwarmInfoResponse, Error> {\n return subscribeToSwarmInfo({ networkManager: this.params.networkManager });\n }\n\n ['DevtoolsHost.exportSqliteDatabase'](): Effect.Effect<DevtoolsHost.ExportSqliteDatabaseResponse, Error> {\n return Effect.tryPromise({\n try: async () => ({\n data: await this.exportSqliteDatabase(),\n }),\n catch: toServiceError,\n });\n }\n\n ['DevtoolsHost.runSqliteQuery'](\n request: DevtoolsHost.RunSqliteQueryRequest,\n ): Effect.Effect<DevtoolsHost.RunSqliteQueryResponse, Error> {\n return Effect.promise(async () => {\n try {\n const parsedParams = request.params ? JSON.parse(request.params) : undefined;\n if (parsedParams !== undefined && !Array.isArray(parsedParams)) {\n throw new Error('Query params must be a JSON array.');\n }\n const rows = await this.runSqliteQuery(request.query, parsedParams);\n return { rows: JSON.stringify(rows) };\n } catch (err) {\n return { rows: '[]', error: err instanceof Error ? err.message : String(err) };\n }\n });\n }\n}\n\n/**\n * The impl under its own tag, so the host can reach the SQL debugging utils the RPC {@link DevtoolsHost.Tag}\n * does not expose.\n */\nexport class DevtoolsHostService extends EffectContext.Service<DevtoolsHostService, DevtoolsServiceImpl>()(\n '@dxos/client-services/DevtoolsHost',\n) {}\n\nconst devtoolsImplLayer: Layer.Layer<\n DevtoolsHostService,\n never,\n | ConfigService\n | KeyringApiService\n | HypercoreStoreService\n | SpaceManagerService\n | IMetadataStoreService\n | SpacesContract.ManagerService\n | Readiness.StackReadinessService\n | SignalManagerService\n | SwarmNetworkManagerService\n | SqlClient.SqlClient\n | SqlExport.SqlExport\n> = Layer.effect(\n DevtoolsHostService,\n Effect.gen(function* () {\n const config = yield* ConfigService;\n const keyring = yield* KeyringApiService;\n const hypercoreStore = yield* HypercoreStoreService;\n const spaceManager = yield* SpaceManagerService;\n const metadataStore = yield* IMetadataStoreService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const readiness = yield* Readiness.StackReadinessService;\n const signalManager = yield* SignalManagerService;\n const networkManager = yield* SwarmNetworkManagerService;\n const sql = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient | SqlExport.SqlExport>();\n return new DevtoolsServiceImpl({\n events: new DevtoolsHostEvents(),\n config,\n keyring,\n hypercoreStore,\n spaceManager,\n metadataStore,\n dataSpaceManager,\n initialized: readiness.initialized,\n signalManager,\n networkManager,\n sql,\n });\n }),\n);\n\nexport const DevtoolsHostLayer = Layer.effect(DevtoolsHost.Tag, DevtoolsHostService).pipe(\n Layer.provideMerge(devtoolsImplLayer),\n);\n","//\n// Copyright 2022 DXOS.org\n//\n\n// @import-as-namespace\n\nimport { buf } from '@dxos/protocols/buf';\nimport { type Platform, Platform_PLATFORM_TYPE, PlatformSchema } from '@dxos/protocols/buf/dxos/client/services_pb';\n\nexport const getPlatform = (): Platform => {\n if ((process as any).browser) {\n if (typeof window !== 'undefined') {\n // Browser.\n const { userAgent } = window.navigator;\n return buf.create(PlatformSchema, {\n type: Platform_PLATFORM_TYPE.BROWSER,\n userAgent,\n uptime: Math.floor((Date.now() - window.performance.timeOrigin) / 1_000),\n });\n } else {\n // Dedicated worker.\n return buf.create(PlatformSchema, {\n type: Platform_PLATFORM_TYPE.DEDICATED_WORKER,\n uptime: Math.floor((Date.now() - performance.timeOrigin) / 1_000),\n });\n }\n } else {\n // Node.\n const { platform, version, arch } = process;\n // `MemoryUsage` is an interface without an index signature, so the Struct field takes the\n // fields explicitly rather than the object itself.\n const { rss, heapTotal, heapUsed, external, arrayBuffers } = process.memoryUsage();\n return buf.create(PlatformSchema, {\n type: Platform_PLATFORM_TYPE.NODE,\n platform,\n arch,\n runtime: version,\n uptime: Math.floor(process.uptime()),\n memory: { rss, heapTotal, heapUsed, external, arrayBuffers },\n });\n }\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nexport const DXOS_VERSION = '0.13.0';\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\n\nimport { asyncTimeout } from '@dxos/async';\nimport { getFirstStreamValue } from '@dxos/async';\nimport { type ClientServices, makeClientServicesRpcFromRouter, makeServicesFromRpc } from '@dxos/client-protocol';\nimport { type Config, type ConfigProto } from '@dxos/config';\nimport { createDidFromIdentityKey, credentialsOfType } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { STORAGE_VERSION } from '@dxos/protocols';\nimport { buf, fromPublicKey, fromTimeframe, toDate, toPublicKey } from '@dxos/protocols/buf';\nimport {\n type Device,\n type Identity,\n IdentitySchema,\n type NetworkStatus,\n type Platform,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport {\n type Space_Metrics,\n type Space_PipelineState,\n Space_PipelineStateSchema,\n IdentitySchema as SpaceIdentitySchema,\n type SpaceMember,\n SpaceMember_PresenceState,\n SpaceMemberSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type SwarmInfo } from '@dxos/protocols/buf/dxos/devtools/swarm_pb';\nimport { type Epoch } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type DevtoolsHost, type LoggingService } from '@dxos/protocols/rpc';\nimport { RpcRouter } from '@dxos/rpc';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as PlatformInfo from '../../PlatformInfo.ts';\nimport { DXOS_VERSION } from '../../version.ts';\nimport { type DataSpace } from '../spaces/index.ts';\n\nconst DEFAULT_TIMEOUT = 1_000;\n\nexport type Diagnostics = {\n client: {\n config: ConfigProto;\n };\n services: {\n created: string;\n platform: Platform;\n config?: ConfigProto;\n client: {\n version: string;\n storage: {\n version: number;\n };\n };\n identity?: Identity;\n devices?: Device[];\n spaces?: SpaceStats[];\n networkStatus?: NetworkStatus;\n swarms?: SwarmInfo[];\n feeds?: Partial<DevtoolsHost.SubscribeToFeedsResponse.Feed>[];\n metrics?: LoggingService.Metrics;\n storage?: { file: string; count: number }[];\n };\n};\n\n// TODO(burdon): Normalize for ECHO/HALO.\nexport type SpaceStats = {\n key: PublicKey;\n properties?: {\n name: string;\n };\n db?: {\n objects: number;\n };\n metrics?: Space_Metrics & {\n startupTime?: number;\n };\n epochs?: { epoch: Epoch; id?: PublicKey }[];\n members?: SpaceMember[];\n pipeline?: Space_PipelineState;\n};\n\n/**\n * {@link createDiagnostics} over the services registered with a stack's {@link RpcRouter.RpcRouter},\n * bridged in-process for the duration of the collection.\n */\nexport const createDiagnosticsFromRouter = (\n router: RpcRouter.Service,\n stack: EffectContext.Context<\n IdentityContract.ManagerService | SpacesContract.ManagerService | SwarmNetworkManagerService\n >,\n config: Config,\n): Promise<Diagnostics['services']> =>\n EffectEx.runPromise(\n Effect.scoped(\n Effect.gen(function* () {\n const rpc = yield* makeClientServicesRpcFromRouter.pipe(Effect.provideService(RpcRouter.RpcRouter, router));\n return yield* Effect.promise(() =>\n createDiagnostics(makeServicesFromRpc(rpc, EffectContext.empty()), stack, config),\n );\n }),\n ),\n );\n\n/**\n * Create diagnostics to provide snapshot of current system state.\n */\nexport const createDiagnostics = async (\n clientServices: Partial<ClientServices>,\n stack: EffectContext.Context<\n IdentityContract.ManagerService | SpacesContract.ManagerService | SwarmNetworkManagerService\n >,\n config: Config,\n): Promise<Diagnostics['services']> => {\n const diagnostics: Diagnostics['services'] = {\n created: new Date().toISOString(),\n platform: PlatformInfo.getPlatform(),\n client: {\n version: DXOS_VERSION,\n storage: {\n version: STORAGE_VERSION,\n },\n },\n };\n\n await Promise.all([\n (async () => {\n // Trace metrics.\n // TODO(burdon): Move here from logging service?\n invariant(clientServices.LoggingService, 'SystemService is not available.');\n diagnostics.metrics = await getFirstStreamValue(clientServices.LoggingService.queryMetrics({}), {\n timeout: DEFAULT_TIMEOUT,\n }).catch(() => undefined);\n })(),\n (async () => {\n diagnostics.storage = await asyncTimeout(getStorageDiagnostics(), DEFAULT_TIMEOUT).catch(() => undefined);\n })(),\n (async () => {\n const identity = EffectContext.get(stack, IdentityContract.ManagerService).identity;\n if (identity) {\n // Identity.\n diagnostics.identity = buf.create(IdentitySchema, {\n did: identity.did,\n identityKey: fromPublicKey(identity.identityKey),\n spaceKey: fromPublicKey(identity.space.key),\n profile: identity.profileDocument,\n });\n\n // Devices.\n const { devices } =\n (await getFirstStreamValue(clientServices.DevicesService!.queryDevices(), {\n timeout: DEFAULT_TIMEOUT,\n }).catch(() => undefined)) ?? {};\n diagnostics.devices = devices;\n\n // TODO(dmaretskyi): Add metrics for halo space.\n\n // Spaces.\n const dataSpaceManager = EffectContext.get(stack, SpacesContract.ManagerService);\n diagnostics.spaces = await Promise.all(\n Array.from(dataSpaceManager.spaces.values()).map((space) => getSpaceStats(space)),\n );\n\n // Feeds.\n const { feeds = [] } =\n (await getFirstStreamValue(clientServices.DevtoolsHost!.subscribeToFeeds({}), {\n timeout: DEFAULT_TIMEOUT,\n }).catch(() => undefined)) ?? {};\n diagnostics.feeds = feeds.map(({ feedKey, bytes, length }) => ({ feedKey, bytes, length }));\n\n // Signal servers.\n\n const status = await getFirstStreamValue(clientServices.NetworkService!.queryStatus(), {\n timeout: DEFAULT_TIMEOUT,\n }).catch(() => undefined);\n diagnostics.networkStatus = status;\n\n // Networking.\n\n diagnostics.swarms = EffectContext.get(stack, SwarmNetworkManagerService).connectionLog?.swarms;\n }\n // Diagnostics are best-effort: a half-open space or a tag the stack has not built yet must\n // leave the other sections intact rather than failing the whole report.\n })().catch((err) => log.warn('failed to collect identity diagnostics', { err })),\n ]);\n\n diagnostics.config = config.values;\n\n return diagnostics;\n};\n\nconst getSpaceStats = async (space: DataSpace): Promise<SpaceStats> => {\n const stats: SpaceStats = {\n key: space.key,\n metrics: space.metrics,\n\n epochs: credentialsOfType<Epoch>('dxos.halo.credentials.Epoch')(space.inner.spaceState.credentials).map(\n ({ credential, assertion }) => ({ epoch: assertion, id: toPublicKey(credential.id) }),\n ),\n\n members: await Promise.all(\n Array.from(space.inner.spaceState.members.values()).map(async (member) =>\n buf.create(SpaceMemberSchema, {\n role: member.role,\n identity: buf.create(SpaceIdentitySchema, {\n did: await createDidFromIdentityKey(member.key),\n identityKey: fromPublicKey(member.key),\n profile: member.assertion.profile,\n }),\n presence:\n space.presence.getPeersByIdentityKey(member.key).length > 0\n ? SpaceMember_PresenceState.ONLINE\n : SpaceMember_PresenceState.OFFLINE,\n }),\n ),\n ),\n\n pipeline: buf.create(Space_PipelineStateSchema, {\n // TODO(burdon): Pick properties from credentials if needed.\n currentEpoch: space.automergeSpaceState.lastEpoch?.credential,\n appliedEpoch: space.automergeSpaceState.lastEpoch?.credential,\n\n controlFeeds: space.inner.controlPipeline.state.feeds.map((feed) => fromPublicKey(feed.key)),\n currentControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.timeframe),\n targetControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.targetTimeframe),\n totalControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.endTimeframe),\n }),\n };\n\n // TODO(burdon): Factor out.\n if (stats.metrics) {\n const open = toDate(stats.metrics.open);\n const ready = toDate(stats.metrics.ready);\n stats.metrics.startupTime = open && ready && ready.getTime() - open.getTime();\n }\n\n return stats;\n};\n\nconst getStorageDiagnostics = async () => {\n if (typeof navigator === 'undefined' || !navigator.storage) {\n return undefined;\n }\n const map = new Map();\n const dir = await navigator.storage.getDirectory();\n for await (const filename of (dir as any)?.keys()) {\n const idx = filename.indexOf('-', filename.indexOf('-') + 1);\n if (idx === -1) {\n continue;\n }\n\n map.set(filename.slice(0, idx), (map.get(filename.slice(0, idx)) ?? 0) + 1);\n }\n\n return Array.from(map.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([file, count]) => ({ file, count }));\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { decode as decodeCbor, encode as encodeCbor } from 'cbor-x';\n\nimport { Event, Mutex, scheduleMicroTask } from '@dxos/async';\nimport { Context, Resource } from '@dxos/context';\nimport { type EdgeConnection } from '@dxos/edge-client';\nimport { EdgeConnectionClosedError, EdgeIdentityChangedError } from '@dxos/edge-client';\nimport { type HypercoreWrapper } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey, type SpaceId } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { EdgeService } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport { EdgeStatus_ConnectionState } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport {\n type Message as RouterMessage,\n MessageSchema as RouterMessageSchema,\n} from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport type { FeedBlock, ProtocolMessage } from '@dxos/protocols/feed-replication';\nimport { ComplexMap, arrayToBuffer, bufferToArray, defaultMap, rangeFromTo } from '@dxos/util';\n\nexport type EdgeFeedReplicatorProps = {\n messenger: EdgeConnection;\n spaceId: SpaceId;\n};\n\nexport class EdgeFeedReplicator extends Resource {\n private readonly _messenger: EdgeConnection;\n\n @logInfo\n private readonly _spaceId: SpaceId;\n\n private readonly _feeds = new ComplexMap<PublicKey, HypercoreWrapper<any>>(PublicKey.hash);\n\n private _connectionCtx?: Context = undefined;\n private _connected = false;\n /**\n * Feed length at service.\n */\n private _remoteLength = new ComplexMap<PublicKey, number>(PublicKey.hash);\n\n /**\n * Protects against concurrent pushes so that remote length is updated consistently.\n */\n private _pushMutex = new ComplexMap<PublicKey, Mutex>(PublicKey.hash);\n\n /** Every block below this is held or already requested on this connection. */\n private _requestedUpTo = new ComplexMap<PublicKey, number>(PublicKey.hash);\n\n constructor({ messenger, spaceId }: EdgeFeedReplicatorProps) {\n super();\n this._messenger = messenger;\n this._spaceId = spaceId;\n }\n\n protected override async _open(): Promise<void> {\n log('open');\n // TODO: handle reconnects\n this._ctx.onDispose(\n this._messenger.onMessage((message: RouterMessage) => {\n if (!message.serviceId) {\n return;\n }\n const [service, ...rest] = message.serviceId.split(':');\n if (service !== EdgeService.FEED_REPLICATOR) {\n return;\n }\n\n const [spaceId] = rest;\n if (spaceId !== this._spaceId) {\n // Every space's replicator sees every peer's feed messages on the shared edge\n // connection, so each message is dropped by all but one replicator — O(spaces^2) lines\n // per sync round at anything above verbose.\n log.verbose('spaceID mismatch', { spaceId, _spaceId: this._spaceId });\n return;\n }\n\n const payload = decodeCbor(message.payload!.value) as ProtocolMessage;\n log('receive', { from: message.source, feedKey: payload.feedKey, type: payload.type });\n this._onMessage(payload);\n }),\n );\n\n this._ctx.onDispose(\n this._messenger.onReconnected(() => {\n scheduleMicroTask(this._ctx, () => this._handleReconnect());\n }),\n );\n }\n\n private async _handleReconnect(): Promise<void> {\n await this._resetConnection();\n if (this._messenger.status.state === EdgeStatus_ConnectionState.CONNECTED) {\n this._startReplication();\n }\n }\n\n protected override async _close(): Promise<void> {\n log('close');\n await this._resetConnection();\n }\n\n private _startReplication(): void {\n this._connected = true;\n const connectionCtx = this._createConnectionContext();\n this._connectionCtx = connectionCtx;\n log('connection context created');\n scheduleMicroTask(connectionCtx, async () => {\n for (const feed of this._feeds.values()) {\n await this._replicateFeed(connectionCtx, feed);\n }\n });\n }\n\n private async _resetConnection(): Promise<void> {\n log('resetConnection');\n this._connected = false;\n await this._connectionCtx?.dispose();\n this._connectionCtx = undefined;\n this._remoteLength.clear();\n this._requestedUpTo.clear();\n }\n\n async addHypercore(feed: HypercoreWrapper<any>): Promise<void> {\n log('addHypercore', { key: feed.key, connected: this._connected, hasConnectionCtx: !!this._connectionCtx });\n this._feeds.set(feed.key, feed);\n\n if (this._connected && this._connectionCtx) {\n await this._replicateFeed(this._connectionCtx, feed);\n }\n }\n\n private _getPushMutex(key: PublicKey): Mutex {\n return defaultMap(this._pushMutex, key, () => new Mutex());\n }\n\n private async _replicateFeed(ctx: Context, feed: HypercoreWrapper<any>): Promise<void> {\n log('replicateFeed', { key: feed.key });\n await this._sendMessage(ctx, {\n type: 'get-metadata',\n feedKey: feed.key.toHex(),\n });\n\n Event.wrap(feed.core as any, 'append').on(ctx, async () => {\n await this._pushBlocksIfNeeded(feed);\n });\n }\n\n private async _sendMessage(ctx: Context, message: ProtocolMessage): Promise<void> {\n if (!this._connectionCtx) {\n log('message dropped because connection was disposed');\n return;\n }\n\n if (message.type === 'data') {\n log('sending blocks', {\n feedKey: message.feedKey,\n blocks: message.blocks.map((b) => b.index),\n });\n }\n\n invariant(message.feedKey);\n const payloadValue = bufferToArray(encodeCbor(message));\n\n log('send', { type: message.type });\n await this._messenger.send(\n ctx,\n buf.create(RouterMessageSchema, {\n source: {\n identityDid: this._messenger.identityDid,\n peerKey: this._messenger.peerKey,\n },\n serviceId: `${EdgeService.FEED_REPLICATOR}:${this._spaceId}`,\n payload: { value: payloadValue },\n }),\n );\n }\n\n private _onMessage(message: ProtocolMessage): void {\n if (!this._connectionCtx) {\n log.warn('received message after connection context was disposed');\n return;\n }\n scheduleMicroTask(this._connectionCtx, async () => {\n switch (message.type) {\n case 'metadata': {\n const feedKey = PublicKey.fromHex(message.feedKey);\n const feed = this._feeds.get(feedKey);\n if (!feed) {\n log.warn('Feed not found', { feedKey });\n return;\n }\n\n using _guard = await this._getPushMutex(feed.key).acquire();\n\n // A reply computed before EDGE's latest push reports less than EDGE holds.\n const remoteLength = Math.max(this._remoteLength.get(feedKey) ?? 0, message.length);\n this._remoteLength.set(feedKey, remoteLength);\n\n // A sparse push moves `feed.length` past a gap, so compare block by block.\n const requestedUpTo = this._requestedUpTo.get(feedKey) ?? 0;\n const firstMissing = findFirstMissing(feed, requestedUpTo, message.length);\n this._requestedUpTo.set(feedKey, Math.max(requestedUpTo, firstMissing));\n const logMeta = { localLength: feed.length, remoteLength, firstMissing, feedKey };\n if (firstMissing < message.length) {\n log('requesting missing blocks', logMeta);\n this._requestedUpTo.set(feedKey, message.length);\n await this._sendMessage(this._connectionCtx!, {\n type: 'request',\n feedKey: feedKey.toHex(),\n range: { from: firstMissing, to: message.length },\n });\n } else if (remoteLength < feed.length && feed.has(remoteLength, feed.length)) {\n log('pushing blocks to remote', logMeta);\n\n await this._pushBlocks(this._connectionCtx!, feed, remoteLength, feed.length);\n }\n\n break;\n }\n\n case 'data': {\n log('received data', { feed: message.feedKey, blocks: message.blocks.map((b) => b.index) });\n\n const feedKey = PublicKey.fromHex(message.feedKey);\n const feed = this._feeds.get(feedKey);\n if (!feed) {\n log.warn('Feed not found', { feedKey });\n return;\n }\n\n const blocksEnd = message.blocks.reduce((end, block) => Math.max(end, block.index + 1), 0);\n // Raised before integrating, whose `append` would otherwise push these blocks back.\n this._remoteLength.set(feedKey, Math.max(this._remoteLength.get(feedKey) ?? 0, blocksEnd));\n await this._integrateBlocks(feed, message.blocks);\n await this._requestGapBelow(feed, blocksEnd);\n break;\n }\n\n default: {\n log.warn('Unknown message', { ...message });\n }\n }\n });\n }\n\n private async _pushBlocks(ctx: Context, feed: HypercoreWrapper<any>, from: number, to: number): Promise<void> {\n log('pushing blocks', { feed: feed.key.toHex(), from, to });\n\n const blocks: FeedBlock[] = await Promise.all(\n rangeFromTo(from, to).map(async (index) => {\n const data = await feed.get(index, { valueEncoding: 'binary' });\n invariant(data instanceof Uint8Array);\n const proof = await feed.proof(index);\n\n return {\n index,\n data,\n nodes: proof.nodes,\n signature: proof.signature,\n } satisfies FeedBlock;\n }),\n );\n\n await this._sendMessage(ctx, {\n type: 'data',\n feedKey: feed.key.toHex(),\n blocks,\n });\n // A push received during the send may have raised it past `to`.\n this._remoteLength.set(feed.key, Math.max(this._remoteLength.get(feed.key) ?? 0, to));\n }\n\n private async _integrateBlocks(feed: HypercoreWrapper<any>, blocks: FeedBlock[]): Promise<void> {\n log('integrating blocks', { feed: feed.key.toHex(), blocks: blocks.length });\n\n for (const block of blocks) {\n if (feed.has(block.index)) {\n continue;\n }\n const blockBuffer = bufferizeBlock(block);\n\n await feed.putBuffer(\n block.index,\n blockBuffer.data,\n { nodes: blockBuffer.nodes, signature: blockBuffer.signature },\n null,\n );\n }\n }\n\n /** Requests the blocks missing below `to`; a push carries only the newest blocks. */\n private async _requestGapBelow(feed: HypercoreWrapper<any>, to: number): Promise<void> {\n if (!this._connectionCtx) {\n return;\n }\n const requestedUpTo = this._requestedUpTo.get(feed.key) ?? 0;\n const from = findFirstMissing(feed, requestedUpTo, to);\n this._requestedUpTo.set(feed.key, Math.max(requestedUpTo, from));\n if (from < to) {\n log('requesting blocks missing below a pushed block', { feedKey: feed.key, from, to });\n this._requestedUpTo.set(feed.key, to);\n await this._sendMessage(this._connectionCtx, { type: 'request', feedKey: feed.key.toHex(), range: { from, to } });\n }\n }\n\n private async _pushBlocksIfNeeded(feed: HypercoreWrapper<any>): Promise<void> {\n using _ = await this._getPushMutex(feed.key).acquire();\n\n if (!this._remoteLength.has(feed.key)) {\n log('blocks not pushed because remote length is unknown');\n return;\n }\n\n const remoteLength = this._remoteLength.get(feed.key)!;\n // A sparse put also emits `append`, and `feed.get` on a hole never resolves.\n if (remoteLength < feed.length && feed.has(remoteLength, feed.length)) {\n await this._pushBlocks(this._connectionCtx!, feed, remoteLength, feed.length);\n }\n }\n\n private _createConnectionContext(): Context {\n const connectionCtx = new Context({\n parent: this._ctx,\n onError: async (err: any) => {\n if (connectionCtx !== this._connectionCtx) {\n return;\n }\n if (err instanceof EdgeIdentityChangedError || err instanceof EdgeConnectionClosedError) {\n log('resetting on reconnect');\n await this._resetConnection();\n } else {\n this._ctx.raise(err);\n }\n },\n });\n return connectionCtx;\n }\n}\n\n/** Index of the first block in `[from, to)` the feed does not hold, or `to` when it holds them all. */\nconst findFirstMissing = (feed: HypercoreWrapper<any>, from: number, to: number): number => {\n for (let index = from; index < to; index++) {\n if (!feed.has(index)) {\n return index;\n }\n }\n return to;\n};\n\n// hypercore requires buffers\nconst bufferizeBlock = (block: FeedBlock) => ({\n index: block.index,\n data: arrayToBuffer(block.data),\n nodes: block.nodes.map((node) => ({\n index: node.index,\n hash: arrayToBuffer(node.hash),\n size: node.size,\n })),\n signature: arrayToBuffer(block.signature),\n});\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { Event } from '@dxos/async';\nimport { AUTH_TIMEOUT, LOAD_CONTROL_FEEDS_TIMEOUT } from '@dxos/client-protocol';\nimport { type Context as DxosContext } from '@dxos/context';\nimport {\n type CredentialSigner,\n DeviceStateMachine,\n type InboxEnvelopeSigner,\n ProfileStateMachine,\n createCredentialSignerWithChain,\n createCredentialSignerWithKey,\n credentialPayload,\n} from '@dxos/credentials';\nimport { type Signer } from '@dxos/crypto';\nimport { type EdgeConnection } from '@dxos/edge-client';\nimport { type HypercoreWrapper, writeMessages } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type IdentityDid, PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport {\n AdmittedFeed_Designation,\n AdmittedFeedSchema,\n AuthorizedDeviceSchema,\n type Credential,\n type DeviceProfileDocument,\n type ProfileDocument,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type DeviceAdmissionRequest } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type Presence } from '@dxos/teleport-extension-gossip';\nimport { trace } from '@dxos/tracing';\nimport { type ComplexMap, ComplexSet } from '@dxos/util';\n\nimport * as Auth from './Auth.ts';\nimport { type Space } from './internal/space/index.ts';\nimport { EdgeFeedReplicator } from './Replication.ts';\n\nexport type IdentityProps = {\n did: IdentityDid;\n identityKey: PublicKey;\n deviceKey: PublicKey;\n signer: Signer;\n space: Space;\n presence?: Presence;\n\n edgeConnection?: EdgeConnection;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n};\n\n/**\n * Agent identity manager, which includes the agent's Halo space.\n */\nexport class Identity {\n public readonly space: Space;\n private readonly _signer: Signer;\n private readonly _presence?: Presence;\n private readonly _deviceStateMachine: DeviceStateMachine;\n private readonly _profileStateMachine: ProfileStateMachine;\n private readonly _edgeFeedReplicator?: EdgeFeedReplicator = undefined;\n private _haloSpaceRootUrl?: string = undefined;\n\n public readonly authVerifier: Auth.TrustedKeySetAuthVerifier;\n\n public readonly did: IdentityDid;\n public readonly identityKey: PublicKey;\n public readonly deviceKey: PublicKey;\n\n public readonly stateUpdate = new Event();\n\n constructor(params: IdentityProps) {\n this.space = params.space;\n this._signer = params.signer;\n this._presence = params.presence;\n\n this.did = params.did;\n this.identityKey = params.identityKey;\n this.deviceKey = params.deviceKey;\n\n log.trace('dxos.halo.device', { deviceKey: params.deviceKey });\n\n this._deviceStateMachine = new DeviceStateMachine({\n identityKey: this.identityKey,\n deviceKey: this.deviceKey,\n onUpdate: () => this.stateUpdate.emit(),\n });\n this._profileStateMachine = new ProfileStateMachine({\n identityKey: this.identityKey,\n onUpdate: () => this.stateUpdate.emit(),\n });\n\n this.authVerifier = new Auth.TrustedKeySetAuthVerifier({\n trustedKeysProvider: () => new ComplexSet(PublicKey.hash, this.authorizedDeviceKeys.keys()),\n update: this.stateUpdate,\n authTimeout: AUTH_TIMEOUT,\n });\n\n if (params.edgeConnection && params.edgeFeatures?.feedReplicator) {\n this._edgeFeedReplicator = new EdgeFeedReplicator({ messenger: params.edgeConnection, spaceId: this.space.id });\n }\n }\n\n // TODO(burdon): Expose state object?\n get authorizedDeviceKeys(): ComplexMap<PublicKey, DeviceProfileDocument> {\n return this._deviceStateMachine.authorizedDeviceKeys;\n }\n\n @trace.span({ op: 'lifecycle' })\n async open(ctx: DxosContext): Promise<void> {\n await this._presence?.open();\n await this.space.spaceState.addCredentialProcessor(this._deviceStateMachine);\n await this.space.spaceState.addCredentialProcessor(this._profileStateMachine);\n if (this._edgeFeedReplicator) {\n this.space.protocol.feedAdded.append(this._onFeedAdded);\n }\n await this.space.open(ctx);\n }\n\n public async joinNetwork(ctx: DxosContext): Promise<void> {\n await this.space.startProtocol(ctx);\n await this._edgeFeedReplicator?.open();\n }\n\n @trace.span({ op: 'lifecycle' })\n async close(ctx: DxosContext): Promise<void> {\n await this._presence?.close();\n await this.authVerifier.close();\n await this.space.spaceState.removeCredentialProcessor(this._profileStateMachine);\n await this.space.spaceState.removeCredentialProcessor(this._deviceStateMachine);\n\n if (this._edgeFeedReplicator) {\n this.space.protocol.feedAdded.remove(this._onFeedAdded);\n }\n\n await this._edgeFeedReplicator?.close();\n\n await this.space.close(ctx);\n }\n\n async ready(): Promise<void> {\n await this._deviceStateMachine.deviceChainReady.wait();\n\n await this.controlPipeline.state.waitUntilReachedTargetTimeframe({ timeout: LOAD_CONTROL_FEEDS_TIMEOUT });\n }\n\n get profileDocument(): ProfileDocument | undefined {\n return this._profileStateMachine.profile;\n }\n\n /**\n * @test-only\n */\n get controlPipeline() {\n return this.space.controlPipeline;\n }\n\n get haloSpaceId() {\n return this.space.id;\n }\n\n /**\n * Automerge URL of the halo space root, once anchored. Handed to a joining device so it replicates\n * the credential chain as a document; undefined while the space is still feed-only.\n */\n get haloSpaceRootUrl(): string | undefined {\n return this._haloSpaceRootUrl;\n }\n\n setHaloSpaceRootUrl(url: string): void {\n this._haloSpaceRootUrl = url;\n }\n\n get haloSpaceKey() {\n return this.space.key;\n }\n\n get haloGenesisFeedKey() {\n return this.space.genesisFeedKey;\n }\n\n get deviceCredentialChain() {\n return this._deviceStateMachine.deviceCredentialChain;\n }\n\n get presence() {\n return this._presence;\n }\n\n get signer() {\n return this._signer;\n }\n\n /**\n * Issues credentials as identity.\n * Requires identity to be ready.\n */\n getIdentityCredentialSigner(): CredentialSigner {\n invariant(this._deviceStateMachine.deviceCredentialChain, 'Device credential chain is not ready.');\n return createCredentialSignerWithChain(\n this._signer,\n this._deviceStateMachine.deviceCredentialChain,\n this.deviceKey,\n );\n }\n\n /**\n * Signs inbox envelopes as identity, with the device key and its delegation chain.\n */\n getInboxEnvelopeSigner(): InboxEnvelopeSigner {\n invariant(this._deviceStateMachine.deviceCredentialChain, 'Device credential chain is not ready.');\n return {\n identityKey: this.identityKey,\n signingKey: this.deviceKey,\n chain: this._deviceStateMachine.deviceCredentialChain,\n signer: this._signer,\n };\n }\n\n /**\n * Issues credentials as device.\n */\n getDeviceCredentialSigner(): CredentialSigner {\n return createCredentialSignerWithKey(this._signer, this.deviceKey);\n }\n\n async admitDevice(request: DeviceAdmissionRequest): Promise<Credential> {\n const deviceKey = requirePublicKey(request.deviceKey);\n const controlFeedKey = requirePublicKey(request.controlFeedKey);\n const dataFeedKey = requirePublicKey(request.dataFeedKey);\n log('Admitting device:', {\n identityKey: this.identityKey,\n hostDevice: this.deviceKey,\n deviceKey,\n controlFeedKey,\n dataFeedKey,\n });\n const signer = this.getIdentityCredentialSigner();\n const deviceCredential = await signer.createCredential({\n subject: deviceKey,\n assertion: create(AuthorizedDeviceSchema, {\n identityKey: fromPublicKey(this.identityKey),\n deviceKey: fromPublicKey(deviceKey),\n }),\n });\n await writeMessages(\n this.controlPipeline.writer,\n [\n deviceCredential,\n await signer.createCredential({\n subject: controlFeedKey,\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(this.haloSpaceKey),\n deviceKey: fromPublicKey(deviceKey),\n identityKey: fromPublicKey(this.identityKey),\n designation: AdmittedFeed_Designation.CONTROL,\n }),\n }),\n await signer.createCredential({\n subject: dataFeedKey,\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(this.haloSpaceKey),\n deviceKey: fromPublicKey(deviceKey),\n identityKey: fromPublicKey(this.identityKey),\n designation: AdmittedFeed_Designation.DATA,\n }),\n }),\n ].map(credentialPayload),\n );\n\n return deviceCredential;\n }\n\n private _onFeedAdded = async (feed: HypercoreWrapper<any>) => {\n await this._edgeFeedReplicator!.addHypercore(feed);\n };\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { SubscriptionList, UpdateScheduler, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type MemberInfo, createDidFromIdentityKey } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { PublicKey } from '@dxos/keys';\nimport { buf, fromPublicKey } from '@dxos/protocols/buf';\nimport {\n type Contact,\n type ContactBook,\n ContactBookSchema,\n ContactSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { ContactsService } from '@dxos/protocols/rpc';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Readiness from '../../Readiness.ts';\nimport { type SpaceManager, SpaceManagerService } from '../space/index.ts';\n\nexport class ContactsServiceImpl implements ContactsService.Handlers {\n 'constructor'(\n private readonly _identityManager: IdentityContract.Manager,\n private readonly _spaceManager: SpaceManager,\n private readonly _dataSpaceManagerProvider: () => Promise<SpacesContract.Manager>,\n ) {}\n\n ['ContactsService.getContacts'](): Effect.Effect<ContactBook, Error> {\n return Effect.promise(() => this.#getContacts());\n }\n\n ['ContactsService.queryContacts'](): EffectStream.Stream<ContactBook, Error> {\n const subscribedSpaceKeySet = new ComplexSet(PublicKey.hash);\n return EffectEx.streamFromEmitter<ContactBook, Error>((emit) => {\n const ctx = Context.default();\n const pushUpdateTask = new UpdateScheduler(\n ctx,\n async () => {\n void emit.single(await this.#getContacts());\n },\n { maxFrequency: 2 },\n );\n scheduleTask(ctx, async () => {\n const subscriptions = new SubscriptionList();\n ctx.onDispose(() => subscriptions.clear());\n const subscribeToSpaceAndUpdate = () => {\n const oldSetSize = subscribedSpaceKeySet.size;\n for (const space of this._spaceManager.spaces.values()) {\n if (!subscribedSpaceKeySet.has(space.key)) {\n subscriptions.add(space.stateUpdate.on(ctx, () => pushUpdateTask.trigger()));\n subscribedSpaceKeySet.add(space.key);\n }\n }\n if (oldSetSize !== subscribedSpaceKeySet.size) {\n pushUpdateTask.trigger();\n }\n };\n const unsubscribe = (await this._dataSpaceManagerProvider()).updated.on(ctx, subscribeToSpaceAndUpdate);\n ctx.onDispose(unsubscribe);\n subscribeToSpaceAndUpdate();\n });\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n async #getContacts(): Promise<ContactBook> {\n const identity = this._identityManager.identity;\n if (identity == null) {\n return buf.create(ContactBookSchema, { contacts: [] });\n }\n const contacts = [...this._spaceManager.spaces.values()]\n .flatMap((s) => [...s.spaceState.members.values()].map((m) => [s.key, m]))\n .reduce((acc, v) => {\n const [spaceKey, memberInfo] = v as [PublicKey, MemberInfo];\n if (memberInfo.key.equals(identity.identityKey)) {\n return acc;\n }\n const existing = acc.get(memberInfo.key);\n if (existing != null) {\n existing.profile ??= memberInfo.profile;\n existing.commonSpaces.push(fromPublicKey(spaceKey));\n } else {\n acc.set(\n memberInfo.key,\n buf.create(ContactSchema, {\n identityKey: fromPublicKey(memberInfo.key),\n profile: memberInfo.profile,\n commonSpaces: [fromPublicKey(spaceKey)],\n }),\n );\n }\n return acc;\n }, new ComplexMap<PublicKey, Contact>(PublicKey.hash));\n // Derived here (and cached by key) so clients can show the DID without hashing each key themselves.\n await Promise.all(\n [...contacts.entries()].map(async ([identityKey, contact]) => {\n contact.did = await createDidFromIdentityKey(identityKey);\n }),\n );\n return buf.create(ContactBookSchema, { contacts: [...contacts.values()] });\n }\n}\n\nexport const ContactsServiceLayer = Layer.effect(\n ContactsService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const spaceManager = yield* SpaceManagerService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const readiness = yield* Readiness.StackReadinessService;\n return new ContactsServiceImpl(identityManager, spaceManager, () =>\n readiness.initialized.wait().then(() => dataSpaceManager),\n );\n }),\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create, fromBinary } from '@bufbuild/protobuf';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { synchronized } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport {\n credentialPayload,\n generateSeedPhrase,\n getCredentialAssertion,\n keyPairFromSeedPhrase,\n} from '@dxos/credentials';\nimport { sign } from '@dxos/crypto';\nimport { type EdgeHttpClient, EdgeHttpClientService } from '@dxos/edge-client';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n EdgeAuthChallengeError,\n EdgeCallFailedError,\n type RecoverIdentityRequest as EdgeRecoverIdentityRequest,\n InvalidRecoveryTokenError,\n type RecoverIdentityResponseBody,\n} from '@dxos/protocols';\nimport { fromDate, fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport { type RecoverIdentityRequest_ExternalSignature } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport {\n type Credential,\n CredentialSchema,\n type IdentityRecovery,\n IdentityRecovery_Kind,\n IdentityRecoveryRevokedSchema,\n IdentityRecoverySchema,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type IdentityService } from '@dxos/protocols/rpc';\nimport { Timeframe } from '@dxos/timeframe';\nimport { ComplexSet } from '@dxos/util';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type JoinIdentityProps } from './identity-manager.ts';\n\n/**\n * Effect service tag for {@link EdgeIdentityRecoveryManager}.\n */\nexport class EdgeIdentityRecoveryManagerService extends EffectContext.Service<\n EdgeIdentityRecoveryManagerService,\n EdgeIdentityRecoveryManager\n>()('@dxos/client-services/EdgeIdentityRecoveryManager') {}\n\nexport type AcceptRecoveredIdentity = (params: JoinIdentityProps) => Promise<Identity>;\n\nexport class EdgeIdentityRecoveryManager {\n private _acceptRecoveredIdentity?: AcceptRecoveredIdentity;\n\n constructor(\n private readonly _keyring: KeyringApi,\n private readonly _edgeClient: EdgeHttpClient | undefined,\n private readonly _identityProvider: () => Identity | undefined,\n ) {}\n\n /**\n * Wires identity acceptance after the composing stack is fully constructed.\n */\n setAcceptRecoveredIdentity(acceptRecoveredIdentity: AcceptRecoveredIdentity): void {\n this._acceptRecoveredIdentity = acceptRecoveredIdentity;\n }\n\n public async createRecoveryCredential({\n data,\n }: IdentityService.CreateRecoveryCredentialRequest): Promise<{ recoveryCode: string | undefined }> {\n const identity = this._identityProvider();\n invariant(identity);\n\n let recoveryKey: PublicKey;\n let lookupKey: PublicKey;\n let algorithm: string;\n let recoveryCode: string | undefined;\n let kind: IdentityRecovery_Kind;\n let label: string | undefined;\n if (data) {\n recoveryKey = data.recoveryKey;\n lookupKey = data.lookupKey;\n algorithm = data.algorithm;\n kind = data.kind ?? IdentityRecovery_Kind.UNKNOWN;\n label = data.label;\n } else {\n // The seed phrase is generated here rather than by the caller, so the label is too.\n recoveryCode = await generateSeedPhrase();\n const keypair = await keyPairFromSeedPhrase(recoveryCode);\n recoveryKey = PublicKey.from(keypair.publicKey);\n lookupKey = PublicKey.from(keypair.publicKey);\n algorithm = 'ED25519';\n kind = IdentityRecovery_Kind.RECOVERY_CODE;\n label = 'Recovery code';\n }\n\n const identityKey = identity.identityKey;\n const credential = await identity.getIdentityCredentialSigner().createCredential({\n subject: identityKey,\n assertion: create(IdentityRecoverySchema, {\n recoveryKey: fromPublicKey(recoveryKey),\n identityKey: fromPublicKey(identityKey),\n algorithm,\n lookupKey: fromPublicKey(lookupKey),\n label,\n kind,\n }),\n });\n\n const receipt = await identity.controlPipeline.writer.write(credentialPayload(credential));\n await identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));\n\n return { recoveryCode };\n }\n\n /**\n * Revoke a recovery credential by writing an `IdentityRecoveryRevoked` assertion to the identity's\n * control feed, mirroring how `SpaceDeleted` tombstones a space: the feed is append-only, so the\n * original credential stays and this marks it spent. The assertion replicates to the user's other\n * devices and to their agent, which is what drives the server-side refusal.\n *\n * Refuses the last un-revoked credential. Doing so would leave the holder unable to recover their\n * identity with no self-service way back — the replacement has to be added first.\n *\n * `@synchronized` so two revocations on this device cannot both observe two active credentials and\n * each cancel a different one. It cannot serialize across devices: the control feed is append-only\n * with no consensus, so two devices revoking at once can still drive the count to zero. The agents\n * service is the authority there — it re-checks the active count before flipping a row to REVOKED.\n */\n @synchronized\n public async revokeRecoveryCredential({ lookupKey }: { lookupKey: PublicKey }): Promise<void> {\n const identity = this._identityProvider();\n invariant(identity);\n\n const active = this.listActiveRecoveryCredentials();\n if (!active.some(({ assertion }) => requirePublicKey(assertion.lookupKey).equals(lookupKey))) {\n throw new Error('Recovery credential is not registered, or is already revoked.');\n }\n if (active.length <= 1) {\n throw new Error('Cannot revoke the only remaining recovery credential; add another one first.');\n }\n\n const identityKey = identity.identityKey;\n const credential = await identity.getIdentityCredentialSigner().createCredential({\n subject: identityKey,\n assertion: create(IdentityRecoveryRevokedSchema, {\n identityKey: fromPublicKey(identityKey),\n lookupKey: fromPublicKey(lookupKey),\n revokedAt: fromDate(new Date()),\n }),\n });\n\n const receipt = await identity.controlPipeline.writer.write(credentialPayload(credential));\n await identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));\n }\n\n /**\n * Recovery credentials in the identity's HALO that no `IdentityRecoveryRevoked` assertion cancels.\n *\n * Credentials written before `lookupKey` existed cannot be matched by a revocation, so they are\n * always active — and still count towards the last-credential check, since they remain usable.\n */\n public listActiveRecoveryCredentials(): { credential: Credential; assertion: IdentityRecovery }[] {\n const identity = this._identityProvider();\n invariant(identity);\n\n const revoked = new ComplexSet<PublicKey>(PublicKey.hash);\n const registered: { credential: Credential; assertion: IdentityRecovery }[] = [];\n for (const credential of identity.space.spaceState.credentials) {\n const assertion = getCredentialAssertion(credential);\n switch (assertion.$typeName) {\n case 'dxos.halo.credentials.IdentityRecovery':\n registered.push({ credential, assertion });\n break;\n case 'dxos.halo.credentials.IdentityRecoveryRevoked':\n revoked.add(requirePublicKey(assertion.lookupKey));\n break;\n }\n }\n\n return registered.filter(\n ({ assertion }) => !(assertion.lookupKey && revoked.has(requirePublicKey(assertion.lookupKey))),\n );\n }\n\n public async requestRecoveryChallenge(ctx: Context) {\n invariant(this._edgeClient, 'Not connected to EDGE.');\n\n const deviceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const request: EdgeRecoverIdentityRequest = {\n deviceKey: deviceKey.toHex(),\n controlFeedKey: controlFeedKey.toHex(),\n };\n\n try {\n await this._edgeClient.recoverIdentity(ctx, request);\n throw new Error('No challenge received.');\n } catch (error: any) {\n if (!(error instanceof EdgeAuthChallengeError)) {\n throw error;\n }\n return {\n deviceKey,\n controlFeedKey,\n challenge: error.challenge,\n };\n }\n }\n\n public async recoverIdentityWithExternalSignature(\n ctx: Context,\n {\n lookupKey,\n deviceKey,\n controlFeedKey,\n signature,\n clientDataJson,\n authenticatorData,\n }: RecoverIdentityRequest_ExternalSignature,\n ): Promise<void> {\n invariant(this._edgeClient, 'Not connected to EDGE.');\n\n const deviceKeyValue = requirePublicKey(deviceKey);\n const controlFeedKeyValue = requirePublicKey(controlFeedKey);\n const request: EdgeRecoverIdentityRequest = {\n lookupKey: requirePublicKey(lookupKey).toHex(),\n deviceKey: deviceKeyValue.toHex(),\n controlFeedKey: controlFeedKeyValue.toHex(),\n signature:\n clientDataJson && authenticatorData\n ? {\n signature: Buffer.from(signature).toString('base64'),\n clientDataJson: Buffer.from(clientDataJson).toString('base64'),\n authenticatorData: Buffer.from(authenticatorData).toString('base64'),\n }\n : Buffer.from(signature).toString('base64'),\n };\n\n const response = await this._edgeClient.recoverIdentity(ctx, request);\n\n await this.#acceptRecoveredIdentity({\n authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),\n haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),\n haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),\n identityKey: PublicKey.fromHex(response.identityKey),\n deviceKey: deviceKeyValue,\n controlFeedKey: controlFeedKeyValue,\n dataFeedKey: await this._keyring.createKey(),\n haloSpaceRootUrl: response.haloSpaceRootUrl,\n });\n }\n\n /**\n * Recover an identity using an opaque one-time token. Accepts either an email magic-link\n * `token` (validated by hub-service) or an OAuth `recoveryProof` (redeemed by kms-service).\n * The two fields are routed to different backends by db-service and must not be conflated.\n */\n public async recoverIdentityWithToken(\n ctx: Context,\n fields: { token: string } | { recoveryProof: string },\n ): Promise<void> {\n invariant(this._edgeClient, 'Not connected to EDGE.');\n\n const deviceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const request: EdgeRecoverIdentityRequest = {\n deviceKey: deviceKey.toHex(),\n controlFeedKey: controlFeedKey.toHex(),\n ...fields,\n };\n\n const response = await this._edgeClient.recoverIdentity(ctx, request).catch((error) => {\n // Rethrow the registered class so the token-rejection identity survives the services RPC boundary.\n if (error instanceof EdgeCallFailedError && InvalidRecoveryTokenError.is(error.cause)) {\n throw new InvalidRecoveryTokenError({ cause: error });\n }\n throw error;\n });\n\n await this.#acceptRecoveredIdentity({\n authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),\n haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),\n haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),\n identityKey: PublicKey.fromHex(response.identityKey),\n deviceKey,\n controlFeedKey,\n dataFeedKey: await this._keyring.createKey(),\n });\n }\n\n public async recoverIdentity(ctx: Context, { recoveryCode }: { recoveryCode: string }): Promise<void> {\n invariant(this._edgeClient, 'Not connected to EDGE.');\n\n const recoveryKeypair = await keyPairFromSeedPhrase(recoveryCode);\n const recoveryKey = PublicKey.from(recoveryKeypair.publicKey);\n const deviceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const request: EdgeRecoverIdentityRequest = {\n lookupKey: recoveryKey.toHex(),\n deviceKey: deviceKey.toHex(),\n controlFeedKey: controlFeedKey.toHex(),\n };\n\n let response: RecoverIdentityResponseBody;\n try {\n response = await this._edgeClient.recoverIdentity(ctx, request);\n } catch (error: any) {\n if (!(error instanceof EdgeAuthChallengeError)) {\n throw error;\n }\n const signature = sign(Buffer.from(error.challenge, 'base64'), recoveryKeypair.secretKey);\n response = await this._edgeClient.recoverIdentity(ctx, {\n ...request,\n signature: Buffer.from(signature).toString('base64'),\n });\n }\n\n log.info('recovering identity', response);\n\n await this.#acceptRecoveredIdentity({\n authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),\n haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),\n haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),\n identityKey: PublicKey.fromHex(response.identityKey),\n deviceKey,\n controlFeedKey,\n dataFeedKey: await this._keyring.createKey(),\n });\n }\n\n #acceptRecoveredIdentity(params: JoinIdentityProps): Promise<Identity> {\n invariant(this._acceptRecoveredIdentity, 'acceptRecoveredIdentity not set');\n return this._acceptRecoveredIdentity(params);\n }\n}\n\nconst decodeCredential = (credentialBase64: string): Credential =>\n fromBinary(CredentialSchema, Buffer.from(credentialBase64, 'base64'));\n\n/**\n * Effect Layer constructing a dormant {@link EdgeIdentityRecoveryManager}.\n */\nexport const EdgeIdentityRecoveryManagerLayer = (): Layer.Layer<\n EdgeIdentityRecoveryManagerService,\n never,\n KeyringApiService | IdentityContract.ManagerService\n> =>\n Layer.effect(\n EdgeIdentityRecoveryManagerService,\n Effect.gen(function* () {\n const keyring = yield* KeyringApiService;\n const edgeClient = yield* Effect.serviceOption(EdgeHttpClientService);\n const identityManager = yield* IdentityContract.ManagerService;\n return new EdgeIdentityRecoveryManager(\n keyring,\n Option.getOrUndefined(edgeClient),\n () => identityManager.identity,\n );\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { type Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { log } from '@dxos/log';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type CreateIdentityOptions, type JoinIdentityProps } from './identity-manager.ts';\nimport { EdgeIdentityRecoveryManagerService } from './identity-recovery-manager.ts';\n\n/**\n * Brings a new identity into the running stack: binds it to the network, joins, and announces it so\n * the identity-bound services open. The persisted identity on boot goes through the same events\n * from the host's open sequence.\n */\nexport interface IdentityLifecycle {\n /** Creates a fresh identity and resolves once its identity-bound services are open. */\n createIdentity(params?: CreateIdentityOptions, ctx?: Context): Promise<Identity>;\n /** Adopts an identity admitted by another device and resolves once its services are open. */\n acceptIdentity(params: JoinIdentityProps): Promise<Identity>;\n}\n\nexport const IdentityLifecycleLayer: Layer.Layer<\n IdentityContract.LifecycleService,\n never,\n Hook.Controller | IdentityContract.ManagerService | EdgeIdentityRecoveryManagerService\n> = Layer.effect(\n IdentityContract.LifecycleService,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const recoveryManager = yield* EdgeIdentityRecoveryManagerService;\n const runtime = yield* RuntimeProvider.currentRuntime<Hook.Controller>();\n const ctx = yield* EffectEx.contextFromScope();\n\n const lifecycle = createIdentityLifecycle({ identityManager, ctx, runtime });\n recoveryManager.setAcceptRecoveredIdentity((params) => lifecycle.acceptIdentity(params));\n\n // The persisted identity joins once networking is up; a missing identity leaves the stack\n // dormant until one is created or accepted.\n yield* Hook.on(\n Events.NetworkReady,\n Effect.fn('IdentityLifecycle.onNetworkReady')(function* () {\n const identity = identityManager.identity;\n if (!identity) {\n log('no identity, skipping network join');\n return;\n }\n log('joining network...');\n yield* Effect.promise(() => identity.joinNetwork(ctx));\n yield* Hook.emit(Events.IdentityAvailable, { identity });\n }),\n );\n return lifecycle;\n }),\n);\n\nconst createIdentityLifecycle = ({\n identityManager,\n ctx: defaultCtx,\n runtime,\n}: {\n identityManager: IdentityContract.Manager;\n ctx: Context;\n runtime: RuntimeProvider.RuntimeProvider<Hook.Controller>;\n}): IdentityLifecycle => {\n const emit = RuntimeProvider.runPromise(runtime);\n\n return {\n createIdentity: async (params = {}, ctx = defaultCtx) => {\n const identity = await identityManager.createIdentity(params, ctx);\n await emit(Hook.emit(Events.IdentityBound, { identity }));\n await identity.joinNetwork(ctx);\n await emit(Hook.emit(Events.IdentityAvailable, { identity }));\n log('identity created', { identityKey: identity.identityKey });\n return identity;\n },\n\n acceptIdentity: async (params) => {\n const ctx = defaultCtx;\n const { identity, identityRecord } = await identityManager.prepareIdentity(params, ctx);\n try {\n await emit(Hook.emit(Events.IdentityBound, { identity, deviceCredential: params.authorizedDeviceCredential }));\n await identity.joinNetwork(ctx);\n } catch (err) {\n // Nothing owns the prepared identity until the manager accepts it.\n await identity.close(ctx).catch((closeErr) => log.catch(closeErr));\n throw err;\n }\n await identityManager.acceptIdentity(identity, identityRecord, params.deviceProfile);\n await emit(Hook.emit(Events.IdentityAvailable, { identity }));\n log('identity accepted', { identityKey: identity.identityKey });\n return identity;\n },\n };\n};\n","//\n// Copyright 2022 DXOS.org\n//\nimport { isValidAutomergeUrl } from '@automerge/automerge-repo';\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport platform from 'platform';\n\nimport { Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport {\n CredentialGenerator,\n createCredentialSignerWithKey,\n createDidFromIdentityKey,\n credentialPayload,\n} from '@dxos/credentials';\nimport { failUndefined } from '@dxos/debug';\nimport { type EchoHost } from '@dxos/echo-host';\nimport { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { type HypercoreStore, HypercoreStoreService } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { fromPublicKey, fromTimeframe, requirePublicKey, toTimeframe } from '@dxos/protocols/buf';\nimport {\n type Device,\n Device_PresenceState,\n DeviceKind,\n DeviceSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport {\n type IdentityRecord,\n IdentityRecordSchema,\n type SpaceMetadata,\n SpaceMetadataSchema,\n} from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport {\n AdmittedFeed_Designation,\n type Credential,\n type DeviceProfileDocument,\n DeviceProfileDocumentSchema,\n DeviceProfileSchema,\n DeviceType,\n IdentityProfileSchema,\n type ProfileDocument,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { Gossip, Presence } from '@dxos/teleport-extension-gossip';\nimport { Timeframe } from '@dxos/timeframe';\nimport { trace as Trace } from '@dxos/tracing';\nimport { deferFunction, isNode, isTauri } from '@dxos/util';\n\nimport * as Auth from '../../Auth.ts';\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport { openCredentialsDocument } from '../../CredentialsDocument.ts';\nimport * as Events from '../../Events.ts';\nimport { Identity } from '../../Identity.ts';\nimport { type IMetadataStore, IMetadataStoreService } from '../metadata/index.ts';\nimport { type SpaceManager, SpaceManagerService, type SwarmIdentity } from '../space/index.ts';\n\nconst DEVICE_PRESENCE_ANNOUNCE_INTERVAL = 10_000;\nconst DEVICE_PRESENCE_OFFLINE_TIMEOUT = 20_000;\n\ninterface ConstructSpaceProps {\n spaceRecord: SpaceMetadata;\n swarmIdentity: SwarmIdentity;\n identityKey: PublicKey;\n gossip: Gossip;\n}\n\nexport type JoinIdentityProps = {\n identityKey: PublicKey;\n deviceKey: PublicKey;\n haloSpaceKey: PublicKey;\n haloGenesisFeedKey: PublicKey;\n controlFeedKey: PublicKey;\n dataFeedKey: PublicKey;\n authorizedDeviceCredential: Credential;\n /**\n * Automerge URL of the host's halo space root, when it has one. The joining device adopts it rather\n * than minting a second root over the same space.\n */\n haloSpaceRootUrl?: string;\n\n /**\n * Latest known timeframe for the control pipeline.\n * We will try to catch up to this timeframe before starting the data pipeline.\n */\n controlTimeframe?: Timeframe;\n // Custom device profile, merged with defaults, to be applied once the identity is accepted.\n deviceProfile?: DeviceProfileDocument;\n};\n\nexport type CreateIdentityOptions = {\n profile?: ProfileDocument;\n // device profile for device creating the identity.\n deviceProfile?: DeviceProfileDocument;\n};\n\nexport type IdentityManagerProps = {\n metadataStore: IMetadataStore;\n keyring: KeyringApi;\n hypercoreStore: HypercoreStore<FeedMessage>;\n spaceManager: SpaceManager;\n edgeConnection?: EdgeConnection;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n devicePresenceAnnounceInterval?: number;\n devicePresenceOfflineTimeout?: number;\n /** See {@link DataSpaceManagerRuntimeProps.automergeCredentials}. Off by default. */\n automergeCredentials?: boolean;\n};\n\n/**\n * Resolves the active identity when it becomes available.\n */\nexport type IdentityProvider = () => Identity;\n\n/**\n * Builds an {@link IdentityProvider} from an {@link IdentityManager}.\n */\nexport const identityProviderFromManager =\n (identityManager: IdentityContract.Manager): IdentityContract.Provider =>\n () =>\n identityManager.identity ?? failUndefined();\n\n// TODO(dmaretskyi): Rename: represents the peer's state machine.\nexport class IdentityManager {\n readonly stateUpdate = new Event();\n\n private readonly _metadataStore: IMetadataStore;\n private readonly _keyring: KeyringApi;\n private readonly _hypercoreStore: HypercoreStore<FeedMessage>;\n private readonly _spaceManager: SpaceManager;\n /**\n * Set late by the service stack: `EchoHostLayer` already depends on this manager for its peer id,\n * so taking the host as a constructor dependency would make the layer graph circular. Anchoring is\n * driven by whichever of the two arrives last.\n */\n private _echoHost: EchoHost | undefined;\n /** Root the inviting device named, adopted once the identity is accepted. */\n private _pendingHaloSpaceRootUrl: string | undefined;\n private readonly _devicePresenceAnnounceInterval: number;\n private readonly _devicePresenceOfflineTimeout: number;\n private readonly _automergeCredentials: boolean;\n private readonly _edgeConnection: EdgeConnection | undefined;\n private readonly _edgeFeatures: Runtime_Client_EdgeFeatures | undefined;\n\n private _identity?: Identity;\n /**\n * Owns the HALO anchoring subscriptions, which outlive any single open() call. Replaced on\n * {@link deleteIdentity}, since a disposed context runs new `onDispose` callbacks immediately and\n * would tear down the next identity's subscriptions as they are registered.\n */\n private _ctx = new Context();\n\n // TODO(dmaretskyi): Perhaps this should take/generate the peerKey outside of an initialized identity.\n constructor(params: IdentityManagerProps) {\n this._metadataStore = params.metadataStore;\n this._keyring = params.keyring;\n this._hypercoreStore = params.hypercoreStore;\n this._spaceManager = params.spaceManager;\n this._edgeConnection = params.edgeConnection;\n this._edgeFeatures = params.edgeFeatures;\n this._devicePresenceAnnounceInterval = params.devicePresenceAnnounceInterval ?? DEVICE_PRESENCE_ANNOUNCE_INTERVAL;\n this._devicePresenceOfflineTimeout = params.devicePresenceOfflineTimeout ?? DEVICE_PRESENCE_OFFLINE_TIMEOUT;\n this._automergeCredentials = params.automergeCredentials ?? false;\n }\n\n get identity() {\n return this._identity;\n }\n\n /**\n * Supplies the echo host used to anchor the HALO space on a root document. Anchors immediately when\n * an identity is already open, since the two are wired in either order.\n */\n async setEchoHost(echoHost: EchoHost): Promise<void> {\n this._echoHost = echoHost;\n if (this._identity) {\n await this._anchorHaloOnRootDocument(this._ctx, this._identity);\n }\n }\n\n @Trace.span({ showInBrowserTimeline: true })\n async open(ctx: Context): Promise<void> {\n log('opening identity manager');\n\n const identityRecord = this._metadataStore.getIdentityRecord();\n log('identity record', { identityRecord });\n if (identityRecord) {\n this._identity = await this._constructIdentity(identityRecord);\n await this._identity.open(ctx);\n await this._identity.ready();\n await this._anchorHaloOnRootDocument(this._ctx, this._identity);\n log.trace('dxos.halo.identity', {\n identityKey: identityRecord.identityKey,\n displayName: this._identity.profileDocument?.displayName,\n });\n\n this.stateUpdate.emit();\n }\n log('opened identity manager');\n }\n\n async close(ctx: Context): Promise<void> {\n await this._ctx.dispose();\n await this._identity?.close(ctx);\n }\n\n /**\n * Closes the identity and drops its persisted record, so the next open starts without one.\n * The identity's storage (feeds, automerge documents, keys) is wiped separately by the reset\n * chain — this only tears down the live identity and the metadata that would resurrect it.\n */\n async deleteIdentity(ctx: Context): Promise<void> {\n const identity = this._identity;\n if (identity) {\n log('deleting identity', { identityKey: identity.identityKey });\n // Dropped before teardown so anything observing `stateUpdate` cannot read a half-closed identity.\n this._identity = undefined;\n await this._ctx.dispose();\n this._ctx = new Context();\n await identity.close(ctx).catch((err) => log.warn('identity teardown failed; deleting anyway', { err }));\n } else {\n log('no live identity to delete');\n }\n\n // Unconditional, so a call that failed here is retried rather than leaving the persisted record\n // to resurrect an identity the caller already deleted.\n await this._metadataStore.clear();\n this.stateUpdate.emit();\n log('deleted identity');\n }\n\n async createIdentity({ profile, deviceProfile }: CreateIdentityOptions = {}, ctx?: Context): Promise<Identity> {\n invariant(!this._identity, 'Identity already exists.');\n log('creating identity...');\n\n const controlFeedKey = await this._keyring.createKey();\n const identityRecord: IdentityRecord = create(IdentityRecordSchema, {\n identityKey: fromPublicKey(await this._keyring.createKey()),\n deviceKey: fromPublicKey(await this._keyring.createKey()),\n haloSpace: create(SpaceMetadataSchema, {\n key: fromPublicKey(await this._keyring.createKey()),\n genesisFeedKey: fromPublicKey(controlFeedKey),\n controlFeedKey: fromPublicKey(controlFeedKey),\n dataFeedKey: fromPublicKey(await this._keyring.createKey()),\n }),\n });\n\n const identity = await this._constructIdentity(identityRecord);\n await identity.open(ctx ?? Context.default());\n\n {\n const identityKey = requirePublicKey(identityRecord.identityKey);\n const deviceKey = requirePublicKey(identityRecord.deviceKey);\n const haloSpace = identityRecord.haloSpace;\n invariant(haloSpace, 'Halo space metadata is required.');\n const generator = new CredentialGenerator(this._keyring, identityKey, deviceKey);\n const credentials = [\n // Space genesis.\n ...(await generator.createSpaceGenesis(\n requirePublicKey(haloSpace.key),\n requirePublicKey(haloSpace.genesisFeedKey),\n )),\n\n // Feed admission.\n await generator.createFeedAdmission(\n requirePublicKey(haloSpace.key),\n requirePublicKey(haloSpace.dataFeedKey),\n AdmittedFeed_Designation.DATA,\n ),\n ];\n\n if (profile) {\n credentials.push(await generator.createProfileCredential(profile));\n }\n\n // Device authorization (writes device chain).\n // NOTE: This credential is written last. This is a hack to make sure that display name is set before identity is \"ready\".\n credentials.push(await generator.createDeviceAuthorization(deviceKey));\n\n // Write device metadata to profile.\n credentials.push(\n await generator.createDeviceProfile({\n ...this.createDefaultDeviceProfile(),\n ...deviceProfile,\n }),\n );\n for (const credential of credentials) {\n await identity.controlPipeline.writer.write(credentialPayload(credential));\n }\n }\n\n await this._metadataStore.setIdentityRecord(identityRecord);\n this._identity = identity;\n await this._identity.ready();\n await this._anchorHaloOnRootDocument(this._ctx, this._identity);\n log.trace('dxos.halo.identity', {\n identityKey: identityRecord.identityKey,\n displayName: this._identity.profileDocument?.displayName,\n });\n this.stateUpdate.emit();\n\n log('created identity', {\n identityKey: identity.identityKey,\n deviceKey: identity.deviceKey,\n profile: identity.profileDocument,\n });\n\n return identity;\n }\n\n createDefaultDeviceProfile(): DeviceProfileDocument {\n // See TODOs in credentials.proto.\n let type: DeviceType;\n if (isNode()) {\n type = DeviceType.AGENT;\n } else {\n if (platform.name?.startsWith('iOS') || platform.name?.startsWith('Android')) {\n type = DeviceType.MOBILE;\n } else if (isTauri() || !platform.name) {\n // Tauri's __TAURI__ global isn't available in web workers. Fallback: WKWebView\n // (Tauri on macOS) reports null for platform.name; all standard browsers don't.\n type = DeviceType.NATIVE;\n } else {\n type = DeviceType.BROWSER;\n }\n }\n\n const os = platform.os?.family === 'OS X' ? 'macOS' : platform.os?.family;\n const name = type === DeviceType.NATIVE || type === DeviceType.MOBILE ? 'App' : platform.name;\n\n return create(DeviceProfileDocumentSchema, {\n type,\n platform: name,\n platformVersion: platform.version,\n architecture: typeof platform.os?.architecture === 'number' ? String(platform.os.architecture) : undefined,\n os,\n osVersion: platform.os?.version,\n });\n }\n\n /**\n * Prepare an identity object as the first step of acceptIdentity flow.\n */\n async prepareIdentity(params: JoinIdentityProps, ctx?: Context) {\n this._pendingHaloSpaceRootUrl = params.haloSpaceRootUrl;\n log('accepting identity', { params });\n invariant(!this._identity, 'Identity already exists.');\n\n const identityRecord: IdentityRecord = create(IdentityRecordSchema, {\n identityKey: fromPublicKey(params.identityKey),\n deviceKey: fromPublicKey(params.deviceKey),\n haloSpace: create(SpaceMetadataSchema, {\n key: fromPublicKey(params.haloSpaceKey),\n genesisFeedKey: fromPublicKey(params.haloGenesisFeedKey),\n controlFeedKey: fromPublicKey(params.controlFeedKey),\n dataFeedKey: fromPublicKey(params.dataFeedKey),\n controlTimeframe: params.controlTimeframe && fromTimeframe(params.controlTimeframe),\n }),\n });\n const identity = await this._constructIdentity(identityRecord);\n await identity.open(ctx ?? Context.default());\n return { identity, identityRecord };\n }\n\n /**\n * Accept an existing identity. Expects its device key to be authorized (now or later).\n */\n public async acceptIdentity(\n identity: Identity,\n identityRecord: IdentityRecord,\n profile?: DeviceProfileDocument,\n ): Promise<void> {\n this._identity = identity;\n\n // Identity becomes ready after device chain is replicated. Wait for it before storing the record.\n await this._identity.ready();\n await this._metadataStore.setIdentityRecord(identityRecord);\n\n log.trace('dxos.halo.identity', {\n identityKey: this._identity!.identityKey,\n displayName: this._identity.profileDocument?.displayName,\n });\n\n await this.updateDeviceProfile({\n ...this.createDefaultDeviceProfile(),\n ...profile,\n });\n await this._anchorHaloOnRootDocument(this._ctx, this._identity);\n this.stateUpdate.emit();\n\n log('accepted identity', { identityKey: identity.identityKey, deviceKey: identity.deviceKey });\n }\n\n /**\n * Update the profile document of an existing identity.\n */\n async updateProfile(profile: ProfileDocument): Promise<ProfileDocument> {\n invariant(this._identity, 'Identity not initialized.');\n // TODO(wittjosiah): Use CredentialGenerator.\n const credential = await this._identity.getIdentityCredentialSigner().createCredential({\n subject: this._identity.identityKey,\n assertion: create(IdentityProfileSchema, { profile }),\n });\n\n const receipt = await this._identity.controlPipeline.writer.write(credentialPayload(credential));\n await this._identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));\n this.stateUpdate.emit();\n return profile;\n }\n\n async updateDeviceProfile(profile: DeviceProfileDocument): Promise<Device> {\n invariant(this._identity, 'Identity not initialized.');\n\n // TODO(nf): CredentialGenerator doesn't work when not updating own device.\n // const generator = new CredentialGenerator(this._keyring, this._identity.identityKey, this._identity.deviceKey);\n // const credential = await generator.createDeviceProfile(profile);\n\n const credential = await this._identity.getDeviceCredentialSigner().createCredential({\n subject: this._identity.deviceKey,\n assertion: create(DeviceProfileSchema, { profile }),\n });\n\n const receipt = await this._identity.controlPipeline.writer.write(credentialPayload(credential));\n await this._identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));\n this.stateUpdate.emit();\n return create(DeviceSchema, {\n deviceKey: fromPublicKey(this._identity.deviceKey),\n kind: DeviceKind.CURRENT,\n presence: Device_PresenceState.ONLINE,\n profile,\n });\n }\n\n private async _constructIdentity(identityRecord: IdentityRecord): Promise<Identity> {\n invariant(!this._identity);\n log('constructing identity', { identityRecord });\n\n const identityKey = requirePublicKey(identityRecord.identityKey);\n const deviceKey = requirePublicKey(identityRecord.deviceKey);\n const haloSpace = identityRecord.haloSpace;\n invariant(haloSpace, 'Halo space metadata is required.');\n\n const gossip = new Gossip({\n localPeerId: deviceKey,\n });\n const presence = new Presence({\n announceInterval: this._devicePresenceAnnounceInterval,\n offlineTimeout: this._devicePresenceOfflineTimeout,\n identityKey: deviceKey,\n gossip,\n });\n\n // Must be created before the space so the feeds are writable.\n const controlFeed = await this._hypercoreStore.openHypercore(requirePublicKey(haloSpace.controlFeedKey), {\n writable: true,\n });\n const dataFeed = await this._hypercoreStore.openHypercore(requirePublicKey(haloSpace.dataFeedKey), {\n writable: true,\n sparse: true,\n });\n\n const space = await this._constructSpace({\n spaceRecord: haloSpace,\n swarmIdentity: {\n identityKey,\n peerKey: deviceKey,\n credentialProvider: Auth.createAuthProvider(createCredentialSignerWithKey(this._keyring, deviceKey)),\n credentialAuthenticator: deferFunction(() => identity.authVerifier.verifier),\n },\n gossip,\n identityKey,\n });\n await space.setControlFeed(controlFeed);\n await space.setDataFeed(dataFeed);\n\n const did = await createDidFromIdentityKey(identityKey);\n const identity: Identity = new Identity({\n space,\n presence,\n signer: this._keyring,\n did,\n identityKey,\n deviceKey,\n edgeConnection: this._edgeConnection,\n edgeFeatures: this._edgeFeatures,\n });\n log('done', { identityKey });\n\n // TODO(mykola): Set new timeframe on a write to a feed.\n if (haloSpace.controlTimeframe) {\n identity.controlPipeline.state.setTargetTimeframe(toTimeframe(haloSpace.controlTimeframe));\n }\n\n identity.stateUpdate.on(() => this.stateUpdate.emit());\n return identity;\n }\n\n /**\n * Gives the HALO space a space root document and mirrors its credential chain into a credentials\n * document, so the chain replicates as automerge rather than only as a control feed.\n *\n * The space keeps its key-derived id, exactly as a data space does. That is not a\n * migration compromise here as it is for data spaces: recovery reconstructs the HALO space from\n * `haloSpaceKey` alone (the only identifier EDGE returns), so a root-derived id would leave a\n * recovering device computing an id no replicated document belongs to.\n */\n private async _anchorHaloOnRootDocument(ctx: Context, identity: Identity): Promise<void> {\n // Opt-in: without the flag the HALO keeps its control feed and grows no documents.\n if (!this._echoHost || !this._automergeCredentials) {\n return;\n }\n const echoHost = this._echoHost;\n\n const spaceId = identity.haloSpaceId;\n try {\n if (!echoHost.getSpaceRootRefs(spaceId)) {\n const adopted = this._pendingHaloSpaceRootUrl;\n if (adopted !== undefined && isValidAutomergeUrl(adopted)) {\n // A second root over the same space would leave the two devices disagreeing about which\n // document carries the chain, so the joining device takes the one the inviter named — and\n // mints nothing when it cannot, since halo documents have no replication path between\n // devices yet and the root may simply never arrive.\n await echoHost.adoptSpaceRoot(ctx, spaceId, adopted).catch((err) => {\n log.warn('halo space root named by the inviting device is not available', { spaceId, adopted, err });\n });\n return;\n } else {\n // HALO has never had a directory — its data has always lived in the control feed — so one\n // is created here to give the root something to point at.\n if (!echoHost.spaceIds.includes(spaceId)) {\n await echoHost.createSpaceRoot(ctx, identity.haloSpaceKey);\n }\n\n const refs = await echoHost.migrateSpaceToRootDocument(ctx, spaceId);\n if (!refs) {\n return;\n }\n\n log('anchored halo space on a root document', { spaceId, refs });\n }\n }\n\n const refs = echoHost.getSpaceRootRefs(spaceId);\n if (refs) {\n identity.setHaloSpaceRootUrl(refs.spaceRootDocUrl);\n }\n\n const store = await openCredentialsDocument(ctx, echoHost, spaceId);\n for (const credential of identity.space.spaceState.credentials) {\n store.append(credential);\n }\n ctx.onDispose(identity.space.credentialProcessed.on((credential) => store.append(credential)));\n\n // The document feeds the same state machine the feed does; processing is idempotent by\n // credential id, so both sources can run during the migration window.\n store.subscribe(ctx, (credential) => identity.space.processDocumentCredential(credential));\n } catch (err) {\n log.warn('failed to anchor the halo space on a root document', { spaceId, err });\n }\n }\n\n private async _constructSpace({ spaceRecord, swarmIdentity, identityKey, gossip }: ConstructSpaceProps) {\n return this._spaceManager.constructSpace({\n metadata: create(SpaceMetadataSchema, {\n key: spaceRecord.key,\n genesisFeedKey: spaceRecord.genesisFeedKey,\n }),\n swarmIdentity,\n onAuthorizedConnection: (session) => {\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n gossip.createExtension({ remotePeerId: session.remotePeerId }),\n );\n },\n onAuthFailure: () => {\n log.warn('auth failure');\n },\n memberKey: identityKey,\n onDelegatedInvitationStatusChange: async () => {}, // TODO: will be used for recovery keys\n onMemberRolesChanged: async () => {}, // TODO: will be used for device revocation\n });\n }\n}\n\nexport type IdentityManagerLayerOptions = Pick<\n IdentityManagerProps,\n 'devicePresenceAnnounceInterval' | 'devicePresenceOfflineTimeout' | 'edgeFeatures' | 'automergeCredentials'\n>;\n\n/**\n * Effect Layer constructing an {@link IdentityManager} from ambient service dependencies.\n */\nexport const IdentityManagerLayer = (\n options: IdentityManagerLayerOptions = {},\n): Layer.Layer<\n IdentityContract.ManagerService,\n never,\n Hook.Controller | IMetadataStoreService | KeyringApiService | HypercoreStoreService | SpaceManagerService\n> =>\n Layer.effect(\n IdentityContract.ManagerService,\n Effect.gen(function* () {\n const metadataStore = yield* IMetadataStoreService;\n const keyring = yield* KeyringApiService;\n const hypercoreStore = yield* HypercoreStoreService;\n const spaceManager = yield* SpaceManagerService;\n const edgeConnection = yield* Effect.serviceOption(EdgeConnectionService);\n const identityManager = new IdentityManager({\n metadataStore,\n keyring,\n hypercoreStore,\n spaceManager,\n edgeConnection: Option.getOrUndefined(edgeConnection),\n ...options,\n });\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(() => identityManager.close(Context.default())));\n yield* Hook.on(\n Events.StorageReady,\n Effect.fn('IdentityManager.onStorageReady')(function* () {\n yield* Effect.promise(() => identityManager.open(ctx));\n yield* Hook.emit(Events.IdentityLoaded, { identity: identityManager.identity });\n }),\n );\n return identityManager;\n }),\n );\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as SqlMigrations from '@dxos/sql-sqlite/SqlMigrations';\n\nimport init from './0001_init.sql?raw';\n\n/**\n * Hypercore file-storage migrations, keyed `<id>_<name>` as `Migrator.fromRecord` expects. Ids must only ever increase,\n * and an applied migration must never be edited — nothing verifies its contents.\n */\nexport const MIGRATIONS = {\n '0001_init': SqlMigrations.apply(init),\n};\n\n/** Own history table per store, since many stores share the client database. */\nexport const MIGRATIONS_TABLE = 'hypercore_files_migrations';\n","//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Migrator from 'effect/sql/Migrator';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport type * as SqlError from 'effect/sql/SqlError';\nimport type { Callback, FileStat, RandomAccessStorage } from 'random-access-storage';\n\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { HypercoreStorageDirectoryService } from '@dxos/feed-store';\nimport { log } from '@dxos/log';\nimport { Directory, type File, type Storage, StorageType, wrapFile } from '@dxos/random-access-storage';\n\nimport { MIGRATIONS, MIGRATIONS_TABLE } from './migrations/hypercore/index.ts';\n\n/**\n * True when a rejected SQL op failed because its connection was already closed — the message\n * `The database connection is not open` (raised by `@effect/sql-sqlite-node`), which arrives\n * wrapped as an effect `SqlError`, so walk the `cause` chain. Signals teardown, not a real fault.\n */\nexport const isClosedConnectionError = (err: unknown): boolean => {\n for (let cur: any = err, depth = 0; cur != null && depth < 5; cur = cur.cause, depth++) {\n const message = typeof cur === 'string' ? cur : cur.message;\n if (typeof message === 'string' && /connection is not open/i.test(message)) {\n return true;\n }\n }\n return false;\n};\n\nexport type SqliteStorageOptions = {\n runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n};\n\n/**\n * Effect service tag for {@link SqliteStorage}.\n */\nexport class SqliteStorageService extends EffectContext.Service<SqliteStorageService, SqliteStorage>()(\n '@dxos/client-services/SqliteStorage',\n) {}\n\n/** Minimal cross-platform EventEmitter needed by the RandomAccessStorage contract. */\nclass BaseEventEmitter {\n readonly #events: Record<string, ((...args: unknown[]) => void)[]> = Object.create(null);\n\n on(event: string, listener: (...args: unknown[]) => void): this {\n (this.#events[event] ??= []).push(listener);\n return this;\n }\n off(event: string, listener: (...args: unknown[]) => void): this {\n const list = this.#events[event];\n if (list) {\n const idx = list.indexOf(listener);\n if (idx !== -1) {\n list.splice(idx, 1);\n }\n }\n return this;\n }\n emit(event: string, ...args: unknown[]): boolean {\n const list = this.#events[event];\n if (!list?.length) {\n return false;\n }\n for (const fn of [...list]) {\n fn(...args);\n }\n return true;\n }\n addListener = this.on;\n removeListener = this.off;\n once(event: string, listener: (...args: unknown[]) => void): this {\n const wrapper = (...args: unknown[]) => {\n this.off(event, wrapper);\n listener(...args);\n };\n return this.on(event, wrapper);\n }\n removeAllListeners(event?: string): this {\n if (event) {\n delete this.#events[event];\n } else {\n for (const key of Object.keys(this.#events)) {\n delete this.#events[key];\n }\n }\n return this;\n }\n listeners(event: string): ((...args: unknown[]) => void)[] {\n return this.#events[event] ?? [];\n }\n rawListeners(event: string): ((...args: unknown[]) => void)[] {\n return this.#events[event] ?? [];\n }\n listenerCount(event: string): number {\n return this.#events[event]?.length ?? 0;\n }\n prependListener(event: string, listener: (...args: unknown[]) => void): this {\n (this.#events[event] ??= []).unshift(listener);\n return this;\n }\n prependOnceListener(event: string, listener: (...args: unknown[]) => void): this {\n const wrapper = (...args: unknown[]) => {\n this.off(event, wrapper);\n listener(...args);\n };\n return this.prependListener(event, wrapper);\n }\n eventNames(): string[] {\n return Object.keys(this.#events);\n }\n getMaxListeners(): number {\n return 0;\n }\n setMaxListeners(): this {\n return this;\n }\n}\n\n/**\n * SQLite-backed random-access file for hypercore storage.\n * Stores each file as a blob in `hypercore_files`. Read-modify-write for writes.\n */\nclass SqliteRandomAccessFile extends BaseEventEmitter implements RandomAccessStorage {\n readonly opened: boolean = false;\n readonly suspended: boolean = false;\n readonly writing: boolean = false;\n readonly readable: boolean = true;\n readonly writable: boolean = true;\n readonly deletable: boolean = true;\n readonly truncatable: boolean = false;\n // Setting statable=false prevents hypercore's statAndReadAll() from computing a negative\n // read-size (stat.size - offset) for new empty files, which causes an infinite async loop.\n readonly statable: boolean = false;\n\n #closed = false;\n #unlinked = false;\n #destroyed = false;\n\n get closed(): boolean {\n return this.#closed;\n }\n\n get unlinked(): boolean {\n return this.#unlinked;\n }\n\n get destroyed(): boolean {\n return this.#destroyed;\n }\n\n // Filesystem-like metadata for compatibility with wrapFile.\n readonly directory: string;\n readonly filename: string;\n\n #buffer: Buffer = Buffer.alloc(0);\n #loaded = false;\n // The one-shot initial DB read (populates `#buffer`); set once, on first access.\n #loading: Promise<void> | null = null;\n // The latest in-flight DB write (from `write`/`del`); replaced on each save, so it always\n // tracks the most recent one. `close()` drains both before reporting closed.\n #saving: Promise<void> | null = null;\n\n constructor(\n private readonly filePath: string,\n private readonly runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>,\n ) {\n super();\n const parts = filePath.split('/');\n this.filename = parts.pop() ?? '';\n this.directory = parts.join('/');\n }\n\n private _ensureLoaded(): Promise<void> {\n if (this.#loaded) {\n return Promise.resolve();\n }\n // If the file was closed (e.g. the storage was torn down during shutdown) before its initial\n // load completed, don't start the DB read. The underlying SQL connection may already be\n // closing, and the read would reject with \"database connection is not open\" as an unhandled\n // rejection — a background read racing teardown. #buffer already defaults to empty, so reads\n // resolve against an empty file.\n if (this.#closed) {\n return Promise.resolve();\n }\n if (!this.#loading) {\n this.#loading = this._loadFromDb();\n // Mark the cached load promise as handled so that if it rejects after every awaiter is gone\n // (e.g. the SQL runtime is disposed at teardown without close() being called on this file),\n // the rejection is never surfaced as an unhandled rejection. Legitimate awaiters still observe\n // the error through their own `.then`/`.catch` on the same promise returned below.\n this.#loading.catch(() => {});\n }\n return this.#loading;\n }\n\n private async _loadFromDb(): Promise<void> {\n const filePath = this.filePath;\n try {\n const rows = await RuntimeProvider.runPromise(this.runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql<{ data: Uint8Array }>`SELECT data FROM hypercore_files WHERE path = ${filePath}`;\n }),\n );\n this.#buffer = rows.length > 0 ? Buffer.from(rows[0].data) : Buffer.alloc(0);\n } catch (err) {\n // A read racing teardown rejects with \"database connection is not open\". The `#closed` guard\n // in `_ensureLoaded` only catches reads not yet started, and `#closed` covers only this file\n // being closed — during client disposal the shared SQL connection can be torn down while this\n // file's `#closed` is still false (the container closed the connection without closing every\n // file first). In either case a closed connection means there is nothing to load, so fall back\n // to the empty `#buffer`; rethrow only a genuine error against a live connection. Swallowing an\n // unhandled rejection here otherwise crashes the whole test worker (exit 1, no test failure).\n if (!this.#closed && !isClosedConnectionError(err)) {\n throw err;\n }\n }\n this.#loaded = true;\n }\n\n private async _saveToDb(): Promise<void> {\n const filePath = this.filePath;\n const data = this.#buffer;\n try {\n await RuntimeProvider.runPromise(this.runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`INSERT OR REPLACE INTO hypercore_files (path, data) VALUES (${filePath}, ${data})`;\n }),\n );\n } catch (err) {\n // Symmetric with `_loadFromDb`: a write racing teardown rejects (as `SqlError: Failed to\n // execute statement` wrapping \"connection is not open\") when the shared SQL connection is\n // torn down before this file's `#closed` flips. Persisting to a dead connection is moot\n // during disposal, so swallow it; rethrow only a genuine failure against a live connection.\n // An unswallowed rejection here surfaces as an unhandled rejection that fails the test worker.\n if (!this.#closed && !isClosedConnectionError(err)) {\n throw err;\n }\n }\n }\n\n write(offset: number, data: Buffer, cb: Callback<any>): void {\n const saving = this._ensureLoaded()\n .then(() => {\n const end = offset + data.length;\n // Hypercore rewrites unchanged pages of every feed it opens, and each save rewrites the whole\n // blob, so a write that changes nothing must not reach the database.\n if (end <= this.#buffer.length && this.#buffer.subarray(offset, end).equals(data)) {\n return;\n }\n if (end > this.#buffer.length) {\n const enlarged = Buffer.alloc(end);\n this.#buffer.copy(enlarged);\n this.#buffer = enlarged;\n }\n data.copy(this.#buffer, offset);\n return this._saveToDb();\n })\n .then(\n () => cb(null),\n (err) => cb(err),\n );\n // Track the in-flight save so `close()` can drain it before reporting closed — otherwise a\n // write racing `close()` (e.g. a background sync write racing `client.reset()`'s teardown)\n // keeps running against a connection the container may tear down immediately after.\n this.#saving = saving.catch(() => {});\n }\n\n read(offset: number, size: number, cb: Callback<Buffer>): void {\n this._ensureLoaded()\n .then(() => {\n if (size === 0) {\n cb(null, Buffer.alloc(0));\n return;\n }\n if (offset + size > this.#buffer.length) {\n cb(new Error(`Could not satisfy length ${size} at offset ${offset} (file size: ${this.#buffer.length})`));\n return;\n }\n cb(null, Buffer.from(this.#buffer.subarray(offset, offset + size)));\n })\n .catch((err) => cb(err));\n }\n\n del(offset: number, size: number, cb: Callback<any>): void {\n const saving = this._ensureLoaded()\n .then(() => {\n const end = Math.min(offset + size, this.#buffer.length);\n if (offset < end) {\n this.#buffer.fill(0, offset, end);\n }\n return this._saveToDb();\n })\n .then(\n () => cb(null),\n (err) => cb(err),\n );\n // See `write()`: track the in-flight save so `close()` can drain it before reporting closed.\n this.#saving = saving.catch(() => {});\n }\n\n stat(cb: Callback<FileStat>): void {\n this._ensureLoaded()\n .then(() => {\n cb(null, { size: this.#buffer.length });\n })\n .catch((err) => cb(err));\n }\n\n close(cb: Callback<Error>): void {\n this.#closed = true;\n // Drain any in-flight initial load and any in-flight write/del before reporting closed, so\n // neither races a torn-down SQL connection (avoids \"database connection is not open\" errors,\n // and the resulting stall in callers — e.g. `client.reset()`'s feed teardown — that wait on\n // this file's `close()` to settle before tearing down the connection itself).\n Promise.all([this.#loading ?? Promise.resolve(), this.#saving ?? Promise.resolve()]).then(\n () => cb(null),\n () => cb(null),\n );\n }\n\n destroy(cb: Callback<Error>): void {\n const filePath = this.filePath;\n RuntimeProvider.runPromise(this.runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`DELETE FROM hypercore_files WHERE path = ${filePath}`;\n }),\n )\n .then(() => {\n this.#buffer = Buffer.alloc(0);\n this.#destroyed = true;\n this.#unlinked = true;\n this.#closed = true;\n cb(null);\n })\n .catch((err) => cb(err));\n }\n}\n\n/**\n * SQLite-backed Storage implementation for hypercore feeds.\n * Table: hypercore_files(path TEXT PRIMARY KEY, data BLOB NOT NULL DEFAULT x'').\n */\nexport class SqliteStorage implements Storage {\n readonly path: string;\n readonly type = StorageType.NODE;\n\n readonly #runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n readonly #files = new Map<string, File>();\n readonly #nativeFiles = new Map<string, SqliteRandomAccessFile>();\n #closed = false;\n\n constructor({ runtime }: SqliteStorageOptions, path = '/sqlite-feeds') {\n this.#runtime = runtime;\n this.path = path;\n }\n\n /**\n * Applies any migrations this database has not recorded yet.\n */\n readonly migrate: Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient> = Migrator.make({})({\n loader: Migrator.fromRecord(MIGRATIONS),\n table: MIGRATIONS_TABLE,\n }).pipe(\n // A malformed bundled manifest is a defect, not something a caller can recover from.\n Effect.catchTag('MigrationError', (error) => Effect.die(error)),\n Effect.asVoid,\n Effect.withSpan('SqliteStorage.migrate'),\n );\n\n get size(): number {\n return this.#files.size;\n }\n\n createDirectory(sub = ''): Directory {\n const dirPath = sub ? `${this.path}/${sub}` : this.path;\n const runtime = this.#runtime;\n const files = this.#files;\n const nativeFiles = this.#nativeFiles;\n\n const getOrCreateFile = (path: string, filename: string): File => {\n const fullPath = `${path}/${filename}`;\n const existingNative = nativeFiles.get(fullPath);\n if (existingNative && !existingNative.destroyed) {\n return files.get(fullPath)!;\n }\n const native = new SqliteRandomAccessFile(fullPath, runtime);\n const file = wrapFile(native, StorageType.NODE);\n files.set(fullPath, file);\n nativeFiles.set(fullPath, native);\n return file;\n };\n\n const list = async (path: string): Promise<string[]> => {\n const prefix = path.endsWith('/') ? path : path + '/';\n const rows = await RuntimeProvider.runPromise(runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql<{\n path: string;\n }>`SELECT path FROM hypercore_files WHERE path = ${path} OR path LIKE ${prefix + '%'}`;\n }),\n );\n return rows.map((row) => row.path.replace(path + '/', '').replace(path, ''));\n };\n\n const remove = async (): Promise<void> => {\n const prefix = dirPath.endsWith('/') ? dirPath : dirPath + '/';\n await RuntimeProvider.runPromise(runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`DELETE FROM hypercore_files WHERE path = ${dirPath} OR path LIKE ${prefix + '%'}`;\n }),\n );\n // Clean up in-memory file cache.\n for (const [filePath] of files) {\n if (filePath === dirPath || filePath.startsWith(prefix)) {\n files.delete(filePath);\n }\n }\n };\n\n return new Directory({\n type: StorageType.NODE,\n path: dirPath,\n list,\n getOrCreateFile,\n remove,\n });\n }\n\n async reset(): Promise<void> {\n log('SqliteStorage: clearing all hypercore files');\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`DELETE FROM hypercore_files`;\n }),\n );\n this.#files.clear();\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n // Close each native file before the SQL connection is torn down. `close()` marks the file\n // closed (so any subsequent read skips the DB) and drains its in-flight initial load —\n // preventing \"database connection is not open\" unhandled rejections from background reads\n // that race shutdown (e.g. a test client closing while a background sync read is in flight).\n const natives = [...this.#nativeFiles.values()];\n await Promise.all(natives.map((native) => new Promise<void>((resolve) => native.close(() => resolve()))));\n this.#files.clear();\n this.#nativeFiles.clear();\n }\n}\n\nexport type SqliteStorageLayerOptions = {\n path?: string;\n};\n\n/**\n * Effect Layer constructing a {@link SqliteStorage} from the ambient SQL runtime.\n */\nexport const SqliteStorageLayer = (\n options: SqliteStorageLayerOptions = {},\n): Layer.Layer<SqliteStorageService, never, SqlClient.SqlClient> =>\n Layer.effect(\n SqliteStorageService,\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n return new SqliteStorage({ runtime }, options.path);\n }),\n );\n\nexport type HypercoreStorageDirectoryLayerOptions = {\n sub?: string;\n};\n\n/**\n * Effect Layer providing the hypercore feeds root directory from {@link SqliteStorage}.\n */\nexport const HypercoreStorageDirectoryLayer = (\n options: HypercoreStorageDirectoryLayerOptions = {},\n): Layer.Layer<HypercoreStorageDirectoryService, never, SqliteStorageService> =>\n Layer.effect(\n HypercoreStorageDirectoryService,\n Effect.gen(function* () {\n const storage = yield* SqliteStorageService;\n return storage.createDirectory(options.sub ?? 'feeds');\n }),\n );\n\n/**\n * Deletes every row the stack persists, so the next open starts from an empty database.\n */\nexport const wipeSqliteStorage: Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient> = Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n // Echo metadata + large space data.\n yield* sql`DELETE FROM space_metadata`;\n yield* sql`DELETE FROM space_large`;\n // Keyring.\n yield* sql`DELETE FROM keyring`;\n // Automerge chunks + heads.\n yield* sql`DELETE FROM automerge_chunks`;\n yield* sql`DELETE FROM automerge_heads`;\n // Hypercore feed files.\n yield* sql`DELETE FROM hypercore_files`;\n // Feed store (queue feeds, blocks, etc.).\n yield* sql`DELETE FROM feeds`;\n yield* sql`DELETE FROM blocks`;\n yield* sql`DELETE FROM subscriptions`;\n yield* sql`DELETE FROM cursor_tokens`;\n yield* sql`DELETE FROM sync_state`;\n // Index tables.\n yield* sql`DELETE FROM indexCursor`;\n yield* sql`DELETE FROM objectMeta`;\n yield* sql`DELETE FROM reverseRef`;\n yield* sql`DELETE FROM ftsIndex`;\n yield* sql`DELETE FROM objectSnapshot`;\n});\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context, Resource } from '@dxos/context';\nimport { createCredential, signPresentation } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { BaseError } from '@dxos/errors';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { toServiceError } from '@dxos/protocols';\nimport { buf, fromPublicKey } from '@dxos/protocols/buf';\nimport {\n type Identity as IdentityProto,\n IdentitySchema,\n type RecoverIdentityRequest,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport {\n AuthSchema,\n type Credential,\n type Presentation,\n type ProfileDocument,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { IdentityService } from '@dxos/protocols/rpc';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport * as SqliteStorage from '../../SqliteStorage.ts';\nimport { type CreateIdentityOptions } from './identity-manager.ts';\nimport { type EdgeIdentityRecoveryManager, EdgeIdentityRecoveryManagerService } from './identity-recovery-manager.ts';\n\nexport class IdentityServiceImpl extends Resource implements IdentityService.Handlers {\n 'constructor'(\n private readonly _identityManager: IdentityContract.Manager,\n private readonly _recoveryManager: EdgeIdentityRecoveryManager,\n private readonly _keyring: KeyringApi,\n private readonly _dataSpaceManager: SpacesContract.Manager,\n private readonly _wipeStorage: () => Promise<void>,\n private readonly _createIdentity: (params: CreateIdentityOptions, ctx?: Context) => Promise<Identity>,\n private readonly _onProfileUpdate?: (profile: ProfileDocument | undefined) => Promise<void>,\n ) {\n super();\n }\n\n ['IdentityService.createIdentity'](\n request: IdentityService.CreateIdentityRequest,\n ): Effect.Effect<IdentityProto, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n await this._createIdentity(\n {\n profile: request.profile,\n deviceProfile: request.deviceProfile,\n },\n ctx,\n );\n return this._getIdentity()!;\n },\n catch: toServiceError,\n });\n }\n\n ['IdentityService.queryIdentity'](): EffectStream.Stream<IdentityService.QueryIdentityResponse, Error> {\n return EffectEx.streamFromEmitter<IdentityService.QueryIdentityResponse, Error>((emit) => {\n // Omit `identity` entirely when absent: an explicit `undefined` would still drive the optional\n // protobuf codec, which dereferences the missing message and throws.\n const emitNext = () => {\n const identity = this._getIdentity();\n void emit.single(identity ? { identity } : {});\n };\n\n emitNext();\n const unsubscribe = this._identityManager.stateUpdate.on(emitNext);\n return Effect.sync(() => unsubscribe());\n });\n }\n\n ['IdentityService.updateProfile'](profile: ProfileDocument): Effect.Effect<IdentityProto, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n invariant(this._identityManager.identity, 'Identity not initialized.');\n await this._identityManager.updateProfile(profile);\n await this._onProfileUpdate?.(this._identityManager.identity.profileDocument);\n return this._getIdentity()!;\n },\n catch: toServiceError,\n });\n }\n\n ['IdentityService.createRecoveryCredential'](\n request: IdentityService.CreateRecoveryCredentialRequest,\n ): Effect.Effect<IdentityService.CreateRecoveryCredentialResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => this._recoveryManager.createRecoveryCredential(request),\n catch: toServiceError,\n });\n }\n\n ['IdentityService.revokeRecoveryCredential'](\n request: IdentityService.RevokeRecoveryCredentialRequest,\n ): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => this._recoveryManager.revokeRecoveryCredential(request),\n catch: toServiceError,\n });\n }\n\n ['IdentityService.requestRecoveryChallenge'](): Effect.Effect<\n IdentityService.RequestRecoveryChallengeResponse,\n Error\n > {\n return Effect.tryPromise({\n try: async () => this._recoveryManager.requestRecoveryChallenge(Context.default()),\n catch: toServiceError,\n });\n }\n\n ['IdentityService.recoverIdentity'](request: RecoverIdentityRequest): Effect.Effect<IdentityProto, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n // buf models the `request` oneof as a tagged union, so the cases are exhaustive here.\n switch (request.request.case) {\n case 'recoveryCode':\n await this._recoveryManager.recoverIdentity(ctx, { recoveryCode: request.request.value });\n break;\n case 'external':\n await this._recoveryManager.recoverIdentityWithExternalSignature(ctx, request.request.value);\n break;\n case 'token':\n await this._recoveryManager.recoverIdentityWithToken(ctx, { token: request.request.value });\n break;\n case 'recoveryProof':\n await this._recoveryManager.recoverIdentityWithToken(ctx, { recoveryProof: request.request.value });\n break;\n case undefined:\n throw new Error('Invalid request.');\n }\n\n return this._getIdentity()!;\n },\n catch: toServiceError,\n });\n }\n\n /**\n * Closes and deletes every space, closes and deletes the identity, then removes the persisted\n * bytes they leave behind: the automerge documents, the hypercore files, the feed store, the\n * index tables and the keyring. The stack stays open throughout, so the client is left exactly as\n * it was before an identity existed and `createIdentity` can run straight afterwards.\n */\n ['IdentityService.deleteIdentity'](): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n // Spaces first: their teardown leaves the swarm and flushes through the identity's HALO,\n // which the identity teardown below closes.\n await this._dataSpaceManager.deleteAllSpaces(ctx);\n await this._identityManager.deleteIdentity(ctx);\n // Last, so nothing still holds the rows it removes.\n await this._wipeStorage();\n },\n catch: toServiceError,\n });\n }\n\n // TODO(burdon): Rename createPresentation?\n ['IdentityService.signPresentation'](\n request: IdentityService.SignPresentationRequest,\n ): Effect.Effect<Presentation, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const { presentation, nonce } = request;\n invariant(this._identityManager.identity, 'Identity not initialized.');\n\n return await signPresentation({\n presentation: presentation,\n signer: this._keyring,\n signerKey: this._identityManager.identity.deviceKey,\n chain: this._identityManager.identity.deviceCredentialChain,\n nonce,\n });\n },\n catch: toServiceError,\n });\n }\n\n ['IdentityService.createAuthCredential'](): Effect.Effect<Credential, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const identity = this._identityManager.identity;\n\n invariant(identity, 'Identity not initialized.');\n\n return await createCredential({\n assertion: create(AuthSchema, {}),\n issuer: identity.identityKey,\n subject: identity.identityKey,\n chain: identity.deviceCredentialChain,\n signingKey: identity.deviceKey,\n signer: this._keyring,\n });\n },\n catch: toServiceError,\n });\n }\n\n private '_getIdentity'(): IdentityProto | undefined {\n if (!this._identityManager.identity) {\n return undefined;\n }\n\n return buf.create(IdentitySchema, {\n did: this._identityManager.identity.did,\n identityKey: fromPublicKey(this._identityManager.identity.identityKey),\n spaceKey: fromPublicKey(this._identityManager.identity.space.key),\n profile: this._identityManager.identity.profileDocument,\n });\n }\n}\n\n// The impl is a {@link Resource}; its open/close lifecycle is bound to the layer scope.\nexport const IdentityServiceLayer = Layer.effect(\n IdentityService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const recoveryManager = yield* EdgeIdentityRecoveryManagerService;\n const keyring = yield* KeyringApiService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const identityLifecycle = yield* IdentityContract.LifecycleService;\n const runtime = yield* RuntimeProvider.currentRuntime<Hook.Controller>();\n // The stack's own SQLite runtime: the wipe runs under the live stack rather than the reset\n // chain, which tears it down.\n const sqlRuntime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n const service = new IdentityServiceImpl(\n identityManager,\n recoveryManager,\n keyring,\n dataSpaceManager,\n () => RuntimeProvider.runPromise(sqlRuntime)(SqliteStorage.wipeSqliteStorage.pipe(Effect.orDie)),\n (params, ctx) => identityLifecycle.createIdentity(params, ctx),\n (profile) =>\n profile\n ? RuntimeProvider.runPromise(runtime)(Hook.emit(Events.ProfileUpdated, { profile }))\n : Promise.resolve(),\n );\n yield* Effect.acquireRelease(\n Effect.promise(() => service.open()),\n () => Effect.promise(() => service.close()),\n );\n return service;\n }),\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { fromBinary } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Event, UpdateScheduler } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport {\n INBOX_ENVELOPE_TTL_MS,\n INBOX_ENVELOPE_VERSION,\n SPACE_INVITATION_NOTICE_TTL_MS,\n type VerifiedSpaceInvitationNotice,\n createDidFromIdentityKey,\n createInboxEnvelope,\n decodeInboxEnvelope,\n encodeInboxEnvelope,\n verifyInboxEnvelope,\n verifySpaceInvitationNotice,\n} from '@dxos/credentials';\nimport {\n type EdgeConnection,\n EdgeConnectionService,\n type EdgeHttpClient,\n EdgeHttpClientService,\n} from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n EdgeCallFailedError,\n EdgeService,\n INBOX_MAX_PAYLOAD_LENGTH,\n InboxAccountRequiredError,\n type InboxNotice,\n InboxPayloadTooLargeError,\n toServiceError,\n} from '@dxos/protocols';\nimport { type Credential, CredentialSchema } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { InboxService } from '@dxos/protocols/rpc';\nimport { Message, SpaceInvitationMessage } from '@dxos/types';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport { type Identity } from '../../Identity.ts';\n\nexport class InboxUnavailableError extends BaseError.extend(\n 'InboxUnavailableError',\n 'The inbox is not available until the identity is ready and connected.',\n) {}\n\n/** The EDGE inbox endpoints the service calls; narrowed so tests can stand in for EDGE. */\nexport type InboxEdgeClient = Pick<EdgeHttpClient, 'sendInboxMessage' | 'listInbox' | 'ackInbox'>;\n\n/** The identity the inbox signs as and receives for. */\nexport type InboxIdentitySource = {\n readonly stateUpdate: Event;\n readonly identity: Pick<Identity, 'identityKey' | 'getInboxEnvelopeSigner'> | undefined;\n};\n\n/** The socket events that say the inbox may have changed. */\nexport type InboxPushSource = Pick<EdgeConnection, 'onMessage' | 'onReconnected'>;\n\n/**\n * Stands in for the EDGE inbox, authenticating each call as whichever identity `identity` holds at\n * the time; tests share one between clients so they can message each other without EDGE.\n */\nexport interface InboxRelay {\n connect(identity: InboxIdentitySource): { edgeClient: InboxEdgeClient; pushSource: InboxPushSource };\n}\n\nexport type InboxServiceOptions = {\n /** Catch-up poll while subscribed, in case a push frame was missed. */\n pollIntervalMs?: number;\n};\n\nconst DEFAULT_POLL_INTERVAL_MS = 5 * 60 * 1_000;\n\n/** Payload types this client surfaces; envelopes of any other type stay pending for a newer client. */\nconst KNOWN_TYPES = new Set<string>([InboxService.INBOX_MESSAGE_TYPE]);\n\ntype Entry = {\n message: InboxService.InboxMessage;\n /** Every EDGE entry carrying this message; a resent envelope lands under a fresh EDGE id. */\n edgeIds: Set<string>;\n};\n\n/** What one EDGE entry turned out to be. */\ntype Classified =\n | { kind: 'message'; message: InboxService.InboxMessage }\n /** Possibly valid for a newer client: neither surfaced nor acked. */\n | { kind: 'pending' }\n /** Can never become valid, so it is acked rather than left to use up the recipient's cap. */\n | { kind: 'rejected'; reason: string };\n\n/** EDGE refuses inbox calls from an identity not linked to an account; retrying cannot succeed until it is. */\nconst isAccountRequired = (error: unknown): boolean =>\n error instanceof EdgeCallFailedError && error.data?.type === 'identity_not_associated_with_account';\n\nconst decodeCredential = (payload: string): Credential | undefined => {\n try {\n return fromBinary(CredentialSchema, Buffer.from(payload, 'base64'));\n } catch {\n return undefined;\n }\n};\n\n/**\n * Converts a legacy (pre-envelope) invitation notice into the message a current sender would build.\n * Receive-only: delete once the notice TTL has passed for every sender on a pre-envelope release.\n */\nconst legacyInvitationMessage = async (notice: VerifiedSpaceInvitationNotice): Promise<InboxService.InboxMessage> => ({\n id: notice.id,\n senderIdentityKey: notice.sender,\n type: InboxService.INBOX_MESSAGE_TYPE,\n payload: Message.encodeJson(\n SpaceInvitationMessage.make({\n sender: { identityDid: await createDidFromIdentityKey(notice.sender) },\n spaceKey: notice.spaceKey.toHex(),\n role: notice.role,\n created: notice.sentAt,\n }),\n ),\n sentAt: notice.sentAt,\n});\n\n/**\n * User-to-user messages relayed through the EDGE inbox, each carried in a signed envelope.\n *\n * The pending set is pulled from EDGE when the first subscriber arrives, on every reconnect, on\n * every `inbox` push frame (which is treated as a doorbell, its payload unread) and on a slow poll;\n * each pull replaces the set, so an ack from another device drops the entry here too.\n */\nexport class InboxServiceImpl implements InboxService.Handlers {\n readonly #changed = new Event<InboxService.Messages>();\n #entries = new Map<string, Entry>();\n /** EDGE ids acked locally; a pull already in flight must not resurrect them. */\n readonly #acked = new Set<string>();\n #loaded = false;\n #status: InboxService.Status = 'available';\n #subscribers = 0;\n #ctx?: Context;\n\n 'constructor'(\n private readonly _identityManager: InboxIdentitySource,\n private readonly _edgeClient?: InboxEdgeClient,\n private readonly _pushSource?: InboxPushSource,\n private readonly _options: InboxServiceOptions = {},\n ) {}\n\n ['InboxService.sendMessage'](request: InboxService.SendMessageRequest): Effect.Effect<void, Error> {\n return Effect.tryPromise({\n try: async () => {\n const identity = this._identityManager.identity;\n if (!identity || !this._edgeClient) {\n throw new InboxUnavailableError();\n }\n const envelope = await createInboxEnvelope(identity.getInboxEnvelopeSigner(), request.recipientIdentityKey, {\n type: request.type,\n payload: request.payload,\n });\n const payload = Buffer.from(encodeInboxEnvelope(envelope)).toString('base64');\n if (payload.length > INBOX_MAX_PAYLOAD_LENGTH) {\n throw new InboxPayloadTooLargeError({\n context: { length: payload.length, maxLength: INBOX_MAX_PAYLOAD_LENGTH },\n });\n }\n const recipientDid = await createDidFromIdentityKey(request.recipientIdentityKey);\n await this._edgeClient.sendInboxMessage(Context.default(), recipientDid, payload).catch((error) => {\n throw isAccountRequired(error) ? new InboxAccountRequiredError({ cause: error }) : error;\n });\n },\n catch: toServiceError,\n });\n }\n\n ['InboxService.subscribe'](): EffectStream.Stream<InboxService.Messages, Error> {\n return EffectEx.streamFromEmitter<InboxService.Messages, Error>((emit) => {\n const unsubscribe = this.#changed.on((snapshot) => void emit.single(snapshot));\n if (this.#loaded || !this._edgeClient) {\n void emit.single(this.#snapshot());\n }\n this.#retain();\n return Effect.promise(async () => {\n unsubscribe();\n await this.#release();\n });\n });\n }\n\n ['InboxService.ack'](request: InboxService.AckRequest): Effect.Effect<void, Error> {\n return Effect.tryPromise({\n try: async () => {\n const edgeIds = request.ids.flatMap((id) => [...(this.#entries.get(id)?.edgeIds ?? [])]);\n if (edgeIds.length === 0) {\n return;\n }\n if (!this._edgeClient) {\n throw new InboxUnavailableError();\n }\n await this._edgeClient.ackInbox(Context.default(), edgeIds);\n edgeIds.forEach((id) => this.#acked.add(id));\n request.ids.forEach((id) => this.#entries.delete(id));\n this.#changed.emit(this.#snapshot());\n },\n catch: toServiceError,\n });\n }\n\n #snapshot(): InboxService.Messages {\n return {\n messages: [...this.#entries.values()]\n .map((entry) => entry.message)\n .sort((a, b) => a.sentAt.getTime() - b.sentAt.getTime()),\n status: this.#status,\n };\n }\n\n #retain(): void {\n this.#subscribers++;\n if (this.#subscribers > 1 || !this._edgeClient) {\n return;\n }\n\n const ctx = new Context();\n const scheduler = new UpdateScheduler(ctx, () => this.#pull(ctx));\n this.#ctx = ctx;\n\n ctx.onDispose(this._identityManager.stateUpdate.on(() => scheduler.trigger()));\n if (this._pushSource) {\n ctx.onDispose(\n this._pushSource.onMessage((message) => {\n if (message.serviceId === EdgeService.INBOX) {\n scheduler.trigger();\n }\n }),\n );\n ctx.onDispose(this._pushSource.onReconnected(() => scheduler.trigger(), { emitCurrentState: false }));\n }\n const interval = setInterval(() => scheduler.trigger(), this._options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n ctx.onDispose(() => clearInterval(interval));\n scheduler.trigger();\n }\n\n async #release(): Promise<void> {\n this.#subscribers--;\n if (this.#subscribers > 0) {\n return;\n }\n const ctx = this.#ctx;\n this.#ctx = undefined;\n await ctx?.dispose();\n }\n\n /** Replaces the pending set with EDGE's, keeping only messages that verify. Never throws. */\n async #pull(ctx: Context): Promise<void> {\n const edgeClient = this._edgeClient;\n const identity = this._identityManager.identity;\n if (!edgeClient) {\n return;\n }\n if (!identity) {\n this.#entries = new Map();\n this.#publish();\n return;\n }\n\n let notices: readonly InboxNotice[];\n try {\n ({ notices } = await edgeClient.listInbox(ctx));\n } catch (error) {\n if (isAccountRequired(error)) {\n // Published only on the transition, so the slow poll does not re-announce it.\n if (this.#status !== 'account-required') {\n this.#status = 'account-required';\n this.#entries = new Map();\n this.#publish();\n }\n return;\n }\n // Offline or not yet authenticated: keep the last set and retry on the next trigger.\n log('inbox pull failed', { error });\n return;\n }\n this.#status = 'available';\n\n const now = new Date();\n const entries = new Map<string, Entry>();\n const rejected: string[] = [];\n for (const edgeNotice of notices) {\n if (this.#acked.has(edgeNotice.id)) {\n continue;\n }\n const result = await this.#classify(identity.identityKey, edgeNotice, now);\n if (result.kind === 'rejected') {\n log.warn('dropping inbox message', { id: edgeNotice.id, reason: result.reason });\n rejected.push(edgeNotice.id);\n continue;\n }\n if (result.kind === 'pending') {\n continue;\n }\n\n const { message } = result;\n const existing = entries.get(message.id);\n if (existing) {\n existing.edgeIds.add(edgeNotice.id);\n } else {\n // Keeps the previous pull's copy, since a converted legacy notice is rebuilt with a fresh object id.\n entries.set(message.id, {\n message: this.#entries.get(message.id)?.message ?? message,\n edgeIds: new Set([edgeNotice.id]),\n });\n }\n }\n\n // Acked ids EDGE no longer returns have been deleted there; forget them.\n const listed = new Set(notices.map((edgeNotice) => edgeNotice.id));\n [...this.#acked].filter((id) => !listed.has(id)).forEach((id) => this.#acked.delete(id));\n\n this.#entries = entries;\n this.#publish();\n\n if (rejected.length > 0) {\n await edgeClient\n .ackInbox(ctx, rejected)\n .catch((error) => log('inbox ack of rejected messages failed', { error }));\n }\n }\n\n /**\n * Decodes an EDGE entry as an envelope first, then as a legacy invitation credential.\n */\n async #classify(self: PublicKey, edgeNotice: InboxNotice, now: Date): Promise<Classified> {\n const bytes = Buffer.from(edgeNotice.payload, 'base64');\n const envelope = decodeInboxEnvelope(bytes);\n if (envelope) {\n if (envelope.version !== INBOX_ENVELOPE_VERSION) {\n return { kind: 'pending' };\n }\n const result = await verifyInboxEnvelope(envelope, {\n self,\n claimedSender: edgeNotice.senderDid,\n now,\n ttlMs: INBOX_ENVELOPE_TTL_MS,\n });\n if (result.kind === 'fail') {\n return { kind: 'rejected', reason: result.reason };\n }\n const { id, type, sender, payload, sentAt } = result.envelope;\n if (!KNOWN_TYPES.has(type)) {\n return { kind: 'pending' };\n }\n return { kind: 'message', message: { id, senderIdentityKey: sender, type, payload, sentAt } };\n }\n\n const credential = decodeCredential(edgeNotice.payload);\n if (!credential) {\n return { kind: 'rejected', reason: 'undecodable' };\n }\n const result = await verifySpaceInvitationNotice(credential, {\n self,\n claimedSender: edgeNotice.senderDid,\n now,\n ttlMs: SPACE_INVITATION_NOTICE_TTL_MS,\n });\n if (result.kind === 'fail') {\n return { kind: 'rejected', reason: result.reason };\n }\n return { kind: 'message', message: await legacyInvitationMessage(result.notice) };\n }\n\n #publish(): void {\n this.#loaded = true;\n this.#changed.emit(this.#snapshot());\n }\n}\n\nexport type InboxServiceLayerOptions = {\n /** Replaces EDGE, so the inbox works in tests without it. */\n relay?: InboxRelay;\n};\n\nexport const InboxServiceLayer = ({ relay }: InboxServiceLayerOptions = {}) =>\n Layer.effect(\n InboxService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n if (relay) {\n const { edgeClient, pushSource } = relay.connect(identityManager);\n return new InboxServiceImpl(identityManager, edgeClient, pushSource);\n }\n // Both are absent in the non-edge stack; the service then reports an empty inbox and refuses to send.\n const edgeClient = Option.getOrUndefined(yield* Effect.serviceOption(EdgeHttpClientService));\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n return new InboxServiceImpl(identityManager, edgeClient, edgeConnection);\n }),\n );\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { type Context } from '@dxos/context';\nimport { getCredentialAssertion } from '@dxos/credentials';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { type PublicKey } from '@dxos/keys';\nimport { AlreadyJoinedError } from '@dxos/protocols';\nimport { fromPublicKey, fromTimeframe, requirePublicKey, toTimeframe } from '@dxos/protocols/buf';\nimport { Invitation, Invitation_Kind } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport type { DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n type AdmissionRequest,\n AdmissionRequestSchema,\n type AdmissionResponse,\n AdmissionResponseSchema,\n DeviceAdmissionCredentialsSchema,\n DeviceAdmissionRequestSchema,\n type IntroductionRequest,\n IntroductionRequestSchema,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\n\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type JoinIdentityProps } from '../identity/index.ts';\n\nexport class DeviceInvitationProtocol implements InvitationProtocol {\n constructor(\n private readonly _keyring: KeyringApi,\n private readonly _getIdentity: () => Identity,\n private readonly _acceptIdentity: (identity: JoinIdentityProps) => Promise<Identity>,\n ) {}\n\n toJSON(): object {\n return {\n kind: 'device',\n };\n }\n\n checkCanInviteNewMembers(): Error | undefined {\n return undefined;\n }\n\n getInvitationContext(): Partial<Invitation> & Pick<Invitation, 'kind'> {\n return {\n kind: Invitation_Kind.DEVICE,\n };\n }\n\n async delegate(): Promise<PublicKey> {\n throw new Error('delegation not supported');\n }\n\n async cancelDelegation(): Promise<void> {\n throw new Error('delegation not supported');\n }\n\n async admit(_: Invitation, request: AdmissionRequest): Promise<AdmissionResponse> {\n invariant(request.kind.case === 'device');\n const identity = this._getIdentity();\n const credential = await identity.admitDevice(request.kind.value);\n invariant(\n getCredentialAssertion(credential).$typeName === 'dxos.halo.credentials.AuthorizedDevice',\n 'Invalid credential',\n );\n\n return create(AdmissionResponseSchema, {\n kind: {\n case: 'device',\n value: create(DeviceAdmissionCredentialsSchema, {\n identityKey: fromPublicKey(identity.identityKey),\n haloSpaceKey: fromPublicKey(identity.haloSpaceKey),\n genesisFeedKey: fromPublicKey(identity.haloGenesisFeedKey),\n controlTimeframe: fromTimeframe(identity.controlPipeline.state.timeframe),\n credential,\n // Absent while the host has not anchored its halo space yet; the joiner then has only the feed.\n haloSpaceRootUrl: identity.haloSpaceRootUrl,\n }),\n },\n });\n }\n\n checkInvitation(invitation: Partial<Invitation>): AlreadyJoinedError | undefined {\n try {\n const identity = this._getIdentity();\n if (identity) {\n return new AlreadyJoinedError({ message: 'Currently only one identity per client is supported.' });\n }\n } catch {\n // No identity.\n }\n }\n\n createIntroduction(): IntroductionRequest {\n return create(IntroductionRequestSchema, {});\n }\n\n async createAdmissionRequest(deviceProfile?: DeviceProfileDocument): Promise<AdmissionRequest> {\n const deviceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const dataFeedKey = await this._keyring.createKey();\n\n return create(AdmissionRequestSchema, {\n kind: {\n case: 'device',\n value: create(DeviceAdmissionRequestSchema, {\n deviceKey: fromPublicKey(deviceKey),\n controlFeedKey: fromPublicKey(controlFeedKey),\n dataFeedKey: fromPublicKey(dataFeedKey),\n profile: deviceProfile,\n }),\n },\n });\n }\n\n async accept(_ctx: Context, response: AdmissionResponse, request: AdmissionRequest): Promise<Partial<Invitation>> {\n invariant(response.kind.case === 'device');\n const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe, haloSpaceRootUrl, credential } =\n response.kind.value;\n\n invariant(request.kind.case === 'device');\n const { deviceKey, controlFeedKey, dataFeedKey, profile } = request.kind.value;\n\n // TODO(wittjosiah): When multiple identities are supported, verify identity doesn't already exist before accepting.\n // ctx is unused here because _acceptIdentity uses the identity lifecycle's own ctx internally.\n\n invariant(credential, 'Admission carries no credential.');\n const identityKeyValue = requirePublicKey(identityKey);\n await this._acceptIdentity({\n identityKey: identityKeyValue,\n deviceKey: requirePublicKey(deviceKey),\n haloSpaceKey: requirePublicKey(haloSpaceKey),\n haloGenesisFeedKey: requirePublicKey(genesisFeedKey),\n controlFeedKey: requirePublicKey(controlFeedKey),\n dataFeedKey: requirePublicKey(dataFeedKey),\n controlTimeframe: controlTimeframe && toTimeframe(controlTimeframe),\n deviceProfile: profile,\n authorizedDeviceCredential: credential,\n haloSpaceRootUrl,\n });\n\n return { identityKey: fromPublicKey(identityKeyValue) };\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Mutex, type MutexGuard } from '@dxos/async';\nimport { type Context, ContextDisposedError, cancelWithContext } from '@dxos/context';\nimport { bufWkt } from '@dxos/protocols/buf';\nimport { type Invitation, Invitation_State } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { SpaceMember_Role } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\n/** Names an invitation state for logging; falls back to `unknown` for a value outside the enum. */\nexport const stateToString = (state: Invitation_State): string => {\n return Object.entries(Invitation_State).find(([key, val]) => val === state)?.[0] ?? 'unknown';\n};\n\n/**\n * When the invitation expires, or `undefined` where it carries no lifetime.\n *\n * An invitation with no `created` timestamp is treated as created now, which is what the host does\n * when it mints one.\n */\nexport const computeExpirationTime = (invitation: Partial<Invitation>): Date | undefined => {\n if (!invitation.lifetime) {\n return;\n }\n const created = invitation.created ? Number(bufWkt.timestampMs(invitation.created)) : Date.now();\n return new Date(created + invitation.lifetime * 1000);\n};\n\nexport const tryAcquireBeforeContextDisposed = async (ctx: Context, mutex: Mutex): Promise<MutexGuard> => {\n let guard: MutexGuard | undefined;\n return cancelWithContext(\n ctx,\n (async () => {\n guard = await mutex.acquire();\n if (ctx.disposed) {\n guard.release();\n guard = undefined;\n throw new ContextDisposedError();\n }\n return guard;\n })(),\n );\n};\n\n/**\n * The role an invitation admits with.\n *\n * An invitation without a role admits an administrator, as it did before the role was carried.\n */\nexport const toSpaceMemberRole = (role: SpaceMember_Role | undefined): SpaceMember_Role =>\n role ?? SpaceMember_Role.ADMIN;\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { type Context } from '@dxos/context';\nimport {\n createCancelDelegatedSpaceInvitationCredential,\n createDelegatedSpaceInvitationCredential,\n credentialIdOf,\n credentialOfPayload,\n getCredentialAssertion,\n} from '@dxos/credentials';\nimport { writeMessages } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { AlreadyJoinedError, AuthorizationError, InvalidInvitationError, SpaceNotFoundError } from '@dxos/protocols';\nimport {\n fromDate,\n fromPublicKey,\n fromTimeframe,\n requirePublicKey,\n toPublicKey,\n toTimeframe,\n} from '@dxos/protocols/buf';\nimport {\n Invitation,\n Invitation_AuthMethod,\n Invitation_Kind,\n Invitation_Type,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type ProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { DelegateSpaceInvitationSchema } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport {\n type AdmissionRequest,\n AdmissionRequestSchema,\n type AdmissionResponse,\n AdmissionResponseSchema,\n type IntroductionRequest,\n IntroductionRequestSchema,\n SpaceAdmissionCredentialsSchema,\n SpaceAdmissionRequestSchema,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\n\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport { type SigningContext } from '../spaces/index.ts';\nimport { computeExpirationTime, toSpaceMemberRole } from './utils.ts';\n\nexport class SpaceInvitationProtocol implements InvitationProtocol {\n constructor(\n private readonly _spaceManager: SpacesContract.Manager,\n private readonly _signingContext: SigningContext,\n private readonly _keyring: KeyringApi,\n private readonly _spaceKey?: PublicKey,\n ) {}\n\n toJSON(): object {\n return {\n kind: 'space',\n deviceKey: this._signingContext.deviceKey,\n spaceKey: this._spaceKey,\n };\n }\n\n checkCanInviteNewMembers(): Error | undefined {\n if (this._spaceKey == null) {\n return new InvalidInvitationError({ message: 'No spaceKey was provided for a space invitation.' });\n }\n const space = this._spaceManager.spaces.get(this._spaceKey);\n if (space == null) {\n return new SpaceNotFoundError(this._spaceKey);\n }\n if (!space?.inner.spaceState.hasMembershipManagementPermission(this._signingContext.identityKey)) {\n return new AuthorizationError({ message: 'No member management permission.' });\n }\n return undefined;\n }\n\n getInvitationContext(): Partial<Invitation> & Pick<Invitation, 'kind'> {\n invariant(this._spaceKey);\n const space = this._spaceManager.spaces.get(this._spaceKey);\n invariant(space);\n return {\n kind: Invitation_Kind.SPACE,\n spaceKey: fromPublicKey(this._spaceKey),\n spaceId: space.id,\n };\n }\n\n async admit(\n invitation: Invitation,\n request: AdmissionRequest,\n guestProfile?: ProfileDocument | undefined,\n ): Promise<AdmissionResponse> {\n invariant(this._spaceKey && request.kind.case === 'space');\n const spaceRequest = request.kind.value;\n log('writing guest credentials', { host: this._signingContext.deviceKey, guest: spaceRequest.deviceKey });\n\n const spaceMemberCredential = await this._spaceManager.admitMember({\n spaceKey: this._spaceKey,\n identityKey: requirePublicKey(spaceRequest.identityKey),\n role: toSpaceMemberRole(invitation.role),\n profile: guestProfile,\n delegationCredentialId: toPublicKey(invitation.delegationCredentialId),\n });\n\n const space = this._spaceManager.spaces.get(this._spaceKey);\n const controlTimeframe = space?.inner.controlPipeline.state.timeframe;\n return create(AdmissionResponseSchema, {\n kind: {\n case: 'space',\n value: create(SpaceAdmissionCredentialsSchema, {\n credential: spaceMemberCredential,\n controlTimeframe: controlTimeframe && fromTimeframe(controlTimeframe),\n }),\n },\n });\n }\n\n async delegate(invitation: Invitation): Promise<PublicKey> {\n invariant(this._spaceKey);\n const space = this._spaceManager.spaces.get(this._spaceKey);\n invariant(space);\n if (invitation.authMethod === Invitation_AuthMethod.KNOWN_PUBLIC_KEY) {\n invariant(invitation.guestKeypair?.publicKey);\n }\n\n log('writing delegate space invitation', { host: this._signingContext.deviceKey, id: invitation.invitationId });\n const swarmKey = toPublicKey(invitation.swarmKey);\n invariant(swarmKey, 'swarmKey missing in the invitation');\n const expiresOn = computeExpirationTime(invitation);\n const credential = await createDelegatedSpaceInvitationCredential(\n this._signingContext.credentialSigner,\n space.key,\n create(DelegateSpaceInvitationSchema, {\n invitationId: invitation.invitationId,\n authMethod: invitation.authMethod,\n swarmKey: fromPublicKey(swarmKey),\n role: toSpaceMemberRole(invitation.role),\n expiresOn: expiresOn && fromDate(expiresOn),\n multiUse: invitation.multiUse ?? false,\n guestKey:\n invitation.authMethod === Invitation_AuthMethod.KNOWN_PUBLIC_KEY\n ? invitation.guestKeypair?.publicKey\n : undefined,\n }),\n );\n\n await writeMessages(space.inner.controlPipeline.writer, [credential]);\n return credentialIdOf(credentialOfPayload(credential));\n }\n\n async cancelDelegation(invitation: Invitation): Promise<void> {\n invariant(this._spaceKey);\n invariant(invitation.type === Invitation_Type.DELEGATED && invitation.delegationCredentialId);\n const delegationCredentialId = toPublicKey(invitation.delegationCredentialId);\n invariant(delegationCredentialId);\n const space = this._spaceManager.spaces.get(this._spaceKey);\n invariant(space);\n\n log('cancelling delegated space invitation', { host: this._signingContext.deviceKey, id: invitation.invitationId });\n const credential = await createCancelDelegatedSpaceInvitationCredential(\n this._signingContext.credentialSigner,\n space.key,\n delegationCredentialId,\n );\n\n await writeMessages(space.inner.controlPipeline.writer, [credential]);\n }\n\n checkInvitation(invitation: Partial<Invitation>): InvalidInvitationError | AlreadyJoinedError | undefined {\n if (invitation.spaceKey == null) {\n return new InvalidInvitationError({ message: 'No spaceKey was provided for a space invitation.' });\n }\n const spaceKey = toPublicKey(invitation.spaceKey);\n if (spaceKey && this._spaceManager.spaces.has(spaceKey)) {\n return new AlreadyJoinedError({ message: 'Already joined space.' });\n }\n }\n\n createIntroduction(): IntroductionRequest {\n return create(IntroductionRequestSchema, { profile: this._signingContext.getProfile() });\n }\n\n async createAdmissionRequest(): Promise<AdmissionRequest> {\n // Generate a pair of keys for our feeds.\n const controlFeedKey = await this._keyring.createKey();\n const dataFeedKey = await this._keyring.createKey();\n\n return create(AdmissionRequestSchema, {\n kind: {\n case: 'space',\n value: create(SpaceAdmissionRequestSchema, {\n identityKey: fromPublicKey(this._signingContext.identityKey),\n deviceKey: fromPublicKey(this._signingContext.deviceKey),\n controlFeedKey: fromPublicKey(controlFeedKey),\n dataFeedKey: fromPublicKey(dataFeedKey),\n }),\n },\n });\n }\n\n async accept(ctx: Context, response: AdmissionResponse): Promise<Partial<Invitation>> {\n invariant(response.kind.case === 'space');\n const { credential, controlTimeframe, dataTimeframe } = response.kind.value;\n invariant(credential, 'Admission carries no credential.');\n const assertion = getCredentialAssertion(credential);\n invariant(assertion.$typeName === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');\n invariant(requirePublicKey(credential.subject?.id).equals(this._signingContext.identityKey));\n\n const spaceKey = requirePublicKey(assertion.spaceKey);\n if (this._spaceManager.spaces.has(spaceKey)) {\n throw new AlreadyJoinedError({ message: 'Already joined space.' });\n }\n\n // Create local space.\n await this._spaceManager.acceptSpace(ctx, {\n spaceKey,\n genesisFeedKey: requirePublicKey(assertion.genesisFeedKey),\n spaceRootUrl: assertion.spaceRootUrl,\n controlTimeframe: controlTimeframe && toTimeframe(controlTimeframe),\n dataTimeframe: dataTimeframe && toTimeframe(dataTimeframe),\n tags: assertion.tags,\n });\n\n await this._signingContext.recordCredential(credential);\n\n return { spaceKey: fromPublicKey(spaceKey) };\n }\n}\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { failUndefined } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { KeyringApiService } from '@dxos/keyring';\nimport { toPublicKey } from '@dxos/protocols/buf';\nimport { type Invitation, Invitation_Kind } from '@dxos/protocols/buf/dxos/client/invitation_pb';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport * as InvitationsContract from '../../contracts/invitations.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport { DeviceInvitationProtocol } from './device-invitation-protocol.ts';\nimport { SpaceInvitationProtocol } from './space-invitation-protocol.ts';\n\n/**\n * Wires the per-kind invitation protocol factories into the invitations manager. Sits above the\n * data space manager because the space protocol needs it, while the manager itself is below.\n */\nexport const InvitationFactoriesLayer: Layer.Layer<\n never,\n never,\n | InvitationsContract.ManagerService\n | IdentityContract.ManagerService\n | IdentityContract.LifecycleService\n | KeyringApiService\n | SpacesContract.ManagerService\n | SpacesContract.SigningContextProviderService\n> = Layer.effectDiscard(\n Effect.gen(function* () {\n const invitationsManager = yield* InvitationsContract.ManagerService;\n const identityManager = yield* IdentityContract.ManagerService;\n const identityLifecycle = yield* IdentityContract.LifecycleService;\n const keyring = yield* KeyringApiService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const signingContextProvider = yield* SpacesContract.SigningContextProviderService;\n\n const factories = new Map<Invitation_Kind, (invitation: Partial<Invitation>) => InvitationProtocol>([\n [\n Invitation_Kind.DEVICE,\n () =>\n new DeviceInvitationProtocol(\n keyring,\n () => identityManager.identity ?? failUndefined(),\n (params) => identityLifecycle.acceptIdentity(params),\n ),\n ],\n [\n Invitation_Kind.SPACE,\n (invitation) =>\n new SpaceInvitationProtocol(\n dataSpaceManager,\n signingContextProvider(),\n keyring,\n toPublicKey(invitation.spaceKey),\n ),\n ],\n ]);\n\n invitationsManager.setInvitationHandlerFactory((invitation) => {\n if (identityManager.identity == null && invitation.kind === Invitation_Kind.SPACE) {\n throw new Error('Identity must be created before joining a space.');\n }\n const factory = factories.get(invitation.kind);\n invariant(factory, `Unknown invitation kind: ${invitation.kind}`);\n return factory(invitation);\n });\n }),\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create, fromBinary } from '@bufbuild/protobuf';\n\nimport { type MutexGuard, scheduleMicroTask, scheduleTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { sign } from '@dxos/crypto';\nimport { type EdgeHttpClient } from '@dxos/edge-client';\nimport { invariant } from '@dxos/invariant';\nimport { SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n EdgeAuthChallengeError,\n EdgeCallFailedError,\n type JoinSpaceRequest,\n type JoinSpaceResponseBody,\n} from '@dxos/protocols';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport {\n Invitation_AuthMethod,\n Invitation_Kind,\n Invitation_State,\n Invitation_Type,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { CredentialSchema, type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n type AdmissionRequest,\n AdmissionRequestSchema,\n type AdmissionResponse,\n AdmissionResponseSchema,\n SpaceAdmissionCredentialsSchema,\n type SpaceAdmissionRequest,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { trace } from '@dxos/tracing';\n\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport { type FlowLockHolder, type GuardedInvitationState } from './invitation-state.ts';\nimport { tryAcquireBeforeContextDisposed } from './utils.ts';\n\nexport interface EdgeInvitationHandlerCallbacks {\n onInvitationSuccess(ctx: Context, response: AdmissionResponse, request: AdmissionRequest): Promise<void>;\n}\n\nexport const MAX_RETRIES_PER_INVITATION = 5;\nexport const DEFAULT_REQUEST_RETRY_INTERVAL_MS = 3000;\nexport const DEFAULT_REQUEST_RETRY_JITTER_MS = 500;\n\nexport type EdgeInvitationConfig = {\n retryInterval?: number;\n retryJitter?: number;\n};\n\nexport class EdgeInvitationHandler implements FlowLockHolder {\n private _flowLock: MutexGuard | undefined;\n\n private readonly _retryInterval: number;\n private readonly _retryJitter: number;\n\n constructor(\n config: EdgeInvitationConfig | undefined,\n private readonly _client: EdgeHttpClient | undefined,\n private readonly _callbacks: EdgeInvitationHandlerCallbacks,\n ) {\n this._retryInterval = config?.retryInterval ?? DEFAULT_REQUEST_RETRY_INTERVAL_MS;\n this._retryJitter = config?.retryJitter ?? DEFAULT_REQUEST_RETRY_JITTER_MS;\n }\n\n public handle(\n ctx: Context,\n guardedState: GuardedInvitationState,\n protocol: InvitationProtocol,\n deviceProfile?: DeviceProfileDocument,\n ): void {\n if (!this._client) {\n log('edge disabled');\n return;\n }\n\n const invitation = guardedState.current;\n const spaceId = invitation.spaceId;\n const canBeHandledByEdge =\n invitation.authMethod !== Invitation_AuthMethod.SHARED_SECRET &&\n invitation.type === Invitation_Type.DELEGATED &&\n invitation.kind === Invitation_Kind.SPACE &&\n spaceId != null &&\n SpaceId.isValid(spaceId);\n\n if (!canBeHandledByEdge) {\n log('invitation could not be handled by edge', { invitation });\n return;\n }\n\n ctx.onDispose(() => {\n this._flowLock?.release();\n this._flowLock = undefined;\n });\n\n let requestCount = 0;\n const tryHandleInvitation = async () => {\n requestCount++;\n const admissionRequest = await protocol.createAdmissionRequest(deviceProfile);\n if (admissionRequest.kind.case === 'space') {\n const spaceRequest = admissionRequest.kind.value;\n try {\n await this._handleSpaceInvitationFlow(ctx, guardedState, spaceRequest, spaceId);\n } catch (error) {\n if (error instanceof EdgeCallFailedError) {\n log.info('join space with edge unsuccessful', {\n reason: error.message,\n retryable: error.isRetryable,\n after: error.retryAfterMs ?? this._calculateNextRetryMs(),\n });\n if (error.isRetryable && requestCount < MAX_RETRIES_PER_INVITATION) {\n scheduleTask(ctx, tryHandleInvitation, error.retryAfterMs ?? this._calculateNextRetryMs());\n }\n } else if (requestCount < MAX_RETRIES_PER_INVITATION) {\n log.info('failed to handle invitation with edge', { error });\n scheduleTask(ctx, tryHandleInvitation, this._calculateNextRetryMs());\n }\n }\n }\n };\n scheduleMicroTask(ctx, tryHandleInvitation);\n }\n\n @trace.span({ op: 'invitation.edge' })\n private async _handleSpaceInvitationFlow(\n ctx: Context,\n guardedState: GuardedInvitationState,\n admissionRequest: SpaceAdmissionRequest,\n spaceId: SpaceId,\n ): Promise<void> {\n try {\n log('edge invitation flow');\n this._flowLock = await tryAcquireBeforeContextDisposed(ctx, guardedState.mutex);\n log.verbose('edge invitation flow acquired the lock');\n\n guardedState.set(this, Invitation_State.CONNECTING);\n\n const response = await this._joinSpaceByInvitation(ctx, guardedState, spaceId, {\n identityKey: requirePublicKey(admissionRequest.identityKey).toHex(),\n invitationId: guardedState.current.invitationId,\n });\n\n const admissionResponse = await this._mapToAdmissionResponse(response);\n await this._callbacks.onInvitationSuccess(\n ctx,\n admissionResponse,\n create(AdmissionRequestSchema, { kind: { case: 'space', value: admissionRequest } }),\n );\n } catch (error) {\n guardedState.set(this, Invitation_State.ERROR);\n throw error;\n } finally {\n this._flowLock?.release();\n this._flowLock = undefined;\n }\n }\n\n private async _mapToAdmissionResponse(edgeResponse: JoinSpaceResponseBody): Promise<AdmissionResponse> {\n const credentialBytes = Buffer.from(edgeResponse.spaceMemberCredential, 'base64');\n return create(AdmissionResponseSchema, {\n kind: {\n case: 'space',\n value: create(SpaceAdmissionCredentialsSchema, {\n credential: fromBinary(CredentialSchema, credentialBytes),\n }),\n },\n });\n }\n\n private async _joinSpaceByInvitation(\n ctx: Context,\n guardedState: GuardedInvitationState,\n spaceId: SpaceId,\n request: JoinSpaceRequest,\n ): Promise<JoinSpaceResponseBody> {\n invariant(this._client);\n try {\n return await this._client.joinSpaceByInvitation(ctx, spaceId, request);\n } catch (error: any) {\n if (error instanceof EdgeAuthChallengeError) {\n const publicKey = guardedState.current.guestKeypair?.publicKey;\n const privateKey = guardedState.current.guestKeypair?.privateKey;\n if (!privateKey || !publicKey) {\n throw error;\n }\n const signature = sign(Buffer.from(error.challenge, 'base64'), Buffer.from(privateKey.data));\n return this._client.joinSpaceByInvitation(ctx, spaceId, {\n ...request,\n signature: Buffer.from(signature).toString('base64'),\n });\n } else {\n throw error;\n }\n }\n }\n\n public hasFlowLock(): boolean {\n return this._flowLock != null;\n }\n\n private _calculateNextRetryMs(): number {\n return this._retryInterval + Math.random() * this._retryJitter;\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport { EmptySchema } from '@bufbuild/protobuf/wkt';\n\nimport { type Mutex, type MutexGuard, Trigger } from '@dxos/async';\nimport { Context, cancelWithContext } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { InvalidInvitationExtensionRoleError } from '@dxos/protocols';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport { Invitation_State } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n InvitationHostService as InvitationHostServiceDesc,\n type InvitationOptions,\n InvitationOptions_Role,\n InvitationOptionsSchema,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\n\nimport { type FlowLockHolder } from './invitation-state.ts';\nimport { tryAcquireBeforeContextDisposed } from './utils.ts';\n\ntype InvitationHostService = BufService<typeof InvitationHostServiceDesc>;\n\nconst OPTIONS_TIMEOUT = 10_000;\n\ntype InvitationGuestExtensionCallbacks = {\n // Deliberately not async to not block the extensions opening.\n onOpen: (ctx: Context, extensionCtx: ExtensionContext) => void;\n onError: (error: Error) => void;\n\n onStateUpdate: (newState: Invitation_State) => void;\n};\n\n/**\n * Guest's side for a connection to a concrete peer in p2p network during invitation.\n */\nexport class InvitationGuestExtension\n extends RpcExtension<\n { InvitationHostService: InvitationHostService },\n { InvitationHostService: InvitationHostService }\n >\n implements FlowLockHolder\n{\n private _ctx = new Context();\n private _remoteOptions?: InvitationOptions;\n private _remoteOptionsTrigger = new Trigger();\n /**\n * Held to allow only one invitation flow at a time to be active.\n */\n private _invitationFlowLock: MutexGuard | null = null;\n\n constructor(\n private readonly _invitationFlowMutex: Mutex,\n private readonly _callbacks: InvitationGuestExtensionCallbacks,\n ) {\n super({\n requested: {\n InvitationHostService: getBufService<InvitationHostService>('dxos.halo.invitations.InvitationHostService'),\n },\n exposed: {\n InvitationHostService: getBufService<InvitationHostService>('dxos.halo.invitations.InvitationHostService'),\n },\n });\n }\n\n public hasFlowLock(): boolean {\n return this._invitationFlowLock != null;\n }\n\n protected override async getHandlers(): Promise<{ InvitationHostService: InvitationHostService }> {\n return {\n InvitationHostService: {\n options: async (options) => {\n invariant(!this._remoteOptions, 'Remote options already set.');\n this._remoteOptions = options;\n this._remoteOptionsTrigger.wake();\n return create(EmptySchema, {});\n },\n introduce: () => {\n throw new Error('Method not allowed.');\n },\n authenticate: () => {\n throw new Error('Method not allowed.');\n },\n admit: () => {\n throw new Error('Method not allowed.');\n },\n },\n };\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n await super.onOpen(context);\n\n try {\n log.verbose('guest acquire lock');\n this._invitationFlowLock = await tryAcquireBeforeContextDisposed(this._ctx, this._invitationFlowMutex);\n log.verbose('guest lock acquired');\n await cancelWithContext(\n this._ctx,\n this.rpc.InvitationHostService.options(create(InvitationOptionsSchema, { role: InvitationOptions_Role.GUEST })),\n );\n log.verbose('options sent');\n await cancelWithContext(this._ctx, this._remoteOptionsTrigger.wait({ timeout: OPTIONS_TIMEOUT }));\n log.verbose('options received');\n if (this._remoteOptions?.role !== InvitationOptions_Role.HOST) {\n throw new InvalidInvitationExtensionRoleError({\n context: {\n expected: InvitationOptions_Role.HOST,\n remoteOptions: this._remoteOptions,\n remotePeerId: context.remotePeerId,\n },\n });\n }\n\n this._callbacks.onOpen(this._ctx, context);\n } catch (err: any) {\n if (this._invitationFlowLock != null) {\n this._callbacks.onError(err);\n }\n if (!this._ctx.disposed) {\n context.close(err);\n }\n }\n }\n\n override async onClose(): Promise<void> {\n await this._destroy();\n }\n\n override async onAbort(): Promise<void> {\n await this._destroy();\n }\n\n private async _destroy(): Promise<void> {\n await this._ctx.dispose();\n if (this._invitationFlowLock != null) {\n this._invitationFlowLock.release();\n this._invitationFlowLock = null;\n log.verbose('invitation flow lock released');\n }\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport { EmptySchema } from '@bufbuild/protobuf/wkt';\n\nimport { type Mutex, type MutexGuard, Trigger, asyncTimeout, scheduleTask } from '@dxos/async';\nimport { Context, cancelWithContext } from '@dxos/context';\nimport { randomBytes, verify } from '@dxos/crypto';\nimport { InvariantViolation, invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { InvalidInvitationExtensionRoleError } from '@dxos/protocols';\nimport { toPublicKey } from '@dxos/protocols/buf';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport { Invitation, Invitation_AuthMethod, Invitation_State } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type ProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n type AdmissionRequest,\n type AdmissionResponse,\n AuthenticationResponse_Status,\n AuthenticationResponseSchema,\n IntroductionResponseSchema,\n InvitationHostService as InvitationHostServiceDesc,\n type InvitationOptions,\n InvitationOptions_Role,\n InvitationOptionsSchema,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\n\nimport type { FlowLockHolder } from './invitation-state.ts';\n\ntype InvitationHostService = BufService<typeof InvitationHostServiceDesc>;\nimport { stateToString, tryAcquireBeforeContextDisposed } from './utils.ts';\n\n/// Timeout for the options exchange.\nconst OPTIONS_TIMEOUT = 10_000;\n\nexport const MAX_OTP_ATTEMPTS = 3;\n\ntype InvitationHostExtensionCallbacks = {\n activeInvitation: Invitation | null;\n\n // Deliberately not async to not block the extensions opening.\n onOpen: (ctx: Context, extensionCtx: ExtensionContext) => void;\n onError: (error: Error) => void;\n\n onStateUpdate: (newState: Invitation_State) => void;\n\n admit: (request: AdmissionRequest) => Promise<AdmissionResponse>;\n};\n\n/**\n * Host's side for a connection to a concrete peer in p2p network during invitation.\n */\nexport class InvitationHostExtension\n extends RpcExtension<\n { InvitationHostService: InvitationHostService },\n { InvitationHostService: InvitationHostService }\n >\n implements FlowLockHolder\n{\n /**\n * @internal\n */\n private _ctx = new Context();\n private _remoteOptions?: InvitationOptions;\n private _remoteOptionsTrigger = new Trigger();\n\n private _challenge?: Buffer = undefined;\n\n public guestProfile?: ProfileDocument = undefined;\n\n public authenticationPassed = false;\n\n /**\n * Retry counter for SHARED_SECRET authentication method.\n */\n public authenticationRetry = 0;\n\n /**\n * Resolved when admission is completed.\n */\n public completedTrigger = new Trigger<PublicKey>();\n\n /**\n * Held to allow only one invitation flow at a time to be active.\n */\n private _invitationFlowLock: MutexGuard | null = null;\n /**\n * The last state THIS connection tried to set, as opposed to the invitation-wide shared state.\n * Records the attempt, not the guard's acceptance, so the two can differ when a write was rejected.\n */\n private _lastSetState: Invitation_State = Invitation_State.INIT;\n\n constructor(\n private readonly _invitationFlowMutex: Mutex,\n private readonly _callbacks: InvitationHostExtensionCallbacks,\n ) {\n super({\n requested: {\n InvitationHostService: getBufService<InvitationHostService>('dxos.halo.invitations.InvitationHostService'),\n },\n exposed: {\n InvitationHostService: getBufService<InvitationHostService>('dxos.halo.invitations.InvitationHostService'),\n },\n });\n }\n\n private _setState(state: Invitation_State): void {\n this._lastSetState = state;\n this._callbacks.onStateUpdate(state);\n }\n\n public hasFlowLock(): boolean {\n return this._invitationFlowLock != null;\n }\n\n protected override async getHandlers(): Promise<{ InvitationHostService: InvitationHostService }> {\n return {\n // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.\n // Perhaps in the future we will have more complex logic here.\n InvitationHostService: {\n options: async (options) => {\n invariant(!this._remoteOptions, 'Remote options already set.');\n this._remoteOptions = options;\n if (options.role === InvitationOptions_Role.GUEST && this.hasFlowLock()) {\n this._setState(Invitation_State.CONNECTED);\n }\n this._remoteOptionsTrigger.wake();\n return create(EmptySchema, {});\n },\n\n introduce: async (request) => {\n const { profile, invitationId } = request;\n log('introducing host invitation');\n\n const invitation = this._requireActiveInvitation();\n this._assertInvitationState(Invitation_State.CONNECTED);\n if (invitationId !== invitation?.invitationId) {\n log.warn('incorrect invitationId', { expected: invitation.invitationId, actual: invitationId });\n this._callbacks.onError(new Error('Incorrect invitationId.'));\n scheduleTask(this._ctx, () => this.close());\n // TODO(dmaretskyi): Better error handling.\n return create(IntroductionResponseSchema, { authMethod: Invitation_AuthMethod.NONE });\n }\n\n log.verbose('guest introduced themselves', { guestProfile: profile });\n this.guestProfile = profile;\n this._setState(Invitation_State.READY_FOR_AUTHENTICATION);\n this._challenge =\n invitation.authMethod === Invitation_AuthMethod.KNOWN_PUBLIC_KEY ? randomBytes(32) : undefined;\n\n log('introduced host invitation');\n return create(IntroductionResponseSchema, {\n authMethod: invitation.authMethod,\n challenge: this._challenge,\n });\n },\n\n authenticate: async ({ authCode: code, signedChallenge }) => {\n log('authenticating host invitation');\n\n const invitation = this._requireActiveInvitation();\n log.verbose('received authentication request', { authCode: code });\n let status = AuthenticationResponse_Status.OK;\n\n this._assertInvitationState([Invitation_State.AUTHENTICATING, Invitation_State.READY_FOR_AUTHENTICATION]);\n this._setState(Invitation_State.AUTHENTICATING);\n\n switch (invitation.authMethod) {\n case Invitation_AuthMethod.NONE: {\n log('authentication not required');\n return create(AuthenticationResponseSchema, { status: AuthenticationResponse_Status.OK });\n }\n\n case Invitation_AuthMethod.SHARED_SECRET: {\n if (invitation.authCode) {\n if (this.authenticationRetry++ > MAX_OTP_ATTEMPTS) {\n status = AuthenticationResponse_Status.INVALID_OPT_ATTEMPTS;\n } else if (code !== invitation.authCode) {\n status = AuthenticationResponse_Status.INVALID_OTP;\n } else {\n this.authenticationPassed = true;\n }\n }\n break;\n }\n\n case Invitation_AuthMethod.KNOWN_PUBLIC_KEY: {\n const guestPublicKey = toPublicKey(invitation.guestKeypair?.publicKey);\n if (!guestPublicKey) {\n status = AuthenticationResponse_Status.INTERNAL_ERROR;\n break;\n }\n const isSignatureValid =\n this._challenge &&\n verify(this._challenge, Buffer.from(signedChallenge ?? []), guestPublicKey.asBuffer());\n if (isSignatureValid) {\n this.authenticationPassed = true;\n } else {\n status = AuthenticationResponse_Status.INVALID_SIGNATURE;\n }\n break;\n }\n\n default: {\n log.error('invalid authentication method', { authMethod: invitation.authMethod });\n status = AuthenticationResponse_Status.INTERNAL_ERROR;\n break;\n }\n }\n\n if (![AuthenticationResponse_Status.OK, AuthenticationResponse_Status.INVALID_OTP].includes(status)) {\n this._callbacks.onError(new Error(`Authentication failed, with status=${status}`));\n scheduleTask(this._ctx, () => this.close());\n return create(AuthenticationResponseSchema, { status });\n }\n\n log('authenticated host invitation', { status });\n return create(AuthenticationResponseSchema, { status });\n },\n\n admit: async (request) => {\n log('admitting guest');\n const invitation = this._requireActiveInvitation();\n\n try {\n // Check authenticated.\n if (isAuthenticationRequired(invitation)) {\n this._assertInvitationState(Invitation_State.AUTHENTICATING);\n if (!this.authenticationPassed) {\n throw new Error('Not authenticated');\n }\n }\n\n const response = await this._callbacks.admit(request);\n\n log('admitted guest');\n return response;\n } catch (err: any) {\n this._callbacks.onError(err);\n throw err;\n }\n },\n },\n };\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n await super.onOpen(context);\n\n try {\n log.verbose('host acquire lock');\n this._invitationFlowLock = await tryAcquireBeforeContextDisposed(this._ctx, this._invitationFlowMutex);\n log.verbose('host lock acquired');\n this._setState(Invitation_State.CONNECTING);\n const optionsAcknowledged = this.rpc.InvitationHostService.options(\n create(InvitationOptionsSchema, { role: InvitationOptions_Role.HOST }),\n );\n void optionsAcknowledged.catch(() => {});\n log.verbose('options sent');\n await cancelWithContext(this._ctx, this._remoteOptionsTrigger.wait({ timeout: OPTIONS_TIMEOUT }));\n log.verbose('options received');\n if (this._remoteOptions?.role !== InvitationOptions_Role.GUEST) {\n throw new InvalidInvitationExtensionRoleError({\n context: {\n expected: InvitationOptions_Role.GUEST,\n remoteOptions: this._remoteOptions,\n remotePeerId: context.remotePeerId,\n },\n });\n }\n // Only while the flow is still where this method left it. When `options` and `introduce` are\n // dispatched in one drain — the overtaking this whole path exists to survive — the handlers\n // have already carried the state past CONNECTED, and re-emitting it here would rewind them.\n if (this._lastSetState === Invitation_State.CONNECTING) {\n this._setState(Invitation_State.CONNECTED);\n }\n // Bounded like the trigger above: a guest that never acknowledges must fail the invitation,\n // not leave it displayed as live with `onOpen` never reached.\n await cancelWithContext(this._ctx, asyncTimeout(optionsAcknowledged, OPTIONS_TIMEOUT));\n this._callbacks.onOpen(this._ctx, context);\n } catch (err: any) {\n if (this._invitationFlowLock != null) {\n this._callbacks.onError(err);\n }\n if (!this._ctx.disposed) {\n context.close(err);\n }\n }\n }\n\n private _requireActiveInvitation(): Invitation {\n const invitation = this._callbacks.activeInvitation;\n if (invitation == null) {\n scheduleTask(this._ctx, () => this.close());\n throw new Error('Active invitation not found');\n }\n return invitation;\n }\n\n private _assertInvitationState(stateOrMany: Invitation_State | Invitation_State[]): void {\n const invitation = this._requireActiveInvitation();\n const validStates = Array.isArray(stateOrMany) ? stateOrMany : [stateOrMany];\n if (!validStates.includes(invitation.state)) {\n scheduleTask(this._ctx, () => this.close());\n throw new InvariantViolation(\n `Expected ${stateToString(invitation.state)} to be one of [${validStates.map(stateToString).join(', ')}]`,\n );\n }\n }\n\n override async onClose(): Promise<void> {\n await this._destroy();\n }\n\n override async onAbort(): Promise<void> {\n await this._destroy();\n }\n\n private async _destroy(): Promise<void> {\n await this._ctx.dispose();\n if (this._invitationFlowLock != null) {\n this._invitationFlowLock?.release();\n this._invitationFlowLock = null;\n log.verbose('invitation flow lock released');\n }\n }\n}\n\nexport const isAuthenticationRequired = (invitation: Invitation) =>\n invitation.authMethod !== Invitation_AuthMethod.NONE;\n","/**\n * A utility object for serializing invitation state changes by multiple concurrent\n * invitation flow connections.\n */\n//\n// Copyright 2024 DXOS.org\n//\n\nimport { Mutex, type PushStream } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\nimport { Invitation, Invitation_State } from '@dxos/protocols/buf/dxos/client/invitation_pb';\n\nimport { stateToString } from './utils.ts';\n\nexport interface FlowLockHolder {\n hasFlowLock(): boolean;\n}\n\nexport interface GuardedInvitationState {\n mutex: Mutex;\n current: Invitation;\n\n complete(newState: Partial<Invitation>): void;\n set(lockHolder: FlowLockHolder | null, newState: Invitation_State): boolean;\n error(lockHolder: FlowLockHolder | null, error: any): boolean;\n}\n\nexport const createGuardedInvitationState = (\n ctx: Context,\n invitation: Invitation,\n stream: PushStream<Invitation>,\n): GuardedInvitationState => {\n const mutex = new Mutex();\n let lastActiveLockHolder: FlowLockHolder | null = null;\n let currentInvitation = { ...invitation };\n const isStateChangeAllowed = (lockHolder: FlowLockHolder | null) => {\n if (ctx.disposed || (lockHolder !== null && mutex.isLocked() && !lockHolder.hasFlowLock())) {\n return false;\n }\n return lockHolder == null || lastActiveLockHolder !== lockHolder || isNonTerminalState(currentInvitation.state);\n };\n return {\n mutex,\n get current() {\n return currentInvitation;\n },\n complete: (newState: Partial<Invitation>) => {\n logStateUpdate(currentInvitation, undefined, invitation.state);\n currentInvitation = { ...currentInvitation, ...newState };\n stream.next(currentInvitation);\n return ctx.dispose();\n },\n set: (lockHolder: FlowLockHolder | null, newState: Invitation_State): boolean => {\n if (isStateChangeAllowed(lockHolder)) {\n logStateUpdate(currentInvitation, lockHolder, newState);\n currentInvitation = { ...currentInvitation, state: newState };\n stream.next(currentInvitation);\n lastActiveLockHolder = lockHolder;\n return true;\n }\n return false;\n },\n error: (lockHolder: FlowLockHolder | null, error: any): boolean => {\n if (isStateChangeAllowed(lockHolder)) {\n logStateUpdate(currentInvitation, lockHolder, Invitation_State.ERROR, error);\n currentInvitation = { ...currentInvitation, state: Invitation_State.ERROR };\n stream.next(currentInvitation);\n stream.error(error);\n lastActiveLockHolder = lockHolder;\n return true;\n }\n return false;\n },\n };\n};\n\n/** How a flow ended, from its last state; a flow disposed before a terminal state is `closed`. */\nexport const getInvitationOutcome = (state: Invitation_State): string =>\n isNonTerminalState(state) ? 'closed' : Invitation_State[state].toLowerCase();\n\nconst logStateUpdate = (\n invitation: Invitation,\n actor: FlowLockHolder | null | undefined,\n newState: Invitation_State,\n error?: Error,\n) => {\n const logContext = {\n invitationId: invitation.invitationId,\n actor: actor?.constructor.name,\n newState: stateToString(newState),\n oldState: stateToString(invitation.state),\n error: error?.message,\n errorStack: error?.stack,\n };\n log.verbose('dxos.sdk.invitations-handler.state.update', logContext);\n};\n\nconst isNonTerminalState = (currentState: Invitation_State): boolean => {\n return ![\n Invitation_State.SUCCESS,\n Invitation_State.ERROR,\n Invitation_State.CANCELLED,\n Invitation_State.TIMEOUT,\n Invitation_State.EXPIRED,\n ].includes(currentState);\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport type { SwarmController, Topology } from '@dxos/network-manager';\nimport { InvitationOptions_Role } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\n/** Connections a host starts to one peer before it stops retrying that peer. */\nconst MAX_DIALS_PER_PEER = 3;\n\n/**\n * Hosts are listening on an invitation topic.\n * They dial one peer at a time, and only while they have no connection (no invitation flow in progress)\n * and no dial still waiting for the swarm to create its connection.\n * A peer whose connection closed is dialed again once the swarm offers it as a candidate after its backoff,\n * up to {@link MAX_DIALS_PER_PEER} times, so a session that fails before the invitation opens does not strand it.\n * A retired peer, an admitted guest or another host, is not dialed and its offers are refused.\n * When the invitation flow ends guest leaves the swarm and topology is updated once again,\n * so we can connect to the next peer.\n *\n * Guests don't initiate connections. They accept all connections because if we reject,\n * the host won't retry their offer.\n * Even if we started an invitation flow with one host we might want to try other hosts in case\n * the first one failed due to a network error, so multiple connections are accepted.\n */\nexport class InvitationTopology implements Topology {\n private _controller?: SwarmController;\n\n /**\n * Dials per peer, keyed by the client's stable network peer key; an inbound session counts once,\n * and a count is pruned once its peer leaves the swarm, so a guest that rejoins is dialed afresh.\n */\n private _dials = new ComplexMap<PublicKey, number>(PublicKey.hash);\n\n /** Dialed peers without a connection yet; a dial stays pending only while its peer is a candidate. */\n private _pending = new ComplexSet<PublicKey>(PublicKey.hash);\n\n constructor(private readonly _role: InvitationOptions_Role) {}\n\n init(controller: SwarmController): void {\n invariant(!this._controller, 'Already initialized.');\n this._controller = controller;\n }\n\n update(): void {\n invariant(this._controller, 'Not initialized.');\n const { ownPeerId, candidates, connected, allPeers } = this._controller.getState();\n\n // guests don't initiate connections\n if (this._role === InvitationOptions_Role.GUEST) {\n return;\n }\n\n // A candidate has no connection and is still in the swarm, so a peer that stopped being one ends its pending dial.\n this._pending = new ComplexSet<PublicKey>(\n PublicKey.hash,\n candidates.filter((peerId) => this._pending.has(peerId)),\n );\n\n // don't start a connection while we have an active invitation flow\n if (connected.length > 0) {\n // Record a connection another host initiated with us, without counting one we already dialed again.\n connected.forEach((peerId) => {\n if (!this._dials.has(peerId)) {\n this._dials.set(peerId, 1);\n }\n });\n return;\n }\n\n // Cleanup.\n this._dials = new ComplexMap<PublicKey, number>(\n PublicKey.hash,\n allPeers.flatMap((peerId): [PublicKey, number][] => {\n const count = this._dials.get(peerId);\n return count === undefined ? [] : [[peerId, count]];\n }),\n );\n\n // A pending dial already holds the one invitation flow.\n if (this._pending.size > 0) {\n return;\n }\n\n const nextPeer = candidates.find((peerId) => (this._dials.get(peerId) ?? 0) < MAX_DIALS_PER_PEER);\n if (nextPeer != null) {\n const dials = (this._dials.get(nextPeer) ?? 0) + 1;\n log('invitation connect', { ownPeerId, remotePeerId: nextPeer, dials });\n this._dials.set(nextPeer, dials);\n this._pending.add(nextPeer);\n this._controller.connect(nextPeer);\n }\n }\n\n async onOffer(peer: PublicKey): Promise<boolean> {\n invariant(this._controller, 'Not initialized.');\n const accept = (this._dials.get(peer) ?? 0) < MAX_DIALS_PER_PEER;\n if (!accept) {\n // the peer's offer displaced any dial of ours to it, which now never opens\n this._pending.delete(peer);\n }\n return accept;\n }\n\n /** Stops dialing a peer and refuses its offers while it stays in the swarm. */\n retire(peer: PublicKey): void {\n this._dials.set(peer, MAX_DIALS_PER_PEER);\n }\n\n async destroy(): Promise<void> {\n this._dials.clear();\n this._pending.clear();\n }\n\n toString(): string {\n return `InvitationTopology(${this._role === InvitationOptions_Role.GUEST ? 'guest' : 'host'})`;\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { type PushStream, TimeoutError, type Trigger, scheduleTask } from '@dxos/async';\nimport {\n ClientTraceEvents,\n INVITATION_TIMEOUT,\n getExpirationTime,\n invitationEventAttributes,\n} from '@dxos/client-protocol';\nimport { type Context, ContextDisposedError } from '@dxos/context';\nimport { createKeyPair, sign } from '@dxos/crypto';\nimport { type EdgeHttpClient, EdgeHttpClientService } from '@dxos/edge-client';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n type SwarmConnection,\n type SwarmNetworkManager,\n SwarmNetworkManagerService,\n createTeleportProtocolFactory,\n} from '@dxos/network-manager';\nimport { InvalidInvitationError, InvalidInvitationExtensionRoleError } from '@dxos/protocols';\nimport { buf, fromPublicKey, requirePublicKey, toPublicKey } from '@dxos/protocols/buf';\nimport {\n type AdmissionKeypair,\n AdmissionKeypairSchema,\n Invitation,\n Invitation_AuthMethod,\n Invitation_Kind,\n Invitation_State,\n Invitation_Type,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n AuthenticationRequestSchema,\n AuthenticationResponse_Status,\n type IntroductionResponse,\n InvitationOptions_Role,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type ExtensionContext, type TeleportExtension, type TeleportProps } from '@dxos/teleport';\nimport { trace as _trace } from '@dxos/tracing';\nimport { ComplexSet } from '@dxos/util';\n\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport { type EdgeInvitationConfig, EdgeInvitationHandler } from './edge-invitation-handler.ts';\nimport { InvitationGuestExtension } from './invitation-guest-extenstion.ts';\nimport { InvitationHostExtension, MAX_OTP_ATTEMPTS, isAuthenticationRequired } from './invitation-host-extension.ts';\nimport { createGuardedInvitationState, getInvitationOutcome } from './invitation-state.ts';\nimport { InvitationTopology } from './invitation-topology.ts';\n\nconst metrics = _trace.metrics;\n\nconst MAX_DELEGATED_INVITATION_HOST_TRIES = 3;\n\nexport type InvitationConnectionProps = {\n teleport: Partial<TeleportProps>;\n edgeInvitations?: EdgeInvitationConfig;\n};\n\n/**\n * Generic handler for Halo and Space invitations.\n * Handles the life-cycle of invitations between peers.\n *\n * Host\n * - Creates an invitation containing a swarm topic (which can be shared via a URL, QR code, or direct message).\n * - Joins the swarm with the topic and waits for guest's introduction.\n * - Wait for guest to authenticate with challenge specified in the invitation.\n * - Waits for guest to present credentials (containing local device and feed keys).\n * - Writes credentials to control feed then exits or waits for more guests (multi use invitations).\n *\n * Guest\n * - Joins the swarm with the topic.\n * - Sends an introduction.\n * - Submits the challenge.\n * - If Space handler then creates a local cloned space (with genesis block).\n * - Sends admission credentials.\n * ```\n * [Guest] [Host]\n * |------------------------------------Introduce-->|\n * |-------------------------------[Authenticate]-->|\n * |----------------------------------------Admit-->|\n * ```\n *\n * TODO: consider refactoring using xstate making the logic separation more explicit:\n * TODO: the flow logic should either be contained in invitations-handler or in extensions, not be split across\n * TODO: potentially re-evaluate host-side API to allow multiple concurrent connection, so that mutex can be removed\n */\n/**\n * Effect service tag for {@link InvitationsHandler}.\n */\nexport class InvitationsHandlerService extends EffectContext.Service<InvitationsHandlerService, InvitationsHandler>()(\n '@dxos/client-services/InvitationsHandler',\n) {}\n\nexport class InvitationsHandler {\n /**\n * @internal\n */\n constructor(\n private readonly _networkManager: SwarmNetworkManager,\n private readonly _edgeClient?: EdgeHttpClient,\n private readonly _connectionProps?: InvitationConnectionProps,\n ) {}\n\n handleInvitationFlow(\n ctx: Context,\n stream: PushStream<Invitation>,\n protocol: InvitationProtocol,\n invitation: Invitation,\n ): void {\n log.verbose('dxos.sdk.invitations-handler.handleInvitationFlow', {\n state: invitation.state,\n invitationId: invitation.invitationId,\n kind: invitation.kind,\n type: invitation.type,\n });\n metrics.increment('dxos.invitation.host', 1, { tags: { role: 'host', method: 'swarm' } });\n\n const hostSpanId = `invitation-host-${invitation.invitationId}`;\n // Reassign ctx to the child context so downstream `@trace.span` calls stay in the same trace.\n // Link child -> parent disposal so `ctx.dispose()` inside this flow still completes the\n // invitation stream (the caller's ctx owns `stream.complete()` via onDispose).\n // Do NOT await `invitationCtx.dispose()` here: `derive()` registers a parent -> child\n // dispose hook, so awaiting the parent dispose would re-enter the still-pending child\n // dispose promise and deadlock.\n const invitationCtx = ctx;\n ctx =\n _trace.spanStart({\n id: hostSpanId,\n instance: this,\n methodName: 'handleInvitationFlow',\n parentCtx: ctx,\n op: 'invitation.host',\n attributes: {\n 'ctx.dxos.invitation.id': invitation.invitationId,\n 'ctx.dxos.invitation.kind': Invitation_Kind[invitation.kind],\n },\n }) ?? ctx;\n if (ctx !== invitationCtx) {\n ctx.onDispose(() => {\n void invitationCtx.dispose();\n });\n }\n ctx.onDispose(() => _trace.spanEnd(hostSpanId));\n const guardedState = createGuardedInvitationState(ctx, invitation, stream);\n const topology = new InvitationTopology(InvitationOptions_Role.HOST);\n // Called for every connecting peer.\n const createExtension = (remotePeerId: PublicKey): InvitationHostExtension => {\n const extension = new InvitationHostExtension(guardedState.mutex, {\n get activeInvitation() {\n return ctx.disposed ? null : guardedState.current;\n },\n\n onStateUpdate: (newState: Invitation_State): Invitation => {\n if (newState !== Invitation_State.ERROR && newState !== Invitation_State.TIMEOUT) {\n guardedState.set(extension, newState);\n }\n return guardedState.current;\n },\n\n admit: async (admissionRequest) => {\n try {\n log.verbose('dxos.sdk.invitations-handler.host.admit', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n });\n const deviceKey = admissionRequest.kind.value?.deviceKey;\n invariant(deviceKey, 'Admission request carries no device key.');\n const admissionResponse = await protocol.admit(invitation, admissionRequest, extension.guestProfile);\n\n // Updating credentials complete.\n extension.completedTrigger.wake(requirePublicKey(deviceKey));\n\n return admissionResponse;\n } catch (err: any) {\n // TODO(burdon): Generic RPC callback to report error to client.\n guardedState.error(extension, err);\n throw err; // Propagate error to guest.\n }\n },\n\n onOpen: (connectionCtx: Context, extensionsCtx: ExtensionContext) => {\n let admitted = false;\n connectionCtx.onDispose(() => {\n if (!admitted) {\n guardedState.set(extension, Invitation_State.CONNECTING);\n }\n });\n\n scheduleTask(connectionCtx, async () => {\n try {\n log('opening host invitation handler');\n log.verbose('connected', { ...protocol.toJSON() });\n const deviceKey = await extension.completedTrigger.wait({ timeout: invitation.timeout });\n log.verbose('admitted guest', { guest: deviceKey, ...protocol.toJSON() });\n guardedState.set(extension, Invitation_State.SUCCESS);\n metrics.increment('dxos.invitation.success', 1, { tags: { role: 'host', method: 'swarm' } });\n _trace.events.emit(ClientTraceEvents.invitationAdmit, invitationEventAttributes(guardedState.current));\n log('host invitation handler opened');\n admitted = true;\n topology.retire(remotePeerId);\n\n if (!invitation.multiUse) {\n await ctx.dispose();\n }\n } catch (err: any) {\n const stateChanged = guardedState.set(extension, Invitation_State.CONNECTING);\n if (err instanceof TimeoutError) {\n if (stateChanged) {\n metrics.increment('dxos.invitation.timeout', 1, { tags: { role: 'host', method: 'swarm' } });\n log.verbose('timeout', { ...protocol.toJSON() });\n }\n } else {\n if (stateChanged) {\n metrics.increment('dxos.invitation.failed', 1, { tags: { role: 'host', method: 'swarm' } });\n log.error('failed', err);\n }\n }\n // Close connection\n extensionsCtx.close(err);\n }\n });\n },\n onError: (err) => {\n const stateChanged = guardedState.set(extension, Invitation_State.CONNECTING);\n if (err instanceof InvalidInvitationExtensionRoleError) {\n log('invalid role', { ...err.context });\n topology.retire(remotePeerId);\n return;\n }\n if (err instanceof TimeoutError) {\n if (stateChanged) {\n metrics.increment('dxos.invitation.timeout', 1, { tags: { role: 'host', method: 'swarm' } });\n log.verbose('timeout', { err });\n }\n } else {\n if (stateChanged) {\n metrics.increment('dxos.invitation.failed', 1, { tags: { role: 'host', method: 'swarm' } });\n log.error('failed', err);\n }\n }\n },\n });\n\n return extension;\n };\n\n const expiresOn = getExpirationTime(invitation);\n if (expiresOn) {\n if (expiresOn.getTime() < Date.now()) {\n log.warn('invitation has already expired');\n guardedState.set(null, Invitation_State.EXPIRED);\n void ctx.dispose().catch((err) => log.catch(err));\n return;\n }\n scheduleTask(\n ctx,\n async () => {\n // ensure the swarm is closed before changing state and closing the stream.\n await swarmConnection.close(ctx);\n guardedState.set(null, Invitation_State.EXPIRED);\n metrics.increment('dxos.invitation.expired', 1, { tags: { role: 'host', method: 'swarm' } });\n await ctx.dispose();\n },\n expiresOn.getTime() - Date.now(),\n );\n }\n\n let swarmConnection: SwarmConnection;\n scheduleTask(ctx, async () => {\n swarmConnection = await this._joinSwarm(ctx, invitation, InvitationOptions_Role.HOST, topology, createExtension);\n guardedState.set(null, Invitation_State.CONNECTING);\n });\n }\n\n acceptInvitation(\n ctx: Context,\n stream: PushStream<Invitation>,\n protocol: InvitationProtocol,\n invitation: Invitation,\n otpEnteredTrigger: Trigger<string>,\n deviceProfile?: DeviceProfileDocument,\n ): void {\n log.verbose('dxos.sdk.invitations-handler.acceptInvitation', {\n state: invitation.state,\n invitationId: invitation.invitationId,\n kind: invitation.kind,\n type: invitation.type,\n });\n const { timeout = INVITATION_TIMEOUT } = invitation;\n\n // The PostHog dashboard \"EDGE replication latency\" (https://eu.posthog.com/project/126171/dashboard/973334)\n // queries this span's name and attributes: update it when changing them.\n const guestSpanId = `invitation-guest-${invitation.invitationId}`;\n // Reassign ctx to the child context returned by spanStart so downstream calls\n // (`edgeInvitationHandler.handle`, `_joinSwarm`, etc.) inherit this span as their\n // parent rather than starting a new root trace.\n // Link child -> parent disposal so `ctx.dispose()` inside this flow still completes the\n // invitation stream. See note in `handleInvitationFlow`: must not await the parent\n // dispose here (`derive()` registers a parent -> child dispose hook, so awaiting would\n // re-enter the still-pending child dispose promise and deadlock).\n const invitationCtx = ctx;\n ctx =\n _trace.spanStart({\n id: guestSpanId,\n instance: this,\n methodName: 'acceptInvitation',\n parentCtx: ctx,\n op: 'invitation.guest',\n attributes: {\n 'ctx.dxos.invitation.id': invitation.invitationId,\n 'ctx.dxos.invitation.kind': Invitation_Kind[invitation.kind],\n 'ctx.dxos.invitation.type': Invitation_Type[invitation.type],\n ...(invitation.spaceId ? { 'ctx.spaceId': invitation.spaceId } : {}),\n },\n }) ?? ctx;\n if (ctx !== invitationCtx) {\n ctx.onDispose(() => {\n void invitationCtx.dispose();\n });\n }\n\n if (deviceProfile) {\n invariant(invitation.kind === Invitation_Kind.DEVICE, 'deviceProfile provided for non-device invitation');\n }\n\n const triedPeersIds = new ComplexSet(PublicKey.hash);\n const guardedState = createGuardedInvitationState(ctx, invitation, stream);\n // A delegated invitation races EDGE against member devices, so its type cannot say which one admitted the guest.\n let admittedBy: 'edge' | 'peer' | undefined;\n ctx.onDispose(() =>\n _trace.spanEnd(guestSpanId, {\n attributes: {\n outcome: getInvitationOutcome(guardedState.current.state),\n ...(admittedBy ? { 'dxos.invitation.admittedBy': admittedBy } : {}),\n },\n }),\n );\n\n const shouldCancelInvitationFlow = (extension: InvitationGuestExtension) => {\n const isLockedByAnotherConnection = guardedState.mutex.isLocked() && !extension.hasFlowLock();\n log('should cancel invitation flow', {\n isLockedByAnotherConnection,\n invitationType: Invitation_Type.DELEGATED,\n triedPeers: triedPeersIds.size,\n });\n if (isLockedByAnotherConnection) {\n return false;\n }\n // A delegated invitation may be retried against other hosts, so it is disposed only on timeout\n // or once the retry budget is spent.\n return invitation.type !== Invitation_Type.DELEGATED || triedPeersIds.size >= MAX_DELEGATED_INVITATION_HOST_TRIES;\n };\n\n let admitted = false;\n const createExtension = (): InvitationGuestExtension => {\n const extension = new InvitationGuestExtension(guardedState.mutex, {\n onStateUpdate: (newState: Invitation_State) => {\n guardedState.set(extension, newState);\n },\n onOpen: (connectionCtx: Context, extensionCtx: ExtensionContext) => {\n triedPeersIds.add(extensionCtx.remotePeerId);\n\n if (admitted) {\n extensionCtx.close();\n return;\n }\n\n connectionCtx.onDispose(async () => {\n log.verbose('extension disposed', { admitted, currentState: guardedState.current.state });\n if (!admitted) {\n guardedState.error(extension, new ContextDisposedError());\n if (shouldCancelInvitationFlow(extension)) {\n await ctx.dispose();\n }\n }\n });\n\n scheduleTask(connectionCtx, async () => {\n try {\n log('opening guest invitation handler');\n\n scheduleTask(\n connectionCtx,\n () => {\n guardedState.set(extension, Invitation_State.TIMEOUT);\n extensionCtx.close();\n },\n timeout,\n );\n\n log.verbose('dxos.sdk.invitations-handler.guest.connected', { ...protocol.toJSON() });\n guardedState.set(extension, Invitation_State.CONNECTED);\n\n // 1. Introduce guest to host.\n log.verbose('dxos.sdk.invitations-handler.guest.introduce', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n });\n const introductionResponse = await extension.rpc.InvitationHostService.introduce({\n invitationId: invitation.invitationId,\n ...protocol.createIntroduction(),\n });\n log.verbose('dxos.sdk.invitations-handler.guest.introduce-response', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n authMethod: introductionResponse.authMethod,\n });\n invitation.authMethod = introductionResponse.authMethod;\n\n // 2. Get authentication code.\n if (isAuthenticationRequired(invitation)) {\n switch (invitation.authMethod) {\n case Invitation_AuthMethod.SHARED_SECRET:\n await this._handleGuestOtpAuth(\n extension,\n (state) => guardedState.set(extension, state),\n otpEnteredTrigger,\n { timeout },\n );\n break;\n case Invitation_AuthMethod.KNOWN_PUBLIC_KEY:\n await this._handleGuestKpkAuth(\n extension,\n (state) => guardedState.set(extension, state),\n invitation,\n introductionResponse,\n );\n break;\n }\n }\n\n // 3. Send admission credentials to host (with local space keys).\n log.verbose('dxos.sdk.invitations-handler.guest.request-admission', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n });\n const admissionRequest = await protocol.createAdmissionRequest(deviceProfile);\n const admissionResponse = await extension.rpc.InvitationHostService.admit(admissionRequest);\n\n // Remote connection no longer needed.\n admitted = true;\n\n // 4. Record credential in our HALO.\n const result = await protocol.accept(ctx, admissionResponse, admissionRequest);\n\n // 5. Success.\n log.verbose('dxos.sdk.invitations-handler.guest.admitted-by-host', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n });\n metrics.increment('dxos.invitation.success', 1, { tags: { role: 'guest', method: 'swarm' } });\n const firstAdmission = admittedBy === undefined;\n admittedBy = 'peer';\n guardedState.complete({\n ...guardedState.current,\n ...result,\n state: Invitation_State.SUCCESS,\n });\n if (firstAdmission) {\n _trace.events.emit(ClientTraceEvents.invitationAccept, invitationEventAttributes(guardedState.current));\n }\n log('guest invitation handler opened');\n } catch (err: any) {\n if (err instanceof TimeoutError) {\n log.verbose('timeout', { ...protocol.toJSON() });\n guardedState.set(extension, Invitation_State.TIMEOUT);\n } else {\n log.verbose('auth failed', err);\n guardedState.error(extension, err);\n }\n extensionCtx.close(err);\n }\n });\n },\n onError: (err) => {\n if (err instanceof InvalidInvitationExtensionRoleError) {\n return;\n }\n if (err instanceof TimeoutError) {\n log.verbose('timeout', { ...protocol.toJSON() });\n guardedState.set(extension, Invitation_State.TIMEOUT);\n } else {\n log.verbose('auth failed', err);\n guardedState.error(extension, err);\n }\n },\n });\n\n return extension;\n };\n\n const edgeInvitationHandler = new EdgeInvitationHandler(this._connectionProps?.edgeInvitations, this._edgeClient, {\n onInvitationSuccess: async (edgeCtx, admissionResponse, admissionRequest) => {\n const result = await protocol.accept(edgeCtx, admissionResponse, admissionRequest);\n log.info('admitted by edge', { ...protocol.toJSON() });\n metrics.increment('dxos.invitation.success', 1, { tags: { role: 'guest', method: 'edge' } });\n // A delegated invitation can also be admitted by a peer in the same run; report the join once.\n const firstAdmission = admittedBy === undefined;\n admittedBy = 'edge';\n guardedState.complete({ ...guardedState.current, ...result, state: Invitation_State.SUCCESS });\n if (firstAdmission) {\n _trace.events.emit(ClientTraceEvents.invitationAccept, invitationEventAttributes(guardedState.current));\n }\n },\n });\n edgeInvitationHandler.handle(ctx, guardedState, protocol, deviceProfile);\n\n scheduleTask(ctx, async () => {\n const error = checkInvitation(protocol, invitation);\n if (error) {\n stream.error(error);\n await ctx.dispose();\n } else {\n invariant(invitation.swarmKey);\n\n const timeoutInactive = () => {\n if (guardedState.mutex.isLocked()) {\n scheduleTask(ctx, timeoutInactive, timeout);\n } else {\n guardedState.set(null, Invitation_State.TIMEOUT);\n }\n };\n\n // Timeout if no connection is established.\n scheduleTask(ctx, timeoutInactive, timeout);\n\n await this._joinSwarm(\n ctx,\n invitation,\n InvitationOptions_Role.GUEST,\n new InvitationTopology(InvitationOptions_Role.GUEST),\n createExtension,\n );\n guardedState.set(null, Invitation_State.CONNECTING);\n }\n });\n }\n\n private async _joinSwarm(\n ctx: Context,\n invitation: Invitation,\n role: InvitationOptions_Role,\n topology: InvitationTopology,\n extensionFactory: (remotePeerId: PublicKey) => TeleportExtension,\n ): Promise<SwarmConnection> {\n let label: string;\n if (role === InvitationOptions_Role.GUEST) {\n label = 'invitation guest';\n } else if (invitation.kind === Invitation_Kind.DEVICE) {\n label = 'invitation host for device';\n } else {\n label = `invitation host for space ${toPublicKey(invitation.spaceKey)?.truncate()}`;\n }\n const swarmKey = toPublicKey(invitation.swarmKey);\n invariant(swarmKey, 'swarmKey missing in the invitation');\n const swarmConnection = await this._networkManager.joinSwarm(ctx, {\n topic: swarmKey,\n protocolProvider: createTeleportProtocolFactory(async (teleport) => {\n teleport.addExtension('dxos.halo.invitations', extensionFactory(teleport.remotePeerId));\n }, this._connectionProps?.teleport),\n topology,\n label,\n });\n ctx.onDispose(() => swarmConnection.close(ctx));\n return swarmConnection;\n }\n\n private async _handleGuestOtpAuth(\n extension: InvitationGuestExtension,\n setState: (newState: Invitation_State) => void,\n authenticated: Trigger<string>,\n options: { timeout: number },\n ): Promise<void> {\n for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {\n log('guest waiting for authentication code...');\n setState(Invitation_State.READY_FOR_AUTHENTICATION);\n const authCode = await authenticated.wait(options);\n\n log('sending authentication request');\n setState(Invitation_State.AUTHENTICATING);\n const response = await extension.rpc.InvitationHostService.authenticate(\n create(AuthenticationRequestSchema, { authCode }),\n );\n if (response.status === undefined || response.status === AuthenticationResponse_Status.OK) {\n break;\n }\n\n if (response.status === AuthenticationResponse_Status.INVALID_OTP) {\n if (attempt === MAX_OTP_ATTEMPTS) {\n throw new Error(`Maximum retry attempts: ${MAX_OTP_ATTEMPTS}`);\n } else {\n log('retrying invalid code', { attempt });\n authenticated.reset();\n }\n }\n }\n }\n\n private async _handleGuestKpkAuth(\n extension: InvitationGuestExtension,\n setState: (newState: Invitation_State) => void,\n invitation: Invitation,\n introductionResponse: IntroductionResponse,\n ): Promise<void> {\n const guestPrivateKey = invitation.guestKeypair?.privateKey?.data;\n if (guestPrivateKey == null) {\n throw new Error('keypair missing in the invitation');\n }\n if (introductionResponse.challenge == null) {\n throw new Error('challenge missing in the introduction');\n }\n log('sending authentication request');\n const signature = sign(Buffer.from(introductionResponse.challenge), Buffer.from(guestPrivateKey));\n const response = await extension.rpc.InvitationHostService.authenticate(\n create(AuthenticationRequestSchema, { signedChallenge: signature }),\n );\n if (response.status !== AuthenticationResponse_Status.OK) {\n throw new Error(`Authentication failed with code: ${response.status}`);\n }\n }\n}\n\nconst checkInvitation = (protocol: InvitationProtocol, invitation: Partial<Invitation>) => {\n const expiresOn = getExpirationTime(invitation);\n if (expiresOn && expiresOn.getTime() < Date.now()) {\n return new InvalidInvitationError({ message: 'Invitation already expired.' });\n }\n return protocol.checkInvitation(invitation);\n};\n\nexport const createAdmissionKeypair = (): AdmissionKeypair => {\n const keypair = createKeyPair();\n return buf.create(AdmissionKeypairSchema, {\n publicKey: fromPublicKey(PublicKey.from(keypair.publicKey)),\n privateKey: { data: new Uint8Array(keypair.secretKey) },\n });\n};\n\nexport type InvitationsHandlerLayerOptions = {\n connectionProps?: InvitationConnectionProps;\n};\n\n/**\n * Effect Layer constructing an {@link InvitationsHandler}.\n */\nexport const InvitationsHandlerLayer = (\n options: InvitationsHandlerLayerOptions = {},\n): Layer.Layer<InvitationsHandlerService, never, SwarmNetworkManagerService> =>\n Layer.effect(\n InvitationsHandlerService,\n Effect.gen(function* () {\n const networkManager = yield* SwarmNetworkManagerService;\n const edgeClient = yield* Effect.serviceOption(EdgeHttpClientService);\n return new InvitationsHandler(networkManager, Option.getOrUndefined(edgeClient), options.connectionProps);\n }),\n );\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { toServiceError } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Invitation } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n QueryInvitationsResponse,\n QueryInvitationsResponse_Action,\n QueryInvitationsResponse_Type,\n QueryInvitationsResponseSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { InvitationsService } from '@dxos/protocols/rpc';\nimport { trace } from '@dxos/tracing';\n\nimport * as InvitationsContract from '../../contracts/invitations.ts';\n\n/**\n * Adapts invitation service observable to client/service stream.\n */\nexport class InvitationsServiceImpl implements InvitationsService.Handlers {\n 'constructor'(private readonly _invitationsManager: InvitationsContract.Manager) {}\n\n // TODO(burdon): Guest/host label.\n 'getLoggingContext'() {\n return {\n // deviceKey: this._identityManager.identity?.deviceKey\n };\n }\n\n ['InvitationsService.createInvitation'](request: Invitation): EffectStream.Stream<Invitation, Error> {\n return EffectEx.streamFromEmitter<Invitation, Error>((emit) => {\n const ctx = Context.default();\n void this._invitationsManager\n .createInvitation(ctx, request)\n .then((invitation) => {\n trace.metrics.increment('dxos.invitation.created');\n invitation.subscribe(\n (value) => void emit.single(value),\n (err) => void emit.fail(err),\n () => void emit.end(),\n );\n })\n .catch((err) => void emit.fail(err));\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['InvitationsService.acceptInvitation'](\n request: InvitationsService.AcceptInvitationRequest,\n ): EffectStream.Stream<Invitation, Error> {\n return EffectEx.streamFromEmitter<Invitation, Error>((emit) => {\n const ctx = Context.default();\n const invitation = this._invitationsManager.acceptInvitation(ctx, { ...request });\n invitation.subscribe(\n (value) => void emit.single(value),\n (err) => void emit.fail(err),\n () => void emit.end(),\n );\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['InvitationsService.authenticate'](\n request: InvitationsService.AuthenticationRequest,\n ): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: () => this._invitationsManager.authenticate(request),\n catch: toServiceError,\n });\n }\n\n ['InvitationsService.cancelInvitation'](\n request: InvitationsService.CancelInvitationRequest,\n ): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: () => this._invitationsManager.cancelInvitation(request),\n catch: toServiceError,\n });\n }\n\n ['InvitationsService.queryInvitations'](): EffectStream.Stream<QueryInvitationsResponse, Error> {\n return EffectEx.streamFromEmitter<QueryInvitationsResponse, Error>((emit) => {\n const ctx = Context.default();\n\n // Push added invitations to the stream.\n this._invitationsManager.invitationCreated.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.ADDED,\n type: QueryInvitationsResponse_Type.CREATED,\n invitations: [invitation],\n }),\n );\n });\n\n this._invitationsManager.invitationAccepted.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.ADDED,\n type: QueryInvitationsResponse_Type.ACCEPTED,\n invitations: [invitation],\n }),\n );\n });\n\n // Push removed invitations to the stream.\n this._invitationsManager.removedCreated.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.REMOVED,\n type: QueryInvitationsResponse_Type.CREATED,\n invitations: [invitation],\n }),\n );\n });\n\n this._invitationsManager.removedAccepted.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.REMOVED,\n type: QueryInvitationsResponse_Type.ACCEPTED,\n invitations: [invitation],\n }),\n );\n });\n\n // Used only for testing.\n this._invitationsManager.saved.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.SAVED,\n type: QueryInvitationsResponse_Type.CREATED,\n invitations: [invitation],\n }),\n );\n });\n\n // Push existing invitations to the stream.\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.ADDED,\n type: QueryInvitationsResponse_Type.CREATED,\n invitations: this._invitationsManager.getCreatedInvitations(),\n existing: true,\n }),\n );\n\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.ADDED,\n type: QueryInvitationsResponse_Type.ACCEPTED,\n invitations: this._invitationsManager.getAcceptedInvitations(),\n existing: true,\n }),\n );\n\n this._invitationsManager.onPersistentInvitationsLoaded(ctx, () => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.LOAD_COMPLETE,\n type: QueryInvitationsResponse_Type.CREATED,\n // TODO(nf): populate with invitations\n }),\n );\n });\n // TODO(nf): expired invitations?\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n}\n\nexport const InvitationsServiceLayer = Layer.effect(\n InvitationsService.Tag,\n Effect.map(\n InvitationsContract.ManagerService,\n (invitationsManager) => new InvitationsServiceImpl(invitationsManager),\n ),\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { Event, PushStream, TimeoutError, Trigger } from '@dxos/async';\nimport {\n AuthenticatingInvitation,\n AUTHENTICATION_CODE_LENGTH,\n CancellableInvitation,\n INVITATION_TIMEOUT,\n} from '@dxos/client-protocol';\nimport { Context } from '@dxos/context';\nimport { generatePasscode } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { buf, bufInit, bufWkt, fromPublicKey } from '@dxos/protocols/buf';\nimport {\n Invitation,\n Invitation_AuthMethod,\n Invitation_State,\n Invitation_Type,\n InvitationSchema,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { SpaceMember_Role } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type InvitationsService } from '@dxos/protocols/rpc';\nimport { trace } from '@dxos/tracing';\n\nimport type { InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport * as InvitationsContract from '../../contracts/invitations.ts';\nimport * as Events from '../../Events.ts';\nimport { type IMetadataStore, IMetadataStoreService, hasInvitationExpired } from '../metadata/index.ts';\nimport { type InvitationsHandler, InvitationsHandlerService, createAdmissionKeypair } from './invitations-handler.ts';\n\n/**\n * Entry point for creating and accepting invitations, keeps track of existing invitation set and\n * emits events when the set changes.\n */\nexport class InvitationsManager {\n private readonly _createInvitations = new Map<string, CancellableInvitation>();\n private readonly _acceptInvitations = new Map<string, AuthenticatingInvitation>();\n\n public readonly invitationCreated = new Event<Invitation>();\n public readonly invitationAccepted = new Event<Invitation>();\n public readonly removedCreated = new Event<Invitation>();\n public readonly removedAccepted = new Event<Invitation>();\n public readonly saved = new Event<Invitation>();\n\n private readonly _persistentInvitationsLoadedEvent = new Event();\n private _persistentInvitationsLoaded = false;\n\n private _invitationHandlerFactory?: (\n invitation: Partial<Invitation> & Pick<Invitation, 'kind'>,\n ) => InvitationProtocol;\n\n constructor(\n private readonly _invitationsHandler: InvitationsHandler,\n private readonly _metadataStore: IMetadataStore,\n ) {}\n\n /**\n * Wires the invitation handler factory after the composing stack is fully constructed.\n */\n setInvitationHandlerFactory(\n getHandler: (invitation: Partial<Invitation> & Pick<Invitation, 'kind'>) => InvitationProtocol,\n ): void {\n this._invitationHandlerFactory = getHandler;\n }\n\n /**\n * Resolves the protocol for an invitation kind; throws until a factory has been wired.\n */\n getInvitationHandler(invitation: Partial<Invitation> & Pick<Invitation, 'kind'>): InvitationProtocol {\n invariant(this._invitationHandlerFactory, 'Invitation handler factory not set.');\n return this._invitationHandlerFactory(invitation);\n }\n\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async createInvitation(\n ctx: Context,\n options: Partial<Invitation> & Pick<Invitation, 'kind'>,\n ): Promise<CancellableInvitation> {\n if (options.invitationId) {\n const existingInvitation = this._createInvitations.get(options.invitationId);\n if (existingInvitation) {\n return existingInvitation;\n }\n }\n\n const handler = this.getInvitationHandler(options);\n const invitationError = handler.checkCanInviteNewMembers();\n if (invitationError != null) {\n throw invitationError;\n }\n const invitation = this._createInvitation(handler, options);\n\n const {\n ctx: invitationCtx,\n stream,\n observableInvitation,\n } = this._createObservableInvitation(ctx, handler, invitation);\n\n this._createInvitations.set(invitation.invitationId, observableInvitation);\n this.invitationCreated.emit(invitation);\n // onComplete is called on cancel, expiration, or redemption of a single-use invitation\n this._onInvitationComplete(observableInvitation, async () => {\n this._createInvitations.delete(observableInvitation.get().invitationId);\n this.removedCreated.emit(observableInvitation.get());\n if (observableInvitation.get().persistent) {\n await this._safeDeleteInvitation(observableInvitation.get());\n }\n });\n\n try {\n await this._persistIfRequired(handler, stream, invitation);\n } catch (err) {\n log.catch(err);\n await observableInvitation.cancel();\n return observableInvitation;\n }\n\n this._invitationsHandler.handleInvitationFlow(invitationCtx, stream, handler, observableInvitation.get());\n\n return observableInvitation;\n }\n\n async loadPersistentInvitations(ctx: Context): Promise<{ invitations: Invitation[] }> {\n if (this._persistentInvitationsLoaded) {\n const invitations = this.getCreatedInvitations().filter((i) => i.persistent);\n return { invitations };\n }\n try {\n const persistentInvitations = this._metadataStore.getInvitations();\n // get saved persistent invitations, filter and remove from storage those that have expired.\n const freshInvitations = persistentInvitations.filter((invitation) => !hasInvitationExpired(invitation));\n\n const loadTasks = freshInvitations.map((persistentInvitation) => {\n invariant(!this._createInvitations.get(persistentInvitation.invitationId), 'invitation already exists');\n return this.createInvitation(ctx, { ...persistentInvitation, persistent: false });\n });\n const cInvitations = await Promise.all(loadTasks);\n\n return { invitations: cInvitations.map((invitation) => invitation.get()) };\n } catch (err) {\n log.catch(err);\n return { invitations: [] };\n } finally {\n this._persistentInvitationsLoadedEvent.emit();\n this._persistentInvitationsLoaded = true;\n }\n }\n\n /**\n * The profile is the shape the device credential is signed over, not the wire shape the\n * service receives — {@link InvitationsServiceImpl} converts before calling this.\n */\n acceptInvitation(\n ctx: Context,\n request: {\n invitation: InvitationsService.AcceptInvitationRequest['invitation'];\n deviceProfile?: DeviceProfileDocument;\n },\n ): AuthenticatingInvitation {\n const options = request.invitation;\n const existingInvitation = this._acceptInvitations.get(options.invitationId);\n if (existingInvitation) {\n return existingInvitation;\n }\n\n const handler = this.getInvitationHandler(options);\n const {\n ctx: invitationCtx,\n invitation,\n stream,\n otpEnteredTrigger,\n } = this._createObservableAcceptingInvitation(ctx, handler, options);\n this._invitationsHandler.acceptInvitation(\n invitationCtx,\n stream,\n handler,\n options,\n otpEnteredTrigger,\n request.deviceProfile,\n );\n this._acceptInvitations.set(invitation.get().invitationId, invitation);\n this.invitationAccepted.emit(invitation.get());\n\n this._onInvitationComplete(invitation, () => {\n this._acceptInvitations.delete(invitation.get().invitationId);\n this.removedAccepted.emit(invitation.get());\n });\n\n return invitation;\n }\n\n async authenticate({ invitationId, authCode }: InvitationsService.AuthenticationRequest): Promise<void> {\n log('authenticating...');\n invariant(invitationId);\n const observable = this._acceptInvitations.get(invitationId);\n if (!observable) {\n log.warn('invalid invitation', { invitationId });\n } else {\n await observable.authenticate(authCode);\n }\n }\n\n async cancelInvitation({ invitationId }: { invitationId: string }): Promise<void> {\n log('cancelInvitation...', { invitationId });\n invariant(invitationId);\n const created = this._createInvitations.get(invitationId);\n if (created) {\n // remove from storage before modifying in-memory state, higher chance of failing\n if (created.get().persistent) {\n await this._metadataStore.removeInvitation(invitationId);\n }\n if (created.get().type === Invitation_Type.DELEGATED) {\n const handler = this.getInvitationHandler(created.get());\n await handler.cancelDelegation(created.get());\n }\n await created.cancel();\n this._createInvitations.delete(invitationId);\n this.removedCreated.emit(created.get());\n return;\n }\n\n const accepted = this._acceptInvitations.get(invitationId);\n if (accepted) {\n await accepted.cancel();\n this._acceptInvitations.delete(invitationId);\n this.removedAccepted.emit(accepted.get());\n }\n }\n\n getCreatedInvitations(): Invitation[] {\n return [...this._createInvitations.values()].map((i) => i.get());\n }\n\n getAcceptedInvitations(): Invitation[] {\n return [...this._acceptInvitations.values()].map((i) => i.get());\n }\n\n onPersistentInvitationsLoaded(ctx: Context, callback: () => void): void {\n if (this._persistentInvitationsLoaded) {\n callback();\n } else {\n this._persistentInvitationsLoadedEvent.once(ctx, () => callback());\n }\n }\n\n private _createInvitation(protocol: InvitationProtocol, _options?: Partial<Invitation>): Invitation {\n const {\n invitationId = PublicKey.random().toHex(),\n type = Invitation_Type.INTERACTIVE,\n authMethod = Invitation_AuthMethod.SHARED_SECRET,\n state = Invitation_State.INIT,\n timeout = INVITATION_TIMEOUT,\n swarmKey = fromPublicKey(PublicKey.random()),\n persistent = _options?.authMethod !== Invitation_AuthMethod.KNOWN_PUBLIC_KEY,\n created = bufWkt.timestampNow(),\n guestKeypair = undefined,\n role = SpaceMember_Role.ADMIN,\n lifetime = 86400 * 7, // 7 days.\n multiUse = false,\n ...options\n } = _options ?? {};\n const authCode =\n options?.authCode ??\n (authMethod === Invitation_AuthMethod.SHARED_SECRET ? generatePasscode(AUTHENTICATION_CODE_LENGTH) : undefined);\n\n return buf.create(InvitationSchema, {\n invitationId,\n type,\n authMethod,\n state,\n swarmKey,\n authCode,\n timeout,\n persistent: persistent && type !== Invitation_Type.DELEGATED, // Delegated invitations are persisted in the control feed.\n guestKeypair:\n guestKeypair ?? (authMethod === Invitation_AuthMethod.KNOWN_PUBLIC_KEY ? createAdmissionKeypair() : undefined),\n created,\n lifetime,\n role,\n multiUse,\n delegationCredentialId: options?.delegationCredentialId,\n ...bufInit(options),\n ...bufInit(protocol.getInvitationContext()),\n });\n }\n\n private _createObservableInvitation(\n ctx: Context,\n handler: InvitationProtocol,\n invitation: Invitation,\n ): { ctx: Context; stream: PushStream<Invitation>; observableInvitation: CancellableInvitation } {\n const stream = new PushStream<Invitation>();\n const invitationCtx = ctx.derive({\n onError: (err) => {\n stream.error(err);\n void invitationCtx.dispose();\n },\n });\n invitationCtx.onDispose(() => {\n log('complete', { ...handler.toJSON() });\n stream.complete();\n });\n const observableInvitation = new CancellableInvitation({\n initialInvitation: invitation,\n subscriber: stream.observable,\n onCancel: async () => {\n stream.next({ ...invitation, state: Invitation_State.CANCELLED });\n await invitationCtx.dispose();\n },\n });\n return { ctx: invitationCtx, stream, observableInvitation };\n }\n\n private _createObservableAcceptingInvitation(\n parentCtx: Context,\n handler: InvitationProtocol,\n initialState: Invitation,\n ): {\n ctx: Context;\n invitation: AuthenticatingInvitation;\n stream: PushStream<Invitation>;\n otpEnteredTrigger: Trigger<string>;\n } {\n const otpEnteredTrigger = new Trigger<string>();\n const stream = new PushStream<Invitation>();\n // Derive from caller ctx so `TRACE_SPAN_ATTRIBUTE` propagates via the parent chain.\n const ctx = parentCtx.derive({\n onError: (err) => {\n if (err instanceof TimeoutError) {\n log('timeout', { ...handler.toJSON() });\n stream.next({ ...initialState, state: Invitation_State.TIMEOUT });\n } else {\n log.warn('auth failed', err);\n stream.next({ ...initialState, state: Invitation_State.ERROR });\n }\n void ctx.dispose();\n },\n });\n ctx.onDispose(() => {\n log('complete', { ...handler.toJSON() });\n stream.complete();\n });\n const invitation = new AuthenticatingInvitation({\n initialInvitation: initialState,\n subscriber: stream.observable,\n onCancel: async () => {\n stream.next({ ...initialState, state: Invitation_State.CANCELLED });\n await ctx.dispose();\n },\n onAuthenticate: async (code: string) => {\n // TODO(burdon): Reset creates a race condition? Event?\n otpEnteredTrigger.wake(code);\n },\n });\n return { ctx, invitation, stream, otpEnteredTrigger };\n }\n\n private async _persistIfRequired(\n handler: InvitationProtocol,\n changeStream: PushStream<Invitation>,\n invitation: Invitation,\n ): Promise<void> {\n if (invitation.type === Invitation_Type.DELEGATED && invitation.delegationCredentialId == null) {\n const delegationCredentialId = await handler.delegate(invitation);\n changeStream.next({ ...invitation, delegationCredentialId: fromPublicKey(delegationCredentialId) });\n } else if (invitation.persistent) {\n await this._metadataStore.addInvitation(invitation);\n this.saved.emit(invitation);\n }\n }\n\n private async _safeDeleteInvitation(invitation: Invitation): Promise<void> {\n try {\n await this._metadataStore.removeInvitation(invitation.invitationId);\n } catch (err) {\n log.catch(err);\n }\n }\n\n private _onInvitationComplete(invitation: CancellableInvitation, callback: () => void): void {\n invitation.subscribe(\n () => {},\n () => {},\n callback,\n );\n }\n}\n\n/**\n * Effect Layer constructing an {@link InvitationsManager}.\n *\n * The invitation handler factory points \"up the stack\" and is wired via\n * {@link InvitationsManager.setInvitationHandlerFactory} after composition.\n */\nexport const InvitationsManagerLayer = (): Layer.Layer<\n InvitationsContract.ManagerService,\n never,\n Hook.Controller | InvitationsHandlerService | IMetadataStoreService\n> =>\n Layer.effect(\n InvitationsContract.ManagerService,\n Effect.gen(function* () {\n const invitationsHandler = yield* InvitationsHandlerService;\n const metadataStore = yield* IMetadataStoreService;\n const invitationsManager = new InvitationsManager(invitationsHandler, metadataStore);\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Hook.on(\n Events.StackOpened,\n Effect.fn('InvitationsManager.onStackOpened')(function* () {\n const loaded = yield* Effect.promise(() => invitationsManager.loadPersistentInvitations(ctx));\n log('loaded persistent invitations', { count: loaded.invitations.length });\n }),\n );\n return invitationsManager;\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\n\nimport { type TransportFactory } from '@dxos/network-manager';\n\n/**\n * Effect service tag for the swarm {@link TransportFactory}.\n */\nexport class TransportFactoryService extends EffectContext.Service<TransportFactoryService, TransportFactory>()(\n '@dxos/client-services/TransportFactory',\n) {}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as EffectStream from 'effect/Stream';\n\nimport { SubscriptionList } from '@dxos/async';\nimport { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { invariant } from '@dxos/invariant';\nimport { toServiceError } from '@dxos/protocols';\nimport { buf, fromPublicKey } from '@dxos/protocols/buf';\nimport {\n type Device,\n Device_PresenceState,\n DeviceKind,\n DeviceSchema,\n EdgeStatus_ConnectionState,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { DevicesService } from '@dxos/protocols/rpc';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\n\nexport class DevicesServiceImpl implements DevicesService.Handlers {\n 'constructor'(\n private readonly _identityManager: IdentityContract.Manager,\n private readonly _edgeConnection?: EdgeConnection,\n ) {}\n\n ['DevicesService.updateDevice'](request: DeviceProfileDocument): Effect.Effect<Device, BaseError> {\n return Effect.tryPromise({\n try: async () => await this._identityManager.updateDeviceProfile(request),\n catch: toServiceError,\n });\n }\n\n ['DevicesService.queryDevices'](): EffectStream.Stream<DevicesService.QueryDevicesResponse, Error> {\n return EffectEx.streamFromEmitter<DevicesService.QueryDevicesResponse, Error>((emit) => {\n const update = () => {\n const deviceKeys = this._identityManager.identity?.authorizedDeviceKeys;\n if (!deviceKeys) {\n void emit.single({ devices: [] });\n } else {\n invariant(this._identityManager.identity?.presence, 'presence not present');\n const identityPresence = this._identityManager.identity.presence;\n void emit.single({\n devices: Array.from(deviceKeys.entries()).map(([key, profile]) => {\n const isMe = this._identityManager.identity?.deviceKey.equals(key);\n let presence;\n if (isMe) {\n presence = Device_PresenceState.ONLINE;\n } else if (profile.os?.toUpperCase() === 'EDGE') {\n presence =\n this._edgeConnection?.status.state === EdgeStatus_ConnectionState.CONNECTED\n ? Device_PresenceState.ONLINE\n : Device_PresenceState.OFFLINE;\n } else {\n presence =\n identityPresence.getPeersByIdentityKey(key).length > 0\n ? Device_PresenceState.ONLINE\n : Device_PresenceState.OFFLINE;\n }\n\n return buf.create(DeviceSchema, {\n deviceKey: fromPublicKey(key),\n kind: this._identityManager.identity?.deviceKey.equals(key) ? DeviceKind.CURRENT : DeviceKind.TRUSTED,\n profile: profile,\n presence,\n });\n }),\n });\n }\n };\n\n let identitySubscribed = false;\n let presenceSubscribed = false;\n const subscribeIdentity = () => {\n if (!identitySubscribed) {\n this._identityManager.identity?.stateUpdate.on(() => {\n update();\n });\n identitySubscribed = true;\n }\n };\n\n const subscribePresence = () => {\n if (!presenceSubscribed) {\n this._identityManager.identity?.presence?.updated.on(() => {\n update();\n });\n presenceSubscribed = true;\n }\n };\n\n const subscriptions = new SubscriptionList();\n\n if (this._identityManager.identity) {\n subscribeIdentity();\n subscribePresence();\n }\n\n subscriptions.add(\n this._identityManager.stateUpdate.on(() => {\n update();\n\n if (this._identityManager.identity) {\n subscribeIdentity();\n subscribePresence();\n }\n }),\n );\n\n update();\n\n return Effect.sync(() => subscriptions.clear());\n });\n }\n}\n\nexport const DevicesServiceLayer = Layer.effect(\n DevicesService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n // Edge connection is absent in the non-edge stack, so resolve it optionally.\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n return new DevicesServiceImpl(identityManager, edgeConnection);\n }),\n);\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport { timestampFromDate } from '@bufbuild/protobuf/wkt';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { PublicKey } from '@dxos/keys';\nimport { type LogLevel, type LogProcessor, type LogEntry as NaturalLogEntry, log } from '@dxos/log';\nimport {\n type LogEntry,\n LogEntrySchema,\n type QueryLogsRequest,\n type QueryLogsRequest_Filter,\n QueryLogsRequest_MatchingOptions,\n} from '@dxos/protocols/buf/dxos/client/logging_pb';\nimport { LoggingService } from '@dxos/protocols/rpc';\nimport { numericalValues, tracer } from '@dxos/util';\n\n/**\n * Logging service used to spy on logs of the host.\n *\n * @deprecated This was created so that logs from the shared worker (WorkerClientServices) could be\n * seen in the main window console without opening the shared worker DevTools. Shared worker client\n * services is deprecated; dedicated worker logs already show in the main window console.\n */\nexport class LoggingServiceImpl implements LoggingService.Handlers {\n private readonly '_logs' = new Event<NaturalLogEntry>();\n private readonly '_started' = Date.now();\n private readonly '_sessionId' = PublicKey.random().toHex();\n\n async 'open'(): Promise<void> {\n log.runtimeConfig.processors.push(this._logProcessor);\n }\n\n async 'close'(): Promise<void> {\n const index = log.runtimeConfig.processors.findIndex((processor: LogProcessor) => processor === this._logProcessor);\n log.runtimeConfig.processors.splice(index, 1);\n }\n\n ['LoggingService.controlMetrics']({\n reset,\n record,\n }: LoggingService.ControlMetricsRequest): Effect.Effect<LoggingService.ControlMetricsResponse, Error> {\n return Effect.sync(() => {\n if (reset) {\n tracer.clear();\n }\n\n if (record === true) {\n tracer.start();\n } else if (record === false) {\n tracer.stop();\n }\n\n return { recording: tracer.recording };\n });\n }\n\n /**\n * @deprecated (Move to diagnostics).\n */\n ['LoggingService.queryMetrics']({\n interval = 5_000,\n }: LoggingService.QueryMetricsRequest): EffectStream.Stream<LoggingService.QueryMetricsResponse, Error> {\n // TODO(burdon): Map all traces; how to bind to reducer/metrics shape (e.g., numericalValues)?\n const getNumericalValues = (key: string) => {\n const events = tracer.get(key) ?? [];\n return { key, stats: numericalValues(events, 'duration') };\n };\n\n return EffectEx.streamFromEmitter<LoggingService.QueryMetricsResponse, Error>((emit) => {\n const update = () => {\n const metrics: LoggingService.Metrics = {\n timestamp: new Date(),\n values: [\n getNumericalValues('dxos.echo.pipeline.control'),\n getNumericalValues('dxos.echo.pipeline.data'),\n ].filter(Boolean) as LoggingService.KeyPair[],\n };\n\n void emit.single({\n timestamp: new Date(),\n metrics,\n });\n };\n\n update();\n const i = setInterval(update, Math.max(interval, 1_000));\n return Effect.sync(() => {\n clearInterval(i);\n });\n });\n }\n\n ['LoggingService.queryLogs'](request: QueryLogsRequest): EffectStream.Stream<LogEntry, Error> {\n return EffectEx.streamFromEmitter<LogEntry, Error>((emit) => {\n const ctx = Context.default();\n const handler = (entry: NaturalLogEntry) => {\n // This call was caused by the logging service itself.\n if (LOG_PROCESSING > 0) {\n return;\n }\n\n // Prevent logging feedback loop from logging service.\n if (\n entry.meta?.F.includes('logging-service') ||\n (entry.context &&\n Object.values(entry.context).some((value) => typeof value === 'string' && value.includes('LoggingService')))\n ) {\n return;\n }\n\n if (!shouldLog(entry, request)) {\n return;\n }\n\n const { filename, line, context: scopeName } = entry.computedMeta;\n const recordContext: Record<string, any> = { ...entry.computedContext };\n if (entry.computedError !== undefined) {\n recordContext.error = entry.computedError;\n }\n\n const record: LogEntry = create(LogEntrySchema, {\n level: entry.level,\n message: entry.message ?? entry.computedError ?? '',\n context: recordContext,\n timestamp: timestampFromDate(new Date(entry.timestamp)),\n meta: {\n // TODO(dmaretskyi): Fix proto.\n file: filename ?? '',\n line: line ?? 0,\n scope: {\n hostSessionId: this._sessionId,\n uptimeSeconds: (Date.now() - this._started) / 1000,\n name: scopeName ?? '',\n },\n },\n });\n\n try {\n LOG_PROCESSING++;\n void emit.single(record);\n } finally {\n LOG_PROCESSING--;\n }\n };\n\n this._logs.on(ctx, handler);\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n private '_logProcessor': LogProcessor = (_config, entry) => {\n this._logs.emit(entry);\n };\n}\n\nconst matchFilter = (\n filter: QueryLogsRequest_Filter,\n level: LogLevel,\n path: string,\n options: QueryLogsRequest_MatchingOptions,\n) => {\n switch (options) {\n case QueryLogsRequest_MatchingOptions.INCLUSIVE:\n return level >= filter.level && (!filter.pattern || path.includes(filter.pattern));\n case QueryLogsRequest_MatchingOptions.EXPLICIT:\n return level === filter.level && (!filter.pattern || path.includes(filter.pattern));\n }\n};\n\n/**\n * Determines if the current line should be logged (called by the processor).\n */\nconst shouldLog = (entry: NaturalLogEntry, request: QueryLogsRequest): boolean => {\n // buf represents an unset `repeated` as `[]` and an unset enum as its zero value, never\n // `undefined`, so absence is read off those rather than off `undefined` — the previous\n // `filters === undefined` branch is unreachable here and an empty filter list would otherwise\n // flip \"log everything\" into \"log nothing\".\n const options =\n request.options === undefined || request.options === QueryLogsRequest_MatchingOptions.NONE\n ? QueryLogsRequest_MatchingOptions.INCLUSIVE\n : request.options;\n if (request.filters.length === 0) {\n return options === QueryLogsRequest_MatchingOptions.INCLUSIVE;\n }\n return request.filters.some((filter) => matchFilter(filter, entry.level, entry.meta?.F ?? '', options));\n};\n\n/**\n * Counter that is used to track whether we are processing a log entry.\n */\nlet LOG_PROCESSING = 0;\n\n/**\n * The impl installs a log processor on open and removes it on close, so its lifecycle is bound to\n * the layer scope.\n */\nexport const LoggingServiceLayer: Layer.Layer<LoggingService.Tag> = Layer.effect(\n LoggingService.Tag,\n Effect.gen(function* () {\n const service = new LoggingServiceImpl();\n yield* Effect.acquireRelease(\n Effect.promise(() => service.open()),\n () => Effect.promise(() => service.close()),\n );\n return service;\n }),\n);\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { type SignalManager, SignalManagerService, type UnsubscribeCallback } from '@dxos/messaging';\nimport { type SwarmNetworkManager, SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { toServiceError } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport { type NetworkStatus, NetworkStatusSchema } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type SwarmResponse } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport {\n type JoinRequest,\n type LeaveRequest,\n type Message,\n type QueryRequest,\n} from '@dxos/protocols/buf/dxos/edge/signal_pb';\nimport { NetworkService } from '@dxos/protocols/rpc';\n\nexport class NetworkServiceImpl implements NetworkService.Handlers {\n 'constructor'(\n private readonly networkManager: SwarmNetworkManager,\n private readonly signalManager: SignalManager,\n private readonly edgeConnection?: EdgeConnection,\n ) {}\n\n ['NetworkService.queryStatus'](): EffectStream.Stream<NetworkStatus, Error> {\n return EffectEx.streamFromEmitter<NetworkStatus, Error>((emit) => {\n const ctx = Context.default();\n const update = () => {\n void emit.single(\n buf.create(NetworkStatusSchema, {\n swarm: this.networkManager.connectionState,\n connectionInfo: this.networkManager.connectionLog?.swarms ?? [],\n signaling: this.signalManager.getStatus?.().map(({ host, state }) => ({ server: host, state })),\n }),\n );\n };\n\n this.networkManager.connectionStateChanged.on(ctx, () => update());\n this.signalManager.statusChanged?.on(ctx, () => update());\n update();\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['NetworkService.updateConfig'](request: NetworkService.UpdateConfigRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n await this.networkManager.setConnectionState(request.swarm);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.joinSwarm'](request: JoinRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n await this.signalManager.join(Context.default(), request);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.leaveSwarm'](request: LeaveRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n await this.signalManager.leave(Context.default(), request);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.querySwarm'](request: QueryRequest): Effect.Effect<SwarmResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n return this.signalManager.query(Context.default(), request);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.subscribeSwarmState'](\n request: NetworkService.SubscribeSwarmStateRequest,\n ): EffectStream.Stream<SwarmResponse, Error> {\n return EffectEx.streamFromEmitter<SwarmResponse, Error>((emit) => {\n const ctx = Context.default();\n this.signalManager.swarmState?.on(ctx, (state) => {\n if (request.topic.toHex() === state.swarmKey) {\n void emit.single(state);\n }\n });\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['NetworkService.sendMessage'](message: Message): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n await this.signalManager.sendMessage(Context.default(), message);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.subscribeMessages'](\n request: NetworkService.SubscribeMessagesRequest,\n ): EffectStream.Stream<Message, Error> {\n const { peer, tags = [] } = request;\n return EffectEx.streamFromEmitter<Message, Error>((emit) => {\n const ctx = Context.default();\n\n // The subscription encapsulates routing (DX-1125): point-to-point messages addressed to `peer`,\n // plus — when `tags` are set — swarm broadcasts whose tags intersect. The returned callback owns\n // teardown, refcounted so it releases only this stream's tag registration.\n let unsubscribe: UnsubscribeCallback | undefined;\n void this.signalManager\n .subscribeMessages({\n peer,\n tags,\n onMessage: (message) => {\n void emit.single(message);\n },\n })\n .then((unsub) => {\n if (ctx.disposed) {\n void unsub();\n } else {\n unsubscribe = unsub;\n }\n })\n .catch((err) => emit.fail(err instanceof Error ? err : new Error(String(err))));\n\n return Effect.promise(async () => {\n await unsubscribe?.();\n await ctx.dispose();\n });\n });\n }\n}\n\nexport const NetworkServiceLayer: Layer.Layer<\n NetworkService.Tag,\n never,\n SwarmNetworkManagerService | SignalManagerService\n> = Layer.effect(\n NetworkService.Tag,\n Effect.gen(function* () {\n const networkManager = yield* SwarmNetworkManagerService;\n const signalManager = yield* SignalManagerService;\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n return new NetworkServiceImpl(networkManager, signalManager, edgeConnection);\n }),\n);\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Context, Resource } from '@dxos/context';\nimport { type CredentialProcessor, type SpecificCredential, specificCredential } from '@dxos/credentials';\nimport { type Credential, type Epoch } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nexport class AutomergeSpaceState extends Resource implements CredentialProcessor {\n public rootUrl: string | undefined = undefined;\n public lastEpoch: SpecificCredential<Epoch> | undefined = undefined;\n\n public readonly onNewEpoch = new Event<SpecificCredential<Epoch>>();\n\n private _isProcessingRootDocs = false;\n\n constructor(private readonly _onNewRoot: (rootUrl: string) => void) {\n super();\n }\n\n protected override async _open(ctx: Context): Promise<void> {}\n\n protected override async _close(ctx: Context): Promise<void> {\n this._isProcessingRootDocs = false;\n }\n\n async processCredential(credential: Credential): Promise<void> {\n const epoch = specificCredential<Epoch>(credential, 'dxos.halo.credentials.Epoch');\n if (!epoch) {\n return;\n }\n\n this.lastEpoch = epoch;\n if (epoch.assertion.automergeRoot) {\n this.rootUrl = epoch.assertion.automergeRoot;\n\n if (this._isProcessingRootDocs) {\n this._onNewRoot(this.rootUrl);\n }\n }\n\n this.onNewEpoch.emit(epoch);\n }\n\n startProcessingRootDocs(): void {\n if (this._isProcessingRootDocs) {\n return;\n }\n\n if (this.rootUrl) {\n this._onNewRoot(this.rootUrl);\n }\n this._isProcessingRootDocs = true;\n }\n\n async ensureEpochInitialized(): Promise<void> {\n await this.onNewEpoch.waitForCondition(() => !!this.lastEpoch);\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport type { AutomergeUrl } from '@automerge/automerge-repo';\n\nimport { type Context } from '@dxos/context';\nimport { type EchoHost } from '@dxos/echo-host';\nimport { invariant } from '@dxos/invariant';\nimport type { PublicKey, SpaceId } from '@dxos/keys';\nimport { SpacesService } from '@dxos/protocols/rpc';\n\nexport type MigrationContext = {\n echoHost: EchoHost;\n\n spaceId: SpaceId;\n /**\n * @deprecated Remove.\n */\n spaceKey: PublicKey;\n migration: SpacesService.Migration;\n currentRoot: string | null;\n\n /**\n * For set automerge root migration type.\n */\n newAutomergeRoot?: string;\n};\n\nexport type MigrationResult = {\n newRoot?: string;\n};\n\nconst LOAD_DOC_TIMEOUT = 10_000;\n\nexport const runEpochMigration = async (ctx: Context, context: MigrationContext): Promise<MigrationResult> => {\n switch (context.migration) {\n case SpacesService.Migration.enums.INIT_AUTOMERGE: {\n using document = await context.echoHost.createDoc();\n await context.echoHost.flush(ctx);\n return { newRoot: document.url };\n }\n case SpacesService.Migration.enums.PRUNE_AUTOMERGE_ROOT_HISTORY: {\n if (!context.currentRoot) {\n throw new Error('Space does not have an automerge root');\n }\n using rootLease = await context.echoHost.loadDoc(ctx, context.currentRoot as AutomergeUrl, {\n timeout: LOAD_DOC_TIMEOUT,\n });\n invariant(rootLease, 'Automerge root document must load for history prune migration.');\n\n using newRoot = await context.echoHost.createDoc(rootLease.doc());\n await context.echoHost.flush(ctx);\n return { newRoot: newRoot.url };\n }\n case SpacesService.Migration.enums.FRAGMENT_AUTOMERGE_ROOT: {\n throw new Error('Migration not available');\n }\n case SpacesService.Migration.enums.MIGRATE_REFERENCES_TO_DXN: {\n throw new Error('Migration not available');\n }\n // TODO(dmaretskyi): This path doesn't seem to fit here. This is not a migration.\n case SpacesService.Migration.enums.REPLACE_AUTOMERGE_ROOT: {\n invariant(context.newAutomergeRoot);\n\n // Defensive programming - it should be the responsibility of the caller to flush the new root.\n await context.echoHost.flush(ctx);\n return {\n newRoot: context.newAutomergeRoot,\n };\n }\n }\n\n return {};\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { create, fromBinary, toBinary } from '@bufbuild/protobuf';\nimport { EmptySchema } from '@bufbuild/protobuf/wkt';\n\nimport { DeferredTask, Event, TimeoutError, Trigger, scheduleMicroTask, scheduleTask, sleep } from '@dxos/async';\nimport { type Context, Resource, rejectOnDispose } from '@dxos/context';\nimport { type CredentialProcessor, verifyCredential } from '@dxos/credentials';\nimport { type EdgeHttpClient } from '@dxos/edge-client';\nimport { type HypercoreWriter } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { type SpaceId } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { EdgeCallFailedError } from '@dxos/protocols';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type Credential, CredentialSchema } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n NotarizationService as NotarizationServiceDesc,\n type NotarizeRequest,\n NotarizeRequestSchema,\n} from '@dxos/protocols/buf/dxos/mesh/teleport/notarization_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\nimport { ComplexMap, ComplexSet, entry } from '@dxos/util';\n\nconst DEFAULT_RETRY_TIMEOUT = 1_000;\n\nconst DEFAULT_SUCCESS_DELAY = 1_000;\n\nconst DEFAULT_NOTARIZE_TIMEOUT = 10_000;\n\nconst DEFAULT_ACTIVE_EDGE_POLLING_INTERVAL = 3_000;\n\nconst MAX_EDGE_RETRIES = 5;\n\nconst WRITER_NOT_SET_ERROR_CODE = 'WRITER_NOT_SET';\n\ntype NotarizationService = BufService<typeof NotarizationServiceDesc>;\n\nexport type NotarizationPluginProps = {\n spaceId: SpaceId;\n edgeClient?: EdgeHttpClient;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n activeEdgePollingInterval?: number;\n};\n\nexport type NotarizeProps = {\n /**\n * For cancellation.\n */\n ctx?: Context;\n\n /**\n * Credentials to notarize.\n */\n credentials: Credential[];\n\n /**\n * Timeout for the whole notarization process.\n * Set to 0 to disable.\n * @default {@link DEFAULT_NOTARIZE_TIMEOUT}\n */\n timeout?: number;\n\n /**\n * Retry timeout.\n * @default {@link DEFAULT_RETRY_TIMEOUT}\n */\n retryTimeout?: number;\n\n /**\n * Minimum wait time after a peer confirms successful notarization before attempting with a new peer.\n * This is to avoid spamming peers with notarization requests.\n * @default {@link DEFAULT_SUCCESS_DELAY}\n */\n successDelay?: number;\n\n /**\n * A random amount of time before making or retrying an edge request to help prevent large bursts of requests.\n */\n edgeRetryJitter?: number;\n};\n\n/**\n * See NotarizationService proto.\n */\nexport class NotarizationPlugin extends Resource implements CredentialProcessor {\n private readonly _extensionOpened = new Event();\n\n private _writer: HypercoreWriter<Credential> | undefined;\n private readonly _extensions = new Set<NotarizationTeleportExtension>();\n private readonly _processedCredentials = new ComplexSet<PublicKey>(PublicKey.hash);\n private readonly _processCredentialsTriggers = new ComplexMap<PublicKey, Trigger>(PublicKey.hash);\n\n private _activeEdgePollingIntervalHandle: any | undefined = undefined;\n private readonly _activeEdgePollingInterval: number;\n private _activeEdgePollingEnabled = false;\n\n @logInfo\n private readonly _spaceId: SpaceId;\n\n private readonly _edgeClient: EdgeHttpClient | undefined;\n\n constructor(params: NotarizationPluginProps) {\n super();\n this._spaceId = params.spaceId;\n this._activeEdgePollingInterval = params.activeEdgePollingInterval ?? DEFAULT_ACTIVE_EDGE_POLLING_INTERVAL;\n if (params.edgeClient && params.edgeFeatures?.feedReplicator) {\n this._edgeClient = params.edgeClient;\n }\n }\n\n setActiveEdgePollingEnabled(enabled: boolean): void {\n const client = this._edgeClient;\n invariant(client);\n this._activeEdgePollingEnabled = enabled;\n if (this.isOpen) {\n if (enabled && !this._activeEdgePollingIntervalHandle) {\n this._startPeriodicEdgePolling(client);\n } else if (!enabled && this._activeEdgePollingIntervalHandle) {\n this._stopPeriodicEdgePolling();\n }\n }\n }\n\n get hasWriter() {\n return !!this._writer;\n }\n\n protected override async _open(): Promise<void> {\n if (this._edgeClient) {\n if (this._activeEdgePollingEnabled) {\n this._startPeriodicEdgePolling(this._edgeClient);\n }\n if (this._writer) {\n this._notarizePendingEdgeCredentials(this._edgeClient, this._writer);\n }\n }\n }\n\n protected override async _close(): Promise<void> {\n this._stopPeriodicEdgePolling();\n await this._ctx.dispose();\n }\n\n /**\n * Request credentials to be notarized.\n */\n async notarize({\n ctx: opCtx,\n credentials,\n timeout = DEFAULT_NOTARIZE_TIMEOUT,\n retryTimeout = DEFAULT_RETRY_TIMEOUT,\n successDelay = DEFAULT_SUCCESS_DELAY,\n edgeRetryJitter,\n }: NotarizeProps): Promise<void> {\n log('notarize', { credentials });\n invariant(\n credentials.every((credential) => credential.id),\n 'Credentials must have an id',\n );\n\n const errors = new Trigger();\n const ctx = this._ctx.derive({\n onError: (err) => {\n log.warn('Notarization error', { err });\n void ctx.dispose();\n errors.throw(err);\n },\n });\n opCtx?.onDispose(() => ctx.dispose());\n\n if (timeout !== 0) {\n this._scheduleTimeout(ctx, errors, timeout);\n }\n\n const allNotarized = Promise.all(\n credentials.map((credential) => this._waitUntilProcessed(requirePublicKey(credential.id))),\n );\n\n this._tryNotarizeCredentialsWithPeers(ctx, credentials, { retryTimeout, successDelay });\n\n if (this._edgeClient) {\n this._tryNotarizeCredentialsWithEdge(ctx, this._edgeClient, credentials, {\n retryTimeout,\n successDelay,\n jitter: edgeRetryJitter,\n });\n }\n\n try {\n await Promise.race([rejectOnDispose(ctx), allNotarized, errors.wait()]);\n log('done');\n } finally {\n await ctx.dispose();\n }\n }\n\n private _tryNotarizeCredentialsWithPeers(\n ctx: Context,\n credentials: Credential[],\n { retryTimeout, successDelay }: NotarizationTimeouts,\n ): void {\n const peersTried = new Set<NotarizationTeleportExtension>();\n\n // Repeatable task that tries to notarize credentials with one of the available peers.\n const notarizeTask = new DeferredTask(ctx, async () => {\n try {\n if (this._extensions.size === 0) {\n return; // No peers to try.\n }\n\n // Pick a peer that we haven't tried yet.\n const peer = [...this._extensions].find((peer) => !peersTried.has(peer));\n if (!peer) {\n log.info('Exhausted all peers to notarize with', { retryIn: retryTimeout });\n peersTried.clear();\n scheduleTask(ctx, () => notarizeTask.schedule(), retryTimeout); // retry with all peers again\n return;\n }\n\n peersTried.add(peer);\n log('try notarizing', { peer: peer.localPeerId, credentialId: credentials.map((credential) => credential.id) });\n await peer.rpc.NotarizationService.notarize(\n create(NotarizeRequestSchema, {\n credentials: credentials.filter(\n (credential) => !this._processedCredentials.has(requirePublicKey(credential.id)),\n ),\n }),\n );\n log('success');\n\n await sleep(successDelay); // wait before trying with a new peer\n } catch (err: any) {\n if (!ctx.disposed && !err.message.includes(WRITER_NOT_SET_ERROR_CODE)) {\n log.info('error notarizing (recoverable)', err);\n }\n notarizeTask.schedule(); // retry immediately with next peer\n }\n });\n\n notarizeTask.schedule();\n this._extensionOpened.on(ctx, () => notarizeTask.schedule());\n }\n\n private _tryNotarizeCredentialsWithEdge(\n ctx: Context,\n client: EdgeHttpClient,\n credentials: Credential[],\n timeouts: NotarizationTimeouts & { jitter?: number },\n ): void {\n const encodedCredentials = credentials.map((credential) => {\n const binary = toBinary(CredentialSchema, credential);\n return Buffer.from(binary).toString('base64');\n });\n scheduleTask(ctx, async () => {\n try {\n await client.notarizeCredentials(\n ctx,\n this._spaceId,\n { credentials: encodedCredentials },\n { retry: { count: MAX_EDGE_RETRIES, timeout: timeouts.retryTimeout, jitter: timeouts.jitter } },\n );\n\n log('edge notarization success');\n } catch (error: any) {\n handleEdgeError(error);\n }\n });\n }\n\n /**\n * Called with credentials arriving from the control pipeline.\n */\n async processCredential(credential: Credential): Promise<void> {\n if (!credential.id) {\n return;\n }\n const id = requirePublicKey(credential.id);\n this._processCredentialsTriggers.get(id)?.wake();\n this._processedCredentials.add(id);\n this._processCredentialsTriggers.delete(id);\n }\n\n setWriter(writer: HypercoreWriter<Credential>): void {\n invariant(!this._writer, 'Writer already set.');\n this._writer = writer;\n if (this._edgeClient && this.isOpen) {\n this._notarizePendingEdgeCredentials(this._edgeClient, writer);\n }\n }\n\n private _startPeriodicEdgePolling(client: EdgeHttpClient): void {\n this._activeEdgePollingIntervalHandle = setInterval(() => {\n if (this._writer) {\n this._notarizePendingEdgeCredentials(client, this._writer);\n }\n }, this._activeEdgePollingInterval);\n }\n\n private _stopPeriodicEdgePolling(): void {\n if (this._activeEdgePollingIntervalHandle) {\n clearInterval(this._activeEdgePollingIntervalHandle);\n this._activeEdgePollingIntervalHandle = undefined;\n }\n }\n\n /**\n * The method is used only for adding agent feeds to spaces.\n * When an agent is created we can admit them into all the existing spaces. In case the operation fails\n * this method will fix it on the next space open.\n * Given how rarely this happens there's no need to poll the endpoint.\n */\n private _notarizePendingEdgeCredentials(client: EdgeHttpClient, writer: HypercoreWriter<Credential>): void {\n scheduleMicroTask(this._ctx, async () => {\n try {\n const response = await client.getCredentialsForNotarization(this._ctx, this._spaceId, {\n retry: { count: MAX_EDGE_RETRIES },\n });\n\n const credentials = response.awaitingNotarization.credentials;\n if (!credentials.length) {\n log('edge did not return credentials for notarization');\n return;\n }\n\n log('got edge credentials for notarization', { count: credentials.length });\n\n const decodedCredentials = credentials.map((credential) => {\n const binary = Buffer.from(credential, 'base64');\n return fromBinary(CredentialSchema, binary);\n });\n\n await this._notarizeCredentials(writer, decodedCredentials);\n\n log.info('notarized edge credentials', { count: decodedCredentials.length });\n } catch (error: any) {\n handleEdgeError(error);\n }\n });\n }\n\n private async _waitUntilProcessed(id: PublicKey): Promise<void> {\n if (this._processedCredentials.has(id)) {\n return;\n }\n await entry(this._processCredentialsTriggers, id).orInsert(new Trigger()).value.wait();\n }\n\n /**\n * Requests from other peers to notarize credentials.\n */\n private async _onNotarize(request: NotarizeRequest): Promise<void> {\n if (!this._writer) {\n throw new Error(WRITER_NOT_SET_ERROR_CODE);\n }\n await this._notarizeCredentials(this._writer, request.credentials ?? []);\n }\n\n private async _notarizeCredentials(writer: HypercoreWriter<Credential>, credentials: Credential[]): Promise<void> {\n for (const credential of credentials) {\n const credentialId = requirePublicKey(credential.id);\n if (this._processedCredentials.has(credentialId)) {\n continue;\n }\n const verificationResult = await verifyCredential(credential);\n if (verificationResult.kind === 'fail') {\n throw new Error(`Credential verification failed: ${verificationResult.errors.join('\\n')}.`);\n }\n await writer.write(credential);\n }\n }\n\n createExtension(): NotarizationTeleportExtension {\n const extension = new NotarizationTeleportExtension({\n onOpen: async () => {\n log('extension opened', { peer: extension.localPeerId });\n this._extensions.add(extension);\n this._extensionOpened.emit();\n },\n onClose: async () => {\n log('extension closed', { peer: extension.localPeerId });\n this._extensions.delete(extension);\n },\n onNotarize: this._onNotarize.bind(this),\n });\n return extension;\n }\n\n private _scheduleTimeout(ctx: Context, errors: Trigger, timeout: number): void {\n scheduleTask(\n ctx,\n () => {\n log.warn('Notarization timeout', {\n timeout,\n peers: Array.from(this._extensions).map((extension) => extension.remotePeerId),\n });\n void ctx.dispose();\n errors.throw(new TimeoutError(timeout, 'Notarization timed out'));\n },\n timeout,\n );\n }\n}\n\nconst handleEdgeError = (error: any) => {\n if (!(error instanceof EdgeCallFailedError) || error.data) {\n log.catch(error);\n } else {\n log.info('Edge notarization failure', { message: error.message });\n }\n};\n\nexport type NotarizationTeleportExtensionProps = {\n onOpen: () => Promise<void>;\n onClose: () => Promise<void>;\n onNotarize: (request: NotarizeRequest) => Promise<void>;\n};\n\nexport class NotarizationTeleportExtension extends RpcExtension<Services, Services> {\n constructor(private readonly _params: NotarizationTeleportExtensionProps) {\n super({\n requested: {\n NotarizationService: getBufService<NotarizationService>('dxos.mesh.teleport.notarization.NotarizationService'),\n },\n exposed: {\n NotarizationService: getBufService<NotarizationService>('dxos.mesh.teleport.notarization.NotarizationService'),\n },\n });\n }\n\n protected async getHandlers(): Promise<Services> {\n return {\n NotarizationService: {\n notarize: async (request) => {\n await this._params.onNotarize(request);\n return create(EmptySchema, {});\n },\n },\n };\n }\n\n override async onOpen(ctx: ExtensionContext): Promise<void> {\n await super.onOpen(ctx);\n await this._params.onOpen();\n }\n\n override async onClose(err?: Error | undefined): Promise<void> {\n await this._params.onClose();\n await super.onClose(err);\n }\n}\n\ntype NotarizationTimeouts = {\n retryTimeout: number;\n successDelay: number;\n};\n\ntype Services = {\n NotarizationService: NotarizationService;\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { save } from '@automerge/automerge';\nimport { type AutomergeUrl, parseAutomergeUrl } from '@automerge/automerge-repo';\nimport { create, equals } from '@bufbuild/protobuf';\n\nimport { Event, Mutex, scheduleTask, sleep, sleepWithContext, synchronized, trackLeaks } from '@dxos/async';\nimport { AUTH_TIMEOUT } from '@dxos/client-protocol';\nimport { Context, ContextDisposedError } from '@dxos/context';\nimport { credentialPayload } from '@dxos/credentials';\nimport { timed, warnAfterTimeout } from '@dxos/debug';\nimport { type DatabaseRoot, type DocumentLease, type EchoHost } from '@dxos/echo-host';\nimport { type DatabaseDirectory, SpaceDocVersion } from '@dxos/echo-protocol';\nimport type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';\nimport { type HypercoreStore, type HypercoreWrapper } from '@dxos/feed-store';\nimport { failedInvariant, invariant } from '@dxos/invariant';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { CancelledError, type FeedProtocol, SystemError } from '@dxos/protocols';\nimport { fromDate, fromPublicKey, fromTimeframe } from '@dxos/protocols/buf';\nimport { SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type Space_Metrics, Space_MetricsSchema } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type FeedMessage, type FeedMessage_Payload } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport {\n AdmittedFeed_Designation,\n AdmittedFeedSchema,\n type Credential,\n type Epoch,\n EpochSchema,\n MemberProfileSchema,\n MembershipPolicy,\n type ProfileDocument,\n ProfileDocumentSchema,\n SpaceMember_Role,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type GossipMessage } from '@dxos/protocols/buf/dxos/mesh/teleport/gossip_pb';\nimport { type SpacesService } from '@dxos/protocols/rpc';\nimport { type Gossip, type Presence } from '@dxos/teleport-extension-gossip';\nimport { Timeframe } from '@dxos/timeframe';\nimport { trace } from '@dxos/tracing';\nimport { type AsyncCallback, CallbackCollection, ComplexSet } from '@dxos/util';\n\nimport * as Auth from '../../Auth.ts';\nimport { EdgeFeedReplicator } from '../../Replication.ts';\nimport { type IMetadataStore } from '../metadata/index.ts';\nimport { createMappedFeedWriter } from '../pipeline/index.ts';\nimport { type Space } from '../space/index.ts';\nimport { AutomergeSpaceState } from './automerge-space-state.ts';\nimport { type SigningContext } from './data-space-manager.ts';\nimport { runEpochMigration } from './epoch-migrations.ts';\nimport { NotarizationPlugin } from './notarization-plugin.ts';\n\nexport type DataSpaceCallbacks = {\n /**\n * Called before transitioning to the ready state.\n */\n beforeReady?: () => Promise<void>;\n\n /**\n * Called after transitioning to the ready state.\n */\n afterReady?: () => Promise<void>;\n\n /**\n * Called before space gets closed.\n */\n beforeClose?: () => Promise<void>;\n};\n\nexport type DataSpaceProps = {\n initialState: SpaceState;\n inner: Space;\n metadataStore: IMetadataStore;\n gossip: Gossip;\n presence: Presence;\n keyring: KeyringApi;\n hypercoreStore: HypercoreStore<FeedMessage>;\n echoHost: EchoHost;\n signingContext: SigningContext;\n callbacks?: DataSpaceCallbacks;\n tags?: string[];\n edgeConnection?: EdgeConnection;\n edgeHttpClient?: EdgeHttpClient;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n activeEdgeNotarizationPollingInterval?: number;\n};\n\nexport type CreateEpochOptions = {\n migration?: SpacesService.Migration;\n newAutomergeRoot?: string;\n};\n\nconst ROOT_DOC_LOAD_ATTEMPT_TIMEOUT = 20_000;\n\nconst ROOT_DOC_LOAD_RETRY_INITIAL_DELAY = 1_000;\nconst ROOT_DOC_LOAD_RETRY_MAX_DELAY = 30_000;\n\n@trackLeaks('open', 'close')\nexport class DataSpace {\n private _ctx = new Context();\n private readonly _inner: Space;\n\n private readonly _gossip: Gossip;\n private readonly _presence: Presence;\n private readonly _keyring: KeyringApi;\n private readonly _hypercoreStore: HypercoreStore<FeedMessage>;\n private readonly _metadataStore: IMetadataStore;\n private readonly _signingContext: SigningContext;\n private readonly _notarizationPlugin: NotarizationPlugin;\n private readonly _callbacks: DataSpaceCallbacks;\n private readonly _echoHost: EchoHost;\n private readonly _edgeFeedReplicator?: EdgeFeedReplicator = undefined;\n\n // TODO(dmaretskyi): Move into Space?\n private readonly _automergeSpaceState = new AutomergeSpaceState((rootUrl) => this._onNewAutomergeRoot(rootUrl));\n\n private readonly _epochProcessingMutex = new Mutex();\n\n private _state = SpaceState.SPACE_CLOSED;\n\n /** Immutable tags from space metadata, available immediately. */\n readonly tags: string[];\n\n private _databaseRoot: DatabaseRoot | null = null;\n\n /**\n * Error for _state === SpaceState.SPACE_ERROR.\n */\n public error: Error | undefined = undefined;\n\n public readonly authVerifier: Auth.TrustedKeySetAuthVerifier;\n public readonly stateUpdate = new Event();\n\n public readonly postOpen = new CallbackCollection<AsyncCallback<void>>();\n public readonly preClose = new CallbackCollection<AsyncCallback<void>>();\n\n public metrics: Space_Metrics = create(Space_MetricsSchema, {});\n\n constructor(params: DataSpaceProps) {\n this._inner = params.inner;\n this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());\n\n this._gossip = params.gossip;\n this._presence = params.presence;\n this._keyring = params.keyring;\n this._hypercoreStore = params.hypercoreStore;\n this._metadataStore = params.metadataStore;\n this._signingContext = params.signingContext;\n this._callbacks = params.callbacks ?? {};\n this._echoHost = params.echoHost;\n this._notarizationPlugin = new NotarizationPlugin({\n spaceId: this._inner.id,\n edgeClient: params.edgeHttpClient,\n edgeFeatures: params.edgeFeatures,\n activeEdgePollingInterval: params.activeEdgeNotarizationPollingInterval,\n });\n\n this.authVerifier = new Auth.TrustedKeySetAuthVerifier({\n trustedKeysProvider: () =>\n new ComplexSet(\n PublicKey.hash,\n Array.from(this._inner.spaceState.members.values())\n .filter((member) => member.role !== SpaceMember_Role.REMOVED)\n .map((member) => member.key),\n ),\n update: this._inner.stateUpdate,\n authTimeout: AUTH_TIMEOUT,\n });\n\n this.tags = params.tags ?? [];\n\n if (params.edgeConnection && params.edgeFeatures?.feedReplicator) {\n this._edgeFeedReplicator = new EdgeFeedReplicator({ messenger: params.edgeConnection, spaceId: this.id });\n }\n\n this._state = params.initialState;\n log('new state', { state: SpaceState[this._state] });\n }\n\n get id() {\n return this._inner.id;\n }\n\n get key() {\n return this._inner.key;\n }\n\n get isOpen() {\n return this._inner.isOpen;\n }\n\n get state(): SpaceState {\n return this._state;\n }\n\n // TODO(burdon): Can we mark this for debugging only?\n get inner() {\n return this._inner;\n }\n\n get presence() {\n return this._presence;\n }\n\n get notarizationPlugin() {\n return this._notarizationPlugin;\n }\n\n /** Membership policy from the genesis credential, defaults to INVITE. */\n get membershipPolicy(): MembershipPolicy {\n return this._inner.spaceState.genesisCredential ? this._inner.spaceState.membershipPolicy : MembershipPolicy.INVITE;\n }\n\n get automergeSpaceState() {\n return this._automergeSpaceState;\n }\n\n get databaseRoot(): DatabaseRoot | null {\n return this._databaseRoot;\n }\n\n private get _automergeInfo() {\n return {\n rootUrl: this._automergeSpaceState.rootUrl,\n lastEpoch: this._automergeSpaceState.lastEpoch,\n };\n }\n\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async open(ctx: Context): Promise<void> {\n if (this._state === SpaceState.SPACE_CLOSED) {\n await this._open(ctx);\n }\n }\n\n private async _open(ctx: Context): Promise<void> {\n await this._presence.open();\n await this._gossip.open();\n await this._notarizationPlugin.open();\n await this._inner.spaceState.addCredentialProcessor(this._notarizationPlugin);\n await this._automergeSpaceState.open();\n await this._inner.spaceState.addCredentialProcessor(this._automergeSpaceState);\n\n if (this._edgeFeedReplicator) {\n this.inner.protocol.feedAdded.append(this._onFeedAdded);\n }\n\n await this._inner.open(ctx);\n await this._inner.startProtocol(ctx);\n\n await this._edgeFeedReplicator?.open();\n\n this._state = SpaceState.SPACE_CONTROL_ONLY;\n log('new state', { state: SpaceState[this._state] });\n this.stateUpdate.emit();\n this.metrics = create(Space_MetricsSchema, {});\n this.metrics.open = fromDate(new Date());\n\n await this.postOpen.callSerial();\n }\n\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async close(ctx: Context): Promise<void> {\n await this._close(ctx);\n }\n\n private async _close(ctx: Context): Promise<void> {\n await this._callbacks.beforeClose?.();\n\n await this.preClose.callSerial();\n\n this._state = SpaceState.SPACE_CLOSED;\n log('new state', { state: SpaceState[this._state] });\n await this._ctx.dispose();\n this._ctx = new Context();\n\n if (this._edgeFeedReplicator) {\n this.inner.protocol.feedAdded.remove(this._onFeedAdded);\n }\n\n await this._edgeFeedReplicator?.close();\n\n await this.authVerifier.close();\n\n await this._inner.close(ctx);\n await this._inner.spaceState.removeCredentialProcessor(this._automergeSpaceState);\n await this._automergeSpaceState.close();\n await this._inner.spaceState.removeCredentialProcessor(this._notarizationPlugin);\n await this._notarizationPlugin.close();\n\n await this._presence.close();\n await this._gossip.close();\n }\n\n async postMessage(channel: string, message: any): Promise<void> {\n return this._gossip.postMessage(channel, message);\n }\n\n listen(channel: string, callback: (message: GossipMessage) => void): { unsubscribe: () => void } {\n return this._gossip.listen(channel, callback);\n }\n\n /**\n * Initialize the data pipeline in a separate task.\n * @param callerCtx - Trace context from the caller (e.g., activate or createSpace) for span parenting.\n */\n initializeDataPipelineAsync(callerCtx?: Context): void {\n const traceCtx = callerCtx ?? this._ctx;\n scheduleTask(this._ctx, async () => {\n try {\n this.metrics.pipelineInitBegin = fromDate(new Date());\n await this.initializeDataPipeline(traceCtx);\n } catch (err) {\n if (err instanceof CancelledError || err instanceof ContextDisposedError) {\n log('data pipeline initialization cancelled', err);\n return;\n }\n\n log.error('Error initializing data pipeline', err);\n this._state = SpaceState.SPACE_ERROR;\n log('new state', { state: SpaceState[this._state] });\n this.error = err as Error;\n this.stateUpdate.emit();\n } finally {\n this.metrics.ready = fromDate(new Date());\n }\n });\n }\n\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async initializeDataPipeline(ctx: Context): Promise<void> {\n if (this._state !== SpaceState.SPACE_CONTROL_ONLY) {\n throw new SystemError({ message: 'Invalid operation' });\n }\n\n this._state = SpaceState.SPACE_INITIALIZING;\n log('new state', { state: SpaceState[this._state] });\n\n log('initializing control pipeline');\n await this._initializeAndReadControlPipeline(ctx);\n\n // Allow other tasks to run before loading the data pipeline.\n await sleep(1);\n\n const ready = this.stateUpdate.waitForCondition(() => this._state === SpaceState.SPACE_READY);\n\n log('initializing automerge root');\n const isPersisted = this._echoHost.spaces.some((s) => s.spaceId === this.id);\n if (isPersisted) {\n try {\n log('opening persisted space root', { spaceId: this.id });\n const root = await this._echoHost.openSpaceRoot(ctx, this.id);\n this._databaseRoot = root;\n if (root.getVersion() !== SpaceDocVersion.CURRENT) {\n this._state = SpaceState.SPACE_REQUIRES_MIGRATION;\n this.stateUpdate.emit();\n } else {\n await this._enterReadyState();\n }\n } catch (err) {\n log.warn('failed to open persisted space root, will wait for credentials', { spaceId: this.id, err });\n }\n }\n\n this._automergeSpaceState.startProcessingRootDocs();\n\n // TODO(dmaretskyi): Change so `initializeDataPipeline` doesn't wait for the space to be READY, but rather any state with a valid root.\n log('waiting for space to be ready');\n await ready;\n log('space is ready');\n }\n\n async *getAllDocuments(): AsyncIterable<[string, Uint8Array]> {\n invariant(this._databaseRoot, 'Space is not ready');\n const doc = this._databaseRoot.doc() ?? failedInvariant();\n const root = save(doc);\n yield [this._databaseRoot.documentId, root];\n\n for (const documentUrl of this._databaseRoot.getAllLinkedDocuments()) {\n const data = await this._echoHost.exportDoc(documentUrl);\n yield [documentUrl.replace(/^automerge:/, ''), data];\n }\n }\n\n /**\n * Get all feeds and their blocks for this space.\n * Used for space archive export.\n */\n async getAllFeeds(): Promise<Array<{ feedId: string; feedNamespace: string; blocks: FeedProtocol.Block[] }>> {\n return this._echoHost.getAllFeedsForSpace(this.id);\n }\n\n private async _enterReadyState(): Promise<void> {\n await this._callbacks.beforeReady?.();\n\n this._state = SpaceState.SPACE_READY;\n log('new state', { state: SpaceState[this._state] });\n this.stateUpdate.emit();\n\n await this._callbacks.afterReady?.();\n }\n\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n private async _initializeAndReadControlPipeline(ctx: Context): Promise<void> {\n await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({\n ctx,\n timeout: 10_000,\n breakOnStall: false,\n });\n\n this.metrics.controlPipelineReady = fromDate(new Date());\n\n await this._createWritableFeeds();\n log('writable feeds created');\n this.stateUpdate.emit();\n\n if (!this.notarizationPlugin.hasWriter) {\n this.notarizationPlugin.setWriter(\n createMappedFeedWriter<Credential, FeedMessage_Payload>(credentialPayload, this._inner.controlPipeline.writer),\n );\n }\n\n await this._syncOwnProfile();\n }\n\n /**\n * Rewrites this member's profile credential when it no longer matches the identity's profile, since\n * other members resolve this identity's name from the space and a profile set or changed while the\n * space was not open never reached it.\n */\n private async _syncOwnProfile(): Promise<void> {\n const profile = this._signingContext.getProfile();\n if (!profile) {\n return;\n }\n\n const self = Array.from(this._inner.spaceState.members.values()).find((member) =>\n member.key.equals(this._signingContext.identityKey),\n );\n if (!self || (self.profile && equals(ProfileDocumentSchema, self.profile, profile))) {\n return;\n }\n\n // A repair, not a precondition: a failed write must not keep the space from opening.\n try {\n await this.updateOwnProfile(profile);\n } catch (err) {\n log.warn('failed to sync own member profile', { space: this.key, err });\n }\n }\n\n @timed(10_000)\n private async _createWritableFeeds(): Promise<void> {\n const credentials: Credential[] = [];\n if (!this.inner.controlFeedKey) {\n const controlFeed = await this._hypercoreStore.openHypercore(await this._keyring.createKey(), { writable: true });\n await this.inner.setControlFeed(controlFeed);\n\n credentials.push(\n await this._signingContext.credentialSigner.createCredential({\n subject: controlFeed.key,\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(this.key),\n deviceKey: fromPublicKey(this._signingContext.deviceKey),\n identityKey: fromPublicKey(this._signingContext.identityKey),\n designation: AdmittedFeed_Designation.CONTROL,\n }),\n }),\n );\n }\n if (!this.inner.dataFeedKey) {\n const dataFeed = await this._hypercoreStore.openHypercore(await this._keyring.createKey(), {\n writable: true,\n sparse: true,\n });\n await this.inner.setDataFeed(dataFeed);\n\n credentials.push(\n await this._signingContext.credentialSigner.createCredential({\n subject: dataFeed.key,\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(this.key),\n deviceKey: fromPublicKey(this._signingContext.deviceKey),\n identityKey: fromPublicKey(this._signingContext.identityKey),\n designation: AdmittedFeed_Designation.DATA,\n }),\n }),\n );\n }\n\n if (credentials.length > 0) {\n try {\n log('will notarize credentials for feed admission', { count: credentials.length });\n // Never times out\n await this.notarizationPlugin.notarize({ ctx: this._ctx, credentials, timeout: 0 });\n\n log('credentials notarized');\n } catch (err) {\n if (err instanceof ContextDisposedError) {\n return;\n }\n log.error('error notarizing credentials for feed admission', err);\n throw err;\n }\n\n // Set this after credentials are notarized so that on failure we will retry.\n await this._metadataStore.setWritableFeedKeys(this.key, this.inner.controlFeedKey!, this.inner.dataFeedKey!);\n }\n }\n\n /**\n * Loads a space's root document, re-driving until it arrives or the space closes.\n *\n * `loadDoc` waits on the network with no deadline of its own, so a space whose root never\n * arrives would wait forever. The retry bounds each attempt and re-drives the document between\n * them: the repo-wide kick only revives `all-failed`/`no-peers` entries, and a root that stalls\n * after its first bytes land leaves a settled entry that neither the kick nor a fresh\n * `findWithProgress` re-issues.\n */\n async #loadRootDoc(rootUrl: AutomergeUrl): Promise<DocumentLease<DatabaseDirectory> | null> {\n for (let attempt = 0, delay = ROOT_DOC_LOAD_RETRY_INITIAL_DELAY; !this._ctx.disposed; attempt++) {\n try {\n if (attempt > 0) {\n this._echoHost.automergeHost.kickStalledSync();\n this._echoHost.automergeHost.resyncDocument(parseAutomergeUrl(rootUrl).documentId);\n }\n\n return await warnAfterTimeout(5_000, 'Automerge root doc load timeout (DataSpace)', () =>\n this._echoHost.loadDoc<DatabaseDirectory>(this._ctx, rootUrl, {\n fetchFromNetwork: true,\n // `loadDoc`'s own deadline, so a timed-out attempt aborts the readiness wait and\n // disposes its lease. An outer timeout would only reject, leaving the subscription live\n // and able to hand back an undisposed lease later.\n timeout: ROOT_DOC_LOAD_ATTEMPT_TIMEOUT,\n }),\n );\n } catch (err) {\n if (this._ctx.disposed || err instanceof ContextDisposedError) {\n return null;\n }\n\n log.info('space root doc did not arrive; resetting stalled sync and retrying', {\n space: this.key,\n rootUrl,\n attempt,\n delay,\n });\n await sleepWithContext(this._ctx, delay);\n delay = Math.min(delay * 2, ROOT_DOC_LOAD_RETRY_MAX_DELAY);\n }\n }\n\n return null;\n }\n\n private _onNewAutomergeRoot(rootUrl: string): void {\n log('loading automerge root doc for space', { space: this.key, rootUrl });\n\n let lease: DocumentLease<DatabaseDirectory> | null = null;\n\n // TODO(dmaretskyi): Make this single-threaded (but doc loading should still be parallel to not block epoch processing).\n queueMicrotask(async () => {\n try {\n lease = await this.#loadRootDoc(rootUrl as AutomergeUrl);\n if (this._ctx.disposed) {\n return;\n }\n if (!lease) {\n log.warn('automerge root doc not available yet', { space: this.key, rootUrl });\n return;\n }\n\n // Ensure only one root is processed at a time.\n using _guard = await this._epochProcessingMutex.acquire();\n\n // Attaching space identifiers to legacy documents.\n const doc = lease.doc();\n if (!doc.access?.spaceId || !doc.access?.spaceKey) {\n lease.change((doc: DatabaseDirectory) => {\n doc.access ??= {};\n doc.access.spaceId ??= this.id;\n // spaceKey is deprecated but still written so older clients can resolve the owning space.\n doc.access.spaceKey ??= this.key.toHex();\n });\n }\n\n // TODO(dmaretskyi): Close roots.\n // TODO(dmaretskyi): How do we handle changing to the next EPOCH?\n // `updateSpaceRoot` takes its own lease on the root, so this one is released either way.\n const rootUrlToAssign = lease.url;\n lease[Symbol.dispose]();\n lease = null;\n const root = await this._echoHost.updateSpaceRoot(this._ctx, this.id, rootUrlToAssign);\n\n // NOTE: Make sure this assignment happens synchronously together with the state change.\n this._databaseRoot = root;\n if (root.getVersion() !== SpaceDocVersion.CURRENT) {\n this._state = SpaceState.SPACE_REQUIRES_MIGRATION;\n this.stateUpdate.emit();\n } else if (this._state !== SpaceState.SPACE_READY) {\n await this._enterReadyState();\n } else {\n this.stateUpdate.emit();\n }\n } catch (err) {\n if (err instanceof ContextDisposedError) {\n return;\n }\n log.warn('error loading automerge root doc', { space: this.key, rootUrl, err });\n } finally {\n // Released on every path that did not hand it to `updateSpaceRoot`.\n lease?.[Symbol.dispose]();\n }\n });\n }\n\n // TODO(dmaretskyi): Use profile from signing context.\n async updateOwnProfile(profile: ProfileDocument): Promise<void> {\n const credential = await this._signingContext.credentialSigner.createCredential({\n subject: this._signingContext.identityKey,\n assertion: create(MemberProfileSchema, { profile }),\n });\n await this.inner.controlPipeline.writer.write(credentialPayload(credential));\n }\n\n async createEpoch(options?: CreateEpochOptions): Promise<CreateEpochResult | null> {\n const ctx = this._ctx.derive();\n\n // Preserving existing behavior.\n if (!options?.migration) {\n return null;\n }\n\n const { newRoot } = await runEpochMigration(ctx, {\n echoHost: this._echoHost,\n spaceId: this.id,\n spaceKey: this.key,\n migration: options.migration,\n currentRoot: this._automergeSpaceState.rootUrl ?? null,\n newAutomergeRoot: options.newAutomergeRoot,\n });\n\n const lastEpoch = this._automergeSpaceState.lastEpoch;\n const epoch: Epoch = create(EpochSchema, {\n previousId: lastEpoch?.credential.id,\n number: (lastEpoch?.assertion.number ?? -1) + 1,\n timeframe: lastEpoch?.assertion.timeframe ?? fromTimeframe(new Timeframe()),\n automergeRoot: newRoot ?? this._automergeSpaceState.rootUrl,\n });\n\n const credential = await this._signingContext.credentialSigner.createCredential({\n subject: this.key,\n assertion: epoch,\n });\n\n const receipt = await this.inner.controlPipeline.writer.write(credentialPayload(credential));\n\n const timeframe = new Timeframe([[receipt.feedKey, receipt.seq]]);\n await this.inner.controlPipeline.state.waitUntilTimeframe(timeframe);\n await this._echoHost.updateIndexes({ reason: 'epoch' });\n\n return { credential, timeframe };\n }\n\n @synchronized\n async activate(ctx: Context): Promise<void> {\n if (![SpaceState.SPACE_CLOSED, SpaceState.SPACE_INACTIVE].includes(this._state)) {\n return;\n }\n\n await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_ACTIVE);\n await this._open(ctx);\n this.initializeDataPipelineAsync(ctx);\n }\n\n @synchronized\n async deactivate(ctx: Context): Promise<void> {\n if (this._state === SpaceState.SPACE_INACTIVE) {\n return;\n }\n await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_INACTIVE);\n if (this._state !== SpaceState.SPACE_CLOSED) {\n await this._close(ctx);\n }\n this._state = SpaceState.SPACE_INACTIVE;\n log('new state', { state: SpaceState[this._state] });\n this.stateUpdate.emit();\n }\n\n /**\n * Tombstones (soft-deletes) the space by moving it to a terminal state.\n * This is intentionally separate from teardown: the caller is responsible for {@link close}-ing the\n * space (teardown uses the resource lifecycle, distinct from this state transition).\n * Terminal: {@link activate} will not re-open a deleted space. Data is not removed until garbage\n * collection (future work).\n */\n @synchronized\n async delete(): Promise<void> {\n if (this._state === SpaceState.SPACE_DELETED) {\n return;\n }\n await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_DELETED);\n this._state = SpaceState.SPACE_DELETED;\n log('new state', { state: SpaceState[this._state] });\n this.stateUpdate.emit();\n }\n\n getEdgeReplicationSetting() {\n return this._metadataStore.getSpaceEdgeReplicationSetting(this.key);\n }\n\n private _onFeedAdded = async (feed: HypercoreWrapper<any>) => {\n await this._edgeFeedReplicator!.addHypercore(feed);\n };\n}\n\ntype CreateEpochResult = {\n credential: Credential;\n timeframe: Timeframe;\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { createCredential, credentialPayload } from '@dxos/credentials';\nimport { failUndefined } from '@dxos/debug';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { fromPublicKey, fromTimeframe } from '@dxos/protocols/buf';\nimport {\n AdmittedFeed_Designation,\n AdmittedFeedSchema,\n EpochSchema,\n MembershipPolicy,\n SpaceGenesisSchema,\n SpaceMember_Role,\n SpaceMemberSchema,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { Timeframe } from '@dxos/timeframe';\n\nimport { type Space } from '../space/index.ts';\nimport { type SigningContext } from './data-space-manager.ts';\n\nexport const spaceGenesis = async (\n keyring: KeyringApi,\n signingContext: SigningContext,\n space: Space,\n automergeRoot?: string,\n tags?: string[],\n membershipPolicy?: MembershipPolicy,\n spaceRootUrl?: string,\n) => {\n // TODO(dmaretskyi): Find a way to reconcile with credential generator.\n const credentials = [\n await createCredential({\n signer: keyring,\n issuer: space.key,\n subject: space.key,\n assertion: create(SpaceGenesisSchema, {\n spaceKey: fromPublicKey(space.key),\n tags: tags ?? [],\n membershipPolicy: membershipPolicy ?? MembershipPolicy.INVITE,\n }),\n }),\n\n await createCredential({\n signer: keyring,\n issuer: space.key,\n subject: signingContext.identityKey,\n assertion: create(SpaceMemberSchema, {\n spaceKey: fromPublicKey(space.key),\n role: SpaceMember_Role.OWNER,\n profile: signingContext.getProfile(),\n genesisFeedKey: fromPublicKey(space.controlFeedKey ?? failUndefined()),\n spaceRootUrl,\n tags: tags ?? [],\n }),\n }),\n\n await signingContext.credentialSigner.createCredential({\n subject: space.controlFeedKey ?? failUndefined(),\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(space.key),\n identityKey: fromPublicKey(signingContext.identityKey),\n deviceKey: fromPublicKey(signingContext.deviceKey),\n designation: AdmittedFeed_Designation.CONTROL,\n }),\n }),\n\n await signingContext.credentialSigner.createCredential({\n subject: space.dataFeedKey ?? failUndefined(),\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(space.key),\n identityKey: fromPublicKey(signingContext.identityKey),\n deviceKey: fromPublicKey(signingContext.deviceKey),\n designation: AdmittedFeed_Designation.DATA,\n }),\n }),\n\n await signingContext.credentialSigner.createCredential({\n subject: space.key ?? failUndefined(),\n assertion: create(EpochSchema, {\n number: 0,\n timeframe: fromTimeframe(new Timeframe()),\n automergeRoot,\n }),\n }),\n ];\n\n for (const credential of credentials) {\n await space.controlPipeline.writer.write(credentialPayload(credential));\n }\n\n return credentials;\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { type Doc } from '@automerge/automerge';\nimport {\n type AutomergeUrl,\n type DocumentId,\n interpretAsDocumentId,\n isValidAutomergeUrl,\n} from '@automerge/automerge-repo';\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { Event, scheduleTask, synchronized, trackLeaks } from '@dxos/async';\nimport { SpaceProperties } from '@dxos/client-protocol';\nimport { Context, LifecycleState, Resource, cancelWithContext } from '@dxos/context';\nimport {\n type CredentialSigner,\n type DelegateInvitationCredential,\n type MemberInfo,\n createAdmissionCredentials,\n credentialOfPayload,\n credentialPayload,\n getCredentialAssertion,\n} from '@dxos/credentials';\nimport { Type } from '@dxos/echo';\nimport {\n DatabaseRoot,\n type EchoHost,\n EchoHostService,\n type EdgeAutomergeReplicator,\n EdgeAutomergeReplicatorService,\n type MeshEchoReplicator,\n MeshEchoReplicatorService,\n type SpaceRootRefs,\n findInlineObjectOfType,\n} from '@dxos/echo-host';\nimport { type DatabaseDirectory, createIdFromSpaceKey } from '@dxos/echo-protocol';\nimport {\n type EdgeConnection,\n EdgeConnectionService,\n type EdgeHttpClient,\n EdgeHttpClientService,\n} from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { type HypercoreStore, HypercoreStoreService, writeMessages } from '@dxos/feed-store';\nimport { assertArgument, assertState, failedInvariant, invariant } from '@dxos/invariant';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { PublicKey, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { AlreadyJoinedError } from '@dxos/protocols';\nimport {\n buf,\n fromDate,\n fromPublicKey,\n fromTimeframe,\n requirePublicKey,\n toDate,\n toPublicKey,\n toTimeframe,\n} from '@dxos/protocols/buf';\nimport {\n AdmissionKeypairSchema,\n Invitation_Kind,\n Invitation_Type,\n SpaceState,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type FeedMessage, type FeedMessage_Payload } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { EdgeReplicationSetting } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { type SpaceMetadata, SpaceMetadataSchema } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport {\n type Credential,\n type ProfileDocument,\n SpaceDeletedSchema,\n SpaceMember_Role as SpaceMemberRole,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type DelegateSpaceInvitation } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type PeerState } from '@dxos/protocols/buf/dxos/mesh/presence_pb';\nimport { type Teleport } from '@dxos/teleport';\nimport { Gossip, Presence } from '@dxos/teleport-extension-gossip';\nimport { trace } from '@dxos/tracing';\nimport { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';\n\nimport * as Auth from '../../Auth.ts';\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as InvitationsContract from '../../contracts/invitations.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport { openCredentialsDocument } from '../../CredentialsDocument.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type IMetadataStore, IMetadataStoreService } from '../metadata/index.ts';\nimport {\n AuthStatus,\n CredentialServerExtension,\n type Space,\n type SpaceManager,\n SpaceManagerService,\n type SpaceProtocol,\n type SpaceProtocolSession,\n} from '../space/index.ts';\nimport { DataSpace } from './data-space.ts';\nimport { spaceGenesis } from './genesis.ts';\n\nconst PRESENCE_ANNOUNCE_INTERVAL = 10_000;\nconst PRESENCE_OFFLINE_TIMEOUT = 20_000;\n\nexport interface SigningContext {\n identityKey: PublicKey;\n deviceKey: PublicKey;\n credentialSigner: CredentialSigner; // TODO(burdon): Already has keyring.\n recordCredential: (credential: Credential) => Promise<void>;\n // TODO(dmaretskyi): Should be a getter.\n getProfile: () => ProfileDocument | undefined;\n}\n\n/**\n * Resolves signing context when identity becomes available.\n */\nexport type SigningContextProvider = () => SigningContext;\n\n/**\n * Builds a {@link SigningContextProvider} from an identity resolver.\n */\nexport const createSigningContextProvider =\n (getIdentity: () => Identity): SigningContextProvider =>\n () => {\n const identity = getIdentity();\n return {\n credentialSigner: identity.getIdentityCredentialSigner(),\n identityKey: identity.identityKey,\n deviceKey: identity.deviceKey,\n getProfile: () => identity.profileDocument,\n recordCredential: async (credential) => {\n await identity.controlPipeline.writer.write(credentialPayload(credential));\n },\n };\n };\n\n/**\n * Effect Layer providing {@link SigningContextProvider} from {@link IdentityProviderService}.\n */\nexport const SigningContextProviderLayer = Layer.effect(\n SpacesContract.SigningContextProviderService,\n Effect.gen(function* () {\n const identityProvider = yield* IdentityContract.ProviderService;\n return createSigningContextProvider(identityProvider);\n }),\n);\n\nexport type DataSpaceManagerProps = {\n spaceManager: SpaceManager;\n metadataStore: IMetadataStore;\n keyring: KeyringApi;\n signingContextProvider: SigningContextProvider;\n hypercoreStore: HypercoreStore<FeedMessage>;\n echoHost: EchoHost;\n invitationsManager: InvitationsContract.Manager;\n edgeConnection?: EdgeConnection;\n edgeHttpClient?: EdgeHttpClient;\n meshReplicator?: MeshEchoReplicator;\n echoEdgeReplicator?: EdgeAutomergeReplicator;\n runtimeProps?: DataSpaceManagerRuntimeProps;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n};\n\nexport type DataSpaceManagerRuntimeProps = {\n spaceMemberPresenceAnnounceInterval?: number;\n spaceMemberPresenceOfflineTimeout?: number;\n activeEdgeNotarizationPollingInterval?: number;\n disableP2pReplication?: boolean;\n /**\n * If true, spaces that were previously SPACE_ACTIVE will be automatically activated on startup.\n * This is used in dedicated worker mode to restore space state after leader changeover.\n */\n autoActivateSpaces?: boolean;\n\n /**\n * Anchor spaces on a space root document and mirror credentials into a credentials document.\n * Off by default — a space then keeps its key-derived id and its control feed, as before.\n */\n automergeCredentials?: boolean;\n};\n\n/** Backoff bounds for retrying an anchor that is waiting on replication or an unassigned directory. */\nconst ANCHOR_RETRY_INITIAL = 500;\nconst ANCHOR_RETRY_MAX = 30_000;\n\n/** Backoff bounds for reporting a space root to edge; replication normally lands well inside this. */\nconst SPACE_ROOT_REPORT_RETRY_INITIAL = 500;\nconst SPACE_ROOT_REPORT_RETRY_MAX = 30_000;\n\n@trackLeaks('open', 'close')\nexport class DataSpaceManager extends Resource {\n public readonly updated = new Event();\n\n private readonly _spaces = new ComplexMap<PublicKey, DataSpace>(PublicKey.hash);\n\n /** Spaces created legacy in this session; see {@link _anchorSpaceOnRootDocument}. */\n private readonly _legacyCreatedSpaces = new Set<SpaceId>();\n /** Roots named by an inviter, to adopt once they replicate; see {@link _anchorSpaceOnRootDocument}. */\n private readonly _pendingSpaceRootUrls = new Map<SpaceId, AutomergeUrl>();\n\n /**\n * Spaces whose close has begun. `DataSpace.isOpen` reads the inner space, which closes last, so it\n * still reads open through `preClose` — the window the anchor's background work resumes in.\n */\n private readonly _closingSpaces = new Set<SpaceId>();\n\n private readonly _spaceManager: SpaceManager;\n private readonly _metadataStore: IMetadataStore;\n private readonly _keyring: KeyringApi;\n private readonly _signingContextProvider: SigningContextProvider;\n private readonly _hypercoreStore: HypercoreStore<FeedMessage>;\n private readonly _echoHost: EchoHost;\n private readonly _invitationsManager: InvitationsContract.Manager;\n private readonly _edgeConnection?: EdgeConnection = undefined;\n private readonly _edgeHttpClient?: EdgeHttpClient = undefined;\n private readonly _edgeFeatures?: Runtime_Client_EdgeFeatures = undefined;\n private readonly _meshReplicator?: MeshEchoReplicator = undefined;\n private readonly _echoEdgeReplicator?: EdgeAutomergeReplicator = undefined;\n private readonly _runtimeProps?: DataSpaceManagerRuntimeProps = undefined;\n\n /** Opt-in to the automerge-backed credential scheme; see {@link DataSpaceManagerRuntimeProps}. */\n private get _automergeCredentials(): boolean {\n return this._runtimeProps?.automergeCredentials ?? false;\n }\n\n constructor(params: DataSpaceManagerProps) {\n super();\n\n this._spaceManager = params.spaceManager;\n this._metadataStore = params.metadataStore;\n this._keyring = params.keyring;\n this._signingContextProvider = params.signingContextProvider;\n this._hypercoreStore = params.hypercoreStore;\n this._echoHost = params.echoHost;\n this._meshReplicator = params.meshReplicator;\n this._invitationsManager = params.invitationsManager;\n this._edgeConnection = params.edgeConnection;\n this._edgeFeatures = params.edgeFeatures;\n this._echoEdgeReplicator = params.echoEdgeReplicator;\n this._edgeHttpClient = params.edgeHttpClient;\n this._runtimeProps = params.runtimeProps;\n\n trace.diagnostic({\n id: 'spaces',\n name: 'Spaces',\n fetch: async () => {\n return Promise.all(\n Array.from(this._spaces.values()).map(async (space) => {\n const rootUrl = space.automergeSpaceState.rootUrl;\n using rootLease = rootUrl\n ? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(this._ctx, rootUrl as AutomergeUrl)\n : undefined;\n const rootDoc = rootLease?.doc();\n\n const properties = rootDoc && findInlineObjectOfType(rootDoc, Type.getTypename(SpaceProperties));\n\n return {\n key: space.key.toHex(),\n state: SpaceState[space.state],\n name: properties?.[1].data.name ?? null,\n inlineObjects: rootDoc ? Object.keys(rootDoc.objects ?? {}).length : null,\n linkedObjects: rootDoc ? Object.keys(rootDoc.links ?? {}).length : null,\n credentials: space.inner.spaceState.credentials.length,\n members: space.inner.spaceState.members.size,\n rootUrl,\n };\n }),\n );\n },\n });\n }\n\n private get signingContext(): SigningContext {\n return this._signingContextProvider();\n }\n\n // TODO(burdon): Remove.\n get spaces() {\n return this._spaces;\n }\n\n getSpaceById(spaceId: SpaceId): DataSpace | undefined {\n return [...this._spaces.values()].find((space) => space.id === spaceId);\n }\n\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n protected override async _open(ctx: Context): Promise<void> {\n log('open');\n log('metadata loaded', { spaces: this._metadataStore.spaces.length });\n\n const spacesToActivate: DataSpace[] = [];\n await forEachAsync(this._metadataStore.spaces, async (spaceMetadata) => {\n try {\n // Tombstoned spaces are never constructed, opened, or replicated.\n if (\n spaceMetadata.state === SpaceState.SPACE_DELETED ||\n this.isSpaceDeleted(requirePublicKey(spaceMetadata.key))\n ) {\n log('skipping deleted space', { spaceKey: spaceMetadata.key });\n return;\n }\n log('load space', { spaceMetadata });\n const space = await this._constructSpace(ctx, spaceMetadata);\n // Track spaces that were previously active for auto-activation (used in dedicated worker mode).\n if (this._runtimeProps?.autoActivateSpaces && spaceMetadata.state === SpaceState.SPACE_ACTIVE) {\n spacesToActivate.push(space);\n }\n } catch (err) {\n log.error('Error loading space', { spaceMetadata, err });\n }\n });\n\n // Auto-activate spaces that were previously active (used in dedicated worker mode after leader changeover).\n for (const space of spacesToActivate) {\n log('auto-activating space', { spaceKey: space.key });\n space.activate(ctx).catch((err) => {\n log.error('Error auto-activating space', { spaceKey: space.key, err });\n });\n }\n\n this.updated.emit();\n }\n\n @synchronized\n protected override async _close(ctx: Context): Promise<void> {\n log('close');\n for (const space of this._spaces.values()) {\n await space.close(ctx);\n }\n this._spaces.clear();\n }\n\n /**\n * Creates a new space writing the genesis credentials to the control feed.\n */\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async createSpace(ctx: Context, options: SpacesContract.CreateSpaceOptions = {}): Promise<DataSpace> {\n assertArgument(\n !!options.rootUrl === !!options.documents,\n 'options',\n 'root url must be required when providing documents',\n );\n\n assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');\n\n const tags = options.tags ? Array.from(options.tags) : [];\n const spaceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const dataFeedKey = await this._keyring.createKey();\n\n // An imported space brings its own root document, so it keeps the key-derived id.\n const anchorOnRootDocument =\n (options.useSpaceRootDocument ?? this._automergeCredentials) && !options.rootUrl && !options.documents;\n const createdSpace = anchorOnRootDocument\n ? await this._echoHost.createSpaceWithRootDocument(ctx, spaceKey)\n : undefined;\n const spaceId = createdSpace?.spaceId ?? (await createIdFromSpaceKey(spaceKey));\n if (!createdSpace) {\n this._legacyCreatedSpaces.add(spaceId);\n }\n\n const metadata: SpaceMetadata = create(SpaceMetadataSchema, {\n key: fromPublicKey(spaceKey),\n spaceId,\n genesisFeedKey: fromPublicKey(controlFeedKey),\n controlFeedKey: fromPublicKey(controlFeedKey),\n dataFeedKey: fromPublicKey(dataFeedKey),\n state: SpaceState.SPACE_ACTIVE,\n tags,\n });\n\n log('creating space...', { spaceId, spaceKey });\n\n // New document IDs for the space.\n const documentIdMapping: Record<DocumentId, DocumentId> = {};\n if (options.documents) {\n invariant(\n Object.keys(options.documents).every((documentId) => /^[a-zA-Z0-9]+$/.test(documentId)),\n 'Invalid document IDs',\n );\n\n await Promise.all(\n Object.entries(options.documents).map(async ([documentId, data]) => {\n log('creating document...', { documentId });\n // TODO(dmaretskyi): Broken types -- the bytes get interpreted as CRDT data.\n using newDoc = await this._echoHost.createDoc(data as any as DatabaseDirectory, {\n preserveHistory: true,\n });\n\n // Archived documents carry the exporting space's identity; the indexer attributes documents by `access.spaceId`, so both fields must name the new space.\n const access = newDoc.doc().access;\n if (access !== undefined && (access.spaceKey !== spaceKey.toHex() || access.spaceId !== spaceId)) {\n newDoc.change((doc) => {\n if (doc.access) {\n doc.access.spaceKey = spaceKey.toHex();\n doc.access.spaceId = spaceId;\n }\n });\n }\n\n documentIdMapping[documentId as DocumentId] = newDoc.documentId;\n }),\n );\n }\n\n log('opening space...', { spaceKey });\n\n let root: DatabaseRoot;\n if (createdSpace) {\n root = createdSpace.directory;\n } else if (options.rootUrl) {\n const newRootDocId = documentIdMapping[interpretAsDocumentId(options.rootUrl)] ?? failedInvariant();\n using rootDocLease = await this._echoHost.loadDoc<DatabaseDirectory>(ctx, newRootDocId);\n invariant(rootDocLease, 'Root document must be available after import.');\n DatabaseRoot.mapLinks(rootDocLease, documentIdMapping);\n\n root = await this._echoHost.updateSpaceRoot(ctx, spaceId, `automerge:${newRootDocId}` as AutomergeUrl);\n } else {\n root = await this._echoHost.createSpaceRoot(ctx, spaceKey);\n }\n await this._echoHost.flush(ctx);\n\n log('constructing space...', { spaceKey });\n\n const space = await this._constructSpace(ctx, metadata);\n await space.open(ctx);\n\n log('adding space...', { spaceKey });\n\n const credentials = await spaceGenesis(\n this._keyring,\n this.signingContext,\n space.inner,\n root.url,\n tags,\n options.membershipPolicy,\n createdSpace?.spaceRootUrl,\n );\n await this._metadataStore.addSpace(metadata);\n\n const memberCredential = credentials[1];\n invariant(\n getCredentialAssertion(memberCredential).$typeName === 'dxos.halo.credentials.SpaceMember',\n 'Invalid credential',\n );\n await this.signingContext.recordCredential(memberCredential);\n\n await space.initializeDataPipeline(ctx);\n\n log('space ready.', { spaceId, spaceKey });\n\n this.updated.emit();\n return space;\n }\n\n /**\n * Accepts an existing space by joining its swarm and initializing the data pipeline.\n * @param ctx - Caller context for cancellation and tracing.\n * @param opts - Space keys and optional timeframes for catch-up.\n */\n // TODO(burdon): Rename join space.\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async acceptSpace(ctx: Context, opts: SpacesContract.AcceptSpaceOptions): Promise<DataSpace> {\n log('accept space', { opts });\n invariant(this._lifecycleState === LifecycleState.OPEN, 'Not open.');\n invariant(!this._spaces.has(opts.spaceKey), 'Space already exists.');\n invariant(!this.isSpaceDeleted(opts.spaceKey), 'Cannot accept a deleted space.');\n\n const tags = opts.tags ? Array.from(opts.tags) : [];\n const metadata: SpaceMetadata = create(SpaceMetadataSchema, {\n key: fromPublicKey(opts.spaceKey),\n spaceId: await createIdFromSpaceKey(opts.spaceKey),\n genesisFeedKey: fromPublicKey(opts.genesisFeedKey),\n controlTimeframe: opts.controlTimeframe && fromTimeframe(opts.controlTimeframe),\n dataTimeframe: opts.dataTimeframe && fromTimeframe(opts.dataTimeframe),\n tags,\n });\n\n const space = await this._constructSpace(ctx, metadata);\n await space.open(ctx);\n // Anchoring must adopt the root the inviter named rather than mint one, so remember it: a second\n // root over the same space would split its credential set, leaving members disagreeing about\n // which document carries the chain.\n if (opts.spaceRootUrl !== undefined && isValidAutomergeUrl(opts.spaceRootUrl)) {\n this._pendingSpaceRootUrls.set(space.id, opts.spaceRootUrl);\n }\n await this._metadataStore.addSpace(metadata);\n // Use DSM lifecycle ctx: the invitation accept flow disposes `ctx` as soon as\n // `acceptSpace` returns (guardedState.complete -> ctx.dispose). Detached data-pipeline\n // initialization must outlive the invitation flow, and its span must be parented to a\n // long-lived context.\n space.initializeDataPipelineAsync(this._ctx);\n\n this.updated.emit();\n return space;\n }\n\n /**\n * Mints a space root over a legacy space, transparently and idempotently, keeping its space id. Never\n * blocks opening the space: a space without an anchor still works, it just has not migrated yet.\n */\n /**\n * @returns Whether the space needs no further anchoring attempt — either because it is now anchored\n * or because it never will be. False means the attempt no-oped and the caller should retry, which a\n * space whose directory is not assigned yet depends on.\n */\n private async _anchorSpaceOnRootDocument(ctx: Context, space: DataSpace, force = false): Promise<boolean> {\n // Migrating a space is the opt-in behaviour, so without the flag a space keeps its control feed\n // and never grows a root. An explicit `migrateSpaceToRootDocument` call still forces it.\n if (!force && !this._automergeCredentials) {\n return true;\n }\n\n // A space created legacy stays unanchored for this session, or there would be no way to produce\n // the pre-migration state the migration path starts from. It anchors on the next load, which is\n // exactly the migration this project is for.\n if (!force && this._legacyCreatedSpaces.has(space.id)) {\n return true;\n }\n\n try {\n if (!this._echoHost.getSpaceRootRefs(space.id)) {\n // A root the inviter named is the space's only root; adopting it has to wait for it to\n // replicate rather than fall through to minting a second one over the same space.\n const named = this._pendingSpaceRootUrls.get(space.id);\n if (named !== undefined) {\n try {\n const refs = await this._echoHost.adoptSpaceRoot(ctx, space.id, named);\n this._pendingSpaceRootUrls.delete(space.id);\n log('adopted the space root named by the inviter', { spaceId: space.id, refs });\n } catch (err) {\n log('space root named by the inviter has not replicated yet', { spaceId: space.id, named, err });\n return false;\n }\n } else {\n const refs = await this._echoHost.migrateSpaceToRootDocument(ctx, space.id);\n if (!refs) {\n return false;\n }\n\n log('migrated space to root document', { spaceId: space.id, refs });\n }\n }\n\n // Re-checked after the adopt/migrate await: the anchor now runs on the manager's context, so a\n // space that started closing during it would otherwise still gain credentials and be reported.\n if (!this._isSpaceLive(space)) {\n return false;\n }\n\n // Unsettled when the mirror bailed on a closing space: latching would leave the credentials\n // half-written with nothing to retry it, since an anchored space never attempts again.\n if (!(await this._mirrorCredentialsToDocument(space))) {\n return false;\n }\n this._reportSpaceRootToEdge(space);\n return true;\n } catch (err) {\n log.warn('failed to anchor space on a root document', { spaceId: space.id, err });\n return false;\n }\n }\n\n /** Whether the anchor's background work may still act on this space. */\n private _isSpaceLive(space: DataSpace): boolean {\n return space.isOpen && !this._closingSpaces.has(space.id);\n }\n\n /**\n * Names the space root to edge, which cannot derive it from a space id that is the hash of the\n * space key, leaving the space on its control feed.\n */\n private _reportSpaceRootToEdge(space: DataSpace): void {\n const refs = this._echoHost.getSpaceRootRefs(space.id);\n if (!this._edgeHttpClient || !refs) {\n return;\n }\n\n // Retried in the background because edge rejects a root whose documents have not replicated to\n // it yet, and bound to the manager's own context because the invitation accept flow disposes\n // its ctx the moment `acceptSpace` returns, which would cancel every pending retry.\n let delay = SPACE_ROOT_REPORT_RETRY_INITIAL;\n const report = async (): Promise<void> => {\n // A retry outlives the attempt that scheduled it, so it has to re-check: a space closed or\n // removed in between must not be named to edge.\n if (!this._isSpaceLive(space)) {\n return;\n }\n try {\n await this._edgeHttpClient!.recordSpaceRoot(this._ctx, space.id, {\n rootDocumentUrl: refs.spaceRootDocUrl,\n });\n log('reported the space root to edge', { spaceId: space.id });\n } catch (err) {\n if (delay > SPACE_ROOT_REPORT_RETRY_MAX) {\n log.warn('gave up reporting the space root to edge', { spaceId: space.id, err });\n return;\n }\n\n log('space root not accepted by edge yet, retrying', { spaceId: space.id, delay, err });\n scheduleTask(this._ctx, report, delay);\n delay *= 2;\n }\n };\n\n scheduleTask(this._ctx, report);\n }\n\n /**\n * Mirrors the space's credentials into its credentials document. Subscribing to processed\n * credentials backfills the existing chain and dual-writes new ones through one path, since the\n * control pipeline replays the whole feed on open.\n */\n private async _mirrorCredentialsToDocument(space: DataSpace): Promise<boolean> {\n {\n // The manager's own context, not the caller's: the invitation flow disposes its context as\n // soon as `acceptSpace` returns, and a store bound to it would be released before its first\n // write — the same reason `initializeDataPipelineAsync` is parented here.\n const ctx = this._ctx;\n const store = await openCredentialsDocument(ctx, this._echoHost, space.id);\n if (!this._isSpaceLive(space)) {\n return false;\n }\n for (const credential of space.inner.spaceState.credentials) {\n store.append(credential);\n }\n\n ctx.onDispose(space.inner.credentialProcessed.on((credential) => store.append(credential)));\n\n // Read side: the document feeds the same state machine the feed does. Processing is idempotent\n // by credential id, so during the migration window both sources can run without conflict — a\n // space that has flipped simply stops gaining feed credentials.\n store.subscribe(ctx, (credential) => space.inner.processDocumentCredential(credential));\n return true;\n }\n }\n\n /**\n * Migrates a legacy space onto a space root document, keeping its id, and starts mirroring its\n * credentials into the document. Idempotent.\n */\n async migrateSpaceToRootDocument(ctx: Context, spaceKey: PublicKey): Promise<SpaceRootRefs> {\n const space = this._spaces.get(spaceKey) ?? failedInvariant();\n await this._anchorSpaceOnRootDocument(ctx, space, true);\n return this._echoHost.getSpaceRootRefs(space.id) ?? failedInvariant();\n }\n\n /**\n * Whether the space has been tombstoned (soft-deleted). Deleted spaces are never opened or replicated.\n */\n isSpaceDeleted(spaceKey: PublicKey): boolean {\n // Mirror the deletion predicate used in `_open`: the tombstone list or a persisted SPACE_DELETED state.\n return (\n this._metadataStore.deletedSpaces.some((key) => key.equals(spaceKey)) ||\n this._metadataStore.spaces.some(\n (spaceMetadata) =>\n requirePublicKey(spaceMetadata.key).equals(spaceKey) && spaceMetadata.state === SpaceState.SPACE_DELETED,\n )\n );\n }\n\n /**\n * Tombstones (soft-deletes) a space initiated locally on this device.\n * Records a SpaceDeleted credential in the HALO so the deletion replicates to the user's other devices,\n * then unloads the space locally. Data is not removed until garbage collection (future work).\n */\n @synchronized\n async markSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void> {\n if (this.isSpaceDeleted(spaceKey)) {\n return;\n }\n\n // Replicates to the user's other devices via the HALO control feed.\n const credential = await this.signingContext.credentialSigner.createCredential({\n subject: spaceKey,\n assertion: create(SpaceDeletedSchema, {\n spaceKey: fromPublicKey(spaceKey),\n deletedAt: fromDate(new Date()),\n }),\n });\n await this.signingContext.recordCredential(credential);\n\n await this._tombstoneSpace(ctx, spaceKey);\n }\n\n /**\n * Closes and tombstones every loaded space without writing SpaceDeleted credentials: used when the\n * identity itself is being deleted, so there is no HALO left to replicate the deletion to.\n */\n @synchronized\n async deleteAllSpaces(ctx: Context): Promise<void> {\n const spaces = [...this._spaces.values()].map((space) => ({ key: space.key, id: space.id }));\n log('deleting all spaces', { count: spaces.length });\n for (const { key, id } of spaces) {\n await this._tombstoneSpace(ctx, key);\n // Drops the host's in-memory state for the space as well as the tombstone, since the stack\n // stays open afterwards and would otherwise keep serving a space that no longer exists.\n await this._echoHost.removeSpace(id);\n }\n }\n\n /**\n * Tombstones a space in response to a SpaceDeleted credential replicated from another device.\n * Does not write a credential (one already exists in the HALO).\n */\n @synchronized\n async handleRemoteSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void> {\n if (this.isSpaceDeleted(spaceKey)) {\n return;\n }\n\n await this._tombstoneSpace(ctx, spaceKey);\n }\n\n /**\n * Persists the tombstone and unloads the space if it is currently loaded.\n * Must be called while holding the DataSpaceManager lock (see callers).\n */\n private async _tombstoneSpace(ctx: Context, spaceKey: PublicKey): Promise<void> {\n await this._metadataStore.addDeletedSpace(spaceKey);\n\n const space = this._spaces.get(spaceKey);\n if (space) {\n // Separate teardown (resource lifecycle) from the terminal state transition.\n if (space.isOpen) {\n // The tombstone above and the SpaceDeleted credential both already exist, so the deletion is\n // committed and the local state must reach it whatever the teardown does. Leaving the swarm\n // waits on the signaling server, which times out when EDGE is unreachable; letting that\n // reject would skip the two lines below and strand a closed space in the live list that\n // `isSpaceDeleted` then refuses to remove on a retry.\n await space.close(ctx).catch((err) => log.warn('space teardown failed; deleting anyway', { spaceKey, err }));\n }\n await space.delete();\n this._spaces.delete(spaceKey);\n }\n\n this.updated.emit();\n }\n\n async admitMember(options: SpacesContract.AdmitMemberOptions): Promise<Credential> {\n const space = this._spaceManager.spaces.get(options.spaceKey);\n invariant(space);\n\n if (space.spaceState.getMemberRole(options.identityKey) !== SpaceMemberRole.REMOVED) {\n throw new AlreadyJoinedError();\n }\n\n // Resolved here rather than at each call site: a caller that forgets it emits a credential the\n // admitted member cannot find the root from.\n const spaceRootUrl = options.spaceRootUrl ?? this._echoHost.getSpaceRootRefs(space.id)?.spaceRootDocUrl;\n\n // TODO(burdon): Check if already admitted.\n const credentials: FeedMessage_Payload[] = await createAdmissionCredentials({\n signer: this.signingContext.credentialSigner,\n identityKey: options.identityKey,\n spaceKey: space.key,\n genesisFeedKey: space.genesisFeedKey,\n role: options.role,\n membershipChainHeads: space.spaceState.membershipChainHeads,\n profile: options.profile,\n invitationCredentialId: options.delegationCredentialId,\n tags: space.spaceState.tags,\n spaceRootUrl,\n });\n\n // TODO(dmaretskyi): Refactor.\n const spaceMemberCredential = credentialOfPayload(credentials[0]);\n invariant(\n getCredentialAssertion(spaceMemberCredential).$typeName === 'dxos.halo.credentials.SpaceMember',\n 'Invalid credential',\n );\n await writeMessages(space.controlPipeline.writer, credentials);\n\n return spaceMemberCredential;\n }\n\n /**\n * Wait until the space data pipeline is fully initialized.\n * Used by invitation handler.\n * TODO(dmaretskyi): Consider removing.\n */\n async waitUntilSpaceReady(spaceKey: PublicKey): Promise<void> {\n await cancelWithContext(\n this._ctx,\n this.updated.waitForCondition(() => {\n const space = this._spaces.get(spaceKey);\n return !!space && space.state === SpaceState.SPACE_READY;\n }),\n );\n }\n\n public async requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential> {\n return this._spaceManager.requestSpaceAdmissionCredential(ctx, {\n spaceKey,\n identityKey: this.signingContext.identityKey,\n timeout: 15_000,\n swarmIdentity: {\n identityKey: this.signingContext.identityKey,\n peerKey: this.signingContext.deviceKey,\n credentialProvider: Auth.createAuthProvider(this.signingContext.credentialSigner),\n credentialAuthenticator: async () => true,\n },\n });\n }\n\n async setSpaceEdgeReplicationSetting(\n ctx: Context,\n spaceKey: PublicKey,\n setting: EdgeReplicationSetting,\n ): Promise<void> {\n const space = this._spaces.get(spaceKey);\n invariant(space, 'Space not found.');\n\n await this._metadataStore.setSpaceEdgeReplicationSetting(spaceKey, setting);\n\n if (space.isOpen) {\n switch (setting) {\n case EdgeReplicationSetting.DISABLED:\n await this._echoEdgeReplicator?.disconnectFromSpace(space.id);\n break;\n case EdgeReplicationSetting.ENABLED:\n await this._echoEdgeReplicator?.connectToSpace(ctx, space.id);\n break;\n }\n }\n\n space.stateUpdate.emit();\n }\n\n private async _constructSpace(ctx: Context, metadata: SpaceMetadata): Promise<DataSpace> {\n log('construct space', { metadata });\n const gossip = new Gossip({\n localPeerId: this.signingContext.deviceKey,\n });\n const presence = new Presence({\n announceInterval: this._runtimeProps?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,\n offlineTimeout: this._runtimeProps?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,\n identityKey: this.signingContext.identityKey,\n gossip,\n });\n\n const controlFeed =\n metadata.controlFeedKey &&\n (await this._hypercoreStore.openHypercore(requirePublicKey(metadata.controlFeedKey), { writable: true }));\n const dataFeed =\n metadata.dataFeedKey &&\n (await this._hypercoreStore.openHypercore(requirePublicKey(metadata.dataFeedKey), {\n writable: true,\n sparse: true,\n }));\n\n const space: Space = await this._spaceManager.constructSpace({\n metadata,\n swarmIdentity: {\n identityKey: this.signingContext.identityKey,\n peerKey: this.signingContext.deviceKey,\n credentialProvider: Auth.createAuthProvider(this.signingContext.credentialSigner),\n credentialAuthenticator: deferFunction(() => dataSpace.authVerifier.verifier),\n },\n onAuthorizedConnection: (session) =>\n queueMicrotask(async () => {\n try {\n if (!session.isOpen) {\n return;\n }\n session.addExtension('dxos.mesh.teleport.admission-discovery', new CredentialServerExtension(space));\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n gossip.createExtension({ remotePeerId: session.remotePeerId }),\n );\n session.addExtension('dxos.mesh.teleport.notarization', dataSpace.notarizationPlugin.createExtension());\n await this._connectEchoMeshReplicator(space, session);\n } catch (err: any) {\n log.warn('error on authorized connection', { err });\n await session.close(err);\n }\n }),\n onAuthFailure: () => {\n log.warn('auth failure');\n },\n onMemberRolesChanged: async (members: MemberInfo[]) => {\n if (dataSpace?.state === SpaceState.SPACE_READY) {\n this._handleMemberRoleChanges(presence, space.protocol, members);\n }\n },\n memberKey: this.signingContext.identityKey,\n onDelegatedInvitationStatusChange: (invitation, isActive) => {\n return this._handleInvitationStatusChange(dataSpace, invitation, isActive);\n },\n });\n controlFeed && (await space.setControlFeed(controlFeed));\n dataFeed && (await space.setDataFeed(dataFeed));\n\n const dataSpace = new DataSpace({\n inner: space,\n initialState: metadata.state === SpaceState.SPACE_INACTIVE ? SpaceState.SPACE_INACTIVE : SpaceState.SPACE_CLOSED,\n metadataStore: this._metadataStore,\n gossip,\n presence,\n keyring: this._keyring,\n hypercoreStore: this._hypercoreStore,\n echoHost: this._echoHost,\n signingContext: this.signingContext,\n callbacks: {\n beforeReady: async () => {\n log('before space ready', { space: space.key });\n },\n afterReady: async () => {\n log('after space ready', { space: space.key, open: this._lifecycleState === LifecycleState.OPEN });\n if (this._lifecycleState === LifecycleState.OPEN) {\n await this._createDelegatedInvitations(dataSpace, [...space.spaceState.invitations.entries()]);\n this._handleMemberRoleChanges(presence, space.protocol, [...space.spaceState.members.values()]);\n this.updated.emit();\n }\n },\n beforeClose: async () => {\n log('before space close', { space: space.key });\n },\n },\n tags: metadata.tags,\n edgeConnection: this._edgeConnection,\n edgeHttpClient: this._edgeHttpClient,\n edgeFeatures: this._edgeFeatures,\n activeEdgeNotarizationPollingInterval: this._runtimeProps?.activeEdgeNotarizationPollingInterval,\n });\n dataSpace.postOpen.append(async () => {\n const setting = dataSpace.getEdgeReplicationSetting();\n if (!setting || setting === EdgeReplicationSetting.ENABLED) {\n // Use lifecycle ctx: the caller ctx from _constructSpace may be disposed by the time postOpen fires.\n await this._echoEdgeReplicator?.connectToSpace(this._ctx, dataSpace.id);\n } else if (this._echoEdgeReplicator) {\n log('not connecting edge replicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });\n }\n });\n dataSpace.preClose.append(async () => {\n this._closingSpaces.add(dataSpace.id);\n const setting = dataSpace.getEdgeReplicationSetting();\n if (!setting || setting === EdgeReplicationSetting.ENABLED) {\n await this._echoEdgeReplicator?.disconnectFromSpace(dataSpace.id);\n }\n });\n\n presence.newPeer.on((peerState) => {\n if (dataSpace.state === SpaceState.SPACE_READY) {\n this._handleNewPeerConnected(space, peerState);\n }\n });\n\n if (metadata.controlTimeframe) {\n dataSpace.inner.controlPipeline.state.setTargetTimeframe(toTimeframe(metadata.controlTimeframe));\n }\n\n // Cleared on the way back up: a closed space can be activated again, and a stale mark would\n // leave it unanchorable for the session.\n dataSpace.stateUpdate.on(this._ctx, () => {\n if (dataSpace.isOpen) {\n this._closingSpaces.delete(dataSpace.id);\n }\n });\n\n // Anchoring materializes credential state, so it waits for the space to be open: a closed space\n // must stay unmaterialized or lazy loading is defeated. Every path that opens a space — load and\n // activate, create, accept — arrives here.\n // Latch only once the anchor has actually settled: migration no-ops while the space's directory is\n // unassigned, and latching on the attempt would strand the space unanchored for the whole session.\n let anchored = false;\n let anchoring = false;\n let retryDelay = ANCHOR_RETRY_INITIAL;\n const attemptAnchor = () => {\n if (anchored || anchoring || !dataSpace.isOpen) {\n return;\n }\n\n anchoring = true;\n // The manager's context, not the caller's: an accepted space arrives with the invitation's\n // context, which `acceptSpace` disposes on return, and the anchor's own awaits would be\n // cancelled under it.\n void this._anchorSpaceOnRootDocument(this._ctx, dataSpace)\n .then((settled) => {\n anchored = settled;\n if (settled) {\n return;\n }\n\n // What an unsettled attempt waits on — an unassigned directory, or a root named by an\n // inviter that has not replicated yet — arrives without emitting a space state update, so\n // nothing else would ever retry.\n if (retryDelay <= ANCHOR_RETRY_MAX) {\n scheduleTask(this._ctx, attemptAnchor, retryDelay);\n retryDelay *= 2;\n }\n })\n .finally(() => {\n anchoring = false;\n });\n };\n\n // Subscribed for the space's lifetime rather than the caller's: a root named by an inviter can\n // replicate long after the invitation context is gone, and its state update is what retries.\n const unsubscribeFromStateUpdate = dataSpace.stateUpdate.on(this._ctx, attemptAnchor);\n dataSpace.preClose.append(async () => unsubscribeFromStateUpdate());\n\n this._spaces.set(requirePublicKey(metadata.key), dataSpace);\n return dataSpace;\n }\n\n private async _connectEchoMeshReplicator(space: Space, session: Teleport): Promise<void> {\n const replicator = this._meshReplicator;\n if (!replicator) {\n log.warn('p2p automerge replication disabled', { space: space.key });\n return;\n }\n await replicator.authorizeDevice(space.id, session.remotePeerId);\n // session ended during device authorization\n if (session.isOpen) {\n session.addExtension('dxos.mesh.teleport.automerge', replicator.createExtension());\n }\n }\n\n private _handleMemberRoleChanges(presence: Presence, spaceProtocol: SpaceProtocol, memberInfo: MemberInfo[]): void {\n let closedSessions = 0;\n for (const member of memberInfo) {\n if (member.key.equals(presence.localIdentityKey)) {\n continue;\n }\n const peers = presence.getPeersByIdentityKey(member.key);\n const sessions = peers.map((peer) => {\n const peerId = toPublicKey(peer.peerId);\n return peerId && spaceProtocol.sessions.get(peerId);\n });\n const sessionsToClose = sessions.filter((s): s is SpaceProtocolSession => {\n return (s && (member.role === SpaceMemberRole.REMOVED) !== (s.authStatus === AuthStatus.FAILURE)) ?? false;\n });\n sessionsToClose.forEach((session) => {\n void session.close().catch(log.error);\n });\n closedSessions += sessionsToClose.length;\n }\n log('processed member role changes', {\n roleChangeCount: memberInfo.length,\n peersOnline: presence.getPeersOnline().length,\n closedSessions,\n });\n // Handle the case when there was a removed peer online, we can now establish a connection with them\n spaceProtocol.updateTopology();\n }\n\n private _handleNewPeerConnected(space: Space, peerState: PeerState): void {\n // `PeerState` is the wire message the gossip channel carries; the space state machine and\n // the session map are keyed by the domain key type.\n const identityKey = toPublicKey(peerState.identityKey);\n const peerId = toPublicKey(peerState.peerId);\n if (!identityKey) {\n return;\n }\n const role = space.spaceState.getMemberRole(identityKey);\n if (role === SpaceMemberRole.REMOVED) {\n const session = peerId && space.protocol.sessions.get(peerId);\n if (session != null) {\n log('closing a session with a removed peer', { peerId });\n void session.close().catch(log.error);\n }\n }\n }\n\n private async _handleInvitationStatusChange(\n dataSpace: DataSpace | undefined,\n delegatedInvitation: DelegateInvitationCredential,\n isActive: boolean,\n ): Promise<void> {\n if (dataSpace?.state !== SpaceState.SPACE_READY) {\n return;\n }\n if (isActive) {\n await this._createDelegatedInvitations(dataSpace, [\n [delegatedInvitation.credentialId, delegatedInvitation.invitation],\n ]);\n } else {\n await this._invitationsManager.cancelInvitation(delegatedInvitation.invitation);\n }\n }\n\n private async _createDelegatedInvitations(\n space: DataSpace,\n invitations: Array<[PublicKey, DelegateSpaceInvitation]>,\n ): Promise<void> {\n const tasks = invitations.map(([credentialId, invitation]) => {\n const expiresOn = toDate(invitation.expiresOn);\n return this._invitationsManager.createInvitation(this._ctx, {\n type: Invitation_Type.DELEGATED,\n kind: Invitation_Kind.SPACE,\n spaceKey: fromPublicKey(space.key),\n authMethod: invitation.authMethod,\n invitationId: invitation.invitationId,\n swarmKey: invitation.swarmKey,\n guestKeypair: invitation.guestKey\n ? buf.create(AdmissionKeypairSchema, { publicKey: invitation.guestKey })\n : undefined,\n lifetime: expiresOn && remainingLifetimeSeconds(expiresOn),\n multiUse: invitation.multiUse,\n delegationCredentialId: fromPublicKey(credentialId),\n persistent: false,\n });\n });\n await Promise.all(tasks);\n }\n}\n\n/**\n * Seconds left until `expiresOn`, as `Invitation.lifetime` requires: a whole number, because the\n * field is a protobuf `int32` and a fractional value fails to encode — which silently killed the\n * `queryInvitations` stream and hung client initialization. Floors to at least 1 since 0 means\n * \"never expires\", so an already-expired invitation must not become immortal.\n */\nexport const remainingLifetimeSeconds = (expiresOn: Date): number =>\n Math.max(1, Math.floor((expiresOn.getTime() - Date.now()) / 1000));\n\nexport type DataSpaceManagerLayerOptions = Pick<DataSpaceManagerProps, 'runtimeProps' | 'edgeFeatures'>;\n\n/**\n * Effect Layer constructing a dormant {@link DataSpaceManager}.\n */\nexport const DataSpaceManagerLayer = (\n options: DataSpaceManagerLayerOptions = {},\n): Layer.Layer<\n SpacesContract.ManagerService,\n never,\n | Hook.Controller\n | SpaceManagerService\n | IMetadataStoreService\n | KeyringApiService\n | SpacesContract.SigningContextProviderService\n | HypercoreStoreService\n | EchoHostService\n | InvitationsContract.ManagerService\n> =>\n Layer.effect(\n SpacesContract.ManagerService,\n Effect.gen(function* () {\n const spaceManager = yield* SpaceManagerService;\n const metadataStore = yield* IMetadataStoreService;\n const keyring = yield* KeyringApiService;\n const signingContextProvider = yield* SpacesContract.SigningContextProviderService;\n const hypercoreStore = yield* HypercoreStoreService;\n const echoHost = yield* EchoHostService;\n const invitationsManager = yield* InvitationsContract.ManagerService;\n const edgeConnection = yield* Effect.serviceOption(EdgeConnectionService);\n const edgeHttpClient = yield* Effect.serviceOption(EdgeHttpClientService);\n const meshReplicator = yield* Effect.serviceOption(MeshEchoReplicatorService);\n const echoEdgeReplicator = yield* Effect.serviceOption(EdgeAutomergeReplicatorService);\n\n const dataSpaceManager = new DataSpaceManager({\n spaceManager,\n metadataStore,\n keyring,\n signingContextProvider,\n hypercoreStore,\n echoHost,\n invitationsManager,\n edgeConnection: Option.getOrUndefined(edgeConnection),\n edgeHttpClient: Option.getOrUndefined(edgeHttpClient),\n meshReplicator: Option.getOrUndefined(meshReplicator),\n echoEdgeReplicator: Option.getOrUndefined(echoEdgeReplicator),\n ...options,\n });\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(() => dataSpaceManager.close(Context.default())));\n yield* Hook.on(\n Events.IdentityAvailable,\n Effect.fn('DataSpaceManager.onIdentityAvailable')(function* ({ identity }) {\n yield* Effect.promise(() => dataSpaceManager.open(ctx));\n yield* Hook.emit(Events.DataSpacesAvailable, { identity });\n }),\n );\n yield* Hook.on(\n Events.ProfileUpdated,\n Effect.fn('DataSpaceManager.onProfileUpdated')(function* ({ profile }) {\n for (const space of dataSpaceManager.spaces.values()) {\n yield* Effect.promise(() => space.updateOwnProfile(profile));\n }\n }),\n );\n return dataSpaceManager;\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { SpacesService } from '@dxos/protocols/rpc';\n\nconst JSON_EXTENSIONS = ['.dx.json', '.dx.json.gz', '.json'];\nconst BINARY_EXTENSIONS = ['.tar', '.tar.gz'];\n\n/**\n * Detect the format of a space archive.\n *\n * Uses filename extension as the primary signal, and falls back to sniffing\n * the first bytes of the archive contents to distinguish JSON from tar.\n */\nexport const detectSpaceArchiveFormat = (\n archive: Pick<SpacesService.SpaceArchive, 'filename' | 'contents'>,\n): SpacesService.SpaceArchiveFormat => {\n const filename = archive.filename?.toLowerCase() ?? '';\n if (JSON_EXTENSIONS.some((ext) => filename.endsWith(ext))) {\n return SpacesService.SpaceArchiveFormat.enums.JSON;\n }\n if (BINARY_EXTENSIONS.some((ext) => filename.endsWith(ext))) {\n return SpacesService.SpaceArchiveFormat.enums.BINARY;\n }\n\n // Fall back to byte sniffing: JSON archives start with '{' (0x7B) or whitespace.\n const bytes = archive.contents;\n if (bytes && bytes.length > 0) {\n for (let i = 0; i < Math.min(bytes.length, 16); i++) {\n const byte = bytes[i];\n // Skip whitespace.\n if (byte === 0x20 || byte === 0x09 || byte === 0x0a || byte === 0x0d) {\n continue;\n }\n if (byte === 0x7b /* '{' */) {\n return SpacesService.SpaceArchiveFormat.enums.JSON;\n }\n break;\n }\n }\n\n return SpacesService.SpaceArchiveFormat.enums.BINARY;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Obj, Type } from '@dxos/echo';\nimport { type SerializedSpace } from '@dxos/echo-client';\nimport { type DatabaseDirectory, type EntityStructure } from '@dxos/echo-protocol';\nimport { assertArgument } from '@dxos/invariant';\nimport { URI } from '@dxos/keys';\nimport { type SpacesService } from '@dxos/protocols/rpc';\n\nconst ATTR_TYPE = '@type';\nconst ATTR_META = '@meta';\nconst ATTR_DELETED = '@deleted';\nconst ATTR_PARENT = '@parent';\nconst ATTR_RELATION_SOURCE = '@relationSource';\nconst ATTR_RELATION_TARGET = '@relationTarget';\n\n/**\n * Type URI of the meta-schema (`TypeSchema` / `Type.Type`). Objects with this\n * `@type` represent persisted ECHO type definitions and must be branded\n * `system.kind = 'type'` so `Filter.type(Type.Type)` and `Type.isType` recognize\n * them after import. Anything else defaults to `'object'` (or `'relation'` when\n * source/target attrs are present).\n */\nconst TYPE_KIND_SCHEMA_URI = Type.getURI(Type.Type).toString();\n\nconst INTERNAL_KEYS: ReadonlySet<string> = new Set([\n 'id',\n ATTR_TYPE,\n ATTR_META,\n ATTR_DELETED,\n ATTR_PARENT,\n ATTR_RELATION_SOURCE,\n ATTR_RELATION_TARGET,\n]);\n\n/**\n * Parse a JSON space archive.\n *\n * The archive contents are expected to be the UTF-8 encoding of\n * `JSON.stringify(serializedSpace)`.\n */\nexport const readSerializedSpaceArchive = (archive: SpacesService.SpaceArchive): SerializedSpace => {\n const text = new TextDecoder().decode(archive.contents);\n const parsed = JSON.parse(text) as SerializedSpace;\n assertArgument(typeof parsed === 'object' && parsed !== null, 'archive', 'Invalid JSON archive payload');\n assertArgument(typeof parsed.version === 'number', 'archive', 'Missing SerializedSpace.version');\n assertArgument(Array.isArray(parsed.objects), 'archive', 'Missing SerializedSpace.objects');\n return parsed;\n};\n\n/**\n * Convert an {@link Obj.JSON} back into an internal {@link EntityStructure} suitable\n * for embedding into a {@link DatabaseDirectory}.\n */\nexport const objJsonToObjectStructure = (obj: Obj.JSON): EntityStructure => {\n const data: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (INTERNAL_KEYS.has(key)) {\n continue;\n }\n data[key] = value;\n }\n\n const system: NonNullable<EntityStructure['system']> = {};\n\n const type = obj[ATTR_TYPE];\n if (type) {\n system.type = { '/': URI.make(type) };\n }\n\n const parent = (obj as any)[ATTR_PARENT];\n if (typeof parent === 'string') {\n system.parent = { '/': URI.make(parent) };\n }\n\n const relationSource = (obj as any)[ATTR_RELATION_SOURCE];\n const relationTarget = (obj as any)[ATTR_RELATION_TARGET];\n if (typeof relationSource === 'string' || typeof relationTarget === 'string') {\n system.kind = 'relation';\n if (typeof relationSource === 'string') {\n system.source = { '/': URI.make(relationSource) };\n }\n if (typeof relationTarget === 'string') {\n system.target = { '/': URI.make(relationTarget) };\n }\n // TODO(wittjosiah): This is fragile, will break if the type URI changes.\n } else if (type === TYPE_KIND_SCHEMA_URI) {\n system.kind = 'type';\n } else {\n system.kind = 'object';\n }\n\n if ((obj as any)[ATTR_DELETED]) {\n system.deleted = true;\n }\n\n const meta = (obj as any)[ATTR_META];\n return {\n system,\n meta: {\n keys: meta?.keys ?? [],\n ...(meta?.tags ? { tags: meta.tags } : {}),\n // Preserve registry-provenance fields so persisted `Type.Type` entities\n // round-trip with their typename / semver (see the symmetric write in\n // `objectStructureToObjJson`).\n ...(meta?.key !== undefined ? { key: meta.key } : {}),\n ...(meta?.version !== undefined ? { version: meta.version } : {}),\n // Preserve annotations (see the symmetric write in `objectStructureToObjJson`).\n ...(meta?.annotations ? { annotations: meta.annotations } : {}),\n },\n data,\n };\n};\n\n/**\n * Build a new {@link DatabaseDirectory} containing every object from the archive,\n * keyed by object id. The caller is responsible for stamping the `access` (space id/key)\n * and version fields after the document is created.\n */\nexport const buildDatabaseDirectoryFromObjects = (objects: readonly Obj.JSON[]): DatabaseDirectory => {\n const map: Record<string, EntityStructure> = {};\n for (const obj of objects) {\n map[obj.id] = objJsonToObjectStructure(obj);\n }\n return {\n objects: map,\n links: {},\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type AutomergeUrl } from '@automerge/automerge-repo';\nimport * as Effect from 'effect/Effect';\nimport * as Exit from 'effect/Exit';\nimport * as Scope from 'effect/Scope';\n\nimport { Context } from '@dxos/context';\nimport { type SpecificCredential } from '@dxos/credentials';\nimport { type Obj } from '@dxos/echo';\nimport { type SerializedFeed, type SerializedSpace } from '@dxos/echo-client';\nimport { type DatabaseRoot, type EchoHost } from '@dxos/echo-host';\nimport { type DatabaseDirectory, type EntityStructure } from '@dxos/echo-protocol';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { assertState, invariant } from '@dxos/invariant';\nimport { DXN, type EntityId, type IdentityDid, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { FeedProtocol, makeInProcessClient } from '@dxos/protocols';\nimport { type Epoch } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { FeedService, SpacesService } from '@dxos/protocols/rpc';\nimport { createFilename } from '@dxos/util';\n\n/**\n * The part of a live space an archive is written from; structural so that the exporter\n * does not depend on the space implementation.\n */\nexport type ExportableSpace = {\n readonly id: SpaceId;\n readonly automergeSpaceState: { readonly lastEpoch: SpecificCredential<Epoch> | undefined };\n readonly databaseRoot: DatabaseRoot | null;\n};\n\nconst SERIALIZED_SPACE_VERSION = 1;\n\nconst FEED_TYPENAME = 'org.dxos.type.feed';\n\nconst ATTR_ID = 'id';\nconst ATTR_TYPE = '@type';\nconst ATTR_META = '@meta';\nconst ATTR_DELETED = '@deleted';\nconst ATTR_PARENT = '@parent';\nconst ATTR_RELATION_SOURCE = '@relationSource';\nconst ATTR_RELATION_TARGET = '@relationTarget';\n\n/**\n * Canonical order of well-known system fields in a serialized object.\n * All remaining `@*` fields follow in the order they appear on the source\n * object, and finally the data fields are appended in their existing order.\n */\nconst SYSTEM_FIELD_ORDER: readonly string[] = [\n ATTR_ID,\n ATTR_TYPE,\n ATTR_META,\n ATTR_DELETED,\n ATTR_PARENT,\n ATTR_RELATION_SOURCE,\n ATTR_RELATION_TARGET,\n];\n\n/**\n * Reorder the keys of an {@link Obj.JSON} so that system fields appear first\n * (`id`, `@type`, `@meta`, then any other `@*` attributes), followed by data\n * fields. The returned object has identical values to the input — only the key\n * iteration order changes.\n */\nexport const orderObjJsonFields = (obj: Obj.JSON): Obj.JSON => {\n const source = obj as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of SYSTEM_FIELD_ORDER) {\n if (key in source) {\n result[key] = source[key];\n }\n }\n for (const key of Object.keys(source)) {\n if (key.startsWith('@') && !(key in result)) {\n result[key] = source[key];\n }\n }\n for (const key of Object.keys(source)) {\n if (!(key in result)) {\n result[key] = source[key];\n }\n }\n return result as Obj.JSON;\n};\n\nexport type WriteSerializedSpaceArchiveOptions = {\n space: ExportableSpace;\n echoHost: EchoHost;\n exportedBy?: IdentityDid;\n};\n\n/**\n * Write a JSON space archive from a live space.\n *\n * This runs entirely inside the worker and walks automerge documents directly —\n * it does not require a client-side {@link EchoDatabase}. The output conforms to\n * {@link SerializedSpace} and is compatible with the JSON format consumed by the\n * importer in {@link readSerializedSpaceArchive}.\n */\nexport const writeSerializedSpaceArchive = async (\n options: WriteSerializedSpaceArchiveOptions,\n): Promise<SpacesService.SpaceArchive> => {\n const { space, echoHost, exportedBy } = options;\n\n const rootUrl = space.automergeSpaceState.lastEpoch?.assertion.automergeRoot;\n assertState(rootUrl, 'Space does not have a root URL');\n const databaseRoot = space.databaseRoot;\n assertState(databaseRoot, 'Space database root is not ready');\n\n const rootDoc = databaseRoot.doc();\n invariant(rootDoc, 'Space database root document is not loaded');\n\n // Collect all object structures across the root doc and any linked docs.\n const objects: Obj.JSON[] = [];\n collectObjectsFromDoc(rootDoc, objects);\n\n for (const linkedUrl of databaseRoot.getAllLinkedDocuments()) {\n using lease = await echoHost.loadDoc<DatabaseDirectory>(Context.default(), linkedUrl as AutomergeUrl);\n if (!lease) {\n log.warn('linked document handle not available; skipping', { url: linkedUrl });\n continue;\n }\n collectObjectsFromDoc(lease.doc(), objects);\n }\n\n // Export queue/feed messages for every Feed object in the space.\n const feeds = await exportFeedData(space, echoHost, objects);\n\n const serialized: SerializedSpace = {\n version: SERIALIZED_SPACE_VERSION,\n timestamp: new Date().toISOString(),\n originalSpaceId: space.id,\n exportedBy,\n createdAt: Date.now(),\n objects,\n ...(feeds.length > 0 ? { feeds } : {}),\n };\n\n const encoded = new TextEncoder().encode(JSON.stringify(serialized));\n return {\n filename: createFilename({ parts: [space.id], ext: 'dx.json' }),\n contents: encoded,\n format: SpacesService.SpaceArchiveFormat.enums.JSON,\n };\n};\n\nconst collectObjectsFromDoc = (doc: DatabaseDirectory, out: Obj.JSON[]): void => {\n const docObjects = doc.objects ?? {};\n for (const [objectId, structure] of Object.entries(docObjects)) {\n out.push(objectStructureToObjJson(objectId, structure));\n }\n};\n\n/**\n * Convert an internal {@link EntityStructure} into an {@link Obj.JSON}.\n *\n * Unlike the equivalent helper used for indexing, this preserves the object's\n * `@meta` section so archives produced by this writer can be round-tripped\n * through {@link Obj.fromJSON}.\n */\nexport const objectStructureToObjJson = (objectId: string, structure: EntityStructure): Obj.JSON => {\n const result: Record<string, unknown> = {\n [ATTR_ID]: objectId,\n [ATTR_TYPE]: (structure.system?.type?.['/'] ?? '') as any,\n };\n\n if (structure.meta) {\n result[ATTR_META] = {\n keys: structure.meta.keys ?? [],\n ...(structure.meta.tags ? { tags: structure.meta.tags } : {}),\n // Preserve the registry-provenance fields (typename / semver) so persisted\n // `Type.Type` entities round-trip with their `meta.key` / `meta.version`\n // intact — `Type.getTypename` / `Type.getVersion` read these. Without them\n // a type loaded from an archive would fall back to its object id.\n ...(structure.meta.key !== undefined ? { key: structure.meta.key } : {}),\n ...(structure.meta.version !== undefined ? { version: structure.meta.version } : {}),\n // Preserve annotations (e.g. `AppAnnotation.RootCollectionAnnotation` on a space's\n // properties object) so archives round-trip app-level metadata, not just schema data.\n ...(structure.meta.annotations && Object.keys(structure.meta.annotations).length > 0\n ? { annotations: structure.meta.annotations }\n : {}),\n };\n }\n if (structure.system?.deleted) {\n result[ATTR_DELETED] = true;\n }\n if (structure.system?.parent) {\n result[ATTR_PARENT] = structure.system.parent['/'];\n }\n if (structure.system?.source) {\n result[ATTR_RELATION_SOURCE] = structure.system.source['/'];\n }\n if (structure.system?.target) {\n result[ATTR_RELATION_TARGET] = structure.system.target['/'];\n }\n Object.assign(result, structure.data);\n\n return result as Obj.JSON;\n};\n\nconst exportFeedData = async (\n space: ExportableSpace,\n echoHost: EchoHost,\n objects: Obj.JSON[],\n): Promise<SerializedFeed[]> => {\n const feeds: SerializedFeed[] = [];\n const spaceId: SpaceId = space.id;\n\n for (const obj of objects) {\n if (obj[ATTR_TYPE] == null) {\n continue;\n }\n\n const typeDxn = obj[ATTR_TYPE];\n const typeDxnNsid = DXN.isDXN(typeDxn) ? DXN.getName(typeDxn) : undefined;\n if (typeDxnNsid !== FEED_TYPENAME) {\n continue;\n }\n\n const namespace = (obj as any).namespace === 'trace' ? 'trace' : 'data';\n\n try {\n const messages = await collectFeedMessages(echoHost, spaceId, obj.id, namespace);\n if (messages.length > 0) {\n feeds.push({\n feedObjectId: obj.id,\n namespace,\n messages,\n });\n }\n } catch (err) {\n log.warn('failed to export feed data', { feedObjectId: obj.id, error: err });\n }\n }\n\n return feeds;\n};\n\nconst collectFeedMessages = async (\n echoHost: EchoHost,\n spaceId: SpaceId,\n feedId: EntityId,\n namespace: string,\n): Promise<Obj.JSON[]> => {\n const feedNamespace =\n namespace === 'trace' ? FeedProtocol.WellKnownNamespaces.trace : FeedProtocol.WellKnownNamespaces.data;\n\n const messages: Obj.JSON[] = [];\n let cursor: string | undefined;\n\n // Bridge the host feed Handlers to a client to call it in-process (Handlers are served, not\n // called directly). The scope owns the client for the duration of the read.\n const scope = Effect.runSync(Scope.make());\n const feedClient = await EffectEx.runPromise(\n makeInProcessClient(FeedService.Rpcs, echoHost.feedService).pipe(Effect.provideService(Scope.Scope, scope)),\n );\n try {\n while (true) {\n const result = await EffectEx.runPromise(\n feedClient['FeedService.queryFeed']({\n query: {\n spaceId,\n feedIds: [feedId],\n feedNamespace,\n after: cursor,\n },\n }),\n );\n const batch = (result.objects ?? []).flatMap((encoded): Obj.JSON[] => {\n try {\n return [JSON.parse(encoded) as Obj.JSON];\n } catch (err) {\n log.verbose('feed object JSON parse failed; object ignored', { encoded, error: err });\n return [];\n }\n });\n if (batch.length === 0) {\n break;\n }\n for (const message of batch) {\n messages.push(orderObjJsonFields(message));\n }\n if (!result.nextCursor || result.nextCursor === cursor) {\n break;\n }\n cursor = result.nextCursor;\n }\n } finally {\n await EffectEx.runPromise(Scope.close(scope, Exit.void));\n }\n return messages;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport type { DocumentId } from '@automerge/automerge-repo';\n\nimport { assertArgument, invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport {\n type FeedArchiveBlock,\n type FeedArchiveMetadata,\n SpaceArchiveFileStructure,\n type SpaceArchiveMetadata,\n} from '@dxos/protocols';\nimport type { SpacesService } from '@dxos/protocols/rpc';\n\n/**\n * Extracted feed data from the archive.\n */\nexport type ExtractedFeed = {\n metadata: FeedArchiveMetadata;\n blocks: FeedArchiveBlock[];\n};\n\nexport type ExtractedSpaceArchive = {\n metadata: SpaceArchiveMetadata;\n documents: Record<DocumentId, Uint8Array>;\n feeds: Record<string, ExtractedFeed>;\n};\n\nexport const extractSpaceArchive = async (archive: SpacesService.SpaceArchive): Promise<ExtractedSpaceArchive> => {\n const { Archive } = await import('@obsidize/tar-browserify');\n const { entries } = await Archive.extract(archive.contents);\n const metadataEntry = entries.find((entry) => entry.fileName === SpaceArchiveFileStructure.metadata);\n assertArgument(metadataEntry, 'metadataEntry', 'Metadata entry not found');\n const metadata = JSON.parse(metadataEntry.getContentAsText());\n const documents: Record<DocumentId, Uint8Array> = {};\n for (const entry of entries.filter((entry) => entry.fileName.startsWith(`${SpaceArchiveFileStructure.documents}/`))) {\n const documentId = entry.fileName\n .replace(`${SpaceArchiveFileStructure.documents}/`, '')\n .replace(/\\.bin$/, '') as DocumentId;\n invariant(!documentId.includes('/'));\n // The reader leaves `content` null for a zero-byte entry, which an export writes for a document with no local chunks.\n if (!entry.content || entry.content.byteLength === 0) {\n log.warn('skipping empty document in space archive', { documentId });\n continue;\n }\n documents[documentId] = entry.content;\n }\n\n const feeds: Record<string, ExtractedFeed> = {};\n const feedsPrefix = `${SpaceArchiveFileStructure.feeds}/`;\n const feedEntries = entries.filter((entry) => entry.fileName.startsWith(feedsPrefix));\n\n const feedMetadataByFeedId = new Map<string, FeedArchiveMetadata>();\n const feedBlocksByFeedId = new Map<string, Map<number, FeedArchiveBlock[]>>();\n\n for (const entry of feedEntries) {\n const relativePath = entry.fileName.slice(feedsPrefix.length);\n const pathParts = relativePath.split('/');\n if (pathParts.length !== 2) {\n continue;\n }\n\n const [feedId, fileName] = pathParts;\n invariant(feedId, 'Feed ID is required');\n invariant(fileName, 'File name is required');\n\n if (fileName === SpaceArchiveFileStructure.feedMetadata) {\n const feedMetadata = JSON.parse(entry.getContentAsText()) as FeedArchiveMetadata;\n feedMetadataByFeedId.set(feedId, feedMetadata);\n } else if (fileName.startsWith(SpaceArchiveFileStructure.feedBlocksPrefix) && fileName.endsWith('.json')) {\n const chunkIndexStr = fileName.slice(SpaceArchiveFileStructure.feedBlocksPrefix.length).replace(/\\.json$/, '');\n const chunkIndex = parseInt(chunkIndexStr, 10);\n invariant(!isNaN(chunkIndex), `Invalid chunk index: ${chunkIndexStr}`);\n\n const blocks = JSON.parse(entry.getContentAsText()) as FeedArchiveBlock[];\n if (!feedBlocksByFeedId.has(feedId)) {\n feedBlocksByFeedId.set(feedId, new Map());\n }\n feedBlocksByFeedId.get(feedId)!.set(chunkIndex, blocks);\n }\n }\n\n for (const [feedId, feedMetadata] of feedMetadataByFeedId) {\n const blockChunks = feedBlocksByFeedId.get(feedId) ?? new Map<number, FeedArchiveBlock[]>();\n const sortedChunkIndices = Array.from(blockChunks.keys()).sort((a, b) => a - b);\n const allBlocks: FeedArchiveBlock[] = [];\n for (const chunkIndex of sortedChunkIndices) {\n allBlocks.push(...blockChunks.get(chunkIndex)!);\n }\n feeds[feedId] = {\n metadata: feedMetadata,\n blocks: allBlocks,\n };\n }\n\n log('extracted space archive', { metadata, documents, feedCount: Object.keys(feeds).length });\n return { metadata, documents, feeds };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as tar from '@obsidize/tar-browserify';\n\nimport { type Context, Resource } from '@dxos/context';\nimport { assertArgument, assertState } from '@dxos/invariant';\nimport type { IdentityDid, SpaceId } from '@dxos/keys';\nimport {\n FEED_ARCHIVE_BLOCKS_PER_CHUNK,\n type FeedArchiveBlock,\n type FeedArchiveMetadata,\n SpaceArchiveFileStructure,\n type SpaceArchiveMetadata,\n SpaceArchiveVersion,\n} from '@dxos/protocols';\nimport { SpacesService } from '@dxos/protocols/rpc';\nimport { createFilename } from '@dxos/util';\n\nexport type SpaceArchiveBeginProps = {\n spaceId?: SpaceId;\n\n /**\n * DID of the identity that exported the space.\n */\n exportedBy?: IdentityDid;\n};\n\nconst CURRENT_VERSION = SpaceArchiveVersion.V1;\n\nexport class SpaceArchiveWriter extends Resource {\n private _tar?: typeof tar;\n private _archive?: tar.Archive;\n\n private _meta?: SpaceArchiveBeginProps = undefined;\n private _currentRootUrl?: string = undefined;\n\n protected override async _open(ctx: Context): Promise<void> {\n this._tar = await import('@obsidize/tar-browserify');\n }\n\n protected override async _close(): Promise<void> {\n return Promise.resolve();\n }\n\n async begin(meta: SpaceArchiveBeginProps): Promise<void> {\n assertState(this._tar, 'Not open');\n assertState(!this._meta, 'Already started');\n this._meta = meta;\n this._archive = new this._tar.Archive();\n }\n\n async setCurrentRootUrl(url: string): Promise<void> {\n assertArgument(url.startsWith('automerge:'), 'url', 'Invalid root URL');\n assertState(this._tar, 'Not open');\n assertState(this._meta, 'Not started');\n this._currentRootUrl = url;\n }\n\n async writeDocument(documentId: string, data: Uint8Array): Promise<void> {\n assertArgument(!documentId.startsWith('automerge:'), 'documentId', 'Invalid document ID');\n assertState(this._archive, 'Not open');\n this._archive.addBinaryFile(`${SpaceArchiveFileStructure.documents}/${documentId}.bin`, data);\n }\n\n /**\n * Writes a feed with its metadata and blocks to the archive.\n * Blocks are written in chunks of {@link FEED_ARCHIVE_BLOCKS_PER_CHUNK}.\n */\n async writeFeed(feedId: string, namespace: string, blocks: FeedArchiveBlock[]): Promise<void> {\n assertArgument(feedId, 'feedId', 'Feed ID is required');\n assertArgument(namespace, 'namespace', 'Namespace is required');\n assertState(this._archive, 'Not open');\n\n const feedPath = `${SpaceArchiveFileStructure.feeds}/${feedId}`;\n\n const metadata: FeedArchiveMetadata = {\n id: feedId,\n namespace,\n };\n this._archive.addTextFile(`${feedPath}/${SpaceArchiveFileStructure.feedMetadata}`, JSON.stringify(metadata));\n\n for (let chunkIndex = 0; chunkIndex * FEED_ARCHIVE_BLOCKS_PER_CHUNK < blocks.length; chunkIndex++) {\n const start = chunkIndex * FEED_ARCHIVE_BLOCKS_PER_CHUNK;\n const end = Math.min(start + FEED_ARCHIVE_BLOCKS_PER_CHUNK, blocks.length);\n const chunk = blocks.slice(start, end);\n this._archive.addTextFile(\n `${feedPath}/${SpaceArchiveFileStructure.feedBlocksPrefix}${chunkIndex}.json`,\n JSON.stringify(chunk),\n );\n }\n }\n\n async finish(): Promise<SpacesService.SpaceArchive> {\n assertState(this._archive, 'Not open');\n assertState(this._meta, 'Not started');\n assertState(this._meta.spaceId, 'No space ID set');\n assertState(this._currentRootUrl, 'No root URL set');\n\n const metadata: SpaceArchiveMetadata = {\n version: CURRENT_VERSION,\n createdAt: Date.now(),\n exportedBy: this._meta.exportedBy,\n originalSpaceId: this._meta.spaceId,\n echo: {\n currentRootUrl: this._currentRootUrl,\n },\n };\n\n this._archive.addTextFile(SpaceArchiveFileStructure.metadata, JSON.stringify(metadata));\n\n const binary = this._archive.toUint8Array();\n\n return {\n filename: createFilename({ parts: [this._meta.spaceId], ext: 'tar' }),\n contents: binary,\n format: SpacesService.SpaceArchiveFormat.enums.BINARY,\n };\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport type { AutomergeUrl } from '@automerge/automerge-repo';\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { SubscriptionList, UpdateScheduler, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport {\n type CredentialProcessor,\n createAdmissionCredentials,\n createDidFromIdentityKey,\n credentialOfPayload,\n credentialPayload,\n getCredentialAssertion,\n} from '@dxos/credentials';\nimport { raise } from '@dxos/debug';\nimport { type EchoHost, EchoHostService } from '@dxos/echo-host';\nimport { type DatabaseDirectory } from '@dxos/echo-protocol';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { writeMessages } from '@dxos/feed-store';\nimport { assertArgument, assertState, invariant } from '@dxos/invariant';\nimport { SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n ApiError,\n AuthorizationError,\n FeedProtocol,\n IdentityNotInitializedError,\n SpaceNotFoundError,\n encodeError,\n makeInProcessClient,\n toServiceError,\n} from '@dxos/protocols';\nimport { buf, fromPublicKey, fromTimeframe, requirePublicKey } from '@dxos/protocols/buf';\nimport { SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n type ContactAdmission,\n ContactAdmissionSchema,\n type CreateEpochResponse,\n CreateEpochResponseSchema,\n IdentitySchema,\n type JoinSpaceResponse,\n JoinSpaceResponseSchema,\n type QuerySpacesResponse,\n QuerySpacesResponseSchema,\n type Space,\n Space_PipelineStateSchema,\n type SpaceMember,\n SpaceMember_PresenceState,\n SpaceMemberSchema,\n SpaceSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { FeedService, SpacesService } from '@dxos/protocols/rpc';\nimport { trace } from '@dxos/tracing';\nimport { type Provider } from '@dxos/util';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Readiness from '../../Readiness.ts';\nimport {\n SpaceArchiveWriter,\n detectSpaceArchiveFormat,\n extractSpaceArchive,\n objJsonToObjectStructure,\n readSerializedSpaceArchive,\n writeSerializedSpaceArchive,\n} from '../space-export/index.ts';\nimport { type SpaceManager, SpaceManagerService } from '../space/index.ts';\nimport { type DataSpace } from './data-space.ts';\n\n/** Reads the space as the buf message the service returns. */\n\nexport class SpacesServiceImpl implements SpacesService.Handlers {\n 'constructor'(\n private readonly _identityManager: IdentityContract.Manager,\n private readonly _spaceManager: SpaceManager,\n private readonly _echoHost: EchoHost,\n private readonly _getDataSpaceManager: Provider<Promise<SpacesContract.Manager>>,\n ) {}\n\n ['SpacesService.createSpace'](request: SpacesService.CreateSpaceRequest): Effect.Effect<Space, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n this._requireIdentity();\n const ctx = new Context();\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = await dataSpaceManager.createSpace(ctx, {\n tags: request?.tags,\n membershipPolicy: request?.membershipPolicy,\n });\n await this._updateMetrics();\n return this._serializeSpace(space);\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.updateSpace']({\n spaceKey,\n state,\n edgeReplication,\n }: SpacesService.UpdateSpaceRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n\n if (state) {\n switch (state) {\n case SpaceState.SPACE_ACTIVE:\n await space.activate(ctx);\n break;\n\n case SpaceState.SPACE_INACTIVE:\n await space.deactivate(ctx);\n break;\n\n case SpaceState.SPACE_DELETED:\n await dataSpaceManager.markSpaceDeleted(ctx, spaceKey);\n // The space is removed from the manager; skip any further mutations (e.g. edgeReplication).\n return;\n default:\n throw new ApiError({ message: 'Invalid space state' });\n }\n }\n\n if (edgeReplication !== undefined) {\n await dataSpaceManager.setSpaceEdgeReplicationSetting(ctx, spaceKey, edgeReplication);\n }\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.updateMemberRole'](request: SpacesService.UpdateMemberRoleRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const identity = this._requireIdentity();\n const space = this._spaceManager.spaces.get(request.spaceKey);\n if (space == null) {\n throw new SpaceNotFoundError(request.spaceKey);\n }\n if (!space.spaceState.hasMembershipManagementPermission(identity.identityKey)) {\n throw new AuthorizationError({\n message: 'No member management permission.',\n context: {\n spaceKey: space.key,\n role: space.spaceState.getMemberRole(identity.identityKey),\n },\n });\n }\n const credentials = await createAdmissionCredentials({\n signer: identity.getIdentityCredentialSigner(),\n identityKey: request.memberKey,\n spaceKey: space.key,\n genesisFeedKey: space.genesisFeedKey,\n role: request.newRole,\n membershipChainHeads: space.spaceState.membershipChainHeads,\n });\n const spaceMemberCredential = credentialOfPayload(credentials[0]);\n invariant(\n getCredentialAssertion(spaceMemberCredential).$typeName === 'dxos.halo.credentials.SpaceMember',\n 'Invalid credential',\n );\n await writeMessages(space.controlPipeline.writer, credentials);\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.querySpaces'](): EffectStream.Stream<QuerySpacesResponse, Error> {\n return EffectEx.streamFromEmitter<QuerySpacesResponse, Error>((emit) => {\n const ctx = Context.default();\n const scheduler = new UpdateScheduler(\n ctx,\n async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n const spaces = await Promise.all(\n Array.from(dataSpaceManager.spaces.values()).map((space) => this._serializeSpace(space)),\n );\n log('update', () => ({ ids: spaces.map((space) => space.id) }));\n await this._updateMetrics();\n void emit.single(buf.create(QuerySpacesResponseSchema, { spaces }));\n },\n { maxFrequency: process.env.NODE_ENV === 'test' ? undefined : 2 },\n );\n\n scheduleTask(ctx, async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n\n const subscriptions = new SubscriptionList();\n ctx.onDispose(() => subscriptions.clear());\n\n // TODO(dmaretskyi): Create a pattern for subscribing to a set of objects.\n const subscribeSpaces = () => {\n subscriptions.clear();\n\n for (const space of dataSpaceManager.spaces.values()) {\n let lastState: SpaceState | undefined;\n subscriptions.add(\n space.stateUpdate.on(ctx, () => {\n // Always send a separate update if the space state has changed.\n if (space.state !== lastState) {\n scheduler.forceTrigger();\n } else {\n scheduler.trigger();\n }\n lastState = space.state;\n }),\n );\n\n subscriptions.add(space.presence.updated.on(ctx, () => scheduler.trigger()));\n subscriptions.add(space.automergeSpaceState.onNewEpoch.on(ctx, () => scheduler.trigger()));\n\n // Pipeline progress.\n subscriptions.add(space.inner.controlPipeline.state.timeframeUpdate.on(ctx, () => scheduler.trigger()));\n }\n };\n\n dataSpaceManager.updated.on(ctx, () => {\n subscribeSpaces();\n scheduler.trigger();\n });\n subscribeSpaces();\n\n scheduler.trigger();\n });\n\n if (!this._identityManager.identity) {\n void emit.single(buf.create(QuerySpacesResponseSchema, { spaces: [] }));\n }\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['SpacesService.postMessage']({\n spaceKey,\n channel,\n message,\n }: SpacesService.PostMessageRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n invariant(message, 'Post carries no message.');\n await space.postMessage(getChannelId(channel), message);\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.subscribeMessages']({\n spaceKey,\n channel,\n }: SpacesService.SubscribeMessagesRequest): EffectStream.Stream<SpacesService.SubscribeMessagesResponse, Error> {\n return EffectStream.unwrap(\n Effect.promise(() => this._getDataSpaceManager()).pipe(\n Effect.map((dataSpaceManager) =>\n EffectEx.streamFromEmitter<SpacesService.SubscribeMessagesResponse, Error>((emit) => {\n const space = dataSpaceManager.spaces.get(spaceKey);\n if (!space) {\n emit.fail(new SpaceNotFoundError(spaceKey));\n return;\n }\n const handle = space.listen(getChannelId(channel), (message) => emit.single({ _tag: 'Message', message }));\n emit.single({ _tag: 'Ready' });\n return Effect.sync(() => handle.unsubscribe());\n }),\n ),\n ),\n );\n }\n\n ['SpacesService.queryCredentials']({\n spaceKey,\n noTail,\n }: SpacesService.QueryCredentialsRequest): EffectStream.Stream<Credential, Error> {\n return EffectEx.streamFromEmitter<Credential, Error>((emit) => {\n const ctx = Context.default();\n const space = this._spaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n\n const processor: CredentialProcessor = {\n processCredential: async (credential) => {\n void emit.single(credential);\n },\n };\n ctx.onDispose(() => space.spaceState.removeCredentialProcessor(processor));\n scheduleTask(ctx, async () => {\n await space.spaceState.addCredentialProcessor(processor);\n if (noTail) {\n void emit.end();\n }\n });\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['SpacesService.writeCredentials']({\n spaceKey,\n credentials,\n }: SpacesService.WriteCredentialsRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const space = this._spaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n for (const bufCredential of credentials ?? []) {\n const credential = bufCredential;\n if (credential.proof) {\n await space.controlPipeline.writer.write(credentialPayload(credential));\n } else {\n invariant(!credential.id, 'Id on unsigned credentials is not allowed');\n invariant(this._identityManager.identity, 'Identity is not available');\n const signer = this._identityManager.identity.getIdentityCredentialSigner();\n const subject = credential.subject;\n invariant(subject?.assertion, 'Credential has no assertion.');\n invariant(requirePublicKey(credential.issuer).equals(signer.getIssuer()));\n const signedCredential = await signer.createCredential({\n subject: requirePublicKey(subject.id),\n assertion: getCredentialAssertion(credential),\n });\n await space.controlPipeline.writer.write(credentialPayload(signedCredential));\n }\n }\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.createEpoch']({\n spaceKey,\n migration,\n automergeRootUrl,\n }: SpacesService.CreateEpochRequest): Effect.Effect<CreateEpochResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n const result = await space.createEpoch({ migration, newAutomergeRoot: automergeRootUrl });\n return buf.create(CreateEpochResponseSchema, {\n epochCredential: result?.credential,\n controlTimeframe: result?.timeframe && fromTimeframe(result.timeframe),\n });\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.admitContact'](request: SpacesService.AdmitContactRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n await dataSpaceManager.admitMember({\n spaceKey: request.spaceKey,\n identityKey: requirePublicKey(request.contact?.identityKey),\n role: request.role,\n // Record the profile the host already knows, so the member is named before they first join.\n profile: request.contact?.profile,\n });\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.joinBySpaceKey']({\n spaceKey,\n }: SpacesService.JoinBySpaceKeyRequest): Effect.Effect<JoinSpaceResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n const dataSpaceManager = await this._getDataSpaceManager();\n const credential = await dataSpaceManager.requestSpaceAdmissionCredential(ctx, spaceKey);\n return this._joinByAdmission(ctx, create(ContactAdmissionSchema, { credential }));\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.exportSpace'](\n request: SpacesService.ExportSpaceRequest,\n ): Effect.Effect<SpacesService.ExportSpaceResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n assertArgument(SpaceId.isValid(request.spaceId), 'spaceId', 'Invalid space ID');\n\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = dataSpaceManager.getSpaceById(request.spaceId) ?? raise(new Error('Space not found'));\n\n const format = request.format ?? SpacesService.SpaceArchiveFormat.enums.BINARY;\n if (format === SpacesService.SpaceArchiveFormat.enums.JSON) {\n const archive = await writeSerializedSpaceArchive({ space, echoHost: this._echoHost });\n return { archive };\n }\n\n await using writer = await new SpaceArchiveWriter().open();\n await writer.begin({ spaceId: space.id });\n const rootUrl = space.automergeSpaceState.lastEpoch?.assertion.automergeRoot;\n assertState(rootUrl, 'Space does not have a root URL');\n await writer.setCurrentRootUrl(rootUrl);\n\n for await (const [documentId, data] of space.getAllDocuments()) {\n // A linked document never persisted locally exports as zero bytes, which no importer can load.\n if (data.byteLength === 0) {\n log.warn('skipping document with no local data in space export', { spaceId: space.id, documentId });\n continue;\n }\n await writer.writeDocument(documentId, data);\n }\n\n const feeds = await space.getAllFeeds();\n for (const feed of feeds) {\n const archiveBlocks = feed.blocks.map((block) => ({\n actorId: block.actorId,\n sequence: block.sequence,\n prevActorId: block.prevActorId,\n prevSequence: block.prevSequence,\n position: block.position,\n timestamp: block.timestamp,\n data: Buffer.from(block.data).toString('base64'),\n }));\n await writer.writeFeed(feed.feedId, feed.feedNamespace, archiveBlocks);\n }\n\n const archive = await writer.finish();\n return { archive };\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.importSpace'](\n request: SpacesService.ImportSpaceRequest,\n ): Effect.Effect<SpacesService.ImportSpaceResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n const dataSpaceManager = await this._getDataSpaceManager();\n\n const format = request.archive.format ?? detectSpaceArchiveFormat(request.archive);\n if (format === SpacesService.SpaceArchiveFormat.enums.JSON) {\n const serialized = readSerializedSpaceArchive(request.archive);\n const space = await dataSpaceManager.createSpace(ctx, { tags: request.tags });\n await this._hydrateSpaceFromSerialized(space, serialized);\n await this._updateMetrics();\n return { newSpaceId: space.id };\n }\n\n const extracted = await extractSpaceArchive(request.archive);\n invariant(extracted.metadata.echo?.currentRootUrl, 'Space archive does not contain a root URL');\n const space = await dataSpaceManager.createSpace(ctx, {\n documents: extracted.documents,\n rootUrl: extracted.metadata.echo?.currentRootUrl as AutomergeUrl,\n tags: request.tags,\n });\n await this._updateMetrics();\n return { newSpaceId: space.id };\n },\n catch: toServiceError,\n });\n }\n\n /**\n * Populate a freshly-created space with the objects and feed messages described in a {@link SerializedSpace}.\n *\n * Objects are written directly into the space's automerge root document as inline\n * {@link EntityStructure} entries; feed messages are appended to the appropriate feed\n * via {@link EchoHost.feedService}.\n */\n private async '_hydrateSpaceFromSerialized'(\n space: DataSpace,\n serialized: ReturnType<typeof readSerializedSpaceArchive>,\n ): Promise<void> {\n const databaseRoot = space.databaseRoot;\n assertState(databaseRoot, 'Space database root is not ready');\n\n databaseRoot.change((doc: DatabaseDirectory) => {\n if (!doc.objects) {\n doc.objects = {};\n }\n for (const obj of serialized.objects) {\n doc.objects[obj.id] = objJsonToObjectStructure(obj);\n }\n });\n\n for (const feed of serialized.feeds ?? []) {\n if (feed.messages.length === 0) {\n continue;\n }\n\n const namespace =\n feed.namespace === 'trace' ? FeedProtocol.WellKnownNamespaces.trace : FeedProtocol.WellKnownNamespaces.data;\n try {\n // Handlers are served, not called directly; bridge to a client in-process for this write.\n const feedService = this._echoHost.feedService;\n await EffectEx.runPromise(\n Effect.gen(function* () {\n const feedClient = yield* makeInProcessClient(FeedService.Rpcs, feedService);\n yield* feedClient['FeedService.insertIntoFeed']({\n spaceId: space.id,\n feedId: feed.feedObjectId,\n subspaceTag: namespace,\n objects: feed.messages.map((message) => JSON.stringify(message)),\n });\n }).pipe(Effect.scoped),\n );\n } catch (err) {\n log.warn('failed to import feed data', { feedObjectId: feed.feedObjectId, error: err });\n }\n }\n }\n\n private async '_joinByAdmission'(ctx: Context, { credential }: ContactAdmission): Promise<JoinSpaceResponse> {\n invariant(credential, 'Admission carries no credential.');\n const assertion = getCredentialAssertion(credential);\n invariant(assertion.$typeName === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');\n const myIdentity = this._identityManager.identity;\n invariant(myIdentity && requirePublicKey(credential.subject?.id).equals(myIdentity.identityKey));\n\n const spaceKey = requirePublicKey(assertion.spaceKey);\n const dataSpaceManager = await this._getDataSpaceManager();\n let dataSpace = dataSpaceManager.spaces.get(spaceKey);\n if (!dataSpace) {\n dataSpace = await dataSpaceManager.acceptSpace(ctx, {\n spaceKey,\n genesisFeedKey: requirePublicKey(assertion.genesisFeedKey),\n tags: assertion.tags,\n });\n await myIdentity.controlPipeline.writer.write(credentialPayload(credential));\n }\n\n return buf.create(JoinSpaceResponseSchema, { space: await this._serializeSpace(dataSpace) });\n }\n\n private async '_serializeSpace'(space: DataSpace): Promise<Space> {\n const lastEpoch = space.automergeSpaceState.lastEpoch?.credential;\n return buf.create(SpaceSchema, {\n id: space.id,\n spaceKey: fromPublicKey(space.key),\n state: space.state,\n error: space.error ? encodeError(space.error) : undefined,\n pipeline: create(Space_PipelineStateSchema, {\n currentEpoch: lastEpoch,\n appliedEpoch: lastEpoch,\n\n controlFeeds: space.inner.controlPipeline.state.feeds.map((feed) => fromPublicKey(feed.key)),\n currentControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.timeframe),\n targetControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.targetTimeframe),\n totalControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.endTimeframe),\n\n directoryUrl: space.databaseRoot?.url,\n }),\n members: await Promise.all(\n Array.from(space.inner.spaceState.members.values()).map(async (member): Promise<SpaceMember> => {\n const peers = space.presence.getPeersByIdentityKey(member.key);\n const isMe = this._identityManager.identity?.identityKey.equals(member.key);\n\n if (isMe) {\n peers.push(space.presence.getLocalState());\n }\n\n return create(SpaceMemberSchema, {\n identity: create(IdentitySchema, {\n did: await createDidFromIdentityKey(member.key),\n identityKey: fromPublicKey(member.key),\n profile: member.profile,\n }),\n role: member.role,\n presence: peers.length > 0 ? SpaceMember_PresenceState.ONLINE : SpaceMember_PresenceState.OFFLINE,\n peerStates: peers,\n });\n }),\n ),\n creator: space.inner.spaceState.creator && fromPublicKey(space.inner.spaceState.creator.key),\n tags: space.tags,\n membershipPolicy: space.membershipPolicy,\n metrics: space.metrics,\n edgeReplication: space.getEdgeReplicationSetting(),\n });\n }\n\n private '_requireIdentity'() {\n if (!this._identityManager.identity) {\n throw new IdentityNotInitializedError({\n message: 'This device has no HALO identity available. See https://docs.dxos.org/guide/platform/halo',\n });\n }\n return this._identityManager.identity;\n }\n\n private async '_updateMetrics'(): Promise<void> {\n const dataSpaceManager = await this._getDataSpaceManager();\n const identity = this._identityManager.identity?.identityKey.truncate();\n if (identity) {\n trace.metrics.gauge('dxos.echo.space.count', dataSpaceManager.spaces.size, {\n tags: { identity },\n });\n }\n }\n}\n\nexport const SpacesServiceLayer: Layer.Layer<\n SpacesService.Tag,\n never,\n | IdentityContract.ManagerService\n | SpaceManagerService\n | EchoHostService\n | SpacesContract.ManagerService\n | Readiness.StackReadinessService\n> = Layer.effect(\n SpacesService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const spaceManager = yield* SpaceManagerService;\n const echoHost = yield* EchoHostService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const readiness = yield* Readiness.StackReadinessService;\n return new SpacesServiceImpl(identityManager, spaceManager, echoHost, () =>\n readiness.initialized.wait().then(() => dataSpaceManager),\n );\n }),\n);\n\n// Add `user-channel` prefix to the channel name, so that it doesn't collide with the internal channels.\nconst getChannelId = (channel: string): string => `user-channel/${channel}`;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport type * as SqlClient from 'effect/sql/SqlClient';\n\nimport * as ComputeSqlService from '@dxos/compute/SqlService';\nimport { SqlService } from '@dxos/protocols/rpc';\n\nconst toWireRow = (row: ComputeSqlService.Row): Record<string, SqlService.SqlValue> =>\n Object.fromEntries(Object.entries(row).map(([column, value]) => [column, SqlService.toSqlValue(value)]));\n\n/**\n * Serves `SqlService` RPCs from the host's shared database through the sanitizing backend.\n */\nexport const SqlServiceLayer: Layer.Layer<SqlService.Tag, never, SqlClient.SqlClient> = Layer.effect(\n SqlService.Tag,\n Effect.gen(function* () {\n const backend = yield* ComputeSqlService.SqlService;\n const handlers: SqlService.Handlers = {\n 'SqlService.execute': (request) =>\n backend.execute(request).pipe(Effect.map((rows) => ({ rows: rows.map(toWireRow) }))),\n 'SqlService.begin': (request) => backend.begin(request),\n 'SqlService.commit': (request) => backend.commit(request),\n 'SqlService.rollback': (request) => backend.rollback(request),\n };\n return handlers;\n }),\n).pipe(Layer.provide(ComputeSqlService.layerGuarded), Layer.orDie);\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Fiber from 'effect/Fiber';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Event, MulticastObservable } from '@dxos/async';\nimport { type Config, ConfigService } from '@dxos/config';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { BaseError } from '@dxos/errors';\nimport { log } from '@dxos/log';\nimport { SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { toServiceError } from '@dxos/protocols';\nimport { type Platform, SystemStatus } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Config as ConfigProto, ConfigSchema } from '@dxos/protocols/buf/dxos/config_pb';\nimport { SystemService } from '@dxos/protocols/rpc';\nimport { RpcRouter } from '@dxos/rpc';\nimport { type MaybePromise, jsonKeyReplacer } from '@dxos/util';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Events from '../../Events.ts';\nimport * as PlatformInfo from '../../PlatformInfo.ts';\nimport { type Diagnostics, createDiagnosticsFromRouter } from '../diagnostics/index.ts';\n\nexport type SystemServiceOptions = {\n config?: () => MaybePromise<Config | undefined>;\n getDiagnostics: () => Promise<Partial<Diagnostics['services']>>;\n /**\n * The embedder's controller, which outlives the stack; a reset is the\n * `Closing → WipingStorage → Reset` chain on it.\n */\n controller: Hook.ControllerService;\n};\n\n/**\n * The one client service that exists while the host is closed: it reports and drives the host's\n * status and performs a reset. The host pushes its status in via {@link setStatus}.\n */\nexport class SystemServiceImpl implements SystemService.Handlers {\n /** A client asked for the host to become this status; the host decides what to do about it. */\n readonly 'statusRequested' = new Event<SystemStatus>();\n\n readonly #statusChanged = new Event<SystemStatus>();\n readonly #status = MulticastObservable.from(this.#statusChanged, SystemStatus.INACTIVE);\n readonly #options: SystemServiceOptions;\n #resetting = false;\n #resetFiber: Fiber.Fiber<void> | undefined;\n\n 'constructor'(options: SystemServiceOptions) {\n this.#options = options;\n }\n\n get 'status'(): SystemStatus {\n return this.#status.get();\n }\n\n /**\n * Reports the host's status to subscribers. Ignored once a reset is under way: that status is\n * final because the app reloads.\n */\n 'setStatus'(status: SystemStatus): void {\n if (this.#resetting) {\n return;\n }\n this.#statusChanged.emit(status);\n }\n\n /**\n * Runs the reset chain: the embedder closes the stack, wipes its storage, and reloads. Reports\n * inactive first so the app falls back at once, and that status is never cleared because the app\n * reloads.\n */\n 'reset'(): Effect.Effect<void> {\n const chain = Effect.gen({ self: this }, function* () {\n log.info('resetting...');\n this.#resetting = true;\n this.#statusChanged.emit(SystemStatus.INACTIVE);\n // `Closing` tears the stack down under this very call, and under any request another session\n // has in flight: component finalizers are not re-entrant against live traffic. That holds only\n // because every embedder shuts down or reloads immediately after `Reset` below — a reset that\n // left the worker serving would need a gate that fails new requests from here on.\n yield* Hook.emit(Events.Closing, undefined);\n yield* Hook.emit(Events.WipingStorage, undefined);\n log.info('reset');\n yield* Hook.emit(Events.Reset, undefined);\n }).pipe(Effect.provideService(Hook.Controller, this.#options.controller));\n\n // Detached from the request fiber: `Closing` above closes the RPC route this very call is\n // served on, which would interrupt the chain before it ever wipes storage. Joining keeps the\n // caller's timing — the join is interrupted, the chain is not.\n //\n // Single-flight over that fiber, because the RPC server dispatches concurrently and a detached\n // chain no longer dies with its caller: a second `reset` would otherwise emit the whole\n // `Closing`/`WipingStorage`/`Reset` sequence again, against a stack the first one already tore\n // down. The fork and the assignment share one synchronous step, so no caller observes the gap.\n return Effect.gen({ self: this }, function* () {\n this.#resetFiber ??= yield* Effect.forkDetach(chain);\n yield* Fiber.join(this.#resetFiber);\n });\n }\n\n ['SystemService.getConfig'](): Effect.Effect<ConfigProto, BaseError> {\n return Effect.tryPromise({\n try: async () => (await this.#options.config?.())?.values ?? create(ConfigSchema, {}),\n catch: toServiceError,\n });\n }\n\n /**\n * NOTE: Since this is serialized as a JSON object, we allow the option to serialize keys.\n */\n ['SystemService.getDiagnostics']({ keys }: SystemService.GetDiagnosticsRequest = {}): Effect.Effect<\n SystemService.GetDiagnosticsResponse,\n Error\n > {\n return Effect.tryPromise({\n try: async () => {\n const diagnostics = await this.#options.getDiagnostics();\n return {\n timestamp: new Date(),\n diagnostics: JSON.parse(\n JSON.stringify(\n diagnostics,\n jsonKeyReplacer({\n truncate: keys === SystemService.KeyOption.enums.TRUNCATE,\n humanize: keys === SystemService.KeyOption.enums.HUMANIZE,\n }),\n ),\n ),\n };\n },\n catch: toServiceError,\n });\n }\n\n ['SystemService.getPlatform'](): Effect.Effect<Platform, BaseError> {\n return Effect.tryPromise({\n try: async () => PlatformInfo.getPlatform(),\n catch: toServiceError,\n });\n }\n\n ['SystemService.updateStatus']({ status }: SystemService.UpdateStatusRequest): Effect.Effect<void, BaseError> {\n return Effect.sync(() => this.statusRequested.emit(status));\n }\n\n // TODO(burdon): Standardize interval option in stream request?\n ['SystemService.queryStatus']({ interval = 3_000 }: SystemService.QueryStatusRequest = {}): EffectStream.Stream<\n SystemService.QueryStatusResponse,\n Error\n > {\n return EffectEx.streamFromEmitter<SystemService.QueryStatusResponse, Error>((emit) => {\n const subscription = this.#status.subscribe((status) => void emit.single({ status }));\n // Clients treat a silent stream as a dead worker, so the current status is repeated.\n const heartbeat = setInterval(() => void emit.single({ status: this.#status.get() }), interval);\n return Effect.sync(() => {\n clearInterval(heartbeat);\n subscription.unsubscribe();\n });\n });\n }\n\n ['SystemService.reset'](): Effect.Effect<void, BaseError> {\n return this.reset();\n }\n}\n\n/**\n * Serves the {@link SystemService} over the stack's domain handlers: active once the stack has\n * opened, inactive when the layer is torn down, and resetting over the embedder's controller.\n */\nexport const SystemServiceLayer: Layer.Layer<\n SystemService.Tag,\n never,\n | RpcRouter.RpcRouter\n | ConfigService\n | Hook.Controller\n | IdentityContract.ManagerService\n | SpacesContract.ManagerService\n | SwarmNetworkManagerService\n> = Layer.effect(\n SystemService.Tag,\n Effect.gen(function* () {\n const config = yield* ConfigService;\n const controller = yield* Hook.Controller;\n const router = yield* RpcRouter.RpcRouter;\n const stack = yield* Effect.context<\n IdentityContract.ManagerService | SpacesContract.ManagerService | SwarmNetworkManagerService\n >();\n const service = new SystemServiceImpl({\n config: () => config,\n getDiagnostics: () => createDiagnosticsFromRouter(router, stack, config),\n controller,\n });\n yield* Hook.on(Events.StackOpened, () => Effect.sync(() => service.setStatus(SystemStatus.ACTIVE)));\n yield* Effect.addFinalizer(() => Effect.sync(() => service.setStatus(SystemStatus.INACTIVE)));\n return service;\n }),\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { type Context, type Lifecycle, Resource } from '@dxos/context';\nimport { type CredentialProcessor, getCredentialAssertion } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { assertState } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport { type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\n\n/**\n * Replicates cross-device space membership and deletion credentials from the halo space.\n */\nexport interface CrossDeviceSpaceSynchronizer extends CredentialProcessor, Lifecycle {\n readonly identity: Identity | undefined;\n setIdentity(identity: Identity): void;\n}\n\n/**\n * Effect service tag for {@link CrossDeviceSpaceSynchronizer}.\n */\nexport class CrossDeviceSpaceSynchronizerService extends EffectContext.Service<\n CrossDeviceSpaceSynchronizerService,\n CrossDeviceSpaceSynchronizer\n>()('@dxos/client-services/CrossDeviceSpaceSynchronizer') {}\n\nclass CrossDeviceSpaceSynchronizerImpl extends Resource implements CrossDeviceSpaceSynchronizer {\n private _identity?: Identity;\n\n constructor(private readonly dataSpaceManager: SpacesContract.Manager) {\n super();\n }\n\n get identity(): Identity | undefined {\n return this._identity;\n }\n\n setIdentity(identity: Identity): void {\n this._identity = identity;\n }\n\n protected override async _open(ctx: Context): Promise<void> {\n assertState(this._identity, 'identity not set');\n await this._identity.space.spaceState.addCredentialProcessor(this);\n }\n\n protected override async _close(ctx: Context): Promise<void> {\n if (!this._identity) {\n return;\n }\n await this._identity.space.spaceState.removeCredentialProcessor(this);\n }\n\n async processCredential(credential: Credential): Promise<void> {\n assertState(this._identity, 'identity not set');\n const assertion = getCredentialAssertion(credential);\n\n // A space was tombstoned on another device: replicate the deletion locally.\n if (assertion.$typeName === 'dxos.halo.credentials.SpaceDeleted') {\n const spaceKey = requirePublicKey(assertion.spaceKey);\n if (spaceKey.equals(this._identity.space.key)) {\n // ignore halo space\n return;\n }\n if (!this.dataSpaceManager) {\n log('dataSpaceManager not initialized yet, ignoring space deletion', { details: assertion });\n return;\n }\n\n try {\n log('tombstoning space recorded in halo', { details: assertion });\n await this.dataSpaceManager.handleRemoteSpaceDeleted(this._ctx, spaceKey);\n } catch (err) {\n log.catch(err);\n }\n return;\n }\n\n if (assertion.$typeName !== 'dxos.halo.credentials.SpaceMember') {\n return;\n }\n const spaceKey = requirePublicKey(assertion.spaceKey);\n if (spaceKey.equals(this._identity.space.key)) {\n // ignore halo space\n return;\n }\n if (!this.dataSpaceManager) {\n log('dataSpaceManager not initialized yet, ignoring space admission', { details: assertion });\n return;\n }\n // Do not re-accept a space that has been tombstoned (handles out-of-order credential replay).\n if (this.dataSpaceManager.isSpaceDeleted(spaceKey)) {\n log('space is deleted, ignoring space admission', { details: assertion });\n return;\n }\n if (this.dataSpaceManager.spaces.has(spaceKey)) {\n log('space already exists, ignoring space admission', { details: assertion });\n return;\n }\n\n try {\n log('accepting space recorded in halo', { details: assertion });\n await this.dataSpaceManager.acceptSpace(this._ctx, {\n spaceKey,\n genesisFeedKey: requirePublicKey(assertion.genesisFeedKey),\n spaceRootUrl: assertion.spaceRootUrl,\n tags: assertion.tags,\n });\n } catch (err) {\n log.catch(err);\n }\n }\n}\n\n/**\n * Creates a dormant {@link CrossDeviceSpaceSynchronizer} bound to the given data space manager.\n */\nexport const createCrossDeviceSpaceSynchronizer = (\n dataSpaceManager: SpacesContract.Manager,\n): CrossDeviceSpaceSynchronizer => new CrossDeviceSpaceSynchronizerImpl(dataSpaceManager);\n\n/**\n * Effect Layer constructing a dormant {@link CrossDeviceSpaceSynchronizer}.\n */\nexport const CrossDeviceSpaceSynchronizerLayer: Layer.Layer<\n CrossDeviceSpaceSynchronizerService,\n never,\n Hook.Controller | SpacesContract.ManagerService\n> = Layer.effect(\n CrossDeviceSpaceSynchronizerService,\n Effect.gen(function* () {\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const synchronizer = createCrossDeviceSpaceSynchronizer(dataSpaceManager);\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(async () => synchronizer.close?.()));\n yield* Hook.on(\n Events.DataSpacesAvailable,\n Effect.fn('CrossDeviceSpaceSynchronizer.onDataSpacesAvailable')(function* ({ identity }) {\n if (synchronizer.identity === identity) {\n return;\n }\n // Rebound on every identity: after an in-place deletion the next one arrives while this is\n // still open on the deleted identity's HALO, which would never admit the new one's spaces.\n yield* Effect.promise(async () => synchronizer.close?.());\n synchronizer.setIdentity(identity);\n yield* Effect.promise(async () => synchronizer.open?.(ctx));\n }),\n );\n return synchronizer;\n }),\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { Encoder, decode as cborXdecode } from 'cbor-x';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Schema from 'effect/Schema';\nimport * as SqlClient from 'effect/sql/SqlClient';\n\nimport { AsyncTask, scheduleTask } from '@dxos/async';\nimport { Context, Resource } from '@dxos/context';\nimport { EchoHostService } from '@dxos/echo-host';\nimport { type EdgeConnection, EdgeConnectionService, MessageSchema } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { type FeedStore, SyncClient, SyncSpaceDeletedError } from '@dxos/feed';\nimport { invariant } from '@dxos/invariant';\nimport { SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { SystemError } from '@dxos/protocols';\nimport { FeedProtocol } from '@dxos/protocols';\nimport { EdgeService } from '@dxos/protocols';\nimport { createBuf } from '@dxos/protocols/buf';\nimport { EdgeStatus_ConnectionState } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Message as RouterMessage } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { bufferToArray } from '@dxos/util';\n\nimport * as Events from '../../Events.ts';\n\nconst encoder = new Encoder({ tagUint8Array: false, useRecords: false });\n\nconst DEFAULT_MESSAGE_BLOCKS_LIMIT = 50;\nconst DEFAULT_SYNC_CONCURRENCY = 5;\nconst DEFAULT_POLLING_INTERVAL = 5_000;\n/**\n * Full-poll interval used once the server has answered the subscribe handshake, and is therefore\n * pushing {@link FeedProtocol.FeedAdvanced} hints. Hints carry the latency, so the poll degrades to\n * a reconcile that only has to catch hints lost to an un-acked send or a socket closing mid-frame.\n */\nconst DEFAULT_RECONCILE_POLLING_INTERVAL = 30_000;\n/** Re-subscribe this long before the server's stated expiry, so a refresh never races the lapse. */\nconst SUBSCRIPTION_REFRESH_MARGIN_MS = 5 * 60_000;\nconst DEFAULT_POLL_REQUEST_THROTTLE_MS = 250;\nconst DEFAULT_FAILURE_BACKOFF_MS = 250;\nconst MAX_FAILURE_BACKOFF_MS = 30_000;\nconst MAX_BLOCKING_SYNC_ITERATIONS = 100;\n\nexport type FeedSyncerOptions = {\n runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n feedStore: FeedStore;\n edgeClient: EdgeConnection;\n peerId: string;\n getSpaceIds: () => SpaceId[];\n\n /**\n * Namespaces to sync.\n */\n syncNamespaces: string[];\n\n /**\n * Maximum number of blocks to sync in a single message.\n * @default 50\n */\n messageBlocksLimit?: number;\n\n /**\n * Maximum number of spaces to sync concurrently.\n * @default 5\n */\n syncConcurrency?: number;\n\n /**\n * Interval between full polls while the server is not known to push hints.\n * @default 5 seconds\n */\n pollingInterval?: number;\n\n /**\n * Interval between full polls once the server has answered the subscribe handshake and is pushing\n * {@link FeedProtocol.FeedAdvanced} hints.\n * @default 30 seconds\n */\n reconcilePollingInterval?: number;\n\n /**\n * Minimum delay between externally requested best-effort polls.\n * @default 250 ms\n */\n pollRequestThrottleMs?: number;\n\n /**\n * When false, only wires the edge message handler; poll/push background tasks and\n * `feedStore.onNewBlocks` auto-push are disabled. Use for tests that call `syncBlocking` explicitly.\n * @default true\n */\n backgroundSync?: boolean;\n\n /**\n * Max time to wait for a feed sync RPC response from edge, in milliseconds.\n * @default 30000 (see `DEFAULT_SYNC_RPC_TIMEOUT_MS` in `@dxos/feed`).\n */\n syncRpcTimeoutMs?: number;\n};\n\n/**\n * Effect service tag for {@link FeedSyncer}.\n *\n * undefined if not initialized.\n */\nexport class FeedSyncerService extends EffectContext.Service<FeedSyncerService, FeedSyncer | undefined>()(\n '@dxos/client-services/FeedSyncer',\n) {}\n\nexport class FeedSyncer extends Resource {\n readonly #syncNamespaces: string[];\n readonly #messageBlocksLimit: number;\n readonly #syncConcurrency: number;\n readonly #pollingInterval: number;\n readonly #reconcilePollingInterval: number;\n readonly #pollRequestThrottleMs: number;\n readonly #backgroundSync: boolean;\n\n readonly #runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n readonly #feedStore: FeedStore;\n readonly #edgeClient: EdgeConnection;\n readonly #syncClient: SyncClient;\n readonly #getSpaceIds: () => SpaceId[];\n\n #spacesToPoll = new Set<SpaceId>();\n /**\n * Spaces the server reported deleted on this connection. Nothing addressed to them is answered, so\n * a request only waits out its timeout and holds the run for every other space; they are left out\n * until the next reconnect, when the report is trusted afresh.\n */\n readonly #deletedSpaces = new Set<SpaceId>();\n /** Last time full poll was completed. */\n #lastFullPoll: number | null = null;\n #throttledPollScheduled = false;\n #lastRequestedPollAt: number | null = null;\n #pushFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n #pullFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n\n /**\n * True once the server answered a `SubscribeRequest` on the current connection, which is the only\n * evidence that it will push hints. An older EDGE ignores the request, so the interval must stay\n * at {@link #pollingInterval} rather than relaxing on a hint that will never arrive. Cleared on\n * reconnect, since the next socket may land on a different build.\n */\n #serverPushesHints = false;\n /** Earliest `expiresAt` across live subscriptions; drives the refresh task. */\n #subscriptionExpiresAt: number | null = null;\n\n constructor(options: FeedSyncerOptions) {\n super();\n this.#runtime = options.runtime;\n this.#feedStore = options.feedStore;\n this.#edgeClient = options.edgeClient;\n this.#syncClient = new SyncClient({\n peerId: options.peerId,\n feedStore: options.feedStore,\n sendMessage: this.#sendMessage.bind(this),\n rpcTimeoutMs: options.syncRpcTimeoutMs,\n });\n this.#getSpaceIds = options.getSpaceIds;\n this.#syncNamespaces = options.syncNamespaces;\n this.#messageBlocksLimit = options.messageBlocksLimit ?? DEFAULT_MESSAGE_BLOCKS_LIMIT;\n this.#syncConcurrency = options.syncConcurrency ?? DEFAULT_SYNC_CONCURRENCY;\n this.#pollingInterval = options.pollingInterval ?? DEFAULT_POLLING_INTERVAL;\n this.#reconcilePollingInterval = options.reconcilePollingInterval ?? DEFAULT_RECONCILE_POLLING_INTERVAL;\n this.#pollRequestThrottleMs = options.pollRequestThrottleMs ?? DEFAULT_POLL_REQUEST_THROTTLE_MS;\n this.#backgroundSync = options.backgroundSync ?? true;\n }\n\n protected override async _open(): Promise<void> {\n this._ctx.onDispose(\n this.#edgeClient.onMessage((msg: RouterMessage) => {\n if (!msg.serviceId) {\n return;\n }\n const service = msg.serviceId.split(':')[0];\n if (service !== EdgeService.QUEUE_REPLICATOR) {\n return;\n }\n log('feed sync edge ingress', {\n serviceId: msg.serviceId,\n payloadByteLength: msg.payload?.value?.byteLength,\n });\n const handleMessageEffect = Effect.gen({ self: this }, function* () {\n const decoded = yield* Effect.try({\n try: () => cborXdecode(msg.payload!.value),\n catch: (error) => new SystemError({ message: 'Failed to decode feed sync message.', cause: error }),\n });\n // v4 dropped `Schema.validate`; decoding through the type side is the equivalent.\n const payload = yield* Schema.decodeEffect(Schema.toType(FeedProtocol.ProtocolMessage))(decoded);\n // Server-initiated messages carry no `requestId`, so `SyncClient.handleMessage` — which\n // matches responses to in-flight RPCs — would discard them.\n if (payload._tag === 'FeedAdvanced') {\n this.#onFeedAdvanced(payload);\n return;\n }\n if (payload._tag === 'SubscribeResponse') {\n this.#onSubscribeResponse(payload);\n return;\n }\n yield* this.#syncClient.handleMessage(payload);\n }).pipe(\n Effect.tapError((cause) =>\n Effect.sync(() =>\n log('feed sync edge message handling failed', {\n serviceId: msg.serviceId,\n payloadByteLength: msg.payload?.value?.byteLength,\n cause: cause instanceof Error ? cause.message : String(cause),\n }),\n ),\n ),\n );\n\n void RuntimeProvider.runPromise(this.#runtime)(handleMessageEffect);\n }),\n );\n\n if (this.#backgroundSync) {\n // Tasks must be opened before registering listeners that call `schedule()`:\n // * `onNewBlocks` can fire from any `feedStore.append` happening on a separate\n // microtask while `_open()` is still awaiting.\n // * The edge client invokes `onReconnected` as a microtask when already connected.\n // `AsyncTask.schedule()` throws if the task is not yet open.\n await this.#pollTask.open();\n await this.#pushTask.open();\n\n this.#feedStore.onNewBlocks.on(this._ctx, () => {\n this.#pushTask.schedule();\n });\n }\n\n this._ctx.onDispose(\n // NOTE: Fires immediately (as a microtask) if the connection is already open, and again\n // on every subsequent reconnect.\n this.#edgeClient.onReconnected(async () => {\n log('feed sync edge reconnected', {\n peerKey: this.#edgeClient.peerKey,\n identityDid: this.#edgeClient.identityDid,\n });\n // A reconnect may land on a different EDGE build, and any subscription the previous socket\n // held is gone with it, so the capability has to be re-established rather than assumed.\n this.#serverPushesHints = false;\n this.#subscriptionExpiresAt = null;\n this.#deletedSpaces.clear();\n if (this.#backgroundSync) {\n this.#sendSubscriptions();\n this.#resetSpacesToPoll();\n this.#pollTask.schedule();\n this.#pushTask.schedule();\n }\n }),\n );\n\n // Only kick the initial round when the socket is already up. While it is not, each send parks on\n // the ready trigger; the `onReconnected` handler above schedules exactly this same work the\n // moment it connects, so a host that gates its dial until after boot loses nothing here.\n if (this.#backgroundSync && this.#edgeClient.status.state === EdgeStatus_ConnectionState.CONNECTED) {\n this.#sendSubscriptions();\n this.#resetSpacesToPoll();\n this.#pollTask.schedule();\n // Flush blocks written before the syncer opened: `onNewBlocks` only fires on append,\n // so existing unpositioned blocks would otherwise never be pushed.\n this.#pushTask.schedule();\n }\n }\n\n protected override async _close(): Promise<void> {\n if (this.#backgroundSync) {\n await this.#pollTask.close();\n await this.#pushTask.close();\n }\n }\n\n /**\n * Full-poll interval currently in force.\n *\n * A server that never answers the subscribe handshake will never hint, so the tight interval is\n * the only thing keeping remote writes visible against it.\n */\n get #currentPollingInterval(): number {\n return this.#serverPushesHints ? this.#reconcilePollingInterval : this.#pollingInterval;\n }\n\n /**\n * Announce interest in every synced namespace of every known space.\n *\n * Namespace-wide (empty `feedIds`): the client cannot enumerate a namespace's feed ids until it\n * has pulled them, so per-feed subscription would miss exactly the feeds it has not seen yet.\n */\n #sendSubscriptions(): void {\n for (const spaceId of this.#getSpaceIds()) {\n for (const feedNamespace of this.#syncNamespaces) {\n this.#sendServerBoundMessage(\n {\n _tag: 'SubscribeRequest',\n spaceId,\n feedNamespace,\n feedIds: [],\n senderPeerId: this.#edgeClient.peerKey,\n recipientPeerId: undefined,\n },\n FeedProtocol.encodeServiceId(feedNamespace, spaceId),\n );\n }\n }\n }\n\n /**\n * Fire-and-forget send of a message the server does not answer with a correlated RPC response.\n *\n * Failure is logged and dropped: the reconcile poll is the backstop for every hint path, so a\n * subscribe that does not land costs freshness rather than correctness.\n */\n #sendServerBoundMessage(message: FeedProtocol.ProtocolMessage, serviceId: string): void {\n const send = Effect.tryPromise(async () =>\n this.#edgeClient.send(\n this._ctx,\n createBuf(MessageSchema, {\n source: {\n identityDid: this.#edgeClient.identityDid,\n peerKey: this.#edgeClient.peerKey,\n },\n serviceId,\n payload: { value: bufferToArray(encoder.encode(message)) },\n }),\n ),\n ).pipe(\n Effect.tapError((cause) =>\n Effect.sync(() =>\n log('feed sync server-bound send failed', {\n tag: message._tag,\n serviceId,\n cause: cause instanceof Error ? cause.message : String(cause),\n }),\n ),\n ),\n Effect.ignore,\n );\n void EffectEx.runPromise(send);\n }\n\n /**\n * The server accepted a subscription, which is this client's only evidence that it is running a\n * build that pushes hints — an older EDGE drops `SubscribeRequest` without replying.\n */\n #onSubscribeResponse(message: Extract<FeedProtocol.ProtocolMessage, { _tag: 'SubscribeResponse' }>): void {\n const wasPushing = this.#serverPushesHints;\n this.#serverPushesHints = true;\n if (this.#subscriptionExpiresAt == null || message.expiresAt < this.#subscriptionExpiresAt) {\n this.#subscriptionExpiresAt = message.expiresAt;\n this.#scheduleSubscriptionRefresh();\n }\n if (!wasPushing) {\n log('feed sync switched to push-driven reconcile', {\n reconcilePollingInterval: this.#reconcilePollingInterval,\n expiresAt: message.expiresAt,\n });\n }\n }\n\n /**\n * The server says a namespace gained blocks. Queue exactly that space for the next pull rather\n * than resetting every space, so an active space cannot drag the whole workspace into a full poll.\n */\n #onFeedAdvanced(message: Extract<FeedProtocol.ProtocolMessage, { _tag: 'FeedAdvanced' }>): void {\n if (!this.#backgroundSync) {\n return;\n }\n const { spaceId } = message;\n if (!SpaceId.isValid(spaceId)) {\n log.warn('feed sync hint carried an invalid space id', { spaceId: message.spaceId });\n return;\n }\n // A well-formed id is not yet one this client tracks, and the hint is server-supplied: without\n // this the server could drive pulls for arbitrary spaces.\n if (!this.#getSpaceIds().includes(spaceId)) {\n log.warn('feed sync hint named an untracked space', { spaceId });\n return;\n }\n log('feed sync hint received', {\n spaceId,\n feedNamespace: message.feedNamespace,\n position: message.position,\n });\n this.#spacesToPoll.add(spaceId);\n this.#pollTask.schedule();\n }\n\n /** Re-announce subscriptions before the server's stated expiry lapses. */\n #scheduleSubscriptionRefresh(): void {\n if (this.#subscriptionExpiresAt == null) {\n return;\n }\n const remaining = this.#subscriptionExpiresAt - Date.now();\n if (remaining <= 0) {\n return;\n }\n // Halving is what keeps a short-lived subscription from refreshing at zero delay, which would\n // spin subscribe/response as fast as the socket allows.\n const margin = Math.min(SUBSCRIPTION_REFRESH_MARGIN_MS, remaining / 2);\n const delay = remaining - margin;\n scheduleTask(\n this._ctx,\n () => {\n this.#subscriptionExpiresAt = null;\n this.#sendSubscriptions();\n },\n delay,\n );\n }\n\n /**\n * Schedules a best-effort pull without blocking the caller.\n */\n schedulePoll(): void {\n if (!this.#backgroundSync) {\n return;\n }\n this.#resetSpacesToPoll();\n if (this.#throttledPollScheduled) {\n return;\n }\n\n const now = Date.now();\n const delay =\n this.#lastRequestedPollAt == null\n ? 0\n : Math.max(this.#pollRequestThrottleMs - (now - this.#lastRequestedPollAt), 0);\n this.#throttledPollScheduled = true;\n scheduleTask(\n this._ctx,\n () => {\n this.#throttledPollScheduled = false;\n this.#lastRequestedPollAt = Date.now();\n this.#pollTask.schedule();\n },\n delay,\n );\n }\n\n /**\n * Performs queue sync and blocks until there are no pending sync batches.\n */\n async syncBlocking(\n ctx: Context,\n {\n spaceId,\n subspaceTag,\n shouldPush = true,\n shouldPull = true,\n }: {\n spaceId: SpaceId;\n subspaceTag: string;\n shouldPush?: boolean;\n shouldPull?: boolean;\n },\n ): Promise<void> {\n invariant(SpaceId.isValid(spaceId));\n invariant(FeedProtocol.isWellKnownNamespace(subspaceTag));\n if (!shouldPush && !shouldPull) {\n return;\n }\n\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen({ self: this }, function* () {\n let done = false;\n let iterations = 0;\n while (!done) {\n done = true;\n if (shouldPull) {\n const pullResult = yield* this.#syncClient.pull(ctx, {\n spaceId,\n feedNamespace: subspaceTag,\n limit: this.#messageBlocksLimit,\n });\n done &&= pullResult.done;\n }\n\n if (shouldPush) {\n const pushResult = yield* this.#syncClient.push(ctx, {\n spaceId,\n feedNamespace: subspaceTag,\n limit: this.#messageBlocksLimit,\n });\n done &&= pushResult.done;\n }\n iterations++;\n if (iterations > MAX_BLOCKING_SYNC_ITERATIONS) {\n throw new Error('Blocking sync exceeded max iterations.');\n }\n }\n }),\n );\n }\n\n #schedulePushRetry({ hadFailure, needsMore }: { hadFailure: boolean; needsMore: boolean }): void {\n if (!needsMore) {\n this.#pushFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n return;\n }\n if (hadFailure) {\n const delayMs = this.#pushFailureBackoffMs;\n this.#pushFailureBackoffMs = Math.min(this.#pushFailureBackoffMs * 2, MAX_FAILURE_BACKOFF_MS);\n log('feed sync push retry scheduled with backoff', { delayMs });\n scheduleTask(this._ctx, () => this.#pushTask.schedule(), delayMs);\n return;\n }\n this.#pushFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n this.#pushTask.schedule();\n }\n\n /**\n * Delays the next poll after a failed pull. A pull that fails the same way on every attempt\n * would otherwise re-run the moment it returns, since a space that is not done is polled again\n * immediately -- a tight loop of requests against the very server that is failing them.\n */\n #schedulePollRetry(): void {\n const delayMs = this.#pullFailureBackoffMs;\n this.#pullFailureBackoffMs = Math.min(this.#pullFailureBackoffMs * 2, MAX_FAILURE_BACKOFF_MS);\n log('feed sync poll retry scheduled with backoff', { delayMs });\n scheduleTask(this._ctx, () => this.#pollTask.schedule(), delayMs);\n }\n\n #resetSpacesToPoll(): void {\n this.#spacesToPoll.clear();\n this.#getSpaceIds().forEach((spaceId) => {\n this.#spacesToPoll.add(spaceId);\n });\n this.#lastFullPoll = Date.now();\n }\n\n #sendMessage(\n ctx: Context,\n message: FeedProtocol.QueryRequest | FeedProtocol.AppendRequest,\n ): Effect.Effect<void, unknown, never> {\n return Effect.gen({ self: this }, function* () {\n const encoded = encoder.encode(message);\n const serviceId = this.#getTargetServiceId(message);\n const rpcTag = 'blocks' in message ? 'AppendRequest' : 'QueryRequest';\n log('feed sync edge rpc outgoing', {\n tag: rpcTag,\n serviceId,\n payloadByteLength: encoded.byteLength,\n spaceId: message.spaceId,\n feedNamespace: message.feedNamespace,\n requestId: message.requestId,\n });\n yield* Effect.tryPromise(async () =>\n this.#edgeClient.send(\n ctx,\n createBuf(MessageSchema, {\n source: {\n identityDid: this.#edgeClient.identityDid,\n peerKey: this.#edgeClient.peerKey,\n },\n serviceId,\n payload: { value: bufferToArray(encoded) },\n }),\n ),\n ).pipe(\n Effect.tapError((cause) =>\n Effect.sync(() =>\n log('feed sync edge send failed', {\n serviceId,\n tag: rpcTag,\n cause: cause instanceof Error ? cause.message : String(cause),\n }),\n ),\n ),\n );\n });\n }\n\n /**\n * Stops syncing a space for the rest of this connection once the server reports it deleted: the\n * namespace counts as done, and the other namespaces are not asked. Logged once, since both tasks\n * may report it.\n */\n #dropDeletedSpace(spaceId: SpaceId, feedNamespace: string, cause: SyncSpaceDeletedError): void {\n if (this.#deletedSpaces.has(spaceId)) {\n return;\n }\n this.#deletedSpaces.add(spaceId);\n this.#spacesToPoll.delete(spaceId);\n log.warn('feed sync stopped for a space the server reports deleted', {\n spaceId,\n feedNamespace,\n cause: cause.message,\n });\n }\n\n #logSyncFailure(\n operation: 'pull' | 'push',\n { spaceId, feedNamespace, cause }: { spaceId: SpaceId; feedNamespace: string; cause: unknown },\n ): void {\n log('feed sync operation failed', {\n operation,\n spaceId,\n feedNamespace,\n cause: cause instanceof Error ? cause.message : String(cause),\n errorTag: cause instanceof Error ? cause.name : undefined,\n });\n }\n\n #getTargetServiceId(message: FeedProtocol.QueryRequest | FeedProtocol.AppendRequest): string {\n // TODO(dmaretskyi): Perhaps in the future we will want to include the queue namespace here as well.\n // This would require putting it at the top level of the message.\n // For now, we let the edge router handle it.\n return FeedProtocol.encodeServiceId(message.feedNamespace, message.spaceId as SpaceId);\n }\n\n readonly #pollTask = new AsyncTask(async () =>\n Effect.gen({ self: this }, function* () {\n let hadPullFailure = false;\n yield* Effect.forEach(\n this.#spacesToPoll,\n (spaceId) =>\n Effect.gen({ self: this }, function* () {\n let doneForAllNamespaces = true;\n for (const feedNamespace of this.#syncNamespaces) {\n if (this.#deletedSpaces.has(spaceId)) {\n break;\n }\n const { done } = yield* this.#syncClient\n .pull(this._ctx, {\n spaceId,\n feedNamespace,\n limit: this.#messageBlocksLimit,\n })\n .pipe(\n Effect.catch((cause) =>\n Effect.sync(() => {\n if (cause instanceof SyncSpaceDeletedError) {\n this.#dropDeletedSpace(spaceId, feedNamespace, cause);\n return { done: true };\n }\n this.#logSyncFailure('pull', { spaceId, feedNamespace, cause });\n hadPullFailure = true;\n return { done: false };\n }),\n ),\n );\n if (!done) {\n doneForAllNamespaces = false;\n }\n }\n if (doneForAllNamespaces) {\n this.#spacesToPoll.delete(spaceId);\n }\n }),\n { concurrency: this.#syncConcurrency },\n );\n\n // A failed pull only swaps the immediate re-poll for the back-off; the full-poll bookkeeping\n // below still runs, or the failing space would become the only one ever polled again.\n const scheduleNext = hadPullFailure ? () => this.#schedulePollRetry() : () => this.#pollTask.schedule();\n if (!hadPullFailure) {\n this.#pullFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n }\n\n // If its time to do a full poll, reset the spaces to poll and schedule the next poll immediately.\n if (this.#lastFullPoll == null || Date.now() - this.#lastFullPoll > this.#currentPollingInterval) {\n this.#resetSpacesToPoll();\n scheduleNext();\n } else if (this.#spacesToPoll.size > 0) {\n // If there are some spaces still syncing, poll them immediately.\n scheduleNext();\n } else {\n // All spaces sync, and there's time before the next full poll, schedule it later.\n this.#resetSpacesToPoll();\n scheduleTask(\n this._ctx,\n () => this.#pollTask.schedule(),\n Math.max(this.#currentPollingInterval - (Date.now() - (this.#lastFullPoll ?? 0)), 0),\n );\n }\n }).pipe(RuntimeProvider.runPromise(this.#runtime)),\n );\n\n readonly #pushTask = new AsyncTask(async () =>\n Effect.gen({ self: this }, function* () {\n const outcomes = yield* Effect.forEach(\n this.#getSpaceIds(),\n (spaceId) =>\n Effect.gen({ self: this }, function* () {\n let needsMore = false;\n let hadFailure = false;\n for (const feedNamespace of this.#syncNamespaces) {\n if (this.#deletedSpaces.has(spaceId)) {\n break;\n }\n const { done } = yield* this.#syncClient\n .push(this._ctx, {\n spaceId,\n feedNamespace,\n limit: this.#messageBlocksLimit,\n })\n .pipe(\n Effect.catch((cause) =>\n Effect.sync(() => {\n if (cause instanceof SyncSpaceDeletedError) {\n this.#dropDeletedSpace(spaceId, feedNamespace, cause);\n return { done: true };\n }\n this.#logSyncFailure('push', { spaceId, feedNamespace, cause });\n hadFailure = true;\n return { done: false };\n }),\n ),\n );\n if (!done) {\n needsMore = true;\n }\n }\n return { hadFailure, needsMore };\n }),\n { concurrency: this.#syncConcurrency },\n );\n // One decision per run: decided per space, a space that pushed fine reset the back-off a\n // failing one was growing, so the failing one was retried at the minimum delay forever.\n this.#schedulePushRetry({\n hadFailure: outcomes.some((outcome) => outcome.hadFailure),\n needsMore: outcomes.some((outcome) => outcome.needsMore),\n });\n }).pipe(RuntimeProvider.runPromise(this.#runtime)),\n );\n}\n\nexport type FeedSyncerLayerOptions = Pick<\n FeedSyncerOptions,\n | 'peerId'\n | 'syncNamespaces'\n | 'messageBlocksLimit'\n | 'syncConcurrency'\n | 'pollingInterval'\n | 'pollRequestThrottleMs'\n | 'backgroundSync'\n | 'syncRpcTimeoutMs'\n>;\n\n/**\n * Effect Layer constructing a {@link FeedSyncer} from ambient SQL, echo host, and edge services.\n *\n * The feed store is sourced from the {@link EchoHostService} (breaking the EchoHost <-> FeedSyncer\n * cycle). Only included when an edge connection is configured, so it resolves the edge tag directly.\n */\nexport const FeedSyncerLayer = (\n options: FeedSyncerLayerOptions,\n): Layer.Layer<\n FeedSyncerService,\n never,\n Hook.Controller | SqlClient.SqlClient | EchoHostService | EdgeConnectionService\n> =>\n Layer.effect(\n FeedSyncerService,\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n const echoHost = yield* EchoHostService;\n const edgeClient = yield* EdgeConnectionService;\n const feedSyncer = new FeedSyncer({\n runtime,\n feedStore: echoHost.feedStore,\n edgeClient,\n getSpaceIds: () => echoHost.spaceIds,\n ...options,\n });\n\n // The echo host falls back to a no-op sync while these are unset, so only this layer sets them.\n echoHost.setFeedSyncHandlers({\n syncFeed: (ctx, request) =>\n feedSyncer.syncBlocking(ctx, {\n spaceId: request.spaceId as SpaceId,\n subspaceTag: request.subspaceTag,\n shouldPush: request.shouldPush,\n shouldPull: request.shouldPull,\n }),\n });\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(() => feedSyncer.close()));\n yield* Hook.on(\n Events.StackOpened,\n Effect.fn('FeedSyncer.onStackOpened')(function* () {\n yield* Effect.promise(() => feedSyncer.open(ctx));\n }),\n );\n return feedSyncer;\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { Mutex } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport {\n EdgeConnectionService,\n EdgeHttpClientService,\n type EdgeIdentity,\n createChainEdgeIdentity,\n createEphemeralEdgeIdentity,\n} from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { SignalManagerService } from '@dxos/messaging';\nimport { SwarmNetworkManager, SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { PeerSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { ChainSchema, type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { TransportFactoryService } from './client-platform.ts';\n\nexport type SwarmNetworkManagerLayerOptions = {\n /** @default true */\n connectionLog?: boolean;\n};\n\n/**\n * Constructs the swarm network manager over the ambient signal manager and transport factory.\n */\nexport const SwarmNetworkManagerLayer = (\n options: SwarmNetworkManagerLayerOptions = {},\n): Layer.Layer<SwarmNetworkManagerService, never, SignalManagerService | TransportFactoryService> =>\n Layer.effect(\n SwarmNetworkManagerService,\n Effect.gen(function* () {\n const signalManager = yield* SignalManagerService;\n const transportFactory = yield* TransportFactoryService;\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n return new SwarmNetworkManager({\n enableDevtoolsLogging: options.connectionLog ?? true,\n transportFactory,\n signalManager,\n peerInfo:\n edgeConnection &&\n create(PeerSchema, { identityDid: edgeConnection.identityDid, peerKey: edgeConnection.peerKey }),\n });\n }),\n );\n\nexport type NetworkLifecycleLayerOptions = {\n /** Emit `NetworkingEnabled` as soon as the stack is open; otherwise the embedder emits it. */\n autoConnect?: boolean;\n};\n\n/**\n * Binds the current identity to edge, signaling, and swarm networking, and drives their lifecycle:\n * opens them once the identity is loaded, starts the edge dial when networking is enabled, and\n * closes them when the layer is destroyed.\n */\nexport const NetworkLifecycleLayer = (\n options: NetworkLifecycleLayerOptions = {},\n): Layer.Layer<never, never, Hook.Controller | SwarmNetworkManagerService | SignalManagerService> =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n const networkManager = yield* SwarmNetworkManagerService;\n const signalManager = yield* SignalManagerService;\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n const edgeHttpClient = Option.getOrUndefined(yield* Effect.serviceOption(EdgeHttpClientService));\n const identityUpdateMutex = new Mutex();\n\n const setNetworkIdentity = async (params?: { deviceCredential?: Credential; identity?: Identity }) => {\n log('setting network identity...');\n using _ = await identityUpdateMutex.acquire();\n const edgeIdentity = await createEdgeIdentity(params);\n edgeConnection?.setIdentity(edgeIdentity);\n edgeHttpClient?.setIdentity(edgeIdentity);\n networkManager.setPeerInfo(\n create(PeerSchema, { identityDid: edgeIdentity.identityDid, peerKey: edgeIdentity.peerKey }),\n );\n log('network identity set');\n };\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() =>\n Effect.promise(async () => {\n await networkManager.close(Context.default());\n await signalManager.close();\n await edgeConnection?.close();\n }),\n );\n\n yield* Hook.on(\n Events.IdentityLoaded,\n Effect.fn('NetworkLifecycle.onIdentityLoaded')(function* ({ identity }) {\n yield* Effect.promise(async () => {\n await setNetworkIdentity({ identity });\n log('opening edge connection...');\n await edgeConnection?.open(ctx);\n log('opening signal manager...');\n await signalManager.open(ctx);\n log('opening network manager...');\n await networkManager.open();\n });\n yield* Hook.emit(Events.NetworkReady, undefined);\n }),\n );\n\n yield* Hook.on(\n Events.IdentityBound,\n Effect.fn('NetworkLifecycle.onIdentityBound')(function* ({ identity, deviceCredential }) {\n yield* Effect.promise(() => setNetworkIdentity({ identity, deviceCredential }));\n }),\n );\n\n // Only the edge dial is gated: subduction and feed sync resume from the edge reconnect.\n yield* Hook.on(\n Events.NetworkingEnabled,\n Effect.fn('NetworkLifecycle.onNetworkingEnabled')(function* () {\n log('starting edge networking');\n edgeConnection?.startNetworking();\n }),\n );\n\n if (options.autoConnect) {\n yield* Hook.on(\n Events.StackOpened,\n Effect.fn('NetworkLifecycle.onStackOpened')(function* () {\n yield* Hook.emit(Events.NetworkingEnabled, undefined);\n }),\n );\n }\n }),\n );\n\nconst createEdgeIdentity = async (params?: {\n deviceCredential?: Credential;\n identity?: Identity;\n}): Promise<EdgeIdentity> => {\n const identity = params?.identity;\n if (!identity) {\n return createEphemeralEdgeIdentity();\n }\n if (params?.deviceCredential) {\n return createChainEdgeIdentity(\n identity.signer,\n identity.identityKey,\n identity.deviceKey,\n create(ChainSchema, { credential: params.deviceCredential }),\n [], // TODO(dmaretskyi): Service access credentials.\n );\n }\n // TODO: throw here or from identity if device chain can't be loaded, to avoid indefinite hangup\n await warnAfterTimeout(10_000, 'Waiting for identity to be ready for edge connection', async () => {\n await identity.ready();\n });\n invariant(identity.deviceCredentialChain);\n return createChainEdgeIdentity(\n identity.signer,\n identity.identityKey,\n identity.deviceKey,\n identity.deviceCredentialChain,\n [], // TODO(dmaretskyi): Service access credentials.\n );\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport type * as SqlError from 'effect/sql/SqlError';\n\nimport {\n type AutomergeReplicator,\n EchoHostLayer,\n EchoHostService,\n type QueryExecutorMode,\n runSqliteHealthCheck,\n} from '@dxos/echo-host';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { SqliteKeyring } from '@dxos/keyring';\nimport { log } from '@dxos/log';\nimport { type SignalManager } from '@dxos/messaging';\nimport { type TransportFactory } from '@dxos/network-manager';\nimport { InvalidStorageVersionError, STORAGE_VERSION } from '@dxos/protocols';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as Events from '../../Events.ts';\nimport * as SqliteStorage from '../../SqliteStorage.ts';\nimport { type IdentityManagerProps, type InboxRelay, identityProviderFromManager } from '../identity/index.ts';\nimport { type InvitationConnectionProps } from '../invitations/index.ts';\nimport { IMetadataStoreService, SqliteMetadataStore } from '../metadata/index.ts';\nimport { SpaceManagerService } from '../space/index.ts';\nimport { type DataSpaceManagerRuntimeProps } from '../spaces/index.ts';\n\nexport type ServiceContextRuntimeProps = Pick<\n IdentityManagerProps,\n 'devicePresenceOfflineTimeout' | 'devicePresenceAnnounceInterval'\n> &\n DataSpaceManagerRuntimeProps & {\n invitationConnectionDefaultProps?: InvitationConnectionProps;\n disableP2pReplication?: boolean;\n enableVectorIndexing?: boolean;\n /** Query evaluation path for every host query; see `QueryExecutorMode`. */\n queryExecutor?: QueryExecutorMode;\n };\n\n/**\n * Combined storage migration effect gathered from the concrete SQLite stores.\n * Run by the storage lifecycle handler when the host starts opening.\n */\nexport class StorageMigrationService extends EffectContext.Service<\n StorageMigrationService,\n Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient>\n>()('@dxos/client-services/StorageMigration') {}\n\nexport type ServiceStackServices = ServiceContextRuntimeProps & {\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n connectionLog?: boolean;\n autoConnect?: boolean;\n /**\n * Whether an edge endpoint is configured. An edge feature can be enabled in config without one,\n * so the feature flag alone does not say whether an edge-dependent spec can be built.\n */\n edgeAvailable?: boolean;\n /** Overrides the config-derived signal manager; tests pass an in-memory one. */\n signalManager?: SignalManager;\n /** Overrides the WebRTC transport; tests pass the in-memory transport. */\n transportFactory?: TransportFactory;\n /** Replaces the EDGE inbox; tests share one relay between clients. */\n inboxRelay?: InboxRelay;\n};\n\n/**\n * Attaches the replicator behind `tag`, when one is wired beneath, to the echo host once networking\n * is up. Each replicator registers itself through this; the stack does not enumerate them.\n */\nexport const registerReplicator = <Self>(\n tag: EffectContext.Key<Self, AutomergeReplicator>,\n): Layer.Layer<never, never, EchoHostService | Hook.Controller> =>\n Layer.unwrap(\n Effect.map(Effect.serviceOption(tag), (replicator) =>\n Option.match(replicator, {\n onNone: () => Layer.empty,\n onSome: (replicator) =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n const echoHost = yield* EchoHostService;\n const ctx = yield* EffectEx.contextFromScope();\n yield* Hook.on(\n Events.NetworkReady,\n Effect.fn('EchoHost.addReplicator')(function* () {\n yield* Effect.promise(() => echoHost.addReplicator(ctx, replicator));\n }),\n );\n }),\n ),\n }),\n ),\n );\n\n/**\n * Provides the {@link IdentityProviderService} from the resolved {@link IdentityContract.Manager}.\n */\nexport const identityProviderLayer = Layer.effect(\n IdentityContract.ProviderService,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n return identityProviderFromManager(identityManager);\n }),\n);\n\n/**\n * Combined storage migration effect. Storage migrations are idempotent `CREATE TABLE` effects that\n * do not depend on store instance state, so they are extracted from throwaway instances to keep the\n * store layers individual.\n */\nexport const storageMigrationLayer = Layer.effect(\n StorageMigrationService,\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n return Effect.all(\n [\n new SqliteMetadataStore({ runtime }).migrate,\n new SqliteKeyring({ runtime }).migrate,\n new SqliteStorage.SqliteStorage({ runtime }).migrate,\n ],\n { discard: true },\n );\n }),\n);\n\n/**\n * Opens storage when the host starts opening: migrations, the storage version check, and the SQLite\n * health check run in this order inside one handler, since a `serial` event would order them by\n * subscription instead.\n */\nexport const storageLifecycleLayer = Layer.effectDiscard(\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n const migrate = yield* StorageMigrationService;\n const metadataStore = yield* IMetadataStoreService;\n yield* Hook.on(\n Events.Opening,\n Effect.fn('Storage.onOpening')(function* () {\n log('running storage migrations...');\n yield* Effect.promise(() => RuntimeProvider.runPromise(runtime)(migrate));\n yield* Effect.promise(() => metadataStore.load());\n if (metadataStore.version !== STORAGE_VERSION) {\n // TODO(mykola): Migrate storage to a new version if incompatibility is detected.\n throw new InvalidStorageVersionError(STORAGE_VERSION, metadataStore.version);\n }\n log('running sqlite health check...');\n yield* Effect.promise(() => runSqliteHealthCheck(runtime));\n log('storage ready');\n yield* Hook.emit(Events.StorageReady, undefined);\n }),\n );\n }),\n);\n\n/**\n * Constructs the {@link EchoHost}, resolving the identity/space callbacks that point down the stack.\n * The feed sync handlers (which point up) are wired later via `EchoHost.setFeedSyncHandlers`.\n *\n * The host is self-contained (runs its own migrations, owns its feed/automerge stores), so its\n * open/close is owned by the layer scope: it opens when the stack is built and closes when the\n * runtime is disposed. Identity-, network-, and storage-bound lifecycle is driven by the events.\n */\nexport const echoHostLayer = (options: { useSubduction?: boolean; queryExecutor?: QueryExecutorMode }) =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n const echoHost = yield* EchoHostService;\n yield* Effect.acquireRelease(\n Effect.promise(() => echoHost.open()),\n () => Effect.promise(() => echoHost.close()),\n );\n\n // Points back down the stack, like the feed sync handlers above: the identity manager anchors\n // the HALO space on a root document and needs the open host to do it.\n const identityManager = yield* IdentityContract.ManagerService;\n yield* Effect.promise(() => identityManager.setEchoHost(echoHost));\n }),\n ).pipe(\n Layer.provideMerge(\n Layer.unwrap(\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const spaceManager = yield* SpaceManagerService;\n return EchoHostLayer({\n peerIdProvider: () => identityManager.identity?.deviceKey?.toHex(),\n getSpaceKeyByRootDocumentId: (documentId) => spaceManager.findSpaceByRootDocumentId(documentId)?.key,\n useSubduction: options.useSubduction,\n queryExecutor: options.queryExecutor,\n });\n }),\n ),\n ),\n );\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as SqlClient from 'effect/sql/SqlClient';\n\nimport { RegisterService } from '@dxos/client-protocol';\nimport * as LayerSpec from '@dxos/compute/LayerSpec';\nimport { ConfigService, resolveTelemetryTag } from '@dxos/config';\nimport {\n EchoEdgeSubductionReplicatorLayer,\n EchoHostService,\n EdgeAutomergeReplicatorService,\n MeshEchoReplicatorLayer,\n MeshEchoReplicatorService,\n} from '@dxos/echo-host';\nimport {\n EdgeClient,\n EdgeConnectionService,\n EdgeHttpClient,\n EdgeHttpClientService,\n createStubEdgeIdentity,\n} from '@dxos/edge-client';\nimport * as Hook from '@dxos/effect/Hook';\nimport {\n HypercoreFactoryLayer,\n HypercoreFactoryService,\n HypercoreStorageDirectoryService,\n HypercoreStoreLayer,\n HypercoreStoreService,\n} from '@dxos/feed-store';\nimport { KeyringApiService, SqliteKeyringLayer } from '@dxos/keyring';\nimport {\n EdgeSignalManager,\n MemorySignalManager,\n MemorySignalManagerContext,\n SignalManagerService,\n} from '@dxos/messaging';\nimport { SwarmNetworkManagerService, createIceProvider, createRtcTransportFactory } from '@dxos/network-manager';\nimport { FeedProtocol } from '@dxos/protocols';\nimport {\n ContactsService,\n DataService,\n DevicesService,\n DevtoolsHost,\n EdgeAgentService,\n FeedService,\n IdentityService,\n InboxService,\n InvitationsService,\n LoggingService,\n NetworkService,\n QueryService,\n SpacesService,\n SqlService,\n SystemService,\n} from '@dxos/protocols/rpc';\nimport { RpcRouter } from '@dxos/rpc';\nimport * as SqlExport from '@dxos/sql-sqlite/SqlExport';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as InvitationsContract from '../../contracts/invitations.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Readiness from '../../Readiness.ts';\nimport * as SqliteStorage from '../../SqliteStorage.ts';\nimport { EdgeAgentManagerLayer, EdgeAgentManagerService, EdgeAgentServiceLayer } from '../agents/index.ts';\nimport { DevicesServiceLayer } from '../devices/index.ts';\nimport { DevtoolsHostLayer, DevtoolsHostService } from '../devtools/index.ts';\nimport {\n EdgeIdentityRecoveryManagerLayer,\n EdgeIdentityRecoveryManagerService,\n} from '../identity/identity-recovery-manager.ts';\nimport {\n ContactsServiceLayer,\n IdentityLifecycleLayer,\n IdentityManagerLayer,\n IdentityServiceLayer,\n InboxServiceLayer,\n} from '../identity/index.ts';\nimport {\n InvitationFactoriesLayer,\n InvitationsHandlerLayer,\n InvitationsHandlerService,\n InvitationsManagerLayer,\n InvitationsServiceLayer,\n} from '../invitations/index.ts';\nimport { LoggingServiceLayer } from '../logging/index.ts';\nimport { IMetadataStoreService, SqliteMetadataStoreLayer } from '../metadata/index.ts';\nimport { NetworkServiceLayer } from '../network/index.ts';\nimport { valueEncoding } from '../pipeline/index.ts';\nimport { SpaceManagerLayer, SpaceManagerService } from '../space/index.ts';\nimport { DataSpaceManagerLayer, SigningContextProviderLayer, SpacesServiceLayer } from '../spaces/index.ts';\nimport { SqlServiceLayer } from '../sql/index.ts';\nimport { SystemServiceLayer } from '../system/index.ts';\nimport { TransportFactoryService } from './client-platform.ts';\nimport {\n CrossDeviceSpaceSynchronizerLayer,\n CrossDeviceSpaceSynchronizerService,\n} from './cross-device-space-synchronizer.ts';\nimport { FeedSyncerLayer, FeedSyncerService } from './feed-syncer.ts';\nimport { NetworkLifecycleLayer, SwarmNetworkManagerLayer } from './network-lifecycle.ts';\nimport {\n type ServiceStackServices,\n StorageMigrationService,\n echoHostLayer,\n identityProviderLayer,\n registerReplicator,\n storageLifecycleLayer,\n storageMigrationLayer,\n} from './service-stack.ts';\n\n/**\n * Subduction needs the edge clients as well as the feature flag: the flag is set in config profiles\n * that configure no edge endpoint, and requiring a tag nothing provides would prune the specs that\n * declare it — silently taking the data space manager, and every service built on it, with them.\n */\nconst subductionEnabled = (options: ServiceStackServices): boolean =>\n !!options.edgeFeatures?.subductionReplicator && !!options.edgeAvailable;\n\n/**\n * The client stack as a list of {@link LayerSpec.LayerSpec}s for a `LayerStack` to aggregate: each\n * spec declares the tags it needs and the tags it provides, so build order — and which specs are\n * built at all — follows from the graph rather than from a hand-written `provideMerge` chain.\n *\n * Two conventions carry the behaviour the chain used to encode:\n *\n * - A spec whose point is a side effect provides no tag for anyone to request (a lifecycle\n * subscription, an rpc registration, a replicator attaching itself to the echo host), so it is\n * `eager`.\n * - Anything conditional is conditional *within* a spec: a spec that needs the edge requires the\n * edge tags, which the embedder supplies ambiently only with an endpoint configured, and an\n * unsatisfied requirement prunes the spec. Option-driven choices (p2p replication, subduction)\n * are made inside the spec body.\n *\n * The embedder supplies {@link ConfigService}, {@link Hook.Controller}, the SQL services, the\n * platform inputs and — when configured — the edge clients as the stack's ambient services.\n */\n/**\n * The client stack as {@link LayerSpec.LayerSpec}s for a `LayerStack` to aggregate: each spec\n * declares the tags it needs and the tags it provides, so build order — and which specs are built at\n * all — follows from the graph rather than from a hand-written `provideMerge` chain.\n *\n * Two conventions carry the behaviour the chain used to encode:\n *\n * - A spec whose point is a side effect provides no tag for anyone to request (a lifecycle\n * subscription, an rpc registration, a replicator attaching itself to the echo host), so it is\n * `eager`.\n * - Anything conditional is conditional *within* a spec: a spec that needs the edge requires the\n * edge tags, which the embedder supplies ambiently only with an endpoint configured, and an\n * unsatisfied requirement prunes the spec. Option-driven choices (p2p replication, subduction)\n * pick which specs {@link clientServiceSpecs} returns.\n *\n * The embedder supplies {@link ConfigService}, {@link Hook.Controller}, the SQL services, the\n * platform inputs and — when configured — the edge clients as the stack's ambient services.\n */\n\n//\n// Platform inputs. These were a layer the embedder provided beneath the stack; as specs the edge\n// clients are conditional like any other spec rather than an ambient service that may or may not be\n// there, which is what lets the stack declare its ambient requirements as tags.\n//\n\n/** Only included with a configured endpoint, so the tags exist exactly when the clients do. */\nexport const EdgeClientsSpec = LayerSpec.make(\n { affinity: 'application', requires: [ConfigService], provides: [EdgeConnectionService, EdgeHttpClientService] },\n () =>\n Layer.unwrap(\n Effect.gen(function* () {\n const config = yield* ConfigService;\n const endpoint = config.get('runtime.services.edge.url')!;\n const clientTag = resolveTelemetryTag(config);\n return Layer.mergeAll(\n // Dialing is driven by `NetworkingEnabled` rather than open, so boot RPCs are not competing\n // with the outbound connection.\n Layer.sync(\n EdgeConnectionService,\n () => new EdgeClient(createStubEdgeIdentity(), { socketEndpoint: endpoint, clientTag, deferConnect: true }),\n ),\n Layer.sync(EdgeHttpClientService, () => new EdgeHttpClient(endpoint, { clientTag })),\n );\n }),\n ),\n);\n\nexport const SignalManagerSpec = (options: ServiceStackServices) => {\n const signalManager = options.signalManager;\n if (signalManager) {\n return LayerSpec.make({ affinity: 'application', requires: [], provides: [SignalManagerService] }, () =>\n Layer.succeed(SignalManagerService, signalManager),\n );\n }\n // Edge is the only real signaling transport; without it there is no cross-process signaling, so\n // the spec takes the edge connection exactly when one will exist.\n const edgeSignaling = !!options.edgeFeatures?.signaling && !!options.edgeAvailable;\n return LayerSpec.make(\n {\n affinity: 'application',\n requires: edgeSignaling ? [EdgeConnectionService] : [],\n provides: [SignalManagerService],\n },\n () =>\n edgeSignaling\n ? Layer.effect(\n SignalManagerService,\n Effect.map(EdgeConnectionService, (edgeConnection) => new EdgeSignalManager({ edgeConnection })),\n )\n : Layer.sync(SignalManagerService, () => new MemorySignalManager(new MemorySignalManagerContext())),\n );\n};\n\nexport const TransportFactorySpec = (options: ServiceStackServices) => {\n const transportFactory = options.transportFactory;\n if (transportFactory) {\n return LayerSpec.make({ affinity: 'application', requires: [], provides: [TransportFactoryService] }, () =>\n Layer.succeed(TransportFactoryService, transportFactory),\n );\n }\n return LayerSpec.make(\n { affinity: 'application', requires: [ConfigService], provides: [TransportFactoryService] },\n () =>\n Layer.effect(\n TransportFactoryService,\n Effect.gen(function* () {\n const config = yield* ConfigService;\n const iceProviders = config.get('runtime.services.iceProviders');\n return createRtcTransportFactory(\n { iceServers: config.get('runtime.services.ice') },\n iceProviders && createIceProvider(iceProviders),\n );\n }),\n ),\n );\n};\n\n//\n// Storage.\n//\n\nexport const SqliteStorageSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [SqliteStorage.SqliteStorageService] },\n () => SqliteStorage.SqliteStorageLayer(),\n);\n\nexport const HypercoreStorageDirectorySpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [SqliteStorage.SqliteStorageService],\n provides: [HypercoreStorageDirectoryService],\n },\n () => SqliteStorage.HypercoreStorageDirectoryLayer(),\n);\n\nexport const KeyringSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [KeyringApiService] },\n () => SqliteKeyringLayer(),\n);\n\nexport const MetadataStoreSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [IMetadataStoreService] },\n () => SqliteMetadataStoreLayer(),\n);\n\nexport const HypercoreFactorySpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [KeyringApiService, HypercoreStorageDirectoryService],\n provides: [HypercoreFactoryService],\n },\n () => HypercoreFactoryLayer({ hypercore: { valueEncoding, stats: true } }),\n);\n\nexport const HypercoreStoreSpec = LayerSpec.make(\n { affinity: 'application', requires: [HypercoreFactoryService], provides: [HypercoreStoreService] },\n () => HypercoreStoreLayer(),\n);\n\nexport const StorageMigrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [StorageMigrationService] },\n () => storageMigrationLayer,\n);\n\nexport const StorageLifecycleSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [SqlClient.SqlClient, StorageMigrationService, IMetadataStoreService, Hook.Controller],\n provides: [],\n eager: true,\n },\n () => storageLifecycleLayer,\n);\n\n//\n// Network.\n//\n\nexport const StackReadinessSpec = LayerSpec.make(\n { affinity: 'application', requires: [Hook.Controller], provides: [Readiness.StackReadinessService] },\n () => Readiness.StackReadinessLayer,\n);\n\nexport const SwarmNetworkManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [SignalManagerService, TransportFactoryService],\n provides: [SwarmNetworkManagerService],\n },\n () => SwarmNetworkManagerLayer({ connectionLog: options.connectionLog }),\n );\n\nexport const NetworkLifecycleSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, SwarmNetworkManagerService, IdentityContract.ManagerService, SignalManagerService],\n provides: [],\n eager: true,\n },\n () => NetworkLifecycleLayer({ autoConnect: options.autoConnect }),\n );\n\n//\n// Identity and spaces.\n//\n\nexport const SpaceManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, HypercoreStoreService, SwarmNetworkManagerService, IMetadataStoreService],\n provides: [SpaceManagerService],\n },\n () => SpaceManagerLayer({ disableP2pReplication: options.disableP2pReplication }),\n );\n\nexport const IdentityManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, IMetadataStoreService, KeyringApiService, HypercoreStoreService, SpaceManagerService],\n provides: [IdentityContract.ManagerService],\n },\n () =>\n IdentityManagerLayer({\n devicePresenceOfflineTimeout: options.devicePresenceOfflineTimeout,\n devicePresenceAnnounceInterval: options.devicePresenceAnnounceInterval,\n edgeFeatures: options.edgeFeatures,\n automergeCredentials: options.automergeCredentials,\n }),\n );\n\nexport const IdentityProviderSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [IdentityContract.ManagerService],\n provides: [IdentityContract.ProviderService],\n },\n () => identityProviderLayer,\n);\n\nexport const EdgeIdentityRecoverySpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [KeyringApiService, IdentityContract.ManagerService],\n provides: [EdgeIdentityRecoveryManagerService],\n },\n () => EdgeIdentityRecoveryManagerLayer(),\n);\n\nexport const IdentityLifecycleSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, IdentityContract.ManagerService, EdgeIdentityRecoveryManagerService],\n provides: [IdentityContract.LifecycleService],\n },\n () => IdentityLifecycleLayer,\n);\n\nexport const SigningContextProviderSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [IdentityContract.ProviderService],\n provides: [SpacesContract.SigningContextProviderService],\n },\n () => SigningContextProviderLayer,\n);\n\n// The edge client is required only when configured, so the handler is built after it rather than\n// finding it absent; without it, edge-assisted admission is simply unavailable.\nexport const InvitationsHandlerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [SwarmNetworkManagerService, ...(options.edgeAvailable ? [EdgeHttpClientService] : [])],\n provides: [InvitationsHandlerService],\n },\n () => InvitationsHandlerLayer({ connectionProps: options.invitationConnectionDefaultProps }),\n );\n\nexport const InvitationsManagerSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, InvitationsHandlerService, IMetadataStoreService],\n provides: [InvitationsContract.ManagerService],\n },\n () => InvitationsManagerLayer(),\n);\n\nexport const EchoHostSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [IdentityContract.ManagerService, SpaceManagerService, SqlClient.SqlClient],\n provides: [EchoHostService],\n },\n () =>\n echoHostLayer({\n useSubduction: options.edgeFeatures?.subductionReplicator,\n queryExecutor: options.queryExecutor,\n }),\n );\n\nexport const DataSpaceManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n Hook.Controller,\n SpaceManagerService,\n IMetadataStoreService,\n KeyringApiService,\n SpacesContract.SigningContextProviderService,\n HypercoreStoreService,\n EchoHostService,\n InvitationsContract.ManagerService,\n // Read with `Effect.serviceOption`, so each is required only where it is also provided.\n ...(options.disableP2pReplication ? [] : [MeshEchoReplicatorService]),\n ...(subductionEnabled(options) ? [EdgeAutomergeReplicatorService] : []),\n ],\n provides: [SpacesContract.ManagerService],\n },\n () => DataSpaceManagerLayer({ runtimeProps: options, edgeFeatures: options.edgeFeatures }),\n );\n\nexport const InvitationFactoriesSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n InvitationsContract.ManagerService,\n IdentityContract.ManagerService,\n IdentityContract.LifecycleService,\n KeyringApiService,\n SpacesContract.ManagerService,\n SpacesContract.SigningContextProviderService,\n ],\n provides: [],\n eager: true,\n },\n () => InvitationFactoriesLayer,\n);\n\n// The edge client is required only when configured, so the manager is built after it rather than\n// finding it absent; without it, it stays dormant (see `EdgeAgentManager._open`).\nexport const EdgeAgentManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n Hook.Controller,\n SpacesContract.ManagerService,\n IdentityContract.ProviderService,\n ...(options.edgeAvailable ? [EdgeHttpClientService] : []),\n ],\n provides: [EdgeAgentManagerService],\n },\n () => EdgeAgentManagerLayer({ edgeFeatures: options.edgeFeatures }),\n );\n\n// Eager: nothing asks for its tag — it exists to subscribe to space changes across devices.\nexport const CrossDeviceSpaceSynchronizerSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, SpacesContract.ManagerService],\n provides: [CrossDeviceSpaceSynchronizerService],\n eager: true,\n },\n () => CrossDeviceSpaceSynchronizerLayer,\n);\n\n//\n// Replication. Each replicator provides its own tag as well as registering itself with the echo\n// host, because `SpacesContract.Manager` reads both tags with `Effect.serviceOption` to decide which\n// replication paths a space gets. The ones that need the edge are pruned without it.\n//\n\nexport const MeshReplicatorSpec = LayerSpec.make(\n { affinity: 'application', requires: [], provides: [MeshEchoReplicatorService] },\n () => MeshEchoReplicatorLayer(),\n);\n\nexport const MeshReplicatorRegistrationSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [MeshEchoReplicatorService, EchoHostService, Hook.Controller],\n provides: [],\n eager: true,\n },\n () => registerReplicator(MeshEchoReplicatorService),\n);\n\nexport const EdgeSubductionReplicatorSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [EdgeConnectionService, EdgeHttpClientService],\n provides: [EdgeAutomergeReplicatorService],\n },\n () => EchoEdgeSubductionReplicatorLayer(),\n);\n\nexport const EdgeSubductionReplicatorRegistrationSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [EdgeAutomergeReplicatorService, EchoHostService, Hook.Controller],\n provides: [],\n eager: true,\n },\n () => registerReplicator(EdgeAutomergeReplicatorService),\n);\n\nexport const FeedSyncerSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, SqlClient.SqlClient, EchoHostService, EdgeConnectionService],\n provides: [FeedSyncerService],\n eager: true,\n },\n () =>\n FeedSyncerLayer({\n peerId: '',\n syncNamespaces: [FeedProtocol.WellKnownNamespaces.data, FeedProtocol.WellKnownNamespaces.trace],\n }),\n);\n\n//\n// RPC services. Each handler keeps its own tag, and its registration with the router is a separate\n// spec — eager, because a registration provides nothing for anyone to ask for.\n//\n\nexport const RpcRouterSpec = LayerSpec.make(\n { affinity: 'application', requires: [], provides: [RpcRouter.RpcRouter] },\n () => RpcRouter.layer,\n);\n\nexport const SystemServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n RpcRouter.RpcRouter,\n ConfigService,\n Hook.Controller,\n IdentityContract.ManagerService,\n SpacesContract.ManagerService,\n SwarmNetworkManagerService,\n ],\n provides: [SystemService.Tag],\n },\n () => SystemServiceLayer,\n);\n\nexport const SystemServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [SystemService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(SystemService.Rpcs, SystemService.Tag),\n);\n\nexport const IdentityServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n Hook.Controller,\n IdentityContract.ManagerService,\n IdentityContract.LifecycleService,\n EdgeIdentityRecoveryManagerService,\n KeyringApiService,\n SpacesContract.ManagerService,\n SqlClient.SqlClient,\n ],\n provides: [IdentityService.Tag],\n },\n () => IdentityServiceLayer,\n);\n\nexport const IdentityServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [IdentityService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(IdentityService.Rpcs, IdentityService.Tag),\n);\n\nexport const ContactsServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n IdentityContract.ManagerService,\n SpaceManagerService,\n SpacesContract.ManagerService,\n Readiness.StackReadinessService,\n ],\n provides: [ContactsService.Tag],\n },\n () => ContactsServiceLayer,\n);\n\nexport const ContactsServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [ContactsService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(ContactsService.Rpcs, ContactsService.Tag),\n);\n\n// The edge tags are required only when configured, so the service is built after them rather than\n// finding them absent; without them (and without a test relay) it still serves an empty inbox.\nexport const InboxServiceSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n IdentityContract.ManagerService,\n ...(options.edgeAvailable && !options.inboxRelay ? [EdgeHttpClientService, EdgeConnectionService] : []),\n ],\n provides: [InboxService.Tag],\n },\n () => InboxServiceLayer({ relay: options.inboxRelay }),\n );\n\nexport const InboxServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [InboxService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(InboxService.Rpcs, InboxService.Tag),\n);\n\nexport const InvitationsServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [InvitationsContract.ManagerService], provides: [InvitationsService.Tag] },\n () => InvitationsServiceLayer,\n);\n\nexport const InvitationsServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [InvitationsService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(InvitationsService.Rpcs, InvitationsService.Tag),\n);\n\nexport const DevicesServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [IdentityContract.ManagerService], provides: [DevicesService.Tag] },\n () => DevicesServiceLayer,\n);\n\nexport const DevicesServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [DevicesService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(DevicesService.Rpcs, DevicesService.Tag),\n);\n\nexport const SpacesServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n IdentityContract.ManagerService,\n SpaceManagerService,\n EchoHostService,\n SpacesContract.ManagerService,\n Readiness.StackReadinessService,\n ],\n provides: [SpacesService.Tag],\n },\n () => SpacesServiceLayer,\n);\n\nexport const SpacesServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [SpacesService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(SpacesService.Rpcs, SpacesService.Tag),\n);\n\nexport const NetworkServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [SwarmNetworkManagerService, SignalManagerService],\n provides: [NetworkService.Tag],\n },\n () => NetworkServiceLayer,\n);\n\nexport const NetworkServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [NetworkService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(NetworkService.Rpcs, NetworkService.Tag),\n);\n\nexport const EdgeAgentServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [EdgeAgentManagerService, Readiness.StackReadinessService],\n provides: [EdgeAgentService.Tag],\n },\n () => EdgeAgentServiceLayer,\n);\n\nexport const EdgeAgentServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [EdgeAgentService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(EdgeAgentService.Rpcs, EdgeAgentService.Tag),\n);\n\n//\n// Data, query and feed: thin projections of the echo host rather than package-local impls.\n//\n\nexport const DataServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [EchoHostService], provides: [DataService.Tag] },\n () =>\n Layer.effect(\n DataService.Tag,\n Effect.map(EchoHostService, (echoHost) => echoHost.dataService),\n ),\n);\n\nexport const DataServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [DataService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(DataService.Rpcs, DataService.Tag),\n);\n\nexport const QueryServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [EchoHostService], provides: [QueryService.Tag] },\n () =>\n Layer.effect(\n QueryService.Tag,\n Effect.map(EchoHostService, (echoHost) => echoHost.queryService),\n ),\n);\n\nexport const QueryServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [QueryService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(QueryService.Rpcs, QueryService.Tag),\n);\n\nexport const FeedServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [EchoHostService], provides: [FeedService.Tag] },\n () =>\n Layer.effect(\n FeedService.Tag,\n Effect.map(EchoHostService, (echoHost) => echoHost.feedService),\n ),\n);\n\nexport const FeedServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [FeedService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(FeedService.Rpcs, FeedService.Tag),\n);\n\nexport const LoggingServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [], provides: [LoggingService.Tag] },\n () => LoggingServiceLayer,\n);\n\nexport const LoggingServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [LoggingService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(LoggingService.Rpcs, LoggingService.Tag),\n);\n\nexport const DevtoolsHostSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n ConfigService,\n KeyringApiService,\n HypercoreStoreService,\n SpaceManagerService,\n IMetadataStoreService,\n SpacesContract.ManagerService,\n Readiness.StackReadinessService,\n SignalManagerService,\n SwarmNetworkManagerService,\n SqlClient.SqlClient,\n SqlExport.SqlExport,\n ],\n provides: [DevtoolsHost.Tag, DevtoolsHostService],\n },\n () => DevtoolsHostLayer,\n);\n\nexport const SqlServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [SqlService.Tag] },\n () => SqlServiceLayer,\n);\n\nexport const SqlServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(SqlService.Rpcs, SqlService.Tag),\n);\n\nexport const DevtoolsHostRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [DevtoolsHost.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(DevtoolsHost.Rpcs, DevtoolsHost.Tag),\n);\n\n/**\n * Every spec the client stack is built from, with the option-driven ones applied.\n */\nexport const clientServiceSpecs = (options: ServiceStackServices): LayerSpec.LayerSpec[] => [\n ...(options.edgeAvailable ? [EdgeClientsSpec] : []),\n SignalManagerSpec(options),\n TransportFactorySpec(options),\n\n SqliteStorageSpec,\n HypercoreStorageDirectorySpec,\n KeyringSpec,\n MetadataStoreSpec,\n HypercoreFactorySpec,\n HypercoreStoreSpec,\n StorageMigrationSpec,\n StorageLifecycleSpec,\n\n StackReadinessSpec,\n SwarmNetworkManagerSpec(options),\n NetworkLifecycleSpec(options),\n\n SpaceManagerSpec(options),\n IdentityManagerSpec(options),\n IdentityProviderSpec,\n EdgeIdentityRecoverySpec,\n IdentityLifecycleSpec,\n SigningContextProviderSpec,\n InvitationsHandlerSpec(options),\n InvitationsManagerSpec,\n EchoHostSpec(options),\n DataSpaceManagerSpec(options),\n InvitationFactoriesSpec,\n EdgeAgentManagerSpec(options),\n CrossDeviceSpaceSynchronizerSpec,\n\n ...(options.disableP2pReplication ? [] : [MeshReplicatorSpec, MeshReplicatorRegistrationSpec]),\n ...(subductionEnabled(options) ? [EdgeSubductionReplicatorSpec, EdgeSubductionReplicatorRegistrationSpec] : []),\n FeedSyncerSpec,\n\n RpcRouterSpec,\n SystemServiceSpec,\n SystemServiceRegistrationSpec,\n IdentityServiceSpec,\n IdentityServiceRegistrationSpec,\n ContactsServiceSpec,\n ContactsServiceRegistrationSpec,\n InboxServiceSpec(options),\n InboxServiceRegistrationSpec,\n InvitationsServiceSpec,\n InvitationsServiceRegistrationSpec,\n DevicesServiceSpec,\n DevicesServiceRegistrationSpec,\n SpacesServiceSpec,\n SpacesServiceRegistrationSpec,\n NetworkServiceSpec,\n NetworkServiceRegistrationSpec,\n EdgeAgentServiceSpec,\n EdgeAgentServiceRegistrationSpec,\n DataServiceSpec,\n DataServiceRegistrationSpec,\n QueryServiceSpec,\n QueryServiceRegistrationSpec,\n FeedServiceSpec,\n FeedServiceRegistrationSpec,\n LoggingServiceSpec,\n LoggingServiceRegistrationSpec,\n SqlServiceSpec,\n SqlServiceRegistrationSpec,\n DevtoolsHostSpec,\n DevtoolsHostRegistrationSpec,\n];\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as SqlClient from 'effect/sql/SqlClient';\n\nimport { LayerStack } from '@dxos/compute-runtime';\nimport * as ServiceResolver from '@dxos/compute/ServiceResolver';\nimport { type Config, ConfigService } from '@dxos/config';\nimport { type QueryExecutorMode } from '@dxos/echo-host';\nimport * as Hook from '@dxos/effect/Hook';\nimport { type SignalManager } from '@dxos/messaging';\nimport { type TransportFactory } from '@dxos/network-manager';\nimport { Runtime_Client_QueryExecutor } from '@dxos/protocols/buf/dxos/config_pb';\nimport * as SqlExport from '@dxos/sql-sqlite/SqlExport';\n\nimport * as Events from '../../Events.ts';\nimport { type InboxRelay } from '../identity/index.ts';\nimport { clientServiceSpecs } from './layer-specs.ts';\nimport { type ServiceContextRuntimeProps } from './service-stack.ts';\n\n/** The SQL services the stack persists through; the embedder provides them beneath it. */\nexport type ClientServicesSqlContext = SqlClient.SqlClient | SqlExport.SqlExport;\n\n/** Everything the stack resolves against rather than building itself. */\nconst AMBIENT_SERVICES = [ConfigService, Hook.Controller, SqlClient.SqlClient, SqlExport.SqlExport] as const;\n\nexport type ClientServicesStackOptions = {\n /** Overrides for the config-derived runtime props. */\n runtimeProps?: ServiceContextRuntimeProps;\n /** Overrides the config-derived signal manager; tests pass an in-memory one. */\n signalManager?: SignalManager;\n /** Overrides the WebRTC transport; tests pass the in-memory transport. */\n transportFactory?: TransportFactory;\n /** Replaces the EDGE inbox; tests share one relay between clients. */\n inboxRelay?: InboxRelay;\n /** @default true */\n connectionLog?: boolean;\n /**\n * Emit `NetworkingEnabled` as soon as the stack is open. Set `false` when the embedder decides\n * when connecting is safe, as the worker does so the dial cannot compete with boot RPCs.\n * @default true\n */\n autoConnect?: boolean;\n};\n\n/**\n * The configured query evaluation path, if any. `EchoHost` falls back to `DX_ECHO_QUERY_EXECUTOR`\n * and then to the compiled SQL executor, so an unset field stays undefined rather than defaulting\n * here — one default, at the point the option enters the host.\n */\nconst queryExecutorFromConfig = (config: Config): QueryExecutorMode | undefined => {\n switch (config.get('runtime.client.queryExecutor')) {\n case Runtime_Client_QueryExecutor.SQL:\n return 'sql';\n case Runtime_Client_QueryExecutor.MEMORY:\n return 'memory';\n default:\n return undefined;\n }\n};\n\n/**\n * Runtime props from config, with explicit overrides winning where defined.\n */\nexport const runtimePropsFromConfig = (\n config: Config,\n overrides: ServiceContextRuntimeProps = {},\n): ServiceContextRuntimeProps => ({\n disableP2pReplication: config.get('runtime.client.disableP2pReplication', false),\n enableVectorIndexing: config.get('runtime.client.enableVectorIndexing', false),\n queryExecutor: queryExecutorFromConfig(config),\n automergeCredentials: config.get('runtime.client.automergeCredentials', false),\n ...Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== undefined)),\n});\n\n/**\n * The client services stack: the {@link clientServiceSpecs} graph aggregated by a {@link LayerStack},\n * over the ambient services the embedder provides beneath it.\n *\n * Specs are built on demand — resolving a tag builds what that tag needs and nothing else — except\n * the `eager` ones (rpc registrations, lifecycle subscriptions, replicators), which this layer builds\n * as it is created, since nothing would ever ask for them. Reach a service with\n * `ServiceResolver.resolve`, which this layer provides alongside the stack; emit `Opening` and\n * `StackOpened` to boot the components, and closing the layer's scope tears everything down.\n */\nexport const layerClientServices = (\n options: ClientServicesStackOptions = {},\n): Layer.Layer<\n LayerStack.Service | ServiceResolver.ServiceResolver,\n never,\n ClientServicesSqlContext | ConfigService | Hook.Controller\n> => layerBuildEagerSpecs.pipe(Layer.provideMerge(layerSpecsFromConfig(options)));\n\n/**\n * Allows outbound network activity to begin; for embedders that build the stack with\n * `autoConnect: false`.\n */\nexport const enableNetworking: Effect.Effect<void, never, Hook.Controller> = Hook.emit(\n Events.NetworkingEnabled,\n undefined,\n);\n\n/**\n * The stack itself. Config decides which specs the graph has, so the layer is unwrapped from an\n * effect that reads it.\n */\nconst layerSpecsFromConfig = (\n options: ClientServicesStackOptions,\n): Layer.Layer<\n LayerStack.Service | ServiceResolver.ServiceResolver,\n never,\n ClientServicesSqlContext | ConfigService | Hook.Controller\n> =>\n Layer.unwrap(\n Effect.gen(function* () {\n const config = yield* ConfigService;\n return LayerStack.layer({\n layers: clientServiceSpecs({\n ...runtimePropsFromConfig(config, options.runtimeProps),\n edgeFeatures: config.get('runtime.client.edgeFeatures'),\n edgeAvailable: !!config.get('runtime.services.edge.url'),\n signalManager: options.signalManager,\n transportFactory: options.transportFactory,\n inboxRelay: options.inboxRelay,\n connectionLog: options.connectionLog ?? true,\n autoConnect: options.autoConnect ?? true,\n }),\n services: AMBIENT_SERVICES,\n });\n }),\n );\n\n/**\n * A spec that only registers an rpc service or subscribes to a lifecycle event provides no tag for\n * anyone to resolve, so the graph stays dormant until its slice is initialized.\n */\nconst layerBuildEagerSpecs: Layer.Layer<never, never, LayerStack.Service> = Layer.effectDiscard(\n Effect.gen(function* () {\n const stack = yield* LayerStack.Service;\n yield* stack.init().pipe(Effect.orDie);\n }),\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chunk-client-services-stack.mjs","names":[],"sources":["../../src/contracts/identity.ts","../../src/contracts/spaces.ts","../../src/Events.ts","../../src/internal/agents/edge-agent-manager.ts","../../src/Readiness.ts","../../src/internal/agents/edge-agent-service.ts","../../src/contracts/invitations.ts","../../src/Auth.ts","../../src/CredentialsDocument.ts","../../src/internal/metadata/metadata-store.ts","../../src/migrations/metadata/index.ts","../../src/internal/metadata/sqlite-metadata-store.ts","../../src/internal/space/auth.ts","../../src/internal/pipeline/feeds.ts","../../src/internal/pipeline/message-selector.ts","../../src/internal/pipeline/timeframe-clock.ts","../../src/internal/pipeline/pipeline.ts","../../src/internal/pipeline/codec.ts","../../src/internal/space/control-pipeline.ts","../../src/internal/space/space.ts","../../src/internal/space/admission-discovery-extension.ts","../../src/internal/space/space-protocol.ts","../../src/internal/space/space-manager.ts","../../src/internal/devtools/feeds.ts","../../src/internal/devtools/keys.ts","../../src/internal/devtools/metadata.ts","../../src/internal/devtools/network.ts","../../src/internal/devtools/spaces.ts","../../src/internal/devtools/devtools.ts","../../src/PlatformInfo.ts","../../src/version.ts","../../src/internal/diagnostics/diagnostics.ts","../../src/Replication.ts","../../src/Identity.ts","../../src/internal/identity/contacts-service.ts","../../src/internal/identity/identity-recovery-manager.ts","../../src/internal/identity/identity-lifecycle.ts","../../src/internal/identity/identity-manager.ts","../../src/migrations/hypercore/index.ts","../../src/SqliteStorage.ts","../../src/internal/identity/identity-service.ts","../../src/internal/identity/inbox-service.ts","../../src/internal/invitations/device-invitation-protocol.ts","../../src/internal/invitations/utils.ts","../../src/internal/invitations/space-invitation-protocol.ts","../../src/internal/invitations/invitation-factories.ts","../../src/internal/invitations/edge-invitation-handler.ts","../../src/internal/invitations/invitation-guest-extenstion.ts","../../src/internal/invitations/invitation-host-extension.ts","../../src/internal/invitations/invitation-state.ts","../../src/internal/invitations/invitation-topology.ts","../../src/internal/invitations/invitations-handler.ts","../../src/internal/invitations/invitations-service.ts","../../src/internal/invitations/invitations-manager.ts","../../src/internal/services/client-platform.ts","../../src/internal/devices/devices-service.ts","../../src/internal/logging/logging-service.ts","../../src/internal/network/network-service.ts","../../src/internal/spaces/automerge-space-state.ts","../../src/internal/spaces/epoch-migrations.ts","../../src/internal/spaces/notarization-plugin.ts","../../src/internal/spaces/data-space.ts","../../src/internal/spaces/genesis.ts","../../src/internal/spaces/data-space-manager.ts","../../src/internal/space-export/archive-format.ts","../../src/internal/space-export/serialized-space-reader.ts","../../src/internal/space-export/serialized-space-writer.ts","../../src/internal/space-export/space-archive-reader.ts","../../src/internal/space-export/space-archive-writer.ts","../../src/internal/spaces/spaces-service.ts","../../src/internal/sql/sql-service.ts","../../src/internal/system/system-service.ts","../../src/internal/services/cross-device-space-synchronizer.ts","../../src/internal/services/feed-syncer.ts","../../src/internal/services/network-lifecycle.ts","../../src/internal/services/service-stack.ts","../../src/internal/services/layer-specs.ts","../../src/internal/services/client-services-stack.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\n\nimport { type Event } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { type EchoHost } from '@dxos/echo-host';\nimport { type PublicKey } from '@dxos/keys';\nimport { type Device } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type IdentityRecord } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport {\n type Credential,\n type DeviceProfileDocument,\n type ProfileDocument,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type Timeframe } from '@dxos/timeframe';\n\nimport { type Identity } from '../Identity.ts';\n\n//\n// The identity subsystem's contract: the interfaces its consumers depend on and the tags that carry\n// them. Nothing here imports an implementation, so depending on the contract cannot drag one in —\n// which a tag typed against an implementation class silently does, even through a type-only import.\n//\n\nexport type JoinIdentityProps = {\n identityKey: PublicKey;\n deviceKey: PublicKey;\n haloSpaceKey: PublicKey;\n haloGenesisFeedKey: PublicKey;\n controlFeedKey: PublicKey;\n dataFeedKey: PublicKey;\n authorizedDeviceCredential: Credential;\n /**\n * Automerge URL of the host's halo space root, when it has one. The joining device adopts it rather\n * than minting a second root over the same space.\n */\n haloSpaceRootUrl?: string;\n /**\n * Latest known timeframe for the control pipeline.\n * We will try to catch up to this timeframe before starting the data pipeline.\n */\n controlTimeframe?: Timeframe;\n /** Custom device profile, merged with defaults, applied once the identity is accepted. */\n deviceProfile?: DeviceProfileDocument;\n};\n\nexport type CreateIdentityOptions = {\n profile?: ProfileDocument;\n /** Device profile for the device creating the identity. */\n deviceProfile?: DeviceProfileDocument;\n};\n\n/**\n * The peer's identity state machine, as its consumers use it.\n */\nexport interface Manager {\n readonly stateUpdate: Event;\n readonly identity: Identity | undefined;\n open(ctx: Context): Promise<void>;\n close(ctx: Context): Promise<void>;\n deleteIdentity(ctx: Context): Promise<void>;\n updateProfile(profile: ProfileDocument): Promise<ProfileDocument>;\n updateDeviceProfile(profile: DeviceProfileDocument): Promise<Device>;\n setEchoHost(echoHost: EchoHost): Promise<void>;\n createIdentity(options?: CreateIdentityOptions, ctx?: Context): Promise<Identity>;\n prepareIdentity(\n params: JoinIdentityProps,\n ctx?: Context,\n ): Promise<{ identity: Identity; identityRecord: IdentityRecord }>;\n acceptIdentity(identity: Identity, identityRecord: IdentityRecord, profile?: DeviceProfileDocument): Promise<void>;\n}\n\n/**\n * Resolves the active identity when it becomes available.\n */\nexport type Provider = () => Identity;\n\n/**\n * Brings a new identity into the running stack: binds it to the network, joins, and announces it so\n * the identity-bound services open. The persisted identity on boot goes through the same events\n * from the host's open sequence.\n */\nexport interface Lifecycle {\n /** Creates a fresh identity and resolves once its identity-bound services are open. */\n createIdentity(params?: CreateIdentityOptions, ctx?: Context): Promise<Identity>;\n /** Adopts an identity admitted by another device and resolves once its services are open. */\n acceptIdentity(params: JoinIdentityProps): Promise<Identity>;\n}\n\n/** Effect service tag for {@link Manager}. */\nexport class ManagerService extends EffectContext.Service<ManagerService, Manager>()(\n '@dxos/client-services/IdentityManager',\n) {}\n\n/** Effect service tag for {@link Provider}. */\nexport class ProviderService extends EffectContext.Service<ProviderService, Provider>()(\n '@dxos/client-services/IdentityProvider',\n) {}\n\n/** Effect service tag for {@link Lifecycle}. */\nexport class LifecycleService extends EffectContext.Service<LifecycleService, Lifecycle>()(\n '@dxos/client-services/IdentityLifecycle',\n) {}\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type AutomergeUrl, type DocumentId } from '@automerge/automerge-repo';\nimport * as EffectContext from 'effect/Context';\n\nimport { type Event } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { type CredentialSigner } from '@dxos/credentials';\nimport { type SpaceRootRefs } from '@dxos/echo-host';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { type EdgeReplicationSetting } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport {\n type Credential,\n type MembershipPolicy,\n type ProfileDocument,\n type SpaceMember_Role,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type Timeframe } from '@dxos/timeframe';\nimport { type ComplexMap } from '@dxos/util';\n\n// The manager is a service, so it gets an interface; `DataSpace` is an aggregate its consumers use\n// as a rich object, so an interface over it would duplicate the class rather than abstract it.\n// `DataSpace` is an aggregate its consumers use as a rich object, so an interface over it would\n// duplicate the class rather than abstract it; it is the one implementation type the contract names.\nimport { type DataSpace } from '../internal/spaces/data-space.ts';\n\n//\n// The data-space subsystem's contract. See `contracts/identity.ts` for why the tags live with the\n// interfaces rather than with the implementations.\n//\n\n/** What a space needs from the identity to sign and record credentials on its behalf. */\nexport interface SigningContext {\n identityKey: PublicKey;\n deviceKey: PublicKey;\n credentialSigner: CredentialSigner;\n recordCredential: (credential: Credential) => Promise<void>;\n getProfile: () => ProfileDocument | undefined;\n}\n\nexport type SigningContextProvider = () => SigningContext;\n\nexport type AcceptSpaceOptions = {\n spaceKey: PublicKey;\n genesisFeedKey: PublicKey;\n\n /** From the admitting `SpaceMember` credential; absent for a space still on its control feed. */\n spaceRootUrl?: string;\n\n /**\n * Latest known timeframe for the control pipeline.\n * We will try to catch up to this timeframe before starting the data pipeline.\n */\n controlTimeframe?: Timeframe;\n\n /**\n * Latest known timeframe for the data pipeline.\n * We will try to catch up to this timeframe before initializing the database.\n */\n dataTimeframe?: Timeframe;\n\n /** Tags assigned to the space member. */\n tags?: string[];\n};\n\nexport type AdmitMemberOptions = {\n spaceKey: PublicKey;\n identityKey: PublicKey;\n role: SpaceMember_Role;\n profile?: ProfileDocument;\n delegationCredentialId?: PublicKey;\n tags?: string[];\n\n /** Successor to `genesisFeedKey`: what lets the admitted member replicate from this credential alone. */\n spaceRootUrl?: string;\n};\n\nexport type CreateSpaceOptions = {\n /**\n * Anchor the space on a space root document, taking its id from that document instead of from the\n * space key. Defaults to the `automergeCredentials` runtime flag, which is off — so a space is\n * key-derived unless the flag opts in. Ignored for an imported space, which brings its own root.\n */\n useSpaceRootDocument?: boolean;\n\n rootUrl?: AutomergeUrl;\n documents?: Record<DocumentId, Uint8Array>;\n tags?: string[];\n membershipPolicy?: MembershipPolicy;\n};\n\n/**\n * The open data spaces, as its consumers use it.\n */\nexport interface Manager {\n readonly updated: Event;\n open(ctx?: Context): Promise<unknown>;\n close(ctx?: Context): Promise<unknown>;\n waitUntilSpaceReady(spaceKey: PublicKey): Promise<void>;\n readonly spaces: ComplexMap<PublicKey, DataSpace>;\n getSpaceById(spaceId: SpaceId): DataSpace | undefined;\n isSpaceDeleted(spaceKey: PublicKey): boolean;\n createSpace(ctx: Context, options?: CreateSpaceOptions): Promise<DataSpace>;\n acceptSpace(ctx: Context, options: AcceptSpaceOptions): Promise<DataSpace>;\n migrateSpaceToRootDocument(ctx: Context, spaceKey: PublicKey): Promise<SpaceRootRefs>;\n markSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void>;\n deleteAllSpaces(ctx: Context): Promise<void>;\n handleRemoteSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void>;\n admitMember(options: AdmitMemberOptions): Promise<Credential>;\n requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential>;\n setSpaceEdgeReplicationSetting(ctx: Context, spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void>;\n}\n\n/** Effect service tag for {@link Manager}. */\nexport class ManagerService extends EffectContext.Service<ManagerService, Manager>()(\n '@dxos/client-services/DataSpaceManager',\n) {}\n\n/** Effect service tag for {@link SigningContextProvider}. */\nexport class SigningContextProviderService extends EffectContext.Service<\n SigningContextProviderService,\n SigningContextProvider\n>()('@dxos/client-services/SigningContextProvider') {}\n","//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Hook from '@dxos/effect/Hook';\nimport { type Credential, type ProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nimport { type Identity } from './Identity.ts';\n\n//\n// Lifecycle events of the client stack. Boot order is the chain of these events, each layer\n// subscribing to the fact it needs and emitting the fact it establishes:\n//\n// Opening → StorageReady → IdentityLoaded → NetworkReady (host emits Opening, then cascades).\n// IdentityBound (a created or accepted identity).\n// IdentityAvailable → DataSpacesAvailable (identity-bound services).\n// StackOpened (host, once the cascade is done).\n// NetworkingEnabled (auto-connect, or the embedder).\n//\n// Teardown has no events: each layer closes its component in its layer finalizer, so runtime\n// disposal unwinds the stack in reverse build order. A reset is the embedder's concern and runs on\n// the embedder's controller, which outlives the stack:\n//\n// Closing → WipingStorage → Reset (system service; the embedder handles).\n//\n// Payloads carry facts only. Cancellation and tracing ride on the Effect: a layer that needs a DXOS\n// `Context` for a component takes one from its scope (`EffectEx.contextFromScope`), and the host\n// emits under its open context (`EffectEx.withContext`) so handler spans nest under it.\n//\n\n/** The host is opening; nothing has been touched yet. */\nexport const Opening = Hook.make<void>()('client-services/Opening');\n\n/** Storage has been migrated, version-checked, and loaded. */\nexport const StorageReady = Hook.make<void>()('client-services/StorageReady');\n\n/** The identity manager is open; `identity` is the persisted identity, if there is one. */\nexport const IdentityLoaded = Hook.make<{ identity?: Identity }>()('client-services/IdentityLoaded');\n\n/** Edge, signaling, and swarm networking are open with the current network identity. */\nexport const NetworkReady = Hook.make<void>()('client-services/NetworkReady');\n\n/**\n * A new identity must be bound to the network before it joins; `deviceCredential` is present when\n * the identity was admitted by another device.\n */\nexport const IdentityBound = Hook.make<{ identity: Identity; deviceCredential?: Credential }>()(\n 'client-services/IdentityBound',\n);\n\n/** An identity has joined the network; identity-bound services may open. */\nexport const IdentityAvailable = Hook.make<{ identity: Identity }>()('client-services/IdentityAvailable');\n\n/** The data space manager is open. */\nexport const DataSpacesAvailable = Hook.make<{ identity: Identity }>()('client-services/DataSpacesAvailable');\n\n/** The open sequence has completed, with or without an identity. */\nexport const StackOpened = Hook.make<void>()('client-services/StackOpened');\n\n/** Outbound networking may begin; emitted on `StackOpened` when auto-connecting, else by the embedder. */\nexport const NetworkingEnabled = Hook.make<void>()('client-services/NetworkingEnabled');\n\n/** A reset began: the embedder disposes the stack. */\nexport const Closing = Hook.make<void>()('client-services/Closing');\n\n/** The stack is gone: the embedder wipes persisted storage so the next open starts fresh. */\nexport const WipingStorage = Hook.make<void>()('client-services/WipingStorage');\n\n/** Storage is wiped; the embedder typically reloads. */\nexport const Reset = Hook.make<void>()('client-services/Reset');\n\n/** The local profile changed and should be broadcast to every open space. */\nexport const ProfileUpdated = Hook.make<{ profile: ProfileDocument }>()('client-services/ProfileUpdated');\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { DeferredTask, Event, scheduleTask, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { Resource } from '@dxos/context';\nimport { type EdgeHttpClient, EdgeHttpClientService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { EdgeAgentStatus, EdgeCallFailedError } from '@dxos/protocols';\nimport { fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport { SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { EdgeReplicationSetting } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { DeviceAdmissionRequestSchema } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type IdentityProvider } from '../identity/index.ts';\n\nconst AGENT_STATUS_QUERY_RETRY_INTERVAL = 5000;\nconst AGENT_STATUS_QUERY_RETRY_JITTER = 1000;\nconst AGENT_FEED_ADDED_CHECK_INTERVAL_MS = 3000;\n\nexport type EdgeAgentManagerConfig = {};\n\n/**\n * Effect service tag for {@link EdgeAgentManager}.\n */\nexport class EdgeAgentManagerService extends EffectContext.Service<EdgeAgentManagerService, EdgeAgentManager>()(\n '@dxos/client-services/EdgeAgentManager',\n) {}\n\nexport class EdgeAgentManager extends Resource {\n public agentStatusChanged = new Event<EdgeAgentStatus>();\n\n private _agentDeviceKey: PublicKey | undefined;\n private _agentStatus: EdgeAgentStatus | undefined;\n\n private _lastKnownDeviceCount = 0;\n\n private _fetchAgentStatusTask: DeferredTask | undefined;\n\n constructor(\n private readonly _edgeFeatures: Runtime_Client_EdgeFeatures | undefined,\n private readonly _edgeHttpClient: EdgeHttpClient | undefined,\n private readonly _dataSpaceManager: SpacesContract.Manager,\n private readonly _identityProvider: IdentityProvider,\n ) {\n super();\n }\n\n private get identity(): Identity {\n return this._identityProvider();\n }\n\n public get agentStatus(): EdgeAgentStatus | undefined {\n return this._agentStatus;\n }\n\n public get agentExists() {\n return this._agentStatus && this._agentStatus !== EdgeAgentStatus.NOT_FOUND;\n }\n\n @synchronized\n public async createAgent(ctx: Context): Promise<void> {\n invariant(this.isOpen);\n invariant(this._edgeHttpClient);\n invariant(this._edgeFeatures?.agents);\n\n const response = await this._edgeHttpClient.createAgent(ctx, {\n identityDid: this.identity.did,\n haloSpaceId: this.identity.haloSpaceId,\n haloSpaceKey: this.identity.haloSpaceKey.toHex(),\n });\n\n const deviceKey = PublicKey.fromHex(response.deviceKey);\n\n if (await this.identity.authorizedDeviceKeys.has(deviceKey)) {\n log.info('agent was already added to HALO, ignoring response', { response });\n this._updateStatus(EdgeAgentStatus.ACTIVE, deviceKey);\n return;\n }\n\n await this.identity.admitDevice(\n create(DeviceAdmissionRequestSchema, {\n deviceKey: fromPublicKey(deviceKey),\n controlFeedKey: fromPublicKey(PublicKey.fromHex(response.feedKey)),\n // TODO: agents don't have data feed, should be removed\n dataFeedKey: fromPublicKey(PublicKey.random()),\n }),\n );\n\n log('agent created', response);\n\n this._updateStatus(EdgeAgentStatus.ACTIVE, deviceKey);\n }\n\n protected override async _open(): Promise<void> {\n const isEnabled = this._edgeHttpClient && this._edgeFeatures?.agents;\n\n log('edge agent manager open', { isEnabled });\n\n if (!isEnabled) {\n return;\n }\n\n this._lastKnownDeviceCount = this.identity.authorizedDeviceKeys.size;\n this._fetchAgentStatusTask = new DeferredTask(this._ctx, async () => {\n await this._fetchAgentStatus(this._ctx);\n });\n this._fetchAgentStatusTask.schedule();\n\n this._dataSpaceManager.updated.on(this._ctx, () => {\n if (this._agentDeviceKey) {\n this._ensureAgentIsInSpaces(this._agentDeviceKey);\n }\n });\n\n this.identity.stateUpdate.on(this._ctx, () => {\n const maybeAgentWasCreated = this.identity.authorizedDeviceKeys.size > this._lastKnownDeviceCount;\n if (this.agentExists || !maybeAgentWasCreated) {\n return;\n }\n this._lastKnownDeviceCount = this.identity.authorizedDeviceKeys.size;\n this._fetchAgentStatusTask?.schedule();\n });\n }\n\n protected override async _close(): Promise<void> {\n this._fetchAgentStatusTask = undefined;\n this._lastKnownDeviceCount = 0;\n this._agentStatus = undefined;\n this._agentDeviceKey = undefined;\n }\n\n protected async _fetchAgentStatus(ctx: Context): Promise<void> {\n invariant(this._edgeHttpClient);\n try {\n log('fetching agent status');\n const { agent } = await this._edgeHttpClient.getAgentStatus(ctx, {\n ownerIdentityDid: this.identity.did,\n });\n const wasAgentCreatedDuringQuery = this._agentStatus === EdgeAgentStatus.ACTIVE;\n if (!wasAgentCreatedDuringQuery) {\n const deviceKey = agent.deviceKey ? PublicKey.fromHex(agent.deviceKey) : undefined;\n this._updateStatus(agent.status, deviceKey);\n }\n } catch (err) {\n if (err instanceof EdgeCallFailedError) {\n if (!err.isRetryable) {\n log.warn('non retryable error on agent status fetch attempt', { err });\n return;\n }\n }\n const retryAfterMs = AGENT_STATUS_QUERY_RETRY_INTERVAL + Math.random() * AGENT_STATUS_QUERY_RETRY_JITTER;\n log.info('agent status fetching failed', { err, retryAfterMs });\n scheduleTask(this._ctx, () => this._fetchAgentStatusTask?.schedule(), retryAfterMs);\n }\n }\n\n /**\n * We don't want notarization plugin to always actively poll edge looking for credentials to notarize,\n * because most of the time we'll be getting an empty response.\n * Instead, we stay in active polling mode while there are spaces where we don't see our agent's feed.\n */\n protected _ensureAgentIsInSpaces(agentDeviceKey: PublicKey): void {\n let activePollingEnabled = false;\n for (const space of this._dataSpaceManager.spaces.values()) {\n if (space.getEdgeReplicationSetting() === EdgeReplicationSetting.DISABLED) {\n space.notarizationPlugin.setActiveEdgePollingEnabled(false);\n continue;\n }\n if ([SpaceState.SPACE_INACTIVE, SpaceState.SPACE_CLOSED].includes(space.state)) {\n space.notarizationPlugin.setActiveEdgePollingEnabled(false);\n continue;\n }\n const agentFeedNeedsNotarization = ![...space.inner.spaceState.feeds.values()].some((feed) =>\n requirePublicKey(feed.assertion.deviceKey).equals(agentDeviceKey),\n );\n space.notarizationPlugin.setActiveEdgePollingEnabled(agentFeedNeedsNotarization);\n activePollingEnabled = activePollingEnabled || agentFeedNeedsNotarization;\n\n log.verbose('set active edge polling', { enabled: agentFeedNeedsNotarization, spaceId: space.id });\n }\n\n if (activePollingEnabled) {\n // Check again to see if active edge polling can be disabled (agent feed is notarized in all the spaces)\n scheduleTask(this._ctx, () => this._ensureAgentIsInSpaces(agentDeviceKey), AGENT_FEED_ADDED_CHECK_INTERVAL_MS);\n }\n }\n\n private _updateStatus(status: EdgeAgentStatus, deviceKey: PublicKey | undefined): void {\n this._agentStatus = status;\n this._agentDeviceKey = deviceKey;\n this.agentStatusChanged.emit(status);\n if (deviceKey) {\n this._ensureAgentIsInSpaces(deviceKey);\n }\n log.verbose('agent status update', { status });\n }\n}\n\nexport type EdgeAgentManagerLayerOptions = {\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n};\n\n/**\n * Effect Layer constructing a dormant {@link EdgeAgentManager}.\n */\nexport const EdgeAgentManagerLayer = (\n options: EdgeAgentManagerLayerOptions = {},\n): Layer.Layer<\n EdgeAgentManagerService,\n never,\n Hook.Controller | SpacesContract.ManagerService | IdentityContract.ProviderService\n> =>\n Layer.effect(\n EdgeAgentManagerService,\n Effect.gen(function* () {\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const identityProvider = yield* IdentityContract.ProviderService;\n const edgeHttpClient = yield* Effect.serviceOption(EdgeHttpClientService);\n const edgeAgentManager = new EdgeAgentManager(\n options.edgeFeatures,\n Option.getOrUndefined(edgeHttpClient),\n dataSpaceManager,\n identityProvider,\n );\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(() => edgeAgentManager.close()));\n yield* Hook.on(\n Events.DataSpacesAvailable,\n Effect.fn('EdgeAgentManager.onDataSpacesAvailable')(function* () {\n // Rebound on every identity, so an identity deleted in place does not leave its agent's\n // status (and the subscriptions on its HALO) standing in for the next one's.\n yield* Effect.promise(() => edgeAgentManager.close());\n yield* Effect.promise(() => edgeAgentManager.open(ctx));\n }),\n );\n return edgeAgentManager;\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { Trigger } from '@dxos/async';\nimport * as Hook from '@dxos/effect/Hook';\n\nimport * as Events from './Events.ts';\n\n/**\n * Readiness gate for the identity-bound services: `initialized` wakes once the data spaces are\n * open, whether the identity was persisted, created, or accepted.\n */\nexport interface StackReadiness {\n readonly initialized: Trigger;\n}\n\nexport class StackReadinessService extends EffectContext.Service<StackReadinessService, StackReadiness>()(\n '@dxos/client-services/StackReadiness',\n) {}\n\nexport const StackReadinessLayer: Layer.Layer<StackReadinessService, never, Hook.Controller> = Layer.effect(\n StackReadinessService,\n Effect.gen(function* () {\n const initialized = new Trigger();\n yield* Hook.on(\n Events.DataSpacesAvailable,\n Effect.fn('StackReadiness.onDataSpacesAvailable')(function* () {\n initialized.wake();\n }),\n );\n return { initialized };\n }),\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { EdgeAgentStatus, toServiceError } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport {\n type QueryAgentStatusResponse,\n QueryAgentStatusResponse_AgentStatus,\n QueryAgentStatusResponseSchema,\n type QueryEdgeStatusResponse,\n QueryEdgeStatusResponseSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { EdgeAgentService } from '@dxos/protocols/rpc';\n\nimport * as Readiness from '../../Readiness.ts';\nimport { type EdgeAgentManager, EdgeAgentManagerService } from './edge-agent-manager.ts';\n\n// TODO(wittjosiah): This service is not currently exposed on the client api, it must be called directly.\nexport class EdgeAgentServiceImpl implements EdgeAgentService.Handlers {\n 'constructor'(\n private readonly _agentManagerProvider: () => Promise<EdgeAgentManager>,\n private readonly _edgeConnection?: EdgeConnection,\n ) {}\n\n // TODO(mykola): Reconcile with NetworkService.queryStatus.\n ['EdgeAgentService.queryEdgeStatus'](): EffectStream.Stream<QueryEdgeStatusResponse, Error> {\n return EffectEx.streamFromEmitter<QueryEdgeStatusResponse, Error>((emit) => {\n const ctx = Context.default();\n const update = () => {\n void emit.single(buf.create(QueryEdgeStatusResponseSchema, { status: this._edgeConnection?.status }));\n };\n\n this._edgeConnection?.statusChanged.on(ctx, update);\n update();\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['EdgeAgentService.createAgent'](): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => (await this._agentManagerProvider()).createAgent(Context.default()),\n catch: toServiceError,\n });\n }\n\n ['EdgeAgentService.queryAgentStatus'](): EffectStream.Stream<QueryAgentStatusResponse, Error> {\n return EffectEx.streamFromEmitter<QueryAgentStatusResponse, Error>((emit) => {\n const ctx = Context.default();\n void emit.single(\n buf.create(QueryAgentStatusResponseSchema, { status: QueryAgentStatusResponse_AgentStatus.UNKNOWN }),\n );\n void this._agentManagerProvider().then((agentManager) => {\n void emit.single(buf.create(QueryAgentStatusResponseSchema, { status: mapStatus(agentManager.agentStatus) }));\n agentManager.agentStatusChanged.on(ctx, (newStatus) => {\n void emit.single(buf.create(QueryAgentStatusResponseSchema, { status: mapStatus(newStatus) }));\n });\n });\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n}\n\nconst mapStatus = (agentStatus: EdgeAgentStatus | undefined): QueryAgentStatusResponse_AgentStatus => {\n switch (agentStatus) {\n case EdgeAgentStatus.ACTIVE:\n return QueryAgentStatusResponse_AgentStatus.ACTIVE;\n case EdgeAgentStatus.INACTIVE:\n return QueryAgentStatusResponse_AgentStatus.INACTIVE;\n case EdgeAgentStatus.NOT_FOUND:\n return QueryAgentStatusResponse_AgentStatus.NOT_FOUND;\n case undefined:\n return QueryAgentStatusResponse_AgentStatus.UNKNOWN;\n }\n};\n\nexport const EdgeAgentServiceLayer: Layer.Layer<\n EdgeAgentService.Tag,\n never,\n Readiness.StackReadinessService | EdgeAgentManagerService\n> = Layer.effect(\n EdgeAgentService.Tag,\n Effect.gen(function* () {\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n const readiness = yield* Readiness.StackReadinessService;\n const edgeAgentManager = yield* EdgeAgentManagerService;\n return new EdgeAgentServiceImpl(() => readiness.initialized.wait().then(() => edgeAgentManager), edgeConnection);\n }),\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\n\nimport { type Event } from '@dxos/async';\nimport { type AuthenticatingInvitation, type CancellableInvitation } from '@dxos/client-protocol';\nimport { type Context } from '@dxos/context';\nimport { type Invitation } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nimport { type InvitationProtocol } from './invitation-protocol.ts';\n\n//\n// The invitations subsystem's contract. See `contracts/identity.ts` for why the tags live with the\n// interfaces rather than with the implementations.\n//\n\n/**\n * Creates and tracks the in-flight invitations, as its consumers use it.\n */\nexport interface Manager {\n readonly invitationCreated: Event<Invitation>;\n readonly invitationAccepted: Event<Invitation>;\n readonly removedCreated: Event<Invitation>;\n readonly removedAccepted: Event<Invitation>;\n readonly saved: Event<Invitation>;\n getCreatedInvitations(): Invitation[];\n getAcceptedInvitations(): Invitation[];\n loadPersistentInvitations(ctx: Context): Promise<{ invitations: Invitation[] }>;\n onPersistentInvitationsLoaded(ctx: Context, callback: () => void): void;\n authenticate(request: { invitationId: string; authCode: string }): Promise<void>;\n setInvitationHandlerFactory(\n getHandler: (invitation: Partial<Invitation> & Pick<Invitation, 'kind'>) => InvitationProtocol,\n ): void;\n getInvitationHandler(invitation: Partial<Invitation> & Pick<Invitation, 'kind'>): InvitationProtocol;\n createInvitation(\n ctx: Context,\n options: Partial<Invitation> & Pick<Invitation, 'kind'>,\n ): Promise<CancellableInvitation>;\n cancelInvitation(request: { invitationId: string }): Promise<void>;\n acceptInvitation(\n ctx: Context,\n request: {\n invitation: Partial<Invitation> & Pick<Invitation, 'invitationId'>;\n deviceProfile?: DeviceProfileDocument;\n },\n ): AuthenticatingInvitation;\n}\n\n/** Effect service tag for {@link Manager}. */\nexport class ManagerService extends EffectContext.Service<ManagerService, Manager>()(\n '@dxos/client-services/InvitationsManager',\n) {}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create, fromBinary, toBinary } from '@bufbuild/protobuf';\n\nimport { type Event, Trigger } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type CredentialSigner, verifyCredential } from '@dxos/credentials';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport { AuthSchema, CredentialSchema } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type ComplexSet, arraysEqual } from '@dxos/util';\n\n// @import-as-namespace\n\n/** Produces a credential proving the peer may join the space, for the given nonce. */\nexport type AuthProvider = (nonce: Uint8Array) => Promise<Uint8Array | undefined>;\n\n/** Verifies a credential produced by an {@link AuthProvider}. */\nexport type AuthVerifier = (nonce: Uint8Array, credential: Uint8Array) => Promise<boolean>;\n\nexport const createAuthProvider =\n (signer: CredentialSigner): AuthProvider =>\n async (nonce) => {\n const credential = await signer.createCredential({\n assertion: create(AuthSchema, {}),\n subject: signer.getIssuer(),\n nonce,\n });\n\n return toBinary(CredentialSchema, credential);\n };\n\nexport type TrustedKeySetAuthVerifierProps = {\n // TODO(dmaretskyi): Change to `isTrusted: (key) => bool`.\n trustedKeysProvider: () => ComplexSet<PublicKey>;\n update: Event<void>;\n /**\n * Timeout to wait for the device key to be added to the trusted set.\n */\n authTimeout: number;\n};\n\n/**\n * Verifies credentials of another member in the space based on a set of trusted key.\n * Will wait up to `authTimeout` for the key to be added to the trusted set.\n */\nexport class TrustedKeySetAuthVerifier {\n private _ctx = new Context();\n\n constructor(private readonly _params: TrustedKeySetAuthVerifierProps) {}\n\n async close(): Promise<void> {\n await this._ctx.dispose();\n }\n\n get verifier(): AuthVerifier {\n return async (nonce, auth) => {\n const credential = fromBinary(CredentialSchema, auth);\n log('authenticating...', { credential });\n\n const result = await verifyCredential(credential);\n if (result.kind === 'fail') {\n log('Invalid credential', { result });\n return false;\n }\n\n const proofNonce = credential.proof?.nonce;\n // Compared as bytes: the browser `buffer` polyfill's `equals` rejects a plain `Uint8Array`,\n // which is what protobuf decoding yields for the nonce.\n if (!proofNonce?.length || !arraysEqual(nonce, proofNonce)) {\n log('Invalid nonce', { nonce, credential });\n return false;\n }\n\n const issuer = requirePublicKey(credential.issuer);\n if (this._isTrustedKey(issuer)) {\n log('key is trusted -- auth success', { key: issuer });\n return true;\n }\n\n const trigger = new Trigger<boolean>();\n this._ctx.onDispose(() => {\n trigger.wake(false);\n });\n\n const clear = this._params.update.on(this._ctx, () => {\n if (this._isTrustedKey(issuer)) {\n log('auth success', { key: issuer });\n trigger.wake(true);\n } else {\n log('key is not currently in trusted set, waiting...', {\n key: issuer,\n trusted: [...this._params.trustedKeysProvider()],\n });\n }\n });\n\n try {\n return await trigger.wait({ timeout: this._params.authTimeout });\n } catch {\n return false;\n } finally {\n clear();\n }\n };\n }\n\n private _isTrustedKey(deviceKey: PublicKey): boolean {\n const deviceSet = this._params.trustedKeysProvider();\n return deviceSet.has(deviceKey);\n }\n}\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type AutomergeUrl } from '@automerge/automerge-repo';\nimport { toBinary } from '@bufbuild/protobuf';\n\nimport { scheduleMicroTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport {\n CREDENTIALS_DOCUMENT_TYPE,\n type CredentialsDocument,\n type OrderedCredential,\n orderCredentials,\n} from '@dxos/credentials';\nimport { AddOnlySet } from '@dxos/echo-doc';\nimport { type DocumentLease, type EchoHost } from '@dxos/echo-host';\nimport { invariant } from '@dxos/invariant';\nimport { type SpaceId } from '@dxos/keys';\nimport { toPublicKey } from '@dxos/protocols/buf';\nimport { type Credential, CredentialSchema } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nconst CREDENTIALS_PATH = ['credentials'];\n\n/**\n * Read/write access to a space's credentials document, the successor to its control feed.\n */\nexport class CredentialsDocumentStore implements Disposable {\n readonly #lease: DocumentLease<CredentialsDocument>;\n\n constructor(lease: DocumentLease<CredentialsDocument>) {\n this.#lease = lease;\n }\n\n get url(): AutomergeUrl {\n return this.#lease.url;\n }\n\n /** Releases the credentials document; the store cannot be read or written after this. */\n [Symbol.dispose](): void {\n this.#lease[Symbol.dispose]();\n }\n\n /**\n * Credentials in the order the state machine must process them.\n *\n * Read from the change history rather than the current state: a member who can write to the\n * document must not be able to revoke another by deleting their credential.\n */\n read(): OrderedCredential[] {\n const doc = this.#lease.doc();\n return doc ? orderCredentials(AddOnlySet.read(doc, CREDENTIALS_PATH)) : [];\n }\n\n /**\n * Replays the document into `process` and keeps doing so as it changes. Ordering is recomputed on\n * every change because a late-arriving parent can reorder credentials that already arrived.\n */\n subscribe(ctx: Context, process: (credential: Credential) => Promise<boolean>): void {\n const replay = () => {\n scheduleMicroTask(ctx, async () => {\n for (const { credential } of this.read()) {\n await process(credential);\n }\n });\n };\n\n this.#lease.on('change', replay);\n ctx.onDispose(() => this.#lease.off('change', replay));\n replay();\n }\n\n /**\n * Appends a credential, keyed by its id so that re-appending one — which the migration backfill and\n * a second device both do — converges instead of duplicating it.\n */\n append(credential: Credential): void {\n const id = toPublicKey(credential.id)?.toHex();\n invariant(id, 'Credential has no id.');\n if (this.#lease.doc()?.credentials?.[id]) {\n return;\n }\n\n this.#lease.change((doc: CredentialsDocument) => {\n doc.credentials ??= {};\n AddOnlySet.add(doc.credentials, id, toBinary(CredentialSchema, credential));\n });\n }\n}\n\n/**\n * Opens the space's credentials document, creating and linking it from the space root on first use.\n */\nexport const openCredentialsDocument = async (\n ctx: Context,\n echoHost: EchoHost,\n spaceId: SpaceId,\n): Promise<CredentialsDocumentStore> => {\n const open = async (url: AutomergeUrl): Promise<CredentialsDocumentStore> => {\n // The lease is held by the store: it writes credentials for as long as the space is open.\n const lease = await echoHost.loadDoc<CredentialsDocument>(ctx, url);\n invariant(lease, 'Credentials document must load.');\n return store(lease);\n };\n\n // Disposed with the caller's context, which is what bounds the store's lifetime — the lease would\n // otherwise keep the document resident for the session.\n const store = (lease: DocumentLease<CredentialsDocument>): CredentialsDocumentStore => {\n const opened = new CredentialsDocumentStore(lease);\n ctx.onDispose(() => opened[Symbol.dispose]());\n return opened;\n };\n\n const existing = echoHost.getSpaceRootRefs(spaceId)?.credentialsDocUrl;\n if (existing) {\n return open(existing);\n }\n\n // The creating lease becomes the store's, so the document is never released between being created\n // and being read back — a fresh document exists only in memory until it is saved.\n const created = await echoHost.createDoc<CredentialsDocument>({\n type: CREDENTIALS_DOCUMENT_TYPE,\n spaceId,\n credentials: {},\n });\n // The link is what the space root records, and a concurrent call may have won it: the store must\n // follow the linked document, since writes to an unlinked one would never be read back.\n const linked = await echoHost.setCredentialsDocument(ctx, spaceId, created.url);\n if (linked !== created.url) {\n created[Symbol.dispose]();\n return open(linked);\n }\n return store(created);\n};\n","//\n// Copyright 2021 DXOS.org\n//\n\nimport { type Message, create, fromBinary, toBinary } from '@bufbuild/protobuf';\nimport { type GenMessage } from '@bufbuild/protobuf/codegenv2';\nimport CRC32 from 'crc-32';\nimport * as EffectContext from 'effect/Context';\n\nimport { Event, scheduleTaskInterval, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { DataCorruptionError, STORAGE_VERSION } from '@dxos/protocols';\nimport { fromDate, fromPublicKey, fromTimeframe, requirePublicKey, toDate } from '@dxos/protocols/buf';\nimport { type Invitation, Invitation_Type, SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n type ControlPipelineSnapshot,\n type EchoMetadata,\n EchoMetadataSchema,\n type EdgeReplicationSetting,\n type IdentityRecord,\n type LargeSpaceMetadata,\n LargeSpaceMetadataSchema,\n type SpaceMetadata,\n} from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { type Directory, type File } from '@dxos/random-access-storage';\nimport { type Timeframe } from '@dxos/timeframe';\nimport { ComplexMap, arrayToBuffer, forEachAsync, isNonNullable } from '@dxos/util';\n\nconst EXPIRED_INVITATION_CLEANUP_INTERVAL = 60 * 60 * 1000; // 1 hour\n\n/**\n * Shared interface for file-based and SQLite-backed metadata stores.\n */\nexport interface IMetadataStore {\n readonly update: Event<EchoMetadata>;\n readonly metadata: EchoMetadata;\n readonly version: number;\n readonly spaces: SpaceMetadata[];\n\n load(): Promise<void>;\n close(): Promise<void>;\n flush(): Promise<void>;\n clear(): Promise<void>;\n hasSpace(spaceKey: PublicKey): boolean;\n\n getIdentityRecord(): IdentityRecord | undefined;\n setIdentityRecord(record: IdentityRecord): Promise<void>;\n\n getInvitations(): Invitation[];\n addInvitation(invitation: Invitation): Promise<void>;\n removeInvitation(invitationId: string): Promise<void>;\n\n addSpace(record: SpaceMetadata): Promise<void>;\n setSpaceDataLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void>;\n setSpaceControlLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void>;\n setWritableFeedKeys(spaceKey: PublicKey, controlFeedKey: PublicKey, dataFeedKey: PublicKey): Promise<void>;\n setSpaceState(spaceKey: PublicKey, state: SpaceState): Promise<void>;\n\n getSpaceControlPipelineSnapshot(spaceKey: PublicKey): ControlPipelineSnapshot | undefined;\n setSpaceControlPipelineSnapshot(spaceKey: PublicKey, snapshot: ControlPipelineSnapshot): Promise<void>;\n\n getSpaceEdgeReplicationSetting(spaceKey: PublicKey): EdgeReplicationSetting | undefined;\n setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void>;\n\n readonly deletedSpaces: PublicKey[];\n addDeletedSpace(spaceKey: PublicKey): Promise<void>;\n}\n\n/**\n * Effect service tag for {@link IMetadataStore}.\n */\nexport class IMetadataStoreService extends EffectContext.Service<IMetadataStoreService, IMetadataStore>()(\n '@dxos/client-services/IMetadataStore',\n) {}\n\nexport interface AddSpaceOptions {\n key: PublicKey;\n genesisFeed: PublicKey;\n}\n\nconst emptyEchoMetadata = (): EchoMetadata =>\n create(EchoMetadataSchema, {\n version: STORAGE_VERSION,\n spaces: [],\n created: fromDate(new Date()),\n updated: fromDate(new Date()),\n });\n\nconst emptyLargeSpaceMetadata = (): LargeSpaceMetadata => create(LargeSpaceMetadataSchema, {});\n\nexport class MetadataStore implements IMetadataStore {\n private _metadata: EchoMetadata = emptyEchoMetadata();\n private _spaceLargeMetadata = new ComplexMap<PublicKey, LargeSpaceMetadata>(PublicKey.hash);\n\n private _metadataFile?: File = undefined;\n\n public readonly update = new Event<EchoMetadata>();\n private readonly _invitationCleanupCtx = new Context();\n\n /**\n * @internal\n */\n readonly _directory: Directory;\n\n constructor(directory: Directory) {\n this._directory = directory;\n }\n\n get metadata(): EchoMetadata {\n return this._metadata;\n }\n\n get version(): number {\n return this._metadata.version ?? 0;\n }\n\n /**\n * Returns a list of currently saved spaces. The list and objects in it can be modified addSpace and\n * addSpaceFeed functions.\n */\n get spaces(): SpaceMetadata[] {\n return this._metadata.spaces ?? [];\n }\n\n /**\n * Returns the keys of spaces that have been tombstoned (soft-deleted).\n */\n get deletedSpaces(): PublicKey[] {\n return (this._metadata.deletedSpaces ?? []).map(requirePublicKey);\n }\n\n private async _readFile<T extends Message>(file: File, schema: GenMessage<T>): Promise<T | undefined> {\n try {\n const { size: fileLength } = await file.stat();\n if (fileLength < 8) {\n return;\n }\n // Loading file size from first 4 bytes.\n const dataSize = (await file.read(0, 4)).readInt32LE(0);\n const checksum = (await file.read(4, 4)).readInt32LE(0);\n log('loaded', { size: dataSize, checksum, name: file.filename });\n\n if (fileLength < dataSize + 8) {\n throw new DataCorruptionError({\n message: 'Metadata size is smaller than expected.',\n context: { fileLength, dataSize },\n });\n }\n\n const data = await file.read(8, dataSize);\n\n const calculatedChecksum = CRC32.buf(data);\n if (calculatedChecksum !== checksum) {\n throw new DataCorruptionError({ message: 'Metadata checksum is invalid.' });\n }\n\n return fromBinary(schema, data);\n } finally {\n await file.close();\n }\n }\n\n /**\n * @internal\n */\n async _writeFile<T extends Message>(file: File, schema: GenMessage<T>, data: T): Promise<void> {\n const encoded = arrayToBuffer(toBinary(schema, data));\n const checksum = CRC32.buf(encoded);\n\n const result = Buffer.alloc(8 + encoded.length);\n\n result.writeInt32LE(encoded.length, 0);\n result.writeInt32LE(checksum, 4);\n encoded.copy(result, 8);\n\n // NOTE: This must be done in one write operation, otherwise the file can be corrupted.\n await file.write(0, result);\n\n log('saved', { size: encoded.length, checksum });\n }\n\n async close(): Promise<void> {\n await this._invitationCleanupCtx.dispose();\n await this.flush();\n await this._metadataFile?.close();\n this._metadataFile = undefined;\n this._metadata = emptyEchoMetadata();\n this._spaceLargeMetadata.clear();\n }\n\n /**\n * Loads metadata from persistent storage.\n */\n @synchronized\n async load(): Promise<void> {\n if (!this._metadataFile || this._metadataFile.closed) {\n this._metadataFile = this._directory.getOrCreateFile('EchoMetadata');\n }\n\n try {\n const metadata = await this._readFile(this._metadataFile, EchoMetadataSchema);\n if (metadata) {\n this._metadata = metadata;\n }\n\n // post-processing\n // proto3 omits the zero enum, so a record written before `state` existed reads back as unset.\n this._metadata.spaces?.forEach((space) => {\n if (!space.state) {\n space.state = SpaceState.SPACE_ACTIVE;\n }\n });\n } catch (err: any) {\n log.error('failed to load metadata', { err });\n this._metadata = emptyEchoMetadata();\n }\n\n await forEachAsync(\n [this._metadata.identity?.haloSpace?.key, ...(this._metadata.spaces?.map((space) => space.key) ?? [])]\n .filter(isNonNullable)\n .map(requirePublicKey),\n async (key) => {\n try {\n await this._loadSpaceLargeMetadata(key);\n } catch (err: any) {\n log.error('failed to load space large metadata', { err });\n }\n },\n );\n\n // Cleanup expired persistent invitations.\n scheduleTaskInterval(\n this._invitationCleanupCtx,\n async () => {\n for (const invitation of this._metadata.invitations ?? []) {\n if (hasInvitationExpired(invitation) || isLegacyInvitationFormat(invitation)) {\n await this.removeInvitation(invitation.invitationId);\n }\n }\n },\n EXPIRED_INVITATION_CLEANUP_INTERVAL,\n );\n }\n\n @synchronized\n private async _save(): Promise<void> {\n const data: EchoMetadata = create(EchoMetadataSchema, {\n ...this._metadata,\n version: STORAGE_VERSION,\n created: this._metadata.created ?? fromDate(new Date()),\n updated: fromDate(new Date()),\n });\n this.update.emit(data);\n\n const file = this._directory.getOrCreateFile('EchoMetadata');\n\n await this._writeFile(file, EchoMetadataSchema, data);\n }\n\n private async _loadSpaceLargeMetadata(key: PublicKey): Promise<void> {\n const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);\n try {\n const metadata = await this._readFile(file, LargeSpaceMetadataSchema);\n if (metadata) {\n this._spaceLargeMetadata.set(key, metadata);\n }\n } catch (err: any) {\n log.error('failed to load space large metadata', { err });\n }\n }\n\n @synchronized\n private async _saveSpaceLargeMetadata(key: PublicKey): Promise<void> {\n const data = this._getLargeSpaceMetadata(key);\n const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);\n await this._writeFile(file, LargeSpaceMetadataSchema, data);\n }\n\n async flush(): Promise<void> {\n await this._directory.flush();\n }\n\n _getSpace(spaceKey: PublicKey): SpaceMetadata {\n const haloSpace = this._metadata.identity?.haloSpace;\n if (haloSpace?.key && requirePublicKey(haloSpace.key).equals(spaceKey)) {\n // Check if the space is the identity space.\n return haloSpace;\n }\n\n const space = this.spaces.find((space) => space.key && requirePublicKey(space.key).equals(spaceKey));\n invariant(space, 'Space not found');\n return space;\n }\n\n hasSpace(spaceKey: PublicKey): boolean {\n const haloSpace = this._metadata.identity?.haloSpace;\n if (haloSpace?.key && requirePublicKey(haloSpace.key).equals(spaceKey)) {\n // Check if the space is the identity space.\n return true;\n }\n\n return !!this.spaces.find((space) => space.key && requirePublicKey(space.key).equals(spaceKey));\n }\n\n private _getLargeSpaceMetadata(key: PublicKey): LargeSpaceMetadata {\n let entry = this._spaceLargeMetadata.get(key);\n if (entry) {\n return entry;\n }\n\n entry = emptyLargeSpaceMetadata();\n this._spaceLargeMetadata.set(key, entry);\n return entry;\n }\n\n /**\n * Clears storage - doesn't work for now.\n */\n async clear(): Promise<void> {\n log('clearing all metadata');\n await this._directory.delete();\n this._metadata = emptyEchoMetadata();\n }\n\n getIdentityRecord(): IdentityRecord | undefined {\n return this._metadata.identity;\n }\n\n async setIdentityRecord(record: IdentityRecord): Promise<void> {\n invariant(!this._metadata.identity, 'Cannot overwrite existing identity in metadata');\n\n this._metadata.identity = record;\n await this._save();\n await this.flush();\n }\n\n getInvitations(): Invitation[] {\n return this._metadata.invitations ?? [];\n }\n\n async addInvitation(invitation: Invitation): Promise<void> {\n if (this._metadata.invitations?.find((i) => i.invitationId === invitation.invitationId)) {\n return;\n }\n\n (this._metadata.invitations ??= []).push(invitation);\n await this._save();\n await this.flush();\n }\n\n async removeInvitation(invitationId: string): Promise<void> {\n this._metadata.invitations = (this._metadata.invitations ?? []).filter((i) => i.invitationId !== invitationId);\n await this._save();\n await this.flush();\n }\n\n /**\n * Records a space as tombstoned (soft-deleted) so it is never re-accepted or auto-opened.\n */\n async addDeletedSpace(spaceKey: PublicKey): Promise<void> {\n if (this.deletedSpaces.some((key) => key.equals(spaceKey))) {\n return;\n }\n\n (this._metadata.deletedSpaces ??= []).push(fromPublicKey(spaceKey));\n await this._save();\n await this.flush();\n }\n\n async addSpace(record: SpaceMetadata): Promise<void> {\n invariant(record.key, 'Space metadata has no key.');\n invariant(!this.hasSpace(requirePublicKey(record.key)), 'Cannot overwrite existing space in metadata');\n\n (this._metadata.spaces ??= []).push(record);\n await this._save();\n await this.flush();\n }\n\n async setSpaceDataLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void> {\n this._getSpace(spaceKey).dataTimeframe = fromTimeframe(timeframe);\n await this._save();\n }\n\n async setSpaceControlLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void> {\n this._getSpace(spaceKey).controlTimeframe = fromTimeframe(timeframe);\n await this._save();\n await this.flush();\n }\n\n async setWritableFeedKeys(spaceKey: PublicKey, controlFeedKey: PublicKey, dataFeedKey: PublicKey): Promise<void> {\n const space = this._getSpace(spaceKey);\n space.controlFeedKey = fromPublicKey(controlFeedKey);\n space.dataFeedKey = fromPublicKey(dataFeedKey);\n await this._save();\n await this.flush();\n }\n\n async setSpaceState(spaceKey: PublicKey, state: SpaceState): Promise<void> {\n this._getSpace(spaceKey).state = state;\n await this._save();\n await this.flush();\n }\n\n getSpaceControlPipelineSnapshot(spaceKey: PublicKey): ControlPipelineSnapshot | undefined {\n return this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot;\n }\n\n async setSpaceControlPipelineSnapshot(spaceKey: PublicKey, snapshot: ControlPipelineSnapshot): Promise<void> {\n this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot = snapshot;\n await this._saveSpaceLargeMetadata(spaceKey);\n await this.flush();\n }\n\n getSpaceEdgeReplicationSetting(spaceKey: PublicKey): EdgeReplicationSetting | undefined {\n return this.hasSpace(spaceKey) ? this._getSpace(spaceKey).edgeReplication : undefined;\n }\n\n async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void> {\n this._getSpace(spaceKey).edgeReplication = setting;\n await this._save();\n await this.flush();\n }\n}\n\nexport const hasInvitationExpired = (invitation: Invitation): boolean => {\n const created = toDate(invitation.created);\n return Boolean(created && invitation.lifetime && created.getTime() + invitation.lifetime * 1000 < Date.now());\n};\n\n// TODO: remove once \"multiuse\" type invitations get removed from local metadata of existing profiles\nconst isLegacyInvitationFormat = (invitation: Invitation): boolean => {\n return invitation.type === Invitation_Type.MULTIUSE;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as SqlMigrations from '@dxos/sql-sqlite/SqlMigrations';\n\nimport init from './0001_init.sql?raw';\n\n/**\n * Space metadata migrations, keyed `<id>_<name>` as `Migrator.fromRecord` expects. Ids must only ever increase,\n * and an applied migration must never be edited — nothing verifies its contents.\n */\nexport const MIGRATIONS = {\n '0001_init': SqlMigrations.apply(init),\n};\n\n/** Own history table per store, since many stores share the client database. */\nexport const MIGRATIONS_TABLE = 'metadata_migrations';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Message, clone, create, equals, fromBinary, toBinary } from '@bufbuild/protobuf';\nimport { type GenMessage } from '@bufbuild/protobuf/codegenv2';\nimport CRC32 from 'crc-32';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Migrator from 'effect/sql/Migrator';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport type * as SqlError from 'effect/sql/SqlError';\n\nimport { Event, scheduleTaskInterval, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { DataCorruptionError, STORAGE_VERSION } from '@dxos/protocols';\nimport { fromDate, fromPublicKey, fromTimeframe, requirePublicKey } from '@dxos/protocols/buf';\nimport { type Invitation, Invitation_Type, SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n type ControlPipelineSnapshot,\n type EchoMetadata,\n EchoMetadataSchema,\n type EdgeReplicationSetting,\n type IdentityRecord,\n type LargeSpaceMetadata,\n LargeSpaceMetadataSchema,\n type SpaceMetadata,\n} from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { type Timeframe } from '@dxos/timeframe';\nimport { ComplexMap, arrayToBuffer, forEachAsync, isNonNullable } from '@dxos/util';\n\nimport { MIGRATIONS, MIGRATIONS_TABLE } from '../../migrations/metadata/index.ts';\nimport { type IMetadataStore, IMetadataStoreService, hasInvitationExpired } from './metadata-store.ts';\n\nconst EXPIRED_INVITATION_CLEANUP_INTERVAL = 60 * 60 * 1000; // 1 hour\n\nconst emptyEchoMetadata = (): EchoMetadata =>\n create(EchoMetadataSchema, {\n version: STORAGE_VERSION,\n spaces: [],\n created: fromDate(new Date()),\n updated: fromDate(new Date()),\n });\n\nconst emptyLargeSpaceMetadata = (): LargeSpaceMetadata => create(LargeSpaceMetadataSchema, {});\n\n/** A deep copy, so later in-place edits to the live record cannot alter what it is compared against. */\nconst withoutUpdated = (metadata: EchoMetadata): EchoMetadata => {\n const copy = clone(EchoMetadataSchema, metadata);\n copy.updated = undefined;\n return copy;\n};\n\nconst MAIN_KEY = 'main';\nconst largeKey = (spaceKey: PublicKey) => `large:${spaceKey.toHex()}`;\n\n// Legacy invitation type detection.\nconst isLegacyInvitationFormat = (invitation: Invitation): boolean => invitation.type === Invitation_Type.MULTIUSE;\n\nexport type SqliteMetadataStoreProps = {\n runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n};\n\n/**\n * SQLite-backed replacement for MetadataStore.\n * Stores EchoMetadata as a single protobuf blob and LargeSpaceMetadata as per-space blobs.\n */\nexport class SqliteMetadataStore implements IMetadataStore {\n readonly #runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n\n #metadata: EchoMetadata = emptyEchoMetadata();\n /** The stored record, minus its `updated` stamp — a save that would only bump the stamp writes nothing. */\n #persisted: EchoMetadata | undefined;\n #loaded = false;\n readonly #spaceLargeMetadata = new ComplexMap<PublicKey, LargeSpaceMetadata>(PublicKey.hash);\n\n readonly update = new Event<EchoMetadata>();\n readonly #invitationCleanupCtx = new Context();\n\n constructor({ runtime }: SqliteMetadataStoreProps) {\n this.#runtime = runtime;\n }\n\n /**\n * Applies any migrations this database has not recorded yet.\n */\n readonly migrate: Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient> = Migrator.make({})({\n loader: Migrator.fromRecord(MIGRATIONS),\n table: MIGRATIONS_TABLE,\n }).pipe(\n // A malformed bundled manifest is a defect, not something a caller can recover from.\n Effect.catchTag('MigrationError', (error) => Effect.die(error)),\n Effect.asVoid,\n Effect.withSpan('SqliteMetadataStore.migrate'),\n );\n\n get metadata(): EchoMetadata {\n return this.#metadata;\n }\n\n get version(): number {\n return this.#metadata.version ?? 0;\n }\n\n get spaces(): SpaceMetadata[] {\n return this.#metadata.spaces ?? [];\n }\n\n async close(): Promise<void> {\n await this.#invitationCleanupCtx.dispose();\n // A store that never loaded holds empty metadata; saving it would wipe the persisted record.\n if (this.#loaded) {\n await this._save();\n }\n this.#loaded = false;\n this.#metadata = emptyEchoMetadata();\n this.#persisted = undefined;\n this.#spaceLargeMetadata.clear();\n }\n\n /**\n * Loads metadata from SQLite.\n */\n @synchronized\n async load(): Promise<void> {\n const rows = await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql<{ value: Uint8Array }>`SELECT value FROM space_metadata WHERE key = ${MAIN_KEY}`;\n }),\n );\n\n if (rows.length > 0) {\n try {\n this.#metadata = this.#decodeWithCrc(rows[0].value, EchoMetadataSchema) ?? emptyEchoMetadata();\n // proto3 omits the zero enum, so a record written before `state` existed reads back as unset.\n this.#metadata.spaces?.forEach((space) => {\n if (!space.state) {\n space.state = SpaceState.SPACE_ACTIVE;\n }\n });\n this.#persisted = withoutUpdated(this.#metadata);\n } catch (err: any) {\n log.error('failed to load metadata from SQLite', { err });\n this.#metadata = emptyEchoMetadata();\n }\n }\n\n // Load large metadata for all known spaces.\n const spaceKeys = [this.#metadata.identity?.haloSpace?.key, ...(this.#metadata.spaces?.map((s) => s.key) ?? [])]\n .filter(isNonNullable)\n .map(requirePublicKey);\n\n await forEachAsync(spaceKeys, async (key) => {\n try {\n await this.#loadSpaceLargeMetadata(key);\n } catch (err: any) {\n log.error('failed to load large space metadata', { err });\n }\n });\n\n scheduleTaskInterval(\n this.#invitationCleanupCtx,\n async () => {\n for (const invitation of this.#metadata.invitations ?? []) {\n if (hasInvitationExpired(invitation) || isLegacyInvitationFormat(invitation)) {\n await this.removeInvitation(invitation.invitationId);\n }\n }\n },\n EXPIRED_INVITATION_CLEANUP_INTERVAL,\n );\n\n // Set last: a throw above (SQL error, a row failing to decode) must leave the store unloaded, or\n // `close()` would save the empty metadata it still holds over the persisted record.\n this.#loaded = true;\n }\n\n async flush(): Promise<void> {\n // No-op: SQLite writes are immediate.\n }\n\n hasSpace(spaceKey: PublicKey): boolean {\n const haloSpace = this.#metadata.identity?.haloSpace;\n if (haloSpace?.key && requirePublicKey(haloSpace.key).equals(spaceKey)) {\n return true;\n }\n return !!this.spaces.find((space) => space.key && requirePublicKey(space.key).equals(spaceKey));\n }\n\n getIdentityRecord(): IdentityRecord | undefined {\n return this.#metadata.identity;\n }\n\n async setIdentityRecord(record: IdentityRecord): Promise<void> {\n invariant(!this.#metadata.identity, 'Cannot overwrite existing identity in metadata');\n this.#metadata.identity = record;\n await this._save();\n }\n\n getInvitations(): Invitation[] {\n return this.#metadata.invitations ?? [];\n }\n\n async addInvitation(invitation: Invitation): Promise<void> {\n if (this.#metadata.invitations?.find((i) => i.invitationId === invitation.invitationId)) {\n return;\n }\n (this.#metadata.invitations ??= []).push(invitation);\n await this._save();\n }\n\n async removeInvitation(invitationId: string): Promise<void> {\n this.#metadata.invitations = (this.#metadata.invitations ?? []).filter((i) => i.invitationId !== invitationId);\n await this._save();\n }\n\n async addSpace(record: SpaceMetadata): Promise<void> {\n invariant(record.key, 'Space metadata has no key.');\n invariant(!this.hasSpace(requirePublicKey(record.key)), 'Cannot overwrite existing space in metadata');\n (this.#metadata.spaces ??= []).push(record);\n await this._save();\n }\n\n async setSpaceDataLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void> {\n this.#getSpace(spaceKey).dataTimeframe = fromTimeframe(timeframe);\n await this._save();\n }\n\n async setSpaceControlLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe): Promise<void> {\n this.#getSpace(spaceKey).controlTimeframe = fromTimeframe(timeframe);\n await this._save();\n }\n\n async setWritableFeedKeys(spaceKey: PublicKey, controlFeedKey: PublicKey, dataFeedKey: PublicKey): Promise<void> {\n const space = this.#getSpace(spaceKey);\n space.controlFeedKey = fromPublicKey(controlFeedKey);\n space.dataFeedKey = fromPublicKey(dataFeedKey);\n await this._save();\n }\n\n async setSpaceState(spaceKey: PublicKey, state: SpaceState): Promise<void> {\n this.#getSpace(spaceKey).state = state;\n await this._save();\n }\n\n getSpaceControlPipelineSnapshot(spaceKey: PublicKey): ControlPipelineSnapshot | undefined {\n return this.#getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot;\n }\n\n async setSpaceControlPipelineSnapshot(spaceKey: PublicKey, snapshot: ControlPipelineSnapshot): Promise<void> {\n this.#getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot = snapshot;\n await this._saveSpaceLargeMetadata(spaceKey);\n }\n\n getSpaceEdgeReplicationSetting(spaceKey: PublicKey): EdgeReplicationSetting | undefined {\n return this.hasSpace(spaceKey) ? this.#getSpace(spaceKey).edgeReplication : undefined;\n }\n\n async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void> {\n this.#getSpace(spaceKey).edgeReplication = setting;\n await this._save();\n }\n\n get deletedSpaces(): PublicKey[] {\n return (this.#metadata.deletedSpaces ?? []).map(requirePublicKey);\n }\n\n async addDeletedSpace(spaceKey: PublicKey): Promise<void> {\n if (this.deletedSpaces.some((key) => key.equals(spaceKey))) {\n return;\n }\n (this.#metadata.deletedSpaces ??= []).push(fromPublicKey(spaceKey));\n await this._save();\n }\n\n async clear(): Promise<void> {\n log('clearing all metadata');\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`DELETE FROM space_metadata`;\n yield* sql`DELETE FROM space_large`;\n }),\n );\n this.#metadata = emptyEchoMetadata();\n this.#persisted = undefined;\n this.#spaceLargeMetadata.clear();\n }\n\n #getSpace(spaceKey: PublicKey): SpaceMetadata {\n const haloSpace = this.#metadata.identity?.haloSpace;\n if (haloSpace?.key && requirePublicKey(haloSpace.key).equals(spaceKey)) {\n return haloSpace;\n }\n const space = this.spaces.find((space) => space.key && requirePublicKey(space.key).equals(spaceKey));\n invariant(space, 'Space not found');\n return space;\n }\n\n #getLargeSpaceMetadata(key: PublicKey): LargeSpaceMetadata {\n let entry = this.#spaceLargeMetadata.get(key);\n if (!entry) {\n entry = emptyLargeSpaceMetadata();\n this.#spaceLargeMetadata.set(key, entry);\n }\n return entry;\n }\n\n @synchronized\n private async _save(): Promise<void> {\n const data: EchoMetadata = create(EchoMetadataSchema, {\n ...this.#metadata,\n version: STORAGE_VERSION,\n created: this.#metadata.created ?? fromDate(new Date()),\n updated: fromDate(new Date()),\n });\n this.update.emit(data);\n const content = withoutUpdated(data);\n if (this.#persisted && equals(EchoMetadataSchema, content, this.#persisted)) {\n return;\n }\n const encoded = this.#encodeWithCrc(EchoMetadataSchema, data);\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`INSERT OR REPLACE INTO space_metadata (key, value) VALUES (${MAIN_KEY}, ${encoded})`;\n }),\n );\n this.#persisted = content;\n }\n\n async #loadSpaceLargeMetadata(key: PublicKey): Promise<void> {\n const keyStr = largeKey(key);\n const rows = await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql<{ value: Uint8Array }>`SELECT value FROM space_large WHERE space_key = ${keyStr}`;\n }),\n );\n if (rows.length > 0) {\n try {\n const meta = this.#decodeWithCrc(rows[0].value, LargeSpaceMetadataSchema);\n if (meta) {\n this.#spaceLargeMetadata.set(key, meta);\n }\n } catch (err: any) {\n log.error('failed to decode large space metadata', { err });\n }\n }\n }\n\n @synchronized\n private async _saveSpaceLargeMetadata(key: PublicKey): Promise<void> {\n const data = this.#getLargeSpaceMetadata(key);\n const keyStr = largeKey(key);\n const encoded = this.#encodeWithCrc(LargeSpaceMetadataSchema, data);\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`INSERT OR REPLACE INTO space_large (space_key, value) VALUES (${keyStr}, ${encoded})`;\n }),\n );\n }\n\n /** Serialize with CRC32 checksum prefix for integrity checking (matches MetadataStore format). */\n #encodeWithCrc<T extends Message>(schema: GenMessage<T>, data: T): Buffer {\n const encoded = arrayToBuffer(toBinary(schema, data));\n const checksum = CRC32.buf(encoded);\n const result = Buffer.alloc(8 + encoded.length);\n result.writeInt32LE(encoded.length, 0);\n result.writeInt32LE(checksum, 4);\n encoded.copy(result, 8);\n return result;\n }\n\n /** Deserialize with CRC32 integrity check (matches MetadataStore format). */\n #decodeWithCrc<T extends Message>(data: Uint8Array, schema: GenMessage<T>): T | undefined {\n const buf = Buffer.from(data);\n if (buf.length < 8) {\n return undefined;\n }\n const dataSize = buf.readInt32LE(0);\n const checksum = buf.readInt32LE(4);\n if (dataSize < 0 || dataSize > buf.length - 8) {\n throw new DataCorruptionError({\n message: 'Metadata size header is invalid.',\n context: { fileLength: buf.length, dataSize },\n });\n }\n if (buf.length !== dataSize + 8) {\n throw new DataCorruptionError({\n message: 'Metadata payload length does not match framing header.',\n context: { fileLength: buf.length, dataSize },\n });\n }\n const payload = buf.subarray(8, dataSize + 8);\n const calculated = CRC32.buf(payload);\n if (calculated !== checksum) {\n throw new DataCorruptionError({ message: 'Metadata checksum is invalid.' });\n }\n return fromBinary(schema, payload);\n }\n}\n\n/**\n * Effect Layer constructing a {@link SqliteMetadataStore} from the ambient SQL runtime.\n */\nexport const SqliteMetadataStoreLayer = (): Layer.Layer<IMetadataStoreService, never, SqlClient.SqlClient> =>\n Layer.effect(\n IMetadataStoreService,\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n const store = new SqliteMetadataStore({ runtime });\n yield* Effect.addFinalizer(() => Effect.promise(() => store.close()));\n return store;\n }),\n );\n","//\n// Copyright 2019 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { runInContext, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { randomBytes } from '@dxos/crypto';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport {\n AuthenticateRequestSchema,\n AuthenticateResponseSchema,\n AuthService as AuthServiceDesc,\n} from '@dxos/protocols/buf/dxos/mesh/teleport/auth_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\n\nimport * as Auth from '../../Auth.ts';\n\ntype AuthService = BufService<typeof AuthServiceDesc>;\n\nexport type AuthExtensionProps = {\n provider: Auth.AuthProvider;\n verifier: Auth.AuthVerifier;\n onAuthSuccess: () => void;\n onAuthFailure: () => void;\n};\n\nexport class AuthExtension extends RpcExtension<Services, Services> {\n private readonly _ctx = new Context({\n onError: (err) => {\n log.catch(err);\n },\n });\n\n constructor(private readonly _authProps: AuthExtensionProps) {\n super({\n requested: {\n AuthService: getBufService<AuthService>('dxos.mesh.teleport.auth.AuthService'),\n },\n exposed: {\n AuthService: getBufService<AuthService>('dxos.mesh.teleport.auth.AuthService'),\n },\n timeout: 60 * 1000, // Long timeout because auth can wait for sync in certain cases.\n });\n }\n\n protected async getHandlers(): Promise<Services> {\n return {\n AuthService: {\n authenticate: async ({ challenge }) => {\n try {\n const credential = await this._authProps.provider(challenge);\n if (!credential) {\n throw new Error('auth rejected');\n }\n return create(AuthenticateResponseSchema, { credential });\n } catch (err) {\n log.error('failed to generate auth credentials', err);\n throw new Error('auth rejected');\n }\n },\n },\n };\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n await super.onOpen(context);\n scheduleTask(this._ctx, async () => {\n try {\n const challenge = randomBytes(32);\n const { credential } = await this.rpc.AuthService.authenticate(\n create(AuthenticateRequestSchema, { challenge }),\n );\n invariant(credential.length > 0, 'invalid credential');\n const success = await this._authProps.verifier(challenge, credential);\n invariant(success, 'credential not verified');\n runInContext(this._ctx, () => this._authProps.onAuthSuccess());\n } catch (err) {\n log('auth failed', err);\n this.close();\n this._authProps.onAuthFailure();\n }\n });\n }\n\n override async onClose(): Promise<void> {\n await this._ctx.dispose();\n await super.onClose();\n }\n\n override async onAbort(): Promise<void> {\n await this._ctx.dispose();\n await super.onAbort();\n }\n}\n\ntype Services = { AuthService: AuthService };\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { type HypercoreWriter } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type MaybePromise } from '@dxos/util';\n\n/**\n * Maps the written arguments onto a different message type.\n */\nexport const createMappedFeedWriter = <Source extends {}, Target extends {}>(\n mapper: (arg: Source) => MaybePromise<Target>,\n writer: HypercoreWriter<Target>,\n): HypercoreWriter<Source> => {\n invariant(mapper);\n invariant(writer);\n\n return {\n write: async (data: Source, options) => await writer.write(await mapper(data), options),\n };\n};\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { type HypercoreBlock, type HypercoreBlockSelector } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { toTimeframe } from '@dxos/protocols/buf';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\n\nimport { type TimeframeClock } from './timeframe-clock.ts';\n\n/**\n * The MessageSelector makes sure that we read in a trusted order.\n * The first message we wish to process is the SpaceGenesis, which will admit a Feed.\n * As we encounter and process FeedAdmit messages those are added to the Space's trust,\n * and we begin processing messages from them as well.\n */\nexport const createMessageSelector = (timeframeClock: TimeframeClock): HypercoreBlockSelector<FeedMessage> => {\n return (messages: HypercoreBlock<FeedMessage>[]) => {\n // Pick the first candidate with a valid timeframe that has no gaps.\n for (let i = 0; i < messages.length; i++) {\n const {\n data: { timeframe },\n } = messages[i];\n invariant(timeframe);\n\n if (!timeframeClock.hasGaps(toTimeframe(timeframe))) {\n return i;\n }\n }\n\n // Not ready for this message yet.\n log('Skipping...');\n };\n};\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { timed } from '@dxos/debug';\nimport { type HypercoreIndex } from '@dxos/feed-store';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { Timeframe } from '@dxos/timeframe';\n\nexport const mapTimeframeToFeedIndexes = (timeframe: Timeframe): HypercoreIndex[] =>\n timeframe.frames().map(([feedKey, index]) => ({ feedKey, index }));\n\nexport const mapFeedIndexesToTimeframe = (indexes: HypercoreIndex[]): Timeframe =>\n new Timeframe(indexes.map(({ feedKey, index }) => [feedKey, index]));\n\nexport const startAfter = (timeframe: Timeframe): HypercoreIndex[] =>\n timeframe.frames().map(([feedKey, index]) => ({ feedKey, index: index + 1 }));\n\n/**\n * Keeps state of the last timeframe that was processed by ECHO.\n */\nexport class TimeframeClock {\n readonly update = new Event<Timeframe>();\n\n private _pendingTimeframe: Timeframe;\n\n constructor(private _timeframe = new Timeframe()) {\n this._pendingTimeframe = _timeframe;\n }\n\n /**\n * Timeframe that was processed by ECHO.\n */\n get timeframe() {\n return this._timeframe;\n }\n\n /**\n * Timeframe that is currently being processed by ECHO.\n * Will be equal to `timeframe` after the processing is complete.\n */\n get pendingTimeframe() {\n return this._pendingTimeframe;\n }\n\n setTimeframe(timeframe: Timeframe): void {\n this._timeframe = timeframe;\n this._pendingTimeframe = timeframe;\n this.update.emit(this._timeframe);\n }\n\n updatePendingTimeframe(key: PublicKey, seq: number): void {\n this._pendingTimeframe = Timeframe.merge(this._pendingTimeframe, new Timeframe([[key, seq]]));\n }\n\n updateTimeframe(): void {\n this._timeframe = this._pendingTimeframe;\n this.update.emit(this._timeframe);\n }\n\n hasGaps(timeframe: Timeframe): boolean {\n const gaps = Timeframe.dependencies(timeframe, this._timeframe);\n return !gaps.isEmpty();\n }\n\n @timed(5_000)\n async waitUntilReached(target: Timeframe): Promise<void> {\n log('waitUntilReached', { target, current: this._timeframe });\n await this.update.waitForCondition(() => {\n log('check if reached', {\n target,\n current: this._timeframe,\n deps: Timeframe.dependencies(target, this._timeframe),\n });\n\n return Timeframe.dependencies(target, this._timeframe).isEmpty();\n });\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { Event, Trigger, sleepWithContext, synchronized } from '@dxos/async';\nimport { Context, rejectOnDispose } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { HypercoreSetIterator, type HypercoreWrapper, type HypercoreWriter } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type FeedMessageBlock } from '@dxos/protocols';\nimport { fromTimeframe } from '@dxos/protocols/buf';\nimport { type FeedMessage, type FeedMessage_Payload, FeedMessageSchema } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { Timeframe } from '@dxos/timeframe';\nimport { ComplexMap } from '@dxos/util';\n\nimport { createMappedFeedWriter } from './feeds.ts';\nimport { createMessageSelector } from './message-selector.ts';\nimport { TimeframeClock, mapFeedIndexesToTimeframe, startAfter } from './timeframe-clock.ts';\n\nexport type WaitUntilReachedTargetProps = {\n /**\n * For cancellation.\n */\n ctx?: Context;\n timeout?: number;\n\n /**\n * @default true\n */\n breakOnStall?: boolean;\n};\n\n/**\n * External state accessor.\n */\nexport class PipelineState {\n /**\n * @internal\n */\n _ctx = new Context();\n\n // TODO(dmaretskyi): Remove?. Avoid accessing `_timeframeClock` before constructor initialization.\n public get timeframeUpdate() {\n return this._timeframeClock.update;\n }\n\n public readonly stalled = new Event();\n\n /**\n * @internal\n */\n _startTimeframe: Timeframe = new Timeframe();\n\n /**\n * Target timeframe we are waiting to reach.\n */\n private _targetTimeframe: Timeframe | undefined;\n\n /**\n * @internal\n */\n _reachedTargetPromise: Promise<void> | undefined;\n\n /**\n * @internal\n */\n _reachedTarget: boolean = false;\n\n constructor(\n private _feeds: ComplexMap<PublicKey, HypercoreWrapper<FeedMessage>>,\n private _timeframeClock: TimeframeClock,\n ) {}\n\n /**\n * Latest theoretical timeframe based on the last mutation in each feed.\n * NOTE: This might never be reached if the mutation dependencies\n */\n // TODO(dmaretskyi): Rename `totalTimeframe`? or `lastTimeframe`.\n get endTimeframe() {\n return mapFeedIndexesToTimeframe(\n Array.from(this._feeds.values())\n .filter((feed) => feed.length > 0)\n .map((feed) => ({\n feedKey: feed.key,\n index: feed.length - 1,\n })),\n );\n }\n\n get startTimeframe() {\n return this._startTimeframe;\n }\n\n get timeframe() {\n return this._timeframeClock.timeframe;\n }\n\n get pendingTimeframe() {\n return this._timeframeClock.pendingTimeframe;\n }\n\n get targetTimeframe() {\n return this._targetTimeframe ? this._targetTimeframe : new Timeframe();\n }\n\n get reachedTarget() {\n return this._reachedTarget;\n }\n\n get feeds() {\n return Array.from(this._feeds.values());\n }\n\n async waitUntilTimeframe(target: Timeframe): Promise<void> {\n await this._timeframeClock.waitUntilReached(target);\n }\n\n setTargetTimeframe(target: Timeframe): void {\n this._targetTimeframe = target;\n }\n\n /**\n * Wait until the pipeline processes all messages in the feed and reaches the target timeframe if that is set.\n *\n * This function will resolve immediately if the pipeline is stalled.\n *\n * @param timeout Timeout in milliseconds to specify the maximum wait time.\n */\n async waitUntilReachedTargetTimeframe({\n ctx = new Context(),\n timeout,\n breakOnStall = true,\n }: WaitUntilReachedTargetProps = {}): Promise<void> {\n log('waitUntilReachedTargetTimeframe', {\n timeout,\n current: this.timeframe,\n target: this.targetTimeframe,\n });\n\n this._reachedTargetPromise ??= Promise.race([\n this._timeframeClock.update.waitForCondition(() => {\n return Timeframe.dependencies(this.targetTimeframe, this.timeframe).isEmpty();\n }),\n ...(breakOnStall ? [this.stalled.discardParameter().waitForCount(1)] : []),\n ]);\n\n let done = false;\n\n if (timeout) {\n return Promise.race([\n rejectOnDispose(ctx),\n rejectOnDispose(this._ctx),\n this._reachedTargetPromise.then(() => {\n done = true;\n this._reachedTarget = true;\n }),\n sleepWithContext(this._ctx, timeout).then(() => {\n if (done) {\n return;\n }\n\n log.warn('waitUntilReachedTargetTimeframe timed out', {\n timeout,\n current: this.timeframe,\n target: this.targetTimeframe,\n dependencies: Timeframe.dependencies(this.targetTimeframe, this.timeframe),\n });\n }),\n ]);\n } else {\n return this._reachedTargetPromise;\n }\n }\n}\n\n// TODO(mykola): Extract to `@dxos/echo-protocol`\nexport interface PipelineAccessor {\n state: PipelineState;\n writer: HypercoreWriter<FeedMessage_Payload>;\n}\n\n/**\n * A multi-reader pipeline that operates on feeds.\n * Might have a single writable feed.\n * Has a timeframe clock to handle message ordering.\n *\n * NOTE:\n * - Feeds passed in must have value encoding consistent with the type expected by the iterator/writer.\n *\n * # Usage examples\n *\n * ## Create a new space.\n *\n * 1. Generate space key, genesis feed key.\n * 2. Create and open pipeline reading from {}.\n * 3. Create and add the writable genesis feed.\n * 4. Write the initial sequence of control and credential messages.\n *\n * ## Load an existing space from storage\n *\n * 1. Load space key, genesis feed key, get starting timeframe from saved snapshot.\n * 2. Create and open pipeline reading from the initial timeframe.\n * 3. Open and add the genesis feed.\n * 4. Once the writable feed is added, the pipeline becomes writable.\n *\n * ## Join an existing space created by another agent/device.\n *\n * 1. Get the space key, genesis feed key from another agent.\n * 2. (optionally) Download the snapshot from another agent.\n * 3. Create and open pipeline.\n * 4. Generate the writable feed key.\n * 5. Wait for the writable feed to be added.\n */\nexport class Pipeline implements PipelineAccessor {\n private readonly _timeframeClock = new TimeframeClock(new Timeframe());\n private readonly _feeds = new ComplexMap<PublicKey, HypercoreWrapper<FeedMessage>>(PublicKey.hash);\n\n // External state accessor.\n private readonly _state: PipelineState = new PipelineState(this._feeds, this._timeframeClock);\n\n // Waits for the message consumer to process the message and yield control back to the pipeline.\n private readonly _processingTrigger = new Trigger().wake();\n private readonly _pauseTrigger = new Trigger().wake();\n\n // Pending downloads.\n private readonly _downloads = new ComplexMap<HypercoreWrapper<FeedMessage>, any>((value) =>\n PublicKey.hash(value.key),\n );\n\n // Inbound feed stream.\n private _feedSetIterator?: HypercoreSetIterator<FeedMessage>;\n\n // Woken (and re-armed) each time `_initIterator` swaps the iterator, so a consumer parked on a\n // finished generator of the previous instance can move to the new one.\n private _iteratorChanged = new Trigger();\n\n // Outbound feed writer.\n private _writer: HypercoreWriter<FeedMessage_Payload> | undefined;\n\n private _isStopping = false;\n private _isStarted = false;\n private _isBeingConsumed = false;\n private _isPaused = false;\n\n get state() {\n return this._state;\n }\n\n get writer(): HypercoreWriter<FeedMessage_Payload> {\n invariant(this._writer, 'Writer not set.');\n return this._writer;\n }\n\n /**\n * Whether the hypercore is part of this pipeline.\n */\n hasHypercore(feedKey: PublicKey): boolean {\n return this._feeds.has(feedKey);\n }\n\n getFeeds(): HypercoreWrapper<FeedMessage>[] {\n return this._feedSetIterator!.feeds;\n }\n\n // NOTE: This cannot be synchronized with `stop` because stop waits for the mutation processing to complete,\n // which might be opening feeds during the mutation processing, which w\n async addHypercore(feed: HypercoreWrapper<FeedMessage>): Promise<void> {\n this._feeds.set(feed.key, feed);\n\n if (this._feedSetIterator && !this._feedSetIterator.hasHypercore(feed.key)) {\n await this._feedSetIterator.addHypercore(feed);\n }\n\n if (this._isStarted && !this._isPaused) {\n this._setFeedDownloadState(feed);\n }\n }\n\n setWriteFeed(feed: HypercoreWrapper<FeedMessage>): void {\n invariant(!this._writer, 'Writer already set.');\n invariant(feed.properties.writable, 'Feed must be writable.');\n\n this._writer = createMappedFeedWriter<FeedMessage_Payload, FeedMessage>(\n (payload: FeedMessage_Payload) =>\n create(FeedMessageSchema, { timeframe: fromTimeframe(this._timeframeClock.timeframe), payload }),\n feed.createHypercoreWriter(),\n );\n }\n\n @synchronized\n async start(): Promise<void> {\n invariant(!this._isStarted, 'Pipeline is already started.');\n log('starting...');\n await this._initIterator();\n await this._feedSetIterator!.open();\n this._isStarted = true;\n log('started');\n\n if (!this._isPaused) {\n for (const feed of this._feeds.values()) {\n this._setFeedDownloadState(feed);\n }\n }\n }\n\n @synchronized\n async stop(): Promise<void> {\n log('stopping...');\n this._isStopping = true;\n for (const [feed, handle] of this._downloads.entries()) {\n feed.undownload(handle);\n }\n this._downloads.clear();\n await this._feedSetIterator?.close();\n await this._processingTrigger.wait(); // Wait for the in-flight message to be processed.\n await this._state._ctx.dispose();\n this._state._ctx = new Context();\n this._state._reachedTargetPromise = undefined;\n this._state._reachedTarget = false;\n this._isStarted = false;\n log('stopped');\n }\n\n /**\n * @param timeframe Timeframe of already processed messages.\n * The pipeline will start processing messages AFTER this timeframe.\n */\n @synchronized\n async setCursor(timeframe: Timeframe): Promise<void> {\n invariant(!this._isStarted || this._isPaused, 'Invalid state.');\n\n this._state._startTimeframe = timeframe;\n this._timeframeClock.setTimeframe(timeframe);\n\n // Cancel downloads of mutations before the cursor.\n if (this._feedSetIterator) {\n await this._feedSetIterator.close();\n await this._initIterator();\n await this._feedSetIterator.open();\n }\n }\n\n /**\n * Calling pause while processing will cause a deadlock.\n */\n @synchronized\n async pause(): Promise<void> {\n if (this._isPaused) {\n return;\n }\n\n this._pauseTrigger.reset();\n await this._processingTrigger.wait();\n this._isPaused = true;\n }\n\n @synchronized\n async unpause(): Promise<void> {\n invariant(this._isPaused, 'Pipeline is not paused.');\n\n this._pauseTrigger.wake();\n this._isPaused = false;\n\n for (const feed of this._feeds.values()) {\n this._setFeedDownloadState(feed);\n }\n }\n\n /**\n * Starts to iterate over the ordered messages from the added feeds.\n * Updates the timeframe clock after the message has bee processed.\n */\n async *consume(): AsyncIterable<FeedMessageBlock> {\n invariant(!this._isBeingConsumed, 'Pipeline is already being consumed.');\n this._isBeingConsumed = true;\n\n invariant(this._feedSetIterator, 'Iterator not initialized.');\n let lastFeedSetIterator = this._feedSetIterator;\n let iterable = lastFeedSetIterator[Symbol.asyncIterator]();\n\n // Iteration counter to make a busy loop visible in debug logs.\n let iteration = 0;\n while (!this._isStopping) {\n iteration += 1;\n log('consume iteration', { iteration });\n await this._pauseTrigger.wait();\n\n // Iterator might have been changed while we were waiting for the processing to complete.\n if (lastFeedSetIterator !== this._feedSetIterator) {\n log('consume: iterator changed while paused', { iteration });\n invariant(this._feedSetIterator, 'Iterator not initialized.');\n lastFeedSetIterator = this._feedSetIterator;\n iterable = lastFeedSetIterator[Symbol.asyncIterator]();\n }\n\n // Will be canceled when the iterator gets closed.\n const { done, value } = await iterable.next();\n if (!done) {\n const block = value ?? failUndefined();\n log('consume block', { iteration, feedKey: PublicKey.from(block.feedKey).truncate(), seq: block.seq });\n this._processingTrigger.reset();\n this._timeframeClock.updatePendingTimeframe(PublicKey.from(block.feedKey), block.seq);\n yield block;\n this._processingTrigger.wake();\n this._timeframeClock.updateTimeframe();\n } else if (!this._isStopping) {\n // The generator ended while the pipeline is not stopping: it was obtained before `start()`\n // set the iterator running, or the iterator is being swapped by `setCursor`. Polling the\n // finished generator would spin the microtask queue forever (starving the whole thread),\n // so wait for the iterator to (re)start or be replaced, then take a fresh generator.\n log('consume: generator ended; waiting for iterator restart or swap', { iteration });\n if (lastFeedSetIterator === this._feedSetIterator) {\n await Promise.race([lastFeedSetIterator.waitUntilRunning(), this._iteratorChanged.wait()]);\n }\n invariant(this._feedSetIterator, 'Iterator not initialized.');\n lastFeedSetIterator = this._feedSetIterator;\n iterable = lastFeedSetIterator[Symbol.asyncIterator]();\n log('consume: resuming with fresh generator', { iteration });\n }\n }\n log('consume: stopped', { iteration });\n\n // TODO(burdon): Test re-entrant?\n this._isBeingConsumed = false;\n }\n\n private _setFeedDownloadState(feed: HypercoreWrapper<FeedMessage>): void {\n let handle = this._downloads.get(feed); // TODO(burdon): Always undefined?\n if (handle) {\n feed.undownload(handle);\n }\n\n const timeframe = this._state._startTimeframe;\n const seq = timeframe.get(feed.key) ?? -1;\n log('download', { feed: feed.key.truncate(), seq, length: feed.length });\n handle = feed.download({ start: seq + 1, linear: true }, (err: any, data: any) => {\n if (err) {\n // log.warn(err); // TODO(burdon): Feed is closed/Download was cancelled.\n } else {\n log('downloaded', { data }); // TODO(burdon): Never called.\n }\n });\n\n this._downloads.set(feed, handle);\n }\n\n private async _initIterator(): Promise<void> {\n this._feedSetIterator = new HypercoreSetIterator<FeedMessage>(createMessageSelector(this._timeframeClock), {\n start: startAfter(this._timeframeClock.timeframe),\n stallTimeout: 1000,\n });\n\n {\n // Wake consumers parked on the previous iterator's finished generator; re-arm for the next swap.\n const changed = this._iteratorChanged;\n this._iteratorChanged = new Trigger();\n changed.wake();\n }\n\n this._feedSetIterator.stalled.on((iterator) => {\n log.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, {\n currentTimeframe: this._timeframeClock.timeframe,\n targetTimeframe: this._state.targetTimeframe,\n });\n this._state.stalled.emit();\n });\n\n for (const feed of this._feeds.values()) {\n // A concurrent `addHypercore` (e.g. a feed admission processed during startup) may have already\n // registered this feed on the new iterator, whose `addHypercore` throws on duplicates.\n if (!this._feedSetIterator.hasHypercore(feed.key)) {\n await this._feedSetIterator.addHypercore(feed);\n }\n }\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { fromBinary, toBinary } from '@bufbuild/protobuf';\n\nimport { type ValueCodec, createCodecEncoding } from '@dxos/hypercore';\nimport { type FeedMessage, FeedMessageSchema } from '@dxos/protocols/buf/dxos/echo/feed_pb';\n\n/**\n * Codec for feed messages.\n */\nexport const codec: ValueCodec<FeedMessage> = {\n encode: (value) => toBinary(FeedMessageSchema, value),\n decode: (buffer) => fromBinary(FeedMessageSchema, buffer),\n};\n\n/**\n * Value encoding used by feed store.\n */\nexport const valueEncoding = createCodecEncoding(codec);\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { DeferredTask, scheduleMicroTask, sleepWithContext, trackLeaks } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport {\n type DelegateInvitationCredential,\n type FeedInfo,\n type MemberInfo,\n type SpaceState,\n SpaceStateMachine,\n} from '@dxos/credentials';\nimport { type HypercoreWrapper } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type FeedMessageBlock } from '@dxos/protocols';\nimport { fromPublicKey, fromTimeframe, requirePublicKey, toTimeframe } from '@dxos/protocols/buf';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport {\n type ControlPipelineSnapshot,\n ControlPipelineSnapshot_ControlMessageSchema,\n ControlPipelineSnapshotSchema,\n} from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { AdmittedFeed_Designation, type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { Timeframe } from '@dxos/timeframe';\nimport { trace } from '@dxos/tracing';\nimport { type AsyncCallback, Callback, tracer } from '@dxos/util';\n\nimport { type IMetadataStore } from '../metadata/index.ts';\nimport { Pipeline, type PipelineAccessor } from '../pipeline/index.ts';\n\nexport type ControlPipelineProps = {\n spaceKey: PublicKey;\n genesisFeed: HypercoreWrapper<FeedMessage>;\n feedProvider: (feedKey: PublicKey) => Promise<HypercoreWrapper<FeedMessage>>;\n metadataStore: IMetadataStore;\n};\n\nconst TIMEFRAME_SAVE_DEBOUNCE_INTERVAL = 500;\n\nconst CONTROL_PIPELINE_SNAPSHOT_DELAY = 10_000;\n\nconst USE_SNAPSHOTS = true;\n\n/**\n * Processes HALO credentials, which include genesis and invitations.\n */\n@trackLeaks('start', 'stop')\nexport class ControlPipeline {\n private readonly _ctx = new Context();\n private readonly _pipeline: Pipeline;\n private readonly _spaceStateMachine: SpaceStateMachine;\n\n private readonly _spaceKey: PublicKey;\n private readonly _metadata: IMetadataStore;\n private _targetTimeframe?: Timeframe;\n private _lastTimeframeSaveTime: number = Date.now();\n\n public readonly onFeedAdmitted = new Callback<AsyncCallback<FeedInfo>>();\n public readonly onMemberRoleChanged: Callback<AsyncCallback<MemberInfo[]>>;\n public readonly onCredentialProcessed: Callback<AsyncCallback<Credential>>;\n public readonly onDelegatedInvitation: Callback<AsyncCallback<DelegateInvitationCredential>>;\n public readonly onDelegatedInvitationRemoved: Callback<AsyncCallback<DelegateInvitationCredential>>;\n\n private _snapshotTask = new DeferredTask(this._ctx, async () => {\n await sleepWithContext(this._ctx, CONTROL_PIPELINE_SNAPSHOT_DELAY);\n await this._saveSnapshot();\n });\n\n constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }: ControlPipelineProps) {\n this._spaceKey = spaceKey;\n this._metadata = metadataStore;\n this._pipeline = new Pipeline();\n void this._pipeline.addHypercore(genesisFeed); // TODO(burdon): Require async open/close?\n\n this._spaceStateMachine = new SpaceStateMachine(spaceKey);\n this._spaceStateMachine.onFeedAdmitted.set(async (info) => {\n // log('feed admitted', { info });\n log('feed admitted', { key: info.key });\n\n // TODO(burdon): Check not stopping.\n if (info.assertion.designation === AdmittedFeed_Designation.CONTROL && !info.key.equals(genesisFeed.key)) {\n scheduleMicroTask(this._ctx, async () => {\n try {\n const feed = await feedProvider(info.key);\n if (this._ctx.disposed) {\n return;\n }\n if (!this._pipeline.hasHypercore(feed.key)) {\n await this._pipeline.addHypercore(feed);\n }\n } catch (err: any) {\n log.catch(err);\n }\n });\n }\n\n await this.onFeedAdmitted.callIfSet(info);\n });\n\n this.onMemberRoleChanged = this._spaceStateMachine.onMemberRoleChanged;\n this.onCredentialProcessed = this._spaceStateMachine.onCredentialProcessed;\n this.onDelegatedInvitation = this._spaceStateMachine.onDelegatedInvitation;\n this.onDelegatedInvitationRemoved = this._spaceStateMachine.onDelegatedInvitationRemoved;\n }\n\n get spaceState(): SpaceState {\n return this._spaceStateMachine;\n }\n\n /**\n * Feeds a credential that came from the space's credentials document rather than a feed. Processing\n * is idempotent by credential id, so a credential the feed already delivered is a no-op — which is\n * what lets both sources run during the migration window.\n */\n async processDocumentCredential(credential: Credential): Promise<boolean> {\n return this._spaceStateMachine.process(credential, {});\n }\n\n get pipeline(): PipelineAccessor {\n return this._pipeline;\n }\n\n async setWriteFeed(feed: HypercoreWrapper<FeedMessage>): Promise<void> {\n await this._pipeline.addHypercore(feed);\n this._pipeline.setWriteFeed(feed);\n }\n\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async start(ctx: Context): Promise<void> {\n const snapshot = this._metadata.getSpaceControlPipelineSnapshot(this._spaceKey);\n log('load snapshot', { key: this._spaceKey, present: !!snapshot, tf: snapshot?.timeframe });\n if (USE_SNAPSHOTS && snapshot) {\n await this._processSnapshot(snapshot);\n }\n\n log('starting...');\n await this._pipeline.start();\n // Started strictly after `pipeline.start()`: a consumer that races the start can obtain the\n // iterator's generator before it is running — the generator then finishes immediately and\n // polling it spins the microtask queue, starving the thread (boot wedge).\n setTimeout(async () => {\n void this._consumePipeline(ctx);\n });\n log('started');\n }\n\n private async _processSnapshot(snapshot: ControlPipelineSnapshot): Promise<void> {\n await this._pipeline.setCursor(toTimeframe(snapshot.timeframe));\n\n for (const message of snapshot.messages ?? []) {\n invariant(message.credential, 'Snapshot entry carries no credential.');\n const result = await this._spaceStateMachine.process(message.credential, {\n sourceFeed: requirePublicKey(message.feedKey),\n skipVerification: true,\n });\n\n if (!result) {\n log.warn('credential processing failed from snapshot', { message });\n }\n }\n }\n\n private async _saveSnapshot(): Promise<void> {\n await this._pipeline.pause();\n const snapshot: ControlPipelineSnapshot = create(ControlPipelineSnapshotSchema, {\n timeframe: fromTimeframe(this._pipeline.state.timeframe),\n // A snapshot replays into the feed pipeline, so an entry with no source feed has no place in it.\n messages: this._spaceStateMachine.credentialEntries.flatMap((entry) =>\n entry.sourceFeed\n ? [\n create(ControlPipelineSnapshot_ControlMessageSchema, {\n feedKey: fromPublicKey(entry.sourceFeed),\n credential: entry.credential,\n }),\n ]\n : [],\n ),\n });\n await this._pipeline.unpause();\n\n log('save snapshot', { key: this._spaceKey, snapshot: getSnapshotLoggerContext(snapshot) });\n await this._metadata.setSpaceControlPipelineSnapshot(this._spaceKey, snapshot);\n }\n\n private async _consumePipeline(ctx: Context): Promise<void> {\n for await (const msg of this._pipeline.consume()) {\n try {\n await this._processMessage(ctx, msg);\n } catch (err: any) {\n log.catch(err);\n }\n }\n }\n\n @trace.span({ showInBrowserTimeline: true, showInRemoteTracing: false })\n private async _processMessage(ctx: Context, msg: FeedMessageBlock): Promise<void> {\n log('processing', { key: msg.feedKey, seq: msg.seq });\n if (msg.data.payload?.payload.case === 'credential') {\n const credential = msg.data.payload.payload.value.credential;\n invariant(credential, 'Credentials message is empty.');\n const timer = tracer.mark('dxos.echo.pipeline.control');\n const result = await this._spaceStateMachine.process(credential, {\n sourceFeed: PublicKey.from(msg.feedKey),\n });\n\n timer.end();\n if (!result) {\n log.warn('processing failed', { msg });\n } else {\n await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);\n }\n\n this._snapshotTask.schedule();\n }\n }\n\n private async _noteTargetStateIfNeeded(timeframe: Timeframe): Promise<void> {\n // TODO(dmaretskyi): Replace this with a proper debounce/throttle.\n\n if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL) {\n this._lastTimeframeSaveTime = Date.now();\n\n await this._saveTargetTimeframe(timeframe);\n }\n }\n\n async stop(): Promise<void> {\n log('stopping...');\n await this._ctx.dispose();\n await this._pipeline.stop();\n await this._saveTargetTimeframe(this._pipeline.state.timeframe);\n log('stopped');\n }\n\n private async _saveTargetTimeframe(timeframe: Timeframe): Promise<void> {\n try {\n const newTimeframe = Timeframe.merge(this._targetTimeframe ?? new Timeframe(), timeframe);\n await this._metadata.setSpaceControlLatestTimeframe(this._spaceKey, newTimeframe);\n this._targetTimeframe = newTimeframe;\n } catch (err: any) {\n log(err);\n }\n }\n}\n\nconst getSnapshotLoggerContext = (snapshot: ControlPipelineSnapshot) => {\n return snapshot.messages?.map((msg) => ({\n issuer: msg.credential?.issuer,\n subject: msg.credential?.subject?.id,\n type: msg.credential?.subject?.assertion?.typeUrl,\n }));\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { Event, scheduleMicroTask, synchronized, trackLeaks } from '@dxos/async';\nimport { type Context, Resource } from '@dxos/context';\nimport { type DelegateInvitationCredential, type FeedInfo, type MemberInfo } from '@dxos/credentials';\nimport { type HypercoreCreateOptions, type HypercoreWrapper } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { AdmittedFeed_Designation, type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type Timeframe } from '@dxos/timeframe';\nimport { trace } from '@dxos/tracing';\nimport { type AsyncCallback, Callback } from '@dxos/util';\n\nimport { type IMetadataStore } from '../metadata/index.ts';\nimport { type PipelineAccessor } from '../pipeline/index.ts';\nimport { ControlPipeline } from './control-pipeline.ts';\nimport { type SpaceProtocol } from './space-protocol.ts';\n\n// TODO(burdon): Factor out?\ntype FeedProvider = (feedKey: PublicKey, opts?: HypercoreCreateOptions) => Promise<HypercoreWrapper<FeedMessage>>;\n\nexport type SpaceProps = {\n id: SpaceId;\n spaceKey: PublicKey;\n protocol: SpaceProtocol;\n genesisFeed: HypercoreWrapper<FeedMessage>;\n feedProvider: FeedProvider;\n metadataStore: IMetadataStore;\n memberKey: PublicKey;\n\n // TODO(dmaretskyi): Superseded by epochs.\n snapshotId?: string | undefined;\n\n onDelegatedInvitationStatusChange: (invitation: DelegateInvitationCredential, isActive: boolean) => Promise<void>;\n onMemberRolesChanged: (member: MemberInfo[]) => Promise<void>;\n};\n\nexport type CreatePipelineProps = {\n start: Timeframe;\n // designation: AdmittedFeed.Designation;\n};\n\n/**\n * Spaces are globally addressable databases with access control.\n */\n// TODO(dmaretskyi): Extract database stuff.\n// TODO(dmaretskyi): Rename HaloGraph move to HALO.\n@trackLeaks('open', 'close')\nexport class Space extends Resource {\n public readonly onCredentialProcessed = new Callback<AsyncCallback<Credential>>();\n\n /** Multi-subscriber counterpart to {@link onCredentialProcessed}, which holds a single handler. */\n public readonly credentialProcessed = new Event<Credential>();\n public readonly stateUpdate = new Event();\n public readonly protocol: SpaceProtocol;\n\n private readonly _id: SpaceId;\n private readonly _key: PublicKey;\n private readonly _genesisFeedKey: PublicKey;\n private readonly _feedProvider: FeedProvider;\n private readonly _controlPipeline: ControlPipeline;\n\n private _controlFeed?: HypercoreWrapper<FeedMessage>;\n private _dataFeed?: HypercoreWrapper<FeedMessage>;\n\n constructor(params: SpaceProps) {\n super();\n invariant(params.spaceKey && params.feedProvider);\n this._id = params.id;\n this._key = params.spaceKey;\n this._genesisFeedKey = params.genesisFeed.key;\n this._feedProvider = params.feedProvider;\n\n this._controlPipeline = new ControlPipeline({\n spaceKey: params.spaceKey,\n genesisFeed: params.genesisFeed,\n feedProvider: params.feedProvider,\n metadataStore: params.metadataStore,\n });\n\n // TODO(dmaretskyi): Feed set abstraction.\n this._controlPipeline.onFeedAdmitted.set(async (info) => {\n // Enable sparse replication to not download mutations covered by prior epochs.\n const sparse = info.assertion.designation === AdmittedFeed_Designation.DATA;\n\n if (!info.key.equals(params.genesisFeed.key)) {\n scheduleMicroTask(this._ctx, async () => {\n await this.protocol.addHypercore(await params.feedProvider(info.key, { sparse }));\n });\n }\n });\n\n this._controlPipeline.onCredentialProcessed.set(async (credential) => {\n await this.onCredentialProcessed.callIfSet(credential);\n this.credentialProcessed.emit(credential);\n log('onCredentialProcessed', { credential });\n this.stateUpdate.emit();\n });\n this._controlPipeline.onDelegatedInvitation.set(async (invitation) => {\n log('onDelegatedInvitation', { invitation });\n await params.onDelegatedInvitationStatusChange(invitation, true);\n });\n this._controlPipeline.onDelegatedInvitationRemoved.set(async (invitation) => {\n log('onDelegatedInvitationRemoved', { invitation });\n await params.onDelegatedInvitationStatusChange(invitation, false);\n });\n this._controlPipeline.onMemberRoleChanged.set(async (changedMembers) => {\n log('onMemberRoleChanged', () => ({ changedMembers: changedMembers.map((m) => [m.key, m.role]) }));\n await params.onMemberRolesChanged(changedMembers);\n });\n\n // Start replicating the genesis feed.\n this.protocol = params.protocol;\n }\n\n @logInfo\n get id() {\n return this._id;\n }\n\n @logInfo\n get key() {\n return this._key;\n }\n\n get genesisFeedKey(): PublicKey {\n return this._genesisFeedKey;\n }\n\n get controlFeedKey() {\n return this._controlFeed?.key;\n }\n\n get dataFeedKey() {\n return this._dataFeed?.key;\n }\n\n get spaceState() {\n return this._controlPipeline.spaceState;\n }\n\n /** @see ControlPipeline.processDocumentCredential */\n async processDocumentCredential(credential: Credential): Promise<boolean> {\n return this._controlPipeline.processDocumentCredential(credential);\n }\n\n /**\n * @test-only\n */\n get controlPipeline(): PipelineAccessor {\n return this._controlPipeline.pipeline;\n }\n\n async setControlFeed(feed: HypercoreWrapper<FeedMessage>): Promise<this> {\n invariant(!this._controlFeed, 'Control feed already set.');\n this._controlFeed = feed;\n await this._controlPipeline.setWriteFeed(feed);\n return this;\n }\n\n async setDataFeed(feed: HypercoreWrapper<FeedMessage>): Promise<this> {\n invariant(!this._dataFeed, 'Data feed already set.');\n this._dataFeed = feed;\n return this;\n }\n\n /**\n * Use for diagnostics.\n */\n getControlFeeds(): FeedInfo[] {\n return Array.from(this._controlPipeline.spaceState.feeds.values());\n }\n\n @trace.span({ op: 'lifecycle' })\n protected override async _open(ctx: Context): Promise<void> {\n log('opening...');\n\n // Order is important.\n await this._controlPipeline.start(ctx);\n\n log('opened');\n }\n\n @synchronized\n public async startProtocol(ctx: Context): Promise<void> {\n invariant(this.isOpen);\n await this.protocol.start(ctx);\n await this.protocol.addHypercore(await this._feedProvider(this._genesisFeedKey));\n }\n\n @synchronized\n protected override async _close(ctx: Context): Promise<void> {\n log('closing...', { key: this._key });\n\n // Closes in reverse order to open.\n await this.protocol.stop(ctx);\n await this._controlPipeline.stop();\n\n log('closed');\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { type Trigger, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { ProtocolError } from '@dxos/protocols';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport { type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n AdmissionDiscoveryService as AdmissionDiscoveryServiceDesc,\n type GetAdmissionCredentialRequest,\n type GetAdmissionCredentialResponse,\n GetAdmissionCredentialResponseSchema,\n} from '@dxos/protocols/buf/dxos/mesh/teleport/admission-discovery_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\n\ntype AdmissionDiscoveryService = BufService<typeof AdmissionDiscoveryServiceDesc>;\n\nimport { type Space } from './space.ts';\n\n/**\n * Guest's side for a connection to a concrete peer in p2p network during invitation.\n */\nexport class CredentialRetrieverExtension extends RpcExtension<\n { AdmissionDiscoveryService: AdmissionDiscoveryService },\n {}\n> {\n private _ctx = new Context();\n\n constructor(\n private readonly _request: GetAdmissionCredentialRequest,\n private readonly _onResult: Trigger<Credential>,\n ) {\n super({\n requested: {\n AdmissionDiscoveryService: getBufService<AdmissionDiscoveryService>(\n 'dxos.mesh.teleport.AdmissionDiscoveryService',\n ),\n },\n });\n }\n\n protected override async getHandlers(): Promise<{}> {\n return {};\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n await super.onOpen(context);\n scheduleTask(this._ctx, async () => {\n try {\n const result = await this.rpc.AdmissionDiscoveryService.getAdmissionCredential(this._request);\n invariant(result.admissionCredential, 'Admission response carries no credential.');\n this._onResult.wake(result.admissionCredential);\n } catch (err: any) {\n context.close(err);\n }\n });\n }\n\n override async onClose(): Promise<void> {\n await this._ctx.dispose();\n }\n\n override async onAbort(): Promise<void> {\n await this._ctx.dispose();\n }\n}\n\nexport class CredentialServerExtension extends RpcExtension<\n {},\n { AdmissionDiscoveryService: AdmissionDiscoveryService }\n> {\n constructor(private readonly _space: Space) {\n super({\n exposed: {\n AdmissionDiscoveryService: getBufService<AdmissionDiscoveryService>(\n 'dxos.mesh.teleport.AdmissionDiscoveryService',\n ),\n },\n });\n }\n\n protected override async getHandlers(): Promise<{ AdmissionDiscoveryService: AdmissionDiscoveryService }> {\n return {\n AdmissionDiscoveryService: {\n getAdmissionCredential: async (\n request: GetAdmissionCredentialRequest,\n ): Promise<GetAdmissionCredentialResponse> => {\n const memberInfo = this._space.spaceState.members.get(requirePublicKey(request.memberKey));\n if (!memberInfo?.credential) {\n throw new ProtocolError({ message: 'Space member not found.', context: { ...request } });\n }\n return create(GetAdmissionCredentialResponseSchema, { admissionCredential: memberInfo.credential });\n },\n },\n };\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { type Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { createIdFromSpaceKey } from '@dxos/echo-protocol';\nimport { type HypercoreWrapper } from '@dxos/feed-store';\nimport { PublicKey, SpaceId } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport {\n MMSTTopology,\n type SwarmConnection,\n type SwarmNetworkManager,\n type WireProtocol,\n type WireProtocolProps,\n type WireProtocolProvider,\n} from '@dxos/network-manager';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { type MuxerStats, Teleport } from '@dxos/teleport';\nimport { ReplicatorExtension } from '@dxos/teleport-extension-replicator';\nimport { type AsyncCallback, CallbackCollection, ComplexMap } from '@dxos/util';\n\nimport * as Auth from '../../Auth.ts';\nimport { AuthExtension } from './auth.ts';\n\nexport const MOCK_AUTH_PROVIDER: Auth.AuthProvider = async (nonce: Uint8Array) => Buffer.from('mock');\nexport const MOCK_AUTH_VERIFIER: Auth.AuthVerifier = async (nonce: Uint8Array, credential: Uint8Array) => true;\n\n// TODO(burdon): Reconcile with SigningContext (define types together).\nexport interface SwarmIdentity {\n peerKey: PublicKey;\n identityKey: PublicKey;\n credentialProvider: Auth.AuthProvider;\n credentialAuthenticator: Auth.AuthVerifier;\n}\n\nexport type SpaceProtocolOptions = {\n topic: PublicKey; // TODO(burdon): Rename?\n swarmIdentity: SwarmIdentity;\n networkManager: SwarmNetworkManager;\n\n onFeed?: (feed: HypercoreWrapper<FeedMessage>) => Promise<void>;\n\n /**\n * Called when new session is authenticated.\n * Additional extensions can be added here.\n */\n onSessionAuth?: (session: Teleport) => void;\n onAuthFailure?: (session: Teleport) => void;\n\n disableP2pReplication?: boolean;\n};\n\n/**\n * Manages Teleport protocol stream creation and joining swarms with replication and presence extensions.\n */\nexport class SpaceProtocol {\n private readonly _networkManager: SwarmNetworkManager;\n private readonly _swarmIdentity: SwarmIdentity;\n private readonly _onSessionAuth?: (session: Teleport) => void;\n private readonly _onAuthFailure?: (session: Teleport) => void;\n\n private readonly _disableP2pReplication: boolean;\n\n @logInfo\n private readonly _topic: Promise<PublicKey>;\n\n private readonly _spaceKey: PublicKey;\n\n private readonly _feeds = new Set<HypercoreWrapper<FeedMessage>>();\n private readonly _sessions = new ComplexMap<PublicKey, SpaceProtocolSession>(PublicKey.hash);\n // TODO(burdon): Move to config (with sensible defaults).\n private readonly _topology = new MMSTTopology({\n originateConnections: 4,\n maxPeers: 10,\n sampleSize: 20,\n });\n\n private _connection?: SwarmConnection;\n\n public readonly feedAdded = new CallbackCollection<AsyncCallback<HypercoreWrapper<FeedMessage>>>();\n\n get sessions(): ReadonlyMap<PublicKey, SpaceProtocolSession> {\n return this._sessions;\n }\n\n get feeds(): ReadonlySet<HypercoreWrapper<FeedMessage>> {\n return this._feeds;\n }\n\n @logInfo\n private get _ownPeerKey() {\n return this._swarmIdentity.peerKey;\n }\n\n constructor({\n topic,\n swarmIdentity,\n networkManager,\n onSessionAuth,\n onAuthFailure,\n disableP2pReplication,\n }: SpaceProtocolOptions) {\n this._spaceKey = topic;\n this._networkManager = networkManager;\n this._swarmIdentity = swarmIdentity;\n this._onSessionAuth = onSessionAuth;\n this._onAuthFailure = onAuthFailure;\n\n // Space swarm topic contract (DX-1125): the SpaceId bytes (first 20 bytes of SHA-256(spaceKey)).\n // Both peers and the edge must derive the identical swarm key; SpaceId is the only derivation\n // computable on workerd (pure subtle-crypto — the previous hypercore `discoveryKey` needs keyed\n // BLAKE2b, unavailable there). Edge counterpart: `TraceFeedWriter.getSpaceSwarmKey`.\n this._topic = createIdFromSpaceKey(topic).then((spaceId) => PublicKey.from(SpaceId.decode(spaceId)));\n\n this._disableP2pReplication = disableP2pReplication ?? false;\n }\n\n // TODO(burdon): Create abstraction for Space (e.g., add keys and have provider).\n async addHypercore(feed: HypercoreWrapper<FeedMessage>): Promise<void> {\n log('addHypercore', { key: feed.key });\n\n this._feeds.add(feed);\n for (const session of this._sessions.values()) {\n session.replicator.addHypercore(feed);\n }\n\n await this.feedAdded.callSerial(feed);\n }\n\n // TODO(burdon): Rename open? Common open/close interfaces for all services?\n async start(ctx: Context): Promise<void> {\n if (this._connection) {\n return;\n }\n\n // TODO(burdon): Document why empty buffer.\n const credentials = await this._swarmIdentity.credentialProvider(Buffer.from(''));\n\n log('starting...');\n const topic = await this._topic;\n this._connection = await this._networkManager.joinSwarm(ctx, {\n protocolProvider: this._createProtocolProvider(credentials),\n topic,\n topology: this._topology,\n label: `swarm ${topic.truncate()} for space ${this._spaceKey.truncate()}`,\n });\n\n log('started');\n }\n\n public updateTopology(): void {\n this._topology.forceUpdate();\n }\n\n async stop(ctx: Context): Promise<void> {\n if (this._connection) {\n log('stopping...');\n await this._connection.close(ctx);\n log('stopped');\n }\n }\n\n private _createProtocolProvider(credentials: Uint8Array | undefined): WireProtocolProvider {\n return (wireProps) => {\n const session = new SpaceProtocolSession({\n wireProps,\n swarmIdentity: this._swarmIdentity,\n onSessionAuth: this._onSessionAuth,\n onAuthFailure: this._onAuthFailure,\n disableP2pReplication: this._disableP2pReplication,\n });\n this._sessions.set(wireProps.remotePeerId, session);\n\n for (const feed of this._feeds) {\n session.replicator.addHypercore(feed);\n }\n\n return session;\n };\n }\n}\n\nexport type SpaceProtocolSessionProps = {\n wireProps: WireProtocolProps;\n swarmIdentity: SwarmIdentity;\n\n /**\n * Called when new session is authenticated.\n * Additional extensions can be added here.\n */\n onSessionAuth?: (session: Teleport) => void;\n\n onAuthFailure?: (session: Teleport) => void;\n\n disableP2pReplication?: boolean;\n};\n\nexport enum AuthStatus {\n INITIAL = 'INITIAL',\n SUCCESS = 'SUCCESS',\n FAILURE = 'FAILURE',\n}\n\n// TODO(dmaretskyi): Move to a separate file.\n/**\n * Represents a single connection to a remote peer\n */\nexport class SpaceProtocolSession implements WireProtocol {\n @logInfo\n private readonly _wireProps: WireProtocolProps;\n\n private readonly _disableP2pReplication: boolean;\n\n private readonly _onSessionAuth?: (session: Teleport) => void;\n private readonly _onAuthFailure?: (session: Teleport) => void;\n private readonly _swarmIdentity: SwarmIdentity;\n\n private readonly _teleport: Teleport;\n\n // TODO(dmaretskyi): Start with upload=false when switching it on the fly works.\n public readonly replicator = new ReplicatorExtension().setOptions({ upload: true });\n\n private _authStatus = AuthStatus.INITIAL;\n\n @logInfo\n get authStatus() {\n return this._authStatus;\n }\n\n get stats(): Event<MuxerStats> {\n return this._teleport.stats;\n }\n\n // TODO(dmaretskyi): Allow to pass in extra extensions.\n constructor({\n wireProps,\n swarmIdentity,\n onSessionAuth,\n onAuthFailure,\n disableP2pReplication,\n }: SpaceProtocolSessionProps) {\n this._wireProps = wireProps;\n this._swarmIdentity = swarmIdentity;\n this._onSessionAuth = onSessionAuth;\n this._onAuthFailure = onAuthFailure;\n\n this._teleport = new Teleport(wireProps);\n\n this._disableP2pReplication = disableP2pReplication ?? false;\n }\n\n get stream() {\n return this._teleport.stream;\n }\n\n get closed() {\n return this._teleport.closed;\n }\n\n async open(sessionId?: PublicKey): Promise<void> {\n await this._teleport.open(sessionId);\n this._teleport.addExtension(\n 'dxos.mesh.teleport.auth',\n new AuthExtension({\n provider: this._swarmIdentity.credentialProvider,\n verifier: this._swarmIdentity.credentialAuthenticator,\n onAuthSuccess: () => {\n log('Peer authenticated');\n this._authStatus = AuthStatus.SUCCESS;\n this._onSessionAuth?.(this._teleport);\n // TODO(dmaretskyi): Configure replicator to upload.\n },\n onAuthFailure: () => {\n this._authStatus = AuthStatus.FAILURE;\n this._onAuthFailure?.(this._teleport);\n },\n }),\n );\n\n if (!this._disableP2pReplication) {\n this._teleport.addExtension('dxos.mesh.teleport.replicator', this.replicator);\n }\n }\n\n async close(): Promise<void> {\n log('close');\n await this._teleport.close();\n }\n\n async abort(): Promise<void> {\n await this._teleport.abort();\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { type AutomergeUrl, parseAutomergeUrl } from '@automerge/automerge-repo';\nimport { create } from '@bufbuild/protobuf';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { Trigger, synchronized, trackLeaks } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type DelegateInvitationCredential, type MemberInfo, getCredentialAssertion } from '@dxos/credentials';\nimport { createIdFromSpaceKey } from '@dxos/echo-protocol';\nimport * as Hook from '@dxos/effect/Hook';\nimport { type HypercoreStore, HypercoreStoreService } from '@dxos/feed-store';\nimport { PublicKey, SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type SwarmNetworkManager, SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport type { FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { type SpaceMetadata } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport type { Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { GetAdmissionCredentialRequestSchema } from '@dxos/protocols/buf/dxos/mesh/teleport/admission-discovery_pb';\nimport { type Teleport } from '@dxos/teleport';\nimport { ComplexMap } from '@dxos/util';\n\nimport * as Events from '../../Events.ts';\nimport { type IMetadataStore, IMetadataStoreService } from '../metadata/index.ts';\nimport { CredentialRetrieverExtension } from './admission-discovery-extension.ts';\nimport { SpaceProtocol, type SwarmIdentity } from './space-protocol.ts';\nimport { Space } from './space.ts';\n\nexport type SpaceManagerProps = {\n hypercoreStore: HypercoreStore<FeedMessage>;\n networkManager: SwarmNetworkManager;\n metadataStore: IMetadataStore;\n\n disableP2pReplication?: boolean;\n};\n\nexport type ConstructSpaceProps = {\n metadata: SpaceMetadata;\n swarmIdentity: SwarmIdentity;\n memberKey: PublicKey;\n /**\n * Called when connection auth passed successful.\n */\n onAuthorizedConnection: (session: Teleport) => void;\n onAuthFailure?: (session: Teleport) => void;\n onDelegatedInvitationStatusChange: (invitation: DelegateInvitationCredential, isActive: boolean) => Promise<void>;\n onMemberRolesChanged: (member: MemberInfo[]) => Promise<void>;\n};\n\nexport type RequestSpaceAdmissionCredentialProps = {\n spaceKey: PublicKey;\n identityKey: PublicKey;\n swarmIdentity: SwarmIdentity;\n timeout: number;\n};\n\n/**\n * Effect service tag for {@link SpaceManager}.\n */\nexport class SpaceManagerService extends EffectContext.Service<SpaceManagerService, SpaceManager>()(\n '@dxos/client-services/SpaceManager',\n) {}\n\n/**\n * Manages a collection of ECHO (Data) Spaces.\n */\n@trackLeaks('open', 'close')\nexport class SpaceManager {\n private readonly _spaces = new ComplexMap<PublicKey, Space>(PublicKey.hash);\n private readonly _hypercoreStore: HypercoreStore<FeedMessage>;\n private readonly _networkManager: SwarmNetworkManager;\n private readonly _metadataStore: IMetadataStore;\n private readonly _disableP2pReplication: boolean;\n\n constructor({ hypercoreStore, networkManager, metadataStore, disableP2pReplication }: SpaceManagerProps) {\n // TODO(burdon): Assert.\n this._hypercoreStore = hypercoreStore;\n this._networkManager = networkManager;\n this._metadataStore = metadataStore;\n this._disableP2pReplication = disableP2pReplication ?? false;\n }\n\n // TODO(burdon): Remove.\n get spaces() {\n return this._spaces;\n }\n\n @synchronized\n async open(): Promise<void> {}\n\n @synchronized\n async close(): Promise<void> {\n await Promise.all([...this._spaces.values()].map((space) => space.close()));\n }\n\n async constructSpace({\n metadata,\n swarmIdentity,\n onAuthorizedConnection,\n onAuthFailure,\n onDelegatedInvitationStatusChange,\n onMemberRolesChanged,\n memberKey,\n }: ConstructSpaceProps): Promise<Space> {\n log('constructing space...', { spaceKey: metadata.genesisFeedKey });\n\n // The genesis feed will be the same as the control feed if the space was created by the local agent.\n const genesisFeed = await this._hypercoreStore.openHypercore(requirePublicKey(metadata.genesisFeedKey));\n\n const spaceKey = requirePublicKey(metadata.key);\n // The carried id is primary; derive only for a space recorded before the field existed.\n const spaceId = metadata.spaceId ? SpaceId.make(metadata.spaceId) : await createIdFromSpaceKey(spaceKey);\n const protocol = new SpaceProtocol({\n topic: spaceKey,\n swarmIdentity,\n networkManager: this._networkManager,\n onSessionAuth: onAuthorizedConnection,\n onAuthFailure,\n disableP2pReplication: this._disableP2pReplication,\n });\n\n const space = new Space({\n id: spaceId,\n spaceKey,\n protocol,\n genesisFeed,\n feedProvider: (feedKey, opts) => this._hypercoreStore.openHypercore(feedKey, opts),\n metadataStore: this._metadataStore,\n memberKey,\n onDelegatedInvitationStatusChange,\n onMemberRolesChanged,\n });\n this._spaces.set(space.key, space);\n\n return space;\n }\n\n public async requestSpaceAdmissionCredential(\n ctx: Context,\n params: RequestSpaceAdmissionCredentialProps,\n ): Promise<Credential> {\n log('requesting space admission credential...', { spaceKey: params.spaceKey });\n\n const onCredentialResolved = new Trigger<Credential>();\n const protocol = new SpaceProtocol({\n topic: params.spaceKey,\n swarmIdentity: params.swarmIdentity,\n networkManager: this._networkManager,\n onSessionAuth: (session: Teleport) => {\n session.addExtension(\n 'dxos.mesh.teleport.admission-discovery',\n new CredentialRetrieverExtension(\n create(GetAdmissionCredentialRequestSchema, {\n spaceKey: fromPublicKey(params.spaceKey),\n memberKey: fromPublicKey(params.identityKey),\n }),\n onCredentialResolved,\n ),\n );\n },\n onAuthFailure: (session: Teleport) => session.close(),\n disableP2pReplication: this._disableP2pReplication,\n });\n\n try {\n await protocol.start(ctx);\n const credential = await onCredentialResolved.wait({ timeout: params.timeout });\n return credential;\n } catch (err: any) {\n throw err;\n } finally {\n await protocol.stop(ctx);\n }\n }\n\n public findSpaceByRootDocumentId(documentId: string): Space | undefined {\n return [...this._spaces.values()].find((space) => {\n return space.spaceState.credentials.some((credential) => {\n const assertion = getCredentialAssertion(credential);\n if (assertion.$typeName !== 'dxos.halo.credentials.Epoch' || !assertion.automergeRoot) {\n return false;\n }\n return parseAutomergeUrl(assertion.automergeRoot as AutomergeUrl).documentId === documentId;\n });\n });\n }\n}\n\nexport type SpaceManagerLayerOptions = Pick<SpaceManagerProps, 'disableP2pReplication'>;\n\n/**\n * Effect Layer constructing a {@link SpaceManager} from ambient service dependencies.\n */\nexport const SpaceManagerLayer = (\n options: SpaceManagerLayerOptions = {},\n): Layer.Layer<\n SpaceManagerService,\n never,\n Hook.Controller | HypercoreStoreService | SwarmNetworkManagerService | IMetadataStoreService\n> =>\n Layer.effect(\n SpaceManagerService,\n Effect.gen(function* () {\n const hypercoreStore = yield* HypercoreStoreService;\n const networkManager = yield* SwarmNetworkManagerService;\n const metadataStore = yield* IMetadataStoreService;\n const spaceManager = new SpaceManager({\n hypercoreStore,\n networkManager,\n metadataStore,\n disableP2pReplication: options.disableP2pReplication,\n });\n\n yield* Effect.addFinalizer(() => Effect.promise(() => spaceManager.close()));\n yield* Events.NetworkReady.pipe(\n Hook.handler(() => Effect.promise(() => spaceManager.open())),\n Hook.subscribe,\n );\n return spaceManager;\n }),\n );\n","//\n// Copyright 2021 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { SubscriptionList } from '@dxos/async';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { HypercoreIterator, type HypercoreStore, type HypercoreWrapper } from '@dxos/feed-store';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type FeedMessageBlock } from '@dxos/protocols';\nimport { buf, fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport {\n type SubscribeToFeedBlocksResponse,\n SubscribeToFeedBlocksResponse_BlockSchema,\n SubscribeToFeedBlocksResponseSchema,\n} from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { type FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { type DevtoolsHost } from '@dxos/protocols/rpc';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type SpaceManager } from '../space/index.ts';\n\n/** Feed blocks come off the iterator in the protobuf.js shape, which crosses as the shared wire bytes. */\n/** The feed's blocks as the devtools RPC message; the iterator yields the domain block shape. */\nconst toBufResponse = (blocks: FeedMessageBlock[]): SubscribeToFeedBlocksResponse =>\n buf.create(SubscribeToFeedBlocksResponseSchema, {\n blocks: blocks.map((block) =>\n buf.create(SubscribeToFeedBlocksResponse_BlockSchema, {\n feedKey: fromPublicKey(block.feedKey),\n seq: block.seq,\n data: block.data,\n }),\n ),\n });\n\ntype FeedInfo = {\n feed: HypercoreWrapper<FeedMessage>;\n owner?: DevtoolsHost.SubscribeToFeedsResponse.FeedOwner;\n};\n\nexport const subscribeToFeeds = (\n { hypercoreStore, spaceManager }: { hypercoreStore: HypercoreStore<FeedMessage>; spaceManager: SpaceManager },\n { feedKeys }: DevtoolsHost.SubscribeToFeedsRequest,\n): EffectStream.Stream<DevtoolsHost.SubscribeToFeedsResponse, Error> => {\n return EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToFeedsResponse, Error>((emit) => {\n const subscriptions = new SubscriptionList();\n const feedMap = new ComplexMap<PublicKey, FeedInfo>(PublicKey.hash);\n\n const update = () => {\n const { feeds } = hypercoreStore;\n feeds\n .filter((feed) => !feedKeys?.length || feedKeys.some((feedKey) => feedKey.equals(feed.key)))\n .forEach((feed) => {\n if (!feedMap.has(feed.key)) {\n feedMap.set(feed.key, { feed });\n feed.on('close', update);\n subscriptions.add(() => feed.off('close', update));\n }\n if (!feedMap.get(feed.key)?.owner) {\n feedMap.get(feed.key)!.owner = findFeedOwner(spaceManager, feed.key);\n }\n });\n\n emit.single({\n feeds: Array.from(feedMap.values()).map(({ feed, owner }) => ({\n feedKey: feed.key,\n length: feed.properties.length,\n bytes: feed.core.byteLength,\n downloaded: feed.core.bitfield?.data.toBuffer() ?? new Uint8Array(),\n owner,\n })),\n });\n };\n\n subscriptions.add(hypercoreStore.feedOpened.on(update));\n update();\n\n return Effect.sync(() => {\n subscriptions.clear();\n });\n });\n};\n\nconst findFeedOwner = (\n spaceManager: SpaceManager,\n feedKey: PublicKey,\n): DevtoolsHost.SubscribeToFeedsResponse.FeedOwner | undefined => {\n const feedInfo = [...spaceManager.spaces.values()]\n .flatMap((space) => [...space.spaceState.feeds.values()])\n .find((feed) => feed.key.equals(feedKey));\n log('feeds', { feedInfo, key: feedKey.truncate(), allSpaces: spaceManager.spaces.size });\n if (!feedInfo) {\n return undefined;\n }\n return {\n identity: requirePublicKey(feedInfo.assertion.identityKey),\n device: requirePublicKey(feedInfo.assertion.deviceKey),\n };\n};\n\nexport const subscribeToFeedBlocks = (\n { hypercoreStore }: { hypercoreStore: HypercoreStore<FeedMessage> },\n { feedKey, maxBlocks = 10 }: DevtoolsHost.SubscribeToFeedBlocksRequest,\n): EffectStream.Stream<SubscribeToFeedBlocksResponse, Error> => {\n return EffectEx.streamFromEmitter<SubscribeToFeedBlocksResponse, Error>((emit) => {\n if (!feedKey) {\n return;\n }\n\n const subscriptions = new SubscriptionList();\n\n const timeout = setTimeout(async () => {\n const feed = hypercoreStore.getHypercore(feedKey);\n if (!feed) {\n return;\n }\n\n const update = async () => {\n if (!feed.properties.length) {\n emit.single(toBufResponse([]));\n return;\n }\n\n const iterator = new HypercoreIterator(feed);\n await iterator.open();\n const blocks = [];\n for await (const block of iterator) {\n blocks.push(block);\n if (blocks.length >= feed.properties.length) {\n break;\n }\n }\n\n emit.single(toBufResponse(blocks.slice(-maxBlocks)));\n\n await iterator.close();\n };\n\n feed.on('append', update);\n subscriptions.add(() => feed.off('append', update));\n\n feed.on('truncate', update);\n subscriptions.add(() => feed.off('truncate', update));\n await update();\n });\n\n return Effect.sync(() => {\n subscriptions.clear();\n clearTimeout(timeout);\n });\n });\n};\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { type DevtoolsHost } from '@dxos/protocols/rpc';\n\nexport const subscribeToKeyringKeys = ({\n keyring,\n}: {\n keyring: KeyringApi;\n}): EffectStream.Stream<DevtoolsHost.SubscribeToKeyringKeysResponse, Error> =>\n EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToKeyringKeysResponse, Error>((emit) => {\n const ctx = Context.default();\n const update = async () => {\n try {\n emit.single({\n keys: await keyring.list(),\n });\n } catch (err: any) {\n emit.fail(err);\n }\n };\n keyring.keysUpdate.on(ctx, update);\n scheduleTask(ctx, update);\n\n return Effect.promise(() => ctx.dispose());\n });\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { buf } from '@dxos/protocols/buf';\nimport {\n type SubscribeToMetadataResponse,\n SubscribeToMetadataResponseSchema,\n} from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { type EchoMetadata } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\n\nimport { type IMetadataStore } from '../metadata/index.ts';\n\nconst toBufResponse = (metadata: EchoMetadata): SubscribeToMetadataResponse =>\n buf.create(SubscribeToMetadataResponseSchema, { metadata });\n\nexport const subscribeToMetadata = ({\n metadataStore,\n}: {\n metadataStore: IMetadataStore;\n}): EffectStream.Stream<SubscribeToMetadataResponse, Error> =>\n EffectEx.streamFromEmitter<SubscribeToMetadataResponse, Error>((emit) => {\n const ctx = Context.default();\n metadataStore.update.on(ctx, (data) => emit.single(toBufResponse(data)));\n emit.single(toBufResponse(metadataStore.metadata));\n\n return Effect.promise(() => ctx.dispose());\n });\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { type MessageInitShape, create } from '@bufbuild/protobuf';\nimport { AnySchema, timestampFromDate } from '@bufbuild/protobuf/wkt';\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type PeerInfo, type SignalManager, type UnsubscribeCallback } from '@dxos/messaging';\nimport { type SwarmNetworkManager } from '@dxos/network-manager';\nimport { requirePublicKey, toDate } from '@dxos/protocols/buf';\nimport { type SignalResponse, SignalResponseSchema } from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { type ConnectionInfo, type SwarmInfo } from '@dxos/protocols/buf/dxos/devtools/swarm_pb';\nimport { SwarmEventSchema } from '@dxos/protocols/buf/dxos/mesh/signal_pb';\nimport { type DevtoolsHost } from '@dxos/protocols/rpc';\n\nexport const subscribeToNetworkStatus = ({\n signalManager,\n}: {\n signalManager: SignalManager;\n}): EffectStream.Stream<DevtoolsHost.SubscribeToSignalStatusResponse, Error> =>\n EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToSignalStatusResponse, Error>((emit) => {\n const update = () => {\n try {\n const status = signalManager.getStatus?.();\n emit.single({ servers: status });\n } catch (err: any) {\n emit.fail(err);\n }\n };\n\n const unsubscribe = signalManager.statusChanged?.on(() => update());\n update();\n\n return Effect.sync(() => unsubscribe?.());\n });\n\nexport const subscribeToSignal = ({\n signalManager,\n networkManager,\n}: {\n signalManager: SignalManager;\n networkManager: SwarmNetworkManager;\n}): EffectStream.Stream<SignalResponse, Error> =>\n EffectEx.streamFromEmitter<SignalResponse, Error>((emit) => {\n const ctx = new Context();\n\n // Observe point-to-point messages delivered to this node's own peer. The subscription owns its\n // routing and teardown (DX-1125); with no local peer yet there is nothing to observe.\n let unsubscribe: UnsubscribeCallback | undefined;\n const peer = networkManager.getPeerInfo();\n if (peer) {\n void signalManager\n .subscribeMessages({\n peer,\n onMessage: (message) => {\n emit.single(\n create(SignalResponseSchema, {\n data: {\n case: 'message',\n value: {\n author: peerKeyBytes(message.author),\n recipient: peerKeyBytes(message.recipient),\n // Messaging keeps payloads packed and dispatches on `typeUrl`, so this is a\n // field map — the payload is never resolved here.\n payload: create(AnySchema, {\n typeUrl: message.payload?.typeUrl,\n value: message.payload?.value,\n }),\n },\n },\n receivedAt: timestampFromDate(new Date()),\n }),\n );\n },\n })\n .then((unsub) => {\n if (ctx.disposed) {\n void unsub();\n } else {\n unsubscribe = unsub;\n }\n })\n .catch((err) => log.catch(err));\n }\n\n signalManager.swarmEvent.on(ctx, (swarmEvent) => {\n const event: MessageInitShape<typeof SwarmEventSchema>['event'] =\n swarmEvent.event.case === 'peerAvailable'\n ? {\n case: 'peerAvailable',\n value: {\n peer: peerKeyBytes(swarmEvent.event.value.peer),\n since: swarmEvent.event.value.since,\n },\n }\n : swarmEvent.event.case === 'peerLeft'\n ? { case: 'peerLeft', value: { peer: peerKeyBytes(swarmEvent.event.value.peer) } }\n : { case: undefined };\n\n emit.single(\n create(SignalResponseSchema, {\n data: { case: 'swarmEvent', value: create(SwarmEventSchema, { event }) },\n topic: swarmEvent.topic?.data,\n receivedAt: timestampFromDate(new Date()),\n }),\n );\n });\n\n return Effect.promise(async () => {\n await unsubscribe?.();\n await ctx.dispose();\n });\n });\n\nexport const subscribeToNetworkTopics = ({\n networkManager,\n}: {\n networkManager: SwarmNetworkManager;\n}): EffectStream.Stream<DevtoolsHost.SubscribeToNetworkTopicsResponse, Error> =>\n EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToNetworkTopicsResponse, Error>((emit) => {\n const update = () => {\n try {\n const topics = networkManager.topics;\n const labeledTopics = topics.map((topic) => ({\n topic,\n label: networkManager.getSwarm(topic)?.label ?? topic.toHex(),\n }));\n emit.single({ topics: labeledTopics });\n } catch (err: any) {\n emit.fail(err);\n }\n };\n const unsubscribe = networkManager.topicsUpdated.on(update);\n\n update();\n\n return Effect.sync(() => unsubscribe());\n });\n\nexport const subscribeToSwarmInfo = ({\n networkManager,\n}: {\n networkManager: SwarmNetworkManager;\n}): EffectStream.Stream<DevtoolsHost.SubscribeToSwarmInfoResponse, Error> =>\n EffectEx.streamFromEmitter<DevtoolsHost.SubscribeToSwarmInfoResponse, Error>((emit) => {\n const update = () => {\n const info = networkManager.connectionLog?.swarms;\n if (info) {\n emit.single({ data: info.map(toSwarmInfo) });\n }\n };\n const unsubscribe = networkManager.connectionLog?.update.on(update);\n update();\n\n return Effect.sync(() => unsubscribe?.());\n });\n\nexport const getNetworkPeers = (\n { networkManager }: { networkManager: SwarmNetworkManager },\n request: DevtoolsHost.GetNetworkPeersRequest,\n): DevtoolsHost.GetNetworkPeersResponse => {\n if (!request.topic) {\n throw new Error('Expected a network topic');\n }\n\n const map = networkManager.getSwarmMap(PublicKey.from(request.topic));\n return {\n peers: map?.peers.map((peer) => ({\n ...peer,\n connections: peer.connections.map((connection) => connection.asUint8Array()),\n })),\n };\n};\n\n/** The peer's key as the raw bytes the devtools swarm event carries. */\nconst peerKeyBytes = (peer: PeerInfo | undefined): Uint8Array =>\n peer ? PublicKey.from(peer.peerKey).asUint8Array() : new Uint8Array();\n\n/**\n * Reads the connection log's message as the devtools RPC shape.\n *\n * The log holds the generated message; the devtools panels are keyed by the domain `PublicKey`, so\n * the keys and timestamps convert at this one boundary.\n */\nconst toSwarmInfo = (swarm: SwarmInfo): DevtoolsHost.SwarmInfo => ({\n id: requirePublicKey(swarm.id),\n topic: requirePublicKey(swarm.topic),\n label: swarm.label,\n isActive: swarm.isActive,\n connections: swarm.connections.map(toConnectionInfo),\n});\n\nconst toConnectionInfo = (connection: ConnectionInfo): DevtoolsHost.ConnectionInfo => ({\n state: connection.state,\n sessionId: requirePublicKey(connection.sessionId),\n remotePeerId: requirePublicKey(connection.remotePeerId),\n transport: connection.transport,\n protocolExtensions: connection.protocolExtensions,\n events: connection.events.map((event) => ({ type: event.type, newState: event.newState, error: event.error })),\n streams: connection.streams,\n closeReason: connection.closeReason,\n identity: connection.identity,\n readBufferSize: connection.readBufferSize,\n writeBufferSize: connection.writeBufferSize,\n lastUpdate: toDate(connection.lastUpdate),\n transportDetails: connection.transportDetails,\n transportBytesSent: connection.transportBytesSent,\n transportBytesReceived: connection.transportBytesReceived,\n transportPacketsSent: connection.transportPacketsSent,\n transportPacketsReceived: connection.transportPacketsReceived,\n});\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as EffectStream from 'effect/Stream';\n\nimport { type Trigger } from '@dxos/async';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport {\n type SubscribeToSpacesResponse,\n type SubscribeToSpacesResponse_SpaceInfo,\n SubscribeToSpacesResponse_SpaceInfoSchema,\n SubscribeToSpacesResponseSchema,\n} from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { type SpaceMetadata } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { type DevtoolsHost } from '@dxos/protocols/rpc';\n\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport { type IMetadataStore } from '../metadata/index.ts';\nimport { type Space, type SpaceManager } from '../space/index.ts';\n\nexport const subscribeToSpaces = (\n {\n spaceManager,\n metadataStore,\n dataSpaceManager,\n initialized,\n }: {\n spaceManager: SpaceManager;\n metadataStore: IMetadataStore;\n dataSpaceManager: SpacesContract.Manager;\n initialized: Trigger;\n },\n { spaceKeys = [] }: DevtoolsHost.SubscribeToSpacesRequest,\n): EffectStream.Stream<SubscribeToSpacesResponse, Error> => {\n return EffectEx.streamFromEmitter<SubscribeToSpacesResponse, Error>((emit) => {\n let unsubscribe: () => void;\n\n const update = async () => {\n const spaces: Space[] = [...spaceManager.spaces.values()];\n const filteredSpaces = spaces.filter(\n (space) => !spaceKeys?.length || spaceKeys.some((spaceKey) => spaceKey.equals(space.key)),\n );\n\n emit.single(\n create(SubscribeToSpacesResponseSchema, {\n spaces: filteredSpaces.map((space): SubscribeToSpacesResponse_SpaceInfo => {\n const spaceMetadata = metadataStore.spaces.find(\n (spaceMetadata: SpaceMetadata) =>\n spaceMetadata.key && requirePublicKey(spaceMetadata.key).equals(space.key),\n );\n\n return create(SubscribeToSpacesResponse_SpaceInfoSchema, {\n key: fromPublicKey(space.key),\n isOpen: space.isOpen,\n timeframe: spaceMetadata?.dataTimeframe,\n genesisFeed: fromPublicKey(space.genesisFeedKey),\n // The write feeds are absent until the space is opened for writing; buf makes that\n // presence explicit where the protobuf.js shape let it pass as a non-null assertion.\n controlFeed: space.controlFeedKey && fromPublicKey(space.controlFeedKey),\n dataFeed: space.dataFeedKey && fromPublicKey(space.dataFeedKey),\n });\n }),\n }),\n );\n };\n\n const timeout = setTimeout(async () => {\n await initialized.wait();\n unsubscribe = dataSpaceManager.updated.on(() => update());\n\n // Send initial spaces.\n await update();\n });\n\n return Effect.sync(() => {\n unsubscribe?.();\n clearTimeout(timeout);\n });\n });\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Event as AsyncEvent, type Trigger } from '@dxos/async';\nimport { type Config, ConfigService } from '@dxos/config';\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { NotImplementedError } from '@dxos/errors';\nimport { type HypercoreStore, HypercoreStoreService } from '@dxos/feed-store';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { type SignalManager, SignalManagerService } from '@dxos/messaging';\nimport { type SwarmNetworkManager, SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { toServiceError } from '@dxos/protocols';\nimport {\n type GetSpaceSnapshotResponse,\n type SaveSpaceSnapshotResponse,\n type SignalResponse,\n type SubscribeToFeedBlocksResponse,\n type SubscribeToMetadataResponse,\n type SubscribeToSpacesResponse,\n} from '@dxos/protocols/buf/dxos/devtools/host_pb';\nimport { DevtoolsHost } from '@dxos/protocols/rpc';\nimport * as SqlExport from '@dxos/sql-sqlite/SqlExport';\n\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Readiness from '../../Readiness.ts';\nimport { type IMetadataStore, IMetadataStoreService } from '../metadata/index.ts';\nimport { type SpaceManager, SpaceManagerService } from '../space/index.ts';\nimport { subscribeToFeedBlocks, subscribeToFeeds } from './feeds.ts';\nimport { subscribeToKeyringKeys } from './keys.ts';\nimport { subscribeToMetadata } from './metadata.ts';\nimport { subscribeToNetworkStatus, subscribeToSignal, subscribeToSwarmInfo } from './network.ts';\nimport { subscribeToSpaces } from './spaces.ts';\n\nexport class DevtoolsHostEvents {\n readonly ready = new AsyncEvent();\n}\n\nexport type DevtoolsServiceProps = {\n events: DevtoolsHostEvents;\n config: Config;\n keyring: KeyringApi;\n hypercoreStore: HypercoreStore<any>;\n spaceManager: SpaceManager;\n metadataStore: IMetadataStore;\n dataSpaceManager: SpacesContract.Manager;\n initialized: Trigger;\n signalManager: SignalManager;\n networkManager: SwarmNetworkManager;\n sql: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlExport.SqlExport>;\n};\n\n/**\n * @deprecated\n */\nexport class DevtoolsServiceImpl implements DevtoolsHost.Handlers {\n 'constructor'(private readonly params: DevtoolsServiceProps) {}\n\n /**\n * Debugging util.\n */\n async 'exportSqliteDatabase'(): Promise<Uint8Array> {\n return RuntimeProvider.runPromise(this.params.sql)(\n Effect.gen(function* () {\n const sql = yield* SqlExport.SqlExport;\n return yield* sql.export;\n }),\n );\n }\n\n /**\n * Debugging util.\n */\n async 'runSqliteQuery'(query: string, params?: unknown[]): Promise<readonly Record<string, unknown>[]> {\n return RuntimeProvider.runPromise(this.params.sql)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql`${sql.unsafe(query, params)}`;\n }),\n );\n }\n\n ['DevtoolsHost.events'](): EffectStream.Stream<DevtoolsHost.Event, Error> {\n return EffectEx.streamFromEmitter<DevtoolsHost.Event, Error>((emit) => {\n const ctx = Context.default();\n this.params.events.ready.on(ctx, () => {\n void emit.single({ ready: {} });\n });\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['DevtoolsHost.getConfig'](): Effect.Effect<DevtoolsHost.GetConfigResponse, Error> {\n return Effect.sync(() => ({ config: JSON.stringify(this.params.config.values) }));\n }\n\n ['DevtoolsHost.getStorageInfo'](): Effect.Effect<DevtoolsHost.StorageInfo, Error> {\n return Effect.tryPromise({\n try: async () => {\n const navigatorInfo = typeof navigator === 'object' ? await navigator.storage.estimate() : undefined;\n\n return {\n type: 'sqlite',\n storageUsage: navigatorInfo?.usage ?? 0,\n originUsage: navigatorInfo?.usage ?? 0,\n usageQuota: navigatorInfo?.quota ?? 0,\n };\n },\n catch: toServiceError,\n });\n }\n\n ['DevtoolsHost.getSnapshots'](): Effect.Effect<DevtoolsHost.GetSnapshotsResponse, Error> {\n return Effect.sync(() => ({\n snapshots: [],\n }));\n }\n\n ['DevtoolsHost.resetStorage'](_request: DevtoolsHost.ResetStorageRequest): Effect.Effect<void, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.resetStorage is not implemented.' }));\n }\n\n ['DevtoolsHost.enableDebugLogging'](\n _request: DevtoolsHost.EnableDebugLoggingRequest,\n ): Effect.Effect<DevtoolsHost.EnableDebugLoggingResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.enableDebugLogging is not implemented.' }));\n }\n\n ['DevtoolsHost.disableDebugLogging'](\n _request: DevtoolsHost.EnableDebugLoggingRequest,\n ): Effect.Effect<DevtoolsHost.EnableDebugLoggingResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.disableDebugLogging is not implemented.' }));\n }\n\n ['DevtoolsHost.subscribeToKeyringKeys'](\n _request: DevtoolsHost.SubscribeToKeyringKeysRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToKeyringKeysResponse, Error> {\n return subscribeToKeyringKeys({ keyring: this.params.keyring });\n }\n\n ['DevtoolsHost.subscribeToCredentialMessages'](\n _request: DevtoolsHost.SubscribeToCredentialMessagesRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToCredentialMessagesResponse, Error> {\n return EffectStream.fail(new Error());\n }\n\n ['DevtoolsHost.subscribeToSpaces'](\n request: DevtoolsHost.SubscribeToSpacesRequest,\n ): EffectStream.Stream<SubscribeToSpacesResponse, Error> {\n return subscribeToSpaces(this.params, request);\n }\n\n ['DevtoolsHost.subscribeToItems'](\n _request: DevtoolsHost.SubscribeToItemsRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToItemsResponse, Error> {\n return EffectStream.fail(new Error());\n }\n\n ['DevtoolsHost.subscribeToFeeds'](\n request: DevtoolsHost.SubscribeToFeedsRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToFeedsResponse, Error> {\n return subscribeToFeeds(this.params, request);\n }\n\n ['DevtoolsHost.subscribeToFeedBlocks'](\n request: DevtoolsHost.SubscribeToFeedBlocksRequest,\n ): EffectStream.Stream<SubscribeToFeedBlocksResponse, Error> {\n return subscribeToFeedBlocks({ hypercoreStore: this.params.hypercoreStore }, request);\n }\n\n ['DevtoolsHost.subscribeToMetadata'](): EffectStream.Stream<SubscribeToMetadataResponse, Error> {\n return subscribeToMetadata({ metadataStore: this.params.metadataStore });\n }\n\n ['DevtoolsHost.getSpaceSnapshot'](\n _request: DevtoolsHost.GetSpaceSnapshotRequest,\n ): Effect.Effect<GetSpaceSnapshotResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.getSpaceSnapshot is not implemented.' }));\n }\n\n ['DevtoolsHost.saveSpaceSnapshot'](\n _request: DevtoolsHost.SaveSpaceSnapshotRequest,\n ): Effect.Effect<SaveSpaceSnapshotResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.saveSpaceSnapshot is not implemented.' }));\n }\n\n ['DevtoolsHost.clearSnapshots'](\n _request: DevtoolsHost.ClearSnapshotsRequest,\n ): Effect.Effect<void, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.clearSnapshots is not implemented.' }));\n }\n\n ['DevtoolsHost.getNetworkPeers'](\n _request: DevtoolsHost.GetNetworkPeersRequest,\n ): Effect.Effect<DevtoolsHost.GetNetworkPeersResponse, NotImplementedError> {\n return Effect.fail(new NotImplementedError({ message: 'DevtoolsHost.getNetworkPeers is not implemented.' }));\n }\n\n ['DevtoolsHost.subscribeToNetworkTopics'](): EffectStream.Stream<\n DevtoolsHost.SubscribeToNetworkTopicsResponse,\n Error\n > {\n return EffectStream.fail(new Error());\n }\n\n ['DevtoolsHost.subscribeToSignalStatus'](): EffectStream.Stream<DevtoolsHost.SubscribeToSignalStatusResponse, Error> {\n return subscribeToNetworkStatus({ signalManager: this.params.signalManager });\n }\n\n ['DevtoolsHost.subscribeToSignal'](): EffectStream.Stream<SignalResponse, Error> {\n return subscribeToSignal({\n signalManager: this.params.signalManager,\n networkManager: this.params.networkManager,\n });\n }\n\n ['DevtoolsHost.subscribeToSwarmInfo'](\n _request: DevtoolsHost.SubscribeToSwarmInfoRequest,\n ): EffectStream.Stream<DevtoolsHost.SubscribeToSwarmInfoResponse, Error> {\n return subscribeToSwarmInfo({ networkManager: this.params.networkManager });\n }\n\n ['DevtoolsHost.exportSqliteDatabase'](): Effect.Effect<DevtoolsHost.ExportSqliteDatabaseResponse, Error> {\n return Effect.tryPromise({\n try: async () => ({\n data: await this.exportSqliteDatabase(),\n }),\n catch: toServiceError,\n });\n }\n\n ['DevtoolsHost.runSqliteQuery'](\n request: DevtoolsHost.RunSqliteQueryRequest,\n ): Effect.Effect<DevtoolsHost.RunSqliteQueryResponse, Error> {\n return Effect.promise(async () => {\n try {\n const parsedParams = request.params ? JSON.parse(request.params) : undefined;\n if (parsedParams !== undefined && !Array.isArray(parsedParams)) {\n throw new Error('Query params must be a JSON array.');\n }\n const rows = await this.runSqliteQuery(request.query, parsedParams);\n return { rows: JSON.stringify(rows) };\n } catch (err) {\n return { rows: '[]', error: err instanceof Error ? err.message : String(err) };\n }\n });\n }\n}\n\n/**\n * The impl under its own tag, so the host can reach the SQL debugging utils the RPC {@link DevtoolsHost.Tag}\n * does not expose.\n */\nexport class DevtoolsHostService extends EffectContext.Service<DevtoolsHostService, DevtoolsServiceImpl>()(\n '@dxos/client-services/DevtoolsHost',\n) {}\n\nconst devtoolsImplLayer: Layer.Layer<\n DevtoolsHostService,\n never,\n | ConfigService\n | KeyringApiService\n | HypercoreStoreService\n | SpaceManagerService\n | IMetadataStoreService\n | SpacesContract.ManagerService\n | Readiness.StackReadinessService\n | SignalManagerService\n | SwarmNetworkManagerService\n | SqlClient.SqlClient\n | SqlExport.SqlExport\n> = Layer.effect(\n DevtoolsHostService,\n Effect.gen(function* () {\n const config = yield* ConfigService;\n const keyring = yield* KeyringApiService;\n const hypercoreStore = yield* HypercoreStoreService;\n const spaceManager = yield* SpaceManagerService;\n const metadataStore = yield* IMetadataStoreService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const readiness = yield* Readiness.StackReadinessService;\n const signalManager = yield* SignalManagerService;\n const networkManager = yield* SwarmNetworkManagerService;\n const sql = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient | SqlExport.SqlExport>();\n return new DevtoolsServiceImpl({\n events: new DevtoolsHostEvents(),\n config,\n keyring,\n hypercoreStore,\n spaceManager,\n metadataStore,\n dataSpaceManager,\n initialized: readiness.initialized,\n signalManager,\n networkManager,\n sql,\n });\n }),\n);\n\nexport const DevtoolsHostLayer = Layer.effect(DevtoolsHost.Tag, DevtoolsHostService).pipe(\n Layer.provideMerge(devtoolsImplLayer),\n);\n","//\n// Copyright 2022 DXOS.org\n//\n\n// @import-as-namespace\n\nimport { buf } from '@dxos/protocols/buf';\nimport { type Platform, Platform_PLATFORM_TYPE, PlatformSchema } from '@dxos/protocols/buf/dxos/client/services_pb';\n\nexport const getPlatform = (): Platform => {\n if ((process as any).browser) {\n if (typeof window !== 'undefined') {\n // Browser.\n const { userAgent } = window.navigator;\n return buf.create(PlatformSchema, {\n type: Platform_PLATFORM_TYPE.BROWSER,\n userAgent,\n uptime: Math.floor((Date.now() - window.performance.timeOrigin) / 1_000),\n });\n } else {\n // Dedicated worker.\n return buf.create(PlatformSchema, {\n type: Platform_PLATFORM_TYPE.DEDICATED_WORKER,\n uptime: Math.floor((Date.now() - performance.timeOrigin) / 1_000),\n });\n }\n } else {\n // Node.\n const { platform, version, arch } = process;\n // `MemoryUsage` is an interface without an index signature, so the Struct field takes the\n // fields explicitly rather than the object itself.\n const { rss, heapTotal, heapUsed, external, arrayBuffers } = process.memoryUsage();\n return buf.create(PlatformSchema, {\n type: Platform_PLATFORM_TYPE.NODE,\n platform,\n arch,\n runtime: version,\n uptime: Math.floor(process.uptime()),\n memory: { rss, heapTotal, heapUsed, external, arrayBuffers },\n });\n }\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nexport const DXOS_VERSION = '0.14.0';\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\n\nimport { asyncTimeout } from '@dxos/async';\nimport { getFirstStreamValue } from '@dxos/async';\nimport { type ClientServices, makeClientServicesRpcFromRouter, makeServicesFromRpc } from '@dxos/client-protocol';\nimport { type Config, type ConfigProto } from '@dxos/config';\nimport { createDidFromIdentityKey, credentialsOfType } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { STORAGE_VERSION } from '@dxos/protocols';\nimport { buf, fromPublicKey, fromTimeframe, toDate, toPublicKey } from '@dxos/protocols/buf';\nimport {\n type Device,\n type Identity,\n IdentitySchema,\n type NetworkStatus,\n type Platform,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport {\n type Space_Metrics,\n type Space_PipelineState,\n Space_PipelineStateSchema,\n IdentitySchema as SpaceIdentitySchema,\n type SpaceMember,\n SpaceMember_PresenceState,\n SpaceMemberSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type SwarmInfo } from '@dxos/protocols/buf/dxos/devtools/swarm_pb';\nimport { type Epoch } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type DevtoolsHost, type LoggingService } from '@dxos/protocols/rpc';\nimport { RpcRouter } from '@dxos/rpc';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as PlatformInfo from '../../PlatformInfo.ts';\nimport { DXOS_VERSION } from '../../version.ts';\nimport { type DataSpace } from '../spaces/index.ts';\n\nconst DEFAULT_TIMEOUT = 1_000;\n\nexport type Diagnostics = {\n client: {\n config: ConfigProto;\n };\n services: {\n created: string;\n platform: Platform;\n config?: ConfigProto;\n client: {\n version: string;\n storage: {\n version: number;\n };\n };\n identity?: Identity;\n devices?: Device[];\n spaces?: SpaceStats[];\n networkStatus?: NetworkStatus;\n swarms?: SwarmInfo[];\n feeds?: Partial<DevtoolsHost.SubscribeToFeedsResponse.Feed>[];\n metrics?: LoggingService.Metrics;\n storage?: { file: string; count: number }[];\n };\n};\n\n// TODO(burdon): Normalize for ECHO/HALO.\nexport type SpaceStats = {\n key: PublicKey;\n properties?: {\n name: string;\n };\n db?: {\n objects: number;\n };\n metrics?: Space_Metrics & {\n startupTime?: number;\n };\n epochs?: { epoch: Epoch; id?: PublicKey }[];\n members?: SpaceMember[];\n pipeline?: Space_PipelineState;\n};\n\n/**\n * {@link createDiagnostics} over the services registered with a stack's {@link RpcRouter.RpcRouter},\n * bridged in-process for the duration of the collection.\n */\nexport const createDiagnosticsFromRouter = (\n router: RpcRouter.Service,\n stack: EffectContext.Context<\n IdentityContract.ManagerService | SpacesContract.ManagerService | SwarmNetworkManagerService\n >,\n config: Config,\n): Promise<Diagnostics['services']> =>\n EffectEx.runPromise(\n Effect.scoped(\n Effect.gen(function* () {\n const rpc = yield* makeClientServicesRpcFromRouter.pipe(Effect.provideService(RpcRouter.RpcRouter, router));\n return yield* Effect.promise(() =>\n createDiagnostics(makeServicesFromRpc(rpc, EffectContext.empty()), stack, config),\n );\n }),\n ),\n );\n\n/**\n * Create diagnostics to provide snapshot of current system state.\n */\nexport const createDiagnostics = async (\n clientServices: Partial<ClientServices>,\n stack: EffectContext.Context<\n IdentityContract.ManagerService | SpacesContract.ManagerService | SwarmNetworkManagerService\n >,\n config: Config,\n): Promise<Diagnostics['services']> => {\n const diagnostics: Diagnostics['services'] = {\n created: new Date().toISOString(),\n platform: PlatformInfo.getPlatform(),\n client: {\n version: DXOS_VERSION,\n storage: {\n version: STORAGE_VERSION,\n },\n },\n };\n\n await Promise.all([\n (async () => {\n // Trace metrics.\n // TODO(burdon): Move here from logging service?\n invariant(clientServices.LoggingService, 'SystemService is not available.');\n diagnostics.metrics = await getFirstStreamValue(clientServices.LoggingService.queryMetrics({}), {\n timeout: DEFAULT_TIMEOUT,\n }).catch(() => undefined);\n })(),\n (async () => {\n diagnostics.storage = await asyncTimeout(getStorageDiagnostics(), DEFAULT_TIMEOUT).catch(() => undefined);\n })(),\n (async () => {\n const identity = EffectContext.get(stack, IdentityContract.ManagerService).identity;\n if (identity) {\n // Identity.\n diagnostics.identity = buf.create(IdentitySchema, {\n did: identity.did,\n identityKey: fromPublicKey(identity.identityKey),\n spaceKey: fromPublicKey(identity.space.key),\n profile: identity.profileDocument,\n });\n\n // Devices.\n const { devices } =\n (await getFirstStreamValue(clientServices.DevicesService!.queryDevices(), {\n timeout: DEFAULT_TIMEOUT,\n }).catch(() => undefined)) ?? {};\n diagnostics.devices = devices;\n\n // TODO(dmaretskyi): Add metrics for halo space.\n\n // Spaces.\n const dataSpaceManager = EffectContext.get(stack, SpacesContract.ManagerService);\n diagnostics.spaces = await Promise.all(\n Array.from(dataSpaceManager.spaces.values()).map((space) => getSpaceStats(space)),\n );\n\n // Feeds.\n const { feeds = [] } =\n (await getFirstStreamValue(clientServices.DevtoolsHost!.subscribeToFeeds({}), {\n timeout: DEFAULT_TIMEOUT,\n }).catch(() => undefined)) ?? {};\n diagnostics.feeds = feeds.map(({ feedKey, bytes, length }) => ({ feedKey, bytes, length }));\n\n // Signal servers.\n\n const status = await getFirstStreamValue(clientServices.NetworkService!.queryStatus(), {\n timeout: DEFAULT_TIMEOUT,\n }).catch(() => undefined);\n diagnostics.networkStatus = status;\n\n // Networking.\n\n diagnostics.swarms = EffectContext.get(stack, SwarmNetworkManagerService).connectionLog?.swarms;\n }\n // Diagnostics are best-effort: a half-open space or a tag the stack has not built yet must\n // leave the other sections intact rather than failing the whole report.\n })().catch((err) => log.warn('failed to collect identity diagnostics', { err })),\n ]);\n\n diagnostics.config = config.values;\n\n return diagnostics;\n};\n\nconst getSpaceStats = async (space: DataSpace): Promise<SpaceStats> => {\n const stats: SpaceStats = {\n key: space.key,\n metrics: space.metrics,\n\n epochs: credentialsOfType<Epoch>('dxos.halo.credentials.Epoch')(space.inner.spaceState.credentials).map(\n ({ credential, assertion }) => ({ epoch: assertion, id: toPublicKey(credential.id) }),\n ),\n\n members: await Promise.all(\n Array.from(space.inner.spaceState.members.values()).map(async (member) =>\n buf.create(SpaceMemberSchema, {\n role: member.role,\n identity: buf.create(SpaceIdentitySchema, {\n did: await createDidFromIdentityKey(member.key),\n identityKey: fromPublicKey(member.key),\n profile: member.assertion.profile,\n }),\n presence:\n space.presence.getPeersByIdentityKey(member.key).length > 0\n ? SpaceMember_PresenceState.ONLINE\n : SpaceMember_PresenceState.OFFLINE,\n }),\n ),\n ),\n\n pipeline: buf.create(Space_PipelineStateSchema, {\n // TODO(burdon): Pick properties from credentials if needed.\n currentEpoch: space.automergeSpaceState.lastEpoch?.credential,\n appliedEpoch: space.automergeSpaceState.lastEpoch?.credential,\n\n controlFeeds: space.inner.controlPipeline.state.feeds.map((feed) => fromPublicKey(feed.key)),\n currentControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.timeframe),\n targetControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.targetTimeframe),\n totalControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.endTimeframe),\n }),\n };\n\n // TODO(burdon): Factor out.\n if (stats.metrics) {\n const open = toDate(stats.metrics.open);\n const ready = toDate(stats.metrics.ready);\n stats.metrics.startupTime = open && ready && ready.getTime() - open.getTime();\n }\n\n return stats;\n};\n\nconst getStorageDiagnostics = async () => {\n if (typeof navigator === 'undefined' || !navigator.storage) {\n return undefined;\n }\n const map = new Map();\n const dir = await navigator.storage.getDirectory();\n for await (const filename of (dir as any)?.keys()) {\n const idx = filename.indexOf('-', filename.indexOf('-') + 1);\n if (idx === -1) {\n continue;\n }\n\n map.set(filename.slice(0, idx), (map.get(filename.slice(0, idx)) ?? 0) + 1);\n }\n\n return Array.from(map.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([file, count]) => ({ file, count }));\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { decode as decodeCbor, encode as encodeCbor } from 'cbor-x';\n\nimport { Event, Mutex, scheduleMicroTask } from '@dxos/async';\nimport { Context, Resource } from '@dxos/context';\nimport { type EdgeConnection } from '@dxos/edge-client';\nimport { EdgeConnectionClosedError, EdgeIdentityChangedError } from '@dxos/edge-client';\nimport { type HypercoreWrapper } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey, type SpaceId } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { EdgeService } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport { EdgeStatus_ConnectionState } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport {\n type Message as RouterMessage,\n MessageSchema as RouterMessageSchema,\n} from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport type { FeedBlock, ProtocolMessage } from '@dxos/protocols/feed-replication';\nimport { ComplexMap, arrayToBuffer, bufferToArray, defaultMap, rangeFromTo } from '@dxos/util';\n\nexport type EdgeFeedReplicatorProps = {\n messenger: EdgeConnection;\n spaceId: SpaceId;\n};\n\nexport class EdgeFeedReplicator extends Resource {\n private readonly _messenger: EdgeConnection;\n\n @logInfo\n private readonly _spaceId: SpaceId;\n\n private readonly _feeds = new ComplexMap<PublicKey, HypercoreWrapper<any>>(PublicKey.hash);\n\n private _connectionCtx?: Context = undefined;\n private _connected = false;\n /**\n * Feed length at service.\n */\n private _remoteLength = new ComplexMap<PublicKey, number>(PublicKey.hash);\n\n /**\n * Protects against concurrent pushes so that remote length is updated consistently.\n */\n private _pushMutex = new ComplexMap<PublicKey, Mutex>(PublicKey.hash);\n\n /** Every block below this is held or already requested on this connection. */\n private _requestedUpTo = new ComplexMap<PublicKey, number>(PublicKey.hash);\n\n constructor({ messenger, spaceId }: EdgeFeedReplicatorProps) {\n super();\n this._messenger = messenger;\n this._spaceId = spaceId;\n }\n\n protected override async _open(): Promise<void> {\n log('open');\n // TODO: handle reconnects\n this._ctx.onDispose(\n this._messenger.onMessage((message: RouterMessage) => {\n if (!message.serviceId) {\n return;\n }\n const [service, ...rest] = message.serviceId.split(':');\n if (service !== EdgeService.FEED_REPLICATOR) {\n return;\n }\n\n const [spaceId] = rest;\n if (spaceId !== this._spaceId) {\n // Every space's replicator sees every peer's feed messages on the shared edge\n // connection, so each message is dropped by all but one replicator — O(spaces^2) lines\n // per sync round at anything above verbose.\n log.verbose('spaceID mismatch', { spaceId, _spaceId: this._spaceId });\n return;\n }\n\n const payload = decodeCbor(message.payload!.value) as ProtocolMessage;\n log('receive', { from: message.source, feedKey: payload.feedKey, type: payload.type });\n this._onMessage(payload);\n }),\n );\n\n this._ctx.onDispose(\n this._messenger.onReconnected(() => {\n scheduleMicroTask(this._ctx, () => this._handleReconnect());\n }),\n );\n }\n\n private async _handleReconnect(): Promise<void> {\n await this._resetConnection();\n if (this._messenger.status.state === EdgeStatus_ConnectionState.CONNECTED) {\n this._startReplication();\n }\n }\n\n protected override async _close(): Promise<void> {\n log('close');\n await this._resetConnection();\n }\n\n private _startReplication(): void {\n this._connected = true;\n const connectionCtx = this._createConnectionContext();\n this._connectionCtx = connectionCtx;\n log('connection context created');\n scheduleMicroTask(connectionCtx, async () => {\n for (const feed of this._feeds.values()) {\n await this._replicateFeed(connectionCtx, feed);\n }\n });\n }\n\n private async _resetConnection(): Promise<void> {\n log('resetConnection');\n this._connected = false;\n await this._connectionCtx?.dispose();\n this._connectionCtx = undefined;\n this._remoteLength.clear();\n this._requestedUpTo.clear();\n }\n\n async addHypercore(feed: HypercoreWrapper<any>): Promise<void> {\n log('addHypercore', { key: feed.key, connected: this._connected, hasConnectionCtx: !!this._connectionCtx });\n this._feeds.set(feed.key, feed);\n\n if (this._connected && this._connectionCtx) {\n await this._replicateFeed(this._connectionCtx, feed);\n }\n }\n\n private _getPushMutex(key: PublicKey): Mutex {\n return defaultMap(this._pushMutex, key, () => new Mutex());\n }\n\n private async _replicateFeed(ctx: Context, feed: HypercoreWrapper<any>): Promise<void> {\n log('replicateFeed', { key: feed.key });\n await this._sendMessage(ctx, {\n type: 'get-metadata',\n feedKey: feed.key.toHex(),\n });\n\n Event.wrap(feed.core as any, 'append').on(ctx, async () => {\n await this._pushBlocksIfNeeded(feed);\n });\n }\n\n private async _sendMessage(ctx: Context, message: ProtocolMessage): Promise<void> {\n if (!this._connectionCtx) {\n log('message dropped because connection was disposed');\n return;\n }\n\n if (message.type === 'data') {\n log('sending blocks', {\n feedKey: message.feedKey,\n blocks: message.blocks.map((b) => b.index),\n });\n }\n\n invariant(message.feedKey);\n const payloadValue = bufferToArray(encodeCbor(message));\n\n log('send', { type: message.type });\n await this._messenger.send(\n ctx,\n buf.create(RouterMessageSchema, {\n source: {\n identityDid: this._messenger.identityDid,\n peerKey: this._messenger.peerKey,\n },\n serviceId: `${EdgeService.FEED_REPLICATOR}:${this._spaceId}`,\n payload: { value: payloadValue },\n }),\n );\n }\n\n private _onMessage(message: ProtocolMessage): void {\n if (!this._connectionCtx) {\n log.warn('received message after connection context was disposed');\n return;\n }\n scheduleMicroTask(this._connectionCtx, async () => {\n switch (message.type) {\n case 'metadata': {\n const feedKey = PublicKey.fromHex(message.feedKey);\n const feed = this._feeds.get(feedKey);\n if (!feed) {\n log.warn('Feed not found', { feedKey });\n return;\n }\n\n using _guard = await this._getPushMutex(feed.key).acquire();\n\n // A reply computed before EDGE's latest push reports less than EDGE holds.\n const remoteLength = Math.max(this._remoteLength.get(feedKey) ?? 0, message.length);\n this._remoteLength.set(feedKey, remoteLength);\n\n // A sparse push moves `feed.length` past a gap, so compare block by block.\n const requestedUpTo = this._requestedUpTo.get(feedKey) ?? 0;\n const firstMissing = findFirstMissing(feed, requestedUpTo, message.length);\n this._requestedUpTo.set(feedKey, Math.max(requestedUpTo, firstMissing));\n const logMeta = { localLength: feed.length, remoteLength, firstMissing, feedKey };\n if (firstMissing < message.length) {\n log('requesting missing blocks', logMeta);\n this._requestedUpTo.set(feedKey, message.length);\n await this._sendMessage(this._connectionCtx!, {\n type: 'request',\n feedKey: feedKey.toHex(),\n range: { from: firstMissing, to: message.length },\n });\n } else if (remoteLength < feed.length && feed.has(remoteLength, feed.length)) {\n log('pushing blocks to remote', logMeta);\n\n await this._pushBlocks(this._connectionCtx!, feed, remoteLength, feed.length);\n }\n\n break;\n }\n\n case 'data': {\n log('received data', { feed: message.feedKey, blocks: message.blocks.map((b) => b.index) });\n\n const feedKey = PublicKey.fromHex(message.feedKey);\n const feed = this._feeds.get(feedKey);\n if (!feed) {\n log.warn('Feed not found', { feedKey });\n return;\n }\n\n const blocksEnd = message.blocks.reduce((end, block) => Math.max(end, block.index + 1), 0);\n // Raised before integrating, whose `append` would otherwise push these blocks back.\n this._remoteLength.set(feedKey, Math.max(this._remoteLength.get(feedKey) ?? 0, blocksEnd));\n await this._integrateBlocks(feed, message.blocks);\n await this._requestGapBelow(feed, blocksEnd);\n break;\n }\n\n default: {\n log.warn('Unknown message', { ...message });\n }\n }\n });\n }\n\n private async _pushBlocks(ctx: Context, feed: HypercoreWrapper<any>, from: number, to: number): Promise<void> {\n log('pushing blocks', { feed: feed.key.toHex(), from, to });\n\n const blocks: FeedBlock[] = await Promise.all(\n rangeFromTo(from, to).map(async (index) => {\n const data = await feed.get(index, { valueEncoding: 'binary' });\n invariant(data instanceof Uint8Array);\n const proof = await feed.proof(index);\n\n return {\n index,\n data,\n nodes: proof.nodes,\n signature: proof.signature,\n } satisfies FeedBlock;\n }),\n );\n\n await this._sendMessage(ctx, {\n type: 'data',\n feedKey: feed.key.toHex(),\n blocks,\n });\n // A push received during the send may have raised it past `to`.\n this._remoteLength.set(feed.key, Math.max(this._remoteLength.get(feed.key) ?? 0, to));\n }\n\n private async _integrateBlocks(feed: HypercoreWrapper<any>, blocks: FeedBlock[]): Promise<void> {\n log('integrating blocks', { feed: feed.key.toHex(), blocks: blocks.length });\n\n for (const block of blocks) {\n if (feed.has(block.index)) {\n continue;\n }\n const blockBuffer = bufferizeBlock(block);\n\n await feed.putBuffer(\n block.index,\n blockBuffer.data,\n { nodes: blockBuffer.nodes, signature: blockBuffer.signature },\n null,\n );\n }\n }\n\n /** Requests the blocks missing below `to`; a push carries only the newest blocks. */\n private async _requestGapBelow(feed: HypercoreWrapper<any>, to: number): Promise<void> {\n if (!this._connectionCtx) {\n return;\n }\n const requestedUpTo = this._requestedUpTo.get(feed.key) ?? 0;\n const from = findFirstMissing(feed, requestedUpTo, to);\n this._requestedUpTo.set(feed.key, Math.max(requestedUpTo, from));\n if (from < to) {\n log('requesting blocks missing below a pushed block', { feedKey: feed.key, from, to });\n this._requestedUpTo.set(feed.key, to);\n await this._sendMessage(this._connectionCtx, { type: 'request', feedKey: feed.key.toHex(), range: { from, to } });\n }\n }\n\n private async _pushBlocksIfNeeded(feed: HypercoreWrapper<any>): Promise<void> {\n using _ = await this._getPushMutex(feed.key).acquire();\n\n if (!this._remoteLength.has(feed.key)) {\n log('blocks not pushed because remote length is unknown');\n return;\n }\n\n const remoteLength = this._remoteLength.get(feed.key)!;\n // A sparse put also emits `append`, and `feed.get` on a hole never resolves.\n if (remoteLength < feed.length && feed.has(remoteLength, feed.length)) {\n await this._pushBlocks(this._connectionCtx!, feed, remoteLength, feed.length);\n }\n }\n\n private _createConnectionContext(): Context {\n const connectionCtx = new Context({\n parent: this._ctx,\n onError: async (err: any) => {\n if (connectionCtx !== this._connectionCtx) {\n return;\n }\n if (err instanceof EdgeIdentityChangedError || err instanceof EdgeConnectionClosedError) {\n log('resetting on reconnect');\n await this._resetConnection();\n } else {\n this._ctx.raise(err);\n }\n },\n });\n return connectionCtx;\n }\n}\n\n/** Index of the first block in `[from, to)` the feed does not hold, or `to` when it holds them all. */\nconst findFirstMissing = (feed: HypercoreWrapper<any>, from: number, to: number): number => {\n for (let index = from; index < to; index++) {\n if (!feed.has(index)) {\n return index;\n }\n }\n return to;\n};\n\n// hypercore requires buffers\nconst bufferizeBlock = (block: FeedBlock) => ({\n index: block.index,\n data: arrayToBuffer(block.data),\n nodes: block.nodes.map((node) => ({\n index: node.index,\n hash: arrayToBuffer(node.hash),\n size: node.size,\n })),\n signature: arrayToBuffer(block.signature),\n});\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { Event } from '@dxos/async';\nimport { AUTH_TIMEOUT, LOAD_CONTROL_FEEDS_TIMEOUT } from '@dxos/client-protocol';\nimport { type Context as DxosContext } from '@dxos/context';\nimport {\n type CredentialSigner,\n DeviceStateMachine,\n type InboxEnvelopeSigner,\n ProfileStateMachine,\n createCredentialSignerWithChain,\n createCredentialSignerWithKey,\n credentialPayload,\n} from '@dxos/credentials';\nimport { type Signer } from '@dxos/crypto';\nimport { type EdgeConnection } from '@dxos/edge-client';\nimport { type HypercoreWrapper, writeMessages } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type IdentityDid, PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport {\n AdmittedFeed_Designation,\n AdmittedFeedSchema,\n AuthorizedDeviceSchema,\n type Credential,\n type DeviceProfileDocument,\n type ProfileDocument,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type DeviceAdmissionRequest } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type Presence } from '@dxos/teleport-extension-gossip';\nimport { trace } from '@dxos/tracing';\nimport { type ComplexMap, ComplexSet } from '@dxos/util';\n\nimport * as Auth from './Auth.ts';\nimport { type Space } from './internal/space/index.ts';\nimport { EdgeFeedReplicator } from './Replication.ts';\n\nexport type IdentityProps = {\n did: IdentityDid;\n identityKey: PublicKey;\n deviceKey: PublicKey;\n signer: Signer;\n space: Space;\n presence?: Presence;\n\n edgeConnection?: EdgeConnection;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n};\n\n/**\n * Agent identity manager, which includes the agent's Halo space.\n */\nexport class Identity {\n public readonly space: Space;\n private readonly _signer: Signer;\n private readonly _presence?: Presence;\n private readonly _deviceStateMachine: DeviceStateMachine;\n private readonly _profileStateMachine: ProfileStateMachine;\n private readonly _edgeFeedReplicator?: EdgeFeedReplicator = undefined;\n private _haloSpaceRootUrl?: string = undefined;\n\n public readonly authVerifier: Auth.TrustedKeySetAuthVerifier;\n\n public readonly did: IdentityDid;\n public readonly identityKey: PublicKey;\n public readonly deviceKey: PublicKey;\n\n public readonly stateUpdate = new Event();\n\n constructor(params: IdentityProps) {\n this.space = params.space;\n this._signer = params.signer;\n this._presence = params.presence;\n\n this.did = params.did;\n this.identityKey = params.identityKey;\n this.deviceKey = params.deviceKey;\n\n log.trace('dxos.halo.device', { deviceKey: params.deviceKey });\n\n this._deviceStateMachine = new DeviceStateMachine({\n identityKey: this.identityKey,\n deviceKey: this.deviceKey,\n onUpdate: () => this.stateUpdate.emit(),\n });\n this._profileStateMachine = new ProfileStateMachine({\n identityKey: this.identityKey,\n onUpdate: () => this.stateUpdate.emit(),\n });\n\n this.authVerifier = new Auth.TrustedKeySetAuthVerifier({\n trustedKeysProvider: () => new ComplexSet(PublicKey.hash, this.authorizedDeviceKeys.keys()),\n update: this.stateUpdate,\n authTimeout: AUTH_TIMEOUT,\n });\n\n if (params.edgeConnection && params.edgeFeatures?.feedReplicator) {\n this._edgeFeedReplicator = new EdgeFeedReplicator({ messenger: params.edgeConnection, spaceId: this.space.id });\n }\n }\n\n // TODO(burdon): Expose state object?\n get authorizedDeviceKeys(): ComplexMap<PublicKey, DeviceProfileDocument> {\n return this._deviceStateMachine.authorizedDeviceKeys;\n }\n\n @trace.span({ op: 'lifecycle' })\n async open(ctx: DxosContext): Promise<void> {\n await this._presence?.open();\n await this.space.spaceState.addCredentialProcessor(this._deviceStateMachine);\n await this.space.spaceState.addCredentialProcessor(this._profileStateMachine);\n if (this._edgeFeedReplicator) {\n this.space.protocol.feedAdded.append(this._onFeedAdded);\n }\n await this.space.open(ctx);\n }\n\n public async joinNetwork(ctx: DxosContext): Promise<void> {\n await this.space.startProtocol(ctx);\n await this._edgeFeedReplicator?.open();\n }\n\n @trace.span({ op: 'lifecycle' })\n async close(ctx: DxosContext): Promise<void> {\n await this._presence?.close();\n await this.authVerifier.close();\n await this.space.spaceState.removeCredentialProcessor(this._profileStateMachine);\n await this.space.spaceState.removeCredentialProcessor(this._deviceStateMachine);\n\n if (this._edgeFeedReplicator) {\n this.space.protocol.feedAdded.remove(this._onFeedAdded);\n }\n\n await this._edgeFeedReplicator?.close();\n\n await this.space.close(ctx);\n }\n\n async ready(): Promise<void> {\n await this._deviceStateMachine.deviceChainReady.wait();\n\n await this.controlPipeline.state.waitUntilReachedTargetTimeframe({ timeout: LOAD_CONTROL_FEEDS_TIMEOUT });\n }\n\n get profileDocument(): ProfileDocument | undefined {\n return this._profileStateMachine.profile;\n }\n\n /**\n * @test-only\n */\n get controlPipeline() {\n return this.space.controlPipeline;\n }\n\n get haloSpaceId() {\n return this.space.id;\n }\n\n /**\n * Automerge URL of the halo space root, once anchored. Handed to a joining device so it replicates\n * the credential chain as a document; undefined while the space is still feed-only.\n */\n get haloSpaceRootUrl(): string | undefined {\n return this._haloSpaceRootUrl;\n }\n\n setHaloSpaceRootUrl(url: string): void {\n this._haloSpaceRootUrl = url;\n }\n\n get haloSpaceKey() {\n return this.space.key;\n }\n\n get haloGenesisFeedKey() {\n return this.space.genesisFeedKey;\n }\n\n get deviceCredentialChain() {\n return this._deviceStateMachine.deviceCredentialChain;\n }\n\n get presence() {\n return this._presence;\n }\n\n get signer() {\n return this._signer;\n }\n\n /**\n * Issues credentials as identity.\n * Requires identity to be ready.\n */\n getIdentityCredentialSigner(): CredentialSigner {\n invariant(this._deviceStateMachine.deviceCredentialChain, 'Device credential chain is not ready.');\n return createCredentialSignerWithChain(\n this._signer,\n this._deviceStateMachine.deviceCredentialChain,\n this.deviceKey,\n );\n }\n\n /**\n * Signs inbox envelopes as identity, with the device key and its delegation chain.\n */\n getInboxEnvelopeSigner(): InboxEnvelopeSigner {\n invariant(this._deviceStateMachine.deviceCredentialChain, 'Device credential chain is not ready.');\n return {\n identityKey: this.identityKey,\n signingKey: this.deviceKey,\n chain: this._deviceStateMachine.deviceCredentialChain,\n signer: this._signer,\n };\n }\n\n /**\n * Issues credentials as device.\n */\n getDeviceCredentialSigner(): CredentialSigner {\n return createCredentialSignerWithKey(this._signer, this.deviceKey);\n }\n\n async admitDevice(request: DeviceAdmissionRequest): Promise<Credential> {\n const deviceKey = requirePublicKey(request.deviceKey);\n const controlFeedKey = requirePublicKey(request.controlFeedKey);\n const dataFeedKey = requirePublicKey(request.dataFeedKey);\n log('Admitting device:', {\n identityKey: this.identityKey,\n hostDevice: this.deviceKey,\n deviceKey,\n controlFeedKey,\n dataFeedKey,\n });\n const signer = this.getIdentityCredentialSigner();\n const deviceCredential = await signer.createCredential({\n subject: deviceKey,\n assertion: create(AuthorizedDeviceSchema, {\n identityKey: fromPublicKey(this.identityKey),\n deviceKey: fromPublicKey(deviceKey),\n }),\n });\n await writeMessages(\n this.controlPipeline.writer,\n [\n deviceCredential,\n await signer.createCredential({\n subject: controlFeedKey,\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(this.haloSpaceKey),\n deviceKey: fromPublicKey(deviceKey),\n identityKey: fromPublicKey(this.identityKey),\n designation: AdmittedFeed_Designation.CONTROL,\n }),\n }),\n await signer.createCredential({\n subject: dataFeedKey,\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(this.haloSpaceKey),\n deviceKey: fromPublicKey(deviceKey),\n identityKey: fromPublicKey(this.identityKey),\n designation: AdmittedFeed_Designation.DATA,\n }),\n }),\n ].map(credentialPayload),\n );\n\n return deviceCredential;\n }\n\n private _onFeedAdded = async (feed: HypercoreWrapper<any>) => {\n await this._edgeFeedReplicator!.addHypercore(feed);\n };\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { SubscriptionList, UpdateScheduler, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type MemberInfo, createDidFromIdentityKey } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { PublicKey } from '@dxos/keys';\nimport { buf, fromPublicKey } from '@dxos/protocols/buf';\nimport {\n type Contact,\n type ContactBook,\n ContactBookSchema,\n ContactSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { ContactsService } from '@dxos/protocols/rpc';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Readiness from '../../Readiness.ts';\nimport { type SpaceManager, SpaceManagerService } from '../space/index.ts';\n\nexport class ContactsServiceImpl implements ContactsService.Handlers {\n 'constructor'(\n private readonly _identityManager: IdentityContract.Manager,\n private readonly _spaceManager: SpaceManager,\n private readonly _dataSpaceManagerProvider: () => Promise<SpacesContract.Manager>,\n ) {}\n\n ['ContactsService.getContacts'](): Effect.Effect<ContactBook, Error> {\n return Effect.promise(() => this.#getContacts());\n }\n\n ['ContactsService.queryContacts'](): EffectStream.Stream<ContactBook, Error> {\n const subscribedSpaceKeySet = new ComplexSet(PublicKey.hash);\n return EffectEx.streamFromEmitter<ContactBook, Error>((emit) => {\n const ctx = Context.default();\n const pushUpdateTask = new UpdateScheduler(\n ctx,\n async () => {\n void emit.single(await this.#getContacts());\n },\n { maxFrequency: 2 },\n );\n scheduleTask(ctx, async () => {\n const subscriptions = new SubscriptionList();\n ctx.onDispose(() => subscriptions.clear());\n const subscribeToSpaceAndUpdate = () => {\n const oldSetSize = subscribedSpaceKeySet.size;\n for (const space of this._spaceManager.spaces.values()) {\n if (!subscribedSpaceKeySet.has(space.key)) {\n subscriptions.add(space.stateUpdate.on(ctx, () => pushUpdateTask.trigger()));\n subscribedSpaceKeySet.add(space.key);\n }\n }\n if (oldSetSize !== subscribedSpaceKeySet.size) {\n pushUpdateTask.trigger();\n }\n };\n const unsubscribe = (await this._dataSpaceManagerProvider()).updated.on(ctx, subscribeToSpaceAndUpdate);\n ctx.onDispose(unsubscribe);\n subscribeToSpaceAndUpdate();\n });\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n async #getContacts(): Promise<ContactBook> {\n const identity = this._identityManager.identity;\n if (identity == null) {\n return buf.create(ContactBookSchema, { contacts: [] });\n }\n const contacts = [...this._spaceManager.spaces.values()]\n .flatMap((s) => [...s.spaceState.members.values()].map((m) => [s.key, m]))\n .reduce((acc, v) => {\n const [spaceKey, memberInfo] = v as [PublicKey, MemberInfo];\n if (memberInfo.key.equals(identity.identityKey)) {\n return acc;\n }\n const existing = acc.get(memberInfo.key);\n if (existing != null) {\n existing.profile ??= memberInfo.profile;\n existing.commonSpaces.push(fromPublicKey(spaceKey));\n } else {\n acc.set(\n memberInfo.key,\n buf.create(ContactSchema, {\n identityKey: fromPublicKey(memberInfo.key),\n profile: memberInfo.profile,\n commonSpaces: [fromPublicKey(spaceKey)],\n }),\n );\n }\n return acc;\n }, new ComplexMap<PublicKey, Contact>(PublicKey.hash));\n // Derived here (and cached by key) so clients can show the DID without hashing each key themselves.\n await Promise.all(\n [...contacts.entries()].map(async ([identityKey, contact]) => {\n contact.did = await createDidFromIdentityKey(identityKey);\n }),\n );\n return buf.create(ContactBookSchema, { contacts: [...contacts.values()] });\n }\n}\n\nexport const ContactsServiceLayer = Layer.effect(\n ContactsService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const spaceManager = yield* SpaceManagerService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const readiness = yield* Readiness.StackReadinessService;\n return new ContactsServiceImpl(identityManager, spaceManager, () =>\n readiness.initialized.wait().then(() => dataSpaceManager),\n );\n }),\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create, fromBinary } from '@bufbuild/protobuf';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { synchronized } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport {\n credentialPayload,\n generateSeedPhrase,\n getCredentialAssertion,\n keyPairFromSeedPhrase,\n} from '@dxos/credentials';\nimport { sign } from '@dxos/crypto';\nimport { type EdgeHttpClient, EdgeHttpClientService } from '@dxos/edge-client';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n EdgeAuthChallengeError,\n EdgeCallFailedError,\n type RecoverIdentityRequest as EdgeRecoverIdentityRequest,\n InvalidRecoveryTokenError,\n type RecoverIdentityResponseBody,\n} from '@dxos/protocols';\nimport { fromDate, fromPublicKey, requirePublicKey } from '@dxos/protocols/buf';\nimport { type RecoverIdentityRequest_ExternalSignature } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport {\n type Credential,\n CredentialSchema,\n type IdentityRecovery,\n IdentityRecovery_Kind,\n IdentityRecoveryRevokedSchema,\n IdentityRecoverySchema,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type IdentityService } from '@dxos/protocols/rpc';\nimport { Timeframe } from '@dxos/timeframe';\nimport { ComplexSet } from '@dxos/util';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type JoinIdentityProps } from './identity-manager.ts';\n\n/**\n * Effect service tag for {@link EdgeIdentityRecoveryManager}.\n */\nexport class EdgeIdentityRecoveryManagerService extends EffectContext.Service<\n EdgeIdentityRecoveryManagerService,\n EdgeIdentityRecoveryManager\n>()('@dxos/client-services/EdgeIdentityRecoveryManager') {}\n\nexport type AcceptRecoveredIdentity = (params: JoinIdentityProps) => Promise<Identity>;\n\nexport class EdgeIdentityRecoveryManager {\n private _acceptRecoveredIdentity?: AcceptRecoveredIdentity;\n\n constructor(\n private readonly _keyring: KeyringApi,\n private readonly _edgeClient: EdgeHttpClient | undefined,\n private readonly _identityProvider: () => Identity | undefined,\n ) {}\n\n /**\n * Wires identity acceptance after the composing stack is fully constructed.\n */\n setAcceptRecoveredIdentity(acceptRecoveredIdentity: AcceptRecoveredIdentity): void {\n this._acceptRecoveredIdentity = acceptRecoveredIdentity;\n }\n\n public async createRecoveryCredential({\n data,\n }: IdentityService.CreateRecoveryCredentialRequest): Promise<{ recoveryCode: string | undefined }> {\n const identity = this._identityProvider();\n invariant(identity);\n\n let recoveryKey: PublicKey;\n let lookupKey: PublicKey;\n let algorithm: string;\n let recoveryCode: string | undefined;\n let kind: IdentityRecovery_Kind;\n let label: string | undefined;\n if (data) {\n recoveryKey = data.recoveryKey;\n lookupKey = data.lookupKey;\n algorithm = data.algorithm;\n kind = data.kind ?? IdentityRecovery_Kind.UNKNOWN;\n label = data.label;\n } else {\n // The seed phrase is generated here rather than by the caller, so the label is too.\n recoveryCode = await generateSeedPhrase();\n const keypair = await keyPairFromSeedPhrase(recoveryCode);\n recoveryKey = PublicKey.from(keypair.publicKey);\n lookupKey = PublicKey.from(keypair.publicKey);\n algorithm = 'ED25519';\n kind = IdentityRecovery_Kind.RECOVERY_CODE;\n label = 'Recovery code';\n }\n\n const identityKey = identity.identityKey;\n const credential = await identity.getIdentityCredentialSigner().createCredential({\n subject: identityKey,\n assertion: create(IdentityRecoverySchema, {\n recoveryKey: fromPublicKey(recoveryKey),\n identityKey: fromPublicKey(identityKey),\n algorithm,\n lookupKey: fromPublicKey(lookupKey),\n label,\n kind,\n }),\n });\n\n const receipt = await identity.controlPipeline.writer.write(credentialPayload(credential));\n await identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));\n\n return { recoveryCode };\n }\n\n /**\n * Revoke a recovery credential by writing an `IdentityRecoveryRevoked` assertion to the identity's\n * control feed, mirroring how `SpaceDeleted` tombstones a space: the feed is append-only, so the\n * original credential stays and this marks it spent. The assertion replicates to the user's other\n * devices and to their agent, which is what drives the server-side refusal.\n *\n * Refuses the last un-revoked credential. Doing so would leave the holder unable to recover their\n * identity with no self-service way back — the replacement has to be added first.\n *\n * `@synchronized` so two revocations on this device cannot both observe two active credentials and\n * each cancel a different one. It cannot serialize across devices: the control feed is append-only\n * with no consensus, so two devices revoking at once can still drive the count to zero. The agents\n * service is the authority there — it re-checks the active count before flipping a row to REVOKED.\n */\n @synchronized\n public async revokeRecoveryCredential({ lookupKey }: { lookupKey: PublicKey }): Promise<void> {\n const identity = this._identityProvider();\n invariant(identity);\n\n const active = this.listActiveRecoveryCredentials();\n if (!active.some(({ assertion }) => requirePublicKey(assertion.lookupKey).equals(lookupKey))) {\n throw new Error('Recovery credential is not registered, or is already revoked.');\n }\n if (active.length <= 1) {\n throw new Error('Cannot revoke the only remaining recovery credential; add another one first.');\n }\n\n const identityKey = identity.identityKey;\n const credential = await identity.getIdentityCredentialSigner().createCredential({\n subject: identityKey,\n assertion: create(IdentityRecoveryRevokedSchema, {\n identityKey: fromPublicKey(identityKey),\n lookupKey: fromPublicKey(lookupKey),\n revokedAt: fromDate(new Date()),\n }),\n });\n\n const receipt = await identity.controlPipeline.writer.write(credentialPayload(credential));\n await identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));\n }\n\n /**\n * Recovery credentials in the identity's HALO that no `IdentityRecoveryRevoked` assertion cancels.\n *\n * Credentials written before `lookupKey` existed cannot be matched by a revocation, so they are\n * always active — and still count towards the last-credential check, since they remain usable.\n */\n public listActiveRecoveryCredentials(): { credential: Credential; assertion: IdentityRecovery }[] {\n const identity = this._identityProvider();\n invariant(identity);\n\n const revoked = new ComplexSet<PublicKey>(PublicKey.hash);\n const registered: { credential: Credential; assertion: IdentityRecovery }[] = [];\n for (const credential of identity.space.spaceState.credentials) {\n const assertion = getCredentialAssertion(credential);\n switch (assertion.$typeName) {\n case 'dxos.halo.credentials.IdentityRecovery':\n registered.push({ credential, assertion });\n break;\n case 'dxos.halo.credentials.IdentityRecoveryRevoked':\n revoked.add(requirePublicKey(assertion.lookupKey));\n break;\n }\n }\n\n return registered.filter(\n ({ assertion }) => !(assertion.lookupKey && revoked.has(requirePublicKey(assertion.lookupKey))),\n );\n }\n\n public async requestRecoveryChallenge(ctx: Context) {\n invariant(this._edgeClient, 'Not connected to EDGE.');\n\n const deviceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const request: EdgeRecoverIdentityRequest = {\n deviceKey: deviceKey.toHex(),\n controlFeedKey: controlFeedKey.toHex(),\n };\n\n try {\n await this._edgeClient.recoverIdentity(ctx, request);\n throw new Error('No challenge received.');\n } catch (error: any) {\n if (!(error instanceof EdgeAuthChallengeError)) {\n throw error;\n }\n return {\n deviceKey,\n controlFeedKey,\n challenge: error.challenge,\n };\n }\n }\n\n public async recoverIdentityWithExternalSignature(\n ctx: Context,\n {\n lookupKey,\n deviceKey,\n controlFeedKey,\n signature,\n clientDataJson,\n authenticatorData,\n }: RecoverIdentityRequest_ExternalSignature,\n ): Promise<void> {\n invariant(this._edgeClient, 'Not connected to EDGE.');\n\n const deviceKeyValue = requirePublicKey(deviceKey);\n const controlFeedKeyValue = requirePublicKey(controlFeedKey);\n const request: EdgeRecoverIdentityRequest = {\n lookupKey: requirePublicKey(lookupKey).toHex(),\n deviceKey: deviceKeyValue.toHex(),\n controlFeedKey: controlFeedKeyValue.toHex(),\n signature:\n clientDataJson && authenticatorData\n ? {\n signature: Buffer.from(signature).toString('base64'),\n clientDataJson: Buffer.from(clientDataJson).toString('base64'),\n authenticatorData: Buffer.from(authenticatorData).toString('base64'),\n }\n : Buffer.from(signature).toString('base64'),\n };\n\n const response = await this._edgeClient.recoverIdentity(ctx, request);\n\n await this.#acceptRecoveredIdentity({\n authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),\n haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),\n haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),\n identityKey: PublicKey.fromHex(response.identityKey),\n deviceKey: deviceKeyValue,\n controlFeedKey: controlFeedKeyValue,\n dataFeedKey: await this._keyring.createKey(),\n haloSpaceRootUrl: response.haloSpaceRootUrl,\n });\n }\n\n /**\n * Recover an identity using an opaque one-time token. Accepts either an email magic-link\n * `token` (validated by hub-service) or an OAuth `recoveryProof` (redeemed by kms-service).\n * The two fields are routed to different backends by db-service and must not be conflated.\n */\n public async recoverIdentityWithToken(\n ctx: Context,\n fields: { token: string } | { recoveryProof: string },\n ): Promise<void> {\n invariant(this._edgeClient, 'Not connected to EDGE.');\n\n const deviceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const request: EdgeRecoverIdentityRequest = {\n deviceKey: deviceKey.toHex(),\n controlFeedKey: controlFeedKey.toHex(),\n ...fields,\n };\n\n const response = await this._edgeClient.recoverIdentity(ctx, request).catch((error) => {\n // Rethrow the registered class so the token-rejection identity survives the services RPC boundary.\n if (error instanceof EdgeCallFailedError && InvalidRecoveryTokenError.is(error.cause)) {\n throw new InvalidRecoveryTokenError({ cause: error });\n }\n throw error;\n });\n\n await this.#acceptRecoveredIdentity({\n authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),\n haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),\n haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),\n identityKey: PublicKey.fromHex(response.identityKey),\n deviceKey,\n controlFeedKey,\n dataFeedKey: await this._keyring.createKey(),\n });\n }\n\n public async recoverIdentity(ctx: Context, { recoveryCode }: { recoveryCode: string }): Promise<void> {\n invariant(this._edgeClient, 'Not connected to EDGE.');\n\n const recoveryKeypair = await keyPairFromSeedPhrase(recoveryCode);\n const recoveryKey = PublicKey.from(recoveryKeypair.publicKey);\n const deviceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const request: EdgeRecoverIdentityRequest = {\n lookupKey: recoveryKey.toHex(),\n deviceKey: deviceKey.toHex(),\n controlFeedKey: controlFeedKey.toHex(),\n };\n\n let response: RecoverIdentityResponseBody;\n try {\n response = await this._edgeClient.recoverIdentity(ctx, request);\n } catch (error: any) {\n if (!(error instanceof EdgeAuthChallengeError)) {\n throw error;\n }\n const signature = sign(Buffer.from(error.challenge, 'base64'), recoveryKeypair.secretKey);\n response = await this._edgeClient.recoverIdentity(ctx, {\n ...request,\n signature: Buffer.from(signature).toString('base64'),\n });\n }\n\n log.info('recovering identity', response);\n\n await this.#acceptRecoveredIdentity({\n authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),\n haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),\n haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),\n identityKey: PublicKey.fromHex(response.identityKey),\n deviceKey,\n controlFeedKey,\n dataFeedKey: await this._keyring.createKey(),\n });\n }\n\n #acceptRecoveredIdentity(params: JoinIdentityProps): Promise<Identity> {\n invariant(this._acceptRecoveredIdentity, 'acceptRecoveredIdentity not set');\n return this._acceptRecoveredIdentity(params);\n }\n}\n\nconst decodeCredential = (credentialBase64: string): Credential =>\n fromBinary(CredentialSchema, Buffer.from(credentialBase64, 'base64'));\n\n/**\n * Effect Layer constructing a dormant {@link EdgeIdentityRecoveryManager}.\n */\nexport const EdgeIdentityRecoveryManagerLayer = (): Layer.Layer<\n EdgeIdentityRecoveryManagerService,\n never,\n KeyringApiService | IdentityContract.ManagerService\n> =>\n Layer.effect(\n EdgeIdentityRecoveryManagerService,\n Effect.gen(function* () {\n const keyring = yield* KeyringApiService;\n const edgeClient = yield* Effect.serviceOption(EdgeHttpClientService);\n const identityManager = yield* IdentityContract.ManagerService;\n return new EdgeIdentityRecoveryManager(\n keyring,\n Option.getOrUndefined(edgeClient),\n () => identityManager.identity,\n );\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { type Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { log } from '@dxos/log';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type CreateIdentityOptions, type JoinIdentityProps } from './identity-manager.ts';\nimport { EdgeIdentityRecoveryManagerService } from './identity-recovery-manager.ts';\n\n/**\n * Brings a new identity into the running stack: binds it to the network, joins, and announces it so\n * the identity-bound services open. The persisted identity on boot goes through the same events\n * from the host's open sequence.\n */\nexport interface IdentityLifecycle {\n /** Creates a fresh identity and resolves once its identity-bound services are open. */\n createIdentity(params?: CreateIdentityOptions, ctx?: Context): Promise<Identity>;\n /** Adopts an identity admitted by another device and resolves once its services are open. */\n acceptIdentity(params: JoinIdentityProps): Promise<Identity>;\n}\n\nexport const IdentityLifecycleLayer: Layer.Layer<\n IdentityContract.LifecycleService,\n never,\n Hook.Controller | IdentityContract.ManagerService | EdgeIdentityRecoveryManagerService\n> = Layer.effect(\n IdentityContract.LifecycleService,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const recoveryManager = yield* EdgeIdentityRecoveryManagerService;\n const runtime = yield* RuntimeProvider.currentRuntime<Hook.Controller>();\n const ctx = yield* EffectEx.contextFromScope();\n\n const lifecycle = createIdentityLifecycle({ identityManager, ctx, runtime });\n recoveryManager.setAcceptRecoveredIdentity((params) => lifecycle.acceptIdentity(params));\n\n // The persisted identity joins once networking is up; a missing identity leaves the stack\n // dormant until one is created or accepted.\n yield* Hook.on(\n Events.NetworkReady,\n Effect.fn('IdentityLifecycle.onNetworkReady')(function* () {\n const identity = identityManager.identity;\n if (!identity) {\n log('no identity, skipping network join');\n return;\n }\n log('joining network...');\n yield* Effect.promise(() => identity.joinNetwork(ctx));\n yield* Hook.emit(Events.IdentityAvailable, { identity });\n }),\n );\n return lifecycle;\n }),\n);\n\nconst createIdentityLifecycle = ({\n identityManager,\n ctx: defaultCtx,\n runtime,\n}: {\n identityManager: IdentityContract.Manager;\n ctx: Context;\n runtime: RuntimeProvider.RuntimeProvider<Hook.Controller>;\n}): IdentityLifecycle => {\n const emit = RuntimeProvider.runPromise(runtime);\n\n return {\n createIdentity: async (params = {}, ctx = defaultCtx) => {\n const identity = await identityManager.createIdentity(params, ctx);\n await emit(Hook.emit(Events.IdentityBound, { identity }));\n await identity.joinNetwork(ctx);\n await emit(Hook.emit(Events.IdentityAvailable, { identity }));\n log('identity created', { identityKey: identity.identityKey });\n return identity;\n },\n\n acceptIdentity: async (params) => {\n const ctx = defaultCtx;\n const { identity, identityRecord } = await identityManager.prepareIdentity(params, ctx);\n try {\n await emit(Hook.emit(Events.IdentityBound, { identity, deviceCredential: params.authorizedDeviceCredential }));\n await identity.joinNetwork(ctx);\n } catch (err) {\n // Nothing owns the prepared identity until the manager accepts it.\n await identity.close(ctx).catch((closeErr) => log.catch(closeErr));\n throw err;\n }\n await identityManager.acceptIdentity(identity, identityRecord, params.deviceProfile);\n await emit(Hook.emit(Events.IdentityAvailable, { identity }));\n log('identity accepted', { identityKey: identity.identityKey });\n return identity;\n },\n };\n};\n","//\n// Copyright 2022 DXOS.org\n//\nimport { isValidAutomergeUrl } from '@automerge/automerge-repo';\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport platform from 'platform';\n\nimport { Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport {\n CredentialGenerator,\n createCredentialSignerWithKey,\n createDidFromIdentityKey,\n credentialPayload,\n} from '@dxos/credentials';\nimport { failUndefined } from '@dxos/debug';\nimport { type EchoHost } from '@dxos/echo-host';\nimport { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { type HypercoreStore, HypercoreStoreService } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { fromPublicKey, fromTimeframe, requirePublicKey, toTimeframe } from '@dxos/protocols/buf';\nimport {\n type Device,\n Device_PresenceState,\n DeviceKind,\n DeviceSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type FeedMessage } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport {\n type IdentityRecord,\n IdentityRecordSchema,\n type SpaceMetadata,\n SpaceMetadataSchema,\n} from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport {\n AdmittedFeed_Designation,\n type Credential,\n type DeviceProfileDocument,\n DeviceProfileDocumentSchema,\n DeviceProfileSchema,\n DeviceType,\n IdentityProfileSchema,\n type ProfileDocument,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { Gossip, Presence } from '@dxos/teleport-extension-gossip';\nimport { Timeframe } from '@dxos/timeframe';\nimport { trace as Trace } from '@dxos/tracing';\nimport { deferFunction, isNode, isTauri } from '@dxos/util';\n\nimport * as Auth from '../../Auth.ts';\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport { openCredentialsDocument } from '../../CredentialsDocument.ts';\nimport * as Events from '../../Events.ts';\nimport { Identity } from '../../Identity.ts';\nimport { type IMetadataStore, IMetadataStoreService } from '../metadata/index.ts';\nimport { type SpaceManager, SpaceManagerService, type SwarmIdentity } from '../space/index.ts';\n\nconst DEVICE_PRESENCE_ANNOUNCE_INTERVAL = 10_000;\nconst DEVICE_PRESENCE_OFFLINE_TIMEOUT = 20_000;\n\ninterface ConstructSpaceProps {\n spaceRecord: SpaceMetadata;\n swarmIdentity: SwarmIdentity;\n identityKey: PublicKey;\n gossip: Gossip;\n}\n\nexport type JoinIdentityProps = {\n identityKey: PublicKey;\n deviceKey: PublicKey;\n haloSpaceKey: PublicKey;\n haloGenesisFeedKey: PublicKey;\n controlFeedKey: PublicKey;\n dataFeedKey: PublicKey;\n authorizedDeviceCredential: Credential;\n /**\n * Automerge URL of the host's halo space root, when it has one. The joining device adopts it rather\n * than minting a second root over the same space.\n */\n haloSpaceRootUrl?: string;\n\n /**\n * Latest known timeframe for the control pipeline.\n * We will try to catch up to this timeframe before starting the data pipeline.\n */\n controlTimeframe?: Timeframe;\n // Custom device profile, merged with defaults, to be applied once the identity is accepted.\n deviceProfile?: DeviceProfileDocument;\n};\n\nexport type CreateIdentityOptions = {\n profile?: ProfileDocument;\n // device profile for device creating the identity.\n deviceProfile?: DeviceProfileDocument;\n};\n\nexport type IdentityManagerProps = {\n metadataStore: IMetadataStore;\n keyring: KeyringApi;\n hypercoreStore: HypercoreStore<FeedMessage>;\n spaceManager: SpaceManager;\n edgeConnection?: EdgeConnection;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n devicePresenceAnnounceInterval?: number;\n devicePresenceOfflineTimeout?: number;\n /** See {@link DataSpaceManagerRuntimeProps.automergeCredentials}. Off by default. */\n automergeCredentials?: boolean;\n};\n\n/**\n * Resolves the active identity when it becomes available.\n */\nexport type IdentityProvider = () => Identity;\n\n/**\n * Builds an {@link IdentityProvider} from an {@link IdentityManager}.\n */\nexport const identityProviderFromManager =\n (identityManager: IdentityContract.Manager): IdentityContract.Provider =>\n () =>\n identityManager.identity ?? failUndefined();\n\n// TODO(dmaretskyi): Rename: represents the peer's state machine.\nexport class IdentityManager {\n readonly stateUpdate = new Event();\n\n private readonly _metadataStore: IMetadataStore;\n private readonly _keyring: KeyringApi;\n private readonly _hypercoreStore: HypercoreStore<FeedMessage>;\n private readonly _spaceManager: SpaceManager;\n /**\n * Set late by the service stack: `EchoHostLayer` already depends on this manager for its peer id,\n * so taking the host as a constructor dependency would make the layer graph circular. Anchoring is\n * driven by whichever of the two arrives last.\n */\n private _echoHost: EchoHost | undefined;\n /** Root the inviting device named, adopted once the identity is accepted. */\n private _pendingHaloSpaceRootUrl: string | undefined;\n private readonly _devicePresenceAnnounceInterval: number;\n private readonly _devicePresenceOfflineTimeout: number;\n private readonly _automergeCredentials: boolean;\n private readonly _edgeConnection: EdgeConnection | undefined;\n private readonly _edgeFeatures: Runtime_Client_EdgeFeatures | undefined;\n\n private _identity?: Identity;\n /**\n * Owns the HALO anchoring subscriptions, which outlive any single open() call. Replaced on\n * {@link deleteIdentity}, since a disposed context runs new `onDispose` callbacks immediately and\n * would tear down the next identity's subscriptions as they are registered.\n */\n private _ctx = new Context();\n\n // TODO(dmaretskyi): Perhaps this should take/generate the peerKey outside of an initialized identity.\n constructor(params: IdentityManagerProps) {\n this._metadataStore = params.metadataStore;\n this._keyring = params.keyring;\n this._hypercoreStore = params.hypercoreStore;\n this._spaceManager = params.spaceManager;\n this._edgeConnection = params.edgeConnection;\n this._edgeFeatures = params.edgeFeatures;\n this._devicePresenceAnnounceInterval = params.devicePresenceAnnounceInterval ?? DEVICE_PRESENCE_ANNOUNCE_INTERVAL;\n this._devicePresenceOfflineTimeout = params.devicePresenceOfflineTimeout ?? DEVICE_PRESENCE_OFFLINE_TIMEOUT;\n this._automergeCredentials = params.automergeCredentials ?? false;\n }\n\n get identity() {\n return this._identity;\n }\n\n /**\n * Supplies the echo host used to anchor the HALO space on a root document. Anchors immediately when\n * an identity is already open, since the two are wired in either order.\n */\n async setEchoHost(echoHost: EchoHost): Promise<void> {\n this._echoHost = echoHost;\n if (this._identity) {\n await this._anchorHaloOnRootDocument(this._ctx, this._identity);\n }\n }\n\n @Trace.span({ showInBrowserTimeline: true })\n async open(ctx: Context): Promise<void> {\n log('opening identity manager');\n\n const identityRecord = this._metadataStore.getIdentityRecord();\n log('identity record', { identityRecord });\n if (identityRecord) {\n this._identity = await this._constructIdentity(identityRecord);\n await this._identity.open(ctx);\n await this._identity.ready();\n await this._anchorHaloOnRootDocument(this._ctx, this._identity);\n log.trace('dxos.halo.identity', {\n identityKey: identityRecord.identityKey,\n displayName: this._identity.profileDocument?.displayName,\n });\n\n this.stateUpdate.emit();\n }\n log('opened identity manager');\n }\n\n async close(ctx: Context): Promise<void> {\n await this._ctx.dispose();\n await this._identity?.close(ctx);\n }\n\n /**\n * Closes the identity and drops its persisted record, so the next open starts without one.\n * The identity's storage (feeds, automerge documents, keys) is wiped separately by the reset\n * chain — this only tears down the live identity and the metadata that would resurrect it.\n */\n async deleteIdentity(ctx: Context): Promise<void> {\n const identity = this._identity;\n if (identity) {\n log('deleting identity', { identityKey: identity.identityKey });\n // Dropped before teardown so anything observing `stateUpdate` cannot read a half-closed identity.\n this._identity = undefined;\n await this._ctx.dispose();\n this._ctx = new Context();\n await identity.close(ctx).catch((err) => log.warn('identity teardown failed; deleting anyway', { err }));\n } else {\n log('no live identity to delete');\n }\n\n // Unconditional, so a call that failed here is retried rather than leaving the persisted record\n // to resurrect an identity the caller already deleted.\n await this._metadataStore.clear();\n this.stateUpdate.emit();\n log('deleted identity');\n }\n\n async createIdentity({ profile, deviceProfile }: CreateIdentityOptions = {}, ctx?: Context): Promise<Identity> {\n invariant(!this._identity, 'Identity already exists.');\n log('creating identity...');\n\n const controlFeedKey = await this._keyring.createKey();\n const identityRecord: IdentityRecord = create(IdentityRecordSchema, {\n identityKey: fromPublicKey(await this._keyring.createKey()),\n deviceKey: fromPublicKey(await this._keyring.createKey()),\n haloSpace: create(SpaceMetadataSchema, {\n key: fromPublicKey(await this._keyring.createKey()),\n genesisFeedKey: fromPublicKey(controlFeedKey),\n controlFeedKey: fromPublicKey(controlFeedKey),\n dataFeedKey: fromPublicKey(await this._keyring.createKey()),\n }),\n });\n\n const identity = await this._constructIdentity(identityRecord);\n await identity.open(ctx ?? Context.default());\n\n {\n const identityKey = requirePublicKey(identityRecord.identityKey);\n const deviceKey = requirePublicKey(identityRecord.deviceKey);\n const haloSpace = identityRecord.haloSpace;\n invariant(haloSpace, 'Halo space metadata is required.');\n const generator = new CredentialGenerator(this._keyring, identityKey, deviceKey);\n const credentials = [\n // Space genesis.\n ...(await generator.createSpaceGenesis(\n requirePublicKey(haloSpace.key),\n requirePublicKey(haloSpace.genesisFeedKey),\n )),\n\n // Feed admission.\n await generator.createFeedAdmission(\n requirePublicKey(haloSpace.key),\n requirePublicKey(haloSpace.dataFeedKey),\n AdmittedFeed_Designation.DATA,\n ),\n ];\n\n if (profile) {\n credentials.push(await generator.createProfileCredential(profile));\n }\n\n // Device authorization (writes device chain).\n // NOTE: This credential is written last. This is a hack to make sure that display name is set before identity is \"ready\".\n credentials.push(await generator.createDeviceAuthorization(deviceKey));\n\n // Write device metadata to profile.\n credentials.push(\n await generator.createDeviceProfile({\n ...this.createDefaultDeviceProfile(),\n ...deviceProfile,\n }),\n );\n for (const credential of credentials) {\n await identity.controlPipeline.writer.write(credentialPayload(credential));\n }\n }\n\n await this._metadataStore.setIdentityRecord(identityRecord);\n this._identity = identity;\n await this._identity.ready();\n await this._anchorHaloOnRootDocument(this._ctx, this._identity);\n log.trace('dxos.halo.identity', {\n identityKey: identityRecord.identityKey,\n displayName: this._identity.profileDocument?.displayName,\n });\n this.stateUpdate.emit();\n\n log('created identity', {\n identityKey: identity.identityKey,\n deviceKey: identity.deviceKey,\n profile: identity.profileDocument,\n });\n\n return identity;\n }\n\n createDefaultDeviceProfile(): DeviceProfileDocument {\n // See TODOs in credentials.proto.\n let type: DeviceType;\n if (isNode()) {\n type = DeviceType.AGENT;\n } else {\n if (platform.name?.startsWith('iOS') || platform.name?.startsWith('Android')) {\n type = DeviceType.MOBILE;\n } else if (isTauri() || !platform.name) {\n // Tauri's __TAURI__ global isn't available in web workers. Fallback: WKWebView\n // (Tauri on macOS) reports null for platform.name; all standard browsers don't.\n type = DeviceType.NATIVE;\n } else {\n type = DeviceType.BROWSER;\n }\n }\n\n const os = platform.os?.family === 'OS X' ? 'macOS' : platform.os?.family;\n const name = type === DeviceType.NATIVE || type === DeviceType.MOBILE ? 'App' : platform.name;\n\n return create(DeviceProfileDocumentSchema, {\n type,\n platform: name,\n platformVersion: platform.version,\n architecture: typeof platform.os?.architecture === 'number' ? String(platform.os.architecture) : undefined,\n os,\n osVersion: platform.os?.version,\n });\n }\n\n /**\n * Prepare an identity object as the first step of acceptIdentity flow.\n */\n async prepareIdentity(params: JoinIdentityProps, ctx?: Context) {\n this._pendingHaloSpaceRootUrl = params.haloSpaceRootUrl;\n log('accepting identity', { params });\n invariant(!this._identity, 'Identity already exists.');\n\n const identityRecord: IdentityRecord = create(IdentityRecordSchema, {\n identityKey: fromPublicKey(params.identityKey),\n deviceKey: fromPublicKey(params.deviceKey),\n haloSpace: create(SpaceMetadataSchema, {\n key: fromPublicKey(params.haloSpaceKey),\n genesisFeedKey: fromPublicKey(params.haloGenesisFeedKey),\n controlFeedKey: fromPublicKey(params.controlFeedKey),\n dataFeedKey: fromPublicKey(params.dataFeedKey),\n controlTimeframe: params.controlTimeframe && fromTimeframe(params.controlTimeframe),\n }),\n });\n const identity = await this._constructIdentity(identityRecord);\n await identity.open(ctx ?? Context.default());\n return { identity, identityRecord };\n }\n\n /**\n * Accept an existing identity. Expects its device key to be authorized (now or later).\n */\n public async acceptIdentity(\n identity: Identity,\n identityRecord: IdentityRecord,\n profile?: DeviceProfileDocument,\n ): Promise<void> {\n this._identity = identity;\n\n // Identity becomes ready after device chain is replicated. Wait for it before storing the record.\n await this._identity.ready();\n await this._metadataStore.setIdentityRecord(identityRecord);\n\n log.trace('dxos.halo.identity', {\n identityKey: this._identity!.identityKey,\n displayName: this._identity.profileDocument?.displayName,\n });\n\n await this.updateDeviceProfile({\n ...this.createDefaultDeviceProfile(),\n ...profile,\n });\n await this._anchorHaloOnRootDocument(this._ctx, this._identity);\n this.stateUpdate.emit();\n\n log('accepted identity', { identityKey: identity.identityKey, deviceKey: identity.deviceKey });\n }\n\n /**\n * Update the profile document of an existing identity.\n */\n async updateProfile(profile: ProfileDocument): Promise<ProfileDocument> {\n invariant(this._identity, 'Identity not initialized.');\n // TODO(wittjosiah): Use CredentialGenerator.\n const credential = await this._identity.getIdentityCredentialSigner().createCredential({\n subject: this._identity.identityKey,\n assertion: create(IdentityProfileSchema, { profile }),\n });\n\n const receipt = await this._identity.controlPipeline.writer.write(credentialPayload(credential));\n await this._identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));\n this.stateUpdate.emit();\n return profile;\n }\n\n async updateDeviceProfile(profile: DeviceProfileDocument): Promise<Device> {\n invariant(this._identity, 'Identity not initialized.');\n\n // TODO(nf): CredentialGenerator doesn't work when not updating own device.\n // const generator = new CredentialGenerator(this._keyring, this._identity.identityKey, this._identity.deviceKey);\n // const credential = await generator.createDeviceProfile(profile);\n\n const credential = await this._identity.getDeviceCredentialSigner().createCredential({\n subject: this._identity.deviceKey,\n assertion: create(DeviceProfileSchema, { profile }),\n });\n\n const receipt = await this._identity.controlPipeline.writer.write(credentialPayload(credential));\n await this._identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));\n this.stateUpdate.emit();\n return create(DeviceSchema, {\n deviceKey: fromPublicKey(this._identity.deviceKey),\n kind: DeviceKind.CURRENT,\n presence: Device_PresenceState.ONLINE,\n profile,\n });\n }\n\n private async _constructIdentity(identityRecord: IdentityRecord): Promise<Identity> {\n invariant(!this._identity);\n log('constructing identity', { identityRecord });\n\n const identityKey = requirePublicKey(identityRecord.identityKey);\n const deviceKey = requirePublicKey(identityRecord.deviceKey);\n const haloSpace = identityRecord.haloSpace;\n invariant(haloSpace, 'Halo space metadata is required.');\n\n const gossip = new Gossip({\n localPeerId: deviceKey,\n });\n const presence = new Presence({\n announceInterval: this._devicePresenceAnnounceInterval,\n offlineTimeout: this._devicePresenceOfflineTimeout,\n identityKey: deviceKey,\n gossip,\n });\n\n // Must be created before the space so the feeds are writable.\n const controlFeed = await this._hypercoreStore.openHypercore(requirePublicKey(haloSpace.controlFeedKey), {\n writable: true,\n });\n const dataFeed = await this._hypercoreStore.openHypercore(requirePublicKey(haloSpace.dataFeedKey), {\n writable: true,\n sparse: true,\n });\n\n const space = await this._constructSpace({\n spaceRecord: haloSpace,\n swarmIdentity: {\n identityKey,\n peerKey: deviceKey,\n credentialProvider: Auth.createAuthProvider(createCredentialSignerWithKey(this._keyring, deviceKey)),\n credentialAuthenticator: deferFunction(() => identity.authVerifier.verifier),\n },\n gossip,\n identityKey,\n });\n await space.setControlFeed(controlFeed);\n await space.setDataFeed(dataFeed);\n\n const did = await createDidFromIdentityKey(identityKey);\n const identity: Identity = new Identity({\n space,\n presence,\n signer: this._keyring,\n did,\n identityKey,\n deviceKey,\n edgeConnection: this._edgeConnection,\n edgeFeatures: this._edgeFeatures,\n });\n log('done', { identityKey });\n\n // TODO(mykola): Set new timeframe on a write to a feed.\n if (haloSpace.controlTimeframe) {\n identity.controlPipeline.state.setTargetTimeframe(toTimeframe(haloSpace.controlTimeframe));\n }\n\n identity.stateUpdate.on(() => this.stateUpdate.emit());\n return identity;\n }\n\n /**\n * Gives the HALO space a space root document and mirrors its credential chain into a credentials\n * document, so the chain replicates as automerge rather than only as a control feed.\n *\n * The space keeps its key-derived id, exactly as a data space does. That is not a\n * migration compromise here as it is for data spaces: recovery reconstructs the HALO space from\n * `haloSpaceKey` alone (the only identifier EDGE returns), so a root-derived id would leave a\n * recovering device computing an id no replicated document belongs to.\n */\n private async _anchorHaloOnRootDocument(ctx: Context, identity: Identity): Promise<void> {\n // Opt-in: without the flag the HALO keeps its control feed and grows no documents.\n if (!this._echoHost || !this._automergeCredentials) {\n return;\n }\n const echoHost = this._echoHost;\n\n const spaceId = identity.haloSpaceId;\n try {\n if (!echoHost.getSpaceRootRefs(spaceId)) {\n const adopted = this._pendingHaloSpaceRootUrl;\n if (adopted !== undefined && isValidAutomergeUrl(adopted)) {\n // A second root over the same space would leave the two devices disagreeing about which\n // document carries the chain, so the joining device takes the one the inviter named — and\n // mints nothing when it cannot, since halo documents have no replication path between\n // devices yet and the root may simply never arrive.\n await echoHost.adoptSpaceRoot(ctx, spaceId, adopted).catch((err) => {\n log.warn('halo space root named by the inviting device is not available', { spaceId, adopted, err });\n });\n return;\n } else {\n // HALO has never had a directory — its data has always lived in the control feed — so one\n // is created here to give the root something to point at.\n if (!echoHost.spaceIds.includes(spaceId)) {\n await echoHost.createSpaceRoot(ctx, identity.haloSpaceKey);\n }\n\n const refs = await echoHost.migrateSpaceToRootDocument(ctx, spaceId);\n if (!refs) {\n return;\n }\n\n log('anchored halo space on a root document', { spaceId, refs });\n }\n }\n\n const refs = echoHost.getSpaceRootRefs(spaceId);\n if (refs) {\n identity.setHaloSpaceRootUrl(refs.spaceRootDocUrl);\n }\n\n const store = await openCredentialsDocument(ctx, echoHost, spaceId);\n for (const credential of identity.space.spaceState.credentials) {\n store.append(credential);\n }\n ctx.onDispose(identity.space.credentialProcessed.on((credential) => store.append(credential)));\n\n // The document feeds the same state machine the feed does; processing is idempotent by\n // credential id, so both sources can run during the migration window.\n store.subscribe(ctx, (credential) => identity.space.processDocumentCredential(credential));\n } catch (err) {\n log.warn('failed to anchor the halo space on a root document', { spaceId, err });\n }\n }\n\n private async _constructSpace({ spaceRecord, swarmIdentity, identityKey, gossip }: ConstructSpaceProps) {\n return this._spaceManager.constructSpace({\n metadata: create(SpaceMetadataSchema, {\n key: spaceRecord.key,\n genesisFeedKey: spaceRecord.genesisFeedKey,\n }),\n swarmIdentity,\n onAuthorizedConnection: (session) => {\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n gossip.createExtension({ remotePeerId: session.remotePeerId }),\n );\n },\n onAuthFailure: () => {\n log.warn('auth failure');\n },\n memberKey: identityKey,\n onDelegatedInvitationStatusChange: async () => {}, // TODO: will be used for recovery keys\n onMemberRolesChanged: async () => {}, // TODO: will be used for device revocation\n });\n }\n}\n\nexport type IdentityManagerLayerOptions = Pick<\n IdentityManagerProps,\n 'devicePresenceAnnounceInterval' | 'devicePresenceOfflineTimeout' | 'edgeFeatures' | 'automergeCredentials'\n>;\n\n/**\n * Effect Layer constructing an {@link IdentityManager} from ambient service dependencies.\n */\nexport const IdentityManagerLayer = (\n options: IdentityManagerLayerOptions = {},\n): Layer.Layer<\n IdentityContract.ManagerService,\n never,\n Hook.Controller | IMetadataStoreService | KeyringApiService | HypercoreStoreService | SpaceManagerService\n> =>\n Layer.effect(\n IdentityContract.ManagerService,\n Effect.gen(function* () {\n const metadataStore = yield* IMetadataStoreService;\n const keyring = yield* KeyringApiService;\n const hypercoreStore = yield* HypercoreStoreService;\n const spaceManager = yield* SpaceManagerService;\n const edgeConnection = yield* Effect.serviceOption(EdgeConnectionService);\n const identityManager = new IdentityManager({\n metadataStore,\n keyring,\n hypercoreStore,\n spaceManager,\n edgeConnection: Option.getOrUndefined(edgeConnection),\n ...options,\n });\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(() => identityManager.close(Context.default())));\n yield* Hook.on(\n Events.StorageReady,\n Effect.fn('IdentityManager.onStorageReady')(function* () {\n yield* Effect.promise(() => identityManager.open(ctx));\n yield* Hook.emit(Events.IdentityLoaded, { identity: identityManager.identity });\n }),\n );\n return identityManager;\n }),\n );\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as SqlMigrations from '@dxos/sql-sqlite/SqlMigrations';\n\nimport init from './0001_init.sql?raw';\n\n/**\n * Hypercore file-storage migrations, keyed `<id>_<name>` as `Migrator.fromRecord` expects. Ids must only ever increase,\n * and an applied migration must never be edited — nothing verifies its contents.\n */\nexport const MIGRATIONS = {\n '0001_init': SqlMigrations.apply(init),\n};\n\n/** Own history table per store, since many stores share the client database. */\nexport const MIGRATIONS_TABLE = 'hypercore_files_migrations';\n","//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Migrator from 'effect/sql/Migrator';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport type * as SqlError from 'effect/sql/SqlError';\nimport type { Callback, FileStat, RandomAccessStorage } from 'random-access-storage';\n\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { HypercoreStorageDirectoryService } from '@dxos/feed-store';\nimport { log } from '@dxos/log';\nimport { Directory, type File, type Storage, StorageType, wrapFile } from '@dxos/random-access-storage';\n\nimport { MIGRATIONS, MIGRATIONS_TABLE } from './migrations/hypercore/index.ts';\n\n/**\n * True when a rejected SQL op failed because its connection was already closed — the message\n * `The database connection is not open` (raised by `@effect/sql-sqlite-node`), which arrives\n * wrapped as an effect `SqlError`, so walk the `cause` chain. Signals teardown, not a real fault.\n */\nexport const isClosedConnectionError = (err: unknown): boolean => {\n for (let cur: any = err, depth = 0; cur != null && depth < 5; cur = cur.cause, depth++) {\n const message = typeof cur === 'string' ? cur : cur.message;\n if (typeof message === 'string' && /connection is not open/i.test(message)) {\n return true;\n }\n }\n return false;\n};\n\nexport type SqliteStorageOptions = {\n runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n};\n\n/**\n * Effect service tag for {@link SqliteStorage}.\n */\nexport class SqliteStorageService extends EffectContext.Service<SqliteStorageService, SqliteStorage>()(\n '@dxos/client-services/SqliteStorage',\n) {}\n\n/** Minimal cross-platform EventEmitter needed by the RandomAccessStorage contract. */\nclass BaseEventEmitter {\n readonly #events: Record<string, ((...args: unknown[]) => void)[]> = Object.create(null);\n\n on(event: string, listener: (...args: unknown[]) => void): this {\n (this.#events[event] ??= []).push(listener);\n return this;\n }\n off(event: string, listener: (...args: unknown[]) => void): this {\n const list = this.#events[event];\n if (list) {\n const idx = list.indexOf(listener);\n if (idx !== -1) {\n list.splice(idx, 1);\n }\n }\n return this;\n }\n emit(event: string, ...args: unknown[]): boolean {\n const list = this.#events[event];\n if (!list?.length) {\n return false;\n }\n for (const fn of [...list]) {\n fn(...args);\n }\n return true;\n }\n addListener = this.on;\n removeListener = this.off;\n once(event: string, listener: (...args: unknown[]) => void): this {\n const wrapper = (...args: unknown[]) => {\n this.off(event, wrapper);\n listener(...args);\n };\n return this.on(event, wrapper);\n }\n removeAllListeners(event?: string): this {\n if (event) {\n delete this.#events[event];\n } else {\n for (const key of Object.keys(this.#events)) {\n delete this.#events[key];\n }\n }\n return this;\n }\n listeners(event: string): ((...args: unknown[]) => void)[] {\n return this.#events[event] ?? [];\n }\n rawListeners(event: string): ((...args: unknown[]) => void)[] {\n return this.#events[event] ?? [];\n }\n listenerCount(event: string): number {\n return this.#events[event]?.length ?? 0;\n }\n prependListener(event: string, listener: (...args: unknown[]) => void): this {\n (this.#events[event] ??= []).unshift(listener);\n return this;\n }\n prependOnceListener(event: string, listener: (...args: unknown[]) => void): this {\n const wrapper = (...args: unknown[]) => {\n this.off(event, wrapper);\n listener(...args);\n };\n return this.prependListener(event, wrapper);\n }\n eventNames(): string[] {\n return Object.keys(this.#events);\n }\n getMaxListeners(): number {\n return 0;\n }\n setMaxListeners(): this {\n return this;\n }\n}\n\n/**\n * SQLite-backed random-access file for hypercore storage.\n * Stores each file as a blob in `hypercore_files`. Read-modify-write for writes.\n */\nclass SqliteRandomAccessFile extends BaseEventEmitter implements RandomAccessStorage {\n readonly opened: boolean = false;\n readonly suspended: boolean = false;\n readonly writing: boolean = false;\n readonly readable: boolean = true;\n readonly writable: boolean = true;\n readonly deletable: boolean = true;\n readonly truncatable: boolean = false;\n // Setting statable=false prevents hypercore's statAndReadAll() from computing a negative\n // read-size (stat.size - offset) for new empty files, which causes an infinite async loop.\n readonly statable: boolean = false;\n\n #closed = false;\n #unlinked = false;\n #destroyed = false;\n\n get closed(): boolean {\n return this.#closed;\n }\n\n get unlinked(): boolean {\n return this.#unlinked;\n }\n\n get destroyed(): boolean {\n return this.#destroyed;\n }\n\n // Filesystem-like metadata for compatibility with wrapFile.\n readonly directory: string;\n readonly filename: string;\n\n #buffer: Buffer = Buffer.alloc(0);\n #loaded = false;\n // The one-shot initial DB read (populates `#buffer`); set once, on first access.\n #loading: Promise<void> | null = null;\n // The latest in-flight DB write (from `write`/`del`); replaced on each save, so it always\n // tracks the most recent one. `close()` drains both before reporting closed.\n #saving: Promise<void> | null = null;\n\n constructor(\n private readonly filePath: string,\n private readonly runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>,\n ) {\n super();\n const parts = filePath.split('/');\n this.filename = parts.pop() ?? '';\n this.directory = parts.join('/');\n }\n\n private _ensureLoaded(): Promise<void> {\n if (this.#loaded) {\n return Promise.resolve();\n }\n // If the file was closed (e.g. the storage was torn down during shutdown) before its initial\n // load completed, don't start the DB read. The underlying SQL connection may already be\n // closing, and the read would reject with \"database connection is not open\" as an unhandled\n // rejection — a background read racing teardown. #buffer already defaults to empty, so reads\n // resolve against an empty file.\n if (this.#closed) {\n return Promise.resolve();\n }\n if (!this.#loading) {\n this.#loading = this._loadFromDb();\n // Mark the cached load promise as handled so that if it rejects after every awaiter is gone\n // (e.g. the SQL runtime is disposed at teardown without close() being called on this file),\n // the rejection is never surfaced as an unhandled rejection. Legitimate awaiters still observe\n // the error through their own `.then`/`.catch` on the same promise returned below.\n this.#loading.catch(() => {});\n }\n return this.#loading;\n }\n\n private async _loadFromDb(): Promise<void> {\n const filePath = this.filePath;\n try {\n const rows = await RuntimeProvider.runPromise(this.runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql<{ data: Uint8Array }>`SELECT data FROM hypercore_files WHERE path = ${filePath}`;\n }),\n );\n this.#buffer = rows.length > 0 ? Buffer.from(rows[0].data) : Buffer.alloc(0);\n } catch (err) {\n // A read racing teardown rejects with \"database connection is not open\". The `#closed` guard\n // in `_ensureLoaded` only catches reads not yet started, and `#closed` covers only this file\n // being closed — during client disposal the shared SQL connection can be torn down while this\n // file's `#closed` is still false (the container closed the connection without closing every\n // file first). In either case a closed connection means there is nothing to load, so fall back\n // to the empty `#buffer`; rethrow only a genuine error against a live connection. Swallowing an\n // unhandled rejection here otherwise crashes the whole test worker (exit 1, no test failure).\n if (!this.#closed && !isClosedConnectionError(err)) {\n throw err;\n }\n }\n this.#loaded = true;\n }\n\n private async _saveToDb(): Promise<void> {\n const filePath = this.filePath;\n const data = this.#buffer;\n try {\n await RuntimeProvider.runPromise(this.runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`INSERT OR REPLACE INTO hypercore_files (path, data) VALUES (${filePath}, ${data})`;\n }),\n );\n } catch (err) {\n // Symmetric with `_loadFromDb`: a write racing teardown rejects (as `SqlError: Failed to\n // execute statement` wrapping \"connection is not open\") when the shared SQL connection is\n // torn down before this file's `#closed` flips. Persisting to a dead connection is moot\n // during disposal, so swallow it; rethrow only a genuine failure against a live connection.\n // An unswallowed rejection here surfaces as an unhandled rejection that fails the test worker.\n if (!this.#closed && !isClosedConnectionError(err)) {\n throw err;\n }\n }\n }\n\n write(offset: number, data: Buffer, cb: Callback<any>): void {\n const saving = this._ensureLoaded()\n .then(() => {\n const end = offset + data.length;\n // Hypercore rewrites unchanged pages of every feed it opens, and each save rewrites the whole\n // blob, so a write that changes nothing must not reach the database.\n if (end <= this.#buffer.length && this.#buffer.subarray(offset, end).equals(data)) {\n return;\n }\n if (end > this.#buffer.length) {\n const enlarged = Buffer.alloc(end);\n this.#buffer.copy(enlarged);\n this.#buffer = enlarged;\n }\n data.copy(this.#buffer, offset);\n return this._saveToDb();\n })\n .then(\n () => cb(null),\n (err) => cb(err),\n );\n // Track the in-flight save so `close()` can drain it before reporting closed — otherwise a\n // write racing `close()` (e.g. a background sync write racing `client.reset()`'s teardown)\n // keeps running against a connection the container may tear down immediately after.\n this.#saving = saving.catch(() => {});\n }\n\n read(offset: number, size: number, cb: Callback<Buffer>): void {\n this._ensureLoaded()\n .then(() => {\n if (size === 0) {\n cb(null, Buffer.alloc(0));\n return;\n }\n if (offset + size > this.#buffer.length) {\n cb(new Error(`Could not satisfy length ${size} at offset ${offset} (file size: ${this.#buffer.length})`));\n return;\n }\n cb(null, Buffer.from(this.#buffer.subarray(offset, offset + size)));\n })\n .catch((err) => cb(err));\n }\n\n del(offset: number, size: number, cb: Callback<any>): void {\n const saving = this._ensureLoaded()\n .then(() => {\n const end = Math.min(offset + size, this.#buffer.length);\n if (offset < end) {\n this.#buffer.fill(0, offset, end);\n }\n return this._saveToDb();\n })\n .then(\n () => cb(null),\n (err) => cb(err),\n );\n // See `write()`: track the in-flight save so `close()` can drain it before reporting closed.\n this.#saving = saving.catch(() => {});\n }\n\n stat(cb: Callback<FileStat>): void {\n this._ensureLoaded()\n .then(() => {\n cb(null, { size: this.#buffer.length });\n })\n .catch((err) => cb(err));\n }\n\n close(cb: Callback<Error>): void {\n this.#closed = true;\n // Drain any in-flight initial load and any in-flight write/del before reporting closed, so\n // neither races a torn-down SQL connection (avoids \"database connection is not open\" errors,\n // and the resulting stall in callers — e.g. `client.reset()`'s feed teardown — that wait on\n // this file's `close()` to settle before tearing down the connection itself).\n Promise.all([this.#loading ?? Promise.resolve(), this.#saving ?? Promise.resolve()]).then(\n () => cb(null),\n () => cb(null),\n );\n }\n\n destroy(cb: Callback<Error>): void {\n const filePath = this.filePath;\n RuntimeProvider.runPromise(this.runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`DELETE FROM hypercore_files WHERE path = ${filePath}`;\n }),\n )\n .then(() => {\n this.#buffer = Buffer.alloc(0);\n this.#destroyed = true;\n this.#unlinked = true;\n this.#closed = true;\n cb(null);\n })\n .catch((err) => cb(err));\n }\n}\n\n/**\n * SQLite-backed Storage implementation for hypercore feeds.\n * Table: hypercore_files(path TEXT PRIMARY KEY, data BLOB NOT NULL DEFAULT x'').\n */\nexport class SqliteStorage implements Storage {\n readonly path: string;\n readonly type = StorageType.NODE;\n\n readonly #runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n readonly #files = new Map<string, File>();\n readonly #nativeFiles = new Map<string, SqliteRandomAccessFile>();\n #closed = false;\n\n constructor({ runtime }: SqliteStorageOptions, path = '/sqlite-feeds') {\n this.#runtime = runtime;\n this.path = path;\n }\n\n /**\n * Applies any migrations this database has not recorded yet.\n */\n readonly migrate: Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient> = Migrator.make({})({\n loader: Migrator.fromRecord(MIGRATIONS),\n table: MIGRATIONS_TABLE,\n }).pipe(\n // A malformed bundled manifest is a defect, not something a caller can recover from.\n Effect.catchTag('MigrationError', (error) => Effect.die(error)),\n Effect.asVoid,\n Effect.withSpan('SqliteStorage.migrate'),\n );\n\n get size(): number {\n return this.#files.size;\n }\n\n createDirectory(sub = ''): Directory {\n const dirPath = sub ? `${this.path}/${sub}` : this.path;\n const runtime = this.#runtime;\n const files = this.#files;\n const nativeFiles = this.#nativeFiles;\n\n const getOrCreateFile = (path: string, filename: string): File => {\n const fullPath = `${path}/${filename}`;\n const existingNative = nativeFiles.get(fullPath);\n if (existingNative && !existingNative.destroyed) {\n return files.get(fullPath)!;\n }\n const native = new SqliteRandomAccessFile(fullPath, runtime);\n const file = wrapFile(native, StorageType.NODE);\n files.set(fullPath, file);\n nativeFiles.set(fullPath, native);\n return file;\n };\n\n const list = async (path: string): Promise<string[]> => {\n const prefix = path.endsWith('/') ? path : path + '/';\n const rows = await RuntimeProvider.runPromise(runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n return yield* sql<{\n path: string;\n }>`SELECT path FROM hypercore_files WHERE path = ${path} OR path LIKE ${prefix + '%'}`;\n }),\n );\n return rows.map((row) => row.path.replace(path + '/', '').replace(path, ''));\n };\n\n const remove = async (): Promise<void> => {\n const prefix = dirPath.endsWith('/') ? dirPath : dirPath + '/';\n await RuntimeProvider.runPromise(runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`DELETE FROM hypercore_files WHERE path = ${dirPath} OR path LIKE ${prefix + '%'}`;\n }),\n );\n // Clean up in-memory file cache.\n for (const [filePath] of files) {\n if (filePath === dirPath || filePath.startsWith(prefix)) {\n files.delete(filePath);\n }\n }\n };\n\n return new Directory({\n type: StorageType.NODE,\n path: dirPath,\n list,\n getOrCreateFile,\n remove,\n });\n }\n\n async reset(): Promise<void> {\n log('SqliteStorage: clearing all hypercore files');\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n yield* sql`DELETE FROM hypercore_files`;\n }),\n );\n this.#files.clear();\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n // Close each native file before the SQL connection is torn down. `close()` marks the file\n // closed (so any subsequent read skips the DB) and drains its in-flight initial load —\n // preventing \"database connection is not open\" unhandled rejections from background reads\n // that race shutdown (e.g. a test client closing while a background sync read is in flight).\n const natives = [...this.#nativeFiles.values()];\n await Promise.all(natives.map((native) => new Promise<void>((resolve) => native.close(() => resolve()))));\n this.#files.clear();\n this.#nativeFiles.clear();\n }\n}\n\nexport type SqliteStorageLayerOptions = {\n path?: string;\n};\n\n/**\n * Effect Layer constructing a {@link SqliteStorage} from the ambient SQL runtime.\n */\nexport const SqliteStorageLayer = (\n options: SqliteStorageLayerOptions = {},\n): Layer.Layer<SqliteStorageService, never, SqlClient.SqlClient> =>\n Layer.effect(\n SqliteStorageService,\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n return new SqliteStorage({ runtime }, options.path);\n }),\n );\n\nexport type HypercoreStorageDirectoryLayerOptions = {\n sub?: string;\n};\n\n/**\n * Effect Layer providing the hypercore feeds root directory from {@link SqliteStorage}.\n */\nexport const HypercoreStorageDirectoryLayer = (\n options: HypercoreStorageDirectoryLayerOptions = {},\n): Layer.Layer<HypercoreStorageDirectoryService, never, SqliteStorageService> =>\n Layer.effect(\n HypercoreStorageDirectoryService,\n Effect.gen(function* () {\n const storage = yield* SqliteStorageService;\n return storage.createDirectory(options.sub ?? 'feeds');\n }),\n );\n\n/**\n * Deletes every row the stack persists, so the next open starts from an empty database.\n */\nexport const wipeSqliteStorage: Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient> = Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n // Echo metadata + large space data.\n yield* sql`DELETE FROM space_metadata`;\n yield* sql`DELETE FROM space_large`;\n // Keyring.\n yield* sql`DELETE FROM keyring`;\n // Automerge chunks + heads.\n yield* sql`DELETE FROM automerge_chunks`;\n yield* sql`DELETE FROM automerge_heads`;\n // Hypercore feed files.\n yield* sql`DELETE FROM hypercore_files`;\n // Feed store (queue feeds, blocks, etc.).\n yield* sql`DELETE FROM feeds`;\n yield* sql`DELETE FROM blocks`;\n yield* sql`DELETE FROM subscriptions`;\n yield* sql`DELETE FROM cursor_tokens`;\n yield* sql`DELETE FROM sync_state`;\n // Index tables.\n yield* sql`DELETE FROM indexCursor`;\n yield* sql`DELETE FROM objectMeta`;\n yield* sql`DELETE FROM reverseRef`;\n yield* sql`DELETE FROM ftsIndex`;\n yield* sql`DELETE FROM objectSnapshot`;\n});\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context, Resource } from '@dxos/context';\nimport { createCredential, signPresentation } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { BaseError } from '@dxos/errors';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { toServiceError } from '@dxos/protocols';\nimport { buf, fromPublicKey } from '@dxos/protocols/buf';\nimport {\n type Identity as IdentityProto,\n IdentitySchema,\n type RecoverIdentityRequest,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport {\n AuthSchema,\n type Credential,\n type Presentation,\n type ProfileDocument,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { IdentityService } from '@dxos/protocols/rpc';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport * as SqliteStorage from '../../SqliteStorage.ts';\nimport { type CreateIdentityOptions } from './identity-manager.ts';\nimport { type EdgeIdentityRecoveryManager, EdgeIdentityRecoveryManagerService } from './identity-recovery-manager.ts';\n\nexport class IdentityServiceImpl extends Resource implements IdentityService.Handlers {\n 'constructor'(\n private readonly _identityManager: IdentityContract.Manager,\n private readonly _recoveryManager: EdgeIdentityRecoveryManager,\n private readonly _keyring: KeyringApi,\n private readonly _dataSpaceManager: SpacesContract.Manager,\n private readonly _wipeStorage: () => Promise<void>,\n private readonly _createIdentity: (params: CreateIdentityOptions, ctx?: Context) => Promise<Identity>,\n private readonly _onProfileUpdate?: (profile: ProfileDocument | undefined) => Promise<void>,\n ) {\n super();\n }\n\n ['IdentityService.createIdentity'](\n request: IdentityService.CreateIdentityRequest,\n ): Effect.Effect<IdentityProto, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n await this._createIdentity(\n {\n profile: request.profile,\n deviceProfile: request.deviceProfile,\n },\n ctx,\n );\n return this._getIdentity()!;\n },\n catch: toServiceError,\n });\n }\n\n ['IdentityService.queryIdentity'](): EffectStream.Stream<IdentityService.QueryIdentityResponse, Error> {\n return EffectEx.streamFromEmitter<IdentityService.QueryIdentityResponse, Error>((emit) => {\n // Omit `identity` entirely when absent: an explicit `undefined` would still drive the optional\n // protobuf codec, which dereferences the missing message and throws.\n const emitNext = () => {\n const identity = this._getIdentity();\n void emit.single(identity ? { identity } : {});\n };\n\n emitNext();\n const unsubscribe = this._identityManager.stateUpdate.on(emitNext);\n return Effect.sync(() => unsubscribe());\n });\n }\n\n ['IdentityService.updateProfile'](profile: ProfileDocument): Effect.Effect<IdentityProto, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n invariant(this._identityManager.identity, 'Identity not initialized.');\n await this._identityManager.updateProfile(profile);\n await this._onProfileUpdate?.(this._identityManager.identity.profileDocument);\n return this._getIdentity()!;\n },\n catch: toServiceError,\n });\n }\n\n ['IdentityService.createRecoveryCredential'](\n request: IdentityService.CreateRecoveryCredentialRequest,\n ): Effect.Effect<IdentityService.CreateRecoveryCredentialResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => this._recoveryManager.createRecoveryCredential(request),\n catch: toServiceError,\n });\n }\n\n ['IdentityService.revokeRecoveryCredential'](\n request: IdentityService.RevokeRecoveryCredentialRequest,\n ): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => this._recoveryManager.revokeRecoveryCredential(request),\n catch: toServiceError,\n });\n }\n\n ['IdentityService.requestRecoveryChallenge'](): Effect.Effect<\n IdentityService.RequestRecoveryChallengeResponse,\n Error\n > {\n return Effect.tryPromise({\n try: async () => this._recoveryManager.requestRecoveryChallenge(Context.default()),\n catch: toServiceError,\n });\n }\n\n ['IdentityService.recoverIdentity'](request: RecoverIdentityRequest): Effect.Effect<IdentityProto, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n // buf models the `request` oneof as a tagged union, so the cases are exhaustive here.\n switch (request.request.case) {\n case 'recoveryCode':\n await this._recoveryManager.recoverIdentity(ctx, { recoveryCode: request.request.value });\n break;\n case 'external':\n await this._recoveryManager.recoverIdentityWithExternalSignature(ctx, request.request.value);\n break;\n case 'token':\n await this._recoveryManager.recoverIdentityWithToken(ctx, { token: request.request.value });\n break;\n case 'recoveryProof':\n await this._recoveryManager.recoverIdentityWithToken(ctx, { recoveryProof: request.request.value });\n break;\n case undefined:\n throw new Error('Invalid request.');\n }\n\n return this._getIdentity()!;\n },\n catch: toServiceError,\n });\n }\n\n /**\n * Closes and deletes every space, closes and deletes the identity, then removes the persisted\n * bytes they leave behind: the automerge documents, the hypercore files, the feed store, the\n * index tables and the keyring. The stack stays open throughout, so the client is left exactly as\n * it was before an identity existed and `createIdentity` can run straight afterwards.\n */\n ['IdentityService.deleteIdentity'](): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n // Spaces first: their teardown leaves the swarm and flushes through the identity's HALO,\n // which the identity teardown below closes.\n await this._dataSpaceManager.deleteAllSpaces(ctx);\n await this._identityManager.deleteIdentity(ctx);\n // Last, so nothing still holds the rows it removes.\n await this._wipeStorage();\n },\n catch: toServiceError,\n });\n }\n\n // TODO(burdon): Rename createPresentation?\n ['IdentityService.signPresentation'](\n request: IdentityService.SignPresentationRequest,\n ): Effect.Effect<Presentation, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const { presentation, nonce } = request;\n invariant(this._identityManager.identity, 'Identity not initialized.');\n\n return await signPresentation({\n presentation: presentation,\n signer: this._keyring,\n signerKey: this._identityManager.identity.deviceKey,\n chain: this._identityManager.identity.deviceCredentialChain,\n nonce,\n });\n },\n catch: toServiceError,\n });\n }\n\n ['IdentityService.createAuthCredential'](): Effect.Effect<Credential, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const identity = this._identityManager.identity;\n\n invariant(identity, 'Identity not initialized.');\n\n return await createCredential({\n assertion: create(AuthSchema, {}),\n issuer: identity.identityKey,\n subject: identity.identityKey,\n chain: identity.deviceCredentialChain,\n signingKey: identity.deviceKey,\n signer: this._keyring,\n });\n },\n catch: toServiceError,\n });\n }\n\n private '_getIdentity'(): IdentityProto | undefined {\n if (!this._identityManager.identity) {\n return undefined;\n }\n\n return buf.create(IdentitySchema, {\n did: this._identityManager.identity.did,\n identityKey: fromPublicKey(this._identityManager.identity.identityKey),\n spaceKey: fromPublicKey(this._identityManager.identity.space.key),\n profile: this._identityManager.identity.profileDocument,\n });\n }\n}\n\n// The impl is a {@link Resource}; its open/close lifecycle is bound to the layer scope.\nexport const IdentityServiceLayer = Layer.effect(\n IdentityService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const recoveryManager = yield* EdgeIdentityRecoveryManagerService;\n const keyring = yield* KeyringApiService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const identityLifecycle = yield* IdentityContract.LifecycleService;\n const runtime = yield* RuntimeProvider.currentRuntime<Hook.Controller>();\n // The stack's own SQLite runtime: the wipe runs under the live stack rather than the reset\n // chain, which tears it down.\n const sqlRuntime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n const service = new IdentityServiceImpl(\n identityManager,\n recoveryManager,\n keyring,\n dataSpaceManager,\n () => RuntimeProvider.runPromise(sqlRuntime)(SqliteStorage.wipeSqliteStorage.pipe(Effect.orDie)),\n (params, ctx) => identityLifecycle.createIdentity(params, ctx),\n (profile) =>\n profile\n ? RuntimeProvider.runPromise(runtime)(Hook.emit(Events.ProfileUpdated, { profile }))\n : Promise.resolve(),\n );\n yield* Effect.acquireRelease(\n Effect.promise(() => service.open()),\n () => Effect.promise(() => service.close()),\n );\n return service;\n }),\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { fromBinary } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Event, UpdateScheduler } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport {\n INBOX_ENVELOPE_TTL_MS,\n INBOX_ENVELOPE_VERSION,\n SPACE_INVITATION_NOTICE_TTL_MS,\n type VerifiedSpaceInvitationNotice,\n createDidFromIdentityKey,\n createInboxEnvelope,\n decodeInboxEnvelope,\n encodeInboxEnvelope,\n verifyInboxEnvelope,\n verifySpaceInvitationNotice,\n} from '@dxos/credentials';\nimport {\n type EdgeConnection,\n EdgeConnectionService,\n type EdgeHttpClient,\n EdgeHttpClientService,\n} from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n EdgeCallFailedError,\n EdgeService,\n INBOX_MAX_PAYLOAD_LENGTH,\n InboxAccountRequiredError,\n type InboxNotice,\n InboxPayloadTooLargeError,\n toServiceError,\n} from '@dxos/protocols';\nimport { type Credential, CredentialSchema } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { InboxService } from '@dxos/protocols/rpc';\nimport { Message, SpaceInvitationMessage } from '@dxos/types';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport { type Identity } from '../../Identity.ts';\n\nexport class InboxUnavailableError extends BaseError.extend(\n 'InboxUnavailableError',\n 'The inbox is not available until the identity is ready and connected.',\n) {}\n\n/** The EDGE inbox endpoints the service calls; narrowed so tests can stand in for EDGE. */\nexport type InboxEdgeClient = Pick<EdgeHttpClient, 'sendInboxMessage' | 'listInbox' | 'ackInbox'>;\n\n/** The identity the inbox signs as and receives for. */\nexport type InboxIdentitySource = {\n readonly stateUpdate: Event;\n readonly identity: Pick<Identity, 'identityKey' | 'getInboxEnvelopeSigner'> | undefined;\n};\n\n/** The socket events that say the inbox may have changed. */\nexport type InboxPushSource = Pick<EdgeConnection, 'onMessage' | 'onReconnected'>;\n\n/**\n * Stands in for the EDGE inbox, authenticating each call as whichever identity `identity` holds at\n * the time; tests share one between clients so they can message each other without EDGE.\n */\nexport interface InboxRelay {\n connect(identity: InboxIdentitySource): { edgeClient: InboxEdgeClient; pushSource: InboxPushSource };\n}\n\nexport type InboxServiceOptions = {\n /** Catch-up poll while subscribed, in case a push frame was missed. */\n pollIntervalMs?: number;\n};\n\nconst DEFAULT_POLL_INTERVAL_MS = 5 * 60 * 1_000;\n\n/** Payload types this client surfaces; envelopes of any other type stay pending for a newer client. */\nconst KNOWN_TYPES = new Set<string>([InboxService.INBOX_MESSAGE_TYPE]);\n\ntype Entry = {\n message: InboxService.InboxMessage;\n /** Every EDGE entry carrying this message; a resent envelope lands under a fresh EDGE id. */\n edgeIds: Set<string>;\n};\n\n/** What one EDGE entry turned out to be. */\ntype Classified =\n | { kind: 'message'; message: InboxService.InboxMessage }\n /** Possibly valid for a newer client: neither surfaced nor acked. */\n | { kind: 'pending' }\n /** Can never become valid, so it is acked rather than left to use up the recipient's cap. */\n | { kind: 'rejected'; reason: string };\n\n/** EDGE refuses inbox calls from an identity not linked to an account; retrying cannot succeed until it is. */\nconst isAccountRequired = (error: unknown): boolean =>\n error instanceof EdgeCallFailedError && error.data?.type === 'identity_not_associated_with_account';\n\nconst decodeCredential = (payload: string): Credential | undefined => {\n try {\n return fromBinary(CredentialSchema, Buffer.from(payload, 'base64'));\n } catch {\n return undefined;\n }\n};\n\n/**\n * Converts a legacy (pre-envelope) invitation notice into the message a current sender would build.\n * Receive-only: delete once the notice TTL has passed for every sender on a pre-envelope release.\n */\nconst legacyInvitationMessage = async (notice: VerifiedSpaceInvitationNotice): Promise<InboxService.InboxMessage> => ({\n id: notice.id,\n senderIdentityKey: notice.sender,\n type: InboxService.INBOX_MESSAGE_TYPE,\n payload: Message.encodeJson(\n SpaceInvitationMessage.make({\n sender: { identityDid: await createDidFromIdentityKey(notice.sender) },\n spaceKey: notice.spaceKey.toHex(),\n role: notice.role,\n created: notice.sentAt,\n }),\n ),\n sentAt: notice.sentAt,\n});\n\n/**\n * User-to-user messages relayed through the EDGE inbox, each carried in a signed envelope.\n *\n * The pending set is pulled from EDGE when the first subscriber arrives, on every reconnect, on\n * every `inbox` push frame (which is treated as a doorbell, its payload unread) and on a slow poll;\n * each pull replaces the set, so an ack from another device drops the entry here too.\n */\nexport class InboxServiceImpl implements InboxService.Handlers {\n readonly #changed = new Event<InboxService.Messages>();\n #entries = new Map<string, Entry>();\n /** EDGE ids acked locally; a pull already in flight must not resurrect them. */\n readonly #acked = new Set<string>();\n #loaded = false;\n #status: InboxService.Status = 'available';\n #subscribers = 0;\n #ctx?: Context;\n\n 'constructor'(\n private readonly _identityManager: InboxIdentitySource,\n private readonly _edgeClient?: InboxEdgeClient,\n private readonly _pushSource?: InboxPushSource,\n private readonly _options: InboxServiceOptions = {},\n ) {}\n\n ['InboxService.sendMessage'](request: InboxService.SendMessageRequest): Effect.Effect<void, Error> {\n return Effect.tryPromise({\n try: async () => {\n const identity = this._identityManager.identity;\n if (!identity || !this._edgeClient) {\n throw new InboxUnavailableError();\n }\n const envelope = await createInboxEnvelope(identity.getInboxEnvelopeSigner(), request.recipientIdentityKey, {\n type: request.type,\n payload: request.payload,\n });\n const payload = Buffer.from(encodeInboxEnvelope(envelope)).toString('base64');\n if (payload.length > INBOX_MAX_PAYLOAD_LENGTH) {\n throw new InboxPayloadTooLargeError({\n context: { length: payload.length, maxLength: INBOX_MAX_PAYLOAD_LENGTH },\n });\n }\n const recipientDid = await createDidFromIdentityKey(request.recipientIdentityKey);\n await this._edgeClient.sendInboxMessage(Context.default(), recipientDid, payload).catch((error) => {\n throw isAccountRequired(error) ? new InboxAccountRequiredError({ cause: error }) : error;\n });\n },\n catch: toServiceError,\n });\n }\n\n ['InboxService.subscribe'](): EffectStream.Stream<InboxService.Messages, Error> {\n return EffectEx.streamFromEmitter<InboxService.Messages, Error>((emit) => {\n const unsubscribe = this.#changed.on((snapshot) => void emit.single(snapshot));\n if (this.#loaded || !this._edgeClient) {\n void emit.single(this.#snapshot());\n }\n this.#retain();\n return Effect.promise(async () => {\n unsubscribe();\n await this.#release();\n });\n });\n }\n\n ['InboxService.ack'](request: InboxService.AckRequest): Effect.Effect<void, Error> {\n return Effect.tryPromise({\n try: async () => {\n const edgeIds = request.ids.flatMap((id) => [...(this.#entries.get(id)?.edgeIds ?? [])]);\n if (edgeIds.length === 0) {\n return;\n }\n if (!this._edgeClient) {\n throw new InboxUnavailableError();\n }\n await this._edgeClient.ackInbox(Context.default(), edgeIds);\n edgeIds.forEach((id) => this.#acked.add(id));\n request.ids.forEach((id) => this.#entries.delete(id));\n this.#changed.emit(this.#snapshot());\n },\n catch: toServiceError,\n });\n }\n\n #snapshot(): InboxService.Messages {\n return {\n messages: [...this.#entries.values()]\n .map((entry) => entry.message)\n .sort((a, b) => a.sentAt.getTime() - b.sentAt.getTime()),\n status: this.#status,\n };\n }\n\n #retain(): void {\n this.#subscribers++;\n if (this.#subscribers > 1 || !this._edgeClient) {\n return;\n }\n\n const ctx = new Context();\n const scheduler = new UpdateScheduler(ctx, () => this.#pull(ctx));\n this.#ctx = ctx;\n\n ctx.onDispose(this._identityManager.stateUpdate.on(() => scheduler.trigger()));\n if (this._pushSource) {\n ctx.onDispose(\n this._pushSource.onMessage((message) => {\n if (message.serviceId === EdgeService.INBOX) {\n scheduler.trigger();\n }\n }),\n );\n ctx.onDispose(this._pushSource.onReconnected(() => scheduler.trigger(), { emitCurrentState: false }));\n }\n const interval = setInterval(() => scheduler.trigger(), this._options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n ctx.onDispose(() => clearInterval(interval));\n scheduler.trigger();\n }\n\n async #release(): Promise<void> {\n this.#subscribers--;\n if (this.#subscribers > 0) {\n return;\n }\n const ctx = this.#ctx;\n this.#ctx = undefined;\n await ctx?.dispose();\n }\n\n /** Replaces the pending set with EDGE's, keeping only messages that verify. Never throws. */\n async #pull(ctx: Context): Promise<void> {\n const edgeClient = this._edgeClient;\n const identity = this._identityManager.identity;\n if (!edgeClient) {\n return;\n }\n if (!identity) {\n this.#entries = new Map();\n this.#publish();\n return;\n }\n\n let notices: readonly InboxNotice[];\n try {\n ({ notices } = await edgeClient.listInbox(ctx));\n } catch (error) {\n if (isAccountRequired(error)) {\n // Published only on the transition, so the slow poll does not re-announce it.\n if (this.#status !== 'account-required') {\n this.#status = 'account-required';\n this.#entries = new Map();\n this.#publish();\n }\n return;\n }\n // Offline or not yet authenticated: keep the last set and retry on the next trigger.\n log('inbox pull failed', { error });\n return;\n }\n this.#status = 'available';\n\n const now = new Date();\n const entries = new Map<string, Entry>();\n const rejected: string[] = [];\n for (const edgeNotice of notices) {\n if (this.#acked.has(edgeNotice.id)) {\n continue;\n }\n const result = await this.#classify(identity.identityKey, edgeNotice, now);\n if (result.kind === 'rejected') {\n log.warn('dropping inbox message', { id: edgeNotice.id, reason: result.reason });\n rejected.push(edgeNotice.id);\n continue;\n }\n if (result.kind === 'pending') {\n continue;\n }\n\n const { message } = result;\n const existing = entries.get(message.id);\n if (existing) {\n existing.edgeIds.add(edgeNotice.id);\n } else {\n // Keeps the previous pull's copy, since a converted legacy notice is rebuilt with a fresh object id.\n entries.set(message.id, {\n message: this.#entries.get(message.id)?.message ?? message,\n edgeIds: new Set([edgeNotice.id]),\n });\n }\n }\n\n // Acked ids EDGE no longer returns have been deleted there; forget them.\n const listed = new Set(notices.map((edgeNotice) => edgeNotice.id));\n [...this.#acked].filter((id) => !listed.has(id)).forEach((id) => this.#acked.delete(id));\n\n this.#entries = entries;\n this.#publish();\n\n if (rejected.length > 0) {\n await edgeClient\n .ackInbox(ctx, rejected)\n .catch((error) => log('inbox ack of rejected messages failed', { error }));\n }\n }\n\n /**\n * Decodes an EDGE entry as an envelope first, then as a legacy invitation credential.\n */\n async #classify(self: PublicKey, edgeNotice: InboxNotice, now: Date): Promise<Classified> {\n const bytes = Buffer.from(edgeNotice.payload, 'base64');\n const envelope = decodeInboxEnvelope(bytes);\n if (envelope) {\n if (envelope.version !== INBOX_ENVELOPE_VERSION) {\n return { kind: 'pending' };\n }\n const result = await verifyInboxEnvelope(envelope, {\n self,\n claimedSender: edgeNotice.senderDid,\n now,\n ttlMs: INBOX_ENVELOPE_TTL_MS,\n });\n if (result.kind === 'fail') {\n return { kind: 'rejected', reason: result.reason };\n }\n const { id, type, sender, payload, sentAt } = result.envelope;\n if (!KNOWN_TYPES.has(type)) {\n return { kind: 'pending' };\n }\n return { kind: 'message', message: { id, senderIdentityKey: sender, type, payload, sentAt } };\n }\n\n const credential = decodeCredential(edgeNotice.payload);\n if (!credential) {\n return { kind: 'rejected', reason: 'undecodable' };\n }\n const result = await verifySpaceInvitationNotice(credential, {\n self,\n claimedSender: edgeNotice.senderDid,\n now,\n ttlMs: SPACE_INVITATION_NOTICE_TTL_MS,\n });\n if (result.kind === 'fail') {\n return { kind: 'rejected', reason: result.reason };\n }\n return { kind: 'message', message: await legacyInvitationMessage(result.notice) };\n }\n\n #publish(): void {\n this.#loaded = true;\n this.#changed.emit(this.#snapshot());\n }\n}\n\nexport type InboxServiceLayerOptions = {\n /** Replaces EDGE, so the inbox works in tests without it. */\n relay?: InboxRelay;\n};\n\nexport const InboxServiceLayer = ({ relay }: InboxServiceLayerOptions = {}) =>\n Layer.effect(\n InboxService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n if (relay) {\n const { edgeClient, pushSource } = relay.connect(identityManager);\n return new InboxServiceImpl(identityManager, edgeClient, pushSource);\n }\n // Both are absent in the non-edge stack; the service then reports an empty inbox and refuses to send.\n const edgeClient = Option.getOrUndefined(yield* Effect.serviceOption(EdgeHttpClientService));\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n return new InboxServiceImpl(identityManager, edgeClient, edgeConnection);\n }),\n );\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { type Context } from '@dxos/context';\nimport { getCredentialAssertion } from '@dxos/credentials';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { type PublicKey } from '@dxos/keys';\nimport { AlreadyJoinedError } from '@dxos/protocols';\nimport { fromPublicKey, fromTimeframe, requirePublicKey, toTimeframe } from '@dxos/protocols/buf';\nimport { Invitation, Invitation_Kind } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport type { DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n type AdmissionRequest,\n AdmissionRequestSchema,\n type AdmissionResponse,\n AdmissionResponseSchema,\n DeviceAdmissionCredentialsSchema,\n DeviceAdmissionRequestSchema,\n type IntroductionRequest,\n IntroductionRequestSchema,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\n\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type JoinIdentityProps } from '../identity/index.ts';\n\nexport class DeviceInvitationProtocol implements InvitationProtocol {\n constructor(\n private readonly _keyring: KeyringApi,\n private readonly _getIdentity: () => Identity,\n private readonly _acceptIdentity: (identity: JoinIdentityProps) => Promise<Identity>,\n ) {}\n\n toJSON(): object {\n return {\n kind: 'device',\n };\n }\n\n checkCanInviteNewMembers(): Error | undefined {\n return undefined;\n }\n\n getInvitationContext(): Partial<Invitation> & Pick<Invitation, 'kind'> {\n return {\n kind: Invitation_Kind.DEVICE,\n };\n }\n\n async delegate(): Promise<PublicKey> {\n throw new Error('delegation not supported');\n }\n\n async cancelDelegation(): Promise<void> {\n throw new Error('delegation not supported');\n }\n\n async admit(_: Invitation, request: AdmissionRequest): Promise<AdmissionResponse> {\n invariant(request.kind.case === 'device');\n const identity = this._getIdentity();\n const credential = await identity.admitDevice(request.kind.value);\n invariant(\n getCredentialAssertion(credential).$typeName === 'dxos.halo.credentials.AuthorizedDevice',\n 'Invalid credential',\n );\n\n return create(AdmissionResponseSchema, {\n kind: {\n case: 'device',\n value: create(DeviceAdmissionCredentialsSchema, {\n identityKey: fromPublicKey(identity.identityKey),\n haloSpaceKey: fromPublicKey(identity.haloSpaceKey),\n genesisFeedKey: fromPublicKey(identity.haloGenesisFeedKey),\n controlTimeframe: fromTimeframe(identity.controlPipeline.state.timeframe),\n credential,\n // Absent while the host has not anchored its halo space yet; the joiner then has only the feed.\n haloSpaceRootUrl: identity.haloSpaceRootUrl,\n }),\n },\n });\n }\n\n checkInvitation(invitation: Partial<Invitation>): AlreadyJoinedError | undefined {\n try {\n const identity = this._getIdentity();\n if (identity) {\n return new AlreadyJoinedError({ message: 'Currently only one identity per client is supported.' });\n }\n } catch {\n // No identity.\n }\n }\n\n createIntroduction(): IntroductionRequest {\n return create(IntroductionRequestSchema, {});\n }\n\n async createAdmissionRequest(deviceProfile?: DeviceProfileDocument): Promise<AdmissionRequest> {\n const deviceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const dataFeedKey = await this._keyring.createKey();\n\n return create(AdmissionRequestSchema, {\n kind: {\n case: 'device',\n value: create(DeviceAdmissionRequestSchema, {\n deviceKey: fromPublicKey(deviceKey),\n controlFeedKey: fromPublicKey(controlFeedKey),\n dataFeedKey: fromPublicKey(dataFeedKey),\n profile: deviceProfile,\n }),\n },\n });\n }\n\n async accept(_ctx: Context, response: AdmissionResponse, request: AdmissionRequest): Promise<Partial<Invitation>> {\n invariant(response.kind.case === 'device');\n const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe, haloSpaceRootUrl, credential } =\n response.kind.value;\n\n invariant(request.kind.case === 'device');\n const { deviceKey, controlFeedKey, dataFeedKey, profile } = request.kind.value;\n\n // TODO(wittjosiah): When multiple identities are supported, verify identity doesn't already exist before accepting.\n // ctx is unused here because _acceptIdentity uses the identity lifecycle's own ctx internally.\n\n invariant(credential, 'Admission carries no credential.');\n const identityKeyValue = requirePublicKey(identityKey);\n await this._acceptIdentity({\n identityKey: identityKeyValue,\n deviceKey: requirePublicKey(deviceKey),\n haloSpaceKey: requirePublicKey(haloSpaceKey),\n haloGenesisFeedKey: requirePublicKey(genesisFeedKey),\n controlFeedKey: requirePublicKey(controlFeedKey),\n dataFeedKey: requirePublicKey(dataFeedKey),\n controlTimeframe: controlTimeframe && toTimeframe(controlTimeframe),\n deviceProfile: profile,\n authorizedDeviceCredential: credential,\n haloSpaceRootUrl,\n });\n\n return { identityKey: fromPublicKey(identityKeyValue) };\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Mutex, type MutexGuard } from '@dxos/async';\nimport { type Context, ContextDisposedError, cancelWithContext } from '@dxos/context';\nimport { bufWkt } from '@dxos/protocols/buf';\nimport { type Invitation, Invitation_State } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { SpaceMember_Role } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\n/** Names an invitation state for logging; falls back to `unknown` for a value outside the enum. */\nexport const stateToString = (state: Invitation_State): string => {\n return Object.entries(Invitation_State).find(([key, val]) => val === state)?.[0] ?? 'unknown';\n};\n\n/**\n * When the invitation expires, or `undefined` where it carries no lifetime.\n *\n * An invitation with no `created` timestamp is treated as created now, which is what the host does\n * when it mints one.\n */\nexport const computeExpirationTime = (invitation: Partial<Invitation>): Date | undefined => {\n if (!invitation.lifetime) {\n return;\n }\n const created = invitation.created ? Number(bufWkt.timestampMs(invitation.created)) : Date.now();\n return new Date(created + invitation.lifetime * 1000);\n};\n\nexport const tryAcquireBeforeContextDisposed = async (ctx: Context, mutex: Mutex): Promise<MutexGuard> => {\n let guard: MutexGuard | undefined;\n return cancelWithContext(\n ctx,\n (async () => {\n guard = await mutex.acquire();\n if (ctx.disposed) {\n guard.release();\n guard = undefined;\n throw new ContextDisposedError();\n }\n return guard;\n })(),\n );\n};\n\n/**\n * The role an invitation admits with.\n *\n * An invitation without a role admits an administrator, as it did before the role was carried.\n */\nexport const toSpaceMemberRole = (role: SpaceMember_Role | undefined): SpaceMember_Role =>\n role ?? SpaceMember_Role.ADMIN;\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { type Context } from '@dxos/context';\nimport {\n createCancelDelegatedSpaceInvitationCredential,\n createDelegatedSpaceInvitationCredential,\n credentialIdOf,\n credentialOfPayload,\n getCredentialAssertion,\n} from '@dxos/credentials';\nimport { writeMessages } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { AlreadyJoinedError, AuthorizationError, InvalidInvitationError, SpaceNotFoundError } from '@dxos/protocols';\nimport {\n fromDate,\n fromPublicKey,\n fromTimeframe,\n requirePublicKey,\n toPublicKey,\n toTimeframe,\n} from '@dxos/protocols/buf';\nimport {\n Invitation,\n Invitation_AuthMethod,\n Invitation_Kind,\n Invitation_Type,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type ProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { DelegateSpaceInvitationSchema } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport {\n type AdmissionRequest,\n AdmissionRequestSchema,\n type AdmissionResponse,\n AdmissionResponseSchema,\n type IntroductionRequest,\n IntroductionRequestSchema,\n SpaceAdmissionCredentialsSchema,\n SpaceAdmissionRequestSchema,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\n\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport { type SigningContext } from '../spaces/index.ts';\nimport { computeExpirationTime, toSpaceMemberRole } from './utils.ts';\n\nexport class SpaceInvitationProtocol implements InvitationProtocol {\n constructor(\n private readonly _spaceManager: SpacesContract.Manager,\n private readonly _signingContext: SigningContext,\n private readonly _keyring: KeyringApi,\n private readonly _spaceKey?: PublicKey,\n ) {}\n\n toJSON(): object {\n return {\n kind: 'space',\n deviceKey: this._signingContext.deviceKey,\n spaceKey: this._spaceKey,\n };\n }\n\n checkCanInviteNewMembers(): Error | undefined {\n if (this._spaceKey == null) {\n return new InvalidInvitationError({ message: 'No spaceKey was provided for a space invitation.' });\n }\n const space = this._spaceManager.spaces.get(this._spaceKey);\n if (space == null) {\n return new SpaceNotFoundError(this._spaceKey);\n }\n if (!space?.inner.spaceState.hasMembershipManagementPermission(this._signingContext.identityKey)) {\n return new AuthorizationError({ message: 'No member management permission.' });\n }\n return undefined;\n }\n\n getInvitationContext(): Partial<Invitation> & Pick<Invitation, 'kind'> {\n invariant(this._spaceKey);\n const space = this._spaceManager.spaces.get(this._spaceKey);\n invariant(space);\n return {\n kind: Invitation_Kind.SPACE,\n spaceKey: fromPublicKey(this._spaceKey),\n spaceId: space.id,\n };\n }\n\n async admit(\n invitation: Invitation,\n request: AdmissionRequest,\n guestProfile?: ProfileDocument | undefined,\n ): Promise<AdmissionResponse> {\n invariant(this._spaceKey && request.kind.case === 'space');\n const spaceRequest = request.kind.value;\n log('writing guest credentials', { host: this._signingContext.deviceKey, guest: spaceRequest.deviceKey });\n\n const spaceMemberCredential = await this._spaceManager.admitMember({\n spaceKey: this._spaceKey,\n identityKey: requirePublicKey(spaceRequest.identityKey),\n role: toSpaceMemberRole(invitation.role),\n profile: guestProfile,\n delegationCredentialId: toPublicKey(invitation.delegationCredentialId),\n });\n\n const space = this._spaceManager.spaces.get(this._spaceKey);\n const controlTimeframe = space?.inner.controlPipeline.state.timeframe;\n return create(AdmissionResponseSchema, {\n kind: {\n case: 'space',\n value: create(SpaceAdmissionCredentialsSchema, {\n credential: spaceMemberCredential,\n controlTimeframe: controlTimeframe && fromTimeframe(controlTimeframe),\n }),\n },\n });\n }\n\n async delegate(invitation: Invitation): Promise<PublicKey> {\n invariant(this._spaceKey);\n const space = this._spaceManager.spaces.get(this._spaceKey);\n invariant(space);\n if (invitation.authMethod === Invitation_AuthMethod.KNOWN_PUBLIC_KEY) {\n invariant(invitation.guestKeypair?.publicKey);\n }\n\n log('writing delegate space invitation', { host: this._signingContext.deviceKey, id: invitation.invitationId });\n const swarmKey = toPublicKey(invitation.swarmKey);\n invariant(swarmKey, 'swarmKey missing in the invitation');\n const expiresOn = computeExpirationTime(invitation);\n const credential = await createDelegatedSpaceInvitationCredential(\n this._signingContext.credentialSigner,\n space.key,\n create(DelegateSpaceInvitationSchema, {\n invitationId: invitation.invitationId,\n authMethod: invitation.authMethod,\n swarmKey: fromPublicKey(swarmKey),\n role: toSpaceMemberRole(invitation.role),\n expiresOn: expiresOn && fromDate(expiresOn),\n multiUse: invitation.multiUse ?? false,\n guestKey:\n invitation.authMethod === Invitation_AuthMethod.KNOWN_PUBLIC_KEY\n ? invitation.guestKeypair?.publicKey\n : undefined,\n }),\n );\n\n await writeMessages(space.inner.controlPipeline.writer, [credential]);\n return credentialIdOf(credentialOfPayload(credential));\n }\n\n async cancelDelegation(invitation: Invitation): Promise<void> {\n invariant(this._spaceKey);\n invariant(invitation.type === Invitation_Type.DELEGATED && invitation.delegationCredentialId);\n const delegationCredentialId = toPublicKey(invitation.delegationCredentialId);\n invariant(delegationCredentialId);\n const space = this._spaceManager.spaces.get(this._spaceKey);\n invariant(space);\n\n log('cancelling delegated space invitation', { host: this._signingContext.deviceKey, id: invitation.invitationId });\n const credential = await createCancelDelegatedSpaceInvitationCredential(\n this._signingContext.credentialSigner,\n space.key,\n delegationCredentialId,\n );\n\n await writeMessages(space.inner.controlPipeline.writer, [credential]);\n }\n\n checkInvitation(invitation: Partial<Invitation>): InvalidInvitationError | AlreadyJoinedError | undefined {\n if (invitation.spaceKey == null) {\n return new InvalidInvitationError({ message: 'No spaceKey was provided for a space invitation.' });\n }\n const spaceKey = toPublicKey(invitation.spaceKey);\n if (spaceKey && this._spaceManager.spaces.has(spaceKey)) {\n return new AlreadyJoinedError({ message: 'Already joined space.' });\n }\n }\n\n createIntroduction(): IntroductionRequest {\n return create(IntroductionRequestSchema, { profile: this._signingContext.getProfile() });\n }\n\n async createAdmissionRequest(): Promise<AdmissionRequest> {\n // Generate a pair of keys for our feeds.\n const controlFeedKey = await this._keyring.createKey();\n const dataFeedKey = await this._keyring.createKey();\n\n return create(AdmissionRequestSchema, {\n kind: {\n case: 'space',\n value: create(SpaceAdmissionRequestSchema, {\n identityKey: fromPublicKey(this._signingContext.identityKey),\n deviceKey: fromPublicKey(this._signingContext.deviceKey),\n controlFeedKey: fromPublicKey(controlFeedKey),\n dataFeedKey: fromPublicKey(dataFeedKey),\n }),\n },\n });\n }\n\n async accept(ctx: Context, response: AdmissionResponse): Promise<Partial<Invitation>> {\n invariant(response.kind.case === 'space');\n const { credential, controlTimeframe, dataTimeframe } = response.kind.value;\n invariant(credential, 'Admission carries no credential.');\n const assertion = getCredentialAssertion(credential);\n invariant(assertion.$typeName === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');\n invariant(requirePublicKey(credential.subject?.id).equals(this._signingContext.identityKey));\n\n const spaceKey = requirePublicKey(assertion.spaceKey);\n if (this._spaceManager.spaces.has(spaceKey)) {\n throw new AlreadyJoinedError({ message: 'Already joined space.' });\n }\n\n // Create local space.\n await this._spaceManager.acceptSpace(ctx, {\n spaceKey,\n genesisFeedKey: requirePublicKey(assertion.genesisFeedKey),\n spaceRootUrl: assertion.spaceRootUrl,\n controlTimeframe: controlTimeframe && toTimeframe(controlTimeframe),\n dataTimeframe: dataTimeframe && toTimeframe(dataTimeframe),\n tags: assertion.tags,\n });\n\n await this._signingContext.recordCredential(credential);\n\n return { spaceKey: fromPublicKey(spaceKey) };\n }\n}\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { failUndefined } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { KeyringApiService } from '@dxos/keyring';\nimport { toPublicKey } from '@dxos/protocols/buf';\nimport { type Invitation, Invitation_Kind } from '@dxos/protocols/buf/dxos/client/invitation_pb';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport * as InvitationsContract from '../../contracts/invitations.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport { DeviceInvitationProtocol } from './device-invitation-protocol.ts';\nimport { SpaceInvitationProtocol } from './space-invitation-protocol.ts';\n\n/**\n * Wires the per-kind invitation protocol factories into the invitations manager. Sits above the\n * data space manager because the space protocol needs it, while the manager itself is below.\n */\nexport const InvitationFactoriesLayer: Layer.Layer<\n never,\n never,\n | InvitationsContract.ManagerService\n | IdentityContract.ManagerService\n | IdentityContract.LifecycleService\n | KeyringApiService\n | SpacesContract.ManagerService\n | SpacesContract.SigningContextProviderService\n> = Layer.effectDiscard(\n Effect.gen(function* () {\n const invitationsManager = yield* InvitationsContract.ManagerService;\n const identityManager = yield* IdentityContract.ManagerService;\n const identityLifecycle = yield* IdentityContract.LifecycleService;\n const keyring = yield* KeyringApiService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const signingContextProvider = yield* SpacesContract.SigningContextProviderService;\n\n const factories = new Map<Invitation_Kind, (invitation: Partial<Invitation>) => InvitationProtocol>([\n [\n Invitation_Kind.DEVICE,\n () =>\n new DeviceInvitationProtocol(\n keyring,\n () => identityManager.identity ?? failUndefined(),\n (params) => identityLifecycle.acceptIdentity(params),\n ),\n ],\n [\n Invitation_Kind.SPACE,\n (invitation) =>\n new SpaceInvitationProtocol(\n dataSpaceManager,\n signingContextProvider(),\n keyring,\n toPublicKey(invitation.spaceKey),\n ),\n ],\n ]);\n\n invitationsManager.setInvitationHandlerFactory((invitation) => {\n if (identityManager.identity == null && invitation.kind === Invitation_Kind.SPACE) {\n throw new Error('Identity must be created before joining a space.');\n }\n const factory = factories.get(invitation.kind);\n invariant(factory, `Unknown invitation kind: ${invitation.kind}`);\n return factory(invitation);\n });\n }),\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create, fromBinary } from '@bufbuild/protobuf';\n\nimport { type MutexGuard, scheduleMicroTask, scheduleTask } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { sign } from '@dxos/crypto';\nimport { type EdgeHttpClient } from '@dxos/edge-client';\nimport { invariant } from '@dxos/invariant';\nimport { SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n EdgeAuthChallengeError,\n EdgeCallFailedError,\n type JoinSpaceRequest,\n type JoinSpaceResponseBody,\n} from '@dxos/protocols';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport {\n Invitation_AuthMethod,\n Invitation_Kind,\n Invitation_State,\n Invitation_Type,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { CredentialSchema, type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n type AdmissionRequest,\n AdmissionRequestSchema,\n type AdmissionResponse,\n AdmissionResponseSchema,\n SpaceAdmissionCredentialsSchema,\n type SpaceAdmissionRequest,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { trace } from '@dxos/tracing';\n\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport { type FlowLockHolder, type GuardedInvitationState } from './invitation-state.ts';\nimport { tryAcquireBeforeContextDisposed } from './utils.ts';\n\nexport interface EdgeInvitationHandlerCallbacks {\n onInvitationSuccess(ctx: Context, response: AdmissionResponse, request: AdmissionRequest): Promise<void>;\n}\n\nexport const MAX_RETRIES_PER_INVITATION = 5;\nexport const DEFAULT_REQUEST_RETRY_INTERVAL_MS = 3000;\nexport const DEFAULT_REQUEST_RETRY_JITTER_MS = 500;\n\nexport type EdgeInvitationConfig = {\n retryInterval?: number;\n retryJitter?: number;\n};\n\nexport class EdgeInvitationHandler implements FlowLockHolder {\n private _flowLock: MutexGuard | undefined;\n\n private readonly _retryInterval: number;\n private readonly _retryJitter: number;\n\n constructor(\n config: EdgeInvitationConfig | undefined,\n private readonly _client: EdgeHttpClient | undefined,\n private readonly _callbacks: EdgeInvitationHandlerCallbacks,\n ) {\n this._retryInterval = config?.retryInterval ?? DEFAULT_REQUEST_RETRY_INTERVAL_MS;\n this._retryJitter = config?.retryJitter ?? DEFAULT_REQUEST_RETRY_JITTER_MS;\n }\n\n public handle(\n ctx: Context,\n guardedState: GuardedInvitationState,\n protocol: InvitationProtocol,\n deviceProfile?: DeviceProfileDocument,\n ): void {\n if (!this._client) {\n log('edge disabled');\n return;\n }\n\n const invitation = guardedState.current;\n const spaceId = invitation.spaceId;\n const canBeHandledByEdge =\n invitation.authMethod !== Invitation_AuthMethod.SHARED_SECRET &&\n invitation.type === Invitation_Type.DELEGATED &&\n invitation.kind === Invitation_Kind.SPACE &&\n spaceId != null &&\n SpaceId.isValid(spaceId);\n\n if (!canBeHandledByEdge) {\n log('invitation could not be handled by edge', { invitation });\n return;\n }\n\n ctx.onDispose(() => {\n this._flowLock?.release();\n this._flowLock = undefined;\n });\n\n let requestCount = 0;\n const tryHandleInvitation = async () => {\n requestCount++;\n const admissionRequest = await protocol.createAdmissionRequest(deviceProfile);\n if (admissionRequest.kind.case === 'space') {\n const spaceRequest = admissionRequest.kind.value;\n try {\n await this._handleSpaceInvitationFlow(ctx, guardedState, spaceRequest, spaceId);\n } catch (error) {\n if (error instanceof EdgeCallFailedError) {\n log.info('join space with edge unsuccessful', {\n reason: error.message,\n retryable: error.isRetryable,\n after: error.retryAfterMs ?? this._calculateNextRetryMs(),\n });\n if (error.isRetryable && requestCount < MAX_RETRIES_PER_INVITATION) {\n scheduleTask(ctx, tryHandleInvitation, error.retryAfterMs ?? this._calculateNextRetryMs());\n }\n } else if (requestCount < MAX_RETRIES_PER_INVITATION) {\n log.info('failed to handle invitation with edge', { error });\n scheduleTask(ctx, tryHandleInvitation, this._calculateNextRetryMs());\n }\n }\n }\n };\n scheduleMicroTask(ctx, tryHandleInvitation);\n }\n\n @trace.span({ op: 'invitation.edge' })\n private async _handleSpaceInvitationFlow(\n ctx: Context,\n guardedState: GuardedInvitationState,\n admissionRequest: SpaceAdmissionRequest,\n spaceId: SpaceId,\n ): Promise<void> {\n try {\n log('edge invitation flow');\n this._flowLock = await tryAcquireBeforeContextDisposed(ctx, guardedState.mutex);\n log.verbose('edge invitation flow acquired the lock');\n\n guardedState.set(this, Invitation_State.CONNECTING);\n\n const response = await this._joinSpaceByInvitation(ctx, guardedState, spaceId, {\n identityKey: requirePublicKey(admissionRequest.identityKey).toHex(),\n invitationId: guardedState.current.invitationId,\n });\n\n const admissionResponse = await this._mapToAdmissionResponse(response);\n await this._callbacks.onInvitationSuccess(\n ctx,\n admissionResponse,\n create(AdmissionRequestSchema, { kind: { case: 'space', value: admissionRequest } }),\n );\n } catch (error) {\n guardedState.set(this, Invitation_State.ERROR);\n throw error;\n } finally {\n this._flowLock?.release();\n this._flowLock = undefined;\n }\n }\n\n private async _mapToAdmissionResponse(edgeResponse: JoinSpaceResponseBody): Promise<AdmissionResponse> {\n const credentialBytes = Buffer.from(edgeResponse.spaceMemberCredential, 'base64');\n return create(AdmissionResponseSchema, {\n kind: {\n case: 'space',\n value: create(SpaceAdmissionCredentialsSchema, {\n credential: fromBinary(CredentialSchema, credentialBytes),\n }),\n },\n });\n }\n\n private async _joinSpaceByInvitation(\n ctx: Context,\n guardedState: GuardedInvitationState,\n spaceId: SpaceId,\n request: JoinSpaceRequest,\n ): Promise<JoinSpaceResponseBody> {\n invariant(this._client);\n try {\n return await this._client.joinSpaceByInvitation(ctx, spaceId, request);\n } catch (error: any) {\n if (error instanceof EdgeAuthChallengeError) {\n const publicKey = guardedState.current.guestKeypair?.publicKey;\n const privateKey = guardedState.current.guestKeypair?.privateKey;\n if (!privateKey || !publicKey) {\n throw error;\n }\n const signature = sign(Buffer.from(error.challenge, 'base64'), Buffer.from(privateKey.data));\n return this._client.joinSpaceByInvitation(ctx, spaceId, {\n ...request,\n signature: Buffer.from(signature).toString('base64'),\n });\n } else {\n throw error;\n }\n }\n }\n\n public hasFlowLock(): boolean {\n return this._flowLock != null;\n }\n\n private _calculateNextRetryMs(): number {\n return this._retryInterval + Math.random() * this._retryJitter;\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport { EmptySchema } from '@bufbuild/protobuf/wkt';\n\nimport { type Mutex, type MutexGuard, Trigger } from '@dxos/async';\nimport { Context, cancelWithContext } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { InvalidInvitationExtensionRoleError } from '@dxos/protocols';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport { Invitation_State } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n InvitationHostService as InvitationHostServiceDesc,\n type InvitationOptions,\n InvitationOptions_Role,\n InvitationOptionsSchema,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\n\nimport { type FlowLockHolder } from './invitation-state.ts';\nimport { tryAcquireBeforeContextDisposed } from './utils.ts';\n\ntype InvitationHostService = BufService<typeof InvitationHostServiceDesc>;\n\nconst OPTIONS_TIMEOUT = 10_000;\n\ntype InvitationGuestExtensionCallbacks = {\n // Deliberately not async to not block the extensions opening.\n onOpen: (ctx: Context, extensionCtx: ExtensionContext) => void;\n onError: (error: Error) => void;\n\n onStateUpdate: (newState: Invitation_State) => void;\n};\n\n/**\n * Guest's side for a connection to a concrete peer in p2p network during invitation.\n */\nexport class InvitationGuestExtension\n extends RpcExtension<\n { InvitationHostService: InvitationHostService },\n { InvitationHostService: InvitationHostService }\n >\n implements FlowLockHolder\n{\n private _ctx = new Context();\n private _remoteOptions?: InvitationOptions;\n private _remoteOptionsTrigger = new Trigger();\n /**\n * Held to allow only one invitation flow at a time to be active.\n */\n private _invitationFlowLock: MutexGuard | null = null;\n\n constructor(\n private readonly _invitationFlowMutex: Mutex,\n private readonly _callbacks: InvitationGuestExtensionCallbacks,\n ) {\n super({\n requested: {\n InvitationHostService: getBufService<InvitationHostService>('dxos.halo.invitations.InvitationHostService'),\n },\n exposed: {\n InvitationHostService: getBufService<InvitationHostService>('dxos.halo.invitations.InvitationHostService'),\n },\n });\n }\n\n public hasFlowLock(): boolean {\n return this._invitationFlowLock != null;\n }\n\n protected override async getHandlers(): Promise<{ InvitationHostService: InvitationHostService }> {\n return {\n InvitationHostService: {\n options: async (options) => {\n invariant(!this._remoteOptions, 'Remote options already set.');\n this._remoteOptions = options;\n this._remoteOptionsTrigger.wake();\n return create(EmptySchema, {});\n },\n introduce: () => {\n throw new Error('Method not allowed.');\n },\n authenticate: () => {\n throw new Error('Method not allowed.');\n },\n admit: () => {\n throw new Error('Method not allowed.');\n },\n },\n };\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n await super.onOpen(context);\n\n try {\n log.verbose('guest acquire lock');\n this._invitationFlowLock = await tryAcquireBeforeContextDisposed(this._ctx, this._invitationFlowMutex);\n log.verbose('guest lock acquired');\n await cancelWithContext(\n this._ctx,\n this.rpc.InvitationHostService.options(create(InvitationOptionsSchema, { role: InvitationOptions_Role.GUEST })),\n );\n log.verbose('options sent');\n await cancelWithContext(this._ctx, this._remoteOptionsTrigger.wait({ timeout: OPTIONS_TIMEOUT }));\n log.verbose('options received');\n if (this._remoteOptions?.role !== InvitationOptions_Role.HOST) {\n throw new InvalidInvitationExtensionRoleError({\n context: {\n expected: InvitationOptions_Role.HOST,\n remoteOptions: this._remoteOptions,\n remotePeerId: context.remotePeerId,\n },\n });\n }\n\n this._callbacks.onOpen(this._ctx, context);\n } catch (err: any) {\n if (this._invitationFlowLock != null) {\n this._callbacks.onError(err);\n }\n if (!this._ctx.disposed) {\n context.close(err);\n }\n }\n }\n\n override async onClose(): Promise<void> {\n await this._destroy();\n }\n\n override async onAbort(): Promise<void> {\n await this._destroy();\n }\n\n private async _destroy(): Promise<void> {\n await this._ctx.dispose();\n if (this._invitationFlowLock != null) {\n this._invitationFlowLock.release();\n this._invitationFlowLock = null;\n log.verbose('invitation flow lock released');\n }\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport { EmptySchema } from '@bufbuild/protobuf/wkt';\n\nimport { type Mutex, type MutexGuard, Trigger, asyncTimeout, scheduleTask } from '@dxos/async';\nimport { Context, cancelWithContext } from '@dxos/context';\nimport { randomBytes, verify } from '@dxos/crypto';\nimport { InvariantViolation, invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { InvalidInvitationExtensionRoleError } from '@dxos/protocols';\nimport { toPublicKey } from '@dxos/protocols/buf';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport { Invitation, Invitation_AuthMethod, Invitation_State } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type ProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n type AdmissionRequest,\n type AdmissionResponse,\n AuthenticationResponse_Status,\n AuthenticationResponseSchema,\n IntroductionResponseSchema,\n InvitationHostService as InvitationHostServiceDesc,\n type InvitationOptions,\n InvitationOptions_Role,\n InvitationOptionsSchema,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\n\nimport type { FlowLockHolder } from './invitation-state.ts';\n\ntype InvitationHostService = BufService<typeof InvitationHostServiceDesc>;\nimport { stateToString, tryAcquireBeforeContextDisposed } from './utils.ts';\n\n/// Timeout for the options exchange.\nconst OPTIONS_TIMEOUT = 10_000;\n\nexport const MAX_OTP_ATTEMPTS = 3;\n\ntype InvitationHostExtensionCallbacks = {\n activeInvitation: Invitation | null;\n\n // Deliberately not async to not block the extensions opening.\n onOpen: (ctx: Context, extensionCtx: ExtensionContext) => void;\n onError: (error: Error) => void;\n\n onStateUpdate: (newState: Invitation_State) => void;\n\n admit: (request: AdmissionRequest) => Promise<AdmissionResponse>;\n};\n\n/**\n * Host's side for a connection to a concrete peer in p2p network during invitation.\n */\nexport class InvitationHostExtension\n extends RpcExtension<\n { InvitationHostService: InvitationHostService },\n { InvitationHostService: InvitationHostService }\n >\n implements FlowLockHolder\n{\n /**\n * @internal\n */\n private _ctx = new Context();\n private _remoteOptions?: InvitationOptions;\n private _remoteOptionsTrigger = new Trigger();\n\n private _challenge?: Buffer = undefined;\n\n public guestProfile?: ProfileDocument = undefined;\n\n public authenticationPassed = false;\n\n /**\n * Retry counter for SHARED_SECRET authentication method.\n */\n public authenticationRetry = 0;\n\n /**\n * Resolved when admission is completed.\n */\n public completedTrigger = new Trigger<PublicKey>();\n\n /**\n * Held to allow only one invitation flow at a time to be active.\n */\n private _invitationFlowLock: MutexGuard | null = null;\n /**\n * The last state THIS connection tried to set, as opposed to the invitation-wide shared state.\n * Records the attempt, not the guard's acceptance, so the two can differ when a write was rejected.\n */\n private _lastSetState: Invitation_State = Invitation_State.INIT;\n\n constructor(\n private readonly _invitationFlowMutex: Mutex,\n private readonly _callbacks: InvitationHostExtensionCallbacks,\n ) {\n super({\n requested: {\n InvitationHostService: getBufService<InvitationHostService>('dxos.halo.invitations.InvitationHostService'),\n },\n exposed: {\n InvitationHostService: getBufService<InvitationHostService>('dxos.halo.invitations.InvitationHostService'),\n },\n });\n }\n\n private _setState(state: Invitation_State): void {\n this._lastSetState = state;\n this._callbacks.onStateUpdate(state);\n }\n\n public hasFlowLock(): boolean {\n return this._invitationFlowLock != null;\n }\n\n protected override async getHandlers(): Promise<{ InvitationHostService: InvitationHostService }> {\n return {\n // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.\n // Perhaps in the future we will have more complex logic here.\n InvitationHostService: {\n options: async (options) => {\n invariant(!this._remoteOptions, 'Remote options already set.');\n this._remoteOptions = options;\n if (options.role === InvitationOptions_Role.GUEST && this.hasFlowLock()) {\n this._setState(Invitation_State.CONNECTED);\n }\n this._remoteOptionsTrigger.wake();\n return create(EmptySchema, {});\n },\n\n introduce: async (request) => {\n const { profile, invitationId } = request;\n log('introducing host invitation');\n\n const invitation = this._requireActiveInvitation();\n this._assertInvitationState(Invitation_State.CONNECTED);\n if (invitationId !== invitation?.invitationId) {\n log.warn('incorrect invitationId', { expected: invitation.invitationId, actual: invitationId });\n this._callbacks.onError(new Error('Incorrect invitationId.'));\n scheduleTask(this._ctx, () => this.close());\n // TODO(dmaretskyi): Better error handling.\n return create(IntroductionResponseSchema, { authMethod: Invitation_AuthMethod.NONE });\n }\n\n log.verbose('guest introduced themselves', { guestProfile: profile });\n this.guestProfile = profile;\n this._setState(Invitation_State.READY_FOR_AUTHENTICATION);\n this._challenge =\n invitation.authMethod === Invitation_AuthMethod.KNOWN_PUBLIC_KEY ? randomBytes(32) : undefined;\n\n log('introduced host invitation');\n return create(IntroductionResponseSchema, {\n authMethod: invitation.authMethod,\n challenge: this._challenge,\n });\n },\n\n authenticate: async ({ authCode: code, signedChallenge }) => {\n log('authenticating host invitation');\n\n const invitation = this._requireActiveInvitation();\n log.verbose('received authentication request', { authCode: code });\n let status = AuthenticationResponse_Status.OK;\n\n this._assertInvitationState([Invitation_State.AUTHENTICATING, Invitation_State.READY_FOR_AUTHENTICATION]);\n this._setState(Invitation_State.AUTHENTICATING);\n\n switch (invitation.authMethod) {\n case Invitation_AuthMethod.NONE: {\n log('authentication not required');\n return create(AuthenticationResponseSchema, { status: AuthenticationResponse_Status.OK });\n }\n\n case Invitation_AuthMethod.SHARED_SECRET: {\n if (invitation.authCode) {\n if (this.authenticationRetry++ > MAX_OTP_ATTEMPTS) {\n status = AuthenticationResponse_Status.INVALID_OPT_ATTEMPTS;\n } else if (code !== invitation.authCode) {\n status = AuthenticationResponse_Status.INVALID_OTP;\n } else {\n this.authenticationPassed = true;\n }\n }\n break;\n }\n\n case Invitation_AuthMethod.KNOWN_PUBLIC_KEY: {\n const guestPublicKey = toPublicKey(invitation.guestKeypair?.publicKey);\n if (!guestPublicKey) {\n status = AuthenticationResponse_Status.INTERNAL_ERROR;\n break;\n }\n const isSignatureValid =\n this._challenge &&\n verify(this._challenge, Buffer.from(signedChallenge ?? []), guestPublicKey.asBuffer());\n if (isSignatureValid) {\n this.authenticationPassed = true;\n } else {\n status = AuthenticationResponse_Status.INVALID_SIGNATURE;\n }\n break;\n }\n\n default: {\n log.error('invalid authentication method', { authMethod: invitation.authMethod });\n status = AuthenticationResponse_Status.INTERNAL_ERROR;\n break;\n }\n }\n\n if (![AuthenticationResponse_Status.OK, AuthenticationResponse_Status.INVALID_OTP].includes(status)) {\n this._callbacks.onError(new Error(`Authentication failed, with status=${status}`));\n scheduleTask(this._ctx, () => this.close());\n return create(AuthenticationResponseSchema, { status });\n }\n\n log('authenticated host invitation', { status });\n return create(AuthenticationResponseSchema, { status });\n },\n\n admit: async (request) => {\n log('admitting guest');\n const invitation = this._requireActiveInvitation();\n\n try {\n // Check authenticated.\n if (isAuthenticationRequired(invitation)) {\n this._assertInvitationState(Invitation_State.AUTHENTICATING);\n if (!this.authenticationPassed) {\n throw new Error('Not authenticated');\n }\n }\n\n const response = await this._callbacks.admit(request);\n\n log('admitted guest');\n return response;\n } catch (err: any) {\n this._callbacks.onError(err);\n throw err;\n }\n },\n },\n };\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n await super.onOpen(context);\n\n try {\n log.verbose('host acquire lock');\n this._invitationFlowLock = await tryAcquireBeforeContextDisposed(this._ctx, this._invitationFlowMutex);\n log.verbose('host lock acquired');\n this._setState(Invitation_State.CONNECTING);\n const optionsAcknowledged = this.rpc.InvitationHostService.options(\n create(InvitationOptionsSchema, { role: InvitationOptions_Role.HOST }),\n );\n void optionsAcknowledged.catch(() => {});\n log.verbose('options sent');\n await cancelWithContext(this._ctx, this._remoteOptionsTrigger.wait({ timeout: OPTIONS_TIMEOUT }));\n log.verbose('options received');\n if (this._remoteOptions?.role !== InvitationOptions_Role.GUEST) {\n throw new InvalidInvitationExtensionRoleError({\n context: {\n expected: InvitationOptions_Role.GUEST,\n remoteOptions: this._remoteOptions,\n remotePeerId: context.remotePeerId,\n },\n });\n }\n // Only while the flow is still where this method left it. When `options` and `introduce` are\n // dispatched in one drain — the overtaking this whole path exists to survive — the handlers\n // have already carried the state past CONNECTED, and re-emitting it here would rewind them.\n if (this._lastSetState === Invitation_State.CONNECTING) {\n this._setState(Invitation_State.CONNECTED);\n }\n // Bounded like the trigger above: a guest that never acknowledges must fail the invitation,\n // not leave it displayed as live with `onOpen` never reached.\n await cancelWithContext(this._ctx, asyncTimeout(optionsAcknowledged, OPTIONS_TIMEOUT));\n this._callbacks.onOpen(this._ctx, context);\n } catch (err: any) {\n if (this._invitationFlowLock != null) {\n this._callbacks.onError(err);\n }\n if (!this._ctx.disposed) {\n context.close(err);\n }\n }\n }\n\n private _requireActiveInvitation(): Invitation {\n const invitation = this._callbacks.activeInvitation;\n if (invitation == null) {\n scheduleTask(this._ctx, () => this.close());\n throw new Error('Active invitation not found');\n }\n return invitation;\n }\n\n private _assertInvitationState(stateOrMany: Invitation_State | Invitation_State[]): void {\n const invitation = this._requireActiveInvitation();\n const validStates = Array.isArray(stateOrMany) ? stateOrMany : [stateOrMany];\n if (!validStates.includes(invitation.state)) {\n scheduleTask(this._ctx, () => this.close());\n throw new InvariantViolation(\n `Expected ${stateToString(invitation.state)} to be one of [${validStates.map(stateToString).join(', ')}]`,\n );\n }\n }\n\n override async onClose(): Promise<void> {\n await this._destroy();\n }\n\n override async onAbort(): Promise<void> {\n await this._destroy();\n }\n\n private async _destroy(): Promise<void> {\n await this._ctx.dispose();\n if (this._invitationFlowLock != null) {\n this._invitationFlowLock?.release();\n this._invitationFlowLock = null;\n log.verbose('invitation flow lock released');\n }\n }\n}\n\nexport const isAuthenticationRequired = (invitation: Invitation) =>\n invitation.authMethod !== Invitation_AuthMethod.NONE;\n","/**\n * A utility object for serializing invitation state changes by multiple concurrent\n * invitation flow connections.\n */\n//\n// Copyright 2024 DXOS.org\n//\n\nimport { Mutex, type PushStream } from '@dxos/async';\nimport { type Context } from '@dxos/context';\nimport { log } from '@dxos/log';\nimport { Invitation, Invitation_State } from '@dxos/protocols/buf/dxos/client/invitation_pb';\n\nimport { stateToString } from './utils.ts';\n\nexport interface FlowLockHolder {\n hasFlowLock(): boolean;\n}\n\nexport interface GuardedInvitationState {\n mutex: Mutex;\n current: Invitation;\n\n complete(newState: Partial<Invitation>): void;\n set(lockHolder: FlowLockHolder | null, newState: Invitation_State): boolean;\n error(lockHolder: FlowLockHolder | null, error: any): boolean;\n}\n\nexport const createGuardedInvitationState = (\n ctx: Context,\n invitation: Invitation,\n stream: PushStream<Invitation>,\n): GuardedInvitationState => {\n const mutex = new Mutex();\n let lastActiveLockHolder: FlowLockHolder | null = null;\n let currentInvitation = { ...invitation };\n const isStateChangeAllowed = (lockHolder: FlowLockHolder | null) => {\n if (ctx.disposed || (lockHolder !== null && mutex.isLocked() && !lockHolder.hasFlowLock())) {\n return false;\n }\n return lockHolder == null || lastActiveLockHolder !== lockHolder || isNonTerminalState(currentInvitation.state);\n };\n return {\n mutex,\n get current() {\n return currentInvitation;\n },\n complete: (newState: Partial<Invitation>) => {\n logStateUpdate(currentInvitation, undefined, invitation.state);\n currentInvitation = { ...currentInvitation, ...newState };\n stream.next(currentInvitation);\n return ctx.dispose();\n },\n set: (lockHolder: FlowLockHolder | null, newState: Invitation_State): boolean => {\n if (isStateChangeAllowed(lockHolder)) {\n logStateUpdate(currentInvitation, lockHolder, newState);\n currentInvitation = { ...currentInvitation, state: newState };\n stream.next(currentInvitation);\n lastActiveLockHolder = lockHolder;\n return true;\n }\n return false;\n },\n error: (lockHolder: FlowLockHolder | null, error: any): boolean => {\n if (isStateChangeAllowed(lockHolder)) {\n logStateUpdate(currentInvitation, lockHolder, Invitation_State.ERROR, error);\n currentInvitation = { ...currentInvitation, state: Invitation_State.ERROR };\n stream.next(currentInvitation);\n stream.error(error);\n lastActiveLockHolder = lockHolder;\n return true;\n }\n return false;\n },\n };\n};\n\n/** How a flow ended, from its last state; a flow disposed before a terminal state is `closed`. */\nexport const getInvitationOutcome = (state: Invitation_State): string =>\n isNonTerminalState(state) ? 'closed' : Invitation_State[state].toLowerCase();\n\nconst logStateUpdate = (\n invitation: Invitation,\n actor: FlowLockHolder | null | undefined,\n newState: Invitation_State,\n error?: Error,\n) => {\n const logContext = {\n invitationId: invitation.invitationId,\n actor: actor?.constructor.name,\n newState: stateToString(newState),\n oldState: stateToString(invitation.state),\n error: error?.message,\n errorStack: error?.stack,\n };\n log.verbose('dxos.sdk.invitations-handler.state.update', logContext);\n};\n\nconst isNonTerminalState = (currentState: Invitation_State): boolean => {\n return ![\n Invitation_State.SUCCESS,\n Invitation_State.ERROR,\n Invitation_State.CANCELLED,\n Invitation_State.TIMEOUT,\n Invitation_State.EXPIRED,\n ].includes(currentState);\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport type { SwarmController, Topology } from '@dxos/network-manager';\nimport { InvitationOptions_Role } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { ComplexMap, ComplexSet } from '@dxos/util';\n\n/** Connections a host starts to one peer before it stops retrying that peer. */\nconst MAX_DIALS_PER_PEER = 3;\n\n/**\n * Hosts are listening on an invitation topic.\n * They dial one peer at a time, and only while they have no connection (no invitation flow in progress)\n * and no dial still waiting for the swarm to create its connection.\n * A peer whose connection closed is dialed again once the swarm offers it as a candidate after its backoff,\n * up to {@link MAX_DIALS_PER_PEER} times, so a session that fails before the invitation opens does not strand it.\n * A retired peer, an admitted guest or another host, is not dialed and its offers are refused.\n * When the invitation flow ends guest leaves the swarm and topology is updated once again,\n * so we can connect to the next peer.\n *\n * Guests don't initiate connections. They accept all connections because if we reject,\n * the host won't retry their offer.\n * Even if we started an invitation flow with one host we might want to try other hosts in case\n * the first one failed due to a network error, so multiple connections are accepted.\n */\nexport class InvitationTopology implements Topology {\n private _controller?: SwarmController;\n\n /**\n * Dials per peer, keyed by the client's stable network peer key; an inbound session counts once,\n * and a count is pruned once its peer leaves the swarm, so a guest that rejoins is dialed afresh.\n */\n private _dials = new ComplexMap<PublicKey, number>(PublicKey.hash);\n\n /** Dialed peers without a connection yet; a dial stays pending only while its peer is a candidate. */\n private _pending = new ComplexSet<PublicKey>(PublicKey.hash);\n\n constructor(private readonly _role: InvitationOptions_Role) {}\n\n init(controller: SwarmController): void {\n invariant(!this._controller, 'Already initialized.');\n this._controller = controller;\n }\n\n update(): void {\n invariant(this._controller, 'Not initialized.');\n const { ownPeerId, candidates, connected, allPeers } = this._controller.getState();\n\n // guests don't initiate connections\n if (this._role === InvitationOptions_Role.GUEST) {\n return;\n }\n\n // A candidate has no connection and is still in the swarm, so a peer that stopped being one ends its pending dial.\n this._pending = new ComplexSet<PublicKey>(\n PublicKey.hash,\n candidates.filter((peerId) => this._pending.has(peerId)),\n );\n\n // don't start a connection while we have an active invitation flow\n if (connected.length > 0) {\n // Record a connection another host initiated with us, without counting one we already dialed again.\n connected.forEach((peerId) => {\n if (!this._dials.has(peerId)) {\n this._dials.set(peerId, 1);\n }\n });\n return;\n }\n\n // Cleanup.\n this._dials = new ComplexMap<PublicKey, number>(\n PublicKey.hash,\n allPeers.flatMap((peerId): [PublicKey, number][] => {\n const count = this._dials.get(peerId);\n return count === undefined ? [] : [[peerId, count]];\n }),\n );\n\n // A pending dial already holds the one invitation flow.\n if (this._pending.size > 0) {\n return;\n }\n\n const nextPeer = candidates.find((peerId) => (this._dials.get(peerId) ?? 0) < MAX_DIALS_PER_PEER);\n if (nextPeer != null) {\n const dials = (this._dials.get(nextPeer) ?? 0) + 1;\n log('invitation connect', { ownPeerId, remotePeerId: nextPeer, dials });\n this._dials.set(nextPeer, dials);\n this._pending.add(nextPeer);\n this._controller.connect(nextPeer);\n }\n }\n\n async onOffer(peer: PublicKey): Promise<boolean> {\n invariant(this._controller, 'Not initialized.');\n const accept = (this._dials.get(peer) ?? 0) < MAX_DIALS_PER_PEER;\n if (!accept) {\n // the peer's offer displaced any dial of ours to it, which now never opens\n this._pending.delete(peer);\n }\n return accept;\n }\n\n /** Stops dialing a peer and refuses its offers while it stays in the swarm. */\n retire(peer: PublicKey): void {\n this._dials.set(peer, MAX_DIALS_PER_PEER);\n }\n\n async destroy(): Promise<void> {\n this._dials.clear();\n this._pending.clear();\n }\n\n toString(): string {\n return `InvitationTopology(${this._role === InvitationOptions_Role.GUEST ? 'guest' : 'host'})`;\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { type PushStream, TimeoutError, type Trigger, scheduleTask } from '@dxos/async';\nimport {\n ClientTraceEvents,\n INVITATION_TIMEOUT,\n getExpirationTime,\n invitationEventAttributes,\n} from '@dxos/client-protocol';\nimport { type Context, ContextDisposedError } from '@dxos/context';\nimport { createKeyPair, sign } from '@dxos/crypto';\nimport { type EdgeHttpClient, EdgeHttpClientService } from '@dxos/edge-client';\nimport * as SpanAttributes from '@dxos/effect/SpanAttributes';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n type SwarmConnection,\n type SwarmNetworkManager,\n SwarmNetworkManagerService,\n createTeleportProtocolFactory,\n} from '@dxos/network-manager';\nimport { InvalidInvitationError, InvalidInvitationExtensionRoleError } from '@dxos/protocols';\nimport { buf, fromPublicKey, requirePublicKey, toPublicKey } from '@dxos/protocols/buf';\nimport {\n type AdmissionKeypair,\n AdmissionKeypairSchema,\n Invitation,\n Invitation_AuthMethod,\n Invitation_Kind,\n Invitation_State,\n Invitation_Type,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n AuthenticationRequestSchema,\n AuthenticationResponse_Status,\n type IntroductionResponse,\n InvitationOptions_Role,\n} from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type ExtensionContext, type TeleportExtension, type TeleportProps } from '@dxos/teleport';\nimport { trace as _trace } from '@dxos/tracing';\nimport { ComplexSet } from '@dxos/util';\n\nimport { type InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport { type EdgeInvitationConfig, EdgeInvitationHandler } from './edge-invitation-handler.ts';\nimport { InvitationGuestExtension } from './invitation-guest-extenstion.ts';\nimport { InvitationHostExtension, MAX_OTP_ATTEMPTS, isAuthenticationRequired } from './invitation-host-extension.ts';\nimport { createGuardedInvitationState, getInvitationOutcome } from './invitation-state.ts';\nimport { InvitationTopology } from './invitation-topology.ts';\n\nconst metrics = _trace.metrics;\n\nconst MAX_DELEGATED_INVITATION_HOST_TRIES = 3;\n\nexport type InvitationConnectionProps = {\n teleport: Partial<TeleportProps>;\n edgeInvitations?: EdgeInvitationConfig;\n};\n\n/**\n * Generic handler for Halo and Space invitations.\n * Handles the life-cycle of invitations between peers.\n *\n * Host\n * - Creates an invitation containing a swarm topic (which can be shared via a URL, QR code, or direct message).\n * - Joins the swarm with the topic and waits for guest's introduction.\n * - Wait for guest to authenticate with challenge specified in the invitation.\n * - Waits for guest to present credentials (containing local device and feed keys).\n * - Writes credentials to control feed then exits or waits for more guests (multi use invitations).\n *\n * Guest\n * - Joins the swarm with the topic.\n * - Sends an introduction.\n * - Submits the challenge.\n * - If Space handler then creates a local cloned space (with genesis block).\n * - Sends admission credentials.\n * ```\n * [Guest] [Host]\n * |------------------------------------Introduce-->|\n * |-------------------------------[Authenticate]-->|\n * |----------------------------------------Admit-->|\n * ```\n *\n * TODO: consider refactoring using xstate making the logic separation more explicit:\n * TODO: the flow logic should either be contained in invitations-handler or in extensions, not be split across\n * TODO: potentially re-evaluate host-side API to allow multiple concurrent connection, so that mutex can be removed\n */\n/**\n * Effect service tag for {@link InvitationsHandler}.\n */\nexport class InvitationsHandlerService extends EffectContext.Service<InvitationsHandlerService, InvitationsHandler>()(\n '@dxos/client-services/InvitationsHandler',\n) {}\n\nexport class InvitationsHandler {\n /**\n * @internal\n */\n constructor(\n private readonly _networkManager: SwarmNetworkManager,\n private readonly _edgeClient?: EdgeHttpClient,\n private readonly _connectionProps?: InvitationConnectionProps,\n ) {}\n\n handleInvitationFlow(\n ctx: Context,\n stream: PushStream<Invitation>,\n protocol: InvitationProtocol,\n invitation: Invitation,\n ): void {\n log.verbose('dxos.sdk.invitations-handler.handleInvitationFlow', {\n state: invitation.state,\n invitationId: invitation.invitationId,\n kind: invitation.kind,\n type: invitation.type,\n });\n metrics.increment('dxos.invitation.host', 1, { tags: { role: 'host', method: 'swarm' } });\n\n const hostSpanId = `invitation-host-${invitation.invitationId}`;\n // Reassign ctx to the child context so downstream `@trace.span` calls stay in the same trace.\n // Link child -> parent disposal so `ctx.dispose()` inside this flow still completes the\n // invitation stream (the caller's ctx owns `stream.complete()` via onDispose).\n // Do NOT await `invitationCtx.dispose()` here: `derive()` registers a parent -> child\n // dispose hook, so awaiting the parent dispose would re-enter the still-pending child\n // dispose promise and deadlock.\n const invitationCtx = ctx;\n ctx =\n _trace.spanStart({\n id: hostSpanId,\n instance: this,\n methodName: 'handleInvitationFlow',\n parentCtx: ctx,\n op: 'invitation.host',\n attributes: {\n 'ctx.dxos.invitation.id': invitation.invitationId,\n 'ctx.dxos.invitation.kind': Invitation_Kind[invitation.kind],\n // Invitations are rare and counted one by one, so a 30% sample would hide most of them.\n [SpanAttributes.SAMPLING.keep]: true,\n },\n }) ?? ctx;\n if (ctx !== invitationCtx) {\n ctx.onDispose(() => {\n void invitationCtx.dispose();\n });\n }\n const guardedState = createGuardedInvitationState(ctx, invitation, stream);\n ctx.onDispose(() =>\n _trace.spanEnd(hostSpanId, { attributes: { outcome: getInvitationOutcome(guardedState.current.state) } }),\n );\n const topology = new InvitationTopology(InvitationOptions_Role.HOST);\n // Called for every connecting peer.\n const createExtension = (remotePeerId: PublicKey): InvitationHostExtension => {\n const extension = new InvitationHostExtension(guardedState.mutex, {\n get activeInvitation() {\n return ctx.disposed ? null : guardedState.current;\n },\n\n onStateUpdate: (newState: Invitation_State): Invitation => {\n if (newState !== Invitation_State.ERROR && newState !== Invitation_State.TIMEOUT) {\n guardedState.set(extension, newState);\n }\n return guardedState.current;\n },\n\n admit: async (admissionRequest) => {\n try {\n log.verbose('dxos.sdk.invitations-handler.host.admit', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n });\n const deviceKey = admissionRequest.kind.value?.deviceKey;\n invariant(deviceKey, 'Admission request carries no device key.');\n const admissionResponse = await protocol.admit(invitation, admissionRequest, extension.guestProfile);\n\n // Updating credentials complete.\n extension.completedTrigger.wake(requirePublicKey(deviceKey));\n\n return admissionResponse;\n } catch (err: any) {\n // TODO(burdon): Generic RPC callback to report error to client.\n guardedState.error(extension, err);\n throw err; // Propagate error to guest.\n }\n },\n\n onOpen: (connectionCtx: Context, extensionsCtx: ExtensionContext) => {\n let admitted = false;\n connectionCtx.onDispose(() => {\n if (!admitted) {\n guardedState.set(extension, Invitation_State.CONNECTING);\n }\n });\n\n scheduleTask(connectionCtx, async () => {\n try {\n log('opening host invitation handler');\n log.verbose('connected', { ...protocol.toJSON() });\n const deviceKey = await extension.completedTrigger.wait({ timeout: invitation.timeout });\n log.verbose('admitted guest', { guest: deviceKey, ...protocol.toJSON() });\n guardedState.set(extension, Invitation_State.SUCCESS);\n metrics.increment('dxos.invitation.success', 1, { tags: { role: 'host', method: 'swarm' } });\n _trace.events.emit(ClientTraceEvents.invitationAdmit, invitationEventAttributes(guardedState.current));\n log('host invitation handler opened');\n admitted = true;\n topology.retire(remotePeerId);\n\n if (!invitation.multiUse) {\n await ctx.dispose();\n }\n } catch (err: any) {\n const stateChanged = guardedState.set(extension, Invitation_State.CONNECTING);\n if (err instanceof TimeoutError) {\n if (stateChanged) {\n metrics.increment('dxos.invitation.timeout', 1, { tags: { role: 'host', method: 'swarm' } });\n log.verbose('timeout', { ...protocol.toJSON() });\n }\n } else {\n if (stateChanged) {\n metrics.increment('dxos.invitation.failed', 1, { tags: { role: 'host', method: 'swarm' } });\n log.error('failed', err);\n }\n }\n // Close connection\n extensionsCtx.close(err);\n }\n });\n },\n onError: (err) => {\n const stateChanged = guardedState.set(extension, Invitation_State.CONNECTING);\n if (err instanceof InvalidInvitationExtensionRoleError) {\n log('invalid role', { ...err.context });\n topology.retire(remotePeerId);\n return;\n }\n if (err instanceof TimeoutError) {\n if (stateChanged) {\n metrics.increment('dxos.invitation.timeout', 1, { tags: { role: 'host', method: 'swarm' } });\n log.verbose('timeout', { err });\n }\n } else {\n if (stateChanged) {\n metrics.increment('dxos.invitation.failed', 1, { tags: { role: 'host', method: 'swarm' } });\n log.error('failed', err);\n }\n }\n },\n });\n\n return extension;\n };\n\n const expiresOn = getExpirationTime(invitation);\n if (expiresOn) {\n if (expiresOn.getTime() < Date.now()) {\n log.warn('invitation has already expired');\n guardedState.set(null, Invitation_State.EXPIRED);\n void ctx.dispose().catch((err) => log.catch(err));\n return;\n }\n scheduleTask(\n ctx,\n async () => {\n // ensure the swarm is closed before changing state and closing the stream.\n await swarmConnection.close(ctx);\n guardedState.set(null, Invitation_State.EXPIRED);\n metrics.increment('dxos.invitation.expired', 1, { tags: { role: 'host', method: 'swarm' } });\n await ctx.dispose();\n },\n expiresOn.getTime() - Date.now(),\n );\n }\n\n let swarmConnection: SwarmConnection;\n scheduleTask(ctx, async () => {\n swarmConnection = await this._joinSwarm(ctx, invitation, InvitationOptions_Role.HOST, topology, createExtension);\n guardedState.set(null, Invitation_State.CONNECTING);\n });\n }\n\n acceptInvitation(\n ctx: Context,\n stream: PushStream<Invitation>,\n protocol: InvitationProtocol,\n invitation: Invitation,\n otpEnteredTrigger: Trigger<string>,\n deviceProfile?: DeviceProfileDocument,\n ): void {\n log.verbose('dxos.sdk.invitations-handler.acceptInvitation', {\n state: invitation.state,\n invitationId: invitation.invitationId,\n kind: invitation.kind,\n type: invitation.type,\n });\n const { timeout = INVITATION_TIMEOUT } = invitation;\n\n // The PostHog dashboard \"EDGE replication latency\" (https://eu.posthog.com/project/126171/dashboard/973334)\n // queries this span's name and attributes: update it when changing them.\n const guestSpanId = `invitation-guest-${invitation.invitationId}`;\n // Reassign ctx to the child context returned by spanStart so downstream calls\n // (`edgeInvitationHandler.handle`, `_joinSwarm`, etc.) inherit this span as their\n // parent rather than starting a new root trace.\n // Link child -> parent disposal so `ctx.dispose()` inside this flow still completes the\n // invitation stream. See note in `handleInvitationFlow`: must not await the parent\n // dispose here (`derive()` registers a parent -> child dispose hook, so awaiting would\n // re-enter the still-pending child dispose promise and deadlock).\n const invitationCtx = ctx;\n ctx =\n _trace.spanStart({\n id: guestSpanId,\n instance: this,\n methodName: 'acceptInvitation',\n parentCtx: ctx,\n op: 'invitation.guest',\n attributes: {\n 'ctx.dxos.invitation.id': invitation.invitationId,\n 'ctx.dxos.invitation.kind': Invitation_Kind[invitation.kind],\n 'ctx.dxos.invitation.type': Invitation_Type[invitation.type],\n ...(invitation.spaceId ? { 'ctx.spaceId': invitation.spaceId } : {}),\n [SpanAttributes.SAMPLING.keep]: true,\n },\n }) ?? ctx;\n if (ctx !== invitationCtx) {\n ctx.onDispose(() => {\n void invitationCtx.dispose();\n });\n }\n\n if (deviceProfile) {\n invariant(invitation.kind === Invitation_Kind.DEVICE, 'deviceProfile provided for non-device invitation');\n }\n\n const triedPeersIds = new ComplexSet(PublicKey.hash);\n const guardedState = createGuardedInvitationState(ctx, invitation, stream);\n // A delegated invitation races EDGE against member devices, so its type cannot say which one admitted the guest.\n let admittedBy: 'edge' | 'peer' | undefined;\n ctx.onDispose(() =>\n _trace.spanEnd(guestSpanId, {\n attributes: {\n outcome: getInvitationOutcome(guardedState.current.state),\n ...(admittedBy ? { 'dxos.invitation.admittedBy': admittedBy } : {}),\n },\n }),\n );\n\n const shouldCancelInvitationFlow = (extension: InvitationGuestExtension) => {\n const isLockedByAnotherConnection = guardedState.mutex.isLocked() && !extension.hasFlowLock();\n log('should cancel invitation flow', {\n isLockedByAnotherConnection,\n invitationType: Invitation_Type.DELEGATED,\n triedPeers: triedPeersIds.size,\n });\n if (isLockedByAnotherConnection) {\n return false;\n }\n // A delegated invitation may be retried against other hosts, so it is disposed only on timeout\n // or once the retry budget is spent.\n return invitation.type !== Invitation_Type.DELEGATED || triedPeersIds.size >= MAX_DELEGATED_INVITATION_HOST_TRIES;\n };\n\n let admitted = false;\n const createExtension = (): InvitationGuestExtension => {\n const extension = new InvitationGuestExtension(guardedState.mutex, {\n onStateUpdate: (newState: Invitation_State) => {\n guardedState.set(extension, newState);\n },\n onOpen: (connectionCtx: Context, extensionCtx: ExtensionContext) => {\n triedPeersIds.add(extensionCtx.remotePeerId);\n\n if (admitted) {\n extensionCtx.close();\n return;\n }\n\n connectionCtx.onDispose(async () => {\n log.verbose('extension disposed', { admitted, currentState: guardedState.current.state });\n if (!admitted) {\n guardedState.error(extension, new ContextDisposedError());\n if (shouldCancelInvitationFlow(extension)) {\n await ctx.dispose();\n }\n }\n });\n\n scheduleTask(connectionCtx, async () => {\n try {\n log('opening guest invitation handler');\n\n scheduleTask(\n connectionCtx,\n () => {\n guardedState.set(extension, Invitation_State.TIMEOUT);\n extensionCtx.close();\n },\n timeout,\n );\n\n log.verbose('dxos.sdk.invitations-handler.guest.connected', { ...protocol.toJSON() });\n guardedState.set(extension, Invitation_State.CONNECTED);\n\n // 1. Introduce guest to host.\n log.verbose('dxos.sdk.invitations-handler.guest.introduce', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n });\n const introductionResponse = await extension.rpc.InvitationHostService.introduce({\n invitationId: invitation.invitationId,\n ...protocol.createIntroduction(),\n });\n log.verbose('dxos.sdk.invitations-handler.guest.introduce-response', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n authMethod: introductionResponse.authMethod,\n });\n invitation.authMethod = introductionResponse.authMethod;\n\n // 2. Get authentication code.\n if (isAuthenticationRequired(invitation)) {\n switch (invitation.authMethod) {\n case Invitation_AuthMethod.SHARED_SECRET:\n await this._handleGuestOtpAuth(\n extension,\n (state) => guardedState.set(extension, state),\n otpEnteredTrigger,\n { timeout },\n );\n break;\n case Invitation_AuthMethod.KNOWN_PUBLIC_KEY:\n await this._handleGuestKpkAuth(\n extension,\n (state) => guardedState.set(extension, state),\n invitation,\n introductionResponse,\n );\n break;\n }\n }\n\n // 3. Send admission credentials to host (with local space keys).\n log.verbose('dxos.sdk.invitations-handler.guest.request-admission', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n });\n const admissionRequest = await protocol.createAdmissionRequest(deviceProfile);\n const admissionResponse = await extension.rpc.InvitationHostService.admit(admissionRequest);\n\n // Remote connection no longer needed.\n admitted = true;\n\n // 4. Record credential in our HALO.\n const result = await protocol.accept(ctx, admissionResponse, admissionRequest);\n\n // 5. Success.\n log.verbose('dxos.sdk.invitations-handler.guest.admitted-by-host', {\n invitationId: invitation.invitationId,\n ...protocol.toJSON(),\n });\n metrics.increment('dxos.invitation.success', 1, { tags: { role: 'guest', method: 'swarm' } });\n const firstAdmission = admittedBy === undefined;\n admittedBy = 'peer';\n guardedState.complete({\n ...guardedState.current,\n ...result,\n state: Invitation_State.SUCCESS,\n });\n if (firstAdmission) {\n _trace.events.emit(ClientTraceEvents.invitationAccept, invitationEventAttributes(guardedState.current));\n }\n log('guest invitation handler opened');\n } catch (err: any) {\n if (err instanceof TimeoutError) {\n log.verbose('timeout', { ...protocol.toJSON() });\n guardedState.set(extension, Invitation_State.TIMEOUT);\n } else {\n log.verbose('auth failed', err);\n guardedState.error(extension, err);\n }\n extensionCtx.close(err);\n }\n });\n },\n onError: (err) => {\n if (err instanceof InvalidInvitationExtensionRoleError) {\n return;\n }\n if (err instanceof TimeoutError) {\n log.verbose('timeout', { ...protocol.toJSON() });\n guardedState.set(extension, Invitation_State.TIMEOUT);\n } else {\n log.verbose('auth failed', err);\n guardedState.error(extension, err);\n }\n },\n });\n\n return extension;\n };\n\n const edgeInvitationHandler = new EdgeInvitationHandler(this._connectionProps?.edgeInvitations, this._edgeClient, {\n onInvitationSuccess: async (edgeCtx, admissionResponse, admissionRequest) => {\n const result = await protocol.accept(edgeCtx, admissionResponse, admissionRequest);\n log.info('admitted by edge', { ...protocol.toJSON() });\n metrics.increment('dxos.invitation.success', 1, { tags: { role: 'guest', method: 'edge' } });\n // A delegated invitation can also be admitted by a peer in the same run; report the join once.\n const firstAdmission = admittedBy === undefined;\n admittedBy = 'edge';\n guardedState.complete({ ...guardedState.current, ...result, state: Invitation_State.SUCCESS });\n if (firstAdmission) {\n _trace.events.emit(ClientTraceEvents.invitationAccept, invitationEventAttributes(guardedState.current));\n }\n },\n });\n edgeInvitationHandler.handle(ctx, guardedState, protocol, deviceProfile);\n\n scheduleTask(ctx, async () => {\n const error = checkInvitation(protocol, invitation);\n if (error) {\n stream.error(error);\n await ctx.dispose();\n } else {\n invariant(invitation.swarmKey);\n\n const timeoutInactive = () => {\n if (guardedState.mutex.isLocked()) {\n scheduleTask(ctx, timeoutInactive, timeout);\n } else {\n guardedState.set(null, Invitation_State.TIMEOUT);\n }\n };\n\n // Timeout if no connection is established.\n scheduleTask(ctx, timeoutInactive, timeout);\n\n await this._joinSwarm(\n ctx,\n invitation,\n InvitationOptions_Role.GUEST,\n new InvitationTopology(InvitationOptions_Role.GUEST),\n createExtension,\n );\n guardedState.set(null, Invitation_State.CONNECTING);\n }\n });\n }\n\n private async _joinSwarm(\n ctx: Context,\n invitation: Invitation,\n role: InvitationOptions_Role,\n topology: InvitationTopology,\n extensionFactory: (remotePeerId: PublicKey) => TeleportExtension,\n ): Promise<SwarmConnection> {\n let label: string;\n if (role === InvitationOptions_Role.GUEST) {\n label = 'invitation guest';\n } else if (invitation.kind === Invitation_Kind.DEVICE) {\n label = 'invitation host for device';\n } else {\n label = `invitation host for space ${toPublicKey(invitation.spaceKey)?.truncate()}`;\n }\n const swarmKey = toPublicKey(invitation.swarmKey);\n invariant(swarmKey, 'swarmKey missing in the invitation');\n const swarmConnection = await this._networkManager.joinSwarm(ctx, {\n topic: swarmKey,\n protocolProvider: createTeleportProtocolFactory(async (teleport) => {\n teleport.addExtension('dxos.halo.invitations', extensionFactory(teleport.remotePeerId));\n }, this._connectionProps?.teleport),\n topology,\n label,\n });\n ctx.onDispose(() => swarmConnection.close(ctx));\n return swarmConnection;\n }\n\n private async _handleGuestOtpAuth(\n extension: InvitationGuestExtension,\n setState: (newState: Invitation_State) => void,\n authenticated: Trigger<string>,\n options: { timeout: number },\n ): Promise<void> {\n for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {\n log('guest waiting for authentication code...');\n setState(Invitation_State.READY_FOR_AUTHENTICATION);\n const authCode = await authenticated.wait(options);\n\n log('sending authentication request');\n setState(Invitation_State.AUTHENTICATING);\n const response = await extension.rpc.InvitationHostService.authenticate(\n create(AuthenticationRequestSchema, { authCode }),\n );\n if (response.status === undefined || response.status === AuthenticationResponse_Status.OK) {\n break;\n }\n\n if (response.status === AuthenticationResponse_Status.INVALID_OTP) {\n if (attempt === MAX_OTP_ATTEMPTS) {\n throw new Error(`Maximum retry attempts: ${MAX_OTP_ATTEMPTS}`);\n } else {\n log('retrying invalid code', { attempt });\n authenticated.reset();\n }\n }\n }\n }\n\n private async _handleGuestKpkAuth(\n extension: InvitationGuestExtension,\n setState: (newState: Invitation_State) => void,\n invitation: Invitation,\n introductionResponse: IntroductionResponse,\n ): Promise<void> {\n const guestPrivateKey = invitation.guestKeypair?.privateKey?.data;\n if (guestPrivateKey == null) {\n throw new Error('keypair missing in the invitation');\n }\n if (introductionResponse.challenge == null) {\n throw new Error('challenge missing in the introduction');\n }\n log('sending authentication request');\n const signature = sign(Buffer.from(introductionResponse.challenge), Buffer.from(guestPrivateKey));\n const response = await extension.rpc.InvitationHostService.authenticate(\n create(AuthenticationRequestSchema, { signedChallenge: signature }),\n );\n if (response.status !== AuthenticationResponse_Status.OK) {\n throw new Error(`Authentication failed with code: ${response.status}`);\n }\n }\n}\n\nconst checkInvitation = (protocol: InvitationProtocol, invitation: Partial<Invitation>) => {\n const expiresOn = getExpirationTime(invitation);\n if (expiresOn && expiresOn.getTime() < Date.now()) {\n return new InvalidInvitationError({ message: 'Invitation already expired.' });\n }\n return protocol.checkInvitation(invitation);\n};\n\nexport const createAdmissionKeypair = (): AdmissionKeypair => {\n const keypair = createKeyPair();\n return buf.create(AdmissionKeypairSchema, {\n publicKey: fromPublicKey(PublicKey.from(keypair.publicKey)),\n privateKey: { data: new Uint8Array(keypair.secretKey) },\n });\n};\n\nexport type InvitationsHandlerLayerOptions = {\n connectionProps?: InvitationConnectionProps;\n};\n\n/**\n * Effect Layer constructing an {@link InvitationsHandler}.\n */\nexport const InvitationsHandlerLayer = (\n options: InvitationsHandlerLayerOptions = {},\n): Layer.Layer<InvitationsHandlerService, never, SwarmNetworkManagerService> =>\n Layer.effect(\n InvitationsHandlerService,\n Effect.gen(function* () {\n const networkManager = yield* SwarmNetworkManagerService;\n const edgeClient = yield* Effect.serviceOption(EdgeHttpClientService);\n return new InvitationsHandler(networkManager, Option.getOrUndefined(edgeClient), options.connectionProps);\n }),\n );\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { toServiceError } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Invitation } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n QueryInvitationsResponse,\n QueryInvitationsResponse_Action,\n QueryInvitationsResponse_Type,\n QueryInvitationsResponseSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { InvitationsService } from '@dxos/protocols/rpc';\nimport { trace } from '@dxos/tracing';\n\nimport * as InvitationsContract from '../../contracts/invitations.ts';\n\n/**\n * Adapts invitation service observable to client/service stream.\n */\nexport class InvitationsServiceImpl implements InvitationsService.Handlers {\n 'constructor'(private readonly _invitationsManager: InvitationsContract.Manager) {}\n\n // TODO(burdon): Guest/host label.\n 'getLoggingContext'() {\n return {\n // deviceKey: this._identityManager.identity?.deviceKey\n };\n }\n\n ['InvitationsService.createInvitation'](request: Invitation): EffectStream.Stream<Invitation, Error> {\n return EffectEx.streamFromEmitter<Invitation, Error>((emit) => {\n const ctx = Context.default();\n void this._invitationsManager\n .createInvitation(ctx, request)\n .then((invitation) => {\n trace.metrics.increment('dxos.invitation.created');\n invitation.subscribe(\n (value) => void emit.single(value),\n (err) => void emit.fail(err),\n () => void emit.end(),\n );\n })\n .catch((err) => void emit.fail(err));\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['InvitationsService.acceptInvitation'](\n request: InvitationsService.AcceptInvitationRequest,\n ): EffectStream.Stream<Invitation, Error> {\n return EffectEx.streamFromEmitter<Invitation, Error>((emit) => {\n const ctx = Context.default();\n const invitation = this._invitationsManager.acceptInvitation(ctx, { ...request });\n invitation.subscribe(\n (value) => void emit.single(value),\n (err) => void emit.fail(err),\n () => void emit.end(),\n );\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['InvitationsService.authenticate'](\n request: InvitationsService.AuthenticationRequest,\n ): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: () => this._invitationsManager.authenticate(request),\n catch: toServiceError,\n });\n }\n\n ['InvitationsService.cancelInvitation'](\n request: InvitationsService.CancelInvitationRequest,\n ): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: () => this._invitationsManager.cancelInvitation(request),\n catch: toServiceError,\n });\n }\n\n ['InvitationsService.queryInvitations'](): EffectStream.Stream<QueryInvitationsResponse, Error> {\n return EffectEx.streamFromEmitter<QueryInvitationsResponse, Error>((emit) => {\n const ctx = Context.default();\n\n // Push added invitations to the stream.\n this._invitationsManager.invitationCreated.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.ADDED,\n type: QueryInvitationsResponse_Type.CREATED,\n invitations: [invitation],\n }),\n );\n });\n\n this._invitationsManager.invitationAccepted.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.ADDED,\n type: QueryInvitationsResponse_Type.ACCEPTED,\n invitations: [invitation],\n }),\n );\n });\n\n // Push removed invitations to the stream.\n this._invitationsManager.removedCreated.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.REMOVED,\n type: QueryInvitationsResponse_Type.CREATED,\n invitations: [invitation],\n }),\n );\n });\n\n this._invitationsManager.removedAccepted.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.REMOVED,\n type: QueryInvitationsResponse_Type.ACCEPTED,\n invitations: [invitation],\n }),\n );\n });\n\n // Used only for testing.\n this._invitationsManager.saved.on(ctx, (invitation) => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.SAVED,\n type: QueryInvitationsResponse_Type.CREATED,\n invitations: [invitation],\n }),\n );\n });\n\n // Push existing invitations to the stream.\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.ADDED,\n type: QueryInvitationsResponse_Type.CREATED,\n invitations: this._invitationsManager.getCreatedInvitations(),\n existing: true,\n }),\n );\n\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.ADDED,\n type: QueryInvitationsResponse_Type.ACCEPTED,\n invitations: this._invitationsManager.getAcceptedInvitations(),\n existing: true,\n }),\n );\n\n this._invitationsManager.onPersistentInvitationsLoaded(ctx, () => {\n void emit.single(\n buf.create(QueryInvitationsResponseSchema, {\n action: QueryInvitationsResponse_Action.LOAD_COMPLETE,\n type: QueryInvitationsResponse_Type.CREATED,\n // TODO(nf): populate with invitations\n }),\n );\n });\n // TODO(nf): expired invitations?\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n}\n\nexport const InvitationsServiceLayer = Layer.effect(\n InvitationsService.Tag,\n Effect.map(\n InvitationsContract.ManagerService,\n (invitationsManager) => new InvitationsServiceImpl(invitationsManager),\n ),\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { Event, PushStream, TimeoutError, Trigger } from '@dxos/async';\nimport {\n AuthenticatingInvitation,\n AUTHENTICATION_CODE_LENGTH,\n CancellableInvitation,\n INVITATION_TIMEOUT,\n} from '@dxos/client-protocol';\nimport { Context } from '@dxos/context';\nimport { generatePasscode } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { buf, bufInit, bufWkt, fromPublicKey } from '@dxos/protocols/buf';\nimport {\n Invitation,\n Invitation_AuthMethod,\n Invitation_State,\n Invitation_Type,\n InvitationSchema,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { SpaceMember_Role } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type InvitationsService } from '@dxos/protocols/rpc';\nimport { trace } from '@dxos/tracing';\n\nimport type { InvitationProtocol } from '../../contracts/invitation-protocol.ts';\nimport * as InvitationsContract from '../../contracts/invitations.ts';\nimport * as Events from '../../Events.ts';\nimport { type IMetadataStore, IMetadataStoreService, hasInvitationExpired } from '../metadata/index.ts';\nimport { type InvitationsHandler, InvitationsHandlerService, createAdmissionKeypair } from './invitations-handler.ts';\n\n/**\n * Entry point for creating and accepting invitations, keeps track of existing invitation set and\n * emits events when the set changes.\n */\nexport class InvitationsManager {\n private readonly _createInvitations = new Map<string, CancellableInvitation>();\n private readonly _acceptInvitations = new Map<string, AuthenticatingInvitation>();\n\n public readonly invitationCreated = new Event<Invitation>();\n public readonly invitationAccepted = new Event<Invitation>();\n public readonly removedCreated = new Event<Invitation>();\n public readonly removedAccepted = new Event<Invitation>();\n public readonly saved = new Event<Invitation>();\n\n private readonly _persistentInvitationsLoadedEvent = new Event();\n private _persistentInvitationsLoaded = false;\n\n private _invitationHandlerFactory?: (\n invitation: Partial<Invitation> & Pick<Invitation, 'kind'>,\n ) => InvitationProtocol;\n\n constructor(\n private readonly _invitationsHandler: InvitationsHandler,\n private readonly _metadataStore: IMetadataStore,\n ) {}\n\n /**\n * Wires the invitation handler factory after the composing stack is fully constructed.\n */\n setInvitationHandlerFactory(\n getHandler: (invitation: Partial<Invitation> & Pick<Invitation, 'kind'>) => InvitationProtocol,\n ): void {\n this._invitationHandlerFactory = getHandler;\n }\n\n /**\n * Resolves the protocol for an invitation kind; throws until a factory has been wired.\n */\n getInvitationHandler(invitation: Partial<Invitation> & Pick<Invitation, 'kind'>): InvitationProtocol {\n invariant(this._invitationHandlerFactory, 'Invitation handler factory not set.');\n return this._invitationHandlerFactory(invitation);\n }\n\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async createInvitation(\n ctx: Context,\n options: Partial<Invitation> & Pick<Invitation, 'kind'>,\n ): Promise<CancellableInvitation> {\n if (options.invitationId) {\n const existingInvitation = this._createInvitations.get(options.invitationId);\n if (existingInvitation) {\n return existingInvitation;\n }\n }\n\n const handler = this.getInvitationHandler(options);\n const invitationError = handler.checkCanInviteNewMembers();\n if (invitationError != null) {\n throw invitationError;\n }\n const invitation = this._createInvitation(handler, options);\n\n const {\n ctx: invitationCtx,\n stream,\n observableInvitation,\n } = this._createObservableInvitation(ctx, handler, invitation);\n\n this._createInvitations.set(invitation.invitationId, observableInvitation);\n this.invitationCreated.emit(invitation);\n // onComplete is called on cancel, expiration, or redemption of a single-use invitation\n this._onInvitationComplete(observableInvitation, async () => {\n this._createInvitations.delete(observableInvitation.get().invitationId);\n this.removedCreated.emit(observableInvitation.get());\n if (observableInvitation.get().persistent) {\n await this._safeDeleteInvitation(observableInvitation.get());\n }\n });\n\n try {\n await this._persistIfRequired(handler, stream, invitation);\n } catch (err) {\n log.catch(err);\n await observableInvitation.cancel();\n return observableInvitation;\n }\n\n this._invitationsHandler.handleInvitationFlow(invitationCtx, stream, handler, observableInvitation.get());\n\n return observableInvitation;\n }\n\n async loadPersistentInvitations(ctx: Context): Promise<{ invitations: Invitation[] }> {\n if (this._persistentInvitationsLoaded) {\n const invitations = this.getCreatedInvitations().filter((i) => i.persistent);\n return { invitations };\n }\n try {\n const persistentInvitations = this._metadataStore.getInvitations();\n // get saved persistent invitations, filter and remove from storage those that have expired.\n const freshInvitations = persistentInvitations.filter((invitation) => !hasInvitationExpired(invitation));\n\n const loadTasks = freshInvitations.map((persistentInvitation) => {\n invariant(!this._createInvitations.get(persistentInvitation.invitationId), 'invitation already exists');\n return this.createInvitation(ctx, { ...persistentInvitation, persistent: false });\n });\n const cInvitations = await Promise.all(loadTasks);\n\n return { invitations: cInvitations.map((invitation) => invitation.get()) };\n } catch (err) {\n log.catch(err);\n return { invitations: [] };\n } finally {\n this._persistentInvitationsLoadedEvent.emit();\n this._persistentInvitationsLoaded = true;\n }\n }\n\n /**\n * The profile is the shape the device credential is signed over, not the wire shape the\n * service receives — {@link InvitationsServiceImpl} converts before calling this.\n */\n acceptInvitation(\n ctx: Context,\n request: {\n invitation: InvitationsService.AcceptInvitationRequest['invitation'];\n deviceProfile?: DeviceProfileDocument;\n },\n ): AuthenticatingInvitation {\n const options = request.invitation;\n const existingInvitation = this._acceptInvitations.get(options.invitationId);\n if (existingInvitation) {\n return existingInvitation;\n }\n\n const handler = this.getInvitationHandler(options);\n const {\n ctx: invitationCtx,\n invitation,\n stream,\n otpEnteredTrigger,\n } = this._createObservableAcceptingInvitation(ctx, handler, options);\n this._invitationsHandler.acceptInvitation(\n invitationCtx,\n stream,\n handler,\n options,\n otpEnteredTrigger,\n request.deviceProfile,\n );\n this._acceptInvitations.set(invitation.get().invitationId, invitation);\n this.invitationAccepted.emit(invitation.get());\n\n this._onInvitationComplete(invitation, () => {\n this._acceptInvitations.delete(invitation.get().invitationId);\n this.removedAccepted.emit(invitation.get());\n });\n\n return invitation;\n }\n\n async authenticate({ invitationId, authCode }: InvitationsService.AuthenticationRequest): Promise<void> {\n log('authenticating...');\n invariant(invitationId);\n const observable = this._acceptInvitations.get(invitationId);\n if (!observable) {\n log.warn('invalid invitation', { invitationId });\n } else {\n await observable.authenticate(authCode);\n }\n }\n\n async cancelInvitation({ invitationId }: { invitationId: string }): Promise<void> {\n log('cancelInvitation...', { invitationId });\n invariant(invitationId);\n const created = this._createInvitations.get(invitationId);\n if (created) {\n // remove from storage before modifying in-memory state, higher chance of failing\n if (created.get().persistent) {\n await this._metadataStore.removeInvitation(invitationId);\n }\n if (created.get().type === Invitation_Type.DELEGATED) {\n const handler = this.getInvitationHandler(created.get());\n await handler.cancelDelegation(created.get());\n }\n await created.cancel();\n this._createInvitations.delete(invitationId);\n this.removedCreated.emit(created.get());\n return;\n }\n\n const accepted = this._acceptInvitations.get(invitationId);\n if (accepted) {\n await accepted.cancel();\n this._acceptInvitations.delete(invitationId);\n this.removedAccepted.emit(accepted.get());\n }\n }\n\n getCreatedInvitations(): Invitation[] {\n return [...this._createInvitations.values()].map((i) => i.get());\n }\n\n getAcceptedInvitations(): Invitation[] {\n return [...this._acceptInvitations.values()].map((i) => i.get());\n }\n\n onPersistentInvitationsLoaded(ctx: Context, callback: () => void): void {\n if (this._persistentInvitationsLoaded) {\n callback();\n } else {\n this._persistentInvitationsLoadedEvent.once(ctx, () => callback());\n }\n }\n\n private _createInvitation(protocol: InvitationProtocol, _options?: Partial<Invitation>): Invitation {\n const {\n invitationId = PublicKey.random().toHex(),\n type = Invitation_Type.INTERACTIVE,\n authMethod = Invitation_AuthMethod.SHARED_SECRET,\n state = Invitation_State.INIT,\n timeout = INVITATION_TIMEOUT,\n swarmKey = fromPublicKey(PublicKey.random()),\n persistent = _options?.authMethod !== Invitation_AuthMethod.KNOWN_PUBLIC_KEY,\n created = bufWkt.timestampNow(),\n guestKeypair = undefined,\n role = SpaceMember_Role.ADMIN,\n lifetime = 86400 * 7, // 7 days.\n multiUse = false,\n ...options\n } = _options ?? {};\n const authCode =\n options?.authCode ??\n (authMethod === Invitation_AuthMethod.SHARED_SECRET ? generatePasscode(AUTHENTICATION_CODE_LENGTH) : undefined);\n\n return buf.create(InvitationSchema, {\n invitationId,\n type,\n authMethod,\n state,\n swarmKey,\n authCode,\n timeout,\n persistent: persistent && type !== Invitation_Type.DELEGATED, // Delegated invitations are persisted in the control feed.\n guestKeypair:\n guestKeypair ?? (authMethod === Invitation_AuthMethod.KNOWN_PUBLIC_KEY ? createAdmissionKeypair() : undefined),\n created,\n lifetime,\n role,\n multiUse,\n delegationCredentialId: options?.delegationCredentialId,\n ...bufInit(options),\n ...bufInit(protocol.getInvitationContext()),\n });\n }\n\n private _createObservableInvitation(\n ctx: Context,\n handler: InvitationProtocol,\n invitation: Invitation,\n ): { ctx: Context; stream: PushStream<Invitation>; observableInvitation: CancellableInvitation } {\n const stream = new PushStream<Invitation>();\n const invitationCtx = ctx.derive({\n onError: (err) => {\n stream.error(err);\n void invitationCtx.dispose();\n },\n });\n invitationCtx.onDispose(() => {\n log('complete', { ...handler.toJSON() });\n stream.complete();\n });\n const observableInvitation = new CancellableInvitation({\n initialInvitation: invitation,\n subscriber: stream.observable,\n onCancel: async () => {\n stream.next({ ...invitation, state: Invitation_State.CANCELLED });\n await invitationCtx.dispose();\n },\n });\n return { ctx: invitationCtx, stream, observableInvitation };\n }\n\n private _createObservableAcceptingInvitation(\n parentCtx: Context,\n handler: InvitationProtocol,\n initialState: Invitation,\n ): {\n ctx: Context;\n invitation: AuthenticatingInvitation;\n stream: PushStream<Invitation>;\n otpEnteredTrigger: Trigger<string>;\n } {\n const otpEnteredTrigger = new Trigger<string>();\n const stream = new PushStream<Invitation>();\n // Derive from caller ctx so `TRACE_SPAN_ATTRIBUTE` propagates via the parent chain.\n const ctx = parentCtx.derive({\n onError: (err) => {\n if (err instanceof TimeoutError) {\n log('timeout', { ...handler.toJSON() });\n stream.next({ ...initialState, state: Invitation_State.TIMEOUT });\n } else {\n log.warn('auth failed', err);\n stream.next({ ...initialState, state: Invitation_State.ERROR });\n }\n void ctx.dispose();\n },\n });\n ctx.onDispose(() => {\n log('complete', { ...handler.toJSON() });\n stream.complete();\n });\n const invitation = new AuthenticatingInvitation({\n initialInvitation: initialState,\n subscriber: stream.observable,\n onCancel: async () => {\n stream.next({ ...initialState, state: Invitation_State.CANCELLED });\n await ctx.dispose();\n },\n onAuthenticate: async (code: string) => {\n // TODO(burdon): Reset creates a race condition? Event?\n otpEnteredTrigger.wake(code);\n },\n });\n return { ctx, invitation, stream, otpEnteredTrigger };\n }\n\n private async _persistIfRequired(\n handler: InvitationProtocol,\n changeStream: PushStream<Invitation>,\n invitation: Invitation,\n ): Promise<void> {\n if (invitation.type === Invitation_Type.DELEGATED && invitation.delegationCredentialId == null) {\n const delegationCredentialId = await handler.delegate(invitation);\n changeStream.next({ ...invitation, delegationCredentialId: fromPublicKey(delegationCredentialId) });\n } else if (invitation.persistent) {\n await this._metadataStore.addInvitation(invitation);\n this.saved.emit(invitation);\n }\n }\n\n private async _safeDeleteInvitation(invitation: Invitation): Promise<void> {\n try {\n await this._metadataStore.removeInvitation(invitation.invitationId);\n } catch (err) {\n log.catch(err);\n }\n }\n\n private _onInvitationComplete(invitation: CancellableInvitation, callback: () => void): void {\n invitation.subscribe(\n () => {},\n () => {},\n callback,\n );\n }\n}\n\n/**\n * Effect Layer constructing an {@link InvitationsManager}.\n *\n * The invitation handler factory points \"up the stack\" and is wired via\n * {@link InvitationsManager.setInvitationHandlerFactory} after composition.\n */\nexport const InvitationsManagerLayer = (): Layer.Layer<\n InvitationsContract.ManagerService,\n never,\n Hook.Controller | InvitationsHandlerService | IMetadataStoreService\n> =>\n Layer.effect(\n InvitationsContract.ManagerService,\n Effect.gen(function* () {\n const invitationsHandler = yield* InvitationsHandlerService;\n const metadataStore = yield* IMetadataStoreService;\n const invitationsManager = new InvitationsManager(invitationsHandler, metadataStore);\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Hook.on(\n Events.StackOpened,\n Effect.fn('InvitationsManager.onStackOpened')(function* () {\n const loaded = yield* Effect.promise(() => invitationsManager.loadPersistentInvitations(ctx));\n log('loaded persistent invitations', { count: loaded.invitations.length });\n }),\n );\n return invitationsManager;\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\n\nimport { type TransportFactory } from '@dxos/network-manager';\n\n/**\n * Effect service tag for the swarm {@link TransportFactory}.\n */\nexport class TransportFactoryService extends EffectContext.Service<TransportFactoryService, TransportFactory>()(\n '@dxos/client-services/TransportFactory',\n) {}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as EffectStream from 'effect/Stream';\n\nimport { SubscriptionList } from '@dxos/async';\nimport { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { invariant } from '@dxos/invariant';\nimport { toServiceError } from '@dxos/protocols';\nimport { buf, fromPublicKey } from '@dxos/protocols/buf';\nimport {\n type Device,\n Device_PresenceState,\n DeviceKind,\n DeviceSchema,\n EdgeStatus_ConnectionState,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type DeviceProfileDocument } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { DevicesService } from '@dxos/protocols/rpc';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\n\nexport class DevicesServiceImpl implements DevicesService.Handlers {\n 'constructor'(\n private readonly _identityManager: IdentityContract.Manager,\n private readonly _edgeConnection?: EdgeConnection,\n ) {}\n\n ['DevicesService.updateDevice'](request: DeviceProfileDocument): Effect.Effect<Device, BaseError> {\n return Effect.tryPromise({\n try: async () => await this._identityManager.updateDeviceProfile(request),\n catch: toServiceError,\n });\n }\n\n ['DevicesService.queryDevices'](): EffectStream.Stream<DevicesService.QueryDevicesResponse, Error> {\n return EffectEx.streamFromEmitter<DevicesService.QueryDevicesResponse, Error>((emit) => {\n const update = () => {\n const deviceKeys = this._identityManager.identity?.authorizedDeviceKeys;\n if (!deviceKeys) {\n void emit.single({ devices: [] });\n } else {\n invariant(this._identityManager.identity?.presence, 'presence not present');\n const identityPresence = this._identityManager.identity.presence;\n void emit.single({\n devices: Array.from(deviceKeys.entries()).map(([key, profile]) => {\n const isMe = this._identityManager.identity?.deviceKey.equals(key);\n let presence;\n if (isMe) {\n presence = Device_PresenceState.ONLINE;\n } else if (profile.os?.toUpperCase() === 'EDGE') {\n presence =\n this._edgeConnection?.status.state === EdgeStatus_ConnectionState.CONNECTED\n ? Device_PresenceState.ONLINE\n : Device_PresenceState.OFFLINE;\n } else {\n presence =\n identityPresence.getPeersByIdentityKey(key).length > 0\n ? Device_PresenceState.ONLINE\n : Device_PresenceState.OFFLINE;\n }\n\n return buf.create(DeviceSchema, {\n deviceKey: fromPublicKey(key),\n kind: this._identityManager.identity?.deviceKey.equals(key) ? DeviceKind.CURRENT : DeviceKind.TRUSTED,\n profile: profile,\n presence,\n });\n }),\n });\n }\n };\n\n let identitySubscribed = false;\n let presenceSubscribed = false;\n const subscribeIdentity = () => {\n if (!identitySubscribed) {\n this._identityManager.identity?.stateUpdate.on(() => {\n update();\n });\n identitySubscribed = true;\n }\n };\n\n const subscribePresence = () => {\n if (!presenceSubscribed) {\n this._identityManager.identity?.presence?.updated.on(() => {\n update();\n });\n presenceSubscribed = true;\n }\n };\n\n const subscriptions = new SubscriptionList();\n\n if (this._identityManager.identity) {\n subscribeIdentity();\n subscribePresence();\n }\n\n subscriptions.add(\n this._identityManager.stateUpdate.on(() => {\n update();\n\n if (this._identityManager.identity) {\n subscribeIdentity();\n subscribePresence();\n }\n }),\n );\n\n update();\n\n return Effect.sync(() => subscriptions.clear());\n });\n }\n}\n\nexport const DevicesServiceLayer = Layer.effect(\n DevicesService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n // Edge connection is absent in the non-edge stack, so resolve it optionally.\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n return new DevicesServiceImpl(identityManager, edgeConnection);\n }),\n);\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport { timestampFromDate } from '@bufbuild/protobuf/wkt';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { PublicKey } from '@dxos/keys';\nimport { type LogLevel, type LogProcessor, type LogEntry as NaturalLogEntry, log } from '@dxos/log';\nimport {\n type LogEntry,\n LogEntrySchema,\n type QueryLogsRequest,\n type QueryLogsRequest_Filter,\n QueryLogsRequest_MatchingOptions,\n} from '@dxos/protocols/buf/dxos/client/logging_pb';\nimport { LoggingService } from '@dxos/protocols/rpc';\nimport { numericalValues, tracer } from '@dxos/util';\n\n/**\n * Logging service used to spy on logs of the host.\n *\n * @deprecated This was created so that logs from the shared worker (WorkerClientServices) could be\n * seen in the main window console without opening the shared worker DevTools. Shared worker client\n * services is deprecated; dedicated worker logs already show in the main window console.\n */\nexport class LoggingServiceImpl implements LoggingService.Handlers {\n private readonly '_logs' = new Event<NaturalLogEntry>();\n private readonly '_started' = Date.now();\n private readonly '_sessionId' = PublicKey.random().toHex();\n\n async 'open'(): Promise<void> {\n log.runtimeConfig.processors.push(this._logProcessor);\n }\n\n async 'close'(): Promise<void> {\n const index = log.runtimeConfig.processors.findIndex((processor: LogProcessor) => processor === this._logProcessor);\n log.runtimeConfig.processors.splice(index, 1);\n }\n\n ['LoggingService.controlMetrics']({\n reset,\n record,\n }: LoggingService.ControlMetricsRequest): Effect.Effect<LoggingService.ControlMetricsResponse, Error> {\n return Effect.sync(() => {\n if (reset) {\n tracer.clear();\n }\n\n if (record === true) {\n tracer.start();\n } else if (record === false) {\n tracer.stop();\n }\n\n return { recording: tracer.recording };\n });\n }\n\n /**\n * @deprecated (Move to diagnostics).\n */\n ['LoggingService.queryMetrics']({\n interval = 5_000,\n }: LoggingService.QueryMetricsRequest): EffectStream.Stream<LoggingService.QueryMetricsResponse, Error> {\n // TODO(burdon): Map all traces; how to bind to reducer/metrics shape (e.g., numericalValues)?\n const getNumericalValues = (key: string) => {\n const events = tracer.get(key) ?? [];\n return { key, stats: numericalValues(events, 'duration') };\n };\n\n return EffectEx.streamFromEmitter<LoggingService.QueryMetricsResponse, Error>((emit) => {\n const update = () => {\n const metrics: LoggingService.Metrics = {\n timestamp: new Date(),\n values: [\n getNumericalValues('dxos.echo.pipeline.control'),\n getNumericalValues('dxos.echo.pipeline.data'),\n ].filter(Boolean) as LoggingService.KeyPair[],\n };\n\n void emit.single({\n timestamp: new Date(),\n metrics,\n });\n };\n\n update();\n const i = setInterval(update, Math.max(interval, 1_000));\n return Effect.sync(() => {\n clearInterval(i);\n });\n });\n }\n\n ['LoggingService.queryLogs'](request: QueryLogsRequest): EffectStream.Stream<LogEntry, Error> {\n return EffectEx.streamFromEmitter<LogEntry, Error>((emit) => {\n const ctx = Context.default();\n const handler = (entry: NaturalLogEntry) => {\n // This call was caused by the logging service itself.\n if (LOG_PROCESSING > 0) {\n return;\n }\n\n // Prevent logging feedback loop from logging service.\n if (\n entry.meta?.F.includes('logging-service') ||\n (entry.context &&\n Object.values(entry.context).some((value) => typeof value === 'string' && value.includes('LoggingService')))\n ) {\n return;\n }\n\n if (!shouldLog(entry, request)) {\n return;\n }\n\n const { filename, line, context: scopeName } = entry.computedMeta;\n const recordContext: Record<string, any> = { ...entry.computedContext };\n if (entry.computedError !== undefined) {\n recordContext.error = entry.computedError;\n }\n\n const record: LogEntry = create(LogEntrySchema, {\n level: entry.level,\n message: entry.message ?? entry.computedError ?? '',\n context: recordContext,\n timestamp: timestampFromDate(new Date(entry.timestamp)),\n meta: {\n // TODO(dmaretskyi): Fix proto.\n file: filename ?? '',\n line: line ?? 0,\n scope: {\n hostSessionId: this._sessionId,\n uptimeSeconds: (Date.now() - this._started) / 1000,\n name: scopeName ?? '',\n },\n },\n });\n\n try {\n LOG_PROCESSING++;\n void emit.single(record);\n } finally {\n LOG_PROCESSING--;\n }\n };\n\n this._logs.on(ctx, handler);\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n private '_logProcessor': LogProcessor = (_config, entry) => {\n this._logs.emit(entry);\n };\n}\n\nconst matchFilter = (\n filter: QueryLogsRequest_Filter,\n level: LogLevel,\n path: string,\n options: QueryLogsRequest_MatchingOptions,\n) => {\n switch (options) {\n case QueryLogsRequest_MatchingOptions.INCLUSIVE:\n return level >= filter.level && (!filter.pattern || path.includes(filter.pattern));\n case QueryLogsRequest_MatchingOptions.EXPLICIT:\n return level === filter.level && (!filter.pattern || path.includes(filter.pattern));\n }\n};\n\n/**\n * Determines if the current line should be logged (called by the processor).\n */\nconst shouldLog = (entry: NaturalLogEntry, request: QueryLogsRequest): boolean => {\n // buf represents an unset `repeated` as `[]` and an unset enum as its zero value, never\n // `undefined`, so absence is read off those rather than off `undefined` — the previous\n // `filters === undefined` branch is unreachable here and an empty filter list would otherwise\n // flip \"log everything\" into \"log nothing\".\n const options =\n request.options === undefined || request.options === QueryLogsRequest_MatchingOptions.NONE\n ? QueryLogsRequest_MatchingOptions.INCLUSIVE\n : request.options;\n if (request.filters.length === 0) {\n return options === QueryLogsRequest_MatchingOptions.INCLUSIVE;\n }\n return request.filters.some((filter) => matchFilter(filter, entry.level, entry.meta?.F ?? '', options));\n};\n\n/**\n * Counter that is used to track whether we are processing a log entry.\n */\nlet LOG_PROCESSING = 0;\n\n/**\n * The impl installs a log processor on open and removes it on close, so its lifecycle is bound to\n * the layer scope.\n */\nexport const LoggingServiceLayer: Layer.Layer<LoggingService.Tag> = Layer.effect(\n LoggingService.Tag,\n Effect.gen(function* () {\n const service = new LoggingServiceImpl();\n yield* Effect.acquireRelease(\n Effect.promise(() => service.open()),\n () => Effect.promise(() => service.close()),\n );\n return service;\n }),\n);\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Context } from '@dxos/context';\nimport { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { type SignalManager, SignalManagerService, type UnsubscribeCallback } from '@dxos/messaging';\nimport { type SwarmNetworkManager, SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { toServiceError } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport { type NetworkStatus, NetworkStatusSchema } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type SwarmResponse } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport {\n type JoinRequest,\n type LeaveRequest,\n type Message,\n type QueryRequest,\n} from '@dxos/protocols/buf/dxos/edge/signal_pb';\nimport { NetworkService } from '@dxos/protocols/rpc';\n\nexport class NetworkServiceImpl implements NetworkService.Handlers {\n 'constructor'(\n private readonly networkManager: SwarmNetworkManager,\n private readonly signalManager: SignalManager,\n private readonly edgeConnection?: EdgeConnection,\n ) {}\n\n ['NetworkService.queryStatus'](): EffectStream.Stream<NetworkStatus, Error> {\n return EffectEx.streamFromEmitter<NetworkStatus, Error>((emit) => {\n const ctx = Context.default();\n const update = () => {\n void emit.single(\n buf.create(NetworkStatusSchema, {\n swarm: this.networkManager.connectionState,\n connectionInfo: this.networkManager.connectionLog?.swarms ?? [],\n signaling: this.signalManager.getStatus?.().map(({ host, state }) => ({ server: host, state })),\n }),\n );\n };\n\n this.networkManager.connectionStateChanged.on(ctx, () => update());\n this.signalManager.statusChanged?.on(ctx, () => update());\n update();\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['NetworkService.updateConfig'](request: NetworkService.UpdateConfigRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n await this.networkManager.setConnectionState(request.swarm);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.joinSwarm'](request: JoinRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n await this.signalManager.join(Context.default(), request);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.leaveSwarm'](request: LeaveRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n await this.signalManager.leave(Context.default(), request);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.querySwarm'](request: QueryRequest): Effect.Effect<SwarmResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n return this.signalManager.query(Context.default(), request);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.subscribeSwarmState'](\n request: NetworkService.SubscribeSwarmStateRequest,\n ): EffectStream.Stream<SwarmResponse, Error> {\n return EffectEx.streamFromEmitter<SwarmResponse, Error>((emit) => {\n const ctx = Context.default();\n this.signalManager.swarmState?.on(ctx, (state) => {\n if (request.topic.toHex() === state.swarmKey) {\n void emit.single(state);\n }\n });\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['NetworkService.sendMessage'](message: Message): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n await this.signalManager.sendMessage(Context.default(), message);\n },\n catch: toServiceError,\n });\n }\n\n ['NetworkService.subscribeMessages'](\n request: NetworkService.SubscribeMessagesRequest,\n ): EffectStream.Stream<Message, Error> {\n const { peer, tags = [] } = request;\n return EffectEx.streamFromEmitter<Message, Error>((emit) => {\n const ctx = Context.default();\n\n // The subscription encapsulates routing (DX-1125): point-to-point messages addressed to `peer`,\n // plus — when `tags` are set — swarm broadcasts whose tags intersect. The returned callback owns\n // teardown, refcounted so it releases only this stream's tag registration.\n let unsubscribe: UnsubscribeCallback | undefined;\n void this.signalManager\n .subscribeMessages({\n peer,\n tags,\n onMessage: (message) => {\n void emit.single(message);\n },\n })\n .then((unsub) => {\n if (ctx.disposed) {\n void unsub();\n } else {\n unsubscribe = unsub;\n }\n })\n .catch((err) => emit.fail(err instanceof Error ? err : new Error(String(err))));\n\n return Effect.promise(async () => {\n await unsubscribe?.();\n await ctx.dispose();\n });\n });\n }\n}\n\nexport const NetworkServiceLayer: Layer.Layer<\n NetworkService.Tag,\n never,\n SwarmNetworkManagerService | SignalManagerService\n> = Layer.effect(\n NetworkService.Tag,\n Effect.gen(function* () {\n const networkManager = yield* SwarmNetworkManagerService;\n const signalManager = yield* SignalManagerService;\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n return new NetworkServiceImpl(networkManager, signalManager, edgeConnection);\n }),\n);\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type Context, Resource } from '@dxos/context';\nimport { type CredentialProcessor, type SpecificCredential, specificCredential } from '@dxos/credentials';\nimport { type Credential, type Epoch } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nexport class AutomergeSpaceState extends Resource implements CredentialProcessor {\n public rootUrl: string | undefined = undefined;\n public lastEpoch: SpecificCredential<Epoch> | undefined = undefined;\n\n public readonly onNewEpoch = new Event<SpecificCredential<Epoch>>();\n\n private _isProcessingRootDocs = false;\n\n constructor(private readonly _onNewRoot: (rootUrl: string) => void) {\n super();\n }\n\n protected override async _open(ctx: Context): Promise<void> {}\n\n protected override async _close(ctx: Context): Promise<void> {\n this._isProcessingRootDocs = false;\n }\n\n async processCredential(credential: Credential): Promise<void> {\n const epoch = specificCredential<Epoch>(credential, 'dxos.halo.credentials.Epoch');\n if (!epoch) {\n return;\n }\n\n this.lastEpoch = epoch;\n if (epoch.assertion.automergeRoot) {\n this.rootUrl = epoch.assertion.automergeRoot;\n\n if (this._isProcessingRootDocs) {\n this._onNewRoot(this.rootUrl);\n }\n }\n\n this.onNewEpoch.emit(epoch);\n }\n\n startProcessingRootDocs(): void {\n if (this._isProcessingRootDocs) {\n return;\n }\n\n if (this.rootUrl) {\n this._onNewRoot(this.rootUrl);\n }\n this._isProcessingRootDocs = true;\n }\n\n async ensureEpochInitialized(): Promise<void> {\n await this.onNewEpoch.waitForCondition(() => !!this.lastEpoch);\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport type { AutomergeUrl } from '@automerge/automerge-repo';\n\nimport { type Context } from '@dxos/context';\nimport { type EchoHost } from '@dxos/echo-host';\nimport { invariant } from '@dxos/invariant';\nimport type { PublicKey, SpaceId } from '@dxos/keys';\nimport { SpacesService } from '@dxos/protocols/rpc';\n\nexport type MigrationContext = {\n echoHost: EchoHost;\n\n spaceId: SpaceId;\n /**\n * @deprecated Remove.\n */\n spaceKey: PublicKey;\n migration: SpacesService.Migration;\n currentRoot: string | null;\n\n /**\n * For set automerge root migration type.\n */\n newAutomergeRoot?: string;\n};\n\nexport type MigrationResult = {\n newRoot?: string;\n};\n\nconst LOAD_DOC_TIMEOUT = 10_000;\n\nexport const runEpochMigration = async (ctx: Context, context: MigrationContext): Promise<MigrationResult> => {\n switch (context.migration) {\n case SpacesService.Migration.enums.INIT_AUTOMERGE: {\n using document = await context.echoHost.createDoc();\n await context.echoHost.flush(ctx);\n return { newRoot: document.url };\n }\n case SpacesService.Migration.enums.PRUNE_AUTOMERGE_ROOT_HISTORY: {\n if (!context.currentRoot) {\n throw new Error('Space does not have an automerge root');\n }\n using rootLease = await context.echoHost.loadDoc(ctx, context.currentRoot as AutomergeUrl, {\n timeout: LOAD_DOC_TIMEOUT,\n });\n invariant(rootLease, 'Automerge root document must load for history prune migration.');\n\n using newRoot = await context.echoHost.createDoc(rootLease.doc());\n await context.echoHost.flush(ctx);\n return { newRoot: newRoot.url };\n }\n case SpacesService.Migration.enums.FRAGMENT_AUTOMERGE_ROOT: {\n throw new Error('Migration not available');\n }\n case SpacesService.Migration.enums.MIGRATE_REFERENCES_TO_DXN: {\n throw new Error('Migration not available');\n }\n // TODO(dmaretskyi): This path doesn't seem to fit here. This is not a migration.\n case SpacesService.Migration.enums.REPLACE_AUTOMERGE_ROOT: {\n invariant(context.newAutomergeRoot);\n\n // Defensive programming - it should be the responsibility of the caller to flush the new root.\n await context.echoHost.flush(ctx);\n return {\n newRoot: context.newAutomergeRoot,\n };\n }\n }\n\n return {};\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { create, fromBinary, toBinary } from '@bufbuild/protobuf';\nimport { EmptySchema } from '@bufbuild/protobuf/wkt';\n\nimport { DeferredTask, Event, TimeoutError, Trigger, scheduleMicroTask, scheduleTask, sleep } from '@dxos/async';\nimport { type Context, Resource, rejectOnDispose } from '@dxos/context';\nimport { type CredentialProcessor, verifyCredential } from '@dxos/credentials';\nimport { type EdgeHttpClient } from '@dxos/edge-client';\nimport { type HypercoreWriter } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { type SpaceId } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { EdgeCallFailedError } from '@dxos/protocols';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport { type BufService, getBufService } from '@dxos/protocols/buf-service';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type Credential, CredentialSchema } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport {\n NotarizationService as NotarizationServiceDesc,\n type NotarizeRequest,\n NotarizeRequestSchema,\n} from '@dxos/protocols/buf/dxos/mesh/teleport/notarization_pb';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\nimport { ComplexMap, ComplexSet, entry } from '@dxos/util';\n\nconst DEFAULT_RETRY_TIMEOUT = 1_000;\n\nconst DEFAULT_SUCCESS_DELAY = 1_000;\n\nconst DEFAULT_NOTARIZE_TIMEOUT = 10_000;\n\nconst DEFAULT_ACTIVE_EDGE_POLLING_INTERVAL = 3_000;\n\nconst MAX_EDGE_RETRIES = 5;\n\nconst WRITER_NOT_SET_ERROR_CODE = 'WRITER_NOT_SET';\n\ntype NotarizationService = BufService<typeof NotarizationServiceDesc>;\n\nexport type NotarizationPluginProps = {\n spaceId: SpaceId;\n edgeClient?: EdgeHttpClient;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n activeEdgePollingInterval?: number;\n};\n\nexport type NotarizeProps = {\n /**\n * For cancellation.\n */\n ctx?: Context;\n\n /**\n * Credentials to notarize.\n */\n credentials: Credential[];\n\n /**\n * Timeout for the whole notarization process.\n * Set to 0 to disable.\n * @default {@link DEFAULT_NOTARIZE_TIMEOUT}\n */\n timeout?: number;\n\n /**\n * Retry timeout.\n * @default {@link DEFAULT_RETRY_TIMEOUT}\n */\n retryTimeout?: number;\n\n /**\n * Minimum wait time after a peer confirms successful notarization before attempting with a new peer.\n * This is to avoid spamming peers with notarization requests.\n * @default {@link DEFAULT_SUCCESS_DELAY}\n */\n successDelay?: number;\n\n /**\n * A random amount of time before making or retrying an edge request to help prevent large bursts of requests.\n */\n edgeRetryJitter?: number;\n};\n\n/**\n * See NotarizationService proto.\n */\nexport class NotarizationPlugin extends Resource implements CredentialProcessor {\n private readonly _extensionOpened = new Event();\n\n private _writer: HypercoreWriter<Credential> | undefined;\n private readonly _extensions = new Set<NotarizationTeleportExtension>();\n private readonly _processedCredentials = new ComplexSet<PublicKey>(PublicKey.hash);\n private readonly _processCredentialsTriggers = new ComplexMap<PublicKey, Trigger>(PublicKey.hash);\n\n private _activeEdgePollingIntervalHandle: any | undefined = undefined;\n private readonly _activeEdgePollingInterval: number;\n private _activeEdgePollingEnabled = false;\n\n @logInfo\n private readonly _spaceId: SpaceId;\n\n private readonly _edgeClient: EdgeHttpClient | undefined;\n\n constructor(params: NotarizationPluginProps) {\n super();\n this._spaceId = params.spaceId;\n this._activeEdgePollingInterval = params.activeEdgePollingInterval ?? DEFAULT_ACTIVE_EDGE_POLLING_INTERVAL;\n if (params.edgeClient && params.edgeFeatures?.feedReplicator) {\n this._edgeClient = params.edgeClient;\n }\n }\n\n setActiveEdgePollingEnabled(enabled: boolean): void {\n const client = this._edgeClient;\n invariant(client);\n this._activeEdgePollingEnabled = enabled;\n if (this.isOpen) {\n if (enabled && !this._activeEdgePollingIntervalHandle) {\n this._startPeriodicEdgePolling(client);\n } else if (!enabled && this._activeEdgePollingIntervalHandle) {\n this._stopPeriodicEdgePolling();\n }\n }\n }\n\n get hasWriter() {\n return !!this._writer;\n }\n\n protected override async _open(): Promise<void> {\n if (this._edgeClient) {\n if (this._activeEdgePollingEnabled) {\n this._startPeriodicEdgePolling(this._edgeClient);\n }\n if (this._writer) {\n this._notarizePendingEdgeCredentials(this._edgeClient, this._writer);\n }\n }\n }\n\n protected override async _close(): Promise<void> {\n this._stopPeriodicEdgePolling();\n await this._ctx.dispose();\n }\n\n /**\n * Request credentials to be notarized.\n */\n async notarize({\n ctx: opCtx,\n credentials,\n timeout = DEFAULT_NOTARIZE_TIMEOUT,\n retryTimeout = DEFAULT_RETRY_TIMEOUT,\n successDelay = DEFAULT_SUCCESS_DELAY,\n edgeRetryJitter,\n }: NotarizeProps): Promise<void> {\n log('notarize', { credentials });\n invariant(\n credentials.every((credential) => credential.id),\n 'Credentials must have an id',\n );\n\n const errors = new Trigger();\n const ctx = this._ctx.derive({\n onError: (err) => {\n log.warn('Notarization error', { err });\n void ctx.dispose();\n errors.throw(err);\n },\n });\n opCtx?.onDispose(() => ctx.dispose());\n\n if (timeout !== 0) {\n this._scheduleTimeout(ctx, errors, timeout);\n }\n\n const allNotarized = Promise.all(\n credentials.map((credential) => this._waitUntilProcessed(requirePublicKey(credential.id))),\n );\n\n this._tryNotarizeCredentialsWithPeers(ctx, credentials, { retryTimeout, successDelay });\n\n if (this._edgeClient) {\n this._tryNotarizeCredentialsWithEdge(ctx, this._edgeClient, credentials, {\n retryTimeout,\n successDelay,\n jitter: edgeRetryJitter,\n });\n }\n\n try {\n await Promise.race([rejectOnDispose(ctx), allNotarized, errors.wait()]);\n log('done');\n } finally {\n await ctx.dispose();\n }\n }\n\n private _tryNotarizeCredentialsWithPeers(\n ctx: Context,\n credentials: Credential[],\n { retryTimeout, successDelay }: NotarizationTimeouts,\n ): void {\n const peersTried = new Set<NotarizationTeleportExtension>();\n\n // Repeatable task that tries to notarize credentials with one of the available peers.\n const notarizeTask = new DeferredTask(ctx, async () => {\n try {\n if (this._extensions.size === 0) {\n return; // No peers to try.\n }\n\n // Pick a peer that we haven't tried yet.\n const peer = [...this._extensions].find((peer) => !peersTried.has(peer));\n if (!peer) {\n log.info('Exhausted all peers to notarize with', { retryIn: retryTimeout });\n peersTried.clear();\n scheduleTask(ctx, () => notarizeTask.schedule(), retryTimeout); // retry with all peers again\n return;\n }\n\n peersTried.add(peer);\n log('try notarizing', { peer: peer.localPeerId, credentialId: credentials.map((credential) => credential.id) });\n await peer.rpc.NotarizationService.notarize(\n create(NotarizeRequestSchema, {\n credentials: credentials.filter(\n (credential) => !this._processedCredentials.has(requirePublicKey(credential.id)),\n ),\n }),\n );\n log('success');\n\n await sleep(successDelay); // wait before trying with a new peer\n } catch (err: any) {\n if (!ctx.disposed && !err.message.includes(WRITER_NOT_SET_ERROR_CODE)) {\n log.info('error notarizing (recoverable)', err);\n }\n notarizeTask.schedule(); // retry immediately with next peer\n }\n });\n\n notarizeTask.schedule();\n this._extensionOpened.on(ctx, () => notarizeTask.schedule());\n }\n\n private _tryNotarizeCredentialsWithEdge(\n ctx: Context,\n client: EdgeHttpClient,\n credentials: Credential[],\n timeouts: NotarizationTimeouts & { jitter?: number },\n ): void {\n const encodedCredentials = credentials.map((credential) => {\n const binary = toBinary(CredentialSchema, credential);\n return Buffer.from(binary).toString('base64');\n });\n scheduleTask(ctx, async () => {\n try {\n await client.notarizeCredentials(\n ctx,\n this._spaceId,\n { credentials: encodedCredentials },\n { retry: { count: MAX_EDGE_RETRIES, timeout: timeouts.retryTimeout, jitter: timeouts.jitter } },\n );\n\n log('edge notarization success');\n } catch (error: any) {\n handleEdgeError(error);\n }\n });\n }\n\n /**\n * Called with credentials arriving from the control pipeline.\n */\n async processCredential(credential: Credential): Promise<void> {\n if (!credential.id) {\n return;\n }\n const id = requirePublicKey(credential.id);\n this._processCredentialsTriggers.get(id)?.wake();\n this._processedCredentials.add(id);\n this._processCredentialsTriggers.delete(id);\n }\n\n setWriter(writer: HypercoreWriter<Credential>): void {\n invariant(!this._writer, 'Writer already set.');\n this._writer = writer;\n if (this._edgeClient && this.isOpen) {\n this._notarizePendingEdgeCredentials(this._edgeClient, writer);\n }\n }\n\n private _startPeriodicEdgePolling(client: EdgeHttpClient): void {\n this._activeEdgePollingIntervalHandle = setInterval(() => {\n if (this._writer) {\n this._notarizePendingEdgeCredentials(client, this._writer);\n }\n }, this._activeEdgePollingInterval);\n }\n\n private _stopPeriodicEdgePolling(): void {\n if (this._activeEdgePollingIntervalHandle) {\n clearInterval(this._activeEdgePollingIntervalHandle);\n this._activeEdgePollingIntervalHandle = undefined;\n }\n }\n\n /**\n * The method is used only for adding agent feeds to spaces.\n * When an agent is created we can admit them into all the existing spaces. In case the operation fails\n * this method will fix it on the next space open.\n * Given how rarely this happens there's no need to poll the endpoint.\n */\n private _notarizePendingEdgeCredentials(client: EdgeHttpClient, writer: HypercoreWriter<Credential>): void {\n scheduleMicroTask(this._ctx, async () => {\n try {\n const response = await client.getCredentialsForNotarization(this._ctx, this._spaceId, {\n retry: { count: MAX_EDGE_RETRIES },\n });\n\n const credentials = response.awaitingNotarization.credentials;\n if (!credentials.length) {\n log('edge did not return credentials for notarization');\n return;\n }\n\n log('got edge credentials for notarization', { count: credentials.length });\n\n const decodedCredentials = credentials.map((credential) => {\n const binary = Buffer.from(credential, 'base64');\n return fromBinary(CredentialSchema, binary);\n });\n\n await this._notarizeCredentials(writer, decodedCredentials);\n\n log.info('notarized edge credentials', { count: decodedCredentials.length });\n } catch (error: any) {\n handleEdgeError(error);\n }\n });\n }\n\n private async _waitUntilProcessed(id: PublicKey): Promise<void> {\n if (this._processedCredentials.has(id)) {\n return;\n }\n await entry(this._processCredentialsTriggers, id).orInsert(new Trigger()).value.wait();\n }\n\n /**\n * Requests from other peers to notarize credentials.\n */\n private async _onNotarize(request: NotarizeRequest): Promise<void> {\n if (!this._writer) {\n throw new Error(WRITER_NOT_SET_ERROR_CODE);\n }\n await this._notarizeCredentials(this._writer, request.credentials ?? []);\n }\n\n private async _notarizeCredentials(writer: HypercoreWriter<Credential>, credentials: Credential[]): Promise<void> {\n for (const credential of credentials) {\n const credentialId = requirePublicKey(credential.id);\n if (this._processedCredentials.has(credentialId)) {\n continue;\n }\n const verificationResult = await verifyCredential(credential);\n if (verificationResult.kind === 'fail') {\n throw new Error(`Credential verification failed: ${verificationResult.errors.join('\\n')}.`);\n }\n await writer.write(credential);\n }\n }\n\n createExtension(): NotarizationTeleportExtension {\n const extension = new NotarizationTeleportExtension({\n onOpen: async () => {\n log('extension opened', { peer: extension.localPeerId });\n this._extensions.add(extension);\n this._extensionOpened.emit();\n },\n onClose: async () => {\n log('extension closed', { peer: extension.localPeerId });\n this._extensions.delete(extension);\n },\n onNotarize: this._onNotarize.bind(this),\n });\n return extension;\n }\n\n private _scheduleTimeout(ctx: Context, errors: Trigger, timeout: number): void {\n scheduleTask(\n ctx,\n () => {\n log.warn('Notarization timeout', {\n timeout,\n peers: Array.from(this._extensions).map((extension) => extension.remotePeerId),\n });\n void ctx.dispose();\n errors.throw(new TimeoutError(timeout, 'Notarization timed out'));\n },\n timeout,\n );\n }\n}\n\nconst handleEdgeError = (error: any) => {\n if (!(error instanceof EdgeCallFailedError) || error.data) {\n log.catch(error);\n } else {\n log.info('Edge notarization failure', { message: error.message });\n }\n};\n\nexport type NotarizationTeleportExtensionProps = {\n onOpen: () => Promise<void>;\n onClose: () => Promise<void>;\n onNotarize: (request: NotarizeRequest) => Promise<void>;\n};\n\nexport class NotarizationTeleportExtension extends RpcExtension<Services, Services> {\n constructor(private readonly _params: NotarizationTeleportExtensionProps) {\n super({\n requested: {\n NotarizationService: getBufService<NotarizationService>('dxos.mesh.teleport.notarization.NotarizationService'),\n },\n exposed: {\n NotarizationService: getBufService<NotarizationService>('dxos.mesh.teleport.notarization.NotarizationService'),\n },\n });\n }\n\n protected async getHandlers(): Promise<Services> {\n return {\n NotarizationService: {\n notarize: async (request) => {\n await this._params.onNotarize(request);\n return create(EmptySchema, {});\n },\n },\n };\n }\n\n override async onOpen(ctx: ExtensionContext): Promise<void> {\n await super.onOpen(ctx);\n await this._params.onOpen();\n }\n\n override async onClose(err?: Error | undefined): Promise<void> {\n await this._params.onClose();\n await super.onClose(err);\n }\n}\n\ntype NotarizationTimeouts = {\n retryTimeout: number;\n successDelay: number;\n};\n\ntype Services = {\n NotarizationService: NotarizationService;\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { save } from '@automerge/automerge';\nimport { type AutomergeUrl, parseAutomergeUrl } from '@automerge/automerge-repo';\nimport { create, equals } from '@bufbuild/protobuf';\n\nimport { Event, Mutex, scheduleTask, sleep, sleepWithContext, synchronized, trackLeaks } from '@dxos/async';\nimport { AUTH_TIMEOUT } from '@dxos/client-protocol';\nimport { Context, ContextDisposedError } from '@dxos/context';\nimport { credentialPayload } from '@dxos/credentials';\nimport { timed, warnAfterTimeout } from '@dxos/debug';\nimport { type DatabaseRoot, type DocumentLease, type EchoHost } from '@dxos/echo-host';\nimport { type DatabaseDirectory, SpaceDocVersion } from '@dxos/echo-protocol';\nimport type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';\nimport { type HypercoreStore, type HypercoreWrapper } from '@dxos/feed-store';\nimport { failedInvariant, invariant } from '@dxos/invariant';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { CancelledError, type FeedProtocol, SystemError } from '@dxos/protocols';\nimport { fromDate, fromPublicKey, fromTimeframe } from '@dxos/protocols/buf';\nimport { SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type Space_Metrics, Space_MetricsSchema } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type FeedMessage, type FeedMessage_Payload } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport {\n AdmittedFeed_Designation,\n AdmittedFeedSchema,\n type Credential,\n type Epoch,\n EpochSchema,\n MemberProfileSchema,\n MembershipPolicy,\n type ProfileDocument,\n ProfileDocumentSchema,\n SpaceMember_Role,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type GossipMessage } from '@dxos/protocols/buf/dxos/mesh/teleport/gossip_pb';\nimport { type SpacesService } from '@dxos/protocols/rpc';\nimport { type Gossip, type Presence } from '@dxos/teleport-extension-gossip';\nimport { Timeframe } from '@dxos/timeframe';\nimport { trace } from '@dxos/tracing';\nimport { type AsyncCallback, CallbackCollection, ComplexSet } from '@dxos/util';\n\nimport * as Auth from '../../Auth.ts';\nimport { EdgeFeedReplicator } from '../../Replication.ts';\nimport { type IMetadataStore } from '../metadata/index.ts';\nimport { createMappedFeedWriter } from '../pipeline/index.ts';\nimport { type Space } from '../space/index.ts';\nimport { AutomergeSpaceState } from './automerge-space-state.ts';\nimport { type SigningContext } from './data-space-manager.ts';\nimport { runEpochMigration } from './epoch-migrations.ts';\nimport { NotarizationPlugin } from './notarization-plugin.ts';\n\nexport type DataSpaceCallbacks = {\n /**\n * Called before transitioning to the ready state.\n */\n beforeReady?: () => Promise<void>;\n\n /**\n * Called after transitioning to the ready state.\n */\n afterReady?: () => Promise<void>;\n\n /**\n * Called before space gets closed.\n */\n beforeClose?: () => Promise<void>;\n};\n\nexport type DataSpaceProps = {\n initialState: SpaceState;\n inner: Space;\n metadataStore: IMetadataStore;\n gossip: Gossip;\n presence: Presence;\n keyring: KeyringApi;\n hypercoreStore: HypercoreStore<FeedMessage>;\n echoHost: EchoHost;\n signingContext: SigningContext;\n callbacks?: DataSpaceCallbacks;\n tags?: string[];\n edgeConnection?: EdgeConnection;\n edgeHttpClient?: EdgeHttpClient;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n activeEdgeNotarizationPollingInterval?: number;\n};\n\nexport type CreateEpochOptions = {\n migration?: SpacesService.Migration;\n newAutomergeRoot?: string;\n};\n\nconst ROOT_DOC_LOAD_ATTEMPT_TIMEOUT = 20_000;\n\nconst ROOT_DOC_LOAD_RETRY_INITIAL_DELAY = 1_000;\nconst ROOT_DOC_LOAD_RETRY_MAX_DELAY = 30_000;\n\n@trackLeaks('open', 'close')\nexport class DataSpace {\n private _ctx = new Context();\n private readonly _inner: Space;\n\n private readonly _gossip: Gossip;\n private readonly _presence: Presence;\n private readonly _keyring: KeyringApi;\n private readonly _hypercoreStore: HypercoreStore<FeedMessage>;\n private readonly _metadataStore: IMetadataStore;\n private readonly _signingContext: SigningContext;\n private readonly _notarizationPlugin: NotarizationPlugin;\n private readonly _callbacks: DataSpaceCallbacks;\n private readonly _echoHost: EchoHost;\n private readonly _edgeFeedReplicator?: EdgeFeedReplicator = undefined;\n\n // TODO(dmaretskyi): Move into Space?\n private readonly _automergeSpaceState = new AutomergeSpaceState((rootUrl) => this._onNewAutomergeRoot(rootUrl));\n\n private readonly _epochProcessingMutex = new Mutex();\n\n private _state = SpaceState.SPACE_CLOSED;\n\n /** Immutable tags from space metadata, available immediately. */\n readonly tags: string[];\n\n private _databaseRoot: DatabaseRoot | null = null;\n\n /**\n * Error for _state === SpaceState.SPACE_ERROR.\n */\n public error: Error | undefined = undefined;\n\n public readonly authVerifier: Auth.TrustedKeySetAuthVerifier;\n public readonly stateUpdate = new Event();\n\n public readonly postOpen = new CallbackCollection<AsyncCallback<void>>();\n public readonly preClose = new CallbackCollection<AsyncCallback<void>>();\n\n public metrics: Space_Metrics = create(Space_MetricsSchema, {});\n\n constructor(params: DataSpaceProps) {\n this._inner = params.inner;\n this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());\n\n this._gossip = params.gossip;\n this._presence = params.presence;\n this._keyring = params.keyring;\n this._hypercoreStore = params.hypercoreStore;\n this._metadataStore = params.metadataStore;\n this._signingContext = params.signingContext;\n this._callbacks = params.callbacks ?? {};\n this._echoHost = params.echoHost;\n this._notarizationPlugin = new NotarizationPlugin({\n spaceId: this._inner.id,\n edgeClient: params.edgeHttpClient,\n edgeFeatures: params.edgeFeatures,\n activeEdgePollingInterval: params.activeEdgeNotarizationPollingInterval,\n });\n\n this.authVerifier = new Auth.TrustedKeySetAuthVerifier({\n trustedKeysProvider: () =>\n new ComplexSet(\n PublicKey.hash,\n Array.from(this._inner.spaceState.members.values())\n .filter((member) => member.role !== SpaceMember_Role.REMOVED)\n .map((member) => member.key),\n ),\n update: this._inner.stateUpdate,\n authTimeout: AUTH_TIMEOUT,\n });\n\n this.tags = params.tags ?? [];\n\n if (params.edgeConnection && params.edgeFeatures?.feedReplicator) {\n this._edgeFeedReplicator = new EdgeFeedReplicator({ messenger: params.edgeConnection, spaceId: this.id });\n }\n\n this._state = params.initialState;\n log('new state', { state: SpaceState[this._state] });\n }\n\n get id() {\n return this._inner.id;\n }\n\n get key() {\n return this._inner.key;\n }\n\n get isOpen() {\n return this._inner.isOpen;\n }\n\n get state(): SpaceState {\n return this._state;\n }\n\n // TODO(burdon): Can we mark this for debugging only?\n get inner() {\n return this._inner;\n }\n\n get presence() {\n return this._presence;\n }\n\n get notarizationPlugin() {\n return this._notarizationPlugin;\n }\n\n /** Membership policy from the genesis credential, defaults to INVITE. */\n get membershipPolicy(): MembershipPolicy {\n return this._inner.spaceState.genesisCredential ? this._inner.spaceState.membershipPolicy : MembershipPolicy.INVITE;\n }\n\n get automergeSpaceState() {\n return this._automergeSpaceState;\n }\n\n get databaseRoot(): DatabaseRoot | null {\n return this._databaseRoot;\n }\n\n private get _automergeInfo() {\n return {\n rootUrl: this._automergeSpaceState.rootUrl,\n lastEpoch: this._automergeSpaceState.lastEpoch,\n };\n }\n\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async open(ctx: Context): Promise<void> {\n if (this._state === SpaceState.SPACE_CLOSED) {\n await this._open(ctx);\n }\n }\n\n private async _open(ctx: Context): Promise<void> {\n await this._presence.open();\n await this._gossip.open();\n await this._notarizationPlugin.open();\n await this._inner.spaceState.addCredentialProcessor(this._notarizationPlugin);\n await this._automergeSpaceState.open();\n await this._inner.spaceState.addCredentialProcessor(this._automergeSpaceState);\n\n if (this._edgeFeedReplicator) {\n this.inner.protocol.feedAdded.append(this._onFeedAdded);\n }\n\n await this._inner.open(ctx);\n await this._inner.startProtocol(ctx);\n\n await this._edgeFeedReplicator?.open();\n\n this._state = SpaceState.SPACE_CONTROL_ONLY;\n log('new state', { state: SpaceState[this._state] });\n this.stateUpdate.emit();\n this.metrics = create(Space_MetricsSchema, {});\n this.metrics.open = fromDate(new Date());\n\n await this.postOpen.callSerial();\n }\n\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async close(ctx: Context): Promise<void> {\n await this._close(ctx);\n }\n\n private async _close(ctx: Context): Promise<void> {\n await this._callbacks.beforeClose?.();\n\n await this.preClose.callSerial();\n\n this._state = SpaceState.SPACE_CLOSED;\n log('new state', { state: SpaceState[this._state] });\n await this._ctx.dispose();\n this._ctx = new Context();\n\n if (this._edgeFeedReplicator) {\n this.inner.protocol.feedAdded.remove(this._onFeedAdded);\n }\n\n await this._edgeFeedReplicator?.close();\n\n await this.authVerifier.close();\n\n await this._inner.close(ctx);\n await this._inner.spaceState.removeCredentialProcessor(this._automergeSpaceState);\n await this._automergeSpaceState.close();\n await this._inner.spaceState.removeCredentialProcessor(this._notarizationPlugin);\n await this._notarizationPlugin.close();\n\n await this._presence.close();\n await this._gossip.close();\n }\n\n async postMessage(channel: string, message: any): Promise<void> {\n return this._gossip.postMessage(channel, message);\n }\n\n listen(channel: string, callback: (message: GossipMessage) => void): { unsubscribe: () => void } {\n return this._gossip.listen(channel, callback);\n }\n\n /**\n * Initialize the data pipeline in a separate task.\n * @param callerCtx - Trace context from the caller (e.g., activate or createSpace) for span parenting.\n */\n initializeDataPipelineAsync(callerCtx?: Context): void {\n const traceCtx = callerCtx ?? this._ctx;\n scheduleTask(this._ctx, async () => {\n try {\n this.metrics.pipelineInitBegin = fromDate(new Date());\n await this.initializeDataPipeline(traceCtx);\n } catch (err) {\n if (err instanceof CancelledError || err instanceof ContextDisposedError) {\n log('data pipeline initialization cancelled', err);\n return;\n }\n\n log.error('Error initializing data pipeline', err);\n this._state = SpaceState.SPACE_ERROR;\n log('new state', { state: SpaceState[this._state] });\n this.error = err as Error;\n this.stateUpdate.emit();\n } finally {\n this.metrics.ready = fromDate(new Date());\n }\n });\n }\n\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async initializeDataPipeline(ctx: Context): Promise<void> {\n if (this._state !== SpaceState.SPACE_CONTROL_ONLY) {\n throw new SystemError({ message: 'Invalid operation' });\n }\n\n this._state = SpaceState.SPACE_INITIALIZING;\n log('new state', { state: SpaceState[this._state] });\n\n log('initializing control pipeline');\n await this._initializeAndReadControlPipeline(ctx);\n\n // Allow other tasks to run before loading the data pipeline.\n await sleep(1);\n\n const ready = this.stateUpdate.waitForCondition(() => this._state === SpaceState.SPACE_READY);\n\n log('initializing automerge root');\n const isPersisted = this._echoHost.spaces.some((s) => s.spaceId === this.id);\n if (isPersisted) {\n try {\n log('opening persisted space root', { spaceId: this.id });\n const root = await this._echoHost.openSpaceRoot(ctx, this.id);\n this._databaseRoot = root;\n if (root.getVersion() !== SpaceDocVersion.CURRENT) {\n this._state = SpaceState.SPACE_REQUIRES_MIGRATION;\n this.stateUpdate.emit();\n } else {\n await this._enterReadyState();\n }\n } catch (err) {\n log.warn('failed to open persisted space root, will wait for credentials', { spaceId: this.id, err });\n }\n }\n\n this._automergeSpaceState.startProcessingRootDocs();\n\n // TODO(dmaretskyi): Change so `initializeDataPipeline` doesn't wait for the space to be READY, but rather any state with a valid root.\n log('waiting for space to be ready');\n await ready;\n log('space is ready');\n }\n\n async *getAllDocuments(): AsyncIterable<[string, Uint8Array]> {\n invariant(this._databaseRoot, 'Space is not ready');\n const doc = this._databaseRoot.doc() ?? failedInvariant();\n const root = save(doc);\n yield [this._databaseRoot.documentId, root];\n\n for (const documentUrl of this._databaseRoot.getAllLinkedDocuments()) {\n const data = await this._echoHost.exportDoc(documentUrl);\n yield [documentUrl.replace(/^automerge:/, ''), data];\n }\n }\n\n /**\n * Get all feeds and their blocks for this space.\n * Used for space archive export.\n */\n async getAllFeeds(): Promise<Array<{ feedId: string; feedNamespace: string; blocks: FeedProtocol.Block[] }>> {\n return this._echoHost.getAllFeedsForSpace(this.id);\n }\n\n private async _enterReadyState(): Promise<void> {\n await this._callbacks.beforeReady?.();\n\n this._state = SpaceState.SPACE_READY;\n log('new state', { state: SpaceState[this._state] });\n this.stateUpdate.emit();\n\n await this._callbacks.afterReady?.();\n }\n\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n private async _initializeAndReadControlPipeline(ctx: Context): Promise<void> {\n await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({\n ctx,\n timeout: 10_000,\n breakOnStall: false,\n });\n\n this.metrics.controlPipelineReady = fromDate(new Date());\n\n await this._createWritableFeeds();\n log('writable feeds created');\n this.stateUpdate.emit();\n\n if (!this.notarizationPlugin.hasWriter) {\n this.notarizationPlugin.setWriter(\n createMappedFeedWriter<Credential, FeedMessage_Payload>(credentialPayload, this._inner.controlPipeline.writer),\n );\n }\n\n await this._syncOwnProfile();\n }\n\n /**\n * Rewrites this member's profile credential when it no longer matches the identity's profile, since\n * other members resolve this identity's name from the space and a profile set or changed while the\n * space was not open never reached it.\n */\n private async _syncOwnProfile(): Promise<void> {\n const profile = this._signingContext.getProfile();\n if (!profile) {\n return;\n }\n\n const self = Array.from(this._inner.spaceState.members.values()).find((member) =>\n member.key.equals(this._signingContext.identityKey),\n );\n if (!self || (self.profile && equals(ProfileDocumentSchema, self.profile, profile))) {\n return;\n }\n\n // A repair, not a precondition: a failed write must not keep the space from opening.\n try {\n await this.updateOwnProfile(profile);\n } catch (err) {\n log.warn('failed to sync own member profile', { space: this.key, err });\n }\n }\n\n @timed(10_000)\n private async _createWritableFeeds(): Promise<void> {\n const credentials: Credential[] = [];\n if (!this.inner.controlFeedKey) {\n const controlFeed = await this._hypercoreStore.openHypercore(await this._keyring.createKey(), { writable: true });\n await this.inner.setControlFeed(controlFeed);\n\n credentials.push(\n await this._signingContext.credentialSigner.createCredential({\n subject: controlFeed.key,\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(this.key),\n deviceKey: fromPublicKey(this._signingContext.deviceKey),\n identityKey: fromPublicKey(this._signingContext.identityKey),\n designation: AdmittedFeed_Designation.CONTROL,\n }),\n }),\n );\n }\n if (!this.inner.dataFeedKey) {\n const dataFeed = await this._hypercoreStore.openHypercore(await this._keyring.createKey(), {\n writable: true,\n sparse: true,\n });\n await this.inner.setDataFeed(dataFeed);\n\n credentials.push(\n await this._signingContext.credentialSigner.createCredential({\n subject: dataFeed.key,\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(this.key),\n deviceKey: fromPublicKey(this._signingContext.deviceKey),\n identityKey: fromPublicKey(this._signingContext.identityKey),\n designation: AdmittedFeed_Designation.DATA,\n }),\n }),\n );\n }\n\n if (credentials.length > 0) {\n try {\n log('will notarize credentials for feed admission', { count: credentials.length });\n // Never times out\n await this.notarizationPlugin.notarize({ ctx: this._ctx, credentials, timeout: 0 });\n\n log('credentials notarized');\n } catch (err) {\n if (err instanceof ContextDisposedError) {\n return;\n }\n log.error('error notarizing credentials for feed admission', err);\n throw err;\n }\n\n // Set this after credentials are notarized so that on failure we will retry.\n await this._metadataStore.setWritableFeedKeys(this.key, this.inner.controlFeedKey!, this.inner.dataFeedKey!);\n }\n }\n\n /**\n * Loads a space's root document, re-driving until it arrives or the space closes.\n *\n * `loadDoc` waits on the network with no deadline of its own, so a space whose root never\n * arrives would wait forever. The retry bounds each attempt and re-drives the document between\n * them: the repo-wide kick only revives `all-failed`/`no-peers` entries, and a root that stalls\n * after its first bytes land leaves a settled entry that neither the kick nor a fresh\n * `findWithProgress` re-issues.\n */\n async #loadRootDoc(rootUrl: AutomergeUrl): Promise<DocumentLease<DatabaseDirectory> | null> {\n for (let attempt = 0, delay = ROOT_DOC_LOAD_RETRY_INITIAL_DELAY; !this._ctx.disposed; attempt++) {\n try {\n if (attempt > 0) {\n this._echoHost.automergeHost.kickStalledSync();\n this._echoHost.automergeHost.resyncDocument(parseAutomergeUrl(rootUrl).documentId);\n }\n\n return await warnAfterTimeout(5_000, 'Automerge root doc load timeout (DataSpace)', () =>\n this._echoHost.loadDoc<DatabaseDirectory>(this._ctx, rootUrl, {\n fetchFromNetwork: true,\n // `loadDoc`'s own deadline, so a timed-out attempt aborts the readiness wait and\n // disposes its lease. An outer timeout would only reject, leaving the subscription live\n // and able to hand back an undisposed lease later.\n timeout: ROOT_DOC_LOAD_ATTEMPT_TIMEOUT,\n }),\n );\n } catch (err) {\n if (this._ctx.disposed || err instanceof ContextDisposedError) {\n return null;\n }\n\n log.info('space root doc did not arrive; resetting stalled sync and retrying', {\n space: this.key,\n rootUrl,\n attempt,\n delay,\n });\n await sleepWithContext(this._ctx, delay);\n delay = Math.min(delay * 2, ROOT_DOC_LOAD_RETRY_MAX_DELAY);\n }\n }\n\n return null;\n }\n\n private _onNewAutomergeRoot(rootUrl: string): void {\n log('loading automerge root doc for space', { space: this.key, rootUrl });\n\n let lease: DocumentLease<DatabaseDirectory> | null = null;\n\n // TODO(dmaretskyi): Make this single-threaded (but doc loading should still be parallel to not block epoch processing).\n queueMicrotask(async () => {\n try {\n lease = await this.#loadRootDoc(rootUrl as AutomergeUrl);\n if (this._ctx.disposed) {\n return;\n }\n if (!lease) {\n log.warn('automerge root doc not available yet', { space: this.key, rootUrl });\n return;\n }\n\n // Ensure only one root is processed at a time.\n using _guard = await this._epochProcessingMutex.acquire();\n\n // Attaching space identifiers to legacy documents.\n const doc = lease.doc();\n if (!doc.access?.spaceId || !doc.access?.spaceKey) {\n lease.change((doc: DatabaseDirectory) => {\n doc.access ??= {};\n doc.access.spaceId ??= this.id;\n // spaceKey is deprecated but still written so older clients can resolve the owning space.\n doc.access.spaceKey ??= this.key.toHex();\n });\n }\n\n // TODO(dmaretskyi): Close roots.\n // TODO(dmaretskyi): How do we handle changing to the next EPOCH?\n // `updateSpaceRoot` takes its own lease on the root, so this one is released either way.\n const rootUrlToAssign = lease.url;\n lease[Symbol.dispose]();\n lease = null;\n const root = await this._echoHost.updateSpaceRoot(this._ctx, this.id, rootUrlToAssign);\n\n // NOTE: Make sure this assignment happens synchronously together with the state change.\n this._databaseRoot = root;\n if (root.getVersion() !== SpaceDocVersion.CURRENT) {\n this._state = SpaceState.SPACE_REQUIRES_MIGRATION;\n this.stateUpdate.emit();\n } else if (this._state !== SpaceState.SPACE_READY) {\n await this._enterReadyState();\n } else {\n this.stateUpdate.emit();\n }\n } catch (err) {\n if (err instanceof ContextDisposedError) {\n return;\n }\n log.warn('error loading automerge root doc', { space: this.key, rootUrl, err });\n } finally {\n // Released on every path that did not hand it to `updateSpaceRoot`.\n lease?.[Symbol.dispose]();\n }\n });\n }\n\n // TODO(dmaretskyi): Use profile from signing context.\n async updateOwnProfile(profile: ProfileDocument): Promise<void> {\n const credential = await this._signingContext.credentialSigner.createCredential({\n subject: this._signingContext.identityKey,\n assertion: create(MemberProfileSchema, { profile }),\n });\n await this.inner.controlPipeline.writer.write(credentialPayload(credential));\n }\n\n async createEpoch(options?: CreateEpochOptions): Promise<CreateEpochResult | null> {\n const ctx = this._ctx.derive();\n\n // Preserving existing behavior.\n if (!options?.migration) {\n return null;\n }\n\n const { newRoot } = await runEpochMigration(ctx, {\n echoHost: this._echoHost,\n spaceId: this.id,\n spaceKey: this.key,\n migration: options.migration,\n currentRoot: this._automergeSpaceState.rootUrl ?? null,\n newAutomergeRoot: options.newAutomergeRoot,\n });\n\n const lastEpoch = this._automergeSpaceState.lastEpoch;\n const epoch: Epoch = create(EpochSchema, {\n previousId: lastEpoch?.credential.id,\n number: (lastEpoch?.assertion.number ?? -1) + 1,\n timeframe: lastEpoch?.assertion.timeframe ?? fromTimeframe(new Timeframe()),\n automergeRoot: newRoot ?? this._automergeSpaceState.rootUrl,\n });\n\n const credential = await this._signingContext.credentialSigner.createCredential({\n subject: this.key,\n assertion: epoch,\n });\n\n const receipt = await this.inner.controlPipeline.writer.write(credentialPayload(credential));\n\n const timeframe = new Timeframe([[receipt.feedKey, receipt.seq]]);\n await this.inner.controlPipeline.state.waitUntilTimeframe(timeframe);\n await this._echoHost.updateIndexes({ reason: 'epoch' });\n\n return { credential, timeframe };\n }\n\n @synchronized\n async activate(ctx: Context): Promise<void> {\n if (![SpaceState.SPACE_CLOSED, SpaceState.SPACE_INACTIVE].includes(this._state)) {\n return;\n }\n\n await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_ACTIVE);\n await this._open(ctx);\n this.initializeDataPipelineAsync(ctx);\n }\n\n @synchronized\n async deactivate(ctx: Context): Promise<void> {\n if (this._state === SpaceState.SPACE_INACTIVE) {\n return;\n }\n await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_INACTIVE);\n if (this._state !== SpaceState.SPACE_CLOSED) {\n await this._close(ctx);\n }\n this._state = SpaceState.SPACE_INACTIVE;\n log('new state', { state: SpaceState[this._state] });\n this.stateUpdate.emit();\n }\n\n /**\n * Tombstones (soft-deletes) the space by moving it to a terminal state.\n * This is intentionally separate from teardown: the caller is responsible for {@link close}-ing the\n * space (teardown uses the resource lifecycle, distinct from this state transition).\n * Terminal: {@link activate} will not re-open a deleted space. Data is not removed until garbage\n * collection (future work).\n */\n @synchronized\n async delete(): Promise<void> {\n if (this._state === SpaceState.SPACE_DELETED) {\n return;\n }\n await this._metadataStore.setSpaceState(this.key, SpaceState.SPACE_DELETED);\n this._state = SpaceState.SPACE_DELETED;\n log('new state', { state: SpaceState[this._state] });\n this.stateUpdate.emit();\n }\n\n getEdgeReplicationSetting() {\n return this._metadataStore.getSpaceEdgeReplicationSetting(this.key);\n }\n\n private _onFeedAdded = async (feed: HypercoreWrapper<any>) => {\n await this._edgeFeedReplicator!.addHypercore(feed);\n };\n}\n\ntype CreateEpochResult = {\n credential: Credential;\n timeframe: Timeframe;\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\n\nimport { createCredential, credentialPayload } from '@dxos/credentials';\nimport { failUndefined } from '@dxos/debug';\nimport { type KeyringApi } from '@dxos/keyring';\nimport { fromPublicKey, fromTimeframe } from '@dxos/protocols/buf';\nimport {\n AdmittedFeed_Designation,\n AdmittedFeedSchema,\n EpochSchema,\n MembershipPolicy,\n SpaceGenesisSchema,\n SpaceMember_Role,\n SpaceMemberSchema,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { Timeframe } from '@dxos/timeframe';\n\nimport { type Space } from '../space/index.ts';\nimport { type SigningContext } from './data-space-manager.ts';\n\nexport const spaceGenesis = async (\n keyring: KeyringApi,\n signingContext: SigningContext,\n space: Space,\n automergeRoot?: string,\n tags?: string[],\n membershipPolicy?: MembershipPolicy,\n spaceRootUrl?: string,\n) => {\n // TODO(dmaretskyi): Find a way to reconcile with credential generator.\n const credentials = [\n await createCredential({\n signer: keyring,\n issuer: space.key,\n subject: space.key,\n assertion: create(SpaceGenesisSchema, {\n spaceKey: fromPublicKey(space.key),\n tags: tags ?? [],\n membershipPolicy: membershipPolicy ?? MembershipPolicy.INVITE,\n }),\n }),\n\n await createCredential({\n signer: keyring,\n issuer: space.key,\n subject: signingContext.identityKey,\n assertion: create(SpaceMemberSchema, {\n spaceKey: fromPublicKey(space.key),\n role: SpaceMember_Role.OWNER,\n profile: signingContext.getProfile(),\n genesisFeedKey: fromPublicKey(space.controlFeedKey ?? failUndefined()),\n spaceRootUrl,\n tags: tags ?? [],\n }),\n }),\n\n await signingContext.credentialSigner.createCredential({\n subject: space.controlFeedKey ?? failUndefined(),\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(space.key),\n identityKey: fromPublicKey(signingContext.identityKey),\n deviceKey: fromPublicKey(signingContext.deviceKey),\n designation: AdmittedFeed_Designation.CONTROL,\n }),\n }),\n\n await signingContext.credentialSigner.createCredential({\n subject: space.dataFeedKey ?? failUndefined(),\n assertion: create(AdmittedFeedSchema, {\n spaceKey: fromPublicKey(space.key),\n identityKey: fromPublicKey(signingContext.identityKey),\n deviceKey: fromPublicKey(signingContext.deviceKey),\n designation: AdmittedFeed_Designation.DATA,\n }),\n }),\n\n await signingContext.credentialSigner.createCredential({\n subject: space.key ?? failUndefined(),\n assertion: create(EpochSchema, {\n number: 0,\n timeframe: fromTimeframe(new Timeframe()),\n automergeRoot,\n }),\n }),\n ];\n\n for (const credential of credentials) {\n await space.controlPipeline.writer.write(credentialPayload(credential));\n }\n\n return credentials;\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { type Doc } from '@automerge/automerge';\nimport {\n type AutomergeUrl,\n type DocumentId,\n interpretAsDocumentId,\n isValidAutomergeUrl,\n} from '@automerge/automerge-repo';\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { Event, scheduleTask, synchronized, trackLeaks } from '@dxos/async';\nimport { SpaceProperties } from '@dxos/client-protocol';\nimport { Context, LifecycleState, Resource, cancelWithContext } from '@dxos/context';\nimport {\n type CredentialSigner,\n type DelegateInvitationCredential,\n type MemberInfo,\n createAdmissionCredentials,\n credentialOfPayload,\n credentialPayload,\n getCredentialAssertion,\n} from '@dxos/credentials';\nimport { Type } from '@dxos/echo';\nimport {\n DatabaseRoot,\n type EchoHost,\n EchoHostService,\n type EdgeAutomergeReplicator,\n EdgeAutomergeReplicatorService,\n type MeshEchoReplicator,\n MeshEchoReplicatorService,\n type SpaceRootRefs,\n findInlineObjectOfType,\n} from '@dxos/echo-host';\nimport { type DatabaseDirectory, createIdFromSpaceKey } from '@dxos/echo-protocol';\nimport {\n type EdgeConnection,\n EdgeConnectionService,\n type EdgeHttpClient,\n EdgeHttpClientService,\n} from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { type HypercoreStore, HypercoreStoreService, writeMessages } from '@dxos/feed-store';\nimport { assertArgument, assertState, failedInvariant, invariant } from '@dxos/invariant';\nimport { type KeyringApi, KeyringApiService } from '@dxos/keyring';\nimport { PublicKey, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { AlreadyJoinedError } from '@dxos/protocols';\nimport {\n buf,\n fromDate,\n fromPublicKey,\n fromTimeframe,\n requirePublicKey,\n toDate,\n toPublicKey,\n toTimeframe,\n} from '@dxos/protocols/buf';\nimport {\n AdmissionKeypairSchema,\n Invitation_Kind,\n Invitation_Type,\n SpaceState,\n} from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type FeedMessage, type FeedMessage_Payload } from '@dxos/protocols/buf/dxos/echo/feed_pb';\nimport { EdgeReplicationSetting } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport { type SpaceMetadata, SpaceMetadataSchema } from '@dxos/protocols/buf/dxos/echo/metadata_pb';\nimport {\n type Credential,\n type ProfileDocument,\n SpaceDeletedSchema,\n SpaceMember_Role as SpaceMemberRole,\n} from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { type DelegateSpaceInvitation } from '@dxos/protocols/buf/dxos/halo/invitations_pb';\nimport { type PeerState } from '@dxos/protocols/buf/dxos/mesh/presence_pb';\nimport { type Teleport } from '@dxos/teleport';\nimport { Gossip, Presence } from '@dxos/teleport-extension-gossip';\nimport { trace } from '@dxos/tracing';\nimport { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';\n\nimport * as Auth from '../../Auth.ts';\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as InvitationsContract from '../../contracts/invitations.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport { openCredentialsDocument } from '../../CredentialsDocument.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { type IMetadataStore, IMetadataStoreService } from '../metadata/index.ts';\nimport {\n AuthStatus,\n CredentialServerExtension,\n type Space,\n type SpaceManager,\n SpaceManagerService,\n type SpaceProtocol,\n type SpaceProtocolSession,\n} from '../space/index.ts';\nimport { DataSpace } from './data-space.ts';\nimport { spaceGenesis } from './genesis.ts';\n\nconst PRESENCE_ANNOUNCE_INTERVAL = 10_000;\nconst PRESENCE_OFFLINE_TIMEOUT = 20_000;\n\nexport interface SigningContext {\n identityKey: PublicKey;\n deviceKey: PublicKey;\n credentialSigner: CredentialSigner; // TODO(burdon): Already has keyring.\n recordCredential: (credential: Credential) => Promise<void>;\n // TODO(dmaretskyi): Should be a getter.\n getProfile: () => ProfileDocument | undefined;\n}\n\n/**\n * Resolves signing context when identity becomes available.\n */\nexport type SigningContextProvider = () => SigningContext;\n\n/**\n * Builds a {@link SigningContextProvider} from an identity resolver.\n */\nexport const createSigningContextProvider =\n (getIdentity: () => Identity): SigningContextProvider =>\n () => {\n const identity = getIdentity();\n return {\n credentialSigner: identity.getIdentityCredentialSigner(),\n identityKey: identity.identityKey,\n deviceKey: identity.deviceKey,\n getProfile: () => identity.profileDocument,\n recordCredential: async (credential) => {\n await identity.controlPipeline.writer.write(credentialPayload(credential));\n },\n };\n };\n\n/**\n * Effect Layer providing {@link SigningContextProvider} from {@link IdentityProviderService}.\n */\nexport const SigningContextProviderLayer = Layer.effect(\n SpacesContract.SigningContextProviderService,\n Effect.gen(function* () {\n const identityProvider = yield* IdentityContract.ProviderService;\n return createSigningContextProvider(identityProvider);\n }),\n);\n\nexport type DataSpaceManagerProps = {\n spaceManager: SpaceManager;\n metadataStore: IMetadataStore;\n keyring: KeyringApi;\n signingContextProvider: SigningContextProvider;\n hypercoreStore: HypercoreStore<FeedMessage>;\n echoHost: EchoHost;\n invitationsManager: InvitationsContract.Manager;\n edgeConnection?: EdgeConnection;\n edgeHttpClient?: EdgeHttpClient;\n meshReplicator?: MeshEchoReplicator;\n echoEdgeReplicator?: EdgeAutomergeReplicator;\n runtimeProps?: DataSpaceManagerRuntimeProps;\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n};\n\nexport type DataSpaceManagerRuntimeProps = {\n spaceMemberPresenceAnnounceInterval?: number;\n spaceMemberPresenceOfflineTimeout?: number;\n activeEdgeNotarizationPollingInterval?: number;\n disableP2pReplication?: boolean;\n /**\n * If true, spaces that were previously SPACE_ACTIVE will be automatically activated on startup.\n * This is used in dedicated worker mode to restore space state after leader changeover.\n */\n autoActivateSpaces?: boolean;\n\n /**\n * Anchor spaces on a space root document and mirror credentials into a credentials document.\n * Off by default — a space then keeps its key-derived id and its control feed, as before.\n */\n automergeCredentials?: boolean;\n};\n\n/** Backoff bounds for retrying an anchor that is waiting on replication or an unassigned directory. */\nconst ANCHOR_RETRY_INITIAL = 500;\nconst ANCHOR_RETRY_MAX = 30_000;\n\n/** Backoff bounds for reporting a space root to edge; replication normally lands well inside this. */\nconst SPACE_ROOT_REPORT_RETRY_INITIAL = 500;\nconst SPACE_ROOT_REPORT_RETRY_MAX = 30_000;\n\n@trackLeaks('open', 'close')\nexport class DataSpaceManager extends Resource {\n public readonly updated = new Event();\n\n private readonly _spaces = new ComplexMap<PublicKey, DataSpace>(PublicKey.hash);\n\n /** Spaces created legacy in this session; see {@link _anchorSpaceOnRootDocument}. */\n private readonly _legacyCreatedSpaces = new Set<SpaceId>();\n /** Roots named by an inviter, to adopt once they replicate; see {@link _anchorSpaceOnRootDocument}. */\n private readonly _pendingSpaceRootUrls = new Map<SpaceId, AutomergeUrl>();\n\n /**\n * Spaces whose close has begun. `DataSpace.isOpen` reads the inner space, which closes last, so it\n * still reads open through `preClose` — the window the anchor's background work resumes in.\n */\n private readonly _closingSpaces = new Set<SpaceId>();\n\n private readonly _spaceManager: SpaceManager;\n private readonly _metadataStore: IMetadataStore;\n private readonly _keyring: KeyringApi;\n private readonly _signingContextProvider: SigningContextProvider;\n private readonly _hypercoreStore: HypercoreStore<FeedMessage>;\n private readonly _echoHost: EchoHost;\n private readonly _invitationsManager: InvitationsContract.Manager;\n private readonly _edgeConnection?: EdgeConnection = undefined;\n private readonly _edgeHttpClient?: EdgeHttpClient = undefined;\n private readonly _edgeFeatures?: Runtime_Client_EdgeFeatures = undefined;\n private readonly _meshReplicator?: MeshEchoReplicator = undefined;\n private readonly _echoEdgeReplicator?: EdgeAutomergeReplicator = undefined;\n private readonly _runtimeProps?: DataSpaceManagerRuntimeProps = undefined;\n\n /** Opt-in to the automerge-backed credential scheme; see {@link DataSpaceManagerRuntimeProps}. */\n private get _automergeCredentials(): boolean {\n return this._runtimeProps?.automergeCredentials ?? false;\n }\n\n constructor(params: DataSpaceManagerProps) {\n super();\n\n this._spaceManager = params.spaceManager;\n this._metadataStore = params.metadataStore;\n this._keyring = params.keyring;\n this._signingContextProvider = params.signingContextProvider;\n this._hypercoreStore = params.hypercoreStore;\n this._echoHost = params.echoHost;\n this._meshReplicator = params.meshReplicator;\n this._invitationsManager = params.invitationsManager;\n this._edgeConnection = params.edgeConnection;\n this._edgeFeatures = params.edgeFeatures;\n this._echoEdgeReplicator = params.echoEdgeReplicator;\n this._edgeHttpClient = params.edgeHttpClient;\n this._runtimeProps = params.runtimeProps;\n\n trace.diagnostic({\n id: 'spaces',\n name: 'Spaces',\n fetch: async () => {\n return Promise.all(\n Array.from(this._spaces.values()).map(async (space) => {\n const rootUrl = space.automergeSpaceState.rootUrl;\n using rootLease = rootUrl\n ? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(this._ctx, rootUrl as AutomergeUrl)\n : undefined;\n const rootDoc = rootLease?.doc();\n\n const properties = rootDoc && findInlineObjectOfType(rootDoc, Type.getTypename(SpaceProperties));\n\n return {\n key: space.key.toHex(),\n state: SpaceState[space.state],\n name: properties?.[1].data.name ?? null,\n inlineObjects: rootDoc ? Object.keys(rootDoc.objects ?? {}).length : null,\n linkedObjects: rootDoc ? Object.keys(rootDoc.links ?? {}).length : null,\n credentials: space.inner.spaceState.credentials.length,\n members: space.inner.spaceState.members.size,\n rootUrl,\n };\n }),\n );\n },\n });\n }\n\n private get signingContext(): SigningContext {\n return this._signingContextProvider();\n }\n\n // TODO(burdon): Remove.\n get spaces() {\n return this._spaces;\n }\n\n getSpaceById(spaceId: SpaceId): DataSpace | undefined {\n return [...this._spaces.values()].find((space) => space.id === spaceId);\n }\n\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n protected override async _open(ctx: Context): Promise<void> {\n log('open');\n log('metadata loaded', { spaces: this._metadataStore.spaces.length });\n\n const spacesToActivate: DataSpace[] = [];\n await forEachAsync(this._metadataStore.spaces, async (spaceMetadata) => {\n try {\n // Tombstoned spaces are never constructed, opened, or replicated.\n if (\n spaceMetadata.state === SpaceState.SPACE_DELETED ||\n this.isSpaceDeleted(requirePublicKey(spaceMetadata.key))\n ) {\n log('skipping deleted space', { spaceKey: spaceMetadata.key });\n return;\n }\n log('load space', { spaceMetadata });\n const space = await this._constructSpace(ctx, spaceMetadata);\n // Track spaces that were previously active for auto-activation (used in dedicated worker mode).\n if (this._runtimeProps?.autoActivateSpaces && spaceMetadata.state === SpaceState.SPACE_ACTIVE) {\n spacesToActivate.push(space);\n }\n } catch (err) {\n log.error('Error loading space', { spaceMetadata, err });\n }\n });\n\n // Auto-activate spaces that were previously active (used in dedicated worker mode after leader changeover).\n for (const space of spacesToActivate) {\n log('auto-activating space', { spaceKey: space.key });\n space.activate(ctx).catch((err) => {\n log.error('Error auto-activating space', { spaceKey: space.key, err });\n });\n }\n\n this.updated.emit();\n }\n\n @synchronized\n protected override async _close(ctx: Context): Promise<void> {\n log('close');\n for (const space of this._spaces.values()) {\n await space.close(ctx);\n }\n this._spaces.clear();\n }\n\n /**\n * Creates a new space writing the genesis credentials to the control feed.\n */\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async createSpace(ctx: Context, options: SpacesContract.CreateSpaceOptions = {}): Promise<DataSpace> {\n assertArgument(\n !!options.rootUrl === !!options.documents,\n 'options',\n 'root url must be required when providing documents',\n );\n\n assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');\n\n const tags = options.tags ? Array.from(options.tags) : [];\n const spaceKey = await this._keyring.createKey();\n const controlFeedKey = await this._keyring.createKey();\n const dataFeedKey = await this._keyring.createKey();\n\n // An imported space brings its own root document, so it keeps the key-derived id.\n const anchorOnRootDocument =\n (options.useSpaceRootDocument ?? this._automergeCredentials) && !options.rootUrl && !options.documents;\n const createdSpace = anchorOnRootDocument\n ? await this._echoHost.createSpaceWithRootDocument(ctx, spaceKey)\n : undefined;\n const spaceId = createdSpace?.spaceId ?? (await createIdFromSpaceKey(spaceKey));\n if (!createdSpace) {\n this._legacyCreatedSpaces.add(spaceId);\n }\n\n const metadata: SpaceMetadata = create(SpaceMetadataSchema, {\n key: fromPublicKey(spaceKey),\n spaceId,\n genesisFeedKey: fromPublicKey(controlFeedKey),\n controlFeedKey: fromPublicKey(controlFeedKey),\n dataFeedKey: fromPublicKey(dataFeedKey),\n state: SpaceState.SPACE_ACTIVE,\n tags,\n });\n\n log('creating space...', { spaceId, spaceKey });\n\n // New document IDs for the space.\n const documentIdMapping: Record<DocumentId, DocumentId> = {};\n if (options.documents) {\n invariant(\n Object.keys(options.documents).every((documentId) => /^[a-zA-Z0-9]+$/.test(documentId)),\n 'Invalid document IDs',\n );\n\n await Promise.all(\n Object.entries(options.documents).map(async ([documentId, data]) => {\n log('creating document...', { documentId });\n // TODO(dmaretskyi): Broken types -- the bytes get interpreted as CRDT data.\n using newDoc = await this._echoHost.createDoc(data as any as DatabaseDirectory, {\n preserveHistory: true,\n });\n\n // Archived documents carry the exporting space's identity; the indexer attributes documents by `access.spaceId`, so both fields must name the new space.\n const access = newDoc.doc().access;\n if (access !== undefined && (access.spaceKey !== spaceKey.toHex() || access.spaceId !== spaceId)) {\n newDoc.change((doc) => {\n if (doc.access) {\n doc.access.spaceKey = spaceKey.toHex();\n doc.access.spaceId = spaceId;\n }\n });\n }\n\n documentIdMapping[documentId as DocumentId] = newDoc.documentId;\n }),\n );\n }\n\n log('opening space...', { spaceKey });\n\n let root: DatabaseRoot;\n if (createdSpace) {\n root = createdSpace.directory;\n } else if (options.rootUrl) {\n const newRootDocId = documentIdMapping[interpretAsDocumentId(options.rootUrl)] ?? failedInvariant();\n using rootDocLease = await this._echoHost.loadDoc<DatabaseDirectory>(ctx, newRootDocId);\n invariant(rootDocLease, 'Root document must be available after import.');\n DatabaseRoot.mapLinks(rootDocLease, documentIdMapping);\n\n root = await this._echoHost.updateSpaceRoot(ctx, spaceId, `automerge:${newRootDocId}` as AutomergeUrl);\n } else {\n root = await this._echoHost.createSpaceRoot(ctx, spaceKey);\n }\n await this._echoHost.flush(ctx);\n\n log('constructing space...', { spaceKey });\n\n const space = await this._constructSpace(ctx, metadata);\n await space.open(ctx);\n\n log('adding space...', { spaceKey });\n\n const credentials = await spaceGenesis(\n this._keyring,\n this.signingContext,\n space.inner,\n root.url,\n tags,\n options.membershipPolicy,\n createdSpace?.spaceRootUrl,\n );\n await this._metadataStore.addSpace(metadata);\n\n const memberCredential = credentials[1];\n invariant(\n getCredentialAssertion(memberCredential).$typeName === 'dxos.halo.credentials.SpaceMember',\n 'Invalid credential',\n );\n await this.signingContext.recordCredential(memberCredential);\n\n await space.initializeDataPipeline(ctx);\n\n log('space ready.', { spaceId, spaceKey });\n\n this.updated.emit();\n return space;\n }\n\n /**\n * Accepts an existing space by joining its swarm and initializing the data pipeline.\n * @param ctx - Caller context for cancellation and tracing.\n * @param opts - Space keys and optional timeframes for catch-up.\n */\n // TODO(burdon): Rename join space.\n @synchronized\n @trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })\n async acceptSpace(ctx: Context, opts: SpacesContract.AcceptSpaceOptions): Promise<DataSpace> {\n log('accept space', { opts });\n invariant(this._lifecycleState === LifecycleState.OPEN, 'Not open.');\n invariant(!this._spaces.has(opts.spaceKey), 'Space already exists.');\n invariant(!this.isSpaceDeleted(opts.spaceKey), 'Cannot accept a deleted space.');\n\n const tags = opts.tags ? Array.from(opts.tags) : [];\n const metadata: SpaceMetadata = create(SpaceMetadataSchema, {\n key: fromPublicKey(opts.spaceKey),\n spaceId: await createIdFromSpaceKey(opts.spaceKey),\n genesisFeedKey: fromPublicKey(opts.genesisFeedKey),\n controlTimeframe: opts.controlTimeframe && fromTimeframe(opts.controlTimeframe),\n dataTimeframe: opts.dataTimeframe && fromTimeframe(opts.dataTimeframe),\n tags,\n });\n\n const space = await this._constructSpace(ctx, metadata);\n await space.open(ctx);\n // Anchoring must adopt the root the inviter named rather than mint one, so remember it: a second\n // root over the same space would split its credential set, leaving members disagreeing about\n // which document carries the chain.\n if (opts.spaceRootUrl !== undefined && isValidAutomergeUrl(opts.spaceRootUrl)) {\n this._pendingSpaceRootUrls.set(space.id, opts.spaceRootUrl);\n }\n await this._metadataStore.addSpace(metadata);\n // Use DSM lifecycle ctx: the invitation accept flow disposes `ctx` as soon as\n // `acceptSpace` returns (guardedState.complete -> ctx.dispose). Detached data-pipeline\n // initialization must outlive the invitation flow, and its span must be parented to a\n // long-lived context.\n space.initializeDataPipelineAsync(this._ctx);\n\n this.updated.emit();\n return space;\n }\n\n /**\n * Mints a space root over a legacy space, transparently and idempotently, keeping its space id. Never\n * blocks opening the space: a space without an anchor still works, it just has not migrated yet.\n */\n /**\n * @returns Whether the space needs no further anchoring attempt — either because it is now anchored\n * or because it never will be. False means the attempt no-oped and the caller should retry, which a\n * space whose directory is not assigned yet depends on.\n */\n private async _anchorSpaceOnRootDocument(ctx: Context, space: DataSpace, force = false): Promise<boolean> {\n // Migrating a space is the opt-in behaviour, so without the flag a space keeps its control feed\n // and never grows a root. An explicit `migrateSpaceToRootDocument` call still forces it.\n if (!force && !this._automergeCredentials) {\n return true;\n }\n\n // A space created legacy stays unanchored for this session, or there would be no way to produce\n // the pre-migration state the migration path starts from. It anchors on the next load, which is\n // exactly the migration this project is for.\n if (!force && this._legacyCreatedSpaces.has(space.id)) {\n return true;\n }\n\n try {\n if (!this._echoHost.getSpaceRootRefs(space.id)) {\n // A root the inviter named is the space's only root; adopting it has to wait for it to\n // replicate rather than fall through to minting a second one over the same space.\n const named = this._pendingSpaceRootUrls.get(space.id);\n if (named !== undefined) {\n try {\n const refs = await this._echoHost.adoptSpaceRoot(ctx, space.id, named);\n this._pendingSpaceRootUrls.delete(space.id);\n log('adopted the space root named by the inviter', { spaceId: space.id, refs });\n } catch (err) {\n log('space root named by the inviter has not replicated yet', { spaceId: space.id, named, err });\n return false;\n }\n } else {\n const refs = await this._echoHost.migrateSpaceToRootDocument(ctx, space.id);\n if (!refs) {\n return false;\n }\n\n log('migrated space to root document', { spaceId: space.id, refs });\n }\n }\n\n // Re-checked after the adopt/migrate await: the anchor now runs on the manager's context, so a\n // space that started closing during it would otherwise still gain credentials and be reported.\n if (!this._isSpaceLive(space)) {\n return false;\n }\n\n // Unsettled when the mirror bailed on a closing space: latching would leave the credentials\n // half-written with nothing to retry it, since an anchored space never attempts again.\n if (!(await this._mirrorCredentialsToDocument(space))) {\n return false;\n }\n this._reportSpaceRootToEdge(space);\n return true;\n } catch (err) {\n log.warn('failed to anchor space on a root document', { spaceId: space.id, err });\n return false;\n }\n }\n\n /** Whether the anchor's background work may still act on this space. */\n private _isSpaceLive(space: DataSpace): boolean {\n return space.isOpen && !this._closingSpaces.has(space.id);\n }\n\n /**\n * Names the space root to edge, which cannot derive it from a space id that is the hash of the\n * space key, leaving the space on its control feed.\n */\n private _reportSpaceRootToEdge(space: DataSpace): void {\n const refs = this._echoHost.getSpaceRootRefs(space.id);\n if (!this._edgeHttpClient || !refs) {\n return;\n }\n\n // Retried in the background because edge rejects a root whose documents have not replicated to\n // it yet, and bound to the manager's own context because the invitation accept flow disposes\n // its ctx the moment `acceptSpace` returns, which would cancel every pending retry.\n let delay = SPACE_ROOT_REPORT_RETRY_INITIAL;\n const report = async (): Promise<void> => {\n // A retry outlives the attempt that scheduled it, so it has to re-check: a space closed or\n // removed in between must not be named to edge.\n if (!this._isSpaceLive(space)) {\n return;\n }\n try {\n await this._edgeHttpClient!.recordSpaceRoot(this._ctx, space.id, {\n rootDocumentUrl: refs.spaceRootDocUrl,\n });\n log('reported the space root to edge', { spaceId: space.id });\n } catch (err) {\n if (delay > SPACE_ROOT_REPORT_RETRY_MAX) {\n log.warn('gave up reporting the space root to edge', { spaceId: space.id, err });\n return;\n }\n\n log('space root not accepted by edge yet, retrying', { spaceId: space.id, delay, err });\n scheduleTask(this._ctx, report, delay);\n delay *= 2;\n }\n };\n\n scheduleTask(this._ctx, report);\n }\n\n /**\n * Mirrors the space's credentials into its credentials document. Subscribing to processed\n * credentials backfills the existing chain and dual-writes new ones through one path, since the\n * control pipeline replays the whole feed on open.\n */\n private async _mirrorCredentialsToDocument(space: DataSpace): Promise<boolean> {\n {\n // The manager's own context, not the caller's: the invitation flow disposes its context as\n // soon as `acceptSpace` returns, and a store bound to it would be released before its first\n // write — the same reason `initializeDataPipelineAsync` is parented here.\n const ctx = this._ctx;\n const store = await openCredentialsDocument(ctx, this._echoHost, space.id);\n if (!this._isSpaceLive(space)) {\n return false;\n }\n for (const credential of space.inner.spaceState.credentials) {\n store.append(credential);\n }\n\n ctx.onDispose(space.inner.credentialProcessed.on((credential) => store.append(credential)));\n\n // Read side: the document feeds the same state machine the feed does. Processing is idempotent\n // by credential id, so during the migration window both sources can run without conflict — a\n // space that has flipped simply stops gaining feed credentials.\n store.subscribe(ctx, (credential) => space.inner.processDocumentCredential(credential));\n return true;\n }\n }\n\n /**\n * Migrates a legacy space onto a space root document, keeping its id, and starts mirroring its\n * credentials into the document. Idempotent.\n */\n async migrateSpaceToRootDocument(ctx: Context, spaceKey: PublicKey): Promise<SpaceRootRefs> {\n const space = this._spaces.get(spaceKey) ?? failedInvariant();\n await this._anchorSpaceOnRootDocument(ctx, space, true);\n return this._echoHost.getSpaceRootRefs(space.id) ?? failedInvariant();\n }\n\n /**\n * Whether the space has been tombstoned (soft-deleted). Deleted spaces are never opened or replicated.\n */\n isSpaceDeleted(spaceKey: PublicKey): boolean {\n // Mirror the deletion predicate used in `_open`: the tombstone list or a persisted SPACE_DELETED state.\n return (\n this._metadataStore.deletedSpaces.some((key) => key.equals(spaceKey)) ||\n this._metadataStore.spaces.some(\n (spaceMetadata) =>\n requirePublicKey(spaceMetadata.key).equals(spaceKey) && spaceMetadata.state === SpaceState.SPACE_DELETED,\n )\n );\n }\n\n /**\n * Tombstones (soft-deletes) a space initiated locally on this device.\n * Records a SpaceDeleted credential in the HALO so the deletion replicates to the user's other devices,\n * then unloads the space locally. Data is not removed until garbage collection (future work).\n */\n @synchronized\n async markSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void> {\n if (this.isSpaceDeleted(spaceKey)) {\n return;\n }\n\n // Replicates to the user's other devices via the HALO control feed.\n const credential = await this.signingContext.credentialSigner.createCredential({\n subject: spaceKey,\n assertion: create(SpaceDeletedSchema, {\n spaceKey: fromPublicKey(spaceKey),\n deletedAt: fromDate(new Date()),\n }),\n });\n await this.signingContext.recordCredential(credential);\n\n await this._tombstoneSpace(ctx, spaceKey);\n }\n\n /**\n * Closes and tombstones every loaded space without writing SpaceDeleted credentials: used when the\n * identity itself is being deleted, so there is no HALO left to replicate the deletion to.\n */\n @synchronized\n async deleteAllSpaces(ctx: Context): Promise<void> {\n const spaces = [...this._spaces.values()].map((space) => ({ key: space.key, id: space.id }));\n log('deleting all spaces', { count: spaces.length });\n for (const { key, id } of spaces) {\n await this._tombstoneSpace(ctx, key);\n // Drops the host's in-memory state for the space as well as the tombstone, since the stack\n // stays open afterwards and would otherwise keep serving a space that no longer exists.\n await this._echoHost.removeSpace(id);\n }\n }\n\n /**\n * Tombstones a space in response to a SpaceDeleted credential replicated from another device.\n * Does not write a credential (one already exists in the HALO).\n */\n @synchronized\n async handleRemoteSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void> {\n if (this.isSpaceDeleted(spaceKey)) {\n return;\n }\n\n await this._tombstoneSpace(ctx, spaceKey);\n }\n\n /**\n * Persists the tombstone and unloads the space if it is currently loaded.\n * Must be called while holding the DataSpaceManager lock (see callers).\n */\n private async _tombstoneSpace(ctx: Context, spaceKey: PublicKey): Promise<void> {\n await this._metadataStore.addDeletedSpace(spaceKey);\n\n const space = this._spaces.get(spaceKey);\n if (space) {\n // Separate teardown (resource lifecycle) from the terminal state transition.\n if (space.isOpen) {\n // The tombstone above and the SpaceDeleted credential both already exist, so the deletion is\n // committed and the local state must reach it whatever the teardown does. Leaving the swarm\n // waits on the signaling server, which times out when EDGE is unreachable; letting that\n // reject would skip the two lines below and strand a closed space in the live list that\n // `isSpaceDeleted` then refuses to remove on a retry.\n await space.close(ctx).catch((err) => log.warn('space teardown failed; deleting anyway', { spaceKey, err }));\n }\n await space.delete();\n this._spaces.delete(spaceKey);\n }\n\n this.updated.emit();\n }\n\n async admitMember(options: SpacesContract.AdmitMemberOptions): Promise<Credential> {\n const space = this._spaceManager.spaces.get(options.spaceKey);\n invariant(space);\n\n if (space.spaceState.getMemberRole(options.identityKey) !== SpaceMemberRole.REMOVED) {\n throw new AlreadyJoinedError();\n }\n\n // Resolved here rather than at each call site: a caller that forgets it emits a credential the\n // admitted member cannot find the root from.\n const spaceRootUrl = options.spaceRootUrl ?? this._echoHost.getSpaceRootRefs(space.id)?.spaceRootDocUrl;\n\n // TODO(burdon): Check if already admitted.\n const credentials: FeedMessage_Payload[] = await createAdmissionCredentials({\n signer: this.signingContext.credentialSigner,\n identityKey: options.identityKey,\n spaceKey: space.key,\n genesisFeedKey: space.genesisFeedKey,\n role: options.role,\n membershipChainHeads: space.spaceState.membershipChainHeads,\n profile: options.profile,\n invitationCredentialId: options.delegationCredentialId,\n tags: space.spaceState.tags,\n spaceRootUrl,\n });\n\n // TODO(dmaretskyi): Refactor.\n const spaceMemberCredential = credentialOfPayload(credentials[0]);\n invariant(\n getCredentialAssertion(spaceMemberCredential).$typeName === 'dxos.halo.credentials.SpaceMember',\n 'Invalid credential',\n );\n await writeMessages(space.controlPipeline.writer, credentials);\n\n return spaceMemberCredential;\n }\n\n /**\n * Wait until the space data pipeline is fully initialized.\n * Used by invitation handler.\n * TODO(dmaretskyi): Consider removing.\n */\n async waitUntilSpaceReady(spaceKey: PublicKey): Promise<void> {\n await cancelWithContext(\n this._ctx,\n this.updated.waitForCondition(() => {\n const space = this._spaces.get(spaceKey);\n return !!space && space.state === SpaceState.SPACE_READY;\n }),\n );\n }\n\n public async requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential> {\n return this._spaceManager.requestSpaceAdmissionCredential(ctx, {\n spaceKey,\n identityKey: this.signingContext.identityKey,\n timeout: 15_000,\n swarmIdentity: {\n identityKey: this.signingContext.identityKey,\n peerKey: this.signingContext.deviceKey,\n credentialProvider: Auth.createAuthProvider(this.signingContext.credentialSigner),\n credentialAuthenticator: async () => true,\n },\n });\n }\n\n async setSpaceEdgeReplicationSetting(\n ctx: Context,\n spaceKey: PublicKey,\n setting: EdgeReplicationSetting,\n ): Promise<void> {\n const space = this._spaces.get(spaceKey);\n invariant(space, 'Space not found.');\n\n await this._metadataStore.setSpaceEdgeReplicationSetting(spaceKey, setting);\n\n if (space.isOpen) {\n switch (setting) {\n case EdgeReplicationSetting.DISABLED:\n await this._echoEdgeReplicator?.disconnectFromSpace(space.id);\n break;\n case EdgeReplicationSetting.ENABLED:\n await this._echoEdgeReplicator?.connectToSpace(ctx, space.id);\n break;\n }\n }\n\n space.stateUpdate.emit();\n }\n\n private async _constructSpace(ctx: Context, metadata: SpaceMetadata): Promise<DataSpace> {\n log('construct space', { metadata });\n const gossip = new Gossip({\n localPeerId: this.signingContext.deviceKey,\n });\n const presence = new Presence({\n announceInterval: this._runtimeProps?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,\n offlineTimeout: this._runtimeProps?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,\n identityKey: this.signingContext.identityKey,\n gossip,\n });\n\n const controlFeed =\n metadata.controlFeedKey &&\n (await this._hypercoreStore.openHypercore(requirePublicKey(metadata.controlFeedKey), { writable: true }));\n const dataFeed =\n metadata.dataFeedKey &&\n (await this._hypercoreStore.openHypercore(requirePublicKey(metadata.dataFeedKey), {\n writable: true,\n sparse: true,\n }));\n\n const space: Space = await this._spaceManager.constructSpace({\n metadata,\n swarmIdentity: {\n identityKey: this.signingContext.identityKey,\n peerKey: this.signingContext.deviceKey,\n credentialProvider: Auth.createAuthProvider(this.signingContext.credentialSigner),\n credentialAuthenticator: deferFunction(() => dataSpace.authVerifier.verifier),\n },\n onAuthorizedConnection: (session) =>\n queueMicrotask(async () => {\n try {\n if (!session.isOpen) {\n return;\n }\n session.addExtension('dxos.mesh.teleport.admission-discovery', new CredentialServerExtension(space));\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n gossip.createExtension({ remotePeerId: session.remotePeerId }),\n );\n session.addExtension('dxos.mesh.teleport.notarization', dataSpace.notarizationPlugin.createExtension());\n await this._connectEchoMeshReplicator(space, session);\n } catch (err: any) {\n log.warn('error on authorized connection', { err });\n await session.close(err);\n }\n }),\n onAuthFailure: () => {\n log.warn('auth failure');\n },\n onMemberRolesChanged: async (members: MemberInfo[]) => {\n if (dataSpace?.state === SpaceState.SPACE_READY) {\n this._handleMemberRoleChanges(presence, space.protocol, members);\n }\n },\n memberKey: this.signingContext.identityKey,\n onDelegatedInvitationStatusChange: (invitation, isActive) => {\n return this._handleInvitationStatusChange(dataSpace, invitation, isActive);\n },\n });\n controlFeed && (await space.setControlFeed(controlFeed));\n dataFeed && (await space.setDataFeed(dataFeed));\n\n const dataSpace = new DataSpace({\n inner: space,\n initialState: metadata.state === SpaceState.SPACE_INACTIVE ? SpaceState.SPACE_INACTIVE : SpaceState.SPACE_CLOSED,\n metadataStore: this._metadataStore,\n gossip,\n presence,\n keyring: this._keyring,\n hypercoreStore: this._hypercoreStore,\n echoHost: this._echoHost,\n signingContext: this.signingContext,\n callbacks: {\n beforeReady: async () => {\n log('before space ready', { space: space.key });\n },\n afterReady: async () => {\n log('after space ready', { space: space.key, open: this._lifecycleState === LifecycleState.OPEN });\n if (this._lifecycleState === LifecycleState.OPEN) {\n await this._createDelegatedInvitations(dataSpace, [...space.spaceState.invitations.entries()]);\n this._handleMemberRoleChanges(presence, space.protocol, [...space.spaceState.members.values()]);\n this.updated.emit();\n }\n },\n beforeClose: async () => {\n log('before space close', { space: space.key });\n },\n },\n tags: metadata.tags,\n edgeConnection: this._edgeConnection,\n edgeHttpClient: this._edgeHttpClient,\n edgeFeatures: this._edgeFeatures,\n activeEdgeNotarizationPollingInterval: this._runtimeProps?.activeEdgeNotarizationPollingInterval,\n });\n dataSpace.postOpen.append(async () => {\n const setting = dataSpace.getEdgeReplicationSetting();\n if (!setting || setting === EdgeReplicationSetting.ENABLED) {\n // Use lifecycle ctx: the caller ctx from _constructSpace may be disposed by the time postOpen fires.\n await this._echoEdgeReplicator?.connectToSpace(this._ctx, dataSpace.id);\n } else if (this._echoEdgeReplicator) {\n log('not connecting edge replicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });\n }\n });\n dataSpace.preClose.append(async () => {\n this._closingSpaces.add(dataSpace.id);\n const setting = dataSpace.getEdgeReplicationSetting();\n if (!setting || setting === EdgeReplicationSetting.ENABLED) {\n await this._echoEdgeReplicator?.disconnectFromSpace(dataSpace.id);\n }\n });\n\n presence.newPeer.on((peerState) => {\n if (dataSpace.state === SpaceState.SPACE_READY) {\n this._handleNewPeerConnected(space, peerState);\n }\n });\n\n if (metadata.controlTimeframe) {\n dataSpace.inner.controlPipeline.state.setTargetTimeframe(toTimeframe(metadata.controlTimeframe));\n }\n\n // Cleared on the way back up: a closed space can be activated again, and a stale mark would\n // leave it unanchorable for the session.\n dataSpace.stateUpdate.on(this._ctx, () => {\n if (dataSpace.isOpen) {\n this._closingSpaces.delete(dataSpace.id);\n }\n });\n\n // Anchoring materializes credential state, so it waits for the space to be open: a closed space\n // must stay unmaterialized or lazy loading is defeated. Every path that opens a space — load and\n // activate, create, accept — arrives here.\n // Latch only once the anchor has actually settled: migration no-ops while the space's directory is\n // unassigned, and latching on the attempt would strand the space unanchored for the whole session.\n let anchored = false;\n let anchoring = false;\n let retryDelay = ANCHOR_RETRY_INITIAL;\n const attemptAnchor = () => {\n if (anchored || anchoring || !dataSpace.isOpen) {\n return;\n }\n\n anchoring = true;\n // The manager's context, not the caller's: an accepted space arrives with the invitation's\n // context, which `acceptSpace` disposes on return, and the anchor's own awaits would be\n // cancelled under it.\n void this._anchorSpaceOnRootDocument(this._ctx, dataSpace)\n .then((settled) => {\n anchored = settled;\n if (settled) {\n return;\n }\n\n // What an unsettled attempt waits on — an unassigned directory, or a root named by an\n // inviter that has not replicated yet — arrives without emitting a space state update, so\n // nothing else would ever retry.\n if (retryDelay <= ANCHOR_RETRY_MAX) {\n scheduleTask(this._ctx, attemptAnchor, retryDelay);\n retryDelay *= 2;\n }\n })\n .finally(() => {\n anchoring = false;\n });\n };\n\n // Subscribed for the space's lifetime rather than the caller's: a root named by an inviter can\n // replicate long after the invitation context is gone, and its state update is what retries.\n const unsubscribeFromStateUpdate = dataSpace.stateUpdate.on(this._ctx, attemptAnchor);\n dataSpace.preClose.append(async () => unsubscribeFromStateUpdate());\n\n this._spaces.set(requirePublicKey(metadata.key), dataSpace);\n return dataSpace;\n }\n\n private async _connectEchoMeshReplicator(space: Space, session: Teleport): Promise<void> {\n const replicator = this._meshReplicator;\n if (!replicator) {\n log.warn('p2p automerge replication disabled', { space: space.key });\n return;\n }\n await replicator.authorizeDevice(space.id, session.remotePeerId);\n // session ended during device authorization\n if (session.isOpen) {\n session.addExtension('dxos.mesh.teleport.automerge', replicator.createExtension());\n }\n }\n\n private _handleMemberRoleChanges(presence: Presence, spaceProtocol: SpaceProtocol, memberInfo: MemberInfo[]): void {\n let closedSessions = 0;\n for (const member of memberInfo) {\n if (member.key.equals(presence.localIdentityKey)) {\n continue;\n }\n const peers = presence.getPeersByIdentityKey(member.key);\n const sessions = peers.map((peer) => {\n const peerId = toPublicKey(peer.peerId);\n return peerId && spaceProtocol.sessions.get(peerId);\n });\n const sessionsToClose = sessions.filter((s): s is SpaceProtocolSession => {\n return (s && (member.role === SpaceMemberRole.REMOVED) !== (s.authStatus === AuthStatus.FAILURE)) ?? false;\n });\n sessionsToClose.forEach((session) => {\n void session.close().catch(log.error);\n });\n closedSessions += sessionsToClose.length;\n }\n log('processed member role changes', {\n roleChangeCount: memberInfo.length,\n peersOnline: presence.getPeersOnline().length,\n closedSessions,\n });\n // Handle the case when there was a removed peer online, we can now establish a connection with them\n spaceProtocol.updateTopology();\n }\n\n private _handleNewPeerConnected(space: Space, peerState: PeerState): void {\n // `PeerState` is the wire message the gossip channel carries; the space state machine and\n // the session map are keyed by the domain key type.\n const identityKey = toPublicKey(peerState.identityKey);\n const peerId = toPublicKey(peerState.peerId);\n if (!identityKey) {\n return;\n }\n const role = space.spaceState.getMemberRole(identityKey);\n if (role === SpaceMemberRole.REMOVED) {\n const session = peerId && space.protocol.sessions.get(peerId);\n if (session != null) {\n log('closing a session with a removed peer', { peerId });\n void session.close().catch(log.error);\n }\n }\n }\n\n private async _handleInvitationStatusChange(\n dataSpace: DataSpace | undefined,\n delegatedInvitation: DelegateInvitationCredential,\n isActive: boolean,\n ): Promise<void> {\n if (dataSpace?.state !== SpaceState.SPACE_READY) {\n return;\n }\n if (isActive) {\n await this._createDelegatedInvitations(dataSpace, [\n [delegatedInvitation.credentialId, delegatedInvitation.invitation],\n ]);\n } else {\n await this._invitationsManager.cancelInvitation(delegatedInvitation.invitation);\n }\n }\n\n private async _createDelegatedInvitations(\n space: DataSpace,\n invitations: Array<[PublicKey, DelegateSpaceInvitation]>,\n ): Promise<void> {\n const tasks = invitations.map(([credentialId, invitation]) => {\n const expiresOn = toDate(invitation.expiresOn);\n return this._invitationsManager.createInvitation(this._ctx, {\n type: Invitation_Type.DELEGATED,\n kind: Invitation_Kind.SPACE,\n spaceKey: fromPublicKey(space.key),\n authMethod: invitation.authMethod,\n invitationId: invitation.invitationId,\n swarmKey: invitation.swarmKey,\n guestKeypair: invitation.guestKey\n ? buf.create(AdmissionKeypairSchema, { publicKey: invitation.guestKey })\n : undefined,\n lifetime: expiresOn && remainingLifetimeSeconds(expiresOn),\n multiUse: invitation.multiUse,\n delegationCredentialId: fromPublicKey(credentialId),\n persistent: false,\n });\n });\n await Promise.all(tasks);\n }\n}\n\n/**\n * Seconds left until `expiresOn`, as `Invitation.lifetime` requires: a whole number, because the\n * field is a protobuf `int32` and a fractional value fails to encode — which silently killed the\n * `queryInvitations` stream and hung client initialization. Floors to at least 1 since 0 means\n * \"never expires\", so an already-expired invitation must not become immortal.\n */\nexport const remainingLifetimeSeconds = (expiresOn: Date): number =>\n Math.max(1, Math.floor((expiresOn.getTime() - Date.now()) / 1000));\n\nexport type DataSpaceManagerLayerOptions = Pick<DataSpaceManagerProps, 'runtimeProps' | 'edgeFeatures'>;\n\n/**\n * Effect Layer constructing a dormant {@link DataSpaceManager}.\n */\nexport const DataSpaceManagerLayer = (\n options: DataSpaceManagerLayerOptions = {},\n): Layer.Layer<\n SpacesContract.ManagerService,\n never,\n | Hook.Controller\n | SpaceManagerService\n | IMetadataStoreService\n | KeyringApiService\n | SpacesContract.SigningContextProviderService\n | HypercoreStoreService\n | EchoHostService\n | InvitationsContract.ManagerService\n> =>\n Layer.effect(\n SpacesContract.ManagerService,\n Effect.gen(function* () {\n const spaceManager = yield* SpaceManagerService;\n const metadataStore = yield* IMetadataStoreService;\n const keyring = yield* KeyringApiService;\n const signingContextProvider = yield* SpacesContract.SigningContextProviderService;\n const hypercoreStore = yield* HypercoreStoreService;\n const echoHost = yield* EchoHostService;\n const invitationsManager = yield* InvitationsContract.ManagerService;\n const edgeConnection = yield* Effect.serviceOption(EdgeConnectionService);\n const edgeHttpClient = yield* Effect.serviceOption(EdgeHttpClientService);\n const meshReplicator = yield* Effect.serviceOption(MeshEchoReplicatorService);\n const echoEdgeReplicator = yield* Effect.serviceOption(EdgeAutomergeReplicatorService);\n\n const dataSpaceManager = new DataSpaceManager({\n spaceManager,\n metadataStore,\n keyring,\n signingContextProvider,\n hypercoreStore,\n echoHost,\n invitationsManager,\n edgeConnection: Option.getOrUndefined(edgeConnection),\n edgeHttpClient: Option.getOrUndefined(edgeHttpClient),\n meshReplicator: Option.getOrUndefined(meshReplicator),\n echoEdgeReplicator: Option.getOrUndefined(echoEdgeReplicator),\n ...options,\n });\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(() => dataSpaceManager.close(Context.default())));\n yield* Hook.on(\n Events.IdentityAvailable,\n Effect.fn('DataSpaceManager.onIdentityAvailable')(function* ({ identity }) {\n yield* Effect.promise(() => dataSpaceManager.open(ctx));\n yield* Hook.emit(Events.DataSpacesAvailable, { identity });\n }),\n );\n yield* Hook.on(\n Events.ProfileUpdated,\n Effect.fn('DataSpaceManager.onProfileUpdated')(function* ({ profile }) {\n for (const space of dataSpaceManager.spaces.values()) {\n yield* Effect.promise(() => space.updateOwnProfile(profile));\n }\n }),\n );\n return dataSpaceManager;\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { SpacesService } from '@dxos/protocols/rpc';\n\nconst JSON_EXTENSIONS = ['.dx.json', '.dx.json.gz', '.json'];\nconst BINARY_EXTENSIONS = ['.tar', '.tar.gz'];\n\n/**\n * Detect the format of a space archive.\n *\n * Uses filename extension as the primary signal, and falls back to sniffing\n * the first bytes of the archive contents to distinguish JSON from tar.\n */\nexport const detectSpaceArchiveFormat = (\n archive: Pick<SpacesService.SpaceArchive, 'filename' | 'contents'>,\n): SpacesService.SpaceArchiveFormat => {\n const filename = archive.filename?.toLowerCase() ?? '';\n if (JSON_EXTENSIONS.some((ext) => filename.endsWith(ext))) {\n return SpacesService.SpaceArchiveFormat.enums.JSON;\n }\n if (BINARY_EXTENSIONS.some((ext) => filename.endsWith(ext))) {\n return SpacesService.SpaceArchiveFormat.enums.BINARY;\n }\n\n // Fall back to byte sniffing: JSON archives start with '{' (0x7B) or whitespace.\n const bytes = archive.contents;\n if (bytes && bytes.length > 0) {\n for (let i = 0; i < Math.min(bytes.length, 16); i++) {\n const byte = bytes[i];\n // Skip whitespace.\n if (byte === 0x20 || byte === 0x09 || byte === 0x0a || byte === 0x0d) {\n continue;\n }\n if (byte === 0x7b /* '{' */) {\n return SpacesService.SpaceArchiveFormat.enums.JSON;\n }\n break;\n }\n }\n\n return SpacesService.SpaceArchiveFormat.enums.BINARY;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Obj, Type } from '@dxos/echo';\nimport { type SerializedSpace } from '@dxos/echo-client';\nimport { type DatabaseDirectory, type EntityStructure } from '@dxos/echo-protocol';\nimport { assertArgument } from '@dxos/invariant';\nimport { URI } from '@dxos/keys';\nimport { type SpacesService } from '@dxos/protocols/rpc';\n\nconst ATTR_TYPE = '@type';\nconst ATTR_META = '@meta';\nconst ATTR_DELETED = '@deleted';\nconst ATTR_PARENT = '@parent';\nconst ATTR_RELATION_SOURCE = '@relationSource';\nconst ATTR_RELATION_TARGET = '@relationTarget';\n\n/**\n * Type URI of the meta-schema (`TypeSchema` / `Type.Type`). Objects with this\n * `@type` represent persisted ECHO type definitions and must be branded\n * `system.kind = 'type'` so `Filter.type(Type.Type)` and `Type.isType` recognize\n * them after import. Anything else defaults to `'object'` (or `'relation'` when\n * source/target attrs are present).\n */\nconst TYPE_KIND_SCHEMA_URI = Type.getURI(Type.Type).toString();\n\nconst INTERNAL_KEYS: ReadonlySet<string> = new Set([\n 'id',\n ATTR_TYPE,\n ATTR_META,\n ATTR_DELETED,\n ATTR_PARENT,\n ATTR_RELATION_SOURCE,\n ATTR_RELATION_TARGET,\n]);\n\n/**\n * Parse a JSON space archive.\n *\n * The archive contents are expected to be the UTF-8 encoding of\n * `JSON.stringify(serializedSpace)`.\n */\nexport const readSerializedSpaceArchive = (archive: SpacesService.SpaceArchive): SerializedSpace => {\n const text = new TextDecoder().decode(archive.contents);\n const parsed = JSON.parse(text) as SerializedSpace;\n assertArgument(typeof parsed === 'object' && parsed !== null, 'archive', 'Invalid JSON archive payload');\n assertArgument(typeof parsed.version === 'number', 'archive', 'Missing SerializedSpace.version');\n assertArgument(Array.isArray(parsed.objects), 'archive', 'Missing SerializedSpace.objects');\n return parsed;\n};\n\n/**\n * Convert an {@link Obj.JSON} back into an internal {@link EntityStructure} suitable\n * for embedding into a {@link DatabaseDirectory}.\n */\nexport const objJsonToObjectStructure = (obj: Obj.JSON): EntityStructure => {\n const data: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (INTERNAL_KEYS.has(key)) {\n continue;\n }\n data[key] = value;\n }\n\n const system: NonNullable<EntityStructure['system']> = {};\n\n const type = obj[ATTR_TYPE];\n if (type) {\n system.type = { '/': URI.make(type) };\n }\n\n const parent = (obj as any)[ATTR_PARENT];\n if (typeof parent === 'string') {\n system.parent = { '/': URI.make(parent) };\n }\n\n const relationSource = (obj as any)[ATTR_RELATION_SOURCE];\n const relationTarget = (obj as any)[ATTR_RELATION_TARGET];\n if (typeof relationSource === 'string' || typeof relationTarget === 'string') {\n system.kind = 'relation';\n if (typeof relationSource === 'string') {\n system.source = { '/': URI.make(relationSource) };\n }\n if (typeof relationTarget === 'string') {\n system.target = { '/': URI.make(relationTarget) };\n }\n // TODO(wittjosiah): This is fragile, will break if the type URI changes.\n } else if (type === TYPE_KIND_SCHEMA_URI) {\n system.kind = 'type';\n } else {\n system.kind = 'object';\n }\n\n if ((obj as any)[ATTR_DELETED]) {\n system.deleted = true;\n }\n\n const meta = (obj as any)[ATTR_META];\n return {\n system,\n meta: {\n keys: meta?.keys ?? [],\n ...(meta?.tags ? { tags: meta.tags } : {}),\n // Preserve registry-provenance fields so persisted `Type.Type` entities\n // round-trip with their typename / semver (see the symmetric write in\n // `objectStructureToObjJson`).\n ...(meta?.key !== undefined ? { key: meta.key } : {}),\n ...(meta?.version !== undefined ? { version: meta.version } : {}),\n // Preserve annotations (see the symmetric write in `objectStructureToObjJson`).\n ...(meta?.annotations ? { annotations: meta.annotations } : {}),\n },\n data,\n };\n};\n\n/**\n * Build a new {@link DatabaseDirectory} containing every object from the archive,\n * keyed by object id. The caller is responsible for stamping the `access` (space id/key)\n * and version fields after the document is created.\n */\nexport const buildDatabaseDirectoryFromObjects = (objects: readonly Obj.JSON[]): DatabaseDirectory => {\n const map: Record<string, EntityStructure> = {};\n for (const obj of objects) {\n map[obj.id] = objJsonToObjectStructure(obj);\n }\n return {\n objects: map,\n links: {},\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type AutomergeUrl } from '@automerge/automerge-repo';\nimport * as Effect from 'effect/Effect';\nimport * as Exit from 'effect/Exit';\nimport * as Scope from 'effect/Scope';\n\nimport { Context } from '@dxos/context';\nimport { type SpecificCredential } from '@dxos/credentials';\nimport { type Obj } from '@dxos/echo';\nimport { type SerializedFeed, type SerializedSpace } from '@dxos/echo-client';\nimport { type DatabaseRoot, type EchoHost } from '@dxos/echo-host';\nimport { type DatabaseDirectory, type EntityStructure } from '@dxos/echo-protocol';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { assertState, invariant } from '@dxos/invariant';\nimport { DXN, type EntityId, type IdentityDid, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { FeedProtocol, makeInProcessClient } from '@dxos/protocols';\nimport { type Epoch } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { FeedService, SpacesService } from '@dxos/protocols/rpc';\nimport { createFilename } from '@dxos/util';\n\n/**\n * The part of a live space an archive is written from; structural so that the exporter\n * does not depend on the space implementation.\n */\nexport type ExportableSpace = {\n readonly id: SpaceId;\n readonly automergeSpaceState: { readonly lastEpoch: SpecificCredential<Epoch> | undefined };\n readonly databaseRoot: DatabaseRoot | null;\n};\n\nconst SERIALIZED_SPACE_VERSION = 1;\n\nconst FEED_TYPENAME = 'org.dxos.type.feed';\n\nconst ATTR_ID = 'id';\nconst ATTR_TYPE = '@type';\nconst ATTR_META = '@meta';\nconst ATTR_DELETED = '@deleted';\nconst ATTR_PARENT = '@parent';\nconst ATTR_RELATION_SOURCE = '@relationSource';\nconst ATTR_RELATION_TARGET = '@relationTarget';\n\n/**\n * Canonical order of well-known system fields in a serialized object.\n * All remaining `@*` fields follow in the order they appear on the source\n * object, and finally the data fields are appended in their existing order.\n */\nconst SYSTEM_FIELD_ORDER: readonly string[] = [\n ATTR_ID,\n ATTR_TYPE,\n ATTR_META,\n ATTR_DELETED,\n ATTR_PARENT,\n ATTR_RELATION_SOURCE,\n ATTR_RELATION_TARGET,\n];\n\n/**\n * Reorder the keys of an {@link Obj.JSON} so that system fields appear first\n * (`id`, `@type`, `@meta`, then any other `@*` attributes), followed by data\n * fields. The returned object has identical values to the input — only the key\n * iteration order changes.\n */\nexport const orderObjJsonFields = (obj: Obj.JSON): Obj.JSON => {\n const source = obj as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of SYSTEM_FIELD_ORDER) {\n if (key in source) {\n result[key] = source[key];\n }\n }\n for (const key of Object.keys(source)) {\n if (key.startsWith('@') && !(key in result)) {\n result[key] = source[key];\n }\n }\n for (const key of Object.keys(source)) {\n if (!(key in result)) {\n result[key] = source[key];\n }\n }\n return result as Obj.JSON;\n};\n\nexport type WriteSerializedSpaceArchiveOptions = {\n space: ExportableSpace;\n echoHost: EchoHost;\n exportedBy?: IdentityDid;\n};\n\n/**\n * Write a JSON space archive from a live space.\n *\n * This runs entirely inside the worker and walks automerge documents directly —\n * it does not require a client-side {@link EchoDatabase}. The output conforms to\n * {@link SerializedSpace} and is compatible with the JSON format consumed by the\n * importer in {@link readSerializedSpaceArchive}.\n */\nexport const writeSerializedSpaceArchive = async (\n options: WriteSerializedSpaceArchiveOptions,\n): Promise<SpacesService.SpaceArchive> => {\n const { space, echoHost, exportedBy } = options;\n\n const rootUrl = space.automergeSpaceState.lastEpoch?.assertion.automergeRoot;\n assertState(rootUrl, 'Space does not have a root URL');\n const databaseRoot = space.databaseRoot;\n assertState(databaseRoot, 'Space database root is not ready');\n\n const rootDoc = databaseRoot.doc();\n invariant(rootDoc, 'Space database root document is not loaded');\n\n // Collect all object structures across the root doc and any linked docs.\n const objects: Obj.JSON[] = [];\n collectObjectsFromDoc(rootDoc, objects);\n\n for (const linkedUrl of databaseRoot.getAllLinkedDocuments()) {\n using lease = await echoHost.loadDoc<DatabaseDirectory>(Context.default(), linkedUrl as AutomergeUrl);\n if (!lease) {\n log.warn('linked document handle not available; skipping', { url: linkedUrl });\n continue;\n }\n collectObjectsFromDoc(lease.doc(), objects);\n }\n\n // Export queue/feed messages for every Feed object in the space.\n const feeds = await exportFeedData(space, echoHost, objects);\n\n const serialized: SerializedSpace = {\n version: SERIALIZED_SPACE_VERSION,\n timestamp: new Date().toISOString(),\n originalSpaceId: space.id,\n exportedBy,\n createdAt: Date.now(),\n objects,\n ...(feeds.length > 0 ? { feeds } : {}),\n };\n\n const encoded = new TextEncoder().encode(JSON.stringify(serialized));\n return {\n filename: createFilename({ parts: [space.id], ext: 'dx.json' }),\n contents: encoded,\n format: SpacesService.SpaceArchiveFormat.enums.JSON,\n };\n};\n\nconst collectObjectsFromDoc = (doc: DatabaseDirectory, out: Obj.JSON[]): void => {\n const docObjects = doc.objects ?? {};\n for (const [objectId, structure] of Object.entries(docObjects)) {\n out.push(objectStructureToObjJson(objectId, structure));\n }\n};\n\n/**\n * Convert an internal {@link EntityStructure} into an {@link Obj.JSON}.\n *\n * Unlike the equivalent helper used for indexing, this preserves the object's\n * `@meta` section so archives produced by this writer can be round-tripped\n * through {@link Obj.fromJSON}.\n */\nexport const objectStructureToObjJson = (objectId: string, structure: EntityStructure): Obj.JSON => {\n const result: Record<string, unknown> = {\n [ATTR_ID]: objectId,\n [ATTR_TYPE]: (structure.system?.type?.['/'] ?? '') as any,\n };\n\n if (structure.meta) {\n result[ATTR_META] = {\n keys: structure.meta.keys ?? [],\n ...(structure.meta.tags ? { tags: structure.meta.tags } : {}),\n // Preserve the registry-provenance fields (typename / semver) so persisted\n // `Type.Type` entities round-trip with their `meta.key` / `meta.version`\n // intact — `Type.getTypename` / `Type.getVersion` read these. Without them\n // a type loaded from an archive would fall back to its object id.\n ...(structure.meta.key !== undefined ? { key: structure.meta.key } : {}),\n ...(structure.meta.version !== undefined ? { version: structure.meta.version } : {}),\n // Preserve annotations (e.g. `AppAnnotation.RootCollectionAnnotation` on a space's\n // properties object) so archives round-trip app-level metadata, not just schema data.\n ...(structure.meta.annotations && Object.keys(structure.meta.annotations).length > 0\n ? { annotations: structure.meta.annotations }\n : {}),\n };\n }\n if (structure.system?.deleted) {\n result[ATTR_DELETED] = true;\n }\n if (structure.system?.parent) {\n result[ATTR_PARENT] = structure.system.parent['/'];\n }\n if (structure.system?.source) {\n result[ATTR_RELATION_SOURCE] = structure.system.source['/'];\n }\n if (structure.system?.target) {\n result[ATTR_RELATION_TARGET] = structure.system.target['/'];\n }\n Object.assign(result, structure.data);\n\n return result as Obj.JSON;\n};\n\nconst exportFeedData = async (\n space: ExportableSpace,\n echoHost: EchoHost,\n objects: Obj.JSON[],\n): Promise<SerializedFeed[]> => {\n const feeds: SerializedFeed[] = [];\n const spaceId: SpaceId = space.id;\n\n for (const obj of objects) {\n if (obj[ATTR_TYPE] == null) {\n continue;\n }\n\n const typeDxn = obj[ATTR_TYPE];\n const typeDxnNsid = DXN.isDXN(typeDxn) ? DXN.getName(typeDxn) : undefined;\n if (typeDxnNsid !== FEED_TYPENAME) {\n continue;\n }\n\n const namespace = (obj as any).namespace === 'trace' ? 'trace' : 'data';\n\n try {\n const messages = await collectFeedMessages(echoHost, spaceId, obj.id, namespace);\n if (messages.length > 0) {\n feeds.push({\n feedObjectId: obj.id,\n namespace,\n messages,\n });\n }\n } catch (err) {\n log.warn('failed to export feed data', { feedObjectId: obj.id, error: err });\n }\n }\n\n return feeds;\n};\n\nconst collectFeedMessages = async (\n echoHost: EchoHost,\n spaceId: SpaceId,\n feedId: EntityId,\n namespace: string,\n): Promise<Obj.JSON[]> => {\n const feedNamespace =\n namespace === 'trace' ? FeedProtocol.WellKnownNamespaces.trace : FeedProtocol.WellKnownNamespaces.data;\n\n const messages: Obj.JSON[] = [];\n let cursor: string | undefined;\n\n // Bridge the host feed Handlers to a client to call it in-process (Handlers are served, not\n // called directly). The scope owns the client for the duration of the read.\n const scope = Effect.runSync(Scope.make());\n const feedClient = await EffectEx.runPromise(\n makeInProcessClient(FeedService.Rpcs, echoHost.feedService).pipe(Effect.provideService(Scope.Scope, scope)),\n );\n try {\n while (true) {\n const result = await EffectEx.runPromise(\n feedClient['FeedService.queryFeed']({\n query: {\n spaceId,\n feedIds: [feedId],\n feedNamespace,\n after: cursor,\n },\n }),\n );\n const batch = (result.objects ?? []).flatMap((encoded): Obj.JSON[] => {\n try {\n return [JSON.parse(encoded) as Obj.JSON];\n } catch (err) {\n log.verbose('feed object JSON parse failed; object ignored', { encoded, error: err });\n return [];\n }\n });\n if (batch.length === 0) {\n break;\n }\n for (const message of batch) {\n messages.push(orderObjJsonFields(message));\n }\n if (!result.nextCursor || result.nextCursor === cursor) {\n break;\n }\n cursor = result.nextCursor;\n }\n } finally {\n await EffectEx.runPromise(Scope.close(scope, Exit.void));\n }\n return messages;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport type { DocumentId } from '@automerge/automerge-repo';\n\nimport { assertArgument, invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport {\n type FeedArchiveBlock,\n type FeedArchiveMetadata,\n SpaceArchiveFileStructure,\n type SpaceArchiveMetadata,\n} from '@dxos/protocols';\nimport type { SpacesService } from '@dxos/protocols/rpc';\n\n/**\n * Extracted feed data from the archive.\n */\nexport type ExtractedFeed = {\n metadata: FeedArchiveMetadata;\n blocks: FeedArchiveBlock[];\n};\n\nexport type ExtractedSpaceArchive = {\n metadata: SpaceArchiveMetadata;\n documents: Record<DocumentId, Uint8Array>;\n feeds: Record<string, ExtractedFeed>;\n};\n\nexport const extractSpaceArchive = async (archive: SpacesService.SpaceArchive): Promise<ExtractedSpaceArchive> => {\n const { Archive } = await import('@obsidize/tar-browserify');\n const { entries } = await Archive.extract(archive.contents);\n const metadataEntry = entries.find((entry) => entry.fileName === SpaceArchiveFileStructure.metadata);\n assertArgument(metadataEntry, 'metadataEntry', 'Metadata entry not found');\n const metadata = JSON.parse(metadataEntry.getContentAsText());\n const documents: Record<DocumentId, Uint8Array> = {};\n for (const entry of entries.filter((entry) => entry.fileName.startsWith(`${SpaceArchiveFileStructure.documents}/`))) {\n const documentId = entry.fileName\n .replace(`${SpaceArchiveFileStructure.documents}/`, '')\n .replace(/\\.bin$/, '') as DocumentId;\n invariant(!documentId.includes('/'));\n // The reader leaves `content` null for a zero-byte entry, which an export writes for a document with no local chunks.\n if (!entry.content || entry.content.byteLength === 0) {\n log.warn('skipping empty document in space archive', { documentId });\n continue;\n }\n documents[documentId] = entry.content;\n }\n\n const feeds: Record<string, ExtractedFeed> = {};\n const feedsPrefix = `${SpaceArchiveFileStructure.feeds}/`;\n const feedEntries = entries.filter((entry) => entry.fileName.startsWith(feedsPrefix));\n\n const feedMetadataByFeedId = new Map<string, FeedArchiveMetadata>();\n const feedBlocksByFeedId = new Map<string, Map<number, FeedArchiveBlock[]>>();\n\n for (const entry of feedEntries) {\n const relativePath = entry.fileName.slice(feedsPrefix.length);\n const pathParts = relativePath.split('/');\n if (pathParts.length !== 2) {\n continue;\n }\n\n const [feedId, fileName] = pathParts;\n invariant(feedId, 'Feed ID is required');\n invariant(fileName, 'File name is required');\n\n if (fileName === SpaceArchiveFileStructure.feedMetadata) {\n const feedMetadata = JSON.parse(entry.getContentAsText()) as FeedArchiveMetadata;\n feedMetadataByFeedId.set(feedId, feedMetadata);\n } else if (fileName.startsWith(SpaceArchiveFileStructure.feedBlocksPrefix) && fileName.endsWith('.json')) {\n const chunkIndexStr = fileName.slice(SpaceArchiveFileStructure.feedBlocksPrefix.length).replace(/\\.json$/, '');\n const chunkIndex = parseInt(chunkIndexStr, 10);\n invariant(!isNaN(chunkIndex), `Invalid chunk index: ${chunkIndexStr}`);\n\n const blocks = JSON.parse(entry.getContentAsText()) as FeedArchiveBlock[];\n if (!feedBlocksByFeedId.has(feedId)) {\n feedBlocksByFeedId.set(feedId, new Map());\n }\n feedBlocksByFeedId.get(feedId)!.set(chunkIndex, blocks);\n }\n }\n\n for (const [feedId, feedMetadata] of feedMetadataByFeedId) {\n const blockChunks = feedBlocksByFeedId.get(feedId) ?? new Map<number, FeedArchiveBlock[]>();\n const sortedChunkIndices = Array.from(blockChunks.keys()).sort((a, b) => a - b);\n const allBlocks: FeedArchiveBlock[] = [];\n for (const chunkIndex of sortedChunkIndices) {\n allBlocks.push(...blockChunks.get(chunkIndex)!);\n }\n feeds[feedId] = {\n metadata: feedMetadata,\n blocks: allBlocks,\n };\n }\n\n log('extracted space archive', { metadata, documents, feedCount: Object.keys(feeds).length });\n return { metadata, documents, feeds };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as tar from '@obsidize/tar-browserify';\n\nimport { type Context, Resource } from '@dxos/context';\nimport { assertArgument, assertState } from '@dxos/invariant';\nimport type { IdentityDid, SpaceId } from '@dxos/keys';\nimport {\n FEED_ARCHIVE_BLOCKS_PER_CHUNK,\n type FeedArchiveBlock,\n type FeedArchiveMetadata,\n SpaceArchiveFileStructure,\n type SpaceArchiveMetadata,\n SpaceArchiveVersion,\n} from '@dxos/protocols';\nimport { SpacesService } from '@dxos/protocols/rpc';\nimport { createFilename } from '@dxos/util';\n\nexport type SpaceArchiveBeginProps = {\n spaceId?: SpaceId;\n\n /**\n * DID of the identity that exported the space.\n */\n exportedBy?: IdentityDid;\n};\n\nconst CURRENT_VERSION = SpaceArchiveVersion.V1;\n\nexport class SpaceArchiveWriter extends Resource {\n private _tar?: typeof tar;\n private _archive?: tar.Archive;\n\n private _meta?: SpaceArchiveBeginProps = undefined;\n private _currentRootUrl?: string = undefined;\n\n protected override async _open(ctx: Context): Promise<void> {\n this._tar = await import('@obsidize/tar-browserify');\n }\n\n protected override async _close(): Promise<void> {\n return Promise.resolve();\n }\n\n async begin(meta: SpaceArchiveBeginProps): Promise<void> {\n assertState(this._tar, 'Not open');\n assertState(!this._meta, 'Already started');\n this._meta = meta;\n this._archive = new this._tar.Archive();\n }\n\n async setCurrentRootUrl(url: string): Promise<void> {\n assertArgument(url.startsWith('automerge:'), 'url', 'Invalid root URL');\n assertState(this._tar, 'Not open');\n assertState(this._meta, 'Not started');\n this._currentRootUrl = url;\n }\n\n async writeDocument(documentId: string, data: Uint8Array): Promise<void> {\n assertArgument(!documentId.startsWith('automerge:'), 'documentId', 'Invalid document ID');\n assertState(this._archive, 'Not open');\n this._archive.addBinaryFile(`${SpaceArchiveFileStructure.documents}/${documentId}.bin`, data);\n }\n\n /**\n * Writes a feed with its metadata and blocks to the archive.\n * Blocks are written in chunks of {@link FEED_ARCHIVE_BLOCKS_PER_CHUNK}.\n */\n async writeFeed(feedId: string, namespace: string, blocks: FeedArchiveBlock[]): Promise<void> {\n assertArgument(feedId, 'feedId', 'Feed ID is required');\n assertArgument(namespace, 'namespace', 'Namespace is required');\n assertState(this._archive, 'Not open');\n\n const feedPath = `${SpaceArchiveFileStructure.feeds}/${feedId}`;\n\n const metadata: FeedArchiveMetadata = {\n id: feedId,\n namespace,\n };\n this._archive.addTextFile(`${feedPath}/${SpaceArchiveFileStructure.feedMetadata}`, JSON.stringify(metadata));\n\n for (let chunkIndex = 0; chunkIndex * FEED_ARCHIVE_BLOCKS_PER_CHUNK < blocks.length; chunkIndex++) {\n const start = chunkIndex * FEED_ARCHIVE_BLOCKS_PER_CHUNK;\n const end = Math.min(start + FEED_ARCHIVE_BLOCKS_PER_CHUNK, blocks.length);\n const chunk = blocks.slice(start, end);\n this._archive.addTextFile(\n `${feedPath}/${SpaceArchiveFileStructure.feedBlocksPrefix}${chunkIndex}.json`,\n JSON.stringify(chunk),\n );\n }\n }\n\n async finish(): Promise<SpacesService.SpaceArchive> {\n assertState(this._archive, 'Not open');\n assertState(this._meta, 'Not started');\n assertState(this._meta.spaceId, 'No space ID set');\n assertState(this._currentRootUrl, 'No root URL set');\n\n const metadata: SpaceArchiveMetadata = {\n version: CURRENT_VERSION,\n createdAt: Date.now(),\n exportedBy: this._meta.exportedBy,\n originalSpaceId: this._meta.spaceId,\n echo: {\n currentRootUrl: this._currentRootUrl,\n },\n };\n\n this._archive.addTextFile(SpaceArchiveFileStructure.metadata, JSON.stringify(metadata));\n\n const binary = this._archive.toUint8Array();\n\n return {\n filename: createFilename({ parts: [this._meta.spaceId], ext: 'tar' }),\n contents: binary,\n format: SpacesService.SpaceArchiveFormat.enums.BINARY,\n };\n }\n}\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport type { AutomergeUrl } from '@automerge/automerge-repo';\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { SubscriptionList, UpdateScheduler, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport {\n type CredentialProcessor,\n createAdmissionCredentials,\n createDidFromIdentityKey,\n credentialOfPayload,\n credentialPayload,\n getCredentialAssertion,\n} from '@dxos/credentials';\nimport { raise } from '@dxos/debug';\nimport { type EchoHost, EchoHostService } from '@dxos/echo-host';\nimport { type DatabaseDirectory } from '@dxos/echo-protocol';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { BaseError } from '@dxos/errors';\nimport { writeMessages } from '@dxos/feed-store';\nimport { assertArgument, assertState, invariant } from '@dxos/invariant';\nimport { SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n ApiError,\n AuthorizationError,\n FeedProtocol,\n IdentityNotInitializedError,\n SpaceNotFoundError,\n encodeError,\n makeInProcessClient,\n toServiceError,\n} from '@dxos/protocols';\nimport { buf, fromPublicKey, fromTimeframe, requirePublicKey } from '@dxos/protocols/buf';\nimport { SpaceState } from '@dxos/protocols/buf/dxos/client/invitation_pb';\nimport {\n type ContactAdmission,\n ContactAdmissionSchema,\n type CreateEpochResponse,\n CreateEpochResponseSchema,\n IdentitySchema,\n type JoinSpaceResponse,\n JoinSpaceResponseSchema,\n type QuerySpacesResponse,\n QuerySpacesResponseSchema,\n type Space,\n Space_PipelineStateSchema,\n type SpaceMember,\n SpaceMember_PresenceState,\n SpaceMemberSchema,\n SpaceSchema,\n} from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\nimport { FeedService, SpacesService } from '@dxos/protocols/rpc';\nimport { trace } from '@dxos/tracing';\nimport { type Provider } from '@dxos/util';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Readiness from '../../Readiness.ts';\nimport {\n SpaceArchiveWriter,\n detectSpaceArchiveFormat,\n extractSpaceArchive,\n objJsonToObjectStructure,\n readSerializedSpaceArchive,\n writeSerializedSpaceArchive,\n} from '../space-export/index.ts';\nimport { type SpaceManager, SpaceManagerService } from '../space/index.ts';\nimport { type DataSpace } from './data-space.ts';\n\n/** Reads the space as the buf message the service returns. */\n\nexport class SpacesServiceImpl implements SpacesService.Handlers {\n 'constructor'(\n private readonly _identityManager: IdentityContract.Manager,\n private readonly _spaceManager: SpaceManager,\n private readonly _echoHost: EchoHost,\n private readonly _getDataSpaceManager: Provider<Promise<SpacesContract.Manager>>,\n ) {}\n\n ['SpacesService.createSpace'](request: SpacesService.CreateSpaceRequest): Effect.Effect<Space, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n this._requireIdentity();\n const ctx = new Context();\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = await dataSpaceManager.createSpace(ctx, {\n tags: request?.tags,\n membershipPolicy: request?.membershipPolicy,\n });\n await this._updateMetrics();\n return this._serializeSpace(space);\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.updateSpace']({\n spaceKey,\n state,\n edgeReplication,\n }: SpacesService.UpdateSpaceRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n\n if (state) {\n switch (state) {\n case SpaceState.SPACE_ACTIVE:\n await space.activate(ctx);\n break;\n\n case SpaceState.SPACE_INACTIVE:\n await space.deactivate(ctx);\n break;\n\n case SpaceState.SPACE_DELETED:\n await dataSpaceManager.markSpaceDeleted(ctx, spaceKey);\n // The space is removed from the manager; skip any further mutations (e.g. edgeReplication).\n return;\n default:\n throw new ApiError({ message: 'Invalid space state' });\n }\n }\n\n if (edgeReplication !== undefined) {\n await dataSpaceManager.setSpaceEdgeReplicationSetting(ctx, spaceKey, edgeReplication);\n }\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.updateMemberRole'](request: SpacesService.UpdateMemberRoleRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const identity = this._requireIdentity();\n const space = this._spaceManager.spaces.get(request.spaceKey);\n if (space == null) {\n throw new SpaceNotFoundError(request.spaceKey);\n }\n if (!space.spaceState.hasMembershipManagementPermission(identity.identityKey)) {\n throw new AuthorizationError({\n message: 'No member management permission.',\n context: {\n spaceKey: space.key,\n role: space.spaceState.getMemberRole(identity.identityKey),\n },\n });\n }\n const credentials = await createAdmissionCredentials({\n signer: identity.getIdentityCredentialSigner(),\n identityKey: request.memberKey,\n spaceKey: space.key,\n genesisFeedKey: space.genesisFeedKey,\n role: request.newRole,\n membershipChainHeads: space.spaceState.membershipChainHeads,\n });\n const spaceMemberCredential = credentialOfPayload(credentials[0]);\n invariant(\n getCredentialAssertion(spaceMemberCredential).$typeName === 'dxos.halo.credentials.SpaceMember',\n 'Invalid credential',\n );\n await writeMessages(space.controlPipeline.writer, credentials);\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.querySpaces'](): EffectStream.Stream<QuerySpacesResponse, Error> {\n return EffectEx.streamFromEmitter<QuerySpacesResponse, Error>((emit) => {\n const ctx = Context.default();\n const scheduler = new UpdateScheduler(\n ctx,\n async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n const spaces = await Promise.all(\n Array.from(dataSpaceManager.spaces.values()).map((space) => this._serializeSpace(space)),\n );\n log('update', () => ({ ids: spaces.map((space) => space.id) }));\n await this._updateMetrics();\n void emit.single(buf.create(QuerySpacesResponseSchema, { spaces }));\n },\n { maxFrequency: process.env.NODE_ENV === 'test' ? undefined : 2 },\n );\n\n scheduleTask(ctx, async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n\n const subscriptions = new SubscriptionList();\n ctx.onDispose(() => subscriptions.clear());\n\n // TODO(dmaretskyi): Create a pattern for subscribing to a set of objects.\n const subscribeSpaces = () => {\n subscriptions.clear();\n\n for (const space of dataSpaceManager.spaces.values()) {\n let lastState: SpaceState | undefined;\n subscriptions.add(\n space.stateUpdate.on(ctx, () => {\n // Always send a separate update if the space state has changed.\n if (space.state !== lastState) {\n scheduler.forceTrigger();\n } else {\n scheduler.trigger();\n }\n lastState = space.state;\n }),\n );\n\n subscriptions.add(space.presence.updated.on(ctx, () => scheduler.trigger()));\n subscriptions.add(space.automergeSpaceState.onNewEpoch.on(ctx, () => scheduler.trigger()));\n\n // Pipeline progress.\n subscriptions.add(space.inner.controlPipeline.state.timeframeUpdate.on(ctx, () => scheduler.trigger()));\n }\n };\n\n dataSpaceManager.updated.on(ctx, () => {\n subscribeSpaces();\n scheduler.trigger();\n });\n subscribeSpaces();\n\n scheduler.trigger();\n });\n\n if (!this._identityManager.identity) {\n void emit.single(buf.create(QuerySpacesResponseSchema, { spaces: [] }));\n }\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['SpacesService.postMessage']({\n spaceKey,\n channel,\n message,\n }: SpacesService.PostMessageRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n invariant(message, 'Post carries no message.');\n await space.postMessage(getChannelId(channel), message);\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.subscribeMessages']({\n spaceKey,\n channel,\n }: SpacesService.SubscribeMessagesRequest): EffectStream.Stream<SpacesService.SubscribeMessagesResponse, Error> {\n return EffectStream.unwrap(\n Effect.promise(() => this._getDataSpaceManager()).pipe(\n Effect.map((dataSpaceManager) =>\n EffectEx.streamFromEmitter<SpacesService.SubscribeMessagesResponse, Error>((emit) => {\n const space = dataSpaceManager.spaces.get(spaceKey);\n if (!space) {\n emit.fail(new SpaceNotFoundError(spaceKey));\n return;\n }\n const handle = space.listen(getChannelId(channel), (message) => emit.single({ _tag: 'Message', message }));\n emit.single({ _tag: 'Ready' });\n return Effect.sync(() => handle.unsubscribe());\n }),\n ),\n ),\n );\n }\n\n ['SpacesService.queryCredentials']({\n spaceKey,\n noTail,\n }: SpacesService.QueryCredentialsRequest): EffectStream.Stream<Credential, Error> {\n return EffectEx.streamFromEmitter<Credential, Error>((emit) => {\n const ctx = Context.default();\n const space = this._spaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n\n const processor: CredentialProcessor = {\n processCredential: async (credential) => {\n void emit.single(credential);\n },\n };\n ctx.onDispose(() => space.spaceState.removeCredentialProcessor(processor));\n scheduleTask(ctx, async () => {\n await space.spaceState.addCredentialProcessor(processor);\n if (noTail) {\n void emit.end();\n }\n });\n\n return Effect.promise(() => ctx.dispose());\n });\n }\n\n ['SpacesService.writeCredentials']({\n spaceKey,\n credentials,\n }: SpacesService.WriteCredentialsRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const space = this._spaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n for (const bufCredential of credentials ?? []) {\n const credential = bufCredential;\n if (credential.proof) {\n await space.controlPipeline.writer.write(credentialPayload(credential));\n } else {\n invariant(!credential.id, 'Id on unsigned credentials is not allowed');\n invariant(this._identityManager.identity, 'Identity is not available');\n const signer = this._identityManager.identity.getIdentityCredentialSigner();\n const subject = credential.subject;\n invariant(subject?.assertion, 'Credential has no assertion.');\n invariant(requirePublicKey(credential.issuer).equals(signer.getIssuer()));\n const signedCredential = await signer.createCredential({\n subject: requirePublicKey(subject.id),\n assertion: getCredentialAssertion(credential),\n });\n await space.controlPipeline.writer.write(credentialPayload(signedCredential));\n }\n }\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.createEpoch']({\n spaceKey,\n migration,\n automergeRootUrl,\n }: SpacesService.CreateEpochRequest): Effect.Effect<CreateEpochResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));\n const result = await space.createEpoch({ migration, newAutomergeRoot: automergeRootUrl });\n return buf.create(CreateEpochResponseSchema, {\n epochCredential: result?.credential,\n controlTimeframe: result?.timeframe && fromTimeframe(result.timeframe),\n });\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.admitContact'](request: SpacesService.AdmitContactRequest): Effect.Effect<void, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const dataSpaceManager = await this._getDataSpaceManager();\n await dataSpaceManager.admitMember({\n spaceKey: request.spaceKey,\n identityKey: requirePublicKey(request.contact?.identityKey),\n role: request.role,\n // Record the profile the host already knows, so the member is named before they first join.\n profile: request.contact?.profile,\n });\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.joinBySpaceKey']({\n spaceKey,\n }: SpacesService.JoinBySpaceKeyRequest): Effect.Effect<JoinSpaceResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n const dataSpaceManager = await this._getDataSpaceManager();\n const credential = await dataSpaceManager.requestSpaceAdmissionCredential(ctx, spaceKey);\n return this._joinByAdmission(ctx, create(ContactAdmissionSchema, { credential }));\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.exportSpace'](\n request: SpacesService.ExportSpaceRequest,\n ): Effect.Effect<SpacesService.ExportSpaceResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n assertArgument(SpaceId.isValid(request.spaceId), 'spaceId', 'Invalid space ID');\n\n const dataSpaceManager = await this._getDataSpaceManager();\n const space = dataSpaceManager.getSpaceById(request.spaceId) ?? raise(new Error('Space not found'));\n\n const format = request.format ?? SpacesService.SpaceArchiveFormat.enums.BINARY;\n if (format === SpacesService.SpaceArchiveFormat.enums.JSON) {\n const archive = await writeSerializedSpaceArchive({ space, echoHost: this._echoHost });\n return { archive };\n }\n\n await using writer = await new SpaceArchiveWriter().open();\n await writer.begin({ spaceId: space.id });\n const rootUrl = space.automergeSpaceState.lastEpoch?.assertion.automergeRoot;\n assertState(rootUrl, 'Space does not have a root URL');\n await writer.setCurrentRootUrl(rootUrl);\n\n for await (const [documentId, data] of space.getAllDocuments()) {\n // A linked document never persisted locally exports as zero bytes, which no importer can load.\n if (data.byteLength === 0) {\n log.warn('skipping document with no local data in space export', { spaceId: space.id, documentId });\n continue;\n }\n await writer.writeDocument(documentId, data);\n }\n\n const feeds = await space.getAllFeeds();\n for (const feed of feeds) {\n const archiveBlocks = feed.blocks.map((block) => ({\n actorId: block.actorId,\n sequence: block.sequence,\n prevActorId: block.prevActorId,\n prevSequence: block.prevSequence,\n position: block.position,\n timestamp: block.timestamp,\n data: Buffer.from(block.data).toString('base64'),\n }));\n await writer.writeFeed(feed.feedId, feed.feedNamespace, archiveBlocks);\n }\n\n const archive = await writer.finish();\n return { archive };\n },\n catch: toServiceError,\n });\n }\n\n ['SpacesService.importSpace'](\n request: SpacesService.ImportSpaceRequest,\n ): Effect.Effect<SpacesService.ImportSpaceResponse, BaseError> {\n return Effect.tryPromise({\n try: async () => {\n const ctx = Context.default();\n const dataSpaceManager = await this._getDataSpaceManager();\n\n const format = request.archive.format ?? detectSpaceArchiveFormat(request.archive);\n if (format === SpacesService.SpaceArchiveFormat.enums.JSON) {\n const serialized = readSerializedSpaceArchive(request.archive);\n const space = await dataSpaceManager.createSpace(ctx, { tags: request.tags });\n await this._hydrateSpaceFromSerialized(space, serialized);\n await this._updateMetrics();\n return { newSpaceId: space.id };\n }\n\n const extracted = await extractSpaceArchive(request.archive);\n invariant(extracted.metadata.echo?.currentRootUrl, 'Space archive does not contain a root URL');\n const space = await dataSpaceManager.createSpace(ctx, {\n documents: extracted.documents,\n rootUrl: extracted.metadata.echo?.currentRootUrl as AutomergeUrl,\n tags: request.tags,\n });\n await this._updateMetrics();\n return { newSpaceId: space.id };\n },\n catch: toServiceError,\n });\n }\n\n /**\n * Populate a freshly-created space with the objects and feed messages described in a {@link SerializedSpace}.\n *\n * Objects are written directly into the space's automerge root document as inline\n * {@link EntityStructure} entries; feed messages are appended to the appropriate feed\n * via {@link EchoHost.feedService}.\n */\n private async '_hydrateSpaceFromSerialized'(\n space: DataSpace,\n serialized: ReturnType<typeof readSerializedSpaceArchive>,\n ): Promise<void> {\n const databaseRoot = space.databaseRoot;\n assertState(databaseRoot, 'Space database root is not ready');\n\n databaseRoot.change((doc: DatabaseDirectory) => {\n if (!doc.objects) {\n doc.objects = {};\n }\n for (const obj of serialized.objects) {\n doc.objects[obj.id] = objJsonToObjectStructure(obj);\n }\n });\n\n for (const feed of serialized.feeds ?? []) {\n if (feed.messages.length === 0) {\n continue;\n }\n\n const namespace =\n feed.namespace === 'trace' ? FeedProtocol.WellKnownNamespaces.trace : FeedProtocol.WellKnownNamespaces.data;\n try {\n // Handlers are served, not called directly; bridge to a client in-process for this write.\n const feedService = this._echoHost.feedService;\n await EffectEx.runPromise(\n Effect.gen(function* () {\n const feedClient = yield* makeInProcessClient(FeedService.Rpcs, feedService);\n yield* feedClient['FeedService.insertIntoFeed']({\n spaceId: space.id,\n feedId: feed.feedObjectId,\n subspaceTag: namespace,\n objects: feed.messages.map((message) => JSON.stringify(message)),\n });\n }).pipe(Effect.scoped),\n );\n } catch (err) {\n log.warn('failed to import feed data', { feedObjectId: feed.feedObjectId, error: err });\n }\n }\n }\n\n private async '_joinByAdmission'(ctx: Context, { credential }: ContactAdmission): Promise<JoinSpaceResponse> {\n invariant(credential, 'Admission carries no credential.');\n const assertion = getCredentialAssertion(credential);\n invariant(assertion.$typeName === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');\n const myIdentity = this._identityManager.identity;\n invariant(myIdentity && requirePublicKey(credential.subject?.id).equals(myIdentity.identityKey));\n\n const spaceKey = requirePublicKey(assertion.spaceKey);\n const dataSpaceManager = await this._getDataSpaceManager();\n let dataSpace = dataSpaceManager.spaces.get(spaceKey);\n if (!dataSpace) {\n dataSpace = await dataSpaceManager.acceptSpace(ctx, {\n spaceKey,\n genesisFeedKey: requirePublicKey(assertion.genesisFeedKey),\n tags: assertion.tags,\n });\n await myIdentity.controlPipeline.writer.write(credentialPayload(credential));\n }\n\n return buf.create(JoinSpaceResponseSchema, { space: await this._serializeSpace(dataSpace) });\n }\n\n private async '_serializeSpace'(space: DataSpace): Promise<Space> {\n const lastEpoch = space.automergeSpaceState.lastEpoch?.credential;\n return buf.create(SpaceSchema, {\n id: space.id,\n spaceKey: fromPublicKey(space.key),\n state: space.state,\n error: space.error ? encodeError(space.error) : undefined,\n pipeline: create(Space_PipelineStateSchema, {\n currentEpoch: lastEpoch,\n appliedEpoch: lastEpoch,\n\n controlFeeds: space.inner.controlPipeline.state.feeds.map((feed) => fromPublicKey(feed.key)),\n currentControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.timeframe),\n targetControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.targetTimeframe),\n totalControlTimeframe: fromTimeframe(space.inner.controlPipeline.state.endTimeframe),\n\n directoryUrl: space.databaseRoot?.url,\n }),\n members: await Promise.all(\n Array.from(space.inner.spaceState.members.values()).map(async (member): Promise<SpaceMember> => {\n const peers = space.presence.getPeersByIdentityKey(member.key);\n const isMe = this._identityManager.identity?.identityKey.equals(member.key);\n\n if (isMe) {\n peers.push(space.presence.getLocalState());\n }\n\n return create(SpaceMemberSchema, {\n identity: create(IdentitySchema, {\n did: await createDidFromIdentityKey(member.key),\n identityKey: fromPublicKey(member.key),\n profile: member.profile,\n }),\n role: member.role,\n presence: peers.length > 0 ? SpaceMember_PresenceState.ONLINE : SpaceMember_PresenceState.OFFLINE,\n peerStates: peers,\n });\n }),\n ),\n creator: space.inner.spaceState.creator && fromPublicKey(space.inner.spaceState.creator.key),\n tags: space.tags,\n membershipPolicy: space.membershipPolicy,\n metrics: space.metrics,\n edgeReplication: space.getEdgeReplicationSetting(),\n });\n }\n\n private '_requireIdentity'() {\n if (!this._identityManager.identity) {\n throw new IdentityNotInitializedError({\n message: 'This device has no HALO identity available. See https://docs.dxos.org/guide/platform/halo',\n });\n }\n return this._identityManager.identity;\n }\n\n private async '_updateMetrics'(): Promise<void> {\n const dataSpaceManager = await this._getDataSpaceManager();\n const identity = this._identityManager.identity?.identityKey.truncate();\n if (identity) {\n trace.metrics.gauge('dxos.echo.space.count', dataSpaceManager.spaces.size, {\n tags: { identity },\n });\n }\n }\n}\n\nexport const SpacesServiceLayer: Layer.Layer<\n SpacesService.Tag,\n never,\n | IdentityContract.ManagerService\n | SpaceManagerService\n | EchoHostService\n | SpacesContract.ManagerService\n | Readiness.StackReadinessService\n> = Layer.effect(\n SpacesService.Tag,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const spaceManager = yield* SpaceManagerService;\n const echoHost = yield* EchoHostService;\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const readiness = yield* Readiness.StackReadinessService;\n return new SpacesServiceImpl(identityManager, spaceManager, echoHost, () =>\n readiness.initialized.wait().then(() => dataSpaceManager),\n );\n }),\n);\n\n// Add `user-channel` prefix to the channel name, so that it doesn't collide with the internal channels.\nconst getChannelId = (channel: string): string => `user-channel/${channel}`;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport type * as SqlClient from 'effect/sql/SqlClient';\n\nimport * as ComputeSqlService from '@dxos/compute/SqlService';\nimport { SqlService } from '@dxos/protocols/rpc';\n\nconst toWireRow = (row: ComputeSqlService.Row): Record<string, SqlService.SqlValue> =>\n Object.fromEntries(Object.entries(row).map(([column, value]) => [column, SqlService.toSqlValue(value)]));\n\n/**\n * Serves `SqlService` RPCs from the host's shared database through the sanitizing backend.\n */\nexport const SqlServiceLayer: Layer.Layer<SqlService.Tag, never, SqlClient.SqlClient> = Layer.effect(\n SqlService.Tag,\n Effect.gen(function* () {\n const backend = yield* ComputeSqlService.SqlService;\n const handlers: SqlService.Handlers = {\n 'SqlService.execute': (request) =>\n backend.execute(request).pipe(Effect.map((rows) => ({ rows: rows.map(toWireRow) }))),\n 'SqlService.begin': (request) => backend.begin(request),\n 'SqlService.commit': (request) => backend.commit(request),\n 'SqlService.rollback': (request) => backend.rollback(request),\n };\n return handlers;\n }),\n).pipe(Layer.provide(ComputeSqlService.layerGuarded), Layer.orDie);\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Fiber from 'effect/Fiber';\nimport * as Layer from 'effect/Layer';\nimport * as EffectStream from 'effect/Stream';\n\nimport { Event, MulticastObservable } from '@dxos/async';\nimport { type Config, ConfigService } from '@dxos/config';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { BaseError } from '@dxos/errors';\nimport { log } from '@dxos/log';\nimport { SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { toServiceError } from '@dxos/protocols';\nimport { type Platform, SystemStatus } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Config as ConfigProto, ConfigSchema } from '@dxos/protocols/buf/dxos/config_pb';\nimport { SystemService } from '@dxos/protocols/rpc';\nimport { RpcRouter } from '@dxos/rpc';\nimport { type MaybePromise, jsonKeyReplacer } from '@dxos/util';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Events from '../../Events.ts';\nimport * as PlatformInfo from '../../PlatformInfo.ts';\nimport { type Diagnostics, createDiagnosticsFromRouter } from '../diagnostics/index.ts';\n\nexport type SystemServiceOptions = {\n config?: () => MaybePromise<Config | undefined>;\n getDiagnostics: () => Promise<Partial<Diagnostics['services']>>;\n /**\n * The embedder's controller, which outlives the stack; a reset is the\n * `Closing → WipingStorage → Reset` chain on it.\n */\n controller: Hook.ControllerService;\n};\n\n/**\n * The one client service that exists while the host is closed: it reports and drives the host's\n * status and performs a reset. The host pushes its status in via {@link setStatus}.\n */\nexport class SystemServiceImpl implements SystemService.Handlers {\n /** A client asked for the host to become this status; the host decides what to do about it. */\n readonly 'statusRequested' = new Event<SystemStatus>();\n\n readonly #statusChanged = new Event<SystemStatus>();\n readonly #status = MulticastObservable.from(this.#statusChanged, SystemStatus.INACTIVE);\n readonly #options: SystemServiceOptions;\n #resetting = false;\n #resetFiber: Fiber.Fiber<void> | undefined;\n\n 'constructor'(options: SystemServiceOptions) {\n this.#options = options;\n }\n\n get 'status'(): SystemStatus {\n return this.#status.get();\n }\n\n /**\n * Reports the host's status to subscribers. Ignored once a reset is under way: that status is\n * final because the app reloads.\n */\n 'setStatus'(status: SystemStatus): void {\n if (this.#resetting) {\n return;\n }\n this.#statusChanged.emit(status);\n }\n\n /**\n * Runs the reset chain: the embedder closes the stack, wipes its storage, and reloads. Reports\n * inactive first so the app falls back at once, and that status is never cleared because the app\n * reloads.\n */\n 'reset'(): Effect.Effect<void> {\n const chain = Effect.gen({ self: this }, function* () {\n log.info('resetting...');\n this.#resetting = true;\n this.#statusChanged.emit(SystemStatus.INACTIVE);\n // `Closing` tears the stack down under this very call, and under any request another session\n // has in flight: component finalizers are not re-entrant against live traffic. That holds only\n // because every embedder shuts down or reloads immediately after `Reset` below — a reset that\n // left the worker serving would need a gate that fails new requests from here on.\n yield* Hook.emit(Events.Closing, undefined);\n yield* Hook.emit(Events.WipingStorage, undefined);\n log.info('reset');\n yield* Hook.emit(Events.Reset, undefined);\n }).pipe(Effect.provideService(Hook.Controller, this.#options.controller));\n\n // Detached from the request fiber: `Closing` above closes the RPC route this very call is\n // served on, which would interrupt the chain before it ever wipes storage. Joining keeps the\n // caller's timing — the join is interrupted, the chain is not.\n //\n // Single-flight over that fiber, because the RPC server dispatches concurrently and a detached\n // chain no longer dies with its caller: a second `reset` would otherwise emit the whole\n // `Closing`/`WipingStorage`/`Reset` sequence again, against a stack the first one already tore\n // down. The fork and the assignment share one synchronous step, so no caller observes the gap.\n return Effect.gen({ self: this }, function* () {\n this.#resetFiber ??= yield* Effect.forkDetach(chain);\n yield* Fiber.join(this.#resetFiber);\n });\n }\n\n ['SystemService.getConfig'](): Effect.Effect<ConfigProto, BaseError> {\n return Effect.tryPromise({\n try: async () => (await this.#options.config?.())?.values ?? create(ConfigSchema, {}),\n catch: toServiceError,\n });\n }\n\n /**\n * NOTE: Since this is serialized as a JSON object, we allow the option to serialize keys.\n */\n ['SystemService.getDiagnostics']({ keys }: SystemService.GetDiagnosticsRequest = {}): Effect.Effect<\n SystemService.GetDiagnosticsResponse,\n Error\n > {\n return Effect.tryPromise({\n try: async () => {\n const diagnostics = await this.#options.getDiagnostics();\n return {\n timestamp: new Date(),\n diagnostics: JSON.parse(\n JSON.stringify(\n diagnostics,\n jsonKeyReplacer({\n truncate: keys === SystemService.KeyOption.enums.TRUNCATE,\n humanize: keys === SystemService.KeyOption.enums.HUMANIZE,\n }),\n ),\n ),\n };\n },\n catch: toServiceError,\n });\n }\n\n ['SystemService.getPlatform'](): Effect.Effect<Platform, BaseError> {\n return Effect.tryPromise({\n try: async () => PlatformInfo.getPlatform(),\n catch: toServiceError,\n });\n }\n\n ['SystemService.updateStatus']({ status }: SystemService.UpdateStatusRequest): Effect.Effect<void, BaseError> {\n return Effect.sync(() => this.statusRequested.emit(status));\n }\n\n // TODO(burdon): Standardize interval option in stream request?\n ['SystemService.queryStatus']({ interval = 3_000 }: SystemService.QueryStatusRequest = {}): EffectStream.Stream<\n SystemService.QueryStatusResponse,\n Error\n > {\n return EffectEx.streamFromEmitter<SystemService.QueryStatusResponse, Error>((emit) => {\n const subscription = this.#status.subscribe((status) => void emit.single({ status }));\n // Clients treat a silent stream as a dead worker, so the current status is repeated.\n const heartbeat = setInterval(() => void emit.single({ status: this.#status.get() }), interval);\n return Effect.sync(() => {\n clearInterval(heartbeat);\n subscription.unsubscribe();\n });\n });\n }\n\n ['SystemService.reset'](): Effect.Effect<void, BaseError> {\n return this.reset();\n }\n}\n\n/**\n * Serves the {@link SystemService} over the stack's domain handlers: active once the stack has\n * opened, inactive when the layer is torn down, and resetting over the embedder's controller.\n */\nexport const SystemServiceLayer: Layer.Layer<\n SystemService.Tag,\n never,\n | RpcRouter.RpcRouter\n | ConfigService\n | Hook.Controller\n | IdentityContract.ManagerService\n | SpacesContract.ManagerService\n | SwarmNetworkManagerService\n> = Layer.effect(\n SystemService.Tag,\n Effect.gen(function* () {\n const config = yield* ConfigService;\n const controller = yield* Hook.Controller;\n const router = yield* RpcRouter.RpcRouter;\n const stack = yield* Effect.context<\n IdentityContract.ManagerService | SpacesContract.ManagerService | SwarmNetworkManagerService\n >();\n const service = new SystemServiceImpl({\n config: () => config,\n getDiagnostics: () => createDiagnosticsFromRouter(router, stack, config),\n controller,\n });\n yield* Hook.on(Events.StackOpened, () => Effect.sync(() => service.setStatus(SystemStatus.ACTIVE)));\n yield* Effect.addFinalizer(() => Effect.sync(() => service.setStatus(SystemStatus.INACTIVE)));\n return service;\n }),\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { type Context, type Lifecycle, Resource } from '@dxos/context';\nimport { type CredentialProcessor, getCredentialAssertion } from '@dxos/credentials';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { assertState } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { requirePublicKey } from '@dxos/protocols/buf';\nimport { type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\n\n/**\n * Replicates cross-device space membership and deletion credentials from the halo space.\n */\nexport interface CrossDeviceSpaceSynchronizer extends CredentialProcessor, Lifecycle {\n readonly identity: Identity | undefined;\n setIdentity(identity: Identity): void;\n}\n\n/**\n * Effect service tag for {@link CrossDeviceSpaceSynchronizer}.\n */\nexport class CrossDeviceSpaceSynchronizerService extends EffectContext.Service<\n CrossDeviceSpaceSynchronizerService,\n CrossDeviceSpaceSynchronizer\n>()('@dxos/client-services/CrossDeviceSpaceSynchronizer') {}\n\nclass CrossDeviceSpaceSynchronizerImpl extends Resource implements CrossDeviceSpaceSynchronizer {\n private _identity?: Identity;\n\n constructor(private readonly dataSpaceManager: SpacesContract.Manager) {\n super();\n }\n\n get identity(): Identity | undefined {\n return this._identity;\n }\n\n setIdentity(identity: Identity): void {\n this._identity = identity;\n }\n\n protected override async _open(ctx: Context): Promise<void> {\n assertState(this._identity, 'identity not set');\n await this._identity.space.spaceState.addCredentialProcessor(this);\n }\n\n protected override async _close(ctx: Context): Promise<void> {\n if (!this._identity) {\n return;\n }\n await this._identity.space.spaceState.removeCredentialProcessor(this);\n }\n\n async processCredential(credential: Credential): Promise<void> {\n assertState(this._identity, 'identity not set');\n const assertion = getCredentialAssertion(credential);\n\n // A space was tombstoned on another device: replicate the deletion locally.\n if (assertion.$typeName === 'dxos.halo.credentials.SpaceDeleted') {\n const spaceKey = requirePublicKey(assertion.spaceKey);\n if (spaceKey.equals(this._identity.space.key)) {\n // ignore halo space\n return;\n }\n if (!this.dataSpaceManager) {\n log('dataSpaceManager not initialized yet, ignoring space deletion', { details: assertion });\n return;\n }\n\n try {\n log('tombstoning space recorded in halo', { details: assertion });\n await this.dataSpaceManager.handleRemoteSpaceDeleted(this._ctx, spaceKey);\n } catch (err) {\n log.catch(err);\n }\n return;\n }\n\n if (assertion.$typeName !== 'dxos.halo.credentials.SpaceMember') {\n return;\n }\n const spaceKey = requirePublicKey(assertion.spaceKey);\n if (spaceKey.equals(this._identity.space.key)) {\n // ignore halo space\n return;\n }\n if (!this.dataSpaceManager) {\n log('dataSpaceManager not initialized yet, ignoring space admission', { details: assertion });\n return;\n }\n // Do not re-accept a space that has been tombstoned (handles out-of-order credential replay).\n if (this.dataSpaceManager.isSpaceDeleted(spaceKey)) {\n log('space is deleted, ignoring space admission', { details: assertion });\n return;\n }\n if (this.dataSpaceManager.spaces.has(spaceKey)) {\n log('space already exists, ignoring space admission', { details: assertion });\n return;\n }\n\n try {\n log('accepting space recorded in halo', { details: assertion });\n await this.dataSpaceManager.acceptSpace(this._ctx, {\n spaceKey,\n genesisFeedKey: requirePublicKey(assertion.genesisFeedKey),\n spaceRootUrl: assertion.spaceRootUrl,\n tags: assertion.tags,\n });\n } catch (err) {\n log.catch(err);\n }\n }\n}\n\n/**\n * Creates a dormant {@link CrossDeviceSpaceSynchronizer} bound to the given data space manager.\n */\nexport const createCrossDeviceSpaceSynchronizer = (\n dataSpaceManager: SpacesContract.Manager,\n): CrossDeviceSpaceSynchronizer => new CrossDeviceSpaceSynchronizerImpl(dataSpaceManager);\n\n/**\n * Effect Layer constructing a dormant {@link CrossDeviceSpaceSynchronizer}.\n */\nexport const CrossDeviceSpaceSynchronizerLayer: Layer.Layer<\n CrossDeviceSpaceSynchronizerService,\n never,\n Hook.Controller | SpacesContract.ManagerService\n> = Layer.effect(\n CrossDeviceSpaceSynchronizerService,\n Effect.gen(function* () {\n const dataSpaceManager = yield* SpacesContract.ManagerService;\n const synchronizer = createCrossDeviceSpaceSynchronizer(dataSpaceManager);\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(async () => synchronizer.close?.()));\n yield* Hook.on(\n Events.DataSpacesAvailable,\n Effect.fn('CrossDeviceSpaceSynchronizer.onDataSpacesAvailable')(function* ({ identity }) {\n if (synchronizer.identity === identity) {\n return;\n }\n // Rebound on every identity: after an in-place deletion the next one arrives while this is\n // still open on the deleted identity's HALO, which would never admit the new one's spaces.\n yield* Effect.promise(async () => synchronizer.close?.());\n synchronizer.setIdentity(identity);\n yield* Effect.promise(async () => synchronizer.open?.(ctx));\n }),\n );\n return synchronizer;\n }),\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { Encoder, decode as cborXdecode } from 'cbor-x';\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Schema from 'effect/Schema';\nimport * as SqlClient from 'effect/sql/SqlClient';\n\nimport { AsyncTask, scheduleTask } from '@dxos/async';\nimport { Context, Resource } from '@dxos/context';\nimport { EchoHostService } from '@dxos/echo-host';\nimport { type EdgeConnection, EdgeConnectionService, MessageSchema } from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { type FeedStore, SyncClient, SyncSpaceDeletedError } from '@dxos/feed';\nimport { invariant } from '@dxos/invariant';\nimport { SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { SystemError } from '@dxos/protocols';\nimport { FeedProtocol } from '@dxos/protocols';\nimport { EdgeService } from '@dxos/protocols';\nimport { createBuf } from '@dxos/protocols/buf';\nimport { EdgeStatus_ConnectionState } from '@dxos/protocols/buf/dxos/client/services_pb';\nimport { type Message as RouterMessage } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { bufferToArray } from '@dxos/util';\n\nimport * as Events from '../../Events.ts';\n\nconst encoder = new Encoder({ tagUint8Array: false, useRecords: false });\n\nconst DEFAULT_MESSAGE_BLOCKS_LIMIT = 50;\nconst DEFAULT_SYNC_CONCURRENCY = 5;\nconst DEFAULT_POLLING_INTERVAL = 5_000;\n/**\n * Full-poll interval used once the server has answered the subscribe handshake, and is therefore\n * pushing {@link FeedProtocol.FeedAdvanced} hints. Hints carry the latency, so the poll degrades to\n * a reconcile that only has to catch hints lost to an un-acked send or a socket closing mid-frame.\n */\nconst DEFAULT_RECONCILE_POLLING_INTERVAL = 30_000;\n/** Re-subscribe this long before the server's stated expiry, so a refresh never races the lapse. */\nconst SUBSCRIPTION_REFRESH_MARGIN_MS = 5 * 60_000;\nconst DEFAULT_POLL_REQUEST_THROTTLE_MS = 250;\nconst DEFAULT_FAILURE_BACKOFF_MS = 250;\nconst MAX_FAILURE_BACKOFF_MS = 30_000;\nconst MAX_BLOCKING_SYNC_ITERATIONS = 100;\n\nexport type FeedSyncerOptions = {\n runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n feedStore: FeedStore;\n edgeClient: EdgeConnection;\n peerId: string;\n getSpaceIds: () => SpaceId[];\n\n /**\n * Namespaces to sync.\n */\n syncNamespaces: string[];\n\n /**\n * Maximum number of blocks to sync in a single message.\n * @default 50\n */\n messageBlocksLimit?: number;\n\n /**\n * Maximum number of spaces to sync concurrently.\n * @default 5\n */\n syncConcurrency?: number;\n\n /**\n * Interval between full polls while the server is not known to push hints.\n * @default 5 seconds\n */\n pollingInterval?: number;\n\n /**\n * Interval between full polls once the server has answered the subscribe handshake and is pushing\n * {@link FeedProtocol.FeedAdvanced} hints.\n * @default 30 seconds\n */\n reconcilePollingInterval?: number;\n\n /**\n * Minimum delay between externally requested best-effort polls.\n * @default 250 ms\n */\n pollRequestThrottleMs?: number;\n\n /**\n * When false, only wires the edge message handler; poll/push background tasks and\n * `feedStore.onNewBlocks` auto-push are disabled. Use for tests that call `syncBlocking` explicitly.\n * @default true\n */\n backgroundSync?: boolean;\n\n /**\n * Max time to wait for a feed sync RPC response from edge, in milliseconds.\n * @default 30000 (see `DEFAULT_SYNC_RPC_TIMEOUT_MS` in `@dxos/feed`).\n */\n syncRpcTimeoutMs?: number;\n};\n\n/**\n * Effect service tag for {@link FeedSyncer}.\n *\n * undefined if not initialized.\n */\nexport class FeedSyncerService extends EffectContext.Service<FeedSyncerService, FeedSyncer | undefined>()(\n '@dxos/client-services/FeedSyncer',\n) {}\n\nexport class FeedSyncer extends Resource {\n readonly #syncNamespaces: string[];\n readonly #messageBlocksLimit: number;\n readonly #syncConcurrency: number;\n readonly #pollingInterval: number;\n readonly #reconcilePollingInterval: number;\n readonly #pollRequestThrottleMs: number;\n readonly #backgroundSync: boolean;\n\n readonly #runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient>;\n readonly #feedStore: FeedStore;\n readonly #edgeClient: EdgeConnection;\n readonly #syncClient: SyncClient;\n readonly #getSpaceIds: () => SpaceId[];\n\n #spacesToPoll = new Set<SpaceId>();\n /**\n * Spaces the server reported deleted on this connection. Nothing addressed to them is answered, so\n * a request only waits out its timeout and holds the run for every other space; they are left out\n * until the next reconnect, when the report is trusted afresh.\n */\n readonly #deletedSpaces = new Set<SpaceId>();\n /** Last time full poll was completed. */\n #lastFullPoll: number | null = null;\n #throttledPollScheduled = false;\n #lastRequestedPollAt: number | null = null;\n #pushFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n #pullFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n\n /**\n * True once the server answered a `SubscribeRequest` on the current connection, which is the only\n * evidence that it will push hints. An older EDGE ignores the request, so the interval must stay\n * at {@link #pollingInterval} rather than relaxing on a hint that will never arrive. Cleared on\n * reconnect, since the next socket may land on a different build.\n */\n #serverPushesHints = false;\n /** Earliest `expiresAt` across live subscriptions; drives the refresh task. */\n #subscriptionExpiresAt: number | null = null;\n\n constructor(options: FeedSyncerOptions) {\n super();\n this.#runtime = options.runtime;\n this.#feedStore = options.feedStore;\n this.#edgeClient = options.edgeClient;\n this.#syncClient = new SyncClient({\n peerId: options.peerId,\n feedStore: options.feedStore,\n sendMessage: this.#sendMessage.bind(this),\n rpcTimeoutMs: options.syncRpcTimeoutMs,\n });\n this.#getSpaceIds = options.getSpaceIds;\n this.#syncNamespaces = options.syncNamespaces;\n this.#messageBlocksLimit = options.messageBlocksLimit ?? DEFAULT_MESSAGE_BLOCKS_LIMIT;\n this.#syncConcurrency = options.syncConcurrency ?? DEFAULT_SYNC_CONCURRENCY;\n this.#pollingInterval = options.pollingInterval ?? DEFAULT_POLLING_INTERVAL;\n this.#reconcilePollingInterval = options.reconcilePollingInterval ?? DEFAULT_RECONCILE_POLLING_INTERVAL;\n this.#pollRequestThrottleMs = options.pollRequestThrottleMs ?? DEFAULT_POLL_REQUEST_THROTTLE_MS;\n this.#backgroundSync = options.backgroundSync ?? true;\n }\n\n protected override async _open(): Promise<void> {\n this._ctx.onDispose(\n this.#edgeClient.onMessage((msg: RouterMessage) => {\n if (!msg.serviceId) {\n return;\n }\n const service = msg.serviceId.split(':')[0];\n if (service !== EdgeService.QUEUE_REPLICATOR) {\n return;\n }\n log('feed sync edge ingress', {\n serviceId: msg.serviceId,\n payloadByteLength: msg.payload?.value?.byteLength,\n });\n const handleMessageEffect = Effect.gen({ self: this }, function* () {\n const decoded = yield* Effect.try({\n try: () => cborXdecode(msg.payload!.value),\n catch: (error) => new SystemError({ message: 'Failed to decode feed sync message.', cause: error }),\n });\n // v4 dropped `Schema.validate`; decoding through the type side is the equivalent.\n const payload = yield* Schema.decodeEffect(Schema.toType(FeedProtocol.ProtocolMessage))(decoded);\n // Server-initiated messages carry no `requestId`, so `SyncClient.handleMessage` — which\n // matches responses to in-flight RPCs — would discard them.\n if (payload._tag === 'FeedAdvanced') {\n this.#onFeedAdvanced(payload);\n return;\n }\n if (payload._tag === 'SubscribeResponse') {\n this.#onSubscribeResponse(payload);\n return;\n }\n yield* this.#syncClient.handleMessage(payload);\n }).pipe(\n Effect.tapError((cause) =>\n Effect.sync(() =>\n log('feed sync edge message handling failed', {\n serviceId: msg.serviceId,\n payloadByteLength: msg.payload?.value?.byteLength,\n cause: cause instanceof Error ? cause.message : String(cause),\n }),\n ),\n ),\n );\n\n void RuntimeProvider.runPromise(this.#runtime)(handleMessageEffect);\n }),\n );\n\n if (this.#backgroundSync) {\n // Tasks must be opened before registering listeners that call `schedule()`:\n // * `onNewBlocks` can fire from any `feedStore.append` happening on a separate\n // microtask while `_open()` is still awaiting.\n // * The edge client invokes `onReconnected` as a microtask when already connected.\n // `AsyncTask.schedule()` throws if the task is not yet open.\n await this.#pollTask.open();\n await this.#pushTask.open();\n\n this.#feedStore.onNewBlocks.on(this._ctx, () => {\n this.#pushTask.schedule();\n });\n }\n\n this._ctx.onDispose(\n // NOTE: Fires immediately (as a microtask) if the connection is already open, and again\n // on every subsequent reconnect.\n this.#edgeClient.onReconnected(async () => {\n log('feed sync edge reconnected', {\n peerKey: this.#edgeClient.peerKey,\n identityDid: this.#edgeClient.identityDid,\n });\n // A reconnect may land on a different EDGE build, and any subscription the previous socket\n // held is gone with it, so the capability has to be re-established rather than assumed.\n this.#serverPushesHints = false;\n this.#subscriptionExpiresAt = null;\n this.#deletedSpaces.clear();\n if (this.#backgroundSync) {\n this.#sendSubscriptions();\n this.#resetSpacesToPoll();\n this.#pollTask.schedule();\n this.#pushTask.schedule();\n }\n }),\n );\n\n // Only kick the initial round when the socket is already up. While it is not, each send parks on\n // the ready trigger; the `onReconnected` handler above schedules exactly this same work the\n // moment it connects, so a host that gates its dial until after boot loses nothing here.\n if (this.#backgroundSync && this.#edgeClient.status.state === EdgeStatus_ConnectionState.CONNECTED) {\n this.#sendSubscriptions();\n this.#resetSpacesToPoll();\n this.#pollTask.schedule();\n // Flush blocks written before the syncer opened: `onNewBlocks` only fires on append,\n // so existing unpositioned blocks would otherwise never be pushed.\n this.#pushTask.schedule();\n }\n }\n\n protected override async _close(): Promise<void> {\n if (this.#backgroundSync) {\n await this.#pollTask.close();\n await this.#pushTask.close();\n }\n }\n\n /**\n * Full-poll interval currently in force.\n *\n * A server that never answers the subscribe handshake will never hint, so the tight interval is\n * the only thing keeping remote writes visible against it.\n */\n get #currentPollingInterval(): number {\n return this.#serverPushesHints ? this.#reconcilePollingInterval : this.#pollingInterval;\n }\n\n /**\n * Announce interest in every synced namespace of every known space.\n *\n * Namespace-wide (empty `feedIds`): the client cannot enumerate a namespace's feed ids until it\n * has pulled them, so per-feed subscription would miss exactly the feeds it has not seen yet.\n */\n #sendSubscriptions(): void {\n for (const spaceId of this.#getSpaceIds()) {\n for (const feedNamespace of this.#syncNamespaces) {\n this.#sendServerBoundMessage(\n {\n _tag: 'SubscribeRequest',\n spaceId,\n feedNamespace,\n feedIds: [],\n senderPeerId: this.#edgeClient.peerKey,\n recipientPeerId: undefined,\n },\n FeedProtocol.encodeServiceId(feedNamespace, spaceId),\n );\n }\n }\n }\n\n /**\n * Fire-and-forget send of a message the server does not answer with a correlated RPC response.\n *\n * Failure is logged and dropped: the reconcile poll is the backstop for every hint path, so a\n * subscribe that does not land costs freshness rather than correctness.\n */\n #sendServerBoundMessage(message: FeedProtocol.ProtocolMessage, serviceId: string): void {\n const send = Effect.tryPromise(async () =>\n this.#edgeClient.send(\n this._ctx,\n createBuf(MessageSchema, {\n source: {\n identityDid: this.#edgeClient.identityDid,\n peerKey: this.#edgeClient.peerKey,\n },\n serviceId,\n payload: { value: bufferToArray(encoder.encode(message)) },\n }),\n ),\n ).pipe(\n Effect.tapError((cause) =>\n Effect.sync(() =>\n log('feed sync server-bound send failed', {\n tag: message._tag,\n serviceId,\n cause: cause instanceof Error ? cause.message : String(cause),\n }),\n ),\n ),\n Effect.ignore,\n );\n void EffectEx.runPromise(send);\n }\n\n /**\n * The server accepted a subscription, which is this client's only evidence that it is running a\n * build that pushes hints — an older EDGE drops `SubscribeRequest` without replying.\n */\n #onSubscribeResponse(message: Extract<FeedProtocol.ProtocolMessage, { _tag: 'SubscribeResponse' }>): void {\n const wasPushing = this.#serverPushesHints;\n this.#serverPushesHints = true;\n if (this.#subscriptionExpiresAt == null || message.expiresAt < this.#subscriptionExpiresAt) {\n this.#subscriptionExpiresAt = message.expiresAt;\n this.#scheduleSubscriptionRefresh();\n }\n if (!wasPushing) {\n log('feed sync switched to push-driven reconcile', {\n reconcilePollingInterval: this.#reconcilePollingInterval,\n expiresAt: message.expiresAt,\n });\n }\n }\n\n /**\n * The server says a namespace gained blocks. Queue exactly that space for the next pull rather\n * than resetting every space, so an active space cannot drag the whole workspace into a full poll.\n */\n #onFeedAdvanced(message: Extract<FeedProtocol.ProtocolMessage, { _tag: 'FeedAdvanced' }>): void {\n if (!this.#backgroundSync) {\n return;\n }\n const { spaceId } = message;\n if (!SpaceId.isValid(spaceId)) {\n log.warn('feed sync hint carried an invalid space id', { spaceId: message.spaceId });\n return;\n }\n // A well-formed id is not yet one this client tracks, and the hint is server-supplied: without\n // this the server could drive pulls for arbitrary spaces.\n if (!this.#getSpaceIds().includes(spaceId)) {\n log.warn('feed sync hint named an untracked space', { spaceId });\n return;\n }\n log('feed sync hint received', {\n spaceId,\n feedNamespace: message.feedNamespace,\n position: message.position,\n });\n this.#spacesToPoll.add(spaceId);\n this.#pollTask.schedule();\n }\n\n /** Re-announce subscriptions before the server's stated expiry lapses. */\n #scheduleSubscriptionRefresh(): void {\n if (this.#subscriptionExpiresAt == null) {\n return;\n }\n const remaining = this.#subscriptionExpiresAt - Date.now();\n if (remaining <= 0) {\n return;\n }\n // Halving is what keeps a short-lived subscription from refreshing at zero delay, which would\n // spin subscribe/response as fast as the socket allows.\n const margin = Math.min(SUBSCRIPTION_REFRESH_MARGIN_MS, remaining / 2);\n const delay = remaining - margin;\n scheduleTask(\n this._ctx,\n () => {\n this.#subscriptionExpiresAt = null;\n this.#sendSubscriptions();\n },\n delay,\n );\n }\n\n /**\n * Schedules a best-effort pull without blocking the caller.\n */\n schedulePoll(): void {\n if (!this.#backgroundSync) {\n return;\n }\n this.#resetSpacesToPoll();\n if (this.#throttledPollScheduled) {\n return;\n }\n\n const now = Date.now();\n const delay =\n this.#lastRequestedPollAt == null\n ? 0\n : Math.max(this.#pollRequestThrottleMs - (now - this.#lastRequestedPollAt), 0);\n this.#throttledPollScheduled = true;\n scheduleTask(\n this._ctx,\n () => {\n this.#throttledPollScheduled = false;\n this.#lastRequestedPollAt = Date.now();\n this.#pollTask.schedule();\n },\n delay,\n );\n }\n\n /**\n * Performs queue sync and blocks until there are no pending sync batches.\n */\n async syncBlocking(\n ctx: Context,\n {\n spaceId,\n subspaceTag,\n shouldPush = true,\n shouldPull = true,\n }: {\n spaceId: SpaceId;\n subspaceTag: string;\n shouldPush?: boolean;\n shouldPull?: boolean;\n },\n ): Promise<void> {\n invariant(SpaceId.isValid(spaceId));\n invariant(FeedProtocol.isWellKnownNamespace(subspaceTag));\n if (!shouldPush && !shouldPull) {\n return;\n }\n\n await RuntimeProvider.runPromise(this.#runtime)(\n Effect.gen({ self: this }, function* () {\n let done = false;\n let iterations = 0;\n while (!done) {\n done = true;\n if (shouldPull) {\n const pullResult = yield* this.#syncClient.pull(ctx, {\n spaceId,\n feedNamespace: subspaceTag,\n limit: this.#messageBlocksLimit,\n });\n done &&= pullResult.done;\n }\n\n if (shouldPush) {\n const pushResult = yield* this.#syncClient.push(ctx, {\n spaceId,\n feedNamespace: subspaceTag,\n limit: this.#messageBlocksLimit,\n });\n done &&= pushResult.done;\n }\n iterations++;\n if (iterations > MAX_BLOCKING_SYNC_ITERATIONS) {\n throw new Error('Blocking sync exceeded max iterations.');\n }\n }\n }),\n );\n }\n\n #schedulePushRetry({ hadFailure, needsMore }: { hadFailure: boolean; needsMore: boolean }): void {\n if (!needsMore) {\n this.#pushFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n return;\n }\n if (hadFailure) {\n const delayMs = this.#pushFailureBackoffMs;\n this.#pushFailureBackoffMs = Math.min(this.#pushFailureBackoffMs * 2, MAX_FAILURE_BACKOFF_MS);\n log('feed sync push retry scheduled with backoff', { delayMs });\n scheduleTask(this._ctx, () => this.#pushTask.schedule(), delayMs);\n return;\n }\n this.#pushFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n this.#pushTask.schedule();\n }\n\n /**\n * Delays the next poll after a failed pull. A pull that fails the same way on every attempt\n * would otherwise re-run the moment it returns, since a space that is not done is polled again\n * immediately -- a tight loop of requests against the very server that is failing them.\n */\n #schedulePollRetry(): void {\n const delayMs = this.#pullFailureBackoffMs;\n this.#pullFailureBackoffMs = Math.min(this.#pullFailureBackoffMs * 2, MAX_FAILURE_BACKOFF_MS);\n log('feed sync poll retry scheduled with backoff', { delayMs });\n scheduleTask(this._ctx, () => this.#pollTask.schedule(), delayMs);\n }\n\n #resetSpacesToPoll(): void {\n this.#spacesToPoll.clear();\n this.#getSpaceIds().forEach((spaceId) => {\n this.#spacesToPoll.add(spaceId);\n });\n this.#lastFullPoll = Date.now();\n }\n\n #sendMessage(\n ctx: Context,\n message: FeedProtocol.QueryRequest | FeedProtocol.AppendRequest,\n ): Effect.Effect<void, unknown, never> {\n return Effect.gen({ self: this }, function* () {\n const encoded = encoder.encode(message);\n const serviceId = this.#getTargetServiceId(message);\n const rpcTag = 'blocks' in message ? 'AppendRequest' : 'QueryRequest';\n log('feed sync edge rpc outgoing', {\n tag: rpcTag,\n serviceId,\n payloadByteLength: encoded.byteLength,\n spaceId: message.spaceId,\n feedNamespace: message.feedNamespace,\n requestId: message.requestId,\n });\n yield* Effect.tryPromise(async () =>\n this.#edgeClient.send(\n ctx,\n createBuf(MessageSchema, {\n source: {\n identityDid: this.#edgeClient.identityDid,\n peerKey: this.#edgeClient.peerKey,\n },\n serviceId,\n payload: { value: bufferToArray(encoded) },\n }),\n ),\n ).pipe(\n Effect.tapError((cause) =>\n Effect.sync(() =>\n log('feed sync edge send failed', {\n serviceId,\n tag: rpcTag,\n cause: cause instanceof Error ? cause.message : String(cause),\n }),\n ),\n ),\n );\n });\n }\n\n /**\n * Stops syncing a space for the rest of this connection once the server reports it deleted: the\n * namespace counts as done, and the other namespaces are not asked. Logged once, since both tasks\n * may report it.\n */\n #dropDeletedSpace(spaceId: SpaceId, feedNamespace: string, cause: SyncSpaceDeletedError): void {\n if (this.#deletedSpaces.has(spaceId)) {\n return;\n }\n this.#deletedSpaces.add(spaceId);\n this.#spacesToPoll.delete(spaceId);\n log.warn('feed sync stopped for a space the server reports deleted', {\n spaceId,\n feedNamespace,\n cause: cause.message,\n });\n }\n\n #logSyncFailure(\n operation: 'pull' | 'push',\n { spaceId, feedNamespace, cause }: { spaceId: SpaceId; feedNamespace: string; cause: unknown },\n ): void {\n log('feed sync operation failed', {\n operation,\n spaceId,\n feedNamespace,\n cause: cause instanceof Error ? cause.message : String(cause),\n errorTag: cause instanceof Error ? cause.name : undefined,\n });\n }\n\n #getTargetServiceId(message: FeedProtocol.QueryRequest | FeedProtocol.AppendRequest): string {\n // TODO(dmaretskyi): Perhaps in the future we will want to include the queue namespace here as well.\n // This would require putting it at the top level of the message.\n // For now, we let the edge router handle it.\n return FeedProtocol.encodeServiceId(message.feedNamespace, message.spaceId as SpaceId);\n }\n\n readonly #pollTask = new AsyncTask(async () =>\n Effect.gen({ self: this }, function* () {\n let hadPullFailure = false;\n yield* Effect.forEach(\n this.#spacesToPoll,\n (spaceId) =>\n Effect.gen({ self: this }, function* () {\n let doneForAllNamespaces = true;\n for (const feedNamespace of this.#syncNamespaces) {\n if (this.#deletedSpaces.has(spaceId)) {\n break;\n }\n const { done } = yield* this.#syncClient\n .pull(this._ctx, {\n spaceId,\n feedNamespace,\n limit: this.#messageBlocksLimit,\n })\n .pipe(\n Effect.catch((cause) =>\n Effect.sync(() => {\n if (cause instanceof SyncSpaceDeletedError) {\n this.#dropDeletedSpace(spaceId, feedNamespace, cause);\n return { done: true };\n }\n this.#logSyncFailure('pull', { spaceId, feedNamespace, cause });\n hadPullFailure = true;\n return { done: false };\n }),\n ),\n );\n if (!done) {\n doneForAllNamespaces = false;\n }\n }\n if (doneForAllNamespaces) {\n this.#spacesToPoll.delete(spaceId);\n }\n }),\n { concurrency: this.#syncConcurrency },\n );\n\n // A failed pull only swaps the immediate re-poll for the back-off; the full-poll bookkeeping\n // below still runs, or the failing space would become the only one ever polled again.\n const scheduleNext = hadPullFailure ? () => this.#schedulePollRetry() : () => this.#pollTask.schedule();\n if (!hadPullFailure) {\n this.#pullFailureBackoffMs = DEFAULT_FAILURE_BACKOFF_MS;\n }\n\n // If its time to do a full poll, reset the spaces to poll and schedule the next poll immediately.\n if (this.#lastFullPoll == null || Date.now() - this.#lastFullPoll > this.#currentPollingInterval) {\n this.#resetSpacesToPoll();\n scheduleNext();\n } else if (this.#spacesToPoll.size > 0) {\n // If there are some spaces still syncing, poll them immediately.\n scheduleNext();\n } else {\n // All spaces sync, and there's time before the next full poll, schedule it later.\n this.#resetSpacesToPoll();\n scheduleTask(\n this._ctx,\n () => this.#pollTask.schedule(),\n Math.max(this.#currentPollingInterval - (Date.now() - (this.#lastFullPoll ?? 0)), 0),\n );\n }\n }).pipe(RuntimeProvider.runPromise(this.#runtime)),\n );\n\n readonly #pushTask = new AsyncTask(async () =>\n Effect.gen({ self: this }, function* () {\n const outcomes = yield* Effect.forEach(\n this.#getSpaceIds(),\n (spaceId) =>\n Effect.gen({ self: this }, function* () {\n let needsMore = false;\n let hadFailure = false;\n for (const feedNamespace of this.#syncNamespaces) {\n if (this.#deletedSpaces.has(spaceId)) {\n break;\n }\n const { done } = yield* this.#syncClient\n .push(this._ctx, {\n spaceId,\n feedNamespace,\n limit: this.#messageBlocksLimit,\n })\n .pipe(\n Effect.catch((cause) =>\n Effect.sync(() => {\n if (cause instanceof SyncSpaceDeletedError) {\n this.#dropDeletedSpace(spaceId, feedNamespace, cause);\n return { done: true };\n }\n this.#logSyncFailure('push', { spaceId, feedNamespace, cause });\n hadFailure = true;\n return { done: false };\n }),\n ),\n );\n if (!done) {\n needsMore = true;\n }\n }\n return { hadFailure, needsMore };\n }),\n { concurrency: this.#syncConcurrency },\n );\n // One decision per run: decided per space, a space that pushed fine reset the back-off a\n // failing one was growing, so the failing one was retried at the minimum delay forever.\n this.#schedulePushRetry({\n hadFailure: outcomes.some((outcome) => outcome.hadFailure),\n needsMore: outcomes.some((outcome) => outcome.needsMore),\n });\n }).pipe(RuntimeProvider.runPromise(this.#runtime)),\n );\n}\n\nexport type FeedSyncerLayerOptions = Pick<\n FeedSyncerOptions,\n | 'peerId'\n | 'syncNamespaces'\n | 'messageBlocksLimit'\n | 'syncConcurrency'\n | 'pollingInterval'\n | 'pollRequestThrottleMs'\n | 'backgroundSync'\n | 'syncRpcTimeoutMs'\n>;\n\n/**\n * Effect Layer constructing a {@link FeedSyncer} from ambient SQL, echo host, and edge services.\n *\n * The feed store is sourced from the {@link EchoHostService} (breaking the EchoHost <-> FeedSyncer\n * cycle). Only included when an edge connection is configured, so it resolves the edge tag directly.\n */\nexport const FeedSyncerLayer = (\n options: FeedSyncerLayerOptions,\n): Layer.Layer<\n FeedSyncerService,\n never,\n Hook.Controller | SqlClient.SqlClient | EchoHostService | EdgeConnectionService\n> =>\n Layer.effect(\n FeedSyncerService,\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n const echoHost = yield* EchoHostService;\n const edgeClient = yield* EdgeConnectionService;\n const feedSyncer = new FeedSyncer({\n runtime,\n feedStore: echoHost.feedStore,\n edgeClient,\n getSpaceIds: () => echoHost.spaceIds,\n ...options,\n });\n\n // The echo host falls back to a no-op sync while these are unset, so only this layer sets them.\n echoHost.setFeedSyncHandlers({\n syncFeed: (ctx, request) =>\n feedSyncer.syncBlocking(ctx, {\n spaceId: request.spaceId as SpaceId,\n subspaceTag: request.subspaceTag,\n shouldPush: request.shouldPush,\n shouldPull: request.shouldPull,\n }),\n });\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() => Effect.promise(() => feedSyncer.close()));\n yield* Hook.on(\n Events.StackOpened,\n Effect.fn('FeedSyncer.onStackOpened')(function* () {\n yield* Effect.promise(() => feedSyncer.open(ctx));\n }),\n );\n return feedSyncer;\n }),\n );\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\n\nimport { Mutex } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport {\n EdgeConnectionService,\n EdgeHttpClientService,\n type EdgeIdentity,\n createChainEdgeIdentity,\n createEphemeralEdgeIdentity,\n} from '@dxos/edge-client';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { SignalManagerService } from '@dxos/messaging';\nimport { SwarmNetworkManager, SwarmNetworkManagerService } from '@dxos/network-manager';\nimport { PeerSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { ChainSchema, type Credential } from '@dxos/protocols/buf/dxos/halo/credentials_pb';\n\nimport * as Events from '../../Events.ts';\nimport { type Identity } from '../../Identity.ts';\nimport { TransportFactoryService } from './client-platform.ts';\n\nexport type SwarmNetworkManagerLayerOptions = {\n /** @default true */\n connectionLog?: boolean;\n};\n\n/**\n * Constructs the swarm network manager over the ambient signal manager and transport factory.\n */\nexport const SwarmNetworkManagerLayer = (\n options: SwarmNetworkManagerLayerOptions = {},\n): Layer.Layer<SwarmNetworkManagerService, never, SignalManagerService | TransportFactoryService> =>\n Layer.effect(\n SwarmNetworkManagerService,\n Effect.gen(function* () {\n const signalManager = yield* SignalManagerService;\n const transportFactory = yield* TransportFactoryService;\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n return new SwarmNetworkManager({\n enableDevtoolsLogging: options.connectionLog ?? true,\n transportFactory,\n signalManager,\n peerInfo:\n edgeConnection &&\n create(PeerSchema, { identityDid: edgeConnection.identityDid, peerKey: edgeConnection.peerKey }),\n });\n }),\n );\n\nexport type NetworkLifecycleLayerOptions = {\n /** Emit `NetworkingEnabled` as soon as the stack is open; otherwise the embedder emits it. */\n autoConnect?: boolean;\n};\n\n/**\n * Binds the current identity to edge, signaling, and swarm networking, and drives their lifecycle:\n * opens them once the identity is loaded, starts the edge dial when networking is enabled, and\n * closes them when the layer is destroyed.\n */\nexport const NetworkLifecycleLayer = (\n options: NetworkLifecycleLayerOptions = {},\n): Layer.Layer<never, never, Hook.Controller | SwarmNetworkManagerService | SignalManagerService> =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n const networkManager = yield* SwarmNetworkManagerService;\n const signalManager = yield* SignalManagerService;\n const edgeConnection = Option.getOrUndefined(yield* Effect.serviceOption(EdgeConnectionService));\n const edgeHttpClient = Option.getOrUndefined(yield* Effect.serviceOption(EdgeHttpClientService));\n const identityUpdateMutex = new Mutex();\n\n const setNetworkIdentity = async (params?: { deviceCredential?: Credential; identity?: Identity }) => {\n log('setting network identity...');\n using _ = await identityUpdateMutex.acquire();\n const edgeIdentity = await createEdgeIdentity(params);\n edgeConnection?.setIdentity(edgeIdentity);\n edgeHttpClient?.setIdentity(edgeIdentity);\n networkManager.setPeerInfo(\n create(PeerSchema, { identityDid: edgeIdentity.identityDid, peerKey: edgeIdentity.peerKey }),\n );\n log('network identity set');\n };\n\n const ctx = yield* EffectEx.contextFromScope();\n yield* Effect.addFinalizer(() =>\n Effect.promise(async () => {\n await networkManager.close(Context.default());\n await signalManager.close();\n await edgeConnection?.close();\n }),\n );\n\n yield* Hook.on(\n Events.IdentityLoaded,\n Effect.fn('NetworkLifecycle.onIdentityLoaded')(function* ({ identity }) {\n yield* Effect.promise(async () => {\n await setNetworkIdentity({ identity });\n log('opening edge connection...');\n await edgeConnection?.open(ctx);\n log('opening signal manager...');\n await signalManager.open(ctx);\n log('opening network manager...');\n await networkManager.open();\n });\n yield* Hook.emit(Events.NetworkReady, undefined);\n }),\n );\n\n yield* Hook.on(\n Events.IdentityBound,\n Effect.fn('NetworkLifecycle.onIdentityBound')(function* ({ identity, deviceCredential }) {\n yield* Effect.promise(() => setNetworkIdentity({ identity, deviceCredential }));\n }),\n );\n\n // Only the edge dial is gated: subduction and feed sync resume from the edge reconnect.\n yield* Hook.on(\n Events.NetworkingEnabled,\n Effect.fn('NetworkLifecycle.onNetworkingEnabled')(function* () {\n log('starting edge networking');\n edgeConnection?.startNetworking();\n }),\n );\n\n if (options.autoConnect) {\n yield* Hook.on(\n Events.StackOpened,\n Effect.fn('NetworkLifecycle.onStackOpened')(function* () {\n yield* Hook.emit(Events.NetworkingEnabled, undefined);\n }),\n );\n }\n }),\n );\n\nconst createEdgeIdentity = async (params?: {\n deviceCredential?: Credential;\n identity?: Identity;\n}): Promise<EdgeIdentity> => {\n const identity = params?.identity;\n if (!identity) {\n return createEphemeralEdgeIdentity();\n }\n if (params?.deviceCredential) {\n return createChainEdgeIdentity(\n identity.signer,\n identity.identityKey,\n identity.deviceKey,\n create(ChainSchema, { credential: params.deviceCredential }),\n [], // TODO(dmaretskyi): Service access credentials.\n );\n }\n // TODO: throw here or from identity if device chain can't be loaded, to avoid indefinite hangup\n await warnAfterTimeout(10_000, 'Waiting for identity to be ready for edge connection', async () => {\n await identity.ready();\n });\n invariant(identity.deviceCredentialChain);\n return createChainEdgeIdentity(\n identity.signer,\n identity.identityKey,\n identity.deviceKey,\n identity.deviceCredentialChain,\n [], // TODO(dmaretskyi): Service access credentials.\n );\n};\n","//\n// Copyright 2022 DXOS.org\n//\n\nimport * as EffectContext from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Option from 'effect/Option';\nimport * as SqlClient from 'effect/sql/SqlClient';\nimport type * as SqlError from 'effect/sql/SqlError';\n\nimport {\n type AutomergeReplicator,\n EchoHostLayer,\n EchoHostService,\n type QueryExecutorMode,\n runSqliteHealthCheck,\n} from '@dxos/echo-host';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport * as Hook from '@dxos/effect/Hook';\nimport * as RuntimeProvider from '@dxos/effect/RuntimeProvider';\nimport { SqliteKeyring } from '@dxos/keyring';\nimport { log } from '@dxos/log';\nimport { type SignalManager } from '@dxos/messaging';\nimport { type TransportFactory } from '@dxos/network-manager';\nimport { InvalidStorageVersionError, STORAGE_VERSION } from '@dxos/protocols';\nimport { type Runtime_Client_EdgeFeatures } from '@dxos/protocols/buf/dxos/config_pb';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as Events from '../../Events.ts';\nimport * as SqliteStorage from '../../SqliteStorage.ts';\nimport { type IdentityManagerProps, type InboxRelay, identityProviderFromManager } from '../identity/index.ts';\nimport { type InvitationConnectionProps } from '../invitations/index.ts';\nimport { IMetadataStoreService, SqliteMetadataStore } from '../metadata/index.ts';\nimport { SpaceManagerService } from '../space/index.ts';\nimport { type DataSpaceManagerRuntimeProps } from '../spaces/index.ts';\n\nexport type ServiceContextRuntimeProps = Pick<\n IdentityManagerProps,\n 'devicePresenceOfflineTimeout' | 'devicePresenceAnnounceInterval'\n> &\n DataSpaceManagerRuntimeProps & {\n invitationConnectionDefaultProps?: InvitationConnectionProps;\n disableP2pReplication?: boolean;\n enableVectorIndexing?: boolean;\n /** Query evaluation path for every host query; see `QueryExecutorMode`. */\n queryExecutor?: QueryExecutorMode;\n };\n\n/**\n * Combined storage migration effect gathered from the concrete SQLite stores.\n * Run by the storage lifecycle handler when the host starts opening.\n */\nexport class StorageMigrationService extends EffectContext.Service<\n StorageMigrationService,\n Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient>\n>()('@dxos/client-services/StorageMigration') {}\n\nexport type ServiceStackServices = ServiceContextRuntimeProps & {\n edgeFeatures?: Runtime_Client_EdgeFeatures;\n connectionLog?: boolean;\n autoConnect?: boolean;\n /**\n * Whether an edge endpoint is configured. An edge feature can be enabled in config without one,\n * so the feature flag alone does not say whether an edge-dependent spec can be built.\n */\n edgeAvailable?: boolean;\n /** Overrides the config-derived signal manager; tests pass an in-memory one. */\n signalManager?: SignalManager;\n /** Overrides the WebRTC transport; tests pass the in-memory transport. */\n transportFactory?: TransportFactory;\n /** Replaces the EDGE inbox; tests share one relay between clients. */\n inboxRelay?: InboxRelay;\n};\n\n/**\n * Attaches the replicator behind `tag`, when one is wired beneath, to the echo host once networking\n * is up. Each replicator registers itself through this; the stack does not enumerate them.\n */\nexport const registerReplicator = <Self>(\n tag: EffectContext.Key<Self, AutomergeReplicator>,\n): Layer.Layer<never, never, EchoHostService | Hook.Controller> =>\n Layer.unwrap(\n Effect.map(Effect.serviceOption(tag), (replicator) =>\n Option.match(replicator, {\n onNone: () => Layer.empty,\n onSome: (replicator) =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n const echoHost = yield* EchoHostService;\n const ctx = yield* EffectEx.contextFromScope();\n yield* Hook.on(\n Events.NetworkReady,\n Effect.fn('EchoHost.addReplicator')(function* () {\n yield* Effect.promise(() => echoHost.addReplicator(ctx, replicator));\n }),\n );\n }),\n ),\n }),\n ),\n );\n\n/**\n * Provides the {@link IdentityProviderService} from the resolved {@link IdentityContract.Manager}.\n */\nexport const identityProviderLayer = Layer.effect(\n IdentityContract.ProviderService,\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n return identityProviderFromManager(identityManager);\n }),\n);\n\n/**\n * Combined storage migration effect. Storage migrations are idempotent `CREATE TABLE` effects that\n * do not depend on store instance state, so they are extracted from throwaway instances to keep the\n * store layers individual.\n */\nexport const storageMigrationLayer = Layer.effect(\n StorageMigrationService,\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n return Effect.all(\n [\n new SqliteMetadataStore({ runtime }).migrate,\n new SqliteKeyring({ runtime }).migrate,\n new SqliteStorage.SqliteStorage({ runtime }).migrate,\n ],\n { discard: true },\n );\n }),\n);\n\n/**\n * Opens storage when the host starts opening: migrations, the storage version check, and the SQLite\n * health check run in this order inside one handler, since a `serial` event would order them by\n * subscription instead.\n */\nexport const storageLifecycleLayer = Layer.effectDiscard(\n Effect.gen(function* () {\n const runtime = yield* RuntimeProvider.currentRuntime<SqlClient.SqlClient>();\n const migrate = yield* StorageMigrationService;\n const metadataStore = yield* IMetadataStoreService;\n yield* Hook.on(\n Events.Opening,\n Effect.fn('Storage.onOpening')(function* () {\n log('running storage migrations...');\n yield* Effect.promise(() => RuntimeProvider.runPromise(runtime)(migrate));\n yield* Effect.promise(() => metadataStore.load());\n if (metadataStore.version !== STORAGE_VERSION) {\n // TODO(mykola): Migrate storage to a new version if incompatibility is detected.\n throw new InvalidStorageVersionError(STORAGE_VERSION, metadataStore.version);\n }\n log('running sqlite health check...');\n yield* Effect.promise(() => runSqliteHealthCheck(runtime));\n log('storage ready');\n yield* Hook.emit(Events.StorageReady, undefined);\n }),\n );\n }),\n);\n\n/**\n * Constructs the {@link EchoHost}, resolving the identity/space callbacks that point down the stack.\n * The feed sync handlers (which point up) are wired later via `EchoHost.setFeedSyncHandlers`.\n *\n * The host is self-contained (runs its own migrations, owns its feed/automerge stores), so its\n * open/close is owned by the layer scope: it opens when the stack is built and closes when the\n * runtime is disposed. Identity-, network-, and storage-bound lifecycle is driven by the events.\n */\nexport const echoHostLayer = (options: { useSubduction?: boolean; queryExecutor?: QueryExecutorMode }) =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n const echoHost = yield* EchoHostService;\n yield* Effect.acquireRelease(\n Effect.promise(() => echoHost.open()),\n () => Effect.promise(() => echoHost.close()),\n );\n\n // Points back down the stack, like the feed sync handlers above: the identity manager anchors\n // the HALO space on a root document and needs the open host to do it.\n const identityManager = yield* IdentityContract.ManagerService;\n yield* Effect.promise(() => identityManager.setEchoHost(echoHost));\n }),\n ).pipe(\n Layer.provideMerge(\n Layer.unwrap(\n Effect.gen(function* () {\n const identityManager = yield* IdentityContract.ManagerService;\n const spaceManager = yield* SpaceManagerService;\n return EchoHostLayer({\n peerIdProvider: () => identityManager.identity?.deviceKey?.toHex(),\n getSpaceKeyByRootDocumentId: (documentId) => spaceManager.findSpaceByRootDocumentId(documentId)?.key,\n useSubduction: options.useSubduction,\n queryExecutor: options.queryExecutor,\n });\n }),\n ),\n ),\n );\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as SqlClient from 'effect/sql/SqlClient';\n\nimport { RegisterService } from '@dxos/client-protocol';\nimport * as LayerSpec from '@dxos/compute/LayerSpec';\nimport { ConfigService, resolveTelemetryTag } from '@dxos/config';\nimport {\n EchoEdgeSubductionReplicatorLayer,\n EchoHostService,\n EdgeAutomergeReplicatorService,\n MeshEchoReplicatorLayer,\n MeshEchoReplicatorService,\n} from '@dxos/echo-host';\nimport {\n EdgeClient,\n EdgeConnectionService,\n EdgeHttpClient,\n EdgeHttpClientService,\n createStubEdgeIdentity,\n} from '@dxos/edge-client';\nimport * as Hook from '@dxos/effect/Hook';\nimport {\n HypercoreFactoryLayer,\n HypercoreFactoryService,\n HypercoreStorageDirectoryService,\n HypercoreStoreLayer,\n HypercoreStoreService,\n} from '@dxos/feed-store';\nimport { KeyringApiService, SqliteKeyringLayer } from '@dxos/keyring';\nimport {\n EdgeSignalManager,\n MemorySignalManager,\n MemorySignalManagerContext,\n SignalManagerService,\n} from '@dxos/messaging';\nimport { SwarmNetworkManagerService, createIceProvider, createRtcTransportFactory } from '@dxos/network-manager';\nimport { FeedProtocol } from '@dxos/protocols';\nimport {\n ContactsService,\n DataService,\n DevicesService,\n DevtoolsHost,\n EdgeAgentService,\n FeedService,\n IdentityService,\n InboxService,\n InvitationsService,\n LoggingService,\n NetworkService,\n QueryService,\n SpacesService,\n SqlService,\n SystemService,\n} from '@dxos/protocols/rpc';\nimport { RpcRouter } from '@dxos/rpc';\nimport * as SqlExport from '@dxos/sql-sqlite/SqlExport';\n\nimport * as IdentityContract from '../../contracts/identity.ts';\nimport * as InvitationsContract from '../../contracts/invitations.ts';\nimport * as SpacesContract from '../../contracts/spaces.ts';\nimport * as Readiness from '../../Readiness.ts';\nimport * as SqliteStorage from '../../SqliteStorage.ts';\nimport { EdgeAgentManagerLayer, EdgeAgentManagerService, EdgeAgentServiceLayer } from '../agents/index.ts';\nimport { DevicesServiceLayer } from '../devices/index.ts';\nimport { DevtoolsHostLayer, DevtoolsHostService } from '../devtools/index.ts';\nimport {\n EdgeIdentityRecoveryManagerLayer,\n EdgeIdentityRecoveryManagerService,\n} from '../identity/identity-recovery-manager.ts';\nimport {\n ContactsServiceLayer,\n IdentityLifecycleLayer,\n IdentityManagerLayer,\n IdentityServiceLayer,\n InboxServiceLayer,\n} from '../identity/index.ts';\nimport {\n InvitationFactoriesLayer,\n InvitationsHandlerLayer,\n InvitationsHandlerService,\n InvitationsManagerLayer,\n InvitationsServiceLayer,\n} from '../invitations/index.ts';\nimport { LoggingServiceLayer } from '../logging/index.ts';\nimport { IMetadataStoreService, SqliteMetadataStoreLayer } from '../metadata/index.ts';\nimport { NetworkServiceLayer } from '../network/index.ts';\nimport { valueEncoding } from '../pipeline/index.ts';\nimport { SpaceManagerLayer, SpaceManagerService } from '../space/index.ts';\nimport { DataSpaceManagerLayer, SigningContextProviderLayer, SpacesServiceLayer } from '../spaces/index.ts';\nimport { SqlServiceLayer } from '../sql/index.ts';\nimport { SystemServiceLayer } from '../system/index.ts';\nimport { TransportFactoryService } from './client-platform.ts';\nimport {\n CrossDeviceSpaceSynchronizerLayer,\n CrossDeviceSpaceSynchronizerService,\n} from './cross-device-space-synchronizer.ts';\nimport { FeedSyncerLayer, FeedSyncerService } from './feed-syncer.ts';\nimport { NetworkLifecycleLayer, SwarmNetworkManagerLayer } from './network-lifecycle.ts';\nimport {\n type ServiceStackServices,\n StorageMigrationService,\n echoHostLayer,\n identityProviderLayer,\n registerReplicator,\n storageLifecycleLayer,\n storageMigrationLayer,\n} from './service-stack.ts';\n\n/**\n * Subduction needs the edge clients as well as the feature flag: the flag is set in config profiles\n * that configure no edge endpoint, and requiring a tag nothing provides would prune the specs that\n * declare it — silently taking the data space manager, and every service built on it, with them.\n */\nconst subductionEnabled = (options: ServiceStackServices): boolean =>\n !!options.edgeFeatures?.subductionReplicator && !!options.edgeAvailable;\n\n/**\n * The client stack as a list of {@link LayerSpec.LayerSpec}s for a `LayerStack` to aggregate: each\n * spec declares the tags it needs and the tags it provides, so build order — and which specs are\n * built at all — follows from the graph rather than from a hand-written `provideMerge` chain.\n *\n * Two conventions carry the behaviour the chain used to encode:\n *\n * - A spec whose point is a side effect provides no tag for anyone to request (a lifecycle\n * subscription, an rpc registration, a replicator attaching itself to the echo host), so it is\n * `eager`.\n * - Anything conditional is conditional *within* a spec: a spec that needs the edge requires the\n * edge tags, which the embedder supplies ambiently only with an endpoint configured, and an\n * unsatisfied requirement prunes the spec. Option-driven choices (p2p replication, subduction)\n * are made inside the spec body.\n *\n * The embedder supplies {@link ConfigService}, {@link Hook.Controller}, the SQL services, the\n * platform inputs and — when configured — the edge clients as the stack's ambient services.\n */\n/**\n * The client stack as {@link LayerSpec.LayerSpec}s for a `LayerStack` to aggregate: each spec\n * declares the tags it needs and the tags it provides, so build order — and which specs are built at\n * all — follows from the graph rather than from a hand-written `provideMerge` chain.\n *\n * Two conventions carry the behaviour the chain used to encode:\n *\n * - A spec whose point is a side effect provides no tag for anyone to request (a lifecycle\n * subscription, an rpc registration, a replicator attaching itself to the echo host), so it is\n * `eager`.\n * - Anything conditional is conditional *within* a spec: a spec that needs the edge requires the\n * edge tags, which the embedder supplies ambiently only with an endpoint configured, and an\n * unsatisfied requirement prunes the spec. Option-driven choices (p2p replication, subduction)\n * pick which specs {@link clientServiceSpecs} returns.\n *\n * The embedder supplies {@link ConfigService}, {@link Hook.Controller}, the SQL services, the\n * platform inputs and — when configured — the edge clients as the stack's ambient services.\n */\n\n//\n// Platform inputs. These were a layer the embedder provided beneath the stack; as specs the edge\n// clients are conditional like any other spec rather than an ambient service that may or may not be\n// there, which is what lets the stack declare its ambient requirements as tags.\n//\n\n/** Only included with a configured endpoint, so the tags exist exactly when the clients do. */\nexport const EdgeClientsSpec = LayerSpec.make(\n { affinity: 'application', requires: [ConfigService], provides: [EdgeConnectionService, EdgeHttpClientService] },\n () =>\n Layer.unwrap(\n Effect.gen(function* () {\n const config = yield* ConfigService;\n const endpoint = config.get('runtime.services.edge.url')!;\n const clientTag = resolveTelemetryTag(config);\n return Layer.mergeAll(\n // Dialing is driven by `NetworkingEnabled` rather than open, so boot RPCs are not competing\n // with the outbound connection.\n Layer.sync(\n EdgeConnectionService,\n () => new EdgeClient(createStubEdgeIdentity(), { socketEndpoint: endpoint, clientTag, deferConnect: true }),\n ),\n Layer.sync(EdgeHttpClientService, () => new EdgeHttpClient(endpoint, { clientTag })),\n );\n }),\n ),\n);\n\nexport const SignalManagerSpec = (options: ServiceStackServices) => {\n const signalManager = options.signalManager;\n if (signalManager) {\n return LayerSpec.make({ affinity: 'application', requires: [], provides: [SignalManagerService] }, () =>\n Layer.succeed(SignalManagerService, signalManager),\n );\n }\n // Edge is the only real signaling transport; without it there is no cross-process signaling, so\n // the spec takes the edge connection exactly when one will exist.\n const edgeSignaling = !!options.edgeFeatures?.signaling && !!options.edgeAvailable;\n return LayerSpec.make(\n {\n affinity: 'application',\n requires: edgeSignaling ? [EdgeConnectionService] : [],\n provides: [SignalManagerService],\n },\n () =>\n edgeSignaling\n ? Layer.effect(\n SignalManagerService,\n Effect.map(EdgeConnectionService, (edgeConnection) => new EdgeSignalManager({ edgeConnection })),\n )\n : Layer.sync(SignalManagerService, () => new MemorySignalManager(new MemorySignalManagerContext())),\n );\n};\n\nexport const TransportFactorySpec = (options: ServiceStackServices) => {\n const transportFactory = options.transportFactory;\n if (transportFactory) {\n return LayerSpec.make({ affinity: 'application', requires: [], provides: [TransportFactoryService] }, () =>\n Layer.succeed(TransportFactoryService, transportFactory),\n );\n }\n return LayerSpec.make(\n { affinity: 'application', requires: [ConfigService], provides: [TransportFactoryService] },\n () =>\n Layer.effect(\n TransportFactoryService,\n Effect.gen(function* () {\n const config = yield* ConfigService;\n const iceProviders = config.get('runtime.services.iceProviders');\n return createRtcTransportFactory(\n { iceServers: config.get('runtime.services.ice') },\n iceProviders && createIceProvider(iceProviders),\n );\n }),\n ),\n );\n};\n\n//\n// Storage.\n//\n\nexport const SqliteStorageSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [SqliteStorage.SqliteStorageService] },\n () => SqliteStorage.SqliteStorageLayer(),\n);\n\nexport const HypercoreStorageDirectorySpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [SqliteStorage.SqliteStorageService],\n provides: [HypercoreStorageDirectoryService],\n },\n () => SqliteStorage.HypercoreStorageDirectoryLayer(),\n);\n\nexport const KeyringSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [KeyringApiService] },\n () => SqliteKeyringLayer(),\n);\n\nexport const MetadataStoreSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [IMetadataStoreService] },\n () => SqliteMetadataStoreLayer(),\n);\n\nexport const HypercoreFactorySpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [KeyringApiService, HypercoreStorageDirectoryService],\n provides: [HypercoreFactoryService],\n },\n () => HypercoreFactoryLayer({ hypercore: { valueEncoding, stats: true } }),\n);\n\nexport const HypercoreStoreSpec = LayerSpec.make(\n { affinity: 'application', requires: [HypercoreFactoryService], provides: [HypercoreStoreService] },\n () => HypercoreStoreLayer(),\n);\n\nexport const StorageMigrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [StorageMigrationService] },\n () => storageMigrationLayer,\n);\n\nexport const StorageLifecycleSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [SqlClient.SqlClient, StorageMigrationService, IMetadataStoreService, Hook.Controller],\n provides: [],\n eager: true,\n },\n () => storageLifecycleLayer,\n);\n\n//\n// Network.\n//\n\nexport const StackReadinessSpec = LayerSpec.make(\n { affinity: 'application', requires: [Hook.Controller], provides: [Readiness.StackReadinessService] },\n () => Readiness.StackReadinessLayer,\n);\n\nexport const SwarmNetworkManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [SignalManagerService, TransportFactoryService],\n provides: [SwarmNetworkManagerService],\n },\n () => SwarmNetworkManagerLayer({ connectionLog: options.connectionLog }),\n );\n\nexport const NetworkLifecycleSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, SwarmNetworkManagerService, IdentityContract.ManagerService, SignalManagerService],\n provides: [],\n eager: true,\n },\n () => NetworkLifecycleLayer({ autoConnect: options.autoConnect }),\n );\n\n//\n// Identity and spaces.\n//\n\nexport const SpaceManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, HypercoreStoreService, SwarmNetworkManagerService, IMetadataStoreService],\n provides: [SpaceManagerService],\n },\n () => SpaceManagerLayer({ disableP2pReplication: options.disableP2pReplication }),\n );\n\nexport const IdentityManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, IMetadataStoreService, KeyringApiService, HypercoreStoreService, SpaceManagerService],\n provides: [IdentityContract.ManagerService],\n },\n () =>\n IdentityManagerLayer({\n devicePresenceOfflineTimeout: options.devicePresenceOfflineTimeout,\n devicePresenceAnnounceInterval: options.devicePresenceAnnounceInterval,\n edgeFeatures: options.edgeFeatures,\n automergeCredentials: options.automergeCredentials,\n }),\n );\n\nexport const IdentityProviderSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [IdentityContract.ManagerService],\n provides: [IdentityContract.ProviderService],\n },\n () => identityProviderLayer,\n);\n\nexport const EdgeIdentityRecoverySpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [KeyringApiService, IdentityContract.ManagerService],\n provides: [EdgeIdentityRecoveryManagerService],\n },\n () => EdgeIdentityRecoveryManagerLayer(),\n);\n\nexport const IdentityLifecycleSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, IdentityContract.ManagerService, EdgeIdentityRecoveryManagerService],\n provides: [IdentityContract.LifecycleService],\n },\n () => IdentityLifecycleLayer,\n);\n\nexport const SigningContextProviderSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [IdentityContract.ProviderService],\n provides: [SpacesContract.SigningContextProviderService],\n },\n () => SigningContextProviderLayer,\n);\n\n// The edge client is required only when configured, so the handler is built after it rather than\n// finding it absent; without it, edge-assisted admission is simply unavailable.\nexport const InvitationsHandlerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [SwarmNetworkManagerService, ...(options.edgeAvailable ? [EdgeHttpClientService] : [])],\n provides: [InvitationsHandlerService],\n },\n () => InvitationsHandlerLayer({ connectionProps: options.invitationConnectionDefaultProps }),\n );\n\nexport const InvitationsManagerSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, InvitationsHandlerService, IMetadataStoreService],\n provides: [InvitationsContract.ManagerService],\n },\n () => InvitationsManagerLayer(),\n);\n\nexport const EchoHostSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [IdentityContract.ManagerService, SpaceManagerService, SqlClient.SqlClient],\n provides: [EchoHostService],\n },\n () =>\n echoHostLayer({\n useSubduction: options.edgeFeatures?.subductionReplicator,\n queryExecutor: options.queryExecutor,\n }),\n );\n\nexport const DataSpaceManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n Hook.Controller,\n SpaceManagerService,\n IMetadataStoreService,\n KeyringApiService,\n SpacesContract.SigningContextProviderService,\n HypercoreStoreService,\n EchoHostService,\n InvitationsContract.ManagerService,\n // Read with `Effect.serviceOption`, so each is required only where it is also provided.\n ...(options.disableP2pReplication ? [] : [MeshEchoReplicatorService]),\n ...(subductionEnabled(options) ? [EdgeAutomergeReplicatorService] : []),\n ],\n provides: [SpacesContract.ManagerService],\n },\n () => DataSpaceManagerLayer({ runtimeProps: options, edgeFeatures: options.edgeFeatures }),\n );\n\nexport const InvitationFactoriesSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n InvitationsContract.ManagerService,\n IdentityContract.ManagerService,\n IdentityContract.LifecycleService,\n KeyringApiService,\n SpacesContract.ManagerService,\n SpacesContract.SigningContextProviderService,\n ],\n provides: [],\n eager: true,\n },\n () => InvitationFactoriesLayer,\n);\n\n// The edge client is required only when configured, so the manager is built after it rather than\n// finding it absent; without it, it stays dormant (see `EdgeAgentManager._open`).\nexport const EdgeAgentManagerSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n Hook.Controller,\n SpacesContract.ManagerService,\n IdentityContract.ProviderService,\n ...(options.edgeAvailable ? [EdgeHttpClientService] : []),\n ],\n provides: [EdgeAgentManagerService],\n },\n () => EdgeAgentManagerLayer({ edgeFeatures: options.edgeFeatures }),\n );\n\n// Eager: nothing asks for its tag — it exists to subscribe to space changes across devices.\nexport const CrossDeviceSpaceSynchronizerSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, SpacesContract.ManagerService],\n provides: [CrossDeviceSpaceSynchronizerService],\n eager: true,\n },\n () => CrossDeviceSpaceSynchronizerLayer,\n);\n\n//\n// Replication. Each replicator provides its own tag as well as registering itself with the echo\n// host, because `SpacesContract.Manager` reads both tags with `Effect.serviceOption` to decide which\n// replication paths a space gets. The ones that need the edge are pruned without it.\n//\n\nexport const MeshReplicatorSpec = LayerSpec.make(\n { affinity: 'application', requires: [], provides: [MeshEchoReplicatorService] },\n () => MeshEchoReplicatorLayer(),\n);\n\nexport const MeshReplicatorRegistrationSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [MeshEchoReplicatorService, EchoHostService, Hook.Controller],\n provides: [],\n eager: true,\n },\n () => registerReplicator(MeshEchoReplicatorService),\n);\n\nexport const EdgeSubductionReplicatorSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [EdgeConnectionService, EdgeHttpClientService],\n provides: [EdgeAutomergeReplicatorService],\n },\n () => EchoEdgeSubductionReplicatorLayer(),\n);\n\nexport const EdgeSubductionReplicatorRegistrationSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [EdgeAutomergeReplicatorService, EchoHostService, Hook.Controller],\n provides: [],\n eager: true,\n },\n () => registerReplicator(EdgeAutomergeReplicatorService),\n);\n\nexport const FeedSyncerSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [Hook.Controller, SqlClient.SqlClient, EchoHostService, EdgeConnectionService],\n provides: [FeedSyncerService],\n eager: true,\n },\n () =>\n FeedSyncerLayer({\n peerId: '',\n syncNamespaces: [FeedProtocol.WellKnownNamespaces.data, FeedProtocol.WellKnownNamespaces.trace],\n }),\n);\n\n//\n// RPC services. Each handler keeps its own tag, and its registration with the router is a separate\n// spec — eager, because a registration provides nothing for anyone to ask for.\n//\n\nexport const RpcRouterSpec = LayerSpec.make(\n { affinity: 'application', requires: [], provides: [RpcRouter.RpcRouter] },\n () => RpcRouter.layer,\n);\n\nexport const SystemServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n RpcRouter.RpcRouter,\n ConfigService,\n Hook.Controller,\n IdentityContract.ManagerService,\n SpacesContract.ManagerService,\n SwarmNetworkManagerService,\n ],\n provides: [SystemService.Tag],\n },\n () => SystemServiceLayer,\n);\n\nexport const SystemServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [SystemService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(SystemService.Rpcs, SystemService.Tag),\n);\n\nexport const IdentityServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n Hook.Controller,\n IdentityContract.ManagerService,\n IdentityContract.LifecycleService,\n EdgeIdentityRecoveryManagerService,\n KeyringApiService,\n SpacesContract.ManagerService,\n SqlClient.SqlClient,\n ],\n provides: [IdentityService.Tag],\n },\n () => IdentityServiceLayer,\n);\n\nexport const IdentityServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [IdentityService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(IdentityService.Rpcs, IdentityService.Tag),\n);\n\nexport const ContactsServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n IdentityContract.ManagerService,\n SpaceManagerService,\n SpacesContract.ManagerService,\n Readiness.StackReadinessService,\n ],\n provides: [ContactsService.Tag],\n },\n () => ContactsServiceLayer,\n);\n\nexport const ContactsServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [ContactsService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(ContactsService.Rpcs, ContactsService.Tag),\n);\n\n// The edge tags are required only when configured, so the service is built after them rather than\n// finding them absent; without them (and without a test relay) it still serves an empty inbox.\nexport const InboxServiceSpec = (options: ServiceStackServices) =>\n LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n IdentityContract.ManagerService,\n ...(options.edgeAvailable && !options.inboxRelay ? [EdgeHttpClientService, EdgeConnectionService] : []),\n ],\n provides: [InboxService.Tag],\n },\n () => InboxServiceLayer({ relay: options.inboxRelay }),\n );\n\nexport const InboxServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [InboxService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(InboxService.Rpcs, InboxService.Tag),\n);\n\nexport const InvitationsServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [InvitationsContract.ManagerService], provides: [InvitationsService.Tag] },\n () => InvitationsServiceLayer,\n);\n\nexport const InvitationsServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [InvitationsService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(InvitationsService.Rpcs, InvitationsService.Tag),\n);\n\nexport const DevicesServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [IdentityContract.ManagerService], provides: [DevicesService.Tag] },\n () => DevicesServiceLayer,\n);\n\nexport const DevicesServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [DevicesService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(DevicesService.Rpcs, DevicesService.Tag),\n);\n\nexport const SpacesServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n IdentityContract.ManagerService,\n SpaceManagerService,\n EchoHostService,\n SpacesContract.ManagerService,\n Readiness.StackReadinessService,\n ],\n provides: [SpacesService.Tag],\n },\n () => SpacesServiceLayer,\n);\n\nexport const SpacesServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [SpacesService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(SpacesService.Rpcs, SpacesService.Tag),\n);\n\nexport const NetworkServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [SwarmNetworkManagerService, SignalManagerService],\n provides: [NetworkService.Tag],\n },\n () => NetworkServiceLayer,\n);\n\nexport const NetworkServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [NetworkService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(NetworkService.Rpcs, NetworkService.Tag),\n);\n\nexport const EdgeAgentServiceSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [EdgeAgentManagerService, Readiness.StackReadinessService],\n provides: [EdgeAgentService.Tag],\n },\n () => EdgeAgentServiceLayer,\n);\n\nexport const EdgeAgentServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [EdgeAgentService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(EdgeAgentService.Rpcs, EdgeAgentService.Tag),\n);\n\n//\n// Data, query and feed: thin projections of the echo host rather than package-local impls.\n//\n\nexport const DataServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [EchoHostService], provides: [DataService.Tag] },\n () =>\n Layer.effect(\n DataService.Tag,\n Effect.map(EchoHostService, (echoHost) => echoHost.dataService),\n ),\n);\n\nexport const DataServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [DataService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(DataService.Rpcs, DataService.Tag),\n);\n\nexport const QueryServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [EchoHostService], provides: [QueryService.Tag] },\n () =>\n Layer.effect(\n QueryService.Tag,\n Effect.map(EchoHostService, (echoHost) => echoHost.queryService),\n ),\n);\n\nexport const QueryServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [QueryService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(QueryService.Rpcs, QueryService.Tag),\n);\n\nexport const FeedServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [EchoHostService], provides: [FeedService.Tag] },\n () =>\n Layer.effect(\n FeedService.Tag,\n Effect.map(EchoHostService, (echoHost) => echoHost.feedService),\n ),\n);\n\nexport const FeedServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [FeedService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(FeedService.Rpcs, FeedService.Tag),\n);\n\nexport const LoggingServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [], provides: [LoggingService.Tag] },\n () => LoggingServiceLayer,\n);\n\nexport const LoggingServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [LoggingService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(LoggingService.Rpcs, LoggingService.Tag),\n);\n\nexport const DevtoolsHostSpec = LayerSpec.make(\n {\n affinity: 'application',\n requires: [\n ConfigService,\n KeyringApiService,\n HypercoreStoreService,\n SpaceManagerService,\n IMetadataStoreService,\n SpacesContract.ManagerService,\n Readiness.StackReadinessService,\n SignalManagerService,\n SwarmNetworkManagerService,\n SqlClient.SqlClient,\n SqlExport.SqlExport,\n ],\n provides: [DevtoolsHost.Tag, DevtoolsHostService],\n },\n () => DevtoolsHostLayer,\n);\n\nexport const SqlServiceSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlClient.SqlClient], provides: [SqlService.Tag] },\n () => SqlServiceLayer,\n);\n\nexport const SqlServiceRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [SqlService.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(SqlService.Rpcs, SqlService.Tag),\n);\n\nexport const DevtoolsHostRegistrationSpec = LayerSpec.make(\n { affinity: 'application', requires: [DevtoolsHost.Tag, RpcRouter.RpcRouter], provides: [], eager: true },\n () => RegisterService(DevtoolsHost.Rpcs, DevtoolsHost.Tag),\n);\n\n/**\n * Every spec the client stack is built from, with the option-driven ones applied.\n */\nexport const clientServiceSpecs = (options: ServiceStackServices): LayerSpec.LayerSpec[] => [\n ...(options.edgeAvailable ? [EdgeClientsSpec] : []),\n SignalManagerSpec(options),\n TransportFactorySpec(options),\n\n SqliteStorageSpec,\n HypercoreStorageDirectorySpec,\n KeyringSpec,\n MetadataStoreSpec,\n HypercoreFactorySpec,\n HypercoreStoreSpec,\n StorageMigrationSpec,\n StorageLifecycleSpec,\n\n StackReadinessSpec,\n SwarmNetworkManagerSpec(options),\n NetworkLifecycleSpec(options),\n\n SpaceManagerSpec(options),\n IdentityManagerSpec(options),\n IdentityProviderSpec,\n EdgeIdentityRecoverySpec,\n IdentityLifecycleSpec,\n SigningContextProviderSpec,\n InvitationsHandlerSpec(options),\n InvitationsManagerSpec,\n EchoHostSpec(options),\n DataSpaceManagerSpec(options),\n InvitationFactoriesSpec,\n EdgeAgentManagerSpec(options),\n CrossDeviceSpaceSynchronizerSpec,\n\n ...(options.disableP2pReplication ? [] : [MeshReplicatorSpec, MeshReplicatorRegistrationSpec]),\n ...(subductionEnabled(options) ? [EdgeSubductionReplicatorSpec, EdgeSubductionReplicatorRegistrationSpec] : []),\n FeedSyncerSpec,\n\n RpcRouterSpec,\n SystemServiceSpec,\n SystemServiceRegistrationSpec,\n IdentityServiceSpec,\n IdentityServiceRegistrationSpec,\n ContactsServiceSpec,\n ContactsServiceRegistrationSpec,\n InboxServiceSpec(options),\n InboxServiceRegistrationSpec,\n InvitationsServiceSpec,\n InvitationsServiceRegistrationSpec,\n DevicesServiceSpec,\n DevicesServiceRegistrationSpec,\n SpacesServiceSpec,\n SpacesServiceRegistrationSpec,\n NetworkServiceSpec,\n NetworkServiceRegistrationSpec,\n EdgeAgentServiceSpec,\n EdgeAgentServiceRegistrationSpec,\n DataServiceSpec,\n DataServiceRegistrationSpec,\n QueryServiceSpec,\n QueryServiceRegistrationSpec,\n FeedServiceSpec,\n FeedServiceRegistrationSpec,\n LoggingServiceSpec,\n LoggingServiceRegistrationSpec,\n SqlServiceSpec,\n SqlServiceRegistrationSpec,\n DevtoolsHostSpec,\n DevtoolsHostRegistrationSpec,\n];\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as SqlClient from 'effect/sql/SqlClient';\n\nimport { LayerStack } from '@dxos/compute-runtime';\nimport * as ServiceResolver from '@dxos/compute/ServiceResolver';\nimport { type Config, ConfigService } from '@dxos/config';\nimport { type QueryExecutorMode } from '@dxos/echo-host';\nimport * as Hook from '@dxos/effect/Hook';\nimport { type SignalManager } from '@dxos/messaging';\nimport { type TransportFactory } from '@dxos/network-manager';\nimport { Runtime_Client_QueryExecutor } from '@dxos/protocols/buf/dxos/config_pb';\nimport * as SqlExport from '@dxos/sql-sqlite/SqlExport';\n\nimport * as Events from '../../Events.ts';\nimport { type InboxRelay } from '../identity/index.ts';\nimport { clientServiceSpecs } from './layer-specs.ts';\nimport { type ServiceContextRuntimeProps } from './service-stack.ts';\n\n/** The SQL services the stack persists through; the embedder provides them beneath it. */\nexport type ClientServicesSqlContext = SqlClient.SqlClient | SqlExport.SqlExport;\n\n/** Everything the stack resolves against rather than building itself. */\nconst AMBIENT_SERVICES = [ConfigService, Hook.Controller, SqlClient.SqlClient, SqlExport.SqlExport] as const;\n\nexport type ClientServicesStackOptions = {\n /** Overrides for the config-derived runtime props. */\n runtimeProps?: ServiceContextRuntimeProps;\n /** Overrides the config-derived signal manager; tests pass an in-memory one. */\n signalManager?: SignalManager;\n /** Overrides the WebRTC transport; tests pass the in-memory transport. */\n transportFactory?: TransportFactory;\n /** Replaces the EDGE inbox; tests share one relay between clients. */\n inboxRelay?: InboxRelay;\n /** @default true */\n connectionLog?: boolean;\n /**\n * Emit `NetworkingEnabled` as soon as the stack is open. Set `false` when the embedder decides\n * when connecting is safe, as the worker does so the dial cannot compete with boot RPCs.\n * @default true\n */\n autoConnect?: boolean;\n};\n\n/**\n * The configured query evaluation path, if any. `EchoHost` falls back to `DX_ECHO_QUERY_EXECUTOR`\n * and then to the compiled SQL executor, so an unset field stays undefined rather than defaulting\n * here — one default, at the point the option enters the host.\n */\nconst queryExecutorFromConfig = (config: Config): QueryExecutorMode | undefined => {\n switch (config.get('runtime.client.queryExecutor')) {\n case Runtime_Client_QueryExecutor.SQL:\n return 'sql';\n case Runtime_Client_QueryExecutor.MEMORY:\n return 'memory';\n default:\n return undefined;\n }\n};\n\n/**\n * Runtime props from config, with explicit overrides winning where defined.\n */\nexport const runtimePropsFromConfig = (\n config: Config,\n overrides: ServiceContextRuntimeProps = {},\n): ServiceContextRuntimeProps => ({\n disableP2pReplication: config.get('runtime.client.disableP2pReplication', false),\n enableVectorIndexing: config.get('runtime.client.enableVectorIndexing', false),\n queryExecutor: queryExecutorFromConfig(config),\n automergeCredentials: config.get('runtime.client.automergeCredentials', false),\n ...Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== undefined)),\n});\n\n/**\n * The client services stack: the {@link clientServiceSpecs} graph aggregated by a {@link LayerStack},\n * over the ambient services the embedder provides beneath it.\n *\n * Specs are built on demand — resolving a tag builds what that tag needs and nothing else — except\n * the `eager` ones (rpc registrations, lifecycle subscriptions, replicators), which this layer builds\n * as it is created, since nothing would ever ask for them. Reach a service with\n * `ServiceResolver.resolve`, which this layer provides alongside the stack; emit `Opening` and\n * `StackOpened` to boot the components, and closing the layer's scope tears everything down.\n */\nexport const layerClientServices = (\n options: ClientServicesStackOptions = {},\n): Layer.Layer<\n LayerStack.Service | ServiceResolver.ServiceResolver,\n never,\n ClientServicesSqlContext | ConfigService | Hook.Controller\n> => layerBuildEagerSpecs.pipe(Layer.provideMerge(layerSpecsFromConfig(options)));\n\n/**\n * Allows outbound network activity to begin; for embedders that build the stack with\n * `autoConnect: false`.\n */\nexport const enableNetworking: Effect.Effect<void, never, Hook.Controller> = Hook.emit(\n Events.NetworkingEnabled,\n undefined,\n);\n\n/**\n * The stack itself. Config decides which specs the graph has, so the layer is unwrapped from an\n * effect that reads it.\n */\nconst layerSpecsFromConfig = (\n options: ClientServicesStackOptions,\n): Layer.Layer<\n LayerStack.Service | ServiceResolver.ServiceResolver,\n never,\n ClientServicesSqlContext | ConfigService | Hook.Controller\n> =>\n Layer.unwrap(\n Effect.gen(function* () {\n const config = yield* ConfigService;\n return LayerStack.layer({\n layers: clientServiceSpecs({\n ...runtimePropsFromConfig(config, options.runtimeProps),\n edgeFeatures: config.get('runtime.client.edgeFeatures'),\n edgeAvailable: !!config.get('runtime.services.edge.url'),\n signalManager: options.signalManager,\n transportFactory: options.transportFactory,\n inboxRelay: options.inboxRelay,\n connectionLog: options.connectionLog ?? true,\n autoConnect: options.autoConnect ?? true,\n }),\n services: AMBIENT_SERVICES,\n });\n }),\n );\n\n/**\n * A spec that only registers an rpc service or subscribes to a lifecycle event provides no tag for\n * anyone to resolve, so the graph stays dormant until its slice is initialized.\n */\nconst layerBuildEagerSpecs: Layer.Layer<never, never, LayerStack.Service> = Layer.effectDiscard(\n Effect.gen(function* () {\n const stack = yield* LayerStack.Service;\n yield* stack.init().pipe(Effect.orDie);\n }),\n);\n"],"mappings":"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"}
|