core-native
Version:
A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.
149 lines • 8.15 kB
JavaScript
import { __extends, __generator } from "tslib";
import React from "react";
import { AppState } from "react-native";
import {} from "redux-saga";
import { delay, call as rawCall } from "redux-saga/effects";
import { app } from "../app";
import { executeAction } from "../module";
import { Module } from "./Module";
var ModuleProxy = /** @class */ (function () {
function ModuleProxy(module, actions) {
this.module = module;
this.actions = actions;
}
ModuleProxy.prototype.getActions = function () {
return this.actions;
};
ModuleProxy.prototype.attachLifecycle = function (ComponentType) {
var _a;
var moduleName = this.module.name;
var lifecycleListener = this.module;
var modulePrototype = Object.getPrototypeOf(lifecycleListener);
var actions = this.actions;
return _a = /** @class */ (function (_super) {
__extends(class_1, _super);
function class_1(props) {
var _this = _super.call(this, props) || this;
_this.lifecycleSagaTask = null;
_this.tickCount = 0;
_this.mountedTime = Date.now();
_this.onAppStateChange = function (nextAppState) {
var appState = _this.state.appState;
if (["inactive", "background"].includes(appState) && nextAppState === "active") {
if (_this.hasOwnLifecycle("onAppActive")) {
app.store.dispatch(actions.onAppActive());
}
}
else if (appState === "active" && ["inactive", "background"].includes(nextAppState)) {
if (_this.hasOwnLifecycle("onAppInactive")) {
app.store.dispatch(actions.onAppInactive());
}
}
_this.setState({ appState: nextAppState });
};
_this.hasOwnLifecycle = function (methodName) {
return Object.prototype.hasOwnProperty.call(modulePrototype, methodName);
};
_this.state = { appState: AppState.currentState };
return _this;
}
class_1.prototype.componentDidMount = function () {
this.lifecycleSagaTask = app.sagaMiddleware.run(this.lifecycleSaga.bind(this));
// According to the document, this API may change soon
// Ref: https://facebook.github.io/react-native/docs/appstate#addeventlistener
this.unsubscribeAppStateChange = AppState.addEventListener("change", this.onAppStateChange);
var props = this.props;
if ("navigation" in props && typeof props.navigation.addListener === "function") {
if (this.hasOwnLifecycle("onFocus")) {
this.unsubscribeFocus = props.navigation.addListener("focus", function () {
app.store.dispatch(actions.onFocus());
});
}
if (this.hasOwnLifecycle("onBlur")) {
this.unsubscribeBlur = props.navigation.addListener("blur", function () {
app.store.dispatch(actions.onBlur());
});
}
}
};
class_1.prototype.componentWillUnmount = function () {
var _b, _c, _d, _e;
if (this.hasOwnLifecycle("onDestroy")) {
app.store.dispatch(actions.onDestroy());
}
app.logger.info({
action: "".concat(moduleName, "/@@DESTROY"),
info: {
tick_count: this.tickCount.toString(),
staying_second: ((Date.now() - this.mountedTime) / 1000).toFixed(2),
},
});
try {
(_b = this.lifecycleSagaTask) === null || _b === void 0 ? void 0 : _b.cancel();
}
catch (e) {
// In rare case, it may throw error, just ignore
}
(_c = this.unsubscribeFocus) === null || _c === void 0 ? void 0 : _c.call(this);
(_d = this.unsubscribeBlur) === null || _d === void 0 ? void 0 : _d.call(this);
(_e = this.unsubscribeAppStateChange) === null || _e === void 0 ? void 0 : _e.remove();
};
class_1.prototype.render = function () {
return <ComponentType {...this.props}/>;
};
class_1.prototype.lifecycleSaga = function () {
var props, enterActionName, startTime, tickIntervalInMillisecond, boundTicker, tickActionName;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
props = this.props;
enterActionName = "".concat(moduleName, "/@@ENTER");
startTime = Date.now();
if (!("navigation" in props)) return [3 /*break*/, 2];
return [4 /*yield*/, rawCall(executeAction, enterActionName, lifecycleListener.onEnter.bind(lifecycleListener), ((_b = props.route) === null || _b === void 0 ? void 0 : _b.params) || {})];
case 1:
_c.sent();
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, rawCall(executeAction, enterActionName, lifecycleListener.onEnter.bind(lifecycleListener), {})];
case 3:
_c.sent();
_c.label = 4;
case 4:
app.logger.info({
action: enterActionName,
elapsedTime: Date.now() - startTime,
info: {
component_props: JSON.stringify(props),
},
});
if (!this.hasOwnLifecycle("onTick")) return [3 /*break*/, 8];
tickIntervalInMillisecond = (lifecycleListener.onTick.tickInterval || 5) * 1000;
boundTicker = lifecycleListener.onTick.bind(lifecycleListener);
tickActionName = "".concat(moduleName, "/@@TICK");
_c.label = 5;
case 5:
if (!true) return [3 /*break*/, 8];
return [4 /*yield*/, rawCall(executeAction, tickActionName, boundTicker)];
case 6:
_c.sent();
this.tickCount++;
return [4 /*yield*/, delay(tickIntervalInMillisecond)];
case 7:
_c.sent();
return [3 /*break*/, 5];
case 8: return [2 /*return*/];
}
});
};
return class_1;
}(React.PureComponent)),
_a.displayName = "ModuleBoundary(".concat(moduleName, ")"),
// Copy static navigation options, important for navigator
_a.navigationOptions = ComponentType.navigationOptions,
_a;
};
return ModuleProxy;
}());
export { ModuleProxy };
//# sourceMappingURL=ModuleProxy.js.map