mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
`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.
86 lines
2.9 KiB
JavaScript
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 }
|
|
}
|
|
}
|
|
}
|