@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,77 @@
1
+ /**
2
+ * Security limits for the Aster RPC framework.
3
+ *
4
+ * All size caps, entry limits, and validation constants live here.
5
+ * Import from this module -- never hardcode limits elsewhere.
6
+ *
7
+ * Spec reference: Aster-SPEC.md S-Security, Aster-ContractIdentity.md S11.4.4.1
8
+ */
9
+ /** Maximum wire frame size in bytes (16 MiB). Spec S4.3. */
10
+ export declare const MAX_FRAME_SIZE: number;
11
+ /** Maximum decompressed payload size (16 MiB). Prevents zstd decompression bombs. */
12
+ export declare const MAX_DECOMPRESSED_SIZE: number;
13
+ /** Default timeout for reading a frame from a QUIC stream (seconds). */
14
+ export declare const DEFAULT_FRAME_READ_TIMEOUT_S = 30;
15
+ /** Server-side upper bound on handler execution time (5 minutes).
16
+ * Applied regardless of client deadline. If the client sends no deadline
17
+ * (deadlineEpochMs=0), this is used as the default. If the client sends
18
+ * a deadline further in the future, it is clamped to this value. */
19
+ export declare const MAX_HANDLER_TIMEOUT_S = 300;
20
+ /** Maximum number of items in a client-stream or bidi-stream before
21
+ * the server stops accepting. Prevents memory exhaustion from a
22
+ * malicious client sending millions of tiny frames. */
23
+ export declare const MAX_CLIENT_STREAM_ITEMS = 100000;
24
+ /** Maximum number of key-value pairs in StreamHeader/CallHeader metadata. */
25
+ export declare const MAX_METADATA_ENTRIES = 64;
26
+ /** Maximum total size of all metadata keys + values in bytes. */
27
+ export declare const MAX_METADATA_TOTAL_BYTES = 8192;
28
+ /** Maximum length of a single metadata key. */
29
+ export declare const MAX_METADATA_KEY_LEN = 256;
30
+ /** Maximum length of a single metadata value. */
31
+ export declare const MAX_METADATA_VALUE_LEN = 4096;
32
+ /** Maximum length of the RpcStatus message string. */
33
+ export declare const MAX_STATUS_MESSAGE_LEN = 4096;
34
+ /** Maximum number of detail key-value pairs in an RpcStatus. */
35
+ export declare const MAX_STATUS_DETAIL_ENTRIES = 32;
36
+ /** Maximum number of ServiceSummary entries in a ConsumerAdmissionResponse. */
37
+ export declare const MAX_SERVICES_IN_ADMISSION = 10000;
38
+ /** Maximum size of the admission request/response JSON payload. */
39
+ export declare const MAX_ADMISSION_PAYLOAD_SIZE: number;
40
+ /** Maximum number of channels per ServiceSummary. */
41
+ export declare const MAX_CHANNELS_PER_SERVICE = 100;
42
+ /** Expected hex string lengths for credential/identity fields. */
43
+ export declare const HEX_FIELD_LENGTHS: Record<string, number>;
44
+ /** Maximum number of entries in a contract collection index. */
45
+ export declare const MAX_COLLECTION_INDEX_ENTRIES = 10000;
46
+ /** Maximum length of a collection entry name. */
47
+ export declare const MAX_COLLECTION_ENTRY_NAME_LEN = 256;
48
+ /** Maximum number of entries in a registry ACL list. */
49
+ export declare const MAX_ACL_LIST_SIZE = 10000;
50
+ /** Maximum number of methods in a ContractManifest. */
51
+ export declare const MAX_MANIFEST_METHODS = 10000;
52
+ /** Maximum number of fields per method in a ContractManifest. */
53
+ export declare const MAX_MANIFEST_FIELDS_PER_METHOD = 1000;
54
+ /** Maximum number of type hashes in a ContractManifest. */
55
+ export declare const MAX_MANIFEST_TYPE_HASHES = 100000;
56
+ /** Maximum gossip message payload before JSON parsing. */
57
+ export declare const MAX_GOSSIP_PAYLOAD_SIZE: number;
58
+ /** Maximum nesting depth for JSON deserialization from untrusted sources. */
59
+ export declare const MAX_JSON_DEPTH = 50;
60
+ /** Maximum length of a service name. */
61
+ export declare const MAX_SERVICE_NAME_LEN = 256;
62
+ /** Maximum length of a method name. */
63
+ export declare const MAX_METHOD_NAME_LEN = 256;
64
+ /** Raised when a security limit is exceeded. Maps to RESOURCE_EXHAUSTED. */
65
+ export declare class LimitExceeded extends Error {
66
+ readonly field: string;
67
+ readonly limit: number;
68
+ readonly actual: number | undefined;
69
+ constructor(field: string, limit: number, actual?: number);
70
+ }
71
+ /** Validate that a hex-encoded field has the expected length. */
72
+ export declare function validateHexField(name: string, value: string): void;
73
+ /** Validate metadata key-value pairs against limits. */
74
+ export declare function validateMetadata(keys: string[], values: string[]): void;
75
+ /** Truncate an RpcStatus message to the maximum allowed length. */
76
+ export declare function validateStatusMessage(message: string): string;
77
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,4DAA4D;AAC5D,eAAO,MAAM,cAAc,QAAmB,CAAC;AAE/C,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,QAAmB,CAAC;AAEtD,wEAAwE;AACxE,eAAO,MAAM,4BAA4B,KAAO,CAAC;AAEjD;;;qEAGqE;AACrE,eAAO,MAAM,qBAAqB,MAAQ,CAAC;AAE3C;;wDAEwD;AACxD,eAAO,MAAM,uBAAuB,SAAU,CAAC;AAI/C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,iEAAiE;AACjE,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,+CAA+C;AAC/C,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAI3C,sDAAsD;AACtD,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAI5C,+EAA+E;AAC/E,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD,mEAAmE;AACnE,eAAO,MAAM,0BAA0B,QAAY,CAAC;AAEpD,qDAAqD;AACrD,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAI5C,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMpD,CAAC;AAIF,gEAAgE;AAChE,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAEnD,iDAAiD;AACjD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,uDAAuD;AACvD,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,iEAAiE;AACjE,eAAO,MAAM,8BAA8B,OAAQ,CAAC;AAEpD,2DAA2D;AAC3D,eAAO,MAAM,wBAAwB,SAAU,CAAC;AAIhD,0DAA0D;AAC1D,eAAO,MAAM,uBAAuB,QAAY,CAAC;AAEjD,6EAA6E;AAC7E,eAAO,MAAM,cAAc,KAAK,CAAC;AAIjC,wCAAwC;AACxC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,uCAAuC;AACvC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAIvC,4EAA4E;AAC5E,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;gBAExB,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAQ1D;AAID,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAWlE;AAID,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAwBvE;AAED,mEAAmE;AACnE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK7D"}
package/dist/limits.js ADDED
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Security limits for the Aster RPC framework.
3
+ *
4
+ * All size caps, entry limits, and validation constants live here.
5
+ * Import from this module -- never hardcode limits elsewhere.
6
+ *
7
+ * Spec reference: Aster-SPEC.md S-Security, Aster-ContractIdentity.md S11.4.4.1
8
+ */
9
+ // -- Wire-level limits -------------------------------------------------------
10
+ /** Maximum wire frame size in bytes (16 MiB). Spec S4.3. */
11
+ export const MAX_FRAME_SIZE = 16 * 1024 * 1024;
12
+ /** Maximum decompressed payload size (16 MiB). Prevents zstd decompression bombs. */
13
+ export const MAX_DECOMPRESSED_SIZE = 16 * 1024 * 1024;
14
+ /** Default timeout for reading a frame from a QUIC stream (seconds). */
15
+ export const DEFAULT_FRAME_READ_TIMEOUT_S = 30.0;
16
+ /** Server-side upper bound on handler execution time (5 minutes).
17
+ * Applied regardless of client deadline. If the client sends no deadline
18
+ * (deadlineEpochMs=0), this is used as the default. If the client sends
19
+ * a deadline further in the future, it is clamped to this value. */
20
+ export const MAX_HANDLER_TIMEOUT_S = 300.0;
21
+ /** Maximum number of items in a client-stream or bidi-stream before
22
+ * the server stops accepting. Prevents memory exhaustion from a
23
+ * malicious client sending millions of tiny frames. */
24
+ export const MAX_CLIENT_STREAM_ITEMS = 100_000;
25
+ // -- Metadata limits ---------------------------------------------------------
26
+ /** Maximum number of key-value pairs in StreamHeader/CallHeader metadata. */
27
+ export const MAX_METADATA_ENTRIES = 64;
28
+ /** Maximum total size of all metadata keys + values in bytes. */
29
+ export const MAX_METADATA_TOTAL_BYTES = 8192;
30
+ /** Maximum length of a single metadata key. */
31
+ export const MAX_METADATA_KEY_LEN = 256;
32
+ /** Maximum length of a single metadata value. */
33
+ export const MAX_METADATA_VALUE_LEN = 4096;
34
+ // -- RPC status limits -------------------------------------------------------
35
+ /** Maximum length of the RpcStatus message string. */
36
+ export const MAX_STATUS_MESSAGE_LEN = 4096;
37
+ /** Maximum number of detail key-value pairs in an RpcStatus. */
38
+ export const MAX_STATUS_DETAIL_ENTRIES = 32;
39
+ // -- Admission limits --------------------------------------------------------
40
+ /** Maximum number of ServiceSummary entries in a ConsumerAdmissionResponse. */
41
+ export const MAX_SERVICES_IN_ADMISSION = 10_000;
42
+ /** Maximum size of the admission request/response JSON payload. */
43
+ export const MAX_ADMISSION_PAYLOAD_SIZE = 64 * 1024;
44
+ /** Maximum number of channels per ServiceSummary. */
45
+ export const MAX_CHANNELS_PER_SERVICE = 100;
46
+ // -- Credential field lengths (hex characters) --------------------------------
47
+ /** Expected hex string lengths for credential/identity fields. */
48
+ export const HEX_FIELD_LENGTHS = {
49
+ root_pubkey: 64, // 32 bytes -> 64 hex chars
50
+ nonce: 64,
51
+ signature: 128, // 64 bytes -> 128 hex chars
52
+ endpoint_id: 64,
53
+ contract_id: 64,
54
+ };
55
+ // -- Registry / collection limits --------------------------------------------
56
+ /** Maximum number of entries in a contract collection index. */
57
+ export const MAX_COLLECTION_INDEX_ENTRIES = 10_000;
58
+ /** Maximum length of a collection entry name. */
59
+ export const MAX_COLLECTION_ENTRY_NAME_LEN = 256;
60
+ /** Maximum number of entries in a registry ACL list. */
61
+ export const MAX_ACL_LIST_SIZE = 10_000;
62
+ /** Maximum number of methods in a ContractManifest. */
63
+ export const MAX_MANIFEST_METHODS = 10_000;
64
+ /** Maximum number of fields per method in a ContractManifest. */
65
+ export const MAX_MANIFEST_FIELDS_PER_METHOD = 1_000;
66
+ /** Maximum number of type hashes in a ContractManifest. */
67
+ export const MAX_MANIFEST_TYPE_HASHES = 100_000;
68
+ // -- Gossip limits -----------------------------------------------------------
69
+ /** Maximum gossip message payload before JSON parsing. */
70
+ export const MAX_GOSSIP_PAYLOAD_SIZE = 64 * 1024;
71
+ /** Maximum nesting depth for JSON deserialization from untrusted sources. */
72
+ export const MAX_JSON_DEPTH = 50;
73
+ // -- General string limits ---------------------------------------------------
74
+ /** Maximum length of a service name. */
75
+ export const MAX_SERVICE_NAME_LEN = 256;
76
+ /** Maximum length of a method name. */
77
+ export const MAX_METHOD_NAME_LEN = 256;
78
+ // -- Validation helpers -------------------------------------------------------
79
+ /** Raised when a security limit is exceeded. Maps to RESOURCE_EXHAUSTED. */
80
+ export class LimitExceeded extends Error {
81
+ field;
82
+ limit;
83
+ actual;
84
+ constructor(field, limit, actual) {
85
+ const detail = actual !== undefined ? ` (got ${actual})` : '';
86
+ super(`${field} exceeds limit of ${limit}${detail}`);
87
+ this.name = 'LimitExceeded';
88
+ this.field = field;
89
+ this.limit = limit;
90
+ this.actual = actual;
91
+ }
92
+ }
93
+ const HEX_REGEX = /^[0-9a-fA-F]*$/;
94
+ /** Validate that a hex-encoded field has the expected length. */
95
+ export function validateHexField(name, value) {
96
+ if (!value)
97
+ return; // empty is allowed (optional fields)
98
+ const expected = HEX_FIELD_LENGTHS[name];
99
+ if (expected !== undefined && value.length !== expected) {
100
+ throw new LimitExceeded(name, expected, value.length);
101
+ }
102
+ if (!HEX_REGEX.test(value)) {
103
+ throw new Error(`${name}: invalid hex string`);
104
+ }
105
+ }
106
+ const encoder = new TextEncoder();
107
+ /** Validate metadata key-value pairs against limits. */
108
+ export function validateMetadata(keys, values) {
109
+ const count = keys.length;
110
+ if (count > MAX_METADATA_ENTRIES) {
111
+ throw new LimitExceeded('metadata entries', MAX_METADATA_ENTRIES, count);
112
+ }
113
+ let totalBytes = 0;
114
+ for (const k of keys) {
115
+ if (k.length > MAX_METADATA_KEY_LEN) {
116
+ throw new LimitExceeded('metadata key length', MAX_METADATA_KEY_LEN, k.length);
117
+ }
118
+ totalBytes += encoder.encode(k).byteLength;
119
+ }
120
+ for (const v of values) {
121
+ if (v.length > MAX_METADATA_VALUE_LEN) {
122
+ throw new LimitExceeded('metadata value length', MAX_METADATA_VALUE_LEN, v.length);
123
+ }
124
+ totalBytes += encoder.encode(v).byteLength;
125
+ }
126
+ if (totalBytes > MAX_METADATA_TOTAL_BYTES) {
127
+ throw new LimitExceeded('metadata total bytes', MAX_METADATA_TOTAL_BYTES, totalBytes);
128
+ }
129
+ }
130
+ /** Truncate an RpcStatus message to the maximum allowed length. */
131
+ export function validateStatusMessage(message) {
132
+ if (message.length > MAX_STATUS_MESSAGE_LEN) {
133
+ return message.slice(0, MAX_STATUS_MESSAGE_LEN - 3) + '...';
134
+ }
135
+ return message;
136
+ }
137
+ //# sourceMappingURL=limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Structured logging for Aster services.
3
+ *
4
+ * Provides JSON and text format logging with request correlation,
5
+ * sensitive field masking, and standard log fields.
6
+ */
7
+ /** Request context stored via AsyncLocalStorage for correlation. */
8
+ export interface RequestContext {
9
+ service: string;
10
+ method: string;
11
+ requestId: string;
12
+ peer?: string;
13
+ }
14
+ /** Run a callback with request context attached to all logs within. */
15
+ export declare function withRequestContext<T>(ctx: RequestContext, fn: () => T): T;
16
+ /** Get the current request context (if any). */
17
+ export declare function getRequestContext(): RequestContext | undefined;
18
+ type LogLevel = 'debug' | 'info' | 'warning' | 'error';
19
+ export interface LoggerOptions {
20
+ format?: 'json' | 'text';
21
+ level?: LogLevel;
22
+ mask?: boolean;
23
+ }
24
+ /** Simple structured logger. For production, swap with pino. */
25
+ export declare class AsterLogger {
26
+ private format;
27
+ private minLevel;
28
+ private mask;
29
+ constructor(opts?: LoggerOptions);
30
+ debug(msg: string, fields?: Record<string, unknown>): void;
31
+ info(msg: string, fields?: Record<string, unknown>): void;
32
+ warning(msg: string, fields?: Record<string, unknown>): void;
33
+ warn(msg: string, fields?: Record<string, unknown>): void;
34
+ error(msg: string, fields?: Record<string, unknown>): void;
35
+ private log;
36
+ }
37
+ /** Create a logger from AsterConfig values. */
38
+ export declare function createLogger(opts?: LoggerOptions): AsterLogger;
39
+ export {};
40
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,oEAAoE;AACpE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEzE;AAED,gDAAgD;AAChD,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D;AAED,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AA4BvD,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,gEAAgE;AAChE,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAU;gBAEV,IAAI,CAAC,EAAE,aAAa;IAMhC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAC1D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IACzD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAC5D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAE1D,OAAO,CAAC,GAAG;CAgCZ;AAED,+CAA+C;AAC/C,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,WAAW,CAE9D"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Structured logging for Aster services.
3
+ *
4
+ * Provides JSON and text format logging with request correlation,
5
+ * sensitive field masking, and standard log fields.
6
+ */
7
+ import { AsyncLocalStorage } from 'node:async_hooks';
8
+ const requestContext = new AsyncLocalStorage();
9
+ /** Run a callback with request context attached to all logs within. */
10
+ export function withRequestContext(ctx, fn) {
11
+ return requestContext.run(ctx, fn);
12
+ }
13
+ /** Get the current request context (if any). */
14
+ export function getRequestContext() {
15
+ return requestContext.getStore();
16
+ }
17
+ const LEVEL_ORDER = {
18
+ debug: 0,
19
+ info: 1,
20
+ warning: 2,
21
+ error: 3,
22
+ };
23
+ /** Sensitive fields that are masked in log output. */
24
+ const SENSITIVE_FIELDS = new Set([
25
+ 'secret_key', 'private_key', 'signing_key', 'signature', 'credential_json',
26
+ ]);
27
+ /** Identifier fields that are truncated. */
28
+ const TRUNCATE_FIELDS = new Set([
29
+ 'root_pubkey', 'endpoint_id', 'node_id', 'contract_id', 'nonce',
30
+ ]);
31
+ function maskValue(key, value, mask) {
32
+ if (!mask)
33
+ return value;
34
+ if (SENSITIVE_FIELDS.has(key))
35
+ return '***';
36
+ if (TRUNCATE_FIELDS.has(key) && typeof value === 'string' && value.length > 12) {
37
+ return `${value.slice(0, 7)}...${value.slice(-4)}`;
38
+ }
39
+ return value;
40
+ }
41
+ /** Simple structured logger. For production, swap with pino. */
42
+ export class AsterLogger {
43
+ format;
44
+ minLevel;
45
+ mask;
46
+ constructor(opts) {
47
+ this.format = opts?.format ?? 'text';
48
+ this.minLevel = LEVEL_ORDER[opts?.level ?? 'info'];
49
+ this.mask = opts?.mask ?? true;
50
+ }
51
+ debug(msg, fields) { this.log('debug', msg, fields); }
52
+ info(msg, fields) { this.log('info', msg, fields); }
53
+ warning(msg, fields) { this.log('warning', msg, fields); }
54
+ warn(msg, fields) { this.log('warning', msg, fields); }
55
+ error(msg, fields) { this.log('error', msg, fields); }
56
+ log(level, msg, fields) {
57
+ if (LEVEL_ORDER[level] < this.minLevel)
58
+ return;
59
+ const ctx = getRequestContext();
60
+ const entry = {
61
+ ts: new Date().toISOString(),
62
+ level,
63
+ msg,
64
+ };
65
+ if (ctx) {
66
+ entry.service = ctx.service;
67
+ entry.method = ctx.method;
68
+ entry.request_id = ctx.requestId;
69
+ if (ctx.peer)
70
+ entry.peer = maskValue('endpoint_id', ctx.peer, this.mask);
71
+ }
72
+ if (fields) {
73
+ for (const [k, v] of Object.entries(fields)) {
74
+ entry[k] = maskValue(k, v, this.mask);
75
+ }
76
+ }
77
+ if (this.format === 'json') {
78
+ console.log(JSON.stringify(entry));
79
+ }
80
+ else {
81
+ const time = new Date().toLocaleTimeString('en-US', { hour12: false });
82
+ const ctxStr = ctx ? ` [svc=${ctx.service} method=${ctx.method} req=${ctx.requestId.slice(0, 8)}]` : '';
83
+ const fieldStr = fields ? ' ' + Object.entries(fields).map(([k, v]) => `${k}=${maskValue(k, v, this.mask)}`).join(' ') : '';
84
+ console.log(`${time} ${level.toUpperCase().padEnd(7)} ${msg}${ctxStr}${fieldStr}`);
85
+ }
86
+ }
87
+ }
88
+ /** Create a logger from AsterConfig values. */
89
+ export function createLogger(opts) {
90
+ return new AsterLogger(opts);
91
+ }
92
+ //# sourceMappingURL=logging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Metadata — extensible semantic documentation for services, methods, and fields.
3
+ *
4
+ * Provides descriptions that AI agents (via MCP) and humans can use to
5
+ * understand what services do and how to populate request fields.
6
+ *
7
+ * Metadata is NON-CANONICAL — it does NOT affect contract identity (BLAKE3 hash)
8
+ * and does NOT appear in the wire protocol.
9
+ */
10
+ export declare class Metadata {
11
+ description: string;
12
+ constructor(init?: Partial<Metadata>);
13
+ }
14
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,qBACa,QAAQ;IACnB,WAAW,SAAM;gBAEL,IAAI,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC;CAGrC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Metadata — extensible semantic documentation for services, methods, and fields.
3
+ *
4
+ * Provides descriptions that AI agents (via MCP) and humans can use to
5
+ * understand what services do and how to populate request fields.
6
+ *
7
+ * Metadata is NON-CANONICAL — it does NOT affect contract identity (BLAKE3 hash)
8
+ * and does NOT appear in the wire protocol.
9
+ */
10
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
11
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
12
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
13
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
14
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
15
+ var _, done = false;
16
+ for (var i = decorators.length - 1; i >= 0; i--) {
17
+ var context = {};
18
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
19
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
20
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
21
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
22
+ if (kind === "accessor") {
23
+ if (result === void 0) continue;
24
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
25
+ if (_ = accept(result.get)) descriptor.get = _;
26
+ if (_ = accept(result.set)) descriptor.set = _;
27
+ if (_ = accept(result.init)) initializers.unshift(_);
28
+ }
29
+ else if (_ = accept(result)) {
30
+ if (kind === "field") initializers.unshift(_);
31
+ else descriptor[key] = _;
32
+ }
33
+ }
34
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
35
+ done = true;
36
+ };
37
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
38
+ var useValue = arguments.length > 2;
39
+ for (var i = 0; i < initializers.length; i++) {
40
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
41
+ }
42
+ return useValue ? value : void 0;
43
+ };
44
+ import { WireType } from './decorators.js';
45
+ let Metadata = (() => {
46
+ let _classDecorators = [WireType('_aster/Metadata')];
47
+ let _classDescriptor;
48
+ let _classExtraInitializers = [];
49
+ let _classThis;
50
+ var Metadata = class {
51
+ static { _classThis = this; }
52
+ static {
53
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
54
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
55
+ Metadata = _classThis = _classDescriptor.value;
56
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
57
+ __runInitializers(_classThis, _classExtraInitializers);
58
+ }
59
+ description = '';
60
+ constructor(init) {
61
+ if (init)
62
+ Object.assign(this, init);
63
+ }
64
+ };
65
+ return Metadata = _classThis;
66
+ })();
67
+ export { Metadata };
68
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;IAG9B,QAAQ;4BADpB,QAAQ,CAAC,iBAAiB,CAAC;;;;;;;;YAC5B,6KAMC;;;YANY,uDAAQ;;QACnB,WAAW,GAAG,EAAE,CAAC;QAEjB,YAAY,IAAwB;YAClC,IAAI,IAAI;gBAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;;;;SALU,QAAQ"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Connection and admission metrics.
3
+ *
4
+ * Lightweight in-memory counters for monitoring connection and
5
+ * admission activity. Complements the RPC-level MetricsInterceptor.
6
+ */
7
+ /** Connection metrics counters. */
8
+ export declare class ConnectionMetrics {
9
+ connectionsAccepted: number;
10
+ connectionsRejected: number;
11
+ connectionsClosed: number;
12
+ connectionsActive: number;
13
+ /** Currently active RPC streams. */
14
+ streamsActive: number;
15
+ /** Total streams handled since startup. */
16
+ streamsTotal: number;
17
+ onAccept(): void;
18
+ onReject(): void;
19
+ onClose(): void;
20
+ onStreamOpen(): void;
21
+ onStreamClose(): void;
22
+ snapshot(): Record<string, number>;
23
+ reset(): void;
24
+ }
25
+ /** Admission metrics counters. */
26
+ export declare class AdmissionMetrics {
27
+ admissionsAttempted: number;
28
+ admissionsSucceeded: number;
29
+ admissionsRejected: number;
30
+ admissionsErrored: number;
31
+ /** Duration of the last admission handshake in milliseconds. */
32
+ lastAdmissionMs: number;
33
+ onAttempt(): void;
34
+ onSuccess(durationMs?: number): void;
35
+ onReject(): void;
36
+ onError(): void;
37
+ snapshot(): Record<string, number>;
38
+ reset(): void;
39
+ }
40
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,mCAAmC;AACnC,qBAAa,iBAAiB;IAC5B,mBAAmB,SAAK;IACxB,mBAAmB,SAAK;IACxB,iBAAiB,SAAK;IACtB,iBAAiB,SAAK;IAEtB,oCAAoC;IACpC,aAAa,SAAK;IAClB,2CAA2C;IAC3C,YAAY,SAAK;IAEjB,QAAQ,IAAI,IAAI;IAKhB,QAAQ,IAAI,IAAI;IAIhB,OAAO,IAAI,IAAI;IAKf,YAAY,IAAI,IAAI;IAKpB,aAAa,IAAI,IAAI;IAIrB,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAWlC,KAAK,IAAI,IAAI;CAQd;AAED,kCAAkC;AAClC,qBAAa,gBAAgB;IAC3B,mBAAmB,SAAK;IACxB,mBAAmB,SAAK;IACxB,kBAAkB,SAAK;IACvB,iBAAiB,SAAK;IACtB,gEAAgE;IAChE,eAAe,SAAK;IAEpB,SAAS,IAAI,IAAI;IAIjB,SAAS,CAAC,UAAU,SAAI,GAAG,IAAI;IAK/B,QAAQ,IAAI,IAAI;IAIhB,OAAO,IAAI,IAAI;IAIf,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAUlC,KAAK,IAAI,IAAI;CAOd"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Connection and admission metrics.
3
+ *
4
+ * Lightweight in-memory counters for monitoring connection and
5
+ * admission activity. Complements the RPC-level MetricsInterceptor.
6
+ */
7
+ /** Connection metrics counters. */
8
+ export class ConnectionMetrics {
9
+ connectionsAccepted = 0;
10
+ connectionsRejected = 0;
11
+ connectionsClosed = 0;
12
+ connectionsActive = 0;
13
+ /** Currently active RPC streams. */
14
+ streamsActive = 0;
15
+ /** Total streams handled since startup. */
16
+ streamsTotal = 0;
17
+ onAccept() {
18
+ this.connectionsAccepted++;
19
+ this.connectionsActive++;
20
+ }
21
+ onReject() {
22
+ this.connectionsRejected++;
23
+ }
24
+ onClose() {
25
+ this.connectionsClosed++;
26
+ this.connectionsActive = Math.max(0, this.connectionsActive - 1);
27
+ }
28
+ onStreamOpen() {
29
+ this.streamsActive++;
30
+ this.streamsTotal++;
31
+ }
32
+ onStreamClose() {
33
+ this.streamsActive = Math.max(0, this.streamsActive - 1);
34
+ }
35
+ snapshot() {
36
+ return {
37
+ connections_accepted: this.connectionsAccepted,
38
+ connections_rejected: this.connectionsRejected,
39
+ connections_closed: this.connectionsClosed,
40
+ connections_active: this.connectionsActive,
41
+ streams_active: this.streamsActive,
42
+ streams_total: this.streamsTotal,
43
+ };
44
+ }
45
+ reset() {
46
+ this.connectionsAccepted = 0;
47
+ this.connectionsRejected = 0;
48
+ this.connectionsClosed = 0;
49
+ this.connectionsActive = 0;
50
+ this.streamsActive = 0;
51
+ this.streamsTotal = 0;
52
+ }
53
+ }
54
+ /** Admission metrics counters. */
55
+ export class AdmissionMetrics {
56
+ admissionsAttempted = 0;
57
+ admissionsSucceeded = 0;
58
+ admissionsRejected = 0;
59
+ admissionsErrored = 0;
60
+ /** Duration of the last admission handshake in milliseconds. */
61
+ lastAdmissionMs = 0;
62
+ onAttempt() {
63
+ this.admissionsAttempted++;
64
+ }
65
+ onSuccess(durationMs = 0) {
66
+ this.admissionsSucceeded++;
67
+ this.lastAdmissionMs = durationMs;
68
+ }
69
+ onReject() {
70
+ this.admissionsRejected++;
71
+ }
72
+ onError() {
73
+ this.admissionsErrored++;
74
+ }
75
+ snapshot() {
76
+ return {
77
+ admissions_attempted: this.admissionsAttempted,
78
+ admissions_succeeded: this.admissionsSucceeded,
79
+ admissions_rejected: this.admissionsRejected,
80
+ admissions_errored: this.admissionsErrored,
81
+ last_admission_ms: this.lastAdmissionMs,
82
+ };
83
+ }
84
+ reset() {
85
+ this.admissionsAttempted = 0;
86
+ this.admissionsSucceeded = 0;
87
+ this.admissionsRejected = 0;
88
+ this.admissionsErrored = 0;
89
+ this.lastAdmissionMs = 0;
90
+ }
91
+ }
92
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,mCAAmC;AACnC,MAAM,OAAO,iBAAiB;IAC5B,mBAAmB,GAAG,CAAC,CAAC;IACxB,mBAAmB,GAAG,CAAC,CAAC;IACxB,iBAAiB,GAAG,CAAC,CAAC;IACtB,iBAAiB,GAAG,CAAC,CAAC;IAEtB,oCAAoC;IACpC,aAAa,GAAG,CAAC,CAAC;IAClB,2CAA2C;IAC3C,YAAY,GAAG,CAAC,CAAC;IAEjB,QAAQ;QACN,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO;QACL,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,YAAY;QACV,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,aAAa;QACX,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,QAAQ;QACN,OAAO;YACL,oBAAoB,EAAE,IAAI,CAAC,mBAAmB;YAC9C,oBAAoB,EAAE,IAAI,CAAC,mBAAmB;YAC9C,kBAAkB,EAAE,IAAI,CAAC,iBAAiB;YAC1C,kBAAkB,EAAE,IAAI,CAAC,iBAAiB;YAC1C,cAAc,EAAE,IAAI,CAAC,aAAa;YAClC,aAAa,EAAE,IAAI,CAAC,YAAY;SACjC,CAAC;IACJ,CAAC;IAED,KAAK;QACH,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;IACxB,CAAC;CACF;AAED,kCAAkC;AAClC,MAAM,OAAO,gBAAgB;IAC3B,mBAAmB,GAAG,CAAC,CAAC;IACxB,mBAAmB,GAAG,CAAC,CAAC;IACxB,kBAAkB,GAAG,CAAC,CAAC;IACvB,iBAAiB,GAAG,CAAC,CAAC;IACtB,gEAAgE;IAChE,eAAe,GAAG,CAAC,CAAC;IAEpB,SAAS;QACP,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED,SAAS,CAAC,UAAU,GAAG,CAAC;QACtB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC;IACpC,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO;QACL,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAED,QAAQ;QACN,OAAO;YACL,oBAAoB,EAAE,IAAI,CAAC,mBAAmB;YAC9C,oBAAoB,EAAE,IAAI,CAAC,mBAAmB;YAC9C,mBAAmB,EAAE,IAAI,CAAC,kBAAkB;YAC5C,kBAAkB,EAAE,IAAI,CAAC,iBAAiB;YAC1C,iBAAiB,EAAE,IAAI,CAAC,eAAe;SACxC,CAAC;IACJ,CAAC;IAED,KAAK;QACH,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF"}