@aster-rpc/aster 0.1.2

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.
Files changed (233) hide show
  1. package/dist/capabilities.d.ts +26 -0
  2. package/dist/capabilities.d.ts.map +1 -0
  3. package/dist/capabilities.js +29 -0
  4. package/dist/capabilities.js.map +1 -0
  5. package/dist/client.d.ts +65 -0
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +108 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/codec.d.ts +156 -0
  10. package/dist/codec.d.ts.map +1 -0
  11. package/dist/codec.js +477 -0
  12. package/dist/codec.js.map +1 -0
  13. package/dist/config.d.ts +102 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +454 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/contract/identity.d.ts +115 -0
  18. package/dist/contract/identity.d.ts.map +1 -0
  19. package/dist/contract/identity.js +188 -0
  20. package/dist/contract/identity.js.map +1 -0
  21. package/dist/contract/manifest.d.ts +77 -0
  22. package/dist/contract/manifest.d.ts.map +1 -0
  23. package/dist/contract/manifest.js +127 -0
  24. package/dist/contract/manifest.js.map +1 -0
  25. package/dist/contract/publication.d.ts +71 -0
  26. package/dist/contract/publication.d.ts.map +1 -0
  27. package/dist/contract/publication.js +85 -0
  28. package/dist/contract/publication.js.map +1 -0
  29. package/dist/decorators.d.ts +139 -0
  30. package/dist/decorators.d.ts.map +1 -0
  31. package/dist/decorators.js +175 -0
  32. package/dist/decorators.js.map +1 -0
  33. package/dist/dynamic.d.ts +61 -0
  34. package/dist/dynamic.d.ts.map +1 -0
  35. package/dist/dynamic.js +147 -0
  36. package/dist/dynamic.js.map +1 -0
  37. package/dist/framing.d.ts +74 -0
  38. package/dist/framing.d.ts.map +1 -0
  39. package/dist/framing.js +162 -0
  40. package/dist/framing.js.map +1 -0
  41. package/dist/health.d.ts +127 -0
  42. package/dist/health.d.ts.map +1 -0
  43. package/dist/health.js +236 -0
  44. package/dist/health.js.map +1 -0
  45. package/dist/index.d.ts +67 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +101 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/interceptors/audit.d.ts +25 -0
  50. package/dist/interceptors/audit.d.ts.map +1 -0
  51. package/dist/interceptors/audit.js +46 -0
  52. package/dist/interceptors/audit.js.map +1 -0
  53. package/dist/interceptors/auth.d.ts +13 -0
  54. package/dist/interceptors/auth.d.ts.map +1 -0
  55. package/dist/interceptors/auth.js +34 -0
  56. package/dist/interceptors/auth.js.map +1 -0
  57. package/dist/interceptors/base.d.ts +74 -0
  58. package/dist/interceptors/base.d.ts.map +1 -0
  59. package/dist/interceptors/base.js +103 -0
  60. package/dist/interceptors/base.js.map +1 -0
  61. package/dist/interceptors/capability.d.ts +16 -0
  62. package/dist/interceptors/capability.d.ts.map +1 -0
  63. package/dist/interceptors/capability.js +63 -0
  64. package/dist/interceptors/capability.js.map +1 -0
  65. package/dist/interceptors/circuit-breaker.d.ts +40 -0
  66. package/dist/interceptors/circuit-breaker.d.ts.map +1 -0
  67. package/dist/interceptors/circuit-breaker.js +91 -0
  68. package/dist/interceptors/circuit-breaker.js.map +1 -0
  69. package/dist/interceptors/compression.d.ts +11 -0
  70. package/dist/interceptors/compression.d.ts.map +1 -0
  71. package/dist/interceptors/compression.js +12 -0
  72. package/dist/interceptors/compression.js.map +1 -0
  73. package/dist/interceptors/deadline.d.ts +12 -0
  74. package/dist/interceptors/deadline.d.ts.map +1 -0
  75. package/dist/interceptors/deadline.js +28 -0
  76. package/dist/interceptors/deadline.js.map +1 -0
  77. package/dist/interceptors/metrics.d.ts +43 -0
  78. package/dist/interceptors/metrics.d.ts.map +1 -0
  79. package/dist/interceptors/metrics.js +132 -0
  80. package/dist/interceptors/metrics.js.map +1 -0
  81. package/dist/interceptors/rate-limit.d.ts +24 -0
  82. package/dist/interceptors/rate-limit.d.ts.map +1 -0
  83. package/dist/interceptors/rate-limit.js +84 -0
  84. package/dist/interceptors/rate-limit.js.map +1 -0
  85. package/dist/interceptors/retry.d.ts +25 -0
  86. package/dist/interceptors/retry.d.ts.map +1 -0
  87. package/dist/interceptors/retry.js +55 -0
  88. package/dist/interceptors/retry.js.map +1 -0
  89. package/dist/limits.d.ts +77 -0
  90. package/dist/limits.d.ts.map +1 -0
  91. package/dist/limits.js +137 -0
  92. package/dist/limits.js.map +1 -0
  93. package/dist/logging.d.ts +40 -0
  94. package/dist/logging.d.ts.map +1 -0
  95. package/dist/logging.js +92 -0
  96. package/dist/logging.js.map +1 -0
  97. package/dist/metadata.d.ts +14 -0
  98. package/dist/metadata.d.ts.map +1 -0
  99. package/dist/metadata.js +68 -0
  100. package/dist/metadata.js.map +1 -0
  101. package/dist/metrics.d.ts +40 -0
  102. package/dist/metrics.d.ts.map +1 -0
  103. package/dist/metrics.js +92 -0
  104. package/dist/metrics.js.map +1 -0
  105. package/dist/peer-store.d.ts +53 -0
  106. package/dist/peer-store.d.ts.map +1 -0
  107. package/dist/peer-store.js +105 -0
  108. package/dist/peer-store.js.map +1 -0
  109. package/dist/protocol.d.ts +44 -0
  110. package/dist/protocol.d.ts.map +1 -0
  111. package/dist/protocol.js +59 -0
  112. package/dist/protocol.js.map +1 -0
  113. package/dist/registration.d.ts +81 -0
  114. package/dist/registration.d.ts.map +1 -0
  115. package/dist/registration.js +161 -0
  116. package/dist/registration.js.map +1 -0
  117. package/dist/registry/acl.d.ts +57 -0
  118. package/dist/registry/acl.d.ts.map +1 -0
  119. package/dist/registry/acl.js +104 -0
  120. package/dist/registry/acl.js.map +1 -0
  121. package/dist/registry/client.d.ts +70 -0
  122. package/dist/registry/client.d.ts.map +1 -0
  123. package/dist/registry/client.js +115 -0
  124. package/dist/registry/client.js.map +1 -0
  125. package/dist/registry/gossip.d.ts +43 -0
  126. package/dist/registry/gossip.d.ts.map +1 -0
  127. package/dist/registry/gossip.js +102 -0
  128. package/dist/registry/gossip.js.map +1 -0
  129. package/dist/registry/keys.d.ts +25 -0
  130. package/dist/registry/keys.d.ts.map +1 -0
  131. package/dist/registry/keys.js +47 -0
  132. package/dist/registry/keys.js.map +1 -0
  133. package/dist/registry/models.d.ts +80 -0
  134. package/dist/registry/models.d.ts.map +1 -0
  135. package/dist/registry/models.js +35 -0
  136. package/dist/registry/models.js.map +1 -0
  137. package/dist/registry/publisher.d.ts +65 -0
  138. package/dist/registry/publisher.d.ts.map +1 -0
  139. package/dist/registry/publisher.js +164 -0
  140. package/dist/registry/publisher.js.map +1 -0
  141. package/dist/runtime.d.ts +267 -0
  142. package/dist/runtime.d.ts.map +1 -0
  143. package/dist/runtime.js +1366 -0
  144. package/dist/runtime.js.map +1 -0
  145. package/dist/server.d.ts +100 -0
  146. package/dist/server.d.ts.map +1 -0
  147. package/dist/server.js +511 -0
  148. package/dist/server.js.map +1 -0
  149. package/dist/service.d.ts +72 -0
  150. package/dist/service.d.ts.map +1 -0
  151. package/dist/service.js +98 -0
  152. package/dist/service.js.map +1 -0
  153. package/dist/session.d.ts +64 -0
  154. package/dist/session.d.ts.map +1 -0
  155. package/dist/session.js +350 -0
  156. package/dist/session.js.map +1 -0
  157. package/dist/status.d.ts +113 -0
  158. package/dist/status.d.ts.map +1 -0
  159. package/dist/status.js +206 -0
  160. package/dist/status.js.map +1 -0
  161. package/dist/transport/base.d.ts +46 -0
  162. package/dist/transport/base.d.ts.map +1 -0
  163. package/dist/transport/base.js +10 -0
  164. package/dist/transport/base.js.map +1 -0
  165. package/dist/transport/iroh.d.ts +45 -0
  166. package/dist/transport/iroh.d.ts.map +1 -0
  167. package/dist/transport/iroh.js +225 -0
  168. package/dist/transport/iroh.js.map +1 -0
  169. package/dist/transport/local.d.ts +48 -0
  170. package/dist/transport/local.d.ts.map +1 -0
  171. package/dist/transport/local.js +139 -0
  172. package/dist/transport/local.js.map +1 -0
  173. package/dist/trust/admission.d.ts +60 -0
  174. package/dist/trust/admission.d.ts.map +1 -0
  175. package/dist/trust/admission.js +149 -0
  176. package/dist/trust/admission.js.map +1 -0
  177. package/dist/trust/bootstrap.d.ts +109 -0
  178. package/dist/trust/bootstrap.d.ts.map +1 -0
  179. package/dist/trust/bootstrap.js +311 -0
  180. package/dist/trust/bootstrap.js.map +1 -0
  181. package/dist/trust/clock.d.ts +93 -0
  182. package/dist/trust/clock.d.ts.map +1 -0
  183. package/dist/trust/clock.js +154 -0
  184. package/dist/trust/clock.js.map +1 -0
  185. package/dist/trust/consumer.d.ts +139 -0
  186. package/dist/trust/consumer.d.ts.map +1 -0
  187. package/dist/trust/consumer.js +323 -0
  188. package/dist/trust/consumer.js.map +1 -0
  189. package/dist/trust/credentials.d.ts +98 -0
  190. package/dist/trust/credentials.d.ts.map +1 -0
  191. package/dist/trust/credentials.js +250 -0
  192. package/dist/trust/credentials.js.map +1 -0
  193. package/dist/trust/delegated.d.ts +118 -0
  194. package/dist/trust/delegated.d.ts.map +1 -0
  195. package/dist/trust/delegated.js +292 -0
  196. package/dist/trust/delegated.js.map +1 -0
  197. package/dist/trust/gossip.d.ts +146 -0
  198. package/dist/trust/gossip.d.ts.map +1 -0
  199. package/dist/trust/gossip.js +334 -0
  200. package/dist/trust/gossip.js.map +1 -0
  201. package/dist/trust/hooks.d.ts +84 -0
  202. package/dist/trust/hooks.d.ts.map +1 -0
  203. package/dist/trust/hooks.js +125 -0
  204. package/dist/trust/hooks.js.map +1 -0
  205. package/dist/trust/iid.d.ts +65 -0
  206. package/dist/trust/iid.d.ts.map +1 -0
  207. package/dist/trust/iid.js +104 -0
  208. package/dist/trust/iid.js.map +1 -0
  209. package/dist/trust/mesh.d.ts +43 -0
  210. package/dist/trust/mesh.d.ts.map +1 -0
  211. package/dist/trust/mesh.js +105 -0
  212. package/dist/trust/mesh.js.map +1 -0
  213. package/dist/trust/nonce.d.ts +39 -0
  214. package/dist/trust/nonce.d.ts.map +1 -0
  215. package/dist/trust/nonce.js +46 -0
  216. package/dist/trust/nonce.js.map +1 -0
  217. package/dist/trust/producer.d.ts +80 -0
  218. package/dist/trust/producer.d.ts.map +1 -0
  219. package/dist/trust/producer.js +151 -0
  220. package/dist/trust/producer.js.map +1 -0
  221. package/dist/trust/rcan.d.ts +29 -0
  222. package/dist/trust/rcan.d.ts.map +1 -0
  223. package/dist/trust/rcan.js +57 -0
  224. package/dist/trust/rcan.js.map +1 -0
  225. package/dist/types.d.ts +57 -0
  226. package/dist/types.d.ts.map +1 -0
  227. package/dist/types.js +50 -0
  228. package/dist/types.js.map +1 -0
  229. package/dist/xlang.d.ts +26 -0
  230. package/dist/xlang.d.ts.map +1 -0
  231. package/dist/xlang.js +55 -0
  232. package/dist/xlang.js.map +1 -0
  233. package/package.json +59 -0
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Contract identity — canonical serialization and BLAKE3 hashing.
3
+ *
4
+ * Spec reference: Aster-ContractIdentity.md S11.3
5
+ *
6
+ * Contract ID = BLAKE3(canonical_xlang_bytes(ServiceContract))
7
+ *
8
+ * All canonical encoding and hashing is delegated to the Rust core via
9
+ * NAPI-RS. The native binding is required — without it, there is no Iroh
10
+ * transport either, so the entire binding is non-functional.
11
+ */
12
+ // -- Enums (normative values from spec) ---------------------------------------
13
+ export const TypeKind = { PRIMITIVE: 0, REF: 1, SELF_REF: 2, ANY: 3 };
14
+ export const ContainerKind = { NONE: 0, LIST: 1, SET: 2, MAP: 3 };
15
+ export const TypeDefKind = { MESSAGE: 0, ENUM: 1, UNION: 2 };
16
+ export const MethodPattern = { UNARY: 0, SERVER_STREAM: 1, CLIENT_STREAM: 2, BIDI_STREAM: 3 };
17
+ export const CapabilityKind = { ROLE: 0, ANY_OF: 1, ALL_OF: 2 };
18
+ export const ScopeKind = {
19
+ SHARED: 0,
20
+ SESSION: 1,
21
+ /** Legacy alias kept for back-compat with code that imported ScopeKind.STREAM.
22
+ * Resolves to the same integer (1), so contract ids are unaffected. */
23
+ STREAM: 1,
24
+ };
25
+ // -- Serde-compatible enum names (must match Rust #[serde(rename_all = "snake_case")]) --
26
+ const PATTERN_NAMES = {
27
+ 0: 'unary', 1: 'server_stream', 2: 'client_stream', 3: 'bidi_stream',
28
+ };
29
+ // The Rust canonical encoder accepts both "session" and "stream" via
30
+ // #[serde(alias = "stream")]. We send "stream" here for compat with
31
+ // pre-rename NAPI binaries that haven't been rebuilt yet.
32
+ const SCOPE_NAMES = { 0: 'shared', 1: 'stream' };
33
+ const CAP_NAMES = { 0: 'role', 1: 'any_of', 2: 'all_of' };
34
+ function hex(data) {
35
+ return Array.from(data, b => b.toString(16).padStart(2, '0')).join('');
36
+ }
37
+ /** Convert a ServiceContract to JSON matching the Rust serde format. */
38
+ function contractToJson(contract) {
39
+ return JSON.stringify({
40
+ name: contract.name,
41
+ version: contract.version,
42
+ methods: contract.methods.map(m => ({
43
+ name: m.name,
44
+ pattern: PATTERN_NAMES[m.pattern] ?? m.pattern,
45
+ request_type: hex(m.requestType),
46
+ response_type: hex(m.responseType),
47
+ idempotent: m.idempotent,
48
+ default_timeout: m.defaultTimeout,
49
+ requires: m.requires ? {
50
+ kind: CAP_NAMES[m.requires.kind] ?? m.requires.kind,
51
+ roles: m.requires.roles,
52
+ } : null,
53
+ })),
54
+ serialization_modes: contract.serializationModes,
55
+ scoped: SCOPE_NAMES[contract.scoped] ?? contract.scoped,
56
+ requires: contract.requires ? {
57
+ kind: CAP_NAMES[contract.requires.kind] ?? contract.requires.kind,
58
+ roles: contract.requires.roles,
59
+ } : null,
60
+ });
61
+ }
62
+ let _native;
63
+ /**
64
+ * Set the native contract binding. Called once at startup when the
65
+ * NAPI-RS addon is loaded.
66
+ */
67
+ export function setNativeContract(native) {
68
+ _native = native;
69
+ }
70
+ function requireNative() {
71
+ if (!_native) {
72
+ throw new Error('Native contract binding not configured. Call setNativeContract() with ' +
73
+ 'the NAPI-RS binding at startup. Without native support, contract ' +
74
+ 'identity and Iroh transport are unavailable.');
75
+ }
76
+ return _native;
77
+ }
78
+ // -- Public API ---------------------------------------------------------------
79
+ /** Serialize a ServiceContract to canonical XLANG bytes via Rust core. */
80
+ export function canonicalXlangBytes(contract) {
81
+ const native = requireNative();
82
+ return new Uint8Array(native.canonicalBytesFromJson('ServiceContract', contractToJson(contract)));
83
+ }
84
+ /** Compute BLAKE3 hash of canonical bytes. Returns 64-char hex string. */
85
+ export function computeContractId(canonicalBytes) {
86
+ const native = requireNative();
87
+ const digest = native.computeTypeHash(canonicalBytes);
88
+ return Array.from(new Uint8Array(digest), b => b.toString(16).padStart(2, '0')).join('');
89
+ }
90
+ /** Compute contract ID directly from a ServiceContract (most efficient path). */
91
+ export function contractIdFromJson(contract) {
92
+ const native = requireNative();
93
+ return native.computeContractIdFromJson(contractToJson(contract));
94
+ }
95
+ /** Alias for contractIdFromJson. */
96
+ export function contractIdFromContract(contract) {
97
+ return contractIdFromJson(contract);
98
+ }
99
+ /**
100
+ * Compute a contract ID from a @Service-decorated class.
101
+ * Builds the ServiceContract from service info and computes its ID.
102
+ */
103
+ export function contractIdFromService(serviceClass) {
104
+ // Build a minimal ServiceContract from service info
105
+ const info = serviceClass[Symbol.for('aster.service_info')];
106
+ if (!info) {
107
+ throw new TypeError(`${serviceClass.name} is not decorated with @Service`);
108
+ }
109
+ const contract = {
110
+ name: info.name,
111
+ version: info.version,
112
+ methods: [],
113
+ serializationModes: [],
114
+ // Accept both the canonical 'session' value and the legacy 'stream' alias.
115
+ scoped: (info.scoped === 'session' || info.scoped === 'stream') ? 1 : 0,
116
+ requires: undefined,
117
+ };
118
+ for (const [, m] of info.methods) {
119
+ contract.methods.push({
120
+ name: m.name,
121
+ pattern: m.pattern === 'server_stream' ? 1 : m.pattern === 'client_stream' ? 2 : m.pattern === 'bidi_stream' ? 3 : 0,
122
+ requestType: new Uint8Array(32),
123
+ responseType: new Uint8Array(32),
124
+ idempotent: m.idempotent ?? false,
125
+ defaultTimeout: 0,
126
+ requires: undefined,
127
+ });
128
+ }
129
+ return contractIdFromJson(contract);
130
+ }
131
+ /**
132
+ * Build the transitive type graph for a set of @WireType classes.
133
+ * Alias for walkTypeGraph (from codec.ts) for contract identity use.
134
+ */
135
+ export function buildTypeGraph(rootTypes) {
136
+ const WIRE_TYPE_KEY = Symbol.for('aster.wire_type');
137
+ const visited = new Set();
138
+ const ordered = [];
139
+ function visit(cls) {
140
+ if (visited.has(cls))
141
+ return;
142
+ visited.add(cls);
143
+ const tag = cls[WIRE_TYPE_KEY];
144
+ if (!tag)
145
+ return;
146
+ try {
147
+ const inst = new cls();
148
+ for (const key of Object.keys(inst)) {
149
+ const ctor = inst[key]?.constructor;
150
+ if (ctor && ctor[WIRE_TYPE_KEY])
151
+ visit(ctor);
152
+ }
153
+ }
154
+ catch { /* ignore */ }
155
+ ordered.push(cls);
156
+ }
157
+ for (const cls of rootTypes)
158
+ visit(cls);
159
+ return ordered;
160
+ }
161
+ /**
162
+ * Build a ServiceContract from a ServiceInfo object.
163
+ * Used for contract identity verification.
164
+ */
165
+ export function fromServiceInfo(info) {
166
+ const contract = {
167
+ name: info.name,
168
+ version: info.version,
169
+ methods: [],
170
+ serializationModes: [],
171
+ // Accept both the canonical 'session' value and the legacy 'stream' alias.
172
+ scoped: (info.scoped === 'session' || info.scoped === 'stream') ? 1 : 0,
173
+ requires: info.requires ? { kind: info.requires.kind === 'any_of' ? 1 : 2, roles: info.requires.roles } : undefined,
174
+ };
175
+ for (const [, m] of info.methods) {
176
+ contract.methods.push({
177
+ name: m.name,
178
+ pattern: m.pattern === 'server_stream' ? 1 : m.pattern === 'client_stream' ? 2 : m.pattern === 'bidi_stream' ? 3 : 0,
179
+ requestType: new Uint8Array(32),
180
+ responseType: new Uint8Array(32),
181
+ idempotent: m.idempotent ?? false,
182
+ defaultTimeout: 0,
183
+ requires: undefined,
184
+ });
185
+ }
186
+ return contract;
187
+ }
188
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/contract/identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * ContractManifest — persisted contract identity metadata.
3
+ *
4
+ * Spec reference: Aster-ContractIdentity.md S11.4
5
+ *
6
+ * A manifest records a service contract's identity (BLAKE3 hash),
7
+ * method schemas, type hashes, and metadata. Used for:
8
+ * - Startup verification (contract hasn't changed)
9
+ * - Dynamic discovery (shell, MCP, other language clients)
10
+ * - Contract publication (registry + blobs)
11
+ */
12
+ /** Method descriptor within a manifest. */
13
+ export interface ManifestMethod {
14
+ name: string;
15
+ pattern: string;
16
+ requestType: string;
17
+ responseType: string;
18
+ timeout: number;
19
+ idempotent: boolean;
20
+ /** Request type field descriptors for dynamic invocation. */
21
+ fields: ManifestField[];
22
+ /** Fory wire tags for request/response types. */
23
+ requestWireTag?: string;
24
+ responseWireTag?: string;
25
+ /** Fory wire tags for response fields (for dynamic type synthesis). */
26
+ responseFields?: ManifestField[];
27
+ }
28
+ /** Field descriptor for dynamic invocation. */
29
+ export interface ManifestField {
30
+ name: string;
31
+ type: string;
32
+ required: boolean;
33
+ default?: unknown;
34
+ }
35
+ /** Persisted contract manifest. */
36
+ export interface ContractManifest {
37
+ service: string;
38
+ version: number;
39
+ contractId: string;
40
+ canonicalEncoding: string;
41
+ typeCount: number;
42
+ typeHashes: string[];
43
+ methodCount: number;
44
+ methods: ManifestMethod[];
45
+ serializationModes: string[];
46
+ scoped: string;
47
+ deprecated: boolean;
48
+ semver?: string;
49
+ vcsRevision?: string;
50
+ vcsTag?: string;
51
+ vcsUrl?: string;
52
+ changelog?: string;
53
+ }
54
+ /** Error raised when a live contract doesn't match the manifest. */
55
+ export declare class FatalContractMismatch extends Error {
56
+ readonly serviceName: string;
57
+ readonly serviceVersion: number;
58
+ readonly expectedId: string;
59
+ readonly actualId: string;
60
+ constructor(serviceName: string, serviceVersion: number, expectedId: string, actualId: string);
61
+ }
62
+ /** Verify that a contract ID matches the manifest. Throws on mismatch. */
63
+ export declare function verifyManifestOrFatal(manifest: ContractManifest, actualContractId: string): void;
64
+ /** Serialize a manifest to JSON. */
65
+ export declare function manifestToJson(manifest: ContractManifest): string;
66
+ /**
67
+ * Extract method descriptors from a manifest for introspection.
68
+ * Returns a simplified record of method name → pattern.
69
+ */
70
+ export declare function extractMethodDescriptors(manifest: ContractManifest): Record<string, string>;
71
+ /**
72
+ * Save a manifest to a JSON file.
73
+ */
74
+ export declare function saveManifest(manifest: ContractManifest, filePath: string): void;
75
+ /** Parse a manifest from JSON. */
76
+ export declare function manifestFromJson(json: string): ContractManifest;
77
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/contract/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,6DAA6D;IAC7D,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC;AAED,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,mCAAmC;AACnC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,oEAAoE;AACpE,qBAAa,qBAAsB,SAAQ,KAAK;aAE5B,WAAW,EAAE,MAAM;aACnB,cAAc,EAAE,MAAM;aACtB,UAAU,EAAE,MAAM;aAClB,QAAQ,EAAE,MAAM;gBAHhB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM;CAUnC;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,gBAAgB,EAC1B,gBAAgB,EAAE,MAAM,GACvB,IAAI,CASN;AAED,oCAAoC;AACpC,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CA0BjE;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAM3F;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAG/E;AAED,kCAAkC;AAClC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CA6C/D"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * ContractManifest — persisted contract identity metadata.
3
+ *
4
+ * Spec reference: Aster-ContractIdentity.md S11.4
5
+ *
6
+ * A manifest records a service contract's identity (BLAKE3 hash),
7
+ * method schemas, type hashes, and metadata. Used for:
8
+ * - Startup verification (contract hasn't changed)
9
+ * - Dynamic discovery (shell, MCP, other language clients)
10
+ * - Contract publication (registry + blobs)
11
+ */
12
+ import { MAX_MANIFEST_METHODS, MAX_MANIFEST_TYPE_HASHES } from '../limits.js';
13
+ /** Error raised when a live contract doesn't match the manifest. */
14
+ export class FatalContractMismatch extends Error {
15
+ serviceName;
16
+ serviceVersion;
17
+ expectedId;
18
+ actualId;
19
+ constructor(serviceName, serviceVersion, expectedId, actualId) {
20
+ super(`Contract identity mismatch for '${serviceName}' v${serviceVersion}:\n` +
21
+ ` expected: ${expectedId}\n` +
22
+ ` actual: ${actualId}\n` +
23
+ `This usually means the service definition changed without updating the manifest.`);
24
+ this.serviceName = serviceName;
25
+ this.serviceVersion = serviceVersion;
26
+ this.expectedId = expectedId;
27
+ this.actualId = actualId;
28
+ this.name = 'FatalContractMismatch';
29
+ }
30
+ }
31
+ /** Verify that a contract ID matches the manifest. Throws on mismatch. */
32
+ export function verifyManifestOrFatal(manifest, actualContractId) {
33
+ if (manifest.contractId !== actualContractId) {
34
+ throw new FatalContractMismatch(manifest.service, manifest.version, manifest.contractId, actualContractId);
35
+ }
36
+ }
37
+ /** Serialize a manifest to JSON. */
38
+ export function manifestToJson(manifest) {
39
+ return JSON.stringify({
40
+ service: manifest.service,
41
+ version: manifest.version,
42
+ contract_id: manifest.contractId,
43
+ canonical_encoding: manifest.canonicalEncoding,
44
+ type_count: manifest.typeCount,
45
+ type_hashes: manifest.typeHashes,
46
+ method_count: manifest.methodCount,
47
+ methods: manifest.methods.map(m => ({
48
+ name: m.name,
49
+ pattern: m.pattern,
50
+ request_type: m.requestType,
51
+ response_type: m.responseType,
52
+ timeout: m.timeout,
53
+ idempotent: m.idempotent,
54
+ fields: m.fields,
55
+ request_wire_tag: m.requestWireTag,
56
+ response_wire_tag: m.responseWireTag,
57
+ response_fields: m.responseFields,
58
+ })),
59
+ serialization_modes: manifest.serializationModes,
60
+ scoped: manifest.scoped,
61
+ deprecated: manifest.deprecated,
62
+ semver: manifest.semver,
63
+ }, null, 2);
64
+ }
65
+ /**
66
+ * Extract method descriptors from a manifest for introspection.
67
+ * Returns a simplified record of method name → pattern.
68
+ */
69
+ export function extractMethodDescriptors(manifest) {
70
+ const result = {};
71
+ for (const method of manifest.methods) {
72
+ result[method.name] = method.pattern ?? 'unary';
73
+ }
74
+ return result;
75
+ }
76
+ /**
77
+ * Save a manifest to a JSON file.
78
+ */
79
+ export function saveManifest(manifest, filePath) {
80
+ const { writeFileSync } = require('node:fs');
81
+ writeFileSync(filePath, manifestToJson(manifest), 'utf-8');
82
+ }
83
+ /** Parse a manifest from JSON. */
84
+ export function manifestFromJson(json) {
85
+ const data = JSON.parse(json);
86
+ // Validate limits
87
+ const methods = data.methods ?? [];
88
+ if (methods.length > MAX_MANIFEST_METHODS) {
89
+ throw new Error(`manifest has ${methods.length} methods, max is ${MAX_MANIFEST_METHODS}`);
90
+ }
91
+ const typeHashes = data.type_hashes ?? [];
92
+ if (typeHashes.length > MAX_MANIFEST_TYPE_HASHES) {
93
+ throw new Error(`manifest has ${typeHashes.length} type hashes, max is ${MAX_MANIFEST_TYPE_HASHES}`);
94
+ }
95
+ // Coerce version to number
96
+ const version = typeof data.version === 'string' ? parseInt(data.version, 10) : data.version;
97
+ return {
98
+ service: data.service,
99
+ version,
100
+ contractId: data.contract_id,
101
+ canonicalEncoding: data.canonical_encoding ?? 'fory-xlang/0.15',
102
+ typeCount: data.type_count ?? 0,
103
+ typeHashes,
104
+ methodCount: data.method_count ?? methods.length,
105
+ methods: methods.map((m) => ({
106
+ name: m.name,
107
+ pattern: m.pattern,
108
+ requestType: m.request_type ?? '',
109
+ responseType: m.response_type ?? '',
110
+ timeout: m.timeout ?? 0,
111
+ idempotent: m.idempotent ?? false,
112
+ fields: m.fields ?? [],
113
+ requestWireTag: m.request_wire_tag,
114
+ responseWireTag: m.response_wire_tag,
115
+ responseFields: m.response_fields,
116
+ })),
117
+ serializationModes: data.serialization_modes ?? [],
118
+ scoped: data.scoped ?? 'shared',
119
+ deprecated: data.deprecated ?? false,
120
+ semver: data.semver,
121
+ vcsRevision: data.vcs_revision,
122
+ vcsTag: data.vcs_tag,
123
+ vcsUrl: data.vcs_url,
124
+ changelog: data.changelog,
125
+ };
126
+ }
127
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/contract/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Contract publication — write contracts to registry doc + blob store.
3
+ *
4
+ * Spec reference: Aster-ContractIdentity.md S11.4
5
+ *
6
+ * On server startup, each service's contract is:
7
+ * 1. Serialized to canonical bytes
8
+ * 2. Stored as a blob collection (contract.bin + manifest.json)
9
+ * 3. Referenced in the registry doc via an ArtifactRef
10
+ */
11
+ import { type ContractManifest } from './manifest.js';
12
+ /** Reference to a contract artifact in the blob store. */
13
+ export interface ArtifactRef {
14
+ contractId: string;
15
+ collectionHash: string;
16
+ collectionTicket: string;
17
+ }
18
+ /**
19
+ * Build a collection of contract artifacts for blob storage.
20
+ *
21
+ * Returns a list of [name, data] pairs suitable for upload:
22
+ * - "manifest.json" — human/machine-readable contract metadata
23
+ * - "contract.bin" — canonical XLANG bytes (for hash verification)
24
+ *
25
+ * @param manifest - The contract manifest
26
+ * @param canonicalBytes - The canonical XLANG bytes of the ServiceContract
27
+ */
28
+ export declare function buildCollection(manifest: ContractManifest, canonicalBytes: Uint8Array): [name: string, data: Uint8Array][];
29
+ /**
30
+ * Upload a pre-built collection of [name, data] entries to the blob store
31
+ * as a native iroh HashSeq collection. GC protection is handled automatically.
32
+ * Returns the collection hash.
33
+ */
34
+ export declare function uploadCollection(blobsClient: {
35
+ addCollection(entries: [string, Uint8Array][]): Promise<string>;
36
+ }, entries: [name: string, data: Uint8Array][]): Promise<string>;
37
+ /**
38
+ * Fetch a collection from the blob store by hash using native HashSeq.
39
+ * Returns [name, data] pairs.
40
+ */
41
+ export declare function fetchFromCollection(blobsClient: {
42
+ listCollection(hash: string): Promise<Array<{
43
+ name: string;
44
+ hash: string;
45
+ size: number;
46
+ }>>;
47
+ read(hash: string): Promise<Uint8Array>;
48
+ }, collectionHash: string): Promise<[name: string, data: Uint8Array][]>;
49
+ /**
50
+ * Fetch a contract manifest from the blob store by its collection hash.
51
+ */
52
+ export declare function fetchContract(blobsClient: {
53
+ listCollection(hash: string): Promise<Array<{
54
+ name: string;
55
+ hash: string;
56
+ size: number;
57
+ }>>;
58
+ read(hash: string): Promise<Uint8Array>;
59
+ }, collectionHash: string): Promise<ContractManifest>;
60
+ /**
61
+ * Publish a contract collection to the blob store.
62
+ *
63
+ * This is the high-level function called by AsterServer on startup.
64
+ * It takes a BlobsClient (from NAPI), uploads the collection, and
65
+ * returns an ArtifactRef.
66
+ */
67
+ export declare function publishContract(blobsClient: {
68
+ addCollection(entries: [string, Uint8Array][]): Promise<string>;
69
+ createCollectionTicket(hash: string): string;
70
+ }, manifest: ContractManifest, canonicalBytes?: Uint8Array): Promise<ArtifactRef>;
71
+ //# sourceMappingURL=publication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publication.d.ts","sourceRoot":"","sources":["../../src/contract/publication.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,gBAAgB,EAAkB,MAAM,eAAe,CAAC;AAGtE,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,gBAAgB,EAC1B,cAAc,EAAE,UAAU,GACzB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,CAcpC;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE;IAAE,aAAa,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,EAChF,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,GAC1C,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE;IAAE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAAC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,EACpJ,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,CAQ7C;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE;IAAE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAAC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,EACpJ,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAM3B;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE;IAAE,aAAa,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAC9H,QAAQ,EAAE,gBAAgB,EAC1B,cAAc,CAAC,EAAE,UAAU,GAC1B,OAAO,CAAC,WAAW,CAAC,CAWtB"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Contract publication — write contracts to registry doc + blob store.
3
+ *
4
+ * Spec reference: Aster-ContractIdentity.md S11.4
5
+ *
6
+ * On server startup, each service's contract is:
7
+ * 1. Serialized to canonical bytes
8
+ * 2. Stored as a blob collection (contract.bin + manifest.json)
9
+ * 3. Referenced in the registry doc via an ArtifactRef
10
+ */
11
+ import { manifestToJson } from './manifest.js';
12
+ import { MAX_COLLECTION_INDEX_ENTRIES } from '../limits.js';
13
+ /**
14
+ * Build a collection of contract artifacts for blob storage.
15
+ *
16
+ * Returns a list of [name, data] pairs suitable for upload:
17
+ * - "manifest.json" — human/machine-readable contract metadata
18
+ * - "contract.bin" — canonical XLANG bytes (for hash verification)
19
+ *
20
+ * @param manifest - The contract manifest
21
+ * @param canonicalBytes - The canonical XLANG bytes of the ServiceContract
22
+ */
23
+ export function buildCollection(manifest, canonicalBytes) {
24
+ const encoder = new TextEncoder();
25
+ const manifestJson = manifestToJson(manifest);
26
+ const entries = [
27
+ ['manifest.json', encoder.encode(manifestJson)],
28
+ ['contract.bin', canonicalBytes],
29
+ ];
30
+ if (entries.length > MAX_COLLECTION_INDEX_ENTRIES) {
31
+ throw new Error(`collection has ${entries.length} entries, max is ${MAX_COLLECTION_INDEX_ENTRIES}`);
32
+ }
33
+ return entries;
34
+ }
35
+ /**
36
+ * Upload a pre-built collection of [name, data] entries to the blob store
37
+ * as a native iroh HashSeq collection. GC protection is handled automatically.
38
+ * Returns the collection hash.
39
+ */
40
+ export async function uploadCollection(blobsClient, entries) {
41
+ return blobsClient.addCollection(entries);
42
+ }
43
+ /**
44
+ * Fetch a collection from the blob store by hash using native HashSeq.
45
+ * Returns [name, data] pairs.
46
+ */
47
+ export async function fetchFromCollection(blobsClient, collectionHash) {
48
+ const collectionEntries = await blobsClient.listCollection(collectionHash);
49
+ const entries = [];
50
+ for (const { name, hash } of collectionEntries) {
51
+ const data = await blobsClient.read(hash);
52
+ entries.push([name, data]);
53
+ }
54
+ return entries;
55
+ }
56
+ /**
57
+ * Fetch a contract manifest from the blob store by its collection hash.
58
+ */
59
+ export async function fetchContract(blobsClient, collectionHash) {
60
+ const { manifestFromJson } = await import('./manifest.js');
61
+ const entries = await fetchFromCollection(blobsClient, collectionHash);
62
+ const manifestEntry = entries.find(([name]) => name === 'manifest.json');
63
+ if (!manifestEntry)
64
+ throw new Error('collection does not contain manifest.json');
65
+ return manifestFromJson(new TextDecoder().decode(manifestEntry[1]));
66
+ }
67
+ /**
68
+ * Publish a contract collection to the blob store.
69
+ *
70
+ * This is the high-level function called by AsterServer on startup.
71
+ * It takes a BlobsClient (from NAPI), uploads the collection, and
72
+ * returns an ArtifactRef.
73
+ */
74
+ export async function publishContract(blobsClient, manifest, canonicalBytes) {
75
+ // Build collection entries and upload as native HashSeq
76
+ const entries = buildCollection(manifest, canonicalBytes ?? new Uint8Array());
77
+ const collectionHash = await blobsClient.addCollection(entries);
78
+ const ticket = blobsClient.createCollectionTicket(collectionHash);
79
+ return {
80
+ contractId: manifest.contractId,
81
+ collectionHash,
82
+ collectionTicket: ticket,
83
+ };
84
+ }
85
+ //# sourceMappingURL=publication.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publication.js","sourceRoot":"","sources":["../../src/contract/publication.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAyB,cAAc,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAS5D;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,QAA0B,EAC1B,cAA0B;IAE1B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE9C,MAAM,OAAO,GAA2B;QACtC,CAAC,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC/C,CAAC,cAAc,EAAE,cAAc,CAAC;KACjC,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,GAAG,4BAA4B,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,CAAC,MAAM,oBAAoB,4BAA4B,EAAE,CAAC,CAAC;IACtG,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAgF,EAChF,OAA2C;IAE3C,OAAO,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAoJ,EACpJ,cAAsB;IAEtB,MAAM,iBAAiB,GAAG,MAAM,WAAW,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;IAC3E,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,iBAAiB,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAoJ,EACpJ,cAAsB;IAEtB,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;IACzE,IAAI,CAAC,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACjF,OAAO,gBAAgB,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAA8H,EAC9H,QAA0B,EAC1B,cAA2B;IAE3B,wDAAwD;IACxD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,cAAc,IAAI,IAAI,UAAU,EAAE,CAAC,CAAC;IAC9E,MAAM,cAAc,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,WAAW,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;IAElE,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,cAAc;QACd,gBAAgB,EAAE,MAAM;KACzB,CAAC;AACJ,CAAC"}