grafast 0.1.1-beta.10 → 0.1.1-beta.12
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 +0 -3
- package/dist/args.d.ts +4 -7
- package/dist/args.js +53 -37
- package/dist/config.d.ts +0 -17
- package/dist/config.js +1 -95
- package/dist/constraints.d.ts +15 -1
- package/dist/constraints.js +40 -1
- package/dist/dev.js +2 -4
- package/dist/engine/LayerPlan.d.ts +1 -0
- package/dist/engine/LayerPlan.js +62 -9
- package/dist/engine/OperationPlan.js +370 -274
- package/dist/engine/OutputPlan.d.ts +6 -5
- package/dist/engine/OutputPlan.js +423 -444
- package/dist/engine/executeBucket.js +60 -82
- package/dist/error.d.ts +13 -0
- package/dist/execute.d.ts +2 -2
- package/dist/execute.js +27 -6
- package/dist/grafastGraphql.d.ts +6 -1
- package/dist/grafastGraphql.js +33 -13
- package/dist/graphqlCollectFields.d.ts +6 -0
- package/dist/graphqlCollectFields.js +14 -8
- package/dist/index.d.ts +21 -12
- package/dist/index.js +5 -2
- package/dist/interfaces.d.ts +63 -2
- package/dist/interfaces.js +0 -2
- package/dist/mermaid.js +20 -11
- package/dist/middleware.d.ts +7 -0
- package/dist/middleware.js +25 -0
- package/dist/operationPlan-input.js +8 -1
- package/dist/planJSONInterfaces.d.ts +2 -0
- package/dist/prepare.js +26 -8
- package/dist/step.d.ts +5 -5
- package/dist/step.js +27 -2
- package/dist/steps/__flag.d.ts +3 -2
- package/dist/steps/__inputObject.d.ts +1 -0
- package/dist/steps/__inputObject.js +36 -0
- package/dist/steps/__item.d.ts +3 -3
- package/dist/steps/__trackedValue.d.ts +8 -0
- package/dist/steps/__trackedValue.js +40 -0
- package/dist/steps/__value.d.ts +2 -1
- package/dist/steps/constant.d.ts +2 -0
- package/dist/steps/constant.js +12 -0
- package/dist/steps/graphqlResolver.js +8 -5
- package/dist/steps/listen.d.ts +2 -2
- package/dist/steps/object.d.ts +1 -1
- package/dist/steps/sideEffect.d.ts +0 -1
- package/dist/subscribe.js +23 -3
- package/dist/thereCanBeOnlyOne.js +1 -1
- package/dist/utils.d.ts +5 -1
- package/dist/utils.js +7 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -51,11 +51,8 @@ And please give some love to our featured sponsors 🤩:
|
|
|
51
51
|
<table><tr>
|
|
52
52
|
<td align="center"><a href="https://www.the-guild.dev/"><img src="https://graphile.org/images/sponsors/theguild.png" width="90" height="90" alt="The Guild" /><br />The Guild</a> *</td>
|
|
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
|
-
<td align="center"><a href="https://www.netflix.com/"><img src="https://graphile.org/images/sponsors/Netflix.png" width="90" height="90" alt="Netflix" /><br />Netflix</a> *</td>
|
|
55
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>
|
|
56
|
-
</tr><tr>
|
|
57
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>
|
|
58
|
-
<td align="center"><a href="https://www.sylvera.com/"><img src="https://graphile.org/images/sponsors/sylvera.svg" width="90" height="90" alt="Sylvera" /><br />Sylvera</a> *</td>
|
|
59
56
|
</tr></table>
|
|
60
57
|
|
|
61
58
|
<em>\* Sponsors the entire Graphile suite</em>
|
package/dist/args.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { ExecutionArgs } from "graphql";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* @experimental
|
|
7
|
-
*/
|
|
8
|
-
export declare function hookArgs(rawArgs: ExecutionArgs, resolvedPreset: GraphileConfig.ResolvedPreset, ctx: Partial<Grafast.RequestContext>): Grafast.ExecutionArgs | PromiseLike<Grafast.ExecutionArgs>;
|
|
2
|
+
import type { GrafastExecutionArgs, PromiseOrDirect } from "./interfaces.js";
|
|
3
|
+
/** @deprecated Pass `resolvedPreset` and `requestContext` via args directly */
|
|
4
|
+
export declare function hookArgs(rawArgs: ExecutionArgs, resolvedPreset: GraphileConfig.ResolvedPreset, ctx: Partial<Grafast.RequestContext>): PromiseOrDirect<Grafast.ExecutionArgs>;
|
|
5
|
+
export declare function hookArgs(rawArgs: GrafastExecutionArgs): PromiseOrDirect<Grafast.ExecutionArgs>;
|
|
9
6
|
//# sourceMappingURL=args.d.ts.map
|
package/dist/args.js
CHANGED
|
@@ -1,62 +1,78 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.hookArgs = void 0;
|
|
4
|
-
const config_js_1 = require("./config.js");
|
|
5
4
|
const interfaces_js_1 = require("./interfaces.js");
|
|
5
|
+
const middleware_js_1 = require("./middleware.js");
|
|
6
6
|
const utils_js_1 = require("./utils.js");
|
|
7
|
+
const EMPTY_OBJECT = Object.freeze(Object.create(null));
|
|
8
|
+
const $$writeTest = Symbol("grafastWriteTest");
|
|
7
9
|
/**
|
|
8
10
|
* Applies Graphile Config hooks to your GraphQL request, e.g. to
|
|
9
11
|
* populate context or similar.
|
|
10
12
|
*
|
|
11
13
|
* @experimental
|
|
12
14
|
*/
|
|
13
|
-
function hookArgs(rawArgs,
|
|
15
|
+
function hookArgs(rawArgs, legacyResolvedPreset, legacyCtx) {
|
|
16
|
+
if (legacyResolvedPreset !== undefined) {
|
|
17
|
+
rawArgs.resolvedPreset = legacyResolvedPreset;
|
|
18
|
+
}
|
|
19
|
+
if (legacyCtx !== undefined) {
|
|
20
|
+
rawArgs.requestContext = rawArgs.requestContext ?? legacyCtx;
|
|
21
|
+
}
|
|
22
|
+
const { middleware: rawMiddleware, resolvedPreset, contextValue: rawContextValue, } = rawArgs;
|
|
23
|
+
try {
|
|
24
|
+
rawContextValue[$$writeTest] = true;
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
// Make context mutable
|
|
28
|
+
rawArgs.contextValue = Object.assign(Object.create(null), rawContextValue);
|
|
29
|
+
}
|
|
30
|
+
const middleware = rawMiddleware === undefined && resolvedPreset != null
|
|
31
|
+
? (0, middleware_js_1.getGrafastMiddleware)(resolvedPreset)
|
|
32
|
+
: rawMiddleware ?? null;
|
|
33
|
+
if (rawMiddleware === undefined) {
|
|
34
|
+
rawArgs.middleware = middleware;
|
|
35
|
+
}
|
|
14
36
|
const args = rawArgs;
|
|
15
37
|
// Assert that args haven't already been hooked
|
|
16
38
|
if (args[interfaces_js_1.$$hooked]) {
|
|
17
39
|
throw new Error("Must not call hookArgs twice!");
|
|
18
40
|
}
|
|
19
41
|
args[interfaces_js_1.$$hooked] = true;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
if (middleware != null) {
|
|
43
|
+
return middleware.run("prepareArgs", { args }, finalizeWithEvent);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return finalize(args);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.hookArgs = hookArgs;
|
|
50
|
+
function finalize(args) {
|
|
51
|
+
const userContext = args.resolvedPreset?.grafast?.context;
|
|
52
|
+
const contextValue = args.contextValue;
|
|
53
|
+
if (typeof userContext === "function") {
|
|
54
|
+
const result = userContext(args.requestContext ?? EMPTY_OBJECT, args);
|
|
55
|
+
if ((0, utils_js_1.isPromiseLike)(result)) {
|
|
56
|
+
// Deliberately shadowed 'result'
|
|
57
|
+
return result.then((result) => {
|
|
58
|
+
Object.assign(contextValue, result);
|
|
36
59
|
return args;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
else if (typeof userContext === "object" && userContext !== null) {
|
|
40
|
-
Object.assign(args.contextValue, userContext);
|
|
41
|
-
return args;
|
|
60
|
+
});
|
|
42
61
|
}
|
|
43
62
|
else {
|
|
63
|
+
Object.assign(contextValue, result);
|
|
44
64
|
return args;
|
|
45
65
|
}
|
|
46
|
-
};
|
|
47
|
-
if (resolvedPreset !== config_js_1.NULL_PRESET &&
|
|
48
|
-
resolvedPreset.plugins &&
|
|
49
|
-
resolvedPreset.plugins.length > 0) {
|
|
50
|
-
const event = { args, ctx, resolvedPreset };
|
|
51
|
-
const result = (0, config_js_1.hook)(resolvedPreset, "args", event);
|
|
52
|
-
if ((0, utils_js_1.isPromiseLike)(result)) {
|
|
53
|
-
return result.then(() => finalize(event.args));
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
return finalize(event.args);
|
|
57
|
-
}
|
|
58
66
|
}
|
|
59
|
-
|
|
67
|
+
else if (typeof userContext === "object" && userContext !== null) {
|
|
68
|
+
Object.assign(contextValue, userContext);
|
|
69
|
+
return args;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
return args;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function finalizeWithEvent(event) {
|
|
76
|
+
return finalize(event.args);
|
|
60
77
|
}
|
|
61
|
-
exports.hookArgs = hookArgs;
|
|
62
78
|
//# sourceMappingURL=args.js.map
|
package/dist/config.d.ts
CHANGED
|
@@ -1,19 +1,2 @@
|
|
|
1
|
-
import type { AsyncHooks, PluginHook } from "graphile-config";
|
|
2
1
|
export declare const NULL_PRESET: GraphileConfig.ResolvedPreset;
|
|
3
|
-
type GraphileConfigModule = typeof import("graphile-config");
|
|
4
|
-
type PromiseOrValue<T> = T | Promise<T>;
|
|
5
|
-
export declare function withGraphileConfig<T>(callback: (graphileConfig: GraphileConfigModule | null) => PromiseOrValue<T>): PromiseOrValue<T>;
|
|
6
|
-
declare const $$skipHooks: unique symbol;
|
|
7
|
-
declare const $$hooksForPreset: unique symbol;
|
|
8
|
-
declare global {
|
|
9
|
-
namespace GraphileConfig {
|
|
10
|
-
interface ResolvedPreset {
|
|
11
|
-
[$$hooksForPreset]?: null | AsyncHooks<GraphileConfig.GrafastHooks>;
|
|
12
|
-
[$$skipHooks]?: Record<string, boolean>;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
export declare function withHooks<TResult>(resolvedPreset: GraphileConfig.ResolvedPreset, callback: (hooks: AsyncHooks<GraphileConfig.GrafastHooks> | null) => PromiseOrValue<TResult>): PromiseOrValue<TResult>;
|
|
17
|
-
export declare function hook<THookName extends keyof GraphileConfig.GrafastHooks>(resolvedPreset: GraphileConfig.ResolvedPreset, hookName: THookName, ...args: Parameters<GraphileConfig.GrafastHooks[THookName] extends PluginHook<infer U> ? U : never>): PromiseOrValue<void>;
|
|
18
|
-
export {};
|
|
19
2
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.js
CHANGED
|
@@ -1,99 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.NULL_PRESET = void 0;
|
|
4
4
|
exports.NULL_PRESET = Object.freeze(Object.create(null));
|
|
5
|
-
let graphileConfig = undefined;
|
|
6
|
-
let graphileConfigLoaded = false;
|
|
7
|
-
function withGraphileConfig(callback) {
|
|
8
|
-
if (graphileConfig === undefined) {
|
|
9
|
-
// ESM:
|
|
10
|
-
// This should be
|
|
11
|
-
// graphileConfig = import("graphile-config").then(
|
|
12
|
-
// but that causes a segfault in jest/node when testing third party
|
|
13
|
-
// modules. So we had to convert everything to CommonJS.
|
|
14
|
-
graphileConfig = new Promise((resolve, reject) => {
|
|
15
|
-
try {
|
|
16
|
-
resolve(require("graphile-config"));
|
|
17
|
-
}
|
|
18
|
-
catch (e) {
|
|
19
|
-
if (e.code === "ERR_REQUIRE_ESM") {
|
|
20
|
-
return import("graphile-config").then(resolve, reject);
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
reject(e);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}).then((GC) => {
|
|
27
|
-
graphileConfig = GC;
|
|
28
|
-
graphileConfigLoaded = true;
|
|
29
|
-
return GC;
|
|
30
|
-
}, () => {
|
|
31
|
-
graphileConfig = null;
|
|
32
|
-
graphileConfigLoaded = true;
|
|
33
|
-
return null;
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
if (graphileConfigLoaded) {
|
|
37
|
-
return callback(graphileConfig);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
return graphileConfig.then(callback);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
exports.withGraphileConfig = withGraphileConfig;
|
|
44
|
-
const $$skipHooks = Symbol("skipHooks");
|
|
45
|
-
const $$hooksForPreset = Symbol("grafastHooks");
|
|
46
|
-
function withHooks(resolvedPreset, callback) {
|
|
47
|
-
const existing = resolvedPreset[$$hooksForPreset];
|
|
48
|
-
if (existing !== undefined) {
|
|
49
|
-
return callback(existing);
|
|
50
|
-
}
|
|
51
|
-
if (!resolvedPreset.plugins || resolvedPreset.plugins.length === 0) {
|
|
52
|
-
resolvedPreset[$$hooksForPreset] = null;
|
|
53
|
-
return callback(null);
|
|
54
|
-
}
|
|
55
|
-
const plugins = resolvedPreset.plugins;
|
|
56
|
-
return withGraphileConfig((gc) => {
|
|
57
|
-
if (gc !== null) {
|
|
58
|
-
const hooks = new gc.AsyncHooks();
|
|
59
|
-
gc.applyHooks(plugins, (p) => p.grafast?.hooks, (name, fn, _plugin) => {
|
|
60
|
-
hooks.hook(name, fn);
|
|
61
|
-
});
|
|
62
|
-
resolvedPreset[$$hooksForPreset] = hooks;
|
|
63
|
-
return callback(hooks);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
resolvedPreset[$$hooksForPreset] = null;
|
|
67
|
-
return callback(null);
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
exports.withHooks = withHooks;
|
|
72
|
-
function hook(resolvedPreset, hookName, ...args) {
|
|
73
|
-
if (resolvedPreset[$$skipHooks]?.[hookName]) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
return withHooks(resolvedPreset, (hooks) => {
|
|
77
|
-
if (hooks !== null) {
|
|
78
|
-
if (hooks.callbacks[hookName] !== undefined) {
|
|
79
|
-
return hooks.process(hookName, ...args);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
if (!resolvedPreset[$$skipHooks]) {
|
|
83
|
-
resolvedPreset[$$skipHooks] = Object.create(null);
|
|
84
|
-
}
|
|
85
|
-
resolvedPreset[$$skipHooks][hookName] = true;
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
if (!resolvedPreset[$$skipHooks]) {
|
|
91
|
-
resolvedPreset[$$skipHooks] = Object.create(null);
|
|
92
|
-
}
|
|
93
|
-
resolvedPreset[$$skipHooks][hookName] = true;
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
exports.hook = hook;
|
|
99
5
|
//# sourceMappingURL=config.js.map
|
package/dist/constraints.d.ts
CHANGED
|
@@ -27,6 +27,20 @@ interface ExistsConstraint {
|
|
|
27
27
|
path: (string | number)[];
|
|
28
28
|
exists: boolean;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* If `keys` is null: asserts that there is no value at the given
|
|
32
|
+
* path.
|
|
33
|
+
*
|
|
34
|
+
* Otherwise: asserts that the value at the given path has the exact same keys.
|
|
35
|
+
*/
|
|
36
|
+
interface KeysConstraint {
|
|
37
|
+
type: "keys";
|
|
38
|
+
path: (string | number)[];
|
|
39
|
+
/**
|
|
40
|
+
* If this is null it implies that the object did not exist.
|
|
41
|
+
*/
|
|
42
|
+
keys: ReadonlyArray<string> | null;
|
|
43
|
+
}
|
|
30
44
|
/**
|
|
31
45
|
* If `expectedLength` is null: asserts that there is no value at the given
|
|
32
46
|
* path.
|
|
@@ -52,7 +66,7 @@ interface IsEmptyConstraint {
|
|
|
52
66
|
path: (string | number)[];
|
|
53
67
|
isEmpty: boolean;
|
|
54
68
|
}
|
|
55
|
-
export type Constraint = ValueConstraint | EqualityConstraint | ExistsConstraint | LengthConstraint | IsEmptyConstraint;
|
|
69
|
+
export type Constraint = ValueConstraint | EqualityConstraint | ExistsConstraint | LengthConstraint | IsEmptyConstraint | KeysConstraint;
|
|
56
70
|
/**
|
|
57
71
|
* Implements the `MatchesConstraints` algorithm.
|
|
58
72
|
*/
|
package/dist/constraints.js
CHANGED
|
@@ -32,7 +32,8 @@ function matchesConstraint(constraint, object) {
|
|
|
32
32
|
const value = valueAtPath(object, constraint.path);
|
|
33
33
|
switch (constraint.type) {
|
|
34
34
|
case "length": {
|
|
35
|
-
|
|
35
|
+
const actualLength = Array.isArray(value) ? value.length : null;
|
|
36
|
+
return actualLength === constraint.expectedLength;
|
|
36
37
|
}
|
|
37
38
|
case "exists": {
|
|
38
39
|
return (value !== undefined) === constraint.exists;
|
|
@@ -49,6 +50,44 @@ function matchesConstraint(constraint, object) {
|
|
|
49
50
|
Object.keys(value).length === 0;
|
|
50
51
|
return isEmpty === constraint.isEmpty;
|
|
51
52
|
}
|
|
53
|
+
case "keys": {
|
|
54
|
+
const { keys: expectedKeys } = constraint;
|
|
55
|
+
if (expectedKeys === null) {
|
|
56
|
+
return value == null || typeof value !== "object";
|
|
57
|
+
}
|
|
58
|
+
else if (value == null || typeof value !== "object") {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// keys are always in order of the gql type; see coerceInputValue and __InputObjectStep ctor
|
|
63
|
+
const valueKeys = Object.keys(value);
|
|
64
|
+
const valueKeyCount = valueKeys.length;
|
|
65
|
+
const expectedKeyCount = expectedKeys.length;
|
|
66
|
+
// Optimization: early bail
|
|
67
|
+
if (valueKeyCount < expectedKeyCount) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* This is `i` but adjusted so that `undefined` doesn't increment it.
|
|
72
|
+
* Should match index in `expectedKeys`.
|
|
73
|
+
*/
|
|
74
|
+
let definedRawKeyCount = 0;
|
|
75
|
+
for (let i = 0; i < valueKeyCount; i++) {
|
|
76
|
+
const valueKey = valueKeys[i];
|
|
77
|
+
if (value[valueKey] !== undefined) {
|
|
78
|
+
if (valueKey !== expectedKeys[definedRawKeyCount]) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
definedRawKeyCount++;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Make sure there aren't any additional expected keys
|
|
85
|
+
if (definedRawKeyCount !== expectedKeyCount) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
52
91
|
default: {
|
|
53
92
|
const never = constraint;
|
|
54
93
|
throw new Error(`Unsupported constraint type '${never.type}'`);
|
package/dist/dev.js
CHANGED
|
@@ -19,9 +19,7 @@ if (typeof process !== "undefined" &&
|
|
|
19
19
|
typeof nodeEnv === "undefined") {
|
|
20
20
|
console.warn(`The GRAPHILE_ENV environmental variable is not set; Grafast will run in production mode. In your development environments, it's recommended that you set \`GRAPHILE_ENV=development\` to opt in to additional checks that will provide guidance and help you to catch issues in your code earlier, and other changes such as formatting to improve your development experience.`);
|
|
21
21
|
}
|
|
22
|
-
else if (exports.isDev && !exports.isTest) {
|
|
23
|
-
console.warn(`Grafast is running in development mode due to
|
|
24
|
-
? `GRAPHILE_ENV=${graphileEnv}`
|
|
25
|
-
: `NODE_ENV=${nodeEnv}`}\`; this is recommended for development environments (and strongly discouraged in production), but will impact on performance - in particular, planning will be significantly more expensive.`);
|
|
22
|
+
else if (exports.isDev && !exports.isTest && typeof graphileEnv === "undefined") {
|
|
23
|
+
console.warn(`Grafast is running in development mode due to \`NODE_ENV=${nodeEnv}\`; this is recommended for development environments (and strongly discouraged in production), but will impact on performance - in particular, planning will be significantly more expensive. To remove this warning, make this explicit with \`GRAPHILE_ENV=development\` envvar.`);
|
|
26
24
|
}
|
|
27
25
|
//# sourceMappingURL=dev.js.map
|
|
@@ -113,6 +113,7 @@ export declare class LayerPlan<TReason extends LayerPlanReason = LayerPlanReason
|
|
|
113
113
|
constructor(operationPlan: OperationPlan, parentLayerPlan: LayerPlan | null, reason: TReason);
|
|
114
114
|
toString(): string;
|
|
115
115
|
print(depth?: number): string;
|
|
116
|
+
_hasSetRootStep: boolean;
|
|
116
117
|
setRootStep($root: ExecutableStep): void;
|
|
117
118
|
finalize(): void;
|
|
118
119
|
newBucket(parentBucket: Bucket): Bucket | null;
|
package/dist/engine/LayerPlan.js
CHANGED
|
@@ -89,6 +89,23 @@ class LayerPlan {
|
|
|
89
89
|
this.steps = [];
|
|
90
90
|
/** @internal */
|
|
91
91
|
this.pendingSteps = [];
|
|
92
|
+
/**
|
|
93
|
+
* This goes along with `parentStep` in the reason, except it applies to all
|
|
94
|
+
* layer plan types and we figure it out automatically from the parent layer
|
|
95
|
+
* plan. If this step has an error at a given index, then it should be
|
|
96
|
+
* treated as if the parentStep had an error at that same index.
|
|
97
|
+
*
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
this.parentSideEffectStep = null;
|
|
101
|
+
/**
|
|
102
|
+
* This tracks the latest seen side effect at the current point in planning
|
|
103
|
+
* (such that created steps take this to be their implicitSideEffectStep).
|
|
104
|
+
* This isn't used once planning is complete.
|
|
105
|
+
*
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
this.latestSideEffectStep = null;
|
|
92
109
|
/**
|
|
93
110
|
* Describes the order in which the steps within this LayerPlan are executed.
|
|
94
111
|
*
|
|
@@ -97,6 +114,13 @@ class LayerPlan {
|
|
|
97
114
|
* @internal
|
|
98
115
|
*/
|
|
99
116
|
this.phases = [];
|
|
117
|
+
this._hasSetRootStep = false;
|
|
118
|
+
// This layer plan is dependent on the latest side effect. Note that when
|
|
119
|
+
// we set a `rootStep` later, if the root step is dependent on this step
|
|
120
|
+
// (directly or indirectly) we will clear this property.
|
|
121
|
+
this.parentSideEffectStep = parentLayerPlan?.latestSideEffectStep ?? null;
|
|
122
|
+
// There has yet to be any side effects created in this layer.
|
|
123
|
+
this.latestSideEffectStep = null;
|
|
100
124
|
this.stepsByConstructor = new Map();
|
|
101
125
|
if (parentLayerPlan !== null) {
|
|
102
126
|
this.depth = parentLayerPlan.depth + 1;
|
|
@@ -133,7 +157,7 @@ class LayerPlan {
|
|
|
133
157
|
? `{${this.reason.typeNames.join(",")}}`
|
|
134
158
|
: "";
|
|
135
159
|
const deps = this.copyStepIds.length > 0 ? `/${this.copyStepIds}` : "";
|
|
136
|
-
return `LayerPlan<${this.id}${chain}?${this.reason.type}${reasonExtra}!${this.rootStep?.id ?? "x"}${deps}>`;
|
|
160
|
+
return `LayerPlan<${this.id}${chain}${this.parentSideEffectStep ? `^${this.parentSideEffectStep.id}` : ""}?${this.reason.type}${reasonExtra}!${this.rootStep?.id ?? "x"}${deps}>`;
|
|
137
161
|
}
|
|
138
162
|
print(depth = 0) {
|
|
139
163
|
const output = [`${" ".repeat(depth * 2)}${this}`];
|
|
@@ -143,7 +167,15 @@ class LayerPlan {
|
|
|
143
167
|
return output.join("\n");
|
|
144
168
|
}
|
|
145
169
|
setRootStep($root) {
|
|
170
|
+
if (this._hasSetRootStep) {
|
|
171
|
+
throw new Error(`Set root step on ${this} more than once`);
|
|
172
|
+
}
|
|
173
|
+
this._hasSetRootStep = true;
|
|
146
174
|
this.operationPlan.stepTracker.setLayerPlanRootStep(this, $root);
|
|
175
|
+
// NOTE: we may clear `this.parentSideEffectStep` based on the `$root` step
|
|
176
|
+
// having an explicit dependency on `this.parentSideEffectStep`; but that
|
|
177
|
+
// will be done as part of `OperationPlan::finalizeLayerPlans()` because
|
|
178
|
+
// steps aren't assigned `implicitSideEffectStep`s until that point.
|
|
147
179
|
}
|
|
148
180
|
/** @internal Use plan.getStep(id) instead. */
|
|
149
181
|
getStep(id, requestingStep) {
|
|
@@ -176,6 +208,14 @@ class LayerPlan {
|
|
|
176
208
|
: [];
|
|
177
209
|
const iterators = this.reason.type === "mutationField" ? parentBucket.iterators : [];
|
|
178
210
|
const map = new Map();
|
|
211
|
+
const $parentSideEffect = this.parentSideEffectStep;
|
|
212
|
+
let parentSideEffectValue;
|
|
213
|
+
if ($parentSideEffect) {
|
|
214
|
+
parentSideEffectValue = parentBucket.store.get($parentSideEffect.id);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
parentSideEffectValue = null;
|
|
218
|
+
}
|
|
179
219
|
let size = 0;
|
|
180
220
|
switch (this.reason.type) {
|
|
181
221
|
case "nullableBoundary": {
|
|
@@ -194,15 +234,20 @@ class LayerPlan {
|
|
|
194
234
|
size = 0;
|
|
195
235
|
}
|
|
196
236
|
else {
|
|
197
|
-
size = parentBucket.size;
|
|
198
237
|
store.set(itemStepId, fieldValue);
|
|
199
238
|
for (const stepId of copyStepIds) {
|
|
200
239
|
store.set(stepId, parentBucket.store.get(stepId));
|
|
201
240
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
241
|
+
const parentBucketSize = parentBucket.size;
|
|
242
|
+
for (let originalIndex = 0; originalIndex < parentBucketSize; originalIndex++) {
|
|
243
|
+
if (parentSideEffectValue === null ||
|
|
244
|
+
!(parentSideEffectValue._flagsAt(originalIndex) & interfaces_js_1.FLAG_ERROR)) {
|
|
245
|
+
const newIndex = size++;
|
|
246
|
+
map.set(originalIndex, newIndex);
|
|
247
|
+
polymorphicPathList[newIndex] =
|
|
248
|
+
parentBucket.polymorphicPathList[originalIndex];
|
|
249
|
+
iterators[newIndex] = parentBucket.iterators[originalIndex];
|
|
250
|
+
}
|
|
206
251
|
}
|
|
207
252
|
}
|
|
208
253
|
}
|
|
@@ -244,10 +289,12 @@ class LayerPlan {
|
|
|
244
289
|
// than we have parent bucket entries (because we exclude nulls), so
|
|
245
290
|
// we must "multiply up" (down) the store entries.
|
|
246
291
|
for (let originalIndex = 0; originalIndex < parentBucket.size; originalIndex++) {
|
|
247
|
-
|
|
248
|
-
|
|
292
|
+
if ((parentSideEffectValue === null ||
|
|
293
|
+
!(parentSideEffectValue._flagsAt(originalIndex) & interfaces_js_1.FLAG_ERROR)) &&
|
|
294
|
+
!(nullableStepStore._flagsAt(originalIndex) & interfaces_js_1.FLAG_NULL)) {
|
|
249
295
|
const newIndex = size++;
|
|
250
296
|
map.set(originalIndex, newIndex);
|
|
297
|
+
const fieldValue = nullableStepStore.at(originalIndex);
|
|
251
298
|
itemStepIdList[newIndex] = fieldValue;
|
|
252
299
|
polymorphicPathList[newIndex] =
|
|
253
300
|
parentBucket.polymorphicPathList[originalIndex];
|
|
@@ -295,7 +342,9 @@ class LayerPlan {
|
|
|
295
342
|
// have parent buckets, so we must "multiply up" the store entries.
|
|
296
343
|
for (let originalIndex = 0; originalIndex < parentBucket.size; originalIndex++) {
|
|
297
344
|
const list = listStepStore.at(originalIndex);
|
|
298
|
-
if (
|
|
345
|
+
if ((parentSideEffectValue === null ||
|
|
346
|
+
!(parentSideEffectValue._flagsAt(originalIndex) & interfaces_js_1.FLAG_ERROR)) &&
|
|
347
|
+
Array.isArray(list)) {
|
|
299
348
|
const newIndexes = [];
|
|
300
349
|
map.set(originalIndex, newIndexes);
|
|
301
350
|
for (let j = 0, l = list.length; j < l; j++) {
|
|
@@ -356,6 +405,10 @@ class LayerPlan {
|
|
|
356
405
|
if (flags & (interfaces_js_1.FLAG_ERROR | interfaces_js_1.FLAG_INHIBITED | interfaces_js_1.FLAG_NULL)) {
|
|
357
406
|
continue;
|
|
358
407
|
}
|
|
408
|
+
if (parentSideEffectValue !== null &&
|
|
409
|
+
parentSideEffectValue._flagsAt(originalIndex) & interfaces_js_1.FLAG_ERROR) {
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
359
412
|
const value = polymorphicPlanStore.at(originalIndex);
|
|
360
413
|
const typeName = (0, polymorphic_js_1.resolveType)(value);
|
|
361
414
|
if (!targetTypeNames.includes(typeName)) {
|