grafast 0.1.1-beta.2 → 0.1.1-beta.21
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 +2 -3
- package/dist/args.d.ts +4 -7
- package/dist/args.js +53 -38
- package/dist/assert.js +2 -3
- package/dist/bucket.d.ts +1 -89
- package/dist/config.d.ts +0 -17
- package/dist/config.js +1 -95
- package/dist/constraints.d.ts +15 -1
- package/dist/constraints.js +41 -3
- package/dist/deferred.js +1 -2
- package/dist/dev.d.ts +1 -4
- package/dist/dev.js +18 -3
- package/dist/engine/LayerPlan.d.ts +21 -111
- package/dist/engine/LayerPlan.js +196 -78
- package/dist/engine/OperationPlan.d.ts +30 -104
- package/dist/engine/OperationPlan.js +763 -471
- package/dist/engine/OutputPlan.d.ts +9 -20
- package/dist/engine/OutputPlan.js +432 -444
- package/dist/engine/StepTracker.d.ts +1 -95
- package/dist/engine/StepTracker.js +94 -20
- package/dist/engine/executeBucket.d.ts +5 -7
- package/dist/engine/executeBucket.js +646 -244
- package/dist/engine/executeOutputPlan.d.ts +0 -53
- package/dist/engine/executeOutputPlan.js +7 -2
- package/dist/engine/lib/defaultPlanResolver.d.ts +6 -0
- package/dist/engine/lib/defaultPlanResolver.js +11 -0
- package/dist/engine/lib/withGlobalLayerPlan.d.ts +2 -0
- package/dist/engine/lib/withGlobalLayerPlan.js +7 -4
- package/dist/engine/lock.d.ts +4 -0
- package/dist/engine/lock.js +82 -0
- package/dist/envelop.js +5 -4
- package/dist/error.d.ts +18 -49
- package/dist/error.js +50 -39
- package/dist/establishOperationPlan.js +57 -42
- package/dist/execute.d.ts +5 -4
- package/dist/execute.js +31 -15
- package/dist/exportAs.d.ts +1 -18
- package/dist/exportAs.js +2 -3
- package/dist/global.js +2 -3
- package/dist/grafastGraphql.d.ts +6 -1
- package/dist/grafastGraphql.js +35 -16
- package/dist/grafastPrint.d.ts +3 -0
- package/dist/grafastPrint.js +67 -6
- package/dist/graphqlCollectFields.d.ts +7 -34
- package/dist/graphqlCollectFields.js +24 -13
- package/dist/graphqlMergeSelectionSets.js +1 -2
- package/dist/index.d.ts +44 -29
- package/dist/index.js +91 -18
- package/dist/input.d.ts +1 -9
- package/dist/input.js +75 -28
- package/dist/inspect.d.ts +9 -3
- package/dist/inspect.js +3 -3
- package/dist/interfaces.d.ts +238 -93
- package/dist/interfaces.js +20 -3
- package/dist/makeGrafastSchema.d.ts +21 -9
- package/dist/makeGrafastSchema.js +353 -133
- package/dist/mermaid.d.ts +0 -17
- package/dist/mermaid.js +131 -19
- package/dist/middleware.d.ts +7 -0
- package/dist/middleware.js +24 -0
- package/dist/multistep.d.ts +19 -0
- package/dist/multistep.js +54 -0
- package/dist/operationPlan-input.d.ts +5 -4
- package/dist/operationPlan-input.js +140 -368
- package/dist/planJSONInterfaces.d.ts +12 -2
- package/dist/polymorphic.js +4 -5
- package/dist/prepare.d.ts +1 -7
- package/dist/prepare.js +100 -74
- package/dist/step.d.ts +118 -172
- package/dist/step.js +262 -183
- package/dist/steps/__flag.d.ts +65 -0
- package/dist/steps/__flag.js +261 -0
- package/dist/steps/__inputDefault.d.ts +14 -0
- package/dist/steps/__inputDefault.js +48 -0
- package/dist/steps/__inputDynamicScalar.d.ts +4 -6
- package/dist/steps/__inputDynamicScalar.js +4 -2
- package/dist/steps/__inputList.d.ts +5 -9
- package/dist/steps/__inputList.js +4 -1
- package/dist/steps/__inputObject.d.ts +7 -11
- package/dist/steps/__inputObject.js +49 -3
- package/dist/steps/__inputStaticLeaf.d.ts +2 -4
- package/dist/steps/__inputStaticLeaf.js +3 -1
- package/dist/steps/__item.d.ts +10 -12
- package/dist/steps/__item.js +8 -2
- package/dist/steps/__trackedValue.d.ts +7 -55
- package/dist/steps/__trackedValue.js +69 -8
- package/dist/steps/__value.d.ts +5 -4
- package/dist/steps/__value.js +5 -4
- package/dist/steps/access.d.ts +10 -10
- package/dist/steps/access.js +50 -17
- package/dist/steps/applyInput.d.ts +44 -0
- package/dist/steps/applyInput.js +206 -0
- package/dist/steps/applyTransforms.d.ts +2 -25
- package/dist/steps/applyTransforms.js +53 -31
- package/dist/steps/bakedInput.d.ts +23 -0
- package/dist/steps/bakedInput.js +90 -0
- package/dist/steps/condition.d.ts +31 -0
- package/dist/steps/condition.js +94 -0
- package/dist/steps/connection.d.ts +56 -42
- package/dist/steps/connection.js +97 -44
- package/dist/steps/constant.d.ts +7 -7
- package/dist/steps/constant.js +86 -7
- package/dist/steps/each.d.ts +3 -3
- package/dist/steps/each.js +2 -3
- package/dist/steps/error.d.ts +4 -4
- package/dist/steps/error.js +7 -6
- package/dist/steps/filter.d.ts +3 -2
- package/dist/steps/filter.js +1 -2
- package/dist/steps/first.d.ts +10 -9
- package/dist/steps/first.js +9 -13
- package/dist/steps/graphqlResolver.d.ts +3 -76
- package/dist/steps/graphqlResolver.js +89 -72
- package/dist/steps/groupBy.d.ts +3 -2
- package/dist/steps/groupBy.js +1 -2
- package/dist/steps/index.d.ts +12 -3
- package/dist/steps/index.js +48 -6
- package/dist/steps/lambda.d.ts +9 -9
- package/dist/steps/lambda.js +18 -9
- package/dist/steps/last.d.ts +9 -8
- package/dist/steps/last.js +7 -6
- package/dist/steps/list.d.ts +20 -9
- package/dist/steps/list.js +56 -13
- package/dist/steps/listTransform.d.ts +18 -22
- package/dist/steps/listTransform.js +58 -27
- package/dist/steps/listen.d.ts +6 -11
- package/dist/steps/listen.js +14 -16
- package/dist/steps/load.d.ts +42 -33
- package/dist/steps/load.js +60 -27
- package/dist/steps/node.d.ts +17 -10
- package/dist/steps/node.js +18 -6
- package/dist/steps/object.d.ts +33 -27
- package/dist/steps/object.js +53 -32
- package/dist/steps/partitionByIndex.d.ts +3 -2
- package/dist/steps/partitionByIndex.js +1 -2
- package/dist/steps/polymorphicBranch.d.ts +27 -0
- package/dist/steps/polymorphicBranch.js +62 -0
- package/dist/steps/proxy.d.ts +11 -12
- package/dist/steps/proxy.js +8 -5
- package/dist/steps/remapKeys.d.ts +10 -10
- package/dist/steps/remapKeys.js +14 -7
- package/dist/steps/reverse.d.ts +8 -8
- package/dist/steps/reverse.js +10 -7
- package/dist/steps/setter.d.ts +9 -18
- package/dist/steps/setter.js +24 -14
- package/dist/steps/sideEffect.d.ts +28 -0
- package/dist/steps/sideEffect.js +44 -0
- package/dist/stringifyPayload.js +1 -2
- package/dist/stripAnsi.js +2 -2
- package/dist/subscribe.d.ts +7 -1
- package/dist/subscribe.js +24 -9
- package/dist/thereCanBeOnlyOne.js +1 -1
- package/dist/timeSource.d.ts +0 -1
- package/dist/utils.d.ts +56 -55
- package/dist/utils.js +179 -59
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -8
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.executeBucket = executeBucket;
|
|
4
|
+
exports.newBucket = newBucket;
|
|
5
|
+
exports.bucketToString = bucketToString;
|
|
6
|
+
exports.batchExecutionValue = batchExecutionValue;
|
|
7
|
+
exports.unaryExecutionValue = unaryExecutionValue;
|
|
4
8
|
const tslib_1 = require("tslib");
|
|
5
9
|
const iterall_1 = require("iterall");
|
|
6
10
|
const assert = tslib_1.__importStar(require("../assert.js"));
|
|
@@ -8,17 +12,8 @@ const dev_js_1 = require("../dev.js");
|
|
|
8
12
|
const error_js_1 = require("../error.js");
|
|
9
13
|
const inspect_js_1 = require("../inspect.js");
|
|
10
14
|
const interfaces_js_1 = require("../interfaces.js");
|
|
11
|
-
const step_js_1 = require("../step.js");
|
|
12
15
|
const timeSource_js_1 = require("../timeSource.js");
|
|
13
16
|
const utils_js_1 = require("../utils.js");
|
|
14
|
-
const DEBUG_POLYMORPHISM = false;
|
|
15
|
-
/** Path to use when there's no polymorphic paths. */
|
|
16
|
-
const NO_POLY_PATH = "";
|
|
17
|
-
// TODO: the handling of polymorphism via POLY_SKIPPED is distasteful. Find a
|
|
18
|
-
// better approach.
|
|
19
|
-
// An error that indicates this entry was skipped because it didn't match
|
|
20
|
-
// polymorphicPath.
|
|
21
|
-
const POLY_SKIPPED = (0, error_js_1.newGrafastError)(new Error("GrafastInternalError<757b99f9-cb4d-4141-895d-8c687b2048fd>: Polymorphic skipped; you should never see this"), null);
|
|
22
17
|
const timeoutError = Object.freeze(new error_js_1.SafeError("Execution timeout exceeded, please simplify or add limits to your request.", Object.freeze({ [interfaces_js_1.$$timeout]: true })));
|
|
23
18
|
function noop() {
|
|
24
19
|
/*noop*/
|
|
@@ -33,31 +28,45 @@ function noop() {
|
|
|
33
28
|
*
|
|
34
29
|
* @internal
|
|
35
30
|
*/
|
|
36
|
-
function mergeErrorsBackIn(results,
|
|
31
|
+
function mergeErrorsBackIn(results, forcedValues, resultCount) {
|
|
32
|
+
const finalFlags = [];
|
|
37
33
|
const finalResults = [];
|
|
34
|
+
/** The index within `results`, which is shorter than `resultCount` */
|
|
38
35
|
let resultIndex = 0;
|
|
39
|
-
for (let
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
|
|
36
|
+
for (let finalIndex = 0; finalIndex < resultCount; finalIndex++) {
|
|
37
|
+
const flags = forcedValues.flags[finalIndex];
|
|
38
|
+
if (flags !== undefined) {
|
|
39
|
+
const value = forcedValues.results[finalIndex];
|
|
40
|
+
finalResults[finalIndex] = value;
|
|
41
|
+
finalFlags[finalIndex] = flags;
|
|
43
42
|
}
|
|
44
43
|
else {
|
|
45
|
-
finalResults[
|
|
44
|
+
finalResults[finalIndex] = results[resultIndex++];
|
|
45
|
+
finalFlags[finalIndex] = 0;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
return finalResults;
|
|
48
|
+
return { flags: finalFlags, results: finalResults };
|
|
49
49
|
}
|
|
50
50
|
/** @internal */
|
|
51
51
|
function executeBucket(bucket, requestContext) {
|
|
52
52
|
/**
|
|
53
53
|
* Execute the step directly; since there's no errors we can pass the
|
|
54
|
-
* dependencies through verbatim
|
|
54
|
+
* dependencies through verbatim.
|
|
55
55
|
*/
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
function reallyExecuteStepWithoutFiltering(size, step, dependencies, extra) {
|
|
57
|
+
const results = executeOrStream(size, step, dependencies, extra);
|
|
58
|
+
const flags = (0, utils_js_1.arrayOfLength)(size, interfaces_js_1.NO_FLAGS);
|
|
59
|
+
if ((0, utils_js_1.isPromiseLike)(results)) {
|
|
60
|
+
return results.then((results) => ({ flags, results }));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
return { flags, results };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const { stopTime, eventEmitter, args } = requestContext;
|
|
67
|
+
const { middleware } = args;
|
|
58
68
|
const { metaByMetaKey, size, store, layerPlan: { phases, children: childLayerPlans }, } = bucket;
|
|
59
69
|
const phaseCount = phases.length;
|
|
60
|
-
let sideEffectStepsWithErrors = null;
|
|
61
70
|
// Like a `for(i = 0; i < phaseCount; i++)` loop with some `await`s in it, except it does promise
|
|
62
71
|
// handling manually so that it can complete synchronously (no promises) if
|
|
63
72
|
// possible.
|
|
@@ -74,9 +83,8 @@ function executeBucket(bucket, requestContext) {
|
|
|
74
83
|
*/
|
|
75
84
|
let indexesPendingLoopOver = [];
|
|
76
85
|
let executePromises = null;
|
|
77
|
-
let sideEffectSteps = null;
|
|
78
86
|
let executePromiseResultIndex = null;
|
|
79
|
-
const
|
|
87
|
+
const resultList = [];
|
|
80
88
|
if (phase.checkTimeout &&
|
|
81
89
|
stopTime !== null &&
|
|
82
90
|
timeSource_js_1.timeSource.now() >= stopTime) {
|
|
@@ -85,11 +93,14 @@ function executeBucket(bucket, requestContext) {
|
|
|
85
93
|
const normalSteps = phase.normalSteps;
|
|
86
94
|
for (let normalStepIndex = 0, l = normalSteps.length; normalStepIndex < l; normalStepIndex++) {
|
|
87
95
|
const step = normalSteps[normalStepIndex].step;
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
results
|
|
96
|
+
const stepSize = step._isUnary ? 1 : bucket.size;
|
|
97
|
+
const r = timeoutError;
|
|
98
|
+
const results = (0, utils_js_1.arrayOfLength)(stepSize, r);
|
|
99
|
+
const flags = (0, utils_js_1.arrayOfLength)(stepSize, interfaces_js_1.FLAG_ERROR);
|
|
100
|
+
resultList[normalStepIndex] = { flags, results };
|
|
91
101
|
indexesPendingLoopOver.push(normalStepIndex);
|
|
92
|
-
|
|
102
|
+
// TODO: I believe we can remove this line?
|
|
103
|
+
bucket.flagUnion |= interfaces_js_1.FLAG_ERROR;
|
|
93
104
|
}
|
|
94
105
|
}
|
|
95
106
|
}
|
|
@@ -97,18 +108,11 @@ function executeBucket(bucket, requestContext) {
|
|
|
97
108
|
const normalSteps = phase.normalSteps;
|
|
98
109
|
for (let normalStepIndex = 0, l = normalSteps.length; normalStepIndex < l; normalStepIndex++) {
|
|
99
110
|
const step = normalSteps[normalStepIndex].step;
|
|
100
|
-
|
|
101
|
-
if (sideEffectSteps === null) {
|
|
102
|
-
sideEffectSteps = [step];
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
sideEffectSteps.push(step);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
111
|
+
const stepSize = step._isUnary ? 1 : bucket.size;
|
|
108
112
|
try {
|
|
109
113
|
const r = executeStep(step);
|
|
110
114
|
if ((0, utils_js_1.isPromiseLike)(r)) {
|
|
111
|
-
|
|
115
|
+
resultList[normalStepIndex] = undefined /* will populate shortly */;
|
|
112
116
|
if (!executePromises) {
|
|
113
117
|
executePromises = [r];
|
|
114
118
|
executePromiseResultIndex = [normalStepIndex];
|
|
@@ -119,37 +123,21 @@ function executeBucket(bucket, requestContext) {
|
|
|
119
123
|
}
|
|
120
124
|
}
|
|
121
125
|
else {
|
|
122
|
-
|
|
126
|
+
resultList[normalStepIndex] = r;
|
|
123
127
|
indexesPendingLoopOver.push(normalStepIndex);
|
|
124
128
|
}
|
|
125
129
|
}
|
|
126
130
|
catch (e) {
|
|
127
|
-
const r =
|
|
128
|
-
const
|
|
129
|
-
|
|
131
|
+
const r = e;
|
|
132
|
+
const results = (0, utils_js_1.arrayOfLength)(stepSize, r);
|
|
133
|
+
const flags = (0, utils_js_1.arrayOfLength)(stepSize, interfaces_js_1.FLAG_ERROR);
|
|
134
|
+
resultList[normalStepIndex] = { flags, results };
|
|
130
135
|
indexesPendingLoopOver.push(normalStepIndex);
|
|
131
|
-
|
|
136
|
+
// TODO: I believe we can remove this line?
|
|
137
|
+
bucket.flagUnion |= interfaces_js_1.FLAG_ERROR;
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
140
|
}
|
|
135
|
-
const handleSideEffectSteps = () => {
|
|
136
|
-
if (!sideEffectStepsWithErrors) {
|
|
137
|
-
sideEffectStepsWithErrors = bucket.polymorphicPathList.reduce((memo, path) => {
|
|
138
|
-
memo[path ?? NO_POLY_PATH] = [];
|
|
139
|
-
return memo;
|
|
140
|
-
}, Object.create(null));
|
|
141
|
-
}
|
|
142
|
-
for (const step of sideEffectSteps) {
|
|
143
|
-
if (step.polymorphicPaths) {
|
|
144
|
-
for (const path of step.polymorphicPaths) {
|
|
145
|
-
sideEffectStepsWithErrors[path].push(step);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
sideEffectStepsWithErrors[NO_POLY_PATH].push(step);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
141
|
const next = () => {
|
|
154
142
|
return nextPhase(phaseIndex + 1);
|
|
155
143
|
};
|
|
@@ -164,16 +152,26 @@ function executeBucket(bucket, requestContext) {
|
|
|
164
152
|
indexesPendingLoopOver = [];
|
|
165
153
|
// Validate executed steps
|
|
166
154
|
for (const allStepsIndex of indexesToProcess) {
|
|
167
|
-
const result = results[allStepsIndex];
|
|
168
155
|
const finishedStep = _allSteps[allStepsIndex];
|
|
169
|
-
const
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
|
|
156
|
+
const internalResult = resultList[allStepsIndex];
|
|
157
|
+
if (!internalResult) {
|
|
158
|
+
throw new Error(`GrafastInternalError<166ef53d-b80d-4bea-8b54-803c2694112a>: Result from ${finishedStep} should exist`);
|
|
159
|
+
}
|
|
160
|
+
const { /* flags, */ results } = internalResult;
|
|
161
|
+
const resultLength = results?.length;
|
|
162
|
+
const expectedSize = finishedStep._isUnary ? 1 : size;
|
|
163
|
+
if (resultLength !== expectedSize) {
|
|
164
|
+
if (!Array.isArray(results)) {
|
|
165
|
+
throw new Error(`Result from ${finishedStep} should be an array, instead received ${(0, inspect_js_1.inspect)(results, { colors: true })}`);
|
|
173
166
|
}
|
|
174
|
-
throw new Error(`Result array from ${finishedStep} should have length ${
|
|
167
|
+
throw new Error(`Result array from ${finishedStep} should have length ${expectedSize}${finishedStep._isUnary ? " (because it's unary)" : ""}, instead it had length ${results.length}`);
|
|
168
|
+
}
|
|
169
|
+
if (finishedStep._isUnary) {
|
|
170
|
+
// Handled later
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
bucket.store.set(finishedStep.id, batchExecutionValue((0, utils_js_1.arrayOfLength)(size)));
|
|
175
174
|
}
|
|
176
|
-
bucket.store.set(finishedStep.id, (0, utils_js_1.arrayOfLength)(size));
|
|
177
175
|
}
|
|
178
176
|
// Need to complete promises, check for errors, etc.
|
|
179
177
|
// **DO NOT THROW, DO NOT ALLOW AN ERROR TO BE RAISED!**
|
|
@@ -182,25 +180,34 @@ function executeBucket(bucket, requestContext) {
|
|
|
182
180
|
let promises;
|
|
183
181
|
let pendingPromises;
|
|
184
182
|
let pendingPromiseIndexes;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
// Fast
|
|
189
|
-
typeof value !== "object"
|
|
190
|
-
|
|
191
|
-
|
|
183
|
+
// TODO: it seems that if this throws an error it results in a permanent
|
|
184
|
+
// hang of defers? In the mean time... Don't throw any errors here!
|
|
185
|
+
const success = (finishedStep, bucket, resultIndex, value, flags) => {
|
|
186
|
+
// Fast lanes
|
|
187
|
+
if (typeof value !== "object") {
|
|
188
|
+
// non-objects
|
|
189
|
+
bucket.setResult(finishedStep, resultIndex, value, flags);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
else if (value === null) {
|
|
193
|
+
// nulls
|
|
194
|
+
const finalFlags = flags | interfaces_js_1.FLAG_NULL;
|
|
195
|
+
bucket.setResult(finishedStep, resultIndex, null, finalFlags);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
else if ((0, error_js_1.isFlaggedValue)(value)) {
|
|
199
|
+
// flagged values
|
|
200
|
+
const finalFlags = flags | value.flags;
|
|
201
|
+
bucket.setResult(finishedStep, resultIndex, value.value, finalFlags);
|
|
192
202
|
return;
|
|
193
203
|
}
|
|
194
204
|
let valueIsAsyncIterable;
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
// iterable.
|
|
198
|
-
finishedStep._stepOptions.stream &&
|
|
205
|
+
if (finishedStep._stepOptions.walkIterable &&
|
|
206
|
+
// PERF: do we want to handle arrays differently?
|
|
199
207
|
((valueIsAsyncIterable = (0, iterall_1.isAsyncIterable)(value)) || (0, iterall_1.isIterable)(value))) {
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
: Infinity;
|
|
208
|
+
// PERF: we've already calculated this once; can we reference that again here?
|
|
209
|
+
const stream = evaluateStream(bucket, finishedStep);
|
|
210
|
+
const initialCount = stream?.initialCount ?? Infinity;
|
|
204
211
|
const iterator = valueIsAsyncIterable
|
|
205
212
|
? value[Symbol.asyncIterator]()
|
|
206
213
|
: value[Symbol.iterator]();
|
|
@@ -216,7 +223,7 @@ function executeBucket(bucket, requestContext) {
|
|
|
216
223
|
// Optimization - defer everything
|
|
217
224
|
const arr = [];
|
|
218
225
|
arr[interfaces_js_1.$$streamMore] = iterator;
|
|
219
|
-
|
|
226
|
+
bucket.setResult(finishedStep, resultIndex, arr, flags);
|
|
220
227
|
}
|
|
221
228
|
else {
|
|
222
229
|
// Evaluate the first initialCount entries, rest is streamed.
|
|
@@ -232,11 +239,11 @@ function executeBucket(bucket, requestContext) {
|
|
|
232
239
|
*/
|
|
233
240
|
let resultPromise;
|
|
234
241
|
while ((resultPromise = iterator.next())) {
|
|
235
|
-
const
|
|
236
|
-
if (
|
|
242
|
+
const resolvedResult = await resultPromise;
|
|
243
|
+
if (resolvedResult.done) {
|
|
237
244
|
break;
|
|
238
245
|
}
|
|
239
|
-
arr.push(await
|
|
246
|
+
arr.push(await resolvedResult.value);
|
|
240
247
|
if (++valuesSeen >= initialCount) {
|
|
241
248
|
// This is safe to do in the `while` since we checked
|
|
242
249
|
// the `0` entries condition in the optimization
|
|
@@ -245,11 +252,10 @@ function executeBucket(bucket, requestContext) {
|
|
|
245
252
|
break;
|
|
246
253
|
}
|
|
247
254
|
}
|
|
248
|
-
|
|
255
|
+
bucket.setResult(finishedStep, resultIndex, arr, flags);
|
|
249
256
|
}
|
|
250
257
|
catch (e) {
|
|
251
|
-
bucket.
|
|
252
|
-
finalResult[resultIndex] = (0, error_js_1.newGrafastError)(e, finishedStep.id);
|
|
258
|
+
bucket.setResult(finishedStep, resultIndex, e, flags | interfaces_js_1.FLAG_ERROR);
|
|
253
259
|
}
|
|
254
260
|
})();
|
|
255
261
|
if (!promises) {
|
|
@@ -260,27 +266,25 @@ function executeBucket(bucket, requestContext) {
|
|
|
260
266
|
}
|
|
261
267
|
}
|
|
262
268
|
}
|
|
263
|
-
else if ((proto = Object.getPrototypeOf(value)) === null ||
|
|
264
|
-
proto === Object.prototype) {
|
|
265
|
-
finalResult[resultIndex] = value;
|
|
266
|
-
}
|
|
267
|
-
else if (value instanceof Error) {
|
|
268
|
-
const e = error_js_1.$$error in value ? value : (0, error_js_1.newGrafastError)(value, finishedStep.id);
|
|
269
|
-
finalResult[resultIndex] = e;
|
|
270
|
-
bucket.hasErrors = true;
|
|
271
|
-
}
|
|
272
269
|
else {
|
|
273
|
-
|
|
270
|
+
bucket.setResult(finishedStep, resultIndex, value, flags);
|
|
274
271
|
}
|
|
275
272
|
};
|
|
276
273
|
for (const allStepsIndex of indexesToProcess) {
|
|
277
274
|
const step = _allSteps[allStepsIndex];
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
275
|
+
const internalResult = resultList[allStepsIndex];
|
|
276
|
+
if (!internalResult) {
|
|
277
|
+
throw new Error(`GrafastInternalError<b82038d6-ca4e-4b55-8ed4-4d7c879f5dc2>: Result from ${step} should exist`);
|
|
278
|
+
}
|
|
279
|
+
const { flags, results } = internalResult;
|
|
280
|
+
const count = step._isUnary ? 1 : size;
|
|
281
|
+
for (let dataIndex = 0; dataIndex < count; dataIndex++) {
|
|
282
|
+
const val = results[dataIndex];
|
|
282
283
|
if (step.isSyncAndSafe || !(0, utils_js_1.isPromiseLike)(val)) {
|
|
283
|
-
|
|
284
|
+
if (flags[dataIndex] == null) {
|
|
285
|
+
throw new Error(`GraphileInternalError<75df71bb-0f76-4a98-9664-9167d502296a>: result for ${step} has no flag at index ${dataIndex} (value = ${(0, inspect_js_1.inspect)(val)})`);
|
|
286
|
+
}
|
|
287
|
+
success(step, bucket, dataIndex, val, flags[dataIndex]);
|
|
284
288
|
}
|
|
285
289
|
else {
|
|
286
290
|
if (!pendingPromises) {
|
|
@@ -301,41 +305,34 @@ function executeBucket(bucket, requestContext) {
|
|
|
301
305
|
const settledResult = resultSettledResult[i];
|
|
302
306
|
const { s: allStepsIndex, i: dataIndex } = pendingPromiseIndexes[i];
|
|
303
307
|
const finishedStep = _allSteps[allStepsIndex];
|
|
304
|
-
const storeEntry = bucket.store.get(finishedStep.id);
|
|
305
308
|
if (settledResult.status === "fulfilled") {
|
|
306
|
-
success(finishedStep,
|
|
309
|
+
success(finishedStep, bucket, dataIndex, settledResult.value, interfaces_js_1.NO_FLAGS);
|
|
307
310
|
}
|
|
308
311
|
else {
|
|
309
|
-
|
|
310
|
-
|
|
312
|
+
const error = settledResult.reason;
|
|
313
|
+
bucket.setResult(finishedStep, dataIndex, error, interfaces_js_1.FLAG_ERROR);
|
|
311
314
|
}
|
|
312
315
|
}
|
|
313
|
-
if (bucket.hasErrors && sideEffectSteps) {
|
|
314
|
-
handleSideEffectSteps();
|
|
315
|
-
}
|
|
316
316
|
return promises ? Promise.all(promises) : undefined;
|
|
317
317
|
})
|
|
318
318
|
.then(null, (e) => {
|
|
319
319
|
// THIS SHOULD NEVER HAPPEN!
|
|
320
320
|
console.error(`GrafastInternalError<1e9731b4-005e-4b0e-bc61-43baa62e6444>: this error should never occur! Please file an issue against grafast. Details: ${e}`);
|
|
321
|
-
bucket.
|
|
321
|
+
bucket.flagUnion |= interfaces_js_1.FLAG_ERROR;
|
|
322
322
|
for (let i = 0, pendingPromisesLength = pendingPromises.length; i < pendingPromisesLength; i++) {
|
|
323
323
|
const { s: allStepsIndex, i: dataIndex } = pendingPromiseIndexes[i];
|
|
324
324
|
const finishedStep = _allSteps[allStepsIndex];
|
|
325
|
-
const
|
|
326
|
-
|
|
325
|
+
const error = new Error(`GrafastInternalError<1e9731b4-005e-4b0e-bc61-43baa62e6444>: error occurred whilst performing completedStep(${finishedStep.id})`);
|
|
326
|
+
bucket.setResult(finishedStep, dataIndex, error, interfaces_js_1.FLAG_ERROR);
|
|
327
327
|
}
|
|
328
328
|
});
|
|
329
329
|
}
|
|
330
330
|
else {
|
|
331
|
-
if (bucket.hasErrors && sideEffectSteps) {
|
|
332
|
-
handleSideEffectSteps();
|
|
333
|
-
}
|
|
334
331
|
return promises ? Promise.all(promises) : undefined;
|
|
335
332
|
}
|
|
336
333
|
};
|
|
337
334
|
const runSyncSteps = () => {
|
|
338
|
-
const executedLength =
|
|
335
|
+
const executedLength = resultList.length;
|
|
339
336
|
if (dev_js_1.isDev) {
|
|
340
337
|
assert.strictEqual(executedLength, phase.normalSteps?.length ?? 0, "Expected only and all normalSteps to have executed");
|
|
341
338
|
}
|
|
@@ -351,48 +348,151 @@ function executeBucket(bucket, requestContext) {
|
|
|
351
348
|
stopTime,
|
|
352
349
|
meta,
|
|
353
350
|
eventEmitter,
|
|
351
|
+
stream: evaluateStream(bucket, step),
|
|
354
352
|
_bucket: bucket,
|
|
355
353
|
_requestContext: requestContext,
|
|
356
354
|
};
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
355
|
+
if (step._isUnary) {
|
|
356
|
+
// Handled later
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
bucket.store.set(step.id, batchExecutionValue((0, utils_js_1.arrayOfLength)(size)));
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
for (let dataIndex = 0; dataIndex < size; dataIndex++) {
|
|
363
|
+
stepLoop: for (let allStepsIndex = executedLength; allStepsIndex < allStepsLength; allStepsIndex++) {
|
|
364
|
+
const step = (0, utils_js_1.sudo)(_allSteps[allStepsIndex]);
|
|
365
|
+
// Unary steps only need to be processed once
|
|
366
|
+
if (step._isUnary && dataIndex !== 0) {
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
// Check if the side effect errored
|
|
370
|
+
const $sideEffect = step.implicitSideEffectStep;
|
|
371
|
+
if ($sideEffect) {
|
|
372
|
+
let currentPolymorphicPath;
|
|
373
|
+
if ($sideEffect.polymorphicPaths === null ||
|
|
374
|
+
(currentPolymorphicPath =
|
|
375
|
+
bucket.polymorphicPathList[dataIndex]) === null ||
|
|
376
|
+
$sideEffect.polymorphicPaths.has(currentPolymorphicPath)) {
|
|
377
|
+
const depExecutionValue = bucket.store.get($sideEffect.id);
|
|
378
|
+
if (depExecutionValue === undefined) {
|
|
379
|
+
throw new Error(`GrafastInternalError<fcc8d302-ac66-40e8-aaea-ee2c7e2b30b2>: failed to get result for side effect ${$sideEffect} which impacts ${step}`);
|
|
380
|
+
}
|
|
381
|
+
const depFlags = depExecutionValue._flagsAt(dataIndex);
|
|
382
|
+
if (depFlags & interfaces_js_1.FLAG_POLY_SKIPPED) {
|
|
383
|
+
/* noop */
|
|
384
|
+
}
|
|
385
|
+
else if (depFlags & interfaces_js_1.FLAG_ERROR) {
|
|
386
|
+
if (step._isUnary) {
|
|
387
|
+
// COPY the unary value
|
|
388
|
+
bucket.store.set(step.id, depExecutionValue);
|
|
389
|
+
bucket.flagUnion |= depFlags;
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
const depVal = depExecutionValue.at(dataIndex);
|
|
393
|
+
bucket.setResult(step, dataIndex, depVal, depFlags);
|
|
394
|
+
}
|
|
395
|
+
continue stepLoop;
|
|
373
396
|
}
|
|
374
|
-
continue outerLoop;
|
|
375
397
|
}
|
|
376
398
|
}
|
|
377
|
-
}
|
|
378
|
-
stepLoop: for (let allStepsIndex = executedLength; allStepsIndex < allStepsLength; allStepsIndex++) {
|
|
379
|
-
const step = _allSteps[allStepsIndex];
|
|
380
|
-
const storeEntry = bucket.store.get(step.id);
|
|
381
399
|
try {
|
|
382
400
|
const deps = [];
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
401
|
+
const extra = extras[allStepsIndex];
|
|
402
|
+
let forceIndexValue = undefined;
|
|
403
|
+
let rejectValue = undefined;
|
|
404
|
+
let indexFlags = interfaces_js_1.NO_FLAGS;
|
|
405
|
+
for (let i = 0, l = step.dependencies.length; i < l; i++) {
|
|
406
|
+
const $dep = step.dependencies[i];
|
|
407
|
+
const forbiddenFlags = step.dependencyForbiddenFlags[i];
|
|
408
|
+
const onReject = step.dependencyOnReject[i];
|
|
409
|
+
const depExecutionVal = bucket.store.get($dep.id);
|
|
410
|
+
// Search for "f2b3b1b3" for similar block
|
|
411
|
+
const flags = depExecutionVal._flagsAt(dataIndex);
|
|
412
|
+
const disallowedFlags = flags & forbiddenFlags;
|
|
413
|
+
if (disallowedFlags) {
|
|
414
|
+
indexFlags |= disallowedFlags;
|
|
415
|
+
// If there's a reject behavior and we're FRESHLY rejected (weren't
|
|
416
|
+
// already inhibited), use that as a fallback.
|
|
417
|
+
// TODO: validate this.
|
|
418
|
+
// If dep is inhibited and we don't allow inhibited, copy through (null or error).
|
|
419
|
+
// If dep is inhibited and we do allow inhibited, but we're disallowed, use our onReject.
|
|
420
|
+
// If dep is not inhibited, but we're disallowed, use our onReject.
|
|
421
|
+
if (onReject !== undefined &&
|
|
422
|
+
(disallowedFlags & (interfaces_js_1.FLAG_INHIBITED | interfaces_js_1.FLAG_ERROR)) === interfaces_js_1.NO_FLAGS) {
|
|
423
|
+
rejectValue ||= onReject;
|
|
424
|
+
}
|
|
425
|
+
if (forceIndexValue == null) {
|
|
426
|
+
if ((flags & interfaces_js_1.FLAG_ERROR) !== 0) {
|
|
427
|
+
const v = depExecutionVal.at(dataIndex);
|
|
428
|
+
forceIndexValue = v;
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
forceIndexValue = null;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
// First error wins, ignore this second error.
|
|
436
|
+
}
|
|
437
|
+
// End "f2b3b1b3" block
|
|
438
|
+
}
|
|
439
|
+
else if (forceIndexValue === undefined) {
|
|
440
|
+
const depVal = depExecutionVal.at(dataIndex);
|
|
441
|
+
let depFlags;
|
|
442
|
+
if ((bucket.flagUnion & interfaces_js_1.FLAG_ERROR) === interfaces_js_1.FLAG_ERROR &&
|
|
443
|
+
((depFlags = depExecutionVal._flagsAt(dataIndex)) &
|
|
444
|
+
interfaces_js_1.FLAG_ERROR) ===
|
|
445
|
+
interfaces_js_1.FLAG_ERROR) {
|
|
446
|
+
if (step._isUnary) {
|
|
447
|
+
// COPY the unary value
|
|
448
|
+
bucket.store.set(step.id, depExecutionVal);
|
|
449
|
+
bucket.flagUnion |= depFlags;
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
bucket.setResult(step, dataIndex, depVal, interfaces_js_1.FLAG_ERROR);
|
|
453
|
+
}
|
|
454
|
+
continue stepLoop;
|
|
455
|
+
}
|
|
456
|
+
deps.push(depVal);
|
|
388
457
|
}
|
|
389
|
-
deps.push(depVal);
|
|
390
458
|
}
|
|
391
|
-
|
|
459
|
+
let stepResult, stepFlags;
|
|
460
|
+
if (forceIndexValue !== undefined) {
|
|
461
|
+
// Search for "17217999b7a7" for similar block
|
|
462
|
+
if (forceIndexValue == null && rejectValue != null) {
|
|
463
|
+
indexFlags |= interfaces_js_1.FLAG_ERROR;
|
|
464
|
+
forceIndexValue = rejectValue;
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
indexFlags |= interfaces_js_1.FLAG_INHIBITED;
|
|
468
|
+
}
|
|
469
|
+
// End "17217999b7a7" block
|
|
470
|
+
stepResult = forceIndexValue;
|
|
471
|
+
stepFlags = indexFlags;
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
const rawStepResult = step.unbatchedExecute(extra, ...deps);
|
|
475
|
+
if (typeof rawStepResult === "object" &&
|
|
476
|
+
rawStepResult !== null &&
|
|
477
|
+
(0, error_js_1.isFlaggedValue)(rawStepResult)) {
|
|
478
|
+
stepResult = rawStepResult.value;
|
|
479
|
+
stepFlags = rawStepResult.flags;
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
stepResult = rawStepResult;
|
|
483
|
+
stepFlags = rawStepResult == null ? interfaces_js_1.FLAG_NULL : interfaces_js_1.NO_FLAGS;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
// TODO: what if stepResult is _returned_ error (as opposed to
|
|
487
|
+
// thrown)?
|
|
488
|
+
// NOTE: we are in `runSyncSteps` so this step is guaranteed to
|
|
489
|
+
// be "isSyncAndSafe". As such, we don't need to worry about it
|
|
490
|
+
// returning an error (unsafe) or a promise (async), we only
|
|
491
|
+
// need to check if it's null.
|
|
492
|
+
bucket.setResult(step, dataIndex, stepResult, stepFlags);
|
|
392
493
|
}
|
|
393
494
|
catch (e) {
|
|
394
|
-
bucket.
|
|
395
|
-
storeEntry[dataIndex] = (0, error_js_1.newGrafastError)(e, step.id);
|
|
495
|
+
bucket.setResult(step, dataIndex, e, interfaces_js_1.FLAG_ERROR);
|
|
396
496
|
}
|
|
397
497
|
}
|
|
398
498
|
}
|
|
@@ -411,7 +511,7 @@ function executeBucket(bucket, requestContext) {
|
|
|
411
511
|
const executePromise = executePromises[i];
|
|
412
512
|
const index = executePromiseResultIndex[i];
|
|
413
513
|
processedPromises.push(executePromise.then((promiseResult) => {
|
|
414
|
-
|
|
514
|
+
resultList[index] = promiseResult;
|
|
415
515
|
indexesPendingLoopOver.push(index);
|
|
416
516
|
// We must loop over the results in the same tick in which the
|
|
417
517
|
// promise resolved.
|
|
@@ -438,12 +538,26 @@ function executeBucket(bucket, requestContext) {
|
|
|
438
538
|
return executeSamePhaseChildren();
|
|
439
539
|
}
|
|
440
540
|
// Function definitions below here
|
|
441
|
-
function executeOrStream(step,
|
|
442
|
-
if (step.
|
|
443
|
-
|
|
541
|
+
function executeOrStream(count, step, values, extra) {
|
|
542
|
+
if (dev_js_1.isDev && step._isUnary && count !== 1) {
|
|
543
|
+
throw new Error(`GrafastInternalError<84a6cdfa-e8fe-4dea-85fe-9426a6a78027>: ${step} is a unary step, but we're attempting to pass it ${count} (!= 1) values`);
|
|
544
|
+
}
|
|
545
|
+
if (step.execute.length > 1) {
|
|
546
|
+
throw new Error(`${step} is using a legacy form of 'execute' which accepts multiple arguments, please see https://err.red/gev2`);
|
|
547
|
+
}
|
|
548
|
+
const executeDetails = {
|
|
549
|
+
indexMap: makeIndexMap(count),
|
|
550
|
+
indexForEach: makeIndexForEach(count),
|
|
551
|
+
count,
|
|
552
|
+
values,
|
|
553
|
+
extra,
|
|
554
|
+
stream: evaluateStream(bucket, step),
|
|
555
|
+
};
|
|
556
|
+
if (!step.isSyncAndSafe && middleware != null) {
|
|
557
|
+
return middleware.run("executeStep", { args, step, executeDetails }, executeStepFromEvent);
|
|
444
558
|
}
|
|
445
559
|
else {
|
|
446
|
-
return step.execute(
|
|
560
|
+
return step.execute(executeDetails);
|
|
447
561
|
}
|
|
448
562
|
}
|
|
449
563
|
// Slow mode...
|
|
@@ -452,107 +566,200 @@ function executeBucket(bucket, requestContext) {
|
|
|
452
566
|
* polymorphicPaths from the input dependencies and then padding the lists
|
|
453
567
|
* back out at the end.
|
|
454
568
|
*/
|
|
455
|
-
function
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
569
|
+
function reallyExecuteStepWithFiltering(step, dependenciesIncludingSideEffects, dependencyForbiddenFlags, dependencyOnReject, polymorphicPathList, extra) {
|
|
570
|
+
const expectedSize = step._isUnary ? 1 : size;
|
|
571
|
+
const forcedValues = {
|
|
572
|
+
flags: (0, utils_js_1.arrayOfLength)(expectedSize, undefined),
|
|
573
|
+
results: (0, utils_js_1.arrayOfLength)(expectedSize, undefined),
|
|
574
|
+
};
|
|
575
|
+
/**
|
|
576
|
+
* If there's errors/forbidden values, we must manipulate the arrays being
|
|
577
|
+
* passed into the step execution
|
|
578
|
+
*/
|
|
579
|
+
let needsTransform = false;
|
|
459
580
|
/** If all we see is errors, there's no need to execute! */
|
|
460
|
-
let
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
581
|
+
let newSize = 0;
|
|
582
|
+
let stepPolymorphicPaths = step.polymorphicPaths;
|
|
583
|
+
const legitDepsCount = (0, utils_js_1.sudo)(step).dependencies.length;
|
|
584
|
+
const dependenciesIncludingSideEffectsCount = dependenciesIncludingSideEffects.length;
|
|
585
|
+
let dependencies = dependenciesIncludingSideEffectsCount > legitDepsCount
|
|
586
|
+
? dependenciesIncludingSideEffects.slice(0, legitDepsCount)
|
|
587
|
+
: dependenciesIncludingSideEffects;
|
|
588
|
+
// OPTIM: if unariesIncludingSideEffects.some(isGrafastError) then shortcut execution because everything fails
|
|
589
|
+
let hasPolyMatch = true;
|
|
590
|
+
if (step._isUnary && stepPolymorphicPaths !== null) {
|
|
591
|
+
// Check that at least one datapoint matches one of our paths
|
|
592
|
+
hasPolyMatch = false;
|
|
593
|
+
for (let dataIndex = 0; dataIndex < size; dataIndex++) {
|
|
594
|
+
if (stepPolymorphicPaths.has(polymorphicPathList[dataIndex])) {
|
|
595
|
+
hasPolyMatch = true;
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
stepPolymorphicPaths = null;
|
|
600
|
+
}
|
|
601
|
+
for (let dataIndex = 0; dataIndex < expectedSize; dataIndex++) {
|
|
602
|
+
let forceIndexValue = hasPolyMatch
|
|
603
|
+
? undefined
|
|
604
|
+
: null;
|
|
605
|
+
let rejectValue = undefined;
|
|
606
|
+
let indexFlags = hasPolyMatch
|
|
607
|
+
? interfaces_js_1.NO_FLAGS
|
|
608
|
+
: interfaces_js_1.FLAG_POLY_SKIPPED;
|
|
464
609
|
if (stepPolymorphicPaths !== null &&
|
|
465
|
-
!stepPolymorphicPaths.has(
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
610
|
+
!stepPolymorphicPaths.has(polymorphicPathList[dataIndex])) {
|
|
611
|
+
indexFlags |= interfaces_js_1.FLAG_POLY_SKIPPED;
|
|
612
|
+
forceIndexValue = null;
|
|
613
|
+
}
|
|
614
|
+
else if (extra._bucket.flagUnion) {
|
|
615
|
+
for (let i = 0; i < dependenciesIncludingSideEffectsCount; i++) {
|
|
616
|
+
const depExecutionVal = dependenciesIncludingSideEffects[i];
|
|
617
|
+
const forbiddenFlags = dependencyForbiddenFlags[i];
|
|
618
|
+
const onReject = dependencyOnReject[i];
|
|
619
|
+
// Search for "f2b3b1b3" for similar block
|
|
620
|
+
const flags = depExecutionVal._flagsAt(dataIndex);
|
|
621
|
+
const disallowedFlags = flags & forbiddenFlags;
|
|
622
|
+
if (disallowedFlags) {
|
|
623
|
+
indexFlags |= disallowedFlags;
|
|
624
|
+
// If there's a reject behavior and we're FRESHLY rejected (weren't
|
|
625
|
+
// already inhibited), use that as a fallback.
|
|
626
|
+
// TODO: validate this.
|
|
627
|
+
// If dep is inhibited and we don't allow inhibited, copy through (null or error).
|
|
628
|
+
// If dep is inhibited and we do allow inhibited, but we're disallowed, use our onReject.
|
|
629
|
+
// If dep is not inhibited, but we're disallowed, use our onReject.
|
|
630
|
+
if (onReject !== undefined &&
|
|
631
|
+
(disallowedFlags & (interfaces_js_1.FLAG_INHIBITED | interfaces_js_1.FLAG_ERROR)) === interfaces_js_1.NO_FLAGS) {
|
|
632
|
+
rejectValue ||= onReject;
|
|
633
|
+
}
|
|
634
|
+
if (forceIndexValue == null) {
|
|
635
|
+
if ((flags & interfaces_js_1.FLAG_ERROR) !== 0) {
|
|
636
|
+
const v = depExecutionVal.at(dataIndex);
|
|
637
|
+
forceIndexValue = v;
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
forceIndexValue = null;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
// First error wins, ignore this second error.
|
|
484
645
|
}
|
|
646
|
+
// End "f2b3b1b3" block
|
|
647
|
+
break;
|
|
485
648
|
}
|
|
486
649
|
}
|
|
487
|
-
|
|
488
|
-
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
// All good
|
|
653
|
+
}
|
|
654
|
+
if (forceIndexValue !== undefined) {
|
|
655
|
+
if (!needsTransform) {
|
|
656
|
+
needsTransform = true;
|
|
657
|
+
// Clone up until this point, make mutable, don't add self
|
|
658
|
+
dependencies = dependencies.map((ev) => ev.isBatch
|
|
659
|
+
? // TODO: move this creation to happen once the full list is
|
|
660
|
+
// already built, ideally we shouldn't be mutating an execution
|
|
661
|
+
// value later.
|
|
662
|
+
batchExecutionValue(ev.entries.slice(0, dataIndex))
|
|
663
|
+
: ev);
|
|
664
|
+
}
|
|
665
|
+
// Search for "17217999b7a7" for similar block
|
|
666
|
+
if (forceIndexValue == null && rejectValue != null) {
|
|
667
|
+
indexFlags |= interfaces_js_1.FLAG_ERROR;
|
|
668
|
+
forceIndexValue = rejectValue;
|
|
669
|
+
}
|
|
670
|
+
else {
|
|
671
|
+
indexFlags |= interfaces_js_1.FLAG_INHIBITED;
|
|
489
672
|
}
|
|
673
|
+
// End "17217999b7a7" block
|
|
674
|
+
forcedValues.flags[dataIndex] = indexFlags;
|
|
675
|
+
forcedValues.results[dataIndex] = forceIndexValue;
|
|
490
676
|
}
|
|
491
677
|
else {
|
|
492
|
-
|
|
678
|
+
newSize++;
|
|
679
|
+
if (needsTransform) {
|
|
680
|
+
// dependenciesWithoutErrors has limited content; add this non-error value
|
|
681
|
+
for (let depListIndex = 0; depListIndex < legitDepsCount; depListIndex++) {
|
|
682
|
+
const depList = dependencies[depListIndex];
|
|
683
|
+
if (depList.isBatch) {
|
|
684
|
+
const depVal = dependenciesIncludingSideEffects[depListIndex];
|
|
685
|
+
depList.entries.push(depVal.at(dataIndex));
|
|
686
|
+
depList._flags.push(depVal._flagsAt(dataIndex));
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
493
690
|
}
|
|
494
691
|
}
|
|
495
|
-
|
|
496
|
-
const dependencies = sideEffectStepsWithErrors
|
|
497
|
-
? dependenciesIncludingSideEffects.slice(0, step.dependencies.length)
|
|
498
|
-
: dependenciesIncludingSideEffects;
|
|
499
|
-
if (needsNoExecution) {
|
|
692
|
+
if (newSize === 0) {
|
|
500
693
|
// Everything is errors; we can skip execution
|
|
501
|
-
return
|
|
694
|
+
return forcedValues;
|
|
502
695
|
}
|
|
503
|
-
else if (
|
|
504
|
-
const
|
|
505
|
-
const resultWithoutErrors = executeOrStream(step, dependenciesWithoutErrors, extra);
|
|
696
|
+
else if (needsTransform) {
|
|
697
|
+
const resultWithoutErrors = executeOrStream(newSize, step, dependencies, extra);
|
|
506
698
|
if ((0, utils_js_1.isPromiseLike)(resultWithoutErrors)) {
|
|
507
|
-
return resultWithoutErrors.then((r) => mergeErrorsBackIn(r,
|
|
699
|
+
return resultWithoutErrors.then((r) => mergeErrorsBackIn(r, forcedValues, expectedSize));
|
|
508
700
|
}
|
|
509
701
|
else {
|
|
510
|
-
return mergeErrorsBackIn(resultWithoutErrors,
|
|
702
|
+
return mergeErrorsBackIn(resultWithoutErrors, forcedValues, expectedSize);
|
|
511
703
|
}
|
|
512
704
|
}
|
|
513
705
|
else {
|
|
514
|
-
|
|
706
|
+
if (dev_js_1.isDev) {
|
|
707
|
+
assert.ok(newSize === expectedSize, "GrafastInternalError<47fca4ab-069c-428f-8374-267479c7fd27>: Expected newSize to equal expectedSize");
|
|
708
|
+
}
|
|
709
|
+
return reallyExecuteStepWithoutFiltering(newSize, step, dependencies, extra);
|
|
515
710
|
}
|
|
516
711
|
}
|
|
517
712
|
/**
|
|
518
713
|
* This function MIGHT throw or reject, so be sure to handle that.
|
|
519
714
|
*/
|
|
520
715
|
function executeStep(step) {
|
|
716
|
+
// DELIBERATE SHADOWING!
|
|
717
|
+
const size = step._isUnary ? 1 : bucket.size;
|
|
521
718
|
try {
|
|
522
719
|
const meta = step.metaKey !== undefined ? metaByMetaKey[step.metaKey] : undefined;
|
|
523
720
|
const extra = {
|
|
524
721
|
stopTime,
|
|
525
722
|
meta,
|
|
526
723
|
eventEmitter,
|
|
724
|
+
stream: evaluateStream(bucket, step),
|
|
527
725
|
_bucket: bucket,
|
|
528
726
|
_requestContext: requestContext,
|
|
529
727
|
};
|
|
530
|
-
|
|
531
|
-
const
|
|
532
|
-
|
|
728
|
+
/** Only mutate this inside `addDependency` */
|
|
729
|
+
const _rawDependencies = [];
|
|
730
|
+
const _rawForbiddenFlags = [];
|
|
731
|
+
const _rawOnReject = [];
|
|
732
|
+
const dependencies = _rawDependencies;
|
|
733
|
+
let needsFiltering = false;
|
|
734
|
+
const defaultForbiddenFlags = (0, utils_js_1.sudo)(step).defaultForbiddenFlags;
|
|
735
|
+
const addDependency = ($dep, forbiddenFlags, onReject) => {
|
|
736
|
+
if (step._isUnary && !$dep._isUnary) {
|
|
737
|
+
throw new Error(`GrafastInternalError<58bc38e2-8722-4c19-ba38-fd01a020654b>: unary step ${step} cannot be made dependent on non-unary step ${$dep}!`);
|
|
738
|
+
}
|
|
739
|
+
const executionValue = store.get($dep.id);
|
|
740
|
+
if (executionValue === undefined) {
|
|
741
|
+
throw new Error(`GrafastInternalError<d9e9eb37-4251-4659-a545-4730826ecf0e>: ${$dep} data couldn't be found, but required by ${step} (with side effect ${step.implicitSideEffectStep})!`);
|
|
742
|
+
}
|
|
743
|
+
_rawDependencies.push(executionValue);
|
|
744
|
+
_rawForbiddenFlags.push(forbiddenFlags);
|
|
745
|
+
_rawOnReject.push(onReject);
|
|
746
|
+
if (!needsFiltering && (bucket.flagUnion & forbiddenFlags) !== 0) {
|
|
747
|
+
const flags = executionValue._getStateUnion();
|
|
748
|
+
needsFiltering = (flags & forbiddenFlags) !== 0;
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
const sstep = (0, utils_js_1.sudo)(step);
|
|
752
|
+
const depCount = sstep.dependencies.length;
|
|
753
|
+
if (depCount > 0) {
|
|
533
754
|
for (let i = 0, l = depCount; i < l; i++) {
|
|
534
|
-
const $dep =
|
|
535
|
-
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
if (!dependencies.includes(sideEffectStoreEntry)) {
|
|
543
|
-
dependencies.push(sideEffectStoreEntry);
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
else {
|
|
549
|
-
for (const sideEffectStep of sideEffectStepsWithErrors[NO_POLY_PATH]) {
|
|
550
|
-
const sideEffectStoreEntry = store.get(sideEffectStep.id);
|
|
551
|
-
if (!dependencies.includes(sideEffectStoreEntry)) {
|
|
552
|
-
dependencies.push(sideEffectStoreEntry);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
755
|
+
const $dep = sstep.dependencies[i];
|
|
756
|
+
addDependency($dep, sstep.dependencyForbiddenFlags[i], sstep.dependencyOnReject[i]);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
const $sideEffect = step.implicitSideEffectStep;
|
|
760
|
+
if ($sideEffect) {
|
|
761
|
+
if ($sideEffect._isUnary || !step._isUnary) {
|
|
762
|
+
addDependency($sideEffect, defaultForbiddenFlags, undefined);
|
|
556
763
|
}
|
|
557
764
|
}
|
|
558
765
|
if (dev_js_1.isDev &&
|
|
@@ -560,16 +767,24 @@ function executeBucket(bucket, requestContext) {
|
|
|
560
767
|
step.polymorphicPaths === null) {
|
|
561
768
|
throw new Error(`GrafastInternalError<c33328fe-6758-4699-8ac6-7be41ce58bfb>: a step without polymorphic paths cannot belong to a polymorphic bucket`);
|
|
562
769
|
}
|
|
563
|
-
|
|
564
|
-
step.
|
|
565
|
-
step.
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
770
|
+
if (!needsFiltering) {
|
|
771
|
+
const isSelectiveStep = step.layerPlan.reason.type === "polymorphic" &&
|
|
772
|
+
step.polymorphicPaths.size !==
|
|
773
|
+
step.layerPlan.reason.polymorphicPaths.size;
|
|
774
|
+
needsFiltering ||= isSelectiveStep;
|
|
775
|
+
}
|
|
776
|
+
const result = needsFiltering
|
|
777
|
+
? reallyExecuteStepWithFiltering(step, dependencies, _rawForbiddenFlags, _rawOnReject, bucket.polymorphicPathList, extra)
|
|
778
|
+
: reallyExecuteStepWithoutFiltering(size, step, $sideEffect ? dependencies.slice(0, depCount) : dependencies, extra);
|
|
569
779
|
if ((0, utils_js_1.isPromiseLike)(result)) {
|
|
570
780
|
return result.then(null, (error) => {
|
|
571
|
-
//
|
|
572
|
-
|
|
781
|
+
// Don't need to do this here, it will be done where the
|
|
782
|
+
// ExecutionValue is created:
|
|
783
|
+
// bucket.hasNonZeroStatus = true;
|
|
784
|
+
return {
|
|
785
|
+
flags: (0, utils_js_1.arrayOfLength)(size, interfaces_js_1.FLAG_ERROR | interfaces_js_1.FLAG_STOPPED),
|
|
786
|
+
results: (0, utils_js_1.arrayOfLength)(size, error),
|
|
787
|
+
};
|
|
573
788
|
});
|
|
574
789
|
}
|
|
575
790
|
else {
|
|
@@ -577,8 +792,13 @@ function executeBucket(bucket, requestContext) {
|
|
|
577
792
|
}
|
|
578
793
|
}
|
|
579
794
|
catch (error) {
|
|
580
|
-
//
|
|
581
|
-
|
|
795
|
+
// Don't need to do this here, it will be done where the
|
|
796
|
+
// ExecutionValue is created:
|
|
797
|
+
// bucket.hasNonZeroStatus = true;
|
|
798
|
+
return {
|
|
799
|
+
flags: (0, utils_js_1.arrayOfLength)(size, interfaces_js_1.FLAG_ERROR | interfaces_js_1.FLAG_STOPPED),
|
|
800
|
+
results: (0, utils_js_1.arrayOfLength)(size, error),
|
|
801
|
+
};
|
|
582
802
|
}
|
|
583
803
|
}
|
|
584
804
|
function executeSamePhaseChildren() {
|
|
@@ -591,8 +811,10 @@ function executeBucket(bucket, requestContext) {
|
|
|
591
811
|
* are called.
|
|
592
812
|
*/
|
|
593
813
|
const enqueue = (callback) => {
|
|
594
|
-
const result =
|
|
595
|
-
|
|
814
|
+
const result = mutationQueue ? mutationQueue.then(callback) : callback();
|
|
815
|
+
if ((0, utils_js_1.isPromiseLike)(result)) {
|
|
816
|
+
mutationQueue = result.then(noop, noop);
|
|
817
|
+
}
|
|
596
818
|
return result;
|
|
597
819
|
};
|
|
598
820
|
loop: for (const childLayerPlan of childLayerPlans) {
|
|
@@ -615,7 +837,9 @@ function executeBucket(bucket, requestContext) {
|
|
|
615
837
|
if (childBucket !== null) {
|
|
616
838
|
// Enqueue for execution (mutations must run in order)
|
|
617
839
|
const promise = enqueue(() => executeBucket(childBucket, requestContext));
|
|
618
|
-
|
|
840
|
+
if ((0, utils_js_1.isPromiseLike)(promise)) {
|
|
841
|
+
childPromises.push(promise);
|
|
842
|
+
}
|
|
619
843
|
}
|
|
620
844
|
break;
|
|
621
845
|
}
|
|
@@ -648,7 +872,6 @@ function executeBucket(bucket, requestContext) {
|
|
|
648
872
|
}
|
|
649
873
|
}
|
|
650
874
|
}
|
|
651
|
-
exports.executeBucket = executeBucket;
|
|
652
875
|
/** @internal */
|
|
653
876
|
function newBucket(spec, parentMetaByMetaKey) {
|
|
654
877
|
if (dev_js_1.isDev) {
|
|
@@ -668,8 +891,10 @@ function newBucket(spec, parentMetaByMetaKey) {
|
|
|
668
891
|
}
|
|
669
892
|
*/
|
|
670
893
|
for (const [key, list] of spec.store.entries()) {
|
|
671
|
-
assert.ok(
|
|
672
|
-
|
|
894
|
+
assert.ok(typeof list.isBatch === "boolean", `Store entry for step '${key}' for layerPlan '${spec.layerPlan.id}' should be an ExecutionValue`);
|
|
895
|
+
if (list.isBatch) {
|
|
896
|
+
assert.strictEqual(list.entries.length, spec.size, `Store entry for step '${key}' for layerPlan '${spec.layerPlan.id}' should have same length as bucket`);
|
|
897
|
+
}
|
|
673
898
|
}
|
|
674
899
|
if (!spec.iterators) {
|
|
675
900
|
throw new Error(`newBucket called but no iterators array was specified`);
|
|
@@ -683,18 +908,195 @@ function newBucket(spec, parentMetaByMetaKey) {
|
|
|
683
908
|
? // Reset the metaByMetaKey
|
|
684
909
|
spec.layerPlan.operationPlan.makeMetaByMetaKey()
|
|
685
910
|
: parentMetaByMetaKey;
|
|
911
|
+
// Copy from spec
|
|
912
|
+
const { layerPlan, store, size, flagUnion, polymorphicPathList, iterators } = spec;
|
|
913
|
+
const children = Object.create(null);
|
|
686
914
|
return {
|
|
687
|
-
|
|
688
|
-
layerPlan
|
|
689
|
-
store
|
|
690
|
-
size
|
|
691
|
-
|
|
692
|
-
polymorphicPathList
|
|
693
|
-
iterators
|
|
915
|
+
toString: bucketToString,
|
|
916
|
+
layerPlan,
|
|
917
|
+
store,
|
|
918
|
+
size,
|
|
919
|
+
flagUnion,
|
|
920
|
+
polymorphicPathList,
|
|
921
|
+
iterators,
|
|
694
922
|
metaByMetaKey,
|
|
695
923
|
isComplete: false,
|
|
696
|
-
children
|
|
924
|
+
children,
|
|
925
|
+
setResult(step, index, value, flags) {
|
|
926
|
+
const stepId = step.id;
|
|
927
|
+
if (index >= size) {
|
|
928
|
+
throw new Error(`GrafastInternalError<9465db89-cc9d-415c-97e7-57bb19ddebe0>: attempt to write to out of bounds index ${index} for bucket of size ${size} for step ${step}`);
|
|
929
|
+
}
|
|
930
|
+
if (flags !== 0) {
|
|
931
|
+
this.flagUnion |= flags;
|
|
932
|
+
}
|
|
933
|
+
if (step._isUnary) {
|
|
934
|
+
if (dev_js_1.isDev && store.has(stepId)) {
|
|
935
|
+
const ev = store.get(stepId);
|
|
936
|
+
console.error(`GrafastInternalWarning<603e635f-af46-4feb-abb1-bac184bf7ef2>: value for step ${step} has already been stored to bucket ${layerPlan}; overwriting.`, {
|
|
937
|
+
isBatch: ev?.isBatch,
|
|
938
|
+
value0: ev?.at(0),
|
|
939
|
+
flags0: ev?._flagsAt(0),
|
|
940
|
+
}, { isBatch: false, value, flags });
|
|
941
|
+
}
|
|
942
|
+
const ev = unaryExecutionValue(value, flags);
|
|
943
|
+
store.set(stepId, ev);
|
|
944
|
+
}
|
|
945
|
+
else {
|
|
946
|
+
const storeEntry = store.get(stepId);
|
|
947
|
+
if (!storeEntry || !storeEntry.isBatch) {
|
|
948
|
+
if (!storeEntry) {
|
|
949
|
+
throw new Error(`GrafastInternalError<e2ba1e4a-5391-4f81-bb21-fb200e29aea2>: value for step ${step} expected to be a batch value, but is not set`);
|
|
950
|
+
}
|
|
951
|
+
else {
|
|
952
|
+
throw new Error(`GrafastInternalError<f587d317-8919-4f14-905a-ab7bb338dd2b>: value for step ${step} expected to be a batch value, but is unary (non-batch)`);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
storeEntry._setResult(index, value, flags);
|
|
956
|
+
}
|
|
957
|
+
},
|
|
697
958
|
};
|
|
698
959
|
}
|
|
699
|
-
|
|
960
|
+
function bucketToString() {
|
|
961
|
+
return `Bucket<${this.layerPlan}>`;
|
|
962
|
+
}
|
|
963
|
+
// NOTE: I evaluated using `__proto__: batchExecutionValueProto` to extract the
|
|
964
|
+
// shared properties of these objects to see if performance was improved, but
|
|
965
|
+
// this was actually a net loss in performance.
|
|
966
|
+
//
|
|
967
|
+
// This is also evidence that you shouldn't trust ChatGPT for performance
|
|
968
|
+
// advice, and should always run your own benchmarks instead:
|
|
969
|
+
// https://chatgpt.com/share/67d1746f-4da8-8012-bdf8-707e54a4238e
|
|
970
|
+
// TODO: memoize?
|
|
971
|
+
function batchExecutionValue(entries, _flags = (0, utils_js_1.arrayOfLength)(entries.length, 0)) {
|
|
972
|
+
return {
|
|
973
|
+
// Try and keep these properties in the same order as unaryExecutionValue
|
|
974
|
+
isBatch: true,
|
|
975
|
+
at: batchEntriesAt,
|
|
976
|
+
unaryValue: batchThrowNotUnary,
|
|
977
|
+
_flagsAt: batchFlagsAt,
|
|
978
|
+
_getStateUnion: batchGetStateUnion,
|
|
979
|
+
_setResult: batchSetResult,
|
|
980
|
+
_copyResult: batchCopyResult,
|
|
981
|
+
entries,
|
|
982
|
+
_flags,
|
|
983
|
+
_cachedStateUnion: null,
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
// TODO: memoize?
|
|
987
|
+
function unaryExecutionValue(value, _entryFlags = 0) {
|
|
988
|
+
return {
|
|
989
|
+
// Try and keep these properties in the same order as batchExecutionValue
|
|
990
|
+
isBatch: false,
|
|
991
|
+
at: unaryAt,
|
|
992
|
+
unaryValue: unaryThisDotValue,
|
|
993
|
+
_flagsAt: unaryFlagsAt,
|
|
994
|
+
_getStateUnion: unaryGetStateUnion,
|
|
995
|
+
_setResult: unarySetResult,
|
|
996
|
+
_copyResult: unaryCopyResult,
|
|
997
|
+
value,
|
|
998
|
+
_entryFlags,
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
function batchThrowNotUnary() {
|
|
1002
|
+
throw new Error(`This is not a unary value so we cannot get the single value - there may be more than one!`);
|
|
1003
|
+
}
|
|
1004
|
+
function batchGetStateUnion() {
|
|
1005
|
+
if (this._cachedStateUnion === null) {
|
|
1006
|
+
let u = interfaces_js_1.NO_FLAGS;
|
|
1007
|
+
for (const flag of this._flags) {
|
|
1008
|
+
u = u | flag;
|
|
1009
|
+
}
|
|
1010
|
+
this._cachedStateUnion = u;
|
|
1011
|
+
}
|
|
1012
|
+
return this._cachedStateUnion;
|
|
1013
|
+
}
|
|
1014
|
+
function batchEntriesAt(i) {
|
|
1015
|
+
return this.entries[i];
|
|
1016
|
+
}
|
|
1017
|
+
function batchFlagsAt(i) {
|
|
1018
|
+
return this._flags[i];
|
|
1019
|
+
}
|
|
1020
|
+
function batchSetResult(i, value, flags) {
|
|
1021
|
+
this.entries[i] = value;
|
|
1022
|
+
this._flags[i] = flags;
|
|
1023
|
+
}
|
|
1024
|
+
// NOTE: batchCopyResult and unaryCopyResult are **identical**, but we don't
|
|
1025
|
+
// want a single megamorphic function so we define it twice.
|
|
1026
|
+
function batchCopyResult(targetIndex, source, sourceIndex) {
|
|
1027
|
+
this._setResult(targetIndex, source.at(sourceIndex), source._flagsAt(sourceIndex));
|
|
1028
|
+
}
|
|
1029
|
+
function unaryCopyResult(targetIndex, source, sourceIndex) {
|
|
1030
|
+
this._setResult(targetIndex, source.at(sourceIndex), source._flagsAt(sourceIndex));
|
|
1031
|
+
}
|
|
1032
|
+
function unaryThisDotValue() {
|
|
1033
|
+
return this.value;
|
|
1034
|
+
}
|
|
1035
|
+
function unaryAt() {
|
|
1036
|
+
return this.value;
|
|
1037
|
+
}
|
|
1038
|
+
function unaryFlagsAt() {
|
|
1039
|
+
return this._entryFlags;
|
|
1040
|
+
}
|
|
1041
|
+
function unaryGetStateUnion() {
|
|
1042
|
+
return this._entryFlags;
|
|
1043
|
+
}
|
|
1044
|
+
function unarySetResult(i, value, flags) {
|
|
1045
|
+
if (i !== 0) {
|
|
1046
|
+
throw new Error(`Unary step only expects one result`);
|
|
1047
|
+
}
|
|
1048
|
+
this.value = value;
|
|
1049
|
+
this._entryFlags = flags;
|
|
1050
|
+
}
|
|
1051
|
+
const indexMapCache = new Map();
|
|
1052
|
+
function makeIndexMap(count) {
|
|
1053
|
+
const existing = indexMapCache.get(count);
|
|
1054
|
+
if (existing !== undefined) {
|
|
1055
|
+
return existing;
|
|
1056
|
+
}
|
|
1057
|
+
const result = (callback) => {
|
|
1058
|
+
const results = [];
|
|
1059
|
+
for (let i = 0; i < count; i++) {
|
|
1060
|
+
results.push(callback(i));
|
|
1061
|
+
}
|
|
1062
|
+
return results;
|
|
1063
|
+
};
|
|
1064
|
+
if (count <= 100) {
|
|
1065
|
+
indexMapCache.set(count, result);
|
|
1066
|
+
}
|
|
1067
|
+
return result;
|
|
1068
|
+
}
|
|
1069
|
+
const indexForEachCache = new Map();
|
|
1070
|
+
function makeIndexForEach(count) {
|
|
1071
|
+
const existing = indexForEachCache.get(count);
|
|
1072
|
+
if (existing !== undefined) {
|
|
1073
|
+
return existing;
|
|
1074
|
+
}
|
|
1075
|
+
const result = (callback) => {
|
|
1076
|
+
for (let i = 0; i < count; i++) {
|
|
1077
|
+
callback(i);
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
if (count <= 100) {
|
|
1081
|
+
indexForEachCache.set(count, result);
|
|
1082
|
+
}
|
|
1083
|
+
return result;
|
|
1084
|
+
}
|
|
1085
|
+
function executeStepFromEvent(event) {
|
|
1086
|
+
return event.step.execute(event.executeDetails);
|
|
1087
|
+
}
|
|
1088
|
+
function evaluateStream(bucket, step) {
|
|
1089
|
+
const stream = step._stepOptions.stream;
|
|
1090
|
+
if (!stream)
|
|
1091
|
+
return null;
|
|
1092
|
+
const shouldStream = stream.ifStepId == null
|
|
1093
|
+
? true
|
|
1094
|
+
: (bucket.store.get(stream.ifStepId)?.unaryValue() ?? true);
|
|
1095
|
+
if (!shouldStream)
|
|
1096
|
+
return null;
|
|
1097
|
+
const initialCount = stream.initialCountStepId == null
|
|
1098
|
+
? 0
|
|
1099
|
+
: (bucket.store.get(stream.initialCountStepId)?.unaryValue() ?? 0);
|
|
1100
|
+
return { initialCount };
|
|
1101
|
+
}
|
|
700
1102
|
//# sourceMappingURL=executeBucket.js.map
|