grafast 0.0.1-alpha.9 → 0.0.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +15 -17
- package/README.md +138 -1
- package/dist/LICENSES.txt +1 -1
- package/dist/args.d.ts +7 -1
- package/dist/assert.d.ts +2 -0
- package/dist/bucket.d.ts +66 -1
- package/dist/constraints.d.ts +31 -0
- package/dist/deferred.d.ts +7 -0
- package/dist/dev.d.ts +3 -0
- package/dist/engine/LayerPlan.d.ts +131 -0
- package/dist/engine/OperationPlan.d.ts +151 -0
- package/dist/engine/OutputPlan.d.ts +105 -1
- package/dist/engine/StepTracker.d.ts +56 -1
- package/dist/engine/executeBucket.d.ts +4 -1
- package/dist/engine/executeOutputPlan.d.ts +42 -1
- package/dist/envelop.d.ts +12 -0
- package/dist/envelop.js +2 -51
- package/dist/error.d.ts +23 -0
- package/dist/establishOperationPlan.d.ts +10 -31
- package/dist/execute.d.ts +8 -0
- package/dist/exportAs.d.ts +14 -0
- package/dist/grafastGraphql.d.ts +8 -3
- package/dist/grafastPrint.d.ts +8 -0
- package/dist/graphqlCollectFields.d.ts +22 -0
- package/dist/graphqlMergeSelectionSets.d.ts +4 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +387 -53
- package/dist/input.d.ts +8 -1
- package/dist/interfaces.d.ts +356 -59
- package/dist/makeGrafastSchema.d.ts +30 -3
- package/dist/mermaid.d.ts +28 -0
- package/dist/polymorphic.d.ts +8 -0
- package/dist/prepare.d.ts +16 -2
- package/dist/step.d.ts +183 -0
- package/dist/steps/__inputDynamicScalar.d.ts +3 -0
- package/dist/steps/__inputList.d.ts +3 -0
- package/dist/steps/__inputObject.d.ts +3 -0
- package/dist/steps/__inputStaticLeaf.d.ts +5 -0
- package/dist/steps/__item.d.ts +8 -0
- package/dist/steps/__trackedValue.d.ts +74 -0
- package/dist/steps/__value.d.ts +5 -0
- package/dist/steps/access.d.ts +20 -0
- package/dist/steps/{deepEval.d.ts → applyTransforms.d.ts} +16 -3
- package/dist/steps/connection.d.ts +49 -0
- package/dist/steps/constant.d.ts +11 -3
- package/dist/steps/each.d.ts +3 -0
- package/dist/steps/filter.d.ts +4 -0
- package/dist/steps/first.d.ts +4 -0
- package/dist/steps/graphqlResolver.d.ts +18 -0
- package/dist/steps/groupBy.d.ts +6 -0
- package/dist/steps/index.d.ts +6 -2
- package/dist/steps/lambda.d.ts +8 -0
- package/dist/steps/last.d.ts +4 -0
- package/dist/steps/list.d.ts +7 -0
- package/dist/steps/listTransform.d.ts +21 -0
- package/dist/steps/listen.d.ts +16 -0
- package/dist/steps/load.d.ts +13 -0
- package/dist/steps/node.d.ts +20 -12
- package/dist/steps/object.d.ts +15 -0
- package/dist/steps/partitionByIndex.d.ts +35 -0
- package/dist/steps/proxy.d.ts +11 -0
- package/dist/steps/remapKeys.d.ts +8 -0
- package/dist/steps/reverse.d.ts +9 -0
- package/dist/subscribe.d.ts +4 -0
- package/dist/utils.d.ts +113 -5
- package/dist/version.d.ts +2 -0
- package/fwd/graphql/index.d.ts +1 -0
- package/fwd/graphql/index.js +1 -0
- package/package.json +14 -6
package/LICENSE.md
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright ©
|
|
3
|
+
Copyright © `2023` Benjie Gillam
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the “Software”), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
unknown. Usage of this software is entirely at your own risk.
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
11
14
|
|
|
12
15
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
13
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
SOFTWARE.
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
19
21
|
|
|
20
22
|
---
|
|
21
23
|
|
|
22
|
-
The contents of the `node_modules` directory are produced from external
|
|
23
|
-
libraries; their license terms will likely differ from the terms above - you
|
|
24
|
-
should review them also.
|
|
25
|
-
|
|
26
24
|
Licenses of bundled dependencies (if any) are detailed in dist/LICENSES.txt
|
package/README.md
CHANGED
|
@@ -1,3 +1,140 @@
|
|
|
1
1
|
# Gra*fast*
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/sponsors/benjie)
|
|
4
|
+
[](https://patreon.com/benjie)
|
|
5
|
+
[](http://discord.gg/graphile)
|
|
6
|
+
[](https://twitter.com/GrafastHQ)
|
|
7
|
+
|
|
8
|
+
_**The next-generation planning and execution engine for GraphQL**_
|
|
9
|
+
|
|
10
|
+
**Documentation**: https://grafast.org/grafast/
|
|
11
|
+
|
|
12
|
+
## About
|
|
13
|
+
|
|
14
|
+
Gra*fast* understands GraphQL and (with your help) your business logic; this
|
|
15
|
+
allows it to orchestrate a GraphQL request's data requirements in an extremely
|
|
16
|
+
efficient manner, leading to excellent performance, reduced server load, and
|
|
17
|
+
happier customers.
|
|
18
|
+
|
|
19
|
+
This increased efficiency is achieved by leveraging the declarative nature of
|
|
20
|
+
GraphQL and deeper integration with your existing Node.js or remote business
|
|
21
|
+
logic via "plan resolvers" attached to the fields of your schema. These plan
|
|
22
|
+
resolvers detail the abstract steps necessary to execute the given field, these
|
|
23
|
+
steps are then combined with the steps from all other fields in the request into
|
|
24
|
+
an operation plan. This operation plan can then be rewritten and optimized
|
|
25
|
+
before execution, and can often be re-used for similar queries in the future.
|
|
26
|
+
|
|
27
|
+
In addition to "plan resolvers," Gra*fast* is also backwards compatible with
|
|
28
|
+
traditional resolvers - in fact most existing GraphQL.js schemas should already
|
|
29
|
+
be executable via Gra*fast* (and doing so should result in a small speed
|
|
30
|
+
improvement). Replace your resolvers with Gra*fast* plan resolvers to see the
|
|
31
|
+
real efficiency gains!
|
|
32
|
+
|
|
33
|
+
Gra*fast* schemas can be built using the same techniques other GraphQL.js
|
|
34
|
+
schemas can be built - Gra*fast* schemas _are_ GraphQL.js schemas - for example
|
|
35
|
+
schema-first, code-first or auto-generated. If you maintain a library that
|
|
36
|
+
builds GraphQL schemas, get in touch - we'd love to help you integrate Gra*fast*
|
|
37
|
+
with it!
|
|
38
|
+
|
|
39
|
+
<!-- SPONSORS_BEGIN -->
|
|
40
|
+
|
|
41
|
+
## Crowd-funded open-source software
|
|
42
|
+
|
|
43
|
+
To help us develop this software sustainably under the MIT license, we ask all
|
|
44
|
+
individuals and businesses that use it to help support its ongoing maintenance
|
|
45
|
+
and development via sponsorship.
|
|
46
|
+
|
|
47
|
+
### [Click here to find out more about sponsors and sponsorship.](https://www.graphile.org/sponsor/)
|
|
48
|
+
|
|
49
|
+
And please give some love to our featured sponsors 🤩:
|
|
50
|
+
|
|
51
|
+
<table><tr>
|
|
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
|
+
<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://qwick.com/"><img src="https://graphile.org/images/sponsors/qwick.png" width="90" height="90" alt="Qwick" /><br />Qwick</a> *</td>
|
|
55
|
+
<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>
|
|
56
|
+
</tr><tr>
|
|
57
|
+
<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>
|
|
58
|
+
<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>
|
|
59
|
+
<td align="center"><a href="https://www.accenture.com/"><img src="https://graphile.org/images/sponsors/accenture.svg" width="90" height="90" alt="Accenture" /><br />Accenture</a> *</td>
|
|
60
|
+
</tr></table>
|
|
61
|
+
|
|
62
|
+
<em>\* Sponsors the entire Graphile suite</em>
|
|
63
|
+
|
|
64
|
+
<!-- SPONSORS_END -->
|
|
65
|
+
|
|
66
|
+
## Overview
|
|
67
|
+
|
|
68
|
+
Gra*fast* is an alternative GraphQL execution engine for JavaScript; you can use
|
|
69
|
+
it as a drop-in replacement for the "execute" method of GraphQL.js. Any GraphQL
|
|
70
|
+
server that allows replacement of the `execute` method (which includes any
|
|
71
|
+
server that fully supports [envelop][]) can support Gra*fast*.
|
|
72
|
+
|
|
73
|
+
When Gra*fast* sees a GraphQL request for the first time it will "plan" the
|
|
74
|
+
request: figuring out the data requirements, the steps that need to be taken,
|
|
75
|
+
and how to write the results to the response. This "first draft" plan will be
|
|
76
|
+
optimised and rewritten to give the best achievable performance (for example
|
|
77
|
+
removing redundant or duplicate processing steps, rewriting and merging
|
|
78
|
+
processing steps, etc). Finally, the plan will be executed, and the response
|
|
79
|
+
returned to the client. Future requests that are compatible with this plan can
|
|
80
|
+
be executed immediately without a need to re-plan.
|
|
81
|
+
|
|
82
|
+
## Requirements
|
|
83
|
+
|
|
84
|
+
Gra*fast* should work with any GraphQL.js schema that matches the following
|
|
85
|
+
requirements:
|
|
86
|
+
|
|
87
|
+
- GraphQL.js v16+
|
|
88
|
+
- you must not override the default GraphQL field resolver (TODO: support this)
|
|
89
|
+
- for every request:
|
|
90
|
+
- `context` must be an object (anything suitable to be used as the key to a
|
|
91
|
+
`WeakMap`); if you do not need a context then `{}` is perfectly acceptable
|
|
92
|
+
- `rootValue` must be an object or `null`/`undefined`
|
|
93
|
+
- resolver limitations:
|
|
94
|
+
- only explicit field resolvers (baked into the GraphQL schema) are supported,
|
|
95
|
+
i.e. resolvers passed via `rootValue` are not (currently) supported
|
|
96
|
+
- our support for traditional GraphQL resolvers does not have full parity with
|
|
97
|
+
the fourth argument to `resolve` (aka `resolveInfo`) - in particular, the
|
|
98
|
+
`resolveInfo.path` property is not currently supported.
|
|
99
|
+
|
|
100
|
+
If you find a GraphQL schema that matches these requirements and doesn't work
|
|
101
|
+
with Gra*fast*, please file an issue.
|
|
102
|
+
|
|
103
|
+
## Advice
|
|
104
|
+
|
|
105
|
+
To reap the most benefit from using Gra*fast*, you want as little to change
|
|
106
|
+
between executions as possible. In particular, this means you should:
|
|
107
|
+
|
|
108
|
+
- **CRITICAL**: Cache (e.g. with a LRU cache) the parsed GraphQL document, so
|
|
109
|
+
the same AST can be reused over and over for the same document
|
|
110
|
+
- `grafserv` handles this for you
|
|
111
|
+
- Envelop users can use `@envelop/parser-cache` for this
|
|
112
|
+
- Don't use `rootValue` (Do you really need it? Use `context` instead.)
|
|
113
|
+
- Where possible, memoize the variables object (e.g. using a cache over
|
|
114
|
+
`canonicalJSONStringify(variables)`) so the same variables results in the same
|
|
115
|
+
object in memory
|
|
116
|
+
- Cache (e.g. with a LRU cache) the GraphQL `context` object, so the same
|
|
117
|
+
context can be reused over and over for the same user
|
|
118
|
+
- This is less important - feel free to break it if you need to, for example
|
|
119
|
+
if you're still using DataLoaders during migration
|
|
120
|
+
|
|
121
|
+
## Usage
|
|
122
|
+
|
|
123
|
+
Where you would use `graphql` from the `graphql` module, use `grafast` instead:
|
|
124
|
+
|
|
125
|
+
```diff
|
|
126
|
+
-import { graphql } from "graphql";
|
|
127
|
+
+import { grafast as graphql } from "grafast";
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Where you would use `execute` from the `graphql` module, use `grafast`'s
|
|
131
|
+
`execute` instead:
|
|
132
|
+
|
|
133
|
+
```diff
|
|
134
|
+
-import { execute } from "graphql";
|
|
135
|
+
+import { execute } from "grafast";
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Full documentation
|
|
139
|
+
|
|
140
|
+
https://grafast.org/grafast/
|
package/dist/LICENSES.txt
CHANGED
|
@@ -254,7 +254,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
254
254
|
|
|
255
255
|
|
|
256
256
|
--------------------------------------------------------------------------------
|
|
257
|
-
tamedevil v0.0.0-
|
|
257
|
+
tamedevil v0.0.0-beta.1 - Benjie Gillam <benjie@jemjie.com>
|
|
258
258
|
git+https://github.com/graphile/heart.git
|
|
259
259
|
--------------------------------------------------------------------------------
|
|
260
260
|
|
package/dist/args.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import type { ExecutionArgs } from "graphql";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Applies Graphile Config hooks to your GraphQL request, e.g. to
|
|
4
|
+
* populate context or similar.
|
|
5
|
+
*
|
|
6
|
+
* @experimental
|
|
7
|
+
*/
|
|
8
|
+
export declare function hookArgs(rawArgs: ExecutionArgs, resolvedPreset: GraphileConfig.ResolvedPreset, ctx: Partial<Grafast.RequestContext>): Grafast.ExecutionArgs | PromiseLike<Grafast.ExecutionArgs>;
|
|
3
9
|
//# sourceMappingURL=args.d.ts.map
|
package/dist/assert.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Equivalent to `assert.ok(...)` */
|
|
1
2
|
export declare function ok(val: any, message: string): asserts val;
|
|
3
|
+
/** Equivalent to `assert.strictEqual(...)` */
|
|
2
4
|
export declare function strictEqual<T>(actual: any, expected: T, message: string): asserts actual is T;
|
|
3
5
|
//# sourceMappingURL=assert.d.ts.map
|
package/dist/bucket.d.ts
CHANGED
|
@@ -1,20 +1,85 @@
|
|
|
1
1
|
import type { LayerPlan } from "./engine/LayerPlan";
|
|
2
2
|
import type { MetaByMetaKey } from "./engine/OperationPlan";
|
|
3
3
|
import type { ExecutionEventEmitter } from "./interfaces.js";
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
4
7
|
export interface RequestTools {
|
|
8
|
+
/** The `timeSource.now()` at which the request started executing */
|
|
5
9
|
startTime: number;
|
|
10
|
+
/** The `timeSource.now()` at which the request should stop executing (if a timeout was configured) */
|
|
6
11
|
stopTime: number | null;
|
|
7
12
|
readonly eventEmitter: ExecutionEventEmitter | undefined;
|
|
8
|
-
|
|
13
|
+
/**
|
|
14
|
+
* If we're running inside GraphQL then we should not serialize scalars,
|
|
15
|
+
* otherwise we'll face the double-serialization problem.
|
|
16
|
+
*/
|
|
9
17
|
insideGraphQL: false;
|
|
10
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
|
+
*/
|
|
11
30
|
export interface Bucket {
|
|
31
|
+
/**
|
|
32
|
+
* The LayerPlan definition this bucket adheres to
|
|
33
|
+
*/
|
|
12
34
|
layerPlan: LayerPlan;
|
|
35
|
+
/**
|
|
36
|
+
* How many entries are there in the bucket?
|
|
37
|
+
*/
|
|
13
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
|
+
*/
|
|
14
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
|
+
*/
|
|
15
66
|
store: Map<number, any[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Set this true when the bucket is fully executed.
|
|
69
|
+
*
|
|
70
|
+
* Initialize it to false.
|
|
71
|
+
*/
|
|
16
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
|
+
*/
|
|
17
79
|
hasErrors: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* The child buckets of this bucket.
|
|
82
|
+
*/
|
|
18
83
|
children: {
|
|
19
84
|
[layerPlanId: number]: {
|
|
20
85
|
bucket: Bucket;
|
package/dist/constraints.d.ts
CHANGED
|
@@ -1,30 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asserts that a value strictly matches.
|
|
3
|
+
*/
|
|
1
4
|
interface ValueConstraint {
|
|
2
5
|
type: "value";
|
|
3
6
|
path: (string | number)[];
|
|
4
7
|
value: unknown;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Asserts that `(value === expectedValue)` is always equal to `pass`.
|
|
11
|
+
*/
|
|
6
12
|
interface EqualityConstraint {
|
|
7
13
|
type: "equal";
|
|
8
14
|
path: (string | number)[];
|
|
9
15
|
expectedValue: unknown;
|
|
10
16
|
pass: boolean;
|
|
11
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Asserts that the property at the given path exists.
|
|
20
|
+
*
|
|
21
|
+
* Let `tail` be the last entry in `path`, and `rest` be the rest of `path`.
|
|
22
|
+
* The value at path `rest` must be an object, and that object must have an
|
|
23
|
+
* attribute `tail` which is not `undefined`.
|
|
24
|
+
*/
|
|
12
25
|
interface ExistsConstraint {
|
|
13
26
|
type: "exists";
|
|
14
27
|
path: (string | number)[];
|
|
15
28
|
exists: boolean;
|
|
16
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* If `expectedLength` is null: asserts that there is no value at the given
|
|
32
|
+
* path.
|
|
33
|
+
*
|
|
34
|
+
* Otherwise: asserts that the value at the given path is an array containing
|
|
35
|
+
* `expectedLength` entries.
|
|
36
|
+
*/
|
|
17
37
|
interface LengthConstraint {
|
|
18
38
|
type: "length";
|
|
19
39
|
path: (string | number)[];
|
|
40
|
+
/**
|
|
41
|
+
* If this is null it implies that the array did not exist.
|
|
42
|
+
*/
|
|
20
43
|
expectedLength: number | null;
|
|
21
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Checks if the object at the given path matches the `isEmpty` property
|
|
47
|
+
* (implying no keys). Objects are empty if and only if they exist and have no
|
|
48
|
+
* keys.
|
|
49
|
+
*/
|
|
22
50
|
interface IsEmptyConstraint {
|
|
23
51
|
type: "isEmpty";
|
|
24
52
|
path: (string | number)[];
|
|
25
53
|
isEmpty: boolean;
|
|
26
54
|
}
|
|
27
55
|
export type Constraint = ValueConstraint | EqualityConstraint | ExistsConstraint | LengthConstraint | IsEmptyConstraint;
|
|
56
|
+
/**
|
|
57
|
+
* Implements the `MatchesConstraints` algorithm.
|
|
58
|
+
*/
|
|
28
59
|
export declare function matchesConstraints(constraints: Constraint[], object: unknown): boolean;
|
|
29
60
|
export {};
|
|
30
61
|
//# sourceMappingURL=constraints.d.ts.map
|
package/dist/deferred.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A promise that can be `.resolve()`-ed or `.reject()`-ed at a later time.
|
|
3
|
+
*/
|
|
1
4
|
export interface Deferred<T> extends PromiseLike<T> {
|
|
2
5
|
resolve: (input: T | PromiseLike<T>) => void;
|
|
3
6
|
reject: (error: Error) => void;
|
|
4
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Returns a promise that can be `.resolve()`-ed or `.reject()`-ed at a later
|
|
10
|
+
* time.
|
|
11
|
+
*/
|
|
5
12
|
export declare function defer<T = void>(): Deferred<T>;
|
|
6
13
|
//# sourceMappingURL=deferred.d.ts.map
|
package/dist/dev.d.ts
CHANGED
|
@@ -1,38 +1,64 @@
|
|
|
1
1
|
import type { Bucket } from "../bucket.js";
|
|
2
2
|
import type { ExecutableStep, ModifierStep, UnbatchedExecutableStep } from "../step";
|
|
3
3
|
import type { OperationPlan } from "./OperationPlan";
|
|
4
|
+
/** Non-branching, non-deferred */
|
|
4
5
|
export interface LayerPlanReasonRoot {
|
|
5
6
|
type: "root";
|
|
6
7
|
}
|
|
8
|
+
/** Non-branching, non-deferred */
|
|
7
9
|
export interface LayerPlanReasonNullableField {
|
|
8
10
|
type: "nullableBoundary";
|
|
11
|
+
/**
|
|
12
|
+
* Can be used such that the same LayerPlan can be used for two selection
|
|
13
|
+
* sets for the same parent plan. In this case an additional output plan
|
|
14
|
+
* would be added to the LayerPlan.
|
|
15
|
+
*
|
|
16
|
+
* Also needed for execution (see `executeBucket`).
|
|
17
|
+
*/
|
|
9
18
|
parentStep: ExecutableStep;
|
|
10
19
|
}
|
|
20
|
+
/** Non-branching, non-deferred */
|
|
11
21
|
export interface LayerPlanReasonListItem {
|
|
12
22
|
type: "listItem";
|
|
23
|
+
/**
|
|
24
|
+
* Can be used such that the same LayerPlan can be used for two lists for
|
|
25
|
+
* the same parent plan. In this case an additional output plan would be
|
|
26
|
+
* added to the LayerPlan.
|
|
27
|
+
*
|
|
28
|
+
* Also needed for execution (see `executeBucket`).
|
|
29
|
+
*/
|
|
13
30
|
parentStep: ExecutableStep;
|
|
31
|
+
/** If this listItem is to be streamed, the configuration for that streaming */
|
|
14
32
|
stream?: {
|
|
15
33
|
initialCount: number;
|
|
16
34
|
label?: string;
|
|
17
35
|
};
|
|
18
36
|
}
|
|
37
|
+
/** Non-branching, deferred */
|
|
19
38
|
export interface LayerPlanReasonSubscription {
|
|
20
39
|
type: "subscription";
|
|
21
40
|
}
|
|
41
|
+
/** Non-branching, deferred */
|
|
22
42
|
export interface LayerPlanReasonMutationField {
|
|
23
43
|
type: "mutationField";
|
|
24
44
|
mutationIndex: number;
|
|
25
45
|
}
|
|
46
|
+
/** Non-branching, deferred */
|
|
26
47
|
export interface LayerPlanReasonDefer {
|
|
27
48
|
type: "defer";
|
|
28
49
|
label?: string;
|
|
29
50
|
}
|
|
51
|
+
/** Branching, non-deferred */
|
|
30
52
|
export interface LayerPlanReasonPolymorphic {
|
|
31
53
|
type: "polymorphic";
|
|
32
54
|
typeNames: string[];
|
|
55
|
+
/**
|
|
56
|
+
* Needed for execution (see `executeBucket`).
|
|
57
|
+
*/
|
|
33
58
|
parentStep: ExecutableStep;
|
|
34
59
|
polymorphicPaths: Set<string>;
|
|
35
60
|
}
|
|
61
|
+
/** Non-branching, non-deferred */
|
|
36
62
|
export interface LayerPlanReasonSubroutine {
|
|
37
63
|
type: "subroutine";
|
|
38
64
|
parentStep: ExecutableStep;
|
|
@@ -45,38 +71,143 @@ export type HasParent<A extends LayerPlanReason> = A extends any ? A extends {
|
|
|
45
71
|
parentStep: ExecutableStep;
|
|
46
72
|
} ? A : never : never;
|
|
47
73
|
export type LayerPlanReasonsWithParentStep = HasParent<LayerPlanReason>;
|
|
74
|
+
/** @internal */
|
|
48
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
|
+
*/
|
|
49
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
|
+
*/
|
|
50
87
|
normalSteps: Array<{
|
|
51
88
|
step: ExecutableStep;
|
|
52
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
|
+
*/
|
|
53
96
|
unbatchedSyncAndSafeSteps: Array<{
|
|
54
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
|
+
*/
|
|
55
102
|
scratchpad: any;
|
|
56
103
|
}> | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* Optimization - a digest of all steps in normalSteps and unbatchedSyncAndSafeSteps
|
|
106
|
+
*
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
57
109
|
_allSteps: ExecutableStep[];
|
|
58
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* A LayerPlan represents (via "reason") either the root (root), when something
|
|
113
|
+
* happens at a later time (mutationField, defer), when plurality changes
|
|
114
|
+
* (list, stream, subscription, polymorphic), or when a subprocess needs to be
|
|
115
|
+
* computed (subroutine).
|
|
116
|
+
*
|
|
117
|
+
* Layer plans belong to an operation plan.
|
|
118
|
+
*
|
|
119
|
+
* Every layer plan (except for the root layer plan) has exactly one parent
|
|
120
|
+
* layer plan.
|
|
121
|
+
*
|
|
122
|
+
* Every layer plan is caused by a parent step.
|
|
123
|
+
*
|
|
124
|
+
* The LayerPlan of a step influences:
|
|
125
|
+
*
|
|
126
|
+
* 1. how steps are deduplicated
|
|
127
|
+
* 2. the order in which the steps are executed
|
|
128
|
+
* 3. where the result of executing the step is stored
|
|
129
|
+
* 4. when the step execution cache is allowed to be GC'd
|
|
130
|
+
*
|
|
131
|
+
* NOTE: `__ListTransformStep`'s effectively have a temporary bucket inside
|
|
132
|
+
* them (built on the `__Item`) that's thrown away once the transform is
|
|
133
|
+
* complete.
|
|
134
|
+
*
|
|
135
|
+
*/
|
|
59
136
|
export declare class LayerPlan<TReason extends LayerPlanReason = LayerPlanReason> {
|
|
60
137
|
readonly operationPlan: OperationPlan;
|
|
61
138
|
parentLayerPlan: LayerPlan | null;
|
|
62
139
|
readonly reason: TReason;
|
|
63
140
|
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
|
+
*/
|
|
64
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
|
+
*/
|
|
65
167
|
copyStepIds: number[];
|
|
168
|
+
/** @internal */
|
|
66
169
|
children: LayerPlan[];
|
|
170
|
+
/** @internal */
|
|
67
171
|
steps: ExecutableStep[];
|
|
172
|
+
/** @internal */
|
|
68
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
|
+
*/
|
|
69
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
|
+
*/
|
|
70
192
|
ancestry: LayerPlan[];
|
|
193
|
+
/** How "deep" this layer plan is (how many ancestors it has). The root layer plan has a depth of 0. */
|
|
71
194
|
depth: number;
|
|
195
|
+
/** The depth at which a "defer boundary" occurs (OperationPlan.getPeers cannot pass a defer boundary), or 0. */
|
|
72
196
|
deferBoundaryDepth: number;
|
|
197
|
+
/**
|
|
198
|
+
* An optimization for OperationPlan.getPeers; this tracks the steps in this
|
|
199
|
+
* layer plan, grouped by their step class.
|
|
200
|
+
*/
|
|
73
201
|
stepsByConstructor: Map<Function, Set<ExecutableStep>>;
|
|
74
202
|
constructor(operationPlan: OperationPlan, parentLayerPlan: LayerPlan | null, reason: TReason);
|
|
75
203
|
toString(): string;
|
|
76
204
|
print(depth?: number): string;
|
|
77
205
|
setRootStep($root: ExecutableStep): void;
|
|
206
|
+
/** @internal Use plan.getStep(id) instead. */
|
|
78
207
|
getStep(id: number, requestingStep: ExecutableStep): ExecutableStep;
|
|
208
|
+
/** @internal */
|
|
79
209
|
_addStep(step: ExecutableStep): number;
|
|
210
|
+
/** @internal */
|
|
80
211
|
_addModifierStep(step: ModifierStep<any>): string;
|
|
81
212
|
finalize(): void;
|
|
82
213
|
newBucket(parentBucket: Bucket): Bucket | null;
|