Files
orca/config/scripts/persistence-call-probe.mjs
T
Neil 49e5fa597a refactor(lint): enable anti-slop/no-reflect-apply (#20782)
`anti-slop/no-reflect-apply` rejects `Reflect.apply(fn, thisArg, argsArray)`.
It defeats the call-signature checks TypeScript applies to an ordinary call:
the args array is checked as an array, not positionally against the callee's
parameters, so arity and type errors pass silently. Dynamic dispatch belongs
behind a named interface, not behind a reflective call.

Flipped the rule from "off" to "error" and cleared all 17 baseline violations
across `src config tests mobile` (16 sites; one file had two).

Fix pattern: `Reflect.apply(fn, recv, args)` becomes `fn.call(recv, ...args)`,
or a direct method call when the implicit receiver is already the right object.
The receiver is preserved at every site.

Where the callee is a captured built-in whose overloads split on an argument's
shape (`String.prototype.split`, `JSON.stringify`), a call-signature capture no
longer compiles once the args are passed positionally. Those three sites capture
the function through a method-shaped type
(`{ split(separator: unknown, limit?: number): string[] }['split']`), which keeps
the forwarding call checked rather than asserted.

Behaviour notes:
- `diff-section-layout.test.ts` drops a `limit === undefined ? [sep] : [sep, limit]`
  conditional. Equivalent: `String.prototype.split` maps an undefined limit to
  2^32-1, and the `Symbol.split` path forwards undefined either way.
- `workspace-space-compaction.test.ts` forwards `reduce`'s two arguments unchanged,
  so the `arguments.length >= 2` initial-value branch is unaffected.
- `agent-session-history-byte-accounting.test.ts` is the one site where the receiver
  is not literally preserved (`JSON` -> undefined). `JSON.stringify` never reads
  `this` per spec, and restoring `.call(JSON, ...)` would reintroduce the overload
  failure under strictBindCallApply.

No suppression comments added — the rule has zero `oxlint-disable` sites.

`Reflect.apply` still appears at electron.vite.config.ts:159, inside a template
literal of generated bootstrap source. That is string content, not lintable code.
2026-09-15 00:10:11 -07:00

86 lines
2.9 KiB
JavaScript

export function installPersistenceCallProbe() {
const store = globalThis.__orcaLiveStoreProbeTarget
if (!store || globalThis.__orcaPersistenceCallProbe) {
throw new Error('Missing verified live store, or probe already active')
}
const contextSymbol = Object.getOwnPropertySymbols(store).find(
(symbol) => symbol.description === 'PrimaryStateWriteOperations'
)
const serialization = store[contextSymbol]?.serialization
if (!serialization?.buildStateToSave) {
throw new Error('Live serialization context was not found')
}
const events = []
const cleanup = []
function wrap(object, name, describe) {
const descriptor = Object.getOwnPropertyDescriptor(object, name)
const original = object[name]
const wrapped = function (...args) {
const details = describe?.(args) ?? {}
const start = performance.now()
const epoch = Date.now()
let result
try {
result = original.call(this, ...args)
return result
} finally {
const durationMs = performance.now() - start
if (events.length < 1000) {
events.push({
name,
epoch,
durationMs,
...details,
payloadBytes: name === 'buildStateToSave' ? result?.payload?.length : undefined,
stack:
durationMs > 20
? new Error('Persistence timing').stack?.split('\n').slice(2, 9)
: undefined
})
}
}
}
Object.defineProperty(object, name, { value: wrapped, configurable: true, writable: true })
cleanup.push(() => {
if (object[name] !== wrapped) {
return
}
if (descriptor) {
Object.defineProperty(object, name, descriptor)
} else {
delete object[name]
}
})
}
wrap(serialization, 'buildStateToSave')
wrap(store, 'flushOrThrow')
wrap(store, 'persistPtyBinding', ([args, hostId]) => {
if (hostId && hostId !== 'local') {
return { local: false }
}
const session = store.getWorkspaceSession()
const key = `${args.tabId}:${args.leafId}`
const worktreeId = args.expectedSourceBinding?.worktreeId ?? args.worktreeId
const tab = session.tabsByWorktree?.[worktreeId]?.find((t) => t.id === args.tabId)
return {
local: true,
tabAlreadyBound: tab?.ptyId === args.ptyId,
leafAlreadyBound:
session.terminalLayoutsByTabId?.[args.tabId]?.ptyIdsByLeafId?.[args.leafId] === args.ptyId,
incarnationAlreadyMatches:
session.terminalPtyIncarnationsByPaneKey?.[key] === args.incarnationId,
layoutExists: !!session.terminalLayoutsByTabId?.[args.tabId]?.root
}
})
globalThis.__orcaPersistenceCallProbe = {
stop() {
for (const restore of cleanup.toReversed()) {
restore()
}
delete globalThis.__orcaPersistenceCallProbe
delete globalThis.__orcaLiveStoreProbeTarget
return { events }
}
}
}