docs: document cron store helpers

This commit is contained in:
Peter Steinberger
2026-06-04 13:50:06 -04:00
parent 77f09f2575
commit d1bf769dbd
15 changed files with 21 additions and 0 deletions
+1
View File
@@ -1,3 +1,4 @@
/** Prunes expired per-run cron sessions and archives unreferenced transcripts. */
import { parseDurationMs } from "../cli/parse-duration.js";
import { loadSessionStore } from "../config/sessions/store-load.js";
import { archiveRemovedSessionTranscripts, updateSessionStore } from "../config/sessions/store.js";
+1
View File
@@ -1,3 +1,4 @@
/** Resolves and validates session-target keys used by cron jobs and delivery. */
const INVALID_CRON_SESSION_TARGET_ID_ERROR = "invalid cron sessionTarget session id";
/** Returns whether an error came from cron session target id validation. */
+1
View File
@@ -1,3 +1,4 @@
/** Resolves deterministic cron stagger windows for recurring schedules. */
import { parseStrictNonNegativeInteger } from "../infra/parse-finite-number.js";
import type { CronSchedule } from "./types.js";
+3
View File
@@ -1,3 +1,4 @@
/** Public cron store load/save API backed by SQLite plus quarantine sidecars. */
import fs from "node:fs";
import path from "node:path";
import { isRecord } from "@openclaw/normalization-core/record-coerce";
@@ -119,6 +120,8 @@ export async function saveCronJobsStore(
const resolvedStorePath = path.resolve(storePath);
const storeKey = cronStoreKey(resolvedStorePath);
if (opts?.stateOnly) {
// Hot-path timer updates only mutate runtime columns; full config JSON stays
// untouched so user-authored cron definitions do not churn.
runOpenClawStateWriteTransaction(({ db }) => {
updateCronRuntimeRows(db, storeKey, store);
});
+1
View File
@@ -1,3 +1,4 @@
/** SQLite column codec for cron delivery configuration. */
import type { CronDelivery } from "../types.js";
import { booleanToInteger, integerToBoolean } from "./scalar-codec.js";
import type { CronJobInsert, CronJobRow } from "./schema.js";
+1
View File
@@ -1,3 +1,4 @@
/** SQLite column codec for cron failure-alert configuration. */
import type { CronFailureAlert } from "../types.js";
import { booleanToInteger, integerToBoolean, normalizeNumber } from "./scalar-codec.js";
import type { CronJobInsert, CronJobRow } from "./schema.js";
+1
View File
@@ -1,3 +1,4 @@
/** Cron store key normalization for SQLite partitions. */
import path from "node:path";
/** Returns the canonical per-file SQLite partition key for cron store rows. */
+1
View File
@@ -1,3 +1,4 @@
/** SQLite column codec for cron payload variants. */
import type { CronPayload } from "../types.js";
import {
booleanToInteger,
+5
View File
@@ -1,3 +1,4 @@
/** Converts cron jobs between public store shape and normalized SQLite rows. */
import type { DatabaseSync } from "node:sqlite";
import { isRecord } from "@openclaw/normalization-core/record-coerce";
import { executeSqliteQuerySync } from "../../infra/kysely-sync.js";
@@ -61,6 +62,8 @@ function bindScheduleColumns(
function stripJobRuntimeFields(job: CronStoreFile["jobs"][number]): Record<string, unknown> {
const { state: _state, updatedAtMs: _updatedAtMs, ...rest } = job;
// job_json stores config shape only; runtime state lives in split columns and
// state_json so state-only writes never rewrite public job config.
return { ...rest, state: {} };
}
@@ -72,6 +75,8 @@ function mergeFailureDestinationProjection(
if (!failureDestination) {
return configJob;
}
// Empty SQLite sentinels preserve explicit undefined fields for failure
// destination overrides; project them back into the config sidecar shape.
const delivery: Record<string, unknown> =
isRecord(configJob.delivery) && !Array.isArray(configJob.delivery)
? { ...configJob.delivery }
+1
View File
@@ -1,3 +1,4 @@
/** Kysely row types and table facade for the cron_jobs SQLite table. */
import type { DatabaseSync } from "node:sqlite";
import type { Insertable, Selectable } from "kysely";
import { getNodeSqliteKysely } from "../../infra/kysely-sync.js";
+1
View File
@@ -1,3 +1,4 @@
/** SQLite column codec for mutable cron runtime state. */
import type { CronJobState } from "../types.js";
import {
booleanToInteger,
+1
View File
@@ -1,3 +1,4 @@
/** Shared cron store sidecar and quarantine types. */
import type { CronStoreFile } from "../types.js";
/** Invalid config-backed cron job captured for quarantine instead of runtime load. */
+1
View File
@@ -1,3 +1,4 @@
/** Cron scheduling, delivery, diagnostics, and store data contracts. */
import type { FailoverReason } from "../agents/embedded-agent-helpers/types.js";
import type { EmbeddedAgentExecutionPhase } from "../agents/embedded-agent-runner/execution-phase.js";
import type { ChannelId } from "../channels/plugins/types.public.js";
+1
View File
@@ -1,3 +1,4 @@
/** Validates user-supplied one-shot cron timestamps before scheduling. */
import {
asDateTimestampMs,
resolveTimestampMsToIsoString,
+1
View File
@@ -1,3 +1,4 @@
/** Normalizes cron webhook destination URLs. */
function isAllowedWebhookProtocol(protocol: string) {
return protocol === "http:" || protocol === "https:";
}