@cosmicdrift/kumiko-types 0.364.0 → 0.365.1

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/config.d.ts CHANGED
@@ -154,12 +154,17 @@ export type JobBackoff = JobBackoffStrategy | {
154
154
  readonly type: JobBackoffStrategy;
155
155
  readonly delayMs?: number | undefined;
156
156
  };
157
+ export type MaxPerTenantOptions = {
158
+ readonly limit: number;
159
+ readonly onLimit: "skip" | "defer";
160
+ readonly deferMs?: number | undefined;
161
+ };
157
162
  export type JobDefinition = {
158
163
  readonly name: string;
159
164
  readonly handler: JobHandlerFn;
160
165
  readonly trigger: JobTrigger;
161
166
  readonly concurrency?: ConcurrencyMode | undefined;
162
- readonly maxPerTenant?: number | undefined;
167
+ readonly maxPerTenant?: number | MaxPerTenantOptions | undefined;
163
168
  readonly debounceMs?: number | undefined;
164
169
  readonly retries?: number | undefined;
165
170
  readonly backoff?: JobBackoff | undefined;
@@ -11,4 +11,9 @@ export type DbTx = postgres.TransactionSql<Record<string, unknown>> | RawDbClien
11
11
  export type DbRunner = DbConnection | DbTx;
12
12
  export type DbRow = Record<string, unknown>;
13
13
  export type PgClient = ReturnType<typeof postgres>;
14
- export type PgListenClient = ReturnType<typeof postgres>;
14
+ export type PgListenSubscription = {
15
+ unlisten(): Promise<void>;
16
+ };
17
+ export type PgListenClient = {
18
+ listen(channel: string, onnotify: (payload: string) => void, onlisten?: () => void): Promise<PgListenSubscription>;
19
+ };
@@ -11,5 +11,8 @@ export type FileContext = {
11
11
  refFromFileRef(row: {
12
12
  readonly storageKey: string;
13
13
  }): FileHandle;
14
+ listFromFileRef(row: {
15
+ readonly storageKey: string;
16
+ }): Promise<readonly string[]>;
14
17
  list(prefix: string): Promise<readonly string[]>;
15
18
  };
@@ -127,6 +127,10 @@ export type JobTriggerEvent = {
127
127
  };
128
128
  export type JobRunnerRef = {
129
129
  handleEvent(eventName: string, payload: Record<string, unknown>, user?: SessionUser, triggerEvent?: JobTriggerEvent): Promise<void>;
130
+ dispatch?(jobName: string, payload: Record<string, unknown>, meta?: {
131
+ readonly priority?: number;
132
+ readonly jobId?: string;
133
+ }): Promise<unknown>;
130
134
  };
131
135
  export type DispatchWriteRef = {
132
136
  readonly write: (user: SessionUser, qn: string, payload: unknown, inheritedOrigin?: WriteOrigin) => Promise<WriteResult>;
@@ -238,6 +242,7 @@ type SharedContextFields = {
238
242
  readonly notify?: NotifyFn;
239
243
  readonly _notifyFactory?: NotifyFactory;
240
244
  readonly _notifyInTransactionFactory?: (user: SessionUser, tenantId: TenantId) => NotifyFn;
245
+ readonly _notifyAfterCommitFactory?: (user: SessionUser, tenantId: TenantId) => NotifyFn;
241
246
  readonly _escapeHatchAuditSink?: EscapeHatchAuditSink;
242
247
  readonly secrets?: import("./secrets-types.js").SecretsContext;
243
248
  readonly masterKeyProvider?: import("./secrets-types.js").MasterKeyProvider;
@@ -355,6 +360,7 @@ export type JobContext = SharedContextFields & {
355
360
  readonly registry: Registry;
356
361
  readonly systemUser: SessionUser;
357
362
  readonly log: Logger;
363
+ readonly metricsFor: (featureName: string) => MetricsHandle;
358
364
  readonly triggeredBy: {
359
365
  readonly id: string;
360
366
  readonly tenantId: TenantId;
@@ -596,7 +602,9 @@ export type WriteHandlerDef = {
596
602
  /** Runs after all pre-handler gates (and after reserveBeforeTransaction) and before the
597
603
  * transaction opens: no transaction and no connection held, for external I/O and reads only.
598
604
  * Its `data` reaches the handler as `event.prepared`; a failure result or throw rejects the
599
- * write before anything is written. A handler with this phase cannot run as a nested ctx.write. */
605
+ * write before anything is written. A handler with this phase cannot run as a nested ctx.write.
606
+ * `ctx.forTenant` is available but read-only here: its db denies writes for the own and a
607
+ * foreign tenant alike (a foreign tenant stays gated by the SystemAdmin check). */
600
608
  readonly beforeTransaction?: BeforeTransactionPhase;
601
609
  /** `"perCommand"`: the handler runs without a transaction of its own. Every ctx.write/writeAs it
602
610
  * issues runs as its own top-level command with its own transaction and afterCommit hooks;
@@ -40,7 +40,8 @@ interface KmsAdapterBase {
40
40
  createKey(subject: SubjectId, ctx: KmsContext): Promise<void>;
41
41
  /**
42
42
  * Erases the key material immediately; the tombstone row stays for the
43
- * audit trail. Idempotent — repeat calls and unknown subjects are no-ops.
43
+ * audit trail. Idempotent. A never-keyed subject gets a tombstone too, so a
44
+ * later createKey cannot mint a fresh key for pre-KMS plaintext.
44
45
  */
45
46
  eraseKey(subject: SubjectId, ctx: KmsContext): Promise<void>;
46
47
  /** Probe for boot + readiness. Throws when the backend is unreachable. */
@@ -16,4 +16,9 @@ export type MultiStreamApplyContext<TMap extends object = KumikoEventTypeMap> =
16
16
  readonly files?: FileContext;
17
17
  readonly derivatives?: DerivativesContext;
18
18
  readonly secrets?: SecretsContext;
19
+ readonly jobs?: {
20
+ dispatch(jobName: string, payload: Record<string, unknown>, options?: {
21
+ readonly jobId?: string;
22
+ }): Promise<void>;
23
+ };
19
24
  };
package/dist/screen.d.ts CHANGED
@@ -13,6 +13,8 @@ export interface FieldFormatRegistry {
13
13
  readonly locale?: string;
14
14
  readonly dateStyle?: "full" | "long" | "medium" | "short";
15
15
  readonly timeStyle?: "full" | "long" | "medium" | "short";
16
+ /** IANA zone id (e.g. "Europe/Berlin"). Default: the runtime's zone. */
17
+ readonly timeZone?: string;
16
18
  };
17
19
  date: {
18
20
  readonly locale?: string;
@@ -723,6 +725,8 @@ export type DashboardPanelEmptyState = {
723
725
  /** Second line under `emptyLabel`. */
724
726
  readonly emptyHint?: string;
725
727
  };
728
+ export declare const DASHBOARD_STAT_TONES: readonly ["default", "positive", "ok", "warn", "negative"];
729
+ export type DashboardStatTone = (typeof DASHBOARD_STAT_TONES)[number];
726
730
  export type DashboardStatPanel = DashboardPanelQueryOptions & DashboardPanelGate & {
727
731
  readonly kind: "stat";
728
732
  /** Stable id: kebab-case, unique within the panel set. */
@@ -736,7 +740,7 @@ export type DashboardStatPanel = DashboardPanelQueryOptions & DashboardPanelGate
736
740
  /** Formats a numeric value as currency (minor units); ignored for string values. The sparkline is not formatted. */
737
741
  readonly valueFormat?: DashboardValueFormat;
738
742
  /** Fixed tone when `toneField` is unset or yields none; not applied while the value is 0. */
739
- readonly tone?: "default" | "positive" | "ok" | "warn" | "negative";
743
+ readonly tone?: DashboardStatTone;
740
744
  /** Record field holding `{ atMs, value | null }[]` (MetricResult.points),
741
745
  * drawn as a sparkline next to the value. */
742
746
  readonly sparklineField?: string;
package/dist/screen.js CHANGED
@@ -1,6 +1,13 @@
1
1
  export function metricField(metric) {
2
2
  return typeof metric === "string" ? metric : metric.field;
3
3
  }
4
+ // Query result contract: flat record; `valueField` points at the
5
+ // value (string is display-ready, number is locale-formatted, DashboardI18nText
6
+ // is translated), `subField` optionally at a sub line (string | DashboardI18nText), `toneField` optionally at
7
+ // "default" | "positive" | "ok" | "warn" | "negative".
8
+ // `visibleWhen` only on a top-level stat; the boot validator rejects it on a
9
+ // stat-group child (gate the whole group instead).
10
+ export const DASHBOARD_STAT_TONES = ["default", "positive", "ok", "warn", "negative"];
4
11
  /** Group key of a field value; `collapsedWhen` and row values both go through it. */
5
12
  export function relatedListGroupKey(value) {
6
13
  return value === undefined || value === null ? "" : String(value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.364.0",
3
+ "version": "0.365.1",
4
4
  "description": "Framework-Type-Definitions für Kumiko — FeatureDefinition, BootCheck-Types und die reinen Engine-Types. Erlaubt Downstream-Konsumenten, gegen die Type-Contracts zu bauen, ohne das ganze Framework-Package zu importieren. Enthaelt keine identitaets-sensitiven Runtime-Werte mehr (Error-Klassen leben seit #1629 in kumiko-framework, Brand-Symbole nutzen Symbol.for) und ist deshalb eine plain dependency, keine peerDependency.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
package/src/changes.json CHANGED
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.365.0",
4
+ "type": "improvement",
5
+ "title": "DASHBOARD_STAT_TONES is the single source for dashboard stat tones",
6
+ "detail": "screen.ts exports DASHBOARD_STAT_TONES and DashboardStatTone; DashboardStatPanel.tone derives from it, and the web renderer builds its runtime tone check and StatTone type from the same constant, so a new tone can no longer be silently dropped from toneField values."
7
+ },
2
8
  {
3
9
  "version": "0.362.0",
4
10
  "type": "improvement",