@datadog/mobile-react-native
Version:
A client-side React Native module to interact with Datadog
143 lines (124 loc) • 6.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createDefaultMetroSerializer = exports.createDatadogMetroSerializer = exports.createDatadogBundleCallback = void 0;
exports.unstable_beforeAssetSerializationPlugin = unstable_beforeAssetSerializationPlugin;
var _baseJSBundle = _interopRequireDefault(require("metro/src/DeltaBundler/Serializers/baseJSBundle"));
var _bundleToString = _interopRequireDefault(require("metro/src/lib/bundleToString"));
var _debugIdHelper = require("./debugIdHelper");
var _utils = require("./utils");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2016-Present Datadog, Inc.
*
* Portions of this code are adapted from Sentry's Metro configuration:
* https://github.com/getsentry/sentry-react-native/blob/17c0c2e8913030e4826d055284a735efad637312/packages/core/src/js/tools/sentryMetroSerializer.ts
*/
// eslint-disable-next-line import/no-extraneous-dependencies
// eslint-disable-next-line import/no-extraneous-dependencies
/**
* Creates a Metro serializer that adds a Debug ID module to the bundle.
* This module injects the Debug ID at runtime, making it globally accessible.
*
* @param customSerializer - Optional custom {@link MetroSerializer}. If provided, you are responsible
* for invoking `options.datadogBundleCallback` within it.
*/
const createDatadogMetroSerializer = customSerializer => {
const serializer = customSerializer || createDefaultMetroSerializer();
return async (entryPoint, preModules, graph, options) => {
// Skip for hot reload mode
if (graph.transformOptions.hot) {
return serializer(entryPoint, preModules, graph, options);
}
// Make sure we don't add the Debug ID module twice
if ((0, _debugIdHelper.checkIfDebugIdModuleExists)(preModules)) {
return serializer(entryPoint, preModules, graph, options);
}
// Create a virtual module to inject the Debug ID in a globally accessible property
const debugIdModule = (0, _debugIdHelper.createDebugIdModule)(_debugIdHelper.DEBUG_ID_PLACEHOLDER);
// Set the datadogBundleCallback in the options, to be used later by the serializer
options.datadogBundleCallback = createDatadogBundleCallback(debugIdModule);
// Add the Debug ID virtual module to the pre-modules
const preModulesWithDebugId = (0, _debugIdHelper.addDebugIdModule)(preModules, debugIdModule);
// Run serializer
const serializerOutput = serializer(entryPoint, preModulesWithDebugId, graph, options);
// Get serialized code and sourcemap
const {
code,
map
} = await (0, _utils.convertSerializerOutput)(serializerOutput);
// Retrieve the Debug ID, previously injected as a snippet of code in a virtual module by `datadogBundleCallback`.
const debugId = (0, _debugIdHelper.getDebugIdFromBundleSource)(code);
if (!debugId) {
throw new Error('[DATADOG METRO PLUGIN] Debug ID was not found in the bundle. Call `options.datadogBundleCallback` if you are using a custom serializer.');
}
// Inject the Debug ID as a comment in the bundle, and as a top-level property in the sourcemap.
const result = (0, _debugIdHelper.injectDebugIdInCodeAndSourceMap)(debugId, code, map);
return result;
};
};
/**
* Creates a Metro Bundle Serializer like metro does by default, while also calling the datadogBundleCallback.
* https://github.com/facebook/metro/blob/a3d021a0d021b5706372059f472715c63019e044/packages/metro/src/Server.js#L272-L307
*/
exports.createDatadogMetroSerializer = createDatadogMetroSerializer;
const createDefaultMetroSerializer = () => {
return (entryPoint, preModules, graph, options) => {
// Default metro bundle
// https://github.com/facebook/metro/blob/a3d021a0d021b5706372059f472715c63019e044/packages/metro/src/DeltaBundler/Serializers/baseJSBundle.js#L25
let bundle = (0, _baseJSBundle.default)(entryPoint, preModules, graph, options);
// Modify the bundle through the datadogBundleCallback, if we are not in hot-reload mode
if (options.datadogBundleCallback && !graph.transformOptions.hot) {
bundle = options.datadogBundleCallback(bundle);
}
// Retrieves the processed code from the bundle
const {
code
} = (0, _bundleToString.default)(bundle);
// If we are in hot-reload mode, we skip sourcemaps generation, and only return the code.
if (graph.transformOptions.hot) {
return code;
}
// Force generation of sourcemaps
const map = (0, _utils.metroSourceMapString)([...preModules, ...(0, _utils.getSortedModules)(graph, options)], {
processModuleFilter: options.processModuleFilter,
shouldAddToIgnoreList: options.shouldAddToIgnoreList
});
return {
code,
map
};
};
};
/**
* Creates a callback used to transform the given bundle by injecting the Debug ID snippet.
* @param debugIdModule - The virtual Debug ID module
* @returns The bundle callback
*/
exports.createDefaultMetroSerializer = createDefaultMetroSerializer;
const createDatadogBundleCallback = debugIdModule => {
return bundle => {
const debugId = (0, _debugIdHelper.createDebugIdFromBundle)(bundle);
const code = debugIdModule.getSource().toString();
debugIdModule.setSource((0, _debugIdHelper.injectDebugIdInCode)(code, debugId));
bundle.pre = (0, _debugIdHelper.injectDebugIdInCode)(bundle.pre, debugId);
return bundle;
};
};
/**
* Adds Debug ID module for runtime injection, used for Expo.
*/
exports.createDatadogBundleCallback = createDatadogBundleCallback;
function unstable_beforeAssetSerializationPlugin({
premodules,
debugId
}) {
if (!debugId || (0, _debugIdHelper.checkIfDebugIdModuleExists)(premodules)) {
return premodules;
}
return [...(0, _debugIdHelper.addDebugIdModule)(premodules, (0, _debugIdHelper.createDebugIdModule)(debugId))];
}
//# sourceMappingURL=metroSerializer.js.map