@cosmicdrift/kumiko-types 0.304.0 → 0.306.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 +5 -1
- package/src/config.ts +13 -3
- package/src/extension-options-map.ts +21 -0
- package/src/feature.ts +8 -3
- package/src/fields.ts +32 -0
- package/src/tenant-db-types.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.306.0",
|
|
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>",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
"types": "./src/event-type-map.ts",
|
|
35
35
|
"default": "./src/event-type-map.ts"
|
|
36
36
|
},
|
|
37
|
+
"./extension-options-map": {
|
|
38
|
+
"types": "./src/extension-options-map.ts",
|
|
39
|
+
"default": "./src/extension-options-map.ts"
|
|
40
|
+
},
|
|
37
41
|
"./http-route": {
|
|
38
42
|
"types": "./src/http-route.ts",
|
|
39
43
|
"default": "./src/http-route.ts"
|
package/src/config.ts
CHANGED
|
@@ -358,6 +358,14 @@ export type JobTrigger =
|
|
|
358
358
|
| { readonly cron: string }
|
|
359
359
|
| { readonly manual: true };
|
|
360
360
|
|
|
361
|
+
export type JobBackoffStrategy = "fixed" | "exponential";
|
|
362
|
+
// String form uses the framework's default base delay; the object form's
|
|
363
|
+
// `delayMs` is the base BullMQ multiplies: "fixed" keeps it constant,
|
|
364
|
+
// "exponential" scales it delayMs * 2^(attemptsMade-1) per retry.
|
|
365
|
+
export type JobBackoff =
|
|
366
|
+
| JobBackoffStrategy
|
|
367
|
+
| { readonly type: JobBackoffStrategy; readonly delayMs?: number | undefined };
|
|
368
|
+
|
|
361
369
|
export type JobDefinition = {
|
|
362
370
|
readonly name: string;
|
|
363
371
|
readonly handler: JobHandlerFn;
|
|
@@ -366,14 +374,16 @@ export type JobDefinition = {
|
|
|
366
374
|
readonly maxPerTenant?: number | undefined;
|
|
367
375
|
readonly debounceMs?: number | undefined;
|
|
368
376
|
readonly retries?: number | undefined;
|
|
369
|
-
readonly backoff?:
|
|
377
|
+
readonly backoff?: JobBackoff | undefined;
|
|
370
378
|
readonly timeout?: number | undefined;
|
|
371
379
|
readonly schema?: ZodType | undefined;
|
|
372
380
|
// Enqueue this job once when a runner for its lane starts. Fire-and-forget:
|
|
373
381
|
// the enqueue is awaited, the run is not, so a throwing handler only fails
|
|
374
382
|
// the queue job — the process keeps booting and reports ready.
|
|
375
|
-
// Deduped
|
|
376
|
-
//
|
|
383
|
+
// Deduped via a persistent per-queue marker set at enqueue time (not the
|
|
384
|
+
// fixed job id alone, which BullMQ's bounded retention can evict), so it
|
|
385
|
+
// runs at most once per Redis dataset: a boot job that already ran (or
|
|
386
|
+
// failed) is not retried on a later deploy.
|
|
377
387
|
// Never a deploy gate — use `bootGate` for that.
|
|
378
388
|
readonly runOnBoot?: boolean | undefined;
|
|
379
389
|
// Run this job inline while the runner for its lane starts, before cron
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Cross-Feature Compile-Time-Type-Map for `r.useExtension(name, entity, options)`.
|
|
2
|
+
// Augmented per extension point via `declare module "@cosmicdrift/kumiko-framework/engine"`,
|
|
3
|
+
// mirroring event-type-map.ts; names without augmentation stay untyped.
|
|
4
|
+
|
|
5
|
+
import type { EscapeHatchDeclaration } from "./handlers";
|
|
6
|
+
|
|
7
|
+
// MUST be `interface` (not `type`): only interfaces support TS declaration-
|
|
8
|
+
// merging. See event-type-map.ts for the same constraint.
|
|
9
|
+
|
|
10
|
+
// biome-ignore lint/suspicious/noEmptyInterface: declaration-merging marker — augmented per extension point
|
|
11
|
+
export interface KumikoExtensionOptionsMap {}
|
|
12
|
+
|
|
13
|
+
/** Options shape for an extension name: the augmented hook shape plus `escapeHatch`, or an untyped bag if unaugmented. */
|
|
14
|
+
export type ExtensionOptionsFor<N extends string> = N extends keyof KumikoExtensionOptionsMap
|
|
15
|
+
? KumikoExtensionOptionsMap[N] & { readonly escapeHatch?: EscapeHatchDeclaration }
|
|
16
|
+
: Record<string, unknown>;
|
|
17
|
+
|
|
18
|
+
/** Rest-tuple for useExtension's positional options arg: required for an augmented name, optional otherwise. */
|
|
19
|
+
export type ExtensionOptionsArgs<N extends string> = N extends keyof KumikoExtensionOptionsMap
|
|
20
|
+
? [options: ExtensionOptionsFor<N>]
|
|
21
|
+
: [options?: Record<string, unknown>];
|
package/src/feature.ts
CHANGED
|
@@ -24,6 +24,7 @@ import type {
|
|
|
24
24
|
} from "./define-handler";
|
|
25
25
|
import type { RegisterEntityCrudOptions } from "./entity-handlers";
|
|
26
26
|
import type { EntityTableMeta } from "./entity-table-meta-types";
|
|
27
|
+
import type { ExtensionOptionsArgs, ExtensionOptionsFor } from "./extension-options-map";
|
|
27
28
|
import type { EntityDefinition } from "./fields";
|
|
28
29
|
import type {
|
|
29
30
|
AccessRule,
|
|
@@ -653,9 +654,13 @@ export type FeatureRegistrar<TFeature extends string = string> = {
|
|
|
653
654
|
|
|
654
655
|
extendsRegistrar(name: string, def: RegistrarExtensionDef): void;
|
|
655
656
|
|
|
656
|
-
useExtension
|
|
657
|
-
|
|
658
|
-
|
|
657
|
+
useExtension<N extends string>(
|
|
658
|
+
extensionName: N,
|
|
659
|
+
entity: NameOrRef,
|
|
660
|
+
...options: ExtensionOptionsArgs<N>
|
|
661
|
+
): void;
|
|
662
|
+
useExtension<N extends string>(
|
|
663
|
+
definition: { readonly name: N; readonly entity: NameOrRef } & ExtensionOptionsFor<N>,
|
|
659
664
|
): void;
|
|
660
665
|
|
|
661
666
|
/**
|
package/src/fields.ts
CHANGED
|
@@ -836,6 +836,38 @@ export type FieldDefinition =
|
|
|
836
836
|
| FilesFieldDef
|
|
837
837
|
| ImagesFieldDef;
|
|
838
838
|
|
|
839
|
+
// Exhaustive catalogue of `FieldDefinition["type"]` values, derived from a
|
|
840
|
+
// `Record` so an added/removed union member fails to compile here instead of
|
|
841
|
+
// silently drifting out of sync with the runtime validator that consults
|
|
842
|
+
// this list (feature-ast's pattern-change-schema). Plain array, not a Set —
|
|
843
|
+
// same rationale as NO_WIDGET_FIELD_TYPES (guard-types-class-free.test.ts).
|
|
844
|
+
const FIELD_TYPE_NAME_FLAGS: Record<FieldDefinition["type"], true> = {
|
|
845
|
+
text: true,
|
|
846
|
+
longText: true,
|
|
847
|
+
boolean: true,
|
|
848
|
+
select: true,
|
|
849
|
+
multiSelect: true,
|
|
850
|
+
number: true,
|
|
851
|
+
bigInt: true,
|
|
852
|
+
decimal: true,
|
|
853
|
+
money: true,
|
|
854
|
+
reference: true,
|
|
855
|
+
embedded: true,
|
|
856
|
+
jsonb: true,
|
|
857
|
+
date: true,
|
|
858
|
+
timestamp: true,
|
|
859
|
+
tz: true,
|
|
860
|
+
locatedTimestamp: true,
|
|
861
|
+
file: true,
|
|
862
|
+
image: true,
|
|
863
|
+
files: true,
|
|
864
|
+
images: true,
|
|
865
|
+
};
|
|
866
|
+
|
|
867
|
+
export const FIELD_TYPE_NAMES: readonly FieldDefinition["type"][] = Object.keys(
|
|
868
|
+
FIELD_TYPE_NAME_FLAGS,
|
|
869
|
+
) as FieldDefinition["type"][];
|
|
870
|
+
|
|
839
871
|
/** FieldDefinition as an entity-less inline form screen (actionForm,
|
|
840
872
|
* secretMint) may declare it: a `money` field there has no entity to borrow
|
|
841
873
|
* `defaultCurrency` from, so it must name its own currency source, or the
|
package/src/tenant-db-types.ts
CHANGED
|
@@ -108,7 +108,7 @@ export type UncheckedSystemDb = {
|
|
|
108
108
|
// durability writes that must survive a rollback of the handler's own
|
|
109
109
|
// transaction. Throws if the dispatch has no outside-transaction source
|
|
110
110
|
// configured (e.g. a hand-built UncheckedSystemDb that only ever passed
|
|
111
|
-
// the in-tx db
|
|
111
|
+
// the in-tx db, as createSystemDbView callers do).
|
|
112
112
|
readonly outsideTransaction: {
|
|
113
113
|
assertTenantMatch(tenantId: TenantId): TenantDb;
|
|
114
114
|
acknowledgeCrossTenant(reason: string): TenantDb;
|