@voltro/plugin-clickhouse 0.33.0 → 0.35.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/CHANGELOG.md +1968 -0
- package/dist/index.d.ts +26 -9
- package/dist/index.js +28 -10
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -47,16 +47,28 @@ export declare interface ClickhouseAnalyticsOptions {
|
|
|
47
47
|
readonly mirrorTables?: ReadonlyArray<string>;
|
|
48
48
|
/** Primary-key column on the mirrored source rows. Default `'id'`. */
|
|
49
49
|
readonly mirrorPrimaryKey?: string;
|
|
50
|
-
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Client-side batching of `track()` inserts — ON by default (20 events /
|
|
52
|
+
* 5 s, plugin-posthog's numbers). What changes observably with batching: a
|
|
53
|
+
* successful `track()` means "buffered", the actual insert happens off the
|
|
54
|
+
* call path (flushed by size, on the timer, and on graceful shutdown via
|
|
55
|
+
* `dispose`; a flush failure is logged + that batch dropped; a hard crash
|
|
56
|
+
* loses whatever is still buffered).
|
|
57
|
+
*
|
|
58
|
+
* `batch: false` opts OUT: every `track()` is one immediate HTTP insert and
|
|
59
|
+
* a success means ClickHouse accepted the row — at one round-trip and one
|
|
60
|
+
* MergeTree part per event, which is the part-explosion PERF-11 measured.
|
|
61
|
+
* `batch: {...}` keeps batching and tunes size/interval.
|
|
62
|
+
*/
|
|
63
|
+
readonly batch?: ClickhouseBatchOptions | false;
|
|
54
64
|
}
|
|
55
65
|
|
|
56
|
-
/**
|
|
57
|
-
* ONE multi-row `client.insert`, cutting
|
|
66
|
+
/** Client-side batching tunables (batching is ON by default). Buffers
|
|
67
|
+
* `track()` rows and flushes them in ONE multi-row `client.insert`, cutting
|
|
68
|
+
* HTTP round-trips and MergeTree part churn under load. */
|
|
58
69
|
export declare interface ClickhouseBatchOptions {
|
|
59
|
-
/** Flush once the buffer reaches this many events. Default
|
|
70
|
+
/** Flush once the buffer reaches this many events. Default 20 (mirrors
|
|
71
|
+
* plugin-posthog's conservative batcher). */
|
|
60
72
|
readonly maxSize?: number;
|
|
61
73
|
/** Flush a non-empty buffer this many ms after the first event lands
|
|
62
74
|
* (so low-volume trickles don't sit until shutdown). Default 5000. */
|
|
@@ -70,8 +82,13 @@ export declare const EVENTS_TABLE_DDL: (database: string, table: string) => stri
|
|
|
70
82
|
* gives idempotent upserts — re-inserting the same row with a newer
|
|
71
83
|
* `version` collapses to the latest on merge. Deletes insert a tombstone
|
|
72
84
|
* (`is_deleted = 1`); queries filter `is_deleted = 0` (or use the
|
|
73
|
-
* `FINAL` modifier).
|
|
74
|
-
*
|
|
85
|
+
* `FINAL` modifier).
|
|
86
|
+
*
|
|
87
|
+
* `version` is the framework's per-change ordering token
|
|
88
|
+
* (`MirrorVersion`), assigned in COMMIT order and carried on the write.
|
|
89
|
+
* It is never read from a clock inside this sink — that is what makes
|
|
90
|
+
* "a later write always wins" true of the later COMMIT rather than of
|
|
91
|
+
* whichever HTTP request happened to arrive last.
|
|
75
92
|
*/
|
|
76
93
|
export declare const MIRROR_TABLE_DDL: (database: string, sourceTable: string) => string;
|
|
77
94
|
|
package/dist/index.js
CHANGED
|
@@ -138,23 +138,37 @@ var a = r({ scope: "@voltro/plugin-clickhouse" }), o = "clickhouse", s = (e) =>
|
|
|
138
138
|
return {
|
|
139
139
|
tables: e.mirrorTables,
|
|
140
140
|
primaryKey: e.mirrorPrimaryKey,
|
|
141
|
-
upsert: (r, i) => t.gen(function* () {
|
|
141
|
+
upsert: ({ table: r, row: i, version: a }) => t.gen(function* () {
|
|
142
142
|
let t = String(i[e.mirrorPrimaryKey]);
|
|
143
143
|
yield* n(r, {
|
|
144
144
|
id: t,
|
|
145
145
|
data: JSON.stringify(i),
|
|
146
|
-
version:
|
|
146
|
+
version: a,
|
|
147
147
|
is_deleted: 0
|
|
148
148
|
});
|
|
149
149
|
}).pipe(d("mirror.upsert")),
|
|
150
|
-
remove: (e, r) => t.gen(function* () {
|
|
150
|
+
remove: ({ table: e, primaryKeyValue: r, version: i }) => t.gen(function* () {
|
|
151
151
|
yield* n(e, {
|
|
152
152
|
id: String(r),
|
|
153
153
|
data: "{}",
|
|
154
|
-
version:
|
|
154
|
+
version: i,
|
|
155
155
|
is_deleted: 1
|
|
156
156
|
});
|
|
157
|
-
}).pipe(d("mirror.remove"))
|
|
157
|
+
}).pipe(d("mirror.remove")),
|
|
158
|
+
maxVersion: ({ table: n, primaryKeyValue: r }) => t.gen(function* () {
|
|
159
|
+
p(String(n), "mirror table");
|
|
160
|
+
let i = yield* _(e), a = `SELECT max(version) AS v, count() AS n FROM ${e.database}.${s(String(n))} WHERE id = {id: String} FORMAT JSON`, o = yield* t.tryPromise({
|
|
161
|
+
try: () => i.query({
|
|
162
|
+
query: a,
|
|
163
|
+
query_params: { id: String(r) }
|
|
164
|
+
}),
|
|
165
|
+
catch: (e) => e
|
|
166
|
+
}), { data: c } = yield* t.tryPromise({
|
|
167
|
+
try: () => o.json(),
|
|
168
|
+
catch: (e) => e
|
|
169
|
+
}), l = c[0];
|
|
170
|
+
return l === void 0 || Number(l.n) === 0 || l.v === null ? null : Number(l.v);
|
|
171
|
+
}).pipe(d("mirror.maxVersion"))
|
|
158
172
|
};
|
|
159
173
|
}, O = (e) => {
|
|
160
174
|
let n = e.mirrorTables.length > 0 ? D(e) : void 0;
|
|
@@ -248,7 +262,7 @@ var a = r({ scope: "@voltro/plugin-clickhouse" }), o = "clickhouse", s = (e) =>
|
|
|
248
262
|
}).pipe(d("topN")),
|
|
249
263
|
...n === void 0 ? {} : { mirror: n }
|
|
250
264
|
};
|
|
251
|
-
}, k =
|
|
265
|
+
}, k = 20, A = 5e3, j = (n) => {
|
|
252
266
|
let r = (n.mirrorTables ?? []).map((e) => p(e, "mirror table")), i = {
|
|
253
267
|
client: null,
|
|
254
268
|
database: p(n.database ?? "default", "database"),
|
|
@@ -256,10 +270,14 @@ var a = r({ scope: "@voltro/plugin-clickhouse" }), o = "clickhouse", s = (e) =>
|
|
|
256
270
|
mirrorTables: r,
|
|
257
271
|
mirrorPrimaryKey: n.mirrorPrimaryKey ?? "id"
|
|
258
272
|
};
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
273
|
+
if (n.batch !== !1) {
|
|
274
|
+
let e = n.batch ?? {};
|
|
275
|
+
i.batcher = b(i, {
|
|
276
|
+
maxSize: e.maxSize ?? k,
|
|
277
|
+
flushIntervalMs: e.flushIntervalMs ?? A
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
263
281
|
kind: "clickhouse",
|
|
264
282
|
build: (e) => O(i),
|
|
265
283
|
initialize: () => t.gen(function* () {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/plugin-clickhouse",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "ClickHouse AnalyticsSink. Native HTTP ingest into a ClickHouse cluster — self-hosted OR ClickHouse Cloud. Production-grade OLAP for high-cardinality events with millisecond aggregate queries over billions of rows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@clickhouse/client": "^1.23.1",
|
|
37
|
-
"@voltro/logger": "0.
|
|
38
|
-
"@voltro/runtime": "0.
|
|
37
|
+
"@voltro/logger": "0.35.0",
|
|
38
|
+
"@voltro/runtime": "0.35.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"effect": "^3.22.0"
|