{"version":3,"file":"signal.mjs","names":[],"sources":["../../src/extension/signal.ts"],"sourcesContent":["import { SignalError, signalExitCode } from '../core/errors.ts';\nimport { defineInterceptor } from '../core/interceptors.ts';\nimport { thenMaybe } from '../core/results.ts';\nimport type { PadroneSignal } from '../core/runtime.ts';\nimport type { AnyPadroneBuilder, CommandTypesBase } from '../types/index.ts';\n\n// ── Interceptor ─────────────────────────────────────────────────────────\n\nconst signalMeta = { id: 'padrone:signal', name: 'padrone:signal', order: -2000 } as const;\n\nconst signalInterceptor = defineInterceptor(signalMeta, () => {\n  const abortController = new AbortController();\n  let receivedSignal: PadroneSignal | undefined;\n  let lastSigintTime = 0;\n  let unsubscribe: (() => void) | undefined;\n  const DOUBLE_SIGINT_MS = 2000;\n\n  const cleanup = () => {\n    unsubscribe?.();\n    unsubscribe = undefined;\n  };\n\n  const attachSignalInfo = <T>(result: T): T => {\n    if (receivedSignal && result && typeof result === 'object') {\n      (result as any).signal = receivedSignal;\n      (result as any).exitCode = signalExitCode(receivedSignal);\n    }\n    return result;\n  };\n\n  return {\n    start(ctx, next) {\n      const runtimeExit = ctx.runtime.exit;\n      unsubscribe = ctx.runtime.onSignal?.((sig) => {\n        if (abortController.signal.aborted) {\n          if (sig === 'SIGINT') {\n            const elapsed = Date.now() - lastSigintTime;\n            if (elapsed > 0 && elapsed < DOUBLE_SIGINT_MS) {\n              runtimeExit?.(signalExitCode(sig));\n            }\n            lastSigintTime = Date.now();\n          }\n          return;\n        }\n        if (sig === 'SIGINT') lastSigintTime = Date.now();\n        receivedSignal = sig;\n        abortController.abort(sig);\n      });\n\n      const result = next({ signal: abortController.signal });\n      return thenMaybe(result, (r) => {\n        cleanup();\n        return attachSignalInfo(r);\n      });\n    },\n    error(_ctx, next) {\n      return thenMaybe(next(), (er) => {\n        if (receivedSignal && er.error instanceof Error) {\n          er.error = new SignalError(receivedSignal, { cause: er.error });\n        }\n        return er;\n      });\n    },\n    shutdown(_ctx, next) {\n      cleanup();\n      return next();\n    },\n  };\n});\n\n// ── Extension ───────────────────────────────────────────────────────────\n\n/**\n * Extension that wires process signal handling (SIGINT, SIGTERM, SIGHUP) into the interceptor lifecycle.\n *\n * - Creates an `AbortController` whose signal is propagated to all downstream phases.\n * - Subscribes to `runtime.onSignal` to forward OS signals to the abort controller.\n * - Implements SIGINT double-tap: two SIGINTs within 2 seconds force-exits the process.\n * - Attaches `signal` and `exitCode` to results and errors when interrupted.\n * - Cleans up the signal subscription on completion or failure.\n *\n * Included in the default extensions. Runs at order `-2000` (outermost).\n */\nexport function padroneSignalHandling(options?: { disabled?: boolean }): <T extends CommandTypesBase>(builder: T) => T {\n  const interceptor = options?.disabled ? defineInterceptor({ ...signalMeta, disabled: true }, () => ({})) : signalInterceptor;\n  return ((builder: AnyPadroneBuilder) => builder.intercept(interceptor)) as any;\n}\n"],"mappings":";;;;AAQA,MAAM,aAAa;CAAE,IAAI;CAAkB,MAAM;CAAkB,OAAO;AAAM;AAEhF,MAAM,oBAAoB,kBAAkB,kBAAkB;CAC5D,MAAM,kBAAkB,IAAI,gBAAgB;CAC5C,IAAI;CACJ,IAAI,iBAAiB;CACrB,IAAI;CACJ,MAAM,mBAAmB;CAEzB,MAAM,gBAAgB;EACpB,cAAc;EACd,cAAc,KAAA;CAChB;CAEA,MAAM,oBAAuB,WAAiB;EAC5C,IAAI,kBAAkB,UAAU,OAAO,WAAW,UAAU;GAC1D,OAAgB,SAAS;GACzB,OAAgB,WAAW,eAAe,cAAc;EAC1D;EACA,OAAO;CACT;CAEA,OAAO;EACL,MAAM,KAAK,MAAM;GACf,MAAM,cAAc,IAAI,QAAQ;GAChC,cAAc,IAAI,QAAQ,YAAY,QAAQ;IAC5C,IAAI,gBAAgB,OAAO,SAAS;KAClC,IAAI,QAAQ,UAAU;MACpB,MAAM,UAAU,KAAK,IAAI,IAAI;MAC7B,IAAI,UAAU,KAAK,UAAU,kBAC3B,cAAc,eAAe,GAAG,CAAC;MAEnC,iBAAiB,KAAK,IAAI;KAC5B;KACA;IACF;IACA,IAAI,QAAQ,UAAU,iBAAiB,KAAK,IAAI;IAChD,iBAAiB;IACjB,gBAAgB,MAAM,GAAG;GAC3B,CAAC;GAGD,OAAO,UADQ,KAAK,EAAE,QAAQ,gBAAgB,OAAO,CAC/B,IAAI,MAAM;IAC9B,QAAQ;IACR,OAAO,iBAAiB,CAAC;GAC3B,CAAC;EACH;EACA,MAAM,MAAM,MAAM;GAChB,OAAO,UAAU,KAAK,IAAI,OAAO;IAC/B,IAAI,kBAAkB,GAAG,iBAAiB,OACxC,GAAG,QAAQ,IAAI,YAAY,gBAAgB,EAAE,OAAO,GAAG,MAAM,CAAC;IAEhE,OAAO;GACT,CAAC;EACH;EACA,SAAS,MAAM,MAAM;GACnB,QAAQ;GACR,OAAO,KAAK;EACd;CACF;AACF,CAAC;;;;;;;;;;;;AAeD,SAAgB,sBAAsB,SAAiF;CACrH,MAAM,cAAc,SAAS,WAAW,kBAAkB;EAAE,GAAG;EAAY,UAAU;CAAK,UAAU,CAAC,EAAE,IAAI;CAC3G,SAAS,YAA+B,QAAQ,UAAU,WAAW;AACvE"}