@macroui/event-tracker 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/event-tracker.cjs +4252 -879
- package/dist/event-tracker.cjs.map +1 -0
- package/dist/event-tracker.js +4252 -879
- package/dist/event-tracker.js.map +1 -0
- package/dist/event-tracker.min.js +2 -1
- package/dist/event-tracker.min.js.map +1 -0
- package/dist/event-tracker.mjs +4212 -880
- package/dist/event-tracker.mjs.map +1 -0
- package/dist/plugin/debug-sender.cjs +53 -2
- package/dist/plugin/debug-sender.mjs +53 -2
- package/dist/plugin/experiment.cjs +181 -0
- package/dist/plugin/experiment.cjs.map +1 -0
- package/dist/plugin/experiment.mjs +178 -0
- package/dist/plugin/experiment.mjs.map +1 -0
- package/dist/plugin/indexeddb-sender.cjs +51 -2
- package/dist/plugin/indexeddb-sender.mjs +51 -2
- package/dist/plugin/otel-bridge.cjs +164 -0
- package/dist/plugin/otel-bridge.cjs.map +1 -0
- package/dist/plugin/otel-bridge.mjs +162 -0
- package/dist/plugin/otel-bridge.mjs.map +1 -0
- package/dist/plugin/predictive-batcher.cjs +61 -0
- package/dist/plugin/predictive-batcher.cjs.map +1 -0
- package/dist/plugin/predictive-batcher.mjs +58 -0
- package/dist/plugin/predictive-batcher.mjs.map +1 -0
- package/dist/plugin/webview-bridge.cjs +83 -31
- package/dist/plugin/webview-bridge.mjs +83 -31
- package/dist/stats.cjs +148 -0
- package/dist/stats.cjs.map +1 -0
- package/dist/stats.mjs +145 -0
- package/dist/stats.mjs.map +1 -0
- package/dist/types/core/env.d.ts +2 -0
- package/dist/types/core/failed-queue.d.ts +19 -2
- package/dist/types/core/idle.d.ts +23 -0
- package/dist/types/core/payload-signer.d.ts +31 -0
- package/dist/types/core/pii.d.ts +46 -0
- package/dist/types/core/platform.d.ts +23 -0
- package/dist/types/core/privacy.d.ts +42 -0
- package/dist/types/core/replay.d.ts +41 -0
- package/dist/types/core/retry-policy.d.ts +11 -8
- package/dist/types/core/send-pipeline.d.ts +5 -1
- package/dist/types/core/stats.d.ts +77 -0
- package/dist/types/core/tracker.d.ts +7 -1
- package/dist/types/core/wasm-crypto.d.ts +28 -0
- package/dist/types/edge/index.d.ts +41 -0
- package/dist/types/federation.d.ts +34 -0
- package/dist/types/index.d.ts +42 -1
- package/dist/types/plugins/audience-sync/index.d.ts +67 -0
- package/dist/types/plugins/cross-domain/index.d.ts +20 -0
- package/dist/types/plugins/csp-compliant/index.d.ts +17 -0
- package/dist/types/plugins/experiment/index.d.ts +43 -0
- package/dist/types/plugins/otel-bridge/index.d.ts +22 -0
- package/dist/types/plugins/otel-exporter/index.d.ts +50 -0
- package/dist/types/plugins/pii-detector/index.d.ts +8 -0
- package/dist/types/plugins/predictive-batcher/index.d.ts +29 -0
- package/dist/types/plugins/privacy/index.d.ts +19 -0
- package/dist/types/plugins/rate-limiter/index.d.ts +41 -0
- package/dist/types/plugins/schema-registry/index.d.ts +41 -0
- package/dist/types/plugins/webview-bridge/index.d.ts +33 -9
- package/dist/types/send/ajax-sender.d.ts +6 -1
- package/dist/types/send/batch-sender.d.ts +12 -1
- package/dist/types/send/encode.d.ts +13 -1
- package/dist/types/send/offscreen-sender.d.ts +25 -0
- package/dist/types/send/sender.d.ts +20 -3
- package/dist/types/send/ws-sender.d.ts +38 -0
- package/dist/types/types/config.d.ts +17 -1
- package/dist/types/types/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/types/types.test-d.d.ts +0 -5
- package/dist/types.test-d.ts +0 -103
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-tracker.min.js","sources":["../node_modules/tslib/tslib.es6.js","../src/core/env.ts","../src/core/uuid.ts","../src/core/logger.ts","../src/core/identity.ts","../src/types/constants.ts","../src/presets/preset-properties.ts","../src/storage/store.ts","../src/send/encode.ts","../src/send/image-sender.ts","../src/send/beacon-sender.ts","../src/core/payload-signer.ts","../src/send/ajax-sender.ts","../src/send/batch-sender.ts","../src/core/stage.ts","../src/core/lifecycle.ts","../src/core/plugin.ts","../src/core/instance-channel.ts","../src/core/retry-policy.ts","../src/core/failed-queue.ts","../src/core/errors.ts","../src/core/signed-identity.ts","../src/core/send-pipeline.ts","../src/send/sender.ts","../src/core/stats.ts","../src/core/tracker.ts","../src/core/register-api.ts","../src/core/identity-api.ts","../src/core/profile-api.ts","../src/core/track-api.ts","../src/core/platform.ts","../src/core/wasm-crypto.ts","../src/core/pii.ts","../src/core/privacy.ts","../src/core/idle.ts","../src/send/offscreen-sender.ts","../src/send/ws-sender.ts","../src/plugins/session-event/index.ts","../src/plugins/encrypt/index.ts","../src/plugins/otel-bridge/index.ts","../src/plugins/otel-exporter/index.ts","../src/plugins/experiment/index.ts","../src/plugins/predictive-batcher/index.ts","../src/plugins/schema-registry/index.ts","../src/plugins/rate-limiter/index.ts","../src/plugins/audience-sync/index.ts","../src/index.ts","../src/plugins/auto-track/index.ts","../src/core/replay.ts","../src/plugins/cross-domain/index.ts","../src/plugins/csp-compliant/index.ts","../src/plugins/debug-sender/index.ts","../src/plugins/exposure/index.ts","../src/plugins/indexeddb-sender/index.ts","../src/edge/index.ts","../src/plugins/pageleave/index.ts","../src/plugins/pageload/index.ts","../src/plugins/pii-detector/index.ts","../src/plugins/privacy/index.ts","../src/plugins/webview-bridge/index.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\r\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\r\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nvar ownKeys = function(o) {\r\n ownKeys = Object.getOwnPropertyNames || function (o) {\r\n var ar = [];\r\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\r\n return ar;\r\n };\r\n return ownKeys(o);\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose, inner;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n if (async) inner = dispose;\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n var r, s = 0;\r\n function next() {\r\n while (r = env.stack.pop()) {\r\n try {\r\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\r\n if (r.dispose) {\r\n var result = r.dispose.call(r.value);\r\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n else s |= 1;\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\r\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\r\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\r\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\r\n });\r\n }\r\n return path;\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __esDecorate: __esDecorate,\r\n __runInitializers: __runInitializers,\r\n __propKey: __propKey,\r\n __setFunctionName: __setFunctionName,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,\r\n};\r\n","/**\n * 浏览器端辅助方法\n */\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\nexport function hasLocalStorage(): boolean {\n try {\n if (!isBrowser() || !window.localStorage) return false;\n const k = '__et_test__';\n window.localStorage.setItem(k, '1');\n window.localStorage.removeItem(k);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function hasSessionStorage(): boolean {\n try {\n if (!isBrowser() || !window.sessionStorage) return false;\n const k = '__et_test__';\n window.sessionStorage.setItem(k, '1');\n window.sessionStorage.removeItem(k);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function hasCookie(): boolean {\n if (!isBrowser() || !document.cookie) return false;\n document.cookie = '__et_test__=1';\n const ok = document.cookie.indexOf('__et_test__') !== -1;\n document.cookie = '__et_test__=; expires=Thu, 01 Jan 1970 00:00:00 GMT';\n return ok;\n}\n\nexport function hasBeacon(): boolean {\n return isBrowser() && typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function';\n}\n\nexport function hasFetch(): boolean {\n return isBrowser() && typeof fetch === 'function';\n}\n\nexport function hasImage(): boolean {\n return isBrowser() && typeof Image === 'function';\n}\n\nexport function hasCompressionStream(): boolean {\n return typeof (globalThis as { CompressionStream?: unknown }).CompressionStream === 'function';\n}\n\nexport function hasBroadcastChannel(): boolean {\n return typeof (globalThis as { BroadcastChannel?: unknown }).BroadcastChannel === 'function';\n}\n","/**\n * UUID v4 生成(无依赖,使用 crypto.getRandomValues)\n */\n\nexport function uuidv4(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n const arr = new Uint8Array(16);\n crypto.getRandomValues(arr);\n // RFC 4122 v4\n arr[6] = (arr[6] & 0x0f) | 0x40;\n arr[8] = (arr[8] & 0x3f) | 0x80;\n const hex = Array.from(arr, b => b.toString(16).padStart(2, '0'));\n return (\n hex.slice(0, 4).join('') +\n '-' +\n hex.slice(4, 6).join('') +\n '-' +\n hex.slice(6, 8).join('') +\n '-' +\n hex.slice(8, 10).join('') +\n '-' +\n hex.slice(10, 16).join('')\n );\n }\n // 退化实现\n let d = Date.now();\n let d2 = (typeof performance !== 'undefined' && performance.now && performance.now() * 1000) || 0;\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n let r = Math.random() * 16;\n if (d > 0) {\n r = (d + r) % 16 | 0;\n d = Math.floor(d / 16);\n } else {\n r = (d2 + r) % 16 | 0;\n d2 = Math.floor(d2 / 16);\n }\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n}\n","/**\n * 简易 logger\n */\n\nimport type { LogLevel, TrackerConfig } from '../types/index.js';\n\nconst PREFIX = '[EventTracker]';\n\nexport class Logger {\n constructor(private config: Pick<TrackerConfig, 'debug' | 'show_log'>) {}\n\n log(...args: unknown[]): void {\n if (this.shouldLog('log', args)) this.out('log', args);\n }\n warn(...args: unknown[]): void {\n if (this.shouldLog('warn', args)) this.out('warn', args);\n }\n error(...args: unknown[]): void {\n if (this.shouldLog('error', args)) this.out('error', args);\n }\n\n private shouldLog(level: LogLevel, args: unknown[]): boolean {\n if (this.config.debug === 2) {\n if (level === 'error') throw args[0] instanceof Error ? args[0] : new Error(String(args[0]));\n return true;\n }\n if (this.config.debug === 1) {\n if (level === 'warn' || level === 'error') return true;\n }\n if (this.config.show_log && level === 'log') return true;\n return false;\n }\n\n private out(level: LogLevel, args: unknown[]): void {\n const fn = typeof console !== 'undefined' && console[level] ? console[level] : console.log;\n try {\n fn.call(console, PREFIX, ...args);\n } catch {\n /* ignore */\n }\n }\n}\n","/**\n * 用户身份管理\n * - distinct_id 业务用户 ID\n * - anonymous_id 匿名 ID(首次访问生成,永不重置)\n * - first_id 首次访问 ID\n */\n\nimport type { KVStore } from '../storage/store.js';\nimport { uuidv4 } from './uuid.js';\n\nconst KEY_DISTINCT = 'et_distinct_id';\nconst KEY_ANONYMOUS = 'et_anonymous_id';\nconst KEY_FIRST = 'et_first_id';\nconst KEY_LOGIN = 'et_login_id';\nconst KEY_ORIGINAL = 'et_original_id';\n\nexport class IdentityManager {\n private distinctId: string;\n private anonymousId: string;\n private firstId: string;\n private loginId = '';\n private originalId = '';\n\n constructor(\n private store: KVStore,\n private opts: {\n getDistinctId?: () => string;\n setDistinctId?: (id: string) => void;\n getAnonymousId?: () => string;\n setAnonymousId?: (id: string) => void;\n getFirstId?: () => string;\n setFirstId?: (id: string) => void;\n } = {},\n ) {\n this.anonymousId = this.readOrCreate(KEY_ANONYMOUS, () => uuidv4(), this.opts.getAnonymousId, this.opts.setAnonymousId);\n this.firstId = this.readOrCreate(KEY_FIRST, () => uuidv4(), this.opts.getFirstId, this.opts.setFirstId);\n this.distinctId = this.readOrCreate(KEY_DISTINCT, () => this.anonymousId, this.opts.getDistinctId, this.opts.setDistinctId);\n }\n\n private readOrCreate(\n key: string,\n factory: () => string,\n reader?: () => string,\n writer?: (id: string) => void,\n ): string {\n if (reader) {\n try {\n const v = reader();\n if (v) return v;\n } catch {\n /* fall through */\n }\n }\n const stored = this.store.get(key);\n if (stored) return stored;\n const fresh = factory();\n this.persist(key, fresh, writer);\n return fresh;\n }\n\n private persist(key: string, value: string, writer?: (id: string) => void) {\n if (writer) {\n try {\n writer(value);\n return;\n } catch {\n /* fall through */\n }\n }\n this.store.set(key, value);\n }\n\n getDistinctId(): string {\n return this.distinctId;\n }\n\n getAnonymousId(): string {\n return this.anonymousId;\n }\n\n getFirstId(): string {\n return this.firstId;\n }\n\n getLoginId(): string {\n return this.loginId;\n }\n\n getOriginalId(): string {\n return this.originalId;\n }\n\n /** 设置业务用户 ID(保留 anonymous/first 关系) */\n identify(distinctId: string, isSave = true): void {\n if (distinctId === this.loginId) return;\n const prevDistinct = this.distinctId;\n this.distinctId = distinctId;\n this.loginId = distinctId;\n this.originalId = prevDistinct;\n this.persist(KEY_DISTINCT, distinctId, this.opts.setDistinctId);\n if (isSave) {\n this.persist(KEY_LOGIN, distinctId);\n } else {\n this.store.remove(KEY_LOGIN);\n }\n this.persist(KEY_ORIGINAL, prevDistinct);\n }\n\n /** 重置:业务用户登出,回到匿名 */\n resetAnonymousIdentity(newAnonymousId?: string): void {\n this.distinctId = newAnonymousId || this.anonymousId;\n this.loginId = '';\n this.originalId = '';\n this.persist(KEY_DISTINCT, this.distinctId, this.opts.setDistinctId);\n this.store.remove(KEY_LOGIN);\n this.store.remove(KEY_ORIGINAL);\n if (newAnonymousId) {\n this.anonymousId = newAnonymousId;\n this.persist(KEY_ANONYMOUS, newAnonymousId, this.opts.setAnonymousId);\n }\n }\n\n /** 登入:等价 identify */\n login(loginId: string): void {\n this.identify(loginId, true);\n }\n\n /** 登出:保留 anonymous,重置 distinct */\n logout(): void {\n this.resetAnonymousIdentity();\n }\n}\n","/**\n * SDK 预置事件名与预置属性 key(v1.1:完整对齐神策)\n * 命名风格对齐神策,方便跨平台对接\n */\n\n/** 预置事件名 */\nexport const PresetEvent = {\n PageView: '$pageview',\n WebPageLoad: '$WebPageLoad',\n WebPageLeave: '$WebPageLeave',\n WebClick: '$WebClick',\n WebStay: '$WebStay',\n SignUp: '$SignUp',\n BindID: '$BindID',\n UnbindID: '$UnbindID',\n ABTestTrigger: '$ABTestTrigger',\n PlanPopupClick: '$PlanPopupClick',\n PlanPopupDisplay: '$PlanPopupDisplay',\n ChannelLinkReaching: '$ChannelLinkReaching',\n ElementExposure: '$element_exposure',\n ScrollDepth: '$scrolldepth',\n ExitClick: '$exit_click',\n PageLeave: '$page_leave',\n HeatmapEvent: '$heatmap_event',\n} as const;\n\nexport type PresetEventName = (typeof PresetEvent)[keyof typeof PresetEvent];\n\n/** 预置属性 key */\nexport const PresetProperty = {\n // 设备 / 环境\n AppId: '$app_id',\n AppVersion: '$app_version',\n Lib: '$lib',\n LibMethod: '$lib_method',\n LibDetail: '$lib_detail',\n LibVersion: '$lib_version',\n ScreenWidth: '$screen_width',\n ScreenHeight: '$screen_height',\n ViewportWidth: '$viewport_width',\n ViewportHeight: '$viewport_height',\n TimezoneOffset: '$timezone_offset',\n UserAgent: '$user_agent',\n Language: '$language',\n FirstBrowserCharset: '$first_browser_charset',\n FirstBrowserLanguage: '$first_browser_language',\n\n // 位置 / 流量来源\n URL: '$url',\n URLPath: '$url_path',\n Title: '$title',\n Referrer: '$referrer',\n ReferrerHost: '$referrer_host',\n LatestReferrer: '$latest_referrer',\n LatestReferrerHost: '$latest_referrer_host',\n LatestLandingPage: '$latest_landing_page',\n LatestSearchKeyword: '$latest_search_keyword',\n LatestTrafficSourceType: '$latest_traffic_source_type',\n FirstReferrer: '$first_referrer',\n FirstReferrerHost: '$first_referrer_host',\n FirstSearchKeyword: '$first_search_keyword',\n FirstTrafficSourceType: '$first_traffic_source_type',\n FirstVisitTime: '$first_visit_time',\n SearchKeywordId: '$search_keyword_id',\n SearchKeywordIdHash: '$search_keyword_id_hash',\n SearchKeywordIdType: '$search_keyword_id_type',\n IsFirstDay: '$is_first_day',\n IsFirstTime: '$is_first_time',\n\n // UTM\n LatestUtmSource: '$latest_utm_source',\n LatestUtmMedium: '$latest_utm_medium',\n LatestUtmCampaign: '$latest_utm_campaign',\n LatestUtmContent: '$latest_utm_content',\n LatestUtmTerm: '$latest_utm_term',\n Utms: '$utms',\n\n // 身份\n DistinctId: '$distinct_id',\n AnonymousId: '$anonymous_id',\n FirstId: '$first_id',\n OriginalId: '$original_id',\n LoginId: '$login_id',\n IsLoginId: '$is_login_id',\n IdentityLoginId: '$identity_login_id',\n IdentityAnonymousId: '$identity_anonymous_id',\n IdentityCookieId: '$identity_cookie_id',\n IdentityEmail: '$identity_email',\n IdentityMobile: '$identity_mobile',\n\n // 全埋点元素属性\n ElementSelector: '$element_selector',\n ElementPath: '$element_path',\n ElementType: '$element_type',\n ElementId: '$element_id',\n ElementClassName: '$element_class_name',\n ElementName: '$element_name',\n ElementContent: '$element_content',\n ElementTargetUrl: '$element_target_url',\n ElementPosition: '$element_position',\n PageX: '$page_x',\n PageY: '$page_y',\n\n // 性能\n PageHeight: '$page_height',\n PageResourceSize: '$page_resource_size',\n EventDuration: '$event_duration',\n ViewportPosition: '$viewport_position',\n\n // 渠道\n LatestWxAdClickId: '$latest_wx_ad_click_id',\n LatestWxAdCallbacks: '$latest_wx_ad_callbacks',\n LatestWxAdHashKey: '$latest_wx_ad_hash_key',\n IsChannelCallbackEvent: '$is_channel_callback_event',\n\n // 会话\n EventSessionId: '$event_session_id',\n\n // 元信息\n Time: '$time',\n Event: '$event',\n Option: '$option',\n Project: '$project',\n Token: '$token',\n\n // 特殊\n SignupMethod: '$signup_method',\n} as const;\n\nexport type PresetPropertyKey = (typeof PresetProperty)[keyof typeof PresetProperty];\n\n/** 库自身信息 */\nexport const LIB_NAME = 'event-tracker';\nexport const LIB_VERSION = '1.1.0';\n","/**\n * 公共属性 / 预置事件属性\n * - 每次事件都会附加的属性\n * - 包括 $lib / $lib_version / $app_id / $screen_width / $viewport_width / $url / $referrer / $latest_utm_* / ...\n *\n * 泛型 TRegisterProps:让用户能约束 register() / preset 的字段类型\n */\n\nimport { isBrowser } from '../core/env.js';\nimport { PresetProperty } from '../types/constants.js';\nimport type { TrackerConfig } from '../types/index.js';\n\n/** 默认 register 类型 */\nexport type DefaultRegisterProps = Record<string, unknown>;\n\nexport class PresetPropertyBuilder<TRegister extends DefaultRegisterProps = DefaultRegisterProps> {\n /** 当前会话级用户预设属性(来自 config.preset_properties) */\n private preset: Partial<TRegister> = {} as Partial<TRegister>;\n\n setPreset(props: Partial<TRegister>): void {\n this.preset = { ...props };\n }\n\n /** 一次性写入:每条事件都带 */\n register(props: Partial<TRegister>): void {\n Object.assign(this.preset, props);\n }\n\n /** 一次性写入:只在同会话内首次写入生效 */\n registerOnce(props: Partial<TRegister>): void {\n for (const k of Object.keys(props) as (keyof TRegister)[]) {\n if (!(k in this.preset)) {\n this.preset[k] = props[k];\n }\n }\n }\n\n clearRegister(): void {\n this.preset = {};\n }\n\n unsetRegister<K extends keyof TRegister>(key: K): void {\n if (Object.prototype.hasOwnProperty.call(this.preset, key)) {\n delete this.preset[key];\n }\n }\n\n getPreset(): Partial<TRegister> {\n return { ...this.preset };\n }\n\n /** 计算一次最终合并的属性(含 lib 自身信息、UA、URL 等) */\n build(config: TrackerConfig, baseProps: Record<string, unknown> = {}): Record<string, unknown> {\n const out: Record<string, unknown> = {\n ...this.preset,\n ...baseProps,\n };\n\n out[PresetProperty.Lib] = config.lib_name || 'event-tracker';\n out[PresetProperty.LibVersion] = config.lib_version || '0.1.0';\n if (config.app_id) out[PresetProperty.AppId] = config.app_id;\n if (config.app_version) out[PresetProperty.AppVersion] = config.app_version;\n\n if (isBrowser()) {\n try {\n out[PresetProperty.URL] = location.href;\n out[PresetProperty.URLPath] = location.pathname;\n out[PresetProperty.Title] = document.title;\n if (document.referrer) {\n out[PresetProperty.Referrer] = document.referrer;\n }\n const sw = (window.screen && (window.screen as Screen).width) || 0;\n const sh = (window.screen && (window.screen as Screen).height) || 0;\n if (sw) out[PresetProperty.ScreenWidth] = sw;\n if (sh) out[PresetProperty.ScreenHeight] = sh;\n const vw = window.innerWidth || (document.documentElement && document.documentElement.clientWidth) || 0;\n const vh = window.innerHeight || (document.documentElement && document.documentElement.clientHeight) || 0;\n if (vw) out[PresetProperty.ViewportWidth] = vw;\n if (vh) out[PresetProperty.ViewportHeight] = vh;\n if (navigator) {\n out[PresetProperty.Language] = (navigator as Navigator).language || '';\n out[PresetProperty.UserAgent] = config.user_agent || (navigator as Navigator).userAgent || '';\n out[PresetProperty.TimezoneOffset] = new Date().getTimezoneOffset();\n }\n } catch {\n /* ignore in non-browser */\n }\n }\n\n // utm 参数\n if (isBrowser() && config.is_collect_utm !== false) {\n const utm = parseUtm(location.search);\n for (const [k, v] of Object.entries(utm)) {\n const propKey = PresetProperty.LatestUtmSource.replace('Source', capitalize(k.replace('utm_', '')));\n out[propKey] = v;\n }\n out[PresetProperty.LatestTrafficSourceType] = out[PresetProperty.LatestUtmSource] ? '付费广告流量' : '直接流量';\n }\n\n return out;\n }\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport function parseUtm(query: string): Record<string, string> {\n const out: Record<string, string> = {};\n if (!query) return out;\n const s = query.startsWith('?') ? query.substring(1) : query;\n const parts = s.split('&');\n for (const p of parts) {\n const eq = p.indexOf('=');\n if (eq === -1) continue;\n const k = decodeURIComponent(p.substring(0, eq));\n const v = decodeURIComponent(p.substring(eq + 1));\n if (k.startsWith('utm_')) out[k] = v;\n }\n return out;\n}\n","/**\n * 统一 KV 存储抽象\n * - CookieStore\n * - LocalStorageStore\n * - SessionStorageStore\n * - MemoryStore\n */\n\nimport { hasCookie, hasLocalStorage, hasSessionStorage } from '../core/env.js';\nimport type { StorageType } from '../types/index.js';\n\nexport interface KVStore {\n get(key: string): string | null;\n set(key: string, value: string, expiresDays?: number): void;\n remove(key: string): void;\n /** 当前所有 key(用于清除命名空间) */\n keys(prefix?: string): string[];\n}\n\nexport class MemoryStore implements KVStore {\n private backing: Map<string, string> = new Map();\n get(key: string): string | null {\n return this.backing.has(key) ? this.backing.get(key)! : null;\n }\n set(key: string, value: string): void {\n this.backing.set(key, value);\n }\n remove(key: string): void {\n this.backing.delete(key);\n }\n keys(prefix = ''): string[] {\n return Array.from(this.backing.keys()).filter(k => k.startsWith(prefix));\n }\n}\n\nclass CookieStore implements KVStore {\n constructor(\n private domain?: string,\n private crossSubdomain = true,\n private secure = false,\n ) {}\n get(key: string): string | null {\n const name = encodeURIComponent(key) + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1);\n if (c.indexOf(name) === 0) {\n return decodeURIComponent(c.substring(name.length, c.length));\n }\n }\n return null;\n }\n set(key: string, value: string, expiresDays = 365): void {\n let expires = '';\n if (expiresDays) {\n const date = new Date();\n date.setTime(date.getTime() + expiresDays * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n let cookie = encodeURIComponent(key) + '=' + encodeURIComponent(value) + expires + '; path=/';\n if (this.domain && this.crossSubdomain) {\n cookie += '; domain=' + this.domain;\n }\n if (this.secure) cookie += '; Secure';\n document.cookie = cookie;\n }\n remove(key: string): void {\n this.set(key, '', -1);\n }\n keys(prefix = ''): string[] {\n return document.cookie.split(';').map(c => {\n const eq = c.indexOf('=');\n return decodeURIComponent((eq > -1 ? c.substring(0, eq) : c).trim());\n }).filter(k => k.startsWith(prefix));\n }\n}\n\nclass LocalStorageStore implements KVStore {\n get(key: string): string | null {\n try {\n return window.localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n set(key: string, value: string): void {\n try {\n window.localStorage.setItem(key, value);\n } catch {\n /* quota exceeded, ignore */\n }\n }\n remove(key: string): void {\n try {\n window.localStorage.removeItem(key);\n } catch {\n /* ignore */\n }\n }\n keys(prefix = ''): string[] {\n const out: string[] = [];\n try {\n for (let i = 0; i < window.localStorage.length; i++) {\n const k = window.localStorage.key(i);\n if (k && k.startsWith(prefix)) out.push(k);\n }\n } catch {\n /* ignore */\n }\n return out;\n }\n}\n\nclass SessionStorageStore implements KVStore {\n get(key: string): string | null {\n try {\n return window.sessionStorage.getItem(key);\n } catch {\n return null;\n }\n }\n set(key: string, value: string): void {\n try {\n window.sessionStorage.setItem(key, value);\n } catch {\n /* ignore */\n }\n }\n remove(key: string): void {\n try {\n window.sessionStorage.removeItem(key);\n } catch {\n /* ignore */\n }\n }\n keys(prefix = ''): string[] {\n const out: string[] = [];\n try {\n for (let i = 0; i < window.sessionStorage.length; i++) {\n const k = window.sessionStorage.key(i);\n if (k && k.startsWith(prefix)) out.push(k);\n }\n } catch {\n /* ignore */\n }\n return out;\n }\n}\n\nexport function createStore(\n type: StorageType,\n opts?: { cookieDomain?: string; cookieCrossSubdomain?: boolean; secureCookie?: boolean },\n): KVStore {\n switch (type) {\n case 'cookie':\n return new CookieStore(opts?.cookieDomain, opts?.cookieCrossSubdomain, opts?.secureCookie);\n case 'localStorage':\n return hasLocalStorage() ? new LocalStorageStore() : new MemoryStore();\n case 'sessionStorage':\n return hasSessionStorage() ? new SessionStorageStore() : new MemoryStore();\n case 'memory':\n default:\n return new MemoryStore();\n }\n}\n\n/** 自动选最合适的存储(cookie 不可用 → localStorage → memory) */\nexport function autoStore(opts?: {\n cookieDomain?: string;\n cookieCrossSubdomain?: boolean;\n secureCookie?: boolean;\n}): KVStore {\n if (hasCookie()) return new CookieStore(opts?.cookieDomain, opts?.cookieCrossSubdomain, opts?.secureCookie);\n if (hasLocalStorage()) return new LocalStorageStore();\n return new MemoryStore();\n}\n\nexport { CookieStore, LocalStorageStore, SessionStorageStore };\n","/**\n * 序列化 & 编码(v1.2.0 性能优化)\n *\n * - TextEncoder / URLSearchParams 单例\n * - payload cache(同一 event 短时间内不重复编码)\n * - 提供 base64url safe encode\n */\n\nimport type { EventData } from '../types/index.js';\n\nexport type EncryptFn = (data: string) => string | Promise<string>;\n\n// ============================================================\n// 单例 TextEncoder / TextDecoder\n// ============================================================\nlet _encoder: TextEncoder | null = null;\nlet _decoder: TextDecoder | null = null;\nexport function getTextEncoder(): TextEncoder {\n if (!_encoder) _encoder = new TextEncoder();\n return _encoder;\n}\nexport function getTextDecoder(): TextDecoder {\n if (!_decoder) _decoder = new TextDecoder();\n return _decoder;\n}\n\n// ============================================================\n// Payload 短缓存:相同 event 在 TTL 期内复用编码结果\n// ============================================================\nconst PAYLOAD_CACHE_TTL = 500; // ms\nconst PAYLOAD_CACHE_MAX = 64;\ninterface CacheEntry {\n ts: number;\n data: string;\n}\nconst payloadCache = new Map<string, CacheEntry>();\n\nfunction cacheKey(json: string): string {\n // 简单 hash:长度 + 前 64 字符 + 末 64 字符\n const n = json.length;\n if (n <= 128) return json;\n return `${n}|${json.slice(0, 64)}|${json.slice(-64)}`;\n}\n\nfunction cacheGet(key: string): string | undefined {\n const e = payloadCache.get(key);\n if (!e) return undefined;\n if (Date.now() - e.ts > PAYLOAD_CACHE_TTL) {\n payloadCache.delete(key);\n return undefined;\n }\n // LRU bump\n payloadCache.delete(key);\n payloadCache.set(key, e);\n return e.data;\n}\n\nfunction cacheSet(key: string, data: string): void {\n if (payloadCache.size >= PAYLOAD_CACHE_MAX) {\n // 删最旧\n const first = payloadCache.keys().next().value;\n if (first !== undefined) payloadCache.delete(first);\n }\n payloadCache.set(key, { ts: Date.now(), data });\n}\n\nexport function encodeEvent(event: EventData, encryptor?: EncryptFn): string | Promise<string> {\n const json = JSON.stringify(event);\n const k = cacheKey(json);\n if (!encryptor) {\n const cached = cacheGet(k);\n if (cached !== undefined) return cached;\n cacheSet(k, json);\n return json;\n }\n // 加密时直接返回(不可缓存)\n return encryptor(json);\n}\n\nexport function encodeBatch(events: EventData[], encryptor?: EncryptFn): string | Promise<string> {\n const json = JSON.stringify(events);\n const k = cacheKey(json);\n if (!encryptor) {\n const cached = cacheGet(k);\n if (cached !== undefined) return cached;\n cacheSet(k, json);\n return json;\n }\n return encryptor(json);\n}\n\nexport function buildUrl(serverUrl: string | string[], payload: string, contentType: 'json' | 'form' = 'form'): string {\n const base = Array.isArray(serverUrl) ? serverUrl[0] || '' : serverUrl;\n const has = base.indexOf('?') >= 0;\n if (contentType === 'form') {\n return `${base}${has ? '&' : '?'}data=${encodeURIComponent(payload)}`;\n }\n return `${base}${has ? '&' : '?'}data=${encodeURIComponent(payload)}`;\n}\n\n// ============================================================\n// 工具:bytes ↔ string(用单例 TextEncoder)\n// ============================================================\nexport function strToBytes(s: string): Uint8Array {\n return getTextEncoder().encode(s);\n}\n\nexport function bytesToStr(b: Uint8Array): string {\n return getTextDecoder().decode(b);\n}\n\n// ============================================================\n// 工具:base64url(用于 sendBeacon/POST 二进制)\n// ============================================================\nexport function toBase64Url(bytes: Uint8Array): string {\n let s = '';\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\n return btoa(s).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '');\n}\n\n// ============================================================\n// 工具:清空 payload 缓存(debug / 测试用)\n// ============================================================\nexport function _clearPayloadCache(): void {\n payloadCache.clear();\n}\n\n// ============================================================\n// decodeEvent 缓存:相同 JSON 短时间内不重复 JSON.parse\n// ============================================================\nconst DECODE_CACHE_TTL = 500;\nconst DECODE_CACHE_MAX = 64;\nconst decodeCache = new Map<string, { ts: number; data: unknown }>();\n\nfunction decodeGet(key: string): unknown | undefined {\n const e = decodeCache.get(key);\n if (!e) return undefined;\n if (Date.now() - e.ts > DECODE_CACHE_TTL) {\n decodeCache.delete(key);\n return undefined;\n }\n decodeCache.delete(key);\n decodeCache.set(key, e);\n return e.data;\n}\n\nfunction decodeSet(key: string, data: unknown): void {\n if (decodeCache.size >= DECODE_CACHE_MAX) {\n const first = decodeCache.keys().next().value;\n if (first !== undefined) decodeCache.delete(first);\n }\n decodeCache.set(key, { ts: Date.now(), data });\n}\n\n/** 反序列化(带缓存) */\nexport function decodeEvent<T = unknown>(json: string): T {\n const k = cacheKey(json);\n const cached = decodeGet(k);\n if (cached !== undefined) return cached as T;\n try {\n const data = JSON.parse(json) as T;\n decodeSet(k, data);\n return data;\n } catch {\n // 缓存负缓存\n decodeSet(k, null);\n return null as T;\n }\n}","/**\n * Image 发送器(1x1 gif 兜底,兼容性最好)\n */\n\nimport { hasImage } from '../core/env.js';\nimport { encodeEvent, buildUrl } from './encode.js';\nimport type { SendContext, Sender } from './sender.js';\nimport type { EventData } from '../types/index.js';\n\n/**\n * 间接构造 Image(避免编译期绑定到 module-local Image)\n * 测试可以通过覆盖 globalThis.Image 来 spy\n */\nfunction makeImage(): HTMLImageElement | { src: string; onload?: () => void; onerror?: () => void; onabort?: () => void } {\n // 用 eval 避免编译器静态解析 Image 标识符\n // eslint-disable-next-line no-eval\n const g: { Image?: new () => HTMLImageElement } = (0, eval)('this') || globalThis;\n const Ctor = g.Image;\n if (typeof Ctor === 'function') return new Ctor();\n return { src: '', onload: undefined, onerror: undefined, onabort: undefined };\n}\n\nexport class ImageSender implements Sender {\n name = 'image' as const;\n\n canUse(): boolean {\n return hasImage();\n }\n\n async send(event: EventData, ctx: SendContext): Promise<void> {\n try {\n const payload = await Promise.resolve(encodeEvent(event, ctx.config.encryptor));\n const url = buildUrl(ctx.config.server_url || '', payload, 'form');\n await new Promise<void>((resolve) => {\n const img = makeImage() as {\n src: string;\n onload?: () => void;\n onerror?: () => void;\n onabort?: () => void;\n };\n const done = () => resolve();\n img.onload = done;\n img.onerror = done;\n img.onabort = done;\n img.src = url;\n setTimeout(done, 3000);\n });\n } catch (e) {\n ctx.logger.error('ImageSender failed:', e);\n }\n }\n}","/**\n * Beacon 发送器(navigator.sendBeacon)\n */\n\nimport { hasBeacon } from '../core/env.js';\nimport { encodeEvent, buildUrl } from './encode.js';\nimport type { SendContext, Sender } from './sender.js';\nimport type { EventData } from '../types/index.js';\n\nexport class BeaconSender implements Sender {\n name = 'beacon' as const;\n\n canUse(): boolean {\n return hasBeacon();\n }\n\n async send(event: EventData, ctx: SendContext): Promise<void> {\n try {\n const payload = await Promise.resolve(encodeEvent(event, ctx.config.encryptor));\n const url = buildUrl(ctx.config.server_url || '', payload, 'form');\n const blob = new Blob([payload], { type: 'application/x-www-form-urlencoded' });\n const ok = navigator.sendBeacon(url, blob);\n if (!ok) {\n ctx.logger.warn('BeaconSender returned false, URL:', url.slice(0, 80));\n }\n } catch (e) {\n ctx.logger.error('BeaconSender failed:', e);\n }\n }\n}","/**\n * Payload 完整性签名(v1.3.0)\n *\n * - 用 identity_secret 对 payload 做 HMAC-SHA256\n * - 通过 X-Payload-Sig 头传到服务端\n * - 服务端用同一 secret 校验\n * - 支持异步签名(Web Crypto)\n */\n\nexport interface SignOptions {\n secret: string;\n /** salt(可选,时间戳 / distinct_id 拼接) */\n salt?: string;\n}\n\nconst encoder = new TextEncoder();\n\n/** 把字符串 secret 转 Uint8Array */\nfunction secretToKey(secret: string): Uint8Array {\n // 简单:UTF-8 编码;也可以 HKDF,但 secret 通常够长\n return encoder.encode(secret);\n}\n\n/** 异步 HMAC-SHA256 */\nexport async function hmacSign(payload: string, opts: SignOptions): Promise<string> {\n const keyData = secretToKey(opts.salt ? `${opts.secret}:${opts.salt}` : opts.secret);\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n keyData as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const sig = await crypto.subtle.sign('HMAC', cryptoKey, encoder.encode(payload) as BufferSource);\n // 转 base64url\n const bytes = new Uint8Array(sig);\n let s = '';\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\n return btoa(s).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '');\n}\n\n/** 同步 fallback(仅 Node crypto 环境) */\nexport function hmacSignSync(payload: string, opts: SignOptions): string {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const nodeCrypto = (globalThis as { process?: { versions?: { node?: string } } }).process?.versions?.node\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n ? require('crypto')\n : null;\n if (!nodeCrypto) {\n throw new Error('hmacSignSync only available in Node');\n }\n const hmac = nodeCrypto.createHmac('sha256', opts.salt ? `${opts.secret}:${opts.salt}` : opts.secret);\n hmac.update(payload);\n return hmac.digest('base64url');\n}\n\n/** 验证签名 */\nexport async function hmacVerify(\n payload: string,\n signature: string,\n opts: SignOptions,\n): Promise<boolean> {\n const expected = await hmacSign(payload, opts);\n return constantTimeEqual(expected, signature);\n}\n\nfunction constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let r = 0;\n for (let i = 0; i < a.length; i++) r |= a.charCodeAt(i) ^ b.charCodeAt(i);\n return r === 0;\n}\n\n/**\n * 在 SendContext 上挂载签名 + 自动给 AJAX 请求加 X-Payload-Sig\n */\nexport interface SignedContext {\n config: { identity_secret?: string };\n logger?: { warn: (msg: string, e?: unknown) => void };\n}\n\nexport async function signPayload(\n payload: string,\n ctx: SignedContext,\n distinctId?: string,\n): Promise<string | null> {\n const secret = ctx.config.identity_secret;\n if (!secret) return null;\n try {\n return await hmacSign(payload, { secret, salt: distinctId });\n } catch (e) {\n ctx.logger?.warn?.('signPayload failed:', e);\n return null;\n }\n}","/**\n * Ajax 发送器(fetch + keepalive + gzip)\n *\n * - 支持 gzip(v1.2.0 #6):通过 CompressionStream('gzip')\n * - keepalive: true 支持 unload 后继续发送\n * - Content-Encoding: gzip 用于告诉服务端解码\n */\n\nimport { hasFetch, hasCompressionStream } from '../core/env.js';\nimport { encodeEvent, encodeBatch, strToBytes, toBase64Url } from './encode.js';\nimport type { SendContext, Sender } from './sender.js';\nimport type { EventData } from '../types/index.js';\nimport { signPayload } from '../core/payload-signer.js';\n\ninterface SendConfigBatchExt {\n gzip?: boolean;\n}\n\n/**\n * 可选:把字符串压缩为 gzip Uint8Array\n * 不支持时返回 null(fallback 到原始字符串)\n */\nasync function maybeGzip(\n text: string,\n enabled: boolean,\n): Promise<{ body: BodyInit; headers: Record<string, string> } | null> {\n if (!enabled || !hasCompressionStream()) return null;\n try {\n const stream = new (globalThis as { CompressionStream?: typeof CompressionStream }).CompressionStream('gzip');\n const writer = stream.writable.getWriter();\n await writer.write(strToBytes(text) as unknown as BufferSource);\n await writer.close();\n const reader = stream.readable.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n // 循环读\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(value);\n total += value.byteLength;\n }\n }\n const merged = new Uint8Array(total);\n let off = 0;\n for (const c of chunks) {\n merged.set(c, off);\n off += c.byteLength;\n }\n // 用 base64url 作为 binary safe 形式(服务端需配套解码)\n return {\n body: toBase64Url(merged),\n headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Content-Encoding': 'gzip' },\n };\n } catch {\n return null;\n }\n}\n\nexport class AjaxSender implements Sender {\n name = 'ajax' as const;\n\n canUse(): boolean {\n return hasFetch();\n }\n\n private getGzipEnabled(ctx: SendContext): boolean {\n return Boolean((ctx.config.batch_send as SendConfigBatchExt | undefined)?.gzip);\n }\n\n async send(event: EventData, ctx: SendContext): Promise<void> {\n try {\n const payload = await Promise.resolve(encodeEvent(event, ctx.config.encryptor));\n const url = Array.isArray(ctx.config.server_url) ? ctx.config.server_url[0] : ctx.config.server_url;\n const gz = await maybeGzip(payload, this.getGzipEnabled(ctx));\n let body: BodyInit;\n let headers: Record<string, string>;\n if (gz) {\n body = `data=${gz.body}`;\n headers = gz.headers;\n } else {\n body = `data=${encodeURIComponent(payload)}`;\n headers = { 'Content-Type': 'application/x-www-form-urlencoded' };\n }\n // 签名\n const sig = await signPayload(payload, ctx, event.distinct_id);\n if (sig) headers['X-Payload-Sig'] = sig;\n const res = await fetch(url, {\n method: 'POST',\n mode: 'cors',\n credentials: 'omit',\n headers,\n body,\n keepalive: true,\n });\n if (!res.ok) {\n ctx.logger.warn('AjaxSender non-2xx:', res.status);\n ctx.config.on_error?.(new Error(`HTTP ${res.status}`), event);\n } else {\n ctx.config.callback?.(event);\n }\n } catch (e) {\n ctx.logger.error('AjaxSender failed:', e);\n ctx.config.on_error?.(e as Error, event);\n }\n }\n\n async sendBatch(events: EventData[], ctx: SendContext): Promise<void> {\n try {\n const payload = await Promise.resolve(encodeBatch(events, ctx.config.encryptor));\n const url = Array.isArray(ctx.config.server_url) ? ctx.config.server_url[0] : ctx.config.server_url;\n const gz = await maybeGzip(payload, this.getGzipEnabled(ctx));\n let body: BodyInit;\n let headers: Record<string, string>;\n if (gz) {\n body = `data=${gz.body}&batch=1`;\n headers = gz.headers;\n } else {\n body = `data=${encodeURIComponent(payload)}&batch=1`;\n headers = { 'Content-Type': 'application/x-www-form-urlencoded' };\n }\n const sig = await signPayload(payload, ctx, events[0]?.distinct_id);\n if (sig) headers['X-Payload-Sig'] = sig;\n await fetch(url, {\n method: 'POST',\n mode: 'cors',\n credentials: 'omit',\n headers,\n body,\n keepalive: true,\n });\n } catch (e) {\n ctx.logger.error('AjaxSender.sendBatch failed:', e);\n }\n }\n}","/**\n * Batch 发送器:事件先入队到 localStorage,链式 setTimeout 调度\n *\n * - 不使用 setInterval,改为每次 flush 完后再排下一次(chain)\n * - 队列满 / 显式 flush 时立即发送\n * - 支持 gzip(v1.2.0 #6)+ CompressionStream\n * - 链式调度避免 setInterval 在页面隐藏时仍在跑\n */\n\nimport { encodeBatch } from './encode.js';\nimport type { SendContext, Sender } from './sender.js';\nimport type { EventData, TrackerConfig } from '../types/index.js';\nimport { BeaconSender } from './beacon-sender.js';\n\nconst QUEUE_KEY = 'et_batch_queue';\nconst DEFAULT_MAX = 50;\nconst DEFAULT_INTERVAL = 6000;\n\nexport class BatchSender implements Sender {\n name = 'batch' as const;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private running = false;\n private ctx?: SendContext;\n\n canUse(): boolean {\n return typeof window !== 'undefined' && !!window.localStorage;\n }\n\n start(ctx: SendContext): void {\n if (!this.canUse()) return;\n this.ctx = ctx;\n this.scheduleNext();\n }\n\n stop(): void {\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n this.ctx = undefined;\n }\n\n async send(event: EventData, ctx: SendContext): Promise<void> {\n this.enqueue(event, ctx.config);\n const max = (typeof ctx.config.batch_send === 'object' && ctx.config.batch_send?.max_length) || DEFAULT_MAX;\n const queue = this.read(ctx.config);\n if (queue.length >= max) {\n await this.flush(ctx);\n } else {\n // 入队后顺便排个调度\n this.scheduleNext();\n }\n }\n\n /** 链式调度:flush 完后再排下一次 */\n private scheduleNext(): void {\n if (this.timer || !this.ctx) return;\n const bs = this.ctx.config.batch_send;\n const predict = (this.ctx.config as unknown as { batch_send_predict?: () => number }).batch_send_predict;\n const interval = predict\n ? predict()\n : (typeof bs === 'object' && bs?.send_interval) || this.ctx.config.datasend_timeout || DEFAULT_INTERVAL;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush(this.ctx!).then(() => this.scheduleNext());\n }, interval);\n }\n\n /** 窥探当前队列长度(pipeline.flush 用于 onFlush 计数) */\n peekQueueSize(): number {\n if (!this.ctx) return 0;\n return this.read(this.ctx.config).length;\n }\n\n private enqueue(event: EventData, config: TrackerConfig): void {\n const q = this.read(config);\n q.push(event);\n this.write(q, config);\n }\n\n private read(config: TrackerConfig): EventData[] {\n try {\n const raw = window.localStorage.getItem(QUEUE_KEY);\n if (!raw) return [];\n const arr = JSON.parse(raw);\n return Array.isArray(arr) ? arr : [];\n } catch {\n return [];\n }\n }\n\n private write(queue: EventData[], config: TrackerConfig): void {\n try {\n const payload = encodeBatch(queue, config.encryptor);\n // 异步时(Promise<string>)暂存 JSON 原文\n const str = typeof payload === 'string' ? payload : JSON.stringify(queue);\n window.localStorage.setItem(QUEUE_KEY, str);\n } catch {\n // quota exceed, drop oldest half\n const half = queue.slice(Math.floor(queue.length / 2));\n try {\n const payload2 = encodeBatch(half, config.encryptor);\n const str2 = typeof payload2 === 'string' ? payload2 : JSON.stringify(half);\n window.localStorage.setItem(QUEUE_KEY, str2);\n } catch {\n /* ignore */\n }\n }\n }\n\n async flush(ctx: SendContext): Promise<void> {\n if (this.running) return;\n this.running = true;\n try {\n const queue = this.read(ctx.config);\n if (!queue.length) return;\n // 清空队列\n try {\n window.localStorage.removeItem(QUEUE_KEY);\n } catch {\n /* ignore */\n }\n // 走 ajax 批量(gzip 支持)\n const ajax = new (await import('./ajax-sender.js')).AjaxSender();\n if (ajax.canUse()) {\n await ajax.sendBatch!(queue, ctx);\n } else {\n // 降级为逐条 beacon\n const beacon = new BeaconSender();\n for (const ev of queue) {\n await beacon.send(ev, ctx);\n }\n }\n } finally {\n this.running = false;\n }\n }\n}","/**\n * 事件数据拦截 Stage\n * - 3 个 Stage: buildDataStage / businessStage / sendDataStage\n * - 按 priority 升序执行\n * - cancellationToken 可中断后续\n *\n * 灵感来自神策 sa-sdk-javascript 内部实现\n */\n\nexport type StageName = 'buildDataStage' | 'businessStage' | 'sendDataStage';\n\nexport interface StageContext<T> {\n data: T;\n /** 阶段元信息 */\n meta: {\n stage: StageName;\n [key: string]: unknown;\n };\n /** 取消令牌:调 stop() 后后续 interceptor 跳过 */\n cancellationToken: { stop: () => void };\n /** SDK 引用,供 interceptor 使用 */\n owner?: unknown;\n}\n\nexport interface StageInterceptor<T> {\n /** 唯一名(同名注册会覆盖) */\n name: string;\n /** 数字越小越先执行,默认 100 */\n priority?: number;\n /** 拦截处理,返回新数据或直接改 ctx.data */\n entry: (ctx: StageContext<T>) => T | void;\n}\n\nexport class StageChain<T = unknown> {\n private list: Array<{ priority: number; spec: StageInterceptor<T> }> = [];\n private stopped = false;\n private stopFlag = false;\n\n constructor(private stage: StageName) {}\n\n /** 注册一个拦截器(同名覆盖) */\n register(spec: StageInterceptor<T>): void {\n this.unregister(spec.name);\n this.list.push({ priority: spec.priority ?? 100, spec });\n this.list.sort((a, b) => a.priority - b.priority);\n }\n\n /** 移除一个拦截器 */\n unregister(name: string): void {\n this.list = this.list.filter(item => item.spec.name !== name);\n }\n\n /** 获取所有拦截器名(调试用) */\n list2(): string[] {\n return this.list.map(i => `${i.spec.name}@${i.priority}`);\n }\n\n /** 重置 stage(含清除停止标志) */\n reset(): void {\n this.stopFlag = false;\n }\n\n /** 主入口:顺序执行 */\n run(input: T, owner?: unknown): T {\n this.stopFlag = false;\n const ctx: StageContext<T> = {\n data: input,\n meta: { stage: this.stage },\n cancellationToken: {\n stop: () => { this.stopFlag = true; },\n },\n owner,\n };\n for (const { spec } of this.list) {\n if (this.stopFlag) break;\n const out = spec.entry(ctx);\n if (out !== undefined) {\n ctx.data = out as T;\n }\n }\n return ctx.data;\n }\n}\n","/**\n * 7 个生命周期钩子\n * - sdkReady SDK 加载完成,init 之前\n * - sdkInitPara init 处理参数时(合并前)\n * - sdkAfterInitPara init 处理参数后\n * - sdkInitAPI API 挂到 window 之前\n * - sdkAfterInitAPI API 挂到 window 之后\n * - changeDistinctId distinct 变化时\n * - switch 配置切换(多实例)\n */\n\nexport type HookName =\n | 'sdkReady'\n | 'sdkInitPara'\n | 'sdkAfterInitPara'\n | 'sdkInitAPI'\n | 'sdkAfterInitAPI'\n | 'changeDistinctId'\n | 'switch';\n\nexport const ALL_HOOKS: readonly HookName[] = [\n 'sdkReady',\n 'sdkInitPara',\n 'sdkAfterInitPara',\n 'sdkInitAPI',\n 'sdkAfterInitAPI',\n 'changeDistinctId',\n 'switch',\n] as const;\n\nexport type HookFn = (...args: unknown[]) => void | Promise<void>;\n\nexport class Lifecycle {\n private hooks: Record<HookName, Set<HookFn>> = {\n sdkReady: new Set(),\n sdkInitPara: new Set(),\n sdkAfterInitPara: new Set(),\n sdkInitAPI: new Set(),\n sdkAfterInitAPI: new Set(),\n changeDistinctId: new Set(),\n switch: new Set(),\n };\n\n /** 注册钩子,返回取消函数 */\n on(name: HookName, fn: HookFn): () => void {\n if (!this.hooks[name]) {\n throw new Error(`[Lifecycle] unknown hook: ${name}`);\n }\n this.hooks[name].add(fn);\n return () => this.off(name, fn);\n }\n\n /** 取消钩子 */\n off(name: HookName, fn: HookFn): void {\n this.hooks[name]?.delete(fn);\n }\n\n /** 同步触发钩子(catch 内部错误,不向外抛) */\n emit(name: HookName, ...args: unknown[]): void {\n const set = this.hooks[name];\n if (!set) return;\n // 拷贝一份以容忍 off() 出现在回调中\n for (const fn of Array.from(set)) {\n try {\n fn(...args);\n } catch (e) {\n // 钩子内错误吞掉,避免影响主流程\n if (typeof console !== 'undefined' && console.error) {\n console.error(`[EventTracker] hook ${name} error:`, e);\n }\n }\n }\n }\n\n /** 移除全部钩子 */\n clear(): void {\n for (const k of Object.keys(this.hooks) as HookName[]) {\n this.hooks[k].clear();\n }\n }\n\n /** 调试用 */\n inspect(): Record<HookName, number> {\n const out = {} as Record<HookName, number>;\n for (const k of Object.keys(this.hooks) as HookName[]) {\n out[k] = this.hooks[k].size;\n }\n return out;\n }\n}\n","import { StageChain, type StageInterceptor, type StageName } from './stage.js';\nimport { Lifecycle, type HookName, type HookFn } from './lifecycle.js';\nimport type { TrackerConfig } from '../types/index.js';\n\nexport interface InstallContext {\n /** 当前配置(reference,mutate 会影响 SDK) */\n config: TrackerConfig;\n /** 钩子系统 */\n registry: PluginRegistry;\n /** 3 个 stage 注入点 */\n stages: {\n buildDataStage: StageChain<unknown>;\n businessStage: StageChain<unknown>;\n sendDataStage: StageChain<unknown>;\n };\n /** SDK 自身引用(提供 track / identify / use / quick 等 API) */\n sdk: import('./tracker.js').EventTracker;\n /** 给插件使用的命名空间(每个 plugin 可写入自己的子对象) */\n kit: Record<string, unknown>;\n /** 跨实例 channel */\n channel: import('./instance-channel.js').InstanceChannel;\n /** 持久化 store */\n store: import('../storage/store.js').KVStore;\n /** 卸载 */\n uninstall: () => void;\n}\n\nexport interface Plugin {\n /** 唯一名(同名重复 install 会先卸载旧的) */\n name: string;\n install?(ctx: InstallContext): void;\n uninstall?(ctx?: InstallContext): void;\n}\n\nexport class PluginRegistry {\n /** 3 个 stage */\n readonly stages: {\n buildDataStage: StageChain<unknown>;\n businessStage: StageChain<unknown>;\n sendDataStage: StageChain<unknown>;\n };\n\n /** 7 个生命周期钩子 */\n readonly lifecycle = new Lifecycle();\n\n /** 已安装的 plugin 列表 */\n private plugins: Plugin[] = [];\n\n /** commonWays:quick() 调用入口 */\n readonly commonWays: Record<string, (...args: unknown[]) => unknown> = {};\n\n /** hook 注册快捷方法(向后兼容 + 简化插件作者) */\n on(name: HookName, fn: HookFn): () => void {\n return this.lifecycle.on(name, fn);\n }\n off(name: HookName, fn: HookFn): void {\n this.lifecycle.off(name, fn);\n }\n emit(name: HookName, ...args: unknown[]): void {\n this.lifecycle.emit(name, ...args);\n }\n\n /** stage 注册拦截器 */\n intercept<T = unknown>(stage: StageName, spec: StageInterceptor<T>): void {\n this.stages[stage].register(spec as StageInterceptor<unknown>);\n }\n\n /** 兼容旧 API:invoke(name, ...args) = emit(name, ...args) */\n invoke(name: HookName, ...args: unknown[]): void {\n this.lifecycle.emit(name, ...args);\n }\n\n constructor() {\n this.stages = {\n buildDataStage: new StageChain('buildDataStage'),\n businessStage: new StageChain('businessStage'),\n sendDataStage: new StageChain('sendDataStage'),\n };\n }\n\n /** 安装 plugin */\n install(\n plugin: Plugin,\n ctx: Omit<InstallContext, 'registry' | 'stages'>,\n ): void {\n // 同名先卸载\n const idx = this.plugins.findIndex(p => p.name === plugin.name);\n if (idx >= 0) {\n this.uninstall(this.plugins[idx]);\n this.plugins.splice(idx, 1);\n }\n this.plugins.push(plugin);\n if (plugin.install) {\n const full: InstallContext = {\n ...ctx,\n registry: this,\n stages: this.stages,\n };\n try {\n plugin.install(full);\n } catch (e) {\n if (typeof console !== 'undefined' && console.error) {\n console.error(`[EventTracker] plugin ${plugin.name} install failed:`, e);\n }\n }\n }\n }\n\n /** 卸载 plugin */\n uninstall(plugin: Plugin, ctx?: InstallContext): void {\n try {\n plugin.uninstall?.(ctx);\n } catch (e) {\n if (typeof console !== 'undefined' && console.error) {\n console.error(`[EventTracker] plugin ${plugin.name} uninstall failed:`, e);\n }\n }\n }\n\n /** 列出已安装 */\n list(): string[] {\n return this.plugins.map(p => p.name);\n }\n}\n","/**\n * 跨实例 channel\n * - 用 BroadcastChannel 实现,浏览器跨 tab 通信\n * - 降级到 localStorage(无 BroadcastChannel 时)\n * - 主要用于:\n * - 共享 disabled 状态\n * - 共享 changeDistinctId\n * - 共享 session_id\n */\n\nexport interface ChannelMessage {\n type: 'state' | 'distinct' | 'session' | 'custom';\n source: string; // 实例 id,避开自己发出的回声\n payload: unknown;\n}\n\ntype Listener = (msg: ChannelMessage) => void;\n\nconst CHANNEL_NAME = 'event-tracker';\n\nexport class InstanceChannel {\n private bc: BroadcastChannel | null = null;\n private listeners = new Set<Listener>();\n private sourceId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n private localStorageKey = `et_channel_${CHANNEL_NAME}`;\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor() {\n this.initBroadcastChannel();\n if (!this.bc) this.initLocalStoragePolling();\n }\n\n private initBroadcastChannel(): void {\n if (typeof BroadcastChannel === 'undefined') return;\n try {\n this.bc = new BroadcastChannel(CHANNEL_NAME);\n this.bc.onmessage = (ev: MessageEvent<ChannelMessage>) => {\n if (ev.data?.source === this.sourceId) return;\n this.listeners.forEach(fn => fn(ev.data));\n };\n } catch {\n this.bc = null;\n }\n }\n\n private initLocalStoragePolling(): void {\n // storage event 兼容性\n if (typeof window !== 'undefined') {\n window.addEventListener('storage', (ev: StorageEvent) => {\n if (ev.key !== this.localStorageKey || !ev.newValue) return;\n try {\n const msg = JSON.parse(ev.newValue) as ChannelMessage;\n if (msg.source === this.sourceId) return;\n this.listeners.forEach(fn => fn(msg));\n } catch {\n /* ignore */\n }\n });\n }\n }\n\n /** 发送消息 */\n post(type: ChannelMessage['type'], payload: unknown): void {\n const msg: ChannelMessage = { type, source: this.sourceId, payload };\n if (this.bc) {\n try { this.bc.postMessage(msg); } catch { /* ignore */ }\n } else {\n // localStorage 降级\n try {\n localStorage.setItem(this.localStorageKey, JSON.stringify(msg));\n } catch { /* ignore quota */ }\n }\n }\n\n /** 监听消息,返回取消函数 */\n on(fn: Listener): () => void {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n /** 关闭 */\n close(): void {\n if (this.bc) {\n try { this.bc.close(); } catch { /* ignore */ }\n this.bc = null;\n }\n this.listeners.clear();\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /** 实例 id(用于调试 / 验证) */\n getSourceId(): string {\n return this.sourceId;\n }\n}\n","/**\n * 失败重试 + 退避(v1.2.0)\n *\n * - 指数退避(base 1s, cap 30s)\n * - 全抖动(full jitter):sleep = random(0, base * 2^attempt)\n * - 可配置 retry jitter type(off / equal / full / decorrelated)\n * - 超过 max_retry_count / max_retry_duration 放弃\n */\n\nimport type { TrackerConfig } from '../types/index.js';\nimport type { Logger } from './logger.js';\n\nexport interface RetryConfig {\n max_retry_count: number;\n max_retry_duration: number;\n}\n\nexport type JitterType = 'off' | 'equal' | 'full' | 'decorrelated';\n\n/** 重试执行结果 */\nexport interface RetryResult {\n ok: boolean;\n attempts: number;\n finalErr: Error | null;\n}\n\nexport class RetryPolicy {\n private jitter: JitterType;\n\n constructor(\n private config: TrackerConfig,\n private logger: Logger,\n jitter: JitterType = 'full',\n ) {\n this.jitter = jitter;\n }\n\n /** 计算本次重试要 sleep 多久(指数退避 + 抖动) */\n backoff(attempt: number, baseMs = 1000, capMs = 30000): number {\n const exp = Math.min(baseMs * 2 ** attempt, capMs);\n switch (this.jitter) {\n case 'off':\n return exp;\n case 'equal':\n // half deterministic + half random\n return exp / 2 + Math.random() * (exp / 2);\n case 'full':\n return Math.random() * exp;\n case 'decorrelated':\n // decorrelated jitter:sleep = uniform(base, prev*3),cap\n // 这里没有 prev 状态,用 attempt - 1 的 base*2^(attempt-1)*3\n const prev = Math.min(baseMs * 2 ** Math.max(0, attempt - 1) * 3, capMs);\n return baseMs + Math.random() * (prev - baseMs);\n default:\n return exp;\n }\n }\n\n /**\n * 带重试执行 send 函数\n * @param send 单次发送\n * @param shouldRetry 判断失败是否重试\n */\n async execute(\n send: () => Promise<void> | void,\n shouldRetry: (err: Error | null) => boolean = () => true,\n onFailed?: (err: Error, attempt: number) => void,\n ): Promise<RetryResult> {\n const maxCount = this.config.max_retry_count ?? 3;\n const maxDur = this.config.max_retry_duration ?? 60000;\n const start = Date.now();\n let lastErr: Error | null = null;\n let sleepAcc = 0;\n\n for (let attempt = 0; attempt <= maxCount; attempt++) {\n try {\n await send();\n return { ok: true, attempts: attempt + 1, finalErr: null };\n } catch (e) {\n lastErr = e as Error;\n if (!shouldRetry(lastErr)) {\n return { ok: false, attempts: attempt + 1, finalErr: lastErr };\n }\n const nextSleep = this.backoff(attempt);\n if (Date.now() - start + sleepAcc + nextSleep > maxDur) {\n this.logger.warn(`[EventTracker] max_retry_duration reached, give up`);\n onFailed?.(lastErr, attempt + 1);\n return { ok: false, attempts: attempt + 1, finalErr: lastErr };\n }\n if (attempt < maxCount) {\n sleepAcc += nextSleep;\n await this.sleep(nextSleep);\n }\n }\n }\n onFailed?.(lastErr as Error, maxCount + 1);\n return { ok: false, attempts: maxCount + 1, finalErr: lastErr };\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}","/**\n * 失败队列(v1.2.0)\n *\n * - 失败事件写入 localStorage(et_failed_queue)\n * - 下次启动时优先 flush(drain)\n * - 上限 50 条\n * - 单飞锁:同一时刻只有一个 drain 在跑\n * - AbortSignal 支持:drain 中断后保留队列\n */\n\nimport type { EventData } from '../types/index.js';\nimport { encodeBatch } from '../send/encode.js';\nimport { isBrowser, hasLocalStorage } from '../core/env.js';\n\nconst QUEUE_KEY = 'et_failed_queue';\nconst DEFAULT_MAX = 50;\n\nexport class FailedQueue {\n private config: { max: number; encryptor?: (s: string) => string | Promise<string> };\n private draining = false;\n private drainPromise: Promise<void> | null = null;\n private drainAbort: AbortController | null = null;\n\n constructor(config: { max?: number; encryptor?: (s: string) => string | Promise<string> } = {}) {\n this.config = { max: config.max ?? DEFAULT_MAX, encryptor: config.encryptor };\n }\n\n /** 读队列 */\n read(): EventData[] {\n if (!isBrowser() || !hasLocalStorage()) return [];\n try {\n const raw = localStorage.getItem(QUEUE_KEY);\n if (!raw) return [];\n const arr = JSON.parse(raw);\n return Array.isArray(arr) ? arr : [];\n } catch {\n return [];\n }\n }\n\n /** 写一条 */\n enqueue(event: EventData): void {\n if (!isBrowser() || !hasLocalStorage()) return;\n const q = this.read();\n q.push(event);\n if (q.length > this.config.max) q.splice(0, q.length - this.config.max);\n try {\n // encryptor 可能是异步(Promise<string>),这里只用 JSON 原文入队\n const enc = this.config.encryptor;\n const str = enc ? JSON.stringify(q) : JSON.stringify(q);\n localStorage.setItem(QUEUE_KEY, str);\n } catch {\n // quota 满,丢弃一半\n const half = q.slice(Math.floor(q.length / 2));\n try {\n localStorage.setItem(QUEUE_KEY, JSON.stringify(half));\n } catch { /* ignore */ }\n }\n }\n\n /** 清空 */\n clear(): void {\n if (!isBrowser() || !hasLocalStorage()) return;\n try { localStorage.removeItem(QUEUE_KEY); } catch { /* ignore */ }\n }\n\n /** 取走全部(同时清空) */\n takeAll(): EventData[] {\n const q = this.read();\n this.clear();\n return q;\n }\n\n /** 队列大小 */\n size(): number {\n return this.read().length;\n }\n\n /**\n * 单飞 drain:同一时刻只有一个 drain 在跑,后续 drain 直接复用 promise\n * @param sender 实际发送函数\n * @returns Promise<number> 实际发送成功条数\n */\n async drain(sender: (events: EventData[]) => Promise<number>): Promise<number> {\n if (this.draining && this.drainPromise) {\n await this.drainPromise.catch(() => { /* ignore */ });\n return 0;\n }\n this.draining = true;\n this.drainAbort = new AbortController();\n this.drainPromise = this._drain(sender);\n try {\n await this.drainPromise;\n return 0; // 由 _drain 内部统计\n } finally {\n this.draining = false;\n this.drainPromise = null;\n this.drainAbort = null;\n }\n }\n\n /** 取消正在跑的 drain(保留队列) */\n abortDrain(reason?: string): void {\n this.drainAbort?.abort(reason);\n }\n\n private async _drain(sender: (events: EventData[]) => Promise<number>): Promise<void> {\n const signal = this.drainAbort!.signal;\n while (!signal.aborted) {\n const q = this.takeAll();\n if (!q.length) return;\n try {\n const ok = await sender(q);\n if (ok < q.length) {\n // 部分失败,把剩余塞回去\n const remain = q.slice(ok);\n for (const e of remain) this.enqueue(e);\n return;\n }\n } catch {\n // 全部失败,回滚\n for (const e of q) this.enqueue(e);\n return;\n }\n }\n }\n}\n\n// 重新导出避免循环引用\nexport { encodeBatch };","/**\n * SDK 统一错误类型(v1.1)\n *\n * 所有内部 / 暴露给用户的错误都继承 SDKError,带 code 字段方便用户处理:\n * - SDKError\n * ├── InitError 配置错误(缺 server_url 等)\n * ├── SendError 发送失败\n * ├── EncryptError 加密 / 解密失败\n * ├── IdentityError 身份 / ID 操作失败\n * ├── StorageError 存储读写失败\n * ├── PluginError 插件 install / uninstall 失败\n * └── ConfigError 配置校验失败\n */\n\n/** 基类 */\nexport class SDKError extends Error {\n /** 错误码 */\n readonly code: string;\n /** 原始错误 */\n readonly cause?: unknown;\n /** 出错时间戳 */\n readonly timestamp: number;\n /** 上下文(带最少 1KB 容量) */\n readonly context?: Record<string, unknown>;\n\n constructor(\n code: string,\n message: string,\n options: { cause?: unknown; context?: Record<string, unknown> } = {},\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.cause = options.cause;\n this.context = options.context;\n this.timestamp = Date.now();\n // 保留下调用栈\n if (typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /** 序列化为对象(方便日志) */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n timestamp: this.timestamp,\n context: this.context,\n stack: this.stack,\n };\n }\n}\n\nexport class InitError extends SDKError {\n constructor(message: string, options?: { cause?: unknown; context?: Record<string, unknown> }) {\n super('INIT', message, options);\n }\n}\n\nexport class SendError extends SDKError {\n readonly attempts: number;\n constructor(message: string, attempts: number, options?: { cause?: unknown; context?: Record<string, unknown> }) {\n super('SEND', message, options);\n this.attempts = attempts;\n }\n}\n\nexport class EncryptError extends SDKError {\n constructor(message: string, options?: { cause?: unknown; context?: Record<string, unknown> }) {\n super('ENCRYPT', message, options);\n }\n}\n\nexport class IdentityError extends SDKError {\n constructor(message: string, options?: { cause?: unknown; context?: Record<string, unknown> }) {\n super('IDENTITY', message, options);\n }\n}\n\nexport class StorageError extends SDKError {\n constructor(message: string, options?: { cause?: unknown; context?: Record<string, unknown> }) {\n super('STORAGE', message, options);\n }\n}\n\nexport class PluginError extends SDKError {\n readonly plugin: string;\n constructor(plugin: string, message: string, options?: { cause?: unknown; context?: Record<string, unknown> }) {\n super('PLUGIN', message, options);\n this.plugin = plugin;\n }\n}\n\nexport class ConfigError extends SDKError {\n constructor(message: string, options?: { cause?: unknown; context?: Record<string, unknown> }) {\n super('CONFIG', message, options);\n }\n}\n\n/** 判断是否是 SDKError */\nexport function isSDKError(e: unknown): e is SDKError {\n return e instanceof SDKError;\n}","/**\n * 签名 Identity(HMAC-SHA256)\n * - 把 cookie / localStorage 中的 distinct_id / first_id 加密 + 签名\n * - 防止用户篡改身份\n * - 基于 Web Crypto API(jsdom + Node 18+)\n */\n\nimport { SDKError } from './errors.js';\n\nfunction getSubtle(): SubtleCrypto {\n if (typeof globalThis !== 'undefined' && (globalThis as { crypto?: Crypto }).crypto?.subtle) {\n return (globalThis as { crypto: Crypto }).crypto.subtle;\n }\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { webcrypto } = require('crypto');\n (globalThis as { crypto: typeof webcrypto }).crypto = webcrypto;\n return webcrypto.subtle;\n}\n\nconst ENC = (() => {\n if (typeof globalThis !== 'undefined' && (globalThis as { TextEncoder?: typeof TextEncoder }).TextEncoder) {\n return new (globalThis as { TextEncoder: typeof TextEncoder }).TextEncoder();\n }\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { TextEncoder } = require('util');\n (globalThis as { TextEncoder: typeof TextEncoder }).TextEncoder = TextEncoder;\n return new TextEncoder();\n})();\n\n/** 把字符串编码到 base64 */\nfunction bytesToB64(bytes: Uint8Array): string {\n if (typeof btoa !== 'undefined') {\n let s = '';\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\n return btoa(s);\n }\n return Buffer.from(bytes).toString('base64');\n}\n\nfunction b64ToBytes(b64: string): Uint8Array {\n if (typeof atob !== 'undefined') {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n }\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\n/** 同步签名(基于 simple hash,与 HMAC 不同;但不依赖 Web Crypto) */\nfunction syncSign(data: string, secret: string): string {\n // FNV-1a 64-bit 模拟:base64(rotate-xor(secret, data))\n let h1 = 0x811c9dc5;\n let h2 = 0xcbf29ce4;\n for (let i = 0; i < data.length; i++) {\n h1 ^= data.charCodeAt(i);\n h1 = Math.imul(h1, 0x01000193) >>> 0;\n h2 ^= secret.charCodeAt(i % secret.length);\n h2 = Math.imul(h2, 0x100000001b3) >>> 0;\n }\n const combined = (BigInt(h1) << 32n) | BigInt(h2);\n return combined.toString(36);\n}\n\n/** 异步 HMAC-SHA256(推荐使用) */\nexport async function hmacSignAsync(data: string, secret: string): Promise<string> {\n const subtle = getSubtle();\n const key = await subtle.importKey(\n 'raw',\n ENC.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const sig = new Uint8Array(await subtle.sign('HMAC', key, ENC.encode(data)));\n return bytesToB64(sig);\n}\n\n/** 异步验证签名 */\nexport async function hmacVerifyAsync(data: string, secret: string, signature: string): Promise<boolean> {\n const expected = await hmacSignAsync(data, secret);\n // 常数时间比较\n if (expected.length !== signature.length) return false;\n let diff = 0;\n for (let i = 0; i < expected.length; i++) {\n diff |= expected.charCodeAt(i) ^ signature.charCodeAt(i);\n }\n return diff === 0;\n}\n\n// ============================================================\n// SignedIdentity 工厂\n// ============================================================\n\nexport interface SignedIdentity {\n /** 同步签名 */\n sign(value: string): string;\n /** 异步签名(HMAC-SHA256) */\n signAsync(value: string): Promise<string>;\n /** 同步校验 */\n verify(value: string, signed: string): boolean;\n /** 异步校验 */\n verifyAsync(value: string, signed: string): Promise<boolean>;\n /** 给 KV 写入用的编码(`${value}|${sig}`) */\n encode(value: string): string;\n /** 从 KV 读取后还原(失败返回 null) */\n decode(raw: string): string | null;\n /** 异步版本 */\n encodeAsync(value: string): Promise<string>;\n decodeAsync(raw: string): Promise<string | null>;\n}\n\n/** 创建签名器 */\nexport function createSignedIdentity(secret: string): SignedIdentity {\n if (!secret) {\n throw new SDKError('IDENTITY', 'createSignedIdentity: secret is required', {\n context: { hint: 'set config.identity_secret to enable signed identity' },\n });\n }\n return {\n sign: (v) => syncSign(v, secret),\n signAsync: (v) => hmacSignAsync(v, secret),\n verify: (v, sig) => syncSign(v, secret) === sig,\n verifyAsync: (v, sig) => hmacVerifyAsync(v, secret, sig),\n encode: (v) => `${v}|${syncSign(v, secret)}`,\n decode: (raw) => {\n const idx = raw.lastIndexOf('|');\n if (idx <= 0) return null;\n const v = raw.slice(0, idx);\n const sig = raw.slice(idx + 1);\n if (syncSign(v, secret) !== sig) return null;\n return v;\n },\n encodeAsync: async (v) => `${v}|${await hmacSignAsync(v, secret)}`,\n decodeAsync: async (raw) => {\n const idx = raw.lastIndexOf('|');\n if (idx <= 0) return null;\n const v = raw.slice(0, idx);\n const sig = raw.slice(idx + 1);\n if (!(await hmacVerifyAsync(v, secret, sig))) return null;\n return v;\n },\n };\n}","/**\n * 发送管线(v1.1.1)\n * - 集中管理 build / encrypt / send / failed-queue / batch flush\n * - flush() / waitUntilIdle() 让上层能主动等待\n */\n\nimport type { TrackerConfig, EventData, Callback, PropertyMap } from '../types/index.js';\nimport type { PluginRegistry } from './plugin.js';\nimport type { IdentityManager } from './identity.js';\nimport type { PresetPropertyBuilder } from '../presets/preset-properties.js';\nimport type { RetryPolicy, RetryResult } from './retry-policy.js';\nimport type { FailedQueue } from './failed-queue.js';\nimport type { BatchSender } from '../send/batch-sender.js';\nimport type { Sender, SendContext } from '../send/sender.js';\nimport { sendWithStats } from '../send/sender.js';\nimport { Logger } from './logger.js';\nimport { EncryptError } from './errors.js';\nimport { LIB_NAME, LIB_VERSION } from '../types/constants.js';\nimport { isBrowser } from './env.js';\nimport type { StatsCollector } from './stats.js';\n\n/** 异步任务信号 */\ninterface PendingTask {\n promise: Promise<unknown>;\n resolve: () => void;\n reject: (e: unknown) => void;\n}\n\nexport class SendPipeline {\n private pending: PendingTask[] = [];\n private senders: Sender[] = [];\n private batchSender?: BatchSender;\n private abortControllers = new Map<Symbol, AbortController>();\n\n constructor(\n private config: TrackerConfig,\n private registry: PluginRegistry,\n private identity: IdentityManager,\n private presetProps: PresetPropertyBuilder,\n private retryPolicy: RetryPolicy,\n private failedQueue: FailedQueue,\n private logger: Logger,\n private stats?: StatsCollector,\n ) {}\n\n setSenders(senders: Sender[]): void {\n this.senders = senders;\n }\n setBatchSender(b: BatchSender): void {\n this.batchSender = b;\n }\n\n /** 构造共享的 SendContext(含 stats + logger + config) */\n private makeCtx(): SendContext {\n const ctx: SendContext = { config: this.config, logger: this.logger };\n if (this.stats) ctx.stats = this.stats;\n return ctx;\n }\n\n /** 构造事件对象 */\n buildEvent(\n type: EventData['type'],\n opts: { event?: string; properties?: Record<string, unknown> } = {},\n ): EventData {\n const time = this.config.get_client_timestamp?.() || Date.now();\n const merged = this.presetProps.build(this.config, opts.properties || {});\n const data: EventData = {\n type,\n time,\n distinct_id: this.identity.getDistinctId(),\n anonymous_id: this.identity.getAnonymousId(),\n first_id: this.identity.getFirstId(),\n login_id: this.identity.getLoginId() || undefined,\n original_id: this.identity.getOriginalId() || undefined,\n properties: merged,\n lib: { $lib: this.config.lib_name || LIB_NAME, $lib_version: this.config.lib_version || LIB_VERSION },\n token: this.config.app_id,\n project: this.config.app_id,\n };\n if (opts.event) data.event = opts.event;\n return data;\n }\n\n /** 异步发送 */\n send(data: EventData, callback?: Callback): void {\n if (this.config.disabled) {\n callback?.(null);\n return;\n }\n\n // 1. 插件 beforeTrack\n this.registry.invoke('sdkInitAPI', data);\n\n // 2. encryptEvent 钩子\n const hook = this.config.encryptEvent;\n if (hook) {\n try {\n const t = hook(data as unknown as Record<string, unknown>);\n if (t && typeof t === 'object') data = t as EventData;\n } catch (e) {\n this.logger.error('encryptEvent hook failed:', e);\n }\n }\n\n // 3. encrypt\n if (this.config.encryptor) {\n try {\n const out = this.config.encryptor(JSON.stringify(data));\n if (typeof out === 'string') {\n data._encrypted = out;\n this.dispatchAfterEncrypt(data, callback);\n } else {\n // 异步:等密文完成后再 dispatch\n out.then(\n (enc) => {\n data._encrypted = enc;\n this.dispatchAfterEncrypt(data, callback);\n },\n (err) => {\n this.logger.error(new EncryptError('async encryptor failed', { cause: err }));\n this.dispatchAfterEncrypt(data, callback);\n },\n );\n }\n } catch (e) {\n this.logger.error(new EncryptError('encryptor threw', { cause: e }));\n this.dispatchAfterEncrypt(data, callback);\n }\n } else {\n this.dispatchAfterEncrypt(data, callback);\n }\n }\n\n /** 加密后真正下发 */\n private dispatchAfterEncrypt(data: EventData, callback?: Callback): void {\n data.properties = this.registry.stages.sendDataStage.run(\n data.properties,\n this,\n ) as PropertyMap;\n\n const ctx = this.makeCtx();\n\n if (this.config.send_type === 'batch' && this.batchSender) {\n const p = Promise.resolve(this.batchSender.send(data, ctx))\n .then(() => callback?.(null))\n .catch((err) => callback?.(err as Error));\n this.trackPending(p);\n return;\n }\n\n const sender = this.pickSender();\n const task = this.retryPolicy.execute(\n () => {\n // 重试时回调钩子\n return sendWithStats(sender, data, ctx);\n },\n () => true,\n (err, attempt) => {\n this.failedQueue.enqueue(data);\n this.logger.warn('event send failed, queued:', err.message);\n // 失败入队回调\n try {\n this.config.onFailedEnqueue?.(\n data as unknown as Record<string, unknown>,\n err.message,\n );\n } catch { /* ignore */ }\n // 重试钩子\n try {\n this.config.onRetry?.(\n data as unknown as Record<string, unknown>,\n attempt,\n );\n } catch { /* ignore */ }\n this.stats?.recordRetry();\n },\n );\n const wrap = task.then((r: RetryResult) => {\n callback?.(r.ok ? null : r.finalErr);\n });\n this.trackPending(wrap);\n }\n\n private pickSender(): Sender {\n const req = this.config.send_type;\n if (req && req !== 'batch') {\n const match = this.senders.find(s => s.name === req && s.canUse());\n if (match) return match;\n }\n return (\n this.senders.find(s => s.name === 'beacon' && s.canUse()) ||\n this.senders.find(s => s.name === 'ajax' && s.canUse()) ||\n this.senders.find(s => s.name === 'image' && s.canUse()) ||\n this.senders[0]\n );\n }\n\n private trackPending(p: Promise<unknown>): void {\n const task: PendingTask = {\n promise: p,\n resolve: () => { /* noop */ },\n reject: () => { /* noop */ },\n };\n const wrapped = new Promise<void>((res, rej) => {\n task.resolve = res;\n task.reject = rej;\n });\n p.then(\n () => task.resolve(),\n (e) => task.reject(e),\n );\n this.pending.push(task);\n void wrapped; // 保留 reference\n }\n\n /**\n * 强制 flush:\n * - batch 模式:立即触发 batch sender 的 flush\n * - failed queue:把残留队列重发\n * - 所有 pending:等完成\n */\n async flush(): Promise<void> {\n const start = Date.now();\n let count = 0;\n if (this.batchSender) {\n try {\n const queued = (this.batchSender as unknown as { peekQueueSize?: () => number }).peekQueueSize?.() ?? 0;\n await this.batchSender.flush({ config: this.config, logger: this.logger });\n count += queued;\n } catch (e) {\n this.logger.warn('batch flush failed:', e);\n }\n }\n await this.waitUntilIdle();\n this.stats?.recordFlush();\n try {\n this.config.onFlush?.(count, Date.now() - start);\n } catch { /* ignore */ }\n }\n\n /** 等待所有 in-flight 任务结束 */\n async waitUntilIdle(): Promise<void> {\n while (this.pending.length) {\n const snapshot = this.pending.splice(0);\n await Promise.allSettled(snapshot.map(t => t.promise));\n }\n }\n\n /** Abort 所有挂起 / in-flight 任务 */\n abortAll(reason?: string): void {\n for (const [, ctrl] of this.abortControllers) {\n ctrl.abort(reason);\n }\n this.abortControllers.clear();\n this.pending = [];\n }\n\n /** 给 sender 用:申请一个 AbortSignal,发送完成 / abort 时自动释放 */\n takeAbortController(key: Symbol): AbortController {\n const ctrl = new AbortController();\n this.abortControllers.set(key, ctrl);\n return ctrl;\n }\n releaseAbortController(key: Symbol): void {\n this.abortControllers.delete(key);\n }\n}","/**\n * 发送器基类\n */\n\nimport type { EventData, TrackerConfig, SendType } from '../types/index.js';\nimport type { Logger } from '../core/logger.js';\nimport type { StatsCollector } from '../core/stats.js';\n\nexport interface SendContext {\n config: TrackerConfig;\n logger: Logger;\n /** 可选的 stats 收集器,未提供时退化为无统计模式 */\n stats?: StatsCollector;\n}\n\nexport interface Sender {\n /** 此发送器是否适用于当前上下文 */\n canUse(): boolean;\n /** 发送器名称,用于 pickSender/stats 聚合 */\n name: SendType | string;\n /** 发送单条事件 */\n send(event: EventData, ctx: SendContext): Promise<void> | void;\n}\n\n/**\n * 带 stats 计时 + onSendSuccess / onSendError 钩子的发送包装。\n * 由 SendPipeline 调用,统一埋点失败统计与可观测性。\n *\n * 不作为 Sender 接口成员,由 SendPipeline 显式调用本函数包一层,\n * 这样所有 Sender 子类都不必各自实现。\n * @internal\n */\nexport async function sendWithStats(\n sender: Sender,\n event: EventData,\n ctx: SendContext,\n): Promise<void> {\n const stats = ctx.stats;\n const senderName = sender.name;\n const start = stats ? stats.recordStart(senderName) : Date.now();\n\n try {\n await sender.send(event, ctx);\n stats?.recordSuccess(senderName, start);\n if (ctx.config.onSendSuccess) {\n try {\n ctx.config.onSendSuccess(\n event as unknown as Record<string, unknown>,\n Date.now() - start,\n );\n } catch {\n /* 用户回调异常不影响主流程 */\n }\n }\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n stats?.recordFailure(senderName, start, e);\n if (ctx.config.onSendError) {\n try {\n ctx.config.onSendError(e, event as unknown as Record<string, unknown>);\n } catch {\n /* ignore */\n }\n }\n throw e;\n }\n}\n\n/**\n * 支持批量发送的发送器(image/beacon 不支持,ajax/batch 支持)\n */\nexport interface BatchCapableSender extends Sender {\n /** 批量发送 */\n sendBatch?(events: EventData[], ctx: SendContext): Promise<void> | void;\n}\n\nexport function pickSender(type: SendType | undefined, candidates: Sender[]): Sender {\n if (type) {\n const match = candidates.find(s => s.name === type && s.canUse());\n if (match) return match;\n }\n // 降级链:beacon → ajax → image\n return (\n candidates.find(s => s.name === 'beacon' && s.canUse()) ||\n candidates.find(s => s.name === 'ajax' && s.canUse()) ||\n candidates.find(s => s.name === 'image' && s.canUse()) ||\n candidates[0]\n );\n}","/**\n * Sender 失败统计(v1.2.0)\n *\n * - 每个 sender 维护 attempts / success / failure / total_duration\n * - SDK 全局汇总\n * - 用户可 sdk.getStats() 查\n * - 自动每 60s 输出到 console(debug 模式)\n */\n\nimport type { SendType } from '../types/index.js';\n\nexport interface SenderStat {\n /** sender 名称(image / beacon / ajax / batch) */\n name: string;\n /** 尝试次数 */\n attempts: number;\n /** 成功次数 */\n success: number;\n /** 失败次数 */\n failure: number;\n /** 累计耗时(ms) */\n total_duration: number;\n /** 平均耗时(ms) */\n avg_duration: number;\n /** 最大单次耗时(ms) */\n max_duration: number;\n /** 最近一次失败原因 */\n last_error?: string;\n /** 最近一次失败时间戳 */\n last_error_at?: number;\n}\n\nexport interface StatsSnapshot {\n /** SDK 启动后累计发送次数 */\n total: number;\n /** 成功累计 */\n success: number;\n /** 失败累计 */\n failure: number;\n /** 重试累计 */\n retry: number;\n /** in-flight(当前未完成) */\n in_flight: number;\n /** flush 累计 */\n flush_count: number;\n /** 上次 flush 时间 */\n last_flush_at?: number;\n /** 每个 sender 统计 */\n by_sender: Record<string, SenderStat>;\n /** 时间戳 */\n taken_at: number;\n}\n\nexport class StatsCollector {\n private total = 0;\n private success = 0;\n private failure = 0;\n private retry = 0;\n private in_flight = 0;\n private flushCount = 0;\n private lastFlushAt?: number;\n private bySender: Map<string, SenderStat> = new Map();\n\n /** 记录一次发送开始 */\n recordStart(senderName: string): number {\n this.total++;\n this.in_flight++;\n const s = this.getOrCreate(senderName);\n s.attempts++;\n return Date.now();\n }\n\n /** 记录一次发送成功 */\n recordSuccess(senderName: string, startTs: number): void {\n this.success++;\n this.in_flight = Math.max(0, this.in_flight - 1);\n const s = this.getOrCreate(senderName);\n const dur = Date.now() - startTs;\n s.total_duration += dur;\n s.avg_duration = s.total_duration / s.attempts;\n if (dur > s.max_duration) s.max_duration = dur;\n }\n\n /** 记录一次发送失败 */\n recordFailure(senderName: string, startTs: number, err: Error): void {\n this.failure++;\n this.in_flight = Math.max(0, this.in_flight - 1);\n const s = this.getOrCreate(senderName);\n s.failure++;\n s.last_error = err.message;\n s.last_error_at = Date.now();\n }\n\n /** 记录一次重试 */\n recordRetry(): void {\n this.retry++;\n }\n\n /** 记录一次 flush */\n recordFlush(): void {\n this.flushCount++;\n this.lastFlushAt = Date.now();\n }\n\n /** 拍快照 */\n snapshot(): StatsSnapshot {\n const by_sender: Record<string, SenderStat> = {};\n for (const [k, v] of this.bySender) {\n by_sender[k] = { ...v };\n }\n return {\n total: this.total,\n success: this.success,\n failure: this.failure,\n retry: this.retry,\n in_flight: this.in_flight,\n flush_count: this.flushCount,\n last_flush_at: this.lastFlushAt,\n by_sender,\n taken_at: Date.now(),\n };\n }\n\n /** 重置 */\n reset(): void {\n this.total = 0;\n this.success = 0;\n this.failure = 0;\n this.retry = 0;\n this.in_flight = 0;\n this.flushCount = 0;\n this.lastFlushAt = undefined;\n this.bySender.clear();\n }\n\n /** 列出所有 sender 名 */\n listSenders(): string[] {\n return Array.from(this.bySender.keys());\n }\n\n private getOrCreate(name: string): SenderStat {\n let s = this.bySender.get(name);\n if (!s) {\n s = {\n name,\n attempts: 0,\n success: 0,\n failure: 0,\n total_duration: 0,\n avg_duration: 0,\n max_duration: 0,\n };\n this.bySender.set(name, s);\n }\n return s;\n }\n}\n\n/** 全局单例 */\nexport const GLOBAL_STATS = new StatsCollector();","/**\n * SDK 主类(v1.1.1)\n *\n * 通过 attachXxxApi 模块化挂载所有方法,主类只负责:\n * - 初始化(init)\n * - 装配管线(Pipeline)\n * - 提供公共 getter / setter\n * - 提供 flush / waitUntilIdle / abort / close\n */\n\nimport { isBrowser } from './env.js';\nimport { uuidv4 } from './uuid.js';\nimport { Logger } from './logger.js';\nimport { IdentityManager } from './identity.js';\nimport { PresetPropertyBuilder } from '../presets/preset-properties.js';\nimport { autoStore } from '../storage/store.js';\nimport type { KVStore } from '../storage/store.js';\nimport { ImageSender } from '../send/image-sender.js';\nimport { BeaconSender } from '../send/beacon-sender.js';\nimport { AjaxSender } from '../send/ajax-sender.js';\nimport { BatchSender } from '../send/batch-sender.js';\nimport type { Sender } from '../send/sender.js';\nimport { PluginRegistry, type Plugin, type InstallContext } from './plugin.js';\nimport { InstanceChannel } from './instance-channel.js';\nimport { RetryPolicy } from './retry-policy.js';\nimport { FailedQueue } from './failed-queue.js';\nimport { SignedIdentity, createSignedIdentity } from './signed-identity.js';\nimport { InitError } from './errors.js';\nimport { attachRegisterApi } from './register-api.js';\nimport { attachIdentityApi } from './identity-api.js';\nimport { attachProfileApi } from './profile-api.js';\nimport { attachTrackApi } from './track-api.js';\nimport { SendPipeline } from './send-pipeline.js';\nimport { StatsCollector } from './stats.js';\nimport { LIB_NAME, LIB_VERSION } from '../types/constants.js';\nimport type {\n EventData,\n TrackerConfig,\n Callback,\n SendType,\n StorageType,\n ServerURL,\n} from '../types/index.js';\n\nconst DEFAULT_CONFIG: Required<Pick<TrackerConfig, 'send_type' | 'max_retry_count' | 'debug' | 'storage_type' | 'is_collect_utm' | 'send_timeout' | 'max_retry_duration'>> = {\n send_type: 'image',\n max_retry_count: 3,\n debug: 0,\n storage_type: 'memory',\n is_collect_utm: true,\n send_timeout: 5000,\n max_retry_duration: 30_000,\n};\n\nexport class EventTracker {\n readonly lib_name = LIB_NAME;\n readonly lib_version = LIB_VERSION;\n readonly DEFAULT_SEND_TYPE: SendType = 'image';\n\n private _config!: TrackerConfig;\n private _store!: KVStore;\n private _identity!: IdentityManager;\n private _presetProps!: PresetPropertyBuilder;\n private _logger!: Logger;\n private _registry!: PluginRegistry;\n private _senders: Sender[] = [];\n private _batchSender?: BatchSender;\n private _retryPolicy!: RetryPolicy;\n private _failedQueue!: FailedQueue;\n private _channel!: InstanceChannel;\n private _pipeline!: SendPipeline;\n private _signedIdentity?: SignedIdentity;\n private _stats!: StatsCollector;\n private _statsTimer: ReturnType<typeof setInterval> | null = null;\n private _inited = false;\n\n readonly instanceId: string;\n\n constructor() {\n this.instanceId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n // ============================================================\n // 初始化\n // ============================================================\n\n /**\n * 初始化 SDK(只可调用一次;重复调用会被忽略)\n * @param config 完整配置项;详见 TrackerConfig\n * @throws InitError 当 server_url / app_id 缺失时\n * @example\n * ```ts\n * sdk.init({\n * app_id: 'demo',\n * server_url: 'https://api.example.com/sa',\n * send_type: 'beacon',\n * debug: 1,\n * });\n * ```\n */\n init(config: TrackerConfig): void {\n if (this._inited) {\n this._logger?.warn('EventTracker already initialized, re-init ignored');\n return;\n }\n this._config = { ...DEFAULT_CONFIG, ...config };\n this._config.lib_name = this._config.lib_name || LIB_NAME;\n this._config.lib_version = this._config.lib_version || LIB_VERSION;\n if (!this._config.server_url) {\n throw new InitError('server_url is required');\n }\n if (!this._config.app_id) {\n throw new InitError('app_id is required');\n }\n\n this._logger = new Logger({ debug: this._config.debug, show_log: this._config.show_log });\n this._store = autoStore({\n cookieDomain: this._config.cookie_domain,\n cookieCrossSubdomain: this._config.cookie_cross_subdomain,\n secureCookie: this._config.secure_cookie,\n });\n if (this._config.identity_secret) {\n this._signedIdentity = createSignedIdentity(this._config.identity_secret);\n }\n this._identity = new IdentityManager(this._store, {\n getDistinctId: this._config.get_distinct_id,\n setDistinctId: this._config.set_distinct_id,\n getAnonymousId: this._config.get_anonymous_id,\n setAnonymousId: this._config.set_anonymous_id,\n getFirstId: this._config.get_first_id,\n setFirstId: this._config.set_first_id,\n });\n this._presetProps = new PresetPropertyBuilder();\n if (this._config.preset_properties) {\n this._presetProps.setPreset(this._config.preset_properties);\n }\n this._registry = new PluginRegistry();\n this._channel = new InstanceChannel();\n this._retryPolicy = new RetryPolicy(this._config, this._logger);\n this._failedQueue = new FailedQueue({ max: 200, encryptor: this._config.encryptor });\n\n this._senders = [new ImageSender(), new BeaconSender(), new AjaxSender()];\n this._batchSender = new BatchSender();\n this._stats = new StatsCollector();\n\n this._pipeline = new SendPipeline(\n this._config,\n this._registry,\n this._identity,\n this._presetProps,\n this._retryPolicy,\n this._failedQueue,\n this._logger,\n this._stats,\n );\n this._pipeline.setSenders(this._senders);\n this._pipeline.setBatchSender(this._batchSender);\n\n // 启动 stats 周期性打印(debug 模式下默认开启)\n const showStats = this._config.show_stats ?? (this._config.debug ?? 0) >= 1;\n if (showStats && typeof window !== 'undefined') {\n const interval = this._config.stats_interval ?? 60_000;\n this._statsTimer = setInterval(() => {\n const snap = this._stats.snapshot();\n // eslint-disable-next-line no-console\n console.log('[EventTracker stats]', snap);\n }, interval);\n }\n\n // 启动 batch(如果是 batch 模式)\n if (this._config.send_type === 'batch') {\n this._batchSender.start({ config: this._config, logger: this._logger });\n }\n\n // 挂载 API\n attachRegisterApi(this, this._presetProps);\n attachIdentityApi(this, this._identity);\n attachProfileApi(this, this._pipeline);\n attachTrackApi(this, this._pipeline);\n\n this._registry.invoke('sdkReady', this._config);\n this._registry.invoke('sdkInitPara', this._config);\n this._inited = true;\n this._logger.log('EventTracker initialized:', {\n app_id: this._config.app_id,\n send_type: this._config.send_type,\n });\n this._registry.invoke('sdkAfterInitPara', this._config);\n this._registry.invoke('sdkInitAPI', this);\n this._registry.invoke('sdkAfterInitAPI', this);\n }\n\n // ============================================================\n // 插件\n // ============================================================\n use(plugin: Plugin): this {\n if (!this._inited) {\n setTimeout(() => this.use(plugin), 0);\n return this;\n }\n const ctx: InstallContext = {\n config: this._config,\n registry: this._registry,\n stages: this._registry.stages,\n sdk: this,\n kit: {},\n channel: this._channel,\n store: this._store,\n uninstall: () => this._registry.uninstall(plugin, ctx),\n };\n this._registry.install(plugin, ctx);\n return this;\n }\n\n // ============================================================\n // 公共 API(type stubs;实现在 attachXxxApi)\n // - 初始化为 noop,避免 uninit 时调用报错\n // - init() 时被 attachXxxApi 替换为真实实现\n // ============================================================\n /** @internal */\n __noop = (): void => { /* replaced by attachXxxApi */ };\n\n track(event: string, properties?: Record<string, unknown>, _callback?: Callback): void {\n void event; void properties; void _callback;\n }\n trackSignup(userId: string, properties?: Record<string, unknown>, _callback?: Callback): void {\n void userId; void properties; void _callback;\n }\n trackLinkage(properties: Record<string, unknown>, _callback?: Callback): void {\n void properties; void _callback;\n }\n trackLink(element: HTMLElement | string, properties?: Record<string, unknown>, _callback?: Callback): void {\n void element; void properties; void _callback;\n }\n trackLinks(\n elements: HTMLElement[] | NodeListOf<Element> | string,\n properties?: Record<string, unknown>,\n _callback?: Callback,\n ): void {\n void elements; void properties; void _callback;\n }\n trackHeatMap(properties: Record<string, unknown>, _callback?: Callback): void {\n void properties; void _callback;\n }\n trackWebClick(properties: Record<string, unknown>, _callback?: Callback): void {\n void properties; void _callback;\n }\n trackWebStay(properties: Record<string, unknown>, _callback?: Callback): void {\n void properties; void _callback;\n }\n\n identify(_distinctId: string, _isSave?: boolean): this { return this; }\n login(_loginId: string): this { return this; }\n logout(_resetAnonymousId?: string): this { return this; }\n resetAnonymousIdentity(_newAnonymousId?: string): this { return this; }\n alias(_newId: string, _originalId?: string): void { /* noop */ }\n\n getDistinctId(): string { return ''; }\n getAnonymousId(): string { return ''; }\n getFirstId(): string { return ''; }\n getLoginId(): string { return ''; }\n getOriginalId(): string { return ''; }\n\n register(_props: Record<string, unknown>): this { return this; }\n registerOnce(_props: Record<string, unknown>): this { return this; }\n clearAllRegister(): this { return this; }\n unsetRegister(_key: string): this { return this; }\n registerPage(_props: Record<string, unknown>): this { return this; }\n registerSession(_props: Record<string, unknown>): this { return this; }\n registerSessionOnce(_props: Record<string, unknown>): this { return this; }\n\n setProfile(_props: Record<string, unknown>, _callback?: Callback): void { /* noop */ }\n setOnceProfile(_props: Record<string, unknown>, _callback?: Callback): void { /* noop */ }\n incrementProfile(_props: Record<string, number>, _callback?: Callback): void { /* noop */ }\n appendProfile(_props: Record<string, unknown>, _callback?: Callback): void { /* noop */ }\n unsetProfile(_prop: string, _callback?: Callback): void { /* noop */ }\n deleteProfile(_callback?: Callback): void { /* noop */ }\n\n // ============================================================\n // 控制\n // ============================================================\n /** 关闭 SDK(track noop) */\n disable(): this {\n this._config.disabled = true;\n this._logger.warn('EventTracker disabled');\n return this;\n }\n /** 启用 SDK */\n enable(): this {\n this._config.disabled = false;\n return this;\n }\n\n /** 切换 server_url(多 sink / 灰度 / 主备切换)\n * @param url 单个 URL 或 URL 数组\n */\n setServerURL(url: ServerURL): this {\n return this.switchServer(url);\n }\n switchServer(url: ServerURL): this {\n if (!url) return this;\n this._config.server_url = url;\n this._registry.invoke('switch', url);\n return this;\n }\n\n /**\n * 强制 flush batch sender + failed queue + 等待所有 in-flight 完成\n */\n async flush(): Promise<void> {\n if (!this._inited) return;\n await this._pipeline.flush();\n }\n\n /**\n * 等待所有 in-flight 任务结束(发送、加密、queue 处理)\n */\n async waitUntilIdle(): Promise<void> {\n if (!this._inited) return;\n await this._pipeline.waitUntilIdle();\n }\n\n /** Abort 所有挂起任务 */\n abort(reason?: string): void {\n this._pipeline.abortAll(reason);\n }\n\n /** 完整关闭:channel close + pipeline abort + batch stop */\n close(): void {\n this._batchSender?.stop();\n this._channel?.close();\n if (this._statsTimer) {\n clearInterval(this._statsTimer);\n this._statsTimer = null;\n }\n this.abort('closed');\n }\n\n /** 工具 */\n uuid(): string {\n return uuidv4();\n }\n\n /** 预置属性(手动计算) */\n getPresetProperties(): Record<string, unknown> {\n return this._presetProps.build(this._config, {});\n }\n\n /** 完整关闭:channel close + pipeline abort + batch stop */\n shutdown(): void {\n this.close();\n }\n\n // ============================================================\n // Getter\n // ============================================================\n getConfig(): TrackerConfig {\n return { ...this._config };\n }\n getLogger(): Logger {\n return this._logger;\n }\n getRegistry(): PluginRegistry {\n return this._registry;\n }\n getRetryPolicy(): RetryPolicy {\n return this._retryPolicy;\n }\n getFailedQueue(): FailedQueue {\n return this._failedQueue;\n }\n getChannel(): InstanceChannel {\n return this._channel;\n }\n getPipeline(): SendPipeline {\n return this._pipeline;\n }\n getSignedIdentity(): SignedIdentity | undefined {\n return this._signedIdentity;\n }\n /** 获取 sender 失败统计快照(v1.2.0) */\n getStats() {\n return this._stats?.snapshot();\n }\n /** 重置 sender 统计 */\n resetStats(): void {\n this._stats?.reset();\n }\n isBrowser(): boolean {\n return isBrowser();\n }\n isInitialized(): boolean {\n return this._inited;\n }\n}\n\n// ============================================================\n// 多实例工厂\n// ============================================================\nconst INSTANCES = new Map<string, EventTracker>();\n\n/** 创建 / 切换实例 */\nexport function initPara(config: TrackerConfig): EventTracker {\n const instanceId = (config as { client_id?: string }).client_id || `instance-${INSTANCES.size + 1}`;\n let tracker = INSTANCES.get(instanceId);\n if (tracker) {\n tracker.switchServer(config.server_url);\n if (config.app_id) (tracker.getConfig() as { app_id?: string }).app_id = config.app_id;\n return tracker;\n }\n tracker = new EventTracker();\n tracker.init(config);\n INSTANCES.set(instanceId, tracker);\n return tracker;\n}\n\n/** 通过 client_id 取已有实例 */\nexport function registerAppid(instanceId: string): EventTracker | undefined {\n return INSTANCES.get(instanceId);\n}\n\n/** 列出所有实例 */\nexport function listInstances(): EventTracker[] {\n return Array.from(INSTANCES.values());\n}\n\n// 兼容旧 SDK 全局\nif (typeof window !== 'undefined') {\n (window as unknown as { eventTracker: EventTracker }).eventTracker = new EventTracker();\n}","/**\n * 公共属性注册 API(v1.1.1)\n */\n\nimport type { EventTracker } from '../core/tracker.js';\nimport type { PresetPropertyBuilder } from '../presets/preset-properties.js';\n\nexport interface RegisterApi {\n /** 注册永久属性(每次事件附带) */\n register(props: Record<string, unknown>): this;\n /** 注册一次性属性(首次读取后清除) */\n registerOnce(props: Record<string, unknown>): this;\n /** 清空所有永久属性 */\n clearAllRegister(): this;\n /** 移除单个属性 */\n unsetRegister(key: string): this;\n /** 注册一次性属性(神策 registerPage 别名) */\n registerPage(props: Record<string, unknown>): this;\n /** 注册会话属性(每次会话唯一;等同 registerOnce) */\n registerSession(props: Record<string, unknown>): this;\n /** 注册会话一次性属性 */\n registerSessionOnce(props: Record<string, unknown>): this;\n}\n\nexport function attachRegisterApi(sdk: EventTracker, builder: PresetPropertyBuilder): void {\n const proto = Object.getPrototypeOf(sdk) as object;\n const init = (sdk as unknown as { _registerAttached?: boolean })._registerAttached;\n if (init) return;\n (sdk as unknown as { _registerAttached?: boolean })._registerAttached = true;\n\n sdk.register = function (this: EventTracker, p: Record<string, unknown>) {\n builder.register(p);\n return this;\n };\n sdk.registerOnce = function (this: EventTracker, p: Record<string, unknown>) {\n builder.registerOnce(p);\n return this;\n };\n sdk.clearAllRegister = function (this: EventTracker) {\n builder.clearRegister();\n return this;\n };\n sdk.unsetRegister = function (this: EventTracker, k: string) {\n builder.unsetRegister(k);\n return this;\n };\n sdk.registerPage = function (this: EventTracker, p: Record<string, unknown>) {\n builder.registerOnce(p);\n return this;\n };\n sdk.registerSession = function (this: EventTracker, p: Record<string, unknown>) {\n builder.register(p);\n return this;\n };\n sdk.registerSessionOnce = function (this: EventTracker, p: Record<string, unknown>) {\n builder.registerOnce(p);\n return this;\n };\n\n // 防 TS 报 unused\n void proto;\n}","/**\n * 身份 API(v1.1.1)\n */\n\nimport type { EventTracker } from '../core/tracker.js';\nimport type { IdentityManager } from '../core/identity.js';\n\nexport function attachIdentityApi(sdk: EventTracker, identity: IdentityManager): void {\n const flag = (sdk as unknown as { _identityAttached?: boolean })._identityAttached;\n if (flag) return;\n (sdk as unknown as { _identityAttached?: boolean })._identityAttached = true;\n\n sdk.identify = function (this: EventTracker, id: string, save = true) {\n identity.identify(id, save);\n sdk.getRegistry().invoke('changeDistinctId', id);\n return this;\n };\n\n sdk.login = function (this: EventTracker, id: string) {\n identity.login(id);\n sdk.getRegistry().invoke('changeDistinctId', id);\n return this;\n };\n\n sdk.logout = function (this: EventTracker, newAnon?: string) {\n identity.resetAnonymousIdentity(newAnon);\n sdk.getRegistry().invoke('changeDistinctId', identity.getDistinctId());\n return this;\n };\n\n sdk.resetAnonymousIdentity = sdk.logout;\n\n sdk.alias = function (this: EventTracker, newId: string, originalId?: string) {\n const srcId = originalId || identity.getDistinctId();\n if (srcId === newId) return;\n identity.identify(newId, true);\n sdk.track('$SignUp', { $signup_method: 'alias' });\n sdk.getRegistry().invoke('changeDistinctId', newId);\n };\n\n sdk.getDistinctId = () => identity.getDistinctId();\n sdk.getAnonymousId = () => identity.getAnonymousId();\n sdk.getFirstId = () => identity.getFirstId();\n sdk.getLoginId = () => identity.getLoginId();\n sdk.getOriginalId = () => identity.getOriginalId();\n}","/**\n * Profile API(v1.1.1)\n */\n\nimport type { EventTracker } from '../core/tracker.js';\nimport type { SendPipeline } from './send-pipeline.js';\nimport type { Callback, EventData } from '../types/index.js';\n\nexport function attachProfileApi(sdk: EventTracker, pipeline: SendPipeline): void {\n const flag = (sdk as unknown as { _profileAttached?: boolean })._profileAttached;\n if (flag) return;\n (sdk as unknown as { _profileAttached?: boolean })._profileAttached = true;\n\n const profileSend = (type: EventData['type'], props: Record<string, unknown>, callback?: Callback): void => {\n const data = pipeline.buildEvent(type, { properties: props });\n pipeline.send(data, callback);\n };\n\n sdk.setProfile = (p, cb) => profileSend('profile_set', p, cb);\n sdk.setOnceProfile = (p, cb) => profileSend('profile_set_once', p, cb);\n sdk.incrementProfile = (p, cb) => profileSend('profile_increment', p, cb);\n sdk.appendProfile = (p, cb) => profileSend('profile_append', p, cb);\n sdk.unsetProfile = (prop, cb) => profileSend('profile_unset', { [prop]: true }, cb);\n sdk.deleteProfile = (cb) => profileSend('profile_delete', {}, cb);\n}","/**\n * Track API(v1.1.1)\n */\n\nimport type { EventTracker } from '../core/tracker.js';\nimport type { SendPipeline } from './send-pipeline.js';\nimport { isBrowser } from './env.js';\nimport { PresetEvent } from '../types/constants.js';\nimport type { Callback } from '../types/index.js';\n\nexport function attachTrackApi(sdk: EventTracker, pipeline: SendPipeline): void {\n const flag = (sdk as unknown as { _trackAttached?: boolean })._trackAttached;\n if (flag) return;\n (sdk as unknown as { _trackAttached?: boolean })._trackAttached = true;\n\n sdk.track = function (this: EventTracker, event: string, props: Record<string, unknown> = {}, cb?: Callback) {\n const data = pipeline.buildEvent('track', { event, properties: props });\n pipeline.send(data, cb);\n };\n\n sdk.trackSignup = function (this: EventTracker, userId: string, props: Record<string, unknown> = {}, cb?: Callback) {\n const data = pipeline.buildEvent('track_signup', {\n event: '$SignUp',\n properties: { ...props, $signup_method: props.$signup_method || '' },\n });\n data.original_id = sdk.getOriginalId();\n sdk.identify(userId, true);\n data.distinct_id = userId;\n data.login_id = userId;\n pipeline.send(data, cb);\n };\n\n sdk.trackLinkage = function (this: EventTracker, p: Record<string, unknown>, cb?: Callback) {\n sdk.track('$Linkage', p, cb);\n };\n\n sdk.trackLink = function (this: EventTracker, element: HTMLElement | string, props: Record<string, unknown> = {}, cb?: Callback) {\n if (!isBrowser()) return;\n const el = typeof element === 'string' ? document.querySelector(element) as HTMLElement | null : element;\n if (!el) return;\n const handler = () => {\n sdk.track('$WebClick', {\n ...props,\n $element_selector: el.id ? `#${el.id}` : el.tagName.toLowerCase(),\n $element_target_url: el instanceof HTMLAnchorElement ? el.href : undefined,\n }, cb);\n };\n el.addEventListener('click', handler, { once: true });\n };\n\n sdk.trackLinks = function (this: EventTracker, elements: any, props: Record<string, unknown> = {}, cb?: Callback) {\n if (!isBrowser()) return;\n let list: HTMLElement[];\n if (typeof elements === 'string') {\n list = Array.from(document.querySelectorAll(elements)) as HTMLElement[];\n } else if (elements && 'length' in elements && !('click' in elements)) {\n list = Array.from(elements) as HTMLElement[];\n } else {\n list = elements as HTMLElement[];\n }\n for (const el of list) sdk.trackLink(el, props, cb);\n };\n\n sdk.trackHeatMap = (p: Record<string, unknown>, cb?: Callback) => sdk.track('$heatmap_event', p, cb);\n sdk.trackWebClick = (p: Record<string, unknown>, cb?: Callback) => sdk.track(PresetEvent.WebStay === '$WebStay' ? '$WebClick' : '$WebClick', p, cb);\n sdk.trackWebStay = (p: Record<string, unknown>, cb?: Callback) => sdk.track('$WebStay', p, cb);\n}","/**\n * 平台适配层(v1.2.0)\n *\n * - 探测运行时:web / React Native / Node\n * - 提供平台特定的 KVStore fallback(Node 用 Map,RN 用 AsyncStorage shim)\n * - 默认 sender 在非 web 下做适配(beacon/image 禁用)\n */\n\nimport { MemoryStore } from '../storage/store.js';\nimport type { KVStore } from '../storage/store.js';\nimport { isBrowser } from '../core/env.js';\n\nexport type Platform = 'web' | 'rn' | 'node' | 'unknown';\n\nexport function detectPlatform(): Platform {\n if (isBrowser()) return 'web';\n // React Native: 探测 navigator.product === 'ReactNative' 或 global.__DEV__\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const g = globalThis as any;\n if (\n typeof g.navigator !== 'undefined' && g.navigator?.product === 'ReactNative'\n ) return 'rn';\n if (typeof g.__REACT_NATIVE__ !== 'undefined') return 'rn';\n // Node: process.versions.node\n if (typeof process !== 'undefined' && process.versions?.node) return 'node';\n return 'unknown';\n}\n\n/**\n * 自适应 KVStore\n * - web:交给上层默认(cookie/localStorage)\n * - rn:尝试 global.AsyncStorage,否则 MemoryStore\n * - node:MemoryStore(后续可挂 fs adapter)\n */\nexport function platformStore(): KVStore {\n // React Native AsyncStorage 适配层需要异步接口,KVStore 当前为同步契约,\n // 临时回退到 MemoryStore,输出更稳定的浏览器演示行为。\n // 后续可通过将 KVStore 改为异步接口以支持 RN 场景。\n // if (detectPlatform() === 'rn') {\n // const g = globalThis as unknown as {\n // AsyncStorage?: { getItem: (k: string) => Promise<string|null>; setItem: (k: string, v: string) => Promise<void> };\n // };\n // if (g.AsyncStorage && typeof g.AsyncStorage.getItem === 'function') {\n // return new AsyncStorageAdapter(g.AsyncStorage);\n // }\n // }\n return new MemoryStore();\n}\n\n/* AsyncStorageAdapter 故意移除 —— KVStore 为同步契约,适配 RN 的异步\n * 版本将在后续迭代中将 KVStore 升级为 async 后再实现。\n */\n\n/**\n * 平台相关的 sender 过滤:\n * - web:全部 sender 可用\n * - rn/node:禁用 image/beacon(无 navigator),仅 ajax\n */\nexport function isPlatformSenderEnabled(name: string): boolean {\n const p = detectPlatform();\n if (p === 'web') return true;\n if (name === 'ajax') return true;\n return false;\n}","/**\n * WASM 加密(v1.2.0 可选)\n *\n * - 把常见 HMAC-SHA256 / AES-GCM 操作抽到 wasm(性能 5-10x)\n * - 通过 dynamic import('./crypto-wasm.js') 按需加载\n * - wasm 未提供时 fallback 到 js\n * - 提供 `getWasmCrypto()` lazy 工厂\n *\n * 注意:本目录仅含 runtime glue;实际 wasm binary 由用户在构建期注入\n * (如:npm i @macroui/crypto-wasm 并在 init 时传入)\n */\n\nexport interface WasmCrypto {\n hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array;\n aesGcmEncrypt(key: Uint8Array, iv: Uint8Array, data: Uint8Array): Uint8Array;\n aesGcmDecrypt(key: Uint8Array, iv: Uint8Array, data: Uint8Array): Uint8Array;\n available: boolean;\n}\n\nlet _instance: Promise<WasmCrypto> | null = null;\n\n/**\n * 加载 wasm crypto\n * - 优先尝试 globalThis.__ET_WASM_CRYPTO__(用户注入)\n * - 否则尝试 import('@macroui/crypto-wasm') peer dep\n * - 失败时 fallback 到 JS 实现\n */\nexport function getWasmCrypto(): Promise<WasmCrypto> {\n if (_instance) return _instance;\n _instance = (async () => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const g = globalThis as any;\n if (g.__ET_WASM_CRYPTO__) return g.__ET_WASM_CRYPTO__ as WasmCrypto;\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = await (Function('return import(\"@macroui/crypto-wasm\")')() as Promise<any>);\n if (mod && mod.default) return mod.default as WasmCrypto;\n } catch { /* ignore */ }\n // JS fallback\n return makeJsFallback();\n })();\n return _instance;\n}\n\nasync function makeJsFallback(): Promise<WasmCrypto> {\n return {\n available: false,\n async hmacSha256(key, data) {\n const k = await crypto.subtle.importKey(\n 'raw', key as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false, ['sign'],\n );\n const sig = await crypto.subtle.sign('HMAC', k, data as BufferSource);\n return new Uint8Array(sig);\n },\n async aesGcmEncrypt(key, iv, data) {\n const k = await crypto.subtle.importKey('raw', key as BufferSource, 'AES-GCM', false, ['encrypt']);\n const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv: iv as BufferSource }, k, data as BufferSource);\n return new Uint8Array(ct);\n },\n async aesGcmDecrypt(key, iv, data) {\n const k = await crypto.subtle.importKey('raw', key as BufferSource, 'AES-GCM', false, ['decrypt']);\n const pt = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: iv as BufferSource }, k, data as BufferSource);\n return new Uint8Array(pt);\n },\n } as unknown as WasmCrypto;\n}\n\n/** 同步 hash 工具(用于 cache key,fallback) */\nexport function fastHash(s: string): number {\n let h = 2166136261;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return h >>> 0;\n}\n\n/** 注入自定义 wasm crypto(advanced 用) */\nexport function setWasmCrypto(c: WasmCrypto): void {\n _instance = Promise.resolve(c);\n}","/**\n * PII 自动检测与脱敏(v1.3.0)\n *\n * - 正则检测身份证 / 手机号 / 邮箱 / 银行卡 / IP\n * - 默认行为:hash(保留可关联性)\n * - 可配置:drop / mask / hash / passthrough\n * - 仅在 sendDataStage 中对 properties 字段做处理\n */\n\nexport type PiiAction = 'drop' | 'mask' | 'hash' | 'pass';\n\nexport interface PiiPattern {\n name: string;\n /** 正则 */\n re: RegExp;\n action: PiiAction;\n}\n\nconst MASK_CHAR = '*';\n\n// 中国大陆身份证\nconst RE_ID_CN = /\\b\\d{17}[\\dXx]\\b/g;\n// 手机号(11 位,1 开头)\nconst RE_PHONE_CN = /\\b1[3-9]\\d{9}\\b/g;\n// 邮箱\nconst RE_EMAIL = /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/g;\n// 银行卡(13-19 位数字)\nconst RE_BANKCARD = /\\b\\d{13,19}\\b/g;\n// IPv4\nconst RE_IPV4 = /\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/g;\n\nexport const DEFAULT_PATTERNS: PiiPattern[] = [\n { name: 'id_card_cn', re: RE_ID_CN, action: 'mask' },\n { name: 'phone_cn', re: RE_PHONE_CN, action: 'mask' },\n { name: 'email', re: RE_EMAIL, action: 'hash' },\n { name: 'bankcard', re: RE_BANKCARD, action: 'mask' },\n { name: 'ipv4', re: RE_IPV4, action: 'hash' },\n];\n\nexport interface PiiOptions {\n /** 自定义模式(在默认之后追加) */\n patterns?: PiiPattern[];\n /** 全局关闭 */\n enabled?: boolean;\n /** 白名单字段名(不处理) */\n excludeKeys?: string[];\n}\n\n/** 简单 hash(fnv1a) */\nexport function fnv1a(s: string): string {\n let h = 2166136261 >>> 0;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 16777619) >>> 0;\n }\n return 'h_' + h.toString(36);\n}\n\n/** 脱敏:保留前 1 后 1 */\nexport function maskValue(v: string): string {\n if (v.length <= 2) return MASK_CHAR.repeat(v.length);\n return v[0] + MASK_CHAR.repeat(v.length - 2) + v[v.length - 1];\n}\n\nfunction applyAction(action: PiiAction, v: string): string | undefined {\n switch (action) {\n case 'drop':\n return undefined;\n case 'mask':\n return maskValue(v);\n case 'hash':\n return fnv1a(v);\n case 'pass':\n default:\n return v;\n }\n}\n\nexport class PiiDetector {\n private patterns: PiiPattern[];\n private exclude: Set<string>;\n\n constructor(opts: PiiOptions = {}) {\n this.patterns = [...DEFAULT_PATTERNS, ...(opts.patterns || [])];\n this.exclude = new Set(opts.excludeKeys || []);\n }\n\n /** 对单个值做检测 */\n scan(value: unknown): { value: unknown; hits: Array<{ name: string; action: PiiAction }> } {\n if (typeof value !== 'string') return { value, hits: [] };\n let cur = value;\n const hits: Array<{ name: string; action: PiiAction }> = [];\n for (const p of this.patterns) {\n if (!p.re.test(cur)) {\n p.re.lastIndex = 0;\n continue;\n }\n p.re.lastIndex = 0;\n hits.push({ name: p.name, action: p.action });\n cur = cur.replace(p.re, (m) => {\n const r = applyAction(p.action, m);\n return r === undefined ? '' : r;\n });\n }\n return { value: cur, hits };\n }\n\n /** 对整棵 properties 做扫描(递归) */\n scanProperties(props: Record<string, unknown>): { properties: Record<string, unknown>; hits: number } {\n const out: Record<string, unknown> = {};\n let hits = 0;\n for (const [k, v] of Object.entries(props)) {\n if (this.exclude.has(k)) {\n out[k] = v;\n continue;\n }\n if (typeof v === 'string') {\n const { value, hits: h } = this.scan(v);\n out[k] = value;\n hits += h.length;\n } else if (v && typeof v === 'object' && !Array.isArray(v)) {\n const { properties: nested, hits: nh } = this.scanProperties(v as Record<string, unknown>);\n out[k] = nested;\n hits += nh;\n } else if (Array.isArray(v)) {\n out[k] = v.map((it) => {\n if (typeof it === 'string') {\n const { value: _v, hits: h } = this.scan(it);\n hits += h.length;\n return _v;\n }\n return it;\n });\n } else {\n out[k] = v;\n }\n }\n return { properties: out, hits };\n }\n}","/**\n * Privacy & Consent 管理(v1.3.0)\n *\n * - privacy_mode: 'off' | 'balanced' | 'strict'\n * off: 不脱敏\n * balanced: 按 excludeKeys 白名单 + 加密\n * strict: 强制脱敏 IP/UA/distinct_id,事件打 PII 标记\n * - Consent: grant(scope) / revoke(scope) / has(scope)\n * scope: 'analytics' | 'personalization' | 'marketing' | 'all'\n * 未授权时事件直接 drop + stats.dropped++\n */\n\nimport type { Logger } from './logger.js';\n\nexport type PrivacyMode = 'off' | 'balanced' | 'strict';\nexport type ConsentScope = 'analytics' | 'personalization' | 'marketing' | 'all';\n\nconst CONSENT_KEY = '__et_consent__';\n\nexport interface PrivacyState {\n mode: PrivacyMode;\n scopes: Set<ConsentScope>;\n}\n\nexport class PrivacyManager {\n private state: PrivacyState = { mode: 'off', scopes: new Set() };\n private storage: Storage | null = null;\n private listeners = new Set<(s: PrivacyState) => void>();\n\n constructor(private logger: Logger) {\n if (typeof window !== 'undefined') {\n try { this.storage = window.localStorage; } catch { /* ignore */ }\n this.loadFromStorage();\n }\n }\n\n setMode(mode: PrivacyMode): void {\n this.state.mode = mode;\n this.logger.log?.(`[Privacy] mode set to ${mode}`);\n this.emit();\n }\n\n getMode(): PrivacyMode {\n return this.state.mode;\n }\n\n /** 授权某个 scope */\n grant(scope: ConsentScope): void {\n if (scope === 'all') {\n this.state.scopes.add('analytics');\n this.state.scopes.add('personalization');\n this.state.scopes.add('marketing');\n } else {\n this.state.scopes.add(scope);\n }\n this.persist();\n this.logger.log?.(`[Consent] granted ${scope}`);\n this.emit();\n }\n\n /** 撤销某个 scope */\n revoke(scope: ConsentScope): void {\n if (scope === 'all') {\n this.state.scopes.clear();\n } else {\n this.state.scopes.delete(scope);\n }\n this.persist();\n this.logger.warn?.(`[Consent] revoked ${scope}`);\n this.emit();\n }\n\n /** 检查是否授权 */\n has(scope: ConsentScope): boolean {\n if (this.state.scopes.has('all')) return true;\n return this.state.scopes.has(scope);\n }\n\n /** 是否应该上报此事件 */\n shouldTrack(scope: ConsentScope = 'analytics'): boolean {\n if (!this.has(scope)) return false;\n return true;\n }\n\n /** 订阅 state 变化 */\n subscribe(fn: (s: PrivacyState) => void): () => void {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n /** strict 模式下脱敏 properties */\n applyPrivacy(props: Record<string, unknown>, mode: PrivacyMode = this.state.mode): Record<string, unknown> {\n if (mode === 'off') return props;\n const out = { ...props };\n // balanced + strict 都脱敏\n if (mode === 'strict') {\n // 删除 IP / UA / 设备指纹类\n for (const k of ['$ip', '$ip_addr', '$user_agent', '$device_id', '$mac', '$idfa']) {\n if (k in out) delete out[k];\n }\n }\n // balanced: 保留分析维度,但匿名 distinct_id 替换为 hash\n if (mode === 'balanced' || mode === 'strict') {\n if ('$distinct_id' in out && typeof out.$distinct_id === 'string') {\n // 保留字段名让下游做关联;不再做 hash(由 identity 层做)\n }\n }\n return out;\n }\n\n private loadFromStorage(): void {\n if (!this.storage) return;\n try {\n const raw = this.storage.getItem(CONSENT_KEY);\n if (!raw) return;\n const data = JSON.parse(raw);\n if (data.mode) this.state.mode = data.mode;\n if (Array.isArray(data.scopes)) this.state.scopes = new Set(data.scopes);\n } catch { /* ignore */ }\n }\n\n private persist(): void {\n if (!this.storage) return;\n try {\n this.storage.setItem(CONSENT_KEY, JSON.stringify({\n mode: this.state.mode,\n scopes: Array.from(this.state.scopes),\n }));\n } catch { /* ignore */ }\n }\n\n private emit(): void {\n for (const l of Array.from(this.listeners)) {\n try { l(this.state); } catch { /* ignore */ }\n }\n }\n}","/**\n * Idle Scheduler(v1.3.0)\n *\n * - 用 requestIdleCallback(fallback setTimeout)调度低优先级任务\n * - 首屏 TTI 不阻塞\n * - 适用场景:preset property 计算 / 插件 install / stage 注册\n */\n\nexport type IdleCallback = (deadline: { didTimeout: boolean; timeRemaining: () => number }) => void;\n\nexport interface IdleScheduler {\n schedule(fn: IdleCallback, opts?: { timeout?: number }): number;\n cancel(handle: number): void;\n}\n\nfunction hasRIC(): boolean {\n return typeof (globalThis as { requestIdleCallback?: unknown }).requestIdleCallback === 'function';\n}\n\nexport function createIdleScheduler(): IdleScheduler {\n if (hasRIC()) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ric = (globalThis as any).requestIdleCallback.bind(globalThis);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cic = (globalThis as any).cancelIdleCallback.bind(globalThis);\n return {\n schedule(fn, opts) {\n return ric(fn, opts || {});\n },\n cancel(handle) {\n cic(handle);\n },\n };\n }\n // fallback: setTimeout(0)\n return {\n schedule(fn) {\n return setTimeout(() => fn({ didTimeout: false, timeRemaining: () => 50 }), 0) as unknown as number;\n },\n cancel(handle) {\n clearTimeout(handle as unknown as ReturnType<typeof setTimeout>);\n },\n };\n}\n\nexport const globalIdleScheduler = createIdleScheduler();\n\n/**\n * 当浏览器空闲时再跑(timeout fallback 200ms)\n */\nexport function whenIdle(fn: IdleCallback, timeout = 200): () => void {\n const handle = globalIdleScheduler.schedule(fn, { timeout });\n return () => globalIdleScheduler.cancel(handle);\n}","/**\n * OffscreenSender (v1.3.0)\n *\n * 把 send/gzip/encrypt 全部挪到 Web Worker,主线程零阻塞\n *\n * - 使用专用 Worker(postMessage 协议)\n * - 主线程仅保留外壳:encodeEvent + postMessage\n * - 支持 batch send(同 worker 内聚合 + 单次 flush)\n * - 不可用时(Safari 14 之前 / Node)自动 fallback 到 ajax\n */\n\nimport type { Sender, SendContext } from './sender.js';\nimport type { EventData } from '../types/index.js';\n\ninterface WorkerMsgIn {\n kind: 'send' | 'sendBatch' | 'shutdown';\n payload?: EventData | EventData[];\n url?: string;\n serverUrl?: string | string[];\n gzip?: boolean;\n encryptor?: string; // 序列化后的 encryptor(实际场景由 worker 内 import SDK)\n}\n\ninterface WorkerMsgOut {\n kind: 'result' | 'error';\n ok: boolean;\n err?: string;\n durationMs?: number;\n}\n\nconst WORKER_SRC = `\nself.onmessage = async function (e) {\n const msg = e.data;\n const start = Date.now();\n try {\n if (msg.kind === 'send') {\n const ev = msg.payload;\n const body = 'data=' + encodeURIComponent(JSON.stringify(ev)) + '&batch=0';\n const r = await fetch(msg.url, { method:'POST', mode:'cors', credentials:'omit',\n headers:{'Content-Type':'application/x-www-form-urlencoded'}, body, keepalive:true });\n self.postMessage({ kind: r.ok ? 'result' : 'error', ok: r.ok, durationMs: Date.now() - start });\n } else if (msg.kind === 'sendBatch') {\n const evs = msg.payload;\n const body = 'data=' + encodeURIComponent(JSON.stringify(evs)) + '&batch=1';\n const r = await fetch(msg.url, { method:'POST', mode:'cors', credentials:'omit',\n headers:{'Content-Type':'application/x-www-form-urlencoded'}, body, keepalive:true });\n self.postMessage({ kind: r.ok ? 'result' : 'error', ok: r.ok, durationMs: Date.now() - start });\n } else if (msg.kind === 'shutdown') {\n self.close();\n }\n } catch (err) {\n self.postMessage({ kind: 'error', ok: false, err: String(err), durationMs: Date.now() - start });\n }\n};\n`;\n\nfunction hasWorker(): boolean {\n return typeof (globalThis as { Worker?: unknown }).Worker === 'function';\n}\n\nexport class OffscreenSender implements Sender {\n name = 'offscreen' as const;\n private worker: Worker | null = null;\n private fallback?: Sender;\n private queue: Array<{ resolve: () => void; reject: (e: Error) => void }> = [];\n\n canUse(): boolean {\n return hasWorker();\n }\n\n private getWorker(): Worker | null {\n if (this.worker) return this.worker;\n if (!hasWorker()) return null;\n try {\n const blob = new Blob([WORKER_SRC], { type: 'application/javascript' });\n const url = URL.createObjectURL(blob);\n this.worker = new Worker(url);\n this.worker.onmessage = (e: MessageEvent<WorkerMsgOut>) => {\n const head = this.queue.shift();\n if (!head) return;\n if (e.data.kind === 'error') {\n head.reject(new Error(e.data.err || 'worker send failed'));\n } else {\n head.resolve();\n }\n };\n this.worker.onerror = (e) => {\n // 全队列 reject\n const q = this.queue.splice(0);\n for (const t of q) t.reject(new Error(e.message || 'worker error'));\n };\n } catch {\n this.worker = null;\n }\n return this.worker;\n }\n\n async send(event: EventData, ctx: SendContext): Promise<void> {\n const url = Array.isArray(ctx.config.server_url) ? ctx.config.server_url[0] : ctx.config.server_url;\n const w = this.getWorker();\n if (!w) {\n // fallback\n const { AjaxSender } = await import('./ajax-sender.js');\n if (!this.fallback) this.fallback = new AjaxSender();\n return this.fallback.send(event, ctx);\n }\n return new Promise<void>((resolve, reject) => {\n this.queue.push({ resolve, reject });\n w.postMessage({\n kind: 'send',\n payload: event,\n url,\n } satisfies WorkerMsgIn);\n });\n }\n\n /** 批量发送(worker 内聚合) */\n async sendBatch(events: EventData[], ctx: SendContext): Promise<void> {\n const url = Array.isArray(ctx.config.server_url) ? ctx.config.server_url[0] : ctx.config.server_url;\n const w = this.getWorker();\n if (!w) {\n const { AjaxSender } = await import('./ajax-sender.js');\n if (!this.fallback) this.fallback = new AjaxSender();\n return (this.fallback as { sendBatch?: (events: EventData[], ctx: SendContext) => Promise<void> }).sendBatch?.(events, ctx);\n }\n return new Promise<void>((resolve, reject) => {\n this.queue.push({ resolve, reject });\n w.postMessage({\n kind: 'sendBatch',\n payload: events,\n url,\n } satisfies WorkerMsgIn);\n });\n }\n\n /** 关闭 worker */\n destroy(): void {\n if (this.worker) {\n this.worker.postMessage({ kind: 'shutdown' } satisfies WorkerMsgIn);\n this.worker.terminate();\n this.worker = null;\n }\n }\n}","/**\n * WebSocket Sender(v1.3.0)\n *\n * - 长连接上报,适合实时数据\n * - 支持服务端反向下发配置(dynamic config)\n * - 自动重连(指数退避)\n * - 离线时本地缓冲\n */\n\nimport type { Sender, SendContext } from './sender.js';\nimport type { EventData, TrackerConfig } from '../types/index.js';\n\ninterface WSMessage {\n kind: 'event' | 'batch' | 'ack' | 'config';\n data?: unknown;\n}\n\nexport interface WebSocketSenderOptions {\n /** WS 服务地址 */\n url: string;\n /** 鉴权 token(首条消息携带) */\n authToken?: string;\n /** 重连延迟上限(ms) */\n maxReconnectMs?: number;\n /** 离线缓冲上限 */\n maxBuffer?: number;\n}\n\nexport class WebSocketSender implements Sender {\n name = 'ws' as const;\n private ws: WebSocket | null = null;\n private buffer: EventData[] = [];\n private reconnectDelay = 1000;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private configCb: ((cfg: Partial<TrackerConfig>) => void) | null = null;\n\n constructor(private opts: WebSocketSenderOptions) {}\n\n canUse(): boolean {\n return typeof (globalThis as { WebSocket?: unknown }).WebSocket === 'function';\n }\n\n connect(): void {\n if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) return;\n try {\n this.ws = new WebSocket(this.opts.url);\n } catch {\n this.scheduleReconnect();\n return;\n }\n this.ws.onopen = () => {\n this.reconnectDelay = 1000;\n // 鉴权\n if (this.opts.authToken) {\n this.safeSend({ kind: 'event', data: { _auth: this.opts.authToken } } as WSMessage);\n }\n // flush buffer\n const take = this.buffer.splice(0);\n for (const e of take) this.safeSend({ kind: 'event', data: e });\n };\n this.ws.onmessage = (e) => {\n try {\n const msg = JSON.parse(typeof e.data === 'string' ? e.data : '{}') as WSMessage;\n if (msg.kind === 'config' && msg.data) {\n this.configCb?.(msg.data as Partial<TrackerConfig>);\n }\n } catch { /* ignore */ }\n };\n this.ws.onerror = () => {\n this.scheduleReconnect();\n };\n this.ws.onclose = () => {\n this.scheduleReconnect();\n };\n }\n\n onConfig(cb: (cfg: Partial<TrackerConfig>) => void): void {\n this.configCb = cb;\n }\n\n async send(event: EventData, _ctx: SendContext): Promise<void> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n this.buffer.push(event);\n if (this.buffer.length > (this.opts.maxBuffer ?? 1000)) this.buffer.shift();\n if (!this.ws) this.connect();\n return;\n }\n this.safeSend({ kind: 'event', data: event });\n }\n\n async sendBatch(events: EventData[], _ctx: SendContext): Promise<void> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n this.buffer.push(...events);\n if (!this.ws) this.connect();\n return;\n }\n this.safeSend({ kind: 'batch', data: events });\n }\n\n close(): void {\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n if (this.ws) {\n this.ws.onclose = null;\n this.ws.close();\n this.ws = null;\n }\n }\n\n private safeSend(msg: WSMessage): void {\n try {\n this.ws?.send(JSON.stringify(msg));\n } catch {\n // 发送失败,回滚\n if (msg.kind === 'event' && msg.data) this.buffer.unshift(msg.data as EventData);\n if (msg.kind === 'batch' && Array.isArray(msg.data)) this.buffer.unshift(...(msg.data as EventData[]));\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return;\n const delay = Math.min(this.reconnectDelay, this.opts.maxReconnectMs ?? 30000);\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.opts.maxReconnectMs ?? 30000);\n this.connect();\n }, delay);\n }\n}","/**\n * session-event 插件:会话管理\n * - 每条事件附 $event_session_id(首次访问生成,存 storage)\n * - $session_start / $session_end 事件\n * - 超时(默认 30 分钟)则重开会话\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport type { StageContext, StageInterceptor } from '../../core/stage.js';\nimport { isBrowser } from '../../core/env.js';\nimport { PresetEvent, PresetProperty } from '../../types/constants.js';\nimport { uuidv4 } from '../../core/uuid.js';\nimport type { EventData } from '../../types/index.js';\nimport type { KVStore } from '../../storage/store.js';\n\nconst SESSION_KEY = 'et_session_id';\nconst SESSION_LAST_KEY = 'et_session_last_active';\nconst DEFAULT_TIMEOUT = 30 * 60 * 1000; // 30 分钟\n\nexport interface SessionOptions {\n /** 会话超时(ms) */\n timeout?: number;\n /** 是否在超时上报 $session_end */\n endOnTimeout?: boolean;\n}\n\nexport function sessionEvent(opts: SessionOptions = {}): Plugin {\n const timeout = opts.timeout ?? DEFAULT_TIMEOUT;\n let sdkRef: import('../../core/tracker.js').EventTracker | null = null;\n let storeRef: KVStore | null = null;\n let sessionId = '';\n let lastActive = 0;\n\n function newSession(reason: 'start' | 'timeout'): void {\n sessionId = uuidv4();\n lastActive = Date.now();\n if (storeRef) {\n storeRef.set(SESSION_KEY, sessionId);\n storeRef.set(SESSION_LAST_KEY, String(lastActive));\n }\n if (sdkRef && reason === 'start') {\n sdkRef.track('$session_start', { $event_session_id: sessionId });\n }\n }\n\n function check(): void {\n const now = Date.now();\n if (!sessionId || (lastActive && now - lastActive > timeout)) {\n newSession(now - lastActive > timeout ? 'timeout' : 'start');\n }\n lastActive = now;\n if (storeRef) storeRef.set(SESSION_LAST_KEY, String(lastActive));\n }\n\n const interceptor: StageInterceptor<unknown> = {\n name: 'session-event',\n priority: 10, // 早于业务拦截器\n entry(ctx: StageContext<unknown>) {\n if (ctx.meta.stage !== 'buildDataStage') return;\n check();\n const ev = ctx.data as EventData;\n if (ev && ev.properties) {\n ev.properties[PresetProperty.EventSessionId] = sessionId;\n }\n },\n };\n\n return {\n name: 'session-event',\n install({ sdk, stages, store }) {\n if (!isBrowser()) return;\n sdkRef = sdk;\n storeRef = store;\n\n // 读已有\n const existing = store.get(SESSION_KEY);\n const last = Number(store.get(SESSION_LAST_KEY) || '0');\n if (existing && last && Date.now() - last < timeout) {\n sessionId = existing;\n lastActive = last;\n } else {\n newSession('start');\n }\n\n stages.buildDataStage.register(interceptor);\n\n // 跨 tab 同步:通过 storage 事件检测其它 tab 关闭\n window.addEventListener('storage', (ev) => {\n if (ev.key === SESSION_KEY && !ev.newValue) {\n // 其它 tab 关闭了会话,本地也清掉\n sessionId = '';\n }\n });\n },\n uninstall() {\n sdkRef = null;\n storeRef = null;\n },\n };\n}","/**\n * encrypt 插件(v1.1 增强版)\n *\n * 三个能力:\n * 1. 加密 + 解密配对(神策风格)\n * - config.encryptor / config.decoder\n * - 加密函数接收 JSON 字符串返回字符串;解密函数反向\n *\n * 2. Web Crypto AES-GCM\n * - aesGcmEncrypt / aesGcmDecrypt\n * - 基于 Web Crypto API,256-bit key,输出 base64(iv||ciphertext)\n *\n * 3. 钩子:encryptEvent / decryptEvent\n * - 用于在事件被发送前/接收后做二次处理(脱敏、补字段等)\n *\n * 用法示例:\n * import { encryptor, aesGcmEncrypt, aesGcmDecrypt } from '@macroui/event-tracker/plugin/encrypt';\n * const key = 'my-32-byte-secret-key-1234567890ab';\n * sdk.use(encryptor({\n * encrypt: aesGcmEncrypt(key),\n * decrypt: aesGcmDecrypt(key),\n * encryptEvent: (e) => scrubPII(e),\n * decryptEvent: (e) => e,\n * }));\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport type { EventData } from '../../types/index.js';\n\nexport type EncryptFn = (data: string) => string;\nexport type DecryptFn = (data: string) => string;\nexport type EventTransform = (event: EventData) => EventData | unknown;\n\nexport interface EncryptorOptions {\n /** 加密:JSON 字符串 -> 字符串 */\n encrypt: EncryptFn;\n /** 解密:字符串 -> JSON 字符串(可选;多数场景 SDK 不下行) */\n decrypt?: DecryptFn;\n /** 事件级加密前钩子(脱敏、补字段) */\n encryptEvent?: EventTransform;\n /** 事件级解密后钩子(一般用于 debug 拉回来的事件) */\n decryptEvent?: EventTransform;\n}\n\n// ============================================================\n// 1. XOR + Base64(兼容 v1.0,作为默认简易实现)\n// ============================================================\n\nfunction xorBase64(input: string, key: string): string {\n const k = key || 'default';\n let out = '';\n for (let i = 0; i < input.length; i++) {\n out += String.fromCharCode(input.charCodeAt(i) ^ k.charCodeAt(i % k.length));\n }\n if (typeof btoa !== 'undefined') return btoa(out);\n return Buffer.from(out, 'binary').toString('base64');\n}\n\nexport function defaultEncryptor(key: string): EncryptFn {\n return (data) => xorBase64(data, key);\n}\n\nexport function defaultDecryptor(key: string): DecryptFn {\n return (data) => {\n const bin = typeof atob !== 'undefined' ? atob(data) : Buffer.from(data, 'base64').toString('binary');\n let out = '';\n const k = key || 'default';\n for (let i = 0; i < bin.length; i++) {\n out += String.fromCharCode(bin.charCodeAt(i) ^ k.charCodeAt(i % k.length));\n }\n return out;\n };\n}\n\nexport { xorBase64 };\n\n// ============================================================\n// 2. AES-GCM(Web Crypto API;需要 https / localhost)\n// ============================================================\n\nconst ENC = new TextEncoder();\nconst DEC = new TextDecoder();\n\nfunction bytesToB64(bytes: Uint8Array): string {\n if (typeof btoa !== 'undefined') {\n let s = '';\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\n return btoa(s);\n }\n return Buffer.from(bytes).toString('base64');\n}\n\nfunction b64ToBytes(b64: string): Uint8Array {\n if (typeof atob !== 'undefined') {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n }\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\nasync function importAesKey(rawKey: string): Promise<CryptoKey> {\n // 把字符串 key 哈希成 256-bit raw key\n const subtle = getSubtle();\n const hash = await subtle.digest('SHA-256', ENC.encode(rawKey));\n return subtle.importKey('raw', hash, { name: 'AES-GCM' }, false, ['encrypt', 'decrypt']);\n}\n\nfunction getSubtle(): SubtleCrypto {\n if (typeof globalThis !== 'undefined' && (globalThis as { crypto?: Crypto }).crypto?.subtle) {\n return (globalThis as { crypto: Crypto }).crypto.subtle;\n }\n // node 18+ 的 webcrypto\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { webcrypto } = require('crypto');\n (globalThis as { crypto: typeof webcrypto }).crypto = webcrypto;\n return webcrypto.subtle;\n } catch {\n throw new Error('[encrypt] Web Crypto API not available (need https/localhost or Node 18+)');\n }\n}\n\n/** AES-GCM 加密(同步 API 抛错;改用 Async 版本)\n * @deprecated Web Crypto API 是异步的,同步签名不现实;\n * 改用 aesGcmEncryptAsync + asyncSend helper,或预计算密文。\n */\nexport function aesGcmEncrypt(_rawKey: string): EncryptFn {\n return () => {\n throw new Error('[encrypt] Web Crypto subtle.encrypt is async-only; use aesGcmEncryptAsync and send via asyncSend()');\n };\n}\n\n/** AES-GCM 加密(异步版):返回 Promise<string> */\nexport function aesGcmEncryptAsync(rawKey: string): (data: string) => Promise<string> {\n let keyPromise: Promise<CryptoKey> | null = null;\n return async (data: string): Promise<string> => {\n if (!keyPromise) keyPromise = importAesKey(rawKey);\n const key = await keyPromise;\n const subtle = getSubtle();\n const iv = (globalThis as { crypto: Crypto }).crypto.getRandomValues(new Uint8Array(12));\n const cipher = new Uint8Array(\n await subtle.encrypt({ name: 'AES-GCM', iv }, key, ENC.encode(data)),\n );\n const out = new Uint8Array(iv.length + cipher.length);\n out.set(iv, 0);\n out.set(cipher, iv.length);\n return bytesToB64(out);\n };\n}\n\n/** AES-GCM 解密(异步版) */\nexport function aesGcmDecryptAsync(rawKey: string): (data: string) => Promise<string> {\n let keyPromise: Promise<CryptoKey> | null = null;\n return async (data: string): Promise<string> => {\n if (!keyPromise) keyPromise = importAesKey(rawKey);\n const key = await keyPromise;\n const subtle = getSubtle();\n const raw = b64ToBytes(data);\n const iv = raw.slice(0, 12);\n const cipher = raw.slice(12);\n const plain = await subtle.decrypt({ name: 'AES-GCM', iv }, key, cipher);\n return DEC.decode(plain);\n };\n}\n\n// ============================================================\n// 3. 插件\n// ============================================================\n\nexport function encryptor(opts: EncryptorOptions): Plugin {\n return {\n name: 'encryptor',\n install({ sdk, config }) {\n // 写入 config;tracker.sendEvent 会自动调用\n config.encryptor = opts.encrypt;\n config.decoder = opts.decrypt;\n // config.encryptEvent/decryptEvent 在 TrackerConfig 里是宽松的 Record<string,unknown> 函数\n const cfg = config as unknown as {\n encryptEvent?: EventTransform;\n decryptEvent?: EventTransform;\n };\n cfg.encryptEvent = opts.encryptEvent;\n cfg.decryptEvent = opts.decryptEvent;\n // 保留到 sdk 上,供调试 / 二次使用\n const ref = sdk as unknown as {\n __encryptor?: EncryptFn;\n __decoder?: DecryptFn;\n __encryptEvent?: EventTransform;\n __decryptEvent?: EventTransform;\n };\n ref.__encryptor = opts.encrypt;\n ref.__decoder = opts.decrypt;\n ref.__encryptEvent = opts.encryptEvent;\n ref.__decryptEvent = opts.decryptEvent;\n },\n uninstall(ctx) {\n if (!ctx) return;\n const { config, sdk } = ctx;\n delete config.encryptor;\n delete config.decoder;\n const cfg = config as unknown as {\n encryptEvent?: EventTransform;\n decryptEvent?: EventTransform;\n };\n delete cfg.encryptEvent;\n delete cfg.decryptEvent;\n const ref = sdk as unknown as Record<string, unknown>;\n delete ref.__encryptor;\n delete ref.__decoder;\n delete ref.__encryptEvent;\n delete ref.__decryptEvent;\n },\n };\n}\n\n/** 便捷工厂:XOR 配对 */\nexport function xorEncryptor(key: string): Plugin {\n return encryptor({ encrypt: defaultEncryptor(key), decrypt: defaultDecryptor(key) });\n}","/**\n * OpenTelemetry Bridge Plugin (v1.2.0)\n *\n * 把 SDK 事件转发到 OTel:\n * - track → otel tracer.startActiveSpan\n * - 用 @opentelemetry/api 作为可选 peer dependency\n * - 通过 dynamic import 兼容未安装 OTel 的场景\n * - 属性透传:event 类型 / properties → span attributes\n * - 支持自定义 mapper\n */\n\nimport type { Plugin, InstallContext } from '../../core/plugin.js';\nimport type { StageContext, StageInterceptor } from '../../core/stage.js';\n\nexport interface OtelBridgeOptions {\n /** tracer 名(默认 '@macroui/event-tracker') */\n tracerName?: string;\n /** span 名映射:(eventName) => spanName,默认 = eventName */\n spanName?: (event: string) => string;\n /** 属性过滤:返回 false 的属性不上报 */\n filterAttr?: (key: string, value: unknown) => boolean;\n /** 全局关闭 */\n enabled?: boolean;\n}\n\n/**\n * 尝试 dynamic import @opentelemetry/api\n * 成功返回 { trace, context },失败返回 null\n */\nasync function tryLoadOtel(): Promise<{\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trace: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n context: any;\n} | null> {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = await (Function('return import(\"@opentelemetry/api\")')() as Promise<any>);\n if (mod && mod.trace && mod.context) return mod;\n return null;\n } catch {\n return null;\n }\n}\n\nexport function otelBridge(opts: OtelBridgeOptions = {}): Plugin {\n return {\n name: 'otel-bridge',\n async install({ stages }: InstallContext) {\n if (opts.enabled === false) return;\n const otel = await tryLoadOtel();\n if (!otel) {\n // eslint-disable-next-line no-console\n console.warn('[otel-bridge] @opentelemetry/api not found, plugin noop');\n return;\n }\n const tracer = otel.trace.getTracer(opts.tracerName || '@macroui/event-tracker');\n const spanName = opts.spanName || ((e: string) => e);\n const filter = opts.filterAttr || (() => true);\n\n const interceptor: StageInterceptor<unknown> = {\n name: 'otel-bridge',\n priority: 40,\n entry(ctx: StageContext<unknown>) {\n if (ctx.meta.stage !== 'sendDataStage') return ctx.data;\n const ev = ctx.data as { event?: string; properties?: Record<string, unknown>; type?: string };\n const eventName = ev.event || ev.type || 'event';\n const span = tracer.startSpan(spanName(eventName), {\n attributes: {\n 'et.event.name': eventName,\n 'et.event.type': ev.type || '',\n 'et.event.time': Date.now(),\n },\n });\n const props = ev.properties || {};\n for (const [k, v] of Object.entries(props)) {\n if (!filter(k, v)) continue;\n try {\n span.setAttribute(`et.${k}`, v as never);\n } catch {\n /* ignore */\n }\n }\n // span 立刻结束(事件级 trace)\n span.end();\n return ctx.data;\n },\n };\n stages.sendDataStage.register(interceptor);\n },\n };\n}","/**\n * OpenTelemetry Exporter (v1.3.0)\n *\n * - OTLP/HTTP + OTLP/gRPC 两种协议\n * - 把 EventTracker 事件 → OTel Span\n * - 不依赖 @opentelemetry/api(内部实现)\n * - 可独立 import:@macroui/event-tracker/plugin/otel-exporter\n */\n\nexport interface OtlpHttpOptions {\n endpoint: string; // 如 https://otel.example.com/v1/traces\n headers?: Record<string, string>;\n /** gzip */\n gzip?: boolean;\n /** timeout (ms) */\n timeoutMs?: number;\n}\n\nexport interface SpanData {\n name: string;\n kind?: 'SPAN_KIND_INTERNAL' | 'SPAN_KIND_CLIENT' | 'SPAN_KIND_SERVER';\n startTimeUnixNano: bigint | number;\n endTimeUnixNano: bigint | number;\n attributes: Array<{ key: string; value: { stringValue?: string; intValue?: number | bigint; boolValue?: boolean } }>;\n traceId: string;\n spanId: string;\n}\n\nexport interface OtelEvent {\n name: string;\n properties?: Record<string, unknown>;\n time: number;\n distinctId?: string;\n}\n\nfunction toHexId(num: number | bigint, len: number): string {\n const hex = BigInt(num).toString(16).padStart(len, '0');\n return hex.slice(-len);\n}\n\nfunction rand16(): string {\n const arr = new Uint8Array(8);\n crypto.getRandomValues(arr);\n let hex = '';\n for (const b of arr) hex += b.toString(16).padStart(2, '0');\n return hex;\n}\n\nfunction attrValue(v: unknown): { stringValue?: string; intValue?: number; boolValue?: boolean } {\n if (typeof v === 'string') return { stringValue: v };\n if (typeof v === 'number') return { intValue: Number.isFinite(v) ? v : 0 };\n if (typeof v === 'boolean') return { boolValue: v };\n return { stringValue: JSON.stringify(v) };\n}\n\nexport function eventToSpan(ev: OtelEvent): SpanData {\n const start = ev.time * 1_000_000; // ms → ns\n const end = (ev.time + 1) * 1_000_000; // 占 1ms\n const traceId = rand16() + rand16();\n const spanId = rand16();\n const attrs: SpanData['attributes'] = [\n { key: 'et.event.name', value: { stringValue: ev.name } },\n { key: 'et.event.time', value: { intValue: ev.time } },\n ];\n if (ev.distinctId) attrs.push({ key: 'enduser.id', value: { stringValue: ev.distinctId } });\n for (const [k, v] of Object.entries(ev.properties || {})) {\n attrs.push({ key: `et.${k}`, value: attrValue(v) });\n }\n return {\n name: ev.name,\n startTimeUnixNano: start,\n endTimeUnixNano: end,\n attributes: attrs,\n traceId,\n spanId,\n };\n}\n\nexport async function exportOtlpHttp(events: OtelEvent[], opts: OtlpHttpOptions): Promise<void> {\n const spans = events.map(eventToSpan);\n const body = {\n resourceSpans: [{\n resource: {\n attributes: [\n { key: 'service.name', value: { stringValue: 'event-tracker' } },\n { key: 'service.version', value: { stringValue: '1.3.0' } },\n ],\n },\n scopeSpans: [{\n scope: { name: '@macroui/event-tracker', version: '1.3.0' },\n spans: spans.map(s => ({\n ...s,\n startTimeUnixNano: String(s.startTimeUnixNano),\n endTimeUnixNano: String(s.endTimeUnixNano),\n traceId: s.traceId,\n spanId: s.spanId,\n })),\n }],\n }],\n };\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 5000);\n try {\n const res = await fetch(opts.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(opts.headers || {}),\n },\n body: JSON.stringify(body),\n signal: ctrl.signal,\n });\n if (!res.ok) {\n throw new Error(`OTLP HTTP ${res.status}`);\n }\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** OTel Exporter Plugin 形态 */\nexport interface OtelExporterOptions extends OtlpHttpOptions {\n /** 上报前过滤 */\n filter?: (ev: OtelEvent) => boolean;\n /** 批量上报:攒够 N 条 / T ms 触发 */\n batchSize?: number;\n batchIntervalMs?: number;\n}\n\nimport type { Plugin } from '../../core/plugin.js';\n\nexport function otelExporter(opts: OtelExporterOptions): Plugin {\n let buffer: OtelEvent[] = [];\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n async function flush() {\n if (!buffer.length) return;\n const take = buffer.splice(0, buffer.batchSize || 100);\n try {\n await exportOtlpHttp(take, opts);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('[otelExporter] export failed:', e);\n }\n }\n\n function schedule() {\n if (timer) return;\n timer = setTimeout(() => {\n timer = null;\n void flush();\n }, opts.batchIntervalMs ?? 5000);\n }\n\n return {\n name: 'otel-exporter',\n install({ sdk }) {\n const orig = (sdk as unknown as { track: (e: string, p?: Record<string, unknown>) => void }).track;\n (sdk as unknown as { track: typeof orig }).track = function (event: string, properties?: Record<string, unknown>) {\n try {\n const ev: OtelEvent = {\n name: event,\n properties,\n time: Date.now(),\n distinctId: (sdk as unknown as { getDistinctId?: () => string }).getDistinctId?.(),\n };\n if (!opts.filter || opts.filter(ev)) {\n buffer.push(ev);\n if (buffer.length >= (opts.batchSize || 100)) {\n void flush();\n } else {\n schedule();\n }\n }\n } catch { /* ignore */ }\n return orig.call(this, event, properties);\n };\n },\n uninstall() {\n if (timer) clearTimeout(timer);\n timer = null;\n buffer = [];\n },\n };\n}","/**\n * A/B Test / 实验埋点 helper(v1.2.0)\n *\n * 提供:\n * - sdk.experiment(key, variants): 根据 variants 配置确定分组,sticky(localStorage)\n * - 每次 track 时自动注入 $experiment_key / $variant_id\n * - 支持曝光事件:exposure(key, variant)\n * - 不依赖外部实验平台 SDK\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport type { StorageType } from '../../types/index.js';\n\nexport interface ExperimentVariant {\n /** 实验分组 id */\n id: string;\n /** 权重(数字,绝对值或 0-100 百分比) */\n weight?: number;\n /** 默认附加的 properties(会 merge 到事件 properties) */\n properties?: Record<string, unknown>;\n}\n\nexport interface ExperimentOptions {\n /** 自定义存储前缀 */\n storagePrefix?: string;\n /** 存储类型(默认 localStorage) */\n storage?: StorageType;\n}\n\nconst memoryFallback = new Map<string, string>();\n\nfunction getStored(key: string): string | null {\n try {\n if (typeof window !== 'undefined' && window.localStorage) {\n return window.localStorage.getItem(key);\n }\n } catch { /* ignore */ }\n return memoryFallback.get(key) ?? null;\n}\n\nfunction setStored(key: string, value: string): void {\n try {\n if (typeof window !== 'undefined' && window.localStorage) {\n window.localStorage.setItem(key, value);\n return;\n }\n } catch { /* ignore */ }\n memoryFallback.set(key, value);\n}\n\n/** 工具:hash 0-1(简单的字符串 hash) */\nfunction hash01(s: string): number {\n let h = 2166136261;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n // 转成 [0,1)\n return ((h >>> 0) % 1_000_000) / 1_000_000;\n}\n\nexport interface ExperimentContext {\n /** 拉取指定实验的分组(无配置返回 null) */\n variantOf: (key: string) => ExperimentVariant | null;\n /** 直接获取 variant id */\n variantIdOf: (key: string) => string | null;\n /** 上报曝光(一次会话只上报一次) */\n exposure: (key: string, properties?: Record<string, unknown>) => void;\n /** 强制设置(debug 用) */\n forceSet: (key: string, variantId: string) => void;\n /** 列出当前所有已分配 */\n list: () => Record<string, string>;\n}\n\n/**\n * 创建实验上下文(不依赖 SDK,可单独用)\n */\nexport function createExperiment(\n experiments: Record<string, ExperimentVariant[]>,\n opts: ExperimentOptions = {},\n): ExperimentContext {\n const prefix = opts.storagePrefix || '__et_exp_';\n const exposedKey = (k: string) => `${prefix}exp_${k}`;\n const variantKey = (k: string) => `${prefix}var_${k}`;\n\n function variantOf(key: string): ExperimentVariant | null {\n const variants = experiments[key];\n if (!variants || !variants.length) return null;\n // 已 sticky\n const stored = getStored(variantKey(key));\n if (stored) {\n const v = variants.find(x => x.id === stored);\n if (v) return v;\n }\n // 按权重分桶\n const totalW = variants.reduce((s, v) => s + (v.weight ?? 1), 0);\n const r = hash01(`${key}:${Math.random()}`) * totalW;\n let acc = 0;\n let chosen = variants[variants.length - 1];\n for (const v of variants) {\n acc += v.weight ?? 1;\n if (r <= acc) {\n chosen = v;\n break;\n }\n }\n setStored(variantKey(key), chosen.id);\n return chosen;\n }\n\n return {\n variantOf,\n variantIdOf: (k) => variantOf(k)?.id ?? null,\n exposure: (k, properties) => {\n if (typeof window === 'undefined') return;\n const expKey = exposedKey(k);\n const flag = getStored(expKey);\n if (flag) return; // 同一会话已曝光\n setStored(expKey, String(Date.now()));\n const v = variantOf(k);\n try {\n const sdk = (window as unknown as { eventTracker?: { track?: (e: string, p?: Record<string, unknown>) => void } }).eventTracker;\n sdk?.track?.('$ExperimentExposure', {\n $experiment_key: k,\n $variant_id: v?.id,\n $is_first_exposure: true,\n ...(properties || {}),\n });\n } catch { /* ignore */ }\n },\n forceSet: (k, vid) => setStored(variantKey(k), vid),\n list: () => {\n const out: Record<string, string> = {};\n for (const k of Object.keys(experiments)) {\n const v = variantOf(k);\n if (v) out[k] = v.id;\n }\n return out;\n },\n };\n}\n\n/** 插件形态:把 experiment 注入到事件 properties */\nexport function experiment(\n experiments: Record<string, ExperimentVariant[]>,\n opts: ExperimentOptions = {},\n): Plugin {\n const ctx = createExperiment(experiments, opts);\n return {\n name: 'experiment',\n install({ sdk, stages }) {\n (sdk as unknown as { experiment?: ExperimentContext }).experiment = ctx;\n stages.sendDataStage.register({\n name: 'experiment-inject',\n priority: 80,\n entry(stageCtx) {\n if (stageCtx.meta.stage !== 'sendDataStage') return stageCtx.data;\n const ev = stageCtx.data as { properties?: Record<string, unknown>; event?: string };\n const props = { ...(ev.properties || {}) };\n // 对每个实验查询分组并注入(只对第一个匹配 key 做强制注入,其余按需)\n for (const [key, v] of Object.entries(experiments)) {\n const variant = ctx.variantOf(key);\n if (!variant) continue;\n props[`$exp__${key}`] = variant.id;\n // 用户自定义 variant properties 合并\n if (variant.properties) Object.assign(props, variant.properties);\n }\n return { ...ev, properties: props };\n },\n });\n },\n };\n}","/**\n * Predictive Batching(v1.2.0)\n *\n * - 监听 user activity(click/scroll/keypress/mousemove 节流)\n * - 高活动期:缩短 batch flush 间隔\n * - 低活动期:拉长间隔,省电 / 省流量\n * - 通过 SDK config.batch_send.dynamic_interval 启用\n *\n * 不属于 SDK 强耦合:作为可选插件\n */\n\nimport type { Plugin } from '../../core/plugin.js';\n\nexport interface PredictiveBatchOptions {\n /** 最小间隔(活动期) */\n minInterval?: number;\n /** 最大间隔(静默期) */\n maxInterval?: number;\n /** 活动统计窗口(ms) */\n windowMs?: number;\n /** 活动阈值(窗口内事件 > 此数视为活动期) */\n activityThreshold?: number;\n /** 是否监听这些事件类型 */\n events?: ('click' | 'scroll' | 'keypress' | 'mousemove' | 'touchstart')[];\n}\n\n/**\n * 不修改 SDK 内部,而是提供一个工具函数 getInterval(opts)\n * 业务侧在 BatchSender.flush interval 决策时调用\n */\nexport function makeIntervalPredictor(opts: PredictiveBatchOptions = {}): () => number {\n const min = opts.minInterval ?? 1000;\n const max = opts.maxInterval ?? 30000;\n const winMs = opts.windowMs ?? 5000;\n const threshold = opts.activityThreshold ?? 5;\n const events = opts.events ?? ['click', 'scroll', 'keypress'];\n const counts: number[] = [];\n\n if (typeof window !== 'undefined') {\n const handler = () => {\n const now = Date.now();\n counts.push(now);\n while (counts.length && now - counts[0] > winMs) counts.shift();\n };\n for (const e of events) window.addEventListener(e, handler, { passive: true });\n }\n\n return () => {\n if (counts.length > threshold) return min;\n if (counts.length > 0) return Math.round(min + (max - min) * (1 - counts.length / threshold));\n return max;\n };\n}\n\nexport function predictiveBatcher(opts: PredictiveBatchOptions = {}): Plugin {\n const predict = makeIntervalPredictor(opts);\n return {\n name: 'predictive-batcher',\n install({ config }) {\n // 把 dynamic_interval 计算器挂到 config(BatchSender 可选读取)\n (config as unknown as { batch_send_predict?: () => number }).batch_send_predict = predict;\n },\n };\n}","/**\n * Schema Registry 校验(v1.3.0)\n *\n * - 内置默认 schemas:pageview / track / profile_set\n * - 支持自定义 schemas:schema({eventName, jsonSchema})\n * - 远程 schema URL:服务端可下发(带 ETag 缓存)\n * - 校验失败:默认 warn + 仍上报(可配置 drop)\n * - 动态 import ajv,未安装时 noop\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport type { StageContext, StageInterceptor } from '../../core/stage.js';\n\nexport interface SchemaEntry {\n /** 事件名 */\n event: string;\n /** JSON Schema(Draft-07 兼容) */\n schema: Record<string, unknown>;\n}\n\nexport interface SchemaOptions {\n /** 自定义 schemas */\n schemas?: SchemaEntry[];\n /** 远程 schema URL(HTTP 拉取,带 ETag) */\n remoteUrl?: string;\n /** 校验失败处理 */\n onInvalid?: 'warn' | 'drop' | 'pass';\n /** 远程 schema TTL(ms),默认 1h */\n remoteTtlMs?: number;\n}\n\ninterface AjvLike {\n compile: (schema: object) => (data: unknown) => boolean;\n errors?: unknown[];\n}\n\nasync function tryLoadAjv(): Promise<AjvLike | null> {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = await (Function('return import(\"ajv\")')() as Promise<any>);\n if (mod && mod.default) {\n const Ajv = mod.default;\n const ajv = new Ajv({ allErrors: true, strict: false });\n return ajv as unknown as AjvLike;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport class SchemaRegistry {\n private ajv: AjvLike | null = null;\n private entries = new Map<string, (data: unknown) => boolean>();\n private remoteCache: { url: string; etag?: string; schemas: SchemaEntry[]; ts: number } | null = null;\n\n constructor(private opts: SchemaOptions) {}\n\n async init(): Promise<void> {\n this.ajv = await tryLoadAjv();\n if (!this.ajv) return;\n for (const e of this.opts.schemas || []) this.add(e);\n if (this.opts.remoteUrl) await this.fetchRemote();\n }\n\n add(entry: SchemaEntry): void {\n if (!this.ajv) return;\n const validate = this.ajv.compile(entry.schema);\n this.entries.set(entry.event, validate);\n }\n\n private async fetchRemote(): Promise<void> {\n if (!this.opts.remoteUrl) return;\n const ttl = this.opts.remoteTtlMs ?? 3600_000;\n if (this.remoteCache && Date.now() - this.remoteCache.ts < ttl) {\n for (const e of this.remoteCache.schemas) this.add(e);\n return;\n }\n try {\n const headers: Record<string, string> = {};\n if (this.remoteCache?.etag) headers['If-None-Match'] = this.remoteCache.etag;\n const r = await fetch(this.opts.remoteUrl, { headers });\n if (r.status === 304 && this.remoteCache) {\n this.remoteCache.ts = Date.now();\n for (const e of this.remoteCache.schemas) this.add(e);\n return;\n }\n if (!r.ok) return;\n const etag = r.headers.get('ETag') || undefined;\n const data = await r.json();\n const list: SchemaEntry[] = Array.isArray(data) ? data : (data.schemas || []);\n this.remoteCache = { url: this.opts.remoteUrl, etag, schemas: list, ts: Date.now() };\n for (const e of list) this.add(e);\n } catch {\n /* ignore */\n }\n }\n\n validate(event: string, data: unknown): { ok: boolean; errors?: unknown[] } {\n const fn = this.entries.get(event);\n if (!fn) return { ok: true };\n const ok = fn(data);\n return { ok, errors: ok ? undefined : (this.ajv?.errors || []) };\n }\n}\n\nexport function schemaRegistry(opts: SchemaOptions = {}): Plugin {\n let registry: SchemaRegistry | null = null;\n\n return {\n name: 'schema-registry',\n async install({ stages, logger }) {\n registry = new SchemaRegistry(opts);\n await registry.init();\n const onInvalid = opts.onInvalid || 'warn';\n\n const interceptor: StageInterceptor<unknown> = {\n name: 'schema-registry',\n priority: 20,\n entry(ctx: StageContext<unknown>) {\n if (ctx.meta.stage !== 'sendDataStage') return ctx.data;\n if (!registry) return ctx.data;\n const ev = ctx.data as { event?: string; type?: string; properties?: Record<string, unknown> };\n const eventName = ev.event || ev.type || '';\n const { ok, errors } = registry.validate(eventName, ev.properties || {});\n if (!ok) {\n if (onInvalid === 'drop') return undefined;\n if (onInvalid === 'warn') logger.warn?.(`[Schema] invalid event '${eventName}':`, errors);\n // pass 模式:忽略错误继续上报\n }\n return ctx.data;\n },\n };\n stages.sendDataStage.register(interceptor);\n },\n uninstall() {\n registry = null;\n },\n };\n}","/**\n * Rate Limiter(v1.3.0)\n *\n * - 三档限流:\n * 1. 全局(global):每秒最多 N 条\n * 2. 用户级(user):每用户每秒最多 M 条\n * 3. per-event(event):每个事件名每秒最多 K 条\n * - 超出 drop + 触发 onDrop 回调\n * - 用滑动窗口(100ms bucket)实现\n */\n\nexport interface RateLimitRule {\n /** 时间窗口(ms) */\n windowMs: number;\n /** 窗口内最大条数 */\n max: number;\n}\n\nexport interface RateLimiterOptions {\n global?: RateLimitRule;\n user?: RateLimitRule;\n perEvent?: RateLimitRule;\n /** 触发 drop 回调 */\n onDrop?: (info: { scope: 'global' | 'user' | 'event'; key?: string; event?: string }) => void;\n}\n\ninterface Bucket {\n ts: number;\n count: number;\n}\n\nexport class RateLimiter {\n private globalBuckets: Bucket[] = [];\n private userBuckets = new Map<string, Bucket[]>();\n private eventBuckets = new Map<string, Bucket[]>();\n\n constructor(private opts: RateLimiterOptions) {}\n\n /** 是否允许 */\n allow(event: string, userId?: string): boolean {\n const now = Date.now();\n if (this.opts.global && !this.checkBucket(this.globalBuckets, this.opts.global, now)) {\n this.opts.onDrop?.({ scope: 'global' });\n return false;\n }\n if (this.opts.user && userId) {\n let arr = this.userBuckets.get(userId);\n if (!arr) { arr = []; this.userBuckets.set(userId, arr); }\n if (!this.checkBucket(arr, this.opts.user, now)) {\n this.opts.onDrop?.({ scope: 'user', key: userId });\n return false;\n }\n }\n if (this.opts.perEvent) {\n let arr = this.eventBuckets.get(event);\n if (!arr) { arr = []; this.eventBuckets.set(event, arr); }\n if (!this.checkBucket(arr, this.opts.perEvent, now)) {\n this.opts.onDrop?.({ scope: 'event', event });\n return false;\n }\n }\n return true;\n }\n\n private checkBucket(buckets: Bucket[], rule: RateLimitRule, now: number): boolean {\n const cutoff = now - rule.windowMs;\n while (buckets.length && buckets[0].ts < cutoff) buckets.shift();\n const current = buckets.reduce((s, b) => s + b.count, 0);\n if (current >= rule.max) return false;\n buckets.push({ ts: now, count: 1 });\n return true;\n }\n\n /** 清空所有 bucket */\n reset(): void {\n this.globalBuckets = [];\n this.userBuckets.clear();\n this.eventBuckets.clear();\n }\n}\n\nimport type { Plugin, InstallContext } from '../../core/plugin.js';\nimport type { StageContext, StageInterceptor } from '../../core/stage.js';\n\nexport function rateLimiter(opts: RateLimiterOptions): Plugin {\n let limiter: RateLimiter | null = null;\n\n return {\n name: 'rate-limiter',\n install({ stages, sdk }: InstallContext) {\n limiter = new RateLimiter(opts);\n const interceptor: StageInterceptor<unknown> = {\n name: 'rate-limiter',\n priority: 15,\n entry(ctx: StageContext<unknown>) {\n if (ctx.meta.stage !== 'sendDataStage') return ctx.data;\n const ev = ctx.data as { event?: string; type?: string; distinct_id?: string };\n const event = ev.event || ev.type || '';\n const userId = ev.distinct_id || (sdk as unknown as { getDistinctId?: () => string }).getDistinctId?.();\n if (!limiter!.allow(event, userId)) {\n return undefined; // drop\n }\n return ctx.data;\n },\n };\n stages.sendDataStage.register(interceptor);\n },\n uninstall() {\n limiter?.reset();\n limiter = null;\n },\n };\n}","/**\n * Audience Sync(v1.3.0)\n *\n * - 用户登录/属性变更后,把 distinct_id 同步到外部平台(Mailchimp / Braze / 自定义 webhook)\n * - 订阅式:sdk.on('identify', cb)\n * - 支持多 destination\n */\n\nexport interface AudienceDestination {\n name: string;\n endpoint: string;\n method?: 'POST' | 'PUT';\n headers?: Record<string, string>;\n /** 转换器:把 distinctId + props 转成目标平台格式 */\n transform?: (data: { distinct_id: string; properties: Record<string, unknown>; traits?: Record<string, unknown> }) => unknown;\n}\n\nexport interface AudienceSyncOptions {\n destinations: AudienceDestination[];\n /** 触发条件:'identify' | 'login' | 'all' */\n triggerOn?: 'identify' | 'login' | 'all';\n /** 失败重试次数 */\n maxRetry?: number;\n}\n\nexport interface AudienceContext {\n subscribe(fn: (data: { distinct_id: string; properties?: Record<string, unknown>; traits?: Record<string, unknown>; trigger: string }) => void): () => void;\n flush(): Promise<void>;\n queueSize(): number;\n}\n\nexport class AudienceSync {\n private listeners = new Set<(data: { distinct_id: string; properties?: Record<string, unknown>; traits?: Record<string, unknown>; trigger: string }) => void>();\n private pending: Array<{ distinct_id: string; properties?: Record<string, unknown>; traits?: Record<string, unknown>; trigger: string }> = [];\n\n constructor(public options: AudienceSyncOptions) {}\n\n subscribe(fn: (data: { distinct_id: string; properties?: Record<string, unknown>; traits?: Record<string, unknown>; trigger: string }) => void): () => void {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n emit(data: { distinct_id: string; properties?: Record<string, unknown>; traits?: Record<string, unknown>; trigger: string }): void {\n for (const l of this.listeners) {\n try { l(data); } catch { /* ignore */ }\n }\n }\n\n /** 缓存到队列(用于晚点批量) */\n enqueue(data: { distinct_id: string; properties?: Record<string, unknown>; traits?: Record<string, unknown>; trigger: string }): void {\n this.pending.push(data);\n }\n\n queueSize(): number { return this.pending.length; }\n\n /** 手动 flush:把队列里的事件推到所有 destination */\n async flush(): Promise<void> {\n if (!this.pending.length) return;\n const take = this.pending.splice(0);\n for (const d of this.options.destinations) {\n for (const ev of take) {\n await this.send(d, ev).catch(() => { /* ignore */ });\n }\n }\n }\n\n private async send(d: AudienceDestination, data: { distinct_id: string; properties?: Record<string, unknown>; traits?: Record<string, unknown>; trigger: string }): Promise<void> {\n const payload = d.transform\n ? d.transform(data)\n : data;\n const max = this.options.maxRetry ?? 2;\n for (let i = 0; i <= max; i++) {\n try {\n const r = await fetch(d.endpoint, {\n method: d.method || 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(d.headers || {}),\n },\n body: JSON.stringify(payload),\n keepalive: true,\n });\n if (r.ok) return;\n } catch { /* ignore retry */ }\n }\n }\n}\n\nimport type { Plugin, InstallContext } from '../../core/plugin.js';\n\nexport function audienceSync(options: AudienceSyncOptions): Plugin {\n let sync: AudienceSync | null = null;\n\n return {\n name: 'audience-sync',\n install({ sdk }: InstallContext) {\n sync = new AudienceSync(options);\n (sdk as unknown as { audience?: AudienceContext }).audience = sync;\n\n const origIdentify = (sdk as unknown as { identify?: (id: string, save?: boolean) => unknown }).identify?.bind(sdk);\n if (typeof origIdentify === 'function') {\n (sdk as unknown as { identify: typeof origIdentify }).identify = ((id: string, save?: boolean) => {\n const r = origIdentify(id, save);\n sync!.emit({ distinct_id: id, trigger: 'identify' });\n return r;\n }) as typeof origIdentify;\n }\n const origLogin = (sdk as unknown as { login?: (id: string) => unknown }).login?.bind(sdk);\n if (typeof origLogin === 'function') {\n (sdk as unknown as { login: typeof origLogin }).login = ((id: string) => {\n const r = origLogin(id);\n sync!.emit({ distinct_id: id, trigger: 'login' });\n return r;\n }) as typeof origLogin;\n }\n },\n uninstall() {\n sync = null;\n },\n };\n}","/**\n * 主入口:构造一个默认 SDK 实例(兼容神策风格的全局对象)\n *\n * 暴露:\n * - default export: 已经 attach 了所有 API 的全局单例\n * - EventTracker: 类,可以多实例\n * - named exports: 所有插件 / 工具\n */\n\nimport { EventTracker } from './core/tracker.js';\nimport { attachRegisterApi } from './core/register-api.js';\nimport { attachIdentityApi } from './core/identity-api.js';\nimport { attachProfileApi } from './core/profile-api.js';\nimport { attachTrackApi } from './core/track-api.js';\nimport { IdentityManager } from './core/identity.js';\nimport { PresetPropertyBuilder } from './presets/preset-properties.js';\nimport { PluginRegistry } from './core/plugin.js';\nimport { RetryPolicy } from './core/retry-policy.js';\nimport { FailedQueue } from './core/failed-queue.js';\nimport { InstanceChannel } from './core/instance-channel.js';\nimport { Logger } from './core/logger.js';\nimport { SendPipeline } from './core/send-pipeline.js';\nimport { PresetEvent, PresetProperty, LIB_NAME, LIB_VERSION } from './types/constants.js';\nimport type { TrackerConfig, EventData, SendType, StorageType, Callback } from './types/index.js';\n\n// 默认实例(神策风格的 window.eventTracker)\n// - 所有方法初始化为 noop(见 EventTracker 上的 default impl)\n// - init() 后被 attachXxxApi 替换\nconst tracker = new EventTracker();\n\nif (typeof window !== 'undefined') {\n (window as unknown as { eventTracker: EventTracker }).eventTracker = tracker;\n}\n\nexport default tracker;\nexport { tracker };\nexport { EventTracker };\n\n// 工厂 + 实例切换\nexport { initPara, registerAppid, listInstances } from './core/tracker.js';\n\n// 类型导出\nexport type {\n TrackerConfig,\n BaseConfig,\n SendConfig,\n StorageConfig,\n IdentityConfig,\n EncryptConfig,\n PresetConfig,\n DebugConfig,\n ObservabilityConfig,\n JsAppConfig,\n ClientConfig,\n DebugSenderConfig,\n EventData,\n SendType,\n StorageType,\n Callback,\n LogLevel,\n JSONValue,\n JSONObject,\n JSONArray,\n PropertyMap,\n ServerURL,\n StageName,\n HookName,\n} from './types/index.js';\n\nexport type { Plugin, InstallContext } from './core/plugin.js';\nexport type { StageInterceptor, StageContext, StageChain } from './core/stage.js';\nexport type { Lifecycle, HookFn } from './core/lifecycle.js';\n\n// 工具 / 错误\nexport {\n SDKError,\n InitError,\n SendError,\n EncryptError,\n IdentityError,\n StorageError,\n PluginError,\n ConfigError,\n isSDKError,\n} from './core/errors.js';\n\nexport {\n createSignedIdentity,\n hmacSignAsync,\n hmacVerifyAsync,\n} from './core/signed-identity.js';\nexport type { SignedIdentity } from './core/signed-identity.js';\n\n// 内部组件(高级用法)\nexport { SendPipeline } from './core/send-pipeline.js';\nexport { PluginRegistry } from './core/plugin.js';\nexport { RetryPolicy } from './core/retry-policy.js';\nexport { FailedQueue } from './core/failed-queue.js';\nexport { InstanceChannel } from './core/instance-channel.js';\nexport { Logger } from './core/logger.js';\nexport { IdentityManager } from './core/identity.js';\nexport { PresetPropertyBuilder } from './presets/preset-properties.js';\nexport { StatsCollector, GLOBAL_STATS } from './core/stats.js';\nexport type { StatsSnapshot, SenderStat } from './core/stats.js';\nexport { detectPlatform, platformStore, isPlatformSenderEnabled } from './core/platform.js';\nexport type { Platform } from './core/platform.js';\nexport { getWasmCrypto, fastHash, setWasmCrypto } from './core/wasm-crypto.js';\nexport type { WasmCrypto } from './core/wasm-crypto.js';\nexport { hmacSign, hmacSignSync, hmacVerify, signPayload } from './core/payload-signer.js';\nexport type { SignOptions } from './core/payload-signer.js';\nexport { PiiDetector, fnv1a, maskValue, DEFAULT_PATTERNS } from './core/pii.js';\nexport type { PiiOptions, PiiAction, PiiPattern } from './core/pii.js';\nexport { PrivacyManager } from './core/privacy.js';\nexport type { PrivacyMode, ConsentScope, PrivacyState } from './core/privacy.js';\nexport { createReplay } from './core/replay.js';\nexport type { ReplayEvent, ReplayOptions, ReplayHandle } from './core/replay.js';\nexport { createIdleScheduler, whenIdle, globalIdleScheduler } from './core/idle.js';\nexport type { IdleScheduler, IdleCallback } from './core/idle.js';\nexport { OffscreenSender } from './send/offscreen-sender.js';\nexport { WebSocketSender } from './send/ws-sender.js';\nexport type { WebSocketSenderOptions } from './send/ws-sender.js';\nexport { initEdge, trackOnce } from './edge/index.js';\nexport type { EdgeTracker, EdgeInitOptions, EdgeEnv } from './edge/index.js';\n\n// 预设常量\nexport { PresetEvent, PresetProperty, LIB_NAME, LIB_VERSION };\n\n// 插件\nexport { autoTrack } from './plugins/auto-track/index.js';\nexport { pageLoad } from './plugins/pageload/index.js';\nexport { pageLeave } from './plugins/pageleave/index.js';\nexport { exposure } from './plugins/exposure/index.js';\nexport { sessionEvent } from './plugins/session-event/index.js';\nexport { debugSender } from './plugins/debug-sender/index.js';\nexport { indexedDBSender } from './plugins/indexeddb-sender/index.js';\nexport { webviewBridge } from './plugins/webview-bridge/index.js';\nexport type { BridgeAPI, WebViewBridgeOptions } from './plugins/webview-bridge/index.js';\nexport { encryptor, xorEncryptor, defaultEncryptor, defaultDecryptor, aesGcmEncryptAsync, aesGcmDecryptAsync } from './plugins/encrypt/index.js';\nexport { otelBridge } from './plugins/otel-bridge/index.js';\nexport { otelExporter } from './plugins/otel-exporter/index.js';\nexport type { OtlpHttpOptions, SpanData, OtelEvent, OtelExporterOptions } from './plugins/otel-exporter/index.js';\nexport { experiment, createExperiment } from './plugins/experiment/index.js';\nexport type { ExperimentVariant, ExperimentOptions, ExperimentContext } from './plugins/experiment/index.js';\nexport { predictiveBatcher, makeIntervalPredictor } from './plugins/predictive-batcher/index.js';\nexport { piiDetector } from './plugins/pii-detector/index.js';\nexport { privacy } from './plugins/privacy/index.js';\nexport type { PrivacyOptions } from './plugins/privacy/index.js';\nexport { crossDomainStitching } from './plugins/cross-domain/index.js';\nexport type { CrossDomainOptions } from './plugins/cross-domain/index.js';\nexport { schemaRegistry, SchemaRegistry } from './plugins/schema-registry/index.js';\nexport type { SchemaEntry, SchemaOptions } from './plugins/schema-registry/index.js';\nexport { rateLimiter, RateLimiter } from './plugins/rate-limiter/index.js';\nexport type { RateLimiterOptions, RateLimitRule } from './plugins/rate-limiter/index.js';\nexport { cspCompliant } from './plugins/csp-compliant/index.js';\nexport type { CspOptions } from './plugins/csp-compliant/index.js';\nexport { audienceSync, AudienceSync } from './plugins/audience-sync/index.js';\nexport type { AudienceDestination, AudienceSyncOptions, AudienceContext } from './plugins/audience-sync/index.js';","/**\n * auto-track 插件\n * - $pageview: 路由变化时自动 track\n * - $WebClick: 监听 click,自动 track\n * - $WebStay: 页面离开时上报停留时长\n * - $scrolldepth: 25/50/75/100% 触发\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport { isBrowser } from '../../core/env.js';\nimport { PresetEvent, PresetProperty } from '../../types/constants.js';\n\nexport interface AutoTrackOptions {\n pageview?: boolean;\n webclick?: boolean;\n webstay?: boolean;\n scrolldepth?: boolean;\n /** webclick 元素选择器过滤,匹配才上报 */\n webclickSelector?: string;\n /** 上报时附带的元素属性(attribute 名单) */\n webclickAttrs?: string[];\n /** scroll 触发阈值(百分比数组) */\n scrollThresholds?: number[];\n}\n\nexport function autoTrack(opts: AutoTrackOptions = {}): Plugin {\n let sdkRef: import('../../core/tracker.js').EventTracker | null = null;\n let enterTime = Date.now();\n let reachedThresholds = new Set<number>();\n const thresholds = opts.scrollThresholds ?? [25, 50, 75, 100];\n\n function fire(event: string, properties: Record<string, unknown> = {}): void {\n if (!sdkRef) return;\n sdkRef.track(event, properties);\n }\n\n function path(): string {\n try { return location.pathname + location.search + location.hash; } catch { return ''; }\n }\n\n function setupPageview(): void {\n const send = () => {\n fire(PresetEvent.PageView, {\n [PresetProperty.URLPath]: path(),\n [PresetProperty.Title]: document.title,\n [PresetProperty.Referrer]: document.referrer,\n });\n };\n // 首次加载\n setTimeout(send, 0);\n // history.pushState/replaceState\n const wrap = (key: 'pushState' | 'replaceState') => {\n const orig = history[key];\n history[key] = function (...args: unknown[]) {\n const r = orig.apply(this, args as Parameters<typeof orig>);\n setTimeout(send, 0);\n return r;\n };\n };\n wrap('pushState');\n wrap('replaceState');\n // popstate\n window.addEventListener('popstate', () => setTimeout(send, 0));\n // hashchange\n window.addEventListener('hashchange', () => setTimeout(send, 0));\n }\n\n function setupWebClick(selector: string | undefined, attrs: string[]): void {\n const onClick = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const el = target.closest(selector || 'a, button, [data-track-click]') as HTMLElement | null;\n if (!el) return;\n const props: Record<string, unknown> = {\n [PresetProperty.ElementSelector]: cssPath(el),\n [PresetProperty.ElementType]: el.tagName.toLowerCase(),\n [PresetProperty.ElementContent]: (el.textContent || '').trim().slice(0, 100),\n [PresetProperty.ElementId]: el.id || undefined,\n [PresetProperty.ElementClassName]: el.className || undefined,\n };\n if (el instanceof HTMLAnchorElement) {\n props['$element_href'] = el.href;\n }\n for (const a of attrs) {\n const v = el.getAttribute(a);\n if (v != null) props[a] = v;\n }\n fire(PresetEvent.WebClick, props);\n };\n document.addEventListener('click', onClick, true);\n }\n\n function cssPath(el: Element): string {\n if (el.id) return `#${el.id}`;\n const parts: string[] = [];\n let cur: Element | null = el;\n while (cur && cur !== document.body && parts.length < 5) {\n const self: Element = cur;\n let part = self.tagName.toLowerCase();\n if (self.classList && self.classList.length) {\n part += '.' + Array.from(self.classList).slice(0, 2).join('.');\n }\n const parent: Element | null = self.parentElement;\n if (parent) {\n const siblings: Element[] = Array.from(parent.children).filter((c): c is Element => c instanceof Element && c.tagName === self.tagName);\n if (siblings.length > 1) {\n part += `:nth-of-type(${siblings.indexOf(self) + 1})`;\n }\n }\n parts.unshift(part);\n cur = parent;\n }\n return parts.join(' > ');\n }\n\n function setupWebStay(): void {\n const onEnter = () => { enterTime = Date.now(); };\n const onLeave = () => {\n const dur = Date.now() - enterTime;\n fire(PresetEvent.WebStay, {\n [PresetProperty.EventDuration]: dur,\n [PresetProperty.URLPath]: path(),\n });\n };\n window.addEventListener('beforeunload', onLeave);\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') onLeave();\n else onEnter();\n });\n }\n\n function setupScrollDepth(): void {\n reachedThresholds = new Set();\n const onScroll = () => {\n const docH = document.documentElement.scrollHeight - window.innerHeight;\n if (docH <= 0) return;\n const pct = Math.min(100, Math.round((window.scrollY / docH) * 100));\n for (const t of thresholds) {\n if (pct >= t && !reachedThresholds.has(t)) {\n reachedThresholds.add(t);\n fire('$scroll_depth', { percent: t, [PresetProperty.URLPath]: path() });\n }\n }\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n }\n\n return {\n name: 'auto-track',\n install({ sdk }) {\n if (!isBrowser()) return;\n sdkRef = sdk;\n if (opts.pageview !== false) setupPageview();\n if (opts.webclick !== false) setupWebClick(opts.webclickSelector, opts.webclickAttrs || ['data-track-id', 'data-sensors-click']);\n if (opts.webstay !== false) setupWebStay();\n if (opts.scrolldepth) setupScrollDepth();\n },\n };\n}\n","/**\n * Replay Engine(v1.3.0)\n *\n * - 把历史事件序列(JSON)喂回 SDK,重放真实交互链路\n * - 基于时间戳的同步调度(speed 可调)\n * - 输出每个 event 的回调 + 整体进度\n * - 支持 pause/resume/seek\n */\n\nexport interface ReplayEvent {\n type: string;\n event?: string;\n time: number;\n properties?: Record<string, unknown>;\n distinct_id?: string;\n // 其它字段透传\n [k: string]: unknown;\n}\n\nexport interface ReplayOptions {\n /** 速率倍率(1 = 实时,2 = 2x) */\n speed?: number;\n /** 是否调用真实的 sdk.track(默认 true;false = dryRun 仅回调) */\n callRealTrack?: boolean;\n /** 起始时间偏移(ms),跳过前面这段时间 */\n startOffsetMs?: number;\n /** 进度回调 */\n onProgress?: (info: { current: number; total: number; percent: number }) => void;\n /** 每条事件回调 */\n onEvent?: (ev: ReplayEvent, i: number) => void;\n /** 完成回调 */\n onEnd?: () => void;\n}\n\nexport interface ReplayHandle {\n pause(): void;\n resume(): void;\n seek(index: number): void;\n stop(): void;\n}\n\nexport function createReplay(events: ReplayEvent[], opts: ReplayOptions = {}): ReplayHandle {\n const speed = opts.speed ?? 1;\n const callReal = opts.callRealTrack !== false;\n const startOffset = opts.startOffsetMs ?? 0;\n\n let paused = false;\n let stopped = false;\n let currentIndex = 0;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let lastFiredAt: number | null = null;\n\n // 排序 + 过滤\n const sorted = [...events]\n .filter(e => e.time >= startOffset)\n .sort((a, b) => a.time - b.time);\n\n function getSdk(): { track?: (e: string, p?: Record<string, unknown>) => void } | null {\n if (typeof window === 'undefined') return null;\n return (window as unknown as { eventTracker?: { track?: (e: string, p?: Record<string, unknown>) => void } }).eventTracker ?? null;\n }\n\n function fireNext() {\n if (stopped || paused) return;\n if (currentIndex >= sorted.length) {\n opts.onEnd?.();\n return;\n }\n const ev = sorted[currentIndex];\n const now = Date.now();\n const relTime = ev.time - (sorted[0]?.time ?? 0);\n const targetRel = relTime / speed;\n if (lastFiredAt !== null) {\n const elapsed = now - lastFiredAt;\n const wait = targetRel - elapsed;\n if (wait > 0) {\n timer = setTimeout(fireNext, wait);\n return;\n }\n }\n lastFiredAt = now;\n opts.onEvent?.(ev, currentIndex);\n opts.onProgress?.({\n current: currentIndex + 1,\n total: sorted.length,\n percent: ((currentIndex + 1) / sorted.length) * 100,\n });\n if (callReal && ev.event) {\n const sdk = getSdk();\n try { sdk?.track?.(ev.event, ev.properties); } catch { /* ignore */ }\n }\n currentIndex++;\n // 立即尝试下一条\n queueMicrotask(fireNext);\n }\n\n // 启动\n if (typeof window !== 'undefined') {\n queueMicrotask(fireNext);\n } else if (sorted.length) {\n // node 环境:同步遍历\n for (let i = 0; i < sorted.length; i++) {\n opts.onEvent?.(sorted[i], i);\n opts.onProgress?.({ current: i + 1, total: sorted.length, percent: ((i + 1) / sorted.length) * 100 });\n if (callReal && sorted[i].event) {\n // node 下没有 sdk.track,跳过\n }\n }\n opts.onEnd?.();\n }\n\n return {\n pause() { paused = true; if (timer) { clearTimeout(timer); timer = null; } },\n resume() { paused = false; lastFiredAt = null; fireNext(); },\n seek(i) { currentIndex = Math.max(0, Math.min(i, sorted.length - 1)); lastFiredAt = null; fireNext(); },\n stop() { stopped = true; if (timer) { clearTimeout(timer); timer = null; } },\n };\n}","/**\n * Cross-domain Stitching(v1.3.0)\n *\n * - 在 cookie 写入 _sa_link_id(同根域跨子域共享)\n * - 客户端初始化时检测:当前 distinct_id 是否与 _sa_link_id 绑定\n * - 未登录用户跨子域跳转时,session 连续\n * - 不依赖登录态\n */\n\nimport type { Plugin, InstallContext } from '../../core/plugin.js';\n\nexport interface CrossDomainOptions {\n /** cookie 名,默认 _sa_link_id */\n cookieName?: string;\n /** 共享域(如 .example.com),自动加 . */\n domain?: string;\n /** 过期天数,默认 365 */\n expiresDays?: number;\n /** 是否把 _sa_link_id 注入到 register / event properties */\n injectProperty?: boolean;\n}\n\nfunction readCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n const target = encodeURIComponent(name) + '=';\n const parts = document.cookie.split(';');\n for (const raw of parts) {\n let c = raw;\n while (c.charAt(0) === ' ') c = c.substring(1);\n if (c.indexOf(target) === 0) {\n return decodeURIComponent(c.substring(target.length));\n }\n }\n return null;\n}\n\nfunction writeCookie(name: string, value: string, domain?: string, days = 365): void {\n if (typeof document === 'undefined') return;\n const exp = new Date();\n exp.setTime(exp.getTime() + days * 24 * 60 * 60 * 1000);\n let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; expires=${exp.toUTCString()}; path=/`;\n if (domain) {\n cookie += `; domain=${domain}`;\n }\n try { document.cookie = cookie; } catch { /* ignore */ }\n}\n\nexport function crossDomainStitching(opts: CrossDomainOptions = {}): Plugin {\n const cookieName = opts.cookieName || '_sa_link_id';\n const domain = opts.domain?.startsWith('.') ? opts.domain : opts.domain ? `.${opts.domain}` : undefined;\n const expiresDays = opts.expiresDays ?? 365;\n const inject = opts.injectProperty !== false;\n\n return {\n name: 'cross-domain-stitching',\n install({ sdk, config }: InstallContext) {\n let linkId = readCookie(cookieName);\n if (!linkId) {\n // 生成新 link_id\n const c = (sdk as unknown as { uuid?: () => string }).uuid;\n linkId = typeof c === 'function' ? c() : `link_${Date.now()}_${Math.random().toString(36).slice(2)}`;\n writeCookie(cookieName, linkId, domain, expiresDays);\n }\n // 暴露\n (sdk as unknown as { getLinkId?: () => string }).getLinkId = () => linkId!;\n (config as unknown as { _sa_link_id?: string })._sa_link_id = linkId;\n if (inject) {\n sdk.register({ _sa_link_id: linkId! });\n }\n },\n };\n}","/**\n * CSP Nonce 支持(v1.3.0)\n *\n * - 从 meta[name=csp-nonce] 或 config.csp_nonce 读 nonce\n * - 在 sendDataStage 给所有事件加 $csp_nonce 属性\n * - 业务侧可以用它把数据通过合法 CSP 通道回传到自家 server\n */\n\nimport type { Plugin, InstallContext } from '../../core/plugin.js';\n\nexport interface CspOptions {\n /** 直接传 nonce 字符串 */\n nonce?: string;\n /** 从 meta[name=csp-nonce] 读 */\n metaSelector?: string;\n /** 是否自动注册为 event property */\n injectProperty?: boolean;\n}\n\nfunction readMetaNonce(selector: string): string | null {\n if (typeof document === 'undefined') return null;\n const el = document.querySelector(selector);\n return el?.getAttribute('nonce') || null;\n}\n\nexport function cspCompliant(opts: CspOptions = {}): Plugin {\n return {\n name: 'csp-compliant',\n install({ sdk, config }: InstallContext) {\n const nonce = opts.nonce\n || (opts.metaSelector && readMetaNonce(opts.metaSelector))\n || (config as unknown as { csp_nonce?: string }).csp_nonce\n || null;\n if (!nonce) return;\n (config as unknown as { csp_nonce?: string }).csp_nonce = nonce;\n if (opts.injectProperty !== false) {\n sdk.register({ $csp_nonce: nonce });\n }\n // 暴露获取方法\n (sdk as unknown as { getCspNonce?: () => string | null }).getCspNonce = () => nonce;\n },\n };\n}","/**\n * Debug 发送器(独立 plugin)\n * - 启用后走 GET 请求到 debug_mode_url(默认从 server_url 推导 ?debug)\n * - 成功后 alert(\"debug数据发送成功\" + data)\n * - 失败时 alert(\"debug失败\" + JSON.stringify(err))\n * - 优先级最高(先于其它 senders 执行)\n */\n\nimport { encodeEvent, buildUrl } from '../../send/encode.js';\nimport { hasImage } from '../../core/env.js';\nimport { PresetProperty } from '../../types/constants.js';\nimport type { Plugin, InstallContext } from '../../core/plugin.js';\nimport type { EventData } from '../../types/index.js';\nimport type { StageContext } from '../../core/stage.js';\n\nexport interface DebugOptions {\n /** 是否启用(默认从 config.debug_mode 取) */\n enable?: boolean;\n /** 调试接收端 URL(默认从 config.server_url 推导 ?debug) */\n url?: string;\n /** 调试上传标记(出现在 Dry-Run header) */\n upload?: string;\n /** 成功回调(默认 alert) */\n onSuccess?: (event: EventData) => void;\n /** 失败回调(默认 alert) */\n onError?: (err: Error, event: EventData) => void;\n}\n\nfunction deriveDebugUrl(serverUrl: string | string[]): string {\n const base = Array.isArray(serverUrl) ? serverUrl[0] : serverUrl;\n return base.includes('?') ? base + '&debug' : base + '?debug';\n}\n\nexport function debugSender(opts: DebugOptions = {}): Plugin {\n return {\n name: 'debug-sender',\n install({ config, stages, registry, sdk }: InstallContext) {\n const enabled = opts.enable ?? !!config.debug_mode;\n if (!enabled) return;\n const url = opts.url ?? config.debug_mode_url ?? deriveDebugUrl(config.server_url);\n const upload = opts.upload ?? config.debug_mode_upload ?? 'true';\n\n stages.sendDataStage.register({\n name: 'debug-sender',\n priority: 30, // 最高优先级\n entry(ctx: StageContext<unknown>) {\n const event = ctx.data as EventData;\n try {\n const enc = encodeEvent(event, config.encryptor);\n Promise.resolve(enc).then((payload) => {\n const fullUrl = buildUrl(url, payload, 'form');\n if (hasImage()) {\n const img = new Image(1, 1);\n img.onload = () => {\n try { opts.onSuccess?.(event); } catch { /* ignore */ }\n try {\n if (typeof alert !== 'undefined') alert('debug数据发送成功' + (event.event || ''));\n } catch { /* ignore */ }\n };\n img.onerror = () => {\n const err = new Error('Image load failed');\n try { opts.onError?.(err, event); } catch { /* ignore */ }\n try {\n if (typeof alert !== 'undefined') alert('debug失败 错误原因' + JSON.stringify({ message: err.message }));\n } catch { /* ignore */ }\n };\n img.src = fullUrl;\n } else {\n ctx.cancellationToken.stop();\n }\n }).catch((e) => {\n sdk.getLogger().error('debug-sender error:', e);\n });\n } catch (e) {\n sdk.getLogger().error('debug-sender error:', e);\n }\n return event;\n },\n });\n\n // 标记 Dry-Run 风格\n registry.on('sdkAfterInitAPI', () => {\n Object.defineProperty(globalThis, '__et_debug_upload__', { value: upload, writable: true });\n });\n },\n uninstall() {\n try { delete (globalThis as Record<string, unknown>).__et_debug_upload__; } catch { /* ignore */ }\n },\n };\n}\n\n// 占位\nexport { PresetProperty };\n","/**\n * exposure 插件:元素曝光(IntersectionObserver)\n * - $element_exposure 事件\n * - 元素进入视口超过阈值持续 X ms 才上报(默认 500ms)\n * - 同元素同阈值只上报一次\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport { isBrowser } from '../../core/env.js';\nimport { PresetEvent, PresetProperty } from '../../types/constants.js';\n\nexport interface ExposureOptions {\n /** 选择器或元素集合 */\n selector?: string;\n /** 阈值(0~1,默认 0.5) */\n threshold?: number;\n /** 最小停留时间(ms,默认 500) */\n duration?: number;\n /** 额外附加属性(按 data-attr 注入到事件) */\n attrPrefix?: string;\n}\n\nexport function exposure(opts: ExposureOptions = {}): Plugin {\n let sdkRef: import('../../core/tracker.js').EventTracker | null = null;\n let observer: IntersectionObserver | null = null;\n const reported = new WeakSet<Element>();\n\n function cssPath(el: Element): string {\n if (el.id) return `#${el.id}`;\n const parts: string[] = [];\n let cur: Element | null = el;\n while (cur && cur !== document.body && parts.length < 5) {\n let part = cur.tagName.toLowerCase();\n if (cur.classList && cur.classList.length) {\n part += '.' + Array.from(cur.classList).slice(0, 2).join('.');\n }\n parts.unshift(part);\n cur = cur.parentElement;\n }\n return parts.join(' > ');\n }\n\n function setupObserver(): void {\n if (!('IntersectionObserver' in window)) return;\n const threshold = opts.threshold ?? 0.5;\n const duration = opts.duration ?? 500;\n observer = new IntersectionObserver(\n entries => {\n for (const entry of entries) {\n if (entry.intersectionRatio >= threshold) {\n const el = entry.target;\n const timer = setTimeout(() => {\n if (reported.has(el)) return;\n reported.add(el);\n if (!sdkRef) return;\n const props: Record<string, unknown> = {\n [PresetProperty.ElementSelector]: cssPath(el),\n [PresetProperty.ElementType]: el.tagName.toLowerCase(),\n $intersection_ratio: entry.intersectionRatio,\n $exposure_duration: duration,\n };\n if (el instanceof HTMLElement && el.dataset) {\n const prefix = opts.attrPrefix || 'data-exp-';\n for (const k of Object.keys(el.dataset)) {\n if (k.startsWith(prefix)) {\n props[k] = el.dataset[k];\n }\n }\n }\n sdkRef.track(PresetEvent.ElementExposure, props);\n }, duration);\n // 离开时取消未上报\n const off = () => {\n clearTimeout(timer);\n el.removeEventListener('mouseleave', off);\n };\n el.addEventListener('mouseleave', off);\n }\n }\n },\n { threshold: [threshold] },\n );\n\n if (opts.selector) {\n const targets = document.querySelectorAll(opts.selector);\n targets.forEach(t => observer!.observe(t));\n }\n }\n\n return {\n name: 'exposure',\n install({ sdk }) {\n if (!isBrowser()) return;\n sdkRef = sdk;\n if (document.readyState === 'complete') setupObserver();\n else window.addEventListener('load', setupObserver, { once: true });\n },\n uninstall() {\n observer?.disconnect();\n observer = null;\n sdkRef = null;\n },\n };\n}","/**\n * indexeddb-sender 插件:把事件写到 IndexedDB(用于离线缓存 / 批量消费)\n * - 不实际发送,只把序列化事件追加到指定 IDB store\n * - 适合后续被 webview bridge / native / service worker 消费\n */\n\nimport type { Plugin, InstallContext } from '../../core/plugin.js';\nimport type { StageContext, StageInterceptor } from '../../core/stage.js';\nimport type { EventData } from '../../types/index.js';\nimport { isBrowser } from '../../core/env.js';\nimport { encodeEvent } from '../../send/encode.js';\n\nexport interface IndexedDBSenderOptions {\n /** IDB 名(默认 event-tracker-outbox) */\n dbName?: string;\n /** object store 名(默认 outbox) */\n storeName?: string;\n /** 上限(条),超过从头丢弃 */\n max?: number;\n}\n\nexport function indexedDBSender(opts: IndexedDBSenderOptions = {}): Plugin {\n const dbName = opts.dbName || 'event-tracker-outbox';\n const storeName = opts.storeName || 'outbox';\n const max = opts.max || 500;\n\n let dbPromise: Promise<IDBDatabase | null> | null = null;\n\n function openDB(): Promise<IDBDatabase | null> {\n if (!isBrowser() || typeof indexedDB === 'undefined') return Promise.resolve(null);\n return new Promise(resolve => {\n try {\n const req = indexedDB.open(dbName, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName, { autoIncrement: true });\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => resolve(null);\n } catch {\n resolve(null);\n }\n });\n }\n\n const interceptor: StageInterceptor<unknown> = {\n name: 'indexeddb-sender',\n priority: 60,\n entry(ctx: StageContext<unknown>) {\n if (ctx.meta.stage !== 'sendDataStage') return;\n const ev = ctx.data as EventData;\n dbPromise ??= openDB();\n dbPromise.then(db => {\n if (!db) return;\n try {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n const payload = encodeEvent(ev);\n // 限制大小:> max 则删头\n const cntReq = store.count();\n cntReq.onsuccess = () => {\n if ((cntReq.result as number) >= max) {\n store.delete(IDBKeyRange.lowerBound(0, true));\n }\n store.add({ time: Date.now(), payload });\n };\n } catch {\n /* ignore */\n }\n }).catch(() => { /* ignore */ });\n return ev;\n },\n };\n\n return {\n name: 'indexeddb-sender',\n install({ stages }: InstallContext) {\n if (!isBrowser()) return;\n stages.sendDataStage.register(interceptor);\n },\n uninstall() {\n dbPromise = null;\n },\n };\n}","/**\n * Edge Worker Adapter (v1.3.0)\n *\n * - 适配 Cloudflare Workers / D1\n * - 不依赖 DOM,用 globalThis.fetch / crypto\n * - KV 存储用 Map(运行时)\n * - 暴露 init() 工厂\n */\n\nimport type { TrackerConfig, EventData } from '../types/index.js';\nimport { encodeEvent, encodeBatch } from '../send/encode.js';\n\nexport interface EdgeEnv {\n /** 转发到真实 server_url 的可选 fetcher */\n fetch?: typeof fetch;\n /** D1 binding(可选,用于去重 / 缓冲) */\n DB?: {\n prepare: (sql: string) => {\n bind: (...args: unknown[]) => {\n run: () => Promise<unknown>;\n all: () => Promise<{ results?: unknown[] }>;\n };\n };\n };\n}\n\nexport interface EdgeInitOptions extends Partial<TrackerConfig> {\n /** Cloudflare env */\n env?: EdgeEnv;\n /** 队列缓冲上限 */\n maxQueue?: number;\n /** flush 间隔(ms) */\n flushIntervalMs?: number;\n}\n\nexport interface EdgeTracker {\n track: (event: string, properties?: Record<string, unknown>) => Promise<void>;\n flush: () => Promise<void>;\n size: () => number;\n close: () => void;\n}\n\nexport function initEdge(options: EdgeInitOptions): EdgeTracker {\n if (!options.server_url) throw new Error('server_url required');\n const env = options.env || {};\n const fetcher: typeof fetch = env.fetch || globalThis.fetch;\n const queue: EventData[] = [];\n const maxQueue = options.maxQueue ?? 500;\n const flushInterval = options.flushIntervalMs ?? 3000;\n let timer: ReturnType<typeof setInterval> | null = null;\n let distinctId = 'edge-user';\n\n function buildEvent(event: string, properties?: Record<string, unknown>): EventData {\n return {\n type: 'track',\n event,\n time: Date.now(),\n distinct_id: distinctId,\n properties: properties || {},\n lib: { $lib: 'event-tracker-edge', $lib_version: '1.3.0' },\n token: options.app_id || 'edge',\n project: options.app_id || 'edge',\n };\n }\n\n async function flush() {\n if (!queue.length) return;\n const take = queue.splice(0);\n try {\n const url = Array.isArray(options.server_url) ? options.server_url[0] : options.server_url!;\n const payload = await Promise.resolve(encodeBatch(take, options.encryptor));\n await fetcher(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: `data=${encodeURIComponent(payload)}&batch=1`,\n });\n } catch {\n // 失败回滚(重新入队,最多 maxQueue)\n const remain = queue.unshift(...take);\n if (remain > maxQueue) queue.splice(0, remain - maxQueue);\n }\n }\n\n return {\n async track(event: string, properties?: Record<string, unknown>) {\n const e = buildEvent(event, properties);\n queue.push(e);\n if (queue.length >= maxQueue) await flush();\n else if (!timer) timer = setInterval(flush, flushInterval);\n },\n async flush() { await flush(); },\n size() { return queue.length; },\n close() {\n if (timer) clearInterval(timer);\n timer = null;\n void flush();\n },\n };\n}\n\n/** 单事件便捷方法(不缓冲,立即发送) */\nexport async function trackOnce(\n event: string,\n properties: Record<string, unknown>,\n options: EdgeInitOptions,\n): Promise<void> {\n const fetcher: typeof fetch = options.env?.fetch || globalThis.fetch;\n if (!options.server_url) throw new Error('server_url required');\n const ev: EventData = {\n type: 'track',\n event,\n time: Date.now(),\n distinct_id: 'edge-user',\n properties,\n lib: { $lib: 'event-tracker-edge', $lib_version: '1.3.0' },\n token: options.app_id || 'edge',\n project: options.app_id || 'edge',\n };\n const url = Array.isArray(options.server_url) ? options.server_url[0] : options.server_url;\n const payload = await Promise.resolve(encodeEvent(ev, options.encryptor));\n await fetcher(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: `data=${encodeURIComponent(payload)}`,\n });\n}","/**\n * pageleave 插件:用户离开页面(关闭、跳转、切到后台)时上报\n * - $WebPageLeave 事件\n * - 包含 $event_duration / $url_path / $referrer / $viewport_position\n * - 包含 page_visible 标记(visibilitychange API)\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport { isBrowser } from '../../core/env.js';\nimport { PresetEvent, PresetProperty } from '../../types/constants.js';\n\nexport interface PageLeaveOptions {\n /** 是否同步阻塞(sendBeacon 异步即可) */\n sendOnUnload?: boolean;\n}\n\nexport function pageLeave(_opts: PageLeaveOptions = {}): Plugin {\n let sdkRef: import('../../core/tracker.js').EventTracker | null = null;\n let enterTime = Date.now();\n\n function fire(reason: 'unload' | 'hidden' | 'pagehide'): void {\n if (!sdkRef) return;\n const dur = Date.now() - enterTime;\n sdkRef.track(PresetEvent.WebPageLeave, {\n [PresetProperty.EventDuration]: dur,\n [PresetProperty.URLPath]: location.pathname + location.search + location.hash,\n [PresetProperty.Title]: document.title,\n [PresetProperty.ViewportPosition]: window.scrollY || 0,\n $page_leave_reason: reason,\n });\n }\n\n return {\n name: 'pageleave',\n install({ sdk }) {\n if (!isBrowser()) return;\n sdkRef = sdk;\n enterTime = Date.now();\n\n // 重新进入页面时刷新 enterTime\n const onVisible = () => {\n if (document.visibilityState === 'visible') enterTime = Date.now();\n };\n document.addEventListener('visibilitychange', onVisible);\n\n // 关闭/离开\n window.addEventListener('pagehide', () => fire('pagehide'));\n window.addEventListener('beforeunload', () => fire('unload'));\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') fire('hidden');\n });\n },\n uninstall() {\n sdkRef = null;\n },\n };\n}","/**\n * pageload 插件:performance API 采集首屏加载性能\n * - $WebPageLoad 事件,包含:\n * $load_time / $dom_ready_time / $dom_interactive_time / $response_time\n * $page_resource_size / $page_height / $viewport_position\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport { isBrowser } from '../../core/env.js';\nimport { PresetEvent, PresetProperty } from '../../types/constants.js';\n\nexport interface PageLoadOptions {\n /** 是否立即触发(默认 true) */\n immediate?: boolean;\n /** 自定义时间轴 */\n measures?: string[];\n}\n\nexport function pageLoad(opts: PageLoadOptions = {}): Plugin {\n let sdkRef: import('../../core/tracker.js').EventTracker | null = null;\n\n function fire(): void {\n if (!sdkRef) return;\n const props: Record<string, unknown> = {\n [PresetProperty.URLPath]: location.pathname + location.search + location.hash,\n [PresetProperty.Title]: document.title,\n };\n\n // 尝试 performance API\n try {\n const perf = (typeof performance !== 'undefined' ? performance : null);\n if (perf) {\n const nav = perf.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined;\n if (nav) {\n if (typeof nav.domContentLoadedEventEnd === 'number') {\n props['$dom_ready_time'] = Math.round(nav.domContentLoadedEventEnd - nav.startTime);\n }\n if (typeof nav.domInteractive === 'number') {\n props['$dom_interactive_time'] = Math.round(nav.domInteractive - nav.startTime);\n }\n if (typeof nav.loadEventEnd === 'number' && typeof nav.startTime === 'number') {\n props['$load_time'] = Math.round(nav.loadEventEnd - nav.startTime);\n }\n if (typeof nav.responseEnd === 'number' && typeof nav.requestStart === 'number') {\n props['$response_time'] = Math.round(nav.responseEnd - nav.requestStart);\n }\n if (typeof nav.transferSize === 'number') {\n props[PresetProperty.PageResourceSize] = nav.transferSize;\n }\n }\n // paint\n const fp = perf.getEntriesByName('first-paint')[0];\n const fcp = perf.getEntriesByName('first-contentful-paint')[0];\n if (fp) props['$first_paint'] = Math.round(fp.startTime);\n if (fcp) props['$first_contentful_paint'] = Math.round(fcp.startTime);\n }\n } catch {\n /* ignore */\n }\n\n // 页面尺寸\n try {\n if (document.documentElement) {\n props[PresetProperty.PageHeight] = document.documentElement.scrollHeight;\n props[PresetProperty.ViewportPosition] = window.scrollY || 0;\n }\n } catch {\n /* ignore */\n }\n\n sdkRef.track(PresetEvent.WebPageLoad, props);\n }\n\n return {\n name: 'pageload',\n install({ sdk }) {\n if (!isBrowser()) return;\n sdkRef = sdk;\n const fireNow = opts.immediate !== false;\n if (document.readyState === 'complete') {\n if (fireNow) fire();\n else window.addEventListener('load', fire, { once: true });\n } else {\n window.addEventListener('load', () => {\n if (fireNow) fire();\n else setTimeout(fire, 0);\n }, { once: true });\n }\n },\n };\n}","/**\n * PII Detection Plugin (v1.3.0)\n *\n * 在 sendDataStage 拦截所有事件 properties,扫描 PII 并做脱敏\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport type { StageContext, StageInterceptor } from '../../core/stage.js';\nimport { PiiDetector } from '../../core/pii.js';\nimport type { PiiOptions } from '../../core/pii.js';\n\nexport function piiDetector(opts: PiiOptions = {}): Plugin {\n const detector = new PiiDetector(opts);\n let piiHits = 0;\n\n const interceptor: StageInterceptor<unknown> = {\n name: 'pii-detector',\n priority: 25, // 在加密 / IDB 之前\n entry(ctx: StageContext<unknown>) {\n if (ctx.meta.stage !== 'sendDataStage') return ctx.data;\n if (opts.enabled === false) return ctx.data;\n const ev = ctx.data as { properties?: Record<string, unknown> };\n const props = ev.properties || {};\n const { properties, hits } = detector.scanProperties(props);\n piiHits += hits;\n return { ...ev, properties };\n },\n };\n\n return {\n name: 'pii-detector',\n install({ stages }) {\n stages.sendDataStage.register(interceptor);\n },\n uninstall() {\n piiHits = 0;\n },\n /** 内部用:获取累计命中数(测试 / debug) */\n __getHits: () => piiHits,\n } as Plugin & { __getHits: () => number };\n}","/**\n * Privacy & Consent Plugin (v1.3.0)\n *\n * - 接入 PrivacyManager 到 SDK\n * - sendDataStage 拦截:\n * 1. 未授权 scope → drop\n * 2. 按 privacy_mode 脱敏\n * - 在 sdk 上挂 sdk.privacy / sdk.consent API\n */\n\nimport type { Plugin, InstallContext } from '../../core/plugin.js';\nimport type { StageContext, StageInterceptor } from '../../core/stage.js';\nimport { PrivacyManager } from '../../core/privacy.js';\nimport type { ConsentScope, PrivacyMode } from '../../core/privacy.js';\n\nexport interface PrivacyOptions {\n mode?: PrivacyMode;\n /** 缺哪些 scope 时不 track?默认 ['analytics'] */\n requireScopes?: ConsentScope[];\n /** 是否在 init 时打印授权 banner */\n showBanner?: boolean;\n}\n\nexport function privacy(opts: PrivacyOptions = {}): Plugin {\n let manager: PrivacyManager | null = null;\n let requireScopes = opts.requireScopes || ['analytics'];\n let droppedCount = 0;\n\n return {\n name: 'privacy',\n install({ sdk, stages, logger }: InstallContext) {\n manager = new PrivacyManager(logger);\n if (opts.mode) manager.setMode(opts.mode);\n\n // 暴露给 SDK\n (sdk as unknown as {\n privacy: {\n setMode: (m: PrivacyMode) => void;\n getMode: () => PrivacyMode;\n grant: (s: ConsentScope) => void;\n revoke: (s: ConsentScope) => void;\n has: (s: ConsentScope) => boolean;\n onChange: (fn: (s: unknown) => void) => () => void;\n dropped: () => number;\n };\n }).privacy = {\n setMode: (m) => manager!.setMode(m),\n getMode: () => manager!.getMode(),\n grant: (s) => manager!.grant(s),\n revoke: (s) => manager!.revoke(s),\n has: (s) => manager!.has(s),\n onChange: (fn) => manager!.subscribe(fn),\n dropped: () => droppedCount,\n };\n\n stages.sendDataStage.register({\n name: 'privacy-gate',\n priority: 30,\n entry(ctx: StageContext<unknown>) {\n if (ctx.meta.stage !== 'sendDataStage') return ctx.data;\n const ev = ctx.data as { properties?: Record<string, unknown> };\n // 1. consent gate\n const scope: ConsentScope = (ev.properties?.$consent_scope as ConsentScope) || 'analytics';\n if (!manager!.has(scope)) {\n droppedCount++;\n return undefined; // drop\n }\n // 2. privacy 脱敏\n const mode = manager!.getMode();\n if (mode !== 'off' && ev.properties) {\n const newProps = manager!.applyPrivacy(ev.properties, mode);\n return { ...ev, properties: newProps };\n }\n return ctx.data;\n },\n });\n },\n uninstall() {\n manager = null;\n droppedCount = 0;\n },\n };\n}","/**\n * WebView 桥(v2 RPC)\n *\n * v1: vapph5define.call(name, args) 同步返回,缺点:\n * - 没法 timeout\n * - 没法传 callback-style\n * - 没法识别 native async\n *\n * v2:\n * - RPC 协议:call(name, args, cbId) → native 通过 vapph5define.rpc.response(cbId, result)\n * - 自动超时(默认 5s)→ reject\n * - 自动探测:window.vapph5define.rpc / window.vapph5define.call 任一可用\n * - SDK 暴露 sdk.bridge.callAsync(name, args) 返回 Promise\n * - 兼容旧 sdk.bridge.call(name, args)\n * - install 时 fetch app info 可 await\n */\n\nimport type { Plugin } from '../../core/plugin.js';\nimport { isBrowser } from '../../core/env.js';\n\ndeclare global {\n interface Window {\n vapph5define?: {\n /** v1 同步调用 */\n call: (name: string, ...args: unknown[]) => unknown;\n /** v1 监听 */\n handle: (name: string, fn: (...args: unknown[]) => unknown) => void;\n /** 是否在 app 中 */\n isInApp?: boolean;\n /** v2 RPC */\n rpc?: {\n call: (name: string, cbId: string, args: unknown) => void;\n response: (cbId: string, result: unknown, err?: string) => void;\n };\n };\n }\n}\n\nexport interface WebViewBridgeOptions {\n /** 自定义 vapph5 对象,默认 window.vapph5define */\n defineName?: string;\n /** 是否在 install 时立刻拉 app 信息 */\n fetchOnInit?: boolean;\n /** 自定义取 app 信息的协议名(默认 'getAppInfo') */\n protocolName?: string;\n /** RPC 默认超时(ms) */\n timeout?: number;\n /** 取回的应用信息合并到 SDK 的字段映射 */\n fieldMap?: Partial<Record<'app_version' | 'app_id' | 'app_state' | 'channel' | 'lib', string>>;\n}\n\nexport interface BridgeAPI {\n /** 同步调用(v1 风格) */\n call: <T = unknown>(name: string, ...args: unknown[]) => T | undefined;\n /** 异步 RPC 调用(v2) */\n callAsync: <T = unknown>(name: string, args?: unknown, timeoutMs?: number) => Promise<T>;\n /** 注册 native handler */\n on: (name: string, fn: (...args: unknown[]) => unknown) => void;\n /** 检测是否在 webview 中 */\n isInApp: () => boolean;\n}\n\nexport function webviewBridge(opts: WebViewBridgeOptions = {}): Plugin {\n let rpcCbSeq = 0;\n const rpcPending = new Map<string, {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n }>();\n\n return {\n name: 'webview-bridge',\n install({ sdk, config }) {\n if (!isBrowser()) return;\n const win = window as Window;\n const defineName = opts.defineName || 'vapph5define';\n const define = (win as unknown as Record<string, unknown>)[defineName] as Window['vapph5define'] | undefined;\n if (!define || typeof define.call !== 'function') {\n return; // 不在 WebView 中\n }\n const timeout = opts.timeout ?? 5000;\n\n const callAsync: BridgeAPI['callAsync'] = (name, args, timeoutMs) => {\n return new Promise((resolve, reject) => {\n // 优先用 v2 rpc\n if (define.rpc && typeof define.rpc.call === 'function') {\n const cbId = `rpc_${++rpcCbSeq}_${Date.now()}`;\n const t = setTimeout(() => {\n rpcPending.delete(cbId);\n reject(new Error(`[WebViewBridge] RPC '${name}' timeout after ${timeoutMs ?? timeout}ms`));\n }, timeoutMs ?? timeout);\n rpcPending.set(cbId, { resolve, reject, timer: t });\n try {\n define.rpc.call(name, cbId, args);\n } catch (e) {\n clearTimeout(t);\n rpcPending.delete(cbId);\n reject(e as Error);\n }\n } else {\n // fallback v1:同步转异步\n try {\n const r = (define as (...a: unknown[]) => unknown).call(name, args);\n resolve(r);\n } catch (e) {\n reject(e as Error);\n }\n }\n });\n };\n\n // 注册 v2 rpc response 监听\n if (define.rpc && typeof define.rpc.response === 'function') {\n define.handle('rpc.response', (cbId: unknown, result: unknown, err?: unknown) => {\n if (typeof cbId !== 'string') return;\n const p = rpcPending.get(cbId);\n if (!p) return;\n rpcPending.delete(cbId);\n clearTimeout(p.timer);\n if (err) p.reject(new Error(String(err)));\n else p.resolve(result);\n });\n }\n\n const bridge: BridgeAPI = {\n call: (name, ...args) => define.call(name, ...args) as never,\n callAsync,\n on: (name, fn) => define.handle(name, fn),\n isInApp: () => define.isInApp === true || (define.call('isInApp') as boolean) === true,\n };\n\n (sdk as unknown as { bridge?: BridgeAPI }).bridge = bridge;\n (config as unknown as { is_webview?: boolean }).is_webview = true;\n\n if (opts.fetchOnInit !== false) {\n // 用 callAsync(支持 v2 rpc + v1 同步),避免阻塞 install\n const protocolName = opts.protocolName || 'getAppInfo';\n void callAsync<Record<string, unknown>>(protocolName).then(result => {\n if (!result || typeof result !== 'object') return;\n const fm = opts.fieldMap || {};\n for (const [sdkKey, resultKey] of Object.entries(fm)) {\n const v = result[resultKey as string];\n if (v !== undefined && v !== null) {\n (config as unknown as Record<string, unknown>)[sdkKey] = v;\n }\n }\n sdk.register({\n $app_version: result.app_version || result.appVersion,\n $app_id: result.app_id || result.appId,\n $channel: result.channel,\n $lib: result.lib || result.lib_name || result.libName,\n });\n }).catch(() => { /* ignore timeout / err */ });\n }\n },\n };\n}"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","__extends","TypeError","String","__","this","constructor","create","__assign","assign","t","s","i","n","arguments","length","apply","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","__generator","body","f","y","_","label","sent","trys","ops","g","Iterator","verb","Symbol","iterator","v","op","pop","push","__spreadArray","to","from","pack","ar","l","slice","concat","SuppressedError","isBrowser","window","document","hasLocalStorage","localStorage","k","setItem","removeItem","_a","hasImage","Image","uuidv4","crypto","getRandomValues","arr","Uint8Array","hex","toString","padStart","join","Date","now","d2","performance","replace","c","r","Math","random","floor","Logger","config","log","args","_i","shouldLog","out","warn","error","level","debug","Error","show_log","fn","console","KEY_DISTINCT","KEY_ANONYMOUS","KEY_LOGIN","KEY_ORIGINAL","IdentityManager","store","opts","_this","loginId","originalId","anonymousId","readOrCreate","getAnonymousId","setAnonymousId","firstId","getFirstId","setFirstId","distinctId","getDistinctId","setDistinctId","key","factory","reader","writer","stored","get","fresh","persist","set","getLoginId","getOriginalId","identify","isSave","prevDistinct","remove","resetAnonymousIdentity","newAnonymousId","login","logout","PresetEvent","PageView","WebPageLoad","WebPageLeave","WebClick","WebStay","SignUp","BindID","UnbindID","ABTestTrigger","PlanPopupClick","PlanPopupDisplay","ChannelLinkReaching","ElementExposure","ScrollDepth","ExitClick","PageLeave","HeatmapEvent","PresetProperty","AppId","AppVersion","Lib","LibMethod","LibDetail","LibVersion","ScreenWidth","ScreenHeight","ViewportWidth","ViewportHeight","TimezoneOffset","UserAgent","Language","FirstBrowserCharset","FirstBrowserLanguage","URL","URLPath","Title","Referrer","ReferrerHost","LatestReferrer","LatestReferrerHost","LatestLandingPage","LatestSearchKeyword","LatestTrafficSourceType","FirstReferrer","FirstReferrerHost","FirstSearchKeyword","FirstTrafficSourceType","FirstVisitTime","SearchKeywordId","SearchKeywordIdHash","SearchKeywordIdType","IsFirstDay","IsFirstTime","LatestUtmSource","LatestUtmMedium","LatestUtmCampaign","LatestUtmContent","LatestUtmTerm","Utms","DistinctId","AnonymousId","FirstId","OriginalId","LoginId","IsLoginId","IdentityLoginId","IdentityAnonymousId","IdentityCookieId","IdentityEmail","IdentityMobile","ElementSelector","ElementPath","ElementType","ElementId","ElementClassName","ElementName","ElementContent","ElementTargetUrl","ElementPosition","PageX","PageY","PageHeight","PageResourceSize","EventDuration","ViewportPosition","LatestWxAdClickId","LatestWxAdCallbacks","LatestWxAdHashKey","IsChannelCallbackEvent","EventSessionId","Time","Event","Option","Project","Token","SignupMethod","LIB_NAME","LIB_VERSION","PresetPropertyBuilder","preset","setPreset","props","register","registerOnce","keys","clearRegister","unsetRegister","getPreset","build","baseProps","lib_name","lib_version","app_id","app_version","location","href","pathname","title","referrer","sw","screen","width","sh","height","vw","innerWidth","documentElement","clientWidth","vh","innerHeight","clientHeight","navigator","language","user_agent","userAgent","getTimezoneOffset","is_collect_utm","utm","query","parts","startsWith","substring","split","parts_1","eq","indexOf","decodeURIComponent","parseUtm","search","_b","entries","_c","capitalize","charAt","toUpperCase","MemoryStore","backing","Map","has","delete","prefix","filter","CookieStore","domain","crossSubdomain","secure","name","encodeURIComponent","ca","cookie","expiresDays","expires","date","setTime","getTime","toUTCString","map","trim","LocalStorageStore","getItem","SessionStorageStore","sessionStorage","autoStore","ok","hasCookie","cookieDomain","cookieCrossSubdomain","secureCookie","_encoder","payloadCache","cacheKey","json","cacheGet","ts","data","cacheSet","size","first","undefined","encodeEvent","event","encryptor","JSON","stringify","cached","encodeBatch","events","buildUrl","serverUrl","payload","contentType","base","isArray","strToBytes","TextEncoder","encode","toBase64Url","bytes","fromCharCode","btoa","ImageSender","canUse","send","ctx","url_1","server_url","Ctor","img","eval","globalThis","src","onload","onerror","onabort","setTimeout","logger","e_1","BeaconSender","sendBeacon","url","blob","Blob","type","encoder","hmacSign","secret","salt","keyData","subtle","importKey","hash","cryptoKey","sign","sig","constantTimeEqual","a","charCodeAt","signPayload","identity_secret","maybeGzip","text","enabled","CompressionStream","stream","writable","getWriter","write","close","readable","getReader","chunks","total","read","byteLength","merged","off","chunks_1","headers","AjaxSender","fetch","getGzipEnabled","Boolean","batch_send","gzip","_g","gz","distinct_id","method","mode","credentials","keepalive","res","_d","callback","status","on_error","_f","_e","sendBatch","e_2","QUEUE_KEY","BatchSender","timer","running","start","scheduleNext","stop","clearTimeout","enqueue","max","max_length","flush","bs","predict","batch_send_predict","interval","send_interval","datasend_timeout","peekQueueSize","q","raw","parse","queue","str","half","payload2","str2","ajax","beacon","queue_1","ev","StageChain","stage","list","stopped","stopFlag","spec","unregister","priority","sort","item","list2","reset","run","input","owner","meta","cancellationToken","entry","Lifecycle","hooks","sdkReady","Set","sdkInitPara","sdkAfterInitPara","sdkInitAPI","sdkAfterInitAPI","changeDistinctId","switch","on","add","emit","clear","inspect","PluginRegistry","lifecycle","plugins","commonWays","stages","buildDataStage","businessStage","sendDataStage","intercept","invoke","install","plugin","idx","findIndex","uninstall","splice","full","registry","CHANNEL_NAME","InstanceChannel","bc","listeners","sourceId","localStorageKey","pollTimer","initBroadcastChannel","initLocalStoragePolling","BroadcastChannel","onmessage","source","forEach","addEventListener","newValue","msg_1","post","msg","postMessage","clearInterval","getSourceId","RetryPolicy","jitter","backoff","attempt","baseMs","capMs","exp","min","pow","prev","execute","send_1","shouldRetry","onFailed","maxCount","max_retry_count","maxDur","max_retry_duration","lastErr","sleepAcc","attempts","finalErr","nextSleep","sleep","ms","FailedQueue","draining","drainPromise","drainAbort","takeAll","drain","sender","catch","AbortController","_drain","abortDrain","reason","abort","signal","aborted","remain","remain_1","q_1","SDKError","_super","code","message","options","cause","context","timestamp","captureStackTrace","toJSON","stack","InitError","SendError","EncryptError","IdentityError","StorageError","PluginError","ConfigError","ENC","require","bytesToB64","Buffer","syncSign","h1","h2","imul","BigInt","hmacSignAsync","webcrypto","getSubtle","bind","hmacVerifyAsync","signature","expected","diff","createSignedIdentity","hint","signAsync","verify","verifyAsync","decode","lastIndexOf","encodeAsync","decodeAsync","SendPipeline","identity","presetProps","retryPolicy","failedQueue","stats","pending","senders","abortControllers","setSenders","setBatchSender","batchSender","makeCtx","buildEvent","time","get_client_timestamp","properties","anonymous_id","first_id","login_id","original_id","lib","$lib","$lib_version","token","project","disabled","hook","encryptEvent","_encrypted","dispatchAfterEncrypt","enc","err","send_type","trackPending","pickSender","task","senderName","recordStart","recordSuccess","onSendSuccess","err_1","recordFailure","onSendError","sendWithStats","onFailedEnqueue","onRetry","recordRetry","wrap","req","match","find","promise","rej","count","queued","waitUntilIdle","recordFlush","onFlush","_h","snapshot","allSettled","abortAll","takeAbortController","ctrl","releaseAbortController","StatsCollector","success","failure","retry","in_flight","flushCount","bySender","getOrCreate","startTs","dur","total_duration","avg_duration","max_duration","last_error","last_error_at","lastFlushAt","by_sender","flush_count","last_flush_at","taken_at","listSenders","GLOBAL_STATS","DEFAULT_CONFIG","storage_type","send_timeout","EventTracker","DEFAULT_SEND_TYPE","_senders","_statsTimer","_inited","__noop","instanceId","init","_logger","_config","sdk","builder","_store","cookie_domain","cookie_cross_subdomain","secure_cookie","_signedIdentity","_identity","get_distinct_id","set_distinct_id","get_anonymous_id","set_anonymous_id","get_first_id","set_first_id","_presetProps","preset_properties","_registry","_channel","_retryPolicy","_failedQueue","_batchSender","_stats","_pipeline","show_stats","stats_interval","setInterval","snap","getPrototypeOf","_registerAttached","clearAllRegister","registerPage","registerSession","registerSessionOnce","_identityAttached","id","save","getRegistry","newAnon","alias","newId","track","$signup_method","attachIdentityApi","pipeline","_profileAttached","profileSend","setProfile","cb","setOnceProfile","incrementProfile","appendProfile","unsetProfile","prop","deleteProfile","attachProfileApi","_trackAttached","trackSignup","userId","trackLinkage","trackLink","element","el","querySelector","$element_selector","tagName","toLowerCase","$element_target_url","HTMLAnchorElement","once","trackLinks","elements","list_1","querySelectorAll","trackHeatMap","trackWebClick","trackWebStay","attachTrackApi","use","kit","channel","_callback","_distinctId","_isSave","_loginId","_resetAnonymousId","_newAnonymousId","_newId","_originalId","_props","_key","_prop","disable","enable","setServerURL","switchServer","uuid","getPresetProperties","shutdown","getConfig","getLogger","getRetryPolicy","getFailedQueue","getChannel","getPipeline","getSignedIdentity","getStats","resetStats","isInitialized","INSTANCES","detectPlatform","product","__REACT_NATIVE__","process","versions","node","eventTracker","_instance","makeJsFallback","available","hmacSha256","aesGcmEncrypt","iv","encrypt","ct","aesGcmDecrypt","decrypt","pt","DEFAULT_PATTERNS","re","action","fnv1a","h","maskValue","repeat","PiiDetector","patterns","exclude","excludeKeys","scan","hits","cur","test","lastIndex","m","applyAction","scanProperties","nested","nh","it","_v","CONSENT_KEY","PrivacyManager","state","scopes","storage","loadFromStorage","setMode","getMode","grant","scope","revoke","shouldTrack","subscribe","applyPrivacy","$distinct_id","createIdleScheduler","requestIdleCallback","ric_1","cic_1","cancelIdleCallback","schedule","cancel","handle","didTimeout","timeRemaining","globalIdleScheduler","hasWorker","Worker","OffscreenSender","worker","getWorker","createObjectURL","head","shift","kind","w","fallback","destroy","terminate","WebSocketSender","ws","buffer","reconnectDelay","reconnectTimer","configCb","WebSocket","connect","readyState","OPEN","CONNECTING","scheduleReconnect","onopen","authToken","safeSend","_auth","take_1","onclose","onConfig","_ctx","maxBuffer","unshift","delay","maxReconnectMs","SESSION_KEY","SESSION_LAST_KEY","defaultEncryptor","xorBase64","defaultDecryptor","bin","atob","DEC","TextDecoder","importAesKey","rawKey","digest","decoder","cfg","decryptEvent","ref","__encryptor","__decoder","__encryptEvent","__decryptEvent","tryLoadOtel","Function","mod","trace","rand16","arr_1","attrValue","stringValue","intValue","Number","isFinite","boolValue","eventToSpan","end","traceId","spanId","attrs","startTimeUnixNano","endTimeUnixNano","attributes","exportOtlpHttp","spans","resourceSpans","resource","scopeSpans","version","timeoutMs","endpoint","memoryFallback","getStored","setStored","createExperiment","experiments","storagePrefix","variantKey","variantOf","variants","x","totalW","reduce","weight","hash01","acc","chosen","variants_1","variantIdOf","exposure","expKey","exposedKey","$experiment_key","$variant_id","$is_first_exposure","forceSet","vid","makeIntervalPredictor","minInterval","maxInterval","winMs","windowMs","threshold","activityThreshold","counts","handler","events_1","passive","round","tryLoadAjv","default","Ajv","allErrors","strict","SchemaRegistry","ajv","remoteCache","schemas","remoteUrl","fetchRemote","validate","compile","schema","ttl","remoteTtlMs","etag","errors","RateLimiter","globalBuckets","userBuckets","eventBuckets","allow","global","checkBucket","onDrop","user","perEvent","buckets","rule","cutoff","AudienceSync","queueSize","take","destinations","transform","maxRetry","tracker","keyPromise","b64","b64ToBytes","cipher","plain","sync","audience","origIdentify","trigger","origLogin","sdkRef","enterTime","reachedThresholds","thresholds","scrollThresholds","fire","path","setupWebClick","selector","target","closest","self_1","part","classList","parent_1","parentElement","siblings","children","Element","cssPath","textContent","className","attrs_1","getAttribute","setupWebStay","onLeave","visibilityState","pageview","orig","history","setupPageview","webclick","webclickSelector","webclickAttrs","webstay","scrolldepth","docH","scrollHeight","pct","scrollY","thresholds_1","percent","speed","callReal","callRealTrack","startOffset","startOffsetMs","paused","currentIndex","lastFiredAt","sorted","fireNext","onEnd","relTime","wait","onEvent","onProgress","current","getSdk","queueMicrotask","pause","resume","seek","cookieName","inject","injectProperty","linkId","readCookie","days","writeCookie","getLinkId","_sa_link_id","nonce","metaSelector","readMetaNonce","csp_nonce","$csp_nonce","getCspNonce","debug_mode","debug_mode_url","includes","upload","debug_mode_upload","fullUrl","onSuccess","alert","onError","defineProperty","__et_debug_upload__","experiment","stageCtx","variant","observer","reported","WeakSet","setupObserver","duration","IntersectionObserver","intersectionRatio","el_1","timer_1","$intersection_ratio","$exposure_duration","HTMLElement","dataset","attrPrefix","off_1","removeEventListener","entries_1","observe","disconnect","__ET_WASM_CRYPTO__","nodeCrypto","hmac","createHmac","update","dbName","storeName","dbPromise","interceptor","indexedDB","req_1","open","onupgradeneeded","db","objectStoreNames","contains","createObjectStore","autoIncrement","onsuccess","store_1","transaction","objectStore","payload_1","cntReq_1","IDBKeyRange","lowerBound","fetcher","env","maxQueue","flushInterval","flushIntervalMs","client_id","values","otel","tracer","getTracer","tracerName","spanName","filterAttr","eventName","span","startSpan","setAttribute","batchSize","batchIntervalMs","_opts","$page_leave_reason","perf","nav","getEntriesByType","domContentLoadedEventEnd","startTime","domInteractive","loadEventEnd","responseEnd","requestStart","transferSize","fp","getEntriesByName","fcp","fireNow","immediate","detector","piiHits","__getHits","manager","droppedCount","requireScopes","privacy","onChange","dropped","$consent_scope","newProps","limiter","onInvalid","timeout","storeRef","sessionId","lastActive","newSession","$event_session_id","existing","last","rpcCbSeq","rpcPending","define","defineName","callAsync","rpc","cbId_1","response","cbId","bridge","isInApp","is_webview","fetchOnInit","protocolName","fm","fieldMap","sdkKey","$app_version","appVersion","$app_id","appId","$channel","libName"],"mappings":"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","x_google_ignoreList":[0]}
|