@graphql-tools/executor 1.3.9 → 1.3.10-alpha-20241220133031-cfab60caa8f85f373e84a3aaa788c633be066072

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.
@@ -60,6 +60,29 @@ function execute(args) {
60
60
  }
61
61
  return executeImpl(exeContext);
62
62
  }
63
+ // AbortSignal handler cache to avoid the "possible EventEmitter memory leak detected"
64
+ // on Node.js
65
+ const abortSignalHandlers = new WeakMap();
66
+ /**
67
+ * Register an AbortSignal handler for a signal.
68
+ * This helper function mainly exists to work around the
69
+ * "possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit."
70
+ * warning occuring on Node.js
71
+ */
72
+ function registerAbortSignalHandler(signal, handler) {
73
+ let handlers = abortSignalHandlers.get(signal);
74
+ if (!Array.isArray(handlers)) {
75
+ handlers = new Set();
76
+ abortSignalHandlers.set(signal, handlers);
77
+ function abortSignalHandler() {
78
+ for (const handler of handlers) {
79
+ handler();
80
+ }
81
+ }
82
+ signal.addEventListener('abort', abortSignalHandler, { once: true });
83
+ }
84
+ handlers.add(handler);
85
+ }
63
86
  function executeImpl(exeContext) {
64
87
  if (exeContext.signal?.aborted) {
65
88
  throw exeContext.signal.reason;
@@ -500,9 +523,11 @@ function getStreamValues(exeContext, fieldNodes, path) {
500
523
  * recursively until all the results are completed.
501
524
  */
502
525
  async function completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info, path, iterator, asyncPayloadRecord) {
503
- exeContext.signal?.addEventListener('abort', () => {
504
- iterator.return?.();
505
- }, { once: true });
526
+ if (exeContext.signal) {
527
+ registerAbortSignalHandler(exeContext.signal, () => {
528
+ iterator.return?.();
529
+ });
530
+ }
506
531
  const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
507
532
  const stream = getStreamValues(exeContext, fieldNodes, path);
508
533
  let containsPromise = false;
@@ -963,9 +988,11 @@ function assertEventStream(result, signal) {
963
988
  return {
964
989
  [Symbol.asyncIterator]() {
965
990
  const asyncIterator = result[Symbol.asyncIterator]();
966
- signal?.addEventListener('abort', () => {
967
- asyncIterator.return?.();
968
- });
991
+ if (signal) {
992
+ registerAbortSignalHandler(signal, () => {
993
+ asyncIterator.return?.();
994
+ });
995
+ }
969
996
  return asyncIterator;
970
997
  },
971
998
  };
@@ -1189,10 +1216,12 @@ function getCompletedIncrementalResults(exeContext) {
1189
1216
  function yieldSubsequentPayloads(exeContext) {
1190
1217
  let isDone = false;
1191
1218
  const abortPromise = new Promise((_, reject) => {
1192
- exeContext.signal?.addEventListener('abort', () => {
1193
- isDone = true;
1194
- reject(exeContext.signal?.reason);
1195
- }, { once: true });
1219
+ if (exeContext.signal) {
1220
+ registerAbortSignalHandler(exeContext.signal, () => {
1221
+ isDone = true;
1222
+ reject(exeContext.signal?.reason);
1223
+ });
1224
+ }
1196
1225
  });
1197
1226
  async function next() {
1198
1227
  if (isDone) {
@@ -48,6 +48,29 @@ export function execute(args) {
48
48
  }
49
49
  return executeImpl(exeContext);
50
50
  }
51
+ // AbortSignal handler cache to avoid the "possible EventEmitter memory leak detected"
52
+ // on Node.js
53
+ const abortSignalHandlers = new WeakMap();
54
+ /**
55
+ * Register an AbortSignal handler for a signal.
56
+ * This helper function mainly exists to work around the
57
+ * "possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit."
58
+ * warning occuring on Node.js
59
+ */
60
+ function registerAbortSignalHandler(signal, handler) {
61
+ let handlers = abortSignalHandlers.get(signal);
62
+ if (!Array.isArray(handlers)) {
63
+ handlers = new Set();
64
+ abortSignalHandlers.set(signal, handlers);
65
+ function abortSignalHandler() {
66
+ for (const handler of handlers) {
67
+ handler();
68
+ }
69
+ }
70
+ signal.addEventListener('abort', abortSignalHandler, { once: true });
71
+ }
72
+ handlers.add(handler);
73
+ }
51
74
  function executeImpl(exeContext) {
52
75
  if (exeContext.signal?.aborted) {
53
76
  throw exeContext.signal.reason;
@@ -488,9 +511,11 @@ function getStreamValues(exeContext, fieldNodes, path) {
488
511
  * recursively until all the results are completed.
489
512
  */
490
513
  async function completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info, path, iterator, asyncPayloadRecord) {
491
- exeContext.signal?.addEventListener('abort', () => {
492
- iterator.return?.();
493
- }, { once: true });
514
+ if (exeContext.signal) {
515
+ registerAbortSignalHandler(exeContext.signal, () => {
516
+ iterator.return?.();
517
+ });
518
+ }
494
519
  const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
495
520
  const stream = getStreamValues(exeContext, fieldNodes, path);
496
521
  let containsPromise = false;
@@ -949,9 +974,11 @@ function assertEventStream(result, signal) {
949
974
  return {
950
975
  [Symbol.asyncIterator]() {
951
976
  const asyncIterator = result[Symbol.asyncIterator]();
952
- signal?.addEventListener('abort', () => {
953
- asyncIterator.return?.();
954
- });
977
+ if (signal) {
978
+ registerAbortSignalHandler(signal, () => {
979
+ asyncIterator.return?.();
980
+ });
981
+ }
955
982
  return asyncIterator;
956
983
  },
957
984
  };
@@ -1175,10 +1202,12 @@ function getCompletedIncrementalResults(exeContext) {
1175
1202
  function yieldSubsequentPayloads(exeContext) {
1176
1203
  let isDone = false;
1177
1204
  const abortPromise = new Promise((_, reject) => {
1178
- exeContext.signal?.addEventListener('abort', () => {
1179
- isDone = true;
1180
- reject(exeContext.signal?.reason);
1181
- }, { once: true });
1205
+ if (exeContext.signal) {
1206
+ registerAbortSignalHandler(exeContext.signal, () => {
1207
+ isDone = true;
1208
+ reject(exeContext.signal?.reason);
1209
+ });
1210
+ }
1182
1211
  });
1183
1212
  async function next() {
1184
1213
  if (isDone) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-tools/executor",
3
- "version": "1.3.9",
3
+ "version": "1.3.10-alpha-20241220133031-cfab60caa8f85f373e84a3aaa788c633be066072",
4
4
  "sideEffects": false,
5
5
  "peerDependencies": {
6
6
  "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"