{"version":3,"sources":["../src/testing.ts"],"sourcesContent":["// Public testing utility — `@immediately-run/sdk/testing` (TESTING_AUTOMATION_SPEC\n// §3/§7). A mock host transport so apps built on this SDK can unit-test their host\n// interaction in CI, with no live bundler/host: drive the SDK's REAL transport path\n// by installing this at the §4 discovery global, then `emit()` host→app pushes and\n// assert your app reacts.\n//\n//   import { createMockHost } from '@immediately-run/sdk/testing';\n//   const host = createMockHost();\n//   host.install();                       // SDK now resolves this transport\n//   host.stubProtocol('spaces', 'list', () => ({ ok: true, data: [] }));\n//   // …render your app / call SDK functions…\n//   host.emit({ type: 'mount-add', mount: { path: '/spaces/a', type: 'firestore', id: 'a' } });\n//   expect(host.sent).toContainEqual({ type: 'request-mounts', data: {} });\n//   host.uninstall();\n//\n// It implements the `sandboxUtils` host transport (sendMessage / protocolRequest /\n// onMessage), so tests exercise the actual `transport()` resolution, the\n// `addListener` type-filter, and `protocolRequest` round-trips — higher fidelity\n// than mocking `./sandboxUtils` wholesale.\n\n/** A message pushed host → app, as it arrives on `onMessage`. */\nexport interface HostMessage {\n  type: string;\n  [k: string]: unknown;\n}\n\n/** An outbound `sendMessage` captured by the mock. */\nexport interface SentMessage {\n  type: string;\n  data: Record<string, unknown>;\n}\n\n/** An outbound `protocolRequest` captured by the mock. */\nexport interface ProtocolCall {\n  protocol: string;\n  method: string;\n  params: unknown[];\n}\n\n/** Responder stub for a `protocolRequest(protocol, method, …)`. */\nexport type ProtocolResponder = (params: unknown[]) => unknown;\n\n/** Extra §4 discovery-global fields to publish alongside `transport` on install. */\nexport interface MockHostGlobalExtras {\n  runtimeVersion?: string;\n  protocolVersion?: string;\n  appMountPath?: string;\n}\n\ninterface ImmediatelyRunGlobal extends MockHostGlobalExtras {\n  transport?: unknown;\n}\n\n/** The controllable mock host returned by {@link createMockHost}. */\nexport interface MockHost {\n  /** The §4 host transport object (also published on the global by `install`). */\n  transport: {\n    sendMessage(type: string, data?: Record<string, unknown>): void;\n    protocolRequest(protocol: string, method: string, params: unknown[]): Promise<unknown>;\n    onMessage(handler: (msg: HostMessage) => void): { dispose(): void };\n  };\n  /** Publish the transport at `globalThis.__immediatelyRun__` (npm-fetched path). */\n  install(extras?: MockHostGlobalExtras): void;\n  /** Remove the discovery global (call in `afterEach`). */\n  uninstall(): void;\n  /** Simulate a host → app push; delivered to every live `onMessage` handler. */\n  emit(msg: HostMessage): void;\n  /** Register a response for a `protocolRequest`; unstubbed calls reject. */\n  stubProtocol(protocol: string, method: string, responder: ProtocolResponder): void;\n  /** Every `sendMessage` the SDK made, in order. */\n  readonly sent: SentMessage[];\n  /** Every `protocolRequest` the SDK made, in order. */\n  readonly protocolCalls: ProtocolCall[];\n  /** Count of live `onMessage` listeners (leak checks). */\n  handlerCount(): number;\n}\n\nconst GLOBAL_KEY = '__immediatelyRun__';\n\n/** Build a controllable mock host. Nothing is global until you call `install()`. */\nexport function createMockHost(): MockHost {\n  const handlers = new Set<(msg: HostMessage) => void>();\n  const sent: SentMessage[] = [];\n  const protocolCalls: ProtocolCall[] = [];\n  const responders = new Map<string, ProtocolResponder>();\n  const key = (protocol: string, method: string) => `${protocol}::${method}`;\n\n  const transport: MockHost['transport'] = {\n    sendMessage(type, data = {}) {\n      sent.push({ type, data });\n    },\n    protocolRequest(protocol, method, params) {\n      protocolCalls.push({ protocol, method, params });\n      const responder = responders.get(key(protocol, method));\n      if (!responder) {\n        return Promise.reject(new Error(`mockHost: no stub for protocolRequest('${protocol}', '${method}')`));\n      }\n      // Resolve async so callers observe real microtask ordering.\n      return Promise.resolve().then(() => responder(params));\n    },\n    onMessage(handler) {\n      handlers.add(handler);\n      return { dispose: () => handlers.delete(handler) };\n    },\n  };\n\n  const g = globalThis as { [GLOBAL_KEY]?: ImmediatelyRunGlobal };\n\n  return {\n    transport,\n    install(extras = {}) {\n      g[GLOBAL_KEY] = { ...extras, transport };\n    },\n    uninstall() {\n      delete g[GLOBAL_KEY];\n    },\n    emit(msg) {\n      // Copy so a handler that unsubscribes mid-emit doesn't mutate the live set.\n      for (const handler of [...handlers]) handler(msg);\n    },\n    stubProtocol(protocol, method, responder) {\n      responders.set(key(protocol, method), responder);\n    },\n    sent,\n    protocolCalls,\n    handlerCount: () => handlers.size,\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6EA,MAAM,aAAa;AAGZ,SAAS,iBAA2B;AACzC,QAAM,WAAW,oBAAI,IAAgC;AACrD,QAAM,OAAsB,CAAC;AAC7B,QAAM,gBAAgC,CAAC;AACvC,QAAM,aAAa,oBAAI,IAA+B;AACtD,QAAM,MAAM,CAAC,UAAkB,WAAmB,GAAG,QAAQ,KAAK,MAAM;AAExE,QAAM,YAAmC;AAAA,IACvC,YAAY,MAAM,OAAO,CAAC,GAAG;AAC3B,WAAK,KAAK,EAAE,MAAM,KAAK,CAAC;AAAA,IAC1B;AAAA,IACA,gBAAgB,UAAU,QAAQ,QAAQ;AACxC,oBAAc,KAAK,EAAE,UAAU,QAAQ,OAAO,CAAC;AAC/C,YAAM,YAAY,WAAW,IAAI,IAAI,UAAU,MAAM,CAAC;AACtD,UAAI,CAAC,WAAW;AACd,eAAO,QAAQ,OAAO,IAAI,MAAM,0CAA0C,QAAQ,OAAO,MAAM,IAAI,CAAC;AAAA,MACtG;AAEA,aAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM,UAAU,MAAM,CAAC;AAAA,IACvD;AAAA,IACA,UAAU,SAAS;AACjB,eAAS,IAAI,OAAO;AACpB,aAAO,EAAE,SAAS,MAAM,SAAS,OAAO,OAAO,EAAE;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,IAAI;AAEV,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,SAAS,CAAC,GAAG;AACnB,QAAE,UAAU,IAAI,EAAE,GAAG,QAAQ,UAAU;AAAA,IACzC;AAAA,IACA,YAAY;AACV,aAAO,EAAE,UAAU;AAAA,IACrB;AAAA,IACA,KAAK,KAAK;AAER,iBAAW,WAAW,CAAC,GAAG,QAAQ,EAAG,SAAQ,GAAG;AAAA,IAClD;AAAA,IACA,aAAa,UAAU,QAAQ,WAAW;AACxC,iBAAW,IAAI,IAAI,UAAU,MAAM,GAAG,SAAS;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,MAAM,SAAS;AAAA,EAC/B;AACF;","names":[]}