@orpc/shared 1.14.6 → 2.0.0-beta.2

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/dist/index.mjs CHANGED
@@ -1,33 +1,94 @@
1
- export { group, guard, mapEntries, mapValues, omit, retry, sleep } from 'radash';
1
+ import { AbortError, AsyncIteratorClass, isTypescriptObject, getOrBind } from '@standardserver/shared';
2
+ export { AbortError, AsyncIteratorClass, SequentialIdGenerator, getOrBind, isAsyncIteratorObject, isTypescriptObject, parseEmptyableJSON, sleep, stringifyJSON, toArray } from '@standardserver/shared';
2
3
 
3
4
  function resolveMaybeOptionalOptions(rest) {
4
5
  return rest[0] ?? {};
5
6
  }
6
7
 
7
- function toArray(value) {
8
- return Array.isArray(value) ? value : value === void 0 || value === null ? [] : [value];
9
- }
10
8
  function splitInHalf(arr) {
11
9
  const half = Math.ceil(arr.length / 2);
12
10
  return [arr.slice(0, half), arr.slice(half)];
13
11
  }
14
12
 
15
- function readAsBuffer(source) {
13
+ async function loadBytes(source) {
16
14
  if (typeof source.bytes === "function") {
17
15
  return source.bytes();
18
16
  }
19
- return source.arrayBuffer();
17
+ return new Uint8Array(await source.arrayBuffer());
18
+ }
19
+ async function toStringOrBytes(source) {
20
+ if (typeof source === "string") {
21
+ return source;
22
+ }
23
+ if (source instanceof ArrayBuffer) {
24
+ return new Uint8Array(source);
25
+ }
26
+ if (source instanceof Blob) {
27
+ return loadBytes(source);
28
+ }
29
+ if (Array.isArray(source)) {
30
+ return loadBytes(new Blob(source));
31
+ }
32
+ if (source instanceof Uint8Array) {
33
+ return source;
34
+ }
35
+ return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
36
+ }
37
+
38
+ function isDeepEqual(a, b) {
39
+ return isDeepEqualInternal(a, b, /* @__PURE__ */ new WeakMap());
40
+ }
41
+ function isDeepEqualInternal(a, b, visited) {
42
+ if (Object.is(a, b)) {
43
+ return true;
44
+ }
45
+ if (typeof a !== typeof b) {
46
+ return false;
47
+ }
48
+ if (a === null || typeof a !== "object") {
49
+ return false;
50
+ }
51
+ if (b === null || typeof b !== "object") {
52
+ return false;
53
+ }
54
+ const isArray = Array.isArray(a);
55
+ if (isArray !== Array.isArray(b)) {
56
+ return false;
57
+ }
58
+ if (isArray && a.length !== b.length) {
59
+ return false;
60
+ }
61
+ const aRecord = a;
62
+ const bRecord = b;
63
+ const visitedMatches = visited.get(a);
64
+ if (visitedMatches?.has(b)) {
65
+ return true;
66
+ }
67
+ if (visitedMatches) {
68
+ visitedMatches.add(b);
69
+ } else {
70
+ visited.set(a, new WeakSet([b]));
71
+ }
72
+ const aKeys = Object.keys(aRecord).filter((k) => aRecord[k] !== void 0);
73
+ const bKeys = Object.keys(bRecord).filter((k) => bRecord[k] !== void 0);
74
+ if (aKeys.length !== bKeys.length) {
75
+ return false;
76
+ }
77
+ for (const key of aKeys) {
78
+ if (!Object.hasOwn(bRecord, key)) {
79
+ return false;
80
+ }
81
+ if (!isDeepEqualInternal(aRecord[key], bRecord[key], visited)) {
82
+ return false;
83
+ }
84
+ }
85
+ return true;
20
86
  }
21
87
 
22
88
  const ORPC_NAME = "orpc";
23
- const ORPC_SHARED_PACKAGE_NAME = "@orpc/shared";
24
- const ORPC_SHARED_PACKAGE_VERSION = "1.14.6";
25
89
 
26
- class AbortError extends Error {
27
- constructor(...rest) {
28
- super(...rest);
29
- this.name = "AbortError";
30
- }
90
+ function isAbortError(error) {
91
+ return error instanceof Error && error.name.includes("Abort");
31
92
  }
32
93
 
33
94
  function once(fn) {
@@ -41,15 +102,6 @@ function once(fn) {
41
102
  return result;
42
103
  };
43
104
  }
44
- function sequential(fn) {
45
- let lastOperationPromise = Promise.resolve();
46
- return (...args) => {
47
- return lastOperationPromise = lastOperationPromise.catch(() => {
48
- }).then(() => {
49
- return fn(...args);
50
- });
51
- };
52
- }
53
105
  function defer(callback) {
54
106
  if (typeof setTimeout === "function") {
55
107
  setTimeout(callback, 0);
@@ -57,33 +109,146 @@ function defer(callback) {
57
109
  Promise.resolve().then(() => Promise.resolve().then(() => Promise.resolve().then(callback)));
58
110
  }
59
111
  }
112
+ function tryOrUndefined(fn) {
113
+ try {
114
+ return fn();
115
+ } catch {
116
+ return void 0;
117
+ }
118
+ }
119
+
120
+ function tryDecodeURIComponent(value) {
121
+ try {
122
+ return decodeURIComponent(value);
123
+ } catch {
124
+ return value;
125
+ }
126
+ }
127
+
128
+ function pathToHttpPath(path) {
129
+ return `/${path.map(encodeURIComponent).join("/")}`;
130
+ }
131
+ function normalizeHttpPath(path) {
132
+ const paths = path.split("/");
133
+ if (paths.at(0) === "") {
134
+ paths.shift();
135
+ }
136
+ return pathToHttpPath(paths.map(tryDecodeURIComponent));
137
+ }
138
+ function mergeHttpPath(a, b) {
139
+ return `${a.endsWith("/") ? a.slice(0, -1) : a}${b}`;
140
+ }
141
+ function matchesHttpPathPrefix(url, prefix) {
142
+ if (!url.startsWith(prefix)) {
143
+ return false;
144
+ }
145
+ const charAfterPrefix = url[prefix.length];
146
+ return charAfterPrefix === "/" || charAfterPrefix === "?" || charAfterPrefix === "#" || charAfterPrefix === void 0 || prefix[prefix.length - 1] === "/";
147
+ }
148
+ function matchesHttpPath(url, path) {
149
+ const pathWithoutEndSlash = path.endsWith("/") ? path.slice(0, path.length - 1) : path;
150
+ if (!url.startsWith(pathWithoutEndSlash)) {
151
+ return false;
152
+ }
153
+ let charAfterPrefix = url[pathWithoutEndSlash.length];
154
+ if (charAfterPrefix === "/") {
155
+ charAfterPrefix = url[pathWithoutEndSlash.length + 1];
156
+ }
157
+ return charAfterPrefix === void 0 || charAfterPrefix === "?" || charAfterPrefix === "#";
158
+ }
159
+
160
+ function compareSequentialIds(a, b) {
161
+ if (a.length !== b.length) {
162
+ return a.length - b.length;
163
+ }
164
+ return a < b ? -1 : a > b ? 1 : 0;
165
+ }
166
+
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
+ }
60
221
 
61
222
  const SPAN_ERROR_STATUS = 2;
62
- const GLOBAL_OTEL_CONFIG_KEY = `__${ORPC_SHARED_PACKAGE_NAME}@${ORPC_SHARED_PACKAGE_VERSION}/otel/config__`;
63
- function setGlobalOtelConfig(config) {
64
- globalThis[GLOBAL_OTEL_CONFIG_KEY] = config;
223
+ const OPENTELEMETRY_CONFIG_SYMBOL = Symbol.for("ORPC_OPENTELEMETRY_CONFIG");
224
+ function setOpenTelemetryConfig(config) {
225
+ globalThis[OPENTELEMETRY_CONFIG_SYMBOL] = config;
65
226
  }
66
- function getGlobalOtelConfig() {
67
- return globalThis[GLOBAL_OTEL_CONFIG_KEY];
227
+ function getOpenTelemetryConfig() {
228
+ return globalThis[OPENTELEMETRY_CONFIG_SYMBOL];
68
229
  }
69
- function startSpan(name, options = {}, context) {
70
- const tracer = getGlobalOtelConfig()?.tracer;
71
- return tracer?.startSpan(name, options, context);
230
+ function startSpan(options) {
231
+ const tracer = getOpenTelemetryConfig()?.tracer;
232
+ if (!tracer) {
233
+ return void 0;
234
+ }
235
+ const { name, context, ...spanOptions } = typeof options === "string" ? { name: options } : options;
236
+ return tracer.startSpan(name, spanOptions, context);
72
237
  }
73
- function setSpanError(span, error, options = {}) {
238
+ function recordSpanError(span, error) {
74
239
  if (!span) {
75
240
  return;
76
241
  }
77
242
  const exception = toOtelException(error);
78
243
  span.recordException(exception);
79
- if (!options.signal?.aborted || options.signal.reason !== error) {
244
+ if (!isAbortError(error)) {
80
245
  span.setStatus({
81
246
  code: SPAN_ERROR_STATUS,
82
247
  message: exception.message
83
248
  });
84
249
  }
85
250
  }
86
- function setSpanAttribute(span, key, value) {
251
+ function setSpanAttributeIfDefined(span, key, value) {
87
252
  if (!span || value === void 0) {
88
253
  return;
89
254
  }
@@ -121,29 +286,32 @@ function toSpanAttributeValue(data) {
121
286
  return String(data);
122
287
  }
123
288
  }
124
- async function runWithSpan({ name, context, ...options }, fn) {
125
- const tracer = getGlobalOtelConfig()?.tracer;
289
+ async function runWithSpan(options, fn) {
290
+ const tracer = getOpenTelemetryConfig()?.tracer;
126
291
  if (!tracer) {
127
292
  return fn();
128
293
  }
294
+ if (typeof options === "string") {
295
+ options = { name: options };
296
+ }
129
297
  const callback = async (span) => {
130
298
  try {
131
299
  return await fn(span);
132
300
  } catch (e) {
133
- setSpanError(span, e, options);
301
+ recordSpanError(span, e);
134
302
  throw e;
135
303
  } finally {
136
304
  span.end();
137
305
  }
138
306
  };
139
- if (context) {
140
- return tracer.startActiveSpan(name, options, context, callback);
307
+ if (options.context) {
308
+ return tracer.startActiveSpan(options.name, options, options.context, callback);
141
309
  } else {
142
- return tracer.startActiveSpan(name, options, callback);
310
+ return tracer.startActiveSpan(options.name, options, callback);
143
311
  }
144
312
  }
145
313
  async function runInSpanContext(span, fn) {
146
- const otelConfig = getGlobalOtelConfig();
314
+ const otelConfig = getOpenTelemetryConfig();
147
315
  if (!span || !otelConfig) {
148
316
  return fn();
149
317
  }
@@ -155,15 +323,9 @@ class AsyncIdQueue {
155
323
  openIds = /* @__PURE__ */ new Set();
156
324
  queues = /* @__PURE__ */ new Map();
157
325
  waiters = /* @__PURE__ */ new Map();
158
- get length() {
326
+ get size() {
159
327
  return this.openIds.size;
160
328
  }
161
- get waiterIds() {
162
- return Array.from(this.waiters.keys());
163
- }
164
- hasBufferedItems(id) {
165
- return Boolean(this.queues.get(id)?.length);
166
- }
167
329
  open(id) {
168
330
  this.openIds.add(id);
169
331
  }
@@ -231,74 +393,54 @@ class AsyncIdQueue {
231
393
  }
232
394
  }
233
395
 
234
- function isAsyncIteratorObject(maybe) {
235
- if (!maybe || typeof maybe !== "object") {
236
- return false;
237
- }
238
- return "next" in maybe && typeof maybe.next === "function" && Symbol.asyncIterator in maybe && typeof maybe[Symbol.asyncIterator] === "function";
239
- }
240
- const fallbackAsyncDisposeSymbol = Symbol.for("asyncDispose");
241
- const asyncDisposeSymbol = Symbol.asyncDispose ?? fallbackAsyncDisposeSymbol;
242
- class AsyncIteratorClass {
243
- #isDone = false;
244
- #isExecuteComplete = false;
245
- #cleanup;
246
- #next;
247
- constructor(next, cleanup) {
248
- this.#cleanup = cleanup;
249
- this.#next = sequential(async () => {
250
- if (this.#isDone) {
251
- return { done: true, value: void 0 };
252
- }
396
+ function wrapAsyncIterator(iterator, { runWith, mapResult, mapError, onError, onFinish }) {
397
+ runWith ??= (run) => run();
398
+ let isDone;
399
+ return new AsyncIteratorClass(async () => {
400
+ try {
401
+ let result;
253
402
  try {
254
- const result = await next();
255
- if (result.done) {
256
- this.#isDone = true;
257
- }
258
- return result;
259
- } catch (err) {
260
- this.#isDone = true;
261
- throw err;
262
- } finally {
263
- if (this.#isDone && !this.#isExecuteComplete) {
264
- this.#isExecuteComplete = true;
265
- await this.#cleanup("next");
266
- }
403
+ result = await runWith(() => iterator.next());
404
+ isDone = result.done;
405
+ } catch (error) {
406
+ isDone = true;
407
+ throw error;
267
408
  }
268
- });
269
- }
270
- next() {
271
- return this.#next();
272
- }
273
- async return(value) {
274
- this.#isDone = true;
275
- if (!this.#isExecuteComplete) {
276
- this.#isExecuteComplete = true;
277
- await this.#cleanup("return");
409
+ return mapResult ? await mapResult(result) : result;
410
+ } catch (error) {
411
+ await onError?.(error);
412
+ throw mapError ? await mapError(error) : error;
278
413
  }
279
- return { done: true, value };
280
- }
281
- async throw(err) {
282
- this.#isDone = true;
283
- if (!this.#isExecuteComplete) {
284
- this.#isExecuteComplete = true;
285
- await this.#cleanup("throw");
414
+ }, async (_state) => {
415
+ try {
416
+ if (!isDone) {
417
+ try {
418
+ await runWith(async () => iterator.return?.());
419
+ } catch (error) {
420
+ await onError?.(error);
421
+ throw error;
422
+ }
423
+ }
424
+ } finally {
425
+ await onFinish?.();
286
426
  }
287
- throw err;
288
- }
289
- /**
290
- * asyncDispose symbol only available in esnext, we should fallback to Symbol.for('asyncDispose')
291
- */
292
- async [asyncDisposeSymbol]() {
293
- this.#isDone = true;
294
- if (!this.#isExecuteComplete) {
295
- this.#isExecuteComplete = true;
296
- await this.#cleanup("dispose");
427
+ });
428
+ }
429
+ function traceAsyncIterator(options, iterator) {
430
+ const getSpan = once(() => startSpan(options));
431
+ return wrapAsyncIterator(iterator, {
432
+ runWith: (run) => runInSpanContext(getSpan(), run),
433
+ mapResult(result) {
434
+ getSpan()?.addEvent(result.done ? "completed" : "yielded");
435
+ return result;
436
+ },
437
+ onError(error) {
438
+ recordSpanError(getSpan(), error);
439
+ },
440
+ onFinish() {
441
+ getSpan()?.end();
297
442
  }
298
- }
299
- [Symbol.asyncIterator]() {
300
- return this;
301
- }
443
+ });
302
444
  }
303
445
  function replicateAsyncIterator(source, count) {
304
446
  const queue = new AsyncIdQueue();
@@ -338,9 +480,9 @@ function replicateAsyncIterator(source, count) {
338
480
  }
339
481
  throw item.error;
340
482
  },
341
- async (reason) => {
342
- queue.close({ id });
343
- if (reason !== "next" && !queue.length && !isSourceFinished) {
483
+ async ({ kind, error }) => {
484
+ queue.close({ id, reason: error });
485
+ if (kind === "cancelled" && !queue.size && !isSourceFinished) {
344
486
  isSourceFinished = true;
345
487
  await source?.return?.();
346
488
  }
@@ -349,189 +491,6 @@ function replicateAsyncIterator(source, count) {
349
491
  });
350
492
  return replicated;
351
493
  }
352
- function asyncIteratorWithSpan({ name, ...options }, iterator) {
353
- let span;
354
- return new AsyncIteratorClass(
355
- async () => {
356
- span ??= startSpan(name);
357
- try {
358
- const result = await runInSpanContext(span, () => iterator.next());
359
- span?.addEvent(result.done ? "completed" : "yielded");
360
- return result;
361
- } catch (err) {
362
- setSpanError(span, err, options);
363
- throw err;
364
- }
365
- },
366
- async (reason) => {
367
- try {
368
- if (reason !== "next") {
369
- await runInSpanContext(span, () => iterator.return?.());
370
- }
371
- } catch (err) {
372
- setSpanError(span, err, options);
373
- throw err;
374
- } finally {
375
- span?.end();
376
- }
377
- }
378
- );
379
- }
380
-
381
- class EventPublisher {
382
- #listenersMap = /* @__PURE__ */ new Map();
383
- #maxBufferedEvents;
384
- constructor(options = {}) {
385
- this.#maxBufferedEvents = options.maxBufferedEvents ?? 100;
386
- }
387
- get size() {
388
- return this.#listenersMap.size;
389
- }
390
- /**
391
- * Emits an event and delivers the payload to all subscribed listeners.
392
- */
393
- publish(event, payload) {
394
- const listeners = this.#listenersMap.get(event);
395
- if (!listeners) {
396
- return;
397
- }
398
- for (const listener of listeners) {
399
- listener(payload);
400
- }
401
- }
402
- subscribe(event, listenerOrOptions) {
403
- if (typeof listenerOrOptions === "function") {
404
- let listeners = this.#listenersMap.get(event);
405
- if (!listeners) {
406
- this.#listenersMap.set(event, listeners = []);
407
- }
408
- listeners.push(listenerOrOptions);
409
- return once(() => {
410
- listeners.splice(listeners.indexOf(listenerOrOptions), 1);
411
- if (listeners.length === 0) {
412
- this.#listenersMap.delete(event);
413
- }
414
- });
415
- }
416
- const signal = listenerOrOptions?.signal;
417
- const maxBufferedEvents = listenerOrOptions?.maxBufferedEvents ?? this.#maxBufferedEvents;
418
- signal?.throwIfAborted();
419
- const bufferedEvents = [];
420
- const pullResolvers = [];
421
- const unsubscribe = this.subscribe(event, (payload) => {
422
- const resolver = pullResolvers.shift();
423
- if (resolver) {
424
- resolver[0]({ done: false, value: payload });
425
- } else {
426
- bufferedEvents.push(payload);
427
- if (bufferedEvents.length > maxBufferedEvents) {
428
- bufferedEvents.shift();
429
- }
430
- }
431
- });
432
- const abortListener = (event2) => {
433
- unsubscribe();
434
- pullResolvers.forEach((resolver) => resolver[1](event2.target.reason));
435
- pullResolvers.length = 0;
436
- bufferedEvents.length = 0;
437
- };
438
- signal?.addEventListener("abort", abortListener, { once: true });
439
- return new AsyncIteratorClass(async () => {
440
- if (signal?.aborted) {
441
- throw signal.reason;
442
- }
443
- if (bufferedEvents.length > 0) {
444
- return { done: false, value: bufferedEvents.shift() };
445
- }
446
- return new Promise((resolve, reject) => {
447
- pullResolvers.push([resolve, reject]);
448
- });
449
- }, async () => {
450
- unsubscribe();
451
- signal?.removeEventListener("abort", abortListener);
452
- pullResolvers.forEach((resolver) => resolver[0]({ done: true, value: void 0 }));
453
- pullResolvers.length = 0;
454
- bufferedEvents.length = 0;
455
- });
456
- }
457
- }
458
-
459
- class SequentialIdGenerator {
460
- index = BigInt(1);
461
- generate() {
462
- const id = this.index.toString(36);
463
- this.index++;
464
- return id;
465
- }
466
- }
467
- function compareSequentialIds(a, b) {
468
- if (a.length !== b.length) {
469
- return a.length - b.length;
470
- }
471
- return a < b ? -1 : a > b ? 1 : 0;
472
- }
473
-
474
- function onStart(callback) {
475
- return async (options, ...rest) => {
476
- await callback(options, ...rest);
477
- return await options.next();
478
- };
479
- }
480
- function onSuccess(callback) {
481
- return async (options, ...rest) => {
482
- const result = await options.next();
483
- await callback(result, options, ...rest);
484
- return result;
485
- };
486
- }
487
- function onError(callback) {
488
- return async (options, ...rest) => {
489
- try {
490
- return await options.next();
491
- } catch (error) {
492
- await callback(error, options, ...rest);
493
- throw error;
494
- }
495
- };
496
- }
497
- function onFinish(callback) {
498
- let state;
499
- return async (options, ...rest) => {
500
- try {
501
- const result = await options.next();
502
- state = [null, result, true];
503
- return result;
504
- } catch (error) {
505
- state = [error, void 0, false];
506
- throw error;
507
- } finally {
508
- await callback(state, options, ...rest);
509
- }
510
- };
511
- }
512
- function intercept(interceptors, options, main) {
513
- const next = (options2, index) => {
514
- const interceptor = interceptors[index];
515
- if (!interceptor) {
516
- return main(options2);
517
- }
518
- return interceptor({
519
- ...options2,
520
- next: (newOptions = options2) => next(newOptions, index + 1)
521
- });
522
- };
523
- return next(options, 0);
524
- }
525
-
526
- function parseEmptyableJSON(text) {
527
- if (!text) {
528
- return void 0;
529
- }
530
- return JSON.parse(text);
531
- }
532
- function stringifyJSON(value) {
533
- return JSON.stringify(value);
534
- }
535
494
 
536
495
  function findDeepMatches(check, payload, segments = [], maps = [], values = []) {
537
496
  if (check(payload)) {
@@ -541,7 +500,7 @@ function findDeepMatches(check, payload, segments = [], maps = [], values = [])
541
500
  payload.forEach((v, i) => {
542
501
  findDeepMatches(check, v, [...segments, i], maps, values);
543
502
  });
544
- } else if (isObject(payload)) {
503
+ } else if (isPlainObject(payload)) {
545
504
  for (const key in payload) {
546
505
  findDeepMatches(check, payload[key], [...segments, key], maps, values);
547
506
  }
@@ -554,21 +513,47 @@ function getConstructor(value) {
554
513
  }
555
514
  return Object.getPrototypeOf(value)?.constructor;
556
515
  }
557
- function isObject(value) {
516
+ function isPlainObject(value) {
558
517
  if (!value || typeof value !== "object") {
559
518
  return false;
560
519
  }
561
520
  const proto = Object.getPrototypeOf(value);
562
521
  return proto === Object.prototype || !proto || !proto.constructor;
563
522
  }
564
- function isTypescriptObject(value) {
565
- return !!value && (typeof value === "object" || typeof value === "function");
523
+ function get(object, path) {
524
+ let current = object;
525
+ for (const key of path) {
526
+ if (!isTypescriptObject(current)) {
527
+ return void 0;
528
+ }
529
+ current = current[key];
530
+ }
531
+ return current;
532
+ }
533
+ function set(root, path, value) {
534
+ let current = root;
535
+ for (let i = 0; i < path.length - 1; i++) {
536
+ const key = path[i];
537
+ const next = current[key];
538
+ if (!isTypescriptObject(next)) {
539
+ current[key] = {};
540
+ }
541
+ current = current[key];
542
+ }
543
+ current[path.at(-1)] = value;
544
+ }
545
+ function omit(obj, keys) {
546
+ const result = { ...obj };
547
+ for (const key of keys) {
548
+ delete result[key];
549
+ }
550
+ return result;
566
551
  }
567
552
  function clone(value) {
568
553
  if (Array.isArray(value)) {
569
554
  return value.map(clone);
570
555
  }
571
- if (isObject(value)) {
556
+ if (isPlainObject(value)) {
572
557
  const result = {};
573
558
  for (const key in value) {
574
559
  result[key] = clone(value[key]);
@@ -580,16 +565,6 @@ function clone(value) {
580
565
  }
581
566
  return value;
582
567
  }
583
- function get(object, path) {
584
- let current = object;
585
- for (const key of path) {
586
- if (!isTypescriptObject(current)) {
587
- return void 0;
588
- }
589
- current = current[key];
590
- }
591
- return current;
592
- }
593
568
  function isPropertyKey(value) {
594
569
  const type = typeof value;
595
570
  return type === "string" || type === "number" || type === "symbol";
@@ -601,54 +576,132 @@ const NullProtoObj = /* @__PURE__ */ (() => {
601
576
  Object.freeze(e.prototype);
602
577
  return e;
603
578
  })();
604
-
605
- function value(value2, ...args) {
606
- if (typeof value2 === "function") {
607
- return value2(...args);
579
+ function bindMethods(obj) {
580
+ const methods = new NullProtoObj();
581
+ let current = obj;
582
+ while (current && current !== Object.prototype) {
583
+ for (const key of Object.getOwnPropertyNames(current)) {
584
+ if (key === "constructor" || key in methods) {
585
+ continue;
586
+ }
587
+ const val = obj[key];
588
+ if (typeof val === "function") {
589
+ methods[key] = val.bind(obj);
590
+ }
591
+ }
592
+ for (const sym of Object.getOwnPropertySymbols(current)) {
593
+ if (sym in methods) {
594
+ continue;
595
+ }
596
+ const val = obj[sym];
597
+ if (typeof val === "function") {
598
+ methods[sym] = val.bind(obj);
599
+ }
600
+ }
601
+ current = Object.getPrototypeOf(current);
608
602
  }
609
- return value2;
610
- }
611
- function fallback(value2, fallback2) {
612
- return value2 === void 0 ? fallback2 : value2;
603
+ return methods;
613
604
  }
614
605
 
615
- function preventNativeAwait(target) {
616
- return new Proxy(target, {
617
- get(target2, prop, receiver) {
618
- const value2 = Reflect.get(target2, prop, receiver);
619
- if (prop !== "then" || typeof value2 !== "function") {
620
- return value2;
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
+ }
621
636
  }
622
- return new Proxy(value2, {
623
- apply(targetFn, thisArg, args) {
624
- if (args.length !== 2 || args.some((arg) => !isNativeFunction(arg))) {
625
- return Reflect.apply(targetFn, thisArg, args);
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);
626
648
  }
627
- let shouldOmit = true;
628
- args[0].call(thisArg, preventNativeAwait(new Proxy(target2, {
629
- get: (target3, prop2, receiver2) => {
630
- if (shouldOmit && prop2 === "then") {
631
- shouldOmit = false;
632
- return void 0;
633
- }
634
- return Reflect.get(target3, prop2, receiver2);
635
- }
636
- })));
637
649
  }
638
- });
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}"`);
639
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
+ function promiseWithResolvers() {
685
+ const result = {};
686
+ result.promise = new Promise((resolve, reject) => {
687
+ result.resolve = resolve;
688
+ result.reject = reject;
640
689
  });
690
+ return result;
641
691
  }
642
- const NATIVE_FUNCTION_REGEX = /^\s*function\s*\(\)\s*\{\s*\[native code\]\s*\}\s*$/;
643
- function isNativeFunction(fn) {
644
- return typeof fn === "function" && NATIVE_FUNCTION_REGEX.test(fn.toString());
692
+
693
+ function value(value2, ...args) {
694
+ if (typeof value2 === "function") {
695
+ return value2(...args);
696
+ }
697
+ return value2;
645
698
  }
646
- function overlayProxy(target, partial) {
699
+
700
+ function override(target, partial) {
647
701
  const proxy = new Proxy(typeof target === "function" ? partial : target, {
648
702
  get(_, prop) {
649
703
  const targetValue = prop in partial ? partial : value(target);
650
- const v = Reflect.get(targetValue, prop);
651
- return typeof v === "function" ? v.bind(targetValue) : v;
704
+ return getOrBind(targetValue, prop);
652
705
  },
653
706
  has(_, prop) {
654
707
  return Reflect.has(partial, prop) || Reflect.has(value(target), prop);
@@ -657,14 +710,150 @@ function overlayProxy(target, partial) {
657
710
  return proxy;
658
711
  }
659
712
 
660
- function streamToAsyncIteratorClass(stream) {
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
+ function replicateReadableStream(stream, count) {
757
+ if (count <= 0) {
758
+ return [];
759
+ }
760
+ const replicated = [];
761
+ let pending = stream;
762
+ for (let index = 0; index < count - 1; index++) {
763
+ const [replica, remainder] = pending.tee();
764
+ replicated.push(replica);
765
+ pending = remainder;
766
+ }
767
+ replicated.push(pending);
768
+ return replicated;
769
+ }
770
+ function wrapReadableStream(stream, { runWith, mapResult, mapError, onError, onFinish }) {
771
+ runWith ??= (run) => run();
772
+ const reader = once(() => stream.getReader());
773
+ const finish = once(async () => onFinish?.());
774
+ return new ReadableStream({
775
+ async pull(controller) {
776
+ let result;
777
+ try {
778
+ const readResult = await runWith(() => reader().read());
779
+ result = mapResult ? await mapResult(readResult) : readResult;
780
+ } catch (error) {
781
+ try {
782
+ await onError?.(error);
783
+ controller.error(mapError ? await mapError(error) : error);
784
+ } finally {
785
+ await finish();
786
+ }
787
+ return;
788
+ }
789
+ if (result.done) {
790
+ controller.close();
791
+ await finish();
792
+ } else {
793
+ controller.enqueue(result.value);
794
+ }
795
+ },
796
+ async cancel(reason) {
797
+ try {
798
+ try {
799
+ await runWith(() => reader().cancel(reason));
800
+ } catch (error) {
801
+ await onError?.(error);
802
+ throw error;
803
+ }
804
+ } finally {
805
+ await finish();
806
+ }
807
+ }
808
+ });
809
+ }
810
+ function traceReadableStream(options, stream) {
811
+ const getSpan = once(() => startSpan(options));
812
+ return wrapReadableStream(stream, {
813
+ runWith: (run) => runInSpanContext(getSpan(), run),
814
+ mapResult(result) {
815
+ getSpan()?.addEvent(result.done ? "closed" : "enqueued");
816
+ return result;
817
+ },
818
+ onError(error) {
819
+ recordSpanError(getSpan(), error);
820
+ },
821
+ onFinish() {
822
+ getSpan()?.end();
823
+ }
824
+ });
825
+ }
826
+ function streamToAsyncIteratorClass(stream, { signal } = {}) {
661
827
  const reader = stream.getReader();
828
+ let cancelledBySignal = false;
662
829
  return new AsyncIteratorClass(
663
830
  async () => {
664
- return reader.read();
831
+ if (signal?.aborted) {
832
+ cancelledBySignal = true;
833
+ throw signal.reason;
834
+ }
835
+ if (!signal) {
836
+ return reader.read();
837
+ }
838
+ const { promise, reject } = promiseWithResolvers();
839
+ const onAbort = () => reject(signal.reason);
840
+ signal.addEventListener("abort", onAbort, { once: true });
841
+ try {
842
+ return await Promise.race([
843
+ reader.read(),
844
+ promise.catch(async (reason) => {
845
+ cancelledBySignal = true;
846
+ throw reason;
847
+ })
848
+ ]);
849
+ } finally {
850
+ signal.removeEventListener("abort", onAbort);
851
+ }
665
852
  },
666
- async () => {
667
- await reader.cancel();
853
+ async ({ kind, error }) => {
854
+ if (kind === "cancelled" || kind === "error" && cancelledBySignal) {
855
+ await reader.cancel(error);
856
+ }
668
857
  }
669
858
  );
670
859
  }
@@ -690,7 +879,7 @@ function asyncIteratorToUnproxiedDataStream(iterator) {
690
879
  if (done) {
691
880
  controller.close();
692
881
  } else {
693
- const unproxied = isObject(value) ? { ...value } : Array.isArray(value) ? value.map((i) => i) : value;
882
+ const unproxied = isPlainObject(value) ? { ...value } : Array.isArray(value) ? value.map((i) => i) : value;
694
883
  controller.enqueue(unproxied);
695
884
  }
696
885
  },
@@ -700,12 +889,4 @@ function asyncIteratorToUnproxiedDataStream(iterator) {
700
889
  });
701
890
  }
702
891
 
703
- function tryDecodeURIComponent(value) {
704
- try {
705
- return decodeURIComponent(value);
706
- } catch {
707
- return value;
708
- }
709
- }
710
-
711
- export { AbortError, AsyncIdQueue, AsyncIteratorClass, EventPublisher, NullProtoObj, ORPC_NAME, ORPC_SHARED_PACKAGE_NAME, ORPC_SHARED_PACKAGE_VERSION, SequentialIdGenerator, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, asyncIteratorWithSpan, clone, compareSequentialIds, defer, fallback, findDeepMatches, get, getConstructor, getGlobalOtelConfig, intercept, isAsyncIteratorObject, isObject, isPropertyKey, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, overlayProxy, parseEmptyableJSON, preventNativeAwait, readAsBuffer, replicateAsyncIterator, resolveMaybeOptionalOptions, runInSpanContext, runWithSpan, sequential, setGlobalOtelConfig, setSpanAttribute, setSpanError, splitInHalf, startSpan, streamToAsyncIteratorClass, stringifyJSON, toArray, toOtelException, toSpanAttributeValue, tryDecodeURIComponent, value };
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 };