@procedures/client 0.2.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +77 -44
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/adapters/http/client/transport.d.ts.map +1 -1
  5. package/dist/adapters/http/client/transport.js +35 -3
  6. package/dist/adapters/http/client/transport.js.map +1 -1
  7. package/dist/adapters/http/client/types.d.ts +3 -2
  8. package/dist/adapters/http/client/types.d.ts.map +1 -1
  9. package/dist/adapters/http/server/transport.d.ts +2 -2
  10. package/dist/adapters/http/server/transport.d.ts.map +1 -1
  11. package/dist/adapters/http/server/transport.js +54 -22
  12. package/dist/adapters/http/server/transport.js.map +1 -1
  13. package/dist/adapters/http/shared/headers.d.ts +1 -1
  14. package/dist/adapters/http/shared/headers.d.ts.map +1 -1
  15. package/dist/adapters/http/shared/headers.js +7 -6
  16. package/dist/adapters/http/shared/headers.js.map +1 -1
  17. package/dist/adapters/local/client/transport.d.ts +3 -0
  18. package/dist/adapters/local/client/transport.d.ts.map +1 -1
  19. package/dist/adapters/local/client/transport.js +67 -6
  20. package/dist/adapters/local/client/transport.js.map +1 -1
  21. package/dist/adapters/local/client/types.d.ts +15 -0
  22. package/dist/adapters/local/client/types.d.ts.map +1 -1
  23. package/dist/adapters/local/client/types.js.map +1 -1
  24. package/dist/adapters/mock/client/transport.d.ts +3 -2
  25. package/dist/adapters/mock/client/transport.d.ts.map +1 -1
  26. package/dist/adapters/mock/client/transport.js +8 -5
  27. package/dist/adapters/mock/client/transport.js.map +1 -1
  28. package/dist/adapters/mock/client/types.d.ts +7 -6
  29. package/dist/adapters/mock/client/types.d.ts.map +1 -1
  30. package/dist/adapters/port/transport.d.ts +62 -0
  31. package/dist/adapters/port/transport.d.ts.map +1 -0
  32. package/dist/adapters/port/transport.js +94 -0
  33. package/dist/adapters/port/transport.js.map +1 -0
  34. package/dist/adapters/websocket/client/index.d.ts +1 -1
  35. package/dist/adapters/websocket/client/index.d.ts.map +1 -1
  36. package/dist/adapters/websocket/client/index.js.map +1 -1
  37. package/dist/adapters/websocket/client/node.d.ts +30 -0
  38. package/dist/adapters/websocket/client/node.d.ts.map +1 -0
  39. package/dist/adapters/websocket/client/node.js +32 -0
  40. package/dist/adapters/websocket/client/node.js.map +1 -0
  41. package/dist/adapters/websocket/client/transport.d.ts +47 -7
  42. package/dist/adapters/websocket/client/transport.d.ts.map +1 -1
  43. package/dist/adapters/websocket/client/transport.js +229 -75
  44. package/dist/adapters/websocket/client/transport.js.map +1 -1
  45. package/dist/adapters/websocket/client/types.d.ts +71 -21
  46. package/dist/adapters/websocket/client/types.d.ts.map +1 -1
  47. package/dist/adapters/websocket/client/types.js.map +1 -1
  48. package/dist/adapters/websocket/server/transport.d.ts +65 -24
  49. package/dist/adapters/websocket/server/transport.d.ts.map +1 -1
  50. package/dist/adapters/websocket/server/transport.js +192 -263
  51. package/dist/adapters/websocket/server/transport.js.map +1 -1
  52. package/dist/adapters/websocket/server/types.d.ts +20 -1
  53. package/dist/adapters/websocket/server/types.d.ts.map +1 -1
  54. package/dist/adapters/websocket/shared/rpc.d.ts +129 -0
  55. package/dist/adapters/websocket/shared/rpc.d.ts.map +1 -0
  56. package/dist/adapters/websocket/shared/rpc.js +425 -0
  57. package/dist/adapters/websocket/shared/rpc.js.map +1 -0
  58. package/dist/browser.d.ts +29 -7
  59. package/dist/browser.d.ts.map +1 -1
  60. package/dist/browser.js +26 -3
  61. package/dist/browser.js.map +1 -1
  62. package/dist/client/call-types.d.ts +10 -10
  63. package/dist/client/call-types.d.ts.map +1 -1
  64. package/dist/client/call-types.js +1 -6
  65. package/dist/client/call-types.js.map +1 -1
  66. package/dist/client/client.d.ts +6 -1
  67. package/dist/client/client.d.ts.map +1 -1
  68. package/dist/client/client.js +23 -9
  69. package/dist/client/client.js.map +1 -1
  70. package/dist/client/deadline.d.ts +38 -0
  71. package/dist/client/deadline.d.ts.map +1 -0
  72. package/dist/client/deadline.js +60 -0
  73. package/dist/client/deadline.js.map +1 -0
  74. package/dist/client/errors/factory.d.ts.map +1 -1
  75. package/dist/client/errors/factory.js +11 -7
  76. package/dist/client/errors/factory.js.map +1 -1
  77. package/dist/client/errors/http-errors.d.ts.map +1 -1
  78. package/dist/client/errors/http-errors.js +6 -0
  79. package/dist/client/errors/http-errors.js.map +1 -1
  80. package/dist/client/errors/index.d.ts +1 -1
  81. package/dist/client/errors/index.js +1 -1
  82. package/dist/client/errors/registry.d.ts +2 -1
  83. package/dist/client/errors/registry.d.ts.map +1 -1
  84. package/dist/client/errors/registry.js +72 -22
  85. package/dist/client/errors/registry.js.map +1 -1
  86. package/dist/client/index.d.ts +9 -2
  87. package/dist/client/index.d.ts.map +1 -1
  88. package/dist/client/index.js +8 -2
  89. package/dist/client/index.js.map +1 -1
  90. package/dist/client/middleware/cache.d.ts +19 -5
  91. package/dist/client/middleware/cache.d.ts.map +1 -1
  92. package/dist/client/middleware/cache.js +106 -18
  93. package/dist/client/middleware/cache.js.map +1 -1
  94. package/dist/client/middleware/circuit-breaker.d.ts +28 -10
  95. package/dist/client/middleware/circuit-breaker.d.ts.map +1 -1
  96. package/dist/client/middleware/circuit-breaker.js +35 -24
  97. package/dist/client/middleware/circuit-breaker.js.map +1 -1
  98. package/dist/client/middleware/contexts.d.ts +16 -10
  99. package/dist/client/middleware/contexts.d.ts.map +1 -1
  100. package/dist/client/middleware/contexts.js.map +1 -1
  101. package/dist/client/middleware/items.d.ts +31 -2
  102. package/dist/client/middleware/items.d.ts.map +1 -1
  103. package/dist/client/middleware/items.js +86 -6
  104. package/dist/client/middleware/items.js.map +1 -1
  105. package/dist/client/middleware/lru.d.ts +2 -0
  106. package/dist/client/middleware/lru.d.ts.map +1 -1
  107. package/dist/client/middleware/lru.js +11 -0
  108. package/dist/client/middleware/lru.js.map +1 -1
  109. package/dist/client/middleware/rate-limit.d.ts +7 -6
  110. package/dist/client/middleware/rate-limit.d.ts.map +1 -1
  111. package/dist/client/middleware/rate-limit.js +9 -7
  112. package/dist/client/middleware/rate-limit.js.map +1 -1
  113. package/dist/client/middleware/resilience.d.ts +61 -0
  114. package/dist/client/middleware/resilience.d.ts.map +1 -0
  115. package/dist/client/middleware/resilience.js +59 -0
  116. package/dist/client/middleware/resilience.js.map +1 -0
  117. package/dist/client/middleware/retry.d.ts +45 -11
  118. package/dist/client/middleware/retry.d.ts.map +1 -1
  119. package/dist/client/middleware/retry.js +102 -22
  120. package/dist/client/middleware/retry.js.map +1 -1
  121. package/dist/client/middleware/timeout.d.ts +15 -12
  122. package/dist/client/middleware/timeout.d.ts.map +1 -1
  123. package/dist/client/middleware/timeout.js +48 -46
  124. package/dist/client/middleware/timeout.js.map +1 -1
  125. package/dist/client/middleware/tracing.d.ts.map +1 -1
  126. package/dist/client/middleware/tracing.js +11 -3
  127. package/dist/client/middleware/tracing.js.map +1 -1
  128. package/dist/client/types.d.ts +9 -1
  129. package/dist/client/types.d.ts.map +1 -1
  130. package/dist/client/types.js.map +1 -1
  131. package/dist/clock.d.ts +19 -0
  132. package/dist/clock.d.ts.map +1 -0
  133. package/dist/clock.js +18 -0
  134. package/dist/clock.js.map +1 -0
  135. package/dist/duration.d.ts +37 -0
  136. package/dist/duration.d.ts.map +1 -0
  137. package/dist/duration.js +44 -0
  138. package/dist/duration.js.map +1 -0
  139. package/dist/index.d.ts +4 -0
  140. package/dist/index.d.ts.map +1 -1
  141. package/dist/index.js +4 -0
  142. package/dist/index.js.map +1 -1
  143. package/dist/machines.d.ts +90 -0
  144. package/dist/machines.d.ts.map +1 -0
  145. package/dist/machines.js +127 -0
  146. package/dist/machines.js.map +1 -0
  147. package/dist/node.d.ts +11 -0
  148. package/dist/node.d.ts.map +1 -0
  149. package/dist/node.js +10 -0
  150. package/dist/node.js.map +1 -0
  151. package/dist/procedures/capability.d.ts +3 -6
  152. package/dist/procedures/capability.d.ts.map +1 -1
  153. package/dist/procedures/capability.js +7 -8
  154. package/dist/procedures/capability.js.map +1 -1
  155. package/dist/procedures/collection/index.d.ts +3 -3
  156. package/dist/procedures/collection/index.d.ts.map +1 -1
  157. package/dist/procedures/collection/index.js +1 -1
  158. package/dist/procedures/collection/index.js.map +1 -1
  159. package/dist/procedures/collection/procedures.d.ts.map +1 -1
  160. package/dist/procedures/collection/procedures.js +49 -1
  161. package/dist/procedures/collection/procedures.js.map +1 -1
  162. package/dist/procedures/collection/schemas.d.ts +33 -0
  163. package/dist/procedures/collection/schemas.d.ts.map +1 -1
  164. package/dist/procedures/collection/schemas.js +68 -0
  165. package/dist/procedures/collection/schemas.js.map +1 -1
  166. package/dist/procedures/collection/storage.d.ts +37 -0
  167. package/dist/procedures/collection/storage.d.ts.map +1 -1
  168. package/dist/procedures/core/array.d.ts +1 -1
  169. package/dist/procedures/core/array.d.ts.map +1 -1
  170. package/dist/procedures/core/array.js +81 -29
  171. package/dist/procedures/core/array.js.map +1 -1
  172. package/dist/procedures/core/index.d.ts.map +1 -1
  173. package/dist/procedures/core/index.js +17 -2
  174. package/dist/procedures/core/index.js.map +1 -1
  175. package/dist/procedures/core/logic.js +1 -1
  176. package/dist/procedures/core/logic.js.map +1 -1
  177. package/dist/procedures/core/math.d.ts.map +1 -1
  178. package/dist/procedures/core/math.js +5 -1
  179. package/dist/procedures/core/math.js.map +1 -1
  180. package/dist/procedures/core/meta.d.ts.map +1 -1
  181. package/dist/procedures/core/meta.js +43 -8
  182. package/dist/procedures/core/meta.js.map +1 -1
  183. package/dist/procedures/core/object.d.ts.map +1 -1
  184. package/dist/procedures/core/object.js +42 -13
  185. package/dist/procedures/core/object.js.map +1 -1
  186. package/dist/procedures/core/operands.d.ts.map +1 -1
  187. package/dist/procedures/core/operands.js +6 -1
  188. package/dist/procedures/core/operands.js.map +1 -1
  189. package/dist/procedures/core/string.d.ts.map +1 -1
  190. package/dist/procedures/core/string.js +4 -2
  191. package/dist/procedures/core/string.js.map +1 -1
  192. package/dist/procedures/core/type.d.ts.map +1 -1
  193. package/dist/procedures/core/type.js +4 -2
  194. package/dist/procedures/core/type.js.map +1 -1
  195. package/dist/procedures/define-procedure.d.ts +19 -7
  196. package/dist/procedures/define-procedure.d.ts.map +1 -1
  197. package/dist/procedures/define-procedure.js +57 -17
  198. package/dist/procedures/define-procedure.js.map +1 -1
  199. package/dist/procedures/discovery.d.ts +4 -6
  200. package/dist/procedures/discovery.d.ts.map +1 -1
  201. package/dist/procedures/discovery.js +4 -6
  202. package/dist/procedures/discovery.js.map +1 -1
  203. package/dist/procedures/effects.d.ts +16 -0
  204. package/dist/procedures/effects.d.ts.map +1 -1
  205. package/dist/procedures/effects.js +33 -0
  206. package/dist/procedures/effects.js.map +1 -1
  207. package/dist/procedures/idempotency.d.ts +73 -0
  208. package/dist/procedures/idempotency.d.ts.map +1 -0
  209. package/dist/procedures/idempotency.js +131 -0
  210. package/dist/procedures/idempotency.js.map +1 -0
  211. package/dist/procedures/index.d.ts +7 -3
  212. package/dist/procedures/index.d.ts.map +1 -1
  213. package/dist/procedures/index.js +6 -2
  214. package/dist/procedures/index.js.map +1 -1
  215. package/dist/procedures/interceptors.d.ts +17 -4
  216. package/dist/procedures/interceptors.d.ts.map +1 -1
  217. package/dist/procedures/interceptors.js +18 -7
  218. package/dist/procedures/interceptors.js.map +1 -1
  219. package/dist/procedures/invoke.d.ts +15 -3
  220. package/dist/procedures/invoke.d.ts.map +1 -1
  221. package/dist/procedures/invoke.js +8 -3
  222. package/dist/procedures/invoke.js.map +1 -1
  223. package/dist/procedures/manifest.d.ts +83 -0
  224. package/dist/procedures/manifest.d.ts.map +1 -0
  225. package/dist/procedures/manifest.js +90 -0
  226. package/dist/procedures/manifest.js.map +1 -0
  227. package/dist/procedures/ref.d.ts +4 -2
  228. package/dist/procedures/ref.d.ts.map +1 -1
  229. package/dist/procedures/ref.js +2 -1
  230. package/dist/procedures/ref.js.map +1 -1
  231. package/dist/procedures/runtime-programs.d.ts +19 -0
  232. package/dist/procedures/runtime-programs.d.ts.map +1 -0
  233. package/dist/procedures/runtime-programs.js +24 -0
  234. package/dist/procedures/runtime-programs.js.map +1 -0
  235. package/dist/procedures/types.d.ts +16 -0
  236. package/dist/procedures/types.d.ts.map +1 -1
  237. package/dist/procedures/types.js.map +1 -1
  238. package/dist/protocol.d.ts +47 -0
  239. package/dist/protocol.d.ts.map +1 -0
  240. package/dist/protocol.js +68 -0
  241. package/dist/protocol.js.map +1 -0
  242. package/dist/server/host-policy.d.ts +4 -3
  243. package/dist/server/host-policy.d.ts.map +1 -1
  244. package/dist/server/host-policy.js +6 -3
  245. package/dist/server/host-policy.js.map +1 -1
  246. package/dist/server/host-procedures.d.ts +31 -0
  247. package/dist/server/host-procedures.d.ts.map +1 -0
  248. package/dist/server/host-procedures.js +75 -0
  249. package/dist/server/host-procedures.js.map +1 -0
  250. package/dist/server/index.d.ts +3 -3
  251. package/dist/server/index.d.ts.map +1 -1
  252. package/dist/server/index.js +1 -1
  253. package/dist/server/index.js.map +1 -1
  254. package/dist/server/procedure-server.d.ts +112 -5
  255. package/dist/server/procedure-server.d.ts.map +1 -1
  256. package/dist/server/procedure-server.js +273 -19
  257. package/dist/server/procedure-server.js.map +1 -1
  258. package/dist/server/request-auth.d.ts +19 -0
  259. package/dist/server/request-auth.d.ts.map +1 -0
  260. package/dist/server/request-auth.js +32 -0
  261. package/dist/server/request-auth.js.map +1 -0
  262. package/dist/server/types.d.ts +32 -0
  263. package/dist/server/types.d.ts.map +1 -1
  264. package/dist/server/types.js.map +1 -1
  265. package/dist/timers.d.ts +60 -0
  266. package/dist/timers.d.ts.map +1 -0
  267. package/dist/timers.js +33 -0
  268. package/dist/timers.js.map +1 -0
  269. package/dist/tracing/traceparent.d.ts +26 -0
  270. package/dist/tracing/traceparent.d.ts.map +1 -0
  271. package/dist/tracing/traceparent.js +53 -0
  272. package/dist/tracing/traceparent.js.map +1 -0
  273. package/package.json +11 -4
  274. package/src/adapters/http/client/transport.ts +31 -3
  275. package/src/adapters/http/client/types.ts +3 -2
  276. package/src/adapters/http/server/transport.ts +61 -26
  277. package/src/adapters/http/shared/headers.ts +7 -6
  278. package/src/adapters/local/client/transport.ts +74 -7
  279. package/src/adapters/local/client/types.ts +18 -0
  280. package/src/adapters/mock/client/transport.ts +9 -6
  281. package/src/adapters/mock/client/types.ts +7 -6
  282. package/src/adapters/port/transport.ts +124 -0
  283. package/src/adapters/websocket/client/index.ts +1 -0
  284. package/src/adapters/websocket/client/node.ts +34 -0
  285. package/src/adapters/websocket/client/transport.ts +251 -81
  286. package/src/adapters/websocket/client/types.ts +81 -21
  287. package/src/adapters/websocket/server/transport.ts +199 -301
  288. package/src/adapters/websocket/server/types.ts +20 -1
  289. package/src/adapters/websocket/shared/rpc.ts +453 -0
  290. package/src/browser.ts +51 -3
  291. package/src/client/call-types.ts +10 -14
  292. package/src/client/client.ts +28 -9
  293. package/src/client/deadline.ts +64 -0
  294. package/src/client/errors/README.md +2 -0
  295. package/src/client/errors/factory.ts +12 -8
  296. package/src/client/errors/http-errors.ts +5 -0
  297. package/src/client/errors/index.ts +1 -1
  298. package/src/client/errors/registry.ts +79 -22
  299. package/src/client/index.ts +21 -3
  300. package/src/client/middleware/cache.ts +120 -23
  301. package/src/client/middleware/circuit-breaker.ts +65 -35
  302. package/src/client/middleware/contexts.ts +17 -10
  303. package/src/client/middleware/items.ts +101 -6
  304. package/src/client/middleware/lru.ts +12 -0
  305. package/src/client/middleware/rate-limit.ts +9 -9
  306. package/src/client/middleware/resilience.ts +81 -0
  307. package/src/client/middleware/retry.ts +146 -34
  308. package/src/client/middleware/timeout.ts +57 -55
  309. package/src/client/middleware/tracing.ts +13 -4
  310. package/src/client/types.ts +9 -1
  311. package/src/clock.ts +21 -0
  312. package/src/duration.ts +56 -0
  313. package/src/index.ts +4 -0
  314. package/src/machines.ts +186 -0
  315. package/src/node.ts +11 -0
  316. package/src/procedures/capability.ts +7 -8
  317. package/src/procedures/collection/index.ts +9 -1
  318. package/src/procedures/collection/procedures.ts +57 -0
  319. package/src/procedures/collection/schemas.ts +110 -0
  320. package/src/procedures/collection/storage.ts +38 -0
  321. package/src/procedures/core/array.ts +79 -31
  322. package/src/procedures/core/index.ts +17 -2
  323. package/src/procedures/core/logic.ts +1 -1
  324. package/src/procedures/core/math.ts +5 -1
  325. package/src/procedures/core/meta.ts +45 -8
  326. package/src/procedures/core/object.ts +48 -14
  327. package/src/procedures/core/operands.ts +7 -0
  328. package/src/procedures/core/string.ts +4 -2
  329. package/src/procedures/core/type.ts +4 -2
  330. package/src/procedures/define-procedure.ts +73 -20
  331. package/src/procedures/discovery.ts +4 -6
  332. package/src/procedures/effects.ts +35 -0
  333. package/src/procedures/idempotency.ts +152 -0
  334. package/src/procedures/index.ts +18 -2
  335. package/src/procedures/interceptors.ts +28 -11
  336. package/src/procedures/invoke.ts +19 -5
  337. package/src/procedures/manifest.ts +158 -0
  338. package/src/procedures/ref.ts +4 -2
  339. package/src/procedures/runtime-programs.ts +27 -0
  340. package/src/procedures/types.ts +16 -0
  341. package/src/protocol.ts +108 -0
  342. package/src/server/host-policy.ts +8 -5
  343. package/src/server/host-procedures.ts +102 -0
  344. package/src/server/index.ts +5 -2
  345. package/src/server/procedure-server.ts +328 -12
  346. package/src/server/request-auth.ts +35 -0
  347. package/src/server/types.ts +37 -0
  348. package/src/timers.ts +82 -0
  349. package/src/tracing/traceparent.ts +61 -0
  350. package/dist/procedures/cli/announce.d.ts +0 -67
  351. package/dist/procedures/cli/announce.d.ts.map +0 -1
  352. package/dist/procedures/cli/announce.js +0 -392
  353. package/dist/procedures/cli/announce.js.map +0 -1
  354. package/dist/procedures/cli/discover.d.ts +0 -66
  355. package/dist/procedures/cli/discover.d.ts.map +0 -1
  356. package/dist/procedures/cli/discover.js +0 -310
  357. package/dist/procedures/cli/discover.js.map +0 -1
  358. package/dist/procedures/cli/index.d.ts +0 -13
  359. package/dist/procedures/cli/index.d.ts.map +0 -1
  360. package/dist/procedures/cli/index.js +0 -203
  361. package/dist/procedures/cli/index.js.map +0 -1
  362. package/dist/procedures/cli/init.d.ts +0 -17
  363. package/dist/procedures/cli/init.d.ts.map +0 -1
  364. package/dist/procedures/cli/init.js +0 -336
  365. package/dist/procedures/cli/init.js.map +0 -1
  366. package/src/procedures/cli/announce.ts +0 -470
  367. package/src/procedures/cli/discover.ts +0 -390
  368. package/src/procedures/cli/index.ts +0 -231
  369. package/src/procedures/cli/init.ts +0 -370
@@ -56,7 +56,8 @@ import { RouteResolver, type ResolvedRoute, type RouteResolutionResult } from ".
56
56
  import { BatchExecutor, type ExecutionContext } from "./batch-executor.js";
57
57
  import type { ProcedureRegistry } from "../procedures/registry.js";
58
58
  import type { EventBus } from "../events/types.js";
59
- import { TIMEOUT_METADATA_KEY, narrowCapability } from "../procedures/capability.js";
59
+ import { narrowCapability } from "../procedures/capability.js";
60
+ import { TIMEOUT_METADATA_KEY, absorbTimeout, writeRemainingTime } from "./deadline.js";
60
61
  import type { Capability, ClearanceOrder, NestedCallOptions } from "../procedures/types.js";
61
62
  import { PROCEDURE_REGISTRY } from "../procedures/registry.js";
62
63
  import { validateSchema } from "../procedures/schema.js";
@@ -147,6 +148,11 @@ interface CallerContext {
147
148
 
148
149
  /** The options of `exec()` and `execStream()`. */
149
150
  export interface ExecOptions {
151
+ /**
152
+ * The signal of the program: an abort stops the call that runs, and the calls that did not
153
+ * start do not start (roadmap R14). Each nested call gets it.
154
+ */
155
+ signal?: AbortSignal | undefined;
150
156
  /**
151
157
  * This function gets the hydration events of this program only: the refs that hydration runs,
152
158
  * also inside control flow and runners, with the call that gets each result. A trace uses it.
@@ -155,6 +161,14 @@ export interface ExecOptions {
155
161
  onRef?: ((event: HydrationEvent) => void) | undefined;
156
162
  }
157
163
 
164
+ /** The caller context of `exec()` and `execStream()`: the observer and the signal. */
165
+ function callerOf(options: ExecOptions): CallerContext {
166
+ const caller: CallerContext = {};
167
+ if (options.onRef) caller.onRef = options.onRef;
168
+ if (options.signal) caller.signal = options.signal;
169
+ return caller;
170
+ }
171
+
158
172
  /**
159
173
  * Generate a unique message ID.
160
174
  */
@@ -357,7 +371,7 @@ export class Client<TContext = {}> {
357
371
  * ```typescript
358
372
  * // Type accumulation example
359
373
  * const client = new Client(transport)
360
- * .use(createTimeoutMiddleware({ overall: 5000 })) // Client<TimeoutContext>
374
+ * .use(createOverallTimeoutMiddleware({ overall: 5000 })) // Client<TimeoutContext>
361
375
  * .use(createRetryMiddleware()) // Client<TimeoutContext & RetryContext>
362
376
  * .use(createCacheMiddleware({ methods: ["users.get"] })); // Client<... & CacheContext>
363
377
  *
@@ -478,7 +492,7 @@ export class Client<TContext = {}> {
478
492
  input?: unknown,
479
493
  options: ExecOptions = {}
480
494
  ): Promise<TOutput> {
481
- const caller: CallerContext = options.onRef ? { onRef: options.onRef } : {};
495
+ const caller: CallerContext = callerOf(options);
482
496
  const { path, input: hydratedInput } = await this.prepareRef(refOrPath, input, caller);
483
497
  return this.execInternal<TOutput>(path, hydratedInput, caller);
484
498
  }
@@ -501,7 +515,7 @@ export class Client<TContext = {}> {
501
515
  options: ExecOptions = {}
502
516
  ): AsyncIterable<TOutput> {
503
517
  const self = this;
504
- const caller: CallerContext = options.onRef ? { onRef: options.onRef } : {};
518
+ const caller: CallerContext = callerOf(options);
505
519
  return (async function* () {
506
520
  const { path, input: hydratedInput } = await self.prepareRef(refOrPath, input, caller);
507
521
  yield* self.execStreamInternal<TOutput>(path, hydratedInput, caller);
@@ -744,6 +758,10 @@ export class Client<TContext = {}> {
744
758
  (message.metadata as any).__schema = opts.schema;
745
759
  }
746
760
 
761
+ // The remaining time of the caller becomes the deadline of the call: the client sends the
762
+ // remaining time again for each try (roadmap R10)
763
+ absorbTimeout(message.metadata);
764
+
747
765
  // Compose middleware chain
748
766
  const runner = this.composeMiddleware<TReq, TRes>();
749
767
 
@@ -771,6 +789,9 @@ export class Client<TContext = {}> {
771
789
  // Innermost function: call transport
772
790
  const self = this;
773
791
  const transportRunner: ClientRunner<TReq, TRes> = async function* (context: ClientContext<TReq>) {
792
+ // The remaining time of the deadline goes with each try, so the server stops the handler
793
+ // when this client stops waiting (roadmap R10)
794
+ writeRemainingTime(context.message.metadata);
774
795
  yield* self.transport.send<TReq, TRes>(context.message);
775
796
  };
776
797
 
@@ -1163,11 +1184,9 @@ export class Client<TContext = {}> {
1163
1184
  yield* outputItems(await invokeProcedure(procedure, input, options));
1164
1185
  return;
1165
1186
  }
1166
- const callOptions: CallOptions<TContext> = { context: context.metadata as ClientContextInput<TContext> };
1167
- if (context.signal) {
1168
- callOptions.signal = context.signal;
1169
- }
1170
- yield* self.stream(self.pathToMethod(path), input, callOptions);
1187
+ // The deadline of the capability goes with the call, as for exec() (roadmap R14: before, a
1188
+ // remote leaf of route() sent the signal, not the deadline)
1189
+ yield* self.stream(self.pathToMethod(path), input, self.remoteCallOptions({ metadata: context.metadata, signal: context.signal }));
1171
1190
  })();
1172
1191
  }
1173
1192
 
@@ -0,0 +1,64 @@
1
+ /**
2
+ * One deadline for a call (roadmap R10).
3
+ *
4
+ * A call has one absolute deadline in its metadata (`__deadline`, a time of `Date.now()`). The
5
+ * key starts with `__`, so it stays in this process. Each part of the client can only make it
6
+ * earlier: the remaining time that the caller sends, the overall timeout and the timeout of each
7
+ * try. Just before the transport sends a try, the client writes the remaining time into
8
+ * `procedure-timeout`. The server uses it to make its own deadline earlier, so a handler stops
9
+ * when its caller stops waiting.
10
+ *
11
+ * Before, the overall timeout and the timeout of each try did not reach the server, and a
12
+ * client could also send `X-Timeout`, which the server ignored.
13
+ */
14
+
15
+ import type { Metadata } from "./types.js";
16
+
17
+ /**
18
+ * The metadata key of the remaining time of a remote call, in milliseconds. A server uses it
19
+ * only to make its deadline earlier.
20
+ */
21
+ export const TIMEOUT_METADATA_KEY = "procedure-timeout";
22
+
23
+ /** The metadata key of the absolute deadline of a call. It stays in this process. */
24
+ export const DEADLINE_METADATA_KEY = "__deadline";
25
+
26
+ /** The deadline of a call, or undefined. */
27
+ export function deadlineOf(metadata: Metadata): number | undefined {
28
+ const deadline = metadata[DEADLINE_METADATA_KEY];
29
+ return typeof deadline === "number" && Number.isFinite(deadline) ? deadline : undefined;
30
+ }
31
+
32
+ /**
33
+ * This function makes the deadline of a call earlier: the earlier of its deadline and `at`. It
34
+ * gives the deadline from before, to put back with `restoreDeadline`.
35
+ */
36
+ export function narrowDeadline(metadata: Metadata, at: number): number | undefined {
37
+ const before = deadlineOf(metadata);
38
+ metadata[DEADLINE_METADATA_KEY] = before === undefined ? at : Math.min(before, at);
39
+ return before;
40
+ }
41
+
42
+ /** This function puts back the deadline from before a `narrowDeadline`. */
43
+ export function restoreDeadline(metadata: Metadata, before: number | undefined): void {
44
+ if (before === undefined) delete metadata[DEADLINE_METADATA_KEY];
45
+ else metadata[DEADLINE_METADATA_KEY] = before;
46
+ }
47
+
48
+ /**
49
+ * The remaining time that the caller gives in `procedure-timeout` becomes the deadline of the
50
+ * call, when the call starts. The client then writes the remaining time again for each try.
51
+ */
52
+ export function absorbTimeout(metadata: Metadata, now: number = Date.now()): void {
53
+ const timeoutMs = metadata[TIMEOUT_METADATA_KEY];
54
+ if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs < 0) return;
55
+ delete metadata[TIMEOUT_METADATA_KEY];
56
+ narrowDeadline(metadata, now + timeoutMs);
57
+ }
58
+
59
+ /** This function writes the remaining time of the deadline into `procedure-timeout`, for one try. */
60
+ export function writeRemainingTime(metadata: Metadata, now: number = Date.now()): void {
61
+ const deadline = deadlineOf(metadata);
62
+ if (deadline === undefined) return;
63
+ metadata[TIMEOUT_METADATA_KEY] = Math.max(0, Math.floor(deadline - now));
64
+ }
@@ -213,6 +213,8 @@ console.error(formatError(error, true)); // include stack trace
213
213
  2. Add metadata to `ERROR_REGISTRY` in `registry.ts` or `HTTP_ERROR_REGISTRY` in `http-errors.ts`
214
214
  3. If HTTP-related, add to `HTTP_STATUS_ERROR_MAP` in `http-errors.ts`
215
215
 
216
+ `ERROR_CODES` of the wire protocol (`src/protocol.ts`, `WIRE-PROTOCOL.md`) is the source of the codes of the protocol. `ERROR_REGISTRY` has an entry for each of them, and that entry takes its HTTP status and its retry flag from `ERROR_CODES`. To add a code of the protocol, add it to `ERROR_CODES`. A code without texts in `registry.ts` gets the meaning of the protocol as its texts. `defineProtocolError` gives a code of the protocol its own texts.
217
+
216
218
  Example:
217
219
  ```typescript
218
220
  // 1. Add to ErrorCode enum
@@ -94,8 +94,10 @@ export type ErrorPattern = {
94
94
  const ERROR_PATTERNS : ErrorPattern[] = [
95
95
  {
96
96
  code: ErrorCode.ABORTED,
97
+ // The reason of AbortSignal.timeout() is a TimeoutError with the message "The operation was
98
+ // aborted due to timeout": it is a timeout (roadmap R30: before, it was ABORTED)
97
99
  detect: (name: string, message: string) =>
98
- name === "aborterror" || message.includes("abort"),
100
+ name === "aborterror" || (name !== "timeouterror" && message.includes("abort")),
99
101
  },
100
102
  {
101
103
  code: ErrorCode.TIMEOUT,
@@ -124,13 +126,8 @@ const ERROR_PATTERNS : ErrorPattern[] = [
124
126
  message.includes("network") ||
125
127
  message.includes("connection"),
126
128
  },
127
- {
128
- code: ErrorCode.PARSE_ERROR,
129
- detect: (_name: string, message: string) =>
130
- message.includes("parse") ||
131
- message.includes("json") ||
132
- message.includes("unexpected token"),
133
- },
129
+ // Before the parse errors: "Converting circular structure to JSON" names JSON too (roadmap R30:
130
+ // before, it was PARSE_ERROR)
134
131
  {
135
132
  code: ErrorCode.SERIALIZE_ERROR,
136
133
  detect: (_name: string, message: string) =>
@@ -138,6 +135,13 @@ const ERROR_PATTERNS : ErrorPattern[] = [
138
135
  message.includes("stringify") ||
139
136
  message.includes("circular"),
140
137
  },
138
+ {
139
+ code: ErrorCode.PARSE_ERROR,
140
+ detect: (_name: string, message: string) =>
141
+ message.includes("parse") ||
142
+ message.includes("json") ||
143
+ message.includes("unexpected token"),
144
+ },
141
145
  ] as const satisfies ErrorPattern[];
142
146
 
143
147
  /**
@@ -8,6 +8,7 @@
8
8
  import { ErrorCategory, ErrorSeverity, type ErrorMetadata } from "./types.js";
9
9
  import { ErrorCode } from "./codes.js";
10
10
  import { HTTPStatus } from "./http-status.js";
11
+ import { httpStatusOf } from "../../protocol.js";
11
12
 
12
13
  /**
13
14
  * Helper to create HTTP error metadata.
@@ -595,6 +596,10 @@ export function httpStatusToErrorCode(status: number): ErrorCode {
595
596
  * ```
596
597
  */
597
598
  export function errorCodeToHTTPStatus(code: ErrorCode): HTTPStatus {
599
+ // A code of the wire protocol has the status of ERROR_CODES: before, TIMEOUT gave 408 here and
600
+ // 504 on the wire
601
+ const protocolStatus = httpStatusOf(code);
602
+ if (protocolStatus !== undefined) return protocolStatus as HTTPStatus;
598
603
  // Build map from HTTP_STATUS_ERROR_MAP
599
604
  const entry = HTTP_STATUS_ERROR_MAP.find(([, errorCode]) => errorCode === code);
600
605
  return entry?.[0] ?? HTTPStatus.INTERNAL_SERVER_ERROR;
@@ -20,7 +20,7 @@
20
20
  * console.log(error.metadata.userMessage); // User-friendly message
21
21
  * console.log(error.metadata.devMessage); // Developer diagnostic
22
22
  * console.log(error.metadata.suggestions); // Suggested actions
23
- * console.log(error.metadata.retryable); // true
23
+ * console.log(error.metadata.retryable); // false (ERROR_CODES of the protocol)
24
24
  *
25
25
  * // Format for logging
26
26
  * console.log(formatError(error));
@@ -15,6 +15,7 @@ import {
15
15
  } from "./types.js";
16
16
  import { HTTP_ERROR_REGISTRY } from "./http-errors.js";
17
17
  import { ErrorCode } from "./codes.js";
18
+ import { ERROR_CODES, type ProtocolErrorCode } from "../../protocol.js";
18
19
 
19
20
  /**
20
21
  * Create error metadata with defaults.
@@ -47,12 +48,71 @@ function defineError(
47
48
  return result;
48
49
  }
49
50
 
51
+ /** The texts of an entry. For a code of the protocol, `ERROR_CODES` gives the status and the retry flag. */
52
+ type ProtocolErrorTexts = Omit<ErrorMetadata, "code" | "httpStatus" | "retryable">;
53
+
50
54
  /**
51
- * Universal Error Registry
52
- *
53
- * Protocol-agnostic error codes with rich metadata.
55
+ * This function makes the entry of a code of the wire protocol. The HTTP status and the retry
56
+ * flag come from `ERROR_CODES` (`protocol.ts`, `WIRE-PROTOCOL.md`), the source of these facts.
57
+ */
58
+ function defineProtocolError(code: ProtocolErrorCode, texts: ProtocolErrorTexts): ErrorMetadata {
59
+ const info = ERROR_CODES[code];
60
+ return defineError(code, { ...texts, httpStatus: info.http, retryable: info.retryable });
61
+ }
62
+
63
+ /** The category of each code of the protocol, for a code that the registry does not describe. */
64
+ const PROTOCOL_CATEGORIES: Readonly<Record<ProtocolErrorCode, ErrorCategory>> = {
65
+ NOT_FOUND: ErrorCategory.CLIENT,
66
+ NO_HANDLER: ErrorCategory.SERVER,
67
+ NOT_EXPOSED: ErrorCategory.AUTH,
68
+ NOT_DECLARED: ErrorCategory.AUTH,
69
+ FORBIDDEN: ErrorCategory.AUTH,
70
+ UNAUTHORIZED: ErrorCategory.AUTH,
71
+ VALIDATION_ERROR: ErrorCategory.CLIENT,
72
+ INVALID_REQUEST: ErrorCategory.PROTOCOL,
73
+ PROTOCOL_VERSION: ErrorCategory.PROTOCOL,
74
+ OUTPUT_VALIDATION_ERROR: ErrorCategory.SERVER,
75
+ NO_OUTPUT: ErrorCategory.SERVER,
76
+ HANDLER_ERROR: ErrorCategory.SERVER,
77
+ INTERNAL_ERROR: ErrorCategory.SERVER,
78
+ NOT_ACCEPTABLE: ErrorCategory.CLIENT,
79
+ DUPLICATE: ErrorCategory.CLIENT,
80
+ DUPLICATE_REQUEST: ErrorCategory.CLIENT,
81
+ ABORTED: ErrorCategory.CANCELLED,
82
+ TIMEOUT: ErrorCategory.TIMEOUT,
83
+ UNAVAILABLE: ErrorCategory.SERVER,
84
+ CONNECTION_CLOSED: ErrorCategory.NETWORK,
85
+ CONNECTION_NOT_FOUND: ErrorCategory.CLIENT,
86
+ };
87
+
88
+ /**
89
+ * This function gives the registry with one entry for each code of the protocol. The status and
90
+ * the retry flag of such an entry come from `ERROR_CODES`, so the two lists agree (before, the
91
+ * registry gave `TIMEOUT` the status 408 and two codes another retry flag). A code without texts
92
+ * here gets the meaning of the protocol as its texts.
93
+ */
94
+ function withProtocolCodes(described: ErrorRegistry): ErrorRegistry {
95
+ const registry: ErrorRegistry = { ...described };
96
+ for (const code of Object.keys(ERROR_CODES) as ProtocolErrorCode[]) {
97
+ const info = ERROR_CODES[code];
98
+ const meaning = `${info.meaning}.`;
99
+ const texts: ProtocolErrorTexts = described[code] ?? {
100
+ summary: info.meaning,
101
+ detail: meaning,
102
+ category: PROTOCOL_CATEGORIES[code],
103
+ severity: info.retryable ? ErrorSeverity.WARNING : ErrorSeverity.ERROR,
104
+ userMessage: meaning,
105
+ devMessage: meaning,
106
+ };
107
+ registry[code] = { ...texts, code, httpStatus: info.http, retryable: info.retryable };
108
+ }
109
+ return registry;
110
+ }
111
+
112
+ /**
113
+ * The entries with their own texts. `ERROR_REGISTRY` adds the codes of the protocol.
54
114
  */
55
- export const ERROR_REGISTRY: ErrorRegistry = {
115
+ const DESCRIBED_ERRORS = {
56
116
  //
57
117
  // ═══ Network Errors ═══
58
118
  //
@@ -108,16 +168,14 @@ export const ERROR_REGISTRY: ErrorRegistry = {
108
168
  // ═══ Timeout Errors ═══
109
169
  //
110
170
 
111
- TIMEOUT: defineError(ErrorCode.TIMEOUT, {
171
+ TIMEOUT: defineProtocolError("TIMEOUT", {
112
172
  summary: "Request timed out",
113
173
  detail:
114
174
  "The request exceeded the configured timeout duration. This may indicate slow server response, network congestion, or overly aggressive timeout settings.",
115
175
  category: ErrorCategory.TIMEOUT,
116
- retryable: true,
117
176
  severity: ErrorSeverity.WARNING,
118
177
  userMessage: "The request took too long to complete. Please try again.",
119
178
  devMessage: "Request exceeded timeout threshold. Consider increasing timeout or optimizing server response time.",
120
- httpStatus: 408,
121
179
  suggestions: [
122
180
  "Try again with a longer timeout",
123
181
  "Check server performance",
@@ -159,11 +217,10 @@ export const ERROR_REGISTRY: ErrorRegistry = {
159
217
  // ═══ Cancellation Errors ═══
160
218
  //
161
219
 
162
- ABORTED: defineError(ErrorCode.ABORTED, {
220
+ ABORTED: defineProtocolError("ABORTED", {
163
221
  summary: "Request was aborted",
164
222
  detail: "The request was explicitly cancelled by the client via AbortSignal. This is user-initiated.",
165
223
  category: ErrorCategory.CANCELLED,
166
- retryable: false,
167
224
  severity: ErrorSeverity.INFO,
168
225
  userMessage: "The request was cancelled.",
169
226
  devMessage: "Request aborted via AbortSignal. This is expected and not an error condition.",
@@ -269,15 +326,13 @@ export const ERROR_REGISTRY: ErrorRegistry = {
269
326
  ],
270
327
  }),
271
328
 
272
- UNAUTHORIZED: defineError(ErrorCode.UNAUTHORIZED, {
329
+ UNAUTHORIZED: defineProtocolError("UNAUTHORIZED", {
273
330
  summary: "Unauthorized",
274
331
  detail: "Authentication is required but was not provided or is invalid.",
275
332
  category: ErrorCategory.AUTH,
276
- retryable: false,
277
333
  severity: ErrorSeverity.ERROR,
278
334
  userMessage: "Authentication required. Please sign in.",
279
335
  devMessage: "Missing or invalid authentication credentials. Check auth token/API key.",
280
- httpStatus: 401,
281
336
  suggestions: [
282
337
  "Provide valid authentication credentials",
283
338
  "Check token hasn't expired",
@@ -285,15 +340,13 @@ export const ERROR_REGISTRY: ErrorRegistry = {
285
340
  ],
286
341
  }),
287
342
 
288
- FORBIDDEN: defineError(ErrorCode.FORBIDDEN, {
343
+ FORBIDDEN: defineProtocolError("FORBIDDEN", {
289
344
  summary: "Forbidden",
290
345
  detail: "The authenticated user doesn't have permission to access this resource.",
291
346
  category: ErrorCategory.AUTH,
292
- retryable: false,
293
347
  severity: ErrorSeverity.ERROR,
294
348
  userMessage: "You don't have permission to access this resource.",
295
349
  devMessage: "Insufficient permissions. Check user roles and resource ACLs.",
296
- httpStatus: 403,
297
350
  suggestions: [
298
351
  "Verify user has required permissions",
299
352
  "Check resource access control lists",
@@ -301,15 +354,13 @@ export const ERROR_REGISTRY: ErrorRegistry = {
301
354
  ],
302
355
  }),
303
356
 
304
- NOT_FOUND: defineError(ErrorCode.NOT_FOUND, {
357
+ NOT_FOUND: defineProtocolError("NOT_FOUND", {
305
358
  summary: "Not found",
306
359
  detail: "The requested resource does not exist.",
307
360
  category: ErrorCategory.CLIENT,
308
- retryable: false,
309
361
  severity: ErrorSeverity.ERROR,
310
362
  userMessage: "The requested item was not found.",
311
363
  devMessage: "Resource not found. Verify ID/path is correct and resource exists.",
312
- httpStatus: 404,
313
364
  suggestions: [
314
365
  "Verify the resource ID is correct",
315
366
  "Check the resource hasn't been deleted",
@@ -402,17 +453,15 @@ export const ERROR_REGISTRY: ErrorRegistry = {
402
453
  // ═══ Server Errors (5xx) ═══
403
454
  //
404
455
 
405
- INTERNAL_ERROR: defineError(ErrorCode.INTERNAL_ERROR, {
456
+ INTERNAL_ERROR: defineProtocolError("INTERNAL_ERROR", {
406
457
  summary: "Internal server error",
407
458
  detail: "The server encountered an unexpected condition. This is a server-side bug.",
408
459
  category: ErrorCategory.SERVER,
409
- retryable: true,
410
460
  severity: ErrorSeverity.CRITICAL,
411
461
  userMessage: "Server error occurred. Please try again later.",
412
462
  devMessage: "Internal server error. Check server logs for details.",
413
- httpStatus: 500,
463
+ // The protocol says that a retry does not help (ERROR_CODES: retryable false)
414
464
  suggestions: [
415
- "Retry the request",
416
465
  "Check server logs",
417
466
  "Contact server team",
418
467
  ],
@@ -554,6 +603,14 @@ export const ERROR_REGISTRY: ErrorRegistry = {
554
603
  ...HTTP_ERROR_REGISTRY,
555
604
  } as const satisfies ErrorRegistry;
556
605
 
606
+ /**
607
+ * Universal Error Registry
608
+ *
609
+ * Protocol-agnostic error codes with rich metadata. Each code of the wire protocol has an entry,
610
+ * and `ERROR_CODES` gives its HTTP status and its retry flag.
611
+ */
612
+ export const ERROR_REGISTRY: ErrorRegistry = withProtocolCodes(DESCRIBED_ERRORS);
613
+
557
614
  /**
558
615
  * Get error metadata by code.
559
616
  *
@@ -29,7 +29,7 @@ export { LocalTransport } from "../adapters/local/client/index.js";
29
29
  export type { LocalTransportOptions, Handler } from "../adapters/local/client/index.js";
30
30
 
31
31
  export { WebSocketTransport } from "../adapters/websocket/client/index.js";
32
- export type { WebSocketTransportOptions } from "../adapters/websocket/client/index.js";
32
+ export type { WebSocketTransportOptions, WebSocketClass } from "../adapters/websocket/client/index.js";
33
33
  // WebSocketState is a runtime enum — export as a value (not type-only) so consumers can compare
34
34
  // transport.getState() === WebSocketState.CONNECTED. See documentation/BUGS-2026-07.md (L1).
35
35
  export { WebSocketState } from "../adapters/websocket/client/index.js";
@@ -43,10 +43,13 @@ export type {
43
43
  } from "../adapters/mock/client//index.js";
44
44
 
45
45
  // Middleware
46
- export { createRetryMiddleware } from "./middleware/retry.js";``
46
+ export { createRetryMiddleware } from "./middleware/retry.js";
47
+ // The delivery of a failed try: it did not leave, or its outcome is indeterminate (roadmap R1)
48
+ export { DELIVERY_METADATA_KEY, deliveryOf, isNotSentError } from "./middleware/items.js";
49
+ export type { Delivery } from "./middleware/items.js";
47
50
  export type { RetryOptions } from "./middleware/retry.js";
48
51
 
49
- export { createCacheMiddleware } from "./middleware/cache.js";
52
+ export { createCacheMiddleware, invalidateCache } from "./middleware/cache.js";
50
53
  export type { CacheOptions, CacheStats } from "./middleware/cache.js";
51
54
 
52
55
  export {
@@ -55,6 +58,21 @@ export {
55
58
  createCombinedTimeoutMiddleware,
56
59
  } from "./middleware/timeout.js";
57
60
  export type { TimeoutOptions } from "./middleware/timeout.js";
61
+ // Typed durations (roadmap R11)
62
+ export { ms, seconds, minutes, hours, toMs, isDuration } from "../duration.js";
63
+ export type { Duration } from "../duration.js";
64
+ // The resilience preset and the deadline of a call (roadmap R10)
65
+ export { resilience } from "./middleware/resilience.js";
66
+ export type { ResilienceOptions, ResilienceContext } from "./middleware/resilience.js";
67
+ export {
68
+ TIMEOUT_METADATA_KEY,
69
+ DEADLINE_METADATA_KEY,
70
+ deadlineOf,
71
+ narrowDeadline,
72
+ restoreDeadline,
73
+ absorbTimeout,
74
+ writeRemainingTime,
75
+ } from "./deadline.js";
58
76
 
59
77
  export { createPaginationMiddleware, paginateAll } from "./middleware/pagination.js";
60
78
  export type { PaginationOptions } from "./middleware/pagination.js";