@supalive/core 1.7.1 → 1.8.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/index-0XwMOQBo.d.ts +2110 -0
- package/dist/index-0XwMOQBo.d.ts.map +1 -0
- package/dist/index-BHwZ0TXc.d.ts +2126 -0
- package/dist/index-BHwZ0TXc.d.ts.map +1 -0
- package/dist/index-BSqGOgxz.d.ts +2126 -0
- package/dist/index-BSqGOgxz.d.ts.map +1 -0
- package/dist/index-BSvfTwmf.d.ts +2127 -0
- package/dist/index-BSvfTwmf.d.ts.map +1 -0
- package/dist/index-BX33pXeZ.d.ts +2126 -0
- package/dist/index-BX33pXeZ.d.ts.map +1 -0
- package/dist/index-B_eYxS62.d.ts +2127 -0
- package/dist/index-B_eYxS62.d.ts.map +1 -0
- package/dist/index-BbGO7Ejp.d.ts +2126 -0
- package/dist/index-BbGO7Ejp.d.ts.map +1 -0
- package/dist/index-C2ZMPgsI.d.ts +2114 -0
- package/dist/index-C2ZMPgsI.d.ts.map +1 -0
- package/dist/index-CTFFQWz1.d.ts +2126 -0
- package/dist/index-CTFFQWz1.d.ts.map +1 -0
- package/dist/index-CjOTzplF.d.ts +2126 -0
- package/dist/index-CjOTzplF.d.ts.map +1 -0
- package/dist/index-CmFZetc-.d.ts +2127 -0
- package/dist/index-CmFZetc-.d.ts.map +1 -0
- package/dist/index-Cmrr9Tec.d.ts +2126 -0
- package/dist/index-Cmrr9Tec.d.ts.map +1 -0
- package/dist/index-CqVR7zll.d.ts +2125 -0
- package/dist/index-CqVR7zll.d.ts.map +1 -0
- package/dist/index-CtHo5xAL.d.ts +2125 -0
- package/dist/index-CtHo5xAL.d.ts.map +1 -0
- package/dist/index-Ctw7txMT.d.ts +2166 -0
- package/dist/index-Ctw7txMT.d.ts.map +1 -0
- package/dist/index-Cwbbu-XP.d.ts +2166 -0
- package/dist/index-Cwbbu-XP.d.ts.map +1 -0
- package/dist/index-Cy8IkuGR.d.ts +2125 -0
- package/dist/index-Cy8IkuGR.d.ts.map +1 -0
- package/dist/index-D4_QHo7q.d.ts +2126 -0
- package/dist/index-D4_QHo7q.d.ts.map +1 -0
- package/dist/index-D87c8EVr.d.ts +2125 -0
- package/dist/index-D87c8EVr.d.ts.map +1 -0
- package/dist/index-D9vqKJO_.d.ts +2126 -0
- package/dist/index-D9vqKJO_.d.ts.map +1 -0
- package/dist/index-DJnKNJ6y.d.ts +2110 -0
- package/dist/index-DJnKNJ6y.d.ts.map +1 -0
- package/dist/index-DTPJn741.d.ts +2126 -0
- package/dist/index-DTPJn741.d.ts.map +1 -0
- package/dist/index-DeM-i96w.d.ts +2109 -0
- package/dist/index-DeM-i96w.d.ts.map +1 -0
- package/dist/index-DfMHVkVC.d.ts +2126 -0
- package/dist/index-DfMHVkVC.d.ts.map +1 -0
- package/dist/index-DgZeS3JK.d.ts +2166 -0
- package/dist/index-DgZeS3JK.d.ts.map +1 -0
- package/dist/index-DkfqkzsC.d.ts +2125 -0
- package/dist/index-DkfqkzsC.d.ts.map +1 -0
- package/dist/index-DzGkzEaO.d.ts +2126 -0
- package/dist/index-DzGkzEaO.d.ts.map +1 -0
- package/dist/index-Dzbvt3C2.d.ts +2127 -0
- package/dist/index-Dzbvt3C2.d.ts.map +1 -0
- package/dist/index-WvntPU0e.d.ts +2111 -0
- package/dist/index-WvntPU0e.d.ts.map +1 -0
- package/dist/index-YnlFOYMJ.d.ts +2127 -0
- package/dist/index-YnlFOYMJ.d.ts.map +1 -0
- package/dist/mysql-6XsvNwxp.d.ts +109 -0
- package/dist/mysql-6XsvNwxp.d.ts.map +1 -0
- package/dist/mysql-9euRTU3L.d.ts +109 -0
- package/dist/mysql-9euRTU3L.d.ts.map +1 -0
- package/dist/mysql-B2kTH1jJ.d.ts +109 -0
- package/dist/mysql-B2kTH1jJ.d.ts.map +1 -0
- package/dist/mysql-B49q-Cmk.d.ts +109 -0
- package/dist/mysql-B49q-Cmk.d.ts.map +1 -0
- package/dist/mysql-B5FzK4eP.js +602 -0
- package/dist/mysql-B5FzK4eP.js.map +1 -0
- package/dist/mysql-B94uJ3tN.js +602 -0
- package/dist/mysql-B94uJ3tN.js.map +1 -0
- package/dist/mysql-BB7xHRP5.d.ts +109 -0
- package/dist/mysql-BB7xHRP5.d.ts.map +1 -0
- package/dist/mysql-BF2gBly8.js +602 -0
- package/dist/mysql-BF2gBly8.js.map +1 -0
- package/dist/mysql-BK0abZ2z.d.ts +109 -0
- package/dist/mysql-BK0abZ2z.d.ts.map +1 -0
- package/dist/mysql-BK5D6KCY.d.ts +109 -0
- package/dist/mysql-BK5D6KCY.d.ts.map +1 -0
- package/dist/mysql-BNIwKbOq.js +602 -0
- package/dist/mysql-BNIwKbOq.js.map +1 -0
- package/dist/mysql-BNoXrafv.js +602 -0
- package/dist/mysql-BNoXrafv.js.map +1 -0
- package/dist/mysql-BPQInRAe.js +602 -0
- package/dist/mysql-BPQInRAe.js.map +1 -0
- package/dist/mysql-BYGEXm2C.d.ts +109 -0
- package/dist/mysql-BYGEXm2C.d.ts.map +1 -0
- package/dist/mysql-BYI8YXkW.d.ts +109 -0
- package/dist/mysql-BYI8YXkW.d.ts.map +1 -0
- package/dist/mysql-BYcoH18V.js +602 -0
- package/dist/mysql-BYcoH18V.js.map +1 -0
- package/dist/mysql-BkVE_Ujv.d.ts +109 -0
- package/dist/mysql-BkVE_Ujv.d.ts.map +1 -0
- package/dist/mysql-Bm2p56cX.d.ts +109 -0
- package/dist/mysql-Bm2p56cX.d.ts.map +1 -0
- package/dist/mysql-BpXbhT7n.d.ts +109 -0
- package/dist/mysql-BpXbhT7n.d.ts.map +1 -0
- package/dist/mysql-C5mY2vsv.d.ts +109 -0
- package/dist/mysql-C5mY2vsv.d.ts.map +1 -0
- package/dist/mysql-CA7GCR62.js +602 -0
- package/dist/mysql-CA7GCR62.js.map +1 -0
- package/dist/mysql-CB92MLis.d.ts +109 -0
- package/dist/mysql-CB92MLis.d.ts.map +1 -0
- package/dist/mysql-CJzUHhkD.d.ts +109 -0
- package/dist/mysql-CJzUHhkD.d.ts.map +1 -0
- package/dist/mysql-CMxoLJKU.js +602 -0
- package/dist/mysql-CMxoLJKU.js.map +1 -0
- package/dist/mysql-CWUc2OMX.js +602 -0
- package/dist/mysql-CWUc2OMX.js.map +1 -0
- package/dist/mysql-CXjC0ysZ.js +602 -0
- package/dist/mysql-CXjC0ysZ.js.map +1 -0
- package/dist/mysql-Cki0N6RJ.d.ts +109 -0
- package/dist/mysql-Cki0N6RJ.d.ts.map +1 -0
- package/dist/mysql-CmEj_TDt.d.ts +109 -0
- package/dist/mysql-CmEj_TDt.d.ts.map +1 -0
- package/dist/mysql-CqIRmBp7.d.ts +109 -0
- package/dist/mysql-CqIRmBp7.d.ts.map +1 -0
- package/dist/mysql-CtEorg4f.d.ts +109 -0
- package/dist/mysql-CtEorg4f.d.ts.map +1 -0
- package/dist/mysql-CuOauMxY.d.ts +109 -0
- package/dist/mysql-CuOauMxY.d.ts.map +1 -0
- package/dist/mysql-CuXo3LRu.js +602 -0
- package/dist/mysql-CuXo3LRu.js.map +1 -0
- package/dist/mysql-CzTpgBoO.js +602 -0
- package/dist/mysql-CzTpgBoO.js.map +1 -0
- package/dist/mysql-D8wL7pst.js +602 -0
- package/dist/mysql-D8wL7pst.js.map +1 -0
- package/dist/mysql-DA72G9SS.d.ts +109 -0
- package/dist/mysql-DA72G9SS.d.ts.map +1 -0
- package/dist/mysql-DGE7rJ0V.js +602 -0
- package/dist/mysql-DGE7rJ0V.js.map +1 -0
- package/dist/mysql-DVAc6aZz.d.ts +109 -0
- package/dist/mysql-DVAc6aZz.d.ts.map +1 -0
- package/dist/mysql-DVwWeE_Y.d.ts +109 -0
- package/dist/mysql-DVwWeE_Y.d.ts.map +1 -0
- package/dist/mysql-Db5cdkrK.d.ts +109 -0
- package/dist/mysql-Db5cdkrK.d.ts.map +1 -0
- package/dist/mysql-DfJaMwhW.d.ts +109 -0
- package/dist/mysql-DfJaMwhW.d.ts.map +1 -0
- package/dist/mysql-DifqBSa_.d.ts +109 -0
- package/dist/mysql-DifqBSa_.d.ts.map +1 -0
- package/dist/mysql-Dir8ENr2.d.ts +109 -0
- package/dist/mysql-Dir8ENr2.d.ts.map +1 -0
- package/dist/mysql-DpjO1Ytp.d.ts +109 -0
- package/dist/mysql-DpjO1Ytp.d.ts.map +1 -0
- package/dist/mysql-DswRsxyn.js +602 -0
- package/dist/mysql-DswRsxyn.js.map +1 -0
- package/dist/mysql-Dt8SVcVr.js +602 -0
- package/dist/mysql-Dt8SVcVr.js.map +1 -0
- package/dist/mysql-DtvfcLez.js +602 -0
- package/dist/mysql-DtvfcLez.js.map +1 -0
- package/dist/mysql-Dx64LagV.d.ts +109 -0
- package/dist/mysql-Dx64LagV.d.ts.map +1 -0
- package/dist/mysql-EDJ_yHHV.d.ts +109 -0
- package/dist/mysql-EDJ_yHHV.d.ts.map +1 -0
- package/dist/mysql-EgLnP40l.js +602 -0
- package/dist/mysql-EgLnP40l.js.map +1 -0
- package/dist/mysql-HDKtlHA7.js +602 -0
- package/dist/mysql-HDKtlHA7.js.map +1 -0
- package/dist/mysql-JpthxaEC.js +602 -0
- package/dist/mysql-JpthxaEC.js.map +1 -0
- package/dist/mysql-P_b5BFqG.js +602 -0
- package/dist/mysql-P_b5BFqG.js.map +1 -0
- package/dist/mysql-SLS-B4FA.js +602 -0
- package/dist/mysql-SLS-B4FA.js.map +1 -0
- package/dist/mysql-W2O36FZp.js +602 -0
- package/dist/mysql-W2O36FZp.js.map +1 -0
- package/dist/mysql-e29bahXC.js +602 -0
- package/dist/mysql-e29bahXC.js.map +1 -0
- package/dist/mysql-xrp4lX9M.js +602 -0
- package/dist/mysql-xrp4lX9M.js.map +1 -0
- package/dist/mysql-yzsN4kja.js +602 -0
- package/dist/mysql-yzsN4kja.js.map +1 -0
- package/dist/overlap-checker-BGIygypG.js +235 -0
- package/dist/overlap-checker-BGIygypG.js.map +1 -0
- package/dist/overlap-checker-BZShba_4.js +235 -0
- package/dist/overlap-checker-BZShba_4.js.map +1 -0
- package/dist/overlap-checker-BqR9qCfy.js +235 -0
- package/dist/overlap-checker-BqR9qCfy.js.map +1 -0
- package/dist/overlap-checker-BsSy8AzX.js +235 -0
- package/dist/overlap-checker-BsSy8AzX.js.map +1 -0
- package/dist/overlap-checker-C7ZufVA_.js +235 -0
- package/dist/overlap-checker-C7ZufVA_.js.map +1 -0
- package/dist/overlap-checker-CVOLquoJ.js +235 -0
- package/dist/overlap-checker-CVOLquoJ.js.map +1 -0
- package/dist/overlap-checker-C_TrIsl9.js +235 -0
- package/dist/overlap-checker-C_TrIsl9.js.map +1 -0
- package/dist/overlap-checker-CdY929rB.js +235 -0
- package/dist/overlap-checker-CdY929rB.js.map +1 -0
- package/dist/overlap-checker-CexhOI6d.js +235 -0
- package/dist/overlap-checker-CexhOI6d.js.map +1 -0
- package/dist/overlap-checker-CiQ0i2he.js +235 -0
- package/dist/overlap-checker-CiQ0i2he.js.map +1 -0
- package/dist/overlap-checker-Clg2Tvh1.js +235 -0
- package/dist/overlap-checker-Clg2Tvh1.js.map +1 -0
- package/dist/overlap-checker-CmH6Q_Zr.js +235 -0
- package/dist/overlap-checker-CmH6Q_Zr.js.map +1 -0
- package/dist/overlap-checker-Con95unw.js +235 -0
- package/dist/overlap-checker-Con95unw.js.map +1 -0
- package/dist/overlap-checker-D3fIwrEe.js +235 -0
- package/dist/overlap-checker-D3fIwrEe.js.map +1 -0
- package/dist/overlap-checker-D8aJEZhc.js +235 -0
- package/dist/overlap-checker-D8aJEZhc.js.map +1 -0
- package/dist/overlap-checker-DF8mpxy4.js +235 -0
- package/dist/overlap-checker-DF8mpxy4.js.map +1 -0
- package/dist/overlap-checker-DMkMOPz8.js +235 -0
- package/dist/overlap-checker-DMkMOPz8.js.map +1 -0
- package/dist/overlap-checker-DNqu1-af.js +235 -0
- package/dist/overlap-checker-DNqu1-af.js.map +1 -0
- package/dist/overlap-checker-DO4z3CWn.js +235 -0
- package/dist/overlap-checker-DO4z3CWn.js.map +1 -0
- package/dist/overlap-checker-DOuPHIda.js +235 -0
- package/dist/overlap-checker-DOuPHIda.js.map +1 -0
- package/dist/overlap-checker-DPlDexLT.js +235 -0
- package/dist/overlap-checker-DPlDexLT.js.map +1 -0
- package/dist/overlap-checker-DvVGLMNQ.js +235 -0
- package/dist/overlap-checker-DvVGLMNQ.js.map +1 -0
- package/dist/overlap-checker-FEC4bTk3.js +235 -0
- package/dist/overlap-checker-FEC4bTk3.js.map +1 -0
- package/dist/overlap-checker-JLCNx5q4.js +235 -0
- package/dist/overlap-checker-JLCNx5q4.js.map +1 -0
- package/dist/overlap-checker-fpoPpTQY.js +235 -0
- package/dist/overlap-checker-fpoPpTQY.js.map +1 -0
- package/dist/overlap-checker-j0GcZW77.js +235 -0
- package/dist/overlap-checker-j0GcZW77.js.map +1 -0
- package/dist/overlap-checker-zUQdaIYv.js +235 -0
- package/dist/overlap-checker-zUQdaIYv.js.map +1 -0
- package/dist/postgres-AyB5fPHb.js +857 -0
- package/dist/postgres-AyB5fPHb.js.map +1 -0
- package/dist/postgres-B-OZJdD9.d.ts +113 -0
- package/dist/postgres-B-OZJdD9.d.ts.map +1 -0
- package/dist/postgres-B1ybwr2I.d.ts +113 -0
- package/dist/postgres-B1ybwr2I.d.ts.map +1 -0
- package/dist/postgres-B2396cQX.js +857 -0
- package/dist/postgres-B2396cQX.js.map +1 -0
- package/dist/postgres-B7w7AW5q.d.ts +113 -0
- package/dist/postgres-B7w7AW5q.d.ts.map +1 -0
- package/dist/postgres-BE2VC-lV.d.ts +113 -0
- package/dist/postgres-BE2VC-lV.d.ts.map +1 -0
- package/dist/postgres-BIVafBnG.js +857 -0
- package/dist/postgres-BIVafBnG.js.map +1 -0
- package/dist/postgres-BJ3N1ARq.d.ts +113 -0
- package/dist/postgres-BJ3N1ARq.d.ts.map +1 -0
- package/dist/postgres-BKCshpjz.d.ts +113 -0
- package/dist/postgres-BKCshpjz.d.ts.map +1 -0
- package/dist/postgres-BLDfi_c1.js +857 -0
- package/dist/postgres-BLDfi_c1.js.map +1 -0
- package/dist/postgres-BLsYmvBT.js +857 -0
- package/dist/postgres-BLsYmvBT.js.map +1 -0
- package/dist/postgres-BOHVFFRE.d.ts +113 -0
- package/dist/postgres-BOHVFFRE.d.ts.map +1 -0
- package/dist/postgres-BSm7hkOq.js +857 -0
- package/dist/postgres-BSm7hkOq.js.map +1 -0
- package/dist/postgres-Bc0E1TrW.d.ts +113 -0
- package/dist/postgres-Bc0E1TrW.d.ts.map +1 -0
- package/dist/postgres-BoMAdlCX.d.ts +113 -0
- package/dist/postgres-BoMAdlCX.d.ts.map +1 -0
- package/dist/postgres-C4x9dHnD.js +857 -0
- package/dist/postgres-C4x9dHnD.js.map +1 -0
- package/dist/postgres-C7JBu6rW.d.ts +113 -0
- package/dist/postgres-C7JBu6rW.d.ts.map +1 -0
- package/dist/postgres-C7K6Ylb-.d.ts +113 -0
- package/dist/postgres-C7K6Ylb-.d.ts.map +1 -0
- package/dist/postgres-CECxtb8l.js +857 -0
- package/dist/postgres-CECxtb8l.js.map +1 -0
- package/dist/postgres-CGHUivER.d.ts +113 -0
- package/dist/postgres-CGHUivER.d.ts.map +1 -0
- package/dist/postgres-CH2UJrpO.js +857 -0
- package/dist/postgres-CH2UJrpO.js.map +1 -0
- package/dist/postgres-CJAn-jlg.js +857 -0
- package/dist/postgres-CJAn-jlg.js.map +1 -0
- package/dist/postgres-CPZDIBB0.d.ts +113 -0
- package/dist/postgres-CPZDIBB0.d.ts.map +1 -0
- package/dist/postgres-CaxNPOOz.js +857 -0
- package/dist/postgres-CaxNPOOz.js.map +1 -0
- package/dist/postgres-Chws2Anm.js +857 -0
- package/dist/postgres-Chws2Anm.js.map +1 -0
- package/dist/postgres-Cjmj7ESy.js +857 -0
- package/dist/postgres-Cjmj7ESy.js.map +1 -0
- package/dist/postgres-Clc1i2dP.d.ts +113 -0
- package/dist/postgres-Clc1i2dP.d.ts.map +1 -0
- package/dist/postgres-Cm-bmEN9.js +857 -0
- package/dist/postgres-Cm-bmEN9.js.map +1 -0
- package/dist/postgres-CotH5IcJ.d.ts +113 -0
- package/dist/postgres-CotH5IcJ.d.ts.map +1 -0
- package/dist/postgres-CtCEIxj_.js +857 -0
- package/dist/postgres-CtCEIxj_.js.map +1 -0
- package/dist/postgres-Cwq5EPBg.js +857 -0
- package/dist/postgres-Cwq5EPBg.js.map +1 -0
- package/dist/postgres-CzE7AZii.js +857 -0
- package/dist/postgres-CzE7AZii.js.map +1 -0
- package/dist/postgres-D-9VfxTJ.js +857 -0
- package/dist/postgres-D-9VfxTJ.js.map +1 -0
- package/dist/postgres-D3yPBJPF.d.ts +113 -0
- package/dist/postgres-D3yPBJPF.d.ts.map +1 -0
- package/dist/postgres-D5r-bNx9.d.ts +113 -0
- package/dist/postgres-D5r-bNx9.d.ts.map +1 -0
- package/dist/postgres-D9uq7-pc.d.ts +113 -0
- package/dist/postgres-D9uq7-pc.d.ts.map +1 -0
- package/dist/postgres-DC-_vGdw.js +857 -0
- package/dist/postgres-DC-_vGdw.js.map +1 -0
- package/dist/postgres-DKcSOpXu.js +857 -0
- package/dist/postgres-DKcSOpXu.js.map +1 -0
- package/dist/postgres-DKrGqh_j.d.ts +113 -0
- package/dist/postgres-DKrGqh_j.d.ts.map +1 -0
- package/dist/postgres-DPje6yca.js +857 -0
- package/dist/postgres-DPje6yca.js.map +1 -0
- package/dist/postgres-DUfgpwmk.js +857 -0
- package/dist/postgres-DUfgpwmk.js.map +1 -0
- package/dist/postgres-DkxzH2Dg.d.ts +113 -0
- package/dist/postgres-DkxzH2Dg.d.ts.map +1 -0
- package/dist/postgres-Dm2hJj_z.d.ts +113 -0
- package/dist/postgres-Dm2hJj_z.d.ts.map +1 -0
- package/dist/postgres-DmvXfcDq.d.ts +113 -0
- package/dist/postgres-DmvXfcDq.d.ts.map +1 -0
- package/dist/postgres-DpJbDdVo.d.ts +113 -0
- package/dist/postgres-DpJbDdVo.d.ts.map +1 -0
- package/dist/postgres-DqMmjAnq.js +857 -0
- package/dist/postgres-DqMmjAnq.js.map +1 -0
- package/dist/postgres-Dqo6TmkC.d.ts +113 -0
- package/dist/postgres-Dqo6TmkC.d.ts.map +1 -0
- package/dist/postgres-DuJMKfZT.js +857 -0
- package/dist/postgres-DuJMKfZT.js.map +1 -0
- package/dist/postgres-DuXHCyLM.d.ts +113 -0
- package/dist/postgres-DuXHCyLM.d.ts.map +1 -0
- package/dist/postgres-GjRa0yUX.d.ts +113 -0
- package/dist/postgres-GjRa0yUX.d.ts.map +1 -0
- package/dist/postgres-QmkUq1wW.js +857 -0
- package/dist/postgres-QmkUq1wW.js.map +1 -0
- package/dist/postgres-RYL0Miyw.js +857 -0
- package/dist/postgres-RYL0Miyw.js.map +1 -0
- package/dist/postgres-TiV0hbea.d.ts +113 -0
- package/dist/postgres-TiV0hbea.d.ts.map +1 -0
- package/dist/postgres-oXKx8meT.d.ts +113 -0
- package/dist/postgres-oXKx8meT.d.ts.map +1 -0
- package/dist/postgres-sIfan-wV.d.ts +113 -0
- package/dist/postgres-sIfan-wV.d.ts.map +1 -0
- package/dist/postgres-t-CmTR4w.js +857 -0
- package/dist/postgres-t-CmTR4w.js.map +1 -0
- package/dist/postgres-wSYI5UGF.d.ts +113 -0
- package/dist/postgres-wSYI5UGF.d.ts.map +1 -0
- package/dist/query-BLQJ9SWs.js +738 -0
- package/dist/query-BLQJ9SWs.js.map +1 -0
- package/dist/query-BMkGnyXV.js +722 -0
- package/dist/query-BMkGnyXV.js.map +1 -0
- package/dist/query-BXFo-xCO.js +705 -0
- package/dist/query-BXFo-xCO.js.map +1 -0
- package/dist/query-BXMj4jr-.js +718 -0
- package/dist/query-BXMj4jr-.js.map +1 -0
- package/dist/query-BuL8f9F8.js +724 -0
- package/dist/query-BuL8f9F8.js.map +1 -0
- package/dist/query-C10FzUWC.js +721 -0
- package/dist/query-C10FzUWC.js.map +1 -0
- package/dist/query-C4u8tD4H.js +698 -0
- package/dist/query-C4u8tD4H.js.map +1 -0
- package/dist/query-CLJCQlyA.js +722 -0
- package/dist/query-CLJCQlyA.js.map +1 -0
- package/dist/query-CMzRDKYw.js +714 -0
- package/dist/query-CMzRDKYw.js.map +1 -0
- package/dist/query-CNOc_XzM.js +709 -0
- package/dist/query-CNOc_XzM.js.map +1 -0
- package/dist/query-CVKqKDJE.js +737 -0
- package/dist/query-CVKqKDJE.js.map +1 -0
- package/dist/query-CbY0iPoj.js +724 -0
- package/dist/query-CbY0iPoj.js.map +1 -0
- package/dist/query-ClVEugE4.js +693 -0
- package/dist/query-ClVEugE4.js.map +1 -0
- package/dist/query-Cx7F-ete.js +740 -0
- package/dist/query-Cx7F-ete.js.map +1 -0
- package/dist/query-Cz7nBVio.js +738 -0
- package/dist/query-Cz7nBVio.js.map +1 -0
- package/dist/query-DC40-Yjv.js +737 -0
- package/dist/query-DC40-Yjv.js.map +1 -0
- package/dist/query-DQQ-PgGW.js +724 -0
- package/dist/query-DQQ-PgGW.js.map +1 -0
- package/dist/query-DleaAa4_.js +734 -0
- package/dist/query-DleaAa4_.js.map +1 -0
- package/dist/query-EzBrnggP.js +721 -0
- package/dist/query-EzBrnggP.js.map +1 -0
- package/dist/query-LVDVZXYz.js +729 -0
- package/dist/query-LVDVZXYz.js.map +1 -0
- package/dist/query-RyqMp8z7.js +697 -0
- package/dist/query-RyqMp8z7.js.map +1 -0
- package/dist/query-UQIzz6l1.js +722 -0
- package/dist/query-UQIzz6l1.js.map +1 -0
- package/dist/query-UzuYEXCD.js +724 -0
- package/dist/query-UzuYEXCD.js.map +1 -0
- package/dist/query-a1sRfDbW.js +739 -0
- package/dist/query-a1sRfDbW.js.map +1 -0
- package/dist/query-dsNEpb6t.js +706 -0
- package/dist/query-dsNEpb6t.js.map +1 -0
- package/dist/query-ur-jCtVr.js +740 -0
- package/dist/query-ur-jCtVr.js.map +1 -0
- package/dist/realtime_db-1gVIBhXB.js +272 -0
- package/dist/realtime_db-1gVIBhXB.js.map +1 -0
- package/dist/realtime_db-B7y4VvqK.js +272 -0
- package/dist/realtime_db-B7y4VvqK.js.map +1 -0
- package/dist/realtime_db-B9p7nVqA.js +272 -0
- package/dist/realtime_db-B9p7nVqA.js.map +1 -0
- package/dist/realtime_db-BGbxIA49.js +272 -0
- package/dist/realtime_db-BGbxIA49.js.map +1 -0
- package/dist/realtime_db-BHcg-hrk.js +272 -0
- package/dist/realtime_db-BHcg-hrk.js.map +1 -0
- package/dist/realtime_db-BNGcb0XU.js +272 -0
- package/dist/realtime_db-BNGcb0XU.js.map +1 -0
- package/dist/realtime_db-BeSfp0TC.js +272 -0
- package/dist/realtime_db-BeSfp0TC.js.map +1 -0
- package/dist/realtime_db-Bqjr53bi.js +272 -0
- package/dist/realtime_db-Bqjr53bi.js.map +1 -0
- package/dist/realtime_db-CC7YVTXO.js +272 -0
- package/dist/realtime_db-CC7YVTXO.js.map +1 -0
- package/dist/realtime_db-CKC01P0a.js +272 -0
- package/dist/realtime_db-CKC01P0a.js.map +1 -0
- package/dist/realtime_db-COWVCIVH.js +272 -0
- package/dist/realtime_db-COWVCIVH.js.map +1 -0
- package/dist/realtime_db-CRzNVBAz.js +272 -0
- package/dist/realtime_db-CRzNVBAz.js.map +1 -0
- package/dist/realtime_db-Cfkgkm9D.js +272 -0
- package/dist/realtime_db-Cfkgkm9D.js.map +1 -0
- package/dist/realtime_db-D3D8n8z1.js +272 -0
- package/dist/realtime_db-D3D8n8z1.js.map +1 -0
- package/dist/realtime_db-DI5Z16wS.js +272 -0
- package/dist/realtime_db-DI5Z16wS.js.map +1 -0
- package/dist/realtime_db-DbLFDG_j.js +272 -0
- package/dist/realtime_db-DbLFDG_j.js.map +1 -0
- package/dist/realtime_db-DiYQbfeA.js +272 -0
- package/dist/realtime_db-DiYQbfeA.js.map +1 -0
- package/dist/realtime_db-DnJ7fr2H.js +272 -0
- package/dist/realtime_db-DnJ7fr2H.js.map +1 -0
- package/dist/realtime_db-DpGFkUHy.js +272 -0
- package/dist/realtime_db-DpGFkUHy.js.map +1 -0
- package/dist/realtime_db-DpZLibPQ.js +272 -0
- package/dist/realtime_db-DpZLibPQ.js.map +1 -0
- package/dist/realtime_db-DwxYj-Si.js +272 -0
- package/dist/realtime_db-DwxYj-Si.js.map +1 -0
- package/dist/realtime_db-F0o5WP5z.js +272 -0
- package/dist/realtime_db-F0o5WP5z.js.map +1 -0
- package/dist/realtime_db-G-9ZPdwx.js +272 -0
- package/dist/realtime_db-G-9ZPdwx.js.map +1 -0
- package/dist/realtime_db-NPtQRElK.js +272 -0
- package/dist/realtime_db-NPtQRElK.js.map +1 -0
- package/dist/realtime_db-Zs7Ox8YY.js +272 -0
- package/dist/realtime_db-Zs7Ox8YY.js.map +1 -0
- package/dist/realtime_db-jQ7mhwvO.js +272 -0
- package/dist/realtime_db-jQ7mhwvO.js.map +1 -0
- package/dist/realtime_db-xIwkcoDg.js +272 -0
- package/dist/realtime_db-xIwkcoDg.js.map +1 -0
- package/dist/src/client/index.d.ts +1 -1
- package/dist/src/client/index.js +3 -3
- package/dist/src/exports/mysql.d.ts +1 -1
- package/dist/src/exports/mysql.js +1 -1
- package/dist/src/exports/postgres.d.ts +1 -1
- package/dist/src/exports/postgres.js +1 -1
- package/dist/src/exports/procedure.d.ts +2 -2
- package/dist/src/exports/procedure.js +1 -1
- package/dist/src/exports/schema-sql.d.ts +1 -1
- package/dist/src/exports/server.d.ts +4 -4
- package/dist/src/exports/server.js +3 -3
- package/dist/src/exports/subscription-manager-worker-entry.js +2 -2
- package/dist/src/exports/types.d.ts +2 -2
- package/dist/src/exports/types.js +1 -1
- package/dist/subscription-worker-5l4qavz7.js +749 -0
- package/dist/subscription-worker-5l4qavz7.js.map +1 -0
- package/dist/subscription-worker-B7sDMXsu.js +749 -0
- package/dist/subscription-worker-B7sDMXsu.js.map +1 -0
- package/dist/subscription-worker-BCXO8Lwm.js +749 -0
- package/dist/subscription-worker-BCXO8Lwm.js.map +1 -0
- package/dist/subscription-worker-BEIjeBhb.js +749 -0
- package/dist/subscription-worker-BEIjeBhb.js.map +1 -0
- package/dist/subscription-worker-BQv_WD7J.js +749 -0
- package/dist/subscription-worker-BQv_WD7J.js.map +1 -0
- package/dist/subscription-worker-Beayghw3.js +749 -0
- package/dist/subscription-worker-Beayghw3.js.map +1 -0
- package/dist/subscription-worker-C4b0RWPI.js +749 -0
- package/dist/subscription-worker-C4b0RWPI.js.map +1 -0
- package/dist/subscription-worker-CFPiS-lO.js +749 -0
- package/dist/subscription-worker-CFPiS-lO.js.map +1 -0
- package/dist/subscription-worker-CKQad7zS.js +749 -0
- package/dist/subscription-worker-CKQad7zS.js.map +1 -0
- package/dist/subscription-worker-CUGSAwmV.js +749 -0
- package/dist/subscription-worker-CUGSAwmV.js.map +1 -0
- package/dist/subscription-worker-CjYVbFq2.js +749 -0
- package/dist/subscription-worker-CjYVbFq2.js.map +1 -0
- package/dist/subscription-worker-Cm-wPcp-.js +749 -0
- package/dist/subscription-worker-Cm-wPcp-.js.map +1 -0
- package/dist/subscription-worker-Cu6-TIg3.js +749 -0
- package/dist/subscription-worker-Cu6-TIg3.js.map +1 -0
- package/dist/subscription-worker-D02vQ0YL.js +749 -0
- package/dist/subscription-worker-D02vQ0YL.js.map +1 -0
- package/dist/subscription-worker-D8TcRMuX.js +749 -0
- package/dist/subscription-worker-D8TcRMuX.js.map +1 -0
- package/dist/subscription-worker-DC9v3_Xn.js +749 -0
- package/dist/subscription-worker-DC9v3_Xn.js.map +1 -0
- package/dist/subscription-worker-DHOkFYtt.js +749 -0
- package/dist/subscription-worker-DHOkFYtt.js.map +1 -0
- package/dist/subscription-worker-DrR2G0UY.js +749 -0
- package/dist/subscription-worker-DrR2G0UY.js.map +1 -0
- package/dist/subscription-worker-Dwdp_WGy.js +749 -0
- package/dist/subscription-worker-Dwdp_WGy.js.map +1 -0
- package/dist/subscription-worker-Dy1rzhyX.js +749 -0
- package/dist/subscription-worker-Dy1rzhyX.js.map +1 -0
- package/dist/subscription-worker-DyOE3VkC.js +749 -0
- package/dist/subscription-worker-DyOE3VkC.js.map +1 -0
- package/dist/subscription-worker-O731E8Bh.js +749 -0
- package/dist/subscription-worker-O731E8Bh.js.map +1 -0
- package/dist/subscription-worker-Sj1M8tbn.js +749 -0
- package/dist/subscription-worker-Sj1M8tbn.js.map +1 -0
- package/dist/subscription-worker-Zrw5q6qO.js +749 -0
- package/dist/subscription-worker-Zrw5q6qO.js.map +1 -0
- package/dist/subscription-worker-exWsillu.js +749 -0
- package/dist/subscription-worker-exWsillu.js.map +1 -0
- package/dist/subscription-worker-pTVrvvmW.js +749 -0
- package/dist/subscription-worker-pTVrvvmW.js.map +1 -0
- package/dist/subscription-worker-zvtbinBF.js +749 -0
- package/dist/subscription-worker-zvtbinBF.js.map +1 -0
- package/dist/types_db-B039N8Em.js +173 -0
- package/dist/types_db-B039N8Em.js.map +1 -0
- package/dist/types_db-NY-7zuhP.js +173 -0
- package/dist/types_db-NY-7zuhP.js.map +1 -0
- package/dist/types_server-6U7QWGuL.d.ts +328 -0
- package/dist/types_server-6U7QWGuL.d.ts.map +1 -0
- package/dist/types_server-B2rOOZ0z.d.ts +328 -0
- package/dist/types_server-B2rOOZ0z.d.ts.map +1 -0
- package/dist/types_server-B49_-V9c.d.ts +328 -0
- package/dist/types_server-B49_-V9c.d.ts.map +1 -0
- package/dist/types_server-BDHd_YTS.d.ts +328 -0
- package/dist/types_server-BDHd_YTS.d.ts.map +1 -0
- package/dist/types_server-BEX-uJc5.d.ts +328 -0
- package/dist/types_server-BEX-uJc5.d.ts.map +1 -0
- package/dist/types_server-BH5h91D0.d.ts +328 -0
- package/dist/types_server-BH5h91D0.d.ts.map +1 -0
- package/dist/types_server-BNuTxu-E.d.ts +328 -0
- package/dist/types_server-BNuTxu-E.d.ts.map +1 -0
- package/dist/types_server-BQ33p2LM.d.ts +328 -0
- package/dist/types_server-BQ33p2LM.d.ts.map +1 -0
- package/dist/types_server-BiXcNKA3.d.ts +328 -0
- package/dist/types_server-BiXcNKA3.d.ts.map +1 -0
- package/dist/types_server-BkbGHQzW.d.ts +328 -0
- package/dist/types_server-BkbGHQzW.d.ts.map +1 -0
- package/dist/types_server-BkeSAZmH.d.ts +328 -0
- package/dist/types_server-BkeSAZmH.d.ts.map +1 -0
- package/dist/types_server-BlpFFYCI.d.ts +328 -0
- package/dist/types_server-BlpFFYCI.d.ts.map +1 -0
- package/dist/types_server-BtvZjizR.d.ts +328 -0
- package/dist/types_server-BtvZjizR.d.ts.map +1 -0
- package/dist/types_server-C38fddo_.d.ts +328 -0
- package/dist/types_server-C38fddo_.d.ts.map +1 -0
- package/dist/types_server-CN02ApQ_.d.ts +328 -0
- package/dist/types_server-CN02ApQ_.d.ts.map +1 -0
- package/dist/types_server-CPd_Fuhq.d.ts +328 -0
- package/dist/types_server-CPd_Fuhq.d.ts.map +1 -0
- package/dist/types_server-Ce4bZgQJ.d.ts +328 -0
- package/dist/types_server-Ce4bZgQJ.d.ts.map +1 -0
- package/dist/types_server-CexXO5sW.d.ts +328 -0
- package/dist/types_server-CexXO5sW.d.ts.map +1 -0
- package/dist/types_server-Cq8HGFGy.d.ts +328 -0
- package/dist/types_server-Cq8HGFGy.d.ts.map +1 -0
- package/dist/types_server-CuHsqi4p.d.ts +328 -0
- package/dist/types_server-CuHsqi4p.d.ts.map +1 -0
- package/dist/types_server-D8PzF-79.d.ts +328 -0
- package/dist/types_server-D8PzF-79.d.ts.map +1 -0
- package/dist/types_server-DB3IrC2o.d.ts +328 -0
- package/dist/types_server-DB3IrC2o.d.ts.map +1 -0
- package/dist/types_server-DUV3oRXr.d.ts +328 -0
- package/dist/types_server-DUV3oRXr.d.ts.map +1 -0
- package/dist/types_server-DYNpoqfL.d.ts +328 -0
- package/dist/types_server-DYNpoqfL.d.ts.map +1 -0
- package/dist/types_server-MkSVQQVM.d.ts +328 -0
- package/dist/types_server-MkSVQQVM.d.ts.map +1 -0
- package/dist/types_server-N_coWvBq.d.ts +328 -0
- package/dist/types_server-N_coWvBq.d.ts.map +1 -0
- package/dist/types_server-XPVdOY-I.d.ts +328 -0
- package/dist/types_server-XPVdOY-I.d.ts.map +1 -0
- package/dist/types_server-eQqn3f_C.d.ts +328 -0
- package/dist/types_server-eQqn3f_C.d.ts.map +1 -0
- package/dist/types_server-hAXcDGD4.d.ts +328 -0
- package/dist/types_server-hAXcDGD4.d.ts.map +1 -0
- package/dist/types_server-sKy9tI8G.d.ts +328 -0
- package/dist/types_server-sKy9tI8G.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,857 @@
|
|
|
1
|
+
import { r as utf8Encode } from "./bytes-AuEkyxeU.js";
|
|
2
|
+
import { r as supaliveStringify } from "./helper-wGbzz6zo.js";
|
|
3
|
+
import { t as CORE_INIT_LOCK_KEY } from "./db-ClCicssQ.js";
|
|
4
|
+
import { C as normalizeIdToBytes, l as OccConflictError, w as normalizeToBytes } from "./types_db-NY-7zuhP.js";
|
|
5
|
+
import { i as mapReadSetToRaw, t as checkLogsAffectReadSet } from "./overlap-checker-CmH6Q_Zr.js";
|
|
6
|
+
import { Pool } from "pg";
|
|
7
|
+
//#region src/db/postgres.ts
|
|
8
|
+
function toBufferView(bytes) {
|
|
9
|
+
if (Buffer.isBuffer(bytes)) return bytes;
|
|
10
|
+
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
11
|
+
}
|
|
12
|
+
var PgDatabase = class {
|
|
13
|
+
constructor(logger, config, pool = void 0) {
|
|
14
|
+
this.logger = logger;
|
|
15
|
+
this.config = config;
|
|
16
|
+
if (pool) this.pool = pool;
|
|
17
|
+
else this.pool = new Pool(config);
|
|
18
|
+
}
|
|
19
|
+
logger;
|
|
20
|
+
config;
|
|
21
|
+
pool;
|
|
22
|
+
sqlBuilder = pgSql;
|
|
23
|
+
dbType = "postgres";
|
|
24
|
+
columnTypes = /* @__PURE__ */ new Map();
|
|
25
|
+
sqlCache = /* @__PURE__ */ new Map();
|
|
26
|
+
/**
|
|
27
|
+
* Fetches actual column types from Postgres for `table` and returns a
|
|
28
|
+
* map of DB column name → PG type string (as produced by `format_type`,
|
|
29
|
+
* e.g. `bigint`, `integer`, `character varying(32)`, `text[]`, `jsonb`).
|
|
30
|
+
* No caching here — see {@link getColumnTypes} for the cached path.
|
|
31
|
+
*/
|
|
32
|
+
async loadColumnTypesFromPg(table) {
|
|
33
|
+
const result = await this.query(`SELECT a.attname AS column_name, format_type(a.atttypid, a.atttypmod) AS pg_type
|
|
34
|
+
FROM pg_attribute a
|
|
35
|
+
WHERE a.attrelid = $1::regclass AND a.attnum > 0 AND NOT a.attisdropped
|
|
36
|
+
ORDER BY a.attnum`, [table]);
|
|
37
|
+
const out = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const row of result.rows) out.set(row.column_name.toLowerCase(), row.pg_type);
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Synchronous column-type lookup. The apply path calls this on every
|
|
43
|
+
* batched write, so it can't await — populate the cache via
|
|
44
|
+
* {@link bootstrapColumnTypes} at server start. Throws if `table` is
|
|
45
|
+
* missing (programmer error / bootstrap skipped).
|
|
46
|
+
*/
|
|
47
|
+
getColumnTypes(table) {
|
|
48
|
+
const hit = this.columnTypes.get(table);
|
|
49
|
+
if (!hit) {
|
|
50
|
+
this.logger.warn({ table }, "PgDatabase: no cached column types fallback to non-batched writes");
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return hit;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Eagerly load column types into the in-memory cache. With a Redis
|
|
57
|
+
* client supplied, attempts the cache key first and falls through to
|
|
58
|
+
* Postgres on miss (writing the result back to Redis). This is the
|
|
59
|
+
* "one server queries PG, the rest read from Redis" pattern for cold
|
|
60
|
+
* starts in a multi-instance deploy. Without Redis, always queries PG.
|
|
61
|
+
*
|
|
62
|
+
* Pass `tables` to limit the load to a specific list; otherwise every
|
|
63
|
+
* user table in the connected database is loaded.
|
|
64
|
+
*
|
|
65
|
+
* The Redis cache key should encode whatever invalidates types in your
|
|
66
|
+
* environment (typically a schema version / deploy version). The
|
|
67
|
+
* subscriber in supalive-server.ts is expected to publish a reload
|
|
68
|
+
* signal after migrations and invoke {@link invalidateColumnTypes}.
|
|
69
|
+
*/
|
|
70
|
+
async bootstrapColumnTypes(opts) {
|
|
71
|
+
this.invalidateColumnTypes();
|
|
72
|
+
const { redis, cacheKey, tables } = opts;
|
|
73
|
+
if (redis) {
|
|
74
|
+
const cached = await redis.getCachedTableColumnTypes(cacheKey);
|
|
75
|
+
if (cached) {
|
|
76
|
+
for (const [table, cols] of Object.entries(cached)) this.columnTypes.set(table, new Map(Object.entries(cols)));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const names = tables ?? await this.listUserTables();
|
|
81
|
+
for (const t of names) {
|
|
82
|
+
if (this.columnTypes.has(t)) continue;
|
|
83
|
+
const fresh = await this.loadColumnTypesFromPg(t);
|
|
84
|
+
this.columnTypes.set(t, fresh);
|
|
85
|
+
}
|
|
86
|
+
if (redis) {
|
|
87
|
+
const dump = {};
|
|
88
|
+
for (const [table, cols] of this.columnTypes) dump[table] = Object.fromEntries([...cols.entries()].sort());
|
|
89
|
+
await redis.setCachedTableColumnsTypes(cacheKey, dump);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Invalidate cached types (and dependent SQL) for `table`, or the entire
|
|
94
|
+
* cache if `table` is omitted. The Redis-pubsub reload signal in
|
|
95
|
+
* supalive-server.ts is expected to call this on schema changes.
|
|
96
|
+
*/
|
|
97
|
+
invalidateColumnTypes(table) {
|
|
98
|
+
if (table) {
|
|
99
|
+
this.columnTypes.delete(table);
|
|
100
|
+
for (const k of [...this.sqlCache.keys()]) if (k.includes(`:${table}:`) || k === `d:${table}`) this.sqlCache.delete(k);
|
|
101
|
+
} else {
|
|
102
|
+
this.columnTypes.clear();
|
|
103
|
+
this.sqlCache.clear();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Enumerate the user-defined tables in the connected database — used
|
|
107
|
+
* by bootstrapColumnTypes() when no explicit list is provided. */
|
|
108
|
+
async listUserTables() {
|
|
109
|
+
return (await this.query(`SELECT c.relname FROM pg_class c
|
|
110
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
111
|
+
WHERE c.relkind = 'r' AND n.nspname = ANY (current_schemas(false))
|
|
112
|
+
AND c.relname NOT IN ('commit_logs','metadata')`)).rows.map((r) => r.relname);
|
|
113
|
+
}
|
|
114
|
+
async getCoreVersion() {
|
|
115
|
+
const result = await this.query("SELECT meta_value FROM metadata WHERE meta_key = 'core_version'");
|
|
116
|
+
return BigInt(result.rows[0]?.meta_value ?? 0);
|
|
117
|
+
}
|
|
118
|
+
coreMigrationStatements(toVersion) {
|
|
119
|
+
if (toVersion === 1n) return [`INSERT INTO metadata (meta_key, meta_value) VALUES ('latest_committed_ts', 0) ON CONFLICT (meta_key) DO NOTHING;`, `INSERT INTO metadata (meta_key, meta_value) VALUES ('min_retained_ts', 0) ON CONFLICT (meta_key) DO NOTHING;`];
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
async withCoreInitLock(fn) {
|
|
123
|
+
const client = await this.pool.connect();
|
|
124
|
+
try {
|
|
125
|
+
await client.query("BEGIN");
|
|
126
|
+
await client.query("SELECT pg_advisory_xact_lock($1)", [CORE_INIT_LOCK_KEY]);
|
|
127
|
+
await fn({
|
|
128
|
+
exec: async (sql, params = []) => {
|
|
129
|
+
const r = await client.query(sql, params);
|
|
130
|
+
return {
|
|
131
|
+
rows: r.rows,
|
|
132
|
+
rowCount: r.rowCount
|
|
133
|
+
};
|
|
134
|
+
},
|
|
135
|
+
getVersion: async () => {
|
|
136
|
+
const r = await client.query("SELECT meta_value FROM metadata WHERE meta_key = 'core_version'");
|
|
137
|
+
return BigInt(r.rows[0]?.meta_value ?? 0);
|
|
138
|
+
},
|
|
139
|
+
setVersion: async (version) => {
|
|
140
|
+
await client.query(`INSERT INTO metadata (meta_key, meta_value) VALUES ('core_version', $1)
|
|
141
|
+
ON CONFLICT (meta_key) DO UPDATE SET meta_value = EXCLUDED.meta_value`, [version.toString()]);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
await client.query("COMMIT");
|
|
145
|
+
} catch (err) {
|
|
146
|
+
await client.query("ROLLBACK").catch(() => {});
|
|
147
|
+
throw translatePgError(err);
|
|
148
|
+
} finally {
|
|
149
|
+
client.release();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async query(sql, params = []) {
|
|
153
|
+
const client = await this.pool.connect();
|
|
154
|
+
try {
|
|
155
|
+
const result = await client.query(sql, params);
|
|
156
|
+
return {
|
|
157
|
+
rows: result.rows,
|
|
158
|
+
rowCount: result.rowCount
|
|
159
|
+
};
|
|
160
|
+
} catch (err) {
|
|
161
|
+
throw translatePgError(err);
|
|
162
|
+
} finally {
|
|
163
|
+
client.release();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async getClient() {
|
|
167
|
+
return await this.pool.connect();
|
|
168
|
+
}
|
|
169
|
+
async getTransactionClient() {
|
|
170
|
+
const client = await this.pool.connect();
|
|
171
|
+
const tx = new PgTxDatabase(this.logger, this.config, this.pool, client);
|
|
172
|
+
tx.adoptCaches(this.columnTypes, this.sqlCache);
|
|
173
|
+
return tx;
|
|
174
|
+
}
|
|
175
|
+
/** Internal: replace this instance's caches with shared references from
|
|
176
|
+
* a parent. Used by PgDatabase.getTransactionClient. */
|
|
177
|
+
adoptCaches(columnTypes, sqlCache) {
|
|
178
|
+
this.columnTypes = columnTypes;
|
|
179
|
+
this.sqlCache = sqlCache;
|
|
180
|
+
}
|
|
181
|
+
async getLatestSnapshotTimestamp() {
|
|
182
|
+
const result = await this.query("SELECT meta_value FROM metadata WHERE meta_key = 'latest_committed_ts'");
|
|
183
|
+
return BigInt(result.rows[0]?.meta_value ?? 0);
|
|
184
|
+
}
|
|
185
|
+
async updateLatestSnapshotTimestamp(commitTs) {
|
|
186
|
+
await this.query("UPDATE metadata SET meta_value = $1 WHERE meta_key = 'latest_committed_ts' AND meta_value < $1", [commitTs]);
|
|
187
|
+
}
|
|
188
|
+
async getMinSnapshotTimestamp() {
|
|
189
|
+
const result = await this.query("SELECT meta_value FROM metadata WHERE meta_key = 'min_retained_ts'");
|
|
190
|
+
return BigInt(result.rows[0]?.meta_value ?? 0);
|
|
191
|
+
}
|
|
192
|
+
async updateMinSnapshotTimestamp(ts) {
|
|
193
|
+
await this.query("UPDATE metadata SET meta_value = $1 WHERE meta_key = 'min_retained_ts' AND meta_value < $1", [ts]);
|
|
194
|
+
}
|
|
195
|
+
async getNextTimestamp() {
|
|
196
|
+
const result = await this.query("SELECT nextval('global_commit_ts') as nextval");
|
|
197
|
+
return BigInt(result.rows[0]?.nextval ?? "0");
|
|
198
|
+
}
|
|
199
|
+
async attachPrevDataToWriteSet(writeSet, readSet) {
|
|
200
|
+
const readTsByKey = /* @__PURE__ */ new Map();
|
|
201
|
+
for (let i = readSet.length - 1; i >= 0; i--) {
|
|
202
|
+
const r = readSet[i];
|
|
203
|
+
if (r.kind !== "point" || r.expectedCommitTs === void 0) continue;
|
|
204
|
+
const key = `${r.table} ${r.id}`;
|
|
205
|
+
if (!readTsByKey.has(key)) readTsByKey.set(key, r.expectedCommitTs);
|
|
206
|
+
}
|
|
207
|
+
const byTable = /* @__PURE__ */ new Map();
|
|
208
|
+
for (const entry of writeSet) {
|
|
209
|
+
if (entry.op !== "update" && entry.op !== "delete") continue;
|
|
210
|
+
const bucket = byTable.get(entry.table);
|
|
211
|
+
if (bucket) bucket.push(entry);
|
|
212
|
+
else byTable.set(entry.table, [entry]);
|
|
213
|
+
}
|
|
214
|
+
if (byTable.size === 0) return;
|
|
215
|
+
for (const [table, entries] of byTable) {
|
|
216
|
+
const ids = entries.map((e) => e.id);
|
|
217
|
+
const sql = `SELECT * FROM ${table} WHERE id IN (${ids.map((_, i) => `$${i + 1}`).join(", ")})`;
|
|
218
|
+
const result = await this.query(sql, ids);
|
|
219
|
+
const byId = /* @__PURE__ */ new Map();
|
|
220
|
+
for (const row of result.rows) byId.set(String(row.id), row);
|
|
221
|
+
for (const entry of entries) {
|
|
222
|
+
const row = byId.get(entry.id);
|
|
223
|
+
const key = `${entry.table} ${entry.id}`;
|
|
224
|
+
const priorReadTs = readTsByKey.get(key);
|
|
225
|
+
if (row) {
|
|
226
|
+
entry.prevData = row;
|
|
227
|
+
entry.expectedCommitTs = priorReadTs !== void 0 ? priorReadTs : BigInt(row.commit_ts);
|
|
228
|
+
} else if (priorReadTs !== void 0) entry.expectedCommitTs = priorReadTs;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async prepareCommitWrites(readSet, writeSet, commitTs) {
|
|
233
|
+
const result = [];
|
|
234
|
+
await this.pgPrepareBatchWrites(result, writeSet, commitTs);
|
|
235
|
+
await this.pgPrepareCommitLogs(result, writeSet, commitTs);
|
|
236
|
+
if (!readSet.some((r) => r.kind === "range")) return {
|
|
237
|
+
commits: result,
|
|
238
|
+
validateReadPoints: this.pgPrepareValidatePointReadsByCommitTs(readSet, writeSet),
|
|
239
|
+
hasRangeRead: false
|
|
240
|
+
};
|
|
241
|
+
return {
|
|
242
|
+
commits: result,
|
|
243
|
+
hasRangeRead: true,
|
|
244
|
+
tableIds: [...new Set(readSet.map((r) => r.tableId))],
|
|
245
|
+
rawReadSet: mapReadSetToRaw(readSet)
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
async pgPrepareBatchWrites(result, writeSet, commitTs) {
|
|
249
|
+
let i = 0;
|
|
250
|
+
let counter = 0;
|
|
251
|
+
while (i < writeSet.length) {
|
|
252
|
+
counter++;
|
|
253
|
+
const { table, op } = writeSet[i];
|
|
254
|
+
let j = i + 1;
|
|
255
|
+
while (j < writeSet.length && writeSet[j].table === table && writeSet[j].op === op) j++;
|
|
256
|
+
const batch = writeSet.slice(i, j);
|
|
257
|
+
if (op === "insert") await this.pgPrepareInsertBatch(result, table, batch, commitTs);
|
|
258
|
+
else if (op === "update") await this.pgPrepareUpdateBatch(result, table, batch, commitTs);
|
|
259
|
+
else await this.pgPrepareDeleteBatch(result, table, batch);
|
|
260
|
+
i = j;
|
|
261
|
+
if (counter % 50 == 0) await new Promise((resolve) => setImmediate(resolve));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
pgPrepareInsertSingle(result, table, entry, commitTs) {
|
|
265
|
+
const data = {
|
|
266
|
+
...entry.data ?? {},
|
|
267
|
+
commit_ts: commitTs
|
|
268
|
+
};
|
|
269
|
+
const cols = Object.keys(data);
|
|
270
|
+
const placeholders = cols.map((_, i) => `$${i + 1}`);
|
|
271
|
+
result.push({
|
|
272
|
+
sql: `INSERT INTO ${table} (${cols.join(", ")}) VALUES (${placeholders.join(", ")})`,
|
|
273
|
+
params: Object.values(data),
|
|
274
|
+
operation: "insertSingle",
|
|
275
|
+
table,
|
|
276
|
+
entryId: entry.id
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
async pgPrepareInsertBatch(result, table, entries, commitTs) {
|
|
280
|
+
if (entries.length === 0) return;
|
|
281
|
+
const types = this.getColumnTypes(table);
|
|
282
|
+
if (!types) {
|
|
283
|
+
this.logger.warn({ table }, "No column types found, falling back to non-batched writes for insert");
|
|
284
|
+
let counter = 0;
|
|
285
|
+
for (const entry of entries) {
|
|
286
|
+
counter++;
|
|
287
|
+
this.pgPrepareInsertSingle(result, table, entry, commitTs);
|
|
288
|
+
if (counter % 50 == 0) await new Promise((resolve) => setImmediate(resolve));
|
|
289
|
+
}
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const groups = /* @__PURE__ */ new Map();
|
|
293
|
+
for (const entry of entries) {
|
|
294
|
+
const cols = [...Object.keys(entry.data ?? {}), "commit_ts"].sort();
|
|
295
|
+
const key = cols.join("|");
|
|
296
|
+
let g = groups.get(key);
|
|
297
|
+
if (!g) {
|
|
298
|
+
g = {
|
|
299
|
+
cols,
|
|
300
|
+
rows: []
|
|
301
|
+
};
|
|
302
|
+
groups.set(key, g);
|
|
303
|
+
}
|
|
304
|
+
g.rows.push(entry);
|
|
305
|
+
}
|
|
306
|
+
let counter = 0;
|
|
307
|
+
for (const { cols, rows } of groups.values()) {
|
|
308
|
+
counter++;
|
|
309
|
+
const sql = this.buildOrGetInsertSql(table, types, cols);
|
|
310
|
+
const params = cols.map(() => new Array(rows.length));
|
|
311
|
+
for (let r = 0; r < rows.length; r++) {
|
|
312
|
+
const data = {
|
|
313
|
+
...rows[r].data ?? {},
|
|
314
|
+
commit_ts: commitTs
|
|
315
|
+
};
|
|
316
|
+
for (let c = 0; c < cols.length; c++) {
|
|
317
|
+
const pgType = types.get(cols[c].toLowerCase()) ?? "text";
|
|
318
|
+
params[c][r] = encodeForCarrier(data[cols[c]], pgType);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (counter % 50 == 0) await new Promise((resolve) => setImmediate(resolve));
|
|
322
|
+
result.push({
|
|
323
|
+
sql,
|
|
324
|
+
params,
|
|
325
|
+
operation: "insertBatch",
|
|
326
|
+
table
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
pgPrepareUpdateSingle(result, table, entry, commitTs) {
|
|
331
|
+
const data = {
|
|
332
|
+
...entry.data ?? {},
|
|
333
|
+
commit_ts: commitTs
|
|
334
|
+
};
|
|
335
|
+
const sets = Object.keys(data).map((col, i) => `${col} = $${i + 1}`);
|
|
336
|
+
const values = Object.values(data);
|
|
337
|
+
const idP = `$${values.length + 1}`;
|
|
338
|
+
const tsP = `$${values.length + 2}`;
|
|
339
|
+
const expected = entry.expectedCommitTs ?? -1n;
|
|
340
|
+
result.push({
|
|
341
|
+
sql: `UPDATE ${table} SET ${sets.join(", ")} WHERE id = ${idP} AND commit_ts = ${tsP}`,
|
|
342
|
+
params: [
|
|
343
|
+
...values,
|
|
344
|
+
entry.id,
|
|
345
|
+
expected
|
|
346
|
+
],
|
|
347
|
+
operation: "updateSingle",
|
|
348
|
+
table,
|
|
349
|
+
entryId: entry.id,
|
|
350
|
+
expectedTs: expected
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async pgPrepareUpdateBatch(result, table, entries, commitTs) {
|
|
354
|
+
if (entries.length === 0) return;
|
|
355
|
+
const types = this.getColumnTypes(table);
|
|
356
|
+
if (!types) {
|
|
357
|
+
this.logger.warn({ table }, "No column types found, falling back to non-batched writes for update");
|
|
358
|
+
let counter = 0;
|
|
359
|
+
for (const entry of entries) {
|
|
360
|
+
counter++;
|
|
361
|
+
this.pgPrepareUpdateSingle(result, table, entry, commitTs);
|
|
362
|
+
if (counter % 50 == 0) await new Promise((resolve) => setImmediate(resolve));
|
|
363
|
+
}
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const groups = /* @__PURE__ */ new Map();
|
|
367
|
+
for (const entry of entries) {
|
|
368
|
+
const cols = [...Object.keys(entry.data ?? {}), "commit_ts"].sort();
|
|
369
|
+
const key = cols.join("|");
|
|
370
|
+
let g = groups.get(key);
|
|
371
|
+
if (!g) {
|
|
372
|
+
g = {
|
|
373
|
+
cols,
|
|
374
|
+
rows: []
|
|
375
|
+
};
|
|
376
|
+
groups.set(key, g);
|
|
377
|
+
}
|
|
378
|
+
g.rows.push(entry);
|
|
379
|
+
}
|
|
380
|
+
let counter = 0;
|
|
381
|
+
for (const { cols, rows } of groups.values()) {
|
|
382
|
+
counter++;
|
|
383
|
+
const sql = this.buildOrGetUpdateSql(table, types, cols);
|
|
384
|
+
const idType = types.get("id") ?? "text";
|
|
385
|
+
const idArr = new Array(rows.length);
|
|
386
|
+
const expArr = new Array(rows.length);
|
|
387
|
+
const colArrs = cols.map(() => new Array(rows.length));
|
|
388
|
+
for (let r = 0; r < rows.length; r++) {
|
|
389
|
+
const entry = rows[r];
|
|
390
|
+
const data = {
|
|
391
|
+
...entry.data ?? {},
|
|
392
|
+
commit_ts: commitTs
|
|
393
|
+
};
|
|
394
|
+
const expected = entry.expectedCommitTs ?? -1n;
|
|
395
|
+
idArr[r] = encodeForCarrier(entry.id, idType);
|
|
396
|
+
expArr[r] = encodeForCarrier(expected, "bigint");
|
|
397
|
+
for (let c = 0; c < cols.length; c++) {
|
|
398
|
+
const pgType = types.get(cols[c].toLowerCase()) ?? "text";
|
|
399
|
+
colArrs[c][r] = encodeForCarrier(data[cols[c]], pgType);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (counter % 50 == 0) await new Promise((resolve) => setImmediate(resolve));
|
|
403
|
+
const params = [
|
|
404
|
+
idArr,
|
|
405
|
+
expArr,
|
|
406
|
+
...colArrs
|
|
407
|
+
];
|
|
408
|
+
result.push({
|
|
409
|
+
sql,
|
|
410
|
+
params,
|
|
411
|
+
operation: "updateBatch",
|
|
412
|
+
table,
|
|
413
|
+
entries: rows
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
pgPrepareDeleteSingle(result, table, entry) {
|
|
418
|
+
const expected = entry.expectedCommitTs ?? -1n;
|
|
419
|
+
result.push({
|
|
420
|
+
sql: `DELETE FROM ${table} WHERE id = $1 AND commit_ts = $2`,
|
|
421
|
+
params: [entry.id, expected],
|
|
422
|
+
operation: "deleteSingle",
|
|
423
|
+
table,
|
|
424
|
+
entryId: entry.id,
|
|
425
|
+
expectedTs: expected
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
async pgPrepareDeleteBatch(result, table, entries) {
|
|
429
|
+
if (entries.length === 0) return;
|
|
430
|
+
const types = this.getColumnTypes(table);
|
|
431
|
+
if (!types) {
|
|
432
|
+
this.logger.warn({ table }, "No column types found, falling back to non-batched writes for delete");
|
|
433
|
+
let counter = 0;
|
|
434
|
+
for (const entry of entries) {
|
|
435
|
+
counter++;
|
|
436
|
+
this.pgPrepareDeleteSingle(result, table, entry);
|
|
437
|
+
if (counter % 50 == 0) await new Promise((resolve) => setImmediate(resolve));
|
|
438
|
+
}
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
const sql = this.buildOrGetDeleteSql(table, types);
|
|
442
|
+
const idType = types.get("id") ?? "text";
|
|
443
|
+
const idArr = new Array(entries.length);
|
|
444
|
+
const expArr = new Array(entries.length);
|
|
445
|
+
let counter = 0;
|
|
446
|
+
for (let i = 0; i < entries.length; i++) {
|
|
447
|
+
counter++;
|
|
448
|
+
const entry = entries[i];
|
|
449
|
+
const expected = entry.expectedCommitTs ?? -1n;
|
|
450
|
+
idArr[i] = encodeForCarrier(entry.id, idType);
|
|
451
|
+
expArr[i] = encodeForCarrier(expected, "bigint");
|
|
452
|
+
if (counter % 50 == 0) await new Promise((resolve) => setImmediate(resolve));
|
|
453
|
+
}
|
|
454
|
+
result.push({
|
|
455
|
+
sql,
|
|
456
|
+
params: [idArr, expArr],
|
|
457
|
+
operation: "deleteBatch",
|
|
458
|
+
table,
|
|
459
|
+
entries
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
buildOrGetInsertSql(table, types, cols) {
|
|
463
|
+
const key = `i:${table}:${cols.join(",")}`;
|
|
464
|
+
let sql = this.sqlCache.get(key);
|
|
465
|
+
if (sql) return sql;
|
|
466
|
+
const placeholders = cols.map((c, i) => {
|
|
467
|
+
const pgType = types.get(c.toLowerCase()) ?? "text";
|
|
468
|
+
return `$${i + 1}::${pgCarrierType(pgType)}`;
|
|
469
|
+
});
|
|
470
|
+
const aliases = cols.map((_, i) => `c${i}`);
|
|
471
|
+
const selectExprs = cols.map((c, i) => {
|
|
472
|
+
const pgType = types.get(c.toLowerCase()) ?? "text";
|
|
473
|
+
return pgSelectExpr(aliases[i], pgType);
|
|
474
|
+
});
|
|
475
|
+
sql = `INSERT INTO ${table} (${cols.join(", ")}) SELECT ${selectExprs.join(", ")} FROM unnest(${placeholders.join(", ")}) AS u(${aliases.join(", ")})`;
|
|
476
|
+
this.sqlCache.set(key, sql);
|
|
477
|
+
return sql;
|
|
478
|
+
}
|
|
479
|
+
buildOrGetUpdateSql(table, types, cols) {
|
|
480
|
+
const key = `u:${table}:${cols.join(",")}`;
|
|
481
|
+
let sql = this.sqlCache.get(key);
|
|
482
|
+
if (sql) return sql;
|
|
483
|
+
const idCarrier = `$1::${pgCarrierType(types.get("id") ?? "text")}`;
|
|
484
|
+
const expCarrier = `$2::bigint[]`;
|
|
485
|
+
const dataCarriers = cols.map((c, i) => {
|
|
486
|
+
const pgType = types.get(c.toLowerCase()) ?? "text";
|
|
487
|
+
return `$${i + 3}::${pgCarrierType(pgType)}`;
|
|
488
|
+
});
|
|
489
|
+
const aliases = [
|
|
490
|
+
"id_c",
|
|
491
|
+
"exp_c",
|
|
492
|
+
...cols.map((_, i) => `c${i}`)
|
|
493
|
+
];
|
|
494
|
+
sql = `UPDATE ${table} AS t SET ${cols.map((c, i) => {
|
|
495
|
+
const pgType = types.get(c.toLowerCase()) ?? "text";
|
|
496
|
+
return `${c} = ${pgSelectExpr(`u.${aliases[i + 2]}`, pgType)}`;
|
|
497
|
+
}).join(", ")} FROM unnest(${idCarrier}, ${expCarrier}, ${dataCarriers.join(", ")}) AS u(${aliases.join(", ")}) WHERE t.id = u.id_c AND t.commit_ts = u.exp_c RETURNING t.id AS id`;
|
|
498
|
+
this.sqlCache.set(key, sql);
|
|
499
|
+
return sql;
|
|
500
|
+
}
|
|
501
|
+
buildOrGetDeleteSql(table, types) {
|
|
502
|
+
const key = `d:${table}`;
|
|
503
|
+
let sql = this.sqlCache.get(key);
|
|
504
|
+
if (sql) return sql;
|
|
505
|
+
sql = `DELETE FROM ${table} AS t USING unnest($1::${pgCarrierType(types.get("id") ?? "text")}, $2::bigint[]) AS u(id_c, exp_c) WHERE t.id = u.id_c AND t.commit_ts = u.exp_c RETURNING t.id AS id`;
|
|
506
|
+
this.sqlCache.set(key, sql);
|
|
507
|
+
return sql;
|
|
508
|
+
}
|
|
509
|
+
async pgPrepareCommitLogs(result, writeEntries, commitTs) {
|
|
510
|
+
if (writeEntries.length === 0) return;
|
|
511
|
+
const ids = new Array(writeEntries.length);
|
|
512
|
+
const tss = new Array(writeEntries.length);
|
|
513
|
+
const tableIds = new Array(writeEntries.length);
|
|
514
|
+
const datas = new Array(writeEntries.length);
|
|
515
|
+
let counter = 0;
|
|
516
|
+
for (let i = 0; i < writeEntries.length; i++) {
|
|
517
|
+
counter++;
|
|
518
|
+
const entry = writeEntries[i];
|
|
519
|
+
ids[i] = toBufferView(normalizeIdToBytes(entry.id));
|
|
520
|
+
tss[i] = commitTs;
|
|
521
|
+
tableIds[i] = toBufferView(entry.tableId);
|
|
522
|
+
datas[i] = toBufferView(utf8Encode(supaliveStringify(entry)));
|
|
523
|
+
if (counter % 50 == 0) await new Promise((resolve) => setImmediate(resolve));
|
|
524
|
+
}
|
|
525
|
+
result.push({
|
|
526
|
+
sql: "INSERT INTO commit_logs (id, ts, table_id, data) SELECT * FROM unnest($1::bytea[], $2::bigint[], $3::bytea[], $4::bytea[])",
|
|
527
|
+
params: [
|
|
528
|
+
ids,
|
|
529
|
+
tss,
|
|
530
|
+
tableIds,
|
|
531
|
+
datas
|
|
532
|
+
],
|
|
533
|
+
table: "commit_logs",
|
|
534
|
+
operation: "commit_logs"
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Point-only OCC check. For each genuine point read, compare the row's
|
|
539
|
+
* current commit_ts against the value captured at read time. A `null`
|
|
540
|
+
* expectedCommitTs means "row didn't exist when we read"; any row found
|
|
541
|
+
* now is a conflict. Reads whose row is being written in this same txn
|
|
542
|
+
* are skipped — the CAS UPDATE/DELETE already validated those.
|
|
543
|
+
*/
|
|
544
|
+
pgPrepareValidatePointReadsByCommitTs(readSet, writeSet) {
|
|
545
|
+
const result = [];
|
|
546
|
+
const writeKeys = /* @__PURE__ */ new Set();
|
|
547
|
+
for (const w of writeSet) writeKeys.add(`${w.table} ${w.id}`);
|
|
548
|
+
const byTable = /* @__PURE__ */ new Map();
|
|
549
|
+
const seen = /* @__PURE__ */ new Set();
|
|
550
|
+
for (const entry of readSet) {
|
|
551
|
+
if (entry.kind !== "point") continue;
|
|
552
|
+
const key = `${entry.table} ${entry.id}`;
|
|
553
|
+
if (writeKeys.has(key) || seen.has(key)) continue;
|
|
554
|
+
seen.add(key);
|
|
555
|
+
if (entry.expectedCommitTs === void 0) continue;
|
|
556
|
+
const bucket = byTable.get(entry.table);
|
|
557
|
+
if (bucket) bucket.push({
|
|
558
|
+
entry,
|
|
559
|
+
key
|
|
560
|
+
});
|
|
561
|
+
else byTable.set(entry.table, [{
|
|
562
|
+
entry,
|
|
563
|
+
key
|
|
564
|
+
}]);
|
|
565
|
+
}
|
|
566
|
+
for (const [table, pendings] of byTable) {
|
|
567
|
+
const ids = pendings.map((p) => p.entry.id);
|
|
568
|
+
const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ");
|
|
569
|
+
result.push({
|
|
570
|
+
sql: `SELECT id, commit_ts FROM ${table} WHERE id IN (${placeholders})`,
|
|
571
|
+
params: ids,
|
|
572
|
+
table,
|
|
573
|
+
operation: "pointReadValidation",
|
|
574
|
+
pendingsEntry: pendings
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
return result;
|
|
578
|
+
}
|
|
579
|
+
async commitWrites(beginTs, queries, commitTs) {
|
|
580
|
+
await this.pgApplyWrites(queries.commits);
|
|
581
|
+
if (!queries.hasRangeRead) {
|
|
582
|
+
if ((queries.validateReadPoints?.length ?? 0) > 0) await this.validatePointReadsByCommitTs(queries.validateReadPoints ?? []);
|
|
583
|
+
return { success: true };
|
|
584
|
+
}
|
|
585
|
+
const logs = await this.getCommitLogsSinceTs(beginTs, commitTs, queries.tableIds ?? []);
|
|
586
|
+
if (checkLogsAffectReadSet(logs, queries.rawReadSet ?? [])) throw new OccConflictError(`Conflict detected: overlapping commit logs since ${beginTs}`, { logs });
|
|
587
|
+
return { success: true };
|
|
588
|
+
}
|
|
589
|
+
async pgApplyWrites(result) {
|
|
590
|
+
for (const q of result) switch (q.operation) {
|
|
591
|
+
case "insertSingle":
|
|
592
|
+
try {
|
|
593
|
+
await this.query(q.sql, q.params);
|
|
594
|
+
} catch (err) {
|
|
595
|
+
if (err && typeof err === "object" && err.code === "23505") throw new OccConflictError(`Conflict: insert into ${q.table}/${q.entryId} hit duplicate key`, err);
|
|
596
|
+
throw err;
|
|
597
|
+
}
|
|
598
|
+
break;
|
|
599
|
+
case "insertBatch":
|
|
600
|
+
try {
|
|
601
|
+
await this.query(q.sql, q.params);
|
|
602
|
+
} catch (err) {
|
|
603
|
+
if (err && typeof err === "object" && err.code === "23505") {
|
|
604
|
+
const failedId = (err.detail?.match(/Key \([^)]+\)=\(([^)]+)\)/))?.[1];
|
|
605
|
+
throw new OccConflictError(failedId !== void 0 ? `Conflict: insert into ${q.table}/${failedId} hit duplicate key` : `Conflict: batch insert into ${q.table} hit duplicate key`, err);
|
|
606
|
+
}
|
|
607
|
+
throw err;
|
|
608
|
+
}
|
|
609
|
+
break;
|
|
610
|
+
case "updateSingle":
|
|
611
|
+
if (((await this.query(q.sql, q.params)).rowCount ?? 0) === 0) throw new OccConflictError(`Conflict: CAS update of ${q.table}/${q.entryId} (expected commit_ts=${q.expectedTs}) matched no rows`, {
|
|
612
|
+
table: q.table,
|
|
613
|
+
id: q.entryId,
|
|
614
|
+
expectedTs: q.expectedTs
|
|
615
|
+
});
|
|
616
|
+
break;
|
|
617
|
+
case "updateBatch": {
|
|
618
|
+
const result = await this.query(q.sql, q.params);
|
|
619
|
+
const returned = /* @__PURE__ */ new Set();
|
|
620
|
+
for (const r of result.rows) returned.add(r.id);
|
|
621
|
+
for (const entry of q.entries) if (!returned.has(entry.id)) {
|
|
622
|
+
const expected = entry.expectedCommitTs ?? -1n;
|
|
623
|
+
throw new OccConflictError(`Conflict: CAS update of ${q.table}/${entry.id} (expected commit_ts=${expected}) matched no rows`, {
|
|
624
|
+
table: q.table,
|
|
625
|
+
id: q.entryId,
|
|
626
|
+
expectedTs: q.expectedTs
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
case "deleteSingle":
|
|
632
|
+
if (((await this.query(q.sql, q.params)).rowCount ?? 0) === 0) throw new OccConflictError(`Conflict: CAS delete of ${q.table}/${q.entryId} (expected commit_ts=${q.expectedTs}) matched no rows`, {
|
|
633
|
+
table: q.table,
|
|
634
|
+
id: q.entryId,
|
|
635
|
+
expectedTs: q.expectedTs
|
|
636
|
+
});
|
|
637
|
+
break;
|
|
638
|
+
case "deleteBatch": {
|
|
639
|
+
const result = await this.query(q.sql, q.params);
|
|
640
|
+
const returned = /* @__PURE__ */ new Set();
|
|
641
|
+
for (const r of result.rows) returned.add(r.id);
|
|
642
|
+
for (const entry of q.entries) if (!returned.has(entry.id)) {
|
|
643
|
+
const expected = entry.expectedCommitTs ?? -1n;
|
|
644
|
+
throw new OccConflictError(`Conflict: CAS delete of ${q.table}/${entry.id} (expected commit_ts=${expected}) matched no rows`, {
|
|
645
|
+
table: q.table,
|
|
646
|
+
id: entry.id,
|
|
647
|
+
expected
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
break;
|
|
651
|
+
}
|
|
652
|
+
case "commit_logs":
|
|
653
|
+
await this.query(q.sql, q.params);
|
|
654
|
+
break;
|
|
655
|
+
default: throw new Error("Unhandled Postgres Operation: " + q.operation);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Point-only OCC check. For each genuine point read, compare the row's
|
|
660
|
+
* current commit_ts against the value captured at read time. A `null`
|
|
661
|
+
* expectedCommitTs means "row didn't exist when we read"; any row found
|
|
662
|
+
* now is a conflict. Reads whose row is being written in this same txn
|
|
663
|
+
* are skipped — the CAS UPDATE/DELETE already validated those.
|
|
664
|
+
*/
|
|
665
|
+
async validatePointReadsByCommitTs(queries) {
|
|
666
|
+
for (const q of queries) {
|
|
667
|
+
const result = await this.query(q.sql, q.params);
|
|
668
|
+
const currentById = /* @__PURE__ */ new Map();
|
|
669
|
+
for (const row of result.rows) currentById.set(row.id, BigInt(row.commit_ts));
|
|
670
|
+
for (const { entry } of q.pendingsEntry ?? []) {
|
|
671
|
+
const current = currentById.get(entry.id);
|
|
672
|
+
const expected = entry.expectedCommitTs;
|
|
673
|
+
if (expected === null) {
|
|
674
|
+
if (current !== void 0) throw new OccConflictError(`Conflict: row ${entry.table}/${entry.id} was inserted concurrently`, {
|
|
675
|
+
table: entry.table,
|
|
676
|
+
id: entry.id
|
|
677
|
+
});
|
|
678
|
+
} else {
|
|
679
|
+
if (current === void 0) throw new OccConflictError(`Conflict: row ${entry.table}/${entry.id} was deleted concurrently`, {
|
|
680
|
+
table: entry.table,
|
|
681
|
+
id: entry.id,
|
|
682
|
+
expected
|
|
683
|
+
});
|
|
684
|
+
if (current !== expected) throw new OccConflictError(`Conflict: row ${entry.table}/${entry.id} changed from ts=${expected} to ts=${current}`, {
|
|
685
|
+
table: entry.table,
|
|
686
|
+
id: entry.id,
|
|
687
|
+
expected,
|
|
688
|
+
current
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
async pruneCommitLogsBefore(ts) {
|
|
695
|
+
const result = await this.query(`DELETE FROM commit_logs WHERE ts < $1`, [ts]);
|
|
696
|
+
return BigInt(result.rowCount ?? 0);
|
|
697
|
+
}
|
|
698
|
+
async getMinCommitLogTs() {
|
|
699
|
+
const min = (await this.query(`SELECT min(ts) AS min FROM commit_logs`)).rows[0]?.min;
|
|
700
|
+
return min === null || min === void 0 ? null : BigInt(min);
|
|
701
|
+
}
|
|
702
|
+
async getCommitLogsBetweenTs(beginTs, endTs, tableIds) {
|
|
703
|
+
if (tableIds.length === 0) return [];
|
|
704
|
+
const sql = `SELECT id, ts, table_id, data FROM commit_logs WHERE ts >= $1 AND ts < $2 AND table_id IN (${tableIds.map((_, i) => `$${i + 3}`).join(", ")})`;
|
|
705
|
+
return (await this.query(sql, [
|
|
706
|
+
beginTs,
|
|
707
|
+
endTs,
|
|
708
|
+
...tableIds.map(toBufferView)
|
|
709
|
+
])).rows.map((row) => ({
|
|
710
|
+
id: normalizeToBytes(row.id),
|
|
711
|
+
ts: BigInt(row.ts),
|
|
712
|
+
tableId: normalizeToBytes(row.table_id),
|
|
713
|
+
data: normalizeToBytes(row.data)
|
|
714
|
+
}));
|
|
715
|
+
}
|
|
716
|
+
async getCommitLogsSinceTs(sinceTs, excludeTs, tableIds) {
|
|
717
|
+
if (tableIds.length === 0) return [];
|
|
718
|
+
const sql = `SELECT id, ts, table_id, data FROM commit_logs WHERE ts >= $1 AND ts <> $2 AND table_id IN (${tableIds.map((_, i) => `$${i + 3}`).join(", ")})`;
|
|
719
|
+
return (await this.query(sql, [
|
|
720
|
+
sinceTs,
|
|
721
|
+
excludeTs,
|
|
722
|
+
...tableIds.map(toBufferView)
|
|
723
|
+
])).rows.map((row) => ({
|
|
724
|
+
id: normalizeToBytes(row.id),
|
|
725
|
+
ts: BigInt(row.ts),
|
|
726
|
+
tableId: normalizeToBytes(row.table_id),
|
|
727
|
+
data: normalizeToBytes(row.data)
|
|
728
|
+
}));
|
|
729
|
+
}
|
|
730
|
+
async close() {
|
|
731
|
+
await this.pool.end();
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
var PgTxDatabase = class extends PgDatabase {
|
|
735
|
+
constructor(logger, config, pool, client) {
|
|
736
|
+
super(logger, config, pool);
|
|
737
|
+
this.client = client;
|
|
738
|
+
}
|
|
739
|
+
client;
|
|
740
|
+
async query(sql, params = []) {
|
|
741
|
+
try {
|
|
742
|
+
const result = await this.client.query(sql, params);
|
|
743
|
+
return {
|
|
744
|
+
rows: result.rows,
|
|
745
|
+
rowCount: result.rowCount
|
|
746
|
+
};
|
|
747
|
+
} catch (err) {
|
|
748
|
+
throw translatePgError(err);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
async begin() {
|
|
752
|
+
await this.client.query("BEGIN");
|
|
753
|
+
}
|
|
754
|
+
async commit() {
|
|
755
|
+
await this.client.query("COMMIT");
|
|
756
|
+
}
|
|
757
|
+
async rollback() {
|
|
758
|
+
await this.client.query("ROLLBACK");
|
|
759
|
+
}
|
|
760
|
+
release() {
|
|
761
|
+
this.client.release();
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
/**
|
|
765
|
+
* Returns the unnest carrier array type for a column of `pgType`.
|
|
766
|
+
* Scalars ride as their own array type so PG infers cleanly without an
|
|
767
|
+
* extra cast on the SELECT/SET side. Array and jsonb columns can't ride
|
|
768
|
+
* as their own array type (ragged 2D arrays aren't permitted, and the
|
|
769
|
+
* driver can't tag jsonb sub-elements correctly inside a typed array),
|
|
770
|
+
* so they get the universal `text[]` carrier with an explicit cast in
|
|
771
|
+
* the SELECT/SET clause. Bytea rides natively as `bytea[]`.
|
|
772
|
+
*/
|
|
773
|
+
function pgCarrierType(pgType) {
|
|
774
|
+
const base = pgType.trim().toLowerCase();
|
|
775
|
+
if (base === "bytea") return "bytea[]";
|
|
776
|
+
if (base === "jsonb" || base === "json") return "text[]";
|
|
777
|
+
if (base.endsWith("[]")) return "text[]";
|
|
778
|
+
return `${pgType}[]`;
|
|
779
|
+
}
|
|
780
|
+
/** SELECT/SET expression for an unnest alias of a column with `pgType`.
|
|
781
|
+
* When the carrier matches the column type (scalar / bytea), no cast is
|
|
782
|
+
* needed and the alias passes through. When the carrier is text[] (jsonb
|
|
783
|
+
* or array column), we cast back to the declared type. */
|
|
784
|
+
function pgSelectExpr(alias, pgType) {
|
|
785
|
+
const base = pgType.trim().toLowerCase();
|
|
786
|
+
if (base === "jsonb" || base === "json" || base.endsWith("[]")) return `(${alias})::${pgType}`;
|
|
787
|
+
return alias;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Encodes a JS runtime value for transport via the chosen unnest carrier.
|
|
791
|
+
* For scalar columns the pg driver handles type coercion directly (bigint,
|
|
792
|
+
* number, boolean, Date, etc. all serialize cleanly). For jsonb columns we
|
|
793
|
+
* stringify; for array columns we build a PG array literal. For bytea
|
|
794
|
+
* columns we forward the bytes.
|
|
795
|
+
*
|
|
796
|
+
* Codecs declared by the upstream schema layer run before this point, so
|
|
797
|
+
* `value` is already in the driver-side shape for its declared column.
|
|
798
|
+
*/
|
|
799
|
+
function encodeForCarrier(value, pgTypeBase) {
|
|
800
|
+
if (value === null || value === void 0) return null;
|
|
801
|
+
if (pgTypeBase === "bytea") return toBufferView(normalizeToBytes(value));
|
|
802
|
+
if (pgTypeBase === "jsonb" || pgTypeBase === "json") return typeof value === "string" ? value : supaliveStringify(value);
|
|
803
|
+
if (pgTypeBase.endsWith("[]")) {
|
|
804
|
+
if (!Array.isArray(value)) throw new Error(`Expected array for column of type ${pgTypeBase}, got ${typeof value}`);
|
|
805
|
+
return pgArrayLiteral(value);
|
|
806
|
+
}
|
|
807
|
+
return value;
|
|
808
|
+
}
|
|
809
|
+
/** Serializes a JS array to a Postgres array literal `{a,b,c}`. Strings
|
|
810
|
+
* are double-quoted with backslash/quote escaping; primitives stringify
|
|
811
|
+
* directly; null becomes the literal NULL. */
|
|
812
|
+
function pgArrayLiteral(arr) {
|
|
813
|
+
const parts = new Array(arr.length);
|
|
814
|
+
for (let i = 0; i < arr.length; i++) {
|
|
815
|
+
const v = arr[i];
|
|
816
|
+
if (v === null || v === void 0) parts[i] = "NULL";
|
|
817
|
+
else if (typeof v === "string") parts[i] = `"${v.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
818
|
+
else if (typeof v === "number" || typeof v === "bigint" || typeof v === "boolean") parts[i] = String(v);
|
|
819
|
+
else parts[i] = `"${supaliveStringify(v).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
820
|
+
}
|
|
821
|
+
return `{${parts.join(",")}}`;
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Postgres deadlock_detected (40P01) is transient and semantically equivalent
|
|
825
|
+
* to an OCC conflict from the mutation runner's perspective: re-execute the
|
|
826
|
+
* handler with a fresh snapshot. Wrapping here lets realtime_db.ts stay
|
|
827
|
+
* driver-agnostic — its retry loop already handles OccConflictError.
|
|
828
|
+
*/
|
|
829
|
+
function translatePgError(err) {
|
|
830
|
+
if (err && typeof err === "object" && err.code === "40P01") return new OccConflictError("deadlock detected", err);
|
|
831
|
+
return err;
|
|
832
|
+
}
|
|
833
|
+
function pgScopedTarget(col, pathIndex) {
|
|
834
|
+
return pathIndex === void 0 ? col : `jsonb_path_query_first(${col}::jsonb, $${pathIndex}::jsonpath)`;
|
|
835
|
+
}
|
|
836
|
+
const pgSql = {
|
|
837
|
+
placeholder: (i) => `$${i}`,
|
|
838
|
+
like: (col, i) => `${col} LIKE $${i}`,
|
|
839
|
+
ilike: (col, i) => `${col} ILIKE $${i}`,
|
|
840
|
+
icontains: (col, i) => `${col} ILIKE $${i}`,
|
|
841
|
+
jsonContains: (col, i, opts) => `${pgScopedTarget(col, opts?.pathIndex)} @> $${i}::jsonb`,
|
|
842
|
+
jsonContainedBy: (col, i, opts) => `${pgScopedTarget(col, opts?.pathIndex)} <@ $${i}::jsonb`,
|
|
843
|
+
jsonHasKey: (col, i, opts) => {
|
|
844
|
+
if (opts?.pathCount && opts.pathCount > 0) {
|
|
845
|
+
const joiner = opts.mode === "all" ? " AND " : " OR ";
|
|
846
|
+
const parts = [];
|
|
847
|
+
for (let k = 0; k < opts.pathCount; k++) parts.push(`jsonb_path_exists(${col}, $${i + k}::jsonpath)`);
|
|
848
|
+
return `(${parts.join(joiner)})`;
|
|
849
|
+
}
|
|
850
|
+
return opts?.raw ? `jsonb_path_exists(${col}, $${i}::jsonpath)` : `${col} ? $${i}`;
|
|
851
|
+
},
|
|
852
|
+
jsonArrayContains: (col, i, opts) => `${pgScopedTarget(col, opts?.pathIndex)} @> jsonb_build_array($${i}::jsonb)`
|
|
853
|
+
};
|
|
854
|
+
//#endregion
|
|
855
|
+
export { PgDatabase as t };
|
|
856
|
+
|
|
857
|
+
//# sourceMappingURL=postgres-RYL0Miyw.js.map
|