@fz-firefly/taro 0.0.0-stage → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -2
- package/dist/index.cjs +870 -0
- package/dist/index.d.cts +163 -0
- package/dist/index.d.ts +163 -0
- package/dist/index.js +843 -0
- package/dist/react.cjs +32 -0
- package/dist/react.d.cts +2 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +1 -0
- package/dist/vue.cjs +20 -0
- package/dist/vue.d.cts +2 -0
- package/dist/vue.d.ts +2 -0
- package/dist/vue.js +1 -0
- package/package.json +60 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
// \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
let _fz_firefly_core = require("@fz-firefly/core");
|
|
24
|
+
let _tarojs_taro = require("@tarojs/taro");
|
|
25
|
+
_tarojs_taro = __toESM(_tarojs_taro, 1);
|
|
26
|
+
// src/platform/runtime.ts
|
|
27
|
+
/** 读取 Taro 运行时;不在 Taro 环境时返回 null。 */
|
|
28
|
+
function getTaro() {
|
|
29
|
+
var _ref;
|
|
30
|
+
return (_ref = _tarojs_taro.default) !== null && _ref !== void 0 ? _ref : null;
|
|
31
|
+
}
|
|
32
|
+
/** 安全读取系统信息,失败时返回 null。 */
|
|
33
|
+
function readSystemInfo(runtime = getTaro()) {
|
|
34
|
+
try {
|
|
35
|
+
var _runtime$getSystemInf, _runtime$getSystemInf2;
|
|
36
|
+
return (_runtime$getSystemInf = runtime === null || runtime === void 0 || (_runtime$getSystemInf2 = runtime.getSystemInfoSync) === null || _runtime$getSystemInf2 === void 0 ? void 0 : _runtime$getSystemInf2.call(runtime)) !== null && _runtime$getSystemInf !== void 0 ? _runtime$getSystemInf : null;
|
|
37
|
+
} catch (_unused) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** 读取当前页面;非 Taro 环境返回 null。 */
|
|
42
|
+
function readCurrentPage(runtime = getTaro()) {
|
|
43
|
+
try {
|
|
44
|
+
var _runtime$getCurrentPa, _pages;
|
|
45
|
+
const pages = runtime === null || runtime === void 0 || (_runtime$getCurrentPa = runtime.getCurrentPages) === null || _runtime$getCurrentPa === void 0 ? void 0 : _runtime$getCurrentPa.call(runtime);
|
|
46
|
+
if (!pages || pages.length === 0) return null;
|
|
47
|
+
return (_pages = pages[pages.length - 1]) !== null && _pages !== void 0 ? _pages : null;
|
|
48
|
+
} catch (_unused2) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const PLATFORM_MAP = {
|
|
53
|
+
WEB: "web",
|
|
54
|
+
H5: "web",
|
|
55
|
+
WEAPP: "mp-weixin",
|
|
56
|
+
MP_WEIXIN: "mp-weixin",
|
|
57
|
+
ALIPAY: "mp-alipay",
|
|
58
|
+
MP_ALIPAY: "mp-alipay",
|
|
59
|
+
RN: "app",
|
|
60
|
+
SWAN: "app",
|
|
61
|
+
TT: "app",
|
|
62
|
+
QQ: "app",
|
|
63
|
+
JD: "app"
|
|
64
|
+
};
|
|
65
|
+
const DIST_MAP = {
|
|
66
|
+
WEB: "h5",
|
|
67
|
+
H5: "h5",
|
|
68
|
+
WEAPP: "mp-weixin",
|
|
69
|
+
MP_WEIXIN: "mp-weixin",
|
|
70
|
+
ALIPAY: "mp-alipay",
|
|
71
|
+
MP_ALIPAY: "mp-alipay",
|
|
72
|
+
RN: "rn",
|
|
73
|
+
SWAN: "mp-swan",
|
|
74
|
+
TT: "mp-tt",
|
|
75
|
+
QQ: "mp-qq",
|
|
76
|
+
JD: "mp-jd"
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* 识别当前 Taro 运行平台。
|
|
80
|
+
*
|
|
81
|
+
* 优先使用 Taro.getEnv()(WEAPP / WEB / ALIPAY / RN...),
|
|
82
|
+
* 拿不到时按是否存在 window 粗略判断。协议只接受 web / mp-weixin /
|
|
83
|
+
* mp-alipay / app,其他小程序统一归为 app,并在 dist 里保留真实平台。
|
|
84
|
+
*/
|
|
85
|
+
function detectPlatform(runtime = getTaro()) {
|
|
86
|
+
const raw = readEnv(runtime);
|
|
87
|
+
if (raw) {
|
|
88
|
+
var _PLATFORM_MAP$raw, _DIST_MAP$raw;
|
|
89
|
+
return {
|
|
90
|
+
platform: (_PLATFORM_MAP$raw = PLATFORM_MAP[raw]) !== null && _PLATFORM_MAP$raw !== void 0 ? _PLATFORM_MAP$raw : "app",
|
|
91
|
+
dist: (_DIST_MAP$raw = DIST_MAP[raw]) !== null && _DIST_MAP$raw !== void 0 ? _DIST_MAP$raw : raw.toLowerCase()
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const isWeb = typeof window !== "undefined";
|
|
95
|
+
return {
|
|
96
|
+
platform: isWeb ? "web" : "app",
|
|
97
|
+
dist: isWeb ? "h5" : "app"
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** 读取 Taro 运行环境,统一转成大写。 */
|
|
101
|
+
function readEnv(runtime) {
|
|
102
|
+
try {
|
|
103
|
+
var _runtime$getEnv;
|
|
104
|
+
const env = runtime === null || runtime === void 0 || (_runtime$getEnv = runtime.getEnv) === null || _runtime$getEnv === void 0 ? void 0 : _runtime$getEnv.call(runtime);
|
|
105
|
+
return typeof env === "string" && env ? env.toUpperCase() : void 0;
|
|
106
|
+
} catch (_unused3) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// \0@oxc-project+runtime@0.155.0/helpers/esm/typeof.js
|
|
111
|
+
function _typeof(o) {
|
|
112
|
+
"@babel/helpers - typeof";
|
|
113
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
114
|
+
return typeof o;
|
|
115
|
+
} : function(o) {
|
|
116
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
117
|
+
}, _typeof(o);
|
|
118
|
+
}
|
|
119
|
+
// \0@oxc-project+runtime@0.155.0/helpers/esm/toPrimitive.js
|
|
120
|
+
function toPrimitive(t, r) {
|
|
121
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
122
|
+
var e = t[Symbol.toPrimitive];
|
|
123
|
+
if (void 0 !== e) {
|
|
124
|
+
var i = e.call(t, r || "default");
|
|
125
|
+
if ("object" != _typeof(i)) return i;
|
|
126
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
127
|
+
}
|
|
128
|
+
return ("string" === r ? String : Number)(t);
|
|
129
|
+
}
|
|
130
|
+
// \0@oxc-project+runtime@0.155.0/helpers/esm/toPropertyKey.js
|
|
131
|
+
function toPropertyKey(t) {
|
|
132
|
+
var i = toPrimitive(t, "string");
|
|
133
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
134
|
+
}
|
|
135
|
+
// \0@oxc-project+runtime@0.155.0/helpers/esm/defineProperty.js
|
|
136
|
+
function _defineProperty(e, r, t) {
|
|
137
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
138
|
+
value: t,
|
|
139
|
+
enumerable: !0,
|
|
140
|
+
configurable: !0,
|
|
141
|
+
writable: !0
|
|
142
|
+
}) : e[r] = t, e;
|
|
143
|
+
}
|
|
144
|
+
// \0@oxc-project+runtime@0.155.0/helpers/esm/objectSpread2.js
|
|
145
|
+
function ownKeys(e, r) {
|
|
146
|
+
var t = Object.keys(e);
|
|
147
|
+
if (Object.getOwnPropertySymbols) {
|
|
148
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
149
|
+
r && (o = o.filter(function(r) {
|
|
150
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
151
|
+
})), t.push.apply(t, o);
|
|
152
|
+
}
|
|
153
|
+
return t;
|
|
154
|
+
}
|
|
155
|
+
function _objectSpread2(e) {
|
|
156
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
157
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
158
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
|
|
159
|
+
_defineProperty(e, r, t[r]);
|
|
160
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
|
|
161
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return e;
|
|
165
|
+
}
|
|
166
|
+
// src/hooks/http-errors.ts
|
|
167
|
+
/** 响应头白名单,避免把敏感头带进监控。 */
|
|
168
|
+
const RESPONSE_HEADER_WHITELIST = [
|
|
169
|
+
"content-type",
|
|
170
|
+
"content-length",
|
|
171
|
+
"x-request-id",
|
|
172
|
+
"x-trace-id",
|
|
173
|
+
"traceparent",
|
|
174
|
+
"x-b3-traceid"
|
|
175
|
+
];
|
|
176
|
+
function headerValue(headers, name) {
|
|
177
|
+
if (!headers) return "";
|
|
178
|
+
for (const [key, value] of Object.entries(headers)) if (key.toLowerCase() === name) return value;
|
|
179
|
+
return "";
|
|
180
|
+
}
|
|
181
|
+
/** 只保留白名单内的响应头。 */
|
|
182
|
+
function pickResponseHeaders(headers) {
|
|
183
|
+
if (!headers) return void 0;
|
|
184
|
+
const result = {};
|
|
185
|
+
for (const name of RESPONSE_HEADER_WHITELIST) {
|
|
186
|
+
const value = headerValue(headers, name);
|
|
187
|
+
if (value) result[name] = value;
|
|
188
|
+
}
|
|
189
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
190
|
+
}
|
|
191
|
+
/** 从响应头里取 request id / trace id。 */
|
|
192
|
+
function requestIdOf(headers) {
|
|
193
|
+
for (const name of [
|
|
194
|
+
"x-request-id",
|
|
195
|
+
"x-trace-id",
|
|
196
|
+
"traceparent",
|
|
197
|
+
"x-b3-traceid"
|
|
198
|
+
]) {
|
|
199
|
+
const value = headerValue(headers, name);
|
|
200
|
+
if (value) return value;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** 读取 content-length;缺失或非法时返回 undefined。 */
|
|
204
|
+
function contentLengthOf(headers) {
|
|
205
|
+
const value = headerValue(headers, "content-length");
|
|
206
|
+
if (!value) return void 0;
|
|
207
|
+
const parsed = Number(value);
|
|
208
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
|
|
209
|
+
}
|
|
210
|
+
/** 估算响应体大小。 */
|
|
211
|
+
function sizeOf(body) {
|
|
212
|
+
if (!body) return void 0;
|
|
213
|
+
if (typeof body.value === "string") return body.value.length;
|
|
214
|
+
try {
|
|
215
|
+
return JSON.stringify(body.value).length;
|
|
216
|
+
} catch (_unused) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* 每个 Taro 运行时只安装一个拦截器。
|
|
222
|
+
*
|
|
223
|
+
* Taro H5 的 `@tarojs/taro-h5` 是 ES module namespace,直接改写
|
|
224
|
+
* `runtime.request` 会失败;`addInterceptor` 是公开且跨平台的入口。
|
|
225
|
+
* 重复 init 时只替换 capture,避免拦截器无限叠加。
|
|
226
|
+
*/
|
|
227
|
+
const interceptorStates = /* @__PURE__ */ new WeakMap();
|
|
228
|
+
/** 创建请求捕获逻辑,实际包装方式由运行时能力决定。 */
|
|
229
|
+
function createRequestCapture(client, options) {
|
|
230
|
+
var _options$slowRequestT;
|
|
231
|
+
const captureBody = options.captureHttpBody !== false;
|
|
232
|
+
const captureResponseBody = options.captureHttpResponseBody !== false;
|
|
233
|
+
const requestBodyOptions = {
|
|
234
|
+
redactKeys: options.redactKeys,
|
|
235
|
+
maxChars: options.maxHttpBodyChars
|
|
236
|
+
};
|
|
237
|
+
const responseBodyOptions = {
|
|
238
|
+
redactKeys: options.redactKeys,
|
|
239
|
+
maxChars: options.maxHttpResponseChars
|
|
240
|
+
};
|
|
241
|
+
const slowThresholdMs = (_options$slowRequestT = options.slowRequestThresholdMs) !== null && _options$slowRequestT !== void 0 ? _options$slowRequestT : 1e3;
|
|
242
|
+
return (requestOptions) => {
|
|
243
|
+
var _requestOptions$metho;
|
|
244
|
+
const method = ((_requestOptions$metho = requestOptions.method) !== null && _requestOptions$metho !== void 0 ? _requestOptions$metho : "GET").toUpperCase();
|
|
245
|
+
const url = requestOptions.url;
|
|
246
|
+
if ((0, _fz_firefly_core.isIngestRequestUrl)(url)) return null;
|
|
247
|
+
const startedAt = Date.now();
|
|
248
|
+
const contentType = headerValue(requestOptions.header, "content-type");
|
|
249
|
+
let bodyCapture;
|
|
250
|
+
let bodyRead = false;
|
|
251
|
+
const readBody = () => {
|
|
252
|
+
if (!captureBody) return void 0;
|
|
253
|
+
if (!bodyRead) {
|
|
254
|
+
bodyRead = true;
|
|
255
|
+
bodyCapture = (0, _fz_firefly_core.serializeHttpBody)(requestOptions.data, contentType, requestBodyOptions);
|
|
256
|
+
}
|
|
257
|
+
return bodyCapture;
|
|
258
|
+
};
|
|
259
|
+
let reported = false;
|
|
260
|
+
const report = (statusCode, details = {}) => {
|
|
261
|
+
if (reported) return;
|
|
262
|
+
reported = true;
|
|
263
|
+
try {
|
|
264
|
+
var _details$result, _responseHeaders$cont, _details$result2, _contentLengthOf, _details$result3;
|
|
265
|
+
const durationMs = Date.now() - startedAt;
|
|
266
|
+
const ok = statusCode >= 200 && statusCode < 400;
|
|
267
|
+
const slow = durationMs >= slowThresholdMs;
|
|
268
|
+
const body = !ok || slow ? readBody() : void 0;
|
|
269
|
+
const responseHeaders = pickResponseHeaders((_details$result = details.result) === null || _details$result === void 0 ? void 0 : _details$result.header);
|
|
270
|
+
const responseContentType = (_responseHeaders$cont = responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders["content-type"]) !== null && _responseHeaders$cont !== void 0 ? _responseHeaders$cont : contentType;
|
|
271
|
+
const responseBody = (!ok || slow) && captureResponseBody ? (0, _fz_firefly_core.serializeHttpResponseBody)((_details$result2 = details.result) === null || _details$result2 === void 0 ? void 0 : _details$result2.data, responseContentType, responseBodyOptions) : void 0;
|
|
272
|
+
(0, _fz_firefly_core.captureHttpRequest)(client, _objectSpread2({
|
|
273
|
+
method,
|
|
274
|
+
url,
|
|
275
|
+
statusCode,
|
|
276
|
+
durationMs,
|
|
277
|
+
category: "taro",
|
|
278
|
+
ok,
|
|
279
|
+
startedAt,
|
|
280
|
+
requestBody: body === null || body === void 0 ? void 0 : body.value,
|
|
281
|
+
requestBodyTruncated: body === null || body === void 0 ? void 0 : body.truncated,
|
|
282
|
+
responseBody: responseBody === null || responseBody === void 0 ? void 0 : responseBody.value,
|
|
283
|
+
responseBodyTruncated: responseBody === null || responseBody === void 0 ? void 0 : responseBody.truncated,
|
|
284
|
+
responseHeaders,
|
|
285
|
+
requestId: requestIdOf(responseHeaders),
|
|
286
|
+
responseSize: (_contentLengthOf = contentLengthOf((_details$result3 = details.result) === null || _details$result3 === void 0 ? void 0 : _details$result3.header)) !== null && _contentLengthOf !== void 0 ? _contentLengthOf : sizeOf(responseBody),
|
|
287
|
+
slowThresholdMs
|
|
288
|
+
}, details.error ? { error: details.error } : {}));
|
|
289
|
+
} catch (_unused2) {}
|
|
290
|
+
};
|
|
291
|
+
return {
|
|
292
|
+
options: _objectSpread2(_objectSpread2({}, requestOptions), {}, {
|
|
293
|
+
success(result) {
|
|
294
|
+
var _result$statusCode, _requestOptions$succe;
|
|
295
|
+
report((_result$statusCode = result.statusCode) !== null && _result$statusCode !== void 0 ? _result$statusCode : 0, { result });
|
|
296
|
+
(_requestOptions$succe = requestOptions.success) === null || _requestOptions$succe === void 0 || _requestOptions$succe.call(requestOptions, result);
|
|
297
|
+
},
|
|
298
|
+
fail(error) {
|
|
299
|
+
var _error$errMsg, _requestOptions$fail;
|
|
300
|
+
const message = (_error$errMsg = error.errMsg) !== null && _error$errMsg !== void 0 ? _error$errMsg : "request failed";
|
|
301
|
+
if (!/abort|cancel/i.test(message)) report(0, { error: message });
|
|
302
|
+
(_requestOptions$fail = requestOptions.fail) === null || _requestOptions$fail === void 0 || _requestOptions$fail.call(requestOptions, error);
|
|
303
|
+
}
|
|
304
|
+
}),
|
|
305
|
+
reportError(error) {
|
|
306
|
+
report(0, { error: error instanceof Error ? error.message : String(error) });
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/** 通过 Taro.addInterceptor 记录请求;运行时没有该 API 时返回 null。 */
|
|
312
|
+
function installRequestInterceptor(runtime, capture) {
|
|
313
|
+
if (typeof runtime.addInterceptor !== "function") return null;
|
|
314
|
+
let state = interceptorStates.get(runtime);
|
|
315
|
+
if (!state) {
|
|
316
|
+
const nextState = { capture: null };
|
|
317
|
+
const interceptor = (chain) => {
|
|
318
|
+
const active = nextState.capture;
|
|
319
|
+
if (!active) return chain.proceed(chain.requestParams);
|
|
320
|
+
const captured = active(chain.requestParams);
|
|
321
|
+
if (!captured) return chain.proceed(chain.requestParams);
|
|
322
|
+
try {
|
|
323
|
+
return chain.proceed(captured.options);
|
|
324
|
+
} catch (error) {
|
|
325
|
+
captured.reportError(error);
|
|
326
|
+
throw error;
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
try {
|
|
330
|
+
runtime.addInterceptor(interceptor);
|
|
331
|
+
state = nextState;
|
|
332
|
+
interceptorStates.set(runtime, state);
|
|
333
|
+
} catch (_unused3) {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
const previous = state.capture;
|
|
338
|
+
state.capture = capture;
|
|
339
|
+
return () => {
|
|
340
|
+
if (state.capture === capture) state.capture = previous;
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/** 包装 Taro.request,记录成功/失败/慢请求。 */
|
|
344
|
+
function installTaroRequestErrors(client, options, runtime = getTaro()) {
|
|
345
|
+
if (options.captureHttp === false || !runtime) return () => {};
|
|
346
|
+
const capture = createRequestCapture(client, options);
|
|
347
|
+
const disposeInterceptor = installRequestInterceptor(runtime, capture);
|
|
348
|
+
if (disposeInterceptor) return disposeInterceptor;
|
|
349
|
+
const original = runtime.request;
|
|
350
|
+
if (typeof original !== "function") return () => {};
|
|
351
|
+
const wrapped = function(requestOptions) {
|
|
352
|
+
const captured = capture(requestOptions);
|
|
353
|
+
if (!captured) return original.call(this, requestOptions);
|
|
354
|
+
try {
|
|
355
|
+
return original.call(this, captured.options);
|
|
356
|
+
} catch (error) {
|
|
357
|
+
captured.reportError(error);
|
|
358
|
+
throw error;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
try {
|
|
362
|
+
runtime.request = wrapped;
|
|
363
|
+
return () => {
|
|
364
|
+
if (runtime.request === wrapped) runtime.request = original;
|
|
365
|
+
};
|
|
366
|
+
} catch (_unused4) {
|
|
367
|
+
return () => {};
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// src/hooks/lifecycle.ts
|
|
371
|
+
/**
|
|
372
|
+
* 应用隐藏/恢复时冲刷队列,并记录小程序生命周期面包屑。
|
|
373
|
+
*
|
|
374
|
+
* - onAppHide:小程序切后台,最后一次补发机会;
|
|
375
|
+
* - onAppShow:回到前台时补发离线期间积压的事件;
|
|
376
|
+
* - pagehide:H5 关闭标签页。
|
|
377
|
+
*/
|
|
378
|
+
function installLifecycleFlush(client, runtime = getTaro(), options = {}) {
|
|
379
|
+
const disposers = [];
|
|
380
|
+
const flush = () => {
|
|
381
|
+
client.flush();
|
|
382
|
+
};
|
|
383
|
+
const addLifecycle = (category, message, data) => {
|
|
384
|
+
if (!options.isMiniProgram || options.captureLifecycle === false) return;
|
|
385
|
+
try {
|
|
386
|
+
client.addBreadcrumb({
|
|
387
|
+
type: "lifecycle",
|
|
388
|
+
category,
|
|
389
|
+
level: "info",
|
|
390
|
+
timestamp: Date.now(),
|
|
391
|
+
message,
|
|
392
|
+
data
|
|
393
|
+
});
|
|
394
|
+
} catch (_unused) {}
|
|
395
|
+
};
|
|
396
|
+
const onHide = () => {
|
|
397
|
+
flush();
|
|
398
|
+
addLifecycle("app", "应用进入后台", { state: "hide" });
|
|
399
|
+
};
|
|
400
|
+
const onShow = () => {
|
|
401
|
+
flush();
|
|
402
|
+
addLifecycle("app", "应用回到前台", { state: "show" });
|
|
403
|
+
};
|
|
404
|
+
if (runtime === null || runtime === void 0 ? void 0 : runtime.onAppHide) try {
|
|
405
|
+
runtime.onAppHide(onHide);
|
|
406
|
+
disposers.push(() => {
|
|
407
|
+
try {
|
|
408
|
+
var _runtime$offAppHide;
|
|
409
|
+
(_runtime$offAppHide = runtime.offAppHide) === null || _runtime$offAppHide === void 0 || _runtime$offAppHide.call(runtime, onHide);
|
|
410
|
+
} catch (_unused2) {}
|
|
411
|
+
});
|
|
412
|
+
} catch (_unused3) {}
|
|
413
|
+
if (runtime === null || runtime === void 0 ? void 0 : runtime.onAppShow) try {
|
|
414
|
+
runtime.onAppShow(onShow);
|
|
415
|
+
disposers.push(() => {
|
|
416
|
+
try {
|
|
417
|
+
var _runtime$offAppShow;
|
|
418
|
+
(_runtime$offAppShow = runtime.offAppShow) === null || _runtime$offAppShow === void 0 || _runtime$offAppShow.call(runtime, onShow);
|
|
419
|
+
} catch (_unused4) {}
|
|
420
|
+
});
|
|
421
|
+
} catch (_unused5) {}
|
|
422
|
+
const onNetworkStatus = (event) => {
|
|
423
|
+
var _event$networkType;
|
|
424
|
+
const online = event.isConnected !== false && event.networkType !== "none";
|
|
425
|
+
addLifecycle("network", online ? "网络恢复" : "网络断开", {
|
|
426
|
+
online,
|
|
427
|
+
network_type: (_event$networkType = event.networkType) !== null && _event$networkType !== void 0 ? _event$networkType : "unknown"
|
|
428
|
+
});
|
|
429
|
+
};
|
|
430
|
+
if (runtime === null || runtime === void 0 ? void 0 : runtime.onNetworkStatusChange) try {
|
|
431
|
+
runtime.onNetworkStatusChange(onNetworkStatus);
|
|
432
|
+
disposers.push(() => {
|
|
433
|
+
try {
|
|
434
|
+
var _runtime$offNetworkSt;
|
|
435
|
+
(_runtime$offNetworkSt = runtime.offNetworkStatusChange) === null || _runtime$offNetworkSt === void 0 || _runtime$offNetworkSt.call(runtime, onNetworkStatus);
|
|
436
|
+
} catch (_unused6) {}
|
|
437
|
+
});
|
|
438
|
+
} catch (_unused7) {}
|
|
439
|
+
if (typeof window !== "undefined") try {
|
|
440
|
+
window.addEventListener("pagehide", flush);
|
|
441
|
+
disposers.push(() => {
|
|
442
|
+
try {
|
|
443
|
+
window.removeEventListener("pagehide", flush);
|
|
444
|
+
} catch (_unused8) {}
|
|
445
|
+
});
|
|
446
|
+
} catch (_unused9) {}
|
|
447
|
+
return () => {
|
|
448
|
+
for (const dispose of disposers) dispose();
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
// src/hooks/navigation.ts
|
|
452
|
+
const NAVIGATION_APIS = [
|
|
453
|
+
"navigateTo",
|
|
454
|
+
"redirectTo",
|
|
455
|
+
"switchTab",
|
|
456
|
+
"reLaunch",
|
|
457
|
+
"navigateBack"
|
|
458
|
+
];
|
|
459
|
+
/**
|
|
460
|
+
* 记录 Taro 页面跳转面包屑。
|
|
461
|
+
*
|
|
462
|
+
* Taro 没有 uni.addInterceptor,也没有跨框架的路由事件,所以在运行时包装
|
|
463
|
+
* Taro.navigateTo / redirectTo / switchTab / reLaunch / navigateBack。
|
|
464
|
+
* 调用发生在 wrapper 内时记一条面包屑,再原样调用宿主实现。
|
|
465
|
+
*
|
|
466
|
+
* 已知边界:业务如果在 initFirefly 之前解构了导航方法,或直接调用平台原生
|
|
467
|
+
* API(例如 wx.navigateTo),不会经过包装,需要手动 addBreadcrumb。
|
|
468
|
+
*/
|
|
469
|
+
function installNavigationBreadcrumbs(client, runtime = getTaro()) {
|
|
470
|
+
if (!runtime) return () => {};
|
|
471
|
+
const target = runtime;
|
|
472
|
+
const restores = [];
|
|
473
|
+
for (const api of NAVIGATION_APIS) {
|
|
474
|
+
const original = target[api];
|
|
475
|
+
if (typeof original !== "function") continue;
|
|
476
|
+
const wrapper = function(options) {
|
|
477
|
+
try {
|
|
478
|
+
recordNavigation(client, api, options);
|
|
479
|
+
} catch (_unused) {}
|
|
480
|
+
return original.call(this, options);
|
|
481
|
+
};
|
|
482
|
+
try {
|
|
483
|
+
target[api] = wrapper;
|
|
484
|
+
restores.push(() => {
|
|
485
|
+
if (target[api] === wrapper) target[api] = original;
|
|
486
|
+
});
|
|
487
|
+
} catch (_unused2) {}
|
|
488
|
+
}
|
|
489
|
+
return () => {
|
|
490
|
+
for (const restore of restores) restore();
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
/** 把一次导航写成面包屑。 */
|
|
494
|
+
function recordNavigation(client, api, options) {
|
|
495
|
+
var _client$startPageSess;
|
|
496
|
+
const url = typeof (options === null || options === void 0 ? void 0 : options.url) === "string" ? options.url : "";
|
|
497
|
+
const delta = typeof (options === null || options === void 0 ? void 0 : options.delta) === "number" ? options.delta : void 0;
|
|
498
|
+
(_client$startPageSess = client.startPageSession) === null || _client$startPageSess === void 0 || _client$startPageSess.call(client, url || void 0, {
|
|
499
|
+
navigation_type: api,
|
|
500
|
+
api
|
|
501
|
+
});
|
|
502
|
+
client.addBreadcrumb({
|
|
503
|
+
type: "navigation",
|
|
504
|
+
category: "taro",
|
|
505
|
+
level: "info",
|
|
506
|
+
timestamp: Date.now(),
|
|
507
|
+
message: url ? `${api} ${url}` : api,
|
|
508
|
+
data: url || delta !== void 0 ? _objectSpread2(_objectSpread2({ api }, url ? { url } : {}), delta !== void 0 ? { delta } : {}) : { api }
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
// src/hooks/taro-errors.ts
|
|
512
|
+
/**
|
|
513
|
+
* 挂载 Taro 全局错误钩子。
|
|
514
|
+
*
|
|
515
|
+
* Taro.onError / onUnhandledRejection 会转发小程序 App.onError 和
|
|
516
|
+
* App.onUnhandledRejection;H5 与 RN 也会走对应实现。
|
|
517
|
+
* 不同平台支持程度不同,存在才注册,不存在只降级不报错。
|
|
518
|
+
* H5 下如果 Taro 没有对应 API,回退到 window error / unhandledrejection。
|
|
519
|
+
*/
|
|
520
|
+
function installTaroErrorHooks(client, runtime = getTaro()) {
|
|
521
|
+
if (!runtime) return () => {};
|
|
522
|
+
const captureError = (error) => {
|
|
523
|
+
try {
|
|
524
|
+
if (typeof error === "string" && /\n\s+at\s/.test(error)) {
|
|
525
|
+
var _error$split$;
|
|
526
|
+
const firstLine = ((_error$split$ = error.split("\n")[0]) === null || _error$split$ === void 0 ? void 0 : _error$split$.trim()) || "Error";
|
|
527
|
+
const reconstructed = new Error(firstLine);
|
|
528
|
+
reconstructed.stack = error;
|
|
529
|
+
client.captureException(reconstructed, { tags: { source: "taro" } });
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
client.captureException(error, { tags: { source: "taro" } });
|
|
533
|
+
} catch (_unused) {}
|
|
534
|
+
};
|
|
535
|
+
const handleRejection = (event) => {
|
|
536
|
+
var _event$reason;
|
|
537
|
+
captureError((_event$reason = event === null || event === void 0 ? void 0 : event.reason) !== null && _event$reason !== void 0 ? _event$reason : /* @__PURE__ */ new Error("Unhandled promise rejection"));
|
|
538
|
+
};
|
|
539
|
+
const hasTaroError = typeof runtime.onError === "function";
|
|
540
|
+
const hasTaroRejection = typeof runtime.onUnhandledRejection === "function";
|
|
541
|
+
const hasWindow = typeof window !== "undefined";
|
|
542
|
+
/** H5 的 window error 兜底,忽略资源加载错误。 */
|
|
543
|
+
const handleWindowError = (event) => {
|
|
544
|
+
try {
|
|
545
|
+
const target = event.target;
|
|
546
|
+
if (target && typeof target.tagName === "string") return;
|
|
547
|
+
if (event.error) captureError(event.error);
|
|
548
|
+
else if (event.message) client.captureException(new Error(event.message));
|
|
549
|
+
} catch (_unused2) {}
|
|
550
|
+
};
|
|
551
|
+
const handleWindowRejection = (event) => {
|
|
552
|
+
handleRejection({ reason: event.reason });
|
|
553
|
+
};
|
|
554
|
+
if (hasWindow) window.addEventListener("error", handleWindowError);
|
|
555
|
+
else if (hasTaroError) try {
|
|
556
|
+
var _runtime$onError;
|
|
557
|
+
(_runtime$onError = runtime.onError) === null || _runtime$onError === void 0 || _runtime$onError.call(runtime, captureError);
|
|
558
|
+
} catch (_unused3) {}
|
|
559
|
+
if (hasTaroRejection) try {
|
|
560
|
+
var _runtime$onUnhandledR;
|
|
561
|
+
(_runtime$onUnhandledR = runtime.onUnhandledRejection) === null || _runtime$onUnhandledR === void 0 || _runtime$onUnhandledR.call(runtime, handleRejection);
|
|
562
|
+
} catch (_unused4) {}
|
|
563
|
+
if (!hasTaroRejection && hasWindow) window.addEventListener("unhandledrejection", handleWindowRejection);
|
|
564
|
+
return () => {
|
|
565
|
+
if (hasWindow) window.removeEventListener("error", handleWindowError);
|
|
566
|
+
else if (hasTaroError) try {
|
|
567
|
+
var _runtime$offError;
|
|
568
|
+
(_runtime$offError = runtime.offError) === null || _runtime$offError === void 0 || _runtime$offError.call(runtime, captureError);
|
|
569
|
+
} catch (_unused5) {}
|
|
570
|
+
if (hasTaroRejection) try {
|
|
571
|
+
var _runtime$offUnhandled;
|
|
572
|
+
(_runtime$offUnhandled = runtime.offUnhandledRejection) === null || _runtime$offUnhandled === void 0 || _runtime$offUnhandled.call(runtime, handleRejection);
|
|
573
|
+
} catch (_unused6) {}
|
|
574
|
+
if (!hasTaroRejection && hasWindow) window.removeEventListener("unhandledrejection", handleWindowRejection);
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
// src/platform/context.ts
|
|
578
|
+
/** 读取时区;小程序可能没有 Intl,失败时返回 undefined。 */
|
|
579
|
+
function readTimezone() {
|
|
580
|
+
try {
|
|
581
|
+
return typeof Intl !== "undefined" ? Intl.DateTimeFormat().resolvedOptions().timeZone : void 0;
|
|
582
|
+
} catch (_unused) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
/** 安全读取全局对象;globalThis 在部分老运行时不存在。 */
|
|
587
|
+
function getGlobalObject() {
|
|
588
|
+
return typeof globalThis === "undefined" ? void 0 : globalThis;
|
|
589
|
+
}
|
|
590
|
+
/** 读取 H5 环境的 navigator;小程序里通常不存在。 */
|
|
591
|
+
function readNavigator() {
|
|
592
|
+
var _getGlobalObject$wind, _getGlobalObject;
|
|
593
|
+
return (_getGlobalObject$wind = (_getGlobalObject = getGlobalObject()) === null || _getGlobalObject === void 0 || (_getGlobalObject = _getGlobalObject.window) === null || _getGlobalObject === void 0 ? void 0 : _getGlobalObject.navigator) !== null && _getGlobalObject$wind !== void 0 ? _getGlobalObject$wind : {};
|
|
594
|
+
}
|
|
595
|
+
/** 从 UA 粗略识别浏览器。 */
|
|
596
|
+
function detectBrowser(ua) {
|
|
597
|
+
if (/MicroMessenger/i.test(ua)) return "WeChat";
|
|
598
|
+
if (/Edg\//.test(ua)) return "Edge";
|
|
599
|
+
if (/Chrome\//.test(ua)) return "Chrome";
|
|
600
|
+
if (/Firefox\//.test(ua)) return "Firefox";
|
|
601
|
+
if (/Safari\//.test(ua)) return "Safari";
|
|
602
|
+
return "Unknown";
|
|
603
|
+
}
|
|
604
|
+
/** 从 UA 提取浏览器版本。 */
|
|
605
|
+
function detectBrowserVersion(ua, browser) {
|
|
606
|
+
var _patterns$browser;
|
|
607
|
+
return (_patterns$browser = {
|
|
608
|
+
WeChat: /MicroMessenger\/([\d.]+)/i,
|
|
609
|
+
Edge: /Edg\/([\d.]+)/i,
|
|
610
|
+
Chrome: /Chrome\/([\d.]+)/i,
|
|
611
|
+
Firefox: /Firefox\/([\d.]+)/i,
|
|
612
|
+
Safari: /Version\/([\d.]+).*Safari/i
|
|
613
|
+
}[browser]) === null || _patterns$browser === void 0 || (_patterns$browser = _patterns$browser.exec(ua)) === null || _patterns$browser === void 0 ? void 0 : _patterns$browser[1];
|
|
614
|
+
}
|
|
615
|
+
/** 创建 Taro 上下文采集器。 */
|
|
616
|
+
function createContext(runtime = getTaro(), platformInfo = detectPlatform(runtime)) {
|
|
617
|
+
return {
|
|
618
|
+
platform: platformInfo.platform,
|
|
619
|
+
pageUrl: () => {
|
|
620
|
+
var _getGlobalObject2;
|
|
621
|
+
return (_getGlobalObject2 = getGlobalObject()) === null || _getGlobalObject2 === void 0 || (_getGlobalObject2 = _getGlobalObject2.location) === null || _getGlobalObject2 === void 0 ? void 0 : _getGlobalObject2.href;
|
|
622
|
+
},
|
|
623
|
+
pageRoute: () => {
|
|
624
|
+
var _readCurrentPage;
|
|
625
|
+
return (_readCurrentPage = readCurrentPage(runtime)) === null || _readCurrentPage === void 0 ? void 0 : _readCurrentPage.route;
|
|
626
|
+
},
|
|
627
|
+
collect() {
|
|
628
|
+
var _readSystemInfo, _info$platform, _info$system, _info$model, _info$brand, _info$windowWidth, _info$windowHeight, _info$pixelRatio, _info$networkType, _info$carrier, _info$SDKVersion, _ref, _page$route, _page$options, _ref2, _info$language;
|
|
629
|
+
const info = (_readSystemInfo = readSystemInfo(runtime)) !== null && _readSystemInfo !== void 0 ? _readSystemInfo : {};
|
|
630
|
+
const page = readCurrentPage(runtime);
|
|
631
|
+
const nav = platformInfo.platform === "web" ? readNavigator() : {};
|
|
632
|
+
const contexts = {
|
|
633
|
+
os: {
|
|
634
|
+
name: (_info$platform = info.platform) !== null && _info$platform !== void 0 ? _info$platform : "unknown",
|
|
635
|
+
version: (_info$system = info.system) !== null && _info$system !== void 0 ? _info$system : "unknown"
|
|
636
|
+
},
|
|
637
|
+
device: {
|
|
638
|
+
model: (_info$model = info.model) !== null && _info$model !== void 0 ? _info$model : "unknown",
|
|
639
|
+
brand: (_info$brand = info.brand) !== null && _info$brand !== void 0 ? _info$brand : "unknown"
|
|
640
|
+
},
|
|
641
|
+
screen: {
|
|
642
|
+
width: (_info$windowWidth = info.windowWidth) !== null && _info$windowWidth !== void 0 ? _info$windowWidth : 0,
|
|
643
|
+
height: (_info$windowHeight = info.windowHeight) !== null && _info$windowHeight !== void 0 ? _info$windowHeight : 0,
|
|
644
|
+
pixel_ratio: (_info$pixelRatio = info.pixelRatio) !== null && _info$pixelRatio !== void 0 ? _info$pixelRatio : 1
|
|
645
|
+
},
|
|
646
|
+
network: _objectSpread2(_objectSpread2({ effective_type: (_info$networkType = info.networkType) !== null && _info$networkType !== void 0 ? _info$networkType : "unknown" }, info.networkType ? { online: info.networkType !== "none" } : {}), info.carrier || info.operator ? { carrier: (_info$carrier = info.carrier) !== null && _info$carrier !== void 0 ? _info$carrier : info.operator } : {}),
|
|
647
|
+
runtime: {
|
|
648
|
+
name: "taro",
|
|
649
|
+
platform: platformInfo.dist,
|
|
650
|
+
sdk: "@fz-firefly/taro",
|
|
651
|
+
base_library: (_info$SDKVersion = info.SDKVersion) !== null && _info$SDKVersion !== void 0 ? _info$SDKVersion : "unknown"
|
|
652
|
+
},
|
|
653
|
+
page: {
|
|
654
|
+
route: (_ref = (_page$route = page === null || page === void 0 ? void 0 : page.route) !== null && _page$route !== void 0 ? _page$route : page === null || page === void 0 ? void 0 : page.$taroPath) !== null && _ref !== void 0 ? _ref : "unknown",
|
|
655
|
+
query: (_page$options = page === null || page === void 0 ? void 0 : page.options) !== null && _page$options !== void 0 ? _page$options : {}
|
|
656
|
+
},
|
|
657
|
+
locale: _objectSpread2({ language: (_ref2 = (_info$language = info.language) !== null && _info$language !== void 0 ? _info$language : nav.language) !== null && _ref2 !== void 0 ? _ref2 : "unknown" }, readTimezone() ? { timezone: readTimezone() } : {})
|
|
658
|
+
};
|
|
659
|
+
if (nav.userAgent) {
|
|
660
|
+
var _detectBrowserVersion, _ref3, _nav$language, _info$windowWidth2, _info$windowHeight2;
|
|
661
|
+
const browser = detectBrowser(nav.userAgent);
|
|
662
|
+
contexts.browser = {
|
|
663
|
+
name: browser,
|
|
664
|
+
version: (_detectBrowserVersion = detectBrowserVersion(nav.userAgent, browser)) !== null && _detectBrowserVersion !== void 0 ? _detectBrowserVersion : "unknown",
|
|
665
|
+
language: (_ref3 = (_nav$language = nav.language) !== null && _nav$language !== void 0 ? _nav$language : info.language) !== null && _ref3 !== void 0 ? _ref3 : "unknown",
|
|
666
|
+
user_agent: nav.userAgent,
|
|
667
|
+
viewport: {
|
|
668
|
+
width: (_info$windowWidth2 = info.windowWidth) !== null && _info$windowWidth2 !== void 0 ? _info$windowWidth2 : 0,
|
|
669
|
+
height: (_info$windowHeight2 = info.windowHeight) !== null && _info$windowHeight2 !== void 0 ? _info$windowHeight2 : 0
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
if (info.appVersion) contexts.app = { version: info.appVersion };
|
|
674
|
+
return contexts;
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
// src/platform/storage.ts
|
|
679
|
+
/**
|
|
680
|
+
* 创建 Taro 存储。
|
|
681
|
+
*
|
|
682
|
+
* 优先使用 Taro.setStorageSync 持久化,配额满或被禁用时退化为内存 Map。
|
|
683
|
+
* 小程序、H5、RN 都走同一套 API,不直接访问 localStorage。
|
|
684
|
+
*/
|
|
685
|
+
function createStorage(runtime = getTaro()) {
|
|
686
|
+
var _runtime$getStorageSy, _runtime$setStorageSy, _runtime$removeStorag;
|
|
687
|
+
const memory = /* @__PURE__ */ new Map();
|
|
688
|
+
const getStorage = runtime === null || runtime === void 0 || (_runtime$getStorageSy = runtime.getStorageSync) === null || _runtime$getStorageSy === void 0 ? void 0 : _runtime$getStorageSy.bind(runtime);
|
|
689
|
+
const setStorage = runtime === null || runtime === void 0 || (_runtime$setStorageSy = runtime.setStorageSync) === null || _runtime$setStorageSy === void 0 ? void 0 : _runtime$setStorageSy.bind(runtime);
|
|
690
|
+
const removeStorage = runtime === null || runtime === void 0 || (_runtime$removeStorag = runtime.removeStorageSync) === null || _runtime$removeStorag === void 0 ? void 0 : _runtime$removeStorag.bind(runtime);
|
|
691
|
+
let persistent = Boolean(getStorage && setStorage && removeStorage);
|
|
692
|
+
return {
|
|
693
|
+
get(key) {
|
|
694
|
+
var _memory$get;
|
|
695
|
+
if (persistent && getStorage) try {
|
|
696
|
+
const value = getStorage(key);
|
|
697
|
+
if (value === "" || value === null || value === void 0) return null;
|
|
698
|
+
return typeof value === "string" ? value : String(value);
|
|
699
|
+
} catch (_unused) {
|
|
700
|
+
persistent = false;
|
|
701
|
+
}
|
|
702
|
+
return (_memory$get = memory.get(key)) !== null && _memory$get !== void 0 ? _memory$get : null;
|
|
703
|
+
},
|
|
704
|
+
set(key, value) {
|
|
705
|
+
memory.set(key, value);
|
|
706
|
+
if (persistent && setStorage) try {
|
|
707
|
+
setStorage(key, value);
|
|
708
|
+
} catch (_unused2) {
|
|
709
|
+
persistent = false;
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
remove(key) {
|
|
713
|
+
memory.delete(key);
|
|
714
|
+
if (persistent && removeStorage) try {
|
|
715
|
+
removeStorage(key);
|
|
716
|
+
} catch (_unused3) {
|
|
717
|
+
persistent = false;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
// src/platform/transport.ts
|
|
723
|
+
/**
|
|
724
|
+
* 创建 Taro 上报通道。
|
|
725
|
+
*
|
|
726
|
+
* 使用 Taro.request,body 直接传 JSON 字符串,避免平台把对象重新序列化。
|
|
727
|
+
* H5、小程序、RN 都由 Taro 统一转发。
|
|
728
|
+
*/
|
|
729
|
+
function createTransport(endpoint, runtime = getTaro()) {
|
|
730
|
+
var _runtime$request;
|
|
731
|
+
const baseUrl = `${endpoint.replace(/\/+$/, "")}/api/ingest/v1/envelope`;
|
|
732
|
+
const request = runtime === null || runtime === void 0 || (_runtime$request = runtime.request) === null || _runtime$request === void 0 ? void 0 : _runtime$request.bind(runtime);
|
|
733
|
+
return { send(body, dsn) {
|
|
734
|
+
return new Promise((resolve, reject) => {
|
|
735
|
+
if (!request) {
|
|
736
|
+
reject(new _fz_firefly_core.FireflyTransportError("Firefly: 当前环境不支持 Taro.request"));
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
const url = `${baseUrl}?key=${encodeURIComponent(dsn)}`;
|
|
740
|
+
try {
|
|
741
|
+
request({
|
|
742
|
+
url,
|
|
743
|
+
method: "POST",
|
|
744
|
+
header: { "Content-Type": "text/plain;charset=UTF-8" },
|
|
745
|
+
data: body,
|
|
746
|
+
dataType: "text",
|
|
747
|
+
success(result) {
|
|
748
|
+
var _result$statusCode, _result$header$retry, _result$header, _result$header2;
|
|
749
|
+
const status = Number((_result$statusCode = result === null || result === void 0 ? void 0 : result.statusCode) !== null && _result$statusCode !== void 0 ? _result$statusCode : 0);
|
|
750
|
+
if (status >= 200 && status < 300) {
|
|
751
|
+
resolve();
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
const retryAfter = (_result$header$retry = result === null || result === void 0 || (_result$header = result.header) === null || _result$header === void 0 ? void 0 : _result$header["retry-after"]) !== null && _result$header$retry !== void 0 ? _result$header$retry : result === null || result === void 0 || (_result$header2 = result.header) === null || _result$header2 === void 0 ? void 0 : _result$header2["Retry-After"];
|
|
755
|
+
reject(new _fz_firefly_core.FireflyTransportError(`Firefly: 上报失败,HTTP ${status}`, {
|
|
756
|
+
statusCode: status,
|
|
757
|
+
retryAfterMs: (0, _fz_firefly_core.parseRetryAfter)(retryAfter)
|
|
758
|
+
}));
|
|
759
|
+
},
|
|
760
|
+
fail(error) {
|
|
761
|
+
reject(new _fz_firefly_core.FireflyTransportError((error === null || error === void 0 ? void 0 : error.errMsg) ? `Firefly: ${error.errMsg}` : "Firefly: 上报网络错误", { cause: error }));
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
} catch (error) {
|
|
765
|
+
reject(error instanceof _fz_firefly_core.FireflyTransportError ? error : new _fz_firefly_core.FireflyTransportError("Firefly: 上报网络错误", { cause: error }));
|
|
766
|
+
}
|
|
767
|
+
});
|
|
768
|
+
} };
|
|
769
|
+
}
|
|
770
|
+
// \0@oxc-project+runtime@0.155.0/helpers/esm/objectWithoutPropertiesLoose.js
|
|
771
|
+
function _objectWithoutPropertiesLoose(r, e) {
|
|
772
|
+
if (null == r) return {};
|
|
773
|
+
var t = {};
|
|
774
|
+
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
775
|
+
if (e.includes(n)) continue;
|
|
776
|
+
t[n] = r[n];
|
|
777
|
+
}
|
|
778
|
+
return t;
|
|
779
|
+
}
|
|
780
|
+
// \0@oxc-project+runtime@0.155.0/helpers/esm/objectWithoutProperties.js
|
|
781
|
+
function _objectWithoutProperties(e, t) {
|
|
782
|
+
if (null == e) return {};
|
|
783
|
+
var o, r, i = _objectWithoutPropertiesLoose(e, t);
|
|
784
|
+
if (Object.getOwnPropertySymbols) {
|
|
785
|
+
var s = Object.getOwnPropertySymbols(e);
|
|
786
|
+
for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
|
787
|
+
}
|
|
788
|
+
return i;
|
|
789
|
+
}
|
|
790
|
+
// src/init.ts
|
|
791
|
+
const _excluded = ["runtime"];
|
|
792
|
+
/**
|
|
793
|
+
* Taro 平台入口。
|
|
794
|
+
*
|
|
795
|
+
* 一行接入:
|
|
796
|
+
* ```ts
|
|
797
|
+
* const handle = initFirefly({ dsn, endpoint, environment, release })
|
|
798
|
+
* ```
|
|
799
|
+
*
|
|
800
|
+
* 这个入口只负责 Taro 平台能力;React / Vue 的组件错误处理
|
|
801
|
+
* 分别从 `@fz-firefly/taro/react` 和 `@fz-firefly/taro/vue` 引入。
|
|
802
|
+
*/
|
|
803
|
+
function initFirefly(options) {
|
|
804
|
+
var _clientOptions$dist;
|
|
805
|
+
const { runtime: injectedRuntime } = options, clientOptions = _objectWithoutProperties(options, _excluded);
|
|
806
|
+
const runtime = injectedRuntime === void 0 ? getTaro() : injectedRuntime;
|
|
807
|
+
const platformInfo = detectPlatform(runtime);
|
|
808
|
+
const resolved = (0, _fz_firefly_core.resolveOptions)(_objectSpread2(_objectSpread2({}, clientOptions), {}, { dist: (_clientOptions$dist = clientOptions.dist) !== null && _clientOptions$dist !== void 0 ? _clientOptions$dist : platformInfo.dist }));
|
|
809
|
+
const client = (0, _fz_firefly_core.createClient)(resolved, {
|
|
810
|
+
storage: createStorage(runtime),
|
|
811
|
+
transport: createTransport(resolved.endpoint, runtime),
|
|
812
|
+
context: createContext(runtime, platformInfo)
|
|
813
|
+
});
|
|
814
|
+
const initial = readInitialPage(runtime);
|
|
815
|
+
client.startPageSession(initial.path, _objectSpread2(_objectSpread2({ navigation_type: "initial" }, initial.query ? { query: initial.query } : {}), initial.url ? { url: initial.url } : {}));
|
|
816
|
+
const disposeHooks = [
|
|
817
|
+
installTaroErrorHooks(client, runtime),
|
|
818
|
+
...options.captureResourceErrors === false ? [] : [(0, _fz_firefly_core.installResourceErrorHooks)(client)],
|
|
819
|
+
...options.captureClicks === false ? [] : [(0, _fz_firefly_core.installClickBreadcrumbs)(client)],
|
|
820
|
+
(0, _fz_firefly_core.installConsoleBreadcrumbs)(client, options),
|
|
821
|
+
(0, _fz_firefly_core.installLifecycleBreadcrumbs)(client, options),
|
|
822
|
+
installLifecycleFlush(client, runtime, {
|
|
823
|
+
captureLifecycle: options.captureLifecycle,
|
|
824
|
+
isMiniProgram: platformInfo.platform !== "web"
|
|
825
|
+
}),
|
|
826
|
+
installNavigationBreadcrumbs(client, runtime),
|
|
827
|
+
installTaroRequestErrors(client, options, runtime)
|
|
828
|
+
];
|
|
829
|
+
return {
|
|
830
|
+
client,
|
|
831
|
+
dispose() {
|
|
832
|
+
for (const dispose of disposeHooks) dispose();
|
|
833
|
+
client.close();
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
/** 读取首次进入页面的 path/query;小程序用当前页,H5 回退到 location。 */
|
|
838
|
+
function readInitialPage(runtime) {
|
|
839
|
+
try {
|
|
840
|
+
var _ref, _page$route;
|
|
841
|
+
const page = readCurrentPage(runtime);
|
|
842
|
+
const location = typeof window === "undefined" ? void 0 : window.location;
|
|
843
|
+
const pageQuery = (page === null || page === void 0 ? void 0 : page.options) && Object.keys(page.options).length > 0 ? page.options : void 0;
|
|
844
|
+
const query = pageQuery !== null && pageQuery !== void 0 ? pageQuery : queryOf(location === null || location === void 0 ? void 0 : location.search);
|
|
845
|
+
return _objectSpread2(_objectSpread2({ path: (_ref = (_page$route = page === null || page === void 0 ? void 0 : page.route) !== null && _page$route !== void 0 ? _page$route : page === null || page === void 0 ? void 0 : page.$taroPath) !== null && _ref !== void 0 ? _ref : location === null || location === void 0 ? void 0 : location.pathname }, query ? { query } : {}), (location === null || location === void 0 ? void 0 : location.href) ? { url: location.href } : {});
|
|
846
|
+
} catch (_unused) {
|
|
847
|
+
return {};
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
/** 把 H5 location.search 解析成可序列化对象。 */
|
|
851
|
+
function queryOf(search) {
|
|
852
|
+
if (!search) return void 0;
|
|
853
|
+
try {
|
|
854
|
+
const params = new URLSearchParams(search);
|
|
855
|
+
const result = {};
|
|
856
|
+
params.forEach((value, key) => {
|
|
857
|
+
result[key] = value;
|
|
858
|
+
});
|
|
859
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
860
|
+
} catch (_unused2) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
exports.detectPlatform = detectPlatform;
|
|
865
|
+
exports.getTaro = getTaro;
|
|
866
|
+
exports.initFirefly = initFirefly;
|
|
867
|
+
exports.readCurrentPage = readCurrentPage;
|
|
868
|
+
exports.readSystemInfo = readSystemInfo;
|
|
869
|
+
|
|
870
|
+
//# sourceMappingURL=index.cjs.map
|