feat(verifier): OverrideExtractorValues for V8-driven extractors

Web tick path runs extractor bodies in V8 against the real DOM, then
overrides goja-side .current slots so LTL predicates evaluate against
those values. Mobile callers can pass nil for a no-op.
This commit is contained in:
pj committed 2026-04-27 18:42:14 +07:00
1 parent 87b30d0f22
commit 0d6f32f8a4
2 files changed
+80

No files matched your search

+25
View File
@@ -1,6 +1,7 @@
package verifier
import (
"encoding/json"
"errors"
"fmt"
"math/rand/v2"
@@ -238,6 +239,30 @@ func (v *Verifier) PushSnapshot(input SnapshotInput) error {
return nil
}
// OverrideExtractorValues replaces each extractor's `current` slot with a
// caller-supplied value, keyed by registration index. Used by the web tick
// path so extractor bodies that ran in V8 (against the real DOM) drive the
// goja-side LTL predicates without re-running the getter against an empty
// state.ax shim. Passing a nil/empty map is a no-op so the mobile path can
// call this unconditionally. The override must run *after* PushSnapshot
// (which advanced `previous`) and *before* EvaluateProperties.
func (v *Verifier) OverrideExtractorValues(overrides map[int]json.RawMessage) error {
if len(overrides) == 0 {
return nil
}
for index, raw := range overrides {
if index < 0 || index >= len(v.extractors) {
return fmt.Errorf("extractor override index %d out of range (have %d)", index, len(v.extractors))
}
value, err := jsonToJSValue(v.runtime, raw)
if err != nil {
return fmt.Errorf("extractor override %d: %w", index, err)
}
_ = v.extractors[index].handle.Set("current", value)
}
return nil
}
// SnapshotInput bundles everything a step feeds into the verifier. Fields
// other than Snapshots are optional; callers that only have snapshots can
// populate Snapshots alone and leave the rest zero.