autotel-subscribers 45.0.0 → 46.0.0
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/dist/amplitude.cjs +1 -2
- package/dist/amplitude.d.cts +1 -2
- package/dist/amplitude.d.ts +1 -2
- package/dist/amplitude.js +1 -2
- package/dist/architecture-snapshot.cjs +1 -2
- package/dist/architecture-snapshot.d.cts +1 -2
- package/dist/architecture-snapshot.d.ts +1 -2
- package/dist/architecture-snapshot.js +1 -2
- package/dist/event-subscriber-base-C_F3Ycbe.cjs +1 -2
- package/dist/event-subscriber-base-Day2ml6V.js +1 -2
- package/dist/event-subscriber-base-DpZclJM4.d.cts +1 -2
- package/dist/event-subscriber-base-DpZclJM4.d.ts +1 -2
- package/dist/factories.cjs +1 -2
- package/dist/factories.d.cts +1 -2
- package/dist/factories.d.ts +1 -2
- package/dist/factories.js +1 -2
- package/dist/file.cjs +1 -2
- package/dist/file.d.cts +1 -2
- package/dist/file.d.ts +1 -2
- package/dist/file.js +1 -2
- package/dist/index.cjs +3 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/loki.cjs +229 -0
- package/dist/loki.d.cts +119 -0
- package/dist/loki.d.ts +119 -0
- package/dist/loki.js +221 -0
- package/dist/middleware.cjs +1 -2
- package/dist/middleware.d.cts +1 -2
- package/dist/middleware.d.ts +1 -2
- package/dist/middleware.js +1 -2
- package/dist/mixpanel.cjs +1 -2
- package/dist/mixpanel.d.cts +1 -2
- package/dist/mixpanel.d.ts +1 -2
- package/dist/mixpanel.js +1 -2
- package/dist/posthog-ByP8BmHb.js +1 -2
- package/dist/posthog-DOOBZanH.cjs +1 -2
- package/dist/posthog.d.cts +1 -2
- package/dist/posthog.d.ts +1 -2
- package/dist/security.cjs +1 -2
- package/dist/security.d.cts +1 -2
- package/dist/security.d.ts +1 -2
- package/dist/security.js +1 -2
- package/dist/segment.cjs +1 -2
- package/dist/segment.d.cts +1 -2
- package/dist/segment.d.ts +1 -2
- package/dist/segment.js +1 -2
- package/dist/slack.cjs +1 -2
- package/dist/slack.d.cts +1 -2
- package/dist/slack.d.ts +1 -2
- package/dist/slack.js +1 -2
- package/dist/webhook-delivery-D3v50C81.js +1 -2
- package/dist/webhook-delivery-DZeUlZhi.cjs +1 -2
- package/dist/webhook.cjs +1 -2
- package/dist/webhook.d.cts +1 -2
- package/dist/webhook.d.ts +1 -2
- package/dist/webhook.js +1 -2
- package/package.json +17 -10
- package/dist/amplitude.cjs.map +0 -1
- package/dist/amplitude.d.cts.map +0 -1
- package/dist/amplitude.d.ts.map +0 -1
- package/dist/amplitude.js.map +0 -1
- package/dist/architecture-snapshot.cjs.map +0 -1
- package/dist/architecture-snapshot.d.cts.map +0 -1
- package/dist/architecture-snapshot.d.ts.map +0 -1
- package/dist/architecture-snapshot.js.map +0 -1
- package/dist/event-subscriber-base-C_F3Ycbe.cjs.map +0 -1
- package/dist/event-subscriber-base-Day2ml6V.js.map +0 -1
- package/dist/event-subscriber-base-DpZclJM4.d.cts.map +0 -1
- package/dist/event-subscriber-base-DpZclJM4.d.ts.map +0 -1
- package/dist/factories.cjs.map +0 -1
- package/dist/factories.d.cts.map +0 -1
- package/dist/factories.d.ts.map +0 -1
- package/dist/factories.js.map +0 -1
- package/dist/file.cjs.map +0 -1
- package/dist/file.d.cts.map +0 -1
- package/dist/file.d.ts.map +0 -1
- package/dist/file.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/middleware.cjs.map +0 -1
- package/dist/middleware.d.cts.map +0 -1
- package/dist/middleware.d.ts.map +0 -1
- package/dist/middleware.js.map +0 -1
- package/dist/mixpanel.cjs.map +0 -1
- package/dist/mixpanel.d.cts.map +0 -1
- package/dist/mixpanel.d.ts.map +0 -1
- package/dist/mixpanel.js.map +0 -1
- package/dist/posthog-ByP8BmHb.js.map +0 -1
- package/dist/posthog-DOOBZanH.cjs.map +0 -1
- package/dist/posthog.d.cts.map +0 -1
- package/dist/posthog.d.ts.map +0 -1
- package/dist/security.cjs.map +0 -1
- package/dist/security.d.cts.map +0 -1
- package/dist/security.d.ts.map +0 -1
- package/dist/security.js.map +0 -1
- package/dist/segment.cjs.map +0 -1
- package/dist/segment.d.cts.map +0 -1
- package/dist/segment.d.ts.map +0 -1
- package/dist/segment.js.map +0 -1
- package/dist/slack.cjs.map +0 -1
- package/dist/slack.d.cts.map +0 -1
- package/dist/slack.d.ts.map +0 -1
- package/dist/slack.js.map +0 -1
- package/dist/webhook-delivery-D3v50C81.js.map +0 -1
- package/dist/webhook-delivery-DZeUlZhi.cjs.map +0 -1
- package/dist/webhook.cjs.map +0 -1
- package/dist/webhook.d.cts.map +0 -1
- package/dist/webhook.d.ts.map +0 -1
- package/dist/webhook.js.map +0 -1
package/dist/loki.d.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { EventAttributes, EventSubscriber, EventTrackingOptions, FunnelStatus, OutcomeStatus } from "autotel/event-subscriber";
|
|
2
|
+
//#region src/loki.d.ts
|
|
3
|
+
interface LokiConfig {
|
|
4
|
+
/**
|
|
5
|
+
* Base URL of the Loki instance, without the push path.
|
|
6
|
+
* Falls back to `LOKI_ENDPOINT`, `LOKI_URL`, then `LOKI_BASE_URL`.
|
|
7
|
+
*
|
|
8
|
+
* @example 'http://localhost:3100'
|
|
9
|
+
* @example 'https://logs-prod-eu-west-0.grafana.net'
|
|
10
|
+
*/
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
/**
|
|
13
|
+
* API token. Paired with {@link LokiConfig.user} it is sent as HTTP Basic,
|
|
14
|
+
* which is what Grafana Cloud expects. Alone it is sent as Bearer, which
|
|
15
|
+
* suits an instance behind an authenticating proxy.
|
|
16
|
+
* Falls back to `LOKI_API_KEY`, then `GRAFANA_API_KEY`.
|
|
17
|
+
*/
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Grafana Cloud instance ID — the numeric user of the Loki datasource, not
|
|
21
|
+
* an account email. Supplying it switches authentication to Basic.
|
|
22
|
+
* Falls back to `LOKI_USER`, then `GRAFANA_USER`.
|
|
23
|
+
*/
|
|
24
|
+
user?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Tenant for multi-tenant self-hosted Loki, sent as `X-Scope-OrgID`.
|
|
27
|
+
* Independent of the auth mode. Falls back to `LOKI_TENANT_ID`.
|
|
28
|
+
*/
|
|
29
|
+
tenantId?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Event fields promoted to stream labels.
|
|
32
|
+
* Defaults to `['service', 'environment', 'level']`.
|
|
33
|
+
*
|
|
34
|
+
* Keep this short and bounded. Promoting `requestId` or `userId` creates one
|
|
35
|
+
* stream per value, which degrades and eventually breaks an instance.
|
|
36
|
+
*/
|
|
37
|
+
labelFields?: string[];
|
|
38
|
+
/** Static labels merged into every stream, e.g. `{ cluster: 'prod-eu' }`. */
|
|
39
|
+
labels?: Record<string, string>;
|
|
40
|
+
/** Events buffered before a push. Default 100. */
|
|
41
|
+
batchSize?: number;
|
|
42
|
+
/** Milliseconds before a partial batch is pushed anyway. Default 5000. */
|
|
43
|
+
flushIntervalMs?: number;
|
|
44
|
+
/** Request timeout in milliseconds. Default 5000. */
|
|
45
|
+
timeoutMs?: number;
|
|
46
|
+
/** Attempts including the first. Default 3. */
|
|
47
|
+
maxRetries?: number;
|
|
48
|
+
/** Set false to construct the subscriber without sending anything. */
|
|
49
|
+
enabled?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** One event as it is written to the Loki line. */
|
|
52
|
+
type LokiEvent = Record<string, unknown> & {
|
|
53
|
+
timestamp?: string;
|
|
54
|
+
};
|
|
55
|
+
interface LokiStream {
|
|
56
|
+
stream: Record<string, string>;
|
|
57
|
+
values: [string, string][];
|
|
58
|
+
}
|
|
59
|
+
interface LokiPayload {
|
|
60
|
+
streams: LokiStream[];
|
|
61
|
+
}
|
|
62
|
+
/** Resolve the push URL, tolerating an endpoint that already carries the path. */
|
|
63
|
+
declare function resolveLokiPushUrl(endpoint: string): string;
|
|
64
|
+
/** Loki entry timestamps are nanosecond epoch strings. */
|
|
65
|
+
declare function toLokiTimestamp(timestamp?: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Build the stream labels for one event.
|
|
68
|
+
*
|
|
69
|
+
* Only configured fields holding a string, number or boolean become labels.
|
|
70
|
+
* Objects and arrays are skipped rather than stringified, because a serialised
|
|
71
|
+
* object is exactly the unbounded label value that wrecks a Loki instance.
|
|
72
|
+
*/
|
|
73
|
+
declare function toLokiLabels(event: LokiEvent, config?: Pick<LokiConfig, 'labelFields' | 'labels'>): Record<string, string>;
|
|
74
|
+
/**
|
|
75
|
+
* Group events into streams by label set.
|
|
76
|
+
*
|
|
77
|
+
* Loki rejects a push whose entries run backwards within a stream, so each
|
|
78
|
+
* stream's values are sorted by timestamp before they go out.
|
|
79
|
+
*/
|
|
80
|
+
declare function buildLokiPayload(events: LokiEvent[], config?: Pick<LokiConfig, 'labelFields' | 'labels'>): LokiPayload;
|
|
81
|
+
/** Auth and tenancy headers for a resolved config. */
|
|
82
|
+
declare function toLokiHeaders(config: Pick<LokiConfig, 'apiKey' | 'user' | 'tenantId'>): Record<string, string>;
|
|
83
|
+
/** Push a batch of events without going through a subscriber. */
|
|
84
|
+
declare function sendBatchToLoki(events: LokiEvent[], config?: LokiConfig): Promise<void>;
|
|
85
|
+
/** Push a single event without going through a subscriber. */
|
|
86
|
+
declare function sendToLoki(event: LokiEvent, config?: LokiConfig): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Buffers events and pushes them to Loki as grouped streams.
|
|
89
|
+
*
|
|
90
|
+
* Batching is not an optimisation here so much as the shape Loki wants: one
|
|
91
|
+
* request carrying several streams costs far less than one request per event,
|
|
92
|
+
* and grouping is what lets entries be ordered within a stream.
|
|
93
|
+
*/
|
|
94
|
+
declare class LokiSubscriber implements EventSubscriber {
|
|
95
|
+
readonly name = "LokiSubscriber";
|
|
96
|
+
readonly version = "1.0.0";
|
|
97
|
+
private readonly config;
|
|
98
|
+
private readonly endpoint;
|
|
99
|
+
private readonly enabled;
|
|
100
|
+
private readonly batchSize;
|
|
101
|
+
private readonly flushIntervalMs;
|
|
102
|
+
private readonly httpClient;
|
|
103
|
+
private buffer;
|
|
104
|
+
private timer;
|
|
105
|
+
private readonly pending;
|
|
106
|
+
private warnedMissingEndpoint;
|
|
107
|
+
constructor(config?: LokiConfig);
|
|
108
|
+
private record;
|
|
109
|
+
/** Push everything buffered so far. Safe to call when empty. */
|
|
110
|
+
flush(): Promise<void>;
|
|
111
|
+
trackEvent(name: string, attributes?: EventAttributes, options?: EventTrackingOptions): Promise<void>;
|
|
112
|
+
trackFunnelStep(funnelName: string, step: FunnelStatus, attributes?: EventAttributes, options?: EventTrackingOptions): Promise<void>;
|
|
113
|
+
trackOutcome(operationName: string, outcome: OutcomeStatus, attributes?: EventAttributes, options?: EventTrackingOptions): Promise<void>;
|
|
114
|
+
trackValue(name: string, value: number, attributes?: EventAttributes, options?: EventTrackingOptions): Promise<void>;
|
|
115
|
+
private track;
|
|
116
|
+
shutdown(): Promise<void>;
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { LokiConfig, LokiEvent, LokiPayload, LokiSubscriber, buildLokiPayload, resolveLokiPushUrl, sendBatchToLoki, sendToLoki, toLokiHeaders, toLokiLabels, toLokiTimestamp };
|
package/dist/loki.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { n as createHttpClient, t as postJsonWithRetry } from "./webhook-delivery-D3v50C81.js";
|
|
2
|
+
|
|
3
|
+
//#region src/loki.ts
|
|
4
|
+
/** Push path appended to {@link LokiConfig.endpoint}. */
|
|
5
|
+
const LOKI_PUSH_PATH = "/loki/api/v1/push";
|
|
6
|
+
/**
|
|
7
|
+
* Fields promoted to Loki labels when none are configured. Deliberately short:
|
|
8
|
+
* every distinct combination of label values is a separate stream.
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_LABEL_FIELDS = [
|
|
11
|
+
"service",
|
|
12
|
+
"environment",
|
|
13
|
+
"level"
|
|
14
|
+
];
|
|
15
|
+
function firstEnv(...names) {
|
|
16
|
+
for (const name of names) {
|
|
17
|
+
const value = process.env[name];
|
|
18
|
+
if (value) return value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Resolve the push URL, tolerating an endpoint that already carries the path. */
|
|
22
|
+
function resolveLokiPushUrl(endpoint) {
|
|
23
|
+
const trimmed = endpoint.replace(/\/+$/, "");
|
|
24
|
+
return trimmed.endsWith(LOKI_PUSH_PATH) ? trimmed : `${trimmed}${LOKI_PUSH_PATH}`;
|
|
25
|
+
}
|
|
26
|
+
/** Loki entry timestamps are nanosecond epoch strings. */
|
|
27
|
+
function toLokiTimestamp(timestamp) {
|
|
28
|
+
const parsed = timestamp ? Date.parse(timestamp) : NaN;
|
|
29
|
+
return `${Number.isFinite(parsed) ? parsed : Date.now()}000000`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build the stream labels for one event.
|
|
33
|
+
*
|
|
34
|
+
* Only configured fields holding a string, number or boolean become labels.
|
|
35
|
+
* Objects and arrays are skipped rather than stringified, because a serialised
|
|
36
|
+
* object is exactly the unbounded label value that wrecks a Loki instance.
|
|
37
|
+
*/
|
|
38
|
+
function toLokiLabels(event, config = {}) {
|
|
39
|
+
const fields = config.labelFields ?? [...DEFAULT_LABEL_FIELDS];
|
|
40
|
+
const labels = { ...config.labels };
|
|
41
|
+
for (const field of fields) {
|
|
42
|
+
const value = event[field];
|
|
43
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") labels[field] = String(value);
|
|
44
|
+
}
|
|
45
|
+
return labels;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Group events into streams by label set.
|
|
49
|
+
*
|
|
50
|
+
* Loki rejects a push whose entries run backwards within a stream, so each
|
|
51
|
+
* stream's values are sorted by timestamp before they go out.
|
|
52
|
+
*/
|
|
53
|
+
function buildLokiPayload(events, config = {}) {
|
|
54
|
+
const byLabels = /* @__PURE__ */ new Map();
|
|
55
|
+
for (const event of events) {
|
|
56
|
+
const labels = toLokiLabels(event, config);
|
|
57
|
+
const key = JSON.stringify(Object.entries(labels).toSorted(([a], [b]) => a.localeCompare(b)));
|
|
58
|
+
const entry = [toLokiTimestamp(typeof event.timestamp === "string" ? event.timestamp : void 0), JSON.stringify(event)];
|
|
59
|
+
const existing = byLabels.get(key);
|
|
60
|
+
if (existing) existing.values.push(entry);
|
|
61
|
+
else byLabels.set(key, {
|
|
62
|
+
stream: labels,
|
|
63
|
+
values: [entry]
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
for (const stream of byLabels.values()) stream.values = stream.values.toSorted(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
67
|
+
return { streams: [...byLabels.values()] };
|
|
68
|
+
}
|
|
69
|
+
/** Auth and tenancy headers for a resolved config. */
|
|
70
|
+
function toLokiHeaders(config) {
|
|
71
|
+
const headers = {};
|
|
72
|
+
if (config.user && config.apiKey) headers.Authorization = `Basic ${Buffer.from(`${config.user}:${config.apiKey}`).toString("base64")}`;
|
|
73
|
+
else if (config.apiKey) headers.Authorization = `Bearer ${config.apiKey}`;
|
|
74
|
+
if (config.tenantId) headers["X-Scope-OrgID"] = config.tenantId;
|
|
75
|
+
return headers;
|
|
76
|
+
}
|
|
77
|
+
/** Push a batch of events without going through a subscriber. */
|
|
78
|
+
async function sendBatchToLoki(events, config = {}) {
|
|
79
|
+
if (events.length === 0) return;
|
|
80
|
+
const endpoint = config.endpoint ?? firstEnv("LOKI_ENDPOINT", "LOKI_URL", "LOKI_BASE_URL");
|
|
81
|
+
if (!endpoint) throw new Error("Loki endpoint is not configured");
|
|
82
|
+
const resolved = {
|
|
83
|
+
...config,
|
|
84
|
+
endpoint,
|
|
85
|
+
apiKey: config.apiKey ?? firstEnv("LOKI_API_KEY", "GRAFANA_API_KEY"),
|
|
86
|
+
user: config.user ?? firstEnv("LOKI_USER", "GRAFANA_USER"),
|
|
87
|
+
tenantId: config.tenantId ?? firstEnv("LOKI_TENANT_ID")
|
|
88
|
+
};
|
|
89
|
+
await postJsonWithRetry(createHttpClient({ timeoutMs: resolved.timeoutMs ?? 5e3 }), resolveLokiPushUrl(endpoint), buildLokiPayload(events, resolved), {
|
|
90
|
+
headers: toLokiHeaders(resolved),
|
|
91
|
+
maxRetries: resolved.maxRetries ?? 3,
|
|
92
|
+
label: "Loki"
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/** Push a single event without going through a subscriber. */
|
|
96
|
+
async function sendToLoki(event, config = {}) {
|
|
97
|
+
await sendBatchToLoki([event], config);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Buffers events and pushes them to Loki as grouped streams.
|
|
101
|
+
*
|
|
102
|
+
* Batching is not an optimisation here so much as the shape Loki wants: one
|
|
103
|
+
* request carrying several streams costs far less than one request per event,
|
|
104
|
+
* and grouping is what lets entries be ordered within a stream.
|
|
105
|
+
*/
|
|
106
|
+
var LokiSubscriber = class {
|
|
107
|
+
name = "LokiSubscriber";
|
|
108
|
+
version = "1.0.0";
|
|
109
|
+
config;
|
|
110
|
+
endpoint;
|
|
111
|
+
enabled;
|
|
112
|
+
batchSize;
|
|
113
|
+
flushIntervalMs;
|
|
114
|
+
httpClient;
|
|
115
|
+
buffer = [];
|
|
116
|
+
timer;
|
|
117
|
+
pending = /* @__PURE__ */ new Set();
|
|
118
|
+
warnedMissingEndpoint = false;
|
|
119
|
+
constructor(config = {}) {
|
|
120
|
+
this.endpoint = config.endpoint ?? firstEnv("LOKI_ENDPOINT", "LOKI_URL", "LOKI_BASE_URL");
|
|
121
|
+
this.config = {
|
|
122
|
+
...config,
|
|
123
|
+
apiKey: config.apiKey ?? firstEnv("LOKI_API_KEY", "GRAFANA_API_KEY"),
|
|
124
|
+
user: config.user ?? firstEnv("LOKI_USER", "GRAFANA_USER"),
|
|
125
|
+
tenantId: config.tenantId ?? firstEnv("LOKI_TENANT_ID")
|
|
126
|
+
};
|
|
127
|
+
this.enabled = config.enabled ?? true;
|
|
128
|
+
this.batchSize = config.batchSize ?? 100;
|
|
129
|
+
this.flushIntervalMs = config.flushIntervalMs ?? 5e3;
|
|
130
|
+
this.httpClient = createHttpClient({ timeoutMs: config.timeoutMs ?? 5e3 });
|
|
131
|
+
}
|
|
132
|
+
record(event) {
|
|
133
|
+
if (!this.enabled) return;
|
|
134
|
+
if (!this.endpoint) {
|
|
135
|
+
if (!this.warnedMissingEndpoint) {
|
|
136
|
+
this.warnedMissingEndpoint = true;
|
|
137
|
+
console.warn("[autotel/loki] No endpoint configured; set LOKI_ENDPOINT or pass { endpoint }. Events are being dropped.");
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
this.buffer.push(event);
|
|
142
|
+
if (this.buffer.length >= this.batchSize) {
|
|
143
|
+
this.track(this.flush());
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (!this.timer) {
|
|
147
|
+
this.timer = setTimeout(() => {
|
|
148
|
+
this.timer = void 0;
|
|
149
|
+
this.track(this.flush());
|
|
150
|
+
}, this.flushIntervalMs);
|
|
151
|
+
this.timer.unref?.();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** Push everything buffered so far. Safe to call when empty. */
|
|
155
|
+
async flush() {
|
|
156
|
+
if (this.buffer.length === 0 || !this.endpoint) return;
|
|
157
|
+
const batch = this.buffer;
|
|
158
|
+
this.buffer = [];
|
|
159
|
+
await postJsonWithRetry(this.httpClient, resolveLokiPushUrl(this.endpoint), buildLokiPayload(batch, this.config), {
|
|
160
|
+
headers: toLokiHeaders(this.config),
|
|
161
|
+
maxRetries: this.config.maxRetries ?? 3,
|
|
162
|
+
label: "Loki"
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
async trackEvent(name, attributes, options) {
|
|
166
|
+
this.record({
|
|
167
|
+
type: "event",
|
|
168
|
+
name,
|
|
169
|
+
...attributes,
|
|
170
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
171
|
+
...options?.autotel ? { autotel: options.autotel } : {}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async trackFunnelStep(funnelName, step, attributes, options) {
|
|
175
|
+
this.record({
|
|
176
|
+
type: "funnel",
|
|
177
|
+
funnel: funnelName,
|
|
178
|
+
step,
|
|
179
|
+
...attributes,
|
|
180
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
181
|
+
...options?.autotel ? { autotel: options.autotel } : {}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
async trackOutcome(operationName, outcome, attributes, options) {
|
|
185
|
+
this.record({
|
|
186
|
+
type: "outcome",
|
|
187
|
+
operation: operationName,
|
|
188
|
+
outcome,
|
|
189
|
+
...attributes,
|
|
190
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
191
|
+
...options?.autotel ? { autotel: options.autotel } : {}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
async trackValue(name, value, attributes, options) {
|
|
195
|
+
this.record({
|
|
196
|
+
type: "value",
|
|
197
|
+
name,
|
|
198
|
+
value,
|
|
199
|
+
...attributes,
|
|
200
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
201
|
+
...options?.autotel ? { autotel: options.autotel } : {}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
track(request) {
|
|
205
|
+
this.pending.add(request);
|
|
206
|
+
request.catch(() => {}).finally(() => {
|
|
207
|
+
this.pending.delete(request);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
async shutdown() {
|
|
211
|
+
if (this.timer) {
|
|
212
|
+
clearTimeout(this.timer);
|
|
213
|
+
this.timer = void 0;
|
|
214
|
+
}
|
|
215
|
+
if (this.pending.size > 0) await Promise.allSettled(this.pending);
|
|
216
|
+
await this.flush().catch(() => {});
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
//#endregion
|
|
221
|
+
export { LokiSubscriber, buildLokiPayload, resolveLokiPushUrl, sendBatchToLoki, sendToLoki, toLokiHeaders, toLokiLabels, toLokiTimestamp };
|
package/dist/middleware.cjs
CHANGED
|
@@ -477,5 +477,4 @@ exports.timeoutMiddleware = timeoutMiddleware;
|
|
|
477
477
|
exports.transformMiddleware = transformMiddleware;
|
|
478
478
|
exports.withEventLogger = withEventLogger;
|
|
479
479
|
exports.withIdempotency = withIdempotency;
|
|
480
|
-
exports.withRateLimit = withRateLimit;
|
|
481
|
-
//# sourceMappingURL=middleware.cjs.map
|
|
480
|
+
exports.withRateLimit = withRateLimit;
|
package/dist/middleware.d.cts
CHANGED
|
@@ -250,5 +250,4 @@ declare function withEventLogger(options: {
|
|
|
250
250
|
sink: SendEventSink;
|
|
251
251
|
}): SubscriberMiddleware;
|
|
252
252
|
//#endregion
|
|
253
|
-
export { EventsEvent, IdempotencyStore, RateLimitAlgorithm, RateLimitRecord, RateLimitStore, SendEventRecord, SendEventSink, SubscriberMiddleware, applyMiddleware, batchingMiddleware, circuitBreakerMiddleware, createIdempotencyStore, createMiddleware, createRateLimitStore, enrichmentMiddleware, filterMiddleware, inMemoryIdempotencyStore, inMemoryRateLimitStore, loggingMiddleware, rateLimitMiddleware, retryMiddleware, samplingMiddleware, timeoutMiddleware, transformMiddleware, withEventLogger, withIdempotency, withRateLimit };
|
|
254
|
-
//# sourceMappingURL=middleware.d.cts.map
|
|
253
|
+
export { EventsEvent, IdempotencyStore, RateLimitAlgorithm, RateLimitRecord, RateLimitStore, SendEventRecord, SendEventSink, SubscriberMiddleware, applyMiddleware, batchingMiddleware, circuitBreakerMiddleware, createIdempotencyStore, createMiddleware, createRateLimitStore, enrichmentMiddleware, filterMiddleware, inMemoryIdempotencyStore, inMemoryRateLimitStore, loggingMiddleware, rateLimitMiddleware, retryMiddleware, samplingMiddleware, timeoutMiddleware, transformMiddleware, withEventLogger, withIdempotency, withRateLimit };
|
package/dist/middleware.d.ts
CHANGED
|
@@ -250,5 +250,4 @@ declare function withEventLogger(options: {
|
|
|
250
250
|
sink: SendEventSink;
|
|
251
251
|
}): SubscriberMiddleware;
|
|
252
252
|
//#endregion
|
|
253
|
-
export { EventsEvent, IdempotencyStore, RateLimitAlgorithm, RateLimitRecord, RateLimitStore, SendEventRecord, SendEventSink, SubscriberMiddleware, applyMiddleware, batchingMiddleware, circuitBreakerMiddleware, createIdempotencyStore, createMiddleware, createRateLimitStore, enrichmentMiddleware, filterMiddleware, inMemoryIdempotencyStore, inMemoryRateLimitStore, loggingMiddleware, rateLimitMiddleware, retryMiddleware, samplingMiddleware, timeoutMiddleware, transformMiddleware, withEventLogger, withIdempotency, withRateLimit };
|
|
254
|
-
//# sourceMappingURL=middleware.d.ts.map
|
|
253
|
+
export { EventsEvent, IdempotencyStore, RateLimitAlgorithm, RateLimitRecord, RateLimitStore, SendEventRecord, SendEventSink, SubscriberMiddleware, applyMiddleware, batchingMiddleware, circuitBreakerMiddleware, createIdempotencyStore, createMiddleware, createRateLimitStore, enrichmentMiddleware, filterMiddleware, inMemoryIdempotencyStore, inMemoryRateLimitStore, loggingMiddleware, rateLimitMiddleware, retryMiddleware, samplingMiddleware, timeoutMiddleware, transformMiddleware, withEventLogger, withIdempotency, withRateLimit };
|
package/dist/middleware.js
CHANGED
|
@@ -457,5 +457,4 @@ function withEventLogger(options) {
|
|
|
457
457
|
}
|
|
458
458
|
|
|
459
459
|
//#endregion
|
|
460
|
-
export { applyMiddleware, batchingMiddleware, circuitBreakerMiddleware, createIdempotencyStore, createMiddleware, createRateLimitStore, enrichmentMiddleware, filterMiddleware, inMemoryIdempotencyStore, inMemoryRateLimitStore, loggingMiddleware, rateLimitMiddleware, retryMiddleware, samplingMiddleware, timeoutMiddleware, transformMiddleware, withEventLogger, withIdempotency, withRateLimit };
|
|
461
|
-
//# sourceMappingURL=middleware.js.map
|
|
460
|
+
export { applyMiddleware, batchingMiddleware, circuitBreakerMiddleware, createIdempotencyStore, createMiddleware, createRateLimitStore, enrichmentMiddleware, filterMiddleware, inMemoryIdempotencyStore, inMemoryRateLimitStore, loggingMiddleware, rateLimitMiddleware, retryMiddleware, samplingMiddleware, timeoutMiddleware, transformMiddleware, withEventLogger, withIdempotency, withRateLimit };
|
package/dist/mixpanel.cjs
CHANGED
package/dist/mixpanel.d.cts
CHANGED
|
@@ -31,5 +31,4 @@ declare class MixpanelSubscriber implements EventSubscriber {
|
|
|
31
31
|
trackValue(name: string, value: number, attributes?: EventAttributes, options?: EventTrackingOptions): Promise<void>;
|
|
32
32
|
}
|
|
33
33
|
//#endregion
|
|
34
|
-
export { MixpanelConfig, MixpanelSubscriber };
|
|
35
|
-
//# sourceMappingURL=mixpanel.d.cts.map
|
|
34
|
+
export { MixpanelConfig, MixpanelSubscriber };
|
package/dist/mixpanel.d.ts
CHANGED
|
@@ -31,5 +31,4 @@ declare class MixpanelSubscriber implements EventSubscriber {
|
|
|
31
31
|
trackValue(name: string, value: number, attributes?: EventAttributes, options?: EventTrackingOptions): Promise<void>;
|
|
32
32
|
}
|
|
33
33
|
//#endregion
|
|
34
|
-
export { MixpanelConfig, MixpanelSubscriber };
|
|
35
|
-
//# sourceMappingURL=mixpanel.d.ts.map
|
|
34
|
+
export { MixpanelConfig, MixpanelSubscriber };
|
package/dist/mixpanel.js
CHANGED
package/dist/posthog-ByP8BmHb.js
CHANGED
package/dist/posthog.d.cts
CHANGED
|
@@ -328,5 +328,4 @@ declare class PostHogSubscriber extends EventSubscriber$1 {
|
|
|
328
328
|
protected handleError(error: Error, payload: EventPayload): void;
|
|
329
329
|
}
|
|
330
330
|
//#endregion
|
|
331
|
-
export { ErrorContext, FeatureFlagOptions, PersonProperties, PostHogConfig, PostHogSubscriber };
|
|
332
|
-
//# sourceMappingURL=posthog.d.cts.map
|
|
331
|
+
export { ErrorContext, FeatureFlagOptions, PersonProperties, PostHogConfig, PostHogSubscriber };
|
package/dist/posthog.d.ts
CHANGED
|
@@ -328,5 +328,4 @@ declare class PostHogSubscriber extends EventSubscriber$1 {
|
|
|
328
328
|
protected handleError(error: Error, payload: EventPayload): void;
|
|
329
329
|
}
|
|
330
330
|
//#endregion
|
|
331
|
-
export { ErrorContext, FeatureFlagOptions, PersonProperties, PostHogConfig, PostHogSubscriber };
|
|
332
|
-
//# sourceMappingURL=posthog.d.ts.map
|
|
331
|
+
export { ErrorContext, FeatureFlagOptions, PersonProperties, PostHogConfig, PostHogSubscriber };
|
package/dist/security.cjs
CHANGED
package/dist/security.d.cts
CHANGED
|
@@ -53,5 +53,4 @@ declare class SecuritySubscriber extends EventSubscriber$1 {
|
|
|
53
53
|
private toAlert;
|
|
54
54
|
}
|
|
55
55
|
//#endregion
|
|
56
|
-
export { SecurityAlert, SecurityAlertSeverity, SecuritySubscriber, SecuritySubscriberConfig };
|
|
57
|
-
//# sourceMappingURL=security.d.cts.map
|
|
56
|
+
export { SecurityAlert, SecurityAlertSeverity, SecuritySubscriber, SecuritySubscriberConfig };
|
package/dist/security.d.ts
CHANGED
|
@@ -53,5 +53,4 @@ declare class SecuritySubscriber extends EventSubscriber$1 {
|
|
|
53
53
|
private toAlert;
|
|
54
54
|
}
|
|
55
55
|
//#endregion
|
|
56
|
-
export { SecurityAlert, SecurityAlertSeverity, SecuritySubscriber, SecuritySubscriberConfig };
|
|
57
|
-
//# sourceMappingURL=security.d.ts.map
|
|
56
|
+
export { SecurityAlert, SecurityAlertSeverity, SecuritySubscriber, SecuritySubscriberConfig };
|
package/dist/security.js
CHANGED
package/dist/segment.cjs
CHANGED
package/dist/segment.d.cts
CHANGED
package/dist/segment.d.ts
CHANGED
package/dist/segment.js
CHANGED
package/dist/slack.cjs
CHANGED
package/dist/slack.d.cts
CHANGED
|
@@ -60,5 +60,4 @@ declare class SlackSubscriber extends EventSubscriber {
|
|
|
60
60
|
protected handleError(error: Error, payload: EventPayload): void;
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
|
-
export { SlackSubscriber, SlackSubscriberConfig };
|
|
64
|
-
//# sourceMappingURL=slack.d.cts.map
|
|
63
|
+
export { SlackSubscriber, SlackSubscriberConfig };
|
package/dist/slack.d.ts
CHANGED
|
@@ -60,5 +60,4 @@ declare class SlackSubscriber extends EventSubscriber {
|
|
|
60
60
|
protected handleError(error: Error, payload: EventPayload): void;
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
|
-
export { SlackSubscriber, SlackSubscriberConfig };
|
|
64
|
-
//# sourceMappingURL=slack.d.ts.map
|
|
63
|
+
export { SlackSubscriber, SlackSubscriberConfig };
|
package/dist/slack.js
CHANGED
|
@@ -181,5 +181,4 @@ async function postJsonWithRetry(client, url, payload, options = {}) {
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
//#endregion
|
|
184
|
-
export { createHttpClient as n, postJsonWithRetry as t };
|
|
185
|
-
//# sourceMappingURL=webhook-delivery-D3v50C81.js.map
|
|
184
|
+
export { createHttpClient as n, postJsonWithRetry as t };
|
package/dist/webhook.cjs
CHANGED
package/dist/webhook.d.cts
CHANGED
package/dist/webhook.d.ts
CHANGED
package/dist/webhook.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-subscribers",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "46.0.0",
|
|
4
4
|
"description": "Write Once, Observe Anywhere - Event subscribers for autotel (PostHog, Mixpanel, Amplitude, Segment)",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -71,6 +71,11 @@
|
|
|
71
71
|
"types": "./dist/testing/index.d.ts",
|
|
72
72
|
"import": "./dist/testing/index.js",
|
|
73
73
|
"require": "./dist/testing/index.cjs"
|
|
74
|
+
},
|
|
75
|
+
"./loki": {
|
|
76
|
+
"types": "./dist/loki.d.ts",
|
|
77
|
+
"import": "./dist/loki.js",
|
|
78
|
+
"require": "./dist/loki.cjs"
|
|
74
79
|
}
|
|
75
80
|
},
|
|
76
81
|
"files": [
|
|
@@ -87,6 +92,8 @@
|
|
|
87
92
|
"amplitude",
|
|
88
93
|
"segment",
|
|
89
94
|
"webhook",
|
|
95
|
+
"loki",
|
|
96
|
+
"grafana",
|
|
90
97
|
"adapters",
|
|
91
98
|
"business-metrics",
|
|
92
99
|
"product-analytics",
|
|
@@ -99,7 +106,7 @@
|
|
|
99
106
|
"slow-redact": "^0.3.2"
|
|
100
107
|
},
|
|
101
108
|
"peerDependencies": {
|
|
102
|
-
"autotel": "6.
|
|
109
|
+
"autotel": "6.2.0"
|
|
103
110
|
},
|
|
104
111
|
"peerDependenciesMeta": {
|
|
105
112
|
"posthog-node": {
|
|
@@ -116,27 +123,27 @@
|
|
|
116
123
|
}
|
|
117
124
|
},
|
|
118
125
|
"devDependencies": {
|
|
119
|
-
"@amplitude/analytics-node": "^1.5.
|
|
126
|
+
"@amplitude/analytics-node": "^1.5.69",
|
|
120
127
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
121
|
-
"@cloudflare/workers-types": "^5.
|
|
122
|
-
"@prisma/client": "^7.9.
|
|
128
|
+
"@cloudflare/workers-types": "^5.20260728.1",
|
|
129
|
+
"@prisma/client": "^7.9.1",
|
|
123
130
|
"@segment/analytics-node": "^3.1.0",
|
|
124
|
-
"@types/node": "^26.1.
|
|
131
|
+
"@types/node": "^26.1.2",
|
|
125
132
|
"@typescript-eslint/eslint-plugin": "^8.65.0",
|
|
126
133
|
"@typescript-eslint/parser": "^8.65.0",
|
|
127
134
|
"drizzle-orm": "^0.45.2",
|
|
128
135
|
"eslint-config-prettier": "^10.1.8",
|
|
129
136
|
"eslint-plugin-unicorn": "^64.0.0",
|
|
130
137
|
"mixpanel": "^0.22.0",
|
|
131
|
-
"mongoose": "^9.8.
|
|
132
|
-
"posthog-node": "^5.46.
|
|
138
|
+
"mongoose": "^9.8.1",
|
|
139
|
+
"posthog-node": "^5.46.1",
|
|
133
140
|
"prettier": "^3.9.6",
|
|
134
141
|
"rimraf": "^6.1.3",
|
|
135
|
-
"tsdown": "^0.22.
|
|
142
|
+
"tsdown": "^0.22.14",
|
|
136
143
|
"typescript": "^6.0.3",
|
|
137
144
|
"typescript-eslint": "^8.65.0",
|
|
138
145
|
"vitest": "^4.1.10",
|
|
139
|
-
"autotel": "6.
|
|
146
|
+
"autotel": "6.2.0"
|
|
140
147
|
},
|
|
141
148
|
"repository": {
|
|
142
149
|
"type": "git",
|