alepha 0.20.5 → 0.20.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/audits/index.d.ts +391 -359
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +23 -1
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +18 -0
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +51 -0
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.browser.js +33 -14
- package/dist/api/jobs/index.browser.js.map +1 -1
- package/dist/api/jobs/index.d.ts +452 -155
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +474 -159
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +28 -0
- package/dist/api/keys/index.d.ts.map +1 -1
- package/dist/api/keys/index.js +53 -0
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.d.ts +29 -1
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +55 -13
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/organizations/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +17 -2
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +37 -0
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.js.map +1 -1
- package/dist/api/users/index.d.ts +168 -27
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +237 -28
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +3 -3
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts +18 -0
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +47 -0
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +24 -0
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.d.ts +20 -3
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/cache/database/index.d.ts +155 -0
- package/dist/cache/database/index.d.ts.map +1 -0
- package/dist/cache/database/index.js +266 -0
- package/dist/cache/database/index.js.map +1 -0
- package/dist/cache/redis/index.js.map +1 -1
- package/dist/captcha/index.js.map +1 -1
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +34 -4
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +85 -6
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/platform/index.js +1 -1
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/command/index.d.ts +1 -1
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.browser.js.map +1 -1
- package/dist/crypto/index.js.map +1 -1
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/brevo/index.js.map +1 -1
- package/dist/email/core/index.js.map +1 -1
- package/dist/email/core/index.workerd.js.map +1 -1
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.js.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/queue/core/index.js.map +1 -1
- package/dist/queue/core/index.workerd.js.map +1 -1
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/react/auth/index.browser.js.map +1 -1
- package/dist/react/auth/index.js.map +1 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.js +2 -0
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/head/index.browser.js.map +1 -1
- package/dist/react/head/index.js.map +1 -1
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.js.map +1 -1
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.js.map +1 -1
- package/dist/react/websocket/index.js.map +1 -1
- package/dist/redis/index.bun.js.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.js.map +1 -1
- package/dist/router/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +22 -0
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +12 -0
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +12 -0
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.browser.js.map +1 -1
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.js.map +1 -1
- package/dist/server/etag/index.js.map +1 -1
- package/dist/server/health/index.js.map +1 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.browser.js.map +1 -1
- package/dist/system/index.js.map +1 -1
- package/dist/system/index.workerd.js.map +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/topic/redis/index.js.map +1 -1
- package/dist/websocket/index.browser.js +4 -0
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.js +10 -0
- package/dist/websocket/index.js.map +1 -1
- package/package.json +19 -9
- package/src/api/audits/controllers/AdminAuditController.ts +29 -0
- package/src/api/files/controllers/FileController.ts +24 -0
- package/src/api/files/services/FileService.ts +41 -0
- package/src/api/jobs/__tests__/$job.spec.ts +427 -2
- package/src/api/jobs/entities/jobExecutionEntity.ts +3 -3
- package/src/api/jobs/index.ts +47 -10
- package/src/api/jobs/primitives/$job.ts +22 -9
- package/src/api/jobs/providers/DirectJobDispatcher.ts +71 -0
- package/src/api/jobs/providers/JobDispatcher.ts +49 -0
- package/src/api/jobs/providers/JobProvider.ts +365 -142
- package/src/api/jobs/providers/JobQueueProvider.ts +43 -18
- package/src/api/jobs/schemas/jobConfigAtom.ts +4 -3
- package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +11 -0
- package/src/api/jobs/schemas/jobRegistrationSchema.ts +4 -2
- package/src/api/jobs/services/JobService.ts +21 -11
- package/src/api/keys/controllers/AdminApiKeyController.ts +23 -0
- package/src/api/keys/services/ApiKeyService.ts +42 -0
- package/src/api/notifications/__tests__/AlephaApiNotifications.spec.ts +63 -0
- package/src/api/notifications/controllers/AdminNotificationController.ts +48 -1
- package/src/api/notifications/index.ts +13 -3
- package/src/api/notifications/jobs/NotificationJobs.ts +0 -6
- package/src/api/parameters/controllers/AdminParameterController.ts +26 -0
- package/src/api/parameters/services/ParameterProvider.ts +18 -0
- package/src/api/users/__tests__/Registration-emailMode.spec.ts +203 -0
- package/src/api/users/__tests__/UsernameSlugger.spec.ts +138 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +41 -3
- package/src/api/users/controllers/AdminSessionController.ts +29 -0
- package/src/api/users/controllers/AdminUserController.ts +32 -0
- package/src/api/users/index.ts +3 -0
- package/src/api/users/services/CredentialService.ts +5 -0
- package/src/api/users/services/RegistrationService.ts +49 -1
- package/src/api/users/services/SessionCrudService.ts +16 -0
- package/src/api/users/services/SessionService.ts +17 -59
- package/src/api/users/services/UsernameSlugger.ts +195 -0
- package/src/bucket/primitives/$bucket.ts +21 -0
- package/src/bucket/providers/CloudflareR2Provider.ts +15 -0
- package/src/bucket/providers/FileStorageProvider.ts +9 -0
- package/src/bucket/providers/LocalFileStorageProvider.ts +14 -0
- package/src/bucket/providers/MemoryFileStorageProvider.ts +9 -0
- package/src/bucket/providers/NodeS3BucketProvider.ts +35 -0
- package/src/cache/core/primitives/$cache.ts +20 -3
- package/src/cache/database/__tests__/DatabaseCacheProvider.behavior.spec.ts +203 -0
- package/src/cache/database/__tests__/DatabaseCacheProvider.spec.ts +110 -0
- package/src/cache/database/entities/cacheEntries.ts +55 -0
- package/src/cache/database/index.ts +36 -0
- package/src/cache/database/providers/DatabaseCacheProvider.ts +348 -0
- package/src/cli/core/services/ProjectScaffolder.ts +0 -2
- package/src/cli/core/tasks/BuildCloudflareTask.ts +17 -3
- package/src/cli/core/tasks/BuildSitemapTask.ts +7 -0
- package/src/cli/core/tasks/BuildVercelTask.ts +82 -3
- package/src/cli/platform/__tests__/detectResources.spec.ts +96 -0
- package/src/cli/platform/commands/platform.ts +7 -1
- package/src/scheduler/index.ts +14 -0
- package/src/scheduler/providers/CronProvider.ts +13 -0
|
@@ -10,11 +10,11 @@ import { $entity, db } from "alepha/orm";
|
|
|
10
10
|
* the last N rows per job (configurable via `jobConfig.keepLastSuccess`).
|
|
11
11
|
*
|
|
12
12
|
* Status transitions:
|
|
13
|
-
* - queue push → pending
|
|
13
|
+
* - queue push → pending (or `scheduled` if `delay`/`scheduledAt` was given)
|
|
14
14
|
* - worker claim → running
|
|
15
|
-
* - success → ok
|
|
15
|
+
* - success → ok (or row deleted, depending on `record` and `keepLastSuccess`)
|
|
16
16
|
* - terminal failure → error
|
|
17
|
-
* -
|
|
17
|
+
* - retryable failure → scheduled (with scheduledAt = now; sweep picks it up)
|
|
18
18
|
* - delay → scheduled (with scheduledAt = now + delay)
|
|
19
19
|
* - sweep picks due ones → pending
|
|
20
20
|
* - cancel → cancelled
|
|
@@ -71,7 +71,7 @@ const jobConfig = $atom({
|
|
|
71
71
|
name: "alepha.jobs",
|
|
72
72
|
description: "Configuration for the $job primitive.",
|
|
73
73
|
schema: t.object({
|
|
74
|
-
|
|
74
|
+
sweepCron: t.text({ description: "Cron expression for the sweep tick. Must be minute-granular at minimum (cron resolution). On Cloudflare Workers this expression is emitted into wrangler.jsonc by the build." }),
|
|
75
75
|
staleThreshold: t.integer({ description: "Pending age (ms) before the sweep re-dispatches it." }),
|
|
76
76
|
runTimeout: t.integer({ description: "Running age (ms) before assumed crash (fallback when no per-job timeout)." }),
|
|
77
77
|
keepLastSuccess: t.integer({ description: "Max successful rows to keep per job. Set 0 to disable and delete on success." }),
|
|
@@ -80,7 +80,7 @@ const jobConfig = $atom({
|
|
|
80
80
|
drainTimeout: t.integer({ description: "Max time (ms) to wait for in-flight jobs during shutdown." })
|
|
81
81
|
}),
|
|
82
82
|
default: {
|
|
83
|
-
|
|
83
|
+
sweepCron: "*/5 * * * *",
|
|
84
84
|
staleThreshold: 3e5,
|
|
85
85
|
runTimeout: 18e5,
|
|
86
86
|
keepLastSuccess: 10,
|
|
@@ -108,10 +108,28 @@ const jobExecutionQuerySchema = t.object({
|
|
|
108
108
|
});
|
|
109
109
|
//#endregion
|
|
110
110
|
//#region ../../src/api/jobs/schemas/jobExecutionResourceSchema.ts
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Public-facing schema for a job execution row.
|
|
113
|
+
*
|
|
114
|
+
* Diverges from the raw entity in two places, both for API ergonomics:
|
|
115
|
+
*
|
|
116
|
+
* - `priority` is exposed as the **string enum** (`critical`/`high`/...)
|
|
117
|
+
* instead of the numeric value used internally for SQL ordering. The
|
|
118
|
+
* `JobService` is responsible for the int → string transform.
|
|
119
|
+
* - `can` derives the available admin actions from the row's status.
|
|
120
|
+
*/
|
|
121
|
+
const jobExecutionResourceSchema = t.extend(jobExecutionEntity.schema, {
|
|
122
|
+
priority: t.enum([
|
|
123
|
+
"critical",
|
|
124
|
+
"high",
|
|
125
|
+
"normal",
|
|
126
|
+
"low"
|
|
127
|
+
]),
|
|
128
|
+
can: t.object({
|
|
129
|
+
retry: t.boolean(),
|
|
130
|
+
cancel: t.boolean()
|
|
131
|
+
})
|
|
132
|
+
}, {
|
|
115
133
|
title: "JobExecutionResource",
|
|
116
134
|
description: "A job execution row with derived actions."
|
|
117
135
|
});
|
|
@@ -120,7 +138,11 @@ const jobExecutionResourceSchema = t.extend(jobExecutionEntity.schema, { can: t.
|
|
|
120
138
|
const jobRegistrationSchema = t.object({
|
|
121
139
|
name: t.text(),
|
|
122
140
|
description: t.optional(t.text()),
|
|
123
|
-
type: t.enum([
|
|
141
|
+
type: t.enum([
|
|
142
|
+
"cron",
|
|
143
|
+
"queue",
|
|
144
|
+
"direct"
|
|
145
|
+
], { description: "Effective runtime mode. 'cron' = scheduled. 'queue' = push-driven, dispatched via AlephaApiJobsQueue. 'direct' = push-driven, processed in-process (no queue infrastructure loaded), with the sweep as the safety net." }),
|
|
124
146
|
priority: t.enum([
|
|
125
147
|
"critical",
|
|
126
148
|
"high",
|
|
@@ -129,10 +151,7 @@ const jobRegistrationSchema = t.object({
|
|
|
129
151
|
]),
|
|
130
152
|
cron: t.optional(t.text()),
|
|
131
153
|
timeout: t.optional(t.text()),
|
|
132
|
-
retry: t.optional(t.object({
|
|
133
|
-
retries: t.integer(),
|
|
134
|
-
hasBackoff: t.boolean()
|
|
135
|
-
})),
|
|
154
|
+
retry: t.optional(t.object({ retries: t.integer() })),
|
|
136
155
|
recent: t.object({
|
|
137
156
|
ok: t.integer(),
|
|
138
157
|
error: t.integer(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/api/jobs/entities/jobExecutionEntity.ts","../../../src/api/jobs/schemas/jobConfigAtom.ts","../../../src/api/jobs/schemas/jobExecutionQuerySchema.ts","../../../src/api/jobs/schemas/jobExecutionResourceSchema.ts","../../../src/api/jobs/schemas/jobRegistrationSchema.ts","../../../src/api/jobs/schemas/triggerJobSchema.ts","../../../src/api/jobs/index.browser.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { $entity, db } from \"alepha/orm\";\n\n/**\n * Job execution record.\n *\n * Stores durable state for queue-mode jobs (outbox pattern) and error records\n * for cron-mode jobs. Successful executions are trimmed by the sweep to keep\n * the last N rows per job (configurable via `jobConfig.keepLastSuccess`).\n *\n * Status transitions:\n * - queue push → pending\n * - worker claim → running\n * - success → ok\n * - terminal failure → error\n * - retry → scheduled (with scheduledAt = now + backoff)\n * - delay → scheduled (with scheduledAt = now + delay)\n * - sweep picks due ones → pending\n * - cancel → cancelled\n */\nexport const jobExecutionEntity = $entity({\n name: \"job_executions\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n createdAt: db.createdAt(),\n updatedAt: db.updatedAt(),\n\n jobName: t.text(),\n key: t.optional(t.nullable(t.text())),\n\n status: db.default(\n t.enum([\"pending\", \"running\", \"scheduled\", \"ok\", \"error\", \"cancelled\"]),\n \"pending\",\n ),\n priority: db.default(t.integer({ minimum: 0, maximum: 3 }), 2),\n\n attempt: db.default(t.integer(), 0),\n maxAttempts: db.default(t.integer(), 1),\n\n payload: t.optional(t.record(t.text(), t.any())),\n\n scheduledAt: t.optional(t.datetime()),\n startedAt: t.optional(t.datetime()),\n completedAt: t.optional(t.datetime()),\n\n error: t.optional(t.text()),\n logs: t.optional(t.array(logEntrySchema)),\n\n triggeredBy: t.optional(t.text()),\n triggeredByName: t.optional(t.text()),\n cancelledBy: t.optional(t.text()),\n cancelledByName: t.optional(t.text()),\n }),\n indexes: [\n { columns: [\"jobName\", \"status\", \"scheduledAt\"] },\n { columns: [\"jobName\", \"startedAt\"] },\n { columns: [\"jobName\", \"key\"], unique: true },\n ],\n});\n\nexport type JobExecutionEntity = Static<typeof jobExecutionEntity.schema>;\n\nexport type JobStatus =\n | \"pending\"\n | \"running\"\n | \"scheduled\"\n | \"ok\"\n | \"error\"\n | \"cancelled\";\n","import { $atom, type Static, t } from \"alepha\";\n\nexport const jobConfig = $atom({\n name: \"alepha.jobs\",\n description: \"Configuration for the $job primitive.\",\n schema: t.object({\n sweepInterval: t.integer({\n description: \"Sweep cron interval in milliseconds.\",\n }),\n staleThreshold: t.integer({\n description: \"Pending age (ms) before the sweep re-dispatches it.\",\n }),\n runTimeout: t.integer({\n description:\n \"Running age (ms) before assumed crash (fallback when no per-job timeout).\",\n }),\n keepLastSuccess: t.integer({\n description:\n \"Max successful rows to keep per job. Set 0 to disable and delete on success.\",\n }),\n keepLastError: t.integer({\n description: \"Max error rows to keep per job.\",\n }),\n logMaxEntries: t.integer({\n description: \"Max log entries captured per execution.\",\n }),\n drainTimeout: t.integer({\n description: \"Max time (ms) to wait for in-flight jobs during shutdown.\",\n }),\n }),\n default: {\n sweepInterval: 300_000,\n staleThreshold: 300_000,\n runTimeout: 1_800_000,\n keepLastSuccess: 10,\n keepLastError: 10,\n logMaxEntries: 100,\n drainTimeout: 30_000,\n },\n});\n\nexport type JobConfig = Static<typeof jobConfig.schema>;\n\ndeclare module \"alepha\" {\n interface State {\n [jobConfig.key]: JobConfig;\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const jobExecutionQuerySchema = t.object({\n status: t.optional(\n t.enum([\"pending\", \"running\", \"scheduled\", \"ok\", \"error\", \"cancelled\"]),\n ),\n limit: t.optional(t.integer({ minimum: 1, maximum: 200, default: 20 })),\n});\n\nexport type JobExecutionQuery = Static<typeof jobExecutionQuerySchema>;\n","import { type Static, t } from \"alepha\";\nimport { jobExecutionEntity } from \"../entities/jobExecutionEntity.ts\";\n\nexport const jobExecutionResourceSchema = t.extend(\n jobExecutionEntity.schema,\n {\n can: t.object({\n retry: t.boolean(),\n cancel: t.boolean(),\n }),\n },\n {\n title: \"JobExecutionResource\",\n description: \"A job execution row with derived actions.\",\n },\n);\n\nexport type JobExecutionResource = Static<typeof jobExecutionResourceSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobRegistrationSchema = t.object({\n name: t.text(),\n description: t.optional(t.text()),\n type: t.enum([\"cron\", \"queue\"]),\n priority: t.enum([\"critical\", \"high\", \"normal\", \"low\"]),\n cron: t.optional(t.text()),\n timeout: t.optional(t.text()),\n retry: t.optional(\n t.object({\n retries: t.integer(),\n hasBackoff: t.boolean(),\n }),\n ),\n recent: t.object({\n ok: t.integer(),\n error: t.integer(),\n lastRun: t.optional(t.datetime()),\n }),\n});\n\nexport type JobRegistration = Static<typeof jobRegistrationSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const triggerJobSchema = t.object({\n payload: t.optional(t.record(t.text(), t.any())),\n});\n\nexport type TriggerJob = Static<typeof triggerJobSchema>;\n","import { $module } from \"alepha\";\n\n// -----------------------------------------------------------------------------------------------------------------\n\nexport * from \"./entities/jobExecutionEntity.ts\";\nexport * from \"./schemas/jobConfigAtom.ts\";\nexport * from \"./schemas/jobExecutionQuerySchema.ts\";\nexport * from \"./schemas/jobExecutionResourceSchema.ts\";\nexport * from \"./schemas/jobRegistrationSchema.ts\";\nexport * from \"./schemas/triggerJobSchema.ts\";\n\n// -----------------------------------------------------------------------------------------------------------------\n\nexport const AlephaApiJobs = $module({\n name: \"alepha.api.jobs\",\n services: [],\n});\n\nexport const AlephaApiJobsQueue = $module({\n name: \"alepha.api.jobs.queue\",\n services: [],\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/api/jobs/entities/jobExecutionEntity.ts","../../../src/api/jobs/schemas/jobConfigAtom.ts","../../../src/api/jobs/schemas/jobExecutionQuerySchema.ts","../../../src/api/jobs/schemas/jobExecutionResourceSchema.ts","../../../src/api/jobs/schemas/jobRegistrationSchema.ts","../../../src/api/jobs/schemas/triggerJobSchema.ts","../../../src/api/jobs/index.browser.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { $entity, db } from \"alepha/orm\";\n\n/**\n * Job execution record.\n *\n * Stores durable state for queue-mode jobs (outbox pattern) and error records\n * for cron-mode jobs. Successful executions are trimmed by the sweep to keep\n * the last N rows per job (configurable via `jobConfig.keepLastSuccess`).\n *\n * Status transitions:\n * - queue push → pending (or `scheduled` if `delay`/`scheduledAt` was given)\n * - worker claim → running\n * - success → ok (or row deleted, depending on `record` and `keepLastSuccess`)\n * - terminal failure → error\n * - retryable failure → scheduled (with scheduledAt = now; sweep picks it up)\n * - delay → scheduled (with scheduledAt = now + delay)\n * - sweep picks due ones → pending\n * - cancel → cancelled\n */\nexport const jobExecutionEntity = $entity({\n name: \"job_executions\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n createdAt: db.createdAt(),\n updatedAt: db.updatedAt(),\n\n jobName: t.text(),\n key: t.optional(t.nullable(t.text())),\n\n status: db.default(\n t.enum([\"pending\", \"running\", \"scheduled\", \"ok\", \"error\", \"cancelled\"]),\n \"pending\",\n ),\n priority: db.default(t.integer({ minimum: 0, maximum: 3 }), 2),\n\n attempt: db.default(t.integer(), 0),\n maxAttempts: db.default(t.integer(), 1),\n\n payload: t.optional(t.record(t.text(), t.any())),\n\n scheduledAt: t.optional(t.datetime()),\n startedAt: t.optional(t.datetime()),\n completedAt: t.optional(t.datetime()),\n\n error: t.optional(t.text()),\n logs: t.optional(t.array(logEntrySchema)),\n\n triggeredBy: t.optional(t.text()),\n triggeredByName: t.optional(t.text()),\n cancelledBy: t.optional(t.text()),\n cancelledByName: t.optional(t.text()),\n }),\n indexes: [\n { columns: [\"jobName\", \"status\", \"scheduledAt\"] },\n { columns: [\"jobName\", \"startedAt\"] },\n { columns: [\"jobName\", \"key\"], unique: true },\n ],\n});\n\nexport type JobExecutionEntity = Static<typeof jobExecutionEntity.schema>;\n\nexport type JobStatus =\n | \"pending\"\n | \"running\"\n | \"scheduled\"\n | \"ok\"\n | \"error\"\n | \"cancelled\";\n","import { $atom, type Static, t } from \"alepha\";\n\nexport const jobConfig = $atom({\n name: \"alepha.jobs\",\n description: \"Configuration for the $job primitive.\",\n schema: t.object({\n sweepCron: t.text({\n description:\n \"Cron expression for the sweep tick. Must be minute-granular at minimum (cron resolution). On Cloudflare Workers this expression is emitted into wrangler.jsonc by the build.\",\n }),\n staleThreshold: t.integer({\n description: \"Pending age (ms) before the sweep re-dispatches it.\",\n }),\n runTimeout: t.integer({\n description:\n \"Running age (ms) before assumed crash (fallback when no per-job timeout).\",\n }),\n keepLastSuccess: t.integer({\n description:\n \"Max successful rows to keep per job. Set 0 to disable and delete on success.\",\n }),\n keepLastError: t.integer({\n description: \"Max error rows to keep per job.\",\n }),\n logMaxEntries: t.integer({\n description: \"Max log entries captured per execution.\",\n }),\n drainTimeout: t.integer({\n description: \"Max time (ms) to wait for in-flight jobs during shutdown.\",\n }),\n }),\n default: {\n sweepCron: \"*/5 * * * *\",\n staleThreshold: 300_000,\n runTimeout: 1_800_000,\n keepLastSuccess: 10,\n keepLastError: 10,\n logMaxEntries: 100,\n drainTimeout: 30_000,\n },\n});\n\nexport type JobConfig = Static<typeof jobConfig.schema>;\n\ndeclare module \"alepha\" {\n interface State {\n [jobConfig.key]: JobConfig;\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const jobExecutionQuerySchema = t.object({\n status: t.optional(\n t.enum([\"pending\", \"running\", \"scheduled\", \"ok\", \"error\", \"cancelled\"]),\n ),\n limit: t.optional(t.integer({ minimum: 1, maximum: 200, default: 20 })),\n});\n\nexport type JobExecutionQuery = Static<typeof jobExecutionQuerySchema>;\n","import { type Static, t } from \"alepha\";\nimport { jobExecutionEntity } from \"../entities/jobExecutionEntity.ts\";\n\n/**\n * Public-facing schema for a job execution row.\n *\n * Diverges from the raw entity in two places, both for API ergonomics:\n *\n * - `priority` is exposed as the **string enum** (`critical`/`high`/...)\n * instead of the numeric value used internally for SQL ordering. The\n * `JobService` is responsible for the int → string transform.\n * - `can` derives the available admin actions from the row's status.\n */\nexport const jobExecutionResourceSchema = t.extend(\n jobExecutionEntity.schema,\n {\n priority: t.enum([\"critical\", \"high\", \"normal\", \"low\"]),\n can: t.object({\n retry: t.boolean(),\n cancel: t.boolean(),\n }),\n },\n {\n title: \"JobExecutionResource\",\n description: \"A job execution row with derived actions.\",\n },\n);\n\nexport type JobExecutionResource = Static<typeof jobExecutionResourceSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobRegistrationSchema = t.object({\n name: t.text(),\n description: t.optional(t.text()),\n type: t.enum([\"cron\", \"queue\", \"direct\"], {\n description:\n \"Effective runtime mode. 'cron' = scheduled. 'queue' = push-driven, dispatched via AlephaApiJobsQueue. 'direct' = push-driven, processed in-process (no queue infrastructure loaded), with the sweep as the safety net.\",\n }),\n priority: t.enum([\"critical\", \"high\", \"normal\", \"low\"]),\n cron: t.optional(t.text()),\n timeout: t.optional(t.text()),\n retry: t.optional(\n t.object({\n retries: t.integer(),\n }),\n ),\n recent: t.object({\n ok: t.integer(),\n error: t.integer(),\n lastRun: t.optional(t.datetime()),\n }),\n});\n\nexport type JobRegistration = Static<typeof jobRegistrationSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const triggerJobSchema = t.object({\n payload: t.optional(t.record(t.text(), t.any())),\n});\n\nexport type TriggerJob = Static<typeof triggerJobSchema>;\n","import { $module } from \"alepha\";\n\n// -----------------------------------------------------------------------------------------------------------------\n\nexport * from \"./entities/jobExecutionEntity.ts\";\nexport * from \"./schemas/jobConfigAtom.ts\";\nexport * from \"./schemas/jobExecutionQuerySchema.ts\";\nexport * from \"./schemas/jobExecutionResourceSchema.ts\";\nexport * from \"./schemas/jobRegistrationSchema.ts\";\nexport * from \"./schemas/triggerJobSchema.ts\";\n\n// -----------------------------------------------------------------------------------------------------------------\n\nexport const AlephaApiJobs = $module({\n name: \"alepha.api.jobs\",\n services: [],\n});\n\nexport const AlephaApiJobsQueue = $module({\n name: \"alepha.api.jobs.queue\",\n services: [],\n});\n"],"mappings":"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"}
|