├── .npmrc ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── bower.json ├── index.d.ts ├── index.esm.js ├── index.umd.js ├── package.json └── t.js /.npmrc: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NPM_TOKEN} 2 | registry=https://registry.npmjs.org 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | JavaScript Browser Agent Changelog 2 | ================================== 3 | 4 | ## [Version 3.10.4](https://cdn.trackjs.com/agent/3.10.4/t.js) (2023-12-05) 5 | 6 | Update Typescript types for Network optional fields. 7 | 8 | ## [Version 3.10.3](https://cdn.trackjs.com/agent/3.10.3/t.js) (2023-11-13) 9 | 10 | No Change, build system updates. 11 | 12 | ## [Version 3.10.2](https://cdn.trackjs.com/agent/3.10.2/t.js) (2023-10-23) 13 | 14 | Features: 15 | - Verified with Node 18 LTS 16 | 17 | ## [Version 3.10.1](https://cdn.trackjs.com/agent/3.10.1/t.js) (2021-08-05) 18 | 19 | Bugfixes: 20 | - Fix typo in readme. 21 | 22 | ## [Version 3.10.0](https://cdn.trackjs.com/agent/3.10.0/t.js) (2021-07-15) 23 | 24 | Features: 25 | - Agent supports ServiceWorkers and SharedWorkers 26 | 27 | ## [Version 3.9.2](https://cdn.trackjs.com/agent/3.9.2/t.js) (2021-05-01) 28 | 29 | Bugfixes: 30 | - Handle case where read-only error object passed into the global error handler. 31 | - Handle serializing a circular-referenced object with broken property getters. 32 | 33 | ## [Version 3.9.1](https://cdn.trackjs.com/agent/3.9.1/t.js) (2021-04-23) 34 | 35 | Bugfixes: 36 | - Fixed rare case where `Illegal invocation` was thrown when calling a console function. 37 | 38 | ## [Version 3.9.0](https://cdn.trackjs.com/agent/3.9.0/t.js) (2021-03-04) 39 | 40 | Features: 41 | - Added `forwardingDomain` option to allow for ad blocker bypass. 42 | 43 | ## [Version 3.8.0](https://cdn.trackjs.com/agent/3.8.0/t.js) (2021-02-17) 44 | 45 | Features: 46 | - Agent supports use inside of WebWorkers. Can be imported as a module or using `importScript`. 47 | - Tooling upgrade to Node 14.5.4 48 | 49 | ## [Version 3.7.7](https://cdn.trackjs.com/agent/3.7.7/t.js) (2021-02-11) 50 | 51 | Bugfixes: 52 | - Normalized the error messages for network failures, which sometimes do not include a `statusText` property, by removing it from the message string. Customers will no longer need duplicate ignore rules to handle both variants. 53 | - Expose error when user calls `XMLHttpRequest.send` before `XMLHttpRequest.open`, which was previously treated as an internal fault. 54 | - Update typescript definitions to include the `error` argument in the `onError` callback. 55 | 56 | ## [Version 3.7.6](https://cdn.trackjs.com/agent/3.7.6/t.js) (2020-11-30) 57 | 58 | Bugfixes: 59 | - Handles internal failure where the reason for a Promise rejection is `null`. 60 | 61 | ## [Version 3.7.5](https://cdn.trackjs.com/agent/3.7.5/t.js) (2020-09-10) 62 | 63 | Bugfixes: 64 | - Escapes space and tab characters in network telemetry URLs that would be automatically converted by the browser. 65 | 66 | ## [Version 3.7.4](https://cdn.trackjs.com/agent/3.7.4/t.js) (2020-05-19) 67 | 68 | Bugfixes: 69 | - Fix `fetch` wrapping that caused errors during abort. ([Issue#38](https://github.com/TrackJs/trackjs-package/issues/38)). 70 | - Add console.warn Typescript definition. ([Issue#39](https://github.com/TrackJs/trackjs-package/issues/39)). 71 | 72 | ## [Version 3.7.3](https://cdn.trackjs.com/agent/3.7.3/t.js) (2020-02-26) 73 | 74 | Bugfixes: 75 | - Allow `undefined` configuration properties to be passed without stopping. 76 | 77 | 78 | ## [Version 3.7.2](https://cdn.trackjs.com/agent/3.7.2/t.js) (2019-09-12) 79 | 80 | Bugfixes: 81 | - Update `fetch` wrapping to accommodate non-standardized URL object behavior utilized by Facebook sdk. 82 | 83 | 84 | ## [Version 3.7.1](https://cdn.trackjs.com/agent/3.7.1/t.js) (2019-09-11) 85 | 86 | Bugfixes: 87 | - Change `fetch` wrapping to avoid a [Microsoft Edge Bug](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/23391036/) creating a `Request` object. 88 | - Add `TrackJS.isInstalled()` to Typescript definition. 89 | 90 | 91 | ## [Version 3.7.0](https://cdn.trackjs.com/agent/3.7.0/t.js) (2019-08-19) 92 | 93 | Features: 94 | - Capture the element inner text as part of visitor Telemetry. 95 | 96 | 97 | ## [Version 3.6.0](https://cdn.trackjs.com/agent/3.6.0/t.js) (2019-08-12) 98 | 99 | Bugfixes: 100 | - Add safety checking to XHR header detection to not show console warnings. 101 | 102 | 103 | ## [Version 3.5.0](https://cdn.trackjs.com/agent/3.5.0/t.js) (2019-08-12) 104 | 105 | Features: 106 | - Revert of 3.4.0 due to a CORS issue. 107 | 108 | 109 | ## [Version 3.4.0](https://cdn.trackjs.com/agent/3.4.0/t.js) (2019-08-05) 110 | 111 | Features: 112 | - Check for the presence of a Node correlationId on network request for cross-referencing with the Node agent. 113 | - Force TrackJS agent version into dependencies, even if we were bundled. 114 | - Change method of Image creation to be safer. 115 | - Added `agentPlatform` to error capture payload. 116 | - Added `TrackJS.isInstalled()` for checking install state. 117 | 118 | Bugfixes: 119 | - None 120 | 121 | 122 | ## [Version 3.3.0](https://cdn.trackjs.com/agent/3.3.0/t.js) (2019-03-04) 123 | 124 | Features: 125 | - Changed error capture to accept a `202 Accepted` response from the API to be more accurate to behavior. 126 | - Added agent version to error capture API call. 127 | - Improved internal implementation of util.contains. 128 | 129 | Bugfixes: 130 | - Handle case where undefined can be thrown from an XHR listener. 131 | 132 | 133 | ## [Version 3.2.0](https://cdn.trackjs.com/agent/3.2.0/t.js) (2019-02-22) 134 | 135 | Features: 136 | - Support Symbol types in object serializer. 137 | 138 | Bugfixes: 139 | - Fixed error thrown when requiring into Node. Replaced with no-op. 140 | 141 | 142 | ## [Version 3.1.2](https://cdn.trackjs.com/agent/3.1.2/t.js) (2019-01-31) 143 | 144 | Features: 145 | - None 146 | 147 | Bugfixes: 148 | - Fixed serialization of unthrown errors in IE11. 149 | 150 | 151 | ## [Version 3.1.1](https://cdn.trackjs.com/agent/3.1.1/t.js) (2019-01-26) 152 | 153 | Features: 154 | - None 155 | 156 | Bugfixes: 157 | - Changed how window and document are detected in the main closure for webpack. 158 | 159 | 160 | 161 | ## [Version 3.1.0](https://cdn.trackjs.com/agent/3.1.0/t.js) (2019-01-19) 162 | 163 | Features: 164 | - Detect if we are running in a NodeJS environment and safely disable monitoring. 165 | 166 | Bugfixes: 167 | - Removed warning message printed when functions are called where `enabled=false` is in the configuration. 168 | 169 | 170 | 171 | ## [Version 3.0.1](https://cdn.trackjs.com/agent/3.0.1/t.js) (2018-11-10) 172 | 173 | Features: 174 | - None 175 | 176 | Bugfixes: 177 | - Updated install example with a safety check. 178 | - Updated types definition to include the global object. 179 | 180 | 181 | ## [Version 3.0.0](https://cdn.trackjs.com/agent/3.0.0/t.js) (2018-10-29) 182 | 183 | Features: 184 | - Changed the global namespace to `TrackJS`. The previous `trackJs` still exists, but is deprecated. 185 | - Changed initialization behavior to be explicit, preferring to call the new `TrackJS.install(config)` instead of populating the `_trackJs` init object. The init object is still supported, but is deprecated. 186 | - Added support for the agent to be loaded as a module using any of the AMD, CommonJS, or ES6 Module notations. 187 | - Expanded the Typescript definition file to support the new module-based loading system. 188 | - Updated the CDN paths for the new agent to prevent forcing breaking changes on users referencing `current`. The new URL paths will now be `/agent//t.js`, `/agent/v3/canary/t.js`, and `/agent/v3/latest/t.js`. 189 | 190 | Bugfixes: 191 | - None 192 | 193 | 194 | ## [Version 2.13.0](https://cdn.trackjs.com/releases/2.13.0/tracker.js) (2018-08-29) 195 | 196 | Features: 197 | - Added new `dependencies` config key to opt-out of window.* version discovery. 198 | - Added exclusion of the `data-value` attribute from visitor element enumeration. 199 | 200 | Bugfixes: 201 | - None 202 | 203 | 204 | ## [Version 2.12.0](https://cdn.trackjs.com/releases/2.12.0/tracker.js) (2018-08-20) 205 | 206 | Features: 207 | - Added Method and URL information to `failed to Fetch` errors. 208 | - Added calling Stack Trace to `fetch` network errors. 209 | 210 | Bugfixes: 211 | - None 212 | 213 | 214 | ## [Version 2.11.1](https://cdn.trackjs.com/releases/2.11.1/tracker.js) (2018-08-14) 215 | 216 | Features: 217 | - None 218 | 219 | Bugfixes: 220 | - Deployment pipeline check 221 | 222 | 223 | ## [Version 2.11.0](https://cdn.trackjs.com/releases/2.11.0/tracker.js) (2018-08-10) 224 | 225 | Features: 226 | - Added truncation of Network Telemetry URLS to 2000 characters. 227 | - Added limit to Visitor Telemetry Elements of 10 Attributes. 228 | - Added limit to Visitor Telemetry Element Attributes of 100 characters. 229 | - Added truncation of Console Telemetry to 1000 characters if the total Console Telemetry size is larger than 80,000 characters. Truncation will be applied to console messages one at a time, oldest first, until within the limit. 230 | 231 | Bugfixes: 232 | - None 233 | 234 | ## [Version 2.10.2](https://cdn.trackjs.com/releases/2.10.2/tracker.js) (2017-11-21) 235 | 236 | Features: 237 | - None 238 | 239 | Bugfixes: 240 | - Handle case where customer wraps `Function.prototype` that prevented later function wrapping. 241 | 242 | 243 | ## [Version 2.10.1](https://cdn.trackjs.com/releases/2.10.1/tracker.js) (2017-11-16) 244 | 245 | Features: 246 | - None 247 | 248 | Bugfixes: 249 | - Suppress an "Permission Denied" error that may occur in Selenium Firefox environments due to our wrapping. 250 | 251 | 252 | ## [Version 2.10.0](https://cdn.trackjs.com/releases/2.10.0/tracker.js) (2017-11-03) 253 | 254 | Features: 255 | - Added patching of function properties and prototype from a callback onto the wrapped function. This makes it less obvious that we have changed out the function. 256 | 257 | Bugfixes: 258 | - Fixed issue where Promise rejections from browser extensions could throw "Permission Denied" on Firefox when accessing the `reason` property. 259 | - Fixed issue with how we track the lifecycle of callback functions to use an external state approach. While this approach will expose some TrackJS internals into the global namespace ("__trackjs__"), it is more resilient to the varied kinds of callbacks we need to support. 260 | - Fixed issue where we could double-wrap callback functions, causing unnecessarily long stack traces. 261 | 262 | ## [Version 2.9.0](https://cdn.trackjs.com/releases/2.9.0/tracker.js) (2017-09-07) 263 | 264 | Features: 265 | - Added capture of the original page URL and referrer to the error payload. 266 | 267 | Bugfixes: 268 | - None. 269 | 270 | 271 | ## [Version 2.8.5](https://cdn.trackjs.com/releases/2.8.5/tracker.js) (2017-08-23) 272 | 273 | Features: 274 | - None. 275 | 276 | Bugfixes: 277 | 278 | - Fixed missing type definition for the dedupe option. 279 | 280 | 281 | ## [Version 2.8.4](https://cdn.trackjs.com/releases/2.8.4/tracker.js) (2017-06-28) 282 | 283 | Features: 284 | - None. 285 | 286 | Bugfixes: 287 | 288 | - Fixed issue in default serializer that could cause error "Right-hand side of 'instanceof' is not an object" when the page had mangled the value of `HTMLElement`. 289 | 290 | 291 | ## [Version 2.8.3](https://cdn.trackjs.com/releases/2.8.3/tracker.js) (2017-06-22) 292 | 293 | Features: 294 | 295 | - Added ability to disable Fetch wrapping using `network.fetch = false` in the initialization object. This works around an old ZoneJS bug that has been patched in their library, but still has a large presence. 296 | 297 | Bugfixes: 298 | 299 | - Fixed bug where duplicate garbage data could be sent when a Fetch request completes. 300 | 301 | 302 | ## [Version 2.8.2](https://cdn.trackjs.com/releases/2.8.2/tracker.js) (2017-06-08) 303 | 304 | Features: 305 | 306 | - None 307 | 308 | Bugfixes: 309 | 310 | - Fixed bug in fetch wrapping that caused failures when a prepopulated `Request` object was used. 311 | 312 | ## [Version 2.8.1](https://cdn.trackjs.com/releases/2.8.1/tracker.js) (2017-06-07) 313 | 314 | Features: 315 | 316 | - None 317 | 318 | Bugfixes: 319 | 320 | - Disable fetch that had been released while we debug an issue. 321 | 322 | ## [Version 2.8.0](https://cdn.trackjs.com/releases/2.8.0/tracker.js) (2017-06-02) 323 | 324 | Features: 325 | 326 | - Added support for `fetch` network events to the Telemetry Timeline. 327 | 328 | Bugfixes: 329 | 330 | - None. 331 | 332 | ## [Version 2.7.1](https://cdn.trackjs.com/releases/2.7.1/tracker.js) (2017-03-30) 333 | 334 | Bugfixes: 335 | 336 | - Removed internal error payload cloning to reduce "Out of Memory" internal errors 337 | 338 | ## [Version 2.7.0](https://cdn.trackjs.com/releases/2.7.0/tracker.js) (2017-03-15) 339 | 340 | Features: 341 | 342 | - Added configurable capability to de-duplicate subsequent errors that have the same message and stack trace through the same error entry point. 343 | - Created `Promise` error entry type and expanded unhandledrejection promise capture to include the BluebirdJS polyfill. 344 | 345 | Bugfixes: 346 | 347 | - Disabled tracker no longer prints warnings about a missing API Key 348 | - Prevent case where an `undefined` error message could be represented as `'{}'` 349 | - Fixed timing of Page View pixel to wait for document load even on older browsers. Load will timeout at 10 seconds and send the pixel regardless. 350 | - Fixed issue where `addEventListener` with malformed capture options could cause an infinite recursion. 351 | - Fixed configuration of TypeScript definition typings. 352 | 353 | ## [Version 2.6.4](https://cdn.trackjs.com/releases/2.6.4/tracker.js) (2017-03-03) 354 | 355 | *Empty released testing changes to automated deployments* 356 | 357 | 358 | ## [Version 2.6.3](https://cdn.trackjs.com/releases/2.6.3/tracker.js) (2017-01-27) 359 | 360 | Features: 361 | 362 | - None 363 | 364 | Bugfixes: 365 | 366 | - Corrected issue with removing event listeners that may have been attached before the tracker has initialized. 367 | 368 | 369 | ## [Version 2.6.2](https://cdn.trackjs.com/releases/2.6.2/tracker.js) (2016-12-29) 370 | 371 | Features: 372 | 373 | - Instances of `Error` will be correctly serialized out into JSON strings. 374 | - Instances of `HTMLElement` will be serialized out as HTML representations. 375 | - Objects with circular references will be serialized using a fallback first-level-only serializer. 376 | 377 | Bugfixes: 378 | 379 | - Corrected serialization of instantiated strings to not be double-quoted. 380 | - Corrected serialization of undefined and NaN values within an array. 381 | 382 | 383 | ## [Version 2.6.1](https://cdn.trackjs.com/releases/2.6.1/tracker.js) (2016-12-17) 384 | 385 | Features: 386 | 387 | - None 388 | 389 | Bugfixes: 390 | 391 | - Changed the `addEventListener` wrapping behavior to use `EventTarget` if it exists. This resolves a conflict with ZoneJS and Angular2. 392 | 393 | 394 | ## [Version 2.6.0](https://cdn.trackjs.com/releases/2.6.0/tracker.js) (2016-11-25) 395 | 396 | Features: 397 | 398 | - Added navigation telemetry for `history.pushState`, `history.replaceState`, and `popstate` events. 399 | 400 | Bugfixes: 401 | 402 | - None 403 | 404 | 405 | ## [Version 2.5.3](https://cdn.trackjs.com/releases/2.5.3/tracker.js) (2016-11-08) 406 | 407 | Features: 408 | 409 | - None 410 | 411 | Bugfixes: 412 | 413 | - Fixed support for wrapping `EventHandler` objects passed into `addEventListener`. 414 | 415 | 416 | ## [Version 2.5.2](https://cdn.trackjs.com/releases/2.5.2/tracker.js) (2016-10-22) 417 | 418 | Features: 419 | 420 | - New Canary Build deployment pipeline 421 | 422 | Bugfixes: 423 | 424 | - None 425 | 426 | ## [Version 2.5.1](https://cdn.trackjs.com/releases/2.5.1/tracker.js) (2016-08-22) 427 | 428 | Features: 429 | 430 | - None 431 | 432 | Bugfixes: 433 | 434 | - Fixed passthrough arguments of `window.onerror` 435 | 436 | ## [Version 2.5.0](https://cdn.trackjs.com/releases/2.5.0/tracker.js) (2016-08-03) 437 | 438 | Features: 439 | 440 | - Added option to track an error for `console.warn` 441 | - Added tracking for global unhandled promise rejections from Chrome and Bluebird.js 442 | 443 | Bugfixes: 444 | 445 | - Fixed TypeScript definitions to support proper module exports 446 | - Fixed passthrough override of `window.onerror` 447 | - Fixed network wrapping to support URL objects 448 | 449 | ## [Version 2.4.0](https://cdn.trackjs.com/releases/2.4.0/tracker.js) (2016-07-03) 450 | 451 | Features: 452 | 453 | - Added Typescript definition file to NPM and Bower packages 454 | 455 | Bugfixes: 456 | 457 | - None 458 | 459 | ## [Version 2.3.1](https://cdn.trackjs.com/releases/2.3.1/tracker.js) (2016-03-28) 460 | 461 | Features: 462 | 463 | - None 464 | 465 | Bugfixes: 466 | 467 | - Corrected behavior of tracking `null` or `undefined` to be properly represented. 468 | - Removed array notation from singular argument passed into console. 469 | 470 | ## [Version 2.3.0](https://cdn.trackjs.com/releases/2.3.0/tracker.js) (2016-03-26) 471 | 472 | Features: 473 | 474 | - Changed default behavior to not drop a cookie containing the correlationId. Tracker will no longer maintain a cross-page identification of the user. 475 | - Updated default object serialization to attempt simple stringify on complex objects. 476 | 477 | Bugfixes: 478 | 479 | - None 480 | 481 | ## [Version 2.2.0](https://cdn.trackjs.com/releases/2.2.0/tracker.js) (2016-01-06) 482 | 483 | Features: 484 | 485 | - Introduced `trackJs.addMetadata` and `trackJs.removeMetadata` API 486 | 487 | Bugfixes: 488 | 489 | - None 490 | 491 | ## [Version 2.1.16](https://cdn.trackjs.com/releases/2.1.16/tracker.js) (2015-11-18) 492 | 493 | Features: 494 | 495 | - Added capture logic for specific Android [object Event] error 496 | 497 | Bugfixes: 498 | 499 | - None 500 | 501 | ## [Version 2.1.15](https://cdn.trackjs.com/releases/2.1.15/tracker.js) (2015-10-13) 502 | 503 | Features: 504 | 505 | - Added optional flag to suspend use of cookies. This was requested for better support of the new privacy-focused Safari. 506 | 507 | Bugfixes: 508 | 509 | - None 510 | 511 | 512 | ## [Version 2.1.14](https://cdn.trackjs.com/releases/2.1.14/tracker.js) (2015-08-16) 513 | 514 | Features: 515 | 516 | - None 517 | 518 | Bugfixes: 519 | 520 | - Suppressed a duplicate "Script error" that could be tracked when hosted from the CDN and captured from a watched function. This also removes the need to use the "crossorigin" attribute in our script, which has also been removed from our suggested install. 521 | 522 | ## [Version 2.1.13](https://cdn.trackjs.com/releases/2.1.13/tracker.js) (2015-07-28) 523 | 524 | Features: 525 | 526 | - None 527 | 528 | Bugfixes: 529 | 530 | - Fixed bug in custom `serialize` configuration where objects passed to `trackJs.track` may be double-serialized. 531 | 532 | ## [Version 2.1.12](https://cdn.trackjs.com/releases/2.1.12/tracker.js) (2015-06-05) 533 | 534 | Features: 535 | 536 | - None 537 | 538 | Bugfixes: 539 | 540 | - Prevented a non-blocking security error from being displayed in the Safari web console when enumerating library versions from within an iframe. 541 | 542 | ## [Version 2.1.11](https://cdn.trackjs.com/releases/2.1.11/tracker.js) (2015-03-27) 543 | 544 | Features: 545 | 546 | - None 547 | 548 | Bugfixes: 549 | 550 | - Changed behavior of disabled tracker to not polyfill and wrap console.log 551 | - Fixed bug where objects sent into console.error were not properly serialized when tracked 552 | 553 | ## [Version 2.1.10](https://cdn.trackjs.com/releases/2.1.10/tracker.js) (2015-03-23) 554 | 555 | Features: 556 | 557 | - None 558 | 559 | Bugfixes: 560 | 561 | - Fixed bug where a server outage on usage.trackjs.com could impact the load time of customer applications. 562 | 563 | ## [Version 2.1.9](https://cdn.trackjs.com/releases/2.1.9/tracker.js) (2015-02-16) 564 | ***Released February 16, 2015*** 565 | 566 | Features: 567 | 568 | - None 569 | 570 | Bugfixes: 571 | 572 | - Added exclusion for `https://localhost:0/chromecheckurl` from network telemetry. This url is used by Chrome on IOS 7+ to communicate with the native webdriver. It is not relevant to customer code. 573 | 574 | ## [Version 2.1.8](https://cdn.trackjs.com/releases/2.1.8/tracker.js) (2015-01-15) 575 | 576 | Features: 577 | 578 | - Reformatted an AJAX Error to include the METHOD and URL that originated the error, in the format `404 Not Found: POST /some/api`. 579 | 580 | Bugfixes: 581 | 582 | - None 583 | 584 | ## [Version 2.1.7](https://cdn.trackjs.com/releases/2.1.7/tracker.js) (2014-12-18) 585 | 586 | Features: 587 | 588 | - None 589 | 590 | Bugfixes: 591 | 592 | - stopped usage beacon from sending when tracker is disabled 593 | - prevented chrome warning when detecting webkitIndexDB 594 | 595 | ## [Version 2.1.6](https://cdn.trackjs.com/releases/2.1.6/tracker.js) (2014-10-31) 596 | 597 | Features: 598 | 599 | - None 600 | 601 | Bugfixes: 602 | 603 | - `trackJs.watchAll` returns the object for chaining initializations. 604 | 605 | ## [Version 2.1.5](https://cdn.trackjs.com/releases/2.1.5/tracker.js) (2014-10-26) 606 | 607 | Features: 608 | 609 | - None 610 | 611 | Bugfixes: 612 | 613 | - Fixed bug where `application` could be partially changed after initialization, causing errors and hits to be out of sync. 614 | 615 | ## [Version 2.1.4](https://cdn.trackjs.com/releases/2.1.4/tracker.js) (2014-10-16) 616 | 617 | Features: 618 | 619 | - Added GitHub, NPM, and Bower Packages 620 | 621 | Bugfixes: 622 | 623 | - None 624 | 625 | ## [Version 2.1.2](https://cdn.trackjs.com/releases/2.1.2/tracker.js) (2014-10-15) 626 | 627 | Features: 628 | 629 | - None 630 | 631 | Bugfixes: 632 | 633 | - Fixed bug with handling of SyntaxError in Chrome where file, column, and line are not populated. 634 | 635 | ## [Version 2.1.1](https://cdn.trackjs.com/releases/2.1.1/tracker.js) (2014-08-27) 636 | 637 | Features: 638 | 639 | - Added stacktrace to errors generated from `console.error` 640 | - Added safer handling of falsy values in the default serializer 641 | - Change the logging behavior to include last 30 events rather than the last 10 of each type. 642 | - Added extra param to [onError callback](./Configuration) with the originating 643 | `Error` object. 644 | 645 | Bugfixes: 646 | 647 | - None 648 | 649 | ## [Version 2.1.0](https://cdn.trackjs.com/releases/2.1.0/tracker.js) (2014-08-23) 650 | 651 | Features: 652 | 653 | - Added support for multiple applications under a single account. 654 | 655 | Bugfixes: 656 | 657 | - None 658 | 659 | ## [Version 2.0.3](https://cdn.trackjs.com/releases/2.0.3/tracker.js) (2014-07-15) 660 | 661 | Features: 662 | 663 | - None 664 | 665 | Bugfixes: 666 | 667 | - Fixed bug in `watchAll` where function context was being lost, affecting Backbone.js wrapping. 668 | - Prevented errors that have already been tracked from being captured again from `watchAll` 669 | - Added Corresponding wrapping of `removeEventListener` elements and XHR that impacted Meteor apps. 670 | 671 | ## [Version 2.0.2](https://cdn.trackjs.com/releases/2.0.2/tracker.js) (2014-07-09) 672 | 673 | Features: 674 | 675 | - None 676 | 677 | Bugfixes: 678 | 679 | - Fixed bug where Internet Explorer 8 improperly serialized some messages, preventing them from display in the UI 680 | - Added checks for `_trackJS` and `_trackjs` (in addition to `_trackJs`) for preconfig. 681 | - Added safety check to error wrapping in case a string is thrown. 682 | 683 | ## [Version 2.0.1](https://cdn.trackjs.com/releases/2.0.1/tracker.js) (2014-07-08) 684 | 685 | Features: 686 | 687 | - None 688 | 689 | Bugfixes: 690 | 691 | - Fixed bug where `window.onerror` would generate an error if called with invalid arguments. 692 | - Fixed bug where `window.onerror` messages would not include all possible information. 693 | 694 | ## [Version 2.0.0](https://cdn.trackjs.com/releases/2.0.0/tracker.js) (2014-07-01) 695 | 696 | Features: 697 | 698 | - (Breaking) Restructuring of the configuration structure. See docs for updates. 699 | - (Breaking) Renamed `customer` to `token` 700 | - (Breaking) Removal of the global `track` alias 701 | - (Breaking) Removal of `ignore` RegEx option 702 | - Added `onError` callback for finer control of ignoring and manipulating errors 703 | - Added `serialize` callback to control how objects are serialized into the log 704 | - Added error catching for `setTimeout`, `setInterval`, `element.addEventListener`, and `xhr.addEventListener` 705 | - Added option to capture a bind-time stacktrace 706 | - Added finer control of which console functions should be wrapped 707 | 708 | Bugfixes: 709 | 710 | - Fixed bug where caught errors were tracked a second time by window.onerror 711 | - Fixed bug when cookies are disabled in Android 712 | 713 | ## [Version 1.2.7](https://cdn.trackjs.com/releases/1.2.7/tracker.js) (2014-06-10) 714 | 715 | Features: 716 | 717 | - None 718 | 719 | Bugfixes: 720 | 721 | - Fixed tracking input events on multiselect. 722 | 723 | ## [Version 1.2.6](https://cdn.trackjs.com/releases/1.2.6/tracker.js) (2014-05-29) 724 | 725 | Features: 726 | 727 | - None 728 | 729 | Bugfixes: 730 | 731 | - Fixed bug in ignore api that prevented multiple matching 732 | 733 | ## [Version 1.2.5](https://cdn.trackjs.com/releases/1.2.5/tracker.js) (2014-04-04) 734 | 735 | Features: 736 | 737 | - Added stacktrace that may be available to global window.onerror 738 | 739 | Bugfixes: 740 | 741 | - None 742 | 743 | ## [Version 1.2.4](https://cdn.trackjs.com/releases/1.2.4/tracker.js) (2014-04-03) 744 | 745 | Features: 746 | 747 | - None 748 | 749 | Bugfixes: 750 | 751 | - Fixed IE10/11 XDomainRequest inspection. 752 | 753 | ## [Version 1.2.3](https://cdn.trackjs.com/releases/1.2.3/tracker.js) (2014-03-27) 754 | 755 | Features: 756 | 757 | - None 758 | 759 | Bugfixes: 760 | 761 | - Fixed inspection errors in Firefox 6.0 and below 762 | 763 | ## [Version 1.2.2](https://cdn.trackjs.com/releases/1.2.2/tracker.js) (2014-02-23) 764 | 765 | Features: 766 | 767 | - Exceptions wrapped by watchAll are rethrown after transmission. 768 | 769 | Bugfixes: 770 | 771 | - Fixed webkit warning message on transmission. 772 | 773 | ## [Version 1.2.1](https://cdn.trackjs.com/releases/1.2.1/tracker.js) (2014-01-23) 774 | 775 | Features: 776 | 777 | - None 778 | 779 | Bugfixes: 780 | 781 | - Fixed IE8 bug with observing network requests--IE8 won't support this, and the feature has been disabled for this browser. 782 | 783 | ## [Version 1.2.0](https://cdn.trackjs.com/releases/1.2.0/tracker.js) (2013-12-30) 784 | 785 | Features: 786 | 787 | - Added `trackJs.track()` now supports objects, strings, or error objects 788 | - Added `trackJs.watchAll()` supports watching objects of functions 789 | - Added `trackJs.watch()` returns a watched version of a single function 790 | - Added `trackJs.attempt()` executes a single function and catches errors from it 791 | - Deprecated `trackAll()` 792 | 793 | Bugfixes: 794 | 795 | - None 796 | 797 | ## [Version 1.1.0](https://cdn.trackjs.com/releases/1.1.0/tracker.js) (2013-11-14) 798 | 799 | Features: 800 | 801 | - Added ability to ignore functions on an object for trackAll() 802 | - Added ignore by message configuration 803 | - Added configuration option to disable inspectors 804 | - Added direct logging capability from trackJs.log, trackJs.warn, etc. for use if console inspector is disabled. 805 | - Added Support pre-load configuration 806 | 807 | Bugfixes: 808 | 809 | - None 810 | 811 | ## [Version 1.0.1](https://cdn.trackjs.com/releases/1.0.1/tracker.js) (2013-10-18) 812 | 813 | Features: 814 | 815 | - Initial beta release 816 | 817 | Bugfixes: 818 | 819 | - None 820 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Terms of Service 2 | ====================== 3 | 4 | The License and Terms of Service for the TrackJS Browser Error Monitoring Agent is located at https://trackjs.com/terms/. The text is copied here for reference, please visit the link for official terms. 5 | 6 | --- 7 | 8 | These Terms of Service governs the use of the TrackJS Service (The “Service”) operated by TrackJS, LLC (or “TrackJS”). This Agreement sets forth the legally binding terms and conditions for your use of trackjs.com (the “Site”). “You” or similar terms means you, the person accessing trackjs.com, the business or entity on whose behalf you access trackjs.com, as well as any person on whose behalf you are using trackjs.com or who may have rights through you. 9 | 10 | By creating an account, by logging into the Service, and/or by accessing or using the Site in any manner, including, but not limited to, visiting or browsing the Site or contributing content or other materials to the Site, you acknowledge that you have reviewed and accept the terms of service, agree to become bound by its terms, and certify that you are an authorized representative of the entity purchasing the service, and that you have the right and authority to enter into this agreement on the entity’s behalf. 11 | 12 | ## Account Terms 13 | 14 | - You must be at least 13 years or older to use TrackJS. 15 | - You may not have more than one free account at a time. 16 | 17 | ## Grant of License and Restrictions on Use 18 | 19 | Subject to the terms of this Agreement and proper payment to TrackJS, TrackJS grants you a non-exclusive, non-transferable, limited right to use the Service and Error Tracking Agents (The “Agents”) solely for your own internal business purposes for the term of this Agreement. You may embed the Agents within your own materially-larger software product or similar item (“Customer’s Product”) and you may distribute the Agents to third parties as a supporting and component part of Customer’s Product, but you may not distribute the Service or Agents as a stand-alone or primary element to any third party. In addition, you will not (and you will not allow any thirty party to): copy, distribute, rent, lease, transfer or sublicense all or any portion of the Service or Agents to any third party other than as part of Customer’s Product explicitly permitted above; modify or prepare derivative works of the Service or Agents; use the Service or Agents in any commercial context or for any commercial purpose or in any commercial product including reselling the Service or Agents other than as permitted above as part of Customer’s Product; use the Service or Agents in any manner that threatens the integrity, performance or availability of the Service; or reverse engineer, decompile, or disassemble the Service or Agents. 20 | 21 | ## Grant of License to TrackJS 22 | 23 | You grant TrackJS a worldwide right to use, store, and reproduce the data gathered by TrackJS of your website (the “Data”) as necessary for TrackJS to (i) create reports or statistics of the Data for you; (ii) provide Service to you; and (iii) create reports or statistics using the Data in the aggregate, provided that no such report identifies you by name or other distinguishing mark. 24 | 25 | ## Ownership 26 | 27 | You acknowledge that the Service and Agents are the exclusive property of TrackJS. TrackJS retains all rights, title and interest in and to copyrights, trade secrets, trademarks and other intellectual property rights in the Services and Agents and you shall not acquire any right, title, or interest in the Services and/or Agents, except the right to use it in accordance with this Agreement. Any rights to the Services and/or Agents granted are licensed and not sold. 28 | 29 | ## Term and Termination 30 | 31 | Either party may terminate this Agreement at any time with notice. Upon termination TrackJS will stop providing and you will stop accessing Services. Further, all rights and license to the Agents immediately terminate, you will immediately stop using the Agents in any way, and you will immediately delete and not retain any and all copies of the Agents in your possession or control. In the event of any termination you will not be entitled to any refunds or any other fees. This Agreement will automatically terminate if you do not comply with any terms or conditions of this Agreement, including paying for the Services. All terms of this Agreement which by this nature are intended to survive termination of this Agreement shall survive. 32 | 33 | ## Warranty Disclaimers 34 | 35 | TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, EXCEPT AS EXPRESSLY PROVIDED FOR IN THIS AGREEMENT, THE AGENTS AND SERVICES ARE BEING PROVIDED “AS IS” AND “AS AVAILABLE” WITHOUT WARRANTY OF ANY KIND. TRACKJS DOES NOT WARRANT THAT THE SERVICE WILL MEET CUSTOMER’S REQUIREMENTS. TRACKJS HEREBY DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, WITHOUT LIMITATION, ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTIES AS TO NON-INFRINGEMENT. 36 | 37 | ## Limitation of Liability 38 | 39 | TRACKJS’ ENTIRE LIABILITY UNDER, FOR BREACH OF, OR ARISING OUT OF THIS AGREEMENT AND/OR RELATED TO THIS AGREEMENT, THE AGENTS AND SERVICES, IS LIMITED TO THE PAYMENTS ACTUALLY MADE BY THE CUSTOMER FOR THE SERVICE DURING THE TWELVE (12) MONTHS PRIOR TO THE DATE OF THE EVENT GIVING RISE TO ANY LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT, OR OTHERWISE, SHALL TRACKJS BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL INCIDENTAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING WITHOUT LIMITATION, LOST PROFITS, LOSSES OR EXPENSES, WHETHER OR NOT TRACKJS WAS ADVISED OF, KNEW OF SHOULD HAVE KNOWN OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. 40 | 41 | ## Indemnification 42 | 43 | You agree to indemnify and hold TrackJS, and its subsidiaries, affiliates, officers, directors, agents, partners and employees, harmless from any claim or demand, including reasonable attorneys’ fees, made by any third party due to or arising out of the Services provided under this Agreement or any act or omission by you (including the entity on whose behalf you are entering into this Agreement). This indemnity obligation will survive the expiration or termination of this Agreement by either party for any reason. 44 | 45 | ## Confidentiality 46 | 47 | TrackJS acknowledges that you may disclose non-public, confidential information to TrackJS under this Agreement and you acknowledge that the Agents and Services provided to you, and the terms and conditions of this Agreement are confidential and proprietary to TrackJS. Each party agrees to take all reasonably necessary action, including appropriate instructions and agreements with employees and agents, to protect such confidential and proprietary information of the other party from unauthorized disclosure. In the event of any breach of this section, each party acknowledges that the non-breaching party would suffer irreparable harm and shall therefore be entitled to seek injunctive relief without the necessity of posting bond. You also acknowledge that infringement or unauthorized copying of the intellectual property of TrackJS would cause irreparable harm to TrackJS. 48 | 49 | ## Publicity 50 | 51 | You are permitted to state publicly that you are a Subscriber of TrackJS. You agree that TrackJS may include your name and trademarks in a list of TrackJS Customers, online or in promotional materials. You also agree that TrackJS may verbally reference you as a customer of the Service. You may opt out of the provisions in this Section by e-mailing a request to hello@trackjs.com. 52 | 53 | ## Governing Law and Venue 54 | 55 | The Site is controlled and operated within the United States, and is not intended to subject TrackJS to any the law or jurisdiction outside of the United States. The Site does not constitute any contract with any jurisdiction outside the State of Minnesota. Use of this Site is prohibited in any jurisdiction having laws that would void this Agreement in whole or essential part or which makes accessing the Site illegal. This Agreement is entered into and performed in the State of Minnesota, United States of America. It is governed by and shall be construed under the laws of Minnesota, exclusive of any choice of law or conflict of laws provisions. In any claim or action directly or indirectly arising under this Agreement or related to the Site, Services or Agents, each party irrevocably submits to the personal jurisdiction of the Minnesota State District Court sitting in Washington County, Minnesota or of the United States Court for the District of Minnesota. Each party waives any jurisdictional, venue or inconvenient forum objections to these courts. You agree that you shall pursue any claim against TrackJS in your individual capacity only, and you will not participate in any collective or so-called “class” action against us. 56 | 57 | ## General Provisions 58 | 59 | This Agreement is the complete and exclusive statement of the agreement between us concerning its subject matter and supersedes all prior agreements and representations between the parties. Any waiver of or modification to the terms of this Agreement will not be effective unless executed in writing and signed by TrackJS. If any provision of this Agreement is held to be unenforceable, in whole or in part, such holding shall not affect the validity of the other provisions of this Agreement. The software is controlled by U.S. Export Regulations, and it may not be exported to or used by embargoed countries or individuals. You may not assign this Agreement or any license granted under this Agreement without our prior written consent, which may be granted or not granted in our sole judgment. By agreeing to this Agreement you also agree to our collection, use and disclosure of information as described in the most-recent version of our Privacy Policy [https://trackjs.com/privacy] which is incorporated here by reference. 60 | 61 | ## Changes To This Agreement 62 | 63 | TrackJS reserves the right, at our sole discretion, to modify or replace these Terms of Service by posting the updated terms on the Site. Your continued use of the Site after any such changes constitutes your acceptance of the new Terms and Conditions. 64 | 65 | Please review this Agreement periodically for changes. If you do not agree to any of this Agreement or any changes to this Agreement, do not use, access or continue to access the Site or discontinue any use of the Site immediately. 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TrackJS Browser Agent 2 | =============== 3 | 4 | The browser agent for collecting errors from JavaScript, Network, and console 5 | exceptions. The agent wraps the browser API to record context about your 6 | application, network, and visitor, and include that context when unhandled 7 | errors occur. 8 | 9 | You'll need a TrackJS account to use this agent. If you don't have one, [why not 10 | start a free trial today?](https://trackjs.com/signup) 11 | 12 | ## Quick Start 13 | 14 | 1. [Signup for TrackJS](https://trackjs.com/signup) and get your token. 15 | 2. Add a dependency on TrackJS with `npm install trackjs --save` 16 | 3. Install the agent in your app. You can paste the script tags into the 17 | `` of your HTML: 18 | 19 | ```html 20 | 21 | 24 | ``` 25 | 26 | Or you can bundle it as a module into your application. 27 | 28 | ```javascript 29 | import { TrackJS } from 'trackjs'; 30 | TrackJS.install({ token: 'YOUR_TOKEN_HERE' }); 31 | ``` 32 | 33 | 4. Test it out by calling `TrackJS.track('testing!')` somewhere in your 34 | application. 35 | 5. You should see your error on [TrackJS](https://my.trackjs.com/recent) within 36 | a few seconds. 37 | 38 | 39 | ## More Information 40 | 41 | You can find more information about how to install and configure the agent in 42 | the [TrackJS Documentation](https://docs.trackjs.com/). If you run into any 43 | trouble, let us know right away at `hello@trackjs.com` 44 | 45 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trackjs", 3 | "version": "3.10.4", 4 | "authors": ["TrackJS LLC"], 5 | "description": "TrackJS JavaScript error monitoring agent.", 6 | "license": "UNLICENSED", 7 | "main": "index.umd.js", 8 | "moduleType": "node", 9 | "ignore": [], 10 | "keywords": [ 11 | "error", 12 | "exception", 13 | "monitoring", 14 | "tracking", 15 | "logging", 16 | "crash reporting" 17 | ], 18 | "homepage": "https://trackjs.com/", 19 | "repository": { 20 | "type": "git", 21 | "url": "git://github.com/TrackJs/trackjs-package.git" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for TrackJS 3.10.4 2 | // Project: https://github.com/TrackJS/trackjs-package 3 | 4 | interface TrackJSStatic { 5 | 6 | /** 7 | * Adds a new key-value pair to the metadata store. If the key already exists 8 | * it will be updated. 9 | * 10 | * @param {String} key 11 | * @param {String} value 12 | */ 13 | addMetadata(key: string, value: string): void; 14 | 15 | /** 16 | * Invokes the provided function within a try/catch wrapper that forwards 17 | * the error to TrackJS. 18 | * 19 | * @param {Function} func The function to be invoked. 20 | * @param {Object} context The context to invoke the function with. 21 | * @param {...} Additional arguments passed to the function. 22 | * @return {*} Output of the function. 23 | */ 24 | attempt(func: Function, context?: any, ...args: any[]): any; 25 | 26 | /** 27 | * Configures the instance of TrackJS with the provided configuration. 28 | * 29 | * @param {Object} options The Configuration object to apply 30 | * @returns {Boolean} True if the configuration was successful. 31 | */ 32 | configure(options: TrackJSConfigureOptions): boolean; 33 | 34 | /** 35 | * Non-exposed browser console logging. Use this private console to prevent 36 | * messages from being exposed into the standard browser console. 37 | */ 38 | console: { 39 | 40 | /** 41 | * Records context into the Telemetry log with normal severity 42 | * 43 | * @param {...} args Arguments to be serialized into the Telemetry log. 44 | */ 45 | log(...args: any[]): void; 46 | 47 | /** 48 | * Records context into the Telemetry log with DEBUG severity 49 | * 50 | * @param {...} args Arguments to be serialized into the Telemetry log. 51 | */ 52 | debug(...args: any[]): void; 53 | 54 | /** 55 | * Records context into the Telemetry log with INFO severity 56 | * 57 | * @param {...} args Arguments to be serialized into the Telemetry log. 58 | */ 59 | info(...args: any[]): void; 60 | 61 | /** 62 | * Records context into the Telemetry log with WARN severity 63 | * 64 | * @param {...} args Arguments to be serialized into the Telemetry log. 65 | */ 66 | warn(...args: any[]): void; 67 | 68 | /** 69 | * Records context into the Telemetry log with ERROR severity. If console 70 | * errors are enabled, which is default, this will also transmit an error. 71 | * 72 | * @param {...} args Arguments to be serialized into the Telemetry log. 73 | */ 74 | error(...args: any[]): void; 75 | 76 | } 77 | 78 | /** 79 | * Running version of the tracker script 80 | */ 81 | hash: string; 82 | 83 | /** 84 | * Installs the agent into the current browser document. 85 | * 86 | * @param options The configuration object to apply. 87 | */ 88 | install(options: TrackJSInstallOptions): boolean; 89 | 90 | /** 91 | * Whether the agent has been installed into the current environment 92 | * 93 | * @returns {boolean} 94 | */ 95 | isInstalled(): boolean; 96 | 97 | /** 98 | * Removes a key from the metadata store, if it exists. 99 | * 100 | * @param {String} key 101 | */ 102 | removeMetadata(key: string): void; 103 | 104 | /** 105 | * Directly invokes an error to be sent to TrackJS. 106 | * 107 | * @param {Error|Object|String} error The error to be tracked. If error does 108 | * not have a stacktrace, will attempt to generate one. 109 | */ 110 | track(error: Error | Object | String): void; 111 | 112 | /** 113 | * Running version of the tracker script 114 | */ 115 | version: string; 116 | 117 | /** 118 | * Returns a wrapped and watched version of the function to automatically 119 | * catch any errors that may arise. 120 | * 121 | * @param {Function} func The function to be watched. 122 | * @param {Object} context The context to invoke the function with. 123 | * @return {Function} Wrapped function 124 | */ 125 | watch(func: Function, context?: any): Function; 126 | 127 | /** 128 | * Wrap and watch all of the functions on an object that will 129 | * automatically catch any errors that may arise. 130 | * 131 | * @param {Object} obj The Object containing functions to be watched 132 | * @return {Object} Object now containing wrapped functions. 133 | */ 134 | watchAll(obj: Object): Object; 135 | } 136 | 137 | /** 138 | * String formatted as an ISO-8601 Date. Example 0000-00-00T00:00:00.000Z 139 | */ 140 | export interface ISO8601DateString extends String { } 141 | 142 | /** 143 | * Payload of an error sent to TrackJS. Useful when manipulating errors via 144 | * the `onError` callback. 145 | */ 146 | export interface TrackJSErrorPayload { 147 | /** Stack trace at time of asynchronous callback binding. */ 148 | bindStack?: string; 149 | /** Timestamp of the asynchronous callback binding. */ 150 | bindTime?: ISO8601DateString; 151 | /** Browser Console Telemetry */ 152 | console: { 153 | /** Timestamp the event occurred */ 154 | timestamp: ISO8601DateString; 155 | /** Console severity of the event */ 156 | severity: string; 157 | /** Formatted message captured */ 158 | message: string; 159 | }[]; 160 | /** Context provided about the customer session */ 161 | customer: { 162 | /** Customer application id */ 163 | application?: string; 164 | /** Unique Id describing the current page view */ 165 | correlationId: string; 166 | /** Customer-provided visitor session ID */ 167 | sessionId?: string; 168 | /** Customer token */ 169 | token: string; 170 | /** Customer-provided visitor user ID */ 171 | userId?: string; 172 | /** Customer-provided system version ID */ 173 | version?: string; 174 | }; 175 | /** How the error was captured. */ 176 | entry: string; 177 | /** Context about the browser environment */ 178 | environment: { 179 | /** How long the visitor has been on the page in MS */ 180 | age: number; 181 | /** Other discovered JavaScript libraries on the DOM. */ 182 | dependencies: { [name: string]: string }; 183 | /** browser userAgent string */ 184 | userAgent: string; 185 | /** current window height */ 186 | viewportHeight: number; 187 | /** current window width */ 188 | viewportWidth: number; 189 | }; 190 | /** Custom environment metadata. */ 191 | metadata: { 192 | /** metadata group name */ 193 | key: string; 194 | /** metadata value */ 195 | value: string; 196 | }[]; 197 | /** Error message */ 198 | message: string; 199 | /** Navigation Telemetry */ 200 | nav: { 201 | /** Timestamp of the navigation event */ 202 | "on": ISO8601DateString; 203 | /** Navigation method used. IE "replaceState" "setState" */ 204 | "type": string; 205 | /** Previous URL */ 206 | "from": string; 207 | /** New URL */ 208 | "to": string 209 | }[]; 210 | /** Network Telemetry */ 211 | network: { 212 | /** Timestamp the request started */ 213 | startedOn: ISO8601DateString; 214 | /** Timestamp the request completed */ 215 | completedOn?: ISO8601DateString; 216 | /** HTTP Method used */ 217 | method: string; 218 | /** URL Requested */ 219 | url: string; 220 | /** HTTP Status Code */ 221 | statusCode?: number; 222 | /** HTTP Status Text */ 223 | statusText?: string; 224 | /** Mechanism of network use. IE "fetch", "xhr" */ 225 | type: string; 226 | }[]; 227 | /** location of the browser at the time of the error */ 228 | url: string; 229 | /** stack trace */ 230 | stack: string; 231 | /** client-reported time the error occurred */ 232 | timestamp: ISO8601DateString; 233 | /** Visitor Action Telemetry */ 234 | visitor: { 235 | /** timestamp the event occurred */ 236 | timestamp: ISO8601DateString; 237 | /** visitor action taken. "input" or "click" */ 238 | action: string; 239 | /** DOM element acted upon */ 240 | element: { 241 | /** name of the element tag. IE "input" */ 242 | tag: string; 243 | /** hashmap of element attributes */ 244 | attributes: { [attributeName: string]: string }; 245 | /** value of the element */ 246 | value: { 247 | /** Number of characters in the value */ 248 | length: number; 249 | /** Patterns describing the value. */ 250 | pattern: string; 251 | }; 252 | }; 253 | }[]; 254 | /** version of the tracker.js lib */ 255 | version: string; 256 | /** Number of messages throttled clientside */ 257 | throttled: number; 258 | } 259 | 260 | /** 261 | * Configuration options that can be passed to `trackJs.configure()` 262 | */ 263 | export interface TrackJSConfigureOptions { 264 | 265 | /** 266 | * Whether duplicate errors should be suppressed before sending. 267 | * @default true 268 | */ 269 | dedupe?: boolean; 270 | 271 | /** 272 | * Whether to attempt discovery of other JavaScript libs on the page. 273 | * @default true 274 | */ 275 | dependencies?: boolean; 276 | 277 | /** 278 | * Custom handler to be notified *before* an error is transmitted. Can be used 279 | * to modify or ignore error data. 280 | * 281 | * @param {TrackJSErrorPayload} payload Error payload to send to TrackJS. 282 | * @param {Error} error Error object that initiated the capture. 283 | */ 284 | onError?: (payload: TrackJSErrorPayload, error?: Error) => boolean; 285 | 286 | /** 287 | * Custom handler for serializing non-string data in errors and telemetry 288 | * events. 289 | */ 290 | serialize?: (what: any) => string; 291 | 292 | /** 293 | * Id of the visitor session. Use this to correlate TrackJS 294 | * Error reports with other reporting data. 295 | */ 296 | sessionId?: string; 297 | 298 | /** 299 | * Id of the visitor. Use this to identify the current user for support. 300 | */ 301 | userId?: string; 302 | 303 | /** 304 | * Id of the running application. Recommend to use either a SEMVER 305 | * representation, or a VCS Hash Key. 306 | */ 307 | version?: string; 308 | 309 | } 310 | 311 | /** 312 | * Configuration options that are initialized from `window._trackJs` 313 | */ 314 | export interface TrackJSInstallOptions extends TrackJSConfigureOptions { 315 | 316 | /** 317 | * TrackJS Application token. Get this from `https://my.trackjs.com/Account/Applications` 318 | */ 319 | application?: string; 320 | 321 | callback?: { 322 | /** 323 | * Whether errors should be recorded when caught from callback functions. 324 | * @default true 325 | */ 326 | enabled?: boolean; 327 | /** 328 | * Whether stack traces should be generated at the time of invocation of an 329 | * asynchronous action. This will produce stack traces similar to the 330 | * "async" traces in Chrome Developer tools. 331 | * There is a performance impact to enabling this. Confirm behavior in your 332 | * application before releasing. 333 | * default false. 334 | */ 335 | bindStack?: boolean; 336 | }; 337 | 338 | console?: { 339 | /** 340 | * Whether events should be recorded from the console. 341 | * @default true 342 | */ 343 | enabled?: boolean; 344 | /** 345 | * Whether console messages should be passed through to the browser console 346 | * or hidden by TrackJS. Useful for removing debug messaging from production. 347 | * @default true 348 | */ 349 | display?: boolean; 350 | /** 351 | * Whether an error should be recorded by a call to `console.error`. 352 | * @default true 353 | */ 354 | error?: boolean; 355 | /** 356 | * Whether a warning should be recorded by a call to `console.warn`. 357 | * @default false 358 | */ 359 | warn?: boolean; 360 | /** 361 | * Limit the console functions to be watched by whitelisting them here. 362 | * @default ["log","debug","info","warn","error"] 363 | */ 364 | watch?: string[]; 365 | }; 366 | 367 | /** 368 | * Whether the tracker script is enabled. 369 | * @default true 370 | */ 371 | enabled?: boolean; 372 | 373 | /** 374 | * Domain where errors and usage data to be sent in order to bypass ad blocker 375 | * restrictions to `trackjs.com`. IE "errors.example.com". 376 | */ 377 | forwardingDomain?: string; 378 | 379 | network?: { 380 | /** 381 | * Whether events should be recorded from the network. 382 | * @default true 383 | */ 384 | enabled?: boolean; 385 | /** 386 | * Whether an error should be recorded by XHR responses with status code 387 | * 400 or greater. 388 | * @default true 389 | */ 390 | error?: boolean; 391 | }; 392 | 393 | /** 394 | * Your account token. Get this from `https://my.trackjs.com/install` 395 | */ 396 | token: string; 397 | 398 | visitor?: { 399 | /** 400 | * Whether events should be recorded from the visitor actions. 401 | * @default true 402 | */ 403 | enabled?: boolean; 404 | }; 405 | 406 | window?: { 407 | /** 408 | * Whether events should be recorded from globally unhandled errors. 409 | * @default true 410 | */ 411 | enabled?: boolean; 412 | /** 413 | * Whether events should be recorded from globally unhandled promise 414 | * rejections, if supported. 415 | * @default true 416 | */ 417 | promise?: boolean; 418 | }; 419 | 420 | } 421 | 422 | declare global { 423 | var TrackJS: TrackJSStatic | undefined; 424 | interface Window { 425 | TrackJS: TrackJSStatic | undefined; 426 | } 427 | } 428 | 429 | declare var TrackJS: TrackJSStatic 430 | export { TrackJS } 431 | -------------------------------------------------------------------------------- /index.esm.js: -------------------------------------------------------------------------------- 1 | //! TrackJS JavaScript error monitoring agent. 2 | //! COPYRIGHT (c) 2023 ALL RIGHTS RESERVED 3 | //! See License at https://trackjs.com/terms/ 4 | var TrackJS = (function(g,l,n){"use awesome";var u=function(a,b){this.config=a;this.onError=b;a.enabled&&this.watch()};u.prototype={watch:function(){c.forEach(["EventTarget","Node","XMLHttpRequest"],function(a){c.has(g,a+".prototype.addEventListener")&&c.hasOwn(g[a].prototype,"addEventListener")&&this.wrapEventTarget(g[a].prototype)},this);this.wrapTimer("setTimeout");this.wrapTimer("setInterval")},wrap:function(a){function b(){try{return a.apply(this,arguments)}catch(b){throw d.onError("catch",b,{bindTime:e,bindStack:f}), 5 | c.wrapError(b);}}var d=this;try{if(!c.isFunction(a)||c.hasOwn(a,"__trackjs__"))return a;if(c.hasOwn(a,"__trackjs_state__"))return a.__trackjs_state__}catch(p){return a}var e,f;if(d.config.bindStack)try{throw Error();}catch(p){f=p.stack,e=c.isoNow()}for(var h in a)c.hasOwn(a,h)&&(b[h]=a[h]);b.prototype=a.prototype;b.__trackjs__=!0;return a.__trackjs_state__=b},wrapEventTarget:function(a){var b=this;c.has(a,"addEventListener.call")&&c.has(a,"removeEventListener.call")&&(c.patch(a,"addEventListener", 6 | function(a){return function(e,f,h,p){try{c.has(f,"handleEvent")&&(f.handleEvent=b.wrap(f.handleEvent))}catch(g){}return a.call(this,e,b.wrap(f),h,p)}}),c.patch(a,"removeEventListener",function(a){return function(b,f,c,g){try{f=f&&(f.__trackjs_state__||f)}catch(k){}return a.call(this,b,f,c,g)}}))},wrapTimer:function(a){var b=this;c.patch(g,a,function(a){return function(e,f){var h=Array.prototype.slice.call(arguments),g=h[0];c.isFunction(g)&&(h[0]=b.wrap(g));return c.has(a,"apply")?a.apply(this,h): 7 | a(h[0],h[1])}})}};var q=function(a){this.initCurrent(a)||console.warn("[TrackJS] invalid config")};q.prototype={current:{},initOnly:{application:!0,cookie:!0,enabled:!0,token:!0,callback:{enabled:!0},console:{enabled:!0},navigation:{enabled:!0},network:{enabled:!0,fetch:!0},visitor:{enabled:!0},window:{enabled:!0,promise:!0}},defaults:{application:"",cookie:!1,dedupe:!0,dependencies:!0,enabled:!0,forwardingDomain:"",errorURL:"https://capture.trackjs.com/capture",errorNoSSLURL:"http://capture.trackjs.com/capture", 8 | faultURL:"https://usage.trackjs.com/fault.gif",usageURL:"https://usage.trackjs.com/usage.gif",onError:function(){return!0},serialize:function(a){function b(a){var d="<"+a.tagName.toLowerCase();a=a.attributes||[];for(var b=0;b"}if(""===a)return"Empty String";if(a===n)return"undefined";if(c.isString(a)||c.isNumber(a)||c.isBoolean(a)||c.isFunction(a))return""+a;if(c.isElement(a))return b(a);if("symbol"===typeof a)return Symbol.prototype.toString.call(a); 9 | var d;try{d=JSON.stringify(a,function(a,d){return d===n?"undefined":c.isNumber(d)&&isNaN(d)?"NaN":c.isError(d)?{name:d.name,message:d.message,stack:d.stack}:c.isElement(d)?b(d):d})}catch(f){d="";for(var e in a)if(a.hasOwnProperty(e))try{d+=',"'+e+'":"'+a[e]+'"'}catch(h){}d=d?"{"+d.replace(",","")+"}":"Unserializable Object"}return d.replace(/"undefined"/g,"undefined").replace(/"NaN"/g,"NaN")},sessionId:"",token:"",userId:"",version:"",callback:{enabled:!0,bindStack:!1},console:{enabled:!0,display:!0, 10 | error:!0,warn:!1,watch:["log","debug","info","warn","error"]},navigation:{enabled:!0},network:{enabled:!0,error:!0,fetch:!0},visitor:{enabled:!0},window:{enabled:!0,promise:!0}},initCurrent:function(a){this.removeEmpty(a);if(this.validate(a,this.defaults,"[TrackJS] config",{}))return this.current=c.defaultsDeep({},a,this.defaults),!0;this.current=c.defaultsDeep({},this.defaults);return!1},setCurrent:function(a){return this.validate(a,this.defaults,"[TrackJS] config",this.initOnly)?(this.current=c.defaultsDeep({}, 11 | a,this.current),!0):!1},removeEmpty:function(a){for(var b in a)a.hasOwnProperty(b)&&a[b]===n&&delete a[b]},validate:function(a,b,d,e){var f=!0;d=d||"";e=e||{};for(var c in a)if(a.hasOwnProperty(c))if(b.hasOwnProperty(c)){var g=typeof b[c];g!==typeof a[c]?(console.warn(d+"."+c+": property must be type "+g+"."),f=!1):"[object Array]"!==Object.prototype.toString.call(a[c])||this.validateArray(a[c],b[c],d+"."+c)?"[object Object]"===Object.prototype.toString.call(a[c])?f=this.validate(a[c],b[c],d+"."+ 12 | c,e[c]):e.hasOwnProperty(c)&&(console.warn(d+"."+c+": property cannot be set after load."),f=!1):f=!1}else console.warn(d+"."+c+": property not supported."),f=!1;return f},validateArray:function(a,b,d){var e=!0;d=d||"";for(var f=0;fthis.maxLength&&(this.appender= 19 | this.appender.slice(Math.max(this.appender.length-this.maxLength,0)))},add:function(a,b){var d=this.util.uuid();this.appender.push({key:d,category:a,value:b});this.truncate();return d},get:function(a,b){var d,e;for(e=0;ec.indexOf("localhost:0")&&(c=b.escapeUrl(c),this._trackJs={method:a,url:c});return d.apply(this,arguments)};a.prototype.send=function(){if(!this._trackJs)try{return e.apply(this,arguments)}catch(a){b.onError("ajax",a);return}try{this._trackJs.logId=b.log.add("n",{type:"xhr",startedOn:b.util.isoNow(),method:this._trackJs.method,url:c.truncate(this._trackJs.url,2E3)}),b.listenForNetworkComplete(this)}catch(a){b.onFault(a)}return e.apply(this,arguments)};return a},listenForNetworkComplete:function(a){var b= 26 | this;b.window.ProgressEvent&&a.addEventListener&&a.addEventListener("readystatechange",function(){4===a.readyState&&b.finalizeNetworkEvent(a)},!0);a.addEventListener?a.addEventListener("load",function(){b.finalizeNetworkEvent(a);b.checkNetworkFault(a)},!0):setTimeout(function(){try{var d=a.onload;a.onload=function(){b.finalizeNetworkEvent(a);b.checkNetworkFault(a);"function"===typeof d&&b.util.hasFunction(d,"apply")&&d.apply(a,arguments)};var e=a.onerror;a.onerror=function(){b.finalizeNetworkEvent(a); 27 | b.checkNetworkFault(a);"function"===typeof oldOnError&&e.apply(a,arguments)}}catch(c){b.onFault(c)}},0)},finalizeNetworkEvent:function(a){if(a._trackJs){var b=this.log.get("n",a._trackJs.logId);b&&(b.completedOn=this.util.isoNow(),a.getAllResponseHeaders&&a.getResponseHeader&&0<=(a.getAllResponseHeaders()||"").toLowerCase().indexOf("trackjs-correlation-id")&&(b.requestCorrelationId=a.getResponseHeader("trackjs-correlation-id")),b.statusCode=1223==a.status?204:a.status,b.statusText=1223==a.status? 28 | "No Content":a.statusText)}},checkNetworkFault:function(a){if(this.options.error&&400<=a.status&&1223!=a.status){var b=a._trackJs||{};this.onError("ajax",a.status+" : "+b.method+" "+b.url)}},report:function(){return this.log.all("n")}};var t=function(a,b){this.util=a;this.config=b;this.disabled=!1;this.throttleStats={attemptCount:0,throttledCount:0,lastAttempt:(new Date).getTime()};g.JSON&&g.JSON.stringify||(this.disabled=!0)};t.prototype={errorEndpoint:function(a){var b=this.config.current,d=b.errorURL; 29 | c.isBrowser&&!c.testCrossdomainXhr()&&-1===g.location.protocol.indexOf("https")?d=b.errorNoSSLURL:b.forwardingDomain&&(d="https://"+b.forwardingDomain+"/capture");return d+"?token="+a+"&v=3.10.4"},usageEndpoint:function(a){var b=this.config.current,d=b.usageURL;b.forwardingDomain&&(d="https://"+b.forwardingDomain+"/usage.gif");return this.appendObjectAsQuery(a,d)},trackerFaultEndpoint:function(a){var b=(this.config||{}).current||q.prototype.defaults,d=b.faultURL;b.forwardingDomain&&(d="https://"+ 30 | b.forwardingDomain+"/fault.gif");return this.appendObjectAsQuery(a,d)},appendObjectAsQuery:function(a,b){b+="?";for(var d in a)a.hasOwnProperty(d)&&(b+=encodeURIComponent(d)+"="+encodeURIComponent(a[d])+"&");return b},getCORSRequest:function(a,b){var d;this.util.testCrossdomainXhr()?(d=new g.XMLHttpRequest,d.open(a,b),d.setRequestHeader("Content-Type","text/plain")):"undefined"!==typeof g.XDomainRequest?(d=new g.XDomainRequest,d.open(a,b)):d=null;return d},sendTrackerFault:function(a){this.throttle(a)|| 31 | (c.isBrowser?l.createElement("img").src=this.trackerFaultEndpoint(a):fetch(this.trackerFaultEndpoint(a),{mode:"no-cors",__trackjs__:!0}))},sendUsage:function(a){c.isBrowser?l.createElement("img").src=this.usageEndpoint(a):fetch(this.usageEndpoint(a),{mode:"no-cors",__trackjs__:!0})},sendError:function(a,b){var d=this;if(!this.disabled&&!this.throttle(a))try{if(c.isBrowser){var e=this.getCORSRequest("POST",this.errorEndpoint(b));e.onreadystatechange=function(){4!==e.readyState||c.contains([200,202], 32 | e.status)||(d.disabled=!0)};e._trackJs=n;e.send(g.JSON.stringify(a))}else if(c.isWorker){var f={method:"POST",mode:"cors",body:g.JSON.stringify(a),__trackjs__:1};fetch(this.errorEndpoint(b),f).then(function(a){a.ok||(d.disabled=!0)})["catch"](function(a){d.disabled=!0})}}catch(h){throw this.disabled=!0,h;}},throttle:function(a){var b=(new Date).getTime();this.throttleStats.attemptCount++;if(this.throttleStats.lastAttempt+1E3>=b){if(this.throttleStats.lastAttempt=b,10h&&"[object Object]"===b(e[c])?(d[c]=d[c]||{},a(d[c],[e[c]],f,h+1)):d.hasOwnProperty(c)||(d[c]=e[c])})});return d}function b(a){return Object.prototype.toString.call(a)}return{isBrowser:"undefined"!== 34 | typeof g&&"undefined"!==typeof g.document,isWorker:"object"===typeof self&&self.constructor&&0<=(self.constructor.name||"").indexOf("WorkerGlobalScope"),isNode:"undefined"!==typeof process&&null!=process.versions&&null!=process.versions.node,addEventListenerSafe:function(a,b,c,h){a.addEventListener?a.addEventListener(b,c,h):a.attachEvent&&a.attachEvent("on"+b,c)},afterDocumentLoad:function(a){if(c.isWorker)c.defer(a);else{var b=!1;"complete"===l.readyState?c.defer(a):(c.addEventListenerSafe(l,"readystatechange", 35 | function(){"complete"!==l.readyState||b||(c.defer(a),b=!0)}),setTimeout(function(){b||(c.defer(a),b=!0)},1E4))}},bind:function(a,b){return function(){return a.apply(b,Array.prototype.slice.call(arguments))}},contains:function(a,b){return 0<=a.indexOf(b)},defaults:function(d){return a(d,Array.prototype.slice.call(arguments,1),!1)},defaultsDeep:function(d){return a(d,Array.prototype.slice.call(arguments,1),!0)},defer:function(a,b){setTimeout(function(){a.apply(b)})},forEach:function(a,b,f){if(c.isArray(a)){if(a.forEach)return a.forEach(b, 36 | f);for(var h=0;h"}if(""===a)return"Empty String";if(a===n)return"undefined";if(c.isString(a)||c.isNumber(a)||c.isBoolean(a)||c.isFunction(a))return""+a;if(c.isElement(a))return b(a);if("symbol"===typeof a)return Symbol.prototype.toString.call(a); 14 | var d;try{d=JSON.stringify(a,function(a,d){return d===n?"undefined":c.isNumber(d)&&isNaN(d)?"NaN":c.isError(d)?{name:d.name,message:d.message,stack:d.stack}:c.isElement(d)?b(d):d})}catch(f){d="";for(var e in a)if(a.hasOwnProperty(e))try{d+=',"'+e+'":"'+a[e]+'"'}catch(h){}d=d?"{"+d.replace(",","")+"}":"Unserializable Object"}return d.replace(/"undefined"/g,"undefined").replace(/"NaN"/g,"NaN")},sessionId:"",token:"",userId:"",version:"",callback:{enabled:!0,bindStack:!1},console:{enabled:!0,display:!0, 15 | error:!0,warn:!1,watch:["log","debug","info","warn","error"]},navigation:{enabled:!0},network:{enabled:!0,error:!0,fetch:!0},visitor:{enabled:!0},window:{enabled:!0,promise:!0}},initCurrent:function(a){this.removeEmpty(a);if(this.validate(a,this.defaults,"[TrackJS] config",{}))return this.current=c.defaultsDeep({},a,this.defaults),!0;this.current=c.defaultsDeep({},this.defaults);return!1},setCurrent:function(a){return this.validate(a,this.defaults,"[TrackJS] config",this.initOnly)?(this.current=c.defaultsDeep({}, 16 | a,this.current),!0):!1},removeEmpty:function(a){for(var b in a)a.hasOwnProperty(b)&&a[b]===n&&delete a[b]},validate:function(a,b,d,e){var f=!0;d=d||"";e=e||{};for(var c in a)if(a.hasOwnProperty(c))if(b.hasOwnProperty(c)){var g=typeof b[c];g!==typeof a[c]?(console.warn(d+"."+c+": property must be type "+g+"."),f=!1):"[object Array]"!==Object.prototype.toString.call(a[c])||this.validateArray(a[c],b[c],d+"."+c)?"[object Object]"===Object.prototype.toString.call(a[c])?f=this.validate(a[c],b[c],d+"."+ 17 | c,e[c]):e.hasOwnProperty(c)&&(console.warn(d+"."+c+": property cannot be set after load."),f=!1):f=!1}else console.warn(d+"."+c+": property not supported."),f=!1;return f},validateArray:function(a,b,d){var e=!0;d=d||"";for(var f=0;fthis.maxLength&&(this.appender= 24 | this.appender.slice(Math.max(this.appender.length-this.maxLength,0)))},add:function(a,b){var d=this.util.uuid();this.appender.push({key:d,category:a,value:b});this.truncate();return d},get:function(a,b){var d,e;for(e=0;ec.indexOf("localhost:0")&&(c=b.escapeUrl(c),this._trackJs={method:a,url:c});return d.apply(this,arguments)};a.prototype.send=function(){if(!this._trackJs)try{return e.apply(this,arguments)}catch(a){b.onError("ajax",a);return}try{this._trackJs.logId=b.log.add("n",{type:"xhr",startedOn:b.util.isoNow(),method:this._trackJs.method,url:c.truncate(this._trackJs.url,2E3)}),b.listenForNetworkComplete(this)}catch(a){b.onFault(a)}return e.apply(this,arguments)};return a},listenForNetworkComplete:function(a){var b= 31 | this;b.window.ProgressEvent&&a.addEventListener&&a.addEventListener("readystatechange",function(){4===a.readyState&&b.finalizeNetworkEvent(a)},!0);a.addEventListener?a.addEventListener("load",function(){b.finalizeNetworkEvent(a);b.checkNetworkFault(a)},!0):setTimeout(function(){try{var d=a.onload;a.onload=function(){b.finalizeNetworkEvent(a);b.checkNetworkFault(a);"function"===typeof d&&b.util.hasFunction(d,"apply")&&d.apply(a,arguments)};var e=a.onerror;a.onerror=function(){b.finalizeNetworkEvent(a); 32 | b.checkNetworkFault(a);"function"===typeof oldOnError&&e.apply(a,arguments)}}catch(c){b.onFault(c)}},0)},finalizeNetworkEvent:function(a){if(a._trackJs){var b=this.log.get("n",a._trackJs.logId);b&&(b.completedOn=this.util.isoNow(),a.getAllResponseHeaders&&a.getResponseHeader&&0<=(a.getAllResponseHeaders()||"").toLowerCase().indexOf("trackjs-correlation-id")&&(b.requestCorrelationId=a.getResponseHeader("trackjs-correlation-id")),b.statusCode=1223==a.status?204:a.status,b.statusText=1223==a.status? 33 | "No Content":a.statusText)}},checkNetworkFault:function(a){if(this.options.error&&400<=a.status&&1223!=a.status){var b=a._trackJs||{};this.onError("ajax",a.status+" : "+b.method+" "+b.url)}},report:function(){return this.log.all("n")}};var t=function(a,b){this.util=a;this.config=b;this.disabled=!1;this.throttleStats={attemptCount:0,throttledCount:0,lastAttempt:(new Date).getTime()};g.JSON&&g.JSON.stringify||(this.disabled=!0)};t.prototype={errorEndpoint:function(a){var b=this.config.current,d=b.errorURL; 34 | c.isBrowser&&!c.testCrossdomainXhr()&&-1===g.location.protocol.indexOf("https")?d=b.errorNoSSLURL:b.forwardingDomain&&(d="https://"+b.forwardingDomain+"/capture");return d+"?token="+a+"&v=3.10.4"},usageEndpoint:function(a){var b=this.config.current,d=b.usageURL;b.forwardingDomain&&(d="https://"+b.forwardingDomain+"/usage.gif");return this.appendObjectAsQuery(a,d)},trackerFaultEndpoint:function(a){var b=(this.config||{}).current||q.prototype.defaults,d=b.faultURL;b.forwardingDomain&&(d="https://"+ 35 | b.forwardingDomain+"/fault.gif");return this.appendObjectAsQuery(a,d)},appendObjectAsQuery:function(a,b){b+="?";for(var d in a)a.hasOwnProperty(d)&&(b+=encodeURIComponent(d)+"="+encodeURIComponent(a[d])+"&");return b},getCORSRequest:function(a,b){var d;this.util.testCrossdomainXhr()?(d=new g.XMLHttpRequest,d.open(a,b),d.setRequestHeader("Content-Type","text/plain")):"undefined"!==typeof g.XDomainRequest?(d=new g.XDomainRequest,d.open(a,b)):d=null;return d},sendTrackerFault:function(a){this.throttle(a)|| 36 | (c.isBrowser?l.createElement("img").src=this.trackerFaultEndpoint(a):fetch(this.trackerFaultEndpoint(a),{mode:"no-cors",__trackjs__:!0}))},sendUsage:function(a){c.isBrowser?l.createElement("img").src=this.usageEndpoint(a):fetch(this.usageEndpoint(a),{mode:"no-cors",__trackjs__:!0})},sendError:function(a,b){var d=this;if(!this.disabled&&!this.throttle(a))try{if(c.isBrowser){var e=this.getCORSRequest("POST",this.errorEndpoint(b));e.onreadystatechange=function(){4!==e.readyState||c.contains([200,202], 37 | e.status)||(d.disabled=!0)};e._trackJs=n;e.send(g.JSON.stringify(a))}else if(c.isWorker){var f={method:"POST",mode:"cors",body:g.JSON.stringify(a),__trackjs__:1};fetch(this.errorEndpoint(b),f).then(function(a){a.ok||(d.disabled=!0)})["catch"](function(a){d.disabled=!0})}}catch(h){throw this.disabled=!0,h;}},throttle:function(a){var b=(new Date).getTime();this.throttleStats.attemptCount++;if(this.throttleStats.lastAttempt+1E3>=b){if(this.throttleStats.lastAttempt=b,10h&&"[object Object]"===b(e[c])?(d[c]=d[c]||{},a(d[c],[e[c]],f,h+1)):d.hasOwnProperty(c)||(d[c]=e[c])})});return d}function b(a){return Object.prototype.toString.call(a)}return{isBrowser:"undefined"!== 39 | typeof g&&"undefined"!==typeof g.document,isWorker:"object"===typeof self&&self.constructor&&0<=(self.constructor.name||"").indexOf("WorkerGlobalScope"),isNode:"undefined"!==typeof process&&null!=process.versions&&null!=process.versions.node,addEventListenerSafe:function(a,b,c,h){a.addEventListener?a.addEventListener(b,c,h):a.attachEvent&&a.attachEvent("on"+b,c)},afterDocumentLoad:function(a){if(c.isWorker)c.defer(a);else{var b=!1;"complete"===l.readyState?c.defer(a):(c.addEventListenerSafe(l,"readystatechange", 40 | function(){"complete"!==l.readyState||b||(c.defer(a),b=!0)}),setTimeout(function(){b||(c.defer(a),b=!0)},1E4))}},bind:function(a,b){return function(){return a.apply(b,Array.prototype.slice.call(arguments))}},contains:function(a,b){return 0<=a.indexOf(b)},defaults:function(d){return a(d,Array.prototype.slice.call(arguments,1),!1)},defaultsDeep:function(d){return a(d,Array.prototype.slice.call(arguments,1),!0)},defer:function(a,b){setTimeout(function(){a.apply(b)})},forEach:function(a,b,f){if(c.isArray(a)){if(a.forEach)return a.forEach(b, 41 | f);for(var h=0;h"}if(""===a)return"Empty String";if(a===n)return"undefined";if(c.isString(a)||c.isNumber(a)||c.isBoolean(a)||c.isFunction(a))return""+a;if(c.isElement(a))return b(a);if("symbol"===typeof a)return Symbol.prototype.toString.call(a); 9 | var d;try{d=JSON.stringify(a,function(a,d){return d===n?"undefined":c.isNumber(d)&&isNaN(d)?"NaN":c.isError(d)?{name:d.name,message:d.message,stack:d.stack}:c.isElement(d)?b(d):d})}catch(f){d="";for(var e in a)if(a.hasOwnProperty(e))try{d+=',"'+e+'":"'+a[e]+'"'}catch(h){}d=d?"{"+d.replace(",","")+"}":"Unserializable Object"}return d.replace(/"undefined"/g,"undefined").replace(/"NaN"/g,"NaN")},sessionId:"",token:"",userId:"",version:"",callback:{enabled:!0,bindStack:!1},console:{enabled:!0,display:!0, 10 | error:!0,warn:!1,watch:["log","debug","info","warn","error"]},navigation:{enabled:!0},network:{enabled:!0,error:!0,fetch:!0},visitor:{enabled:!0},window:{enabled:!0,promise:!0}},initCurrent:function(a){this.removeEmpty(a);if(this.validate(a,this.defaults,"[TrackJS] config",{}))return this.current=c.defaultsDeep({},a,this.defaults),!0;this.current=c.defaultsDeep({},this.defaults);return!1},setCurrent:function(a){return this.validate(a,this.defaults,"[TrackJS] config",this.initOnly)?(this.current=c.defaultsDeep({}, 11 | a,this.current),!0):!1},removeEmpty:function(a){for(var b in a)a.hasOwnProperty(b)&&a[b]===n&&delete a[b]},validate:function(a,b,d,e){var f=!0;d=d||"";e=e||{};for(var c in a)if(a.hasOwnProperty(c))if(b.hasOwnProperty(c)){var g=typeof b[c];g!==typeof a[c]?(console.warn(d+"."+c+": property must be type "+g+"."),f=!1):"[object Array]"!==Object.prototype.toString.call(a[c])||this.validateArray(a[c],b[c],d+"."+c)?"[object Object]"===Object.prototype.toString.call(a[c])?f=this.validate(a[c],b[c],d+"."+ 12 | c,e[c]):e.hasOwnProperty(c)&&(console.warn(d+"."+c+": property cannot be set after load."),f=!1):f=!1}else console.warn(d+"."+c+": property not supported."),f=!1;return f},validateArray:function(a,b,d){var e=!0;d=d||"";for(var f=0;fthis.maxLength&&(this.appender= 19 | this.appender.slice(Math.max(this.appender.length-this.maxLength,0)))},add:function(a,b){var d=this.util.uuid();this.appender.push({key:d,category:a,value:b});this.truncate();return d},get:function(a,b){var d,e;for(e=0;ec.indexOf("localhost:0")&&(c=b.escapeUrl(c),this._trackJs={method:a,url:c});return d.apply(this,arguments)};a.prototype.send=function(){if(!this._trackJs)try{return e.apply(this,arguments)}catch(a){b.onError("ajax",a);return}try{this._trackJs.logId=b.log.add("n",{type:"xhr",startedOn:b.util.isoNow(),method:this._trackJs.method,url:c.truncate(this._trackJs.url,2E3)}),b.listenForNetworkComplete(this)}catch(a){b.onFault(a)}return e.apply(this,arguments)};return a},listenForNetworkComplete:function(a){var b= 26 | this;b.window.ProgressEvent&&a.addEventListener&&a.addEventListener("readystatechange",function(){4===a.readyState&&b.finalizeNetworkEvent(a)},!0);a.addEventListener?a.addEventListener("load",function(){b.finalizeNetworkEvent(a);b.checkNetworkFault(a)},!0):setTimeout(function(){try{var d=a.onload;a.onload=function(){b.finalizeNetworkEvent(a);b.checkNetworkFault(a);"function"===typeof d&&b.util.hasFunction(d,"apply")&&d.apply(a,arguments)};var e=a.onerror;a.onerror=function(){b.finalizeNetworkEvent(a); 27 | b.checkNetworkFault(a);"function"===typeof oldOnError&&e.apply(a,arguments)}}catch(c){b.onFault(c)}},0)},finalizeNetworkEvent:function(a){if(a._trackJs){var b=this.log.get("n",a._trackJs.logId);b&&(b.completedOn=this.util.isoNow(),a.getAllResponseHeaders&&a.getResponseHeader&&0<=(a.getAllResponseHeaders()||"").toLowerCase().indexOf("trackjs-correlation-id")&&(b.requestCorrelationId=a.getResponseHeader("trackjs-correlation-id")),b.statusCode=1223==a.status?204:a.status,b.statusText=1223==a.status? 28 | "No Content":a.statusText)}},checkNetworkFault:function(a){if(this.options.error&&400<=a.status&&1223!=a.status){var b=a._trackJs||{};this.onError("ajax",a.status+" : "+b.method+" "+b.url)}},report:function(){return this.log.all("n")}};var t=function(a,b){this.util=a;this.config=b;this.disabled=!1;this.throttleStats={attemptCount:0,throttledCount:0,lastAttempt:(new Date).getTime()};g.JSON&&g.JSON.stringify||(this.disabled=!0)};t.prototype={errorEndpoint:function(a){var b=this.config.current,d=b.errorURL; 29 | c.isBrowser&&!c.testCrossdomainXhr()&&-1===g.location.protocol.indexOf("https")?d=b.errorNoSSLURL:b.forwardingDomain&&(d="https://"+b.forwardingDomain+"/capture");return d+"?token="+a+"&v=3.10.4"},usageEndpoint:function(a){var b=this.config.current,d=b.usageURL;b.forwardingDomain&&(d="https://"+b.forwardingDomain+"/usage.gif");return this.appendObjectAsQuery(a,d)},trackerFaultEndpoint:function(a){var b=(this.config||{}).current||q.prototype.defaults,d=b.faultURL;b.forwardingDomain&&(d="https://"+ 30 | b.forwardingDomain+"/fault.gif");return this.appendObjectAsQuery(a,d)},appendObjectAsQuery:function(a,b){b+="?";for(var d in a)a.hasOwnProperty(d)&&(b+=encodeURIComponent(d)+"="+encodeURIComponent(a[d])+"&");return b},getCORSRequest:function(a,b){var d;this.util.testCrossdomainXhr()?(d=new g.XMLHttpRequest,d.open(a,b),d.setRequestHeader("Content-Type","text/plain")):"undefined"!==typeof g.XDomainRequest?(d=new g.XDomainRequest,d.open(a,b)):d=null;return d},sendTrackerFault:function(a){this.throttle(a)|| 31 | (c.isBrowser?l.createElement("img").src=this.trackerFaultEndpoint(a):fetch(this.trackerFaultEndpoint(a),{mode:"no-cors",__trackjs__:!0}))},sendUsage:function(a){c.isBrowser?l.createElement("img").src=this.usageEndpoint(a):fetch(this.usageEndpoint(a),{mode:"no-cors",__trackjs__:!0})},sendError:function(a,b){var d=this;if(!this.disabled&&!this.throttle(a))try{if(c.isBrowser){var e=this.getCORSRequest("POST",this.errorEndpoint(b));e.onreadystatechange=function(){4!==e.readyState||c.contains([200,202], 32 | e.status)||(d.disabled=!0)};e._trackJs=n;e.send(g.JSON.stringify(a))}else if(c.isWorker){var f={method:"POST",mode:"cors",body:g.JSON.stringify(a),__trackjs__:1};fetch(this.errorEndpoint(b),f).then(function(a){a.ok||(d.disabled=!0)})["catch"](function(a){d.disabled=!0})}}catch(h){throw this.disabled=!0,h;}},throttle:function(a){var b=(new Date).getTime();this.throttleStats.attemptCount++;if(this.throttleStats.lastAttempt+1E3>=b){if(this.throttleStats.lastAttempt=b,10h&&"[object Object]"===b(e[c])?(d[c]=d[c]||{},a(d[c],[e[c]],f,h+1)):d.hasOwnProperty(c)||(d[c]=e[c])})});return d}function b(a){return Object.prototype.toString.call(a)}return{isBrowser:"undefined"!== 34 | typeof g&&"undefined"!==typeof g.document,isWorker:"object"===typeof self&&self.constructor&&0<=(self.constructor.name||"").indexOf("WorkerGlobalScope"),isNode:"undefined"!==typeof process&&null!=process.versions&&null!=process.versions.node,addEventListenerSafe:function(a,b,c,h){a.addEventListener?a.addEventListener(b,c,h):a.attachEvent&&a.attachEvent("on"+b,c)},afterDocumentLoad:function(a){if(c.isWorker)c.defer(a);else{var b=!1;"complete"===l.readyState?c.defer(a):(c.addEventListenerSafe(l,"readystatechange", 35 | function(){"complete"!==l.readyState||b||(c.defer(a),b=!0)}),setTimeout(function(){b||(c.defer(a),b=!0)},1E4))}},bind:function(a,b){return function(){return a.apply(b,Array.prototype.slice.call(arguments))}},contains:function(a,b){return 0<=a.indexOf(b)},defaults:function(d){return a(d,Array.prototype.slice.call(arguments,1),!1)},defaultsDeep:function(d){return a(d,Array.prototype.slice.call(arguments,1),!0)},defer:function(a,b){setTimeout(function(){a.apply(b)})},forEach:function(a,b,f){if(c.isArray(a)){if(a.forEach)return a.forEach(b, 36 | f);for(var h=0;h