grafast 0.1.1-beta.0 → 0.1.1-beta.10
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 +3 -4
- package/dist/args.js +62 -0
- package/dist/assert.js +24 -0
- package/dist/bucket.d.ts +1 -89
- package/dist/bucket.js +4 -0
- package/dist/config.js +99 -0
- package/dist/constraints.js +72 -0
- package/dist/deferred.js +25 -0
- package/dist/dev.d.ts +1 -4
- package/dist/dev.js +27 -0
- package/dist/engine/LayerPlan.d.ts +1 -96
- package/dist/engine/LayerPlan.js +606 -0
- package/dist/engine/OperationPlan.d.ts +4 -92
- package/dist/engine/OperationPlan.js +2636 -0
- package/dist/engine/OutputPlan.d.ts +0 -12
- package/dist/engine/OutputPlan.js +1065 -0
- package/dist/engine/StepTracker.d.ts +1 -95
- package/dist/engine/StepTracker.js +579 -0
- package/dist/engine/executeBucket.d.ts +5 -7
- package/dist/engine/executeBucket.js +1083 -0
- package/dist/engine/executeOutputPlan.d.ts +0 -53
- package/dist/engine/executeOutputPlan.js +27 -0
- package/dist/engine/lib/withGlobalLayerPlan.d.ts +2 -0
- package/dist/engine/lib/withGlobalLayerPlan.js +40 -0
- package/dist/engine/lock.d.ts +4 -0
- package/dist/engine/lock.js +82 -0
- package/dist/envelop.js +73 -5
- package/dist/error.d.ts +8 -52
- package/dist/error.js +73 -0
- package/dist/establishOperationPlan.js +186 -0
- package/dist/execute.d.ts +5 -4
- package/dist/execute.js +76 -0
- package/dist/exportAs.d.ts +1 -18
- package/dist/exportAs.js +57 -0
- package/dist/global.js +13 -0
- package/dist/grafastGraphql.js +133 -0
- package/dist/grafastPrint.d.ts +3 -0
- package/dist/grafastPrint.js +239 -0
- package/dist/graphqlCollectFields.d.ts +1 -34
- package/dist/graphqlCollectFields.js +217 -0
- package/dist/graphqlMergeSelectionSets.js +60 -0
- package/dist/index.d.ts +165 -4
- package/dist/index.js +297 -499
- package/dist/input.d.ts +1 -9
- package/dist/input.js +159 -0
- package/dist/inspect.d.ts +2 -1
- package/dist/inspect.js +20 -0
- package/dist/interfaces.d.ts +68 -176
- package/dist/interfaces.js +82 -0
- package/dist/makeGrafastSchema.d.ts +5 -2
- package/dist/makeGrafastSchema.js +360 -0
- package/dist/mermaid.d.ts +0 -17
- package/dist/mermaid.js +354 -7
- package/dist/operationPlan-input.js +449 -0
- package/dist/planJSONInterfaces.d.ts +4 -0
- package/dist/planJSONInterfaces.js +3 -0
- package/dist/polymorphic.js +73 -0
- package/dist/prepare.d.ts +1 -7
- package/dist/prepare.js +771 -0
- package/dist/step.d.ts +41 -83
- package/dist/step.js +423 -0
- package/dist/steps/__flag.d.ts +64 -0
- package/dist/steps/__flag.js +258 -0
- package/dist/steps/__inputDynamicScalar.d.ts +2 -2
- package/dist/steps/__inputDynamicScalar.js +125 -0
- package/dist/steps/__inputList.js +110 -0
- package/dist/steps/__inputObject.d.ts +2 -2
- package/dist/steps/__inputObject.js +128 -0
- package/dist/steps/__inputStaticLeaf.js +43 -0
- package/dist/steps/__item.d.ts +3 -5
- package/dist/steps/__item.js +56 -0
- package/dist/steps/__trackedValue.d.ts +3 -14
- package/dist/steps/__trackedValue.js +260 -0
- package/dist/steps/__value.js +47 -0
- package/dist/steps/access.d.ts +3 -5
- package/dist/steps/access.js +183 -0
- package/dist/steps/applyTransforms.d.ts +0 -23
- package/dist/steps/applyTransforms.js +171 -0
- package/dist/steps/condition.d.ts +31 -0
- package/dist/steps/condition.js +94 -0
- package/dist/steps/connection.d.ts +24 -13
- package/dist/steps/connection.js +352 -0
- package/dist/steps/constant.d.ts +4 -2
- package/dist/steps/constant.js +84 -0
- package/dist/steps/each.js +64 -0
- package/dist/steps/error.d.ts +2 -2
- package/dist/steps/error.js +33 -0
- package/dist/steps/filter.js +32 -0
- package/dist/steps/first.d.ts +4 -4
- package/dist/steps/first.js +44 -0
- package/dist/steps/graphqlResolver.d.ts +2 -75
- package/dist/steps/graphqlResolver.js +286 -0
- package/dist/steps/groupBy.js +40 -0
- package/dist/steps/index.d.ts +9 -2
- package/dist/steps/index.js +147 -0
- package/dist/steps/lambda.d.ts +2 -2
- package/dist/steps/lambda.js +63 -0
- package/dist/steps/last.d.ts +3 -3
- package/dist/steps/last.js +41 -0
- package/dist/steps/list.d.ts +5 -3
- package/dist/steps/list.js +77 -0
- package/dist/steps/listTransform.d.ts +5 -11
- package/dist/steps/listTransform.js +209 -0
- package/dist/steps/listen.d.ts +2 -5
- package/dist/steps/listen.js +59 -0
- package/dist/steps/load.d.ts +38 -25
- package/dist/steps/load.js +337 -0
- package/dist/steps/node.d.ts +9 -8
- package/dist/steps/node.js +112 -0
- package/dist/steps/object.d.ts +13 -14
- package/dist/steps/object.js +191 -0
- package/dist/steps/partitionByIndex.js +86 -0
- package/dist/steps/polymorphicBranch.d.ts +27 -0
- package/dist/steps/polymorphicBranch.js +62 -0
- package/dist/steps/proxy.d.ts +3 -4
- package/dist/steps/proxy.js +117 -0
- package/dist/steps/remapKeys.d.ts +3 -3
- package/dist/steps/remapKeys.js +86 -0
- package/dist/steps/reverse.d.ts +3 -3
- package/dist/steps/reverse.js +55 -0
- package/dist/steps/setter.js +28 -0
- package/dist/steps/sideEffect.d.ts +29 -0
- package/dist/steps/sideEffect.js +40 -0
- package/dist/stringifyPayload.js +59 -0
- package/dist/stripAnsi.js +14 -0
- package/dist/subscribe.d.ts +7 -1
- package/dist/subscribe.js +10 -0
- package/dist/thereCanBeOnlyOne.js +21 -0
- package/dist/timeSource.js +8 -0
- package/dist/utils.d.ts +1 -24
- package/dist/utils.js +739 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +6 -0
- package/package.json +11 -6
- package/dist/LICENSES.txt +0 -300
package/README.md
CHANGED
|
@@ -52,11 +52,10 @@ And please give some love to our featured sponsors 🤩:
|
|
|
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
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
|
-
<td align="center"><a href=""><img src="https://graphile.org/images/sponsors/chadf.png" width="90" height="90" alt="Chad Furman" /><br />Chad Furman</a> *</td>
|
|
56
|
-
</tr><tr>
|
|
57
55
|
<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>
|
|
58
|
-
|
|
59
|
-
<td align="center"><a href="https://
|
|
56
|
+
</tr><tr>
|
|
57
|
+
<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>
|
|
60
59
|
</tr></table>
|
|
61
60
|
|
|
62
61
|
<em>\* Sponsors the entire Graphile suite</em>
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hookArgs = void 0;
|
|
4
|
+
const config_js_1 = require("./config.js");
|
|
5
|
+
const interfaces_js_1 = require("./interfaces.js");
|
|
6
|
+
const utils_js_1 = require("./utils.js");
|
|
7
|
+
/**
|
|
8
|
+
* Applies Graphile Config hooks to your GraphQL request, e.g. to
|
|
9
|
+
* populate context or similar.
|
|
10
|
+
*
|
|
11
|
+
* @experimental
|
|
12
|
+
*/
|
|
13
|
+
function hookArgs(rawArgs, resolvedPreset, ctx) {
|
|
14
|
+
const args = rawArgs;
|
|
15
|
+
// Assert that args haven't already been hooked
|
|
16
|
+
if (args[interfaces_js_1.$$hooked]) {
|
|
17
|
+
throw new Error("Must not call hookArgs twice!");
|
|
18
|
+
}
|
|
19
|
+
args[interfaces_js_1.$$hooked] = true;
|
|
20
|
+
// Make context mutable
|
|
21
|
+
args.contextValue = Object.assign(Object.create(null), args.contextValue);
|
|
22
|
+
// finalize(args): args is deliberately shadowed
|
|
23
|
+
const finalize = (args) => {
|
|
24
|
+
const userContext = resolvedPreset.grafast?.context;
|
|
25
|
+
if (typeof userContext === "function") {
|
|
26
|
+
const result = userContext(ctx, args);
|
|
27
|
+
if ((0, utils_js_1.isPromiseLike)(result)) {
|
|
28
|
+
// Deliberately shadowed 'result'
|
|
29
|
+
return result.then((result) => {
|
|
30
|
+
Object.assign(args.contextValue, result);
|
|
31
|
+
return args;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
Object.assign(args.contextValue, result);
|
|
36
|
+
return args;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (typeof userContext === "object" && userContext !== null) {
|
|
40
|
+
Object.assign(args.contextValue, userContext);
|
|
41
|
+
return args;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return args;
|
|
45
|
+
}
|
|
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
|
+
}
|
|
59
|
+
return finalize(args);
|
|
60
|
+
}
|
|
61
|
+
exports.hookArgs = hookArgs;
|
|
62
|
+
//# sourceMappingURL=args.js.map
|
package/dist/assert.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Due to the following Jest issue, GraphQL's `instanceof Error` test
|
|
4
|
+
* cannot pass for Node assertions. So we have to define our own.
|
|
5
|
+
*
|
|
6
|
+
* https://github.com/facebook/jest/issues/2549
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.strictEqual = exports.ok = void 0;
|
|
10
|
+
/** Equivalent to `assert.ok(...)` */
|
|
11
|
+
function ok(val, message) {
|
|
12
|
+
if (!val) {
|
|
13
|
+
throw new Error(message);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.ok = ok;
|
|
17
|
+
/** Equivalent to `assert.strictEqual(...)` */
|
|
18
|
+
function strictEqual(actual, expected, message) {
|
|
19
|
+
if (actual !== expected) {
|
|
20
|
+
throw new Error(message + ` (${actual} !== ${expected})`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.strictEqual = strictEqual;
|
|
24
|
+
//# sourceMappingURL=assert.js.map
|
package/dist/bucket.d.ts
CHANGED
|
@@ -1,90 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import type { MetaByMetaKey } from "./engine/OperationPlan";
|
|
3
|
-
import type { ExecutionEventEmitter } from "./interfaces.js";
|
|
4
|
-
/**
|
|
5
|
-
* @internal
|
|
6
|
-
*/
|
|
7
|
-
export interface RequestTools {
|
|
8
|
-
/** The `timeSource.now()` at which the request started executing */
|
|
9
|
-
startTime: number;
|
|
10
|
-
/** The `timeSource.now()` at which the request should stop executing (if a timeout was configured) */
|
|
11
|
-
stopTime: number | null;
|
|
12
|
-
readonly eventEmitter: ExecutionEventEmitter | undefined;
|
|
13
|
-
/**
|
|
14
|
-
* If we're running inside GraphQL then we should not serialize scalars,
|
|
15
|
-
* otherwise we'll face the double-serialization problem.
|
|
16
|
-
*/
|
|
17
|
-
insideGraphQL: false;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* A "bucket" is where the results from plans are stored so that other plans
|
|
21
|
-
* can retrieve them, it may take on different forms depending on the mode of
|
|
22
|
-
* execution. A "LayerPlan" is used to both identify the bucket and to specify
|
|
23
|
-
* why it exists and how it behaves.
|
|
24
|
-
*
|
|
25
|
-
* Every `ExecutableStep` belongs to exactly one LayerPlan (and thus bucket),
|
|
26
|
-
* specified by `plan.layerPlan`.
|
|
27
|
-
*
|
|
28
|
-
* @internal
|
|
29
|
-
*/
|
|
30
|
-
export interface Bucket {
|
|
31
|
-
/**
|
|
32
|
-
* The LayerPlan definition this bucket adheres to
|
|
33
|
-
*/
|
|
34
|
-
layerPlan: LayerPlan;
|
|
35
|
-
/**
|
|
36
|
-
* How many entries are there in the bucket?
|
|
37
|
-
*/
|
|
38
|
-
size: number;
|
|
39
|
-
/**
|
|
40
|
-
* The polymorphic path through which each of the entries (respectively) has
|
|
41
|
-
* travelled. This influences the steps that will be executed using the
|
|
42
|
-
* related inputs.
|
|
43
|
-
*/
|
|
44
|
-
polymorphicPathList: readonly (string | null)[];
|
|
45
|
-
/**
|
|
46
|
-
* These are the iterators the bucket (or its descendents, without crossing a
|
|
47
|
-
* stream/defer boundary) have created (if any). Each of these must either be
|
|
48
|
-
* processed via `processRoot`, or must be manually released (via
|
|
49
|
-
* `releaseUnusedIterators`) otherwise a memory leak could occur.
|
|
50
|
-
*/
|
|
51
|
-
iterators: Array<Set<AsyncIterator<any> | Iterator<any>>>;
|
|
52
|
-
/**
|
|
53
|
-
* `metaByMetaKey` belongs to the bucket rather than the request context
|
|
54
|
-
* because mutations and subscriptions shouldn't re-use caches.
|
|
55
|
-
*
|
|
56
|
-
* TODO: `inheritMeta: boolean`?
|
|
57
|
-
*/
|
|
58
|
-
metaByMetaKey: MetaByMetaKey;
|
|
59
|
-
/**
|
|
60
|
-
* Every entry in the store is a list with the same length as the bucket has
|
|
61
|
-
* `size`.
|
|
62
|
-
*
|
|
63
|
-
* The entry for '-1' is the request indexes, so we can associate the results
|
|
64
|
-
* back to the request that triggered them.
|
|
65
|
-
*/
|
|
66
|
-
store: Map<number, any[]>;
|
|
67
|
-
/**
|
|
68
|
-
* Set this true when the bucket is fully executed.
|
|
69
|
-
*
|
|
70
|
-
* Initialize it to false.
|
|
71
|
-
*/
|
|
72
|
-
isComplete: boolean;
|
|
73
|
-
/**
|
|
74
|
-
* If an error occurred at any stage we need to drop down to more careful
|
|
75
|
-
* (and slower) handling.
|
|
76
|
-
*
|
|
77
|
-
* Initialize it to false.
|
|
78
|
-
*/
|
|
79
|
-
hasErrors: boolean;
|
|
80
|
-
/**
|
|
81
|
-
* The child buckets of this bucket.
|
|
82
|
-
*/
|
|
83
|
-
children: {
|
|
84
|
-
[layerPlanId: number]: {
|
|
85
|
-
bucket: Bucket;
|
|
86
|
-
map: Map<number, number | number[]>;
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
}
|
|
1
|
+
export {};
|
|
90
2
|
//# sourceMappingURL=bucket.d.ts.map
|
package/dist/bucket.js
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hook = exports.withHooks = exports.withGraphileConfig = exports.NULL_PRESET = void 0;
|
|
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
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// PERF: optimise constraint matching, e.g. by collapsing redundant constraints
|
|
3
|
+
// and then compiling (JIT-style) remaining constraints into a function using
|
|
4
|
+
// tamedevil
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.matchesConstraints = void 0;
|
|
7
|
+
function valueAtPath(object, path) {
|
|
8
|
+
let value = object;
|
|
9
|
+
for (let i = 0, l = path.length; i < l; i++) {
|
|
10
|
+
const key = path[i];
|
|
11
|
+
const expectArray = typeof key === "number";
|
|
12
|
+
const isArray = Array.isArray(value);
|
|
13
|
+
if (expectArray !== isArray) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
if (value == null) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
value = value[key];
|
|
21
|
+
if (typeof value === "undefined") {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Implements the `MatchesConstraint` algorithm.
|
|
30
|
+
*/
|
|
31
|
+
function matchesConstraint(constraint, object) {
|
|
32
|
+
const value = valueAtPath(object, constraint.path);
|
|
33
|
+
switch (constraint.type) {
|
|
34
|
+
case "length": {
|
|
35
|
+
return Array.isArray(value) && value.length === constraint.expectedLength;
|
|
36
|
+
}
|
|
37
|
+
case "exists": {
|
|
38
|
+
return (value !== undefined) === constraint.exists;
|
|
39
|
+
}
|
|
40
|
+
case "equal": {
|
|
41
|
+
return (value === constraint.expectedValue) === constraint.pass;
|
|
42
|
+
}
|
|
43
|
+
case "value": {
|
|
44
|
+
return value === constraint.value;
|
|
45
|
+
}
|
|
46
|
+
case "isEmpty": {
|
|
47
|
+
const isEmpty = typeof value === "object" &&
|
|
48
|
+
value !== null &&
|
|
49
|
+
Object.keys(value).length === 0;
|
|
50
|
+
return isEmpty === constraint.isEmpty;
|
|
51
|
+
}
|
|
52
|
+
default: {
|
|
53
|
+
const never = constraint;
|
|
54
|
+
throw new Error(`Unsupported constraint type '${never.type}'`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Implements the `MatchesConstraints` algorithm.
|
|
60
|
+
*/
|
|
61
|
+
function matchesConstraints(constraints, object) {
|
|
62
|
+
// In my testing, verbose loops are still about 20% faster than for...of
|
|
63
|
+
for (let i = 0, l = constraints.length; i < l; i++) {
|
|
64
|
+
const constraint = constraints[i];
|
|
65
|
+
if (!matchesConstraint(constraint, object)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
exports.matchesConstraints = matchesConstraints;
|
|
72
|
+
//# sourceMappingURL=constraints.js.map
|
package/dist/deferred.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defer = void 0;
|
|
4
|
+
function NOOP() { }
|
|
5
|
+
/**
|
|
6
|
+
* Returns a promise that can be `.resolve()`-ed or `.reject()`-ed at a later
|
|
7
|
+
* time.
|
|
8
|
+
*/
|
|
9
|
+
function defer() {
|
|
10
|
+
let resolve;
|
|
11
|
+
let reject;
|
|
12
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
13
|
+
resolve = _resolve;
|
|
14
|
+
reject = _reject;
|
|
15
|
+
});
|
|
16
|
+
promise.resolve = resolve;
|
|
17
|
+
promise.reject = reject;
|
|
18
|
+
// PERF: this is to avoid unhandledPromiseRejection errors; generally
|
|
19
|
+
// deferred errors are handled at a later time (or can be safely ignored if
|
|
20
|
+
// another error wins). Maybe there's a better way?
|
|
21
|
+
promise.then(null, NOOP);
|
|
22
|
+
return promise;
|
|
23
|
+
}
|
|
24
|
+
exports.defer = defer;
|
|
25
|
+
//# sourceMappingURL=deferred.js.map
|
package/dist/dev.d.ts
CHANGED
package/dist/dev.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.noop = exports.isTest = exports.isDev = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
const graphileEnv = typeof process !== "undefined" ? process.env.GRAPHILE_ENV : undefined;
|
|
8
|
+
const nodeEnv = typeof process !== "undefined" ? process.env.NODE_ENV : undefined;
|
|
9
|
+
const mode = graphileEnv !== undefined ? graphileEnv : nodeEnv;
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
exports.isDev = mode === "development" || mode === "test";
|
|
14
|
+
exports.isTest = mode === "test";
|
|
15
|
+
function noop() { }
|
|
16
|
+
exports.noop = noop;
|
|
17
|
+
if (typeof process !== "undefined" &&
|
|
18
|
+
typeof graphileEnv === "undefined" &&
|
|
19
|
+
typeof nodeEnv === "undefined") {
|
|
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
|
+
}
|
|
22
|
+
else if (exports.isDev && !exports.isTest) {
|
|
23
|
+
console.warn(`Grafast is running in development mode due to \`${graphileEnv !== undefined
|
|
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.`);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Bucket } from "../bucket.js";
|
|
2
|
-
import type { ExecutableStep
|
|
2
|
+
import type { ExecutableStep } from "../step";
|
|
3
3
|
import type { OperationPlan } from "./OperationPlan";
|
|
4
4
|
/** Non-branching, non-deferred */
|
|
5
5
|
export interface LayerPlanReasonRoot {
|
|
@@ -71,43 +71,6 @@ export type HasParent<A extends LayerPlanReason> = A extends any ? A extends {
|
|
|
71
71
|
parentStep: ExecutableStep;
|
|
72
72
|
} ? A : never : never;
|
|
73
73
|
export type LayerPlanReasonsWithParentStep = HasParent<LayerPlanReason>;
|
|
74
|
-
/** @internal */
|
|
75
|
-
export interface LayerPlanPhase {
|
|
76
|
-
/**
|
|
77
|
-
* If true, we should check before the layer plan executes to see if the
|
|
78
|
-
* execution has already timed out.
|
|
79
|
-
*
|
|
80
|
-
* @see {@link RequestTools.stopTime}
|
|
81
|
-
*/
|
|
82
|
-
checkTimeout: boolean;
|
|
83
|
-
/**
|
|
84
|
-
* A list of steps that can be ran in parallel at this point, since all
|
|
85
|
-
* their previous dependencies have already been satisfied.
|
|
86
|
-
*/
|
|
87
|
-
normalSteps: Array<{
|
|
88
|
-
step: ExecutableStep;
|
|
89
|
-
}> | undefined;
|
|
90
|
-
/**
|
|
91
|
-
* A list of 'isSyncAndSafe' steps with unbatchedExecute methods that can be
|
|
92
|
-
* ran once the `normalSteps` have completed; they must only depend on steps
|
|
93
|
-
* that have already been executed before them (including previous
|
|
94
|
-
* unbatchedSyncAndSafeSteps in the same list).
|
|
95
|
-
*/
|
|
96
|
-
unbatchedSyncAndSafeSteps: Array<{
|
|
97
|
-
step: UnbatchedExecutableStep;
|
|
98
|
-
/**
|
|
99
|
-
* Store the result of the step here if you want - useful to avoid lookups
|
|
100
|
-
* and when there's no storage. HIGHLY VOLATILE, will not survive a tick!
|
|
101
|
-
*/
|
|
102
|
-
scratchpad: any;
|
|
103
|
-
}> | undefined;
|
|
104
|
-
/**
|
|
105
|
-
* Optimization - a digest of all steps in normalSteps and unbatchedSyncAndSafeSteps
|
|
106
|
-
*
|
|
107
|
-
* @internal
|
|
108
|
-
*/
|
|
109
|
-
_allSteps: ExecutableStep[];
|
|
110
|
-
}
|
|
111
74
|
/**
|
|
112
75
|
* A LayerPlan represents (via "reason") either the root (root), when something
|
|
113
76
|
* happens at a later time (mutationField, defer), when plurality changes
|
|
@@ -138,58 +101,6 @@ export declare class LayerPlan<TReason extends LayerPlanReason = LayerPlanReason
|
|
|
138
101
|
parentLayerPlan: LayerPlan | null;
|
|
139
102
|
readonly reason: TReason;
|
|
140
103
|
id: number;
|
|
141
|
-
/**
|
|
142
|
-
* Every layer plan has a "root step" that shapes the value the layer
|
|
143
|
-
* returns. Note that this step may be dependent on other steps included in
|
|
144
|
-
* the LayerPlan, or could be provided externally.
|
|
145
|
-
*
|
|
146
|
-
* The root step is different for different layer step reasons:
|
|
147
|
-
*
|
|
148
|
-
* - root: the `operationPlan.rootValue`
|
|
149
|
-
* - listItem: the `__ItemStep`
|
|
150
|
-
* - stream: also the `__ItemStep`
|
|
151
|
-
* - subscription: also the `__ItemStep`
|
|
152
|
-
* - mutationField: the result plan of the mutation field
|
|
153
|
-
* - defer: the parent layer's rootStep (defer always results in an object, unless an error occurs)
|
|
154
|
-
* - polymorphic: the plan for the particular type
|
|
155
|
-
* - subroutine: the result (returned) plan of the subroutine
|
|
156
|
-
*
|
|
157
|
-
* @internal
|
|
158
|
-
*/
|
|
159
|
-
readonly rootStep: ExecutableStep | null;
|
|
160
|
-
/**
|
|
161
|
-
* Which plans the results for which are available in a parent bucket need to
|
|
162
|
-
* be "copied across" to this bucket because plans in this bucket still
|
|
163
|
-
* reference them?
|
|
164
|
-
*
|
|
165
|
-
* @internal
|
|
166
|
-
*/
|
|
167
|
-
copyStepIds: number[];
|
|
168
|
-
/** @internal */
|
|
169
|
-
children: LayerPlan[];
|
|
170
|
-
/** @internal */
|
|
171
|
-
steps: ExecutableStep[];
|
|
172
|
-
/** @internal */
|
|
173
|
-
pendingSteps: ExecutableStep[];
|
|
174
|
-
/**
|
|
175
|
-
* Describes the order in which the steps within this LayerPlan are executed.
|
|
176
|
-
*
|
|
177
|
-
* Special attention must be paid to steps that have side effects.
|
|
178
|
-
*
|
|
179
|
-
* @internal
|
|
180
|
-
*/
|
|
181
|
-
phases: Array<LayerPlanPhase>;
|
|
182
|
-
/**
|
|
183
|
-
* The list of layerPlans that steps added to this LayerPlan may depend upon.
|
|
184
|
-
* Note this includes self, so it has one more entry than `depth`.
|
|
185
|
-
*
|
|
186
|
-
* ```
|
|
187
|
-
* this.ancestry[this.depth] === this;
|
|
188
|
-
* ```
|
|
189
|
-
*
|
|
190
|
-
* @internal
|
|
191
|
-
*/
|
|
192
|
-
ancestry: LayerPlan[];
|
|
193
104
|
/** How "deep" this layer plan is (how many ancestors it has). The root layer plan has a depth of 0. */
|
|
194
105
|
depth: number;
|
|
195
106
|
/** The depth at which a "defer boundary" occurs (OperationPlan.getPeers cannot pass a defer boundary), or 0. */
|
|
@@ -203,12 +114,6 @@ export declare class LayerPlan<TReason extends LayerPlanReason = LayerPlanReason
|
|
|
203
114
|
toString(): string;
|
|
204
115
|
print(depth?: number): string;
|
|
205
116
|
setRootStep($root: ExecutableStep): void;
|
|
206
|
-
/** @internal Use plan.getStep(id) instead. */
|
|
207
|
-
getStep(id: number, requestingStep: ExecutableStep): ExecutableStep;
|
|
208
|
-
/** @internal */
|
|
209
|
-
_addStep(step: ExecutableStep): number;
|
|
210
|
-
/** @internal */
|
|
211
|
-
_addModifierStep(step: ModifierStep<any>): string;
|
|
212
117
|
finalize(): void;
|
|
213
118
|
newBucket(parentBucket: Bucket): Bucket | null;
|
|
214
119
|
}
|