init
This commit is contained in:
parent
9754ce9cf8
commit
109994db57
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -118,7 +118,7 @@ out
|
|||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
#dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
|
|
21
dist/index.d.ts
vendored
Normal file
21
dist/index.d.ts
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
export type Event = Record<string, string | string[]>;
|
||||
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<void>;
|
||||
}
|
||||
declare global {
|
||||
var HTTPLogger: typeof HTTPLog;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=index.d.ts.map
|
1
dist/index.d.ts.map
vendored
Normal file
1
dist/index.d.ts.map
vendored
Normal file
|
@ -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"}
|
79
dist/index.js
vendored
Normal file
79
dist/index.js
vendored
Normal file
|
@ -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
|
1
dist/index.js.map
vendored
Normal file
1
dist/index.js.map
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
2
index.ts
2
index.ts
|
@ -108,7 +108,7 @@ class HTTPLog implements IHTTPLogger {
|
|||
}
|
||||
|
||||
declare global {
|
||||
var HTTPLogger: IHTTPLogger;
|
||||
var HTTPLogger: typeof HTTPLog;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
|
|
26
logger.test.ts
Normal file
26
logger.test.ts
Normal file
|
@ -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);
|
||||
});
|
|
@ -28,5 +28,6 @@
|
|||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
},
|
||||
"include": ["./*"]
|
||||
"include": ["./*"],
|
||||
"exclude": ["node_modules", "dist", "./*.test.ts", "./*.spec.ts"]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue