/** * Structural surface @shade/files needs from a Shade instance. * * Defining this locally — instead of `import type { Shade } from '@shade/sdk'` * — breaks the @shade/sdk ↔ @shade/files dependency cycle. Without this * break, a consumer that installs @shade/sdk from a registry ends up with * two distinct `Shade` classes in `node_modules` (one from * `@shade/sdk/node_modules/@shade/files/.../Shade`, one from * `@shade/sdk/Shade`). TypeScript treats them as nominally different types, * raising `this is not assignable to Shade` from inside SDK methods that * pass `this` into `createFilesNamespace`. * * The Shade class structurally implements every member listed below, so * `createFilesNamespace(this)` from the SDK side compiles regardless of * how many copies of @shade/sdk a consumer's package manager installs. * * Member signatures match Shade's exactly so this is a structural * subtype, not a parallel API. */ import type { ShadeEnvelope } from '@shade/core'; import type { IncomingTransfer, TransferHandle, TransferOptions, } from '@shade/transfer'; import type { ObservabilityHook } from '@shade/observability'; export interface ShadeBridge { /** Address that names this Shade instance to peers. */ readonly myAddress: string; /** Encrypt + send `plaintext` to `peer`; returns the wire envelope. */ send(peer: string, plaintext: string): Promise; /** * Decrypt an inbound envelope from `peer` and return the plaintext. * Used by the request-response RPC route on the server side. */ receive(peer: string, envelope: ShadeEnvelope): Promise; /** * Subscribe to incoming ratchet plaintext. Returns an unsubscribe. * Handlers may be sync or async; async handlers are awaited in * registration order. */ onMessage( handler: (from: string, plaintext: string) => void | Promise, ): () => void; /** * Upload bytes via the SDK's transfer engine. Required when the bridge * is used with `streams` content I/O (read/write > 256 KiB). */ upload(opts: TransferOptions): Promise; /** Subscribe to incoming transfers initiated by a peer. */ onIncomingTransfer( handler: (incoming: IncomingTransfer) => void | Promise, ): Promise<() => void>; /** Fingerprint accessor for the trust-gate hooks. */ getFingerprintFor(peer: string): Promise; /** * Optional inheritable observability bus. Files inherits the bus when * the SDK passes one in via the namespace; otherwise files runs without * observability hooks. */ getObservability?(): ObservabilityHook | undefined; /** Optional control-envelope passthrough used by the WebRTC bridge. */ deliverControlEnvelope?(peer: string, envelope: ShadeEnvelope): Promise; }