@orpc/shared 2.0.0-beta.2 → 2.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,9 @@
7
7
  <a href="https://www.npmjs.com/package/@orpc/shared">
8
8
  <img alt="weekly downloads" src="https://img.shields.io/npm/dw/%40orpc%2Fshared?logo=npm" />
9
9
  </a>
10
+ <a href="https://app.codspeed.io/middleapi/orpc?utm_source=badge">
11
+ <img alt="CodSpeed" src="https://img.shields.io/endpoint?url=https://codspeed.io/badge.json" />
12
+ </a>
10
13
  <a href="https://github.com/middleapi/orpc/blob/main/LICENSE">
11
14
  <img alt="MIT License" src="https://img.shields.io/github/license/middleapi/orpc?logo=open-source-initiative" />
12
15
  </a>
@@ -26,10 +29,10 @@ You can read the documentation [here](https://orpc.dev).
26
29
 
27
30
  **Core**
28
31
 
29
- - [@orpc/contract](https://www.npmjs.com/package/@orpc/contract): Define type-safe contracts for your API.
30
- - [@orpc/server](https://www.npmjs.com/package/@orpc/server): Implement your API or contract on the server.
31
- - [@orpc/client](https://www.npmjs.com/package/@orpc/client): Consume your API from the client with full type safety.
32
- - [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Bring OpenAPI compatibility to your APIs.
32
+ - [@orpc/contract](https://www.npmjs.com/package/@orpc/contract): Define API contract as the single source of truth.
33
+ - [@orpc/server](https://www.npmjs.com/package/@orpc/server): Build APIs or implement contracts.
34
+ - [@orpc/client](https://www.npmjs.com/package/@orpc/client): Consume APIs with end-to-end type safety.
35
+ - [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Add OpenAPI compatibility to APIs.
33
36
 
34
37
  **Schema validation**
35
38
 
@@ -37,23 +40,30 @@ You can read the documentation [here](https://orpc.dev).
37
40
  - [@orpc/valibot](https://www.npmjs.com/package/@orpc/valibot): Integrate with [Valibot](https://valibot.dev/).
38
41
  - [@orpc/arktype](https://www.npmjs.com/package/@orpc/arktype): Integrate with [ArkType](https://arktype.io/).
39
42
 
43
+ **Built-in features**
44
+
45
+ - [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher): Pub/Sub with memory, Redis, and Upstash adapters.
46
+ - [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit): Rate limiting with memory, Redis, and Upstash adapters.
47
+ - [@orpc/json-schema](https://www.npmjs.com/package/@orpc/json-schema): Smart coercion for OpenAPI requests.
48
+
40
49
  **Framework & ecosystem integrations**
41
50
 
42
- - [@orpc/next](https://www.npmjs.com/package/@orpc/react): Use oRPC with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data).
51
+ - [@orpc/next](https://www.npmjs.com/package/@orpc/next): Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data).
52
+ - [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
43
53
  - [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
54
+ - [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
55
+ - [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
44
56
  - [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
45
-
46
- **Built-in features**
47
-
48
- - [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher): Pub/Sub.
49
- - [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit): Rate limiting.
50
- - [@orpc/json-schema](https://www.npmjs.com/package/@orpc/json-schema): Smart coercion for OpenAPI requests.
57
+ - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
58
+ - [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).
59
+ - [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare): Adapters for [Cloudflare's RateLimit and Durable Objects](https://developers.cloudflare.com/workers/).
60
+ - [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc): Reuse existing [tRPC](https://trpc.io/) routers within oRPC.
51
61
 
52
62
  **Observability**
53
63
 
54
- - [@orpc/opentelemetry](https://www.npmjs.com/package/@orpc/opentelemetry): Instrument your API with [OpenTelemetry](https://opentelemetry.io/).
55
- - [@orpc/pino](https://www.npmjs.com/package/@orpc/pino): Log with [Pino](https://getpino.io/).
56
- - [@orpc/evlog](https://www.npmjs.com/package/@orpc/evlog): Log with [Evlog](https://evlog.dev/).
64
+ - [@orpc/opentelemetry](https://www.npmjs.com/package/@orpc/opentelemetry): Integrate with [OpenTelemetry](https://opentelemetry.io/) for distributed tracing.
65
+ - [@orpc/pino](https://www.npmjs.com/package/@orpc/pino): Integrate with [Pino](https://getpino.io/) for logging.
66
+ - [@orpc/evlog](https://www.npmjs.com/package/@orpc/evlog): Integrate with [Evlog](https://evlog.dev/) for logging.
57
67
 
58
68
  ## Sponsors
59
69
 
@@ -99,12 +109,10 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
99
109
  <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&amp;v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td>
100
110
  <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&amp;v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td>
101
111
  <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&amp;v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td>
102
- <td align="center"><a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="139" alt="Andrew Peters"/><br />Andrew Peters</a></td>
103
112
  <td align="center"><a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&amp;v=4" width="139" alt="Ryan Vogel"/><br />Ryan Vogel</a></td>
113
+ <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
104
114
  </tr>
105
115
  <tr>
106
- <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
107
- <td align="center"><a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&amp;v=4" width="139" alt="Peter Adam"/><br />Peter Adam</a></td>
108
116
  <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&amp;v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
109
117
  <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&amp;v=4" width="139" alt="shota"/><br />shota</a></td>
110
118
  </tr>
@@ -115,25 +123,25 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
115
123
  <table>
116
124
  <tr>
117
125
  <td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&amp;v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td>
126
+ <td align="center"><a href="https://github.com/Nic13Gamer?ref=orpc" target="_blank" rel="noopener" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&amp;v=4" width="119" alt="Nicholas"/><br />Nicholas</a></td>
118
127
  <td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&amp;v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td>
119
128
  <td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td>
120
129
  <td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&amp;v=4" width="119" alt="soonoo"/><br />soonoo</a></td>
121
130
  <td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&amp;v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td>
122
131
  <td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&amp;v=4" width="119" alt="Denis"/><br />Denis</a></td>
123
- <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&amp;v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
124
132
  </tr>
125
133
  <tr>
134
+ <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&amp;v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
126
135
  <td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&amp;v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td>
127
136
  <td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&amp;v=4" width="119" alt="Sam"/><br />Sam</a></td>
128
137
  <td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&amp;v=4" width="119" alt="Titoine"/><br />Titoine</a></td>
129
138
  <td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&amp;v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td>
130
139
  <td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&amp;v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td>
131
140
  <td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&amp;v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td>
132
- <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&amp;v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
133
141
  </tr>
134
142
  <tr>
143
+ <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&amp;v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
135
144
  <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&amp;v=4" width="119" alt="Alex"/><br />Alex</a></td>
136
- <td align="center"><a href="https://github.com/nattstack?ref=orpc" target="_blank" rel="noopener" title="nattstack"><img src="https://avatars.githubusercontent.com/u/31426677?u=fa9dbb8b3e66eb0ea3c88db5dc07f31c8c5418fe&amp;v=4" width="119" alt="nattstack"/><br />nattstack</a></td>
137
145
  <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=29e91400dbd4a9c217048a8f59562c4f740498e6&amp;v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
138
146
  </tr>
139
147
  </table>
@@ -150,7 +158,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
150
158
  <a href="https://github.com/theoludwig?ref=orpc" target="_blank" rel="noopener" title="Théo LUDWIG"><img src="https://avatars.githubusercontent.com/u/25207499?u=a6a9653725a2f574c07893748806668e0598cdbe&amp;v=4" width="32" height="32" alt="Théo LUDWIG" /></a>
151
159
  <a href="https://github.com/abhay-ramesh?ref=orpc" target="_blank" rel="noopener" title="Abhay Ramesh"><img src="https://avatars.githubusercontent.com/u/66196314?u=c5c2b0327b26606c2efcfaf17046ab18c3d25c57&amp;v=4" width="32" height="32" alt="Abhay Ramesh" /></a>
152
160
  <a href="https://github.com/shr-ink?ref=orpc" target="_blank" rel="noopener" title="shr.ink oü"><img src="https://avatars.githubusercontent.com/u/139700438?v=4" width="32" height="32" alt="shr.ink oü" /></a>
153
- <a href="https://github.com/johngerome?ref=orpc" target="_blank" rel="noopener" title="0x4e32"><img src="https://avatars.githubusercontent.com/u/2002000?u=24e8dd943cfc862aa284d858a023532c75071ade&amp;v=4" width="32" height="32" alt="0x4e32" /></a>
161
+ <a href="https://github.com/johngerome?ref=orpc" target="_blank" rel="noopener" title="0x4e32"><img src="https://avatars.githubusercontent.com/u/2002000?u=505e54608466ab53754f702973687b04c6424c1f&amp;v=4" width="32" height="32" alt="0x4e32" /></a>
154
162
  <a href="https://github.com/yzuyr?ref=orpc" target="_blank" rel="noopener" title="Ryuz"><img src="https://avatars.githubusercontent.com/u/196539378?u=d38374588d219b6748b16406982f6559411466d4&amp;v=4" width="32" height="32" alt="Ryuz" /></a>
155
163
  <a href="https://github.com/happyboy2022?ref=orpc" target="_blank" rel="noopener" title="happyboy"><img src="https://avatars.githubusercontent.com/u/103669586?u=65b49c4b893ed3703909fbb3a7a22313f3f9c121&amp;v=4" width="32" height="32" alt="happyboy" /></a>
156
164
  <a href="https://github.com/YiCChi?ref=orpc" target="_blank" rel="noopener" title="yicchi"><img src="https://avatars.githubusercontent.com/u/86967274?u=6c2756f09fe15dd94d572f560e979cd157982852&amp;v=4" width="32" height="32" alt="yicchi" /></a>
@@ -164,7 +172,9 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
164
172
  <a href="https://github.com/nelsonlaidev?ref=orpc" target="_blank" rel="noopener" title="Nelson Lai"><img src="https://avatars.githubusercontent.com/u/75498339?u=2fc0e0b95dd184c5ffb744df977cb15a18b60672&amp;v=4" width="32" height="32" alt="Nelson Lai" /></a>
165
173
  <a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="Lê Cao Nguyên"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&amp;v=4" width="32" height="32" alt="Lê Cao Nguyên" /></a>
166
174
  <a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&amp;v=4" width="32" height="32" alt="Robert Soriano" /></a>
175
+ <a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="32" height="32" alt="Andrew Peters" /></a>
167
176
  <a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a>
177
+ <a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&amp;v=4" width="32" height="32" alt="Peter Adam" /></a>
168
178
  <a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a>
169
179
  <a href="https://github.com/NovakAnton?ref=orpc" target="_blank" rel="noopener" title="Novak Antonijevic"><img src="https://avatars.githubusercontent.com/u/157126729?u=ae49fa22292d55c0434ff0ca008206155b18663b&amp;v=4" width="32" height="32" alt="Novak Antonijevic" /></a>
170
180
  <a href="https://github.com/laduniestu?ref=orpc" target="_blank" rel="noopener" title="Laduni Estu Syalwa"><img src="https://avatars.githubusercontent.com/u/44757637?u=a2fc1ea8f7d827a96721176f79d30592d1c48059&amp;v=4" width="32" height="32" alt="Laduni Estu Syalwa" /></a>
@@ -172,6 +182,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
172
182
  <a href="https://github.com/illarionvk?ref=orpc" target="_blank" rel="noopener" title="Illarion Koperski"><img src="https://avatars.githubusercontent.com/u/5012724?u=7cfa13652f7ac5fb3c56d880e3eb3fbe40c3ea34&amp;v=4" width="32" height="32" alt="Illarion Koperski" /></a>
173
183
  <a href="https://github.com/steelbrain?ref=orpc" target="_blank" rel="noopener" title="Anees Iqbal"><img src="https://avatars.githubusercontent.com/u/4278113?u=22b80b5399eed68ac76cd58b02961b0481f1db11&amp;v=4" width="32" height="32" alt="Anees Iqbal" /></a>
174
184
  <a href="https://github.com/Scrumplex?ref=orpc" target="_blank" rel="noopener" title="Sefa Eyeoglu"><img src="https://avatars.githubusercontent.com/u/11587657?u=ab503582165c0bbff0cca47ce31c9450bb1553c9&amp;v=4" width="32" height="32" alt="Sefa Eyeoglu" /></a>
185
+ <a href="https://github.com/nattstack?ref=orpc" target="_blank" rel="noopener" title="natt"><img src="https://avatars.githubusercontent.com/u/31426677?u=fa9dbb8b3e66eb0ea3c88db5dc07f31c8c5418fe&amp;v=4" width="32" height="32" alt="natt" /></a>
175
186
  <a href="https://github.com/ChromeGG?ref=orpc" target="_blank" rel="noopener" title="Adam Tkaczyk"><img src="https://avatars.githubusercontent.com/u/39050595?u=a58ca6042a6950e94e6e92442db76ef584279bc0&amp;v=4" width="32" height="32" alt="Adam Tkaczyk" /></a>
176
187
  <a href="https://github.com/plancraft?ref=orpc" target="_blank" rel="noopener" title="plancraft"><img src="https://avatars.githubusercontent.com/u/46482287?v=4" width="32" height="32" alt="plancraft" /></a>
177
188
  </p>
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { Promisable } from 'type-fest';
2
- export { IsEqual, PartialDeep, Promisable, Writable } from 'type-fest';
1
+ import { Arrayable, Promisable } from 'type-fest';
2
+ export { Arrayable, IsEqual, PartialDeep, Promisable, Writable } from 'type-fest';
3
3
  import { Tracer, TraceAPI, ContextAPI, PropagationAPI, SpanOptions, Context, Span, AttributeValue, Exception } from '@opentelemetry/api';
4
4
  import { AsyncIteratorClass } from '@standardserver/shared';
5
- export { AbortError, AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, sleep, stringifyJSON, toArray } from '@standardserver/shared';
5
+ export { AbortError, AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, sequential, sleep, stringifyJSON, toArray } from '@standardserver/shared';
6
6
 
7
7
  type MaybeOptionalOptions<TOptions> = object extends TOptions ? [options?: TOptions] : [options: TOptions];
8
8
  declare function resolveMaybeOptionalOptions<T>(rest: MaybeOptionalOptions<T>): T;
@@ -14,13 +14,13 @@ declare function splitInHalf<T>(arr: readonly T[]): [T[], T[]];
14
14
  *
15
15
  * Prefers the newer `.bytes` method when available as it more efficient but not widely supported yet.
16
16
  */
17
- declare function loadBytes(source: Pick<Blob, 'arrayBuffer' | 'bytes'>): Promise<Uint8Array<ArrayBuffer>>;
17
+ declare function loadBytes(source: Pick<Blob, 'arrayBuffer' | 'bytes'>): ReturnType<Blob['bytes']>;
18
18
  /**
19
19
  * Normalize text or binary-like inputs to either:
20
20
  * - the original string value, or
21
21
  * - a Uint8Array view over the source bytes.
22
22
  */
23
- declare function toStringOrBytes(source: string | ArrayBuffer | Blob | Exclude<ConstructorParameters<typeof Blob>[0], undefined>[0][] | Pick<Uint8Array<ArrayBuffer>, 'buffer' | 'byteOffset' | 'byteLength'>): Promise<string | Uint8Array<ArrayBuffer>>;
23
+ declare function toStringOrBytes(source: Arrayable<string | ArrayBuffer | Pick<Uint8Array<ArrayBuffer>, 'buffer' | 'byteOffset' | 'byteLength'>>): string | Awaited<ReturnType<Blob['bytes']>>;
24
24
 
25
25
  declare function isDeepEqual(a: unknown, b: unknown): boolean;
26
26
 
@@ -41,6 +41,7 @@ declare function normalizeHttpPath(path: string): `/${string}`;
41
41
  declare function mergeHttpPath(a: `/${string}`, b: `/${string}`): `/${string}`;
42
42
  declare function matchesHttpPathPrefix(url: `/${string}`, prefix: `/${string}`): boolean;
43
43
  declare function matchesHttpPath(url: `/${string}`, path: `/${string}`): boolean;
44
+ declare function isCompressibleContentType(contentType: string | null | undefined): boolean;
44
45
 
45
46
  /**
46
47
  * Compares two sequential IDs.
@@ -102,6 +103,30 @@ type OnFinishState<TResult, TError> = [error: TError, data: undefined, isSuccess
102
103
  declare function onFinish<T, TOptions extends {
103
104
  next: () => any;
104
105
  }, TRest extends any[]>(callback: NoInfer<(state: OnFinishState<Awaited<ReturnType<TOptions['next']>>, ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError>, options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
106
+ /**
107
+ * Creates a middleware or interceptor that invokes a callback when the returned async
108
+ * iterator object throws an error while being consumed.
109
+ *
110
+ * This does not replace the `onError`. `onError` only fires on the
111
+ * initial call (before the interceptor returns the iterator), whereas this
112
+ * callback only fires while consuming the iterator. Use both together to
113
+ * catch all possible errors.
114
+ */
115
+ declare function onAsyncIteratorObjectError<T, TOptions extends {
116
+ next: () => any;
117
+ }, TRest extends any[]>(callback: NoInfer<(error: ThrowableError | (ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError), options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
118
+ /**
119
+ * Creates an interceptor that invokes a callback when the returned readable
120
+ * stream errors while being consumed.
121
+ *
122
+ * This does not replace the `onError`. `onError` only fires on the
123
+ * initial call (before the interceptor returns the stream), whereas this
124
+ * callback only fires while consuming the stream. Use both together to catch
125
+ * all possible errors.
126
+ */
127
+ declare function onReadableStreamError<T, TOptions extends {
128
+ next: () => any;
129
+ }, TRest extends any[]>(callback: NoInfer<(error: ThrowableError | (ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError), options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
105
130
  declare function intercept<TOptions extends InterceptableOptions, TResult>(interceptors: undefined | Interceptor<TOptions, TResult>[], options: NoInfer<TOptions>, main: NoInfer<(options: TOptions) => TResult>): TResult;
106
131
 
107
132
  /**
@@ -147,8 +172,8 @@ interface WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>
147
172
  */
148
173
  runWith?: <T>(run: () => Promise<T>) => Promise<T>;
149
174
  mapResult?: (result: IteratorResult<TYield, TReturn>) => Promisable<IteratorResult<TMappedYield, TMappedReturn>>;
150
- mapError?: (error: unknown) => Promisable<unknown>;
151
- onError?: (error: unknown) => Promisable<void>;
175
+ mapError?: (error: ThrowableError) => Promisable<ThrowableError>;
176
+ onError?: (error: ThrowableError) => Promisable<void>;
152
177
  /**
153
178
  * Execute after the stream finishes or is cancelled.
154
179
  */
@@ -157,6 +182,35 @@ interface WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>
157
182
  declare function wrapAsyncIterator<TYield, TReturn, TMappedYield = TYield, TMappedReturn = TReturn>(iterator: AsyncIterator<TYield, TReturn>, { runWith, mapResult, mapError, onError, onFinish }: WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>): NoInfer<AsyncIteratorClass<TMappedYield, TMappedReturn>>;
158
183
  declare function traceAsyncIterator<T, TReturn, TNext>(options: StartSpanOptions | string, iterator: AsyncIterator<T, TReturn, TNext>): AsyncIteratorClass<T, TReturn, TNext>;
159
184
  declare function replicateAsyncIterator<T, TReturn, TNext>(source: AsyncIterator<T, TReturn, TNext>, count: number): (AsyncIteratorClass<T, TReturn, TNext>)[];
185
+ interface ConsumeAsyncIteratorOptions<T, TReturn, TError> {
186
+ /**
187
+ * Called on each event
188
+ */
189
+ onEvent: (event: T) => void;
190
+ /**
191
+ * Called once error happens
192
+ */
193
+ onError?: (error: TError) => void;
194
+ /**
195
+ * Called once AsyncIteratorObject is done
196
+ *
197
+ * @info If iterator is canceled, `undefined` can be passed on success
198
+ */
199
+ onSuccess?: (value: TReturn | undefined) => void;
200
+ /**
201
+ * Called once after onError or onSuccess
202
+ *
203
+ * @info If iterator is canceled, `undefined` can be passed on success
204
+ */
205
+ onFinish?: (state: [error: TError, data: undefined, isSuccess: false] | [error: null, data: TReturn | undefined, isSuccess: true]) => void;
206
+ }
207
+ /**
208
+ * Consumes an AsyncIteratorObject with lifecycle callbacks
209
+ *
210
+ * @warning If no `onError` or `onFinish` is provided, error will be thrown into unhandled rejection channel.
211
+ * @return unsubscribe callback
212
+ */
213
+ declare function consumeAsyncIterator<T, TReturn, TError = ThrowableError>(iterator: AsyncIterator<T, TReturn> | PromiseWithError<AsyncIterator<T, TReturn>, TError>, options: ConsumeAsyncIteratorOptions<T, TReturn, TError | ThrowableError>): () => Promise<void>;
160
214
 
161
215
  type Segment = string | number;
162
216
  declare function findDeepMatches(check: (value: unknown) => boolean, payload: unknown, segments?: Segment[], maps?: Segment[][], values?: unknown[]): {
@@ -257,6 +311,11 @@ declare class AsyncIdQueue<T> {
257
311
  * Returns a signal that aborts only after all provided signals are aborted.
258
312
  */
259
313
  declare function allAbortSignal(signals: readonly (AbortSignal | undefined)[]): AbortSignal | undefined;
314
+ /**
315
+ * Returns a signal that aborts as soon as any of the provided signals aborts,
316
+ * with the same abort reason.
317
+ */
318
+ declare function anyAbortSignal(signals: readonly (AbortSignal | undefined)[]): AbortSignal | undefined;
260
319
  declare function runWithSignal<T>(signal: AbortSignal | undefined, fn: () => Promise<T>): Promise<T>;
261
320
 
262
321
  declare function replicateReadableStream<T>(stream: ReadableStream<T>, count: number): ReadableStream<T>[];
@@ -265,7 +324,7 @@ type ReadableStreamReadResult<T> = {
265
324
  value: T;
266
325
  } | {
267
326
  done: true;
268
- value: undefined | T;
327
+ value?: undefined | T;
269
328
  };
270
329
  interface WrapReadableStreamOptions<T, TMapped> {
271
330
  /**
@@ -275,8 +334,8 @@ interface WrapReadableStreamOptions<T, TMapped> {
275
334
  */
276
335
  runWith?: <T>(run: () => Promise<T>) => Promise<T>;
277
336
  mapResult?: (result: ReadableStreamReadResult<T>) => Promisable<ReadableStreamReadResult<TMapped>>;
278
- mapError?: (error: unknown) => Promisable<unknown>;
279
- onError?: (error: unknown) => Promisable<void>;
337
+ mapError?: (error: ThrowableError) => Promisable<ThrowableError>;
338
+ onError?: (error: ThrowableError) => Promisable<void>;
280
339
  /**
281
340
  * Guaranteed to execute exactly once after the stream finishes or is cancelled.
282
341
  */
@@ -285,9 +344,9 @@ interface WrapReadableStreamOptions<T, TMapped> {
285
344
  declare function wrapReadableStream<T, TMapped = T>(stream: ReadableStream<T>, { runWith, mapResult, mapError, onError, onFinish }: WrapReadableStreamOptions<T, TMapped>): NoInfer<ReadableStream<TMapped>>;
286
345
  declare function traceReadableStream<T>(options: StartSpanOptions | string, stream: ReadableStream<T>): ReadableStream<T>;
287
346
  /**
288
- * Converts a `ReadableStream` into an `AsyncIteratorClass`.
347
+ * Converts a {@link ReadableStream} into an {@link AsyncIteratorClass}.
289
348
  */
290
- declare function streamToAsyncIteratorClass<T>(stream: ReadableStream<T>, { signal }?: {
349
+ declare function streamToAsyncIteratorObject<T>(stream: ReadableStream<T>, { signal }?: {
291
350
  signal?: undefined | AbortSignal;
292
351
  }): AsyncIteratorClass<T>;
293
352
  /**
@@ -302,5 +361,5 @@ declare function asyncIteratorToUnproxiedDataStream<T>(iterator: AsyncIterator<T
302
361
 
303
362
  declare function tryDecodeURIComponent(value: string): string;
304
363
 
305
- export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, defer, findDeepMatches, get, getConstructor, getOpenTelemetryConfig, intercept, isAbortError, isDeepEqual, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, normalizeHttpPath, omit, onError, onFinish, onStart, onSuccess, once, override, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOpenTelemetryConfig, setSpanAttributeIfDefined, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorClass, toOtelException, toSpanAttributeValue, toStringOrBytes, traceAsyncIterator, traceReadableStream, tryDecodeURIComponent, tryOrUndefined, value, wrapAsyncIterator, wrapReadableStream };
306
- export type { AnyFunction, AsyncIdQueueCloseOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OnFinishState, OpenTelemetryConfig, OrderablePlugin, PromiseWithError, Public, ReadableStreamReadResult, Registry, RunWithSpanOptions, Segment, StartSpanOptions, ThrowableError, Value, WrapAsyncIteratorOptions, WrapReadableStreamOptions };
364
+ export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, consumeAsyncIterator, defer, findDeepMatches, get, getConstructor, getOpenTelemetryConfig, intercept, isAbortError, isCompressibleContentType, isDeepEqual, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOpenTelemetryConfig, setSpanAttributeIfDefined, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toOtelException, toSpanAttributeValue, toStringOrBytes, traceAsyncIterator, traceReadableStream, tryDecodeURIComponent, tryOrUndefined, value, wrapAsyncIterator, wrapReadableStream };
365
+ export type { AnyFunction, AsyncIdQueueCloseOptions, ConsumeAsyncIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OnFinishState, OpenTelemetryConfig, OrderablePlugin, PromiseWithError, Public, ReadableStreamReadResult, Registry, RunWithSpanOptions, Segment, StartSpanOptions, ThrowableError, Value, WrapAsyncIteratorOptions, WrapReadableStreamOptions };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { Promisable } from 'type-fest';
2
- export { IsEqual, PartialDeep, Promisable, Writable } from 'type-fest';
1
+ import { Arrayable, Promisable } from 'type-fest';
2
+ export { Arrayable, IsEqual, PartialDeep, Promisable, Writable } from 'type-fest';
3
3
  import { Tracer, TraceAPI, ContextAPI, PropagationAPI, SpanOptions, Context, Span, AttributeValue, Exception } from '@opentelemetry/api';
4
4
  import { AsyncIteratorClass } from '@standardserver/shared';
5
- export { AbortError, AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, sleep, stringifyJSON, toArray } from '@standardserver/shared';
5
+ export { AbortError, AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, sequential, sleep, stringifyJSON, toArray } from '@standardserver/shared';
6
6
 
7
7
  type MaybeOptionalOptions<TOptions> = object extends TOptions ? [options?: TOptions] : [options: TOptions];
8
8
  declare function resolveMaybeOptionalOptions<T>(rest: MaybeOptionalOptions<T>): T;
@@ -14,13 +14,13 @@ declare function splitInHalf<T>(arr: readonly T[]): [T[], T[]];
14
14
  *
15
15
  * Prefers the newer `.bytes` method when available as it more efficient but not widely supported yet.
16
16
  */
17
- declare function loadBytes(source: Pick<Blob, 'arrayBuffer' | 'bytes'>): Promise<Uint8Array<ArrayBuffer>>;
17
+ declare function loadBytes(source: Pick<Blob, 'arrayBuffer' | 'bytes'>): ReturnType<Blob['bytes']>;
18
18
  /**
19
19
  * Normalize text or binary-like inputs to either:
20
20
  * - the original string value, or
21
21
  * - a Uint8Array view over the source bytes.
22
22
  */
23
- declare function toStringOrBytes(source: string | ArrayBuffer | Blob | Exclude<ConstructorParameters<typeof Blob>[0], undefined>[0][] | Pick<Uint8Array<ArrayBuffer>, 'buffer' | 'byteOffset' | 'byteLength'>): Promise<string | Uint8Array<ArrayBuffer>>;
23
+ declare function toStringOrBytes(source: Arrayable<string | ArrayBuffer | Pick<Uint8Array<ArrayBuffer>, 'buffer' | 'byteOffset' | 'byteLength'>>): string | Awaited<ReturnType<Blob['bytes']>>;
24
24
 
25
25
  declare function isDeepEqual(a: unknown, b: unknown): boolean;
26
26
 
@@ -41,6 +41,7 @@ declare function normalizeHttpPath(path: string): `/${string}`;
41
41
  declare function mergeHttpPath(a: `/${string}`, b: `/${string}`): `/${string}`;
42
42
  declare function matchesHttpPathPrefix(url: `/${string}`, prefix: `/${string}`): boolean;
43
43
  declare function matchesHttpPath(url: `/${string}`, path: `/${string}`): boolean;
44
+ declare function isCompressibleContentType(contentType: string | null | undefined): boolean;
44
45
 
45
46
  /**
46
47
  * Compares two sequential IDs.
@@ -102,6 +103,30 @@ type OnFinishState<TResult, TError> = [error: TError, data: undefined, isSuccess
102
103
  declare function onFinish<T, TOptions extends {
103
104
  next: () => any;
104
105
  }, TRest extends any[]>(callback: NoInfer<(state: OnFinishState<Awaited<ReturnType<TOptions['next']>>, ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError>, options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
106
+ /**
107
+ * Creates a middleware or interceptor that invokes a callback when the returned async
108
+ * iterator object throws an error while being consumed.
109
+ *
110
+ * This does not replace the `onError`. `onError` only fires on the
111
+ * initial call (before the interceptor returns the iterator), whereas this
112
+ * callback only fires while consuming the iterator. Use both together to
113
+ * catch all possible errors.
114
+ */
115
+ declare function onAsyncIteratorObjectError<T, TOptions extends {
116
+ next: () => any;
117
+ }, TRest extends any[]>(callback: NoInfer<(error: ThrowableError | (ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError), options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
118
+ /**
119
+ * Creates an interceptor that invokes a callback when the returned readable
120
+ * stream errors while being consumed.
121
+ *
122
+ * This does not replace the `onError`. `onError` only fires on the
123
+ * initial call (before the interceptor returns the stream), whereas this
124
+ * callback only fires while consuming the stream. Use both together to catch
125
+ * all possible errors.
126
+ */
127
+ declare function onReadableStreamError<T, TOptions extends {
128
+ next: () => any;
129
+ }, TRest extends any[]>(callback: NoInfer<(error: ThrowableError | (ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError), options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
105
130
  declare function intercept<TOptions extends InterceptableOptions, TResult>(interceptors: undefined | Interceptor<TOptions, TResult>[], options: NoInfer<TOptions>, main: NoInfer<(options: TOptions) => TResult>): TResult;
106
131
 
107
132
  /**
@@ -147,8 +172,8 @@ interface WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>
147
172
  */
148
173
  runWith?: <T>(run: () => Promise<T>) => Promise<T>;
149
174
  mapResult?: (result: IteratorResult<TYield, TReturn>) => Promisable<IteratorResult<TMappedYield, TMappedReturn>>;
150
- mapError?: (error: unknown) => Promisable<unknown>;
151
- onError?: (error: unknown) => Promisable<void>;
175
+ mapError?: (error: ThrowableError) => Promisable<ThrowableError>;
176
+ onError?: (error: ThrowableError) => Promisable<void>;
152
177
  /**
153
178
  * Execute after the stream finishes or is cancelled.
154
179
  */
@@ -157,6 +182,35 @@ interface WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>
157
182
  declare function wrapAsyncIterator<TYield, TReturn, TMappedYield = TYield, TMappedReturn = TReturn>(iterator: AsyncIterator<TYield, TReturn>, { runWith, mapResult, mapError, onError, onFinish }: WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>): NoInfer<AsyncIteratorClass<TMappedYield, TMappedReturn>>;
158
183
  declare function traceAsyncIterator<T, TReturn, TNext>(options: StartSpanOptions | string, iterator: AsyncIterator<T, TReturn, TNext>): AsyncIteratorClass<T, TReturn, TNext>;
159
184
  declare function replicateAsyncIterator<T, TReturn, TNext>(source: AsyncIterator<T, TReturn, TNext>, count: number): (AsyncIteratorClass<T, TReturn, TNext>)[];
185
+ interface ConsumeAsyncIteratorOptions<T, TReturn, TError> {
186
+ /**
187
+ * Called on each event
188
+ */
189
+ onEvent: (event: T) => void;
190
+ /**
191
+ * Called once error happens
192
+ */
193
+ onError?: (error: TError) => void;
194
+ /**
195
+ * Called once AsyncIteratorObject is done
196
+ *
197
+ * @info If iterator is canceled, `undefined` can be passed on success
198
+ */
199
+ onSuccess?: (value: TReturn | undefined) => void;
200
+ /**
201
+ * Called once after onError or onSuccess
202
+ *
203
+ * @info If iterator is canceled, `undefined` can be passed on success
204
+ */
205
+ onFinish?: (state: [error: TError, data: undefined, isSuccess: false] | [error: null, data: TReturn | undefined, isSuccess: true]) => void;
206
+ }
207
+ /**
208
+ * Consumes an AsyncIteratorObject with lifecycle callbacks
209
+ *
210
+ * @warning If no `onError` or `onFinish` is provided, error will be thrown into unhandled rejection channel.
211
+ * @return unsubscribe callback
212
+ */
213
+ declare function consumeAsyncIterator<T, TReturn, TError = ThrowableError>(iterator: AsyncIterator<T, TReturn> | PromiseWithError<AsyncIterator<T, TReturn>, TError>, options: ConsumeAsyncIteratorOptions<T, TReturn, TError | ThrowableError>): () => Promise<void>;
160
214
 
161
215
  type Segment = string | number;
162
216
  declare function findDeepMatches(check: (value: unknown) => boolean, payload: unknown, segments?: Segment[], maps?: Segment[][], values?: unknown[]): {
@@ -257,6 +311,11 @@ declare class AsyncIdQueue<T> {
257
311
  * Returns a signal that aborts only after all provided signals are aborted.
258
312
  */
259
313
  declare function allAbortSignal(signals: readonly (AbortSignal | undefined)[]): AbortSignal | undefined;
314
+ /**
315
+ * Returns a signal that aborts as soon as any of the provided signals aborts,
316
+ * with the same abort reason.
317
+ */
318
+ declare function anyAbortSignal(signals: readonly (AbortSignal | undefined)[]): AbortSignal | undefined;
260
319
  declare function runWithSignal<T>(signal: AbortSignal | undefined, fn: () => Promise<T>): Promise<T>;
261
320
 
262
321
  declare function replicateReadableStream<T>(stream: ReadableStream<T>, count: number): ReadableStream<T>[];
@@ -265,7 +324,7 @@ type ReadableStreamReadResult<T> = {
265
324
  value: T;
266
325
  } | {
267
326
  done: true;
268
- value: undefined | T;
327
+ value?: undefined | T;
269
328
  };
270
329
  interface WrapReadableStreamOptions<T, TMapped> {
271
330
  /**
@@ -275,8 +334,8 @@ interface WrapReadableStreamOptions<T, TMapped> {
275
334
  */
276
335
  runWith?: <T>(run: () => Promise<T>) => Promise<T>;
277
336
  mapResult?: (result: ReadableStreamReadResult<T>) => Promisable<ReadableStreamReadResult<TMapped>>;
278
- mapError?: (error: unknown) => Promisable<unknown>;
279
- onError?: (error: unknown) => Promisable<void>;
337
+ mapError?: (error: ThrowableError) => Promisable<ThrowableError>;
338
+ onError?: (error: ThrowableError) => Promisable<void>;
280
339
  /**
281
340
  * Guaranteed to execute exactly once after the stream finishes or is cancelled.
282
341
  */
@@ -285,9 +344,9 @@ interface WrapReadableStreamOptions<T, TMapped> {
285
344
  declare function wrapReadableStream<T, TMapped = T>(stream: ReadableStream<T>, { runWith, mapResult, mapError, onError, onFinish }: WrapReadableStreamOptions<T, TMapped>): NoInfer<ReadableStream<TMapped>>;
286
345
  declare function traceReadableStream<T>(options: StartSpanOptions | string, stream: ReadableStream<T>): ReadableStream<T>;
287
346
  /**
288
- * Converts a `ReadableStream` into an `AsyncIteratorClass`.
347
+ * Converts a {@link ReadableStream} into an {@link AsyncIteratorClass}.
289
348
  */
290
- declare function streamToAsyncIteratorClass<T>(stream: ReadableStream<T>, { signal }?: {
349
+ declare function streamToAsyncIteratorObject<T>(stream: ReadableStream<T>, { signal }?: {
291
350
  signal?: undefined | AbortSignal;
292
351
  }): AsyncIteratorClass<T>;
293
352
  /**
@@ -302,5 +361,5 @@ declare function asyncIteratorToUnproxiedDataStream<T>(iterator: AsyncIterator<T
302
361
 
303
362
  declare function tryDecodeURIComponent(value: string): string;
304
363
 
305
- export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, defer, findDeepMatches, get, getConstructor, getOpenTelemetryConfig, intercept, isAbortError, isDeepEqual, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, normalizeHttpPath, omit, onError, onFinish, onStart, onSuccess, once, override, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOpenTelemetryConfig, setSpanAttributeIfDefined, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorClass, toOtelException, toSpanAttributeValue, toStringOrBytes, traceAsyncIterator, traceReadableStream, tryDecodeURIComponent, tryOrUndefined, value, wrapAsyncIterator, wrapReadableStream };
306
- export type { AnyFunction, AsyncIdQueueCloseOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OnFinishState, OpenTelemetryConfig, OrderablePlugin, PromiseWithError, Public, ReadableStreamReadResult, Registry, RunWithSpanOptions, Segment, StartSpanOptions, ThrowableError, Value, WrapAsyncIteratorOptions, WrapReadableStreamOptions };
364
+ export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, consumeAsyncIterator, defer, findDeepMatches, get, getConstructor, getOpenTelemetryConfig, intercept, isAbortError, isCompressibleContentType, isDeepEqual, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOpenTelemetryConfig, setSpanAttributeIfDefined, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toOtelException, toSpanAttributeValue, toStringOrBytes, traceAsyncIterator, traceReadableStream, tryDecodeURIComponent, tryOrUndefined, value, wrapAsyncIterator, wrapReadableStream };
365
+ export type { AnyFunction, AsyncIdQueueCloseOptions, ConsumeAsyncIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OnFinishState, OpenTelemetryConfig, OrderablePlugin, PromiseWithError, Public, ReadableStreamReadResult, Registry, RunWithSpanOptions, Segment, StartSpanOptions, ThrowableError, Value, WrapAsyncIteratorOptions, WrapReadableStreamOptions };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { AbortError, AsyncIteratorClass, isTypescriptObject, getOrBind } from '@standardserver/shared';
2
- export { AbortError, AsyncIteratorClass, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, sleep, stringifyJSON, toArray } from '@standardserver/shared';
1
+ import { AbortError, AsyncIteratorClass, getOrBind, isTypescriptObject, isAsyncIteratorObject } from '@standardserver/shared';
2
+ export { AbortError, AsyncIteratorClass, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, sequential, sleep, stringifyJSON, toArray } from '@standardserver/shared';
3
3
 
4
4
  function resolveMaybeOptionalOptions(rest) {
5
5
  return rest[0] ?? {};
@@ -16,24 +16,44 @@ async function loadBytes(source) {
16
16
  }
17
17
  return new Uint8Array(await source.arrayBuffer());
18
18
  }
19
- async function toStringOrBytes(source) {
19
+ function toStringOrBytes(source) {
20
20
  if (typeof source === "string") {
21
21
  return source;
22
22
  }
23
23
  if (source instanceof ArrayBuffer) {
24
24
  return new Uint8Array(source);
25
25
  }
26
- if (source instanceof Blob) {
27
- return loadBytes(source);
28
- }
29
26
  if (Array.isArray(source)) {
30
- return loadBytes(new Blob(source));
27
+ return concatBytes(source);
31
28
  }
32
29
  if (source instanceof Uint8Array) {
33
30
  return source;
34
31
  }
35
32
  return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
36
33
  }
34
+ function toBytes(item) {
35
+ if (typeof item === "string") {
36
+ return new TextEncoder().encode(item);
37
+ }
38
+ if (item instanceof ArrayBuffer) {
39
+ return new Uint8Array(item);
40
+ }
41
+ if (item instanceof Uint8Array) {
42
+ return item;
43
+ }
44
+ return new Uint8Array(item.buffer, item.byteOffset, item.byteLength);
45
+ }
46
+ function concatBytes(items) {
47
+ const chunks = items.map(toBytes);
48
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
49
+ const result = new Uint8Array(totalLength);
50
+ let offset = 0;
51
+ for (const chunk of chunks) {
52
+ result.set(chunk, offset);
53
+ offset += chunk.byteLength;
54
+ }
55
+ return result;
56
+ }
37
57
 
38
58
  function isDeepEqual(a, b) {
39
59
  return isDeepEqualInternal(a, b, /* @__PURE__ */ new WeakMap());
@@ -156,6 +176,17 @@ function matchesHttpPath(url, path) {
156
176
  }
157
177
  return charAfterPrefix === void 0 || charAfterPrefix === "?" || charAfterPrefix === "#";
158
178
  }
179
+ const COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
180
+ const MAX_COMPRESSIBLE_CONTENT_TYPE_LENGTH = 1024;
181
+ function isCompressibleContentType(contentType) {
182
+ if (contentType === null || contentType === void 0) {
183
+ return false;
184
+ }
185
+ if (contentType.length > MAX_COMPRESSIBLE_CONTENT_TYPE_LENGTH) {
186
+ return false;
187
+ }
188
+ return COMPRESSIBLE_CONTENT_TYPE_REGEX.test(contentType);
189
+ }
159
190
 
160
191
  function compareSequentialIds(a, b) {
161
192
  if (a.length !== b.length) {
@@ -164,61 +195,6 @@ function compareSequentialIds(a, b) {
164
195
  return a < b ? -1 : a > b ? 1 : 0;
165
196
  }
166
197
 
167
- function onStart(callback) {
168
- return async (options, ...rest) => {
169
- await callback(options, ...rest);
170
- return await options.next();
171
- };
172
- }
173
- function onSuccess(callback) {
174
- return async (options, ...rest) => {
175
- const result = await options.next();
176
- await callback(result, options, ...rest);
177
- return result;
178
- };
179
- }
180
- function onError(callback) {
181
- return async (options, ...rest) => {
182
- try {
183
- return await options.next();
184
- } catch (error) {
185
- await callback(error, options, ...rest);
186
- throw error;
187
- }
188
- };
189
- }
190
- function onFinish(callback) {
191
- let state;
192
- return async (options, ...rest) => {
193
- try {
194
- const result = await options.next();
195
- state = [null, result, true];
196
- return result;
197
- } catch (error) {
198
- state = [error, void 0, false];
199
- throw error;
200
- } finally {
201
- await callback(state, options, ...rest);
202
- }
203
- };
204
- }
205
- function intercept(interceptors, options, main) {
206
- if (!interceptors?.length) {
207
- return main(options);
208
- }
209
- const next = (options2, index) => {
210
- const interceptor = interceptors[index];
211
- if (!interceptor) {
212
- return main(options2);
213
- }
214
- return interceptor({
215
- ...options2,
216
- next: (newOptions = options2) => next(newOptions, index + 1)
217
- });
218
- };
219
- return next(options, 0);
220
- }
221
-
222
198
  const SPAN_ERROR_STATUS = 2;
223
199
  const OPENTELEMETRY_CONFIG_SYMBOL = Symbol.for("ORPC_OPENTELEMETRY_CONFIG");
224
200
  function setOpenTelemetryConfig(config) {
@@ -491,6 +467,52 @@ function replicateAsyncIterator(source, count) {
491
467
  });
492
468
  return replicated;
493
469
  }
470
+ function consumeAsyncIterator(iterator, options) {
471
+ void (async () => {
472
+ let onFinishState;
473
+ try {
474
+ const resolvedIterator = await iterator;
475
+ while (true) {
476
+ const { done, value } = await resolvedIterator.next();
477
+ if (done) {
478
+ const realValue = value;
479
+ onFinishState = [null, realValue, true];
480
+ options.onSuccess?.(realValue);
481
+ break;
482
+ }
483
+ options.onEvent(value);
484
+ }
485
+ } catch (error) {
486
+ onFinishState = [error, void 0, false];
487
+ options.onError?.(error);
488
+ } finally {
489
+ options.onFinish?.(onFinishState);
490
+ }
491
+ })();
492
+ return async () => {
493
+ await (await iterator)?.return?.();
494
+ };
495
+ }
496
+
497
+ function value(value2, ...args) {
498
+ if (typeof value2 === "function") {
499
+ return value2(...args);
500
+ }
501
+ return value2;
502
+ }
503
+
504
+ function override(target, partial) {
505
+ const proxy = new Proxy(typeof target === "function" ? partial : target, {
506
+ get(_, prop) {
507
+ const targetValue = prop in partial ? partial : value(target);
508
+ return getOrBind(targetValue, prop);
509
+ },
510
+ has(_, prop) {
511
+ return Reflect.has(partial, prop) || Reflect.has(value(target), prop);
512
+ }
513
+ });
514
+ return proxy;
515
+ }
494
516
 
495
517
  function findDeepMatches(check, payload, segments = [], maps = [], values = []) {
496
518
  if (check(payload)) {
@@ -603,84 +625,6 @@ function bindMethods(obj) {
603
625
  return methods;
604
626
  }
605
627
 
606
- function sortPlugins(plugins) {
607
- const pluginCount = plugins.length;
608
- const pluginIdToIndices = /* @__PURE__ */ new Map();
609
- for (let i = 0; i < pluginCount; i++) {
610
- const plugin = plugins[i];
611
- const indices = pluginIdToIndices.get(plugin.name);
612
- if (indices === void 0) {
613
- pluginIdToIndices.set(plugin.name, [i]);
614
- } else {
615
- indices.push(i);
616
- }
617
- }
618
- const graph = Array.from(
619
- { length: pluginCount },
620
- () => /* @__PURE__ */ new Set()
621
- );
622
- for (let i = 0; i < pluginCount; i++) {
623
- const plugin = plugins[i];
624
- const beforeList = plugin.before;
625
- if (beforeList !== void 0) {
626
- for (const beforeId of beforeList) {
627
- const beforeIndices = pluginIdToIndices.get(beforeId);
628
- if (beforeIndices === void 0)
629
- continue;
630
- for (const beforeIndex of beforeIndices) {
631
- const beforeGraph = graph[beforeIndex];
632
- if (beforeGraph !== void 0) {
633
- beforeGraph.add(i);
634
- }
635
- }
636
- }
637
- }
638
- const afterList = plugin.after;
639
- if (afterList !== void 0) {
640
- const currentGraph = graph[i];
641
- if (currentGraph !== void 0) {
642
- for (const afterId of afterList) {
643
- const afterIndices = pluginIdToIndices.get(afterId);
644
- if (afterIndices === void 0)
645
- continue;
646
- for (const afterIndex of afterIndices) {
647
- currentGraph.add(afterIndex);
648
- }
649
- }
650
- }
651
- }
652
- }
653
- const sorted = [];
654
- const visiting = /* @__PURE__ */ new Set();
655
- const visited = /* @__PURE__ */ new Set();
656
- function visit(index) {
657
- if (visited.has(index))
658
- return;
659
- if (visiting.has(index)) {
660
- const plugin2 = plugins[index];
661
- const pluginId = plugin2 !== void 0 ? plugin2.name : "unknown";
662
- throw new Error(`Circular dependency detected involving plugin "${pluginId}"`);
663
- }
664
- visiting.add(index);
665
- const deps = graph[index];
666
- if (deps !== void 0) {
667
- for (const depIndex of deps) {
668
- visit(depIndex);
669
- }
670
- }
671
- visiting.delete(index);
672
- visited.add(index);
673
- const plugin = plugins[index];
674
- if (plugin !== void 0) {
675
- sorted.push(plugin);
676
- }
677
- }
678
- for (let i = 0; i < pluginCount; i++) {
679
- visit(i);
680
- }
681
- return sorted;
682
- }
683
-
684
628
  function promiseWithResolvers() {
685
629
  const result = {};
686
630
  result.promise = new Promise((resolve, reject) => {
@@ -690,69 +634,6 @@ function promiseWithResolvers() {
690
634
  return result;
691
635
  }
692
636
 
693
- function value(value2, ...args) {
694
- if (typeof value2 === "function") {
695
- return value2(...args);
696
- }
697
- return value2;
698
- }
699
-
700
- function override(target, partial) {
701
- const proxy = new Proxy(typeof target === "function" ? partial : target, {
702
- get(_, prop) {
703
- const targetValue = prop in partial ? partial : value(target);
704
- return getOrBind(targetValue, prop);
705
- },
706
- has(_, prop) {
707
- return Reflect.has(partial, prop) || Reflect.has(value(target), prop);
708
- }
709
- });
710
- return proxy;
711
- }
712
-
713
- function allAbortSignal(signals) {
714
- const realSignals = signals.filter((signal) => signal !== void 0);
715
- if (realSignals.length === 0 || realSignals.length !== signals.length) {
716
- return void 0;
717
- }
718
- const controller = new AbortController();
719
- const abortIfAllAborted = () => {
720
- if (realSignals.every((signal) => signal.aborted)) {
721
- controller.abort();
722
- }
723
- };
724
- abortIfAllAborted();
725
- for (const signal of realSignals) {
726
- signal.addEventListener("abort", () => {
727
- abortIfAllAborted();
728
- }, {
729
- once: true,
730
- signal: controller.signal
731
- });
732
- }
733
- return controller.signal;
734
- }
735
- async function runWithSignal(signal, fn) {
736
- if (!signal) {
737
- return fn();
738
- }
739
- signal.throwIfAborted();
740
- const { promise, reject, resolve } = promiseWithResolvers();
741
- let abortListener;
742
- signal.addEventListener("abort", abortListener = () => {
743
- reject(signal.reason);
744
- abortListener = void 0;
745
- });
746
- try {
747
- fn().then(resolve, reject);
748
- return await promise;
749
- } finally {
750
- if (abortListener) {
751
- signal.removeEventListener("abort", abortListener);
752
- }
753
- }
754
- }
755
-
756
637
  function replicateReadableStream(stream, count) {
757
638
  if (count <= 0) {
758
639
  return [];
@@ -823,7 +704,7 @@ function traceReadableStream(options, stream) {
823
704
  }
824
705
  });
825
706
  }
826
- function streamToAsyncIteratorClass(stream, { signal } = {}) {
707
+ function streamToAsyncIteratorObject(stream, { signal } = {}) {
827
708
  const reader = stream.getReader();
828
709
  let cancelledBySignal = false;
829
710
  return new AsyncIteratorClass(
@@ -889,4 +770,228 @@ function asyncIteratorToUnproxiedDataStream(iterator) {
889
770
  });
890
771
  }
891
772
 
892
- export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, defer, findDeepMatches, get, getConstructor, getOpenTelemetryConfig, intercept, isAbortError, isDeepEqual, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, normalizeHttpPath, omit, onError, onFinish, onStart, onSuccess, once, override, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOpenTelemetryConfig, setSpanAttributeIfDefined, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorClass, toOtelException, toSpanAttributeValue, toStringOrBytes, traceAsyncIterator, traceReadableStream, tryDecodeURIComponent, tryOrUndefined, value, wrapAsyncIterator, wrapReadableStream };
773
+ function onStart(callback) {
774
+ return async (options, ...rest) => {
775
+ await callback(options, ...rest);
776
+ return await options.next();
777
+ };
778
+ }
779
+ function onSuccess(callback) {
780
+ return async (options, ...rest) => {
781
+ const result = await options.next();
782
+ await callback(result, options, ...rest);
783
+ return result;
784
+ };
785
+ }
786
+ function onError(callback) {
787
+ return async (options, ...rest) => {
788
+ try {
789
+ return await options.next();
790
+ } catch (error) {
791
+ await callback(error, options, ...rest);
792
+ throw error;
793
+ }
794
+ };
795
+ }
796
+ function onFinish(callback) {
797
+ let state;
798
+ return async (options, ...rest) => {
799
+ try {
800
+ const result = await options.next();
801
+ state = [null, result, true];
802
+ return result;
803
+ } catch (error) {
804
+ state = [error, void 0, false];
805
+ throw error;
806
+ } finally {
807
+ await callback(state, options, ...rest);
808
+ }
809
+ };
810
+ }
811
+ function onAsyncIteratorObjectError(callback) {
812
+ return async (options, ...rest) => {
813
+ const output = await options.next();
814
+ if (!isAsyncIteratorObject(output)) {
815
+ return output;
816
+ }
817
+ return override(output, wrapAsyncIterator(output, {
818
+ onError: (error) => callback(error, options, ...rest)
819
+ }));
820
+ };
821
+ }
822
+ function onReadableStreamError(callback) {
823
+ return async (options, ...rest) => {
824
+ const output = await options.next();
825
+ if (!(output instanceof ReadableStream)) {
826
+ return output;
827
+ }
828
+ return override(output, wrapReadableStream(output, {
829
+ onError: (error) => callback(error, options, ...rest)
830
+ }));
831
+ };
832
+ }
833
+ function intercept(interceptors, options, main) {
834
+ if (!interceptors?.length) {
835
+ return main(options);
836
+ }
837
+ const next = (options2, index) => {
838
+ const interceptor = interceptors[index];
839
+ if (!interceptor) {
840
+ return main(options2);
841
+ }
842
+ return interceptor({
843
+ ...options2,
844
+ next: (newOptions = options2) => next(newOptions, index + 1)
845
+ });
846
+ };
847
+ return next(options, 0);
848
+ }
849
+
850
+ function sortPlugins(plugins) {
851
+ const pluginCount = plugins.length;
852
+ const pluginIdToIndices = /* @__PURE__ */ new Map();
853
+ for (let i = 0; i < pluginCount; i++) {
854
+ const plugin = plugins[i];
855
+ const indices = pluginIdToIndices.get(plugin.name);
856
+ if (indices === void 0) {
857
+ pluginIdToIndices.set(plugin.name, [i]);
858
+ } else {
859
+ indices.push(i);
860
+ }
861
+ }
862
+ const graph = Array.from(
863
+ { length: pluginCount },
864
+ () => /* @__PURE__ */ new Set()
865
+ );
866
+ for (let i = 0; i < pluginCount; i++) {
867
+ const plugin = plugins[i];
868
+ const beforeList = plugin.before;
869
+ if (beforeList !== void 0) {
870
+ for (const beforeId of beforeList) {
871
+ const beforeIndices = pluginIdToIndices.get(beforeId);
872
+ if (beforeIndices === void 0)
873
+ continue;
874
+ for (const beforeIndex of beforeIndices) {
875
+ const beforeGraph = graph[beforeIndex];
876
+ if (beforeGraph !== void 0) {
877
+ beforeGraph.add(i);
878
+ }
879
+ }
880
+ }
881
+ }
882
+ const afterList = plugin.after;
883
+ if (afterList !== void 0) {
884
+ const currentGraph = graph[i];
885
+ if (currentGraph !== void 0) {
886
+ for (const afterId of afterList) {
887
+ const afterIndices = pluginIdToIndices.get(afterId);
888
+ if (afterIndices === void 0)
889
+ continue;
890
+ for (const afterIndex of afterIndices) {
891
+ currentGraph.add(afterIndex);
892
+ }
893
+ }
894
+ }
895
+ }
896
+ }
897
+ const sorted = [];
898
+ const visiting = /* @__PURE__ */ new Set();
899
+ const visited = /* @__PURE__ */ new Set();
900
+ function visit(index) {
901
+ if (visited.has(index))
902
+ return;
903
+ if (visiting.has(index)) {
904
+ const plugin2 = plugins[index];
905
+ const pluginId = plugin2 !== void 0 ? plugin2.name : "unknown";
906
+ throw new Error(`Circular dependency detected involving plugin "${pluginId}"`);
907
+ }
908
+ visiting.add(index);
909
+ const deps = graph[index];
910
+ if (deps !== void 0) {
911
+ for (const depIndex of deps) {
912
+ visit(depIndex);
913
+ }
914
+ }
915
+ visiting.delete(index);
916
+ visited.add(index);
917
+ const plugin = plugins[index];
918
+ if (plugin !== void 0) {
919
+ sorted.push(plugin);
920
+ }
921
+ }
922
+ for (let i = 0; i < pluginCount; i++) {
923
+ visit(i);
924
+ }
925
+ return sorted;
926
+ }
927
+
928
+ function allAbortSignal(signals) {
929
+ const realSignals = signals.filter((signal) => signal !== void 0);
930
+ if (realSignals.length === 0 || realSignals.length !== signals.length) {
931
+ return void 0;
932
+ }
933
+ const controller = new AbortController();
934
+ const abortIfAllAborted = () => {
935
+ if (realSignals.every((signal) => signal.aborted)) {
936
+ controller.abort();
937
+ }
938
+ };
939
+ abortIfAllAborted();
940
+ for (const signal of realSignals) {
941
+ signal.addEventListener("abort", () => {
942
+ abortIfAllAborted();
943
+ }, {
944
+ once: true,
945
+ signal: controller.signal
946
+ });
947
+ }
948
+ return controller.signal;
949
+ }
950
+ function anyAbortSignal(signals) {
951
+ const realSignals = signals.filter((signal) => signal !== void 0);
952
+ if (realSignals.length === 0) {
953
+ return void 0;
954
+ }
955
+ if (realSignals.length === 1) {
956
+ return realSignals[0];
957
+ }
958
+ if (typeof AbortSignal.any === "function") {
959
+ return AbortSignal.any(realSignals);
960
+ }
961
+ const controller = new AbortController();
962
+ for (const signal of realSignals) {
963
+ if (signal.aborted) {
964
+ controller.abort(signal.reason);
965
+ break;
966
+ }
967
+ signal.addEventListener("abort", () => {
968
+ controller.abort(signal.reason);
969
+ }, {
970
+ once: true,
971
+ signal: controller.signal
972
+ });
973
+ }
974
+ return controller.signal;
975
+ }
976
+ async function runWithSignal(signal, fn) {
977
+ if (!signal) {
978
+ return fn();
979
+ }
980
+ signal.throwIfAborted();
981
+ const { promise, reject, resolve } = promiseWithResolvers();
982
+ let abortListener;
983
+ signal.addEventListener("abort", abortListener = () => {
984
+ reject(signal.reason);
985
+ abortListener = void 0;
986
+ });
987
+ try {
988
+ fn().then(resolve, reject);
989
+ return await promise;
990
+ } finally {
991
+ if (abortListener) {
992
+ signal.removeEventListener("abort", abortListener);
993
+ }
994
+ }
995
+ }
996
+
997
+ export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, consumeAsyncIterator, defer, findDeepMatches, get, getConstructor, getOpenTelemetryConfig, intercept, isAbortError, isCompressibleContentType, isDeepEqual, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOpenTelemetryConfig, setSpanAttributeIfDefined, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toOtelException, toSpanAttributeValue, toStringOrBytes, traceAsyncIterator, traceReadableStream, tryDecodeURIComponent, tryOrUndefined, value, wrapAsyncIterator, wrapReadableStream };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/shared",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.2",
4
+ "version": "2.0.0-beta.20",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.dev",
7
7
  "repository": {
@@ -33,14 +33,14 @@
33
33
  }
34
34
  },
35
35
  "dependencies": {
36
- "@standardserver/shared": "^0.0.25",
36
+ "@standardserver/shared": "^0.5.0",
37
37
  "radash": "^12.1.1",
38
38
  "type-fest": "^5.3.1"
39
39
  },
40
40
  "devDependencies": {
41
- "@opentelemetry/api": "^1.9.0",
42
- "arktype": "^2.1.29",
43
- "valibot": "^1.2.0",
41
+ "@opentelemetry/api": "^1.9.1",
42
+ "arktype": "^2.2.1",
43
+ "valibot": "^1.4.1",
44
44
  "zod": "^4.4.3"
45
45
  },
46
46
  "scripts": {