footprintjs - v11.2.0
    Preparing search index...

    Interface ScopeMethods

    interface ScopeMethods {
        $attachScopeRecorder(recorder: ScopeRecorder): void;
        $attempt(): AttemptContext;
        $batchArray(key: string, fn: (arr: unknown[]) => void): void;
        $break(reason?: string): void;
        $call<R>(
            target: string,
            fn: (attempt: AttemptContext) => R | Promise<R>,
            policy?: RetryPolicy,
            options?: CallOptions,
        ): Promise<R>;
        $debug(key: string, value: unknown): void;
        $delete(key: string, description?: string): void;
        $detachAndForget(
            driver: DetachDriver,
            child: FlowChart,
            input?: unknown,
        ): void;
        $detachAndJoinLater(
            driver: DetachDriver,
            child: FlowChart,
            input?: unknown,
        ): DetachHandle;
        $detachScopeRecorder(recorderId: string): void;
        $emit(name: string, payload?: unknown): void;
        $error(key: string, value: unknown): void;
        $eval(name: string, value: unknown): void;
        $getArgs<T = Record<string, unknown>>(): T;
        $getEnv(): Readonly<ExecutionEnv>;
        $getScopeRecorders(): ScopeRecorder[];
        $getValue(key: string): unknown;
        $log(value: unknown): void;
        $metric(name: string, value: unknown): void;
        $read(dotPath: string): unknown;
        $setValue(
            key: string,
            value: unknown,
            shouldRedact?: boolean,
            description?: string,
        ): void;
        $toRaw(): ReactiveTarget;
        $update(key: string, value: unknown, description?: string): void;
    }
    Index
    • The attempt this stage function runs in (P1b): attempt / of, the signal to pass to fetch and SDK calls (it aborts at the attempt's cap, the run's deadline, or a cancellation), and timeLeftMs() — the milliseconds before the run's deadline (Infinity without one; reading it with a deadline marks the stage's commit untrackedSources: ['env']). A stage with no retry policy and no deadline is attempt 1 of 1.

      Returns AttemptContext

    • Batch-mutate an array key in a single clone+write cycle.

      Every scope.items.push(x) clones the entire array and commits it — O(N) per call. For N mutations on an M-length array that is O(N×M). Use $batchArray to clone once, apply all mutations inside fn, then commit once — O(M) total.

      // Before: 1000 clones × growing array = O(N²)
      for (let i = 0; i < 1000; i++) scope.items.push(i);

      // After: 1 clone + 1 commit = O(N)
      scope.$batchArray('items', (arr) => {
      for (let i = 0; i < 1000; i++) arr.push(i);
      });

      fn receives a plain (non-proxy) mutable deep copy (structuredClone) of the current array — "clone once" means the elements too. Mutating an element inside fn (arr[0].n = 9) changes the copy and lands in the one committed write; the value in state is never touched (9.22.0 — a shallow copy used to share the committed elements, so an element edit changed committed state in place with no trace row).

      Mutations inside fn are NOT tracked individually — only the final committed array appears in the narrative as a single write. If the key does not exist or is not an array, fn receives an empty array and the result is committed as the new value.

      If fn throws, setValue is never called and state remains unchanged (atomic on error). The exception propagates to the caller.

      key is untyped (string) — TypeScript will not catch typos. arr is typed as unknown[] because ScopeMethods is not parameterized by T; cast inside fn when element types are known: (arr as string[]).push(x).

      Parameters

      • key: string
      • fn: (arr: unknown[]) => void

      Returns void

    • Stop the current execution context.

      • In a top-level chart: the traverser exits cleanly after this stage completes.
      • Inside a subflow: by default, only the subflow's own execution stops; control returns to the parent as normal. If the subflow is mounted with propagateBreak: true, the break signal (and its optional reason) propagates up to the parent scope, terminating the outer loop too. See SubflowMountOptions.propagateBreak.

      Parameters

      • Optionalreason: string

        Optional free-form string describing why the break happened. Propagates to FlowBreakEvent.reason so recorders and custom narratives can surface it, served under the run's redaction policy. Defaults to undefined.

      Returns void

    • A call to an outside system, made inside this stage (P2): fn runs on the attempt runner under policy (none = ONE attempt — still recorded), and every attempt is an AttemptRecord of kind 'call' on this stage's node and on onAttempt, with its timing, outcome, category and decision. It runs under this stage attempt's time and signal — pass t.signal on. target is a NAME from code (1–128 characters, no control character), never a value. A malformed call (target, fn, policy) or one from an attempt that already ended THROWS at the call, synchronously, like every scope refusal — it is the stage's code breaking its contract; a call that runs and fails REJECTS with its last attempt's own error. A call that changes an outside system declares it in options ({ touches, idempotencyKey }, P3): a touching call that may retry needs a key, every record carries its effect, and a call that ends without an answer after any attempt of unknown effect rejects with UnknownEffectError.

      const quote = await scope.$call('stripe.quotes.create', (t) => stripe.quotes.create(body, { signal: t.signal }),
      { attempts: 3, timeoutMs: 10_000 });

      Type Parameters

      • R

      Parameters

      Returns Promise<R>

    • Parameters

      • key: string
      • value: unknown

      Returns void

    • Parameters

      • key: string
      • Optionaldescription: string

      Returns void

    • Parameters

      • recorderId: string

      Returns void

    • Fire a structured event to every attached recorder implementing onEmit. The primary primitive for consumer-authored observability events (LLM tokens, billing metrics, domain milestones, etc.) that shouldn't live in scope state.

      Synchronous, pass-through — delivered to recorders immediately, in call order. Zero-allocation when no recorders are attached.

      Use hierarchical dotted names: '<namespace>.<category>.<event>'. Examples:

      • 'agentfootprint.llm.tokens'
      • 'myapp.billing.spend'
      • 'auth.check.denied'

      The library stays vocabulary-agnostic — no central registry, no reserved prefixes. Namespace prefixes prevent collisions across libraries and apps naturally.

      If RedactionPolicy.emitPatterns matches the name, the payload is replaced with '[REDACTED]' before dispatch. No recorder ever sees the raw value for redacted event names.

      Parameters

      • name: string

        Consumer-chosen event identifier (see naming convention).

      • Optionalpayload: unknown

        Structured data to attach. Shape is up to the consumer; library treats it as opaque.

      Returns void

      scope.$emit('agentfootprint.llm.tokens', { input: 100, output: 50 });
      scope.$emit('myapp.decision', { branch: 'approved', confidence: 0.92 });
    • Parameters

      • key: string
      • value: unknown

      Returns void

    • Parameters

      • name: string
      • value: unknown

      Returns void

    • Parameters

      • name: string
      • value: unknown

      Returns void

    • Proxy-synthesized: calls getValue(rootKey) then walks the nested path (lodash.get-style, no lodash dep). Not a direct delegation.

      Parameters

      • dotPath: string

      Returns unknown

    • Parameters

      • key: string
      • value: unknown
      • OptionalshouldRedact: boolean
      • Optionaldescription: string

      Returns void

    • Parameters

      • key: string
      • value: unknown
      • Optionaldescription: string

      Returns void