@jerry_aurora/sky-monitor-sdk 0.2.0

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.
Files changed (148) hide show
  1. package/README.md +355 -0
  2. package/dist/chunk-2EV6VMEO.js +2 -0
  3. package/dist/chunk-2EV6VMEO.js.map +1 -0
  4. package/dist/chunk-2R7LNQYV.js +4 -0
  5. package/dist/chunk-2R7LNQYV.js.map +1 -0
  6. package/dist/chunk-4DK7RV2K.js +2 -0
  7. package/dist/chunk-4DK7RV2K.js.map +1 -0
  8. package/dist/chunk-4GL6IXHZ.cjs +2 -0
  9. package/dist/chunk-4GL6IXHZ.cjs.map +1 -0
  10. package/dist/chunk-4K5NIPXS.cjs +2 -0
  11. package/dist/chunk-4K5NIPXS.cjs.map +1 -0
  12. package/dist/chunk-5RS6LIZN.js +2 -0
  13. package/dist/chunk-5RS6LIZN.js.map +1 -0
  14. package/dist/chunk-5VYMD33V.cjs +2 -0
  15. package/dist/chunk-5VYMD33V.cjs.map +1 -0
  16. package/dist/chunk-647GK2XE.js +2 -0
  17. package/dist/chunk-647GK2XE.js.map +1 -0
  18. package/dist/chunk-6KJXTS2V.js +2 -0
  19. package/dist/chunk-6KJXTS2V.js.map +1 -0
  20. package/dist/chunk-6YTKBMJD.cjs +2 -0
  21. package/dist/chunk-6YTKBMJD.cjs.map +1 -0
  22. package/dist/chunk-ACIPNVBT.cjs +2 -0
  23. package/dist/chunk-ACIPNVBT.cjs.map +1 -0
  24. package/dist/chunk-BEGDR54W.js +2 -0
  25. package/dist/chunk-BEGDR54W.js.map +1 -0
  26. package/dist/chunk-BVOILM65.cjs +2 -0
  27. package/dist/chunk-BVOILM65.cjs.map +1 -0
  28. package/dist/chunk-FBQC6XIY.cjs +2 -0
  29. package/dist/chunk-FBQC6XIY.cjs.map +1 -0
  30. package/dist/chunk-GBREIA45.js +2 -0
  31. package/dist/chunk-GBREIA45.js.map +1 -0
  32. package/dist/chunk-GU7O5MWM.js +2 -0
  33. package/dist/chunk-GU7O5MWM.js.map +1 -0
  34. package/dist/chunk-JMHMJVBJ.cjs +2 -0
  35. package/dist/chunk-JMHMJVBJ.cjs.map +1 -0
  36. package/dist/chunk-LAATIQ3Y.cjs +2 -0
  37. package/dist/chunk-LAATIQ3Y.cjs.map +1 -0
  38. package/dist/chunk-LFJTX6FJ.cjs +2 -0
  39. package/dist/chunk-LFJTX6FJ.cjs.map +1 -0
  40. package/dist/chunk-LKBNR7RI.js +2 -0
  41. package/dist/chunk-LKBNR7RI.js.map +1 -0
  42. package/dist/chunk-NM4RALDJ.cjs +2 -0
  43. package/dist/chunk-NM4RALDJ.cjs.map +1 -0
  44. package/dist/chunk-O32X45L3.js +2 -0
  45. package/dist/chunk-O32X45L3.js.map +1 -0
  46. package/dist/chunk-S3ROE6GJ.js +2 -0
  47. package/dist/chunk-S3ROE6GJ.js.map +1 -0
  48. package/dist/chunk-SNOBW3V4.js +2 -0
  49. package/dist/chunk-SNOBW3V4.js.map +1 -0
  50. package/dist/chunk-XOLMXHFL.js +2 -0
  51. package/dist/chunk-XOLMXHFL.js.map +1 -0
  52. package/dist/chunk-Y2IWAJSY.cjs +4 -0
  53. package/dist/chunk-Y2IWAJSY.cjs.map +1 -0
  54. package/dist/chunk-Y46XWPAC.cjs +2 -0
  55. package/dist/chunk-Y46XWPAC.cjs.map +1 -0
  56. package/dist/chunk-ZIKPTR2L.cjs +2 -0
  57. package/dist/chunk-ZIKPTR2L.cjs.map +1 -0
  58. package/dist/index-Bh5S5dim.d.ts +203 -0
  59. package/dist/index-D6soZ1u6.d.cts +203 -0
  60. package/dist/index.cjs +2 -0
  61. package/dist/index.cjs.map +1 -0
  62. package/dist/index.d.cts +32 -0
  63. package/dist/index.d.ts +32 -0
  64. package/dist/index.js +2 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/platforms/browser.cjs +2 -0
  67. package/dist/platforms/browser.cjs.map +1 -0
  68. package/dist/platforms/browser.d.cts +10 -0
  69. package/dist/platforms/browser.d.ts +10 -0
  70. package/dist/platforms/browser.js +2 -0
  71. package/dist/platforms/browser.js.map +1 -0
  72. package/dist/plugins/dedupe.cjs +2 -0
  73. package/dist/plugins/dedupe.cjs.map +1 -0
  74. package/dist/plugins/dedupe.d.cts +39 -0
  75. package/dist/plugins/dedupe.d.ts +39 -0
  76. package/dist/plugins/dedupe.js +2 -0
  77. package/dist/plugins/dedupe.js.map +1 -0
  78. package/dist/plugins/error.cjs +2 -0
  79. package/dist/plugins/error.cjs.map +1 -0
  80. package/dist/plugins/error.d.cts +51 -0
  81. package/dist/plugins/error.d.ts +51 -0
  82. package/dist/plugins/error.js +2 -0
  83. package/dist/plugins/error.js.map +1 -0
  84. package/dist/plugins/fetch.cjs +2 -0
  85. package/dist/plugins/fetch.cjs.map +1 -0
  86. package/dist/plugins/fetch.d.cts +35 -0
  87. package/dist/plugins/fetch.d.ts +35 -0
  88. package/dist/plugins/fetch.js +2 -0
  89. package/dist/plugins/fetch.js.map +1 -0
  90. package/dist/plugins/offline-queue.cjs +2 -0
  91. package/dist/plugins/offline-queue.cjs.map +1 -0
  92. package/dist/plugins/offline-queue.d.cts +93 -0
  93. package/dist/plugins/offline-queue.d.ts +93 -0
  94. package/dist/plugins/offline-queue.js +2 -0
  95. package/dist/plugins/offline-queue.js.map +1 -0
  96. package/dist/plugins/performance.cjs +2 -0
  97. package/dist/plugins/performance.cjs.map +1 -0
  98. package/dist/plugins/performance.d.cts +31 -0
  99. package/dist/plugins/performance.d.ts +31 -0
  100. package/dist/plugins/performance.js +2 -0
  101. package/dist/plugins/performance.js.map +1 -0
  102. package/dist/plugins/replay.cjs +77 -0
  103. package/dist/plugins/replay.cjs.map +1 -0
  104. package/dist/plugins/replay.js +77 -0
  105. package/dist/plugins/replay.js.map +1 -0
  106. package/dist/plugins/sampling.cjs +2 -0
  107. package/dist/plugins/sampling.cjs.map +1 -0
  108. package/dist/plugins/sampling.d.cts +56 -0
  109. package/dist/plugins/sampling.d.ts +56 -0
  110. package/dist/plugins/sampling.js +2 -0
  111. package/dist/plugins/sampling.js.map +1 -0
  112. package/dist/plugins/session.cjs +2 -0
  113. package/dist/plugins/session.cjs.map +1 -0
  114. package/dist/plugins/session.d.cts +74 -0
  115. package/dist/plugins/session.d.ts +74 -0
  116. package/dist/plugins/session.js +2 -0
  117. package/dist/plugins/session.js.map +1 -0
  118. package/dist/plugins/trace.cjs +2 -0
  119. package/dist/plugins/trace.cjs.map +1 -0
  120. package/dist/plugins/trace.d.cts +125 -0
  121. package/dist/plugins/trace.d.ts +125 -0
  122. package/dist/plugins/trace.js +2 -0
  123. package/dist/plugins/trace.js.map +1 -0
  124. package/dist/plugins/transport.cjs +2 -0
  125. package/dist/plugins/transport.cjs.map +1 -0
  126. package/dist/plugins/transport.d.cts +231 -0
  127. package/dist/plugins/transport.d.ts +231 -0
  128. package/dist/plugins/transport.js +2 -0
  129. package/dist/plugins/transport.js.map +1 -0
  130. package/dist/plugins/xhr.cjs +2 -0
  131. package/dist/plugins/xhr.cjs.map +1 -0
  132. package/dist/plugins/xhr.d.cts +35 -0
  133. package/dist/plugins/xhr.d.ts +35 -0
  134. package/dist/plugins/xhr.js +2 -0
  135. package/dist/plugins/xhr.js.map +1 -0
  136. package/dist/presets.cjs +2 -0
  137. package/dist/presets.cjs.map +1 -0
  138. package/dist/presets.d.cts +45 -0
  139. package/dist/presets.d.ts +45 -0
  140. package/dist/presets.js +2 -0
  141. package/dist/presets.js.map +1 -0
  142. package/dist/sky-monitor-replay.umd.js +77 -0
  143. package/dist/sky-monitor-replay.umd.js.map +1 -0
  144. package/dist/sky-monitor.umd.js +4 -0
  145. package/dist/sky-monitor.umd.js.map +1 -0
  146. package/dist/types-BGUJGEpp.d.cts +90 -0
  147. package/dist/types-BGUJGEpp.d.ts +90 -0
  148. package/package.json +122 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/session/session.ts","../src/plugins/session/platforms/browser/index.ts","../src/plugins/session/index.ts"],"names":["Session","monitor","generateSessionId","duration","toolName","count","visible","BrowserSessionAdapter","callbacks","SessionPlugin","self","event"],"mappings":"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","file":"chunk-6KJXTS2V.js","sourcesContent":["/**\n * Session 类 - 会话级埋点\n */\n\nimport type { IMonitor } from '../../core/types'\nimport type { SessionStats } from './types'\nimport { generateSessionId } from '../../core/utils'\n\n/**\n * 会话管理类\n */\nexport class Session {\n private _sessionId: string\n private _startTime: number | null = null\n private _traceCount: number = 0\n private _toolUsage: Map<string, number> = new Map()\n private _visible: boolean = true\n private _monitor: IMonitor\n private _ended: boolean = false\n\n constructor(monitor: IMonitor) {\n this._monitor = monitor\n this._sessionId = generateSessionId()\n }\n\n get sessionId(): string {\n return this._sessionId\n }\n\n get id(): string {\n return this._sessionId\n }\n\n get ended(): boolean {\n return this._ended\n }\n\n start(): void {\n if (this._startTime !== null) return\n this._startTime = Date.now()\n\n this._monitor.track('session_start', {\n sessionId: this._sessionId,\n timestamp: this._startTime,\n })\n }\n\n end(): void {\n if (this._ended || this._startTime === null) return\n this._ended = true\n const duration = Date.now() - this._startTime\n\n this._monitor.track('session_end', {\n sessionId: this._sessionId,\n duration,\n traceCount: this._traceCount,\n toolUsage: Object.fromEntries(this._toolUsage),\n })\n }\n\n incrementTraceCount(): void {\n if (this._ended) return\n this._traceCount++\n }\n\n incrementToolUsage(toolName: string): void {\n if (this._ended) return\n const count = this._toolUsage.get(toolName) || 0\n this._toolUsage.set(toolName, count + 1)\n }\n\n setVisible(visible: boolean): void {\n if (this._ended || this._visible === visible) return\n this._visible = visible\n\n this._monitor.track('session_visibility', {\n sessionId: this._sessionId,\n visible,\n timestamp: Date.now(),\n })\n }\n\n getStats(): SessionStats {\n const duration = this._startTime ? Date.now() - this._startTime : 0\n return {\n sessionId: this._sessionId,\n duration,\n traceCount: this._traceCount,\n toolUsage: Object.fromEntries(this._toolUsage),\n }\n }\n}\n","/**\n * Session 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的会话生命周期管理:\n * - visibilitychange 事件\n * - beforeunload 事件\n */\n\nexport interface BrowserSessionCallbacks {\n onVisibilityChange: (visible: boolean) => void\n onBeforeUnload: () => void\n}\n\n/**\n * 浏览器平台适配\n * 管理会话相关的浏览器事件\n */\nexport class BrowserSessionAdapter {\n private _visibilityHandler: (() => void) | null = null\n private _beforeUnloadHandler: (() => void) | null = null\n\n /**\n * 初始化浏览器事件监听\n */\n setupOnce(callbacks: BrowserSessionCallbacks): void {\n if (typeof window === 'undefined') return\n\n this._visibilityHandler = () => {\n callbacks.onVisibilityChange(!document.hidden)\n }\n document.addEventListener('visibilitychange', this._visibilityHandler)\n\n this._beforeUnloadHandler = () => callbacks.onBeforeUnload()\n window.addEventListener('beforeunload', this._beforeUnloadHandler)\n }\n\n /**\n * 清理浏览器事件监听\n */\n teardown(): void {\n if (typeof window === 'undefined') return\n\n if (this._visibilityHandler) {\n document.removeEventListener('visibilitychange', this._visibilityHandler)\n this._visibilityHandler = null\n }\n if (this._beforeUnloadHandler) {\n window.removeEventListener('beforeunload', this._beforeUnloadHandler)\n this._beforeUnloadHandler = null\n }\n }\n}\n","/**\n * Session 插件 - 会话管理\n */\n\nimport type { Plugin, IMonitor, MonitorEvent } from '../../core/types'\nimport { Session } from './session'\nimport { BrowserSessionAdapter } from './platforms/browser'\n\nexport type { SessionStats } from './types'\nexport { Session } from './session'\n\n/**\n * Session 插件\n * 提供会话级埋点能力\n */\nexport class SessionPlugin implements Plugin {\n name = 'session'\n priority = 100\n\n private _session: Session | null = null\n private _platformAdapter: BrowserSessionAdapter\n\n constructor() {\n this._platformAdapter = new BrowserSessionAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(monitor: IMonitor): void {\n const self = this\n Object.defineProperties(monitor, {\n startSession: {\n value: () => {\n if (self._session && !self._session.ended) return\n self._session = new Session(monitor)\n self._session.start()\n self._setupAutoListeners()\n },\n writable: false,\n },\n endSession: {\n value: () => {\n if (!self._session || self._session.ended) return\n self._session.end()\n self._platformAdapter.teardown()\n },\n writable: false,\n },\n getSession: {\n value: () => self._session,\n writable: false,\n },\n })\n }\n\n /**\n * 事件处理:关联 sessionId\n */\n processEvent(event: MonitorEvent): MonitorEvent {\n if (this._session && !this._session.ended) {\n event.context.sessionId = this._session.id\n }\n return event\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n this._platformAdapter.teardown()\n if (this._session && !this._session.ended) {\n this._session.end()\n }\n this._session = null\n }\n\n private _setupAutoListeners(): void {\n this._platformAdapter.setupOnce({\n onVisibilityChange: (visible) => {\n if (this._session && !this._session.ended) {\n this._session.setVisible(visible)\n }\n },\n onBeforeUnload: () => {\n if (this._session && !this._session.ended) {\n this._session.end()\n }\n },\n })\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkY46XWPAC_cjs=require('./chunk-Y46XWPAC.cjs');var t=class{constructor(e){this._startTime=null;this._traceCount=0;this._toolUsage=new Map;this._visible=true;this._ended=false;this._monitor=e,this._sessionId=chunkY46XWPAC_cjs.b();}get sessionId(){return this._sessionId}get id(){return this._sessionId}get ended(){return this._ended}start(){this._startTime===null&&(this._startTime=Date.now(),this._monitor.track("session_start",{sessionId:this._sessionId,timestamp:this._startTime}));}end(){if(this._ended||this._startTime===null)return;this._ended=true;let e=Date.now()-this._startTime;this._monitor.track("session_end",{sessionId:this._sessionId,duration:e,traceCount:this._traceCount,toolUsage:Object.fromEntries(this._toolUsage)});}incrementTraceCount(){this._ended||this._traceCount++;}incrementToolUsage(e){if(this._ended)return;let s=this._toolUsage.get(e)||0;this._toolUsage.set(e,s+1);}setVisible(e){this._ended||this._visible===e||(this._visible=e,this._monitor.track("session_visibility",{sessionId:this._sessionId,visible:e,timestamp:Date.now()}));}getStats(){let e=this._startTime?Date.now()-this._startTime:0;return {sessionId:this._sessionId,duration:e,traceCount:this._traceCount,toolUsage:Object.fromEntries(this._toolUsage)}}};var i=class{constructor(){this._visibilityHandler=null;this._beforeUnloadHandler=null;}setupOnce(e){typeof window>"u"||(this._visibilityHandler=()=>{e.onVisibilityChange(!document.hidden);},document.addEventListener("visibilitychange",this._visibilityHandler),this._beforeUnloadHandler=()=>e.onBeforeUnload(),window.addEventListener("beforeunload",this._beforeUnloadHandler));}teardown(){typeof window>"u"||(this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._beforeUnloadHandler&&(window.removeEventListener("beforeunload",this._beforeUnloadHandler),this._beforeUnloadHandler=null));}};var r=class{constructor(){this.name="session";this.priority=100;this._session=null;this._platformAdapter=new i;}setupOnce(e){let s=this;Object.defineProperties(e,{startSession:{value:()=>{s._session&&!s._session.ended||(s._session=new t(e),s._session.start(),s._setupAutoListeners());},writable:false},endSession:{value:()=>{!s._session||s._session.ended||(s._session.end(),s._platformAdapter.teardown());},writable:false},getSession:{value:()=>s._session,writable:false}});}processEvent(e){return this._session&&!this._session.ended&&(e.context.sessionId=this._session.id),e}teardown(){this._platformAdapter.teardown(),this._session&&!this._session.ended&&this._session.end(),this._session=null;}_setupAutoListeners(){this._platformAdapter.setupOnce({onVisibilityChange:e=>{this._session&&!this._session.ended&&this._session.setVisible(e);},onBeforeUnload:()=>{this._session&&!this._session.ended&&this._session.end();}});}};exports.a=t;exports.b=r;//# sourceMappingURL=chunk-6YTKBMJD.cjs.map
2
+ //# sourceMappingURL=chunk-6YTKBMJD.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/session/session.ts","../src/plugins/session/platforms/browser/index.ts","../src/plugins/session/index.ts"],"names":["Session","monitor","generateSessionId","duration","toolName","count","visible","BrowserSessionAdapter","callbacks","SessionPlugin","self","event"],"mappings":"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","file":"chunk-6YTKBMJD.cjs","sourcesContent":["/**\n * Session 类 - 会话级埋点\n */\n\nimport type { IMonitor } from '../../core/types'\nimport type { SessionStats } from './types'\nimport { generateSessionId } from '../../core/utils'\n\n/**\n * 会话管理类\n */\nexport class Session {\n private _sessionId: string\n private _startTime: number | null = null\n private _traceCount: number = 0\n private _toolUsage: Map<string, number> = new Map()\n private _visible: boolean = true\n private _monitor: IMonitor\n private _ended: boolean = false\n\n constructor(monitor: IMonitor) {\n this._monitor = monitor\n this._sessionId = generateSessionId()\n }\n\n get sessionId(): string {\n return this._sessionId\n }\n\n get id(): string {\n return this._sessionId\n }\n\n get ended(): boolean {\n return this._ended\n }\n\n start(): void {\n if (this._startTime !== null) return\n this._startTime = Date.now()\n\n this._monitor.track('session_start', {\n sessionId: this._sessionId,\n timestamp: this._startTime,\n })\n }\n\n end(): void {\n if (this._ended || this._startTime === null) return\n this._ended = true\n const duration = Date.now() - this._startTime\n\n this._monitor.track('session_end', {\n sessionId: this._sessionId,\n duration,\n traceCount: this._traceCount,\n toolUsage: Object.fromEntries(this._toolUsage),\n })\n }\n\n incrementTraceCount(): void {\n if (this._ended) return\n this._traceCount++\n }\n\n incrementToolUsage(toolName: string): void {\n if (this._ended) return\n const count = this._toolUsage.get(toolName) || 0\n this._toolUsage.set(toolName, count + 1)\n }\n\n setVisible(visible: boolean): void {\n if (this._ended || this._visible === visible) return\n this._visible = visible\n\n this._monitor.track('session_visibility', {\n sessionId: this._sessionId,\n visible,\n timestamp: Date.now(),\n })\n }\n\n getStats(): SessionStats {\n const duration = this._startTime ? Date.now() - this._startTime : 0\n return {\n sessionId: this._sessionId,\n duration,\n traceCount: this._traceCount,\n toolUsage: Object.fromEntries(this._toolUsage),\n }\n }\n}\n","/**\n * Session 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的会话生命周期管理:\n * - visibilitychange 事件\n * - beforeunload 事件\n */\n\nexport interface BrowserSessionCallbacks {\n onVisibilityChange: (visible: boolean) => void\n onBeforeUnload: () => void\n}\n\n/**\n * 浏览器平台适配\n * 管理会话相关的浏览器事件\n */\nexport class BrowserSessionAdapter {\n private _visibilityHandler: (() => void) | null = null\n private _beforeUnloadHandler: (() => void) | null = null\n\n /**\n * 初始化浏览器事件监听\n */\n setupOnce(callbacks: BrowserSessionCallbacks): void {\n if (typeof window === 'undefined') return\n\n this._visibilityHandler = () => {\n callbacks.onVisibilityChange(!document.hidden)\n }\n document.addEventListener('visibilitychange', this._visibilityHandler)\n\n this._beforeUnloadHandler = () => callbacks.onBeforeUnload()\n window.addEventListener('beforeunload', this._beforeUnloadHandler)\n }\n\n /**\n * 清理浏览器事件监听\n */\n teardown(): void {\n if (typeof window === 'undefined') return\n\n if (this._visibilityHandler) {\n document.removeEventListener('visibilitychange', this._visibilityHandler)\n this._visibilityHandler = null\n }\n if (this._beforeUnloadHandler) {\n window.removeEventListener('beforeunload', this._beforeUnloadHandler)\n this._beforeUnloadHandler = null\n }\n }\n}\n","/**\n * Session 插件 - 会话管理\n */\n\nimport type { Plugin, IMonitor, MonitorEvent } from '../../core/types'\nimport { Session } from './session'\nimport { BrowserSessionAdapter } from './platforms/browser'\n\nexport type { SessionStats } from './types'\nexport { Session } from './session'\n\n/**\n * Session 插件\n * 提供会话级埋点能力\n */\nexport class SessionPlugin implements Plugin {\n name = 'session'\n priority = 100\n\n private _session: Session | null = null\n private _platformAdapter: BrowserSessionAdapter\n\n constructor() {\n this._platformAdapter = new BrowserSessionAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(monitor: IMonitor): void {\n const self = this\n Object.defineProperties(monitor, {\n startSession: {\n value: () => {\n if (self._session && !self._session.ended) return\n self._session = new Session(monitor)\n self._session.start()\n self._setupAutoListeners()\n },\n writable: false,\n },\n endSession: {\n value: () => {\n if (!self._session || self._session.ended) return\n self._session.end()\n self._platformAdapter.teardown()\n },\n writable: false,\n },\n getSession: {\n value: () => self._session,\n writable: false,\n },\n })\n }\n\n /**\n * 事件处理:关联 sessionId\n */\n processEvent(event: MonitorEvent): MonitorEvent {\n if (this._session && !this._session.ended) {\n event.context.sessionId = this._session.id\n }\n return event\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n this._platformAdapter.teardown()\n if (this._session && !this._session.ended) {\n this._session.end()\n }\n this._session = null\n }\n\n private _setupAutoListeners(): void {\n this._platformAdapter.setupOnce({\n onVisibilityChange: (visible) => {\n if (this._session && !this._session.ended) {\n this._session.setVisible(visible)\n }\n },\n onBeforeUnload: () => {\n if (this._session && !this._session.ended) {\n this._session.end()\n }\n },\n })\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var r=["js_error","promise_error","resource_error","web_vital","session_start","session_end"],s=class{constructor(e={}){this.name="sampling";this.priority=10;this._shouldSample=null;this._rate=e.rate??1,this._mode=e.mode??"session",this._typeRates=e.typeRates??{},this._alwaysSample=new Set([...r,...e.alwaysSample??[]]);}setupOnce(e){(this._mode==="user"||this._mode==="session")&&(this._shouldSample=this._decideSampling());}processEvent(e){if(this._alwaysSample.has(e.type))return e;let a=this._typeRates[e.type]??this._rate,t;switch(this._mode){case "user":case "session":t=this._shouldSample??true;break;default:t=Math.random()<a;break}return t?e:null}_decideSampling(){return Math.random()<this._rate}resetSampling(){(this._mode==="user"||this._mode==="session")&&(this._shouldSample=this._decideSampling());}};exports.a=s;//# sourceMappingURL=chunk-ACIPNVBT.cjs.map
2
+ //# sourceMappingURL=chunk-ACIPNVBT.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/sampling/index.ts"],"names":["DEFAULT_ALWAYS_SAMPLE","SamplingPlugin","options","_monitor","event","rate","shouldSample"],"mappings":"aA6BA,IAAMA,CAAAA,CAAwB,CAC5B,UAAA,CACA,eAAA,CACA,iBACA,WAAA,CACA,eAAA,CACA,aACF,CAAA,CAKaC,CAAAA,CAAN,KAAuC,CAU5C,WAAA,CAAYC,EAAiC,EAAC,CAAG,CATjD,IAAA,CAAA,IAAA,CAAO,UAAA,CACP,IAAA,CAAA,QAAA,CAAW,EAAA,CAMX,IAAA,CAAQ,cAAgC,IAAA,CAGtC,IAAA,CAAK,KAAA,CAAQA,CAAAA,CAAQ,IAAA,EAAQ,CAAA,CAC7B,IAAA,CAAK,KAAA,CAAQA,EAAQ,IAAA,EAAQ,SAAA,CAC7B,IAAA,CAAK,UAAA,CAAaA,CAAAA,CAAQ,SAAA,EAAa,EAAC,CACxC,KAAK,aAAA,CAAgB,IAAI,GAAA,CAAI,CAC3B,GAAGF,CAAAA,CACH,GAAIE,CAAAA,CAAQ,cAAgB,EAC9B,CAAC,EACH,CAKA,SAAA,CAAUC,CAAAA,CAA0B,CAAA,CAE9B,KAAK,KAAA,GAAU,MAAA,EAAU,IAAA,CAAK,KAAA,GAAU,SAAA,IAC1C,IAAA,CAAK,aAAA,CAAgB,IAAA,CAAK,iBAAgB,EAE9C,CAKA,YAAA,CAAaC,CAAAA,CAA0C,CAErD,GAAI,IAAA,CAAK,aAAA,CAAc,IAAIA,CAAAA,CAAM,IAAI,CAAA,CACnC,OAAOA,CAAAA,CAIT,IAAMC,CAAAA,CAAO,IAAA,CAAK,WAAWD,CAAAA,CAAM,IAAI,CAAA,EAAK,IAAA,CAAK,KAAA,CAG7CE,CAAAA,CAEJ,OAAQ,IAAA,CAAK,OACX,KAAK,MAAA,CACL,KAAK,SAAA,CAEHA,CAAAA,CAAe,IAAA,CAAK,aAAA,EAAiB,KACrC,MAEF,QAEEA,CAAAA,CAAe,IAAA,CAAK,MAAA,EAAO,CAAID,CAAAA,CAC/B,KACJ,CAEA,OAAOC,CAAAA,CAAeF,CAAAA,CAAQ,IAChC,CAKQ,eAAA,EAA2B,CAGjC,OAAO,KAAK,MAAA,EAAO,CAAI,IAAA,CAAK,KAC9B,CAKA,aAAA,EAAsB,CAAA,CAChB,IAAA,CAAK,QAAU,MAAA,EAAU,IAAA,CAAK,KAAA,GAAU,SAAA,IAC1C,IAAA,CAAK,aAAA,CAAgB,IAAA,CAAK,eAAA,IAE9B,CACF","file":"chunk-ACIPNVBT.cjs","sourcesContent":["/**\n * Sampling 插件 - 智能采样\n *\n * 支持:\n * - 按用户/会话采样(同一用户要么全采要么不采)\n * - 按事件类型差异化采样率\n * - 重要事件(error/vital)默认全量\n */\n\nimport type { Plugin, MonitorEvent, IMonitor } from '../../core/types'\n\n/** 采样模式 */\nexport type SamplingMode = 'random' | 'user' | 'session'\n\n/** 事件类型采样率配置 */\nexport type TypeRates = Record<string, number>\n\nexport interface SamplingPluginOptions {\n /** 默认采样率 0-1,默认 1.0(全量) */\n rate?: number\n /** 采样模式,默认 'session' */\n mode?: SamplingMode\n /** 按事件类型的采样率(覆盖默认) */\n typeRates?: TypeRates\n /** 始终采样的事件类型(不受采样率影响) */\n alwaysSample?: string[]\n}\n\n/** 默认始终采样的事件类型 */\nconst DEFAULT_ALWAYS_SAMPLE = [\n 'js_error',\n 'promise_error',\n 'resource_error',\n 'web_vital',\n 'session_start',\n 'session_end',\n]\n\n/**\n * 采样插件\n */\nexport class SamplingPlugin implements Plugin {\n name = 'sampling'\n priority = 10\n\n private _rate: number\n private _mode: SamplingMode\n private _typeRates: TypeRates\n private _alwaysSample: Set<string>\n private _shouldSample: boolean | null = null // 缓存用户/会话级采样决策\n\n constructor(options: SamplingPluginOptions = {}) {\n this._rate = options.rate ?? 1.0\n this._mode = options.mode ?? 'session'\n this._typeRates = options.typeRates ?? {}\n this._alwaysSample = new Set([\n ...DEFAULT_ALWAYS_SAMPLE,\n ...(options.alwaysSample ?? []),\n ])\n }\n\n /**\n * 插件初始化\n */\n setupOnce(_monitor: IMonitor): void {\n // 用户/会话模式:初始化时决定是否采样\n if (this._mode === 'user' || this._mode === 'session') {\n this._shouldSample = this._decideSampling()\n }\n }\n\n /**\n * 事件处理:采样过滤\n */\n processEvent(event: MonitorEvent): MonitorEvent | null {\n // 1. 始终采样的事件类型\n if (this._alwaysSample.has(event.type)) {\n return event\n }\n\n // 2. 获取该事件类型的采样率\n const rate = this._typeRates[event.type] ?? this._rate\n\n // 3. 根据模式决定是否采样\n let shouldSample: boolean\n\n switch (this._mode) {\n case 'user':\n case 'session':\n // 用户/会话级:使用缓存的决策\n shouldSample = this._shouldSample ?? true\n break\n case 'random':\n default:\n // 随机模式:每个事件独立决策\n shouldSample = Math.random() < rate\n break\n }\n\n return shouldSample ? event : null\n }\n\n /**\n * 决定是否采样(用户/会话级)\n */\n private _decideSampling(): boolean {\n // 基于随机数决定,但结果会被缓存\n // 这样同一个会话内的所有事件采样决策一致\n return Math.random() < this._rate\n }\n\n /**\n * 重置采样决策(新会话时调用)\n */\n resetSampling(): void {\n if (this._mode === 'user' || this._mode === 'session') {\n this._shouldSample = this._decideSampling()\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ var s=class{constructor(){this._originalFetch=null;}setupOnce(o,t){typeof window>"u"||(this._originalFetch=window.fetch,window.fetch=async(r,e)=>{let n=typeof r=="string"?r:r.url;if(o(n))return this._originalFetch.call(window,r,e);let a=Date.now(),l=e?.method||"GET";try{await t.onRequest(n,l,a);let i=await this._originalFetch.call(window,r,e);return t.onSuccess(n,l,i.status,Date.now()-a),i}catch(i){throw t.onError(n,l,Date.now()-a,String(i)),i}});}teardown(){this._originalFetch&&typeof window<"u"&&(window.fetch=this._originalFetch),this._originalFetch=null;}};var u=class{constructor(o={}){this.name="fetch";this.priority=200;this._monitor=null;this._options=o,this._platformAdapter=new s;}setupOnce(o){this._monitor=o,this._platformAdapter.setupOnce(t=>this._shouldIgnore(t),{onRequest:async()=>{},onSuccess:(t,r,e,n)=>{this._monitor.track("http_request",{url:t,method:r,status:e,duration:n});},onError:(t,r,e,n)=>{this._monitor.track("http_request",{url:t,method:r,status:0,duration:e,error:n});}});}teardown(){this._platformAdapter.teardown(),this._monitor=null;}_shouldIgnore(o){let{includeUrls:t,excludeUrls:r}=this._options;return !!(r?.some(e=>e.test(o))||t&&!t.some(e=>e.test(o)))}};export{u as a};//# sourceMappingURL=chunk-BEGDR54W.js.map
2
+ //# sourceMappingURL=chunk-BEGDR54W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/fetch/platforms/browser/index.ts","../src/plugins/fetch/index.ts"],"names":["BrowserFetchAdapter","shouldIgnore","callbacks","input","init","url","start","method","response","error","FetchPlugin","options","monitor","status","duration","includeUrls","excludeUrls","re"],"mappings":"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","file":"chunk-BEGDR54W.js","sourcesContent":["/**\n * Fetch 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的 fetch 拦截:\n * - 包装 window.fetch\n * - 保留原始引用\n */\n\nexport interface BrowserFetchCallbacks {\n onRequest: (url: string, method: string, start: number) => Promise<void>\n onSuccess: (url: string, method: string, status: number, duration: number) => void\n onError: (url: string, method: string, duration: number, error: string) => void\n}\n\n/**\n * 浏览器平台适配\n * 管理 window.fetch 拦截\n */\nexport class BrowserFetchAdapter {\n private _originalFetch: typeof fetch | null = null\n\n /**\n * 初始化 fetch 拦截\n */\n setupOnce(\n shouldIgnore: (url: string) => boolean,\n callbacks: BrowserFetchCallbacks\n ): void {\n if (typeof window === 'undefined') return\n\n this._originalFetch = window.fetch\n\n window.fetch = async (input, init) => {\n const url = typeof input === 'string' ? input : (input as Request).url\n\n if (shouldIgnore(url)) {\n return this._originalFetch!.call(window, input, init)\n }\n\n const start = Date.now()\n const method = init?.method || 'GET'\n\n try {\n await callbacks.onRequest(url, method, start)\n const response = await this._originalFetch!.call(window, input, init)\n callbacks.onSuccess(url, method, response.status, Date.now() - start)\n return response\n } catch (error) {\n callbacks.onError(url, method, Date.now() - start, String(error))\n throw error\n }\n }\n }\n\n /**\n * 清理 fetch 拦截\n */\n teardown(): void {\n if (this._originalFetch && typeof window !== 'undefined') {\n window.fetch = this._originalFetch\n }\n this._originalFetch = null\n }\n}\n","/**\n * Fetch 插件 - 拦截 fetch 请求\n */\n\nimport type { Plugin, IMonitor } from '../../core/types'\nimport { BrowserFetchAdapter } from './platforms/browser'\n\nexport interface FetchPluginOptions {\n /** 包含的 URL 正则(白名单) */\n includeUrls?: RegExp[]\n /** 排除的 URL 正则(黑名单) */\n excludeUrls?: RegExp[]\n}\n\n/**\n * Fetch 插件\n * 包装模式拦截 fetch,保留原始引用\n */\nexport class FetchPlugin implements Plugin {\n name = 'fetch'\n priority = 200\n\n private _monitor: IMonitor | null = null\n private _options: FetchPluginOptions\n private _platformAdapter: BrowserFetchAdapter\n\n constructor(options: FetchPluginOptions = {}) {\n this._options = options\n this._platformAdapter = new BrowserFetchAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(monitor: IMonitor): void {\n this._monitor = monitor\n this._platformAdapter.setupOnce(\n (url) => this._shouldIgnore(url),\n {\n onRequest: async () => {\n // 可选:请求前的钩子\n },\n onSuccess: (url, method, status, duration) => {\n this._monitor!.track('http_request', {\n url,\n method,\n status,\n duration,\n })\n },\n onError: (url, method, duration, error) => {\n this._monitor!.track('http_request', {\n url,\n method,\n status: 0,\n duration,\n error,\n })\n },\n }\n )\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n this._platformAdapter.teardown()\n this._monitor = null\n }\n\n private _shouldIgnore(url: string): boolean {\n const { includeUrls, excludeUrls } = this._options\n if (excludeUrls?.some((re) => re.test(url))) return true\n if (includeUrls && !includeUrls.some((re) => re.test(url))) return true\n return false\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var t=class{constructor(){this._transport=null;this._offlineQueue=null;}registerTransport(e){this._transport=e;}registerOfflineQueue(e){this._offlineQueue=e;}getTransport(){return this._transport}getOfflineQueue(){return this._offlineQueue}async moveToOffline(e){if(this._offlineQueue)try{await this._offlineQueue.saveEvents(e);}catch(o){console.warn("[SkyMonitor] Move to offline failed:",o);}}async sendEvents(e){return this._transport?this._transport.send(e):false}teardown(){this._transport=null,this._offlineQueue=null;}},n=null;function i(){return n||(n=new t),n}exports.a=i;//# sourceMappingURL=chunk-BVOILM65.cjs.map
2
+ //# sourceMappingURL=chunk-BVOILM65.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/plugin-coordinator.ts"],"names":["PluginCoordinator","transport","offlineQueue","events","e","_coordinator","getPluginCoordinator"],"mappings":"aA+BO,IAAMA,CAAAA,CAAN,KAAwB,CAAxB,WAAA,EAAA,CACL,KAAQ,UAAA,CAAgC,IAAA,CACxC,KAAQ,aAAA,CAAsC,KAAA,CAK9C,kBAAkBC,CAAAA,CAA6B,CAC7C,KAAK,UAAA,CAAaA,EACpB,CAKA,oBAAA,CAAqBC,CAAAA,CAAmC,CACtD,IAAA,CAAK,aAAA,CAAgBA,EACvB,CAKA,YAAA,EAAkC,CAChC,OAAO,IAAA,CAAK,UACd,CAKA,eAAA,EAAwC,CACtC,OAAO,IAAA,CAAK,aACd,CAMA,MAAM,cAAcC,CAAAA,CAAuC,CACzD,GAAI,IAAA,CAAK,aAAA,CACP,GAAI,CACF,MAAM,IAAA,CAAK,cAAc,UAAA,CAAWA,CAAM,EAC5C,CAAA,MAASC,CAAAA,CAAG,CACV,OAAA,CAAQ,IAAA,CAAK,uCAAwCA,CAAC,EACxD,CAEJ,CAMA,MAAM,WAAWD,CAAAA,CAA0C,CACzD,OAAI,IAAA,CAAK,UAAA,CACA,IAAA,CAAK,UAAA,CAAW,IAAA,CAAKA,CAAM,EAE7B,KACT,CAKA,UAAiB,CACf,IAAA,CAAK,WAAa,IAAA,CAClB,IAAA,CAAK,cAAgB,KACvB,CACF,EAGIE,CAAAA,CAAyC,IAAA,CAKtC,SAASC,CAAAA,EAA0C,CACxD,OAAKD,CAAAA,GACHA,CAAAA,CAAe,IAAIL,CAAAA,CAAAA,CAEdK,CACT","file":"chunk-BVOILM65.cjs","sourcesContent":["/**\n * Plugin Coordinator - 插件协调器\n *\n * 解决插件之间的双向依赖问题:\n * - TransportPlugin 和 OfflineQueuePlugin 的协调\n * - 统一管理插件间的通信\n *\n * 设计原则:\n * - 插件不直接相互引用\n * - 通过协调器进行通信\n * - 单向依赖:Plugin → Coordinator\n */\n\nimport type { MonitorEvent, ITransport } from './types'\n\n/**\n * 离线队列接口\n */\nexport interface IOfflineQueue {\n /** 保存事件到离线队列 */\n saveEvents(events: MonitorEvent[]): Promise<void>\n /** 手动触发重传 */\n flush(): Promise<boolean>\n /** 获取离线事件数量 */\n getCount(): Promise<number>\n}\n\n/**\n * 插件协调器\n * 管理 TransportPlugin 和 OfflineQueuePlugin 之间的通信\n */\nexport class PluginCoordinator {\n private _transport: ITransport | null = null\n private _offlineQueue: IOfflineQueue | null = null\n\n /**\n * 注册传输适配器\n */\n registerTransport(transport: ITransport): void {\n this._transport = transport\n }\n\n /**\n * 注册离线队列\n */\n registerOfflineQueue(offlineQueue: IOfflineQueue): void {\n this._offlineQueue = offlineQueue\n }\n\n /**\n * 获取传输适配器(供 OfflineQueuePlugin 使用)\n */\n getTransport(): ITransport | null {\n return this._transport\n }\n\n /**\n * 获取离线队列(供 TransportPlugin 使用)\n */\n getOfflineQueue(): IOfflineQueue | null {\n return this._offlineQueue\n }\n\n /**\n * 将事件移入离线队列\n * TransportPlugin 在重试失败后调用\n */\n async moveToOffline(events: MonitorEvent[]): Promise<void> {\n if (this._offlineQueue) {\n try {\n await this._offlineQueue.saveEvents(events)\n } catch (e) {\n console.warn('[SkyMonitor] Move to offline failed:', e)\n }\n }\n }\n\n /**\n * 发送事件\n * OfflineQueuePlugin 在重传时调用\n */\n async sendEvents(events: MonitorEvent[]): Promise<boolean> {\n if (this._transport) {\n return this._transport.send(events)\n }\n return false\n }\n\n /**\n * 清理\n */\n teardown(): void {\n this._transport = null\n this._offlineQueue = null\n }\n}\n\n/** 全局协调器实例 */\nlet _coordinator: PluginCoordinator | null = null\n\n/**\n * 获取全局协调器实例\n */\nexport function getPluginCoordinator(): PluginCoordinator {\n if (!_coordinator) {\n _coordinator = new PluginCoordinator()\n }\n return _coordinator\n}\n\n/**\n * 重置协调器(用于测试)\n */\nexport function resetPluginCoordinator(): void {\n if (_coordinator) {\n _coordinator.teardown()\n _coordinator = null\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var s=class{constructor(){this._observers=[];this._visibilityHandler=null;this._beforeUnloadHandler=null;}setupOnce(r){typeof window>"u"||typeof PerformanceObserver>"u"||(this._observeFCP(r),this._observeLCP(r),this._observeCLS(r),this._observeINP(r),this._setupVisibilityHandler(r));}teardown(){for(let r of this._observers)r.disconnect();this._observers=[],this._visibilityHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._beforeUnloadHandler&&typeof window<"u"&&(window.removeEventListener("beforeunload",this._beforeUnloadHandler),this._beforeUnloadHandler=null);}_observeFCP(r){try{let e=new PerformanceObserver(t=>{for(let i of t.getEntries())i.name==="first-contentful-paint"&&r.onFCP(i.startTime);});e.observe({type:"paint",buffered:!0}),this._observers.push(e);}catch(e){console.warn("[SkyMonitor] FCP observer failed:",e);}}_observeLCP(r){try{let e=new PerformanceObserver(t=>{let i=t.getEntries();if(i.length>0){let n=i[i.length-1];r.onLCP(n.startTime);}});e.observe({type:"largest-contentful-paint",buffered:!0}),this._observers.push(e);}catch(e){console.warn("[SkyMonitor] LCP observer failed:",e);}}_observeCLS(r){try{let e=0,t=new PerformanceObserver(n=>{for(let a of n.getEntries()){let o=a;o.hadRecentInput||(e+=o.value);}});t.observe({type:"layout-shift",buffered:!0}),this._observers.push(t);let i=this._visibilityHandler;this._visibilityHandler=()=>{document.hidden&&e>0&&(r.onCLS(e),e=0),i?.();};}catch(e){console.warn("[SkyMonitor] CLS observer failed:",e);}}_observeINP(r){try{let e=0,t=new PerformanceObserver(n=>{for(let a of n.getEntries()){let o=a;o.duration>e&&(e=o.duration);}});t.observe({type:"event",buffered:!0}),this._observers.push(t);let i=this._visibilityHandler;this._visibilityHandler=()=>{document.hidden&&e>0&&(r.onINP(e),e=0),i?.();};}catch(e){console.warn("[SkyMonitor] INP observer failed:",e);}}_setupVisibilityHandler(r){this._visibilityHandler||(this._visibilityHandler=()=>{}),document.addEventListener("visibilitychange",this._visibilityHandler),this._beforeUnloadHandler=()=>{},window.addEventListener("beforeunload",this._beforeUnloadHandler);}};var l=class{constructor(){this.name="performance";this.priority=150;this._monitor=null;this._lcpValue=0;this._clsValue=0;this._inpValue=0;this._platformAdapter=new s;}setupOnce(r){this._monitor=r,this._platformAdapter.setupOnce({onFCP:e=>{this._monitor.track("web_vital",{name:"FCP",value:e});},onLCP:e=>{this._lcpValue=e,this._reportIfHidden();},onCLS:e=>{this._clsValue+=e,this._reportIfHidden();},onINP:e=>{this._inpValue=e,this._reportIfHidden();}});}teardown(){this._platformAdapter.teardown(),this._monitor=null;}_reportIfHidden(){typeof document>"u"||document.hidden&&(this._lcpValue>0&&(this._monitor.track("web_vital",{name:"LCP",value:this._lcpValue}),this._lcpValue=0),this._clsValue>0&&(this._monitor.track("web_vital",{name:"CLS",value:this._clsValue}),this._clsValue=0),this._inpValue>0&&(this._monitor.track("web_vital",{name:"INP",value:this._inpValue}),this._inpValue=0));}};exports.a=l;//# sourceMappingURL=chunk-FBQC6XIY.cjs.map
2
+ //# sourceMappingURL=chunk-FBQC6XIY.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/performance/platforms/browser/index.ts","../src/plugins/performance/index.ts"],"names":["BrowserPerformanceAdapter","callbacks","observer","list","entry","entries","lastEntry","clsValue","layoutShift","originalVisibilityHandler","inpValue","eventEntry","PerformancePlugin","monitor","value"],"mappings":"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","file":"chunk-FBQC6XIY.cjs","sourcesContent":["/**\n * Performance 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的性能指标采集:\n * - PerformanceObserver\n * - document.hidden\n * - visibilitychange 事件\n */\n\nexport interface BrowserPerformanceCallbacks {\n onFCP: (value: number) => void\n onLCP: (value: number) => void\n onCLS: (value: number) => void\n onINP: (value: number) => void\n}\n\n/**\n * 浏览器平台适配\n * 管理 PerformanceObserver 和可见性事件\n */\nexport class BrowserPerformanceAdapter {\n private _observers: PerformanceObserver[] = []\n private _visibilityHandler: (() => void) | null = null\n private _beforeUnloadHandler: (() => void) | null = null\n\n /**\n * 初始化性能监听\n */\n setupOnce(callbacks: BrowserPerformanceCallbacks): void {\n if (typeof window === 'undefined' || typeof PerformanceObserver === 'undefined') return\n\n this._observeFCP(callbacks)\n this._observeLCP(callbacks)\n this._observeCLS(callbacks)\n this._observeINP(callbacks)\n this._setupVisibilityHandler(callbacks)\n }\n\n /**\n * 清理性能监听\n */\n teardown(): void {\n for (const observer of this._observers) {\n observer.disconnect()\n }\n this._observers = []\n\n if (this._visibilityHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this._visibilityHandler)\n this._visibilityHandler = null\n }\n\n if (this._beforeUnloadHandler && typeof window !== 'undefined') {\n window.removeEventListener('beforeunload', this._beforeUnloadHandler)\n this._beforeUnloadHandler = null\n }\n }\n\n private _observeFCP(callbacks: BrowserPerformanceCallbacks): void {\n try {\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n if (entry.name === 'first-contentful-paint') {\n callbacks.onFCP(entry.startTime)\n }\n }\n })\n observer.observe({ type: 'paint', buffered: true })\n this._observers.push(observer)\n } catch (e) {\n console.warn('[SkyMonitor] FCP observer failed:', e)\n }\n }\n\n private _observeLCP(callbacks: BrowserPerformanceCallbacks): void {\n try {\n const observer = new PerformanceObserver((list) => {\n const entries = list.getEntries()\n if (entries.length > 0) {\n const lastEntry = entries[entries.length - 1] as PerformanceEntry & { startTime: number }\n callbacks.onLCP(lastEntry.startTime)\n }\n })\n observer.observe({ type: 'largest-contentful-paint', buffered: true })\n this._observers.push(observer)\n } catch (e) {\n console.warn('[SkyMonitor] LCP observer failed:', e)\n }\n }\n\n private _observeCLS(callbacks: BrowserPerformanceCallbacks): void {\n try {\n let clsValue = 0\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n const layoutShift = entry as PerformanceEntry & { hadRecentInput: boolean; value: number }\n if (!layoutShift.hadRecentInput) {\n clsValue += layoutShift.value\n }\n }\n })\n observer.observe({ type: 'layout-shift', buffered: true })\n this._observers.push(observer)\n\n // 页面隐藏时上报\n const originalVisibilityHandler = this._visibilityHandler\n this._visibilityHandler = () => {\n if (document.hidden && clsValue > 0) {\n callbacks.onCLS(clsValue)\n clsValue = 0\n }\n originalVisibilityHandler?.()\n }\n } catch (e) {\n console.warn('[SkyMonitor] CLS observer failed:', e)\n }\n }\n\n private _observeINP(callbacks: BrowserPerformanceCallbacks): void {\n try {\n let inpValue = 0\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n const eventEntry = entry as PerformanceEntry & { duration: number }\n if (eventEntry.duration > inpValue) {\n inpValue = eventEntry.duration\n }\n }\n })\n observer.observe({ type: 'event', buffered: true })\n this._observers.push(observer)\n\n // 页面隐藏时上报\n const originalVisibilityHandler = this._visibilityHandler\n this._visibilityHandler = () => {\n if (document.hidden && inpValue > 0) {\n callbacks.onINP(inpValue)\n inpValue = 0\n }\n originalVisibilityHandler?.()\n }\n } catch (e) {\n console.warn('[SkyMonitor] INP observer failed:', e)\n }\n }\n\n private _setupVisibilityHandler(callbacks: BrowserPerformanceCallbacks): void {\n if (!this._visibilityHandler) {\n this._visibilityHandler = () => {\n // 由各个 observer 处理\n }\n }\n\n document.addEventListener('visibilitychange', this._visibilityHandler)\n\n // beforeunload 兜底\n this._beforeUnloadHandler = () => {\n // 由各个 observer 处理\n }\n window.addEventListener('beforeunload', this._beforeUnloadHandler)\n }\n}\n","/**\n * Performance 插件 - Web Vitals 采集\n */\n\nimport type { Plugin, IMonitor } from '../../core/types'\nimport { BrowserPerformanceAdapter } from './platforms/browser'\n\n/**\n * Performance 插件\n * 采集 FCP、LCP、CLS、INP\n */\nexport class PerformancePlugin implements Plugin {\n name = 'performance'\n priority = 150\n\n private _monitor: IMonitor | null = null\n private _platformAdapter: BrowserPerformanceAdapter\n private _lcpValue: number = 0\n private _clsValue: number = 0\n private _inpValue: number = 0\n\n constructor() {\n this._platformAdapter = new BrowserPerformanceAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(monitor: IMonitor): void {\n this._monitor = monitor\n this._platformAdapter.setupOnce({\n onFCP: (value) => {\n this._monitor!.track('web_vital', {\n name: 'FCP',\n value,\n })\n },\n onLCP: (value) => {\n this._lcpValue = value\n this._reportIfHidden()\n },\n onCLS: (value) => {\n this._clsValue += value\n this._reportIfHidden()\n },\n onINP: (value) => {\n this._inpValue = value\n this._reportIfHidden()\n },\n })\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n this._platformAdapter.teardown()\n this._monitor = null\n }\n\n private _reportIfHidden(): void {\n if (typeof document === 'undefined') return\n\n if (document.hidden) {\n if (this._lcpValue > 0) {\n this._monitor!.track('web_vital', { name: 'LCP', value: this._lcpValue })\n this._lcpValue = 0\n }\n if (this._clsValue > 0) {\n this._monitor!.track('web_vital', { name: 'CLS', value: this._clsValue })\n this._clsValue = 0\n }\n if (this._inpValue > 0) {\n this._monitor!.track('web_vital', { name: 'INP', value: this._inpValue })\n this._inpValue = 0\n }\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ var t={development:{debug:true,transport:{mode:"immediate",maxRetries:1},sampling:{rate:1},plugins:["error","performance","fetch","xhr","session","dedupe"]},production:{debug:false,transport:{mode:"batch",batchSize:10,flushInterval:5e3,maxRetries:3},sampling:{rate:.1,mode:"session"},plugins:["error","performance","fetch","sampling","dedupe"]},minimal:{debug:false,transport:{mode:"batch",batchSize:20,flushInterval:1e4},sampling:{rate:.05,mode:"session"},plugins:["error","sampling"]}};function n(e){return t[e]}function i(e,r){return {debug:r.debug??e.debug,transport:{...e.transport,...r.transport},sampling:{...e.sampling,...r.sampling},plugins:r.plugins??e.plugins}}export{t as a,n as b,i as c};//# sourceMappingURL=chunk-GBREIA45.js.map
2
+ //# sourceMappingURL=chunk-GBREIA45.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/presets.ts"],"names":["PRESETS","getPreset","preset","mergePreset","overrides"],"mappings":"AAuCO,IAAMA,CAAAA,CAA+C,CAC1D,WAAA,CAAa,CACX,KAAA,CAAO,IAAA,CACP,SAAA,CAAW,CACT,IAAA,CAAM,WAAA,CACN,UAAA,CAAY,CACd,CAAA,CACA,QAAA,CAAU,CACR,IAAA,CAAM,CACR,CAAA,CACA,OAAA,CAAS,CAAC,OAAA,CAAS,aAAA,CAAe,OAAA,CAAS,KAAA,CAAO,SAAA,CAAW,QAAQ,CACvE,CAAA,CACA,WAAY,CACV,KAAA,CAAO,KAAA,CACP,SAAA,CAAW,CACT,IAAA,CAAM,OAAA,CACN,SAAA,CAAW,EAAA,CACX,aAAA,CAAe,GAAA,CACf,UAAA,CAAY,CACd,CAAA,CACA,QAAA,CAAU,CACR,KAAM,EAAA,CACN,IAAA,CAAM,SACR,CAAA,CACA,OAAA,CAAS,CAAC,OAAA,CAAS,aAAA,CAAe,OAAA,CAAS,UAAA,CAAY,QAAQ,CACjE,CAAA,CACA,OAAA,CAAS,CACP,KAAA,CAAO,MACP,SAAA,CAAW,CACT,IAAA,CAAM,OAAA,CACN,SAAA,CAAW,EAAA,CACX,aAAA,CAAe,GACjB,CAAA,CACA,QAAA,CAAU,CACR,IAAA,CAAM,GAAA,CACN,IAAA,CAAM,SACR,CAAA,CACA,OAAA,CAAS,CAAC,OAAA,CAAS,UAAU,CAC/B,CACF,EAOO,SAASC,CAAAA,CAAUC,CAAAA,CAAqC,CAC7D,OAAOF,CAAAA,CAAQE,CAAM,CACvB,CAQO,SAASC,CAAAA,CACdD,CAAAA,CACAE,CAAAA,CACc,CACd,OAAO,CACL,KAAA,CAAOA,CAAAA,CAAU,KAAA,EAASF,CAAAA,CAAO,KAAA,CACjC,SAAA,CAAW,CACT,GAAGA,CAAAA,CAAO,SAAA,CACV,GAAGE,CAAAA,CAAU,SACf,CAAA,CACA,QAAA,CAAU,CACR,GAAGF,CAAAA,CAAO,QAAA,CACV,GAAGE,CAAAA,CAAU,QACf,CAAA,CACA,OAAA,CAASA,CAAAA,CAAU,OAAA,EAAWF,CAAAA,CAAO,OACvC,CACF","file":"chunk-GBREIA45.js","sourcesContent":["/**\n * 预设配置\n *\n * 提供三种预设:\n * - development: 开发环境,即时发送,详细日志\n * - production: 生产环境,批量发送,采样\n * - minimal: 最小化,只采集错误\n */\n\nimport type { SamplingPluginOptions } from './plugins/sampling'\nimport type { TransportPluginOptions } from './plugins/transport'\n\n/** 预设名称 */\nexport type MonitorPreset = 'development' | 'production' | 'minimal'\n\n/** 插件名称 */\nexport type PluginName =\n | 'error'\n | 'performance'\n | 'fetch'\n | 'xhr'\n | 'session'\n | 'trace'\n | 'dedupe'\n | 'sampling'\n\n/** 预设配置内容 */\nexport interface PresetConfig {\n /** 调试模式 */\n debug: boolean\n /** 传输配置 */\n transport: Partial<TransportPluginOptions>\n /** 采样配置 */\n sampling: Partial<SamplingPluginOptions>\n /** 启用的插件 */\n plugins: PluginName[]\n}\n\n/** 预设配置定义 */\nexport const PRESETS: Record<MonitorPreset, PresetConfig> = {\n development: {\n debug: true,\n transport: {\n mode: 'immediate',\n maxRetries: 1,\n },\n sampling: {\n rate: 1.0,\n },\n plugins: ['error', 'performance', 'fetch', 'xhr', 'session', 'dedupe'],\n },\n production: {\n debug: false,\n transport: {\n mode: 'batch',\n batchSize: 10,\n flushInterval: 5000,\n maxRetries: 3,\n },\n sampling: {\n rate: 0.1,\n mode: 'session',\n },\n plugins: ['error', 'performance', 'fetch', 'sampling', 'dedupe'],\n },\n minimal: {\n debug: false,\n transport: {\n mode: 'batch',\n batchSize: 20,\n flushInterval: 10000,\n },\n sampling: {\n rate: 0.05,\n mode: 'session',\n },\n plugins: ['error', 'sampling'],\n },\n}\n\n/**\n * 获取预设配置\n * @param preset - 预设名称\n * @returns 预设配置\n */\nexport function getPreset(preset: MonitorPreset): PresetConfig {\n return PRESETS[preset]\n}\n\n/**\n * 合并预设配置和用户配置\n * @param preset - 预设配置\n * @param overrides - 用户覆盖配置\n * @returns 合并后的配置\n */\nexport function mergePreset(\n preset: PresetConfig,\n overrides: Partial<PresetConfig>\n): PresetConfig {\n return {\n debug: overrides.debug ?? preset.debug,\n transport: {\n ...preset.transport,\n ...overrides.transport,\n },\n sampling: {\n ...preset.sampling,\n ...overrides.sampling,\n },\n plugins: overrides.plugins ?? preset.plugins,\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import {a as a$6}from'./chunk-SNOBW3V4.js';import {a as a$1,d}from'./chunk-O32X45L3.js';import {a,b as b$1}from'./chunk-2EV6VMEO.js';import {b,c as c$1}from'./chunk-GBREIA45.js';import {b as b$2}from'./chunk-6KJXTS2V.js';import {c}from'./chunk-647GK2XE.js';import {a as a$2}from'./chunk-5RS6LIZN.js';import {a as a$3}from'./chunk-XOLMXHFL.js';import {a as a$5}from'./chunk-BEGDR54W.js';import {a as a$4}from'./chunk-LKBNR7RI.js';import {a as a$7}from'./chunk-2R7LNQYV.js';var i=class{constructor(t){this._context={};this._plugins=new Map;this._sortedPlugins=[];this._options={debug:false,...t};}use(t){return this._plugins.has(t.name)&&this._plugins.get(t.name).teardown?.(),this._plugins.set(t.name,t),this._sortPlugins(),t.setupOnce?.(this),this}track(t,n={}){let o={id:c(),type:t,timestamp:Date.now(),data:n,context:{...this._context,appId:this._options.appId}};this._options.debug&&console.warn("[SkyMonitor] track:",o);for(let r of this._sortedPlugins)if(r.processEvent&&(o=r.processEvent(o),o===null))return}setContext(t){this._context={...this._context,...t};}getContext(){return {...this._context}}getOptions(){return {...this._options}}clearContext(){this._context={};}hasPlugin(t){return this._plugins.has(t)}getPlugin(t){return this._plugins.get(t)}destroy(){for(let t of this._sortedPlugins)t.teardown?.();this._plugins.clear(),this._sortedPlugins=[];}_sortPlugins(){this._sortedPlugins=[...this._plugins.values()].sort((t,n)=>(t.priority??100)-(n.priority??100));}};function j(e){return new i({...e,storage:e.storage??new a})}function q(e){let t=null;e.preset&&(t=b(e.preset),t=c$1(t,{debug:e.debug,transport:e.transport,sampling:e.sampling,plugins:e.plugins}));let n=new i({appId:e.appId,debug:t?.debug??e.debug??false,storage:new a}),o=t?.plugins??e.plugins??["error","performance","fetch","dedupe"],r=e.endpoint??"/api/monitor",_=new a$1(r),x={error:()=>n.use(new a$7(e.error)),performance:()=>n.use(new a$6),fetch:()=>n.use(new a$5(e.fetch)),xhr:()=>n.use(new a$4(e.xhr)),session:()=>n.use(new b$2),trace:()=>{},dedupe:()=>n.use(new a$3(e.dedupe)),sampling:()=>{let p=t?.sampling??e.sampling??{};n.use(new a$2(p));}};for(let p of o)x[p]?.();let y=new b$1(e.offlineQueue);n.use(y);let v=t?.transport??e.transport??{},C=new d({endpoint:r,transport:_,...v});return n.use(C),n}export{i as a,j as b,q as c};//# sourceMappingURL=chunk-GU7O5MWM.js.map
2
+ //# sourceMappingURL=chunk-GU7O5MWM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/monitor.ts","../src/platforms/browser/index.ts"],"names":["Monitor","options","plugin","type","data","event","generateEventId","ctx","name","a","b","createBrowserMonitor","BrowserStorage","createMonitorWithPreset","config","presetConfig","getPreset","mergePreset","monitor","plugins","endpoint","transport","BrowserTransport","pluginMap","ErrorPlugin","PerformancePlugin","FetchPlugin","XHRPlugin","SessionPlugin","DedupePlugin","samplingConfig","SamplingPlugin","offlineQueue","OfflineQueuePlugin","transportConfig","transportPlugin","TransportPlugin"],"mappings":"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","file":"chunk-GU7O5MWM.js","sourcesContent":["/**\n * Monitor 核心类 - 微内核架构\n *\n * 职责:\n * - track() 上报事件\n * - use() 注册插件\n * - setContext() 设置上下文\n * - 事件管道调度\n */\n\nimport type {\n MonitorOptions,\n MonitorEvent,\n MonitorContext,\n Plugin,\n IMonitor,\n} from './types'\nimport { generateEventId } from './utils'\n\n/**\n * 监控核心类\n */\nexport class Monitor implements IMonitor {\n private _options: MonitorOptions\n private _context: MonitorContext = {}\n private _plugins: Map<string, Plugin> = new Map()\n private _sortedPlugins: Plugin[] = []\n\n constructor(options: MonitorOptions) {\n this._options = {\n debug: false,\n ...options,\n }\n }\n\n /**\n * 注册插件\n * @param plugin - 插件实例\n * @returns this(支持链式调用)\n */\n use(plugin: Plugin): this {\n // 同名插件覆盖:先销毁旧插件\n if (this._plugins.has(plugin.name)) {\n const old = this._plugins.get(plugin.name)!\n old.teardown?.()\n }\n\n this._plugins.set(plugin.name, plugin)\n this._sortPlugins()\n plugin.setupOnce?.(this)\n\n return this\n }\n\n /**\n * 手动上报事件\n * @param type - 事件类型\n * @param data - 事件数据\n */\n track(type: string, data: Record<string, unknown> = {}): void {\n let event: MonitorEvent | null = {\n id: generateEventId(),\n type,\n timestamp: Date.now(),\n data,\n context: { ...this._context, appId: this._options.appId },\n }\n\n if (this._options.debug) {\n console.warn('[SkyMonitor] track:', event)\n }\n\n // 通过插件管道处理\n for (const plugin of this._sortedPlugins) {\n if (plugin.processEvent) {\n event = plugin.processEvent(event)\n if (event === null) return // 被过滤,终止管道\n }\n }\n }\n\n /**\n * 设置全局上下文\n * @param ctx - 上下文对象(会合并到现有上下文)\n */\n setContext(ctx: MonitorContext): void {\n this._context = { ...this._context, ...ctx }\n }\n\n /**\n * 获取当前上下文\n */\n getContext(): MonitorContext {\n return { ...this._context }\n }\n\n /**\n * 获取配置选项\n */\n getOptions(): MonitorOptions {\n return { ...this._options }\n }\n\n /**\n * 清空上下文\n */\n clearContext(): void {\n this._context = {}\n }\n\n /**\n * 检查插件是否已注册\n * @param name - 插件名称\n */\n hasPlugin(name: string): boolean {\n return this._plugins.has(name)\n }\n\n /**\n * 获取插件实例\n * @param name - 插件名称\n */\n getPlugin<T extends Plugin>(name: string): T | undefined {\n return this._plugins.get(name) as T | undefined\n }\n\n /**\n * 销毁所有插件\n */\n destroy(): void {\n for (const plugin of this._sortedPlugins) {\n plugin.teardown?.()\n }\n this._plugins.clear()\n this._sortedPlugins = []\n }\n\n /**\n * 按优先级排序插件\n */\n private _sortPlugins(): void {\n this._sortedPlugins = [...this._plugins.values()].sort(\n (a, b) => (a.priority ?? 100) - (b.priority ?? 100)\n )\n }\n}\n\n/**\n * 创建监控实例\n * @param options - 配置选项\n * @returns Monitor 实例\n */\nexport function createMonitor(options: MonitorOptions): Monitor {\n return new Monitor(options)\n}\n","/**\n * 浏览器平台入口\n */\n\nimport { Monitor } from '../../core/monitor'\nimport type { MonitorOptions } from '../../core/types'\nimport { BrowserStorage } from './storage'\nimport { BrowserTransport } from './transport'\nimport { getPreset, mergePreset, type MonitorPreset, type PresetConfig, type PluginName } from '../../presets'\nimport { TransportPlugin, type TransportPluginOptions } from '../../plugins/transport'\nimport { OfflineQueuePlugin, type OfflineQueuePluginOptions } from '../../plugins/offline-queue'\nimport { ErrorPlugin, type ErrorPluginOptions } from '../../plugins/error'\nimport { PerformancePlugin } from '../../plugins/performance'\nimport { FetchPlugin, type FetchPluginOptions } from '../../plugins/fetch'\nimport { XHRPlugin, type XHRPluginOptions } from '../../plugins/xhr'\nimport { SessionPlugin } from '../../plugins/session'\nimport { DedupePlugin, type DedupePluginOptions } from '../../plugins/dedupe'\nimport { SamplingPlugin, type SamplingPluginOptions } from '../../plugins/sampling'\nimport type { ReplayPluginOptions } from '../../plugins/replay'\n\nexport { BrowserStorage } from './storage'\nexport { BrowserTransport } from './transport'\n\n/** 扩展的监控配置 - 全量插件映射 */\nexport interface MonitorConfig {\n /** 应用标识(必填) */\n appId: string\n /** 上报地址,默认 '/api/monitor' */\n endpoint?: string\n /** 调试模式 */\n debug?: boolean\n /** 预设配置 */\n preset?: MonitorPreset\n /** 启用的插件列表 */\n plugins?: PluginName[]\n\n // ===== 插件配置 =====\n\n /** 传输配置 */\n transport?: Partial<TransportPluginOptions>\n /** 采样配置 */\n sampling?: Partial<SamplingPluginOptions>\n /** 错误监控配置 */\n error?: ErrorPluginOptions\n /** Fetch 拦截配置 */\n fetch?: FetchPluginOptions\n /** XHR 拦截配置 */\n xhr?: XHRPluginOptions\n /** 去重配置 */\n dedupe?: DedupePluginOptions\n /** 离线队列配置 */\n offlineQueue?: OfflineQueuePluginOptions\n /** 会话录制配置 */\n replay?: ReplayPluginOptions\n}\n\n/**\n * 创建浏览器监控实例(简化版)\n * @param options - 配置选项\n * @returns Monitor 实例\n */\nexport function createBrowserMonitor(options: MonitorOptions): Monitor {\n return new Monitor({\n ...options,\n storage: options.storage ?? new BrowserStorage(),\n })\n}\n\n/**\n * 创建浏览器监控实例(完整版,支持预设)\n * @param config - 配置选项\n * @returns Monitor 实例\n */\nexport function createMonitorWithPreset(config: MonitorConfig): Monitor {\n // 获取预设配置\n let presetConfig: PresetConfig | null = null\n if (config.preset) {\n presetConfig = getPreset(config.preset)\n presetConfig = mergePreset(presetConfig, {\n debug: config.debug,\n transport: config.transport,\n sampling: config.sampling,\n plugins: config.plugins,\n })\n }\n\n // 创建 Monitor 实例\n const monitor = new Monitor({\n appId: config.appId,\n debug: presetConfig?.debug ?? config.debug ?? false,\n storage: new BrowserStorage(),\n })\n\n // 确定要启用的插件\n const plugins = presetConfig?.plugins ?? config.plugins ?? ['error', 'performance', 'fetch', 'dedupe']\n const endpoint = config.endpoint ?? '/api/monitor'\n\n // 创建传输适配器\n const transport = new BrowserTransport(endpoint)\n\n // 注册插件(按配置映射)\n const pluginMap: Record<PluginName, () => void> = {\n error: () => monitor.use(new ErrorPlugin(config.error)),\n performance: () => monitor.use(new PerformancePlugin()),\n fetch: () => monitor.use(new FetchPlugin(config.fetch)),\n xhr: () => monitor.use(new XHRPlugin(config.xhr)),\n session: () => monitor.use(new SessionPlugin()),\n trace: () => {}, // Trace 需要手动创建\n dedupe: () => monitor.use(new DedupePlugin(config.dedupe)),\n sampling: () => {\n const samplingConfig = presetConfig?.sampling ?? config.sampling ?? {}\n monitor.use(new SamplingPlugin(samplingConfig))\n },\n }\n\n // 按顺序注册插件\n for (const name of plugins) {\n pluginMap[name]?.()\n }\n\n // 注册离线队列(通过协调器自动连接)\n const offlineQueue = new OfflineQueuePlugin(config.offlineQueue)\n monitor.use(offlineQueue)\n\n // 注册传输插件(通过协调器自动连接)\n const transportConfig = presetConfig?.transport ?? config.transport ?? {}\n const transportPlugin = new TransportPlugin({\n endpoint,\n transport,\n ...transportConfig,\n })\n\n monitor.use(transportPlugin)\n\n // 注意:ReplayPlugin 需要用户单独导入并注册\n // import { ReplayPlugin } from '@sky-monitor/sdk/plugins/replay'\n // monitor.use(new ReplayPlugin(config.replay))\n\n return monitor\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkBVOILM65_cjs=require('./chunk-BVOILM65.cjs');var h=class{constructor(e="/api/monitor"){this._endpoint=e;}async send(e){try{return (await fetch(this._endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})).ok}catch(t){return console.warn("[SkyMonitor] Transport send failed:",t),false}}sendBeacon(e){if(typeof navigator>"u"||!navigator.sendBeacon)return false;try{return navigator.sendBeacon(this._endpoint,JSON.stringify(e))}catch(t){return console.warn("[SkyMonitor] Transport sendBeacon failed:",t),false}}};var l=class{constructor(){this._timer=null;this._throttleTimer=null;this._beforeUnloadHandler=null;this._visibilityHandler=null;this._pagehideHandler=null;}setupOnce(e,t,i,r){typeof window>"u"||(e==="batch"?this._timer=setInterval(()=>r.onFlush(),t):e==="throttle"&&(this._timer=setInterval(()=>r.onThrottleFlush(),i)),this._pagehideHandler=n=>{n.persisted||r.onBeacon();},window.addEventListener("pagehide",this._pagehideHandler),this._visibilityHandler=()=>{document.visibilityState==="hidden"&&r.onBeacon();},document.addEventListener("visibilitychange",this._visibilityHandler),this._beforeUnloadHandler=()=>r.onBeacon(),window.addEventListener("beforeunload",this._beforeUnloadHandler));}teardown(){this._timer&&(clearInterval(this._timer),this._timer=null),this._throttleTimer&&(clearTimeout(this._throttleTimer),this._throttleTimer=null),typeof window<"u"&&(this._pagehideHandler&&window.removeEventListener("pagehide",this._pagehideHandler),this._visibilityHandler&&document.removeEventListener("visibilitychange",this._visibilityHandler),this._beforeUnloadHandler&&window.removeEventListener("beforeunload",this._beforeUnloadHandler));}};var s=class{constructor(e=100){this._high=[];this._normal=[];this._low=[];this._maxSize=e;}enqueue(e,t="normal"){if(this.size>=this._maxSize)if(this._low.length>0)this._low.shift();else if(this._normal.length>0&&t==="high")this._normal.shift();else {if(t==="low")return false;if(t==="normal"&&this._normal.length===0&&this._low.length===0)return false}let i={event:e,priority:t,retryCount:0};switch(t){case "high":this._high.push(i);break;case "normal":this._normal.push(i);break;case "low":this._low.push(i);break}return true}dequeue(e){let t=[];for(;t.length<e&&this.size>0;)this._high.length>0?t.push(this._high.shift()):this._normal.length>0?t.push(this._normal.shift()):this._low.length>0&&t.push(this._low.shift());return t}peek(e){let t=[],i=e,r=Math.min(i,this._high.length);if(t.push(...this._high.slice(0,r)),i-=r,i>0){let n=Math.min(i,this._normal.length);t.push(...this._normal.slice(0,n)),i-=n;}if(i>0){let n=Math.min(i,this._low.length);t.push(...this._low.slice(0,n));}return t}unshift(e){for(let t of e.reverse())switch(t.priority){case "high":this._high.unshift(t);break;case "normal":this._normal.unshift(t);break;case "low":this._low.unshift(t);break}}clear(){this._high=[],this._normal=[],this._low=[];}get size(){return this._high.length+this._normal.length+this._low.length}get isEmpty(){return this.size===0}get stats(){return {high:this._high.length,normal:this._normal.length,low:this._low.length}}};var o=class{constructor(e={}){this._retryCount=0;this._baseDelay=e.baseDelay??1e3,this._maxDelay=e.maxDelay??3e4,this._jitter=e.jitter??.2,this._currentDelay=this._baseDelay;}getNextDelay(){let e=this._addJitter(this._currentDelay);return this._currentDelay=Math.min(this._currentDelay*2,this._maxDelay),this._retryCount++,e}reset(){this._currentDelay=this._baseDelay,this._retryCount=0;}recordFailure(){this._currentDelay=Math.min(this._currentDelay*2,this._maxDelay),this._retryCount++;}get retryCount(){return this._retryCount}get currentDelay(){return this._currentDelay}_addJitter(e){let t=1+(Math.random()*2-1)*this._jitter;return Math.round(e*t)}};var d=["js_error","promise_error","resource_error"],_=class{constructor(e){this.name="transport";this.priority=500;this._retryTimer=null;this._isRetrying=false;this._lastThrottleSend=0;this._transport=e.transport??new h(e.endpoint),this._defaultMode=e.mode??"batch",this._typeConfig=e.typeConfig??{},this._batchSize=e.batchSize??10,this._flushInterval=e.flushInterval??5e3,this._throttleInterval=e.throttleInterval??1e3,this._maxRetries=e.maxRetries??3,this._criticalTypes=new Set(e.criticalTypes??d);for(let t of this._criticalTypes)this._typeConfig[t]||(this._typeConfig[t]="immediate");this._queue=new s(e.maxBufferSize??100),this._throttleQueue=new s(e.maxBufferSize??100),this._retryScheduler=new o({baseDelay:e.baseRetryDelay??1e3,maxDelay:e.maxRetryDelay??3e4}),this._platformAdapter=new l;}setupOnce(e){chunkBVOILM65_cjs.a().registerTransport(this._transport),this._platformAdapter.setupOnce(this._defaultMode,this._flushInterval,this._throttleInterval,{onFlush:()=>this._flush(),onThrottleFlush:()=>this._throttleFlush(),onBeacon:()=>this._flushBeacon()});}processEvent(e){let t=this._getPriority(e);switch(this._getModeForEvent(e)){case "immediate":this._sendImmediate(e);break;case "throttle":this._throttleQueue.enqueue(e,t);break;default:this._queue.enqueue(e,t)||console.warn("[SkyMonitor] Buffer full, event dropped:",e.type),this._queue.size>=this._batchSize&&this._flush();break}return null}_getModeForEvent(e){return this._typeConfig[e.type]??this._defaultMode}teardown(){this._retryTimer&&(clearTimeout(this._retryTimer),this._retryTimer=null),this._platformAdapter.teardown(),this._flushBeacon();}_getPriority(e){return this._criticalTypes.has(e.type)?"high":"normal"}async _sendImmediate(e){await this._transport.send([e])||(this._queue.enqueue(e,"high"),this._scheduleRetry());}async _flush(){if(this._queue.isEmpty||this._isRetrying)return;let e=this._queue.dequeue(this._batchSize);if(e.length===0)return;let t=e.map(r=>r.event);if(await this._transport.send(t))this._retryScheduler.reset();else {for(let r of e)r.retryCount++,r.retryCount<this._maxRetries?this._queue.unshift([r]):this._moveToOffline([r.event]);this._scheduleRetry();}}_throttleFlush(){let e=Date.now();if(!(e-this._lastThrottleSend<this._throttleInterval)){if(this._lastThrottleSend=e,!this._throttleQueue.isEmpty){let t=this._throttleQueue.dequeue(this._throttleQueue.size),i=t.map(r=>r.event);this._transport.send(i).catch(()=>{this._throttleQueue.unshift(t);});}this._flush();}}_flushBeacon(){let e=this._queue.dequeue(this._queue.size),t=this._throttleQueue.dequeue(this._throttleQueue.size),i=[...e,...t];if(i.length===0)return;let r=i.map(n=>n.event);this._transport.sendBeacon?this._transport.sendBeacon(r)||(this._queue.unshift(e),this._throttleQueue.unshift(t)):this._transport.send(r);}_scheduleRetry(){if(this._isRetrying||this._retryTimer)return;let e=this._retryScheduler.getNextDelay();this._retryTimer=setTimeout(()=>{this._retryTimer=null,this._isRetrying=true,this._flush().finally(()=>{this._isRetrying=false;});},e);}async _moveToOffline(e){await chunkBVOILM65_cjs.a().moveToOffline(e);}};exports.a=h;exports.b=s;exports.c=o;exports.d=_;//# sourceMappingURL=chunk-JMHMJVBJ.cjs.map
2
+ //# sourceMappingURL=chunk-JMHMJVBJ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/platforms/browser/transport.ts","../src/plugins/transport/platforms/browser/index.ts","../src/plugins/transport/priority-queue.ts","../src/plugins/transport/retry-scheduler.ts","../src/plugins/transport/index.ts"],"names":["BrowserTransport","endpoint","events","e","BrowserTransportAdapter","mode","flushInterval","throttleInterval","callbacks","PriorityQueue","maxSize","event","priority","item","count","result","remaining","highCount","normalCount","lowCount","items","RetryScheduler","options","delay","jitterFactor","DEFAULT_CRITICAL","TransportPlugin","type","_monitor","getPluginCoordinator","now","batchItems","throttleItems","allItems"],"mappings":"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","file":"chunk-JMHMJVBJ.cjs","sourcesContent":["/**\n * 浏览器传输适配器 - sendBeacon + fetch\n */\n\nimport type { ITransport, MonitorEvent } from '../../core/types'\n\n/**\n * 浏览器传输实现\n */\nexport class BrowserTransport implements ITransport {\n private _endpoint: string\n\n constructor(endpoint: string = '/api/monitor') {\n this._endpoint = endpoint\n }\n\n /**\n * 发送事件(fetch)\n */\n async send(events: MonitorEvent[]): Promise<boolean> {\n try {\n const response = await fetch(this._endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(events),\n })\n return response.ok\n } catch (e) {\n console.warn('[SkyMonitor] Transport send failed:', e)\n return false\n }\n }\n\n /**\n * 发送事件(sendBeacon,用于页面关闭)\n */\n sendBeacon(events: MonitorEvent[]): boolean {\n if (typeof navigator === 'undefined' || !navigator.sendBeacon) {\n return false\n }\n\n try {\n return navigator.sendBeacon(\n this._endpoint,\n JSON.stringify(events)\n )\n } catch (e) {\n console.warn('[SkyMonitor] Transport sendBeacon failed:', e)\n return false\n }\n }\n}\n","/**\n * Transport 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的生命周期管理:\n * - 页面卸载时用 sendBeacon\n * - 页面隐藏时刷新缓冲\n * - 定时器管理\n */\n\nimport type { MonitorEvent } from '../../../../core/types'\n\nexport interface BrowserTransportState {\n queue: Array<{ event: MonitorEvent; retryCount: number }>\n isEmpty: boolean\n size: number\n}\n\nexport interface BrowserTransportCallbacks {\n onFlush: () => Promise<void>\n onThrottleFlush: () => void\n onBeacon: () => void\n}\n\n/**\n * 浏览器平台适配\n * 管理 window/document 事件和定时器\n */\nexport class BrowserTransportAdapter {\n private _timer: ReturnType<typeof setInterval> | null = null\n private _throttleTimer: ReturnType<typeof setTimeout> | null = null\n private _beforeUnloadHandler: (() => void) | null = null\n private _visibilityHandler: (() => void) | null = null\n private _pagehideHandler: ((e: PageTransitionEvent) => void) | null = null\n\n /**\n * 初始化浏览器事件监听\n */\n setupOnce(\n mode: 'batch' | 'throttle' | 'immediate',\n flushInterval: number,\n throttleInterval: number,\n callbacks: BrowserTransportCallbacks\n ): void {\n if (typeof window === 'undefined') return\n\n // 根据模式设置定时器\n if (mode === 'batch') {\n this._timer = setInterval(() => callbacks.onFlush(), flushInterval)\n } else if (mode === 'throttle') {\n this._timer = setInterval(() => callbacks.onThrottleFlush(), throttleInterval)\n }\n\n // 页面卸载时用 sendBeacon(三重保障)\n this._pagehideHandler = (e: PageTransitionEvent) => {\n if (e.persisted) return\n callbacks.onBeacon()\n }\n window.addEventListener('pagehide', this._pagehideHandler)\n\n this._visibilityHandler = () => {\n if (document.visibilityState === 'hidden') {\n callbacks.onBeacon()\n }\n }\n document.addEventListener('visibilitychange', this._visibilityHandler)\n\n this._beforeUnloadHandler = () => callbacks.onBeacon()\n window.addEventListener('beforeunload', this._beforeUnloadHandler)\n }\n\n /**\n * 清理浏览器事件监听\n */\n teardown(): void {\n if (this._timer) {\n clearInterval(this._timer)\n this._timer = null\n }\n if (this._throttleTimer) {\n clearTimeout(this._throttleTimer)\n this._throttleTimer = null\n }\n\n if (typeof window !== 'undefined') {\n if (this._pagehideHandler) {\n window.removeEventListener('pagehide', this._pagehideHandler)\n }\n if (this._visibilityHandler) {\n document.removeEventListener('visibilitychange', this._visibilityHandler)\n }\n if (this._beforeUnloadHandler) {\n window.removeEventListener('beforeunload', this._beforeUnloadHandler)\n }\n }\n }\n}\n","/**\n * 优先级队列 - 按优先级排序事件\n *\n * 支持三个优先级级别:high > normal > low\n * 缓冲区满时优先丢弃低优先级事件\n */\n\nimport type { MonitorEvent, EventPriority, PrioritizedEvent } from '../../core/types'\n\n/**\n * 优先级队列\n */\nexport class PriorityQueue {\n private _high: PrioritizedEvent[] = []\n private _normal: PrioritizedEvent[] = []\n private _low: PrioritizedEvent[] = []\n private _maxSize: number\n\n constructor(maxSize: number = 100) {\n this._maxSize = maxSize\n }\n\n /**\n * 添加事件到队列\n * @param event - 监控事件\n * @param priority - 优先级\n * @returns 是否成功添加(缓冲区满且无法丢弃时返回 false)\n */\n enqueue(event: MonitorEvent, priority: EventPriority = 'normal'): boolean {\n // 缓冲区满时,尝试丢弃低优先级事件\n if (this.size >= this._maxSize) {\n if (this._low.length > 0) {\n this._low.shift()\n } else if (this._normal.length > 0 && priority === 'high') {\n this._normal.shift()\n } else if (priority === 'low') {\n // 新事件是低优先级,直接丢弃\n return false\n } else if (priority === 'normal' && this._normal.length === 0 && this._low.length === 0) {\n // 队列全是高优先级,丢弃新的普通事件\n return false\n }\n }\n\n const item: PrioritizedEvent = { event, priority, retryCount: 0 }\n\n switch (priority) {\n case 'high':\n this._high.push(item)\n break\n case 'normal':\n this._normal.push(item)\n break\n case 'low':\n this._low.push(item)\n break\n }\n\n return true\n }\n\n /**\n * 取出指定数量的事件(按优先级顺序)\n * @param count - 取出数量\n * @returns 事件数组\n */\n dequeue(count: number): PrioritizedEvent[] {\n const result: PrioritizedEvent[] = []\n\n while (result.length < count && this.size > 0) {\n if (this._high.length > 0) {\n result.push(this._high.shift()!)\n } else if (this._normal.length > 0) {\n result.push(this._normal.shift()!)\n } else if (this._low.length > 0) {\n result.push(this._low.shift()!)\n }\n }\n\n return result\n }\n\n /**\n * 查看队列头部事件(不移除)\n * @param count - 查看数量\n */\n peek(count: number): PrioritizedEvent[] {\n const result: PrioritizedEvent[] = []\n let remaining = count\n\n // 先从 high 取\n const highCount = Math.min(remaining, this._high.length)\n result.push(...this._high.slice(0, highCount))\n remaining -= highCount\n\n // 再从 normal 取\n if (remaining > 0) {\n const normalCount = Math.min(remaining, this._normal.length)\n result.push(...this._normal.slice(0, normalCount))\n remaining -= normalCount\n }\n\n // 最后从 low 取\n if (remaining > 0) {\n const lowCount = Math.min(remaining, this._low.length)\n result.push(...this._low.slice(0, lowCount))\n }\n\n return result\n }\n\n /**\n * 将事件放回队列头部(用于重试)\n */\n unshift(items: PrioritizedEvent[]): void {\n for (const item of items.reverse()) {\n switch (item.priority) {\n case 'high':\n this._high.unshift(item)\n break\n case 'normal':\n this._normal.unshift(item)\n break\n case 'low':\n this._low.unshift(item)\n break\n }\n }\n }\n\n /**\n * 清空队列\n */\n clear(): void {\n this._high = []\n this._normal = []\n this._low = []\n }\n\n /**\n * 队列总大小\n */\n get size(): number {\n return this._high.length + this._normal.length + this._low.length\n }\n\n /**\n * 队列是否为空\n */\n get isEmpty(): boolean {\n return this.size === 0\n }\n\n /**\n * 各优先级队列大小\n */\n get stats(): { high: number; normal: number; low: number } {\n return {\n high: this._high.length,\n normal: this._normal.length,\n low: this._low.length,\n }\n }\n}\n","/**\n * 指数退避重试调度器\n *\n * 特性:\n * - 指数退避:每次失败后延迟翻倍\n * - 延迟上限:不超过 maxDelay\n * - 抖动:±20% 防止惊群效应\n * - 成功重置:成功后重置为 baseDelay\n */\n\n/** 重试调度器配置 */\nexport interface RetrySchedulerOptions {\n /** 基础延迟(毫秒),默认 1000 */\n baseDelay?: number\n /** 最大延迟(毫秒),默认 30000 */\n maxDelay?: number\n /** 抖动比例 0-1,默认 0.2(±20%) */\n jitter?: number\n}\n\n/**\n * 指数退避重试调度器\n */\nexport class RetryScheduler {\n private _baseDelay: number\n private _maxDelay: number\n private _jitter: number\n private _currentDelay: number\n private _retryCount: number = 0\n\n constructor(options: RetrySchedulerOptions = {}) {\n this._baseDelay = options.baseDelay ?? 1000\n this._maxDelay = options.maxDelay ?? 30000\n this._jitter = options.jitter ?? 0.2\n this._currentDelay = this._baseDelay\n }\n\n /**\n * 获取下次重试延迟(带抖动)\n * @returns 延迟时间(毫秒)\n */\n getNextDelay(): number {\n // 计算带抖动的延迟\n const delay = this._addJitter(this._currentDelay)\n\n // 更新下次延迟(指数增长)\n this._currentDelay = Math.min(this._currentDelay * 2, this._maxDelay)\n this._retryCount++\n\n return delay\n }\n\n /**\n * 重置延迟(成功后调用)\n */\n reset(): void {\n this._currentDelay = this._baseDelay\n this._retryCount = 0\n }\n\n /**\n * 记录失败(不获取延迟,只更新状态)\n */\n recordFailure(): void {\n this._currentDelay = Math.min(this._currentDelay * 2, this._maxDelay)\n this._retryCount++\n }\n\n /**\n * 获取当前重试次数\n */\n get retryCount(): number {\n return this._retryCount\n }\n\n /**\n * 获取当前延迟(不带抖动)\n */\n get currentDelay(): number {\n return this._currentDelay\n }\n\n /**\n * 添加抖动\n * @param delay - 原始延迟\n * @returns 带抖动的延迟\n */\n private _addJitter(delay: number): number {\n // 生成 -jitter 到 +jitter 之间的随机数\n const jitterFactor = 1 + (Math.random() * 2 - 1) * this._jitter\n return Math.round(delay * jitterFactor)\n }\n}\n","/**\n * Transport 插件 - 事件上报策略\n *\n * 支持三种发送模式:\n * - immediate: 立即发送\n * - batch: 批量发送(默认)\n * - throttle: 节流发送\n *\n * 特性:\n * - 优先级队列(high > normal > low)\n * - 指数退避重试\n * - 关键事件立即发送\n * - 页面卸载时用 sendBeacon\n */\n\nimport type {\n Plugin,\n IMonitor,\n MonitorEvent,\n ITransport,\n TransportMode,\n EventPriority,\n} from '../../core/types'\nimport { getPluginCoordinator } from '../../core/plugin-coordinator'\nimport { BrowserTransport } from '../../platforms/browser/transport'\nimport { BrowserTransportAdapter } from './platforms/browser'\nimport { PriorityQueue } from './priority-queue'\nimport { RetryScheduler } from './retry-scheduler'\n\n/** 按事件类型配置发送模式 */\nexport type TypeModeConfig = Record<string, TransportMode>\n\nexport interface TransportPluginOptions {\n /** 上报地址 */\n endpoint: string\n /** 传输适配器(可选,默认使用 BrowserTransport) */\n transport?: ITransport\n /** 默认发送模式,默认 'batch' */\n mode?: TransportMode\n /** 按事件类型配置发送模式(优先级高于 mode) */\n typeConfig?: TypeModeConfig\n /** 批量大小,默认 10 */\n batchSize?: number\n /** 刷新间隔(毫秒),默认 5000 */\n flushInterval?: number\n /** 节流间隔(毫秒),默认 1000 */\n throttleInterval?: number\n /** 最大重试次数,默认 3 */\n maxRetries?: number\n /** 基础重试延迟(毫秒),默认 1000 */\n baseRetryDelay?: number\n /** 最大重试延迟(毫秒),默认 30000 */\n maxRetryDelay?: number\n /** 最大缓冲区大小,默认 100 */\n maxBufferSize?: number\n /** 关键事件类型(立即发送,兼容旧配置) */\n criticalTypes?: string[]\n}\n\n/** 默认关键事件类型 */\nconst DEFAULT_CRITICAL: string[] = ['js_error', 'promise_error', 'resource_error']\n\n/**\n * Transport 插件\n */\nexport class TransportPlugin implements Plugin {\n name = 'transport'\n priority = 500\n\n private _transport: ITransport\n private _defaultMode: TransportMode\n private _typeConfig: TypeModeConfig\n private _batchSize: number\n private _flushInterval: number\n private _throttleInterval: number\n private _maxRetries: number\n private _criticalTypes: Set<string>\n\n private _queue: PriorityQueue\n private _throttleQueue: PriorityQueue\n private _retryScheduler: RetryScheduler\n private _platformAdapter: BrowserTransportAdapter\n\n private _retryTimer: ReturnType<typeof setTimeout> | null = null\n private _isRetrying: boolean = false\n private _lastThrottleSend: number = 0\n\n constructor(options: TransportPluginOptions) {\n this._transport = options.transport ?? new BrowserTransport(options.endpoint)\n this._defaultMode = options.mode ?? 'batch'\n this._typeConfig = options.typeConfig ?? {}\n this._batchSize = options.batchSize ?? 10\n this._flushInterval = options.flushInterval ?? 5000\n this._throttleInterval = options.throttleInterval ?? 1000\n this._maxRetries = options.maxRetries ?? 3\n this._criticalTypes = new Set(options.criticalTypes ?? DEFAULT_CRITICAL)\n\n // 将 criticalTypes 合并到 typeConfig(immediate 模式)\n for (const type of this._criticalTypes) {\n if (!this._typeConfig[type]) {\n this._typeConfig[type] = 'immediate'\n }\n }\n\n this._queue = new PriorityQueue(options.maxBufferSize ?? 100)\n this._throttleQueue = new PriorityQueue(options.maxBufferSize ?? 100)\n this._retryScheduler = new RetryScheduler({\n baseDelay: options.baseRetryDelay ?? 1000,\n maxDelay: options.maxRetryDelay ?? 30000,\n })\n this._platformAdapter = new BrowserTransportAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(_monitor: IMonitor): void {\n // 注册到协调器\n getPluginCoordinator().registerTransport(this._transport)\n\n this._platformAdapter.setupOnce(\n this._defaultMode,\n this._flushInterval,\n this._throttleInterval,\n {\n onFlush: () => this._flush(),\n onThrottleFlush: () => this._throttleFlush(),\n onBeacon: () => this._flushBeacon(),\n }\n )\n }\n\n /**\n * 事件处理:根据事件类型和模式处理\n */\n processEvent(event: MonitorEvent): MonitorEvent | null {\n const priority = this._getPriority(event)\n const mode = this._getModeForEvent(event)\n\n switch (mode) {\n case 'immediate':\n this._sendImmediate(event)\n break\n\n case 'throttle':\n this._throttleQueue.enqueue(event, priority)\n break\n\n case 'batch':\n default:\n const added = this._queue.enqueue(event, priority)\n if (!added) {\n console.warn('[SkyMonitor] Buffer full, event dropped:', event.type)\n }\n if (this._queue.size >= this._batchSize) {\n this._flush()\n }\n break\n }\n\n return null\n }\n\n /**\n * 获取事件的发送模式\n */\n private _getModeForEvent(event: MonitorEvent): TransportMode {\n return this._typeConfig[event.type] ?? this._defaultMode\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n if (this._retryTimer) {\n clearTimeout(this._retryTimer)\n this._retryTimer = null\n }\n this._platformAdapter.teardown()\n this._flushBeacon()\n }\n\n /**\n * 获取事件优先级\n */\n private _getPriority(event: MonitorEvent): EventPriority {\n if (this._criticalTypes.has(event.type)) {\n return 'high'\n }\n // 可以根据事件类型扩展优先级逻辑\n return 'normal'\n }\n\n /**\n * 立即发送单个事件\n */\n private async _sendImmediate(event: MonitorEvent): Promise<void> {\n const success = await this._transport.send([event])\n if (!success) {\n // 失败时加入队列等待重试\n this._queue.enqueue(event, 'high')\n this._scheduleRetry()\n }\n }\n\n /**\n * 批量发送\n */\n private async _flush(): Promise<void> {\n if (this._queue.isEmpty || this._isRetrying) return\n\n const items = this._queue.dequeue(this._batchSize)\n if (items.length === 0) return\n\n const events = items.map((item) => item.event)\n const success = await this._transport.send(events)\n\n if (success) {\n this._retryScheduler.reset()\n } else {\n // 失败:增加重试计数并放回队列\n for (const item of items) {\n item.retryCount++\n if (item.retryCount < this._maxRetries) {\n this._queue.unshift([item])\n } else {\n // 达到最大重试次数,移入离线队列\n this._moveToOffline([item.event])\n }\n }\n this._scheduleRetry()\n }\n }\n\n /**\n * 节流发送\n */\n private _throttleFlush(): void {\n const now = Date.now()\n if (now - this._lastThrottleSend < this._throttleInterval) return\n\n this._lastThrottleSend = now\n\n // 发送节流队列\n if (!this._throttleQueue.isEmpty) {\n const items = this._throttleQueue.dequeue(this._throttleQueue.size)\n const events = items.map((item) => item.event)\n this._transport.send(events).catch(() => {\n // 失败时放回队列\n this._throttleQueue.unshift(items)\n })\n }\n\n // 同时也触发批量队列\n this._flush()\n }\n\n /**\n * 页面卸载时发送(sendBeacon)\n */\n private _flushBeacon(): void {\n // 合并两个队列\n const batchItems = this._queue.dequeue(this._queue.size)\n const throttleItems = this._throttleQueue.dequeue(this._throttleQueue.size)\n const allItems = [...batchItems, ...throttleItems]\n\n if (allItems.length === 0) return\n\n const events = allItems.map((item) => item.event)\n\n if (this._transport.sendBeacon) {\n const success = this._transport.sendBeacon(events)\n if (!success) {\n this._queue.unshift(batchItems)\n this._throttleQueue.unshift(throttleItems)\n }\n } else {\n this._transport.send(events)\n }\n }\n\n /**\n * 调度重试\n */\n private _scheduleRetry(): void {\n if (this._isRetrying || this._retryTimer) return\n\n const delay = this._retryScheduler.getNextDelay()\n this._retryTimer = setTimeout(() => {\n this._retryTimer = null\n this._isRetrying = true\n this._flush().finally(() => {\n this._isRetrying = false\n })\n }, delay)\n }\n\n /**\n * 移入离线队列(通过协调器)\n */\n private async _moveToOffline(events: MonitorEvent[]): Promise<void> {\n await getPluginCoordinator().moveToOffline(events)\n }\n}\n\n// 导出工具类\nexport { PriorityQueue } from './priority-queue'\nexport { RetryScheduler } from './retry-scheduler'\nexport type { RetrySchedulerOptions } from './retry-scheduler'\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var s=class{constructor(){this._OriginalXHR=null;}setupOnce(t,e){if(typeof window>"u")return;this._OriginalXHR=window.XMLHttpRequest;let o=this._OriginalXHR;window.XMLHttpRequest=new Proxy(o,{construct(n,l){let r=new n(...l),a="GET",u="",p=0,d=false,h=r.open;r.open=function(i,c,...w){return a=i,u=c,d=t(u),h.apply(this,[i,c,...w])};let m=r.send;return r.send=function(i){return p=Date.now(),m.call(this,i)},r.addEventListener("loadend",()=>{d||e.onSuccess(u,a,r.status,Date.now()-p);}),r}});}teardown(){this._OriginalXHR&&typeof window<"u"&&(window.XMLHttpRequest=this._OriginalXHR),this._OriginalXHR=null;}};var g=class{constructor(t={}){this.name="xhr";this.priority=200;this._monitor=null;this._options=t,this._platformAdapter=new s;}setupOnce(t){this._monitor=t,this._platformAdapter.setupOnce(e=>this._shouldIgnore(e),{onRequest:()=>{},onSuccess:(e,o,n,l)=>{this._monitor.track("http_request",{url:e,method:o,status:n,duration:l});}});}teardown(){this._platformAdapter.teardown(),this._monitor=null;}_shouldIgnore(t){let{includeUrls:e,excludeUrls:o}=this._options;return !!(o?.some(n=>n.test(t))||e&&!e.some(n=>n.test(t)))}};exports.a=g;//# sourceMappingURL=chunk-LAATIQ3Y.cjs.map
2
+ //# sourceMappingURL=chunk-LAATIQ3Y.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/xhr/platforms/browser/index.ts","../src/plugins/xhr/index.ts"],"names":["BrowserXHRAdapter","shouldIgnore","callbacks","OriginalXHR","target","args","xhr","method","url","start","ignored","originalOpen","m","u","rest","originalSend","body","XHRPlugin","options","monitor","status","duration","includeUrls","excludeUrls","re"],"mappings":"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","file":"chunk-LAATIQ3Y.cjs","sourcesContent":["/**\n * XHR 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的 XMLHttpRequest 拦截:\n * - 使用 Proxy 代理 XMLHttpRequest\n * - 保留原始引用\n */\n\nexport interface BrowserXHRCallbacks {\n onRequest: (url: string, method: string, start: number) => void\n onSuccess: (url: string, method: string, status: number, duration: number) => void\n}\n\n/**\n * 浏览器平台适配\n * 管理 window.XMLHttpRequest 拦截\n */\nexport class BrowserXHRAdapter {\n private _OriginalXHR: typeof XMLHttpRequest | null = null\n\n /**\n * 初始化 XHR 拦截\n */\n setupOnce(\n shouldIgnore: (url: string) => boolean,\n callbacks: BrowserXHRCallbacks\n ): void {\n if (typeof window === 'undefined') return\n\n this._OriginalXHR = window.XMLHttpRequest\n\n const OriginalXHR = this._OriginalXHR\n\n window.XMLHttpRequest = new Proxy(OriginalXHR, {\n construct(target, args) {\n const xhr = new target(...(args as []))\n let method = 'GET'\n let url = ''\n let start = 0\n let ignored = false\n\n const originalOpen = xhr.open\n xhr.open = function (m: string, u: string, ...rest: unknown[]) {\n method = m\n url = u\n ignored = shouldIgnore(url)\n return originalOpen.apply(this, [m, u, ...rest] as Parameters<typeof originalOpen>)\n }\n\n const originalSend = xhr.send\n xhr.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n start = Date.now()\n return originalSend.call(this, body)\n }\n\n xhr.addEventListener('loadend', () => {\n if (ignored) return\n callbacks.onSuccess(url, method, xhr.status, Date.now() - start)\n })\n\n return xhr\n },\n }) as typeof XMLHttpRequest\n }\n\n /**\n * 清理 XHR 拦截\n */\n teardown(): void {\n if (this._OriginalXHR && typeof window !== 'undefined') {\n window.XMLHttpRequest = this._OriginalXHR\n }\n this._OriginalXHR = null\n }\n}\n","/**\n * XHR 插件 - 拦截 XMLHttpRequest\n */\n\nimport type { Plugin, IMonitor } from '../../core/types'\nimport { BrowserXHRAdapter } from './platforms/browser'\n\nexport interface XHRPluginOptions {\n /** 包含的 URL 正则(白名单) */\n includeUrls?: RegExp[]\n /** 排除的 URL 正则(黑名单) */\n excludeUrls?: RegExp[]\n}\n\n/**\n * XHR 插件\n * 基于 Proxy 代理 XMLHttpRequest 实例\n */\nexport class XHRPlugin implements Plugin {\n name = 'xhr'\n priority = 200\n\n private _monitor: IMonitor | null = null\n private _options: XHRPluginOptions\n private _platformAdapter: BrowserXHRAdapter\n\n constructor(options: XHRPluginOptions = {}) {\n this._options = options\n this._platformAdapter = new BrowserXHRAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(monitor: IMonitor): void {\n this._monitor = monitor\n this._platformAdapter.setupOnce(\n (url) => this._shouldIgnore(url),\n {\n onRequest: () => {\n // 可选:请求前的钩子\n },\n onSuccess: (url, method, status, duration) => {\n this._monitor!.track('http_request', {\n url,\n method,\n status,\n duration,\n })\n },\n }\n )\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n this._platformAdapter.teardown()\n this._monitor = null\n }\n\n private _shouldIgnore(url: string): boolean {\n const { includeUrls, excludeUrls } = this._options\n if (excludeUrls?.some((re) => re.test(url))) return true\n if (includeUrls && !includeUrls.some((re) => re.test(url))) return true\n return false\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkFBQC6XIY_cjs=require('./chunk-FBQC6XIY.cjs'),chunkJMHMJVBJ_cjs=require('./chunk-JMHMJVBJ.cjs'),chunkNM4RALDJ_cjs=require('./chunk-NM4RALDJ.cjs'),chunkZIKPTR2L_cjs=require('./chunk-ZIKPTR2L.cjs'),chunk6YTKBMJD_cjs=require('./chunk-6YTKBMJD.cjs'),chunkY46XWPAC_cjs=require('./chunk-Y46XWPAC.cjs'),chunkACIPNVBT_cjs=require('./chunk-ACIPNVBT.cjs'),chunk4K5NIPXS_cjs=require('./chunk-4K5NIPXS.cjs'),chunk4GL6IXHZ_cjs=require('./chunk-4GL6IXHZ.cjs'),chunkLAATIQ3Y_cjs=require('./chunk-LAATIQ3Y.cjs'),chunkY2IWAJSY_cjs=require('./chunk-Y2IWAJSY.cjs');var i=class{constructor(t){this._context={};this._plugins=new Map;this._sortedPlugins=[];this._options={debug:false,...t};}use(t){return this._plugins.has(t.name)&&this._plugins.get(t.name).teardown?.(),this._plugins.set(t.name,t),this._sortPlugins(),t.setupOnce?.(this),this}track(t,n={}){let o={id:chunkY46XWPAC_cjs.c(),type:t,timestamp:Date.now(),data:n,context:{...this._context,appId:this._options.appId}};this._options.debug&&console.warn("[SkyMonitor] track:",o);for(let r of this._sortedPlugins)if(r.processEvent&&(o=r.processEvent(o),o===null))return}setContext(t){this._context={...this._context,...t};}getContext(){return {...this._context}}getOptions(){return {...this._options}}clearContext(){this._context={};}hasPlugin(t){return this._plugins.has(t)}getPlugin(t){return this._plugins.get(t)}destroy(){for(let t of this._sortedPlugins)t.teardown?.();this._plugins.clear(),this._sortedPlugins=[];}_sortPlugins(){this._sortedPlugins=[...this._plugins.values()].sort((t,n)=>(t.priority??100)-(n.priority??100));}};function j(e){return new i({...e,storage:e.storage??new chunkNM4RALDJ_cjs.a})}function q(e){let t=null;e.preset&&(t=chunkZIKPTR2L_cjs.b(e.preset),t=chunkZIKPTR2L_cjs.c(t,{debug:e.debug,transport:e.transport,sampling:e.sampling,plugins:e.plugins}));let n=new i({appId:e.appId,debug:t?.debug??e.debug??false,storage:new chunkNM4RALDJ_cjs.a}),o=t?.plugins??e.plugins??["error","performance","fetch","dedupe"],r=e.endpoint??"/api/monitor",_=new chunkJMHMJVBJ_cjs.a(r),x={error:()=>n.use(new chunkY2IWAJSY_cjs.a(e.error)),performance:()=>n.use(new chunkFBQC6XIY_cjs.a),fetch:()=>n.use(new chunk4GL6IXHZ_cjs.a(e.fetch)),xhr:()=>n.use(new chunkLAATIQ3Y_cjs.a(e.xhr)),session:()=>n.use(new chunk6YTKBMJD_cjs.b),trace:()=>{},dedupe:()=>n.use(new chunk4K5NIPXS_cjs.a(e.dedupe)),sampling:()=>{let p=t?.sampling??e.sampling??{};n.use(new chunkACIPNVBT_cjs.a(p));}};for(let p of o)x[p]?.();let y=new chunkNM4RALDJ_cjs.b(e.offlineQueue);n.use(y);let v=t?.transport??e.transport??{},C=new chunkJMHMJVBJ_cjs.d({endpoint:r,transport:_,...v});return n.use(C),n}exports.a=i;exports.b=j;exports.c=q;//# sourceMappingURL=chunk-LFJTX6FJ.cjs.map
2
+ //# sourceMappingURL=chunk-LFJTX6FJ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/monitor.ts","../src/platforms/browser/index.ts"],"names":["Monitor","options","plugin","type","data","event","generateEventId","ctx","name","a","b","createBrowserMonitor","BrowserStorage","createMonitorWithPreset","config","presetConfig","getPreset","mergePreset","monitor","plugins","endpoint","transport","BrowserTransport","pluginMap","ErrorPlugin","PerformancePlugin","FetchPlugin","XHRPlugin","SessionPlugin","DedupePlugin","samplingConfig","SamplingPlugin","offlineQueue","OfflineQueuePlugin","transportConfig","transportPlugin","TransportPlugin"],"mappings":"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","file":"chunk-LFJTX6FJ.cjs","sourcesContent":["/**\n * Monitor 核心类 - 微内核架构\n *\n * 职责:\n * - track() 上报事件\n * - use() 注册插件\n * - setContext() 设置上下文\n * - 事件管道调度\n */\n\nimport type {\n MonitorOptions,\n MonitorEvent,\n MonitorContext,\n Plugin,\n IMonitor,\n} from './types'\nimport { generateEventId } from './utils'\n\n/**\n * 监控核心类\n */\nexport class Monitor implements IMonitor {\n private _options: MonitorOptions\n private _context: MonitorContext = {}\n private _plugins: Map<string, Plugin> = new Map()\n private _sortedPlugins: Plugin[] = []\n\n constructor(options: MonitorOptions) {\n this._options = {\n debug: false,\n ...options,\n }\n }\n\n /**\n * 注册插件\n * @param plugin - 插件实例\n * @returns this(支持链式调用)\n */\n use(plugin: Plugin): this {\n // 同名插件覆盖:先销毁旧插件\n if (this._plugins.has(plugin.name)) {\n const old = this._plugins.get(plugin.name)!\n old.teardown?.()\n }\n\n this._plugins.set(plugin.name, plugin)\n this._sortPlugins()\n plugin.setupOnce?.(this)\n\n return this\n }\n\n /**\n * 手动上报事件\n * @param type - 事件类型\n * @param data - 事件数据\n */\n track(type: string, data: Record<string, unknown> = {}): void {\n let event: MonitorEvent | null = {\n id: generateEventId(),\n type,\n timestamp: Date.now(),\n data,\n context: { ...this._context, appId: this._options.appId },\n }\n\n if (this._options.debug) {\n console.warn('[SkyMonitor] track:', event)\n }\n\n // 通过插件管道处理\n for (const plugin of this._sortedPlugins) {\n if (plugin.processEvent) {\n event = plugin.processEvent(event)\n if (event === null) return // 被过滤,终止管道\n }\n }\n }\n\n /**\n * 设置全局上下文\n * @param ctx - 上下文对象(会合并到现有上下文)\n */\n setContext(ctx: MonitorContext): void {\n this._context = { ...this._context, ...ctx }\n }\n\n /**\n * 获取当前上下文\n */\n getContext(): MonitorContext {\n return { ...this._context }\n }\n\n /**\n * 获取配置选项\n */\n getOptions(): MonitorOptions {\n return { ...this._options }\n }\n\n /**\n * 清空上下文\n */\n clearContext(): void {\n this._context = {}\n }\n\n /**\n * 检查插件是否已注册\n * @param name - 插件名称\n */\n hasPlugin(name: string): boolean {\n return this._plugins.has(name)\n }\n\n /**\n * 获取插件实例\n * @param name - 插件名称\n */\n getPlugin<T extends Plugin>(name: string): T | undefined {\n return this._plugins.get(name) as T | undefined\n }\n\n /**\n * 销毁所有插件\n */\n destroy(): void {\n for (const plugin of this._sortedPlugins) {\n plugin.teardown?.()\n }\n this._plugins.clear()\n this._sortedPlugins = []\n }\n\n /**\n * 按优先级排序插件\n */\n private _sortPlugins(): void {\n this._sortedPlugins = [...this._plugins.values()].sort(\n (a, b) => (a.priority ?? 100) - (b.priority ?? 100)\n )\n }\n}\n\n/**\n * 创建监控实例\n * @param options - 配置选项\n * @returns Monitor 实例\n */\nexport function createMonitor(options: MonitorOptions): Monitor {\n return new Monitor(options)\n}\n","/**\n * 浏览器平台入口\n */\n\nimport { Monitor } from '../../core/monitor'\nimport type { MonitorOptions } from '../../core/types'\nimport { BrowserStorage } from './storage'\nimport { BrowserTransport } from './transport'\nimport { getPreset, mergePreset, type MonitorPreset, type PresetConfig, type PluginName } from '../../presets'\nimport { TransportPlugin, type TransportPluginOptions } from '../../plugins/transport'\nimport { OfflineQueuePlugin, type OfflineQueuePluginOptions } from '../../plugins/offline-queue'\nimport { ErrorPlugin, type ErrorPluginOptions } from '../../plugins/error'\nimport { PerformancePlugin } from '../../plugins/performance'\nimport { FetchPlugin, type FetchPluginOptions } from '../../plugins/fetch'\nimport { XHRPlugin, type XHRPluginOptions } from '../../plugins/xhr'\nimport { SessionPlugin } from '../../plugins/session'\nimport { DedupePlugin, type DedupePluginOptions } from '../../plugins/dedupe'\nimport { SamplingPlugin, type SamplingPluginOptions } from '../../plugins/sampling'\nimport type { ReplayPluginOptions } from '../../plugins/replay'\n\nexport { BrowserStorage } from './storage'\nexport { BrowserTransport } from './transport'\n\n/** 扩展的监控配置 - 全量插件映射 */\nexport interface MonitorConfig {\n /** 应用标识(必填) */\n appId: string\n /** 上报地址,默认 '/api/monitor' */\n endpoint?: string\n /** 调试模式 */\n debug?: boolean\n /** 预设配置 */\n preset?: MonitorPreset\n /** 启用的插件列表 */\n plugins?: PluginName[]\n\n // ===== 插件配置 =====\n\n /** 传输配置 */\n transport?: Partial<TransportPluginOptions>\n /** 采样配置 */\n sampling?: Partial<SamplingPluginOptions>\n /** 错误监控配置 */\n error?: ErrorPluginOptions\n /** Fetch 拦截配置 */\n fetch?: FetchPluginOptions\n /** XHR 拦截配置 */\n xhr?: XHRPluginOptions\n /** 去重配置 */\n dedupe?: DedupePluginOptions\n /** 离线队列配置 */\n offlineQueue?: OfflineQueuePluginOptions\n /** 会话录制配置 */\n replay?: ReplayPluginOptions\n}\n\n/**\n * 创建浏览器监控实例(简化版)\n * @param options - 配置选项\n * @returns Monitor 实例\n */\nexport function createBrowserMonitor(options: MonitorOptions): Monitor {\n return new Monitor({\n ...options,\n storage: options.storage ?? new BrowserStorage(),\n })\n}\n\n/**\n * 创建浏览器监控实例(完整版,支持预设)\n * @param config - 配置选项\n * @returns Monitor 实例\n */\nexport function createMonitorWithPreset(config: MonitorConfig): Monitor {\n // 获取预设配置\n let presetConfig: PresetConfig | null = null\n if (config.preset) {\n presetConfig = getPreset(config.preset)\n presetConfig = mergePreset(presetConfig, {\n debug: config.debug,\n transport: config.transport,\n sampling: config.sampling,\n plugins: config.plugins,\n })\n }\n\n // 创建 Monitor 实例\n const monitor = new Monitor({\n appId: config.appId,\n debug: presetConfig?.debug ?? config.debug ?? false,\n storage: new BrowserStorage(),\n })\n\n // 确定要启用的插件\n const plugins = presetConfig?.plugins ?? config.plugins ?? ['error', 'performance', 'fetch', 'dedupe']\n const endpoint = config.endpoint ?? '/api/monitor'\n\n // 创建传输适配器\n const transport = new BrowserTransport(endpoint)\n\n // 注册插件(按配置映射)\n const pluginMap: Record<PluginName, () => void> = {\n error: () => monitor.use(new ErrorPlugin(config.error)),\n performance: () => monitor.use(new PerformancePlugin()),\n fetch: () => monitor.use(new FetchPlugin(config.fetch)),\n xhr: () => monitor.use(new XHRPlugin(config.xhr)),\n session: () => monitor.use(new SessionPlugin()),\n trace: () => {}, // Trace 需要手动创建\n dedupe: () => monitor.use(new DedupePlugin(config.dedupe)),\n sampling: () => {\n const samplingConfig = presetConfig?.sampling ?? config.sampling ?? {}\n monitor.use(new SamplingPlugin(samplingConfig))\n },\n }\n\n // 按顺序注册插件\n for (const name of plugins) {\n pluginMap[name]?.()\n }\n\n // 注册离线队列(通过协调器自动连接)\n const offlineQueue = new OfflineQueuePlugin(config.offlineQueue)\n monitor.use(offlineQueue)\n\n // 注册传输插件(通过协调器自动连接)\n const transportConfig = presetConfig?.transport ?? config.transport ?? {}\n const transportPlugin = new TransportPlugin({\n endpoint,\n transport,\n ...transportConfig,\n })\n\n monitor.use(transportPlugin)\n\n // 注意:ReplayPlugin 需要用户单独导入并注册\n // import { ReplayPlugin } from '@sky-monitor/sdk/plugins/replay'\n // monitor.use(new ReplayPlugin(config.replay))\n\n return monitor\n}\n"]}
@@ -0,0 +1,2 @@
1
+ var s=class{constructor(){this._OriginalXHR=null;}setupOnce(t,e){if(typeof window>"u")return;this._OriginalXHR=window.XMLHttpRequest;let o=this._OriginalXHR;window.XMLHttpRequest=new Proxy(o,{construct(n,l){let r=new n(...l),a="GET",u="",p=0,d=false,h=r.open;r.open=function(i,c,...w){return a=i,u=c,d=t(u),h.apply(this,[i,c,...w])};let m=r.send;return r.send=function(i){return p=Date.now(),m.call(this,i)},r.addEventListener("loadend",()=>{d||e.onSuccess(u,a,r.status,Date.now()-p);}),r}});}teardown(){this._OriginalXHR&&typeof window<"u"&&(window.XMLHttpRequest=this._OriginalXHR),this._OriginalXHR=null;}};var g=class{constructor(t={}){this.name="xhr";this.priority=200;this._monitor=null;this._options=t,this._platformAdapter=new s;}setupOnce(t){this._monitor=t,this._platformAdapter.setupOnce(e=>this._shouldIgnore(e),{onRequest:()=>{},onSuccess:(e,o,n,l)=>{this._monitor.track("http_request",{url:e,method:o,status:n,duration:l});}});}teardown(){this._platformAdapter.teardown(),this._monitor=null;}_shouldIgnore(t){let{includeUrls:e,excludeUrls:o}=this._options;return !!(o?.some(n=>n.test(t))||e&&!e.some(n=>n.test(t)))}};export{g as a};//# sourceMappingURL=chunk-LKBNR7RI.js.map
2
+ //# sourceMappingURL=chunk-LKBNR7RI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/xhr/platforms/browser/index.ts","../src/plugins/xhr/index.ts"],"names":["BrowserXHRAdapter","shouldIgnore","callbacks","OriginalXHR","target","args","xhr","method","url","start","ignored","originalOpen","m","u","rest","originalSend","body","XHRPlugin","options","monitor","status","duration","includeUrls","excludeUrls","re"],"mappings":"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","file":"chunk-LKBNR7RI.js","sourcesContent":["/**\n * XHR 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的 XMLHttpRequest 拦截:\n * - 使用 Proxy 代理 XMLHttpRequest\n * - 保留原始引用\n */\n\nexport interface BrowserXHRCallbacks {\n onRequest: (url: string, method: string, start: number) => void\n onSuccess: (url: string, method: string, status: number, duration: number) => void\n}\n\n/**\n * 浏览器平台适配\n * 管理 window.XMLHttpRequest 拦截\n */\nexport class BrowserXHRAdapter {\n private _OriginalXHR: typeof XMLHttpRequest | null = null\n\n /**\n * 初始化 XHR 拦截\n */\n setupOnce(\n shouldIgnore: (url: string) => boolean,\n callbacks: BrowserXHRCallbacks\n ): void {\n if (typeof window === 'undefined') return\n\n this._OriginalXHR = window.XMLHttpRequest\n\n const OriginalXHR = this._OriginalXHR\n\n window.XMLHttpRequest = new Proxy(OriginalXHR, {\n construct(target, args) {\n const xhr = new target(...(args as []))\n let method = 'GET'\n let url = ''\n let start = 0\n let ignored = false\n\n const originalOpen = xhr.open\n xhr.open = function (m: string, u: string, ...rest: unknown[]) {\n method = m\n url = u\n ignored = shouldIgnore(url)\n return originalOpen.apply(this, [m, u, ...rest] as Parameters<typeof originalOpen>)\n }\n\n const originalSend = xhr.send\n xhr.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n start = Date.now()\n return originalSend.call(this, body)\n }\n\n xhr.addEventListener('loadend', () => {\n if (ignored) return\n callbacks.onSuccess(url, method, xhr.status, Date.now() - start)\n })\n\n return xhr\n },\n }) as typeof XMLHttpRequest\n }\n\n /**\n * 清理 XHR 拦截\n */\n teardown(): void {\n if (this._OriginalXHR && typeof window !== 'undefined') {\n window.XMLHttpRequest = this._OriginalXHR\n }\n this._OriginalXHR = null\n }\n}\n","/**\n * XHR 插件 - 拦截 XMLHttpRequest\n */\n\nimport type { Plugin, IMonitor } from '../../core/types'\nimport { BrowserXHRAdapter } from './platforms/browser'\n\nexport interface XHRPluginOptions {\n /** 包含的 URL 正则(白名单) */\n includeUrls?: RegExp[]\n /** 排除的 URL 正则(黑名单) */\n excludeUrls?: RegExp[]\n}\n\n/**\n * XHR 插件\n * 基于 Proxy 代理 XMLHttpRequest 实例\n */\nexport class XHRPlugin implements Plugin {\n name = 'xhr'\n priority = 200\n\n private _monitor: IMonitor | null = null\n private _options: XHRPluginOptions\n private _platformAdapter: BrowserXHRAdapter\n\n constructor(options: XHRPluginOptions = {}) {\n this._options = options\n this._platformAdapter = new BrowserXHRAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(monitor: IMonitor): void {\n this._monitor = monitor\n this._platformAdapter.setupOnce(\n (url) => this._shouldIgnore(url),\n {\n onRequest: () => {\n // 可选:请求前的钩子\n },\n onSuccess: (url, method, status, duration) => {\n this._monitor!.track('http_request', {\n url,\n method,\n status,\n duration,\n })\n },\n }\n )\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n this._platformAdapter.teardown()\n this._monitor = null\n }\n\n private _shouldIgnore(url: string): boolean {\n const { includeUrls, excludeUrls } = this._options\n if (excludeUrls?.some((re) => re.test(url))) return true\n if (includeUrls && !includeUrls.some((re) => re.test(url))) return true\n return false\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkBVOILM65_cjs=require('./chunk-BVOILM65.cjs');var d="sky-monitor",n="events";var s=class{constructor(){this._db=null;this._dbPromise=null;}async save(e){try{(await this._getDB()).transaction(n,"readwrite").objectStore(n).add(e);}catch(t){console.warn("[SkyMonitor] Storage save failed:",t);}}async getAll(){try{let e=await this._getDB();return new Promise((t,r)=>{let i=e.transaction(n,"readonly").objectStore(n).getAll();i.onsuccess=()=>t(i.result),i.onerror=()=>r(i.error);})}catch(e){return console.warn("[SkyMonitor] Storage getAll failed:",e),[]}}async clear(){try{(await this._getDB()).transaction(n,"readwrite").objectStore(n).clear();}catch(e){console.warn("[SkyMonitor] Storage clear failed:",e);}}async _getDB(){return this._db?this._db:(this._dbPromise||(this._dbPromise=this._openDB()),this._db=await this._dbPromise,this._db)}_openDB(){return new Promise((e,t)=>{let r=indexedDB.open(d,1);r.onerror=()=>t(r.error),r.onsuccess=()=>e(r.result),r.onupgradeneeded=u=>{let i=u.target.result;i.objectStoreNames.contains(n)||i.createObjectStore(n,{keyPath:"id"});};})}};var a=class{constructor(){this._onlineHandler=null;this._retryTimer=null;}setupOnce(e,t){typeof window>"u"||(this._onlineHandler=()=>t.onOnline(),window.addEventListener("online",this._onlineHandler),this._retryTimer=setInterval(()=>t.onRetry(),e),t.onRetry());}teardown(){this._retryTimer&&(clearInterval(this._retryTimer),this._retryTimer=null),this._onlineHandler&&typeof window<"u"&&(window.removeEventListener("online",this._onlineHandler),this._onlineHandler=null);}isOnline(){return typeof navigator>"u"?true:navigator.onLine}};var c=class{constructor(e={}){this.name="offline-queue";this.priority=400;this._retryCount=0;this._isSending=false;this._storage=e.storage??new s,this._maxRetries=e.maxRetries??3,this._retryInterval=e.retryInterval??1e4,this._platformAdapter=new a;}setupOnce(e){chunkBVOILM65_cjs.a().registerOfflineQueue(this),this._platformAdapter.setupOnce(this._retryInterval,{onOnline:()=>this._onOnline(),onRetry:()=>this._retry()});}processEvent(e){return this._storage.save(e).catch(t=>{console.warn("[SkyMonitor] OfflineQueue save failed:",t);}),e}async saveEvents(e){for(let t of e)await this._storage.save(t);}teardown(){this._platformAdapter.teardown();}_onOnline(){this._retryCount=0,this._retry();}async _retry(){if(this._platformAdapter.isOnline()&&!(this._retryCount>=this._maxRetries)&&!this._isSending){this._isSending=true;try{let e=await this._storage.getAll();if(e.length===0){this._isSending=!1;return}await chunkBVOILM65_cjs.a().sendEvents(e)?(await this._storage.clear(),this._retryCount=0):this._retryCount++;}catch(e){this._retryCount++,console.warn("[SkyMonitor] OfflineQueue retry failed:",e);}finally{this._isSending=false;}}}async flush(){try{let e=await this._storage.getAll();if(e.length===0)return !0;let t=await chunkBVOILM65_cjs.a().sendEvents(e);return t&&await this._storage.clear(),t}catch(e){return console.warn("[SkyMonitor] OfflineQueue flush failed:",e),false}}async getCount(){return (await this._storage.getAll()).length}};exports.a=s;exports.b=c;//# sourceMappingURL=chunk-NM4RALDJ.cjs.map
2
+ //# sourceMappingURL=chunk-NM4RALDJ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/platforms/browser/storage.ts","../src/plugins/offline-queue/platforms/browser/index.ts","../src/plugins/offline-queue/index.ts"],"names":["DB_NAME","STORE_NAME","BrowserStorage","event","e","db","resolve","reject","request","BrowserOfflineQueueAdapter","retryInterval","callbacks","OfflineQueuePlugin","options","_monitor","getPluginCoordinator","events","success"],"mappings":"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","file":"chunk-NM4RALDJ.cjs","sourcesContent":["/**\n * 浏览器存储适配器 - IndexedDB\n */\n\nimport type { IStorage, MonitorEvent } from '../../core/types'\n\nconst DB_NAME = 'sky-monitor'\nconst STORE_NAME = 'events'\nconst DB_VERSION = 1\n\n/**\n * IndexedDB 存储实现\n */\nexport class BrowserStorage implements IStorage {\n private _db: IDBDatabase | null = null\n private _dbPromise: Promise<IDBDatabase> | null = null\n\n /**\n * 保存事件\n */\n async save(event: MonitorEvent): Promise<void> {\n try {\n const db = await this._getDB()\n const tx = db.transaction(STORE_NAME, 'readwrite')\n tx.objectStore(STORE_NAME).add(event)\n } catch (e) {\n console.warn('[SkyMonitor] Storage save failed:', e)\n }\n }\n\n /**\n * 获取所有事件\n */\n async getAll(): Promise<MonitorEvent[]> {\n try {\n const db = await this._getDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly')\n const request = tx.objectStore(STORE_NAME).getAll()\n request.onsuccess = () => resolve(request.result)\n request.onerror = () => reject(request.error)\n })\n } catch (e) {\n console.warn('[SkyMonitor] Storage getAll failed:', e)\n return []\n }\n }\n\n /**\n * 清空所有事件\n */\n async clear(): Promise<void> {\n try {\n const db = await this._getDB()\n const tx = db.transaction(STORE_NAME, 'readwrite')\n tx.objectStore(STORE_NAME).clear()\n } catch (e) {\n console.warn('[SkyMonitor] Storage clear failed:', e)\n }\n }\n\n /**\n * 获取数据库连接(单例)\n */\n private async _getDB(): Promise<IDBDatabase> {\n if (this._db) return this._db\n\n if (!this._dbPromise) {\n this._dbPromise = this._openDB()\n }\n\n this._db = await this._dbPromise\n return this._db\n }\n\n /**\n * 打开数据库\n */\n private _openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION)\n\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(request.result)\n\n request.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME, { keyPath: 'id' })\n }\n }\n })\n }\n}\n","/**\n * OfflineQueue 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的网络状态检测:\n * - navigator.onLine 检测\n * - online/offline 事件监听\n */\n\nexport interface BrowserOfflineQueueCallbacks {\n onOnline: () => void\n onRetry: () => void\n}\n\n/**\n * 浏览器平台适配\n * 管理网络状态检测和事件监听\n */\nexport class BrowserOfflineQueueAdapter {\n private _onlineHandler: (() => void) | null = null\n private _retryTimer: ReturnType<typeof setInterval> | null = null\n\n /**\n * 初始化浏览器网络状态监听\n */\n setupOnce(retryInterval: number, callbacks: BrowserOfflineQueueCallbacks): void {\n if (typeof window === 'undefined') return\n\n this._onlineHandler = () => callbacks.onOnline()\n window.addEventListener('online', this._onlineHandler)\n\n // 启动重试定时器\n this._retryTimer = setInterval(() => callbacks.onRetry(), retryInterval)\n\n // 页面加载时尝试重传\n callbacks.onRetry()\n }\n\n /**\n * 清理浏览器事件监听\n */\n teardown(): void {\n if (this._retryTimer) {\n clearInterval(this._retryTimer)\n this._retryTimer = null\n }\n if (this._onlineHandler && typeof window !== 'undefined') {\n window.removeEventListener('online', this._onlineHandler)\n this._onlineHandler = null\n }\n }\n\n /**\n * 检查网络是否在线\n */\n isOnline(): boolean {\n if (typeof navigator === 'undefined') return true\n return navigator.onLine\n }\n}\n","/**\n * OfflineQueue 插件 - 离线队列\n *\n * 修复版本:\n * - 正确的重传逻辑\n * - 通过协调器与 TransportPlugin 通信\n * - 发送成功后才清理\n */\n\nimport type { Plugin, IMonitor, MonitorEvent, IStorage } from '../../core/types'\nimport { getPluginCoordinator, type IOfflineQueue } from '../../core/plugin-coordinator'\nimport { BrowserStorage } from '../../platforms/browser/storage'\nimport { BrowserOfflineQueueAdapter } from './platforms/browser'\n\nexport interface OfflineQueuePluginOptions {\n /** 存储适配器(可选,默认使用 BrowserStorage) */\n storage?: IStorage\n /** 最大重试次数,默认 3 */\n maxRetries?: number\n /** 重试间隔(毫秒),默认 10000 */\n retryInterval?: number\n}\n\n/**\n * OfflineQueue 插件\n * IndexedDB 离线队列,网络恢复后自动重传\n */\nexport class OfflineQueuePlugin implements Plugin, IOfflineQueue {\n name = 'offline-queue'\n priority = 400\n\n private _storage: IStorage\n private _maxRetries: number\n private _retryInterval: number\n private _retryCount: number = 0\n private _isSending: boolean = false\n private _platformAdapter: BrowserOfflineQueueAdapter\n\n constructor(options: OfflineQueuePluginOptions = {}) {\n this._storage = options.storage ?? new BrowserStorage()\n this._maxRetries = options.maxRetries ?? 3\n this._retryInterval = options.retryInterval ?? 10000\n this._platformAdapter = new BrowserOfflineQueueAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(_monitor: IMonitor): void {\n // 注册到协调器\n getPluginCoordinator().registerOfflineQueue(this)\n\n this._platformAdapter.setupOnce(this._retryInterval, {\n onOnline: () => this._onOnline(),\n onRetry: () => this._retry(),\n })\n }\n\n /**\n * 事件处理:存入离线队列\n */\n processEvent(event: MonitorEvent): MonitorEvent {\n this._storage.save(event).catch((e) => {\n console.warn('[SkyMonitor] OfflineQueue save failed:', e)\n })\n return event\n }\n\n /**\n * 批量保存事件到离线队列\n */\n async saveEvents(events: MonitorEvent[]): Promise<void> {\n for (const event of events) {\n await this._storage.save(event)\n }\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n this._platformAdapter.teardown()\n }\n\n /**\n * 网络恢复时重置重试计数并立即重传\n */\n private _onOnline(): void {\n this._retryCount = 0\n this._retry()\n }\n\n /**\n * 重传离线事件(通过协调器发送)\n */\n private async _retry(): Promise<void> {\n // 检查网络状态\n if (!this._platformAdapter.isOnline()) return\n // 检查重试次数\n if (this._retryCount >= this._maxRetries) return\n // 防止并发重传\n if (this._isSending) return\n\n this._isSending = true\n\n try {\n const events = await this._storage.getAll()\n if (events.length === 0) {\n this._isSending = false\n return\n }\n\n // 通过协调器发送\n const success = await getPluginCoordinator().sendEvents(events)\n\n if (success) {\n // 发送成功,清理存储\n await this._storage.clear()\n this._retryCount = 0\n } else {\n // 发送失败,增加重试计数\n this._retryCount++\n }\n } catch (e) {\n this._retryCount++\n console.warn('[SkyMonitor] OfflineQueue retry failed:', e)\n } finally {\n this._isSending = false\n }\n }\n\n /**\n * 手动触发重传\n */\n async flush(): Promise<boolean> {\n try {\n const events = await this._storage.getAll()\n if (events.length === 0) return true\n\n const success = await getPluginCoordinator().sendEvents(events)\n if (success) {\n await this._storage.clear()\n }\n return success\n } catch (e) {\n console.warn('[SkyMonitor] OfflineQueue flush failed:', e)\n return false\n }\n }\n\n /**\n * 获取离线事件数量\n */\n async getCount(): Promise<number> {\n const events = await this._storage.getAll()\n return events.length\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import {a}from'./chunk-4DK7RV2K.js';var h=class{constructor(e="/api/monitor"){this._endpoint=e;}async send(e){try{return (await fetch(this._endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})).ok}catch(t){return console.warn("[SkyMonitor] Transport send failed:",t),false}}sendBeacon(e){if(typeof navigator>"u"||!navigator.sendBeacon)return false;try{return navigator.sendBeacon(this._endpoint,JSON.stringify(e))}catch(t){return console.warn("[SkyMonitor] Transport sendBeacon failed:",t),false}}};var l=class{constructor(){this._timer=null;this._throttleTimer=null;this._beforeUnloadHandler=null;this._visibilityHandler=null;this._pagehideHandler=null;}setupOnce(e,t,i,r){typeof window>"u"||(e==="batch"?this._timer=setInterval(()=>r.onFlush(),t):e==="throttle"&&(this._timer=setInterval(()=>r.onThrottleFlush(),i)),this._pagehideHandler=n=>{n.persisted||r.onBeacon();},window.addEventListener("pagehide",this._pagehideHandler),this._visibilityHandler=()=>{document.visibilityState==="hidden"&&r.onBeacon();},document.addEventListener("visibilitychange",this._visibilityHandler),this._beforeUnloadHandler=()=>r.onBeacon(),window.addEventListener("beforeunload",this._beforeUnloadHandler));}teardown(){this._timer&&(clearInterval(this._timer),this._timer=null),this._throttleTimer&&(clearTimeout(this._throttleTimer),this._throttleTimer=null),typeof window<"u"&&(this._pagehideHandler&&window.removeEventListener("pagehide",this._pagehideHandler),this._visibilityHandler&&document.removeEventListener("visibilitychange",this._visibilityHandler),this._beforeUnloadHandler&&window.removeEventListener("beforeunload",this._beforeUnloadHandler));}};var s=class{constructor(e=100){this._high=[];this._normal=[];this._low=[];this._maxSize=e;}enqueue(e,t="normal"){if(this.size>=this._maxSize)if(this._low.length>0)this._low.shift();else if(this._normal.length>0&&t==="high")this._normal.shift();else {if(t==="low")return false;if(t==="normal"&&this._normal.length===0&&this._low.length===0)return false}let i={event:e,priority:t,retryCount:0};switch(t){case "high":this._high.push(i);break;case "normal":this._normal.push(i);break;case "low":this._low.push(i);break}return true}dequeue(e){let t=[];for(;t.length<e&&this.size>0;)this._high.length>0?t.push(this._high.shift()):this._normal.length>0?t.push(this._normal.shift()):this._low.length>0&&t.push(this._low.shift());return t}peek(e){let t=[],i=e,r=Math.min(i,this._high.length);if(t.push(...this._high.slice(0,r)),i-=r,i>0){let n=Math.min(i,this._normal.length);t.push(...this._normal.slice(0,n)),i-=n;}if(i>0){let n=Math.min(i,this._low.length);t.push(...this._low.slice(0,n));}return t}unshift(e){for(let t of e.reverse())switch(t.priority){case "high":this._high.unshift(t);break;case "normal":this._normal.unshift(t);break;case "low":this._low.unshift(t);break}}clear(){this._high=[],this._normal=[],this._low=[];}get size(){return this._high.length+this._normal.length+this._low.length}get isEmpty(){return this.size===0}get stats(){return {high:this._high.length,normal:this._normal.length,low:this._low.length}}};var o=class{constructor(e={}){this._retryCount=0;this._baseDelay=e.baseDelay??1e3,this._maxDelay=e.maxDelay??3e4,this._jitter=e.jitter??.2,this._currentDelay=this._baseDelay;}getNextDelay(){let e=this._addJitter(this._currentDelay);return this._currentDelay=Math.min(this._currentDelay*2,this._maxDelay),this._retryCount++,e}reset(){this._currentDelay=this._baseDelay,this._retryCount=0;}recordFailure(){this._currentDelay=Math.min(this._currentDelay*2,this._maxDelay),this._retryCount++;}get retryCount(){return this._retryCount}get currentDelay(){return this._currentDelay}_addJitter(e){let t=1+(Math.random()*2-1)*this._jitter;return Math.round(e*t)}};var d=["js_error","promise_error","resource_error"],_=class{constructor(e){this.name="transport";this.priority=500;this._retryTimer=null;this._isRetrying=false;this._lastThrottleSend=0;this._transport=e.transport??new h(e.endpoint),this._defaultMode=e.mode??"batch",this._typeConfig=e.typeConfig??{},this._batchSize=e.batchSize??10,this._flushInterval=e.flushInterval??5e3,this._throttleInterval=e.throttleInterval??1e3,this._maxRetries=e.maxRetries??3,this._criticalTypes=new Set(e.criticalTypes??d);for(let t of this._criticalTypes)this._typeConfig[t]||(this._typeConfig[t]="immediate");this._queue=new s(e.maxBufferSize??100),this._throttleQueue=new s(e.maxBufferSize??100),this._retryScheduler=new o({baseDelay:e.baseRetryDelay??1e3,maxDelay:e.maxRetryDelay??3e4}),this._platformAdapter=new l;}setupOnce(e){a().registerTransport(this._transport),this._platformAdapter.setupOnce(this._defaultMode,this._flushInterval,this._throttleInterval,{onFlush:()=>this._flush(),onThrottleFlush:()=>this._throttleFlush(),onBeacon:()=>this._flushBeacon()});}processEvent(e){let t=this._getPriority(e);switch(this._getModeForEvent(e)){case "immediate":this._sendImmediate(e);break;case "throttle":this._throttleQueue.enqueue(e,t);break;default:this._queue.enqueue(e,t)||console.warn("[SkyMonitor] Buffer full, event dropped:",e.type),this._queue.size>=this._batchSize&&this._flush();break}return null}_getModeForEvent(e){return this._typeConfig[e.type]??this._defaultMode}teardown(){this._retryTimer&&(clearTimeout(this._retryTimer),this._retryTimer=null),this._platformAdapter.teardown(),this._flushBeacon();}_getPriority(e){return this._criticalTypes.has(e.type)?"high":"normal"}async _sendImmediate(e){await this._transport.send([e])||(this._queue.enqueue(e,"high"),this._scheduleRetry());}async _flush(){if(this._queue.isEmpty||this._isRetrying)return;let e=this._queue.dequeue(this._batchSize);if(e.length===0)return;let t=e.map(r=>r.event);if(await this._transport.send(t))this._retryScheduler.reset();else {for(let r of e)r.retryCount++,r.retryCount<this._maxRetries?this._queue.unshift([r]):this._moveToOffline([r.event]);this._scheduleRetry();}}_throttleFlush(){let e=Date.now();if(!(e-this._lastThrottleSend<this._throttleInterval)){if(this._lastThrottleSend=e,!this._throttleQueue.isEmpty){let t=this._throttleQueue.dequeue(this._throttleQueue.size),i=t.map(r=>r.event);this._transport.send(i).catch(()=>{this._throttleQueue.unshift(t);});}this._flush();}}_flushBeacon(){let e=this._queue.dequeue(this._queue.size),t=this._throttleQueue.dequeue(this._throttleQueue.size),i=[...e,...t];if(i.length===0)return;let r=i.map(n=>n.event);this._transport.sendBeacon?this._transport.sendBeacon(r)||(this._queue.unshift(e),this._throttleQueue.unshift(t)):this._transport.send(r);}_scheduleRetry(){if(this._isRetrying||this._retryTimer)return;let e=this._retryScheduler.getNextDelay();this._retryTimer=setTimeout(()=>{this._retryTimer=null,this._isRetrying=true,this._flush().finally(()=>{this._isRetrying=false;});},e);}async _moveToOffline(e){await a().moveToOffline(e);}};export{h as a,s as b,o as c,_ as d};//# sourceMappingURL=chunk-O32X45L3.js.map
2
+ //# sourceMappingURL=chunk-O32X45L3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/platforms/browser/transport.ts","../src/plugins/transport/platforms/browser/index.ts","../src/plugins/transport/priority-queue.ts","../src/plugins/transport/retry-scheduler.ts","../src/plugins/transport/index.ts"],"names":["BrowserTransport","endpoint","events","e","BrowserTransportAdapter","mode","flushInterval","throttleInterval","callbacks","PriorityQueue","maxSize","event","priority","item","count","result","remaining","highCount","normalCount","lowCount","items","RetryScheduler","options","delay","jitterFactor","DEFAULT_CRITICAL","TransportPlugin","type","_monitor","getPluginCoordinator","now","batchItems","throttleItems","allItems"],"mappings":"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","file":"chunk-O32X45L3.js","sourcesContent":["/**\n * 浏览器传输适配器 - sendBeacon + fetch\n */\n\nimport type { ITransport, MonitorEvent } from '../../core/types'\n\n/**\n * 浏览器传输实现\n */\nexport class BrowserTransport implements ITransport {\n private _endpoint: string\n\n constructor(endpoint: string = '/api/monitor') {\n this._endpoint = endpoint\n }\n\n /**\n * 发送事件(fetch)\n */\n async send(events: MonitorEvent[]): Promise<boolean> {\n try {\n const response = await fetch(this._endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(events),\n })\n return response.ok\n } catch (e) {\n console.warn('[SkyMonitor] Transport send failed:', e)\n return false\n }\n }\n\n /**\n * 发送事件(sendBeacon,用于页面关闭)\n */\n sendBeacon(events: MonitorEvent[]): boolean {\n if (typeof navigator === 'undefined' || !navigator.sendBeacon) {\n return false\n }\n\n try {\n return navigator.sendBeacon(\n this._endpoint,\n JSON.stringify(events)\n )\n } catch (e) {\n console.warn('[SkyMonitor] Transport sendBeacon failed:', e)\n return false\n }\n }\n}\n","/**\n * Transport 插件 - 浏览器平台实现\n *\n * 负责浏览器特定的生命周期管理:\n * - 页面卸载时用 sendBeacon\n * - 页面隐藏时刷新缓冲\n * - 定时器管理\n */\n\nimport type { MonitorEvent } from '../../../../core/types'\n\nexport interface BrowserTransportState {\n queue: Array<{ event: MonitorEvent; retryCount: number }>\n isEmpty: boolean\n size: number\n}\n\nexport interface BrowserTransportCallbacks {\n onFlush: () => Promise<void>\n onThrottleFlush: () => void\n onBeacon: () => void\n}\n\n/**\n * 浏览器平台适配\n * 管理 window/document 事件和定时器\n */\nexport class BrowserTransportAdapter {\n private _timer: ReturnType<typeof setInterval> | null = null\n private _throttleTimer: ReturnType<typeof setTimeout> | null = null\n private _beforeUnloadHandler: (() => void) | null = null\n private _visibilityHandler: (() => void) | null = null\n private _pagehideHandler: ((e: PageTransitionEvent) => void) | null = null\n\n /**\n * 初始化浏览器事件监听\n */\n setupOnce(\n mode: 'batch' | 'throttle' | 'immediate',\n flushInterval: number,\n throttleInterval: number,\n callbacks: BrowserTransportCallbacks\n ): void {\n if (typeof window === 'undefined') return\n\n // 根据模式设置定时器\n if (mode === 'batch') {\n this._timer = setInterval(() => callbacks.onFlush(), flushInterval)\n } else if (mode === 'throttle') {\n this._timer = setInterval(() => callbacks.onThrottleFlush(), throttleInterval)\n }\n\n // 页面卸载时用 sendBeacon(三重保障)\n this._pagehideHandler = (e: PageTransitionEvent) => {\n if (e.persisted) return\n callbacks.onBeacon()\n }\n window.addEventListener('pagehide', this._pagehideHandler)\n\n this._visibilityHandler = () => {\n if (document.visibilityState === 'hidden') {\n callbacks.onBeacon()\n }\n }\n document.addEventListener('visibilitychange', this._visibilityHandler)\n\n this._beforeUnloadHandler = () => callbacks.onBeacon()\n window.addEventListener('beforeunload', this._beforeUnloadHandler)\n }\n\n /**\n * 清理浏览器事件监听\n */\n teardown(): void {\n if (this._timer) {\n clearInterval(this._timer)\n this._timer = null\n }\n if (this._throttleTimer) {\n clearTimeout(this._throttleTimer)\n this._throttleTimer = null\n }\n\n if (typeof window !== 'undefined') {\n if (this._pagehideHandler) {\n window.removeEventListener('pagehide', this._pagehideHandler)\n }\n if (this._visibilityHandler) {\n document.removeEventListener('visibilitychange', this._visibilityHandler)\n }\n if (this._beforeUnloadHandler) {\n window.removeEventListener('beforeunload', this._beforeUnloadHandler)\n }\n }\n }\n}\n","/**\n * 优先级队列 - 按优先级排序事件\n *\n * 支持三个优先级级别:high > normal > low\n * 缓冲区满时优先丢弃低优先级事件\n */\n\nimport type { MonitorEvent, EventPriority, PrioritizedEvent } from '../../core/types'\n\n/**\n * 优先级队列\n */\nexport class PriorityQueue {\n private _high: PrioritizedEvent[] = []\n private _normal: PrioritizedEvent[] = []\n private _low: PrioritizedEvent[] = []\n private _maxSize: number\n\n constructor(maxSize: number = 100) {\n this._maxSize = maxSize\n }\n\n /**\n * 添加事件到队列\n * @param event - 监控事件\n * @param priority - 优先级\n * @returns 是否成功添加(缓冲区满且无法丢弃时返回 false)\n */\n enqueue(event: MonitorEvent, priority: EventPriority = 'normal'): boolean {\n // 缓冲区满时,尝试丢弃低优先级事件\n if (this.size >= this._maxSize) {\n if (this._low.length > 0) {\n this._low.shift()\n } else if (this._normal.length > 0 && priority === 'high') {\n this._normal.shift()\n } else if (priority === 'low') {\n // 新事件是低优先级,直接丢弃\n return false\n } else if (priority === 'normal' && this._normal.length === 0 && this._low.length === 0) {\n // 队列全是高优先级,丢弃新的普通事件\n return false\n }\n }\n\n const item: PrioritizedEvent = { event, priority, retryCount: 0 }\n\n switch (priority) {\n case 'high':\n this._high.push(item)\n break\n case 'normal':\n this._normal.push(item)\n break\n case 'low':\n this._low.push(item)\n break\n }\n\n return true\n }\n\n /**\n * 取出指定数量的事件(按优先级顺序)\n * @param count - 取出数量\n * @returns 事件数组\n */\n dequeue(count: number): PrioritizedEvent[] {\n const result: PrioritizedEvent[] = []\n\n while (result.length < count && this.size > 0) {\n if (this._high.length > 0) {\n result.push(this._high.shift()!)\n } else if (this._normal.length > 0) {\n result.push(this._normal.shift()!)\n } else if (this._low.length > 0) {\n result.push(this._low.shift()!)\n }\n }\n\n return result\n }\n\n /**\n * 查看队列头部事件(不移除)\n * @param count - 查看数量\n */\n peek(count: number): PrioritizedEvent[] {\n const result: PrioritizedEvent[] = []\n let remaining = count\n\n // 先从 high 取\n const highCount = Math.min(remaining, this._high.length)\n result.push(...this._high.slice(0, highCount))\n remaining -= highCount\n\n // 再从 normal 取\n if (remaining > 0) {\n const normalCount = Math.min(remaining, this._normal.length)\n result.push(...this._normal.slice(0, normalCount))\n remaining -= normalCount\n }\n\n // 最后从 low 取\n if (remaining > 0) {\n const lowCount = Math.min(remaining, this._low.length)\n result.push(...this._low.slice(0, lowCount))\n }\n\n return result\n }\n\n /**\n * 将事件放回队列头部(用于重试)\n */\n unshift(items: PrioritizedEvent[]): void {\n for (const item of items.reverse()) {\n switch (item.priority) {\n case 'high':\n this._high.unshift(item)\n break\n case 'normal':\n this._normal.unshift(item)\n break\n case 'low':\n this._low.unshift(item)\n break\n }\n }\n }\n\n /**\n * 清空队列\n */\n clear(): void {\n this._high = []\n this._normal = []\n this._low = []\n }\n\n /**\n * 队列总大小\n */\n get size(): number {\n return this._high.length + this._normal.length + this._low.length\n }\n\n /**\n * 队列是否为空\n */\n get isEmpty(): boolean {\n return this.size === 0\n }\n\n /**\n * 各优先级队列大小\n */\n get stats(): { high: number; normal: number; low: number } {\n return {\n high: this._high.length,\n normal: this._normal.length,\n low: this._low.length,\n }\n }\n}\n","/**\n * 指数退避重试调度器\n *\n * 特性:\n * - 指数退避:每次失败后延迟翻倍\n * - 延迟上限:不超过 maxDelay\n * - 抖动:±20% 防止惊群效应\n * - 成功重置:成功后重置为 baseDelay\n */\n\n/** 重试调度器配置 */\nexport interface RetrySchedulerOptions {\n /** 基础延迟(毫秒),默认 1000 */\n baseDelay?: number\n /** 最大延迟(毫秒),默认 30000 */\n maxDelay?: number\n /** 抖动比例 0-1,默认 0.2(±20%) */\n jitter?: number\n}\n\n/**\n * 指数退避重试调度器\n */\nexport class RetryScheduler {\n private _baseDelay: number\n private _maxDelay: number\n private _jitter: number\n private _currentDelay: number\n private _retryCount: number = 0\n\n constructor(options: RetrySchedulerOptions = {}) {\n this._baseDelay = options.baseDelay ?? 1000\n this._maxDelay = options.maxDelay ?? 30000\n this._jitter = options.jitter ?? 0.2\n this._currentDelay = this._baseDelay\n }\n\n /**\n * 获取下次重试延迟(带抖动)\n * @returns 延迟时间(毫秒)\n */\n getNextDelay(): number {\n // 计算带抖动的延迟\n const delay = this._addJitter(this._currentDelay)\n\n // 更新下次延迟(指数增长)\n this._currentDelay = Math.min(this._currentDelay * 2, this._maxDelay)\n this._retryCount++\n\n return delay\n }\n\n /**\n * 重置延迟(成功后调用)\n */\n reset(): void {\n this._currentDelay = this._baseDelay\n this._retryCount = 0\n }\n\n /**\n * 记录失败(不获取延迟,只更新状态)\n */\n recordFailure(): void {\n this._currentDelay = Math.min(this._currentDelay * 2, this._maxDelay)\n this._retryCount++\n }\n\n /**\n * 获取当前重试次数\n */\n get retryCount(): number {\n return this._retryCount\n }\n\n /**\n * 获取当前延迟(不带抖动)\n */\n get currentDelay(): number {\n return this._currentDelay\n }\n\n /**\n * 添加抖动\n * @param delay - 原始延迟\n * @returns 带抖动的延迟\n */\n private _addJitter(delay: number): number {\n // 生成 -jitter 到 +jitter 之间的随机数\n const jitterFactor = 1 + (Math.random() * 2 - 1) * this._jitter\n return Math.round(delay * jitterFactor)\n }\n}\n","/**\n * Transport 插件 - 事件上报策略\n *\n * 支持三种发送模式:\n * - immediate: 立即发送\n * - batch: 批量发送(默认)\n * - throttle: 节流发送\n *\n * 特性:\n * - 优先级队列(high > normal > low)\n * - 指数退避重试\n * - 关键事件立即发送\n * - 页面卸载时用 sendBeacon\n */\n\nimport type {\n Plugin,\n IMonitor,\n MonitorEvent,\n ITransport,\n TransportMode,\n EventPriority,\n} from '../../core/types'\nimport { getPluginCoordinator } from '../../core/plugin-coordinator'\nimport { BrowserTransport } from '../../platforms/browser/transport'\nimport { BrowserTransportAdapter } from './platforms/browser'\nimport { PriorityQueue } from './priority-queue'\nimport { RetryScheduler } from './retry-scheduler'\n\n/** 按事件类型配置发送模式 */\nexport type TypeModeConfig = Record<string, TransportMode>\n\nexport interface TransportPluginOptions {\n /** 上报地址 */\n endpoint: string\n /** 传输适配器(可选,默认使用 BrowserTransport) */\n transport?: ITransport\n /** 默认发送模式,默认 'batch' */\n mode?: TransportMode\n /** 按事件类型配置发送模式(优先级高于 mode) */\n typeConfig?: TypeModeConfig\n /** 批量大小,默认 10 */\n batchSize?: number\n /** 刷新间隔(毫秒),默认 5000 */\n flushInterval?: number\n /** 节流间隔(毫秒),默认 1000 */\n throttleInterval?: number\n /** 最大重试次数,默认 3 */\n maxRetries?: number\n /** 基础重试延迟(毫秒),默认 1000 */\n baseRetryDelay?: number\n /** 最大重试延迟(毫秒),默认 30000 */\n maxRetryDelay?: number\n /** 最大缓冲区大小,默认 100 */\n maxBufferSize?: number\n /** 关键事件类型(立即发送,兼容旧配置) */\n criticalTypes?: string[]\n}\n\n/** 默认关键事件类型 */\nconst DEFAULT_CRITICAL: string[] = ['js_error', 'promise_error', 'resource_error']\n\n/**\n * Transport 插件\n */\nexport class TransportPlugin implements Plugin {\n name = 'transport'\n priority = 500\n\n private _transport: ITransport\n private _defaultMode: TransportMode\n private _typeConfig: TypeModeConfig\n private _batchSize: number\n private _flushInterval: number\n private _throttleInterval: number\n private _maxRetries: number\n private _criticalTypes: Set<string>\n\n private _queue: PriorityQueue\n private _throttleQueue: PriorityQueue\n private _retryScheduler: RetryScheduler\n private _platformAdapter: BrowserTransportAdapter\n\n private _retryTimer: ReturnType<typeof setTimeout> | null = null\n private _isRetrying: boolean = false\n private _lastThrottleSend: number = 0\n\n constructor(options: TransportPluginOptions) {\n this._transport = options.transport ?? new BrowserTransport(options.endpoint)\n this._defaultMode = options.mode ?? 'batch'\n this._typeConfig = options.typeConfig ?? {}\n this._batchSize = options.batchSize ?? 10\n this._flushInterval = options.flushInterval ?? 5000\n this._throttleInterval = options.throttleInterval ?? 1000\n this._maxRetries = options.maxRetries ?? 3\n this._criticalTypes = new Set(options.criticalTypes ?? DEFAULT_CRITICAL)\n\n // 将 criticalTypes 合并到 typeConfig(immediate 模式)\n for (const type of this._criticalTypes) {\n if (!this._typeConfig[type]) {\n this._typeConfig[type] = 'immediate'\n }\n }\n\n this._queue = new PriorityQueue(options.maxBufferSize ?? 100)\n this._throttleQueue = new PriorityQueue(options.maxBufferSize ?? 100)\n this._retryScheduler = new RetryScheduler({\n baseDelay: options.baseRetryDelay ?? 1000,\n maxDelay: options.maxRetryDelay ?? 30000,\n })\n this._platformAdapter = new BrowserTransportAdapter()\n }\n\n /**\n * 插件初始化\n */\n setupOnce(_monitor: IMonitor): void {\n // 注册到协调器\n getPluginCoordinator().registerTransport(this._transport)\n\n this._platformAdapter.setupOnce(\n this._defaultMode,\n this._flushInterval,\n this._throttleInterval,\n {\n onFlush: () => this._flush(),\n onThrottleFlush: () => this._throttleFlush(),\n onBeacon: () => this._flushBeacon(),\n }\n )\n }\n\n /**\n * 事件处理:根据事件类型和模式处理\n */\n processEvent(event: MonitorEvent): MonitorEvent | null {\n const priority = this._getPriority(event)\n const mode = this._getModeForEvent(event)\n\n switch (mode) {\n case 'immediate':\n this._sendImmediate(event)\n break\n\n case 'throttle':\n this._throttleQueue.enqueue(event, priority)\n break\n\n case 'batch':\n default:\n const added = this._queue.enqueue(event, priority)\n if (!added) {\n console.warn('[SkyMonitor] Buffer full, event dropped:', event.type)\n }\n if (this._queue.size >= this._batchSize) {\n this._flush()\n }\n break\n }\n\n return null\n }\n\n /**\n * 获取事件的发送模式\n */\n private _getModeForEvent(event: MonitorEvent): TransportMode {\n return this._typeConfig[event.type] ?? this._defaultMode\n }\n\n /**\n * 插件销毁\n */\n teardown(): void {\n if (this._retryTimer) {\n clearTimeout(this._retryTimer)\n this._retryTimer = null\n }\n this._platformAdapter.teardown()\n this._flushBeacon()\n }\n\n /**\n * 获取事件优先级\n */\n private _getPriority(event: MonitorEvent): EventPriority {\n if (this._criticalTypes.has(event.type)) {\n return 'high'\n }\n // 可以根据事件类型扩展优先级逻辑\n return 'normal'\n }\n\n /**\n * 立即发送单个事件\n */\n private async _sendImmediate(event: MonitorEvent): Promise<void> {\n const success = await this._transport.send([event])\n if (!success) {\n // 失败时加入队列等待重试\n this._queue.enqueue(event, 'high')\n this._scheduleRetry()\n }\n }\n\n /**\n * 批量发送\n */\n private async _flush(): Promise<void> {\n if (this._queue.isEmpty || this._isRetrying) return\n\n const items = this._queue.dequeue(this._batchSize)\n if (items.length === 0) return\n\n const events = items.map((item) => item.event)\n const success = await this._transport.send(events)\n\n if (success) {\n this._retryScheduler.reset()\n } else {\n // 失败:增加重试计数并放回队列\n for (const item of items) {\n item.retryCount++\n if (item.retryCount < this._maxRetries) {\n this._queue.unshift([item])\n } else {\n // 达到最大重试次数,移入离线队列\n this._moveToOffline([item.event])\n }\n }\n this._scheduleRetry()\n }\n }\n\n /**\n * 节流发送\n */\n private _throttleFlush(): void {\n const now = Date.now()\n if (now - this._lastThrottleSend < this._throttleInterval) return\n\n this._lastThrottleSend = now\n\n // 发送节流队列\n if (!this._throttleQueue.isEmpty) {\n const items = this._throttleQueue.dequeue(this._throttleQueue.size)\n const events = items.map((item) => item.event)\n this._transport.send(events).catch(() => {\n // 失败时放回队列\n this._throttleQueue.unshift(items)\n })\n }\n\n // 同时也触发批量队列\n this._flush()\n }\n\n /**\n * 页面卸载时发送(sendBeacon)\n */\n private _flushBeacon(): void {\n // 合并两个队列\n const batchItems = this._queue.dequeue(this._queue.size)\n const throttleItems = this._throttleQueue.dequeue(this._throttleQueue.size)\n const allItems = [...batchItems, ...throttleItems]\n\n if (allItems.length === 0) return\n\n const events = allItems.map((item) => item.event)\n\n if (this._transport.sendBeacon) {\n const success = this._transport.sendBeacon(events)\n if (!success) {\n this._queue.unshift(batchItems)\n this._throttleQueue.unshift(throttleItems)\n }\n } else {\n this._transport.send(events)\n }\n }\n\n /**\n * 调度重试\n */\n private _scheduleRetry(): void {\n if (this._isRetrying || this._retryTimer) return\n\n const delay = this._retryScheduler.getNextDelay()\n this._retryTimer = setTimeout(() => {\n this._retryTimer = null\n this._isRetrying = true\n this._flush().finally(() => {\n this._isRetrying = false\n })\n }, delay)\n }\n\n /**\n * 移入离线队列(通过协调器)\n */\n private async _moveToOffline(events: MonitorEvent[]): Promise<void> {\n await getPluginCoordinator().moveToOffline(events)\n }\n}\n\n// 导出工具类\nexport { PriorityQueue } from './priority-queue'\nexport { RetryScheduler } from './retry-scheduler'\nexport type { RetrySchedulerOptions } from './retry-scheduler'\n"]}