@uniformdev/insights 20.7.1-alpha.102

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.
@@ -0,0 +1,757 @@
1
+ import {
2
+ BackendInsightsProxyHandler,
3
+ createBackendInsightsProxyHandler
4
+ } from "./chunk-FFLO523H.mjs";
5
+
6
+ // src/batching.ts
7
+ import pLimit from "p-limit";
8
+ var DEFAULT_BATCH_CONFIG = {
9
+ maxBatchSize: 50,
10
+ maxBatchDelayMs: 2e3,
11
+ maxPayloadSizeBytes: 1024 * 1024,
12
+ // 1MB
13
+ maxRequestsPerSecond: 1
14
+ };
15
+ var createEventHash = (action, pageViewId, payload) => {
16
+ const payloadStr = JSON.stringify(payload);
17
+ return `${action}:${pageViewId}:${payloadStr}`;
18
+ };
19
+ var isDuplicateEvent = (deduplicationMap, hash, deduplicationWindowMs = 5 * 60 * 1e3) => {
20
+ const now = Date.now();
21
+ const existing = deduplicationMap.get(hash);
22
+ if (existing && now - existing.timestamp < deduplicationWindowMs) {
23
+ return true;
24
+ }
25
+ for (const [key, entry] of deduplicationMap.entries()) {
26
+ if (now - entry.timestamp >= deduplicationWindowMs) {
27
+ deduplicationMap.delete(key);
28
+ }
29
+ }
30
+ deduplicationMap.set(hash, { timestamp: now, hash });
31
+ return false;
32
+ };
33
+ var getEventPriority = (action) => {
34
+ switch (action) {
35
+ case "session_start":
36
+ return 3;
37
+ // Highest priority, as session start has to be the first for correct attribution in Insights
38
+ case "page_hit":
39
+ return 2;
40
+ // Medium priority, has to come right after session start for correct attribution in Insights
41
+ default:
42
+ return 1;
43
+ }
44
+ };
45
+ var sortEventsByPriority = (events) => {
46
+ return events.sort((a, b) => {
47
+ if (b.priority !== a.priority) {
48
+ return b.priority - a.priority;
49
+ }
50
+ return a.timestamp - b.timestamp;
51
+ });
52
+ };
53
+ var adjustTimestampsForOrder = (events) => {
54
+ const sortedEvents = sortEventsByPriority(events);
55
+ const baseTime = Date.now();
56
+ const timeIncrement = 100;
57
+ return sortedEvents.map((event, index) => ({
58
+ ...event.message,
59
+ timestamp: new Date(baseTime + index * timeIncrement).toISOString()
60
+ }));
61
+ };
62
+ var buildEndpointUrl = (endpoint) => {
63
+ if (endpoint.type === "api") {
64
+ const url = new URL(endpoint.host);
65
+ url.pathname = `/v0/events`;
66
+ if (endpoint.host.includes("tinybird.co")) {
67
+ url.pathname = "/v0/events";
68
+ }
69
+ url.searchParams.set("name", "events");
70
+ return url.toString();
71
+ } else {
72
+ return endpoint.path;
73
+ }
74
+ };
75
+ var sendBatchToEndpoint = async (messages, endpoint) => {
76
+ const endpointUrl = buildEndpointUrl(endpoint);
77
+ const ndjson = messages.map((msg) => JSON.stringify(msg)).join("\n");
78
+ const headers = {
79
+ "Content-Type": "application/x-ndjson"
80
+ };
81
+ if (endpoint.type === "api" && endpoint.apiKey) {
82
+ headers.Authorization = `Bearer ${endpoint.apiKey}`;
83
+ }
84
+ const response = await fetch(endpointUrl, {
85
+ method: "POST",
86
+ headers,
87
+ body: ndjson
88
+ });
89
+ if (!response.ok) {
90
+ throw new Error(`Failed to send batch: ${response.statusText}`);
91
+ }
92
+ const json = await response.json();
93
+ return json;
94
+ };
95
+ var createBatchProcessor = (config, endpoint) => {
96
+ let eventQueue = [];
97
+ let batchTimeout = null;
98
+ const limit = pLimit(config.maxRequestsPerSecond);
99
+ const processBatch = async () => {
100
+ if (eventQueue.length === 0) return;
101
+ const messages = adjustTimestampsForOrder(eventQueue);
102
+ const batches = [];
103
+ let currentBatch = [];
104
+ let currentBatchSize = 0;
105
+ for (const message of messages) {
106
+ const messageSize = JSON.stringify(message).length;
107
+ if (currentBatch.length >= config.maxBatchSize || currentBatchSize + messageSize > config.maxPayloadSizeBytes) {
108
+ if (currentBatch.length > 0) {
109
+ batches.push(currentBatch);
110
+ }
111
+ currentBatch = [message];
112
+ currentBatchSize = messageSize;
113
+ } else {
114
+ currentBatch.push(message);
115
+ currentBatchSize += messageSize;
116
+ }
117
+ }
118
+ if (currentBatch.length > 0) {
119
+ batches.push(currentBatch);
120
+ }
121
+ const sendPromises = batches.map(
122
+ (batch) => limit(async () => {
123
+ try {
124
+ await sendBatchToEndpoint(batch, endpoint);
125
+ } catch (error) {
126
+ console.warn("Failed to send batch:", error);
127
+ }
128
+ })
129
+ );
130
+ await Promise.all(sendPromises);
131
+ eventQueue = [];
132
+ batchTimeout = null;
133
+ };
134
+ const scheduleBatch = () => {
135
+ if (batchTimeout) return;
136
+ batchTimeout = setTimeout(() => {
137
+ processBatch();
138
+ }, config.maxBatchDelayMs);
139
+ };
140
+ const addEvent = (message) => {
141
+ const priority = getEventPriority(message.action);
142
+ const timestamp = new Date(message.timestamp).getTime();
143
+ eventQueue.push({ message, priority, timestamp });
144
+ if (eventQueue.length >= config.maxBatchSize) {
145
+ if (batchTimeout) {
146
+ clearTimeout(batchTimeout);
147
+ batchTimeout = null;
148
+ }
149
+ processBatch();
150
+ } else {
151
+ scheduleBatch();
152
+ }
153
+ };
154
+ const flush = () => {
155
+ if (batchTimeout) {
156
+ clearTimeout(batchTimeout);
157
+ batchTimeout = null;
158
+ }
159
+ processBatch();
160
+ };
161
+ const clear = () => {
162
+ if (batchTimeout) {
163
+ clearTimeout(batchTimeout);
164
+ batchTimeout = null;
165
+ }
166
+ eventQueue = [];
167
+ };
168
+ return { addEvent, flush, clear };
169
+ };
170
+ var createDeduplicationManager = () => {
171
+ const deduplicationMap = /* @__PURE__ */ new Map();
172
+ return {
173
+ isDuplicate: (message) => {
174
+ const hash = createEventHash(message.action, message.page_view_id, message.payload);
175
+ return isDuplicateEvent(deduplicationMap, hash);
176
+ },
177
+ clear: () => {
178
+ deduplicationMap.clear();
179
+ }
180
+ };
181
+ };
182
+
183
+ // src/utils.ts
184
+ var getWebMetadata = () => {
185
+ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
186
+ const locale = navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || "en";
187
+ return {
188
+ "user-agent": window.navigator.userAgent,
189
+ locale,
190
+ location: timeZone,
191
+ referrer: document.referrer,
192
+ pathname: window.location.pathname,
193
+ href: window.location.href
194
+ };
195
+ };
196
+ var generateVisitorId = async () => {
197
+ return `visitor_${generalRandomId()}`;
198
+ };
199
+ var generateSessionId = async () => {
200
+ return `session_${generalRandomId()}`;
201
+ };
202
+ var generatePageId = () => {
203
+ return `page_${generalRandomId()}`;
204
+ };
205
+ var generalRandomId = () => {
206
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
207
+ const id = crypto.randomUUID();
208
+ return id.replaceAll("-", "").toLowerCase();
209
+ }
210
+ return Math.random().toString(32).substring(2);
211
+ };
212
+ var convertUniformMetadataToInsightsMetadata = (uniformMetadata) => {
213
+ return uniformMetadata ? {
214
+ composition_id: uniformMetadata.compositionId,
215
+ pm_node_path: uniformMetadata.matchedRoute,
216
+ dynamic_inputs: uniformMetadata.dynamicInputs
217
+ } : void 0;
218
+ };
219
+
220
+ // src/events/enrichment.ts
221
+ var buildEnrichmentUpdatedMessage = ({
222
+ sessionId,
223
+ visitorId,
224
+ pageId,
225
+ projectId,
226
+ enrichmentId,
227
+ key,
228
+ strength,
229
+ compositionData
230
+ }) => ({
231
+ action: "enrichment_updated",
232
+ version: "2",
233
+ session_id: sessionId,
234
+ visitor_id: visitorId,
235
+ page_view_id: pageId,
236
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
237
+ project_id: projectId,
238
+ payload: {
239
+ id: enrichmentId,
240
+ key,
241
+ strength
242
+ },
243
+ web_metadata: getWebMetadata(),
244
+ uniform: compositionData || {}
245
+ });
246
+
247
+ // src/events/goal.ts
248
+ var buildGoalConvertMessage = (sessionId, visitorId, pageId, projectId, goalId, compositionData) => ({
249
+ action: "goal_convert",
250
+ version: "2",
251
+ session_id: sessionId,
252
+ visitor_id: visitorId,
253
+ page_view_id: pageId,
254
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
255
+ project_id: projectId,
256
+ payload: {
257
+ goal_id: goalId
258
+ },
259
+ web_metadata: getWebMetadata(),
260
+ uniform: compositionData || {}
261
+ });
262
+
263
+ // src/events/page.ts
264
+ var buildPageHitMessage = (sessionId, visitorId, pageId, projectId, compositionData) => ({
265
+ action: "page_hit",
266
+ version: "2",
267
+ session_id: sessionId,
268
+ visitor_id: visitorId,
269
+ page_view_id: pageId,
270
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
271
+ project_id: projectId,
272
+ payload: {},
273
+ web_metadata: getWebMetadata(),
274
+ uniform: compositionData || {}
275
+ });
276
+
277
+ // src/events/personalization.ts
278
+ var buildPersonalizationResultMessage = (sessionId, visitorId, pageId, projectId, result, variant, compositionData) => ({
279
+ action: "personalization_result",
280
+ version: "2",
281
+ session_id: sessionId,
282
+ visitor_id: visitorId,
283
+ page_view_id: pageId,
284
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
285
+ project_id: projectId,
286
+ payload: {
287
+ name: result.name,
288
+ variantId: variant.id,
289
+ control: variant.control || result.control,
290
+ changed: result.changed
291
+ },
292
+ web_metadata: getWebMetadata(),
293
+ uniform: compositionData || {}
294
+ });
295
+
296
+ // src/events/segment.ts
297
+ var buildSegmentUpdatedMessage = ({
298
+ sessionId,
299
+ visitorId,
300
+ pageId,
301
+ projectId,
302
+ segmentId,
303
+ value,
304
+ compositionData
305
+ }) => ({
306
+ action: "segment_updated",
307
+ version: "2",
308
+ session_id: sessionId,
309
+ visitor_id: visitorId,
310
+ page_view_id: pageId,
311
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
312
+ project_id: projectId,
313
+ payload: {
314
+ id: segmentId,
315
+ value
316
+ },
317
+ web_metadata: getWebMetadata(),
318
+ uniform: compositionData || {}
319
+ });
320
+
321
+ // src/events/session.ts
322
+ var buildSessionStartMessage = (sessionId, visitorId, pageId, projectId, previousSessionId, compositionData) => ({
323
+ action: "session_start",
324
+ version: "2",
325
+ session_id: sessionId,
326
+ visitor_id: visitorId,
327
+ page_view_id: pageId,
328
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
329
+ project_id: projectId,
330
+ payload: {
331
+ previous_session_id: previousSessionId
332
+ },
333
+ web_metadata: getWebMetadata(),
334
+ uniform: compositionData || {}
335
+ });
336
+
337
+ // src/events/test.ts
338
+ var buildTestResultMessage = (sessionId, visitorId, pageId, projectId, result, compositionData) => ({
339
+ action: "test_result",
340
+ version: "2",
341
+ session_id: sessionId,
342
+ visitor_id: visitorId,
343
+ page_view_id: pageId,
344
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
345
+ project_id: projectId,
346
+ payload: {
347
+ name: result.name,
348
+ variantId: result.variantId,
349
+ control: result.control,
350
+ variantAssigned: result.variantAssigned
351
+ },
352
+ web_metadata: getWebMetadata(),
353
+ uniform: compositionData || {}
354
+ });
355
+
356
+ // src/storage.ts
357
+ var createInsightsStorage = (customStorage) => {
358
+ if (customStorage) {
359
+ return customStorage;
360
+ }
361
+ const STORAGE_KEY = "ufin";
362
+ return {
363
+ get: () => {
364
+ if (typeof localStorage === "undefined") {
365
+ return void 0;
366
+ }
367
+ const data = localStorage.getItem(STORAGE_KEY);
368
+ if (!data) {
369
+ return void 0;
370
+ }
371
+ try {
372
+ return JSON.parse(data);
373
+ } catch (e) {
374
+ return void 0;
375
+ }
376
+ },
377
+ set: (data) => {
378
+ if (typeof localStorage === "undefined") {
379
+ return;
380
+ }
381
+ const toSet = {
382
+ ...data,
383
+ updated: Date.now()
384
+ };
385
+ try {
386
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(toSet));
387
+ } catch (e) {
388
+ }
389
+ },
390
+ clear: () => {
391
+ if (typeof localStorage === "undefined") {
392
+ return;
393
+ }
394
+ try {
395
+ localStorage.removeItem(STORAGE_KEY);
396
+ } catch (e) {
397
+ }
398
+ }
399
+ };
400
+ };
401
+ var createMemoryStorage = () => {
402
+ let data;
403
+ return {
404
+ get: () => data,
405
+ set: (newData) => {
406
+ data = {
407
+ ...newData,
408
+ updated: Date.now()
409
+ };
410
+ },
411
+ clear: () => {
412
+ data = void 0;
413
+ }
414
+ };
415
+ };
416
+
417
+ // src/plugin.ts
418
+ var createInsightsCore = (options) => {
419
+ if (options.endpoint.type === "api" && !options.endpoint.host) {
420
+ throw new Error("Insights context plugin requires API host");
421
+ }
422
+ if (options.endpoint.type === "api" && !options.endpoint.apiKey) {
423
+ throw new Error("Insights context plugin requires API key");
424
+ }
425
+ if (!options.endpoint.projectId) {
426
+ throw new Error("Insights context plugin requires project ID");
427
+ }
428
+ const {
429
+ endpoint,
430
+ storage: customStorage,
431
+ batchConfig,
432
+ sessionDurationSeconds = 30 * 60,
433
+ getVisitorId = generateVisitorId,
434
+ getSessionId = generateSessionId
435
+ } = options;
436
+ const storage = createInsightsStorage(customStorage);
437
+ let storageData;
438
+ let pageId = generatePageId();
439
+ let previousUrl = void 0;
440
+ const batchProcessor = batchConfig ? createBatchProcessor({ ...DEFAULT_BATCH_CONFIG, ...batchConfig }, endpoint) : null;
441
+ const deduplicationManager = batchConfig ? createDeduplicationManager() : null;
442
+ const sendEventDirectly = async (message) => {
443
+ if (typeof window !== "undefined" && window.__UNIFORM_CONTEXTUAL_EDITING__) {
444
+ return;
445
+ }
446
+ try {
447
+ const endpointUrl = endpoint.type === "api" ? `${endpoint.host}/v0/events?name=events` : endpoint.path;
448
+ const headers = {
449
+ "Content-Type": "application/x-ndjson"
450
+ };
451
+ if (endpoint.type === "api" && endpoint.apiKey) {
452
+ headers.Authorization = `Bearer ${endpoint.apiKey}`;
453
+ }
454
+ await fetch(endpointUrl, {
455
+ method: "POST",
456
+ headers,
457
+ body: JSON.stringify(message)
458
+ });
459
+ } catch (error) {
460
+ console.warn("Failed to send event:", error);
461
+ }
462
+ };
463
+ const addEvent = (message) => {
464
+ if (typeof window !== "undefined" && window.__UNIFORM_CONTEXTUAL_EDITING__) {
465
+ return;
466
+ }
467
+ if (batchProcessor && deduplicationManager) {
468
+ if (!deduplicationManager.isDuplicate(message)) {
469
+ batchProcessor.addEvent(message);
470
+ }
471
+ } else {
472
+ sendEventDirectly(message);
473
+ }
474
+ };
475
+ return {
476
+ init: async (context) => {
477
+ storageData = storage.get();
478
+ if (!storageData || Date.now() - storageData.updated > sessionDurationSeconds * 1e3) {
479
+ const previousSessionId = storageData == null ? void 0 : storageData.sessionId;
480
+ let visitorId;
481
+ if (storageData == null ? void 0 : storageData.visitorId) {
482
+ visitorId = storageData.visitorId;
483
+ } else {
484
+ visitorId = await getVisitorId({
485
+ context,
486
+ previousVisitorId: storageData == null ? void 0 : storageData.visitorId,
487
+ previousSessionId
488
+ });
489
+ }
490
+ const sessionId = await getSessionId({ context, visitorId, previousSessionId });
491
+ const newStorageData = {
492
+ visitorId,
493
+ sessionId,
494
+ updated: Date.now()
495
+ };
496
+ storage.set(newStorageData);
497
+ storageData = newStorageData;
498
+ const message = buildSessionStartMessage(
499
+ storageData.sessionId,
500
+ storageData.visitorId,
501
+ pageId,
502
+ endpoint.projectId,
503
+ previousSessionId
504
+ );
505
+ addEvent(message);
506
+ } else if (storageData) {
507
+ storage.set(storageData);
508
+ }
509
+ },
510
+ pageHit: (compositionData) => {
511
+ if (!storageData) {
512
+ return;
513
+ }
514
+ if (typeof window !== "undefined" && previousUrl === window.location.href) {
515
+ return;
516
+ }
517
+ if (typeof window !== "undefined") {
518
+ previousUrl = window.location.href;
519
+ }
520
+ pageId = generatePageId();
521
+ const message = buildPageHitMessage(
522
+ storageData.sessionId,
523
+ storageData.visitorId,
524
+ pageId,
525
+ endpoint.projectId,
526
+ compositionData
527
+ );
528
+ addEvent(message);
529
+ },
530
+ testResult: (result, compositionData) => {
531
+ if (!storageData) {
532
+ return;
533
+ }
534
+ const message = buildTestResultMessage(
535
+ storageData.sessionId,
536
+ storageData.visitorId,
537
+ pageId,
538
+ endpoint.projectId,
539
+ result,
540
+ compositionData
541
+ );
542
+ addEvent(message);
543
+ },
544
+ personalizationResult: (result, compositionData) => {
545
+ if (!storageData) {
546
+ return;
547
+ }
548
+ result.variantIds.forEach((variant) => {
549
+ const message = buildPersonalizationResultMessage(
550
+ storageData.sessionId,
551
+ storageData.visitorId,
552
+ pageId,
553
+ endpoint.projectId,
554
+ result,
555
+ variant,
556
+ compositionData
557
+ );
558
+ addEvent(message);
559
+ });
560
+ },
561
+ goalConvert: (goalId, compositionData) => {
562
+ if (!storageData) {
563
+ return;
564
+ }
565
+ const message = buildGoalConvertMessage(
566
+ storageData.sessionId,
567
+ storageData.visitorId,
568
+ pageId,
569
+ endpoint.projectId,
570
+ goalId,
571
+ compositionData
572
+ );
573
+ addEvent(message);
574
+ },
575
+ segmentUpdated: (segmentId, value, compositionData) => {
576
+ if (!storageData) {
577
+ return;
578
+ }
579
+ const message = buildSegmentUpdatedMessage({
580
+ sessionId: storageData.sessionId,
581
+ visitorId: storageData.visitorId,
582
+ pageId,
583
+ projectId: endpoint.projectId,
584
+ segmentId,
585
+ value,
586
+ compositionData
587
+ });
588
+ addEvent(message);
589
+ },
590
+ enrichmentUpdated: (enrichmentId, key, strength, compositionData) => {
591
+ if (!storageData) {
592
+ return;
593
+ }
594
+ const message = buildEnrichmentUpdatedMessage({
595
+ sessionId: storageData.sessionId,
596
+ visitorId: storageData.visitorId,
597
+ pageId,
598
+ projectId: endpoint.projectId,
599
+ enrichmentId,
600
+ key,
601
+ strength,
602
+ compositionData
603
+ });
604
+ addEvent(message);
605
+ },
606
+ forget: () => {
607
+ storage.clear();
608
+ storageData = void 0;
609
+ deduplicationManager == null ? void 0 : deduplicationManager.clear();
610
+ batchProcessor == null ? void 0 : batchProcessor.flush();
611
+ },
612
+ get sessionId() {
613
+ return storageData == null ? void 0 : storageData.sessionId;
614
+ }
615
+ };
616
+ };
617
+ var createInsightsPlugin = (options) => {
618
+ const insights = createInsightsCore(options);
619
+ let previousUrl = void 0;
620
+ let isInitialized = false;
621
+ let eventQueue = [];
622
+ let contextInstance = void 0;
623
+ const processQueuedEvents = () => {
624
+ if (isInitialized && eventQueue.length > 0) {
625
+ eventQueue.forEach((event) => event());
626
+ eventQueue = [];
627
+ }
628
+ };
629
+ const queueEvent = (eventFn) => {
630
+ if (isInitialized) {
631
+ eventFn();
632
+ } else {
633
+ eventQueue.push(eventFn);
634
+ }
635
+ };
636
+ const previousScores = {};
637
+ const handleScoreUpdates = (updatedScores, compositionData) => {
638
+ if (!contextInstance) {
639
+ return;
640
+ }
641
+ Object.entries(updatedScores).forEach(([scoreKey, value]) => {
642
+ var _a, _b;
643
+ if (previousScores[scoreKey] === value) {
644
+ return;
645
+ }
646
+ const aggregateDimension = contextInstance.manifest.getAggregateDimensionByKey(scoreKey);
647
+ const signalDimension = (_b = (_a = contextInstance.manifest.data.project.pz) == null ? void 0 : _a.sig) == null ? void 0 : _b[scoreKey];
648
+ if (aggregateDimension || signalDimension) {
649
+ insights.segmentUpdated(scoreKey, value, compositionData);
650
+ previousScores[scoreKey] = value;
651
+ }
652
+ });
653
+ };
654
+ return {
655
+ init: (context) => {
656
+ if (typeof window === "undefined") {
657
+ return () => {
658
+ };
659
+ }
660
+ contextInstance = context;
661
+ const consentChanged = () => {
662
+ if (context.storage.data.consent) {
663
+ insights.init(context).then(() => {
664
+ isInitialized = true;
665
+ processQueuedEvents();
666
+ });
667
+ } else {
668
+ insights.forget();
669
+ isInitialized = false;
670
+ }
671
+ };
672
+ const handlePersonalizationResult = (data) => {
673
+ queueEvent(() => {
674
+ insights.personalizationResult(
675
+ data,
676
+ convertUniformMetadataToInsightsMetadata(data.compositionMetadata)
677
+ );
678
+ });
679
+ };
680
+ const handleTestResult = (result) => {
681
+ queueEvent(() => {
682
+ insights.testResult(result, convertUniformMetadataToInsightsMetadata(result.compositionMetadata));
683
+ });
684
+ };
685
+ const handleGoalConvert = (result) => {
686
+ const compositionMetadata = context.getCompositionMetadata();
687
+ queueEvent(() => {
688
+ insights.goalConvert(result.goalId, convertUniformMetadataToInsightsMetadata(compositionMetadata));
689
+ });
690
+ };
691
+ const handleCanvasDataUpdated = (data) => {
692
+ if (data) {
693
+ queueEvent(() => {
694
+ insights.pageHit(convertUniformMetadataToInsightsMetadata(data));
695
+ });
696
+ }
697
+ };
698
+ context.storage.events.on("goalConverted", handleGoalConvert);
699
+ context.storage.events.on("consentUpdated", consentChanged);
700
+ context.events.on("personalizationResult", handlePersonalizationResult);
701
+ context.events.on("testResult", handleTestResult);
702
+ context.events.on("canvasDataUpdated", handleCanvasDataUpdated);
703
+ if (context.storage.data.consent) {
704
+ consentChanged();
705
+ }
706
+ return () => {
707
+ context.storage.events.off("consentUpdated", consentChanged);
708
+ context.storage.events.off("goalConverted", handleGoalConvert);
709
+ context.events.off("personalizationResult", handlePersonalizationResult);
710
+ context.events.off("testResult", handleTestResult);
711
+ context.events.off("canvasDataUpdated", handleCanvasDataUpdated);
712
+ };
713
+ },
714
+ update: (updatedData, recalculatedScores) => {
715
+ var _a;
716
+ const compositionMetadata = convertUniformMetadataToInsightsMetadata(
717
+ (_a = updatedData.compositionMetadata) != null ? _a : contextInstance == null ? void 0 : contextInstance.getCompositionMetadata()
718
+ );
719
+ if (updatedData.url && updatedData.url.toString() !== previousUrl) {
720
+ previousUrl = updatedData.url.toString();
721
+ queueEvent(() => {
722
+ insights.pageHit(compositionMetadata);
723
+ });
724
+ }
725
+ if (updatedData.enrichments && updatedData.enrichments.length > 0) {
726
+ queueEvent(() => {
727
+ updatedData.enrichments.forEach((enrichmentData) => {
728
+ insights.enrichmentUpdated(
729
+ enrichmentData.cat,
730
+ enrichmentData.key,
731
+ enrichmentData.str,
732
+ compositionMetadata
733
+ );
734
+ });
735
+ });
736
+ }
737
+ if (recalculatedScores) {
738
+ queueEvent(() => {
739
+ handleScoreUpdates(recalculatedScores, compositionMetadata);
740
+ });
741
+ }
742
+ },
743
+ forget: () => {
744
+ insights.forget();
745
+ isInitialized = false;
746
+ eventQueue = [];
747
+ }
748
+ };
749
+ };
750
+ export {
751
+ BackendInsightsProxyHandler,
752
+ createBackendInsightsProxyHandler,
753
+ createInsightsPlugin,
754
+ createInsightsStorage,
755
+ createMemoryStorage,
756
+ createInsightsPlugin as enableUniformInsights
757
+ };