@arms/rum-miniapp 0.1.6 → 0.1.7
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 +146 -9
- package/dist/miniapp-sdk.js +1 -1
- package/docs/SDK/347/211/210/346/234/254/350/257/264/346/230/216.md +71 -0
- package/docs/SDK/351/205/215/347/275/256/345/217/202/350/200/203.md +523 -0
- package/docs//346/216/245/345/205/245/345/260/217/347/250/213/345/272/217/345/272/224/347/224/250.md +272 -0
- package/es/collector/action/index.d.ts +14 -0
- package/es/collector/action/index.js +1 -0
- package/es/collector/application/index.d.ts +15 -0
- package/es/collector/application/index.js +5 -0
- package/es/collector/exception/index.d.ts +29 -0
- package/es/collector/exception/index.js +7 -0
- package/es/collector/longtask/render-block.d.ts +15 -0
- package/es/collector/longtask/render-block.js +1 -0
- package/es/collector/resource/api.d.ts +28 -0
- package/es/collector/resource/api.js +19 -0
- package/es/collector/resource/static-resource.d.ts +10 -0
- package/es/collector/resource/static-resource.js +148 -0
- package/es/collector/view/perf.d.ts +26 -0
- package/es/collector/view/perf.js +10 -0
- package/es/collector/view/pv.d.ts +12 -0
- package/es/collector/view/pv.js +2 -0
- package/es/configManager.d.ts +13 -0
- package/es/configManager.js +7 -0
- package/es/empty.js +1 -0
- package/es/index.d.ts +3 -0
- package/es/index.js +1 -0
- package/es/processor/default-processor.d.ts +5 -0
- package/es/processor/default-processor.js +1 -0
- package/es/processor/session-processor.d.ts +8 -0
- package/es/processor/session-processor.js +1 -0
- package/es/reporter/index.d.ts +10 -0
- package/es/reporter/index.js +3 -0
- package/es/shell.d.ts +42 -0
- package/es/shell.js +10 -0
- package/es/style.js +1 -0
- package/es/types/client.d.ts +39 -0
- package/es/types/client.js +1 -0
- package/es/utils/api.d.ts +43 -0
- package/es/utils/api.js +3 -0
- package/es/utils/base.d.ts +19 -0
- package/es/utils/base.js +16 -0
- package/es/utils/constants.d.ts +1 -0
- package/es/utils/constants.js +1 -0
- package/es/utils/hackApp.d.ts +3 -0
- package/es/utils/hackApp.js +2 -0
- package/es/utils/hackComponent.d.ts +3 -0
- package/es/utils/hackComponent.js +5 -0
- package/es/utils/hackPage.d.ts +3 -0
- package/es/utils/hackPage.js +2 -0
- package/es/utils/network.d.ts +1 -0
- package/es/utils/network.js +1 -0
- package/es/utils/platform.d.ts +41 -0
- package/es/utils/platform.js +6 -0
- package/es/utils/session.d.ts +26 -0
- package/es/utils/session.js +4 -0
- package/es/utils/sse.d.ts +23 -0
- package/es/utils/sse.js +14 -0
- package/es/utils/url.d.ts +29 -0
- package/es/utils/url.js +16 -0
- package/es/utils/view.d.ts +32 -0
- package/es/utils/view.js +31 -0
- package/lib/collector/action/index.js +1 -1
- package/lib/collector/application/index.js +2 -2
- package/lib/collector/exception/index.js +3 -3
- package/lib/collector/longtask/render-block.js +1 -1
- package/lib/collector/resource/api.d.ts +1 -0
- package/lib/collector/resource/api.js +13 -7
- package/lib/collector/resource/static-resource.js +10 -10
- package/lib/collector/view/perf.js +6 -5
- package/lib/collector/view/pv.js +2 -2
- package/lib/configManager.js +6 -5
- package/lib/empty.js +2 -0
- package/lib/processor/default-processor.js +1 -1
- package/lib/processor/session-processor.js +1 -1
- package/lib/reporter/index.js +2 -2
- package/lib/shell.js +6 -6
- package/lib/types/client.d.ts +21 -2
- package/lib/utils/api.d.ts +13 -0
- package/lib/utils/api.js +3 -1
- package/lib/utils/base.js +1 -1
- package/lib/utils/hackApp.js +2 -2
- package/lib/utils/hackComponent.js +2 -2
- package/lib/utils/hackPage.js +2 -2
- package/lib/utils/platform.js +1 -1
- package/lib/utils/session.js +4 -2
- package/lib/utils/sse.d.ts +23 -0
- package/lib/utils/sse.js +14 -0
- package/lib/utils/url.js +2 -2
- package/package.json +12 -3
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ICollector, IContext, RumEvent } from '@arms/rum-core';
|
|
2
|
+
export default class PvCollector implements ICollector {
|
|
3
|
+
name: string;
|
|
4
|
+
ctx: IContext;
|
|
5
|
+
sendEvent: (payload: RumEvent) => void;
|
|
6
|
+
private prevPage;
|
|
7
|
+
setup(ctx: IContext, sendEvent: (payload: RumEvent) => void): void;
|
|
8
|
+
onUnload: () => void;
|
|
9
|
+
sendPv: (ops?: Record<string, unknown>) => void;
|
|
10
|
+
private getViewName;
|
|
11
|
+
destroy(): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{isFunction,isObject,isString,RumEventType}from"@arms/rum-core";import{getCurPage,getCurView,getRumViewId}from"../../utils/view";import{addPageListener,removePageListener}from"../../utils/hackPage";export default class PvCollector{constructor(){var a=this;this.name="pv-collector",this.ctx=void 0,this.sendEvent=void 0,this.prevPage=void 0,this.onUnload=function(){var b=getCurView(a.ctx);b&&b.id&&a.ctx.removeView(b.id)},this.sendPv=function(b){var c=getCurPage();if(c){var d=c.route,e=c.options,f=getRumViewId(c);if(!(a.prevPage&&f===a.prevPage.viewId))// 路由没有发生变化,不发送
|
|
2
|
+
{var g=f?"route_back":"initial_load";f=getRumViewId(c,a.ctx.session),a.prevPage={route:d,viewId:f};var h=a.getViewName(d);a.ctx.addView({id:f,name:h});var i={};e||(isFunction(c.getLoadOptions)?e=c.getLoadOptions():isObject(b)&&(e=b)),e&&Object.keys(e).forEach(function(a){var b=e[a];if(isString(b))try{i[a]=decodeURIComponent(b)}catch(c){i[a]=b}else i[a]=b}),a.sendEvent({event_type:RumEventType.VIEW,type:"pv",url:d,name:h,loading_type:g,snapshots:JSON.stringify(i).substring(0,5e3)})}}}}setup(a,b){this.ctx=a,this.sendEvent=b,this.sendPv(),addPageListener("onLoad",this.sendPv),addPageListener("onUnload",this.onUnload)}getViewName(a){var b=this.ctx.getConfig(),c=b.parseViewName,d=a;return isFunction(c)&&(d=c(a)),d}destroy(){removePageListener("onLoad",this.sendPv),removePageListener("onUnload",this.onUnload)}}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ConfigManager, IContext, IConfiguration, ICacheConfiguration } from "@arms/rum-core";
|
|
2
|
+
import { IMiniappConfig } from "./types/client";
|
|
3
|
+
export default class MiniappConfigManager extends ConfigManager {
|
|
4
|
+
private version;
|
|
5
|
+
fetchRemoteCfg(config: IConfiguration): Promise<unknown>;
|
|
6
|
+
private getV1Config;
|
|
7
|
+
private getV2Config;
|
|
8
|
+
getCacheConfig(): ICacheConfiguration;
|
|
9
|
+
setCacheConfig(remoteCfg: ICacheConfiguration): void;
|
|
10
|
+
getRemoteConfigUrl(): string;
|
|
11
|
+
parseConfig(json: any): Partial<IMiniappConfig>;
|
|
12
|
+
}
|
|
13
|
+
export declare function checkEnable(ctx: IContext, key: string, def?: boolean): boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{ConfigManager,getUrlParams,parseRule2Match,isBoolean,isObject}from"@arms/rum-core";import sdk,{getStorageSync,setStorageSync}from"./utils/platform";import{getURL}from"./utils/url";var LOCAL_STORE_CONFIG_KEY="arms_rum2_local_config";function parseV2Config(a){var b,c={};c.enable=null===(b=a.enable)||void 0===b||b;// 处理Session配置
|
|
2
|
+
var d=a.session;if(d){var e,f,g={};g.sampling=null!==(e=d.sampling)&&void 0!==e?e:100,g.storage=null!==(f=d.storage)&&void 0!==f?f:"auto",c.sessionConfig=g}// 处理上报配置
|
|
3
|
+
var h=a.report;if(h){var i={};i.flushTime=h.flush_interval,i.maxEventCount=h.max_batch_count,c.reportConfig=i}// 处理链路追踪
|
|
4
|
+
var j=a.tracing;if(j){var k,l={};l.enable=null===(k=j.enable)||void 0===k||k;var m=[];(j.rules||[]).forEach(function(a){var b={enable:a.enable,tracestate:a.tracestate,baggage:a.baggage,propagatorTypes:a.protocols,sampling:a.sampling};return"{location.origin}"===a.match?void(l={...l,...b}):void(b.match=parseRule2Match(a),m.push(b))}),l.allowedUrls=m,c.tracing=l}// 处理采集器
|
|
5
|
+
var n=a.collectors;if(n&&0<Object.keys(n).length){var o={};n.forEach(function(a){var b=a.name;if(b){var c={...a},d=a.filters;0<(null===d||void 0===d?void 0:d.length)&&(c.filters=c.filters.map(function(a){return parseRule2Match(a)})),o[b]=c}}),c.collectors={...c.collectors,...o}}return c}export default class MiniappConfigManager extends ConfigManager{constructor(...a){super(...a),this.version="v2"}async fetchRemoteCfg(){var a=this.getRemoteConfigUrl();return a?a.includes(".rum.aliyuncs.com")?(this.version="v1",this.getV1Config(a)):this.getV2Config(a):void 0}async getV1Config(a){// return fetch(url).then(res => res.json());
|
|
6
|
+
return new Promise(function(b,c){var d=sdk.request||sdk.httpRequest;d({url:a,method:"GET",success:function(a){b(a)},fail:function(a){c(a)}})})}async getV2Config(a){var b=getUrlParams(a),c={instanceId:"",agentType:"rum_web_sdk",attributes:b,instanceConfigs:[{configType:"rum_web_config",version:1}],capabilities:2};return new Promise(function(b,d){var e=sdk.request||sdk.httpRequest;e({url:a,method:"POST",data:JSON.stringify(c),header:{"Content-Type":"application/json","x-log-apiversion":"0.6.0"},success:function(a){b(a)},fail:function(a){d(a)}})})}getCacheConfig(){var a=getStorageSync(LOCAL_STORE_CONFIG_KEY);if(a){var b,c=this.currentConfig;try{if(b=JSON.parse(a),"pid"in b&&b.pid===c.pid||"endpoint"in b&&b.endpoint)return b.content=this.parseConfig(b.content),b}catch(a){//
|
|
7
|
+
}return b}}setCacheConfig(a){var b=this.currentConfig,c={...a,pid:b.pid,endpoint:b.endpoint};setStorageSync(LOCAL_STORE_CONFIG_KEY,JSON.stringify(c))}getRemoteConfigUrl(){var a=this.currentConfig,b=a.pid,c=a.remoteConfig,d=a.endpoint,e=c||{},f=e.url,g=e.region;if(f)return f;if(b){var h=b.split("@");return!h||2>h.length?void 0:"https://"+h[0]+"-sdk.rum.aliyuncs.com/config/"+(g||"cn-hangzhou")+"/"+h[1]+"?t="+Date.now()}var i=getURL(d);return i.protocol+"://"+i.hostname+"/agentconfig?workspace="+i.searchParams.workspace+"&service="+i.searchParams.service_id}parseConfig(a){try{var b=a.data||a,c=b.instanceConfigs[0].config;return"v2"===this.version?parseV2Config(JSON.parse(c)):a}catch(b){return a}}}export function checkEnable(a,b,c=!0){var d,e=a.getConfig();if(!1===e.enable)return!1;var f=null===(d=e.collectors)||void 0===d?void 0:d[b];return isBoolean(f)?f:isObject(f)&&"enable"in f?f.enable:c}
|
package/es/empty.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// empty module placeholder for tree-shaking unused core modules
|
package/es/index.d.ts
ADDED
package/es/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import armsRum,{ArmsRum}from"./shell";export{ArmsRum};export default armsRum;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getCurrentTime}from"../utils/base";import{getCurView}from"../utils/view";export default class DefaultProcessor{constructor(){this.name="default-processor"}process(a){var b=a.getRumEvent(),c=getCurView(a),d={timestamp:getCurrentTime(),session_id:a.session.getSessionId(),event_id:a.session.getEventId(),view:c,...b};return d}}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IContext, IProcessor } from "@arms/rum-core";
|
|
2
|
+
export default class SessionProcessor implements IProcessor {
|
|
3
|
+
name: string;
|
|
4
|
+
ctx: IContext;
|
|
5
|
+
setup(ctx: IContext): void;
|
|
6
|
+
update: (e?: Event) => void;
|
|
7
|
+
process(ctx: IContext): import("@arms/rum-core").RumEvent;
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{debounce,ONE_SECOND}from"@arms/rum-core";import{addPageListener}from"../utils/hackPage";export default class SessionProcessor{constructor(){var a=this;this.name="session-processor",this.ctx=void 0,this.update=function(b){b&&!b.isTrusted||a.ctx.session.updateSession()}}setup(a){var b=this;this.ctx=a,this.update=debounce(this.update,ONE_SECOND),addPageListener("*",function(a){a&&a.type&&a.target&&b.update()})}process(a){return this.update(),a.getRumEvent()}}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IContext, IReporter, Reporter, RumEventBundle } from '@arms/rum-core';
|
|
2
|
+
/**
|
|
3
|
+
* miniapp reporter
|
|
4
|
+
*/
|
|
5
|
+
declare class MiniappReporter extends Reporter implements IReporter {
|
|
6
|
+
name: string;
|
|
7
|
+
init(ctx: IContext): void;
|
|
8
|
+
request(ctx: IContext, bundle: RumEventBundle): void;
|
|
9
|
+
}
|
|
10
|
+
export default MiniappReporter;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{AppType,isFunction,Reporter}from"@arms/rum-core";import sdk,{VERSION}from"../utils/platform";/**
|
|
2
|
+
* miniapp reporter
|
|
3
|
+
*/class MiniappReporter extends Reporter{constructor(...a){super(...a),this.name="miniapp-reporter"}init(){var a=this;isFunction(sdk.onAppHide)&&sdk.onAppHide(function(){a.flushEventQueue()})}request(a,b){var c=a.getConfig();try{b.app.type=AppType.miniapp,b._v=VERSION;var d=sdk.request||sdk.httpRequest;d({url:c.endpoint,method:"POST",dataType:"text",data:JSON.stringify(b)})}catch(a){console.warn("[arms] sendRequest fail",a)}}}export default MiniappReporter;
|
package/es/shell.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Shell } from '@arms/rum-core';
|
|
2
|
+
import PvCollector from './collector/view/pv';
|
|
3
|
+
import PerfCollector from './collector/view/perf';
|
|
4
|
+
import ExceptionCollector from './collector/exception';
|
|
5
|
+
import ApiCollector from './collector/resource/api';
|
|
6
|
+
import ActionCollector from './collector/action';
|
|
7
|
+
import ApplicationCollector from './collector/application';
|
|
8
|
+
import RenderBlockCollector from './collector/longtask/render-block';
|
|
9
|
+
import { IMiniappConfig } from './types/client';
|
|
10
|
+
declare const builtInCollectors: readonly [typeof PvCollector, typeof PerfCollector, typeof ExceptionCollector, typeof ApiCollector, typeof ActionCollector, typeof ApplicationCollector, typeof RenderBlockCollector];
|
|
11
|
+
type CollectorName = (typeof builtInCollectors)[number]['prototype']['name'];
|
|
12
|
+
type CollectorMap = {
|
|
13
|
+
[K in CollectorName]: InstanceType<Extract<(typeof builtInCollectors)[number], {
|
|
14
|
+
prototype: {
|
|
15
|
+
name: K;
|
|
16
|
+
};
|
|
17
|
+
}>>;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* 对外导出 shell 层, 所有 shell 层模型的 API 设计约定:
|
|
21
|
+
* 1. API 命名空间按照 variables / functions / events 来组织
|
|
22
|
+
* 2. 事件(events)的命名格式为:on[Will|Did]VerbNoun?,参考 https://code.visualstudio.com/api/references/vscode-api#events
|
|
23
|
+
* 3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
|
|
24
|
+
*/
|
|
25
|
+
export declare class ArmsRum extends Shell {
|
|
26
|
+
version: string;
|
|
27
|
+
private configManager;
|
|
28
|
+
/**
|
|
29
|
+
* 初始化
|
|
30
|
+
*/
|
|
31
|
+
init(configuration: IMiniappConfig): Promise<this>;
|
|
32
|
+
updateNetType: (type: string) => void;
|
|
33
|
+
getConfig(): import("@arms/rum-core").IConfiguration;
|
|
34
|
+
/**
|
|
35
|
+
* set config
|
|
36
|
+
*/
|
|
37
|
+
setConfig<T extends keyof IMiniappConfig>(key: T, value: IMiniappConfig[T]): void;
|
|
38
|
+
setConfig(value: IMiniappConfig): void;
|
|
39
|
+
getCollector<T extends CollectorName>(name: T): CollectorMap[T] | undefined;
|
|
40
|
+
}
|
|
41
|
+
declare const _default: ArmsRum;
|
|
42
|
+
export default _default;
|
package/es/shell.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{Shell}from"@arms/rum-core";import PvCollector from"./collector/view/pv";import PerfCollector from"./collector/view/perf";import ExceptionCollector from"./collector/exception";import ApiCollector from"./collector/resource/api";import ActionCollector from"./collector/action";import ApplicationCollector from"./collector/application";import RenderBlockCollector from"./collector/longtask/render-block";import DefaultProcessor from"./processor/default-processor";import SessionProcessor from"./processor/session-processor";import Reporter from"./reporter";import{getNetType}from"./utils/network";import{VERSION}from"./utils/platform";import{RumSession}from"./utils/session";import MiniappConfigManager from"./configManager";var builtInCollectors=[PvCollector,PerfCollector,ExceptionCollector,ApiCollector,ActionCollector,ApplicationCollector,RenderBlockCollector];/**
|
|
2
|
+
* 对外导出 shell 层, 所有 shell 层模型的 API 设计约定:
|
|
3
|
+
* 1. API 命名空间按照 variables / functions / events 来组织
|
|
4
|
+
* 2. 事件(events)的命名格式为:on[Will|Did]VerbNoun?,参考 https://code.visualstudio.com/api/references/vscode-api#events
|
|
5
|
+
* 3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
|
|
6
|
+
*/export class ArmsRum extends Shell{constructor(...a){var b;super(...a),b=this,this.version=VERSION,this.configManager=void 0,this.updateNetType=function(a){var c=b.getConfig().net||{};b.setConfig("net",{...c,type:a})}}/**
|
|
7
|
+
* 初始化
|
|
8
|
+
*/async init(a){this.configManager=new MiniappConfigManager,await this.configManager.init(a);var b=this.configManager.getConfig();if(!1!==b.enable)return this.client.useCollectors(builtInCollectors.map(function(a){return new a})),this.client.useProcessors([new DefaultProcessor,new SessionProcessor]),this.client.useReporter(new Reporter),this.client.init(b,new RumSession,this.configManager),getNetType(this.updateNetType),this}getConfig(){var a;return null===(a=this.configManager)||void 0===a?void 0:a.getConfig()}/**
|
|
9
|
+
* set config
|
|
10
|
+
*/setConfig(...a){var b=this.configManager;if(b)if(2===a.length){var c,d=b.getConfig();b.setConfig((c={},c[a[0]]=a[1],c))}else b.setConfig(a[0])}getCollector(a){return this.client.getCollectors().find(function(b){return b.name===a})}}export default new ArmsRum;
|
package/es/style.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//empty file
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { IConfiguration, ICollectorConfig, ITracingOption } from "@arms/rum-core";
|
|
2
|
+
import { IApiBaseAttr, ISseCollectorConfig } from "../utils/api";
|
|
3
|
+
export interface IMiniappConfig extends IConfiguration {
|
|
4
|
+
/**
|
|
5
|
+
* view.name 解析
|
|
6
|
+
*/
|
|
7
|
+
parseViewName?(url: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* resource.name 解析
|
|
10
|
+
*/
|
|
11
|
+
parseResourceName?(url: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* tracing 配置 'tracecontext' | 'b3' | 'b3multi' | 'jaeger';
|
|
14
|
+
*/
|
|
15
|
+
tracing?: boolean | ITracingOption;
|
|
16
|
+
/**
|
|
17
|
+
* request 自定义解析;
|
|
18
|
+
*/
|
|
19
|
+
evaluateApi?(request: any, response: any, error?: Error): Promise<IApiBaseAttr>;
|
|
20
|
+
/**
|
|
21
|
+
* 各个 collector 配置
|
|
22
|
+
* 在小程序端扩展了 api 采集器的类型,支持 SSE 子配置
|
|
23
|
+
*/
|
|
24
|
+
collectors?: {
|
|
25
|
+
[key: string]: boolean | ICollectorConfig;
|
|
26
|
+
} & {
|
|
27
|
+
/**
|
|
28
|
+
* API 采集器配置
|
|
29
|
+
* 支持通用的采集器配置,并扩展了 SSE 子配置
|
|
30
|
+
*/
|
|
31
|
+
api?: boolean | (ICollectorConfig & {
|
|
32
|
+
/**
|
|
33
|
+
* SSE 采集器子配置
|
|
34
|
+
* 控制 SSE 流的启用和超时策略(仅微信小程序支持)
|
|
35
|
+
*/
|
|
36
|
+
sse?: ISseCollectorConfig;
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BaseObject, IViewData, ResourceStatus } from "@arms/rum-core";
|
|
2
|
+
export interface IMeasure {
|
|
3
|
+
[key: string]: number;
|
|
4
|
+
}
|
|
5
|
+
export interface IApiBaseAttr {
|
|
6
|
+
name?: string;
|
|
7
|
+
message?: string;
|
|
8
|
+
success?: ResourceStatus;
|
|
9
|
+
duration?: number;
|
|
10
|
+
status_code?: number | string;
|
|
11
|
+
snapshots?: string;
|
|
12
|
+
properties?: BaseObject;
|
|
13
|
+
}
|
|
14
|
+
export interface IApiAttr extends IApiBaseAttr {
|
|
15
|
+
view: IViewData;
|
|
16
|
+
url: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
timestamp: number;
|
|
19
|
+
method: string;
|
|
20
|
+
trace_id?: string;
|
|
21
|
+
trace_data?: string;
|
|
22
|
+
sse?: ISseMetrics;
|
|
23
|
+
}
|
|
24
|
+
export interface ISseMetrics {
|
|
25
|
+
status: 'success' | 'error' | 'timeout' | 'abort';
|
|
26
|
+
time_to_first_token?: number;
|
|
27
|
+
inter_token_latency_avg?: number;
|
|
28
|
+
inter_token_latency_max?: number;
|
|
29
|
+
message_count?: number;
|
|
30
|
+
timing_data?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ISseCollectorConfig {
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
timeout?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface Options {
|
|
37
|
+
url: string;
|
|
38
|
+
method?: string;
|
|
39
|
+
header?: any;
|
|
40
|
+
success?: (res: any) => void;
|
|
41
|
+
fail?: (res: any) => void;
|
|
42
|
+
}
|
|
43
|
+
export declare function reviseApiAttr(attrs: IApiBaseAttr): IApiBaseAttr;
|
package/es/utils/api.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{isNumber,isObject,isString,verifyProperties}from"@arms/rum-core";// SSE 协议层指标 - 对齐浏览器端 ISseMetrics
|
|
2
|
+
// SSE 采集器子配置
|
|
3
|
+
export function reviseApiAttr(a){if(isObject(a)){var b={};isString(a.name)&&(b.name=a.name.substring(0,1e3)),isString(a.message)&&(b.message=a.message.substring(0,1e3)),"success"in a&&(b.success=a.success?1:0),isNumber(a.duration)&&0<=a.duration&&(b.duration=a.duration),isString(a.status_code)&&(b.status_code=a.status_code.substring(0,100)),isNumber(a.status_code)&&(b.status_code=a.status_code),isString(a.snapshots)&&(b.snapshots=a.snapshots.substring(0,5e3));var c=verifyProperties(a.properties);return c&&(b.properties=c),b}}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 保留指定位数的小数
|
|
3
|
+
* @param num 原数据
|
|
4
|
+
* @param decimal 小数位数
|
|
5
|
+
* @returns
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatNumber(num: number, decimal?: number): number;
|
|
8
|
+
/**
|
|
9
|
+
* 获取获取当前时间 fix Data.now() 存在的缺陷
|
|
10
|
+
* duration方法用于计算时间跨度,由于Date.now存在bug,可能为负数,尽可能使用performance.now计算
|
|
11
|
+
* https://blog.insiderattack.net/how-not-to-measure-time-in-programming-11089d546180
|
|
12
|
+
* 目前(2022年10月29日15:56:26)只有微信支持wx.getPerformance,具备now的功能,但功能仅仅是封装了Date.now
|
|
13
|
+
* qq支持getPerformance,但返回的依然是Date.now()
|
|
14
|
+
* 字节跳动支持 tt.performance 但不支持now方法
|
|
15
|
+
* 微信、百度、字节小程序支持 performance.now
|
|
16
|
+
* 支付宝、钉钉小程序占不支持 performance.now
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
export declare function getCurrentTime(timeOffset?: number): number;
|
package/es/utils/base.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{getPerformance}from"./platform";/**
|
|
2
|
+
* 保留指定位数的小数
|
|
3
|
+
* @param num 原数据
|
|
4
|
+
* @param decimal 小数位数
|
|
5
|
+
* @returns
|
|
6
|
+
*/export function formatNumber(a,b=3){if(!a)return a;var c=a.toString(),d=c.indexOf(".");return c=-1===d?c.substring(0):c.substring(0,b+d+1),parseFloat(c)}/**
|
|
7
|
+
* 获取获取当前时间 fix Data.now() 存在的缺陷
|
|
8
|
+
* duration方法用于计算时间跨度,由于Date.now存在bug,可能为负数,尽可能使用performance.now计算
|
|
9
|
+
* https://blog.insiderattack.net/how-not-to-measure-time-in-programming-11089d546180
|
|
10
|
+
* 目前(2022年10月29日15:56:26)只有微信支持wx.getPerformance,具备now的功能,但功能仅仅是封装了Date.now
|
|
11
|
+
* qq支持getPerformance,但返回的依然是Date.now()
|
|
12
|
+
* 字节跳动支持 tt.performance 但不支持now方法
|
|
13
|
+
* 微信、百度、字节小程序支持 performance.now
|
|
14
|
+
* 支付宝、钉钉小程序占不支持 performance.now
|
|
15
|
+
* @returns
|
|
16
|
+
*/export function getCurrentTime(a){var b=getPerformance(),c=0;return b&&b.timeOrigin&&b.now&&(c=Math.round(b.timeOrigin+(a?a:b.now()))),1e12>c&&(c=new Date().getTime()),c}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const COMMON_DELAY = 200;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export var COMMON_DELAY=200;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{interceptFunction}from"@arms/rum-core";import{appName}from"./platform";var listeners={onLaunch:[],"*":[]};function hackPage(a){Object.keys(listeners).forEach(function(b){"swan"===appName&&Object.defineProperty(a,b,{writable:!0});"*"===b||interceptFunction(a,b,function(...a){var c=this,d=[...listeners[b],...listeners["*"]];d.forEach(function(b){b.apply(c,a)})},!0)})}export var originalApp=App;App=function(...a){try{hackPage.apply(this,a)}catch(a){//
|
|
2
|
+
}return originalApp.apply(this,a)},Object.keys(originalApp).forEach(function(a){App[a]=originalApp[a]});export function addAppListener(a,b){a in listeners||(listeners[a]=[]),listeners[a].push(b)}export function removeAppListener(a,b){if(a in listeners){var c=listeners[a],d=c.indexOf(b);c.splice(d,1)}}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{interceptFunction,isFunction}from"@arms/rum-core";import{appName}from"./platform";var listnersMap=new Map;["methods","lifetimes"].forEach(function(a){listnersMap.set(a,{})});var componentLifetimes=["created","attached","ready","moved","detached","error"],ignores=[// 'onLoad',
|
|
2
|
+
"onShow",// 'onReady',
|
|
3
|
+
"onHide",// 'onUnload',
|
|
4
|
+
"onPullDownRefresh","onReachBottom","onShareAppMessage","onShareTimeline","onAddToFavorites","onPageScroll","onResize","onTabItemTap","onSaveExitState",...componentLifetimes];function hackComponent(a,b){var c=listnersMap.get(b);Object.keys(a).forEach(function(b){var d=a[b];!isFunction(d)||ignores.includes(b)||b in c||(c[b]=[])}),Object.keys(c).forEach(function(d){var e=a;"swan"===appName&&Object.defineProperty(e,d,{writable:!0});"*"===d||("lifetimes"===b&&!isFunction(e[d])&&(!e.lifetimes&&(e.lifetimes={}),e=e.lifetimes),interceptFunction(e,d,function(...a){var b=this,e=[...c[d],...(c["*"]||[])];e.forEach(function(c){c.apply(b,a)})},!0))})}export var originalComponent=Component;Component=function(...a){try{var b=a[0]||{};b.methods||(b.methods={}),b.lifetimes||(b.lifetimes={}),hackComponent.call(this,b.methods,"methods"),hackComponent.call(this,b,"lifetimes")}catch(a){//
|
|
5
|
+
}return originalComponent.apply(this,a)},Object.keys(originalComponent).forEach(function(a){Component[a]=originalComponent[a]});export function addComponentListener(a,b){var c;c=componentLifetimes.includes(a)?listnersMap.get("lifetimes"):listnersMap.get("methods"),a in c||(c[a]=[]),c[a].push(b)}export function removeComponentListener(a,b){var c;if(c=componentLifetimes.includes(a)?listnersMap.get("lifetimes"):listnersMap.get("methods"),!!(a in c)){var d=c[a],e=d.indexOf(b);d.splice(e,1)}}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{interceptFunction,isFunction}from"@arms/rum-core";import{appName}from"./platform";import{addComponentListener,removeComponentListener}from"./hackComponent";var listeners={onLoad:[],onShow:[],onHide:[],onUnload:[],"*":[]},ignores=["onLoad","onShow","onReady","onHide","onUnload","onPullDownRefresh","onReachBottom","onShareAppMessage","onShareTimeline","onAddToFavorites","onPageScroll","onResize","onTabItemTap","onSaveExitState"];function hackPage(a){Object.keys(a).forEach(function(b){var c=a[b];!isFunction(c)||ignores.includes(b)||b in listeners||(listeners[b]=[])}),Object.keys(listeners).forEach(function(b){"swan"===appName&&Object.defineProperty(a,b,{writable:!0});"*"===b||interceptFunction(a,b,function(...a){var c=this,d=[...listeners[b],...listeners["*"]];d.forEach(function(b){b.apply(c,a)})},!0)})}export var originalPage=Page;Page=function(...a){try{hackPage.apply(this,a)}catch(a){//
|
|
2
|
+
}return originalPage.apply(this,a)},Object.keys(originalPage).forEach(function(a){Page[a]=originalPage[a]});export function addPageListener(a,b,c=!1){c||addComponentListener(a,b),a in listeners||(listeners[a]=[]),listeners[a].push(b)}export function removePageListener(a,b,c=!1){if(c||removeComponentListener(a,b),!!(a in listeners)){var d=listeners[a],e=d.indexOf(b);d.splice(e,1)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getNetType(callback: (s: string) => void): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import sdk from"./platform";export function getNetType(a){sdk.getNetworkType&&sdk.getNetworkType({success:function(b){var c=b.networkType||b.subtype;a(c?c.toLowerCase():void 0)}}),sdk.onNetworkStatusChange&&sdk.onNetworkStatusChange(function(b){var c=b.networkType||b.subtype;a(c?c.toLowerCase():void 0)})}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const VERSION: string;
|
|
2
|
+
export interface Page {
|
|
3
|
+
route: string;
|
|
4
|
+
is: string;
|
|
5
|
+
getPageId: () => string;
|
|
6
|
+
__rum_view_id?: string;
|
|
7
|
+
options?: Record<string, unknown>;
|
|
8
|
+
getLoadOptions?: () => Record<string, string | number>;
|
|
9
|
+
}
|
|
10
|
+
interface SDK {
|
|
11
|
+
onAppShow: (listener: Function) => void;
|
|
12
|
+
onAppHide: (listener: Function) => void;
|
|
13
|
+
onError: (listener: Function) => void;
|
|
14
|
+
onUnhandledRejection: (listener: Function) => void;
|
|
15
|
+
offError: (listener: Function) => void;
|
|
16
|
+
request: (options: any) => void;
|
|
17
|
+
httpRequest: (options: any) => void;
|
|
18
|
+
getStorageSync: (key: any) => any;
|
|
19
|
+
setStorageSync: (key: any, data?: string) => void;
|
|
20
|
+
getNetworkType: (listener: any) => void;
|
|
21
|
+
onNetworkStatusChange: (listener: any) => void;
|
|
22
|
+
getPerformance: () => any;
|
|
23
|
+
onTouchEnd: (listener: any) => void;
|
|
24
|
+
offTouchEnd: (listener: any) => void;
|
|
25
|
+
performance: any;
|
|
26
|
+
getLaunchOptionsSync: () => any;
|
|
27
|
+
}
|
|
28
|
+
export declare const qqName = "qq";
|
|
29
|
+
export declare const bytedanceName = "bytedance";
|
|
30
|
+
export declare const wechatName = "wechat";
|
|
31
|
+
export declare const dingtalkName = "dingtalk";
|
|
32
|
+
export declare const alipayName = "alipay";
|
|
33
|
+
export declare const swanName = "swan";
|
|
34
|
+
export declare const jdName = "jd";
|
|
35
|
+
export declare const ksName = "ks";
|
|
36
|
+
export declare const sdk: SDK, appName: string;
|
|
37
|
+
export declare function getStorageSync(key: string): any;
|
|
38
|
+
export declare function setStorageSync(key: string, data: string): void;
|
|
39
|
+
export declare function getPerformance(): any;
|
|
40
|
+
export declare const HEADER_KEY: string;
|
|
41
|
+
export default sdk;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export var VERSION='npm-0.1.7';var OBJ="object";export var qqName="qq";export var bytedanceName="bytedance";export var wechatName="wechat";export var dingtalkName="dingtalk";export var alipayName="alipay";export var swanName="swan";export var jdName="jd";export var ksName="ks";function isFunc(a){return"function"==typeof a}/**
|
|
2
|
+
* 获取跨平台的 SDK
|
|
3
|
+
*/function getSDK(){var a,b="unknown";if(typeof ks==OBJ)a=ks,b=ksName;else if(typeof swan==OBJ)a=swan,b=swanName;else if(typeof qq==OBJ)// qq的全局也有wx命名空间,和qq等效,这会导致判断AppName失效
|
|
4
|
+
a=qq,b=qqName;else if(typeof tt==OBJ)// 字节的全局也有wx命名空间,和tt等效,这会导致判断AppName失效
|
|
5
|
+
a=tt,b=bytedanceName;else if(typeof dd==OBJ)// dd 必须出现在 my之前,因为现在dd环境里也有my
|
|
6
|
+
a=dd,b=dingtalkName;else if(typeof my==OBJ)a=my,b=alipayName;else if(typeof jd==OBJ)a=jd,b=jdName;else if(typeof wx==OBJ)a=wx,b=wechatName;else throw new Error("Current platform is not supported.");return{sdk:a,appName:b}}var _getSDK=getSDK(),sdk=_getSDK.sdk,appName=_getSDK.appName;export{sdk,appName};export function getStorageSync(a){return isFunc(sdk.getStorageSync)?appName===alipayName||appName===dingtalkName?sdk.getStorageSync({key:a}).data:sdk.getStorageSync(a):void 0}export function setStorageSync(a,b){return isFunc(sdk.getStorageSync)?appName===alipayName||appName===dingtalkName?sdk.setStorageSync({key:a,data:b}):sdk.setStorageSync(a,b):void 0}export function getPerformance(){return isFunc(sdk.getPerformance)?sdk.getPerformance():"performance"in sdk?sdk.performance:void 0}export var HEADER_KEY=function(){return"alipay"===appName?"headers":"header"}();export default sdk;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { IContext, IRumSession, RumEvent, SessionConfig } from "@arms/rum-core";
|
|
2
|
+
interface SessionInfo {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
sampled: boolean;
|
|
5
|
+
startTime: number;
|
|
6
|
+
lastTime: number;
|
|
7
|
+
isNew?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class RumSession implements IRumSession {
|
|
10
|
+
ctx: IContext;
|
|
11
|
+
sessionConfig: SessionConfig;
|
|
12
|
+
init(ctx: IContext): void;
|
|
13
|
+
getSessionId(): string;
|
|
14
|
+
getSampled(): boolean;
|
|
15
|
+
checkSession(info: SessionInfo): boolean;
|
|
16
|
+
updateSession(): void;
|
|
17
|
+
getSessionInfo(): SessionInfo;
|
|
18
|
+
getEventId(): string;
|
|
19
|
+
getViewId(): string;
|
|
20
|
+
getUserId(): any;
|
|
21
|
+
private resetSession;
|
|
22
|
+
private getUUID;
|
|
23
|
+
private fixSessionConfig;
|
|
24
|
+
getBaseEvent(): RumEvent;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{generateEventId,generateGUID,generateSpanId,isNumber,ONE_DAY,ONE_HOUR,ONE_MINUTE,performDraw}from"@arms/rum-core";import{getCurrentTime}from"./base";import{getCurView}from"./view";import{getStorageSync,setStorageSync}from"./platform";// 存储userID的键名
|
|
2
|
+
var USER_ID="_arms_uid",RUM_SESSION="_arms_session";// 存储session
|
|
3
|
+
export class RumSession{constructor(){this.ctx=void 0,this.sessionConfig=void 0}init(a){var b;this.ctx=a,this.sessionConfig=this.fixSessionConfig(null===(b=a.config)||void 0===b?void 0:b.sessionConfig)}getSessionId(){return this.getSessionInfo().sessionId}getSampled(){return this.getSessionInfo().sampled}checkSession(a){var b=this.sessionConfig,c=b.overtime,d=b.maxDuration,e=getCurrentTime();return!(a.startTime+d<e||a.lastTime+c<e)}updateSession(){var a=this.getSessionInfo();if(!a.isNew){var b=a.startTime,c=getCurrentTime(),d=a.sampled?1:0;setStorageSync(RUM_SESSION,a.sessionId+"-"+d+"-"+b+"-"+c)}}getSessionInfo(){var a=(getStorageSync(RUM_SESSION)||"").split("-"),b=a[0],c=a[1],d=a[2],e=a[3],f={sessionId:b,sampled:"0"!==c,startTime:parseInt(d||"")||0,lastTime:parseInt(e||"")||0};return this.checkSession(f)||(f=this.resetSession()),f}getEventId(){return generateEventId(this.getSessionId())}getViewId(){return this.getUUID()}getUserId(){var a=getStorageSync(USER_ID);return a&&0===a.indexOf("user_")&&(a=""),a||(a="uid_"+generateSpanId(16,36),setStorageSync(USER_ID,a)),a}resetSession(){var a=this.sessionConfig.sampling,b=this.getUUID(),c=getCurrentTime(),d=performDraw(a),e=b+"-"+(d?1:0)+"-"+c+"-"+c;return setStorageSync(RUM_SESSION,e),{sessionId:b,sampled:d,startTime:c,lastTime:c,isNew:!0}}getUUID(){return generateGUID().replace(/-/g,"")}fixSessionConfig(a={}){var b=a.sampleRate,c=a.sampling,d=a.maxDuration,e=a.overtime;// 优先使用 sampling(0-100),若未配置则从旧字段 sampleRate(0-1)迁移
|
|
4
|
+
return(!isNumber(c)||0>c||100<c)&&(isNumber(b)&&0<=b&&1>=b?c=100*b:c=100),(!isNumber(d)||d<4*ONE_HOUR||d>ONE_DAY)&&(d=ONE_DAY),(!isNumber(e)||e>ONE_HOUR||e<10*ONE_MINUTE)&&(e=30*ONE_MINUTE),{sampling:c,maxDuration:d,overtime:e}}getBaseEvent(){return{timestamp:getCurrentTime(),session_id:this.getSessionId(),event_id:this.getEventId(),view:this.ctx?getCurView(this.ctx):void 0,times:1}}}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ISseMetrics } from './api';
|
|
2
|
+
export declare class SseMetricsTracker {
|
|
3
|
+
private startTime;
|
|
4
|
+
private firstMessageTime;
|
|
5
|
+
private lastMessageTime;
|
|
6
|
+
private messageCount;
|
|
7
|
+
private intervals;
|
|
8
|
+
start(startTime?: number): void;
|
|
9
|
+
onMessage(): void;
|
|
10
|
+
finish(status: ISseMetrics['status']): ISseMetrics;
|
|
11
|
+
}
|
|
12
|
+
export declare function arrayBufferToString(buffer: ArrayBuffer): string;
|
|
13
|
+
export declare function parseSseChunk(text: string, buffer: string): {
|
|
14
|
+
events: string[];
|
|
15
|
+
remaining: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function isSseRequest(options: {
|
|
18
|
+
header?: Record<string, string>;
|
|
19
|
+
headers?: Record<string, string>;
|
|
20
|
+
url?: string;
|
|
21
|
+
enableChunked?: boolean;
|
|
22
|
+
}): boolean;
|
|
23
|
+
export declare function isSseSupported(): boolean;
|
package/es/utils/sse.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import{appName,wechatName}from"./platform";// ==================== SseMetricsTracker ====================
|
|
2
|
+
export class SseMetricsTracker{constructor(){this.startTime=0,this.firstMessageTime=0,this.lastMessageTime=0,this.messageCount=0,this.intervals=[]}start(a){this.startTime=a||Date.now(),this.firstMessageTime=0,this.lastMessageTime=0,this.messageCount=0,this.intervals=[]}onMessage(){var a=Date.now();this.messageCount++,1===this.messageCount?this.firstMessageTime=a:this.intervals.push(a-this.lastMessageTime),this.lastMessageTime=a}finish(a){var b={status:a,message_count:this.messageCount};if(0<this.firstMessageTime&&(b.time_to_first_token=this.firstMessageTime-this.startTime),0<this.intervals.length){for(var c=0,d=0;d<this.intervals.length;d++)c+=this.intervals[d];b.inter_token_latency_avg=Math.round(c/this.intervals.length),b.inter_token_latency_max=Math.max.apply(null,this.intervals)}return b}}// ==================== 辅助函数 ====================
|
|
3
|
+
// ArrayBuffer 转字符串 - 兼容无 TextDecoder 环境
|
|
4
|
+
export function arrayBufferToString(a){try{// 优先使用 TextDecoder
|
|
5
|
+
if("undefined"!=typeof TextDecoder)return new TextDecoder("utf-8").decode(a)}catch(a){// fallthrough
|
|
6
|
+
}// 降级方案
|
|
7
|
+
for(var b="",c=new Uint8Array(a),d=0;d<c.length;d++)b+=String.fromCharCode(c[d]);try{return decodeURIComponent(escape(b))}catch(a){return b}}// SSE 协议解析 - 按 \n\n 分割事件
|
|
8
|
+
export function parseSseChunk(a,b){// 最后一部分可能不完整
|
|
9
|
+
for(var c=(b+a).split("\n\n"),d=c.pop()||"",e=[],f=0;f<c.length;f++)0<c[f].trim().length&&e.push(c[f]);return{events:e,remaining:d}}// 判断请求是否为 SSE 请求
|
|
10
|
+
export function isSseRequest(a){// 检查是否已显式设置 enableChunked
|
|
11
|
+
if(!0===a.enableChunked)return!0;var b=a.header||a.headers||{},c=b.Accept||b.accept||"";// 检查 Accept 头
|
|
12
|
+
if(-1!==c.indexOf("text/event-stream"))return!0;// 检查 Content-Type(某些场景服务端预设)
|
|
13
|
+
var d=b["Content-Type"]||b["content-type"]||"";return-1!==d.indexOf("text/event-stream")}// 判断当前平台是否支持 SSE 监控(仅微信小程序且支持 enableChunked)
|
|
14
|
+
export function isSseSupported(){if(appName!==wechatName)return!1;try{return"undefined"!=typeof wx&&wx.canIUse&&wx.canIUse("request.object.enableChunked")}catch(a){return!1}}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IContext } from "@arms/rum-core";
|
|
2
|
+
/**
|
|
3
|
+
* 根据指定 URL 获取视图的名称,默认为其path部分
|
|
4
|
+
* @param url 需要提取路径部分的 URL
|
|
5
|
+
* @param isHash 是否为 hash 模式路由的 URL
|
|
6
|
+
*/
|
|
7
|
+
export declare function getPathByURL(url: string, isHash?: boolean): string;
|
|
8
|
+
/**
|
|
9
|
+
* 检查是否为上报域名
|
|
10
|
+
* @param ctx
|
|
11
|
+
* @param url 需要提取路径部分的 URL
|
|
12
|
+
*/
|
|
13
|
+
export declare function isEndpoint(ctx: IContext, url: string): boolean;
|
|
14
|
+
interface ParsedURL {
|
|
15
|
+
uri: string;
|
|
16
|
+
protocol: string | undefined;
|
|
17
|
+
host: string | undefined;
|
|
18
|
+
hostname: string | undefined;
|
|
19
|
+
port: string | undefined;
|
|
20
|
+
pathname: string | undefined;
|
|
21
|
+
search: string | undefined;
|
|
22
|
+
hash: string | undefined;
|
|
23
|
+
searchParams: Record<string, string | string[]>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 解析 URL 字符串为结构化对象
|
|
27
|
+
*/
|
|
28
|
+
export declare function getURL(url: string): ParsedURL;
|
|
29
|
+
export {};
|
package/es/utils/url.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function _createForOfIteratorHelperLoose(a,b){var c="undefined"!=typeof Symbol&&a[Symbol.iterator]||a["@@iterator"];if(c)return(c=c.call(a)).next.bind(c);if(Array.isArray(a)||(c=_unsupportedIterableToArray(a))||b&&a&&"number"==typeof a.length){c&&(a=c);var d=0;return function(){return d>=a.length?{done:!0}:{done:!1,value:a[d++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}import{isArray}from"@arms/rum-core";/**
|
|
2
|
+
* 根据指定 URL 获取视图的名称,默认为其path部分
|
|
3
|
+
* @param url 需要提取路径部分的 URL
|
|
4
|
+
* @param isHash 是否为 hash 模式路由的 URL
|
|
5
|
+
*/export function getPathByURL(a,b=!1){try{var c=getURL(a);return b?c.hash:c.pathname}catch(a){return""}}/**
|
|
6
|
+
* 检查是否为上报域名
|
|
7
|
+
* @param ctx
|
|
8
|
+
* @param url 需要提取路径部分的 URL
|
|
9
|
+
*/export function isEndpoint(a,b){var c=a.getConfig(),d=c.endpoint;try{return getURL(b).hostname===getURL(d).hostname}catch(a){return!1}}var REGEX=/^(?:([^:\/?#]+):\/\/)?((?:([^\/?#@]*)@)?([^\/?#:]*)(?:\:(\d*))?)?([^?#]*)(?:\?([^#]*))?(?:#((?:.|\n)*))?/i;/**
|
|
10
|
+
* 安全解码 URL 组件,失败时返回原始字符串
|
|
11
|
+
*/function safeDecode(a){if(!a)return"";try{return decodeURIComponent(a)}catch(b){return a}}/**
|
|
12
|
+
* 解析查询字符串为键值对对象
|
|
13
|
+
*/function getSearchParams(a){var b={};if(!a)return b;for(var c,d,e=a.split("&"),f=_createForOfIteratorHelperLoose(e);!(c=f()).done;)if(d=c.value,d){var g=d.indexOf("=");if(!(0>g)){var h=safeDecode(d.slice(0,g)),i=safeDecode(d.slice(g+1));if(h){var j=b[h];b[h]=void 0===j?i:isArray(j)?[...j,i]:[j,i]}}}return b}/**
|
|
14
|
+
* 解析 URL 字符串为结构化对象
|
|
15
|
+
*/export function getURL(a){if("string"!=typeof a||!a)return{uri:"",protocol:void 0,host:void 0,hostname:void 0,port:void 0,pathname:void 0,search:void 0,hash:void 0,searchParams:{}};var b=safeDecode(a),c=b.match(REGEX);if(!c)return{uri:a,protocol:void 0,host:void 0,hostname:void 0,port:void 0,pathname:void 0,search:void 0,hash:void 0,searchParams:{}};// 提取 host,移除认证信息(如果有)
|
|
16
|
+
var d=c[2]||"",e=d.includes("@")?d.replace(/^[^@]+@/,""):d;return{uri:c[0]||"",protocol:c[1],host:e||void 0,hostname:c[4],port:c[5],pathname:c[6],search:c[7],hash:c[8],searchParams:getSearchParams(c[7])}}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IContext, IRumSession, IViewData } from "@arms/rum-core";
|
|
2
|
+
import { Page } from "./platform";
|
|
3
|
+
export declare const PAGE_ID = "__rum_view_id";
|
|
4
|
+
/**
|
|
5
|
+
* 获取当前 page
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export declare function getCurPage(): Page;
|
|
9
|
+
/**
|
|
10
|
+
* 获取当前 view
|
|
11
|
+
* @param ctx
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
export declare function getCurView(ctx: IContext): IViewData;
|
|
15
|
+
/**
|
|
16
|
+
* 获取 RUM 内置的view_id标识
|
|
17
|
+
* @param page
|
|
18
|
+
* @param session
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
export declare function getRumViewId(page: Page, session?: IRumSession): string;
|
|
22
|
+
/**
|
|
23
|
+
* 获取当前 view
|
|
24
|
+
* @param viewId
|
|
25
|
+
* @param ctx
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
export declare function getViewById(viewId: string, ctx: IContext): IViewData;
|
|
29
|
+
/**
|
|
30
|
+
* 获取当前 page
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
package/es/utils/view.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export var PAGE_ID="__rum_view_id";/**
|
|
2
|
+
* 获取当前 page
|
|
3
|
+
* @returns
|
|
4
|
+
*/export function getCurPage(){if("function"==typeof getCurrentPages)try{var a=getCurrentPages()||[];return a[a.length-1]}catch(a){console.warn("[arms] error in getCurView",a)}}/**
|
|
5
|
+
* 获取当前 view
|
|
6
|
+
* @param ctx
|
|
7
|
+
* @returns
|
|
8
|
+
*/export function getCurView(a){if(a){var b=a.getViews();if(b&&b.length)return b[b.length-1]}}/**
|
|
9
|
+
* 获取 RUM 内置的view_id标识
|
|
10
|
+
* @param page
|
|
11
|
+
* @param session
|
|
12
|
+
* @returns
|
|
13
|
+
*/export function getRumViewId(a,b){return a?a[PAGE_ID]?a[PAGE_ID]:b?a[PAGE_ID]=b.getViewId():void 0:void 0}/**
|
|
14
|
+
* 获取当前 view
|
|
15
|
+
* @param viewId
|
|
16
|
+
* @param ctx
|
|
17
|
+
* @returns
|
|
18
|
+
*/export function getViewById(a,b){return a&&b?b.getViews().find(function(b){return b.id===a}):void 0}/**
|
|
19
|
+
* 获取当前 page
|
|
20
|
+
* @returns
|
|
21
|
+
*/// export function getPageByPageIdForWx(pageId: number) {
|
|
22
|
+
// if (typeof getCurrentPages === 'function') {
|
|
23
|
+
// const pid = `pageId:${pageId}`;
|
|
24
|
+
// try {
|
|
25
|
+
// const pages = (getCurrentPages() || []);
|
|
26
|
+
// return pages.find(page => page.getPageId() === pid);
|
|
27
|
+
// } catch (error) {
|
|
28
|
+
// console.warn('[arms] error in getCurView', error);
|
|
29
|
+
// }
|
|
30
|
+
// }
|
|
31
|
+
// }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";exports.__esModule=!0,exports["default"]=void 0;var _rumCore=require("@arms/rum-core"),_hackPage=require("../../utils/hackPage"),_configManager=require("../../configManager");class ActionCollector{constructor(){var a=this;this.name="action-collector",this.DELAY_TIME=300,this.ctx=void 0,this.sendEvent=void 0,this.events=["tap"],this.lastEvent=void 0,this.timer=void 0,this.onEvent=function(b){if(b&&a.events.includes(b.type)&&b.target){var c=b.target,d=b.currentTarget,e=b.type,f=d.dataset,g=d.id;if(g||d===c||(g=c.id,f=c.dataset),!g)return;var h=a.ctx.session.getBaseEvent(),i={...h,event_type:_rumCore.RumEventType.ACTION,type:e,name:g,snapshots:JSON.stringify({dataset:f}).substring(0,1e3)};clearTimeout(a.timer),a.lastEvent?a.lastEvent.name===i.name?a.lastEvent.times+=1:a.sendAction():a.lastEvent=i,a.timer=setTimeout(a.sendAction,a.DELAY_TIME)}},this.sendAction=function(){a.sendEvent(a.lastEvent),a.lastEvent=null}}setup(a,b){(0,_configManager.checkEnable)(a,"action")&&(this.ctx=a,this.sendEvent=b,(0,_hackPage.addPageListener)("*",this.onEvent))}destroy(){(0,_hackPage.removePageListener)("*",this.onEvent)}}exports["default"]=ActionCollector;
|