@lastos/page-spy-plugin-mp-data-harbor
Version:
Used for caching data and downloading.
351 lines (338 loc) • 9.79 kB
JavaScript
import { psLog as psLog$1 } from '@lastos/page-spy-mp-base';
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function toPrimitive(t, r) {
if ("object" != _typeof(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof(i)) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function toPropertyKey(t) {
var i = toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
function _defineProperty(obj, key, value) {
key = toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
const unproxyConsole = {
...console
};
const psLog = ['log', 'info', 'error', 'warn', 'debug'].reduce((result, method) => {
result[method] = function () {
for (var _len = arguments.length, message = new Array(_len), _key = 0; _key < _len; _key++) {
message[_key] = arguments[_key];
}
console[method]("[PageSpy] [".concat(method.toLocaleUpperCase(), "] "), ...message);
};
result.unproxy[method] = function () {
for (var _len2 = arguments.length, message = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
message[_key2] = arguments[_key2];
}
unproxyConsole[method]("[PageSpy] [".concat(method.toLocaleUpperCase(), "] "), ...message);
};
return result;
}, {
unproxy: {}
});
const removeEndSlash = s => {
return s.replace(/\/$/, '');
};
class MemoryHarbor {
constructor() {
_defineProperty(this, "container", []);
}
add(data) {
this.container.push(data);
return true;
}
clear() {
this.container = [];
}
}
const ROOM_SESSION_KEY = 'page-spy-room';
// the plugin should store the mp sdk by self, received from initiation.
let mp;
const getMPSDK = () => mp;
const setMPSDK = sdk => {
mp = sdk;
};
const getDeviceId = () => {
const cache = mp.getStorageSync(ROOM_SESSION_KEY);
if (cache !== null && cache !== void 0 && cache.address && typeof cache.address === 'string') {
return cache.address.slice(0, 4);
}
return '--';
};
const formatFilename = name => {
return name.toString().replace(/[^\w]/g, '_');
};
const makeData = (type, data) => {
return {
type,
timestamp: Date.now(),
data
};
};
const buildSearchParams = obj => {
return Object.entries(obj).map(_ref => {
let [key, value] = _ref;
return "".concat(key, "=").concat(encodeURIComponent(value));
}).join('&');
};
const saveData = async _ref => {
let {
url,
data
} = _ref;
return new Promise((resolve, reject) => {
const mp = getMPSDK();
mp.request({
data,
url,
method: 'POST',
success: res => {
if (res.statusCode === 200) {
const data = res.data;
if (data.success) {
resolve(data);
} else {
reject(data);
}
}
},
fail: err => {
psLog.warn('Upload failed', err);
reject(err);
}
});
});
};
const defaultConfig = {
caredData: {
console: true,
network: true,
storage: true,
system: true,
meta: true
},
filename: () => {
return new Date().toLocaleString();
},
onAfterUpload: () => {}
};
class MPDataHarborPlugin {
constructor(config) {
_defineProperty(this, "enforce", 'pre');
_defineProperty(this, "name", 'DataHarborPlugin');
_defineProperty(this, "apiBase", '');
_defineProperty(this, "isPaused", false);
_defineProperty(this, "$socketStore", null);
_defineProperty(this, "$pageSpyConfig", null);
_defineProperty(this, "client", null);
this.$harborConfig = {
...defaultConfig,
...config
};
this.harbor = new MemoryHarbor();
}
async onInit(_ref) {
var _this$$socketStore;
let {
socketStore,
config,
client,
mp
} = _ref;
if (MPDataHarborPlugin.hasInited) return;
MPDataHarborPlugin.hasInited = true;
setMPSDK(mp);
this.$pageSpyConfig = config;
this.$socketStore = socketStore; // TODO: fix this type issue
this.client = client;
const {
api,
enableSSL,
offline
} = config;
if (!offline && !api) {
psLog$1.warn("Cannot upload log to PageSpy for miss 'api' configuration. See: ", config);
} else {
// because this plugin is mainly used in mp, so align with mp sdk, default to https
const apiScheme = enableSSL === false ? 'http://' : 'https://';
this.apiBase = removeEndSlash("".concat(apiScheme).concat(api));
}
(_this$$socketStore = this.$socketStore) === null || _this$$socketStore === void 0 || _this$$socketStore.addListener('public-data', message => {
if (this.isPaused || !this.isCaredPublicData(message)) return;
const data = makeData(message.type, message.data);
const ok = this.harbor.add(data);
if (!ok) {
psLog$1.warn("[".concat(this.name, "] Fail to save data in harbor "), data);
}
});
}
onActionSheet() {
return [{
text: '上传离线日志',
action: async () => {
const mp = getMPSDK();
mp.showLoading({
title: '正在上传离线日志...'
});
try {
const result = await this.upload();
mp.hideLoading();
if (result) {
this.$harborConfig.onAfterUpload(result);
mp.showModal({
title: '上传成功',
confirmText: '复制链接',
showCancel: false,
success(res) {
if (res.confirm) {
mp.setClipboardData({
data: result
});
}
}
});
} else {
mp.showToast({
title: '上传失败'
});
}
} catch (e) {
mp.hideLoading();
mp.showToast({
title: '上传失败'
});
}
}
}];
}
async upload(params) {
var _this$client;
const {
filename
} = this.$harborConfig;
const {
project = '',
title = ''
} = this.$pageSpyConfig || {};
const tags = {
project,
title,
deviceId: getDeviceId(),
// userAgent: navigator.userAgent,
userAgent: (_this$client = this.client) === null || _this$client === void 0 ? void 0 : _this$client.getName(),
remark: (params === null || params === void 0 ? void 0 : params.remark) || '',
name: formatFilename(filename()) + '.json'
};
const data = [...this.harbor.container];
data.push(this.makeMetaInfo());
const url = "".concat(this.apiBase, "/api/v1/jsonLog/upload?").concat(buildSearchParams(tags));
let debugUrl = '';
try {
const res = await saveData({
data,
url
});
debugUrl = this.getDebugUrl(res);
if ((params === null || params === void 0 ? void 0 : params.clearCache) !== false) {
var _this$$socketStore2;
this.harbor.clear();
(_this$$socketStore2 = this.$socketStore) === null || _this$$socketStore2 === void 0 || _this$$socketStore2.dispatchEvent('harbor-clear', null);
}
} catch (e) {
psLog$1.error(e);
}
return debugUrl;
}
onReset() {
this.harbor.clear();
MPDataHarborPlugin.hasInited = false;
}
pause() {
this.isPaused = true;
}
resume() {
this.isPaused = false;
}
// Drop data in harbor and re-record
reharbor() {
var _this$$socketStore3;
this.harbor.clear();
(_this$$socketStore3 = this.$socketStore) === null || _this$$socketStore3 === void 0 || _this$$socketStore3.dispatchEvent('harbor-clear', null);
if (this.isPaused) {
this.isPaused = false;
}
}
isCaredPublicData(message) {
if (!message) return false;
const {
type
} = message;
const {
caredData
} = this.$harborConfig;
switch (type) {
case 'console':
if (caredData.console) return true;
return false;
case 'storage':
if (caredData.storage) return true;
return false;
case 'system':
if (caredData.system) return true;
return false;
case 'network':
return !!caredData.network;
// const { url } = message.data as RequestItem;
// const isFetchHarborStockUrl = this.harbor.stock.includes(url);
// if (caredData.network && !isFetchHarborStockUrl) return true;
// return false;
default:
return false;
}
}
// To make sure the replay panel can properly display, we must put a client info
// message to the data.
makeMetaInfo() {
var _this$client2;
const clientInfo = (_this$client2 = this.client) === null || _this$client2 === void 0 ? void 0 : _this$client2.makeClientInfoMsg();
return {
type: 'meta',
timestamp: Date.now(),
data: clientInfo
};
}
getDebugUrl(result) {
if (!result || !result.success) return '';
const debugOrigin = "".concat(this.apiBase, "/#/replay");
const logUrl = "".concat(this.apiBase, "/api/v1/log/download?fileId=").concat(result.data.fileId);
return "".concat(debugOrigin, "?url=").concat(logUrl);
}
}
_defineProperty(MPDataHarborPlugin, "hasInited", false);
export { MPDataHarborPlugin as default };
//# sourceMappingURL=index.min.js.map