UNPKG

core-native

Version:

A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.

94 lines 4.02 kB
import { __awaiter } from "tslib"; import React from "react"; import { AppRegistry, AppState } from "react-native"; import { Provider } from "react-redux"; import { app } from "../app"; import { call, delay } from "../typed-saga"; import { ErrorBoundary } from "../util/ErrorBoundary"; import { ajax } from "../util/network"; import { APIException } from "../Exception"; import { captureError } from "../util/error-util"; const LOGGER_ACTION = "@@framework/logger"; export function startApp(config) { setupGlobalErrorHandler(config.errorListener); runBackgroundLoop(config.loggerConfig); renderRoot(config.registeredAppName, config.componentType, config.beforeRendering); } function setupGlobalErrorHandler(errorListener) { app.errorHandler = errorListener.onError.bind(errorListener); ErrorUtils.setGlobalHandler((error, isFatal) => captureError(error, "@@framework/global", isFatal ? { severity: "fatal" } : undefined)); } function renderRoot(registeredAppName, EntryComponent, beforeRendering) { class WrappedAppComponent extends React.PureComponent { constructor(props) { super(props); this.onAppStateChange = (nextAppState) => { const { appState } = this.state; if (["inactive", "background"].includes(appState) && nextAppState === "active") { app.logger.info({ action: "@@ACTIVE", info: { prevState: appState } }); } else if (appState === "active" && ["inactive", "background"].includes(nextAppState)) { app.logger.info({ action: "@@INACTIVE", info: { nextState: nextAppState } }); sendEventLogs(); } this.setState({ appState: nextAppState }); }; this.state = { initialized: false, appState: AppState.currentState }; } componentDidMount() { return __awaiter(this, void 0, void 0, function* () { if (beforeRendering) { yield beforeRendering(); } this.setState({ initialized: true }); AppState.addEventListener("change", this.onAppStateChange); }); } componentWillUnmount() { AppState.removeEventListener("change", this.onAppStateChange); } render() { return (this.state.initialized && (<Provider store={app.store}> <ErrorBoundary> <EntryComponent /> </ErrorBoundary> </Provider>)); } } AppRegistry.registerComponent(registeredAppName, () => WrappedAppComponent); } function runBackgroundLoop(loggerConfig) { app.logger.info({ action: "@@ENTER" }); app.loggerConfig = loggerConfig || null; app.sagaMiddleware.run(function* () { while (true) { // Loop on every 15 second yield delay(15000); // Send collected log to event server yield* call(sendEventLogs); } }); } export function sendEventLogs() { return __awaiter(this, void 0, void 0, function* () { if (app.loggerConfig) { const logs = app.logger.collect(200); const logLength = logs.length; if (logLength > 0) { try { yield ajax("POST", app.loggerConfig.serverURL, {}, { events: logs }, true); app.logger.emptyLastCollection(); } catch (e) { if (e instanceof APIException) { // For APIException, retry always leads to same error, so have to give up // Do not log network exceptions app.logger.emptyLastCollection(); app.logger.exception(e, { droppedLogs: logLength.toString() }, LOGGER_ACTION); } } } } }); } //# sourceMappingURL=bootstrap.js.map