react-on-rails-pro-node-renderer 17.0.0-rc.2 → 17.0.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/worker/vm.js CHANGED
@@ -53,6 +53,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
53
53
  exports.VMContextNotFoundError = void 0;
54
54
  exports.hasVMContextForBundle = hasVMContextForBundle;
55
55
  exports.getVMContext = getVMContext;
56
+ exports.hasAnyVMContext = hasAnyVMContext;
56
57
  exports.buildExecutionContext = buildExecutionContext;
57
58
  exports.resetVM = resetVM;
58
59
  exports.removeVM = removeVM;
@@ -72,12 +73,55 @@ const log_js_1 = __importDefault(require("../shared/log.js"));
72
73
  const configBuilder_js_1 = require("../shared/configBuilder.js");
73
74
  const utils_js_1 = require("../shared/utils.js");
74
75
  const errorReporter = __importStar(require("../shared/errorReporter.js"));
76
+ const vmSourceMapSupport_js_1 = require("./vmSourceMapSupport.js");
75
77
  const readFileAsync = (0, util_1.promisify)(fs_1.default.readFile);
78
+ // Length of the `Module.wrap` prefix that is prepended to the first line of a
79
+ // wrapped bundle. Needed to correct first-line stack-frame columns before
80
+ // source map lookups.
81
+ const MODULE_WRAP_FIRST_LINE_PREFIX_LENGTH = module_1.default.wrap('\n').indexOf('\n');
76
82
  const writeFileAsync = (0, util_1.promisify)(fs_1.default.writeFile);
77
83
  // Store contexts by their bundle file paths
78
84
  const vmContexts = new Map();
79
85
  // Track VM creation promises to handle concurrent buildVM requests
80
86
  const vmCreationPromises = new Map();
87
+ // Execution contexts can outlive VM pool entries while a request is still
88
+ // running. Keep source maps for those evicted contexts until the request
89
+ // releases them, then drop both the registration and parsed-map cache.
90
+ const activeSourceMapRequestCounts = new Map();
91
+ const evictedSourceMapRegistrations = new Set();
92
+ function retainSourceMapRegistration(sourceMapRegistration) {
93
+ activeSourceMapRequestCounts.set(sourceMapRegistration, (activeSourceMapRequestCounts.get(sourceMapRegistration) ?? 0) + 1);
94
+ }
95
+ function releaseSourceMapRegistration(sourceMapRegistration) {
96
+ const currentCount = activeSourceMapRequestCounts.get(sourceMapRegistration) ?? 0;
97
+ if (currentCount <= 1) {
98
+ activeSourceMapRequestCounts.delete(sourceMapRegistration);
99
+ const wasEvicted = evictedSourceMapRegistrations.delete(sourceMapRegistration);
100
+ // Eviction deletes the VM first today; keep the guard so future callers do
101
+ // not unregister a source map for a live pooled VM.
102
+ let isStillInPool = false;
103
+ for (const vmContext of vmContexts.values()) {
104
+ if (vmContext.sourceMapRegistration === sourceMapRegistration) {
105
+ isStillInPool = true;
106
+ break;
107
+ }
108
+ }
109
+ if (wasEvicted && !isStillInPool) {
110
+ (0, vmSourceMapSupport_js_1.unregisterBundleForSourceMaps)(sourceMapRegistration);
111
+ }
112
+ return;
113
+ }
114
+ activeSourceMapRequestCounts.set(sourceMapRegistration, currentCount - 1);
115
+ }
116
+ function retireSourceMapRegistrationAfterEviction(sourceMapRegistration) {
117
+ (0, vmSourceMapSupport_js_1.retireMissingSourceMapRetry)(sourceMapRegistration);
118
+ if ((activeSourceMapRequestCounts.get(sourceMapRegistration) ?? 0) > 0) {
119
+ evictedSourceMapRegistrations.add(sourceMapRegistration);
120
+ }
121
+ else {
122
+ (0, vmSourceMapSupport_js_1.unregisterBundleForSourceMaps)(sourceMapRegistration);
123
+ }
124
+ }
81
125
  /**
82
126
  * Returns all bundle paths that have a VM context
83
127
  * @internal Used in tests
@@ -91,12 +135,35 @@ function hasVMContextForBundle(bundlePath) {
91
135
  function getVMContext(bundlePath) {
92
136
  return vmContexts.get(bundlePath);
93
137
  }
138
+ /**
139
+ * Whether this worker has at least one bundle compiled into a VM context.
140
+ * Used by the built-in /ready readiness endpoint: a worker with zero loaded
141
+ * bundles cannot serve render requests until a bundle is uploaded.
142
+ *
143
+ * This intentionally stays false while a bundle is still compiling in
144
+ * vmCreationPromises; /ready flips to 200 only after compilation finishes and
145
+ * the compiled context is stored in vmContexts.
146
+ *
147
+ * Pool eviction can remove older bundle contexts, but readiness remains true as
148
+ * long as at least one compiled bundle remains in the pool.
149
+ */
150
+ function hasAnyVMContext() {
151
+ return vmContexts.size > 0;
152
+ }
94
153
  const extendContext = (contextObject, additionalContext) => {
95
154
  if (log_js_1.default.level === 'debug') {
96
155
  log_js_1.default.debug(`Adding ${Object.keys(additionalContext).join(', ')} to context object.`);
97
156
  }
98
157
  Object.assign(contextObject, additionalContext);
99
158
  };
159
+ const readPrepareStackTraceHook = (context) => {
160
+ try {
161
+ return vm_1.default.runInContext('typeof Error === "undefined" ? undefined : Error.prepareStackTrace', context);
162
+ }
163
+ catch {
164
+ return undefined;
165
+ }
166
+ };
100
167
  // Helper function to manage VM pool size
101
168
  function manageVMPoolSize() {
102
169
  const { maxVMPoolSize } = (0, configBuilder_js_1.getConfig)();
@@ -105,9 +172,11 @@ function manageVMPoolSize() {
105
172
  }
106
173
  const sortedEntries = Array.from(vmContexts.entries()).sort(([, a], [, b]) => a.lastUsed - b.lastUsed);
107
174
  while (sortedEntries.length > maxVMPoolSize) {
108
- const oldestPath = sortedEntries.shift()?.[0];
109
- if (oldestPath) {
175
+ const oldestEntry = sortedEntries.shift();
176
+ if (oldestEntry) {
177
+ const [oldestPath, oldestContext] = oldestEntry;
110
178
  vmContexts.delete(oldestPath);
179
+ retireSourceMapRegistrationAfterEviction(oldestContext.sourceMapRegistration);
111
180
  log_js_1.default.debug(`Removed VM for bundle ${oldestPath} due to pool size limit (max: ${maxVMPoolSize})`);
112
181
  }
113
182
  }
@@ -139,12 +208,29 @@ async function buildVM(filePath) {
139
208
  // than a try/finally inside the IIFE, because an IIFE's finally block can
140
209
  // execute synchronously (before `vmCreationPromises.set`) when the code throws
141
210
  // before the first `await`, which would leave a stale rejected promise in the map.
211
+ let sourceMapRegistration;
142
212
  const vmCreationPromise = (async () => {
143
213
  try {
144
214
  const { supportModules, stubTimers, additionalContext } = (0, configBuilder_js_1.getConfig)();
145
215
  const additionalContextIsObject = additionalContext !== null && additionalContext.constructor === Object;
146
216
  const sharedConsoleHistory = new sharedConsoleHistory_js_1.default();
147
- const contextObject = { sharedConsoleHistory };
217
+ // Request-derived bundle paths are built from validated timestamp path components.
218
+ // Direct `buildExecutionContext` callers pass trusted internal bundle paths.
219
+ // codeql[js/path-injection]
220
+ const bundleContents = await readFileAsync(filePath, 'utf8');
221
+ const firstLineColumnOffset = additionalContextIsObject || supportModules ? MODULE_WRAP_FIRST_LINE_PREFIX_LENGTH : 0;
222
+ const preloadedSourceMap = await (0, vmSourceMapSupport_js_1.preloadSourceMapJsonForBundle)(filePath, bundleContents);
223
+ const currentSourceMapRegistration = (0, vmSourceMapSupport_js_1.registerBundleForSourceMaps)(filePath, firstLineColumnOffset, bundleContents, preloadedSourceMap.sourceMapJson, preloadedSourceMap.retryMissingSourceMap);
224
+ sourceMapRegistration = currentSourceMapRegistration;
225
+ // Host callback used by the in-VM `Error.prepareStackTrace` hook (see
226
+ // vmSourceMapSupport.ts) to remap bundle stack frames to original
227
+ // TS/JS sources. Only resolves positions for registered bundle paths.
228
+ const contextObject = {
229
+ sharedConsoleHistory,
230
+ [vmSourceMapSupport_js_1.SOURCE_MAP_LOOKUP_ATTEMPT_CONTEXT_KEY]: vmSourceMapSupport_js_1.createSourceMapLookupAttempt,
231
+ [vmSourceMapSupport_js_1.SOURCE_MAP_RESOLVER_CONTEXT_KEY]: (fileName, lineNumber, columnNumber, lookupAttempt) => (0, vmSourceMapSupport_js_1.resolveOriginalPositionForRegistration)(currentSourceMapRegistration, fileName, lineNumber, columnNumber, lookupAttempt),
232
+ [vmSourceMapSupport_js_1.SOURCE_MAP_STACK_REMAPPER_CONTEXT_KEY]: (stack) => (0, vmSourceMapSupport_js_1.remapStackTrace)(stack, currentSourceMapRegistration),
233
+ };
148
234
  if (supportModules) {
149
235
  // IMPORTANT: When adding anything to this object, update:
150
236
  // 1. docs/oss/building-features/node-renderer/js-configuration.md
@@ -217,20 +303,29 @@ async function buildVM(filePath) {
217
303
  vm_1.default.runInContext(`function clearImmediate() {}`, context);
218
304
  vm_1.default.runInContext(`function queueMicrotask() {}`, context);
219
305
  }
220
- // Run bundle code in created context:
221
- const bundleContents = await readFileAsync(filePath, 'utf8');
306
+ // Install lazy source-mapped stack traces for errors created inside the
307
+ // VM. Must run before the bundle is evaluated so the bundle's own error
308
+ // handling (e.g. react-on-rails `handleError`) sees remapped stacks.
309
+ vm_1.default.runInContext(vmSourceMapSupport_js_1.PREPARE_STACK_TRACE_INSTALL_SCRIPT, context);
310
+ const installedPrepareStackTrace = readPrepareStackTraceHook(context);
222
311
  // If node-specific code is provided then it must be wrapped into a module wrapper. The bundle
223
312
  // may need the `require` function, which is not available when running in vm unless passed in.
313
+ // Pass `filename` so stack frames point at the real bundle path (instead of
314
+ // `evalmachine.<anonymous>`), which also keys lazy source map resolution.
224
315
  if (additionalContextIsObject || supportModules) {
225
- vm_1.default.runInContext(module_1.default.wrap(bundleContents), context)(exports, require, module, filePath, path_1.default.dirname(filePath));
316
+ vm_1.default.runInContext(module_1.default.wrap(bundleContents), context, { filename: filePath })(exports, require, module, filePath, path_1.default.dirname(filePath));
226
317
  }
227
318
  else {
228
- vm_1.default.runInContext(bundleContents, context);
319
+ vm_1.default.runInContext(bundleContents, context, { filename: filePath });
320
+ }
321
+ if (readPrepareStackTraceHook(context) !== installedPrepareStackTrace) {
322
+ log_js_1.default.warn('Bundle replaced Error.prepareStackTrace; source-mapped stack traces are disabled for bundle %s', filePath);
229
323
  }
230
324
  // Only now, after VM is fully initialized, store the context
231
325
  const newVmContext = {
232
326
  context,
233
327
  sharedConsoleHistory,
328
+ sourceMapRegistration: currentSourceMapRegistration,
234
329
  lastUsed: Date.now(),
235
330
  };
236
331
  vmContexts.set(filePath, newVmContext);
@@ -247,8 +342,18 @@ async function buildVM(filePath) {
247
342
  return newVmContext;
248
343
  }
249
344
  catch (error) {
345
+ // Materialize/remap the stack before reporting so failed bundle builds
346
+ // still include original source locations, then retire the registration:
347
+ // failed builds never enter the VM pool and cannot be reused.
348
+ (0, vmSourceMapSupport_js_1.remapErrorStack)(error, sourceMapRegistration);
250
349
  log_js_1.default.error({ error }, 'Caught Error when creating context in buildVM');
251
350
  errorReporter.error(error);
351
+ if (sourceMapRegistration) {
352
+ (0, vmSourceMapSupport_js_1.unregisterBundleForSourceMaps)(sourceMapRegistration);
353
+ }
354
+ else {
355
+ (0, vmSourceMapSupport_js_1.unregisterBundleForSourceMaps)(filePath);
356
+ }
252
357
  throw error;
253
358
  }
254
359
  })();
@@ -305,23 +410,53 @@ async function getOrBuildVMContext(bundleFilePath, buildVmsIfNeeded) {
305
410
  * @see handleIncrementalRenderRequest.ts for how update chunks access the same context
306
411
  */
307
412
  async function buildExecutionContext(bundlePaths, buildVmsIfNeeded) {
413
+ const retainedSourceMapRegistrations = new Set();
414
+ const retainSourceMapRegistrationOnce = (sourceMapRegistration) => {
415
+ if (retainedSourceMapRegistrations.has(sourceMapRegistration)) {
416
+ return;
417
+ }
418
+ retainSourceMapRegistration(sourceMapRegistration);
419
+ retainedSourceMapRegistrations.add(sourceMapRegistration);
420
+ };
308
421
  const mapBundleFilePathToVMContext = new Map();
309
- await Promise.all(bundlePaths.map(async (bundleFilePath) => {
310
- const vmContext = await getOrBuildVMContext(bundleFilePath, buildVmsIfNeeded);
311
- vmContext.lastUsed = Date.now();
312
- mapBundleFilePathToVMContext.set(bundleFilePath, vmContext);
422
+ let buildRejected = false;
423
+ let firstBuildRejection;
424
+ // Wait for every parallel build callback before releasing retained source-map
425
+ // registrations; otherwise a sibling build can retain after an early rejection.
426
+ await Promise.allSettled(bundlePaths.map(async (bundleFilePath) => {
427
+ try {
428
+ const vmContext = await getOrBuildVMContext(bundleFilePath, buildVmsIfNeeded);
429
+ retainSourceMapRegistrationOnce(vmContext.sourceMapRegistration);
430
+ vmContext.lastUsed = Date.now();
431
+ mapBundleFilePathToVMContext.set(bundleFilePath, vmContext);
432
+ }
433
+ catch (error) {
434
+ if (!buildRejected) {
435
+ buildRejected = true;
436
+ firstBuildRejection = error;
437
+ }
438
+ throw error;
439
+ }
313
440
  }));
441
+ if (buildRejected) {
442
+ retainedSourceMapRegistrations.forEach(releaseSourceMapRegistration);
443
+ throw firstBuildRejection;
444
+ }
314
445
  // This Map persists for the lifetime of this ExecutionContext (one HTTP request).
315
446
  // It allows data to be shared between the initial render and subsequent update chunks.
316
447
  // Example: asyncPropsManager is stored here during initial render and accessed by update chunks.
317
448
  const sharedExecutionContext = new Map();
449
+ let released = false;
318
450
  const runInVM = async (renderingRequest, bundleFilePath, vmCluster) => {
451
+ let sourceMapRegistrationForRequest;
319
452
  try {
320
453
  const { serverBundleCachePath } = (0, configBuilder_js_1.getConfig)();
321
454
  const vmContext = mapBundleFilePathToVMContext.get(bundleFilePath);
322
455
  if (!vmContext) {
323
456
  throw new VMContextNotFoundError(bundleFilePath);
324
457
  }
458
+ sourceMapRegistrationForRequest = vmContext.sourceMapRegistration;
459
+ const remapStackTraceForRequest = (stack) => (0, vmSourceMapSupport_js_1.remapStackTrace)(stack, vmContext.sourceMapRegistration);
325
460
  // Update last used timestamp
326
461
  vmContext.lastUsed = Date.now();
327
462
  const { context, sharedConsoleHistory } = vmContext;
@@ -361,7 +496,7 @@ async function buildExecutionContext(bundlePaths, buildVmsIfNeeded) {
361
496
  });
362
497
  if ((0, utils_js_1.isReadableStream)(result)) {
363
498
  const newStreamAfterHandlingError = (0, utils_js_1.handleStreamError)(result, (error) => {
364
- const msg = (0, utils_js_1.formatExceptionMessage)({ renderingRequest }, error, 'Error in a rendering stream');
499
+ const msg = (0, utils_js_1.formatExceptionMessage)({ renderingRequest }, error, 'Error in a rendering stream', remapStackTraceForRequest);
365
500
  errorReporter.message(msg);
366
501
  });
367
502
  return newStreamAfterHandlingError;
@@ -382,7 +517,9 @@ async function buildExecutionContext(bundlePaths, buildVmsIfNeeded) {
382
517
  return result;
383
518
  }
384
519
  catch (exception) {
385
- const exceptionMessage = (0, utils_js_1.formatExceptionMessage)({ renderingRequest }, exception);
520
+ const exceptionMessage = (0, utils_js_1.formatExceptionMessage)({ renderingRequest }, exception, undefined, sourceMapRegistrationForRequest
521
+ ? (stack) => (0, vmSourceMapSupport_js_1.remapStackTrace)(stack, sourceMapRegistrationForRequest)
522
+ : (_stack) => undefined);
386
523
  log_js_1.default.debug('Caught exception in rendering request: %s', exceptionMessage);
387
524
  return Promise.resolve({ exceptionMessage });
388
525
  }
@@ -390,19 +527,36 @@ async function buildExecutionContext(bundlePaths, buildVmsIfNeeded) {
390
527
  return {
391
528
  getVMContext: (bundleFilePath) => mapBundleFilePathToVMContext.get(bundleFilePath),
392
529
  runInVM,
530
+ release: () => {
531
+ if (released) {
532
+ return;
533
+ }
534
+ released = true;
535
+ retainedSourceMapRegistrations.forEach(releaseSourceMapRegistration);
536
+ },
393
537
  };
394
538
  }
395
539
  /** @internal Used in tests */
396
540
  function resetVM() {
397
541
  vmContexts.clear();
398
542
  vmCreationPromises.clear();
543
+ activeSourceMapRequestCounts.clear();
544
+ evictedSourceMapRegistrations.clear();
545
+ (0, vmSourceMapSupport_js_1.resetSourceMapSupport)();
399
546
  }
400
547
  // Optional: Add a method to remove a specific VM if needed
401
548
  /**
402
549
  * @public TODO: Remove the line below when this function is actually used
403
550
  */
404
551
  function removeVM(bundlePath) {
552
+ const vmContext = vmContexts.get(bundlePath);
405
553
  vmContexts.delete(bundlePath);
406
554
  vmCreationPromises.delete(bundlePath);
555
+ if (vmContext) {
556
+ retireSourceMapRegistrationAfterEviction(vmContext.sourceMapRegistration);
557
+ }
558
+ else {
559
+ (0, vmSourceMapSupport_js_1.unregisterBundleForSourceMaps)(bundlePath);
560
+ }
407
561
  }
408
562
  //# sourceMappingURL=vm.js.map
@@ -0,0 +1,110 @@
1
+ export interface BundleSourceMapRegistration {
2
+ bundleFilePath: string;
3
+ /**
4
+ * Column correction for frames on line 1 of the bundle. When the bundle is
5
+ * evaluated wrapped in `Module.wrap` (the `supportModules` /
6
+ * `additionalContext` path), the wrapper prefix shifts every first-line
7
+ * column by its length.
8
+ */
9
+ firstLineColumnOffset: number;
10
+ /**
11
+ * `undefined` means the bundle text was not available at registration time
12
+ * and must be checked lazily. `null` means it was checked and no
13
+ * sourceMappingURL comment was present.
14
+ */
15
+ sourceMappingUrl?: string | null;
16
+ /**
17
+ * `undefined` keeps lazy synchronous lookup behavior. `null` means registration
18
+ * time lookup found no usable source map. A string freezes the source-map JSON
19
+ * for this VM generation so same-path rebuilds cannot remap old bytecode with
20
+ * a newer map.
21
+ */
22
+ sourceMapJson?: string | null;
23
+ realBundleDirectory: string;
24
+ /**
25
+ * External source maps can arrive after a bundle first becomes visible. When
26
+ * true, a missing external map is retried briefly before caching the miss.
27
+ */
28
+ retryMissingSourceMap?: boolean;
29
+ }
30
+ interface SourceMapLookupAttempt {
31
+ missingSourceMaps: WeakSet<BundleSourceMapRegistration>;
32
+ }
33
+ export declare function retireMissingSourceMapRetry(registration: BundleSourceMapRegistration): void;
34
+ export declare function createSourceMapLookupAttempt(): SourceMapLookupAttempt;
35
+ /**
36
+ * Name of the host-callback global injected into the VM context. Used by
37
+ * {@link PREPARE_STACK_TRACE_INSTALL_SCRIPT}.
38
+ */
39
+ export declare const SOURCE_MAP_RESOLVER_CONTEXT_KEY = "__reactOnRailsProResolveOriginalSourcePosition";
40
+ /**
41
+ * Name of the host-callback global used to group resolver calls that belong to
42
+ * one `.stack` formatting attempt.
43
+ */
44
+ export declare const SOURCE_MAP_LOOKUP_ATTEMPT_CONTEXT_KEY = "__reactOnRailsProCreateSourceMapLookupAttempt";
45
+ /**
46
+ * Name of the host-callback global injected into the VM context for stacks
47
+ * serialized by react-on-rails before they can escape to the host formatter.
48
+ */
49
+ export declare const SOURCE_MAP_STACK_REMAPPER_CONTEXT_KEY = "__reactOnRailsProRemapStackTrace";
50
+ /** @internal Used by VM build to avoid synchronous external-map reads. */
51
+ export declare function preloadSourceMapJsonForBundle(bundleFilePath: string, bundleContents: string): Promise<{
52
+ retryMissingSourceMap: boolean;
53
+ sourceMapJson: string | null;
54
+ } | {
55
+ retryMissingSourceMap: boolean;
56
+ sourceMapJson: string | undefined;
57
+ }>;
58
+ /**
59
+ * Registers a bundle file so stack frames pointing into it can be remapped.
60
+ * Pass `bundleContents` when available; omitting it makes the first error-path
61
+ * lookup synchronously re-read the bundle to find its `sourceMappingURL`.
62
+ * `preloadedSourceMapJson` supplies known JSON/null for this VM generation;
63
+ * `retryMissingSourceMap` keeps external preload misses retryable until a map is
64
+ * found, the retry cap is reached, or a same-path generation replaces the registration.
65
+ */
66
+ export declare function registerBundleForSourceMaps(bundleFilePath: string, firstLineColumnOffset?: number, bundleContents?: string, preloadedSourceMapJson?: string | null, retryMissingSourceMap?: boolean): {
67
+ bundleFilePath: string;
68
+ firstLineColumnOffset: number;
69
+ realBundleDirectory: string;
70
+ sourceMappingUrl: string | null | undefined;
71
+ sourceMapJson: string | null | undefined;
72
+ retryMissingSourceMap: boolean;
73
+ };
74
+ /**
75
+ * Drops the registration and any cached source map for a bundle.
76
+ */
77
+ export declare function unregisterBundleForSourceMaps(bundleOrRegistration: string | BundleSourceMapRegistration): void;
78
+ /** @internal Used in tests */
79
+ export declare function resetSourceMapSupport(): void;
80
+ export interface ResolvedSourcePosition {
81
+ source: string;
82
+ line: number;
83
+ column: number;
84
+ }
85
+ /**
86
+ * Resolves a 1-based generated position in a registered bundle to its original
87
+ * source position. Returns null when the position cannot be mapped.
88
+ *
89
+ * SECURITY: this function is exposed to untrusted bundle code inside the VM
90
+ * context, so it validates its inputs and only operates on registered bundle
91
+ * paths.
92
+ *
93
+ * @param lineNumber 1-based generated line number, matching V8 CallSite values.
94
+ * @param columnNumber 1-based generated column number, matching V8 CallSite values.
95
+ */
96
+ export declare function resolveOriginalPositionForRegistration(registration: BundleSourceMapRegistration, fileName: unknown, lineNumber: unknown, columnNumber: unknown, lookupAttempt?: unknown): ResolvedSourcePosition | null;
97
+ export declare function remapStackTrace(stack: unknown, registration?: BundleSourceMapRegistration): string | undefined;
98
+ export declare function remapErrorStack(error: unknown, registration?: BundleSourceMapRegistration): void;
99
+ /**
100
+ * Script run inside the VM context (before the bundle is evaluated) that
101
+ * installs an `Error.prepareStackTrace` mirroring V8's default format but
102
+ * rewriting `file:line:column` locations through the host-side resolver when a
103
+ * source-mapped position is available. Bundle code can replace
104
+ * `Error.prepareStackTrace` after this script runs; if it does, source mapping
105
+ * is disabled for that VM context. Any failure falls back to the original frame
106
+ * text.
107
+ */
108
+ export declare const PREPARE_STACK_TRACE_INSTALL_SCRIPT = "\nError.prepareStackTrace = function (error, callSites) {\n var header;\n try {\n header = String(error);\n } catch (formatError) {\n header = '<error>';\n }\n var parts = [header];\n var sourceMapLookupAttempt;\n try {\n if (typeof __reactOnRailsProCreateSourceMapLookupAttempt === 'function') {\n sourceMapLookupAttempt = __reactOnRailsProCreateSourceMapLookupAttempt();\n }\n } catch (lookupAttemptError) {\n sourceMapLookupAttempt = undefined;\n }\n for (var i = 0; i < callSites.length; i++) {\n var frameText;\n try {\n frameText = String(callSites[i]);\n } catch (formatFrameError) {\n frameText = '<frame>';\n }\n try {\n var fileName = callSites[i].getFileName();\n var line = callSites[i].getLineNumber();\n var column = callSites[i].getColumnNumber();\n if (\n fileName != null &&\n line != null &&\n column != null &&\n typeof __reactOnRailsProResolveOriginalSourcePosition === 'function'\n ) {\n var position = __reactOnRailsProResolveOriginalSourcePosition(fileName, line, column, sourceMapLookupAttempt);\n if (position) {\n var generatedLocation = fileName + ':' + line + ':' + column;\n var originalLocation = position.source + ':' + position.line + ':' + position.column;\n if (frameText.indexOf(generatedLocation) !== -1) {\n // String first-arg: replace only the frame's canonical location once.\n // Do not use a /g regex here; a repeated numeric location elsewhere\n // in the frame text should not be rewritten.\n frameText = frameText.replace(generatedLocation, function () { return originalLocation; });\n } else {\n frameText = frameText + ' -> ' + originalLocation;\n }\n }\n }\n } catch (resolveError) {\n // Keep the original frame text.\n }\n parts.push(' at ' + frameText);\n }\n return parts.join('\\n');\n};\n";
109
+ export {};
110
+ //# sourceMappingURL=vmSourceMapSupport.d.ts.map