/** * Boot-time persisted-schedule loader. * * Extracted from server.ts so the logic can be imported by tests * without triggering the daemon's bootstrap IIFE. The loader handles * BOTH on-disk formats: * * - IPC (`source: 'ipc'`): written by `photon ps enable` and similar * CLI hooks. Carries `photonName`, `args`, and `workingDir` on the * task itself. TTL-swept after 30 days of inactivity. * - ScheduleProvider: written by `this.schedule.create()` at runtime * from photon code. Carries `params` (mapped to args) and `status`. * The photon name is inferred from the directory path and passed * in as `photonNameHint`. NOT TTL-swept — lifecycle is owned by * the photon that created it. * * Before this unification, the boot scanner only handled IPC and every * ScheduleProvider file was silently skipped (`source !== 'ipc'`). That * caused schedules to stay dormant across daemon restarts until the * owning photon happened to be invoked and triggered the lazy * `autoRegisterFromMetadata` path. */ export interface PersistedScheduleJob { id: string; method: string; args: Record; cron: string; requiredConfig?: string[]; runCount: number; createdAt: number; createdBy: string; photonName: string; workingDir?: string; photonPath?: string; /** * Absolute path of the backing JSON file this job was loaded from. * The fire handler uses it to drop phantom registrations whose * backing file has been unlinked (e.g. via * `this.schedule.cancel()`) out from under the in-memory cron map. */ sourceFile?: string; /** * Epoch-ms of the last successful execution, read from the persisted * `lastExecutionAt` field. Used by the daemon boot path to detect fire * windows that elapsed while the daemon was down and schedule one * catch-up run for the most recent missed occurrence. */ lastRun?: number; lastAttempt?: number; lastStatus?: 'success' | 'error'; lastError?: string; consecutiveFailures?: number; } export interface LoadScheduleCallbacks { /** Called for every valid job. Return `true` if the engine accepted it. */ register: (job: PersistedScheduleJob) => boolean; /** True if the given job id is already known to the cron engine. */ alreadyRegistered: (jobId: string) => boolean; /** Optional logger hooks — no-op by default. */ warn?: (msg: string, ctx?: Record) => void; info?: (msg: string, ctx?: Record) => void; } /** * Scan one directory of schedule JSON files and hand every valid job * to `cb.register`. Returns counts of loaded + skipped for logging. * * @param schedulesPath Directory containing {taskId}.json files. * @param ttlMs Age in ms above which untouched IPC jobs are deleted. * ScheduleProvider jobs ignore TTL (photon owns them). * @param photonNameHint Used when task doesn't carry its own * `photonName` (ScheduleProvider case — photon * name is the parent directory's basename). * @param workingDirHint Fallback working dir when task lacks one * (the base dir that owns this schedule tree). * @param cb Engine hooks. */ export declare function loadPersistedSchedulesFromDir(schedulesPath: string, ttlMs: number, photonNameHint: string | null, workingDirHint: string | undefined, cb: LoadScheduleCallbacks): { loaded: number; skipped: number; }; //# sourceMappingURL=schedule-loader.d.ts.map