@aztec/foundation 0.0.1-commit.2ed92850 → 0.0.1-commit.2f68f620

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 (322) hide show
  1. package/dest/array/sorted_array.d.ts +6 -1
  2. package/dest/array/sorted_array.d.ts.map +1 -1
  3. package/dest/array/sorted_array.js +18 -15
  4. package/dest/bigint-buffer/index.d.ts +1 -1
  5. package/dest/bigint-buffer/index.d.ts.map +1 -1
  6. package/dest/bigint-buffer/index.js +6 -1
  7. package/dest/branded-types/block_number.d.ts +3 -3
  8. package/dest/branded-types/block_number.d.ts.map +1 -1
  9. package/dest/branded-types/block_number.js +15 -4
  10. package/dest/branded-types/buffer32_hash.d.ts +27 -0
  11. package/dest/branded-types/buffer32_hash.d.ts.map +1 -0
  12. package/dest/branded-types/buffer32_hash.js +12 -0
  13. package/dest/branded-types/checkpoint_number.d.ts +9 -3
  14. package/dest/branded-types/checkpoint_number.d.ts.map +1 -1
  15. package/dest/branded-types/checkpoint_number.js +11 -0
  16. package/dest/branded-types/epoch.d.ts +2 -2
  17. package/dest/branded-types/epoch.d.ts.map +1 -1
  18. package/dest/branded-types/index.d.ts +2 -1
  19. package/dest/branded-types/index.d.ts.map +1 -1
  20. package/dest/branded-types/index.js +1 -0
  21. package/dest/branded-types/index_within_checkpoint.d.ts +2 -2
  22. package/dest/branded-types/index_within_checkpoint.d.ts.map +1 -1
  23. package/dest/branded-types/slot.d.ts +5 -2
  24. package/dest/branded-types/slot.d.ts.map +1 -1
  25. package/dest/branded-types/slot.js +3 -0
  26. package/dest/buffer/buffer16.d.ts +3 -1
  27. package/dest/buffer/buffer16.d.ts.map +1 -1
  28. package/dest/buffer/buffer32.d.ts +28 -61
  29. package/dest/buffer/buffer32.d.ts.map +1 -1
  30. package/dest/buffer/buffer32.js +29 -63
  31. package/dest/buffer/index.d.ts +2 -1
  32. package/dest/buffer/index.d.ts.map +1 -1
  33. package/dest/buffer/index.js +1 -0
  34. package/dest/buffer/utils.d.ts +3 -0
  35. package/dest/buffer/utils.d.ts.map +1 -0
  36. package/dest/buffer/utils.js +7 -0
  37. package/dest/collection/array.d.ts +17 -1
  38. package/dest/collection/array.d.ts.map +1 -1
  39. package/dest/collection/array.js +57 -0
  40. package/dest/collection/index.d.ts +3 -1
  41. package/dest/collection/index.d.ts.map +1 -1
  42. package/dest/collection/index.js +2 -0
  43. package/dest/collection/lru_map.d.ts +41 -0
  44. package/dest/collection/lru_map.d.ts.map +1 -0
  45. package/dest/collection/lru_map.js +119 -0
  46. package/dest/collection/lru_set.d.ts +35 -0
  47. package/dest/collection/lru_set.d.ts.map +1 -0
  48. package/dest/collection/lru_set.js +95 -0
  49. package/dest/committable/committable.js +1 -1
  50. package/dest/config/env_var.d.ts +2 -2
  51. package/dest/config/env_var.d.ts.map +1 -1
  52. package/dest/config/index.d.ts +47 -30
  53. package/dest/config/index.d.ts.map +1 -1
  54. package/dest/config/index.js +44 -44
  55. package/dest/config/network_config.d.ts +15 -41
  56. package/dest/config/network_config.d.ts.map +1 -1
  57. package/dest/config/network_config.js +4 -1
  58. package/dest/config/network_name.d.ts +2 -2
  59. package/dest/config/network_name.d.ts.map +1 -1
  60. package/dest/config/network_name.js +3 -3
  61. package/dest/config/secret_value.d.ts +2 -2
  62. package/dest/config/secret_value.d.ts.map +1 -1
  63. package/dest/crypto/aes128/index.d.ts +2 -1
  64. package/dest/crypto/aes128/index.d.ts.map +1 -1
  65. package/dest/crypto/aes128/index.js +11 -2
  66. package/dest/crypto/bls/bn254_keystore.d.ts +10 -177
  67. package/dest/crypto/bls/bn254_keystore.d.ts.map +1 -1
  68. package/dest/crypto/bls/bn254_keystore.js +22 -34
  69. package/dest/crypto/poseidon/index.d.ts +1 -1
  70. package/dest/crypto/poseidon/index.d.ts.map +1 -1
  71. package/dest/crypto/poseidon/index.js +40 -33
  72. package/dest/crypto/random/randomness_singleton.d.ts +4 -3
  73. package/dest/crypto/random/randomness_singleton.d.ts.map +1 -1
  74. package/dest/crypto/random/randomness_singleton.js +4 -4
  75. package/dest/crypto/schnorr/index.d.ts +8 -7
  76. package/dest/crypto/schnorr/index.d.ts.map +1 -1
  77. package/dest/crypto/schnorr/index.js +6 -6
  78. package/dest/crypto/schnorr/signature.d.ts +9 -29
  79. package/dest/crypto/schnorr/signature.d.ts.map +1 -1
  80. package/dest/crypto/schnorr/signature.js +20 -36
  81. package/dest/crypto/secp256k1-signer/utils.d.ts +12 -1
  82. package/dest/crypto/secp256k1-signer/utils.d.ts.map +1 -1
  83. package/dest/crypto/secp256k1-signer/utils.js +26 -0
  84. package/dest/curves/bls12/field.d.ts +3 -3
  85. package/dest/curves/bls12/field.d.ts.map +1 -1
  86. package/dest/curves/bls12/field.js +0 -5
  87. package/dest/curves/bls12/point.d.ts +2 -2
  88. package/dest/curves/bls12/point.d.ts.map +1 -1
  89. package/dest/curves/bn254/field.d.ts +24 -19
  90. package/dest/curves/bn254/field.d.ts.map +1 -1
  91. package/dest/curves/bn254/field.js +28 -19
  92. package/dest/curves/grumpkin/point.d.ts +14 -28
  93. package/dest/curves/grumpkin/point.d.ts.map +1 -1
  94. package/dest/curves/grumpkin/point.js +29 -43
  95. package/dest/eth-address/index.d.ts +2 -2
  96. package/dest/eth-address/index.d.ts.map +1 -1
  97. package/dest/eth-address/index.js +0 -3
  98. package/dest/eth-signature/eth_signature.d.ts +3 -2
  99. package/dest/eth-signature/eth_signature.d.ts.map +1 -1
  100. package/dest/eth-signature/eth_signature.js +7 -2
  101. package/dest/fifo/fifo_frame_reader.d.ts +41 -0
  102. package/dest/fifo/fifo_frame_reader.d.ts.map +1 -0
  103. package/dest/fifo/fifo_frame_reader.js +91 -0
  104. package/dest/fifo/index.d.ts +2 -0
  105. package/dest/fifo/index.d.ts.map +1 -0
  106. package/dest/fifo/index.js +1 -0
  107. package/dest/fifo_set/fifo_set.d.ts +15 -0
  108. package/dest/fifo_set/fifo_set.d.ts.map +1 -0
  109. package/dest/fifo_set/fifo_set.js +39 -0
  110. package/dest/fifo_set/index.d.ts +2 -0
  111. package/dest/fifo_set/index.d.ts.map +1 -0
  112. package/dest/fifo_set/index.js +1 -0
  113. package/dest/jest/setup.js +28 -1
  114. package/dest/json-rpc/client/fetch.d.ts +1 -1
  115. package/dest/json-rpc/client/fetch.d.ts.map +1 -1
  116. package/dest/json-rpc/client/fetch.js +4 -3
  117. package/dest/json-rpc/client/safe_json_rpc_client.d.ts +2 -1
  118. package/dest/json-rpc/client/safe_json_rpc_client.d.ts.map +1 -1
  119. package/dest/json-rpc/client/safe_json_rpc_client.js +3 -3
  120. package/dest/json-rpc/client/undici.d.ts +1 -1
  121. package/dest/json-rpc/client/undici.d.ts.map +1 -1
  122. package/dest/json-rpc/client/undici.js +5 -3
  123. package/dest/json-rpc/fixtures/test_state.d.ts +4 -8
  124. package/dest/json-rpc/fixtures/test_state.d.ts.map +1 -1
  125. package/dest/json-rpc/fixtures/test_state.js +57 -17
  126. package/dest/json-rpc/server/api_key_auth.d.ts +19 -0
  127. package/dest/json-rpc/server/api_key_auth.d.ts.map +1 -0
  128. package/dest/json-rpc/server/api_key_auth.js +57 -0
  129. package/dest/json-rpc/server/index.d.ts +2 -1
  130. package/dest/json-rpc/server/index.d.ts.map +1 -1
  131. package/dest/json-rpc/server/index.js +1 -0
  132. package/dest/json-rpc/server/safe_json_rpc_server.d.ts +8 -3
  133. package/dest/json-rpc/server/safe_json_rpc_server.d.ts.map +1 -1
  134. package/dest/json-rpc/server/safe_json_rpc_server.js +27 -13
  135. package/dest/log/bigint-utils.d.ts +5 -0
  136. package/dest/log/bigint-utils.d.ts.map +1 -0
  137. package/dest/log/bigint-utils.js +21 -0
  138. package/dest/log/gcloud-logger-config.d.ts +1 -1
  139. package/dest/log/gcloud-logger-config.d.ts.map +1 -1
  140. package/dest/log/gcloud-logger-config.js +3 -0
  141. package/dest/log/libp2p_logger.d.ts +5 -2
  142. package/dest/log/libp2p_logger.d.ts.map +1 -1
  143. package/dest/log/libp2p_logger.js +14 -4
  144. package/dest/log/log-filters.d.ts +17 -4
  145. package/dest/log/log-filters.d.ts.map +1 -1
  146. package/dest/log/log-filters.js +26 -12
  147. package/dest/log/pino-logger-server.d.ts +9 -0
  148. package/dest/log/pino-logger-server.d.ts.map +1 -0
  149. package/dest/log/pino-logger-server.js +18 -0
  150. package/dest/log/pino-logger.d.ts +37 -8
  151. package/dest/log/pino-logger.d.ts.map +1 -1
  152. package/dest/log/pino-logger.js +137 -29
  153. package/dest/noir/noir_package_config.d.ts +19 -104
  154. package/dest/noir/noir_package_config.d.ts.map +1 -1
  155. package/dest/noir/noir_package_config.js +1 -1
  156. package/dest/queue/base_memory_queue.d.ts +2 -2
  157. package/dest/queue/base_memory_queue.d.ts.map +1 -1
  158. package/dest/queue/batch_queue.d.ts +1 -1
  159. package/dest/queue/batch_queue.d.ts.map +1 -1
  160. package/dest/queue/batch_queue.js +1 -0
  161. package/dest/queue/semaphore.d.ts +5 -1
  162. package/dest/queue/semaphore.d.ts.map +1 -1
  163. package/dest/retry/index.d.ts +12 -1
  164. package/dest/retry/index.d.ts.map +1 -1
  165. package/dest/retry/index.js +21 -0
  166. package/dest/schemas/api.d.ts +12 -10
  167. package/dest/schemas/api.d.ts.map +1 -1
  168. package/dest/schemas/api.js +7 -1
  169. package/dest/schemas/parse.d.ts +4 -4
  170. package/dest/schemas/parse.d.ts.map +1 -1
  171. package/dest/schemas/parse.js +6 -5
  172. package/dest/schemas/schemas.d.ts +15 -15
  173. package/dest/schemas/types.d.ts +3 -3
  174. package/dest/schemas/types.d.ts.map +1 -1
  175. package/dest/schemas/utils.d.ts +7 -11
  176. package/dest/schemas/utils.d.ts.map +1 -1
  177. package/dest/schemas/utils.js +2 -18
  178. package/dest/serialize/buffer_reader.d.ts +8 -1
  179. package/dest/serialize/buffer_reader.d.ts.map +1 -1
  180. package/dest/serialize/buffer_reader.js +13 -0
  181. package/dest/serialize/buffer_sink.d.ts +134 -0
  182. package/dest/serialize/buffer_sink.d.ts.map +1 -0
  183. package/dest/serialize/buffer_sink.js +297 -0
  184. package/dest/serialize/index.d.ts +2 -1
  185. package/dest/serialize/index.d.ts.map +1 -1
  186. package/dest/serialize/index.js +1 -0
  187. package/dest/serialize/serialize.d.ts +19 -1
  188. package/dest/serialize/serialize.d.ts.map +1 -1
  189. package/dest/serialize/serialize.js +31 -0
  190. package/dest/sleep/index.d.ts +2 -1
  191. package/dest/sleep/index.d.ts.map +1 -1
  192. package/dest/sleep/index.js +10 -1
  193. package/dest/string/index.js +1 -1
  194. package/dest/timer/date.d.ts +25 -1
  195. package/dest/timer/date.d.ts.map +1 -1
  196. package/dest/timer/date.js +33 -0
  197. package/dest/timer/index.d.ts +2 -2
  198. package/dest/timer/index.d.ts.map +1 -1
  199. package/dest/timer/index.js +1 -1
  200. package/dest/timer/timeout.d.ts +3 -1
  201. package/dest/timer/timeout.d.ts.map +1 -1
  202. package/dest/timer/timeout.js +26 -0
  203. package/dest/transport/dispatch/create_dispatch_proxy.d.ts +11 -2
  204. package/dest/transport/dispatch/create_dispatch_proxy.d.ts.map +1 -1
  205. package/dest/transport/index.d.ts +1 -2
  206. package/dest/transport/index.d.ts.map +1 -1
  207. package/dest/transport/index.js +0 -1
  208. package/dest/transport/transport_client.js +2 -2
  209. package/dest/trees/balanced_merkle_tree_root.d.ts +2 -3
  210. package/dest/trees/balanced_merkle_tree_root.d.ts.map +1 -1
  211. package/dest/trees/balanced_merkle_tree_root.js +2 -3
  212. package/dest/trees/hasher.d.ts +3 -2
  213. package/dest/trees/hasher.d.ts.map +1 -1
  214. package/dest/trees/hasher.js +5 -5
  215. package/dest/trees/indexed_merkle_tree_calculator.d.ts +1 -1
  216. package/dest/trees/indexed_merkle_tree_calculator.d.ts.map +1 -1
  217. package/dest/trees/indexed_merkle_tree_calculator.js +5 -1
  218. package/dest/trees/membership_witness.d.ts +2 -2
  219. package/dest/trees/membership_witness.d.ts.map +1 -1
  220. package/dest/trees/merkle_tree_calculator.d.ts +4 -2
  221. package/dest/trees/merkle_tree_calculator.d.ts.map +1 -1
  222. package/dest/trees/merkle_tree_calculator.js +1 -5
  223. package/dest/trees/sibling_path.d.ts +5 -4
  224. package/dest/trees/sibling_path.d.ts.map +1 -1
  225. package/dest/trees/sibling_path.js +10 -8
  226. package/dest/trees/unbalanced_merkle_tree_root.d.ts +2 -3
  227. package/dest/trees/unbalanced_merkle_tree_root.d.ts.map +1 -1
  228. package/dest/trees/unbalanced_merkle_tree_root.js +2 -3
  229. package/dest/types/index.d.ts +25 -1
  230. package/dest/types/index.d.ts.map +1 -1
  231. package/dest/types/index.js +18 -0
  232. package/package.json +27 -4
  233. package/src/array/sorted_array.ts +22 -17
  234. package/src/bigint-buffer/index.ts +6 -1
  235. package/src/branded-types/block_number.ts +20 -2
  236. package/src/branded-types/buffer32_hash.ts +38 -0
  237. package/src/branded-types/checkpoint_number.ts +16 -1
  238. package/src/branded-types/epoch.ts +1 -1
  239. package/src/branded-types/index.ts +1 -0
  240. package/src/branded-types/index_within_checkpoint.ts +1 -1
  241. package/src/branded-types/slot.ts +6 -1
  242. package/src/buffer/buffer16.ts +3 -0
  243. package/src/buffer/buffer32.ts +39 -68
  244. package/src/buffer/index.ts +1 -0
  245. package/src/buffer/utils.ts +8 -0
  246. package/src/collection/array.ts +55 -0
  247. package/src/collection/index.ts +2 -0
  248. package/src/collection/lru_map.ts +143 -0
  249. package/src/collection/lru_set.ts +115 -0
  250. package/src/committable/committable.ts +1 -1
  251. package/src/config/env_var.ts +75 -21
  252. package/src/config/index.ts +116 -96
  253. package/src/config/network_config.ts +3 -0
  254. package/src/config/network_name.ts +6 -6
  255. package/src/config/secret_value.ts +1 -1
  256. package/src/crypto/aes128/index.ts +11 -2
  257. package/src/crypto/bls/bn254_keystore.ts +33 -43
  258. package/src/crypto/poseidon/index.ts +42 -34
  259. package/src/crypto/random/randomness_singleton.ts +9 -5
  260. package/src/crypto/schnorr/index.ts +9 -8
  261. package/src/crypto/schnorr/signature.ts +17 -46
  262. package/src/crypto/secp256k1-signer/utils.ts +32 -0
  263. package/src/curves/bls12/field.ts +0 -7
  264. package/src/curves/bn254/field.ts +41 -36
  265. package/src/curves/grumpkin/point.ts +23 -40
  266. package/src/eth-address/index.ts +0 -4
  267. package/src/eth-signature/eth_signature.ts +7 -1
  268. package/src/fifo/fifo_frame_reader.ts +113 -0
  269. package/src/fifo/index.ts +1 -0
  270. package/src/fifo_set/fifo_set.ts +52 -0
  271. package/src/fifo_set/index.ts +1 -0
  272. package/src/jest/setup.mjs +31 -1
  273. package/src/json-rpc/client/fetch.ts +4 -3
  274. package/src/json-rpc/client/safe_json_rpc_client.ts +4 -2
  275. package/src/json-rpc/client/undici.ts +5 -3
  276. package/src/json-rpc/fixtures/test_state.ts +10 -10
  277. package/src/json-rpc/server/api_key_auth.ts +63 -0
  278. package/src/json-rpc/server/index.ts +1 -0
  279. package/src/json-rpc/server/safe_json_rpc_server.ts +31 -13
  280. package/src/log/bigint-utils.ts +25 -0
  281. package/src/log/gcloud-logger-config.ts +5 -0
  282. package/src/log/libp2p_logger.ts +12 -5
  283. package/src/log/log-filters.ts +29 -11
  284. package/src/log/pino-logger-server.ts +25 -0
  285. package/src/log/pino-logger.ts +160 -39
  286. package/src/noir/noir_package_config.ts +32 -20
  287. package/src/queue/base_memory_queue.ts +1 -1
  288. package/src/queue/batch_queue.ts +1 -0
  289. package/src/queue/semaphore.ts +5 -0
  290. package/src/retry/index.ts +30 -0
  291. package/src/schemas/api.ts +25 -25
  292. package/src/schemas/parse.ts +9 -6
  293. package/src/schemas/schemas.ts +4 -4
  294. package/src/schemas/types.ts +2 -2
  295. package/src/schemas/utils.ts +4 -38
  296. package/src/serialize/buffer_reader.ts +15 -0
  297. package/src/serialize/buffer_sink.ts +350 -0
  298. package/src/serialize/index.ts +1 -0
  299. package/src/serialize/serialize.ts +32 -0
  300. package/src/sleep/index.ts +10 -1
  301. package/src/string/index.ts +1 -1
  302. package/src/timer/date.ts +48 -0
  303. package/src/timer/index.ts +1 -1
  304. package/src/timer/timeout.ts +31 -0
  305. package/src/transport/dispatch/create_dispatch_proxy.ts +11 -1
  306. package/src/transport/index.ts +0 -1
  307. package/src/transport/transport_client.ts +2 -2
  308. package/src/trees/balanced_merkle_tree_root.ts +2 -5
  309. package/src/trees/hasher.ts +6 -3
  310. package/src/trees/indexed_merkle_tree_calculator.ts +5 -1
  311. package/src/trees/merkle_tree_calculator.ts +4 -10
  312. package/src/trees/sibling_path.ts +11 -6
  313. package/src/trees/unbalanced_merkle_tree_root.ts +2 -5
  314. package/src/types/index.ts +52 -0
  315. package/dest/crypto/serialize.d.ts +0 -51
  316. package/dest/crypto/serialize.d.ts.map +0 -1
  317. package/dest/crypto/serialize.js +0 -68
  318. package/dest/transport/dispatch/create_dispatch_fn.d.ts +0 -25
  319. package/dest/transport/dispatch/create_dispatch_fn.d.ts.map +0 -1
  320. package/dest/transport/dispatch/create_dispatch_fn.js +0 -17
  321. package/src/crypto/serialize.ts +0 -85
  322. package/src/transport/dispatch/create_dispatch_fn.ts +0 -35
@@ -10,7 +10,13 @@ import { ZodError } from 'zod';
10
10
 
11
11
  import { type Logger, createLogger } from '../../log/index.js';
12
12
  import { promiseWithResolvers } from '../../promise/utils.js';
13
- import { type ApiSchema, type ApiSchemaFor, parseWithOptionals, schemaHasMethod } from '../../schemas/index.js';
13
+ import {
14
+ type ApiSchema,
15
+ type ApiSchemaFor,
16
+ getSchemaParameters,
17
+ parseWithOptionals,
18
+ schemaHasMethod,
19
+ } from '../../schemas/index.js';
14
20
  import { jsonStringify } from '../convert.js';
15
21
  import { assert } from '../js_utils.js';
16
22
 
@@ -53,8 +59,10 @@ export class SafeJsonRpcServer {
53
59
  config: Partial<SafeJsonRpcServerConfig> = {},
54
60
  /** Health check function */
55
61
  private readonly healthCheck: StatusCheckFn = () => true,
56
- /** Additional middlewares */
62
+ /** Additional Koa middlewares */
57
63
  private extraMiddlewares: Application.Middleware[] = [],
64
+ /** Additional per-request diagnostics middlewares */
65
+ private diagnosticsMiddleware?: DiagnosticsMiddleware,
58
66
  /** Logger */
59
67
  private log = createLogger('json-rpc:server'),
60
68
  ) {
@@ -155,7 +163,7 @@ export class SafeJsonRpcServer {
155
163
  };
156
164
  return;
157
165
  }
158
- const resp = await this.processBatch(ctx.request.body);
166
+ const resp = await this.processBatch(ctx.request.body, ctx.request.headers);
159
167
  if (Array.isArray(resp)) {
160
168
  ctx.status = 200;
161
169
  ctx.body = resp;
@@ -164,7 +172,7 @@ export class SafeJsonRpcServer {
164
172
  ctx.body = resp;
165
173
  }
166
174
  } else {
167
- const resp = await this.processRequest(ctx.request.body);
175
+ const resp = await this.processRequest(ctx.request.body, ctx.request.headers);
168
176
  if ('error' in resp) {
169
177
  ctx.status = this.config.http200OnError ? 200 : 400;
170
178
  }
@@ -176,11 +184,11 @@ export class SafeJsonRpcServer {
176
184
  return router;
177
185
  }
178
186
 
179
- private async processBatch(requests: any[]) {
187
+ private async processBatch(requests: any[], headers: http.IncomingHttpHeaders = {}) {
180
188
  if (requests.length === 0) {
181
189
  return { jsonrpc: '2.0', error: { code: -32600, message: 'Invalid Request' }, id: null };
182
190
  }
183
- const results = await Promise.allSettled(requests.map(req => this.processRequest(req)));
191
+ const results = await Promise.allSettled(requests.map(req => this.processRequest(req, headers)));
184
192
  return results.map(res => {
185
193
  if (res.status === 'fulfilled') {
186
194
  return res.value;
@@ -191,7 +199,7 @@ export class SafeJsonRpcServer {
191
199
  });
192
200
  }
193
201
 
194
- private async processRequest(request: any) {
202
+ private async processRequest(request: any, headers: http.IncomingHttpHeaders = {}) {
195
203
  if (!request || typeof request !== 'object') {
196
204
  return { jsonrpc: '2.0', error: { code: -32600, message: 'Invalid Request' }, id: null };
197
205
  }
@@ -206,7 +214,16 @@ export class SafeJsonRpcServer {
206
214
  return { jsonrpc, id, error: { code: -32601, message: `Method not found: ${method}` } };
207
215
  } else {
208
216
  try {
209
- const result = await this.proxy.call(method, params);
217
+ let result: any;
218
+
219
+ if (this.diagnosticsMiddleware) {
220
+ await this.diagnosticsMiddleware({ id: id ?? null, method, params, headers }, async () => {
221
+ result = await this.proxy.call(method, params);
222
+ });
223
+ } else {
224
+ result = await this.proxy.call(method, params);
225
+ }
226
+
210
227
  return { jsonrpc, id, result };
211
228
  } catch (err: any) {
212
229
  if (err && err instanceof ZodError) {
@@ -309,7 +326,7 @@ export class SafeJsonProxy<T extends object = any> implements Proxy {
309
326
  assert(schemaHasMethod(this.schema, methodName), `Method ${methodName} not found in schema`);
310
327
  const method = this.handler[methodName as keyof T];
311
328
  assert(typeof method === 'function', `Method ${methodName} is not a function`);
312
- const args = await parseWithOptionals(jsonParams, this.schema[methodName].parameters());
329
+ const args = await parseWithOptionals(jsonParams, getSchemaParameters(this.schema[methodName]));
313
330
  const ret = await method.apply(this.handler, args);
314
331
  this.log.debug(format('response', methodName, ret));
315
332
  return ret;
@@ -377,6 +394,7 @@ function makeAggregateHealthcheck(namedHandlers: NamespacedApiHandlers, log?: Lo
377
394
  export type SafeJsonRpcServerOptions = Partial<
378
395
  SafeJsonRpcServerConfig & {
379
396
  healthCheck: StatusCheckFn;
397
+ diagnostic: DiagnosticsMiddleware;
380
398
  log: Logger;
381
399
  middlewares: Application.Middleware[];
382
400
  }
@@ -391,10 +409,10 @@ export function createNamespacedSafeJsonRpcServer(
391
409
  handlers: NamespacedApiHandlers,
392
410
  options: Omit<SafeJsonRpcServerOptions, 'healthcheck'> = {},
393
411
  ): SafeJsonRpcServer {
394
- const { middlewares, log } = options;
412
+ const { diagnostic, middlewares, log } = options;
395
413
  const proxy = new NamespacedSafeJsonProxy(handlers);
396
414
  const healthCheck = makeAggregateHealthcheck(handlers, log);
397
- return new SafeJsonRpcServer(proxy, options, healthCheck, middlewares, log);
415
+ return new SafeJsonRpcServer(proxy, options, healthCheck, middlewares, diagnostic, log);
398
416
  }
399
417
 
400
418
  export function createSafeJsonRpcServer<T extends object = any>(
@@ -402,9 +420,9 @@ export function createSafeJsonRpcServer<T extends object = any>(
402
420
  schema: ApiSchemaFor<T>,
403
421
  options: SafeJsonRpcServerOptions = {},
404
422
  ) {
405
- const { log, healthCheck, middlewares: extraMiddlewares } = options;
423
+ const { diagnostic, log, healthCheck, middlewares: extraMiddlewares } = options;
406
424
  const proxy = new SafeJsonProxy(handler, schema);
407
- return new SafeJsonRpcServer(proxy, options, healthCheck, extraMiddlewares, log);
425
+ return new SafeJsonRpcServer(proxy, options, healthCheck, extraMiddlewares, diagnostic, log);
408
426
  }
409
427
 
410
428
  /**
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Converts bigint values to strings recursively in a log object to avoid serialization issues.
3
+ */
4
+ export function convertBigintsToStrings(obj: unknown): unknown {
5
+ if (typeof obj === 'bigint') {
6
+ return String(obj);
7
+ }
8
+
9
+ if (Array.isArray(obj)) {
10
+ return obj.map(item => convertBigintsToStrings(item));
11
+ }
12
+
13
+ if (obj !== null && typeof obj === 'object') {
14
+ if (typeof (obj as any).toJSON === 'function') {
15
+ return convertBigintsToStrings((obj as any).toJSON());
16
+ }
17
+ const result: Record<string, unknown> = {};
18
+ for (const key in obj) {
19
+ result[key] = convertBigintsToStrings((obj as Record<string, unknown>)[key]);
20
+ }
21
+ return result;
22
+ }
23
+
24
+ return obj;
25
+ }
@@ -1,5 +1,7 @@
1
1
  import type { pino } from 'pino';
2
2
 
3
+ import { convertBigintsToStrings } from './bigint-utils.js';
4
+
3
5
  /* eslint-disable camelcase */
4
6
 
5
7
  const GOOGLE_CLOUD_TRACE_ID = 'logging.googleapis.com/trace';
@@ -15,6 +17,9 @@ export const GoogleCloudLoggerConfig = {
15
17
  messageKey: 'message',
16
18
  formatters: {
17
19
  log(object: Record<string, unknown>): Record<string, unknown> {
20
+ // Convert bigints to strings recursively to avoid serialization issues
21
+ object = convertBigintsToStrings(object) as Record<string, unknown>;
22
+
18
23
  // Add trace context attributes following Cloud Logging structured log format described
19
24
  // in https://cloud.google.com/logging/docs/structured-logging#special-payload-fields
20
25
  const { trace_id, span_id, trace_flags, ...rest } = object;
@@ -2,15 +2,17 @@ import type { ComponentLogger, Logger } from '@libp2p/interface';
2
2
 
3
3
  import { getLogLevelFromFilters } from './log-filters.js';
4
4
  import type { LogLevel } from './log-levels.js';
5
- import { logFilters, logger } from './pino-logger.js';
5
+ import { type LoggerBindings, logFilters, logger } from './pino-logger.js';
6
6
 
7
7
  /**
8
8
  * Creates a libp2p compatible logger that wraps our pino logger.
9
9
  * This adapter implements the ComponentLogger interface required by libp2p.
10
+ * @param namespace - Base namespace for the logger
11
+ * @param bindings - Optional bindings to pass to the logger (actor, instanceId)
10
12
  */
11
- export function createLibp2pComponentLogger(namespace: string): ComponentLogger {
13
+ export function createLibp2pComponentLogger(namespace: string, bindings?: LoggerBindings): ComponentLogger {
12
14
  return {
13
- forComponent: (component: string) => createLibp2pLogger(`${namespace}:${component}`),
15
+ forComponent: (component: string) => createLibp2pLogger(`${namespace}:${component}`, bindings),
14
16
  };
15
17
  }
16
18
 
@@ -24,9 +26,14 @@ function replaceFormatting(message: string) {
24
26
  return message.replace(/(%p|%a)/g, '%s');
25
27
  }
26
28
 
27
- function createLibp2pLogger(component: string): Logger {
29
+ function createLibp2pLogger(component: string, bindings?: LoggerBindings): Logger {
28
30
  // Create a direct pino logger instance for libp2p that supports string interpolation
29
- const log = logger.child({ module: component }, { level: getLogLevelFromFilters(logFilters, component) });
31
+ const actor = bindings?.actor;
32
+ const instanceId = bindings?.instanceId;
33
+ const log = logger.child(
34
+ { module: component, ...(actor && { actor }), ...(instanceId && { instanceId }) },
35
+ { level: getLogLevelFromFilters(logFilters, component) },
36
+ );
30
37
 
31
38
  const logIfEnabled = (level: LogLevel, message: string, ...args: unknown[]) => {
32
39
  if (!log.isLevelEnabled(level)) {
@@ -19,22 +19,40 @@ export function getLogLevelFromFilters(filters: LogFilters, module: string): Log
19
19
  return undefined;
20
20
  }
21
21
 
22
- export function assertLogLevel(level: string): asserts level is LogLevel {
23
- if (!LogLevels.includes(level as LogLevel)) {
24
- throw new Error(`Invalid log level: ${level}`);
22
+ /**
23
+ * Parses the LOG_LEVEL env string into a default level and per-module filter overrides.
24
+ *
25
+ * Format: `<default_level>;<level>:<module1>,<module2>;<level>:<module3>;...`
26
+ * - First segment (before the first `;`) is the default log level for all modules.
27
+ * - Remaining segments are `level:module` pairs: apply the given level to the listed modules (comma-separated).
28
+ * - Later filters override earlier ones for overlapping module matches.
29
+ * - The `aztec:` prefix is stripped from module names; spaces are trimmed.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * parseLogLevel('debug;warn:module1,module2;error:module3', 'info')
34
+ * // => ['debug', [['module3', 'error'], ['module2', 'warn'], ['module1', 'warn']]]
35
+ * ```
36
+ */
37
+ export function parseLogLevelEnvVar(
38
+ logLevelEnvVar: string | undefined,
39
+ defaultLevel: LogLevel,
40
+ ): [LogLevel, LogFilters] {
41
+ if (!logLevelEnvVar) {
42
+ return [defaultLevel, []];
25
43
  }
44
+ const [level] = logLevelEnvVar.split(';', 1);
45
+ assertValidLogLevel(level);
46
+ return [level, parseFilters(logLevelEnvVar.slice(level.length + 1))];
26
47
  }
27
48
 
28
- export function parseEnv(env: string | undefined, defaultLevel: LogLevel): [LogLevel, LogFilters] {
29
- if (!env) {
30
- return [defaultLevel, []];
49
+ function assertValidLogLevel(level: string): asserts level is LogLevel {
50
+ if (!LogLevels.includes(level as LogLevel)) {
51
+ throw new Error(`Invalid log level: ${level}`);
31
52
  }
32
- const [level] = env.split(';', 1);
33
- assertLogLevel(level);
34
- return [level, parseFilters(env.slice(level.length + 1))];
35
53
  }
36
54
 
37
- export function parseFilters(definition: string | undefined): LogFilters {
55
+ function parseFilters(definition: string | undefined): LogFilters {
38
56
  if (!definition) {
39
57
  return [];
40
58
  }
@@ -48,7 +66,7 @@ export function parseFilters(definition: string | undefined): LogFilters {
48
66
  throw new Error(`Invalid log filter statement: ${statement}`);
49
67
  }
50
68
  const sanitizedLevel = level.trim().toLowerCase();
51
- assertLogLevel(sanitizedLevel);
69
+ assertValidLogLevel(sanitizedLevel);
52
70
  for (const module of modules.split(',')) {
53
71
  filters.push([
54
72
  module
@@ -0,0 +1,25 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+
3
+ import { type LoggerBindings, addLogBindingsHandler, removeLogBindingsHandler } from './pino-logger.js';
4
+
5
+ /** AsyncLocalStorage for logger bindings context propagation (Node.js only). */
6
+ const bindingsStorage = new AsyncLocalStorage<LoggerBindings>();
7
+
8
+ /** Returns the current bindings from AsyncLocalStorage, if any. */
9
+ export function getBindings(): LoggerBindings | undefined {
10
+ return bindingsStorage.getStore();
11
+ }
12
+
13
+ /**
14
+ * Runs a callback within a bindings context. All loggers created within the callback
15
+ * will automatically inherit the bindings (actor, instanceId) via the log bindings handler.
16
+ */
17
+ export async function withLoggerBindings<T>(bindings: LoggerBindings, callback: () => Promise<T>): Promise<T> {
18
+ const handler = () => bindingsStorage.getStore();
19
+ addLogBindingsHandler(handler);
20
+ try {
21
+ return await bindingsStorage.run(bindings, callback);
22
+ } finally {
23
+ removeLogBindingsHandler(handler);
24
+ }
25
+ }
@@ -1,4 +1,4 @@
1
- import { createColors, isColorSupported } from 'colorette';
1
+ import { type Color, createColors, isColorSupported } from 'colorette';
2
2
  import isNode from 'detect-node';
3
3
  import { pino, symbols } from 'pino';
4
4
  import type { Writable } from 'stream';
@@ -7,14 +7,59 @@ import { inspect } from 'util';
7
7
  import { compactArray } from '../collection/array.js';
8
8
  import type { EnvVar } from '../config/index.js';
9
9
  import { parseBooleanEnv } from '../config/parse-env.js';
10
+ import { convertBigintsToStrings } from './bigint-utils.js';
10
11
  import { GoogleCloudLoggerConfig } from './gcloud-logger-config.js';
11
- import { getLogLevelFromFilters, parseEnv } from './log-filters.js';
12
+ import { getLogLevelFromFilters, parseLogLevelEnvVar } from './log-filters.js';
12
13
  import type { LogLevel } from './log-levels.js';
13
14
  import type { LogData, LogFn } from './log_fn.js';
14
15
 
15
- export function createLogger(module: string): Logger {
16
- module = logNameHandlers.reduce((moduleName, handler) => handler(moduleName), module.replace(/^aztec:/, ''));
17
- const pinoLogger = logger.child({ module }, { level: getLogLevelFromFilters(logFilters, module) });
16
+ /** Optional bindings to pass to createLogger for additional context. */
17
+ export type LoggerBindings = {
18
+ /** Actor label shown in logs (e.g., 'MAIN', 'prover-node'). */
19
+ actor?: string;
20
+ /** Instance identifier for distinguishing multiple instances of the same component. */
21
+ instanceId?: string;
22
+ };
23
+
24
+ const MAX_MODULE_NAME_LENGTH = 256;
25
+
26
+ // Allow global hooks for providing default bindings.
27
+ // Used by withLoggerBindings in pino-logger-server to propagate bindings via AsyncLocalStorage.
28
+ type LogBindingsHandler = () => LoggerBindings | undefined;
29
+ const logBindingsHandlers: LogBindingsHandler[] = [];
30
+
31
+ export function addLogBindingsHandler(handler: LogBindingsHandler): void {
32
+ logBindingsHandlers.push(handler);
33
+ }
34
+
35
+ export function removeLogBindingsHandler(handler: LogBindingsHandler) {
36
+ const index = logBindingsHandlers.indexOf(handler);
37
+ if (index !== -1) {
38
+ logBindingsHandlers.splice(index, 1);
39
+ }
40
+ }
41
+
42
+ function getBindingsFromHandlers(): LoggerBindings | undefined {
43
+ for (const handler of logBindingsHandlers) {
44
+ const bindings = handler();
45
+ if (bindings) {
46
+ return bindings;
47
+ }
48
+ }
49
+ return undefined;
50
+ }
51
+
52
+ export function createLogger(module: string, bindings?: LoggerBindings): Logger {
53
+ module = module.slice(0, MAX_MODULE_NAME_LENGTH).replace(/^aztec:/, '');
54
+
55
+ const resolvedBindings = { ...getBindingsFromHandlers(), ...bindings };
56
+ const actor = resolvedBindings?.actor;
57
+ const instanceId = resolvedBindings?.instanceId;
58
+
59
+ const pinoLogger = logger.child(
60
+ { module, ...(actor && { actor }), ...(instanceId && { instanceId }) },
61
+ { level: getLogLevelFromFilters(logFilters, module) },
62
+ );
18
63
 
19
64
  // We check manually for isLevelEnabled to avoid calling processLogData unnecessarily.
20
65
  // Note that isLevelEnabled is missing from the browser version of pino.
@@ -44,11 +89,24 @@ export function createLogger(module: string): Logger {
44
89
  isLevelEnabled: (level: LogLevel) => isLevelEnabled(pinoLogger, level),
45
90
  /** Module name for the logger. */
46
91
  module,
47
- /** Creates another logger by extending this logger module name. */
48
- createChild: (childModule: string) => createLogger(`${module}:${childModule}`),
92
+ /** Creates another logger by extending this logger module name and preserving bindings. */
93
+ createChild: (childModule: string) => createLogger(`${module}:${childModule}`, { actor, instanceId }),
94
+ /** Returns the bindings (actor, instanceId) for this logger. */
95
+ getBindings: () => ({ actor, instanceId }),
49
96
  };
50
97
  }
51
98
 
99
+ /**
100
+ * Returns a logger for the given module. If loggerOrBindings is already a Logger, returns it directly.
101
+ * Otherwise, creates a new logger with the given module name and bindings.
102
+ */
103
+ export function resolveLogger(module: string, loggerOrBindings?: Logger | LoggerBindings): Logger {
104
+ if (loggerOrBindings && 'info' in loggerOrBindings) {
105
+ return loggerOrBindings as Logger;
106
+ }
107
+ return createLogger(module, loggerOrBindings);
108
+ }
109
+
52
110
  // Allow global hooks for processing log data.
53
111
  // Used for injecting OTEL trace_id in telemetry client.
54
112
  type LogDataHandler = (data: LogData) => LogData;
@@ -62,31 +120,6 @@ function processLogData(data: LogData): LogData {
62
120
  return logDataHandlers.reduce((accum, handler) => handler(accum), data);
63
121
  }
64
122
 
65
- // Allow global hooks for tweaking module names.
66
- // Used in tests to add a uid to modules, so we can differentiate multiple nodes in the same process.
67
- type LogNameHandler = (module: string) => string;
68
- const logNameHandlers: LogNameHandler[] = [];
69
-
70
- export function addLogNameHandler(handler: LogNameHandler): void {
71
- logNameHandlers.push(handler);
72
- }
73
-
74
- export function removeLogNameHandler(handler: LogNameHandler) {
75
- const index = logNameHandlers.indexOf(handler);
76
- if (index !== -1) {
77
- logNameHandlers.splice(index, 1);
78
- }
79
- }
80
-
81
- /** Creates all loggers within the given callback with the suffix appended to the module name. */
82
- export async function withLogNameSuffix<T>(suffix: string, callback: () => Promise<T>): Promise<T> {
83
- const logNameHandler = (module: string) => `${module}:${suffix}`;
84
- addLogNameHandler(logNameHandler);
85
- const result = await callback();
86
- removeLogNameHandler(logNameHandler);
87
- return result;
88
- }
89
-
90
123
  // Patch isLevelEnabled missing from pino/browser.
91
124
  function isLevelEnabled(logger: pino.Logger<'verbose', boolean>, level: LogLevel): boolean {
92
125
  return typeof logger.isLevelEnabled === 'function'
@@ -96,7 +129,7 @@ function isLevelEnabled(logger: pino.Logger<'verbose', boolean>, level: LogLevel
96
129
 
97
130
  // Load log levels from environment variables.
98
131
  const defaultLogLevel = process.env.NODE_ENV === 'test' ? 'silent' : 'info';
99
- export const [logLevel, logFilters] = parseEnv(process.env.LOG_LEVEL, defaultLogLevel);
132
+ export const [logLevel, logFilters] = parseLogLevelEnvVar(process.env.LOG_LEVEL, defaultLogLevel);
100
133
 
101
134
  // Define custom logging levels for pino.
102
135
  const customLevels = { verbose: 25 };
@@ -135,6 +168,9 @@ const pinoOpts: pino.LoggerOptions<keyof typeof customLevels> = {
135
168
  ...redactedPaths.map(p => `opts.${p}`),
136
169
  ],
137
170
  },
171
+ formatters: {
172
+ log: obj => convertBigintsToStrings(obj) as Record<string, unknown>,
173
+ },
138
174
  ...(useGcloudLogging ? GoogleCloudLoggerConfig : {}),
139
175
  };
140
176
 
@@ -146,22 +182,90 @@ export const levels = {
146
182
  // Transport options for pretty logging to stderr via pino-pretty.
147
183
  const colorEnv = process.env['FORCE_COLOR' satisfies EnvVar];
148
184
  const useColor = colorEnv === undefined ? isColorSupported : parseBooleanEnv(colorEnv);
149
- const { bold, reset } = createColors({ useColor });
150
- export const pinoPrettyOpts = {
185
+ const { bold, reset, cyan, magenta, yellow, blue, green, magentaBright, yellowBright, blueBright, greenBright } =
186
+ createColors({ useColor });
187
+
188
+ // Per-actor coloring: each unique actor gets a different color for easier visual distinction.
189
+ // Disabled when LOG_NO_COLOR_PER_ACTOR is set to a truthy value.
190
+ const useColorPerActor = useColor && !parseBooleanEnv(process.env['LOG_NO_COLOR_PER_ACTOR' satisfies EnvVar]);
191
+ const actorColors: Color[] = [yellow, magenta, blue, green, magentaBright, yellowBright, blueBright, greenBright];
192
+ const actorColorMap = new Map<string, Color>();
193
+ let nextColorIndex = 0;
194
+
195
+ /** Returns the color function assigned to a given actor, assigning a new one if needed. */
196
+ export function getActorColor(actor: string): Color {
197
+ let color = actorColorMap.get(actor);
198
+ if (!color) {
199
+ color = actorColors[nextColorIndex % actorColors.length];
200
+ actorColorMap.set(actor, color);
201
+ nextColorIndex++;
202
+ }
203
+ return color;
204
+ }
205
+
206
+ /** Resets the actor-to-color mapping. Useful for testing. */
207
+ export function resetActorColors(): void {
208
+ actorColorMap.clear();
209
+ nextColorIndex = 0;
210
+ }
211
+
212
+ // String template for messageFormat (used in worker threads and when per-actor coloring is disabled).
213
+ const messageFormatString = `${bold('{module}')}{if actor} ${cyan('{actor}')}{end}{if instanceId} ${reset(cyan('{instanceId}'))}{end} ${reset('{msg}')}`;
214
+
215
+ // Function for messageFormat when per-actor coloring is enabled (can only be used in-process, not worker threads).
216
+ type LogObject = { actor?: string; module?: string; instanceId?: string; msg?: string };
217
+
218
+ /** Formats a log message with per-actor coloring. Actor, module, and instanceId share the same color. */
219
+ export function formatLogMessage(log: LogObject, messageKey: string): string {
220
+ const actor = log.actor;
221
+ const module = log.module ?? '';
222
+ const instanceId = log.instanceId;
223
+ const msg = log[messageKey as keyof LogObject] ?? '';
224
+
225
+ // Use actor color for actor, module, and instanceId when actor is present
226
+ const color = actor ? getActorColor(actor) : cyan;
227
+
228
+ let result = bold(color(module));
229
+ if (actor) {
230
+ result += ' ' + color(actor);
231
+ }
232
+ if (instanceId) {
233
+ result += ' ' + reset(color(instanceId));
234
+ }
235
+ result += ' ' + reset(String(msg));
236
+ return result;
237
+ }
238
+
239
+ // Base options for pino-pretty (shared between transport and direct use).
240
+ const pinoPrettyBaseOpts = {
151
241
  destination: 2,
152
242
  sync: true,
153
243
  colorize: useColor,
154
- ignore: 'module,pid,hostname,trace_id,span_id,trace_flags,severity',
155
- messageFormat: `${bold('{module}')} ${reset('{msg}')}`,
244
+ ignore: 'module,actor,instanceId,pid,hostname,trace_id,span_id,trace_flags,severity',
156
245
  customLevels: 'fatal:60,error:50,warn:40,info:30,verbose:25,debug:20,trace:10',
157
246
  customColors: 'fatal:bgRed,error:red,warn:yellow,info:green,verbose:magenta,debug:blue,trace:gray',
158
247
  minimumLevel: 'trace' as const,
159
248
  singleLine: !parseBooleanEnv(process.env['LOG_MULTILINE' satisfies EnvVar]),
160
249
  };
161
250
 
251
+ /**
252
+ * Pino-pretty options for direct use (e.g., jest/setup.mjs).
253
+ * Includes function-based messageFormat for per-actor coloring when enabled.
254
+ */
255
+ export const pinoPrettyOpts = {
256
+ ...pinoPrettyBaseOpts,
257
+ messageFormat: useColorPerActor ? formatLogMessage : messageFormatString,
258
+ };
259
+
260
+ // Transport options use string template only (functions can't be serialized to worker threads).
261
+ const prettyTransportOpts = {
262
+ ...pinoPrettyBaseOpts,
263
+ messageFormat: messageFormatString,
264
+ };
265
+
162
266
  const prettyTransport: pino.TransportTargetOptions = {
163
267
  target: 'pino-pretty',
164
- options: pinoPrettyOpts,
268
+ options: prettyTransportOpts,
165
269
  level: 'trace',
166
270
  };
167
271
 
@@ -262,6 +366,8 @@ export type Logger = { [K in LogLevel]: LogFn } & { /** Error log function */ er
262
366
  isLevelEnabled: (level: LogLevel) => boolean;
263
367
  module: string;
264
368
  createChild: (childModule: string) => Logger;
369
+ /** Returns the bindings (actor, instanceId) for this logger. */
370
+ getBindings: () => LoggerBindings;
265
371
  };
266
372
 
267
373
  /**
@@ -271,5 +377,20 @@ export type Logger = { [K in LogLevel]: LogFn } & { /** Error log function */ er
271
377
  * @returns A string with both the log message and the error message.
272
378
  */
273
379
  function formatErr(msg: string, err?: unknown): string {
274
- return err ? `${msg}: ${inspect(err)}` : msg;
380
+ if (!err) {
381
+ return msg;
382
+ }
383
+
384
+ try {
385
+ return `${msg}: ${inspect(err)}`;
386
+ } catch {
387
+ // inspect can crash on error objects with broken property descriptors
388
+ try {
389
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
390
+ return `${msg}: ${err instanceof Error ? `${err.name}: ${err.message}` : String(err)}`;
391
+ } catch {
392
+ // if even String(err) fails, return the original message with a note about the error
393
+ return `${msg}: [unserializable error]`;
394
+ }
395
+ }
275
396
  }
@@ -10,26 +10,6 @@ const noirLocalDependencySchema = z.object({
10
10
  path: z.string(),
11
11
  });
12
12
 
13
- const noirPackageConfigSchema = z.object({
14
- package: z.object({
15
- name: z.string().default(''),
16
- type: z.enum(['lib', 'contract', 'bin']).default('bin'),
17
- entry: z.string().optional(),
18
- description: z.string().optional(),
19
- authors: z.array(z.string()).optional(),
20
- // eslint-disable-next-line camelcase
21
- compiler_version: z.string().optional(),
22
- backend: z.string().optional(),
23
- license: z.string().optional(),
24
- }),
25
- dependencies: z.record(z.union([noirGitDependencySchema, noirLocalDependencySchema])).default({}),
26
- });
27
-
28
- /**
29
- * Noir package configuration.
30
- */
31
- export type NoirPackageConfig = z.infer<typeof noirPackageConfigSchema>;
32
-
33
13
  /**
34
14
  * A remote package dependency.
35
15
  */
@@ -45,6 +25,38 @@ export type NoirLocalDependencyConfig = z.infer<typeof noirLocalDependencySchema
45
25
  */
46
26
  export type NoirDependencyConfig = NoirGitDependencyConfig | NoirLocalDependencyConfig;
47
27
 
28
+ /**
29
+ * Noir package configuration.
30
+ */
31
+ export type NoirPackageConfig = {
32
+ package: {
33
+ name: string;
34
+ type: 'lib' | 'contract' | 'bin';
35
+ entry?: string | undefined;
36
+ description?: string | undefined;
37
+ authors?: string[] | undefined;
38
+ compiler_version?: string | undefined;
39
+ backend?: string | undefined;
40
+ license?: string | undefined;
41
+ };
42
+ dependencies: Record<string, NoirDependencyConfig>;
43
+ };
44
+
45
+ const noirPackageConfigSchema: z.ZodType<NoirPackageConfig> = z.object({
46
+ package: z.object({
47
+ name: z.string().default(''),
48
+ type: z.enum(['lib', 'contract', 'bin']).default('bin'),
49
+ entry: z.string().optional(),
50
+ description: z.string().optional(),
51
+ authors: z.array(z.string()).optional(),
52
+ // eslint-disable-next-line camelcase
53
+ compiler_version: z.string().optional(),
54
+ backend: z.string().optional(),
55
+ license: z.string().optional(),
56
+ }),
57
+ dependencies: z.record(z.string(), z.union([noirGitDependencySchema, noirLocalDependencySchema])).default({}),
58
+ });
59
+
48
60
  /**
49
61
  * Checks that an object is a package configuration.
50
62
  * @param config - Config to check
@@ -122,7 +122,7 @@ export abstract class BaseMemoryQueue<T> {
122
122
  * @param handler - A function that takes an item of type T and returns a Promise<void> after processing the item.
123
123
  * @returns A Promise<void> that resolves when the queue is finished processing.
124
124
  */
125
- public async process(handler: (item: T) => Promise<void>) {
125
+ public async process(handler: (item: T) => Promise<void> | void) {
126
126
  try {
127
127
  while (true) {
128
128
  const item = await this.get();
@@ -105,6 +105,7 @@ export class BatchQueue<T, K extends string | number> {
105
105
  return Promise.resolve();
106
106
  }
107
107
 
108
+ this.flushCurrentBatch();
108
109
  this.container.end();
109
110
  return runningPromise;
110
111
  }
@@ -1,5 +1,10 @@
1
1
  import { FifoMemoryQueue } from './fifo_memory_queue.js';
2
2
 
3
+ export interface ISemaphore {
4
+ acquire(): Promise<void>;
5
+ release(): void;
6
+ }
7
+
3
8
  /**
4
9
  * Allows the acquiring of up to `size` tokens before calls to acquire block, waiting for a call to release().
5
10
  */