diff --git a/.changeset/fast-phones-change.md b/.changeset/fast-phones-change.md new file mode 100644 index 000000000..953968342 --- /dev/null +++ b/.changeset/fast-phones-change.md @@ -0,0 +1,8 @@ +--- +"grafast": patch +--- + +🚨 ExecutionValue no longer exposes .value and .entries (you need to narrow to +access these). Added new `.unaryValue()` that can be used to assert the value is +unary and retrieve its value - this should be used instead of `.at(0)` in +general. diff --git a/grafast/grafast/__tests__/unaryDeps-test.ts b/grafast/grafast/__tests__/unaryDeps-test.ts index be3ab9de9..67f8325de 100644 --- a/grafast/grafast/__tests__/unaryDeps-test.ts +++ b/grafast/grafast/__tests__/unaryDeps-test.ts @@ -86,8 +86,9 @@ class GetRecordsStep> extends ExecutableStep { indexMap, values, }: ExecutionDetails): Promise> { - const db = values[this.dbDepId].value as sqlite3.Database; - const first = this.firstUDI != null ? values[this.firstUDI].value : null; + const db = values[this.dbDepId].unaryValue() as sqlite3.Database; + const first = + this.firstUDI != null ? values[this.firstUDI].unaryValue() : null; const identifierCols = Object.keys(this.depIdByIdentifier); diff --git a/grafast/grafast/src/engine/executeBucket.ts b/grafast/grafast/src/engine/executeBucket.ts index 0c85ac477..2fbdf5f2f 100644 --- a/grafast/grafast/src/engine/executeBucket.ts +++ b/grafast/grafast/src/engine/executeBucket.ts @@ -1246,6 +1246,12 @@ export function bucketToString(this: Bucket) { return `Bucket<${this.layerPlan}>`; } +function throwNotUnary(): never { + throw new Error( + `This is not a unary value so we cannot get the single value - there may be more than one!`, + ); +} + // TODO: memoize? export function batchExecutionValue( entries: TData[], @@ -1256,6 +1262,7 @@ export function batchExecutionValue( at: batchEntriesAt, isBatch: true, entries, + unaryValue: throwNotUnary, _flags, _flagsAt: batchFlagsAt, _getStateUnion() { @@ -1313,6 +1320,7 @@ export function unaryExecutionValue( at: unaryAt, isBatch: false, value, + unaryValue: () => value, _entryFlags, _flagsAt: unaryFlagsAt, _getStateUnion: unaryGetStateUnion, diff --git a/grafast/grafast/src/interfaces.ts b/grafast/grafast/src/interfaces.ts index da93a4c8c..9472c0ce1 100644 --- a/grafast/grafast/src/interfaces.ts +++ b/grafast/grafast/src/interfaces.ts @@ -849,6 +849,8 @@ export type ExecutionValue = interface ExecutionValueBase { at(i: number): TData; isBatch: boolean; + /** Returns this.value for a unary execution value; throws if non-unary */ + unaryValue(): TData; /** @internal */ _flagsAt(i: number): ExecutionEntryFlags; /** bitwise OR of all the entry states @internal */ @@ -866,7 +868,8 @@ export interface BatchExecutionValue extends ExecutionValueBase { isBatch: true; entries: ReadonlyArray; - value?: never; + /** Always throws, since this should only be called on unary execution values */ + unaryValue(): never; /** @internal */ readonly _flags: Array; } @@ -874,7 +877,8 @@ export interface UnaryExecutionValue extends ExecutionValueBase { isBatch: false; value: TData; - entries?: never; + /** Same as getting .value */ + unaryValue(): TData; /** @internal */ _entryFlags: ExecutionEntryFlags; } diff --git a/grafast/grafast/src/steps/applyTransforms.ts b/grafast/grafast/src/steps/applyTransforms.ts index 14aca23b7..45920969c 100644 --- a/grafast/grafast/src/steps/applyTransforms.ts +++ b/grafast/grafast/src/steps/applyTransforms.ts @@ -105,7 +105,7 @@ export class ApplyTransformsStep extends ExecutableStep { ); } if (itemStep._isUnary) { - store.set(itemStepId, unaryExecutionValue(values0.at(0))); + store.set(itemStepId, unaryExecutionValue(values0.unaryValue())); } else { store.set(itemStepId, batchExecutionValue([])); } diff --git a/grafast/grafast/src/steps/listTransform.ts b/grafast/grafast/src/steps/listTransform.ts index b7fcb8e2e..0804e9b9e 100644 --- a/grafast/grafast/src/steps/listTransform.ts +++ b/grafast/grafast/src/steps/listTransform.ts @@ -231,7 +231,7 @@ export class __ListTransformStep< const listStepValue = values[this.listStepDepId]; if (itemStep._isUnary) { - const list = listStepValue.at(0); + const list = listStepValue.unaryValue(); store.set( itemStepId, unaryExecutionValue(Array.isArray(list) ? list[0] : list),