UNPKG

mappls-map-react-native

Version:

A Mappls GL react native module for creating custom maps

131 lines (111 loc) 3.52 kB
import { NativeEventEmitter, NativeModules, type EmitterSubscription, type EventSubscription } from "react-native"; import NativeRCTMGLLogging from "../../specs/NativeRCTMGLLogging"; const MGLLogging = NativeRCTMGLLogging == null ? Object.create(NativeModules.MGLLogging): NativeRCTMGLLogging; export type LogLevel = "error" | "warning" | "info" | "debug" | "verbose"; interface Log { message: string; level: LogLevel; tag?: string; } type LogCallback = (log: Log) => boolean; export class Logger { static instance: Logger | null = null; static sharedInstance(): Logger { if (this.instance === null) { this.instance = new Logger(); } return this.instance; } private loggerEmitter: NativeEventEmitter; private startedCount: number; private logCallback: LogCallback | null; private subscription: EmitterSubscription | null | EventSubscription; constructor() { this.loggerEmitter = new NativeEventEmitter(MGLLogging); this.startedCount = 0; this.logCallback = null; this.subscription = null; } /** * Set custom logger function. * @param {Logger~logCallback} logCallback - callback taking a log object as param. If callback return falsy value then * default logging will take place. */ static setLogCallback(logCallback: LogCallback): void { this.sharedInstance().setLogCallback(logCallback); } /** * Set custom logger function. * @param {Logger~logCallback} logCallback - callback taking a log object as param. If callback return falsy value then * default logging will take place. */ setLogCallback(logCallback: LogCallback): void { this.logCallback = logCallback; } /** * This callback is displayed as part of the Requester class. * @callback Logger~logCallback * @param {object} log * @param {string} log.message - the message of the log * @param {string} log.level - log level * @param {string} log.tag - optional tag used on android */ /** * setLogLevel * @param {LogLevel} level */ static setLogLevel(level: LogLevel): void { MGLLogging.setLogLevel(level); } /** * @type {('error'|'warning'|'info'|'debug'|'verbose')} LogLevel - Supported log levels */ start(): void { if (this.startedCount === 0) { this.subscribe(); } this.startedCount += 1; } stop(): void { this.startedCount -= 1; if (this.startedCount === 0) { this.unsubscribe(); } } subscribe(): void { this.subscription = this.loggerEmitter.addListener("LogEvent", (log) => { this.onLog(log); }); } unsubscribe(): void { if (this.subscription) { this.subscription.remove(); this.subscription = null; } } effectiveLevel({ level, message, tag }: Log): LogLevel { if (level === "warning") { if ( tag === "Mbgl-HttpRequest" && message.startsWith("Request failed due to a permanent error: Canceled") ) { // this seems to happening too much to show a warning every time return "info"; } } return level; } onLog(log: Log): void { if (!this.logCallback || !this.logCallback(log)) { const { message } = log; const level = this.effectiveLevel(log); if (level === "error") { console.error("Mappls error", message, log); } else if (level === "warning") { console.warn("Mappls warning", message, log); } else { console.log(`Mappls [${level}]`, message, log); } } } }