# Migration ## 1. Decide whether native Node is sufficient For ordinary modern Node.js files, prefer native source maps. Before adopting this package, inventory actual use of: - `source-map-support/register` or `register-hook-require`; - `vm.runInThisContext()` or another generated-code path; - browser global or AMD distribution; - custom `retrieveFile` or `retrieveSourceMap` hooks; - direct `mapSourcePosition`, `wrapCallSite`, or `getErrorSource` calls; - `hookRequire`, `handleUncaughtExceptions`, or a captured `Error.prepareStackTrace` integration. If none remains, test and use the native path instead of adding a process-wide userland formatter. ## 2. Lowest-change dependency alias Preserve the historical dependency key: ```sh npm install source-map-support@npm:@stackline/source-map-support ``` Equivalent manifest entry: ```json { "dependencies": { "source-map-support": "npm:@stackline/source-map-support@1.0.0" } } ``` This keeps existing source such as: ```js require('source-map-support/register') ``` It also keeps bundler or Electron webpack externals keyed by `source-map-support`. Commit the manifest and lockfile together, install from a clean state, and confirm that the lock resolves the alias to the exact scoped release. ## 3. Explicit scoped migration Change the root import when the application can accept a source diff: ```js const sourceMapSupport = require('@stackline/source-map-support') sourceMapSupport.install({ handleUncaughtExceptions: false }) ``` or in an ESM host: ```js import sourceMapSupport, { install, mapSourcePosition } from '@stackline/source-map-support' ``` Map historical deep entries directly: | Historical | Scoped | | --- | --- | | `source-map-support/register` | `@stackline/source-map-support/register` | | `source-map-support/register-hook-require` | `@stackline/source-map-support/register-hook-require` | | `source-map-support/browser-source-map-support` | `@stackline/source-map-support/browser-source-map-support` | The `.js` variants are also exported. ## 4. Review global ownership `install()` replaces `Error.prepareStackTrace`. The default Node install can also wrap `process.emit`, and `hookRequire` wraps `Module.prototype._compile`. Before switching: - identify the existing stack formatter and preserve it if the application deliberately calls it; - set `handleUncaughtExceptions: false` when a framework or Electron host owns uncaught errors; - avoid installing both native and userland mapping without a real-process smoke test; - install in the intended realm only; Electron main and renderer processes have different globals and environment detection; - remember that `resetRetrieveHandlers()` is not an uninstall function. ## 5. Re-test retrieval and map forms Exercise the application's actual generated outputs: - ordinary local files and native mapping choice; - VM filenames and generated code; - inline and external maps; - indexed Source Map v3 payloads with multiple `sections` and nonzero offsets; - `sourceRoot`, URL, file URL, and Windows drive paths; - maps containing `sourcesContent`; - runtime-transpiler maps with `hookRequire`; - every custom provider hit, miss, and expected failure; - browser global or AMD loading and origin policy; - mapped names, eval frames, and error source excerpts. Custom providers remain synchronous. Measure startup and stack-access cost with real map sizes. A downstream integration can deliberately capture the package formatter and replace the default on-access formatter with cheaper frame capture; migration must not assume that every consumer leaves `Error.prepareStackTrace` untouched. ## 6. Review maintained corrections - The production parser is now exact `@jridgewell/trace-mapping@0.3.31` with two exact MIT transitive dependencies. Its `AnyMap` path accepts both regular and indexed/sectioned Source Map v3 payloads. - Generated sources without maps are no longer kept indefinitely in the content cache. - Malformed maps, malformed inline base64, and special object keys fail back to generated positions. - URL resolution, process-free browser path handling, UTF-8 inline browser maps, `Error.cause`, and existing nonzero exit codes have maintained corrections. - Differently named property aliases retain the current native V8 CallSite formatting and should be regression-tested, but are not a maintained divergence. - The runtime floor is Node.js 14.15.1. - ESM-host and TypeScript declarations are additive. These are observable edges. Do not infer that parser replacement makes source map contents trusted or that memory is globally bounded. ## 7. Browser migration Use an ordinary root import with a browser-condition-aware bundler, the dedicated browser deep export, or a copied standalone UMD artifact. Root ESM imports select the browser ESM host; root CommonJS and the explicit browser deep entry use the UMD implementation. Do not substitute the Node `register` entry. If default retrieval is used, confirm that synchronous XHR is acceptable and permitted by origin policy. Prefer a preloaded bounded custom map provider when the application already owns the artifacts. The packed UMD and ESM artifacts resolve relative paths without a Node `process` global and treat malformed inline base64 maps as misses. Exercise both root-condition routes and any copied standalone artifact in the actual browser bundler; testing one delivery form does not qualify the others. Automatic mapped `Error.stack` output depends on V8-compatible stack hooks. Test the exact supported browsers; successful direct `mapSourcePosition()` behavior is not proof that every engine invokes `Error.prepareStackTrace`. ## Rollback Restore the prior dependency range and lockfile, reinstall cleanly, and rerun the same smoke tests. Restart every affected process or browser realm: removing the dependency does not undo hooks already installed in a running process. Rollback cannot retract source maps or `sourcesContent` already deployed to a browser or production artifact.