@sentry/wasm 10.37.0 → 10.39.0-alpha.0

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.
@@ -6,6 +6,20 @@ const registry = require('./registry.js');
6
6
 
7
7
  const INTEGRATION_NAME = 'Wasm';
8
8
 
9
+ // We use the same prefix as bundler plugins so that thirdPartyErrorFilterIntegration
10
+ // recognizes WASM frames as first-party code without needing modifications.
11
+ const BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';
12
+
13
+ /**
14
+ * Minimal interface for DedicatedWorkerGlobalScope.
15
+ * We can't use the actual type because it breaks everyone who doesn't have {"lib": ["WebWorker"]}
16
+ */
17
+
18
+ // Access WINDOW with proper typing for _sentryWasmImages
19
+ const WINDOW = core.GLOBAL_OBJ
20
+
21
+ ;
22
+
9
23
  const _wasmIntegration = ((options = {}) => {
10
24
  return {
11
25
  name: INTEGRATION_NAME,
@@ -15,18 +29,23 @@ const _wasmIntegration = ((options = {}) => {
15
29
  processEvent(event) {
16
30
  let hasAtLeastOneWasmFrameWithImage = false;
17
31
 
32
+ const existingImagesCount = event.debug_meta?.images?.length || 0;
33
+
18
34
  if (event.exception?.values) {
19
35
  event.exception.values.forEach(exception => {
20
36
  if (exception.stacktrace?.frames) {
21
37
  hasAtLeastOneWasmFrameWithImage =
22
- hasAtLeastOneWasmFrameWithImage || patchFrames(exception.stacktrace.frames, options.applicationKey);
38
+ hasAtLeastOneWasmFrameWithImage ||
39
+ patchFrames(exception.stacktrace.frames, options.applicationKey, existingImagesCount);
23
40
  }
24
41
  });
25
42
  }
26
43
 
27
44
  if (hasAtLeastOneWasmFrameWithImage) {
28
45
  event.debug_meta = event.debug_meta || {};
29
- event.debug_meta.images = [...(event.debug_meta.images || []), ...registry.getImages()];
46
+ const mainThreadImages = registry.getImages();
47
+ const workerImages = WINDOW._sentryWasmImages || [];
48
+ event.debug_meta.images = [...(event.debug_meta.images || []), ...mainThreadImages, ...workerImages];
30
49
  }
31
50
 
32
51
  return event;
@@ -38,17 +57,22 @@ const wasmIntegration = core.defineIntegration(_wasmIntegration);
38
57
 
39
58
  const PARSER_REGEX = /^(.*?):wasm-function\[\d+\]:(0x[a-fA-F0-9]+)$/;
40
59
 
41
- // We use the same prefix as bundler plugins so that thirdPartyErrorFilterIntegration
42
- // recognizes WASM frames as first-party code without needing modifications.
43
- const BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';
44
-
45
60
  /**
46
61
  * Patches a list of stackframes with wasm data needed for server-side symbolication
47
62
  * if applicable. Returns true if the provided list of stack frames had at least one
48
63
  * matching registered image.
64
+ *
65
+ * @param frames - Stack frames to patch
66
+ * @param applicationKey - Optional key for third-party error filtering
67
+ * @param existingImagesOffset - Number of existing debug images that will be prepended
68
+ * to the final images array (used to calculate correct addr_mode indices)
49
69
  */
50
70
  // Only exported for tests
51
- function patchFrames(frames, applicationKey) {
71
+ function patchFrames(
72
+ frames,
73
+ applicationKey,
74
+ existingImagesOffset = 0,
75
+ ) {
52
76
  let hasAtLeastOneWasmFrameWithImage = false;
53
77
  frames.forEach(frame => {
54
78
  if (!frame.filename) {
@@ -72,6 +96,7 @@ function patchFrames(frames, applicationKey) {
72
96
 
73
97
  if (match) {
74
98
  const index = registry.getImage(match[1]);
99
+ const workerImageIndex = getWorkerImage(match[1]);
75
100
  frame.instruction_addr = match[2];
76
101
  frame.filename = match[1];
77
102
  frame.platform = 'native';
@@ -84,7 +109,11 @@ function patchFrames(frames, applicationKey) {
84
109
  }
85
110
 
86
111
  if (index >= 0) {
87
- frame.addr_mode = `rel:${index}`;
112
+ frame.addr_mode = `rel:${existingImagesOffset + index}`;
113
+ hasAtLeastOneWasmFrameWithImage = true;
114
+ } else if (workerImageIndex >= 0) {
115
+ const mainThreadImagesCount = registry.getImages().length;
116
+ frame.addr_mode = `rel:${existingImagesOffset + mainThreadImagesCount + workerImageIndex}`;
88
117
  hasAtLeastOneWasmFrameWithImage = true;
89
118
  }
90
119
  }
@@ -93,6 +122,88 @@ function patchFrames(frames, applicationKey) {
93
122
  return hasAtLeastOneWasmFrameWithImage;
94
123
  }
95
124
 
125
+ /**
126
+ * Looks up an image by URL in worker images.
127
+ */
128
+ function getWorkerImage(url) {
129
+ const workerImages = WINDOW._sentryWasmImages || [];
130
+ return workerImages.findIndex(image => {
131
+ return image.type === 'wasm' && image.code_file === url;
132
+ });
133
+ }
134
+
135
+ /**
136
+ * Use this function to register WASM support in a web worker.
137
+ *
138
+ * This function will:
139
+ * - Patch WebAssembly.instantiateStreaming and WebAssembly.compileStreaming in the worker
140
+ * - Forward WASM debug images to the parent thread for symbolication
141
+ *
142
+ * @param options {RegisterWebWorkerWasmOptions} Options:
143
+ * - `self`: The worker's global scope (self).
144
+ */
145
+ function registerWebWorkerWasm({ self }) {
146
+ patchWebAssemblyWithForwarding(self);
147
+ }
148
+
149
+ /**
150
+ * Patches the WebAssembly object in the worker scope and forwards
151
+ * registered modules to the parent thread.
152
+ */
153
+ function patchWebAssemblyWithForwarding(workerSelf) {
154
+ if ('instantiateStreaming' in WebAssembly) {
155
+ const origInstantiateStreaming = WebAssembly.instantiateStreaming;
156
+ WebAssembly.instantiateStreaming = function instantiateStreaming(
157
+ response,
158
+ importObject,
159
+ ) {
160
+ return Promise.resolve(response).then(response => {
161
+ return origInstantiateStreaming(response, importObject).then(rv => {
162
+ if (response.url) {
163
+ registerModuleAndForward(rv.module, response.url, workerSelf);
164
+ }
165
+ return rv;
166
+ });
167
+ });
168
+ } ;
169
+ }
170
+
171
+ if ('compileStreaming' in WebAssembly) {
172
+ const origCompileStreaming = WebAssembly.compileStreaming;
173
+ WebAssembly.compileStreaming = function compileStreaming(
174
+ source,
175
+ ) {
176
+ return Promise.resolve(source).then(response => {
177
+ return origCompileStreaming(response).then(module => {
178
+ if (response.url) {
179
+ registerModuleAndForward(module, response.url, workerSelf);
180
+ }
181
+ return module;
182
+ });
183
+ });
184
+ } ;
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Registers a WASM module and forwards its debug image to the parent thread.
190
+ */
191
+ function registerModuleAndForward(
192
+ module,
193
+ url,
194
+ workerSelf,
195
+ ) {
196
+ const image = registry.registerModule(module, url);
197
+
198
+ if (image) {
199
+ workerSelf.postMessage({
200
+ _sentryMessage: true,
201
+ _sentryWasmImages: [image],
202
+ });
203
+ }
204
+ }
205
+
96
206
  exports.patchFrames = patchFrames;
207
+ exports.registerWebWorkerWasm = registerWebWorkerWasm;
97
208
  exports.wasmIntegration = wasmIntegration;
98
209
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/index.ts"],"sourcesContent":["import type { Event, IntegrationFn, StackFrame } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { patchWebAssembly } from './patchWebAssembly';\nimport { getImage, getImages } from './registry';\n\nconst INTEGRATION_NAME = 'Wasm';\n\ninterface WasmIntegrationOptions {\n /**\n * Key to identify this application for third-party error filtering.\n * This key should match one of the keys provided to the `filterKeys` option\n * of the `thirdPartyErrorFilterIntegration`.\n */\n applicationKey?: string;\n}\n\nconst _wasmIntegration = ((options: WasmIntegrationOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n patchWebAssembly();\n },\n processEvent(event: Event): Event {\n let hasAtLeastOneWasmFrameWithImage = false;\n\n if (event.exception?.values) {\n event.exception.values.forEach(exception => {\n if (exception.stacktrace?.frames) {\n hasAtLeastOneWasmFrameWithImage =\n hasAtLeastOneWasmFrameWithImage || patchFrames(exception.stacktrace.frames, options.applicationKey);\n }\n });\n }\n\n if (hasAtLeastOneWasmFrameWithImage) {\n event.debug_meta = event.debug_meta || {};\n event.debug_meta.images = [...(event.debug_meta.images || []), ...getImages()];\n }\n\n return event;\n },\n };\n}) satisfies IntegrationFn;\n\nexport const wasmIntegration = defineIntegration(_wasmIntegration);\n\nconst PARSER_REGEX = /^(.*?):wasm-function\\[\\d+\\]:(0x[a-fA-F0-9]+)$/;\n\n// We use the same prefix as bundler plugins so that thirdPartyErrorFilterIntegration\n// recognizes WASM frames as first-party code without needing modifications.\nconst BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';\n\n/**\n * Patches a list of stackframes with wasm data needed for server-side symbolication\n * if applicable. Returns true if the provided list of stack frames had at least one\n * matching registered image.\n */\n// Only exported for tests\nexport function patchFrames(frames: Array<StackFrame>, applicationKey?: string): boolean {\n let hasAtLeastOneWasmFrameWithImage = false;\n frames.forEach(frame => {\n if (!frame.filename) {\n return;\n }\n\n const split = frame.filename.split('(');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSplit = split[split.length - 1]!;\n\n // Let's call this first match a \"messy match\".\n // The browser stacktrace parser spits out frames that have a filename like this: \"int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb\"\n // It contains some leftover mess because wasm stack frames are more complicated than our parser can handle: \"at MyClass::bar(int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb)\"\n // This first match simply tries to mitigate the mess up until the first opening parens.\n // The match afterwards is a sensible fallback\n let match = lastSplit.match(PARSER_REGEX) as null | [string, string, string];\n\n if (!match) {\n match = frame.filename.match(PARSER_REGEX) as null | [string, string, string];\n }\n\n if (match) {\n const index = getImage(match[1]);\n frame.instruction_addr = match[2];\n frame.filename = match[1];\n frame.platform = 'native';\n\n if (applicationKey) {\n frame.module_metadata = {\n ...frame.module_metadata,\n [`${BUNDLER_PLUGIN_APP_KEY_PREFIX}${applicationKey}`]: true,\n };\n }\n\n if (index >= 0) {\n frame.addr_mode = `rel:${index}`;\n hasAtLeastOneWasmFrameWithImage = true;\n }\n }\n });\n\n return hasAtLeastOneWasmFrameWithImage;\n}\n"],"names":["patchWebAssembly","getImages","defineIntegration","getImage"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/index.ts"],"sourcesContent":["import type { DebugImage, Event, IntegrationFn, StackFrame } from '@sentry/core';\nimport { defineIntegration, GLOBAL_OBJ } from '@sentry/core';\nimport { patchWebAssembly } from './patchWebAssembly';\nimport { getImage, getImages, registerModule } from './registry';\n\nconst INTEGRATION_NAME = 'Wasm';\n\n// We use the same prefix as bundler plugins so that thirdPartyErrorFilterIntegration\n// recognizes WASM frames as first-party code without needing modifications.\nconst BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';\n\n/**\n * Minimal interface for DedicatedWorkerGlobalScope.\n * We can't use the actual type because it breaks everyone who doesn't have {\"lib\": [\"WebWorker\"]}\n */\ninterface MinimalDedicatedWorkerGlobalScope {\n postMessage: (message: unknown) => void;\n}\n\ninterface RegisterWebWorkerWasmOptions {\n self: MinimalDedicatedWorkerGlobalScope;\n}\n\ninterface WasmIntegrationOptions {\n /**\n * Key to identify this application for third-party error filtering.\n * This key should match one of the keys provided to the `filterKeys` option\n * of the `thirdPartyErrorFilterIntegration`.\n */\n applicationKey?: string;\n}\n\n// Access WINDOW with proper typing for _sentryWasmImages\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n _sentryWasmImages?: Array<DebugImage>;\n};\n\nconst _wasmIntegration = ((options: WasmIntegrationOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n patchWebAssembly();\n },\n processEvent(event: Event): Event {\n let hasAtLeastOneWasmFrameWithImage = false;\n\n const existingImagesCount = event.debug_meta?.images?.length || 0;\n\n if (event.exception?.values) {\n event.exception.values.forEach(exception => {\n if (exception.stacktrace?.frames) {\n hasAtLeastOneWasmFrameWithImage =\n hasAtLeastOneWasmFrameWithImage ||\n patchFrames(exception.stacktrace.frames, options.applicationKey, existingImagesCount);\n }\n });\n }\n\n if (hasAtLeastOneWasmFrameWithImage) {\n event.debug_meta = event.debug_meta || {};\n const mainThreadImages = getImages();\n const workerImages = WINDOW._sentryWasmImages || [];\n event.debug_meta.images = [...(event.debug_meta.images || []), ...mainThreadImages, ...workerImages];\n }\n\n return event;\n },\n };\n}) satisfies IntegrationFn;\n\nexport const wasmIntegration = defineIntegration(_wasmIntegration);\n\nconst PARSER_REGEX = /^(.*?):wasm-function\\[\\d+\\]:(0x[a-fA-F0-9]+)$/;\n\n/**\n * Patches a list of stackframes with wasm data needed for server-side symbolication\n * if applicable. Returns true if the provided list of stack frames had at least one\n * matching registered image.\n *\n * @param frames - Stack frames to patch\n * @param applicationKey - Optional key for third-party error filtering\n * @param existingImagesOffset - Number of existing debug images that will be prepended\n * to the final images array (used to calculate correct addr_mode indices)\n */\n// Only exported for tests\nexport function patchFrames(\n frames: Array<StackFrame>,\n applicationKey?: string,\n existingImagesOffset: number = 0,\n): boolean {\n let hasAtLeastOneWasmFrameWithImage = false;\n frames.forEach(frame => {\n if (!frame.filename) {\n return;\n }\n\n const split = frame.filename.split('(');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSplit = split[split.length - 1]!;\n\n // Let's call this first match a \"messy match\".\n // The browser stacktrace parser spits out frames that have a filename like this: \"int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb\"\n // It contains some leftover mess because wasm stack frames are more complicated than our parser can handle: \"at MyClass::bar(int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb)\"\n // This first match simply tries to mitigate the mess up until the first opening parens.\n // The match afterwards is a sensible fallback\n let match = lastSplit.match(PARSER_REGEX) as null | [string, string, string];\n\n if (!match) {\n match = frame.filename.match(PARSER_REGEX) as null | [string, string, string];\n }\n\n if (match) {\n const index = getImage(match[1]);\n const workerImageIndex = getWorkerImage(match[1]);\n frame.instruction_addr = match[2];\n frame.filename = match[1];\n frame.platform = 'native';\n\n if (applicationKey) {\n frame.module_metadata = {\n ...frame.module_metadata,\n [`${BUNDLER_PLUGIN_APP_KEY_PREFIX}${applicationKey}`]: true,\n };\n }\n\n if (index >= 0) {\n frame.addr_mode = `rel:${existingImagesOffset + index}`;\n hasAtLeastOneWasmFrameWithImage = true;\n } else if (workerImageIndex >= 0) {\n const mainThreadImagesCount = getImages().length;\n frame.addr_mode = `rel:${existingImagesOffset + mainThreadImagesCount + workerImageIndex}`;\n hasAtLeastOneWasmFrameWithImage = true;\n }\n }\n });\n\n return hasAtLeastOneWasmFrameWithImage;\n}\n\n/**\n * Looks up an image by URL in worker images.\n */\nfunction getWorkerImage(url: string): number {\n const workerImages = WINDOW._sentryWasmImages || [];\n return workerImages.findIndex(image => {\n return image.type === 'wasm' && image.code_file === url;\n });\n}\n\n/**\n * Use this function to register WASM support in a web worker.\n *\n * This function will:\n * - Patch WebAssembly.instantiateStreaming and WebAssembly.compileStreaming in the worker\n * - Forward WASM debug images to the parent thread for symbolication\n *\n * @param options {RegisterWebWorkerWasmOptions} Options:\n * - `self`: The worker's global scope (self).\n */\nexport function registerWebWorkerWasm({ self }: RegisterWebWorkerWasmOptions): void {\n patchWebAssemblyWithForwarding(self);\n}\n\n/**\n * Patches the WebAssembly object in the worker scope and forwards\n * registered modules to the parent thread.\n */\nfunction patchWebAssemblyWithForwarding(workerSelf: MinimalDedicatedWorkerGlobalScope): void {\n if ('instantiateStreaming' in WebAssembly) {\n const origInstantiateStreaming = WebAssembly.instantiateStreaming;\n WebAssembly.instantiateStreaming = function instantiateStreaming(\n response: Response | PromiseLike<Response>,\n importObject: WebAssembly.Imports,\n ): Promise<WebAssembly.Module> {\n return Promise.resolve(response).then(response => {\n return origInstantiateStreaming(response, importObject).then(rv => {\n if (response.url) {\n registerModuleAndForward(rv.module, response.url, workerSelf);\n }\n return rv;\n });\n });\n } as typeof WebAssembly.instantiateStreaming;\n }\n\n if ('compileStreaming' in WebAssembly) {\n const origCompileStreaming = WebAssembly.compileStreaming;\n WebAssembly.compileStreaming = function compileStreaming(\n source: Response | Promise<Response>,\n ): Promise<WebAssembly.Module> {\n return Promise.resolve(source).then(response => {\n return origCompileStreaming(response).then(module => {\n if (response.url) {\n registerModuleAndForward(module, response.url, workerSelf);\n }\n return module;\n });\n });\n } as typeof WebAssembly.compileStreaming;\n }\n}\n\n/**\n * Registers a WASM module and forwards its debug image to the parent thread.\n */\nfunction registerModuleAndForward(\n module: WebAssembly.Module,\n url: string,\n workerSelf: MinimalDedicatedWorkerGlobalScope,\n): void {\n const image = registerModule(module, url);\n\n if (image) {\n workerSelf.postMessage({\n _sentryMessage: true,\n _sentryWasmImages: [image],\n });\n }\n}\n"],"names":["GLOBAL_OBJ","patchWebAssembly","getImages","defineIntegration","getImage","registerModule"],"mappings":"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"}
@@ -33,34 +33,39 @@ function getModuleInfo(module) {
33
33
  }
34
34
 
35
35
  /**
36
- * Records a module
36
+ * Records a module and returns the created debug image.
37
37
  */
38
38
  function registerModule(module, url) {
39
39
  const { buildId, debugFile } = getModuleInfo(module);
40
- if (buildId) {
41
- const oldIdx = getImage(url);
42
- if (oldIdx >= 0) {
43
- IMAGES.splice(oldIdx, 1);
44
- }
40
+ if (!buildId) {
41
+ return null;
42
+ }
45
43
 
46
- let debugFileUrl = null;
47
- if (debugFile) {
48
- try {
49
- debugFileUrl = new URL(debugFile, url).href;
50
- } catch {
51
- // debugFile could be a blob URL which causes the URL constructor to throw
52
- // for now we just ignore this case
53
- }
54
- }
44
+ const oldIdx = getImage(url);
45
+ if (oldIdx >= 0) {
46
+ IMAGES.splice(oldIdx, 1);
47
+ }
55
48
 
56
- IMAGES.push({
57
- type: 'wasm',
58
- code_id: buildId,
59
- code_file: url,
60
- debug_file: debugFileUrl,
61
- debug_id: `${buildId.padEnd(32, '0').slice(0, 32)}0`,
62
- });
49
+ let debugFileUrl = null;
50
+ if (debugFile) {
51
+ try {
52
+ debugFileUrl = new URL(debugFile, url).href;
53
+ } catch {
54
+ // debugFile could be a blob URL which causes the URL constructor to throw
55
+ // for now we just ignore this case
56
+ }
63
57
  }
58
+
59
+ const image = {
60
+ type: 'wasm',
61
+ code_id: buildId,
62
+ code_file: url,
63
+ debug_file: debugFileUrl,
64
+ debug_id: `${buildId.padEnd(32, '0').slice(0, 32)}0`,
65
+ };
66
+
67
+ IMAGES.push(image);
68
+ return image;
64
69
  }
65
70
 
66
71
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sources":["../../../src/registry.ts"],"sourcesContent":["import type { DebugImage } from '@sentry/core';\n\nexport const IMAGES: Array<DebugImage> = [];\n\nexport interface ModuleInfo {\n buildId: string | null;\n debugFile: string | null;\n}\n\n/**\n * Returns the extracted meta information from a web assembly module that\n * Sentry uses to identify debug images.\n *\n * @param module\n */\nexport function getModuleInfo(module: WebAssembly.Module): ModuleInfo {\n const buildIds = WebAssembly.Module.customSections(module, 'build_id');\n let buildId = null;\n let debugFile = null;\n\n const buildId0 = buildIds[0];\n if (buildId0) {\n const firstBuildId = new Uint8Array(buildId0);\n buildId = Array.from(firstBuildId).reduce((acc, x) => {\n return acc + x.toString(16).padStart(2, '0');\n }, '');\n }\n\n const externalDebugInfo = WebAssembly.Module.customSections(module, 'external_debug_info');\n const externalDebugInfo0 = externalDebugInfo[0];\n if (externalDebugInfo0) {\n const firstExternalDebugInfo = new Uint8Array(externalDebugInfo0);\n const decoder = new TextDecoder('utf-8');\n debugFile = decoder.decode(firstExternalDebugInfo);\n }\n\n return { buildId, debugFile };\n}\n\n/**\n * Records a module\n */\nexport function registerModule(module: WebAssembly.Module, url: string): void {\n const { buildId, debugFile } = getModuleInfo(module);\n if (buildId) {\n const oldIdx = getImage(url);\n if (oldIdx >= 0) {\n IMAGES.splice(oldIdx, 1);\n }\n\n let debugFileUrl = null;\n if (debugFile) {\n try {\n debugFileUrl = new URL(debugFile, url).href;\n } catch {\n // debugFile could be a blob URL which causes the URL constructor to throw\n // for now we just ignore this case\n }\n }\n\n IMAGES.push({\n type: 'wasm',\n code_id: buildId,\n code_file: url,\n debug_file: debugFileUrl,\n debug_id: `${buildId.padEnd(32, '0').slice(0, 32)}0`,\n });\n }\n}\n\n/**\n * Returns all known images.\n */\nexport function getImages(): Array<DebugImage> {\n return IMAGES;\n}\n\n/**\n * Looks up an image by URL.\n *\n * @param url the URL of the WebAssembly module.\n */\nexport function getImage(url: string): number {\n return IMAGES.findIndex(image => {\n return image.type === 'wasm' && image.code_file === url;\n });\n}\n"],"names":[],"mappings":";;AAEO,MAAM,MAAM,GAAsB;;AAOzC;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAC,MAAM,EAAkC;AACtE,EAAE,MAAM,QAAA,GAAW,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC;AACxE,EAAE,IAAI,OAAA,GAAU,IAAI;AACpB,EAAE,IAAI,SAAA,GAAY,IAAI;;AAEtB,EAAE,MAAM,QAAA,GAAW,QAAQ,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,QAAQ,EAAE;AAChB,IAAI,MAAM,YAAA,GAAe,IAAI,UAAU,CAAC,QAAQ,CAAC;AACjD,IAAI,UAAU,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK;AAC1D,MAAM,OAAO,GAAA,GAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAClD,IAAI,CAAC,EAAE,EAAE,CAAC;AACV,EAAE;;AAEF,EAAE,MAAM,iBAAA,GAAoB,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,qBAAqB,CAAC;AAC5F,EAAE,MAAM,kBAAA,GAAqB,iBAAiB,CAAC,CAAC,CAAC;AACjD,EAAE,IAAI,kBAAkB,EAAE;AAC1B,IAAI,MAAM,sBAAA,GAAyB,IAAI,UAAU,CAAC,kBAAkB,CAAC;AACrE,IAAI,MAAM,OAAA,GAAU,IAAI,WAAW,CAAC,OAAO,CAAC;AAC5C,IAAI,YAAY,OAAO,CAAC,MAAM,CAAC,sBAAsB,CAAC;AACtD,EAAE;;AAEF,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW;AAC/B;;AAEA;AACA;AACA;AACO,SAAS,cAAc,CAAC,MAAM,EAAsB,GAAG,EAAgB;AAC9E,EAAE,MAAM,EAAE,OAAO,EAAE,SAAA,KAAc,aAAa,CAAC,MAAM,CAAC;AACtD,EAAE,IAAI,OAAO,EAAE;AACf,IAAI,MAAM,MAAA,GAAS,QAAQ,CAAC,GAAG,CAAC;AAChC,IAAI,IAAI,MAAA,IAAU,CAAC,EAAE;AACrB,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,IAAI;;AAEJ,IAAI,IAAI,YAAA,GAAe,IAAI;AAC3B,IAAI,IAAI,SAAS,EAAE;AACnB,MAAM,IAAI;AACV,QAAQ,YAAA,GAAe,IAAI,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI;AACnD,MAAM,EAAE,MAAM;AACd;AACA;AACA,MAAM;AACN,IAAI;;AAEJ,IAAI,MAAM,CAAC,IAAI,CAAC;AAChB,MAAM,IAAI,EAAE,MAAM;AAClB,MAAM,OAAO,EAAE,OAAO;AACtB,MAAM,SAAS,EAAE,GAAG;AACpB,MAAM,UAAU,EAAE,YAAY;AAC9B,MAAM,QAAQ,EAAE,CAAC,EAAA,OAAA,CAAA,MAAA,CAAA,EAAA,EAAA,GAAA,CAAA,CAAA,KAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,SAAA,GAAA;AACA,EAAA,OAAA,MAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAA,QAAA,CAAA,GAAA,EAAA;AACA,EAAA,OAAA,MAAA,CAAA,SAAA,CAAA,KAAA,IAAA;AACA,IAAA,OAAA,KAAA,CAAA,IAAA,KAAA,MAAA,IAAA,KAAA,CAAA,SAAA,KAAA,GAAA;AACA,EAAA,CAAA,CAAA;AACA;;;;;;;;"}
1
+ {"version":3,"file":"registry.js","sources":["../../../src/registry.ts"],"sourcesContent":["import type { DebugImage } from '@sentry/core';\n\nexport const IMAGES: Array<DebugImage> = [];\n\nexport interface ModuleInfo {\n buildId: string | null;\n debugFile: string | null;\n}\n\n/**\n * Returns the extracted meta information from a web assembly module that\n * Sentry uses to identify debug images.\n *\n * @param module\n */\nexport function getModuleInfo(module: WebAssembly.Module): ModuleInfo {\n const buildIds = WebAssembly.Module.customSections(module, 'build_id');\n let buildId = null;\n let debugFile = null;\n\n const buildId0 = buildIds[0];\n if (buildId0) {\n const firstBuildId = new Uint8Array(buildId0);\n buildId = Array.from(firstBuildId).reduce((acc, x) => {\n return acc + x.toString(16).padStart(2, '0');\n }, '');\n }\n\n const externalDebugInfo = WebAssembly.Module.customSections(module, 'external_debug_info');\n const externalDebugInfo0 = externalDebugInfo[0];\n if (externalDebugInfo0) {\n const firstExternalDebugInfo = new Uint8Array(externalDebugInfo0);\n const decoder = new TextDecoder('utf-8');\n debugFile = decoder.decode(firstExternalDebugInfo);\n }\n\n return { buildId, debugFile };\n}\n\n/**\n * Records a module and returns the created debug image.\n */\nexport function registerModule(module: WebAssembly.Module, url: string): DebugImage | null {\n const { buildId, debugFile } = getModuleInfo(module);\n if (!buildId) {\n return null;\n }\n\n const oldIdx = getImage(url);\n if (oldIdx >= 0) {\n IMAGES.splice(oldIdx, 1);\n }\n\n let debugFileUrl = null;\n if (debugFile) {\n try {\n debugFileUrl = new URL(debugFile, url).href;\n } catch {\n // debugFile could be a blob URL which causes the URL constructor to throw\n // for now we just ignore this case\n }\n }\n\n const image: DebugImage = {\n type: 'wasm',\n code_id: buildId,\n code_file: url,\n debug_file: debugFileUrl,\n debug_id: `${buildId.padEnd(32, '0').slice(0, 32)}0`,\n };\n\n IMAGES.push(image);\n return image;\n}\n\n/**\n * Returns all known images.\n */\nexport function getImages(): Array<DebugImage> {\n return IMAGES;\n}\n\n/**\n * Looks up an image by URL.\n *\n * @param url the URL of the WebAssembly module.\n */\nexport function getImage(url: string): number {\n return IMAGES.findIndex(image => {\n return image.type === 'wasm' && image.code_file === url;\n });\n}\n"],"names":[],"mappings":"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"}
@@ -1,9 +1,23 @@
1
- import { defineIntegration } from '@sentry/core';
1
+ import { defineIntegration, GLOBAL_OBJ } from '@sentry/core';
2
2
  import { patchWebAssembly } from './patchWebAssembly.js';
3
- import { getImages, getImage } from './registry.js';
3
+ import { getImage, getImages, registerModule } from './registry.js';
4
4
 
5
5
  const INTEGRATION_NAME = 'Wasm';
6
6
 
7
+ // We use the same prefix as bundler plugins so that thirdPartyErrorFilterIntegration
8
+ // recognizes WASM frames as first-party code without needing modifications.
9
+ const BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';
10
+
11
+ /**
12
+ * Minimal interface for DedicatedWorkerGlobalScope.
13
+ * We can't use the actual type because it breaks everyone who doesn't have {"lib": ["WebWorker"]}
14
+ */
15
+
16
+ // Access WINDOW with proper typing for _sentryWasmImages
17
+ const WINDOW = GLOBAL_OBJ
18
+
19
+ ;
20
+
7
21
  const _wasmIntegration = ((options = {}) => {
8
22
  return {
9
23
  name: INTEGRATION_NAME,
@@ -13,18 +27,23 @@ const _wasmIntegration = ((options = {}) => {
13
27
  processEvent(event) {
14
28
  let hasAtLeastOneWasmFrameWithImage = false;
15
29
 
30
+ const existingImagesCount = event.debug_meta?.images?.length || 0;
31
+
16
32
  if (event.exception?.values) {
17
33
  event.exception.values.forEach(exception => {
18
34
  if (exception.stacktrace?.frames) {
19
35
  hasAtLeastOneWasmFrameWithImage =
20
- hasAtLeastOneWasmFrameWithImage || patchFrames(exception.stacktrace.frames, options.applicationKey);
36
+ hasAtLeastOneWasmFrameWithImage ||
37
+ patchFrames(exception.stacktrace.frames, options.applicationKey, existingImagesCount);
21
38
  }
22
39
  });
23
40
  }
24
41
 
25
42
  if (hasAtLeastOneWasmFrameWithImage) {
26
43
  event.debug_meta = event.debug_meta || {};
27
- event.debug_meta.images = [...(event.debug_meta.images || []), ...getImages()];
44
+ const mainThreadImages = getImages();
45
+ const workerImages = WINDOW._sentryWasmImages || [];
46
+ event.debug_meta.images = [...(event.debug_meta.images || []), ...mainThreadImages, ...workerImages];
28
47
  }
29
48
 
30
49
  return event;
@@ -36,17 +55,22 @@ const wasmIntegration = defineIntegration(_wasmIntegration);
36
55
 
37
56
  const PARSER_REGEX = /^(.*?):wasm-function\[\d+\]:(0x[a-fA-F0-9]+)$/;
38
57
 
39
- // We use the same prefix as bundler plugins so that thirdPartyErrorFilterIntegration
40
- // recognizes WASM frames as first-party code without needing modifications.
41
- const BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';
42
-
43
58
  /**
44
59
  * Patches a list of stackframes with wasm data needed for server-side symbolication
45
60
  * if applicable. Returns true if the provided list of stack frames had at least one
46
61
  * matching registered image.
62
+ *
63
+ * @param frames - Stack frames to patch
64
+ * @param applicationKey - Optional key for third-party error filtering
65
+ * @param existingImagesOffset - Number of existing debug images that will be prepended
66
+ * to the final images array (used to calculate correct addr_mode indices)
47
67
  */
48
68
  // Only exported for tests
49
- function patchFrames(frames, applicationKey) {
69
+ function patchFrames(
70
+ frames,
71
+ applicationKey,
72
+ existingImagesOffset = 0,
73
+ ) {
50
74
  let hasAtLeastOneWasmFrameWithImage = false;
51
75
  frames.forEach(frame => {
52
76
  if (!frame.filename) {
@@ -70,6 +94,7 @@ function patchFrames(frames, applicationKey) {
70
94
 
71
95
  if (match) {
72
96
  const index = getImage(match[1]);
97
+ const workerImageIndex = getWorkerImage(match[1]);
73
98
  frame.instruction_addr = match[2];
74
99
  frame.filename = match[1];
75
100
  frame.platform = 'native';
@@ -82,7 +107,11 @@ function patchFrames(frames, applicationKey) {
82
107
  }
83
108
 
84
109
  if (index >= 0) {
85
- frame.addr_mode = `rel:${index}`;
110
+ frame.addr_mode = `rel:${existingImagesOffset + index}`;
111
+ hasAtLeastOneWasmFrameWithImage = true;
112
+ } else if (workerImageIndex >= 0) {
113
+ const mainThreadImagesCount = getImages().length;
114
+ frame.addr_mode = `rel:${existingImagesOffset + mainThreadImagesCount + workerImageIndex}`;
86
115
  hasAtLeastOneWasmFrameWithImage = true;
87
116
  }
88
117
  }
@@ -91,5 +120,86 @@ function patchFrames(frames, applicationKey) {
91
120
  return hasAtLeastOneWasmFrameWithImage;
92
121
  }
93
122
 
94
- export { patchFrames, wasmIntegration };
123
+ /**
124
+ * Looks up an image by URL in worker images.
125
+ */
126
+ function getWorkerImage(url) {
127
+ const workerImages = WINDOW._sentryWasmImages || [];
128
+ return workerImages.findIndex(image => {
129
+ return image.type === 'wasm' && image.code_file === url;
130
+ });
131
+ }
132
+
133
+ /**
134
+ * Use this function to register WASM support in a web worker.
135
+ *
136
+ * This function will:
137
+ * - Patch WebAssembly.instantiateStreaming and WebAssembly.compileStreaming in the worker
138
+ * - Forward WASM debug images to the parent thread for symbolication
139
+ *
140
+ * @param options {RegisterWebWorkerWasmOptions} Options:
141
+ * - `self`: The worker's global scope (self).
142
+ */
143
+ function registerWebWorkerWasm({ self }) {
144
+ patchWebAssemblyWithForwarding(self);
145
+ }
146
+
147
+ /**
148
+ * Patches the WebAssembly object in the worker scope and forwards
149
+ * registered modules to the parent thread.
150
+ */
151
+ function patchWebAssemblyWithForwarding(workerSelf) {
152
+ if ('instantiateStreaming' in WebAssembly) {
153
+ const origInstantiateStreaming = WebAssembly.instantiateStreaming;
154
+ WebAssembly.instantiateStreaming = function instantiateStreaming(
155
+ response,
156
+ importObject,
157
+ ) {
158
+ return Promise.resolve(response).then(response => {
159
+ return origInstantiateStreaming(response, importObject).then(rv => {
160
+ if (response.url) {
161
+ registerModuleAndForward(rv.module, response.url, workerSelf);
162
+ }
163
+ return rv;
164
+ });
165
+ });
166
+ } ;
167
+ }
168
+
169
+ if ('compileStreaming' in WebAssembly) {
170
+ const origCompileStreaming = WebAssembly.compileStreaming;
171
+ WebAssembly.compileStreaming = function compileStreaming(
172
+ source,
173
+ ) {
174
+ return Promise.resolve(source).then(response => {
175
+ return origCompileStreaming(response).then(module => {
176
+ if (response.url) {
177
+ registerModuleAndForward(module, response.url, workerSelf);
178
+ }
179
+ return module;
180
+ });
181
+ });
182
+ } ;
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Registers a WASM module and forwards its debug image to the parent thread.
188
+ */
189
+ function registerModuleAndForward(
190
+ module,
191
+ url,
192
+ workerSelf,
193
+ ) {
194
+ const image = registerModule(module, url);
195
+
196
+ if (image) {
197
+ workerSelf.postMessage({
198
+ _sentryMessage: true,
199
+ _sentryWasmImages: [image],
200
+ });
201
+ }
202
+ }
203
+
204
+ export { patchFrames, registerWebWorkerWasm, wasmIntegration };
95
205
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/index.ts"],"sourcesContent":["import type { Event, IntegrationFn, StackFrame } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { patchWebAssembly } from './patchWebAssembly';\nimport { getImage, getImages } from './registry';\n\nconst INTEGRATION_NAME = 'Wasm';\n\ninterface WasmIntegrationOptions {\n /**\n * Key to identify this application for third-party error filtering.\n * This key should match one of the keys provided to the `filterKeys` option\n * of the `thirdPartyErrorFilterIntegration`.\n */\n applicationKey?: string;\n}\n\nconst _wasmIntegration = ((options: WasmIntegrationOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n patchWebAssembly();\n },\n processEvent(event: Event): Event {\n let hasAtLeastOneWasmFrameWithImage = false;\n\n if (event.exception?.values) {\n event.exception.values.forEach(exception => {\n if (exception.stacktrace?.frames) {\n hasAtLeastOneWasmFrameWithImage =\n hasAtLeastOneWasmFrameWithImage || patchFrames(exception.stacktrace.frames, options.applicationKey);\n }\n });\n }\n\n if (hasAtLeastOneWasmFrameWithImage) {\n event.debug_meta = event.debug_meta || {};\n event.debug_meta.images = [...(event.debug_meta.images || []), ...getImages()];\n }\n\n return event;\n },\n };\n}) satisfies IntegrationFn;\n\nexport const wasmIntegration = defineIntegration(_wasmIntegration);\n\nconst PARSER_REGEX = /^(.*?):wasm-function\\[\\d+\\]:(0x[a-fA-F0-9]+)$/;\n\n// We use the same prefix as bundler plugins so that thirdPartyErrorFilterIntegration\n// recognizes WASM frames as first-party code without needing modifications.\nconst BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';\n\n/**\n * Patches a list of stackframes with wasm data needed for server-side symbolication\n * if applicable. Returns true if the provided list of stack frames had at least one\n * matching registered image.\n */\n// Only exported for tests\nexport function patchFrames(frames: Array<StackFrame>, applicationKey?: string): boolean {\n let hasAtLeastOneWasmFrameWithImage = false;\n frames.forEach(frame => {\n if (!frame.filename) {\n return;\n }\n\n const split = frame.filename.split('(');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSplit = split[split.length - 1]!;\n\n // Let's call this first match a \"messy match\".\n // The browser stacktrace parser spits out frames that have a filename like this: \"int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb\"\n // It contains some leftover mess because wasm stack frames are more complicated than our parser can handle: \"at MyClass::bar(int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb)\"\n // This first match simply tries to mitigate the mess up until the first opening parens.\n // The match afterwards is a sensible fallback\n let match = lastSplit.match(PARSER_REGEX) as null | [string, string, string];\n\n if (!match) {\n match = frame.filename.match(PARSER_REGEX) as null | [string, string, string];\n }\n\n if (match) {\n const index = getImage(match[1]);\n frame.instruction_addr = match[2];\n frame.filename = match[1];\n frame.platform = 'native';\n\n if (applicationKey) {\n frame.module_metadata = {\n ...frame.module_metadata,\n [`${BUNDLER_PLUGIN_APP_KEY_PREFIX}${applicationKey}`]: true,\n };\n }\n\n if (index >= 0) {\n frame.addr_mode = `rel:${index}`;\n hasAtLeastOneWasmFrameWithImage = true;\n }\n }\n });\n\n return hasAtLeastOneWasmFrameWithImage;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/index.ts"],"sourcesContent":["import type { DebugImage, Event, IntegrationFn, StackFrame } from '@sentry/core';\nimport { defineIntegration, GLOBAL_OBJ } from '@sentry/core';\nimport { patchWebAssembly } from './patchWebAssembly';\nimport { getImage, getImages, registerModule } from './registry';\n\nconst INTEGRATION_NAME = 'Wasm';\n\n// We use the same prefix as bundler plugins so that thirdPartyErrorFilterIntegration\n// recognizes WASM frames as first-party code without needing modifications.\nconst BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';\n\n/**\n * Minimal interface for DedicatedWorkerGlobalScope.\n * We can't use the actual type because it breaks everyone who doesn't have {\"lib\": [\"WebWorker\"]}\n */\ninterface MinimalDedicatedWorkerGlobalScope {\n postMessage: (message: unknown) => void;\n}\n\ninterface RegisterWebWorkerWasmOptions {\n self: MinimalDedicatedWorkerGlobalScope;\n}\n\ninterface WasmIntegrationOptions {\n /**\n * Key to identify this application for third-party error filtering.\n * This key should match one of the keys provided to the `filterKeys` option\n * of the `thirdPartyErrorFilterIntegration`.\n */\n applicationKey?: string;\n}\n\n// Access WINDOW with proper typing for _sentryWasmImages\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n _sentryWasmImages?: Array<DebugImage>;\n};\n\nconst _wasmIntegration = ((options: WasmIntegrationOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n patchWebAssembly();\n },\n processEvent(event: Event): Event {\n let hasAtLeastOneWasmFrameWithImage = false;\n\n const existingImagesCount = event.debug_meta?.images?.length || 0;\n\n if (event.exception?.values) {\n event.exception.values.forEach(exception => {\n if (exception.stacktrace?.frames) {\n hasAtLeastOneWasmFrameWithImage =\n hasAtLeastOneWasmFrameWithImage ||\n patchFrames(exception.stacktrace.frames, options.applicationKey, existingImagesCount);\n }\n });\n }\n\n if (hasAtLeastOneWasmFrameWithImage) {\n event.debug_meta = event.debug_meta || {};\n const mainThreadImages = getImages();\n const workerImages = WINDOW._sentryWasmImages || [];\n event.debug_meta.images = [...(event.debug_meta.images || []), ...mainThreadImages, ...workerImages];\n }\n\n return event;\n },\n };\n}) satisfies IntegrationFn;\n\nexport const wasmIntegration = defineIntegration(_wasmIntegration);\n\nconst PARSER_REGEX = /^(.*?):wasm-function\\[\\d+\\]:(0x[a-fA-F0-9]+)$/;\n\n/**\n * Patches a list of stackframes with wasm data needed for server-side symbolication\n * if applicable. Returns true if the provided list of stack frames had at least one\n * matching registered image.\n *\n * @param frames - Stack frames to patch\n * @param applicationKey - Optional key for third-party error filtering\n * @param existingImagesOffset - Number of existing debug images that will be prepended\n * to the final images array (used to calculate correct addr_mode indices)\n */\n// Only exported for tests\nexport function patchFrames(\n frames: Array<StackFrame>,\n applicationKey?: string,\n existingImagesOffset: number = 0,\n): boolean {\n let hasAtLeastOneWasmFrameWithImage = false;\n frames.forEach(frame => {\n if (!frame.filename) {\n return;\n }\n\n const split = frame.filename.split('(');\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSplit = split[split.length - 1]!;\n\n // Let's call this first match a \"messy match\".\n // The browser stacktrace parser spits out frames that have a filename like this: \"int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb\"\n // It contains some leftover mess because wasm stack frames are more complicated than our parser can handle: \"at MyClass::bar(int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb)\"\n // This first match simply tries to mitigate the mess up until the first opening parens.\n // The match afterwards is a sensible fallback\n let match = lastSplit.match(PARSER_REGEX) as null | [string, string, string];\n\n if (!match) {\n match = frame.filename.match(PARSER_REGEX) as null | [string, string, string];\n }\n\n if (match) {\n const index = getImage(match[1]);\n const workerImageIndex = getWorkerImage(match[1]);\n frame.instruction_addr = match[2];\n frame.filename = match[1];\n frame.platform = 'native';\n\n if (applicationKey) {\n frame.module_metadata = {\n ...frame.module_metadata,\n [`${BUNDLER_PLUGIN_APP_KEY_PREFIX}${applicationKey}`]: true,\n };\n }\n\n if (index >= 0) {\n frame.addr_mode = `rel:${existingImagesOffset + index}`;\n hasAtLeastOneWasmFrameWithImage = true;\n } else if (workerImageIndex >= 0) {\n const mainThreadImagesCount = getImages().length;\n frame.addr_mode = `rel:${existingImagesOffset + mainThreadImagesCount + workerImageIndex}`;\n hasAtLeastOneWasmFrameWithImage = true;\n }\n }\n });\n\n return hasAtLeastOneWasmFrameWithImage;\n}\n\n/**\n * Looks up an image by URL in worker images.\n */\nfunction getWorkerImage(url: string): number {\n const workerImages = WINDOW._sentryWasmImages || [];\n return workerImages.findIndex(image => {\n return image.type === 'wasm' && image.code_file === url;\n });\n}\n\n/**\n * Use this function to register WASM support in a web worker.\n *\n * This function will:\n * - Patch WebAssembly.instantiateStreaming and WebAssembly.compileStreaming in the worker\n * - Forward WASM debug images to the parent thread for symbolication\n *\n * @param options {RegisterWebWorkerWasmOptions} Options:\n * - `self`: The worker's global scope (self).\n */\nexport function registerWebWorkerWasm({ self }: RegisterWebWorkerWasmOptions): void {\n patchWebAssemblyWithForwarding(self);\n}\n\n/**\n * Patches the WebAssembly object in the worker scope and forwards\n * registered modules to the parent thread.\n */\nfunction patchWebAssemblyWithForwarding(workerSelf: MinimalDedicatedWorkerGlobalScope): void {\n if ('instantiateStreaming' in WebAssembly) {\n const origInstantiateStreaming = WebAssembly.instantiateStreaming;\n WebAssembly.instantiateStreaming = function instantiateStreaming(\n response: Response | PromiseLike<Response>,\n importObject: WebAssembly.Imports,\n ): Promise<WebAssembly.Module> {\n return Promise.resolve(response).then(response => {\n return origInstantiateStreaming(response, importObject).then(rv => {\n if (response.url) {\n registerModuleAndForward(rv.module, response.url, workerSelf);\n }\n return rv;\n });\n });\n } as typeof WebAssembly.instantiateStreaming;\n }\n\n if ('compileStreaming' in WebAssembly) {\n const origCompileStreaming = WebAssembly.compileStreaming;\n WebAssembly.compileStreaming = function compileStreaming(\n source: Response | Promise<Response>,\n ): Promise<WebAssembly.Module> {\n return Promise.resolve(source).then(response => {\n return origCompileStreaming(response).then(module => {\n if (response.url) {\n registerModuleAndForward(module, response.url, workerSelf);\n }\n return module;\n });\n });\n } as typeof WebAssembly.compileStreaming;\n }\n}\n\n/**\n * Registers a WASM module and forwards its debug image to the parent thread.\n */\nfunction registerModuleAndForward(\n module: WebAssembly.Module,\n url: string,\n workerSelf: MinimalDedicatedWorkerGlobalScope,\n): void {\n const image = registerModule(module, url);\n\n if (image) {\n workerSelf.postMessage({\n _sentryMessage: true,\n _sentryWasmImages: [image],\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"type":"module","version":"10.37.0","sideEffects":false}
1
+ {"type":"module","version":"10.39.0-alpha.0","sideEffects":false}
@@ -31,34 +31,39 @@ function getModuleInfo(module) {
31
31
  }
32
32
 
33
33
  /**
34
- * Records a module
34
+ * Records a module and returns the created debug image.
35
35
  */
36
36
  function registerModule(module, url) {
37
37
  const { buildId, debugFile } = getModuleInfo(module);
38
- if (buildId) {
39
- const oldIdx = getImage(url);
40
- if (oldIdx >= 0) {
41
- IMAGES.splice(oldIdx, 1);
42
- }
38
+ if (!buildId) {
39
+ return null;
40
+ }
43
41
 
44
- let debugFileUrl = null;
45
- if (debugFile) {
46
- try {
47
- debugFileUrl = new URL(debugFile, url).href;
48
- } catch {
49
- // debugFile could be a blob URL which causes the URL constructor to throw
50
- // for now we just ignore this case
51
- }
52
- }
42
+ const oldIdx = getImage(url);
43
+ if (oldIdx >= 0) {
44
+ IMAGES.splice(oldIdx, 1);
45
+ }
53
46
 
54
- IMAGES.push({
55
- type: 'wasm',
56
- code_id: buildId,
57
- code_file: url,
58
- debug_file: debugFileUrl,
59
- debug_id: `${buildId.padEnd(32, '0').slice(0, 32)}0`,
60
- });
47
+ let debugFileUrl = null;
48
+ if (debugFile) {
49
+ try {
50
+ debugFileUrl = new URL(debugFile, url).href;
51
+ } catch {
52
+ // debugFile could be a blob URL which causes the URL constructor to throw
53
+ // for now we just ignore this case
54
+ }
61
55
  }
56
+
57
+ const image = {
58
+ type: 'wasm',
59
+ code_id: buildId,
60
+ code_file: url,
61
+ debug_file: debugFileUrl,
62
+ debug_id: `${buildId.padEnd(32, '0').slice(0, 32)}0`,
63
+ };
64
+
65
+ IMAGES.push(image);
66
+ return image;
62
67
  }
63
68
 
64
69
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sources":["../../../src/registry.ts"],"sourcesContent":["import type { DebugImage } from '@sentry/core';\n\nexport const IMAGES: Array<DebugImage> = [];\n\nexport interface ModuleInfo {\n buildId: string | null;\n debugFile: string | null;\n}\n\n/**\n * Returns the extracted meta information from a web assembly module that\n * Sentry uses to identify debug images.\n *\n * @param module\n */\nexport function getModuleInfo(module: WebAssembly.Module): ModuleInfo {\n const buildIds = WebAssembly.Module.customSections(module, 'build_id');\n let buildId = null;\n let debugFile = null;\n\n const buildId0 = buildIds[0];\n if (buildId0) {\n const firstBuildId = new Uint8Array(buildId0);\n buildId = Array.from(firstBuildId).reduce((acc, x) => {\n return acc + x.toString(16).padStart(2, '0');\n }, '');\n }\n\n const externalDebugInfo = WebAssembly.Module.customSections(module, 'external_debug_info');\n const externalDebugInfo0 = externalDebugInfo[0];\n if (externalDebugInfo0) {\n const firstExternalDebugInfo = new Uint8Array(externalDebugInfo0);\n const decoder = new TextDecoder('utf-8');\n debugFile = decoder.decode(firstExternalDebugInfo);\n }\n\n return { buildId, debugFile };\n}\n\n/**\n * Records a module\n */\nexport function registerModule(module: WebAssembly.Module, url: string): void {\n const { buildId, debugFile } = getModuleInfo(module);\n if (buildId) {\n const oldIdx = getImage(url);\n if (oldIdx >= 0) {\n IMAGES.splice(oldIdx, 1);\n }\n\n let debugFileUrl = null;\n if (debugFile) {\n try {\n debugFileUrl = new URL(debugFile, url).href;\n } catch {\n // debugFile could be a blob URL which causes the URL constructor to throw\n // for now we just ignore this case\n }\n }\n\n IMAGES.push({\n type: 'wasm',\n code_id: buildId,\n code_file: url,\n debug_file: debugFileUrl,\n debug_id: `${buildId.padEnd(32, '0').slice(0, 32)}0`,\n });\n }\n}\n\n/**\n * Returns all known images.\n */\nexport function getImages(): Array<DebugImage> {\n return IMAGES;\n}\n\n/**\n * Looks up an image by URL.\n *\n * @param url the URL of the WebAssembly module.\n */\nexport function getImage(url: string): number {\n return IMAGES.findIndex(image => {\n return image.type === 'wasm' && image.code_file === url;\n });\n}\n"],"names":[],"mappings":"AAEO,MAAM,MAAM,GAAsB;;AAOzC;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAC,MAAM,EAAkC;AACtE,EAAE,MAAM,QAAA,GAAW,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC;AACxE,EAAE,IAAI,OAAA,GAAU,IAAI;AACpB,EAAE,IAAI,SAAA,GAAY,IAAI;;AAEtB,EAAE,MAAM,QAAA,GAAW,QAAQ,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,QAAQ,EAAE;AAChB,IAAI,MAAM,YAAA,GAAe,IAAI,UAAU,CAAC,QAAQ,CAAC;AACjD,IAAI,UAAU,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK;AAC1D,MAAM,OAAO,GAAA,GAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAClD,IAAI,CAAC,EAAE,EAAE,CAAC;AACV,EAAE;;AAEF,EAAE,MAAM,iBAAA,GAAoB,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,qBAAqB,CAAC;AAC5F,EAAE,MAAM,kBAAA,GAAqB,iBAAiB,CAAC,CAAC,CAAC;AACjD,EAAE,IAAI,kBAAkB,EAAE;AAC1B,IAAI,MAAM,sBAAA,GAAyB,IAAI,UAAU,CAAC,kBAAkB,CAAC;AACrE,IAAI,MAAM,OAAA,GAAU,IAAI,WAAW,CAAC,OAAO,CAAC;AAC5C,IAAI,YAAY,OAAO,CAAC,MAAM,CAAC,sBAAsB,CAAC;AACtD,EAAE;;AAEF,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW;AAC/B;;AAEA;AACA;AACA;AACO,SAAS,cAAc,CAAC,MAAM,EAAsB,GAAG,EAAgB;AAC9E,EAAE,MAAM,EAAE,OAAO,EAAE,SAAA,KAAc,aAAa,CAAC,MAAM,CAAC;AACtD,EAAE,IAAI,OAAO,EAAE;AACf,IAAI,MAAM,MAAA,GAAS,QAAQ,CAAC,GAAG,CAAC;AAChC,IAAI,IAAI,MAAA,IAAU,CAAC,EAAE;AACrB,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,IAAI;;AAEJ,IAAI,IAAI,YAAA,GAAe,IAAI;AAC3B,IAAI,IAAI,SAAS,EAAE;AACnB,MAAM,IAAI;AACV,QAAQ,YAAA,GAAe,IAAI,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI;AACnD,MAAM,EAAE,MAAM;AACd;AACA;AACA,MAAM;AACN,IAAI;;AAEJ,IAAI,MAAM,CAAC,IAAI,CAAC;AAChB,MAAM,IAAI,EAAE,MAAM;AAClB,MAAM,OAAO,EAAE,OAAO;AACtB,MAAM,SAAS,EAAE,GAAG;AACpB,MAAM,UAAU,EAAE,YAAY;AAC9B,MAAM,QAAQ,EAAE,CAAC,EAAA,OAAA,CAAA,MAAA,CAAA,EAAA,EAAA,GAAA,CAAA,CAAA,KAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,SAAA,GAAA;AACA,EAAA,OAAA,MAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAA,QAAA,CAAA,GAAA,EAAA;AACA,EAAA,OAAA,MAAA,CAAA,SAAA,CAAA,KAAA,IAAA;AACA,IAAA,OAAA,KAAA,CAAA,IAAA,KAAA,MAAA,IAAA,KAAA,CAAA,SAAA,KAAA,GAAA;AACA,EAAA,CAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"registry.js","sources":["../../../src/registry.ts"],"sourcesContent":["import type { DebugImage } from '@sentry/core';\n\nexport const IMAGES: Array<DebugImage> = [];\n\nexport interface ModuleInfo {\n buildId: string | null;\n debugFile: string | null;\n}\n\n/**\n * Returns the extracted meta information from a web assembly module that\n * Sentry uses to identify debug images.\n *\n * @param module\n */\nexport function getModuleInfo(module: WebAssembly.Module): ModuleInfo {\n const buildIds = WebAssembly.Module.customSections(module, 'build_id');\n let buildId = null;\n let debugFile = null;\n\n const buildId0 = buildIds[0];\n if (buildId0) {\n const firstBuildId = new Uint8Array(buildId0);\n buildId = Array.from(firstBuildId).reduce((acc, x) => {\n return acc + x.toString(16).padStart(2, '0');\n }, '');\n }\n\n const externalDebugInfo = WebAssembly.Module.customSections(module, 'external_debug_info');\n const externalDebugInfo0 = externalDebugInfo[0];\n if (externalDebugInfo0) {\n const firstExternalDebugInfo = new Uint8Array(externalDebugInfo0);\n const decoder = new TextDecoder('utf-8');\n debugFile = decoder.decode(firstExternalDebugInfo);\n }\n\n return { buildId, debugFile };\n}\n\n/**\n * Records a module and returns the created debug image.\n */\nexport function registerModule(module: WebAssembly.Module, url: string): DebugImage | null {\n const { buildId, debugFile } = getModuleInfo(module);\n if (!buildId) {\n return null;\n }\n\n const oldIdx = getImage(url);\n if (oldIdx >= 0) {\n IMAGES.splice(oldIdx, 1);\n }\n\n let debugFileUrl = null;\n if (debugFile) {\n try {\n debugFileUrl = new URL(debugFile, url).href;\n } catch {\n // debugFile could be a blob URL which causes the URL constructor to throw\n // for now we just ignore this case\n }\n }\n\n const image: DebugImage = {\n type: 'wasm',\n code_id: buildId,\n code_file: url,\n debug_file: debugFileUrl,\n debug_id: `${buildId.padEnd(32, '0').slice(0, 32)}0`,\n };\n\n IMAGES.push(image);\n return image;\n}\n\n/**\n * Returns all known images.\n */\nexport function getImages(): Array<DebugImage> {\n return IMAGES;\n}\n\n/**\n * Looks up an image by URL.\n *\n * @param url the URL of the WebAssembly module.\n */\nexport function getImage(url: string): number {\n return IMAGES.findIndex(image => {\n return image.type === 'wasm' && image.code_file === url;\n });\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,14 @@
1
1
  import type { StackFrame } from '@sentry/core';
2
+ /**
3
+ * Minimal interface for DedicatedWorkerGlobalScope.
4
+ * We can't use the actual type because it breaks everyone who doesn't have {"lib": ["WebWorker"]}
5
+ */
6
+ interface MinimalDedicatedWorkerGlobalScope {
7
+ postMessage: (message: unknown) => void;
8
+ }
9
+ interface RegisterWebWorkerWasmOptions {
10
+ self: MinimalDedicatedWorkerGlobalScope;
11
+ }
2
12
  interface WasmIntegrationOptions {
3
13
  /**
4
14
  * Key to identify this application for third-party error filtering.
@@ -12,7 +22,23 @@ export declare const wasmIntegration: (options?: WasmIntegrationOptions | undefi
12
22
  * Patches a list of stackframes with wasm data needed for server-side symbolication
13
23
  * if applicable. Returns true if the provided list of stack frames had at least one
14
24
  * matching registered image.
25
+ *
26
+ * @param frames - Stack frames to patch
27
+ * @param applicationKey - Optional key for third-party error filtering
28
+ * @param existingImagesOffset - Number of existing debug images that will be prepended
29
+ * to the final images array (used to calculate correct addr_mode indices)
30
+ */
31
+ export declare function patchFrames(frames: Array<StackFrame>, applicationKey?: string, existingImagesOffset?: number): boolean;
32
+ /**
33
+ * Use this function to register WASM support in a web worker.
34
+ *
35
+ * This function will:
36
+ * - Patch WebAssembly.instantiateStreaming and WebAssembly.compileStreaming in the worker
37
+ * - Forward WASM debug images to the parent thread for symbolication
38
+ *
39
+ * @param options {RegisterWebWorkerWasmOptions} Options:
40
+ * - `self`: The worker's global scope (self).
15
41
  */
16
- export declare function patchFrames(frames: Array<StackFrame>, applicationKey?: string): boolean;
42
+ export declare function registerWebWorkerWasm({ self }: RegisterWebWorkerWasmOptions): void;
17
43
  export {};
18
44
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,cAAc,CAAC;AAOrE,UAAU,sBAAsB;IAC9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA8BD,eAAO,MAAM,eAAe,sFAAsC,CAAC;AAQnE;;;;GAIG;AAEH,wBAAgB,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CA2CvF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoC,UAAU,EAAE,MAAM,cAAc,CAAC;AAWjF;;;GAGG;AACH,UAAU,iCAAiC;IACzC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;AAED,UAAU,4BAA4B;IACpC,IAAI,EAAE,iCAAiC,CAAC;CACzC;AAED,UAAU,sBAAsB;IAC9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAwCD,eAAO,MAAM,eAAe,sFAAsC,CAAC;AAInE;;;;;;;;;GASG;AAEH,wBAAgB,WAAW,CACzB,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,EACzB,cAAc,CAAC,EAAE,MAAM,EACvB,oBAAoB,GAAE,MAAU,GAC/B,OAAO,CAgDT;AAYD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,IAAI,EAAE,EAAE,4BAA4B,GAAG,IAAI,CAElF"}
@@ -12,9 +12,9 @@ export interface ModuleInfo {
12
12
  */
13
13
  export declare function getModuleInfo(module: WebAssembly.Module): ModuleInfo;
14
14
  /**
15
- * Records a module
15
+ * Records a module and returns the created debug image.
16
16
  */
17
- export declare function registerModule(module: WebAssembly.Module, url: string): void;
17
+ export declare function registerModule(module: WebAssembly.Module, url: string): DebugImage | null;
18
18
  /**
19
19
  * Returns all known images.
20
20
  */
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,UAAU,CAAM,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,GAAG,UAAU,CAsBpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CA0B5E;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI5C"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,UAAU,CAAM,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,GAAG,UAAU,CAsBpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA+BzF;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI5C"}
@@ -1,4 +1,14 @@
1
1
  import { StackFrame } from '@sentry/core';
2
+ /**
3
+ * Minimal interface for DedicatedWorkerGlobalScope.
4
+ * We can't use the actual type because it breaks everyone who doesn't have {"lib": ["WebWorker"]}
5
+ */
6
+ interface MinimalDedicatedWorkerGlobalScope {
7
+ postMessage: (message: unknown) => void;
8
+ }
9
+ interface RegisterWebWorkerWasmOptions {
10
+ self: MinimalDedicatedWorkerGlobalScope;
11
+ }
2
12
  interface WasmIntegrationOptions {
3
13
  /**
4
14
  * Key to identify this application for third-party error filtering.
@@ -12,7 +22,23 @@ export declare const wasmIntegration: (options?: WasmIntegrationOptions | undefi
12
22
  * Patches a list of stackframes with wasm data needed for server-side symbolication
13
23
  * if applicable. Returns true if the provided list of stack frames had at least one
14
24
  * matching registered image.
25
+ *
26
+ * @param frames - Stack frames to patch
27
+ * @param applicationKey - Optional key for third-party error filtering
28
+ * @param existingImagesOffset - Number of existing debug images that will be prepended
29
+ * to the final images array (used to calculate correct addr_mode indices)
30
+ */
31
+ export declare function patchFrames(frames: Array<StackFrame>, applicationKey?: string, existingImagesOffset?: number): boolean;
32
+ /**
33
+ * Use this function to register WASM support in a web worker.
34
+ *
35
+ * This function will:
36
+ * - Patch WebAssembly.instantiateStreaming and WebAssembly.compileStreaming in the worker
37
+ * - Forward WASM debug images to the parent thread for symbolication
38
+ *
39
+ * @param options {RegisterWebWorkerWasmOptions} Options:
40
+ * - `self`: The worker's global scope (self).
15
41
  */
16
- export declare function patchFrames(frames: Array<StackFrame>, applicationKey?: string): boolean;
42
+ export declare function registerWebWorkerWasm({ self }: RegisterWebWorkerWasmOptions): void;
17
43
  export {};
18
44
  //# sourceMappingURL=index.d.ts.map
@@ -12,9 +12,9 @@ export interface ModuleInfo {
12
12
  */
13
13
  export declare function getModuleInfo(module: WebAssembly.Module): ModuleInfo;
14
14
  /**
15
- * Records a module
15
+ * Records a module and returns the created debug image.
16
16
  */
17
- export declare function registerModule(module: WebAssembly.Module, url: string): void;
17
+ export declare function registerModule(module: WebAssembly.Module, url: string): DebugImage | null;
18
18
  /**
19
19
  * Returns all known images.
20
20
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/wasm",
3
- "version": "10.37.0",
3
+ "version": "10.39.0-alpha.0",
4
4
  "description": "Support for WASM.",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/wasm",
@@ -39,8 +39,8 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@sentry/browser": "10.37.0",
43
- "@sentry/core": "10.37.0"
42
+ "@sentry/browser": "10.39.0-alpha.0",
43
+ "@sentry/core": "10.39.0-alpha.0"
44
44
  },
45
45
  "scripts": {
46
46
  "build": "run-p build:transpile build:bundle build:types",