@segment/analytics-core
Version:
This package represents core 'shared' functionality that is shared by analytics packages. This is not designed to be used directly, but internal to analytics-node and analytics-browser.
59 lines (53 loc) • 1.7 kB
text/typescript
import { CoreContext } from '../context'
import { Callback } from '../events/interfaces'
import { CoreEventQueue } from '../queue/event-queue'
import { invokeCallback } from '../callback'
import { Emitter } from '@segment/analytics-generic-utils'
export type DispatchOptions<Ctx extends CoreContext = CoreContext> = {
timeout?: number
debug?: boolean
callback?: Callback<Ctx>
}
/* The amount of time in ms to wait before invoking the callback. */
export const getDelay = (startTimeInEpochMS: number, timeoutInMS?: number) => {
const elapsedTime = Date.now() - startTimeInEpochMS
// increasing the timeout increases the delay by almost the same amount -- this is weird legacy behavior.
return Math.max((timeoutInMS ?? 300) - elapsedTime, 0)
}
/**
* Push an event into the dispatch queue and invoke any callbacks.
*
* @param event - Segment event to enqueue.
* @param queue - Queue to dispatch against.
* @param emitter - This is typically an instance of "Analytics" -- used for metrics / progress information.
* @param options
*/
export async function dispatch<
Ctx extends CoreContext,
EQ extends CoreEventQueue<Ctx>
>(
ctx: Ctx,
queue: EQ,
emitter: Emitter,
options?: DispatchOptions<Ctx>
): Promise<Ctx> {
emitter.emit('dispatch_start', ctx)
const startTime = Date.now()
let dispatched: Ctx
if (queue.isEmpty()) {
dispatched = await queue.dispatchSingle(ctx)
} else {
dispatched = await queue.dispatch(ctx)
}
if (options?.callback) {
dispatched = await invokeCallback(
dispatched,
options.callback,
getDelay(startTime, options.timeout)
)
}
if (options?.debug) {
dispatched.flush()
}
return dispatched
}