{"version":3,"file":"transitionContext.mjs","names":[],"sources":["../../src/schemas/transitionContext.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport type { MinorModeCatalogSnapshot } from './mode.ts';\nimport { readDoomTransitionCoordinator, readMinorModeCatalogHost } from './transition.ts';\n\nconst MINOR_MODE_RELOAD_HANDOFF_SYMBOL = Symbol.for('@agimon-ai/doompi.minor-mode-reload-handoff.v1');\nconst MINOR_MODE_RELOAD_HANDOFF_TTL_MS = 60_000;\n\ninterface StoredMinorModeReloadHandoff {\n  readonly token: string;\n  readonly sessionId: string;\n  readonly transitionHostGeneration: string;\n  readonly operationId: string;\n  readonly catalogHostGeneration: string;\n  readonly snapshot: MinorModeCatalogSnapshot;\n  readonly expiresAt: number;\n}\n\ninterface MinorModeReloadHandoffRegistry {\n  readonly records: Map<string, StoredMinorModeReloadHandoff>;\n}\n\nexport interface MinorModeReloadHandoffHandle {\n  discard(): boolean;\n}\n\ninterface MinorModeReloadHandoffGlobal {\n  [MINOR_MODE_RELOAD_HANDOFF_SYMBOL]?: MinorModeReloadHandoffRegistry;\n}\n\nfunction reloadHandoffRegistry(): MinorModeReloadHandoffRegistry {\n  const globalRegistry = globalThis as MinorModeReloadHandoffGlobal;\n  const existing = globalRegistry[MINOR_MODE_RELOAD_HANDOFF_SYMBOL];\n  if (existing) return existing;\n  const created: MinorModeReloadHandoffRegistry = { records: new Map() };\n  globalRegistry[MINOR_MODE_RELOAD_HANDOFF_SYMBOL] = created;\n  return created;\n}\n\nfunction pruneExpiredReloadHandoffs(now = Date.now()): void {\n  for (const [sessionId, handoff] of reloadHandoffRegistry().records) {\n    if (handoff.expiresAt <= now) reloadHandoffRegistry().records.delete(sessionId);\n  }\n}\n\nexport function prepareMinorModeReloadHandoff(\n  context: Context,\n  sessionId: string,\n  transitionHostGeneration: string,\n  operationId: string,\n  snapshot: MinorModeCatalogSnapshot | undefined,\n): MinorModeReloadHandoffHandle | undefined {\n  if (!snapshot?.modes.some(({ state }) => state.activation === 'active' || state.activation === 'activating')) {\n    return undefined;\n  }\n  const coordinator = readDoomTransitionCoordinator(context);\n  const catalog = readMinorModeCatalogHost(context);\n  if (\n    !coordinator ||\n    coordinator.hostGeneration !== transitionHostGeneration ||\n    !catalog ||\n    catalog.generation !== snapshot.hostGeneration\n  ) {\n    throw new Error('Minor-mode reload handoff became stale before reload.');\n  }\n\n  pruneExpiredReloadHandoffs();\n  const token = `minor-mode-reload:${crypto.randomUUID()}`;\n  const record: StoredMinorModeReloadHandoff = {\n    token,\n    sessionId,\n    transitionHostGeneration,\n    operationId,\n    catalogHostGeneration: snapshot.hostGeneration,\n    snapshot: structuredClone(snapshot),\n    expiresAt: Date.now() + MINOR_MODE_RELOAD_HANDOFF_TTL_MS,\n  };\n  reloadHandoffRegistry().records.set(sessionId, record);\n\n  return {\n    discard() {\n      const current = reloadHandoffRegistry().records.get(sessionId);\n      if (current?.token !== token) return false;\n      return reloadHandoffRegistry().records.delete(sessionId);\n    },\n  };\n}\n\nexport function discardMinorModeReloadHandoff(sessionId: string): boolean {\n  pruneExpiredReloadHandoffs();\n  return reloadHandoffRegistry().records.delete(sessionId);\n}\n\nexport function consumeMinorModeReloadHandoff(sessionId: string): MinorModeCatalogSnapshot | undefined {\n  pruneExpiredReloadHandoffs();\n  const handoff = reloadHandoffRegistry().records.get(sessionId);\n  if (!handoff) return undefined;\n  reloadHandoffRegistry().records.delete(sessionId);\n  if (\n    handoff.sessionId !== sessionId ||\n    handoff.snapshot.hostGeneration !== handoff.catalogHostGeneration ||\n    !handoff.transitionHostGeneration ||\n    !handoff.operationId\n  ) {\n    return undefined;\n  }\n  return structuredClone(handoff.snapshot);\n}\n"],"mappings":"+FAIA,MAAM,EAAmC,OAAO,IAAI,gDAAgD,EAyBpG,SAAS,GAAwD,CAC/D,IAAM,EAAiB,WACjB,EAAW,EAAe,GAChC,GAAI,EAAU,OAAO,EACrB,IAAM,EAA0C,CAAE,QAAS,IAAI,GAAM,EAErE,MADA,GAAe,GAAoC,EAC5C,CACT,CAEA,SAAS,EAA2B,EAAM,KAAK,IAAI,EAAS,CAC1D,IAAK,GAAM,CAAC,EAAW,KAAY,EAAsB,CAAC,CAAC,QACrD,EAAQ,WAAa,GAAK,EAAsB,CAAC,CAAC,QAAQ,OAAO,CAAS,CAElF,CAEA,SAAgB,EACd,EACA,EACA,EACA,EACA,EAC0C,CAC1C,GAAI,CAAC,GAAU,MAAM,MAAM,CAAE,WAAY,EAAM,aAAe,UAAY,EAAM,aAAe,YAAY,EACzG,OAEF,IAAM,EAAc,EAA8B,CAAO,EACnD,EAAU,EAAyB,CAAO,EAChD,GACE,CAAC,GACD,EAAY,iBAAmB,GAC/B,CAAC,GACD,EAAQ,aAAe,EAAS,eAEhC,MAAU,MAAM,uDAAuD,EAGzE,EAA2B,EAC3B,IAAM,EAAQ,qBAAqB,OAAO,WAAW,IAC/C,EAAuC,CAC3C,QACA,YACA,2BACA,cACA,sBAAuB,EAAS,eAChC,SAAU,gBAAgB,CAAQ,EAClC,UAAW,KAAK,IAAI,EAAI,GAC1B,EAGA,OAFA,EAAsB,CAAC,CAAC,QAAQ,IAAI,EAAW,CAAM,EAE9C,CACL,SAAU,CAGR,OAFgB,EAAsB,CAAC,CAAC,QAAQ,IAAI,CAC1C,CAAC,EAAE,QAAU,GAChB,EAAsB,CAAC,CAAC,QAAQ,OAAO,CAAS,CACzD,CACF,CACF,CAEA,SAAgB,EAA8B,EAA4B,CAExE,OADA,EAA2B,EACpB,EAAsB,CAAC,CAAC,QAAQ,OAAO,CAAS,CACzD,CAEA,SAAgB,EAA8B,EAAyD,CACrG,EAA2B,EAC3B,IAAM,EAAU,EAAsB,CAAC,CAAC,QAAQ,IAAI,CAAS,EACxD,OACL,EAAsB,CAAC,CAAC,QAAQ,OAAO,CAAS,EAE9C,EAAQ,YAAc,GACtB,EAAQ,SAAS,iBAAmB,EAAQ,uBAC3C,EAAQ,0BACR,EAAQ,aAIX,OAAO,gBAAgB,EAAQ,QAAQ,CACzC"}