@kronos-ts/modelling 0.1.1 → 0.2.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/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/state.d.ts +20 -5
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +31 -1
- package/dist/state.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/state.ts +31 -15
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { type StateModule, type StateLifecycle, type IdSchema, type InferIdFromSchema, state, } from "./state.js";
|
|
1
|
+
export { type StateModule, type StateLifecycle, type EvolverBuilder, type IdSchema, type InferIdFromSchema, state, } from "./state.js";
|
|
2
2
|
export { type SourcingInfo, type LoadResult, type StateRepository, type StateManager, createStateManager, } from "./state-manager.js";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,GACN,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,GACN,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,GACN,MAAM,YAAY,CAAA;AAEnB,OAAO,EAKL,kBAAkB,GACnB,MAAM,oBAAoB,CAAA"}
|
package/dist/state.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
|
-
import type { EventCriteria, EventMessage } from "@kronos-ts/messaging";
|
|
3
|
-
import type { EvolverRegistration } from "@kronos-ts/messaging";
|
|
2
|
+
import type { EventCriteria, EventMessage, EvolverRegistration, EventDescriptor } from "@kronos-ts/messaging";
|
|
4
3
|
/**
|
|
5
4
|
* A named record mapping field names to Zod schemas.
|
|
6
5
|
* Used to define state IDs with explicit field names.
|
|
@@ -36,6 +35,15 @@ export interface StateLifecycle<Id = unknown, S = unknown> {
|
|
|
36
35
|
/** Predicate that detects deleted state. */
|
|
37
36
|
isDeleted?: (state: S) => boolean;
|
|
38
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* The state-scoped `on` handed to an `evolve` builder.
|
|
40
|
+
*
|
|
41
|
+
* It is the same `on` as the top-level export, but with the state type `S`
|
|
42
|
+
* already bound. Because `S` is fixed before the evolver callbacks are
|
|
43
|
+
* checked, each callback receives `state: S` contextually — no `(s: S)`
|
|
44
|
+
* annotation, and a wrong return is still rejected against `S`.
|
|
45
|
+
*/
|
|
46
|
+
export type EvolverBuilder<S> = <P extends z.ZodType>(descriptor: EventDescriptor<P>, evolve: (state: S, message: EventMessage<z.infer<P>>) => S | Promise<S>) => EvolverRegistration<S, P>;
|
|
39
47
|
/**
|
|
40
48
|
* A state module — a self-contained definition of state sourced from events.
|
|
41
49
|
*
|
|
@@ -64,14 +72,21 @@ export interface StateModule<Id = unknown, S = unknown> {
|
|
|
64
72
|
* The state type is inferred from the `initial` function's return type —
|
|
65
73
|
* no separate type definition needed.
|
|
66
74
|
*
|
|
75
|
+
* Evolvers are registered through a builder: `evolve: (on) => [...]`, where
|
|
76
|
+
* `on` is bound to the state type. Because `S` is fixed by `initial` before
|
|
77
|
+
* the evolvers are checked, each callback receives `state: S` contextually —
|
|
78
|
+
* no `(s: S)` annotation, and a wrong return is still rejected against `S`.
|
|
79
|
+
* When `initial` under-specifies `S` (empty arrays, unions), annotate the one
|
|
80
|
+
* source of truth: `initial: (id): CourseState => (...)`.
|
|
81
|
+
*
|
|
67
82
|
* ```typescript
|
|
68
83
|
* const Course = state({
|
|
69
84
|
* name: "Course",
|
|
70
85
|
* id: { courseId: z.string() },
|
|
71
86
|
* initial: () => ({ created: false, name: "", capacity: 0 }),
|
|
72
87
|
* criteria: (id) => EventCriteria.havingTags({ courseId: id.courseId }),
|
|
73
|
-
* evolve: [
|
|
74
|
-
* on(CourseCreated, (s, event) => ({ ...s, created: true })),
|
|
88
|
+
* evolve: (on) => [
|
|
89
|
+
* on(CourseCreated, (s, { payload: event }) => ({ ...s, created: true })),
|
|
75
90
|
* ],
|
|
76
91
|
* })
|
|
77
92
|
* ```
|
|
@@ -81,7 +96,7 @@ export declare function state<IS extends IdSchema, S>(def: {
|
|
|
81
96
|
id: IS;
|
|
82
97
|
initial: (id: InferIdFromSchema<IS>) => S;
|
|
83
98
|
criteria: (id: InferIdFromSchema<IS>) => EventCriteria;
|
|
84
|
-
evolve: Array<EvolverRegistration<S, any>>;
|
|
99
|
+
evolve: (on: EvolverBuilder<S>) => Array<EvolverRegistration<S, any>>;
|
|
85
100
|
lifecycle?: StateLifecycle<InferIdFromSchema<IS>, S>;
|
|
86
101
|
}): StateModule<InferIdFromSchema<IS>, S>;
|
|
87
102
|
//# sourceMappingURL=state.d.ts.map
|
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/state.js
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
import { on } from "@kronos-ts/messaging";
|
|
2
|
+
/**
|
|
3
|
+
* Defines a state module — state sourced from events, scoped by an ID.
|
|
4
|
+
*
|
|
5
|
+
* The `id` parameter must be a named record mapping field names to Zod types.
|
|
6
|
+
* A bare Zod type (e.g., `z.string()`) will not compile — you must name
|
|
7
|
+
* the field (e.g., `{ courseId: z.string() }`).
|
|
8
|
+
*
|
|
9
|
+
* The state type is inferred from the `initial` function's return type —
|
|
10
|
+
* no separate type definition needed.
|
|
11
|
+
*
|
|
12
|
+
* Evolvers are registered through a builder: `evolve: (on) => [...]`, where
|
|
13
|
+
* `on` is bound to the state type. Because `S` is fixed by `initial` before
|
|
14
|
+
* the evolvers are checked, each callback receives `state: S` contextually —
|
|
15
|
+
* no `(s: S)` annotation, and a wrong return is still rejected against `S`.
|
|
16
|
+
* When `initial` under-specifies `S` (empty arrays, unions), annotate the one
|
|
17
|
+
* source of truth: `initial: (id): CourseState => (...)`.
|
|
18
|
+
*
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const Course = state({
|
|
21
|
+
* name: "Course",
|
|
22
|
+
* id: { courseId: z.string() },
|
|
23
|
+
* initial: () => ({ created: false, name: "", capacity: 0 }),
|
|
24
|
+
* criteria: (id) => EventCriteria.havingTags({ courseId: id.courseId }),
|
|
25
|
+
* evolve: (on) => [
|
|
26
|
+
* on(CourseCreated, (s, { payload: event }) => ({ ...s, created: true })),
|
|
27
|
+
* ],
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
1
31
|
export function state(def) {
|
|
2
32
|
return {
|
|
3
33
|
kind: "state-module",
|
|
@@ -5,7 +35,7 @@ export function state(def) {
|
|
|
5
35
|
idSchema: def.id,
|
|
6
36
|
create: def.initial,
|
|
7
37
|
criteria: def.criteria,
|
|
8
|
-
evolvers: def.evolve,
|
|
38
|
+
evolvers: def.evolve(on),
|
|
9
39
|
lifecycle: def.lifecycle,
|
|
10
40
|
};
|
|
11
41
|
}
|
package/dist/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,sBAAsB,CAAA;AAiFzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,KAAK,CAAyB,GAO7C;IACC,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,QAAQ,EAAE,GAAG,CAAC,EAAE;QAChB,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EAAkC,CAAC;QACxD,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/src/state.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { z } from "zod"
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
2
|
+
import { on } from "@kronos-ts/messaging"
|
|
3
|
+
import type {
|
|
4
|
+
EventCriteria,
|
|
5
|
+
EventMessage,
|
|
6
|
+
EvolverRegistration,
|
|
7
|
+
EventDescriptor,
|
|
8
|
+
} from "@kronos-ts/messaging"
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
11
|
* A named record mapping field names to Zod schemas.
|
|
@@ -40,6 +45,19 @@ export interface StateLifecycle<Id = unknown, S = unknown> {
|
|
|
40
45
|
isDeleted?: (state: S) => boolean
|
|
41
46
|
}
|
|
42
47
|
|
|
48
|
+
/**
|
|
49
|
+
* The state-scoped `on` handed to an `evolve` builder.
|
|
50
|
+
*
|
|
51
|
+
* It is the same `on` as the top-level export, but with the state type `S`
|
|
52
|
+
* already bound. Because `S` is fixed before the evolver callbacks are
|
|
53
|
+
* checked, each callback receives `state: S` contextually — no `(s: S)`
|
|
54
|
+
* annotation, and a wrong return is still rejected against `S`.
|
|
55
|
+
*/
|
|
56
|
+
export type EvolverBuilder<S> = <P extends z.ZodType>(
|
|
57
|
+
descriptor: EventDescriptor<P>,
|
|
58
|
+
evolve: (state: S, message: EventMessage<z.infer<P>>) => S | Promise<S>,
|
|
59
|
+
) => EvolverRegistration<S, P>
|
|
60
|
+
|
|
43
61
|
/**
|
|
44
62
|
* A state module — a self-contained definition of state sourced from events.
|
|
45
63
|
*
|
|
@@ -72,14 +90,21 @@ export interface StateModule<
|
|
|
72
90
|
* The state type is inferred from the `initial` function's return type —
|
|
73
91
|
* no separate type definition needed.
|
|
74
92
|
*
|
|
93
|
+
* Evolvers are registered through a builder: `evolve: (on) => [...]`, where
|
|
94
|
+
* `on` is bound to the state type. Because `S` is fixed by `initial` before
|
|
95
|
+
* the evolvers are checked, each callback receives `state: S` contextually —
|
|
96
|
+
* no `(s: S)` annotation, and a wrong return is still rejected against `S`.
|
|
97
|
+
* When `initial` under-specifies `S` (empty arrays, unions), annotate the one
|
|
98
|
+
* source of truth: `initial: (id): CourseState => (...)`.
|
|
99
|
+
*
|
|
75
100
|
* ```typescript
|
|
76
101
|
* const Course = state({
|
|
77
102
|
* name: "Course",
|
|
78
103
|
* id: { courseId: z.string() },
|
|
79
104
|
* initial: () => ({ created: false, name: "", capacity: 0 }),
|
|
80
105
|
* criteria: (id) => EventCriteria.havingTags({ courseId: id.courseId }),
|
|
81
|
-
* evolve: [
|
|
82
|
-
* on(CourseCreated, (s, event) => ({ ...s, created: true })),
|
|
106
|
+
* evolve: (on) => [
|
|
107
|
+
* on(CourseCreated, (s, { payload: event }) => ({ ...s, created: true })),
|
|
83
108
|
* ],
|
|
84
109
|
* })
|
|
85
110
|
* ```
|
|
@@ -89,16 +114,7 @@ export function state<IS extends IdSchema, S>(def: {
|
|
|
89
114
|
id: IS
|
|
90
115
|
initial: (id: InferIdFromSchema<IS>) => S
|
|
91
116
|
criteria: (id: InferIdFromSchema<IS>) => EventCriteria
|
|
92
|
-
evolve: Array<EvolverRegistration<S, any>>
|
|
93
|
-
lifecycle?: StateLifecycle<InferIdFromSchema<IS>, S>
|
|
94
|
-
}): StateModule<InferIdFromSchema<IS>, S>
|
|
95
|
-
|
|
96
|
-
export function state<IS extends IdSchema, S>(def: {
|
|
97
|
-
name: string
|
|
98
|
-
id: IS
|
|
99
|
-
initial: (id: InferIdFromSchema<IS>) => S
|
|
100
|
-
criteria: (id: InferIdFromSchema<IS>) => EventCriteria
|
|
101
|
-
evolve: Array<EvolverRegistration<S, any>>
|
|
117
|
+
evolve: (on: EvolverBuilder<S>) => Array<EvolverRegistration<S, any>>
|
|
102
118
|
lifecycle?: StateLifecycle<InferIdFromSchema<IS>, S>
|
|
103
119
|
}): StateModule<InferIdFromSchema<IS>, S> {
|
|
104
120
|
return {
|
|
@@ -107,7 +123,7 @@ export function state<IS extends IdSchema, S>(def: {
|
|
|
107
123
|
idSchema: def.id,
|
|
108
124
|
create: def.initial,
|
|
109
125
|
criteria: def.criteria,
|
|
110
|
-
evolvers: def.evolve,
|
|
126
|
+
evolvers: def.evolve(on as unknown as EvolverBuilder<S>),
|
|
111
127
|
lifecycle: def.lifecycle,
|
|
112
128
|
}
|
|
113
129
|
}
|