logdb-client
Advanced tools
Comparing version 0.0.7 to 0.0.8
import * as axios from 'axios'; | ||
interface ClientOptions { | ||
name: string; | ||
url: string; | ||
token: string; | ||
listen?: string[]; | ||
} | ||
interface WriteEventBody { | ||
evt_type: string; | ||
payload: string; | ||
timestamp: number; | ||
} | ||
interface EventObject { | ||
id: number; | ||
evt_type: string; | ||
type: string; | ||
payload: string; | ||
timestamp: number; | ||
} | ||
interface EventObject { | ||
id: number; | ||
type: string; | ||
payload: string; | ||
timestamp: number; | ||
} | ||
interface EventContext { | ||
@@ -26,3 +37,3 @@ id: number; | ||
interface MessageHandlerInternalMap { | ||
event: EventHandlerFn; | ||
'*': EventHandlerFn; | ||
fail: FailEventHandlerFn; | ||
@@ -34,2 +45,5 @@ response: EventsReceivedHandlerFn; | ||
/** | ||
* LogDB class provides an interface for interacting with LogDB. | ||
*/ | ||
declare class LogDB { | ||
@@ -40,15 +54,88 @@ private handlers; | ||
lastEventId: number; | ||
/** | ||
* Creates an instance of LogDB. | ||
* @param {ClientOptions} options - The configuration options for the LogDB client. | ||
*/ | ||
constructor(options: ClientOptions); | ||
/** | ||
* Initializes the LogDB API client. | ||
* @private | ||
*/ | ||
private createApiClient; | ||
/** | ||
* Registers an event handler for a specific event type. | ||
* @private | ||
* @template Type | ||
* @param {Type} name - The name of the event handler. | ||
* @param {EventHandler<Type>} callback - The callback function to handle the event. | ||
*/ | ||
private registerHandler; | ||
/** | ||
* Adds an event handler for a specific event type. | ||
* @template Type | ||
* @param {Type} type - The type of the event to listen to. | ||
* @param {EventHandler<Type>} handler - The handler function for the event. | ||
*/ | ||
on<Type extends EventHandlerName>(type: Type, handler: EventHandler<Type>): void; | ||
emit(type: string, payload: unknown): Promise<axios.AxiosResponse<any, any>>; | ||
emitBulk(type: string, payload: unknown[]): Promise<axios.AxiosResponse<any, any>>; | ||
rawEmit(event: Omit<EventObject, 'id'>): Promise<axios.AxiosResponse<any, any>>; | ||
rawEmitBulk(events: Omit<EventObject, 'id'>[]): Promise<axios.AxiosResponse<any, any>>; | ||
fetchEvents(limit?: number): Promise<axios.AxiosResponse<EventObject[], any> | undefined>; | ||
writeEvents(events: Omit<EventObject, 'id'>[]): Promise<axios.AxiosResponse<any, any>>; | ||
/** | ||
* Sends a single event to the LogDB service. | ||
* @param {string} type - The event type. | ||
* @param {unknown} payload - The event payload. | ||
* @returns {Promise<void>} | ||
*/ | ||
sendEvent(type: string, payload: unknown): Promise<axios.AxiosResponse<any, any>>; | ||
/** | ||
* Sends multiple events to the LogDB service. | ||
* @param {string} type - The event type. | ||
* @param {unknown[]} payload - An array of event payloads. | ||
* @returns {Promise<void>} | ||
*/ | ||
sendBulk(type: string, payload: unknown[]): Promise<axios.AxiosResponse<any, any>>; | ||
/** | ||
* Sends a single raw event to the LogDB service. | ||
* @param {WriteEventBody} event - The event object to send. | ||
* @returns {Promise<void>} | ||
*/ | ||
sendRaw(event: WriteEventBody): Promise<axios.AxiosResponse<any, any>>; | ||
/** | ||
* Sends multiple raw events to the LogDB service. | ||
* @param {WriteEventBody[]} events - An array of event objects to send. | ||
* @returns {Promise<void>} | ||
*/ | ||
sendRawBulk(events: WriteEventBody[]): Promise<axios.AxiosResponse<any, any>>; | ||
/** | ||
* Fetches events from the LogDB service. | ||
* @param {number} [limit=1000] - The maximum number of events to fetch. | ||
* @returns {Promise<EventObject[]>} | ||
*/ | ||
fetchEvents(limit?: number): Promise<axios.AxiosResponse<EventObject[], any>>; | ||
/** | ||
* Writes events to the LogDB service. | ||
* @param {WriteEventBody[]} events - An array of event objects to write. | ||
* @returns {Promise<void>} | ||
*/ | ||
writeEvents(events: WriteEventBody[]): Promise<axios.AxiosResponse<any, any>>; | ||
/** | ||
* Acknowledges an event by its ID. | ||
* @param {number} eventId - The ID of the event to acknowledge. | ||
* @returns {Promise<boolean>} | ||
*/ | ||
ack(eventId: number): Promise<boolean>; | ||
/** | ||
* Sends a negative acknowledgment to the LogDB service. | ||
* @returns {Promise<boolean>} | ||
*/ | ||
nack(): Promise<boolean>; | ||
/** | ||
* Processes received events and invokes the appropriate event handlers. | ||
* @private | ||
* @param {EventObject[]} events - The array of received events. | ||
* @returns {Promise<void>} | ||
*/ | ||
private eventReceiver; | ||
/** | ||
* Starts long polling | ||
* Listens for events from the LogDB service and processes them continuously. | ||
* @returns {Promise<void>} | ||
*/ | ||
listen(): Promise<void>; | ||
@@ -55,0 +142,0 @@ } |
@@ -0,1 +1,4 @@ | ||
// lib/logdb.ts | ||
import picomatch from "picomatch"; | ||
// lib/helpers.ts | ||
@@ -26,2 +29,6 @@ function sleep(ms) { | ||
lastEventId = 0; | ||
/** | ||
* Creates an instance of LogDB. | ||
* @param {ClientOptions} options - The configuration options for the LogDB client. | ||
*/ | ||
constructor(options) { | ||
@@ -31,2 +38,6 @@ this.options = options; | ||
} | ||
/** | ||
* Initializes the LogDB API client. | ||
* @private | ||
*/ | ||
createApiClient() { | ||
@@ -39,9 +50,28 @@ const { url, token } = this.options; | ||
} | ||
/** | ||
* Registers an event handler for a specific event type. | ||
* @private | ||
* @template Type | ||
* @param {Type} name - The name of the event handler. | ||
* @param {EventHandler<Type>} callback - The callback function to handle the event. | ||
*/ | ||
registerHandler(name, callback) { | ||
this.handlers[name] = callback; | ||
} | ||
/** | ||
* Adds an event handler for a specific event type. | ||
* @template Type | ||
* @param {Type} type - The type of the event to listen to. | ||
* @param {EventHandler<Type>} handler - The handler function for the event. | ||
*/ | ||
on(type, handler) { | ||
this.registerHandler(type, handler); | ||
} | ||
async emit(type, payload) { | ||
/** | ||
* Sends a single event to the LogDB service. | ||
* @param {string} type - The event type. | ||
* @param {unknown} payload - The event payload. | ||
* @returns {Promise<void>} | ||
*/ | ||
async sendEvent(type, payload) { | ||
return this.writeEvents([ | ||
@@ -55,3 +85,9 @@ { | ||
} | ||
async emitBulk(type, payload) { | ||
/** | ||
* Sends multiple events to the LogDB service. | ||
* @param {string} type - The event type. | ||
* @param {unknown[]} payload - An array of event payloads. | ||
* @returns {Promise<void>} | ||
*/ | ||
async sendBulk(type, payload) { | ||
const currentTimestamp = timestamp(); | ||
@@ -67,3 +103,8 @@ const events = payload.map((data) => { | ||
} | ||
async rawEmit(event) { | ||
/** | ||
* Sends a single raw event to the LogDB service. | ||
* @param {WriteEventBody} event - The event object to send. | ||
* @returns {Promise<void>} | ||
*/ | ||
async sendRaw(event) { | ||
return this.writeEvents([ | ||
@@ -73,5 +114,15 @@ event | ||
} | ||
async rawEmitBulk(events) { | ||
/** | ||
* Sends multiple raw events to the LogDB service. | ||
* @param {WriteEventBody[]} events - An array of event objects to send. | ||
* @returns {Promise<void>} | ||
*/ | ||
async sendRawBulk(events) { | ||
return this.writeEvents(events); | ||
} | ||
/** | ||
* Fetches events from the LogDB service. | ||
* @param {number} [limit=1000] - The maximum number of events to fetch. | ||
* @returns {Promise<EventObject[]>} | ||
*/ | ||
async fetchEvents(limit = 1e3) { | ||
@@ -81,12 +132,26 @@ try { | ||
} catch (error) { | ||
if (error.response.status === 409) { | ||
if (error?.response?.status === 409) { | ||
await this.nack(); | ||
return await this.logDB.get(`/events/${limit}`); | ||
} else { | ||
throw error; | ||
} | ||
} | ||
} | ||
/** | ||
* Writes events to the LogDB service. | ||
* @param {WriteEventBody[]} events - An array of event objects to write. | ||
* @returns {Promise<void>} | ||
*/ | ||
async writeEvents(events) { | ||
console.log("writing events", events); | ||
return this.logDB.post("/events", events); | ||
return this.logDB.post("/events", events.map((event) => { | ||
event.evt_type = this.options.name + "://" + event.evt_type; | ||
return event; | ||
})); | ||
} | ||
/** | ||
* Acknowledges an event by its ID. | ||
* @param {number} eventId - The ID of the event to acknowledge. | ||
* @returns {Promise<boolean>} | ||
*/ | ||
async ack(eventId) { | ||
@@ -96,2 +161,6 @@ const { status } = await this.logDB.post(`/ack/${eventId}`); | ||
} | ||
/** | ||
* Sends a negative acknowledgment to the LogDB service. | ||
* @returns {Promise<boolean>} | ||
*/ | ||
async nack() { | ||
@@ -101,12 +170,19 @@ const { status } = await this.logDB.post("/nack"); | ||
} | ||
/** | ||
* Processes received events and invokes the appropriate event handlers. | ||
* @private | ||
* @param {EventObject[]} events - The array of received events. | ||
* @returns {Promise<void>} | ||
*/ | ||
async eventReceiver(events) { | ||
console.log(`Received ${events.length} events`); | ||
this.handlers["response"](events); | ||
if ("EVENTS_RECEIVED" in this.handlers) { | ||
this.handlers["EVENTS_RECEIVED"](events); | ||
} | ||
for (const event of events) { | ||
if (event.id > this.lastEventId) { | ||
this.lastEventId = event.id; | ||
const handler = this.handlers["event"]; | ||
const eventContext = { | ||
id: event.id, | ||
type: event.evt_type, | ||
type: event.type, | ||
payload: event.payload, | ||
@@ -116,8 +192,22 @@ createdAt: event.timestamp, | ||
}; | ||
if (handler) { | ||
try { | ||
await handler(eventContext); | ||
} catch (error) { | ||
this.handlers["fail"](error, eventContext); | ||
try { | ||
if ("*" in this.handlers) { | ||
this.handlers["*"](eventContext); | ||
} | ||
for (const handlerType in this.handlers) { | ||
if (!["*"].includes(handlerType)) { | ||
const isMatch = picomatch(handlerType); | ||
if (isMatch(eventContext.type)) { | ||
this.handlers[handlerType](eventContext); | ||
} | ||
} | ||
} | ||
eventContext.processed = true; | ||
} catch (error) { | ||
if ("EVENT_FAILED" in this.handlers) { | ||
this.handlers["EVENT_FAILED"](error, eventContext); | ||
} else { | ||
throw error; | ||
} | ||
await this.nack(); | ||
} | ||
@@ -127,2 +217,7 @@ } | ||
} | ||
/** | ||
* Starts long polling | ||
* Listens for events from the LogDB service and processes them continuously. | ||
* @returns {Promise<void>} | ||
*/ | ||
async listen() { | ||
@@ -132,2 +227,3 @@ console.log(`Waiting for events from ${this.options.url}`); | ||
try { | ||
this.lastEventId = 0; | ||
const response = await this.fetchEvents(); | ||
@@ -137,9 +233,8 @@ if (response?.data && response.data.length > 0) { | ||
} | ||
await this.ack(this.lastEventId); | ||
} catch (error) { | ||
if (error.response && error.response.status === 409) { | ||
await this.nack(); | ||
} | ||
console.log(error); | ||
} finally { | ||
await sleep(5e3); | ||
} | ||
await this.ack(this.lastEventId); | ||
await sleep(5e3); | ||
} | ||
@@ -146,0 +241,0 @@ } |
{ | ||
"name": "logdb-client", | ||
"version": "0.0.7", | ||
"version": "0.0.8", | ||
"type": "module", | ||
@@ -35,4 +35,6 @@ "scripts": { | ||
"dependencies": { | ||
"axios": "^1.7.2" | ||
"@types/picomatch": "^3.0.1", | ||
"axios": "^1.7.2", | ||
"picomatch": "^4.0.2" | ||
} | ||
} |
@@ -47,2 +47,3 @@ # Getting Started | ||
logDB.on('event', (event: EventContext) => { | ||
@@ -49,0 +50,0 @@ console.log(event.id, event.type) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
25145
631
57
4
+ Added@types/picomatch@^3.0.1
+ Addedpicomatch@^4.0.2
+ Added@types/picomatch@3.0.1(transitive)
+ Addedpicomatch@4.0.2(transitive)