@artenx/dshb 0.1.18 → 0.1.19
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/lib/client.js +2157 -567
- package/lib/client.js.map +1 -1
- package/lib/core/index.js +72 -4
- package/lib/core/index.js.map +1 -1
- package/lib/core/node-registry.d.ts +2 -108
- package/lib/core/node-registry.js +43 -2
- package/lib/core/node-registry.js.map +1 -1
- package/lib/core/routes.d.ts +4 -3
- package/lib/core/routes.js +67 -23
- package/lib/core/routes.js.map +1 -1
- package/lib/core/sync/coordinator.d.ts +48 -0
- package/lib/core/sync/coordinator.js +247 -0
- package/lib/core/sync/coordinator.js.map +1 -0
- package/lib/core/sync/host-key.d.ts +2 -0
- package/lib/core/sync/host-key.js +71 -0
- package/lib/core/sync/host-key.js.map +1 -0
- package/lib/core/sync/internal-routes.d.ts +9 -0
- package/lib/core/sync/internal-routes.js +236 -0
- package/lib/core/sync/internal-routes.js.map +1 -0
- package/lib/core/sync/model.d.ts +2 -0
- package/lib/core/sync/model.js +106 -0
- package/lib/core/sync/model.js.map +1 -0
- package/lib/core/sync/node-sync.d.ts +2 -0
- package/lib/core/sync/node-sync.js +660 -0
- package/lib/core/sync/node-sync.js.map +1 -0
- package/lib/core/sync/offline-archive.d.ts +55 -0
- package/lib/core/sync/offline-archive.js +673 -0
- package/lib/core/sync/offline-archive.js.map +1 -0
- package/lib/core/sync/offline-journal.d.ts +22 -0
- package/lib/core/sync/offline-journal.js +74 -0
- package/lib/core/sync/offline-journal.js.map +1 -0
- package/lib/core/sync/offline-routes.d.ts +7 -0
- package/lib/core/sync/offline-routes.js +192 -0
- package/lib/core/sync/offline-routes.js.map +1 -0
- package/lib/core/sync/peer-manager.d.ts +56 -0
- package/lib/core/sync/peer-manager.js +258 -0
- package/lib/core/sync/peer-manager.js.map +1 -0
- package/lib/core/sync/protocol.d.ts +2 -0
- package/lib/core/sync/protocol.js +124 -0
- package/lib/core/sync/protocol.js.map +1 -0
- package/lib/core/sync/remote-helper.d.ts +5 -0
- package/lib/core/sync/remote-helper.js +160 -0
- package/lib/core/sync/remote-helper.js.map +1 -0
- package/lib/core/sync/revision.d.ts +2 -0
- package/lib/core/sync/revision.js +77 -0
- package/lib/core/sync/revision.js.map +1 -0
- package/lib/core/sync/routes.d.ts +9 -0
- package/lib/core/sync/routes.js +339 -0
- package/lib/core/sync/routes.js.map +1 -0
- package/lib/core/sync/scheduler.d.ts +14 -0
- package/lib/core/sync/scheduler.js +81 -0
- package/lib/core/sync/scheduler.js.map +1 -0
- package/lib/core/sync/session-journal.d.ts +2 -0
- package/lib/core/sync/session-journal.js +191 -0
- package/lib/core/sync/session-journal.js.map +1 -0
- package/lib/core/sync/session-routes.d.ts +7 -0
- package/lib/core/sync/session-routes.js +67 -0
- package/lib/core/sync/session-routes.js.map +1 -0
- package/lib/core/sync/session-sync.d.ts +2 -0
- package/lib/core/sync/session-sync.js +2 -0
- package/lib/core/sync/ssh-transport.d.ts +2 -0
- package/lib/core/sync/ssh-transport.js +408 -0
- package/lib/core/sync/ssh-transport.js.map +1 -0
- package/lib/core/sync/stores.d.ts +3 -0
- package/lib/core/sync/stores.js +385 -0
- package/lib/core/sync/stores.js.map +1 -0
- package/lib/core/test.d.ts +1 -1
- package/lib/core/workspace-bindings.d.ts +2 -28
- package/lib/core/workspace-bindings.js +14 -14
- package/lib/core/workspace-bindings.js.map +1 -1
- package/lib/core/workspace-instruction-context.d.ts +3 -2260
- package/lib/core/workspace-instruction-context.js +104 -2
- package/lib/core/workspace-instruction-context.js.map +1 -0
- package/lib/core/workspace-instruction-routes.d.ts +1 -1
- package/lib/core/workspace-instructions.d.ts +2 -68
- package/lib/core/workspace-instructions.js +13 -0
- package/lib/core/workspace-instructions.js.map +1 -1
- package/lib/core/workspaces.d.ts +4 -3
- package/lib/core/workspaces.js +17 -1
- package/lib/core/workspaces.js.map +1 -1
- package/lib/host-key-C5afhAUd.d.ts +30 -0
- package/lib/index-VF8bcBeX.d.ts +2293 -0
- package/lib/{workspace-instruction-context-DytAmaPY.js → lib-gdtU_WKT.js} +159 -102
- package/lib/lib-gdtU_WKT.js.map +1 -0
- package/lib/model-BP7Gw1yk.d.ts +104 -0
- package/lib/node-registry-BTnnM5-k.d.ts +112 -0
- package/lib/node-sync-3Z9QLz2n.d.ts +89 -0
- package/lib/protocol-CV7LGE44.d.ts +35 -0
- package/lib/revision-C9sOlDZ6.d.ts +25 -0
- package/lib/router/router-fs.d.ts +12 -3
- package/lib/router/router-fs.js.map +1 -1
- package/lib/session-journal-pgPqcWn9.d.ts +40 -0
- package/lib/session-sync-EdfwUON5.js +2177 -0
- package/lib/session-sync-EdfwUON5.js.map +1 -0
- package/lib/session-sync-g6qKZzjV.d.ts +1252 -0
- package/lib/ssh-transport-BcIiLxsX.d.ts +55 -0
- package/lib/stores-CKyEt0yk.d.ts +31 -0
- package/lib/workspace-bindings-CsB0TIJB.d.ts +28 -0
- package/lib/workspace-instructions-DirYYiku.d.ts +69 -0
- package/package.json +20 -1
- package/lib/workspace-instruction-context-DytAmaPY.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-sync.js","names":[],"sources":["../../../src/core/sync/node-sync.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\nimport { compareSyncRevision, HybridLogicalClock } from './revision.js'\nimport { isNonNegativeSafeInteger, isRecord, syncRecordKey, type SyncImportMethod, type SyncRecordMetadata, type SyncState } from './model.js'\nimport { NodeRegistry, type NodeCreateInput, type NodeDocker, type NodeProfile, type NodeSecrets, type NodeSsh } from '../node-registry.js'\nimport type { WorkspaceBindingsStore } from '../workspace-bindings.js'\nimport type { SyncStateStore } from './stores.js'\n\nconst MAX_NODE_RECORDS = 10_000\nconst MAX_SECRET_BYTES = 64 * 1024\n\nexport interface SyncNodeProfile {\n name: string\n type: 'remote-ssh' | 'remote-docker'\n ssh: NodeSsh\n docker?: NodeDocker\n}\n\nexport interface SyncNodeEntry {\n metadata: SyncRecordMetadata\n profile?: SyncNodeProfile\n secrets?: NodeSecrets\n}\n\nexport interface SyncNodeManifest {\n protocolVersion: 1\n instanceId: string\n records: SyncNodeEntry[]\n}\n\nexport interface SyncNodeApplyResult {\n created: number\n updated: number\n deleted: number\n pendingRemoval: number\n skipped: number\n}\n\nexport interface SyncNodeView {\n importedVia?: 'peer' | 'offline'\n sourceName?: string\n pendingRemoval: boolean\n credentialsRequired?: boolean\n}\n\nexport class SyncNodeManifestError extends Error {\n constructor(message = 'invalid node sync manifest') {\n super(message)\n this.name = 'SyncNodeManifestError'\n }\n}\n\nexport class SyncNodeInUseError extends Error {\n constructor(readonly workspaces: string[]) {\n super('node is still bound to active workspaces')\n this.name = 'SyncNodeInUseError'\n }\n}\n\ninterface WorkspaceRegistryLike {\n list(): Array<{ path: string; title: string }>\n}\n\nfunction canonicalJson(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`\n const object = value as Record<string, unknown>\n const entries = Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(object[key])}`)\n return `{${entries.join(',')}}`\n}\n\nfunction nodeDigest(profile: SyncNodeProfile, secrets: NodeSecrets | undefined, credentialsRequired: boolean): string {\n const canonicalSecrets = secrets && Object.keys(secrets).length > 0 ? secrets : null\n return `sha256:${createHash('sha256').update(canonicalJson({ profile, secrets: canonicalSecrets, credentialsRequired })).digest('hex')}`\n}\n\nfunction tombstoneDigest(metadata: Pick<SyncRecordMetadata, 'originInstanceId' | 'originEntityId'>): string {\n const origin = { originInstanceId: metadata.originInstanceId, originEntityId: metadata.originEntityId }\n return `sha256:${createHash('sha256').update(canonicalJson({ kind: 'node', origin, deleted: true })).digest('hex')}`\n}\n\nfunction syncable(node: NodeProfile): node is NodeProfile & { type: 'remote-ssh' | 'remote-docker'; ssh: NodeSsh } {\n return (node.type === 'remote-ssh' || node.type === 'remote-docker') && Boolean(node.ssh)\n}\n\nfunction sanitizedProfile(node: NodeProfile): SyncNodeProfile {\n if (!syncable(node)) throw new Error('node is outside the sync scope')\n return {\n name: node.name,\n type: node.type,\n ssh: {\n host: node.ssh.host,\n port: node.ssh.port,\n username: node.ssh.username,\n auth: { kind: node.ssh.auth.kind },\n ...(node.ssh.jump ? {\n jump: node.ssh.jump.map(({ host, port, username }) => ({ host, ...(port ? { port } : {}), ...(username ? { username } : {}) })),\n } : {}),\n ...(node.ssh.hostKeyFingerprint ? { hostKeyFingerprint: node.ssh.hostKeyFingerprint } : {}),\n },\n ...(node.docker ? { docker: { ...node.docker, ...(node.docker.resources ? { resources: { ...node.docker.resources } } : {}) } } : {}),\n }\n}\n\nfunction credentialsRequired(profile: SyncNodeProfile, secrets: NodeSecrets | undefined): boolean {\n if (profile.ssh.auth.kind === 'agent') return true\n if (profile.ssh.auth.kind === 'password') return !secrets?.password\n return !secrets?.privateKey\n}\n\nfunction shareableSecrets(profile: SyncNodeProfile, secrets: NodeSecrets | undefined): NodeSecrets | undefined {\n if (profile.ssh.auth.kind === 'agent') return undefined\n if (profile.ssh.auth.kind === 'password') {\n return secrets?.password ? { password: secrets.password } : undefined\n }\n return secrets?.privateKey\n ? { privateKey: secrets.privateKey, ...(secrets.passphrase ? { passphrase: secrets.passphrase } : {}) }\n : undefined\n}\n\nfunction text(value: unknown, label: string, maxLength: number): string {\n if (typeof value !== 'string' || !value.trim() || value.length > maxLength || /[\\u0000-\\u001f\\u007f]/.test(value)) {\n throw new Error(`invalid node sync ${label}`)\n }\n return value.trim()\n}\n\nfunction parseSsh(value: unknown): NodeSsh {\n if (!isRecord(value)) throw new Error('invalid node sync SSH configuration')\n const allowed = new Set(['host', 'port', 'username', 'auth', 'jump', 'hostKeyFingerprint'])\n if (Object.keys(value).some((key) => !allowed.has(key))) throw new Error('unsupported node sync SSH field')\n if (!Number.isSafeInteger(value.port) || (value.port as number) < 1 || (value.port as number) > 65535) {\n throw new Error('invalid node sync SSH port')\n }\n if (!isRecord(value.auth) || !['password', 'key', 'agent'].includes(String(value.auth.kind))) {\n throw new Error('invalid node sync SSH auth method')\n }\n if (Object.keys(value.auth).some((key) => key !== 'kind')) throw new Error('SSH key paths cannot be imported')\n const jump = value.jump\n if (jump !== undefined && !Array.isArray(jump)) throw new Error('invalid node sync SSH jump list')\n const parsedJump = jump?.map((hop) => {\n if (!isRecord(hop) || Object.keys(hop).some((key) => !['host', 'port', 'username'].includes(key))) {\n throw new Error('invalid node sync SSH jump hop')\n }\n if (hop.port !== undefined && (!Number.isSafeInteger(hop.port) || (hop.port as number) < 1 || (hop.port as number) > 65535)) {\n throw new Error('invalid node sync SSH jump port')\n }\n const host = text(hop.host, 'SSH jump host', 255)\n const username = hop.username === undefined ? undefined : text(hop.username, 'SSH jump username', 128)\n if (/\\s/.test(host) || (username !== undefined && /\\s/.test(username))) throw new Error('invalid node sync SSH jump address')\n return {\n host,\n ...(hop.port === undefined ? {} : { port: hop.port as number }),\n ...(username === undefined ? {} : { username }),\n }\n })\n const fingerprint = value.hostKeyFingerprint\n if (fingerprint !== undefined && (typeof fingerprint !== 'string' || !/^SHA256:[A-Za-z0-9+/]{43}$/.test(fingerprint))) {\n throw new Error('invalid node sync SSH host-key fingerprint')\n }\n const host = text(value.host, 'SSH host', 255)\n const username = text(value.username, 'SSH username', 128)\n if (/\\s/.test(host) || /\\s/.test(username)) throw new Error('invalid node sync SSH address')\n return {\n host,\n port: value.port as number,\n username,\n auth: { kind: value.auth.kind as NodeSsh['auth']['kind'] },\n ...(parsedJump ? { jump: parsedJump } : {}),\n ...(typeof fingerprint === 'string' ? { hostKeyFingerprint: fingerprint } : {}),\n }\n}\n\nfunction parseDocker(value: unknown): NodeDocker {\n if (!isRecord(value)) throw new Error('invalid node sync Docker configuration')\n const allowed = new Set(['mode', 'containerId', 'image', 'resources'])\n if (Object.keys(value).some((key) => !allowed.has(key))) throw new Error('unsupported node sync Docker field')\n if (value.mode !== 'existing' && value.mode !== 'managed') throw new Error('invalid node sync Docker mode')\n const containerId = value.containerId === undefined ? undefined : text(value.containerId, 'Docker container ID', 256)\n const image = value.image === undefined ? undefined : text(value.image, 'Docker image', 512)\n let resources: NodeDocker['resources']\n if (value.resources !== undefined) {\n if (!isRecord(value.resources) || Object.keys(value.resources).some((key) => !['cpus', 'memoryMB'].includes(key))) {\n throw new Error('invalid node sync Docker resources')\n }\n const cpus = value.resources.cpus\n const memoryMB = value.resources.memoryMB\n if (cpus !== undefined && (typeof cpus !== 'number' || !Number.isFinite(cpus) || cpus <= 0)) {\n throw new Error('invalid node sync Docker CPU limit')\n }\n if (memoryMB !== undefined && (!Number.isSafeInteger(memoryMB) || (memoryMB as number) <= 0)) {\n throw new Error('invalid node sync Docker memory limit')\n }\n resources = {\n ...(cpus === undefined ? {} : { cpus: cpus as number }),\n ...(memoryMB === undefined ? {} : { memoryMB: memoryMB as number }),\n }\n }\n return {\n mode: value.mode,\n ...(containerId === undefined ? {} : { containerId }),\n ...(image === undefined ? {} : { image }),\n ...(resources ? { resources } : {}),\n }\n}\n\nfunction parseProfile(value: unknown): SyncNodeProfile {\n if (!isRecord(value)) throw new Error('invalid node sync profile')\n if (Object.keys(value).some((key) => !['name', 'type', 'ssh', 'docker'].includes(key))) {\n throw new Error('unsupported node sync profile field')\n }\n if (value.type !== 'remote-ssh' && value.type !== 'remote-docker') {\n throw new Error('local nodes cannot be imported')\n }\n const ssh = parseSsh(value.ssh)\n if (value.type === 'remote-ssh' && value.docker !== undefined) throw new Error('SSH node contains Docker configuration')\n if (value.type === 'remote-docker' && value.docker === undefined) throw new Error('remote Docker node requires Docker configuration')\n return {\n name: text(value.name, 'name', 64),\n type: value.type,\n ssh,\n ...(value.docker === undefined ? {} : { docker: parseDocker(value.docker) }),\n }\n}\n\nfunction parseSecrets(value: unknown): NodeSecrets | undefined {\n if (value === undefined) return undefined\n if (!isRecord(value) || Object.keys(value).some((key) => !['password', 'privateKey', 'passphrase'].includes(key))) {\n throw new Error('invalid node sync secret payload')\n }\n const result: NodeSecrets = {}\n for (const key of ['password', 'privateKey', 'passphrase'] as const) {\n const secret = value[key]\n if (secret === undefined) continue\n if (typeof secret !== 'string' || Buffer.byteLength(secret, 'utf8') > MAX_SECRET_BYTES || secret.includes('\\0')) {\n throw new Error(`invalid node sync secret: ${key}`)\n }\n if (secret) result[key] = secret\n }\n return Object.keys(result).length > 0 ? result : undefined\n}\n\nfunction validateMetadata(value: unknown): SyncRecordMetadata {\n const safeText = (input: unknown): input is string =>\n typeof input === 'string' && input.length > 0 && input.length <= 512 && !/[\\u0000-\\u001f\\u007f]/.test(input)\n if (\n !isRecord(value) || value.kind !== 'node' ||\n !safeText(value.originInstanceId) ||\n !safeText(value.originEntityId) ||\n !safeText(value.localEntityId) ||\n !isRecord(value.revision) ||\n !isNonNegativeSafeInteger(value.revision.physicalTimeMs) ||\n !isNonNegativeSafeInteger(value.revision.logicalCounter) ||\n !safeText(value.revision.writerInstanceId) ||\n typeof value.contentDigest !== 'string' || !/^sha256:[a-f0-9]{64}$/.test(value.contentDigest) ||\n (value.deleted !== undefined && typeof value.deleted !== 'boolean') ||\n (value.pendingRemoval !== undefined && typeof value.pendingRemoval !== 'boolean') ||\n (value.credentialsRequired !== undefined && typeof value.credentialsRequired !== 'boolean') ||\n (value.importedVia !== undefined && value.importedVia !== 'peer' && value.importedVia !== 'offline') ||\n (value.sourceName !== undefined && !safeText(value.sourceName))\n ) {\n throw new Error('invalid node sync metadata')\n }\n return value as unknown as SyncRecordMetadata\n}\n\nfunction makeTombstone(metadata: SyncRecordMetadata, revision: SyncRecordMetadata['revision']): SyncRecordMetadata {\n const origin = { originInstanceId: metadata.originInstanceId, originEntityId: metadata.originEntityId }\n return {\n ...metadata,\n revision,\n contentDigest: tombstoneDigest(origin),\n deleted: true,\n pendingRemoval: false,\n }\n}\n\nfunction makePlaceholderLocalId(origin: { originInstanceId: string; originEntityId: string }): string {\n return `t-${createHash('sha256').update(canonicalJson(origin)).digest('hex').slice(0, 24)}`\n}\n\nfunction makeImportedLocalId(origin: { originInstanceId: string; originEntityId: string }): string {\n return `s-${createHash('sha256').update(canonicalJson(origin)).digest('hex').slice(0, 32)}`\n}\n\nexport class SyncNodeService {\n private mutationTail: Promise<void> = Promise.resolve()\n\n constructor(\n private readonly registry: NodeRegistry,\n private readonly bindings: WorkspaceBindingsStore,\n private readonly state: SyncStateStore,\n private readonly getWorkspaceRegistry?: () => WorkspaceRegistryLike | undefined,\n private readonly disposeWorld?: (nodeId: string) => void,\n ) {}\n\n exportManifest(): Promise<SyncNodeManifest> {\n return this.serializeMutation(() => this.exportManifestNow())\n }\n\n private async exportManifestNow(): Promise<SyncNodeManifest> {\n const instanceId = this.state.instanceId()\n const initial = this.state.read()\n const clock = new HybridLogicalClock(instanceId, initial.clock)\n const records = new Map(Object.entries(initial.records))\n const changed = new Map<string, SyncRecordMetadata>()\n const localRecords = new Map<string, SyncRecordMetadata>()\n for (const metadata of records.values()) {\n if (metadata.kind !== 'node') continue\n const existing = localRecords.get(metadata.localEntityId)\n if (!existing || compareSyncRevision(metadata.revision, existing.revision) > 0) {\n localRecords.set(metadata.localEntityId, metadata)\n }\n }\n const entries: SyncNodeEntry[] = []\n for (const node of this.registry.list()) {\n if (!syncable(node)) continue\n const profile = sanitizedProfile(node)\n const secrets = shareableSecrets(profile, parseSecrets(await this.registry.getSecrets(node.id)))\n const credentialsNeeded = credentialsRequired(profile, secrets)\n const digest = nodeDigest(profile, secrets, credentialsNeeded)\n const current = localRecords.get(node.id)\n if (current?.deleted) continue\n let metadata = current\n if (!metadata || metadata.contentDigest !== digest || metadata.credentialsRequired !== credentialsNeeded) {\n const revision = clock.tick()\n metadata = {\n ...(current ?? {\n kind: 'node' as const,\n originInstanceId: instanceId,\n originEntityId: node.id,\n localEntityId: node.id,\n }),\n kind: 'node',\n localEntityId: node.id,\n revision,\n contentDigest: digest,\n deleted: false,\n pendingRemoval: false,\n credentialsRequired: credentialsNeeded,\n }\n const key = syncRecordKey('node', metadata)\n records.set(key, metadata)\n localRecords.set(node.id, metadata)\n changed.set(key, metadata)\n }\n entries.push({ metadata, profile, ...(secrets ? { secrets } : {}) })\n }\n\n for (const metadata of records.values()) {\n if (metadata.kind === 'node' && metadata.deleted && !entries.some((entry) => sameOrigin(entry.metadata, metadata))) {\n entries.push({ metadata })\n }\n }\n if (changed.size > 0) {\n this.state.update((state) => {\n mergeClock(state, clock.snapshot())\n for (const [key, metadata] of changed) state.records[key] = metadata\n })\n }\n return { protocolVersion: 1, instanceId, records: entries }\n }\n\n validateManifest(value: unknown): SyncNodeEntry[] {\n if (!Array.isArray(value) || value.length > MAX_NODE_RECORDS) throw new SyncNodeManifestError()\n try {\n const entries = value.map(parseEntry)\n const keys = entries.map((entry) => syncRecordKey('node', entry.metadata))\n if (new Set(keys).size !== keys.length) throw new Error('duplicate origins')\n return entries\n } catch (error) {\n throw new SyncNodeManifestError(error instanceof Error ? error.message : 'invalid node sync manifest')\n }\n }\n\n async preflightManifest(value: unknown): Promise<void> {\n const entries = this.validateManifest(value)\n const localInstanceId = this.state.instanceId()\n const state = this.state.read()\n for (const entry of entries) {\n const { metadata } = entry\n const current = state.records[syncRecordKey('node', metadata)]\n if (current) {\n const comparison = compareSyncRevision(metadata.revision, current.revision)\n if (comparison === 0 && (metadata.contentDigest !== current.contentDigest || Boolean(metadata.deleted) !== Boolean(current.deleted))) {\n throw new SyncNodeManifestError('conflicting node records share the same revision')\n }\n continue\n }\n if (metadata.originInstanceId !== localInstanceId || metadata.deleted) continue\n const local = this.registry.get(metadata.originEntityId)\n if (!local) continue\n const profile = sanitizedProfile(local)\n const secrets = shareableSecrets(profile, parseSecrets(await this.registry.getSecrets(local.id)))\n const required = credentialsRequired(profile, secrets)\n if (nodeDigest(profile, secrets, required) !== metadata.contentDigest) {\n throw new SyncNodeManifestError('local origin metadata is missing for a changed node')\n }\n }\n }\n\n applyManifest(value: unknown, sourceName: string, importedVia: SyncImportMethod = 'peer'): Promise<SyncNodeApplyResult> {\n return this.serializeMutation(() => this.applyManifestNow(value, sourceName, importedVia))\n }\n\n private async applyManifestNow(value: unknown, sourceName: string, importedVia: SyncImportMethod): Promise<SyncNodeApplyResult> {\n await this.preflightManifest(value)\n const entries = this.validateManifest(value)\n let safeSourceName: string\n try {\n safeSourceName = text(sourceName, 'source name', 128)\n } catch (error) {\n throw new SyncNodeManifestError(error instanceof Error ? error.message : 'invalid node sync manifest')\n }\n const result: SyncNodeApplyResult = { created: 0, updated: 0, deleted: 0, pendingRemoval: 0, skipped: 0 }\n const localInstanceId = this.state.instanceId()\n const initial = this.state.read()\n const clock = new HybridLogicalClock(localInstanceId, initial.clock)\n const records = new Map(Object.entries(initial.records))\n const changed = new Map<string, SyncRecordMetadata>()\n\n for (const entry of entries) {\n const { metadata } = entry\n const key = syncRecordKey('node', metadata)\n const current = records.get(key)\n if (metadata.originInstanceId === localInstanceId && !current) {\n const local = this.registry.get(metadata.originEntityId)\n if (local && !metadata.deleted) {\n const localProfile = sanitizedProfile(local)\n const localSecrets = shareableSecrets(localProfile, parseSecrets(await this.registry.getSecrets(local.id)))\n const localRequired = credentialsRequired(localProfile, localSecrets)\n if (nodeDigest(localProfile, localSecrets, localRequired) !== metadata.contentDigest) {\n throw new SyncNodeManifestError('local origin metadata is missing for a changed node')\n }\n clock.observe(metadata.revision)\n const localMetadata = { ...metadata, localEntityId: local.id, importedVia: undefined, sourceName: undefined }\n records.set(key, localMetadata)\n changed.set(key, localMetadata)\n this.state.update((state) => {\n mergeClock(state, clock.snapshot())\n state.records[key] = localMetadata\n })\n result.skipped += 1\n continue\n }\n }\n\n if (current) {\n const comparison = compareSyncRevision(metadata.revision, current.revision)\n if (comparison < 0) {\n result.skipped += 1\n continue\n }\n if (comparison === 0) {\n if (metadata.contentDigest !== current.contentDigest || Boolean(metadata.deleted) !== Boolean(current.deleted)) {\n throw new SyncNodeManifestError('conflicting node records share the same revision')\n }\n result.skipped += 1\n continue\n }\n }\n clock.observe(metadata.revision)\n\n const mappedLocalId = current?.deleted && current.localEntityId.startsWith('t-')\n ? undefined\n : current?.localEntityId\n if (metadata.deleted) {\n const localId = mappedLocalId ?? (metadata.originInstanceId === localInstanceId\n ? metadata.originEntityId\n : makePlaceholderLocalId(metadata))\n const pendingMetadata = {\n ...metadata,\n localEntityId: localId,\n importedVia: metadata.originInstanceId === localInstanceId ? undefined : importedVia,\n sourceName: metadata.originInstanceId === localInstanceId ? undefined : safeSourceName,\n pendingRemoval: true,\n }\n this.saveRecord(pendingMetadata)\n records.set(key, pendingMetadata)\n changed.set(key, pendingMetadata)\n const pending = this.hasActiveBinding(localId)\n if (pending) {\n result.pendingRemoval += 1\n } else {\n await this.removeNodeAndStaleBindings(localId)\n const tombstoneMetadata = {\n ...metadata,\n localEntityId: localId,\n importedVia: metadata.originInstanceId === localInstanceId ? undefined : importedVia,\n sourceName: metadata.originInstanceId === localInstanceId ? undefined : safeSourceName,\n pendingRemoval: false,\n }\n records.set(key, tombstoneMetadata)\n changed.set(key, tombstoneMetadata)\n this.saveRecord(tombstoneMetadata)\n result.deleted += 1\n }\n continue\n }\n\n if (!entry.profile) throw new SyncNodeManifestError('node profile is missing from active manifest record')\n const input = toNodeCreateInput(entry.profile, entry.secrets)\n const localId = mappedLocalId ?? (metadata.originInstanceId === localInstanceId\n ? metadata.originEntityId\n : makeImportedLocalId(metadata))\n let node: NodeProfile\n if (this.registry.get(localId)) {\n node = await this.registry.updateImported(localId, input)\n result.updated += 1\n } else {\n node = await this.registry.createImported(input, localId)\n result.created += 1\n }\n this.disposeWorld?.(node.id)\n const appliedMetadata = {\n ...metadata,\n localEntityId: node.id,\n importedVia: metadata.originInstanceId === localInstanceId ? undefined : importedVia,\n sourceName: metadata.originInstanceId === localInstanceId ? undefined : safeSourceName,\n deleted: false,\n pendingRemoval: false,\n credentialsRequired: credentialsRequired(entry.profile, entry.secrets),\n }\n records.set(key, appliedMetadata)\n changed.set(key, appliedMetadata)\n this.state.update((state) => {\n mergeClock(state, clock.snapshot())\n state.records[key] = appliedMetadata\n })\n }\n\n const finalClock = clock.snapshot()\n if (\n changed.size > 0 ||\n finalClock.physicalTimeMs !== initial.clock.physicalTimeMs ||\n finalClock.logicalCounter !== initial.clock.logicalCounter\n ) {\n this.state.update((state) => {\n mergeClock(state, finalClock)\n for (const [key, metadata] of changed) state.records[key] = metadata\n })\n }\n return result\n }\n\n removeLocalNode(nodeId: string, remove: () => Promise<void>): Promise<void> {\n return this.serializeMutation(() => this.removeLocalNodeNow(nodeId, remove))\n }\n\n private async removeLocalNodeNow(nodeId: string, remove: () => Promise<void>): Promise<void> {\n const node = this.registry.get(nodeId)\n if (!node || !syncable(node)) {\n await remove()\n return\n }\n\n const active = this.activeBindings(nodeId)\n if (active.length > 0) throw new SyncNodeInUseError(active.map((binding) => binding.workspaceId ?? binding.mirrorPath))\n\n const current = findNodeRecord(Object.values(this.state.read().records), nodeId)\n const instanceId = this.state.instanceId()\n const origin = current ?? {\n kind: 'node' as const,\n originInstanceId: instanceId,\n originEntityId: nodeId,\n localEntityId: nodeId,\n revision: { physicalTimeMs: 0, logicalCounter: 0, writerInstanceId: instanceId },\n contentDigest: '',\n }\n const tombstone = { ...makeTombstone(origin, this.state.nextRevision()), pendingRemoval: true }\n const key = syncRecordKey('node', tombstone)\n this.saveRecord(tombstone)\n try {\n await remove()\n this.saveRecord({ ...tombstone, pendingRemoval: false })\n } catch (error) {\n this.state.update((state) => {\n if (current) state.records[key] = current\n else delete state.records[key]\n })\n throw error\n }\n }\n\n view(nodeId: string): SyncNodeView | undefined {\n return this.views([nodeId]).get(nodeId)\n }\n\n views(nodeIds: readonly string[]): Map<string, SyncNodeView> {\n const wanted = new Set(nodeIds)\n const metadataById = new Map<string, SyncRecordMetadata>()\n for (const metadata of Object.values(this.state.read().records)) {\n if (metadata.kind !== 'node' || !wanted.has(metadata.localEntityId)) continue\n const current = metadataById.get(metadata.localEntityId)\n if (!current || compareSyncRevision(metadata.revision, current.revision) > 0) {\n metadataById.set(metadata.localEntityId, metadata)\n }\n }\n const views = new Map<string, SyncNodeView>()\n for (const [localId, metadata] of metadataById) {\n views.set(localId, {\n ...(metadata.importedVia ? { importedVia: metadata.importedVia } : {}),\n ...(metadata.sourceName ? { sourceName: metadata.sourceName } : {}),\n pendingRemoval: Boolean(metadata.deleted && metadata.pendingRemoval),\n ...(metadata.credentialsRequired === undefined ? {} : { credentialsRequired: metadata.credentialsRequired }),\n })\n }\n return views\n }\n\n isPendingRemoval(nodeId: string): boolean {\n return this.view(nodeId)?.pendingRemoval ?? false\n }\n\n originForLocalNode(nodeId: string): { originInstanceId: string; originEntityId: string } | undefined {\n const metadata = findNodeRecord(Object.values(this.state.read().records), nodeId)\n return !metadata || metadata.deleted\n ? undefined\n : { originInstanceId: metadata.originInstanceId, originEntityId: metadata.originEntityId }\n }\n\n localNodeIdForOrigin(origin: { originInstanceId: string; originEntityId: string }): string | undefined {\n const metadata = Object.values(this.state.read().records)\n .filter((record) => record.kind === 'node' &&\n record.originInstanceId === origin.originInstanceId && record.originEntityId === origin.originEntityId)\n .sort((a, b) => compareSyncRevision(b.revision, a.revision))[0]\n return !metadata || metadata.deleted ? undefined : metadata.localEntityId\n }\n\n withAvailableRemoteNode<T>(\n origin: { originInstanceId: string; originEntityId: string },\n operation: (nodeId: string) => Promise<T>,\n ): Promise<T | undefined> {\n return this.serializeMutation(async () => {\n const nodeId = this.localNodeIdForOrigin(origin)\n const node = nodeId ? this.registry.get(nodeId) : undefined\n if (!node || !syncable(node) || this.isPendingRemoval(node.id)) return undefined\n return operation(node.id)\n })\n }\n\n reconcilePendingRemovals(): Promise<void> {\n return this.serializeMutation(() => this.reconcilePendingRemovalsNow())\n }\n\n private async reconcilePendingRemovalsNow(): Promise<void> {\n const records = Object.values(this.state.read().records).filter(\n (metadata) => metadata.kind === 'node' && metadata.deleted && metadata.pendingRemoval,\n )\n for (const metadata of records) {\n if (this.hasActiveBinding(metadata.localEntityId)) continue\n await this.removeNodeAndStaleBindings(metadata.localEntityId)\n this.saveRecord({ ...metadata, pendingRemoval: false })\n }\n }\n\n private hasActiveBinding(nodeId: string): boolean {\n return this.activeBindings(nodeId).length > 0\n }\n\n private activeBindings(nodeId: string): Array<{ mirrorPath: string; workspaceId?: string }> {\n const bindings = this.bindings.list().filter((binding) => binding.nodeId === nodeId)\n if (bindings.length === 0) return []\n let registry: WorkspaceRegistryLike | undefined\n try {\n registry = this.getWorkspaceRegistry?.()\n } catch {}\n if (!registry) return bindings\n try {\n const activePaths = new Set(registry.list().map((workspace) => workspace.path))\n return bindings.filter((binding) => activePaths.has(binding.mirrorPath))\n } catch {\n return bindings\n }\n }\n\n private async removeNodeAndStaleBindings(nodeId: string): Promise<void> {\n const bindings = this.bindings.list().filter((binding) => binding.nodeId === nodeId)\n let activePaths: Set<string> | undefined\n try {\n const registry = this.getWorkspaceRegistry?.()\n if (registry) activePaths = new Set(registry.list().map((workspace) => workspace.path))\n } catch {}\n for (const binding of bindings) {\n if (activePaths?.has(binding.mirrorPath)) continue\n this.bindings.remove(binding.mirrorPath)\n }\n if (this.registry.get(nodeId)) {\n await this.registry.removeImported(nodeId)\n this.disposeWorld?.(nodeId)\n } else {\n await this.registry.removeImported(nodeId)\n }\n }\n\n private saveRecord(metadata: SyncRecordMetadata): void {\n const key = syncRecordKey('node', metadata)\n this.state.update((state) => {\n state.records[key] = metadata\n })\n }\n\n private serializeMutation<T>(operation: () => Promise<T>): Promise<T> {\n const result = this.mutationTail.then(operation)\n this.mutationTail = result.then(() => undefined, () => undefined)\n return result\n }\n}\n\nfunction mergeClock(state: SyncState, incoming: SyncState['clock']): void {\n if (\n incoming.physicalTimeMs > state.clock.physicalTimeMs ||\n (incoming.physicalTimeMs === state.clock.physicalTimeMs && incoming.logicalCounter > state.clock.logicalCounter)\n ) {\n state.clock = incoming\n }\n}\n\nfunction findNodeRecord(records: Iterable<SyncRecordMetadata>, localId: string): SyncRecordMetadata | undefined {\n return [...records]\n .filter((metadata) => metadata.kind === 'node' && metadata.localEntityId === localId)\n .sort((a, b) => compareSyncRevision(b.revision, a.revision))[0]\n}\n\nfunction sameOrigin(a: SyncRecordMetadata, b: SyncRecordMetadata): boolean {\n return a.kind === b.kind && a.originInstanceId === b.originInstanceId && a.originEntityId === b.originEntityId\n}\n\nfunction toNodeCreateInput(profile: SyncNodeProfile, secrets?: NodeSecrets): NodeCreateInput {\n return {\n name: profile.name,\n type: profile.type,\n ssh: profile.ssh,\n ...(profile.docker ? { docker: profile.docker } : {}),\n ...(secrets ? { secrets } : {}),\n }\n}\n\nfunction parseEntry(value: unknown): SyncNodeEntry {\n if (!isRecord(value)) throw new Error('invalid node sync entry')\n const metadata = validateMetadata(value.metadata)\n if (metadata.deleted) {\n if (value.profile !== undefined || value.secrets !== undefined || metadata.contentDigest !== tombstoneDigest(metadata)) {\n throw new Error('invalid node sync tombstone')\n }\n return { metadata }\n }\n\n const profile = parseProfile(value.profile)\n const rawSecrets = parseSecrets(value.secrets)\n if (\n (profile.ssh.auth.kind === 'agent' && rawSecrets) ||\n (profile.ssh.auth.kind === 'password' && (rawSecrets?.privateKey || rawSecrets?.passphrase)) ||\n (profile.ssh.auth.kind === 'key' && (rawSecrets?.password || (!rawSecrets?.privateKey && rawSecrets?.passphrase)))\n ) {\n throw new Error('node sync secrets do not match the SSH auth method')\n }\n const secrets = shareableSecrets(profile, rawSecrets)\n const needed = credentialsRequired(profile, secrets)\n if (metadata.credentialsRequired !== undefined && metadata.credentialsRequired !== needed) {\n throw new Error('node sync credential status does not match its payload')\n }\n if (metadata.contentDigest !== nodeDigest(profile, secrets, needed)) throw new Error('node sync digest mismatch')\n return { metadata: { ...metadata, credentialsRequired: needed }, profile, ...(secrets ? { secrets } : {}) }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { n as SyncStateStore } from "../../stores-CKyEt0yk.js";
|
|
2
|
+
import { s as SyncNodeService } from "../../node-sync-3Z9QLz2n.js";
|
|
3
|
+
import { c as SyncSessionService } from "../../session-sync-g6qKZzjV.js";
|
|
4
|
+
//#region src/core/sync/offline-archive.d.ts
|
|
5
|
+
declare const MAX_OFFLINE_ARCHIVE_BYTES: number;
|
|
6
|
+
declare class SyncOfflineArchiveError extends Error {
|
|
7
|
+
readonly code: string;
|
|
8
|
+
constructor(code: string, message: string, cause?: unknown);
|
|
9
|
+
}
|
|
10
|
+
interface SyncOfflineArchiveFile {
|
|
11
|
+
path: string;
|
|
12
|
+
bytes: number;
|
|
13
|
+
cleanup(): void;
|
|
14
|
+
}
|
|
15
|
+
interface SyncOfflineImportResult {
|
|
16
|
+
nodes: {
|
|
17
|
+
created: number;
|
|
18
|
+
updated: number;
|
|
19
|
+
deleted: number;
|
|
20
|
+
pendingRemoval: number;
|
|
21
|
+
skipped: number;
|
|
22
|
+
};
|
|
23
|
+
sessions?: {
|
|
24
|
+
created: number;
|
|
25
|
+
updated: number;
|
|
26
|
+
archived: number;
|
|
27
|
+
deleted: number;
|
|
28
|
+
skipped: number;
|
|
29
|
+
unmapped: number;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
declare function validateOfflineZipArchive(archive: Buffer): void;
|
|
33
|
+
declare class SyncOfflineArchiveService {
|
|
34
|
+
private readonly nodes;
|
|
35
|
+
private readonly sessions;
|
|
36
|
+
private readonly getAvailableBytes;
|
|
37
|
+
private readonly state?;
|
|
38
|
+
private operationTail;
|
|
39
|
+
private readonly home;
|
|
40
|
+
private readonly journal;
|
|
41
|
+
constructor(nodes: SyncNodeService, sessions: SyncSessionService, home?: string, getAvailableBytes?: (path: string) => bigint, state?: SyncStateStore | undefined);
|
|
42
|
+
exportArchive(password: string, includeSessions?: boolean): Promise<SyncOfflineArchiveFile>;
|
|
43
|
+
importArchive(password: string, input: AsyncIterable<Uint8Array>): Promise<SyncOfflineImportResult>;
|
|
44
|
+
recoverPending(): Promise<void>;
|
|
45
|
+
cleanupStagingDirectories(): void;
|
|
46
|
+
private exportArchiveNow;
|
|
47
|
+
private importArchiveNow;
|
|
48
|
+
private recoverPendingNow;
|
|
49
|
+
private preflightPayloads;
|
|
50
|
+
private applyJournaledPayloads;
|
|
51
|
+
private serializeMutation;
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { MAX_OFFLINE_ARCHIVE_BYTES, SyncOfflineArchiveError, SyncOfflineArchiveFile, SyncOfflineArchiveService, SyncOfflineImportResult, validateOfflineZipArchive };
|
|
55
|
+
//# sourceMappingURL=offline-archive.d.ts.map
|