@orpc/shared 2.0.0-beta.40 → 2.0.0-beta.41

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
@@ -85,7 +85,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
85
85
 
86
86
  <table>
87
87
  <tr>
88
- <td width="2000"><a href="https://screenshotone.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener" title="The screenshot API for developers"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="64" align="left" hspace="12" alt="ScreenshotOne.com"/><b>ScreenshotOne.com</b></a><br /><sub>The screenshot API for developers</sub></td>
88
+ <td width="2000"><a href="https://screenshotone.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="The screenshot API for developers"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="64" align="left" hspace="12" alt="ScreenshotOne.com"/><b>ScreenshotOne.com</b></a><br /><sub>The screenshot API for developers</sub></td>
89
89
  </tr>
90
90
  <tr>
91
91
  <td width="2000"><a href="https://yuzu.health/careers?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="We&#39;re hiring NYC based engineers"><img src="https://avatars.githubusercontent.com/u/102488956?v=4" width="64" align="left" hspace="12" alt="Yuzu"/><b>Yuzu</b></a><br /><sub>We&#39;re hiring NYC based engineers</sub></td>
@@ -127,19 +127,18 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
127
127
  <td align="center"><a href="https://soymilk.party/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&amp;v=4" width="139" alt="あわわわとーにゅ"/><br />あわわわとーにゅ</a></td>
128
128
  <td align="center"><a href="https://github.com/nicognaW?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&amp;v=4" width="139" alt="nk"/><br />nk</a></td>
129
129
  <td align="center"><a href="https://supastarter.dev/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="139" alt="supastarter"/><br />supastarter</a></td>
130
- <td align="center"><a href="https://github.com/divmgl?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&amp;v=4" width="139" alt="Dexter Miguel"/><br />Dexter Miguel</a></td>
131
130
  <td align="center"><a href="https://github.com/herrfugbaum?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&amp;v=4" width="139" alt="herrfugbaum"/><br />herrfugbaum</a></td>
131
+ <td align="center"><a href="https://laststance.io/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&amp;v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td>
132
132
  </tr>
133
133
  <tr>
134
- <td align="center"><a href="https://laststance.io/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&amp;v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td>
135
134
  <td align="center"><a href="https://cra.mr/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="139" alt="David Cramer"/><br />David Cramer</a></td>
136
135
  <td align="center"><a href="https://valerii15298.github.io/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" 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>
137
136
  <td align="center"><a href="https://letstri.dev/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" 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>
138
137
  <td align="center"><a href="https://blacklight.sh/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" 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>
139
138
  <td align="center"><a href="https://github.com/christ12938?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
139
+ <td align="center"><a href="https://github.com/Ryanjso?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" 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>
140
140
  </tr>
141
141
  <tr>
142
- <td align="center"><a href="https://github.com/Ryanjso?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" 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>
143
142
  <td align="center"><a href="https://github.com/itigoore01?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&amp;v=4" width="139" alt="shota"/><br />shota</a></td>
144
143
  <td align="center"><a href="https://github.com/ellis-driscoll?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&amp;v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td>
145
144
  <td align="center"><a href="https://github.com/hoangbn?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Hoang Nguyen"><img src="https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&amp;v=4" width="139" alt="Hoang Nguyen"/><br />Hoang Nguyen</a></td>
@@ -173,12 +172,13 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
173
172
  <td align="center"><a href="https://kellychan.im/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" 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>
174
173
  <td align="center"><a href="https://guyariely.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&amp;v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td>
175
174
  <td align="center"><a href="https://paulsenon.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="PaulSenon"><img src="https://avatars.githubusercontent.com/u/19531087?u=6385741eb91d200b8c513ec6045482e301767ca6&amp;v=4" width="119" alt="PaulSenon"/><br />PaulSenon</a></td>
175
+ <td align="center"><a href="https://nakasyou.how/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Shotaro Nakamura"><img src="https://avatars.githubusercontent.com/u/79000684?u=f644df3f29f0e8677a90967115774564f1d9d6ab&amp;v=4" width="119" alt="Shotaro Nakamura"/><br />Shotaro Nakamura</a></td>
176
176
  <td align="center"><a href="https://piscis.dev/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&amp;v=4" width="119" alt="Alex"/><br />Alex</a></td>
177
177
  <td align="center"><a href="https://opensource.gubanov.eu/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&amp;v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
178
178
  </tr>
179
179
  </table>
180
180
 
181
- With thanks to [36 past sponsors](https://htmlpreview.github.io/?https://github.com/middleapi/static/blob/main/sponsors.svg) who helped get oRPC here.
181
+ With thanks to [38 past sponsors](https://orpc.dev/sponsors#past-sponsors) who helped get oRPC here.
182
182
 
183
183
  ## References
184
184
 
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Arrayable, Promisable } from 'type-fest';
2
2
  export { Arrayable, IsEqual, PartialDeep, Promisable, Writable } from 'type-fest';
3
3
  import { AsyncIteratorClass } from '@standard-server/shared';
4
- export { AbortError, AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, safeDecodeURIComponent, safeEncodeURIComponent, sequential, sleep, stringifyJSON, toArray } from '@standard-server/shared';
4
+ export { AbortError, AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, safeDecodeURIComponent, safeEncodeURIComponent, sequential, sleep, stringifyJSON, throwIfAborted, toArray } from '@standard-server/shared';
5
5
 
6
6
  type MaybeOptionalOptions<TOptions> = object extends TOptions ? [options?: TOptions] : [options: TOptions];
7
7
  declare function resolveMaybeOptionalOptions<T>(rest: MaybeOptionalOptions<T>): T;
@@ -34,9 +34,10 @@ type AnyFunction = (...args: any[]) => any;
34
34
  declare function isAsyncGeneratorFunction(value: unknown): value is (...args: any[]) => AsyncGenerator;
35
35
  declare function once<T>(fn: () => T): () => T;
36
36
  /**
37
- * Executes the callback function after the current call stack has been cleared.
37
+ * Executes the callback function after the current call stack has been cleared,
38
+ * waiting at least `delay` ms when `setTimeout` is available.
38
39
  */
39
- declare function defer(callback: () => void): void;
40
+ declare function defer(callback: () => void, delay?: number): void;
40
41
  declare function tryOrUndefined<T>(fn: () => T): undefined | T;
41
42
 
42
43
  declare function pathToHttpPath(path: readonly string[]): `/${string}`;
@@ -46,12 +47,19 @@ declare function matchesHttpPathPrefix(url: `/${string}`, prefix: `/${string}`):
46
47
  declare function matchesHttpPath(url: `/${string}`, path: `/${string}`): boolean;
47
48
  /**
48
49
  * Parse Accept-Encoding into each coding's q-value, where `0` means the coding is explicitly
49
- * unacceptable. The `*` wildcard is kept under its own key, so a caller can honour it while
50
- * still letting a specific coding take precedence over it.
50
+ * unacceptable. The `*` wildcard is kept under its own key; use {@link isAcceptableEncoding}
51
+ * to decide whether a coding is acceptable.
51
52
  *
52
53
  * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding
53
54
  */
54
55
  declare function parseAcceptEncodingQualities(header: string | undefined): Map<string, number>;
56
+ /**
57
+ * Whether the client accepts a coding, given qualities from {@link parseAcceptEncodingQualities}.
58
+ * An explicit q-value takes precedence over the `*` wildcard, so `gzip;q=0, *` never accepts gzip.
59
+ *
60
+ * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding
61
+ */
62
+ declare function isAcceptableEncoding(qualities: Map<string, number>, coding: string): boolean;
55
63
  /**
56
64
  * Add `accept-encoding` to a Vary header value. The encoding is chosen from the request, so a
57
65
  * shared cache must key on it or it will hand a compressed body to a client that cannot decode it.
@@ -72,6 +80,12 @@ declare function isCompressibleContentType(contentType: string | null | undefine
72
80
  declare function compareSequentialIds(a: string, b: string): number;
73
81
 
74
82
  type IntersectPick<T, U> = Pick<T, keyof T & keyof U>;
83
+ /**
84
+ * Like `Omit`, but distributes over unions and keeps known keys beside index signatures.
85
+ */
86
+ type DistributiveOmit<T, K extends PropertyKey> = {
87
+ [P in keyof T as P extends K ? never : P]: T[P];
88
+ };
75
89
  /**
76
90
  * Remove protected/private properties/methods
77
91
  */
@@ -313,6 +327,7 @@ declare function setOwn(object: object, key: PropertyKey, value: unknown): void;
313
327
  */
314
328
  declare function mergeTwoLevels(first: unknown, second: unknown): unknown;
315
329
  declare function omit<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Omit<T, K>;
330
+ declare function pick<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K>;
316
331
  /**
317
332
  * Deep clones arrays and plain objects, leaving every other value as is.
318
333
  * Circular and shared references are preserved in the copy.
@@ -361,6 +376,11 @@ declare function promiseWithResolvers<T>(): {
361
376
  resolve: (v: T) => void;
362
377
  reject: (reason: unknown) => void;
363
378
  };
379
+ /**
380
+ * Captures the current async context (such as AsyncLocalStorage) through a promise reaction, so no runtime API is needed.
381
+ * The returned function runs a callback inside it once; later calls reject.
382
+ */
383
+ declare function captureAsyncContext(): <T>(callback: () => Promise<T>) => Promise<T>;
364
384
 
365
385
  type Value<T, TArgs extends any[] = []> = T | ((...args: TArgs) => T);
366
386
  declare function value<T, TArgs extends any[]>(value: Value<T, TArgs>, ...args: NoInfer<TArgs>): T extends Value<infer U, any> ? U : never;
@@ -453,5 +473,5 @@ declare function asyncIteratorToStream<T>(iterator: AsyncIterator<T>): ReadableS
453
473
  */
454
474
  declare function asyncIteratorToUnproxiedDataStream<T>(iterator: AsyncIterator<T>): ReadableStream<T>;
455
475
 
456
- export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, consumeAsyncIterator, copyOnWrite, defer, findDeepMatches, get, getConstructor, getConstructors, getOwn, getTracer, intercept, isAbortError, isAsyncGeneratorFunction, isCompressibleContentType, isDeepEqual, isNoTransformCacheControl, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, mergeTwoLevels, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, parseAcceptEncodingQualities, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOwn, setSpanAttributeIfDefined, setTracer, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toSpanAttributeValue, toStringOrBytes, toTracingException, traceAsyncIterator, traceReadableStream, tryOrUndefined, value, varyByAcceptEncoding, wrapAsyncIterator, wrapReadableStream };
457
- export type { AnyFunction, AsyncIdQueueCloseOptions, ConsumeAsyncIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OnFinishState, OrderablePlugin, PromiseWithError, Public, ReadableStreamReadResult, Registry, Segment, StartSpanOptions, ThrowableError, Tracer, TracingAttributeValue, TracingException, TracingExceptionLevel, TracingHeaders, TracingSpan, Value, WrapAsyncIteratorOptions, WrapReadableStreamOptions };
476
+ export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, captureAsyncContext, clone, compareSequentialIds, consumeAsyncIterator, copyOnWrite, defer, findDeepMatches, get, getConstructor, getConstructors, getOwn, getTracer, intercept, isAbortError, isAcceptableEncoding, isAsyncGeneratorFunction, isCompressibleContentType, isDeepEqual, isNoTransformCacheControl, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, mergeTwoLevels, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, parseAcceptEncodingQualities, pathToHttpPath, pick, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOwn, setSpanAttributeIfDefined, setTracer, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toSpanAttributeValue, toStringOrBytes, toTracingException, traceAsyncIterator, traceReadableStream, tryOrUndefined, value, varyByAcceptEncoding, wrapAsyncIterator, wrapReadableStream };
477
+ export type { AnyFunction, AsyncIdQueueCloseOptions, ConsumeAsyncIteratorOptions, DistributiveOmit, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OnFinishState, OrderablePlugin, PromiseWithError, Public, ReadableStreamReadResult, Registry, Segment, StartSpanOptions, ThrowableError, Tracer, TracingAttributeValue, TracingException, TracingExceptionLevel, TracingHeaders, TracingSpan, Value, WrapAsyncIteratorOptions, WrapReadableStreamOptions };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Arrayable, Promisable } from 'type-fest';
2
2
  export { Arrayable, IsEqual, PartialDeep, Promisable, Writable } from 'type-fest';
3
3
  import { AsyncIteratorClass } from '@standard-server/shared';
4
- export { AbortError, AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, safeDecodeURIComponent, safeEncodeURIComponent, sequential, sleep, stringifyJSON, toArray } from '@standard-server/shared';
4
+ export { AbortError, AsyncCleanupFn, AsyncIteratorClass, AsyncIteratorClassNextFn, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, safeDecodeURIComponent, safeEncodeURIComponent, sequential, sleep, stringifyJSON, throwIfAborted, toArray } from '@standard-server/shared';
5
5
 
6
6
  type MaybeOptionalOptions<TOptions> = object extends TOptions ? [options?: TOptions] : [options: TOptions];
7
7
  declare function resolveMaybeOptionalOptions<T>(rest: MaybeOptionalOptions<T>): T;
@@ -34,9 +34,10 @@ type AnyFunction = (...args: any[]) => any;
34
34
  declare function isAsyncGeneratorFunction(value: unknown): value is (...args: any[]) => AsyncGenerator;
35
35
  declare function once<T>(fn: () => T): () => T;
36
36
  /**
37
- * Executes the callback function after the current call stack has been cleared.
37
+ * Executes the callback function after the current call stack has been cleared,
38
+ * waiting at least `delay` ms when `setTimeout` is available.
38
39
  */
39
- declare function defer(callback: () => void): void;
40
+ declare function defer(callback: () => void, delay?: number): void;
40
41
  declare function tryOrUndefined<T>(fn: () => T): undefined | T;
41
42
 
42
43
  declare function pathToHttpPath(path: readonly string[]): `/${string}`;
@@ -46,12 +47,19 @@ declare function matchesHttpPathPrefix(url: `/${string}`, prefix: `/${string}`):
46
47
  declare function matchesHttpPath(url: `/${string}`, path: `/${string}`): boolean;
47
48
  /**
48
49
  * Parse Accept-Encoding into each coding's q-value, where `0` means the coding is explicitly
49
- * unacceptable. The `*` wildcard is kept under its own key, so a caller can honour it while
50
- * still letting a specific coding take precedence over it.
50
+ * unacceptable. The `*` wildcard is kept under its own key; use {@link isAcceptableEncoding}
51
+ * to decide whether a coding is acceptable.
51
52
  *
52
53
  * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding
53
54
  */
54
55
  declare function parseAcceptEncodingQualities(header: string | undefined): Map<string, number>;
56
+ /**
57
+ * Whether the client accepts a coding, given qualities from {@link parseAcceptEncodingQualities}.
58
+ * An explicit q-value takes precedence over the `*` wildcard, so `gzip;q=0, *` never accepts gzip.
59
+ *
60
+ * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding
61
+ */
62
+ declare function isAcceptableEncoding(qualities: Map<string, number>, coding: string): boolean;
55
63
  /**
56
64
  * Add `accept-encoding` to a Vary header value. The encoding is chosen from the request, so a
57
65
  * shared cache must key on it or it will hand a compressed body to a client that cannot decode it.
@@ -72,6 +80,12 @@ declare function isCompressibleContentType(contentType: string | null | undefine
72
80
  declare function compareSequentialIds(a: string, b: string): number;
73
81
 
74
82
  type IntersectPick<T, U> = Pick<T, keyof T & keyof U>;
83
+ /**
84
+ * Like `Omit`, but distributes over unions and keeps known keys beside index signatures.
85
+ */
86
+ type DistributiveOmit<T, K extends PropertyKey> = {
87
+ [P in keyof T as P extends K ? never : P]: T[P];
88
+ };
75
89
  /**
76
90
  * Remove protected/private properties/methods
77
91
  */
@@ -313,6 +327,7 @@ declare function setOwn(object: object, key: PropertyKey, value: unknown): void;
313
327
  */
314
328
  declare function mergeTwoLevels(first: unknown, second: unknown): unknown;
315
329
  declare function omit<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Omit<T, K>;
330
+ declare function pick<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K>;
316
331
  /**
317
332
  * Deep clones arrays and plain objects, leaving every other value as is.
318
333
  * Circular and shared references are preserved in the copy.
@@ -361,6 +376,11 @@ declare function promiseWithResolvers<T>(): {
361
376
  resolve: (v: T) => void;
362
377
  reject: (reason: unknown) => void;
363
378
  };
379
+ /**
380
+ * Captures the current async context (such as AsyncLocalStorage) through a promise reaction, so no runtime API is needed.
381
+ * The returned function runs a callback inside it once; later calls reject.
382
+ */
383
+ declare function captureAsyncContext(): <T>(callback: () => Promise<T>) => Promise<T>;
364
384
 
365
385
  type Value<T, TArgs extends any[] = []> = T | ((...args: TArgs) => T);
366
386
  declare function value<T, TArgs extends any[]>(value: Value<T, TArgs>, ...args: NoInfer<TArgs>): T extends Value<infer U, any> ? U : never;
@@ -453,5 +473,5 @@ declare function asyncIteratorToStream<T>(iterator: AsyncIterator<T>): ReadableS
453
473
  */
454
474
  declare function asyncIteratorToUnproxiedDataStream<T>(iterator: AsyncIterator<T>): ReadableStream<T>;
455
475
 
456
- export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, consumeAsyncIterator, copyOnWrite, defer, findDeepMatches, get, getConstructor, getConstructors, getOwn, getTracer, intercept, isAbortError, isAsyncGeneratorFunction, isCompressibleContentType, isDeepEqual, isNoTransformCacheControl, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, mergeTwoLevels, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, parseAcceptEncodingQualities, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOwn, setSpanAttributeIfDefined, setTracer, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toSpanAttributeValue, toStringOrBytes, toTracingException, traceAsyncIterator, traceReadableStream, tryOrUndefined, value, varyByAcceptEncoding, wrapAsyncIterator, wrapReadableStream };
457
- export type { AnyFunction, AsyncIdQueueCloseOptions, ConsumeAsyncIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OnFinishState, OrderablePlugin, PromiseWithError, Public, ReadableStreamReadResult, Registry, Segment, StartSpanOptions, ThrowableError, Tracer, TracingAttributeValue, TracingException, TracingExceptionLevel, TracingHeaders, TracingSpan, Value, WrapAsyncIteratorOptions, WrapReadableStreamOptions };
476
+ export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, captureAsyncContext, clone, compareSequentialIds, consumeAsyncIterator, copyOnWrite, defer, findDeepMatches, get, getConstructor, getConstructors, getOwn, getTracer, intercept, isAbortError, isAcceptableEncoding, isAsyncGeneratorFunction, isCompressibleContentType, isDeepEqual, isNoTransformCacheControl, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, mergeTwoLevels, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, parseAcceptEncodingQualities, pathToHttpPath, pick, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOwn, setSpanAttributeIfDefined, setTracer, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toSpanAttributeValue, toStringOrBytes, toTracingException, traceAsyncIterator, traceReadableStream, tryOrUndefined, value, varyByAcceptEncoding, wrapAsyncIterator, wrapReadableStream };
477
+ export type { AnyFunction, AsyncIdQueueCloseOptions, ConsumeAsyncIteratorOptions, DistributiveOmit, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OnFinishState, OrderablePlugin, PromiseWithError, Public, ReadableStreamReadResult, Registry, Segment, StartSpanOptions, ThrowableError, Tracer, TracingAttributeValue, TracingException, TracingExceptionLevel, TracingHeaders, TracingSpan, Value, WrapAsyncIteratorOptions, WrapReadableStreamOptions };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { safeDecodeURIComponent, safeEncodeURIComponent, AbortError, AsyncIteratorClass, getOrBind, isTypescriptObject, isAsyncIteratorObject } from '@standard-server/shared';
2
- export { AbortError, AsyncIteratorClass, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, safeDecodeURIComponent, safeEncodeURIComponent, sequential, sleep, stringifyJSON, toArray } from '@standard-server/shared';
1
+ import { safeDecodeURIComponent, safeEncodeURIComponent, AbortError, AsyncIteratorClass, getOrBind, isTypescriptObject, isAsyncIteratorObject, throwIfAborted } from '@standard-server/shared';
2
+ export { AbortError, AsyncIteratorClass, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, safeDecodeURIComponent, safeEncodeURIComponent, sequential, sleep, stringifyJSON, throwIfAborted, toArray } from '@standard-server/shared';
3
3
 
4
4
  function resolveMaybeOptionalOptions(rest) {
5
5
  return rest[0] ?? {};
@@ -127,9 +127,9 @@ function once(fn) {
127
127
  return result;
128
128
  };
129
129
  }
130
- function defer(callback) {
130
+ function defer(callback, delay = 0) {
131
131
  if (typeof setTimeout === "function") {
132
- setTimeout(callback, 0);
132
+ setTimeout(callback, delay);
133
133
  } else {
134
134
  Promise.resolve().then(() => Promise.resolve().then(() => Promise.resolve().then(callback)));
135
135
  }
@@ -187,6 +187,9 @@ function parseAcceptEncodingQualities(header) {
187
187
  }
188
188
  return qualities;
189
189
  }
190
+ function isAcceptableEncoding(qualities, coding) {
191
+ return (qualities.get(coding) ?? qualities.get("*") ?? 0) > 0;
192
+ }
190
193
  function varyByAcceptEncoding(vary) {
191
194
  if (vary === void 0) {
192
195
  return "accept-encoding";
@@ -492,7 +495,12 @@ function consumeAsyncIterator(iterator, options) {
492
495
  options.onSuccess?.(realValue);
493
496
  break;
494
497
  }
495
- options.onEvent(value);
498
+ try {
499
+ options.onEvent(value);
500
+ } catch (error) {
501
+ await resolvedIterator.return?.();
502
+ throw error;
503
+ }
496
504
  }
497
505
  } catch (error) {
498
506
  onFinishState = [error, void 0, false];
@@ -630,6 +638,15 @@ function omit(obj, keys) {
630
638
  }
631
639
  return result;
632
640
  }
641
+ function pick(obj, keys) {
642
+ const result = {};
643
+ for (const key of keys) {
644
+ if (Object.hasOwn(obj, key)) {
645
+ result[key] = obj[key];
646
+ }
647
+ }
648
+ return result;
649
+ }
633
650
  function clone(value) {
634
651
  return cloneWithVisited(value, /* @__PURE__ */ new WeakMap());
635
652
  }
@@ -726,6 +743,19 @@ function promiseWithResolvers() {
726
743
  });
727
744
  return result;
728
745
  }
746
+ function captureAsyncContext() {
747
+ const { promise, resolve } = promiseWithResolvers();
748
+ const result = promise.then((callback) => callback());
749
+ let called = false;
750
+ return (callback) => {
751
+ if (called) {
752
+ return Promise.reject(new Error("A captured async context can be run only once."));
753
+ }
754
+ called = true;
755
+ resolve(callback);
756
+ return result;
757
+ };
758
+ }
729
759
 
730
760
  function replicateReadableStream(stream, count) {
731
761
  if (count <= 0) {
@@ -887,8 +917,8 @@ function onError(callback) {
887
917
  };
888
918
  }
889
919
  function onFinish(callback) {
890
- let state;
891
920
  return async (options, ...rest) => {
921
+ let state;
892
922
  try {
893
923
  const result = await options.next();
894
924
  state = [null, result, true];
@@ -1050,7 +1080,7 @@ async function runWithSignal(signal, fn) {
1050
1080
  if (!signal) {
1051
1081
  return fn();
1052
1082
  }
1053
- signal.throwIfAborted();
1083
+ throwIfAborted(signal);
1054
1084
  const { promise, reject, resolve } = promiseWithResolvers();
1055
1085
  let abortListener;
1056
1086
  signal.addEventListener("abort", abortListener = () => {
@@ -1067,4 +1097,4 @@ async function runWithSignal(signal, fn) {
1067
1097
  }
1068
1098
  }
1069
1099
 
1070
- export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, clone, compareSequentialIds, consumeAsyncIterator, copyOnWrite, defer, findDeepMatches, get, getConstructor, getConstructors, getOwn, getTracer, intercept, isAbortError, isAsyncGeneratorFunction, isCompressibleContentType, isDeepEqual, isNoTransformCacheControl, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, mergeTwoLevels, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, parseAcceptEncodingQualities, pathToHttpPath, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOwn, setSpanAttributeIfDefined, setTracer, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toSpanAttributeValue, toStringOrBytes, toTracingException, traceAsyncIterator, traceReadableStream, tryOrUndefined, value, varyByAcceptEncoding, wrapAsyncIterator, wrapReadableStream };
1100
+ export { AsyncIdQueue, NullProtoObj, ORPC_NAME, allAbortSignal, anyAbortSignal, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, bindMethods, captureAsyncContext, clone, compareSequentialIds, consumeAsyncIterator, copyOnWrite, defer, findDeepMatches, get, getConstructor, getConstructors, getOwn, getTracer, intercept, isAbortError, isAcceptableEncoding, isAsyncGeneratorFunction, isCompressibleContentType, isDeepEqual, isNoTransformCacheControl, isPlainObject, isPropertyKey, loadBytes, matchesHttpPath, matchesHttpPathPrefix, mergeHttpPath, mergeTwoLevels, normalizeHttpPath, omit, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, once, override, parseAcceptEncodingQualities, pathToHttpPath, pick, promiseWithResolvers, recordSpanError, replicateAsyncIterator, replicateReadableStream, resolveMaybeOptionalOptions, runInSpanContext, runWithSignal, runWithSpan, set, setOwn, setSpanAttributeIfDefined, setTracer, sortPlugins, splitInHalf, startSpan, streamToAsyncIteratorObject, toSpanAttributeValue, toStringOrBytes, toTracingException, traceAsyncIterator, traceReadableStream, tryOrUndefined, value, varyByAcceptEncoding, 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.40",
4
+ "version": "2.0.0-beta.41",
5
5
  "description": "Internal utilities shared across oRPC packages",
6
6
  "license": "MIT",
7
7
  "funding": [
@@ -30,7 +30,7 @@
30
30
  "dist"
31
31
  ],
32
32
  "dependencies": {
33
- "@standard-server/shared": "~0.9.2",
33
+ "@standard-server/shared": "~0.10.0",
34
34
  "radash": "^12.1.1",
35
35
  "type-fest": "^5.3.1"
36
36
  },