- App.tsx: full navigation (Auth stack + Main tabs with 5 screens) - Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen - HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors - MapScreen: interactive map with layer toggles (6 layers) - MarketplaceScreen: categories (6), products (5), search - ChatScreen: AI chat with quick prompts (4), bot responses - ProfileScreen: user info, stats, menu (9 items), logout - AlertsScreen: alert list with severity, acknowledge - SensorsScreen: sensor list with type filters (6 types), search - ZonesScreen: zone cards with stats - SettingsScreen: language picker (FR/EN/ES/DE), privacy, about - Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n - Hooks: useSensors, useAlerts, useNotifications, useLocation - Components: Card, Button, LoadingSpinner, ErrorBoundary, Header - Services: iotService, notificationService (with axios API client) - Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN) - Theme: colors.ts with full design system (Blue Ocean palette) - Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
87 lines
3.1 KiB
TypeScript
87 lines
3.1 KiB
TypeScript
import path from 'path';
|
|
import { SourceMapConsumer, RawSourceMap } from 'source-map';
|
|
import { DurationEvent } from '../types/EventInterfaces';
|
|
import { SourceMap } from '../types/SourceMap';
|
|
|
|
/**
|
|
* This function is a helper to the applySourceMapsToEvents. The category allocation logic is implemented here based on the sourcemap url (if available)
|
|
* @param defaultCategory The category the event is of by default without the use of Source maps
|
|
* @param url The URL which can be parsed to interpret the new category of the event (depends on node_modules)
|
|
*/
|
|
const improveCategories = (
|
|
defaultCategory: string,
|
|
url: string | null
|
|
): string => {
|
|
const obtainCategory = (url: string): string => {
|
|
const dirs = url
|
|
.substring(url.lastIndexOf(`${path.sep}node_modules${path.sep}`))
|
|
.split(path.sep);
|
|
return dirs.length > 2 && dirs[1] === 'node_modules'
|
|
? dirs[2]
|
|
: defaultCategory;
|
|
};
|
|
return url ? obtainCategory(url) : defaultCategory;
|
|
};
|
|
|
|
/**
|
|
* Enhances the function line, column and params information and event categories
|
|
* based on JavaScript source maps to make it easier to associate trace events with
|
|
* the application code
|
|
*
|
|
* Throws error if args not set up in ChromeEvents
|
|
* @param {SourceMap} sourceMap
|
|
* @param {DurationEvent[]} chromeEvents
|
|
* @param {string} indexBundleFileName
|
|
* @throws If `args` for events are not populated
|
|
* @returns {DurationEvent[]}
|
|
*/
|
|
const applySourceMapsToEvents = async (
|
|
sourceMap: SourceMap,
|
|
chromeEvents: DurationEvent[],
|
|
indexBundleFileName: string | undefined
|
|
): Promise<DurationEvent[]> => {
|
|
// SEE: Should file here be an optional parameter, so take indexBundleFileName as a parameter and use
|
|
// a default name of `index.bundle`
|
|
const rawSourceMap: RawSourceMap = {
|
|
version: Number(sourceMap.version),
|
|
file: indexBundleFileName || 'index.bundle',
|
|
sources: sourceMap.sources,
|
|
mappings: sourceMap.mappings,
|
|
names: sourceMap.names,
|
|
};
|
|
|
|
const consumer = await new SourceMapConsumer(rawSourceMap);
|
|
const events = chromeEvents.map((event: DurationEvent) => {
|
|
if (event.args) {
|
|
const sm = consumer.originalPositionFor({
|
|
line: Number(event.args.line),
|
|
column: Number(event.args.column),
|
|
});
|
|
/**
|
|
* The categories can help us better visualise the profile if we modify the categories.
|
|
* We change these categories only in the root level and not deeper inside the args, just so we have our
|
|
* original categories as well as these modified categories (as the modified categories simply help with visualisation)
|
|
*/
|
|
event.cat = improveCategories(event.cat!, sm.source);
|
|
event.args = {
|
|
...event.args,
|
|
url: sm.source,
|
|
line: sm.line,
|
|
column: sm.column,
|
|
params: sm.name,
|
|
allocatedCategory: event.cat,
|
|
allocatedName: event.name,
|
|
};
|
|
} else {
|
|
throw new Error(
|
|
`Source maps could not be derived for an event at ${event.ts} and with stackFrame ID ${event.sf}`
|
|
);
|
|
}
|
|
return event;
|
|
});
|
|
consumer.destroy();
|
|
return events;
|
|
};
|
|
|
|
export default applySourceMapsToEvents;
|