diff --git a/pkg/spec/src/extract.ts b/pkg/spec/src/extract.ts index 4c08087..d0edd8f 100644 --- a/pkg/spec/src/extract.ts +++ b/pkg/spec/src/extract.ts @@ -1,7 +1,18 @@ import type { AccessibilityElement, Extracted, State } from "./types.ts"; -export function extract(getter: (state: State) => T): Extracted { - return globalThis.__sanderling__.extract(getter); +export function extract(getter: (state: State) => T): Extracted; +export function extract(name: string, getter: (state: State) => T): Extracted; +export function extract( + nameOrGetter: string | ((state: State) => T), + maybeGetter?: (state: State) => T, +): Extracted { + if (typeof nameOrGetter === "string") { + if (maybeGetter == null) { + throw new TypeError("extract(name, getter): getter is required when a name is supplied"); + } + return globalThis.__sanderling__.extract(maybeGetter, nameOrGetter); + } + return globalThis.__sanderling__.extract(nameOrGetter); } const KEY_DELIMITER = "\x1f"; diff --git a/pkg/spec/src/types.ts b/pkg/spec/src/types.ts index 48336c3..fcebe4a 100644 --- a/pkg/spec/src/types.ts +++ b/pkg/spec/src/types.ts @@ -187,7 +187,7 @@ export interface Sampler { } export interface SanderlingRuntime { - extract: (getter: (state: State) => T) => Extracted; + extract: (getter: (state: State) => T, name?: string) => Extracted; always: (predicateOrFormula: (() => boolean) | Formula) => Formula; now: (predicate: () => boolean) => Formula; next: (predicate: () => boolean) => Formula; diff --git a/pkg/spec/src/web-runtime.ts b/pkg/spec/src/web-runtime.ts index 5120abc..90caeb5 100644 --- a/pkg/spec/src/web-runtime.ts +++ b/pkg/spec/src/web-runtime.ts @@ -20,6 +20,7 @@ interface Handle { interface ExtractorEntry { getter: (state: unknown) => unknown; handle: Handle; + name: string; } interface ActionGeneratorHandle { @@ -290,9 +291,14 @@ function buildState(): unknown { } const runtime = { - extract(getter: (state: unknown) => T): Handle { + extract(getter: (state: unknown) => T, name?: string): Handle { const handle: Handle = { current: undefined, previous: undefined }; - extractors.push({ getter: getter as (s: unknown) => unknown, handle }); + const resolvedName = name && name.length > 0 ? name : `extractor_${extractors.length}`; + extractors.push({ + getter: getter as (s: unknown) => unknown, + handle, + name: resolvedName, + }); return handle; }, always: noopFormula,