UNPKG

salsify-experiences-sdk

Version:

SDK to be used by commerce websites to implement product experiences.

81 lines (66 loc) 2.26 kB
import request from '../request' import SdkSettings from '../../settings' import { Context } from '../../api' import Timeout from '../timeout' const stagingBaseUrl = 'https://retail-client-events-service-staging.internal.salsify.com' const stagingEventsEndpoint = `${stagingBaseUrl}/events` const prodBaseUrl = 'https://retail-client-events-service.internal.salsify.com' const prodEventsEndpoint = `${prodBaseUrl}/events` interface Event { code: string properties: Record<string, unknown> timestamp: number } const MAX_QUEUE_SIZE = 1000 export default class LogTransport { #context: Context #settings: SdkSettings #eventsEndpoint: string #queuedEvents: Array<Event> = [] #timeout?: Timeout public constructor(context: Context, settings: SdkSettings) { this.#context = context this.#settings = settings this.#eventsEndpoint = this.#settings.staging ? stagingEventsEndpoint : prodEventsEndpoint } public log(code: string, properties: Record<string, unknown>, context: Record<string, unknown>): void { const event = { code: 'sdk_' + code, properties, context, timestamp: Date.now() / 1000, } this.#send([event]) } async #send(logs: Array<Event>): Promise<void> { const allLogs = [...this.#queuedEvents.splice(0), ...logs] if (!allLogs.length) return const payload = { app: 'sxp_sdk', channel: this.#context.clientId, csid: this.#context.sessionId, pagesessionid: this.#context.pageSessionId, jsSource: this.#context.jsSource, timestamp: Date.now() / 1000, logs: allLogs, } let response: Response try { response = await request.post(this.#eventsEndpoint, payload) } catch (e) { this.#enqueueAndStartTimeout(allLogs) return } if (response.ok) { this.#timeout?.clear() } else { this.#enqueueAndStartTimeout(allLogs) } } #enqueueAndStartTimeout(logs: Array<Event>): void { if (this.#queuedEvents.length >= MAX_QUEUE_SIZE) return this.#queuedEvents.push(...logs.splice(0, MAX_QUEUE_SIZE - this.#queuedEvents.length)) if (!this.#timeout) this.#timeout = new Timeout() this.#timeout.start(() => this.#send(this.#queuedEvents.splice(0))) } }