@altertable/altertable-js 0.3.0 → 0.4.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.
@@ -1,4 +1,12 @@
1
1
  (() => {
2
+ // src/lib/safelyRunOnBrowser.ts
3
+ function safelyRunOnBrowser(callback, fallback = () => void 0) {
4
+ if (typeof window === "undefined") {
5
+ return fallback();
6
+ }
7
+ return callback({ window });
8
+ }
9
+
2
10
  // src/core.ts
3
11
  var DEFAULT_BASE_URL = "https://api.altertable.ai";
4
12
  var DEFAULT_ENVIRONMENT = "production";
@@ -23,8 +31,14 @@
23
31
  _userId;
24
32
  _referrer;
25
33
  constructor() {
26
- this._referrer = document.referrer || null;
27
- this._lastUrl = window.location.href;
34
+ this._referrer = safelyRunOnBrowser(
35
+ ({ window: window2 }) => window2.document.referrer || null,
36
+ () => null
37
+ );
38
+ this._lastUrl = safelyRunOnBrowser(
39
+ ({ window: window2 }) => window2.location.href,
40
+ () => ""
41
+ );
28
42
  this._sessionId = this._generateId("session");
29
43
  this._visitorId = this._generateId("visitor");
30
44
  this._userId = this._generateId("anonymous");
@@ -33,12 +47,16 @@
33
47
  this._apiKey = apiKey;
34
48
  this._config = config;
35
49
  if (config.autoCapture !== false) {
36
- this.page(this._lastUrl);
50
+ if (this._lastUrl) {
51
+ this.page(this._lastUrl);
52
+ }
37
53
  setInterval(() => {
38
54
  this._checkForChanges();
39
55
  }, AUTO_CAPTURE_INTERVAL);
40
- window.addEventListener("popstate", () => this._checkForChanges());
41
- window.addEventListener("hashchange", () => this._checkForChanges());
56
+ safelyRunOnBrowser(({ window: window2 }) => {
57
+ window2.addEventListener("popstate", () => this._checkForChanges());
58
+ window2.addEventListener("hashchange", () => this._checkForChanges());
59
+ });
42
60
  }
43
61
  }
44
62
  identify(userId) {
@@ -63,7 +81,7 @@
63
81
  environment: this._config.environment || DEFAULT_ENVIRONMENT,
64
82
  properties: {
65
83
  [PROPERTY_LIB]: "@altertable/altertable-js",
66
- [PROPERTY_LIB_VERSION]: "0.3.0",
84
+ [PROPERTY_LIB_VERSION]: "0.4.0",
67
85
  [PROPERTY_RELEASE]: this._config.release,
68
86
  // The above properties might be overridden by user-provided fields
69
87
  // and the React library
@@ -72,12 +90,14 @@
72
90
  });
73
91
  }
74
92
  _checkForChanges() {
75
- const currentUrl = window.location.href;
76
- if (currentUrl !== this._lastUrl) {
77
- this.page(currentUrl);
78
- this._referrer = this._lastUrl;
79
- this._lastUrl = currentUrl;
80
- }
93
+ safelyRunOnBrowser(({ window: window2 }) => {
94
+ const currentUrl = window2.location.href;
95
+ if (currentUrl !== this._lastUrl) {
96
+ this.page(currentUrl);
97
+ this._referrer = this._lastUrl;
98
+ this._lastUrl = currentUrl;
99
+ }
100
+ });
81
101
  }
82
102
  _request(path, body) {
83
103
  const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;
@@ -131,20 +151,25 @@
131
151
  return `${prefix}-${Math.random().toString(36).substring(2)}`;
132
152
  }
133
153
  _getViewport() {
134
- return `${window.innerWidth}x${window.innerHeight}`;
154
+ return safelyRunOnBrowser(
155
+ ({ window: window2 }) => `${window2.innerWidth}x${window2.innerHeight}`,
156
+ () => "0x0"
157
+ );
135
158
  }
136
159
  };
137
160
 
138
161
  // src/index.ts
139
162
  var altertable = new Altertable();
140
- var stub = window.Altertable;
141
- if (stub && Array.isArray(stub)) {
142
- for (const item of stub) {
143
- const method = item[0];
144
- const args = item.slice(1);
145
- altertable[method](...args);
163
+ safelyRunOnBrowser(({ window: window2 }) => {
164
+ const stub = window2.Altertable;
165
+ if (stub && Array.isArray(stub)) {
166
+ for (const item of stub) {
167
+ const method = item[0];
168
+ const args = item.slice(1);
169
+ altertable[method](...args);
170
+ }
146
171
  }
147
- }
148
- window.Altertable = altertable;
172
+ window2.Altertable = altertable;
173
+ });
149
174
  })();
150
175
  //# sourceMappingURL=index.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core.ts","../src/index.ts"],"sourcesContent":["export interface Config {\n /**\n * The base URL of the Altertable API.\n * @default https://api.altertable.ai\n */\n baseUrl?: string;\n /**\n * The environment of the application.\n * @default \"production\"\n */\n environment?: string;\n /**\n * Whether to automatically capture page views and events.\n * @default true\n */\n autoCapture?: boolean;\n /**\n * The release ID of the application.\n * This is helpful to identify the version of the application an event is coming from.\n */\n release?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.altertable.ai';\nconst DEFAULT_ENVIRONMENT = 'production';\n\nexport type EventProperties = Record<string, unknown>;\n\nexport const PAGEVIEW_EVENT = '$pageview';\n\nexport const SESSION_STORAGE_KEY = 'altertable-session-id';\nexport const LOCAL_STORAGE_KEY = 'altertable-visitor-id';\nexport const AUTO_CAPTURE_INTERVAL = 100;\n\nexport const PROPERTY_URL = '$url';\nexport const PROPERTY_SESSION_ID = '$session_id';\nexport const PROPERTY_VISITOR_ID = '$visitor_id';\nexport const PROPERTY_VIEWPORT = '$viewport';\nexport const PROPERTY_REFERER = '$referer';\nexport const PROPERTY_RELEASE = '$release';\nexport const PROPERTY_LIB = '$lib';\nexport const PROPERTY_LIB_VERSION = '$lib_version';\n\nexport class Altertable {\n private _lastUrl: string;\n private _apiKey: string;\n private _config: Config;\n private _sessionId: string;\n private _visitorId: string;\n private _userId: string;\n private _referrer: string | null;\n\n constructor() {\n this._referrer = document.referrer || null;\n this._lastUrl = window.location.href;\n this._sessionId = this._generateId('session');\n this._visitorId = this._generateId('visitor');\n this._userId = this._generateId('anonymous');\n }\n\n init(apiKey: string, config: Config = {}) {\n this._apiKey = apiKey;\n this._config = config;\n\n if (config.autoCapture !== false) {\n this.page(this._lastUrl);\n\n setInterval(() => {\n this._checkForChanges();\n }, AUTO_CAPTURE_INTERVAL);\n\n window.addEventListener('popstate', () => this._checkForChanges());\n window.addEventListener('hashchange', () => this._checkForChanges());\n }\n }\n\n identify(userId: string) {\n // FIXME: dummy implementation\n this._userId = userId;\n }\n\n page(url: string) {\n const parsedUrl = new URL(url);\n const urlWithoutSearch = `${parsedUrl.origin}${parsedUrl.pathname}`;\n this.track(PAGEVIEW_EVENT, {\n [PROPERTY_URL]: urlWithoutSearch,\n [PROPERTY_SESSION_ID]: this._getSessionId(),\n [PROPERTY_VISITOR_ID]: this._getVisitorId(),\n [PROPERTY_VIEWPORT]: this._getViewport(),\n [PROPERTY_REFERER]: this._referrer,\n ...Object.fromEntries(parsedUrl.searchParams),\n });\n }\n\n track(event: string, properties?: EventProperties) {\n this._request('/track', {\n event,\n user_id: this._userId,\n environment: this._config.environment || DEFAULT_ENVIRONMENT,\n properties: {\n [PROPERTY_LIB]: __LIB__,\n [PROPERTY_LIB_VERSION]: __LIB_VERSION__,\n [PROPERTY_RELEASE]: this._config.release,\n // The above properties might be overridden by user-provided fields\n // and the React library\n ...(properties || {}),\n },\n });\n }\n\n private _checkForChanges() {\n const currentUrl = window.location.href;\n if (currentUrl !== this._lastUrl) {\n this.page(currentUrl);\n this._referrer = this._lastUrl;\n this._lastUrl = currentUrl;\n }\n }\n\n private _request(path: string, body: unknown): void {\n const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;\n const payload = JSON.stringify(body);\n\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n const beaconUrl = `${url}?apiKey=${encodeURIComponent(this._apiKey)}`;\n const blob = new Blob([payload], { type: 'application/json' });\n navigator.sendBeacon(beaconUrl, blob);\n } else {\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this._apiKey}`,\n },\n body: payload,\n });\n }\n }\n\n private _getSessionId(): string {\n try {\n let id = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!id) {\n id = this._sessionId;\n sessionStorage.setItem(SESSION_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._sessionId;\n }\n }\n\n private _getVisitorId(): string {\n try {\n let id = localStorage.getItem(LOCAL_STORAGE_KEY);\n if (!id) {\n id = this._visitorId;\n localStorage.setItem(LOCAL_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._visitorId;\n }\n }\n\n private _generateId(prefix: string): string {\n if (\n typeof globalThis.crypto !== 'undefined' &&\n typeof globalThis.crypto.randomUUID === 'function'\n ) {\n try {\n return `${prefix}-${crypto.randomUUID()}`;\n } catch {\n // Continue with Math.random() fallback.\n }\n }\n return `${prefix}-${Math.random().toString(36).substring(2)}`;\n }\n\n private _getViewport(): string {\n return `${window.innerWidth}x${window.innerHeight}`;\n }\n}\n","import { Altertable } from './core';\n\nexport type { Altertable };\n\ndeclare global {\n interface Window {\n Altertable: Altertable | Array<Array<unknown>> | undefined;\n }\n}\n\nexport const altertable = new Altertable();\n\nconst stub = window.Altertable;\nif (stub && Array.isArray(stub)) {\n for (const item of stub) {\n const method = item[0];\n const args = item.slice(1);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (altertable[method as keyof Altertable] as any)(...args);\n }\n}\n\nwindow.Altertable = altertable;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/lib/safelyRunOnBrowser.ts","../src/core.ts","../src/index.ts"],"sourcesContent":["/** Runs code on browser environments safely. */\nexport function safelyRunOnBrowser<TReturn>(\n callback: (params: { window: typeof window }) => TReturn,\n /** Fallback to run on server environments. */\n fallback: () => TReturn = () => undefined as unknown as TReturn\n): TReturn {\n if (typeof window === 'undefined') {\n return fallback();\n }\n\n return callback({ window });\n}\n","import { safelyRunOnBrowser } from './lib/safelyRunOnBrowser';\n\nexport interface Config {\n /**\n * The base URL of the Altertable API.\n * @default https://api.altertable.ai\n */\n baseUrl?: string;\n /**\n * The environment of the application.\n * @default \"production\"\n */\n environment?: string;\n /**\n * Whether to automatically capture page views and events.\n * @default true\n */\n autoCapture?: boolean;\n /**\n * The release ID of the application.\n * This is helpful to identify the version of the application an event is coming from.\n */\n release?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.altertable.ai';\nconst DEFAULT_ENVIRONMENT = 'production';\n\nexport type EventProperties = Record<string, unknown>;\n\nexport const PAGEVIEW_EVENT = '$pageview';\n\nexport const SESSION_STORAGE_KEY = 'altertable-session-id';\nexport const LOCAL_STORAGE_KEY = 'altertable-visitor-id';\nexport const AUTO_CAPTURE_INTERVAL = 100;\n\nexport const PROPERTY_URL = '$url';\nexport const PROPERTY_SESSION_ID = '$session_id';\nexport const PROPERTY_VISITOR_ID = '$visitor_id';\nexport const PROPERTY_VIEWPORT = '$viewport';\nexport const PROPERTY_REFERER = '$referer';\nexport const PROPERTY_RELEASE = '$release';\nexport const PROPERTY_LIB = '$lib';\nexport const PROPERTY_LIB_VERSION = '$lib_version';\n\nexport class Altertable {\n private _lastUrl: string;\n private _apiKey: string;\n private _config: Config;\n private _sessionId: string;\n private _visitorId: string;\n private _userId: string;\n private _referrer: string | null;\n\n constructor() {\n this._referrer = safelyRunOnBrowser<string | null>(\n ({ window }) => window.document.referrer || null,\n () => null\n );\n this._lastUrl = safelyRunOnBrowser(\n ({ window }) => window.location.href,\n () => ''\n );\n this._sessionId = this._generateId('session');\n this._visitorId = this._generateId('visitor');\n this._userId = this._generateId('anonymous');\n }\n\n init(apiKey: string, config: Config = {}) {\n this._apiKey = apiKey;\n this._config = config;\n\n if (config.autoCapture !== false) {\n if (this._lastUrl) {\n this.page(this._lastUrl);\n }\n\n setInterval(() => {\n this._checkForChanges();\n }, AUTO_CAPTURE_INTERVAL);\n\n safelyRunOnBrowser(({ window }) => {\n window.addEventListener('popstate', () => this._checkForChanges());\n window.addEventListener('hashchange', () => this._checkForChanges());\n });\n }\n }\n\n identify(userId: string) {\n // FIXME: dummy implementation\n this._userId = userId;\n }\n\n page(url: string) {\n const parsedUrl = new URL(url);\n const urlWithoutSearch = `${parsedUrl.origin}${parsedUrl.pathname}`;\n this.track(PAGEVIEW_EVENT, {\n [PROPERTY_URL]: urlWithoutSearch,\n [PROPERTY_SESSION_ID]: this._getSessionId(),\n [PROPERTY_VISITOR_ID]: this._getVisitorId(),\n [PROPERTY_VIEWPORT]: this._getViewport(),\n [PROPERTY_REFERER]: this._referrer,\n ...Object.fromEntries(parsedUrl.searchParams),\n });\n }\n\n track(event: string, properties?: EventProperties) {\n this._request('/track', {\n event,\n user_id: this._userId,\n environment: this._config.environment || DEFAULT_ENVIRONMENT,\n properties: {\n [PROPERTY_LIB]: __LIB__,\n [PROPERTY_LIB_VERSION]: __LIB_VERSION__,\n [PROPERTY_RELEASE]: this._config.release,\n // The above properties might be overridden by user-provided fields\n // and the React library\n ...(properties || {}),\n },\n });\n }\n\n private _checkForChanges() {\n safelyRunOnBrowser(({ window }) => {\n const currentUrl = window.location.href;\n if (currentUrl !== this._lastUrl) {\n this.page(currentUrl);\n this._referrer = this._lastUrl;\n this._lastUrl = currentUrl;\n }\n });\n }\n\n private _request(path: string, body: unknown): void {\n const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;\n const payload = JSON.stringify(body);\n\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n const beaconUrl = `${url}?apiKey=${encodeURIComponent(this._apiKey)}`;\n const blob = new Blob([payload], { type: 'application/json' });\n navigator.sendBeacon(beaconUrl, blob);\n } else {\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this._apiKey}`,\n },\n body: payload,\n });\n }\n }\n\n private _getSessionId(): string {\n try {\n let id = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!id) {\n id = this._sessionId;\n sessionStorage.setItem(SESSION_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._sessionId;\n }\n }\n\n private _getVisitorId(): string {\n try {\n let id = localStorage.getItem(LOCAL_STORAGE_KEY);\n if (!id) {\n id = this._visitorId;\n localStorage.setItem(LOCAL_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._visitorId;\n }\n }\n\n private _generateId(prefix: string): string {\n if (\n typeof globalThis.crypto !== 'undefined' &&\n typeof globalThis.crypto.randomUUID === 'function'\n ) {\n try {\n return `${prefix}-${crypto.randomUUID()}`;\n } catch {\n // Continue with Math.random() fallback.\n }\n }\n return `${prefix}-${Math.random().toString(36).substring(2)}`;\n }\n\n private _getViewport(): string {\n return safelyRunOnBrowser(\n ({ window }) => `${window.innerWidth}x${window.innerHeight}`,\n () => '0x0'\n );\n }\n}\n","import { Altertable } from './core';\nimport { safelyRunOnBrowser } from './lib/safelyRunOnBrowser';\n\nexport type { Altertable };\n\ndeclare global {\n interface Window {\n Altertable: Altertable | Array<Array<unknown>> | undefined;\n }\n}\n\nexport const altertable = new Altertable();\n\nsafelyRunOnBrowser(({ window }) => {\n const stub = window.Altertable;\n if (stub && Array.isArray(stub)) {\n for (const item of stub) {\n const method = item[0];\n const args = item.slice(1);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (altertable[method as keyof Altertable] as any)(...args);\n }\n }\n\n window.Altertable = altertable;\n});\n"],"mappings":"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","names":["window","window"]}
package/dist/index.js CHANGED
@@ -23,6 +23,14 @@ __export(index_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(index_exports);
25
25
 
26
+ // src/lib/safelyRunOnBrowser.ts
27
+ function safelyRunOnBrowser(callback, fallback = () => void 0) {
28
+ if (typeof window === "undefined") {
29
+ return fallback();
30
+ }
31
+ return callback({ window });
32
+ }
33
+
26
34
  // src/core.ts
27
35
  var DEFAULT_BASE_URL = "https://api.altertable.ai";
28
36
  var DEFAULT_ENVIRONMENT = "production";
@@ -47,8 +55,14 @@ var Altertable = class {
47
55
  _userId;
48
56
  _referrer;
49
57
  constructor() {
50
- this._referrer = document.referrer || null;
51
- this._lastUrl = window.location.href;
58
+ this._referrer = safelyRunOnBrowser(
59
+ ({ window: window2 }) => window2.document.referrer || null,
60
+ () => null
61
+ );
62
+ this._lastUrl = safelyRunOnBrowser(
63
+ ({ window: window2 }) => window2.location.href,
64
+ () => ""
65
+ );
52
66
  this._sessionId = this._generateId("session");
53
67
  this._visitorId = this._generateId("visitor");
54
68
  this._userId = this._generateId("anonymous");
@@ -57,12 +71,16 @@ var Altertable = class {
57
71
  this._apiKey = apiKey;
58
72
  this._config = config;
59
73
  if (config.autoCapture !== false) {
60
- this.page(this._lastUrl);
74
+ if (this._lastUrl) {
75
+ this.page(this._lastUrl);
76
+ }
61
77
  setInterval(() => {
62
78
  this._checkForChanges();
63
79
  }, AUTO_CAPTURE_INTERVAL);
64
- window.addEventListener("popstate", () => this._checkForChanges());
65
- window.addEventListener("hashchange", () => this._checkForChanges());
80
+ safelyRunOnBrowser(({ window: window2 }) => {
81
+ window2.addEventListener("popstate", () => this._checkForChanges());
82
+ window2.addEventListener("hashchange", () => this._checkForChanges());
83
+ });
66
84
  }
67
85
  }
68
86
  identify(userId) {
@@ -87,7 +105,7 @@ var Altertable = class {
87
105
  environment: this._config.environment || DEFAULT_ENVIRONMENT,
88
106
  properties: {
89
107
  [PROPERTY_LIB]: "@altertable/altertable-js",
90
- [PROPERTY_LIB_VERSION]: "0.3.0",
108
+ [PROPERTY_LIB_VERSION]: "0.4.0",
91
109
  [PROPERTY_RELEASE]: this._config.release,
92
110
  // The above properties might be overridden by user-provided fields
93
111
  // and the React library
@@ -96,12 +114,14 @@ var Altertable = class {
96
114
  });
97
115
  }
98
116
  _checkForChanges() {
99
- const currentUrl = window.location.href;
100
- if (currentUrl !== this._lastUrl) {
101
- this.page(currentUrl);
102
- this._referrer = this._lastUrl;
103
- this._lastUrl = currentUrl;
104
- }
117
+ safelyRunOnBrowser(({ window: window2 }) => {
118
+ const currentUrl = window2.location.href;
119
+ if (currentUrl !== this._lastUrl) {
120
+ this.page(currentUrl);
121
+ this._referrer = this._lastUrl;
122
+ this._lastUrl = currentUrl;
123
+ }
124
+ });
105
125
  }
106
126
  _request(path, body) {
107
127
  const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;
@@ -155,19 +175,24 @@ var Altertable = class {
155
175
  return `${prefix}-${Math.random().toString(36).substring(2)}`;
156
176
  }
157
177
  _getViewport() {
158
- return `${window.innerWidth}x${window.innerHeight}`;
178
+ return safelyRunOnBrowser(
179
+ ({ window: window2 }) => `${window2.innerWidth}x${window2.innerHeight}`,
180
+ () => "0x0"
181
+ );
159
182
  }
160
183
  };
161
184
 
162
185
  // src/index.ts
163
186
  var altertable = new Altertable();
164
- var stub = window.Altertable;
165
- if (stub && Array.isArray(stub)) {
166
- for (const item of stub) {
167
- const method = item[0];
168
- const args = item.slice(1);
169
- altertable[method](...args);
187
+ safelyRunOnBrowser(({ window: window2 }) => {
188
+ const stub = window2.Altertable;
189
+ if (stub && Array.isArray(stub)) {
190
+ for (const item of stub) {
191
+ const method = item[0];
192
+ const args = item.slice(1);
193
+ altertable[method](...args);
194
+ }
170
195
  }
171
- }
172
- window.Altertable = altertable;
196
+ window2.Altertable = altertable;
197
+ });
173
198
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core.ts"],"sourcesContent":["import { Altertable } from './core';\n\nexport type { Altertable };\n\ndeclare global {\n interface Window {\n Altertable: Altertable | Array<Array<unknown>> | undefined;\n }\n}\n\nexport const altertable = new Altertable();\n\nconst stub = window.Altertable;\nif (stub && Array.isArray(stub)) {\n for (const item of stub) {\n const method = item[0];\n const args = item.slice(1);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (altertable[method as keyof Altertable] as any)(...args);\n }\n}\n\nwindow.Altertable = altertable;\n","export interface Config {\n /**\n * The base URL of the Altertable API.\n * @default https://api.altertable.ai\n */\n baseUrl?: string;\n /**\n * The environment of the application.\n * @default \"production\"\n */\n environment?: string;\n /**\n * Whether to automatically capture page views and events.\n * @default true\n */\n autoCapture?: boolean;\n /**\n * The release ID of the application.\n * This is helpful to identify the version of the application an event is coming from.\n */\n release?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.altertable.ai';\nconst DEFAULT_ENVIRONMENT = 'production';\n\nexport type EventProperties = Record<string, unknown>;\n\nexport const PAGEVIEW_EVENT = '$pageview';\n\nexport const SESSION_STORAGE_KEY = 'altertable-session-id';\nexport const LOCAL_STORAGE_KEY = 'altertable-visitor-id';\nexport const AUTO_CAPTURE_INTERVAL = 100;\n\nexport const PROPERTY_URL = '$url';\nexport const PROPERTY_SESSION_ID = '$session_id';\nexport const PROPERTY_VISITOR_ID = '$visitor_id';\nexport const PROPERTY_VIEWPORT = '$viewport';\nexport const PROPERTY_REFERER = '$referer';\nexport const PROPERTY_RELEASE = '$release';\nexport const PROPERTY_LIB = '$lib';\nexport const PROPERTY_LIB_VERSION = '$lib_version';\n\nexport class Altertable {\n private _lastUrl: string;\n private _apiKey: string;\n private _config: Config;\n private _sessionId: string;\n private _visitorId: string;\n private _userId: string;\n private _referrer: string | null;\n\n constructor() {\n this._referrer = document.referrer || null;\n this._lastUrl = window.location.href;\n this._sessionId = this._generateId('session');\n this._visitorId = this._generateId('visitor');\n this._userId = this._generateId('anonymous');\n }\n\n init(apiKey: string, config: Config = {}) {\n this._apiKey = apiKey;\n this._config = config;\n\n if (config.autoCapture !== false) {\n this.page(this._lastUrl);\n\n setInterval(() => {\n this._checkForChanges();\n }, AUTO_CAPTURE_INTERVAL);\n\n window.addEventListener('popstate', () => this._checkForChanges());\n window.addEventListener('hashchange', () => this._checkForChanges());\n }\n }\n\n identify(userId: string) {\n // FIXME: dummy implementation\n this._userId = userId;\n }\n\n page(url: string) {\n const parsedUrl = new URL(url);\n const urlWithoutSearch = `${parsedUrl.origin}${parsedUrl.pathname}`;\n this.track(PAGEVIEW_EVENT, {\n [PROPERTY_URL]: urlWithoutSearch,\n [PROPERTY_SESSION_ID]: this._getSessionId(),\n [PROPERTY_VISITOR_ID]: this._getVisitorId(),\n [PROPERTY_VIEWPORT]: this._getViewport(),\n [PROPERTY_REFERER]: this._referrer,\n ...Object.fromEntries(parsedUrl.searchParams),\n });\n }\n\n track(event: string, properties?: EventProperties) {\n this._request('/track', {\n event,\n user_id: this._userId,\n environment: this._config.environment || DEFAULT_ENVIRONMENT,\n properties: {\n [PROPERTY_LIB]: __LIB__,\n [PROPERTY_LIB_VERSION]: __LIB_VERSION__,\n [PROPERTY_RELEASE]: this._config.release,\n // The above properties might be overridden by user-provided fields\n // and the React library\n ...(properties || {}),\n },\n });\n }\n\n private _checkForChanges() {\n const currentUrl = window.location.href;\n if (currentUrl !== this._lastUrl) {\n this.page(currentUrl);\n this._referrer = this._lastUrl;\n this._lastUrl = currentUrl;\n }\n }\n\n private _request(path: string, body: unknown): void {\n const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;\n const payload = JSON.stringify(body);\n\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n const beaconUrl = `${url}?apiKey=${encodeURIComponent(this._apiKey)}`;\n const blob = new Blob([payload], { type: 'application/json' });\n navigator.sendBeacon(beaconUrl, blob);\n } else {\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this._apiKey}`,\n },\n body: payload,\n });\n }\n }\n\n private _getSessionId(): string {\n try {\n let id = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!id) {\n id = this._sessionId;\n sessionStorage.setItem(SESSION_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._sessionId;\n }\n }\n\n private _getVisitorId(): string {\n try {\n let id = localStorage.getItem(LOCAL_STORAGE_KEY);\n if (!id) {\n id = this._visitorId;\n localStorage.setItem(LOCAL_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._visitorId;\n }\n }\n\n private _generateId(prefix: string): string {\n if (\n typeof globalThis.crypto !== 'undefined' &&\n typeof globalThis.crypto.randomUUID === 'function'\n ) {\n try {\n return `${prefix}-${crypto.randomUUID()}`;\n } catch {\n // Continue with Math.random() fallback.\n }\n }\n return `${prefix}-${Math.random().toString(36).substring(2)}`;\n }\n\n private _getViewport(): string {\n return `${window.innerWidth}x${window.innerHeight}`;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/safelyRunOnBrowser.ts","../src/core.ts"],"sourcesContent":["import { Altertable } from './core';\nimport { safelyRunOnBrowser } from './lib/safelyRunOnBrowser';\n\nexport type { Altertable };\n\ndeclare global {\n interface Window {\n Altertable: Altertable | Array<Array<unknown>> | undefined;\n }\n}\n\nexport const altertable = new Altertable();\n\nsafelyRunOnBrowser(({ window }) => {\n const stub = window.Altertable;\n if (stub && Array.isArray(stub)) {\n for (const item of stub) {\n const method = item[0];\n const args = item.slice(1);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (altertable[method as keyof Altertable] as any)(...args);\n }\n }\n\n window.Altertable = altertable;\n});\n","/** Runs code on browser environments safely. */\nexport function safelyRunOnBrowser<TReturn>(\n callback: (params: { window: typeof window }) => TReturn,\n /** Fallback to run on server environments. */\n fallback: () => TReturn = () => undefined as unknown as TReturn\n): TReturn {\n if (typeof window === 'undefined') {\n return fallback();\n }\n\n return callback({ window });\n}\n","import { safelyRunOnBrowser } from './lib/safelyRunOnBrowser';\n\nexport interface Config {\n /**\n * The base URL of the Altertable API.\n * @default https://api.altertable.ai\n */\n baseUrl?: string;\n /**\n * The environment of the application.\n * @default \"production\"\n */\n environment?: string;\n /**\n * Whether to automatically capture page views and events.\n * @default true\n */\n autoCapture?: boolean;\n /**\n * The release ID of the application.\n * This is helpful to identify the version of the application an event is coming from.\n */\n release?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.altertable.ai';\nconst DEFAULT_ENVIRONMENT = 'production';\n\nexport type EventProperties = Record<string, unknown>;\n\nexport const PAGEVIEW_EVENT = '$pageview';\n\nexport const SESSION_STORAGE_KEY = 'altertable-session-id';\nexport const LOCAL_STORAGE_KEY = 'altertable-visitor-id';\nexport const AUTO_CAPTURE_INTERVAL = 100;\n\nexport const PROPERTY_URL = '$url';\nexport const PROPERTY_SESSION_ID = '$session_id';\nexport const PROPERTY_VISITOR_ID = '$visitor_id';\nexport const PROPERTY_VIEWPORT = '$viewport';\nexport const PROPERTY_REFERER = '$referer';\nexport const PROPERTY_RELEASE = '$release';\nexport const PROPERTY_LIB = '$lib';\nexport const PROPERTY_LIB_VERSION = '$lib_version';\n\nexport class Altertable {\n private _lastUrl: string;\n private _apiKey: string;\n private _config: Config;\n private _sessionId: string;\n private _visitorId: string;\n private _userId: string;\n private _referrer: string | null;\n\n constructor() {\n this._referrer = safelyRunOnBrowser<string | null>(\n ({ window }) => window.document.referrer || null,\n () => null\n );\n this._lastUrl = safelyRunOnBrowser(\n ({ window }) => window.location.href,\n () => ''\n );\n this._sessionId = this._generateId('session');\n this._visitorId = this._generateId('visitor');\n this._userId = this._generateId('anonymous');\n }\n\n init(apiKey: string, config: Config = {}) {\n this._apiKey = apiKey;\n this._config = config;\n\n if (config.autoCapture !== false) {\n if (this._lastUrl) {\n this.page(this._lastUrl);\n }\n\n setInterval(() => {\n this._checkForChanges();\n }, AUTO_CAPTURE_INTERVAL);\n\n safelyRunOnBrowser(({ window }) => {\n window.addEventListener('popstate', () => this._checkForChanges());\n window.addEventListener('hashchange', () => this._checkForChanges());\n });\n }\n }\n\n identify(userId: string) {\n // FIXME: dummy implementation\n this._userId = userId;\n }\n\n page(url: string) {\n const parsedUrl = new URL(url);\n const urlWithoutSearch = `${parsedUrl.origin}${parsedUrl.pathname}`;\n this.track(PAGEVIEW_EVENT, {\n [PROPERTY_URL]: urlWithoutSearch,\n [PROPERTY_SESSION_ID]: this._getSessionId(),\n [PROPERTY_VISITOR_ID]: this._getVisitorId(),\n [PROPERTY_VIEWPORT]: this._getViewport(),\n [PROPERTY_REFERER]: this._referrer,\n ...Object.fromEntries(parsedUrl.searchParams),\n });\n }\n\n track(event: string, properties?: EventProperties) {\n this._request('/track', {\n event,\n user_id: this._userId,\n environment: this._config.environment || DEFAULT_ENVIRONMENT,\n properties: {\n [PROPERTY_LIB]: __LIB__,\n [PROPERTY_LIB_VERSION]: __LIB_VERSION__,\n [PROPERTY_RELEASE]: this._config.release,\n // The above properties might be overridden by user-provided fields\n // and the React library\n ...(properties || {}),\n },\n });\n }\n\n private _checkForChanges() {\n safelyRunOnBrowser(({ window }) => {\n const currentUrl = window.location.href;\n if (currentUrl !== this._lastUrl) {\n this.page(currentUrl);\n this._referrer = this._lastUrl;\n this._lastUrl = currentUrl;\n }\n });\n }\n\n private _request(path: string, body: unknown): void {\n const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;\n const payload = JSON.stringify(body);\n\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n const beaconUrl = `${url}?apiKey=${encodeURIComponent(this._apiKey)}`;\n const blob = new Blob([payload], { type: 'application/json' });\n navigator.sendBeacon(beaconUrl, blob);\n } else {\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this._apiKey}`,\n },\n body: payload,\n });\n }\n }\n\n private _getSessionId(): string {\n try {\n let id = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!id) {\n id = this._sessionId;\n sessionStorage.setItem(SESSION_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._sessionId;\n }\n }\n\n private _getVisitorId(): string {\n try {\n let id = localStorage.getItem(LOCAL_STORAGE_KEY);\n if (!id) {\n id = this._visitorId;\n localStorage.setItem(LOCAL_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._visitorId;\n }\n }\n\n private _generateId(prefix: string): string {\n if (\n typeof globalThis.crypto !== 'undefined' &&\n typeof globalThis.crypto.randomUUID === 'function'\n ) {\n try {\n return `${prefix}-${crypto.randomUUID()}`;\n } catch {\n // Continue with Math.random() fallback.\n }\n }\n return `${prefix}-${Math.random().toString(36).substring(2)}`;\n }\n\n private _getViewport(): string {\n return safelyRunOnBrowser(\n ({ window }) => `${window.innerWidth}x${window.innerHeight}`,\n () => '0x0'\n );\n }\n}\n"],"mappings":"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","names":["window","window"]}
package/dist/index.mjs CHANGED
@@ -1,3 +1,11 @@
1
+ // src/lib/safelyRunOnBrowser.ts
2
+ function safelyRunOnBrowser(callback, fallback = () => void 0) {
3
+ if (typeof window === "undefined") {
4
+ return fallback();
5
+ }
6
+ return callback({ window });
7
+ }
8
+
1
9
  // src/core.ts
2
10
  var DEFAULT_BASE_URL = "https://api.altertable.ai";
3
11
  var DEFAULT_ENVIRONMENT = "production";
@@ -22,8 +30,14 @@ var Altertable = class {
22
30
  _userId;
23
31
  _referrer;
24
32
  constructor() {
25
- this._referrer = document.referrer || null;
26
- this._lastUrl = window.location.href;
33
+ this._referrer = safelyRunOnBrowser(
34
+ ({ window: window2 }) => window2.document.referrer || null,
35
+ () => null
36
+ );
37
+ this._lastUrl = safelyRunOnBrowser(
38
+ ({ window: window2 }) => window2.location.href,
39
+ () => ""
40
+ );
27
41
  this._sessionId = this._generateId("session");
28
42
  this._visitorId = this._generateId("visitor");
29
43
  this._userId = this._generateId("anonymous");
@@ -32,12 +46,16 @@ var Altertable = class {
32
46
  this._apiKey = apiKey;
33
47
  this._config = config;
34
48
  if (config.autoCapture !== false) {
35
- this.page(this._lastUrl);
49
+ if (this._lastUrl) {
50
+ this.page(this._lastUrl);
51
+ }
36
52
  setInterval(() => {
37
53
  this._checkForChanges();
38
54
  }, AUTO_CAPTURE_INTERVAL);
39
- window.addEventListener("popstate", () => this._checkForChanges());
40
- window.addEventListener("hashchange", () => this._checkForChanges());
55
+ safelyRunOnBrowser(({ window: window2 }) => {
56
+ window2.addEventListener("popstate", () => this._checkForChanges());
57
+ window2.addEventListener("hashchange", () => this._checkForChanges());
58
+ });
41
59
  }
42
60
  }
43
61
  identify(userId) {
@@ -62,7 +80,7 @@ var Altertable = class {
62
80
  environment: this._config.environment || DEFAULT_ENVIRONMENT,
63
81
  properties: {
64
82
  [PROPERTY_LIB]: "@altertable/altertable-js",
65
- [PROPERTY_LIB_VERSION]: "0.3.0",
83
+ [PROPERTY_LIB_VERSION]: "0.4.0",
66
84
  [PROPERTY_RELEASE]: this._config.release,
67
85
  // The above properties might be overridden by user-provided fields
68
86
  // and the React library
@@ -71,12 +89,14 @@ var Altertable = class {
71
89
  });
72
90
  }
73
91
  _checkForChanges() {
74
- const currentUrl = window.location.href;
75
- if (currentUrl !== this._lastUrl) {
76
- this.page(currentUrl);
77
- this._referrer = this._lastUrl;
78
- this._lastUrl = currentUrl;
79
- }
92
+ safelyRunOnBrowser(({ window: window2 }) => {
93
+ const currentUrl = window2.location.href;
94
+ if (currentUrl !== this._lastUrl) {
95
+ this.page(currentUrl);
96
+ this._referrer = this._lastUrl;
97
+ this._lastUrl = currentUrl;
98
+ }
99
+ });
80
100
  }
81
101
  _request(path, body) {
82
102
  const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;
@@ -130,21 +150,26 @@ var Altertable = class {
130
150
  return `${prefix}-${Math.random().toString(36).substring(2)}`;
131
151
  }
132
152
  _getViewport() {
133
- return `${window.innerWidth}x${window.innerHeight}`;
153
+ return safelyRunOnBrowser(
154
+ ({ window: window2 }) => `${window2.innerWidth}x${window2.innerHeight}`,
155
+ () => "0x0"
156
+ );
134
157
  }
135
158
  };
136
159
 
137
160
  // src/index.ts
138
161
  var altertable = new Altertable();
139
- var stub = window.Altertable;
140
- if (stub && Array.isArray(stub)) {
141
- for (const item of stub) {
142
- const method = item[0];
143
- const args = item.slice(1);
144
- altertable[method](...args);
162
+ safelyRunOnBrowser(({ window: window2 }) => {
163
+ const stub = window2.Altertable;
164
+ if (stub && Array.isArray(stub)) {
165
+ for (const item of stub) {
166
+ const method = item[0];
167
+ const args = item.slice(1);
168
+ altertable[method](...args);
169
+ }
145
170
  }
146
- }
147
- window.Altertable = altertable;
171
+ window2.Altertable = altertable;
172
+ });
148
173
  export {
149
174
  altertable
150
175
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core.ts","../src/index.ts"],"sourcesContent":["export interface Config {\n /**\n * The base URL of the Altertable API.\n * @default https://api.altertable.ai\n */\n baseUrl?: string;\n /**\n * The environment of the application.\n * @default \"production\"\n */\n environment?: string;\n /**\n * Whether to automatically capture page views and events.\n * @default true\n */\n autoCapture?: boolean;\n /**\n * The release ID of the application.\n * This is helpful to identify the version of the application an event is coming from.\n */\n release?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.altertable.ai';\nconst DEFAULT_ENVIRONMENT = 'production';\n\nexport type EventProperties = Record<string, unknown>;\n\nexport const PAGEVIEW_EVENT = '$pageview';\n\nexport const SESSION_STORAGE_KEY = 'altertable-session-id';\nexport const LOCAL_STORAGE_KEY = 'altertable-visitor-id';\nexport const AUTO_CAPTURE_INTERVAL = 100;\n\nexport const PROPERTY_URL = '$url';\nexport const PROPERTY_SESSION_ID = '$session_id';\nexport const PROPERTY_VISITOR_ID = '$visitor_id';\nexport const PROPERTY_VIEWPORT = '$viewport';\nexport const PROPERTY_REFERER = '$referer';\nexport const PROPERTY_RELEASE = '$release';\nexport const PROPERTY_LIB = '$lib';\nexport const PROPERTY_LIB_VERSION = '$lib_version';\n\nexport class Altertable {\n private _lastUrl: string;\n private _apiKey: string;\n private _config: Config;\n private _sessionId: string;\n private _visitorId: string;\n private _userId: string;\n private _referrer: string | null;\n\n constructor() {\n this._referrer = document.referrer || null;\n this._lastUrl = window.location.href;\n this._sessionId = this._generateId('session');\n this._visitorId = this._generateId('visitor');\n this._userId = this._generateId('anonymous');\n }\n\n init(apiKey: string, config: Config = {}) {\n this._apiKey = apiKey;\n this._config = config;\n\n if (config.autoCapture !== false) {\n this.page(this._lastUrl);\n\n setInterval(() => {\n this._checkForChanges();\n }, AUTO_CAPTURE_INTERVAL);\n\n window.addEventListener('popstate', () => this._checkForChanges());\n window.addEventListener('hashchange', () => this._checkForChanges());\n }\n }\n\n identify(userId: string) {\n // FIXME: dummy implementation\n this._userId = userId;\n }\n\n page(url: string) {\n const parsedUrl = new URL(url);\n const urlWithoutSearch = `${parsedUrl.origin}${parsedUrl.pathname}`;\n this.track(PAGEVIEW_EVENT, {\n [PROPERTY_URL]: urlWithoutSearch,\n [PROPERTY_SESSION_ID]: this._getSessionId(),\n [PROPERTY_VISITOR_ID]: this._getVisitorId(),\n [PROPERTY_VIEWPORT]: this._getViewport(),\n [PROPERTY_REFERER]: this._referrer,\n ...Object.fromEntries(parsedUrl.searchParams),\n });\n }\n\n track(event: string, properties?: EventProperties) {\n this._request('/track', {\n event,\n user_id: this._userId,\n environment: this._config.environment || DEFAULT_ENVIRONMENT,\n properties: {\n [PROPERTY_LIB]: __LIB__,\n [PROPERTY_LIB_VERSION]: __LIB_VERSION__,\n [PROPERTY_RELEASE]: this._config.release,\n // The above properties might be overridden by user-provided fields\n // and the React library\n ...(properties || {}),\n },\n });\n }\n\n private _checkForChanges() {\n const currentUrl = window.location.href;\n if (currentUrl !== this._lastUrl) {\n this.page(currentUrl);\n this._referrer = this._lastUrl;\n this._lastUrl = currentUrl;\n }\n }\n\n private _request(path: string, body: unknown): void {\n const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;\n const payload = JSON.stringify(body);\n\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n const beaconUrl = `${url}?apiKey=${encodeURIComponent(this._apiKey)}`;\n const blob = new Blob([payload], { type: 'application/json' });\n navigator.sendBeacon(beaconUrl, blob);\n } else {\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this._apiKey}`,\n },\n body: payload,\n });\n }\n }\n\n private _getSessionId(): string {\n try {\n let id = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!id) {\n id = this._sessionId;\n sessionStorage.setItem(SESSION_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._sessionId;\n }\n }\n\n private _getVisitorId(): string {\n try {\n let id = localStorage.getItem(LOCAL_STORAGE_KEY);\n if (!id) {\n id = this._visitorId;\n localStorage.setItem(LOCAL_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._visitorId;\n }\n }\n\n private _generateId(prefix: string): string {\n if (\n typeof globalThis.crypto !== 'undefined' &&\n typeof globalThis.crypto.randomUUID === 'function'\n ) {\n try {\n return `${prefix}-${crypto.randomUUID()}`;\n } catch {\n // Continue with Math.random() fallback.\n }\n }\n return `${prefix}-${Math.random().toString(36).substring(2)}`;\n }\n\n private _getViewport(): string {\n return `${window.innerWidth}x${window.innerHeight}`;\n }\n}\n","import { Altertable } from './core';\n\nexport type { Altertable };\n\ndeclare global {\n interface Window {\n Altertable: Altertable | Array<Array<unknown>> | undefined;\n }\n}\n\nexport const altertable = new Altertable();\n\nconst stub = window.Altertable;\nif (stub && Array.isArray(stub)) {\n for (const item of stub) {\n const method = item[0];\n const args = item.slice(1);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (altertable[method as keyof Altertable] as any)(...args);\n }\n}\n\nwindow.Altertable = altertable;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/lib/safelyRunOnBrowser.ts","../src/core.ts","../src/index.ts"],"sourcesContent":["/** Runs code on browser environments safely. */\nexport function safelyRunOnBrowser<TReturn>(\n callback: (params: { window: typeof window }) => TReturn,\n /** Fallback to run on server environments. */\n fallback: () => TReturn = () => undefined as unknown as TReturn\n): TReturn {\n if (typeof window === 'undefined') {\n return fallback();\n }\n\n return callback({ window });\n}\n","import { safelyRunOnBrowser } from './lib/safelyRunOnBrowser';\n\nexport interface Config {\n /**\n * The base URL of the Altertable API.\n * @default https://api.altertable.ai\n */\n baseUrl?: string;\n /**\n * The environment of the application.\n * @default \"production\"\n */\n environment?: string;\n /**\n * Whether to automatically capture page views and events.\n * @default true\n */\n autoCapture?: boolean;\n /**\n * The release ID of the application.\n * This is helpful to identify the version of the application an event is coming from.\n */\n release?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.altertable.ai';\nconst DEFAULT_ENVIRONMENT = 'production';\n\nexport type EventProperties = Record<string, unknown>;\n\nexport const PAGEVIEW_EVENT = '$pageview';\n\nexport const SESSION_STORAGE_KEY = 'altertable-session-id';\nexport const LOCAL_STORAGE_KEY = 'altertable-visitor-id';\nexport const AUTO_CAPTURE_INTERVAL = 100;\n\nexport const PROPERTY_URL = '$url';\nexport const PROPERTY_SESSION_ID = '$session_id';\nexport const PROPERTY_VISITOR_ID = '$visitor_id';\nexport const PROPERTY_VIEWPORT = '$viewport';\nexport const PROPERTY_REFERER = '$referer';\nexport const PROPERTY_RELEASE = '$release';\nexport const PROPERTY_LIB = '$lib';\nexport const PROPERTY_LIB_VERSION = '$lib_version';\n\nexport class Altertable {\n private _lastUrl: string;\n private _apiKey: string;\n private _config: Config;\n private _sessionId: string;\n private _visitorId: string;\n private _userId: string;\n private _referrer: string | null;\n\n constructor() {\n this._referrer = safelyRunOnBrowser<string | null>(\n ({ window }) => window.document.referrer || null,\n () => null\n );\n this._lastUrl = safelyRunOnBrowser(\n ({ window }) => window.location.href,\n () => ''\n );\n this._sessionId = this._generateId('session');\n this._visitorId = this._generateId('visitor');\n this._userId = this._generateId('anonymous');\n }\n\n init(apiKey: string, config: Config = {}) {\n this._apiKey = apiKey;\n this._config = config;\n\n if (config.autoCapture !== false) {\n if (this._lastUrl) {\n this.page(this._lastUrl);\n }\n\n setInterval(() => {\n this._checkForChanges();\n }, AUTO_CAPTURE_INTERVAL);\n\n safelyRunOnBrowser(({ window }) => {\n window.addEventListener('popstate', () => this._checkForChanges());\n window.addEventListener('hashchange', () => this._checkForChanges());\n });\n }\n }\n\n identify(userId: string) {\n // FIXME: dummy implementation\n this._userId = userId;\n }\n\n page(url: string) {\n const parsedUrl = new URL(url);\n const urlWithoutSearch = `${parsedUrl.origin}${parsedUrl.pathname}`;\n this.track(PAGEVIEW_EVENT, {\n [PROPERTY_URL]: urlWithoutSearch,\n [PROPERTY_SESSION_ID]: this._getSessionId(),\n [PROPERTY_VISITOR_ID]: this._getVisitorId(),\n [PROPERTY_VIEWPORT]: this._getViewport(),\n [PROPERTY_REFERER]: this._referrer,\n ...Object.fromEntries(parsedUrl.searchParams),\n });\n }\n\n track(event: string, properties?: EventProperties) {\n this._request('/track', {\n event,\n user_id: this._userId,\n environment: this._config.environment || DEFAULT_ENVIRONMENT,\n properties: {\n [PROPERTY_LIB]: __LIB__,\n [PROPERTY_LIB_VERSION]: __LIB_VERSION__,\n [PROPERTY_RELEASE]: this._config.release,\n // The above properties might be overridden by user-provided fields\n // and the React library\n ...(properties || {}),\n },\n });\n }\n\n private _checkForChanges() {\n safelyRunOnBrowser(({ window }) => {\n const currentUrl = window.location.href;\n if (currentUrl !== this._lastUrl) {\n this.page(currentUrl);\n this._referrer = this._lastUrl;\n this._lastUrl = currentUrl;\n }\n });\n }\n\n private _request(path: string, body: unknown): void {\n const url = `${this._config.baseUrl || DEFAULT_BASE_URL}${path}`;\n const payload = JSON.stringify(body);\n\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n const beaconUrl = `${url}?apiKey=${encodeURIComponent(this._apiKey)}`;\n const blob = new Blob([payload], { type: 'application/json' });\n navigator.sendBeacon(beaconUrl, blob);\n } else {\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this._apiKey}`,\n },\n body: payload,\n });\n }\n }\n\n private _getSessionId(): string {\n try {\n let id = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!id) {\n id = this._sessionId;\n sessionStorage.setItem(SESSION_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._sessionId;\n }\n }\n\n private _getVisitorId(): string {\n try {\n let id = localStorage.getItem(LOCAL_STORAGE_KEY);\n if (!id) {\n id = this._visitorId;\n localStorage.setItem(LOCAL_STORAGE_KEY, id);\n }\n return id;\n } catch {\n return this._visitorId;\n }\n }\n\n private _generateId(prefix: string): string {\n if (\n typeof globalThis.crypto !== 'undefined' &&\n typeof globalThis.crypto.randomUUID === 'function'\n ) {\n try {\n return `${prefix}-${crypto.randomUUID()}`;\n } catch {\n // Continue with Math.random() fallback.\n }\n }\n return `${prefix}-${Math.random().toString(36).substring(2)}`;\n }\n\n private _getViewport(): string {\n return safelyRunOnBrowser(\n ({ window }) => `${window.innerWidth}x${window.innerHeight}`,\n () => '0x0'\n );\n }\n}\n","import { Altertable } from './core';\nimport { safelyRunOnBrowser } from './lib/safelyRunOnBrowser';\n\nexport type { Altertable };\n\ndeclare global {\n interface Window {\n Altertable: Altertable | Array<Array<unknown>> | undefined;\n }\n}\n\nexport const altertable = new Altertable();\n\nsafelyRunOnBrowser(({ window }) => {\n const stub = window.Altertable;\n if (stub && Array.isArray(stub)) {\n for (const item of stub) {\n const method = item[0];\n const args = item.slice(1);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (altertable[method as keyof Altertable] as any)(...args);\n }\n }\n\n window.Altertable = altertable;\n});\n"],"mappings":"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","names":["window","window"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@altertable/altertable-js",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "JavaScript SDK to capture and send events to Altertable.",
5
5
  "main": "dist/index.js",
6
6
  "private": false,