@rotorsoft/act-pg 1.13.0 → 1.13.1
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/.tsbuildinfo +1 -1
- package/dist/@types/postgres-store.d.ts.map +1 -1
- package/dist/index.cjs +63 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +63 -46
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -439,16 +439,13 @@ var PostgresStore = class {
|
|
|
439
439
|
async commit(stream, msgs, meta, expectedVersion) {
|
|
440
440
|
if (msgs.length === 0) return [];
|
|
441
441
|
const client = await this._client("commit");
|
|
442
|
-
let version = -1;
|
|
443
442
|
try {
|
|
444
|
-
await client.query("BEGIN");
|
|
445
443
|
const last = await client.query(
|
|
446
|
-
`SELECT version
|
|
447
|
-
|
|
448
|
-
WHERE stream=$1 ORDER BY version DESC LIMIT 1`,
|
|
444
|
+
`SELECT version FROM ${this._fqt}
|
|
445
|
+
WHERE stream=$1 ORDER BY version DESC LIMIT 1`,
|
|
449
446
|
[stream]
|
|
450
447
|
);
|
|
451
|
-
version = last.
|
|
448
|
+
let version = last.rows.at(0)?.version ?? -1;
|
|
452
449
|
if (typeof expectedVersion === "number" && version !== expectedVersion)
|
|
453
450
|
throw new import_act.ConcurrencyError(
|
|
454
451
|
stream,
|
|
@@ -456,52 +453,69 @@ var PostgresStore = class {
|
|
|
456
453
|
msgs,
|
|
457
454
|
expectedVersion
|
|
458
455
|
);
|
|
459
|
-
const
|
|
456
|
+
const base_version = version;
|
|
457
|
+
const names = [];
|
|
458
|
+
const datas = [];
|
|
459
|
+
const piis = [];
|
|
460
|
+
const versions = [];
|
|
460
461
|
for (const { name, data, pii } of msgs) {
|
|
461
462
|
version++;
|
|
462
|
-
|
|
463
|
+
names.push(name);
|
|
464
|
+
datas.push(JSON.stringify(data));
|
|
465
|
+
piis.push(
|
|
466
|
+
this._resolve_pii_key && pii != null ? JSON.stringify(await (0, import_act_crypto.encrypt)(pii, this._resolve_pii_key)) : pii != null ? JSON.stringify(pii) : null
|
|
467
|
+
);
|
|
468
|
+
versions.push(version);
|
|
469
|
+
}
|
|
470
|
+
const insert_select = msgs.length === 1 ? `SELECT $1, $2::jsonb, $3::jsonb, $5, $4::int, $6 FROM l` : `SELECT u.name, u.data::jsonb, u.pii::jsonb, $5, u.version, $6
|
|
471
|
+
FROM l, unnest($1::text[], $2::text[], $3::text[], $4::int[])
|
|
472
|
+
WITH ORDINALITY AS u(name, data, pii, version, ord)
|
|
473
|
+
ORDER BY u.ord`;
|
|
474
|
+
const notify_ctes = this.config.notify ? `,
|
|
475
|
+
payload AS (
|
|
476
|
+
SELECT json_build_object(
|
|
477
|
+
'stream', $5::text,
|
|
478
|
+
'events', json_agg(json_build_object('id', ins.id, 'name', ins.name) ORDER BY ins.version),
|
|
479
|
+
'by', $9::text
|
|
480
|
+
)::text AS p
|
|
481
|
+
FROM ins
|
|
482
|
+
),
|
|
483
|
+
n AS (
|
|
484
|
+
SELECT pg_notify($8, payload.p) FROM payload
|
|
485
|
+
WHERE octet_length(payload.p) < $10
|
|
486
|
+
)` : "";
|
|
487
|
+
const final_select = this.config.notify ? "SELECT ins.* FROM ins LEFT JOIN n ON true ORDER BY ins.version" : "SELECT * FROM ins ORDER BY version";
|
|
488
|
+
const sql = `WITH l AS (SELECT pg_advisory_xact_lock(hashtext($7))),
|
|
489
|
+
ins AS (
|
|
463
490
|
INSERT INTO ${this._fqt}(name, data, pii, stream, version, meta)
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
stream,
|
|
479
|
-
version - 1,
|
|
480
|
-
msgs,
|
|
481
|
-
expectedVersion ?? -1
|
|
482
|
-
);
|
|
491
|
+
${insert_select}
|
|
492
|
+
RETURNING *
|
|
493
|
+
)${notify_ctes}
|
|
494
|
+
${final_select}`;
|
|
495
|
+
const base_params = msgs.length === 1 ? [names[0], datas[0], piis[0], versions[0], stream, meta, this._fqt] : [names, datas, piis, versions, stream, meta, this._fqt];
|
|
496
|
+
const params = this.config.notify ? [...base_params, this._channel, this._by, NOTIFY_MAX_PAYLOAD_BYTES] : base_params;
|
|
497
|
+
try {
|
|
498
|
+
const { rows } = await client.query(sql, params);
|
|
499
|
+
if (this._resolve_pii_key) {
|
|
500
|
+
for (const row of rows) {
|
|
501
|
+
if (typeof row.pii === "string") {
|
|
502
|
+
const decrypted = await (0, import_act_crypto.decrypt)(row.pii, this._resolve_pii_key);
|
|
503
|
+
row.pii = decrypted;
|
|
504
|
+
}
|
|
483
505
|
}
|
|
484
|
-
throw error;
|
|
485
506
|
}
|
|
507
|
+
return rows;
|
|
508
|
+
} catch (error) {
|
|
509
|
+
if (error?.code === PG_UNIQUE_VIOLATION) {
|
|
510
|
+
throw new import_act.ConcurrencyError(
|
|
511
|
+
stream,
|
|
512
|
+
base_version,
|
|
513
|
+
msgs,
|
|
514
|
+
expectedVersion ?? -1
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
throw error;
|
|
486
518
|
}
|
|
487
|
-
if (this.config.notify) {
|
|
488
|
-
const payload = JSON.stringify({
|
|
489
|
-
stream,
|
|
490
|
-
events: committed.map((c) => ({ id: c.id, name: c.name })),
|
|
491
|
-
by: this._by
|
|
492
|
-
});
|
|
493
|
-
if (Buffer.byteLength(payload, "utf8") < NOTIFY_MAX_PAYLOAD_BYTES)
|
|
494
|
-
await client.query(`SELECT pg_notify($1, $2)`, [
|
|
495
|
-
this._channel,
|
|
496
|
-
payload
|
|
497
|
-
]);
|
|
498
|
-
}
|
|
499
|
-
await client.query("COMMIT");
|
|
500
|
-
return committed;
|
|
501
|
-
} catch (error) {
|
|
502
|
-
await client.query("ROLLBACK").catch(() => {
|
|
503
|
-
});
|
|
504
|
-
throw error;
|
|
505
519
|
} finally {
|
|
506
520
|
client.release();
|
|
507
521
|
}
|
|
@@ -1240,6 +1254,9 @@ var PostgresStore = class {
|
|
|
1240
1254
|
const client = await this._client("truncate");
|
|
1241
1255
|
try {
|
|
1242
1256
|
await client.query("BEGIN");
|
|
1257
|
+
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1258
|
+
this._fqt
|
|
1259
|
+
]);
|
|
1243
1260
|
const result = /* @__PURE__ */ new Map();
|
|
1244
1261
|
if (full.length) {
|
|
1245
1262
|
await client.query(`DELETE FROM ${this._fqs} WHERE stream = ANY($1)`, [
|