@outlit/browser 1.4.1 → 1.4.5

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.
@@ -1,122 +1,9 @@
1
+ import { BrowserTrackOptions, BrowserIdentifyOptions } from '@outlit/core';
2
+ export { BrowserIdentifyOptions, BrowserTrackOptions, CustomerIdentifier, ExplicitJourneyStage, TrackerConfig } from '@outlit/core';
3
+ import { U as UserIdentity, B as BillingOptions, O as Outlit, h as OutlitOptions } from '../tracker-DlHUyaah.mjs';
1
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
5
  import * as react from 'react';
3
6
  import { ReactNode } from 'react';
4
- import { U as UserIdentity, h as OutlitOptions, O as Outlit, B as BillingOptions } from '../tracker-OMgVDwlV.mjs';
5
- import { BrowserTrackOptions, BrowserIdentifyOptions } from '@outlit/core';
6
- export { BrowserIdentifyOptions, BrowserTrackOptions, CustomerIdentifier, ExplicitJourneyStage, TrackerConfig } from '@outlit/core';
7
-
8
- interface OutlitContextValue {
9
- outlit: Outlit | null;
10
- isInitialized: boolean;
11
- isTrackingEnabled: boolean;
12
- enableTracking: () => void;
13
- disableTracking: () => void;
14
- }
15
- declare const OutlitContext: react.Context<OutlitContextValue>;
16
- interface OutlitProviderBaseProps {
17
- children: ReactNode;
18
- /**
19
- * Current user identity.
20
- * When provided with email or userId, calls setUser() to identify the user.
21
- * When null, undefined, or missing identity fields, calls clearUser().
22
- *
23
- * This is the recommended way to handle user identity in server-rendered apps:
24
- * pass the user from your auth system as a prop.
25
- *
26
- * @example
27
- * ```tsx
28
- * // Server component (layout.tsx)
29
- * const session = await auth()
30
- * return (
31
- * <OutlitProvider
32
- * publicKey="pk_xxx"
33
- * user={session?.user ? { email: session.user.email, userId: session.user.id } : null}
34
- * >
35
- * {children}
36
- * </OutlitProvider>
37
- * )
38
- * ```
39
- */
40
- user?: UserIdentity | null;
41
- }
42
- /**
43
- * Props for using a pre-existing Outlit instance.
44
- * The provider will use this instance directly without creating a new one.
45
- * The caller owns the instance lifecycle — shutdown() will NOT be called on unmount.
46
- *
47
- * @example
48
- * ```tsx
49
- * import { Outlit } from '@outlit/browser'
50
- * import { OutlitProvider } from '@outlit/browser/react'
51
- *
52
- * const outlit = new Outlit({ publicKey: 'pk_xxx', trackPageviews: false })
53
- *
54
- * function App() {
55
- * const user = useAuth()
56
- * return (
57
- * <OutlitProvider client={outlit} user={user ? { email: user.email } : null}>
58
- * {children}
59
- * </OutlitProvider>
60
- * )
61
- * }
62
- * ```
63
- */
64
- type NeverOutlitOptions = {
65
- [K in keyof OutlitOptions]?: never;
66
- };
67
- interface OutlitProviderClientProps extends OutlitProviderBaseProps, NeverOutlitOptions {
68
- /** An existing Outlit instance to use. Config props are ignored when this is provided. */
69
- client: Outlit;
70
- }
71
- /**
72
- * Props for creating a new Outlit instance internally.
73
- * This is the default behavior — the provider creates and owns the instance.
74
- */
75
- interface OutlitProviderConfigProps extends OutlitProviderBaseProps, Omit<OutlitOptions, "trackPageviews"> {
76
- client?: never;
77
- /**
78
- * Whether to automatically track pageviews.
79
- * When true (default), tracks pageviews on route changes.
80
- */
81
- trackPageviews?: boolean;
82
- /**
83
- * Whether to start tracking automatically on mount.
84
- * Set to false if you need to wait for user consent.
85
- * Call enableTracking() (from useOutlit hook) after consent is obtained.
86
- * @default true
87
- */
88
- autoTrack?: boolean;
89
- }
90
- type OutlitProviderProps = OutlitProviderClientProps | OutlitProviderConfigProps;
91
- /**
92
- * Outlit Provider component.
93
- * Initializes the client and provides it to child components via context.
94
- *
95
- * Can be used in two ways:
96
- *
97
- * 1. **Config mode** (default): Pass `publicKey` and config options to create a new instance.
98
- * 2. **Client mode**: Pass an existing `client` instance for shared imperative + React usage.
99
- *
100
- * @example
101
- * ```tsx
102
- * // Config mode — provider creates and owns the instance
103
- * <OutlitProvider publicKey="pk_xxx" trackPageviews>
104
- * {children}
105
- * </OutlitProvider>
106
- * ```
107
- *
108
- * @example
109
- * ```tsx
110
- * // Client mode — use an existing instance
111
- * const outlit = new Outlit({ publicKey: 'pk_xxx' })
112
- * outlit.track('pageview') // imperative usage
113
- *
114
- * <OutlitProvider client={outlit} user={user}>
115
- * {children}
116
- * </OutlitProvider>
117
- * ```
118
- */
119
- declare function OutlitProvider(props: OutlitProviderProps): react_jsx_runtime.JSX.Element;
120
7
 
121
8
  interface UseOutlitReturn {
122
9
  /**
@@ -247,4 +134,117 @@ declare function useTrack(): (eventName: string, properties?: BrowserTrackOption
247
134
  */
248
135
  declare function useIdentify(): (options: BrowserIdentifyOptions) => void;
249
136
 
137
+ interface OutlitContextValue {
138
+ outlit: Outlit | null;
139
+ isInitialized: boolean;
140
+ isTrackingEnabled: boolean;
141
+ enableTracking: () => void;
142
+ disableTracking: () => void;
143
+ }
144
+ declare const OutlitContext: react.Context<OutlitContextValue>;
145
+ interface OutlitProviderBaseProps {
146
+ children: ReactNode;
147
+ /**
148
+ * Current user identity.
149
+ * When provided with email or userId, calls setUser() to identify the user.
150
+ * When null, undefined, or missing identity fields, calls clearUser().
151
+ *
152
+ * This is the recommended way to handle user identity in server-rendered apps:
153
+ * pass the user from your auth system as a prop.
154
+ *
155
+ * @example
156
+ * ```tsx
157
+ * // Server component (layout.tsx)
158
+ * const session = await auth()
159
+ * return (
160
+ * <OutlitProvider
161
+ * publicKey="pk_xxx"
162
+ * user={session?.user ? { email: session.user.email, userId: session.user.id } : null}
163
+ * >
164
+ * {children}
165
+ * </OutlitProvider>
166
+ * )
167
+ * ```
168
+ */
169
+ user?: UserIdentity | null;
170
+ }
171
+ /**
172
+ * Props for using a pre-existing Outlit instance.
173
+ * The provider will use this instance directly without creating a new one.
174
+ * The caller owns the instance lifecycle — shutdown() will NOT be called on unmount.
175
+ *
176
+ * @example
177
+ * ```tsx
178
+ * import { Outlit } from '@outlit/browser'
179
+ * import { OutlitProvider } from '@outlit/browser/react'
180
+ *
181
+ * const outlit = new Outlit({ publicKey: 'pk_xxx', trackPageviews: false })
182
+ *
183
+ * function App() {
184
+ * const user = useAuth()
185
+ * return (
186
+ * <OutlitProvider client={outlit} user={user ? { email: user.email } : null}>
187
+ * {children}
188
+ * </OutlitProvider>
189
+ * )
190
+ * }
191
+ * ```
192
+ */
193
+ type NeverOutlitOptions = {
194
+ [K in keyof OutlitOptions]?: never;
195
+ };
196
+ interface OutlitProviderClientProps extends OutlitProviderBaseProps, NeverOutlitOptions {
197
+ /** An existing Outlit instance to use. Config props are ignored when this is provided. */
198
+ client: Outlit;
199
+ }
200
+ /**
201
+ * Props for creating a new Outlit instance internally.
202
+ * This is the default behavior — the provider creates and owns the instance.
203
+ */
204
+ interface OutlitProviderConfigProps extends OutlitProviderBaseProps, Omit<OutlitOptions, "trackPageviews"> {
205
+ client?: never;
206
+ /**
207
+ * Whether to automatically track pageviews.
208
+ * When true (default), tracks pageviews on route changes.
209
+ */
210
+ trackPageviews?: boolean;
211
+ /**
212
+ * Whether to start tracking automatically on mount.
213
+ * Set to false if you need to wait for user consent.
214
+ * Call enableTracking() (from useOutlit hook) after consent is obtained.
215
+ * @default true
216
+ */
217
+ autoTrack?: boolean;
218
+ }
219
+ type OutlitProviderProps = OutlitProviderClientProps | OutlitProviderConfigProps;
220
+ /**
221
+ * Outlit Provider component.
222
+ * Initializes the client and provides it to child components via context.
223
+ *
224
+ * Can be used in two ways:
225
+ *
226
+ * 1. **Config mode** (default): Pass `publicKey` and config options to create a new instance.
227
+ * 2. **Client mode**: Pass an existing `client` instance for shared imperative + React usage.
228
+ *
229
+ * @example
230
+ * ```tsx
231
+ * // Config mode — provider creates and owns the instance
232
+ * <OutlitProvider publicKey="pk_xxx" trackPageviews>
233
+ * {children}
234
+ * </OutlitProvider>
235
+ * ```
236
+ *
237
+ * @example
238
+ * ```tsx
239
+ * // Client mode — use an existing instance
240
+ * const outlit = new Outlit({ publicKey: 'pk_xxx' })
241
+ * outlit.track('pageview') // imperative usage
242
+ *
243
+ * <OutlitProvider client={outlit} user={user}>
244
+ * {children}
245
+ * </OutlitProvider>
246
+ * ```
247
+ */
248
+ declare function OutlitProvider(props: OutlitProviderProps): react_jsx_runtime.JSX.Element;
249
+
250
250
  export { BillingOptions, OutlitContext, type OutlitContextValue, OutlitProvider, type OutlitProviderProps, type UseOutlitReturn, UserIdentity, useIdentify, useOutlit, useTrack };
@@ -1,122 +1,9 @@
1
+ import { BrowserTrackOptions, BrowserIdentifyOptions } from '@outlit/core';
2
+ export { BrowserIdentifyOptions, BrowserTrackOptions, CustomerIdentifier, ExplicitJourneyStage, TrackerConfig } from '@outlit/core';
3
+ import { U as UserIdentity, B as BillingOptions, O as Outlit, h as OutlitOptions } from '../tracker-DlHUyaah.js';
1
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
5
  import * as react from 'react';
3
6
  import { ReactNode } from 'react';
4
- import { U as UserIdentity, h as OutlitOptions, O as Outlit, B as BillingOptions } from '../tracker-OMgVDwlV.js';
5
- import { BrowserTrackOptions, BrowserIdentifyOptions } from '@outlit/core';
6
- export { BrowserIdentifyOptions, BrowserTrackOptions, CustomerIdentifier, ExplicitJourneyStage, TrackerConfig } from '@outlit/core';
7
-
8
- interface OutlitContextValue {
9
- outlit: Outlit | null;
10
- isInitialized: boolean;
11
- isTrackingEnabled: boolean;
12
- enableTracking: () => void;
13
- disableTracking: () => void;
14
- }
15
- declare const OutlitContext: react.Context<OutlitContextValue>;
16
- interface OutlitProviderBaseProps {
17
- children: ReactNode;
18
- /**
19
- * Current user identity.
20
- * When provided with email or userId, calls setUser() to identify the user.
21
- * When null, undefined, or missing identity fields, calls clearUser().
22
- *
23
- * This is the recommended way to handle user identity in server-rendered apps:
24
- * pass the user from your auth system as a prop.
25
- *
26
- * @example
27
- * ```tsx
28
- * // Server component (layout.tsx)
29
- * const session = await auth()
30
- * return (
31
- * <OutlitProvider
32
- * publicKey="pk_xxx"
33
- * user={session?.user ? { email: session.user.email, userId: session.user.id } : null}
34
- * >
35
- * {children}
36
- * </OutlitProvider>
37
- * )
38
- * ```
39
- */
40
- user?: UserIdentity | null;
41
- }
42
- /**
43
- * Props for using a pre-existing Outlit instance.
44
- * The provider will use this instance directly without creating a new one.
45
- * The caller owns the instance lifecycle — shutdown() will NOT be called on unmount.
46
- *
47
- * @example
48
- * ```tsx
49
- * import { Outlit } from '@outlit/browser'
50
- * import { OutlitProvider } from '@outlit/browser/react'
51
- *
52
- * const outlit = new Outlit({ publicKey: 'pk_xxx', trackPageviews: false })
53
- *
54
- * function App() {
55
- * const user = useAuth()
56
- * return (
57
- * <OutlitProvider client={outlit} user={user ? { email: user.email } : null}>
58
- * {children}
59
- * </OutlitProvider>
60
- * )
61
- * }
62
- * ```
63
- */
64
- type NeverOutlitOptions = {
65
- [K in keyof OutlitOptions]?: never;
66
- };
67
- interface OutlitProviderClientProps extends OutlitProviderBaseProps, NeverOutlitOptions {
68
- /** An existing Outlit instance to use. Config props are ignored when this is provided. */
69
- client: Outlit;
70
- }
71
- /**
72
- * Props for creating a new Outlit instance internally.
73
- * This is the default behavior — the provider creates and owns the instance.
74
- */
75
- interface OutlitProviderConfigProps extends OutlitProviderBaseProps, Omit<OutlitOptions, "trackPageviews"> {
76
- client?: never;
77
- /**
78
- * Whether to automatically track pageviews.
79
- * When true (default), tracks pageviews on route changes.
80
- */
81
- trackPageviews?: boolean;
82
- /**
83
- * Whether to start tracking automatically on mount.
84
- * Set to false if you need to wait for user consent.
85
- * Call enableTracking() (from useOutlit hook) after consent is obtained.
86
- * @default true
87
- */
88
- autoTrack?: boolean;
89
- }
90
- type OutlitProviderProps = OutlitProviderClientProps | OutlitProviderConfigProps;
91
- /**
92
- * Outlit Provider component.
93
- * Initializes the client and provides it to child components via context.
94
- *
95
- * Can be used in two ways:
96
- *
97
- * 1. **Config mode** (default): Pass `publicKey` and config options to create a new instance.
98
- * 2. **Client mode**: Pass an existing `client` instance for shared imperative + React usage.
99
- *
100
- * @example
101
- * ```tsx
102
- * // Config mode — provider creates and owns the instance
103
- * <OutlitProvider publicKey="pk_xxx" trackPageviews>
104
- * {children}
105
- * </OutlitProvider>
106
- * ```
107
- *
108
- * @example
109
- * ```tsx
110
- * // Client mode — use an existing instance
111
- * const outlit = new Outlit({ publicKey: 'pk_xxx' })
112
- * outlit.track('pageview') // imperative usage
113
- *
114
- * <OutlitProvider client={outlit} user={user}>
115
- * {children}
116
- * </OutlitProvider>
117
- * ```
118
- */
119
- declare function OutlitProvider(props: OutlitProviderProps): react_jsx_runtime.JSX.Element;
120
7
 
121
8
  interface UseOutlitReturn {
122
9
  /**
@@ -247,4 +134,117 @@ declare function useTrack(): (eventName: string, properties?: BrowserTrackOption
247
134
  */
248
135
  declare function useIdentify(): (options: BrowserIdentifyOptions) => void;
249
136
 
137
+ interface OutlitContextValue {
138
+ outlit: Outlit | null;
139
+ isInitialized: boolean;
140
+ isTrackingEnabled: boolean;
141
+ enableTracking: () => void;
142
+ disableTracking: () => void;
143
+ }
144
+ declare const OutlitContext: react.Context<OutlitContextValue>;
145
+ interface OutlitProviderBaseProps {
146
+ children: ReactNode;
147
+ /**
148
+ * Current user identity.
149
+ * When provided with email or userId, calls setUser() to identify the user.
150
+ * When null, undefined, or missing identity fields, calls clearUser().
151
+ *
152
+ * This is the recommended way to handle user identity in server-rendered apps:
153
+ * pass the user from your auth system as a prop.
154
+ *
155
+ * @example
156
+ * ```tsx
157
+ * // Server component (layout.tsx)
158
+ * const session = await auth()
159
+ * return (
160
+ * <OutlitProvider
161
+ * publicKey="pk_xxx"
162
+ * user={session?.user ? { email: session.user.email, userId: session.user.id } : null}
163
+ * >
164
+ * {children}
165
+ * </OutlitProvider>
166
+ * )
167
+ * ```
168
+ */
169
+ user?: UserIdentity | null;
170
+ }
171
+ /**
172
+ * Props for using a pre-existing Outlit instance.
173
+ * The provider will use this instance directly without creating a new one.
174
+ * The caller owns the instance lifecycle — shutdown() will NOT be called on unmount.
175
+ *
176
+ * @example
177
+ * ```tsx
178
+ * import { Outlit } from '@outlit/browser'
179
+ * import { OutlitProvider } from '@outlit/browser/react'
180
+ *
181
+ * const outlit = new Outlit({ publicKey: 'pk_xxx', trackPageviews: false })
182
+ *
183
+ * function App() {
184
+ * const user = useAuth()
185
+ * return (
186
+ * <OutlitProvider client={outlit} user={user ? { email: user.email } : null}>
187
+ * {children}
188
+ * </OutlitProvider>
189
+ * )
190
+ * }
191
+ * ```
192
+ */
193
+ type NeverOutlitOptions = {
194
+ [K in keyof OutlitOptions]?: never;
195
+ };
196
+ interface OutlitProviderClientProps extends OutlitProviderBaseProps, NeverOutlitOptions {
197
+ /** An existing Outlit instance to use. Config props are ignored when this is provided. */
198
+ client: Outlit;
199
+ }
200
+ /**
201
+ * Props for creating a new Outlit instance internally.
202
+ * This is the default behavior — the provider creates and owns the instance.
203
+ */
204
+ interface OutlitProviderConfigProps extends OutlitProviderBaseProps, Omit<OutlitOptions, "trackPageviews"> {
205
+ client?: never;
206
+ /**
207
+ * Whether to automatically track pageviews.
208
+ * When true (default), tracks pageviews on route changes.
209
+ */
210
+ trackPageviews?: boolean;
211
+ /**
212
+ * Whether to start tracking automatically on mount.
213
+ * Set to false if you need to wait for user consent.
214
+ * Call enableTracking() (from useOutlit hook) after consent is obtained.
215
+ * @default true
216
+ */
217
+ autoTrack?: boolean;
218
+ }
219
+ type OutlitProviderProps = OutlitProviderClientProps | OutlitProviderConfigProps;
220
+ /**
221
+ * Outlit Provider component.
222
+ * Initializes the client and provides it to child components via context.
223
+ *
224
+ * Can be used in two ways:
225
+ *
226
+ * 1. **Config mode** (default): Pass `publicKey` and config options to create a new instance.
227
+ * 2. **Client mode**: Pass an existing `client` instance for shared imperative + React usage.
228
+ *
229
+ * @example
230
+ * ```tsx
231
+ * // Config mode — provider creates and owns the instance
232
+ * <OutlitProvider publicKey="pk_xxx" trackPageviews>
233
+ * {children}
234
+ * </OutlitProvider>
235
+ * ```
236
+ *
237
+ * @example
238
+ * ```tsx
239
+ * // Client mode — use an existing instance
240
+ * const outlit = new Outlit({ publicKey: 'pk_xxx' })
241
+ * outlit.track('pageview') // imperative usage
242
+ *
243
+ * <OutlitProvider client={outlit} user={user}>
244
+ * {children}
245
+ * </OutlitProvider>
246
+ * ```
247
+ */
248
+ declare function OutlitProvider(props: OutlitProviderProps): react_jsx_runtime.JSX.Element;
249
+
250
250
  export { BillingOptions, OutlitContext, type OutlitContextValue, OutlitProvider, type OutlitProviderProps, type UseOutlitReturn, UserIdentity, useIdentify, useOutlit, useTrack };
@@ -28,6 +28,9 @@ __export(react_exports, {
28
28
  });
29
29
  module.exports = __toCommonJS(react_exports);
30
30
 
31
+ // src/react/hooks.ts
32
+ var import_react2 = require("react");
33
+
31
34
  // src/react/provider.tsx
32
35
  var import_react = require("react");
33
36
 
@@ -675,11 +678,23 @@ var Outlit = class {
675
678
  currentUser = null;
676
679
  pendingUser = null;
677
680
  pendingStageEvents = [];
681
+ exitCleanups = [];
678
682
  constructor(options) {
679
683
  this.publicKey = options.publicKey;
680
684
  this.apiHost = options.apiHost ?? import_core3.DEFAULT_API_HOST;
681
685
  this.flushInterval = options.flushInterval ?? 5e3;
682
686
  this.options = options;
687
+ const isDev = typeof window !== "undefined" && typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
688
+ if (isDev) {
689
+ const key = `__outlit_${options.publicKey}`;
690
+ if (window[key]) {
691
+ console.warn(
692
+ "[Outlit] Multiple instances created with the same key. If using HMR, this is expected. Otherwise, use init() for singleton behavior or call shutdown() on the previous instance."
693
+ );
694
+ }
695
+ ;
696
+ window[key] = true;
697
+ }
683
698
  if (typeof window !== "undefined") {
684
699
  const handleExit = () => {
685
700
  if (this.hasHandledExit) return;
@@ -687,15 +702,21 @@ var Outlit = class {
687
702
  this.sessionTracker?.emitEngagement();
688
703
  this.flush();
689
704
  };
690
- document.addEventListener("visibilitychange", () => {
705
+ const visibilityHandler = () => {
691
706
  if (document.visibilityState === "hidden") {
692
707
  handleExit();
693
708
  } else {
694
709
  this.hasHandledExit = false;
695
710
  }
696
- });
711
+ };
712
+ document.addEventListener("visibilitychange", visibilityHandler);
697
713
  window.addEventListener("pagehide", handleExit);
698
714
  window.addEventListener("beforeunload", handleExit);
715
+ this.exitCleanups = [
716
+ () => document.removeEventListener("visibilitychange", visibilityHandler),
717
+ () => window.removeEventListener("pagehide", handleExit),
718
+ () => window.removeEventListener("beforeunload", handleExit)
719
+ ];
699
720
  }
700
721
  this.isInitialized = true;
701
722
  const consent = getConsentState();
@@ -798,11 +819,19 @@ var Outlit = class {
798
819
  console.warn("[Outlit] Tracking not enabled. Call enableTracking() first.");
799
820
  return;
800
821
  }
822
+ if (!options.email && !options.userId) {
823
+ console.warn("[Outlit] identify requires email or userId");
824
+ return;
825
+ }
801
826
  if (options.email || options.userId) {
802
827
  const hadNoUser = !this.currentUser;
803
828
  this.currentUser = {
804
829
  email: options.email,
805
- userId: options.userId
830
+ userId: options.userId,
831
+ customerId: options.customerId,
832
+ customerDomain: options.customerDomain,
833
+ customerTraits: options.customerTraits,
834
+ traits: options.traits
806
835
  };
807
836
  if (hadNoUser) {
808
837
  this.flushPendingStageEvents();
@@ -813,6 +842,9 @@ var Outlit = class {
813
842
  referrer: document.referrer,
814
843
  email: options.email,
815
844
  userId: options.userId,
845
+ customerId: options.customerId,
846
+ customerDomain: options.customerDomain,
847
+ customerTraits: options.customerTraits,
816
848
  traits: options.traits
817
849
  });
818
850
  this.enqueue(event);
@@ -854,7 +886,14 @@ var Outlit = class {
854
886
  */
855
887
  applyUser(identity) {
856
888
  this.currentUser = identity;
857
- this.identify({ email: identity.email, userId: identity.userId, traits: identity.traits });
889
+ this.identify({
890
+ email: identity.email,
891
+ userId: identity.userId,
892
+ traits: identity.traits,
893
+ customerId: identity.customerId,
894
+ customerDomain: identity.customerDomain,
895
+ customerTraits: identity.customerTraits
896
+ });
858
897
  this.flushPendingStageEvents();
859
898
  }
860
899
  /**
@@ -922,11 +961,23 @@ var Outlit = class {
922
961
  console.warn("[Outlit] Tracking not enabled. Call enableTracking() first.");
923
962
  return;
924
963
  }
964
+ try {
965
+ (0, import_core3.validateCustomerIdentity)(
966
+ options.customerId,
967
+ options.customerDomain,
968
+ options.domain,
969
+ options.stripeCustomerId
970
+ );
971
+ } catch (error) {
972
+ console.warn("[Outlit]", error instanceof Error ? error.message : error);
973
+ return;
974
+ }
925
975
  const event = (0, import_core3.buildBillingEvent)({
926
976
  url: window.location.href,
927
977
  referrer: document.referrer,
928
978
  status,
929
979
  customerId: options.customerId,
980
+ customerDomain: options.customerDomain,
930
981
  stripeCustomerId: options.stripeCustomerId,
931
982
  domain: options.domain,
932
983
  properties: options.properties
@@ -961,6 +1012,13 @@ var Outlit = class {
961
1012
  stopCalendarTracking();
962
1013
  stopSessionTracking();
963
1014
  this.sessionTracker = null;
1015
+ for (const cleanup of this.exitCleanups) {
1016
+ cleanup();
1017
+ }
1018
+ this.exitCleanups = [];
1019
+ if (typeof window !== "undefined" && typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
1020
+ delete window[`__outlit_${this.publicKey}`];
1021
+ }
964
1022
  await this.flush();
965
1023
  }
966
1024
  // ============================================
@@ -1037,12 +1095,47 @@ var Outlit = class {
1037
1095
  this.flush();
1038
1096
  }, this.flushInterval);
1039
1097
  }
1098
+ getPayloadUserIdentity() {
1099
+ if (!this.currentUser) {
1100
+ return void 0;
1101
+ }
1102
+ const { email, userId } = this.currentUser;
1103
+ if (!email && !userId) {
1104
+ return void 0;
1105
+ }
1106
+ return {
1107
+ ...email && { email },
1108
+ ...userId && { userId }
1109
+ };
1110
+ }
1111
+ getPayloadCustomerIdentity() {
1112
+ if (!this.currentUser) {
1113
+ return void 0;
1114
+ }
1115
+ const { customerId, customerDomain } = this.currentUser;
1116
+ if (!customerId && !customerDomain) {
1117
+ return void 0;
1118
+ }
1119
+ return {
1120
+ ...customerId && { customerId },
1121
+ ...customerDomain && { customerDomain }
1122
+ };
1123
+ }
1040
1124
  async sendEvents(events) {
1041
1125
  if (events.length === 0) return;
1042
1126
  if (!this.visitorId) return;
1043
- const userIdentity = this.currentUser ?? void 0;
1127
+ const userIdentity = this.getPayloadUserIdentity();
1128
+ const customerIdentity = this.getPayloadCustomerIdentity();
1044
1129
  const sessionId = this.sessionTracker?.getSessionId();
1045
- const payload = (0, import_core3.buildIngestPayload)(this.visitorId, "client", events, userIdentity, sessionId);
1130
+ const payload = (0, import_core3.buildIngestPayload)(
1131
+ this.visitorId,
1132
+ "client",
1133
+ events,
1134
+ userIdentity,
1135
+ sessionId,
1136
+ void 0,
1137
+ customerIdentity
1138
+ );
1046
1139
  const url = `${this.apiHost}/api/i/v1/${this.publicKey}/events`;
1047
1140
  try {
1048
1141
  if (typeof navigator !== "undefined" && navigator.sendBeacon) {
@@ -1093,7 +1186,7 @@ function OutlitProvider(props) {
1093
1186
  (0, import_react.useEffect)(() => {
1094
1187
  if (initializedRef.current) return;
1095
1188
  if (props.client) {
1096
- if (process.env.NODE_ENV !== "production") {
1189
+ if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
1097
1190
  const configKeys = [
1098
1191
  "publicKey",
1099
1192
  "apiHost",
@@ -1191,7 +1284,6 @@ function OutlitProvider(props) {
1191
1284
  }
1192
1285
 
1193
1286
  // src/react/hooks.ts
1194
- var import_react2 = require("react");
1195
1287
  function useOutlit() {
1196
1288
  const { outlit, isInitialized, isTrackingEnabled, enableTracking, disableTracking } = (0, import_react2.useContext)(OutlitContext);
1197
1289
  const track = (0, import_react2.useCallback)(