@@ -131,8 +131,10 @@ but Gra*fast* steps are much more powerful thanks to the additional dependencies
131131and lifecycle methods.
132132
133133When the step class adds a dependency (with `this.addDependency($step)` or
134- similar) a dependency index, `depIndex`, is returned. Dependency indexes start
135- at 0 and increase monotonically (a dependency can never be removed[^1]).
134+ similar) a dependency ID, `depId`, is returned. Dependency IDs are numbers at
135+ runtime and start at 0, increasing monotonically (a dependency can never be
136+ removed[^1]). In TypeScript they are branded as `DepId<TStep>`, which preserves
137+ the dependency step type for helpers such as `details.values.at(depId)`.
136138
137139[^1]:
138140 To remove a dependency, you must instead replace the step with a copy that
@@ -155,9 +157,10 @@ of the execute method.
155157
156158`details.values` is also critical: an ordered array of execution values, one for
157159each dependency. You can retrieve the execution value for a given dependency via
158- its `depIndex` as `const depEv = details.values[depIndex]`. Once you have an
159- execution value, you can retrieve the value for a given index in the batch via
160- `const value = depEv.at(batchIndex)`.
160+ its `depId` as `const depEv = details.values.at(depId)`. Tuple destructuring or
161+ `details.values[depIndex]` is also fine when it is more convenient. Once you
162+ have an execution value, you can retrieve the value for a given index in the
163+ batch via `const value = depEv.at(batchIndex)`.
161164
162165Gra*fast* tracks which steps will always represent exactly one value (e.g. the
163166GraphQL context, input values passed as field arguments, constants, etc), and
@@ -180,9 +183,9 @@ top of the execute method:
180183class MyStep extends Step {
181184 constructor ($a , $b , $c ) {
182185 super();
183- this.aDepIndex = this . addUnaryDependency ($a );
184- this.bDepIndex = this . addDependency ($b );
185- this.cDepIndex = this . addDependency ($c );
186+ this.addUnaryDependency($a);
187+ this.addDependency($b);
188+ this.addDependency($c);
186189 }
187190 execute (details ) {
188191 const { values } = details;
@@ -243,23 +246,25 @@ Here's a hypothetical example, concentrate on the `execute()` method and see how
243246the steps outlined above play out :
244247
245248` ` ` ts
249+ import { Step, type DepId } from "grafast";
246250import { languageService } from "./services/language";
247251
248- class TranslationStep extends Step {
249- langDepIndex: number;
250- textDepIndex: number;
252+ class TranslationStep extends Step<string | undefined> {
253+ langDepId: DepId<Step<string>>;
254+ textDepId: DepId<Step<string>>;
255+
251256 constructor($language: Step<string>, $text: Step<string>) {
252257 super();
253258 // Add our dependencies
254- this.langDepIndex = this.addDependency($language);
255- this.textDepIndex = this.addDependency($text);
259+ this.langDepId = this.addDependency($language);
260+ this.textDepId = this.addDependency($text);
256261 }
257- execute(details) {
262+ async execute(details) {
258263 // highlight-start
259264 // 1. Extract and identify the execution value for each dependency:
260265 // highlight-end
261- const langEv = details.values[ this.langDepIndex] ;
262- const textEv = details.values[ this.textDepIndex] ;
266+ const langEv = details.values.at( this.langDepId) ;
267+ const textEv = details.values.at( this.textDepId) ;
263268
264269 // highlight-start
265270 // 2. Map over the indices to prepare the input for our translation API:
@@ -278,7 +283,7 @@ class TranslationStep extends Step {
278283 // highlight-start
279284 // 4. Finally, return results that correlate with the inputs:
280285 // highlight-end
281- return indexMap((batchIndex) => {
286+ return details. indexMap((batchIndex) => {
282287 const language = langEv.at(batchIndex);
283288 const sourceText = textEv.at(batchIndex);
284289 const match = translations.find(
@@ -736,8 +741,10 @@ as part of `Step`.
736741
737742When your step requires another step's value in order to execute (which is the
738743case for the majority of steps!) it must add a dependency via the
739- ` this .addDependency ($otherStep )` method. This method will return a number,
740- which is the index in the ` execute ` values tuple that represents this step.
744+ ` this .addDependency ($otherStep )` method. This method will return a ` DepId `
745+ (a branded number), which is the index in the ` execute ` values tuple that
746+ represents the dependency. TypeScript uses the brand to infer the dependency's
747+ data type when you later call ` details .values .at (depId )` .
741748
742749It's common to do this in the constructor, but it can be done at other stages
743750too, for example during the optimize phase a step's descendant might ask it to
@@ -750,8 +757,8 @@ class added two dependencies:
750757class AddStep extends Step {
751758 constructor ($a , $b ) {
752759 super ();
753- this .addDependency ($a ); // Returns 0
754- this .addDependency ($b ); // Returns 1
760+ this .addDependency ($a ); // Returns 0 as a DepId
761+ this .addDependency ($b ); // Returns 1 as a DepId
755762 }
756763}
757764` ` `
@@ -805,9 +812,10 @@ input values are not).
805812
806813### getDep
807814
808- Pass in the number of the dependency ( ` 0 ` for the first dependency, ` 1 ` for the
809- second, and so on) and Gra*fast* will return the corresponding step. This should
810- only be used before or during the ` optimize ` phase.
815+ Pass in the dependency ID returned from ` addDependency ` , or a literal dependency
816+ index ( ` 0 ` for the first dependency, ` 1 ` for the second, and so on), and
817+ Gra*fast* will return the corresponding step. This should only be used before
818+ or during the ` optimize ` phase.
811819
812820For example in the ` AddStep ` example above we might have:
813821
0 commit comments