@rocicorp/zero 0.18.2025032001 → 0.18.2025032100
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/out/{chunk-B3PB7LRC.js → chunk-KK323M6P.js} +12 -4
- package/out/{chunk-B3PB7LRC.js.map → chunk-KK323M6P.js.map} +2 -2
- package/out/solid.js +1 -1
- package/out/zero-cache/src/scripts/deploy-permissions.js +9 -3
- package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
- package/out/zero-cache/src/scripts/permissions.d.ts +5 -1
- package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
- package/out/zero-cache/src/scripts/permissions.js +6 -2
- package/out/zero-cache/src/scripts/permissions.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +1 -1
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +3 -3
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +35 -117
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.d.ts +18 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js +75 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.d.ts +27 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js +262 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.d.ts +76 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.js +4 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +12 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +129 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/lsn.d.ts +2 -0
- package/out/zero-cache/src/services/change-source/pg/lsn.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/lsn.js +8 -2
- package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +2 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +1 -0
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +32 -0
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +3 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +14 -4
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/types/pg-types.d.ts +71 -0
- package/out/zero-cache/src/types/pg-types.d.ts.map +1 -0
- package/out/zero-cache/src/types/pg-types.js +72 -0
- package/out/zero-cache/src/types/pg-types.js.map +1 -0
- package/out/zero-cache/src/types/pg.d.ts +0 -2
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +9 -38
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts +3 -2
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +18 -10
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-pg/src/custom.d.ts +1 -1
- package/out/zero-pg/src/custom.d.ts.map +1 -1
- package/out/zero-pg/src/custom.js +3 -6
- package/out/zero-pg/src/custom.js.map +1 -1
- package/out/zero-pg/src/web.d.ts +7 -4
- package/out/zero-pg/src/web.d.ts.map +1 -1
- package/out/zero-pg/src/web.js +10 -13
- package/out/zero-pg/src/web.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +51 -0
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js +8 -0
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero.js +1 -1
- package/package.json +1 -5
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Forked from https://github.com/kibae/pg-logical-replication/blob/c55abddc62eadd61bd38922037ecb7a1469fa8c3/src/output-plugins/pgoutput/binary-reader.ts
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
// should not use { fatal: true } because ErrorResponse can use invalid utf8 chars
|
|
4
|
+
const textDecoder = new TextDecoder();
|
|
5
|
+
// https://www.postgresql.org/docs/14/protocol-message-types.html
|
|
6
|
+
export class BinaryReader {
|
|
7
|
+
_b;
|
|
8
|
+
_p = 0;
|
|
9
|
+
constructor(_b) {
|
|
10
|
+
this._b = _b;
|
|
11
|
+
}
|
|
12
|
+
readUint8() {
|
|
13
|
+
this.checkSize(1);
|
|
14
|
+
return this._b[this._p++];
|
|
15
|
+
}
|
|
16
|
+
readInt16() {
|
|
17
|
+
this.checkSize(2);
|
|
18
|
+
return (this._b[this._p++] << 8) | this._b[this._p++];
|
|
19
|
+
}
|
|
20
|
+
readInt32() {
|
|
21
|
+
this.checkSize(4);
|
|
22
|
+
return ((this._b[this._p++] << 24) |
|
|
23
|
+
(this._b[this._p++] << 16) |
|
|
24
|
+
(this._b[this._p++] << 8) |
|
|
25
|
+
this._b[this._p++]);
|
|
26
|
+
}
|
|
27
|
+
readString() {
|
|
28
|
+
const endIdx = this._b.indexOf(0x00, this._p);
|
|
29
|
+
if (endIdx < 0) {
|
|
30
|
+
// TODO PgError.protocol_violation
|
|
31
|
+
throw Error('unexpected end of message');
|
|
32
|
+
}
|
|
33
|
+
const strBuf = this._b.subarray(this._p, endIdx);
|
|
34
|
+
this._p = endIdx + 1;
|
|
35
|
+
return this.decodeText(strBuf);
|
|
36
|
+
}
|
|
37
|
+
decodeText(strBuf) {
|
|
38
|
+
return textDecoder.decode(strBuf);
|
|
39
|
+
}
|
|
40
|
+
read(n) {
|
|
41
|
+
this.checkSize(n);
|
|
42
|
+
return this._b.subarray(this._p, (this._p += n));
|
|
43
|
+
}
|
|
44
|
+
checkSize(n) {
|
|
45
|
+
if (this._b.length < this._p + n) {
|
|
46
|
+
// TODO PgError.protocol_violation
|
|
47
|
+
throw Error('unexpected end of message');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
array(length, fn) {
|
|
51
|
+
return Array.from({ length }, fn, this);
|
|
52
|
+
}
|
|
53
|
+
// replication helpers
|
|
54
|
+
readLsn() {
|
|
55
|
+
const h = this.readUint32();
|
|
56
|
+
const l = this.readUint32();
|
|
57
|
+
if (h === 0 && l === 0) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return `${h.toString(16).padStart(8, '0')}/${l
|
|
61
|
+
.toString(16)
|
|
62
|
+
.padStart(8, '0')}`.toUpperCase();
|
|
63
|
+
}
|
|
64
|
+
readTime() {
|
|
65
|
+
// (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * USECS_PER_DAY == 946684800000000
|
|
66
|
+
return this.readUint64() + BigInt('946684800000000');
|
|
67
|
+
}
|
|
68
|
+
readUint64() {
|
|
69
|
+
return ((BigInt(this.readUint32()) << BigInt(32)) | BigInt(this.readUint32()));
|
|
70
|
+
}
|
|
71
|
+
readUint32() {
|
|
72
|
+
return this.readInt32() >>> 0;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=binary-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-reader.js","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/binary-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type TypeParser = (val: string) => unknown;
|
|
2
|
+
import type { Message, MessageRelation } from './pgoutput.types.ts';
|
|
3
|
+
export declare class PgoutputParser {
|
|
4
|
+
#private;
|
|
5
|
+
_typeCache: Map<number, {
|
|
6
|
+
typeSchema: string;
|
|
7
|
+
typeName: string;
|
|
8
|
+
}>;
|
|
9
|
+
_relationCache: Map<number, MessageRelation>;
|
|
10
|
+
constructor(typeParsers: Record<number, TypeParser>);
|
|
11
|
+
parse(buf: Buffer): Message;
|
|
12
|
+
private msgBegin;
|
|
13
|
+
private msgOrigin;
|
|
14
|
+
private msgType;
|
|
15
|
+
private msgRelation;
|
|
16
|
+
private readRelationReplicaIdentity;
|
|
17
|
+
private readRelationColumn;
|
|
18
|
+
private msgInsert;
|
|
19
|
+
private msgUpdate;
|
|
20
|
+
private msgDelete;
|
|
21
|
+
private readKeyTuple;
|
|
22
|
+
private readTuple;
|
|
23
|
+
private msgTruncate;
|
|
24
|
+
private msgMessage;
|
|
25
|
+
private msgCommit;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=pgoutput-parser.d.ts.map
|
package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pgoutput-parser.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;AAGlD,OAAO,KAAK,EACV,OAAO,EAOP,eAAe,EAKhB,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,cAAc;;IACzB,UAAU;oBAAgC,MAAM;kBAAY,MAAM;OAAK;IACvE,cAAc,+BAAsC;gBAIxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;IAW5C,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IA8BlC,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,WAAW;IA4BnB,OAAO,CAAC,2BAA2B;IAkBnC,OAAO,CAAC,kBAAkB;IAmB1B,OAAO,CAAC,SAAS;IAgBjB,OAAO,CAAC,SAAS;IA6BjB,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,SAAS;IAwCjB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,SAAS;CASlB"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// Forked from https://github.com/kibae/pg-logical-replication/blob/c55abddc62eadd61bd38922037ecb7a1469fa8c3/src/output-plugins/pgoutput/pgoutput-parser.ts
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
import { BinaryReader } from "./binary-reader.js";
|
|
4
|
+
export class PgoutputParser {
|
|
5
|
+
_typeCache = new Map();
|
|
6
|
+
_relationCache = new Map();
|
|
7
|
+
// Replaces "pg-types" library.
|
|
8
|
+
#typeParsers;
|
|
9
|
+
constructor(typeParsers) {
|
|
10
|
+
this.#typeParsers = typeParsers;
|
|
11
|
+
}
|
|
12
|
+
#getTypeParser(typeOid) {
|
|
13
|
+
// The absence of a TypeParser defaults to "noParse", mimicking
|
|
14
|
+
// the behavior in pg-types:
|
|
15
|
+
// https://github.com/brianc/node-pg-types/blob/5b26b826466cff4a9092b8c9e31960fe293ef3d9/index.js#L15
|
|
16
|
+
return this.#typeParsers[typeOid] ?? String;
|
|
17
|
+
}
|
|
18
|
+
// Replaced "pg-types" library.
|
|
19
|
+
parse(buf) {
|
|
20
|
+
const reader = new BinaryReader(buf);
|
|
21
|
+
const tag = reader.readUint8();
|
|
22
|
+
switch (tag) {
|
|
23
|
+
case 0x42 /*B*/:
|
|
24
|
+
return this.msgBegin(reader);
|
|
25
|
+
case 0x4f /*O*/:
|
|
26
|
+
return this.msgOrigin(reader);
|
|
27
|
+
case 0x59 /*Y*/:
|
|
28
|
+
return this.msgType(reader);
|
|
29
|
+
case 0x52 /*R*/:
|
|
30
|
+
return this.msgRelation(reader);
|
|
31
|
+
case 0x49 /*I*/:
|
|
32
|
+
return this.msgInsert(reader);
|
|
33
|
+
case 0x55 /*U*/:
|
|
34
|
+
return this.msgUpdate(reader);
|
|
35
|
+
case 0x44 /*D*/:
|
|
36
|
+
return this.msgDelete(reader);
|
|
37
|
+
case 0x54 /*T*/:
|
|
38
|
+
return this.msgTruncate(reader);
|
|
39
|
+
case 0x4d /*M*/:
|
|
40
|
+
return this.msgMessage(reader);
|
|
41
|
+
case 0x43 /*C*/:
|
|
42
|
+
return this.msgCommit(reader);
|
|
43
|
+
default:
|
|
44
|
+
throw Error('unknown pgoutput message');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
msgBegin(reader) {
|
|
48
|
+
// TODO lsn can be null if origin sended
|
|
49
|
+
// https://github.com/postgres/postgres/blob/85c61ba8920ba73500e1518c63795982ee455d14/src/backend/replication/pgoutput/pgoutput.c#L409
|
|
50
|
+
// https://github.com/postgres/postgres/blob/27b77ecf9f4d5be211900eda54d8155ada50d696/src/include/replication/reorderbuffer.h#L275
|
|
51
|
+
return {
|
|
52
|
+
tag: 'begin',
|
|
53
|
+
commitLsn: reader.readLsn(),
|
|
54
|
+
commitTime: reader.readTime(),
|
|
55
|
+
xid: reader.readInt32(),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
msgOrigin(reader) {
|
|
59
|
+
return {
|
|
60
|
+
tag: 'origin',
|
|
61
|
+
originLsn: reader.readLsn(),
|
|
62
|
+
originName: reader.readString(),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
msgType(reader) {
|
|
66
|
+
const typeOid = reader.readInt32();
|
|
67
|
+
const typeSchema = reader.readString();
|
|
68
|
+
const typeName = reader.readString();
|
|
69
|
+
// mem leak not likely to happen because amount of types is usually small
|
|
70
|
+
this._typeCache.set(typeOid, { typeSchema, typeName });
|
|
71
|
+
return { tag: 'type', typeOid, typeSchema, typeName };
|
|
72
|
+
}
|
|
73
|
+
msgRelation(reader) {
|
|
74
|
+
// lsn expected to be null
|
|
75
|
+
// https://github.com/postgres/postgres/blob/27b77ecf9f4d5be211900eda54d8155ada50d696/src/backend/replication/walsender.c#L1342
|
|
76
|
+
const relationOid = reader.readInt32();
|
|
77
|
+
const schema = reader.readString();
|
|
78
|
+
const name = reader.readString();
|
|
79
|
+
const replicaIdentity = this.readRelationReplicaIdentity(reader);
|
|
80
|
+
const columns = reader.array(reader.readInt16(), () => this.readRelationColumn(reader));
|
|
81
|
+
const keyColumns = columns.filter(it => it.flags & 0b1).map(it => it.name);
|
|
82
|
+
const msg = {
|
|
83
|
+
tag: 'relation',
|
|
84
|
+
relationOid,
|
|
85
|
+
schema,
|
|
86
|
+
name,
|
|
87
|
+
replicaIdentity,
|
|
88
|
+
columns,
|
|
89
|
+
keyColumns,
|
|
90
|
+
};
|
|
91
|
+
// mem leak not likely to happen because amount of relations is usually small
|
|
92
|
+
this._relationCache.set(relationOid, msg);
|
|
93
|
+
return msg;
|
|
94
|
+
}
|
|
95
|
+
readRelationReplicaIdentity(reader) {
|
|
96
|
+
// https://www.postgresql.org/docs/14/catalog-pg-class.html
|
|
97
|
+
const ident = reader.readUint8();
|
|
98
|
+
switch (ident) {
|
|
99
|
+
case 0x64 /*d*/:
|
|
100
|
+
return 'default';
|
|
101
|
+
case 0x6e /*n*/:
|
|
102
|
+
return 'nothing';
|
|
103
|
+
case 0x66 /*f*/:
|
|
104
|
+
return 'full';
|
|
105
|
+
case 0x69 /*i*/:
|
|
106
|
+
return 'index';
|
|
107
|
+
default:
|
|
108
|
+
throw Error(`unknown replica identity ${String.fromCharCode(ident)}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
readRelationColumn(reader) {
|
|
112
|
+
const flags = reader.readUint8();
|
|
113
|
+
const name = reader.readString();
|
|
114
|
+
const typeOid = reader.readInt32();
|
|
115
|
+
const typeMod = reader.readInt32();
|
|
116
|
+
return {
|
|
117
|
+
flags,
|
|
118
|
+
name,
|
|
119
|
+
typeOid,
|
|
120
|
+
typeMod,
|
|
121
|
+
typeSchema: null,
|
|
122
|
+
typeName: null, // TODO resolve builtin type names?
|
|
123
|
+
...this._typeCache.get(typeOid),
|
|
124
|
+
// parser: types.getTypeParser(typeOid),
|
|
125
|
+
parser: this.#getTypeParser(typeOid),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
msgInsert(reader) {
|
|
129
|
+
const relation = this._relationCache.get(reader.readInt32());
|
|
130
|
+
if (!relation) {
|
|
131
|
+
throw Error('missing relation');
|
|
132
|
+
}
|
|
133
|
+
reader.readUint8(); // consume the 'N' key
|
|
134
|
+
return {
|
|
135
|
+
tag: 'insert',
|
|
136
|
+
relation,
|
|
137
|
+
new: this.readTuple(reader, relation),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
msgUpdate(reader) {
|
|
141
|
+
const relation = this._relationCache.get(reader.readInt32());
|
|
142
|
+
if (!relation) {
|
|
143
|
+
throw Error('missing relation');
|
|
144
|
+
}
|
|
145
|
+
let key = null;
|
|
146
|
+
let old = null;
|
|
147
|
+
let new_ = null;
|
|
148
|
+
const subMsgKey = reader.readUint8();
|
|
149
|
+
if (subMsgKey === 0x4b /*K*/) {
|
|
150
|
+
key = this.readKeyTuple(reader, relation);
|
|
151
|
+
reader.readUint8(); // consume the 'N' key
|
|
152
|
+
new_ = this.readTuple(reader, relation);
|
|
153
|
+
}
|
|
154
|
+
else if (subMsgKey === 0x4f /*O*/) {
|
|
155
|
+
old = this.readTuple(reader, relation);
|
|
156
|
+
reader.readUint8(); // consume the 'N' key
|
|
157
|
+
new_ = this.readTuple(reader, relation, old);
|
|
158
|
+
}
|
|
159
|
+
else if (subMsgKey === 0x4e /*N*/) {
|
|
160
|
+
new_ = this.readTuple(reader, relation);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
throw Error(`unknown submessage key ${String.fromCharCode(subMsgKey)}`);
|
|
164
|
+
}
|
|
165
|
+
return { tag: 'update', relation, key, old, new: new_ };
|
|
166
|
+
}
|
|
167
|
+
msgDelete(reader) {
|
|
168
|
+
const relation = this._relationCache.get(reader.readInt32());
|
|
169
|
+
if (!relation) {
|
|
170
|
+
throw Error('missing relation');
|
|
171
|
+
}
|
|
172
|
+
let key = null;
|
|
173
|
+
let old = null;
|
|
174
|
+
const subMsgKey = reader.readUint8();
|
|
175
|
+
if (subMsgKey === 0x4b /*K*/) {
|
|
176
|
+
key = this.readKeyTuple(reader, relation);
|
|
177
|
+
}
|
|
178
|
+
else if (subMsgKey === 0x4f /*O*/) {
|
|
179
|
+
old = this.readTuple(reader, relation);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
throw Error(`unknown submessage key ${String.fromCharCode(subMsgKey)}`);
|
|
183
|
+
}
|
|
184
|
+
return { tag: 'delete', relation, key, old };
|
|
185
|
+
}
|
|
186
|
+
readKeyTuple(reader, relation) {
|
|
187
|
+
const tuple = this.readTuple(reader, relation);
|
|
188
|
+
const key = Object.create(null);
|
|
189
|
+
for (const k of relation.keyColumns) {
|
|
190
|
+
// If value is `null`, then it is definitely not part of key,
|
|
191
|
+
// because key cannot have nulls by documentation.
|
|
192
|
+
// And if we got `null` while reading keyOnly tuple,
|
|
193
|
+
// then it means that `null` is not actual value
|
|
194
|
+
// but placeholder of non-key column.
|
|
195
|
+
key[k] = tuple[k] === null ? undefined : tuple[k];
|
|
196
|
+
}
|
|
197
|
+
return key;
|
|
198
|
+
}
|
|
199
|
+
readTuple(reader, { columns }, unchangedToastFallback) {
|
|
200
|
+
const nfields = reader.readInt16();
|
|
201
|
+
const tuple = Object.create(null);
|
|
202
|
+
for (let i = 0; i < nfields; i++) {
|
|
203
|
+
const { name, parser } = columns[i];
|
|
204
|
+
const kind = reader.readUint8();
|
|
205
|
+
switch (kind) {
|
|
206
|
+
case 0x62: // 'b' binary
|
|
207
|
+
const bsize = reader.readInt32();
|
|
208
|
+
const bval = reader.read(bsize);
|
|
209
|
+
// dont need to .slice() because new buffer
|
|
210
|
+
// is created for each replication chunk
|
|
211
|
+
tuple[name] = bval;
|
|
212
|
+
break;
|
|
213
|
+
case 0x74: // 't' text
|
|
214
|
+
const valsize = reader.readInt32();
|
|
215
|
+
const valbuf = reader.read(valsize);
|
|
216
|
+
const valtext = reader.decodeText(valbuf);
|
|
217
|
+
tuple[name] = parser(valtext);
|
|
218
|
+
break;
|
|
219
|
+
case 0x6e: // 'n' null
|
|
220
|
+
tuple[name] = null;
|
|
221
|
+
break;
|
|
222
|
+
case 0x75: // 'u' unchanged toast datum
|
|
223
|
+
tuple[name] = unchangedToastFallback?.[name];
|
|
224
|
+
break;
|
|
225
|
+
default:
|
|
226
|
+
throw Error(`unknown attribute kind ${String.fromCharCode(kind)}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return tuple;
|
|
230
|
+
}
|
|
231
|
+
msgTruncate(reader) {
|
|
232
|
+
const nrels = reader.readInt32();
|
|
233
|
+
const flags = reader.readUint8();
|
|
234
|
+
return {
|
|
235
|
+
tag: 'truncate',
|
|
236
|
+
cascade: Boolean(flags & 0b1),
|
|
237
|
+
restartIdentity: Boolean(flags & 0b10),
|
|
238
|
+
relations: reader.array(nrels, () => this._relationCache.get(reader.readInt32())),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
msgMessage(reader) {
|
|
242
|
+
const flags = reader.readUint8();
|
|
243
|
+
return {
|
|
244
|
+
tag: 'message',
|
|
245
|
+
flags,
|
|
246
|
+
transactional: Boolean(flags & 0b1),
|
|
247
|
+
messageLsn: reader.readLsn(),
|
|
248
|
+
prefix: reader.readString(),
|
|
249
|
+
content: reader.read(reader.readInt32()),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
msgCommit(reader) {
|
|
253
|
+
return {
|
|
254
|
+
tag: 'commit',
|
|
255
|
+
flags: reader.readUint8(), // reserved unused
|
|
256
|
+
commitLsn: reader.readLsn(), // should be the same as begin.commitLsn
|
|
257
|
+
commitEndLsn: reader.readLsn(),
|
|
258
|
+
commitTime: reader.readTime(),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=pgoutput-parser.js.map
|
package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pgoutput-parser.js","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export type Message = MessageBegin | MessageCommit | MessageDelete | MessageInsert | MessageMessage | MessageOrigin | MessageRelation | MessageTruncate | MessageType | MessageUpdate;
|
|
2
|
+
export interface MessageBegin {
|
|
3
|
+
tag: 'begin';
|
|
4
|
+
commitLsn: string | null;
|
|
5
|
+
commitTime: bigint;
|
|
6
|
+
xid: number;
|
|
7
|
+
}
|
|
8
|
+
export interface MessageCommit {
|
|
9
|
+
tag: 'commit';
|
|
10
|
+
flags: number;
|
|
11
|
+
commitLsn: string | null;
|
|
12
|
+
commitEndLsn: string | null;
|
|
13
|
+
commitTime: bigint;
|
|
14
|
+
}
|
|
15
|
+
export interface MessageDelete {
|
|
16
|
+
tag: 'delete';
|
|
17
|
+
relation: MessageRelation;
|
|
18
|
+
key: Record<string, any> | null;
|
|
19
|
+
old: Record<string, any> | null;
|
|
20
|
+
}
|
|
21
|
+
export interface MessageInsert {
|
|
22
|
+
tag: 'insert';
|
|
23
|
+
relation: MessageRelation;
|
|
24
|
+
new: Record<string, any>;
|
|
25
|
+
}
|
|
26
|
+
export interface MessageMessage {
|
|
27
|
+
tag: 'message';
|
|
28
|
+
flags: number;
|
|
29
|
+
transactional: boolean;
|
|
30
|
+
messageLsn: string | null;
|
|
31
|
+
prefix: string;
|
|
32
|
+
content: Uint8Array;
|
|
33
|
+
}
|
|
34
|
+
export interface MessageOrigin {
|
|
35
|
+
tag: 'origin';
|
|
36
|
+
originLsn: string | null;
|
|
37
|
+
originName: string;
|
|
38
|
+
}
|
|
39
|
+
export interface MessageRelation {
|
|
40
|
+
tag: 'relation';
|
|
41
|
+
relationOid: number;
|
|
42
|
+
schema: string;
|
|
43
|
+
name: string;
|
|
44
|
+
replicaIdentity: 'default' | 'nothing' | 'full' | 'index';
|
|
45
|
+
columns: RelationColumn[];
|
|
46
|
+
keyColumns: string[];
|
|
47
|
+
}
|
|
48
|
+
export interface RelationColumn {
|
|
49
|
+
name: string;
|
|
50
|
+
flags: number;
|
|
51
|
+
typeOid: number;
|
|
52
|
+
typeMod: number;
|
|
53
|
+
typeSchema: string | null;
|
|
54
|
+
typeName: string | null;
|
|
55
|
+
parser: (raw: any) => any;
|
|
56
|
+
}
|
|
57
|
+
export interface MessageTruncate {
|
|
58
|
+
tag: 'truncate';
|
|
59
|
+
cascade: boolean;
|
|
60
|
+
restartIdentity: boolean;
|
|
61
|
+
relations: MessageRelation[];
|
|
62
|
+
}
|
|
63
|
+
export interface MessageType {
|
|
64
|
+
tag: 'type';
|
|
65
|
+
typeOid: number;
|
|
66
|
+
typeSchema: string;
|
|
67
|
+
typeName: string;
|
|
68
|
+
}
|
|
69
|
+
export interface MessageUpdate {
|
|
70
|
+
tag: 'update';
|
|
71
|
+
relation: MessageRelation;
|
|
72
|
+
key: Record<string, any> | null;
|
|
73
|
+
old: Record<string, any> | null;
|
|
74
|
+
new: Record<string, any>;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=pgoutput.types.d.ts.map
|
package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pgoutput.types.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.ts"],"names":[],"mappings":"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"}
|
package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pgoutput.types.js","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.ts"],"names":[],"mappings":"AAAA,0JAA0J;AAC1J,uDAAuD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LogContext } from '@rocicorp/logger';
|
|
2
|
+
import { type PostgresDB } from '../../../../types/pg.ts';
|
|
3
|
+
import { type Sink, type Source } from '../../../../types/streams.ts';
|
|
4
|
+
import type { Message } from './pgoutput.types.ts';
|
|
5
|
+
export type StreamMessage = [lsn: bigint, Message | {
|
|
6
|
+
tag: 'keepalive';
|
|
7
|
+
}];
|
|
8
|
+
export declare function subscribe(lc: LogContext, db: PostgresDB, slot: string, publications: string[], lsn: bigint, retriesIfReplicationSlotActive?: number, applicationName?: string): Promise<{
|
|
9
|
+
messages: Source<StreamMessage>;
|
|
10
|
+
acks: Sink<bigint>;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/stream.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAMjD,OAAO,EAAC,KAAK,UAAU,EAAC,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAO,KAAK,IAAI,EAAE,KAAK,MAAM,EAAC,MAAM,8BAA8B,CAAC;AAI1E,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,qBAAqB,CAAC;AAIjD,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAG;IAAC,GAAG,EAAE,WAAW,CAAA;CAAC,CAAC,CAAC;AAExE,wBAAsB,SAAS,CAC7B,EAAE,EAAE,UAAU,EACd,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,EACtB,GAAG,EAAE,MAAM,EACX,8BAA8B,SAA6C,EAC3E,eAAe,SAAoB,GAClC,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;CAAC,CAAC,CA6ChE"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { PG_OBJECT_IN_USE } from '@drdgvhbh/postgres-error-codes';
|
|
2
|
+
import { defu } from 'defu';
|
|
3
|
+
import postgres, {} from 'postgres';
|
|
4
|
+
import { assert } from "../../../../../../shared/src/asserts.js";
|
|
5
|
+
import { mapValues } from "../../../../../../shared/src/objects.js";
|
|
6
|
+
import { sleep } from "../../../../../../shared/src/sleep.js";
|
|
7
|
+
import {} from "../../../../types/pg.js";
|
|
8
|
+
import { pipe } from "../../../../types/streams.js";
|
|
9
|
+
import { Subscription } from "../../../../types/subscription.js";
|
|
10
|
+
import { fromBigInt } from "../lsn.js";
|
|
11
|
+
import { PgoutputParser } from "./pgoutput-parser.js";
|
|
12
|
+
const DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE = 5;
|
|
13
|
+
export async function subscribe(lc, db, slot, publications, lsn, retriesIfReplicationSlotActive = DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE, applicationName = 'zero-replicator') {
|
|
14
|
+
const session = postgres(defu({
|
|
15
|
+
max: 1,
|
|
16
|
+
['fetch_types']: false, // Necessary for the streaming protocol
|
|
17
|
+
['idle_timeout']: null,
|
|
18
|
+
['max_lifetime']: null,
|
|
19
|
+
connection: {
|
|
20
|
+
['application_name']: applicationName,
|
|
21
|
+
replication: 'database', // https://www.postgresql.org/docs/current/protocol-replication.html
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
// ParsedOptions are technically compatible with Options, but happen
|
|
25
|
+
// to not be typed that way. The postgres.js author does an equivalent
|
|
26
|
+
// merge of ParsedOptions and Options here:
|
|
27
|
+
// https://github.com/porsager/postgres/blob/089214e85c23c90cf142d47fb30bd03f42874984/src/subscribe.js#L13
|
|
28
|
+
db.options));
|
|
29
|
+
const [readable, writable] = await startReplicationStream(lc, session, slot, publications, lsn, retriesIfReplicationSlotActive + 1);
|
|
30
|
+
const typeParsers = await getTypeParsers(lc, db);
|
|
31
|
+
const parser = new PgoutputParser(typeParsers);
|
|
32
|
+
const messages = Subscription.create({
|
|
33
|
+
cleanup: () => {
|
|
34
|
+
readable.destroyed || readable.destroy();
|
|
35
|
+
return session.end();
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
pipe(readable, messages, buffer => parseStreamMessage(lc, buffer, parser));
|
|
39
|
+
return {
|
|
40
|
+
messages,
|
|
41
|
+
acks: { push: (lsn) => writable.write(makeAck(lsn)) },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async function startReplicationStream(lc, session, slot, publications, lsn, maxAttempts) {
|
|
45
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
46
|
+
try {
|
|
47
|
+
const stream = session
|
|
48
|
+
.unsafe(`START_REPLICATION SLOT "${slot}" LOGICAL ${fromBigInt(lsn)} (
|
|
49
|
+
proto_version '1',
|
|
50
|
+
publication_names '${publications}',
|
|
51
|
+
messages 'true'
|
|
52
|
+
)`)
|
|
53
|
+
.execute();
|
|
54
|
+
return await Promise.all([stream.readable(), stream.writable()]);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
if (
|
|
58
|
+
// error: replication slot "zero_slot_change_source_test_id" is active for PID 268
|
|
59
|
+
e instanceof postgres.PostgresError &&
|
|
60
|
+
e.code === PG_OBJECT_IN_USE) {
|
|
61
|
+
// The freeing up of the replication slot is not transactional;
|
|
62
|
+
// sometimes it takes time for Postgres to consider the slot
|
|
63
|
+
// inactive.
|
|
64
|
+
lc.warn?.(`attempt ${i + 1}: ${String(e)}`, e);
|
|
65
|
+
await sleep(10);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
throw new Error(`exceeded max attempts (${maxAttempts}) to start the Postgres stream`);
|
|
73
|
+
}
|
|
74
|
+
function parseStreamMessage(lc, buffer, parser) {
|
|
75
|
+
// https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-XLOGDATA
|
|
76
|
+
if (buffer[0] !== 0x77 && buffer[0] !== 0x6b) {
|
|
77
|
+
lc.warn?.('Unknown message', buffer[0]);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const lsn = buffer.readBigUInt64BE(1);
|
|
81
|
+
return buffer[0] === 0x77 // XLogData
|
|
82
|
+
? [lsn, parser.parse(buffer.subarray(25))]
|
|
83
|
+
: buffer.readInt8(17) // Primary keepalive message: shouldRespond
|
|
84
|
+
? [lsn, { tag: 'keepalive' }]
|
|
85
|
+
: null;
|
|
86
|
+
}
|
|
87
|
+
// https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-STANDBY-STATUS-UPDATE
|
|
88
|
+
function makeAck(lsn) {
|
|
89
|
+
const microNow = BigInt(Date.now() - Date.UTC(2000, 0, 1)) * BigInt(1000);
|
|
90
|
+
const x = Buffer.alloc(34);
|
|
91
|
+
x[0] = 'r'.charCodeAt(0);
|
|
92
|
+
x.writeBigInt64BE(lsn, 1);
|
|
93
|
+
x.writeBigInt64BE(lsn, 9);
|
|
94
|
+
x.writeBigInt64BE(lsn, 17);
|
|
95
|
+
x.writeBigInt64BE(microNow, 25);
|
|
96
|
+
return x;
|
|
97
|
+
}
|
|
98
|
+
// Arbitrary array type to test if the PostgresDB client has fetched types.
|
|
99
|
+
const INT4_ARRAY_TYPE = 1007;
|
|
100
|
+
// postgres.js has default type parsers with user-defined overrides
|
|
101
|
+
// configurable per-client (see `postgresTypeConfig` in types/pg.ts).
|
|
102
|
+
//
|
|
103
|
+
// From these, the postgres.js client will automatically derive parsers
|
|
104
|
+
// for array versions of these types, provided that the client was
|
|
105
|
+
// configured with `fetch_types: true` (which is the default).
|
|
106
|
+
//
|
|
107
|
+
// A replication session (with `database: replication`), however, does
|
|
108
|
+
// not support this type fetching, so it is done on a connection from
|
|
109
|
+
// a default client.
|
|
110
|
+
async function getTypeParsers(lc, db) {
|
|
111
|
+
if (!db.options.parsers[INT4_ARRAY_TYPE]) {
|
|
112
|
+
assert(db.options.fetch_types, `Supplied db must fetch_types`);
|
|
113
|
+
lc.debug?.('fetching array types');
|
|
114
|
+
// Execute a query to ensure that fetchArrayTypes() gets executed:
|
|
115
|
+
// https://github.com/porsager/postgres/blob/089214e85c23c90cf142d47fb30bd03f42874984/src/connection.js#L536
|
|
116
|
+
await db `SELECT 1`.simple();
|
|
117
|
+
assert(db.options.parsers[INT4_ARRAY_TYPE], `array types not fetched ${Object.keys(db.options.parsers)}`);
|
|
118
|
+
}
|
|
119
|
+
return mapValues(db.options.parsers, parse => {
|
|
120
|
+
// The postgres.js library tags parsers for array types with an `array: true` field.
|
|
121
|
+
// https://github.com/porsager/postgres/blob/089214e85c23c90cf142d47fb30bd03f42874984/src/connection.js#L760
|
|
122
|
+
const isArrayType = parse.array;
|
|
123
|
+
// And then skips the first character when parsing the string,
|
|
124
|
+
// e.g. an array parser will parse '{1,2,3}' from '1,2,3}'.
|
|
125
|
+
// https://github.com/porsager/postgres/blob/089214e85c23c90cf142d47fb30bd03f42874984/src/connection.js#L496
|
|
126
|
+
return isArrayType ? (val) => parse(val.substring(1)) : parse;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,8 @@ import type { Change } from '../protocol/current/data.ts';
|
|
|
12
12
|
*/
|
|
13
13
|
export type LSN = string;
|
|
14
14
|
export type RecordType = Change['tag'];
|
|
15
|
+
export declare function toBigInt(lsn: LSN): bigint;
|
|
15
16
|
export declare function toLexiVersion(lsn: LSN): LexiVersion;
|
|
16
17
|
export declare function fromLexiVersion(lexi: LexiVersion): LSN;
|
|
18
|
+
export declare function fromBigInt(val: bigint): LSN;
|
|
17
19
|
//# sourceMappingURL=lsn.d.ts.map
|