@graphql-tools/executor 1.2.6 → 2.0.0-alpha-20240606144658-8963c8b8f661638eaee0e101a55f3b6e46cc03ff

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.
Files changed (49) hide show
  1. package/cjs/execution/AccumulatorMap.js +21 -0
  2. package/cjs/execution/BoxedPromiseOrValue.js +25 -0
  3. package/cjs/execution/IncrementalGraph.js +271 -0
  4. package/cjs/execution/IncrementalPublisher.js +274 -0
  5. package/cjs/execution/buildFieldPlan.js +62 -0
  6. package/cjs/execution/collectFields.js +174 -0
  7. package/cjs/execution/execute.js +548 -513
  8. package/cjs/execution/getBySet.js +13 -0
  9. package/cjs/execution/isSameSet.js +15 -0
  10. package/cjs/execution/promiseWithResolvers.js +18 -0
  11. package/cjs/execution/types.js +19 -0
  12. package/esm/execution/AccumulatorMap.js +17 -0
  13. package/esm/execution/BoxedPromiseOrValue.js +21 -0
  14. package/esm/execution/IncrementalGraph.js +267 -0
  15. package/esm/execution/IncrementalPublisher.js +270 -0
  16. package/esm/execution/buildFieldPlan.js +58 -0
  17. package/esm/execution/collectFields.js +169 -0
  18. package/esm/execution/execute.js +549 -514
  19. package/esm/execution/getBySet.js +9 -0
  20. package/esm/execution/isSameSet.js +11 -0
  21. package/esm/execution/promiseWithResolvers.js +14 -0
  22. package/esm/execution/types.js +12 -0
  23. package/package.json +2 -2
  24. package/typings/execution/AccumulatorMap.d.cts +7 -0
  25. package/typings/execution/AccumulatorMap.d.ts +7 -0
  26. package/typings/execution/BoxedPromiseOrValue.d.cts +15 -0
  27. package/typings/execution/BoxedPromiseOrValue.d.ts +15 -0
  28. package/typings/execution/IncrementalGraph.d.cts +32 -0
  29. package/typings/execution/IncrementalGraph.d.ts +32 -0
  30. package/typings/execution/IncrementalPublisher.d.cts +8 -0
  31. package/typings/execution/IncrementalPublisher.d.ts +8 -0
  32. package/typings/execution/buildFieldPlan.d.cts +7 -0
  33. package/typings/execution/buildFieldPlan.d.ts +7 -0
  34. package/typings/execution/collectFields.d.cts +40 -0
  35. package/typings/execution/collectFields.d.ts +40 -0
  36. package/typings/execution/execute.d.cts +8 -106
  37. package/typings/execution/execute.d.ts +8 -106
  38. package/typings/execution/getBySet.d.cts +1 -0
  39. package/typings/execution/getBySet.d.ts +1 -0
  40. package/typings/execution/isSameSet.d.cts +1 -0
  41. package/typings/execution/isSameSet.d.ts +1 -0
  42. package/typings/execution/promiseWithResolvers.d.cts +10 -0
  43. package/typings/execution/promiseWithResolvers.d.ts +10 -0
  44. package/typings/execution/types.d.cts +155 -0
  45. package/typings/execution/types.d.ts +155 -0
  46. package/cjs/execution/flattenAsyncIterable.js +0 -89
  47. package/esm/execution/flattenAsyncIterable.js +0 -85
  48. package/typings/execution/flattenAsyncIterable.d.cts +0 -7
  49. package/typings/execution/flattenAsyncIterable.d.ts +0 -7
@@ -0,0 +1,155 @@
1
+ import type { GraphQLError, GraphQLFormattedError } from 'graphql';
2
+ import type { Path } from '@graphql-tools/utils';
3
+ import type { BoxedPromiseOrValue } from './BoxedPromiseOrValue.cjs';
4
+ /**
5
+ * The result of GraphQL execution.
6
+ *
7
+ * - `errors` is included when any errors occurred as a non-empty array.
8
+ * - `data` is the result of a successful execution of the query.
9
+ * - `hasNext` is true if a future payload is expected.
10
+ * - `extensions` is reserved for adding non-standard properties.
11
+ * - `incremental` is a list of the results from defer/stream directives.
12
+ */
13
+ export interface SingularExecutionResult<TData = any, TExtensions = any> {
14
+ errors?: ReadonlyArray<GraphQLError>;
15
+ data?: TData | null;
16
+ extensions?: TExtensions;
17
+ }
18
+ export interface FormattedExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> {
19
+ errors?: ReadonlyArray<GraphQLFormattedError>;
20
+ data?: TData | null;
21
+ extensions?: TExtensions;
22
+ }
23
+ export interface IncrementalExecutionResults<TData = unknown, TExtensions = Record<string, unknown>> {
24
+ initialResult: InitialIncrementalExecutionResult<TData, TExtensions>;
25
+ subsequentResults: AsyncGenerator<SubsequentIncrementalExecutionResult<TData, TExtensions>, void, void>;
26
+ }
27
+ export interface InitialIncrementalExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends SingularExecutionResult<TData, TExtensions> {
28
+ data: TData;
29
+ pending: ReadonlyArray<PendingResult>;
30
+ hasNext: true;
31
+ extensions?: TExtensions;
32
+ }
33
+ export interface FormattedInitialIncrementalExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends FormattedExecutionResult<TData, TExtensions> {
34
+ data: TData;
35
+ pending: ReadonlyArray<PendingResult>;
36
+ hasNext: boolean;
37
+ extensions?: TExtensions;
38
+ }
39
+ export interface SubsequentIncrementalExecutionResult<TData = unknown, TExtensions = Record<string, unknown>> {
40
+ pending?: ReadonlyArray<PendingResult>;
41
+ incremental?: ReadonlyArray<IncrementalResult<TData, TExtensions>>;
42
+ completed?: ReadonlyArray<CompletedResult>;
43
+ hasNext: boolean;
44
+ extensions?: TExtensions;
45
+ }
46
+ export interface FormattedSubsequentIncrementalExecutionResult<TData = unknown, TExtensions = Record<string, unknown>> {
47
+ hasNext: boolean;
48
+ pending?: ReadonlyArray<PendingResult>;
49
+ incremental?: ReadonlyArray<FormattedIncrementalResult<TData, TExtensions>>;
50
+ completed?: ReadonlyArray<FormattedCompletedResult>;
51
+ extensions?: TExtensions;
52
+ }
53
+ interface BareDeferredGroupedFieldSetResult<TData = Record<string, unknown>> {
54
+ errors?: ReadonlyArray<GraphQLError>;
55
+ data: TData;
56
+ }
57
+ export interface IncrementalDeferResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends BareDeferredGroupedFieldSetResult<TData> {
58
+ id: string;
59
+ subPath?: ReadonlyArray<string | number>;
60
+ extensions?: TExtensions;
61
+ }
62
+ export interface FormattedIncrementalDeferResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> {
63
+ errors?: ReadonlyArray<GraphQLFormattedError>;
64
+ data: TData;
65
+ id: string;
66
+ subPath?: ReadonlyArray<string | number>;
67
+ extensions?: TExtensions;
68
+ }
69
+ interface BareStreamItemsResult<TData = ReadonlyArray<unknown>> {
70
+ errors?: ReadonlyArray<GraphQLError>;
71
+ items: TData;
72
+ }
73
+ export interface IncrementalStreamResult<TData = ReadonlyArray<unknown>, TExtensions = Record<string, unknown>> extends BareStreamItemsResult<TData> {
74
+ id: string;
75
+ subPath?: ReadonlyArray<string | number>;
76
+ extensions?: TExtensions;
77
+ }
78
+ export interface FormattedIncrementalStreamResult<TData = Array<unknown>, TExtensions = Record<string, unknown>> {
79
+ errors?: ReadonlyArray<GraphQLFormattedError>;
80
+ items: TData;
81
+ id: string;
82
+ subPath?: ReadonlyArray<string | number>;
83
+ extensions?: TExtensions;
84
+ }
85
+ export type IncrementalResult<TData = unknown, TExtensions = Record<string, unknown>> = IncrementalDeferResult<TData, TExtensions> | IncrementalStreamResult<TData, TExtensions>;
86
+ export type FormattedIncrementalResult<TData = unknown, TExtensions = Record<string, unknown>> = FormattedIncrementalDeferResult<TData, TExtensions> | FormattedIncrementalStreamResult<TData, TExtensions>;
87
+ export interface PendingResult {
88
+ id: string;
89
+ path: ReadonlyArray<string | number>;
90
+ label?: string;
91
+ }
92
+ export interface CompletedResult {
93
+ id: string;
94
+ errors?: ReadonlyArray<GraphQLError>;
95
+ }
96
+ export interface FormattedCompletedResult {
97
+ path: ReadonlyArray<string | number>;
98
+ label?: string;
99
+ errors?: ReadonlyArray<GraphQLError>;
100
+ }
101
+ export declare function isDeferredGroupedFieldSetRecord(incrementalDataRecord: IncrementalDataRecord): incrementalDataRecord is DeferredGroupedFieldSetRecord;
102
+ export type DeferredGroupedFieldSetResult = ReconcilableDeferredGroupedFieldSetResult | NonReconcilableDeferredGroupedFieldSetResult;
103
+ export declare function isDeferredGroupedFieldSetResult(subsequentResult: DeferredGroupedFieldSetResult | StreamItemsResult): subsequentResult is DeferredGroupedFieldSetResult;
104
+ export interface ReconcilableDeferredGroupedFieldSetResult {
105
+ deferredGroupedFieldSetRecord: DeferredGroupedFieldSetRecord;
106
+ path: Array<string | number>;
107
+ result: BareDeferredGroupedFieldSetResult;
108
+ incrementalDataRecords: ReadonlyArray<IncrementalDataRecord> | undefined;
109
+ errors?: never;
110
+ }
111
+ interface NonReconcilableDeferredGroupedFieldSetResult {
112
+ deferredGroupedFieldSetRecord: DeferredGroupedFieldSetRecord;
113
+ path: Array<string | number>;
114
+ errors: ReadonlyArray<GraphQLError>;
115
+ result?: never;
116
+ }
117
+ export declare function isNonReconcilableDeferredGroupedFieldSetResult(deferredGroupedFieldSetResult: DeferredGroupedFieldSetResult): deferredGroupedFieldSetResult is NonReconcilableDeferredGroupedFieldSetResult;
118
+ export interface DeferredGroupedFieldSetRecord {
119
+ path: Path | undefined;
120
+ deferredFragmentRecords: ReadonlyArray<DeferredFragmentRecord>;
121
+ result: BoxedPromiseOrValue<DeferredGroupedFieldSetResult> | (() => BoxedPromiseOrValue<DeferredGroupedFieldSetResult>);
122
+ }
123
+ export type SubsequentResultRecord = DeferredFragmentRecord | StreamRecord;
124
+ export interface DeferredFragmentRecord {
125
+ path: Path | undefined;
126
+ label: string | undefined;
127
+ id?: string | undefined;
128
+ parent: DeferredFragmentRecord | undefined;
129
+ }
130
+ export interface StreamItemResult {
131
+ path: Path;
132
+ item?: unknown;
133
+ incrementalDataRecords?: ReadonlyArray<IncrementalDataRecord> | undefined;
134
+ errors?: ReadonlyArray<GraphQLError> | undefined;
135
+ }
136
+ export type StreamItemRecord = BoxedPromiseOrValue<StreamItemResult> | (() => BoxedPromiseOrValue<StreamItemResult>);
137
+ export interface StreamRecord {
138
+ path: Path;
139
+ label: string | undefined;
140
+ id?: string | undefined;
141
+ streamItemQueue: Array<StreamItemRecord>;
142
+ }
143
+ export interface StreamItemsResult {
144
+ streamRecord: StreamRecord;
145
+ result?: BareStreamItemsResult | undefined;
146
+ incrementalDataRecords?: ReadonlyArray<IncrementalDataRecord> | undefined;
147
+ errors?: ReadonlyArray<GraphQLError> | undefined;
148
+ }
149
+ export interface CancellableStreamRecord extends StreamRecord {
150
+ earlyReturn: () => Promise<unknown>;
151
+ }
152
+ export declare function isCancellableStreamRecord(subsequentResultRecord: SubsequentResultRecord): subsequentResultRecord is CancellableStreamRecord;
153
+ export type IncrementalDataRecord = DeferredGroupedFieldSetRecord | StreamRecord;
154
+ export type IncrementalDataRecordResult = DeferredGroupedFieldSetResult | StreamItemsResult;
155
+ export {};
@@ -0,0 +1,155 @@
1
+ import type { GraphQLError, GraphQLFormattedError } from 'graphql';
2
+ import type { Path } from '@graphql-tools/utils';
3
+ import type { BoxedPromiseOrValue } from './BoxedPromiseOrValue.js';
4
+ /**
5
+ * The result of GraphQL execution.
6
+ *
7
+ * - `errors` is included when any errors occurred as a non-empty array.
8
+ * - `data` is the result of a successful execution of the query.
9
+ * - `hasNext` is true if a future payload is expected.
10
+ * - `extensions` is reserved for adding non-standard properties.
11
+ * - `incremental` is a list of the results from defer/stream directives.
12
+ */
13
+ export interface SingularExecutionResult<TData = any, TExtensions = any> {
14
+ errors?: ReadonlyArray<GraphQLError>;
15
+ data?: TData | null;
16
+ extensions?: TExtensions;
17
+ }
18
+ export interface FormattedExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> {
19
+ errors?: ReadonlyArray<GraphQLFormattedError>;
20
+ data?: TData | null;
21
+ extensions?: TExtensions;
22
+ }
23
+ export interface IncrementalExecutionResults<TData = unknown, TExtensions = Record<string, unknown>> {
24
+ initialResult: InitialIncrementalExecutionResult<TData, TExtensions>;
25
+ subsequentResults: AsyncGenerator<SubsequentIncrementalExecutionResult<TData, TExtensions>, void, void>;
26
+ }
27
+ export interface InitialIncrementalExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends SingularExecutionResult<TData, TExtensions> {
28
+ data: TData;
29
+ pending: ReadonlyArray<PendingResult>;
30
+ hasNext: true;
31
+ extensions?: TExtensions;
32
+ }
33
+ export interface FormattedInitialIncrementalExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends FormattedExecutionResult<TData, TExtensions> {
34
+ data: TData;
35
+ pending: ReadonlyArray<PendingResult>;
36
+ hasNext: boolean;
37
+ extensions?: TExtensions;
38
+ }
39
+ export interface SubsequentIncrementalExecutionResult<TData = unknown, TExtensions = Record<string, unknown>> {
40
+ pending?: ReadonlyArray<PendingResult>;
41
+ incremental?: ReadonlyArray<IncrementalResult<TData, TExtensions>>;
42
+ completed?: ReadonlyArray<CompletedResult>;
43
+ hasNext: boolean;
44
+ extensions?: TExtensions;
45
+ }
46
+ export interface FormattedSubsequentIncrementalExecutionResult<TData = unknown, TExtensions = Record<string, unknown>> {
47
+ hasNext: boolean;
48
+ pending?: ReadonlyArray<PendingResult>;
49
+ incremental?: ReadonlyArray<FormattedIncrementalResult<TData, TExtensions>>;
50
+ completed?: ReadonlyArray<FormattedCompletedResult>;
51
+ extensions?: TExtensions;
52
+ }
53
+ interface BareDeferredGroupedFieldSetResult<TData = Record<string, unknown>> {
54
+ errors?: ReadonlyArray<GraphQLError>;
55
+ data: TData;
56
+ }
57
+ export interface IncrementalDeferResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends BareDeferredGroupedFieldSetResult<TData> {
58
+ id: string;
59
+ subPath?: ReadonlyArray<string | number>;
60
+ extensions?: TExtensions;
61
+ }
62
+ export interface FormattedIncrementalDeferResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> {
63
+ errors?: ReadonlyArray<GraphQLFormattedError>;
64
+ data: TData;
65
+ id: string;
66
+ subPath?: ReadonlyArray<string | number>;
67
+ extensions?: TExtensions;
68
+ }
69
+ interface BareStreamItemsResult<TData = ReadonlyArray<unknown>> {
70
+ errors?: ReadonlyArray<GraphQLError>;
71
+ items: TData;
72
+ }
73
+ export interface IncrementalStreamResult<TData = ReadonlyArray<unknown>, TExtensions = Record<string, unknown>> extends BareStreamItemsResult<TData> {
74
+ id: string;
75
+ subPath?: ReadonlyArray<string | number>;
76
+ extensions?: TExtensions;
77
+ }
78
+ export interface FormattedIncrementalStreamResult<TData = Array<unknown>, TExtensions = Record<string, unknown>> {
79
+ errors?: ReadonlyArray<GraphQLFormattedError>;
80
+ items: TData;
81
+ id: string;
82
+ subPath?: ReadonlyArray<string | number>;
83
+ extensions?: TExtensions;
84
+ }
85
+ export type IncrementalResult<TData = unknown, TExtensions = Record<string, unknown>> = IncrementalDeferResult<TData, TExtensions> | IncrementalStreamResult<TData, TExtensions>;
86
+ export type FormattedIncrementalResult<TData = unknown, TExtensions = Record<string, unknown>> = FormattedIncrementalDeferResult<TData, TExtensions> | FormattedIncrementalStreamResult<TData, TExtensions>;
87
+ export interface PendingResult {
88
+ id: string;
89
+ path: ReadonlyArray<string | number>;
90
+ label?: string;
91
+ }
92
+ export interface CompletedResult {
93
+ id: string;
94
+ errors?: ReadonlyArray<GraphQLError>;
95
+ }
96
+ export interface FormattedCompletedResult {
97
+ path: ReadonlyArray<string | number>;
98
+ label?: string;
99
+ errors?: ReadonlyArray<GraphQLError>;
100
+ }
101
+ export declare function isDeferredGroupedFieldSetRecord(incrementalDataRecord: IncrementalDataRecord): incrementalDataRecord is DeferredGroupedFieldSetRecord;
102
+ export type DeferredGroupedFieldSetResult = ReconcilableDeferredGroupedFieldSetResult | NonReconcilableDeferredGroupedFieldSetResult;
103
+ export declare function isDeferredGroupedFieldSetResult(subsequentResult: DeferredGroupedFieldSetResult | StreamItemsResult): subsequentResult is DeferredGroupedFieldSetResult;
104
+ export interface ReconcilableDeferredGroupedFieldSetResult {
105
+ deferredGroupedFieldSetRecord: DeferredGroupedFieldSetRecord;
106
+ path: Array<string | number>;
107
+ result: BareDeferredGroupedFieldSetResult;
108
+ incrementalDataRecords: ReadonlyArray<IncrementalDataRecord> | undefined;
109
+ errors?: never;
110
+ }
111
+ interface NonReconcilableDeferredGroupedFieldSetResult {
112
+ deferredGroupedFieldSetRecord: DeferredGroupedFieldSetRecord;
113
+ path: Array<string | number>;
114
+ errors: ReadonlyArray<GraphQLError>;
115
+ result?: never;
116
+ }
117
+ export declare function isNonReconcilableDeferredGroupedFieldSetResult(deferredGroupedFieldSetResult: DeferredGroupedFieldSetResult): deferredGroupedFieldSetResult is NonReconcilableDeferredGroupedFieldSetResult;
118
+ export interface DeferredGroupedFieldSetRecord {
119
+ path: Path | undefined;
120
+ deferredFragmentRecords: ReadonlyArray<DeferredFragmentRecord>;
121
+ result: BoxedPromiseOrValue<DeferredGroupedFieldSetResult> | (() => BoxedPromiseOrValue<DeferredGroupedFieldSetResult>);
122
+ }
123
+ export type SubsequentResultRecord = DeferredFragmentRecord | StreamRecord;
124
+ export interface DeferredFragmentRecord {
125
+ path: Path | undefined;
126
+ label: string | undefined;
127
+ id?: string | undefined;
128
+ parent: DeferredFragmentRecord | undefined;
129
+ }
130
+ export interface StreamItemResult {
131
+ path: Path;
132
+ item?: unknown;
133
+ incrementalDataRecords?: ReadonlyArray<IncrementalDataRecord> | undefined;
134
+ errors?: ReadonlyArray<GraphQLError> | undefined;
135
+ }
136
+ export type StreamItemRecord = BoxedPromiseOrValue<StreamItemResult> | (() => BoxedPromiseOrValue<StreamItemResult>);
137
+ export interface StreamRecord {
138
+ path: Path;
139
+ label: string | undefined;
140
+ id?: string | undefined;
141
+ streamItemQueue: Array<StreamItemRecord>;
142
+ }
143
+ export interface StreamItemsResult {
144
+ streamRecord: StreamRecord;
145
+ result?: BareStreamItemsResult | undefined;
146
+ incrementalDataRecords?: ReadonlyArray<IncrementalDataRecord> | undefined;
147
+ errors?: ReadonlyArray<GraphQLError> | undefined;
148
+ }
149
+ export interface CancellableStreamRecord extends StreamRecord {
150
+ earlyReturn: () => Promise<unknown>;
151
+ }
152
+ export declare function isCancellableStreamRecord(subsequentResultRecord: SubsequentResultRecord): subsequentResultRecord is CancellableStreamRecord;
153
+ export type IncrementalDataRecord = DeferredGroupedFieldSetRecord | StreamRecord;
154
+ export type IncrementalDataRecordResult = DeferredGroupedFieldSetResult | StreamItemsResult;
155
+ export {};
@@ -1,89 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.flattenAsyncIterable = void 0;
4
- /**
5
- * Given an AsyncIterable of AsyncIterables, flatten all yielded results into a
6
- * single AsyncIterable.
7
- */
8
- function flattenAsyncIterable(iterable) {
9
- // You might think this whole function could be replaced with
10
- //
11
- // async function* flattenAsyncIterable(iterable) {
12
- // for await (const subIterator of iterable) {
13
- // yield* subIterator;
14
- // }
15
- // }
16
- //
17
- // but calling `.return()` on the iterator it returns won't interrupt the `for await`.
18
- const topIterator = iterable[Symbol.asyncIterator]();
19
- let currentNestedIterator;
20
- let waitForCurrentNestedIterator;
21
- let done = false;
22
- async function next() {
23
- if (done) {
24
- return { value: undefined, done: true };
25
- }
26
- try {
27
- if (!currentNestedIterator) {
28
- // Somebody else is getting it already.
29
- if (waitForCurrentNestedIterator) {
30
- await waitForCurrentNestedIterator;
31
- return await next();
32
- }
33
- // Nobody else is getting it. We should!
34
- let resolve;
35
- waitForCurrentNestedIterator = new Promise(r => {
36
- resolve = r;
37
- });
38
- const topIteratorResult = await topIterator.next();
39
- if (topIteratorResult.done) {
40
- // Given that done only ever transitions from false to true,
41
- // require-atomic-updates is being unnecessarily cautious.
42
- done = true;
43
- return await next();
44
- }
45
- // eslint is making a reasonable point here, but we've explicitly protected
46
- // ourself from the race condition by ensuring that only the single call
47
- // that assigns to waitForCurrentNestedIterator is allowed to assign to
48
- // currentNestedIterator or waitForCurrentNestedIterator.
49
- currentNestedIterator = topIteratorResult.value[Symbol.asyncIterator]();
50
- waitForCurrentNestedIterator = undefined;
51
- resolve();
52
- return await next();
53
- }
54
- const rememberCurrentNestedIterator = currentNestedIterator;
55
- const nestedIteratorResult = await currentNestedIterator.next();
56
- if (!nestedIteratorResult.done) {
57
- return nestedIteratorResult;
58
- }
59
- // The nested iterator is done. If it's still the current one, make it not
60
- // current. (If it's not the current one, somebody else has made us move on.)
61
- if (currentNestedIterator === rememberCurrentNestedIterator) {
62
- currentNestedIterator = undefined;
63
- }
64
- return await next();
65
- }
66
- catch (err) {
67
- done = true;
68
- throw err;
69
- }
70
- }
71
- return {
72
- next,
73
- async return() {
74
- done = true;
75
- await Promise.all([currentNestedIterator?.return?.(), topIterator.return?.()]);
76
- return { value: undefined, done: true };
77
- },
78
- async throw(error) {
79
- done = true;
80
- await Promise.all([currentNestedIterator?.throw?.(error), topIterator.throw?.(error)]);
81
- /* c8 ignore next */
82
- throw error;
83
- },
84
- [Symbol.asyncIterator]() {
85
- return this;
86
- },
87
- };
88
- }
89
- exports.flattenAsyncIterable = flattenAsyncIterable;
@@ -1,85 +0,0 @@
1
- /**
2
- * Given an AsyncIterable of AsyncIterables, flatten all yielded results into a
3
- * single AsyncIterable.
4
- */
5
- export function flattenAsyncIterable(iterable) {
6
- // You might think this whole function could be replaced with
7
- //
8
- // async function* flattenAsyncIterable(iterable) {
9
- // for await (const subIterator of iterable) {
10
- // yield* subIterator;
11
- // }
12
- // }
13
- //
14
- // but calling `.return()` on the iterator it returns won't interrupt the `for await`.
15
- const topIterator = iterable[Symbol.asyncIterator]();
16
- let currentNestedIterator;
17
- let waitForCurrentNestedIterator;
18
- let done = false;
19
- async function next() {
20
- if (done) {
21
- return { value: undefined, done: true };
22
- }
23
- try {
24
- if (!currentNestedIterator) {
25
- // Somebody else is getting it already.
26
- if (waitForCurrentNestedIterator) {
27
- await waitForCurrentNestedIterator;
28
- return await next();
29
- }
30
- // Nobody else is getting it. We should!
31
- let resolve;
32
- waitForCurrentNestedIterator = new Promise(r => {
33
- resolve = r;
34
- });
35
- const topIteratorResult = await topIterator.next();
36
- if (topIteratorResult.done) {
37
- // Given that done only ever transitions from false to true,
38
- // require-atomic-updates is being unnecessarily cautious.
39
- done = true;
40
- return await next();
41
- }
42
- // eslint is making a reasonable point here, but we've explicitly protected
43
- // ourself from the race condition by ensuring that only the single call
44
- // that assigns to waitForCurrentNestedIterator is allowed to assign to
45
- // currentNestedIterator or waitForCurrentNestedIterator.
46
- currentNestedIterator = topIteratorResult.value[Symbol.asyncIterator]();
47
- waitForCurrentNestedIterator = undefined;
48
- resolve();
49
- return await next();
50
- }
51
- const rememberCurrentNestedIterator = currentNestedIterator;
52
- const nestedIteratorResult = await currentNestedIterator.next();
53
- if (!nestedIteratorResult.done) {
54
- return nestedIteratorResult;
55
- }
56
- // The nested iterator is done. If it's still the current one, make it not
57
- // current. (If it's not the current one, somebody else has made us move on.)
58
- if (currentNestedIterator === rememberCurrentNestedIterator) {
59
- currentNestedIterator = undefined;
60
- }
61
- return await next();
62
- }
63
- catch (err) {
64
- done = true;
65
- throw err;
66
- }
67
- }
68
- return {
69
- next,
70
- async return() {
71
- done = true;
72
- await Promise.all([currentNestedIterator?.return?.(), topIterator.return?.()]);
73
- return { value: undefined, done: true };
74
- },
75
- async throw(error) {
76
- done = true;
77
- await Promise.all([currentNestedIterator?.throw?.(error), topIterator.throw?.(error)]);
78
- /* c8 ignore next */
79
- throw error;
80
- },
81
- [Symbol.asyncIterator]() {
82
- return this;
83
- },
84
- };
85
- }
@@ -1,7 +0,0 @@
1
- type AsyncIterableOrGenerator<T> = AsyncGenerator<T, void, void> | AsyncIterable<T>;
2
- /**
3
- * Given an AsyncIterable of AsyncIterables, flatten all yielded results into a
4
- * single AsyncIterable.
5
- */
6
- export declare function flattenAsyncIterable<T>(iterable: AsyncIterableOrGenerator<AsyncIterableOrGenerator<T>>): AsyncGenerator<T, void, void>;
7
- export {};
@@ -1,7 +0,0 @@
1
- type AsyncIterableOrGenerator<T> = AsyncGenerator<T, void, void> | AsyncIterable<T>;
2
- /**
3
- * Given an AsyncIterable of AsyncIterables, flatten all yielded results into a
4
- * single AsyncIterable.
5
- */
6
- export declare function flattenAsyncIterable<T>(iterable: AsyncIterableOrGenerator<AsyncIterableOrGenerator<T>>): AsyncGenerator<T, void, void>;
7
- export {};