grafast 0.1.1-beta.14 → 0.1.1-beta.16

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 CHANGED
@@ -53,6 +53,8 @@ And please give some love to our featured sponsors 🤩:
53
53
  <td align="center"><a href="https://dovetailapp.com/"><img src="https://graphile.org/images/sponsors/dovetail.png" width="90" height="90" alt="Dovetail" /><br />Dovetail</a> *</td>
54
54
  <td align="center"><a href="https://stellate.co/"><img src="https://graphile.org/images/sponsors/Stellate.png" width="90" height="90" alt="Stellate" /><br />Stellate</a> *</td>
55
55
  <td align="center"><a href="https://gosteelhead.com/"><img src="https://graphile.org/images/sponsors/steelhead.svg" width="90" height="90" alt="Steelhead" /><br />Steelhead</a> *</td>
56
+ </tr><tr>
57
+ <td align="center"><a href=""><img src="https://graphile.org/images/sponsors/latchbio.jpg" width="90" height="90" alt="LatchBio" /><br />LatchBio</a> *</td>
56
58
  </tr></table>
57
59
 
58
60
  <em>\* Sponsors the entire Graphile suite</em>
@@ -615,9 +615,7 @@ class OperationPlan {
615
615
  const rawPlanResolver = objectField.extensions?.grafast?.plan;
616
616
  if (rawPlanResolver) {
617
617
  resolverEmulation = false;
618
- }
619
- if (rawPlanResolver?.constructor?.name === "AsyncFunction") {
620
- throw new Error(`Plans must be synchronous, but this schema has an async function at '${objectType.name}.${fieldName}.plan': ${rawPlanResolver.toString()}`);
618
+ (0, utils_js_1.assertNotAsync)(rawPlanResolver, `${objectType.name}.${fieldName}.plan`);
621
619
  }
622
620
  const namedReturnType = getNamedType(fieldType);
623
621
  const resolvedResolver = objectField.resolve;
@@ -848,13 +846,12 @@ class OperationPlan {
848
846
  }
849
847
  else if (isScalarType(nullableFieldType)) {
850
848
  const scalarPlanResolver = nullableFieldType.extensions?.grafast?.plan;
851
- if (scalarPlanResolver?.constructor?.name === "AsyncFunction") {
852
- throw new Error(`Plans must be synchronous, but this schema has an async function at '${nullableFieldType.name}.plan': ${scalarPlanResolver.toString()}`);
853
- }
849
+ const fnDescription = `${nullableFieldType.name}.plan`;
850
+ (0, utils_js_1.assertNotAsync)(scalarPlanResolver, fnDescription);
854
851
  const $sideEffect = parentLayerPlan.latestSideEffectStep;
855
852
  try {
856
853
  const $leaf = typeof scalarPlanResolver === "function"
857
- ? (0, withGlobalLayerPlan_js_1.withGlobalLayerPlan)(parentLayerPlan, polymorphicPaths, scalarPlanResolver, null, $step, this.scalarPlanInfo)
854
+ ? (0, utils_js_1.assertNotPromise)((0, withGlobalLayerPlan_js_1.withGlobalLayerPlan)(parentLayerPlan, polymorphicPaths, scalarPlanResolver, null, $step, this.scalarPlanInfo), scalarPlanResolver, fnDescription)
858
855
  : $step;
859
856
  parentOutputPlan.addChild(parentObjectType, responseKey, {
860
857
  type: "outputPlan",
@@ -1021,7 +1018,7 @@ class OperationPlan {
1021
1018
  try {
1022
1019
  /* TODO: this $oldStep / $step dance turned out to be necessary
1023
1020
  * because `$step` was being replaced in the following query against
1024
- * the pggql_test `polymorpic` schema; but I'm not sure this is the
1021
+ * the graphilecrystaltest `polymorpic` schema; but I'm not sure this is the
1025
1022
  * right behavior - shouldn't deduplication have been temporarily
1026
1023
  * disabled during this?
1027
1024
  *
@@ -49,6 +49,12 @@ function evalDirectiveArgDirect(directive, argumentName, variableValuesStep, def
49
49
  case "IntValue": {
50
50
  return parseInt(value.value, 10);
51
51
  }
52
+ case "FloatValue": {
53
+ return parseFloat(value.value);
54
+ }
55
+ case "StringValue": {
56
+ return value.value;
57
+ }
52
58
  case "NullValue": {
53
59
  return null;
54
60
  }
package/dist/index.d.ts CHANGED
@@ -17,6 +17,8 @@ import { grafast, grafastSync } from "./grafastGraphql.js";
17
17
  import type { $$cacheByOperation, $$hooked, $$queryCache, CacheByOperationEntry, DataFromStep, EstablishOperationPlanEvent, ExecuteEvent, ExecuteStepEvent, GrafastExecutionArgs, GrafastTimeouts, ParseAndValidateEvent, PrepareArgsEvent, ScalarInputPlanResolver, StreamStepEvent, ValidateSchemaEvent } from "./interfaces.js";
18
18
  import { $$bypassGraphQL, $$eventEmitter, $$extensions, $$idempotent, $$verbatim, ArgumentApplyPlanResolver, ArgumentInputPlanResolver, BaseEventMap, BaseGraphQLArguments, BaseGraphQLRootValue, BaseGraphQLVariables, EnumValueApplyPlanResolver, EventCallback, EventMapKey, ExecutionDetails, ExecutionEventEmitter, ExecutionEventMap, ExecutionExtra, FieldArgs, FieldInfo, FieldPlanResolver, GrafastArgumentConfig, GrafastFieldConfig, GrafastFieldConfigArgumentMap, GrafastInputFieldConfig, GrafastPlanJSON, GrafastResultsList, GrafastResultStreamList, GrafastSubscriber, GrafastValuesList, InputObjectFieldApplyPlanResolver, InputObjectFieldInputPlanResolver, InputObjectTypeInputPlanResolver, InputStep, JSONArray, JSONObject, JSONValue, Maybe, NodeIdCodec, NodeIdHandler, OutputPlanForType, PolymorphicData, PromiseOrDirect, ScalarPlanResolver, StepOptimizeOptions, StepStreamOptions, TypedEventEmitter, UnbatchedExecutionExtra } from "./interfaces.js";
19
19
  import { getGrafastMiddleware } from "./middleware.js";
20
+ import type { Multistep, UnwrapMultistep } from "./multistep.js";
21
+ import { multistep } from "./multistep.js";
20
22
  import { polymorphicWrap } from "./polymorphic.js";
21
23
  import { assertExecutableStep, assertListCapableStep, assertModifierStep, BaseStep, ExecutableStep, isExecutableStep, isListCapableStep, isListLikeStep, isModifierStep, isObjectLikeStep, isStreamableStep, ListCapableStep, ListLikeStep, ModifierStep, ObjectLikeStep, PolymorphicStep, StreamableStep, UnbatchedExecutableStep } from "./step.js";
22
24
  import { __FlagStep, __InputListStep, __InputObjectStep, __InputObjectStepWithDollars, __InputStaticLeafStep, __ItemStep, __ListTransformStep, __TrackedValueStep, __TrackedValueStepWithDollars, __ValueStep, access, AccessStep, ActualKeyByDesiredKey, applyTransforms, ApplyTransformsStep, assertEdgeCapableStep, assertNotNull, assertPageInfoCapableStep, condition, ConditionStep, connection, ConnectionCapableStep, ConnectionStep, constant, ConstantStep, context, debugPlans, each, EdgeCapableStep, EdgeStep, error, ErrorStep, filter, FilterPlanMemo, first, FirstStep, GraphQLItemHandler, graphqlItemHandler, graphqlResolver, GraphQLResolverStep, groupBy, GroupByPlanMemo, inhibitOnNull, lambda, LambdaStep, last, LastStep, list, listen, ListenStep, ListStep, listTransform, ListTransformItemPlanCallback, ListTransformOptions, ListTransformReduce, LoadedRecordStep, loadMany, LoadManyCallback, loadManyCallback, loadOne, LoadOneCallback, loadOneCallback, LoadOptions, LoadStep, makeDecodeNodeId, node, nodeIdFromNode, NodeStep, object, ObjectPlanMeta, ObjectStep, operationPlan, PageInfoCapableStep, partitionByIndex, polymorphicBranch, PolymorphicBranchMatcher, PolymorphicBranchMatchers, PolymorphicBranchStep, proxy, ProxyStep, remapKeys, RemapKeysStep, reverse, reverseArray, ReverseStep, rootValue, setter, SetterCapableStep, SetterStep, sideEffect, SideEffectStep, specFromNodeId, trackedContext, trackedRootValue, trap, TRAP_ERROR, TRAP_ERROR_OR_INHIBITED, TRAP_INHIBITED } from "./steps/index.js";
@@ -25,7 +27,7 @@ import { stripAnsi } from "./stripAnsi.js";
25
27
  import { subscribe } from "./subscribe.js";
26
28
  import { arrayOfLength, arraysMatch, getEnumValueConfig, GrafastInputFieldConfigMap, GrafastInputObjectType, GrafastObjectType, inputObjectFieldSpec, InputObjectTypeSpec, isPromiseLike, newGrafastFieldConfigBuilder, newInputObjectTypeBuilder, newObjectTypeBuilder, objectFieldSpec, objectSpec, ObjectTypeFields, ObjectTypeSpec, stepADependsOnStepB, stepAMayDependOnStepB, stepsAreInSamePhase } from "./utils.js";
27
29
  export { isAsyncIterable } from "iterall";
28
- export { __FlagStep, __InputListStep, __InputObjectStep, __InputObjectStepWithDollars, __InputStaticLeafStep, __ItemStep, __ListTransformStep, __TrackedValueStep, __TrackedValueStepWithDollars, __ValueStep, $$bypassGraphQL, $$eventEmitter, $$extensions, $$idempotent, $$inhibit, $$verbatim, access, AccessStep, ActualKeyByDesiredKey, applyTransforms, ApplyTransformsStep, ArgumentApplyPlanResolver, ArgumentInputPlanResolver, arrayOfLength, arraysMatch, assertEdgeCapableStep, assertExecutableStep, assertListCapableStep, assertModifierStep, assertNotNull, assertPageInfoCapableStep, BaseEventMap, BaseGraphQLArguments, BaseGraphQLRootValue, BaseGraphQLVariables, BaseStep, condition, ConditionStep, connection, ConnectionCapableStep, ConnectionStep, constant, ConstantStep, context, DataFromObjectSteps, DataFromStep, debugPlans, defer, Deferred, each, EdgeCapableStep, EdgeStep, EnumPlans, EnumValueApplyPlanResolver, error, ErrorStep, EventCallback, EventMapKey, ExecutableStep, execute, ExecutionDetails, ExecutionEventEmitter, ExecutionEventMap, ExecutionExtra, exportAs, exportAsMany, FieldArgs, FieldInfo, FieldPlanResolver, FieldPlans, filter, FilterPlanMemo, first, FirstStep, flagError, getEnumValueConfig, getGrafastMiddleware, grafast, GrafastArgumentConfig, GrafastExecutionArgs, GrafastFieldConfig, GrafastFieldConfigArgumentMap, grafast as grafastGraphql, grafastSync as grafastGraphqlSync, GrafastInputFieldConfig, GrafastInputFieldConfigMap, GrafastInputObjectType, GrafastObjectType, GrafastPlanJSON, GrafastPlans, grafastPrint, GrafastResultsList, GrafastResultStreamList, GrafastSubscriber, grafastSync, GrafastValuesList, GraphQLItemHandler, graphqlItemHandler, graphqlResolver, GraphQLResolverStep, groupBy, GroupByPlanMemo, inhibitOnNull, InputObjectFieldApplyPlanResolver, InputObjectFieldInputPlanResolver, inputObjectFieldSpec, InputObjectPlans, InputObjectTypeInputPlanResolver, InputObjectTypeSpec, InputStep, InterfaceOrUnionPlans, isDev, isExecutableStep, isListCapableStep, isListLikeStep, isModifierStep, isObjectLikeStep, isPromiseLike, isSafeError, isStreamableStep, isUnaryStep, JSONArray, JSONObject, JSONValue, lambda, LambdaStep, last, LastStep, list, ListCapableStep, listen, ListenStep, ListLikeStep, ListStep, listTransform, ListTransformItemPlanCallback, ListTransformOptions, ListTransformReduce, LoadedRecordStep, loadMany, LoadManyCallback, loadManyCallback, loadOne, LoadOneCallback, loadOneCallback, LoadOptions, LoadStep, makeDecodeNodeId, makeGrafastSchema, Maybe, ModifierStep, newGrafastFieldConfigBuilder, newInputObjectTypeBuilder, newObjectTypeBuilder, node, NodeIdCodec, nodeIdFromNode, NodeIdHandler, NodeStep, noop, object, objectFieldSpec, ObjectLikeStep, ObjectPlanMeta, ObjectPlans, objectSpec, ObjectStep, ObjectTypeFields, ObjectTypeSpec, OperationPlan, operationPlan, OutputPlanForType, PageInfoCapableStep, partitionByIndex, polymorphicBranch, PolymorphicBranchMatcher, PolymorphicBranchMatchers, PolymorphicBranchStep, PolymorphicData, PolymorphicStep, polymorphicWrap, PromiseOrDirect, proxy, ProxyStep, remapKeys, RemapKeysStep, reverse, reverseArray, ReverseStep, rootValue, SafeError, ScalarPlanResolver, ScalarPlans, setter, SetterCapableStep, SetterStep, sideEffect, SideEffectStep, specFromNodeId, stepADependsOnStepB, stepAMayDependOnStepB, StepOptimizeOptions, stepsAreInSamePhase, StepStreamOptions, StreamableStep, stringifyPayload, stripAnsi, subscribe, trackedContext, trackedRootValue, trap, TRAP_ERROR, TRAP_ERROR_OR_INHIBITED, TRAP_INHIBITED, TypedEventEmitter, UnbatchedExecutableStep, UnbatchedExecutionExtra, };
30
+ export { __FlagStep, __InputListStep, __InputObjectStep, __InputObjectStepWithDollars, __InputStaticLeafStep, __ItemStep, __ListTransformStep, __TrackedValueStep, __TrackedValueStepWithDollars, __ValueStep, $$bypassGraphQL, $$eventEmitter, $$extensions, $$idempotent, $$inhibit, $$verbatim, access, AccessStep, ActualKeyByDesiredKey, applyTransforms, ApplyTransformsStep, ArgumentApplyPlanResolver, ArgumentInputPlanResolver, arrayOfLength, arraysMatch, assertEdgeCapableStep, assertExecutableStep, assertListCapableStep, assertModifierStep, assertNotNull, assertPageInfoCapableStep, BaseEventMap, BaseGraphQLArguments, BaseGraphQLRootValue, BaseGraphQLVariables, BaseStep, condition, ConditionStep, connection, ConnectionCapableStep, ConnectionStep, constant, ConstantStep, context, DataFromObjectSteps, DataFromStep, debugPlans, defer, Deferred, each, EdgeCapableStep, EdgeStep, EnumPlans, EnumValueApplyPlanResolver, error, ErrorStep, EventCallback, EventMapKey, ExecutableStep, execute, ExecutionDetails, ExecutionEventEmitter, ExecutionEventMap, ExecutionExtra, exportAs, exportAsMany, FieldArgs, FieldInfo, FieldPlanResolver, FieldPlans, filter, FilterPlanMemo, first, FirstStep, flagError, getEnumValueConfig, getGrafastMiddleware, grafast, GrafastArgumentConfig, GrafastExecutionArgs, GrafastFieldConfig, GrafastFieldConfigArgumentMap, grafast as grafastGraphql, grafastSync as grafastGraphqlSync, GrafastInputFieldConfig, GrafastInputFieldConfigMap, GrafastInputObjectType, GrafastObjectType, GrafastPlanJSON, GrafastPlans, grafastPrint, GrafastResultsList, GrafastResultStreamList, GrafastSubscriber, grafastSync, GrafastValuesList, GraphQLItemHandler, graphqlItemHandler, graphqlResolver, GraphQLResolverStep, groupBy, GroupByPlanMemo, inhibitOnNull, InputObjectFieldApplyPlanResolver, InputObjectFieldInputPlanResolver, inputObjectFieldSpec, InputObjectPlans, InputObjectTypeInputPlanResolver, InputObjectTypeSpec, InputStep, InterfaceOrUnionPlans, isDev, isExecutableStep, isListCapableStep, isListLikeStep, isModifierStep, isObjectLikeStep, isPromiseLike, isSafeError, isStreamableStep, isUnaryStep, JSONArray, JSONObject, JSONValue, lambda, LambdaStep, last, LastStep, list, ListCapableStep, listen, ListenStep, ListLikeStep, ListStep, listTransform, ListTransformItemPlanCallback, ListTransformOptions, ListTransformReduce, LoadedRecordStep, loadMany, LoadManyCallback, loadManyCallback, loadOne, LoadOneCallback, loadOneCallback, LoadOptions, LoadStep, makeDecodeNodeId, makeGrafastSchema, Maybe, ModifierStep, Multistep, multistep, newGrafastFieldConfigBuilder, newInputObjectTypeBuilder, newObjectTypeBuilder, node, NodeIdCodec, nodeIdFromNode, NodeIdHandler, NodeStep, noop, object, objectFieldSpec, ObjectLikeStep, ObjectPlanMeta, ObjectPlans, objectSpec, ObjectStep, ObjectTypeFields, ObjectTypeSpec, OperationPlan, operationPlan, OutputPlanForType, PageInfoCapableStep, partitionByIndex, polymorphicBranch, PolymorphicBranchMatcher, PolymorphicBranchMatchers, PolymorphicBranchStep, PolymorphicData, PolymorphicStep, polymorphicWrap, PromiseOrDirect, proxy, ProxyStep, remapKeys, RemapKeysStep, reverse, reverseArray, ReverseStep, rootValue, SafeError, ScalarPlanResolver, ScalarPlans, setter, SetterCapableStep, SetterStep, sideEffect, SideEffectStep, specFromNodeId, stepADependsOnStepB, stepAMayDependOnStepB, StepOptimizeOptions, stepsAreInSamePhase, StepStreamOptions, StreamableStep, stringifyPayload, stripAnsi, subscribe, trackedContext, trackedRootValue, trap, TRAP_ERROR, TRAP_ERROR_OR_INHIBITED, TRAP_INHIBITED, TypedEventEmitter, UnbatchedExecutableStep, UnbatchedExecutionExtra, UnwrapMultistep, };
29
31
  export { hookArgs } from "./args.js";
30
32
  export { version } from "./version.js";
31
33
  /** @deprecated Renamed to 'applyTransforms' */
@@ -159,7 +161,7 @@ declare global {
159
161
  interface Plugin {
160
162
  grafast?: {
161
163
  middleware?: {
162
- [key in keyof GrafastMiddleware]?: CallbackOrDescriptor<GrafastMiddleware[key] extends (...args: infer UArgs) => infer UResult ? (next: MiddlewareNext<Awaited<UResult>>, ...args: UArgs) => UResult : never>;
164
+ [key in keyof GrafastMiddleware]?: CallbackOrDescriptor<GrafastMiddleware[key] extends (...args: infer UArgs) => infer UResult ? (next: MiddlewareNext<UResult>, ...args: UArgs) => UResult : never>;
163
165
  };
164
166
  };
165
167
  }
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getEnumValueConfig = exports.flagError = exports.FirstStep = exports.first = exports.filter = exports.exportAsMany = exports.exportAs = exports.execute = exports.ExecutableStep = exports.ErrorStep = exports.error = exports.EdgeStep = exports.each = exports.defer = exports.debugPlans = exports.context = exports.ConstantStep = exports.constant = exports.ConnectionStep = exports.connection = exports.ConditionStep = exports.condition = exports.BaseStep = exports.assertPageInfoCapableStep = exports.assertNotNull = exports.assertModifierStep = exports.assertListCapableStep = exports.assertExecutableStep = exports.assertEdgeCapableStep = exports.arraysMatch = exports.arrayOfLength = exports.ApplyTransformsStep = exports.applyTransforms = exports.AccessStep = exports.access = exports.$$verbatim = exports.$$inhibit = exports.$$idempotent = exports.$$extensions = exports.$$eventEmitter = exports.$$bypassGraphQL = exports.__ValueStep = exports.__TrackedValueStep = exports.__ListTransformStep = exports.__ItemStep = exports.__InputStaticLeafStep = exports.__InputObjectStep = exports.__InputListStep = exports.__FlagStep = exports.isAsyncIterable = void 0;
4
- exports.objectFieldSpec = exports.object = exports.noop = exports.NodeStep = exports.nodeIdFromNode = exports.node = exports.newObjectTypeBuilder = exports.newInputObjectTypeBuilder = exports.newGrafastFieldConfigBuilder = exports.ModifierStep = exports.makeGrafastSchema = exports.makeDecodeNodeId = exports.LoadStep = exports.loadOneCallback = exports.loadOne = exports.loadManyCallback = exports.loadMany = exports.LoadedRecordStep = exports.listTransform = exports.ListStep = exports.ListenStep = exports.listen = exports.list = exports.LastStep = exports.last = exports.LambdaStep = exports.lambda = exports.isUnaryStep = exports.isStreamableStep = exports.isSafeError = exports.isPromiseLike = exports.isObjectLikeStep = exports.isModifierStep = exports.isListLikeStep = exports.isListCapableStep = exports.isExecutableStep = exports.isDev = exports.inputObjectFieldSpec = exports.inhibitOnNull = exports.groupBy = exports.GraphQLResolverStep = exports.graphqlResolver = exports.graphqlItemHandler = exports.GraphQLItemHandler = exports.grafastSync = exports.grafastPrint = exports.grafastGraphqlSync = exports.grafastGraphql = exports.grafast = exports.getGrafastMiddleware = void 0;
5
- exports.DeepEvalStep = exports.deepEval = exports.version = exports.hookArgs = exports.UnbatchedExecutableStep = exports.TRAP_INHIBITED = exports.TRAP_ERROR_OR_INHIBITED = exports.TRAP_ERROR = exports.trap = exports.trackedRootValue = exports.trackedContext = exports.subscribe = exports.stripAnsi = exports.stringifyPayload = exports.stepsAreInSamePhase = exports.stepAMayDependOnStepB = exports.stepADependsOnStepB = exports.specFromNodeId = exports.SideEffectStep = exports.sideEffect = exports.SetterStep = exports.setter = exports.SafeError = exports.rootValue = exports.ReverseStep = exports.reverseArray = exports.reverse = exports.RemapKeysStep = exports.remapKeys = exports.ProxyStep = exports.proxy = exports.polymorphicWrap = exports.PolymorphicBranchStep = exports.polymorphicBranch = exports.partitionByIndex = exports.operationPlan = exports.OperationPlan = exports.ObjectStep = exports.objectSpec = void 0;
4
+ exports.object = exports.noop = exports.NodeStep = exports.nodeIdFromNode = exports.node = exports.newObjectTypeBuilder = exports.newInputObjectTypeBuilder = exports.newGrafastFieldConfigBuilder = exports.multistep = exports.ModifierStep = exports.makeGrafastSchema = exports.makeDecodeNodeId = exports.LoadStep = exports.loadOneCallback = exports.loadOne = exports.loadManyCallback = exports.loadMany = exports.LoadedRecordStep = exports.listTransform = exports.ListStep = exports.ListenStep = exports.listen = exports.list = exports.LastStep = exports.last = exports.LambdaStep = exports.lambda = exports.isUnaryStep = exports.isStreamableStep = exports.isSafeError = exports.isPromiseLike = exports.isObjectLikeStep = exports.isModifierStep = exports.isListLikeStep = exports.isListCapableStep = exports.isExecutableStep = exports.isDev = exports.inputObjectFieldSpec = exports.inhibitOnNull = exports.groupBy = exports.GraphQLResolverStep = exports.graphqlResolver = exports.graphqlItemHandler = exports.GraphQLItemHandler = exports.grafastSync = exports.grafastPrint = exports.grafastGraphqlSync = exports.grafastGraphql = exports.grafast = exports.getGrafastMiddleware = void 0;
5
+ exports.DeepEvalStep = exports.deepEval = exports.version = exports.hookArgs = exports.UnbatchedExecutableStep = exports.TRAP_INHIBITED = exports.TRAP_ERROR_OR_INHIBITED = exports.TRAP_ERROR = exports.trap = exports.trackedRootValue = exports.trackedContext = exports.subscribe = exports.stripAnsi = exports.stringifyPayload = exports.stepsAreInSamePhase = exports.stepAMayDependOnStepB = exports.stepADependsOnStepB = exports.specFromNodeId = exports.SideEffectStep = exports.sideEffect = exports.SetterStep = exports.setter = exports.SafeError = exports.rootValue = exports.ReverseStep = exports.reverseArray = exports.reverse = exports.RemapKeysStep = exports.remapKeys = exports.ProxyStep = exports.proxy = exports.polymorphicWrap = exports.PolymorphicBranchStep = exports.polymorphicBranch = exports.partitionByIndex = exports.operationPlan = exports.OperationPlan = exports.ObjectStep = exports.objectSpec = exports.objectFieldSpec = void 0;
6
6
  const tslib_1 = require("tslib");
7
7
  require("./thereCanBeOnlyOne.js");
8
8
  const debug_1 = tslib_1.__importDefault(require("debug"));
@@ -45,6 +45,8 @@ Object.defineProperty(exports, "$$idempotent", { enumerable: true, get: function
45
45
  Object.defineProperty(exports, "$$verbatim", { enumerable: true, get: function () { return interfaces_js_1.$$verbatim; } });
46
46
  const middleware_js_1 = require("./middleware.js");
47
47
  Object.defineProperty(exports, "getGrafastMiddleware", { enumerable: true, get: function () { return middleware_js_1.getGrafastMiddleware; } });
48
+ const multistep_js_1 = require("./multistep.js");
49
+ Object.defineProperty(exports, "multistep", { enumerable: true, get: function () { return multistep_js_1.multistep; } });
48
50
  const polymorphic_js_1 = require("./polymorphic.js");
49
51
  Object.defineProperty(exports, "polymorphicWrap", { enumerable: true, get: function () { return polymorphic_js_1.polymorphicWrap; } });
50
52
  const step_js_1 = require("./step.js");
@@ -288,6 +290,7 @@ Object.defineProperty(exports, "isAsyncIterable", { enumerable: true, get: funct
288
290
  flagError: error_js_1.flagError,
289
291
  SafeError: error_js_1.SafeError,
290
292
  isUnaryStep: withGlobalLayerPlan_js_1.isUnaryStep,
293
+ multistep: multistep_js_1.multistep,
291
294
  });
292
295
  var args_js_1 = require("./args.js");
293
296
  Object.defineProperty(exports, "hookArgs", { enumerable: true, get: function () { return args_js_1.hookArgs; } });
@@ -0,0 +1,19 @@
1
+ import { ExecutableStep } from "./step.js";
2
+ /**
3
+ * When using this, always use `const`! Otherwise tuples will show up as arrays
4
+ * and break things.
5
+ */
6
+ export type Multistep = null | undefined | ExecutableStep | readonly [...(readonly ExecutableStep[])] | Record<string, ExecutableStep>;
7
+ export type UnwrapMultistep<TMultistepSpec extends Multistep> = TMultistepSpec extends null ? null : TMultistepSpec extends undefined ? undefined : TMultistepSpec extends ExecutableStep<infer U> ? U : TMultistepSpec extends readonly [...(readonly any[])] ? {
8
+ [index in keyof TMultistepSpec]: TMultistepSpec[index] extends ExecutableStep<infer V> ? V : never;
9
+ } : {
10
+ [key in keyof TMultistepSpec]: TMultistepSpec[key] extends ExecutableStep<infer V> ? V : never;
11
+ };
12
+ interface MultistepCacheConfig {
13
+ identifier: string;
14
+ cacheSize: number;
15
+ }
16
+ export declare function multistep<const TMultistepSpec extends Multistep>(spec: TMultistepSpec, stable?: string | true | MultistepCacheConfig): ExecutableStep<UnwrapMultistep<TMultistepSpec>>;
17
+ export declare function isMultistep<const TMultistepSpec extends Multistep>(spec: any): spec is TMultistepSpec;
18
+ export {};
19
+ //# sourceMappingURL=multistep.d.ts.map
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isMultistep = exports.multistep = void 0;
4
+ const step_js_1 = require("./step.js");
5
+ const constant_js_1 = require("./steps/constant.js");
6
+ const list_js_1 = require("./steps/list.js");
7
+ const object_js_1 = require("./steps/object.js");
8
+ const utils_js_1 = require("./utils.js");
9
+ function multistep(spec, stable) {
10
+ if (spec == null) {
11
+ return (0, constant_js_1.constant)(spec);
12
+ }
13
+ else if (spec instanceof step_js_1.ExecutableStep) {
14
+ return spec;
15
+ }
16
+ else if ((0, utils_js_1.isTuple)(spec)) {
17
+ const config = stable === true
18
+ ? { identifier: `multistep` }
19
+ : typeof stable === "string"
20
+ ? { identifier: stable }
21
+ : stable;
22
+ const $step = (0, list_js_1.list)(spec, config);
23
+ return $step;
24
+ }
25
+ else {
26
+ const config = stable === true
27
+ ? { identifier: `multistep` }
28
+ : typeof stable === "string"
29
+ ? { identifier: stable }
30
+ : stable;
31
+ const $step = (0, object_js_1.object)(spec, config);
32
+ return $step;
33
+ }
34
+ }
35
+ exports.multistep = multistep;
36
+ function isMultistep(spec) {
37
+ if (spec == null) {
38
+ return true;
39
+ }
40
+ else if (spec instanceof step_js_1.ExecutableStep) {
41
+ return true;
42
+ }
43
+ else if ((0, utils_js_1.isTuple)(spec) && spec.every((s) => s instanceof step_js_1.ExecutableStep)) {
44
+ return true;
45
+ }
46
+ else if (typeof spec === "object" &&
47
+ Object.values(spec).every((s) => s instanceof step_js_1.ExecutableStep)) {
48
+ return true;
49
+ }
50
+ else {
51
+ return false;
52
+ }
53
+ }
54
+ exports.isMultistep = isMultistep;
55
+ //# sourceMappingURL=multistep.js.map
@@ -6,6 +6,7 @@ const graphql = tslib_1.__importStar(require("graphql"));
6
6
  const constant_js_1 = require("./steps/constant.js");
7
7
  const list_js_1 = require("./steps/list.js");
8
8
  const object_js_1 = require("./steps/object.js");
9
+ const utils_js_1 = require("./utils.js");
9
10
  const { getNullableType, isEnumType, isInputObjectType, isListType, isScalarType, } = graphql;
10
11
  function assertNotRuntime(operationPlan, description) {
11
12
  if (operationPlan.phase === "ready") {
@@ -118,21 +119,27 @@ function withFieldArgsForArguments(operationPlan, $parent, $all, field, applyAft
118
119
  if (rest.length === 0) {
119
120
  // Argument
120
121
  const arg = entity;
121
- result = arg.extensions.grafast?.inputPlan
122
- ? arg.extensions.grafast.inputPlan($parent, childFieldArgs, {
122
+ const argInputPlan = arg.extensions.grafast?.inputPlan;
123
+ const fnDescription = `???.${field.name}(${arg.name}:).inputPlan`;
124
+ (0, utils_js_1.assertNotAsync)(argInputPlan, fnDescription);
125
+ result = argInputPlan
126
+ ? (0, utils_js_1.assertNotPromise)(argInputPlan($parent, childFieldArgs, {
123
127
  schema,
124
128
  entity: arg,
125
- })
129
+ }), argInputPlan, fnDescription)
126
130
  : childFieldArgs.get();
127
131
  }
128
132
  else {
129
133
  // Input field
130
134
  const inputField = entity;
131
- result = inputField?.extensions.grafast?.inputPlan
132
- ? inputField.extensions.grafast.inputPlan(childFieldArgs, {
135
+ const inputFieldInputPlan = inputField?.extensions.grafast?.inputPlan;
136
+ const fnDescription = `???.${inputField?.name}.inputPlan`;
137
+ (0, utils_js_1.assertNotAsync)(inputFieldInputPlan, fnDescription);
138
+ result = inputFieldInputPlan
139
+ ? (0, utils_js_1.assertNotPromise)(inputFieldInputPlan(childFieldArgs, {
133
140
  schema,
134
141
  entity: inputField,
135
- })
142
+ }), inputFieldInputPlan, fnDescription)
136
143
  : childFieldArgs.get();
137
144
  }
138
145
  const nullableType = getNullableType(entityType);
@@ -205,21 +212,27 @@ function withFieldArgsForArguments(operationPlan, $parent, $all, field, applyAft
205
212
  if (rest.length === 0) {
206
213
  // Argument
207
214
  const arg = entity;
208
- result = arg.extensions.grafast?.applyPlan
209
- ? arg.extensions.grafast.applyPlan($parent, $target, childFieldArgs, {
215
+ const argApplyPlan = arg.extensions.grafast?.applyPlan;
216
+ const fnDescription = `???.${field.name}(${arg.name}:).applyPlan`;
217
+ (0, utils_js_1.assertNotAsync)(argApplyPlan, fnDescription);
218
+ result = argApplyPlan
219
+ ? (0, utils_js_1.assertNotPromise)(argApplyPlan($parent, $target, childFieldArgs, {
210
220
  schema,
211
221
  entity: arg,
212
- })
222
+ }), argApplyPlan, fnDescription)
213
223
  : undefined;
214
224
  }
215
225
  else if (entity) {
216
226
  // input field
217
227
  const inputField = entity;
218
- result = inputField.extensions.grafast?.applyPlan
219
- ? inputField.extensions.grafast.applyPlan($target, childFieldArgs, {
228
+ const inputFieldApplyPlan = inputField.extensions.grafast?.applyPlan;
229
+ const fnDescription = `???.${inputField.name}.applyPlan`;
230
+ (0, utils_js_1.assertNotAsync)(inputFieldApplyPlan, fnDescription);
231
+ result = inputFieldApplyPlan
232
+ ? (0, utils_js_1.assertNotPromise)(inputFieldApplyPlan($target, childFieldArgs, {
220
233
  schema,
221
234
  entity: inputField,
222
- })
235
+ }), inputFieldApplyPlan, fnDescription)
223
236
  : undefined;
224
237
  }
225
238
  else {
@@ -275,10 +288,12 @@ function withFieldArgsForArguments(operationPlan, $parent, $all, field, applyAft
275
288
  else if (isInputObjectType(nullableEntityType)) {
276
289
  const typeResolver = nullableEntityType.extensions.grafast?.inputPlan ||
277
290
  defaultInputObjectTypeInputPlanResolver;
278
- const resolvedResult = typeResolver(getFieldArgsForPath(path, nullableEntityType, $input, "input"), {
291
+ const fnDescription = `${nullableEntityType}.inputPlan`;
292
+ (0, utils_js_1.assertNotAsync)(typeResolver, fnDescription);
293
+ const resolvedResult = (0, utils_js_1.assertNotPromise)(typeResolver(getFieldArgsForPath(path, nullableEntityType, $input, "input"), {
279
294
  schema,
280
295
  type: nullableEntityType,
281
- });
296
+ }), typeResolver, fnDescription);
282
297
  if (mode === "apply") {
283
298
  // NOTE: if mode === 'input' then `.get()` won't need a
284
299
  // `processAfter` since that will already have been handled in
@@ -289,11 +304,13 @@ function withFieldArgsForArguments(operationPlan, $parent, $all, field, applyAft
289
304
  }
290
305
  else if (isScalarType(nullableEntityType)) {
291
306
  const scalarResolver = nullableEntityType.extensions.grafast?.inputPlan;
307
+ const fnDescription = `${nullableEntityType}.inputPlan`;
308
+ (0, utils_js_1.assertNotAsync)(scalarResolver, fnDescription);
292
309
  if (scalarResolver !== undefined) {
293
- return scalarResolver($input, {
310
+ return (0, utils_js_1.assertNotPromise)(scalarResolver($input, {
294
311
  schema,
295
312
  type: nullableEntityType,
296
- });
313
+ }), scalarResolver, fnDescription);
297
314
  }
298
315
  else {
299
316
  return $input;
@@ -360,12 +377,16 @@ function withFieldArgsForArguments(operationPlan, $parent, $all, field, applyAft
360
377
  const enumValue = nullableEntityType
361
378
  .getValues()
362
379
  .find((v) => v.value === value);
363
- const enumResolver = enumValue?.extensions.grafast?.applyPlan;
364
- if (enumResolver !== undefined) {
365
- const $target = typeof targetStepOrCallback === "function"
366
- ? targetStepOrCallback()
367
- : targetStepOrCallback;
368
- enumResolver($target);
380
+ if (enumValue) {
381
+ const enumResolver = enumValue.extensions.grafast?.applyPlan;
382
+ const fnDescription = `${nullableEntityType.name}.${enumValue.name}.applyPlan`;
383
+ (0, utils_js_1.assertNotAsync)(enumResolver, fnDescription);
384
+ if (enumResolver !== undefined) {
385
+ const $target = typeof targetStepOrCallback === "function"
386
+ ? targetStepOrCallback()
387
+ : targetStepOrCallback;
388
+ (0, utils_js_1.assertNotPromise)(enumResolver($target), enumResolver, fnDescription);
389
+ }
369
390
  }
370
391
  }
371
392
  else {
@@ -408,6 +429,7 @@ function withFieldArgsForArguments(operationPlan, $parent, $all, field, applyAft
408
429
  return localFieldArgs;
409
430
  }
410
431
  const result = callback(fieldArgs);
432
+ (0, utils_js_1.assertNotPromise)(result, callback, operationPlan.loc?.join(">") ?? "???");
411
433
  if (!explicitlyApplied) {
412
434
  processAfter(fieldArgs, [], result, args, applyAfterMode);
413
435
  }
package/dist/step.js CHANGED
@@ -225,6 +225,9 @@ class ExecutableStep extends BaseStep {
225
225
  const options = stepOrOptions instanceof ExecutableStep
226
226
  ? { step: stepOrOptions, skipDeduplication: false }
227
227
  : stepOrOptions;
228
+ if (options.step.layerPlan.id > this.layerPlan.id) {
229
+ throw new Error(`Cannot add dependency ${options.step} to ${this} since the former is in a deeper layerPlan (creates a catch-22)`);
230
+ }
228
231
  return this.operationPlan.stepTracker.addStepDependency(this, options);
229
232
  }
230
233
  /**
@@ -237,6 +240,9 @@ class ExecutableStep extends BaseStep {
237
240
  const options = stepOrOptions instanceof ExecutableStep
238
241
  ? { step: stepOrOptions }
239
242
  : stepOrOptions;
243
+ if (options.step.layerPlan.id > this.layerPlan.id) {
244
+ throw new Error(`Cannot add dependency ${options.step} to ${this} since the former is in a deeper layerPlan (creates a catch-22)`);
245
+ }
240
246
  return this.operationPlan.stepTracker.addStepUnaryDependency(this, options);
241
247
  }
242
248
  finalize() {
@@ -1,4 +1,5 @@
1
- import type { PromiseOrDirect, UnbatchedExecutionExtra, UnwrapPlanTuple } from "../interfaces.js";
1
+ import type { PromiseOrDirect, UnbatchedExecutionExtra } from "../interfaces.js";
2
+ import type { Multistep, UnwrapMultistep } from "../multistep.js";
2
3
  import type { ExecutableStep } from "../step.js";
3
4
  import { UnbatchedExecutableStep } from "../step.js";
4
5
  /**
@@ -23,7 +24,6 @@ export declare class LambdaStep<TIn, TOut> extends UnbatchedExecutableStep<TOut>
23
24
  * callback. Note: if you need to pass more than one value, pass a `ListStep`
24
25
  * as the `$plan` argument.
25
26
  */
26
- declare function lambda<const TIn extends readonly ExecutableStep[], TOut>(plans: TIn, fn: (value: UnwrapPlanTuple<TIn>) => PromiseOrDirect<TOut>, isSyncAndSafe?: boolean): LambdaStep<UnwrapPlanTuple<TIn>, TOut>;
27
- declare function lambda<const TIn, TOut>($plan: ExecutableStep<TIn> | null | undefined, fn: (value: TIn) => PromiseOrDirect<TOut>, isSyncAndSafe?: boolean): LambdaStep<TIn, TOut>;
27
+ declare function lambda<const TInMultistep extends Multistep, TOut>(spec: TInMultistep, fn: (value: UnwrapMultistep<TInMultistep>) => PromiseOrDirect<TOut>, isSyncAndSafe?: boolean): LambdaStep<UnwrapMultistep<TInMultistep>, TOut>;
28
28
  export { lambda };
29
29
  //# sourceMappingURL=lambda.d.ts.map
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.lambda = exports.LambdaStep = void 0;
4
+ const multistep_js_1 = require("../multistep.js");
4
5
  const step_js_1 = require("../step.js");
5
- const list_js_1 = require("./list.js");
6
6
  const sideEffect_js_1 = require("./sideEffect.js");
7
7
  /**
8
8
  * Calls the given lambda function for each tuple
@@ -40,16 +40,20 @@ class LambdaStep extends step_js_1.UnbatchedExecutableStep {
40
40
  }
41
41
  }
42
42
  exports.LambdaStep = LambdaStep;
43
- function lambda(planOrPlans, fn, isSyncAndSafe = false) {
43
+ /**
44
+ * A plan that takes the input `$plan` and feeds each value through the `fn`
45
+ * callback. Note: if you need to pass more than one value, pass a `ListStep`
46
+ * as the `$plan` argument.
47
+ */
48
+ function lambda(spec, fn, isSyncAndSafe = false) {
44
49
  if (fn.length > 1) {
45
50
  throw new Error("lambda callback should accept one argument, perhaps you forgot to destructure the arguments?");
46
51
  }
47
- const $lambda = Array.isArray(planOrPlans)
48
- ? new LambdaStep((0, list_js_1.list)(planOrPlans), fn)
49
- : new LambdaStep(planOrPlans, fn);
52
+ const $in = (0, multistep_js_1.multistep)(spec);
53
+ const $lambda = new LambdaStep($in, fn);
50
54
  if (fn.hasSideEffects) {
51
55
  console.trace(`You passed a function with \`hasSideEffects = true\` to \`lambda()\`, you should use \`sideEffect()\` instead (it has the same signature). We've automatically corrected this, but you should fix it in your code so the types are correct.`);
52
- return (0, sideEffect_js_1.sideEffect)(planOrPlans, fn);
56
+ return (0, sideEffect_js_1.sideEffect)(spec, fn);
53
57
  }
54
58
  if (isSyncAndSafe) {
55
59
  if (fn.constructor.name === "AsyncFunction") {
@@ -2,6 +2,10 @@ import type { ExecutionDetails, StepOptimizeOptions, UnbatchedExecutionExtra, Un
2
2
  import type { ExecutableStep } from "../step.js";
3
3
  import { UnbatchedExecutableStep } from "../step.js";
4
4
  import { ConstantStep } from "./constant.js";
5
+ interface ListStepCacheConfig {
6
+ identifier?: string;
7
+ cacheSize?: number;
8
+ }
5
9
  export declare class ListStep<const TPlanTuple extends readonly ExecutableStep[]> extends UnbatchedExecutableStep<UnwrapPlanTuple<TPlanTuple>> {
6
10
  static $$export: {
7
11
  moduleName: string;
@@ -10,12 +14,16 @@ export declare class ListStep<const TPlanTuple extends readonly ExecutableStep[]
10
14
  isSyncAndSafe: boolean;
11
15
  allowMultipleOptimizations: boolean;
12
16
  optimizeMetaKey: string;
13
- constructor(list: TPlanTuple);
17
+ private cacheSize;
18
+ private valueCount;
19
+ constructor(list: TPlanTuple, cacheConfig?: ListStepCacheConfig);
14
20
  toStringMeta(): string;
15
21
  execute({ indexMap, values }: ExecutionDetails): readonly UnwrapPlanTuple<TPlanTuple>[];
16
22
  unbatchedExecute(_extra: UnbatchedExecutionExtra, ...values: any[]): UnwrapPlanTuple<TPlanTuple>;
23
+ deduplicatedUnbatchedExecute({ meta: inMeta }: UnbatchedExecutionExtra, ...values: any[]): UnwrapPlanTuple<TPlanTuple>;
17
24
  deduplicate(peers: ListStep<TPlanTuple>[]): ListStep<TPlanTuple>[];
18
25
  optimize(opts: StepOptimizeOptions): this | ConstantStep<any[]>;
26
+ finalize(): void;
19
27
  /**
20
28
  * Get the original plan at the given index back again.
21
29
  */
@@ -27,5 +35,6 @@ export declare class ListStep<const TPlanTuple extends readonly ExecutableStep[]
27
35
  * Takes a list of plans and turns it into a single plan that represents the
28
36
  * list of their values.
29
37
  */
30
- export declare function list<const TPlanTuple extends readonly ExecutableStep[]>(list: TPlanTuple): ListStep<TPlanTuple>;
38
+ export declare function list<const TPlanTuple extends readonly ExecutableStep[]>(list: TPlanTuple, cacheConfig?: ListStepCacheConfig): ListStep<TPlanTuple>;
39
+ export {};
31
40
  //# sourceMappingURL=list.d.ts.map
@@ -3,16 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.list = exports.ListStep = void 0;
4
4
  const step_js_1 = require("../step.js");
5
5
  const constant_js_1 = require("./constant.js");
6
+ const DEFAULT_CACHE_SIZE = 100;
6
7
  class ListStep extends step_js_1.UnbatchedExecutableStep {
7
8
  static { this.$$export = {
8
9
  moduleName: "grafast",
9
10
  exportName: "ListStep",
10
11
  }; }
11
- constructor(list) {
12
+ constructor(list, cacheConfig) {
12
13
  super();
13
14
  this.isSyncAndSafe = true;
14
15
  this.allowMultipleOptimizations = true;
15
16
  this.optimizeMetaKey = "ListStep";
17
+ this.valueCount = list.length;
18
+ this.cacheSize =
19
+ cacheConfig?.cacheSize ??
20
+ (cacheConfig?.identifier ? DEFAULT_CACHE_SIZE : 0);
21
+ this.metaKey =
22
+ this.cacheSize <= 0
23
+ ? undefined
24
+ : cacheConfig?.identifier
25
+ ? `list|${list.length}|${cacheConfig.identifier}`
26
+ : this.id;
16
27
  for (let i = 0, l = list.length; i < l; i++) {
17
28
  this.addDependency({ step: list[i], skipDeduplication: true });
18
29
  }
@@ -27,6 +38,30 @@ class ListStep extends step_js_1.UnbatchedExecutableStep {
27
38
  ) {
28
39
  return values;
29
40
  }
41
+ deduplicatedUnbatchedExecute({ meta: inMeta }, ...values //UnwrapPlanTuple<TPlanTuple>,
42
+ ) {
43
+ const meta = inMeta;
44
+ if (meta.nextIndex !== undefined) {
45
+ outer: for (let i = 0, l = meta.results.length; i < l; i++) {
46
+ const cachedValues = meta.results[i];
47
+ for (let j = 0, c = this.valueCount; j < c; j++) {
48
+ if (values[j] !== cachedValues[j]) {
49
+ continue outer;
50
+ }
51
+ }
52
+ return cachedValues;
53
+ }
54
+ }
55
+ else {
56
+ meta.nextIndex = 0;
57
+ meta.results = [];
58
+ }
59
+ meta.results[meta.nextIndex] = values;
60
+ // Only cache this.cacheSize results, use a round-robin
61
+ const maxIndex = this.cacheSize - 1;
62
+ meta.nextIndex = meta.nextIndex === maxIndex ? 0 : meta.nextIndex + 1;
63
+ return values;
64
+ }
30
65
  deduplicate(peers) {
31
66
  return peers;
32
67
  }
@@ -52,6 +87,12 @@ class ListStep extends step_js_1.UnbatchedExecutableStep {
52
87
  }
53
88
  return this;
54
89
  }
90
+ finalize() {
91
+ if (this.cacheSize > 0) {
92
+ this.unbatchedExecute = this.deduplicatedUnbatchedExecute;
93
+ }
94
+ super.finalize();
95
+ }
55
96
  /**
56
97
  * Get the original plan at the given index back again.
57
98
  */
@@ -70,8 +111,8 @@ exports.ListStep = ListStep;
70
111
  * Takes a list of plans and turns it into a single plan that represents the
71
112
  * list of their values.
72
113
  */
73
- function list(list) {
74
- return new ListStep(list);
114
+ function list(list, cacheConfig) {
115
+ return new ListStep(list, cacheConfig);
75
116
  }
76
117
  exports.list = list;
77
118
  //# sourceMappingURL=list.js.map
@@ -1,5 +1,6 @@
1
1
  import type { __ItemStep, ExecutionDetails } from "../index.js";
2
2
  import type { GrafastResultsList, Maybe, PromiseOrDirect } from "../interfaces.js";
3
+ import type { Multistep, UnwrapMultistep } from "../multistep.js";
3
4
  import { ExecutableStep } from "../step.js";
4
5
  export interface LoadOptions<TItem, TParams extends Record<string, any>, TUnarySpec = never> {
5
6
  unary: TUnarySpec;
@@ -25,7 +26,7 @@ export declare function loadManyCallback<TSpec, TItem, TParams extends Record<st
25
26
  /**
26
27
  * You shouldn't create instances of this yourself - use `loadOne` or `loadMany` instead.
27
28
  */
28
- export declare class LoadedRecordStep<TItem, TParams extends Record<string, any>> extends ExecutableStep<TItem> {
29
+ export declare class LoadedRecordStep<TItem, TParams extends Record<string, any> = Record<string, any>> extends ExecutableStep<TItem> {
29
30
  private isSingle;
30
31
  private sourceDescription;
31
32
  private ioEquivalence;
@@ -43,7 +44,7 @@ export declare class LoadedRecordStep<TItem, TParams extends Record<string, any>
43
44
  optimize(): ExecutableStep<any>;
44
45
  execute({ count, values: [values0], }: ExecutionDetails<[TItem]>): GrafastResultsList<TItem>;
45
46
  }
46
- export declare class LoadStep<TSpec, TItem, TData extends TItem | ReadonlyArray<TItem>, TParams extends Record<string, any>, TUnarySpec = never> extends ExecutableStep {
47
+ export declare class LoadStep<const TMultistep extends Multistep, TItem, TData extends TItem | ReadonlyArray<TItem>, TParams extends Record<string, any>, const TUnaryMultistep extends Multistep = never> extends ExecutableStep {
47
48
  private ioEquivalence;
48
49
  private load;
49
50
  static $$export: {
@@ -51,14 +52,12 @@ export declare class LoadStep<TSpec, TItem, TData extends TItem | ReadonlyArray<
51
52
  exportName: string;
52
53
  };
53
54
  isSyncAndSafe: boolean;
54
- loadOptions: Omit<LoadOptions<TItem, TParams, TUnarySpec>, "unary"> | null;
55
+ loadOptions: Omit<LoadOptions<TItem, TParams, UnwrapMultistep<TUnaryMultistep>>, "unary"> | null;
55
56
  loadOptionsKey: string;
56
57
  attributes: Set<keyof TItem>;
57
58
  params: Partial<TParams>;
58
59
  unaryDepId: number | null;
59
- constructor($spec: ExecutableStep<TSpec>, $unarySpec: ExecutableStep<TUnarySpec> | null, ioEquivalence: null | string | {
60
- [key in keyof TSpec]?: string | null;
61
- }, load: LoadCallback<TSpec, TItem, TData, TParams, TUnarySpec>);
60
+ constructor(spec: TMultistep, unarySpec: TUnaryMultistep | null, ioEquivalence: IOEquivalence<TMultistep>, load: LoadCallback<UnwrapMultistep<TMultistep>, TItem, TData, TParams, UnwrapMultistep<TUnaryMultistep>>);
62
61
  toStringMeta(): string;
63
62
  private makeAccessMap;
64
63
  listItem($item: __ItemStep<TItem>): LoadedRecordStep<TItem, TParams>;
@@ -66,27 +65,23 @@ export declare class LoadStep<TSpec, TItem, TData extends TItem | ReadonlyArray<
66
65
  setParam<TParamKey extends keyof TParams>(paramKey: TParamKey, value: TParams[TParamKey]): void;
67
66
  addAttributes(attributes: Set<keyof TItem>): void;
68
67
  finalize(): void;
69
- execute({ count, values: [values0, values1], extra, }: ExecutionDetails<[TSpec, TUnarySpec]>): PromiseOrDirect<GrafastResultsList<Maybe<TData>>>;
68
+ execute({ count, values: [values0, values1], extra, }: ExecutionDetails<[
69
+ UnwrapMultistep<TMultistep>,
70
+ UnwrapMultistep<TUnaryMultistep>
71
+ ]>): PromiseOrDirect<GrafastResultsList<Maybe<TData>>>;
70
72
  }
71
- export declare function loadMany<TSpec, TItem, TParams extends Record<string, any> = Record<string, any>, TUnarySpec = never>($spec: ExecutableStep<TSpec>, loadCallback: LoadManyCallback<TSpec, TItem, TParams, TUnarySpec>): LoadStep<TSpec, TItem, ReadonlyArray<TItem>, TParams, TUnarySpec>;
72
- export declare function loadMany<TSpec, TItem, TParams extends Record<string, any> = Record<string, any>, TUnarySpec = never>($spec: ExecutableStep<TSpec>, ioEquivalence: null | string | (TSpec extends [...any[]] ? {
73
- [key in keyof TSpec]: string | null;
74
- } : TSpec extends Record<string, any> ? {
75
- [key in keyof TSpec]?: string | null;
76
- } : never), loadCallback: LoadManyCallback<TSpec, TItem, TParams, TUnarySpec>): LoadStep<TSpec, TItem, ReadonlyArray<TItem>, TParams, TUnarySpec>;
77
- export declare function loadMany<TSpec, TItem, TParams extends Record<string, any> = Record<string, any>, TUnarySpec = never>($spec: ExecutableStep<TSpec>, $unarySpec: ExecutableStep<TUnarySpec> | null, loadCallback: LoadManyCallback<TSpec, TItem, TParams, TUnarySpec>): LoadStep<TSpec, TItem, ReadonlyArray<TItem>, TParams, TUnarySpec>;
78
- export declare function loadMany<TSpec, TItem, TParams extends Record<string, any> = Record<string, any>, TUnarySpec = never>($spec: ExecutableStep<TSpec>, $unarySpec: ExecutableStep<TUnarySpec> | null, ioEquivalence: null | string | (TSpec extends [...any[]] ? {
79
- [key in keyof TSpec]: string | null;
80
- } : TSpec extends Record<string, any> ? {
81
- [key in keyof TSpec]?: string | null;
82
- } : never), loadCallback: LoadManyCallback<TSpec, TItem, TParams, TUnarySpec>): LoadStep<TSpec, TItem, ReadonlyArray<TItem>, TParams, TUnarySpec>;
83
- export declare function loadOne<const TSpec, TItem, TParams extends Record<string, any> = Record<string, any>, TUnarySpec = never>($spec: ExecutableStep<TSpec>, loadCallback: LoadOneCallback<TSpec, TItem, TParams, TUnarySpec>): LoadedRecordStep<TItem, TParams>;
84
- export declare function loadOne<const TSpec, TItem, TParams extends Record<string, any> = Record<string, any>, TUnarySpec = never>($spec: ExecutableStep<TSpec>, ioEquivalence: null | string | {
85
- [key in keyof TSpec]?: string | null;
86
- }, loadCallback: LoadOneCallback<TSpec, TItem, TParams, TUnarySpec>): LoadedRecordStep<TItem, TParams>;
87
- export declare function loadOne<const TSpec, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnarySpec = never>($spec: ExecutableStep<TSpec>, $unarySpec: ExecutableStep<TUnarySpec> | null, loadCallback: LoadOneCallback<TSpec, TItem, TParams, TUnarySpec>): LoadedRecordStep<TItem, TParams>;
88
- export declare function loadOne<const TSpec, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnarySpec = never>($spec: ExecutableStep<TSpec>, $unarySpec: ExecutableStep<TUnarySpec> | null, ioEquivalence: null | string | {
89
- [key in keyof TSpec]?: string | null;
90
- }, loadCallback: LoadOneCallback<TSpec, TItem, TParams, TUnarySpec>): LoadedRecordStep<TItem, TParams>;
73
+ export declare function loadMany<const TMultistep extends Multistep, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnaryMultistep extends Multistep = never>(spec: TMultistep, loadCallback: LoadManyCallback<UnwrapMultistep<TMultistep>, TItem, TParams, UnwrapMultistep<TUnaryMultistep>>): LoadStep<UnwrapMultistep<TMultistep>, TItem, ReadonlyArray<TItem>, TParams, UnwrapMultistep<TUnaryMultistep>>;
74
+ export declare function loadMany<const TMultistep extends Multistep, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnaryMultistep extends Multistep = never>(spec: TMultistep, ioEquivalence: IOEquivalence<TMultistep>, loadCallback: LoadManyCallback<UnwrapMultistep<TMultistep>, TItem, TParams, UnwrapMultistep<TUnaryMultistep>>): LoadStep<UnwrapMultistep<TMultistep>, TItem, ReadonlyArray<TItem>, TParams, UnwrapMultistep<TUnaryMultistep>>;
75
+ export declare function loadMany<const TMultistep extends Multistep, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnaryMultistep extends Multistep = never>(spec: TMultistep, unarySpec: TUnaryMultistep | null, loadCallback: LoadManyCallback<UnwrapMultistep<TMultistep>, TItem, TParams, UnwrapMultistep<TUnaryMultistep>>): LoadStep<UnwrapMultistep<TMultistep>, TItem, ReadonlyArray<TItem>, TParams, UnwrapMultistep<TUnaryMultistep>>;
76
+ export declare function loadMany<const TMultistep extends Multistep, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnaryMultistep extends Multistep = never>(spec: TMultistep, unarySpec: TUnaryMultistep | null, ioEquivalence: IOEquivalence<TMultistep>, loadCallback: LoadManyCallback<UnwrapMultistep<TMultistep>, TItem, TParams, UnwrapMultistep<TUnaryMultistep>>): LoadStep<UnwrapMultistep<TMultistep>, TItem, ReadonlyArray<TItem>, TParams, UnwrapMultistep<TUnaryMultistep>>;
77
+ type IOEquivalence<TMultistep extends Multistep> = null | string | (UnwrapMultistep<TMultistep> extends readonly [...(readonly any[])] ? {
78
+ [key in Exclude<keyof UnwrapMultistep<TMultistep>, keyof any[]>]: string | null;
79
+ } : UnwrapMultistep<TMultistep> extends Record<string, any> ? {
80
+ [key in keyof UnwrapMultistep<TMultistep>]?: string | null;
81
+ } : never);
82
+ export declare function loadOne<const TMultistep extends Multistep, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnaryMultistep extends Multistep = never>(spec: TMultistep, loadCallback: LoadOneCallback<UnwrapMultistep<TMultistep>, TItem, TParams, UnwrapMultistep<TUnaryMultistep>>): LoadedRecordStep<TItem, TParams>;
83
+ export declare function loadOne<const TMultistep extends Multistep, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnaryMultistep extends Multistep = never>(spec: TMultistep, ioEquivalence: IOEquivalence<TMultistep>, loadCallback: LoadOneCallback<UnwrapMultistep<TMultistep>, TItem, TParams, UnwrapMultistep<TUnaryMultistep>>): LoadedRecordStep<TItem, TParams>;
84
+ export declare function loadOne<const TMultistep extends Multistep, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnaryMultistep extends Multistep = never>(spec: TMultistep, unarySpec: TUnaryMultistep | null, loadCallback: LoadOneCallback<UnwrapMultistep<TMultistep>, TItem, TParams, UnwrapMultistep<TUnaryMultistep>>): LoadedRecordStep<TItem, TParams>;
85
+ export declare function loadOne<const TMultistep extends Multistep, TItem, TParams extends Record<string, any> = Record<string, any>, const TUnaryMultistep extends Multistep = never>(spec: TMultistep, unarySpec: TUnaryMultistep | null, ioEquivalence: IOEquivalence<TMultistep>, loadCallback: LoadOneCallback<UnwrapMultistep<TMultistep>, TItem, TParams, UnwrapMultistep<TUnaryMultistep>>): LoadedRecordStep<TItem, TParams>;
91
86
  export {};
92
87
  //# sourceMappingURL=load.d.ts.map
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loadOne = exports.loadMany = exports.LoadStep = exports.LoadedRecordStep = exports.loadManyCallback = exports.loadOneCallback = void 0;
4
4
  const index_js_1 = require("../index.js");
5
+ const multistep_js_1 = require("../multistep.js");
5
6
  const step_js_1 = require("../step.js");
6
7
  const utils_js_1 = require("../utils.js");
7
8
  const access_js_1 = require("./access.js");
@@ -89,7 +90,7 @@ exports.LoadedRecordStep = LoadedRecordStep;
89
90
  class LoadStep extends step_js_1.ExecutableStep {
90
91
  /* implements ListCapableStep<TItem, LoadedRecordStep<TItem, TParams>> */
91
92
  static { this.$$export = { moduleName: "grafast", exportName: "LoadStep" }; }
92
- constructor($spec, $unarySpec, ioEquivalence, load) {
93
+ constructor(spec, unarySpec, ioEquivalence, load) {
93
94
  super();
94
95
  this.ioEquivalence = ioEquivalence;
95
96
  this.load = load;
@@ -99,7 +100,9 @@ class LoadStep extends step_js_1.ExecutableStep {
99
100
  this.attributes = new Set();
100
101
  this.params = Object.create(null);
101
102
  this.unaryDepId = null;
103
+ const $spec = (0, multistep_js_1.multistep)(spec, "load");
102
104
  this.addDependency($spec);
105
+ const $unarySpec = unarySpec == null ? null : (0, multistep_js_1.multistep)(unarySpec, "loadUnary");
103
106
  if ($unarySpec) {
104
107
  this.unaryDepId = this.addUnaryDependency($unarySpec);
105
108
  }
@@ -117,7 +120,7 @@ class LoadStep extends step_js_1.ExecutableStep {
117
120
  map[this.ioEquivalence] = $spec;
118
121
  return map;
119
122
  }
120
- else if (Array.isArray(this.ioEquivalence)) {
123
+ else if ((0, utils_js_1.isTuple)(this.ioEquivalence)) {
121
124
  for (let i = 0, l = this.ioEquivalence.length; i < l; i++) {
122
125
  const key = this.ioEquivalence[i];
123
126
  map[key] = (0, step_js_1.isListLikeStep)($spec) ? $spec.at(i) : (0, access_js_1.access)($spec, [i]);
@@ -296,41 +299,41 @@ async function executeBatches(loadBatches, load, loadOptions) {
296
299
  }
297
300
  }
298
301
  }
299
- function load($spec, $unarySpec, ioEquivalence, loadCallback) {
300
- return new LoadStep($spec, $unarySpec, ioEquivalence, loadCallback);
302
+ function load(spec, unarySpec, ioEquivalence, loadCallback) {
303
+ return new LoadStep(spec, unarySpec, ioEquivalence, loadCallback);
301
304
  }
302
- function loadMany($spec, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence, loadCallbackOnly) {
305
+ function loadMany(spec, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence, loadCallbackOnly) {
303
306
  if (loadCallbackOnly) {
304
- return load($spec, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence, loadCallbackOnly);
307
+ return load(spec, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence, loadCallbackOnly);
305
308
  }
306
309
  // At most 3 arguments
307
- else if ((0, index_js_1.isExecutableStep)(loadCallbackOrIoEquivalenceOrUnarySpec)) {
308
- return load($spec, loadCallbackOrIoEquivalenceOrUnarySpec, null, loadCallbackOrIoEquivalence);
310
+ else if ((0, multistep_js_1.isMultistep)(loadCallbackOrIoEquivalenceOrUnarySpec)) {
311
+ return load(spec, loadCallbackOrIoEquivalenceOrUnarySpec, null, loadCallbackOrIoEquivalence);
309
312
  }
310
313
  // Unary step is definitely null; 3 arguments
311
314
  else if (loadCallbackOrIoEquivalence) {
312
- return load($spec, null, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence);
315
+ return load(spec, null, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence);
313
316
  }
314
317
  // 2 arguments
315
318
  else {
316
- return load($spec, null, null, loadCallbackOrIoEquivalenceOrUnarySpec);
319
+ return load(spec, null, null, loadCallbackOrIoEquivalenceOrUnarySpec);
317
320
  }
318
321
  }
319
322
  exports.loadMany = loadMany;
320
- function loadOne($spec, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence, loadCallbackOnly) {
323
+ function loadOne(spec, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence, loadCallbackOnly) {
321
324
  if (loadCallbackOnly) {
322
- return load($spec, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence, loadCallbackOnly).single();
325
+ return load(spec, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence, loadCallbackOnly).single();
323
326
  }
324
327
  // At most 3 arguments
325
- else if ((0, index_js_1.isExecutableStep)(loadCallbackOrIoEquivalenceOrUnarySpec)) {
326
- return load($spec, loadCallbackOrIoEquivalenceOrUnarySpec, null, loadCallbackOrIoEquivalence).single();
328
+ else if ((0, multistep_js_1.isMultistep)(loadCallbackOrIoEquivalenceOrUnarySpec)) {
329
+ return load(spec, loadCallbackOrIoEquivalenceOrUnarySpec, null, loadCallbackOrIoEquivalence).single();
327
330
  }
328
331
  // Unary step is definitely null; 3 arguments
329
332
  else if (loadCallbackOrIoEquivalence) {
330
- return load($spec, null, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence).single();
333
+ return load(spec, null, loadCallbackOrIoEquivalenceOrUnarySpec, loadCallbackOrIoEquivalence).single();
331
334
  }
332
335
  else {
333
- return load($spec, null, null, loadCallbackOrIoEquivalenceOrUnarySpec).single();
336
+ return load(spec, null, null, loadCallbackOrIoEquivalenceOrUnarySpec).single();
334
337
  }
335
338
  }
336
339
  exports.loadOne = loadOne;
@@ -19,6 +19,10 @@ export interface ObjectPlanMeta<TSteps extends {
19
19
  }> {
20
20
  results: Results<TSteps>;
21
21
  }
22
+ interface ObjectStepCacheConfig {
23
+ identifier?: string;
24
+ cacheSize?: number;
25
+ }
22
26
  /**
23
27
  * A plan that represents an object using the keys given and the values being
24
28
  * the results of the associated plans.
@@ -36,7 +40,8 @@ export declare class ObjectStep<TPlans extends {
36
40
  allowMultipleOptimizations: boolean;
37
41
  private keys;
38
42
  optimizeMetaKey: string;
39
- constructor(obj: TPlans);
43
+ private cacheSize;
44
+ constructor(obj: TPlans, cacheConfig?: ObjectStepCacheConfig);
40
45
  /**
41
46
  * This key doesn't get typed, but it can be added later which can be quite
42
47
  * handy.
@@ -61,6 +66,6 @@ export declare class ObjectStep<TPlans extends {
61
66
  */
62
67
  export declare function object<TPlans extends {
63
68
  [key: string]: ExecutableStep;
64
- }>(obj: TPlans): ObjectStep<TPlans>;
69
+ }>(obj: TPlans, cacheConfig?: ObjectStepCacheConfig): ObjectStep<TPlans>;
65
70
  export {};
66
71
  //# sourceMappingURL=object.d.ts.map
@@ -6,6 +6,7 @@ const tslib_1 = require("tslib");
6
6
  const tamedevil_1 = tslib_1.__importStar(require("tamedevil"));
7
7
  const step_js_1 = require("../step.js");
8
8
  const constant_js_1 = require("./constant.js");
9
+ const DEFAULT_CACHE_SIZE = 100;
9
10
  const EMPTY_OBJECT = Object.freeze(Object.create(null));
10
11
  /**
11
12
  * A plan that represents an object using the keys given and the values being
@@ -16,13 +17,21 @@ class ObjectStep extends step_js_1.UnbatchedExecutableStep {
16
17
  moduleName: "grafast",
17
18
  exportName: "ObjectStep",
18
19
  }; }
19
- constructor(obj) {
20
+ constructor(obj, cacheConfig) {
20
21
  super();
21
22
  this.isSyncAndSafe = true;
22
23
  this.allowMultipleOptimizations = true;
23
24
  // Optimize needs the same 'meta' for all ObjectSteps
24
25
  this.optimizeMetaKey = "ObjectStep";
25
- this.metaKey = this.id;
26
+ this.cacheSize =
27
+ cacheConfig?.cacheSize ??
28
+ (cacheConfig?.identifier ? DEFAULT_CACHE_SIZE : 0);
29
+ this.metaKey =
30
+ this.cacheSize <= 0
31
+ ? undefined
32
+ : cacheConfig?.identifier
33
+ ? `object|${JSON.stringify(Object.keys(obj))}|${cacheConfig.identifier}`
34
+ : this.id;
26
35
  this.keys = Object.keys(obj);
27
36
  for (let i = 0, l = this.keys.length; i < l; i++) {
28
37
  this.addDependency({ step: obj[this.keys[i]], skipDeduplication: true });
@@ -102,9 +111,11 @@ ${tamedevil_1.default.join(this.keys.map((key, i) => (0, tamedevil_1.default) `
102
111
  const newObj = Object.create(null);
103
112
  ${tamedevil_1.default.join(this.keys.map((key, i) => (0, tamedevil_1.default) ` newObj${tamedevil_1.default.set(key, true)} = ${tamedevil_1.default.identifier(`val${i}`)};\n`), "")}\
104
113
  `;
105
- return tamedevil_1.default.runInBatch((0, tamedevil_1.default) `\
106
- (function ({ meta }, ${tamedevil_1.default.join(this.keys.map((_k, i) => tamedevil_1.default.identifier(`val${i}`)), ", ")}) {
107
- if (meta.nextIndex) {
114
+ const vals = tamedevil_1.default.join(this.keys.map((_k, i) => tamedevil_1.default.identifier(`val${i}`)), ", ");
115
+ if (this.cacheSize > 0) {
116
+ return tamedevil_1.default.runInBatch((0, tamedevil_1.default) `\
117
+ (function ({ meta }, ${vals}) {
118
+ if (meta.nextIndex != null) {
108
119
  for (let i = 0, l = meta.results.length; i < l; i++) {
109
120
  const [values, obj] = meta.results[i];
110
121
  if (${tamedevil_1.default.join(this.keys.map((_key, i) => (0, tamedevil_1.default) `values[${tamedevil_1.default.lit(i)}] === ${tamedevil_1.default.identifier(`val${i}`)}`), " && ")}) {
@@ -113,16 +124,22 @@ ${tamedevil_1.default.join(this.keys.map((key, i) => (0, tamedevil_1.default) `
113
124
  }
114
125
  } else {
115
126
  meta.nextIndex = 0;
116
- if (!meta.results) {
117
- meta.results = [];
118
- }
127
+ meta.results = [];
119
128
  }
120
129
  ${inner}
121
130
  meta.results[meta.nextIndex] = [[${tamedevil_1.default.join(this.keys.map((_key, i) => tamedevil_1.default.identifier(`val${i}`)), ",")}], newObj];
122
- // Only cache 10 results, use a round-robin
123
- meta.nextIndex = meta.nextIndex === 9 ? 0 : meta.nextIndex + 1;
131
+ // Only cache ${tamedevil_1.default.lit(this.cacheSize)} results, use a round-robin
132
+ meta.nextIndex = meta.nextIndex === ${tamedevil_1.default.lit(this.cacheSize - 1)} ? 0 : meta.nextIndex + 1;
133
+ return newObj;
134
+ })`, callback);
135
+ }
136
+ else {
137
+ return tamedevil_1.default.runInBatch((0, tamedevil_1.default) `\
138
+ (function (_, ${vals}) {
139
+ ${inner}
124
140
  return newObj;
125
141
  })`, callback);
142
+ }
126
143
  }
127
144
  finalize() {
128
145
  this.tupleToObjectJIT((fn) => {
@@ -184,8 +201,8 @@ exports.ObjectStep = ObjectStep;
184
201
  * A plan that represents an object using the keys given and the values being
185
202
  * the results of the associated plans.
186
203
  */
187
- function object(obj) {
188
- return new ObjectStep(obj);
204
+ function object(obj, cacheConfig) {
205
+ return new ObjectStep(obj, cacheConfig);
189
206
  }
190
207
  exports.object = object;
191
208
  //# sourceMappingURL=object.js.map
@@ -1,4 +1,5 @@
1
- import type { PromiseOrDirect, UnbatchedExecutionExtra, UnwrapPlanTuple } from "../interfaces.js";
1
+ import type { PromiseOrDirect, UnbatchedExecutionExtra } from "../interfaces.js";
2
+ import type { Multistep, UnwrapMultistep } from "../multistep.js";
2
3
  import type { ExecutableStep } from "../step.js";
3
4
  import { UnbatchedExecutableStep } from "../step.js";
4
5
  /**
@@ -22,7 +23,6 @@ export declare class SideEffectStep<TIn, TOut> extends UnbatchedExecutableStep<T
22
23
  * callback. Note: if you need to pass more than one value, pass a `ListStep`
23
24
  * as the `$plan` argument.
24
25
  */
25
- declare function sideEffect<const TIn extends readonly ExecutableStep[], TOut>(plans: TIn, fn: (value: UnwrapPlanTuple<TIn>) => PromiseOrDirect<TOut>): SideEffectStep<UnwrapPlanTuple<TIn>, TOut>;
26
- declare function sideEffect<const TIn, TOut>($plan: ExecutableStep<TIn> | null | undefined, fn: (value: TIn) => PromiseOrDirect<TOut>): SideEffectStep<TIn, TOut>;
26
+ declare function sideEffect<const TInMultistep extends Multistep, TOut>(spec: TInMultistep, fn: (value: UnwrapMultistep<TInMultistep>) => PromiseOrDirect<TOut>): SideEffectStep<UnwrapMultistep<TInMultistep>, TOut>;
27
27
  export { sideEffect };
28
28
  //# sourceMappingURL=sideEffect.d.ts.map
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sideEffect = exports.SideEffectStep = void 0;
4
+ const multistep_js_1 = require("../multistep.js");
4
5
  const step_js_1 = require("../step.js");
5
- const list_js_1 = require("./list.js");
6
6
  /**
7
7
  * Calls the given callback function for each tuple
8
8
  */
@@ -27,13 +27,17 @@ class SideEffectStep extends step_js_1.UnbatchedExecutableStep {
27
27
  }
28
28
  }
29
29
  exports.SideEffectStep = SideEffectStep;
30
- function sideEffect(planOrPlans, fn) {
30
+ /**
31
+ * A plan that takes the input `$plan` and feeds each value through the `fn`
32
+ * callback. Note: if you need to pass more than one value, pass a `ListStep`
33
+ * as the `$plan` argument.
34
+ */
35
+ function sideEffect(spec, fn) {
31
36
  if (fn.length > 1) {
32
37
  throw new Error("sideEffect callback should accept one argument, perhaps you forgot to destructure the arguments?");
33
38
  }
34
- const $result = Array.isArray(planOrPlans)
35
- ? new SideEffectStep((0, list_js_1.list)(planOrPlans), fn)
36
- : new SideEffectStep(planOrPlans, fn);
39
+ const $in = (0, multistep_js_1.multistep)(spec);
40
+ const $result = new SideEffectStep($in, fn);
37
41
  return $result;
38
42
  }
39
43
  exports.sideEffect = sideEffect;
package/dist/utils.d.ts CHANGED
@@ -143,11 +143,13 @@ export declare function stepAMayDependOnStepB($a: ExecutableStep, $b: Executable
143
143
  export declare function stepsAreInSamePhase(ancestor: ExecutableStep, descendent: ExecutableStep): boolean;
144
144
  export declare const canonicalJSONStringify: (o: object) => string;
145
145
  export declare function assertNotAsync(fn: any, name: string): void;
146
+ export declare function assertNotPromise<TVal>(value: TVal, fn: any, name: string): TVal;
146
147
  export declare function hasItemPlan(step: ExecutableStep & {
147
148
  itemPlan?: ($item: ExecutableStep) => ExecutableStep;
148
149
  }): step is ExecutableStep & {
149
150
  itemPlan: ($item: ExecutableStep) => ExecutableStep;
150
151
  };
151
152
  export declare function exportNameHint(obj: any, nameHint: string): void;
153
+ export declare function isTuple<T extends readonly [...(readonly any[])]>(t: any | T): t is T;
152
154
  export {};
153
155
  //# sourceMappingURL=utils.d.ts.map
package/dist/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.exportNameHint = exports.hasItemPlan = exports.assertNotAsync = exports.canonicalJSONStringify = exports.stepsAreInSamePhase = exports.stepAMayDependOnStepB = exports.stepADependsOnStepB = exports.writeableArray = exports.sudo = exports.isTypePlanned = exports.findVariableNamesUsed = exports.arrayOfLengthCb = exports.arrayOfLength = exports.stack = exports.sharedNull = exports.getEnumValueConfig = exports.inputObjectFieldSpec = exports.newInputObjectTypeBuilder = exports.newGrafastFieldConfigBuilder = exports.objectFieldSpec = exports.newObjectTypeBuilder = exports.objectSpec = exports.arraysMatch = exports.isDeferred = exports.isPromiseLike = exports.isPromise = exports.defaultValueToValueNode = exports.assertNullPrototype = exports.ROOT_VALUE_OBJECT = void 0;
3
+ exports.isTuple = exports.exportNameHint = exports.hasItemPlan = exports.assertNotPromise = exports.assertNotAsync = exports.canonicalJSONStringify = exports.stepsAreInSamePhase = exports.stepAMayDependOnStepB = exports.stepADependsOnStepB = exports.writeableArray = exports.sudo = exports.isTypePlanned = exports.findVariableNamesUsed = exports.arrayOfLengthCb = exports.arrayOfLength = exports.stack = exports.sharedNull = exports.getEnumValueConfig = exports.inputObjectFieldSpec = exports.newInputObjectTypeBuilder = exports.newGrafastFieldConfigBuilder = exports.objectFieldSpec = exports.newObjectTypeBuilder = exports.objectSpec = exports.arraysMatch = exports.isDeferred = exports.isPromiseLike = exports.isPromise = exports.defaultValueToValueNode = exports.assertNullPrototype = exports.ROOT_VALUE_OBJECT = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const graphql = tslib_1.__importStar(require("graphql"));
6
6
  const assert = tslib_1.__importStar(require("./assert.js"));
@@ -719,12 +719,21 @@ exports.stepsAreInSamePhase = stepsAreInSamePhase;
719
719
  // ENHANCE: implement this!
720
720
  const canonicalJSONStringify = (o) => JSON.stringify(o);
721
721
  exports.canonicalJSONStringify = canonicalJSONStringify;
722
+ // PERF: only do this if isDev; otherwise replace with NOOP?
722
723
  function assertNotAsync(fn, name) {
723
724
  if (fn?.constructor?.name === "AsyncFunction") {
724
725
  throw new Error(`Plans must be synchronous, but this schema has an async function at '${name}': ${fn.toString()}`);
725
726
  }
726
727
  }
727
728
  exports.assertNotAsync = assertNotAsync;
729
+ // PERF: only do this if isDev; otherwise replace with NOOP?
730
+ function assertNotPromise(value, fn, name) {
731
+ if (isPromiseLike(value)) {
732
+ throw new Error(`Plans must be synchronous, but this schema has an function at '${name}' that returned a promise-like object: ${fn.toString()}`);
733
+ }
734
+ return value;
735
+ }
736
+ exports.assertNotPromise = assertNotPromise;
728
737
  function hasItemPlan(step) {
729
738
  return "itemPlan" in step && typeof step.itemPlan === "function";
730
739
  }
@@ -743,4 +752,8 @@ function exportNameHint(obj, nameHint) {
743
752
  }
744
753
  }
745
754
  exports.exportNameHint = exportNameHint;
755
+ function isTuple(t) {
756
+ return Array.isArray(t);
757
+ }
758
+ exports.isTuple = isTuple;
746
759
  //# sourceMappingURL=utils.js.map
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version = "0.1.1-beta.14";
1
+ export declare const version = "0.1.1-beta.16";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
4
  // This file is autogenerated by /scripts/postversion.mjs
5
- exports.version = "0.1.1-beta.14";
5
+ exports.version = "0.1.1-beta.16";
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grafast",
3
- "version": "0.1.1-beta.14",
3
+ "version": "0.1.1-beta.16",
4
4
  "description": "Cutting edge GraphQL planning and execution engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -59,7 +59,7 @@
59
59
  "chalk": "^4.1.2",
60
60
  "debug": "^4.3.4",
61
61
  "eventemitter3": "^5.0.1",
62
- "graphile-config": "^0.0.1-beta.9",
62
+ "graphile-config": "^0.0.1-beta.11",
63
63
  "graphql": "^16.1.0-experimental-stream-defer.6",
64
64
  "iterall": "^1.3.0",
65
65
  "tamedevil": "^0.0.0-beta.7",