@arms/rum-reactnative 0.1.4-beta.2 → 0.1.4
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 +1 -1
- package/docs/SDK /347/211/210/346/234/254/350/257/264/346/230/216.md" +8 -2
- package/lib/commonjs/collector/resource/api.js +1 -1
- package/lib/commonjs/utils/platform.js +1 -1
- package/lib/module/collector/resource/api.js +1 -1
- package/lib/module/utils/platform.js +1 -1
- package/lib/typescript/commonjs/src/collector/resource/api.d.ts +0 -2
- package/lib/typescript/module/src/collector/resource/api.d.ts +0 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -437,7 +437,7 @@ SDK 的 peerDependencies 声明为 `react-native: >=0.68.0`,原生构建配置
|
|
|
437
437
|
| JSC Promise rejection 兜底 | `globalThis.onunhandledrejection` | 0.68 | 非 Hermes 引擎有降级方案 |
|
|
438
438
|
| console.error 监听 | `interceptFunction(console, 'error')` | 0.68 | 全版本可用 |
|
|
439
439
|
| **API 性能监控** | `XMLHttpRequest.prototype` 拦截 | 0.68 | 全版本可用 |
|
|
440
|
-
| fetch
|
|
440
|
+
| fetch 采集 | 复用 `XMLHttpRequest.prototype` 拦截 | 0.68 | RN 的 fetch 由 whatwg-fetch 基于 XHR 实现,无需独立 hook(同时启用会重复上报) |
|
|
441
441
|
| 分布式链路追踪 | tracecontext / b3 / jaeger / sw8 | 0.68 | 纯 JS 实现,无原生依赖 |
|
|
442
442
|
| **页面导航追踪(PV)** | React Navigation `addListener('state')` | 0.68 | 兼容 React Navigation v5 / v6 |
|
|
443
443
|
| **用户行为采集(Action)** | patch `React.createElement` | 0.68 | 经典 JSX 运行时 |
|
|
@@ -4,9 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
## 版本列表
|
|
6
6
|
|
|
7
|
-
### v0.1.4(2026年
|
|
7
|
+
### v0.1.4(2026年10月)
|
|
8
8
|
|
|
9
|
-
iOS 看门狗终止(OOM)推断采集、RN 0.68-0.70
|
|
9
|
+
iOS 看门狗终止(OOM)推断采集、RN 0.68-0.70 原生兼容打通、API 采集合并为 XHR 单一通道与发布产物混淆修复。
|
|
10
|
+
|
|
11
|
+
- 新增 iOS OOM(看门狗终止/FOOM)事后推断采集,默认关闭需显式开启
|
|
12
|
+
- 打通 RN 0.68-0.70 原生兼容(Android 宿主需 Kotlin ≥1.8)
|
|
13
|
+
- API 采集合并为 XHR 单一通道:移除独立 fetch 劫持,统一由 XHR 劫持覆盖 fetch 请求,api 事件 type 统一标记为 XHR
|
|
14
|
+
- 修复发布流程,生产产物启用代码混淆压缩并移除 sourcemap
|
|
15
|
+
- `@arms/rum-core` 升级至 0.1.11 并同步收紧 peer 版本要求,接入方需同步升级
|
|
10
16
|
|
|
11
17
|
#### v0.1.4-beta.2(2026年09月23日)
|
|
12
18
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _rumCore=require("@arms/rum-core"),_base=require("../../utils/base"),_api=require("../../utils/api");class ApiCollector{name="api-collector";setup(e,t){!1!==(e.getConfig().collectors||{}).api&&(this.sendEvent=t,this.ctx=e,this.hackXhr())}injectTracing(e,t){const{tracing:r=!1,pid:s,version:i="1.0.0"}=this.ctx.getConfig(),{enable:a,sample:o,propagatorTypes:n,allowedUrls:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _rumCore=require("@arms/rum-core"),_base=require("../../utils/base"),_api=require("../../utils/api");class ApiCollector{name="api-collector";setup(e,t){!1!==(e.getConfig().collectors||{}).api&&(this.sendEvent=t,this.ctx=e,this.hackXhr())}injectTracing(e,t){const{tracing:r=!1,pid:s,version:i="1.0.0"}=this.ctx.getConfig(),{enable:a,sample:o,propagatorTypes:n,allowedUrls:p,tracestate:c,baggage:u=!1}=(0,_rumCore.parseTracingOptions)(r);if(!a)return;const d=(0,_rumCore.find)(p,t=>(0,_rumCore.matchList)([t.match],e.url||""));if(!d)return;let h=d.propagatorTypes;h&&0===h.length&&(h=n);let m=!1;h&&h.indexOf("sw8")>-1&&(h=["sw8"],m=!0);const l=this.ctx.session,g=m?(0,_rumCore.generateGUID)():(0,_rumCore.generateTraceId)(),C=m?(0,_rumCore.generateGUID)():(0,_rumCore.generateSpanId)(),_=(0,_rumCore.performDraw)(o),f=l.getUserId(),y=l.getSessionId(),v=c?`rum=v2&browser&${s}&${y}&${f}`:void 0,A=u?`rum=v2,appType=browser,pid=${s},sid=${y},uid=${f}`:void 0,R=(0,_rumCore.makeTracingHeaders)(g,C,_,h||[],{tracestate:v,baggage:A,appId:s,appVersion:i,viewName:e.view?.name});_&&(e.trace_id=g,e.trace_data=JSON.stringify({spanId:C,sample:o,sampled:_,headers:R})),t(R)}hackXhr(){const e=XMLHttpRequest.prototype,t=this;(0,_rumCore.interceptFunction)(e,"open",function(e,r,s,i,a){const o=t.ctx.getConfig().filters||{},n=String(r),p=e.toUpperCase();if((0,_rumCore.urlMatch)(n,o.resource)||"HEAD"===p||n.length>8182)return;this.apiCache={type:_api.ApiType.XHR,method:e,url:r,async:s,user:i,password:a,headers:{}};const c=t.ctx.session.getBaseEvent();this.apiAttr={...c,url:n,method:p}},!0),(0,_rumCore.interceptFunction)(e,"setRequestHeader",function(e,t){this.apiCache&&(this.apiCache.headers={...this.apiCache.headers,[e]:t})},!0),(0,_rumCore.interceptFunction)(e,"send",function(e){if(!this.apiAttr||!this.apiCache)return;let r=this.apiAttr;this.apiCache.data=e,t.injectTracing(this.apiAttr,e=>{Object.keys(e).forEach(t=>{e[t]&&this.setRequestHeader(t,e[t])})}),this.addEventListener("loadend",async()=>{const{status:e,statusText:s,response:i}=this,{evaluateApi:a}=t.ctx.getConfig();if(!this.apiAttr)return;r.status_code=e,r.message=s;const o={name:this.apiAttr.url,entryType:_api.ApiType.XHR,duration:(0,_base.getCurrentTime)()-r.timestamp};if((0,_rumCore.isFunction)(a))try{let e;r.success===_rumCore.ResourceStatus.Failed&&(e=new Error(_api.ApiType.XHR+" error"));const t=await(a?.(this.apiCache,i,e,this));this.apiAttr=r={...r,...(0,_api.reviseApiAttr)(t)}}catch(e){_rumCore.logger.warn("api-collector","evaluateApi failed for XHR",e)}t.sendAPI(r,o)}),this.addEventListener("error",()=>{this.apiAttr&&(this.apiAttr.success=_rumCore.ResourceStatus.Failed)}),this.addEventListener("abort",()=>{this.apiAttr&&(this.apiAttr.success=_rumCore.ResourceStatus.Failed,this.apiAttr.message="abort")})},!0)}sendAPI(e,t){const{parseResourceName:r}=this.ctx.getConfig(),{url:s,status_code:i,view:a}=e,o=(0,_api.getResourceSuccessByCode)(i),n={duration:t.duration},p={event_type:_rumCore.RumEventType.RESOURCE,url:s,name:(0,_api.getResourceName)(s||"",r),success:o,type:t.initiatorType||t.entryType,...e,timing_data:JSON.stringify(t),...n,view:a};this.sendEvent?.(p)}destroy(){this.sendEvent=()=>{};const e=XMLHttpRequest.prototype;(0,_rumCore.restoreFunction)(e,"open"),(0,_rumCore.restoreFunction)(e,"setRequestHeader"),(0,_rumCore.restoreFunction)(e,"send")}}exports.default=ApiCollector;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.appName=exports.VERSION=void 0,exports.clearStorage=clearStorage,exports.fixAttrs=void 0,exports.getAllStorageKeys=getAllStorageKeys,exports.getStorage=getStorage,exports.removeStorage=removeStorage,exports.setStorage=setStorage;var _rumCore=require("@arms/rum-core"),_reactNative=require("react-native"),_NativeRumSdkReactnative=_interopRequireDefault(require("../NativeRumSdkReactnative"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const _pkg={version:"0.1.4
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.appName=exports.VERSION=void 0,exports.clearStorage=clearStorage,exports.fixAttrs=void 0,exports.getAllStorageKeys=getAllStorageKeys,exports.getStorage=getStorage,exports.removeStorage=removeStorage,exports.setStorage=setStorage;var _rumCore=require("@arms/rum-core"),_reactNative=require("react-native"),_NativeRumSdkReactnative=_interopRequireDefault(require("../NativeRumSdkReactnative"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const _pkg={version:"0.1.4"},VERSION=exports.VERSION=_pkg.version,appName=exports.appName="react-native";function getReactNativeVersion(){try{return require("react-native/package.json").version??""}catch{const e=_reactNative.Platform.constants?.reactNativeVersion;return e?`${e.major}.${e.minor}.${e.patch}`:""}}function getStorage(e){return _NativeRumSdkReactnative.default.getItem(e)}function setStorage(e,t){return _NativeRumSdkReactnative.default.setItem(e,t)}function removeStorage(e){return _NativeRumSdkReactnative.default.removeItem(e)}function clearStorage(){return _NativeRumSdkReactnative.default.clear()}function getAllStorageKeys(){return _NativeRumSdkReactnative.default.getAllKeys()}async function fetchDeviceInfo(){try{return await _NativeRumSdkReactnative.default.getDeviceInfo()}catch(e){return console.warn("[rum] getDeviceInfo failed, falling back to JS defaults",e),{os_type:"ios"===_reactNative.Platform.OS?"iOS":"Android",os_version:String(_reactNative.Platform.Version??"")}}}let _cachedDeviceInfo=null;function getDeviceInfo(){return _cachedDeviceInfo||(_cachedDeviceInfo=fetchDeviceInfo()),_cachedDeviceInfo}const fixAttrs=async function(e){if(!e)return;const t=await getDeviceInfo(),r={id:t.device_id,type:t.device_type,brand:t.device_brand,model:t.device_model,name:t.device_name},a=getReactNativeVersion(),i={type:t.os_type??("ios"===_reactNative.Platform.OS?"iOS":"Android"),version:t.os_version??String(_reactNative.Platform.Version??""),container:appName,container_version:a||void 0};let o;if(t.viewport_width&&t.viewport_height)o={width:t.viewport_width,height:t.viewport_height};else try{const e=_reactNative.Dimensions.get("screen");o={width:Math.round(e.width),height:Math.round(e.height)}}catch{}return e.app.type=_rumCore.AppType.reactnative,e.app.package=e.app.package??t.app_package,e.app.version=e.app.version??t.app_version,e._v=VERSION,e.device={...r,...e.device},e.os={...i,...e.os},o&&(e.viewport={...e.viewport,...o}),e};exports.fixAttrs=fixAttrs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{find,generateGUID,generateSpanId,generateTraceId,
|
|
1
|
+
"use strict";import{find,generateGUID,generateSpanId,generateTraceId,interceptFunction,restoreFunction,isFunction,makeTracingHeaders,matchList,parseTracingOptions,performDraw,RumEventType,ResourceStatus,urlMatch,logger}from"@arms/rum-core";import{getCurrentTime}from"../../utils/base.js";import{ApiType,reviseApiAttr,getResourceName,getResourceSuccessByCode}from"../../utils/api.js";export default class ApiCollector{name="api-collector";setup(e,t){!1!==(e.getConfig().collectors||{}).api&&(this.sendEvent=t,this.ctx=e,this.hackXhr())}injectTracing(e,t){const{tracing:s=!1,pid:r,version:i="1.0.0"}=this.ctx.getConfig(),{enable:a,sample:n,propagatorTypes:o,allowedUrls:c,tracestate:p,baggage:u=!1}=parseTracingOptions(s);if(!a)return;const d=find(c,t=>matchList([t.match],e.url||""));if(!d)return;let h=d.propagatorTypes;h&&0===h.length&&(h=o);let g=!1;h&&h.indexOf("sw8")>-1&&(h=["sw8"],g=!0);const l=this.ctx.session,m=g?generateGUID():generateTraceId(),f=g?generateGUID():generateSpanId(),y=performDraw(n),A=l.getUserId(),v=l.getSessionId(),T=makeTracingHeaders(m,f,y,h||[],{tracestate:p?`rum=v2&browser&${r}&${v}&${A}`:void 0,baggage:u?`rum=v2,appType=browser,pid=${r},sid=${v},uid=${A}`:void 0,appId:r,appVersion:i,viewName:e.view?.name});y&&(e.trace_id=m,e.trace_data=JSON.stringify({spanId:f,sample:n,sampled:y,headers:T})),t(T)}hackXhr(){const e=XMLHttpRequest.prototype,t=this;interceptFunction(e,"open",function(e,s,r,i,a){const n=t.ctx.getConfig().filters||{},o=String(s),c=e.toUpperCase();if(urlMatch(o,n.resource)||"HEAD"===c||o.length>8182)return;this.apiCache={type:ApiType.XHR,method:e,url:s,async:r,user:i,password:a,headers:{}};const p=t.ctx.session.getBaseEvent();this.apiAttr={...p,url:o,method:c}},!0),interceptFunction(e,"setRequestHeader",function(e,t){this.apiCache&&(this.apiCache.headers={...this.apiCache.headers,[e]:t})},!0),interceptFunction(e,"send",function(e){if(!this.apiAttr||!this.apiCache)return;let s=this.apiAttr;this.apiCache.data=e,t.injectTracing(this.apiAttr,e=>{Object.keys(e).forEach(t=>{e[t]&&this.setRequestHeader(t,e[t])})}),this.addEventListener("loadend",async()=>{const{status:e,statusText:r,response:i}=this,{evaluateApi:a}=t.ctx.getConfig();if(!this.apiAttr)return;s.status_code=e,s.message=r;const n={name:this.apiAttr.url,entryType:ApiType.XHR,duration:getCurrentTime()-s.timestamp};if(isFunction(a))try{let e;s.success===ResourceStatus.Failed&&(e=new Error(ApiType.XHR+" error"));const t=await(a?.(this.apiCache,i,e,this));this.apiAttr=s={...s,...reviseApiAttr(t)}}catch(e){logger.warn("api-collector","evaluateApi failed for XHR",e)}t.sendAPI(s,n)}),this.addEventListener("error",()=>{this.apiAttr&&(this.apiAttr.success=ResourceStatus.Failed)}),this.addEventListener("abort",()=>{this.apiAttr&&(this.apiAttr.success=ResourceStatus.Failed,this.apiAttr.message="abort")})},!0)}sendAPI(e,t){const{parseResourceName:s}=this.ctx.getConfig(),{url:r,status_code:i,view:a}=e,n=getResourceSuccessByCode(i),o={duration:t.duration},c={event_type:RumEventType.RESOURCE,url:r,name:getResourceName(r||"",s),success:n,type:t.initiatorType||t.entryType,...e,timing_data:JSON.stringify(t),...o,view:a};this.sendEvent?.(c)}destroy(){this.sendEvent=()=>{};const e=XMLHttpRequest.prototype;restoreFunction(e,"open"),restoreFunction(e,"setRequestHeader"),restoreFunction(e,"send")}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{AppType}from"@arms/rum-core";import{Dimensions,Platform}from"react-native";import NativeRumSdkReactnative from"../NativeRumSdkReactnative.js";const _pkg={version:"0.1.4
|
|
1
|
+
"use strict";import{AppType}from"@arms/rum-core";import{Dimensions,Platform}from"react-native";import NativeRumSdkReactnative from"../NativeRumSdkReactnative.js";const _pkg={version:"0.1.4"};export const VERSION=_pkg.version;export const appName="react-native";function getReactNativeVersion(){try{return require("react-native/package.json").version??""}catch{const e=Platform.constants?.reactNativeVersion;return e?`${e.major}.${e.minor}.${e.patch}`:""}}export function getStorage(e){return NativeRumSdkReactnative.getItem(e)}export function setStorage(e,t){return NativeRumSdkReactnative.setItem(e,t)}export function removeStorage(e){return NativeRumSdkReactnative.removeItem(e)}export function clearStorage(){return NativeRumSdkReactnative.clear()}export function getAllStorageKeys(){return NativeRumSdkReactnative.getAllKeys()}async function fetchDeviceInfo(){try{return await NativeRumSdkReactnative.getDeviceInfo()}catch(e){return console.warn("[rum] getDeviceInfo failed, falling back to JS defaults",e),{os_type:"ios"===Platform.OS?"iOS":"Android",os_version:String(Platform.Version??"")}}}let _cachedDeviceInfo=null;function getDeviceInfo(){return _cachedDeviceInfo||(_cachedDeviceInfo=fetchDeviceInfo()),_cachedDeviceInfo}export const fixAttrs=async function(e){if(!e)return;const t=await getDeviceInfo(),i={id:t.device_id,type:t.device_type,brand:t.device_brand,model:t.device_model,name:t.device_name},r=getReactNativeVersion(),n={type:t.os_type??("ios"===Platform.OS?"iOS":"Android"),version:t.os_version??String(Platform.Version??""),container:appName,container_version:r||void 0};let o;if(t.viewport_width&&t.viewport_height)o={width:t.viewport_width,height:t.viewport_height};else try{const e=Dimensions.get("screen");o={width:Math.round(e.width),height:Math.round(e.height)}}catch{}return e.app.type=AppType.reactnative,e.app.package=e.app.package??t.app_package,e.app.version=e.app.version??t.app_version,e._v=VERSION,e.device={...i,...e.device},e.os={...n,...e.os},o&&(e.viewport={...e.viewport,...o}),e};
|
|
@@ -10,11 +10,9 @@ export default class ApiCollector implements ICollector {
|
|
|
10
10
|
name: string;
|
|
11
11
|
private ctx?;
|
|
12
12
|
private sendEvent?;
|
|
13
|
-
private originFetch;
|
|
14
13
|
setup(ctx: IContext, sendEvent: (payload: RumEvent) => void): void;
|
|
15
14
|
injectTracing(apiAttr: IApiAttr, inject: (tracingHeaders: ITracingHeaders) => void): void;
|
|
16
15
|
hackXhr(): void;
|
|
17
|
-
hackFetch(): void;
|
|
18
16
|
sendAPI(apiAttr: IApiAttr, entry: any): void;
|
|
19
17
|
destroy(): void;
|
|
20
18
|
}
|
|
@@ -10,11 +10,9 @@ export default class ApiCollector implements ICollector {
|
|
|
10
10
|
name: string;
|
|
11
11
|
private ctx?;
|
|
12
12
|
private sendEvent?;
|
|
13
|
-
private originFetch;
|
|
14
13
|
setup(ctx: IContext, sendEvent: (payload: RumEvent) => void): void;
|
|
15
14
|
injectTracing(apiAttr: IApiAttr, inject: (tracingHeaders: ITracingHeaders) => void): void;
|
|
16
15
|
hackXhr(): void;
|
|
17
|
-
hackFetch(): void;
|
|
18
16
|
sendAPI(apiAttr: IApiAttr, entry: any): void;
|
|
19
17
|
destroy(): void;
|
|
20
18
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arms/rum-reactnative",
|
|
3
|
-
"version": "0.1.4
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "RUM SDK For ReactNative",
|
|
5
5
|
"homepage": "https://help.aliyun.com/zh/arms/user-experience-monitoring/",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"access": "public"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@arms/rum-core": "0.1.
|
|
81
|
+
"@arms/rum-core": "0.1.11",
|
|
82
82
|
"@commitlint/config-conventional": "^19.6.0",
|
|
83
83
|
"@eslint/compat": "^1.2.7",
|
|
84
84
|
"@eslint/eslintrc": "^3.3.0",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
"typescript": "^5.8.3"
|
|
108
108
|
},
|
|
109
109
|
"peerDependencies": {
|
|
110
|
-
"@arms/rum-core": "0.1.
|
|
110
|
+
"@arms/rum-core": "0.1.11",
|
|
111
111
|
"react": "*",
|
|
112
112
|
"react-native": ">=0.68.0"
|
|
113
113
|
},
|