diff --git a/.gitignore b/.gitignore index 9b1ee42..4060a83 100644 --- a/.gitignore +++ b/.gitignore @@ -118,7 +118,7 @@ out # Nuxt.js build / generate output .nuxt -dist +#dist # Gatsby files diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..9bdf752 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,21 @@ +export type Event = Record; +export interface IHTTPLogger { + log(event: string, ...tags: string[]): void; +} +export type HTTPLoggerOptions = { + url: string; + bufferSize?: number; + throttle?: number; + fetch?: typeof fetch; + getMetadata?: () => Event; +}; +declare class HTTPLog implements IHTTPLogger { + #private; + constructor({ url, bufferSize, throttle, fetch, getMetadata, }: HTTPLoggerOptions); + log(event: string, ...tags: string[]): Promise; +} +declare global { + var HTTPLogger: typeof HTTPLog; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map new file mode 100644 index 0000000..b2820de --- /dev/null +++ b/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC;CAC7B,CAAC;AAEF,cAAM,OAAQ,YAAW,WAAW;;gBAatB,EACV,GAAQ,EACR,UAAc,EACd,QAAe,EACf,KAAwB,EACxB,WAGE,GACH,EAAE,iBAAiB;IAsDd,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE;CAgB3C;AAED,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,UAAU,EAAE,OAAO,OAAO,CAAC;CAChC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..bb4f662 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,79 @@ +class HTTPLog { + #url; + #buffer = []; + #bufferSize = 3; + #throttle; + #timeout = void 0; + #getMetadata; + #fetch; + constructor({ url = "", bufferSize = 3, throttle = 1000, fetch = globalThis.fetch, getMetadata = () => ({ + title: globalThis.document?.title || "", + url: globalThis.location?.href || "", + }), }) { + if (url === "") { + throw new Error("URL is required"); + } + this.#url = url; + this.#bufferSize = bufferSize; + this.#throttle = throttle; + this.#fetch = (...args) => fetch(...args); + this.#getMetadata = getMetadata; + if (typeof window === "undefined") { + return; + } + addEventListener("unload", () => { + globalThis?.navigator?.sendBeacon?.(this.#url, JSON.stringify(this.#buffer)); + }); + } + async #post() { + const data = this.#buffer.slice(); + if (data.length === 0) { + return; + } + this.#buffer = []; + const body = JSON.stringify(data); + try { + const res = await this.#fetch(this.#url, { + method: "POST", + body: body, + headers: { + "Content-Type": "application/json", + }, + keepalive: true, + credentials: "include", + }); + if (res.status >= 400 && res.status !== 422) { + this.#buffer.push(...data); + } + return res; + } + catch (e) { + console.log("Error", e); + this.#buffer.push(...data); + } + } + async #timer() { + this.#timeout = setTimeout(() => { + this.#post(); + this.#timer(); + }, this.#throttle); + } + async log(event, ...tags) { + this.#buffer.push({ + event, + tags, + ...this.#getMetadata(), + }); + if (this.#buffer.length >= this.#bufferSize) { + this.#post(); + } + if (this.#timeout === void 0) { + this.#post(); + this.#timer(); + } + } +} +// @ts-ignore +globalThis.HTTPLogger = HTTPLog; +export {}; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..62c57c4 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/index.ts b/index.ts index 6eede80..a56cdfe 100644 --- a/index.ts +++ b/index.ts @@ -108,7 +108,7 @@ class HTTPLog implements IHTTPLogger { } declare global { - var HTTPLogger: IHTTPLogger; + var HTTPLogger: typeof HTTPLog; } // @ts-ignore diff --git a/logger.test.ts b/logger.test.ts new file mode 100644 index 0000000..c037270 --- /dev/null +++ b/logger.test.ts @@ -0,0 +1,26 @@ +import { expect, test, beforeAll, jest } from "bun:test"; +import './index.ts'; + +beforeAll(() => { + // Bun: not yet implemented + // jest.useFakeTimers(); +}); + +test("HTTPLogger", async () => { + let ping = 0; + let instance = new HTTPLogger({ + url: "http://localhost:3000", + fetch: async (_, body) => { + ping++; + return new Response(null, { + status: 200, + }); + }, + }); + instance.log("test"); + expect(ping).toBe(1); + instance.log("test2"); + expect(ping).toBe(1); + await new Promise((resolve) => setTimeout(resolve, 1100)); + expect(ping).toBe(2); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 5e7959e..2af9d6b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,5 +28,6 @@ "declaration": true, "declarationMap": true, }, - "include": ["./*"] + "include": ["./*"], + "exclude": ["node_modules", "dist", "./*.test.ts", "./*.spec.ts"] }