@cavuno/board 4.15.0 → 4.16.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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  This changelog records changes that affect Board API compatibility, exported
4
4
  types, runtime behavior, or supported integration patterns.
5
5
 
6
+ ## 4.16.0 — 2026-08-31
7
+
8
+ - **`@cavuno/board/analytics`**: new subpath with `install({ publishableKey })`
9
+ and `track(action, payload?)`. Uses the board publishable key (`pk_…`) only.
10
+ Default collect URL is Cavuno central collect; pass a first-party
11
+ `/.well-known/cavuno/collect` URL when the board host serves those handlers.
12
+ - **Stable analytics tenant**: events are keyed by the immutable public board
13
+ id (`boards_<accountId>`), not the mutable board slug.
14
+ - **Doctor**: `npx @cavuno/board doctor` includes an analytics-surface scan that
15
+ flags legacy third-party tracker credentials in app source.
16
+
6
17
  ## 4.15.0 — 2026-08-30
7
18
 
8
19
  - **LinkedIn conversion IDs on `board.context().analytics`**: five nullable
@@ -0,0 +1,58 @@
1
+ declare const DEFAULT_COLLECT_URL = "https://cavuno.com/api/analytics/collect";
2
+ declare const DEFAULT_SCRIPT_URL = "https://cavuno.com/js/metrics.js";
3
+ /** Placeholder tenant; collect rewrites from the publishable key. */
4
+ declare const PENDING_TENANT_ID = "boards_pending";
5
+ declare const WELL_KNOWN_ANALYTICS_SCRIPT_PATH = "/.well-known/cavuno/analytics.js";
6
+ declare const WELL_KNOWN_SCRIPT_PATH = "/.well-known/cavuno/analytics.js";
7
+ declare const WELL_KNOWN_COLLECT_PATH = "/.well-known/cavuno/collect";
8
+
9
+ /**
10
+ * Optional first-party well-known handlers for board origin Workers.
11
+ * Central collect remains the default when these paths are not mounted.
12
+ */
13
+
14
+ declare const WELL_KNOWN_COLLECT_EVENTS_PATH = "/.well-known/cavuno/collect/v0/events";
15
+ /**
16
+ * Handle `/.well-known/cavuno/{analytics.js,collect}` when mounted on a Worker.
17
+ * Returns null for every other path so the host can fall through.
18
+ */
19
+ declare function matchAnalyticsWellKnown(request: Request): Promise<Response | null>;
20
+
21
+ /**
22
+ * `@cavuno/board/analytics` — client write surface for board analytics.
23
+ *
24
+ * Emits pageviews (via hosted script) and custom events to Cavuno collect.
25
+ * Uses the board publishable key only; no second analytics credential.
26
+ */
27
+
28
+ type AnalyticsInstallOptions = {
29
+ publishableKey: string;
30
+ /** Default: Cavuno central collect (self-host safe) */
31
+ collectUrl?: string;
32
+ /** Default: Cavuno-hosted metrics script */
33
+ scriptUrl?: string;
34
+ };
35
+ /**
36
+ * Load the Cavuno-hosted metrics script and remember collect credentials.
37
+ * Safe to call once per page; subsequent calls update collect targets only.
38
+ */
39
+ declare function install(options: AnalyticsInstallOptions): void;
40
+ /**
41
+ * Emit a custom analytics event to Cavuno collect.
42
+ * Prefer `install` first so pageviews and vitals are also recorded.
43
+ */
44
+ declare function track(action: string, payload?: Record<string, unknown>): void;
45
+ declare const analytics: {
46
+ install: typeof install;
47
+ track: typeof track;
48
+ matchAnalyticsWellKnown: typeof matchAnalyticsWellKnown;
49
+ DEFAULT_COLLECT_URL: string;
50
+ DEFAULT_SCRIPT_URL: string;
51
+ PENDING_TENANT_ID: string;
52
+ WELL_KNOWN_ANALYTICS_SCRIPT_PATH: string;
53
+ WELL_KNOWN_SCRIPT_PATH: string;
54
+ WELL_KNOWN_COLLECT_PATH: string;
55
+ WELL_KNOWN_COLLECT_EVENTS_PATH: string;
56
+ };
57
+
58
+ export { type AnalyticsInstallOptions, DEFAULT_COLLECT_URL, DEFAULT_SCRIPT_URL, PENDING_TENANT_ID, WELL_KNOWN_ANALYTICS_SCRIPT_PATH, WELL_KNOWN_COLLECT_EVENTS_PATH, WELL_KNOWN_COLLECT_PATH, WELL_KNOWN_SCRIPT_PATH, analytics, install, matchAnalyticsWellKnown, track };
@@ -0,0 +1,58 @@
1
+ declare const DEFAULT_COLLECT_URL = "https://cavuno.com/api/analytics/collect";
2
+ declare const DEFAULT_SCRIPT_URL = "https://cavuno.com/js/metrics.js";
3
+ /** Placeholder tenant; collect rewrites from the publishable key. */
4
+ declare const PENDING_TENANT_ID = "boards_pending";
5
+ declare const WELL_KNOWN_ANALYTICS_SCRIPT_PATH = "/.well-known/cavuno/analytics.js";
6
+ declare const WELL_KNOWN_SCRIPT_PATH = "/.well-known/cavuno/analytics.js";
7
+ declare const WELL_KNOWN_COLLECT_PATH = "/.well-known/cavuno/collect";
8
+
9
+ /**
10
+ * Optional first-party well-known handlers for board origin Workers.
11
+ * Central collect remains the default when these paths are not mounted.
12
+ */
13
+
14
+ declare const WELL_KNOWN_COLLECT_EVENTS_PATH = "/.well-known/cavuno/collect/v0/events";
15
+ /**
16
+ * Handle `/.well-known/cavuno/{analytics.js,collect}` when mounted on a Worker.
17
+ * Returns null for every other path so the host can fall through.
18
+ */
19
+ declare function matchAnalyticsWellKnown(request: Request): Promise<Response | null>;
20
+
21
+ /**
22
+ * `@cavuno/board/analytics` — client write surface for board analytics.
23
+ *
24
+ * Emits pageviews (via hosted script) and custom events to Cavuno collect.
25
+ * Uses the board publishable key only; no second analytics credential.
26
+ */
27
+
28
+ type AnalyticsInstallOptions = {
29
+ publishableKey: string;
30
+ /** Default: Cavuno central collect (self-host safe) */
31
+ collectUrl?: string;
32
+ /** Default: Cavuno-hosted metrics script */
33
+ scriptUrl?: string;
34
+ };
35
+ /**
36
+ * Load the Cavuno-hosted metrics script and remember collect credentials.
37
+ * Safe to call once per page; subsequent calls update collect targets only.
38
+ */
39
+ declare function install(options: AnalyticsInstallOptions): void;
40
+ /**
41
+ * Emit a custom analytics event to Cavuno collect.
42
+ * Prefer `install` first so pageviews and vitals are also recorded.
43
+ */
44
+ declare function track(action: string, payload?: Record<string, unknown>): void;
45
+ declare const analytics: {
46
+ install: typeof install;
47
+ track: typeof track;
48
+ matchAnalyticsWellKnown: typeof matchAnalyticsWellKnown;
49
+ DEFAULT_COLLECT_URL: string;
50
+ DEFAULT_SCRIPT_URL: string;
51
+ PENDING_TENANT_ID: string;
52
+ WELL_KNOWN_ANALYTICS_SCRIPT_PATH: string;
53
+ WELL_KNOWN_SCRIPT_PATH: string;
54
+ WELL_KNOWN_COLLECT_PATH: string;
55
+ WELL_KNOWN_COLLECT_EVENTS_PATH: string;
56
+ };
57
+
58
+ export { type AnalyticsInstallOptions, DEFAULT_COLLECT_URL, DEFAULT_SCRIPT_URL, PENDING_TENANT_ID, WELL_KNOWN_ANALYTICS_SCRIPT_PATH, WELL_KNOWN_COLLECT_EVENTS_PATH, WELL_KNOWN_COLLECT_PATH, WELL_KNOWN_SCRIPT_PATH, analytics, install, matchAnalyticsWellKnown, track };
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/analytics/index.ts
21
+ var analytics_exports = {};
22
+ __export(analytics_exports, {
23
+ DEFAULT_COLLECT_URL: () => DEFAULT_COLLECT_URL,
24
+ DEFAULT_SCRIPT_URL: () => DEFAULT_SCRIPT_URL,
25
+ PENDING_TENANT_ID: () => PENDING_TENANT_ID,
26
+ WELL_KNOWN_ANALYTICS_SCRIPT_PATH: () => WELL_KNOWN_ANALYTICS_SCRIPT_PATH,
27
+ WELL_KNOWN_COLLECT_EVENTS_PATH: () => WELL_KNOWN_COLLECT_EVENTS_PATH,
28
+ WELL_KNOWN_COLLECT_PATH: () => WELL_KNOWN_COLLECT_PATH,
29
+ WELL_KNOWN_SCRIPT_PATH: () => WELL_KNOWN_SCRIPT_PATH,
30
+ analytics: () => analytics,
31
+ install: () => install,
32
+ matchAnalyticsWellKnown: () => matchAnalyticsWellKnown,
33
+ track: () => track
34
+ });
35
+ module.exports = __toCommonJS(analytics_exports);
36
+
37
+ // src/analytics/defaults.ts
38
+ var DEFAULT_COLLECT_URL = "https://cavuno.com/api/analytics/collect";
39
+ var DEFAULT_SCRIPT_URL = "https://cavuno.com/js/metrics.js";
40
+ var PENDING_TENANT_ID = "boards_pending";
41
+ var WELL_KNOWN_ANALYTICS_SCRIPT_PATH = "/.well-known/cavuno/analytics.js";
42
+ var WELL_KNOWN_SCRIPT_PATH = WELL_KNOWN_ANALYTICS_SCRIPT_PATH;
43
+ var WELL_KNOWN_COLLECT_PATH = "/.well-known/cavuno/collect";
44
+
45
+ // src/analytics/well-known.ts
46
+ var WELL_KNOWN_COLLECT_EVENTS_PATH = "/.well-known/cavuno/collect/v0/events";
47
+ var CORS_HEADERS = {
48
+ "Access-Control-Allow-Origin": "*",
49
+ "Access-Control-Allow-Methods": "POST, OPTIONS",
50
+ "Access-Control-Allow-Headers": "Authorization, Content-Type, Accept",
51
+ "Access-Control-Max-Age": "86400",
52
+ "Cross-Origin-Resource-Policy": "cross-origin"
53
+ };
54
+ function stripTrailingSlash(pathname) {
55
+ return pathname.length > 1 && pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
56
+ }
57
+ function withCors(response) {
58
+ const headers = new Headers(response.headers);
59
+ for (const [key, value] of Object.entries(CORS_HEADERS)) {
60
+ headers.set(key, value);
61
+ }
62
+ return new Response(response.body, {
63
+ status: response.status,
64
+ statusText: response.statusText,
65
+ headers
66
+ });
67
+ }
68
+ function corsPreflight() {
69
+ return withCors(new Response(null, { status: 204 }));
70
+ }
71
+ async function proxyCollect(request, targetUrl) {
72
+ if (request.method === "OPTIONS") {
73
+ return corsPreflight();
74
+ }
75
+ if (request.method !== "POST") {
76
+ return withCors(new Response(null, { status: 405 }));
77
+ }
78
+ const headers = new Headers();
79
+ const authorization = request.headers.get("Authorization");
80
+ const contentType = request.headers.get("Content-Type");
81
+ const accept = request.headers.get("Accept");
82
+ if (authorization) headers.set("Authorization", authorization);
83
+ if (contentType) headers.set("Content-Type", contentType);
84
+ if (accept) headers.set("Accept", accept);
85
+ const body = await request.arrayBuffer();
86
+ const upstream = await fetch(targetUrl, {
87
+ method: "POST",
88
+ headers,
89
+ body
90
+ });
91
+ return withCors(
92
+ new Response(upstream.body, {
93
+ status: upstream.status,
94
+ headers: {
95
+ "Content-Type": upstream.headers.get("Content-Type") ?? "application/json"
96
+ }
97
+ })
98
+ );
99
+ }
100
+ async function matchAnalyticsWellKnown(request) {
101
+ const path = stripTrailingSlash(new URL(request.url).pathname);
102
+ if (path === WELL_KNOWN_ANALYTICS_SCRIPT_PATH) {
103
+ if (request.method !== "GET" && request.method !== "HEAD") {
104
+ return new Response(null, { status: 405 });
105
+ }
106
+ return Response.redirect(DEFAULT_SCRIPT_URL, 302);
107
+ }
108
+ if (path === WELL_KNOWN_COLLECT_PATH) {
109
+ return proxyCollect(request, DEFAULT_COLLECT_URL);
110
+ }
111
+ if (path === WELL_KNOWN_COLLECT_EVENTS_PATH) {
112
+ return proxyCollect(request, `${DEFAULT_COLLECT_URL}/v0/events`);
113
+ }
114
+ return null;
115
+ }
116
+
117
+ // src/analytics/index.ts
118
+ var GLOBAL_NAME = "CavunoAnalytics";
119
+ var installed = null;
120
+ function getRoot() {
121
+ return globalThis;
122
+ }
123
+ function normalizeCollectUrl(url) {
124
+ return url.replace(/\/+$/, "");
125
+ }
126
+ function resolveDefaultCollectUrl() {
127
+ return DEFAULT_COLLECT_URL;
128
+ }
129
+ function resolveDefaultScriptUrl() {
130
+ return DEFAULT_SCRIPT_URL;
131
+ }
132
+ function postCollectJson(state, action, payload) {
133
+ const body = JSON.stringify({
134
+ publishableKey: state.publishableKey,
135
+ action,
136
+ payload: payload ?? {}
137
+ });
138
+ void fetch(state.collectUrl, {
139
+ method: "POST",
140
+ headers: {
141
+ Authorization: `Bearer ${state.publishableKey}`,
142
+ "Content-Type": "application/json",
143
+ Accept: "application/json"
144
+ },
145
+ body,
146
+ keepalive: true
147
+ }).catch(() => {
148
+ });
149
+ }
150
+ function exposeGlobal(state) {
151
+ const root = getRoot();
152
+ root[GLOBAL_NAME] = {
153
+ trackEvent(action, payload) {
154
+ postCollectJson(state, action, payload);
155
+ }
156
+ };
157
+ }
158
+ function injectScript(state, scriptUrl) {
159
+ const doc = getRoot().document;
160
+ if (!doc?.createElement) {
161
+ return;
162
+ }
163
+ if (doc.querySelector?.(`script[data-cavuno-analytics="1"]`)) {
164
+ return;
165
+ }
166
+ const el = doc.createElement("script");
167
+ el.defer = true;
168
+ el.src = scriptUrl;
169
+ el.setAttribute("data-cavuno-analytics", "1");
170
+ el.setAttribute("data-token", state.publishableKey);
171
+ el.setAttribute("data-host", state.collectUrl);
172
+ el.setAttribute("data-tenant-id", PENDING_TENANT_ID);
173
+ el.setAttribute("data-web-vitals", "true");
174
+ const head = doc.head;
175
+ if (head?.appendChild) {
176
+ head.appendChild(el);
177
+ return;
178
+ }
179
+ const first = doc.getElementsByTagName("script")[0];
180
+ first?.parentNode?.insertBefore(el, first);
181
+ }
182
+ function install(options) {
183
+ const publishableKey = options.publishableKey.trim();
184
+ if (!publishableKey.startsWith("pk_")) {
185
+ throw new Error("analytics.install requires a publishable key (pk_\u2026)");
186
+ }
187
+ const collectUrl = normalizeCollectUrl(
188
+ (options.collectUrl ?? resolveDefaultCollectUrl()).trim() || resolveDefaultCollectUrl()
189
+ );
190
+ const scriptUrl = (options.scriptUrl ?? resolveDefaultScriptUrl()).trim() || resolveDefaultScriptUrl();
191
+ installed = { publishableKey, collectUrl };
192
+ exposeGlobal(installed);
193
+ injectScript(installed, scriptUrl);
194
+ }
195
+ function track(action, payload) {
196
+ const trimmed = action.trim();
197
+ if (!trimmed) {
198
+ return;
199
+ }
200
+ const root = getRoot();
201
+ const globalTrack = root[GLOBAL_NAME]?.trackEvent;
202
+ if (typeof globalTrack === "function" && installed) {
203
+ globalTrack(trimmed, payload);
204
+ return;
205
+ }
206
+ if (!installed) {
207
+ return;
208
+ }
209
+ postCollectJson(installed, trimmed, payload);
210
+ }
211
+ var analytics = {
212
+ install,
213
+ track,
214
+ matchAnalyticsWellKnown,
215
+ DEFAULT_COLLECT_URL,
216
+ DEFAULT_SCRIPT_URL,
217
+ PENDING_TENANT_ID,
218
+ WELL_KNOWN_ANALYTICS_SCRIPT_PATH,
219
+ WELL_KNOWN_SCRIPT_PATH,
220
+ WELL_KNOWN_COLLECT_PATH,
221
+ WELL_KNOWN_COLLECT_EVENTS_PATH
222
+ };
@@ -0,0 +1,199 @@
1
+ // src/analytics/defaults.ts
2
+ var DEFAULT_COLLECT_URL = "https://cavuno.com/api/analytics/collect";
3
+ var DEFAULT_SCRIPT_URL = "https://cavuno.com/js/metrics.js";
4
+ var PENDING_TENANT_ID = "boards_pending";
5
+ var WELL_KNOWN_ANALYTICS_SCRIPT_PATH = "/.well-known/cavuno/analytics.js";
6
+ var WELL_KNOWN_SCRIPT_PATH = WELL_KNOWN_ANALYTICS_SCRIPT_PATH;
7
+ var WELL_KNOWN_COLLECT_PATH = "/.well-known/cavuno/collect";
8
+
9
+ // src/analytics/well-known.ts
10
+ var WELL_KNOWN_COLLECT_EVENTS_PATH = "/.well-known/cavuno/collect/v0/events";
11
+ var CORS_HEADERS = {
12
+ "Access-Control-Allow-Origin": "*",
13
+ "Access-Control-Allow-Methods": "POST, OPTIONS",
14
+ "Access-Control-Allow-Headers": "Authorization, Content-Type, Accept",
15
+ "Access-Control-Max-Age": "86400",
16
+ "Cross-Origin-Resource-Policy": "cross-origin"
17
+ };
18
+ function stripTrailingSlash(pathname) {
19
+ return pathname.length > 1 && pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
20
+ }
21
+ function withCors(response) {
22
+ const headers = new Headers(response.headers);
23
+ for (const [key, value] of Object.entries(CORS_HEADERS)) {
24
+ headers.set(key, value);
25
+ }
26
+ return new Response(response.body, {
27
+ status: response.status,
28
+ statusText: response.statusText,
29
+ headers
30
+ });
31
+ }
32
+ function corsPreflight() {
33
+ return withCors(new Response(null, { status: 204 }));
34
+ }
35
+ async function proxyCollect(request, targetUrl) {
36
+ if (request.method === "OPTIONS") {
37
+ return corsPreflight();
38
+ }
39
+ if (request.method !== "POST") {
40
+ return withCors(new Response(null, { status: 405 }));
41
+ }
42
+ const headers = new Headers();
43
+ const authorization = request.headers.get("Authorization");
44
+ const contentType = request.headers.get("Content-Type");
45
+ const accept = request.headers.get("Accept");
46
+ if (authorization) headers.set("Authorization", authorization);
47
+ if (contentType) headers.set("Content-Type", contentType);
48
+ if (accept) headers.set("Accept", accept);
49
+ const body = await request.arrayBuffer();
50
+ const upstream = await fetch(targetUrl, {
51
+ method: "POST",
52
+ headers,
53
+ body
54
+ });
55
+ return withCors(
56
+ new Response(upstream.body, {
57
+ status: upstream.status,
58
+ headers: {
59
+ "Content-Type": upstream.headers.get("Content-Type") ?? "application/json"
60
+ }
61
+ })
62
+ );
63
+ }
64
+ async function matchAnalyticsWellKnown(request) {
65
+ const path = stripTrailingSlash(new URL(request.url).pathname);
66
+ if (path === WELL_KNOWN_ANALYTICS_SCRIPT_PATH) {
67
+ if (request.method !== "GET" && request.method !== "HEAD") {
68
+ return new Response(null, { status: 405 });
69
+ }
70
+ return Response.redirect(DEFAULT_SCRIPT_URL, 302);
71
+ }
72
+ if (path === WELL_KNOWN_COLLECT_PATH) {
73
+ return proxyCollect(request, DEFAULT_COLLECT_URL);
74
+ }
75
+ if (path === WELL_KNOWN_COLLECT_EVENTS_PATH) {
76
+ return proxyCollect(request, `${DEFAULT_COLLECT_URL}/v0/events`);
77
+ }
78
+ return null;
79
+ }
80
+
81
+ // src/analytics/index.ts
82
+ var GLOBAL_NAME = "CavunoAnalytics";
83
+ var installed = null;
84
+ function getRoot() {
85
+ return globalThis;
86
+ }
87
+ function normalizeCollectUrl(url) {
88
+ return url.replace(/\/+$/, "");
89
+ }
90
+ function resolveDefaultCollectUrl() {
91
+ return DEFAULT_COLLECT_URL;
92
+ }
93
+ function resolveDefaultScriptUrl() {
94
+ return DEFAULT_SCRIPT_URL;
95
+ }
96
+ function postCollectJson(state, action, payload) {
97
+ const body = JSON.stringify({
98
+ publishableKey: state.publishableKey,
99
+ action,
100
+ payload: payload ?? {}
101
+ });
102
+ void fetch(state.collectUrl, {
103
+ method: "POST",
104
+ headers: {
105
+ Authorization: `Bearer ${state.publishableKey}`,
106
+ "Content-Type": "application/json",
107
+ Accept: "application/json"
108
+ },
109
+ body,
110
+ keepalive: true
111
+ }).catch(() => {
112
+ });
113
+ }
114
+ function exposeGlobal(state) {
115
+ const root = getRoot();
116
+ root[GLOBAL_NAME] = {
117
+ trackEvent(action, payload) {
118
+ postCollectJson(state, action, payload);
119
+ }
120
+ };
121
+ }
122
+ function injectScript(state, scriptUrl) {
123
+ const doc = getRoot().document;
124
+ if (!doc?.createElement) {
125
+ return;
126
+ }
127
+ if (doc.querySelector?.(`script[data-cavuno-analytics="1"]`)) {
128
+ return;
129
+ }
130
+ const el = doc.createElement("script");
131
+ el.defer = true;
132
+ el.src = scriptUrl;
133
+ el.setAttribute("data-cavuno-analytics", "1");
134
+ el.setAttribute("data-token", state.publishableKey);
135
+ el.setAttribute("data-host", state.collectUrl);
136
+ el.setAttribute("data-tenant-id", PENDING_TENANT_ID);
137
+ el.setAttribute("data-web-vitals", "true");
138
+ const head = doc.head;
139
+ if (head?.appendChild) {
140
+ head.appendChild(el);
141
+ return;
142
+ }
143
+ const first = doc.getElementsByTagName("script")[0];
144
+ first?.parentNode?.insertBefore(el, first);
145
+ }
146
+ function install(options) {
147
+ const publishableKey = options.publishableKey.trim();
148
+ if (!publishableKey.startsWith("pk_")) {
149
+ throw new Error("analytics.install requires a publishable key (pk_\u2026)");
150
+ }
151
+ const collectUrl = normalizeCollectUrl(
152
+ (options.collectUrl ?? resolveDefaultCollectUrl()).trim() || resolveDefaultCollectUrl()
153
+ );
154
+ const scriptUrl = (options.scriptUrl ?? resolveDefaultScriptUrl()).trim() || resolveDefaultScriptUrl();
155
+ installed = { publishableKey, collectUrl };
156
+ exposeGlobal(installed);
157
+ injectScript(installed, scriptUrl);
158
+ }
159
+ function track(action, payload) {
160
+ const trimmed = action.trim();
161
+ if (!trimmed) {
162
+ return;
163
+ }
164
+ const root = getRoot();
165
+ const globalTrack = root[GLOBAL_NAME]?.trackEvent;
166
+ if (typeof globalTrack === "function" && installed) {
167
+ globalTrack(trimmed, payload);
168
+ return;
169
+ }
170
+ if (!installed) {
171
+ return;
172
+ }
173
+ postCollectJson(installed, trimmed, payload);
174
+ }
175
+ var analytics = {
176
+ install,
177
+ track,
178
+ matchAnalyticsWellKnown,
179
+ DEFAULT_COLLECT_URL,
180
+ DEFAULT_SCRIPT_URL,
181
+ PENDING_TENANT_ID,
182
+ WELL_KNOWN_ANALYTICS_SCRIPT_PATH,
183
+ WELL_KNOWN_SCRIPT_PATH,
184
+ WELL_KNOWN_COLLECT_PATH,
185
+ WELL_KNOWN_COLLECT_EVENTS_PATH
186
+ };
187
+ export {
188
+ DEFAULT_COLLECT_URL,
189
+ DEFAULT_SCRIPT_URL,
190
+ PENDING_TENANT_ID,
191
+ WELL_KNOWN_ANALYTICS_SCRIPT_PATH,
192
+ WELL_KNOWN_COLLECT_EVENTS_PATH,
193
+ WELL_KNOWN_COLLECT_PATH,
194
+ WELL_KNOWN_SCRIPT_PATH,
195
+ analytics,
196
+ install,
197
+ matchAnalyticsWellKnown,
198
+ track
199
+ };