@fullstory/react-native
Version:
The official FullStory React Native plugin
184 lines (179 loc) • 6.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "FSPage", {
enumerable: true,
get: function () {
return _FSPage.FSPage;
}
});
exports.PrivateInterface = exports.FS_REF_SYMBOL = void 0;
exports.applyFSPropertiesWithRef = applyFSPropertiesWithRef;
exports.default = void 0;
var _reactNative = require("react-native");
var _codegenNativeCommands = _interopRequireDefault(require("react-native/Libraries/Utilities/codegenNativeCommands"));
var _fullstoryInterface = require("./fullstoryInterface");
var _FSPage = require("./FSPage");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// When adding new imports, please verify that they are not causing the metro resolver to fail in earlier versions of react-native.
const FullStory = _fullstoryInterface.isTurboModuleEnabled ? require('./NativeFullStory').default : _reactNative.NativeModules.FullStory;
if (!FullStory) {
console.warn('FullStory: Native module not found. Falling back to stub implementations.');
}
const {
anonymize = () => null,
identify = () => null,
setUserVars = () => null,
onReady: nativeOnReady = () => Promise.resolve({
replayStartUrl: '',
replayNowUrl: '',
sessionId: ''
}),
getCurrentSession = () => Promise.resolve(''),
getCurrentSessionURL = () => Promise.resolve(''),
consent = () => null,
event = () => null,
shutdown = () => null,
restart = () => null,
log = () => null,
resetIdleTimer = () => null,
onSessionStarted = () => ({
remove: () => null
})
} = FullStory ?? {};
function onReady(listener) {
if (!listener) {
return nativeOnReady();
}
if (!_fullstoryInterface.isTurboModuleEnabled) {
console.warn('FullStory: onReady with a listener is only supported on the New Architecture.');
return {
remove: () => null
};
}
// Fire immediately if a session is already active
getCurrentSessionURL().then(url => {
if (url) {
getCurrentSession().then(sessionId => {
listener({
replayStartUrl: url,
replayNowUrl: url,
sessionId
});
});
}
});
return onSessionStarted(listener);
}
const FullStoryPrivate = _fullstoryInterface.isTurboModuleEnabled ? require('./NativeFullStoryPrivate').default : _reactNative.NativeModules.FullStoryPrivate;
const identifyWithProperties = (uid, userVars = {}) => identify(uid, userVars);
/*
Batching all property commands into a single native call to reduce the window for race conditions
with React Native's rendering scheduler.
*/
const Commands = (0, _codegenNativeCommands.default)({
supportedCommands: ['setBatchProperties']
});
let getInternalInstanceHandleFromPublicInstance;
try {
// This import confuses the metro resolver in earlier versions of react-native.
getInternalInstanceHandleFromPublicInstance = require('react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance').getInternalInstanceHandleFromPublicInstance;
} catch (e) {}
const FS_REF_SYMBOL = exports.FS_REF_SYMBOL = Symbol('fullstory.ref');
// Shared wrapper for components without refs (most common case)
function sharedRefWrapper(element) {
if (element && _fullstoryInterface.isTurboModuleEnabled && _reactNative.Platform.OS === 'ios' && !_reactNative.Platform.isTV) {
let currentProps;
if (getInternalInstanceHandleFromPublicInstance) {
var _getInternalInstanceH;
currentProps = (_getInternalInstanceH = getInternalInstanceHandleFromPublicInstance(element)) === null || _getInternalInstanceH === void 0 || (_getInternalInstanceH = _getInternalInstanceH.stateNode) === null || _getInternalInstanceH === void 0 ? void 0 : _getInternalInstanceH.canonical.currentProps;
} else {
currentProps = element.currentProps;
}
if (currentProps) {
const batchedProps = {};
const fsClass = currentProps.fsClass;
if (fsClass && typeof fsClass === 'string') {
batchedProps.fsClass = fsClass;
}
const fsAttribute = currentProps.fsAttribute;
if (fsAttribute && typeof fsAttribute === 'object') {
batchedProps.fsAttribute = fsAttribute;
}
const fsTagName = currentProps.fsTagName;
if (fsTagName && typeof fsTagName === 'string') {
batchedProps.fsTagName = fsTagName;
}
const dataElement = currentProps.dataElement;
if (dataElement && typeof dataElement === 'string') {
batchedProps.dataElement = dataElement;
}
const dataComponent = currentProps.dataComponent;
if (dataComponent && typeof dataComponent === 'string') {
batchedProps.dataComponent = dataComponent;
}
const dataSourceFile = currentProps.dataSourceFile;
if (dataSourceFile && typeof dataSourceFile === 'string') {
batchedProps.dataSourceFile = dataSourceFile;
}
// Send all properties as a single batched command
if (Object.keys(batchedProps).length > 0) {
Commands.setBatchProperties(element, batchedProps);
}
}
}
}
Object.defineProperty(sharedRefWrapper, FS_REF_SYMBOL, {
value: true,
enumerable: false,
writable: false,
configurable: false
});
function applyFSPropertiesWithRef(existingRef, hasDynamicAttributes = true) {
// Return early if already wrapped
if (existingRef && existingRef[FS_REF_SYMBOL]) {
return existingRef;
}
// Use shared wrapper for null/undefined refs or static attributes
if (!existingRef && !hasDynamicAttributes) {
return sharedRefWrapper;
}
function refWrapper(element) {
sharedRefWrapper(element);
if (existingRef) {
if (typeof existingRef === 'function') {
existingRef(element);
} else {
existingRef.current = element;
}
}
}
Object.defineProperty(refWrapper, FS_REF_SYMBOL, {
value: true,
enumerable: false,
writable: false,
configurable: false
});
return refWrapper;
}
const FullstoryAPI = {
anonymize,
identify: identifyWithProperties,
setUserVars,
onReady,
getCurrentSession,
getCurrentSessionURL,
consent,
event,
shutdown,
restart,
log,
resetIdleTimer,
LogLevel: _fullstoryInterface.LogLevel
};
const PrivateInterface = exports.PrivateInterface = _reactNative.Platform.OS === 'android' ? {
onFSPressForward: FullStoryPrivate.onFSPressForward
} : {};
var _default = exports.default = FullstoryAPI;
//# sourceMappingURL=index.js.map