/** * Internal dependencies */ import { MAX_LAMBDA_PAYLOAD, getApiUrl } from '../utils/helpers'; import { getChunksBySize } from '../utils/helpers/get-chunks-by-size'; import type { Session } from '../types'; import type { StoredEvent } from '../utils/storage'; type EventChunk = ReadonlyArray< StoredEvent >; export async function sync( events: ReadonlyArray< StoredEvent >, session: Session ): Promise< ReadonlyArray< number > > { if ( ! events.length ) { return []; } //end if return track( events, session ); } //end sync() async function track( events: ReadonlyArray< StoredEvent >, session: Session ): Promise< ReadonlyArray< number > > { if ( session.isStagingSite ) { events.forEach( ( event ) => console.info( '[Staging] Event', JSON.stringify( event.event ) ) // eslint-disable-line ); return events.map( ( event ) => event.id ); } //end if const chunks = getChunksBySize< StoredEvent >( { input: [ ...events ], bytesSize: MAX_LAMBDA_PAYLOAD, sizeCalcFunction: ( item ) => JSON.stringify( item.event ).length, } ); const { api, site, id } = session; const url = getApiUrl( api, `/site/${ site }/session/${ id }`, { a: site, } ); const acknowledgedIds: number[] = []; for ( const chunk of chunks ) { const wasSent = await sendChunk( url, chunk ); if ( wasSent ) { acknowledgedIds.push( ...chunk.map( ( event ) => event.id ) ); } //end if } //end for return acknowledgedIds; } //end track() async function sendChunk( url: string, chunk: EventChunk ): Promise< boolean > { try { const response = await fetch( url, { method: 'POST', mode: 'cors', body: JSON.stringify( chunk.map( ( item ) => item.event ) ), headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', }, } ); return response.ok; } catch { return false; } }