@tinycloud/sdk-services 3.1.0-beta.13 → 3.1.0-beta.14
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/index.cjs +47 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +47 -8
- package/dist/index.js.map +1 -1
- package/dist/kv/index.cjs +47 -8
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +10 -0
- package/dist/kv/index.d.ts +10 -0
- package/dist/kv/index.js +47 -8
- package/dist/kv/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/diagnostics.ts","../src/debug.ts","../src/types.schema.ts","../src/context.ts","../src/errors.ts","../src/encryption/networkId.ts","../src/base/BaseService.ts","../src/kv/PrefixedKVService.ts","../src/kv/types.ts","../src/kv/KVService.ts","../src/responseErrors.ts","../src/sql/SQLMigrations.ts","../src/sql/DatabaseHandle.ts","../src/sql/types.ts","../src/sql/SQLService.ts","../src/duckdb/DuckDbDatabaseHandle.ts","../src/duckdb/types.ts","../src/duckdb/DuckDbService.ts","../src/hooks/HooksService.ts","../src/quota/TinyCloudQuota.ts","../src/vault/types.ts","../src/vault/SignatureCache.ts","../src/vault/DataVaultService.ts","../src/vault/createVaultCrypto.ts","../src/secrets/paths.ts","../src/secrets/SecretsService.ts","../src/encryption/canonical.ts","../src/encryption/types.ts","../src/encryption/discovery.ts","../src/encryption/envelope.ts","../src/encryption/invocation.ts","../src/encryption/receiverKey.ts","../src/encryption/response.ts","../src/encryption/EncryptionService.ts","../src/encryption/index.ts"],"sourcesContent":["/**\n * TinyCloud SDK Services\n *\n * Platform-agnostic services with plugin architecture for TinyCloud.\n *\n * @packageDocumentation\n * @module @tinycloud/sdk-services\n *\n * @example\n * ```typescript\n * import {\n * ServiceContext,\n * BaseService,\n * Result,\n * ErrorCodes,\n * } from '@tinycloud/sdk-services';\n *\n * // Create a context\n * const context = new ServiceContext({\n * invoke: wasmInvoke,\n * hosts: ['https://node.tinycloud.xyz'],\n * });\n *\n * // Create and register a service\n * const kv = new KVService({ prefix: 'myapp' });\n * context.registerService('kv', kv);\n * kv.initialize(context);\n *\n * // Use the service\n * const result = await kv.get('key');\n * if (result.ok) {\n * console.log(result.data);\n * }\n * ```\n */\n\n// Core types\nexport type {\n Result,\n ServiceError,\n PermissionHint,\n StorageQuotaInfo,\n ErrorCode,\n IServiceContext,\n IService,\n ServiceSession,\n RetryPolicy,\n InvokeFunction,\n InvokeAnyFunction,\n InvokeAnyEntry,\n InvocationFact,\n InvocationFacts,\n FetchFunction,\n FetchRequestInit,\n FetchResponse,\n ServiceHeaders,\n EventHandler,\n TelemetryConfig,\n TelemetryEventHandler,\n ServiceRequestEvent,\n ServiceResponseEvent,\n ServiceErrorEvent,\n ServiceRetryEvent,\n TelemetrySpanEvent,\n} from \"./types\";\n\nexport {\n ErrorCodes,\n defaultRetryPolicy,\n TelemetryEvents,\n ok,\n err,\n serviceError,\n} from \"./types\";\n\nexport {\n TinyCloudDebugLogger,\n tinyCloudDebugLogger,\n enableTinyCloudDebug,\n disableTinyCloudDebug,\n getTinyCloudDebugLogs,\n clearTinyCloudDebugLogs,\n installTinyCloudDebugGlobals,\n} from \"./debug\";\nexport type {\n TinyCloudDebugEvent,\n TinyCloudDebugLevel,\n TinyCloudDebugEnableOptions,\n TinyCloudDebugTimer,\n} from \"./debug\";\n\n// Zod schemas and validation\nexport {\n // Schemas\n ServiceErrorSchema,\n KVResponseHeadersSchema,\n KVListResponseSchema,\n ServiceRequestEventSchema,\n ServiceResponseEventSchema,\n ServiceErrorEventSchema,\n ServiceRetryEventSchema,\n TelemetrySpanEventSchema,\n RetryPolicySchema,\n ServiceSessionSchema,\n GenericResultSchema,\n GenericKVResponseSchema,\n KVListResultSchema,\n // Schema factories\n createResultSchema,\n createKVResponseSchema,\n // Validation functions\n validateServiceError,\n validateKVListResponse,\n validateKVResponseHeaders,\n validateServiceSession,\n validateRetryPolicy,\n validateServiceRequestEvent,\n validateServiceResponseEvent,\n validateTelemetrySpanEvent,\n} from \"./types.schema\";\n\nexport type {\n // Inferred types from schemas\n ValidationError,\n ServiceErrorType,\n KVResponseHeadersType,\n KVListResponseType,\n GenericKVResponseType,\n KVListResultType,\n ServiceRequestEventType,\n ServiceResponseEventType,\n ServiceErrorEventType,\n ServiceRetryEventType,\n TelemetrySpanEventType,\n RetryPolicyType,\n ServiceSessionType,\n} from \"./types.schema\";\n\n// Context\nexport { ServiceContext } from \"./context\";\nexport type { ServiceContextConfig } from \"./context\";\n\n// Errors\nexport {\n authRequiredError,\n authExpiredError,\n networkError,\n timeoutError,\n abortedError,\n notFoundError,\n permissionDeniedError,\n wrapError,\n errorResult,\n storageQuotaExceededError,\n storageLimitReachedError,\n storageRejectionError,\n parseStorageQuotaBytes,\n isStorageFullError,\n STORAGE_FULL_MESSAGE,\n STORAGE_WRITE_TOO_LARGE_MESSAGE,\n parseAuthError,\n authUnauthorizedError,\n authorizationVerdictOf,\n validatedCapabilityOf,\n parseCapabilityResource,\n type AuthorizationVerdict,\n parsePermissionHint,\n parsePermissionHintFromErrorText,\n} from \"./errors\";\n\n// Base service\nexport { BaseService } from \"./base/index\";\nexport type {\n ServiceConstructor,\n ServiceRegistration,\n BaseServiceOptions,\n RequestSignal,\n} from \"./base/index\";\n\n// KV service\nexport {\n DEFAULT_SIGNED_READ_URL_EXPIRY_MS,\n KVService,\n PrefixedKVService,\n IKVService,\n KVAction,\n} from \"./kv\";\nexport type {\n IPrefixedKVService,\n KVServiceConfig,\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVBatchReadResponse,\n KVListOptions,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVSignedReadUrlResponse,\n KVChange,\n KVChangesAuthority,\n KVChangesOptions,\n KVChangesResponse,\n KVResponseHeaders,\n KVActionType,\n} from \"./kv\";\n\n// SQL service\nexport { SQLService, DatabaseHandle, SQLMigrations, SQLAction } from \"./sql\";\nexport type { ISQLService, IDatabaseHandle, ISQLMigrations } from \"./sql\";\nexport type {\n SQLServiceConfig,\n QueryOptions,\n ExecuteOptions,\n BatchOptions,\n SqlValue,\n SqlStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n SqlMigration,\n SqlMigrationApplyOptions,\n SqlMigrationApplyResponse,\n SQLActionType,\n} from \"./sql\";\n\n// DuckDB service\nexport { DuckDbService, DuckDbDatabaseHandle, DuckDbAction } from \"./duckdb\";\nexport type { IDuckDbService, IDuckDbDatabaseHandle } from \"./duckdb\";\nexport type {\n DuckDbServiceConfig,\n DuckDbQueryOptions,\n DuckDbExecuteOptions,\n DuckDbBatchOptions,\n DuckDbOptions,\n DuckDbValue,\n DuckDbStatement,\n DuckDbQueryResponse,\n DuckDbExecuteResponse,\n DuckDbBatchResponse,\n DuckDbActionType,\n SchemaInfo,\n TableInfo,\n ColumnInfo,\n ViewInfo,\n} from \"./duckdb\";\n\n// Hooks service\nexport { HooksService } from \"./hooks\";\nexport type {\n IHooksService,\n HookServiceName,\n HookSubscription,\n HookEvent,\n HookStreamEvent,\n HookWebhookScope,\n HookWebhookRegistration,\n HookWebhookRecord,\n HookWebhookListOptions,\n HookWebhookUnregisterOptions,\n SubscribeOptions,\n HooksServiceConfig,\n HookStreamRetryConfig,\n} from \"./hooks\";\n\n// Quota\nexport { TinyCloudQuota } from \"./quota\";\nexport type { QuotaConfig, QuotaStatus } from \"./quota\";\n\n// Vault service\nexport {\n DataVaultService,\n VaultHeaders,\n VaultPublicSpaceKVActions,\n createVaultCrypto,\n} from \"./vault\";\nexport type {\n IDataVaultService,\n VaultCrypto,\n WasmVaultFunctions,\n} from \"./vault\";\nexport type {\n DataVaultConfig,\n VaultPutOptions,\n VaultGetOptions,\n VaultListOptions,\n VaultListPage,\n VaultGrantOptions,\n VaultEntry,\n VaultNetworkReadResult,\n VaultError,\n} from \"./vault\";\n\nexport {\n SecretsService,\n SECRET_NAME_RE,\n canonicalizeSecretScope,\n parseSecretCatalogKey,\n resolveSecretListPrefix,\n resolveSecretPath,\n} from \"./secrets\";\nexport type {\n ISecretsService,\n SecretCatalogEntry,\n SecretPayload,\n SecretsError,\n ParsedSecretCatalogKey,\n ResolvedSecretPath,\n SecretScopeOptions,\n} from \"./secrets\";\n\n// Encryption service (network-scoped one-of-one decrypt)\nexport {\n EncryptionService,\n DecryptTransportResponseError,\n parseNetworkId,\n buildNetworkId,\n isNetworkId,\n networkDiscoveryKey,\n NetworkIdError,\n ENCRYPTION_NETWORK_URN_PREFIX,\n NETWORK_NAME_PATTERN,\n canonicalize as canonicalizeEncryptionJson,\n canonicalHashHex,\n hexEncode,\n hexDecode,\n base64Encode,\n base64Decode,\n utf8Encode,\n utf8Decode,\n encryptToNetwork,\n decryptEnvelopeWithKey,\n validateEnvelope,\n generateRandomReceiverKey,\n deriveSignedReceiverKey,\n buildCanonicalDecryptRequest,\n buildDecryptFacts,\n buildDecryptAttenuation,\n buildDecryptInvocation,\n checkDecryptInvocationInput,\n verifyDecryptResponse,\n canonicalSignedResponse,\n openWrappedKey,\n discoverNetwork,\n ensureNetworkUsableForDecrypt,\n DEFAULT_ENCRYPTION_ALG,\n ENVELOPE_VERSION,\n DEFAULT_KEY_VERSION,\n DECRYPT_FACT_TYPE,\n DECRYPT_RESULT_TYPE,\n DECRYPT_ACTION,\n ENCRYPTION_SERVICE,\n ENCRYPTION_SERVICE_SHORT,\n encryptionError,\n} from \"./encryption\";\nexport type {\n IEncryptionService,\n EncryptionServiceConfig,\n DecryptTransport,\n EncryptToNetworkOptions,\n DecryptEnvelopeOptions,\n ParsedNetworkId,\n BuildDecryptInvocationInput,\n BuiltDecryptInvocation,\n CanonicalJson,\n DecryptCapabilityProof,\n DecryptInvocationFact,\n DecryptInvocationSigner,\n DecryptRequestBody,\n DecryptResponseBody,\n EncryptionCrypto,\n EncryptionError,\n EncryptionErrorInput,\n InlineEncryptedEnvelope,\n NetworkDescriptor,\n ReceiverKeyPair,\n ReceiverKeySigner,\n EncryptToNetworkInput,\n EncryptToNetworkResult,\n CanonicalDecryptRequest,\n BuildCanonicalDecryptRequestInput,\n BuildDecryptFactsInput,\n RandomReceiverKeyInput,\n SignedReceiverKeyInput,\n VerifyDecryptResponseInput,\n DiscoverNetworkInput,\n DiscoveredNetwork,\n DiscoverySource,\n NodeDescriptorFetcher,\n WellKnownDescriptorFetcher,\n Json,\n} from \"./encryption\";\n","/**\n * SDK Services - Core Types\n *\n * These types define the service architecture for TinyCloud SDK.\n * Services use dependency injection via IServiceContext for platform independence.\n */\n\n// =============================================================================\n// Result Type Pattern\n// =============================================================================\n\n/**\n * Result type for service operations.\n * Services return Result instead of throwing, making error handling explicit.\n *\n * @template T - The success data type\n * @template E - The error type (defaults to ServiceError)\n *\n * @example\n * ```typescript\n * const result = await kv.get('key');\n * if (result.ok) {\n * console.log(result.data);\n * } else {\n * console.error(result.error.code);\n * }\n * ```\n */\nexport type Result<T, E = ServiceError> =\n | { ok: true; data: T }\n | { ok: false; error: E };\n\n/**\n * Service error with structured information.\n */\nexport interface ServiceError {\n /** Error code for programmatic handling (e.g., 'KV_NOT_FOUND', 'AUTH_EXPIRED') */\n code: string;\n /** Human-readable error message */\n message: string;\n /** Service that produced the error (e.g., 'kv', 'sql') */\n service: string;\n /** Original error if this wraps another error */\n cause?: Error;\n /** Additional metadata about the error */\n meta?: Record<string, unknown>;\n}\n\n/**\n * A node-supplied permission hint after strict SDK validation. This is\n * deliberately narrower than a general capability: no wildcards, caveats,\n * descriptions, or transport metadata can cross the service boundary.\n */\nexport interface PermissionHint {\n readonly service: \"tinycloud.kv\" | \"tinycloud.encryption\";\n readonly space?: string;\n readonly path: string;\n readonly actions: readonly string[];\n}\n\n/**\n * Storage quota information returned with quota-related errors.\n */\nexport interface StorageQuotaInfo {\n usedBytes: number;\n limitBytes: number;\n service: string;\n}\n\n/**\n * Standard error codes used across services.\n */\nexport const ErrorCodes = {\n // Common errors\n NOT_FOUND: \"NOT_FOUND\",\n AUTH_EXPIRED: \"AUTH_EXPIRED\",\n AUTH_REQUIRED: \"AUTH_REQUIRED\",\n AUTH_UNAUTHORIZED: \"AUTH_UNAUTHORIZED\",\n /** HTTP 401: the delegation the invocation cites was revoked. */\n AUTH_DELEGATION_REVOKED: \"AUTH_DELEGATION_REVOKED\",\n /** HTTP 401: a delegation the cited one rests on was revoked. */\n AUTH_DELEGATION_ANCESTOR_REVOKED: \"AUTH_DELEGATION_ANCESTOR_REVOKED\",\n NETWORK_ERROR: \"NETWORK_ERROR\",\n TIMEOUT: \"TIMEOUT\",\n ABORTED: \"ABORTED\",\n INVALID_INPUT: \"INVALID_INPUT\",\n PERMISSION_DENIED: \"PERMISSION_DENIED\",\n\n // KV-specific errors\n KV_NOT_FOUND: \"KV_NOT_FOUND\",\n KV_WRITE_FAILED: \"KV_WRITE_FAILED\",\n KV_PRECONDITION_FAILED: \"KV_PRECONDITION_FAILED\",\n KV_CONFLICT: \"KV_CONFLICT\",\n KV_RESPONSE_TOO_LARGE: \"KV_RESPONSE_TOO_LARGE\",\n /** HTTP 410 from the change feed: discard sync state and restart without a cursor; `meta.reason` says why. */\n KV_SYNC_RESET_REQUIRED: \"KV_SYNC_RESET_REQUIRED\",\n /** HTTP 403 from the change feed: the retention grant was refused; `meta.reason` says why. */\n KV_RETENTION_GRANT_REFUSED: \"KV_RETENTION_GRANT_REFUSED\",\n\n // SQL-specific errors\n SQL_ERROR: \"SQL_ERROR\",\n SQL_PERMISSION_DENIED: \"SQL_PERMISSION_DENIED\",\n SQL_DATABASE_NOT_FOUND: \"SQL_DATABASE_NOT_FOUND\",\n SQL_RESPONSE_TOO_LARGE: \"SQL_RESPONSE_TOO_LARGE\",\n SQL_QUOTA_EXCEEDED: \"SQL_QUOTA_EXCEEDED\",\n SQL_INVALID_STATEMENT: \"SQL_INVALID_STATEMENT\",\n SQL_SCHEMA_ERROR: \"SQL_SCHEMA_ERROR\",\n SQL_READONLY_VIOLATION: \"SQL_READONLY_VIOLATION\",\n\n // Storage quota errors\n STORAGE_QUOTA_EXCEEDED: \"STORAGE_QUOTA_EXCEEDED\",\n STORAGE_LIMIT_REACHED: \"STORAGE_LIMIT_REACHED\",\n\n // DuckDB-specific errors\n DUCKDB_ERROR: \"DUCKDB_ERROR\",\n DUCKDB_PERMISSION_DENIED: \"DUCKDB_PERMISSION_DENIED\",\n DUCKDB_DATABASE_NOT_FOUND: \"DUCKDB_DATABASE_NOT_FOUND\",\n DUCKDB_RESPONSE_TOO_LARGE: \"DUCKDB_RESPONSE_TOO_LARGE\",\n DUCKDB_QUOTA_EXCEEDED: \"DUCKDB_QUOTA_EXCEEDED\",\n DUCKDB_INVALID_STATEMENT: \"DUCKDB_INVALID_STATEMENT\",\n DUCKDB_SCHEMA_ERROR: \"DUCKDB_SCHEMA_ERROR\",\n DUCKDB_READONLY_VIOLATION: \"DUCKDB_READONLY_VIOLATION\",\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\n// =============================================================================\n// Service Session\n// =============================================================================\n\n/**\n * Session data required for authenticated service operations.\n * Both TinyCloudSession and web-sdk Session can be cast to this interface.\n */\nexport interface ServiceSession {\n /** The delegation header containing the UCAN */\n delegationHeader: { Authorization: string };\n /** The delegation CID */\n delegationCid: string;\n /** The space ID for this session */\n spaceId: string;\n /** The verification method DID */\n verificationMethod: string;\n /** The session key JWK (required for invoke) */\n jwk: object;\n}\n\n// =============================================================================\n// Platform Dependencies (Injected)\n// =============================================================================\n\n/**\n * Headers type - compatible with both browser and Node.js.\n */\nexport type ServiceHeaders = Record<string, string> | [string, string][];\n\n/**\n * A single fact object to include in the UCAN invocation.\n * Facts are key-value objects that the server reads from the UCAN facts field.\n */\nexport interface InvocationFact {\n [key: string]: unknown;\n}\n\n/**\n * Facts to include in the UCAN invocation.\n * This is an array of fact objects per the UCAN spec.\n * Used to pass additional parameters that the server reads from the UCAN facts field.\n */\nexport type InvocationFacts = InvocationFact[];\n\n/**\n * Invoke function signature - platform-specific implementation injected via DI.\n * Both node-sdk-wasm and web-sdk-wasm export this with identical signature.\n *\n * @param session - The service session with delegation data\n * @param service - Service name (e.g., \"kv\")\n * @param path - Resource path or key\n * @param action - Action to perform (e.g., \"tinycloud.kv/get\")\n * @param facts - Optional facts to include in the UCAN (e.g., for capabilities/read params)\n * @returns Headers to include in the request\n */\nexport type InvokeFunction = (\n session: ServiceSession,\n service: string,\n path: string,\n action: string,\n facts?: InvocationFacts,\n) => ServiceHeaders;\n\n/**\n * Multi-resource invocation entry.\n */\nexport interface InvokeAnyEntry {\n /**\n * Legacy space-scoped resource. Optional when `resource` is provided.\n */\n spaceId?: string;\n service: string;\n path: string;\n action: string;\n /** Optional raw resource URI. When set, WASM signs this URI directly. */\n resource?: string;\n /** Capability caveats that must remain on this invocation attenuation. */\n caveats?: Record<string, unknown>[];\n}\n\n/**\n * Invoke function for minting a single authorization header that covers\n * multiple capabilities across one effective invoker.\n */\nexport type InvokeAnyFunction = (\n session: ServiceSession,\n entries: InvokeAnyEntry[],\n facts?: InvocationFacts,\n) => ServiceHeaders;\n\n/**\n * Fetch request options - compatible with standard fetch API.\n */\nexport interface FetchRequestInit {\n method?: string;\n headers?: ServiceHeaders;\n body?: Blob | FormData | string;\n signal?: AbortSignal;\n redirect?: \"error\";\n}\n\n/**\n * Fetch response interface - compatible with standard Response.\n */\nexport interface FetchResponse {\n ok: boolean;\n status: number;\n statusText: string;\n body?: unknown;\n headers: {\n get(name: string): string | null;\n };\n json(): Promise<unknown>;\n text(): Promise<string>;\n arrayBuffer(): Promise<ArrayBuffer>;\n blob(): Promise<Blob>;\n}\n\n/**\n * Fetch function signature - allows for custom fetch implementations.\n * Compatible with both browser fetch and Node.js fetch.\n */\nexport type FetchFunction = (\n url: string,\n init?: FetchRequestInit,\n) => Promise<FetchResponse>;\n\n// =============================================================================\n// Retry Policy\n// =============================================================================\n\n/**\n * Configuration for automatic retry of failed requests.\n */\nexport interface RetryPolicy {\n /** Maximum number of attempts (including initial) */\n maxAttempts: number;\n /** Backoff strategy between retries */\n backoff: \"none\" | \"linear\" | \"exponential\";\n /** Base delay in milliseconds for backoff calculation */\n baseDelayMs: number;\n /** Maximum delay in milliseconds between retries */\n maxDelayMs: number;\n /** Error codes that should trigger a retry */\n retryableErrors: string[];\n}\n\n/**\n * Default retry policy.\n */\nexport const defaultRetryPolicy: RetryPolicy = {\n maxAttempts: 3,\n backoff: \"exponential\",\n baseDelayMs: 1000,\n maxDelayMs: 10000,\n retryableErrors: [ErrorCodes.NETWORK_ERROR, ErrorCodes.TIMEOUT],\n};\n\n// =============================================================================\n// Service Context\n// =============================================================================\n\n/**\n * Event handler function type.\n */\nexport type EventHandler = (data: unknown) => void;\n\n/**\n * SDK telemetry event handler.\n */\nexport type TelemetryEventHandler = (event: string, data: unknown) => void;\n\n/**\n * Default-off telemetry configuration.\n */\nexport type TelemetryConfig =\n | boolean\n | {\n enabled?: boolean;\n onEvent?: TelemetryEventHandler;\n };\n\n/**\n * Service interface - base contract for all services.\n */\nexport interface IService {\n /** Initialize service with context */\n initialize(context: IServiceContext): void;\n\n /** Called when session changes (sign-in, sign-out, refresh) */\n onSessionChange(session: ServiceSession | null): void;\n\n /** Called when SDK signs out - should abort pending operations */\n onSignOut(): void;\n\n /** Service-specific configuration */\n readonly config: Record<string, unknown>;\n}\n\n/**\n * Context provided to services for accessing platform dependencies.\n * The SDK creates this context and passes it to services during initialization.\n */\nexport interface IServiceContext {\n // Session management\n /** Current active session, or null if not authenticated */\n readonly session: ServiceSession | null;\n /** Whether there is an active authenticated session */\n readonly isAuthenticated: boolean;\n\n // Platform dependencies (injected by SDK)\n /** Platform-specific invoke function from WASM binding */\n readonly invoke: InvokeFunction;\n /** Optional multi-resource invoke function */\n readonly invokeAny?: InvokeAnyFunction;\n /** Fetch function (defaults to globalThis.fetch) */\n readonly fetch: FetchFunction;\n /** Available TinyCloud host URLs */\n readonly hosts: string[];\n\n // Cross-service access\n /** Get another registered service by name */\n getService<T extends IService>(name: string): T | undefined;\n\n // Telemetry/Events\n /** Emit a telemetry event */\n emit(event: string, data: unknown): void;\n /** Subscribe to events */\n on(event: string, handler: EventHandler): () => void;\n\n // Lifecycle\n /** Abort signal that fires when SDK signs out */\n readonly abortSignal: AbortSignal;\n\n // Retry policy\n /** Retry policy for failed requests */\n readonly retryPolicy: RetryPolicy;\n}\n\n// =============================================================================\n// Telemetry Events\n// =============================================================================\n\n/**\n * Event emitted before a service request.\n */\nexport interface ServiceRequestEvent {\n service: string;\n action: string;\n span?: string;\n key?: string;\n timestamp: number;\n}\n\n/**\n * Event emitted after a service response.\n */\nexport interface ServiceResponseEvent {\n service: string;\n action: string;\n span?: string;\n ok: boolean;\n duration: number;\n durationMs?: number;\n status?: number;\n}\n\n/**\n * Event emitted on service error.\n */\nexport interface ServiceErrorEvent {\n service: string;\n span?: string;\n error: ServiceError;\n}\n\n/**\n * Event emitted on retry attempt.\n */\nexport interface ServiceRetryEvent {\n service: string;\n attempt: number;\n maxAttempts: number;\n error: ServiceError;\n}\n\n/**\n * Generic named span event for aggregating operation timings.\n */\nexport interface TelemetrySpanEvent {\n span: string;\n ok: boolean;\n durationMs: number;\n service?: string;\n action?: string;\n status?: number;\n error?: ServiceError;\n}\n\n/**\n * Telemetry event names.\n */\nexport const TelemetryEvents = {\n SPAN: \"telemetry.span\",\n SERVICE_REQUEST: \"service.request\",\n SERVICE_RESPONSE: \"service.response\",\n SERVICE_ERROR: \"service.error\",\n SERVICE_RETRY: \"service.retry\",\n SESSION_CHANGED: \"session.changed\",\n SESSION_EXPIRED: \"session.expired\",\n} as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Create a success result.\n */\nexport function ok<T>(data: T): Result<T> {\n return { ok: true, data };\n}\n\n/**\n * Create an error result.\n */\nexport function err<E = ServiceError>(error: E): Result<never, E> {\n return { ok: false, error };\n}\n\n/**\n * Create a ServiceError.\n */\nexport function serviceError(\n code: string,\n message: string,\n service: string,\n options?: { cause?: Error; meta?: Record<string, unknown> },\n): ServiceError {\n return {\n code,\n message,\n service,\n cause: options?.cause,\n meta: options?.meta,\n };\n}\n","/** Safe projections for diagnostic sinks. */\n\nconst REDACTED = \"[REDACTED]\";\nconst SAFE_NUMBER_FIELDS = new Set([\n \"duration\",\n \"durationMs\",\n \"endedAt\",\n \"startedAt\",\n \"status\",\n \"timestamp\",\n]);\nconst SAFE_BOOLEAN_FIELDS = new Set([\"authenticated\", \"ok\", \"persisted\"]);\n\nfunction finiteNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction isBinaryData(value: object): boolean {\n try {\n return (\n Array.isArray(value) ||\n ArrayBuffer.isView(value) ||\n value instanceof ArrayBuffer\n );\n } catch {\n // A revoked Proxy can throw while checking its shape. It is not diagnostic\n // data and must not prevent the SDK operation that emitted it.\n return true;\n }\n}\n\nfunction read(value: object, key: string): unknown {\n try {\n return (value as Record<string, unknown>)[key];\n } catch {\n return REDACTED;\n }\n}\n\n/** Return only stable, non-sensitive error diagnostics. */\nexport function projectDiagnosticError(error: unknown): Record<string, unknown> {\n if (typeof error !== \"object\" || error === null) return {};\n\n const status = finiteNumber(read(error, \"status\"));\n return status !== undefined && status >= 100 && status <= 599 ? { status } : {};\n}\n\n/**\n * Copy only fixed scalar metrics and URL origins. Diagnostic payloads can be\n * supplied by applications and nodes, so strings, nested values, and unknown\n * fields are never projected to debug or telemetry sinks.\n */\nexport function projectDiagnosticData(value: unknown): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value !== \"object\") return REDACTED;\n\n try {\n if (isBinaryData(value)) return REDACTED;\n\n const projected: Record<string, unknown> = {};\n for (const key of SAFE_NUMBER_FIELDS) {\n const number = finiteNumber(read(value, key));\n if (number !== undefined) projected[key] = number;\n }\n for (const key of SAFE_BOOLEAN_FIELDS) {\n const boolean = read(value, key);\n if (typeof boolean === \"boolean\") projected[key] = boolean;\n }\n\n // URLs, like every other string-bearing value, are never projected. Even\n // an origin can encode user-controlled data in a hostname.\n const url = read(value, \"url\");\n if (url !== undefined) projected.url = REDACTED;\n\n const error = read(value, \"error\");\n if (error !== undefined) projected.error = projectDiagnosticError(error);\n\n return projected;\n } catch {\n // Projection is best-effort only. Hostile Proxy traps and exotic objects\n // must never block telemetry, debug logging, or ordinary subscribers.\n return REDACTED;\n }\n}\n","import { projectDiagnosticData } from \"./diagnostics\";\n\nexport type TinyCloudDebugLevel = \"debug\";\n\nexport interface TinyCloudDebugEvent {\n sequence: number;\n timestamp: number;\n timestampIso: string;\n level: TinyCloudDebugLevel;\n event: string;\n message?: string;\n data?: unknown;\n durationMs?: number;\n startedAt?: number;\n endedAt?: number;\n}\n\nexport interface TinyCloudDebugEnableOptions {\n /**\n * Persist the debug flag in browser localStorage. Defaults to true.\n * Node runtimes intentionally do not persist this setting.\n */\n persist?: boolean;\n}\n\nexport interface TinyCloudDebugTimer {\n stop: (data?: unknown) => TinyCloudDebugEvent | undefined;\n}\n\ntype TinyCloudDebugGlobal = typeof globalThis & {\n TinyCloud_debug?: boolean | string;\n TinyCloudDebug?: TinyCloudDebugLogger;\n window?: unknown;\n enableTinyCloudDebug?: typeof enableTinyCloudDebug;\n disableTinyCloudDebug?: typeof disableTinyCloudDebug;\n getTinyCloudDebugLogs?: typeof getTinyCloudDebugLogs;\n clearTinyCloudDebugLogs?: typeof clearTinyCloudDebugLogs;\n};\n\ninterface TinyCloudDebugStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\nconst DEBUG_FLAG = \"TinyCloud_debug\";\nconst MAX_EVENTS = 1000;\n\nfunction getGlobal(): TinyCloudDebugGlobal {\n return globalThis as TinyCloudDebugGlobal;\n}\n\nfunction nowMs(): number {\n const performanceNow = globalThis.performance?.now?.bind(globalThis.performance);\n return typeof performanceNow === \"function\" ? performanceNow() : Date.now();\n}\n\nfunction isTrue(value: unknown): boolean {\n return value === true || value === \"true\" || value === \"1\";\n}\n\nfunction getProcessDebugFlag(): unknown {\n const processLike = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n return processLike?.env?.[DEBUG_FLAG];\n}\n\nfunction isBrowserWindow(): boolean {\n const global = getGlobal();\n return global.window === globalThis;\n}\n\nfunction getLocalStorage(): TinyCloudDebugStorage | undefined {\n if (!isBrowserWindow()) {\n return undefined;\n }\n\n try {\n return (globalThis as typeof globalThis & { localStorage?: TinyCloudDebugStorage }).localStorage;\n } catch {\n return undefined;\n }\n}\n\nfunction getStoredDebugFlag(): unknown {\n const storage = getLocalStorage();\n if (!storage) {\n return undefined;\n }\n\n try {\n return storage.getItem(DEBUG_FLAG);\n } catch {\n return undefined;\n }\n}\n\nfunction setStoredDebugFlag(enabled: boolean): void {\n const storage = getLocalStorage();\n if (!storage) {\n return;\n }\n\n try {\n if (enabled) {\n storage.setItem(DEBUG_FLAG, \"true\");\n } else {\n storage.removeItem(DEBUG_FLAG);\n }\n } catch {\n // localStorage can be unavailable in private browsing or restricted contexts.\n }\n}\n\nfunction shouldStartEnabled(): boolean {\n const global = getGlobal();\n return (\n isTrue(global[DEBUG_FLAG]) ||\n isTrue(getStoredDebugFlag()) ||\n isTrue(getProcessDebugFlag())\n );\n}\n\nexport class TinyCloudDebugLogger {\n private enabled: boolean = shouldStartEnabled();\n private sequence: number = 0;\n private events: TinyCloudDebugEvent[] = [];\n private maxEvents: number = MAX_EVENTS;\n\n isEnabled(): boolean {\n return (\n this.enabled ||\n isTrue(getGlobal()[DEBUG_FLAG]) ||\n isTrue(getProcessDebugFlag())\n );\n }\n\n enable(options: TinyCloudDebugEnableOptions = {}): void {\n this.enabled = true;\n getGlobal()[DEBUG_FLAG] = true;\n\n if (options.persist !== false) {\n setStoredDebugFlag(true);\n }\n\n this.log(\"debug.enabled\", { persisted: options.persist !== false });\n }\n\n disable(options: TinyCloudDebugEnableOptions = {}): void {\n this.log(\"debug.disabled\", { persisted: options.persist !== false });\n this.enabled = false;\n getGlobal()[DEBUG_FLAG] = false;\n\n if (options.persist !== false) {\n setStoredDebugFlag(false);\n }\n }\n\n clear(): void {\n this.events = [];\n }\n\n getLogs(): TinyCloudDebugEvent[] {\n return [...this.events];\n }\n\n log(event: string, data?: unknown, message?: string): TinyCloudDebugEvent | undefined {\n if (!this.isEnabled()) {\n return undefined;\n }\n\n return this.record({\n event,\n data,\n message,\n level: \"debug\",\n timestamp: Date.now(),\n timestampIso: new Date().toISOString(),\n });\n }\n\n startTimer(event: string, data?: unknown): TinyCloudDebugTimer {\n if (!this.isEnabled()) {\n return { stop: () => undefined };\n }\n\n const startedAt = nowMs();\n this.log(`${event}.start`, data);\n\n return {\n stop: (finishData?: unknown) => {\n const endedAt = nowMs();\n return this.record({\n event: `${event}.end`,\n data: finishData,\n durationMs: endedAt - startedAt,\n startedAt,\n endedAt,\n level: \"debug\",\n timestamp: Date.now(),\n timestampIso: new Date().toISOString(),\n });\n },\n };\n }\n\n async timeAsync<T>(\n event: string,\n operation: () => Promise<T>,\n data?: unknown,\n ): Promise<T> {\n if (!this.isEnabled()) {\n return operation();\n }\n\n const timer = this.startTimer(event, data);\n try {\n const result = await operation();\n timer.stop({ ok: true });\n return result;\n } catch (error) {\n timer.stop({ ok: false, error });\n throw error;\n }\n }\n\n time<T>(event: string, operation: () => T, data?: unknown): T {\n if (!this.isEnabled()) {\n return operation();\n }\n\n const timer = this.startTimer(event, data);\n try {\n const result = operation();\n timer.stop({ ok: true });\n return result;\n } catch (error) {\n timer.stop({ ok: false, error });\n throw error;\n }\n }\n\n private record(\n event: Omit<TinyCloudDebugEvent, \"sequence\">,\n ): TinyCloudDebugEvent {\n const debugEvent: TinyCloudDebugEvent = {\n ...event,\n ...(event.data === undefined\n ? {}\n : { data: projectDiagnosticData(event.data) }),\n ...(event.message === undefined ? {} : { message: \"[REDACTED]\" }),\n sequence: ++this.sequence,\n };\n\n this.events.push(debugEvent);\n if (this.events.length > this.maxEvents) {\n this.events.splice(0, this.events.length - this.maxEvents);\n }\n\n try {\n globalThis.console?.debug?.(\"[TinyCloud]\", debugEvent.event, debugEvent);\n } catch {\n // Debug logging should never affect SDK behavior.\n }\n\n return debugEvent;\n }\n}\n\nexport const tinyCloudDebugLogger = new TinyCloudDebugLogger();\n\nexport function enableTinyCloudDebug(\n options?: TinyCloudDebugEnableOptions,\n): TinyCloudDebugLogger {\n tinyCloudDebugLogger.enable(options);\n return tinyCloudDebugLogger;\n}\n\nexport function disableTinyCloudDebug(\n options?: TinyCloudDebugEnableOptions,\n): TinyCloudDebugLogger {\n tinyCloudDebugLogger.disable(options);\n return tinyCloudDebugLogger;\n}\n\nexport function getTinyCloudDebugLogs(): TinyCloudDebugEvent[] {\n return tinyCloudDebugLogger.getLogs();\n}\n\nexport function clearTinyCloudDebugLogs(): void {\n tinyCloudDebugLogger.clear();\n}\n\nexport function installTinyCloudDebugGlobals(): void {\n const global = getGlobal();\n global.TinyCloudDebug = tinyCloudDebugLogger;\n global.enableTinyCloudDebug = enableTinyCloudDebug;\n global.disableTinyCloudDebug = disableTinyCloudDebug;\n global.getTinyCloudDebugLogs = getTinyCloudDebugLogs;\n global.clearTinyCloudDebugLogs = clearTinyCloudDebugLogs;\n}\n\ninstallTinyCloudDebugGlobals();\n","/**\n * Zod schemas for SDK Services API response types.\n *\n * This is the source of truth for service response types. TypeScript types\n * are derived from these schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\n\n// =============================================================================\n// Validation Error Type\n// =============================================================================\n\n/**\n * Validation error type for schema validation failures.\n */\nexport interface ValidationError {\n code: \"VALIDATION_ERROR\";\n message: string;\n service: string;\n meta?: {\n issues: z.ZodIssue[];\n path?: string;\n };\n}\n\n// =============================================================================\n// Service Error Schema\n// =============================================================================\n\n/**\n * Schema for service error with structured information.\n */\nexport const ServiceErrorSchema = z.object({\n /** Error code for programmatic handling (e.g., 'KV_NOT_FOUND', 'AUTH_EXPIRED') */\n code: z.string(),\n /** Human-readable error message */\n message: z.string(),\n /** Service that produced the error (e.g., 'kv', 'sql') */\n service: z.string(),\n /** Original error if this wraps another error - not validated since Error is a class */\n cause: z.unknown().optional(),\n /** Additional metadata about the error - passthrough allows any object properties */\n meta: z.object({}).passthrough().optional(),\n});\n\nexport type ServiceErrorType = z.infer<typeof ServiceErrorSchema>;\n\n// =============================================================================\n// Result Schema Factory\n// =============================================================================\n\n/**\n * Creates a Result schema for a given data type.\n * Result is a discriminated union: { ok: true, data: T } | { ok: false, error: E }\n *\n * @param dataSchema - Zod schema for the success data type\n * @param errorSchema - Zod schema for the error type (defaults to ServiceErrorSchema)\n * @returns A Zod schema for Result<T, E>\n *\n * @example\n * ```typescript\n * const KVGetResultSchema = createResultSchema(z.string());\n * type KVGetResult = z.infer<typeof KVGetResultSchema>;\n * ```\n */\nexport function createResultSchema<T extends z.ZodTypeAny, E extends z.ZodTypeAny>(\n dataSchema: T,\n errorSchema: E = ServiceErrorSchema as unknown as E\n) {\n return z.discriminatedUnion(\"ok\", [\n z.object({\n ok: z.literal(true),\n data: dataSchema,\n }),\n z.object({\n ok: z.literal(false),\n error: errorSchema,\n }),\n ]);\n}\n\n/**\n * Pre-built Result schema with unknown data and ServiceError.\n * Useful for generic validation before type narrowing.\n */\nexport const GenericResultSchema = createResultSchema(z.unknown(), ServiceErrorSchema);\n\n// =============================================================================\n// KV Response Schemas\n// =============================================================================\n\n/**\n * Schema for KV response headers metadata.\n * Note: The `get` method is a function and cannot be validated with Zod.\n * This schema validates the data properties only.\n */\nexport const KVResponseHeadersSchema = z.object({\n /** ETag for conditional requests */\n etag: z.string().optional(),\n /** Content type of the stored value */\n contentType: z.string().optional(),\n /** Last modification timestamp */\n lastModified: z.string().optional(),\n /** Content length in bytes */\n contentLength: z.number().optional(),\n});\n\nexport type KVResponseHeadersType = z.infer<typeof KVResponseHeadersSchema>;\n\n/**\n * Creates a KVResponse schema for a given data type.\n *\n * @param dataSchema - Zod schema for the data payload type\n * @returns A Zod schema for KVResponse<T>\n *\n * @example\n * ```typescript\n * const UserResponseSchema = createKVResponseSchema(UserSchema);\n * type UserResponse = z.infer<typeof UserResponseSchema>;\n * ```\n */\nexport function createKVResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n /** The data payload */\n data: dataSchema,\n /** Response headers with metadata */\n headers: KVResponseHeadersSchema,\n });\n}\n\n/**\n * Generic KVResponse schema with unknown data.\n * Useful for generic validation before type narrowing.\n */\nexport const GenericKVResponseSchema = createKVResponseSchema(z.unknown());\n\nexport type GenericKVResponseType = z.infer<typeof GenericKVResponseSchema>;\n\n/**\n * Schema for KV list response.\n */\nexport const KVListResponseSchema = z.object({\n /** Array of keys matching the list criteria */\n keys: z.array(z.string()),\n truncated: z.boolean().optional(),\n nextCursor: z.string().optional(),\n});\n\nexport type KVListResponseType = z.infer<typeof KVListResponseSchema>;\n\n/**\n * Result schema for KV list operations.\n */\nexport const KVListResultSchema = createResultSchema(KVListResponseSchema);\n\nexport type KVListResultType = z.infer<typeof KVListResultSchema>;\n\n// =============================================================================\n// Telemetry Event Schemas\n// =============================================================================\n\n/**\n * Schema for service request event.\n */\nexport const ServiceRequestEventSchema = z.object({\n service: z.string(),\n action: z.string(),\n span: z.string().optional(),\n key: z.string().optional(),\n timestamp: z.number(),\n});\n\nexport type ServiceRequestEventType = z.infer<typeof ServiceRequestEventSchema>;\n\n/**\n * Schema for service response event.\n */\nexport const ServiceResponseEventSchema = z.object({\n service: z.string(),\n action: z.string(),\n span: z.string().optional(),\n ok: z.boolean(),\n duration: z.number(),\n durationMs: z.number().optional(),\n status: z.number().optional(),\n});\n\nexport type ServiceResponseEventType = z.infer<typeof ServiceResponseEventSchema>;\n\n/**\n * Schema for service error event.\n */\nexport const ServiceErrorEventSchema = z.object({\n service: z.string(),\n span: z.string().optional(),\n error: ServiceErrorSchema,\n});\n\nexport type ServiceErrorEventType = z.infer<typeof ServiceErrorEventSchema>;\n\n/**\n * Schema for service retry event.\n */\nexport const ServiceRetryEventSchema = z.object({\n service: z.string(),\n attempt: z.number().int().positive(),\n maxAttempts: z.number().int().positive(),\n error: ServiceErrorSchema,\n});\n\nexport type ServiceRetryEventType = z.infer<typeof ServiceRetryEventSchema>;\n\n/**\n * Schema for generic named span event.\n */\nexport const TelemetrySpanEventSchema = z.object({\n span: z.string(),\n ok: z.boolean(),\n durationMs: z.number(),\n service: z.string().optional(),\n action: z.string().optional(),\n status: z.number().optional(),\n error: ServiceErrorSchema.optional(),\n});\n\nexport type TelemetrySpanEventType = z.infer<typeof TelemetrySpanEventSchema>;\n\n// =============================================================================\n// Retry Policy Schema\n// =============================================================================\n\n/**\n * Schema for retry policy configuration.\n */\nexport const RetryPolicySchema = z.object({\n /** Maximum number of attempts (including initial) */\n maxAttempts: z.number().int().positive(),\n /** Backoff strategy between retries */\n backoff: z.enum([\"none\", \"linear\", \"exponential\"]),\n /** Base delay in milliseconds for backoff calculation */\n baseDelayMs: z.number().nonnegative(),\n /** Maximum delay in milliseconds between retries */\n maxDelayMs: z.number().nonnegative(),\n /** Error codes that should trigger a retry */\n retryableErrors: z.array(z.string()),\n});\n\nexport type RetryPolicyType = z.infer<typeof RetryPolicySchema>;\n\n// =============================================================================\n// Service Session Schema\n// =============================================================================\n\n/**\n * Schema for service session data required for authenticated operations.\n */\nexport const ServiceSessionSchema = z.object({\n /** The delegation header containing the UCAN */\n delegationHeader: z.object({\n Authorization: z.string(),\n }),\n /** The delegation CID */\n delegationCid: z.string(),\n /** The space ID for this session */\n spaceId: z.string(),\n /** The verification method DID */\n verificationMethod: z.string(),\n /** The session key JWK (required for invoke) */\n jwk: z.object({}).passthrough(),\n});\n\nexport type ServiceSessionType = z.infer<typeof ServiceSessionSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validate service error against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceError(\n data: unknown\n): { ok: true; data: ServiceErrorType } | { ok: false; error: ValidationError } {\n const result = ServiceErrorSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"validation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate KV list response against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateKVListResponse(\n data: unknown\n): { ok: true; data: KVListResponseType } | { ok: false; error: ValidationError } {\n const result = KVListResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"kv\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate KV response headers against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateKVResponseHeaders(\n data: unknown\n): { ok: true; data: KVResponseHeadersType } | { ok: false; error: ValidationError } {\n const result = KVResponseHeadersSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"kv\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service session against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceSession(\n data: unknown\n): { ok: true; data: ServiceSessionType } | { ok: false; error: ValidationError } {\n const result = ServiceSessionSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate retry policy against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateRetryPolicy(\n data: unknown\n): { ok: true; data: RetryPolicyType } | { ok: false; error: ValidationError } {\n const result = RetryPolicySchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"config\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service request event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceRequestEvent(\n data: unknown\n): { ok: true; data: ServiceRequestEventType } | { ok: false; error: ValidationError } {\n const result = ServiceRequestEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service response event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceResponseEvent(\n data: unknown\n): { ok: true; data: ServiceResponseEventType } | { ok: false; error: ValidationError } {\n const result = ServiceResponseEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate named telemetry span event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateTelemetrySpanEvent(\n data: unknown\n): { ok: true; data: TelemetrySpanEventType } | { ok: false; error: ValidationError } {\n const result = TelemetrySpanEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","/**\n * ServiceContext implementation for TinyCloud SDK Services\n * @module @tinycloud/sdk-services\n */\n\nimport {\n IServiceContext,\n IService,\n ServiceSession,\n RetryPolicy,\n InvokeFunction,\n InvokeAnyFunction,\n FetchFunction,\n defaultRetryPolicy,\n EventHandler,\n TelemetryEventHandler,\n TelemetryConfig,\n} from \"./types\";\nimport { tinyCloudDebugLogger } from \"./debug\";\nimport { projectDiagnosticData } from \"./diagnostics\";\n\n/**\n * Configuration options for ServiceContext.\n */\nexport interface ServiceContextConfig {\n /** Function to invoke WASM operations */\n invoke: InvokeFunction;\n /** Optional function to mint a single authorization header for multiple capabilities */\n invokeAny?: InvokeAnyFunction;\n /** Function to make HTTP requests (defaults to globalThis.fetch) */\n fetch?: FetchFunction;\n /** List of TinyCloud host URLs */\n hosts: string[];\n /** Initial session (optional) */\n session?: ServiceSession | null;\n /** Retry policy configuration */\n retryPolicy?: Partial<RetryPolicy>;\n /** Default-off telemetry event delivery. */\n telemetry?: TelemetryConfig;\n}\n\n/**\n * ServiceContext provides platform dependencies and cross-service access to services.\n * This is the primary interface services use to interact with the SDK runtime.\n *\n * @example\n * ```typescript\n * const context = new ServiceContext({\n * invoke: wasmInvoke,\n * hosts: ['https://node.tinycloud.xyz'],\n * retryPolicy: { maxAttempts: 5 },\n * });\n *\n * // Register a service\n * const kvService = new KVService({});\n * context.registerService('kv', kvService);\n * kvService.initialize(context);\n *\n * // Update session when user signs in\n * context.setSession(userSession);\n * ```\n */\nexport class ServiceContext implements IServiceContext {\n private _session: ServiceSession | null = null;\n private _services: Map<string, IService> = new Map();\n private _eventHandlers: Map<string, Set<EventHandler>> = new Map();\n private _abortController: AbortController = new AbortController();\n private _retired = false;\n private readonly _invoke: InvokeFunction;\n private readonly _invokeAny?: InvokeAnyFunction;\n private readonly _fetch: FetchFunction;\n private readonly _hosts: string[];\n private readonly _retryPolicy: RetryPolicy;\n private readonly _telemetryEnabled: boolean;\n private readonly _telemetryHandler?: TelemetryEventHandler;\n\n constructor(config: ServiceContextConfig) {\n this._invoke = this.wrapInvoke(config.invoke);\n this._invokeAny = config.invokeAny\n ? this.wrapInvokeAny(config.invokeAny)\n : undefined;\n this._fetch = this.wrapFetch(config.fetch ?? globalThis.fetch.bind(globalThis));\n this._hosts = config.hosts;\n this._session = config.session ?? null;\n this._retryPolicy = {\n ...defaultRetryPolicy,\n ...config.retryPolicy,\n };\n this._telemetryEnabled =\n typeof config.telemetry === \"boolean\"\n ? config.telemetry\n : config.telemetry?.enabled === true;\n this._telemetryHandler =\n typeof config.telemetry === \"object\" ? config.telemetry.onEvent : undefined;\n }\n\n // ============================================================\n // Session Management\n // ============================================================\n\n /**\n * Get the current session.\n */\n get session(): ServiceSession | null {\n return this._retired ? null : this._session;\n }\n\n /**\n * Check if the context has an authenticated session.\n */\n get isAuthenticated(): boolean {\n return !this._retired && this._session !== null;\n }\n\n /**\n * Update the session and notify all registered services.\n *\n * @param session - New session or null to clear\n */\n setSession(session: ServiceSession | null): void {\n this.assertActive();\n this._session = session;\n this.emit('session.changed', { authenticated: session !== null });\n\n // Notify all services of session change\n for (const service of this._services.values()) {\n service.onSessionChange(session);\n }\n }\n\n // ============================================================\n // Platform Dependencies\n // ============================================================\n\n /**\n * Get the invoke function for WASM operations.\n */\n get invoke(): InvokeFunction {\n this.assertActive();\n return this._invoke;\n }\n\n /**\n * Get the multi-resource invoke function when available.\n */\n get invokeAny(): InvokeAnyFunction | undefined {\n this.assertActive();\n return this._invokeAny;\n }\n\n /**\n * Get the fetch function for HTTP requests.\n */\n get fetch(): FetchFunction {\n this.assertActive();\n return this._fetch;\n }\n\n /**\n * Get the list of TinyCloud host URLs.\n */\n get hosts(): string[] {\n this.assertActive();\n return this._hosts;\n }\n\n // ============================================================\n // Service Registry\n // ============================================================\n\n /**\n * Register a service with the context.\n *\n * @param name - Service name (e.g., 'kv')\n * @param service - Service instance\n */\n registerService(name: string, service: IService): void {\n this._services.set(name, service);\n }\n\n /**\n * Unregister a service from the context.\n *\n * @param name - Service name to remove\n */\n unregisterService(name: string): void {\n this._services.delete(name);\n }\n\n /**\n * Get a registered service by name.\n *\n * @param name - Service name\n * @returns The service instance or undefined if not registered\n */\n getService<T extends IService>(name: string): T | undefined {\n return this._services.get(name) as T | undefined;\n }\n\n // ============================================================\n // Event System (Telemetry)\n // ============================================================\n\n /**\n * Emit a telemetry event.\n *\n * @param event - Event name\n * @param data - Event data\n */\n emit(event: string, data: unknown): void {\n tinyCloudDebugLogger.log(event, data);\n\n if (this._telemetryEnabled && this._telemetryHandler) {\n try {\n this._telemetryHandler(event, projectDiagnosticData(data));\n } catch (error) {\n // Don't let telemetry handlers break SDK operations.\n console.error(`Error in telemetry handler for \"${event}\":`, error);\n }\n }\n\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n // Don't let event handler errors break the flow\n console.error(`Error in event handler for \"${event}\":`, error);\n }\n }\n }\n }\n\n /**\n * Subscribe to telemetry events.\n *\n * @param event - Event name to subscribe to\n * @param handler - Handler function\n * @returns Unsubscribe function\n */\n on(event: string, handler: EventHandler): () => void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this._eventHandlers.delete(event);\n }\n }\n };\n }\n\n /**\n * Remove all event handlers for an event.\n *\n * @param event - Event name (if omitted, clears all events)\n */\n clearEventHandlers(event?: string): void {\n if (event) {\n this._eventHandlers.delete(event);\n } else {\n this._eventHandlers.clear();\n }\n }\n\n // ============================================================\n // Lifecycle\n // ============================================================\n\n /**\n * Get the abort signal for cancelling operations.\n */\n get abortSignal(): AbortSignal {\n return this._abortController.signal;\n }\n\n /**\n * Permanently retire this graph after its owner installs a replacement.\n * Unlike `abort()`, retirement never creates a fresh controller, so captured\n * services cannot resume calls under a superseded session.\n */\n retire(): void {\n if (this._retired) return;\n this._retired = true;\n this._session = null;\n this._abortController.abort();\n for (const service of this._services.values()) {\n // User-provided services are part of the retired graph, but their\n // cleanup must never make installing the replacement graph fail.\n try {\n service.onSignOut();\n } catch (error) {\n console.error(\"Error retiring service:\", error);\n }\n }\n }\n\n /**\n * Abort all pending operations and notify services.\n * Creates a new AbortController for future operations.\n */\n abort(): void {\n // A retired graph must never receive a fresh abort signal. Captured\n // services retain this context, so recreating its controller would make a\n // stale graph look live to custom cleanup code.\n if (this._retired) return;\n this._abortController.abort();\n this._abortController = new AbortController();\n\n // Notify all services\n for (const service of this._services.values()) {\n try {\n service.onSignOut();\n } catch (error) {\n console.error(\"Error signing out service:\", error);\n }\n }\n }\n\n /**\n * Sign out - abort operations and clear session.\n */\n signOut(): void {\n if (this._retired) return;\n this.abort();\n this.setSession(null);\n this.emit('session.expired', {});\n }\n\n // ============================================================\n // Retry Policy\n // ============================================================\n\n /**\n * Get the retry policy configuration.\n */\n get retryPolicy(): RetryPolicy {\n return this._retryPolicy;\n }\n\n private wrapInvoke(invoke: InvokeFunction): InvokeFunction {\n return (session, service, path, action, facts) => {\n this.assertActive();\n if (!tinyCloudDebugLogger.isEnabled()) {\n return invoke(session, service, path, action, facts);\n }\n\n const timer = tinyCloudDebugLogger.startTimer(\"sdk.invoke\", {\n service,\n path,\n action,\n facts,\n });\n\n try {\n const result = invoke(session, service, path, action, facts);\n timer.stop({ ok: true, service, path, action });\n return result;\n } catch (error) {\n timer.stop({ ok: false, service, path, action, error });\n throw error;\n }\n };\n }\n\n private assertActive(): void {\n if (this._retired) {\n throw new Error(\"Service graph has been retired by session replacement.\");\n }\n }\n\n private wrapInvokeAny(invokeAny: InvokeAnyFunction): InvokeAnyFunction {\n return (session, entries, facts) => {\n this.assertActive();\n if (!tinyCloudDebugLogger.isEnabled()) {\n return invokeAny(session, entries, facts);\n }\n\n const timer = tinyCloudDebugLogger.startTimer(\"sdk.invokeAny\", {\n entries,\n facts,\n });\n\n try {\n const result = invokeAny(session, entries, facts);\n timer.stop({ ok: true, entries });\n return result;\n } catch (error) {\n timer.stop({ ok: false, entries, error });\n throw error;\n }\n };\n }\n\n private wrapFetch(fetchFn: FetchFunction): FetchFunction {\n return async (url, init) => {\n this.assertActive();\n const request = {\n ...init,\n signal: this.combineSignals(init?.signal),\n };\n if (!tinyCloudDebugLogger.isEnabled()) {\n return fetchFn(url, request);\n }\n\n const timer = tinyCloudDebugLogger.startTimer(\"sdk.fetch\", {\n url,\n method: request.method ?? \"GET\",\n init: request,\n });\n\n try {\n const response = await fetchFn(url, request);\n timer.stop({\n ok: response.ok,\n url,\n method: request.method ?? \"GET\",\n status: response.status,\n statusText: response.statusText,\n });\n return response;\n } catch (error) {\n timer.stop({\n ok: false,\n url,\n method: request.method ?? \"GET\",\n error,\n });\n throw error;\n }\n };\n }\n\n private combineSignals(signal?: AbortSignal): AbortSignal {\n if (!signal) return this._abortController.signal;\n const combined = new AbortController();\n const abort = (source: AbortSignal) => combined.abort(source.reason);\n if (signal.aborted) {\n abort(signal);\n } else if (this._abortController.signal.aborted) {\n abort(this._abortController.signal);\n } else {\n signal.addEventListener(\"abort\", () => abort(signal), { once: true });\n this._abortController.signal.addEventListener(\n \"abort\",\n () => abort(this._abortController.signal),\n { once: true },\n );\n }\n return combined.signal;\n }\n}\n","/**\n * SDK Services - Error Utilities\n *\n * Utilities for creating and handling service errors.\n */\n\nimport { CAPABILITY_REGISTRY } from \"@tinycloud/bootstrap\";\nimport { parseNetworkId } from \"./encryption/networkId\";\n\nimport {\n type ServiceError,\n ErrorCodes,\n err,\n serviceError,\n type PermissionHint,\n} from \"./types\";\n\n/** Validate one structured node permission hint without accepting raw errors. */\nexport function parsePermissionHint(value: unknown): PermissionHint | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n const candidate = value as Record<string, unknown>;\n const keys = Object.keys(candidate).sort();\n if (keys.some((key) => ![\"actions\", \"path\", \"service\", \"space\"].includes(key))) return undefined;\n if (candidate.service !== \"tinycloud.kv\" && candidate.service !== \"tinycloud.encryption\") return undefined;\n if (typeof candidate.path !== \"string\" || candidate.path.length === 0 || candidate.path.includes(\"*\")) return undefined;\n if (candidate.service === \"tinycloud.kv\" &&\n (typeof candidate.space !== \"string\" || candidate.space.length === 0 || !candidate.path.startsWith(\"vault/\") || candidate.path.endsWith(\"/\"))) {\n return undefined;\n }\n if (candidate.service === \"tinycloud.encryption\" &&\n (candidate.space !== undefined || !candidate.path.startsWith(\"urn:tinycloud:encryption:\") || candidate.path.endsWith(\":\"))) {\n return undefined;\n }\n if (!Array.isArray(candidate.actions) || candidate.actions.length !== 1 ||\n typeof candidate.actions[0] !== \"string\" || candidate.actions[0].includes(\"*\")) return undefined;\n const expectedAction = candidate.service === \"tinycloud.kv\"\n ? \"tinycloud.kv/get\"\n : \"tinycloud.encryption/decrypt\";\n if (candidate.actions[0] !== expectedAction) return undefined;\n const space = typeof candidate.space === \"string\" ? candidate.space : undefined;\n return {\n service: candidate.service,\n ...(space === undefined ? {} : { space }),\n path: candidate.path,\n actions: [candidate.actions[0]],\n };\n}\n\n/** Extract only a validated structured hint from an SDK-owned error body. */\nexport function parsePermissionHintFromErrorText(text: string): PermissionHint | undefined {\n try {\n const parsed: unknown = JSON.parse(text);\n if (typeof parsed !== \"object\" || parsed === null) return undefined;\n const root = parsed as Record<string, unknown>;\n const nested = root.error;\n const nestedRecord = typeof nested === \"object\" && nested !== null\n ? nested as Record<string, unknown>\n : undefined;\n return parsePermissionHint(root.permissionHint) ??\n parsePermissionHint(nestedRecord?.permissionHint);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Create a service error for authentication required.\n */\nexport function authRequiredError(service: string): ServiceError {\n return {\n code: ErrorCodes.AUTH_REQUIRED,\n message: \"Authentication required. Please sign in first.\",\n service,\n };\n}\n\n/**\n * Create a service error for expired authentication.\n */\nexport function authExpiredError(service: string): ServiceError {\n return {\n code: ErrorCodes.AUTH_EXPIRED,\n message: \"Session has expired. Please sign in again.\",\n service,\n };\n}\n\n/**\n * Create a service error for network issues.\n */\nexport function networkError(\n service: string,\n message: string,\n cause?: Error\n): ServiceError {\n return {\n code: ErrorCodes.NETWORK_ERROR,\n message,\n service,\n cause,\n };\n}\n\n/**\n * Abort reason for a service request that exceeded its configured timeout.\n *\n * Named `TimeoutError` (like the reason of the platform's\n * `AbortSignal.timeout()`), so it maps to `ErrorCodes.TIMEOUT` and never to\n * `ErrorCodes.ABORTED`, which is reserved for caller and sign-out aborts.\n */\nexport class RequestTimeoutError extends Error {\n readonly timeoutMs: number;\n\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms.`);\n this.name = \"TimeoutError\";\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Whether an error is a {@link RequestTimeoutError}. Also matches by shape so\n * that a copy of the class from another bundle (ESM/CJS entrypoint) is\n * recognized.\n */\nexport function isRequestTimeoutError(error: unknown): error is RequestTimeoutError {\n return (\n error instanceof RequestTimeoutError ||\n (error instanceof Error &&\n error.name === \"TimeoutError\" &&\n typeof (error as { timeoutMs?: unknown }).timeoutMs === \"number\")\n );\n}\n\n/**\n * Create a service error for timeouts.\n *\n * @param timeoutMs - The configured timeout that elapsed, when known\n * @param cause - The underlying timeout error, when known\n */\nexport function timeoutError(\n service: string,\n timeoutMs?: number,\n cause?: Error\n): ServiceError {\n if (timeoutMs === undefined) {\n return {\n code: ErrorCodes.TIMEOUT,\n message: \"Request timed out.\",\n service,\n ...(cause === undefined ? {} : { cause }),\n };\n }\n return {\n code: ErrorCodes.TIMEOUT,\n message: `Request timed out after ${timeoutMs}ms.`,\n service,\n ...(cause === undefined ? {} : { cause }),\n meta: { timeoutMs },\n };\n}\n\n/**\n * Create a service error for aborted requests.\n */\nexport function abortedError(service: string): ServiceError {\n return {\n code: ErrorCodes.ABORTED,\n message: \"Request was aborted.\",\n service,\n };\n}\n\n/**\n * Create a service error for not found resources.\n */\nexport function notFoundError(\n service: string,\n resource: string\n): ServiceError {\n return {\n code: ErrorCodes.NOT_FOUND,\n message: `Resource not found: ${resource}`,\n service,\n };\n}\n\n/**\n * Create a service error for permission denied.\n */\nexport function permissionDeniedError(\n service: string,\n action: string\n): ServiceError {\n return {\n code: ErrorCodes.PERMISSION_DENIED,\n message: `Permission denied for action: ${action}`,\n service,\n };\n}\n\n/**\n * Parse the server's \"Unauthorized Action: {resource} / {ability}\" pattern.\n */\nexport function parseAuthError(responseText: string): { resource?: string; action?: string } {\n const match = responseText.match(/^Unauthorized Action:\\s*(.+?)\\s*\\/\\s*(tinycloud\\.\\S+)$/m);\n if (match) {\n return { resource: match[1].trim(), action: match[2].trim() };\n }\n return {};\n}\n\n/**\n * Create a service error for unauthorized action (missing capability).\n */\nexport function authUnauthorizedError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return serviceError(ErrorCodes.AUTH_UNAUTHORIZED, message, service, { meta });\n}\n\n/**\n * Authorization verdict read from an error's structure, never its message:\n * - `\"unauthenticated\"`: HTTP 401 — the session is missing or stale.\n * - `\"forbidden\"`: HTTP 403, or `AUTH_UNAUTHORIZED` without a status — the\n * session is valid but lacks the capability.\n * - `\"other\"`: a non-authorization HTTP error status (4xx/5xx).\n */\nexport type AuthorizationVerdict = \"unauthenticated\" | \"forbidden\" | \"other\";\n\nconst grantableActions = new Set(\n CAPABILITY_REGISTRY.map(({ urn }) => urn).filter((urn) => !urn.endsWith(\"/*\"))\n);\n\nconst capabilityServices = new Set(\n CAPABILITY_REGISTRY.map(({ service }) => service.slice(\"tinycloud.\".length))\n);\n\n/**\n * Parse a canonical TinyCloud resource, keeping nested space names intact.\n * The first registered service segment is authoritative: a later matching\n * segment in the path cannot turn a different service into grant advice.\n */\nexport function parseCapabilityResource(\n resource: string,\n service: string\n): { space: string; path: string } | undefined {\n if (\n resource.length === 0 ||\n resource.length > 1024 ||\n !capabilityServices.has(service) ||\n /[\\s\\p{C}*#]/u.test(resource) ||\n resource.includes(\"://\")\n ) return undefined;\n\n const segments = resource.split(\"/\");\n if (!/^tinycloud:[A-Za-z0-9][A-Za-z0-9:._-]*$/.test(segments[0])) return undefined;\n const serviceIndex = segments.findIndex((segment, index) =>\n index > 0 && capabilityServices.has(segment)\n );\n if (serviceIndex < 1 || segments[serviceIndex] !== service) return undefined;\n if (segments.slice(1, serviceIndex).some((segment) =>\n segment.length === 0 || segment === \".\" || segment === \"..\"\n )) return undefined;\n const pathSegments = segments.slice(serviceIndex + 1);\n if (pathSegments.some((segment) => segment === \".\" || segment === \"..\")) return undefined;\n if (service !== \"kv\" && (pathSegments.length === 0 || pathSegments[pathSegments.length - 1] === \"\")) return undefined;\n\n return {\n space: segments.slice(0, serviceIndex).join(\"/\"),\n path: pathSegments.join(\"/\"),\n };\n}\n\n/** A capability resource is a canonical TinyCloud resource or encryption network, never a URL or expression. */\nfunction safeCapabilityResource(value: unknown, service: string, action: string): value is string {\n if (typeof value !== \"string\" || value.length === 0 || value.length > 1024) return false;\n if (service === \"encryption\" && value.startsWith(\"urn:tinycloud:encryption:\")) {\n if (\n !/^[A-Za-z0-9_][A-Za-z0-9_.:/-]*$/.test(value) ||\n value.includes(\"//\") ||\n value.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n ) return false;\n try {\n parseNetworkId(value);\n return true;\n } catch {\n return false;\n }\n }\n const parsed = parseCapabilityResource(value, service);\n return parsed !== undefined &&\n (!parsed.path.endsWith(\"/\") || (service === \"kv\" && action === \"tinycloud.kv/list\")) &&\n (parsed.path !== \"\" || (service === \"kv\" && action === \"tinycloud.kv/list\"));\n}\n\n/**\n * Return a grantable missing capability only when typed authorization evidence\n * and both safe, service-matched capability fields are present. Status alone,\n * message text, wildcard actions and unrecognized actions cannot grant scope.\n */\nexport function validatedCapabilityOf(\n error: unknown\n): { resource: string; requiredAction: string } | undefined {\n const verdict = authorizationVerdictOf(error);\n if (verdict !== \"unauthenticated\" && verdict !== \"forbidden\") return undefined;\n\n const seen = new Set<unknown>();\n let node: unknown = error;\n for (\n let depth = 0;\n depth < MAX_CAUSE_DEPTH && typeof node === \"object\" && node !== null && !seen.has(node);\n depth += 1\n ) {\n seen.add(node);\n const record = node as Record<string, unknown>;\n const status = errorStatusOf(record);\n const meta = record.meta;\n if (\n (status === 401 || status === 403 || (status === undefined && record.code === ErrorCodes.AUTH_UNAUTHORIZED)) &&\n typeof meta === \"object\" && meta !== null && !Array.isArray(meta)\n ) {\n const metadata = meta as Record<string, unknown>;\n const { resource, requiredAction } = metadata;\n if (typeof requiredAction === \"string\" && grantableActions.has(requiredAction)) {\n const actionService = requiredAction.slice(\"tinycloud.\".length, requiredAction.indexOf(\"/\"));\n const explicitService = record.service === undefined ? metadata.service : record.service;\n if (\n safeCapabilityResource(resource, actionService, requiredAction) &&\n (explicitService === undefined ||\n explicitService === actionService ||\n explicitService === `tinycloud.${actionService}`)\n ) {\n return { resource, requiredAction };\n }\n }\n }\n node = record.cause;\n }\n return undefined;\n}\n\nconst MAX_CAUSE_DEPTH = 8;\n\n/** The first 4xx/5xx among `status`, `statusCode`, `meta.status`. Success and\n * informational statuses (e.g. a 200 `Response` kept as `cause`) are not\n * failures, so they are skipped rather than ending the search. */\nfunction errorStatusOf(node: Record<string, unknown>): number | undefined {\n const meta = node.meta;\n const candidates = [\n node.status,\n node.statusCode,\n typeof meta === \"object\" && meta !== null\n ? (meta as Record<string, unknown>).status\n : undefined,\n ];\n for (const candidate of candidates) {\n if (\n typeof candidate === \"number\" &&\n Number.isInteger(candidate) &&\n candidate >= 400 &&\n candidate <= 599\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n\n/**\n * Classify an error from its typed HTTP error status (`status`, `statusCode`,\n * or `meta.status`, 4xx/5xx only) and `AUTH_UNAUTHORIZED` code, following the\n * `cause` chain outer-first (at most {@link MAX_CAUSE_DEPTH} links, cycles\n * stop the walk) so wrappers that rethrow with `cause` keep the verdict. The\n * outermost error status decides, so an outer 5xx keeps its retry budget even\n * over an inner 401. Returns `undefined` for untyped errors; only then may\n * callers fall back to message heuristics.\n */\nexport function authorizationVerdictOf(\n error: unknown,\n): AuthorizationVerdict | undefined {\n const seen = new Set<unknown>();\n let sawUnauthorizedCode = false;\n let node: unknown = error;\n for (\n let depth = 0;\n depth < MAX_CAUSE_DEPTH && typeof node === \"object\" && node !== null && !seen.has(node);\n depth += 1\n ) {\n seen.add(node);\n const record = node as Record<string, unknown>;\n const status = errorStatusOf(record);\n if (status === 401) return \"unauthenticated\";\n if (status === 403) return \"forbidden\";\n if (status !== undefined) return \"other\";\n if (record.code === ErrorCodes.AUTH_UNAUTHORIZED) sawUnauthorizedCode = true;\n node = record.cause;\n }\n return sawUnauthorizedCode ? \"forbidden\" : undefined;\n}\n\n/**\n * Create a service error for storage quota exceeded (402 Payment Required).\n */\nexport function storageQuotaExceededError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return {\n code: ErrorCodes.STORAGE_QUOTA_EXCEEDED,\n message,\n service,\n meta,\n };\n}\n\n/**\n * Create a service error for storage limit reached (413 Payload Too Large).\n */\nexport function storageLimitReachedError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return {\n code: ErrorCodes.STORAGE_LIMIT_REACHED,\n message,\n service,\n meta,\n };\n}\n\n/** Shown when a write is rejected because the owner's storage is full. */\nexport const STORAGE_FULL_MESSAGE =\n \"TinyCloud storage is full, so this change was not saved. Reading still works. Free up space or upgrade your plan to save again.\";\n\n/** Shown when a write is larger than the storage the owner has left. */\nexport const STORAGE_WRITE_TOO_LARGE_MESSAGE =\n \"This change is larger than the TinyCloud storage you have left, so it was not saved. Reading still works. Free up space or upgrade your plan to save it.\";\n\n/**\n * Parse the byte counts from a node storage rejection\n * (\"... Used: 155744 bytes, Limit: 0 bytes\"). The limit is the share of the\n * owner's account-wide budget left for this space, so it is 0 when the\n * owner's other spaces already use the whole budget.\n */\nexport function parseStorageQuotaBytes(\n responseText: string\n): { usedBytes: number; limitBytes: number } | undefined {\n const match = responseText.match(/Used:\\s*(\\d+)\\s*bytes,\\s*Limit:\\s*(\\d+)\\s*bytes/i);\n if (!match) return undefined;\n return {\n usedBytes: parseInt(match[1], 10),\n limitBytes: parseInt(match[2], 10),\n };\n}\n\n/**\n * Build the error for a write the node rejected for storage: 402 when storage\n * is already full, 413 when this write is larger than what is left. KV, SQL\n * and DuckDB all report it with the same codes and message so an app can\n * detect \"storage full\" in one place with {@link isStorageFullError}.\n */\nexport function storageRejectionError(\n service: string,\n status: 402 | 413,\n meta: Record<string, unknown>,\n responseText: string\n): ServiceError {\n const quotaMeta = { ...meta, ...parseStorageQuotaBytes(responseText) };\n return status === 402\n ? storageQuotaExceededError(service, STORAGE_FULL_MESSAGE, quotaMeta)\n : storageLimitReachedError(service, STORAGE_WRITE_TOO_LARGE_MESSAGE, quotaMeta);\n}\n\n/**\n * True when a write failed for storage: the owner's TinyCloud storage is full\n * (`STORAGE_QUOTA_EXCEEDED`), or this write is larger than what is left\n * (`STORAGE_LIMIT_REACHED`). Reads keep working in both cases, so apps should\n * stay usable read-only and point the user at freeing up space or upgrading.\n */\nexport function isStorageFullError(error: { code?: string } | null | undefined): boolean {\n return (\n error?.code === ErrorCodes.STORAGE_QUOTA_EXCEEDED ||\n error?.code === ErrorCodes.STORAGE_LIMIT_REACHED\n );\n}\n\n/**\n * Wrap an unknown error in a ServiceError.\n */\nexport function wrapError(\n service: string,\n error: unknown,\n defaultCode: string = ErrorCodes.NETWORK_ERROR\n): ServiceError {\n if (error instanceof Error) {\n // A configured request timeout elapsed (see BaseService.createRequestSignal)\n if (isRequestTimeoutError(error)) {\n return timeoutError(service, error.timeoutMs, error);\n }\n\n // Check for abort errors\n if (error.name === \"AbortError\") {\n return abortedError(service);\n }\n\n // Check for timeout errors (varies by platform)\n if (\n error.name === \"TimeoutError\" ||\n error.message.toLowerCase().includes(\"timeout\")\n ) {\n return timeoutError(service);\n }\n\n return {\n code: defaultCode,\n message: error.message,\n service,\n cause: error,\n };\n }\n\n return {\n code: defaultCode,\n message: String(error),\n service,\n };\n}\n\n/**\n * Create an error Result from a ServiceError.\n */\nexport function errorResult(error: ServiceError) {\n return err(error);\n}\n","/**\n * TinyCloud encryption network identifiers.\n *\n * A network id is `urn:tinycloud:encryption:<ownerDid>:<network>` where\n * `ownerDid` is the owner's DID and `network` is a\n * non-empty label drawn from `[a-z0-9][a-z0-9-]*`.\n *\n * The embedded owner DID is the root authority for the network: any\n * delegation chain ending in a `tinycloud.encryption/decrypt` grant on\n * the network must root at this owner DID.\n */\n\nconst URN_PREFIX = \"urn:tinycloud:encryption:\";\nconst NETWORK_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;\nconst PKH_EIP155_DID_RE = /^did:pkh:eip155:(\\d+):(0x[a-fA-F0-9]{40})$/;\n\nexport interface ParsedNetworkId {\n /** The full URN string. */\n networkId: string;\n /** Owner DID embedded in the URN (the network's root authority). */\n ownerDid: string;\n /** Network label (the suffix after the owner DID). */\n name: string;\n}\n\nexport class NetworkIdError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NetworkIdError\";\n }\n}\n\n/**\n * Parse a network id string into its owner DID and name components.\n *\n * Throws {@link NetworkIdError} when the input does not match\n * `urn:tinycloud:encryption:<did>:<name>`, when the embedded DID is\n * malformed, or when the network name fails {@link NETWORK_NAME_RE}.\n */\nexport function parseNetworkId(networkId: string): ParsedNetworkId {\n if (typeof networkId !== \"string\" || networkId.length === 0) {\n throw new NetworkIdError(\"networkId must be a non-empty string\");\n }\n if (!networkId.startsWith(URN_PREFIX)) {\n throw new NetworkIdError(\n `networkId must start with ${URN_PREFIX} (got ${JSON.stringify(networkId)})`,\n );\n }\n const body = networkId.slice(URN_PREFIX.length);\n // `body` = \"<ownerDid>:<network>\"\n // ownerDid contains ':' (e.g. did:key:z6Mk...), so we split on the LAST colon\n // and treat the suffix as the network name.\n const lastColon = body.lastIndexOf(\":\");\n if (lastColon <= 0 || lastColon === body.length - 1) {\n throw new NetworkIdError(\n `networkId missing ownerDid or name segment (got ${JSON.stringify(networkId)})`,\n );\n }\n const ownerDid = body.slice(0, lastColon);\n const name = body.slice(lastColon + 1);\n\n if (!ownerDid.startsWith(\"did:\")) {\n throw new NetworkIdError(\n `networkId ownerDid must be a DID (got ${JSON.stringify(ownerDid)})`,\n );\n }\n // Minimal DID shape: did:<method>:<id> — three colon-separated segments,\n // each non-empty.\n const didParts = ownerDid.split(\":\");\n if (didParts.length < 3 || didParts.some((p) => p.length === 0)) {\n throw new NetworkIdError(\n `networkId ownerDid is not a well-formed DID (got ${JSON.stringify(ownerDid)})`,\n );\n }\n if (!NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `networkId name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n return { networkId, ownerDid, name };\n}\n\n/**\n * Construct a network id URN from an owner DID and a network name.\n * Validates inputs and throws {@link NetworkIdError} on bad shape.\n */\nexport function buildNetworkId(ownerDid: string, name: string): string {\n if (typeof ownerDid !== \"string\" || !ownerDid.startsWith(\"did:\")) {\n throw new NetworkIdError(\"ownerDid must be a DID\");\n }\n if (typeof name !== \"string\" || !NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n const networkId = `${URN_PREFIX}${ownerDid}:${name}`;\n // Re-validate the composed result so the same error path triggers\n // for caller inputs that compose into a malformed URN.\n parseNetworkId(networkId);\n return networkId;\n}\n\n/**\n * Returns true when {@link networkId} is a syntactically valid network URN.\n */\nexport function isNetworkId(networkId: unknown): networkId is string {\n if (typeof networkId !== \"string\") {\n return false;\n }\n try {\n parseNetworkId(networkId);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction parsePkhOwnerDid(ownerDid: string):\n | { chainId: string; address: string }\n | null {\n const match = ownerDid.match(PKH_EIP155_DID_RE);\n if (!match) return null;\n return {\n chainId: match[1],\n address: match[2].toLowerCase(),\n };\n}\n\n/**\n * Compare owner DIDs as network principals. For `did:pkh:eip155`, EVM\n * address casing is not part of principal identity; other DID methods\n * remain exact string matches.\n */\nexport function ownerDidMatches(a: string, b: string): boolean {\n const aPkh = parsePkhOwnerDid(a);\n const bPkh = parsePkhOwnerDid(b);\n if (aPkh && bPkh) {\n return aPkh.chainId === bPkh.chainId && aPkh.address === bPkh.address;\n }\n return a === b;\n}\n\n/**\n * Resolve the discovery key used to look up a network's descriptor under\n * an owner's public account-space.\n *\n * Format: `.well-known/encryption/network/<name>`.\n */\nexport function networkDiscoveryKey(name: string): string {\n if (!NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n return `.well-known/encryption/network/${name}`;\n}\n\nexport const ENCRYPTION_NETWORK_URN_PREFIX = URN_PREFIX;\nexport const NETWORK_NAME_PATTERN = NETWORK_NAME_RE;\n","/**\n * BaseService - Abstract base class for all TinyCloud services.\n *\n * Provides common functionality:\n * - Context management\n * - Session lifecycle hooks\n * - Abort signal handling\n * - Telemetry emission\n */\n\nimport {\n IService,\n IServiceContext,\n ServiceSession,\n ServiceError,\n TelemetryEvents,\n err,\n Result,\n} from \"../types\";\nimport { authRequiredError, wrapError, RequestTimeoutError } from \"../errors\";\nimport type { RequestSignal } from \"./types\";\n\n/** setTimeout's delay is a signed 32-bit integer; larger values fire at once. */\nconst MAX_TIMER_DELAY_MS = 2_147_483_647;\n\n/**\n * Abstract base class for TinyCloud services.\n *\n * Services extend this class to get common functionality like\n * context management, session lifecycle, and abort handling.\n *\n * @example\n * ```typescript\n * class MyService extends BaseService implements IMyService {\n * static readonly serviceName = 'myservice';\n *\n * constructor(config: MyServiceConfig = {}) {\n * super();\n * this._config = config;\n * }\n *\n * async doSomething(): Promise<Result<Data>> {\n * if (!this.requireAuth()) {\n * return err(authRequiredError('myservice'));\n * }\n * // ... implementation\n * }\n * }\n * ```\n */\nexport abstract class BaseService implements IService {\n /**\n * Service identifier used for registration.\n * Must be overridden by subclasses.\n */\n static readonly serviceName: string;\n\n /**\n * Service context providing access to platform dependencies.\n * Set during initialize().\n */\n protected context!: IServiceContext;\n\n /**\n * Abort controller for this service's operations.\n * Reset on sign-out.\n */\n protected abortController: AbortController = new AbortController();\n\n /**\n * Service-specific configuration.\n */\n protected _config: Record<string, unknown> = {};\n\n /**\n * Get the service configuration.\n */\n get config(): Record<string, unknown> {\n return this._config;\n }\n\n /**\n * Initialize the service with context.\n * Called by the SDK after instantiation.\n *\n * @param context - The service context\n */\n initialize(context: IServiceContext): void {\n this.context = context;\n }\n\n /**\n * Called when session changes (sign-in, sign-out, refresh).\n * Override in subclasses to handle session changes.\n *\n * @param session - The new session, or null if signed out\n */\n onSessionChange(session: ServiceSession | null): void {\n // Override in subclass if needed\n }\n\n /**\n * Called when SDK signs out.\n * Aborts all pending operations.\n */\n onSignOut(): void {\n this.abortController.abort();\n this.abortController = new AbortController();\n }\n\n /**\n * Get the abort signal for this service.\n * Combines the service-level abort with context-level abort.\n */\n protected get abortSignal(): AbortSignal {\n return this.combineSignals();\n }\n\n /**\n * Check if the service is authenticated.\n */\n protected get isAuthenticated(): boolean {\n return this.context?.isAuthenticated ?? false;\n }\n\n /**\n * Get the current session.\n * Throws if not authenticated.\n */\n protected get session(): ServiceSession {\n if (!this.context?.session) {\n throw new Error(\"Not authenticated\");\n }\n return this.context.session;\n }\n\n /**\n * Check authentication and return error result if not authenticated.\n * Use this at the start of methods that require authentication.\n *\n * @returns true if authenticated, false otherwise\n */\n protected requireAuth(): boolean {\n return this.isAuthenticated;\n }\n\n /**\n * Emit a telemetry event.\n *\n * @param event - Event name\n * @param data - Event data\n */\n protected emit(event: string, data: unknown): void {\n this.context?.emit(event, data);\n }\n\n /**\n * Emit a service request event.\n *\n * @param action - The action being performed\n * @param key - Optional key/path being accessed\n */\n protected emitRequest(action: string, key?: string): void {\n const service = this.getServiceName();\n this.emit(TelemetryEvents.SERVICE_REQUEST, {\n service,\n action,\n span: this.spanName(action),\n key,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Emit a service response event.\n *\n * @param action - The action that was performed\n * @param ok - Whether the request was successful\n * @param startTime - Start time for duration calculation\n * @param status - Optional HTTP status code\n */\n protected emitResponse(\n action: string,\n ok: boolean,\n startTime: number,\n status?: number\n ): void {\n const service = this.getServiceName();\n const durationMs = Date.now() - startTime;\n const span = this.spanName(action);\n this.emit(TelemetryEvents.SERVICE_RESPONSE, {\n service,\n action,\n span,\n ok,\n duration: durationMs,\n durationMs,\n status,\n });\n this.emit(TelemetryEvents.SPAN, {\n span,\n service,\n action,\n ok,\n durationMs,\n status,\n });\n }\n\n /**\n * Emit a service error event.\n *\n * @param error - The service error\n */\n protected emitError(error: ServiceError, action?: string): void {\n const span = action ? this.spanName(action) : undefined;\n this.emit(TelemetryEvents.SERVICE_ERROR, {\n service: this.getServiceName(),\n ...(span ? { span } : {}),\n error,\n });\n }\n\n /**\n * Get the service name from the static property.\n * Subclasses must define static serviceName.\n */\n protected getServiceName(): string {\n return (this.constructor as typeof BaseService).serviceName;\n }\n\n /**\n * Stable span name used by SDK telemetry sinks.\n */\n protected spanName(action: string): string {\n return `sdk.${this.getServiceName()}.${action}`;\n }\n\n /**\n * Create a combined abort signal from multiple sources.\n *\n * @param signals - Additional abort signals to combine\n * @returns A combined abort signal\n */\n protected combineSignals(...signals: (AbortSignal | undefined)[]): AbortSignal {\n const controller = new AbortController();\n const allSignals = [\n this.abortController.signal,\n this.context?.abortSignal,\n ...signals.filter(Boolean),\n ].filter(Boolean) as AbortSignal[];\n\n for (const signal of allSignals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n signal.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n\n return controller.signal;\n }\n\n /**\n * Create the abort signal for one request, bounded by the request timeout.\n *\n * The signal aborts when the service signs out, the context aborts, the\n * caller's `signal` aborts, or the timeout elapses, whichever comes first.\n * A timeout aborts with a {@link RequestTimeoutError} (`TimeoutError`), which\n * `wrapError` maps to `ErrorCodes.TIMEOUT`; the other sources keep their own\n * reason (normally `AbortError`, mapped to `ErrorCodes.ABORTED`).\n *\n * The timeout is `timeoutMs` when given, otherwise `config.timeout`. Only a\n * positive, finite value (at most 2^31-1 ms) applies; `undefined`, `0`, and\n * `Infinity` mean no timeout, so a per-call `0` opts out of a configured one.\n *\n * Callers must call `dispose()` once the response body has been consumed,\n * which clears the timer and removes the listeners this adds to the\n * long-lived service and context signals.\n *\n * @param signal - The caller's abort signal for this request\n * @param timeoutMs - Per-request timeout override in milliseconds\n */\n protected createRequestSignal(\n signal?: AbortSignal,\n timeoutMs?: number\n ): RequestSignal {\n const controller = new AbortController();\n const detachers: Array<() => void> = [];\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const dispose = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n for (const detach of detachers.splice(0)) {\n detach();\n }\n };\n const abort = (reason: unknown): void => {\n dispose();\n controller.abort(reason);\n };\n const requestSignal: RequestSignal = { signal: controller.signal, dispose };\n\n const parents = [\n this.abortController.signal,\n this.context?.abortSignal,\n signal,\n ].filter((parent): parent is AbortSignal => parent !== undefined);\n for (const parent of parents) {\n if (parent.aborted) {\n abort(parent.reason);\n return requestSignal;\n }\n const onAbort = (): void => abort(parent.reason);\n parent.addEventListener(\"abort\", onAbort, { once: true });\n detachers.push(() => parent.removeEventListener(\"abort\", onAbort));\n }\n\n const timeout = timeoutMs ?? this._config.timeout;\n if (\n typeof timeout === \"number\" &&\n timeout > 0 &&\n timeout <= MAX_TIMER_DELAY_MS\n ) {\n timer = setTimeout(() => abort(new RequestTimeoutError(timeout)), timeout);\n }\n\n return requestSignal;\n }\n\n /**\n * Wrap an operation with error handling and telemetry.\n *\n * @param action - The action name for telemetry\n * @param key - Optional key for telemetry\n * @param operation - The operation to execute\n * @returns Result of the operation\n */\n protected async withTelemetry<T>(\n action: string,\n key: string | undefined,\n operation: () => Promise<Result<T>>\n ): Promise<Result<T>> {\n const startTime = Date.now();\n this.emitRequest(action, key);\n\n try {\n const result = await operation();\n\n if (result.ok) {\n this.emitResponse(action, true, startTime);\n } else {\n this.emitResponse(action, false, startTime);\n this.emitError(result.error, action);\n }\n\n return result;\n } catch (error) {\n const serviceError = wrapError(this.getServiceName(), error);\n this.emitResponse(action, false, startTime);\n this.emitError(serviceError, action);\n return err(serviceError);\n }\n }\n}\n","/**\n * PrefixedKVService - A prefix-scoped view of KVService.\n *\n * Provides key-value operations scoped to a specific prefix.\n * All operations automatically prefix keys, enabling app data isolation\n * within a shared space.\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // Create prefix-scoped views\n * const myApp = space.kv.withPrefix('/app.myapp.com');\n * const sharedPhotos = space.kv.withPrefix('/photos');\n *\n * // Operations are automatically prefixed\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Actually writes to: /app.myapp.com/settings.json\n *\n * await myApp.get('settings.json');\n * // -> Actually reads from: /app.myapp.com/settings.json\n *\n * await sharedPhotos.list();\n * // -> Lists: /photos/*\n *\n * // Nested prefixes\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\n\nimport { Result, ok, err, ErrorCodes, serviceError } from \"../types\";\nimport {\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVBatchReadResponse,\n KVListOptions,\n KVChange,\n KVChangesOptions,\n KVChangesResponse,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVSignedReadUrlResponse,\n} from \"./types\";\n\n/**\n * Interface for prefixed KV operations.\n *\n * Provides the same operations as IKVService but scoped to a prefix.\n * Supports nested prefixes via withPrefix().\n */\nexport interface IPrefixedKVService {\n /**\n * The current prefix for this scoped view.\n */\n readonly prefix: string;\n\n /**\n * Get a value by key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to retrieve (will be prefixed)\n * @param options - Optional get configuration\n * @returns Result with the stored value and headers\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.get('settings.json');\n * // -> Reads from: /app.myapp.com/settings.json\n * ```\n */\n get<T = unknown>(\n key: string,\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVResponse<T>>>;\n\n batchGet<T = unknown>(\n keys: string[],\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVBatchReadResponse<T>>>;\n\n /**\n * Store a value at a key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to store under (will be prefixed)\n * @param value - The value to store\n * @param options - Optional put configuration\n * @returns Result indicating success/failure\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Stores at: /app.myapp.com/settings.json\n * ```\n */\n put(\n key: string,\n value: unknown,\n options?: Omit<KVPutOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>>;\n\n /**\n * Store multiple values within this prefix in one TinyCloud KV invocation.\n */\n batchPut(\n items: KVBatchPutItem[],\n options?: Omit<KVBatchPutOptions, 'prefix'>\n ): Promise<Result<KVBatchPutResponse>>;\n\n /**\n * List keys within this prefix.\n *\n * Returns keys that match the prefix, with keys returned relative\n * to the prefix when removePrefix is true (default for prefixed service).\n *\n * @param options - Optional list configuration\n * @returns Result with array of matching keys\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.list();\n * // -> Lists keys under: /app.myapp.com/*\n * // Returns: ['settings.json', 'data/user.json', ...]\n * ```\n */\n list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>>;\n\n /**\n * Read one page of the change feed for everything under this prefix\n * (`tinycloud.kv/sync` on `<prefix>/`). Keys are returned relative to the\n * prefix, like `list`; `source.prefix` stays the node's full prefix.\n * See `IKVService.changes` for paging and errors.\n *\n * @example\n * ```typescript\n * const notes = kv.withPrefix('notes');\n * const page = await notes.changes({ limit: 100 });\n * // -> Feed of: notes/*, keys like 'a.md'\n * ```\n */\n changes(options?: Omit<KVChangesOptions, 'prefix'>): Promise<Result<KVChangesResponse>>;\n\n /**\n * Delete a key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to delete (will be prefixed)\n * @param options - Optional delete configuration\n * @returns Result indicating success/failure\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * await myApp.delete('old-settings.json');\n * // -> Deletes: /app.myapp.com/old-settings.json\n * ```\n */\n delete(\n key: string,\n options?: Omit<KVDeleteOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>>;\n\n /**\n * Get metadata for a key without retrieving the value.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to check (will be prefixed)\n * @param options - Optional head configuration\n * @returns Result with headers only\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.head('large-file.bin');\n * // -> Gets metadata for: /app.myapp.com/large-file.bin\n * ```\n */\n head(key: string, options?: Omit<KVHeadOptions, 'prefix'>): Promise<Result<KVResponse<void>>>;\n\n batchHead(\n keys: string[],\n options?: Omit<KVHeadOptions, 'prefix'>\n ): Promise<Result<KVBatchReadResponse<void>>>;\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to expose via a signed read URL (will be prefixed)\n * @param options - Optional signed URL configuration\n * @returns Result with URL and expiry metadata\n */\n createSignedReadUrl(\n key: string,\n options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>\n ): Promise<Result<KVSignedReadUrlResponse>>;\n\n /**\n * Create a nested prefix-scoped view.\n *\n * The subPrefix is appended to the current prefix.\n *\n * @param subPrefix - The sub-prefix to append\n * @returns A new PrefixedKVService with the combined prefix\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json');\n * // -> Reads from: /app.myapp.com/settings/theme.json\n * ```\n */\n withPrefix(subPrefix: string): IPrefixedKVService;\n}\n\n/**\n * Interface for a KV service that supports prefix delegation.\n *\n * This is the subset of IKVService methods needed by PrefixedKVService.\n */\ninterface IKVServiceLike {\n get<T = unknown>(\n key: string,\n options?: KVGetOptions\n ): Promise<Result<KVResponse<T>>>;\n\n batchGet<T = unknown>(\n keys: string[],\n options?: KVGetOptions\n ): Promise<Result<KVBatchReadResponse<T>>>;\n\n put(\n key: string,\n value: unknown,\n options?: KVPutOptions\n ): Promise<Result<KVResponse<void>>>;\n\n batchPut(\n items: KVBatchPutItem[],\n options?: KVBatchPutOptions\n ): Promise<Result<KVBatchPutResponse>>;\n\n list(options?: KVListOptions): Promise<Result<KVListResponse>>;\n\n changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;\n\n delete(key: string, options?: KVDeleteOptions): Promise<Result<KVResponse<void>>>;\n\n head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;\n\n batchHead(\n keys: string[],\n options?: KVHeadOptions\n ): Promise<Result<KVBatchReadResponse<void>>>;\n\n createSignedReadUrl(\n key: string,\n options?: KVCreateSignedReadUrlOptions\n ): Promise<Result<KVSignedReadUrlResponse>>;\n}\n\n/**\n * PrefixedKVService - Implementation of prefix-scoped KV operations.\n *\n * This class wraps a KVService (or another PrefixedKVService) and\n * automatically prefixes all key operations with the configured prefix.\n *\n * ## Prefix Convention\n *\n * | Pattern | Use Case | Example |\n * | -- | -- | -- |\n * | `/app.{domain}/` | App-private data | `/app.photos.xyz/settings.json` |\n * | `/{type}/` | Shared data type | `/photos/vacation.jpg` |\n * | `/.{name}/` | Hidden/system data | `/.cache/thumbnails/` |\n * | `/public/` | Explicitly shareable | `/public/profile.json` |\n *\n * @example\n * ```typescript\n * // Create from KVService\n * const prefixed = new PrefixedKVService(kvService, '/app.myapp.com');\n *\n * // Or use the withPrefix factory method on KVService\n * const prefixed = kvService.withPrefix('/app.myapp.com');\n *\n * // All operations are automatically prefixed\n * await prefixed.put('settings.json', { theme: 'dark' });\n * await prefixed.get('settings.json');\n *\n * // Nested prefixes\n * const nested = prefixed.withPrefix('/settings');\n * await nested.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\nexport class PrefixedKVService implements IPrefixedKVService {\n /**\n * The underlying KV service.\n */\n private readonly _kv: IKVServiceLike;\n\n /**\n * The prefix for this scoped view.\n */\n private readonly _prefix: string;\n\n /**\n * Create a new PrefixedKVService.\n *\n * @param kv - The underlying KV service to delegate to\n * @param prefix - The prefix to apply to all operations\n */\n constructor(kv: IKVServiceLike, prefix: string) {\n this._kv = kv;\n // Normalize prefix: ensure it doesn't end with slash\n this._prefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n }\n\n /**\n * The current prefix for this scoped view.\n */\n get prefix(): string {\n return this._prefix;\n }\n\n /**\n * Compute the full key path by combining prefix and key.\n *\n * @param key - The key to prefix\n * @returns The full path including prefix\n */\n private getFullKey(key: string): string {\n // Handle keys that start with slash\n const normalizedKey = key.startsWith('/') ? key : `/${key}`;\n return `${this._prefix}${normalizedKey}`;\n }\n\n /**\n * Get a value by key.\n */\n async get<T = unknown>(\n key: string,\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVResponse<T>>> {\n const fullKey = this.getFullKey(key);\n // Use empty prefix override to use the full key as-is\n return this._kv.get<T>(fullKey, { ...options, prefix: '' });\n }\n\n async batchGet<T = unknown>(\n keys: string[],\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVBatchReadResponse<T>>> {\n const response = await this._kv.batchGet<T>(\n keys.map((key) => this.getFullKey(key)),\n { ...options, prefix: '' }\n );\n if (!response.ok) return response;\n return ok({\n ...response.data,\n results: response.data.results.map((item, index) => ({\n ...item,\n key: keys[index]!,\n })),\n });\n }\n\n /**\n * Store a value at a key.\n */\n async put(\n key: string,\n value: unknown,\n options?: Omit<KVPutOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.put(fullKey, value, { ...options, prefix: '' });\n }\n\n /**\n * Store multiple values within this prefix in one TinyCloud KV invocation.\n */\n async batchPut(\n items: KVBatchPutItem[],\n options?: Omit<KVBatchPutOptions, 'prefix'>\n ): Promise<Result<KVBatchPutResponse>> {\n return this._kv.batchPut(\n items.map((item) => ({\n ...item,\n key: this.getFullKey(item.key),\n })),\n { ...options, prefix: '' }\n );\n }\n\n /**\n * List keys within this prefix.\n */\n async list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>> {\n // List uses the prefix directly, and by default removes the prefix from results\n const removePrefix = options?.removePrefix ?? true;\n return this._kv.list({\n ...options,\n prefix: this._prefix,\n removePrefix,\n });\n }\n\n /**\n * Read the change feed for everything under this prefix. A view with an\n * empty prefix (`\"\"` or `\"/\"`) is refused: the node does not serve a\n * whole-space feed.\n */\n async changes(\n options?: Omit<KVChangesOptions, 'prefix'>\n ): Promise<Result<KVChangesResponse>> {\n if (this._prefix.replace(/\\/+$/, '') === '') {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n 'KV changes needs a non-empty prefix; this view has none',\n 'kv'\n ));\n }\n const syncPrefix = `${this._prefix}/`;\n const response = await this._kv.changes({ ...options, prefix: syncPrefix });\n if (!response.ok) return response;\n return ok({\n ...response.data,\n changes: response.data.changes.map((change): KVChange => ({\n ...change,\n key: change.key.startsWith(syncPrefix)\n ? change.key.slice(syncPrefix.length)\n : change.key,\n })),\n });\n }\n\n /**\n * Delete a key.\n */\n async delete(\n key: string,\n options?: Omit<KVDeleteOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.delete(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Get metadata for a key without retrieving the value.\n */\n async head(\n key: string,\n options?: Omit<KVHeadOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.head(fullKey, { ...options, prefix: '' });\n }\n\n async batchHead(\n keys: string[],\n options?: Omit<KVHeadOptions, 'prefix'>\n ): Promise<Result<KVBatchReadResponse<void>>> {\n const response = await this._kv.batchHead(\n keys.map((key) => this.getFullKey(key)),\n { ...options, prefix: '' }\n );\n if (!response.ok) return response;\n return ok({\n ...response.data,\n results: response.data.results.map((item, index) => ({\n ...item,\n key: keys[index]!,\n })),\n });\n }\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n */\n async createSignedReadUrl(\n key: string,\n options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>\n ): Promise<Result<KVSignedReadUrlResponse>> {\n const fullKey = this.getFullKey(key);\n return this._kv.createSignedReadUrl(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Create a nested prefix-scoped view.\n */\n withPrefix(subPrefix: string): IPrefixedKVService {\n // Normalize subPrefix\n const normalizedSubPrefix = subPrefix.startsWith('/')\n ? subPrefix\n : `/${subPrefix}`;\n const combinedPrefix = `${this._prefix}${normalizedSubPrefix}`;\n return new PrefixedKVService(this._kv, combinedPrefix);\n }\n}\n","/**\n * KV Service Types\n *\n * Type definitions for the KV (Key-Value) service operations.\n */\n\nimport type { Result } from \"../types\";\n\n/**\n * Configuration for KVService.\n */\nexport interface KVServiceConfig {\n /**\n * Default prefix for all keys.\n * Useful for namespacing data within a space.\n *\n * @example\n * ```typescript\n * const kv = new KVService({ prefix: 'myapp/settings' });\n * await kv.put('theme', 'dark'); // Stores at 'myapp/settings/theme'\n * ```\n */\n prefix?: string;\n\n /**\n * Default timeout in milliseconds for each KV request, including reading\n * the response body. When it elapses the request is aborted and the\n * operation returns an `ErrorCodes.TIMEOUT` error. A per-call `timeout`\n * option overrides it. Unset (the default), `0`, or `Infinity` means no\n * timeout.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for KV get operations.\n */\nexport interface KVGetOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Return raw response instead of parsed JSON.\n * When true, data will be the raw response text.\n */\n raw?: boolean;\n\n /**\n * Return the raw response bytes as a Uint8Array instead of parsed/text data.\n * Use this to read back binary values (e.g. images) byte-identically. Takes\n * precedence over {@link raw}.\n */\n binary?: boolean;\n\n /**\n * Ask the node to reject the response when the stored value exceeds this\n * number of bytes. This bounds downloads before the response body is read.\n */\n maxResponseBytes?: number;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV put operations.\n */\nexport interface KVPutOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Content type for the value.\n * Defaults to 'application/json' for objects.\n */\n contentType?: string;\n\n /**\n * Custom metadata headers to store with the value.\n */\n metadata?: Record<string, string>;\n\n /** Only write when the current object has this strong ETag. */\n ifMatch?: string;\n\n /** Only write when the key does not exist. */\n ifNoneMatch?: \"*\";\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * One entry in a KV batch put request.\n */\nexport interface KVBatchPutItem {\n /**\n * The key to store under.\n */\n key: string;\n\n /**\n * The value to store.\n *\n * Objects are JSON stringified. Strings are stored as text. Binary values\n * should be supplied as Blob, ArrayBuffer, or Uint8Array.\n */\n value: unknown;\n\n /**\n * Content type for this item. Defaults to application/json for objects and\n * application/octet-stream for binary values.\n */\n contentType?: string;\n}\n\n/**\n * Options for KV batch put operations.\n */\nexport interface KVBatchPutOptions {\n /**\n * Override the default prefix for all entries in this batch.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Response from KV batch put operations.\n */\nexport interface KVBatchPutResponse {\n /**\n * Keys successfully written by the batch.\n */\n written: string[];\n\n /**\n * Number of written keys.\n */\n count: number;\n}\n\n/**\n * Response from a KV batch read. Transport or authorization failures are\n * returned by the outer Result; each requested key has its own Result so a\n * missing key does not discard successful siblings.\n */\nexport interface KVBatchReadResponse<T = unknown> {\n results: Array<{\n key: string;\n result: Result<KVResponse<T>>;\n }>;\n count: number;\n}\n\n/**\n * Options for KV list operations.\n */\nexport interface KVListOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Additional path to append to the prefix.\n */\n path?: string;\n\n /**\n * Whether to remove the prefix from returned keys.\n * When true, keys are returned relative to the prefix.\n */\n removePrefix?: boolean;\n\n /**\n * Return raw response instead of parsed JSON.\n */\n raw?: boolean;\n\n /** Maximum number of keys the node may return. */\n limit?: number;\n\n /** Opaque scope-bound cursor returned by a previous bounded list. */\n cursor?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV delete operations.\n */\nexport interface KVDeleteOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /** Only delete when the current object has this strong ETag. */\n ifMatch?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV head (metadata) operations.\n */\nexport interface KVHeadOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Default lifetime for signed KV read URLs when a caller omits expiresInSeconds.\n * SDK duration defaults are stored in milliseconds; createSignedReadUrl converts\n * this to the node endpoint's ttl_seconds field.\n *\n * Keep this in sync with EXPIRY.SIGNED_READ_URL_MS in @tinycloud/sdk-core.\n * sdk-services cannot import sdk-core because sdk-core depends on sdk-services.\n */\nexport const DEFAULT_SIGNED_READ_URL_EXPIRY_MS = 5 * 60 * 1000;\n\n/**\n * Options for creating a signed KV read URL.\n */\nexport interface KVCreateSignedReadUrlOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Requested URL lifetime in seconds.\n * Defaults to {@link DEFAULT_SIGNED_READ_URL_EXPIRY_MS} converted to seconds.\n * The node may cap this by its configured maximum, the invocation expiry,\n * or the parent delegation expiry.\n */\n expiresInSeconds?: number;\n\n /**\n * Optional blake3 content hash to bind the signed URL to a specific object.\n */\n contentHash?: string;\n\n /**\n * Optional ETag to bind the signed URL to a specific object version.\n */\n etag?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Response headers from KV operations.\n */\nexport interface KVResponseHeaders {\n /**\n * ETag for conditional requests.\n */\n etag?: string;\n\n /**\n * Content type of the stored value.\n */\n contentType?: string;\n\n /**\n * Last modification timestamp.\n */\n lastModified?: string;\n\n /**\n * Content length in bytes.\n */\n contentLength?: number;\n\n /**\n * Get a header value by name.\n * @param name - Header name (case-insensitive)\n */\n get(name: string): string | null;\n}\n\n/**\n * Response from KV get/put operations.\n *\n * @template T - Type of the data payload\n */\nexport interface KVResponse<T = unknown> {\n /**\n * The data payload.\n * For get: the stored value.\n * For put: undefined.\n */\n data: T;\n\n /**\n * Response headers with metadata.\n */\n headers: KVResponseHeaders;\n}\n\n/**\n * Response from KV list operations.\n */\nexport interface KVListResponse {\n /**\n * Array of keys matching the list criteria.\n */\n keys: string[];\n\n /** True when more matching keys exist than the requested limit. */\n truncated?: boolean;\n\n /** Opaque cursor for the next page, when the node returned one. */\n nextCursor?: string;\n}\n\n/**\n * Options for {@link IKVService.changes}, the `tinycloud.kv/sync` change feed.\n */\nexport interface KVChangesOptions {\n /**\n * The space-relative KV prefix to follow, sent as the invocation path. It\n * is not joined with the service's configured prefix, and must be non-empty.\n * Prefixes match whole path segments: `notes` covers `notes` and\n * `notes/a`, while `notes/` covers everything under `notes/` but not\n * `notes` itself. The session must hold `tinycloud.kv/sync` on it by name.\n *\n * Returned `changes[].key` values are full paths in the space, like this\n * prefix. On a service with a configured prefix (for example\n * `DelegatedAccess.kv`, whose prefix is the delegation path), `get` joins\n * that prefix again, so strip it from the key first, or follow the feed\n * with `kv.withPrefix(...).changes()`, which returns relative keys.\n */\n prefix: string;\n\n /**\n * The `cursor` from the previous page. Omit it to bootstrap from the start\n * of the prefix. Opaque; never parse or build one.\n */\n cursor?: string;\n\n /**\n * Page size, 1 through 1000 (node default 500). A page never splits one\n * invocation's changes, so it can hold more than `limit` changes.\n */\n limit?: number;\n\n /**\n * CID of a never-invoked delegation carrying `tinycloud.kv/retain` on the\n * prefix. When valid, the node attests `authority.retainUntil`.\n */\n retentionGrant?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * One key's latest state in a change feed page. Content is not included:\n * read it with `get`/`batchGet` and check it against `etag`.\n */\nexport type KVChange =\n | {\n key: string;\n deleted: false;\n /** The strong ETag `get` returns for this state. */\n etag: string;\n metadata: Record<string, string>;\n }\n | {\n key: string;\n deleted: true;\n };\n\n/**\n * The node-attested window in which the caller's authority holds. Values are\n * RFC 3339 timestamps, or `null` when nothing in the chain sets one.\n */\nexport interface KVChangesAuthority {\n /** The latest `nbf` across the invocation's whole delegation chain. */\n notBefore: string | null;\n /** The earliest `exp` across the invocation's whole delegation chain. */\n expiresAt: string | null;\n /**\n * The earliest `exp` across a valid retention grant's own chain. `null`\n * means no retention: none was presented, or its chain sets no expiry.\n */\n retainUntil: string | null;\n}\n\n/**\n * One page of the `tinycloud.kv/sync` change feed.\n */\nexport interface KVChangesResponse {\n /** Each changed key's latest state, in commit order. */\n changes: KVChange[];\n /**\n * More changes are available now. A page may be empty with `more: true`;\n * keep paging with the returned cursor.\n */\n more: boolean;\n /**\n * The cursor for the next request. An empty poll returns the request's\n * cursor unchanged.\n */\n cursor: string;\n /** The node, space and prefix that served the page. */\n source: {\n nodeDid: string;\n space: string;\n prefix: string;\n };\n authority: KVChangesAuthority;\n}\n\n/**\n * Response from signed KV read URL creation.\n */\nexport interface KVSignedReadUrlResponse {\n /**\n * Absolute URL suitable for passing to external readers.\n */\n url: string;\n\n /**\n * Opaque URL returned by tinycloud-node, usually relative to the node host.\n */\n relativeUrl: string;\n\n /**\n * Opaque signed KV ticket identifier.\n */\n ticketId: string;\n\n /**\n * Expiry timestamp as returned by tinycloud-node.\n */\n expiresAt: string;\n}\n\n/**\n * KV service action types.\n */\nexport const KVAction = {\n GET: \"tinycloud.kv/get\",\n PUT: \"tinycloud.kv/put\",\n LIST: \"tinycloud.kv/list\",\n DELETE: \"tinycloud.kv/del\",\n HEAD: \"tinycloud.kv/metadata\",\n /** The change feed; never implied by `*` or `tinycloud.kv/*`. */\n SYNC: \"tinycloud.kv/sync\",\n /** Retention attestation; presented through `retentionGrant`, never invoked or implied. */\n RETAIN: \"tinycloud.kv/retain\",\n} as const;\n\nexport type KVActionType = (typeof KVAction)[keyof typeof KVAction];\n","/**\n * KVService - Key-Value storage service implementation.\n *\n * Platform-agnostic KV service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n FetchResponse,\n ServiceHeaders,\n} from \"../types\";\nimport {\n authRequiredError,\n wrapError,\n storageRejectionError,\n parseStorageQuotaBytes,\n parseAuthError,\n parsePermissionHintFromErrorText,\n authUnauthorizedError,\n validatedCapabilityOf,\n isRequestTimeoutError,\n} from \"../errors\";\nimport { IKVService } from \"./IKVService\";\nimport { PrefixedKVService, IPrefixedKVService } from \"./PrefixedKVService\";\nimport {\n DEFAULT_SIGNED_READ_URL_EXPIRY_MS,\n KVServiceConfig,\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVBatchReadResponse,\n KVListOptions,\n KVChange,\n KVChangesOptions,\n KVChangesResponse,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVResponseHeaders,\n KVSignedReadUrlResponse,\n KVAction,\n} from \"./types\";\n\ninterface SignedKvUrlNodeResponse {\n url: string;\n ticketId: string;\n expiresAt: string;\n}\n\ninterface KvBatchNodeItem {\n key: string;\n ok: boolean;\n dataBase64?: string;\n headers?: Record<string, string>;\n error?: { code: string; message: string };\n}\n\ninterface KvBatchNodeResponse {\n results: KvBatchNodeItem[];\n}\n\nconst MAX_KV_BATCH_READ_ITEMS = 100;\n\nfunction isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The node's whole 401 body for a revoked chain: tinycloud-core's\n * `InvocationError::DelegationRevoked` (`delegation-revoked: <cid>`) or\n * `DelegationAncestorRevoked` (`delegation-ancestor-revoked: ancestor=<cid>\n * invoked=<cid>`), rendered as-is (older nodes prefixed `Invalid invocation: `).\n * Anchored: only CIDs follow the error kind, so a key, prefix or path in any\n * other 401 (e.g. `Unauthorized Action: <space>/kv/<prefix> / ...`) never matches.\n */\nconst REVOKED_BODY =\n /^(?:Invalid invocation: )?delegation-(?:(revoked): [A-Za-z0-9]+|(ancestor-revoked): ancestor=[A-Za-z0-9]+ invoked=[A-Za-z0-9]+)$/;\n\nfunction revocationCodeOf(\n body: string\n): typeof ErrorCodes.AUTH_DELEGATION_REVOKED | typeof ErrorCodes.AUTH_DELEGATION_ANCESTOR_REVOKED | undefined {\n const match = REVOKED_BODY.exec(body.trim());\n if (match === null) return undefined;\n return match[1] !== undefined ? ErrorCodes.AUTH_DELEGATION_REVOKED : ErrorCodes.AUTH_DELEGATION_ANCESTOR_REVOKED;\n}\n\nfunction encodeKvBatchPartName(path: string): string {\n return encodeURIComponent(path).replace(/[!'()*]/g, (char) =>\n `%${char.charCodeAt(0).toString(16).toUpperCase()}`\n );\n}\n\n/**\n * KV service implementation.\n *\n * Provides key-value storage operations using TinyCloud's KV API.\n * Uses the Result type pattern for explicit error handling.\n *\n * @example\n * ```typescript\n * // Register with SDK\n * const sdk = new TinyCloud({\n * services: { kv: KVService },\n * serviceConfigs: { kv: { prefix: 'myapp' } },\n * });\n *\n * // Use the service\n * const result = await sdk.kv.get('settings');\n * if (result.ok) {\n * console.log(result.data.data);\n * }\n * ```\n */\nexport class KVService extends BaseService implements IKVService {\n /**\n * Service identifier for registration.\n */\n static readonly serviceName = \"kv\";\n\n /**\n * Service configuration.\n */\n declare protected _config: KVServiceConfig;\n\n /**\n * Create a new KVService instance.\n *\n * @param config - Service configuration\n */\n constructor(config: KVServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n /**\n * Get the service configuration.\n */\n get config(): KVServiceConfig {\n return this._config;\n }\n\n private handleQuotaErrorResponse(\n response: FetchResponse,\n errorText: string,\n key: string\n ): Result<never> | undefined {\n if (response.status !== 402 && response.status !== 413) {\n return undefined;\n }\n // A 413 is about storage only when the node says so. A proxy's own\n // request-size limit (Cloudflare's HTML 413) is not.\n if (response.status === 413 && !parseStorageQuotaBytes(errorText)) {\n return undefined;\n }\n return err(\n storageRejectionError(\n \"kv\",\n response.status,\n { status: response.status, statusText: response.statusText, key },\n errorText\n )\n );\n }\n\n /**\n * Classify a KV 404 by reading the response body once.\n *\n * The server returns 404 both for a genuinely missing key AND for an\n * un-hosted space (body \"Space not found\"). Previously get/head/delete\n * collapsed every 404 to KV_NOT_FOUND before reading the body, so an\n * un-hosted-space read was indistinguishable from a missing key. We now\n * preserve status + the \"Space not found\" body for the un-hosted case (so the\n * CLI/SDK can normalize it to SPACE_NOT_HOSTED, matching put/list/sql), and\n * fall through to KV_NOT_FOUND for a real missing key.\n */\n private async classifyNotFound(\n response: FetchResponse,\n key: string\n ): Promise<Result<never>> {\n const errorText = await response.text();\n if (/space not found/i.test(errorText)) {\n return err(\n serviceError(\n ErrorCodes.KV_NOT_FOUND,\n `KV ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n return err(serviceError(ErrorCodes.KV_NOT_FOUND, `Key not found: ${key}`, \"kv\"));\n }\n\n /**\n * Get the full path with optional prefix.\n *\n * @param key - The key\n * @param prefixOverride - Optional prefix override\n * @returns The full path\n */\n private getFullPath(key: string, prefixOverride?: string): string {\n const prefix = prefixOverride ?? this._config.prefix ?? \"\";\n // A delegated share may scope this service to one exact key. In that\n // case `get(\"\")` means that key itself, not a synthetic child with a\n // trailing slash. This also keeps the service's prefix semantics useful\n // for exact (rather than prefix) capabilities.\n return prefix ? (key === \"\" ? prefix : `${prefix}/${key}`) : key;\n }\n\n /**\n * Get the host URL.\n */\n private get host(): string {\n return this.context.hosts[0];\n }\n\n private withJsonContentType(headers: ServiceHeaders): ServiceHeaders {\n if (Array.isArray(headers)) {\n return [...headers, [\"content-type\", \"application/json\"]];\n }\n\n return {\n ...headers,\n \"content-type\": \"application/json\",\n };\n }\n\n /**\n * Execute an invoke operation.\n *\n * @param path - Resource path\n * @param action - KV action\n * @param body - Optional request body\n * @param signal - Request signal from createRequestSignal()\n * @returns Fetch response\n */\n private async invokeOperation(\n path: string,\n action: string,\n body: Blob | string | undefined,\n signal: AbortSignal,\n extraHeaders?: Readonly<Record<string, string>>\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"kv\",\n path,\n action\n );\n\n const requestHeaders: ServiceHeaders = Array.isArray(headers)\n ? [...headers, ...Object.entries(extraHeaders ?? {})]\n : { ...headers, ...extraHeaders };\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: requestHeaders,\n body,\n signal,\n });\n }\n\n /**\n * Serialize a single put value into a fetch body.\n *\n * Binary values (Blob/ArrayBuffer/typed-array, incl. Node Buffer) are sent as\n * raw bytes (as a Blob) so they round-trip byte-identically — without this a\n * Buffer would be JSON.stringify'd into `{\"type\":\"Buffer\",\"data\":[...]}`.\n * Strings are returned unchanged (preserving prior behavior); other values are\n * JSON-encoded. `contentType` overrides the inferred type for binary values.\n */\n private serializePutValue(\n value: unknown,\n contentType?: string\n ): Blob | string {\n if (value instanceof Blob) {\n if (!contentType || value.type === contentType) {\n return value;\n }\n return new Blob([value], { type: contentType });\n }\n\n if (value instanceof ArrayBuffer) {\n return new Blob([value], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (ArrayBuffer.isView(value)) {\n // Pass a ranged view (honors byteOffset/byteLength so a Node Buffer backed\n // by a shared pool isn't over-read); Blob snapshots the bytes at\n // construction, so no defensive copy is needed.\n const view = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n return new Blob([view], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (typeof value === \"string\") {\n return contentType ? new Blob([value], { type: contentType }) : value;\n }\n\n return JSON.stringify(value);\n }\n\n private serializeBatchPutValue(item: KVBatchPutItem): Blob {\n const contentType = item.contentType;\n\n if (item.value instanceof Blob) {\n if (!contentType || item.value.type === contentType) {\n return item.value;\n }\n return new Blob([item.value], { type: contentType });\n }\n\n if (item.value instanceof ArrayBuffer) {\n return new Blob([item.value], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (ArrayBuffer.isView(item.value)) {\n const value = item.value;\n const bytes = new Uint8Array(value.byteLength);\n bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));\n return new Blob([bytes], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (typeof item.value === \"string\") {\n return new Blob([item.value], {\n type: contentType ?? \"text/plain;charset=UTF-8\",\n });\n }\n\n const json = JSON.stringify(item.value);\n if (json === undefined) {\n throw new Error(`Cannot JSON serialize KV batch value for key \"${item.key}\"`);\n }\n\n return new Blob([json], {\n type: contentType ?? \"application/json\",\n });\n }\n\n private normalizeBatchPutResponse(data: unknown): KVBatchPutResponse | undefined {\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n\n const response = data as Partial<KVBatchPutResponse>;\n if (\n !Array.isArray(response.written) ||\n !response.written.every((key) => typeof key === \"string\") ||\n typeof response.count !== \"number\"\n ) {\n return undefined;\n }\n\n return {\n written: response.written,\n count: response.count,\n };\n }\n\n /**\n * Create KVResponseHeaders from fetch response headers.\n *\n * @param headers - Fetch response headers\n * @returns KVResponseHeaders object\n */\n private createResponseHeaders(headers: {\n get(name: string): string | null;\n }): KVResponseHeaders {\n return {\n etag: headers.get(\"etag\") ?? undefined,\n contentType: headers.get(\"content-type\") ?? undefined,\n lastModified: headers.get(\"last-modified\") ?? undefined,\n contentLength: headers.get(\"content-length\")\n ? parseInt(headers.get(\"content-length\")!, 10)\n : undefined,\n get: (name: string) => headers.get(name),\n };\n }\n\n private createBatchResponseHeaders(\n values: Record<string, string>\n ): KVResponseHeaders {\n const normalized = new Map(\n Object.entries(values).map(([name, value]) => [name.toLowerCase(), value])\n );\n return this.createResponseHeaders({\n get: (name) => normalized.get(name.toLowerCase()) ?? null,\n });\n }\n\n private parseBatchValue<T>(\n dataBase64: string,\n headers: Record<string, string>,\n raw: boolean = false,\n binary: boolean = false\n ): T {\n const encoded = globalThis.atob(dataBase64);\n const bytes = Uint8Array.from(encoded, (character) => character.charCodeAt(0));\n if (binary) return bytes as unknown as T;\n\n const text = new TextDecoder().decode(bytes);\n if (raw) return text as unknown as T;\n const contentType = Object.entries(headers).find(\n ([name]) => name.toLowerCase() === \"content-type\"\n )?.[1];\n return (contentType?.includes(\"application/json\")\n ? JSON.parse(text)\n : text) as T;\n }\n\n private normalizeBatchReadResponse(\n data: unknown,\n paths: string[],\n requireData: boolean\n ): KvBatchNodeResponse | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n const response = data as Partial<KvBatchNodeResponse>;\n if (!Array.isArray(response.results) || response.results.length !== paths.length) {\n return undefined;\n }\n\n for (let index = 0; index < response.results.length; index++) {\n const item = response.results[index];\n if (\n !item ||\n typeof item !== \"object\" ||\n item.key !== paths[index] ||\n typeof item.ok !== \"boolean\"\n ) {\n return undefined;\n }\n if (\n item.ok &&\n (!item.headers ||\n typeof item.headers !== \"object\" ||\n Object.values(item.headers).some((value) => typeof value !== \"string\") ||\n (requireData && typeof item.dataBase64 !== \"string\"))\n ) {\n return undefined;\n }\n if (\n !item.ok &&\n (!item.error ||\n typeof item.error.code !== \"string\" ||\n typeof item.error.message !== \"string\")\n ) {\n return undefined;\n }\n }\n return response as KvBatchNodeResponse;\n }\n\n private async batchRead<T>(\n keys: string[],\n action: typeof KVAction.GET | typeof KVAction.HEAD,\n options?: KVGetOptions | KVHeadOptions\n ): Promise<Result<KVBatchReadResponse<T>>> {\n if (!this.requireAuth()) return err(authRequiredError(\"kv\"));\n if (keys.length === 0) return ok({ results: [], count: 0 });\n if (keys.length > MAX_KV_BATCH_READ_ITEMS) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n `KV batch reads accept at most ${MAX_KV_BATCH_READ_ITEMS} keys`,\n \"kv\"\n ));\n }\n if (keys.length === 1) {\n const key = keys[0]!;\n const result = action === KVAction.GET\n ? await this.get<T>(key, options as KVGetOptions)\n : await this.head(key, options as KVHeadOptions);\n return ok({\n results: [{ key, result: result as Result<KVResponse<T>> }],\n count: 1,\n });\n }\n if (!this.context.invokeAny) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV batch reads require SDK runtime support for multi-resource invocations\",\n \"kv\"\n ));\n }\n\n const getOptions = action === KVAction.GET ? options as KVGetOptions : undefined;\n if (\n getOptions?.maxResponseBytes !== undefined &&\n (!Number.isSafeInteger(getOptions.maxResponseBytes) ||\n getOptions.maxResponseBytes <= 0)\n ) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV maxResponseBytes must be a positive safe integer\",\n \"kv\"\n ));\n }\n\n const paths = keys.map((key) => this.getFullPath(key, options?.prefix));\n if (new Set(paths).size !== paths.length) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV batch read received duplicate keys after prefix resolution\",\n \"kv\"\n ));\n }\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const session = this.context.session!;\n const invocationHeaders = this.context.invokeAny(\n session,\n paths.map((path) => ({\n spaceId: session.spaceId,\n service: \"kv\",\n path,\n action,\n }))\n );\n const limitHeaders: Record<string, string> = {};\n if (getOptions?.maxResponseBytes !== undefined) {\n limitHeaders[\"x-tinycloud-max-response-bytes\"] = String(\n getOptions.maxResponseBytes\n );\n }\n const headers: ServiceHeaders = Array.isArray(invocationHeaders)\n ? [...invocationHeaders, ...Object.entries(limitHeaders)]\n : { ...invocationHeaders, ...limitHeaders };\n const response = await this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n signal: request.signal,\n });\n\n if (!response.ok) {\n const errorText = response.status === 401 || response.status === 403\n ? await this.readAuthorizationText(response)\n : await response.text();\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to batch read ${keys.length} key(s)`,\n response,\n errorText,\n paths,\n action\n );\n }\n if (response.status === 413) {\n return err(serviceError(\n ErrorCodes.KV_RESPONSE_TOO_LARGE,\n \"A KV batch value exceeds the requested response limit\",\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n return err(serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to batch read ${keys.length} key(s): ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n\n const payload = this.normalizeBatchReadResponse(\n await response.json(),\n paths,\n action === KVAction.GET\n );\n if (!payload) {\n return err(serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"KV batch read response did not match the requested keys\",\n \"kv\"\n ));\n }\n\n const results = payload.results.map((item, index) => {\n if (!item.ok) {\n return {\n key: keys[index]!,\n result: err(serviceError(item.error!.code, item.error!.message, \"kv\")),\n };\n }\n const headers = item.headers!;\n const data = action === KVAction.HEAD\n ? undefined\n : this.parseBatchValue<T>(\n item.dataBase64!,\n headers,\n getOptions?.raw,\n getOptions?.binary\n );\n return {\n key: keys[index]!,\n result: ok({\n data: data as T,\n headers: this.createBatchResponseHeaders(headers),\n }),\n };\n });\n return ok({ results, count: results.length });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n }\n\n /**\n * Parse response body based on content type.\n *\n * @param response - Fetch response\n * @param raw - Whether to return raw text\n * @returns Parsed data\n */\n private async parseResponse<T>(\n response: FetchResponse,\n raw: boolean = false,\n binary: boolean = false\n ): Promise<T | undefined> {\n if (!response.ok) {\n return undefined;\n }\n\n if (binary) {\n return new Uint8Array(await response.arrayBuffer()) as unknown as T;\n }\n\n if (raw) {\n return (await response.text()) as unknown as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return (await response.json()) as T;\n } else if (contentType?.startsWith(\"text/\")) {\n return (await response.text()) as unknown as T;\n }\n\n // No content-type header - try to parse as JSON, fall back to text\n const text = await response.text();\n if (!text) {\n return undefined;\n }\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n }\n\n private async createSignedReadUrlError(\n response: FetchResponse,\n key: string,\n path: string\n ): Promise<Result<never>> {\n let errorText = response.statusText;\n try {\n const text = await response.text();\n if (text) {\n errorText = text;\n }\n } catch {\n // Ignore secondary body read failure.\n }\n\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to create signed read URL for key ${JSON.stringify(key)}`,\n response,\n errorText,\n [path],\n KVAction.GET\n );\n }\n\n const code =\n response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR;\n return err(\n serviceError(\n code,\n `Failed to create signed read URL for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n /** A known 401/403 keeps its typed status even if reading its body fails. */\n private async readAuthorizationText(response: FetchResponse): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n }\n\n /**\n * AUTH_UNAUTHORIZED for a 401/403 response. The message keeps the HTTP\n * status and the server text (`<context>: <status> - <text>`, the same\n * shape as every other KV failure) so callers that rethrow only the message\n * still see the status; `meta.status` carries it for typed callers.\n * Server hints must match the requested path/action (whether the node sends\n * a relative path or full resource); metadata uses only the request-derived\n * canonical resource under the authenticated session's space.\n */\n private authorizationFailure(\n context: string,\n response: FetchResponse,\n errorText: string,\n paths: readonly string[],\n expectedAction: string,\n extraMeta: Record<string, unknown> = {}\n ): Result<never> {\n const { resource, action } = parseAuthError(errorText);\n const requestedPath = paths.find((path) =>\n resource === path ||\n resource === `${this.context.session!.spaceId}/kv/${path}`\n );\n const capability = requestedPath !== undefined && action === expectedAction\n ? validatedCapabilityOf({\n service: \"kv\",\n code: ErrorCodes.AUTH_UNAUTHORIZED,\n meta: {\n status: response.status,\n resource: `${this.context.session!.spaceId}/kv/${requestedPath}`,\n requiredAction: action,\n },\n })\n : undefined;\n const detail = errorText.trim().length > 0\n ? errorText\n : response.statusText || \"authorization failed\";\n return err(authUnauthorizedError(\"kv\", `${context}: ${response.status} - ${detail}`, {\n status: response.status,\n ...extraMeta,\n ...capability,\n }));\n }\n\n private normalizeSignedReadUrlResponse(\n data: unknown\n ): KVSignedReadUrlResponse | undefined {\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n\n const response = data as Partial<SignedKvUrlNodeResponse>;\n if (\n typeof response.url !== \"string\" ||\n typeof response.ticketId !== \"string\" ||\n typeof response.expiresAt !== \"string\"\n ) {\n return undefined;\n }\n\n return {\n url: new URL(response.url, this.host).toString(),\n relativeUrl: response.url,\n ticketId: response.ticketId,\n expiresAt: response.expiresAt,\n };\n }\n\n /**\n * Get a value by key.\n */\n async get<T = unknown>(\n key: string,\n options?: KVGetOptions\n ): Promise<Result<KVResponse<T>>> {\n return this.withTelemetry(\"get\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (\n options?.maxResponseBytes !== undefined &&\n (!Number.isSafeInteger(options.maxResponseBytes) || options.maxResponseBytes <= 0)\n ) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV maxResponseBytes must be a positive safe integer\",\n \"kv\"\n ));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.GET,\n undefined,\n request.signal,\n options?.maxResponseBytes === undefined\n ? undefined\n : { \"x-tinycloud-max-response-bytes\": String(options.maxResponseBytes) }\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n const errorText = await this.readAuthorizationText(response);\n const permissionHint = parsePermissionHintFromErrorText(errorText);\n const structuredCapability = permissionHint?.service === \"tinycloud.kv\" &&\n permissionHint.space === this.context.session!.spaceId &&\n permissionHint.path === path\n ? validatedCapabilityOf({\n service: \"kv\",\n code: ErrorCodes.AUTH_UNAUTHORIZED,\n meta: {\n status: response.status,\n resource: `${this.context.session!.spaceId}/kv/${path}`,\n requiredAction: KVAction.GET,\n },\n })\n : undefined;\n return this.authorizationFailure(\n `Failed to get key ${JSON.stringify(key)}`,\n response,\n errorText,\n [path],\n KVAction.GET,\n structuredCapability ? { permissionHint, ...structuredCapability } : {}\n );\n }\n\n if (response.status === 404) {\n return this.classifyNotFound(response, key);\n }\n\n const errorText = await response.text();\n if (response.status === 413) {\n return err(serviceError(\n ErrorCodes.KV_RESPONSE_TOO_LARGE,\n `KV value at key ${JSON.stringify(key)} exceeds the requested response limit`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n const data = await this.parseResponse<T>(\n response,\n options?.raw,\n options?.binary\n );\n return ok({\n data: data as T,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async batchGet<T = unknown>(\n keys: string[],\n options?: KVGetOptions\n ): Promise<Result<KVBatchReadResponse<T>>> {\n return this.withTelemetry(\"batchGet\", String(keys.length), () =>\n this.batchRead<T>(keys, KVAction.GET, options)\n );\n }\n\n /**\n * Store a value at a key.\n */\n async put(\n key: string,\n value: unknown,\n options?: KVPutOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"put\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (options?.ifMatch !== undefined && options.ifNoneMatch !== undefined) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV put cannot combine ifMatch and ifNoneMatch\",\n \"kv\"\n ));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n // Serialize the value. Binary values (Blob/ArrayBuffer/typed-array/Buffer)\n // are sent as raw bytes so they round-trip byte-identically; strings are\n // sent as-is; everything else is JSON. Mirrors serializeBatchPutValue.\n const body = this.serializePutValue(value, options?.contentType);\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.PUT,\n body,\n request.signal,\n {\n ...(options?.ifMatch === undefined ? {} : { \"if-match\": options.ifMatch }),\n ...(options?.ifNoneMatch === undefined ? {} : { \"if-none-match\": options.ifNoneMatch }),\n }\n );\n\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to put key ${JSON.stringify(key)}`,\n response,\n await this.readAuthorizationText(response),\n [path],\n KVAction.PUT\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 412) {\n return err(serviceError(\n ErrorCodes.KV_PRECONDITION_FAILED,\n `KV precondition failed for key ${JSON.stringify(key)}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n\n if (\n response.status === 503 &&\n (options?.ifMatch !== undefined || options?.ifNoneMatch !== undefined)\n ) {\n return err(serviceError(\n ErrorCodes.KV_CONFLICT,\n `Concurrent KV update conflicted for key ${JSON.stringify(key)}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n\n // Check for storage quota errors (402, 413)\n const quotaError = this.handleQuotaErrorResponse(\n response,\n errorText,\n key\n );\n if (quotaError) {\n return quotaError;\n }\n\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Store multiple values in one TinyCloud KV invocation.\n */\n async batchPut(\n items: KVBatchPutItem[],\n options?: KVBatchPutOptions\n ): Promise<Result<KVBatchPutResponse>> {\n return this.withTelemetry(\"batchPut\", String(items.length), async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (items.length === 0) {\n return ok({ written: [], count: 0 });\n }\n\n if (!this.context.invokeAny) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV batchPut requires SDK runtime support for multi-resource invocations\",\n \"kv\"\n )\n );\n }\n\n const session = this.context.session!;\n const paths = items.map((item) => this.getFullPath(item.key, options?.prefix));\n const seen = new Set<string>();\n for (const path of paths) {\n if (seen.has(path)) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n `KV batchPut received duplicate key after prefix resolution: ${path}`,\n \"kv\"\n )\n );\n }\n seen.add(path);\n }\n\n // Conservative: `true` means we handed a fully-constructed request to\n // fetch(). It does NOT prove bytes reached the node — DNS/connect\n // failures and synchronous fetch rejections are included. Proving\n // actual dispatch requires lower-level transport instrumentation (out\n // of scope). The over-approximation is intentional and bounded: it can\n // only cause a reconciliation of at most N idempotent, byte-identical\n // overwrites — never a corrupted or differently-timestamped record.\n let requestMayHaveDispatched = false;\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const body = new FormData();\n for (let index = 0; index < items.length; index++) {\n body.append(\n encodeKvBatchPartName(paths[index]!),\n this.serializeBatchPutValue(items[index]!)\n );\n }\n\n const headers = this.context.invokeAny(\n session,\n paths.map((path) => ({\n spaceId: session.spaceId,\n service: \"kv\",\n path,\n action: KVAction.PUT,\n }))\n );\n\n const url = `${this.host}/invoke`;\n const init = {\n method: \"POST\",\n headers,\n body,\n signal: request.signal,\n };\n\n // Resolve the fetch function to a local BEFORE flipping the flag.\n // `this.context.fetch` is a getter (context.ts:154-156) that can\n // itself throw (assertActive()) — if the flag were set first, that\n // throw would be mislabeled as \"may have dispatched\" even though no\n // request was ever handed to a transport (Sol B2).\n const fetchFn = this.context.fetch;\n requestMayHaveDispatched = true;\n const response = await fetchFn(url, init);\n\n if (!response.ok) {\n let errorText: string;\n try {\n errorText = await response.text();\n } catch (textError) {\n // A response was received — the status is known and\n // authoritative — but its body could not be read. Falling\n // through to the generic catch below would report\n // NETWORK_ERROR + requestMayHaveDispatched: true, which the\n // allow-list treats as ambiguous regardless of status. That\n // would turn a deterministic 4xx (nothing written) into a false\n // ambiguity (Sol B4). Classify by status alone instead; whether\n // this is later reconciled is still governed solely by\n // AMBIGUOUS_WRITE_STATUSES, exactly like the body-readable path.\n //\n // Sol B2 (round 2): preserve the underlying rejection instead of\n // discarding it — a bare `catch {}` here would make a\n // body-read failure silently invisible, which is exactly the\n // debugging trap the no-swallowed-errors rule exists to\n // prevent.\n const cause = textError instanceof Error ? textError : new Error(String(textError));\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to batch put ${items.length} key(s): ${response.status} - <response body could not be read: ${cause.message}>`,\n \"kv\",\n { cause, meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to batch put ${items.length} key(s)`,\n response,\n errorText,\n paths,\n KVAction.PUT\n );\n }\n\n const quotaError = this.handleQuotaErrorResponse(\n response,\n errorText,\n \"batch\"\n );\n if (quotaError) {\n return quotaError;\n }\n\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to batch put ${items.length} key(s): ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n let rawBody: unknown;\n try {\n rawBody = await response.json();\n } catch (jsonError) {\n // A 2xx response whose body isn't valid JSON is precisely the\n // unconfirmed-2xx case — the node answered success but the write\n // set can't be confirmed. Falling through to the generic catch\n // below would carry only `requestMayHaveDispatched`, omitting\n // `responseReceived`/`status`/`outcome`, so this must be classified\n // here with the identical metadata block used by the two sibling\n // unconfirmed branches (Sol B3).\n //\n // Sol B2 (round 2): preserve the underlying rejection instead of\n // discarding it — a bare `catch {}` here would make a\n // JSON-parse failure silently invisible, which is exactly the\n // debugging trap the no-swallowed-errors rule exists to\n // prevent.\n const cause = jsonError instanceof Error ? jsonError : new Error(String(jsonError));\n // The configured timeout can also elapse while the 2xx body is\n // still streaming: report TIMEOUT, with the same unconfirmed meta.\n const timedOut = isRequestTimeoutError(cause);\n return err(\n serviceError(\n timedOut ? ErrorCodes.TIMEOUT : ErrorCodes.NETWORK_ERROR,\n timedOut\n ? `KV batchPut response body did not arrive in time: ${cause.message}`\n : `KV batchPut response was not valid JSON: ${cause.message}`,\n \"kv\",\n {\n cause,\n meta: {\n ...(timedOut ? { timeoutMs: cause.timeoutMs } : {}),\n requestMayHaveDispatched: true,\n responseReceived: true,\n status: response.status,\n outcome: \"batch-unconfirmed\",\n },\n }\n )\n );\n }\n\n const batchResponse = this.normalizeBatchPutResponse(rawBody);\n if (!batchResponse) {\n // The code stays NETWORK_ERROR deliberately: adding a member to\n // ErrorCodes (types.ts:73-115) widens the exported ErrorCode union\n // (:117) and would break consumers with exhaustive switches. The\n // node answered 2xx (the write very likely landed) but the body\n // could not confirm it, so the ambiguity is carried in metadata\n // instead of a dedicated code.\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"KV batchPut response did not include matching written keys and count\",\n \"kv\",\n {\n meta: {\n requestMayHaveDispatched: true,\n responseReceived: true,\n status: response.status,\n outcome: \"batch-unconfirmed\",\n },\n }\n )\n );\n }\n\n // Validate against the exact requested path set, not just internal\n // self-consistency (count === written.length would accept a\n // malformed response that reports the right count for the wrong\n // keys, e.g. a partial write padded to look complete).\n const requestedPaths = new Set(paths);\n const writtenPaths = new Set(batchResponse.written);\n const matchesRequest =\n batchResponse.count === paths.length &&\n batchResponse.written.length === paths.length &&\n writtenPaths.size === paths.length &&\n batchResponse.written.every((key) => requestedPaths.has(key));\n\n if (!matchesRequest) {\n // Same rationale as above: NETWORK_ERROR is kept and the\n // ambiguity is carried in meta rather than a new ErrorCodes member.\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `KV batchPut response did not confirm all ${paths.length} requested key(s) were written`,\n \"kv\",\n {\n meta: {\n requestMayHaveDispatched: true,\n responseReceived: true,\n status: response.status,\n outcome: \"batch-unconfirmed\",\n },\n }\n )\n );\n }\n\n return ok(batchResponse);\n } catch (error) {\n const wrapped = wrapError(\"kv\", error);\n return err({\n ...wrapped,\n meta: { ...wrapped.meta, requestMayHaveDispatched },\n });\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * List keys with optional prefix filtering.\n */\n async list(options?: KVListOptions): Promise<Result<KVListResponse>> {\n return this.withTelemetry(\"list\", options?.prefix, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (\n options?.limit !== undefined &&\n (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 1000)\n ) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV list limit must be an integer from 1 through 1000\",\n \"kv\"\n ));\n }\n\n // Build the path from prefix and optional path\n let listPath = options?.prefix ?? this._config.prefix ?? \"\";\n if (options?.path) {\n listPath = listPath ? `${listPath}/${options.path}` : options.path;\n }\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n listPath,\n KVAction.LIST,\n undefined,\n request.signal,\n options?.limit === undefined && options?.cursor === undefined\n ? undefined\n : {\n ...(options?.limit === undefined ? {} : { \"x-tinycloud-limit\": String(options.limit) }),\n ...(options?.cursor === undefined ? {} : { \"x-tinycloud-cursor\": options.cursor }),\n }\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n \"Failed to list keys\",\n response,\n await this.readAuthorizationText(response),\n [listPath],\n KVAction.LIST\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to list keys: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n let keys = await this.parseResponse<string[]>(response, options?.raw);\n keys = keys ?? [];\n\n // Optionally remove prefix from keys\n if (options?.removePrefix && listPath) {\n const prefixWithSlash = listPath.endsWith(\"/\")\n ? listPath\n : `${listPath}/`;\n keys = keys.map((key) =>\n key.startsWith(prefixWithSlash)\n ? key.slice(prefixWithSlash.length)\n : key\n );\n }\n\n return ok({\n keys,\n ...(response.headers.get(\"x-tinycloud-truncated\") === null\n ? {}\n : { truncated: response.headers.get(\"x-tinycloud-truncated\") === \"true\" }),\n ...(response.headers.get(\"x-tinycloud-next-cursor\") === null\n ? {}\n : { nextCursor: response.headers.get(\"x-tinycloud-next-cursor\") ?? undefined }),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Read one page of the `tinycloud.kv/sync` change feed for a prefix.\n */\n async changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>> {\n return this.withTelemetry(\"changes\", options?.prefix, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n // Plain-JS callers can omit the options; TypeScript requires them.\n if (typeof options?.prefix !== \"string\" || options.prefix.length === 0) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV changes prefix must be a non-empty string\",\n \"kv\"\n ));\n }\n if (\n options.limit !== undefined &&\n (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 1000)\n ) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV changes limit must be an integer from 1 through 1000\",\n \"kv\"\n ));\n }\n\n const headers: Record<string, string> = {};\n if (options.limit !== undefined) headers[\"x-tinycloud-limit\"] = String(options.limit);\n if (options.cursor !== undefined) headers[\"x-tinycloud-cursor\"] = options.cursor;\n if (options.retentionGrant !== undefined) {\n headers[\"x-tinycloud-retention-grant\"] = options.retentionGrant;\n }\n\n const request = this.createRequestSignal(options.signal, options.timeout);\n try {\n const response = await this.invokeOperation(\n options.prefix,\n KVAction.SYNC,\n undefined,\n request.signal,\n headers\n );\n\n if (!response.ok) {\n // Awaited so the timeout and abort listeners stay live while the\n // error body is read; `finally` disposes them only afterwards.\n return await this.changesFailure(response, options.prefix, request.signal);\n }\n\n const text = await response.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = undefined;\n }\n const page = this.normalizeChangesResponse(body);\n if (!page) {\n return err(serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"KV changes response was not a tinycloud.kv/sync page\",\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n return ok(page);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Map a failed `kv/sync` response. 410 and the retention 403 carry\n * `{\"error\":{\"code\",\"reason\"}}`; a revoked grant is a 401 whose whole body\n * is the node's revocation error (see REVOKED_BODY). A body read that\n * fails because the request was cancelled or timed out rethrows, so the\n * caller sees `ABORTED`/`TIMEOUT` rather than a mapped status.\n */\n private async changesFailure(\n response: FetchResponse,\n prefix: string,\n signal: AbortSignal\n ): Promise<Result<never>> {\n if (response.status === 404) {\n return this.classifyNotFound(response, prefix);\n }\n let errorText: string;\n try {\n errorText = await response.text();\n } catch (error) {\n if (signal.aborted) throw error;\n errorText = \"\";\n }\n const meta = { status: response.status, statusText: response.statusText };\n let reason: string | undefined;\n let bodyCode: string | undefined;\n try {\n const body: unknown = JSON.parse(errorText);\n const error = isJsonObject(body) ? body.error : undefined;\n if (isJsonObject(error)) {\n if (typeof error.code === \"string\") bodyCode = error.code;\n if (typeof error.reason === \"string\") reason = error.reason;\n }\n } catch {\n // Plain-text body.\n }\n const context = `Failed to read KV changes for ${JSON.stringify(prefix)}`;\n\n if (response.status === 410) {\n return err(serviceError(\n ErrorCodes.KV_SYNC_RESET_REQUIRED,\n `${context}: the node requires a reset (${reason ?? \"reason not given\"}); discard sync state and restart without a cursor`,\n \"kv\",\n { meta: { ...meta, reason } }\n ));\n }\n if (response.status === 403 && bodyCode === \"RETENTION_GRANT_REFUSED\") {\n return err(serviceError(\n ErrorCodes.KV_RETENTION_GRANT_REFUSED,\n `${context}: the retention grant was refused (${reason ?? \"reason not given\"})`,\n \"kv\",\n { meta: { ...meta, reason } }\n ));\n }\n if (response.status === 401) {\n const revoked = revocationCodeOf(errorText);\n if (revoked !== undefined) {\n return err(serviceError(revoked, `${context}: 401 - ${errorText}`, \"kv\", { meta }));\n }\n }\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(context, response, errorText, [prefix], KVAction.SYNC);\n }\n return err(serviceError(\n response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR,\n `${context}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta }\n ));\n }\n\n private normalizeChangesResponse(data: unknown): KVChangesResponse | undefined {\n if (!isJsonObject(data)) return undefined;\n const { changes, more, cursor, source, authority } = data;\n if (\n !Array.isArray(changes) ||\n typeof more !== \"boolean\" ||\n typeof cursor !== \"string\" ||\n !isJsonObject(source) ||\n typeof source.nodeDid !== \"string\" ||\n typeof source.space !== \"string\" ||\n typeof source.prefix !== \"string\" ||\n !isJsonObject(authority)\n ) {\n return undefined;\n }\n const { notBefore, expiresAt, retainUntil } = authority;\n if (\n (notBefore !== null && typeof notBefore !== \"string\") ||\n (expiresAt !== null && typeof expiresAt !== \"string\") ||\n (retainUntil !== null && typeof retainUntil !== \"string\")\n ) {\n return undefined;\n }\n\n const parsed: KVChange[] = [];\n for (const change of changes) {\n if (!isJsonObject(change) || typeof change.key !== \"string\") return undefined;\n if (change.deleted === true) {\n parsed.push({ key: change.key, deleted: true });\n continue;\n }\n const { metadata } = change;\n if (\n change.deleted !== false ||\n typeof change.etag !== \"string\" ||\n !isJsonObject(metadata) ||\n !Object.values(metadata).every((value) => typeof value === \"string\")\n ) {\n return undefined;\n }\n parsed.push({\n key: change.key,\n deleted: false,\n etag: change.etag,\n metadata: metadata as Record<string, string>,\n });\n }\n\n return {\n changes: parsed,\n more,\n cursor,\n source: { nodeDid: source.nodeDid, space: source.space, prefix: source.prefix },\n authority: { notBefore, expiresAt, retainUntil },\n };\n }\n\n /**\n * Delete a key.\n */\n async delete(\n key: string,\n options?: KVDeleteOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"delete\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.DELETE,\n undefined,\n request.signal,\n options?.ifMatch === undefined\n ? undefined\n : { \"if-match\": options.ifMatch }\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to delete key ${JSON.stringify(key)}`,\n response,\n await this.readAuthorizationText(response),\n [path],\n KVAction.DELETE\n );\n }\n\n if (response.status === 404) {\n return this.classifyNotFound(response, key);\n }\n\n const errorText = await response.text();\n if (response.status === 412) {\n return err(serviceError(\n ErrorCodes.KV_PRECONDITION_FAILED,\n `KV precondition failed for key ${JSON.stringify(key)}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n if (response.status === 503 && options?.ifMatch !== undefined) {\n return err(serviceError(\n ErrorCodes.KV_CONFLICT,\n `Concurrent KV delete conflicted for key ${JSON.stringify(key)}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Get metadata for a key without retrieving the value.\n */\n async head(\n key: string,\n options?: KVHeadOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"head\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.HEAD,\n undefined,\n request.signal\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to get metadata for key ${JSON.stringify(key)}`,\n response,\n await this.readAuthorizationText(response),\n [path],\n KVAction.HEAD\n );\n }\n\n if (response.status === 404) {\n return this.classifyNotFound(response, key);\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async batchHead(\n keys: string[],\n options?: KVHeadOptions\n ): Promise<Result<KVBatchReadResponse<void>>> {\n return this.withTelemetry(\"batchHead\", String(keys.length), () =>\n this.batchRead<void>(keys, KVAction.HEAD, options)\n );\n }\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n */\n async createSignedReadUrl(\n key: string,\n options?: KVCreateSignedReadUrlOptions\n ): Promise<Result<KVSignedReadUrlResponse>> {\n return this.withTelemetry(\"createSignedReadUrl\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"kv\",\n path,\n KVAction.GET\n );\n\n const body: {\n space: string;\n path: string;\n ttl_seconds: number;\n content_hash?: string;\n etag?: string;\n } = {\n space: session.spaceId,\n path,\n ttl_seconds:\n options?.expiresInSeconds ??\n Math.ceil(DEFAULT_SIGNED_READ_URL_EXPIRY_MS / 1000),\n };\n\n if (options?.contentHash !== undefined) {\n body.content_hash = options.contentHash;\n }\n if (options?.etag !== undefined) {\n body.etag = options.etag;\n }\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.context.fetch(`${this.host}/signed/kv`, {\n method: \"POST\",\n headers: this.withJsonContentType(headers),\n body: JSON.stringify(body),\n signal: request.signal,\n });\n\n if (!response.ok) {\n return this.createSignedReadUrlError(response, key, path);\n }\n\n const signedUrl = this.normalizeSignedReadUrlResponse(\n await response.json()\n );\n if (!signedUrl) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"Signed read URL response did not include url, ticketId, and expiresAt\",\n \"kv\"\n )\n );\n }\n\n return ok(signedUrl);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Create a prefix-scoped view of this KV service.\n *\n * Returns a PrefixedKVService that automatically prefixes all\n * key operations with the specified prefix. This enables apps\n * to isolate their data within a shared space.\n *\n * @param prefix - The prefix to apply to all operations\n * @returns A PrefixedKVService scoped to the prefix\n *\n * ## Prefix Conventions\n *\n * | Pattern | Use Case | Example |\n * | -- | -- | -- |\n * | `/app.{domain}/` | App-private data | `/app.photos.xyz/settings.json` |\n * | `/{type}/` | Shared data type | `/photos/vacation.jpg` |\n * | `/.{name}/` | Hidden/system data | `/.cache/thumbnails/` |\n * | `/public/` | Explicitly shareable | `/public/profile.json` |\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // Create prefix-scoped views\n * const myApp = space.kv.withPrefix('/app.myapp.com');\n * const sharedPhotos = space.kv.withPrefix('/photos');\n *\n * // Operations are automatically prefixed\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Actually writes to: /app.myapp.com/settings.json\n *\n * await myApp.get('settings.json');\n * // -> Actually reads from: /app.myapp.com/settings.json\n *\n * await sharedPhotos.list();\n * // -> Lists: /photos/*\n *\n * // Nested prefixes\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\n withPrefix(prefix: string): IPrefixedKVService {\n return new PrefixedKVService(this, prefix);\n }\n}\n","export interface ParsedServiceErrorBody {\n error?: string;\n message?: string;\n code?: string;\n}\n\nexport function parseServiceErrorBody(errorText: string): ParsedServiceErrorBody {\n try {\n return JSON.parse(errorText) as ParsedServiceErrorBody;\n } catch {\n return {};\n }\n}\n\nexport function formatServiceResponseError(\n serviceLabel: string,\n operation: string,\n status: number,\n errorText: string,\n parsed: ParsedServiceErrorBody,\n): string {\n if (parsed.message) {\n return compactMessage(parsed.message);\n }\n\n if (looksLikeHtml(errorText)) {\n if (status === 524 || /524\\s*[:-]/i.test(errorText) || /a timeout occurred/i.test(errorText)) {\n return `${serviceLabel} ${operation} failed: upstream request timed out. Please retry.`;\n }\n return `${serviceLabel} ${operation} failed: upstream service returned an HTML error page (${status}).`;\n }\n\n return `${serviceLabel} ${operation} failed: ${status} - ${compactMessage(errorText)}`;\n}\n\nexport function responseErrorMeta(\n status: number,\n statusText: string,\n errorText: string,\n): Record<string, unknown> {\n const meta: Record<string, unknown> = { status, statusText };\n const snippet = compactMessage(errorText);\n if (snippet) {\n meta.responseSnippet = snippet.slice(0, 300);\n }\n return meta;\n}\n\nfunction looksLikeHtml(text: string): boolean {\n return /<!doctype html/i.test(text) || /<html[\\s>]/i.test(text);\n}\n\nfunction compactMessage(message: string): string {\n const compact = message.replace(/\\s+/g, \" \").trim();\n return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;\n}\n","import type { Result } from \"../types\";\nimport type { SQLService } from \"./SQLService\";\nimport type { ISQLMigrations } from \"./ISQLService\";\nimport type {\n SqlMigrationApplyOptions,\n SqlMigrationApplyResponse,\n} from \"./types\";\n\nexport class SQLMigrations implements ISQLMigrations {\n constructor(\n private readonly service: SQLService,\n private readonly dbName: string,\n ) {}\n\n apply(options: SqlMigrationApplyOptions): Promise<Result<SqlMigrationApplyResponse>> {\n return this.service.applyMigrationsOnDb(this.dbName, options);\n }\n}\n","/**\n * DatabaseHandle - Handle for operations on a specific named database.\n *\n * Delegates all operations to the parent SQLService with the database name.\n */\n\nimport type { Result } from \"../types\";\nimport type { IDatabaseHandle, ISQLMigrations } from \"./ISQLService\";\nimport type { SQLService } from \"./SQLService\";\nimport { SQLMigrations } from \"./SQLMigrations\";\nimport type {\n SqlValue,\n SqlStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n QueryOptions,\n ExecuteOptions,\n BatchOptions,\n} from \"./types\";\n\nexport class DatabaseHandle implements IDatabaseHandle {\n private service: SQLService;\n public readonly name: string;\n public readonly migrations: ISQLMigrations;\n\n constructor(service: SQLService, name: string) {\n this.service = service;\n this.name = name;\n this.migrations = new SQLMigrations(service, name);\n }\n\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.service.queryOnDb<T>(this.name, sql, params, options);\n }\n\n async execute(\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.service.executeOnDb(this.name, sql, params, options);\n }\n\n async batch(\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.service.batchOnDb(this.name, statements, options);\n }\n\n async executeStatement(\n name: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.service.executeStatementOnDb(this.name, name, params, options);\n }\n\n async export(options?: QueryOptions): Promise<Result<Blob>> {\n return this.service.exportDb(this.name, options);\n }\n}\n","/**\n * SQL Service Types\n *\n * Type definitions for the SQL service operations.\n */\n\nimport { SQL } from \"@tinycloud/bootstrap\";\n\n/**\n * Configuration for SQLService.\n */\nexport interface SQLServiceConfig {\n /**\n * Default database name.\n * If not set, operations default to \"default\".\n */\n defaultDatabase?: string;\n\n /**\n * Timeout in milliseconds for each SQL request, including reading the\n * response body. When it elapses the request is aborted and the operation\n * returns an `ErrorCodes.TIMEOUT` error. Unset (the default), `0`, or\n * `Infinity` means no timeout.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for SQL query operations.\n */\nexport interface QueryOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n\n /** Maximum rows the node may return. Nodes without limit support ignore it. */\n maxRows?: number;\n\n /** Maximum serialized result bytes the node may return. */\n maxBytes?: number;\n}\n\n/**\n * Options for SQL execute operations.\n */\nexport interface ExecuteOptions {\n /**\n * Schema initialization statements (CREATE TABLE IF NOT EXISTS ...).\n * Executed before the main statement on first write.\n */\n schema?: string[];\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for SQL batch operations.\n */\nexport interface BatchOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A SQL value: null, number, string, or binary data.\n */\nexport type SqlValue = null | number | string | Uint8Array;\n\n/**\n * A SQL statement with optional parameters.\n */\nexport interface SqlStatement {\n sql: string;\n params?: SqlValue[];\n}\n\n/**\n * Response from SQL query operations.\n */\nexport interface QueryResponse<T = Record<string, unknown>> {\n columns: string[];\n rows: T[][];\n rowCount: number;\n}\n\n/**\n * Response from SQL execute operations.\n */\nexport interface ExecuteResponse {\n changes: number;\n lastInsertRowId: number | null;\n}\n\n/**\n * Response from SQL batch operations.\n */\nexport interface BatchResponse {\n results: ExecuteResponse[];\n}\n\n/**\n * A versioned SQL migration owned by an application or SDK subsystem.\n */\nexport interface SqlMigration {\n /**\n * Stable migration id within the namespace, e.g. \"001_initial\".\n */\n id: string;\n\n /**\n * SQL statements to apply when this migration has not been recorded.\n * Statements should be idempotent where SQLite supports it.\n */\n sql: Array<string | SqlStatement>;\n}\n\n/**\n * Options for applying SQL migrations.\n */\nexport interface SqlMigrationApplyOptions {\n /**\n * Namespace for this migration set, usually an app id or SDK subsystem.\n */\n namespace: string;\n\n /**\n * Ordered migration list.\n */\n migrations: SqlMigration[];\n\n /**\n * Custom abort signal for migration operations.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Result from applying SQL migrations.\n */\nexport interface SqlMigrationApplyResponse {\n database: string;\n namespace: string;\n status: \"already_current\" | \"applied\";\n applied: string[];\n skipped: string[];\n}\n\n/**\n * SQL service action types.\n *\n * URNs derive from the canonical capability registry in `@tinycloud/bootstrap`\n * (TC-112 single source of truth, vendored from tinycloud-node). `insert`,\n * `update`, and `delete` were dropped — zero client refs and never accepted\n * node-side. `select` is a deprecated alias of `read`. `execute`/`export` are\n * request-kind artifacts, not grantable capabilities: the node routes them by\n * request-body kind, so they are absent from the registry but kept here as the\n * invocation ability the client sends today (wire alignment tracked in TC-114).\n */\nexport const SQLAction = {\n READ: SQL.READ,\n WRITE: SQL.WRITE,\n SCHEMA: SQL.SCHEMA,\n ADMIN: SQL.ADMIN,\n SELECT: SQL.SELECT,\n EXECUTE: SQL.EXECUTE,\n EXPORT: SQL.EXPORT,\n ALL: SQL.ALL,\n} as const;\n\nexport type SQLActionType = (typeof SQLAction)[keyof typeof SQLAction];\n","/**\n * SQLService - SQL database service implementation.\n *\n * Platform-agnostic SQL service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n type FetchResponse,\n type ServiceHeaders,\n type ServiceSession,\n} from \"../types\";\nimport {\n authRequiredError,\n wrapError,\n parseAuthError,\n storageRejectionError,\n} from \"../errors\";\nimport {\n formatServiceResponseError,\n parseServiceErrorBody,\n responseErrorMeta,\n} from \"../responseErrors\";\nimport type { ISQLService } from \"./ISQLService\";\nimport type { IDatabaseHandle } from \"./ISQLService\";\nimport { DatabaseHandle } from \"./DatabaseHandle\";\nimport {\n type SQLServiceConfig,\n type QueryOptions,\n type ExecuteOptions,\n type BatchOptions,\n type SqlValue,\n type SqlStatement,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n type SqlMigration,\n type SqlMigrationApplyOptions,\n type SqlMigrationApplyResponse,\n SQLAction,\n} from \"./types\";\n\nconst DDL_TOKENS = new Set([\"alter\", \"create\", \"drop\"]);\nconst MIGRATIONS_TABLE = \"__tinycloud_sql_migrations\";\nconst MIGRATIONS_SCHEMA = `CREATE TABLE IF NOT EXISTS ${MIGRATIONS_TABLE} (\n key TEXT PRIMARY KEY,\n namespace TEXT NOT NULL,\n id TEXT NOT NULL,\n applied_at TEXT NOT NULL,\n statement_count INTEGER NOT NULL\n)`;\nconst MIGRATIONS_META_NAMESPACE = \"tinycloud.sql.migrations\";\nconst MIGRATIONS_META_ID = \"000_metadata\";\n\nexport class SQLService extends BaseService implements ISQLService {\n static readonly serviceName = \"sql\";\n\n declare protected _config: SQLServiceConfig;\n private readonly migrationLocks = new Map<string, Promise<Result<SqlMigrationApplyResponse>>>();\n\n constructor(config: SQLServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): SQLServiceConfig {\n return this._config;\n }\n\n private get defaultDbName(): string {\n return this._config.defaultDatabase ?? \"default\";\n }\n\n private get host(): string {\n return this.context.hosts[0];\n }\n\n /**\n * Get a handle to a named database.\n */\n db(name?: string): IDatabaseHandle {\n return new DatabaseHandle(this, name ?? this.defaultDbName);\n }\n\n /**\n * Shortcut: query the default database.\n */\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.queryOnDb<T>(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: execute on the default database.\n */\n async execute(\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.executeOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: batch on the default database.\n */\n async batch(\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.batchOnDb(this.defaultDbName, statements, options);\n }\n\n async applyMigrationsOnDb(\n dbName: string,\n options: SqlMigrationApplyOptions,\n ): Promise<Result<SqlMigrationApplyResponse>> {\n const validationError = validateMigrationOptions(options);\n if (validationError) {\n return err(serviceError(ErrorCodes.INVALID_INPUT, validationError, \"sql\"));\n }\n\n const lockKey = `${dbName}\\0${options.namespace}`;\n const existing = this.migrationLocks.get(lockKey);\n if (existing) {\n return existing;\n }\n\n const promise = this.applyMigrationsOnDbUnlocked(dbName, options);\n this.migrationLocks.set(lockKey, promise);\n try {\n return await promise;\n } finally {\n this.migrationLocks.delete(lockKey);\n }\n }\n\n // === Internal methods called by DatabaseHandle ===\n\n async queryOnDb<T = Record<string, unknown>>(\n dbName: string,\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.withTelemetry(\"query\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const body: Record<string, unknown> = {\n action: \"query\",\n sql,\n params: serializeSqlValues(params ?? []),\n };\n if (options?.maxRows !== undefined) body.maxRows = options.maxRows;\n if (options?.maxBytes !== undefined) body.maxBytes = options.maxBytes;\n\n const action = this.actionForSql(sql, SQLAction.READ);\n const response = await this.invokeSQL(\n dbName,\n action,\n body,\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"query\", dbName, [action]);\n }\n\n const data = (await response.json()) as QueryResponse<T>;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async executeOnDb(\n dbName: string,\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.withTelemetry(\"execute\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const body: Record<string, unknown> = {\n action: \"execute\",\n sql,\n params: serializeSqlValues(params ?? []),\n };\n if (options?.schema) {\n body.schema = options.schema;\n }\n\n const actions = [\n this.actionForSql(sql, SQLAction.WRITE),\n ...(options?.schema ?? []).map((statement) =>\n this.actionForSql(statement, SQLAction.SCHEMA),\n ),\n ];\n const requestedActions = this.dedupeActions(actions);\n const response = await this.invokeSQL(\n dbName,\n requestedActions,\n body,\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"execute\", dbName, requestedActions);\n }\n\n const data = (await response.json()) as ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async batchOnDb(\n dbName: string,\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.withTelemetry(\"batch\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const requestedActions = this.actionsForSqlBatch(statements);\n const response = await this.invokeSQL(\n dbName,\n requestedActions,\n { action: \"batch\", statements },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"batch\", dbName, requestedActions);\n }\n\n const data = (await response.json()) as BatchResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async executeStatementOnDb(\n dbName: string,\n name: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.withTelemetry(\"executeStatement\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n // TC-114: mint the dispatchable ability, not the literal method name.\n // The node has no `tinycloud.sql/execute` capability — it routes an\n // `execute_statement` request by body kind and classifies write-class\n // from the RESOLVED named statement's SQL\n // (tinycloud-node-server/src/routes/mod.rs:1168-1171). A named statement\n // may mutate, and the SQL parser rejects writes under a read/select\n // ability (tinycloud-core/src/sql/parser.rs:135) while permitting reads\n // under write (write ⊇ read), so `write` is the ability that works for\n // both read-only and mutating statements and is contained in a normal\n // read+write delegation.\n const response = await this.invokeSQL(\n dbName,\n SQLAction.WRITE,\n { action: \"execute_statement\", name, params: params ?? [] },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"executeStatement\", dbName, [SQLAction.WRITE]);\n }\n\n const data = (await response.json()) as\n | QueryResponse\n | ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async exportDb(\n dbName: string,\n options?: QueryOptions\n ): Promise<Result<Blob>> {\n return this.withTelemetry(\"export\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n // TC-114: mint the dispatchable ability, not the literal method name.\n // The node has no `tinycloud.sql/export` capability — it routes an\n // `export` request by body kind and authorizes it as a READ\n // (`SqlRequest::Export` is non-write:\n // tinycloud-node-server/src/routes/mod.rs:1172, see comment :1155).\n const response = await this.invokeSQL(\n dbName,\n SQLAction.READ,\n { action: \"export\" },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"export\", dbName, [SQLAction.READ]);\n }\n\n // FetchResponse doesn't expose blob(), so access it from the\n // underlying response which is a standard fetch Response at runtime\n const resp = response as any;\n if (typeof resp.blob === \"function\") {\n const blob = await resp.blob();\n return ok(blob as Blob);\n }\n // If blob() is not available, return the raw text as a Blob-like\n const text = await response.text();\n return ok(text as unknown as Blob);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n private async applyMigrationsOnDbUnlocked(\n dbName: string,\n options: SqlMigrationApplyOptions,\n ): Promise<Result<SqlMigrationApplyResponse>> {\n return this.withTelemetry(\"migrations.apply\", dbName, async () => {\n // Read before writing: an up-to-date database must open with a single\n // read, because writes fail once the owner's storage is full (402) and\n // read-only sessions cannot write at all.\n const listed = await this.queryOnDb<{ id: string }>(\n dbName,\n `SELECT id FROM ${MIGRATIONS_TABLE} WHERE namespace = ? ORDER BY applied_at, id`,\n [options.namespace],\n { signal: options.signal },\n );\n // A node may answer for a database that was never created with either\n // \"no such table\" or \"database not found\"; both mean nothing is applied.\n const tableMissing =\n !listed.ok &&\n (listed.error.code === ErrorCodes.SQL_DATABASE_NOT_FOUND ||\n isMissingTableError(listed.error.message));\n if (!listed.ok && !tableMissing) return listed;\n\n const appliedIds = new Set(\n (listed.ok ? listed.data.rows : [])\n .map((row) => rowValue(row, 0))\n .filter((id): id is string => typeof id === \"string\"),\n );\n const skipped = options.migrations\n .filter((migration) => appliedIds.has(migration.id))\n .map((migration) => migration.id);\n const pending = options.migrations.filter((migration) => !appliedIds.has(migration.id));\n const applied: string[] = [];\n\n if (pending.length > 0 && tableMissing) {\n const created = await this.ensureMigrationsTable(dbName, options.signal);\n if (!created.ok) return created;\n }\n\n for (const migration of pending) {\n const result = await this.applyOneMigration(dbName, options.namespace, migration, options.signal);\n if (!result.ok) return result;\n applied.push(migration.id);\n }\n\n return ok({\n database: dbName,\n namespace: options.namespace,\n status: applied.length > 0 ? \"applied\" : \"already_current\",\n applied,\n skipped,\n });\n });\n }\n\n private async applyOneMigration(\n dbName: string,\n namespace: string,\n migration: SqlMigration,\n signal?: AbortSignal,\n ): Promise<Result<void>> {\n const statements = [\n ...migration.sql.map((statement) =>\n typeof statement === \"string\" ? { sql: statement } : statement,\n ),\n {\n sql: `INSERT OR REPLACE INTO ${MIGRATIONS_TABLE} (key, namespace, id, applied_at, statement_count) VALUES (?, ?, ?, ?, ?)`,\n params: [\n migrationKey(namespace, migration.id),\n namespace,\n migration.id,\n new Date().toISOString(),\n migration.sql.length,\n ],\n },\n ];\n\n const result = await this.batchOnDb(dbName, statements, { signal });\n if (!result.ok) return result;\n return ok(undefined);\n }\n\n private async ensureMigrationsTable(\n dbName: string,\n signal?: AbortSignal,\n ): Promise<Result<void>> {\n const result = await this.batchOnDb(\n dbName,\n [\n { sql: MIGRATIONS_SCHEMA },\n {\n sql: `INSERT OR REPLACE INTO ${MIGRATIONS_TABLE} (key, namespace, id, applied_at, statement_count) VALUES (?, ?, ?, ?, ?)`,\n params: [\n migrationKey(MIGRATIONS_META_NAMESPACE, MIGRATIONS_META_ID),\n MIGRATIONS_META_NAMESPACE,\n MIGRATIONS_META_ID,\n new Date().toISOString(),\n 1,\n ],\n },\n ],\n { signal },\n );\n if (!result.ok) return result;\n return ok(undefined);\n }\n\n // === Private helpers ===\n\n private async invokeSQL(\n dbName: string,\n actions: string | string[],\n body: Record<string, unknown>,\n signal: AbortSignal\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const actionList = Array.isArray(actions) ? actions : [actions];\n const headers =\n actionList.length === 1\n ? this.context.invoke(session, \"sql\", dbName, actionList[0]!)\n : this.invokeSQLAny(session, dbName, actionList);\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body) as any,\n signal,\n });\n }\n\n private actionForSql(sql: string, fallback: string): string {\n const token = firstSqlToken(sql);\n if (token === \"pragma\") return SQLAction.ADMIN;\n if (token !== undefined && DDL_TOKENS.has(token)) return SQLAction.SCHEMA;\n return fallback;\n }\n\n private actionsForSqlBatch(statements: SqlStatement[]): string[] {\n return this.dedupeActions(\n statements.map((statement) => this.actionForSql(statement.sql, SQLAction.WRITE)),\n );\n }\n\n private dedupeActions(actions: string[]): string[] {\n return [...new Set(actions)];\n }\n\n private invokeSQLAny(\n session: ServiceSession,\n dbName: string,\n actions: string[],\n ): ServiceHeaders {\n if (!this.context.invokeAny) {\n throw new Error(\n `SQL operation requires multiple permissions (${actions.join(\", \")}) but this SDK runtime does not support multi-resource invocations`,\n );\n }\n\n return this.context.invokeAny(\n session,\n actions.map((action) => ({\n spaceId: session.spaceId,\n service: \"sql\",\n path: dbName,\n action,\n })),\n );\n }\n\n private async handleErrorResponse(\n response: FetchResponse,\n operation: string,\n dbName: string,\n requestedActions: readonly string[],\n ): Promise<Result<never>> {\n const errorText = await response.text();\n const meta = responseErrorMeta(response.status, response.statusText, errorText);\n\n // The node answers a write-class request on a full space with 402.\n if (response.status === 402) {\n return err(storageRejectionError(\"sql\", 402, meta, errorText));\n }\n\n const errorBody = parseServiceErrorBody(errorText);\n\n const errorCode = this.mapHttpStatusToErrorCode(\n response.status,\n errorBody.error\n );\n const message = formatServiceResponseError(\n \"SQL\",\n operation,\n response.status,\n errorText,\n errorBody,\n );\n\n if (response.status === 401) {\n const { action } = parseAuthError(errorText);\n if (action && requestedActions.includes(action)) {\n meta.requiredAction = action;\n meta.resource = `${this.context.session!.spaceId}/sql/${dbName}`;\n }\n }\n\n return err(\n serviceError(errorCode, message, \"sql\", { meta })\n );\n }\n\n private mapHttpStatusToErrorCode(\n status: number,\n serverError?: string\n ): string {\n switch (status) {\n case 400:\n return ErrorCodes.SQL_ERROR;\n case 401:\n return ErrorCodes.AUTH_UNAUTHORIZED;\n case 403:\n if (serverError === \"sql_readonly_violation\") {\n return ErrorCodes.SQL_READONLY_VIOLATION;\n }\n return ErrorCodes.SQL_PERMISSION_DENIED;\n case 404:\n return ErrorCodes.SQL_DATABASE_NOT_FOUND;\n case 413:\n return ErrorCodes.SQL_RESPONSE_TOO_LARGE;\n case 429:\n return ErrorCodes.SQL_QUOTA_EXCEEDED;\n default:\n return ErrorCodes.NETWORK_ERROR;\n }\n }\n}\n\nfunction firstSqlToken(sql: string): string | undefined {\n let index = 0;\n\n while (index < sql.length) {\n while (index < sql.length && /\\s/.test(sql[index])) {\n index++;\n }\n\n if (sql.startsWith(\"--\", index)) {\n const newline = sql.indexOf(\"\\n\", index + 2);\n if (newline === -1) {\n return undefined;\n }\n index = newline + 1;\n continue;\n }\n\n if (sql.startsWith(\"/*\", index)) {\n const end = sql.indexOf(\"*/\", index + 2);\n if (end === -1) {\n return undefined;\n }\n index = end + 2;\n continue;\n }\n\n break;\n }\n\n const match = /^[A-Za-z_]+/.exec(sql.slice(index));\n return match?.[0].toLowerCase();\n}\n\nfunction validateMigrationOptions(options: SqlMigrationApplyOptions): string | null {\n if (!options || typeof options !== \"object\") {\n return \"SQL migrations require options\";\n }\n if (!options.namespace || typeof options.namespace !== \"string\") {\n return \"SQL migrations require a non-empty namespace\";\n }\n if (!Array.isArray(options.migrations)) {\n return \"SQL migrations require an ordered migrations array\";\n }\n\n const ids = new Set<string>();\n for (const migration of options.migrations) {\n if (!migration.id || typeof migration.id !== \"string\") {\n return \"SQL migrations require every migration to have a non-empty id\";\n }\n if (ids.has(migration.id)) {\n return `Duplicate SQL migration id: ${migration.id}`;\n }\n ids.add(migration.id);\n\n if (!Array.isArray(migration.sql)) {\n return `SQL migration ${migration.id} requires a sql array`;\n }\n for (const statement of migration.sql) {\n if (typeof statement === \"string\") {\n if (statement.trim() === \"\") {\n return `SQL migration ${migration.id} contains an empty statement`;\n }\n continue;\n }\n if (!statement || typeof statement.sql !== \"string\" || statement.sql.trim() === \"\") {\n return `SQL migration ${migration.id} contains an invalid statement`;\n }\n }\n }\n\n return null;\n}\n\nfunction serializeSqlValues(values: SqlValue[]): Array<null | number | string | number[]> {\n return values.map((value) =>\n value instanceof Uint8Array ? Array.from(value) : value,\n );\n}\n\nfunction isMissingTableError(message: string): boolean {\n return /no such table/i.test(message);\n}\n\nfunction migrationKey(namespace: string, id: string): string {\n return `${encodeURIComponent(namespace)}:${encodeURIComponent(id)}`;\n}\n\nfunction rowValue(row: unknown, index: number): unknown {\n if (Array.isArray(row)) return row[index];\n if (row && typeof row === \"object\") {\n const values = Object.values(row as Record<string, unknown>);\n return values[index];\n }\n return undefined;\n}\n","/**\n * DuckDbDatabaseHandle - Handle for operations on a specific named database.\n *\n * Delegates all operations to the parent DuckDbService with the database name.\n */\n\nimport type { Result } from \"../types\";\nimport type { IDuckDbDatabaseHandle } from \"./IDuckDbService\";\nimport type { DuckDbService } from \"./DuckDbService\";\nimport type {\n DuckDbValue,\n DuckDbStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n SchemaInfo,\n DuckDbQueryOptions,\n DuckDbExecuteOptions,\n DuckDbBatchOptions,\n DuckDbOptions,\n} from \"./types\";\n\nexport class DuckDbDatabaseHandle implements IDuckDbDatabaseHandle {\n private service: DuckDbService;\n public readonly name: string;\n\n constructor(service: DuckDbService, name: string) {\n this.service = service;\n this.name = name;\n }\n\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.service.queryOnDb<T>(this.name, sql, params, options);\n }\n\n async queryArrow(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.service.queryArrowOnDb(this.name, sql, params, options);\n }\n\n async execute(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.service.executeOnDb(this.name, sql, params, options);\n }\n\n async batch(\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.service.batchOnDb(this.name, statements, options);\n }\n\n async executeStatement(\n name: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.service.executeStatementOnDb(this.name, name, params, options);\n }\n\n async describe(options?: DuckDbOptions): Promise<Result<SchemaInfo>> {\n return this.service.describeDb(this.name, options);\n }\n\n async export(options?: DuckDbOptions): Promise<Result<Blob>> {\n return this.service.exportOnDb(this.name, options);\n }\n\n async import(data: Uint8Array, options?: DuckDbOptions): Promise<Result<void>> {\n return this.service.importOnDb(this.name, data, options);\n }\n}\n","/**\n * DuckDB Service Types\n *\n * Type definitions for the DuckDB service operations.\n */\n\nimport { DUCKDB } from \"@tinycloud/bootstrap\";\n\n/**\n * Configuration for DuckDbService.\n */\nexport interface DuckDbServiceConfig {\n /**\n * Default database name.\n * If not set, operations default to \"default\".\n */\n defaultDatabase?: string;\n\n /**\n * Timeout in milliseconds for each DuckDB request, including reading the\n * response body. When it elapses the request is aborted and the operation\n * returns an `ErrorCodes.TIMEOUT` error. Unset (the default), `0`, or\n * `Infinity` means no timeout.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for DuckDB query operations.\n */\nexport interface DuckDbQueryOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB execute operations.\n */\nexport interface DuckDbExecuteOptions {\n /**\n * Schema initialization statements (CREATE TABLE IF NOT EXISTS ...).\n * Executed before the main statement on first write.\n */\n schema?: string[];\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB batch operations.\n */\nexport interface DuckDbBatchOptions {\n /**\n * Whether to run statements in a transaction.\n */\n transactional?: boolean;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB operations that only need an abort signal.\n */\nexport interface DuckDbOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A DuckDB value: null, boolean, number, string, binary, array, or object.\n */\nexport type DuckDbValue =\n | null\n | boolean\n | number\n | string\n | Uint8Array\n | DuckDbValueArray\n | DuckDbValueRecord;\n\n/** Array of DuckDB values (workaround for circular type alias). */\nexport interface DuckDbValueArray extends Array<DuckDbValue> {}\n\n/** Record of DuckDB values (workaround for circular type alias). */\nexport interface DuckDbValueRecord {\n [key: string]: DuckDbValue;\n}\n\n/**\n * A DuckDB statement with optional parameters.\n */\nexport interface DuckDbStatement {\n sql: string;\n params?: DuckDbValue[];\n}\n\n/**\n * Response from DuckDB query operations.\n */\nexport interface QueryResponse<T = Record<string, unknown>> {\n columns: string[];\n rows: T[][];\n rowCount: number;\n}\n\n/**\n * Response from DuckDB execute operations.\n */\nexport interface ExecuteResponse {\n changes: number;\n}\n\n/**\n * Response from DuckDB batch operations.\n */\nexport interface BatchResponse {\n results: ExecuteResponse[];\n}\n\n/**\n * Schema information for a DuckDB database.\n */\nexport interface SchemaInfo {\n tables: TableInfo[];\n views: ViewInfo[];\n}\n\n/**\n * Information about a table.\n */\nexport interface TableInfo {\n name: string;\n columns: ColumnInfo[];\n}\n\n/**\n * Information about a column.\n */\nexport interface ColumnInfo {\n name: string;\n type: string;\n nullable: boolean;\n}\n\n/**\n * Information about a view.\n */\nexport interface ViewInfo {\n name: string;\n sql: string;\n}\n\n/**\n * DuckDB service action types.\n *\n * URNs derive from the canonical capability registry in `@tinycloud/bootstrap`\n * (TC-112 single source of truth).\n */\nexport const DuckDbAction = {\n READ: DUCKDB.READ,\n WRITE: DUCKDB.WRITE,\n ADMIN: DUCKDB.ADMIN,\n DESCRIBE: DUCKDB.DESCRIBE,\n EXPORT: DUCKDB.EXPORT,\n IMPORT: DUCKDB.IMPORT,\n EXECUTE: DUCKDB.EXECUTE,\n ALL: DUCKDB.ALL,\n} as const;\n\nexport type DuckDbActionType = (typeof DuckDbAction)[keyof typeof DuckDbAction];\n","/**\n * DuckDbService - DuckDB database service implementation.\n *\n * Platform-agnostic DuckDB service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n type FetchResponse,\n} from \"../types\";\nimport {\n authRequiredError,\n wrapError,\n parseAuthError,\n storageRejectionError,\n} from \"../errors\";\nimport {\n formatServiceResponseError,\n parseServiceErrorBody,\n responseErrorMeta,\n} from \"../responseErrors\";\nimport type { IDuckDbService, IDuckDbDatabaseHandle } from \"./IDuckDbService\";\nimport { DuckDbDatabaseHandle } from \"./DuckDbDatabaseHandle\";\nimport {\n type DuckDbServiceConfig,\n type DuckDbQueryOptions,\n type DuckDbExecuteOptions,\n type DuckDbBatchOptions,\n type DuckDbOptions,\n type DuckDbValue,\n type DuckDbStatement,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n type SchemaInfo,\n DuckDbAction,\n} from \"./types\";\n\nexport class DuckDbService extends BaseService implements IDuckDbService {\n static readonly serviceName = \"duckdb\";\n\n declare protected _config: DuckDbServiceConfig;\n\n constructor(config: DuckDbServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): DuckDbServiceConfig {\n return this._config;\n }\n\n private get defaultDbName(): string {\n return this._config.defaultDatabase ?? \"default\";\n }\n\n private get host(): string {\n return this.context.hosts[0];\n }\n\n /**\n * Get a handle to a named database.\n */\n db(name?: string): IDuckDbDatabaseHandle {\n return new DuckDbDatabaseHandle(this, name ?? this.defaultDbName);\n }\n\n /**\n * Shortcut: query the default database (JSON format).\n */\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.queryOnDb<T>(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: query the default database (Arrow IPC format).\n */\n async queryArrow(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.queryArrowOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: execute on the default database.\n */\n async execute(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.executeOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: batch on the default database.\n */\n async batch(\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.batchOnDb(this.defaultDbName, statements, options);\n }\n\n // === Internal methods called by DuckDbDatabaseHandle ===\n\n async queryOnDb<T = Record<string, unknown>>(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.withTelemetry<QueryResponse<T>>(\"query\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"query\");\n }\n\n const data = (await response.json()) as QueryResponse<T>;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async queryArrowOnDb(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.withTelemetry<ArrayBuffer>(\"queryArrow\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n request.signal,\n { Accept: \"application/vnd.apache.arrow.stream\" }\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"queryArrow\");\n }\n\n const buffer = await response.arrayBuffer();\n return ok(buffer);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async executeOnDb(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.withTelemetry(\"execute\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const body: Record<string, unknown> = {\n action: \"execute\",\n sql,\n params: params ?? [],\n };\n if (options?.schema) {\n body.schema = options.schema;\n }\n\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n body,\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"execute\");\n }\n\n const data = (await response.json()) as ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async batchOnDb(\n dbName: string,\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.withTelemetry(\"batch\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const body: Record<string, unknown> = {\n action: \"batch\",\n statements,\n };\n if (options?.transactional !== undefined) {\n body.transactional = options.transactional;\n }\n\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n body,\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"batch\");\n }\n\n const data = (await response.json()) as BatchResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async executeStatementOnDb(\n dbName: string,\n name: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.withTelemetry(\"executeStatement\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n // TC-114: mint the dispatchable ability, not the literal method name.\n // The node has no `tinycloud.duckdb/execute` capability — it routes an\n // `executeStatement` request by body kind and classifies write-class\n // from the RESOLVED named statement's SQL\n // (tinycloud-node-server/src/routes/mod.rs:1698-1701). Mirroring the SQL\n // path, `write` is the ability that works for both read-only and\n // mutating named statements and is contained in a normal read+write\n // delegation.\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n { action: \"executeStatement\", name, params: params ?? [] },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"executeStatement\");\n }\n\n const data = (await response.json()) as\n | QueryResponse\n | ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async describeDb(\n dbName: string,\n options?: DuckDbOptions\n ): Promise<Result<SchemaInfo>> {\n return this.withTelemetry(\"describe\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n // TC-114: mint the dispatchable ability, not the literal method name.\n // The node has no `tinycloud.duckdb/describe` capability — it routes a\n // `describe` request by body kind and authorizes it as a READ\n // (`DuckDbRequest::Describe` is non-write:\n // tinycloud-node-server/src/routes/mod.rs:1705, see comment :1680).\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"describe\" },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"describe\");\n }\n\n const data = (await response.json()) as SchemaInfo;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async exportOnDb(\n dbName: string,\n options?: DuckDbOptions\n ): Promise<Result<Blob>> {\n return this.withTelemetry(\"export\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.EXPORT,\n { action: \"export\" },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"export\");\n }\n\n const blob = await response.blob();\n return ok(blob);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async importOnDb(\n dbName: string,\n data: Uint8Array,\n options?: DuckDbOptions\n ): Promise<Result<void>> {\n return this.withTelemetry(\"import\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"duckdb\",\n dbName,\n DuckDbAction.IMPORT\n );\n\n const response = await this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/x-duckdb\",\n },\n body: new Blob([data]),\n signal: request.signal,\n });\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"import\");\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n // === Private helpers ===\n\n private async invokeDuckDb(\n dbName: string,\n action: string,\n body: Record<string, unknown>,\n signal: AbortSignal,\n extraHeaders?: Record<string, string>\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(session, \"duckdb\", dbName, action);\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/json\",\n ...extraHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n }\n\n private async handleErrorResponse(\n response: FetchResponse,\n operation: string\n ): Promise<Result<never>> {\n const errorText = await response.text();\n const meta = responseErrorMeta(response.status, response.statusText, errorText);\n\n // The node answers a write-class request on a full space with 402.\n if (response.status === 402) {\n return err(storageRejectionError(\"duckdb\", 402, meta, errorText));\n }\n\n const errorBody = parseServiceErrorBody(errorText);\n\n const errorCode = this.mapHttpStatusToErrorCode(\n response.status,\n errorBody.error\n );\n const message = formatServiceResponseError(\n \"DuckDB\",\n operation,\n response.status,\n errorText,\n errorBody,\n );\n\n if (response.status === 401) {\n const { resource, action } = parseAuthError(errorText);\n if (action) meta.requiredAction = action;\n if (resource) meta.resource = resource;\n }\n\n return err(\n serviceError(errorCode, message, \"duckdb\", { meta })\n );\n }\n\n private mapHttpStatusToErrorCode(\n status: number,\n serverError?: string\n ): string {\n switch (status) {\n case 400:\n return ErrorCodes.DUCKDB_ERROR;\n case 401:\n return ErrorCodes.AUTH_UNAUTHORIZED;\n case 403:\n if (serverError === \"duckdb_readonly_violation\") {\n return ErrorCodes.DUCKDB_READONLY_VIOLATION;\n }\n return ErrorCodes.DUCKDB_PERMISSION_DENIED;\n case 404:\n return ErrorCodes.DUCKDB_DATABASE_NOT_FOUND;\n case 413:\n return ErrorCodes.DUCKDB_RESPONSE_TOO_LARGE;\n case 429:\n return ErrorCodes.DUCKDB_QUOTA_EXCEEDED;\n default:\n return ErrorCodes.NETWORK_ERROR;\n }\n }\n}\n","import { BaseService } from \"../base/BaseService\";\nimport type { RequestSignal } from \"../base/types\";\nimport type {\n FetchResponse,\n InvokeAnyEntry,\n ServiceError,\n ServiceHeaders,\n ServiceSession,\n Result,\n} from \"../types\";\nimport { ErrorCodes, err, ok, serviceError } from \"../types\";\nimport { authRequiredError, wrapError } from \"../errors\";\nimport type { IHooksService } from \"./IHooksService\";\nimport type {\n HookEvent,\n HookStreamEvent,\n HookSubscription,\n HooksServiceConfig,\n SubscribeOptions,\n HookWebhookListOptions,\n HookWebhookRecord,\n HookWebhookRegistration,\n HookWebhookUnregisterOptions,\n} from \"./types\";\n\ninterface HookSubscriber {\n requested: HookSubscription[];\n /** `subscriptionSignature` of each requested entry, fixed at subscribe time. */\n signatures: string[];\n ttlSeconds?: number;\n queue: AsyncQueue<HookEvent>;\n}\n\n/** The one stream the current subscribers need. */\ninterface StreamPlan {\n /** Session generation + merged subscriptions + TTL; a change supersedes the running phase. */\n key: string;\n subscriptions: HookSubscription[];\n ttlSeconds?: number;\n}\n\ntype StreamPhase = \"mint\" | \"open\" | \"read\";\n\n/** How one attempt ended. Holds only SDK-built values. */\ntype AttemptOutcome =\n | { kind: \"ended\" }\n | { kind: \"stopped\" }\n | { kind: \"refused\"; terminal: boolean; error: ServiceError }\n | { kind: \"failed\"; error: ServiceError };\n\ninterface StreamHealth {\n openedAt: number;\n delivered: boolean;\n}\nclass AsyncQueue<T> implements AsyncIterable<T>, AsyncIterator<T> {\n private readonly values: T[] = [];\n private readonly waiters: Array<{\n resolve: (result: IteratorResult<T>) => void;\n reject: (error: unknown) => void;\n }> = [];\n private closed = false;\n private failure?: unknown;\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return this;\n }\n\n push(value: T): void {\n if (this.closed) {\n return;\n }\n\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter.resolve({ value, done: false });\n return;\n }\n\n this.values.push(value);\n }\n\n close(): void {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n while (this.waiters.length > 0) {\n const waiter = this.waiters.shift();\n waiter?.resolve({ value: undefined as never, done: true });\n }\n }\n\n /**\n * Fail the queue: pending and future `next()` calls reject with `error`,\n * so a `for await` consumer sees the iterator throw.\n */\n fail(error: unknown): void {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n this.failure = error;\n while (this.waiters.length > 0) {\n const waiter = this.waiters.shift();\n waiter?.reject(error);\n }\n }\n\n next(): Promise<IteratorResult<T>> {\n if (this.values.length > 0) {\n const value = this.values.shift()!;\n return Promise.resolve({ value, done: false });\n }\n\n if (this.failure !== undefined) {\n return Promise.reject(this.failure);\n }\n\n if (this.closed) {\n return Promise.resolve({ value: undefined as never, done: true });\n }\n\n return new Promise<IteratorResult<T>>((resolve, reject) => {\n this.waiters.push({ resolve, reject });\n });\n }\n}\n\n/** First shared-stream retry delay: fast enough to ride out a ticket 401. */\nconst HOOK_STREAM_RETRY_BASE_DELAY_MS = 250;\n/** Ceiling for shared-stream retry backoff. */\nconst HOOK_STREAM_RETRY_MAX_DELAY_MS = 30_000;\n/**\n * A stream that stays open at least this long without erroring counts as\n * healthy and resets the backoff streak. A stream that delivers an event\n * resets it immediately.\n */\nconst HOOK_STREAM_HEALTHY_MS = 5_000;\n\nexport class HooksService extends BaseService implements IHooksService {\n static readonly serviceName = \"hooks\";\n\n declare protected _config: HooksServiceConfig;\n private readonly _subscribers: Set<HookSubscriber> = new Set();\n /** True while the one supervisor loop runs. Set only by wake(), cleared only at loop exit. */\n private _supervising = false;\n /** The supervisor's current step, interruptible by wake(). */\n private _phase?: { key: string; interrupt: AbortController };\n /** Bumped on every session change; part of the plan key. */\n private _sessionGeneration = 0;\n\n private _lastContextSignal?: AbortSignal;\n constructor(config: HooksServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): HooksServiceConfig {\n return this._config;\n }\n\n private get host(): string {\n return this._config.host ?? this.context.hosts[0];\n }\n\n async *subscribe(\n subscriptions: HookSubscription[],\n options: SubscribeOptions = {},\n ): AsyncIterable<HookEvent> {\n if (!this.requireAuth()) {\n throw new Error(\"Authentication required for hooks subscription\");\n }\n if (subscriptions.length === 0) {\n throw new Error(\"At least one hook subscription is required\");\n }\n\n const requested = subscriptions.map(normalizeSubscription);\n const subscriber: HookSubscriber = {\n requested,\n signatures: requested.map(subscriptionSignature),\n ttlSeconds: options.ttlSeconds,\n queue: new AsyncQueue<HookEvent>(),\n };\n const leave = (): void => {\n this._subscribers.delete(subscriber);\n subscriber.queue.close();\n this.wake();\n };\n const { signal } = options;\n if (signal?.aborted) {\n return;\n }\n signal?.addEventListener(\"abort\", leave, { once: true });\n this._subscribers.add(subscriber);\n this.wake();\n\n try {\n for await (const event of subscriber.queue) {\n yield event;\n }\n } finally {\n signal?.removeEventListener(\"abort\", leave);\n leave();\n }\n }\n\n async register(\n webhook: HookWebhookRegistration,\n ): Promise<Result<HookWebhookRecord>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n if (typeof webhook.secret !== \"string\" || webhook.secret.trim().length === 0) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n \"Webhook secret is required\",\n \"hooks\",\n { meta: { field: \"secret\" } },\n ),\n );\n }\n\n try {\n const response = await this.context.fetch(`${this.host}/hooks/webhooks`, {\n method: \"POST\",\n headers: {\n ...serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/register\",\n buildScopePath(webhook.service, webhook.pathPrefix),\n ),\n ),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n space: webhook.space,\n service: webhook.service,\n pathPrefix: normalizePathPrefix(webhook.pathPrefix),\n abilities: webhook.abilities ?? [],\n callbackUrl: webhook.callbackUrl,\n secret: webhook.secret,\n }),\n });\n\n if (!response.ok) {\n return err(\n await responseError(\"hooks\", \"failed to register webhook\", response),\n );\n }\n\n const data = normalizeWebhookRecord(await response.json());\n if (!data) {\n return err(\n wrapError(\n \"hooks\",\n new Error(\"Webhook registration response did not include a record\"),\n ),\n );\n }\n\n return ok(data);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n async list(\n options: HookWebhookListOptions = {},\n ): Promise<Result<HookWebhookRecord[]>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n try {\n const query = new URLSearchParams();\n if (options.space) {\n query.set(\"space\", options.space);\n }\n if (options.service) {\n query.set(\"service\", options.service);\n }\n if (options.pathPrefix) {\n const normalizedPrefix = normalizePathPrefix(options.pathPrefix);\n if (normalizedPrefix) {\n query.set(\"prefix\", normalizedPrefix);\n }\n }\n\n const response = await this.context.fetch(\n `${this.host}/hooks/webhooks${query.size > 0 ? `?${query.toString()}` : \"\"}`,\n {\n method: \"GET\",\n headers: serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/list\",\n options.service\n ? buildScopePath(options.service, options.pathPrefix)\n : \"webhooks\",\n ),\n ),\n },\n );\n\n if (!response.ok) {\n return err(\n await responseError(\"hooks\", \"failed to list webhooks\", response),\n );\n }\n\n const payload = await response.json();\n const records = normalizeWebhookRecordList(payload);\n if (!records) {\n return err(\n wrapError(\n \"hooks\",\n new Error(\"Webhook list response did not include records\"),\n ),\n );\n }\n\n return ok(records);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n async unregister(\n id: string,\n options: HookWebhookUnregisterOptions = {},\n ): Promise<Result<void>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n try {\n const response = await this.context.fetch(\n `${this.host}/hooks/webhooks/${encodeURIComponent(id)}`,\n {\n method: \"DELETE\",\n headers: serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/unregister\",\n options.target\n ? buildScopePath(\n options.target.service,\n options.target.pathPrefix,\n )\n : `webhooks/${id}`,\n ),\n ),\n },\n );\n\n if (!response.ok) {\n return err(\n await responseError(\n \"hooks\",\n \"failed to unregister webhook\",\n response,\n ),\n );\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n /**\n * Called after anything that may change what the supervisor should do:\n * subscribe, unsubscribe, session change, sign-out. Interrupts the running\n * step if the plan moved away from it, and starts the supervisor if none\n * runs. Touches only SDK-owned state, so it never throws into callers such\n * as `ServiceContext.setSession`.\n */\n private wake(): void {\n const phase = this._phase;\n if (phase && phase.key !== this.plan()?.key) {\n phase.interrupt.abort();\n }\n if (this._supervising || this._subscribers.size === 0) {\n return;\n }\n this._supervising = true;\n this.supervise().catch(() => this.collapse());\n }\n\n /**\n * The only owner of the shared stream. Each iteration is one attempt\n * (mint → open → drain), then a classification and, unless the attempt was\n * superseded or released its subscribers, a backoff. Every await is a\n * `phase` that wake() can interrupt; an interrupted phase yields\n * `undefined`, so a superseded mint can never act. Outside `attempt` and\n * `pause`, which each own one catch, the loop touches only SDK state.\n */\n private async supervise(): Promise<void> {\n let streak = 0;\n for (;;) {\n const plan = this.plan();\n if (!plan) {\n // Same synchronous turn as the emptiness check: a subscribe() that\n // runs after this line starts a fresh supervisor.\n this._supervising = false;\n return;\n }\n const health: StreamHealth = { openedAt: 0, delivered: false };\n const outcome = await this.phase(plan.key, (signal) =>\n this.attempt(plan, signal, health),\n );\n if (\n health.delivered ||\n (health.openedAt > 0 &&\n performance.now() - health.openedAt >= HOOK_STREAM_HEALTHY_MS)\n ) {\n streak = 0;\n }\n if (!outcome) {\n continue;\n }\n if (this.plan()?.key !== plan.key) {\n continue;\n }\n if (outcome.kind === \"stopped\") {\n this.release();\n continue;\n }\n if (outcome.kind === \"refused\" && outcome.terminal) {\n this.release(outcome.error);\n this.report(outcome.error);\n continue;\n }\n if (outcome.kind !== \"ended\") {\n this.report(outcome.error);\n }\n streak += 1;\n await this.phase(plan.key, (signal) =>\n this.pause(streak, signal),\n );\n }\n }\n\n /**\n * Run one step under an interrupt that wake() fires when the plan key moves\n * on. An interrupted step's result is discarded. The interrupt is also\n * fired when the step returns, which releases whatever it left open: the\n * request signal and its listeners, an unread response body, a timer.\n */\n private async phase<T>(\n key: string,\n step: (signal: AbortSignal) => Promise<T>,\n ): Promise<T | undefined> {\n const interrupt = new AbortController();\n this._phase = { key, interrupt };\n try {\n if (this.plan()?.key !== key) {\n // A wake between two phases found nothing to interrupt.\n interrupt.abort();\n }\n const result = await step(interrupt.signal);\n return interrupt.signal.aborted ? undefined : result;\n } finally {\n this._phase = undefined;\n interrupt.abort();\n }\n }\n\n /**\n * One mint → open → drain. The single catch site for everything the\n * attempt touches that the SDK does not own: context accessors, invoke,\n * fetch, response bodies, the SSE parser. Never rejects.\n */\n private async attempt(\n plan: StreamPlan,\n signal: AbortSignal,\n health: StreamHealth,\n ): Promise<AttemptOutcome> {\n let phase: StreamPhase = \"mint\";\n let request: RequestSignal | undefined;\n const owns = (): boolean =>\n !signal.aborted && !request?.signal.aborted && this.plan()?.key === plan.key;\n try {\n const context = this.context;\n const contextSignal = context.abortSignal;\n this._lastContextSignal = contextSignal;\n if (!context.isAuthenticated || contextSignal?.aborted) {\n return { kind: \"stopped\" };\n }\n request = this.createRequestSignal(signal, 0);\n const host = this.host;\n const minted = await awaitOwned(request!.signal, () =>\n context.fetch(`${host}/hooks/tickets`, {\n method: \"POST\",\n headers: {\n ...serviceHeadersToRecord(this.createInvokeHeaders(plan.subscriptions)),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n subscriptions: plan.subscriptions,\n ttlSeconds: plan.ttlSeconds,\n }),\n signal: request!.signal,\n }),\n );\n if (!owns()) return { kind: \"stopped\" };\n if (!minted.ok) {\n const status = minted.status;\n const error = await awaitOwned(request!.signal, () =>\n responseError(\"hooks\", \"failed to mint hook ticket\", minted),\n );\n if (!owns()) return { kind: \"stopped\" };\n return { kind: \"refused\", terminal: isTerminalMintRefusal(status), error };\n }\n const body: unknown = await awaitOwned(request!.signal, () => minted.json());\n if (!owns()) return { kind: \"stopped\" };\n const ticket =\n body !== null && typeof body === \"object\" && \"ticket\" in body\n ? body.ticket\n : undefined;\n if (typeof ticket !== \"string\" || ticket.length === 0) {\n throw new Error(\"Hook ticket response did not include a ticket\");\n }\n\n phase = \"open\";\n if (!owns()) return { kind: \"stopped\" };\n const stream = await awaitOwned(request!.signal, () =>\n context.fetch(`${host}/hooks/events?ticket=${encodeURIComponent(ticket)}`, {\n method: \"GET\",\n headers: { accept: \"text/event-stream\" },\n signal: request!.signal,\n }),\n );\n if (!owns()) return { kind: \"stopped\" };\n if (!stream.ok) {\n return { kind: \"refused\", terminal: false, error: hookStreamRefusal(stream.status) };\n }\n\n health.openedAt = performance.now();\n const iterator = parseSseStream(stream.body, request.signal)[Symbol.asyncIterator]();\n try {\n for (;;) {\n const next = await awaitOwned(request!.signal, () => iterator.next());\n if (!owns()) return { kind: \"stopped\" };\n if (next.done) break;\n const message = next.value;\n if (!message.data) continue;\n const event = parseHookEvent(message);\n if (!owns()) return { kind: \"stopped\" };\n this.dispatch(event);\n health.delivered = true;\n }\n } finally {\n const closing = iterator.return?.();\n if (closing) void Promise.resolve(closing).then(() => undefined, () => undefined);\n }\n return owns() ? { kind: \"ended\" } : { kind: \"stopped\" };\n } catch (thrown) {\n return request?.signal.aborted || thrown === SUPERSEDED\n ? { kind: \"stopped\" }\n : { kind: \"failed\", error: hookStreamFailure(phase, thrown) };\n }\n }\n\n /**\n * Back off before the next attempt. `config.streamRetry` overrides the\n * delay and the clock; whatever they do, the pause ends by the delay or the\n * interrupt, then yields one timer turn so an instant clock cannot starve\n * due timers or the process.\n */\n private async pause(attempt: number, signal: AbortSignal): Promise<void> {\n try {\n this._lastContextSignal = this.context.abortSignal;\n } catch {\n // A hostile context signal getter cannot prevent the next attempt.\n }\n const contextSignal = this._lastContextSignal;\n const waits: Promise<void>[] = [];\n const aborts: Array<{ promise: Promise<void>; dispose: () => void }> = [];\n try {\n const retry = this._config.streamRetry;\n const delayMs = retry?.delay?.(attempt) ?? hookStreamRetryDelay(attempt);\n waits.push((retry?.wait ?? sleep)(delayMs, attempt, signal));\n } catch {\n waits.push(Promise.resolve());\n }\n aborts.push(abortPromise(signal));\n if (contextSignal) aborts.push(abortPromise(contextSignal));\n try {\n await Promise.race([...waits, ...aborts.map(({ promise }) => promise)]);\n } catch {\n // A rejecting custom clock counts as an elapsed delay.\n } finally {\n for (const abort of aborts) abort.dispose();\n }\n // Use a referenced timer: due timers (including runner timeouts) must run\n // before the supervisor starts another iteration, regardless of immediates.\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n }\n\n /** The stream the current subscribers need, or undefined when none remain. */\n private plan(): StreamPlan | undefined {\n if (this._subscribers.size === 0) {\n return undefined;\n }\n const merged = new Map<string, HookSubscription>();\n let ttlSeconds: number | undefined;\n for (const subscriber of this._subscribers) {\n subscriber.requested.forEach((subscription, index) =>\n merged.set(subscriber.signatures[index], subscription),\n );\n if (typeof subscriber.ttlSeconds === \"number\") {\n ttlSeconds = Math.min(subscriber.ttlSeconds, ttlSeconds ?? Infinity);\n }\n }\n const signatures = [...merged.keys()].sort();\n return {\n key: JSON.stringify([this._sessionGeneration, signatures, ttlSeconds ?? null]),\n subscriptions: signatures.map((signature) => merged.get(signature)!),\n ttlSeconds,\n };\n }\n\n private dispatch(event: HookEvent): void {\n for (const subscriber of this._subscribers) {\n if (matchesAnySubscription(event, subscriber.requested)) {\n subscriber.queue.push(event);\n }\n }\n }\n\n /**\n * Detach every subscriber. With `error`, their iterators throw it after\n * draining buffered events; without, they complete.\n */\n private release(error?: ServiceError): void {\n const subscribers = [...this._subscribers];\n this._subscribers.clear();\n for (const { queue } of subscribers) {\n if (error) {\n queue.fail(error);\n } else {\n queue.close();\n }\n }\n }\n\n private report(error: ServiceError): void {\n if (error.meta && typeof error.meta === \"object\") {\n Object.freeze(error.meta);\n }\n Object.freeze(error);\n try {\n this.emitError(error, \"stream\");\n } catch {\n // Telemetry never steers the stream.\n }\n }\n\n /**\n * Unreachable by construction. If the loop ever rejects anyway, fail its\n * subscribers visibly instead of stranding them or crashing the process.\n */\n private collapse(): void {\n this._supervising = false;\n this._phase?.interrupt.abort();\n this._phase = undefined;\n const error = serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"hook stream supervisor stopped unexpectedly\",\n \"hooks\",\n );\n this.report(error);\n this.release(error);\n }\n\n override onSessionChange(session: ServiceSession | null): void {\n super.onSessionChange(session);\n // New credentials supersede the running attempt: it re-mints, or stops\n // if the session is gone.\n this._sessionGeneration += 1;\n this.wake();\n }\n\n override onSignOut(): void {\n super.onSignOut();\n // Sign-out ends every subscription; the empty plan stops the supervisor.\n this.release();\n this.wake();\n }\n\n private createHookHeaders(action: string, path: string): ServiceHeaders {\n return this.context.invoke(this.session, \"hooks\", path, action);\n }\n\n private createInvokeHeaders(\n subscriptions: HookSubscription[],\n ): ServiceHeaders {\n const entries: InvokeAnyEntry[] = subscriptions.map((subscription) => ({\n spaceId: subscription.space,\n service: \"hooks\",\n path: subscription.pathPrefix\n ? `${subscription.service}/${subscription.pathPrefix}`\n : subscription.service,\n action: \"tinycloud.hooks/subscribe\",\n }));\n\n if (this.context.invokeAny) {\n return this.context.invokeAny(this.session, entries);\n }\n\n if (entries.length === 1) {\n const entry = entries[0];\n return this.context.invoke(\n this.session,\n entry.service,\n entry.path,\n entry.action,\n );\n }\n\n throw new Error(\n \"This SDK runtime does not support multi-scope hook invocations\",\n );\n }\n}\n\nfunction buildScopePath(\n service: HookSubscription[\"service\"],\n pathPrefix?: string,\n): string {\n const normalized = normalizePathPrefix(pathPrefix);\n return normalized ? `${service}/${normalized}` : service;\n}\n\n/**\n * Exponential backoff for the shared hook stream, with equal jitter: each\n * delay lands in [cap/2, cap] where cap doubles per attempt, so retries are\n * never zero-delay and never exceed HOOK_STREAM_RETRY_MAX_DELAY_MS.\n */\nfunction hookStreamRetryDelay(attempt: number): number {\n const cap = Math.min(\n HOOK_STREAM_RETRY_BASE_DELAY_MS * 2 ** Math.max(0, attempt - 1),\n HOOK_STREAM_RETRY_MAX_DELAY_MS,\n );\n return cap / 2 + Math.random() * (cap / 2);\n}\n\n/**\n * A 4xx mint refusal is the node saying no for this session and scope set,\n * so retrying cannot help. 408 and 429 mean \"not now\".\n */\nfunction isTerminalMintRefusal(status: unknown): boolean {\n return (\n typeof status === \"number\" &&\n status >= 400 &&\n status < 500 &&\n status !== 408 &&\n status !== 429\n );\n}\n\nconst SUPERSEDED = Symbol(\"hooks attempt superseded\");\n\n/** Race one foreign operation against the attempt interrupt and observe late results. */\nasync function awaitOwned<T>(\n signal: AbortSignal,\n operation: Promise<T> | (() => Promise<T>),\n): Promise<T> {\n if (signal.aborted) {\n if (typeof operation !== \"function\") {\n void operation.then(cancelLateResponse, () => undefined);\n }\n throw SUPERSEDED;\n }\n const promise = typeof operation === \"function\" ? operation() : operation;\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n const cleanup = (): void => signal.removeEventListener(\"abort\", onAbort);\n const onAbort = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(SUPERSEDED);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n promise.then(\n (value) => {\n if (settled) {\n cancelLateResponse(value);\n return;\n }\n settled = true;\n cleanup();\n resolve(value);\n },\n (error: unknown) => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n },\n );\n });\n}\n\nfunction cancelLateResponse(value: unknown): void {\n if (!(value instanceof Response) || !value.body) return;\n try {\n const cancellation = value.body.cancel();\n void cancellation.then(() => undefined, () => undefined);\n } catch {\n // A late body is best-effort cleanup.\n }\n}\n\n/*\n * Stream errors are built from an allow-list, never copied. Past the mint the\n * ticket rides in the request URL, and a mint request carries invocation\n * headers, so any foreign error text (message, cause, stack, meta, a\n * response body) may hold a bearer credential. These builders keep the\n * phase, a numeric HTTP status, and the thrown value's `name`/`code` when\n * they are plain identifiers. Nothing else crosses into telemetry.\n */\nfunction hookStreamRefusal(status: unknown): ServiceError {\n const code = typeof status === \"number\" ? status : undefined;\n return serviceError(\n ErrorCodes.NETWORK_ERROR,\n `hook stream open refused: ${code ?? \"unknown status\"}`,\n \"hooks\",\n { meta: { phase: \"open\", status: code } },\n );\n}\n\nconst STREAM_ERROR_NAMES = new Set([\n \"Error\",\n \"TypeError\",\n \"AbortError\",\n \"TimeoutError\",\n \"SyntaxError\",\n \"RangeError\",\n \"NetworkError\",\n]);\n\nfunction hookStreamFailure(phase: StreamPhase, thrown: unknown): ServiceError {\n const candidateName = readProperty(thrown, \"name\");\n const name =\n typeof candidateName === \"string\" && STREAM_ERROR_NAMES.has(candidateName)\n ? candidateName\n : \"Error\";\n const code =\n identifier(readProperty(thrown, \"code\")) ??\n identifier(readProperty(readProperty(thrown, \"cause\"), \"code\"));\n return serviceError(\n ErrorCodes.NETWORK_ERROR,\n `hook stream ${phase} failed: ${name}${code ? ` (${code})` : \"\"}`,\n \"hooks\",\n { meta: { phase, errorName: name, ...(code ? { errorCode: code } : {}) } },\n );\n}\n\nconst STREAM_ERROR_CODES = new Set([\n \"ECONNREFUSED\", \"ECONNRESET\", \"ECONNABORTED\", \"ETIMEDOUT\", \"EPIPE\",\n \"ENOTFOUND\", \"EAI_AGAIN\", \"EHOSTUNREACH\", \"ENETUNREACH\", \"ENETDOWN\",\n \"EADDRNOTAVAIL\", \"UND_ERR_SOCKET\", \"UND_ERR_CONNECT_TIMEOUT\",\n \"UND_ERR_HEADERS_TIMEOUT\", \"UND_ERR_BODY_TIMEOUT\", \"UND_ERR_CLOSED\",\n \"UND_ERR_ABORTED\", \"UND_ERR_RESPONSE_STATUS_CODE\",\n \"ERR_TLS_CERT_ALTNAME_INVALID\", \"CERT_HAS_EXPIRED\",\n \"DEPTH_ZERO_SELF_SIGNED_CERT\", \"UNABLE_TO_VERIFY_LEAF_SIGNATURE\",\n \"SELF_SIGNED_CERT_IN_CHAIN\", \"ERR_SSL_WRONG_VERSION_NUMBER\",\n]);\n\nfunction identifier(value: unknown): string | undefined {\n return typeof value === \"string\" && STREAM_ERROR_CODES.has(value)\n ? value\n : undefined;\n}\n\n/** Read one property off a value the SDK does not own; a throwing getter or proxy trap reads as absent. */\nfunction readProperty(value: unknown, key: string): unknown {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) {\n return undefined;\n }\n try {\n return Reflect.get(value, key);\n } catch {\n return undefined;\n }\n}\n\n/** The default retry clock: abortable and unref'd, so a parked backoff never keeps the process alive. */\nfunction sleep(delayMs: number, _attempt: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const finish = (): void => {\n clearTimeout(timer);\n signal.removeEventListener(\"abort\", stop);\n resolve();\n };\n const timer = setTimeout(finish, delayMs);\n timer.unref?.();\n const stop = (): void => finish();\n if (signal.aborted) {\n finish();\n } else {\n signal.addEventListener(\"abort\", stop, { once: true });\n }\n });\n}\n\nfunction abortPromise(signal: AbortSignal): {\n promise: Promise<void>;\n dispose: () => void;\n} {\n let resolve!: () => void;\n const promise = new Promise<void>((done) => {\n resolve = done;\n });\n const onAbort = (): void => resolve();\n if (signal.aborted) {\n resolve();\n } else {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n return {\n promise,\n dispose: () => signal.removeEventListener(\"abort\", onAbort),\n };\n}\n\nfunction normalizeSubscription(\n subscription: HookSubscription,\n): HookSubscription {\n return {\n ...subscription,\n pathPrefix: normalizePathPrefix(subscription.pathPrefix),\n abilities: subscription.abilities ? [...subscription.abilities] : [],\n };\n}\n\nfunction subscriptionSignature(subscription: HookSubscription): string {\n return JSON.stringify({\n space: subscription.space,\n service: subscription.service,\n pathPrefix: subscription.pathPrefix ?? \"\",\n abilities: [...(subscription.abilities ?? [])].sort(),\n });\n}\n\nfunction matchesAnySubscription(\n event: HookEvent,\n subscriptions: HookSubscription[],\n): boolean {\n return subscriptions.some((subscription) =>\n matchesSubscription(event, subscription),\n );\n}\n\nfunction matchesSubscription(\n event: HookEvent,\n subscription: HookSubscription,\n): boolean {\n if (event.space !== subscription.space) {\n return false;\n }\n if (event.service !== subscription.service) {\n return false;\n }\n if (subscription.pathPrefix) {\n const prefix = subscription.pathPrefix.endsWith(\"/\")\n ? subscription.pathPrefix\n : `${subscription.pathPrefix}/`;\n if (\n event.path &&\n event.path !== subscription.pathPrefix &&\n !event.path.startsWith(prefix)\n ) {\n return false;\n }\n }\n const abilities = subscription.abilities ?? [];\n if (abilities.length > 0 && !abilities.includes(event.ability)) {\n return false;\n }\n return true;\n}\n\nfunction normalizePathPrefix(pathPrefix?: string): string | undefined {\n if (!pathPrefix) {\n return undefined;\n }\n const trimmed = pathPrefix.replace(/^\\/+|\\/+$/g, \"\");\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction serviceHeadersToRecord(\n headers: ServiceHeaders,\n): Record<string, string> {\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers);\n }\n return { ...headers };\n}\n\nasync function responseError(\n service: string,\n message: string,\n response: FetchResponse,\n): Promise<ReturnType<typeof wrapError>> {\n let detail = response.statusText;\n try {\n const text = await response.text();\n if (text) {\n detail = text;\n }\n } catch {\n // Ignore secondary body read failure.\n }\n const error = wrapError(\n service,\n new Error(`${message}: ${response.status} ${detail}`),\n );\n // Typed status so callers never have to read it back out of the message.\n return {\n ...error,\n meta: { ...error.meta, status: response.status, statusText: response.statusText },\n };\n}\n\nasync function* parseSseStream(\n body: unknown,\n signal?: AbortSignal,\n): AsyncIterable<HookStreamEvent> {\n if (!body) {\n throw new Error(\"Hook stream response does not expose a readable body\");\n }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n for await (const chunk of readBodyChunks(body, signal)) {\n buffer += decoder.decode(chunk, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n\n let separatorIndex = buffer.indexOf(\"\\n\\n\");\n while (separatorIndex >= 0) {\n const rawEvent = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + 2);\n const parsed = parseSseEvent(rawEvent);\n if (parsed) {\n yield parsed;\n }\n separatorIndex = buffer.indexOf(\"\\n\\n\");\n }\n }\n\n buffer += decoder.decode();\n const trailing = parseSseEvent(buffer.trim());\n if (trailing) {\n yield trailing;\n }\n}\n\nasync function* readBodyChunks(\n body: unknown,\n signal?: AbortSignal,\n): AsyncIterable<Uint8Array> {\n const asyncIterable = body as AsyncIterable<Uint8Array>;\n if (typeof asyncIterable?.[Symbol.asyncIterator] === \"function\") {\n const iterator = asyncIterable[Symbol.asyncIterator]();\n const cancel = (): void => {\n try {\n const closing = iterator.return?.();\n if (closing) void Promise.resolve(closing).then(() => undefined, () => undefined);\n } catch {\n // Cancellation must not mask the stream result.\n }\n };\n signal?.addEventListener(\"abort\", cancel, { once: true });\n try {\n while (!signal?.aborted) {\n const next = await iterator.next();\n if (next.done) break;\n yield next.value;\n }\n } finally {\n signal?.removeEventListener(\"abort\", cancel);\n cancel();\n }\n return;\n }\n const stream = body as {\n getReader?: () => {\n read: () => Promise<{ done: boolean; value?: Uint8Array }>;\n releaseLock?: () => void;\n cancel?: () => Promise<void>;\n };\n };\n\n if (typeof stream.getReader !== \"function\") {\n throw new Error(\"Unsupported hook stream body type\");\n }\n\n const reader = stream.getReader();\n const cancelReader = (): void => {\n try {\n const cancellation = reader.cancel?.();\n if (cancellation) void cancellation.then(() => undefined, () => undefined);\n } catch {\n // Cancellation must not mask the stream result.\n }\n };\n signal?.addEventListener(\"abort\", cancelReader, { once: true });\n try {\n while (!signal?.aborted) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) yield value;\n }\n } finally {\n signal?.removeEventListener(\"abort\", cancelReader);\n cancelReader();\n reader.releaseLock?.();\n }\n}\n\nfunction parseSseEvent(rawEvent: string): HookStreamEvent | null {\n if (!rawEvent) {\n return null;\n }\n\n let event = \"message\";\n let id: string | undefined;\n const dataLines: string[] = [];\n\n for (const line of rawEvent.split(\"\\n\")) {\n if (!line || line.startsWith(\":\")) {\n continue;\n }\n const [field, ...rest] = line.split(\":\");\n const value = rest.join(\":\").replace(/^ /, \"\");\n switch (field) {\n case \"event\":\n event = value;\n break;\n case \"id\":\n id = value;\n break;\n case \"data\":\n dataLines.push(value);\n break;\n default:\n break;\n }\n }\n\n if (dataLines.length === 0) {\n return null;\n }\n\n return {\n event,\n id,\n data: dataLines.join(\"\\n\"),\n };\n}\n\nfunction parseHookEvent(message: HookStreamEvent): HookEvent {\n const parsed = JSON.parse(message.data) as Partial<HookEvent>;\n return {\n type: \"write\",\n id: parsed.id ?? message.id ?? \"\",\n space: parsed.space ?? \"\",\n service: parsed.service ?? \"\",\n ability: parsed.ability ?? \"\",\n path: parsed.path,\n actor: parsed.actor ?? \"\",\n epoch: parsed.epoch ?? \"\",\n eventIndex: parsed.eventIndex ?? 0,\n timestamp: parsed.timestamp ?? \"\",\n };\n}\n\nfunction normalizeWebhookRecord(data: unknown): HookWebhookRecord | null {\n if (!data || typeof data !== \"object\") {\n return null;\n }\n\n const record = isRecordContainer(data);\n const candidate =\n pickWebhookRecord(record) ??\n normalizeWebhookRecord(record.webhook) ??\n normalizeWebhookRecord(record.hook) ??\n normalizeWebhookRecord(record.subscription) ??\n normalizeWebhookRecord(record.data);\n return candidate ?? null;\n}\n\nfunction normalizeWebhookRecordList(data: unknown): HookWebhookRecord[] | null {\n if (Array.isArray(data)) {\n const records = data\n .map((entry) => normalizeWebhookRecord(entry))\n .filter((entry): entry is HookWebhookRecord => entry !== null);\n return records;\n }\n\n if (!data || typeof data !== \"object\") {\n return null;\n }\n\n const record = isRecordContainer(data);\n const nested =\n maybeRecordArray(record.webhooks) ??\n maybeRecordArray(record.subscriptions) ??\n maybeRecordArray(record.hooks) ??\n maybeRecordArray(record.data);\n if (nested) {\n return nested;\n }\n\n const single = pickWebhookRecord(record);\n return single ? [single] : null;\n}\n\nfunction maybeRecordArray(value: unknown): HookWebhookRecord[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n\n const records = value\n .map((entry) => normalizeWebhookRecord(entry))\n .filter((entry): entry is HookWebhookRecord => entry !== null);\n return records;\n}\n\nfunction pickWebhookRecord(\n value: Record<string, unknown>,\n): HookWebhookRecord | null {\n const id = stringField(value, \"id\");\n const space = stringField(value, \"space\") ?? stringField(value, \"spaceId\");\n const service = stringField(value, \"service\");\n const callbackUrl =\n stringField(value, \"callbackUrl\") ?? stringField(value, \"callback_url\");\n if (!id || !space || !service || !callbackUrl) {\n return null;\n }\n\n return {\n id,\n space,\n service: service as HookWebhookRecord[\"service\"],\n pathPrefix:\n optionalStringField(value, \"pathPrefix\") ??\n optionalStringField(value, \"path_prefix\"),\n abilities:\n stringArrayField(value, \"abilities\") ??\n parsedStringArrayField(value, \"abilitiesJson\") ??\n parsedStringArrayField(value, \"abilities_json\"),\n callbackUrl,\n active: booleanField(value, \"active\") ?? true,\n createdAt:\n stringField(value, \"createdAt\") ??\n stringField(value, \"created_at\") ??\n new Date().toISOString(),\n subscriberDid:\n optionalStringField(value, \"subscriberDid\") ??\n optionalStringField(value, \"subscriber_did\"),\n };\n}\n\nfunction isRecordContainer(value: object): Record<string, unknown> {\n return value as Record<string, unknown>;\n}\n\nfunction stringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n const field = value[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction optionalStringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n return stringField(value, key);\n}\n\nfunction booleanField(\n value: Record<string, unknown>,\n key: string,\n): boolean | undefined {\n const field = value[key];\n return typeof field === \"boolean\" ? field : undefined;\n}\n\nfunction stringArrayField(\n value: Record<string, unknown>,\n key: string,\n): string[] | undefined {\n const field = value[key];\n if (!Array.isArray(field)) {\n return undefined;\n }\n const strings = field.filter(\n (item): item is string => typeof item === \"string\",\n );\n return strings.length === field.length ? strings : undefined;\n}\n\nfunction parsedStringArrayField(\n value: Record<string, unknown>,\n key: string,\n): string[] | undefined {\n const field = value[key];\n if (typeof field !== \"string\") {\n return undefined;\n }\n\n try {\n const parsed = JSON.parse(field) as unknown;\n if (!Array.isArray(parsed)) {\n return undefined;\n }\n const strings = parsed.filter(\n (item): item is string => typeof item === \"string\",\n );\n return strings.length === parsed.length ? strings : undefined;\n } catch {\n return undefined;\n }\n}\n","import type { StorageQuotaInfo } from \"../types\";\n\nexport interface QuotaConfig {\n /** Called when a storage quota error is detected (402/413) */\n onUpgradeRequired?: (info: StorageQuotaInfo) => void;\n}\n\nexport interface QuotaStatus {\n /** Storage limit in bytes for this space */\n limitBytes: number;\n /** Storage used in bytes for this space */\n usedBytes?: number;\n /** Remaining storage in bytes */\n remainingBytes?: number;\n}\n\nexport class TinyCloudQuota {\n private config: QuotaConfig;\n private quotaUrl: string | null = null;\n\n constructor(config: QuotaConfig = {}) {\n this.config = config;\n }\n\n /** Set the quota URL discovered from the /info endpoint */\n setQuotaUrl(url: string | null): void {\n this.quotaUrl = url;\n }\n\n /** Whether a quota service is available */\n get available(): boolean {\n return this.quotaUrl !== null;\n }\n\n /** Query quota status for a space from the quota URL */\n async getQuota(spaceId: string): Promise<QuotaStatus | null> {\n if (!this.quotaUrl) return null;\n\n const resp = await fetch(\n `${this.quotaUrl}/api/quota/${encodeURIComponent(spaceId)}`\n );\n if (!resp.ok) return null;\n\n const data = (await resp.json()) as { storage_limit_bytes?: number };\n return {\n limitBytes: data.storage_limit_bytes ?? 0,\n };\n }\n\n /** Trigger the upgrade callback when a quota error is encountered */\n handleQuotaError(info: StorageQuotaInfo): void {\n this.config.onUpgradeRequired?.(info);\n }\n}\n","/**\n * Data Vault Service Types\n *\n * Type definitions for the Data Vault (encrypted KV) service operations.\n */\n\nimport type {\n DecryptCapabilityProof,\n IEncryptionService,\n} from \"../encryption\";\nimport type { PermissionHint } from \"../types\";\n\nexport interface VaultNetworkEncryptionConfig {\n /** Default encryption network used for inline vault envelopes. */\n networkId: string;\n /** TinyCloud encryption module used for local encrypt and node-mediated decrypt. */\n service: IEncryptionService;\n /** Proof material presented to the encryption module for decrypt requests. */\n decryptCapabilityProof?:\n | DecryptCapabilityProof\n | (() => DecryptCapabilityProof | Promise<DecryptCapabilityProof>);\n}\n\n/**\n * Configuration for DataVaultService.\n */\nexport interface DataVaultConfig {\n /** Space ID for encrypted data storage */\n spaceId: string;\n /** Key rotation policy */\n keyRotation?: \"per-write\" | \"per-key\"; // default: \"per-write\"\n /** Network-envelope encryption mode. When set, vault.unlock/key grants are not used. */\n encryption?: VaultNetworkEncryptionConfig;\n}\n\n/**\n * Options for vault put operations.\n */\nexport interface VaultPutOptions {\n /** Custom metadata tags appended to the envelope */\n metadata?: Record<string, string>;\n /** Content type hint for deserialization (default: auto-detect) */\n contentType?: string;\n /** Custom serializer (default: JSON.stringify for objects) */\n serialize?: (value: unknown) => Uint8Array;\n}\n\n/**\n * Options for vault get operations.\n */\nexport interface VaultGetOptions<T = unknown> {\n /** Custom deserializer (default: JSON.parse if content-type is JSON) */\n deserialize?: (data: Uint8Array) => T;\n /** Return raw decrypted bytes without deserialization */\n raw?: boolean;\n /** Delegated KV service for reading from the grantor's space (used by getShared) */\n kv?: { get<V>(key: string, options?: { raw?: boolean }): Promise<{ ok: boolean; data?: { data: V }; error?: { message: string } }> };\n}\n\n/**\n * Options for vault list operations.\n */\nexport interface VaultListOptions {\n /** Prefix filter for key names */\n prefix?: string;\n /** Remove prefix from returned keys */\n removePrefix?: boolean;\n /** Maximum number of keys to return. */\n limit?: number;\n /** Opaque cursor returned by a prior bounded page. */\n cursor?: string;\n}\n\nexport interface VaultListPage {\n keys: string[];\n truncated: boolean;\n nextCursor?: string;\n}\n\n/**\n * Options for vault grant (sharing) operations.\n */\nexport interface VaultGrantOptions {\n /** Additional metadata on the grant */\n metadata?: Record<string, string>;\n}\n\n/**\n * A decrypted vault entry returned by get operations.\n *\n * @template T - Type of the decrypted value\n */\nexport interface VaultEntry<T> {\n /** Decrypted value */\n value: T;\n /** Envelope metadata */\n metadata: Record<string, string>;\n /** Key ID used for encryption */\n keyId: string;\n}\n\n/**\n * Safe classification for a network-encrypted vault read.\n *\n * Failure variants intentionally contain no node response, encrypted envelope,\n * plaintext, or key material. Consumers that need to distinguish an authorized\n * absence from a failed read should use this instead of {@link IDataVaultService.get}.\n */\nexport type VaultNetworkReadResult<T> =\n | { status: \"ok\"; entry: VaultEntry<T> }\n | { status: \"not_found\" }\n | { status: \"node_unreachable\" }\n | { status: \"permission_required\"; hint: PermissionHint }\n | { status: \"read_failed\" }\n | { status: \"corrupt_envelope\" }\n | { status: \"decrypt_failed\" }\n | { status: \"invalid_payload\" };\n\n/**\n * Structured error codes for vault operations.\n */\n/**\n * Input types for creating vault errors (service field added automatically).\n */\nexport type VaultErrorInput =\n | { code: \"DECRYPTION_FAILED\"; message?: string; cause?: Error }\n | { code: \"KEY_NOT_FOUND\"; key: string; message?: string }\n | { code: \"INTEGRITY_ERROR\"; message?: string; cause?: Error }\n | { code: \"GRANT_NOT_FOUND\"; grantor: string; key: string; message?: string }\n | { code: \"VAULT_LOCKED\"; message?: string }\n | { code: \"PUBLIC_KEY_NOT_FOUND\"; did: string; message?: string }\n | { code: \"STORAGE_ERROR\"; cause: Error; message?: string }\n | {\n code: \"STORAGE_QUOTA_EXCEEDED\" | \"STORAGE_LIMIT_REACHED\";\n message: string;\n meta?: Record<string, unknown>;\n };\n\n/**\n * Vault error with service field (compatible with ServiceError).\n */\nexport type VaultError = VaultErrorInput & { service: \"vault\"; message: string };\n\n\n/** KV actions the vault needs on the public space for key publishing. */\nexport const VaultPublicSpaceKVActions = [\n \"tinycloud.kv/get\",\n \"tinycloud.kv/put\",\n \"tinycloud.kv/metadata\",\n] as const;\n\n/** Version-keyed signing message configuration for vault key derivation. */\nexport const VaultVersionConfig = {\n \"1\": {\n masterMessage: (spaceId: string) => `tinycloud-vault-master-v1:${spaceId}`,\n identityMessage: \"tinycloud-encryption-identity-v1\",\n },\n} as const;\n\nexport const CURRENT_VAULT_VERSION = \"1\" as const;\n\n/** Metadata header keys used in vault envelopes */\nexport const VaultHeaders = {\n VERSION: \"x-vault-version\",\n CIPHER: \"x-vault-cipher\",\n KEY_ID: \"x-vault-key-id\",\n CONTENT_TYPE: \"x-vault-content-type\",\n KDF: \"x-vault-kdf\",\n KEY_ROTATION: \"x-vault-key-rotation\",\n GRANT_VERSION: \"x-vault-grant-version\",\n GRANTOR: \"x-vault-grantor\",\n} as const;\n","/**\n * Caches vault signatures in IndexedDB, encrypted with a\n * non-extractable CryptoKey. Browser-only — no-ops in Node.\n */\n\n// Minimal type declarations for browser APIs used below.\n// The sdk-services tsconfig targets ES2020 without DOM lib;\n// these declarations let the file compile while the runtime\n// guards (isBrowser()) ensure we never call them in Node.\ndeclare const indexedDB: {\n open(name: string, version?: number): IDBOpenDBRequest;\n};\ninterface IDBOpenDBRequest {\n result: IDBDatabase;\n error: DOMException | null;\n onupgradeneeded: ((this: IDBOpenDBRequest) => void) | null;\n onsuccess: ((this: IDBOpenDBRequest) => void) | null;\n onerror: ((this: IDBOpenDBRequest) => void) | null;\n}\ninterface IDBDatabase {\n objectStoreNames: { contains(name: string): boolean };\n createObjectStore(name: string): void;\n transaction(storeNames: string | string[], mode?: string): IDBTransaction;\n}\ninterface IDBTransaction {\n objectStore(name: string): IDBObjectStore;\n}\ninterface IDBObjectStore {\n get(key: string): IDBRequest;\n put(value: unknown, key: string): IDBRequest;\n delete(key: string): IDBRequest;\n getAllKeys(): IDBRequest;\n}\ninterface IDBRequest<T = unknown> {\n result: T;\n error: DOMException | null;\n onsuccess: ((this: IDBRequest<T>) => void) | null;\n onerror: ((this: IDBRequest<T>) => void) | null;\n}\ntype IDBValidKey = string | number | Date | ArrayBuffer | Uint8Array | IDBValidKey[];\n\nconst DB_NAME = \"tinycloud-vault-cache\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"signatures\";\nconst WRAP_KEY_ID = \"__wrap_key__\";\n\n/** Check whether we're in a browser with IndexedDB + SubtleCrypto support. */\nfunction isBrowser(): boolean {\n try {\n return (\n typeof indexedDB !== \"undefined\" &&\n typeof crypto !== \"undefined\" &&\n typeof crypto.subtle !== \"undefined\"\n );\n } catch {\n return false;\n }\n}\n\n/** Open (or create) the IndexedDB database. */\nfunction openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n}\n\n/** Generic IDB get helper. */\nfunction idbGet<T>(db: IDBDatabase, key: string): Promise<T | undefined> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.get(key);\n req.onsuccess = () => resolve(req.result as T | undefined);\n req.onerror = () => reject(req.error);\n });\n}\n\n/** Generic IDB put helper. */\nfunction idbPut(db: IDBDatabase, key: string, value: unknown): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.put(value, key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n\n/** Generic IDB delete helper. */\nfunction idbDelete(db: IDBDatabase, key: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.delete(key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n\n/** List all keys in the store. */\nfunction idbKeys(db: IDBDatabase): Promise<string[]> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.getAllKeys();\n req.onsuccess = () =>\n resolve((req.result as IDBValidKey[]).filter((k) => typeof k === \"string\") as string[]);\n req.onerror = () => reject(req.error);\n });\n}\n\ninterface EncryptedEntry {\n iv: Uint8Array;\n ciphertext: Uint8Array;\n}\n\n/**\n * Get or create the non-extractable AES-GCM wrapping key.\n * The key is stored directly in IndexedDB (structured-clone preserves CryptoKey).\n */\nasync function getWrapKey(db: IDBDatabase): Promise<CryptoKey> {\n const existing = await idbGet<CryptoKey>(db, WRAP_KEY_ID);\n if (existing) return existing;\n\n const key = await crypto.subtle.generateKey(\n { name: \"AES-GCM\", length: 256 },\n false, // non-extractable\n [\"encrypt\", \"decrypt\"]\n );\n await idbPut(db, WRAP_KEY_ID, key);\n return key;\n}\n\n/** Encrypt signature bytes with the wrap key. */\nasync function encryptSig(\n wrapKey: CryptoKey,\n sigBytes: Uint8Array\n): Promise<EncryptedEntry> {\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const ciphertext = new Uint8Array(\n await crypto.subtle.encrypt({ name: \"AES-GCM\", iv }, wrapKey, sigBytes)\n );\n return { iv, ciphertext };\n}\n\n/** Decrypt an encrypted entry back to signature bytes. */\nasync function decryptSig(\n wrapKey: CryptoKey,\n entry: EncryptedEntry\n): Promise<Uint8Array> {\n const plaintext = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: entry.iv },\n wrapKey,\n entry.ciphertext\n );\n return new Uint8Array(plaintext);\n}\n\n/** Cache key for a given spaceId. */\nfunction cacheKey(spaceId: string): string {\n return `sig:${spaceId}`;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Load a cached signature for the given spaceId.\n * Returns null on cache miss or in non-browser environments.\n */\nexport async function loadCachedSignature(\n spaceId: string\n): Promise<Uint8Array | null> {\n if (!isBrowser()) return null;\n try {\n const db = await openDB();\n const entry = await idbGet<EncryptedEntry>(db, cacheKey(spaceId));\n if (!entry) return null;\n const wrapKey = await getWrapKey(db);\n return await decryptSig(wrapKey, entry);\n } catch {\n return null;\n }\n}\n\n/**\n * Cache a signature for the given spaceId.\n * No-ops in non-browser environments.\n */\nexport async function cacheSignature(\n spaceId: string,\n sigBytes: Uint8Array\n): Promise<void> {\n if (!isBrowser()) return;\n try {\n const db = await openDB();\n const wrapKey = await getWrapKey(db);\n const encrypted = await encryptSig(wrapKey, sigBytes);\n await idbPut(db, cacheKey(spaceId), encrypted);\n } catch {\n // Best-effort — swallow errors\n }\n}\n\n/**\n * Clear cached signature(s).\n * If spaceId is provided, clears only that entry; otherwise clears all.\n */\nexport async function clearSignatureCache(\n spaceId?: string\n): Promise<void> {\n if (!isBrowser()) return;\n try {\n const db = await openDB();\n if (spaceId) {\n await idbDelete(db, cacheKey(spaceId));\n } else {\n // Clear all sig entries but keep the wrap key\n const keys = await idbKeys(db);\n for (const k of keys) {\n if (k.startsWith(\"sig:\")) {\n await idbDelete(db, k);\n }\n }\n }\n } catch {\n // Best-effort\n }\n}\n","/**\n * DataVaultService - Encrypted key-value storage service implementation.\n *\n * Platform-agnostic encrypted KV service that wraps KVService internally.\n * Uses dependency injection via VaultCrypto for WASM crypto operations\n * and DataVaultServiceConfig for platform dependencies.\n *\n * Architecture:\n * - Extends BaseService (not KVService)\n * - Wraps two KV instances: dataKV (prefix \"vault/\") and keyKV (prefix \"keys/\")\n * - Master key and encryption identity live in memory only (cleared on lock)\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n IServiceContext,\n ServiceSession,\n} from \"../types\";\nimport { parsePermissionHint, wrapError } from \"../errors\";\nimport type { IKVService } from \"../kv/IKVService\";\nimport type { KVService } from \"../kv/KVService\";\nimport type {\n DecryptCapabilityProof,\n InlineEncryptedEnvelope,\n} from \"../encryption\";\nimport type { IDataVaultService } from \"./IDataVaultService\";\nimport {\n DataVaultConfig,\n VaultPutOptions,\n VaultGetOptions,\n VaultListOptions,\n VaultGrantOptions,\n VaultEntry,\n VaultNetworkReadResult,\n VaultError,\n VaultErrorInput,\n VaultHeaders,\n VaultVersionConfig,\n CURRENT_VAULT_VERSION,\n VaultListPage,\n} from \"./types\";\nimport {\n loadCachedSignature,\n cacheSignature,\n clearSignatureCache,\n} from \"./SignatureCache\";\n\n// =============================================================================\n// Crypto Interface\n// =============================================================================\n\n/**\n * Crypto operations interface - implementations provided by WASM bindings.\n * Passed via DataVaultServiceConfig to keep the service platform-agnostic.\n */\nexport interface VaultCrypto {\n encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array;\n decrypt(key: Uint8Array, blob: Uint8Array): Uint8Array;\n deriveKey(\n signature: Uint8Array,\n salt: Uint8Array,\n info: Uint8Array\n ): Uint8Array;\n x25519FromSeed(\n seed: Uint8Array\n ): { publicKey: Uint8Array; privateKey: Uint8Array };\n x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n randomBytes(length: number): Uint8Array;\n sha256(data: Uint8Array): Uint8Array;\n}\n\n// =============================================================================\n// Extended Config\n// =============================================================================\n\n/**\n * Extended config used internally by DataVaultService.\n * Includes crypto operations and TinyCloud instance references.\n */\ninterface DataVaultServiceConfig extends DataVaultConfig {\n [key: string]: unknown;\n /** Crypto operations (WASM bindings) */\n crypto: VaultCrypto;\n /** TinyCloud instance for space/kv/delegation operations */\n tc: {\n kv: IKVService;\n ensurePublicSpace(): Promise<Result<void>>;\n publicKV: IKVService;\n readPublicSpace<T>(\n host: string,\n spaceId: string,\n key: string\n ): Promise<Result<T>>;\n makePublicSpaceId(address: string, chainId: number): string;\n did: string;\n address: string;\n chainId: number;\n hosts: string[];\n };\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/** Convert a caught value to an Error. WASM throws plain objects, not Error instances. */\nfunction toError(error: unknown): Error {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null) {\n return new Error(JSON.stringify(error));\n }\n return new Error(String(error));\n}\n\nfunction toBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nfunction fromBytes(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nfunction hexEncode(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((acc, arr) => acc + arr.length, 0);\n const result = new Uint8Array(total);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\nfunction base64Encode(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nfunction base64Decode(str: string): Uint8Array {\n const binary = atob(str);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nfunction unwrapKVData<T = unknown>(value: unknown): T {\n if (value !== null && typeof value === \"object\" && \"data\" in value) {\n return (value as { data: T }).data;\n }\n return value as T;\n}\n\nfunction hasHttpResponse(error: { meta?: Record<string, unknown> }): boolean {\n return typeof error.meta?.status === \"number\";\n}\n\nfunction isUnlockSigner(\n signer: unknown\n): signer is { signMessage(message: string): Promise<string> } {\n return (\n typeof signer === \"object\" &&\n signer !== null &&\n typeof (signer as { signMessage?: unknown }).signMessage === \"function\"\n );\n}\n\nfunction defaultVaultMessage(input: VaultErrorInput): string {\n switch (input.code) {\n case \"DECRYPTION_FAILED\": return input.message ?? \"Decryption failed\";\n case \"KEY_NOT_FOUND\": return input.message ?? `Key not found: ${input.key}`;\n case \"INTEGRITY_ERROR\": return input.message ?? \"Integrity check failed\";\n case \"GRANT_NOT_FOUND\": return input.message ?? `Grant not found: ${input.grantor} / ${input.key}`;\n case \"VAULT_LOCKED\": return input.message ?? \"Vault is locked\";\n case \"PUBLIC_KEY_NOT_FOUND\": return input.message ?? `Public key not found for ${input.did}`;\n case \"STORAGE_ERROR\": return input.message ?? input.cause.message;\n case \"STORAGE_QUOTA_EXCEEDED\":\n case \"STORAGE_LIMIT_REACHED\":\n return input.message;\n }\n}\n\nfunction vaultError(input: VaultErrorInput): Result<never, VaultError> {\n const error: VaultError = {\n ...input,\n service: \"vault\",\n message: defaultVaultMessage(input),\n };\n return { ok: false, error };\n}\n\n/**\n * Wrap a failed KV write. A storage rejection keeps its code, message and\n * byte counts so callers can tell \"storage full\" from other failures.\n */\nfunction kvWriteError(\n context: string,\n error: { code: string; message: string; meta?: Record<string, unknown> }\n): Result<never, VaultError> {\n if (\n error.code === ErrorCodes.STORAGE_QUOTA_EXCEEDED ||\n error.code === ErrorCodes.STORAGE_LIMIT_REACHED\n ) {\n return vaultError({ code: error.code, message: error.message, meta: error.meta });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(`${context}: ${error.message}`),\n });\n}\n\n// =============================================================================\n// DataVaultService\n// =============================================================================\n\n/**\n * Data Vault service implementation.\n *\n * Provides encrypted key-value storage with client-side encryption,\n * key management, and sharing via X25519 grants.\n *\n * @example\n * ```typescript\n * // Unlock the vault\n * await vault.unlock(signer);\n *\n * // Store encrypted data\n * await vault.put('secret/notes', { content: 'Hello' });\n *\n * // Retrieve and decrypt\n * const entry = await vault.get<{ content: string }>('secret/notes');\n * if (entry.ok) {\n * console.log(entry.data.value.content); // 'Hello'\n * }\n *\n * // Share with another user\n * await vault.grant('secret/notes', recipientDID);\n * ```\n */\nexport class DataVaultService extends BaseService implements IDataVaultService {\n /**\n * Service identifier for registration.\n */\n static readonly serviceName = \"vault\";\n\n /**\n * Service configuration.\n */\n declare protected _config: DataVaultServiceConfig;\n\n private masterKey: Uint8Array | null = null;\n private encryptionIdentity: {\n publicKey: Uint8Array;\n privateKey: Uint8Array;\n } | null = null;\n private _isUnlocked = false;\n private vaultConfig: DataVaultServiceConfig;\n private unlockInFlight: Promise<Result<void, VaultError>> | null = null;\n\n /**\n * Create a new DataVaultService instance.\n *\n * @param config - Service configuration including crypto and tc references\n */\n constructor(config: DataVaultServiceConfig) {\n super();\n this.vaultConfig = config;\n this._config = config;\n }\n\n /**\n * Get the service configuration.\n */\n get config(): DataVaultServiceConfig {\n return this._config;\n }\n\n /**\n * Whether the vault is currently unlocked.\n */\n get isUnlocked(): boolean {\n return this.usesNetworkEncryption || this._isUnlocked;\n }\n\n /**\n * The vault's public encryption key (X25519).\n * Throws if vault is locked.\n */\n get publicKey(): Uint8Array {\n if (this.usesNetworkEncryption) {\n throw new Error(\"Network-encrypted vaults do not expose a local public key\");\n }\n if (!this.encryptionIdentity) {\n throw new Error(\"Vault is locked\");\n }\n return this.encryptionIdentity.publicKey;\n }\n\n /**\n * Convenience accessor for crypto operations.\n */\n private get crypto(): VaultCrypto {\n return this.vaultConfig.crypto;\n }\n\n /**\n * Convenience accessor for TinyCloud instance.\n */\n private get tc() {\n return this.vaultConfig.tc;\n }\n\n private get networkEncryption() {\n return this.vaultConfig.encryption;\n }\n\n private get usesNetworkEncryption(): boolean {\n return this.networkEncryption !== undefined;\n }\n\n /**\n * Get the host URL.\n */\n private get host(): string {\n return this.tc.hosts[0];\n }\n\n private async decryptCapabilityProof(): Promise<DecryptCapabilityProof> {\n const proof = this.networkEncryption?.decryptCapabilityProof;\n if (typeof proof === \"function\") {\n return await proof();\n }\n return proof ?? { proofs: [] };\n }\n\n private serializeValue(\n value: unknown,\n options?: VaultPutOptions,\n ): { plaintext: Uint8Array; contentType: string } {\n let plaintext: Uint8Array;\n if (value instanceof Uint8Array) {\n plaintext = value;\n } else if (options?.serialize) {\n plaintext = options.serialize(value);\n } else if (typeof value === \"string\") {\n plaintext = toBytes(value);\n } else {\n plaintext = toBytes(JSON.stringify(value));\n }\n\n const contentType =\n options?.contentType ??\n (value instanceof Uint8Array ? \"application/octet-stream\" : \"application/json\");\n return { plaintext, contentType };\n }\n\n private deserializeValue<T>(\n plaintext: Uint8Array,\n contentType: string,\n options?: VaultGetOptions<T>,\n ): T {\n if (options?.raw) {\n return plaintext as unknown as T;\n }\n if (options?.deserialize) {\n return options.deserialize(plaintext);\n }\n if (contentType === \"application/json\") {\n return JSON.parse(fromBytes(plaintext)) as T;\n }\n return plaintext as unknown as T;\n }\n\n // =========================================================================\n // Phase 1: Core Operations\n // =========================================================================\n\n /**\n * Unlock the vault. Derives keys from two wallet signatures:\n * 1. Master signature (per-space) — used to derive the master encryption key\n * 2. Identity signature (per-address) — used to derive X25519 encryption identity\n *\n * If the identity public key already exists in the public space, the identity\n * signature is skipped entirely (no wallet popup). The identity private key is\n * only needed for sharing operations.\n *\n * @param signer - Object with signMessage method. Optional when cached\n * signatures exist (browser only).\n */\n async unlock(\n signer?: { signMessage(message: string): Promise<string> } | unknown\n ): Promise<Result<void, VaultError>> {\n if (this.usesNetworkEncryption) {\n this._isUnlocked = true;\n return { ok: true, data: undefined };\n }\n\n const unlockSigner = isUnlockSigner(signer) ? signer : undefined;\n if (\n this._isUnlocked &&\n this.masterKey &&\n (this.encryptionIdentity || !unlockSigner)\n ) {\n return { ok: true, data: undefined };\n }\n\n if (this.unlockInFlight) {\n return this.unlockInFlight;\n }\n\n this.unlockInFlight = this.withTelemetry(\"unlock\", undefined, async () => {\n const spaceId = this.vaultConfig.spaceId;\n const versionConfig = VaultVersionConfig[CURRENT_VAULT_VERSION];\n const masterCacheKey = `vault-master:${spaceId}`;\n const identityCacheKey = `vault-identity:${this.tc.address}`;\n\n try {\n // -----------------------------------------------------------------\n // Step 1: Master signature → master key\n // -----------------------------------------------------------------\n if (!this.masterKey) {\n let masterSigBytes = await loadCachedSignature(masterCacheKey);\n\n if (!masterSigBytes) {\n if (!unlockSigner) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Signer is required when no cached master signature exists\",\n });\n }\n const sig = await unlockSigner.signMessage(\n versionConfig.masterMessage(spaceId)\n );\n masterSigBytes = toBytes(sig);\n await cacheSignature(masterCacheKey, masterSigBytes);\n }\n\n // Derive master key: deriveKey(sigBytes, sha256(spaceId), \"vault-master\")\n this.masterKey = this.crypto.deriveKey(\n masterSigBytes,\n this.crypto.sha256(toBytes(spaceId)),\n toBytes(\"vault-master\")\n );\n }\n\n // -----------------------------------------------------------------\n // Step 2: Identity — check public space first, then sign if needed\n // -----------------------------------------------------------------\n const publicSpaceId = this.tc.makePublicSpaceId(this.tc.address, this.tc.chainId);\n\n // Check public space for existing vault pubkey\n let existingPubKey: string | null = null;\n try {\n const existing = await this.tc.readPublicSpace<string>(\n this.host, publicSpaceId, \".well-known/vault-pubkey\"\n );\n if (existing.ok && existing.data) {\n existingPubKey = existing.data as string;\n }\n } catch {\n // Read failed — treat as missing\n }\n\n if (existingPubKey) {\n // Public key exists — trust it, skip identity signing entirely\n this.encryptionIdentity = {\n publicKey: base64Decode(existingPubKey),\n privateKey: new Uint8Array(0), // private key not available without signing\n };\n } else {\n // Public key missing — need identity signature to derive keypair\n let identitySigBytes = await loadCachedSignature(identityCacheKey);\n\n if (!identitySigBytes) {\n if (!unlockSigner) {\n // No signer available — skip identity derivation.\n // Vault still works for get/put (only needs master key).\n this.encryptionIdentity = null;\n this._isUnlocked = true;\n return ok(undefined);\n }\n const sig = await unlockSigner.signMessage(\n versionConfig.identityMessage\n );\n identitySigBytes = toBytes(sig);\n await cacheSignature(identityCacheKey, identitySigBytes);\n }\n\n // Derive X25519 keypair from identity signature\n const seed = this.crypto.deriveKey(\n identitySigBytes,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"encryption-identity\")\n );\n this.encryptionIdentity = this.crypto.x25519FromSeed(seed);\n\n // Publish public key to public space\n try {\n const pubKeyB64 = base64Encode(this.encryptionIdentity.publicKey);\n await this.tc.ensurePublicSpace();\n await this.tc.publicKV.put(\".well-known/vault-pubkey\", pubKeyB64);\n await this.tc.publicKV.put(\".well-known/vault-version\", CURRENT_VAULT_VERSION);\n await this.tc.publicKV.put(\".well-known/vault-space\", this.vaultConfig.spaceId);\n } catch {\n // Publishing failed — vault still usable\n }\n }\n\n this._isUnlocked = true;\n return ok(undefined);\n } catch (error) {\n // Clear key material on failure\n this.masterKey = null;\n this.encryptionIdentity = null;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n\n try {\n return await this.unlockInFlight;\n } finally {\n this.unlockInFlight = null;\n }\n }\n\n /**\n * Clear the cached vault signatures.\n *\n * @param spaceId - Clear only this space's master cache. If omitted, clears all.\n */\n async clearCache(spaceId?: string): Promise<void> {\n if (spaceId) {\n await clearSignatureCache(`vault-master:${spaceId}`);\n } else {\n await clearSignatureCache();\n }\n }\n\n /**\n * Lock the vault, clearing all key material from memory.\n */\n lock(): void {\n this.masterKey = null;\n this.encryptionIdentity = null;\n this._isUnlocked = false;\n }\n\n /**\n * Called when SDK signs out. Locks the vault and aborts operations.\n */\n onSignOut(): void {\n this.lock();\n super.onSignOut();\n }\n\n private async putNetworkEncrypted(\n key: string,\n value: unknown,\n options?: VaultPutOptions,\n ): Promise<Result<void, VaultError>> {\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const { plaintext, contentType } = this.serializeValue(value, options);\n const metadata: Record<string, string> = {\n [VaultHeaders.VERSION]: \"2\",\n [VaultHeaders.CIPHER]: \"tinycloud-network-envelope\",\n [VaultHeaders.CONTENT_TYPE]: contentType,\n ...(options?.metadata ?? {}),\n };\n const aad = toBytes(`tinycloud.vault:${this.vaultConfig.spaceId}:${key}`);\n const envelopeResult = await config.service.encryptToNetwork(\n config.networkId,\n plaintext,\n { aad, metadata },\n );\n if (!envelopeResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(envelopeResult.error.message),\n });\n }\n\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n JSON.stringify(envelopeResult.data),\n );\n if (!valuePutResult.ok) {\n return kvWriteError(\"Failed to store encrypted value\", valuePutResult.error);\n }\n\n return { ok: true, data: undefined };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n private async getNetworkEncrypted<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>,\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n const proof = await this.decryptCapabilityProof();\n const plaintextResult = await config.service.decryptEnvelope(envelope, proof);\n if (!plaintextResult.ok) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: plaintextResult.error.message,\n });\n }\n\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n\n return { ok: true, data: { value, metadata, keyId } };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n /**\n * Read a network-encrypted entry while preserving safe failure phases.\n *\n * Unlike {@link getNetworkEncrypted}, this is intentionally message-free so\n * an operation layer can distinguish an authorized absence from a failed\n * read without receiving node, envelope, plaintext, or key material.\n */\n async readNetworkEncrypted<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>,\n ): Promise<VaultNetworkReadResult<T>> {\n const config = this.networkEncryption;\n if (!config || !this.requireAuth()) {\n return { status: \"read_failed\" };\n }\n\n let valueResult: Awaited<ReturnType<IKVService[\"get\"]>>;\n try {\n valueResult = await this.tc.kv.get<string>(`vault/${key}`, { raw: true });\n } catch {\n return { status: \"node_unreachable\" };\n }\n\n if (!valueResult.ok) {\n const permissionHint = parsePermissionHint(valueResult.error.meta?.permissionHint);\n if (valueResult.error.code === \"AUTH_UNAUTHORIZED\" && permissionHint !== undefined) {\n return { status: \"permission_required\", hint: permissionHint };\n }\n if (\n (valueResult.error.code === \"NOT_FOUND\" ||\n valueResult.error.code === \"KV_NOT_FOUND\") &&\n !hasHttpResponse(valueResult.error)\n ) {\n return { status: \"not_found\" };\n }\n if (\n valueResult.error.code === \"NETWORK_ERROR\" ||\n valueResult.error.code === \"TIMEOUT\" ||\n valueResult.error.code === \"ABORTED\"\n ) {\n return hasHttpResponse(valueResult.error)\n ? { status: \"read_failed\" }\n : { status: \"node_unreachable\" };\n }\n return { status: \"read_failed\" };\n }\n\n let envelope: InlineEncryptedEnvelope;\n try {\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n } catch {\n return { status: \"corrupt_envelope\" };\n }\n\n let plaintextResult: Awaited<ReturnType<typeof config.service.decryptEnvelope>>;\n try {\n const proof = await this.decryptCapabilityProof();\n plaintextResult = await config.service.decryptEnvelope(envelope, proof);\n } catch {\n return { status: \"decrypt_failed\" };\n }\n\n if (!plaintextResult.ok) {\n const permissionHint = parsePermissionHint(\n (plaintextResult.error as { permissionHint?: unknown }).permissionHint,\n );\n if (plaintextResult.error.code === \"DECRYPT_DENIED\" && permissionHint !== undefined) {\n return { status: \"permission_required\", hint: permissionHint };\n }\n if (plaintextResult.error.code === \"INVALID_ENVELOPE\") {\n return { status: \"corrupt_envelope\" };\n }\n if (plaintextResult.error.code === \"TRANSPORT_ERROR\") {\n return { status: \"node_unreachable\" };\n }\n return { status: \"decrypt_failed\" };\n }\n\n try {\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n return { status: \"ok\", entry: { value, metadata, keyId } };\n } catch {\n return { status: \"invalid_payload\" };\n }\n }\n\n private async headNetworkEncrypted(\n key: string,\n ): Promise<Result<Record<string, string>, VaultError>> {\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n return { ok: true, data: envelope.metadata ?? {} };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n /**\n * Encrypt and store a value at the given key.\n *\n * @param key - The key to store under\n * @param value - The value to encrypt and store\n * @param options - Optional put configuration\n */\n async put(\n key: string,\n value: unknown,\n options?: VaultPutOptions\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"put\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.putNetworkEncrypted(key, value, options);\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before storing data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Serialize value\n let plaintext: Uint8Array;\n if (value instanceof Uint8Array) {\n plaintext = value;\n } else if (options?.serialize) {\n plaintext = options.serialize(value);\n } else if (typeof value === \"string\") {\n plaintext = toBytes(value);\n } else {\n plaintext = toBytes(JSON.stringify(value));\n }\n\n const contentType =\n options?.contentType ??\n (value instanceof Uint8Array\n ? \"application/octet-stream\"\n : \"application/json\");\n\n // Generate per-entry key\n const entryKey = this.crypto.randomBytes(32);\n const keyId = hexEncode(this.crypto.sha256(entryKey)).slice(0, 16);\n\n // Encrypt value with entry key\n const encrypted = this.crypto.encrypt(entryKey, plaintext);\n\n // Encrypt entry key with master key\n const keyBlob = this.crypto.encrypt(this.masterKey, entryKey);\n\n // Build metadata\n const metadata: Record<string, string> = {\n [VaultHeaders.VERSION]: \"1\",\n [VaultHeaders.CIPHER]: \"aes-256-gcm\",\n [VaultHeaders.KEY_ID]: keyId,\n [VaultHeaders.CONTENT_TYPE]: contentType,\n [VaultHeaders.KDF]: \"hkdf-sha256\",\n [VaultHeaders.KEY_ROTATION]:\n this.vaultConfig.keyRotation ?? \"per-write\",\n ...(options?.metadata ?? {}),\n };\n\n // Store encrypted entry key in key space\n const keyMetadata = JSON.stringify({\n keyId,\n contentType,\n ...metadata,\n });\n const keyPayload = JSON.stringify({\n key: base64Encode(keyBlob),\n metadata: keyMetadata,\n });\n const keyPutResult = await this.tc.kv.put(\n `keys/${key}`,\n keyPayload\n );\n if (!keyPutResult.ok) {\n return kvWriteError(\"Failed to store key blob\", keyPutResult.error);\n }\n\n // Store encrypted value in data space\n const valuePayload = JSON.stringify({\n data: base64Encode(encrypted),\n metadata,\n });\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n valuePayload\n );\n if (!valuePutResult.ok) {\n return kvWriteError(\"Failed to store encrypted value\", valuePutResult.error);\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * Retrieve and decrypt a value by key.\n *\n * @param key - The key to retrieve\n * @param options - Optional get configuration\n * @returns Result with the decrypted entry\n */\n async get<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n return this.withTelemetry(\"get\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.getNetworkEncrypted<T>(key, options);\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Fetch encrypted entry key from key space\n const keyResult = await this.tc.kv.get<string>(`keys/${key}`, {\n raw: true,\n });\n if (!keyResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const keyEnvelope = JSON.parse(keyResult.data.data as string);\n const keyBlobBytes = base64Decode(keyEnvelope.key);\n const entryKey = this.crypto.decrypt(this.masterKey, keyBlobBytes);\n\n // Fetch encrypted value from data space\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const valueEnvelope = JSON.parse(valueResult.data.data as string);\n const encryptedBytes = base64Decode(valueEnvelope.data);\n const plaintext = this.crypto.decrypt(entryKey, encryptedBytes);\n\n // Read metadata\n const metadata: Record<string, string> = valueEnvelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId = metadata[VaultHeaders.KEY_ID] ?? \"\";\n\n // Deserialize\n let value: T;\n if (options?.raw) {\n value = plaintext as unknown as T;\n } else if (options?.deserialize) {\n value = options.deserialize(plaintext);\n } else if (contentType === \"application/json\") {\n value = JSON.parse(fromBytes(plaintext)) as T;\n } else {\n value = plaintext as unknown as T;\n }\n\n return ok({ value, metadata, keyId });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"decryption\")\n ) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: error.message,\n });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultEntry<T>, VaultError>>;\n }\n\n /**\n * Delete an encrypted key.\n * Removes both the encrypted value and the key blob.\n *\n * @param key - The key to delete\n */\n async delete(key: string): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"delete\", key, async () => {\n if (!this.isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before deleting data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n if (this.usesNetworkEncryption) {\n const valueDelResult = await this.tc.kv.delete(`vault/${key}`);\n if (!valueDelResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n return ok(undefined);\n }\n\n // Delete from both key space and data space\n const [keyDelResult, valueDelResult] = await Promise.all([\n this.tc.kv.delete(`keys/${key}`),\n this.tc.kv.delete(`vault/${key}`),\n ]);\n\n if (!keyDelResult.ok && !valueDelResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * List vault keys with optional prefix filtering.\n *\n * @param options - Optional list configuration\n * @returns Result with array of key names (vault/ prefix stripped)\n */\n async list(\n options?: VaultListOptions\n ): Promise<Result<string[], VaultError>> {\n const page = await this.listPage(options);\n return page.ok ? { ok: true, data: page.data.keys } : page;\n }\n\n async listPage(\n options?: VaultListOptions\n ): Promise<Result<VaultListPage, VaultError>> {\n return this.withTelemetry(\"list\", options?.prefix, async () => {\n if (!this.isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before listing data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const listPrefix = options?.prefix\n ? `vault/${options.prefix}`\n : \"vault/\";\n\n const listResult = await this.tc.kv.list({\n prefix: listPrefix,\n removePrefix: true,\n ...(options?.limit === undefined ? {} : { limit: options.limit }),\n ...(options?.cursor === undefined ? {} : { cursor: options.cursor }),\n });\n\n if (!listResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to list vault keys: ${listResult.error.message}`\n ),\n });\n }\n\n // Keys are already stripped of the \"vault/\" prefix by removePrefix\n let keys = listResult.data.keys;\n\n // If a user prefix was provided, strip it too if requested\n if (options?.removePrefix && options.prefix) {\n const userPrefix = options.prefix.endsWith(\"/\")\n ? options.prefix\n : `${options.prefix}/`;\n keys = keys.map((k) =>\n k.startsWith(userPrefix) ? k.slice(userPrefix.length) : k\n );\n }\n\n return ok({\n keys,\n truncated: listResult.data.truncated === true,\n ...(listResult.data.nextCursor === undefined ? {} : { nextCursor: listResult.data.nextCursor }),\n });\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultListPage, VaultError>>;\n }\n\n /**\n * Get envelope metadata for a key without decrypting the value.\n *\n * @param key - The key to inspect\n * @returns Result with metadata headers\n */\n async head(\n key: string\n ): Promise<Result<Record<string, string>, VaultError>> {\n return this.withTelemetry(\"head\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.headNetworkEncrypted(key);\n }\n\n if (!this._isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading metadata\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Fetch envelope without decrypting\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const valueEnvelope = JSON.parse(valueResult.data.data as string);\n const metadata: Record<string, string> = valueEnvelope.metadata ?? {};\n return ok(metadata);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<Record<string, string>, VaultError>>;\n }\n\n // =========================================================================\n // Batch Operations\n // =========================================================================\n\n /**\n * Encrypt and store multiple entries.\n *\n * @param entries - Array of key/value pairs with optional per-entry options\n * @returns Array of results, one per entry\n */\n async putMany(\n entries: Array<{ key: string; value: unknown; options?: VaultPutOptions }>\n ): Promise<Result<void, VaultError>[]> {\n return Promise.all(\n entries.map((entry) => this.put(entry.key, entry.value, entry.options))\n );\n }\n\n /**\n * Retrieve and decrypt multiple keys.\n *\n * @param keys - Array of keys to retrieve\n * @param options - Optional get configuration applied to all entries\n * @returns Array of results, one per key\n */\n async getMany<T = unknown>(\n keys: string[],\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>[]> {\n return Promise.all(keys.map((key) => this.get<T>(key, options)));\n }\n\n // =========================================================================\n // Phase 2: Sharing\n // =========================================================================\n\n /**\n * Re-encrypt a vault key for another user (renamed from grant).\n * Re-encrypts the data key to the recipient's public key via X25519 DH.\n *\n * @param key - The key to share\n * @param recipientDID - The recipient's primary DID (did:pkh:...)\n * @param options - Optional grant configuration\n */\n async reencrypt(\n key: string,\n recipientDID: string,\n options?: VaultGrantOptions\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"reencrypt\", key, async () => {\n if (this.usesNetworkEncryption) {\n void recipientDID;\n void options;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"Vault key grants are deprecated for network-encrypted vaults; grant tinycloud.encryption/decrypt on the network plus KV access to vault data.\",\n ),\n });\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before granting access\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Step 1: Resolve recipient's public key\n const pubKeyResult = await this.resolvePublicKey(recipientDID);\n if (!pubKeyResult.ok) {\n return pubKeyResult;\n }\n const bobPubKey = pubKeyResult.data;\n\n // Step 2: Fetch and decrypt entry key from key space\n const keyResult = await this.tc.kv.get<string>(`keys/${key}`, {\n raw: true,\n });\n if (!keyResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const keyEnvelope = JSON.parse(keyResult.data.data as string);\n const keyBlobBytes = base64Decode(keyEnvelope.key);\n const entryKey = this.crypto.decrypt(this.masterKey, keyBlobBytes);\n\n // Step 3: Create ephemeral X25519 key pair\n const ephemeralSeed = this.crypto.randomBytes(32);\n const ephemeralKeyPair = this.crypto.x25519FromSeed(ephemeralSeed);\n\n // Step 4: Compute shared secret via DH\n const sharedSecret = this.crypto.x25519Dh(\n ephemeralKeyPair.privateKey,\n bobPubKey\n );\n\n // Step 5: Derive encryption key from shared secret\n const encryptionKey = this.crypto.deriveKey(\n sharedSecret,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"vault-grant\")\n );\n\n // Step 6: Encrypt entry key with derived key\n const encryptedGrant = this.crypto.encrypt(encryptionKey, entryKey);\n\n // Step 7: Concatenate ephemeral public key + encrypted grant\n const grantBlob = concatBytes(\n ephemeralKeyPair.publicKey,\n encryptedGrant\n );\n\n // Step 8: Store grant in key space\n const grantPayload = JSON.stringify({\n grant: base64Encode(grantBlob),\n spaceId: this.vaultConfig.spaceId,\n metadata: {\n [VaultHeaders.GRANT_VERSION]: \"1\",\n [VaultHeaders.GRANTOR]: this.tc.did,\n ...(options?.metadata ?? {}),\n },\n });\n // Store grant in the vault's space (main space)\n const grantPutResult = await this.tc.kv.put(\n `grants/${recipientDID}/${key}`,\n grantPayload\n );\n if (!grantPutResult.ok) {\n return kvWriteError(\"Failed to store grant\", grantPutResult.error);\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * @deprecated Use reencrypt() instead.\n */\n async grant(\n key: string,\n recipientDID: string,\n options?: VaultGrantOptions\n ): Promise<Result<void, VaultError>> {\n return this.reencrypt(key, recipientDID, options);\n }\n\n /**\n * Retrieve and decrypt a value shared by another user.\n *\n * @param grantorDID - The DID of the user who shared the data\n * @param key - The key that was shared\n * @param options - Optional get configuration\n * @returns Result with the decrypted entry\n */\n async getShared<T = unknown>(\n grantorDID: string,\n key: string,\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n return this.withTelemetry(\"getShared\", key, async () => {\n if (this.usesNetworkEncryption) {\n const grantorKV = options?.kv;\n if (!grantorKV) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"getShared requires a delegated KV service via options.kv.\",\n ),\n });\n }\n\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await grantorKV.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n const proof = await this.decryptCapabilityProof();\n const plaintextResult = await config.service.decryptEnvelope(\n envelope,\n proof,\n );\n if (!plaintextResult.ok) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: plaintextResult.error.message,\n });\n }\n\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n void grantorDID;\n return { ok: true, data: { value, metadata, keyId } };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n if (\n !this._isUnlocked ||\n !this.masterKey ||\n !this.encryptionIdentity\n ) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading shared data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const myDID = this.tc.did;\n const grantorKV = options?.kv;\n\n if (!grantorKV) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"getShared requires a delegated KV service via options.kv. \" +\n \"Use useDelegation() to get delegated access, then pass { kv: access.kv }.\"\n ),\n });\n }\n\n // Step 1: Fetch grant from grantor's space via delegated KV\n const grantResult = await grantorKV.get<string>(`grants/${myDID}/${key}`, {\n raw: true,\n });\n if (!grantResult.ok) {\n return vaultError({\n code: \"GRANT_NOT_FOUND\",\n grantor: grantorDID,\n key,\n });\n }\n\n const grantEnvelope = typeof grantResult.data?.data === \"string\"\n ? JSON.parse(grantResult.data.data as string)\n : grantResult.data?.data;\n const grantBlobBytes = base64Decode((grantEnvelope as any).grant);\n\n // Step 2: Extract ephemeral public key and encrypted grant\n const ephemeralPubKey = grantBlobBytes.slice(0, 32);\n const encryptedGrant = grantBlobBytes.slice(32);\n\n // Step 3: Compute shared secret using our private key\n const sharedSecret = this.crypto.x25519Dh(\n this.encryptionIdentity.privateKey,\n ephemeralPubKey\n );\n\n // Step 4: Derive decryption key\n const encryptionKey = this.crypto.deriveKey(\n sharedSecret,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"vault-grant\")\n );\n\n // Step 5: Decrypt entry key\n const entryKey = this.crypto.decrypt(encryptionKey, encryptedGrant);\n\n // Step 6: Fetch encrypted value from grantor's space via delegated KV\n const valueResult = await grantorKV.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({\n code: \"KEY_NOT_FOUND\",\n key,\n });\n }\n\n const valueEnvelope = typeof valueResult.data?.data === \"string\"\n ? JSON.parse(valueResult.data.data as string)\n : valueResult.data?.data;\n const encryptedBytes = base64Decode((valueEnvelope as any).data);\n const plaintext = this.crypto.decrypt(entryKey, encryptedBytes);\n\n // Read metadata\n const metadata: Record<string, string> = (valueEnvelope as any).metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId = metadata[VaultHeaders.KEY_ID] ?? \"\";\n\n // Deserialize\n let value: T;\n if (options?.raw) {\n value = plaintext as unknown as T;\n } else if (options?.deserialize) {\n value = options.deserialize(plaintext);\n } else if (contentType === \"application/json\") {\n value = JSON.parse(fromBytes(plaintext)) as T;\n } else {\n value = plaintext as unknown as T;\n }\n\n return ok({ value, metadata, keyId });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"decryption\")\n ) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: error.message,\n });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultEntry<T>, VaultError>>;\n }\n\n /**\n * Resolve another user's public encryption key from their DID.\n *\n * @param did - The DID to resolve (did:pkh:eip155:{chainId}:{address})\n * @returns Result with the public key bytes\n */\n async resolvePublicKey(\n did: string\n ): Promise<Result<Uint8Array, VaultError>> {\n try {\n const parts = this.parseDID(did);\n if (!parts) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n\n const spaceId = this.tc.makePublicSpaceId(\n parts.address,\n parts.chainId\n );\n\n const result = await this.tc.readPublicSpace<string>(\n this.host,\n spaceId,\n \".well-known/vault-pubkey\"\n );\n\n if (!result.ok) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n\n const pubKeyBytes = base64Decode(result.data as string);\n return { ok: true, data: pubKeyBytes } as Result<Uint8Array, VaultError>;\n } catch (error) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n }\n\n /**\n * List DIDs that have been granted access to a key.\n *\n * @param key - The key to list grants for\n * @returns Result with array of recipient DIDs\n */\n async listGrants(\n key: string\n ): Promise<Result<string[], VaultError>> {\n return this.withTelemetry(\"listGrants\", key, async () => {\n if (this.usesNetworkEncryption) {\n void key;\n return { ok: true, data: [] };\n }\n\n if (!this._isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before listing grants\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const listResult = await this.tc.kv.list({\n prefix: \"grants/\",\n removePrefix: true,\n });\n\n if (!listResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to list grants: ${listResult.error.message}`\n ),\n });\n }\n\n // Grant paths are: {recipientDID}/{key}\n // Filter for the specific key and extract DIDs\n const dids: string[] = [];\n for (const grantPath of listResult.data.keys) {\n // Path format: {recipientDID}/{key}\n // The key may contain slashes, so we need to match the suffix\n if (grantPath.endsWith(`/${key}`)) {\n const did = grantPath.slice(\n 0,\n grantPath.length - key.length - 1\n );\n if (did) {\n dids.push(did);\n }\n }\n }\n\n return ok(dids);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<string[], VaultError>>;\n }\n\n // =========================================================================\n // Phase 3: Key Rotation / Revocation\n // =========================================================================\n\n /**\n * Revoke a previously issued grant.\n *\n * This performs a full key rotation:\n * 1. Lists current grantees\n * 2. Removes the revoked recipient\n * 3. Re-encrypts the value with a new entry key\n * 4. Re-issues grants to remaining recipients\n *\n * @param key - The key to revoke access to\n * @param recipientDID - The recipient whose access to revoke\n */\n async revoke(\n key: string,\n recipientDID: string\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"revoke\", key, async () => {\n if (this.usesNetworkEncryption) {\n void recipientDID;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"Vault key grants are deprecated for network-encrypted vaults; revoke KV and tinycloud.encryption/decrypt grants instead.\",\n ),\n });\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before revoking access\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Step 1: List all current grantees\n const granteesResult = await this.listGrants(key);\n if (!granteesResult.ok) {\n return granteesResult;\n }\n\n const remainingGrantees = granteesResult.data.filter(\n (did) => did !== recipientDID\n );\n\n // Step 2: Delete the grant for the revoked recipient\n const deleteGrantResult = await this.tc.kv.delete(\n `grants/${recipientDID}/${key}`\n );\n // Grant may already be deleted, that's fine\n\n // Step 3: Fetch and decrypt current value\n const getResult = await this.get(key);\n if (!getResult.ok) {\n return getResult as Result<never, VaultError>;\n }\n\n const currentEntry = getResult.data;\n\n // Step 4: Generate new entry key\n const newEntryKey = this.crypto.randomBytes(32);\n const newKeyId = hexEncode(this.crypto.sha256(newEntryKey)).slice(\n 0,\n 16\n );\n\n // Step 5: Re-serialize and re-encrypt value with new key\n let plaintext: Uint8Array;\n if (currentEntry.value instanceof Uint8Array) {\n plaintext = currentEntry.value;\n } else {\n plaintext = toBytes(JSON.stringify(currentEntry.value));\n }\n\n const encrypted = this.crypto.encrypt(newEntryKey, plaintext);\n\n // Step 6: Encrypt new entry key with master key\n const newKeyBlob = this.crypto.encrypt(this.masterKey, newEntryKey);\n\n // Step 7: Update metadata with new key ID\n const metadata: Record<string, string> = {\n ...currentEntry.metadata,\n [VaultHeaders.KEY_ID]: newKeyId,\n };\n\n // Step 8: Store updated key blob\n const keyPayload = JSON.stringify({\n key: base64Encode(newKeyBlob),\n metadata: JSON.stringify({\n keyId: newKeyId,\n ...metadata,\n }),\n });\n const keyPutResult = await this.tc.kv.put(\n `keys/${key}`,\n keyPayload\n );\n if (!keyPutResult.ok) {\n return kvWriteError(\"Failed to store rotated key blob\", keyPutResult.error);\n }\n\n // Step 9: Store re-encrypted value\n const valuePayload = JSON.stringify({\n data: base64Encode(encrypted),\n metadata,\n });\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n valuePayload\n );\n if (!valuePutResult.ok) {\n return kvWriteError(\"Failed to store re-encrypted value\", valuePutResult.error);\n }\n\n // Step 10: Re-issue grants to remaining recipients\n for (const did of remainingGrantees) {\n const grantResult = await this.reencrypt(key, did);\n if (!grantResult.ok) {\n // Continue re-issuing to other recipients even if one fails\n // The failed grant can be re-issued manually\n }\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n // =========================================================================\n // Internal Helpers\n // =========================================================================\n\n /**\n * Parse a DID string to extract address and chainId.\n * Expected format: did:pkh:eip155:{chainId}:{address}\n *\n * @param did - The DID to parse\n * @returns Parsed address and chainId, or null if invalid\n */\n private parseDID(\n did: string\n ): { address: string; chainId: number } | null {\n // did:pkh:eip155:{chainId}:{address}\n const parts = did.split(\":\");\n if (\n parts.length !== 5 ||\n parts[0] !== \"did\" ||\n parts[1] !== \"pkh\" ||\n parts[2] !== \"eip155\"\n ) {\n return null;\n }\n\n const chainId = parseInt(parts[3], 10);\n const address = parts[4];\n if (isNaN(chainId) || !address) {\n return null;\n }\n\n return { address, chainId };\n }\n}\n","import type { VaultCrypto } from \"./DataVaultService\";\n\nexport interface WasmVaultFunctions {\n vault_encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array;\n vault_decrypt(key: Uint8Array, blob: Uint8Array): Uint8Array;\n /** WASM order: (salt, signature, info) — NOT (signature, salt, info) */\n vault_derive_key(salt: Uint8Array, signature: Uint8Array, info: Uint8Array): Uint8Array;\n vault_x25519_from_seed(seed: Uint8Array): { publicKey: Uint8Array; privateKey: Uint8Array };\n vault_x25519_dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n vault_random_bytes(length: number): Uint8Array;\n vault_sha256(data: Uint8Array): Uint8Array;\n}\n\nexport function createVaultCrypto(wasm: WasmVaultFunctions): VaultCrypto {\n return {\n encrypt: (key, plaintext) => wasm.vault_encrypt(key, plaintext),\n decrypt: (key, blob) => wasm.vault_decrypt(key, blob),\n deriveKey: (signature, salt, info) => wasm.vault_derive_key(salt, signature, info),\n x25519FromSeed: (seed) => wasm.vault_x25519_from_seed(seed),\n x25519Dh: (privateKey, publicKey) => wasm.vault_x25519_dh(privateKey, publicKey),\n randomBytes: (length) => wasm.vault_random_bytes(length),\n sha256: (data) => wasm.vault_sha256(data),\n };\n}\n","export const SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;\n\nconst SECRET_PREFIX = \"secrets/\";\nconst SCOPED_SECRET_PREFIX = \"secrets/scoped/\";\nconst RESERVED_SECRET_SCOPES = new Set([\"default\", \"global\"]);\n\nexport interface SecretScopeOptions {\n /** Optional logical scope. Omit for the global secret namespace. */\n scope?: string;\n}\n\nexport interface ResolvedSecretPath {\n /** Canonical env-style secret name. */\n name: string;\n /** Canonical scope. Undefined means global. */\n scope?: string;\n /** Key passed to the data vault service. */\n vaultKey: string;\n /** KV permission path that backs the encrypted vault entry. */\n permissionPaths: {\n vault: string;\n };\n}\n\nexport interface ParsedSecretCatalogKey {\n name: string;\n scope?: string;\n}\n\nexport function canonicalizeSecretScope(\n scope: string | undefined,\n): string | undefined {\n if (scope === undefined) {\n return undefined;\n }\n\n const trimmed = scope.trim();\n if (trimmed === \"\") {\n throw new Error(\n \"Secret scope must be non-empty; omit scope for global secrets.\",\n );\n }\n\n const canonical = trimmed\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n if (canonical === \"\") {\n throw new Error(\"Secret scope must contain at least one letter or number.\");\n }\n if (RESERVED_SECRET_SCOPES.has(canonical)) {\n throw new Error(\n `Secret scope ${JSON.stringify(scope)} is reserved; omit scope for global secrets.`,\n );\n }\n\n return canonical;\n}\n\nexport function resolveSecretPath(\n name: string,\n options: SecretScopeOptions = {},\n): ResolvedSecretPath {\n const normalizedName = name.trim();\n if (!SECRET_NAME_RE.test(normalizedName)) {\n throw new Error(\n `Invalid secret name ${JSON.stringify(name)}. Secret names must match ${SECRET_NAME_RE.source}.`,\n );\n }\n\n const scope = canonicalizeSecretScope(options.scope);\n const vaultKey =\n scope === undefined\n ? `${SECRET_PREFIX}${normalizedName}`\n : `${SCOPED_SECRET_PREFIX}${scope}/${normalizedName}`;\n\n return {\n name: normalizedName,\n ...(scope !== undefined ? { scope } : {}),\n vaultKey,\n permissionPaths: {\n vault: `vault/${vaultKey}`,\n },\n };\n}\n\nexport function resolveSecretListPrefix(\n options: SecretScopeOptions = {},\n): string {\n const scope = canonicalizeSecretScope(options.scope);\n return scope === undefined\n ? \"vault/secrets/\"\n : `vault/secrets/scoped/${scope}/`;\n}\n\n/** Parse a key relative to `secrets/` into its canonical catalog identity. */\nexport function parseSecretCatalogKey(\n key: string,\n): ParsedSecretCatalogKey | undefined {\n if (SECRET_NAME_RE.test(key)) {\n return { name: key };\n }\n\n const parts = key.split(\"/\");\n if (parts.length !== 3 || parts[0] !== \"scoped\") {\n return undefined;\n }\n\n const [, rawScope, name] = parts;\n if (!name || !SECRET_NAME_RE.test(name)) {\n return undefined;\n }\n\n try {\n const scope = canonicalizeSecretScope(rawScope);\n if (scope === undefined || scope !== rawScope) {\n return undefined;\n }\n return { name, scope };\n } catch {\n return undefined;\n }\n}\n","import { ErrorCodes, err, type Result, type ServiceError } from \"../types\";\nimport type { IDataVaultService } from \"../vault/IDataVaultService\";\nimport type { VaultError } from \"../vault/types\";\nimport type {\n ISecretsService,\n SecretCatalogEntry,\n SecretPayload,\n SecretsError,\n} from \"./ISecretsService\";\nimport {\n canonicalizeSecretScope,\n parseSecretCatalogKey,\n resolveSecretPath,\n SECRET_NAME_RE,\n type ResolvedSecretPath,\n type SecretScopeOptions,\n} from \"./paths\";\n\nfunction invalidSecretInput(message: string): Result<never, ServiceError> {\n return err({\n code: ErrorCodes.INVALID_INPUT,\n service: \"secrets\",\n message,\n });\n}\n\nfunction resolveSecretPathResult(\n name: string,\n options?: SecretScopeOptions,\n): ResolvedSecretPath | Result<never, ServiceError> {\n try {\n return resolveSecretPath(name, options);\n } catch (error) {\n return invalidSecretInput(\n error instanceof Error ? error.message : String(error),\n );\n }\n}\n\nexport class SecretsService implements ISecretsService {\n private readonly getVault: () => IDataVaultService;\n\n constructor(vault: IDataVaultService | (() => IDataVaultService)) {\n this.getVault = typeof vault === \"function\" ? vault : () => vault;\n }\n\n get vault(): IDataVaultService {\n return this.getVault();\n }\n\n get isUnlocked(): boolean {\n return this.vault.isUnlocked;\n }\n\n unlock(signer?: unknown): Promise<Result<void, VaultError>> {\n return this.vault.unlock(signer);\n }\n\n lock(): void {\n this.vault.lock();\n }\n\n async get(\n name: string,\n options?: SecretScopeOptions,\n ): Promise<Result<string, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n const result = await this.vault.get<SecretPayload>(secretPath.vaultKey);\n if (!result.ok) {\n return result;\n }\n return { ok: true, data: result.data.value.value };\n }\n\n async put(\n name: string,\n value: string,\n options?: SecretScopeOptions,\n ): Promise<Result<void, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n const now = new Date().toISOString();\n return this.vault.put(secretPath.vaultKey, {\n value,\n createdAt: now,\n updatedAt: now,\n } satisfies SecretPayload);\n }\n\n async delete(\n name: string,\n options?: SecretScopeOptions,\n ): Promise<Result<void, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n return this.vault.delete(secretPath.vaultKey);\n }\n\n async list(\n options?: SecretScopeOptions,\n ): Promise<Result<string[], SecretsError>> {\n let prefix: string;\n try {\n const scope = canonicalizeSecretScope(options?.scope);\n prefix = scope === undefined ? \"secrets/\" : `secrets/scoped/${scope}/`;\n } catch (error) {\n return invalidSecretInput(\n error instanceof Error ? error.message : String(error),\n );\n }\n\n const result = await this.vault.list({\n prefix,\n removePrefix: true,\n });\n if (!result.ok) {\n return result;\n }\n return {\n ok: true,\n data: result.data.filter((name) => SECRET_NAME_RE.test(name)),\n };\n }\n\n async listAll(): Promise<Result<SecretCatalogEntry[], SecretsError>> {\n const entries = new Map<string, SecretCatalogEntry>();\n // A node older than bounded list paging ignores the cursor and returns the\n // same page again; a repeated cursor would loop forever, so it fails.\n const seenCursors = new Set<string>();\n let cursor: string | undefined;\n\n do {\n const result = await this.vault.listPage({\n prefix: \"secrets/\",\n removePrefix: true,\n limit: 1000,\n ...(cursor === undefined ? {} : { cursor }),\n });\n if (!result.ok) {\n return result;\n }\n\n for (const key of result.data.keys) {\n const entry = parseSecretCatalogKey(key);\n if (!entry) continue;\n entries.set(`${entry.scope ?? \"\"}\\u0000${entry.name}`, entry);\n }\n\n cursor = result.data.truncated ? result.data.nextCursor : undefined;\n if (result.data.truncated && cursor === undefined) {\n return invalidSecretInput(\n \"Secret catalog listing was truncated without a continuation cursor.\",\n );\n }\n if (cursor !== undefined) {\n if (seenCursors.has(cursor)) {\n return invalidSecretInput(\n \"Secret catalog listing repeated a continuation cursor; the node does not support paged KV lists.\",\n );\n }\n seenCursors.add(cursor);\n }\n } while (cursor !== undefined);\n\n return {\n ok: true,\n data: [...entries.values()].sort(\n (a, b) =>\n (a.scope ?? \"\").localeCompare(b.scope ?? \"\") ||\n a.name.localeCompare(b.name),\n ),\n };\n }\n}\n","/**\n * Canonical JSON serialization and content hashing for TinyCloud\n * encryption requests/responses.\n *\n * The node and SDK must agree byte-for-byte on the canonical form so\n * that body-hash bindings (`bodyHash`, `encryptedSymmetricKeyHash`,\n * `receiverPublicKeyHash`) verify on both sides.\n *\n * Canonical rules:\n * - Object keys are sorted lexicographically by code point.\n * - Strings are encoded with the JSON.stringify default (RFC 8259).\n * - Numbers are emitted via JSON.stringify; callers should restrict to\n * integers or use string fields for high-precision values.\n * - `undefined` properties are dropped. `null` is preserved.\n * - Arrays preserve element order.\n *\n * Hashing uses SHA-256 supplied by the caller (via an `EncryptionCrypto`\n * binding) so this module stays platform-agnostic.\n */\n\nexport type Json =\n | null\n | boolean\n | number\n | string\n | Json[]\n | { [key: string]: Json | undefined };\n\n/**\n * Produce the canonical JSON string for {@link value}. Object keys are\n * sorted, `undefined` properties are dropped, and primitive types are\n * encoded by `JSON.stringify`.\n */\nexport function canonicalize(value: Json | undefined): string {\n if (value === undefined) {\n return \"\";\n }\n return stringify(value);\n}\n\nfunction stringify(value: Json): string {\n if (value === null) return \"null\";\n switch (typeof value) {\n case \"boolean\":\n case \"number\":\n return JSON.stringify(value);\n case \"string\":\n return JSON.stringify(value);\n case \"object\": {\n if (Array.isArray(value)) {\n return `[${value.map(stringify).join(\",\")}]`;\n }\n const keys = Object.keys(value).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = value[k];\n if (v === undefined) continue;\n parts.push(`${JSON.stringify(k)}:${stringify(v)}`);\n }\n return `{${parts.join(\",\")}}`;\n }\n default:\n throw new TypeError(\n `canonicalize: unsupported value type ${typeof value}`,\n );\n }\n}\n\nconst HEX = \"0123456789abcdef\";\n\nexport function hexEncode(bytes: Uint8Array): string {\n let out = \"\";\n for (let i = 0; i < bytes.length; i++) {\n const b = bytes[i];\n out += HEX[(b >> 4) & 0xf] + HEX[b & 0xf];\n }\n return out;\n}\n\nexport function hexDecode(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new Error(\"hex string must have even length\");\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const hi = parseInt(hex[i * 2], 16);\n const lo = parseInt(hex[i * 2 + 1], 16);\n if (Number.isNaN(hi) || Number.isNaN(lo)) {\n throw new Error(\"invalid hex character\");\n }\n out[i] = (hi << 4) | lo;\n }\n return out;\n}\n\nexport function base64Encode(bytes: Uint8Array): string {\n // base64 (standard, not url-safe) so envelopes pass through JSON cleanly.\n // We avoid `btoa` to stay node-friendly without polyfills.\n const chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n let out = \"\";\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i];\n const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;\n const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;\n out += chars[(b0 >> 2) & 0x3f];\n out += chars[((b0 << 4) | (b1 >> 4)) & 0x3f];\n out += i + 1 < bytes.length ? chars[((b1 << 2) | (b2 >> 6)) & 0x3f] : \"=\";\n out += i + 2 < bytes.length ? chars[b2 & 0x3f] : \"=\";\n }\n return out;\n}\n\nexport function base64Decode(s: string): Uint8Array {\n const clean = s.replace(/[^A-Za-z0-9+/=]/g, \"\");\n const len = clean.length;\n if (len % 4 !== 0) {\n throw new Error(\"invalid base64 input\");\n }\n const padding =\n clean.endsWith(\"==\") ? 2 : clean.endsWith(\"=\") ? 1 : 0;\n const outLen = (len / 4) * 3 - padding;\n const out = new Uint8Array(outLen);\n const lookup: Record<string, number> = {};\n const chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n for (let i = 0; i < chars.length; i++) lookup[chars[i]] = i;\n\n let outIdx = 0;\n for (let i = 0; i < len; i += 4) {\n const v0 = lookup[clean[i]] ?? 0;\n const v1 = lookup[clean[i + 1]] ?? 0;\n const v2 = clean[i + 2] === \"=\" ? 0 : (lookup[clean[i + 2]] ?? 0);\n const v3 = clean[i + 3] === \"=\" ? 0 : (lookup[clean[i + 3]] ?? 0);\n const b0 = (v0 << 2) | (v1 >> 4);\n const b1 = ((v1 & 0x0f) << 4) | (v2 >> 2);\n const b2 = ((v2 & 0x03) << 6) | v3;\n if (outIdx < outLen) out[outIdx++] = b0;\n if (outIdx < outLen) out[outIdx++] = b1;\n if (outIdx < outLen) out[outIdx++] = b2;\n }\n return out;\n}\n\nexport function utf8Encode(s: string): Uint8Array {\n return new TextEncoder().encode(s);\n}\n\nexport function utf8Decode(b: Uint8Array): string {\n return new TextDecoder().decode(b);\n}\n\n/**\n * Compute `hexEncode(sha256(canonicalize(value)))`. The SHA-256 binding\n * is injected so the module remains usable in both the WASM and pure-JS\n * paths.\n */\nexport function canonicalHashHex(\n sha256: (bytes: Uint8Array) => Uint8Array,\n value: Json,\n): string {\n const canonical = canonicalize(value);\n return hexEncode(sha256(utf8Encode(canonical)));\n}\n","/**\n * Type definitions for TinyCloud one-of-one encryption.\n *\n * Wire shapes mirror the protocol described in the encryption\n * architecture: inline envelopes carry the encrypted symmetric key\n * alongside the ciphertext; decrypt requests are short-lived UCAN\n * invocations against a target node plus networkId.\n */\n\nimport type { Json } from \"./canonical\";\nimport type { PermissionHint } from \"../types\";\n\n/** Default ciphersuite identifier for v1 envelopes. */\nexport const DEFAULT_ENCRYPTION_ALG = \"x25519-aes256gcm/v1\" as const;\n\n/** Inline-envelope schema version. */\nexport const ENVELOPE_VERSION = 1 as const;\n\n/** Default key version on freshly-created networks. */\nexport const DEFAULT_KEY_VERSION = 1 as const;\n\n/** Decrypt-invocation fact type. */\nexport const DECRYPT_FACT_TYPE = \"tinycloud.encryption.decrypt/v1\" as const;\n\n/** Decrypt response type. */\nexport const DECRYPT_RESULT_TYPE =\n \"tinycloud.encryption.decrypt-result/v1\" as const;\n\n/** Encryption service identifier (manifest long form). */\nexport const ENCRYPTION_SERVICE = \"tinycloud.encryption\" as const;\n\n/** Short form used in recap/abilities maps. */\nexport const ENCRYPTION_SERVICE_SHORT = \"encryption\" as const;\n\n/** Decrypt ability URN. */\nexport const DECRYPT_ACTION = \"tinycloud.encryption/decrypt\" as const;\n\n/**\n * Inline encrypted envelope persisted in KV/SQL records.\n *\n * - `encryptedSymmetricKey` is opaque to the SDK; only the network can\n * unwrap it.\n * - `encryptedSymmetricKeyHash` is the canonical hash of the wrapped key\n * bytes (hex-encoded sha-256 of the base64 string's canonical JSON\n * form). The node recomputes this on every decrypt request.\n * - `ciphertext` and `aad` are payload bytes only; the node never sees\n * them.\n */\nexport interface InlineEncryptedEnvelope {\n /** Schema version. */\n v: typeof ENVELOPE_VERSION;\n /** Network id URN. */\n networkId: string;\n /** Ciphersuite identifier. */\n alg: string;\n /** Network key version that was used to wrap the symmetric key. */\n keyVersion: number;\n /** Base64-encoded wrapped symmetric key / capsule. */\n encryptedSymmetricKey: string;\n /** Hex sha-256 of the canonical encryptedSymmetricKey string. */\n encryptedSymmetricKeyHash: string;\n /** Base64-encoded payload ciphertext. */\n ciphertext: string;\n /** Base64-encoded associated data, if any. */\n aad?: string;\n /** Caller-supplied metadata. Not authenticated against the node. */\n metadata?: Record<string, string>;\n}\n\n/**\n * Node-published network descriptor. The node DB is authoritative; a\n * cached copy may also live under\n * `.well-known/encryption/network/<name>` in the owner's account\n * space (a discovery record only).\n */\nexport interface NetworkDescriptor {\n networkId: string;\n ownerDid: string;\n name: string;\n members: ReadonlyArray<{ nodeId: string; role: \"primary\" | \"share\" }>;\n threshold: { n: number; t: number };\n state: \"pending\" | \"generating\" | \"active\" | \"rotating\" | \"revoked\" | \"failed\";\n /** Base64-encoded network public key. */\n publicEncryptionKey: string;\n alg: string;\n keyVersion: number;\n keyBackend: \"local-one-of-one\" | \"dstack\" | \"threshold\";\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Decrypt-request body sent over the wire. Hashed (canonically) and\n * bound to the UCAN invocation via `facts.bodyHash`.\n */\nexport interface DecryptRequestBody {\n type: typeof DECRYPT_FACT_TYPE;\n targetNode: string;\n networkId: string;\n alg: string;\n keyVersion: number;\n /** Base64-encoded wrapped symmetric key from the envelope. */\n encryptedSymmetricKey: string;\n /** Recomputed hash of the wrapped key. */\n encryptedSymmetricKeyHash: string;\n /** Base64-encoded per-request receiver public key. */\n receiverPublicKey: string;\n /** Hash of the receiver public key. */\n receiverPublicKeyHash: string;\n}\n\n/**\n * Decrypt-response body returned by the node. The SDK verifies the\n * signature, recomputes hashes, then unwraps `wrappedKey` with the\n * per-request receiver private key before decrypting the payload.\n */\nexport interface DecryptResponseBody {\n type: typeof DECRYPT_RESULT_TYPE;\n targetNode: string;\n networkId: string;\n invocationCid: string;\n encryptedSymmetricKeyHash: string;\n receiverPublicKeyHash: string;\n /** Base64-encoded symmetric key re-encrypted to receiverPublicKey. */\n wrappedKey: string;\n alg: string;\n keyVersion: number;\n requestHash: string;\n nodeId: string;\n /** Base64-encoded ed25519 signature over canonical(response - signature field). */\n nodeSignature: string;\n}\n\n/**\n * Decrypt-invocation facts attached to the UCAN. Verifiers recompute\n * `bodyHash`, `encryptedSymmetricKeyHash`, and `receiverPublicKeyHash`\n * from the request body and reject any mismatch.\n */\nexport interface DecryptInvocationFact {\n type: typeof DECRYPT_FACT_TYPE;\n targetNode: string;\n networkId: string;\n bodyHash: string;\n encryptedSymmetricKeyHash: string;\n receiverPublicKeyHash: string;\n alg: string;\n keyVersion: number;\n}\n\n/**\n * Per-request receiver key pair (x25519). The private key never\n * leaves the SDK; the public key is sent to the node so the node can\n * rewrap the symmetric key.\n */\nexport interface ReceiverKeyPair {\n publicKey: Uint8Array;\n privateKey: Uint8Array;\n}\n\n/**\n * Crypto primitives injected into the encryption module. The SDK\n * provides these via WASM bindings; tests provide simple in-memory\n * implementations.\n */\nexport interface EncryptionCrypto {\n /** SHA-256 → 32-byte digest. */\n sha256(data: Uint8Array): Uint8Array;\n /** Cryptographically secure random bytes. */\n randomBytes(length: number): Uint8Array;\n /** Derive an x25519 key pair from a 32-byte seed. */\n x25519FromSeed(seed: Uint8Array): ReceiverKeyPair;\n /** Compute the x25519 ECDH shared secret. */\n x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n /** Authenticated symmetric encryption (the node's symmetric scheme). */\n authEncrypt(\n key: Uint8Array,\n plaintext: Uint8Array,\n aad?: Uint8Array,\n ): Uint8Array;\n /** Authenticated symmetric decryption (matched to authEncrypt). */\n authDecrypt(\n key: Uint8Array,\n ciphertext: Uint8Array,\n aad?: Uint8Array,\n ): Uint8Array;\n /**\n * Wrap a symmetric key for the network's public encryption key using\n * a sealed-box / hpke / x25519+symmetric construction. Implementation\n * is opaque; only the node can unwrap.\n */\n sealToNetworkKey(\n networkPublicKey: Uint8Array,\n symmetricKey: Uint8Array,\n ): Uint8Array;\n /**\n * Open a wrapped symmetric key that was re-encrypted to the\n * per-request receiver public key. The matching private key must be\n * supplied here; the SDK never sends it to the node.\n */\n openWithReceiverKey(\n receiverPrivateKey: Uint8Array,\n wrappedKey: Uint8Array,\n ): Uint8Array;\n /**\n * Verify an ed25519 signature over `message` produced by the node\n * identified by `nodeId` (the public-key DID).\n */\n verifyNodeSignature(\n nodeId: string,\n message: Uint8Array,\n signature: Uint8Array,\n ): boolean;\n}\n\n/**\n * Signer interface used to derive a receiver key pair from a wallet or\n * session signer. The signature is HKDF-extracted into the receiver\n * seed so the public key is reproducible given the same context.\n */\nexport interface ReceiverKeySigner {\n signMessage(message: string): Promise<string>;\n}\n\n/** Capability proof material accompanying a decrypt invocation. */\nexport interface DecryptCapabilityProof {\n /** Delegation chain CIDs rooted at the network owner DID. */\n proofs: ReadonlyArray<string>;\n /** Optional Authorization header value to use instead of building one. */\n authorization?: string;\n}\n\n/**\n * Inputs to the decrypt invocation builder.\n */\nexport interface BuildDecryptInvocationInput {\n /** Target node DID — also the UCAN audience. */\n targetNode: string;\n /** Network id URN — also the recap resource. */\n networkId: string;\n /** Canonical body that will be POSTed. */\n body: DecryptRequestBody;\n /** Facts include hashes bound to the canonical body. */\n facts: DecryptInvocationFact;\n /** Capability proof chain. */\n proof: DecryptCapabilityProof;\n /** Optional `nbf` UCAN field as an ISO date string. */\n notBefore?: string;\n /** Optional `exp` UCAN field as an ISO date string. */\n expiration?: string;\n}\n\n/**\n * The output of {@link buildDecryptInvocation}.\n */\nexport interface BuiltDecryptInvocation {\n /** HTTP `Authorization` header value. */\n authorization: string;\n /** CID of the invocation (used by the node response binding). */\n invocationCid: string;\n /** Canonical body string the node will hash. */\n canonicalBody: string;\n}\n\n/**\n * Signer interface for producing the decrypt invocation. WASM bindings\n * implement this with the same session signer used for KV/SQL\n * invocations; tests can stub it.\n */\nexport interface DecryptInvocationSigner {\n signDecryptInvocation(input: BuildDecryptInvocationInput): Promise<BuiltDecryptInvocation>;\n}\n\n/**\n * Errors thrown / returned from the encryption module.\n */\nexport type EncryptionErrorInput =\n | { code: \"NETWORK_NOT_FOUND\"; networkId?: string; name?: string; message?: string }\n | { code: \"NETWORK_NOT_ACTIVE\"; state: string; message?: string }\n | { code: \"INVALID_NETWORK_ID\"; message: string }\n | { code: \"INVALID_ENVELOPE\"; message: string }\n | { code: \"DECRYPT_DENIED\"; message: string; permissionHint?: PermissionHint }\n | { code: \"INVALID_RESPONSE\"; message: string }\n | { code: \"RESPONSE_SIGNATURE_INVALID\"; message?: string }\n | { code: \"RESPONSE_BINDING_MISMATCH\"; field: string; message?: string }\n | { code: \"TRANSPORT_ERROR\"; cause: Error; message?: string }\n | { code: \"INVALID_INPUT\"; message: string };\n\nexport type EncryptionError = EncryptionErrorInput & {\n service: \"encryption\";\n message: string;\n};\n\nfunction defaultEncryptionMessage(input: EncryptionErrorInput): string {\n switch (input.code) {\n case \"NETWORK_NOT_FOUND\":\n return (\n input.message ??\n `Network not found: ${input.networkId ?? input.name ?? \"<unknown>\"}`\n );\n case \"NETWORK_NOT_ACTIVE\":\n return input.message ?? `Network not active (state=${input.state})`;\n case \"INVALID_NETWORK_ID\":\n return input.message;\n case \"INVALID_ENVELOPE\":\n return input.message;\n case \"DECRYPT_DENIED\":\n return input.message;\n case \"INVALID_RESPONSE\":\n return input.message;\n case \"RESPONSE_SIGNATURE_INVALID\":\n return input.message ?? \"Node response signature failed to verify\";\n case \"RESPONSE_BINDING_MISMATCH\":\n return (\n input.message ??\n `Node response binding mismatch on field ${JSON.stringify(input.field)}`\n );\n case \"TRANSPORT_ERROR\":\n return input.message ?? input.cause.message;\n case \"INVALID_INPUT\":\n return input.message;\n }\n}\n\nexport function encryptionError(input: EncryptionErrorInput): EncryptionError {\n return {\n ...input,\n service: \"encryption\",\n message: defaultEncryptionMessage(input),\n };\n}\n\n/** Helper for the test/runtime layers to coerce arbitrary throwables. */\nexport function toError(error: unknown): Error {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null) {\n return new Error(JSON.stringify(error));\n }\n return new Error(String(error));\n}\n\n/** Re-export for ergonomic typing of canonical payloads. */\nexport type CanonicalJson = Json;\n","/**\n * Network-descriptor discovery.\n *\n * Resolution order (per architecture):\n *\n * 1. The node's authoritative endpoint\n * `GET /encryption/networks/<networkId>` returns the current\n * descriptor (`state`, `publicEncryptionKey`, `keyVersion`, ...).\n * 2. If the node is unreachable, fall back to the cached discovery\n * record at `.well-known/encryption/network/<name>` inside the\n * owner's public space.\n *\n * The node DB is authoritative on conflict; cached records are\n * advisory only.\n */\n\nimport {\n NetworkIdError,\n networkDiscoveryKey,\n ownerDidMatches,\n parseNetworkId,\n} from \"./networkId\";\nimport {\n encryptionError,\n type EncryptionError,\n type NetworkDescriptor,\n} from \"./types\";\n\nexport type DiscoverySource = \"node\" | \"well-known\";\n\nexport interface DiscoveredNetwork {\n descriptor: NetworkDescriptor;\n source: DiscoverySource;\n}\n\nexport interface NodeDescriptorFetcher {\n /** Fetch the descriptor by full networkId URN. */\n fetchByNetworkId(networkId: string): Promise<NetworkDescriptor | null>;\n}\n\nexport interface WellKnownDescriptorFetcher {\n /**\n * Read the cached well-known descriptor by owner DID + network name.\n * Returns null if no record exists or the record is unreadable.\n */\n fetchWellKnown(\n ownerDid: string,\n discoveryKey: string,\n ): Promise<NetworkDescriptor | null>;\n}\n\nexport interface DiscoverNetworkInput {\n /** Either a networkId URN or a bare network name (paired with `ownerDid`). */\n identifier: string;\n /** Required when identifier is a bare name. */\n ownerDid?: string;\n node?: NodeDescriptorFetcher;\n wellKnown?: WellKnownDescriptorFetcher;\n}\n\n/**\n * Resolve a network descriptor. The node fetcher is preferred; the\n * well-known fallback is used only on transport failure.\n *\n * The returned descriptor is sanity-checked: `networkId`, `ownerDid`,\n * and `name` must agree with the URN, and the public key field must\n * be non-empty.\n */\nexport async function discoverNetwork(\n input: DiscoverNetworkInput,\n):\n | Promise<{ ok: true; data: DiscoveredNetwork } | { ok: false; error: EncryptionError }> {\n let networkId: string;\n let ownerDid: string;\n let name: string;\n try {\n if (input.identifier.startsWith(\"urn:tinycloud:encryption:\")) {\n const parsed = parseNetworkId(input.identifier);\n networkId = parsed.networkId;\n ownerDid = parsed.ownerDid;\n name = parsed.name;\n } else {\n if (input.ownerDid === undefined) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"discoverNetwork requires `ownerDid` when identifier is a bare network name\",\n }),\n };\n }\n networkId = `urn:tinycloud:encryption:${input.ownerDid}:${input.identifier}`;\n const parsed = parseNetworkId(networkId);\n ownerDid = parsed.ownerDid;\n name = parsed.name;\n }\n } catch (err) {\n if (err instanceof NetworkIdError) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: err.message,\n }),\n };\n }\n throw err;\n }\n\n // 1) Try the node first.\n if (input.node !== undefined) {\n try {\n const descriptor = await input.node.fetchByNetworkId(networkId);\n if (descriptor !== null) {\n const validated = validateDescriptor(descriptor, networkId, ownerDid, name);\n if (!validated.ok) return validated;\n return { ok: true, data: { descriptor: validated.data, source: \"node\" } };\n }\n } catch (err) {\n // Fall through to well-known\n }\n }\n\n // 2) Fallback to well-known cache.\n if (input.wellKnown !== undefined) {\n try {\n const descriptor = await input.wellKnown.fetchWellKnown(\n ownerDid,\n networkDiscoveryKey(name),\n );\n if (descriptor !== null) {\n const validated = validateDescriptor(descriptor, networkId, ownerDid, name);\n if (!validated.ok) return validated;\n return {\n ok: true,\n data: { descriptor: validated.data, source: \"well-known\" },\n };\n }\n } catch (err) {\n // Fall through to NOT_FOUND\n }\n }\n\n return {\n ok: false,\n error: encryptionError({\n code: \"NETWORK_NOT_FOUND\",\n networkId,\n name,\n }),\n };\n}\n\nfunction validateDescriptor(\n descriptor: NetworkDescriptor,\n networkId: string,\n ownerDid: string,\n name: string,\n):\n | { ok: true; data: NetworkDescriptor }\n | { ok: false; error: EncryptionError } {\n let descriptorNetwork;\n try {\n descriptorNetwork = parseNetworkId(descriptor.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: `descriptor networkId is malformed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n\n if (\n descriptorNetwork.name !== name ||\n !ownerDidMatches(descriptorNetwork.ownerDid, ownerDid)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: `descriptor networkId ${JSON.stringify(descriptor.networkId)} does not match expected ${JSON.stringify(networkId)}`,\n }),\n };\n }\n\n const descriptorOwnerDid = descriptorOwner(descriptor);\n if (\n descriptorOwnerDid === undefined ||\n !ownerDidMatches(descriptorOwnerDid, ownerDid) ||\n !ownerDidMatches(descriptorOwnerDid, descriptorNetwork.ownerDid)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor ownerDid does not match networkId ownerDid\",\n }),\n };\n }\n if (descriptor.name !== name) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor name does not match networkId name\",\n }),\n };\n }\n if (\n typeof descriptor.publicEncryptionKey !== \"string\" ||\n descriptor.publicEncryptionKey.length === 0\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor publicEncryptionKey must be a non-empty string\",\n }),\n };\n }\n return {\n ok: true,\n data: {\n ...descriptor,\n ownerDid: descriptorOwnerDid,\n },\n };\n}\n\nfunction descriptorOwner(descriptor: NetworkDescriptor): string | undefined {\n if (typeof descriptor.ownerDid === \"string\" && descriptor.ownerDid.length > 0) {\n return descriptor.ownerDid;\n }\n\n const legacyDescriptor = descriptor as NetworkDescriptor & {\n principal?: unknown;\n };\n return typeof legacyDescriptor.principal === \"string\" &&\n legacyDescriptor.principal.length > 0\n ? legacyDescriptor.principal\n : undefined;\n}\n\n/**\n * Reject a descriptor that is not in a state that accepts decrypt\n * requests. Only `active` and `rotating` networks may decrypt; revoked\n * or pending networks reject.\n */\nexport function ensureNetworkUsableForDecrypt(\n descriptor: NetworkDescriptor,\n):\n | { ok: true; data: NetworkDescriptor }\n | { ok: false; error: EncryptionError } {\n if (descriptor.state === \"active\" || descriptor.state === \"rotating\") {\n return { ok: true, data: descriptor };\n }\n return {\n ok: false,\n error: encryptionError({\n code: \"NETWORK_NOT_ACTIVE\",\n state: descriptor.state,\n }),\n };\n}\n","/**\n * Inline-envelope encrypt / decrypt helpers.\n *\n * Encryption is fully local: the SDK generates a per-record symmetric\n * key, encrypts the payload, then wraps the symmetric key against the\n * network's public encryption key. The wrapped key (and key hash)\n * travels alongside the ciphertext inside an\n * {@link InlineEncryptedEnvelope}.\n *\n * Decryption is split: the node unwraps the symmetric key to the\n * per-request receiver public key (see {@link buildDecryptInvocation}\n * and the decrypt route); this module is responsible for the local\n * payload decryption once the symmetric key is available.\n */\n\nimport {\n base64Decode,\n base64Encode,\n canonicalHashHex,\n} from \"./canonical\";\nimport {\n DEFAULT_ENCRYPTION_ALG,\n DEFAULT_KEY_VERSION,\n ENVELOPE_VERSION,\n encryptionError,\n type EncryptionCrypto,\n type EncryptionError,\n type InlineEncryptedEnvelope,\n} from \"./types\";\nimport { parseNetworkId } from \"./networkId\";\n\nexport interface EncryptToNetworkInput {\n /** Target network id URN. */\n networkId: string;\n /** Network public key bytes (already discovered). */\n networkPublicKey: Uint8Array;\n /** Payload bytes to encrypt. Callers serialize objects to bytes themselves. */\n plaintext: Uint8Array;\n /** Optional associated authenticated data. */\n aad?: Uint8Array;\n /** Ciphersuite identifier. Defaults to {@link DEFAULT_ENCRYPTION_ALG}. */\n alg?: string;\n /** Key version. Defaults to {@link DEFAULT_KEY_VERSION}. */\n keyVersion?: number;\n /** Caller-supplied envelope metadata. */\n metadata?: Record<string, string>;\n}\n\nexport interface EncryptToNetworkResult {\n envelope: InlineEncryptedEnvelope;\n /** Symmetric key returned for caller bookkeeping; do NOT persist. */\n symmetricKey: Uint8Array;\n}\n\n/**\n * Local-only encrypt: generates a symmetric key, encrypts the payload,\n * wraps the key against the network public key, and returns the\n * inline envelope.\n */\nexport function encryptToNetwork(\n crypto: EncryptionCrypto,\n input: EncryptToNetworkInput,\n): EncryptToNetworkResult {\n parseNetworkId(input.networkId);\n const alg = input.alg ?? DEFAULT_ENCRYPTION_ALG;\n const keyVersion = input.keyVersion ?? DEFAULT_KEY_VERSION;\n\n const symmetricKey = crypto.randomBytes(32);\n const ciphertext = crypto.authEncrypt(symmetricKey, input.plaintext, input.aad);\n const wrapped = crypto.sealToNetworkKey(input.networkPublicKey, symmetricKey);\n const encryptedSymmetricKey = base64Encode(wrapped);\n const encryptedSymmetricKeyHash = canonicalHashHex(\n crypto.sha256,\n encryptedSymmetricKey,\n );\n\n const envelope: InlineEncryptedEnvelope = {\n v: ENVELOPE_VERSION,\n networkId: input.networkId,\n alg,\n keyVersion,\n encryptedSymmetricKey,\n encryptedSymmetricKeyHash,\n ciphertext: base64Encode(ciphertext),\n ...(input.aad !== undefined ? { aad: base64Encode(input.aad) } : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n };\n\n return { envelope, symmetricKey };\n}\n\n/**\n * Validate an inline envelope shape. Returns an error if the envelope\n * is missing required fields or fails internal hash recomputation.\n */\nexport function validateEnvelope(\n crypto: EncryptionCrypto,\n envelope: unknown,\n): { ok: true; data: InlineEncryptedEnvelope } | { ok: false; error: EncryptionError } {\n if (envelope === null || typeof envelope !== \"object\") {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: \"envelope must be an object\",\n }),\n };\n }\n const e = envelope as InlineEncryptedEnvelope;\n if (e.v !== ENVELOPE_VERSION) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.v must be ${ENVELOPE_VERSION} (got ${e.v as unknown as string})`,\n }),\n };\n }\n try {\n parseNetworkId(e.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.networkId is malformed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n for (const field of [\n \"alg\",\n \"encryptedSymmetricKey\",\n \"encryptedSymmetricKeyHash\",\n \"ciphertext\",\n ] as const) {\n if (typeof e[field] !== \"string\" || (e[field] as string).length === 0) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.${field} must be a non-empty string`,\n }),\n };\n }\n }\n if (typeof e.keyVersion !== \"number\" || !Number.isInteger(e.keyVersion)) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: \"envelope.keyVersion must be an integer\",\n }),\n };\n }\n const expectedHash = canonicalHashHex(crypto.sha256, e.encryptedSymmetricKey);\n if (expectedHash !== e.encryptedSymmetricKeyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message:\n \"envelope.encryptedSymmetricKeyHash does not match canonical hash of encryptedSymmetricKey\",\n }),\n };\n }\n return { ok: true, data: e };\n}\n\n/**\n * Decrypt an inline envelope given the unwrapped symmetric key.\n *\n * Callers typically obtain the symmetric key via the node decrypt\n * endpoint plus the per-request receiver key pair (see\n * `EncryptionService.decryptEnvelope`).\n */\nexport function decryptEnvelopeWithKey(\n crypto: EncryptionCrypto,\n envelope: InlineEncryptedEnvelope,\n symmetricKey: Uint8Array,\n): Uint8Array {\n const ciphertext = base64Decode(envelope.ciphertext);\n const aad = envelope.aad !== undefined ? base64Decode(envelope.aad) : undefined;\n return crypto.authDecrypt(symmetricKey, ciphertext, aad);\n}\n","/**\n * TinyCloud encryption decrypt-invocation builder.\n *\n * The decrypt invocation is a UCAN-style TinyCloud invocation against\n * a node plus a network id. It is structurally distinct from the\n * existing space-shaped invocations:\n *\n * - `aud` (audience) is the **target node DID** (not a space owner).\n * - `att` (attenuation) uses the **networkId URN** as the resource\n * key (not a `tinycloud:pkh:...:<space>` URI).\n * - `fct` (facts) binds `bodyHash`, `encryptedSymmetricKeyHash`, and\n * `receiverPublicKeyHash` so the node can recompute them from the\n * POST body.\n *\n * Production callers inject a `DecryptInvocationSigner` backed by the\n * WASM UCAN/session signer. Tests pass a deterministic stub.\n */\n\nimport { canonicalize, canonicalHashHex, hexEncode, utf8Encode } from \"./canonical\";\nimport { parseNetworkId } from \"./networkId\";\nimport {\n DECRYPT_ACTION,\n DECRYPT_FACT_TYPE,\n ENCRYPTION_SERVICE,\n encryptionError,\n type BuildDecryptInvocationInput,\n type BuiltDecryptInvocation,\n type CanonicalJson,\n type DecryptCapabilityProof,\n type DecryptInvocationFact,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type EncryptionCrypto,\n type EncryptionError,\n} from \"./types\";\n\nexport interface CanonicalDecryptRequest {\n /** The canonical body that the node will hash. */\n canonicalBody: string;\n /** Hex sha-256 of the canonical body bytes. */\n bodyHash: string;\n /** Hex sha-256 of the receiver public key bytes. */\n receiverPublicKeyHash: string;\n}\n\nexport interface BuildCanonicalDecryptRequestInput {\n crypto: EncryptionCrypto;\n body: DecryptRequestBody;\n receiverPublicKey: Uint8Array;\n}\n\n/**\n * Build the canonical body string and its bound hashes for a decrypt\n * request. The output is what gets POSTed to the node, and what the\n * node will hash to verify `facts.bodyHash`.\n */\nexport function buildCanonicalDecryptRequest(\n input: BuildCanonicalDecryptRequestInput,\n): CanonicalDecryptRequest {\n const canonicalBody = canonicalize(input.body as unknown as CanonicalJson);\n const bodyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body as unknown as CanonicalJson,\n );\n const receiverPublicKeyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body.receiverPublicKey,\n );\n return { canonicalBody, bodyHash, receiverPublicKeyHash };\n}\n\nexport interface BuildDecryptFactsInput {\n crypto: EncryptionCrypto;\n body: DecryptRequestBody;\n /** Encrypted symmetric key hash from the envelope (already canonical). */\n encryptedSymmetricKeyHash: string;\n /** Receiver public key bytes. */\n receiverPublicKey: Uint8Array;\n /** Canonical body string used to derive bodyHash. */\n canonicalBody?: string;\n}\n\n/**\n * Build the {@link DecryptInvocationFact} that will be embedded in the\n * UCAN `fct` field. Hashes are recomputed here so callers cannot drift\n * from the canonical body without the node noticing.\n */\nexport function buildDecryptFacts(\n input: BuildDecryptFactsInput,\n): DecryptInvocationFact {\n // When a precomputed canonicalBody string is supplied, hash its bytes\n // directly. Don't route it through canonicalHashHex, which would\n // re-canonicalize the string itself (escaping it as a JSON value).\n const bodyHash =\n input.canonicalBody !== undefined\n ? hexEncode(input.crypto.sha256(utf8Encode(input.canonicalBody)))\n : canonicalHashHex(\n input.crypto.sha256,\n input.body as unknown as CanonicalJson,\n );\n const receiverPublicKeyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body.receiverPublicKey,\n );\n return {\n type: DECRYPT_FACT_TYPE,\n targetNode: input.body.targetNode,\n networkId: input.body.networkId,\n bodyHash,\n encryptedSymmetricKeyHash: input.encryptedSymmetricKeyHash,\n receiverPublicKeyHash,\n alg: input.body.alg,\n keyVersion: input.body.keyVersion,\n };\n}\n\n/**\n * Recap-shaped attenuation for the decrypt invocation. The resource\n * key is the networkId URN; the ability is the long-form\n * `tinycloud.encryption/decrypt`. This is intentionally distinct from\n * the existing space-shaped invocation map so callers cannot\n * accidentally fake a space prefix.\n */\nexport function buildDecryptAttenuation(\n networkId: string,\n): Record<string, Record<string, Record<string, never>>> {\n parseNetworkId(networkId);\n return {\n [networkId]: {\n [DECRYPT_ACTION]: {},\n },\n };\n}\n\n/**\n * Validate a {@link BuildDecryptInvocationInput} payload — the body\n * shape, the facts bindings, and the audience contract — without\n * actually signing. Returns either the input (typed) or a structured\n * error so callers can short-circuit before calling into WASM.\n */\nexport function checkDecryptInvocationInput(\n crypto: EncryptionCrypto,\n input: BuildDecryptInvocationInput,\n):\n | { ok: true; data: BuildDecryptInvocationInput; canonicalBody: string }\n | { ok: false; error: EncryptionError } {\n if (input.body.type !== DECRYPT_FACT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: `body.type must be ${DECRYPT_FACT_TYPE}`,\n }),\n };\n }\n if (input.facts.type !== DECRYPT_FACT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: `facts.type must be ${DECRYPT_FACT_TYPE}`,\n }),\n };\n }\n if (input.facts.targetNode !== input.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.targetNode must equal targetNode — the UCAN audience binds the request to a single node\",\n }),\n };\n }\n if (input.body.targetNode !== input.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"body.targetNode must equal targetNode\",\n }),\n };\n }\n if (input.facts.networkId !== input.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.networkId must equal networkId\",\n }),\n };\n }\n if (input.body.networkId !== input.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"body.networkId must equal networkId\",\n }),\n };\n }\n if (input.facts.alg !== input.body.alg) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.alg must equal body.alg\",\n }),\n };\n }\n if (input.facts.keyVersion !== input.body.keyVersion) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.keyVersion must equal body.keyVersion\",\n }),\n };\n }\n if (\n input.facts.encryptedSymmetricKeyHash !==\n input.body.encryptedSymmetricKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.encryptedSymmetricKeyHash must equal body.encryptedSymmetricKeyHash\",\n }),\n };\n }\n if (\n input.facts.receiverPublicKeyHash !== input.body.receiverPublicKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.receiverPublicKeyHash must equal body.receiverPublicKeyHash\",\n }),\n };\n }\n try {\n parseNetworkId(input.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: err instanceof Error ? err.message : String(err),\n }),\n };\n }\n const canonicalBody = canonicalize(\n input.body as unknown as CanonicalJson,\n );\n const expectedBodyHash = canonicalHashHex(crypto.sha256, input.body as unknown as CanonicalJson);\n if (expectedBodyHash !== input.facts.bodyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.bodyHash does not match the canonical body hash\",\n }),\n };\n }\n return { ok: true, data: input, canonicalBody };\n}\n\n/**\n * Compose the high-level decrypt invocation and hand it to the signer\n * for UCAN minting. The signer returns the Authorization header value\n * plus the invocation CID; this function only validates and\n * orchestrates — it does not perform crypto signing itself.\n */\nexport async function buildDecryptInvocation(\n crypto: EncryptionCrypto,\n signer: DecryptInvocationSigner,\n input: BuildDecryptInvocationInput,\n): Promise<{ ok: true; data: BuiltDecryptInvocation } | { ok: false; error: EncryptionError }> {\n const checked = checkDecryptInvocationInput(crypto, input);\n if (!checked.ok) {\n return checked;\n }\n try {\n const built = await signer.signDecryptInvocation(checked.data);\n if (!built.authorization || !built.invocationCid) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"decrypt-invocation signer returned an empty authorization or invocationCid\",\n }),\n };\n }\n if (built.canonicalBody !== checked.canonicalBody) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"decrypt-invocation signer returned a canonicalBody that does not match the SDK's canonicalization — signer must use the SDK-provided body\",\n }),\n };\n }\n return { ok: true, data: built };\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: err instanceof Error ? err : new Error(String(err)),\n message: `failed to sign decrypt invocation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n}\n\n/** Re-export so callers can introspect the service+action constants. */\nexport { DECRYPT_ACTION, ENCRYPTION_SERVICE };\n","/**\n * Per-request receiver key generation.\n *\n * The receiver key pair is generated for a single decrypt request: the\n * SDK sends `receiverPublicKey` to the node so the node can rewrap the\n * symmetric key; the matching private key never leaves the SDK.\n *\n * Two derivation modes are supported:\n *\n * 1. **Random** — `crypto.randomBytes(32)` seeds a fresh x25519 pair.\n * This is the default for one-of-one flows.\n *\n * 2. **Signed-context** — the caller provides a signer that signs a\n * deterministic context message (network id + nonce + invocation\n * intent). The signature bytes are SHA-256'd into the seed. This is\n * useful when callers want the receiver key to be reproducible by\n * the same session signer (e.g. for delegated reads where the\n * signer is the only stable secret).\n */\n\nimport { utf8Encode } from \"./canonical\";\nimport type {\n EncryptionCrypto,\n ReceiverKeyPair,\n ReceiverKeySigner,\n} from \"./types\";\n\nexport interface RandomReceiverKeyInput {\n crypto: EncryptionCrypto;\n}\n\nexport function generateRandomReceiverKey(\n input: RandomReceiverKeyInput,\n): ReceiverKeyPair {\n const seed = input.crypto.randomBytes(32);\n return input.crypto.x25519FromSeed(seed);\n}\n\nexport interface SignedReceiverKeyInput {\n crypto: EncryptionCrypto;\n signer: ReceiverKeySigner;\n networkId: string;\n /** Optional extra context (e.g. invocation nonce) folded into the message. */\n context?: string;\n}\n\n/**\n * Deterministic receiver-key derivation: signs a context string with\n * the supplied signer, then SHA-256s the signature bytes into the\n * x25519 seed.\n *\n * The context message is:\n * `tinycloud.encryption.receiver-key/v1:<networkId>:<context>`\n *\n * Callers MUST include unique context (e.g. a fresh nonce) on every\n * request unless they explicitly want reproducibility.\n */\nexport async function deriveSignedReceiverKey(\n input: SignedReceiverKeyInput,\n): Promise<ReceiverKeyPair> {\n const message = `tinycloud.encryption.receiver-key/v1:${input.networkId}:${input.context ?? \"\"}`;\n const sig = await input.signer.signMessage(message);\n // Treat the signature as opaque bytes; sha256 collapses to a 32-byte seed.\n const sigBytes = utf8Encode(sig);\n const seed = input.crypto.sha256(sigBytes);\n return input.crypto.x25519FromSeed(seed);\n}\n","/**\n * Decrypt-response verification.\n *\n * The node returns the unwrapped symmetric key re-encrypted to the\n * per-request receiver public key. Before the SDK uses the wrapped\n * key, it must:\n *\n * 1. Verify the node signature over the canonical response (excluding\n * the signature field).\n * 2. Recompute every binding hash and reject any mismatch.\n * 3. Confirm `targetNode`, `networkId`, `alg`, and `keyVersion` echo\n * what the SDK sent.\n *\n * After verification, the SDK opens `wrappedKey` with the per-request\n * receiver private key and uses the resulting symmetric key to\n * decrypt the inline envelope payload.\n */\n\nimport { base64Decode, canonicalize, hexEncode, utf8Encode } from \"./canonical\";\nimport {\n DECRYPT_RESULT_TYPE,\n encryptionError,\n type CanonicalJson,\n type DecryptInvocationFact,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n} from \"./types\";\n\n/**\n * Construct the canonical bytes that the node signed.\n *\n * The signature covers the response with `nodeSignature` removed. We\n * canonicalize and hash the same way the node does so the binding is\n * stable.\n */\nexport function canonicalSignedResponse(\n response: DecryptResponseBody,\n): string {\n // Strip the signature; canonicalize sorts keys for us.\n const { nodeSignature: _drop, ...rest } = response;\n return canonicalize(rest as unknown as CanonicalJson);\n}\n\nexport interface VerifyDecryptResponseInput {\n crypto: EncryptionCrypto;\n request: DecryptRequestBody;\n facts: DecryptInvocationFact;\n /** CID of the signed invocation that produced this response. */\n invocationCid: string;\n /** Hex bodyHash that was bound in `facts.bodyHash`. */\n requestBodyHash: string;\n response: DecryptResponseBody;\n}\n\n/**\n * Verify the node's decrypt response. Returns the response on success;\n * a structured error on signature, binding, or shape failure.\n */\nexport function verifyDecryptResponse(\n input: VerifyDecryptResponseInput,\n):\n | { ok: true; data: DecryptResponseBody }\n | { ok: false; error: EncryptionError } {\n const { crypto, request, facts, invocationCid, requestBodyHash, response } =\n input;\n\n if (response.type !== DECRYPT_RESULT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_RESPONSE\",\n message: `response.type must be ${DECRYPT_RESULT_TYPE}`,\n }),\n };\n }\n if (response.targetNode !== request.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"targetNode\",\n }),\n };\n }\n if (response.networkId !== request.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"networkId\",\n }),\n };\n }\n if (response.nodeId !== request.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"nodeId\",\n }),\n };\n }\n if (response.alg !== request.alg) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"alg\",\n }),\n };\n }\n if (response.keyVersion !== request.keyVersion) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"keyVersion\",\n }),\n };\n }\n if (\n response.encryptedSymmetricKeyHash !==\n request.encryptedSymmetricKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"encryptedSymmetricKeyHash\",\n }),\n };\n }\n if (response.receiverPublicKeyHash !== request.receiverPublicKeyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"receiverPublicKeyHash\",\n }),\n };\n }\n if (response.invocationCid !== invocationCid) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"invocationCid\",\n }),\n };\n }\n // requestHash binds invocationCid || requestBodyHash per spec. The `||`\n // notation is concatenation, not a literal delimiter.\n const expectedRequestHash = hexEncode(\n crypto.sha256(utf8Encode(`${invocationCid}${requestBodyHash}`)),\n );\n if (response.requestHash !== expectedRequestHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"requestHash\",\n }),\n };\n }\n // The facts must agree with the response (defensive: catches a node\n // that returns a fresh body bound to a different invocation).\n if (\n facts.encryptedSymmetricKeyHash !== response.encryptedSymmetricKeyHash ||\n facts.receiverPublicKeyHash !== response.receiverPublicKeyHash ||\n facts.networkId !== response.networkId ||\n facts.targetNode !== response.targetNode ||\n facts.alg !== response.alg ||\n facts.keyVersion !== response.keyVersion\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"facts\",\n }),\n };\n }\n\n const signedBytes = new TextEncoder().encode(\n canonicalSignedResponse(response),\n );\n const signatureBytes = base64Decode(response.nodeSignature);\n if (\n !crypto.verifyNodeSignature(response.nodeId, signedBytes, signatureBytes)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_SIGNATURE_INVALID\",\n }),\n };\n }\n return { ok: true, data: response };\n}\n\n/**\n * After verification, open the response's `wrappedKey` with the\n * per-request receiver private key and return the symmetric key.\n */\nexport function openWrappedKey(\n crypto: EncryptionCrypto,\n receiverPrivateKey: Uint8Array,\n response: DecryptResponseBody,\n): Uint8Array {\n const wrapped = base64Decode(response.wrappedKey);\n return crypto.openWithReceiverKey(receiverPrivateKey, wrapped);\n}\n","/**\n * EncryptionService — TinyCloud one-of-one encryption service.\n *\n * Responsibilities:\n * - Network discovery (`discoverNetwork`).\n * - Local envelope encryption (`encryptToNetwork`).\n * - Node-mediated decrypt with full request/response binding\n * verification (`decryptEnvelope`).\n *\n * Non-responsibilities:\n * - KV/SQL access. Callers fetch encrypted envelopes from their data\n * service of choice and pass them in.\n * - Network onboarding/ceremony. Those routes are node-only.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport { type Result } from \"../types\";\nimport {\n base64Decode,\n base64Encode,\n canonicalHashHex,\n} from \"./canonical\";\nimport {\n discoverNetwork as discoverNetworkFn,\n ensureNetworkUsableForDecrypt,\n type NodeDescriptorFetcher,\n type WellKnownDescriptorFetcher,\n} from \"./discovery\";\nimport {\n decryptEnvelopeWithKey,\n encryptToNetwork as encryptToNetworkFn,\n validateEnvelope,\n} from \"./envelope\";\nimport {\n buildCanonicalDecryptRequest,\n buildDecryptFacts,\n buildDecryptInvocation,\n} from \"./invocation\";\nimport { generateRandomReceiverKey } from \"./receiverKey\";\nimport {\n openWrappedKey,\n verifyDecryptResponse,\n} from \"./response\";\nimport { DecryptTransportResponseError } from \"@tinycloud/sdk-services/internal/decrypt-transport-response-error\";\nimport {\n DECRYPT_FACT_TYPE,\n encryptionError,\n type DecryptCapabilityProof,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n type InlineEncryptedEnvelope,\n type NetworkDescriptor,\n toError,\n} from \"./types\";\nimport type {\n EncryptToNetworkOptions,\n DecryptEnvelopeOptions,\n IEncryptionService,\n} from \"./IEncryptionService\";\n\n// Local Result helpers typed to EncryptionError. The shared `ok` / `err`\n// from `../types` default the error generic to `ServiceError`, which\n// widens our return-type inference here.\nfunction encOk<T>(data: T): Result<T, EncryptionError> {\n return { ok: true, data };\n}\nfunction encErr<T = never>(error: EncryptionError): Result<T, EncryptionError> {\n return { ok: false, error };\n}\n\n/**\n * Transport for posting decrypt requests to a TinyCloud node.\n *\n * Implementations supply the `Authorization` header (built by the\n * decrypt-invocation signer) and POST the canonical body. The\n * response body is JSON-decoded into a {@link DecryptResponseBody}.\n */\nexport interface DecryptTransport {\n postDecrypt(input: {\n targetNode: string;\n networkId: string;\n authorization: string;\n canonicalBody: string;\n signal?: AbortSignal;\n }): Promise<DecryptResponseBody>;\n}\n\nexport { DecryptTransportResponseError } from \"@tinycloud/sdk-services/internal/decrypt-transport-response-error\";\n\nexport interface EncryptionServiceConfig {\n crypto: EncryptionCrypto;\n signer: DecryptInvocationSigner;\n transport: DecryptTransport;\n node?: NodeDescriptorFetcher;\n wellKnown?: WellKnownDescriptorFetcher;\n /** Bound by an owning service graph to prevent cross-session authority use. */\n assertActive?: () => void;\n [key: string]: unknown;\n}\n\nexport class EncryptionService\n extends BaseService\n implements IEncryptionService\n{\n static readonly serviceName = \"encryption\";\n\n declare protected _config: EncryptionServiceConfig;\n\n constructor(config: EncryptionServiceConfig) {\n super();\n this._config = config;\n }\n\n get config(): EncryptionServiceConfig {\n return this._config;\n }\n\n private get crypto(): EncryptionCrypto {\n return this._config.crypto;\n }\n\n async discoverNetwork(\n identifier: string,\n ownerDid?: string,\n ): Promise<Result<NetworkDescriptor, EncryptionError>> {\n this.assertActive();\n const result = await discoverNetworkFn({\n identifier,\n ...(ownerDid !== undefined ? { ownerDid } : {}),\n ...(this._config.node !== undefined ? { node: this._config.node } : {}),\n ...(this._config.wellKnown !== undefined\n ? { wellKnown: this._config.wellKnown }\n : {}),\n });\n this.assertActive();\n if (!result.ok) return result;\n return encOk(result.data.descriptor);\n }\n\n async encryptToNetwork(\n networkId: string,\n plaintext: Uint8Array,\n options?: EncryptToNetworkOptions,\n ): Promise<Result<InlineEncryptedEnvelope, EncryptionError>> {\n try {\n this.assertActive();\n const discovered = await this.discoverNetwork(networkId);\n if (!discovered.ok) return discovered;\n const usable = ensureNetworkUsableForDecrypt(discovered.data);\n // For encryption we tolerate \"rotating\" but reject revoked/failed/pending —\n // ensureNetworkUsableForDecrypt enforces exactly that constraint.\n if (!usable.ok) return usable;\n\n const descriptor = usable.data;\n const networkPublicKey = base64Decode(descriptor.publicEncryptionKey);\n const result = encryptToNetworkFn(this.crypto, {\n // Discovery returns the node's canonical network identifier. Persist\n // that spelling in the envelope so a later response can be compared\n // byte-for-byte (notably for checksummed did:pkh principals).\n networkId: descriptor.networkId,\n networkPublicKey,\n plaintext,\n ...(options?.aad !== undefined ? { aad: options.aad } : {}),\n alg: options?.alg ?? descriptor.alg,\n keyVersion: options?.keyVersion ?? descriptor.keyVersion,\n ...(options?.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n return encOk(result.envelope);\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n }\n\n async decryptEnvelope(\n envelope: InlineEncryptedEnvelope,\n capabilityProof: DecryptCapabilityProof,\n options?: DecryptEnvelopeOptions,\n ): Promise<Result<Uint8Array, EncryptionError>> {\n try {\n this.assertActive();\n const validated = validateEnvelope(this.crypto, envelope);\n if (!validated.ok) return validated;\n if (\n options?.aad !== undefined &&\n validated.data.aad !== base64Encode(options.aad)\n ) {\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"decryptEnvelope aad does not match the envelope\",\n }),\n );\n }\n\n let descriptor: NetworkDescriptor;\n if (options?.descriptor !== undefined) {\n descriptor = options.descriptor;\n } else {\n const discovered = await this.discoverNetwork(envelope.networkId);\n if (!discovered.ok) return discovered;\n descriptor = discovered.data;\n }\n const usable = ensureNetworkUsableForDecrypt(descriptor);\n if (!usable.ok) return usable;\n\n const targetNode =\n options?.targetNode ?? descriptor.members[0]?.nodeId;\n if (targetNode === undefined) {\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"no target node available from descriptor\",\n }),\n );\n }\n\n // Generate per-request receiver key. We use the random mode by\n // default; callers wanting deterministic derivation must wrap\n // this service directly.\n const receiverKey = generateRandomReceiverKey({ crypto: this.crypto });\n const receiverPublicKey = base64Encode(receiverKey.publicKey);\n const receiverPublicKeyHash = canonicalHashHex(\n this.crypto.sha256,\n receiverPublicKey,\n );\n\n const body: DecryptRequestBody = {\n type: DECRYPT_FACT_TYPE,\n targetNode,\n networkId: envelope.networkId,\n alg: envelope.alg,\n keyVersion: envelope.keyVersion,\n encryptedSymmetricKey: envelope.encryptedSymmetricKey,\n encryptedSymmetricKeyHash: envelope.encryptedSymmetricKeyHash,\n receiverPublicKey,\n receiverPublicKeyHash,\n };\n const canonicalRequest = buildCanonicalDecryptRequest({\n crypto: this.crypto,\n body,\n receiverPublicKey: receiverKey.publicKey,\n });\n const facts = buildDecryptFacts({\n crypto: this.crypto,\n body,\n encryptedSymmetricKeyHash: envelope.encryptedSymmetricKeyHash,\n receiverPublicKey: receiverKey.publicKey,\n canonicalBody: canonicalRequest.canonicalBody,\n });\n\n const built = await buildDecryptInvocation(this.crypto, this._config.signer, {\n targetNode,\n networkId: envelope.networkId,\n body,\n facts,\n proof: capabilityProof,\n });\n this.assertActive();\n if (!built.ok) {\n if (built.error.code !== \"TRANSPORT_ERROR\") return built;\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"Unable to build decrypt request\",\n }),\n );\n }\n\n let response: DecryptResponseBody;\n try {\n response = await this._config.transport.postDecrypt({\n targetNode,\n networkId: envelope.networkId,\n authorization: built.data.authorization,\n canonicalBody: built.data.canonicalBody,\n signal: this.abortSignal,\n });\n this.assertActive();\n } catch (error) {\n if (error instanceof DecryptTransportResponseError) {\n return encErr(\n encryptionError(\n error.status === 401 || error.status === 403\n ? {\n code: \"DECRYPT_DENIED\",\n message: \"Node denied decrypt request\",\n ...(error.permissionHint === undefined\n ? {}\n : { permissionHint: error.permissionHint }),\n }\n : { code: \"INVALID_RESPONSE\", message: \"Node decrypt request failed\" },\n ),\n );\n }\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n\n const verified = verifyDecryptResponse({\n crypto: this.crypto,\n request: body,\n facts,\n invocationCid: built.data.invocationCid,\n requestBodyHash: facts.bodyHash,\n response,\n });\n if (!verified.ok) return verified;\n\n const symmetricKey = openWrappedKey(\n this.crypto,\n receiverKey.privateKey,\n verified.data,\n );\n const plaintext = decryptEnvelopeWithKey(\n this.crypto,\n envelope,\n symmetricKey,\n );\n return encOk(plaintext);\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"INVALID_RESPONSE\",\n message: \"Local decryption failed\",\n }),\n );\n }\n }\n\n private assertActive(): void {\n this._config.assertActive?.();\n }\n}\n","/**\n * TinyCloud encryption service exports.\n *\n * Reference architecture:\n * - Network ids: `urn:tinycloud:encryption:<ownerDid>:<network>`\n * - Inline envelopes: `{ v, networkId, alg, keyVersion,\n * encryptedSymmetricKey, encryptedSymmetricKeyHash, ciphertext, aad,\n * metadata }`\n * - Decrypt requests: UCAN-style invocations against a node + networkId.\n */\n\nexport {\n EncryptionService,\n} from \"./EncryptionService\";\n// The root and `/encryption` entrypoints both load this canonical CJS module.\n// That gives this public error normal class identity in CJS and ESM without a\n// mutable global registry or a forgeable structural marker.\nexport { DecryptTransportResponseError } from \"@tinycloud/sdk-services/internal/decrypt-transport-response-error\";\nexport type {\n DecryptTransport,\n EncryptionServiceConfig,\n} from \"./EncryptionService\";\nexport type {\n IEncryptionService,\n EncryptToNetworkOptions,\n DecryptEnvelopeOptions,\n} from \"./IEncryptionService\";\n\nexport {\n parseNetworkId,\n buildNetworkId,\n isNetworkId,\n networkDiscoveryKey,\n NetworkIdError,\n ENCRYPTION_NETWORK_URN_PREFIX,\n NETWORK_NAME_PATTERN,\n type ParsedNetworkId,\n} from \"./networkId\";\n\nexport {\n canonicalize,\n canonicalHashHex,\n hexEncode,\n hexDecode,\n base64Encode,\n base64Decode,\n utf8Encode,\n utf8Decode,\n type Json,\n} from \"./canonical\";\n\nexport {\n encryptToNetwork,\n decryptEnvelopeWithKey,\n validateEnvelope,\n type EncryptToNetworkInput,\n type EncryptToNetworkResult,\n} from \"./envelope\";\n\nexport {\n generateRandomReceiverKey,\n deriveSignedReceiverKey,\n type RandomReceiverKeyInput,\n type SignedReceiverKeyInput,\n} from \"./receiverKey\";\n\nexport {\n buildCanonicalDecryptRequest,\n buildDecryptFacts,\n buildDecryptAttenuation,\n buildDecryptInvocation,\n checkDecryptInvocationInput,\n DECRYPT_ACTION,\n ENCRYPTION_SERVICE,\n type CanonicalDecryptRequest,\n type BuildCanonicalDecryptRequestInput,\n type BuildDecryptFactsInput,\n} from \"./invocation\";\n\nexport {\n verifyDecryptResponse,\n canonicalSignedResponse,\n openWrappedKey,\n type VerifyDecryptResponseInput,\n} from \"./response\";\n\nexport {\n discoverNetwork,\n ensureNetworkUsableForDecrypt,\n type DiscoverNetworkInput,\n type DiscoveredNetwork,\n type DiscoverySource,\n type NodeDescriptorFetcher,\n type WellKnownDescriptorFetcher,\n} from \"./discovery\";\n\nexport {\n DEFAULT_ENCRYPTION_ALG,\n ENVELOPE_VERSION,\n DEFAULT_KEY_VERSION,\n DECRYPT_FACT_TYPE,\n DECRYPT_RESULT_TYPE,\n ENCRYPTION_SERVICE_SHORT,\n encryptionError,\n type BuildDecryptInvocationInput,\n type BuiltDecryptInvocation,\n type CanonicalJson,\n type DecryptCapabilityProof,\n type DecryptInvocationFact,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n type EncryptionErrorInput,\n type InlineEncryptedEnvelope,\n type NetworkDescriptor,\n type ReceiverKeyPair,\n type ReceiverKeySigner,\n} from \"./types\";\n"],"mappings":"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","names":["base64Decode","base64Encode","hexEncode","ok","serviceError","headers","errorText","import_bootstrap","import_bootstrap","valueDelResult","hexEncode","base64Encode","base64Decode","toError","err","crypto","base64Encode","err","base64Decode","hexEncode","crypto","err","crypto","hexEncode","base64Decode","import_decrypt_transport_response_error","identifier","base64Decode","toError","base64Encode","import_decrypt_transport_response_error"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/diagnostics.ts","../src/debug.ts","../src/types.schema.ts","../src/context.ts","../src/errors.ts","../src/encryption/networkId.ts","../src/base/BaseService.ts","../src/kv/PrefixedKVService.ts","../src/kv/types.ts","../src/kv/KVService.ts","../src/responseErrors.ts","../src/sql/SQLMigrations.ts","../src/sql/DatabaseHandle.ts","../src/sql/types.ts","../src/sql/SQLService.ts","../src/duckdb/DuckDbDatabaseHandle.ts","../src/duckdb/types.ts","../src/duckdb/DuckDbService.ts","../src/hooks/HooksService.ts","../src/quota/TinyCloudQuota.ts","../src/vault/types.ts","../src/vault/SignatureCache.ts","../src/vault/DataVaultService.ts","../src/vault/createVaultCrypto.ts","../src/secrets/paths.ts","../src/secrets/SecretsService.ts","../src/encryption/canonical.ts","../src/encryption/types.ts","../src/encryption/discovery.ts","../src/encryption/envelope.ts","../src/encryption/invocation.ts","../src/encryption/receiverKey.ts","../src/encryption/response.ts","../src/encryption/EncryptionService.ts","../src/encryption/index.ts"],"sourcesContent":["/**\n * TinyCloud SDK Services\n *\n * Platform-agnostic services with plugin architecture for TinyCloud.\n *\n * @packageDocumentation\n * @module @tinycloud/sdk-services\n *\n * @example\n * ```typescript\n * import {\n * ServiceContext,\n * BaseService,\n * Result,\n * ErrorCodes,\n * } from '@tinycloud/sdk-services';\n *\n * // Create a context\n * const context = new ServiceContext({\n * invoke: wasmInvoke,\n * hosts: ['https://node.tinycloud.xyz'],\n * });\n *\n * // Create and register a service\n * const kv = new KVService({ prefix: 'myapp' });\n * context.registerService('kv', kv);\n * kv.initialize(context);\n *\n * // Use the service\n * const result = await kv.get('key');\n * if (result.ok) {\n * console.log(result.data);\n * }\n * ```\n */\n\n// Core types\nexport type {\n Result,\n ServiceError,\n PermissionHint,\n StorageQuotaInfo,\n ErrorCode,\n IServiceContext,\n IService,\n ServiceSession,\n RetryPolicy,\n InvokeFunction,\n InvokeAnyFunction,\n InvokeAnyEntry,\n InvocationFact,\n InvocationFacts,\n FetchFunction,\n FetchRequestInit,\n FetchResponse,\n ServiceHeaders,\n EventHandler,\n TelemetryConfig,\n TelemetryEventHandler,\n ServiceRequestEvent,\n ServiceResponseEvent,\n ServiceErrorEvent,\n ServiceRetryEvent,\n TelemetrySpanEvent,\n} from \"./types\";\n\nexport {\n ErrorCodes,\n defaultRetryPolicy,\n TelemetryEvents,\n ok,\n err,\n serviceError,\n} from \"./types\";\n\nexport {\n TinyCloudDebugLogger,\n tinyCloudDebugLogger,\n enableTinyCloudDebug,\n disableTinyCloudDebug,\n getTinyCloudDebugLogs,\n clearTinyCloudDebugLogs,\n installTinyCloudDebugGlobals,\n} from \"./debug\";\nexport type {\n TinyCloudDebugEvent,\n TinyCloudDebugLevel,\n TinyCloudDebugEnableOptions,\n TinyCloudDebugTimer,\n} from \"./debug\";\n\n// Zod schemas and validation\nexport {\n // Schemas\n ServiceErrorSchema,\n KVResponseHeadersSchema,\n KVListResponseSchema,\n ServiceRequestEventSchema,\n ServiceResponseEventSchema,\n ServiceErrorEventSchema,\n ServiceRetryEventSchema,\n TelemetrySpanEventSchema,\n RetryPolicySchema,\n ServiceSessionSchema,\n GenericResultSchema,\n GenericKVResponseSchema,\n KVListResultSchema,\n // Schema factories\n createResultSchema,\n createKVResponseSchema,\n // Validation functions\n validateServiceError,\n validateKVListResponse,\n validateKVResponseHeaders,\n validateServiceSession,\n validateRetryPolicy,\n validateServiceRequestEvent,\n validateServiceResponseEvent,\n validateTelemetrySpanEvent,\n} from \"./types.schema\";\n\nexport type {\n // Inferred types from schemas\n ValidationError,\n ServiceErrorType,\n KVResponseHeadersType,\n KVListResponseType,\n GenericKVResponseType,\n KVListResultType,\n ServiceRequestEventType,\n ServiceResponseEventType,\n ServiceErrorEventType,\n ServiceRetryEventType,\n TelemetrySpanEventType,\n RetryPolicyType,\n ServiceSessionType,\n} from \"./types.schema\";\n\n// Context\nexport { ServiceContext } from \"./context\";\nexport type { ServiceContextConfig } from \"./context\";\n\n// Errors\nexport {\n authRequiredError,\n authExpiredError,\n networkError,\n timeoutError,\n abortedError,\n notFoundError,\n permissionDeniedError,\n wrapError,\n errorResult,\n storageQuotaExceededError,\n storageLimitReachedError,\n storageRejectionError,\n parseStorageQuotaBytes,\n isStorageFullError,\n STORAGE_FULL_MESSAGE,\n STORAGE_WRITE_TOO_LARGE_MESSAGE,\n parseAuthError,\n authUnauthorizedError,\n authorizationVerdictOf,\n validatedCapabilityOf,\n parseCapabilityResource,\n type AuthorizationVerdict,\n parsePermissionHint,\n parsePermissionHintFromErrorText,\n} from \"./errors\";\n\n// Base service\nexport { BaseService } from \"./base/index\";\nexport type {\n ServiceConstructor,\n ServiceRegistration,\n BaseServiceOptions,\n RequestSignal,\n} from \"./base/index\";\n\n// KV service\nexport {\n DEFAULT_SIGNED_READ_URL_EXPIRY_MS,\n KVService,\n PrefixedKVService,\n IKVService,\n KVAction,\n} from \"./kv\";\nexport type {\n IPrefixedKVService,\n KVServiceConfig,\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVBatchReadResponse,\n KVListOptions,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVSignedReadUrlResponse,\n KVChange,\n KVChangesAuthority,\n KVChangesOptions,\n KVChangesResponse,\n KVResponseHeaders,\n KVActionType,\n} from \"./kv\";\n\n// SQL service\nexport { SQLService, DatabaseHandle, SQLMigrations, SQLAction } from \"./sql\";\nexport type { ISQLService, IDatabaseHandle, ISQLMigrations } from \"./sql\";\nexport type {\n SQLServiceConfig,\n QueryOptions,\n ExecuteOptions,\n BatchOptions,\n SqlValue,\n SqlStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n SqlMigration,\n SqlMigrationApplyOptions,\n SqlMigrationApplyResponse,\n SQLActionType,\n} from \"./sql\";\n\n// DuckDB service\nexport { DuckDbService, DuckDbDatabaseHandle, DuckDbAction } from \"./duckdb\";\nexport type { IDuckDbService, IDuckDbDatabaseHandle } from \"./duckdb\";\nexport type {\n DuckDbServiceConfig,\n DuckDbQueryOptions,\n DuckDbExecuteOptions,\n DuckDbBatchOptions,\n DuckDbOptions,\n DuckDbValue,\n DuckDbStatement,\n DuckDbQueryResponse,\n DuckDbExecuteResponse,\n DuckDbBatchResponse,\n DuckDbActionType,\n SchemaInfo,\n TableInfo,\n ColumnInfo,\n ViewInfo,\n} from \"./duckdb\";\n\n// Hooks service\nexport { HooksService } from \"./hooks\";\nexport type {\n IHooksService,\n HookServiceName,\n HookSubscription,\n HookEvent,\n HookStreamEvent,\n HookWebhookScope,\n HookWebhookRegistration,\n HookWebhookRecord,\n HookWebhookListOptions,\n HookWebhookUnregisterOptions,\n SubscribeOptions,\n HooksServiceConfig,\n HookStreamRetryConfig,\n} from \"./hooks\";\n\n// Quota\nexport { TinyCloudQuota } from \"./quota\";\nexport type { QuotaConfig, QuotaStatus } from \"./quota\";\n\n// Vault service\nexport {\n DataVaultService,\n VaultHeaders,\n VaultPublicSpaceKVActions,\n createVaultCrypto,\n} from \"./vault\";\nexport type {\n IDataVaultService,\n VaultCrypto,\n WasmVaultFunctions,\n} from \"./vault\";\nexport type {\n DataVaultConfig,\n VaultPutOptions,\n VaultGetOptions,\n VaultListOptions,\n VaultListPage,\n VaultGrantOptions,\n VaultEntry,\n VaultNetworkReadResult,\n VaultError,\n} from \"./vault\";\n\nexport {\n SecretsService,\n SECRET_NAME_RE,\n canonicalizeSecretScope,\n parseSecretCatalogKey,\n resolveSecretListPrefix,\n resolveSecretPath,\n} from \"./secrets\";\nexport type {\n ISecretsService,\n SecretCatalogEntry,\n SecretPayload,\n SecretsError,\n ParsedSecretCatalogKey,\n ResolvedSecretPath,\n SecretScopeOptions,\n} from \"./secrets\";\n\n// Encryption service (network-scoped one-of-one decrypt)\nexport {\n EncryptionService,\n DecryptTransportResponseError,\n parseNetworkId,\n buildNetworkId,\n isNetworkId,\n networkDiscoveryKey,\n NetworkIdError,\n ENCRYPTION_NETWORK_URN_PREFIX,\n NETWORK_NAME_PATTERN,\n canonicalize as canonicalizeEncryptionJson,\n canonicalHashHex,\n hexEncode,\n hexDecode,\n base64Encode,\n base64Decode,\n utf8Encode,\n utf8Decode,\n encryptToNetwork,\n decryptEnvelopeWithKey,\n validateEnvelope,\n generateRandomReceiverKey,\n deriveSignedReceiverKey,\n buildCanonicalDecryptRequest,\n buildDecryptFacts,\n buildDecryptAttenuation,\n buildDecryptInvocation,\n checkDecryptInvocationInput,\n verifyDecryptResponse,\n canonicalSignedResponse,\n openWrappedKey,\n discoverNetwork,\n ensureNetworkUsableForDecrypt,\n DEFAULT_ENCRYPTION_ALG,\n ENVELOPE_VERSION,\n DEFAULT_KEY_VERSION,\n DECRYPT_FACT_TYPE,\n DECRYPT_RESULT_TYPE,\n DECRYPT_ACTION,\n ENCRYPTION_SERVICE,\n ENCRYPTION_SERVICE_SHORT,\n encryptionError,\n} from \"./encryption\";\nexport type {\n IEncryptionService,\n EncryptionServiceConfig,\n DecryptTransport,\n EncryptToNetworkOptions,\n DecryptEnvelopeOptions,\n ParsedNetworkId,\n BuildDecryptInvocationInput,\n BuiltDecryptInvocation,\n CanonicalJson,\n DecryptCapabilityProof,\n DecryptInvocationFact,\n DecryptInvocationSigner,\n DecryptRequestBody,\n DecryptResponseBody,\n EncryptionCrypto,\n EncryptionError,\n EncryptionErrorInput,\n InlineEncryptedEnvelope,\n NetworkDescriptor,\n ReceiverKeyPair,\n ReceiverKeySigner,\n EncryptToNetworkInput,\n EncryptToNetworkResult,\n CanonicalDecryptRequest,\n BuildCanonicalDecryptRequestInput,\n BuildDecryptFactsInput,\n RandomReceiverKeyInput,\n SignedReceiverKeyInput,\n VerifyDecryptResponseInput,\n DiscoverNetworkInput,\n DiscoveredNetwork,\n DiscoverySource,\n NodeDescriptorFetcher,\n WellKnownDescriptorFetcher,\n Json,\n} from \"./encryption\";\n","/**\n * SDK Services - Core Types\n *\n * These types define the service architecture for TinyCloud SDK.\n * Services use dependency injection via IServiceContext for platform independence.\n */\n\n// =============================================================================\n// Result Type Pattern\n// =============================================================================\n\n/**\n * Result type for service operations.\n * Services return Result instead of throwing, making error handling explicit.\n *\n * @template T - The success data type\n * @template E - The error type (defaults to ServiceError)\n *\n * @example\n * ```typescript\n * const result = await kv.get('key');\n * if (result.ok) {\n * console.log(result.data);\n * } else {\n * console.error(result.error.code);\n * }\n * ```\n */\nexport type Result<T, E = ServiceError> =\n | { ok: true; data: T }\n | { ok: false; error: E };\n\n/**\n * Service error with structured information.\n */\nexport interface ServiceError {\n /** Error code for programmatic handling (e.g., 'KV_NOT_FOUND', 'AUTH_EXPIRED') */\n code: string;\n /** Human-readable error message */\n message: string;\n /** Service that produced the error (e.g., 'kv', 'sql') */\n service: string;\n /** Original error if this wraps another error */\n cause?: Error;\n /** Additional metadata about the error */\n meta?: Record<string, unknown>;\n}\n\n/**\n * A node-supplied permission hint after strict SDK validation. This is\n * deliberately narrower than a general capability: no wildcards, caveats,\n * descriptions, or transport metadata can cross the service boundary.\n */\nexport interface PermissionHint {\n readonly service: \"tinycloud.kv\" | \"tinycloud.encryption\";\n readonly space?: string;\n readonly path: string;\n readonly actions: readonly string[];\n}\n\n/**\n * Storage quota information returned with quota-related errors.\n */\nexport interface StorageQuotaInfo {\n usedBytes: number;\n limitBytes: number;\n service: string;\n}\n\n/**\n * Standard error codes used across services.\n */\nexport const ErrorCodes = {\n // Common errors\n NOT_FOUND: \"NOT_FOUND\",\n AUTH_EXPIRED: \"AUTH_EXPIRED\",\n AUTH_REQUIRED: \"AUTH_REQUIRED\",\n AUTH_UNAUTHORIZED: \"AUTH_UNAUTHORIZED\",\n /** HTTP 401: the delegation the invocation cites was revoked. */\n AUTH_DELEGATION_REVOKED: \"AUTH_DELEGATION_REVOKED\",\n /** HTTP 401: a delegation the cited one rests on was revoked. */\n AUTH_DELEGATION_ANCESTOR_REVOKED: \"AUTH_DELEGATION_ANCESTOR_REVOKED\",\n NETWORK_ERROR: \"NETWORK_ERROR\",\n TIMEOUT: \"TIMEOUT\",\n ABORTED: \"ABORTED\",\n INVALID_INPUT: \"INVALID_INPUT\",\n PERMISSION_DENIED: \"PERMISSION_DENIED\",\n\n // KV-specific errors\n KV_NOT_FOUND: \"KV_NOT_FOUND\",\n KV_WRITE_FAILED: \"KV_WRITE_FAILED\",\n KV_PRECONDITION_FAILED: \"KV_PRECONDITION_FAILED\",\n KV_CONFLICT: \"KV_CONFLICT\",\n KV_RESPONSE_TOO_LARGE: \"KV_RESPONSE_TOO_LARGE\",\n /** HTTP 410 from the change feed: discard sync state and restart without a cursor; `meta.reason` says why. */\n KV_SYNC_RESET_REQUIRED: \"KV_SYNC_RESET_REQUIRED\",\n /** HTTP 403 from the change feed: the retention grant was refused; `meta.reason` says why. */\n KV_RETENTION_GRANT_REFUSED: \"KV_RETENTION_GRANT_REFUSED\",\n\n // SQL-specific errors\n SQL_ERROR: \"SQL_ERROR\",\n SQL_PERMISSION_DENIED: \"SQL_PERMISSION_DENIED\",\n SQL_DATABASE_NOT_FOUND: \"SQL_DATABASE_NOT_FOUND\",\n SQL_RESPONSE_TOO_LARGE: \"SQL_RESPONSE_TOO_LARGE\",\n SQL_QUOTA_EXCEEDED: \"SQL_QUOTA_EXCEEDED\",\n SQL_INVALID_STATEMENT: \"SQL_INVALID_STATEMENT\",\n SQL_SCHEMA_ERROR: \"SQL_SCHEMA_ERROR\",\n SQL_READONLY_VIOLATION: \"SQL_READONLY_VIOLATION\",\n\n // Storage quota errors\n STORAGE_QUOTA_EXCEEDED: \"STORAGE_QUOTA_EXCEEDED\",\n STORAGE_LIMIT_REACHED: \"STORAGE_LIMIT_REACHED\",\n\n // DuckDB-specific errors\n DUCKDB_ERROR: \"DUCKDB_ERROR\",\n DUCKDB_PERMISSION_DENIED: \"DUCKDB_PERMISSION_DENIED\",\n DUCKDB_DATABASE_NOT_FOUND: \"DUCKDB_DATABASE_NOT_FOUND\",\n DUCKDB_RESPONSE_TOO_LARGE: \"DUCKDB_RESPONSE_TOO_LARGE\",\n DUCKDB_QUOTA_EXCEEDED: \"DUCKDB_QUOTA_EXCEEDED\",\n DUCKDB_INVALID_STATEMENT: \"DUCKDB_INVALID_STATEMENT\",\n DUCKDB_SCHEMA_ERROR: \"DUCKDB_SCHEMA_ERROR\",\n DUCKDB_READONLY_VIOLATION: \"DUCKDB_READONLY_VIOLATION\",\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\n// =============================================================================\n// Service Session\n// =============================================================================\n\n/**\n * Session data required for authenticated service operations.\n * Both TinyCloudSession and web-sdk Session can be cast to this interface.\n */\nexport interface ServiceSession {\n /** The delegation header containing the UCAN */\n delegationHeader: { Authorization: string };\n /** The delegation CID */\n delegationCid: string;\n /** The space ID for this session */\n spaceId: string;\n /** The verification method DID */\n verificationMethod: string;\n /** The session key JWK (required for invoke) */\n jwk: object;\n}\n\n// =============================================================================\n// Platform Dependencies (Injected)\n// =============================================================================\n\n/**\n * Headers type - compatible with both browser and Node.js.\n */\nexport type ServiceHeaders = Record<string, string> | [string, string][];\n\n/**\n * A single fact object to include in the UCAN invocation.\n * Facts are key-value objects that the server reads from the UCAN facts field.\n */\nexport interface InvocationFact {\n [key: string]: unknown;\n}\n\n/**\n * Facts to include in the UCAN invocation.\n * This is an array of fact objects per the UCAN spec.\n * Used to pass additional parameters that the server reads from the UCAN facts field.\n */\nexport type InvocationFacts = InvocationFact[];\n\n/**\n * Invoke function signature - platform-specific implementation injected via DI.\n * Both node-sdk-wasm and web-sdk-wasm export this with identical signature.\n *\n * @param session - The service session with delegation data\n * @param service - Service name (e.g., \"kv\")\n * @param path - Resource path or key\n * @param action - Action to perform (e.g., \"tinycloud.kv/get\")\n * @param facts - Optional facts to include in the UCAN (e.g., for capabilities/read params)\n * @returns Headers to include in the request\n */\nexport type InvokeFunction = (\n session: ServiceSession,\n service: string,\n path: string,\n action: string,\n facts?: InvocationFacts,\n) => ServiceHeaders;\n\n/**\n * Multi-resource invocation entry.\n */\nexport interface InvokeAnyEntry {\n /**\n * Legacy space-scoped resource. Optional when `resource` is provided.\n */\n spaceId?: string;\n service: string;\n path: string;\n action: string;\n /** Optional raw resource URI. When set, WASM signs this URI directly. */\n resource?: string;\n /** Capability caveats that must remain on this invocation attenuation. */\n caveats?: Record<string, unknown>[];\n}\n\n/**\n * Invoke function for minting a single authorization header that covers\n * multiple capabilities across one effective invoker.\n */\nexport type InvokeAnyFunction = (\n session: ServiceSession,\n entries: InvokeAnyEntry[],\n facts?: InvocationFacts,\n) => ServiceHeaders;\n\n/**\n * Fetch request options - compatible with standard fetch API.\n */\nexport interface FetchRequestInit {\n method?: string;\n headers?: ServiceHeaders;\n body?: Blob | FormData | string;\n signal?: AbortSignal;\n redirect?: \"error\";\n}\n\n/**\n * Fetch response interface - compatible with standard Response.\n */\nexport interface FetchResponse {\n ok: boolean;\n status: number;\n statusText: string;\n body?: unknown;\n headers: {\n get(name: string): string | null;\n };\n json(): Promise<unknown>;\n text(): Promise<string>;\n arrayBuffer(): Promise<ArrayBuffer>;\n blob(): Promise<Blob>;\n}\n\n/**\n * Fetch function signature - allows for custom fetch implementations.\n * Compatible with both browser fetch and Node.js fetch.\n */\nexport type FetchFunction = (\n url: string,\n init?: FetchRequestInit,\n) => Promise<FetchResponse>;\n\n// =============================================================================\n// Retry Policy\n// =============================================================================\n\n/**\n * Configuration for automatic retry of failed requests.\n */\nexport interface RetryPolicy {\n /** Maximum number of attempts (including initial) */\n maxAttempts: number;\n /** Backoff strategy between retries */\n backoff: \"none\" | \"linear\" | \"exponential\";\n /** Base delay in milliseconds for backoff calculation */\n baseDelayMs: number;\n /** Maximum delay in milliseconds between retries */\n maxDelayMs: number;\n /** Error codes that should trigger a retry */\n retryableErrors: string[];\n}\n\n/**\n * Default retry policy.\n */\nexport const defaultRetryPolicy: RetryPolicy = {\n maxAttempts: 3,\n backoff: \"exponential\",\n baseDelayMs: 1000,\n maxDelayMs: 10000,\n retryableErrors: [ErrorCodes.NETWORK_ERROR, ErrorCodes.TIMEOUT],\n};\n\n// =============================================================================\n// Service Context\n// =============================================================================\n\n/**\n * Event handler function type.\n */\nexport type EventHandler = (data: unknown) => void;\n\n/**\n * SDK telemetry event handler.\n */\nexport type TelemetryEventHandler = (event: string, data: unknown) => void;\n\n/**\n * Default-off telemetry configuration.\n */\nexport type TelemetryConfig =\n | boolean\n | {\n enabled?: boolean;\n onEvent?: TelemetryEventHandler;\n };\n\n/**\n * Service interface - base contract for all services.\n */\nexport interface IService {\n /** Initialize service with context */\n initialize(context: IServiceContext): void;\n\n /** Called when session changes (sign-in, sign-out, refresh) */\n onSessionChange(session: ServiceSession | null): void;\n\n /** Called when SDK signs out - should abort pending operations */\n onSignOut(): void;\n\n /** Service-specific configuration */\n readonly config: Record<string, unknown>;\n}\n\n/**\n * Context provided to services for accessing platform dependencies.\n * The SDK creates this context and passes it to services during initialization.\n */\nexport interface IServiceContext {\n // Session management\n /** Current active session, or null if not authenticated */\n readonly session: ServiceSession | null;\n /** Whether there is an active authenticated session */\n readonly isAuthenticated: boolean;\n\n // Platform dependencies (injected by SDK)\n /** Platform-specific invoke function from WASM binding */\n readonly invoke: InvokeFunction;\n /** Optional multi-resource invoke function */\n readonly invokeAny?: InvokeAnyFunction;\n /** Fetch function (defaults to globalThis.fetch) */\n readonly fetch: FetchFunction;\n /** Available TinyCloud host URLs */\n readonly hosts: string[];\n\n // Cross-service access\n /** Get another registered service by name */\n getService<T extends IService>(name: string): T | undefined;\n\n // Telemetry/Events\n /** Emit a telemetry event */\n emit(event: string, data: unknown): void;\n /** Subscribe to events */\n on(event: string, handler: EventHandler): () => void;\n\n // Lifecycle\n /** Abort signal that fires when SDK signs out */\n readonly abortSignal: AbortSignal;\n\n // Retry policy\n /** Retry policy for failed requests */\n readonly retryPolicy: RetryPolicy;\n}\n\n// =============================================================================\n// Telemetry Events\n// =============================================================================\n\n/**\n * Event emitted before a service request.\n */\nexport interface ServiceRequestEvent {\n service: string;\n action: string;\n span?: string;\n key?: string;\n timestamp: number;\n}\n\n/**\n * Event emitted after a service response.\n */\nexport interface ServiceResponseEvent {\n service: string;\n action: string;\n span?: string;\n ok: boolean;\n duration: number;\n durationMs?: number;\n status?: number;\n}\n\n/**\n * Event emitted on service error.\n */\nexport interface ServiceErrorEvent {\n service: string;\n span?: string;\n error: ServiceError;\n}\n\n/**\n * Event emitted on retry attempt.\n */\nexport interface ServiceRetryEvent {\n service: string;\n attempt: number;\n maxAttempts: number;\n error: ServiceError;\n}\n\n/**\n * Generic named span event for aggregating operation timings.\n */\nexport interface TelemetrySpanEvent {\n span: string;\n ok: boolean;\n durationMs: number;\n service?: string;\n action?: string;\n status?: number;\n error?: ServiceError;\n}\n\n/**\n * Telemetry event names.\n */\nexport const TelemetryEvents = {\n SPAN: \"telemetry.span\",\n SERVICE_REQUEST: \"service.request\",\n SERVICE_RESPONSE: \"service.response\",\n SERVICE_ERROR: \"service.error\",\n SERVICE_RETRY: \"service.retry\",\n SESSION_CHANGED: \"session.changed\",\n SESSION_EXPIRED: \"session.expired\",\n} as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Create a success result.\n */\nexport function ok<T>(data: T): Result<T> {\n return { ok: true, data };\n}\n\n/**\n * Create an error result.\n */\nexport function err<E = ServiceError>(error: E): Result<never, E> {\n return { ok: false, error };\n}\n\n/**\n * Create a ServiceError.\n */\nexport function serviceError(\n code: string,\n message: string,\n service: string,\n options?: { cause?: Error; meta?: Record<string, unknown> },\n): ServiceError {\n return {\n code,\n message,\n service,\n cause: options?.cause,\n meta: options?.meta,\n };\n}\n","/** Safe projections for diagnostic sinks. */\n\nconst REDACTED = \"[REDACTED]\";\nconst SAFE_NUMBER_FIELDS = new Set([\n \"duration\",\n \"durationMs\",\n \"endedAt\",\n \"startedAt\",\n \"status\",\n \"timestamp\",\n]);\nconst SAFE_BOOLEAN_FIELDS = new Set([\"authenticated\", \"ok\", \"persisted\"]);\n\nfunction finiteNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction isBinaryData(value: object): boolean {\n try {\n return (\n Array.isArray(value) ||\n ArrayBuffer.isView(value) ||\n value instanceof ArrayBuffer\n );\n } catch {\n // A revoked Proxy can throw while checking its shape. It is not diagnostic\n // data and must not prevent the SDK operation that emitted it.\n return true;\n }\n}\n\nfunction read(value: object, key: string): unknown {\n try {\n return (value as Record<string, unknown>)[key];\n } catch {\n return REDACTED;\n }\n}\n\n/** Return only stable, non-sensitive error diagnostics. */\nexport function projectDiagnosticError(error: unknown): Record<string, unknown> {\n if (typeof error !== \"object\" || error === null) return {};\n\n const status = finiteNumber(read(error, \"status\"));\n return status !== undefined && status >= 100 && status <= 599 ? { status } : {};\n}\n\n/**\n * Copy only fixed scalar metrics and URL origins. Diagnostic payloads can be\n * supplied by applications and nodes, so strings, nested values, and unknown\n * fields are never projected to debug or telemetry sinks.\n */\nexport function projectDiagnosticData(value: unknown): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value !== \"object\") return REDACTED;\n\n try {\n if (isBinaryData(value)) return REDACTED;\n\n const projected: Record<string, unknown> = {};\n for (const key of SAFE_NUMBER_FIELDS) {\n const number = finiteNumber(read(value, key));\n if (number !== undefined) projected[key] = number;\n }\n for (const key of SAFE_BOOLEAN_FIELDS) {\n const boolean = read(value, key);\n if (typeof boolean === \"boolean\") projected[key] = boolean;\n }\n\n // URLs, like every other string-bearing value, are never projected. Even\n // an origin can encode user-controlled data in a hostname.\n const url = read(value, \"url\");\n if (url !== undefined) projected.url = REDACTED;\n\n const error = read(value, \"error\");\n if (error !== undefined) projected.error = projectDiagnosticError(error);\n\n return projected;\n } catch {\n // Projection is best-effort only. Hostile Proxy traps and exotic objects\n // must never block telemetry, debug logging, or ordinary subscribers.\n return REDACTED;\n }\n}\n","import { projectDiagnosticData } from \"./diagnostics\";\n\nexport type TinyCloudDebugLevel = \"debug\";\n\nexport interface TinyCloudDebugEvent {\n sequence: number;\n timestamp: number;\n timestampIso: string;\n level: TinyCloudDebugLevel;\n event: string;\n message?: string;\n data?: unknown;\n durationMs?: number;\n startedAt?: number;\n endedAt?: number;\n}\n\nexport interface TinyCloudDebugEnableOptions {\n /**\n * Persist the debug flag in browser localStorage. Defaults to true.\n * Node runtimes intentionally do not persist this setting.\n */\n persist?: boolean;\n}\n\nexport interface TinyCloudDebugTimer {\n stop: (data?: unknown) => TinyCloudDebugEvent | undefined;\n}\n\ntype TinyCloudDebugGlobal = typeof globalThis & {\n TinyCloud_debug?: boolean | string;\n TinyCloudDebug?: TinyCloudDebugLogger;\n window?: unknown;\n enableTinyCloudDebug?: typeof enableTinyCloudDebug;\n disableTinyCloudDebug?: typeof disableTinyCloudDebug;\n getTinyCloudDebugLogs?: typeof getTinyCloudDebugLogs;\n clearTinyCloudDebugLogs?: typeof clearTinyCloudDebugLogs;\n};\n\ninterface TinyCloudDebugStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\nconst DEBUG_FLAG = \"TinyCloud_debug\";\nconst MAX_EVENTS = 1000;\n\nfunction getGlobal(): TinyCloudDebugGlobal {\n return globalThis as TinyCloudDebugGlobal;\n}\n\nfunction nowMs(): number {\n const performanceNow = globalThis.performance?.now?.bind(globalThis.performance);\n return typeof performanceNow === \"function\" ? performanceNow() : Date.now();\n}\n\nfunction isTrue(value: unknown): boolean {\n return value === true || value === \"true\" || value === \"1\";\n}\n\nfunction getProcessDebugFlag(): unknown {\n const processLike = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n return processLike?.env?.[DEBUG_FLAG];\n}\n\nfunction isBrowserWindow(): boolean {\n const global = getGlobal();\n return global.window === globalThis;\n}\n\nfunction getLocalStorage(): TinyCloudDebugStorage | undefined {\n if (!isBrowserWindow()) {\n return undefined;\n }\n\n try {\n return (globalThis as typeof globalThis & { localStorage?: TinyCloudDebugStorage }).localStorage;\n } catch {\n return undefined;\n }\n}\n\nfunction getStoredDebugFlag(): unknown {\n const storage = getLocalStorage();\n if (!storage) {\n return undefined;\n }\n\n try {\n return storage.getItem(DEBUG_FLAG);\n } catch {\n return undefined;\n }\n}\n\nfunction setStoredDebugFlag(enabled: boolean): void {\n const storage = getLocalStorage();\n if (!storage) {\n return;\n }\n\n try {\n if (enabled) {\n storage.setItem(DEBUG_FLAG, \"true\");\n } else {\n storage.removeItem(DEBUG_FLAG);\n }\n } catch {\n // localStorage can be unavailable in private browsing or restricted contexts.\n }\n}\n\nfunction shouldStartEnabled(): boolean {\n const global = getGlobal();\n return (\n isTrue(global[DEBUG_FLAG]) ||\n isTrue(getStoredDebugFlag()) ||\n isTrue(getProcessDebugFlag())\n );\n}\n\nexport class TinyCloudDebugLogger {\n private enabled: boolean = shouldStartEnabled();\n private sequence: number = 0;\n private events: TinyCloudDebugEvent[] = [];\n private maxEvents: number = MAX_EVENTS;\n\n isEnabled(): boolean {\n return (\n this.enabled ||\n isTrue(getGlobal()[DEBUG_FLAG]) ||\n isTrue(getProcessDebugFlag())\n );\n }\n\n enable(options: TinyCloudDebugEnableOptions = {}): void {\n this.enabled = true;\n getGlobal()[DEBUG_FLAG] = true;\n\n if (options.persist !== false) {\n setStoredDebugFlag(true);\n }\n\n this.log(\"debug.enabled\", { persisted: options.persist !== false });\n }\n\n disable(options: TinyCloudDebugEnableOptions = {}): void {\n this.log(\"debug.disabled\", { persisted: options.persist !== false });\n this.enabled = false;\n getGlobal()[DEBUG_FLAG] = false;\n\n if (options.persist !== false) {\n setStoredDebugFlag(false);\n }\n }\n\n clear(): void {\n this.events = [];\n }\n\n getLogs(): TinyCloudDebugEvent[] {\n return [...this.events];\n }\n\n log(event: string, data?: unknown, message?: string): TinyCloudDebugEvent | undefined {\n if (!this.isEnabled()) {\n return undefined;\n }\n\n return this.record({\n event,\n data,\n message,\n level: \"debug\",\n timestamp: Date.now(),\n timestampIso: new Date().toISOString(),\n });\n }\n\n startTimer(event: string, data?: unknown): TinyCloudDebugTimer {\n if (!this.isEnabled()) {\n return { stop: () => undefined };\n }\n\n const startedAt = nowMs();\n this.log(`${event}.start`, data);\n\n return {\n stop: (finishData?: unknown) => {\n const endedAt = nowMs();\n return this.record({\n event: `${event}.end`,\n data: finishData,\n durationMs: endedAt - startedAt,\n startedAt,\n endedAt,\n level: \"debug\",\n timestamp: Date.now(),\n timestampIso: new Date().toISOString(),\n });\n },\n };\n }\n\n async timeAsync<T>(\n event: string,\n operation: () => Promise<T>,\n data?: unknown,\n ): Promise<T> {\n if (!this.isEnabled()) {\n return operation();\n }\n\n const timer = this.startTimer(event, data);\n try {\n const result = await operation();\n timer.stop({ ok: true });\n return result;\n } catch (error) {\n timer.stop({ ok: false, error });\n throw error;\n }\n }\n\n time<T>(event: string, operation: () => T, data?: unknown): T {\n if (!this.isEnabled()) {\n return operation();\n }\n\n const timer = this.startTimer(event, data);\n try {\n const result = operation();\n timer.stop({ ok: true });\n return result;\n } catch (error) {\n timer.stop({ ok: false, error });\n throw error;\n }\n }\n\n private record(\n event: Omit<TinyCloudDebugEvent, \"sequence\">,\n ): TinyCloudDebugEvent {\n const debugEvent: TinyCloudDebugEvent = {\n ...event,\n ...(event.data === undefined\n ? {}\n : { data: projectDiagnosticData(event.data) }),\n ...(event.message === undefined ? {} : { message: \"[REDACTED]\" }),\n sequence: ++this.sequence,\n };\n\n this.events.push(debugEvent);\n if (this.events.length > this.maxEvents) {\n this.events.splice(0, this.events.length - this.maxEvents);\n }\n\n try {\n globalThis.console?.debug?.(\"[TinyCloud]\", debugEvent.event, debugEvent);\n } catch {\n // Debug logging should never affect SDK behavior.\n }\n\n return debugEvent;\n }\n}\n\nexport const tinyCloudDebugLogger = new TinyCloudDebugLogger();\n\nexport function enableTinyCloudDebug(\n options?: TinyCloudDebugEnableOptions,\n): TinyCloudDebugLogger {\n tinyCloudDebugLogger.enable(options);\n return tinyCloudDebugLogger;\n}\n\nexport function disableTinyCloudDebug(\n options?: TinyCloudDebugEnableOptions,\n): TinyCloudDebugLogger {\n tinyCloudDebugLogger.disable(options);\n return tinyCloudDebugLogger;\n}\n\nexport function getTinyCloudDebugLogs(): TinyCloudDebugEvent[] {\n return tinyCloudDebugLogger.getLogs();\n}\n\nexport function clearTinyCloudDebugLogs(): void {\n tinyCloudDebugLogger.clear();\n}\n\nexport function installTinyCloudDebugGlobals(): void {\n const global = getGlobal();\n global.TinyCloudDebug = tinyCloudDebugLogger;\n global.enableTinyCloudDebug = enableTinyCloudDebug;\n global.disableTinyCloudDebug = disableTinyCloudDebug;\n global.getTinyCloudDebugLogs = getTinyCloudDebugLogs;\n global.clearTinyCloudDebugLogs = clearTinyCloudDebugLogs;\n}\n\ninstallTinyCloudDebugGlobals();\n","/**\n * Zod schemas for SDK Services API response types.\n *\n * This is the source of truth for service response types. TypeScript types\n * are derived from these schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\n\n// =============================================================================\n// Validation Error Type\n// =============================================================================\n\n/**\n * Validation error type for schema validation failures.\n */\nexport interface ValidationError {\n code: \"VALIDATION_ERROR\";\n message: string;\n service: string;\n meta?: {\n issues: z.ZodIssue[];\n path?: string;\n };\n}\n\n// =============================================================================\n// Service Error Schema\n// =============================================================================\n\n/**\n * Schema for service error with structured information.\n */\nexport const ServiceErrorSchema = z.object({\n /** Error code for programmatic handling (e.g., 'KV_NOT_FOUND', 'AUTH_EXPIRED') */\n code: z.string(),\n /** Human-readable error message */\n message: z.string(),\n /** Service that produced the error (e.g., 'kv', 'sql') */\n service: z.string(),\n /** Original error if this wraps another error - not validated since Error is a class */\n cause: z.unknown().optional(),\n /** Additional metadata about the error - passthrough allows any object properties */\n meta: z.object({}).passthrough().optional(),\n});\n\nexport type ServiceErrorType = z.infer<typeof ServiceErrorSchema>;\n\n// =============================================================================\n// Result Schema Factory\n// =============================================================================\n\n/**\n * Creates a Result schema for a given data type.\n * Result is a discriminated union: { ok: true, data: T } | { ok: false, error: E }\n *\n * @param dataSchema - Zod schema for the success data type\n * @param errorSchema - Zod schema for the error type (defaults to ServiceErrorSchema)\n * @returns A Zod schema for Result<T, E>\n *\n * @example\n * ```typescript\n * const KVGetResultSchema = createResultSchema(z.string());\n * type KVGetResult = z.infer<typeof KVGetResultSchema>;\n * ```\n */\nexport function createResultSchema<T extends z.ZodTypeAny, E extends z.ZodTypeAny>(\n dataSchema: T,\n errorSchema: E = ServiceErrorSchema as unknown as E\n) {\n return z.discriminatedUnion(\"ok\", [\n z.object({\n ok: z.literal(true),\n data: dataSchema,\n }),\n z.object({\n ok: z.literal(false),\n error: errorSchema,\n }),\n ]);\n}\n\n/**\n * Pre-built Result schema with unknown data and ServiceError.\n * Useful for generic validation before type narrowing.\n */\nexport const GenericResultSchema = createResultSchema(z.unknown(), ServiceErrorSchema);\n\n// =============================================================================\n// KV Response Schemas\n// =============================================================================\n\n/**\n * Schema for KV response headers metadata.\n * Note: The `get` method is a function and cannot be validated with Zod.\n * This schema validates the data properties only.\n */\nexport const KVResponseHeadersSchema = z.object({\n /** ETag for conditional requests */\n etag: z.string().optional(),\n /** Content type of the stored value */\n contentType: z.string().optional(),\n /** Last modification timestamp */\n lastModified: z.string().optional(),\n /** Content length in bytes */\n contentLength: z.number().optional(),\n});\n\nexport type KVResponseHeadersType = z.infer<typeof KVResponseHeadersSchema>;\n\n/**\n * Creates a KVResponse schema for a given data type.\n *\n * @param dataSchema - Zod schema for the data payload type\n * @returns A Zod schema for KVResponse<T>\n *\n * @example\n * ```typescript\n * const UserResponseSchema = createKVResponseSchema(UserSchema);\n * type UserResponse = z.infer<typeof UserResponseSchema>;\n * ```\n */\nexport function createKVResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n /** The data payload */\n data: dataSchema,\n /** Response headers with metadata */\n headers: KVResponseHeadersSchema,\n });\n}\n\n/**\n * Generic KVResponse schema with unknown data.\n * Useful for generic validation before type narrowing.\n */\nexport const GenericKVResponseSchema = createKVResponseSchema(z.unknown());\n\nexport type GenericKVResponseType = z.infer<typeof GenericKVResponseSchema>;\n\n/**\n * Schema for KV list response.\n */\nexport const KVListResponseSchema = z.object({\n /** Array of keys matching the list criteria */\n keys: z.array(z.string()),\n truncated: z.boolean().optional(),\n nextCursor: z.string().optional(),\n});\n\nexport type KVListResponseType = z.infer<typeof KVListResponseSchema>;\n\n/**\n * Result schema for KV list operations.\n */\nexport const KVListResultSchema = createResultSchema(KVListResponseSchema);\n\nexport type KVListResultType = z.infer<typeof KVListResultSchema>;\n\n// =============================================================================\n// Telemetry Event Schemas\n// =============================================================================\n\n/**\n * Schema for service request event.\n */\nexport const ServiceRequestEventSchema = z.object({\n service: z.string(),\n action: z.string(),\n span: z.string().optional(),\n key: z.string().optional(),\n timestamp: z.number(),\n});\n\nexport type ServiceRequestEventType = z.infer<typeof ServiceRequestEventSchema>;\n\n/**\n * Schema for service response event.\n */\nexport const ServiceResponseEventSchema = z.object({\n service: z.string(),\n action: z.string(),\n span: z.string().optional(),\n ok: z.boolean(),\n duration: z.number(),\n durationMs: z.number().optional(),\n status: z.number().optional(),\n});\n\nexport type ServiceResponseEventType = z.infer<typeof ServiceResponseEventSchema>;\n\n/**\n * Schema for service error event.\n */\nexport const ServiceErrorEventSchema = z.object({\n service: z.string(),\n span: z.string().optional(),\n error: ServiceErrorSchema,\n});\n\nexport type ServiceErrorEventType = z.infer<typeof ServiceErrorEventSchema>;\n\n/**\n * Schema for service retry event.\n */\nexport const ServiceRetryEventSchema = z.object({\n service: z.string(),\n attempt: z.number().int().positive(),\n maxAttempts: z.number().int().positive(),\n error: ServiceErrorSchema,\n});\n\nexport type ServiceRetryEventType = z.infer<typeof ServiceRetryEventSchema>;\n\n/**\n * Schema for generic named span event.\n */\nexport const TelemetrySpanEventSchema = z.object({\n span: z.string(),\n ok: z.boolean(),\n durationMs: z.number(),\n service: z.string().optional(),\n action: z.string().optional(),\n status: z.number().optional(),\n error: ServiceErrorSchema.optional(),\n});\n\nexport type TelemetrySpanEventType = z.infer<typeof TelemetrySpanEventSchema>;\n\n// =============================================================================\n// Retry Policy Schema\n// =============================================================================\n\n/**\n * Schema for retry policy configuration.\n */\nexport const RetryPolicySchema = z.object({\n /** Maximum number of attempts (including initial) */\n maxAttempts: z.number().int().positive(),\n /** Backoff strategy between retries */\n backoff: z.enum([\"none\", \"linear\", \"exponential\"]),\n /** Base delay in milliseconds for backoff calculation */\n baseDelayMs: z.number().nonnegative(),\n /** Maximum delay in milliseconds between retries */\n maxDelayMs: z.number().nonnegative(),\n /** Error codes that should trigger a retry */\n retryableErrors: z.array(z.string()),\n});\n\nexport type RetryPolicyType = z.infer<typeof RetryPolicySchema>;\n\n// =============================================================================\n// Service Session Schema\n// =============================================================================\n\n/**\n * Schema for service session data required for authenticated operations.\n */\nexport const ServiceSessionSchema = z.object({\n /** The delegation header containing the UCAN */\n delegationHeader: z.object({\n Authorization: z.string(),\n }),\n /** The delegation CID */\n delegationCid: z.string(),\n /** The space ID for this session */\n spaceId: z.string(),\n /** The verification method DID */\n verificationMethod: z.string(),\n /** The session key JWK (required for invoke) */\n jwk: z.object({}).passthrough(),\n});\n\nexport type ServiceSessionType = z.infer<typeof ServiceSessionSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validate service error against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceError(\n data: unknown\n): { ok: true; data: ServiceErrorType } | { ok: false; error: ValidationError } {\n const result = ServiceErrorSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"validation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate KV list response against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateKVListResponse(\n data: unknown\n): { ok: true; data: KVListResponseType } | { ok: false; error: ValidationError } {\n const result = KVListResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"kv\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate KV response headers against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateKVResponseHeaders(\n data: unknown\n): { ok: true; data: KVResponseHeadersType } | { ok: false; error: ValidationError } {\n const result = KVResponseHeadersSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"kv\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service session against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceSession(\n data: unknown\n): { ok: true; data: ServiceSessionType } | { ok: false; error: ValidationError } {\n const result = ServiceSessionSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate retry policy against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateRetryPolicy(\n data: unknown\n): { ok: true; data: RetryPolicyType } | { ok: false; error: ValidationError } {\n const result = RetryPolicySchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"config\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service request event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceRequestEvent(\n data: unknown\n): { ok: true; data: ServiceRequestEventType } | { ok: false; error: ValidationError } {\n const result = ServiceRequestEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service response event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceResponseEvent(\n data: unknown\n): { ok: true; data: ServiceResponseEventType } | { ok: false; error: ValidationError } {\n const result = ServiceResponseEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate named telemetry span event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateTelemetrySpanEvent(\n data: unknown\n): { ok: true; data: TelemetrySpanEventType } | { ok: false; error: ValidationError } {\n const result = TelemetrySpanEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","/**\n * ServiceContext implementation for TinyCloud SDK Services\n * @module @tinycloud/sdk-services\n */\n\nimport {\n IServiceContext,\n IService,\n ServiceSession,\n RetryPolicy,\n InvokeFunction,\n InvokeAnyFunction,\n FetchFunction,\n defaultRetryPolicy,\n EventHandler,\n TelemetryEventHandler,\n TelemetryConfig,\n} from \"./types\";\nimport { tinyCloudDebugLogger } from \"./debug\";\nimport { projectDiagnosticData } from \"./diagnostics\";\n\n/**\n * Configuration options for ServiceContext.\n */\nexport interface ServiceContextConfig {\n /** Function to invoke WASM operations */\n invoke: InvokeFunction;\n /** Optional function to mint a single authorization header for multiple capabilities */\n invokeAny?: InvokeAnyFunction;\n /** Function to make HTTP requests (defaults to globalThis.fetch) */\n fetch?: FetchFunction;\n /** List of TinyCloud host URLs */\n hosts: string[];\n /** Initial session (optional) */\n session?: ServiceSession | null;\n /** Retry policy configuration */\n retryPolicy?: Partial<RetryPolicy>;\n /** Default-off telemetry event delivery. */\n telemetry?: TelemetryConfig;\n}\n\n/**\n * ServiceContext provides platform dependencies and cross-service access to services.\n * This is the primary interface services use to interact with the SDK runtime.\n *\n * @example\n * ```typescript\n * const context = new ServiceContext({\n * invoke: wasmInvoke,\n * hosts: ['https://node.tinycloud.xyz'],\n * retryPolicy: { maxAttempts: 5 },\n * });\n *\n * // Register a service\n * const kvService = new KVService({});\n * context.registerService('kv', kvService);\n * kvService.initialize(context);\n *\n * // Update session when user signs in\n * context.setSession(userSession);\n * ```\n */\nexport class ServiceContext implements IServiceContext {\n private _session: ServiceSession | null = null;\n private _services: Map<string, IService> = new Map();\n private _eventHandlers: Map<string, Set<EventHandler>> = new Map();\n private _abortController: AbortController = new AbortController();\n private _retired = false;\n private readonly _invoke: InvokeFunction;\n private readonly _invokeAny?: InvokeAnyFunction;\n private readonly _fetch: FetchFunction;\n private readonly _hosts: string[];\n private readonly _retryPolicy: RetryPolicy;\n private readonly _telemetryEnabled: boolean;\n private readonly _telemetryHandler?: TelemetryEventHandler;\n\n constructor(config: ServiceContextConfig) {\n this._invoke = this.wrapInvoke(config.invoke);\n this._invokeAny = config.invokeAny\n ? this.wrapInvokeAny(config.invokeAny)\n : undefined;\n this._fetch = this.wrapFetch(config.fetch ?? globalThis.fetch.bind(globalThis));\n this._hosts = config.hosts;\n this._session = config.session ?? null;\n this._retryPolicy = {\n ...defaultRetryPolicy,\n ...config.retryPolicy,\n };\n this._telemetryEnabled =\n typeof config.telemetry === \"boolean\"\n ? config.telemetry\n : config.telemetry?.enabled === true;\n this._telemetryHandler =\n typeof config.telemetry === \"object\" ? config.telemetry.onEvent : undefined;\n }\n\n // ============================================================\n // Session Management\n // ============================================================\n\n /**\n * Get the current session.\n */\n get session(): ServiceSession | null {\n return this._retired ? null : this._session;\n }\n\n /**\n * Check if the context has an authenticated session.\n */\n get isAuthenticated(): boolean {\n return !this._retired && this._session !== null;\n }\n\n /**\n * Update the session and notify all registered services.\n *\n * @param session - New session or null to clear\n */\n setSession(session: ServiceSession | null): void {\n this.assertActive();\n this._session = session;\n this.emit('session.changed', { authenticated: session !== null });\n\n // Notify all services of session change\n for (const service of this._services.values()) {\n service.onSessionChange(session);\n }\n }\n\n // ============================================================\n // Platform Dependencies\n // ============================================================\n\n /**\n * Get the invoke function for WASM operations.\n */\n get invoke(): InvokeFunction {\n this.assertActive();\n return this._invoke;\n }\n\n /**\n * Get the multi-resource invoke function when available.\n */\n get invokeAny(): InvokeAnyFunction | undefined {\n this.assertActive();\n return this._invokeAny;\n }\n\n /**\n * Get the fetch function for HTTP requests.\n */\n get fetch(): FetchFunction {\n this.assertActive();\n return this._fetch;\n }\n\n /**\n * Get the list of TinyCloud host URLs.\n */\n get hosts(): string[] {\n this.assertActive();\n return this._hosts;\n }\n\n // ============================================================\n // Service Registry\n // ============================================================\n\n /**\n * Register a service with the context.\n *\n * @param name - Service name (e.g., 'kv')\n * @param service - Service instance\n */\n registerService(name: string, service: IService): void {\n this._services.set(name, service);\n }\n\n /**\n * Unregister a service from the context.\n *\n * @param name - Service name to remove\n */\n unregisterService(name: string): void {\n this._services.delete(name);\n }\n\n /**\n * Get a registered service by name.\n *\n * @param name - Service name\n * @returns The service instance or undefined if not registered\n */\n getService<T extends IService>(name: string): T | undefined {\n return this._services.get(name) as T | undefined;\n }\n\n // ============================================================\n // Event System (Telemetry)\n // ============================================================\n\n /**\n * Emit a telemetry event.\n *\n * @param event - Event name\n * @param data - Event data\n */\n emit(event: string, data: unknown): void {\n tinyCloudDebugLogger.log(event, data);\n\n if (this._telemetryEnabled && this._telemetryHandler) {\n try {\n this._telemetryHandler(event, projectDiagnosticData(data));\n } catch (error) {\n // Don't let telemetry handlers break SDK operations.\n console.error(`Error in telemetry handler for \"${event}\":`, error);\n }\n }\n\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n // Don't let event handler errors break the flow\n console.error(`Error in event handler for \"${event}\":`, error);\n }\n }\n }\n }\n\n /**\n * Subscribe to telemetry events.\n *\n * @param event - Event name to subscribe to\n * @param handler - Handler function\n * @returns Unsubscribe function\n */\n on(event: string, handler: EventHandler): () => void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this._eventHandlers.delete(event);\n }\n }\n };\n }\n\n /**\n * Remove all event handlers for an event.\n *\n * @param event - Event name (if omitted, clears all events)\n */\n clearEventHandlers(event?: string): void {\n if (event) {\n this._eventHandlers.delete(event);\n } else {\n this._eventHandlers.clear();\n }\n }\n\n // ============================================================\n // Lifecycle\n // ============================================================\n\n /**\n * Get the abort signal for cancelling operations.\n */\n get abortSignal(): AbortSignal {\n return this._abortController.signal;\n }\n\n /**\n * Permanently retire this graph after its owner installs a replacement.\n * Unlike `abort()`, retirement never creates a fresh controller, so captured\n * services cannot resume calls under a superseded session.\n */\n retire(): void {\n if (this._retired) return;\n this._retired = true;\n this._session = null;\n this._abortController.abort();\n for (const service of this._services.values()) {\n // User-provided services are part of the retired graph, but their\n // cleanup must never make installing the replacement graph fail.\n try {\n service.onSignOut();\n } catch (error) {\n console.error(\"Error retiring service:\", error);\n }\n }\n }\n\n /**\n * Abort all pending operations and notify services.\n * Creates a new AbortController for future operations.\n */\n abort(): void {\n // A retired graph must never receive a fresh abort signal. Captured\n // services retain this context, so recreating its controller would make a\n // stale graph look live to custom cleanup code.\n if (this._retired) return;\n this._abortController.abort();\n this._abortController = new AbortController();\n\n // Notify all services\n for (const service of this._services.values()) {\n try {\n service.onSignOut();\n } catch (error) {\n console.error(\"Error signing out service:\", error);\n }\n }\n }\n\n /**\n * Sign out - abort operations and clear session.\n */\n signOut(): void {\n if (this._retired) return;\n this.abort();\n this.setSession(null);\n this.emit('session.expired', {});\n }\n\n // ============================================================\n // Retry Policy\n // ============================================================\n\n /**\n * Get the retry policy configuration.\n */\n get retryPolicy(): RetryPolicy {\n return this._retryPolicy;\n }\n\n private wrapInvoke(invoke: InvokeFunction): InvokeFunction {\n return (session, service, path, action, facts) => {\n this.assertActive();\n if (!tinyCloudDebugLogger.isEnabled()) {\n return invoke(session, service, path, action, facts);\n }\n\n const timer = tinyCloudDebugLogger.startTimer(\"sdk.invoke\", {\n service,\n path,\n action,\n facts,\n });\n\n try {\n const result = invoke(session, service, path, action, facts);\n timer.stop({ ok: true, service, path, action });\n return result;\n } catch (error) {\n timer.stop({ ok: false, service, path, action, error });\n throw error;\n }\n };\n }\n\n private assertActive(): void {\n if (this._retired) {\n throw new Error(\"Service graph has been retired by session replacement.\");\n }\n }\n\n private wrapInvokeAny(invokeAny: InvokeAnyFunction): InvokeAnyFunction {\n return (session, entries, facts) => {\n this.assertActive();\n if (!tinyCloudDebugLogger.isEnabled()) {\n return invokeAny(session, entries, facts);\n }\n\n const timer = tinyCloudDebugLogger.startTimer(\"sdk.invokeAny\", {\n entries,\n facts,\n });\n\n try {\n const result = invokeAny(session, entries, facts);\n timer.stop({ ok: true, entries });\n return result;\n } catch (error) {\n timer.stop({ ok: false, entries, error });\n throw error;\n }\n };\n }\n\n private wrapFetch(fetchFn: FetchFunction): FetchFunction {\n return async (url, init) => {\n this.assertActive();\n const request = {\n ...init,\n signal: this.combineSignals(init?.signal),\n };\n if (!tinyCloudDebugLogger.isEnabled()) {\n return fetchFn(url, request);\n }\n\n const timer = tinyCloudDebugLogger.startTimer(\"sdk.fetch\", {\n url,\n method: request.method ?? \"GET\",\n init: request,\n });\n\n try {\n const response = await fetchFn(url, request);\n timer.stop({\n ok: response.ok,\n url,\n method: request.method ?? \"GET\",\n status: response.status,\n statusText: response.statusText,\n });\n return response;\n } catch (error) {\n timer.stop({\n ok: false,\n url,\n method: request.method ?? \"GET\",\n error,\n });\n throw error;\n }\n };\n }\n\n private combineSignals(signal?: AbortSignal): AbortSignal {\n if (!signal) return this._abortController.signal;\n const combined = new AbortController();\n const abort = (source: AbortSignal) => combined.abort(source.reason);\n if (signal.aborted) {\n abort(signal);\n } else if (this._abortController.signal.aborted) {\n abort(this._abortController.signal);\n } else {\n signal.addEventListener(\"abort\", () => abort(signal), { once: true });\n this._abortController.signal.addEventListener(\n \"abort\",\n () => abort(this._abortController.signal),\n { once: true },\n );\n }\n return combined.signal;\n }\n}\n","/**\n * SDK Services - Error Utilities\n *\n * Utilities for creating and handling service errors.\n */\n\nimport { CAPABILITY_REGISTRY } from \"@tinycloud/bootstrap\";\nimport { parseNetworkId } from \"./encryption/networkId\";\n\nimport {\n type ServiceError,\n ErrorCodes,\n err,\n serviceError,\n type PermissionHint,\n} from \"./types\";\n\n/** Validate one structured node permission hint without accepting raw errors. */\nexport function parsePermissionHint(value: unknown): PermissionHint | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n const candidate = value as Record<string, unknown>;\n const keys = Object.keys(candidate).sort();\n if (keys.some((key) => ![\"actions\", \"path\", \"service\", \"space\"].includes(key))) return undefined;\n if (candidate.service !== \"tinycloud.kv\" && candidate.service !== \"tinycloud.encryption\") return undefined;\n if (typeof candidate.path !== \"string\" || candidate.path.length === 0 || candidate.path.includes(\"*\")) return undefined;\n if (candidate.service === \"tinycloud.kv\" &&\n (typeof candidate.space !== \"string\" || candidate.space.length === 0 || !candidate.path.startsWith(\"vault/\") || candidate.path.endsWith(\"/\"))) {\n return undefined;\n }\n if (candidate.service === \"tinycloud.encryption\" &&\n (candidate.space !== undefined || !candidate.path.startsWith(\"urn:tinycloud:encryption:\") || candidate.path.endsWith(\":\"))) {\n return undefined;\n }\n if (!Array.isArray(candidate.actions) || candidate.actions.length !== 1 ||\n typeof candidate.actions[0] !== \"string\" || candidate.actions[0].includes(\"*\")) return undefined;\n const expectedAction = candidate.service === \"tinycloud.kv\"\n ? \"tinycloud.kv/get\"\n : \"tinycloud.encryption/decrypt\";\n if (candidate.actions[0] !== expectedAction) return undefined;\n const space = typeof candidate.space === \"string\" ? candidate.space : undefined;\n return {\n service: candidate.service,\n ...(space === undefined ? {} : { space }),\n path: candidate.path,\n actions: [candidate.actions[0]],\n };\n}\n\n/** Extract only a validated structured hint from an SDK-owned error body. */\nexport function parsePermissionHintFromErrorText(text: string): PermissionHint | undefined {\n try {\n const parsed: unknown = JSON.parse(text);\n if (typeof parsed !== \"object\" || parsed === null) return undefined;\n const root = parsed as Record<string, unknown>;\n const nested = root.error;\n const nestedRecord = typeof nested === \"object\" && nested !== null\n ? nested as Record<string, unknown>\n : undefined;\n return parsePermissionHint(root.permissionHint) ??\n parsePermissionHint(nestedRecord?.permissionHint);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Create a service error for authentication required.\n */\nexport function authRequiredError(service: string): ServiceError {\n return {\n code: ErrorCodes.AUTH_REQUIRED,\n message: \"Authentication required. Please sign in first.\",\n service,\n };\n}\n\n/**\n * Create a service error for expired authentication.\n */\nexport function authExpiredError(service: string): ServiceError {\n return {\n code: ErrorCodes.AUTH_EXPIRED,\n message: \"Session has expired. Please sign in again.\",\n service,\n };\n}\n\n/**\n * Create a service error for network issues.\n */\nexport function networkError(\n service: string,\n message: string,\n cause?: Error\n): ServiceError {\n return {\n code: ErrorCodes.NETWORK_ERROR,\n message,\n service,\n cause,\n };\n}\n\n/**\n * Abort reason for a service request that exceeded its configured timeout.\n *\n * Named `TimeoutError` (like the reason of the platform's\n * `AbortSignal.timeout()`), so it maps to `ErrorCodes.TIMEOUT` and never to\n * `ErrorCodes.ABORTED`, which is reserved for caller and sign-out aborts.\n */\nexport class RequestTimeoutError extends Error {\n readonly timeoutMs: number;\n\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms.`);\n this.name = \"TimeoutError\";\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Whether an error is a {@link RequestTimeoutError}. Also matches by shape so\n * that a copy of the class from another bundle (ESM/CJS entrypoint) is\n * recognized.\n */\nexport function isRequestTimeoutError(error: unknown): error is RequestTimeoutError {\n return (\n error instanceof RequestTimeoutError ||\n (error instanceof Error &&\n error.name === \"TimeoutError\" &&\n typeof (error as { timeoutMs?: unknown }).timeoutMs === \"number\")\n );\n}\n\n/**\n * Create a service error for timeouts.\n *\n * @param timeoutMs - The configured timeout that elapsed, when known\n * @param cause - The underlying timeout error, when known\n */\nexport function timeoutError(\n service: string,\n timeoutMs?: number,\n cause?: Error\n): ServiceError {\n if (timeoutMs === undefined) {\n return {\n code: ErrorCodes.TIMEOUT,\n message: \"Request timed out.\",\n service,\n ...(cause === undefined ? {} : { cause }),\n };\n }\n return {\n code: ErrorCodes.TIMEOUT,\n message: `Request timed out after ${timeoutMs}ms.`,\n service,\n ...(cause === undefined ? {} : { cause }),\n meta: { timeoutMs },\n };\n}\n\n/**\n * Create a service error for aborted requests.\n */\nexport function abortedError(service: string): ServiceError {\n return {\n code: ErrorCodes.ABORTED,\n message: \"Request was aborted.\",\n service,\n };\n}\n\n/**\n * Create a service error for not found resources.\n */\nexport function notFoundError(\n service: string,\n resource: string\n): ServiceError {\n return {\n code: ErrorCodes.NOT_FOUND,\n message: `Resource not found: ${resource}`,\n service,\n };\n}\n\n/**\n * Create a service error for permission denied.\n */\nexport function permissionDeniedError(\n service: string,\n action: string\n): ServiceError {\n return {\n code: ErrorCodes.PERMISSION_DENIED,\n message: `Permission denied for action: ${action}`,\n service,\n };\n}\n\n/**\n * Parse the server's \"Unauthorized Action: {resource} / {ability}\" pattern.\n */\nexport function parseAuthError(responseText: string): { resource?: string; action?: string } {\n const match = responseText.match(/^Unauthorized Action:\\s*(.+?)\\s*\\/\\s*(tinycloud\\.\\S+)$/m);\n if (match) {\n return { resource: match[1].trim(), action: match[2].trim() };\n }\n return {};\n}\n\n/**\n * Create a service error for unauthorized action (missing capability).\n */\nexport function authUnauthorizedError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return serviceError(ErrorCodes.AUTH_UNAUTHORIZED, message, service, { meta });\n}\n\n/**\n * Authorization verdict read from an error's structure, never its message:\n * - `\"unauthenticated\"`: HTTP 401 — the session is missing or stale.\n * - `\"forbidden\"`: HTTP 403, or `AUTH_UNAUTHORIZED` without a status — the\n * session is valid but lacks the capability.\n * - `\"other\"`: a non-authorization HTTP error status (4xx/5xx).\n */\nexport type AuthorizationVerdict = \"unauthenticated\" | \"forbidden\" | \"other\";\n\nconst grantableActions = new Set(\n CAPABILITY_REGISTRY.map(({ urn }) => urn).filter((urn) => !urn.endsWith(\"/*\"))\n);\n\nconst capabilityServices = new Set(\n CAPABILITY_REGISTRY.map(({ service }) => service.slice(\"tinycloud.\".length))\n);\n\n/**\n * Parse a canonical TinyCloud resource, keeping nested space names intact.\n * The first registered service segment is authoritative: a later matching\n * segment in the path cannot turn a different service into grant advice.\n */\nexport function parseCapabilityResource(\n resource: string,\n service: string\n): { space: string; path: string } | undefined {\n if (\n resource.length === 0 ||\n resource.length > 1024 ||\n !capabilityServices.has(service) ||\n /[\\s\\p{C}*#]/u.test(resource) ||\n resource.includes(\"://\")\n ) return undefined;\n\n const segments = resource.split(\"/\");\n if (!/^tinycloud:[A-Za-z0-9][A-Za-z0-9:._-]*$/.test(segments[0])) return undefined;\n const serviceIndex = segments.findIndex((segment, index) =>\n index > 0 && capabilityServices.has(segment)\n );\n if (serviceIndex < 1 || segments[serviceIndex] !== service) return undefined;\n if (segments.slice(1, serviceIndex).some((segment) =>\n segment.length === 0 || segment === \".\" || segment === \"..\"\n )) return undefined;\n const pathSegments = segments.slice(serviceIndex + 1);\n if (pathSegments.some((segment) => segment === \".\" || segment === \"..\")) return undefined;\n if (service !== \"kv\" && (pathSegments.length === 0 || pathSegments[pathSegments.length - 1] === \"\")) return undefined;\n\n return {\n space: segments.slice(0, serviceIndex).join(\"/\"),\n path: pathSegments.join(\"/\"),\n };\n}\n\n/** A capability resource is a canonical TinyCloud resource or encryption network, never a URL or expression. */\nfunction safeCapabilityResource(value: unknown, service: string, action: string): value is string {\n if (typeof value !== \"string\" || value.length === 0 || value.length > 1024) return false;\n if (service === \"encryption\" && value.startsWith(\"urn:tinycloud:encryption:\")) {\n if (\n !/^[A-Za-z0-9_][A-Za-z0-9_.:/-]*$/.test(value) ||\n value.includes(\"//\") ||\n value.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n ) return false;\n try {\n parseNetworkId(value);\n return true;\n } catch {\n return false;\n }\n }\n const parsed = parseCapabilityResource(value, service);\n return parsed !== undefined &&\n (!parsed.path.endsWith(\"/\") || (service === \"kv\" && action === \"tinycloud.kv/list\")) &&\n (parsed.path !== \"\" || (service === \"kv\" && action === \"tinycloud.kv/list\"));\n}\n\n/**\n * Return a grantable missing capability only when typed authorization evidence\n * and both safe, service-matched capability fields are present. Status alone,\n * message text, wildcard actions and unrecognized actions cannot grant scope.\n */\nexport function validatedCapabilityOf(\n error: unknown\n): { resource: string; requiredAction: string } | undefined {\n const verdict = authorizationVerdictOf(error);\n if (verdict !== \"unauthenticated\" && verdict !== \"forbidden\") return undefined;\n\n const seen = new Set<unknown>();\n let node: unknown = error;\n for (\n let depth = 0;\n depth < MAX_CAUSE_DEPTH && typeof node === \"object\" && node !== null && !seen.has(node);\n depth += 1\n ) {\n seen.add(node);\n const record = node as Record<string, unknown>;\n const status = errorStatusOf(record);\n const meta = record.meta;\n if (\n (status === 401 || status === 403 || (status === undefined && record.code === ErrorCodes.AUTH_UNAUTHORIZED)) &&\n typeof meta === \"object\" && meta !== null && !Array.isArray(meta)\n ) {\n const metadata = meta as Record<string, unknown>;\n const { resource, requiredAction } = metadata;\n if (typeof requiredAction === \"string\" && grantableActions.has(requiredAction)) {\n const actionService = requiredAction.slice(\"tinycloud.\".length, requiredAction.indexOf(\"/\"));\n const explicitService = record.service === undefined ? metadata.service : record.service;\n if (\n safeCapabilityResource(resource, actionService, requiredAction) &&\n (explicitService === undefined ||\n explicitService === actionService ||\n explicitService === `tinycloud.${actionService}`)\n ) {\n return { resource, requiredAction };\n }\n }\n }\n node = record.cause;\n }\n return undefined;\n}\n\nconst MAX_CAUSE_DEPTH = 8;\n\n/** The first 4xx/5xx among `status`, `statusCode`, `meta.status`. Success and\n * informational statuses (e.g. a 200 `Response` kept as `cause`) are not\n * failures, so they are skipped rather than ending the search. */\nfunction errorStatusOf(node: Record<string, unknown>): number | undefined {\n const meta = node.meta;\n const candidates = [\n node.status,\n node.statusCode,\n typeof meta === \"object\" && meta !== null\n ? (meta as Record<string, unknown>).status\n : undefined,\n ];\n for (const candidate of candidates) {\n if (\n typeof candidate === \"number\" &&\n Number.isInteger(candidate) &&\n candidate >= 400 &&\n candidate <= 599\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n\n/**\n * Classify an error from its typed HTTP error status (`status`, `statusCode`,\n * or `meta.status`, 4xx/5xx only) and `AUTH_UNAUTHORIZED` code, following the\n * `cause` chain outer-first (at most {@link MAX_CAUSE_DEPTH} links, cycles\n * stop the walk) so wrappers that rethrow with `cause` keep the verdict. The\n * outermost error status decides, so an outer 5xx keeps its retry budget even\n * over an inner 401. Returns `undefined` for untyped errors; only then may\n * callers fall back to message heuristics.\n */\nexport function authorizationVerdictOf(\n error: unknown,\n): AuthorizationVerdict | undefined {\n const seen = new Set<unknown>();\n let sawUnauthorizedCode = false;\n let node: unknown = error;\n for (\n let depth = 0;\n depth < MAX_CAUSE_DEPTH && typeof node === \"object\" && node !== null && !seen.has(node);\n depth += 1\n ) {\n seen.add(node);\n const record = node as Record<string, unknown>;\n const status = errorStatusOf(record);\n if (status === 401) return \"unauthenticated\";\n if (status === 403) return \"forbidden\";\n if (status !== undefined) return \"other\";\n if (record.code === ErrorCodes.AUTH_UNAUTHORIZED) sawUnauthorizedCode = true;\n node = record.cause;\n }\n return sawUnauthorizedCode ? \"forbidden\" : undefined;\n}\n\n/**\n * Create a service error for storage quota exceeded (402 Payment Required).\n */\nexport function storageQuotaExceededError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return {\n code: ErrorCodes.STORAGE_QUOTA_EXCEEDED,\n message,\n service,\n meta,\n };\n}\n\n/**\n * Create a service error for storage limit reached (413 Payload Too Large).\n */\nexport function storageLimitReachedError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return {\n code: ErrorCodes.STORAGE_LIMIT_REACHED,\n message,\n service,\n meta,\n };\n}\n\n/** Shown when a write is rejected because the owner's storage is full. */\nexport const STORAGE_FULL_MESSAGE =\n \"TinyCloud storage is full, so this change was not saved. Reading still works. Free up space or upgrade your plan to save again.\";\n\n/** Shown when a write is larger than the storage the owner has left. */\nexport const STORAGE_WRITE_TOO_LARGE_MESSAGE =\n \"This change is larger than the TinyCloud storage you have left, so it was not saved. Reading still works. Free up space or upgrade your plan to save it.\";\n\n/**\n * Parse the byte counts from a node storage rejection\n * (\"... Used: 155744 bytes, Limit: 0 bytes\"). The limit is the share of the\n * owner's account-wide budget left for this space, so it is 0 when the\n * owner's other spaces already use the whole budget.\n */\nexport function parseStorageQuotaBytes(\n responseText: string\n): { usedBytes: number; limitBytes: number } | undefined {\n const match = responseText.match(/Used:\\s*(\\d+)\\s*bytes,\\s*Limit:\\s*(\\d+)\\s*bytes/i);\n if (!match) return undefined;\n return {\n usedBytes: parseInt(match[1], 10),\n limitBytes: parseInt(match[2], 10),\n };\n}\n\n/**\n * Build the error for a write the node rejected for storage: 402 when storage\n * is already full, 413 when this write is larger than what is left. KV, SQL\n * and DuckDB all report it with the same codes and message so an app can\n * detect \"storage full\" in one place with {@link isStorageFullError}.\n */\nexport function storageRejectionError(\n service: string,\n status: 402 | 413,\n meta: Record<string, unknown>,\n responseText: string\n): ServiceError {\n const quotaMeta = { ...meta, ...parseStorageQuotaBytes(responseText) };\n return status === 402\n ? storageQuotaExceededError(service, STORAGE_FULL_MESSAGE, quotaMeta)\n : storageLimitReachedError(service, STORAGE_WRITE_TOO_LARGE_MESSAGE, quotaMeta);\n}\n\n/**\n * True when a write failed for storage: the owner's TinyCloud storage is full\n * (`STORAGE_QUOTA_EXCEEDED`), or this write is larger than what is left\n * (`STORAGE_LIMIT_REACHED`). Reads keep working in both cases, so apps should\n * stay usable read-only and point the user at freeing up space or upgrading.\n */\nexport function isStorageFullError(error: { code?: string } | null | undefined): boolean {\n return (\n error?.code === ErrorCodes.STORAGE_QUOTA_EXCEEDED ||\n error?.code === ErrorCodes.STORAGE_LIMIT_REACHED\n );\n}\n\n/**\n * Wrap an unknown error in a ServiceError.\n */\nexport function wrapError(\n service: string,\n error: unknown,\n defaultCode: string = ErrorCodes.NETWORK_ERROR\n): ServiceError {\n if (error instanceof Error) {\n // A configured request timeout elapsed (see BaseService.createRequestSignal)\n if (isRequestTimeoutError(error)) {\n return timeoutError(service, error.timeoutMs, error);\n }\n\n // Check for abort errors\n if (error.name === \"AbortError\") {\n return abortedError(service);\n }\n\n // Check for timeout errors (varies by platform)\n if (\n error.name === \"TimeoutError\" ||\n error.message.toLowerCase().includes(\"timeout\")\n ) {\n return timeoutError(service);\n }\n\n return {\n code: defaultCode,\n message: error.message,\n service,\n cause: error,\n };\n }\n\n return {\n code: defaultCode,\n message: String(error),\n service,\n };\n}\n\n/**\n * Create an error Result from a ServiceError.\n */\nexport function errorResult(error: ServiceError) {\n return err(error);\n}\n","/**\n * TinyCloud encryption network identifiers.\n *\n * A network id is `urn:tinycloud:encryption:<ownerDid>:<network>` where\n * `ownerDid` is the owner's DID and `network` is a\n * non-empty label drawn from `[a-z0-9][a-z0-9-]*`.\n *\n * The embedded owner DID is the root authority for the network: any\n * delegation chain ending in a `tinycloud.encryption/decrypt` grant on\n * the network must root at this owner DID.\n */\n\nconst URN_PREFIX = \"urn:tinycloud:encryption:\";\nconst NETWORK_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;\nconst PKH_EIP155_DID_RE = /^did:pkh:eip155:(\\d+):(0x[a-fA-F0-9]{40})$/;\n\nexport interface ParsedNetworkId {\n /** The full URN string. */\n networkId: string;\n /** Owner DID embedded in the URN (the network's root authority). */\n ownerDid: string;\n /** Network label (the suffix after the owner DID). */\n name: string;\n}\n\nexport class NetworkIdError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NetworkIdError\";\n }\n}\n\n/**\n * Parse a network id string into its owner DID and name components.\n *\n * Throws {@link NetworkIdError} when the input does not match\n * `urn:tinycloud:encryption:<did>:<name>`, when the embedded DID is\n * malformed, or when the network name fails {@link NETWORK_NAME_RE}.\n */\nexport function parseNetworkId(networkId: string): ParsedNetworkId {\n if (typeof networkId !== \"string\" || networkId.length === 0) {\n throw new NetworkIdError(\"networkId must be a non-empty string\");\n }\n if (!networkId.startsWith(URN_PREFIX)) {\n throw new NetworkIdError(\n `networkId must start with ${URN_PREFIX} (got ${JSON.stringify(networkId)})`,\n );\n }\n const body = networkId.slice(URN_PREFIX.length);\n // `body` = \"<ownerDid>:<network>\"\n // ownerDid contains ':' (e.g. did:key:z6Mk...), so we split on the LAST colon\n // and treat the suffix as the network name.\n const lastColon = body.lastIndexOf(\":\");\n if (lastColon <= 0 || lastColon === body.length - 1) {\n throw new NetworkIdError(\n `networkId missing ownerDid or name segment (got ${JSON.stringify(networkId)})`,\n );\n }\n const ownerDid = body.slice(0, lastColon);\n const name = body.slice(lastColon + 1);\n\n if (!ownerDid.startsWith(\"did:\")) {\n throw new NetworkIdError(\n `networkId ownerDid must be a DID (got ${JSON.stringify(ownerDid)})`,\n );\n }\n // Minimal DID shape: did:<method>:<id> — three colon-separated segments,\n // each non-empty.\n const didParts = ownerDid.split(\":\");\n if (didParts.length < 3 || didParts.some((p) => p.length === 0)) {\n throw new NetworkIdError(\n `networkId ownerDid is not a well-formed DID (got ${JSON.stringify(ownerDid)})`,\n );\n }\n if (!NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `networkId name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n return { networkId, ownerDid, name };\n}\n\n/**\n * Construct a network id URN from an owner DID and a network name.\n * Validates inputs and throws {@link NetworkIdError} on bad shape.\n */\nexport function buildNetworkId(ownerDid: string, name: string): string {\n if (typeof ownerDid !== \"string\" || !ownerDid.startsWith(\"did:\")) {\n throw new NetworkIdError(\"ownerDid must be a DID\");\n }\n if (typeof name !== \"string\" || !NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n const networkId = `${URN_PREFIX}${ownerDid}:${name}`;\n // Re-validate the composed result so the same error path triggers\n // for caller inputs that compose into a malformed URN.\n parseNetworkId(networkId);\n return networkId;\n}\n\n/**\n * Returns true when {@link networkId} is a syntactically valid network URN.\n */\nexport function isNetworkId(networkId: unknown): networkId is string {\n if (typeof networkId !== \"string\") {\n return false;\n }\n try {\n parseNetworkId(networkId);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction parsePkhOwnerDid(ownerDid: string):\n | { chainId: string; address: string }\n | null {\n const match = ownerDid.match(PKH_EIP155_DID_RE);\n if (!match) return null;\n return {\n chainId: match[1],\n address: match[2].toLowerCase(),\n };\n}\n\n/**\n * Compare owner DIDs as network principals. For `did:pkh:eip155`, EVM\n * address casing is not part of principal identity; other DID methods\n * remain exact string matches.\n */\nexport function ownerDidMatches(a: string, b: string): boolean {\n const aPkh = parsePkhOwnerDid(a);\n const bPkh = parsePkhOwnerDid(b);\n if (aPkh && bPkh) {\n return aPkh.chainId === bPkh.chainId && aPkh.address === bPkh.address;\n }\n return a === b;\n}\n\n/**\n * Resolve the discovery key used to look up a network's descriptor under\n * an owner's public account-space.\n *\n * Format: `.well-known/encryption/network/<name>`.\n */\nexport function networkDiscoveryKey(name: string): string {\n if (!NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n return `.well-known/encryption/network/${name}`;\n}\n\nexport const ENCRYPTION_NETWORK_URN_PREFIX = URN_PREFIX;\nexport const NETWORK_NAME_PATTERN = NETWORK_NAME_RE;\n","/**\n * BaseService - Abstract base class for all TinyCloud services.\n *\n * Provides common functionality:\n * - Context management\n * - Session lifecycle hooks\n * - Abort signal handling\n * - Telemetry emission\n */\n\nimport {\n IService,\n IServiceContext,\n ServiceSession,\n ServiceError,\n TelemetryEvents,\n err,\n Result,\n} from \"../types\";\nimport { authRequiredError, wrapError, RequestTimeoutError } from \"../errors\";\nimport type { RequestSignal } from \"./types\";\n\n/** setTimeout's delay is a signed 32-bit integer; larger values fire at once. */\nconst MAX_TIMER_DELAY_MS = 2_147_483_647;\n\n/**\n * Abstract base class for TinyCloud services.\n *\n * Services extend this class to get common functionality like\n * context management, session lifecycle, and abort handling.\n *\n * @example\n * ```typescript\n * class MyService extends BaseService implements IMyService {\n * static readonly serviceName = 'myservice';\n *\n * constructor(config: MyServiceConfig = {}) {\n * super();\n * this._config = config;\n * }\n *\n * async doSomething(): Promise<Result<Data>> {\n * if (!this.requireAuth()) {\n * return err(authRequiredError('myservice'));\n * }\n * // ... implementation\n * }\n * }\n * ```\n */\nexport abstract class BaseService implements IService {\n /**\n * Service identifier used for registration.\n * Must be overridden by subclasses.\n */\n static readonly serviceName: string;\n\n /**\n * Service context providing access to platform dependencies.\n * Set during initialize().\n */\n protected context!: IServiceContext;\n\n /**\n * Abort controller for this service's operations.\n * Reset on sign-out.\n */\n protected abortController: AbortController = new AbortController();\n\n /**\n * Service-specific configuration.\n */\n protected _config: Record<string, unknown> = {};\n\n /**\n * Get the service configuration.\n */\n get config(): Record<string, unknown> {\n return this._config;\n }\n\n /**\n * Initialize the service with context.\n * Called by the SDK after instantiation.\n *\n * @param context - The service context\n */\n initialize(context: IServiceContext): void {\n this.context = context;\n }\n\n /**\n * Called when session changes (sign-in, sign-out, refresh).\n * Override in subclasses to handle session changes.\n *\n * @param session - The new session, or null if signed out\n */\n onSessionChange(session: ServiceSession | null): void {\n // Override in subclass if needed\n }\n\n /**\n * Called when SDK signs out.\n * Aborts all pending operations.\n */\n onSignOut(): void {\n this.abortController.abort();\n this.abortController = new AbortController();\n }\n\n /**\n * Get the abort signal for this service.\n * Combines the service-level abort with context-level abort.\n */\n protected get abortSignal(): AbortSignal {\n return this.combineSignals();\n }\n\n /**\n * Check if the service is authenticated.\n */\n protected get isAuthenticated(): boolean {\n return this.context?.isAuthenticated ?? false;\n }\n\n /**\n * Get the current session.\n * Throws if not authenticated.\n */\n protected get session(): ServiceSession {\n if (!this.context?.session) {\n throw new Error(\"Not authenticated\");\n }\n return this.context.session;\n }\n\n /**\n * Check authentication and return error result if not authenticated.\n * Use this at the start of methods that require authentication.\n *\n * @returns true if authenticated, false otherwise\n */\n protected requireAuth(): boolean {\n return this.isAuthenticated;\n }\n\n /**\n * Emit a telemetry event.\n *\n * @param event - Event name\n * @param data - Event data\n */\n protected emit(event: string, data: unknown): void {\n this.context?.emit(event, data);\n }\n\n /**\n * Emit a service request event.\n *\n * @param action - The action being performed\n * @param key - Optional key/path being accessed\n */\n protected emitRequest(action: string, key?: string): void {\n const service = this.getServiceName();\n this.emit(TelemetryEvents.SERVICE_REQUEST, {\n service,\n action,\n span: this.spanName(action),\n key,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Emit a service response event.\n *\n * @param action - The action that was performed\n * @param ok - Whether the request was successful\n * @param startTime - Start time for duration calculation\n * @param status - Optional HTTP status code\n */\n protected emitResponse(\n action: string,\n ok: boolean,\n startTime: number,\n status?: number\n ): void {\n const service = this.getServiceName();\n const durationMs = Date.now() - startTime;\n const span = this.spanName(action);\n this.emit(TelemetryEvents.SERVICE_RESPONSE, {\n service,\n action,\n span,\n ok,\n duration: durationMs,\n durationMs,\n status,\n });\n this.emit(TelemetryEvents.SPAN, {\n span,\n service,\n action,\n ok,\n durationMs,\n status,\n });\n }\n\n /**\n * Emit a service error event.\n *\n * @param error - The service error\n */\n protected emitError(error: ServiceError, action?: string): void {\n const span = action ? this.spanName(action) : undefined;\n this.emit(TelemetryEvents.SERVICE_ERROR, {\n service: this.getServiceName(),\n ...(span ? { span } : {}),\n error,\n });\n }\n\n /**\n * Get the service name from the static property.\n * Subclasses must define static serviceName.\n */\n protected getServiceName(): string {\n return (this.constructor as typeof BaseService).serviceName;\n }\n\n /**\n * Stable span name used by SDK telemetry sinks.\n */\n protected spanName(action: string): string {\n return `sdk.${this.getServiceName()}.${action}`;\n }\n\n /**\n * Create a combined abort signal from multiple sources.\n *\n * @param signals - Additional abort signals to combine\n * @returns A combined abort signal\n */\n protected combineSignals(...signals: (AbortSignal | undefined)[]): AbortSignal {\n const controller = new AbortController();\n const allSignals = [\n this.abortController.signal,\n this.context?.abortSignal,\n ...signals.filter(Boolean),\n ].filter(Boolean) as AbortSignal[];\n\n for (const signal of allSignals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n signal.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n\n return controller.signal;\n }\n\n /**\n * Create the abort signal for one request, bounded by the request timeout.\n *\n * The signal aborts when the service signs out, the context aborts, the\n * caller's `signal` aborts, or the timeout elapses, whichever comes first.\n * A timeout aborts with a {@link RequestTimeoutError} (`TimeoutError`), which\n * `wrapError` maps to `ErrorCodes.TIMEOUT`; the other sources keep their own\n * reason (normally `AbortError`, mapped to `ErrorCodes.ABORTED`).\n *\n * The timeout is `timeoutMs` when given, otherwise `config.timeout`. Only a\n * positive, finite value (at most 2^31-1 ms) applies; `undefined`, `0`, and\n * `Infinity` mean no timeout, so a per-call `0` opts out of a configured one.\n *\n * Callers must call `dispose()` once the response body has been consumed,\n * which clears the timer and removes the listeners this adds to the\n * long-lived service and context signals.\n *\n * @param signal - The caller's abort signal for this request\n * @param timeoutMs - Per-request timeout override in milliseconds\n */\n protected createRequestSignal(\n signal?: AbortSignal,\n timeoutMs?: number\n ): RequestSignal {\n const controller = new AbortController();\n const detachers: Array<() => void> = [];\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const dispose = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n for (const detach of detachers.splice(0)) {\n detach();\n }\n };\n const abort = (reason: unknown): void => {\n dispose();\n controller.abort(reason);\n };\n const requestSignal: RequestSignal = { signal: controller.signal, dispose };\n\n const parents = [\n this.abortController.signal,\n this.context?.abortSignal,\n signal,\n ].filter((parent): parent is AbortSignal => parent !== undefined);\n for (const parent of parents) {\n if (parent.aborted) {\n abort(parent.reason);\n return requestSignal;\n }\n const onAbort = (): void => abort(parent.reason);\n parent.addEventListener(\"abort\", onAbort, { once: true });\n detachers.push(() => parent.removeEventListener(\"abort\", onAbort));\n }\n\n const timeout = timeoutMs ?? this._config.timeout;\n if (\n typeof timeout === \"number\" &&\n timeout > 0 &&\n timeout <= MAX_TIMER_DELAY_MS\n ) {\n timer = setTimeout(() => abort(new RequestTimeoutError(timeout)), timeout);\n }\n\n return requestSignal;\n }\n\n /**\n * Wrap an operation with error handling and telemetry.\n *\n * @param action - The action name for telemetry\n * @param key - Optional key for telemetry\n * @param operation - The operation to execute\n * @returns Result of the operation\n */\n protected async withTelemetry<T>(\n action: string,\n key: string | undefined,\n operation: () => Promise<Result<T>>\n ): Promise<Result<T>> {\n const startTime = Date.now();\n this.emitRequest(action, key);\n\n try {\n const result = await operation();\n\n if (result.ok) {\n this.emitResponse(action, true, startTime);\n } else {\n this.emitResponse(action, false, startTime);\n this.emitError(result.error, action);\n }\n\n return result;\n } catch (error) {\n const serviceError = wrapError(this.getServiceName(), error);\n this.emitResponse(action, false, startTime);\n this.emitError(serviceError, action);\n return err(serviceError);\n }\n }\n}\n","/**\n * PrefixedKVService - A prefix-scoped view of KVService.\n *\n * Provides key-value operations scoped to a specific prefix.\n * All operations automatically prefix keys, enabling app data isolation\n * within a shared space.\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // Create prefix-scoped views\n * const myApp = space.kv.withPrefix('/app.myapp.com');\n * const sharedPhotos = space.kv.withPrefix('/photos');\n *\n * // Operations are automatically prefixed\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Actually writes to: /app.myapp.com/settings.json\n *\n * await myApp.get('settings.json');\n * // -> Actually reads from: /app.myapp.com/settings.json\n *\n * await sharedPhotos.list();\n * // -> Lists: /photos/*\n *\n * // Nested prefixes\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\n\nimport { Result, ok, err, ErrorCodes, serviceError } from \"../types\";\nimport {\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVBatchReadResponse,\n KVListOptions,\n KVChange,\n KVChangesOptions,\n KVChangesResponse,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVSignedReadUrlResponse,\n} from \"./types\";\n\n/**\n * Interface for prefixed KV operations.\n *\n * Provides the same operations as IKVService but scoped to a prefix.\n * Supports nested prefixes via withPrefix().\n */\nexport interface IPrefixedKVService {\n /**\n * The current prefix for this scoped view.\n */\n readonly prefix: string;\n\n /**\n * Get a value by key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to retrieve (will be prefixed)\n * @param options - Optional get configuration\n * @returns Result with the stored value and headers\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.get('settings.json');\n * // -> Reads from: /app.myapp.com/settings.json\n * ```\n */\n get<T = unknown>(\n key: string,\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVResponse<T>>>;\n\n batchGet<T = unknown>(\n keys: string[],\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVBatchReadResponse<T>>>;\n\n /**\n * Store a value at a key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to store under (will be prefixed)\n * @param value - The value to store\n * @param options - Optional put configuration\n * @returns Result indicating success/failure\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Stores at: /app.myapp.com/settings.json\n * ```\n */\n put(\n key: string,\n value: unknown,\n options?: Omit<KVPutOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>>;\n\n /**\n * Store multiple values within this prefix in one TinyCloud KV invocation.\n */\n batchPut(\n items: KVBatchPutItem[],\n options?: Omit<KVBatchPutOptions, 'prefix'>\n ): Promise<Result<KVBatchPutResponse>>;\n\n /**\n * List keys within this prefix.\n *\n * Returns keys that match the prefix, with keys returned relative\n * to the prefix when removePrefix is true (default for prefixed service).\n *\n * @param options - Optional list configuration\n * @returns Result with array of matching keys\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.list();\n * // -> Lists keys under: /app.myapp.com/*\n * // Returns: ['settings.json', 'data/user.json', ...]\n * ```\n */\n list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>>;\n\n /**\n * Read one page of the change feed for everything under this prefix\n * (`tinycloud.kv/sync` on `<prefix>/`). Keys are returned relative to the\n * prefix, like `list`; `source.prefix` stays the node's full prefix.\n * See `IKVService.changes` for paging and errors.\n *\n * @example\n * ```typescript\n * const notes = kv.withPrefix('notes');\n * const page = await notes.changes({ limit: 100 });\n * // -> Feed of: notes/*, keys like 'a.md'\n * ```\n */\n changes(options?: Omit<KVChangesOptions, 'prefix'>): Promise<Result<KVChangesResponse>>;\n\n /**\n * Delete a key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to delete (will be prefixed)\n * @param options - Optional delete configuration\n * @returns Result indicating success/failure\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * await myApp.delete('old-settings.json');\n * // -> Deletes: /app.myapp.com/old-settings.json\n * ```\n */\n delete(\n key: string,\n options?: Omit<KVDeleteOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>>;\n\n /**\n * Get metadata for a key without retrieving the value.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to check (will be prefixed)\n * @param options - Optional head configuration\n * @returns Result with headers only\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.head('large-file.bin');\n * // -> Gets metadata for: /app.myapp.com/large-file.bin\n * ```\n */\n head(key: string, options?: Omit<KVHeadOptions, 'prefix'>): Promise<Result<KVResponse<void>>>;\n\n batchHead(\n keys: string[],\n options?: Omit<KVHeadOptions, 'prefix'>\n ): Promise<Result<KVBatchReadResponse<void>>>;\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to expose via a signed read URL (will be prefixed)\n * @param options - Optional signed URL configuration\n * @returns Result with URL and expiry metadata\n */\n createSignedReadUrl(\n key: string,\n options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>\n ): Promise<Result<KVSignedReadUrlResponse>>;\n\n /**\n * Create a nested prefix-scoped view.\n *\n * The subPrefix is appended to the current prefix.\n *\n * @param subPrefix - The sub-prefix to append\n * @returns A new PrefixedKVService with the combined prefix\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json');\n * // -> Reads from: /app.myapp.com/settings/theme.json\n * ```\n */\n withPrefix(subPrefix: string): IPrefixedKVService;\n}\n\n/**\n * Interface for a KV service that supports prefix delegation.\n *\n * This is the subset of IKVService methods needed by PrefixedKVService.\n */\ninterface IKVServiceLike {\n get<T = unknown>(\n key: string,\n options?: KVGetOptions\n ): Promise<Result<KVResponse<T>>>;\n\n batchGet<T = unknown>(\n keys: string[],\n options?: KVGetOptions\n ): Promise<Result<KVBatchReadResponse<T>>>;\n\n put(\n key: string,\n value: unknown,\n options?: KVPutOptions\n ): Promise<Result<KVResponse<void>>>;\n\n batchPut(\n items: KVBatchPutItem[],\n options?: KVBatchPutOptions\n ): Promise<Result<KVBatchPutResponse>>;\n\n list(options?: KVListOptions): Promise<Result<KVListResponse>>;\n\n changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;\n\n delete(key: string, options?: KVDeleteOptions): Promise<Result<KVResponse<void>>>;\n\n head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;\n\n batchHead(\n keys: string[],\n options?: KVHeadOptions\n ): Promise<Result<KVBatchReadResponse<void>>>;\n\n createSignedReadUrl(\n key: string,\n options?: KVCreateSignedReadUrlOptions\n ): Promise<Result<KVSignedReadUrlResponse>>;\n}\n\n/**\n * PrefixedKVService - Implementation of prefix-scoped KV operations.\n *\n * This class wraps a KVService (or another PrefixedKVService) and\n * automatically prefixes all key operations with the configured prefix.\n *\n * ## Prefix Convention\n *\n * | Pattern | Use Case | Example |\n * | -- | -- | -- |\n * | `/app.{domain}/` | App-private data | `/app.photos.xyz/settings.json` |\n * | `/{type}/` | Shared data type | `/photos/vacation.jpg` |\n * | `/.{name}/` | Hidden/system data | `/.cache/thumbnails/` |\n * | `/public/` | Explicitly shareable | `/public/profile.json` |\n *\n * @example\n * ```typescript\n * // Create from KVService\n * const prefixed = new PrefixedKVService(kvService, '/app.myapp.com');\n *\n * // Or use the withPrefix factory method on KVService\n * const prefixed = kvService.withPrefix('/app.myapp.com');\n *\n * // All operations are automatically prefixed\n * await prefixed.put('settings.json', { theme: 'dark' });\n * await prefixed.get('settings.json');\n *\n * // Nested prefixes\n * const nested = prefixed.withPrefix('/settings');\n * await nested.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\nexport class PrefixedKVService implements IPrefixedKVService {\n /**\n * The underlying KV service.\n */\n private readonly _kv: IKVServiceLike;\n\n /**\n * The prefix for this scoped view.\n */\n private readonly _prefix: string;\n\n /**\n * Create a new PrefixedKVService.\n *\n * @param kv - The underlying KV service to delegate to\n * @param prefix - The prefix to apply to all operations\n */\n constructor(kv: IKVServiceLike, prefix: string) {\n this._kv = kv;\n // Normalize prefix: ensure it doesn't end with slash\n this._prefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n }\n\n /**\n * The current prefix for this scoped view.\n */\n get prefix(): string {\n return this._prefix;\n }\n\n /**\n * Compute the full key path by combining prefix and key.\n *\n * @param key - The key to prefix\n * @returns The full path including prefix\n */\n private getFullKey(key: string): string {\n // Handle keys that start with slash\n const normalizedKey = key.startsWith('/') ? key : `/${key}`;\n return `${this._prefix}${normalizedKey}`;\n }\n\n /**\n * Get a value by key.\n */\n async get<T = unknown>(\n key: string,\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVResponse<T>>> {\n const fullKey = this.getFullKey(key);\n // Use empty prefix override to use the full key as-is\n return this._kv.get<T>(fullKey, { ...options, prefix: '' });\n }\n\n async batchGet<T = unknown>(\n keys: string[],\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVBatchReadResponse<T>>> {\n const response = await this._kv.batchGet<T>(\n keys.map((key) => this.getFullKey(key)),\n { ...options, prefix: '' }\n );\n if (!response.ok) return response;\n return ok({\n ...response.data,\n results: response.data.results.map((item, index) => ({\n ...item,\n key: keys[index]!,\n })),\n });\n }\n\n /**\n * Store a value at a key.\n */\n async put(\n key: string,\n value: unknown,\n options?: Omit<KVPutOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.put(fullKey, value, { ...options, prefix: '' });\n }\n\n /**\n * Store multiple values within this prefix in one TinyCloud KV invocation.\n */\n async batchPut(\n items: KVBatchPutItem[],\n options?: Omit<KVBatchPutOptions, 'prefix'>\n ): Promise<Result<KVBatchPutResponse>> {\n return this._kv.batchPut(\n items.map((item) => ({\n ...item,\n key: this.getFullKey(item.key),\n })),\n { ...options, prefix: '' }\n );\n }\n\n /**\n * List keys within this prefix.\n */\n async list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>> {\n // List uses the prefix directly, and by default removes the prefix from results\n const removePrefix = options?.removePrefix ?? true;\n return this._kv.list({\n ...options,\n prefix: this._prefix,\n removePrefix,\n });\n }\n\n /**\n * Read the change feed for everything under this prefix. A view with an\n * empty prefix (`\"\"` or `\"/\"`) is refused: the node does not serve a\n * whole-space feed.\n */\n async changes(\n options?: Omit<KVChangesOptions, 'prefix'>\n ): Promise<Result<KVChangesResponse>> {\n if (this._prefix.replace(/\\/+$/, '') === '') {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n 'KV changes needs a non-empty prefix; this view has none',\n 'kv'\n ));\n }\n const syncPrefix = `${this._prefix}/`;\n const response = await this._kv.changes({ ...options, prefix: syncPrefix });\n if (!response.ok) return response;\n return ok({\n ...response.data,\n changes: response.data.changes.map((change): KVChange => ({\n ...change,\n key: change.key.startsWith(syncPrefix)\n ? change.key.slice(syncPrefix.length)\n : change.key,\n })),\n });\n }\n\n /**\n * Delete a key.\n */\n async delete(\n key: string,\n options?: Omit<KVDeleteOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.delete(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Get metadata for a key without retrieving the value.\n */\n async head(\n key: string,\n options?: Omit<KVHeadOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.head(fullKey, { ...options, prefix: '' });\n }\n\n async batchHead(\n keys: string[],\n options?: Omit<KVHeadOptions, 'prefix'>\n ): Promise<Result<KVBatchReadResponse<void>>> {\n const response = await this._kv.batchHead(\n keys.map((key) => this.getFullKey(key)),\n { ...options, prefix: '' }\n );\n if (!response.ok) return response;\n return ok({\n ...response.data,\n results: response.data.results.map((item, index) => ({\n ...item,\n key: keys[index]!,\n })),\n });\n }\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n */\n async createSignedReadUrl(\n key: string,\n options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>\n ): Promise<Result<KVSignedReadUrlResponse>> {\n const fullKey = this.getFullKey(key);\n return this._kv.createSignedReadUrl(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Create a nested prefix-scoped view.\n */\n withPrefix(subPrefix: string): IPrefixedKVService {\n // Normalize subPrefix\n const normalizedSubPrefix = subPrefix.startsWith('/')\n ? subPrefix\n : `/${subPrefix}`;\n const combinedPrefix = `${this._prefix}${normalizedSubPrefix}`;\n return new PrefixedKVService(this._kv, combinedPrefix);\n }\n}\n","/**\n * KV Service Types\n *\n * Type definitions for the KV (Key-Value) service operations.\n */\n\nimport type { Result } from \"../types\";\n\n/**\n * Configuration for KVService.\n */\nexport interface KVServiceConfig {\n /**\n * Default prefix for all keys.\n * Useful for namespacing data within a space.\n *\n * @example\n * ```typescript\n * const kv = new KVService({ prefix: 'myapp/settings' });\n * await kv.put('theme', 'dark'); // Stores at 'myapp/settings/theme'\n * ```\n */\n prefix?: string;\n\n /**\n * Default timeout in milliseconds for each KV request, including reading\n * the response body. When it elapses the request is aborted and the\n * operation returns an `ErrorCodes.TIMEOUT` error. A per-call `timeout`\n * option overrides it. Unset (the default), `0`, or `Infinity` means no\n * timeout.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for KV get operations.\n */\nexport interface KVGetOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Return raw response instead of parsed JSON.\n * When true, data will be the raw response text.\n */\n raw?: boolean;\n\n /**\n * Return the raw response bytes as a Uint8Array instead of parsed/text data.\n * Use this to read back binary values (e.g. images) byte-identically. Takes\n * precedence over {@link raw}.\n */\n binary?: boolean;\n\n /**\n * Ask the node to reject the response when the stored value exceeds this\n * number of bytes. This bounds downloads before the response body is read.\n */\n maxResponseBytes?: number;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV put operations.\n */\nexport interface KVPutOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Content type for the value.\n * Defaults to 'application/json' for objects.\n */\n contentType?: string;\n\n /**\n * Custom metadata headers to store with the value.\n */\n metadata?: Record<string, string>;\n\n /** Only write when the current object has this strong ETag. */\n ifMatch?: string;\n\n /** Only write when the key does not exist. */\n ifNoneMatch?: \"*\";\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * One entry in a KV batch put request.\n */\nexport interface KVBatchPutItem {\n /**\n * The key to store under.\n */\n key: string;\n\n /**\n * The value to store.\n *\n * Objects are JSON stringified. Strings are stored as text. Binary values\n * should be supplied as Blob, ArrayBuffer, or Uint8Array.\n */\n value: unknown;\n\n /**\n * Content type for this item. Defaults to application/json for objects and\n * application/octet-stream for binary values.\n */\n contentType?: string;\n}\n\n/**\n * Options for KV batch put operations.\n */\nexport interface KVBatchPutOptions {\n /**\n * Override the default prefix for all entries in this batch.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Response from KV batch put operations.\n */\nexport interface KVBatchPutResponse {\n /**\n * Keys successfully written by the batch.\n */\n written: string[];\n\n /**\n * Number of written keys.\n */\n count: number;\n}\n\n/**\n * Response from a KV batch read. Transport or authorization failures are\n * returned by the outer Result; each requested key has its own Result so a\n * missing key does not discard successful siblings.\n */\nexport interface KVBatchReadResponse<T = unknown> {\n results: Array<{\n key: string;\n result: Result<KVResponse<T>>;\n }>;\n count: number;\n}\n\n/**\n * Options for KV list operations.\n */\nexport interface KVListOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Additional path to append to the prefix.\n */\n path?: string;\n\n /**\n * Whether to remove the prefix from returned keys.\n * When true, keys are returned relative to the prefix.\n */\n removePrefix?: boolean;\n\n /**\n * Return raw response instead of parsed JSON.\n */\n raw?: boolean;\n\n /** Maximum number of keys the node may return. */\n limit?: number;\n\n /** Opaque scope-bound cursor returned by a previous bounded list. */\n cursor?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV delete operations.\n */\nexport interface KVDeleteOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /** Only delete when the current object has this strong ETag. */\n ifMatch?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV head (metadata) operations.\n */\nexport interface KVHeadOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Default lifetime for signed KV read URLs when a caller omits expiresInSeconds.\n * SDK duration defaults are stored in milliseconds; createSignedReadUrl converts\n * this to the node endpoint's ttl_seconds field.\n *\n * Keep this in sync with EXPIRY.SIGNED_READ_URL_MS in @tinycloud/sdk-core.\n * sdk-services cannot import sdk-core because sdk-core depends on sdk-services.\n */\nexport const DEFAULT_SIGNED_READ_URL_EXPIRY_MS = 5 * 60 * 1000;\n\n/**\n * Options for creating a signed KV read URL.\n */\nexport interface KVCreateSignedReadUrlOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Requested URL lifetime in seconds.\n * Defaults to {@link DEFAULT_SIGNED_READ_URL_EXPIRY_MS} converted to seconds.\n * The node may cap this by its configured maximum, the invocation expiry,\n * or the parent delegation expiry.\n */\n expiresInSeconds?: number;\n\n /**\n * Optional blake3 content hash to bind the signed URL to a specific object.\n */\n contentHash?: string;\n\n /**\n * Optional ETag to bind the signed URL to a specific object version.\n */\n etag?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Response headers from KV operations.\n */\nexport interface KVResponseHeaders {\n /**\n * ETag for conditional requests.\n */\n etag?: string;\n\n /**\n * Content type of the stored value.\n */\n contentType?: string;\n\n /**\n * Last modification timestamp.\n */\n lastModified?: string;\n\n /**\n * Content length in bytes.\n */\n contentLength?: number;\n\n /**\n * Get a header value by name.\n * @param name - Header name (case-insensitive)\n */\n get(name: string): string | null;\n}\n\n/**\n * Response from KV get/put operations.\n *\n * @template T - Type of the data payload\n */\nexport interface KVResponse<T = unknown> {\n /**\n * The data payload.\n * For get: the stored value.\n * For put: undefined.\n */\n data: T;\n\n /**\n * Response headers with metadata.\n */\n headers: KVResponseHeaders;\n}\n\n/**\n * Response from KV list operations.\n */\nexport interface KVListResponse {\n /**\n * Array of keys matching the list criteria.\n */\n keys: string[];\n\n /** True when more matching keys exist than the requested limit. */\n truncated?: boolean;\n\n /** Opaque cursor for the next page, when the node returned one. */\n nextCursor?: string;\n}\n\n/**\n * Options for {@link IKVService.changes}, the `tinycloud.kv/sync` change feed.\n */\nexport interface KVChangesOptions {\n /**\n * The space-relative KV prefix to follow, sent as the invocation path. It\n * is not joined with the service's configured prefix, and must be non-empty.\n * Prefixes match whole path segments: `notes` covers `notes` and\n * `notes/a`, while `notes/` covers everything under `notes/` but not\n * `notes` itself. The session must hold `tinycloud.kv/sync` on it by name.\n *\n * Returned `changes[].key` values are full paths in the space, like this\n * prefix. On a service with a configured prefix (for example\n * `DelegatedAccess.kv`, whose prefix is the delegation path), `get` joins\n * that prefix again, so strip it from the key first, or follow the feed\n * with `kv.withPrefix(...).changes()`, which returns relative keys.\n */\n prefix: string;\n\n /**\n * The `cursor` from the previous page. Omit it to bootstrap from the start\n * of the prefix. Opaque; never parse or build one.\n */\n cursor?: string;\n\n /**\n * Page size, 1 through 1000 (node default 500). A page never splits one\n * invocation's changes, so it can hold more than `limit` changes.\n */\n limit?: number;\n\n /**\n * CID of a never-invoked delegation carrying `tinycloud.kv/retain` on the\n * prefix. When valid, the node attests `authority.retainUntil`.\n */\n retentionGrant?: string;\n\n /**\n * Custom timeout for this operation in milliseconds. Overrides\n * `KVServiceConfig.timeout`; `0` disables a configured timeout.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * One key's latest state in a change feed page. Content is not included:\n * read it with `get`/`batchGet` and check it against `etag`.\n */\nexport type KVChange =\n | {\n key: string;\n deleted: false;\n /** The strong ETag `get` returns for this state. */\n etag: string;\n metadata: Record<string, string>;\n }\n | {\n key: string;\n deleted: true;\n };\n\n/**\n * The node-attested window in which the caller's authority holds. Values are\n * RFC 3339 timestamps, or `null` when nothing in the chain sets one.\n */\nexport interface KVChangesAuthority {\n /** The latest `nbf` across the invocation's whole delegation chain. */\n notBefore: string | null;\n /** The earliest `exp` across the invocation's whole delegation chain. */\n expiresAt: string | null;\n /**\n * The earliest `exp` across a valid retention grant's own chain. `null`\n * means no retention: none was presented, or its chain sets no expiry.\n */\n retainUntil: string | null;\n}\n\n/**\n * One page of the `tinycloud.kv/sync` change feed.\n */\nexport interface KVChangesResponse {\n /** Each changed key's latest state, in commit order. */\n changes: KVChange[];\n /**\n * More changes are available now. A page may be empty with `more: true`;\n * keep paging with the returned cursor.\n */\n more: boolean;\n /**\n * The cursor for the next request. An empty poll returns the request's\n * cursor unchanged.\n */\n cursor: string;\n /** The node, space and prefix that served the page. */\n source: {\n nodeDid: string;\n space: string;\n prefix: string;\n };\n authority: KVChangesAuthority;\n}\n\n/**\n * Response from signed KV read URL creation.\n */\nexport interface KVSignedReadUrlResponse {\n /**\n * Absolute URL suitable for passing to external readers.\n */\n url: string;\n\n /**\n * Opaque URL returned by tinycloud-node, usually relative to the node host.\n */\n relativeUrl: string;\n\n /**\n * Opaque signed KV ticket identifier.\n */\n ticketId: string;\n\n /**\n * Expiry timestamp as returned by tinycloud-node.\n */\n expiresAt: string;\n}\n\n/**\n * KV service action types.\n */\nexport const KVAction = {\n GET: \"tinycloud.kv/get\",\n PUT: \"tinycloud.kv/put\",\n LIST: \"tinycloud.kv/list\",\n DELETE: \"tinycloud.kv/del\",\n HEAD: \"tinycloud.kv/metadata\",\n /** The change feed; never implied by `*` or `tinycloud.kv/*`. */\n SYNC: \"tinycloud.kv/sync\",\n /** Retention attestation; presented through `retentionGrant`, never invoked or implied. */\n RETAIN: \"tinycloud.kv/retain\",\n} as const;\n\nexport type KVActionType = (typeof KVAction)[keyof typeof KVAction];\n","/**\n * KVService - Key-Value storage service implementation.\n *\n * Platform-agnostic KV service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n FetchResponse,\n ServiceHeaders,\n} from \"../types\";\nimport {\n authRequiredError,\n wrapError,\n storageRejectionError,\n parseStorageQuotaBytes,\n parseAuthError,\n parsePermissionHintFromErrorText,\n authUnauthorizedError,\n validatedCapabilityOf,\n isRequestTimeoutError,\n} from \"../errors\";\nimport { IKVService } from \"./IKVService\";\nimport { PrefixedKVService, IPrefixedKVService } from \"./PrefixedKVService\";\nimport {\n DEFAULT_SIGNED_READ_URL_EXPIRY_MS,\n KVServiceConfig,\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVBatchReadResponse,\n KVListOptions,\n KVChange,\n KVChangesOptions,\n KVChangesResponse,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVResponseHeaders,\n KVSignedReadUrlResponse,\n KVAction,\n} from \"./types\";\n\ninterface SignedKvUrlNodeResponse {\n url: string;\n ticketId: string;\n expiresAt: string;\n}\n\ninterface KvBatchNodeItem {\n key: string;\n ok: boolean;\n dataBase64?: string;\n headers?: Record<string, string>;\n error?: { code: string; message: string };\n}\n\ninterface KvBatchNodeResponse {\n results: KvBatchNodeItem[];\n}\n\nconst MAX_KV_BATCH_READ_ITEMS = 100;\n\nfunction isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nconst pathByteEncoder = new TextEncoder();\n\n/**\n * Lexicographic UTF-8 byte comparison, matching the ordering of the node's\n * `BTreeMap` (Rust `String` ordering is by UTF-8 bytes). JS string comparison\n * is by UTF-16 code unit, which diverges outside the BMP.\n */\nfunction comparePathsByBytes(a: string, b: string): number {\n const left = pathByteEncoder.encode(a);\n const right = pathByteEncoder.encode(b);\n const length = Math.min(left.length, right.length);\n for (let index = 0; index < length; index++) {\n if (left[index] !== right[index]) {\n return left[index]! - right[index]!;\n }\n }\n return left.length - right.length;\n}\n\n\n/**\n * The node's whole 401 body for a revoked chain: tinycloud-core's\n * `InvocationError::DelegationRevoked` (`delegation-revoked: <cid>`) or\n * `DelegationAncestorRevoked` (`delegation-ancestor-revoked: ancestor=<cid>\n * invoked=<cid>`), rendered as-is (older nodes prefixed `Invalid invocation: `).\n * Anchored: only CIDs follow the error kind, so a key, prefix or path in any\n * other 401 (e.g. `Unauthorized Action: <space>/kv/<prefix> / ...`) never matches.\n */\nconst REVOKED_BODY =\n /^(?:Invalid invocation: )?delegation-(?:(revoked): [A-Za-z0-9]+|(ancestor-revoked): ancestor=[A-Za-z0-9]+ invoked=[A-Za-z0-9]+)$/;\n\nfunction revocationCodeOf(\n body: string\n): typeof ErrorCodes.AUTH_DELEGATION_REVOKED | typeof ErrorCodes.AUTH_DELEGATION_ANCESTOR_REVOKED | undefined {\n const match = REVOKED_BODY.exec(body.trim());\n if (match === null) return undefined;\n return match[1] !== undefined ? ErrorCodes.AUTH_DELEGATION_REVOKED : ErrorCodes.AUTH_DELEGATION_ANCESTOR_REVOKED;\n}\n\nfunction encodeKvBatchPartName(path: string): string {\n return encodeURIComponent(path).replace(/[!'()*]/g, (char) =>\n `%${char.charCodeAt(0).toString(16).toUpperCase()}`\n );\n}\n\n/**\n * KV service implementation.\n *\n * Provides key-value storage operations using TinyCloud's KV API.\n * Uses the Result type pattern for explicit error handling.\n *\n * @example\n * ```typescript\n * // Register with SDK\n * const sdk = new TinyCloud({\n * services: { kv: KVService },\n * serviceConfigs: { kv: { prefix: 'myapp' } },\n * });\n *\n * // Use the service\n * const result = await sdk.kv.get('settings');\n * if (result.ok) {\n * console.log(result.data.data);\n * }\n * ```\n */\nexport class KVService extends BaseService implements IKVService {\n /**\n * Service identifier for registration.\n */\n static readonly serviceName = \"kv\";\n\n /**\n * Service configuration.\n */\n declare protected _config: KVServiceConfig;\n\n /**\n * Create a new KVService instance.\n *\n * @param config - Service configuration\n */\n constructor(config: KVServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n /**\n * Get the service configuration.\n */\n get config(): KVServiceConfig {\n return this._config;\n }\n\n private handleQuotaErrorResponse(\n response: FetchResponse,\n errorText: string,\n key: string\n ): Result<never> | undefined {\n if (response.status !== 402 && response.status !== 413) {\n return undefined;\n }\n // A 413 is about storage only when the node says so. A proxy's own\n // request-size limit (Cloudflare's HTML 413) is not.\n if (response.status === 413 && !parseStorageQuotaBytes(errorText)) {\n return undefined;\n }\n return err(\n storageRejectionError(\n \"kv\",\n response.status,\n { status: response.status, statusText: response.statusText, key },\n errorText\n )\n );\n }\n\n /**\n * Classify a KV 404 by reading the response body once.\n *\n * The server returns 404 both for a genuinely missing key AND for an\n * un-hosted space (body \"Space not found\"). Previously get/head/delete\n * collapsed every 404 to KV_NOT_FOUND before reading the body, so an\n * un-hosted-space read was indistinguishable from a missing key. We now\n * preserve status + the \"Space not found\" body for the un-hosted case (so the\n * CLI/SDK can normalize it to SPACE_NOT_HOSTED, matching put/list/sql), and\n * fall through to KV_NOT_FOUND for a real missing key.\n */\n private async classifyNotFound(\n response: FetchResponse,\n key: string\n ): Promise<Result<never>> {\n const errorText = await response.text();\n if (/space not found/i.test(errorText)) {\n return err(\n serviceError(\n ErrorCodes.KV_NOT_FOUND,\n `KV ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n return err(serviceError(ErrorCodes.KV_NOT_FOUND, `Key not found: ${key}`, \"kv\"));\n }\n\n /**\n * Get the full path with optional prefix.\n *\n * @param key - The key\n * @param prefixOverride - Optional prefix override\n * @returns The full path\n */\n private getFullPath(key: string, prefixOverride?: string): string {\n const prefix = prefixOverride ?? this._config.prefix ?? \"\";\n // A delegated share may scope this service to one exact key. In that\n // case `get(\"\")` means that key itself, not a synthetic child with a\n // trailing slash. This also keeps the service's prefix semantics useful\n // for exact (rather than prefix) capabilities.\n return prefix ? (key === \"\" ? prefix : `${prefix}/${key}`) : key;\n }\n\n /**\n * Get the host URL.\n */\n private get host(): string {\n return this.context.hosts[0];\n }\n\n private withJsonContentType(headers: ServiceHeaders): ServiceHeaders {\n if (Array.isArray(headers)) {\n return [...headers, [\"content-type\", \"application/json\"]];\n }\n\n return {\n ...headers,\n \"content-type\": \"application/json\",\n };\n }\n\n /**\n * Execute an invoke operation.\n *\n * @param path - Resource path\n * @param action - KV action\n * @param body - Optional request body\n * @param signal - Request signal from createRequestSignal()\n * @returns Fetch response\n */\n private async invokeOperation(\n path: string,\n action: string,\n body: Blob | string | undefined,\n signal: AbortSignal,\n extraHeaders?: Readonly<Record<string, string>>\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"kv\",\n path,\n action\n );\n\n const requestHeaders: ServiceHeaders = Array.isArray(headers)\n ? [...headers, ...Object.entries(extraHeaders ?? {})]\n : { ...headers, ...extraHeaders };\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: requestHeaders,\n body,\n signal,\n });\n }\n\n /**\n * Serialize a single put value into a fetch body.\n *\n * Binary values (Blob/ArrayBuffer/typed-array, incl. Node Buffer) are sent as\n * raw bytes (as a Blob) so they round-trip byte-identically — without this a\n * Buffer would be JSON.stringify'd into `{\"type\":\"Buffer\",\"data\":[...]}`.\n * Strings are returned unchanged (preserving prior behavior); other values are\n * JSON-encoded. `contentType` overrides the inferred type for binary values.\n */\n private serializePutValue(\n value: unknown,\n contentType?: string\n ): Blob | string {\n if (value instanceof Blob) {\n if (!contentType || value.type === contentType) {\n return value;\n }\n return new Blob([value], { type: contentType });\n }\n\n if (value instanceof ArrayBuffer) {\n return new Blob([value], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (ArrayBuffer.isView(value)) {\n // Pass a ranged view (honors byteOffset/byteLength so a Node Buffer backed\n // by a shared pool isn't over-read); Blob snapshots the bytes at\n // construction, so no defensive copy is needed.\n const view = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n return new Blob([view], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (typeof value === \"string\") {\n return contentType ? new Blob([value], { type: contentType }) : value;\n }\n\n return JSON.stringify(value);\n }\n\n private serializeBatchPutValue(item: KVBatchPutItem): Blob {\n const contentType = item.contentType;\n\n if (item.value instanceof Blob) {\n if (!contentType || item.value.type === contentType) {\n return item.value;\n }\n return new Blob([item.value], { type: contentType });\n }\n\n if (item.value instanceof ArrayBuffer) {\n return new Blob([item.value], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (ArrayBuffer.isView(item.value)) {\n const value = item.value;\n const bytes = new Uint8Array(value.byteLength);\n bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));\n return new Blob([bytes], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (typeof item.value === \"string\") {\n return new Blob([item.value], {\n type: contentType ?? \"text/plain;charset=UTF-8\",\n });\n }\n\n const json = JSON.stringify(item.value);\n if (json === undefined) {\n throw new Error(`Cannot JSON serialize KV batch value for key \"${item.key}\"`);\n }\n\n return new Blob([json], {\n type: contentType ?? \"application/json\",\n });\n }\n\n private normalizeBatchPutResponse(data: unknown): KVBatchPutResponse | undefined {\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n\n const response = data as Partial<KVBatchPutResponse>;\n if (\n !Array.isArray(response.written) ||\n !response.written.every((key) => typeof key === \"string\") ||\n typeof response.count !== \"number\"\n ) {\n return undefined;\n }\n\n return {\n written: response.written,\n count: response.count,\n };\n }\n\n /**\n * Create KVResponseHeaders from fetch response headers.\n *\n * @param headers - Fetch response headers\n * @returns KVResponseHeaders object\n */\n private createResponseHeaders(headers: {\n get(name: string): string | null;\n }): KVResponseHeaders {\n return {\n etag: headers.get(\"etag\") ?? undefined,\n contentType: headers.get(\"content-type\") ?? undefined,\n lastModified: headers.get(\"last-modified\") ?? undefined,\n contentLength: headers.get(\"content-length\")\n ? parseInt(headers.get(\"content-length\")!, 10)\n : undefined,\n get: (name: string) => headers.get(name),\n };\n }\n\n private createBatchResponseHeaders(\n values: Record<string, string>\n ): KVResponseHeaders {\n const normalized = new Map(\n Object.entries(values).map(([name, value]) => [name.toLowerCase(), value])\n );\n return this.createResponseHeaders({\n get: (name) => normalized.get(name.toLowerCase()) ?? null,\n });\n }\n\n private parseBatchValue<T>(\n dataBase64: string,\n headers: Record<string, string>,\n raw: boolean = false,\n binary: boolean = false\n ): T {\n const encoded = globalThis.atob(dataBase64);\n const bytes = Uint8Array.from(encoded, (character) => character.charCodeAt(0));\n if (binary) return bytes as unknown as T;\n\n const text = new TextDecoder().decode(bytes);\n if (raw) return text as unknown as T;\n const contentType = Object.entries(headers).find(\n ([name]) => name.toLowerCase() === \"content-type\"\n )?.[1];\n return (contentType?.includes(\"application/json\")\n ? JSON.parse(text)\n : text) as T;\n }\n\n /**\n * Validate a batch read response and return its items in the caller's\n * request order. The node flattens invocation abilities from a `BTreeMap`,\n * so results arrive sorted by UTF-8 byte order of the path, not in request\n * order. Items that carry their path in `key` are matched by path; if no\n * item carries a key, items are assumed to be in the node's byte-sorted\n * order and the request is aligned the same way. Any mix of keyed and\n * keyless items, a missing requested path, an unrequested path, or a\n * malformed item fails closed (returns undefined).\n */\n private normalizeBatchReadResponse(\n data: unknown,\n paths: string[],\n requireData: boolean\n ): KvBatchNodeItem[] | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n const response = data as Partial<KvBatchNodeResponse>;\n const items = response.results;\n if (!Array.isArray(items) || items.length !== paths.length) {\n return undefined;\n }\n\n for (const item of items) {\n if (!item || typeof item !== \"object\" || typeof item.ok !== \"boolean\") {\n return undefined;\n }\n if (\n item.ok &&\n (!item.headers ||\n typeof item.headers !== \"object\" ||\n Object.values(item.headers).some((value) => typeof value !== \"string\") ||\n (requireData && typeof item.dataBase64 !== \"string\"))\n ) {\n return undefined;\n }\n if (\n !item.ok &&\n (!item.error ||\n typeof item.error.code !== \"string\" ||\n typeof item.error.message !== \"string\")\n ) {\n return undefined;\n }\n }\n\n if (items.every((item) => typeof item.key === \"string\")) {\n const byPath = new Map(items.map((item) => [item.key, item]));\n if (byPath.size !== items.length) return undefined;\n const aligned: KvBatchNodeItem[] = [];\n for (const path of paths) {\n const item = byPath.get(path);\n if (!item) return undefined;\n aligned.push(item);\n }\n return aligned;\n }\n\n if (items.some((item) => item.key !== undefined)) return undefined;\n\n // No keys carried: the node's order is byte-sorted by path, so align by\n // sorting the request the same way. Request paths are unique (duplicates\n // are rejected before the request is signed).\n const requestOrder = paths\n .map((_, index) => index)\n .sort((a, b) => comparePathsByBytes(paths[a]!, paths[b]!));\n const aligned = new Array<KvBatchNodeItem>(items.length);\n for (let position = 0; position < requestOrder.length; position++) {\n aligned[requestOrder[position]!] = items[position]!;\n }\n return aligned;\n }\n\n private async batchRead<T>(\n keys: string[],\n action: typeof KVAction.GET | typeof KVAction.HEAD,\n options?: KVGetOptions | KVHeadOptions\n ): Promise<Result<KVBatchReadResponse<T>>> {\n if (!this.requireAuth()) return err(authRequiredError(\"kv\"));\n if (keys.length === 0) return ok({ results: [], count: 0 });\n if (keys.length > MAX_KV_BATCH_READ_ITEMS) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n `KV batch reads accept at most ${MAX_KV_BATCH_READ_ITEMS} keys`,\n \"kv\"\n ));\n }\n if (keys.length === 1) {\n const key = keys[0]!;\n const result = action === KVAction.GET\n ? await this.get<T>(key, options as KVGetOptions)\n : await this.head(key, options as KVHeadOptions);\n return ok({\n results: [{ key, result: result as Result<KVResponse<T>> }],\n count: 1,\n });\n }\n if (!this.context.invokeAny) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV batch reads require SDK runtime support for multi-resource invocations\",\n \"kv\"\n ));\n }\n\n const getOptions = action === KVAction.GET ? options as KVGetOptions : undefined;\n if (\n getOptions?.maxResponseBytes !== undefined &&\n (!Number.isSafeInteger(getOptions.maxResponseBytes) ||\n getOptions.maxResponseBytes <= 0)\n ) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV maxResponseBytes must be a positive safe integer\",\n \"kv\"\n ));\n }\n\n const paths = keys.map((key) => this.getFullPath(key, options?.prefix));\n if (new Set(paths).size !== paths.length) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV batch read received duplicate keys after prefix resolution\",\n \"kv\"\n ));\n }\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const session = this.context.session!;\n const invocationHeaders = this.context.invokeAny(\n session,\n paths.map((path) => ({\n spaceId: session.spaceId,\n service: \"kv\",\n path,\n action,\n }))\n );\n const limitHeaders: Record<string, string> = {};\n if (getOptions?.maxResponseBytes !== undefined) {\n limitHeaders[\"x-tinycloud-max-response-bytes\"] = String(\n getOptions.maxResponseBytes\n );\n }\n const headers: ServiceHeaders = Array.isArray(invocationHeaders)\n ? [...invocationHeaders, ...Object.entries(limitHeaders)]\n : { ...invocationHeaders, ...limitHeaders };\n const response = await this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n signal: request.signal,\n });\n\n if (!response.ok) {\n const errorText = response.status === 401 || response.status === 403\n ? await this.readAuthorizationText(response)\n : await response.text();\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to batch read ${keys.length} key(s)`,\n response,\n errorText,\n paths,\n action\n );\n }\n if (response.status === 413) {\n return err(serviceError(\n ErrorCodes.KV_RESPONSE_TOO_LARGE,\n \"A KV batch value exceeds the requested response limit\",\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n return err(serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to batch read ${keys.length} key(s): ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n\n const items = this.normalizeBatchReadResponse(\n await response.json(),\n paths,\n action === KVAction.GET\n );\n if (!items) {\n return err(serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"KV batch read response did not match the requested keys\",\n \"kv\"\n ));\n }\n\n const results = items.map((item, index) => {\n if (!item.ok) {\n return {\n key: keys[index]!,\n result: err(serviceError(item.error!.code, item.error!.message, \"kv\")),\n };\n }\n const headers = item.headers!;\n const data = action === KVAction.HEAD\n ? undefined\n : this.parseBatchValue<T>(\n item.dataBase64!,\n headers,\n getOptions?.raw,\n getOptions?.binary\n );\n return {\n key: keys[index]!,\n result: ok({\n data: data as T,\n headers: this.createBatchResponseHeaders(headers),\n }),\n };\n });\n return ok({ results, count: results.length });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n }\n\n /**\n * Parse response body based on content type.\n *\n * @param response - Fetch response\n * @param raw - Whether to return raw text\n * @returns Parsed data\n */\n private async parseResponse<T>(\n response: FetchResponse,\n raw: boolean = false,\n binary: boolean = false\n ): Promise<T | undefined> {\n if (!response.ok) {\n return undefined;\n }\n\n if (binary) {\n return new Uint8Array(await response.arrayBuffer()) as unknown as T;\n }\n\n if (raw) {\n return (await response.text()) as unknown as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return (await response.json()) as T;\n } else if (contentType?.startsWith(\"text/\")) {\n return (await response.text()) as unknown as T;\n }\n\n // No content-type header - try to parse as JSON, fall back to text\n const text = await response.text();\n if (!text) {\n return undefined;\n }\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n }\n\n private async createSignedReadUrlError(\n response: FetchResponse,\n key: string,\n path: string\n ): Promise<Result<never>> {\n let errorText = response.statusText;\n try {\n const text = await response.text();\n if (text) {\n errorText = text;\n }\n } catch {\n // Ignore secondary body read failure.\n }\n\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to create signed read URL for key ${JSON.stringify(key)}`,\n response,\n errorText,\n [path],\n KVAction.GET\n );\n }\n\n const code =\n response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR;\n return err(\n serviceError(\n code,\n `Failed to create signed read URL for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n /** A known 401/403 keeps its typed status even if reading its body fails. */\n private async readAuthorizationText(response: FetchResponse): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n }\n\n /**\n * AUTH_UNAUTHORIZED for a 401/403 response. The message keeps the HTTP\n * status and the server text (`<context>: <status> - <text>`, the same\n * shape as every other KV failure) so callers that rethrow only the message\n * still see the status; `meta.status` carries it for typed callers.\n * Server hints must match the requested path/action (whether the node sends\n * a relative path or full resource); metadata uses only the request-derived\n * canonical resource under the authenticated session's space.\n */\n private authorizationFailure(\n context: string,\n response: FetchResponse,\n errorText: string,\n paths: readonly string[],\n expectedAction: string,\n extraMeta: Record<string, unknown> = {}\n ): Result<never> {\n const { resource, action } = parseAuthError(errorText);\n const requestedPath = paths.find((path) =>\n resource === path ||\n resource === `${this.context.session!.spaceId}/kv/${path}`\n );\n const capability = requestedPath !== undefined && action === expectedAction\n ? validatedCapabilityOf({\n service: \"kv\",\n code: ErrorCodes.AUTH_UNAUTHORIZED,\n meta: {\n status: response.status,\n resource: `${this.context.session!.spaceId}/kv/${requestedPath}`,\n requiredAction: action,\n },\n })\n : undefined;\n const detail = errorText.trim().length > 0\n ? errorText\n : response.statusText || \"authorization failed\";\n return err(authUnauthorizedError(\"kv\", `${context}: ${response.status} - ${detail}`, {\n status: response.status,\n ...extraMeta,\n ...capability,\n }));\n }\n\n private normalizeSignedReadUrlResponse(\n data: unknown\n ): KVSignedReadUrlResponse | undefined {\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n\n const response = data as Partial<SignedKvUrlNodeResponse>;\n if (\n typeof response.url !== \"string\" ||\n typeof response.ticketId !== \"string\" ||\n typeof response.expiresAt !== \"string\"\n ) {\n return undefined;\n }\n\n return {\n url: new URL(response.url, this.host).toString(),\n relativeUrl: response.url,\n ticketId: response.ticketId,\n expiresAt: response.expiresAt,\n };\n }\n\n /**\n * Get a value by key.\n */\n async get<T = unknown>(\n key: string,\n options?: KVGetOptions\n ): Promise<Result<KVResponse<T>>> {\n return this.withTelemetry(\"get\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (\n options?.maxResponseBytes !== undefined &&\n (!Number.isSafeInteger(options.maxResponseBytes) || options.maxResponseBytes <= 0)\n ) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV maxResponseBytes must be a positive safe integer\",\n \"kv\"\n ));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.GET,\n undefined,\n request.signal,\n options?.maxResponseBytes === undefined\n ? undefined\n : { \"x-tinycloud-max-response-bytes\": String(options.maxResponseBytes) }\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n const errorText = await this.readAuthorizationText(response);\n const permissionHint = parsePermissionHintFromErrorText(errorText);\n const structuredCapability = permissionHint?.service === \"tinycloud.kv\" &&\n permissionHint.space === this.context.session!.spaceId &&\n permissionHint.path === path\n ? validatedCapabilityOf({\n service: \"kv\",\n code: ErrorCodes.AUTH_UNAUTHORIZED,\n meta: {\n status: response.status,\n resource: `${this.context.session!.spaceId}/kv/${path}`,\n requiredAction: KVAction.GET,\n },\n })\n : undefined;\n return this.authorizationFailure(\n `Failed to get key ${JSON.stringify(key)}`,\n response,\n errorText,\n [path],\n KVAction.GET,\n structuredCapability ? { permissionHint, ...structuredCapability } : {}\n );\n }\n\n if (response.status === 404) {\n return this.classifyNotFound(response, key);\n }\n\n const errorText = await response.text();\n if (response.status === 413) {\n return err(serviceError(\n ErrorCodes.KV_RESPONSE_TOO_LARGE,\n `KV value at key ${JSON.stringify(key)} exceeds the requested response limit`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n const data = await this.parseResponse<T>(\n response,\n options?.raw,\n options?.binary\n );\n return ok({\n data: data as T,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async batchGet<T = unknown>(\n keys: string[],\n options?: KVGetOptions\n ): Promise<Result<KVBatchReadResponse<T>>> {\n return this.withTelemetry(\"batchGet\", String(keys.length), () =>\n this.batchRead<T>(keys, KVAction.GET, options)\n );\n }\n\n /**\n * Store a value at a key.\n */\n async put(\n key: string,\n value: unknown,\n options?: KVPutOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"put\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (options?.ifMatch !== undefined && options.ifNoneMatch !== undefined) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV put cannot combine ifMatch and ifNoneMatch\",\n \"kv\"\n ));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n // Serialize the value. Binary values (Blob/ArrayBuffer/typed-array/Buffer)\n // are sent as raw bytes so they round-trip byte-identically; strings are\n // sent as-is; everything else is JSON. Mirrors serializeBatchPutValue.\n const body = this.serializePutValue(value, options?.contentType);\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.PUT,\n body,\n request.signal,\n {\n ...(options?.ifMatch === undefined ? {} : { \"if-match\": options.ifMatch }),\n ...(options?.ifNoneMatch === undefined ? {} : { \"if-none-match\": options.ifNoneMatch }),\n }\n );\n\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to put key ${JSON.stringify(key)}`,\n response,\n await this.readAuthorizationText(response),\n [path],\n KVAction.PUT\n );\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 412) {\n return err(serviceError(\n ErrorCodes.KV_PRECONDITION_FAILED,\n `KV precondition failed for key ${JSON.stringify(key)}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n\n if (\n response.status === 503 &&\n (options?.ifMatch !== undefined || options?.ifNoneMatch !== undefined)\n ) {\n return err(serviceError(\n ErrorCodes.KV_CONFLICT,\n `Concurrent KV update conflicted for key ${JSON.stringify(key)}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n\n // Check for storage quota errors (402, 413)\n const quotaError = this.handleQuotaErrorResponse(\n response,\n errorText,\n key\n );\n if (quotaError) {\n return quotaError;\n }\n\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Store multiple values in one TinyCloud KV invocation.\n */\n async batchPut(\n items: KVBatchPutItem[],\n options?: KVBatchPutOptions\n ): Promise<Result<KVBatchPutResponse>> {\n return this.withTelemetry(\"batchPut\", String(items.length), async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (items.length === 0) {\n return ok({ written: [], count: 0 });\n }\n\n if (!this.context.invokeAny) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV batchPut requires SDK runtime support for multi-resource invocations\",\n \"kv\"\n )\n );\n }\n\n const session = this.context.session!;\n const paths = items.map((item) => this.getFullPath(item.key, options?.prefix));\n const seen = new Set<string>();\n for (const path of paths) {\n if (seen.has(path)) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n `KV batchPut received duplicate key after prefix resolution: ${path}`,\n \"kv\"\n )\n );\n }\n seen.add(path);\n }\n\n // Conservative: `true` means we handed a fully-constructed request to\n // fetch(). It does NOT prove bytes reached the node — DNS/connect\n // failures and synchronous fetch rejections are included. Proving\n // actual dispatch requires lower-level transport instrumentation (out\n // of scope). The over-approximation is intentional and bounded: it can\n // only cause a reconciliation of at most N idempotent, byte-identical\n // overwrites — never a corrupted or differently-timestamped record.\n let requestMayHaveDispatched = false;\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const body = new FormData();\n for (let index = 0; index < items.length; index++) {\n body.append(\n encodeKvBatchPartName(paths[index]!),\n this.serializeBatchPutValue(items[index]!)\n );\n }\n\n const headers = this.context.invokeAny(\n session,\n paths.map((path) => ({\n spaceId: session.spaceId,\n service: \"kv\",\n path,\n action: KVAction.PUT,\n }))\n );\n\n const url = `${this.host}/invoke`;\n const init = {\n method: \"POST\",\n headers,\n body,\n signal: request.signal,\n };\n\n // Resolve the fetch function to a local BEFORE flipping the flag.\n // `this.context.fetch` is a getter (context.ts:154-156) that can\n // itself throw (assertActive()) — if the flag were set first, that\n // throw would be mislabeled as \"may have dispatched\" even though no\n // request was ever handed to a transport (Sol B2).\n const fetchFn = this.context.fetch;\n requestMayHaveDispatched = true;\n const response = await fetchFn(url, init);\n\n if (!response.ok) {\n let errorText: string;\n try {\n errorText = await response.text();\n } catch (textError) {\n // A response was received — the status is known and\n // authoritative — but its body could not be read. Falling\n // through to the generic catch below would report\n // NETWORK_ERROR + requestMayHaveDispatched: true, which the\n // allow-list treats as ambiguous regardless of status. That\n // would turn a deterministic 4xx (nothing written) into a false\n // ambiguity (Sol B4). Classify by status alone instead; whether\n // this is later reconciled is still governed solely by\n // AMBIGUOUS_WRITE_STATUSES, exactly like the body-readable path.\n //\n // Sol B2 (round 2): preserve the underlying rejection instead of\n // discarding it — a bare `catch {}` here would make a\n // body-read failure silently invisible, which is exactly the\n // debugging trap the no-swallowed-errors rule exists to\n // prevent.\n const cause = textError instanceof Error ? textError : new Error(String(textError));\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to batch put ${items.length} key(s): ${response.status} - <response body could not be read: ${cause.message}>`,\n \"kv\",\n { cause, meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to batch put ${items.length} key(s)`,\n response,\n errorText,\n paths,\n KVAction.PUT\n );\n }\n\n const quotaError = this.handleQuotaErrorResponse(\n response,\n errorText,\n \"batch\"\n );\n if (quotaError) {\n return quotaError;\n }\n\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to batch put ${items.length} key(s): ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n let rawBody: unknown;\n try {\n rawBody = await response.json();\n } catch (jsonError) {\n // A 2xx response whose body isn't valid JSON is precisely the\n // unconfirmed-2xx case — the node answered success but the write\n // set can't be confirmed. Falling through to the generic catch\n // below would carry only `requestMayHaveDispatched`, omitting\n // `responseReceived`/`status`/`outcome`, so this must be classified\n // here with the identical metadata block used by the two sibling\n // unconfirmed branches (Sol B3).\n //\n // Sol B2 (round 2): preserve the underlying rejection instead of\n // discarding it — a bare `catch {}` here would make a\n // JSON-parse failure silently invisible, which is exactly the\n // debugging trap the no-swallowed-errors rule exists to\n // prevent.\n const cause = jsonError instanceof Error ? jsonError : new Error(String(jsonError));\n // The configured timeout can also elapse while the 2xx body is\n // still streaming: report TIMEOUT, with the same unconfirmed meta.\n const timedOut = isRequestTimeoutError(cause);\n return err(\n serviceError(\n timedOut ? ErrorCodes.TIMEOUT : ErrorCodes.NETWORK_ERROR,\n timedOut\n ? `KV batchPut response body did not arrive in time: ${cause.message}`\n : `KV batchPut response was not valid JSON: ${cause.message}`,\n \"kv\",\n {\n cause,\n meta: {\n ...(timedOut ? { timeoutMs: cause.timeoutMs } : {}),\n requestMayHaveDispatched: true,\n responseReceived: true,\n status: response.status,\n outcome: \"batch-unconfirmed\",\n },\n }\n )\n );\n }\n\n const batchResponse = this.normalizeBatchPutResponse(rawBody);\n if (!batchResponse) {\n // The code stays NETWORK_ERROR deliberately: adding a member to\n // ErrorCodes (types.ts:73-115) widens the exported ErrorCode union\n // (:117) and would break consumers with exhaustive switches. The\n // node answered 2xx (the write very likely landed) but the body\n // could not confirm it, so the ambiguity is carried in metadata\n // instead of a dedicated code.\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"KV batchPut response did not include matching written keys and count\",\n \"kv\",\n {\n meta: {\n requestMayHaveDispatched: true,\n responseReceived: true,\n status: response.status,\n outcome: \"batch-unconfirmed\",\n },\n }\n )\n );\n }\n\n // Validate against the exact requested path set, not just internal\n // self-consistency (count === written.length would accept a\n // malformed response that reports the right count for the wrong\n // keys, e.g. a partial write padded to look complete).\n const requestedPaths = new Set(paths);\n const writtenPaths = new Set(batchResponse.written);\n const matchesRequest =\n batchResponse.count === paths.length &&\n batchResponse.written.length === paths.length &&\n writtenPaths.size === paths.length &&\n batchResponse.written.every((key) => requestedPaths.has(key));\n\n if (!matchesRequest) {\n // Same rationale as above: NETWORK_ERROR is kept and the\n // ambiguity is carried in meta rather than a new ErrorCodes member.\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `KV batchPut response did not confirm all ${paths.length} requested key(s) were written`,\n \"kv\",\n {\n meta: {\n requestMayHaveDispatched: true,\n responseReceived: true,\n status: response.status,\n outcome: \"batch-unconfirmed\",\n },\n }\n )\n );\n }\n\n return ok(batchResponse);\n } catch (error) {\n const wrapped = wrapError(\"kv\", error);\n return err({\n ...wrapped,\n meta: { ...wrapped.meta, requestMayHaveDispatched },\n });\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * List keys with optional prefix filtering.\n */\n async list(options?: KVListOptions): Promise<Result<KVListResponse>> {\n return this.withTelemetry(\"list\", options?.prefix, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (\n options?.limit !== undefined &&\n (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 1000)\n ) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV list limit must be an integer from 1 through 1000\",\n \"kv\"\n ));\n }\n\n // Build the path from prefix and optional path\n let listPath = options?.prefix ?? this._config.prefix ?? \"\";\n if (options?.path) {\n listPath = listPath ? `${listPath}/${options.path}` : options.path;\n }\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n listPath,\n KVAction.LIST,\n undefined,\n request.signal,\n options?.limit === undefined && options?.cursor === undefined\n ? undefined\n : {\n ...(options?.limit === undefined ? {} : { \"x-tinycloud-limit\": String(options.limit) }),\n ...(options?.cursor === undefined ? {} : { \"x-tinycloud-cursor\": options.cursor }),\n }\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n \"Failed to list keys\",\n response,\n await this.readAuthorizationText(response),\n [listPath],\n KVAction.LIST\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to list keys: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n let keys = await this.parseResponse<string[]>(response, options?.raw);\n keys = keys ?? [];\n\n // Optionally remove prefix from keys\n if (options?.removePrefix && listPath) {\n const prefixWithSlash = listPath.endsWith(\"/\")\n ? listPath\n : `${listPath}/`;\n keys = keys.map((key) =>\n key.startsWith(prefixWithSlash)\n ? key.slice(prefixWithSlash.length)\n : key\n );\n }\n\n return ok({\n keys,\n ...(response.headers.get(\"x-tinycloud-truncated\") === null\n ? {}\n : { truncated: response.headers.get(\"x-tinycloud-truncated\") === \"true\" }),\n ...(response.headers.get(\"x-tinycloud-next-cursor\") === null\n ? {}\n : { nextCursor: response.headers.get(\"x-tinycloud-next-cursor\") ?? undefined }),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Read one page of the `tinycloud.kv/sync` change feed for a prefix.\n */\n async changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>> {\n return this.withTelemetry(\"changes\", options?.prefix, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n // Plain-JS callers can omit the options; TypeScript requires them.\n if (typeof options?.prefix !== \"string\" || options.prefix.length === 0) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV changes prefix must be a non-empty string\",\n \"kv\"\n ));\n }\n if (\n options.limit !== undefined &&\n (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 1000)\n ) {\n return err(serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV changes limit must be an integer from 1 through 1000\",\n \"kv\"\n ));\n }\n\n const headers: Record<string, string> = {};\n if (options.limit !== undefined) headers[\"x-tinycloud-limit\"] = String(options.limit);\n if (options.cursor !== undefined) headers[\"x-tinycloud-cursor\"] = options.cursor;\n if (options.retentionGrant !== undefined) {\n headers[\"x-tinycloud-retention-grant\"] = options.retentionGrant;\n }\n\n const request = this.createRequestSignal(options.signal, options.timeout);\n try {\n const response = await this.invokeOperation(\n options.prefix,\n KVAction.SYNC,\n undefined,\n request.signal,\n headers\n );\n\n if (!response.ok) {\n // Awaited so the timeout and abort listeners stay live while the\n // error body is read; `finally` disposes them only afterwards.\n return await this.changesFailure(response, options.prefix, request.signal);\n }\n\n const text = await response.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = undefined;\n }\n const page = this.normalizeChangesResponse(body);\n if (!page) {\n return err(serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"KV changes response was not a tinycloud.kv/sync page\",\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n return ok(page);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Map a failed `kv/sync` response. 410 and the retention 403 carry\n * `{\"error\":{\"code\",\"reason\"}}`; a revoked grant is a 401 whose whole body\n * is the node's revocation error (see REVOKED_BODY). A body read that\n * fails because the request was cancelled or timed out rethrows, so the\n * caller sees `ABORTED`/`TIMEOUT` rather than a mapped status.\n */\n private async changesFailure(\n response: FetchResponse,\n prefix: string,\n signal: AbortSignal\n ): Promise<Result<never>> {\n if (response.status === 404) {\n return this.classifyNotFound(response, prefix);\n }\n let errorText: string;\n try {\n errorText = await response.text();\n } catch (error) {\n if (signal.aborted) throw error;\n errorText = \"\";\n }\n const meta = { status: response.status, statusText: response.statusText };\n let reason: string | undefined;\n let bodyCode: string | undefined;\n try {\n const body: unknown = JSON.parse(errorText);\n const error = isJsonObject(body) ? body.error : undefined;\n if (isJsonObject(error)) {\n if (typeof error.code === \"string\") bodyCode = error.code;\n if (typeof error.reason === \"string\") reason = error.reason;\n }\n } catch {\n // Plain-text body.\n }\n const context = `Failed to read KV changes for ${JSON.stringify(prefix)}`;\n\n if (response.status === 410) {\n return err(serviceError(\n ErrorCodes.KV_SYNC_RESET_REQUIRED,\n `${context}: the node requires a reset (${reason ?? \"reason not given\"}); discard sync state and restart without a cursor`,\n \"kv\",\n { meta: { ...meta, reason } }\n ));\n }\n if (response.status === 403 && bodyCode === \"RETENTION_GRANT_REFUSED\") {\n return err(serviceError(\n ErrorCodes.KV_RETENTION_GRANT_REFUSED,\n `${context}: the retention grant was refused (${reason ?? \"reason not given\"})`,\n \"kv\",\n { meta: { ...meta, reason } }\n ));\n }\n if (response.status === 401) {\n const revoked = revocationCodeOf(errorText);\n if (revoked !== undefined) {\n return err(serviceError(revoked, `${context}: 401 - ${errorText}`, \"kv\", { meta }));\n }\n }\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(context, response, errorText, [prefix], KVAction.SYNC);\n }\n return err(serviceError(\n response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR,\n `${context}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta }\n ));\n }\n\n private normalizeChangesResponse(data: unknown): KVChangesResponse | undefined {\n if (!isJsonObject(data)) return undefined;\n const { changes, more, cursor, source, authority } = data;\n if (\n !Array.isArray(changes) ||\n typeof more !== \"boolean\" ||\n typeof cursor !== \"string\" ||\n !isJsonObject(source) ||\n typeof source.nodeDid !== \"string\" ||\n typeof source.space !== \"string\" ||\n typeof source.prefix !== \"string\" ||\n !isJsonObject(authority)\n ) {\n return undefined;\n }\n const { notBefore, expiresAt, retainUntil } = authority;\n if (\n (notBefore !== null && typeof notBefore !== \"string\") ||\n (expiresAt !== null && typeof expiresAt !== \"string\") ||\n (retainUntil !== null && typeof retainUntil !== \"string\")\n ) {\n return undefined;\n }\n\n const parsed: KVChange[] = [];\n for (const change of changes) {\n if (!isJsonObject(change) || typeof change.key !== \"string\") return undefined;\n if (change.deleted === true) {\n parsed.push({ key: change.key, deleted: true });\n continue;\n }\n const { metadata } = change;\n if (\n change.deleted !== false ||\n typeof change.etag !== \"string\" ||\n !isJsonObject(metadata) ||\n !Object.values(metadata).every((value) => typeof value === \"string\")\n ) {\n return undefined;\n }\n parsed.push({\n key: change.key,\n deleted: false,\n etag: change.etag,\n metadata: metadata as Record<string, string>,\n });\n }\n\n return {\n changes: parsed,\n more,\n cursor,\n source: { nodeDid: source.nodeDid, space: source.space, prefix: source.prefix },\n authority: { notBefore, expiresAt, retainUntil },\n };\n }\n\n /**\n * Delete a key.\n */\n async delete(\n key: string,\n options?: KVDeleteOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"delete\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.DELETE,\n undefined,\n request.signal,\n options?.ifMatch === undefined\n ? undefined\n : { \"if-match\": options.ifMatch }\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to delete key ${JSON.stringify(key)}`,\n response,\n await this.readAuthorizationText(response),\n [path],\n KVAction.DELETE\n );\n }\n\n if (response.status === 404) {\n return this.classifyNotFound(response, key);\n }\n\n const errorText = await response.text();\n if (response.status === 412) {\n return err(serviceError(\n ErrorCodes.KV_PRECONDITION_FAILED,\n `KV precondition failed for key ${JSON.stringify(key)}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n if (response.status === 503 && options?.ifMatch !== undefined) {\n return err(serviceError(\n ErrorCodes.KV_CONFLICT,\n `Concurrent KV delete conflicted for key ${JSON.stringify(key)}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n ));\n }\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Get metadata for a key without retrieving the value.\n */\n async head(\n key: string,\n options?: KVHeadOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"head\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.HEAD,\n undefined,\n request.signal\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n return this.authorizationFailure(\n `Failed to get metadata for key ${JSON.stringify(key)}`,\n response,\n await this.readAuthorizationText(response),\n [path],\n KVAction.HEAD\n );\n }\n\n if (response.status === 404) {\n return this.classifyNotFound(response, key);\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async batchHead(\n keys: string[],\n options?: KVHeadOptions\n ): Promise<Result<KVBatchReadResponse<void>>> {\n return this.withTelemetry(\"batchHead\", String(keys.length), () =>\n this.batchRead<void>(keys, KVAction.HEAD, options)\n );\n }\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n */\n async createSignedReadUrl(\n key: string,\n options?: KVCreateSignedReadUrlOptions\n ): Promise<Result<KVSignedReadUrlResponse>> {\n return this.withTelemetry(\"createSignedReadUrl\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"kv\",\n path,\n KVAction.GET\n );\n\n const body: {\n space: string;\n path: string;\n ttl_seconds: number;\n content_hash?: string;\n etag?: string;\n } = {\n space: session.spaceId,\n path,\n ttl_seconds:\n options?.expiresInSeconds ??\n Math.ceil(DEFAULT_SIGNED_READ_URL_EXPIRY_MS / 1000),\n };\n\n if (options?.contentHash !== undefined) {\n body.content_hash = options.contentHash;\n }\n if (options?.etag !== undefined) {\n body.etag = options.etag;\n }\n\n const request = this.createRequestSignal(options?.signal, options?.timeout);\n try {\n const response = await this.context.fetch(`${this.host}/signed/kv`, {\n method: \"POST\",\n headers: this.withJsonContentType(headers),\n body: JSON.stringify(body),\n signal: request.signal,\n });\n\n if (!response.ok) {\n return this.createSignedReadUrlError(response, key, path);\n }\n\n const signedUrl = this.normalizeSignedReadUrlResponse(\n await response.json()\n );\n if (!signedUrl) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"Signed read URL response did not include url, ticketId, and expiresAt\",\n \"kv\"\n )\n );\n }\n\n return ok(signedUrl);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n /**\n * Create a prefix-scoped view of this KV service.\n *\n * Returns a PrefixedKVService that automatically prefixes all\n * key operations with the specified prefix. This enables apps\n * to isolate their data within a shared space.\n *\n * @param prefix - The prefix to apply to all operations\n * @returns A PrefixedKVService scoped to the prefix\n *\n * ## Prefix Conventions\n *\n * | Pattern | Use Case | Example |\n * | -- | -- | -- |\n * | `/app.{domain}/` | App-private data | `/app.photos.xyz/settings.json` |\n * | `/{type}/` | Shared data type | `/photos/vacation.jpg` |\n * | `/.{name}/` | Hidden/system data | `/.cache/thumbnails/` |\n * | `/public/` | Explicitly shareable | `/public/profile.json` |\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // Create prefix-scoped views\n * const myApp = space.kv.withPrefix('/app.myapp.com');\n * const sharedPhotos = space.kv.withPrefix('/photos');\n *\n * // Operations are automatically prefixed\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Actually writes to: /app.myapp.com/settings.json\n *\n * await myApp.get('settings.json');\n * // -> Actually reads from: /app.myapp.com/settings.json\n *\n * await sharedPhotos.list();\n * // -> Lists: /photos/*\n *\n * // Nested prefixes\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\n withPrefix(prefix: string): IPrefixedKVService {\n return new PrefixedKVService(this, prefix);\n }\n}\n","export interface ParsedServiceErrorBody {\n error?: string;\n message?: string;\n code?: string;\n}\n\nexport function parseServiceErrorBody(errorText: string): ParsedServiceErrorBody {\n try {\n return JSON.parse(errorText) as ParsedServiceErrorBody;\n } catch {\n return {};\n }\n}\n\nexport function formatServiceResponseError(\n serviceLabel: string,\n operation: string,\n status: number,\n errorText: string,\n parsed: ParsedServiceErrorBody,\n): string {\n if (parsed.message) {\n return compactMessage(parsed.message);\n }\n\n if (looksLikeHtml(errorText)) {\n if (status === 524 || /524\\s*[:-]/i.test(errorText) || /a timeout occurred/i.test(errorText)) {\n return `${serviceLabel} ${operation} failed: upstream request timed out. Please retry.`;\n }\n return `${serviceLabel} ${operation} failed: upstream service returned an HTML error page (${status}).`;\n }\n\n return `${serviceLabel} ${operation} failed: ${status} - ${compactMessage(errorText)}`;\n}\n\nexport function responseErrorMeta(\n status: number,\n statusText: string,\n errorText: string,\n): Record<string, unknown> {\n const meta: Record<string, unknown> = { status, statusText };\n const snippet = compactMessage(errorText);\n if (snippet) {\n meta.responseSnippet = snippet.slice(0, 300);\n }\n return meta;\n}\n\nfunction looksLikeHtml(text: string): boolean {\n return /<!doctype html/i.test(text) || /<html[\\s>]/i.test(text);\n}\n\nfunction compactMessage(message: string): string {\n const compact = message.replace(/\\s+/g, \" \").trim();\n return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;\n}\n","import type { Result } from \"../types\";\nimport type { SQLService } from \"./SQLService\";\nimport type { ISQLMigrations } from \"./ISQLService\";\nimport type {\n SqlMigrationApplyOptions,\n SqlMigrationApplyResponse,\n} from \"./types\";\n\nexport class SQLMigrations implements ISQLMigrations {\n constructor(\n private readonly service: SQLService,\n private readonly dbName: string,\n ) {}\n\n apply(options: SqlMigrationApplyOptions): Promise<Result<SqlMigrationApplyResponse>> {\n return this.service.applyMigrationsOnDb(this.dbName, options);\n }\n}\n","/**\n * DatabaseHandle - Handle for operations on a specific named database.\n *\n * Delegates all operations to the parent SQLService with the database name.\n */\n\nimport type { Result } from \"../types\";\nimport type { IDatabaseHandle, ISQLMigrations } from \"./ISQLService\";\nimport type { SQLService } from \"./SQLService\";\nimport { SQLMigrations } from \"./SQLMigrations\";\nimport type {\n SqlValue,\n SqlStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n QueryOptions,\n ExecuteOptions,\n BatchOptions,\n} from \"./types\";\n\nexport class DatabaseHandle implements IDatabaseHandle {\n private service: SQLService;\n public readonly name: string;\n public readonly migrations: ISQLMigrations;\n\n constructor(service: SQLService, name: string) {\n this.service = service;\n this.name = name;\n this.migrations = new SQLMigrations(service, name);\n }\n\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.service.queryOnDb<T>(this.name, sql, params, options);\n }\n\n async execute(\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.service.executeOnDb(this.name, sql, params, options);\n }\n\n async batch(\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.service.batchOnDb(this.name, statements, options);\n }\n\n async executeStatement(\n name: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.service.executeStatementOnDb(this.name, name, params, options);\n }\n\n async export(options?: QueryOptions): Promise<Result<Blob>> {\n return this.service.exportDb(this.name, options);\n }\n}\n","/**\n * SQL Service Types\n *\n * Type definitions for the SQL service operations.\n */\n\nimport { SQL } from \"@tinycloud/bootstrap\";\n\n/**\n * Configuration for SQLService.\n */\nexport interface SQLServiceConfig {\n /**\n * Default database name.\n * If not set, operations default to \"default\".\n */\n defaultDatabase?: string;\n\n /**\n * Timeout in milliseconds for each SQL request, including reading the\n * response body. When it elapses the request is aborted and the operation\n * returns an `ErrorCodes.TIMEOUT` error. Unset (the default), `0`, or\n * `Infinity` means no timeout.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for SQL query operations.\n */\nexport interface QueryOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n\n /** Maximum rows the node may return. Nodes without limit support ignore it. */\n maxRows?: number;\n\n /** Maximum serialized result bytes the node may return. */\n maxBytes?: number;\n}\n\n/**\n * Options for SQL execute operations.\n */\nexport interface ExecuteOptions {\n /**\n * Schema initialization statements (CREATE TABLE IF NOT EXISTS ...).\n * Executed before the main statement on first write.\n */\n schema?: string[];\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for SQL batch operations.\n */\nexport interface BatchOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A SQL value: null, number, string, or binary data.\n */\nexport type SqlValue = null | number | string | Uint8Array;\n\n/**\n * A SQL statement with optional parameters.\n */\nexport interface SqlStatement {\n sql: string;\n params?: SqlValue[];\n}\n\n/**\n * Response from SQL query operations.\n */\nexport interface QueryResponse<T = Record<string, unknown>> {\n columns: string[];\n rows: T[][];\n rowCount: number;\n}\n\n/**\n * Response from SQL execute operations.\n */\nexport interface ExecuteResponse {\n changes: number;\n lastInsertRowId: number | null;\n}\n\n/**\n * Response from SQL batch operations.\n */\nexport interface BatchResponse {\n results: ExecuteResponse[];\n}\n\n/**\n * A versioned SQL migration owned by an application or SDK subsystem.\n */\nexport interface SqlMigration {\n /**\n * Stable migration id within the namespace, e.g. \"001_initial\".\n */\n id: string;\n\n /**\n * SQL statements to apply when this migration has not been recorded.\n * Statements should be idempotent where SQLite supports it.\n */\n sql: Array<string | SqlStatement>;\n}\n\n/**\n * Options for applying SQL migrations.\n */\nexport interface SqlMigrationApplyOptions {\n /**\n * Namespace for this migration set, usually an app id or SDK subsystem.\n */\n namespace: string;\n\n /**\n * Ordered migration list.\n */\n migrations: SqlMigration[];\n\n /**\n * Custom abort signal for migration operations.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Result from applying SQL migrations.\n */\nexport interface SqlMigrationApplyResponse {\n database: string;\n namespace: string;\n status: \"already_current\" | \"applied\";\n applied: string[];\n skipped: string[];\n}\n\n/**\n * SQL service action types.\n *\n * URNs derive from the canonical capability registry in `@tinycloud/bootstrap`\n * (TC-112 single source of truth, vendored from tinycloud-node). `insert`,\n * `update`, and `delete` were dropped — zero client refs and never accepted\n * node-side. `select` is a deprecated alias of `read`. `execute`/`export` are\n * request-kind artifacts, not grantable capabilities: the node routes them by\n * request-body kind, so they are absent from the registry but kept here as the\n * invocation ability the client sends today (wire alignment tracked in TC-114).\n */\nexport const SQLAction = {\n READ: SQL.READ,\n WRITE: SQL.WRITE,\n SCHEMA: SQL.SCHEMA,\n ADMIN: SQL.ADMIN,\n SELECT: SQL.SELECT,\n EXECUTE: SQL.EXECUTE,\n EXPORT: SQL.EXPORT,\n ALL: SQL.ALL,\n} as const;\n\nexport type SQLActionType = (typeof SQLAction)[keyof typeof SQLAction];\n","/**\n * SQLService - SQL database service implementation.\n *\n * Platform-agnostic SQL service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n type FetchResponse,\n type ServiceHeaders,\n type ServiceSession,\n} from \"../types\";\nimport {\n authRequiredError,\n wrapError,\n parseAuthError,\n storageRejectionError,\n} from \"../errors\";\nimport {\n formatServiceResponseError,\n parseServiceErrorBody,\n responseErrorMeta,\n} from \"../responseErrors\";\nimport type { ISQLService } from \"./ISQLService\";\nimport type { IDatabaseHandle } from \"./ISQLService\";\nimport { DatabaseHandle } from \"./DatabaseHandle\";\nimport {\n type SQLServiceConfig,\n type QueryOptions,\n type ExecuteOptions,\n type BatchOptions,\n type SqlValue,\n type SqlStatement,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n type SqlMigration,\n type SqlMigrationApplyOptions,\n type SqlMigrationApplyResponse,\n SQLAction,\n} from \"./types\";\n\nconst DDL_TOKENS = new Set([\"alter\", \"create\", \"drop\"]);\nconst MIGRATIONS_TABLE = \"__tinycloud_sql_migrations\";\nconst MIGRATIONS_SCHEMA = `CREATE TABLE IF NOT EXISTS ${MIGRATIONS_TABLE} (\n key TEXT PRIMARY KEY,\n namespace TEXT NOT NULL,\n id TEXT NOT NULL,\n applied_at TEXT NOT NULL,\n statement_count INTEGER NOT NULL\n)`;\nconst MIGRATIONS_META_NAMESPACE = \"tinycloud.sql.migrations\";\nconst MIGRATIONS_META_ID = \"000_metadata\";\n\nexport class SQLService extends BaseService implements ISQLService {\n static readonly serviceName = \"sql\";\n\n declare protected _config: SQLServiceConfig;\n private readonly migrationLocks = new Map<string, Promise<Result<SqlMigrationApplyResponse>>>();\n\n constructor(config: SQLServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): SQLServiceConfig {\n return this._config;\n }\n\n private get defaultDbName(): string {\n return this._config.defaultDatabase ?? \"default\";\n }\n\n private get host(): string {\n return this.context.hosts[0];\n }\n\n /**\n * Get a handle to a named database.\n */\n db(name?: string): IDatabaseHandle {\n return new DatabaseHandle(this, name ?? this.defaultDbName);\n }\n\n /**\n * Shortcut: query the default database.\n */\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.queryOnDb<T>(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: execute on the default database.\n */\n async execute(\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.executeOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: batch on the default database.\n */\n async batch(\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.batchOnDb(this.defaultDbName, statements, options);\n }\n\n async applyMigrationsOnDb(\n dbName: string,\n options: SqlMigrationApplyOptions,\n ): Promise<Result<SqlMigrationApplyResponse>> {\n const validationError = validateMigrationOptions(options);\n if (validationError) {\n return err(serviceError(ErrorCodes.INVALID_INPUT, validationError, \"sql\"));\n }\n\n const lockKey = `${dbName}\\0${options.namespace}`;\n const existing = this.migrationLocks.get(lockKey);\n if (existing) {\n return existing;\n }\n\n const promise = this.applyMigrationsOnDbUnlocked(dbName, options);\n this.migrationLocks.set(lockKey, promise);\n try {\n return await promise;\n } finally {\n this.migrationLocks.delete(lockKey);\n }\n }\n\n // === Internal methods called by DatabaseHandle ===\n\n async queryOnDb<T = Record<string, unknown>>(\n dbName: string,\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.withTelemetry(\"query\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const body: Record<string, unknown> = {\n action: \"query\",\n sql,\n params: serializeSqlValues(params ?? []),\n };\n if (options?.maxRows !== undefined) body.maxRows = options.maxRows;\n if (options?.maxBytes !== undefined) body.maxBytes = options.maxBytes;\n\n const action = this.actionForSql(sql, SQLAction.READ);\n const response = await this.invokeSQL(\n dbName,\n action,\n body,\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"query\", dbName, [action]);\n }\n\n const data = (await response.json()) as QueryResponse<T>;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async executeOnDb(\n dbName: string,\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.withTelemetry(\"execute\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const body: Record<string, unknown> = {\n action: \"execute\",\n sql,\n params: serializeSqlValues(params ?? []),\n };\n if (options?.schema) {\n body.schema = options.schema;\n }\n\n const actions = [\n this.actionForSql(sql, SQLAction.WRITE),\n ...(options?.schema ?? []).map((statement) =>\n this.actionForSql(statement, SQLAction.SCHEMA),\n ),\n ];\n const requestedActions = this.dedupeActions(actions);\n const response = await this.invokeSQL(\n dbName,\n requestedActions,\n body,\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"execute\", dbName, requestedActions);\n }\n\n const data = (await response.json()) as ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async batchOnDb(\n dbName: string,\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.withTelemetry(\"batch\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const requestedActions = this.actionsForSqlBatch(statements);\n const response = await this.invokeSQL(\n dbName,\n requestedActions,\n { action: \"batch\", statements },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"batch\", dbName, requestedActions);\n }\n\n const data = (await response.json()) as BatchResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async executeStatementOnDb(\n dbName: string,\n name: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.withTelemetry(\"executeStatement\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n // TC-114: mint the dispatchable ability, not the literal method name.\n // The node has no `tinycloud.sql/execute` capability — it routes an\n // `execute_statement` request by body kind and classifies write-class\n // from the RESOLVED named statement's SQL\n // (tinycloud-node-server/src/routes/mod.rs:1168-1171). A named statement\n // may mutate, and the SQL parser rejects writes under a read/select\n // ability (tinycloud-core/src/sql/parser.rs:135) while permitting reads\n // under write (write ⊇ read), so `write` is the ability that works for\n // both read-only and mutating statements and is contained in a normal\n // read+write delegation.\n const response = await this.invokeSQL(\n dbName,\n SQLAction.WRITE,\n { action: \"execute_statement\", name, params: params ?? [] },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"executeStatement\", dbName, [SQLAction.WRITE]);\n }\n\n const data = (await response.json()) as\n | QueryResponse\n | ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async exportDb(\n dbName: string,\n options?: QueryOptions\n ): Promise<Result<Blob>> {\n return this.withTelemetry(\"export\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n // TC-114: mint the dispatchable ability, not the literal method name.\n // The node has no `tinycloud.sql/export` capability — it routes an\n // `export` request by body kind and authorizes it as a READ\n // (`SqlRequest::Export` is non-write:\n // tinycloud-node-server/src/routes/mod.rs:1172, see comment :1155).\n const response = await this.invokeSQL(\n dbName,\n SQLAction.READ,\n { action: \"export\" },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"export\", dbName, [SQLAction.READ]);\n }\n\n // FetchResponse doesn't expose blob(), so access it from the\n // underlying response which is a standard fetch Response at runtime\n const resp = response as any;\n if (typeof resp.blob === \"function\") {\n const blob = await resp.blob();\n return ok(blob as Blob);\n }\n // If blob() is not available, return the raw text as a Blob-like\n const text = await response.text();\n return ok(text as unknown as Blob);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n private async applyMigrationsOnDbUnlocked(\n dbName: string,\n options: SqlMigrationApplyOptions,\n ): Promise<Result<SqlMigrationApplyResponse>> {\n return this.withTelemetry(\"migrations.apply\", dbName, async () => {\n // Read before writing: an up-to-date database must open with a single\n // read, because writes fail once the owner's storage is full (402) and\n // read-only sessions cannot write at all.\n const listed = await this.queryOnDb<{ id: string }>(\n dbName,\n `SELECT id FROM ${MIGRATIONS_TABLE} WHERE namespace = ? ORDER BY applied_at, id`,\n [options.namespace],\n { signal: options.signal },\n );\n // A node may answer for a database that was never created with either\n // \"no such table\" or \"database not found\"; both mean nothing is applied.\n const tableMissing =\n !listed.ok &&\n (listed.error.code === ErrorCodes.SQL_DATABASE_NOT_FOUND ||\n isMissingTableError(listed.error.message));\n if (!listed.ok && !tableMissing) return listed;\n\n const appliedIds = new Set(\n (listed.ok ? listed.data.rows : [])\n .map((row) => rowValue(row, 0))\n .filter((id): id is string => typeof id === \"string\"),\n );\n const skipped = options.migrations\n .filter((migration) => appliedIds.has(migration.id))\n .map((migration) => migration.id);\n const pending = options.migrations.filter((migration) => !appliedIds.has(migration.id));\n const applied: string[] = [];\n\n if (pending.length > 0 && tableMissing) {\n const created = await this.ensureMigrationsTable(dbName, options.signal);\n if (!created.ok) return created;\n }\n\n for (const migration of pending) {\n const result = await this.applyOneMigration(dbName, options.namespace, migration, options.signal);\n if (!result.ok) return result;\n applied.push(migration.id);\n }\n\n return ok({\n database: dbName,\n namespace: options.namespace,\n status: applied.length > 0 ? \"applied\" : \"already_current\",\n applied,\n skipped,\n });\n });\n }\n\n private async applyOneMigration(\n dbName: string,\n namespace: string,\n migration: SqlMigration,\n signal?: AbortSignal,\n ): Promise<Result<void>> {\n const statements = [\n ...migration.sql.map((statement) =>\n typeof statement === \"string\" ? { sql: statement } : statement,\n ),\n {\n sql: `INSERT OR REPLACE INTO ${MIGRATIONS_TABLE} (key, namespace, id, applied_at, statement_count) VALUES (?, ?, ?, ?, ?)`,\n params: [\n migrationKey(namespace, migration.id),\n namespace,\n migration.id,\n new Date().toISOString(),\n migration.sql.length,\n ],\n },\n ];\n\n const result = await this.batchOnDb(dbName, statements, { signal });\n if (!result.ok) return result;\n return ok(undefined);\n }\n\n private async ensureMigrationsTable(\n dbName: string,\n signal?: AbortSignal,\n ): Promise<Result<void>> {\n const result = await this.batchOnDb(\n dbName,\n [\n { sql: MIGRATIONS_SCHEMA },\n {\n sql: `INSERT OR REPLACE INTO ${MIGRATIONS_TABLE} (key, namespace, id, applied_at, statement_count) VALUES (?, ?, ?, ?, ?)`,\n params: [\n migrationKey(MIGRATIONS_META_NAMESPACE, MIGRATIONS_META_ID),\n MIGRATIONS_META_NAMESPACE,\n MIGRATIONS_META_ID,\n new Date().toISOString(),\n 1,\n ],\n },\n ],\n { signal },\n );\n if (!result.ok) return result;\n return ok(undefined);\n }\n\n // === Private helpers ===\n\n private async invokeSQL(\n dbName: string,\n actions: string | string[],\n body: Record<string, unknown>,\n signal: AbortSignal\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const actionList = Array.isArray(actions) ? actions : [actions];\n const headers =\n actionList.length === 1\n ? this.context.invoke(session, \"sql\", dbName, actionList[0]!)\n : this.invokeSQLAny(session, dbName, actionList);\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body) as any,\n signal,\n });\n }\n\n private actionForSql(sql: string, fallback: string): string {\n const token = firstSqlToken(sql);\n if (token === \"pragma\") return SQLAction.ADMIN;\n if (token !== undefined && DDL_TOKENS.has(token)) return SQLAction.SCHEMA;\n return fallback;\n }\n\n private actionsForSqlBatch(statements: SqlStatement[]): string[] {\n return this.dedupeActions(\n statements.map((statement) => this.actionForSql(statement.sql, SQLAction.WRITE)),\n );\n }\n\n private dedupeActions(actions: string[]): string[] {\n return [...new Set(actions)];\n }\n\n private invokeSQLAny(\n session: ServiceSession,\n dbName: string,\n actions: string[],\n ): ServiceHeaders {\n if (!this.context.invokeAny) {\n throw new Error(\n `SQL operation requires multiple permissions (${actions.join(\", \")}) but this SDK runtime does not support multi-resource invocations`,\n );\n }\n\n return this.context.invokeAny(\n session,\n actions.map((action) => ({\n spaceId: session.spaceId,\n service: \"sql\",\n path: dbName,\n action,\n })),\n );\n }\n\n private async handleErrorResponse(\n response: FetchResponse,\n operation: string,\n dbName: string,\n requestedActions: readonly string[],\n ): Promise<Result<never>> {\n const errorText = await response.text();\n const meta = responseErrorMeta(response.status, response.statusText, errorText);\n\n // The node answers a write-class request on a full space with 402.\n if (response.status === 402) {\n return err(storageRejectionError(\"sql\", 402, meta, errorText));\n }\n\n const errorBody = parseServiceErrorBody(errorText);\n\n const errorCode = this.mapHttpStatusToErrorCode(\n response.status,\n errorBody.error\n );\n const message = formatServiceResponseError(\n \"SQL\",\n operation,\n response.status,\n errorText,\n errorBody,\n );\n\n if (response.status === 401) {\n const { action } = parseAuthError(errorText);\n if (action && requestedActions.includes(action)) {\n meta.requiredAction = action;\n meta.resource = `${this.context.session!.spaceId}/sql/${dbName}`;\n }\n }\n\n return err(\n serviceError(errorCode, message, \"sql\", { meta })\n );\n }\n\n private mapHttpStatusToErrorCode(\n status: number,\n serverError?: string\n ): string {\n switch (status) {\n case 400:\n return ErrorCodes.SQL_ERROR;\n case 401:\n return ErrorCodes.AUTH_UNAUTHORIZED;\n case 403:\n if (serverError === \"sql_readonly_violation\") {\n return ErrorCodes.SQL_READONLY_VIOLATION;\n }\n return ErrorCodes.SQL_PERMISSION_DENIED;\n case 404:\n return ErrorCodes.SQL_DATABASE_NOT_FOUND;\n case 413:\n return ErrorCodes.SQL_RESPONSE_TOO_LARGE;\n case 429:\n return ErrorCodes.SQL_QUOTA_EXCEEDED;\n default:\n return ErrorCodes.NETWORK_ERROR;\n }\n }\n}\n\nfunction firstSqlToken(sql: string): string | undefined {\n let index = 0;\n\n while (index < sql.length) {\n while (index < sql.length && /\\s/.test(sql[index])) {\n index++;\n }\n\n if (sql.startsWith(\"--\", index)) {\n const newline = sql.indexOf(\"\\n\", index + 2);\n if (newline === -1) {\n return undefined;\n }\n index = newline + 1;\n continue;\n }\n\n if (sql.startsWith(\"/*\", index)) {\n const end = sql.indexOf(\"*/\", index + 2);\n if (end === -1) {\n return undefined;\n }\n index = end + 2;\n continue;\n }\n\n break;\n }\n\n const match = /^[A-Za-z_]+/.exec(sql.slice(index));\n return match?.[0].toLowerCase();\n}\n\nfunction validateMigrationOptions(options: SqlMigrationApplyOptions): string | null {\n if (!options || typeof options !== \"object\") {\n return \"SQL migrations require options\";\n }\n if (!options.namespace || typeof options.namespace !== \"string\") {\n return \"SQL migrations require a non-empty namespace\";\n }\n if (!Array.isArray(options.migrations)) {\n return \"SQL migrations require an ordered migrations array\";\n }\n\n const ids = new Set<string>();\n for (const migration of options.migrations) {\n if (!migration.id || typeof migration.id !== \"string\") {\n return \"SQL migrations require every migration to have a non-empty id\";\n }\n if (ids.has(migration.id)) {\n return `Duplicate SQL migration id: ${migration.id}`;\n }\n ids.add(migration.id);\n\n if (!Array.isArray(migration.sql)) {\n return `SQL migration ${migration.id} requires a sql array`;\n }\n for (const statement of migration.sql) {\n if (typeof statement === \"string\") {\n if (statement.trim() === \"\") {\n return `SQL migration ${migration.id} contains an empty statement`;\n }\n continue;\n }\n if (!statement || typeof statement.sql !== \"string\" || statement.sql.trim() === \"\") {\n return `SQL migration ${migration.id} contains an invalid statement`;\n }\n }\n }\n\n return null;\n}\n\nfunction serializeSqlValues(values: SqlValue[]): Array<null | number | string | number[]> {\n return values.map((value) =>\n value instanceof Uint8Array ? Array.from(value) : value,\n );\n}\n\nfunction isMissingTableError(message: string): boolean {\n return /no such table/i.test(message);\n}\n\nfunction migrationKey(namespace: string, id: string): string {\n return `${encodeURIComponent(namespace)}:${encodeURIComponent(id)}`;\n}\n\nfunction rowValue(row: unknown, index: number): unknown {\n if (Array.isArray(row)) return row[index];\n if (row && typeof row === \"object\") {\n const values = Object.values(row as Record<string, unknown>);\n return values[index];\n }\n return undefined;\n}\n","/**\n * DuckDbDatabaseHandle - Handle for operations on a specific named database.\n *\n * Delegates all operations to the parent DuckDbService with the database name.\n */\n\nimport type { Result } from \"../types\";\nimport type { IDuckDbDatabaseHandle } from \"./IDuckDbService\";\nimport type { DuckDbService } from \"./DuckDbService\";\nimport type {\n DuckDbValue,\n DuckDbStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n SchemaInfo,\n DuckDbQueryOptions,\n DuckDbExecuteOptions,\n DuckDbBatchOptions,\n DuckDbOptions,\n} from \"./types\";\n\nexport class DuckDbDatabaseHandle implements IDuckDbDatabaseHandle {\n private service: DuckDbService;\n public readonly name: string;\n\n constructor(service: DuckDbService, name: string) {\n this.service = service;\n this.name = name;\n }\n\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.service.queryOnDb<T>(this.name, sql, params, options);\n }\n\n async queryArrow(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.service.queryArrowOnDb(this.name, sql, params, options);\n }\n\n async execute(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.service.executeOnDb(this.name, sql, params, options);\n }\n\n async batch(\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.service.batchOnDb(this.name, statements, options);\n }\n\n async executeStatement(\n name: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.service.executeStatementOnDb(this.name, name, params, options);\n }\n\n async describe(options?: DuckDbOptions): Promise<Result<SchemaInfo>> {\n return this.service.describeDb(this.name, options);\n }\n\n async export(options?: DuckDbOptions): Promise<Result<Blob>> {\n return this.service.exportOnDb(this.name, options);\n }\n\n async import(data: Uint8Array, options?: DuckDbOptions): Promise<Result<void>> {\n return this.service.importOnDb(this.name, data, options);\n }\n}\n","/**\n * DuckDB Service Types\n *\n * Type definitions for the DuckDB service operations.\n */\n\nimport { DUCKDB } from \"@tinycloud/bootstrap\";\n\n/**\n * Configuration for DuckDbService.\n */\nexport interface DuckDbServiceConfig {\n /**\n * Default database name.\n * If not set, operations default to \"default\".\n */\n defaultDatabase?: string;\n\n /**\n * Timeout in milliseconds for each DuckDB request, including reading the\n * response body. When it elapses the request is aborted and the operation\n * returns an `ErrorCodes.TIMEOUT` error. Unset (the default), `0`, or\n * `Infinity` means no timeout.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for DuckDB query operations.\n */\nexport interface DuckDbQueryOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB execute operations.\n */\nexport interface DuckDbExecuteOptions {\n /**\n * Schema initialization statements (CREATE TABLE IF NOT EXISTS ...).\n * Executed before the main statement on first write.\n */\n schema?: string[];\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB batch operations.\n */\nexport interface DuckDbBatchOptions {\n /**\n * Whether to run statements in a transaction.\n */\n transactional?: boolean;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB operations that only need an abort signal.\n */\nexport interface DuckDbOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A DuckDB value: null, boolean, number, string, binary, array, or object.\n */\nexport type DuckDbValue =\n | null\n | boolean\n | number\n | string\n | Uint8Array\n | DuckDbValueArray\n | DuckDbValueRecord;\n\n/** Array of DuckDB values (workaround for circular type alias). */\nexport interface DuckDbValueArray extends Array<DuckDbValue> {}\n\n/** Record of DuckDB values (workaround for circular type alias). */\nexport interface DuckDbValueRecord {\n [key: string]: DuckDbValue;\n}\n\n/**\n * A DuckDB statement with optional parameters.\n */\nexport interface DuckDbStatement {\n sql: string;\n params?: DuckDbValue[];\n}\n\n/**\n * Response from DuckDB query operations.\n */\nexport interface QueryResponse<T = Record<string, unknown>> {\n columns: string[];\n rows: T[][];\n rowCount: number;\n}\n\n/**\n * Response from DuckDB execute operations.\n */\nexport interface ExecuteResponse {\n changes: number;\n}\n\n/**\n * Response from DuckDB batch operations.\n */\nexport interface BatchResponse {\n results: ExecuteResponse[];\n}\n\n/**\n * Schema information for a DuckDB database.\n */\nexport interface SchemaInfo {\n tables: TableInfo[];\n views: ViewInfo[];\n}\n\n/**\n * Information about a table.\n */\nexport interface TableInfo {\n name: string;\n columns: ColumnInfo[];\n}\n\n/**\n * Information about a column.\n */\nexport interface ColumnInfo {\n name: string;\n type: string;\n nullable: boolean;\n}\n\n/**\n * Information about a view.\n */\nexport interface ViewInfo {\n name: string;\n sql: string;\n}\n\n/**\n * DuckDB service action types.\n *\n * URNs derive from the canonical capability registry in `@tinycloud/bootstrap`\n * (TC-112 single source of truth).\n */\nexport const DuckDbAction = {\n READ: DUCKDB.READ,\n WRITE: DUCKDB.WRITE,\n ADMIN: DUCKDB.ADMIN,\n DESCRIBE: DUCKDB.DESCRIBE,\n EXPORT: DUCKDB.EXPORT,\n IMPORT: DUCKDB.IMPORT,\n EXECUTE: DUCKDB.EXECUTE,\n ALL: DUCKDB.ALL,\n} as const;\n\nexport type DuckDbActionType = (typeof DuckDbAction)[keyof typeof DuckDbAction];\n","/**\n * DuckDbService - DuckDB database service implementation.\n *\n * Platform-agnostic DuckDB service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n type FetchResponse,\n} from \"../types\";\nimport {\n authRequiredError,\n wrapError,\n parseAuthError,\n storageRejectionError,\n} from \"../errors\";\nimport {\n formatServiceResponseError,\n parseServiceErrorBody,\n responseErrorMeta,\n} from \"../responseErrors\";\nimport type { IDuckDbService, IDuckDbDatabaseHandle } from \"./IDuckDbService\";\nimport { DuckDbDatabaseHandle } from \"./DuckDbDatabaseHandle\";\nimport {\n type DuckDbServiceConfig,\n type DuckDbQueryOptions,\n type DuckDbExecuteOptions,\n type DuckDbBatchOptions,\n type DuckDbOptions,\n type DuckDbValue,\n type DuckDbStatement,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n type SchemaInfo,\n DuckDbAction,\n} from \"./types\";\n\nexport class DuckDbService extends BaseService implements IDuckDbService {\n static readonly serviceName = \"duckdb\";\n\n declare protected _config: DuckDbServiceConfig;\n\n constructor(config: DuckDbServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): DuckDbServiceConfig {\n return this._config;\n }\n\n private get defaultDbName(): string {\n return this._config.defaultDatabase ?? \"default\";\n }\n\n private get host(): string {\n return this.context.hosts[0];\n }\n\n /**\n * Get a handle to a named database.\n */\n db(name?: string): IDuckDbDatabaseHandle {\n return new DuckDbDatabaseHandle(this, name ?? this.defaultDbName);\n }\n\n /**\n * Shortcut: query the default database (JSON format).\n */\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.queryOnDb<T>(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: query the default database (Arrow IPC format).\n */\n async queryArrow(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.queryArrowOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: execute on the default database.\n */\n async execute(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.executeOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: batch on the default database.\n */\n async batch(\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.batchOnDb(this.defaultDbName, statements, options);\n }\n\n // === Internal methods called by DuckDbDatabaseHandle ===\n\n async queryOnDb<T = Record<string, unknown>>(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.withTelemetry<QueryResponse<T>>(\"query\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"query\");\n }\n\n const data = (await response.json()) as QueryResponse<T>;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async queryArrowOnDb(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.withTelemetry<ArrayBuffer>(\"queryArrow\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n request.signal,\n { Accept: \"application/vnd.apache.arrow.stream\" }\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"queryArrow\");\n }\n\n const buffer = await response.arrayBuffer();\n return ok(buffer);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async executeOnDb(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.withTelemetry(\"execute\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const body: Record<string, unknown> = {\n action: \"execute\",\n sql,\n params: params ?? [],\n };\n if (options?.schema) {\n body.schema = options.schema;\n }\n\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n body,\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"execute\");\n }\n\n const data = (await response.json()) as ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async batchOnDb(\n dbName: string,\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.withTelemetry(\"batch\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const body: Record<string, unknown> = {\n action: \"batch\",\n statements,\n };\n if (options?.transactional !== undefined) {\n body.transactional = options.transactional;\n }\n\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n body,\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"batch\");\n }\n\n const data = (await response.json()) as BatchResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async executeStatementOnDb(\n dbName: string,\n name: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.withTelemetry(\"executeStatement\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n // TC-114: mint the dispatchable ability, not the literal method name.\n // The node has no `tinycloud.duckdb/execute` capability — it routes an\n // `executeStatement` request by body kind and classifies write-class\n // from the RESOLVED named statement's SQL\n // (tinycloud-node-server/src/routes/mod.rs:1698-1701). Mirroring the SQL\n // path, `write` is the ability that works for both read-only and\n // mutating named statements and is contained in a normal read+write\n // delegation.\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n { action: \"executeStatement\", name, params: params ?? [] },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"executeStatement\");\n }\n\n const data = (await response.json()) as\n | QueryResponse\n | ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async describeDb(\n dbName: string,\n options?: DuckDbOptions\n ): Promise<Result<SchemaInfo>> {\n return this.withTelemetry(\"describe\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n // TC-114: mint the dispatchable ability, not the literal method name.\n // The node has no `tinycloud.duckdb/describe` capability — it routes a\n // `describe` request by body kind and authorizes it as a READ\n // (`DuckDbRequest::Describe` is non-write:\n // tinycloud-node-server/src/routes/mod.rs:1705, see comment :1680).\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"describe\" },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"describe\");\n }\n\n const data = (await response.json()) as SchemaInfo;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async exportOnDb(\n dbName: string,\n options?: DuckDbOptions\n ): Promise<Result<Blob>> {\n return this.withTelemetry(\"export\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.EXPORT,\n { action: \"export\" },\n request.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"export\");\n }\n\n const blob = await response.blob();\n return ok(blob);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n async importOnDb(\n dbName: string,\n data: Uint8Array,\n options?: DuckDbOptions\n ): Promise<Result<void>> {\n return this.withTelemetry(\"import\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n const request = this.createRequestSignal(options?.signal);\n try {\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"duckdb\",\n dbName,\n DuckDbAction.IMPORT\n );\n\n const response = await this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/x-duckdb\",\n },\n body: new Blob([data]),\n signal: request.signal,\n });\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"import\");\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n } finally {\n request.dispose();\n }\n });\n }\n\n // === Private helpers ===\n\n private async invokeDuckDb(\n dbName: string,\n action: string,\n body: Record<string, unknown>,\n signal: AbortSignal,\n extraHeaders?: Record<string, string>\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(session, \"duckdb\", dbName, action);\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/json\",\n ...extraHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n }\n\n private async handleErrorResponse(\n response: FetchResponse,\n operation: string\n ): Promise<Result<never>> {\n const errorText = await response.text();\n const meta = responseErrorMeta(response.status, response.statusText, errorText);\n\n // The node answers a write-class request on a full space with 402.\n if (response.status === 402) {\n return err(storageRejectionError(\"duckdb\", 402, meta, errorText));\n }\n\n const errorBody = parseServiceErrorBody(errorText);\n\n const errorCode = this.mapHttpStatusToErrorCode(\n response.status,\n errorBody.error\n );\n const message = formatServiceResponseError(\n \"DuckDB\",\n operation,\n response.status,\n errorText,\n errorBody,\n );\n\n if (response.status === 401) {\n const { resource, action } = parseAuthError(errorText);\n if (action) meta.requiredAction = action;\n if (resource) meta.resource = resource;\n }\n\n return err(\n serviceError(errorCode, message, \"duckdb\", { meta })\n );\n }\n\n private mapHttpStatusToErrorCode(\n status: number,\n serverError?: string\n ): string {\n switch (status) {\n case 400:\n return ErrorCodes.DUCKDB_ERROR;\n case 401:\n return ErrorCodes.AUTH_UNAUTHORIZED;\n case 403:\n if (serverError === \"duckdb_readonly_violation\") {\n return ErrorCodes.DUCKDB_READONLY_VIOLATION;\n }\n return ErrorCodes.DUCKDB_PERMISSION_DENIED;\n case 404:\n return ErrorCodes.DUCKDB_DATABASE_NOT_FOUND;\n case 413:\n return ErrorCodes.DUCKDB_RESPONSE_TOO_LARGE;\n case 429:\n return ErrorCodes.DUCKDB_QUOTA_EXCEEDED;\n default:\n return ErrorCodes.NETWORK_ERROR;\n }\n }\n}\n","import { BaseService } from \"../base/BaseService\";\nimport type { RequestSignal } from \"../base/types\";\nimport type {\n FetchResponse,\n InvokeAnyEntry,\n ServiceError,\n ServiceHeaders,\n ServiceSession,\n Result,\n} from \"../types\";\nimport { ErrorCodes, err, ok, serviceError } from \"../types\";\nimport { authRequiredError, wrapError } from \"../errors\";\nimport type { IHooksService } from \"./IHooksService\";\nimport type {\n HookEvent,\n HookStreamEvent,\n HookSubscription,\n HooksServiceConfig,\n SubscribeOptions,\n HookWebhookListOptions,\n HookWebhookRecord,\n HookWebhookRegistration,\n HookWebhookUnregisterOptions,\n} from \"./types\";\n\ninterface HookSubscriber {\n requested: HookSubscription[];\n /** `subscriptionSignature` of each requested entry, fixed at subscribe time. */\n signatures: string[];\n ttlSeconds?: number;\n queue: AsyncQueue<HookEvent>;\n}\n\n/** The one stream the current subscribers need. */\ninterface StreamPlan {\n /** Session generation + merged subscriptions + TTL; a change supersedes the running phase. */\n key: string;\n subscriptions: HookSubscription[];\n ttlSeconds?: number;\n}\n\ntype StreamPhase = \"mint\" | \"open\" | \"read\";\n\n/** How one attempt ended. Holds only SDK-built values. */\ntype AttemptOutcome =\n | { kind: \"ended\" }\n | { kind: \"stopped\" }\n | { kind: \"refused\"; terminal: boolean; error: ServiceError }\n | { kind: \"failed\"; error: ServiceError };\n\ninterface StreamHealth {\n openedAt: number;\n delivered: boolean;\n}\nclass AsyncQueue<T> implements AsyncIterable<T>, AsyncIterator<T> {\n private readonly values: T[] = [];\n private readonly waiters: Array<{\n resolve: (result: IteratorResult<T>) => void;\n reject: (error: unknown) => void;\n }> = [];\n private closed = false;\n private failure?: unknown;\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return this;\n }\n\n push(value: T): void {\n if (this.closed) {\n return;\n }\n\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter.resolve({ value, done: false });\n return;\n }\n\n this.values.push(value);\n }\n\n close(): void {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n while (this.waiters.length > 0) {\n const waiter = this.waiters.shift();\n waiter?.resolve({ value: undefined as never, done: true });\n }\n }\n\n /**\n * Fail the queue: pending and future `next()` calls reject with `error`,\n * so a `for await` consumer sees the iterator throw.\n */\n fail(error: unknown): void {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n this.failure = error;\n while (this.waiters.length > 0) {\n const waiter = this.waiters.shift();\n waiter?.reject(error);\n }\n }\n\n next(): Promise<IteratorResult<T>> {\n if (this.values.length > 0) {\n const value = this.values.shift()!;\n return Promise.resolve({ value, done: false });\n }\n\n if (this.failure !== undefined) {\n return Promise.reject(this.failure);\n }\n\n if (this.closed) {\n return Promise.resolve({ value: undefined as never, done: true });\n }\n\n return new Promise<IteratorResult<T>>((resolve, reject) => {\n this.waiters.push({ resolve, reject });\n });\n }\n}\n\n/** First shared-stream retry delay: fast enough to ride out a ticket 401. */\nconst HOOK_STREAM_RETRY_BASE_DELAY_MS = 250;\n/** Ceiling for shared-stream retry backoff. */\nconst HOOK_STREAM_RETRY_MAX_DELAY_MS = 30_000;\n/**\n * A stream that stays open at least this long without erroring counts as\n * healthy and resets the backoff streak. A stream that delivers an event\n * resets it immediately.\n */\nconst HOOK_STREAM_HEALTHY_MS = 5_000;\n\nexport class HooksService extends BaseService implements IHooksService {\n static readonly serviceName = \"hooks\";\n\n declare protected _config: HooksServiceConfig;\n private readonly _subscribers: Set<HookSubscriber> = new Set();\n /** True while the one supervisor loop runs. Set only by wake(), cleared only at loop exit. */\n private _supervising = false;\n /** The supervisor's current step, interruptible by wake(). */\n private _phase?: { key: string; interrupt: AbortController };\n /** Bumped on every session change; part of the plan key. */\n private _sessionGeneration = 0;\n\n private _lastContextSignal?: AbortSignal;\n constructor(config: HooksServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): HooksServiceConfig {\n return this._config;\n }\n\n private get host(): string {\n return this._config.host ?? this.context.hosts[0];\n }\n\n async *subscribe(\n subscriptions: HookSubscription[],\n options: SubscribeOptions = {},\n ): AsyncIterable<HookEvent> {\n if (!this.requireAuth()) {\n throw new Error(\"Authentication required for hooks subscription\");\n }\n if (subscriptions.length === 0) {\n throw new Error(\"At least one hook subscription is required\");\n }\n\n const requested = subscriptions.map(normalizeSubscription);\n const subscriber: HookSubscriber = {\n requested,\n signatures: requested.map(subscriptionSignature),\n ttlSeconds: options.ttlSeconds,\n queue: new AsyncQueue<HookEvent>(),\n };\n const leave = (): void => {\n this._subscribers.delete(subscriber);\n subscriber.queue.close();\n this.wake();\n };\n const { signal } = options;\n if (signal?.aborted) {\n return;\n }\n signal?.addEventListener(\"abort\", leave, { once: true });\n this._subscribers.add(subscriber);\n this.wake();\n\n try {\n for await (const event of subscriber.queue) {\n yield event;\n }\n } finally {\n signal?.removeEventListener(\"abort\", leave);\n leave();\n }\n }\n\n async register(\n webhook: HookWebhookRegistration,\n ): Promise<Result<HookWebhookRecord>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n if (typeof webhook.secret !== \"string\" || webhook.secret.trim().length === 0) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n \"Webhook secret is required\",\n \"hooks\",\n { meta: { field: \"secret\" } },\n ),\n );\n }\n\n try {\n const response = await this.context.fetch(`${this.host}/hooks/webhooks`, {\n method: \"POST\",\n headers: {\n ...serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/register\",\n buildScopePath(webhook.service, webhook.pathPrefix),\n ),\n ),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n space: webhook.space,\n service: webhook.service,\n pathPrefix: normalizePathPrefix(webhook.pathPrefix),\n abilities: webhook.abilities ?? [],\n callbackUrl: webhook.callbackUrl,\n secret: webhook.secret,\n }),\n });\n\n if (!response.ok) {\n return err(\n await responseError(\"hooks\", \"failed to register webhook\", response),\n );\n }\n\n const data = normalizeWebhookRecord(await response.json());\n if (!data) {\n return err(\n wrapError(\n \"hooks\",\n new Error(\"Webhook registration response did not include a record\"),\n ),\n );\n }\n\n return ok(data);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n async list(\n options: HookWebhookListOptions = {},\n ): Promise<Result<HookWebhookRecord[]>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n try {\n const query = new URLSearchParams();\n if (options.space) {\n query.set(\"space\", options.space);\n }\n if (options.service) {\n query.set(\"service\", options.service);\n }\n if (options.pathPrefix) {\n const normalizedPrefix = normalizePathPrefix(options.pathPrefix);\n if (normalizedPrefix) {\n query.set(\"prefix\", normalizedPrefix);\n }\n }\n\n const response = await this.context.fetch(\n `${this.host}/hooks/webhooks${query.size > 0 ? `?${query.toString()}` : \"\"}`,\n {\n method: \"GET\",\n headers: serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/list\",\n options.service\n ? buildScopePath(options.service, options.pathPrefix)\n : \"webhooks\",\n ),\n ),\n },\n );\n\n if (!response.ok) {\n return err(\n await responseError(\"hooks\", \"failed to list webhooks\", response),\n );\n }\n\n const payload = await response.json();\n const records = normalizeWebhookRecordList(payload);\n if (!records) {\n return err(\n wrapError(\n \"hooks\",\n new Error(\"Webhook list response did not include records\"),\n ),\n );\n }\n\n return ok(records);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n async unregister(\n id: string,\n options: HookWebhookUnregisterOptions = {},\n ): Promise<Result<void>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n try {\n const response = await this.context.fetch(\n `${this.host}/hooks/webhooks/${encodeURIComponent(id)}`,\n {\n method: \"DELETE\",\n headers: serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/unregister\",\n options.target\n ? buildScopePath(\n options.target.service,\n options.target.pathPrefix,\n )\n : `webhooks/${id}`,\n ),\n ),\n },\n );\n\n if (!response.ok) {\n return err(\n await responseError(\n \"hooks\",\n \"failed to unregister webhook\",\n response,\n ),\n );\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n /**\n * Called after anything that may change what the supervisor should do:\n * subscribe, unsubscribe, session change, sign-out. Interrupts the running\n * step if the plan moved away from it, and starts the supervisor if none\n * runs. Touches only SDK-owned state, so it never throws into callers such\n * as `ServiceContext.setSession`.\n */\n private wake(): void {\n const phase = this._phase;\n if (phase && phase.key !== this.plan()?.key) {\n phase.interrupt.abort();\n }\n if (this._supervising || this._subscribers.size === 0) {\n return;\n }\n this._supervising = true;\n this.supervise().catch(() => this.collapse());\n }\n\n /**\n * The only owner of the shared stream. Each iteration is one attempt\n * (mint → open → drain), then a classification and, unless the attempt was\n * superseded or released its subscribers, a backoff. Every await is a\n * `phase` that wake() can interrupt; an interrupted phase yields\n * `undefined`, so a superseded mint can never act. Outside `attempt` and\n * `pause`, which each own one catch, the loop touches only SDK state.\n */\n private async supervise(): Promise<void> {\n let streak = 0;\n for (;;) {\n const plan = this.plan();\n if (!plan) {\n // Same synchronous turn as the emptiness check: a subscribe() that\n // runs after this line starts a fresh supervisor.\n this._supervising = false;\n return;\n }\n const health: StreamHealth = { openedAt: 0, delivered: false };\n const outcome = await this.phase(plan.key, (signal) =>\n this.attempt(plan, signal, health),\n );\n if (\n health.delivered ||\n (health.openedAt > 0 &&\n performance.now() - health.openedAt >= HOOK_STREAM_HEALTHY_MS)\n ) {\n streak = 0;\n }\n if (!outcome) {\n continue;\n }\n if (this.plan()?.key !== plan.key) {\n continue;\n }\n if (outcome.kind === \"stopped\") {\n this.release();\n continue;\n }\n if (outcome.kind === \"refused\" && outcome.terminal) {\n this.release(outcome.error);\n this.report(outcome.error);\n continue;\n }\n if (outcome.kind !== \"ended\") {\n this.report(outcome.error);\n }\n streak += 1;\n await this.phase(plan.key, (signal) =>\n this.pause(streak, signal),\n );\n }\n }\n\n /**\n * Run one step under an interrupt that wake() fires when the plan key moves\n * on. An interrupted step's result is discarded. The interrupt is also\n * fired when the step returns, which releases whatever it left open: the\n * request signal and its listeners, an unread response body, a timer.\n */\n private async phase<T>(\n key: string,\n step: (signal: AbortSignal) => Promise<T>,\n ): Promise<T | undefined> {\n const interrupt = new AbortController();\n this._phase = { key, interrupt };\n try {\n if (this.plan()?.key !== key) {\n // A wake between two phases found nothing to interrupt.\n interrupt.abort();\n }\n const result = await step(interrupt.signal);\n return interrupt.signal.aborted ? undefined : result;\n } finally {\n this._phase = undefined;\n interrupt.abort();\n }\n }\n\n /**\n * One mint → open → drain. The single catch site for everything the\n * attempt touches that the SDK does not own: context accessors, invoke,\n * fetch, response bodies, the SSE parser. Never rejects.\n */\n private async attempt(\n plan: StreamPlan,\n signal: AbortSignal,\n health: StreamHealth,\n ): Promise<AttemptOutcome> {\n let phase: StreamPhase = \"mint\";\n let request: RequestSignal | undefined;\n const owns = (): boolean =>\n !signal.aborted && !request?.signal.aborted && this.plan()?.key === plan.key;\n try {\n const context = this.context;\n const contextSignal = context.abortSignal;\n this._lastContextSignal = contextSignal;\n if (!context.isAuthenticated || contextSignal?.aborted) {\n return { kind: \"stopped\" };\n }\n request = this.createRequestSignal(signal, 0);\n const host = this.host;\n const minted = await awaitOwned(request!.signal, () =>\n context.fetch(`${host}/hooks/tickets`, {\n method: \"POST\",\n headers: {\n ...serviceHeadersToRecord(this.createInvokeHeaders(plan.subscriptions)),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n subscriptions: plan.subscriptions,\n ttlSeconds: plan.ttlSeconds,\n }),\n signal: request!.signal,\n }),\n );\n if (!owns()) return { kind: \"stopped\" };\n if (!minted.ok) {\n const status = minted.status;\n const error = await awaitOwned(request!.signal, () =>\n responseError(\"hooks\", \"failed to mint hook ticket\", minted),\n );\n if (!owns()) return { kind: \"stopped\" };\n return { kind: \"refused\", terminal: isTerminalMintRefusal(status), error };\n }\n const body: unknown = await awaitOwned(request!.signal, () => minted.json());\n if (!owns()) return { kind: \"stopped\" };\n const ticket =\n body !== null && typeof body === \"object\" && \"ticket\" in body\n ? body.ticket\n : undefined;\n if (typeof ticket !== \"string\" || ticket.length === 0) {\n throw new Error(\"Hook ticket response did not include a ticket\");\n }\n\n phase = \"open\";\n if (!owns()) return { kind: \"stopped\" };\n const stream = await awaitOwned(request!.signal, () =>\n context.fetch(`${host}/hooks/events?ticket=${encodeURIComponent(ticket)}`, {\n method: \"GET\",\n headers: { accept: \"text/event-stream\" },\n signal: request!.signal,\n }),\n );\n if (!owns()) return { kind: \"stopped\" };\n if (!stream.ok) {\n return { kind: \"refused\", terminal: false, error: hookStreamRefusal(stream.status) };\n }\n\n health.openedAt = performance.now();\n const iterator = parseSseStream(stream.body, request.signal)[Symbol.asyncIterator]();\n try {\n for (;;) {\n const next = await awaitOwned(request!.signal, () => iterator.next());\n if (!owns()) return { kind: \"stopped\" };\n if (next.done) break;\n const message = next.value;\n if (!message.data) continue;\n const event = parseHookEvent(message);\n if (!owns()) return { kind: \"stopped\" };\n this.dispatch(event);\n health.delivered = true;\n }\n } finally {\n const closing = iterator.return?.();\n if (closing) void Promise.resolve(closing).then(() => undefined, () => undefined);\n }\n return owns() ? { kind: \"ended\" } : { kind: \"stopped\" };\n } catch (thrown) {\n return request?.signal.aborted || thrown === SUPERSEDED\n ? { kind: \"stopped\" }\n : { kind: \"failed\", error: hookStreamFailure(phase, thrown) };\n }\n }\n\n /**\n * Back off before the next attempt. `config.streamRetry` overrides the\n * delay and the clock; whatever they do, the pause ends by the delay or the\n * interrupt, then yields one timer turn so an instant clock cannot starve\n * due timers or the process.\n */\n private async pause(attempt: number, signal: AbortSignal): Promise<void> {\n try {\n this._lastContextSignal = this.context.abortSignal;\n } catch {\n // A hostile context signal getter cannot prevent the next attempt.\n }\n const contextSignal = this._lastContextSignal;\n const waits: Promise<void>[] = [];\n const aborts: Array<{ promise: Promise<void>; dispose: () => void }> = [];\n try {\n const retry = this._config.streamRetry;\n const delayMs = retry?.delay?.(attempt) ?? hookStreamRetryDelay(attempt);\n waits.push((retry?.wait ?? sleep)(delayMs, attempt, signal));\n } catch {\n waits.push(Promise.resolve());\n }\n aborts.push(abortPromise(signal));\n if (contextSignal) aborts.push(abortPromise(contextSignal));\n try {\n await Promise.race([...waits, ...aborts.map(({ promise }) => promise)]);\n } catch {\n // A rejecting custom clock counts as an elapsed delay.\n } finally {\n for (const abort of aborts) abort.dispose();\n }\n // Use a referenced timer: due timers (including runner timeouts) must run\n // before the supervisor starts another iteration, regardless of immediates.\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n }\n\n /** The stream the current subscribers need, or undefined when none remain. */\n private plan(): StreamPlan | undefined {\n if (this._subscribers.size === 0) {\n return undefined;\n }\n const merged = new Map<string, HookSubscription>();\n let ttlSeconds: number | undefined;\n for (const subscriber of this._subscribers) {\n subscriber.requested.forEach((subscription, index) =>\n merged.set(subscriber.signatures[index], subscription),\n );\n if (typeof subscriber.ttlSeconds === \"number\") {\n ttlSeconds = Math.min(subscriber.ttlSeconds, ttlSeconds ?? Infinity);\n }\n }\n const signatures = [...merged.keys()].sort();\n return {\n key: JSON.stringify([this._sessionGeneration, signatures, ttlSeconds ?? null]),\n subscriptions: signatures.map((signature) => merged.get(signature)!),\n ttlSeconds,\n };\n }\n\n private dispatch(event: HookEvent): void {\n for (const subscriber of this._subscribers) {\n if (matchesAnySubscription(event, subscriber.requested)) {\n subscriber.queue.push(event);\n }\n }\n }\n\n /**\n * Detach every subscriber. With `error`, their iterators throw it after\n * draining buffered events; without, they complete.\n */\n private release(error?: ServiceError): void {\n const subscribers = [...this._subscribers];\n this._subscribers.clear();\n for (const { queue } of subscribers) {\n if (error) {\n queue.fail(error);\n } else {\n queue.close();\n }\n }\n }\n\n private report(error: ServiceError): void {\n if (error.meta && typeof error.meta === \"object\") {\n Object.freeze(error.meta);\n }\n Object.freeze(error);\n try {\n this.emitError(error, \"stream\");\n } catch {\n // Telemetry never steers the stream.\n }\n }\n\n /**\n * Unreachable by construction. If the loop ever rejects anyway, fail its\n * subscribers visibly instead of stranding them or crashing the process.\n */\n private collapse(): void {\n this._supervising = false;\n this._phase?.interrupt.abort();\n this._phase = undefined;\n const error = serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"hook stream supervisor stopped unexpectedly\",\n \"hooks\",\n );\n this.report(error);\n this.release(error);\n }\n\n override onSessionChange(session: ServiceSession | null): void {\n super.onSessionChange(session);\n // New credentials supersede the running attempt: it re-mints, or stops\n // if the session is gone.\n this._sessionGeneration += 1;\n this.wake();\n }\n\n override onSignOut(): void {\n super.onSignOut();\n // Sign-out ends every subscription; the empty plan stops the supervisor.\n this.release();\n this.wake();\n }\n\n private createHookHeaders(action: string, path: string): ServiceHeaders {\n return this.context.invoke(this.session, \"hooks\", path, action);\n }\n\n private createInvokeHeaders(\n subscriptions: HookSubscription[],\n ): ServiceHeaders {\n const entries: InvokeAnyEntry[] = subscriptions.map((subscription) => ({\n spaceId: subscription.space,\n service: \"hooks\",\n path: subscription.pathPrefix\n ? `${subscription.service}/${subscription.pathPrefix}`\n : subscription.service,\n action: \"tinycloud.hooks/subscribe\",\n }));\n\n if (this.context.invokeAny) {\n return this.context.invokeAny(this.session, entries);\n }\n\n if (entries.length === 1) {\n const entry = entries[0];\n return this.context.invoke(\n this.session,\n entry.service,\n entry.path,\n entry.action,\n );\n }\n\n throw new Error(\n \"This SDK runtime does not support multi-scope hook invocations\",\n );\n }\n}\n\nfunction buildScopePath(\n service: HookSubscription[\"service\"],\n pathPrefix?: string,\n): string {\n const normalized = normalizePathPrefix(pathPrefix);\n return normalized ? `${service}/${normalized}` : service;\n}\n\n/**\n * Exponential backoff for the shared hook stream, with equal jitter: each\n * delay lands in [cap/2, cap] where cap doubles per attempt, so retries are\n * never zero-delay and never exceed HOOK_STREAM_RETRY_MAX_DELAY_MS.\n */\nfunction hookStreamRetryDelay(attempt: number): number {\n const cap = Math.min(\n HOOK_STREAM_RETRY_BASE_DELAY_MS * 2 ** Math.max(0, attempt - 1),\n HOOK_STREAM_RETRY_MAX_DELAY_MS,\n );\n return cap / 2 + Math.random() * (cap / 2);\n}\n\n/**\n * A 4xx mint refusal is the node saying no for this session and scope set,\n * so retrying cannot help. 408 and 429 mean \"not now\".\n */\nfunction isTerminalMintRefusal(status: unknown): boolean {\n return (\n typeof status === \"number\" &&\n status >= 400 &&\n status < 500 &&\n status !== 408 &&\n status !== 429\n );\n}\n\nconst SUPERSEDED = Symbol(\"hooks attempt superseded\");\n\n/** Race one foreign operation against the attempt interrupt and observe late results. */\nasync function awaitOwned<T>(\n signal: AbortSignal,\n operation: Promise<T> | (() => Promise<T>),\n): Promise<T> {\n if (signal.aborted) {\n if (typeof operation !== \"function\") {\n void operation.then(cancelLateResponse, () => undefined);\n }\n throw SUPERSEDED;\n }\n const promise = typeof operation === \"function\" ? operation() : operation;\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n const cleanup = (): void => signal.removeEventListener(\"abort\", onAbort);\n const onAbort = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(SUPERSEDED);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n promise.then(\n (value) => {\n if (settled) {\n cancelLateResponse(value);\n return;\n }\n settled = true;\n cleanup();\n resolve(value);\n },\n (error: unknown) => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n },\n );\n });\n}\n\nfunction cancelLateResponse(value: unknown): void {\n if (!(value instanceof Response) || !value.body) return;\n try {\n const cancellation = value.body.cancel();\n void cancellation.then(() => undefined, () => undefined);\n } catch {\n // A late body is best-effort cleanup.\n }\n}\n\n/*\n * Stream errors are built from an allow-list, never copied. Past the mint the\n * ticket rides in the request URL, and a mint request carries invocation\n * headers, so any foreign error text (message, cause, stack, meta, a\n * response body) may hold a bearer credential. These builders keep the\n * phase, a numeric HTTP status, and the thrown value's `name`/`code` when\n * they are plain identifiers. Nothing else crosses into telemetry.\n */\nfunction hookStreamRefusal(status: unknown): ServiceError {\n const code = typeof status === \"number\" ? status : undefined;\n return serviceError(\n ErrorCodes.NETWORK_ERROR,\n `hook stream open refused: ${code ?? \"unknown status\"}`,\n \"hooks\",\n { meta: { phase: \"open\", status: code } },\n );\n}\n\nconst STREAM_ERROR_NAMES = new Set([\n \"Error\",\n \"TypeError\",\n \"AbortError\",\n \"TimeoutError\",\n \"SyntaxError\",\n \"RangeError\",\n \"NetworkError\",\n]);\n\nfunction hookStreamFailure(phase: StreamPhase, thrown: unknown): ServiceError {\n const candidateName = readProperty(thrown, \"name\");\n const name =\n typeof candidateName === \"string\" && STREAM_ERROR_NAMES.has(candidateName)\n ? candidateName\n : \"Error\";\n const code =\n identifier(readProperty(thrown, \"code\")) ??\n identifier(readProperty(readProperty(thrown, \"cause\"), \"code\"));\n return serviceError(\n ErrorCodes.NETWORK_ERROR,\n `hook stream ${phase} failed: ${name}${code ? ` (${code})` : \"\"}`,\n \"hooks\",\n { meta: { phase, errorName: name, ...(code ? { errorCode: code } : {}) } },\n );\n}\n\nconst STREAM_ERROR_CODES = new Set([\n \"ECONNREFUSED\", \"ECONNRESET\", \"ECONNABORTED\", \"ETIMEDOUT\", \"EPIPE\",\n \"ENOTFOUND\", \"EAI_AGAIN\", \"EHOSTUNREACH\", \"ENETUNREACH\", \"ENETDOWN\",\n \"EADDRNOTAVAIL\", \"UND_ERR_SOCKET\", \"UND_ERR_CONNECT_TIMEOUT\",\n \"UND_ERR_HEADERS_TIMEOUT\", \"UND_ERR_BODY_TIMEOUT\", \"UND_ERR_CLOSED\",\n \"UND_ERR_ABORTED\", \"UND_ERR_RESPONSE_STATUS_CODE\",\n \"ERR_TLS_CERT_ALTNAME_INVALID\", \"CERT_HAS_EXPIRED\",\n \"DEPTH_ZERO_SELF_SIGNED_CERT\", \"UNABLE_TO_VERIFY_LEAF_SIGNATURE\",\n \"SELF_SIGNED_CERT_IN_CHAIN\", \"ERR_SSL_WRONG_VERSION_NUMBER\",\n]);\n\nfunction identifier(value: unknown): string | undefined {\n return typeof value === \"string\" && STREAM_ERROR_CODES.has(value)\n ? value\n : undefined;\n}\n\n/** Read one property off a value the SDK does not own; a throwing getter or proxy trap reads as absent. */\nfunction readProperty(value: unknown, key: string): unknown {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) {\n return undefined;\n }\n try {\n return Reflect.get(value, key);\n } catch {\n return undefined;\n }\n}\n\n/** The default retry clock: abortable and unref'd, so a parked backoff never keeps the process alive. */\nfunction sleep(delayMs: number, _attempt: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const finish = (): void => {\n clearTimeout(timer);\n signal.removeEventListener(\"abort\", stop);\n resolve();\n };\n const timer = setTimeout(finish, delayMs);\n timer.unref?.();\n const stop = (): void => finish();\n if (signal.aborted) {\n finish();\n } else {\n signal.addEventListener(\"abort\", stop, { once: true });\n }\n });\n}\n\nfunction abortPromise(signal: AbortSignal): {\n promise: Promise<void>;\n dispose: () => void;\n} {\n let resolve!: () => void;\n const promise = new Promise<void>((done) => {\n resolve = done;\n });\n const onAbort = (): void => resolve();\n if (signal.aborted) {\n resolve();\n } else {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n return {\n promise,\n dispose: () => signal.removeEventListener(\"abort\", onAbort),\n };\n}\n\nfunction normalizeSubscription(\n subscription: HookSubscription,\n): HookSubscription {\n return {\n ...subscription,\n pathPrefix: normalizePathPrefix(subscription.pathPrefix),\n abilities: subscription.abilities ? [...subscription.abilities] : [],\n };\n}\n\nfunction subscriptionSignature(subscription: HookSubscription): string {\n return JSON.stringify({\n space: subscription.space,\n service: subscription.service,\n pathPrefix: subscription.pathPrefix ?? \"\",\n abilities: [...(subscription.abilities ?? [])].sort(),\n });\n}\n\nfunction matchesAnySubscription(\n event: HookEvent,\n subscriptions: HookSubscription[],\n): boolean {\n return subscriptions.some((subscription) =>\n matchesSubscription(event, subscription),\n );\n}\n\nfunction matchesSubscription(\n event: HookEvent,\n subscription: HookSubscription,\n): boolean {\n if (event.space !== subscription.space) {\n return false;\n }\n if (event.service !== subscription.service) {\n return false;\n }\n if (subscription.pathPrefix) {\n const prefix = subscription.pathPrefix.endsWith(\"/\")\n ? subscription.pathPrefix\n : `${subscription.pathPrefix}/`;\n if (\n event.path &&\n event.path !== subscription.pathPrefix &&\n !event.path.startsWith(prefix)\n ) {\n return false;\n }\n }\n const abilities = subscription.abilities ?? [];\n if (abilities.length > 0 && !abilities.includes(event.ability)) {\n return false;\n }\n return true;\n}\n\nfunction normalizePathPrefix(pathPrefix?: string): string | undefined {\n if (!pathPrefix) {\n return undefined;\n }\n const trimmed = pathPrefix.replace(/^\\/+|\\/+$/g, \"\");\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction serviceHeadersToRecord(\n headers: ServiceHeaders,\n): Record<string, string> {\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers);\n }\n return { ...headers };\n}\n\nasync function responseError(\n service: string,\n message: string,\n response: FetchResponse,\n): Promise<ReturnType<typeof wrapError>> {\n let detail = response.statusText;\n try {\n const text = await response.text();\n if (text) {\n detail = text;\n }\n } catch {\n // Ignore secondary body read failure.\n }\n const error = wrapError(\n service,\n new Error(`${message}: ${response.status} ${detail}`),\n );\n // Typed status so callers never have to read it back out of the message.\n return {\n ...error,\n meta: { ...error.meta, status: response.status, statusText: response.statusText },\n };\n}\n\nasync function* parseSseStream(\n body: unknown,\n signal?: AbortSignal,\n): AsyncIterable<HookStreamEvent> {\n if (!body) {\n throw new Error(\"Hook stream response does not expose a readable body\");\n }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n for await (const chunk of readBodyChunks(body, signal)) {\n buffer += decoder.decode(chunk, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n\n let separatorIndex = buffer.indexOf(\"\\n\\n\");\n while (separatorIndex >= 0) {\n const rawEvent = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + 2);\n const parsed = parseSseEvent(rawEvent);\n if (parsed) {\n yield parsed;\n }\n separatorIndex = buffer.indexOf(\"\\n\\n\");\n }\n }\n\n buffer += decoder.decode();\n const trailing = parseSseEvent(buffer.trim());\n if (trailing) {\n yield trailing;\n }\n}\n\nasync function* readBodyChunks(\n body: unknown,\n signal?: AbortSignal,\n): AsyncIterable<Uint8Array> {\n const asyncIterable = body as AsyncIterable<Uint8Array>;\n if (typeof asyncIterable?.[Symbol.asyncIterator] === \"function\") {\n const iterator = asyncIterable[Symbol.asyncIterator]();\n const cancel = (): void => {\n try {\n const closing = iterator.return?.();\n if (closing) void Promise.resolve(closing).then(() => undefined, () => undefined);\n } catch {\n // Cancellation must not mask the stream result.\n }\n };\n signal?.addEventListener(\"abort\", cancel, { once: true });\n try {\n while (!signal?.aborted) {\n const next = await iterator.next();\n if (next.done) break;\n yield next.value;\n }\n } finally {\n signal?.removeEventListener(\"abort\", cancel);\n cancel();\n }\n return;\n }\n const stream = body as {\n getReader?: () => {\n read: () => Promise<{ done: boolean; value?: Uint8Array }>;\n releaseLock?: () => void;\n cancel?: () => Promise<void>;\n };\n };\n\n if (typeof stream.getReader !== \"function\") {\n throw new Error(\"Unsupported hook stream body type\");\n }\n\n const reader = stream.getReader();\n const cancelReader = (): void => {\n try {\n const cancellation = reader.cancel?.();\n if (cancellation) void cancellation.then(() => undefined, () => undefined);\n } catch {\n // Cancellation must not mask the stream result.\n }\n };\n signal?.addEventListener(\"abort\", cancelReader, { once: true });\n try {\n while (!signal?.aborted) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) yield value;\n }\n } finally {\n signal?.removeEventListener(\"abort\", cancelReader);\n cancelReader();\n reader.releaseLock?.();\n }\n}\n\nfunction parseSseEvent(rawEvent: string): HookStreamEvent | null {\n if (!rawEvent) {\n return null;\n }\n\n let event = \"message\";\n let id: string | undefined;\n const dataLines: string[] = [];\n\n for (const line of rawEvent.split(\"\\n\")) {\n if (!line || line.startsWith(\":\")) {\n continue;\n }\n const [field, ...rest] = line.split(\":\");\n const value = rest.join(\":\").replace(/^ /, \"\");\n switch (field) {\n case \"event\":\n event = value;\n break;\n case \"id\":\n id = value;\n break;\n case \"data\":\n dataLines.push(value);\n break;\n default:\n break;\n }\n }\n\n if (dataLines.length === 0) {\n return null;\n }\n\n return {\n event,\n id,\n data: dataLines.join(\"\\n\"),\n };\n}\n\nfunction parseHookEvent(message: HookStreamEvent): HookEvent {\n const parsed = JSON.parse(message.data) as Partial<HookEvent>;\n return {\n type: \"write\",\n id: parsed.id ?? message.id ?? \"\",\n space: parsed.space ?? \"\",\n service: parsed.service ?? \"\",\n ability: parsed.ability ?? \"\",\n path: parsed.path,\n actor: parsed.actor ?? \"\",\n epoch: parsed.epoch ?? \"\",\n eventIndex: parsed.eventIndex ?? 0,\n timestamp: parsed.timestamp ?? \"\",\n };\n}\n\nfunction normalizeWebhookRecord(data: unknown): HookWebhookRecord | null {\n if (!data || typeof data !== \"object\") {\n return null;\n }\n\n const record = isRecordContainer(data);\n const candidate =\n pickWebhookRecord(record) ??\n normalizeWebhookRecord(record.webhook) ??\n normalizeWebhookRecord(record.hook) ??\n normalizeWebhookRecord(record.subscription) ??\n normalizeWebhookRecord(record.data);\n return candidate ?? null;\n}\n\nfunction normalizeWebhookRecordList(data: unknown): HookWebhookRecord[] | null {\n if (Array.isArray(data)) {\n const records = data\n .map((entry) => normalizeWebhookRecord(entry))\n .filter((entry): entry is HookWebhookRecord => entry !== null);\n return records;\n }\n\n if (!data || typeof data !== \"object\") {\n return null;\n }\n\n const record = isRecordContainer(data);\n const nested =\n maybeRecordArray(record.webhooks) ??\n maybeRecordArray(record.subscriptions) ??\n maybeRecordArray(record.hooks) ??\n maybeRecordArray(record.data);\n if (nested) {\n return nested;\n }\n\n const single = pickWebhookRecord(record);\n return single ? [single] : null;\n}\n\nfunction maybeRecordArray(value: unknown): HookWebhookRecord[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n\n const records = value\n .map((entry) => normalizeWebhookRecord(entry))\n .filter((entry): entry is HookWebhookRecord => entry !== null);\n return records;\n}\n\nfunction pickWebhookRecord(\n value: Record<string, unknown>,\n): HookWebhookRecord | null {\n const id = stringField(value, \"id\");\n const space = stringField(value, \"space\") ?? stringField(value, \"spaceId\");\n const service = stringField(value, \"service\");\n const callbackUrl =\n stringField(value, \"callbackUrl\") ?? stringField(value, \"callback_url\");\n if (!id || !space || !service || !callbackUrl) {\n return null;\n }\n\n return {\n id,\n space,\n service: service as HookWebhookRecord[\"service\"],\n pathPrefix:\n optionalStringField(value, \"pathPrefix\") ??\n optionalStringField(value, \"path_prefix\"),\n abilities:\n stringArrayField(value, \"abilities\") ??\n parsedStringArrayField(value, \"abilitiesJson\") ??\n parsedStringArrayField(value, \"abilities_json\"),\n callbackUrl,\n active: booleanField(value, \"active\") ?? true,\n createdAt:\n stringField(value, \"createdAt\") ??\n stringField(value, \"created_at\") ??\n new Date().toISOString(),\n subscriberDid:\n optionalStringField(value, \"subscriberDid\") ??\n optionalStringField(value, \"subscriber_did\"),\n };\n}\n\nfunction isRecordContainer(value: object): Record<string, unknown> {\n return value as Record<string, unknown>;\n}\n\nfunction stringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n const field = value[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction optionalStringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n return stringField(value, key);\n}\n\nfunction booleanField(\n value: Record<string, unknown>,\n key: string,\n): boolean | undefined {\n const field = value[key];\n return typeof field === \"boolean\" ? field : undefined;\n}\n\nfunction stringArrayField(\n value: Record<string, unknown>,\n key: string,\n): string[] | undefined {\n const field = value[key];\n if (!Array.isArray(field)) {\n return undefined;\n }\n const strings = field.filter(\n (item): item is string => typeof item === \"string\",\n );\n return strings.length === field.length ? strings : undefined;\n}\n\nfunction parsedStringArrayField(\n value: Record<string, unknown>,\n key: string,\n): string[] | undefined {\n const field = value[key];\n if (typeof field !== \"string\") {\n return undefined;\n }\n\n try {\n const parsed = JSON.parse(field) as unknown;\n if (!Array.isArray(parsed)) {\n return undefined;\n }\n const strings = parsed.filter(\n (item): item is string => typeof item === \"string\",\n );\n return strings.length === parsed.length ? strings : undefined;\n } catch {\n return undefined;\n }\n}\n","import type { StorageQuotaInfo } from \"../types\";\n\nexport interface QuotaConfig {\n /** Called when a storage quota error is detected (402/413) */\n onUpgradeRequired?: (info: StorageQuotaInfo) => void;\n}\n\nexport interface QuotaStatus {\n /** Storage limit in bytes for this space */\n limitBytes: number;\n /** Storage used in bytes for this space */\n usedBytes?: number;\n /** Remaining storage in bytes */\n remainingBytes?: number;\n}\n\nexport class TinyCloudQuota {\n private config: QuotaConfig;\n private quotaUrl: string | null = null;\n\n constructor(config: QuotaConfig = {}) {\n this.config = config;\n }\n\n /** Set the quota URL discovered from the /info endpoint */\n setQuotaUrl(url: string | null): void {\n this.quotaUrl = url;\n }\n\n /** Whether a quota service is available */\n get available(): boolean {\n return this.quotaUrl !== null;\n }\n\n /** Query quota status for a space from the quota URL */\n async getQuota(spaceId: string): Promise<QuotaStatus | null> {\n if (!this.quotaUrl) return null;\n\n const resp = await fetch(\n `${this.quotaUrl}/api/quota/${encodeURIComponent(spaceId)}`\n );\n if (!resp.ok) return null;\n\n const data = (await resp.json()) as { storage_limit_bytes?: number };\n return {\n limitBytes: data.storage_limit_bytes ?? 0,\n };\n }\n\n /** Trigger the upgrade callback when a quota error is encountered */\n handleQuotaError(info: StorageQuotaInfo): void {\n this.config.onUpgradeRequired?.(info);\n }\n}\n","/**\n * Data Vault Service Types\n *\n * Type definitions for the Data Vault (encrypted KV) service operations.\n */\n\nimport type {\n DecryptCapabilityProof,\n IEncryptionService,\n} from \"../encryption\";\nimport type { PermissionHint } from \"../types\";\n\nexport interface VaultNetworkEncryptionConfig {\n /** Default encryption network used for inline vault envelopes. */\n networkId: string;\n /** TinyCloud encryption module used for local encrypt and node-mediated decrypt. */\n service: IEncryptionService;\n /** Proof material presented to the encryption module for decrypt requests. */\n decryptCapabilityProof?:\n | DecryptCapabilityProof\n | (() => DecryptCapabilityProof | Promise<DecryptCapabilityProof>);\n}\n\n/**\n * Configuration for DataVaultService.\n */\nexport interface DataVaultConfig {\n /** Space ID for encrypted data storage */\n spaceId: string;\n /** Key rotation policy */\n keyRotation?: \"per-write\" | \"per-key\"; // default: \"per-write\"\n /** Network-envelope encryption mode. When set, vault.unlock/key grants are not used. */\n encryption?: VaultNetworkEncryptionConfig;\n}\n\n/**\n * Options for vault put operations.\n */\nexport interface VaultPutOptions {\n /** Custom metadata tags appended to the envelope */\n metadata?: Record<string, string>;\n /** Content type hint for deserialization (default: auto-detect) */\n contentType?: string;\n /** Custom serializer (default: JSON.stringify for objects) */\n serialize?: (value: unknown) => Uint8Array;\n}\n\n/**\n * Options for vault get operations.\n */\nexport interface VaultGetOptions<T = unknown> {\n /** Custom deserializer (default: JSON.parse if content-type is JSON) */\n deserialize?: (data: Uint8Array) => T;\n /** Return raw decrypted bytes without deserialization */\n raw?: boolean;\n /** Delegated KV service for reading from the grantor's space (used by getShared) */\n kv?: { get<V>(key: string, options?: { raw?: boolean }): Promise<{ ok: boolean; data?: { data: V }; error?: { message: string } }> };\n}\n\n/**\n * Options for vault list operations.\n */\nexport interface VaultListOptions {\n /** Prefix filter for key names */\n prefix?: string;\n /** Remove prefix from returned keys */\n removePrefix?: boolean;\n /** Maximum number of keys to return. */\n limit?: number;\n /** Opaque cursor returned by a prior bounded page. */\n cursor?: string;\n}\n\nexport interface VaultListPage {\n keys: string[];\n truncated: boolean;\n nextCursor?: string;\n}\n\n/**\n * Options for vault grant (sharing) operations.\n */\nexport interface VaultGrantOptions {\n /** Additional metadata on the grant */\n metadata?: Record<string, string>;\n}\n\n/**\n * A decrypted vault entry returned by get operations.\n *\n * @template T - Type of the decrypted value\n */\nexport interface VaultEntry<T> {\n /** Decrypted value */\n value: T;\n /** Envelope metadata */\n metadata: Record<string, string>;\n /** Key ID used for encryption */\n keyId: string;\n}\n\n/**\n * Safe classification for a network-encrypted vault read.\n *\n * Failure variants intentionally contain no node response, encrypted envelope,\n * plaintext, or key material. Consumers that need to distinguish an authorized\n * absence from a failed read should use this instead of {@link IDataVaultService.get}.\n */\nexport type VaultNetworkReadResult<T> =\n | { status: \"ok\"; entry: VaultEntry<T> }\n | { status: \"not_found\" }\n | { status: \"node_unreachable\" }\n | { status: \"permission_required\"; hint: PermissionHint }\n | { status: \"read_failed\" }\n | { status: \"corrupt_envelope\" }\n | { status: \"decrypt_failed\" }\n | { status: \"invalid_payload\" };\n\n/**\n * Structured error codes for vault operations.\n */\n/**\n * Input types for creating vault errors (service field added automatically).\n */\nexport type VaultErrorInput =\n | { code: \"DECRYPTION_FAILED\"; message?: string; cause?: Error }\n | { code: \"KEY_NOT_FOUND\"; key: string; message?: string }\n | { code: \"INTEGRITY_ERROR\"; message?: string; cause?: Error }\n | { code: \"GRANT_NOT_FOUND\"; grantor: string; key: string; message?: string }\n | { code: \"VAULT_LOCKED\"; message?: string }\n | { code: \"PUBLIC_KEY_NOT_FOUND\"; did: string; message?: string }\n | { code: \"STORAGE_ERROR\"; cause: Error; message?: string }\n | {\n code: \"STORAGE_QUOTA_EXCEEDED\" | \"STORAGE_LIMIT_REACHED\";\n message: string;\n meta?: Record<string, unknown>;\n };\n\n/**\n * Vault error with service field (compatible with ServiceError).\n */\nexport type VaultError = VaultErrorInput & { service: \"vault\"; message: string };\n\n\n/** KV actions the vault needs on the public space for key publishing. */\nexport const VaultPublicSpaceKVActions = [\n \"tinycloud.kv/get\",\n \"tinycloud.kv/put\",\n \"tinycloud.kv/metadata\",\n] as const;\n\n/** Version-keyed signing message configuration for vault key derivation. */\nexport const VaultVersionConfig = {\n \"1\": {\n masterMessage: (spaceId: string) => `tinycloud-vault-master-v1:${spaceId}`,\n identityMessage: \"tinycloud-encryption-identity-v1\",\n },\n} as const;\n\nexport const CURRENT_VAULT_VERSION = \"1\" as const;\n\n/** Metadata header keys used in vault envelopes */\nexport const VaultHeaders = {\n VERSION: \"x-vault-version\",\n CIPHER: \"x-vault-cipher\",\n KEY_ID: \"x-vault-key-id\",\n CONTENT_TYPE: \"x-vault-content-type\",\n KDF: \"x-vault-kdf\",\n KEY_ROTATION: \"x-vault-key-rotation\",\n GRANT_VERSION: \"x-vault-grant-version\",\n GRANTOR: \"x-vault-grantor\",\n} as const;\n","/**\n * Caches vault signatures in IndexedDB, encrypted with a\n * non-extractable CryptoKey. Browser-only — no-ops in Node.\n */\n\n// Minimal type declarations for browser APIs used below.\n// The sdk-services tsconfig targets ES2020 without DOM lib;\n// these declarations let the file compile while the runtime\n// guards (isBrowser()) ensure we never call them in Node.\ndeclare const indexedDB: {\n open(name: string, version?: number): IDBOpenDBRequest;\n};\ninterface IDBOpenDBRequest {\n result: IDBDatabase;\n error: DOMException | null;\n onupgradeneeded: ((this: IDBOpenDBRequest) => void) | null;\n onsuccess: ((this: IDBOpenDBRequest) => void) | null;\n onerror: ((this: IDBOpenDBRequest) => void) | null;\n}\ninterface IDBDatabase {\n objectStoreNames: { contains(name: string): boolean };\n createObjectStore(name: string): void;\n transaction(storeNames: string | string[], mode?: string): IDBTransaction;\n}\ninterface IDBTransaction {\n objectStore(name: string): IDBObjectStore;\n}\ninterface IDBObjectStore {\n get(key: string): IDBRequest;\n put(value: unknown, key: string): IDBRequest;\n delete(key: string): IDBRequest;\n getAllKeys(): IDBRequest;\n}\ninterface IDBRequest<T = unknown> {\n result: T;\n error: DOMException | null;\n onsuccess: ((this: IDBRequest<T>) => void) | null;\n onerror: ((this: IDBRequest<T>) => void) | null;\n}\ntype IDBValidKey = string | number | Date | ArrayBuffer | Uint8Array | IDBValidKey[];\n\nconst DB_NAME = \"tinycloud-vault-cache\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"signatures\";\nconst WRAP_KEY_ID = \"__wrap_key__\";\n\n/** Check whether we're in a browser with IndexedDB + SubtleCrypto support. */\nfunction isBrowser(): boolean {\n try {\n return (\n typeof indexedDB !== \"undefined\" &&\n typeof crypto !== \"undefined\" &&\n typeof crypto.subtle !== \"undefined\"\n );\n } catch {\n return false;\n }\n}\n\n/** Open (or create) the IndexedDB database. */\nfunction openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n}\n\n/** Generic IDB get helper. */\nfunction idbGet<T>(db: IDBDatabase, key: string): Promise<T | undefined> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.get(key);\n req.onsuccess = () => resolve(req.result as T | undefined);\n req.onerror = () => reject(req.error);\n });\n}\n\n/** Generic IDB put helper. */\nfunction idbPut(db: IDBDatabase, key: string, value: unknown): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.put(value, key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n\n/** Generic IDB delete helper. */\nfunction idbDelete(db: IDBDatabase, key: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.delete(key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n\n/** List all keys in the store. */\nfunction idbKeys(db: IDBDatabase): Promise<string[]> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.getAllKeys();\n req.onsuccess = () =>\n resolve((req.result as IDBValidKey[]).filter((k) => typeof k === \"string\") as string[]);\n req.onerror = () => reject(req.error);\n });\n}\n\ninterface EncryptedEntry {\n iv: Uint8Array;\n ciphertext: Uint8Array;\n}\n\n/**\n * Get or create the non-extractable AES-GCM wrapping key.\n * The key is stored directly in IndexedDB (structured-clone preserves CryptoKey).\n */\nasync function getWrapKey(db: IDBDatabase): Promise<CryptoKey> {\n const existing = await idbGet<CryptoKey>(db, WRAP_KEY_ID);\n if (existing) return existing;\n\n const key = await crypto.subtle.generateKey(\n { name: \"AES-GCM\", length: 256 },\n false, // non-extractable\n [\"encrypt\", \"decrypt\"]\n );\n await idbPut(db, WRAP_KEY_ID, key);\n return key;\n}\n\n/** Encrypt signature bytes with the wrap key. */\nasync function encryptSig(\n wrapKey: CryptoKey,\n sigBytes: Uint8Array\n): Promise<EncryptedEntry> {\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const ciphertext = new Uint8Array(\n await crypto.subtle.encrypt({ name: \"AES-GCM\", iv }, wrapKey, sigBytes)\n );\n return { iv, ciphertext };\n}\n\n/** Decrypt an encrypted entry back to signature bytes. */\nasync function decryptSig(\n wrapKey: CryptoKey,\n entry: EncryptedEntry\n): Promise<Uint8Array> {\n const plaintext = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: entry.iv },\n wrapKey,\n entry.ciphertext\n );\n return new Uint8Array(plaintext);\n}\n\n/** Cache key for a given spaceId. */\nfunction cacheKey(spaceId: string): string {\n return `sig:${spaceId}`;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Load a cached signature for the given spaceId.\n * Returns null on cache miss or in non-browser environments.\n */\nexport async function loadCachedSignature(\n spaceId: string\n): Promise<Uint8Array | null> {\n if (!isBrowser()) return null;\n try {\n const db = await openDB();\n const entry = await idbGet<EncryptedEntry>(db, cacheKey(spaceId));\n if (!entry) return null;\n const wrapKey = await getWrapKey(db);\n return await decryptSig(wrapKey, entry);\n } catch {\n return null;\n }\n}\n\n/**\n * Cache a signature for the given spaceId.\n * No-ops in non-browser environments.\n */\nexport async function cacheSignature(\n spaceId: string,\n sigBytes: Uint8Array\n): Promise<void> {\n if (!isBrowser()) return;\n try {\n const db = await openDB();\n const wrapKey = await getWrapKey(db);\n const encrypted = await encryptSig(wrapKey, sigBytes);\n await idbPut(db, cacheKey(spaceId), encrypted);\n } catch {\n // Best-effort — swallow errors\n }\n}\n\n/**\n * Clear cached signature(s).\n * If spaceId is provided, clears only that entry; otherwise clears all.\n */\nexport async function clearSignatureCache(\n spaceId?: string\n): Promise<void> {\n if (!isBrowser()) return;\n try {\n const db = await openDB();\n if (spaceId) {\n await idbDelete(db, cacheKey(spaceId));\n } else {\n // Clear all sig entries but keep the wrap key\n const keys = await idbKeys(db);\n for (const k of keys) {\n if (k.startsWith(\"sig:\")) {\n await idbDelete(db, k);\n }\n }\n }\n } catch {\n // Best-effort\n }\n}\n","/**\n * DataVaultService - Encrypted key-value storage service implementation.\n *\n * Platform-agnostic encrypted KV service that wraps KVService internally.\n * Uses dependency injection via VaultCrypto for WASM crypto operations\n * and DataVaultServiceConfig for platform dependencies.\n *\n * Architecture:\n * - Extends BaseService (not KVService)\n * - Wraps two KV instances: dataKV (prefix \"vault/\") and keyKV (prefix \"keys/\")\n * - Master key and encryption identity live in memory only (cleared on lock)\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n IServiceContext,\n ServiceSession,\n} from \"../types\";\nimport { parsePermissionHint, wrapError } from \"../errors\";\nimport type { IKVService } from \"../kv/IKVService\";\nimport type { KVService } from \"../kv/KVService\";\nimport type {\n DecryptCapabilityProof,\n InlineEncryptedEnvelope,\n} from \"../encryption\";\nimport type { IDataVaultService } from \"./IDataVaultService\";\nimport {\n DataVaultConfig,\n VaultPutOptions,\n VaultGetOptions,\n VaultListOptions,\n VaultGrantOptions,\n VaultEntry,\n VaultNetworkReadResult,\n VaultError,\n VaultErrorInput,\n VaultHeaders,\n VaultVersionConfig,\n CURRENT_VAULT_VERSION,\n VaultListPage,\n} from \"./types\";\nimport {\n loadCachedSignature,\n cacheSignature,\n clearSignatureCache,\n} from \"./SignatureCache\";\n\n// =============================================================================\n// Crypto Interface\n// =============================================================================\n\n/**\n * Crypto operations interface - implementations provided by WASM bindings.\n * Passed via DataVaultServiceConfig to keep the service platform-agnostic.\n */\nexport interface VaultCrypto {\n encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array;\n decrypt(key: Uint8Array, blob: Uint8Array): Uint8Array;\n deriveKey(\n signature: Uint8Array,\n salt: Uint8Array,\n info: Uint8Array\n ): Uint8Array;\n x25519FromSeed(\n seed: Uint8Array\n ): { publicKey: Uint8Array; privateKey: Uint8Array };\n x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n randomBytes(length: number): Uint8Array;\n sha256(data: Uint8Array): Uint8Array;\n}\n\n// =============================================================================\n// Extended Config\n// =============================================================================\n\n/**\n * Extended config used internally by DataVaultService.\n * Includes crypto operations and TinyCloud instance references.\n */\ninterface DataVaultServiceConfig extends DataVaultConfig {\n [key: string]: unknown;\n /** Crypto operations (WASM bindings) */\n crypto: VaultCrypto;\n /** TinyCloud instance for space/kv/delegation operations */\n tc: {\n kv: IKVService;\n ensurePublicSpace(): Promise<Result<void>>;\n publicKV: IKVService;\n readPublicSpace<T>(\n host: string,\n spaceId: string,\n key: string\n ): Promise<Result<T>>;\n makePublicSpaceId(address: string, chainId: number): string;\n did: string;\n address: string;\n chainId: number;\n hosts: string[];\n };\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/** Convert a caught value to an Error. WASM throws plain objects, not Error instances. */\nfunction toError(error: unknown): Error {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null) {\n return new Error(JSON.stringify(error));\n }\n return new Error(String(error));\n}\n\nfunction toBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nfunction fromBytes(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nfunction hexEncode(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((acc, arr) => acc + arr.length, 0);\n const result = new Uint8Array(total);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\nfunction base64Encode(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nfunction base64Decode(str: string): Uint8Array {\n const binary = atob(str);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nfunction unwrapKVData<T = unknown>(value: unknown): T {\n if (value !== null && typeof value === \"object\" && \"data\" in value) {\n return (value as { data: T }).data;\n }\n return value as T;\n}\n\nfunction hasHttpResponse(error: { meta?: Record<string, unknown> }): boolean {\n return typeof error.meta?.status === \"number\";\n}\n\nfunction isUnlockSigner(\n signer: unknown\n): signer is { signMessage(message: string): Promise<string> } {\n return (\n typeof signer === \"object\" &&\n signer !== null &&\n typeof (signer as { signMessage?: unknown }).signMessage === \"function\"\n );\n}\n\nfunction defaultVaultMessage(input: VaultErrorInput): string {\n switch (input.code) {\n case \"DECRYPTION_FAILED\": return input.message ?? \"Decryption failed\";\n case \"KEY_NOT_FOUND\": return input.message ?? `Key not found: ${input.key}`;\n case \"INTEGRITY_ERROR\": return input.message ?? \"Integrity check failed\";\n case \"GRANT_NOT_FOUND\": return input.message ?? `Grant not found: ${input.grantor} / ${input.key}`;\n case \"VAULT_LOCKED\": return input.message ?? \"Vault is locked\";\n case \"PUBLIC_KEY_NOT_FOUND\": return input.message ?? `Public key not found for ${input.did}`;\n case \"STORAGE_ERROR\": return input.message ?? input.cause.message;\n case \"STORAGE_QUOTA_EXCEEDED\":\n case \"STORAGE_LIMIT_REACHED\":\n return input.message;\n }\n}\n\nfunction vaultError(input: VaultErrorInput): Result<never, VaultError> {\n const error: VaultError = {\n ...input,\n service: \"vault\",\n message: defaultVaultMessage(input),\n };\n return { ok: false, error };\n}\n\n/**\n * Wrap a failed KV write. A storage rejection keeps its code, message and\n * byte counts so callers can tell \"storage full\" from other failures.\n */\nfunction kvWriteError(\n context: string,\n error: { code: string; message: string; meta?: Record<string, unknown> }\n): Result<never, VaultError> {\n if (\n error.code === ErrorCodes.STORAGE_QUOTA_EXCEEDED ||\n error.code === ErrorCodes.STORAGE_LIMIT_REACHED\n ) {\n return vaultError({ code: error.code, message: error.message, meta: error.meta });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(`${context}: ${error.message}`),\n });\n}\n\n// =============================================================================\n// DataVaultService\n// =============================================================================\n\n/**\n * Data Vault service implementation.\n *\n * Provides encrypted key-value storage with client-side encryption,\n * key management, and sharing via X25519 grants.\n *\n * @example\n * ```typescript\n * // Unlock the vault\n * await vault.unlock(signer);\n *\n * // Store encrypted data\n * await vault.put('secret/notes', { content: 'Hello' });\n *\n * // Retrieve and decrypt\n * const entry = await vault.get<{ content: string }>('secret/notes');\n * if (entry.ok) {\n * console.log(entry.data.value.content); // 'Hello'\n * }\n *\n * // Share with another user\n * await vault.grant('secret/notes', recipientDID);\n * ```\n */\nexport class DataVaultService extends BaseService implements IDataVaultService {\n /**\n * Service identifier for registration.\n */\n static readonly serviceName = \"vault\";\n\n /**\n * Service configuration.\n */\n declare protected _config: DataVaultServiceConfig;\n\n private masterKey: Uint8Array | null = null;\n private encryptionIdentity: {\n publicKey: Uint8Array;\n privateKey: Uint8Array;\n } | null = null;\n private _isUnlocked = false;\n private vaultConfig: DataVaultServiceConfig;\n private unlockInFlight: Promise<Result<void, VaultError>> | null = null;\n\n /**\n * Create a new DataVaultService instance.\n *\n * @param config - Service configuration including crypto and tc references\n */\n constructor(config: DataVaultServiceConfig) {\n super();\n this.vaultConfig = config;\n this._config = config;\n }\n\n /**\n * Get the service configuration.\n */\n get config(): DataVaultServiceConfig {\n return this._config;\n }\n\n /**\n * Whether the vault is currently unlocked.\n */\n get isUnlocked(): boolean {\n return this.usesNetworkEncryption || this._isUnlocked;\n }\n\n /**\n * The vault's public encryption key (X25519).\n * Throws if vault is locked.\n */\n get publicKey(): Uint8Array {\n if (this.usesNetworkEncryption) {\n throw new Error(\"Network-encrypted vaults do not expose a local public key\");\n }\n if (!this.encryptionIdentity) {\n throw new Error(\"Vault is locked\");\n }\n return this.encryptionIdentity.publicKey;\n }\n\n /**\n * Convenience accessor for crypto operations.\n */\n private get crypto(): VaultCrypto {\n return this.vaultConfig.crypto;\n }\n\n /**\n * Convenience accessor for TinyCloud instance.\n */\n private get tc() {\n return this.vaultConfig.tc;\n }\n\n private get networkEncryption() {\n return this.vaultConfig.encryption;\n }\n\n private get usesNetworkEncryption(): boolean {\n return this.networkEncryption !== undefined;\n }\n\n /**\n * Get the host URL.\n */\n private get host(): string {\n return this.tc.hosts[0];\n }\n\n private async decryptCapabilityProof(): Promise<DecryptCapabilityProof> {\n const proof = this.networkEncryption?.decryptCapabilityProof;\n if (typeof proof === \"function\") {\n return await proof();\n }\n return proof ?? { proofs: [] };\n }\n\n private serializeValue(\n value: unknown,\n options?: VaultPutOptions,\n ): { plaintext: Uint8Array; contentType: string } {\n let plaintext: Uint8Array;\n if (value instanceof Uint8Array) {\n plaintext = value;\n } else if (options?.serialize) {\n plaintext = options.serialize(value);\n } else if (typeof value === \"string\") {\n plaintext = toBytes(value);\n } else {\n plaintext = toBytes(JSON.stringify(value));\n }\n\n const contentType =\n options?.contentType ??\n (value instanceof Uint8Array ? \"application/octet-stream\" : \"application/json\");\n return { plaintext, contentType };\n }\n\n private deserializeValue<T>(\n plaintext: Uint8Array,\n contentType: string,\n options?: VaultGetOptions<T>,\n ): T {\n if (options?.raw) {\n return plaintext as unknown as T;\n }\n if (options?.deserialize) {\n return options.deserialize(plaintext);\n }\n if (contentType === \"application/json\") {\n return JSON.parse(fromBytes(plaintext)) as T;\n }\n return plaintext as unknown as T;\n }\n\n // =========================================================================\n // Phase 1: Core Operations\n // =========================================================================\n\n /**\n * Unlock the vault. Derives keys from two wallet signatures:\n * 1. Master signature (per-space) — used to derive the master encryption key\n * 2. Identity signature (per-address) — used to derive X25519 encryption identity\n *\n * If the identity public key already exists in the public space, the identity\n * signature is skipped entirely (no wallet popup). The identity private key is\n * only needed for sharing operations.\n *\n * @param signer - Object with signMessage method. Optional when cached\n * signatures exist (browser only).\n */\n async unlock(\n signer?: { signMessage(message: string): Promise<string> } | unknown\n ): Promise<Result<void, VaultError>> {\n if (this.usesNetworkEncryption) {\n this._isUnlocked = true;\n return { ok: true, data: undefined };\n }\n\n const unlockSigner = isUnlockSigner(signer) ? signer : undefined;\n if (\n this._isUnlocked &&\n this.masterKey &&\n (this.encryptionIdentity || !unlockSigner)\n ) {\n return { ok: true, data: undefined };\n }\n\n if (this.unlockInFlight) {\n return this.unlockInFlight;\n }\n\n this.unlockInFlight = this.withTelemetry(\"unlock\", undefined, async () => {\n const spaceId = this.vaultConfig.spaceId;\n const versionConfig = VaultVersionConfig[CURRENT_VAULT_VERSION];\n const masterCacheKey = `vault-master:${spaceId}`;\n const identityCacheKey = `vault-identity:${this.tc.address}`;\n\n try {\n // -----------------------------------------------------------------\n // Step 1: Master signature → master key\n // -----------------------------------------------------------------\n if (!this.masterKey) {\n let masterSigBytes = await loadCachedSignature(masterCacheKey);\n\n if (!masterSigBytes) {\n if (!unlockSigner) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Signer is required when no cached master signature exists\",\n });\n }\n const sig = await unlockSigner.signMessage(\n versionConfig.masterMessage(spaceId)\n );\n masterSigBytes = toBytes(sig);\n await cacheSignature(masterCacheKey, masterSigBytes);\n }\n\n // Derive master key: deriveKey(sigBytes, sha256(spaceId), \"vault-master\")\n this.masterKey = this.crypto.deriveKey(\n masterSigBytes,\n this.crypto.sha256(toBytes(spaceId)),\n toBytes(\"vault-master\")\n );\n }\n\n // -----------------------------------------------------------------\n // Step 2: Identity — check public space first, then sign if needed\n // -----------------------------------------------------------------\n const publicSpaceId = this.tc.makePublicSpaceId(this.tc.address, this.tc.chainId);\n\n // Check public space for existing vault pubkey\n let existingPubKey: string | null = null;\n try {\n const existing = await this.tc.readPublicSpace<string>(\n this.host, publicSpaceId, \".well-known/vault-pubkey\"\n );\n if (existing.ok && existing.data) {\n existingPubKey = existing.data as string;\n }\n } catch {\n // Read failed — treat as missing\n }\n\n if (existingPubKey) {\n // Public key exists — trust it, skip identity signing entirely\n this.encryptionIdentity = {\n publicKey: base64Decode(existingPubKey),\n privateKey: new Uint8Array(0), // private key not available without signing\n };\n } else {\n // Public key missing — need identity signature to derive keypair\n let identitySigBytes = await loadCachedSignature(identityCacheKey);\n\n if (!identitySigBytes) {\n if (!unlockSigner) {\n // No signer available — skip identity derivation.\n // Vault still works for get/put (only needs master key).\n this.encryptionIdentity = null;\n this._isUnlocked = true;\n return ok(undefined);\n }\n const sig = await unlockSigner.signMessage(\n versionConfig.identityMessage\n );\n identitySigBytes = toBytes(sig);\n await cacheSignature(identityCacheKey, identitySigBytes);\n }\n\n // Derive X25519 keypair from identity signature\n const seed = this.crypto.deriveKey(\n identitySigBytes,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"encryption-identity\")\n );\n this.encryptionIdentity = this.crypto.x25519FromSeed(seed);\n\n // Publish public key to public space\n try {\n const pubKeyB64 = base64Encode(this.encryptionIdentity.publicKey);\n await this.tc.ensurePublicSpace();\n await this.tc.publicKV.put(\".well-known/vault-pubkey\", pubKeyB64);\n await this.tc.publicKV.put(\".well-known/vault-version\", CURRENT_VAULT_VERSION);\n await this.tc.publicKV.put(\".well-known/vault-space\", this.vaultConfig.spaceId);\n } catch {\n // Publishing failed — vault still usable\n }\n }\n\n this._isUnlocked = true;\n return ok(undefined);\n } catch (error) {\n // Clear key material on failure\n this.masterKey = null;\n this.encryptionIdentity = null;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n\n try {\n return await this.unlockInFlight;\n } finally {\n this.unlockInFlight = null;\n }\n }\n\n /**\n * Clear the cached vault signatures.\n *\n * @param spaceId - Clear only this space's master cache. If omitted, clears all.\n */\n async clearCache(spaceId?: string): Promise<void> {\n if (spaceId) {\n await clearSignatureCache(`vault-master:${spaceId}`);\n } else {\n await clearSignatureCache();\n }\n }\n\n /**\n * Lock the vault, clearing all key material from memory.\n */\n lock(): void {\n this.masterKey = null;\n this.encryptionIdentity = null;\n this._isUnlocked = false;\n }\n\n /**\n * Called when SDK signs out. Locks the vault and aborts operations.\n */\n onSignOut(): void {\n this.lock();\n super.onSignOut();\n }\n\n private async putNetworkEncrypted(\n key: string,\n value: unknown,\n options?: VaultPutOptions,\n ): Promise<Result<void, VaultError>> {\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const { plaintext, contentType } = this.serializeValue(value, options);\n const metadata: Record<string, string> = {\n [VaultHeaders.VERSION]: \"2\",\n [VaultHeaders.CIPHER]: \"tinycloud-network-envelope\",\n [VaultHeaders.CONTENT_TYPE]: contentType,\n ...(options?.metadata ?? {}),\n };\n const aad = toBytes(`tinycloud.vault:${this.vaultConfig.spaceId}:${key}`);\n const envelopeResult = await config.service.encryptToNetwork(\n config.networkId,\n plaintext,\n { aad, metadata },\n );\n if (!envelopeResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(envelopeResult.error.message),\n });\n }\n\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n JSON.stringify(envelopeResult.data),\n );\n if (!valuePutResult.ok) {\n return kvWriteError(\"Failed to store encrypted value\", valuePutResult.error);\n }\n\n return { ok: true, data: undefined };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n private async getNetworkEncrypted<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>,\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n const proof = await this.decryptCapabilityProof();\n const plaintextResult = await config.service.decryptEnvelope(envelope, proof);\n if (!plaintextResult.ok) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: plaintextResult.error.message,\n });\n }\n\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n\n return { ok: true, data: { value, metadata, keyId } };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n /**\n * Read a network-encrypted entry while preserving safe failure phases.\n *\n * Unlike {@link getNetworkEncrypted}, this is intentionally message-free so\n * an operation layer can distinguish an authorized absence from a failed\n * read without receiving node, envelope, plaintext, or key material.\n */\n async readNetworkEncrypted<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>,\n ): Promise<VaultNetworkReadResult<T>> {\n const config = this.networkEncryption;\n if (!config || !this.requireAuth()) {\n return { status: \"read_failed\" };\n }\n\n let valueResult: Awaited<ReturnType<IKVService[\"get\"]>>;\n try {\n valueResult = await this.tc.kv.get<string>(`vault/${key}`, { raw: true });\n } catch {\n return { status: \"node_unreachable\" };\n }\n\n if (!valueResult.ok) {\n const permissionHint = parsePermissionHint(valueResult.error.meta?.permissionHint);\n if (valueResult.error.code === \"AUTH_UNAUTHORIZED\" && permissionHint !== undefined) {\n return { status: \"permission_required\", hint: permissionHint };\n }\n if (\n (valueResult.error.code === \"NOT_FOUND\" ||\n valueResult.error.code === \"KV_NOT_FOUND\") &&\n !hasHttpResponse(valueResult.error)\n ) {\n return { status: \"not_found\" };\n }\n if (\n valueResult.error.code === \"NETWORK_ERROR\" ||\n valueResult.error.code === \"TIMEOUT\" ||\n valueResult.error.code === \"ABORTED\"\n ) {\n return hasHttpResponse(valueResult.error)\n ? { status: \"read_failed\" }\n : { status: \"node_unreachable\" };\n }\n return { status: \"read_failed\" };\n }\n\n let envelope: InlineEncryptedEnvelope;\n try {\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n } catch {\n return { status: \"corrupt_envelope\" };\n }\n\n let plaintextResult: Awaited<ReturnType<typeof config.service.decryptEnvelope>>;\n try {\n const proof = await this.decryptCapabilityProof();\n plaintextResult = await config.service.decryptEnvelope(envelope, proof);\n } catch {\n return { status: \"decrypt_failed\" };\n }\n\n if (!plaintextResult.ok) {\n const permissionHint = parsePermissionHint(\n (plaintextResult.error as { permissionHint?: unknown }).permissionHint,\n );\n if (plaintextResult.error.code === \"DECRYPT_DENIED\" && permissionHint !== undefined) {\n return { status: \"permission_required\", hint: permissionHint };\n }\n if (plaintextResult.error.code === \"INVALID_ENVELOPE\") {\n return { status: \"corrupt_envelope\" };\n }\n if (plaintextResult.error.code === \"TRANSPORT_ERROR\") {\n return { status: \"node_unreachable\" };\n }\n return { status: \"decrypt_failed\" };\n }\n\n try {\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n return { status: \"ok\", entry: { value, metadata, keyId } };\n } catch {\n return { status: \"invalid_payload\" };\n }\n }\n\n private async headNetworkEncrypted(\n key: string,\n ): Promise<Result<Record<string, string>, VaultError>> {\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n return { ok: true, data: envelope.metadata ?? {} };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n /**\n * Encrypt and store a value at the given key.\n *\n * @param key - The key to store under\n * @param value - The value to encrypt and store\n * @param options - Optional put configuration\n */\n async put(\n key: string,\n value: unknown,\n options?: VaultPutOptions\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"put\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.putNetworkEncrypted(key, value, options);\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before storing data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Serialize value\n let plaintext: Uint8Array;\n if (value instanceof Uint8Array) {\n plaintext = value;\n } else if (options?.serialize) {\n plaintext = options.serialize(value);\n } else if (typeof value === \"string\") {\n plaintext = toBytes(value);\n } else {\n plaintext = toBytes(JSON.stringify(value));\n }\n\n const contentType =\n options?.contentType ??\n (value instanceof Uint8Array\n ? \"application/octet-stream\"\n : \"application/json\");\n\n // Generate per-entry key\n const entryKey = this.crypto.randomBytes(32);\n const keyId = hexEncode(this.crypto.sha256(entryKey)).slice(0, 16);\n\n // Encrypt value with entry key\n const encrypted = this.crypto.encrypt(entryKey, plaintext);\n\n // Encrypt entry key with master key\n const keyBlob = this.crypto.encrypt(this.masterKey, entryKey);\n\n // Build metadata\n const metadata: Record<string, string> = {\n [VaultHeaders.VERSION]: \"1\",\n [VaultHeaders.CIPHER]: \"aes-256-gcm\",\n [VaultHeaders.KEY_ID]: keyId,\n [VaultHeaders.CONTENT_TYPE]: contentType,\n [VaultHeaders.KDF]: \"hkdf-sha256\",\n [VaultHeaders.KEY_ROTATION]:\n this.vaultConfig.keyRotation ?? \"per-write\",\n ...(options?.metadata ?? {}),\n };\n\n // Store encrypted entry key in key space\n const keyMetadata = JSON.stringify({\n keyId,\n contentType,\n ...metadata,\n });\n const keyPayload = JSON.stringify({\n key: base64Encode(keyBlob),\n metadata: keyMetadata,\n });\n const keyPutResult = await this.tc.kv.put(\n `keys/${key}`,\n keyPayload\n );\n if (!keyPutResult.ok) {\n return kvWriteError(\"Failed to store key blob\", keyPutResult.error);\n }\n\n // Store encrypted value in data space\n const valuePayload = JSON.stringify({\n data: base64Encode(encrypted),\n metadata,\n });\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n valuePayload\n );\n if (!valuePutResult.ok) {\n return kvWriteError(\"Failed to store encrypted value\", valuePutResult.error);\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * Retrieve and decrypt a value by key.\n *\n * @param key - The key to retrieve\n * @param options - Optional get configuration\n * @returns Result with the decrypted entry\n */\n async get<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n return this.withTelemetry(\"get\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.getNetworkEncrypted<T>(key, options);\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Fetch encrypted entry key from key space\n const keyResult = await this.tc.kv.get<string>(`keys/${key}`, {\n raw: true,\n });\n if (!keyResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const keyEnvelope = JSON.parse(keyResult.data.data as string);\n const keyBlobBytes = base64Decode(keyEnvelope.key);\n const entryKey = this.crypto.decrypt(this.masterKey, keyBlobBytes);\n\n // Fetch encrypted value from data space\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const valueEnvelope = JSON.parse(valueResult.data.data as string);\n const encryptedBytes = base64Decode(valueEnvelope.data);\n const plaintext = this.crypto.decrypt(entryKey, encryptedBytes);\n\n // Read metadata\n const metadata: Record<string, string> = valueEnvelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId = metadata[VaultHeaders.KEY_ID] ?? \"\";\n\n // Deserialize\n let value: T;\n if (options?.raw) {\n value = plaintext as unknown as T;\n } else if (options?.deserialize) {\n value = options.deserialize(plaintext);\n } else if (contentType === \"application/json\") {\n value = JSON.parse(fromBytes(plaintext)) as T;\n } else {\n value = plaintext as unknown as T;\n }\n\n return ok({ value, metadata, keyId });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"decryption\")\n ) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: error.message,\n });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultEntry<T>, VaultError>>;\n }\n\n /**\n * Delete an encrypted key.\n * Removes both the encrypted value and the key blob.\n *\n * @param key - The key to delete\n */\n async delete(key: string): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"delete\", key, async () => {\n if (!this.isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before deleting data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n if (this.usesNetworkEncryption) {\n const valueDelResult = await this.tc.kv.delete(`vault/${key}`);\n if (!valueDelResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n return ok(undefined);\n }\n\n // Delete from both key space and data space\n const [keyDelResult, valueDelResult] = await Promise.all([\n this.tc.kv.delete(`keys/${key}`),\n this.tc.kv.delete(`vault/${key}`),\n ]);\n\n if (!keyDelResult.ok && !valueDelResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * List vault keys with optional prefix filtering.\n *\n * @param options - Optional list configuration\n * @returns Result with array of key names (vault/ prefix stripped)\n */\n async list(\n options?: VaultListOptions\n ): Promise<Result<string[], VaultError>> {\n const page = await this.listPage(options);\n return page.ok ? { ok: true, data: page.data.keys } : page;\n }\n\n async listPage(\n options?: VaultListOptions\n ): Promise<Result<VaultListPage, VaultError>> {\n return this.withTelemetry(\"list\", options?.prefix, async () => {\n if (!this.isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before listing data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const listPrefix = options?.prefix\n ? `vault/${options.prefix}`\n : \"vault/\";\n\n const listResult = await this.tc.kv.list({\n prefix: listPrefix,\n removePrefix: true,\n ...(options?.limit === undefined ? {} : { limit: options.limit }),\n ...(options?.cursor === undefined ? {} : { cursor: options.cursor }),\n });\n\n if (!listResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to list vault keys: ${listResult.error.message}`\n ),\n });\n }\n\n // Keys are already stripped of the \"vault/\" prefix by removePrefix\n let keys = listResult.data.keys;\n\n // If a user prefix was provided, strip it too if requested\n if (options?.removePrefix && options.prefix) {\n const userPrefix = options.prefix.endsWith(\"/\")\n ? options.prefix\n : `${options.prefix}/`;\n keys = keys.map((k) =>\n k.startsWith(userPrefix) ? k.slice(userPrefix.length) : k\n );\n }\n\n return ok({\n keys,\n truncated: listResult.data.truncated === true,\n ...(listResult.data.nextCursor === undefined ? {} : { nextCursor: listResult.data.nextCursor }),\n });\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultListPage, VaultError>>;\n }\n\n /**\n * Get envelope metadata for a key without decrypting the value.\n *\n * @param key - The key to inspect\n * @returns Result with metadata headers\n */\n async head(\n key: string\n ): Promise<Result<Record<string, string>, VaultError>> {\n return this.withTelemetry(\"head\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.headNetworkEncrypted(key);\n }\n\n if (!this._isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading metadata\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Fetch envelope without decrypting\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const valueEnvelope = JSON.parse(valueResult.data.data as string);\n const metadata: Record<string, string> = valueEnvelope.metadata ?? {};\n return ok(metadata);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<Record<string, string>, VaultError>>;\n }\n\n // =========================================================================\n // Batch Operations\n // =========================================================================\n\n /**\n * Encrypt and store multiple entries.\n *\n * @param entries - Array of key/value pairs with optional per-entry options\n * @returns Array of results, one per entry\n */\n async putMany(\n entries: Array<{ key: string; value: unknown; options?: VaultPutOptions }>\n ): Promise<Result<void, VaultError>[]> {\n return Promise.all(\n entries.map((entry) => this.put(entry.key, entry.value, entry.options))\n );\n }\n\n /**\n * Retrieve and decrypt multiple keys.\n *\n * @param keys - Array of keys to retrieve\n * @param options - Optional get configuration applied to all entries\n * @returns Array of results, one per key\n */\n async getMany<T = unknown>(\n keys: string[],\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>[]> {\n return Promise.all(keys.map((key) => this.get<T>(key, options)));\n }\n\n // =========================================================================\n // Phase 2: Sharing\n // =========================================================================\n\n /**\n * Re-encrypt a vault key for another user (renamed from grant).\n * Re-encrypts the data key to the recipient's public key via X25519 DH.\n *\n * @param key - The key to share\n * @param recipientDID - The recipient's primary DID (did:pkh:...)\n * @param options - Optional grant configuration\n */\n async reencrypt(\n key: string,\n recipientDID: string,\n options?: VaultGrantOptions\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"reencrypt\", key, async () => {\n if (this.usesNetworkEncryption) {\n void recipientDID;\n void options;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"Vault key grants are deprecated for network-encrypted vaults; grant tinycloud.encryption/decrypt on the network plus KV access to vault data.\",\n ),\n });\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before granting access\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Step 1: Resolve recipient's public key\n const pubKeyResult = await this.resolvePublicKey(recipientDID);\n if (!pubKeyResult.ok) {\n return pubKeyResult;\n }\n const bobPubKey = pubKeyResult.data;\n\n // Step 2: Fetch and decrypt entry key from key space\n const keyResult = await this.tc.kv.get<string>(`keys/${key}`, {\n raw: true,\n });\n if (!keyResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const keyEnvelope = JSON.parse(keyResult.data.data as string);\n const keyBlobBytes = base64Decode(keyEnvelope.key);\n const entryKey = this.crypto.decrypt(this.masterKey, keyBlobBytes);\n\n // Step 3: Create ephemeral X25519 key pair\n const ephemeralSeed = this.crypto.randomBytes(32);\n const ephemeralKeyPair = this.crypto.x25519FromSeed(ephemeralSeed);\n\n // Step 4: Compute shared secret via DH\n const sharedSecret = this.crypto.x25519Dh(\n ephemeralKeyPair.privateKey,\n bobPubKey\n );\n\n // Step 5: Derive encryption key from shared secret\n const encryptionKey = this.crypto.deriveKey(\n sharedSecret,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"vault-grant\")\n );\n\n // Step 6: Encrypt entry key with derived key\n const encryptedGrant = this.crypto.encrypt(encryptionKey, entryKey);\n\n // Step 7: Concatenate ephemeral public key + encrypted grant\n const grantBlob = concatBytes(\n ephemeralKeyPair.publicKey,\n encryptedGrant\n );\n\n // Step 8: Store grant in key space\n const grantPayload = JSON.stringify({\n grant: base64Encode(grantBlob),\n spaceId: this.vaultConfig.spaceId,\n metadata: {\n [VaultHeaders.GRANT_VERSION]: \"1\",\n [VaultHeaders.GRANTOR]: this.tc.did,\n ...(options?.metadata ?? {}),\n },\n });\n // Store grant in the vault's space (main space)\n const grantPutResult = await this.tc.kv.put(\n `grants/${recipientDID}/${key}`,\n grantPayload\n );\n if (!grantPutResult.ok) {\n return kvWriteError(\"Failed to store grant\", grantPutResult.error);\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * @deprecated Use reencrypt() instead.\n */\n async grant(\n key: string,\n recipientDID: string,\n options?: VaultGrantOptions\n ): Promise<Result<void, VaultError>> {\n return this.reencrypt(key, recipientDID, options);\n }\n\n /**\n * Retrieve and decrypt a value shared by another user.\n *\n * @param grantorDID - The DID of the user who shared the data\n * @param key - The key that was shared\n * @param options - Optional get configuration\n * @returns Result with the decrypted entry\n */\n async getShared<T = unknown>(\n grantorDID: string,\n key: string,\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n return this.withTelemetry(\"getShared\", key, async () => {\n if (this.usesNetworkEncryption) {\n const grantorKV = options?.kv;\n if (!grantorKV) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"getShared requires a delegated KV service via options.kv.\",\n ),\n });\n }\n\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await grantorKV.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n const proof = await this.decryptCapabilityProof();\n const plaintextResult = await config.service.decryptEnvelope(\n envelope,\n proof,\n );\n if (!plaintextResult.ok) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: plaintextResult.error.message,\n });\n }\n\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n void grantorDID;\n return { ok: true, data: { value, metadata, keyId } };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n if (\n !this._isUnlocked ||\n !this.masterKey ||\n !this.encryptionIdentity\n ) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading shared data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const myDID = this.tc.did;\n const grantorKV = options?.kv;\n\n if (!grantorKV) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"getShared requires a delegated KV service via options.kv. \" +\n \"Use useDelegation() to get delegated access, then pass { kv: access.kv }.\"\n ),\n });\n }\n\n // Step 1: Fetch grant from grantor's space via delegated KV\n const grantResult = await grantorKV.get<string>(`grants/${myDID}/${key}`, {\n raw: true,\n });\n if (!grantResult.ok) {\n return vaultError({\n code: \"GRANT_NOT_FOUND\",\n grantor: grantorDID,\n key,\n });\n }\n\n const grantEnvelope = typeof grantResult.data?.data === \"string\"\n ? JSON.parse(grantResult.data.data as string)\n : grantResult.data?.data;\n const grantBlobBytes = base64Decode((grantEnvelope as any).grant);\n\n // Step 2: Extract ephemeral public key and encrypted grant\n const ephemeralPubKey = grantBlobBytes.slice(0, 32);\n const encryptedGrant = grantBlobBytes.slice(32);\n\n // Step 3: Compute shared secret using our private key\n const sharedSecret = this.crypto.x25519Dh(\n this.encryptionIdentity.privateKey,\n ephemeralPubKey\n );\n\n // Step 4: Derive decryption key\n const encryptionKey = this.crypto.deriveKey(\n sharedSecret,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"vault-grant\")\n );\n\n // Step 5: Decrypt entry key\n const entryKey = this.crypto.decrypt(encryptionKey, encryptedGrant);\n\n // Step 6: Fetch encrypted value from grantor's space via delegated KV\n const valueResult = await grantorKV.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({\n code: \"KEY_NOT_FOUND\",\n key,\n });\n }\n\n const valueEnvelope = typeof valueResult.data?.data === \"string\"\n ? JSON.parse(valueResult.data.data as string)\n : valueResult.data?.data;\n const encryptedBytes = base64Decode((valueEnvelope as any).data);\n const plaintext = this.crypto.decrypt(entryKey, encryptedBytes);\n\n // Read metadata\n const metadata: Record<string, string> = (valueEnvelope as any).metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId = metadata[VaultHeaders.KEY_ID] ?? \"\";\n\n // Deserialize\n let value: T;\n if (options?.raw) {\n value = plaintext as unknown as T;\n } else if (options?.deserialize) {\n value = options.deserialize(plaintext);\n } else if (contentType === \"application/json\") {\n value = JSON.parse(fromBytes(plaintext)) as T;\n } else {\n value = plaintext as unknown as T;\n }\n\n return ok({ value, metadata, keyId });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"decryption\")\n ) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: error.message,\n });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultEntry<T>, VaultError>>;\n }\n\n /**\n * Resolve another user's public encryption key from their DID.\n *\n * @param did - The DID to resolve (did:pkh:eip155:{chainId}:{address})\n * @returns Result with the public key bytes\n */\n async resolvePublicKey(\n did: string\n ): Promise<Result<Uint8Array, VaultError>> {\n try {\n const parts = this.parseDID(did);\n if (!parts) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n\n const spaceId = this.tc.makePublicSpaceId(\n parts.address,\n parts.chainId\n );\n\n const result = await this.tc.readPublicSpace<string>(\n this.host,\n spaceId,\n \".well-known/vault-pubkey\"\n );\n\n if (!result.ok) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n\n const pubKeyBytes = base64Decode(result.data as string);\n return { ok: true, data: pubKeyBytes } as Result<Uint8Array, VaultError>;\n } catch (error) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n }\n\n /**\n * List DIDs that have been granted access to a key.\n *\n * @param key - The key to list grants for\n * @returns Result with array of recipient DIDs\n */\n async listGrants(\n key: string\n ): Promise<Result<string[], VaultError>> {\n return this.withTelemetry(\"listGrants\", key, async () => {\n if (this.usesNetworkEncryption) {\n void key;\n return { ok: true, data: [] };\n }\n\n if (!this._isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before listing grants\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const listResult = await this.tc.kv.list({\n prefix: \"grants/\",\n removePrefix: true,\n });\n\n if (!listResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to list grants: ${listResult.error.message}`\n ),\n });\n }\n\n // Grant paths are: {recipientDID}/{key}\n // Filter for the specific key and extract DIDs\n const dids: string[] = [];\n for (const grantPath of listResult.data.keys) {\n // Path format: {recipientDID}/{key}\n // The key may contain slashes, so we need to match the suffix\n if (grantPath.endsWith(`/${key}`)) {\n const did = grantPath.slice(\n 0,\n grantPath.length - key.length - 1\n );\n if (did) {\n dids.push(did);\n }\n }\n }\n\n return ok(dids);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<string[], VaultError>>;\n }\n\n // =========================================================================\n // Phase 3: Key Rotation / Revocation\n // =========================================================================\n\n /**\n * Revoke a previously issued grant.\n *\n * This performs a full key rotation:\n * 1. Lists current grantees\n * 2. Removes the revoked recipient\n * 3. Re-encrypts the value with a new entry key\n * 4. Re-issues grants to remaining recipients\n *\n * @param key - The key to revoke access to\n * @param recipientDID - The recipient whose access to revoke\n */\n async revoke(\n key: string,\n recipientDID: string\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"revoke\", key, async () => {\n if (this.usesNetworkEncryption) {\n void recipientDID;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"Vault key grants are deprecated for network-encrypted vaults; revoke KV and tinycloud.encryption/decrypt grants instead.\",\n ),\n });\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before revoking access\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Step 1: List all current grantees\n const granteesResult = await this.listGrants(key);\n if (!granteesResult.ok) {\n return granteesResult;\n }\n\n const remainingGrantees = granteesResult.data.filter(\n (did) => did !== recipientDID\n );\n\n // Step 2: Delete the grant for the revoked recipient\n const deleteGrantResult = await this.tc.kv.delete(\n `grants/${recipientDID}/${key}`\n );\n // Grant may already be deleted, that's fine\n\n // Step 3: Fetch and decrypt current value\n const getResult = await this.get(key);\n if (!getResult.ok) {\n return getResult as Result<never, VaultError>;\n }\n\n const currentEntry = getResult.data;\n\n // Step 4: Generate new entry key\n const newEntryKey = this.crypto.randomBytes(32);\n const newKeyId = hexEncode(this.crypto.sha256(newEntryKey)).slice(\n 0,\n 16\n );\n\n // Step 5: Re-serialize and re-encrypt value with new key\n let plaintext: Uint8Array;\n if (currentEntry.value instanceof Uint8Array) {\n plaintext = currentEntry.value;\n } else {\n plaintext = toBytes(JSON.stringify(currentEntry.value));\n }\n\n const encrypted = this.crypto.encrypt(newEntryKey, plaintext);\n\n // Step 6: Encrypt new entry key with master key\n const newKeyBlob = this.crypto.encrypt(this.masterKey, newEntryKey);\n\n // Step 7: Update metadata with new key ID\n const metadata: Record<string, string> = {\n ...currentEntry.metadata,\n [VaultHeaders.KEY_ID]: newKeyId,\n };\n\n // Step 8: Store updated key blob\n const keyPayload = JSON.stringify({\n key: base64Encode(newKeyBlob),\n metadata: JSON.stringify({\n keyId: newKeyId,\n ...metadata,\n }),\n });\n const keyPutResult = await this.tc.kv.put(\n `keys/${key}`,\n keyPayload\n );\n if (!keyPutResult.ok) {\n return kvWriteError(\"Failed to store rotated key blob\", keyPutResult.error);\n }\n\n // Step 9: Store re-encrypted value\n const valuePayload = JSON.stringify({\n data: base64Encode(encrypted),\n metadata,\n });\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n valuePayload\n );\n if (!valuePutResult.ok) {\n return kvWriteError(\"Failed to store re-encrypted value\", valuePutResult.error);\n }\n\n // Step 10: Re-issue grants to remaining recipients\n for (const did of remainingGrantees) {\n const grantResult = await this.reencrypt(key, did);\n if (!grantResult.ok) {\n // Continue re-issuing to other recipients even if one fails\n // The failed grant can be re-issued manually\n }\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n // =========================================================================\n // Internal Helpers\n // =========================================================================\n\n /**\n * Parse a DID string to extract address and chainId.\n * Expected format: did:pkh:eip155:{chainId}:{address}\n *\n * @param did - The DID to parse\n * @returns Parsed address and chainId, or null if invalid\n */\n private parseDID(\n did: string\n ): { address: string; chainId: number } | null {\n // did:pkh:eip155:{chainId}:{address}\n const parts = did.split(\":\");\n if (\n parts.length !== 5 ||\n parts[0] !== \"did\" ||\n parts[1] !== \"pkh\" ||\n parts[2] !== \"eip155\"\n ) {\n return null;\n }\n\n const chainId = parseInt(parts[3], 10);\n const address = parts[4];\n if (isNaN(chainId) || !address) {\n return null;\n }\n\n return { address, chainId };\n }\n}\n","import type { VaultCrypto } from \"./DataVaultService\";\n\nexport interface WasmVaultFunctions {\n vault_encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array;\n vault_decrypt(key: Uint8Array, blob: Uint8Array): Uint8Array;\n /** WASM order: (salt, signature, info) — NOT (signature, salt, info) */\n vault_derive_key(salt: Uint8Array, signature: Uint8Array, info: Uint8Array): Uint8Array;\n vault_x25519_from_seed(seed: Uint8Array): { publicKey: Uint8Array; privateKey: Uint8Array };\n vault_x25519_dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n vault_random_bytes(length: number): Uint8Array;\n vault_sha256(data: Uint8Array): Uint8Array;\n}\n\nexport function createVaultCrypto(wasm: WasmVaultFunctions): VaultCrypto {\n return {\n encrypt: (key, plaintext) => wasm.vault_encrypt(key, plaintext),\n decrypt: (key, blob) => wasm.vault_decrypt(key, blob),\n deriveKey: (signature, salt, info) => wasm.vault_derive_key(salt, signature, info),\n x25519FromSeed: (seed) => wasm.vault_x25519_from_seed(seed),\n x25519Dh: (privateKey, publicKey) => wasm.vault_x25519_dh(privateKey, publicKey),\n randomBytes: (length) => wasm.vault_random_bytes(length),\n sha256: (data) => wasm.vault_sha256(data),\n };\n}\n","export const SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;\n\nconst SECRET_PREFIX = \"secrets/\";\nconst SCOPED_SECRET_PREFIX = \"secrets/scoped/\";\nconst RESERVED_SECRET_SCOPES = new Set([\"default\", \"global\"]);\n\nexport interface SecretScopeOptions {\n /** Optional logical scope. Omit for the global secret namespace. */\n scope?: string;\n}\n\nexport interface ResolvedSecretPath {\n /** Canonical env-style secret name. */\n name: string;\n /** Canonical scope. Undefined means global. */\n scope?: string;\n /** Key passed to the data vault service. */\n vaultKey: string;\n /** KV permission path that backs the encrypted vault entry. */\n permissionPaths: {\n vault: string;\n };\n}\n\nexport interface ParsedSecretCatalogKey {\n name: string;\n scope?: string;\n}\n\nexport function canonicalizeSecretScope(\n scope: string | undefined,\n): string | undefined {\n if (scope === undefined) {\n return undefined;\n }\n\n const trimmed = scope.trim();\n if (trimmed === \"\") {\n throw new Error(\n \"Secret scope must be non-empty; omit scope for global secrets.\",\n );\n }\n\n const canonical = trimmed\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n if (canonical === \"\") {\n throw new Error(\"Secret scope must contain at least one letter or number.\");\n }\n if (RESERVED_SECRET_SCOPES.has(canonical)) {\n throw new Error(\n `Secret scope ${JSON.stringify(scope)} is reserved; omit scope for global secrets.`,\n );\n }\n\n return canonical;\n}\n\nexport function resolveSecretPath(\n name: string,\n options: SecretScopeOptions = {},\n): ResolvedSecretPath {\n const normalizedName = name.trim();\n if (!SECRET_NAME_RE.test(normalizedName)) {\n throw new Error(\n `Invalid secret name ${JSON.stringify(name)}. Secret names must match ${SECRET_NAME_RE.source}.`,\n );\n }\n\n const scope = canonicalizeSecretScope(options.scope);\n const vaultKey =\n scope === undefined\n ? `${SECRET_PREFIX}${normalizedName}`\n : `${SCOPED_SECRET_PREFIX}${scope}/${normalizedName}`;\n\n return {\n name: normalizedName,\n ...(scope !== undefined ? { scope } : {}),\n vaultKey,\n permissionPaths: {\n vault: `vault/${vaultKey}`,\n },\n };\n}\n\nexport function resolveSecretListPrefix(\n options: SecretScopeOptions = {},\n): string {\n const scope = canonicalizeSecretScope(options.scope);\n return scope === undefined\n ? \"vault/secrets/\"\n : `vault/secrets/scoped/${scope}/`;\n}\n\n/** Parse a key relative to `secrets/` into its canonical catalog identity. */\nexport function parseSecretCatalogKey(\n key: string,\n): ParsedSecretCatalogKey | undefined {\n if (SECRET_NAME_RE.test(key)) {\n return { name: key };\n }\n\n const parts = key.split(\"/\");\n if (parts.length !== 3 || parts[0] !== \"scoped\") {\n return undefined;\n }\n\n const [, rawScope, name] = parts;\n if (!name || !SECRET_NAME_RE.test(name)) {\n return undefined;\n }\n\n try {\n const scope = canonicalizeSecretScope(rawScope);\n if (scope === undefined || scope !== rawScope) {\n return undefined;\n }\n return { name, scope };\n } catch {\n return undefined;\n }\n}\n","import { ErrorCodes, err, type Result, type ServiceError } from \"../types\";\nimport type { IDataVaultService } from \"../vault/IDataVaultService\";\nimport type { VaultError } from \"../vault/types\";\nimport type {\n ISecretsService,\n SecretCatalogEntry,\n SecretPayload,\n SecretsError,\n} from \"./ISecretsService\";\nimport {\n canonicalizeSecretScope,\n parseSecretCatalogKey,\n resolveSecretPath,\n SECRET_NAME_RE,\n type ResolvedSecretPath,\n type SecretScopeOptions,\n} from \"./paths\";\n\nfunction invalidSecretInput(message: string): Result<never, ServiceError> {\n return err({\n code: ErrorCodes.INVALID_INPUT,\n service: \"secrets\",\n message,\n });\n}\n\nfunction resolveSecretPathResult(\n name: string,\n options?: SecretScopeOptions,\n): ResolvedSecretPath | Result<never, ServiceError> {\n try {\n return resolveSecretPath(name, options);\n } catch (error) {\n return invalidSecretInput(\n error instanceof Error ? error.message : String(error),\n );\n }\n}\n\nexport class SecretsService implements ISecretsService {\n private readonly getVault: () => IDataVaultService;\n\n constructor(vault: IDataVaultService | (() => IDataVaultService)) {\n this.getVault = typeof vault === \"function\" ? vault : () => vault;\n }\n\n get vault(): IDataVaultService {\n return this.getVault();\n }\n\n get isUnlocked(): boolean {\n return this.vault.isUnlocked;\n }\n\n unlock(signer?: unknown): Promise<Result<void, VaultError>> {\n return this.vault.unlock(signer);\n }\n\n lock(): void {\n this.vault.lock();\n }\n\n async get(\n name: string,\n options?: SecretScopeOptions,\n ): Promise<Result<string, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n const result = await this.vault.get<SecretPayload>(secretPath.vaultKey);\n if (!result.ok) {\n return result;\n }\n return { ok: true, data: result.data.value.value };\n }\n\n async put(\n name: string,\n value: string,\n options?: SecretScopeOptions,\n ): Promise<Result<void, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n const now = new Date().toISOString();\n return this.vault.put(secretPath.vaultKey, {\n value,\n createdAt: now,\n updatedAt: now,\n } satisfies SecretPayload);\n }\n\n async delete(\n name: string,\n options?: SecretScopeOptions,\n ): Promise<Result<void, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n return this.vault.delete(secretPath.vaultKey);\n }\n\n async list(\n options?: SecretScopeOptions,\n ): Promise<Result<string[], SecretsError>> {\n let prefix: string;\n try {\n const scope = canonicalizeSecretScope(options?.scope);\n prefix = scope === undefined ? \"secrets/\" : `secrets/scoped/${scope}/`;\n } catch (error) {\n return invalidSecretInput(\n error instanceof Error ? error.message : String(error),\n );\n }\n\n const result = await this.vault.list({\n prefix,\n removePrefix: true,\n });\n if (!result.ok) {\n return result;\n }\n return {\n ok: true,\n data: result.data.filter((name) => SECRET_NAME_RE.test(name)),\n };\n }\n\n async listAll(): Promise<Result<SecretCatalogEntry[], SecretsError>> {\n const entries = new Map<string, SecretCatalogEntry>();\n // A node older than bounded list paging ignores the cursor and returns the\n // same page again; a repeated cursor would loop forever, so it fails.\n const seenCursors = new Set<string>();\n let cursor: string | undefined;\n\n do {\n const result = await this.vault.listPage({\n prefix: \"secrets/\",\n removePrefix: true,\n limit: 1000,\n ...(cursor === undefined ? {} : { cursor }),\n });\n if (!result.ok) {\n return result;\n }\n\n for (const key of result.data.keys) {\n const entry = parseSecretCatalogKey(key);\n if (!entry) continue;\n entries.set(`${entry.scope ?? \"\"}\\u0000${entry.name}`, entry);\n }\n\n cursor = result.data.truncated ? result.data.nextCursor : undefined;\n if (result.data.truncated && cursor === undefined) {\n return invalidSecretInput(\n \"Secret catalog listing was truncated without a continuation cursor.\",\n );\n }\n if (cursor !== undefined) {\n if (seenCursors.has(cursor)) {\n return invalidSecretInput(\n \"Secret catalog listing repeated a continuation cursor; the node does not support paged KV lists.\",\n );\n }\n seenCursors.add(cursor);\n }\n } while (cursor !== undefined);\n\n return {\n ok: true,\n data: [...entries.values()].sort(\n (a, b) =>\n (a.scope ?? \"\").localeCompare(b.scope ?? \"\") ||\n a.name.localeCompare(b.name),\n ),\n };\n }\n}\n","/**\n * Canonical JSON serialization and content hashing for TinyCloud\n * encryption requests/responses.\n *\n * The node and SDK must agree byte-for-byte on the canonical form so\n * that body-hash bindings (`bodyHash`, `encryptedSymmetricKeyHash`,\n * `receiverPublicKeyHash`) verify on both sides.\n *\n * Canonical rules:\n * - Object keys are sorted lexicographically by code point.\n * - Strings are encoded with the JSON.stringify default (RFC 8259).\n * - Numbers are emitted via JSON.stringify; callers should restrict to\n * integers or use string fields for high-precision values.\n * - `undefined` properties are dropped. `null` is preserved.\n * - Arrays preserve element order.\n *\n * Hashing uses SHA-256 supplied by the caller (via an `EncryptionCrypto`\n * binding) so this module stays platform-agnostic.\n */\n\nexport type Json =\n | null\n | boolean\n | number\n | string\n | Json[]\n | { [key: string]: Json | undefined };\n\n/**\n * Produce the canonical JSON string for {@link value}. Object keys are\n * sorted, `undefined` properties are dropped, and primitive types are\n * encoded by `JSON.stringify`.\n */\nexport function canonicalize(value: Json | undefined): string {\n if (value === undefined) {\n return \"\";\n }\n return stringify(value);\n}\n\nfunction stringify(value: Json): string {\n if (value === null) return \"null\";\n switch (typeof value) {\n case \"boolean\":\n case \"number\":\n return JSON.stringify(value);\n case \"string\":\n return JSON.stringify(value);\n case \"object\": {\n if (Array.isArray(value)) {\n return `[${value.map(stringify).join(\",\")}]`;\n }\n const keys = Object.keys(value).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = value[k];\n if (v === undefined) continue;\n parts.push(`${JSON.stringify(k)}:${stringify(v)}`);\n }\n return `{${parts.join(\",\")}}`;\n }\n default:\n throw new TypeError(\n `canonicalize: unsupported value type ${typeof value}`,\n );\n }\n}\n\nconst HEX = \"0123456789abcdef\";\n\nexport function hexEncode(bytes: Uint8Array): string {\n let out = \"\";\n for (let i = 0; i < bytes.length; i++) {\n const b = bytes[i];\n out += HEX[(b >> 4) & 0xf] + HEX[b & 0xf];\n }\n return out;\n}\n\nexport function hexDecode(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new Error(\"hex string must have even length\");\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const hi = parseInt(hex[i * 2], 16);\n const lo = parseInt(hex[i * 2 + 1], 16);\n if (Number.isNaN(hi) || Number.isNaN(lo)) {\n throw new Error(\"invalid hex character\");\n }\n out[i] = (hi << 4) | lo;\n }\n return out;\n}\n\nexport function base64Encode(bytes: Uint8Array): string {\n // base64 (standard, not url-safe) so envelopes pass through JSON cleanly.\n // We avoid `btoa` to stay node-friendly without polyfills.\n const chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n let out = \"\";\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i];\n const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;\n const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;\n out += chars[(b0 >> 2) & 0x3f];\n out += chars[((b0 << 4) | (b1 >> 4)) & 0x3f];\n out += i + 1 < bytes.length ? chars[((b1 << 2) | (b2 >> 6)) & 0x3f] : \"=\";\n out += i + 2 < bytes.length ? chars[b2 & 0x3f] : \"=\";\n }\n return out;\n}\n\nexport function base64Decode(s: string): Uint8Array {\n const clean = s.replace(/[^A-Za-z0-9+/=]/g, \"\");\n const len = clean.length;\n if (len % 4 !== 0) {\n throw new Error(\"invalid base64 input\");\n }\n const padding =\n clean.endsWith(\"==\") ? 2 : clean.endsWith(\"=\") ? 1 : 0;\n const outLen = (len / 4) * 3 - padding;\n const out = new Uint8Array(outLen);\n const lookup: Record<string, number> = {};\n const chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n for (let i = 0; i < chars.length; i++) lookup[chars[i]] = i;\n\n let outIdx = 0;\n for (let i = 0; i < len; i += 4) {\n const v0 = lookup[clean[i]] ?? 0;\n const v1 = lookup[clean[i + 1]] ?? 0;\n const v2 = clean[i + 2] === \"=\" ? 0 : (lookup[clean[i + 2]] ?? 0);\n const v3 = clean[i + 3] === \"=\" ? 0 : (lookup[clean[i + 3]] ?? 0);\n const b0 = (v0 << 2) | (v1 >> 4);\n const b1 = ((v1 & 0x0f) << 4) | (v2 >> 2);\n const b2 = ((v2 & 0x03) << 6) | v3;\n if (outIdx < outLen) out[outIdx++] = b0;\n if (outIdx < outLen) out[outIdx++] = b1;\n if (outIdx < outLen) out[outIdx++] = b2;\n }\n return out;\n}\n\nexport function utf8Encode(s: string): Uint8Array {\n return new TextEncoder().encode(s);\n}\n\nexport function utf8Decode(b: Uint8Array): string {\n return new TextDecoder().decode(b);\n}\n\n/**\n * Compute `hexEncode(sha256(canonicalize(value)))`. The SHA-256 binding\n * is injected so the module remains usable in both the WASM and pure-JS\n * paths.\n */\nexport function canonicalHashHex(\n sha256: (bytes: Uint8Array) => Uint8Array,\n value: Json,\n): string {\n const canonical = canonicalize(value);\n return hexEncode(sha256(utf8Encode(canonical)));\n}\n","/**\n * Type definitions for TinyCloud one-of-one encryption.\n *\n * Wire shapes mirror the protocol described in the encryption\n * architecture: inline envelopes carry the encrypted symmetric key\n * alongside the ciphertext; decrypt requests are short-lived UCAN\n * invocations against a target node plus networkId.\n */\n\nimport type { Json } from \"./canonical\";\nimport type { PermissionHint } from \"../types\";\n\n/** Default ciphersuite identifier for v1 envelopes. */\nexport const DEFAULT_ENCRYPTION_ALG = \"x25519-aes256gcm/v1\" as const;\n\n/** Inline-envelope schema version. */\nexport const ENVELOPE_VERSION = 1 as const;\n\n/** Default key version on freshly-created networks. */\nexport const DEFAULT_KEY_VERSION = 1 as const;\n\n/** Decrypt-invocation fact type. */\nexport const DECRYPT_FACT_TYPE = \"tinycloud.encryption.decrypt/v1\" as const;\n\n/** Decrypt response type. */\nexport const DECRYPT_RESULT_TYPE =\n \"tinycloud.encryption.decrypt-result/v1\" as const;\n\n/** Encryption service identifier (manifest long form). */\nexport const ENCRYPTION_SERVICE = \"tinycloud.encryption\" as const;\n\n/** Short form used in recap/abilities maps. */\nexport const ENCRYPTION_SERVICE_SHORT = \"encryption\" as const;\n\n/** Decrypt ability URN. */\nexport const DECRYPT_ACTION = \"tinycloud.encryption/decrypt\" as const;\n\n/**\n * Inline encrypted envelope persisted in KV/SQL records.\n *\n * - `encryptedSymmetricKey` is opaque to the SDK; only the network can\n * unwrap it.\n * - `encryptedSymmetricKeyHash` is the canonical hash of the wrapped key\n * bytes (hex-encoded sha-256 of the base64 string's canonical JSON\n * form). The node recomputes this on every decrypt request.\n * - `ciphertext` and `aad` are payload bytes only; the node never sees\n * them.\n */\nexport interface InlineEncryptedEnvelope {\n /** Schema version. */\n v: typeof ENVELOPE_VERSION;\n /** Network id URN. */\n networkId: string;\n /** Ciphersuite identifier. */\n alg: string;\n /** Network key version that was used to wrap the symmetric key. */\n keyVersion: number;\n /** Base64-encoded wrapped symmetric key / capsule. */\n encryptedSymmetricKey: string;\n /** Hex sha-256 of the canonical encryptedSymmetricKey string. */\n encryptedSymmetricKeyHash: string;\n /** Base64-encoded payload ciphertext. */\n ciphertext: string;\n /** Base64-encoded associated data, if any. */\n aad?: string;\n /** Caller-supplied metadata. Not authenticated against the node. */\n metadata?: Record<string, string>;\n}\n\n/**\n * Node-published network descriptor. The node DB is authoritative; a\n * cached copy may also live under\n * `.well-known/encryption/network/<name>` in the owner's account\n * space (a discovery record only).\n */\nexport interface NetworkDescriptor {\n networkId: string;\n ownerDid: string;\n name: string;\n members: ReadonlyArray<{ nodeId: string; role: \"primary\" | \"share\" }>;\n threshold: { n: number; t: number };\n state: \"pending\" | \"generating\" | \"active\" | \"rotating\" | \"revoked\" | \"failed\";\n /** Base64-encoded network public key. */\n publicEncryptionKey: string;\n alg: string;\n keyVersion: number;\n keyBackend: \"local-one-of-one\" | \"dstack\" | \"threshold\";\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Decrypt-request body sent over the wire. Hashed (canonically) and\n * bound to the UCAN invocation via `facts.bodyHash`.\n */\nexport interface DecryptRequestBody {\n type: typeof DECRYPT_FACT_TYPE;\n targetNode: string;\n networkId: string;\n alg: string;\n keyVersion: number;\n /** Base64-encoded wrapped symmetric key from the envelope. */\n encryptedSymmetricKey: string;\n /** Recomputed hash of the wrapped key. */\n encryptedSymmetricKeyHash: string;\n /** Base64-encoded per-request receiver public key. */\n receiverPublicKey: string;\n /** Hash of the receiver public key. */\n receiverPublicKeyHash: string;\n}\n\n/**\n * Decrypt-response body returned by the node. The SDK verifies the\n * signature, recomputes hashes, then unwraps `wrappedKey` with the\n * per-request receiver private key before decrypting the payload.\n */\nexport interface DecryptResponseBody {\n type: typeof DECRYPT_RESULT_TYPE;\n targetNode: string;\n networkId: string;\n invocationCid: string;\n encryptedSymmetricKeyHash: string;\n receiverPublicKeyHash: string;\n /** Base64-encoded symmetric key re-encrypted to receiverPublicKey. */\n wrappedKey: string;\n alg: string;\n keyVersion: number;\n requestHash: string;\n nodeId: string;\n /** Base64-encoded ed25519 signature over canonical(response - signature field). */\n nodeSignature: string;\n}\n\n/**\n * Decrypt-invocation facts attached to the UCAN. Verifiers recompute\n * `bodyHash`, `encryptedSymmetricKeyHash`, and `receiverPublicKeyHash`\n * from the request body and reject any mismatch.\n */\nexport interface DecryptInvocationFact {\n type: typeof DECRYPT_FACT_TYPE;\n targetNode: string;\n networkId: string;\n bodyHash: string;\n encryptedSymmetricKeyHash: string;\n receiverPublicKeyHash: string;\n alg: string;\n keyVersion: number;\n}\n\n/**\n * Per-request receiver key pair (x25519). The private key never\n * leaves the SDK; the public key is sent to the node so the node can\n * rewrap the symmetric key.\n */\nexport interface ReceiverKeyPair {\n publicKey: Uint8Array;\n privateKey: Uint8Array;\n}\n\n/**\n * Crypto primitives injected into the encryption module. The SDK\n * provides these via WASM bindings; tests provide simple in-memory\n * implementations.\n */\nexport interface EncryptionCrypto {\n /** SHA-256 → 32-byte digest. */\n sha256(data: Uint8Array): Uint8Array;\n /** Cryptographically secure random bytes. */\n randomBytes(length: number): Uint8Array;\n /** Derive an x25519 key pair from a 32-byte seed. */\n x25519FromSeed(seed: Uint8Array): ReceiverKeyPair;\n /** Compute the x25519 ECDH shared secret. */\n x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n /** Authenticated symmetric encryption (the node's symmetric scheme). */\n authEncrypt(\n key: Uint8Array,\n plaintext: Uint8Array,\n aad?: Uint8Array,\n ): Uint8Array;\n /** Authenticated symmetric decryption (matched to authEncrypt). */\n authDecrypt(\n key: Uint8Array,\n ciphertext: Uint8Array,\n aad?: Uint8Array,\n ): Uint8Array;\n /**\n * Wrap a symmetric key for the network's public encryption key using\n * a sealed-box / hpke / x25519+symmetric construction. Implementation\n * is opaque; only the node can unwrap.\n */\n sealToNetworkKey(\n networkPublicKey: Uint8Array,\n symmetricKey: Uint8Array,\n ): Uint8Array;\n /**\n * Open a wrapped symmetric key that was re-encrypted to the\n * per-request receiver public key. The matching private key must be\n * supplied here; the SDK never sends it to the node.\n */\n openWithReceiverKey(\n receiverPrivateKey: Uint8Array,\n wrappedKey: Uint8Array,\n ): Uint8Array;\n /**\n * Verify an ed25519 signature over `message` produced by the node\n * identified by `nodeId` (the public-key DID).\n */\n verifyNodeSignature(\n nodeId: string,\n message: Uint8Array,\n signature: Uint8Array,\n ): boolean;\n}\n\n/**\n * Signer interface used to derive a receiver key pair from a wallet or\n * session signer. The signature is HKDF-extracted into the receiver\n * seed so the public key is reproducible given the same context.\n */\nexport interface ReceiverKeySigner {\n signMessage(message: string): Promise<string>;\n}\n\n/** Capability proof material accompanying a decrypt invocation. */\nexport interface DecryptCapabilityProof {\n /** Delegation chain CIDs rooted at the network owner DID. */\n proofs: ReadonlyArray<string>;\n /** Optional Authorization header value to use instead of building one. */\n authorization?: string;\n}\n\n/**\n * Inputs to the decrypt invocation builder.\n */\nexport interface BuildDecryptInvocationInput {\n /** Target node DID — also the UCAN audience. */\n targetNode: string;\n /** Network id URN — also the recap resource. */\n networkId: string;\n /** Canonical body that will be POSTed. */\n body: DecryptRequestBody;\n /** Facts include hashes bound to the canonical body. */\n facts: DecryptInvocationFact;\n /** Capability proof chain. */\n proof: DecryptCapabilityProof;\n /** Optional `nbf` UCAN field as an ISO date string. */\n notBefore?: string;\n /** Optional `exp` UCAN field as an ISO date string. */\n expiration?: string;\n}\n\n/**\n * The output of {@link buildDecryptInvocation}.\n */\nexport interface BuiltDecryptInvocation {\n /** HTTP `Authorization` header value. */\n authorization: string;\n /** CID of the invocation (used by the node response binding). */\n invocationCid: string;\n /** Canonical body string the node will hash. */\n canonicalBody: string;\n}\n\n/**\n * Signer interface for producing the decrypt invocation. WASM bindings\n * implement this with the same session signer used for KV/SQL\n * invocations; tests can stub it.\n */\nexport interface DecryptInvocationSigner {\n signDecryptInvocation(input: BuildDecryptInvocationInput): Promise<BuiltDecryptInvocation>;\n}\n\n/**\n * Errors thrown / returned from the encryption module.\n */\nexport type EncryptionErrorInput =\n | { code: \"NETWORK_NOT_FOUND\"; networkId?: string; name?: string; message?: string }\n | { code: \"NETWORK_NOT_ACTIVE\"; state: string; message?: string }\n | { code: \"INVALID_NETWORK_ID\"; message: string }\n | { code: \"INVALID_ENVELOPE\"; message: string }\n | { code: \"DECRYPT_DENIED\"; message: string; permissionHint?: PermissionHint }\n | { code: \"INVALID_RESPONSE\"; message: string }\n | { code: \"RESPONSE_SIGNATURE_INVALID\"; message?: string }\n | { code: \"RESPONSE_BINDING_MISMATCH\"; field: string; message?: string }\n | { code: \"TRANSPORT_ERROR\"; cause: Error; message?: string }\n | { code: \"INVALID_INPUT\"; message: string };\n\nexport type EncryptionError = EncryptionErrorInput & {\n service: \"encryption\";\n message: string;\n};\n\nfunction defaultEncryptionMessage(input: EncryptionErrorInput): string {\n switch (input.code) {\n case \"NETWORK_NOT_FOUND\":\n return (\n input.message ??\n `Network not found: ${input.networkId ?? input.name ?? \"<unknown>\"}`\n );\n case \"NETWORK_NOT_ACTIVE\":\n return input.message ?? `Network not active (state=${input.state})`;\n case \"INVALID_NETWORK_ID\":\n return input.message;\n case \"INVALID_ENVELOPE\":\n return input.message;\n case \"DECRYPT_DENIED\":\n return input.message;\n case \"INVALID_RESPONSE\":\n return input.message;\n case \"RESPONSE_SIGNATURE_INVALID\":\n return input.message ?? \"Node response signature failed to verify\";\n case \"RESPONSE_BINDING_MISMATCH\":\n return (\n input.message ??\n `Node response binding mismatch on field ${JSON.stringify(input.field)}`\n );\n case \"TRANSPORT_ERROR\":\n return input.message ?? input.cause.message;\n case \"INVALID_INPUT\":\n return input.message;\n }\n}\n\nexport function encryptionError(input: EncryptionErrorInput): EncryptionError {\n return {\n ...input,\n service: \"encryption\",\n message: defaultEncryptionMessage(input),\n };\n}\n\n/** Helper for the test/runtime layers to coerce arbitrary throwables. */\nexport function toError(error: unknown): Error {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null) {\n return new Error(JSON.stringify(error));\n }\n return new Error(String(error));\n}\n\n/** Re-export for ergonomic typing of canonical payloads. */\nexport type CanonicalJson = Json;\n","/**\n * Network-descriptor discovery.\n *\n * Resolution order (per architecture):\n *\n * 1. The node's authoritative endpoint\n * `GET /encryption/networks/<networkId>` returns the current\n * descriptor (`state`, `publicEncryptionKey`, `keyVersion`, ...).\n * 2. If the node is unreachable, fall back to the cached discovery\n * record at `.well-known/encryption/network/<name>` inside the\n * owner's public space.\n *\n * The node DB is authoritative on conflict; cached records are\n * advisory only.\n */\n\nimport {\n NetworkIdError,\n networkDiscoveryKey,\n ownerDidMatches,\n parseNetworkId,\n} from \"./networkId\";\nimport {\n encryptionError,\n type EncryptionError,\n type NetworkDescriptor,\n} from \"./types\";\n\nexport type DiscoverySource = \"node\" | \"well-known\";\n\nexport interface DiscoveredNetwork {\n descriptor: NetworkDescriptor;\n source: DiscoverySource;\n}\n\nexport interface NodeDescriptorFetcher {\n /** Fetch the descriptor by full networkId URN. */\n fetchByNetworkId(networkId: string): Promise<NetworkDescriptor | null>;\n}\n\nexport interface WellKnownDescriptorFetcher {\n /**\n * Read the cached well-known descriptor by owner DID + network name.\n * Returns null if no record exists or the record is unreadable.\n */\n fetchWellKnown(\n ownerDid: string,\n discoveryKey: string,\n ): Promise<NetworkDescriptor | null>;\n}\n\nexport interface DiscoverNetworkInput {\n /** Either a networkId URN or a bare network name (paired with `ownerDid`). */\n identifier: string;\n /** Required when identifier is a bare name. */\n ownerDid?: string;\n node?: NodeDescriptorFetcher;\n wellKnown?: WellKnownDescriptorFetcher;\n}\n\n/**\n * Resolve a network descriptor. The node fetcher is preferred; the\n * well-known fallback is used only on transport failure.\n *\n * The returned descriptor is sanity-checked: `networkId`, `ownerDid`,\n * and `name` must agree with the URN, and the public key field must\n * be non-empty.\n */\nexport async function discoverNetwork(\n input: DiscoverNetworkInput,\n):\n | Promise<{ ok: true; data: DiscoveredNetwork } | { ok: false; error: EncryptionError }> {\n let networkId: string;\n let ownerDid: string;\n let name: string;\n try {\n if (input.identifier.startsWith(\"urn:tinycloud:encryption:\")) {\n const parsed = parseNetworkId(input.identifier);\n networkId = parsed.networkId;\n ownerDid = parsed.ownerDid;\n name = parsed.name;\n } else {\n if (input.ownerDid === undefined) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"discoverNetwork requires `ownerDid` when identifier is a bare network name\",\n }),\n };\n }\n networkId = `urn:tinycloud:encryption:${input.ownerDid}:${input.identifier}`;\n const parsed = parseNetworkId(networkId);\n ownerDid = parsed.ownerDid;\n name = parsed.name;\n }\n } catch (err) {\n if (err instanceof NetworkIdError) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: err.message,\n }),\n };\n }\n throw err;\n }\n\n // 1) Try the node first.\n if (input.node !== undefined) {\n try {\n const descriptor = await input.node.fetchByNetworkId(networkId);\n if (descriptor !== null) {\n const validated = validateDescriptor(descriptor, networkId, ownerDid, name);\n if (!validated.ok) return validated;\n return { ok: true, data: { descriptor: validated.data, source: \"node\" } };\n }\n } catch (err) {\n // Fall through to well-known\n }\n }\n\n // 2) Fallback to well-known cache.\n if (input.wellKnown !== undefined) {\n try {\n const descriptor = await input.wellKnown.fetchWellKnown(\n ownerDid,\n networkDiscoveryKey(name),\n );\n if (descriptor !== null) {\n const validated = validateDescriptor(descriptor, networkId, ownerDid, name);\n if (!validated.ok) return validated;\n return {\n ok: true,\n data: { descriptor: validated.data, source: \"well-known\" },\n };\n }\n } catch (err) {\n // Fall through to NOT_FOUND\n }\n }\n\n return {\n ok: false,\n error: encryptionError({\n code: \"NETWORK_NOT_FOUND\",\n networkId,\n name,\n }),\n };\n}\n\nfunction validateDescriptor(\n descriptor: NetworkDescriptor,\n networkId: string,\n ownerDid: string,\n name: string,\n):\n | { ok: true; data: NetworkDescriptor }\n | { ok: false; error: EncryptionError } {\n let descriptorNetwork;\n try {\n descriptorNetwork = parseNetworkId(descriptor.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: `descriptor networkId is malformed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n\n if (\n descriptorNetwork.name !== name ||\n !ownerDidMatches(descriptorNetwork.ownerDid, ownerDid)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: `descriptor networkId ${JSON.stringify(descriptor.networkId)} does not match expected ${JSON.stringify(networkId)}`,\n }),\n };\n }\n\n const descriptorOwnerDid = descriptorOwner(descriptor);\n if (\n descriptorOwnerDid === undefined ||\n !ownerDidMatches(descriptorOwnerDid, ownerDid) ||\n !ownerDidMatches(descriptorOwnerDid, descriptorNetwork.ownerDid)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor ownerDid does not match networkId ownerDid\",\n }),\n };\n }\n if (descriptor.name !== name) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor name does not match networkId name\",\n }),\n };\n }\n if (\n typeof descriptor.publicEncryptionKey !== \"string\" ||\n descriptor.publicEncryptionKey.length === 0\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor publicEncryptionKey must be a non-empty string\",\n }),\n };\n }\n return {\n ok: true,\n data: {\n ...descriptor,\n ownerDid: descriptorOwnerDid,\n },\n };\n}\n\nfunction descriptorOwner(descriptor: NetworkDescriptor): string | undefined {\n if (typeof descriptor.ownerDid === \"string\" && descriptor.ownerDid.length > 0) {\n return descriptor.ownerDid;\n }\n\n const legacyDescriptor = descriptor as NetworkDescriptor & {\n principal?: unknown;\n };\n return typeof legacyDescriptor.principal === \"string\" &&\n legacyDescriptor.principal.length > 0\n ? legacyDescriptor.principal\n : undefined;\n}\n\n/**\n * Reject a descriptor that is not in a state that accepts decrypt\n * requests. Only `active` and `rotating` networks may decrypt; revoked\n * or pending networks reject.\n */\nexport function ensureNetworkUsableForDecrypt(\n descriptor: NetworkDescriptor,\n):\n | { ok: true; data: NetworkDescriptor }\n | { ok: false; error: EncryptionError } {\n if (descriptor.state === \"active\" || descriptor.state === \"rotating\") {\n return { ok: true, data: descriptor };\n }\n return {\n ok: false,\n error: encryptionError({\n code: \"NETWORK_NOT_ACTIVE\",\n state: descriptor.state,\n }),\n };\n}\n","/**\n * Inline-envelope encrypt / decrypt helpers.\n *\n * Encryption is fully local: the SDK generates a per-record symmetric\n * key, encrypts the payload, then wraps the symmetric key against the\n * network's public encryption key. The wrapped key (and key hash)\n * travels alongside the ciphertext inside an\n * {@link InlineEncryptedEnvelope}.\n *\n * Decryption is split: the node unwraps the symmetric key to the\n * per-request receiver public key (see {@link buildDecryptInvocation}\n * and the decrypt route); this module is responsible for the local\n * payload decryption once the symmetric key is available.\n */\n\nimport {\n base64Decode,\n base64Encode,\n canonicalHashHex,\n} from \"./canonical\";\nimport {\n DEFAULT_ENCRYPTION_ALG,\n DEFAULT_KEY_VERSION,\n ENVELOPE_VERSION,\n encryptionError,\n type EncryptionCrypto,\n type EncryptionError,\n type InlineEncryptedEnvelope,\n} from \"./types\";\nimport { parseNetworkId } from \"./networkId\";\n\nexport interface EncryptToNetworkInput {\n /** Target network id URN. */\n networkId: string;\n /** Network public key bytes (already discovered). */\n networkPublicKey: Uint8Array;\n /** Payload bytes to encrypt. Callers serialize objects to bytes themselves. */\n plaintext: Uint8Array;\n /** Optional associated authenticated data. */\n aad?: Uint8Array;\n /** Ciphersuite identifier. Defaults to {@link DEFAULT_ENCRYPTION_ALG}. */\n alg?: string;\n /** Key version. Defaults to {@link DEFAULT_KEY_VERSION}. */\n keyVersion?: number;\n /** Caller-supplied envelope metadata. */\n metadata?: Record<string, string>;\n}\n\nexport interface EncryptToNetworkResult {\n envelope: InlineEncryptedEnvelope;\n /** Symmetric key returned for caller bookkeeping; do NOT persist. */\n symmetricKey: Uint8Array;\n}\n\n/**\n * Local-only encrypt: generates a symmetric key, encrypts the payload,\n * wraps the key against the network public key, and returns the\n * inline envelope.\n */\nexport function encryptToNetwork(\n crypto: EncryptionCrypto,\n input: EncryptToNetworkInput,\n): EncryptToNetworkResult {\n parseNetworkId(input.networkId);\n const alg = input.alg ?? DEFAULT_ENCRYPTION_ALG;\n const keyVersion = input.keyVersion ?? DEFAULT_KEY_VERSION;\n\n const symmetricKey = crypto.randomBytes(32);\n const ciphertext = crypto.authEncrypt(symmetricKey, input.plaintext, input.aad);\n const wrapped = crypto.sealToNetworkKey(input.networkPublicKey, symmetricKey);\n const encryptedSymmetricKey = base64Encode(wrapped);\n const encryptedSymmetricKeyHash = canonicalHashHex(\n crypto.sha256,\n encryptedSymmetricKey,\n );\n\n const envelope: InlineEncryptedEnvelope = {\n v: ENVELOPE_VERSION,\n networkId: input.networkId,\n alg,\n keyVersion,\n encryptedSymmetricKey,\n encryptedSymmetricKeyHash,\n ciphertext: base64Encode(ciphertext),\n ...(input.aad !== undefined ? { aad: base64Encode(input.aad) } : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n };\n\n return { envelope, symmetricKey };\n}\n\n/**\n * Validate an inline envelope shape. Returns an error if the envelope\n * is missing required fields or fails internal hash recomputation.\n */\nexport function validateEnvelope(\n crypto: EncryptionCrypto,\n envelope: unknown,\n): { ok: true; data: InlineEncryptedEnvelope } | { ok: false; error: EncryptionError } {\n if (envelope === null || typeof envelope !== \"object\") {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: \"envelope must be an object\",\n }),\n };\n }\n const e = envelope as InlineEncryptedEnvelope;\n if (e.v !== ENVELOPE_VERSION) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.v must be ${ENVELOPE_VERSION} (got ${e.v as unknown as string})`,\n }),\n };\n }\n try {\n parseNetworkId(e.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.networkId is malformed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n for (const field of [\n \"alg\",\n \"encryptedSymmetricKey\",\n \"encryptedSymmetricKeyHash\",\n \"ciphertext\",\n ] as const) {\n if (typeof e[field] !== \"string\" || (e[field] as string).length === 0) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.${field} must be a non-empty string`,\n }),\n };\n }\n }\n if (typeof e.keyVersion !== \"number\" || !Number.isInteger(e.keyVersion)) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: \"envelope.keyVersion must be an integer\",\n }),\n };\n }\n const expectedHash = canonicalHashHex(crypto.sha256, e.encryptedSymmetricKey);\n if (expectedHash !== e.encryptedSymmetricKeyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message:\n \"envelope.encryptedSymmetricKeyHash does not match canonical hash of encryptedSymmetricKey\",\n }),\n };\n }\n return { ok: true, data: e };\n}\n\n/**\n * Decrypt an inline envelope given the unwrapped symmetric key.\n *\n * Callers typically obtain the symmetric key via the node decrypt\n * endpoint plus the per-request receiver key pair (see\n * `EncryptionService.decryptEnvelope`).\n */\nexport function decryptEnvelopeWithKey(\n crypto: EncryptionCrypto,\n envelope: InlineEncryptedEnvelope,\n symmetricKey: Uint8Array,\n): Uint8Array {\n const ciphertext = base64Decode(envelope.ciphertext);\n const aad = envelope.aad !== undefined ? base64Decode(envelope.aad) : undefined;\n return crypto.authDecrypt(symmetricKey, ciphertext, aad);\n}\n","/**\n * TinyCloud encryption decrypt-invocation builder.\n *\n * The decrypt invocation is a UCAN-style TinyCloud invocation against\n * a node plus a network id. It is structurally distinct from the\n * existing space-shaped invocations:\n *\n * - `aud` (audience) is the **target node DID** (not a space owner).\n * - `att` (attenuation) uses the **networkId URN** as the resource\n * key (not a `tinycloud:pkh:...:<space>` URI).\n * - `fct` (facts) binds `bodyHash`, `encryptedSymmetricKeyHash`, and\n * `receiverPublicKeyHash` so the node can recompute them from the\n * POST body.\n *\n * Production callers inject a `DecryptInvocationSigner` backed by the\n * WASM UCAN/session signer. Tests pass a deterministic stub.\n */\n\nimport { canonicalize, canonicalHashHex, hexEncode, utf8Encode } from \"./canonical\";\nimport { parseNetworkId } from \"./networkId\";\nimport {\n DECRYPT_ACTION,\n DECRYPT_FACT_TYPE,\n ENCRYPTION_SERVICE,\n encryptionError,\n type BuildDecryptInvocationInput,\n type BuiltDecryptInvocation,\n type CanonicalJson,\n type DecryptCapabilityProof,\n type DecryptInvocationFact,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type EncryptionCrypto,\n type EncryptionError,\n} from \"./types\";\n\nexport interface CanonicalDecryptRequest {\n /** The canonical body that the node will hash. */\n canonicalBody: string;\n /** Hex sha-256 of the canonical body bytes. */\n bodyHash: string;\n /** Hex sha-256 of the receiver public key bytes. */\n receiverPublicKeyHash: string;\n}\n\nexport interface BuildCanonicalDecryptRequestInput {\n crypto: EncryptionCrypto;\n body: DecryptRequestBody;\n receiverPublicKey: Uint8Array;\n}\n\n/**\n * Build the canonical body string and its bound hashes for a decrypt\n * request. The output is what gets POSTed to the node, and what the\n * node will hash to verify `facts.bodyHash`.\n */\nexport function buildCanonicalDecryptRequest(\n input: BuildCanonicalDecryptRequestInput,\n): CanonicalDecryptRequest {\n const canonicalBody = canonicalize(input.body as unknown as CanonicalJson);\n const bodyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body as unknown as CanonicalJson,\n );\n const receiverPublicKeyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body.receiverPublicKey,\n );\n return { canonicalBody, bodyHash, receiverPublicKeyHash };\n}\n\nexport interface BuildDecryptFactsInput {\n crypto: EncryptionCrypto;\n body: DecryptRequestBody;\n /** Encrypted symmetric key hash from the envelope (already canonical). */\n encryptedSymmetricKeyHash: string;\n /** Receiver public key bytes. */\n receiverPublicKey: Uint8Array;\n /** Canonical body string used to derive bodyHash. */\n canonicalBody?: string;\n}\n\n/**\n * Build the {@link DecryptInvocationFact} that will be embedded in the\n * UCAN `fct` field. Hashes are recomputed here so callers cannot drift\n * from the canonical body without the node noticing.\n */\nexport function buildDecryptFacts(\n input: BuildDecryptFactsInput,\n): DecryptInvocationFact {\n // When a precomputed canonicalBody string is supplied, hash its bytes\n // directly. Don't route it through canonicalHashHex, which would\n // re-canonicalize the string itself (escaping it as a JSON value).\n const bodyHash =\n input.canonicalBody !== undefined\n ? hexEncode(input.crypto.sha256(utf8Encode(input.canonicalBody)))\n : canonicalHashHex(\n input.crypto.sha256,\n input.body as unknown as CanonicalJson,\n );\n const receiverPublicKeyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body.receiverPublicKey,\n );\n return {\n type: DECRYPT_FACT_TYPE,\n targetNode: input.body.targetNode,\n networkId: input.body.networkId,\n bodyHash,\n encryptedSymmetricKeyHash: input.encryptedSymmetricKeyHash,\n receiverPublicKeyHash,\n alg: input.body.alg,\n keyVersion: input.body.keyVersion,\n };\n}\n\n/**\n * Recap-shaped attenuation for the decrypt invocation. The resource\n * key is the networkId URN; the ability is the long-form\n * `tinycloud.encryption/decrypt`. This is intentionally distinct from\n * the existing space-shaped invocation map so callers cannot\n * accidentally fake a space prefix.\n */\nexport function buildDecryptAttenuation(\n networkId: string,\n): Record<string, Record<string, Record<string, never>>> {\n parseNetworkId(networkId);\n return {\n [networkId]: {\n [DECRYPT_ACTION]: {},\n },\n };\n}\n\n/**\n * Validate a {@link BuildDecryptInvocationInput} payload — the body\n * shape, the facts bindings, and the audience contract — without\n * actually signing. Returns either the input (typed) or a structured\n * error so callers can short-circuit before calling into WASM.\n */\nexport function checkDecryptInvocationInput(\n crypto: EncryptionCrypto,\n input: BuildDecryptInvocationInput,\n):\n | { ok: true; data: BuildDecryptInvocationInput; canonicalBody: string }\n | { ok: false; error: EncryptionError } {\n if (input.body.type !== DECRYPT_FACT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: `body.type must be ${DECRYPT_FACT_TYPE}`,\n }),\n };\n }\n if (input.facts.type !== DECRYPT_FACT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: `facts.type must be ${DECRYPT_FACT_TYPE}`,\n }),\n };\n }\n if (input.facts.targetNode !== input.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.targetNode must equal targetNode — the UCAN audience binds the request to a single node\",\n }),\n };\n }\n if (input.body.targetNode !== input.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"body.targetNode must equal targetNode\",\n }),\n };\n }\n if (input.facts.networkId !== input.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.networkId must equal networkId\",\n }),\n };\n }\n if (input.body.networkId !== input.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"body.networkId must equal networkId\",\n }),\n };\n }\n if (input.facts.alg !== input.body.alg) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.alg must equal body.alg\",\n }),\n };\n }\n if (input.facts.keyVersion !== input.body.keyVersion) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.keyVersion must equal body.keyVersion\",\n }),\n };\n }\n if (\n input.facts.encryptedSymmetricKeyHash !==\n input.body.encryptedSymmetricKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.encryptedSymmetricKeyHash must equal body.encryptedSymmetricKeyHash\",\n }),\n };\n }\n if (\n input.facts.receiverPublicKeyHash !== input.body.receiverPublicKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.receiverPublicKeyHash must equal body.receiverPublicKeyHash\",\n }),\n };\n }\n try {\n parseNetworkId(input.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: err instanceof Error ? err.message : String(err),\n }),\n };\n }\n const canonicalBody = canonicalize(\n input.body as unknown as CanonicalJson,\n );\n const expectedBodyHash = canonicalHashHex(crypto.sha256, input.body as unknown as CanonicalJson);\n if (expectedBodyHash !== input.facts.bodyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.bodyHash does not match the canonical body hash\",\n }),\n };\n }\n return { ok: true, data: input, canonicalBody };\n}\n\n/**\n * Compose the high-level decrypt invocation and hand it to the signer\n * for UCAN minting. The signer returns the Authorization header value\n * plus the invocation CID; this function only validates and\n * orchestrates — it does not perform crypto signing itself.\n */\nexport async function buildDecryptInvocation(\n crypto: EncryptionCrypto,\n signer: DecryptInvocationSigner,\n input: BuildDecryptInvocationInput,\n): Promise<{ ok: true; data: BuiltDecryptInvocation } | { ok: false; error: EncryptionError }> {\n const checked = checkDecryptInvocationInput(crypto, input);\n if (!checked.ok) {\n return checked;\n }\n try {\n const built = await signer.signDecryptInvocation(checked.data);\n if (!built.authorization || !built.invocationCid) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"decrypt-invocation signer returned an empty authorization or invocationCid\",\n }),\n };\n }\n if (built.canonicalBody !== checked.canonicalBody) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"decrypt-invocation signer returned a canonicalBody that does not match the SDK's canonicalization — signer must use the SDK-provided body\",\n }),\n };\n }\n return { ok: true, data: built };\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: err instanceof Error ? err : new Error(String(err)),\n message: `failed to sign decrypt invocation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n}\n\n/** Re-export so callers can introspect the service+action constants. */\nexport { DECRYPT_ACTION, ENCRYPTION_SERVICE };\n","/**\n * Per-request receiver key generation.\n *\n * The receiver key pair is generated for a single decrypt request: the\n * SDK sends `receiverPublicKey` to the node so the node can rewrap the\n * symmetric key; the matching private key never leaves the SDK.\n *\n * Two derivation modes are supported:\n *\n * 1. **Random** — `crypto.randomBytes(32)` seeds a fresh x25519 pair.\n * This is the default for one-of-one flows.\n *\n * 2. **Signed-context** — the caller provides a signer that signs a\n * deterministic context message (network id + nonce + invocation\n * intent). The signature bytes are SHA-256'd into the seed. This is\n * useful when callers want the receiver key to be reproducible by\n * the same session signer (e.g. for delegated reads where the\n * signer is the only stable secret).\n */\n\nimport { utf8Encode } from \"./canonical\";\nimport type {\n EncryptionCrypto,\n ReceiverKeyPair,\n ReceiverKeySigner,\n} from \"./types\";\n\nexport interface RandomReceiverKeyInput {\n crypto: EncryptionCrypto;\n}\n\nexport function generateRandomReceiverKey(\n input: RandomReceiverKeyInput,\n): ReceiverKeyPair {\n const seed = input.crypto.randomBytes(32);\n return input.crypto.x25519FromSeed(seed);\n}\n\nexport interface SignedReceiverKeyInput {\n crypto: EncryptionCrypto;\n signer: ReceiverKeySigner;\n networkId: string;\n /** Optional extra context (e.g. invocation nonce) folded into the message. */\n context?: string;\n}\n\n/**\n * Deterministic receiver-key derivation: signs a context string with\n * the supplied signer, then SHA-256s the signature bytes into the\n * x25519 seed.\n *\n * The context message is:\n * `tinycloud.encryption.receiver-key/v1:<networkId>:<context>`\n *\n * Callers MUST include unique context (e.g. a fresh nonce) on every\n * request unless they explicitly want reproducibility.\n */\nexport async function deriveSignedReceiverKey(\n input: SignedReceiverKeyInput,\n): Promise<ReceiverKeyPair> {\n const message = `tinycloud.encryption.receiver-key/v1:${input.networkId}:${input.context ?? \"\"}`;\n const sig = await input.signer.signMessage(message);\n // Treat the signature as opaque bytes; sha256 collapses to a 32-byte seed.\n const sigBytes = utf8Encode(sig);\n const seed = input.crypto.sha256(sigBytes);\n return input.crypto.x25519FromSeed(seed);\n}\n","/**\n * Decrypt-response verification.\n *\n * The node returns the unwrapped symmetric key re-encrypted to the\n * per-request receiver public key. Before the SDK uses the wrapped\n * key, it must:\n *\n * 1. Verify the node signature over the canonical response (excluding\n * the signature field).\n * 2. Recompute every binding hash and reject any mismatch.\n * 3. Confirm `targetNode`, `networkId`, `alg`, and `keyVersion` echo\n * what the SDK sent.\n *\n * After verification, the SDK opens `wrappedKey` with the per-request\n * receiver private key and uses the resulting symmetric key to\n * decrypt the inline envelope payload.\n */\n\nimport { base64Decode, canonicalize, hexEncode, utf8Encode } from \"./canonical\";\nimport {\n DECRYPT_RESULT_TYPE,\n encryptionError,\n type CanonicalJson,\n type DecryptInvocationFact,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n} from \"./types\";\n\n/**\n * Construct the canonical bytes that the node signed.\n *\n * The signature covers the response with `nodeSignature` removed. We\n * canonicalize and hash the same way the node does so the binding is\n * stable.\n */\nexport function canonicalSignedResponse(\n response: DecryptResponseBody,\n): string {\n // Strip the signature; canonicalize sorts keys for us.\n const { nodeSignature: _drop, ...rest } = response;\n return canonicalize(rest as unknown as CanonicalJson);\n}\n\nexport interface VerifyDecryptResponseInput {\n crypto: EncryptionCrypto;\n request: DecryptRequestBody;\n facts: DecryptInvocationFact;\n /** CID of the signed invocation that produced this response. */\n invocationCid: string;\n /** Hex bodyHash that was bound in `facts.bodyHash`. */\n requestBodyHash: string;\n response: DecryptResponseBody;\n}\n\n/**\n * Verify the node's decrypt response. Returns the response on success;\n * a structured error on signature, binding, or shape failure.\n */\nexport function verifyDecryptResponse(\n input: VerifyDecryptResponseInput,\n):\n | { ok: true; data: DecryptResponseBody }\n | { ok: false; error: EncryptionError } {\n const { crypto, request, facts, invocationCid, requestBodyHash, response } =\n input;\n\n if (response.type !== DECRYPT_RESULT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_RESPONSE\",\n message: `response.type must be ${DECRYPT_RESULT_TYPE}`,\n }),\n };\n }\n if (response.targetNode !== request.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"targetNode\",\n }),\n };\n }\n if (response.networkId !== request.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"networkId\",\n }),\n };\n }\n if (response.nodeId !== request.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"nodeId\",\n }),\n };\n }\n if (response.alg !== request.alg) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"alg\",\n }),\n };\n }\n if (response.keyVersion !== request.keyVersion) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"keyVersion\",\n }),\n };\n }\n if (\n response.encryptedSymmetricKeyHash !==\n request.encryptedSymmetricKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"encryptedSymmetricKeyHash\",\n }),\n };\n }\n if (response.receiverPublicKeyHash !== request.receiverPublicKeyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"receiverPublicKeyHash\",\n }),\n };\n }\n if (response.invocationCid !== invocationCid) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"invocationCid\",\n }),\n };\n }\n // requestHash binds invocationCid || requestBodyHash per spec. The `||`\n // notation is concatenation, not a literal delimiter.\n const expectedRequestHash = hexEncode(\n crypto.sha256(utf8Encode(`${invocationCid}${requestBodyHash}`)),\n );\n if (response.requestHash !== expectedRequestHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"requestHash\",\n }),\n };\n }\n // The facts must agree with the response (defensive: catches a node\n // that returns a fresh body bound to a different invocation).\n if (\n facts.encryptedSymmetricKeyHash !== response.encryptedSymmetricKeyHash ||\n facts.receiverPublicKeyHash !== response.receiverPublicKeyHash ||\n facts.networkId !== response.networkId ||\n facts.targetNode !== response.targetNode ||\n facts.alg !== response.alg ||\n facts.keyVersion !== response.keyVersion\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"facts\",\n }),\n };\n }\n\n const signedBytes = new TextEncoder().encode(\n canonicalSignedResponse(response),\n );\n const signatureBytes = base64Decode(response.nodeSignature);\n if (\n !crypto.verifyNodeSignature(response.nodeId, signedBytes, signatureBytes)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_SIGNATURE_INVALID\",\n }),\n };\n }\n return { ok: true, data: response };\n}\n\n/**\n * After verification, open the response's `wrappedKey` with the\n * per-request receiver private key and return the symmetric key.\n */\nexport function openWrappedKey(\n crypto: EncryptionCrypto,\n receiverPrivateKey: Uint8Array,\n response: DecryptResponseBody,\n): Uint8Array {\n const wrapped = base64Decode(response.wrappedKey);\n return crypto.openWithReceiverKey(receiverPrivateKey, wrapped);\n}\n","/**\n * EncryptionService — TinyCloud one-of-one encryption service.\n *\n * Responsibilities:\n * - Network discovery (`discoverNetwork`).\n * - Local envelope encryption (`encryptToNetwork`).\n * - Node-mediated decrypt with full request/response binding\n * verification (`decryptEnvelope`).\n *\n * Non-responsibilities:\n * - KV/SQL access. Callers fetch encrypted envelopes from their data\n * service of choice and pass them in.\n * - Network onboarding/ceremony. Those routes are node-only.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport { type Result } from \"../types\";\nimport {\n base64Decode,\n base64Encode,\n canonicalHashHex,\n} from \"./canonical\";\nimport {\n discoverNetwork as discoverNetworkFn,\n ensureNetworkUsableForDecrypt,\n type NodeDescriptorFetcher,\n type WellKnownDescriptorFetcher,\n} from \"./discovery\";\nimport {\n decryptEnvelopeWithKey,\n encryptToNetwork as encryptToNetworkFn,\n validateEnvelope,\n} from \"./envelope\";\nimport {\n buildCanonicalDecryptRequest,\n buildDecryptFacts,\n buildDecryptInvocation,\n} from \"./invocation\";\nimport { generateRandomReceiverKey } from \"./receiverKey\";\nimport {\n openWrappedKey,\n verifyDecryptResponse,\n} from \"./response\";\nimport { DecryptTransportResponseError } from \"@tinycloud/sdk-services/internal/decrypt-transport-response-error\";\nimport {\n DECRYPT_FACT_TYPE,\n encryptionError,\n type DecryptCapabilityProof,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n type InlineEncryptedEnvelope,\n type NetworkDescriptor,\n toError,\n} from \"./types\";\nimport type {\n EncryptToNetworkOptions,\n DecryptEnvelopeOptions,\n IEncryptionService,\n} from \"./IEncryptionService\";\n\n// Local Result helpers typed to EncryptionError. The shared `ok` / `err`\n// from `../types` default the error generic to `ServiceError`, which\n// widens our return-type inference here.\nfunction encOk<T>(data: T): Result<T, EncryptionError> {\n return { ok: true, data };\n}\nfunction encErr<T = never>(error: EncryptionError): Result<T, EncryptionError> {\n return { ok: false, error };\n}\n\n/**\n * Transport for posting decrypt requests to a TinyCloud node.\n *\n * Implementations supply the `Authorization` header (built by the\n * decrypt-invocation signer) and POST the canonical body. The\n * response body is JSON-decoded into a {@link DecryptResponseBody}.\n */\nexport interface DecryptTransport {\n postDecrypt(input: {\n targetNode: string;\n networkId: string;\n authorization: string;\n canonicalBody: string;\n signal?: AbortSignal;\n }): Promise<DecryptResponseBody>;\n}\n\nexport { DecryptTransportResponseError } from \"@tinycloud/sdk-services/internal/decrypt-transport-response-error\";\n\nexport interface EncryptionServiceConfig {\n crypto: EncryptionCrypto;\n signer: DecryptInvocationSigner;\n transport: DecryptTransport;\n node?: NodeDescriptorFetcher;\n wellKnown?: WellKnownDescriptorFetcher;\n /** Bound by an owning service graph to prevent cross-session authority use. */\n assertActive?: () => void;\n [key: string]: unknown;\n}\n\nexport class EncryptionService\n extends BaseService\n implements IEncryptionService\n{\n static readonly serviceName = \"encryption\";\n\n declare protected _config: EncryptionServiceConfig;\n\n constructor(config: EncryptionServiceConfig) {\n super();\n this._config = config;\n }\n\n get config(): EncryptionServiceConfig {\n return this._config;\n }\n\n private get crypto(): EncryptionCrypto {\n return this._config.crypto;\n }\n\n async discoverNetwork(\n identifier: string,\n ownerDid?: string,\n ): Promise<Result<NetworkDescriptor, EncryptionError>> {\n this.assertActive();\n const result = await discoverNetworkFn({\n identifier,\n ...(ownerDid !== undefined ? { ownerDid } : {}),\n ...(this._config.node !== undefined ? { node: this._config.node } : {}),\n ...(this._config.wellKnown !== undefined\n ? { wellKnown: this._config.wellKnown }\n : {}),\n });\n this.assertActive();\n if (!result.ok) return result;\n return encOk(result.data.descriptor);\n }\n\n async encryptToNetwork(\n networkId: string,\n plaintext: Uint8Array,\n options?: EncryptToNetworkOptions,\n ): Promise<Result<InlineEncryptedEnvelope, EncryptionError>> {\n try {\n this.assertActive();\n const discovered = await this.discoverNetwork(networkId);\n if (!discovered.ok) return discovered;\n const usable = ensureNetworkUsableForDecrypt(discovered.data);\n // For encryption we tolerate \"rotating\" but reject revoked/failed/pending —\n // ensureNetworkUsableForDecrypt enforces exactly that constraint.\n if (!usable.ok) return usable;\n\n const descriptor = usable.data;\n const networkPublicKey = base64Decode(descriptor.publicEncryptionKey);\n const result = encryptToNetworkFn(this.crypto, {\n // Discovery returns the node's canonical network identifier. Persist\n // that spelling in the envelope so a later response can be compared\n // byte-for-byte (notably for checksummed did:pkh principals).\n networkId: descriptor.networkId,\n networkPublicKey,\n plaintext,\n ...(options?.aad !== undefined ? { aad: options.aad } : {}),\n alg: options?.alg ?? descriptor.alg,\n keyVersion: options?.keyVersion ?? descriptor.keyVersion,\n ...(options?.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n return encOk(result.envelope);\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n }\n\n async decryptEnvelope(\n envelope: InlineEncryptedEnvelope,\n capabilityProof: DecryptCapabilityProof,\n options?: DecryptEnvelopeOptions,\n ): Promise<Result<Uint8Array, EncryptionError>> {\n try {\n this.assertActive();\n const validated = validateEnvelope(this.crypto, envelope);\n if (!validated.ok) return validated;\n if (\n options?.aad !== undefined &&\n validated.data.aad !== base64Encode(options.aad)\n ) {\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"decryptEnvelope aad does not match the envelope\",\n }),\n );\n }\n\n let descriptor: NetworkDescriptor;\n if (options?.descriptor !== undefined) {\n descriptor = options.descriptor;\n } else {\n const discovered = await this.discoverNetwork(envelope.networkId);\n if (!discovered.ok) return discovered;\n descriptor = discovered.data;\n }\n const usable = ensureNetworkUsableForDecrypt(descriptor);\n if (!usable.ok) return usable;\n\n const targetNode =\n options?.targetNode ?? descriptor.members[0]?.nodeId;\n if (targetNode === undefined) {\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"no target node available from descriptor\",\n }),\n );\n }\n\n // Generate per-request receiver key. We use the random mode by\n // default; callers wanting deterministic derivation must wrap\n // this service directly.\n const receiverKey = generateRandomReceiverKey({ crypto: this.crypto });\n const receiverPublicKey = base64Encode(receiverKey.publicKey);\n const receiverPublicKeyHash = canonicalHashHex(\n this.crypto.sha256,\n receiverPublicKey,\n );\n\n const body: DecryptRequestBody = {\n type: DECRYPT_FACT_TYPE,\n targetNode,\n networkId: envelope.networkId,\n alg: envelope.alg,\n keyVersion: envelope.keyVersion,\n encryptedSymmetricKey: envelope.encryptedSymmetricKey,\n encryptedSymmetricKeyHash: envelope.encryptedSymmetricKeyHash,\n receiverPublicKey,\n receiverPublicKeyHash,\n };\n const canonicalRequest = buildCanonicalDecryptRequest({\n crypto: this.crypto,\n body,\n receiverPublicKey: receiverKey.publicKey,\n });\n const facts = buildDecryptFacts({\n crypto: this.crypto,\n body,\n encryptedSymmetricKeyHash: envelope.encryptedSymmetricKeyHash,\n receiverPublicKey: receiverKey.publicKey,\n canonicalBody: canonicalRequest.canonicalBody,\n });\n\n const built = await buildDecryptInvocation(this.crypto, this._config.signer, {\n targetNode,\n networkId: envelope.networkId,\n body,\n facts,\n proof: capabilityProof,\n });\n this.assertActive();\n if (!built.ok) {\n if (built.error.code !== \"TRANSPORT_ERROR\") return built;\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"Unable to build decrypt request\",\n }),\n );\n }\n\n let response: DecryptResponseBody;\n try {\n response = await this._config.transport.postDecrypt({\n targetNode,\n networkId: envelope.networkId,\n authorization: built.data.authorization,\n canonicalBody: built.data.canonicalBody,\n signal: this.abortSignal,\n });\n this.assertActive();\n } catch (error) {\n if (error instanceof DecryptTransportResponseError) {\n return encErr(\n encryptionError(\n error.status === 401 || error.status === 403\n ? {\n code: \"DECRYPT_DENIED\",\n message: \"Node denied decrypt request\",\n ...(error.permissionHint === undefined\n ? {}\n : { permissionHint: error.permissionHint }),\n }\n : { code: \"INVALID_RESPONSE\", message: \"Node decrypt request failed\" },\n ),\n );\n }\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n\n const verified = verifyDecryptResponse({\n crypto: this.crypto,\n request: body,\n facts,\n invocationCid: built.data.invocationCid,\n requestBodyHash: facts.bodyHash,\n response,\n });\n if (!verified.ok) return verified;\n\n const symmetricKey = openWrappedKey(\n this.crypto,\n receiverKey.privateKey,\n verified.data,\n );\n const plaintext = decryptEnvelopeWithKey(\n this.crypto,\n envelope,\n symmetricKey,\n );\n return encOk(plaintext);\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"INVALID_RESPONSE\",\n message: \"Local decryption failed\",\n }),\n );\n }\n }\n\n private assertActive(): void {\n this._config.assertActive?.();\n }\n}\n","/**\n * TinyCloud encryption service exports.\n *\n * Reference architecture:\n * - Network ids: `urn:tinycloud:encryption:<ownerDid>:<network>`\n * - Inline envelopes: `{ v, networkId, alg, keyVersion,\n * encryptedSymmetricKey, encryptedSymmetricKeyHash, ciphertext, aad,\n * metadata }`\n * - Decrypt requests: UCAN-style invocations against a node + networkId.\n */\n\nexport {\n EncryptionService,\n} from \"./EncryptionService\";\n// The root and `/encryption` entrypoints both load this canonical CJS module.\n// That gives this public error normal class identity in CJS and ESM without a\n// mutable global registry or a forgeable structural marker.\nexport { DecryptTransportResponseError } from \"@tinycloud/sdk-services/internal/decrypt-transport-response-error\";\nexport type {\n DecryptTransport,\n EncryptionServiceConfig,\n} from \"./EncryptionService\";\nexport type {\n IEncryptionService,\n EncryptToNetworkOptions,\n DecryptEnvelopeOptions,\n} from \"./IEncryptionService\";\n\nexport {\n parseNetworkId,\n buildNetworkId,\n isNetworkId,\n networkDiscoveryKey,\n NetworkIdError,\n ENCRYPTION_NETWORK_URN_PREFIX,\n NETWORK_NAME_PATTERN,\n type ParsedNetworkId,\n} from \"./networkId\";\n\nexport {\n canonicalize,\n canonicalHashHex,\n hexEncode,\n hexDecode,\n base64Encode,\n base64Decode,\n utf8Encode,\n utf8Decode,\n type Json,\n} from \"./canonical\";\n\nexport {\n encryptToNetwork,\n decryptEnvelopeWithKey,\n validateEnvelope,\n type EncryptToNetworkInput,\n type EncryptToNetworkResult,\n} from \"./envelope\";\n\nexport {\n generateRandomReceiverKey,\n deriveSignedReceiverKey,\n type RandomReceiverKeyInput,\n type SignedReceiverKeyInput,\n} from \"./receiverKey\";\n\nexport {\n buildCanonicalDecryptRequest,\n buildDecryptFacts,\n buildDecryptAttenuation,\n buildDecryptInvocation,\n checkDecryptInvocationInput,\n DECRYPT_ACTION,\n ENCRYPTION_SERVICE,\n type CanonicalDecryptRequest,\n type BuildCanonicalDecryptRequestInput,\n type BuildDecryptFactsInput,\n} from \"./invocation\";\n\nexport {\n verifyDecryptResponse,\n canonicalSignedResponse,\n openWrappedKey,\n type VerifyDecryptResponseInput,\n} from \"./response\";\n\nexport {\n discoverNetwork,\n ensureNetworkUsableForDecrypt,\n type DiscoverNetworkInput,\n type DiscoveredNetwork,\n type DiscoverySource,\n type NodeDescriptorFetcher,\n type WellKnownDescriptorFetcher,\n} from \"./discovery\";\n\nexport {\n DEFAULT_ENCRYPTION_ALG,\n ENVELOPE_VERSION,\n DEFAULT_KEY_VERSION,\n DECRYPT_FACT_TYPE,\n DECRYPT_RESULT_TYPE,\n ENCRYPTION_SERVICE_SHORT,\n encryptionError,\n type BuildDecryptInvocationInput,\n type BuiltDecryptInvocation,\n type CanonicalJson,\n type DecryptCapabilityProof,\n type DecryptInvocationFact,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n type EncryptionErrorInput,\n type InlineEncryptedEnvelope,\n type NetworkDescriptor,\n type ReceiverKeyPair,\n type ReceiverKeySigner,\n} from \"./types\";\n"],"mappings":"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","names":["base64Decode","base64Encode","hexEncode","ok","serviceError","aligned","headers","errorText","import_bootstrap","import_bootstrap","valueDelResult","hexEncode","base64Encode","base64Decode","toError","err","crypto","base64Encode","err","base64Decode","hexEncode","crypto","err","crypto","hexEncode","base64Decode","import_decrypt_transport_response_error","identifier","base64Decode","toError","base64Encode","import_decrypt_transport_response_error"]}
|