Skip to content

perf(lifecycle): scope extension timer builtins#605

Closed
JustYannicc wants to merge 121 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-lifecycle-scoped-timer-builtins-20260705
Closed

perf(lifecycle): scope extension timer builtins#605
JustYannicc wants to merge 121 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-lifecycle-scoped-timer-builtins-20260705

Conversation

@JustYannicc

Copy link
Copy Markdown
Collaborator

What changed

  • Route extension require('timers'), require('node:timers'), require('timers/promises'), and require('node:timers/promises') through lifecycle-scoped timer facades when loadExtensionExport has a TimerRegistry.
  • Preserve setImmediate/clearImmediate and timers/promises async iterator/scheduler APIs while tracking pending handles in the ExtensionView registry.
  • Extend the lifecycle sandbox harness with imported timer before/after leak coverage and fired one-shot pruning checks.

Why

Imported Node timer built-ins could bypass ExtensionView cleanup and keep intervals/timeouts alive after unmount or no-view background completion. Bare wrapper timers were already scoped; imported timer modules now use the same lifecycle registry.

Compatibility impact

  • Scoped behavior applies only when loadExtensionExport has a TimerRegistry.
  • Unscoped built-in fallback behavior remains on the existing real Node/static stub path.
  • Raycast-style timers, node: aliases, setImmediate, clearImmediate, timers/promises setTimeout, setInterval async iteration, setImmediate, and scheduler.wait remain available.

How tested

  • node scripts/test-extension-lifecycle-sandbox.mjs
  • node scripts/test-extension-wrapper-cache.mjs
  • npm run typecheck:renderer attempted, but local npm is intentionally disabled and rerouted to pnpm; repo parity rejected pnpm. Ran direct equivalent: ./node_modules/.bin/tsc -p tsconfig.renderer.json --noEmit --pretty false
  • Codex LSP diagnostics on src/renderer/src/ExtensionView.tsx: no diagnostics found
  • Codex LSP references for createExtensionLifecycleScope checked expected production/facade call sites
  • git diff --check

Performance evidence

  • Harness pre-fix imported timer module path: beforeClear { intervals: 1, timeouts: 3, total: 4 }, after clear unchanged at total 4.
  • Harness scoped facade path: beforeClear { intervals: 1, timeouts: 3, total: 4 }, registryBeforeClear { intervals: 1, timeouts: 3 }, after clear total 0.
  • Fired imported one-shots: 4 scheduled handles pruned to registryTimeoutsAfterFlush 0 and hostTimeoutsAfterFlush 0.

Stack validation

  • Started from codex/perf-wave4-integrated-stack-20260705 at ac90ce4 and branched to codex/perf-lifecycle-scoped-timer-builtins-20260705.
  • Changed files: src/renderer/src/ExtensionView.tsx; scripts/test-extension-lifecycle-sandbox.mjs.
  • Temporary sibling node_modules symlink was used for local checks because this worktree had no dependencies; it was removed before commit.

Replaces

  • Supersedes the audit finding that imported extension timer modules could prefer real Node built-ins or global stubs and outlive ExtensionView lifecycle cleanup.

(cherry picked from commit 83c2a89)
(cherry picked from commit 0a7560b)
# Conflicts:
#	src/renderer/src/raycast-api/hooks/use-cached-promise.ts
…launcher surfaces

# Conflicts:
#	src/renderer/src/raycast-api/list-runtime-renderers.tsx
#	src/renderer/src/raycast-api/list-runtime.tsx
…IO stalls

# Conflicts:
#	src/renderer/src/CameraExtension.tsx
# Conflicts:
#	src/renderer/src/raycast-api/list-runtime.tsx
…resh overhead

# Conflicts:
#	scripts/bench-script-command-discovery.mjs
#	scripts/benchmark-file-search-delete-batch.mjs
#	scripts/lib/script-command-runner-harness.mjs
#	scripts/lib/ts-import.mjs
#	scripts/test-file-search-delete-batch.mjs
#	scripts/test-script-command-runner.mjs
#	src/main/file-search-index.ts
#	src/main/main.ts
…hurn

# Conflicts:
#	scripts/lib/script-command-runner-harness.mjs
#	scripts/lib/ts-import.mjs
#	scripts/test-extension-lifecycle-sandbox.mjs
#	scripts/test-script-command-runner.mjs
#	src/main/main.ts
#	src/renderer/src/ExtensionView.tsx
… hot paths

# Conflicts:
#	scripts/test-use-frecency-sorting.mjs
#	src/renderer/src/raycast-api/form-runtime.tsx
#	src/renderer/src/raycast-api/grid-runtime-hooks.ts
#	src/renderer/src/raycast-api/grid-runtime-items.tsx
#	src/renderer/src/raycast-api/hooks/use-frecency-sorting.ts
# Conflicts:
#	.github/workflows/project-checks.yml
#	package.json
#	scripts/file-search-perf-harness.mjs
#	scripts/test-browser-search-performance.mjs
#	scripts/test-file-search-perf-harness.mjs
#	scripts/test-root-search-perf.mjs
#	src/renderer/src/CameraExtension.tsx
#	src/renderer/src/hooks/useBrowserSearch.ts
#	src/renderer/src/raycast-api/list-runtime.tsx
…cle and media fixes

# Conflicts:
#	scripts/lib/ts-import.mjs
#	scripts/measure-extension-bundle-cache.mjs
#	src/main/commands.ts
#	src/main/extension-runner.ts
#	src/main/main.ts
#	src/renderer/src/ExtensionView.tsx
#	src/renderer/src/raycast-api/grid-runtime-hooks.ts
#	src/renderer/src/raycast-api/list-runtime-hooks.ts
@JustYannicc

Copy link
Copy Markdown
Collaborator Author

Superseded by the consolidated runtime/lifecycle/media PR: #622

@JustYannicc JustYannicc closed this Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant