grafast 0.1.1-beta.0 → 0.1.1-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.
Files changed (81) hide show
  1. package/README.md +1 -2
  2. package/dist/args.js +62 -0
  3. package/dist/assert.js +24 -0
  4. package/dist/bucket.js +4 -0
  5. package/dist/config.js +99 -0
  6. package/dist/constraints.js +72 -0
  7. package/dist/deferred.js +25 -0
  8. package/dist/dev.js +10 -0
  9. package/dist/engine/LayerPlan.js +536 -0
  10. package/dist/engine/OperationPlan.js +2543 -0
  11. package/dist/engine/OutputPlan.js +1059 -0
  12. package/dist/engine/StepTracker.js +524 -0
  13. package/dist/engine/executeBucket.js +700 -0
  14. package/dist/engine/executeOutputPlan.js +21 -0
  15. package/dist/engine/lib/withGlobalLayerPlan.js +36 -0
  16. package/dist/envelop.js +73 -5
  17. package/dist/error.js +62 -0
  18. package/dist/establishOperationPlan.js +186 -0
  19. package/dist/execute.js +80 -0
  20. package/dist/exportAs.js +57 -0
  21. package/dist/global.js +13 -0
  22. package/dist/grafastGraphql.js +133 -0
  23. package/dist/grafastPrint.js +177 -0
  24. package/dist/graphqlCollectFields.js +217 -0
  25. package/dist/graphqlMergeSelectionSets.js +60 -0
  26. package/dist/index.d.ts +161 -2
  27. package/dist/index.js +255 -499
  28. package/dist/input.js +159 -0
  29. package/dist/inspect.js +20 -0
  30. package/dist/interfaces.d.ts +3 -160
  31. package/dist/interfaces.js +63 -0
  32. package/dist/makeGrafastSchema.js +174 -0
  33. package/dist/mermaid.js +290 -7
  34. package/dist/operationPlan-input.js +449 -0
  35. package/dist/planJSONInterfaces.js +3 -0
  36. package/dist/polymorphic.js +73 -0
  37. package/dist/prepare.js +763 -0
  38. package/dist/step.js +396 -0
  39. package/dist/steps/__inputDynamicScalar.js +125 -0
  40. package/dist/steps/__inputList.js +110 -0
  41. package/dist/steps/__inputObject.js +128 -0
  42. package/dist/steps/__inputStaticLeaf.js +43 -0
  43. package/dist/steps/__item.js +50 -0
  44. package/dist/steps/__trackedValue.js +257 -0
  45. package/dist/steps/__value.js +47 -0
  46. package/dist/steps/access.js +183 -0
  47. package/dist/steps/applyTransforms.js +151 -0
  48. package/dist/steps/connection.js +315 -0
  49. package/dist/steps/constant.js +72 -0
  50. package/dist/steps/each.js +64 -0
  51. package/dist/steps/error.js +32 -0
  52. package/dist/steps/filter.js +32 -0
  53. package/dist/steps/first.js +49 -0
  54. package/dist/steps/graphqlResolver.js +260 -0
  55. package/dist/steps/groupBy.js +40 -0
  56. package/dist/steps/index.js +117 -0
  57. package/dist/steps/lambda.js +58 -0
  58. package/dist/steps/last.js +41 -0
  59. package/dist/steps/list.js +75 -0
  60. package/dist/steps/listTransform.js +185 -0
  61. package/dist/steps/listen.js +61 -0
  62. package/dist/steps/load.d.ts +4 -4
  63. package/dist/steps/load.js +310 -0
  64. package/dist/steps/node.d.ts +6 -6
  65. package/dist/steps/node.js +107 -0
  66. package/dist/steps/object.js +195 -0
  67. package/dist/steps/partitionByIndex.js +86 -0
  68. package/dist/steps/proxy.js +114 -0
  69. package/dist/steps/remapKeys.js +84 -0
  70. package/dist/steps/reverse.js +52 -0
  71. package/dist/steps/setter.js +28 -0
  72. package/dist/stringifyPayload.js +59 -0
  73. package/dist/stripAnsi.js +14 -0
  74. package/dist/subscribe.js +14 -0
  75. package/dist/thereCanBeOnlyOne.js +21 -0
  76. package/dist/timeSource.js +8 -0
  77. package/dist/utils.js +698 -0
  78. package/dist/version.d.ts +1 -1
  79. package/dist/version.js +6 -0
  80. package/package.json +9 -4
  81. package/dist/LICENSES.txt +0 -300
@@ -0,0 +1,536 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LayerPlan = exports.isPolymorphicLayerPlan = exports.isDeferredLayerPlan = exports.isBranchingLayerPlan = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lru_1 = tslib_1.__importDefault(require("@graphile/lru"));
6
+ const tamedevil_1 = tslib_1.__importDefault(require("tamedevil"));
7
+ const assert = tslib_1.__importStar(require("../assert.js"));
8
+ const error_js_1 = require("../error.js");
9
+ const inspect_js_1 = require("../inspect.js");
10
+ const polymorphic_js_1 = require("../polymorphic.js");
11
+ const executeBucket_js_1 = require("./executeBucket.js");
12
+ function isBranchingLayerPlan(layerPlan) {
13
+ return layerPlan.reason.type === "polymorphic";
14
+ }
15
+ exports.isBranchingLayerPlan = isBranchingLayerPlan;
16
+ function isDeferredLayerPlan(layerPlan) {
17
+ const t = layerPlan.reason.type;
18
+ return (t === "stream" ||
19
+ t === "subscription" ||
20
+ t === "mutationField" ||
21
+ t === "defer");
22
+ }
23
+ exports.isDeferredLayerPlan = isDeferredLayerPlan;
24
+ function isPolymorphicLayerPlan(layerPlan) {
25
+ const t = layerPlan.reason.type;
26
+ return t === "polymorphic";
27
+ }
28
+ exports.isPolymorphicLayerPlan = isPolymorphicLayerPlan;
29
+ /**
30
+ * A LayerPlan represents (via "reason") either the root (root), when something
31
+ * happens at a later time (mutationField, defer), when plurality changes
32
+ * (list, stream, subscription, polymorphic), or when a subprocess needs to be
33
+ * computed (subroutine).
34
+ *
35
+ * Layer plans belong to an operation plan.
36
+ *
37
+ * Every layer plan (except for the root layer plan) has exactly one parent
38
+ * layer plan.
39
+ *
40
+ * Every layer plan is caused by a parent step.
41
+ *
42
+ * The LayerPlan of a step influences:
43
+ *
44
+ * 1. how steps are deduplicated
45
+ * 2. the order in which the steps are executed
46
+ * 3. where the result of executing the step is stored
47
+ * 4. when the step execution cache is allowed to be GC'd
48
+ *
49
+ * NOTE: `__ListTransformStep`'s effectively have a temporary bucket inside
50
+ * them (built on the `__Item`) that's thrown away once the transform is
51
+ * complete.
52
+ *
53
+ */
54
+ class LayerPlan {
55
+ constructor(operationPlan, parentLayerPlan, reason) {
56
+ this.operationPlan = operationPlan;
57
+ this.parentLayerPlan = parentLayerPlan;
58
+ this.reason = reason;
59
+ /**
60
+ * Every layer plan has a "root step" that shapes the value the layer
61
+ * returns. Note that this step may be dependent on other steps included in
62
+ * the LayerPlan, or could be provided externally.
63
+ *
64
+ * The root step is different for different layer step reasons:
65
+ *
66
+ * - root: the `operationPlan.rootValue`
67
+ * - listItem: the `__ItemStep`
68
+ * - stream: also the `__ItemStep`
69
+ * - subscription: also the `__ItemStep`
70
+ * - mutationField: the result plan of the mutation field
71
+ * - defer: the parent layer's rootStep (defer always results in an object, unless an error occurs)
72
+ * - polymorphic: the plan for the particular type
73
+ * - subroutine: the result (returned) plan of the subroutine
74
+ *
75
+ * @internal
76
+ */
77
+ this.rootStep = null;
78
+ /**
79
+ * Which plans the results for which are available in a parent bucket need to
80
+ * be "copied across" to this bucket because plans in this bucket still
81
+ * reference them?
82
+ *
83
+ * @internal
84
+ */
85
+ this.copyStepIds = [];
86
+ /** @internal */
87
+ this.children = [];
88
+ /** @internal */
89
+ this.steps = [];
90
+ /** @internal */
91
+ this.pendingSteps = [];
92
+ /**
93
+ * Describes the order in which the steps within this LayerPlan are executed.
94
+ *
95
+ * Special attention must be paid to steps that have side effects.
96
+ *
97
+ * @internal
98
+ */
99
+ this.phases = [];
100
+ this.stepsByConstructor = new Map();
101
+ if (parentLayerPlan !== null) {
102
+ this.depth = parentLayerPlan.depth + 1;
103
+ this.ancestry = [...parentLayerPlan.ancestry, this];
104
+ if (isDeferredLayerPlan(this)) {
105
+ this.deferBoundaryDepth = this.depth;
106
+ }
107
+ else {
108
+ this.deferBoundaryDepth = parentLayerPlan.deferBoundaryDepth;
109
+ }
110
+ }
111
+ else {
112
+ this.depth = 0;
113
+ this.ancestry = [this];
114
+ this.deferBoundaryDepth = 0;
115
+ }
116
+ this.id = operationPlan.addLayerPlan(this);
117
+ if (!parentLayerPlan) {
118
+ assert.strictEqual(this.id, 0, "All but the first LayerPlan must have a parent");
119
+ }
120
+ else {
121
+ assert.ok(reason.type != "root", "Non-root LayerPlan must have a parentStep");
122
+ parentLayerPlan.children.push(this);
123
+ }
124
+ }
125
+ toString() {
126
+ let chain = "";
127
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
128
+ let current = this;
129
+ while ((current = current.parentLayerPlan)) {
130
+ chain = chain + `∈${current.id}`;
131
+ }
132
+ const reasonExtra = this.reason.type === "polymorphic"
133
+ ? `{${this.reason.typeNames.join(",")}}`
134
+ : "";
135
+ const deps = this.copyStepIds.length > 0 ? `%${this.copyStepIds}` : "";
136
+ return `LayerPlan<${this.id}${chain}?${this.reason.type}${reasonExtra}!${this.rootStep?.id ?? "x"}${deps}>`;
137
+ }
138
+ print(depth = 0) {
139
+ const output = [`${" ".repeat(depth * 2)}${this}`];
140
+ for (const child of this.children) {
141
+ output.push(child.print(depth + 1));
142
+ }
143
+ return output.join("\n");
144
+ }
145
+ setRootStep($root) {
146
+ this.operationPlan.stepTracker.setLayerPlanRootStep(this, $root);
147
+ }
148
+ /** @internal Use plan.getStep(id) instead. */
149
+ getStep(id, requestingStep) {
150
+ return this.operationPlan.getStep(id, requestingStep);
151
+ }
152
+ /** @internal */
153
+ _addStep(step) {
154
+ return this.operationPlan._addStep(step);
155
+ }
156
+ /** @internal */
157
+ _addModifierStep(step) {
158
+ return this.operationPlan._addModifierStep(step);
159
+ }
160
+ finalize() {
161
+ if (this.reason.type === "nullableBoundary" ||
162
+ this.reason.type === "listItem") {
163
+ const n = this.copyStepIds.length;
164
+ const signature = this.reason.type[0] + n;
165
+ withNewBucketFactory(signature, n, this.reason.type, (fn) => {
166
+ this.newBucket = fn(this.copyStepIds);
167
+ });
168
+ }
169
+ }
170
+ newBucket(parentBucket) {
171
+ const copyStepIds = this.copyStepIds;
172
+ const store = new Map();
173
+ const polymorphicPathList = this.reason.type === "mutationField"
174
+ ? parentBucket.polymorphicPathList
175
+ : [];
176
+ const iterators = this.reason.type === "mutationField" ? parentBucket.iterators : [];
177
+ const map = new Map();
178
+ let size = 0;
179
+ switch (this.reason.type) {
180
+ case "nullableBoundary": {
181
+ const itemStepId = this.rootStep?.id;
182
+ assert.ok(itemStepId != null, "GrafastInternalError<f8136364-46c7-4886-b2ae-51319826f97d>: nullableStepStore layer plan has no rootStepId");
183
+ const nullableStepStore = parentBucket.store.get(itemStepId);
184
+ if (!nullableStepStore) {
185
+ throw new Error(`GrafastInternalError<017dc8bf-1db1-4983-a41e-e69c6652e4c7>: could not find entry '${itemStepId}' (${parentBucket.layerPlan.operationPlan.dangerouslyGetStep(itemStepId)}) in store for ${parentBucket.layerPlan}`);
186
+ }
187
+ // PERF: if parent bucket has no nulls/errors in `itemStepId`
188
+ // then we can just copy everything wholesale rather than building
189
+ // new arrays and looping.
190
+ const hasNoNullsOrErrors = false;
191
+ if (hasNoNullsOrErrors) {
192
+ store.set(itemStepId, nullableStepStore);
193
+ for (const planId of copyStepIds) {
194
+ store.set(planId, parentBucket.store.get(planId));
195
+ }
196
+ for (let originalIndex = 0; originalIndex < parentBucket.size; originalIndex++) {
197
+ const newIndex = size++;
198
+ map.set(originalIndex, newIndex);
199
+ polymorphicPathList[newIndex] =
200
+ parentBucket.polymorphicPathList[originalIndex];
201
+ iterators[newIndex] = parentBucket.iterators[originalIndex];
202
+ }
203
+ }
204
+ else {
205
+ const itemStepIdList = [];
206
+ store.set(itemStepId, itemStepIdList);
207
+ // Prepare store with an empty list for each copyPlanId
208
+ for (const planId of copyStepIds) {
209
+ store.set(planId, []);
210
+ }
211
+ // We'll typically be creating fewer nullableBoundary bucket entries
212
+ // than we have parent bucket entries (because we exclude nulls), so
213
+ // we must "multiply up" (down) the store entries.
214
+ for (let originalIndex = 0; originalIndex < parentBucket.size; originalIndex++) {
215
+ const fieldValue = nullableStepStore[originalIndex];
216
+ if (fieldValue != null) {
217
+ const newIndex = size++;
218
+ map.set(originalIndex, newIndex);
219
+ itemStepIdList[newIndex] = fieldValue;
220
+ polymorphicPathList[newIndex] =
221
+ parentBucket.polymorphicPathList[originalIndex];
222
+ iterators[newIndex] = parentBucket.iterators[originalIndex];
223
+ for (const planId of copyStepIds) {
224
+ store.get(planId)[newIndex] =
225
+ parentBucket.store.get(planId)[originalIndex];
226
+ }
227
+ }
228
+ }
229
+ }
230
+ break;
231
+ }
232
+ case "listItem": {
233
+ const listStepId = this.reason.parentStep.id;
234
+ const listStepStore = parentBucket.store.get(listStepId);
235
+ if (!listStepStore) {
236
+ throw new Error(`GrafastInternalError<314865b0-f7e8-4e81-b966-56e5a0de562e>: could not find entry '${listStepId}' (${parentBucket.layerPlan.operationPlan.dangerouslyGetStep(listStepId)}) in store for layerPlan ${parentBucket.layerPlan}`);
237
+ }
238
+ const itemStepId = this.rootStep?.id;
239
+ if (itemStepId == null) {
240
+ throw new Error("GrafastInternalError<b3a2bff9-15c6-47e2-aa82-19c862324f1a>: listItem layer plan has no rootStepId");
241
+ }
242
+ store.set(itemStepId, []);
243
+ // Prepare store with an empty list for each copyPlanId
244
+ for (const planId of copyStepIds) {
245
+ store.set(planId, []);
246
+ }
247
+ // We'll typically be creating more listItem bucket entries than we
248
+ // have parent buckets, so we must "multiply up" the store entries.
249
+ for (let originalIndex = 0; originalIndex < parentBucket.size; originalIndex++) {
250
+ const list = listStepStore[originalIndex];
251
+ if (Array.isArray(list)) {
252
+ const newIndexes = [];
253
+ map.set(originalIndex, newIndexes);
254
+ for (let j = 0, l = list.length; j < l; j++) {
255
+ const newIndex = size++;
256
+ newIndexes.push(newIndex);
257
+ store.get(itemStepId)[newIndex] = list[j];
258
+ polymorphicPathList[newIndex] =
259
+ parentBucket.polymorphicPathList[originalIndex];
260
+ iterators[newIndex] = parentBucket.iterators[originalIndex];
261
+ for (const planId of copyStepIds) {
262
+ store.get(planId)[newIndex] =
263
+ parentBucket.store.get(planId)[originalIndex];
264
+ }
265
+ }
266
+ }
267
+ }
268
+ break;
269
+ }
270
+ case "mutationField": {
271
+ // This is a 1-to-1 map, so we can mostly just copy from parent bucket
272
+ size = parentBucket.size;
273
+ for (let i = 0; i < parentBucket.size; i++) {
274
+ map.set(i, i);
275
+ }
276
+ for (const planId of copyStepIds) {
277
+ store.set(planId, parentBucket.store.get(planId));
278
+ }
279
+ break;
280
+ }
281
+ case "polymorphic": {
282
+ const polymorphicPlanId = this.reason.parentStep.id;
283
+ const polymorphicPlanStore = parentBucket.store.get(polymorphicPlanId);
284
+ if (!polymorphicPlanStore) {
285
+ throw new Error(`GrafastInternalError<af1417c6-752b-466e-af7e-cfc35724c3bc>: Entry for '${parentBucket.layerPlan.operationPlan.dangerouslyGetStep(polymorphicPlanId)}' not found in bucket for '${parentBucket.layerPlan}'`);
286
+ }
287
+ // We're only copying over the entries that match this type (note:
288
+ // they may end up being null, but that's okay)
289
+ const targetTypeNames = this.reason.typeNames;
290
+ for (const planId of copyStepIds) {
291
+ store.set(planId, []);
292
+ if (!parentBucket.store.has(planId)) {
293
+ throw new Error(`GrafastInternalError<548f0d84-4556-4189-8655-fb16aa3345a6>: new bucket for ${this} wants to copy ${this.operationPlan.dangerouslyGetStep(planId)}, but bucket for ${parentBucket.layerPlan} doesn't contain that plan`);
294
+ }
295
+ }
296
+ for (let originalIndex = 0; originalIndex < parentBucket.size; originalIndex++) {
297
+ const value = polymorphicPlanStore[originalIndex];
298
+ if (value == null) {
299
+ continue;
300
+ }
301
+ if ((0, error_js_1.isGrafastError)(value)) {
302
+ continue;
303
+ }
304
+ const typeName = (0, polymorphic_js_1.resolveType)(value);
305
+ if (!targetTypeNames.includes(typeName)) {
306
+ continue;
307
+ }
308
+ const newIndex = size++;
309
+ map.set(originalIndex, newIndex);
310
+ // PERF: might be faster if we look this up as a constant rather than using concatenation here
311
+ const newPolymorphicPath = (parentBucket.polymorphicPathList[originalIndex] ?? "") +
312
+ ">" +
313
+ typeName;
314
+ polymorphicPathList[newIndex] = newPolymorphicPath;
315
+ iterators[newIndex] = parentBucket.iterators[originalIndex];
316
+ for (const planId of copyStepIds) {
317
+ store.get(planId)[newIndex] =
318
+ parentBucket.store.get(planId)[originalIndex];
319
+ }
320
+ }
321
+ break;
322
+ }
323
+ case "subscription":
324
+ case "defer": {
325
+ // TODO
326
+ throw new Error("TODO");
327
+ }
328
+ case "subroutine": {
329
+ throw new Error("Subroutines are experimental and must currently handle their own bucket creation");
330
+ }
331
+ case "root": {
332
+ throw new Error(
333
+ // *confused emoji*
334
+ "GrafastInternalError<05fb7069-81b5-43f7-ae71-f62547d2c2b7>: root cannot be not the root (...)");
335
+ }
336
+ default: {
337
+ const never = this.reason;
338
+ throw new Error(`GrafastInternalError<8162e6c2-3d66-4d67-ba03-5310a4f9a6d4>: unhandled reason '${(0, inspect_js_1.inspect)(never)}'`);
339
+ }
340
+ }
341
+ if (size > 0) {
342
+ // Reference
343
+ const childBucket = (0, executeBucket_js_1.newBucket)({
344
+ layerPlan: this,
345
+ size,
346
+ store,
347
+ // PERF: not necessarily, if we don't copy the errors, we don't have the errors.
348
+ hasErrors: parentBucket.hasErrors,
349
+ polymorphicPathList,
350
+ iterators,
351
+ }, parentBucket.metaByMetaKey);
352
+ parentBucket.children[this.id] = {
353
+ bucket: childBucket,
354
+ map,
355
+ };
356
+ return childBucket;
357
+ }
358
+ else {
359
+ return null;
360
+ }
361
+ }
362
+ }
363
+ exports.LayerPlan = LayerPlan;
364
+ const makeNewBucketCache = new lru_1.default({
365
+ maxLength: 1000,
366
+ });
367
+ const makingNewBucketCallbacks = new Map();
368
+ const te_parentBucketDotPolymorphicPathList = (0, tamedevil_1.default) `parentBucket.polymorphicPathList`;
369
+ const te_parentBucketDotIterators = (0, tamedevil_1.default) `parentBucket.iterators`;
370
+ const te_emptyArray = (0, tamedevil_1.default) `[]`;
371
+ const ref_newBucket = tamedevil_1.default.ref(executeBucket_js_1.newBucket, "newBucket");
372
+ function makeNewBucketExpression(signature, reasonType, inner) {
373
+ return (0, tamedevil_1.default) `\
374
+ (function ${tamedevil_1.default.identifier(`newBucket_${signature}`)}(parentBucket) {
375
+ const store = new Map();
376
+ const polymorphicPathList = ${reasonType === "mutationField"
377
+ ? te_parentBucketDotPolymorphicPathList
378
+ : te_emptyArray};
379
+ const iterators = ${reasonType === "mutationField" ? te_parentBucketDotIterators : te_emptyArray};
380
+ const map = new Map();
381
+ let size = 0;
382
+
383
+ ${inner}
384
+
385
+ if (size > 0) {
386
+ // Reference
387
+ const childBucket = ${ref_newBucket}({
388
+ layerPlan: this,
389
+ size,
390
+ store,
391
+ // PERF: not necessarily, if we don't copy the errors, we don't have the errors.
392
+ hasErrors: parentBucket.hasErrors,
393
+ polymorphicPathList,
394
+ iterators,
395
+ }, parentBucket.metaByMetaKey);
396
+ // PERF: set ourselves in more places so that we never have to call 'getChildBucketAndIndex'.
397
+ parentBucket.children[this.id] = { bucket: childBucket, map };
398
+
399
+ return childBucket;
400
+ } else {
401
+ return null;
402
+ }
403
+ })`;
404
+ }
405
+ function newBucketFactoryInnerExpression(signature, copyCount, reasonType) {
406
+ if (reasonType === "nullableBoundary") {
407
+ // PERF: if parent bucket has no nulls/errors in itemStepId
408
+ // then we can just copy everything wholesale rather than building
409
+ // new arrays and looping.
410
+ const blocks = [];
411
+ const copyBlocks = [];
412
+ for (let i = 0; i < copyCount; i++) {
413
+ const te_source = tamedevil_1.default.identifier(`source${i}`);
414
+ const te_target = tamedevil_1.default.identifier(`target${i}`);
415
+ const te_i = tamedevil_1.default.lit(i);
416
+ blocks.push((0, tamedevil_1.default) `\
417
+ const ${te_source} = parentBucket.store.get(copyPlanIds[${te_i}]);
418
+ const ${te_target} = [];
419
+ store.set(copyPlanIds[${te_i}], ${te_target});
420
+ `);
421
+ copyBlocks.push((0, tamedevil_1.default) `\
422
+ ${te_target}[newIndex] = ${te_source}[originalIndex];
423
+ `);
424
+ }
425
+ return makeNewBucketExpression(signature, reasonType, (0, tamedevil_1.default) `\
426
+ const itemStepId = this.rootStep.id;
427
+ const nullableStepStore = parentBucket.store.get(itemStepId);
428
+
429
+ const itemStepIdList = [];
430
+ store.set(itemStepId, itemStepIdList);
431
+
432
+ // Prepare store with an empty list for each copyPlanId
433
+ ${tamedevil_1.default.join(blocks, "")}
434
+
435
+ // We'll typically be creating fewer nullableBoundary bucket entries
436
+ // than we have parent bucket entries (because we exclude nulls), so
437
+ // we must "multiply up" (down) the store entries.
438
+ for (
439
+ let originalIndex = 0;
440
+ originalIndex < parentBucket.size;
441
+ originalIndex++
442
+ ) {
443
+ const fieldValue = nullableStepStore[originalIndex];
444
+ if (fieldValue != null) {
445
+ const newIndex = size++;
446
+ map.set(originalIndex, newIndex);
447
+ itemStepIdList[newIndex] = fieldValue;
448
+
449
+ polymorphicPathList[newIndex] = parentBucket.polymorphicPathList[originalIndex];
450
+ iterators[newIndex] = parentBucket.iterators[originalIndex];
451
+ ${tamedevil_1.default.join(copyBlocks, "")}
452
+ }
453
+ }
454
+ `);
455
+ }
456
+ else if (reasonType === "listItem") {
457
+ const blocks = [];
458
+ const copyBlocks = [];
459
+ for (let i = 0; i < copyCount; i++) {
460
+ const te_source = tamedevil_1.default.identifier(`source${i}`);
461
+ const te_target = tamedevil_1.default.identifier(`target${i}`);
462
+ const te_i = tamedevil_1.default.lit(i);
463
+ blocks.push((0, tamedevil_1.default) `\
464
+ const ${te_source} = parentBucket.store.get(copyPlanIds[${te_i}]);
465
+ const ${te_target} = [];
466
+ store.set(copyPlanIds[${te_i}], ${te_target});
467
+ `);
468
+ copyBlocks.push((0, tamedevil_1.default) `\
469
+ ${te_target}[newIndex] = ${te_source}[originalIndex];
470
+ `);
471
+ }
472
+ return makeNewBucketExpression(signature, reasonType, (0, tamedevil_1.default) `\
473
+ const listStepStore = parentBucket.store.get(this.reason.parentStep.id);
474
+
475
+ const itemStepIdList = [];
476
+ store.set(this.rootStep.id, itemStepIdList);
477
+
478
+ // Prepare store with an empty list for each copyPlanId
479
+ ${tamedevil_1.default.join(blocks, "")}
480
+
481
+ // We'll typically be creating more listItem bucket entries than we
482
+ // have parent buckets, so we must "multiply up" the store entries.
483
+ for (
484
+ let originalIndex = 0;
485
+ originalIndex < parentBucket.size;
486
+ originalIndex++
487
+ ) {
488
+ const list = listStepStore[originalIndex];
489
+ if (Array.isArray(list)) {
490
+ const newIndexes = [];
491
+ map.set(originalIndex, newIndexes);
492
+ for (let j = 0, l = list.length; j < l; j++) {
493
+ const newIndex = size++;
494
+ newIndexes.push(newIndex);
495
+ itemStepIdList[newIndex] = list[j];
496
+
497
+ polymorphicPathList[newIndex] = parentBucket.polymorphicPathList[originalIndex];
498
+ iterators[newIndex] = parentBucket.iterators[originalIndex];
499
+ ${tamedevil_1.default.join(copyBlocks, "")}
500
+ }
501
+ }
502
+ }
503
+
504
+ `);
505
+ }
506
+ else {
507
+ const never = reasonType;
508
+ return never;
509
+ }
510
+ }
511
+ function withNewBucketFactory(signature, copyCount, reasonType, callback) {
512
+ const fn = makeNewBucketCache.get(signature);
513
+ if (fn !== undefined) {
514
+ return callback(fn);
515
+ }
516
+ const building = makingNewBucketCallbacks.get(signature);
517
+ if (building !== undefined) {
518
+ building.push(callback);
519
+ return;
520
+ }
521
+ const callbacks = [callback];
522
+ makingNewBucketCallbacks.set(signature, callbacks);
523
+ const executorExpression = newBucketFactoryInnerExpression(signature, copyCount, reasonType);
524
+ const factoryExpression = (0, tamedevil_1.default) `\
525
+ function ${tamedevil_1.default.identifier(`layerPlanNewBucketFactory_${signature}`)}(copyPlanIds) {
526
+ return ${executorExpression};
527
+ }`;
528
+ tamedevil_1.default.runInBatch(factoryExpression, (factory) => {
529
+ makeNewBucketCache.set(signature, factory);
530
+ makingNewBucketCallbacks.delete(signature);
531
+ for (const callback of callbacks) {
532
+ callback(factory);
533
+ }
534
+ });
535
+ }
536
+ //# sourceMappingURL=LayerPlan.js.map