@orpc/shared 0.0.0-next.e7896e2 → 0.0.0-next.e7c0280

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
@@ -1,8 +1,3 @@
1
- > [!WARNING]
2
- >
3
- > `@orpc/shared` is an internal dependency of oRPC packages. It does not follow semver and may change at any time without notice.
4
- > Please do not use it in your project.
5
-
6
1
  <div align="center">
7
2
  <image align="center" src="https://orpc.unnoq.com/logo.webp" width=280 alt="oRPC logo" />
8
3
  </div>
@@ -35,7 +30,7 @@
35
30
  - **🔗 End-to-End Type Safety**: Ensure type-safe inputs, outputs, and errors from client to server.
36
31
  - **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
37
32
  - **📝 Contract-First Development**: Optionally define your API contract before implementation.
38
- - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte), Pinia Colada, and more.
33
+ - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), Pinia Colada, and more.
39
34
  - **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
40
35
  - **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
41
36
  - **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Promisable } from 'type-fest';
2
- export { IsEqual, IsNever, PartialDeep, Promisable } from 'type-fest';
2
+ export { IsEqual, IsNever, JsonValue, PartialDeep, Promisable } from 'type-fest';
3
3
  export { group, guard, mapEntries, mapValues, omit } from 'radash';
4
4
 
5
5
  type MaybeOptionalOptions<TOptions> = Record<never, never> extends TOptions ? [options?: TOptions] : [options: TOptions];
@@ -8,6 +8,13 @@ declare function resolveMaybeOptionalOptions<T>(rest: MaybeOptionalOptions<T>):
8
8
  declare function toArray<T>(value: T): T extends readonly any[] ? T : Exclude<T, undefined | null>[];
9
9
  declare function splitInHalf<T>(arr: readonly T[]): [T[], T[]];
10
10
 
11
+ /**
12
+ * Converts Request/Response/Blob/File/.. to a buffer (ArrayBuffer or Uint8Array).
13
+ *
14
+ * Prefers the newer `.bytes` method when available as it more efficient but not widely supported yet.
15
+ */
16
+ declare function readAsBuffer(source: Pick<Blob, 'arrayBuffer' | 'bytes'>): Promise<ArrayBuffer | Uint8Array>;
17
+
11
18
  type AnyFunction = (...args: any[]) => any;
12
19
  declare function once<T extends () => any>(fn: T): () => ReturnType<T>;
13
20
  declare function sequential<A extends any[], R>(fn: (...args: A) => Promise<R>): (...args: A) => Promise<R>;
@@ -80,8 +87,8 @@ declare class EventPublisher<T extends Record<PropertyKey, any>> {
80
87
  }
81
88
 
82
89
  declare class SequentialIdGenerator {
83
- private nextId;
84
- generate(): number;
90
+ private index;
91
+ generate(): string;
85
92
  }
86
93
 
87
94
  type SetOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
@@ -135,14 +142,34 @@ declare function onFinish<T, TOptions extends {
135
142
  declare function intercept<TOptions extends InterceptableOptions, TResult>(interceptors: Interceptor<TOptions, TResult>[], options: NoInfer<TOptions>, main: NoInfer<(options: TOptions) => TResult>): TResult;
136
143
 
137
144
  declare function isAsyncIteratorObject(maybe: unknown): maybe is AsyncIteratorObject<any, any, any>;
138
- interface CreateAsyncIteratorObjectCleanupFn {
145
+ interface AsyncIteratorClassNextFn<T, TReturn> {
146
+ (): Promise<IteratorResult<T, TReturn>>;
147
+ }
148
+ interface AsyncIteratorClassCleanupFn {
139
149
  (reason: 'return' | 'throw' | 'next' | 'dispose'): Promise<void>;
140
150
  }
141
- declare function createAsyncIteratorObject<T, TReturn, TNext>(next: () => Promise<IteratorResult<T, TReturn>>, cleanup: CreateAsyncIteratorObjectCleanupFn): AsyncIteratorObject<T, TReturn, TNext> & AsyncGenerator<T, TReturn, TNext>;
142
- declare function replicateAsyncIterator<T, TReturn, TNext>(source: AsyncIterator<T, TReturn, TNext>, count: number): (AsyncIteratorObject<T, TReturn, TNext> & AsyncGenerator<T, TReturn, TNext>)[];
151
+ declare const fallbackAsyncDisposeSymbol: unique symbol;
152
+ declare const asyncDisposeSymbol: typeof Symbol extends {
153
+ asyncDispose: infer T;
154
+ } ? T : typeof fallbackAsyncDisposeSymbol;
155
+ declare class AsyncIteratorClass<T, TReturn = unknown, TNext = unknown> implements AsyncIteratorObject<T, TReturn, TNext>, AsyncGenerator<T, TReturn, TNext> {
156
+ #private;
157
+ constructor(next: AsyncIteratorClassNextFn<T, TReturn>, cleanup: AsyncIteratorClassCleanupFn);
158
+ next(): Promise<IteratorResult<T, TReturn>>;
159
+ return(value?: any): Promise<IteratorResult<T, TReturn>>;
160
+ throw(err: any): Promise<IteratorResult<T, TReturn>>;
161
+ /**
162
+ * asyncDispose symbol only available in esnext, we should fallback to Symbol.for('asyncDispose')
163
+ */
164
+ [asyncDisposeSymbol](): Promise<void>;
165
+ [Symbol.asyncIterator](): this;
166
+ }
167
+ declare function replicateAsyncIterator<T, TReturn, TNext>(source: AsyncIterator<T, TReturn, TNext>, count: number): (AsyncIteratorClass<T, TReturn, TNext>)[];
143
168
 
144
169
  declare function parseEmptyableJSON(text: string | null | undefined): unknown;
145
- declare function stringifyJSON<T>(value: T): undefined extends T ? undefined | string : string;
170
+ declare function stringifyJSON<T>(value: T | {
171
+ toJSON(): T;
172
+ }): undefined extends T ? undefined | string : string;
146
173
 
147
174
  type Segment = string | number;
148
175
  declare function findDeepMatches(check: (value: unknown) => boolean, payload: unknown, segments?: Segment[], maps?: Segment[][], values?: unknown[]): {
@@ -158,14 +185,14 @@ declare function isObject(value: unknown): value is Record<PropertyKey, unknown>
158
185
  */
159
186
  declare function isTypescriptObject(value: unknown): value is object & Record<PropertyKey, unknown>;
160
187
  declare function clone<T>(value: T): T;
161
- declare function get(object: object, path: readonly string[]): unknown;
188
+ declare function get(object: unknown, path: readonly string[]): unknown;
162
189
  declare function isPropertyKey(value: unknown): value is PropertyKey;
163
190
  declare const NullProtoObj: ({
164
191
  new <T extends Record<PropertyKey, unknown>>(): T;
165
192
  });
166
193
 
167
194
  interface AsyncIdQueueCloseOptions {
168
- id?: number;
195
+ id?: string;
169
196
  reason?: unknown;
170
197
  }
171
198
  declare class AsyncIdQueue<T> {
@@ -173,16 +200,21 @@ declare class AsyncIdQueue<T> {
173
200
  private readonly items;
174
201
  private readonly pendingPulls;
175
202
  get length(): number;
176
- open(id: number): void;
177
- isOpen(id: number): boolean;
178
- push(id: number, item: T): void;
179
- pull(id: number): Promise<T>;
203
+ open(id: string): void;
204
+ isOpen(id: string): boolean;
205
+ push(id: string, item: T): void;
206
+ pull(id: string): Promise<T>;
180
207
  close({ id, reason }?: AsyncIdQueueCloseOptions): void;
181
- assertOpen(id: number): void;
208
+ assertOpen(id: string): void;
182
209
  }
183
210
 
211
+ declare function streamToAsyncIteratorClass<T>(stream: ReadableStream<T>): AsyncIteratorClass<T>;
212
+ declare function asyncIteratorToStream<T>(iterator: AsyncIterator<T>): ReadableStream<T>;
213
+
214
+ declare function tryDecodeURIComponent(value: string): string;
215
+
184
216
  type Value<T, TArgs extends any[] = []> = T | ((...args: TArgs) => T);
185
217
  declare function value<T, TArgs extends any[]>(value: Value<T, TArgs>, ...args: NoInfer<TArgs>): T extends Value<infer U, any> ? U : never;
186
218
 
187
- export { AsyncIdQueue, EventPublisher, NullProtoObj, SequentialIdGenerator, clone, createAsyncIteratorObject, defer, findDeepMatches, get, intercept, isAsyncIteratorObject, isObject, isPropertyKey, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, parseEmptyableJSON, replicateAsyncIterator, resolveMaybeOptionalOptions, sequential, splitInHalf, stringifyJSON, toArray, value };
188
- export type { AnyFunction, AsyncIdQueueCloseOptions, CreateAsyncIteratorObjectCleanupFn, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OmitChainMethodDeep, OnFinishState, PromiseWithError, Registry, Segment, SetOptional, ThrowableError, Value };
219
+ export { AsyncIdQueue, AsyncIteratorClass, EventPublisher, NullProtoObj, SequentialIdGenerator, asyncIteratorToStream, clone, defer, findDeepMatches, get, intercept, isAsyncIteratorObject, isObject, isPropertyKey, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, parseEmptyableJSON, readAsBuffer, replicateAsyncIterator, resolveMaybeOptionalOptions, sequential, splitInHalf, streamToAsyncIteratorClass, stringifyJSON, toArray, tryDecodeURIComponent, value };
220
+ export type { AnyFunction, AsyncIdQueueCloseOptions, AsyncIteratorClassCleanupFn, AsyncIteratorClassNextFn, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OmitChainMethodDeep, OnFinishState, PromiseWithError, Registry, Segment, SetOptional, ThrowableError, Value };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Promisable } from 'type-fest';
2
- export { IsEqual, IsNever, PartialDeep, Promisable } from 'type-fest';
2
+ export { IsEqual, IsNever, JsonValue, PartialDeep, Promisable } from 'type-fest';
3
3
  export { group, guard, mapEntries, mapValues, omit } from 'radash';
4
4
 
5
5
  type MaybeOptionalOptions<TOptions> = Record<never, never> extends TOptions ? [options?: TOptions] : [options: TOptions];
@@ -8,6 +8,13 @@ declare function resolveMaybeOptionalOptions<T>(rest: MaybeOptionalOptions<T>):
8
8
  declare function toArray<T>(value: T): T extends readonly any[] ? T : Exclude<T, undefined | null>[];
9
9
  declare function splitInHalf<T>(arr: readonly T[]): [T[], T[]];
10
10
 
11
+ /**
12
+ * Converts Request/Response/Blob/File/.. to a buffer (ArrayBuffer or Uint8Array).
13
+ *
14
+ * Prefers the newer `.bytes` method when available as it more efficient but not widely supported yet.
15
+ */
16
+ declare function readAsBuffer(source: Pick<Blob, 'arrayBuffer' | 'bytes'>): Promise<ArrayBuffer | Uint8Array>;
17
+
11
18
  type AnyFunction = (...args: any[]) => any;
12
19
  declare function once<T extends () => any>(fn: T): () => ReturnType<T>;
13
20
  declare function sequential<A extends any[], R>(fn: (...args: A) => Promise<R>): (...args: A) => Promise<R>;
@@ -80,8 +87,8 @@ declare class EventPublisher<T extends Record<PropertyKey, any>> {
80
87
  }
81
88
 
82
89
  declare class SequentialIdGenerator {
83
- private nextId;
84
- generate(): number;
90
+ private index;
91
+ generate(): string;
85
92
  }
86
93
 
87
94
  type SetOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
@@ -135,14 +142,34 @@ declare function onFinish<T, TOptions extends {
135
142
  declare function intercept<TOptions extends InterceptableOptions, TResult>(interceptors: Interceptor<TOptions, TResult>[], options: NoInfer<TOptions>, main: NoInfer<(options: TOptions) => TResult>): TResult;
136
143
 
137
144
  declare function isAsyncIteratorObject(maybe: unknown): maybe is AsyncIteratorObject<any, any, any>;
138
- interface CreateAsyncIteratorObjectCleanupFn {
145
+ interface AsyncIteratorClassNextFn<T, TReturn> {
146
+ (): Promise<IteratorResult<T, TReturn>>;
147
+ }
148
+ interface AsyncIteratorClassCleanupFn {
139
149
  (reason: 'return' | 'throw' | 'next' | 'dispose'): Promise<void>;
140
150
  }
141
- declare function createAsyncIteratorObject<T, TReturn, TNext>(next: () => Promise<IteratorResult<T, TReturn>>, cleanup: CreateAsyncIteratorObjectCleanupFn): AsyncIteratorObject<T, TReturn, TNext> & AsyncGenerator<T, TReturn, TNext>;
142
- declare function replicateAsyncIterator<T, TReturn, TNext>(source: AsyncIterator<T, TReturn, TNext>, count: number): (AsyncIteratorObject<T, TReturn, TNext> & AsyncGenerator<T, TReturn, TNext>)[];
151
+ declare const fallbackAsyncDisposeSymbol: unique symbol;
152
+ declare const asyncDisposeSymbol: typeof Symbol extends {
153
+ asyncDispose: infer T;
154
+ } ? T : typeof fallbackAsyncDisposeSymbol;
155
+ declare class AsyncIteratorClass<T, TReturn = unknown, TNext = unknown> implements AsyncIteratorObject<T, TReturn, TNext>, AsyncGenerator<T, TReturn, TNext> {
156
+ #private;
157
+ constructor(next: AsyncIteratorClassNextFn<T, TReturn>, cleanup: AsyncIteratorClassCleanupFn);
158
+ next(): Promise<IteratorResult<T, TReturn>>;
159
+ return(value?: any): Promise<IteratorResult<T, TReturn>>;
160
+ throw(err: any): Promise<IteratorResult<T, TReturn>>;
161
+ /**
162
+ * asyncDispose symbol only available in esnext, we should fallback to Symbol.for('asyncDispose')
163
+ */
164
+ [asyncDisposeSymbol](): Promise<void>;
165
+ [Symbol.asyncIterator](): this;
166
+ }
167
+ declare function replicateAsyncIterator<T, TReturn, TNext>(source: AsyncIterator<T, TReturn, TNext>, count: number): (AsyncIteratorClass<T, TReturn, TNext>)[];
143
168
 
144
169
  declare function parseEmptyableJSON(text: string | null | undefined): unknown;
145
- declare function stringifyJSON<T>(value: T): undefined extends T ? undefined | string : string;
170
+ declare function stringifyJSON<T>(value: T | {
171
+ toJSON(): T;
172
+ }): undefined extends T ? undefined | string : string;
146
173
 
147
174
  type Segment = string | number;
148
175
  declare function findDeepMatches(check: (value: unknown) => boolean, payload: unknown, segments?: Segment[], maps?: Segment[][], values?: unknown[]): {
@@ -158,14 +185,14 @@ declare function isObject(value: unknown): value is Record<PropertyKey, unknown>
158
185
  */
159
186
  declare function isTypescriptObject(value: unknown): value is object & Record<PropertyKey, unknown>;
160
187
  declare function clone<T>(value: T): T;
161
- declare function get(object: object, path: readonly string[]): unknown;
188
+ declare function get(object: unknown, path: readonly string[]): unknown;
162
189
  declare function isPropertyKey(value: unknown): value is PropertyKey;
163
190
  declare const NullProtoObj: ({
164
191
  new <T extends Record<PropertyKey, unknown>>(): T;
165
192
  });
166
193
 
167
194
  interface AsyncIdQueueCloseOptions {
168
- id?: number;
195
+ id?: string;
169
196
  reason?: unknown;
170
197
  }
171
198
  declare class AsyncIdQueue<T> {
@@ -173,16 +200,21 @@ declare class AsyncIdQueue<T> {
173
200
  private readonly items;
174
201
  private readonly pendingPulls;
175
202
  get length(): number;
176
- open(id: number): void;
177
- isOpen(id: number): boolean;
178
- push(id: number, item: T): void;
179
- pull(id: number): Promise<T>;
203
+ open(id: string): void;
204
+ isOpen(id: string): boolean;
205
+ push(id: string, item: T): void;
206
+ pull(id: string): Promise<T>;
180
207
  close({ id, reason }?: AsyncIdQueueCloseOptions): void;
181
- assertOpen(id: number): void;
208
+ assertOpen(id: string): void;
182
209
  }
183
210
 
211
+ declare function streamToAsyncIteratorClass<T>(stream: ReadableStream<T>): AsyncIteratorClass<T>;
212
+ declare function asyncIteratorToStream<T>(iterator: AsyncIterator<T>): ReadableStream<T>;
213
+
214
+ declare function tryDecodeURIComponent(value: string): string;
215
+
184
216
  type Value<T, TArgs extends any[] = []> = T | ((...args: TArgs) => T);
185
217
  declare function value<T, TArgs extends any[]>(value: Value<T, TArgs>, ...args: NoInfer<TArgs>): T extends Value<infer U, any> ? U : never;
186
218
 
187
- export { AsyncIdQueue, EventPublisher, NullProtoObj, SequentialIdGenerator, clone, createAsyncIteratorObject, defer, findDeepMatches, get, intercept, isAsyncIteratorObject, isObject, isPropertyKey, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, parseEmptyableJSON, replicateAsyncIterator, resolveMaybeOptionalOptions, sequential, splitInHalf, stringifyJSON, toArray, value };
188
- export type { AnyFunction, AsyncIdQueueCloseOptions, CreateAsyncIteratorObjectCleanupFn, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OmitChainMethodDeep, OnFinishState, PromiseWithError, Registry, Segment, SetOptional, ThrowableError, Value };
219
+ export { AsyncIdQueue, AsyncIteratorClass, EventPublisher, NullProtoObj, SequentialIdGenerator, asyncIteratorToStream, clone, defer, findDeepMatches, get, intercept, isAsyncIteratorObject, isObject, isPropertyKey, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, parseEmptyableJSON, readAsBuffer, replicateAsyncIterator, resolveMaybeOptionalOptions, sequential, splitInHalf, streamToAsyncIteratorClass, stringifyJSON, toArray, tryDecodeURIComponent, value };
220
+ export type { AnyFunction, AsyncIdQueueCloseOptions, AsyncIteratorClassCleanupFn, AsyncIteratorClassNextFn, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OmitChainMethodDeep, OnFinishState, PromiseWithError, Registry, Segment, SetOptional, ThrowableError, Value };
package/dist/index.mjs CHANGED
@@ -12,6 +12,13 @@ function splitInHalf(arr) {
12
12
  return [arr.slice(0, half), arr.slice(half)];
13
13
  }
14
14
 
15
+ function readAsBuffer(source) {
16
+ if (typeof source.bytes === "function") {
17
+ return source.bytes();
18
+ }
19
+ return source.arrayBuffer();
20
+ }
21
+
15
22
  function once(fn) {
16
23
  let cached;
17
24
  return () => {
@@ -120,63 +127,70 @@ function isAsyncIteratorObject(maybe) {
120
127
  if (!maybe || typeof maybe !== "object") {
121
128
  return false;
122
129
  }
123
- return Symbol.asyncIterator in maybe && typeof maybe[Symbol.asyncIterator] === "function";
130
+ return "next" in maybe && typeof maybe.next === "function" && Symbol.asyncIterator in maybe && typeof maybe[Symbol.asyncIterator] === "function";
124
131
  }
125
- function createAsyncIteratorObject(next, cleanup) {
126
- let isExecuteComplete = false;
127
- let isDone = false;
128
- const iterator = {
129
- next: sequential(async () => {
130
- if (isDone) {
132
+ const fallbackAsyncDisposeSymbol = Symbol.for("asyncDispose");
133
+ const asyncDisposeSymbol = Symbol.asyncDispose ?? fallbackAsyncDisposeSymbol;
134
+ class AsyncIteratorClass {
135
+ #isDone = false;
136
+ #isExecuteComplete = false;
137
+ #cleanup;
138
+ #next;
139
+ constructor(next, cleanup) {
140
+ this.#cleanup = cleanup;
141
+ this.#next = sequential(async () => {
142
+ if (this.#isDone) {
131
143
  return { done: true, value: void 0 };
132
144
  }
133
145
  try {
134
146
  const result = await next();
135
147
  if (result.done) {
136
- isDone = true;
148
+ this.#isDone = true;
137
149
  }
138
150
  return result;
139
151
  } catch (err) {
140
- isDone = true;
152
+ this.#isDone = true;
141
153
  throw err;
142
154
  } finally {
143
- if (isDone && !isExecuteComplete) {
144
- isExecuteComplete = true;
145
- await cleanup("next");
155
+ if (this.#isDone && !this.#isExecuteComplete) {
156
+ this.#isExecuteComplete = true;
157
+ await this.#cleanup("next");
146
158
  }
147
159
  }
148
- }),
149
- async return(value) {
150
- isDone = true;
151
- if (!isExecuteComplete) {
152
- isExecuteComplete = true;
153
- await cleanup("return");
154
- }
155
- return { done: true, value };
156
- },
157
- async throw(err) {
158
- isDone = true;
159
- if (!isExecuteComplete) {
160
- isExecuteComplete = true;
161
- await cleanup("throw");
162
- }
163
- throw err;
164
- },
165
- /**
166
- * asyncDispose symbol only available in esnext, we should fallback to Symbol.for('asyncDispose')
167
- */
168
- async [Symbol.asyncDispose ?? Symbol.for("asyncDispose")]() {
169
- isDone = true;
170
- if (!isExecuteComplete) {
171
- isExecuteComplete = true;
172
- await cleanup("dispose");
173
- }
174
- },
175
- [Symbol.asyncIterator]() {
176
- return iterator;
160
+ });
161
+ }
162
+ next() {
163
+ return this.#next();
164
+ }
165
+ async return(value) {
166
+ this.#isDone = true;
167
+ if (!this.#isExecuteComplete) {
168
+ this.#isExecuteComplete = true;
169
+ await this.#cleanup("return");
177
170
  }
178
- };
179
- return iterator;
171
+ return { done: true, value };
172
+ }
173
+ async throw(err) {
174
+ this.#isDone = true;
175
+ if (!this.#isExecuteComplete) {
176
+ this.#isExecuteComplete = true;
177
+ await this.#cleanup("throw");
178
+ }
179
+ throw err;
180
+ }
181
+ /**
182
+ * asyncDispose symbol only available in esnext, we should fallback to Symbol.for('asyncDispose')
183
+ */
184
+ async [asyncDisposeSymbol]() {
185
+ this.#isDone = true;
186
+ if (!this.#isExecuteComplete) {
187
+ this.#isExecuteComplete = true;
188
+ await this.#cleanup("dispose");
189
+ }
190
+ }
191
+ [Symbol.asyncIterator]() {
192
+ return this;
193
+ }
180
194
  }
181
195
  function replicateAsyncIterator(source, count) {
182
196
  const queue = new AsyncIdQueue();
@@ -187,8 +201,8 @@ function replicateAsyncIterator(source, count) {
187
201
  while (true) {
188
202
  const item = await source.next();
189
203
  for (let id = 0; id < count; id++) {
190
- if (queue.isOpen(id)) {
191
- queue.push(id, item);
204
+ if (queue.isOpen(id.toString())) {
205
+ queue.push(id.toString(), item);
192
206
  }
193
207
  }
194
208
  if (item.done) {
@@ -200,12 +214,12 @@ function replicateAsyncIterator(source, count) {
200
214
  }
201
215
  });
202
216
  for (let id = 0; id < count; id++) {
203
- queue.open(id);
204
- replicated.push(createAsyncIteratorObject(
217
+ queue.open(id.toString());
218
+ replicated.push(new AsyncIteratorClass(
205
219
  () => {
206
220
  start();
207
221
  return new Promise((resolve, reject) => {
208
- queue.pull(id).then(resolve).catch(reject);
222
+ queue.pull(id.toString()).then(resolve).catch(reject);
209
223
  defer(() => {
210
224
  if (error) {
211
225
  reject(error.value);
@@ -214,9 +228,9 @@ function replicateAsyncIterator(source, count) {
214
228
  });
215
229
  },
216
230
  async (reason) => {
217
- queue.close({ id });
231
+ queue.close({ id: id.toString() });
218
232
  if (reason !== "next") {
219
- if (replicated.every((_, id2) => !queue.isOpen(id2))) {
233
+ if (replicated.every((_, id2) => !queue.isOpen(id2.toString()))) {
220
234
  await source?.return?.();
221
235
  }
222
236
  }
@@ -263,6 +277,7 @@ class EventPublisher {
263
277
  }
264
278
  const signal = listenerOrOptions?.signal;
265
279
  const maxBufferedEvents = listenerOrOptions?.maxBufferedEvents ?? this.#maxBufferedEvents;
280
+ signal?.throwIfAborted();
266
281
  const bufferedEvents = [];
267
282
  const pullResolvers = [];
268
283
  const unsubscribe = this.subscribe(event, (payload) => {
@@ -283,7 +298,7 @@ class EventPublisher {
283
298
  bufferedEvents.length = 0;
284
299
  };
285
300
  signal?.addEventListener("abort", abortListener, { once: true });
286
- return createAsyncIteratorObject(async () => {
301
+ return new AsyncIteratorClass(async () => {
287
302
  if (signal?.aborted) {
288
303
  throw signal.reason;
289
304
  }
@@ -304,13 +319,11 @@ class EventPublisher {
304
319
  }
305
320
 
306
321
  class SequentialIdGenerator {
307
- nextId = 0;
322
+ index = BigInt(0);
308
323
  generate() {
309
- if (this.nextId === Number.MAX_SAFE_INTEGER) {
310
- this.nextId = 0;
311
- return Number.MAX_SAFE_INTEGER;
312
- }
313
- return this.nextId++;
324
+ const id = this.index.toString(32);
325
+ this.index++;
326
+ return id;
314
327
  }
315
328
  }
316
329
 
@@ -436,6 +449,41 @@ const NullProtoObj = /* @__PURE__ */ (() => {
436
449
  return e;
437
450
  })();
438
451
 
452
+ function streamToAsyncIteratorClass(stream) {
453
+ const reader = stream.getReader();
454
+ return new AsyncIteratorClass(
455
+ async () => {
456
+ return reader.read();
457
+ },
458
+ async () => {
459
+ await reader.cancel();
460
+ }
461
+ );
462
+ }
463
+ function asyncIteratorToStream(iterator) {
464
+ return new ReadableStream({
465
+ async pull(controller) {
466
+ const { done, value } = await iterator.next();
467
+ if (done) {
468
+ controller.close();
469
+ } else {
470
+ controller.enqueue(value);
471
+ }
472
+ },
473
+ async cancel() {
474
+ await iterator.return?.();
475
+ }
476
+ });
477
+ }
478
+
479
+ function tryDecodeURIComponent(value) {
480
+ try {
481
+ return decodeURIComponent(value);
482
+ } catch {
483
+ return value;
484
+ }
485
+ }
486
+
439
487
  function value(value2, ...args) {
440
488
  if (typeof value2 === "function") {
441
489
  return value2(...args);
@@ -443,4 +491,4 @@ function value(value2, ...args) {
443
491
  return value2;
444
492
  }
445
493
 
446
- export { AsyncIdQueue, EventPublisher, NullProtoObj, SequentialIdGenerator, clone, createAsyncIteratorObject, defer, findDeepMatches, get, intercept, isAsyncIteratorObject, isObject, isPropertyKey, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, parseEmptyableJSON, replicateAsyncIterator, resolveMaybeOptionalOptions, sequential, splitInHalf, stringifyJSON, toArray, value };
494
+ export { AsyncIdQueue, AsyncIteratorClass, EventPublisher, NullProtoObj, SequentialIdGenerator, asyncIteratorToStream, clone, defer, findDeepMatches, get, intercept, isAsyncIteratorObject, isObject, isPropertyKey, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, parseEmptyableJSON, readAsBuffer, replicateAsyncIterator, resolveMaybeOptionalOptions, sequential, splitInHalf, streamToAsyncIteratorClass, stringifyJSON, toArray, tryDecodeURIComponent, value };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/shared",
3
3
  "type": "module",
4
- "version": "0.0.0-next.e7896e2",
4
+ "version": "0.0.0-next.e7c0280",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -24,13 +24,13 @@
24
24
  "dist"
25
25
  ],
26
26
  "dependencies": {
27
- "radash": "^12.1.0",
27
+ "radash": "^12.1.1",
28
28
  "type-fest": "^4.39.1"
29
29
  },
30
30
  "devDependencies": {
31
31
  "arktype": "2.1.20",
32
32
  "valibot": "^1.1.0",
33
- "zod": "^3.25.49"
33
+ "zod": "^4.0.5"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "unbuild",