@astrale-os/kernel-dsl 0.2.0-beta.15 → 0.2.0-beta.18
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/CHANGELOG.md +221 -0
- package/dist/v1/builder/class/authoring.d.ts +19 -9
- package/dist/v1/builder/class/property.d.ts +13 -7
- package/dist/v1/builder/class/property.js +13 -5
- package/dist/v1/builder/index.d.ts +1 -1
- package/dist/v1/builder/index.js +1 -1
- package/dist/v1/builder/lowering/value/compile.js +8 -1
- package/dist/v1/builder/schema/projection.d.ts +8 -6
- package/dist/v1/compiled/admission/accept.js +39 -10
- package/dist/v1/compiled/compiler/compile.js +1 -1
- package/dist/v1/index.d.ts +3 -1
- package/dist/v1/index.js +2 -1
- package/dist/v1/language/class/model/property.d.ts +1 -2
- package/dist/v1/language/class/resolved.d.ts +4 -2
- package/dist/v1/language/index.d.ts +2 -0
- package/dist/v1/language/index.js +1 -0
- package/dist/v1/language/state/index.d.ts +3 -0
- package/dist/v1/language/state/index.js +1 -0
- package/dist/v1/language/state/machine.d.ts +28 -0
- package/dist/v1/language/state/machine.js +40 -0
- package/dist/v1/language/state/topology.d.ts +14 -0
- package/dist/v1/language/state/topology.js +69 -0
- package/dist/v1/schema/analysis/class.d.ts +2 -1
- package/dist/v1/schema/analysis/class.js +1 -1
- package/dist/v1/schema/compatibility/meaning.js +1 -1
- package/dist/v1/schema/diagnostic.d.ts +1 -1
- package/dist/v1/schema/normalization/domain.js +4 -1
- package/dist/v1/schema/validation/class.js +29 -3
- package/dist/v1/schema/validation/domain.structure.js +31 -1
- package/package.json +5 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.2.0-beta.18](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.17...kernel-dsl-v0.2.0-beta.18) (2026-08-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **dsl:** make StateProperty topology portable ([#534](https://github.com/astrale-os/kernel/issues/534)) ([f71cf87](https://github.com/astrale-os/kernel/commit/f71cf879e68475ffd002cafe6688be0649eb9c49))
|
|
9
|
+
|
|
10
|
+
## [0.2.0-beta.17](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.16...kernel-dsl-v0.2.0-beta.17) (2026-08-29)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### ⚠ BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
* View declarations now contain only target and optional description. Legacy View.auth fields are rejected; callable authorization, View.resolve admission, Policies, and Shell handshakes remain independent.
|
|
16
|
+
* **dsl:** make edge direction explicit
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* add aliased domain dependency projection ([afb799b](https://github.com/astrale-os/kernel/commit/afb799b0d61fd6f7436fe659f558a6a62ef1e7a1))
|
|
21
|
+
* add aliased Domain dependency projection ([9c4c4fb](https://github.com/astrale-os/kernel/commit/9c4c4fb4f942c0c5e3961faf4428ed299d42f847))
|
|
22
|
+
* add compiled remote domain serving ([ac9e365](https://github.com/astrale-os/kernel/commit/ac9e36538982a91359712e4cbbc68353ea2cc1a2))
|
|
23
|
+
* add compiled remote Domain serving ([6149628](https://github.com/astrale-os/kernel/commit/6149628820d1294981156ff5b50ceaa522ea0403))
|
|
24
|
+
* **callable:** preserve native binary streams and status ([d14c6f1](https://github.com/astrale-os/kernel/commit/d14c6f13492c14a3363b2c4af59c738034752fa2))
|
|
25
|
+
* **dsl:** authorize Edge value reads with policies ([#502](https://github.com/astrale-os/kernel/issues/502)) ([a27e129](https://github.com/astrale-os/kernel/commit/a27e129378ff64e69031a011cbfa21299998a35e))
|
|
26
|
+
* **dsl:** make edge direction explicit ([3f05bf5](https://github.com/astrale-os/kernel/commit/3f05bf52ce5b20e9f549ec0fd98cb0e4e03de1ea))
|
|
27
|
+
* remove Property visibility and cut DSL V2 ([#518](https://github.com/astrale-os/kernel/issues/518)) ([4d99e8f](https://github.com/astrale-os/kernel/commit/4d99e8f0837136cf6be257ab3a6df666b62e06b5))
|
|
28
|
+
* remove View authentication declarations ([4a5bfe0](https://github.com/astrale-os/kernel/commit/4a5bfe016717267d31257748f95e7f646782f876))
|
|
29
|
+
* **runtime:** implement auto property projection lifecycle ([#451](https://github.com/astrale-os/kernel/issues/451)) ([e0c484a](https://github.com/astrale-os/kernel/commit/e0c484a79f2d5314b6a54597c340bd09d3e4e566))
|
|
30
|
+
* **schema:** split inspection and add convergence ([6afbd39](https://github.com/astrale-os/kernel/commit/6afbd39506b8a9e37225aded1c02f94ffa64e54b))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* admit optional callable node paths ([#464](https://github.com/astrale-os/kernel/issues/464)) ([8f261d5](https://github.com/astrale-os/kernel/commit/8f261d54dfb489541d2976892c5cacadf688f1a1))
|
|
36
|
+
* **api:** retain visibility-free DSL as V1 ([#526](https://github.com/astrale-os/kernel/issues/526)) ([e24c1ea](https://github.com/astrale-os/kernel/commit/e24c1ea257e8567d9bd33c6ada0de63bb346a496))
|
|
37
|
+
* **boot:** point local host CLI at graph.query ([8341e10](https://github.com/astrale-os/kernel/commit/8341e1020cd32848ffb95de80e66936f17db3087))
|
|
38
|
+
* **boot:** point local host CLI at graph.query ([70c656b](https://github.com/astrale-os/kernel/commit/70c656bc7162b477a97ace4b999f8e7f6bf3a988))
|
|
39
|
+
* **ci:** enforce the official Kernel cohort ([#469](https://github.com/astrale-os/kernel/issues/469)) ([f6ea87a](https://github.com/astrale-os/kernel/commit/f6ea87a47f7b1f9c415e404dc1a09b480a2a3f5f))
|
|
40
|
+
* **core:** preserve callable identity and runtime boundaries ([#394](https://github.com/astrale-os/kernel/issues/394)) ([ad67dad](https://github.com/astrale-os/kernel/commit/ad67dad84aef3c8b79f769009595ea1f1229026b))
|
|
41
|
+
* **deps:** refresh the Kernel dependency cohort ([#393](https://github.com/astrale-os/kernel/issues/393)) ([883e7bb](https://github.com/astrale-os/kernel/commit/883e7bb7ce17eecb7dad1c94ad2089c576ba3746))
|
|
42
|
+
* **dsl:** close runtime facade contracts ([ff99450](https://github.com/astrale-os/kernel/commit/ff99450ce3889013f57c39293e7022b32e186ca6))
|
|
43
|
+
* **dsl:** close semantic qualification gaps ([4a48cd7](https://github.com/astrale-os/kernel/commit/4a48cd729bcaf839ceda880b26ade064d6505fe2))
|
|
44
|
+
* **dsl:** expose runtime-clean load paths ([7dba075](https://github.com/astrale-os/kernel/commit/7dba075887e4796e5464d5a41ddb03212eed887f))
|
|
45
|
+
* **dsl:** keep schema projections declaration-nameable ([#432](https://github.com/astrale-os/kernel/issues/432)) ([448d23d](https://github.com/astrale-os/kernel/commit/448d23d58fc2b564ef93be4a54dc8ebd385b5066))
|
|
46
|
+
* **dsl:** make schema declarations portable ([55e13c0](https://github.com/astrale-os/kernel/commit/55e13c06896eb5d6cf195607aec10f176b585504))
|
|
47
|
+
* **dsl:** make schema declarations portable ([90c04ac](https://github.com/astrale-os/kernel/commit/90c04acfa5af714c70a92dc90999675d53f159bc))
|
|
48
|
+
* **dsl:** preserve generic resolved domain type ([46f306b](https://github.com/astrale-os/kernel/commit/46f306bc3d1c73c822608c777a82f4502591d3e2))
|
|
49
|
+
* **dsl:** reject unknown authoring fields on edge endpoints ([0483aa9](https://github.com/astrale-os/kernel/commit/0483aa9d985459c873922262b6f60363ffb3902b))
|
|
50
|
+
* **dsl:** reject unknown authoring fields on edge endpoints ([cb90dae](https://github.com/astrale-os/kernel/commit/cb90dae6e165166ddcfe5e31ee2780d36b07ea53))
|
|
51
|
+
* **dsl:** reject unknown edge endpoint fields ([06a47ed](https://github.com/astrale-os/kernel/commit/06a47edf1bb1ba58d0ac7258e810ef2d20b30c69))
|
|
52
|
+
* **dsl:** reject unknown edge endpoint fields ([2d83dbf](https://github.com/astrale-os/kernel/commit/2d83dbf25a3e3818f9db2519b15741d109750727))
|
|
53
|
+
* **dsl:** trust exact generated build material ([#466](https://github.com/astrale-os/kernel/issues/466)) ([77f2686](https://github.com/astrale-os/kernel/commit/77f26862d8041928029c04da9f2b2521a101c17e))
|
|
54
|
+
* **packages:** keep workspace guard private ([e0ba76c](https://github.com/astrale-os/kernel/commit/e0ba76c5ae163245e31115e2a72e0663db0f5320))
|
|
55
|
+
* **packages:** keep workspace guard private ([d260a52](https://github.com/astrale-os/kernel/commit/d260a52329cde5ce4b0260c43a3bbf28cb78f408))
|
|
56
|
+
* **packages:** keep workspace guard private ([a3e82ec](https://github.com/astrale-os/kernel/commit/a3e82ec671f07252a5966b4de988e275e4078b8c))
|
|
57
|
+
* publish a TypeScript-compatible cohort ([#406](https://github.com/astrale-os/kernel/issues/406)) ([f1a0cd0](https://github.com/astrale-os/kernel/commit/f1a0cd09f2f0b4498f9fa8924b2e319cac6552b7))
|
|
58
|
+
* **release:** add package repository metadata ([8238077](https://github.com/astrale-os/kernel/commit/8238077d47a96c0f7b50a1bae8769fe4faab45b7))
|
|
59
|
+
* **release:** harden public package closure ([#397](https://github.com/astrale-os/kernel/issues/397)) ([5a5886f](https://github.com/astrale-os/kernel/commit/5a5886fe66c7b3ea0a014766a5df8c04fd93efeb))
|
|
60
|
+
* **schema:** harden introspection evidence and caches ([9516eb5](https://github.com/astrale-os/kernel/commit/9516eb510242427296861ef9e730b01861e45463))
|
|
61
|
+
* stabilize governed Kernel integration ([#347](https://github.com/astrale-os/kernel/issues/347)) ([6869e3f](https://github.com/astrale-os/kernel/commit/6869e3fc4de1e73ff701bb38383e89c934ddfdf2))
|
|
62
|
+
* **system:** clear Codegraph diagnostic debt ([f7a8e1f](https://github.com/astrale-os/kernel/commit/f7a8e1f5c5694d9c3c45d95fde184f0d5f2c7343))
|
|
63
|
+
* **system:** clear Codegraph diagnostic debt ([45f86a9](https://github.com/astrale-os/kernel/commit/45f86a9ce14a224efed0e07966a5df8d7a892078))
|
|
64
|
+
* **system:** preserve erased domain and runtime facade contracts ([b525d47](https://github.com/astrale-os/kernel/commit/b525d4781d2d58776ec6b4bbe1e045a3c1accebb))
|
|
65
|
+
* **system:** preserve public revision vocabulary ([5e990d0](https://github.com/astrale-os/kernel/commit/5e990d0b28578a040b80c508943552c46b8632ae))
|
|
66
|
+
* **test:** preserve authored semantic contracts ([bedb8cd](https://github.com/astrale-os/kernel/commit/bedb8cd2d36f4a95cb8d219067df0d0e39100f08))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Documentation
|
|
70
|
+
|
|
71
|
+
* **release:** align kernel beta changelogs ([ad59dbc](https://github.com/astrale-os/kernel/commit/ad59dbc8df458d8bd025692d594b0b4666cd2e1f))
|
|
72
|
+
|
|
73
|
+
## [0.2.0-beta.16](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.15...kernel-dsl-v0.2.0-beta.16) (2026-08-29)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Features
|
|
77
|
+
|
|
78
|
+
* remove Property visibility and cut DSL V2 ([#518](https://github.com/astrale-os/kernel/issues/518)) ([4d99e8f](https://github.com/astrale-os/kernel/commit/4d99e8f0837136cf6be257ab3a6df666b62e06b5))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### Bug Fixes
|
|
82
|
+
|
|
83
|
+
* **api:** retain visibility-free DSL as V1 ([#526](https://github.com/astrale-os/kernel/issues/526)) ([e24c1ea](https://github.com/astrale-os/kernel/commit/e24c1ea257e8567d9bd33c6ada0de63bb346a496))
|
|
84
|
+
|
|
85
|
+
## [0.2.0-beta.15](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.14...kernel-dsl-v0.2.0-beta.15) (2026-08-27)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
### Features
|
|
89
|
+
|
|
90
|
+
* **dsl:** authorize Edge value reads with policies ([#502](https://github.com/astrale-os/kernel/issues/502)) ([a27e129](https://github.com/astrale-os/kernel/commit/a27e129378ff64e69031a011cbfa21299998a35e))
|
|
91
|
+
|
|
92
|
+
## [0.2.0-beta.14](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.13...kernel-dsl-v0.2.0-beta.14) (2026-08-26)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
### Bug Fixes
|
|
96
|
+
|
|
97
|
+
* **ci:** enforce the official Kernel cohort ([#469](https://github.com/astrale-os/kernel/issues/469)) ([f6ea87a](https://github.com/astrale-os/kernel/commit/f6ea87a47f7b1f9c415e404dc1a09b480a2a3f5f))
|
|
98
|
+
|
|
99
|
+
## [0.2.0-beta.13](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.12...kernel-dsl-v0.2.0-beta.13) (2026-08-26)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### Features
|
|
103
|
+
|
|
104
|
+
* **runtime:** implement auto property projection lifecycle ([#451](https://github.com/astrale-os/kernel/issues/451)) ([e0c484a](https://github.com/astrale-os/kernel/commit/e0c484a79f2d5314b6a54597c340bd09d3e4e566))
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
### Bug Fixes
|
|
108
|
+
|
|
109
|
+
* **dsl:** trust exact generated build material ([#466](https://github.com/astrale-os/kernel/issues/466)) ([77f2686](https://github.com/astrale-os/kernel/commit/77f26862d8041928029c04da9f2b2521a101c17e))
|
|
110
|
+
|
|
111
|
+
## [0.2.0-beta.12](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.11...kernel-dsl-v0.2.0-beta.12) (2026-08-26)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
### Bug Fixes
|
|
115
|
+
|
|
116
|
+
* admit optional callable node paths ([#464](https://github.com/astrale-os/kernel/issues/464)) ([8f261d5](https://github.com/astrale-os/kernel/commit/8f261d54dfb489541d2976892c5cacadf688f1a1))
|
|
117
|
+
* **system:** clear Codegraph diagnostic debt ([f7a8e1f](https://github.com/astrale-os/kernel/commit/f7a8e1f5c5694d9c3c45d95fde184f0d5f2c7343))
|
|
118
|
+
|
|
119
|
+
## [0.2.0-beta.11](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.10...kernel-dsl-v0.2.0-beta.11) (2026-08-25)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
### Features
|
|
123
|
+
|
|
124
|
+
* **callable:** preserve native binary streams and status ([d14c6f1](https://github.com/astrale-os/kernel/commit/d14c6f13492c14a3363b2c4af59c738034752fa2))
|
|
125
|
+
* **schema:** split inspection and add convergence ([6afbd39](https://github.com/astrale-os/kernel/commit/6afbd39506b8a9e37225aded1c02f94ffa64e54b))
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
### Bug Fixes
|
|
129
|
+
|
|
130
|
+
* **schema:** harden introspection evidence and caches ([9516eb5](https://github.com/astrale-os/kernel/commit/9516eb510242427296861ef9e730b01861e45463))
|
|
131
|
+
|
|
132
|
+
## [0.2.0-beta.10](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.9...kernel-dsl-v0.2.0-beta.10) (2026-08-25)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
### Bug Fixes
|
|
136
|
+
|
|
137
|
+
* **dsl:** keep schema projections declaration-nameable ([#432](https://github.com/astrale-os/kernel/issues/432)) ([448d23d](https://github.com/astrale-os/kernel/commit/448d23d58fc2b564ef93be4a54dc8ebd385b5066))
|
|
138
|
+
|
|
139
|
+
## [0.2.0-beta.9](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.8...kernel-dsl-v0.2.0-beta.9) (2026-08-24)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
### Bug Fixes
|
|
143
|
+
|
|
144
|
+
* **packages:** keep workspace guard private ([e0ba76c](https://github.com/astrale-os/kernel/commit/e0ba76c5ae163245e31115e2a72e0663db0f5320))
|
|
145
|
+
* **packages:** keep workspace guard private ([d260a52](https://github.com/astrale-os/kernel/commit/d260a52329cde5ce4b0260c43a3bbf28cb78f408))
|
|
146
|
+
* **packages:** keep workspace guard private ([a3e82ec](https://github.com/astrale-os/kernel/commit/a3e82ec671f07252a5966b4de988e275e4078b8c))
|
|
147
|
+
|
|
148
|
+
## [0.2.0-beta.8](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.7...kernel-dsl-v0.2.0-beta.8) (2026-08-24)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
### Features
|
|
152
|
+
|
|
153
|
+
* add aliased domain dependency projection ([afb799b](https://github.com/astrale-os/kernel/commit/afb799b0d61fd6f7436fe659f558a6a62ef1e7a1))
|
|
154
|
+
* add aliased Domain dependency projection ([9c4c4fb](https://github.com/astrale-os/kernel/commit/9c4c4fb4f942c0c5e3961faf4428ed299d42f847))
|
|
155
|
+
|
|
156
|
+
## [0.2.0-beta.7](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.6...kernel-dsl-v0.2.0-beta.7) (2026-08-24)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
### Bug Fixes
|
|
160
|
+
|
|
161
|
+
* **dsl:** make schema declarations portable ([55e13c0](https://github.com/astrale-os/kernel/commit/55e13c06896eb5d6cf195607aec10f176b585504))
|
|
162
|
+
* publish a TypeScript-compatible cohort ([#406](https://github.com/astrale-os/kernel/issues/406)) ([f1a0cd0](https://github.com/astrale-os/kernel/commit/f1a0cd09f2f0b4498f9fa8924b2e319cac6552b7))
|
|
163
|
+
|
|
164
|
+
## [0.2.0-beta.6](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.5...kernel-dsl-v0.2.0-beta.6) (2026-08-23)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
### Bug Fixes
|
|
168
|
+
|
|
169
|
+
* **core:** preserve callable identity and runtime boundaries ([#394](https://github.com/astrale-os/kernel/issues/394)) ([ad67dad](https://github.com/astrale-os/kernel/commit/ad67dad84aef3c8b79f769009595ea1f1229026b))
|
|
170
|
+
* **deps:** refresh the Kernel dependency cohort ([#393](https://github.com/astrale-os/kernel/issues/393)) ([883e7bb](https://github.com/astrale-os/kernel/commit/883e7bb7ce17eecb7dad1c94ad2089c576ba3746))
|
|
171
|
+
* **dsl:** close runtime facade contracts ([ff99450](https://github.com/astrale-os/kernel/commit/ff99450ce3889013f57c39293e7022b32e186ca6))
|
|
172
|
+
* **dsl:** close semantic qualification gaps ([4a48cd7](https://github.com/astrale-os/kernel/commit/4a48cd729bcaf839ceda880b26ade064d6505fe2))
|
|
173
|
+
* **dsl:** expose runtime-clean load paths ([7dba075](https://github.com/astrale-os/kernel/commit/7dba075887e4796e5464d5a41ddb03212eed887f))
|
|
174
|
+
* **dsl:** preserve generic resolved domain type ([46f306b](https://github.com/astrale-os/kernel/commit/46f306bc3d1c73c822608c777a82f4502591d3e2))
|
|
175
|
+
* **release:** harden public package closure ([#397](https://github.com/astrale-os/kernel/issues/397)) ([5a5886f](https://github.com/astrale-os/kernel/commit/5a5886fe66c7b3ea0a014766a5df8c04fd93efeb))
|
|
176
|
+
* **system:** preserve erased domain and runtime facade contracts ([b525d47](https://github.com/astrale-os/kernel/commit/b525d4781d2d58776ec6b4bbe1e045a3c1accebb))
|
|
177
|
+
* **system:** preserve public revision vocabulary ([5e990d0](https://github.com/astrale-os/kernel/commit/5e990d0b28578a040b80c508943552c46b8632ae))
|
|
178
|
+
* **test:** preserve authored semantic contracts ([bedb8cd](https://github.com/astrale-os/kernel/commit/bedb8cd2d36f4a95cb8d219067df0d0e39100f08))
|
|
179
|
+
|
|
180
|
+
## [0.2.0-beta.5](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.4...kernel-dsl-v0.2.0-beta.5) (2026-08-21)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
### ⚠ BREAKING CHANGES
|
|
184
|
+
|
|
185
|
+
* View declarations now contain only target and optional description. Legacy View.auth fields are rejected; callable authorization, View.resolve admission, Policies, and Shell handshakes remain independent.
|
|
186
|
+
|
|
187
|
+
### Features
|
|
188
|
+
|
|
189
|
+
* remove View authentication declarations ([4a5bfe0](https://github.com/astrale-os/kernel/commit/4a5bfe016717267d31257748f95e7f646782f876))
|
|
190
|
+
|
|
191
|
+
## [0.2.0-beta.4](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.2.0-beta.3...kernel-dsl-v0.2.0-beta.4) (2026-08-21)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
### Bug Fixes
|
|
195
|
+
|
|
196
|
+
* **release:** add package repository metadata ([8238077](https://github.com/astrale-os/kernel/commit/8238077d47a96c0f7b50a1bae8769fe4faab45b7))
|
|
197
|
+
|
|
198
|
+
## [0.1.5](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.1.4...kernel-dsl-v0.1.5) (2026-08-07)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
### Features
|
|
202
|
+
|
|
203
|
+
* **dsl:** add non-breaking policy IR preview ([1202d29](https://github.com/astrale-os/kernel/commit/1202d294cc7f32bc8e3e29d7537d3604403d09a5))
|
|
204
|
+
* **dsl:** align policy authoring with v1 ([514961f](https://github.com/astrale-os/kernel/commit/514961f9902d97e96535126b0a983764bb0f30ac))
|
|
205
|
+
* **dsl:** align policy authoring with v1 ([d082d5e](https://github.com/astrale-os/kernel/commit/d082d5e923458c0eec4ee28358f1b41309067843))
|
|
206
|
+
|
|
207
|
+
## [0.1.4](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.1.3...kernel-dsl-v0.1.4) (2026-07-10)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
### Bug Fixes
|
|
211
|
+
|
|
212
|
+
* export ./package.json from all published packages ([9560a34](https://github.com/astrale-os/kernel/commit/9560a34379c68d475f09a863e9d1962b560d83a0))
|
|
213
|
+
* export ./package.json from all published packages ([8633acb](https://github.com/astrale-os/kernel/commit/8633acba8953644805fc43840732bd16c3e19ab1))
|
|
214
|
+
* export ./package.json in publishConfig.exports too — the map that ships ([85ba0a1](https://github.com/astrale-os/kernel/commit/85ba0a121466ed5ef33fced51d28c0d09a7c0ec4))
|
|
215
|
+
|
|
216
|
+
## [0.1.3](https://github.com/astrale-os/kernel/compare/kernel-dsl-v0.1.2...kernel-dsl-v0.1.3) (2026-07-08)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
### Features
|
|
220
|
+
|
|
221
|
+
* support top-level functions of the kernel domain ([db45b06](https://github.com/astrale-os/kernel/commit/db45b061d0a7562950277344778991592f0a19eb))
|
|
@@ -6,12 +6,13 @@ import type { ResolvedMethod } from '../../language/callable/resolved.js';
|
|
|
6
6
|
import type { MediaType } from '../../language/class/model/data.js';
|
|
7
7
|
import type { EdgeCount } from '../../language/class/model/edge.js';
|
|
8
8
|
import type { ResolvedClass, ResolvedProperty } from '../../language/class/resolved.js';
|
|
9
|
+
import type { StateTopology, StateTopologyOf } from '../../language/state/topology.js';
|
|
9
10
|
import type { Method, ProjectionOfCallable } from '../callable/authoring.js';
|
|
10
11
|
import type { Policy } from '../policy/authoring.js';
|
|
11
12
|
import type { Lazy } from '../schema/lazy.js';
|
|
12
13
|
import type { ClassProjectionOfResolved } from '../schema/projection.js';
|
|
13
14
|
import type { TypedValueSchema } from '../value/schema.js';
|
|
14
|
-
import type { AutoProperty, Property, PropertyOptions, ValueSchemaInput } from './property.js';
|
|
15
|
+
import type { AutoProperty, Property, PropertyOptions, PropertyStateMachineOf, ValueSchemaInput } from './property.js';
|
|
15
16
|
import type { PropertyRecordInput } from './property.js';
|
|
16
17
|
import { type AUTHORING } from '../schema/handle.js';
|
|
17
18
|
declare const CLASS_TYPE: unique symbol;
|
|
@@ -88,26 +89,27 @@ export type ClassInput = ({
|
|
|
88
89
|
readonly abstract: boolean;
|
|
89
90
|
} & Omit<UndirectedEdgeInput, 'orientation'>);
|
|
90
91
|
export type Class = NodeClass | EdgeClass;
|
|
91
|
-
export interface AuthoredPropertyProjection<out Input = unknown, out Output = unknown, out Required extends boolean = boolean, out Name extends string = string, out Owner = 'self'> {
|
|
92
|
+
export interface AuthoredPropertyProjection<out Input = unknown, out Output = unknown, out Required extends boolean = boolean, out Name extends string = string, out Owner = 'self', out State extends StateTopology | undefined = StateTopology | undefined> {
|
|
92
93
|
readonly input: Input;
|
|
93
94
|
readonly output: Output;
|
|
94
95
|
readonly required: Required;
|
|
95
96
|
readonly name: Name;
|
|
96
97
|
readonly owner: Owner;
|
|
98
|
+
readonly state?: State;
|
|
97
99
|
}
|
|
98
100
|
export interface AuthoredMethodProjection<out Value extends Method = Method, out Name extends string = string, out Owner = 'self'> {
|
|
99
101
|
readonly value: Value;
|
|
100
102
|
readonly name: Name;
|
|
101
103
|
readonly owner: Owner;
|
|
102
104
|
}
|
|
103
|
-
type PropertySchemaOf<Field> = Field extends AutoProperty<infer Value> ? PropertySchemaOf<Value> : Field extends Property<infer Schema, PropertyOptions> ? Schema : Field;
|
|
104
|
-
type PropertyOptionsOf<Field> = Field extends AutoProperty<infer Value> ? PropertyOptionsOf<Value> : Field extends Property<ValueSchemaInput, infer Options> ? Options : Record<never, never>;
|
|
105
|
+
type PropertySchemaOf<Field> = Field extends AutoProperty<infer Value> ? PropertySchemaOf<Value> : Field extends Property<infer Schema, PropertyOptions, unknown> ? Schema : Field;
|
|
106
|
+
type PropertyOptionsOf<Field> = Field extends AutoProperty<infer Value> ? PropertyOptionsOf<Value> : Field extends Property<ValueSchemaInput, infer Options, unknown> ? Options : Record<never, never>;
|
|
105
107
|
type ValueInputOf<Schema> = Schema extends TypedValueSchema<infer Value> ? Value : Schema extends z.ZodType ? z.input<Schema> : PortableValue;
|
|
106
108
|
type ValueOutputOf<Schema> = Schema extends TypedValueSchema<infer Value> ? Value : Schema extends z.ZodType ? z.output<Schema> : PortableValue;
|
|
107
109
|
type PropertyRequiredOf<Field> = PropertyOptionsOf<Field> extends {
|
|
108
110
|
readonly required: infer Required extends boolean;
|
|
109
111
|
} ? Required : undefined extends ValueInputOf<PropertySchemaOf<Field>> ? false : true;
|
|
110
|
-
type PropertyProjectionOf<Name extends string, Field> = AuthoredPropertyProjection<Field extends AutoProperty ? never : ValueInputOf<PropertySchemaOf<Field>>, ValueOutputOf<PropertySchemaOf<Field>>, PropertyRequiredOf<Field>, Name>;
|
|
112
|
+
type PropertyProjectionOf<Name extends string, Field> = AuthoredPropertyProjection<Field extends AutoProperty ? never : ValueInputOf<PropertySchemaOf<Field>>, ValueOutputOf<PropertySchemaOf<Field>>, PropertyRequiredOf<Field>, Name, 'self', Field extends Property ? StateTopologyOf<PropertyStateMachineOf<Field>> : undefined>;
|
|
111
113
|
type PropertyProjectionsOf<Input> = Input extends Readonly<Record<string, unknown>> ? {
|
|
112
114
|
readonly [Name in keyof Input]: PropertyProjectionOf<Extract<Name, string>, Input[Name]>;
|
|
113
115
|
} : Readonly<Record<never, never>>;
|
|
@@ -124,7 +126,7 @@ type ParentPropertyProjectionsOf<Input> = Input extends {
|
|
|
124
126
|
type EffectivePropertyProjectionsOf<Input> = PropertyProjectionEntriesOf<'properties' extends keyof Input ? Input extends {
|
|
125
127
|
readonly properties?: infer Value;
|
|
126
128
|
} ? NonNullable<Value> : never : never> | ParentPropertyProjectionsOf<Input>;
|
|
127
|
-
type BindPropertyOwners<Entries, Owner> = Entries extends AuthoredPropertyProjection<infer Input, infer Output, infer Required, infer Name, infer ExistingOwner> ? AuthoredPropertyProjection<Input, Output, Required, Name, ExistingOwner extends 'self' ? Owner : ExistingOwner> : Entries;
|
|
129
|
+
type BindPropertyOwners<Entries, Owner> = Entries extends AuthoredPropertyProjection<infer Input, infer Output, infer Required, infer Name, infer ExistingOwner, infer State> ? AuthoredPropertyProjection<Input, Output, Required, Name, ExistingOwner extends 'self' ? Owner : ExistingOwner, State> : Entries;
|
|
128
130
|
type MethodFieldsOf<Input> = 'methods' extends keyof Input ? Input extends {
|
|
129
131
|
readonly methods?: infer Methods extends Readonly<Record<string, Method>>;
|
|
130
132
|
} ? NonNullable<Methods> : Readonly<Record<never, never>> : Readonly<Record<never, never>>;
|
|
@@ -208,7 +210,7 @@ type UndirectedEdgeClassIdentity<Config> = Config extends {
|
|
|
208
210
|
readonly endpoints: Endpoints;
|
|
209
211
|
readonly constraints: Constraints;
|
|
210
212
|
} : never;
|
|
211
|
-
type OwnerErasedPropertyProjection<Entry> = Entry extends AuthoredPropertyProjection<infer Input, infer Output, infer Required, infer Name, unknown> ? AuthoredPropertyProjection<Input, Output, Required, Name, unknown> : Entry extends ResolvedProperty<infer Value, infer Required> & {
|
|
213
|
+
type OwnerErasedPropertyProjection<Entry> = Entry extends AuthoredPropertyProjection<infer Input, infer Output, infer Required, infer Name, unknown, infer State> ? AuthoredPropertyProjection<Input, Output, Required, Name, unknown, State> : Entry extends ResolvedProperty<infer Value, infer Required, infer State> & {
|
|
212
214
|
readonly name: infer Name;
|
|
213
215
|
readonly key: infer Key;
|
|
214
216
|
} ? {
|
|
@@ -216,6 +218,7 @@ type OwnerErasedPropertyProjection<Entry> = Entry extends AuthoredPropertyProjec
|
|
|
216
218
|
readonly required: Required;
|
|
217
219
|
readonly name: Name;
|
|
218
220
|
readonly key: Key;
|
|
221
|
+
readonly state?: State;
|
|
219
222
|
} : never;
|
|
220
223
|
type OwnerErasedMethodProjection<Entry> = Entry extends AuthoredMethodProjection<infer Value, infer Name, unknown> ? AuthoredMethodProjection<Value, Name, unknown> : Entry extends ResolvedMethod<infer Input, infer Output, infer Static, infer Inheritance, infer Auth, infer _Policy, infer Key> & {
|
|
221
224
|
readonly name: infer Name;
|
|
@@ -355,11 +358,18 @@ export declare const edgeClass: Readonly<{
|
|
|
355
358
|
directed<const Input extends Omit<DirectedEdgeInput, 'orientation'>>(input: Input & {
|
|
356
359
|
readonly source: ExactEndpointInput<Input['source'], DirectedSourceInput>;
|
|
357
360
|
readonly target: ExactEndpointInput<Input['target'], DirectedTargetInput>;
|
|
358
|
-
}): DirectedEdgeClass<CompactDirectedInput<Input>>;
|
|
361
|
+
} & WithoutStateProperties<Input>): DirectedEdgeClass<CompactDirectedInput<Input>>;
|
|
359
362
|
undirected<const Input extends Omit<UndirectedEdgeInput, 'orientation'>>(input: Input & {
|
|
360
363
|
readonly endpoints: readonly [ExactEndpointInput<Input['endpoints'][0], IncidentEndpointInput>, ExactEndpointInput<Input['endpoints'][1], IncidentEndpointInput>];
|
|
361
|
-
}): UndirectedEdgeClass<CompactUndirectedInput<Input>>;
|
|
364
|
+
} & WithoutStateProperties<Input>): UndirectedEdgeClass<CompactUndirectedInput<Input>>;
|
|
362
365
|
}>;
|
|
366
|
+
type WithoutStateProperties<Input> = Input extends {
|
|
367
|
+
readonly properties?: infer Properties extends Readonly<Record<string, unknown>>;
|
|
368
|
+
} ? {
|
|
369
|
+
readonly properties?: {
|
|
370
|
+
readonly [Name in keyof Properties]: Properties[Name] extends Property ? [PropertyStateMachineOf<Properties[Name]>] extends [never] ? Properties[Name] : never : Properties[Name];
|
|
371
|
+
};
|
|
372
|
+
} : unknown;
|
|
363
373
|
export type ProjectionOfClass<Value extends Class> = Value extends NodeClass<infer Config> ? Config : Value extends DirectedEdgeClass<infer Input> ? Input : Value extends UndirectedEdgeClass<infer Input> ? Input : never;
|
|
364
374
|
export declare function classConfiguration(value: NodeClass): NodeClassInput;
|
|
365
375
|
export declare function classConfiguration(value: DirectedEdgeClass): Omit<DirectedEdgeInput, 'orientation'>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
2
|
import type { AutoEvent, AutoSet } from '../../language/class/model/property.js';
|
|
3
|
+
import type { StateMachine } from '../../language/state/index.js';
|
|
3
4
|
import type { JsonSchema } from '../../language/value/model/schema.js';
|
|
4
5
|
import type { AUTHORING } from '../schema/handle.js';
|
|
5
6
|
declare const PROPERTY_INPUT: unique symbol;
|
|
6
7
|
declare const AUTO_INPUT: unique symbol;
|
|
7
8
|
export type ValueSchemaInput = z.ZodType | JsonSchema;
|
|
8
9
|
export interface PropertyOptions {
|
|
9
|
-
readonly visibility?: 'public' | 'private';
|
|
10
10
|
readonly required?: boolean;
|
|
11
11
|
readonly description?: string;
|
|
12
12
|
}
|
|
@@ -14,15 +14,17 @@ export interface AutoOptions {
|
|
|
14
14
|
readonly on: AutoEvent | readonly AutoEvent[];
|
|
15
15
|
readonly set: AutoSet;
|
|
16
16
|
}
|
|
17
|
-
export interface Property<out Schema extends ValueSchemaInput = ValueSchemaInput, out Options extends PropertyOptions = PropertyOptions> {
|
|
17
|
+
export interface Property<out Schema extends ValueSchemaInput = ValueSchemaInput, out Options extends PropertyOptions = PropertyOptions, out Machine = unknown> {
|
|
18
18
|
readonly [AUTHORING]: 'property';
|
|
19
19
|
readonly [PROPERTY_INPUT]: {
|
|
20
20
|
readonly schema: Schema;
|
|
21
21
|
readonly options: Options;
|
|
22
|
+
readonly machine?: Machine;
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
|
-
export type PropertySchemaOf<Value extends Property> = Value extends Property<infer Schema, PropertyOptions> ? Schema : never;
|
|
25
|
-
export type PropertyOptionsOf<Value extends Property> = Value extends Property<ValueSchemaInput, infer Options> ? Options : never;
|
|
25
|
+
export type PropertySchemaOf<Value extends Property> = Value extends Property<infer Schema, PropertyOptions, unknown> ? Schema : never;
|
|
26
|
+
export type PropertyOptionsOf<Value extends Property> = Value extends Property<ValueSchemaInput, infer Options, unknown> ? Options : never;
|
|
27
|
+
export type PropertyStateMachineOf<Value extends Property> = Value extends Property<ValueSchemaInput, PropertyOptions, infer Machine> ? Machine : never;
|
|
26
28
|
export interface AutoProperty<out PropertyValue extends Property = Property> {
|
|
27
29
|
readonly [AUTHORING]: 'auto';
|
|
28
30
|
readonly [AUTO_INPUT]: {
|
|
@@ -33,9 +35,10 @@ export interface AutoProperty<out PropertyValue extends Property = Property> {
|
|
|
33
35
|
};
|
|
34
36
|
};
|
|
35
37
|
}
|
|
36
|
-
export type PropertyAuthoringInput<Value extends Property> = Value extends Property<infer Schema, infer Options> ? {
|
|
38
|
+
export type PropertyAuthoringInput<Value extends Property> = Value extends Property<infer Schema, infer Options, infer Machine> ? {
|
|
37
39
|
readonly schema: Schema;
|
|
38
40
|
readonly options: Options;
|
|
41
|
+
readonly machine?: Machine;
|
|
39
42
|
} : never;
|
|
40
43
|
export declare function propertyAuthoringInput<const Value extends Property>(value: Value): PropertyAuthoringInput<Value>;
|
|
41
44
|
export declare function autoPropertyAuthoringInput<const Value extends AutoProperty>(value: Value): Value extends AutoProperty<infer Property> ? {
|
|
@@ -47,6 +50,9 @@ export declare function autoPropertyAuthoringInput<const Value extends AutoPrope
|
|
|
47
50
|
} : never;
|
|
48
51
|
export type PropertyFieldInput = ValueSchemaInput | Property | AutoProperty;
|
|
49
52
|
export type PropertyRecordInput = Readonly<Record<string, PropertyFieldInput>>;
|
|
50
|
-
export declare function property<const Schema extends ValueSchemaInput, const Options extends PropertyOptions = Record<never, never>>(schema: Schema, options?: Options): Property<Schema, Options>;
|
|
51
|
-
export declare function
|
|
53
|
+
export declare function property<const Schema extends ValueSchemaInput, const Options extends PropertyOptions = Record<never, never>>(schema: Schema, options?: Options): Property<Schema, Options, never>;
|
|
54
|
+
export declare function stateProperty<const Machine extends StateMachine, const Options extends Omit<PropertyOptions, 'required'> = Record<never, never>>(machine: Machine, options?: Options & Record<Exclude<keyof Options, 'description'>, never>): Property<Machine['stateSchema'], Readonly<Options & {
|
|
55
|
+
readonly required: true;
|
|
56
|
+
}>, Machine>;
|
|
57
|
+
export declare function auto<const PropertyValue extends Property>(property: [PropertyStateMachineOf<PropertyValue>] extends [never] ? PropertyValue : never, options: AutoOptions): AutoProperty<PropertyValue>;
|
|
52
58
|
export {};
|
|
@@ -10,14 +10,22 @@ export function autoPropertyAuthoringInput(value) {
|
|
|
10
10
|
}
|
|
11
11
|
export function property(schema, options) {
|
|
12
12
|
const admitted = options ?? {};
|
|
13
|
-
assertKnownKeys(admitted, ['
|
|
13
|
+
assertKnownKeys(admitted, ['required', 'description']);
|
|
14
14
|
return authoringValue('property', {
|
|
15
15
|
[PROPERTY_INPUT]: {
|
|
16
16
|
schema,
|
|
17
|
-
options:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
options: admitted,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export function stateProperty(machine, options) {
|
|
22
|
+
const admitted = options ?? {};
|
|
23
|
+
assertKnownKeys(admitted, ['description']);
|
|
24
|
+
return authoringValue('property', {
|
|
25
|
+
[PROPERTY_INPUT]: {
|
|
26
|
+
schema: machine.stateSchema,
|
|
27
|
+
options: { ...admitted, required: true },
|
|
28
|
+
machine,
|
|
21
29
|
},
|
|
22
30
|
});
|
|
23
31
|
}
|
|
@@ -4,7 +4,7 @@ export { defineClass, edgeClass, nodeClass } from './class/authoring.js';
|
|
|
4
4
|
export { fullMatch } from './value/full-match.js';
|
|
5
5
|
export { path } from './value/path.js';
|
|
6
6
|
export { policy } from './policy/authoring.js';
|
|
7
|
-
export { auto, property } from './class/property.js';
|
|
7
|
+
export { auto, property, stateProperty } from './class/property.js';
|
|
8
8
|
export { defineSchema } from './schema/define.js';
|
|
9
9
|
export type { DefinedSchema } from './schema/define.js';
|
|
10
10
|
export type { ResolvedDomainOfInput } from './schema/projection.js';
|
package/dist/v1/builder/index.js
CHANGED
|
@@ -4,7 +4,7 @@ export { defineClass, edgeClass, nodeClass } from './class/authoring.js';
|
|
|
4
4
|
export { fullMatch } from './value/full-match.js';
|
|
5
5
|
export { path } from './value/path.js';
|
|
6
6
|
export { policy } from './policy/authoring.js';
|
|
7
|
-
export { auto, property } from './class/property.js';
|
|
7
|
+
export { auto, property, stateProperty } from './class/property.js';
|
|
8
8
|
export { defineSchema } from './schema/define.js';
|
|
9
9
|
export { valueSchema } from './value/schema.js';
|
|
10
10
|
export { view } from './view/authoring.js';
|
|
@@ -36,11 +36,18 @@ export class BuilderValueSchemas {
|
|
|
36
36
|
compiled[name] = {
|
|
37
37
|
schema: canonicalizeValueSchema(schema, 'property-facet', this.registry),
|
|
38
38
|
required: authoredInput?.options.required ?? isRequired(schemaInput),
|
|
39
|
-
visibility: authoredInput?.options.visibility ?? 'public',
|
|
40
39
|
...(autoInput === undefined ? {} : { auto: autoInput.options }),
|
|
41
40
|
...(authoredInput?.options.description === undefined
|
|
42
41
|
? {}
|
|
43
42
|
: { description: authoredInput.options.description }),
|
|
43
|
+
...(authoredInput?.machine === undefined
|
|
44
|
+
? {}
|
|
45
|
+
: {
|
|
46
|
+
state: {
|
|
47
|
+
initial: authoredInput.machine.initial,
|
|
48
|
+
transitions: authoredInput.machine.transitions,
|
|
49
|
+
},
|
|
50
|
+
}),
|
|
44
51
|
};
|
|
45
52
|
}
|
|
46
53
|
return compiled;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import type { Revision } from '../../addressing/index.js';
|
|
2
2
|
import type * as domain from '../../domain/model/domain.js';
|
|
3
3
|
import type * as language from '../../language/index.js';
|
|
4
|
+
import type { StateTopology } from '../../language/state/index.js';
|
|
4
5
|
import type { DomainOfSchema, DomainSchema } from '../../schema/model/schema.js';
|
|
5
6
|
import type { CallableProjection, Function, Method } from '../callable/authoring.js';
|
|
6
7
|
import type { AuthoredPropertyProjection, AuthoredMethodProjection, Class, ClassIdentityProjection, ClassIdentityProjectionOf, ClassOwnerProjection, ClassOwnerProjectionOf, ClassReferenceProjection, ClassReferenceProjectionOf, DirectedEdgeClass, NodeClass, ProjectionOfClass, UndirectedEdgeClass } from '../class/authoring.js';
|
|
7
8
|
import type { DomainSchemaInput } from './input.js';
|
|
8
|
-
export interface PropertyProjection<Value = unknown, Required extends boolean = boolean, Name extends string = string, Key extends language.PropertyKey = language.PropertyKey> {
|
|
9
|
+
export interface PropertyProjection<Value = unknown, Required extends boolean = boolean, Name extends string = string, Key extends language.PropertyKey = language.PropertyKey, State extends StateTopology | undefined = StateTopology | undefined> {
|
|
9
10
|
readonly value: Value;
|
|
10
11
|
readonly required: Required;
|
|
11
12
|
readonly name: Name;
|
|
12
13
|
readonly key: Key;
|
|
14
|
+
readonly state?: State;
|
|
13
15
|
}
|
|
14
16
|
export interface MethodProjection<Input = unknown, Output = unknown, Static extends boolean = boolean, Inheritance extends language.MethodInheritance = language.MethodInheritance, Auth extends language.FunctionAuth = language.FunctionAuth, Name extends string = string, Key extends language.MethodKey = language.MethodKey> {
|
|
15
17
|
readonly input: Input;
|
|
@@ -256,10 +258,10 @@ type CallableAuthOf<Value extends Method | Function> = CallableConfig<Value>['au
|
|
|
256
258
|
type MethodProjectionOfEntry<Origin extends string, OwnerName extends string, Entry> = Entry extends language.ResolvedMethod ? MethodProjectionOfResolved<Entry> : Entry extends AuthoredMethodEntry<unknown, infer Name, infer Value> ? MethodProjection<CallableInputValue<Value>, CallableOutputValue<Value>, CallableStaticOf<Value>, CallableInheritanceOf<Value>, CallableAuthOf<Value>, Name, language.MethodKey<Origin, OwnerName, Name>> : never;
|
|
257
259
|
type MethodProjectionOfEntries<Origin extends string, OwnerName extends string, Entries> = Entries extends unknown ? MethodProjectionOfEntry<Origin, OwnerName, Entries> : never;
|
|
258
260
|
type MethodCollectionOperation = 'byKey' | 'get';
|
|
259
|
-
type PropertyProjectionOfResolved<Value> = Value extends language.ResolvedProperty<infer PropertyValue, infer Required> & {
|
|
261
|
+
type PropertyProjectionOfResolved<Value> = Value extends language.ResolvedProperty<infer PropertyValue, infer Required, infer State> & {
|
|
260
262
|
readonly name: infer Name extends string;
|
|
261
263
|
readonly key: infer Key extends language.PropertyKey;
|
|
262
|
-
} ? PropertyProjection<PropertyValue, Required, Name, Key> : never;
|
|
264
|
+
} ? PropertyProjection<PropertyValue, Required, Name, Key, State> : never;
|
|
263
265
|
type MethodProjectionOfResolved<Value> = Value extends language.ResolvedMethod<infer Input, infer Output, infer Static, infer Inheritance, infer Auth, infer _Policy, infer Key> & {
|
|
264
266
|
readonly name: infer Name extends string;
|
|
265
267
|
} ? MethodProjection<Input, Output, Static, Inheritance, Auth, Name, Key> : never;
|
|
@@ -288,12 +290,12 @@ type ShallowClassProjectionTupleOfResolved<Parents extends readonly unknown[]> =
|
|
|
288
290
|
type ExactClass<Value> = Value extends {
|
|
289
291
|
readonly key: infer Key extends language.DefinitionKey<string, 'class'>;
|
|
290
292
|
} ? Key extends `${infer Origin}:class.${infer Name}` ? string extends Origin ? never : string extends Name ? never : Value : never : never;
|
|
291
|
-
type OwnPropertyProjectionsOf<Origin extends string, Name extends string, Value> = OwnPropertyEntries<Value> extends infer Entry ? Entry extends AuthoredPropertyEntry<unknown, infer PropertyName, infer Field> ? Field extends AuthoredPropertyProjection<unknown, infer Output, infer Required> ? PropertyProjection<Output, Required, PropertyName, language.PropertyKey<Origin, Name, PropertyName
|
|
293
|
+
type OwnPropertyProjectionsOf<Origin extends string, Name extends string, Value> = OwnPropertyEntries<Value> extends infer Entry ? Entry extends AuthoredPropertyEntry<unknown, infer PropertyName, infer Field> ? Field extends AuthoredPropertyProjection<unknown, infer Output, infer Required, string, unknown, infer State> ? PropertyProjection<Output, Required, PropertyName, language.PropertyKey<Origin, Name, PropertyName>, State> : never : never : never;
|
|
292
294
|
type EffectivePropertyEntriesOfClass<Value> = ClassInputOf<Value> extends {
|
|
293
295
|
readonly effectiveProperties: infer Properties;
|
|
294
296
|
} ? Properties : never;
|
|
295
297
|
type OwnerNameOf<Root extends DomainSchemaInput, CurrentName extends string, Owner> = Owner extends 'self' ? CurrentName : Owner extends ClassOwnerProjection ? Extract<LocalNameOfOwner<Root, Owner>, string> : Owner extends ClassIdentityProjection ? Extract<LocalNameOfIdentity<Root, Owner>, string> : never;
|
|
296
|
-
type EffectivePropertyProjectionOfEntry<Origin extends string, CurrentName extends string, Root extends DomainSchemaInput, Entry> = Entry extends language.ResolvedProperty ? PropertyProjectionOfResolved<Entry> : Entry extends AuthoredPropertyProjection<unknown, infer Output, infer Required, infer PropertyName, infer Owner> ? OwnerNameOf<Root, CurrentName, Owner> extends infer OwnerName extends string ? PropertyProjection<Output, Required, PropertyName, language.PropertyKey<Origin, OwnerName, PropertyName
|
|
298
|
+
type EffectivePropertyProjectionOfEntry<Origin extends string, CurrentName extends string, Root extends DomainSchemaInput, Entry> = Entry extends language.ResolvedProperty ? PropertyProjectionOfResolved<Entry> : Entry extends AuthoredPropertyProjection<unknown, infer Output, infer Required, infer PropertyName, infer Owner, infer State> ? OwnerNameOf<Root, CurrentName, Owner> extends infer OwnerName extends string ? PropertyProjection<Output, Required, PropertyName, language.PropertyKey<Origin, OwnerName, PropertyName>, State> : never : never;
|
|
297
299
|
type EffectivePropertyProjectionsOf<Origin extends string, Name extends string, Value, Root extends DomainSchemaInput> = EffectivePropertyEntriesOfClass<Value> extends infer Entry ? Entry extends unknown ? EffectivePropertyProjectionOfEntry<Origin, Name, Root, Entry> : never : never;
|
|
298
300
|
type OwnInstanceMethodProjectionsOf<Origin extends string, Name extends string, Value> = MethodProjectionOfEntries<Origin, Name, OwnMethodEntries<Value, false>>;
|
|
299
301
|
type OwnStaticMethodProjectionsOf<Origin extends string, Name extends string, Value> = MethodProjectionOfEntries<Origin, Name, OwnMethodEntries<Value, true>>;
|
|
@@ -316,7 +318,7 @@ type ClassProjectionOfAuthoring<Origin extends string, Name extends string, Valu
|
|
|
316
318
|
type FunctionProjectionOfAuthoring<Origin extends string, Name extends string, Value> = Value extends Function ? FunctionProjection<CallableInputValue<Value>, CallableOutputValue<Value>, CallableAuthOf<Value>, language.FunctionRef<Name> & {
|
|
317
319
|
readonly origin: Origin;
|
|
318
320
|
}, language.DefinitionKey<Origin, 'function', Name>> : never;
|
|
319
|
-
type ResolvedPropertyOfProjection<Value> = Value extends PropertyProjection<infer PropertyValue, infer Required, infer Name, infer Key> ? language.ResolvedProperty<PropertyValue, Required> & {
|
|
321
|
+
type ResolvedPropertyOfProjection<Value> = Value extends PropertyProjection<infer PropertyValue, infer Required, infer Name, infer Key, infer State> ? language.ResolvedProperty<PropertyValue, Required, State> & {
|
|
320
322
|
readonly name: Name;
|
|
321
323
|
readonly key: Key;
|
|
322
324
|
} : never;
|
|
@@ -4,6 +4,7 @@ import { isDefinitionRef, Key } from '../../addressing/index.js';
|
|
|
4
4
|
import { DEPENDENCY_ALIAS_PATTERN, DOMAIN_ORIGIN_PATTERN, DOMAIN_REVISION_PATTERN, MEMBER_NAME_PATTERN, } from '../../addressing/patterns.js';
|
|
5
5
|
import { MEDIA_TYPE_PATTERN } from '../../language/class/model/data.js';
|
|
6
6
|
import { PropertyValues } from '../../language/class/property-values.js';
|
|
7
|
+
import { admitStateTopology } from '../../language/state/topology.js';
|
|
7
8
|
import { classifyValueProgramOrdering } from '../../language/value/ordering.js';
|
|
8
9
|
import { invalidCompiled } from '../diagnostic.js';
|
|
9
10
|
import { revisionOfCompiledEntry } from './revision.js';
|
|
@@ -158,10 +159,8 @@ function compiledClass(input, values, path) {
|
|
|
158
159
|
const parents = array(value.extends, 'Class extends', extendsPath).map((parent, index) => definitionRef(parent, 'class', 'Class parent', `${extendsPath}/${index}`));
|
|
159
160
|
unique(parents.map(Key.of), 'Class parents', extendsPath);
|
|
160
161
|
const propertiesPath = `${path}/properties`;
|
|
161
|
-
const properties = array(value.properties, 'Class properties', propertiesPath);
|
|
162
|
-
|
|
163
|
-
compiledProperty(property, values, `${propertiesPath}/${index}`);
|
|
164
|
-
unique(properties.map((property, index) => string(object(property, 'Compiled Property', `${propertiesPath}/${index}`).name, 'Property name', `${propertiesPath}/${index}/name`)), 'Class Properties', propertiesPath);
|
|
162
|
+
const properties = array(value.properties, 'Class properties', propertiesPath).map((property, index) => compiledProperty(property, values, value.kind === 'node', `${propertiesPath}/${index}`));
|
|
163
|
+
unique(properties.map((property) => property.name), 'Class Properties', propertiesPath);
|
|
165
164
|
if (value.kind === 'node') {
|
|
166
165
|
if (value.data !== undefined)
|
|
167
166
|
dataDefinition(value.data, `${path}/data`);
|
|
@@ -177,7 +176,7 @@ function compiledClass(input, values, path) {
|
|
|
177
176
|
classPolicies(value.policies, `${path}/policies`);
|
|
178
177
|
edgeContract(value, path);
|
|
179
178
|
}
|
|
180
|
-
return value;
|
|
179
|
+
return { ...value, properties };
|
|
181
180
|
}
|
|
182
181
|
function compiledFunction(input, values, path) {
|
|
183
182
|
const value = object(input, 'Compiled Function', path);
|
|
@@ -185,25 +184,55 @@ function compiledFunction(input, values, path) {
|
|
|
185
184
|
definitionRef(value.ref, 'function', 'Function ref', `${path}/ref`);
|
|
186
185
|
return value;
|
|
187
186
|
}
|
|
188
|
-
function compiledProperty(input, values, path) {
|
|
187
|
+
function compiledProperty(input, values, node, path) {
|
|
189
188
|
const value = object(input, 'Compiled Property', path);
|
|
190
|
-
exact(value, ['name', 'required', '
|
|
189
|
+
exact(value, ['name', 'required', 'value'], 'Compiled Property', path, [
|
|
191
190
|
'auto',
|
|
192
191
|
'description',
|
|
193
192
|
'ordering',
|
|
193
|
+
'state',
|
|
194
194
|
]);
|
|
195
195
|
memberName(value.name, 'Property name', `${path}/name`);
|
|
196
196
|
boolean(value.required, 'Property required', `${path}/required`);
|
|
197
|
-
if (value.visibility !== 'public' && value.visibility !== 'private') {
|
|
198
|
-
invalid('Property visibility', undefined, `${path}/visibility`);
|
|
199
|
-
}
|
|
200
197
|
description(value.description, 'Property description', `${path}/description`);
|
|
201
198
|
if (value.auto !== undefined)
|
|
202
199
|
propertyAuto(value.auto, `${path}/auto`);
|
|
203
200
|
const valueIndex = index(value.value, values.length, 'Property value', `${path}/value`);
|
|
201
|
+
let state;
|
|
202
|
+
if (value.state !== undefined) {
|
|
203
|
+
if (!node)
|
|
204
|
+
invalid('Property state placement', 'COMPILED_SOURCE_INVALID', `${path}/state`);
|
|
205
|
+
let topology;
|
|
206
|
+
try {
|
|
207
|
+
topology = admitStateTopology(value.state);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
invalid('Property state topology', 'COMPILED_SOURCE_INVALID', `${path}/state`);
|
|
211
|
+
}
|
|
212
|
+
const program = values[valueIndex];
|
|
213
|
+
const schema = program.nodes[program.root].schema;
|
|
214
|
+
const states = Object.keys(topology.transitions);
|
|
215
|
+
const schemaObject = schema;
|
|
216
|
+
const schemaMatches = schema !== null &&
|
|
217
|
+
typeof schema === 'object' &&
|
|
218
|
+
!Array.isArray(schema) &&
|
|
219
|
+
Object.keys(schemaObject).length === 2 &&
|
|
220
|
+
schemaObject.type === 'string' &&
|
|
221
|
+
Array.isArray(schemaObject.enum) &&
|
|
222
|
+
schemaObject.enum.length === states.length &&
|
|
223
|
+
schemaObject.enum.every((state, index) => state === states[index]);
|
|
224
|
+
if (!value.required || value.auto !== undefined || !schemaMatches) {
|
|
225
|
+
invalid('Property state contract', 'COMPILED_SOURCE_INVALID', `${path}/state`);
|
|
226
|
+
}
|
|
227
|
+
state = topology;
|
|
228
|
+
}
|
|
204
229
|
if (value.ordering !== classifyValueProgramOrdering(values[valueIndex])) {
|
|
205
230
|
invalid('Property ordering', 'COMPILED_CANONICAL_MISMATCH', `${path}/ordering`);
|
|
206
231
|
}
|
|
232
|
+
return {
|
|
233
|
+
...value,
|
|
234
|
+
...(state === undefined ? {} : { state }),
|
|
235
|
+
};
|
|
207
236
|
}
|
|
208
237
|
function compiledCallable(input, values, method, path) {
|
|
209
238
|
const value = object(input, 'Compiled Callable', path);
|
|
@@ -37,9 +37,9 @@ function compileEntry(schema, lookup) {
|
|
|
37
37
|
return {
|
|
38
38
|
name,
|
|
39
39
|
required: property.required,
|
|
40
|
-
visibility: property.visibility,
|
|
41
40
|
...(property.auto === undefined ? {} : { auto: property.auto }),
|
|
42
41
|
...(property.description === undefined ? {} : { description: property.description }),
|
|
42
|
+
...(property.state === undefined ? {} : { state: property.state }),
|
|
43
43
|
...(ordering === undefined ? {} : { ordering }),
|
|
44
44
|
value: add(property.schema, `${pointer}/properties/${name}/schema`),
|
|
45
45
|
};
|
package/dist/v1/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Stable aggregate facade for the V1 language. */
|
|
2
|
-
export { auto, core, defineClass, defineSchema, edgeClass, func, fullMatch, method, nodeClass, output, path, policy, property, valueSchema, view, } from './builder/index.js';
|
|
2
|
+
export { auto, core, defineClass, defineSchema, edgeClass, func, fullMatch, method, nodeClass, output, path, policy, property, stateProperty, valueSchema, view, } from './builder/index.js';
|
|
3
|
+
export { stateMachine } from './language/state/index.js';
|
|
4
|
+
export type { EventOf, StateMachine, StateOf } from './language/state/index.js';
|
|
3
5
|
export { PropertyValues } from './language/index.js';
|
|
4
6
|
export * as metadata from './language/definition/metadata.js';
|
|
5
7
|
export type { AnyResolvedClass, BoundMethodOf, BoundMethodShortcutsOf, CallableResultOf, CallableInputOf, CallableOutputOf, ClassSatisfactionKeysOf, ClassDefinition, CoreDefinition, CoreEdge, FunctionAuth, FunctionDefinition, MethodDefinition, MethodInheritance, MethodOwnerKeyOf, PolicyCheckExpression, PolicyDefinition, PropertyInputOf, PropertyAccessOf, PropertyOutputOf, PropertyShortcutsOf, PropertyValuesOf, ResolvedClass, ResolvedCoreDefinition, ResolvedData, ResolvedFunction, ResolvedMethod, ResolvedMethodCollection, ResolvedPolicy, ResolvedProperty, ResolvedView, MethodAccessOf, SelfMethodsOf, SelfPropertiesOf, SelfStaticMethodsOf, StaticMethodsOf, ViewDefinition, } from './language/index.js';
|
package/dist/v1/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Stable aggregate facade for the V1 language. */
|
|
2
|
-
export { auto, core, defineClass, defineSchema, edgeClass, func, fullMatch, method, nodeClass, output, path, policy, property, valueSchema, view, } from './builder/index.js';
|
|
2
|
+
export { auto, core, defineClass, defineSchema, edgeClass, func, fullMatch, method, nodeClass, output, path, policy, property, stateProperty, valueSchema, view, } from './builder/index.js';
|
|
3
|
+
export { stateMachine } from './language/state/index.js';
|
|
3
4
|
export { PropertyValues } from './language/index.js';
|
|
4
5
|
export * as metadata from './language/definition/metadata.js';
|
|
5
6
|
export { acceptDefinitionRef, callableAddress, ClassKey, equalDefinitionRefs, isDefinitionRef, Key, MethodKey, PropertyKey, } from './addressing/index.js';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export type PropertyVisibility = 'public' | 'private';
|
|
2
1
|
export type AutoEvent = 'create' | 'update';
|
|
3
2
|
export type AutoSet = 'instant';
|
|
4
3
|
export interface PropertyAuto {
|
|
@@ -8,9 +7,9 @@ export interface PropertyAuto {
|
|
|
8
7
|
export interface PropertyDefinition {
|
|
9
8
|
readonly schema: import('../../value/model/schema.js').JsonSchema;
|
|
10
9
|
readonly required: boolean;
|
|
11
|
-
readonly visibility: PropertyVisibility;
|
|
12
10
|
readonly auto?: PropertyAuto;
|
|
13
11
|
readonly description?: string;
|
|
12
|
+
readonly state?: import('../../state/index.js').StateTopology;
|
|
14
13
|
}
|
|
15
14
|
export type PropertyRecord = Readonly<Record<string, PropertyDefinition>>;
|
|
16
15
|
export interface PropertyFacet {
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import type { Value as PortableValue } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import type { ClassRef, DefinitionKey, Key, PolicyRef, PropertyKey } from '../../addressing/index.js';
|
|
3
3
|
import type { ResolvedMethodCollection } from '../callable/resolved.js';
|
|
4
|
+
import type { StateTopology } from '../state/index.js';
|
|
4
5
|
import type { Diagnostic } from '../validation/diagnostic.js';
|
|
5
6
|
import type { OrderingKind } from '../value/ordering.js';
|
|
6
7
|
import type { ClassDefinition, ClassKind } from './model/class.js';
|
|
7
8
|
import type { DataDefinition } from './model/data.js';
|
|
8
9
|
import type { PropertyDefinition } from './model/property.js';
|
|
9
10
|
import type { PropertyValues } from './property-values.js';
|
|
10
|
-
export interface ResolvedProperty<out Value = PortableValue, out Required extends boolean = boolean> {
|
|
11
|
+
export interface ResolvedProperty<out Value = PortableValue, out Required extends boolean = boolean, out State extends StateTopology | undefined = StateTopology | undefined> {
|
|
11
12
|
readonly owner: AnyResolvedClass;
|
|
12
13
|
readonly name: string;
|
|
13
14
|
readonly key: PropertyKey;
|
|
14
|
-
readonly definition: PropertyDefinition & {
|
|
15
|
+
readonly definition: Omit<PropertyDefinition, 'required' | 'state'> & {
|
|
15
16
|
readonly required: Required;
|
|
17
|
+
readonly state?: State;
|
|
16
18
|
};
|
|
17
19
|
/** The one portable scalar ordering domain, when the Property is orderable. */
|
|
18
20
|
readonly ordering?: OrderingKind;
|
|
@@ -2,6 +2,8 @@ export type { ClassRef, CoreRef, DefinitionBase, DefinitionKey, DefinitionRef, F
|
|
|
2
2
|
export type { Value as PropertyValue } from '@astrale-os/kernel-dsl/value';
|
|
3
3
|
export type { JsonSchema as ValueSchema, JsonSchemaObject as ValueSchemaObject, } from './value/model/schema.js';
|
|
4
4
|
export type { OrderingKind } from './value/ordering.js';
|
|
5
|
+
export { stateMachine } from './state/index.js';
|
|
6
|
+
export type { EventOf, StateMachine, StateOf, StateTopology } from './state/index.js';
|
|
5
7
|
export type * from './callable/model/callable.js';
|
|
6
8
|
export type * from './callable/resolved.js';
|
|
7
9
|
export type * from './class/model/class.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { stateMachine } from './machine.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { EventName, StateName, StateTopology, TransitionRelation, ValidTransitionRelation } from './topology.js';
|
|
3
|
+
export interface StateMachine<Transitions extends TransitionRelation = any, Initial extends StateName<Transitions> = StateName<Transitions>> extends StateTopology<Transitions, Initial> {
|
|
4
|
+
readonly stateSchema: z.ZodType<StateName<Transitions>>;
|
|
5
|
+
readonly eventSchema: z.ZodType<EventName<Transitions>>;
|
|
6
|
+
eventsFrom<State extends StateName<Transitions>>(state: State): readonly EventName<Transitions, State>[];
|
|
7
|
+
decide<State extends StateName<Transitions>, Event extends EventName<Transitions>>(state: State, event: Event): TransitionDecision<Transitions, State, Event>;
|
|
8
|
+
}
|
|
9
|
+
export type StateOf<Machine extends StateMachine> = StateName<Machine['transitions']>;
|
|
10
|
+
export type EventOf<Machine extends StateMachine, State extends StateOf<Machine> = StateOf<Machine>> = EventName<Machine['transitions'], State>;
|
|
11
|
+
type TransitionDecision<Transitions extends TransitionRelation, State extends StateName<Transitions>, Event extends EventName<Transitions>> = State extends StateName<Transitions> ? Event extends EventName<Transitions> ? Event extends keyof Transitions[State] ? Readonly<{
|
|
12
|
+
kind: 'allowed';
|
|
13
|
+
transition: Readonly<{
|
|
14
|
+
from: State;
|
|
15
|
+
event: Event;
|
|
16
|
+
to: Transitions[State][Event];
|
|
17
|
+
}>;
|
|
18
|
+
}> : Readonly<{
|
|
19
|
+
kind: 'rejected';
|
|
20
|
+
code: 'STATE_TRANSITION_ILLEGAL';
|
|
21
|
+
from: State;
|
|
22
|
+
event: Event;
|
|
23
|
+
}> : never : never;
|
|
24
|
+
export declare function stateMachine<const Transitions extends TransitionRelation, const Initial extends StateName<Transitions>>(input: Readonly<{
|
|
25
|
+
initial: Initial;
|
|
26
|
+
transitions: Transitions & ValidTransitionRelation<Transitions>;
|
|
27
|
+
}>): StateMachine<Transitions, Initial>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { compareUnicode } from '../../addressing/ordering.js';
|
|
3
|
+
import { admitStateTopology } from './topology.js';
|
|
4
|
+
export function stateMachine(input) {
|
|
5
|
+
const topology = admitStateTopology(input);
|
|
6
|
+
const states = Object.keys(topology.transitions);
|
|
7
|
+
const events = [
|
|
8
|
+
...new Set(states.flatMap((state) => Object.keys(topology.transitions[state]))),
|
|
9
|
+
].sort(compareUnicode);
|
|
10
|
+
const stateSet = new Set(states);
|
|
11
|
+
const eventSet = new Set(events);
|
|
12
|
+
return Object.freeze({
|
|
13
|
+
...topology,
|
|
14
|
+
stateSchema: z.enum(states),
|
|
15
|
+
eventSchema: z.enum(events),
|
|
16
|
+
eventsFrom(state) {
|
|
17
|
+
admitState(state, stateSet);
|
|
18
|
+
return Object.freeze(Object.keys(topology.transitions[state]));
|
|
19
|
+
},
|
|
20
|
+
decide(state, event) {
|
|
21
|
+
admitState(state, stateSet);
|
|
22
|
+
admitEvent(event, eventSet);
|
|
23
|
+
const target = topology.transitions[state][event];
|
|
24
|
+
return target === undefined
|
|
25
|
+
? Object.freeze({ kind: 'rejected', code: 'STATE_TRANSITION_ILLEGAL', from: state, event })
|
|
26
|
+
: Object.freeze({
|
|
27
|
+
kind: 'allowed',
|
|
28
|
+
transition: Object.freeze({ from: state, event, to: target }),
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function admitState(state, states) {
|
|
34
|
+
if (!states.has(state))
|
|
35
|
+
throw new TypeError(`State machine does not declare state "${state}".`);
|
|
36
|
+
}
|
|
37
|
+
function admitEvent(event, events) {
|
|
38
|
+
if (!events.has(event))
|
|
39
|
+
throw new TypeError(`State machine does not declare event "${event}".`);
|
|
40
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type TransitionRelation = Readonly<Record<string, Readonly<Record<string, string>>>>;
|
|
2
|
+
export type StateName<Transitions extends TransitionRelation> = Extract<keyof Transitions, string>;
|
|
3
|
+
export type EventName<Transitions extends TransitionRelation, State extends StateName<Transitions> = StateName<Transitions>> = State extends StateName<Transitions> ? Extract<keyof Transitions[State], string> : never;
|
|
4
|
+
export type ValidTransitionRelation<Transitions extends TransitionRelation> = Readonly<{
|
|
5
|
+
[State in StateName<Transitions>]: Readonly<{
|
|
6
|
+
[Event in keyof Transitions[State]]: string extends StateName<Transitions> ? string : Exclude<StateName<Transitions>, State>;
|
|
7
|
+
}>;
|
|
8
|
+
}>;
|
|
9
|
+
export interface StateTopology<Transitions extends TransitionRelation = TransitionRelation, Initial extends StateName<Transitions> = StateName<Transitions>> {
|
|
10
|
+
readonly initial: Initial;
|
|
11
|
+
readonly transitions: Transitions;
|
|
12
|
+
}
|
|
13
|
+
export type StateTopologyOf<Value> = Value extends StateTopology<infer Transitions, infer Initial> ? StateTopology<Transitions, Initial> : undefined;
|
|
14
|
+
export declare function admitStateTopology(input: unknown): StateTopology;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { compareUnicode } from '../../addressing/ordering.js';
|
|
2
|
+
export function admitStateTopology(input) {
|
|
3
|
+
if (!isRecord(input) || !exactKeys(input, ['initial', 'transitions']))
|
|
4
|
+
invalidInput();
|
|
5
|
+
const initial = input.initial;
|
|
6
|
+
const authored = input.transitions;
|
|
7
|
+
if (typeof initial !== 'string' || initial.length === 0 || !isRecord(authored))
|
|
8
|
+
invalidInput();
|
|
9
|
+
const states = Object.keys(authored);
|
|
10
|
+
if (states.length === 0)
|
|
11
|
+
throw new TypeError('State topology requires at least one state.');
|
|
12
|
+
if (states.includes(''))
|
|
13
|
+
throw new TypeError('State topology has an empty state name.');
|
|
14
|
+
if (!states.includes(initial)) {
|
|
15
|
+
throw new TypeError(`State topology initial state "${initial}" is not declared.`);
|
|
16
|
+
}
|
|
17
|
+
const declared = new Set(states);
|
|
18
|
+
const transitions = Object.create(null);
|
|
19
|
+
let transitionCount = 0;
|
|
20
|
+
for (const state of states.sort(compareUnicode)) {
|
|
21
|
+
const outgoing = authored[state];
|
|
22
|
+
if (!isRecord(outgoing))
|
|
23
|
+
throw new TypeError(`State "${state}" transitions must be an object.`);
|
|
24
|
+
const accepted = Object.create(null);
|
|
25
|
+
for (const event of Object.keys(outgoing).sort(compareUnicode)) {
|
|
26
|
+
const target = outgoing[event];
|
|
27
|
+
if (event.length === 0)
|
|
28
|
+
throw new TypeError(`State "${state}" has an empty event name.`);
|
|
29
|
+
if (typeof target !== 'string' || !declared.has(target)) {
|
|
30
|
+
throw new TypeError(`State "${state}" event "${event}" targets undeclared state "${String(target)}".`);
|
|
31
|
+
}
|
|
32
|
+
if (target === state) {
|
|
33
|
+
throw new TypeError(`State "${state}" event "${event}" is a self-transition.`);
|
|
34
|
+
}
|
|
35
|
+
accepted[event] = target;
|
|
36
|
+
transitionCount += 1;
|
|
37
|
+
}
|
|
38
|
+
transitions[state] = Object.freeze(accepted);
|
|
39
|
+
}
|
|
40
|
+
if (transitionCount === 0)
|
|
41
|
+
throw new TypeError('State topology requires at least one transition.');
|
|
42
|
+
const reachable = new Set([initial]);
|
|
43
|
+
const pending = [initial];
|
|
44
|
+
while (pending.length > 0) {
|
|
45
|
+
const state = pending.shift();
|
|
46
|
+
for (const target of Object.values(transitions[state])) {
|
|
47
|
+
if (reachable.has(target))
|
|
48
|
+
continue;
|
|
49
|
+
reachable.add(target);
|
|
50
|
+
pending.push(target);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const state of states) {
|
|
54
|
+
if (!reachable.has(state)) {
|
|
55
|
+
throw new TypeError(`State "${state}" is unreachable from initial "${initial}".`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return Object.freeze({ initial, transitions: Object.freeze(transitions) });
|
|
59
|
+
}
|
|
60
|
+
function invalidInput() {
|
|
61
|
+
throw new TypeError('State topology must contain exactly initial and transitions.');
|
|
62
|
+
}
|
|
63
|
+
function isRecord(input) {
|
|
64
|
+
return input !== null && typeof input === 'object' && !Array.isArray(input);
|
|
65
|
+
}
|
|
66
|
+
function exactKeys(input, expected) {
|
|
67
|
+
const keys = Reflect.ownKeys(input);
|
|
68
|
+
return keys.length === expected.length && keys.every((key) => expected.includes(String(key)));
|
|
69
|
+
}
|
|
@@ -3,6 +3,7 @@ import type { MethodDefinition } from '../../language/callable/model/callable.js
|
|
|
3
3
|
import type { ClassDefinition } from '../../language/class/model/class.js';
|
|
4
4
|
import type { DataDefinition } from '../../language/class/model/data.js';
|
|
5
5
|
import type { PropertyAuto } from '../../language/class/model/property.js';
|
|
6
|
+
import type { StateTopology } from '../../language/state/index.js';
|
|
6
7
|
import type { JsonSchema } from '../../language/value/model/schema.js';
|
|
7
8
|
import type { SchemaDiagnostic } from '../diagnostic.js';
|
|
8
9
|
import type { DomainResolutionContext } from '../resolution/context.js';
|
|
@@ -13,8 +14,8 @@ export interface EffectiveField {
|
|
|
13
14
|
readonly name: string;
|
|
14
15
|
readonly schema: JsonSchema;
|
|
15
16
|
readonly required: boolean;
|
|
16
|
-
readonly visibility: 'public' | 'private';
|
|
17
17
|
readonly auto?: PropertyAuto;
|
|
18
|
+
readonly state?: StateTopology;
|
|
18
19
|
}
|
|
19
20
|
export interface EffectiveMethod {
|
|
20
21
|
readonly identity: string;
|
|
@@ -62,8 +62,8 @@ function ownFields(owner, declaration) {
|
|
|
62
62
|
name,
|
|
63
63
|
schema: property.schema,
|
|
64
64
|
required: property.required,
|
|
65
|
-
visibility: property.visibility,
|
|
66
65
|
...(property.auto === undefined ? {} : { auto: property.auto }),
|
|
66
|
+
...(property.state === undefined ? {} : { state: property.state }),
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
return result;
|
|
@@ -371,7 +371,7 @@ function propertyMeaning(field) {
|
|
|
371
371
|
name: field.name,
|
|
372
372
|
schema: semanticValueSchema(field.schema),
|
|
373
373
|
required: field.required,
|
|
374
|
-
|
|
374
|
+
...(field.state === undefined ? {} : { state: field.state }),
|
|
375
375
|
};
|
|
376
376
|
}
|
|
377
377
|
function methodMeaning(method) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SchemaDiagnosticCode = 'DM_MEMBER_ROOT_INVALID' | 'DM_DEPENDENCY_CONTEXT_INVALID' | 'DM_DEPENDENCY_NOT_RETAINED' | 'DM_MEANING_INCONSISTENT' | 'DM_MEMBER_ORIGIN_MISMATCH' | 'DV_ACCEPTANCE_CONTEXT' | 'DV_CALLABLE_AUTH' | 'DV_CALLABLE_IO' | 'DV_CALLABLE_POLICY_AUTH' | 'DV_CLASS_ABSTRACT' | 'DV_CLASS_ACYCLIC' | 'DV_CLASS_KIND' | 'DV_CORE_EDGE_CLASS' | 'DV_CORE_EDGE_CONSTRAINTS' | 'DV_CORE_EDGE_KEY' | 'DV_CORE_EDGE_PROPERTIES' | 'DV_CORE_NODE_CLASS' | 'DV_CORE_NODE_PROPERTIES' | 'DV_CORE_REF' | 'DV_DATA_COMPOSITION' | 'DV_DEPENDENCY_ACYCLIC' | 'DV_DEPENDENCY_DIRECT' | 'DV_DEPENDENCY_EXACT' | 'DV_DEPENDENCY_LIMITS' | 'DV_DEPENDENCY_REVISION_COHERENCE' | 'DV_DEPENDENCY_UNIQUE' | 'DV_EDGE_ACCEPTS' | 'DV_EDGE_CLASS_COMPOSITION' | 'DV_EDGE_CONSTRAINT' | 'DV_EDGE_ROLE' | 'DV_EDGE_UNDIRECTED' | 'DV_JSON_VALUE' | 'DV_METHOD_ABSTRACT' | 'DV_METHOD_COMPOSITION' | 'DV_PROPERTY_AUTO' | 'DV_PROPERTY_COMPOSITION' | 'DV_REF_RESOLVES' | 'DV_VALUE_SCHEMA' | 'DV_VIEW_TARGET' | 'PL_BUDGET' | 'PL_COMPOSITION' | 'PL_CONNECTIVITY' | 'PL_REF' | 'PL_REPEAT' | 'PL_TARGET' | 'PL_TYPING' | 'PL_USE' | 'PL_VARIABLE_SCOPE' | 'STRUCTURE_ABSTRACT_POLICY' | 'STRUCTURE_CALLABLE_POLICY_AUTH' | 'STRUCTURE_DUPLICATE_ITEM' | 'STRUCTURE_EDGE_ORIENTATION' | 'STRUCTURE_FORMAT' | 'STRUCTURE_INVALID' | 'STRUCTURE_KEY' | 'STRUCTURE_MAXIMUM' | 'STRUCTURE_MINIMUM' | 'STRUCTURE_MULTIPLE' | 'STRUCTURE_REQUIRED' | 'STRUCTURE_TYPE' | 'STRUCTURE_UNION' | 'STRUCTURE_UNKNOWN_FIELD' | 'STRUCTURE_VALUE' | 'UNSUPPORTED_DOCUMENT_FORMAT' | 'UNSUPPORTED_DSL_VERSION';
|
|
1
|
+
export type SchemaDiagnosticCode = 'DM_MEMBER_ROOT_INVALID' | 'DM_DEPENDENCY_CONTEXT_INVALID' | 'DM_DEPENDENCY_NOT_RETAINED' | 'DM_MEANING_INCONSISTENT' | 'DM_MEMBER_ORIGIN_MISMATCH' | 'DV_ACCEPTANCE_CONTEXT' | 'DV_CALLABLE_AUTH' | 'DV_CALLABLE_IO' | 'DV_CALLABLE_POLICY_AUTH' | 'DV_CLASS_ABSTRACT' | 'DV_CLASS_ACYCLIC' | 'DV_CLASS_KIND' | 'DV_CORE_EDGE_CLASS' | 'DV_CORE_EDGE_CONSTRAINTS' | 'DV_CORE_EDGE_KEY' | 'DV_CORE_EDGE_PROPERTIES' | 'DV_CORE_NODE_CLASS' | 'DV_CORE_NODE_PROPERTIES' | 'DV_CORE_REF' | 'DV_DATA_COMPOSITION' | 'DV_DEPENDENCY_ACYCLIC' | 'DV_DEPENDENCY_DIRECT' | 'DV_DEPENDENCY_EXACT' | 'DV_DEPENDENCY_LIMITS' | 'DV_DEPENDENCY_REVISION_COHERENCE' | 'DV_DEPENDENCY_UNIQUE' | 'DV_EDGE_ACCEPTS' | 'DV_EDGE_CLASS_COMPOSITION' | 'DV_EDGE_CONSTRAINT' | 'DV_EDGE_ROLE' | 'DV_EDGE_UNDIRECTED' | 'DV_JSON_VALUE' | 'DV_METHOD_ABSTRACT' | 'DV_METHOD_COMPOSITION' | 'DV_PROPERTY_AUTO' | 'DV_PROPERTY_COMPOSITION' | 'DV_PROPERTY_STATE' | 'DV_REF_RESOLVES' | 'DV_VALUE_SCHEMA' | 'DV_VIEW_TARGET' | 'PL_BUDGET' | 'PL_COMPOSITION' | 'PL_CONNECTIVITY' | 'PL_REF' | 'PL_REPEAT' | 'PL_TARGET' | 'PL_TYPING' | 'PL_USE' | 'PL_VARIABLE_SCOPE' | 'STRUCTURE_ABSTRACT_POLICY' | 'STRUCTURE_CALLABLE_POLICY_AUTH' | 'STRUCTURE_DUPLICATE_ITEM' | 'STRUCTURE_EDGE_ORIENTATION' | 'STRUCTURE_FORMAT' | 'STRUCTURE_INVALID' | 'STRUCTURE_KEY' | 'STRUCTURE_MAXIMUM' | 'STRUCTURE_MINIMUM' | 'STRUCTURE_MULTIPLE' | 'STRUCTURE_REQUIRED' | 'STRUCTURE_TYPE' | 'STRUCTURE_UNION' | 'STRUCTURE_UNKNOWN_FIELD' | 'STRUCTURE_VALUE' | 'UNSUPPORTED_DOCUMENT_FORMAT' | 'UNSUPPORTED_DSL_VERSION';
|
|
2
2
|
export interface SchemaDiagnostic<out Code extends SchemaDiagnosticCode = SchemaDiagnosticCode> {
|
|
3
3
|
readonly code: Code;
|
|
4
4
|
readonly pointer: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import { compareDefinitionRefs, compareUnicode } from '../../addressing/ordering.js';
|
|
3
3
|
import { normalizePolicyChecks, normalizePolicyExpression, } from '../../language/policy/normalization/normalize.js';
|
|
4
|
+
import { admitStateTopology } from '../../language/state/topology.js';
|
|
4
5
|
import { canonicalizeValueSchema } from '../../language/value/profile/canonicalize.js';
|
|
5
6
|
export function normalizeDomainSchema(schema) {
|
|
6
7
|
const classes = mapRecord(schema.classes, canonicalizeClass);
|
|
@@ -123,7 +124,6 @@ function canonicalizeProperty(value) {
|
|
|
123
124
|
return {
|
|
124
125
|
schema: canonicalizeValueSchema(value.schema, 'property-facet'),
|
|
125
126
|
required: value.required,
|
|
126
|
-
visibility: value.visibility,
|
|
127
127
|
...(value.auto === undefined
|
|
128
128
|
? {}
|
|
129
129
|
: {
|
|
@@ -133,6 +133,9 @@ function canonicalizeProperty(value) {
|
|
|
133
133
|
},
|
|
134
134
|
}),
|
|
135
135
|
...(value.description === undefined ? {} : { description: value.description }),
|
|
136
|
+
...(value.state === undefined
|
|
137
|
+
? {}
|
|
138
|
+
: { state: admitStateTopology(value.state) }),
|
|
136
139
|
};
|
|
137
140
|
}
|
|
138
141
|
function canonicalizeDirectedEndpoints(value) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Key } from '../../addressing/key.js';
|
|
2
2
|
import { definitionRefIndex } from '../../addressing/ordering.js';
|
|
3
|
+
import { admitStateTopology } from '../../language/state/topology.js';
|
|
3
4
|
import { classifyOrdering } from '../../language/value/ordering.js';
|
|
4
5
|
import { diagnostic } from '../diagnostic.js';
|
|
5
6
|
import { createValueSchemaRegistry } from '../resolution/value.registry.js';
|
|
@@ -26,15 +27,40 @@ export function validateDefinitions(environment, analysis) {
|
|
|
26
27
|
function validateFacet(environment, declaration, pointer, diagnostics) {
|
|
27
28
|
const valueRegistry = createValueSchemaRegistry(environment);
|
|
28
29
|
for (const [name, property] of Object.entries(declaration.properties)) {
|
|
30
|
+
const propertyPointer = `${pointer}/properties/${escapePointer(name)}`;
|
|
31
|
+
if (property.state !== undefined) {
|
|
32
|
+
if (declaration.kind !== 'node') {
|
|
33
|
+
diagnostics.push(diagnostic('DV_PROPERTY_STATE', `${propertyPointer}/state`, 'A State Property may be declared only on a Node Class.'));
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const topology = admitStateTopology(property.state);
|
|
37
|
+
const expected = Object.keys(topology.transitions).sort();
|
|
38
|
+
const schema = property.schema;
|
|
39
|
+
const schemaMatches = schema !== null &&
|
|
40
|
+
typeof schema === 'object' &&
|
|
41
|
+
!Array.isArray(schema) &&
|
|
42
|
+
Object.keys(schema).length === 2 &&
|
|
43
|
+
schema.type === 'string' &&
|
|
44
|
+
Array.isArray(schema.enum) &&
|
|
45
|
+
schema.enum.length === expected.length &&
|
|
46
|
+
[...schema.enum].sort().every((state, index) => state === expected[index]);
|
|
47
|
+
if (!property.required || property.auto !== undefined || !schemaMatches) {
|
|
48
|
+
diagnostics.push(diagnostic('DV_PROPERTY_STATE', `${propertyPointer}/state`, 'A State Property is required, non-automatic, and has exactly its declared states.'));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
diagnostics.push(diagnostic('DV_PROPERTY_STATE', `${propertyPointer}/state`, error instanceof Error ? error.message : 'Invalid State topology.'));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
29
55
|
if (property.auto === undefined)
|
|
30
56
|
continue;
|
|
31
|
-
const
|
|
57
|
+
const autoPointer = `${propertyPointer}/auto`;
|
|
32
58
|
if (property.required && !property.auto.on.includes('create')) {
|
|
33
|
-
diagnostics.push(diagnostic('DV_PROPERTY_AUTO', `${
|
|
59
|
+
diagnostics.push(diagnostic('DV_PROPERTY_AUTO', `${autoPointer}/on`, 'A required auto Property must run on create.'));
|
|
34
60
|
}
|
|
35
61
|
if (property.auto.set === 'instant' &&
|
|
36
62
|
classifyOrdering(property.schema, valueRegistry) !== 'instant') {
|
|
37
|
-
diagnostics.push(diagnostic('DV_PROPERTY_AUTO', `${
|
|
63
|
+
diagnostics.push(diagnostic('DV_PROPERTY_AUTO', `${autoPointer}/set`, 'The instant setter requires an Instant value schema.'));
|
|
38
64
|
}
|
|
39
65
|
}
|
|
40
66
|
if (declaration.kind !== 'node')
|
|
@@ -34,10 +34,15 @@ const jsonSchemaSchema = z.union([z.boolean(), jsonObjectSchema]);
|
|
|
34
34
|
const dataDeclarationSchema = z.strictObject({
|
|
35
35
|
mediaType: z.string().regex(MEDIA_TYPE_PATTERN),
|
|
36
36
|
});
|
|
37
|
+
const stateNameSchema = z.string().min(1);
|
|
38
|
+
const stateTransitionsSchema = z.custom(isStateTransitions);
|
|
39
|
+
const stateTopologySchema = z.strictObject({
|
|
40
|
+
initial: stateNameSchema,
|
|
41
|
+
transitions: stateTransitionsSchema,
|
|
42
|
+
});
|
|
37
43
|
const propertyDefinitionSchema = z.strictObject({
|
|
38
44
|
schema: jsonSchemaSchema,
|
|
39
45
|
required: z.boolean(),
|
|
40
|
-
visibility: z.enum(['public', 'private']),
|
|
41
46
|
auto: z
|
|
42
47
|
.strictObject({
|
|
43
48
|
on: uniqueArray(z.enum(['create', 'update'])).min(1),
|
|
@@ -45,6 +50,7 @@ const propertyDefinitionSchema = z.strictObject({
|
|
|
45
50
|
})
|
|
46
51
|
.optional(),
|
|
47
52
|
description: descriptionSchema.optional(),
|
|
53
|
+
state: stateTopologySchema.optional(),
|
|
48
54
|
});
|
|
49
55
|
const propertyRecordSchema = z.record(memberNameSchema, propertyDefinitionSchema);
|
|
50
56
|
const domainDependencySchema = z.strictObject({
|
|
@@ -326,6 +332,30 @@ function absoluteRefSchema(kind) {
|
|
|
326
332
|
name: memberNameSchema,
|
|
327
333
|
});
|
|
328
334
|
}
|
|
335
|
+
function isStateTransitions(input) {
|
|
336
|
+
if (!isRecord(input))
|
|
337
|
+
return false;
|
|
338
|
+
for (const state of Reflect.ownKeys(input)) {
|
|
339
|
+
if (typeof state !== 'string' || state.length === 0)
|
|
340
|
+
return false;
|
|
341
|
+
const outgoing = Reflect.get(input, state);
|
|
342
|
+
if (!isRecord(outgoing))
|
|
343
|
+
return false;
|
|
344
|
+
for (const event of Reflect.ownKeys(outgoing)) {
|
|
345
|
+
const target = Reflect.get(outgoing, event);
|
|
346
|
+
if (typeof event !== 'string' ||
|
|
347
|
+
event.length === 0 ||
|
|
348
|
+
typeof target !== 'string' ||
|
|
349
|
+
target.length === 0) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return true;
|
|
355
|
+
}
|
|
356
|
+
function isRecord(input) {
|
|
357
|
+
return input !== null && typeof input === 'object' && !Array.isArray(input);
|
|
358
|
+
}
|
|
329
359
|
function uniqueArray(element) {
|
|
330
360
|
return z.array(element).superRefine((values, context) => {
|
|
331
361
|
const firstIndexByValue = new Map();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/kernel-dsl",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.18",
|
|
4
4
|
"description": "Astrale Kernel DSL - Schema authoring, inference, and IR serialization",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -59,6 +59,10 @@
|
|
|
59
59
|
"types": "./dist/v1/language/index.d.ts",
|
|
60
60
|
"import": "./dist/v1/language/index.js"
|
|
61
61
|
},
|
|
62
|
+
"./v1/language/state": {
|
|
63
|
+
"types": "./dist/v1/language/state/index.d.ts",
|
|
64
|
+
"import": "./dist/v1/language/state/index.js"
|
|
65
|
+
},
|
|
62
66
|
"./v1/schema": {
|
|
63
67
|
"types": "./dist/v1/schema/index.d.ts",
|
|
64
68
|
"import": "./dist/v1/schema/index.js"
|