import { LocalEvent } from "../../commons/types/local-event"; import { EventEmitter } from "../../commons/utils/event-emitter"; import { Http } from "../../commons/utils/http"; import { Event } from "../../event/core/event"; import { PageCartEvent } from "../../event/types/page/cart"; import { OrderProduct, PageConfirmationEvent } from "../../event/types/page/confirmation"; import { PageHomeEvent } from "../../event/types/page/home"; import { SessionUserEvent } from "../../event/types/session/user"; import { CartProduct } from "../types/base/cart-event"; /** * Error thrown whenever the user tries to send a * closed batch request. * * @class BatchAlreadyClosedError * @extends {Error} */ export class BatchAlreadyClosedError extends Error { /** * Creates an instance of BatchAlreadyClosedError. * * @memberof BatchAlreadyClosedError */ constructor() { super("Batch request already closed."); } } /** * A Batch event builder. * * Use this class to send multiple events at once, * without opening unnecessary requests. The batch * can only be sent once. * * @export * @class BatchEventBuilder */ export class BatchEventBuilder { /** * Start a new batch. * * @static * @return {BatchEventBuilder} * @memberof BatchEventBuilder */ public static start(): BatchEventBuilder { return new BatchEventBuilder(); } public events: Event[] = []; private closed = false; /** * Push all events to the server. This method can * only be called once pper batch, otherwise a * `BatchAlreadyClosedError` will be thrown. * * @return {Promise} * @memberof BatchEventBuilder */ public async push(): Promise { if (this.closed) { throw new BatchAlreadyClosedError(); } this.closed = true; EventEmitter.trigger(LocalEvent.EventBatch, this); return Http.post( `${window._RecSys.Bundle.Properties.event.url}/${window._RecSys.Bundle.Configuration.store.slug}/${window._RecSys.Bundle.Properties.event.endpoint.event}`, this, ); } /** * Append a generic Event to the batch request. * * @param {Event} event Event to be appended. * @return {BatchEventBuilder} * @memberof BatchEventBuilder */ public withEvent(event: Event): BatchEventBuilder { this.events.push(event); return this; } /** * Append an Order Confirmation Event. * * @param {string} orderId Order's ID. * @param {OrderProduct[]} [products=[]] Products bought. * @return {BatchEventBuilder} * @memberof BatchEventBuilder */ public withPageConfirmationEvent(orderId: string, products: OrderProduct[] = []): BatchEventBuilder { this.events.push(new PageConfirmationEvent(orderId).withProducts(products)); return this; } /** * Append a Cart Pageview Event. * * @param {CartProduct[]} [products=[]] Product's inside the cart. * @return {BatchEventBuilder} * @memberof BatchEventBuilder */ public withCartPageviewEvent(products: CartProduct[] = []): BatchEventBuilder { this.events.push(new PageCartEvent().withProducts(products)); return this; } /** * Append a Home Pageview Event. * * @return {BatchEventBuilder} * @memberof BatchEventBuilder */ public withHomePageViewEvent(): BatchEventBuilder { this.events.push(new PageHomeEvent()); return this; } /** * Append a User Login Event. * * @param {string} email User's email. * @param {boolean} [allowMailMarketing=true] Wheter mail sould be sent to this user. * @return {BatchEventBuilder} * @memberof BatchEventBuilder */ public withUserLoginEvent(email: string, allowMailMarketing = true): BatchEventBuilder { this.events.push(new SessionUserEvent(email, allowMailMarketing)); return this; } }