1const DB_NAME = 'yaqeenInteraction' 2const DB_VERSION = 1 3const STORE_NAME = 'interactions' 4 5async function onSync(token) { 6 if (!token) { 7 console.error('No token found') 8 return 9 } 10 11 const interactions = await fetchWithToken(token) 12 13 if (interactions?.data?.length === 0) { 14 console.debug('No interactions found') 15 return 16 } 17 18 const openRequest = indexedDB.open(DB_NAME, DB_VERSION); 19 20 openRequest.onsuccess = (event) => { 21 const db = event.target.result; 22 const transaction = db.transaction(STORE_NAME, 'readwrite'); 23 const store = transaction.objectStore(STORE_NAME); 24 // clear the store 25 store.clear() 26 27 // populate the store 28 interactions.data.forEach((interaction) => { 29 store.add(interaction, interaction.object.id) 30 }) 31 32 console.debug('IndexedDB populated with', interactions.data.length, 'interactions') 33 }; 34 35 openRequest.onerror = (err) => { 36 console.error('Error opening IndexedDB:', err) 37 } 38} 39 40/** 41 * Returns a list of interactions to be deleted. We aim to keep only the recent 200 interactions. 42 * Refer to src/constants/x-api.ts for the definition of the interaction object. 43 * @typedef {Object} Interaction 44 * @property {string} id 45 * @property {Object} actor 46 * @property {string} actor.objectType 47 * @property {string} actor.name 48 * @property {Object} actor.account 49 * @property {string} actor.account.homePage 50 * @property {string} actor.account.name 51 * @property {Object} verb 52 * @property {string} verb.id 53 * @property {Object} verb.display 54 * @param {{ 55 * id: string, 56 * actor: { 57 * objectType: 'Agent', 58 * name?: string, 59 * account?: { 60 * homePage: string, 61 * name: string 62 * } 63 * }, 64 * verb: { 65 * id: string, 66 * display: { 67 * 'en-US': string 68 * } 69 * }, 70 * object: { 71 * id: string, 72 * objectType: 'Activity', 73 * definition: { 74 * name: { 75 * 'en-US': string 76 * }, 77 * description?: { 78 * 'en-US': string 79 * }, 80 * extensions: { 81 * 'http://yqn.io/extensions/post-type': string, 82 * 'http://yqn.io/extensions/post-title': string, 83 * 'http://yqn.io/extensions/post-thumbnail': string, 84 * 'http://yqn.io/extensions/post-authors': string[] 85 * } 86 * } 87 * }, 88 * result?: { 89 * score: { 90 * raw: number 91 * } 92 * }, 93 * timestamp: string, 94 * version: string 95 * }[]} data 96 * 97 * @returns string[] 98 */ 99function getDeletionList(data) { 100 const MAX_INTERACTIONS = 800 101 // sort by timestamp and retrieve only the last 800 interactions 102 const sortedData = data.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp)); 103 const trimmedData = sortedData.slice(0, MAX_INTERACTIONS); 104 105 // retrieve data that is not in the trimmed data 106 const remainingData = data.filter((interaction) => !trimmedData.some((t) => t.id === interaction.id)); 107 return remainingData.map((interaction) => interaction.id) 108} 109 110async function fetchWithToken(token) { 111 const response = await fetch('https://webhooks.yaqeeninstitute.org/web-api-dev/api/v1/interactions', { 112 headers: { 113 Authorization: token, 114 }, 115 }) 116 return response.json() 117} 118 119async function onLimit() { 120 const openRequest = indexedDB.open(DB_NAME, DB_VERSION); 121 122 openRequest.onsuccess = (event) => { 123 const db = event.target.result; 124 const transaction = db.transaction(STORE_NAME, 'readwrite'); 125 const store = transaction.objectStore(STORE_NAME); 126 const deletionList = getDeletionList(store.getAll()) 127 deletionList.forEach((id) => { 128 store.delete(id) 129 }) 130 131 console.debug('Deleted', deletionList.length, 'interactions') 132 }; 133 134 openRequest.onerror = (err) => { 135 console.error('Error opening IndexedDB:', err) 136 } 137} 138 139self.onmessage = async (event) => { 140 console.debug('Received message from main', event) 141 try { 142 const eventData = event.data 143 if (eventData.action === 'sync') { 144 onSync(eventData.token) 145 } 146 147 if (eventData.action === 'limit') { 148 onLimit() 149 } 150 } catch (e) { 151 console.error('Error starting interaction tracker', e) 152 } 153};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.