@ultimat3/core 27.10.4 → 27.12.0
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/package.json +2 -2
- package/src/config-defaults.ts +9 -1
- package/src/config-jobs.ts +20 -0
- package/src/config.ts +14 -0
- package/src/index.ts +8 -1
- package/src/mcp-exposure.ts +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/core",
|
|
3
|
-
"version": "27.
|
|
3
|
+
"version": "27.12.0",
|
|
4
4
|
"description": "Ultimate's foundation: errors, context, env, config, clock, ids, logging, telemetry, lifecycle",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,6 +37,6 @@
|
|
|
37
37
|
"test": "bun test"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@ultimat3/schema": "27.
|
|
40
|
+
"@ultimat3/schema": "27.12.0"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/config-defaults.ts
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
// Split from `config.ts`, which sits at its 500-line ceiling; literals only, so it reads no key.
|
|
3
3
|
|
|
4
4
|
import type { AppConfig } from './config';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
JOBS_CONCURRENCY_DEFAULT,
|
|
7
|
+
JOBS_DEAD_RETENTION_MS_DEFAULT,
|
|
8
|
+
JOBS_DONE_RETENTION_MS_DEFAULT,
|
|
9
|
+
JOBS_OUTBOX_RETENTION_MS_DEFAULT,
|
|
10
|
+
} from './config-jobs';
|
|
6
11
|
import { DRAIN_DEADLINE_DEFAULT_MS } from './drain-deadline';
|
|
7
12
|
import { defaultReadinessGraceMs } from './lifecycle-grace';
|
|
8
13
|
import { ROLES } from './roles';
|
|
@@ -31,6 +36,9 @@ export function configDefaults(name: string): Omit<AppConfig, Sectioned> {
|
|
|
31
36
|
maxAttempts: 5,
|
|
32
37
|
backoff: 'exponential',
|
|
33
38
|
visibilityTimeoutMs: 30_000,
|
|
39
|
+
doneRetentionMs: JOBS_DONE_RETENTION_MS_DEFAULT,
|
|
40
|
+
deadRetentionMs: JOBS_DEAD_RETENTION_MS_DEFAULT,
|
|
41
|
+
outboxRetentionMs: JOBS_OUTBOX_RETENTION_MS_DEFAULT,
|
|
34
42
|
},
|
|
35
43
|
// ON by default since 22.0.0, when the boot began obeying the key: an app with no section
|
|
36
44
|
// keeps the `sync` node it always got, and `enabled: false` is the explicit opt-out.
|
package/src/config-jobs.ts
CHANGED
|
@@ -14,6 +14,26 @@ import { isJsonObject } from './json-object';
|
|
|
14
14
|
*/
|
|
15
15
|
export const JOBS_CONCURRENCY_DEFAULT = 8;
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* `jobs.doneRetentionMs` when no layer says: how long a `done` row and its step records are kept
|
|
19
|
+
* before the boot's hourly purge deletes them. Two weeks — every incident is read inside it, and
|
|
20
|
+
* a finished row is bookkeeping, unlike an inbox message: a `mail.send` input is an address and a
|
|
21
|
+
* rendered body, personal data with no reason to outlive the delivery.
|
|
22
|
+
*/
|
|
23
|
+
export const JOBS_DONE_RETENTION_MS_DEFAULT = 14 * 86_400_000;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `jobs.deadRetentionMs` when no layer says: `dead`, `failed` and `cancelled` rows, which staff
|
|
27
|
+
* read to explain a failure, kept a quarter.
|
|
28
|
+
*/
|
|
29
|
+
export const JOBS_DEAD_RETENTION_MS_DEFAULT = 90 * 86_400_000;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* `jobs.outboxRetentionMs` when no layer says: a PUBLISHED `x_outbox` row, whose job is already in
|
|
33
|
+
* `x_jobs`, kept a week. An unpublished row is never swept, whatever this says.
|
|
34
|
+
*/
|
|
35
|
+
export const JOBS_OUTBOX_RETENTION_MS_DEFAULT = 7 * 86_400_000;
|
|
36
|
+
|
|
17
37
|
/** One slot count for every queue, or slots per queue name — `jobWorker`'s own `concurrency`. */
|
|
18
38
|
export type JobsConcurrency = number | Readonly<Record<string, number>>;
|
|
19
39
|
|
package/src/config.ts
CHANGED
|
@@ -163,6 +163,17 @@ export interface JobsConfig {
|
|
|
163
163
|
readonly maxAttempts: number;
|
|
164
164
|
readonly backoff: (typeof JOB_BACKOFFS)[number];
|
|
165
165
|
readonly visibilityTimeoutMs: number;
|
|
166
|
+
/**
|
|
167
|
+
* Age past which the hourly purge deletes a `done` row and its steps. Unset: 14 days
|
|
168
|
+
* (`JOBS_DONE_RETENTION_MS_DEFAULT`). OPTIONAL, as `realtime.maxSocketsPerActor` is, so a
|
|
169
|
+
* `JobsConfig` literal written before the key existed still type-checks: `defineConfig` fills it
|
|
170
|
+
* in, and the boot (`runtime-jobs-retention.ts`) resolves the same constant for one that did not.
|
|
171
|
+
*/
|
|
172
|
+
readonly doneRetentionMs?: number | undefined;
|
|
173
|
+
/** The same for `dead`, `failed` and `cancelled` rows. Unset: 90 days. */
|
|
174
|
+
readonly deadRetentionMs?: number | undefined;
|
|
175
|
+
/** Age of `published_at` past which a PUBLISHED `x_outbox` row goes. Unset: 7 days. */
|
|
176
|
+
readonly outboxRetentionMs?: number | undefined;
|
|
166
177
|
}
|
|
167
178
|
|
|
168
179
|
/**
|
|
@@ -274,6 +285,9 @@ function validate(config: AppConfig): void {
|
|
|
274
285
|
...jobsConcurrencyIssues(config.jobs.concurrency),
|
|
275
286
|
countIssue('jobs.maxAttempts', config.jobs.maxAttempts, 1),
|
|
276
287
|
countIssue('jobs.visibilityTimeoutMs', config.jobs.visibilityTimeoutMs, 1),
|
|
288
|
+
...(['doneRetentionMs', 'deadRetentionMs', 'outboxRetentionMs'] as const).map((key) =>
|
|
289
|
+
config.jobs[key] === undefined ? undefined : countIssue(`jobs.${key}`, config.jobs[key], 1),
|
|
290
|
+
),
|
|
277
291
|
oneOfIssue('jobs.backoff', config.jobs.backoff, JOB_BACKOFFS),
|
|
278
292
|
countIssue('cache.defaultTtlMs', config.cache.defaultTtlMs, 0),
|
|
279
293
|
oneOfIssue('database.driver', config.database.driver, DATABASE_DRIVERS),
|
package/src/index.ts
CHANGED
|
@@ -146,7 +146,13 @@ export type { AiConfig, AiConfigInput, McpConfig } from './config-ai';
|
|
|
146
146
|
export type { DrainConfig, HealthConfig, ReadinessMode } from './config-health';
|
|
147
147
|
export { READINESS_MODES } from './config-health';
|
|
148
148
|
export type { IslandsConfig, IslandsSection, IslandsSectionInput } from './config-islands';
|
|
149
|
-
export {
|
|
149
|
+
export {
|
|
150
|
+
JOBS_CONCURRENCY_DEFAULT,
|
|
151
|
+
JOBS_DEAD_RETENTION_MS_DEFAULT,
|
|
152
|
+
JOBS_DONE_RETENTION_MS_DEFAULT,
|
|
153
|
+
JOBS_OUTBOX_RETENTION_MS_DEFAULT,
|
|
154
|
+
type JobsConcurrency,
|
|
155
|
+
} from './config-jobs';
|
|
150
156
|
export type {
|
|
151
157
|
MailConfig,
|
|
152
158
|
MailRetainMimeConfig,
|
|
@@ -675,6 +681,7 @@ export { setLogSink } from './logger';
|
|
|
675
681
|
export {
|
|
676
682
|
isMcpExposed,
|
|
677
683
|
type McpAnnotationHints,
|
|
684
|
+
type McpEffect,
|
|
678
685
|
type McpExposureDeclaration,
|
|
679
686
|
type McpListFilterOp,
|
|
680
687
|
type McpListParams,
|
package/src/mcp-exposure.ts
CHANGED
|
@@ -14,6 +14,15 @@ export interface McpAnnotationHints {
|
|
|
14
14
|
readonly openWorldHint?: boolean;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* What an exposed action DOES, for a surface that dispatches by it (`@ultimat3/mcp`'s
|
|
19
|
+
* `surface: 'meta-split'`): `'write'` creates or changes app state, reversibly or within a
|
|
20
|
+
* standing budget; `'delete'` archives, cancels or deletes, sends something outside the app, or
|
|
21
|
+
* commits money. A query is a read and declares none. No default: a wrong one either hides a
|
|
22
|
+
* deletion behind an ordinary write or asks deletion-grade consent for an update.
|
|
23
|
+
*/
|
|
24
|
+
export type McpEffect = 'write' | 'delete';
|
|
25
|
+
|
|
17
26
|
/** One comparison a list filter accepts. A filter key is `<field><op>`: `status_eq`. */
|
|
18
27
|
export type McpListFilterOp = '_eq' | '_in' | '_gt' | '_lt' | '_cont';
|
|
19
28
|
|
|
@@ -64,6 +73,12 @@ export interface McpExposureDeclaration {
|
|
|
64
73
|
* nothing, `openWorldHint: true` for one that reaches outside the app.
|
|
65
74
|
*/
|
|
66
75
|
readonly annotations?: McpAnnotationHints;
|
|
76
|
+
/**
|
|
77
|
+
* The action's effect class — required for an action a `'meta-split'` surface groups
|
|
78
|
+
* (`X_MCP_EFFECT_UNDECLARED`), refused on a query (`X_MCP_EFFECT_CONFLICT`). Picks
|
|
79
|
+
* `write_resource` or `delete_resource`; ignored by every other surface.
|
|
80
|
+
*/
|
|
81
|
+
readonly effect?: McpEffect;
|
|
67
82
|
/** A list query's whitelist, carried to the tool for the meta surface. Never an action's. */
|
|
68
83
|
readonly listParams?: McpListParams;
|
|
69
84
|
}
|