posthog-js 1.29.1 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.d.ts CHANGED
@@ -1,8 +1,95 @@
1
- import { MaskInputOptions, SlimDOMOptions } from 'rrweb-snapshot';
2
- import { record } from 'rrweb';
3
- import { listenerHandler, eventWithTime } from 'rrweb/typings/types';
4
1
  import { Integration, EventProcessor, Hub } from '@sentry/types';
5
2
 
3
+ declare enum NodeType {
4
+ Document = 0,
5
+ DocumentType = 1,
6
+ Element = 2,
7
+ Text = 3,
8
+ CDATA = 4,
9
+ Comment = 5
10
+ }
11
+ declare type documentNode = {
12
+ type: NodeType.Document;
13
+ childNodes: serializedNodeWithId[];
14
+ compatMode?: string;
15
+ };
16
+ declare type documentTypeNode = {
17
+ type: NodeType.DocumentType;
18
+ name: string;
19
+ publicId: string;
20
+ systemId: string;
21
+ };
22
+ declare type attributes = {
23
+ [key: string]: string | number | boolean;
24
+ };
25
+ declare type elementNode = {
26
+ type: NodeType.Element;
27
+ tagName: string;
28
+ attributes: attributes;
29
+ childNodes: serializedNodeWithId[];
30
+ isSVG?: true;
31
+ needBlock?: boolean;
32
+ };
33
+ declare type textNode = {
34
+ type: NodeType.Text;
35
+ textContent: string;
36
+ isStyle?: true;
37
+ };
38
+ declare type cdataNode = {
39
+ type: NodeType.CDATA;
40
+ textContent: '';
41
+ };
42
+ declare type commentNode = {
43
+ type: NodeType.Comment;
44
+ textContent: string;
45
+ };
46
+ declare type serializedNode = (documentNode | documentTypeNode | elementNode | textNode | cdataNode | commentNode) & {
47
+ rootId?: number;
48
+ isShadowHost?: boolean;
49
+ isShadow?: boolean;
50
+ };
51
+ declare type serializedNodeWithId = serializedNode & {
52
+ id: number;
53
+ };
54
+ interface INode extends Node {
55
+ __sn: serializedNodeWithId;
56
+ }
57
+ declare type idNodeMap = {
58
+ [key: number]: INode;
59
+ };
60
+ declare type MaskInputOptions = Partial<{
61
+ color: boolean;
62
+ date: boolean;
63
+ 'datetime-local': boolean;
64
+ email: boolean;
65
+ month: boolean;
66
+ number: boolean;
67
+ range: boolean;
68
+ search: boolean;
69
+ tel: boolean;
70
+ text: boolean;
71
+ time: boolean;
72
+ url: boolean;
73
+ week: boolean;
74
+ textarea: boolean;
75
+ select: boolean;
76
+ password: boolean;
77
+ }>;
78
+ declare type SlimDOMOptions = Partial<{
79
+ script: boolean;
80
+ comment: boolean;
81
+ headFavicon: boolean;
82
+ headWhitespace: boolean;
83
+ headMetaDescKeywords: boolean;
84
+ headMetaSocial: boolean;
85
+ headMetaRobots: boolean;
86
+ headMetaHttpEquiv: boolean;
87
+ headMetaAuthorship: boolean;
88
+ headMetaVerification: boolean;
89
+ }>;
90
+ declare type MaskTextFn = (text: string) => string;
91
+ declare type MaskInputFn = (text: string) => string;
92
+
6
93
  declare class CaptureMetrics {
7
94
  enabled: boolean;
8
95
  metrics: Record<string, number>;
@@ -101,6 +188,11 @@ interface PostHogConfig {
101
188
  _onCapture: (eventName: string, eventData: CaptureResult) => void;
102
189
  _capture_metrics: boolean;
103
190
  _capture_performance: boolean;
191
+ bootstrap: {
192
+ distinctID?: string;
193
+ isIdentifiedID?: boolean;
194
+ featureFlags?: Record<string, boolean | string>;
195
+ };
104
196
  }
105
197
  interface OptInOutCapturingOptions {
106
198
  capture: (event: string, properties: Properties, options: CaptureOptions) => void;
@@ -331,11 +423,348 @@ declare class PostHogFeatureFlags {
331
423
  send_event?: boolean;
332
424
  }): boolean;
333
425
  addFeatureFlagsHandler(handler: FeatureFlagsCallback): void;
334
- receivedFeatureFlags(response: DecideResponse): void;
426
+ receivedFeatureFlags(response: Partial<DecideResponse>): void;
335
427
  override(flags: boolean | string[] | Record<string, string | boolean>): void;
336
428
  onFeatureFlags(callback: FeatureFlagsCallback): void;
337
429
  }
338
430
 
431
+ declare type PackFn = (event: eventWithTime) => string;
432
+
433
+ declare enum EventType {
434
+ DomContentLoaded = 0,
435
+ Load = 1,
436
+ FullSnapshot = 2,
437
+ IncrementalSnapshot = 3,
438
+ Meta = 4,
439
+ Custom = 5,
440
+ Plugin = 6
441
+ }
442
+ declare type domContentLoadedEvent = {
443
+ type: EventType.DomContentLoaded;
444
+ data: {};
445
+ };
446
+ declare type loadedEvent = {
447
+ type: EventType.Load;
448
+ data: {};
449
+ };
450
+ declare type fullSnapshotEvent = {
451
+ type: EventType.FullSnapshot;
452
+ data: {
453
+ node: serializedNodeWithId;
454
+ initialOffset: {
455
+ top: number;
456
+ left: number;
457
+ };
458
+ };
459
+ };
460
+ declare type incrementalSnapshotEvent = {
461
+ type: EventType.IncrementalSnapshot;
462
+ data: incrementalData;
463
+ };
464
+ declare type metaEvent = {
465
+ type: EventType.Meta;
466
+ data: {
467
+ href: string;
468
+ width: number;
469
+ height: number;
470
+ };
471
+ };
472
+ declare type customEvent<T = unknown> = {
473
+ type: EventType.Custom;
474
+ data: {
475
+ tag: string;
476
+ payload: T;
477
+ };
478
+ };
479
+ declare type pluginEvent<T = unknown> = {
480
+ type: EventType.Plugin;
481
+ data: {
482
+ plugin: string;
483
+ payload: T;
484
+ };
485
+ };
486
+ declare enum IncrementalSource {
487
+ Mutation = 0,
488
+ MouseMove = 1,
489
+ MouseInteraction = 2,
490
+ Scroll = 3,
491
+ ViewportResize = 4,
492
+ Input = 5,
493
+ TouchMove = 6,
494
+ MediaInteraction = 7,
495
+ StyleSheetRule = 8,
496
+ CanvasMutation = 9,
497
+ Font = 10,
498
+ Log = 11,
499
+ Drag = 12,
500
+ StyleDeclaration = 13
501
+ }
502
+ declare type mutationData = {
503
+ source: IncrementalSource.Mutation;
504
+ } & mutationCallbackParam;
505
+ declare type mousemoveData = {
506
+ source: IncrementalSource.MouseMove | IncrementalSource.TouchMove | IncrementalSource.Drag;
507
+ positions: mousePosition[];
508
+ };
509
+ declare type mouseInteractionData = {
510
+ source: IncrementalSource.MouseInteraction;
511
+ } & mouseInteractionParam;
512
+ declare type scrollData = {
513
+ source: IncrementalSource.Scroll;
514
+ } & scrollPosition;
515
+ declare type viewportResizeData = {
516
+ source: IncrementalSource.ViewportResize;
517
+ } & viewportResizeDimension;
518
+ declare type inputData = {
519
+ source: IncrementalSource.Input;
520
+ id: number;
521
+ } & inputValue;
522
+ declare type mediaInteractionData = {
523
+ source: IncrementalSource.MediaInteraction;
524
+ } & mediaInteractionParam;
525
+ declare type styleSheetRuleData = {
526
+ source: IncrementalSource.StyleSheetRule;
527
+ } & styleSheetRuleParam;
528
+ declare type styleDeclarationData = {
529
+ source: IncrementalSource.StyleDeclaration;
530
+ } & styleDeclarationParam;
531
+ declare type canvasMutationData = {
532
+ source: IncrementalSource.CanvasMutation;
533
+ } & canvasMutationParam;
534
+ declare type fontData = {
535
+ source: IncrementalSource.Font;
536
+ } & fontParam;
537
+ declare type incrementalData = mutationData | mousemoveData | mouseInteractionData | scrollData | viewportResizeData | inputData | mediaInteractionData | styleSheetRuleData | canvasMutationData | fontData | styleDeclarationData;
538
+ declare type event = domContentLoadedEvent | loadedEvent | fullSnapshotEvent | incrementalSnapshotEvent | metaEvent | customEvent | pluginEvent;
539
+ declare type eventWithTime = event & {
540
+ timestamp: number;
541
+ delay?: number;
542
+ };
543
+ declare type blockClass = string | RegExp;
544
+ declare type maskTextClass = string | RegExp;
545
+ declare type SamplingStrategy = Partial<{
546
+ mousemove: boolean | number;
547
+ mousemoveCallback: number;
548
+ mouseInteraction: boolean | Record<string, boolean | undefined>;
549
+ scroll: number;
550
+ media: number;
551
+ input: 'all' | 'last';
552
+ }>;
553
+ declare type RecordPlugin<TOptions = unknown> = {
554
+ name: string;
555
+ observer?: (cb: Function, win: IWindow, options: TOptions) => listenerHandler;
556
+ eventProcessor?: <TExtend>(event: eventWithTime) => eventWithTime & TExtend;
557
+ options: TOptions;
558
+ };
559
+ declare type recordOptions<T> = {
560
+ emit?: (e: T, isCheckout?: boolean) => void;
561
+ checkoutEveryNth?: number;
562
+ checkoutEveryNms?: number;
563
+ blockClass?: blockClass;
564
+ blockSelector?: string;
565
+ ignoreClass?: string;
566
+ maskTextClass?: maskTextClass;
567
+ maskTextSelector?: string;
568
+ maskAllInputs?: boolean;
569
+ maskInputOptions?: MaskInputOptions;
570
+ maskInputFn?: MaskInputFn;
571
+ maskTextFn?: MaskTextFn;
572
+ slimDOMOptions?: SlimDOMOptions | 'all' | true;
573
+ inlineStylesheet?: boolean;
574
+ hooks?: hooksParam;
575
+ packFn?: PackFn;
576
+ sampling?: SamplingStrategy;
577
+ recordCanvas?: boolean;
578
+ userTriggeredOnInput?: boolean;
579
+ collectFonts?: boolean;
580
+ inlineImages?: boolean;
581
+ plugins?: RecordPlugin[];
582
+ mousemoveWait?: number;
583
+ keepIframeSrcFn?: KeepIframeSrcFn;
584
+ };
585
+ declare type hooksParam = {
586
+ mutation?: mutationCallBack;
587
+ mousemove?: mousemoveCallBack;
588
+ mouseInteraction?: mouseInteractionCallBack;
589
+ scroll?: scrollCallback;
590
+ viewportResize?: viewportResizeCallback;
591
+ input?: inputCallback;
592
+ mediaInteaction?: mediaInteractionCallback;
593
+ styleSheetRule?: styleSheetRuleCallback;
594
+ styleDeclaration?: styleDeclarationCallback;
595
+ canvasMutation?: canvasMutationCallback;
596
+ font?: fontCallback;
597
+ };
598
+ declare type textMutation = {
599
+ id: number;
600
+ value: string | null;
601
+ };
602
+ declare type styleAttributeValue = {
603
+ [key: string]: styleValueWithPriority | string | false;
604
+ };
605
+ declare type styleValueWithPriority = [string, string];
606
+ declare type attributeMutation = {
607
+ id: number;
608
+ attributes: {
609
+ [key: string]: string | styleAttributeValue | null;
610
+ };
611
+ };
612
+ declare type removedNodeMutation = {
613
+ parentId: number;
614
+ id: number;
615
+ isShadow?: boolean;
616
+ };
617
+ declare type addedNodeMutation = {
618
+ parentId: number;
619
+ previousId?: number | null;
620
+ nextId: number | null;
621
+ node: serializedNodeWithId;
622
+ };
623
+ declare type mutationCallbackParam = {
624
+ texts: textMutation[];
625
+ attributes: attributeMutation[];
626
+ removes: removedNodeMutation[];
627
+ adds: addedNodeMutation[];
628
+ isAttachIframe?: true;
629
+ };
630
+ declare type mutationCallBack = (m: mutationCallbackParam) => void;
631
+ declare type mousemoveCallBack = (p: mousePosition[], source: IncrementalSource.MouseMove | IncrementalSource.TouchMove | IncrementalSource.Drag) => void;
632
+ declare type mousePosition = {
633
+ x: number;
634
+ y: number;
635
+ id: number;
636
+ timeOffset: number;
637
+ };
638
+ declare enum MouseInteractions {
639
+ MouseUp = 0,
640
+ MouseDown = 1,
641
+ Click = 2,
642
+ ContextMenu = 3,
643
+ DblClick = 4,
644
+ Focus = 5,
645
+ Blur = 6,
646
+ TouchStart = 7,
647
+ TouchMove_Departed = 8,
648
+ TouchEnd = 9,
649
+ TouchCancel = 10
650
+ }
651
+ declare enum CanvasContext {
652
+ '2D' = 0,
653
+ WebGL = 1,
654
+ WebGL2 = 2
655
+ }
656
+ declare type mouseInteractionParam = {
657
+ type: MouseInteractions;
658
+ id: number;
659
+ x: number;
660
+ y: number;
661
+ };
662
+ declare type mouseInteractionCallBack = (d: mouseInteractionParam) => void;
663
+ declare type scrollPosition = {
664
+ id: number;
665
+ x: number;
666
+ y: number;
667
+ };
668
+ declare type scrollCallback = (p: scrollPosition) => void;
669
+ declare type styleSheetAddRule = {
670
+ rule: string;
671
+ index?: number | number[];
672
+ };
673
+ declare type styleSheetDeleteRule = {
674
+ index: number | number[];
675
+ };
676
+ declare type styleSheetRuleParam = {
677
+ id: number;
678
+ removes?: styleSheetDeleteRule[];
679
+ adds?: styleSheetAddRule[];
680
+ };
681
+ declare type styleSheetRuleCallback = (s: styleSheetRuleParam) => void;
682
+ declare type styleDeclarationParam = {
683
+ id: number;
684
+ index: number[];
685
+ set?: {
686
+ property: string;
687
+ value: string | null;
688
+ priority: string | undefined;
689
+ };
690
+ remove?: {
691
+ property: string;
692
+ };
693
+ };
694
+ declare type styleDeclarationCallback = (s: styleDeclarationParam) => void;
695
+ declare type canvasMutationCommand = {
696
+ property: string;
697
+ args: Array<unknown>;
698
+ setter?: true;
699
+ };
700
+ declare type canvasMutationParam = {
701
+ id: number;
702
+ type: CanvasContext;
703
+ commands: canvasMutationCommand[];
704
+ } | ({
705
+ id: number;
706
+ type: CanvasContext;
707
+ } & canvasMutationCommand);
708
+ declare type canvasMutationCallback = (p: canvasMutationParam) => void;
709
+ declare type fontParam = {
710
+ family: string;
711
+ fontSource: string;
712
+ buffer: boolean;
713
+ descriptors?: FontFaceDescriptors;
714
+ };
715
+ declare type fontCallback = (p: fontParam) => void;
716
+ declare type viewportResizeDimension = {
717
+ width: number;
718
+ height: number;
719
+ };
720
+ declare type viewportResizeCallback = (d: viewportResizeDimension) => void;
721
+ declare type inputValue = {
722
+ text: string;
723
+ isChecked: boolean;
724
+ userTriggered?: boolean;
725
+ };
726
+ declare type inputCallback = (v: inputValue & {
727
+ id: number;
728
+ }) => void;
729
+ declare const enum MediaInteractions {
730
+ Play = 0,
731
+ Pause = 1,
732
+ Seeked = 2,
733
+ VolumeChange = 3
734
+ }
735
+ declare type mediaInteractionParam = {
736
+ type: MediaInteractions;
737
+ id: number;
738
+ currentTime?: number;
739
+ volume?: number;
740
+ muted?: boolean;
741
+ };
742
+ declare type mediaInteractionCallback = (p: mediaInteractionParam) => void;
743
+ declare type Mirror = {
744
+ map: idNodeMap;
745
+ getId: (n: INode) => number;
746
+ getNode: (id: number) => INode | null;
747
+ removeNodeFromMap: (n: INode) => void;
748
+ has: (id: number) => boolean;
749
+ reset: () => void;
750
+ };
751
+ declare type listenerHandler = () => void;
752
+ declare type KeepIframeSrcFn = (src: string) => boolean;
753
+ declare global {
754
+ interface Window {
755
+ FontFace: typeof FontFace;
756
+ }
757
+ }
758
+ declare type IWindow = Window & typeof globalThis;
759
+
760
+ declare function record<T = eventWithTime>(options?: recordOptions<T>): listenerHandler | undefined;
761
+ declare namespace record {
762
+ var addCustomEvent: <T>(tag: string, payload: T) => void;
763
+ var freezePage: () => void;
764
+ var takeFullSnapshot: (isCheckout?: boolean | undefined) => void;
765
+ var mirror: Mirror;
766
+ }
767
+
339
768
  declare class SessionRecording {
340
769
  instance: PostHog;
341
770
  captureStarted: boolean;
@@ -501,6 +930,7 @@ declare class PostHog {
501
930
  * @param {Array} array
502
931
  */
503
932
  _execute_array(array: SnippetArrayItem[]): void;
933
+ _hasBootstrappedFeatureFlags(): boolean;
504
934
  /**
505
935
  * push() keeps the standard async-array-push
506
936
  * behavior around after the lib is loaded.
package/dist/module.js CHANGED
@@ -885,7 +885,7 @@ var LZString = {
885
885
  }
886
886
  };
887
887
 
888
- var version = "1.29.1";
888
+ var version = "1.30.0";
889
889
 
890
890
  // e.g. Config.DEBUG = Config.DEBUG || instance.get_config('debug')
891
891
 
@@ -3294,6 +3294,7 @@ var PostHogFeatureFlags = /*#__PURE__*/function () {
3294
3294
  }, {
3295
3295
  key: "receivedFeatureFlags",
3296
3296
  value: function receivedFeatureFlags(response) {
3297
+ this.instance.decideEndpointWasHit = true;
3297
3298
  parseFeatureFlagDecideResponse(response, this.instance.persistence);
3298
3299
  var flags = this.getFlags();
3299
3300
  var variants = this.getFlagVariants();
@@ -3971,8 +3972,9 @@ var Decide = /*#__PURE__*/function () {
3971
3972
  function Decide(instance) {
3972
3973
  _classCallCheck(this, Decide);
3973
3974
 
3974
- this.instance = instance;
3975
- this.instance.decideEndpointWasHit = false;
3975
+ this.instance = instance; // don't need to wait for `decide` to return if flags were provided on initialisation
3976
+
3977
+ this.instance.decideEndpointWasHit = this.instance._hasBootstrappedFeatureFlags();
3976
3978
  }
3977
3979
 
3978
3980
  _createClass(Decide, [{
@@ -4345,19 +4347,27 @@ var RequestQueue = /*#__PURE__*/function (_RequestQueueScaffold) {
4345
4347
  }, {
4346
4348
  key: "unload",
4347
4349
  value: function unload() {
4350
+ var _this3 = this;
4351
+
4348
4352
  clearTimeout(this._poller);
4349
4353
  var requests = this._event_queue.length > 0 ? this.formatQueue() : {};
4350
4354
  this._event_queue.length = 0;
4351
-
4352
- for (var key in requests) {
4353
- var _requests$key3 = requests[key],
4354
- _url2 = _requests$key3.url,
4355
- _data2 = _requests$key3.data,
4356
- _options = _requests$key3.options;
4357
- this.handlePollRequest(_url2, _data2, _objectSpread2(_objectSpread2({}, _options), {}, {
4355
+ var requestValues = Object.values(requests); // Always force events to be sent before recordings, as events are more important, and recordings are bigger and thus less likely to arrive
4356
+
4357
+ var sortedRequests = [].concat(_toConsumableArray(requestValues.filter(function (r) {
4358
+ return r.url.indexOf('/e') === 0;
4359
+ })), _toConsumableArray(requestValues.filter(function (r) {
4360
+ return r.url.indexOf('/e') !== 0;
4361
+ })));
4362
+ sortedRequests.map(function (_ref) {
4363
+ var url = _ref.url,
4364
+ data = _ref.data,
4365
+ options = _ref.options;
4366
+
4367
+ _this3.handlePollRequest(url, data, _objectSpread2(_objectSpread2({}, options), {}, {
4358
4368
  transport: 'sendBeacon'
4359
4369
  }));
4360
- }
4370
+ });
4361
4371
  }
4362
4372
  }, {
4363
4373
  key: "formatQueue",
@@ -5950,7 +5960,8 @@ var defaultConfig = function defaultConfig() {
5950
5960
  _capture_metrics: false,
5951
5961
  _capture_performance: false,
5952
5962
  name: 'posthog',
5953
- callback_fn: 'posthog._jsc'
5963
+ callback_fn: 'posthog._jsc',
5964
+ bootstrap: {}
5954
5965
  };
5955
5966
  };
5956
5967
  /**
@@ -6099,6 +6110,8 @@ var PostHog = /*#__PURE__*/function () {
6099
6110
  }, {
6100
6111
  key: "_init",
6101
6112
  value: function _init(token) {
6113
+ var _config$bootstrap;
6114
+
6102
6115
  var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6103
6116
  var name = arguments.length > 2 ? arguments[2] : undefined;
6104
6117
  this.__loaded = true;
@@ -6123,19 +6136,49 @@ var PostHog = /*#__PURE__*/function () {
6123
6136
 
6124
6137
  this._gdpr_init();
6125
6138
 
6139
+ if (((_config$bootstrap = config.bootstrap) === null || _config$bootstrap === void 0 ? void 0 : _config$bootstrap.distinctID) !== undefined) {
6140
+ var _config$bootstrap2;
6141
+
6142
+ var uuid = this.get_config('get_device_id')(_UUID());
6143
+ var deviceID = (_config$bootstrap2 = config.bootstrap) !== null && _config$bootstrap2 !== void 0 && _config$bootstrap2.isIdentifiedID ? uuid : config.bootstrap.distinctID;
6144
+ this.register({
6145
+ distinct_id: config.bootstrap.distinctID,
6146
+ $device_id: deviceID
6147
+ });
6148
+ }
6149
+
6150
+ if (this._hasBootstrappedFeatureFlags()) {
6151
+ var _config$bootstrap3;
6152
+
6153
+ var activeFlags = Object.keys(((_config$bootstrap3 = config.bootstrap) === null || _config$bootstrap3 === void 0 ? void 0 : _config$bootstrap3.featureFlags) || {}).filter(function (flag) {
6154
+ var _config$bootstrap4, _config$bootstrap4$fe;
6155
+
6156
+ return !!((_config$bootstrap4 = config.bootstrap) !== null && _config$bootstrap4 !== void 0 && (_config$bootstrap4$fe = _config$bootstrap4.featureFlags) !== null && _config$bootstrap4$fe !== void 0 && _config$bootstrap4$fe[flag]);
6157
+ }).reduce(function (res, key) {
6158
+ var _config$bootstrap5, _config$bootstrap5$fe;
6159
+
6160
+ return res[key] = ((_config$bootstrap5 = config.bootstrap) === null || _config$bootstrap5 === void 0 ? void 0 : (_config$bootstrap5$fe = _config$bootstrap5.featureFlags) === null || _config$bootstrap5$fe === void 0 ? void 0 : _config$bootstrap5$fe[key]) || false, res;
6161
+ }, {});
6162
+ this.featureFlags.receivedFeatureFlags({
6163
+ featureFlags: activeFlags
6164
+ });
6165
+ }
6166
+
6126
6167
  if (!this.get_distinct_id()) {
6127
6168
  // There is no need to set the distinct id
6128
6169
  // or the device id if something was already stored
6129
6170
  // in the persitence
6130
- var uuid = this.get_config('get_device_id')(_UUID());
6171
+ var _uuid = this.get_config('get_device_id')(_UUID());
6172
+
6131
6173
  this.register_once({
6132
- distinct_id: uuid,
6133
- $device_id: uuid
6174
+ distinct_id: _uuid,
6175
+ $device_id: _uuid
6134
6176
  }, '');
6135
- } // Set up the window close event handler "unload"
6177
+ } // Set up event handler for pageleave
6178
+ // Use `onpagehide` if available, see https://calendar.perfplanet.com/2020/beaconing-in-practice/#beaconing-reliability-avoiding-abandons
6136
6179
 
6137
6180
 
6138
- win.addEventListener && win.addEventListener('unload', this._handle_unload.bind(this));
6181
+ win.addEventListener && win.addEventListener('onpagehide' in self ? 'pagehide' : 'unload', this._handle_unload.bind(this));
6139
6182
  } // Private methods
6140
6183
 
6141
6184
  }, {
@@ -6410,6 +6453,13 @@ var PostHog = /*#__PURE__*/function () {
6410
6453
  execute(other_calls, this);
6411
6454
  execute(capturing_calls, this);
6412
6455
  }
6456
+ }, {
6457
+ key: "_hasBootstrappedFeatureFlags",
6458
+ value: function _hasBootstrappedFeatureFlags() {
6459
+ var _this$config$bootstra, _this$config$bootstra2;
6460
+
6461
+ return ((_this$config$bootstra = this.config.bootstrap) === null || _this$config$bootstra === void 0 ? void 0 : _this$config$bootstra.featureFlags) && Object.keys((_this$config$bootstra2 = this.config.bootstrap) === null || _this$config$bootstra2 === void 0 ? void 0 : _this$config$bootstra2.featureFlags).length > 0 || false;
6462
+ }
6413
6463
  /**
6414
6464
  * push() keeps the standard async-array-push
6415
6465
  * behavior around after the lib is loaded.