@haathie/pgmb 0.2.11 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/lib/types.d.ts +13 -0
- package/lib/webhook-handler.d.ts +1 -1
- package/lib/webhook-handler.js +16 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -422,7 +422,10 @@ const pgmb = new PgmbClient({
|
|
|
422
422
|
headers: {
|
|
423
423
|
// add a custom user-agent header
|
|
424
424
|
'user-agent': 'my-service-client/1.0.0'
|
|
425
|
-
}
|
|
425
|
+
},
|
|
426
|
+
// if payload is larger than 1KB, will be sent as a gzipped body
|
|
427
|
+
// with content-encoding: gzip header
|
|
428
|
+
minCompressSizeBytes: 1024,
|
|
426
429
|
},
|
|
427
430
|
// this function is called to obtain webhook URLs
|
|
428
431
|
// for a given set of PGMB subscription IDs. These
|
package/lib/types.d.ts
CHANGED
|
@@ -34,6 +34,19 @@ export type PgmbWebhookOpts<T extends IEventData> = {
|
|
|
34
34
|
splitBy?: ISplitFn<T>;
|
|
35
35
|
jsonifier?: JSONifier;
|
|
36
36
|
serialiseEvent?(ev: IReadEvent, logger: Logger): SerialisedEvent;
|
|
37
|
+
/**
|
|
38
|
+
* Minimum size in bytes for the payload to be compressed.
|
|
39
|
+
* @default 1024
|
|
40
|
+
*/
|
|
41
|
+
minCompressSizeBytes?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Compress the webhook payload before sending.
|
|
44
|
+
* By default, uses gzip compression via the `zlib` library.
|
|
45
|
+
*/
|
|
46
|
+
compress?(data: Uint8Array | string): Promise<{
|
|
47
|
+
data: Uint8Array | string;
|
|
48
|
+
contentEncoding: string;
|
|
49
|
+
}>;
|
|
37
50
|
};
|
|
38
51
|
export interface IEventData {
|
|
39
52
|
topic: string;
|
package/lib/webhook-handler.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ import type { IEventData, IEventHandler, PgmbWebhookOpts } from './types.ts';
|
|
|
3
3
|
* Create a handler that sends events to a webhook URL via HTTP POST.
|
|
4
4
|
* @param url Where to send the webhook requests
|
|
5
5
|
*/
|
|
6
|
-
export declare function createWebhookHandler<T extends IEventData>({ timeoutMs, headers, retryOpts, jsonifier, serialiseEvent }: Partial<PgmbWebhookOpts<T>>): IEventHandler;
|
|
6
|
+
export declare function createWebhookHandler<T extends IEventData>({ timeoutMs, headers, retryOpts, jsonifier, serialiseEvent, minCompressSizeBytes, compress }: Partial<PgmbWebhookOpts<T>>): IEventHandler;
|
package/lib/webhook-handler.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { gzip } from 'node:zlib';
|
|
3
5
|
import { createRetryHandler } from "./retry-handler.js";
|
|
6
|
+
import { getEnvNumber } from "./utils.js";
|
|
7
|
+
const gzipPromise = promisify(gzip);
|
|
4
8
|
/**
|
|
5
9
|
* Create a handler that sends events to a webhook URL via HTTP POST.
|
|
6
10
|
* @param url Where to send the webhook requests
|
|
@@ -8,7 +12,7 @@ import { createRetryHandler } from "./retry-handler.js";
|
|
|
8
12
|
export function createWebhookHandler({ timeoutMs = 5_000, headers, retryOpts = {
|
|
9
13
|
// retry after 5 minutes, then after 30 minutes
|
|
10
14
|
retriesS: [5 * 60, 30 * 60]
|
|
11
|
-
}, jsonifier = JSON, serialiseEvent = createSimpleSerialiser(jsonifier) }) {
|
|
15
|
+
}, jsonifier = JSON, serialiseEvent = createSimpleSerialiser(jsonifier), minCompressSizeBytes = getEnvNumber('PGMB_WEBHOOK_MIN_COMPRESS_SIZE_BYTES', 1024), compress = gzipCompress }) {
|
|
12
16
|
const handler = async (ev, { logger, extra }) => {
|
|
13
17
|
assert(typeof extra === 'object'
|
|
14
18
|
&& extra !== null
|
|
@@ -19,14 +23,18 @@ export function createWebhookHandler({ timeoutMs = 5_000, headers, retryOpts = {
|
|
|
19
23
|
const idempotencyKey = getIdempotencyKeyHeader(ev);
|
|
20
24
|
logger = logger.child({ idempotencyKey });
|
|
21
25
|
const { body, contentType } = serialiseEvent(ev, logger);
|
|
26
|
+
const { data: compBody, contentEncoding } = body.length >= minCompressSizeBytes
|
|
27
|
+
? await compress(body)
|
|
28
|
+
: { data: body };
|
|
22
29
|
const { status, statusText, body: res } = await fetch(url, {
|
|
23
30
|
method: 'POST',
|
|
24
31
|
headers: {
|
|
25
32
|
'content-type': contentType,
|
|
26
33
|
'idempotency-key': idempotencyKey,
|
|
34
|
+
...(contentEncoding ? { 'content-encoding': contentEncoding } : {}),
|
|
27
35
|
...headers
|
|
28
36
|
},
|
|
29
|
-
body,
|
|
37
|
+
body: compBody,
|
|
30
38
|
redirect: 'manual',
|
|
31
39
|
signal: AbortSignal.timeout(timeoutMs)
|
|
32
40
|
});
|
|
@@ -63,3 +71,9 @@ function createSimpleSerialiser(jsonifier) {
|
|
|
63
71
|
contentType: 'application/json'
|
|
64
72
|
});
|
|
65
73
|
}
|
|
74
|
+
async function gzipCompress(data) {
|
|
75
|
+
return {
|
|
76
|
+
data: await gzipPromise(data),
|
|
77
|
+
contentEncoding: 'gzip'
|
|
78
|
+
};
|
|
79
|
+
}
|
package/package.json
CHANGED