|
1 |
| -<<<<<<< HEAD |
2 |
| -<<<<<<< HEAD |
3 | 1 | import { Logger as ILogger } from '@amplitude/analytics-types';
|
4 |
| -======= |
5 |
| -import { Logger as ILogger, SpecialEventType } from '@amplitude/analytics-types'; |
6 |
| ->>>>>>> 3e83ab49 (feat(session replay): add ability to target on multiple events) |
7 |
| -======= |
8 |
| -import { Logger as ILogger } from '@amplitude/analytics-types'; |
9 |
| ->>>>>>> 79705348 (test(targeting + session replay): get test coverage up to 100%) |
10 | 2 | import { DBSchema, IDBPDatabase, IDBPTransaction, openDB } from 'idb';
|
11 | 3 |
|
12 | 4 | export const MAX_IDB_STORAGE_LENGTH = 1000 * 60 * 60 * 24 * 2; // 2 days
|
13 | 5 |
|
14 |
| -<<<<<<< HEAD |
15 |
| -<<<<<<< HEAD |
16 |
| -======= |
17 |
| ->>>>>>> 7ea29d5c (fix(targeting): keep track of open db instances and ensure deduplication of events) |
18 | 6 | // This type is constructed to allow for future proofing - in the future we may want
|
19 | 7 | // to track how many of each event is fired, and we may want to track event properties
|
20 | 8 | // Any further fields, like event properties, can be added to this type without causing
|
21 | 9 | // a breaking change
|
22 | 10 | type EventData = { event_type: string };
|
23 | 11 |
|
24 | 12 | type EventTypeStore = { [event_type: string]: { [timestamp: number]: EventData } };
|
25 |
| -<<<<<<< HEAD |
26 |
| -======= |
27 |
| ->>>>>>> 3e83ab49 (feat(session replay): add ability to target on multiple events) |
28 |
| -======= |
29 |
| ->>>>>>> 7ea29d5c (fix(targeting): keep track of open db instances and ensure deduplication of events) |
30 | 13 | export interface TargetingDB extends DBSchema {
|
31 | 14 | eventTypesForSession: {
|
32 | 15 | key: number;
|
33 | 16 | value: {
|
34 | 17 | sessionId: number;
|
35 |
| -<<<<<<< HEAD |
36 |
| -<<<<<<< HEAD |
37 |
| -<<<<<<< HEAD |
38 |
| - eventTypes: EventTypeStore; |
39 |
| -======= |
40 |
| - eventTypes: Set<string>; |
41 |
| ->>>>>>> 3e83ab49 (feat(session replay): add ability to target on multiple events) |
42 |
| -======= |
43 |
| - eventTypes: Array<{ event_type: string }>; |
44 |
| ->>>>>>> 79705348 (test(targeting + session replay): get test coverage up to 100%) |
45 |
| -======= |
46 | 18 | eventTypes: EventTypeStore;
|
47 |
| ->>>>>>> 7ea29d5c (fix(targeting): keep track of open db instances and ensure deduplication of events) |
48 | 19 | };
|
49 | 20 | };
|
50 | 21 | }
|
51 | 22 |
|
52 |
| -<<<<<<< HEAD |
53 |
| -<<<<<<< HEAD |
54 | 23 | export class TargetingIDBStore {
|
55 | 24 | dbs: { [apiKey: string]: IDBPDatabase<TargetingDB> } = {};
|
56 | 25 |
|
@@ -177,155 +146,3 @@ export class TargetingIDBStore {
|
177 | 146 | }
|
178 | 147 |
|
179 | 148 | export const targetingIDBStore = new TargetingIDBStore();
|
180 |
| -======= |
181 |
| -export const createStore = async (dbName: string) => { |
182 |
| - return await openDB<TargetingDB>(dbName, 1, { |
183 |
| - upgrade: (db: IDBPDatabase<TargetingDB>) => { |
184 |
| - if (!db.objectStoreNames.contains('eventTypesForSession')) { |
185 |
| - db.createObjectStore('eventTypesForSession', { |
186 |
| - keyPath: 'sessionId', |
187 |
| - }); |
188 |
| - } |
189 |
| - }, |
190 |
| - }); |
191 |
| -}; |
192 |
| -======= |
193 |
| -export class TargetingIDBStore { |
194 |
| - dbs: { [apiKey: string]: IDBPDatabase<TargetingDB> } | undefined; |
195 |
| ->>>>>>> 7ea29d5c (fix(targeting): keep track of open db instances and ensure deduplication of events) |
196 |
| - |
197 |
| - createStore = async (dbName: string) => { |
198 |
| - return await openDB<TargetingDB>(dbName, 1, { |
199 |
| - upgrade: (db: IDBPDatabase<TargetingDB>) => { |
200 |
| - if (!db.objectStoreNames.contains('eventTypesForSession')) { |
201 |
| - db.createObjectStore('eventTypesForSession', { |
202 |
| - keyPath: 'sessionId', |
203 |
| - }); |
204 |
| - } |
205 |
| - }, |
206 |
| - }); |
207 |
| - }; |
208 |
| - |
209 |
| - openOrCreateDB = async (apiKey: string) => { |
210 |
| - if (this.dbs && this.dbs[apiKey]) { |
211 |
| - return this.dbs[apiKey]; |
212 |
| - } |
213 |
| - const dbName = `${apiKey.substring(0, 10)}_amp_targeting`; |
214 |
| - const db = await this.createStore(dbName); |
215 |
| - this.dbs = { |
216 |
| - ...this.dbs, |
217 |
| - [apiKey]: db, |
218 |
| - }; |
219 |
| - return db; |
220 |
| - }; |
221 |
| - |
222 |
| - updateEventListForSession = async ({ |
223 |
| - sessionId, |
224 |
| - eventType, |
225 |
| - eventTime, |
226 |
| - loggerProvider, |
227 |
| - tx, |
228 |
| - }: { |
229 |
| - sessionId: number; |
230 |
| - eventType: string; |
231 |
| - eventTime: number; |
232 |
| - loggerProvider: ILogger; |
233 |
| - tx: IDBPTransaction<TargetingDB, ['eventTypesForSession'], 'readwrite'>; |
234 |
| - }) => { |
235 |
| - try { |
236 |
| - const eventTypesForSessionStorage = await tx.store.get(sessionId); |
237 |
| - const eventTypesForSession = eventTypesForSessionStorage ? eventTypesForSessionStorage.eventTypes : {}; |
238 |
| - const eventTypeStore = eventTypesForSession[eventType] || {}; |
239 |
| - |
240 |
| - const updatedEventTypes: EventTypeStore = { |
241 |
| - ...eventTypesForSession, |
242 |
| - [eventType]: { |
243 |
| - ...eventTypeStore, |
244 |
| - [eventTime]: { event_type: eventType }, |
245 |
| - }, |
246 |
| - }; |
247 |
| - await tx.store.put({ sessionId, eventTypes: updatedEventTypes }); |
248 |
| - return updatedEventTypes; |
249 |
| - } catch (e) { |
250 |
| - loggerProvider.warn(`Failed to store events for targeting ${sessionId}: ${e as string}`); |
251 |
| - } |
252 |
| - return undefined; |
253 |
| - }; |
254 |
| - |
255 |
| - deleteOldSessionEventTypes = async ({ |
256 |
| - currentSessionId, |
257 |
| - loggerProvider, |
258 |
| - tx, |
259 |
| - }: { |
260 |
| - currentSessionId: number; |
261 |
| - loggerProvider: ILogger; |
262 |
| - tx: IDBPTransaction<TargetingDB, ['eventTypesForSession'], 'readwrite'>; |
263 |
| - }) => { |
264 |
| - try { |
265 |
| - const allEventTypeObjs = await tx.store.getAll(); |
266 |
| - for (let i = 0; i < allEventTypeObjs.length; i++) { |
267 |
| - const eventTypeObj = allEventTypeObjs[i]; |
268 |
| - const amountOfTimeSinceSession = Date.now() - eventTypeObj.sessionId; |
269 |
| - if (eventTypeObj.sessionId !== currentSessionId && amountOfTimeSinceSession > MAX_IDB_STORAGE_LENGTH) { |
270 |
| - await tx.store.delete(eventTypeObj.sessionId); |
271 |
| - } |
272 |
| - } |
273 |
| - } catch (e) { |
274 |
| - loggerProvider.warn(`Failed to clear old session events for targeting: ${e as string}`); |
275 |
| - } |
276 |
| - }; |
277 |
| - |
278 |
| - storeEventTypeForSession = async ({ |
279 |
| - loggerProvider, |
280 |
| - sessionId, |
281 |
| - eventType, |
282 |
| - eventTime, |
283 |
| - apiKey, |
284 |
| - }: { |
285 |
| - loggerProvider: ILogger; |
286 |
| - apiKey: string; |
287 |
| - eventType: string; |
288 |
| - eventTime: number; |
289 |
| - sessionId: number; |
290 |
| - }) => { |
291 |
| - try { |
292 |
| - const db = await this.openOrCreateDB(apiKey); |
293 |
| - |
294 |
| - const tx = db.transaction<'eventTypesForSession', 'readwrite'>('eventTypesForSession', 'readwrite'); |
295 |
| - if (!tx) { |
296 |
| - return; |
297 |
| - } |
298 |
| - |
299 |
| -<<<<<<< HEAD |
300 |
| - return updatedEventTypes; |
301 |
| - } catch (e) { |
302 |
| - loggerProvider.warn(`Failed to store events for targeting ${sessionId}: ${e as string}`); |
303 |
| - } |
304 |
| - return undefined; |
305 |
| -}; |
306 |
| ->>>>>>> 3e83ab49 (feat(session replay): add ability to target on multiple events) |
307 |
| -======= |
308 |
| - // Update the list of events for the session |
309 |
| - const updatedEventTypes = await this.updateEventListForSession({ |
310 |
| - sessionId, |
311 |
| - tx, |
312 |
| - loggerProvider, |
313 |
| - eventType, |
314 |
| - eventTime, |
315 |
| - }); |
316 |
| - |
317 |
| - // Clear out sessions older than 2 days |
318 |
| - await this.deleteOldSessionEventTypes({ currentSessionId: sessionId, tx, loggerProvider }); |
319 |
| - |
320 |
| - await tx.done; |
321 |
| - |
322 |
| - return updatedEventTypes; |
323 |
| - } catch (e) { |
324 |
| - loggerProvider.warn(`Failed to store events for targeting ${sessionId}: ${e as string}`); |
325 |
| - } |
326 |
| - return undefined; |
327 |
| - }; |
328 |
| -} |
329 |
| - |
330 |
| -export const targetingIDBStore = new TargetingIDBStore(); |
331 |
| ->>>>>>> 7ea29d5c (fix(targeting): keep track of open db instances and ensure deduplication of events) |
0 commit comments