@nicia-ai/typegraph 0.33.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/backend/postgres/index.cjs +30 -26
- package/dist/backend/postgres/index.d.cts +39 -7
- package/dist/backend/postgres/index.d.ts +39 -7
- package/dist/backend/postgres/index.js +17 -13
- package/dist/backend/postgres/pglite.cjs +22 -18
- package/dist/backend/postgres/pglite.cjs.map +1 -1
- package/dist/backend/postgres/pglite.d.cts +4 -4
- package/dist/backend/postgres/pglite.d.ts +4 -4
- package/dist/backend/postgres/pglite.js +17 -13
- package/dist/backend/postgres/pglite.js.map +1 -1
- package/dist/backend/sqlite/index.cjs +26 -23
- package/dist/backend/sqlite/index.d.cts +8 -8
- package/dist/backend/sqlite/index.d.ts +8 -8
- package/dist/backend/sqlite/index.js +14 -11
- package/dist/backend/sqlite/libsql.cjs +21 -17
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +13 -6
- package/dist/backend/sqlite/libsql.d.ts +13 -6
- package/dist/backend/sqlite/libsql.js +17 -13
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +102 -18
- package/dist/backend/sqlite/local.cjs.map +1 -1
- package/dist/backend/sqlite/local.d.cts +95 -5
- package/dist/backend/sqlite/local.d.ts +95 -5
- package/dist/backend/sqlite/local.js +96 -13
- package/dist/backend/sqlite/local.js.map +1 -1
- package/dist/{chunk-JHOBXD7O.js → chunk-3TWF3SH4.js} +332 -64
- package/dist/chunk-3TWF3SH4.js.map +1 -0
- package/dist/chunk-4JEZZJ6S.cjs +1271 -0
- package/dist/chunk-4JEZZJ6S.cjs.map +1 -0
- package/dist/{chunk-I4W7MKVG.cjs → chunk-4TOD4LBZ.cjs} +249 -294
- package/dist/chunk-4TOD4LBZ.cjs.map +1 -0
- package/dist/chunk-55MZDDZV.js +239 -0
- package/dist/chunk-55MZDDZV.js.map +1 -0
- package/dist/{chunk-LM2IC4ZJ.cjs → chunk-5A6FNS6N.cjs} +75 -19
- package/dist/chunk-5A6FNS6N.cjs.map +1 -0
- package/dist/{chunk-FDN43KXV.cjs → chunk-5AQIKK56.cjs} +65 -24
- package/dist/chunk-5AQIKK56.cjs.map +1 -0
- package/dist/{chunk-IZ4PCL47.js → chunk-5SEGFTZX.js} +4 -66
- package/dist/chunk-5SEGFTZX.js.map +1 -0
- package/dist/{chunk-CWFPJ3RC.js → chunk-6FR2MMS6.js} +7 -7
- package/dist/chunk-6FR2MMS6.js.map +1 -0
- package/dist/chunk-7YSP4V4R.cjs +69 -0
- package/dist/chunk-7YSP4V4R.cjs.map +1 -0
- package/dist/chunk-A42GCBGX.cjs +28 -0
- package/dist/chunk-A42GCBGX.cjs.map +1 -0
- package/dist/chunk-ACSVZPK7.cjs +21 -0
- package/dist/chunk-ACSVZPK7.cjs.map +1 -0
- package/dist/{chunk-OIE2UPVG.cjs → chunk-BLZDPRXT.cjs} +52 -21
- package/dist/chunk-BLZDPRXT.cjs.map +1 -0
- package/dist/chunk-BYPOGQWK.js +25 -0
- package/dist/chunk-BYPOGQWK.js.map +1 -0
- package/dist/{chunk-NG5N7R45.cjs → chunk-CK5BVQOW.cjs} +325 -213
- package/dist/chunk-CK5BVQOW.cjs.map +1 -0
- package/dist/chunk-CTTSDJLY.cjs +261 -0
- package/dist/chunk-CTTSDJLY.cjs.map +1 -0
- package/dist/chunk-CUHM5CWJ.cjs +12 -0
- package/dist/chunk-CUHM5CWJ.cjs.map +1 -0
- package/dist/chunk-CZQ3FO2Q.js +2320 -0
- package/dist/chunk-CZQ3FO2Q.js.map +1 -0
- package/dist/{chunk-CFNT3ITG.cjs → chunk-D7ZEOS56.cjs} +25 -52
- package/dist/chunk-D7ZEOS56.cjs.map +1 -0
- package/dist/chunk-DFVLCOP6.js +10 -0
- package/dist/chunk-DFVLCOP6.js.map +1 -0
- package/dist/chunk-DI74SMXS.cjs +29 -0
- package/dist/chunk-DI74SMXS.cjs.map +1 -0
- package/dist/{chunk-KY5SDVA7.cjs → chunk-EM3CWPND.cjs} +442 -113
- package/dist/chunk-EM3CWPND.cjs.map +1 -0
- package/dist/chunk-EMF62TZG.cjs +1176 -0
- package/dist/chunk-EMF62TZG.cjs.map +1 -0
- package/dist/chunk-EOLERH7Y.cjs +40 -0
- package/dist/chunk-EOLERH7Y.cjs.map +1 -0
- package/dist/{chunk-3QRBXYT5.cjs → chunk-FACJJWGF.cjs} +24 -6
- package/dist/chunk-FACJJWGF.cjs.map +1 -0
- package/dist/{chunk-KTIEB7VH.cjs → chunk-FL472AMI.cjs} +49 -165
- package/dist/chunk-FL472AMI.cjs.map +1 -0
- package/dist/{chunk-4RBAJVEC.cjs → chunk-FN35DLCN.cjs} +31 -9
- package/dist/chunk-FN35DLCN.cjs.map +1 -0
- package/dist/{chunk-C4C4Q7A6.js → chunk-FPIZFYHE.js} +12 -35
- package/dist/chunk-FPIZFYHE.js.map +1 -0
- package/dist/{chunk-XKNAK27R.js → chunk-FRV5Q5IO.js} +64 -8
- package/dist/chunk-FRV5Q5IO.js.map +1 -0
- package/dist/{chunk-K5P5OZXS.js → chunk-G6Q5UM7U.js} +2 -2
- package/dist/{chunk-K5P5OZXS.js.map → chunk-G6Q5UM7U.js.map} +1 -1
- package/dist/chunk-GSQ6NPH6.cjs +100 -0
- package/dist/chunk-GSQ6NPH6.cjs.map +1 -0
- package/dist/chunk-GUR2FNB5.cjs +12 -0
- package/dist/{chunk-6ZR4QC3O.cjs.map → chunk-GUR2FNB5.cjs.map} +1 -1
- package/dist/{chunk-ZFWNO3GE.cjs → chunk-H7YNSMA7.cjs} +107 -2
- package/dist/chunk-H7YNSMA7.cjs.map +1 -0
- package/dist/{chunk-GYVBEZAO.js → chunk-I7ZUZKFD.js} +47 -19
- package/dist/chunk-I7ZUZKFD.js.map +1 -0
- package/dist/chunk-ITE4IXAK.js +25 -0
- package/dist/chunk-ITE4IXAK.js.map +1 -0
- package/dist/{chunk-D3EWZ67S.cjs → chunk-J7WFGBJR.cjs} +3372 -4970
- package/dist/chunk-J7WFGBJR.cjs.map +1 -0
- package/dist/{chunk-PYD3UCDU.js → chunk-JBTOYDMN.js} +202 -251
- package/dist/chunk-JBTOYDMN.js.map +1 -0
- package/dist/{chunk-XVUJY72M.js → chunk-K3PPLHY7.js} +234 -118
- package/dist/chunk-K3PPLHY7.js.map +1 -0
- package/dist/{chunk-454I6GDF.js → chunk-KBGQIPRQ.js} +102 -3
- package/dist/chunk-KBGQIPRQ.js.map +1 -0
- package/dist/chunk-KMI7LYAF.js +1252 -0
- package/dist/chunk-KMI7LYAF.js.map +1 -0
- package/dist/{chunk-JIEJCTDS.cjs → chunk-LGEALRC6.cjs} +21 -4
- package/dist/chunk-LGEALRC6.cjs.map +1 -0
- package/dist/{chunk-TQOYM4LN.js → chunk-MP2JQKSG.js} +21 -5
- package/dist/chunk-MP2JQKSG.js.map +1 -0
- package/dist/{chunk-3642VBVC.cjs → chunk-O7UN7OXA.cjs} +389 -121
- package/dist/chunk-O7UN7OXA.cjs.map +1 -0
- package/dist/chunk-OHMP6N2J.js +47 -0
- package/dist/chunk-OHMP6N2J.js.map +1 -0
- package/dist/{chunk-6NRFUHMS.js → chunk-OR5ZA5WP.js} +135 -24
- package/dist/chunk-OR5ZA5WP.js.map +1 -0
- package/dist/{chunk-PRMKPFN5.js → chunk-Q5TEXCTB.js} +61 -6
- package/dist/chunk-Q5TEXCTB.js.map +1 -0
- package/dist/chunk-QNKSQTKQ.js +1312 -0
- package/dist/chunk-QNKSQTKQ.js.map +1 -0
- package/dist/{chunk-YCV72E6L.js → chunk-QOTI55H7.js} +7 -116
- package/dist/chunk-QOTI55H7.js.map +1 -0
- package/dist/{chunk-QBYTJSAY.js → chunk-QWEUYILR.js} +99 -34
- package/dist/chunk-QWEUYILR.js.map +1 -0
- package/dist/{chunk-OS6KS3HV.js → chunk-RGP33ZJ5.js} +485 -82
- package/dist/chunk-RGP33ZJ5.js.map +1 -0
- package/dist/chunk-RGPG7EOJ.js +94 -0
- package/dist/chunk-RGPG7EOJ.js.map +1 -0
- package/dist/{chunk-WWVV44DY.cjs → chunk-S55OV6PW.cjs} +15 -15
- package/dist/chunk-S55OV6PW.cjs.map +1 -0
- package/dist/{chunk-3E7SNSIA.cjs → chunk-SJDMVITW.cjs} +4 -4
- package/dist/{chunk-3E7SNSIA.cjs.map → chunk-SJDMVITW.cjs.map} +1 -1
- package/dist/{chunk-XLUNB2TZ.js → chunk-SNXVDZAJ.js} +3 -3
- package/dist/{chunk-XLUNB2TZ.js.map → chunk-SNXVDZAJ.js.map} +1 -1
- package/dist/{chunk-CEF2QOTO.js → chunk-T2WUSPDA.js} +49 -8
- package/dist/chunk-T2WUSPDA.js.map +1 -0
- package/dist/{chunk-YW7GHMF4.cjs → chunk-TCOCYN2P.cjs} +75 -20
- package/dist/chunk-TCOCYN2P.cjs.map +1 -0
- package/dist/{chunk-FLRCVI2G.cjs → chunk-TDXIBCGY.cjs} +2 -2
- package/dist/{chunk-FLRCVI2G.cjs.map → chunk-TDXIBCGY.cjs.map} +1 -1
- package/dist/chunk-TEDRJXOG.cjs +32 -0
- package/dist/chunk-TEDRJXOG.cjs.map +1 -0
- package/dist/{chunk-WLP6TKFB.js → chunk-UES55P7G.js} +2809 -4398
- package/dist/chunk-UES55P7G.js.map +1 -0
- package/dist/{chunk-EF3Z645U.cjs → chunk-UMDVATGY.cjs} +6 -72
- package/dist/chunk-UMDVATGY.cjs.map +1 -0
- package/dist/chunk-UR7W5YQK.js +18 -0
- package/dist/chunk-UR7W5YQK.js.map +1 -0
- package/dist/chunk-UT3S4SEN.js +31 -0
- package/dist/chunk-UT3S4SEN.js.map +1 -0
- package/dist/{chunk-3IR2GEMJ.cjs → chunk-UUT7UN2N.cjs} +149 -38
- package/dist/chunk-UUT7UN2N.cjs.map +1 -0
- package/dist/{chunk-PIHXFF73.js → chunk-UZV3AZKF.js} +21 -3
- package/dist/chunk-UZV3AZKF.js.map +1 -0
- package/dist/{chunk-DJYRRDHA.js → chunk-VHMPG6UL.js} +29 -7
- package/dist/chunk-VHMPG6UL.js.map +1 -0
- package/dist/{chunk-MBLXCV2Y.cjs → chunk-VPYHY3LJ.cjs} +111 -43
- package/dist/chunk-VPYHY3LJ.cjs.map +1 -0
- package/dist/{chunk-WYTUF3QO.js → chunk-VSPCZAXF.js} +3 -3
- package/dist/{chunk-WYTUF3QO.js.map → chunk-VSPCZAXF.js.map} +1 -1
- package/dist/chunk-W63OVYY4.js +29 -0
- package/dist/chunk-W63OVYY4.js.map +1 -0
- package/dist/{chunk-UPDMJEW6.js → chunk-WDBCBWC4.js} +356 -30
- package/dist/chunk-WDBCBWC4.js.map +1 -0
- package/dist/chunk-WJT7OU7E.cjs +1334 -0
- package/dist/chunk-WJT7OU7E.cjs.map +1 -0
- package/dist/chunk-XOX22WHL.cjs +2383 -0
- package/dist/chunk-XOX22WHL.cjs.map +1 -0
- package/dist/{ddl-CVnHJcar.d.ts → ddl-C2rZ-Aen.d.ts} +4 -4
- package/dist/{ddl-Dxt_fBHr.d.cts → ddl-CZz7a0E8.d.cts} +4 -4
- package/dist/{extension-types-YGFJPrzK.d.cts → extension-types-ixRpJVUp.d.cts} +24 -1
- package/dist/{extension-types-YGFJPrzK.d.ts → extension-types-ixRpJVUp.d.ts} +24 -1
- package/dist/{types-DGylBhWo.d.ts → fulltext-strategy-B57yvC5Q.d.ts} +2558 -2125
- package/dist/{types-C_UnQOQp.d.cts → fulltext-strategy-CDkSSYhq.d.cts} +2558 -2125
- package/dist/graph-extension/index.cjs +21 -19
- package/dist/graph-extension/index.d.cts +4 -4
- package/dist/graph-extension/index.d.ts +4 -4
- package/dist/graph-extension/index.js +6 -4
- package/dist/graph-merge/index.cjs +408 -169
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +63 -33
- package/dist/graph-merge/index.d.ts +63 -33
- package/dist/graph-merge/index.js +286 -47
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/{index-DGX6D9j1.d.ts → index-6CSUAq-x.d.ts} +234 -93
- package/dist/{index-SEvUHDA6.d.cts → index-Bks_3HHK.d.cts} +234 -93
- package/dist/index.cjs +240 -211
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +35 -27
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +28 -27
- package/dist/indexes/index.d.cts +5 -5
- package/dist/indexes/index.d.ts +5 -5
- package/dist/indexes/index.js +10 -9
- package/dist/interchange/index.cjs +47 -17
- package/dist/interchange/index.d.cts +126 -12
- package/dist/interchange/index.d.ts +126 -12
- package/dist/interchange/index.js +14 -4
- package/dist/{manager-BYl_zyZR.d.cts → manager-DwQi8eV0.d.cts} +9 -2
- package/dist/{manager-C0_r0ALf.d.ts → manager-ejUCB52T.d.ts} +9 -2
- package/dist/{materialize-indexes-D20xNluI.d.cts → materialize-indexes-B4e9360H.d.cts} +20 -4
- package/dist/{materialize-indexes-CAkIYFV-.d.ts → materialize-indexes-te9TPMMJ.d.ts} +20 -4
- package/dist/{postgres-_9psmVGm.d.cts → postgres-CfEqsRMp.d.cts} +152 -1
- package/dist/{postgres-MzBPkYzq.d.ts → postgres-DQ5R6rzV.d.ts} +152 -1
- package/dist/profiler/index.cjs +11 -11
- package/dist/profiler/index.d.cts +7 -7
- package/dist/profiler/index.d.ts +7 -7
- package/dist/profiler/index.js +4 -4
- package/dist/provenance/index.cjs +590 -0
- package/dist/provenance/index.cjs.map +1 -0
- package/dist/provenance/index.d.cts +73 -0
- package/dist/provenance/index.d.ts +73 -0
- package/dist/provenance/index.js +588 -0
- package/dist/provenance/index.js.map +1 -0
- package/dist/schema/index.cjs +55 -38
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +57 -57
- package/dist/schema/index.d.ts +57 -57
- package/dist/schema/index.js +30 -13
- package/dist/schema/index.js.map +1 -1
- package/dist/{sqlite-gm44dShb.d.ts → sqlite-D7zBinNR.d.cts} +92 -1
- package/dist/{sqlite-BfksSb45.d.cts → sqlite-DvQndLky.d.ts} +92 -1
- package/dist/{store-view-FfE5_7eo.d.ts → store-view-BSpqvAxK.d.cts} +445 -46
- package/dist/{store-view-9jQ2rPum.d.cts → store-view-CKbHFRnn.d.ts} +445 -46
- package/dist/{types-B6mhrcLv.d.cts → types-Bv9DcS_E.d.cts} +2 -2
- package/dist/{types-CdWxK-nD.d.ts → types-CoxuV7EJ.d.ts} +2 -2
- package/dist/{where-Bpp2ul_z.d.cts → where-7RKFOsXt.d.ts} +2 -2
- package/dist/{where-BsEXraKW.d.ts → where-DdMIXOtH.d.cts} +2 -2
- package/package.json +21 -14
- package/dist/chunk-2YMGNYXY.js +0 -40
- package/dist/chunk-2YMGNYXY.js.map +0 -1
- package/dist/chunk-3642VBVC.cjs.map +0 -1
- package/dist/chunk-3EUKJEQ3.js +0 -77
- package/dist/chunk-3EUKJEQ3.js.map +0 -1
- package/dist/chunk-3IR2GEMJ.cjs.map +0 -1
- package/dist/chunk-3QRBXYT5.cjs.map +0 -1
- package/dist/chunk-454I6GDF.js.map +0 -1
- package/dist/chunk-4RBAJVEC.cjs.map +0 -1
- package/dist/chunk-6NRFUHMS.js.map +0 -1
- package/dist/chunk-6ZR4QC3O.cjs +0 -12
- package/dist/chunk-73KASJGO.cjs +0 -52
- package/dist/chunk-73KASJGO.cjs.map +0 -1
- package/dist/chunk-BF3ZDEUE.cjs +0 -773
- package/dist/chunk-BF3ZDEUE.cjs.map +0 -1
- package/dist/chunk-C4C4Q7A6.js.map +0 -1
- package/dist/chunk-CEF2QOTO.js.map +0 -1
- package/dist/chunk-CFNT3ITG.cjs.map +0 -1
- package/dist/chunk-CWFPJ3RC.js.map +0 -1
- package/dist/chunk-D3EWZ67S.cjs.map +0 -1
- package/dist/chunk-DJYRRDHA.js.map +0 -1
- package/dist/chunk-EF3Z645U.cjs.map +0 -1
- package/dist/chunk-FDN43KXV.cjs.map +0 -1
- package/dist/chunk-GYVBEZAO.js.map +0 -1
- package/dist/chunk-HTGDWIDE.cjs +0 -89
- package/dist/chunk-HTGDWIDE.cjs.map +0 -1
- package/dist/chunk-I4W7MKVG.cjs.map +0 -1
- package/dist/chunk-IZ4PCL47.js.map +0 -1
- package/dist/chunk-JHOBXD7O.js.map +0 -1
- package/dist/chunk-JIEJCTDS.cjs.map +0 -1
- package/dist/chunk-KTIEB7VH.cjs.map +0 -1
- package/dist/chunk-KY5SDVA7.cjs.map +0 -1
- package/dist/chunk-LM2IC4ZJ.cjs.map +0 -1
- package/dist/chunk-MBLXCV2Y.cjs.map +0 -1
- package/dist/chunk-NG5N7R45.cjs.map +0 -1
- package/dist/chunk-OIE2UPVG.cjs.map +0 -1
- package/dist/chunk-OS6KS3HV.js.map +0 -1
- package/dist/chunk-PIHXFF73.js.map +0 -1
- package/dist/chunk-PRMKPFN5.js.map +0 -1
- package/dist/chunk-PYD3UCDU.js.map +0 -1
- package/dist/chunk-QBYTJSAY.js.map +0 -1
- package/dist/chunk-SPT5JMME.js +0 -610
- package/dist/chunk-SPT5JMME.js.map +0 -1
- package/dist/chunk-SST7XDY6.cjs +0 -624
- package/dist/chunk-SST7XDY6.cjs.map +0 -1
- package/dist/chunk-TQOYM4LN.js.map +0 -1
- package/dist/chunk-UPDMJEW6.js.map +0 -1
- package/dist/chunk-WLP6TKFB.js.map +0 -1
- package/dist/chunk-WWVV44DY.cjs.map +0 -1
- package/dist/chunk-XKNAK27R.js.map +0 -1
- package/dist/chunk-XVUJY72M.js.map +0 -1
- package/dist/chunk-YCV72E6L.js.map +0 -1
- package/dist/chunk-YW7GHMF4.cjs.map +0 -1
- package/dist/chunk-ZFWNO3GE.cjs.map +0 -1
|
@@ -0,0 +1,2383 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkEOLERH7Y_cjs = require('./chunk-EOLERH7Y.cjs');
|
|
4
|
+
var chunk4TOD4LBZ_cjs = require('./chunk-4TOD4LBZ.cjs');
|
|
5
|
+
var chunkBLZDPRXT_cjs = require('./chunk-BLZDPRXT.cjs');
|
|
6
|
+
var chunk7YSP4V4R_cjs = require('./chunk-7YSP4V4R.cjs');
|
|
7
|
+
var chunkH7YNSMA7_cjs = require('./chunk-H7YNSMA7.cjs');
|
|
8
|
+
var chunkLGEALRC6_cjs = require('./chunk-LGEALRC6.cjs');
|
|
9
|
+
var drizzleOrm = require('drizzle-orm');
|
|
10
|
+
var nanoid = require('nanoid');
|
|
11
|
+
|
|
12
|
+
// src/core/temporal.ts
|
|
13
|
+
var RECORDED_MAX = "9999-12-31T23:59:59.999Z";
|
|
14
|
+
function assertValidRecordedInstant(value, path) {
|
|
15
|
+
chunkBLZDPRXT_cjs.validateCanonicalIsoDate(value, path);
|
|
16
|
+
if (value >= RECORDED_MAX) {
|
|
17
|
+
throw new chunkLGEALRC6_cjs.ValidationError(
|
|
18
|
+
`${path} must be before the recorded-time open sentinel ${RECORDED_MAX}.`,
|
|
19
|
+
{
|
|
20
|
+
issues: [
|
|
21
|
+
{
|
|
22
|
+
path,
|
|
23
|
+
message: `Expected a timestamp before ${RECORDED_MAX}, got "${value}"`
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
suggestion: "Use a real recorded-time commit instant, not the open-interval sentinel."
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function asRecordedInstant(value) {
|
|
34
|
+
assertValidRecordedInstant(value, "asRecordedInstant");
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
function resolveReadCoordinate(mode, asOf, suggestion) {
|
|
38
|
+
if (mode !== "asOf" && asOf !== void 0) {
|
|
39
|
+
throw new chunkLGEALRC6_cjs.ValidationError(
|
|
40
|
+
`Temporal mode "${mode}" does not take an asOf timestamp.`,
|
|
41
|
+
{
|
|
42
|
+
issues: [
|
|
43
|
+
{
|
|
44
|
+
path: "asOf",
|
|
45
|
+
message: `asOf is only valid with mode "asOf", not "${mode}"`
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
suggestion: 'Pin an instant with store.asOf(timestamp) or store.view({ mode: "asOf", asOf }); drop asOf for other modes.'
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
assertValidAsOf(
|
|
55
|
+
mode,
|
|
56
|
+
asOf,
|
|
57
|
+
suggestion === void 0 ? void 0 : { suggestion }
|
|
58
|
+
);
|
|
59
|
+
return { valid: asOf === void 0 ? { mode } : { mode, asOf } };
|
|
60
|
+
}
|
|
61
|
+
function withRecordedCoordinate(coordinate, recordedAsOf) {
|
|
62
|
+
assertValidRecordedInstant(recordedAsOf, "asOfRecorded");
|
|
63
|
+
return {
|
|
64
|
+
...coordinate,
|
|
65
|
+
recorded: { asOf: recordedAsOf }
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function assertValidAsOf(mode, asOf, options) {
|
|
69
|
+
if (mode === "asOf" && asOf === void 0) {
|
|
70
|
+
throw new chunkLGEALRC6_cjs.ValidationError(
|
|
71
|
+
'Temporal mode "asOf" requires a timestamp',
|
|
72
|
+
{
|
|
73
|
+
issues: [
|
|
74
|
+
{ path: "asOf", message: "Timestamp is required for asOf mode" }
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
suggestion: options?.suggestion ?? 'Provide an ISO-8601 timestamp for asOf mode, e.g. "2026-01-01T00:00:00.000Z".'
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (asOf !== void 0) {
|
|
83
|
+
chunkBLZDPRXT_cjs.validateCanonicalIsoDate(asOf, "asOf");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function describeCoordinate(coordinate) {
|
|
87
|
+
const { mode, asOf } = coordinate.valid;
|
|
88
|
+
const valid = asOf === void 0 ? `mode "${mode}"` : `mode "${mode}" asOf ${asOf}`;
|
|
89
|
+
return coordinate.recorded === void 0 ? valid : `${valid}, recorded asOf ${coordinate.recorded.asOf}`;
|
|
90
|
+
}
|
|
91
|
+
function coordinateContext(coordinate) {
|
|
92
|
+
const { mode, asOf } = coordinate.valid;
|
|
93
|
+
return {
|
|
94
|
+
temporalMode: mode,
|
|
95
|
+
...asOf !== void 0 && { asOf },
|
|
96
|
+
...coordinate.recorded === void 0 ? {} : { recordedAsOf: coordinate.recorded.asOf }
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
var SqlSchemaDescriptor = class {
|
|
100
|
+
// Private field gives SqlSchema nominal identity; runtime checks use instanceof.
|
|
101
|
+
#brand = true;
|
|
102
|
+
tables;
|
|
103
|
+
nodesTable;
|
|
104
|
+
edgesTable;
|
|
105
|
+
recordedNodesTable;
|
|
106
|
+
recordedEdgesTable;
|
|
107
|
+
recordedClockTable;
|
|
108
|
+
revisionOriginsTable;
|
|
109
|
+
fulltextTable;
|
|
110
|
+
constructor(fields) {
|
|
111
|
+
this.tables = fields.tables;
|
|
112
|
+
this.nodesTable = fields.nodesTable;
|
|
113
|
+
this.edgesTable = fields.edgesTable;
|
|
114
|
+
this.recordedNodesTable = fields.recordedNodesTable;
|
|
115
|
+
this.recordedEdgesTable = fields.recordedEdgesTable;
|
|
116
|
+
this.recordedClockTable = fields.recordedClockTable;
|
|
117
|
+
this.revisionOriginsTable = fields.revisionOriginsTable;
|
|
118
|
+
this.fulltextTable = fields.fulltextTable;
|
|
119
|
+
void this.#brand;
|
|
120
|
+
Object.freeze(this);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var DEFAULT_TABLE_NAMES = {
|
|
124
|
+
nodes: "typegraph_nodes",
|
|
125
|
+
edges: "typegraph_edges",
|
|
126
|
+
recordedNodes: "typegraph_recorded_nodes",
|
|
127
|
+
recordedEdges: "typegraph_recorded_edges",
|
|
128
|
+
recordedClock: "typegraph_recorded_clock",
|
|
129
|
+
revisionOrigins: "typegraph_revision_origins",
|
|
130
|
+
fulltext: "typegraph_node_fulltext",
|
|
131
|
+
uniques: "typegraph_node_uniques"
|
|
132
|
+
};
|
|
133
|
+
function resolveTableNames(names) {
|
|
134
|
+
return {
|
|
135
|
+
nodes: names.nodes ?? DEFAULT_TABLE_NAMES.nodes,
|
|
136
|
+
edges: names.edges ?? DEFAULT_TABLE_NAMES.edges,
|
|
137
|
+
recordedNodes: names.recordedNodes ?? DEFAULT_TABLE_NAMES.recordedNodes,
|
|
138
|
+
recordedEdges: names.recordedEdges ?? DEFAULT_TABLE_NAMES.recordedEdges,
|
|
139
|
+
recordedClock: names.recordedClock ?? DEFAULT_TABLE_NAMES.recordedClock,
|
|
140
|
+
revisionOrigins: names.revisionOrigins ?? DEFAULT_TABLE_NAMES.revisionOrigins,
|
|
141
|
+
fulltext: names.fulltext ?? DEFAULT_TABLE_NAMES.fulltext,
|
|
142
|
+
uniques: names.uniques ?? DEFAULT_TABLE_NAMES.uniques
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
var VALID_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_$]*$/i;
|
|
146
|
+
function validateTableName(name, label) {
|
|
147
|
+
if (!name || name.length === 0) {
|
|
148
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(`${label} table name cannot be empty`);
|
|
149
|
+
}
|
|
150
|
+
if (name.length > chunk7YSP4V4R_cjs.MAX_PG_IDENTIFIER_LENGTH) {
|
|
151
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
152
|
+
`${label} table name exceeds maximum length of ${chunk7YSP4V4R_cjs.MAX_PG_IDENTIFIER_LENGTH} characters`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
if (!VALID_IDENTIFIER_PATTERN.test(name)) {
|
|
156
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
157
|
+
`${label} table name "${name}" is not a valid SQL identifier. Table names must start with a letter or underscore and contain only letters, digits, underscores, or dollar signs.`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function quoteIdentifier(name) {
|
|
162
|
+
return `"${name.replaceAll('"', '""')}"`;
|
|
163
|
+
}
|
|
164
|
+
function freezeSqlSchema(fields) {
|
|
165
|
+
return new SqlSchemaDescriptor(fields);
|
|
166
|
+
}
|
|
167
|
+
function isSqlSchema(schema) {
|
|
168
|
+
return schema instanceof SqlSchemaDescriptor && Object.isFrozen(schema);
|
|
169
|
+
}
|
|
170
|
+
function requireSqlSchema(schema, surface = "SqlSchema") {
|
|
171
|
+
if (isSqlSchema(schema)) return schema;
|
|
172
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
173
|
+
`${surface} must be created with createSqlSchema(...).`,
|
|
174
|
+
{ code: "INVALID_SQL_SCHEMA", surface },
|
|
175
|
+
{
|
|
176
|
+
suggestion: "Pass the result of createSqlSchema(...) instead of a plain schema-shaped object."
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
function createSqlSchema(names = {}) {
|
|
181
|
+
const tables = resolveTableNames(names);
|
|
182
|
+
validateTableName(tables.nodes, "nodes");
|
|
183
|
+
validateTableName(tables.edges, "edges");
|
|
184
|
+
validateTableName(tables.recordedNodes, "recordedNodes");
|
|
185
|
+
validateTableName(tables.recordedEdges, "recordedEdges");
|
|
186
|
+
validateTableName(tables.recordedClock, "recordedClock");
|
|
187
|
+
validateTableName(tables.revisionOrigins, "revisionOrigins");
|
|
188
|
+
validateTableName(tables.fulltext, "fulltext");
|
|
189
|
+
validateTableName(tables.uniques, "uniques");
|
|
190
|
+
return freezeSqlSchema({
|
|
191
|
+
tables: Object.freeze(tables),
|
|
192
|
+
nodesTable: drizzleOrm.sql.raw(quoteIdentifier(tables.nodes)),
|
|
193
|
+
edgesTable: drizzleOrm.sql.raw(quoteIdentifier(tables.edges)),
|
|
194
|
+
recordedNodesTable: drizzleOrm.sql.raw(quoteIdentifier(tables.recordedNodes)),
|
|
195
|
+
recordedEdgesTable: drizzleOrm.sql.raw(quoteIdentifier(tables.recordedEdges)),
|
|
196
|
+
recordedClockTable: drizzleOrm.sql.raw(quoteIdentifier(tables.recordedClock)),
|
|
197
|
+
revisionOriginsTable: drizzleOrm.sql.raw(quoteIdentifier(tables.revisionOrigins)),
|
|
198
|
+
fulltextTable: drizzleOrm.sql.raw(quoteIdentifier(tables.fulltext))
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
var EXTERNAL_RECORDED_READ_SOURCE = /* @__PURE__ */ Symbol(
|
|
202
|
+
"ExternalRecordedReadSource"
|
|
203
|
+
);
|
|
204
|
+
var TYPEGRAPH_RECORDED_READ_SOURCE = /* @__PURE__ */ Symbol(
|
|
205
|
+
"TypeGraphRecordedReadSource"
|
|
206
|
+
);
|
|
207
|
+
function recordedRelation(options) {
|
|
208
|
+
const schema = requireSqlSchema(options.schema, "recordedRelation schema");
|
|
209
|
+
return Object.freeze({
|
|
210
|
+
source: "external",
|
|
211
|
+
schema,
|
|
212
|
+
[EXTERNAL_RECORDED_READ_SOURCE]: true
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function requireExternalRecordedReadSource(source) {
|
|
216
|
+
if (source === void 0) return void 0;
|
|
217
|
+
if (isExternalRecordedReadSource(source)) return source;
|
|
218
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
219
|
+
"recordedRead must be created with recordedRelation({ schema }).",
|
|
220
|
+
{ code: "INVALID_RECORDED_READ_SOURCE" },
|
|
221
|
+
{
|
|
222
|
+
suggestion: "Pass { recordedRead: recordedRelation({ schema }) } for an externally populated recorded relation. Use { history: true } when TypeGraph should capture writes."
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
function isExternalRecordedReadSource(source) {
|
|
227
|
+
if (typeof source !== "object" || source === null) return false;
|
|
228
|
+
const candidate = source;
|
|
229
|
+
return candidate.source === "external" && candidate[EXTERNAL_RECORDED_READ_SOURCE] === true && isSqlSchema(candidate.schema) && Object.isFrozen(candidate);
|
|
230
|
+
}
|
|
231
|
+
function createRecordedReadBinding(schema) {
|
|
232
|
+
const readSchema = requireSqlSchema(schema, "recorded read binding schema");
|
|
233
|
+
return Object.freeze({
|
|
234
|
+
source: "typegraph-capture",
|
|
235
|
+
schema: readSchema,
|
|
236
|
+
[TYPEGRAPH_RECORDED_READ_SOURCE]: true
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
function requireRecordedReadBinding(binding, surface) {
|
|
240
|
+
if (isRecordedReadBinding(binding)) return binding;
|
|
241
|
+
if (binding !== void 0) {
|
|
242
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
243
|
+
"Recorded-time reads require a recorded read relation created by TypeGraph.",
|
|
244
|
+
{ code: "INVALID_RECORDED_READ_BINDING", surface },
|
|
245
|
+
{
|
|
246
|
+
suggestion: "Use createStore(graph, backend, { history: true }) or { recordedRead: recordedRelation({ schema }) } instead of passing a plain object."
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
251
|
+
"Recorded-time reads require a recorded read relation.",
|
|
252
|
+
{ code: "RECORDED_READ_REQUIRES_BINDING", surface },
|
|
253
|
+
{
|
|
254
|
+
suggestion: "Create the store with createStore(graph, backend, { history: true }) to bind TypeGraph's built-in captured relation, or pass { recordedRead: recordedRelation({ schema }) } for an externally populated recorded relation."
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
function isTypeGraphRecordedReadSource(source) {
|
|
259
|
+
if (typeof source !== "object" || source === null) return false;
|
|
260
|
+
const candidate = source;
|
|
261
|
+
return candidate.source === "typegraph-capture" && candidate[TYPEGRAPH_RECORDED_READ_SOURCE] === true && isSqlSchema(candidate.schema) && Object.isFrozen(candidate);
|
|
262
|
+
}
|
|
263
|
+
function isRecordedReadBinding(binding) {
|
|
264
|
+
return isExternalRecordedReadSource(binding) || isTypeGraphRecordedReadSource(binding);
|
|
265
|
+
}
|
|
266
|
+
function recordedReadSqlSchema(binding) {
|
|
267
|
+
const { schema } = requireRecordedReadBinding(
|
|
268
|
+
binding,
|
|
269
|
+
"recorded-read-schema"
|
|
270
|
+
);
|
|
271
|
+
return freezeSqlSchema({
|
|
272
|
+
tables: schema.tables,
|
|
273
|
+
nodesTable: schema.recordedNodesTable,
|
|
274
|
+
edgesTable: schema.recordedEdgesTable,
|
|
275
|
+
recordedNodesTable: schema.recordedNodesTable,
|
|
276
|
+
recordedEdgesTable: schema.recordedEdgesTable,
|
|
277
|
+
recordedClockTable: schema.recordedClockTable,
|
|
278
|
+
revisionOriginsTable: schema.revisionOriginsTable,
|
|
279
|
+
fulltextTable: schema.fulltextTable
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function recordedReadSchemaFor(schema, recordedAsOf, binding, surface) {
|
|
283
|
+
const baseSchema = requireSqlSchema(schema, `${surface} schema`);
|
|
284
|
+
if (recordedAsOf === void 0) return baseSchema;
|
|
285
|
+
return recordedReadSqlSchema(requireRecordedReadBinding(binding, surface));
|
|
286
|
+
}
|
|
287
|
+
var DEFAULT_SQL_SCHEMA = createSqlSchema();
|
|
288
|
+
function vectorSlotKey(nodeKind, fieldPath) {
|
|
289
|
+
return `${nodeKind}\0${fieldPath}`;
|
|
290
|
+
}
|
|
291
|
+
var ALIAS_CTE_PREFIX = "cte_";
|
|
292
|
+
var EMBEDDINGS_CTE_ALIAS = "cte_embeddings";
|
|
293
|
+
var FULLTEXT_CTE_ALIAS = "cte_fulltext";
|
|
294
|
+
var HYBRID_CANDIDATES_CTE_ALIAS = "cte_relevance_candidates";
|
|
295
|
+
function generateId() {
|
|
296
|
+
return nanoid.nanoid();
|
|
297
|
+
}
|
|
298
|
+
function requireRecordedSchema(target) {
|
|
299
|
+
if (target.tableNames === void 0) {
|
|
300
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
301
|
+
"Recorded-time capture requires the backend to expose tableNames.",
|
|
302
|
+
{ dialect: target.dialect },
|
|
303
|
+
{
|
|
304
|
+
suggestion: "Use a built-in SQLite/PostgreSQL backend, or set tableNames on the custom backend so recorded-time capture targets the configured relations."
|
|
305
|
+
}
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
return createSqlSchema(target.tableNames);
|
|
309
|
+
}
|
|
310
|
+
function requireCaptureStatements(target) {
|
|
311
|
+
if (target.executeStatement === void 0) {
|
|
312
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
313
|
+
"Recorded-time capture requires backend.executeStatement support on the transaction backend.",
|
|
314
|
+
{ dialect: target.dialect },
|
|
315
|
+
{
|
|
316
|
+
suggestion: "Use the built-in SQLite/PostgreSQL backends or provide executeStatement on the custom backend's transaction target."
|
|
317
|
+
}
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
async function executeStatement(target, query) {
|
|
322
|
+
requireCaptureStatements(target);
|
|
323
|
+
await target.executeStatement(chunkEOLERH7Y_cjs.asCompiledStatementSql(query));
|
|
324
|
+
}
|
|
325
|
+
function unsupportedPostgresIsolationError(isolationLevel) {
|
|
326
|
+
return new chunkLGEALRC6_cjs.ConfigurationError(
|
|
327
|
+
"Recorded-time capture on PostgreSQL requires read_committed isolation.",
|
|
328
|
+
{ isolationLevel: isolationLevel ?? "unknown" },
|
|
329
|
+
{
|
|
330
|
+
suggestion: "Omit the transaction isolation option or use read_committed. PostgreSQL repeatable_read/serializable snapshots cannot safely allocate the per-graph recorded clock inside the captured transaction."
|
|
331
|
+
}
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
function isSupportedRecordedIsolationLevel(isolationLevel) {
|
|
335
|
+
return isolationLevel === void 0 || isolationLevel === "read_committed" || isolationLevel === "read_uncommitted";
|
|
336
|
+
}
|
|
337
|
+
function assertRequestedRecordedIsolation(backend, options) {
|
|
338
|
+
if (backend.dialect !== "postgres") return;
|
|
339
|
+
const isolationLevel = options?.isolationLevel;
|
|
340
|
+
if (isSupportedRecordedIsolationLevel(isolationLevel)) return;
|
|
341
|
+
throw unsupportedPostgresIsolationError(isolationLevel);
|
|
342
|
+
}
|
|
343
|
+
function normalizeIsolationLevel(value) {
|
|
344
|
+
if (typeof value !== "string") return void 0;
|
|
345
|
+
return value.replaceAll(" ", "_").toLowerCase();
|
|
346
|
+
}
|
|
347
|
+
async function assertRecordedCaptureTransactionIsolation(target) {
|
|
348
|
+
if (target.dialect !== "postgres") return;
|
|
349
|
+
const rows = await target.execute(
|
|
350
|
+
chunkEOLERH7Y_cjs.asCompiledRowsSql(drizzleOrm.sql`
|
|
351
|
+
SELECT current_setting('transaction_isolation') AS transaction_isolation
|
|
352
|
+
`)
|
|
353
|
+
);
|
|
354
|
+
const isolationLevel = normalizeIsolationLevel(
|
|
355
|
+
rows[0]?.transaction_isolation
|
|
356
|
+
);
|
|
357
|
+
if (isSupportedRecordedIsolationLevel(isolationLevel)) return;
|
|
358
|
+
throw unsupportedPostgresIsolationError(isolationLevel);
|
|
359
|
+
}
|
|
360
|
+
function recordedCaptureRequiresCallbackTransactionError(details) {
|
|
361
|
+
return new chunkLGEALRC6_cjs.ConfigurationError(
|
|
362
|
+
"withTransaction() has no recorded-time capture flush point when history is enabled.",
|
|
363
|
+
details,
|
|
364
|
+
{
|
|
365
|
+
suggestion: "Use store.withRecordedTransaction(externalTx, async (tx) => ...) so TypeGraph can flush capture before the caller commits."
|
|
366
|
+
}
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
function historyUnsafeRawWriteError(surface) {
|
|
370
|
+
return new chunkLGEALRC6_cjs.ConfigurationError(
|
|
371
|
+
`${surface} is not available when history capture is enabled because raw SQL writes bypass recorded-time capture.`,
|
|
372
|
+
{ code: "RECORDED_CAPTURE_RAW_SQL_DISABLED" },
|
|
373
|
+
{
|
|
374
|
+
suggestion: "Run graph writes through store.nodes/store.edges (or tx.nodes/tx.edges inside a transaction), or perform raw relational writes outside a history-enabled TypeGraph store."
|
|
375
|
+
}
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
function revisionTrackingUnsafeRawWriteError(surface) {
|
|
379
|
+
return new chunkLGEALRC6_cjs.ConfigurationError(
|
|
380
|
+
`${surface} is not available when revision tracking is enabled because raw SQL writes bypass the revision anchor.`,
|
|
381
|
+
{ code: "REVISION_TRACKING_RAW_SQL_DISABLED" },
|
|
382
|
+
{
|
|
383
|
+
suggestion: "Run graph writes through store.nodes/store.edges (or tx.nodes/tx.edges inside a transaction), so TypeGraph can advance the revision anchor."
|
|
384
|
+
}
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
function failHistoryUnsafeSqlRef() {
|
|
388
|
+
throw historyUnsafeRawWriteError("tx.sql");
|
|
389
|
+
}
|
|
390
|
+
function failRevisionTrackingUnsafeSqlRef() {
|
|
391
|
+
throw revisionTrackingUnsafeRawWriteError("tx.sql");
|
|
392
|
+
}
|
|
393
|
+
function createHistoryUnsafeSqlRef() {
|
|
394
|
+
return createUnsafeSqlRef(failHistoryUnsafeSqlRef);
|
|
395
|
+
}
|
|
396
|
+
function createRevisionTrackingUnsafeSqlRef() {
|
|
397
|
+
return createUnsafeSqlRef(failRevisionTrackingUnsafeSqlRef);
|
|
398
|
+
}
|
|
399
|
+
function createUnsafeSqlRef(fail) {
|
|
400
|
+
return new Proxy(
|
|
401
|
+
function unsafeSqlRef() {
|
|
402
|
+
return fail();
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
get() {
|
|
406
|
+
return fail();
|
|
407
|
+
},
|
|
408
|
+
apply() {
|
|
409
|
+
return fail();
|
|
410
|
+
},
|
|
411
|
+
set() {
|
|
412
|
+
return fail();
|
|
413
|
+
},
|
|
414
|
+
defineProperty() {
|
|
415
|
+
return fail();
|
|
416
|
+
},
|
|
417
|
+
deleteProperty() {
|
|
418
|
+
return fail();
|
|
419
|
+
},
|
|
420
|
+
// Enumeration / inspection traps too, so spreading (`{...tx.sql}`),
|
|
421
|
+
// `Object.keys`, `in`, and prototype reads also fail loudly rather than
|
|
422
|
+
// silently yielding an empty object that reads as "no raw handle".
|
|
423
|
+
has() {
|
|
424
|
+
return fail();
|
|
425
|
+
},
|
|
426
|
+
ownKeys() {
|
|
427
|
+
return fail();
|
|
428
|
+
},
|
|
429
|
+
getOwnPropertyDescriptor() {
|
|
430
|
+
return fail();
|
|
431
|
+
},
|
|
432
|
+
getPrototypeOf() {
|
|
433
|
+
return fail();
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
function rawWriteGuards(target, prefix) {
|
|
439
|
+
return {
|
|
440
|
+
...target.executeStatement === void 0 ? {} : {
|
|
441
|
+
executeStatement(_query) {
|
|
442
|
+
return Promise.reject(
|
|
443
|
+
historyUnsafeRawWriteError(`${prefix}.executeStatement`)
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
...target.executeDdl === void 0 ? {} : {
|
|
448
|
+
executeDdl(_ddl) {
|
|
449
|
+
return Promise.reject(
|
|
450
|
+
historyUnsafeRawWriteError(`${prefix}.executeDdl`)
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
function assertCapturableBackend(backend) {
|
|
457
|
+
if (!backend.capabilities.transactions) {
|
|
458
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
459
|
+
"history: true requires a backend with transaction support.",
|
|
460
|
+
{ dialect: backend.dialect },
|
|
461
|
+
{
|
|
462
|
+
suggestion: "Use a transactional SQLite/PostgreSQL backend or disable recorded-time capture for this store."
|
|
463
|
+
}
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
if (backend.executeStatement === void 0) {
|
|
467
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
468
|
+
"history: true requires a backend that supports executeStatement.",
|
|
469
|
+
{ dialect: backend.dialect },
|
|
470
|
+
{
|
|
471
|
+
suggestion: "Use a built-in SQLite/PostgreSQL backend, or implement executeStatement on the custom backend so recorded-time capture can write history rows."
|
|
472
|
+
}
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
if (backend.capabilities.returning === false) {
|
|
476
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
477
|
+
"history: true requires a backend that supports UPDATE \u2026 RETURNING.",
|
|
478
|
+
{ dialect: backend.dialect },
|
|
479
|
+
{
|
|
480
|
+
suggestion: "Use a built-in SQLite/PostgreSQL backend, or run recorded-time capture on a backend whose engine supports UPDATE \u2026 RETURNING \u2014 capture closes recorded intervals with a RETURNING statement on its hot path."
|
|
481
|
+
}
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
if (backend.tableNames === void 0) {
|
|
485
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
486
|
+
"history: true requires a backend that exposes tableNames.",
|
|
487
|
+
{ dialect: backend.dialect },
|
|
488
|
+
{
|
|
489
|
+
suggestion: "Use a built-in SQLite/PostgreSQL backend, or set tableNames on the custom backend so recorded-time capture can resolve the recorded relations instead of silently falling back to defaults."
|
|
490
|
+
}
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
function assertRevisionTrackableBackend(backend) {
|
|
495
|
+
if (!backend.capabilities.transactions) {
|
|
496
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
497
|
+
"revisionTracking: true requires a backend with transaction support.",
|
|
498
|
+
{ dialect: backend.dialect },
|
|
499
|
+
{
|
|
500
|
+
suggestion: "Use a transactional SQLite/PostgreSQL backend or leave revision tracking disabled."
|
|
501
|
+
}
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
if (backend.executeStatement === void 0) {
|
|
505
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
506
|
+
"revisionTracking: true requires a backend that supports executeStatement.",
|
|
507
|
+
{ dialect: backend.dialect },
|
|
508
|
+
{
|
|
509
|
+
suggestion: "Use a built-in SQLite/PostgreSQL backend, or implement executeStatement so TypeGraph can advance the revision clock."
|
|
510
|
+
}
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
if (backend.tableNames === void 0) {
|
|
514
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
515
|
+
"revisionTracking: true requires a backend that exposes tableNames.",
|
|
516
|
+
{ dialect: backend.dialect },
|
|
517
|
+
{
|
|
518
|
+
suggestion: "Use a built-in SQLite/PostgreSQL backend, or set tableNames so TypeGraph can address the revision clock relation."
|
|
519
|
+
}
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
if (backend.ensureRevisionOriginsTable === void 0) {
|
|
523
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
524
|
+
"revisionTracking: true requires a backend that can bootstrap revision origins.",
|
|
525
|
+
{ dialect: backend.dialect },
|
|
526
|
+
{
|
|
527
|
+
suggestion: "Use a built-in SQLite/PostgreSQL backend, or implement ensureRevisionOriginsTable so TypeGraph can durably namespace revision anchors."
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// src/store/recorded-capture/clock.ts
|
|
534
|
+
var RECORDED_MIN = "1970-01-01T00:00:00.000Z";
|
|
535
|
+
var RECORDED_MAX_TIME = new Date(RECORDED_MAX).getTime();
|
|
536
|
+
var RECORDED_CLOCK_ADVISORY_LOCK_NAMESPACE = "typegraph:recorded-clock";
|
|
537
|
+
var RECORDED_GRAPH_WRITE_ADVISORY_LOCK_NAMESPACE = "typegraph:recorded-graph-write";
|
|
538
|
+
function graphAdvisoryLockSql(namespace, graphId) {
|
|
539
|
+
return drizzleOrm.sql`
|
|
540
|
+
SELECT pg_advisory_xact_lock(
|
|
541
|
+
hashtext(${namespace}),
|
|
542
|
+
hashtext(${graphId})
|
|
543
|
+
)
|
|
544
|
+
`;
|
|
545
|
+
}
|
|
546
|
+
function recordedClockAdvisoryLockSql(graphId) {
|
|
547
|
+
return graphAdvisoryLockSql(RECORDED_CLOCK_ADVISORY_LOCK_NAMESPACE, graphId);
|
|
548
|
+
}
|
|
549
|
+
function recordedGraphWriteAdvisoryLockSql(graphId) {
|
|
550
|
+
return graphAdvisoryLockSql(
|
|
551
|
+
RECORDED_GRAPH_WRITE_ADVISORY_LOCK_NAMESPACE,
|
|
552
|
+
graphId
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
var GRAPH_WRITE_LOCK_EVIDENCE = Object.freeze({});
|
|
556
|
+
function graphWriteLockEvidence() {
|
|
557
|
+
return GRAPH_WRITE_LOCK_EVIDENCE;
|
|
558
|
+
}
|
|
559
|
+
function uncapturedGraphWriteLock() {
|
|
560
|
+
return graphWriteLockEvidence();
|
|
561
|
+
}
|
|
562
|
+
function createRecordedGraphLockMemo() {
|
|
563
|
+
return /* @__PURE__ */ new Map();
|
|
564
|
+
}
|
|
565
|
+
var recordedGraphLockMemos = /* @__PURE__ */ new WeakMap();
|
|
566
|
+
function registerRecordedGraphLockMemo(backend, memo) {
|
|
567
|
+
recordedGraphLockMemos.set(backend, memo);
|
|
568
|
+
}
|
|
569
|
+
async function acquireRecordedGraphWriteLock(target, graphId) {
|
|
570
|
+
await target.execute(
|
|
571
|
+
chunkEOLERH7Y_cjs.asCompiledRowsSql(recordedGraphWriteAdvisoryLockSql(graphId))
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
async function lockRecordedGraphWrite(target, graphId, memo) {
|
|
575
|
+
if (target.dialect !== "postgres") return graphWriteLockEvidence();
|
|
576
|
+
const effectiveMemo = memo ?? recordedGraphLockMemos.get(target);
|
|
577
|
+
if (effectiveMemo === void 0) {
|
|
578
|
+
await acquireRecordedGraphWriteLock(target, graphId);
|
|
579
|
+
return graphWriteLockEvidence();
|
|
580
|
+
}
|
|
581
|
+
let pending = effectiveMemo.get(graphId);
|
|
582
|
+
if (pending === void 0) {
|
|
583
|
+
pending = acquireRecordedGraphWriteLock(target, graphId).catch(
|
|
584
|
+
(error) => {
|
|
585
|
+
effectiveMemo.delete(graphId);
|
|
586
|
+
throw error;
|
|
587
|
+
}
|
|
588
|
+
);
|
|
589
|
+
effectiveMemo.set(graphId, pending);
|
|
590
|
+
}
|
|
591
|
+
await pending;
|
|
592
|
+
return graphWriteLockEvidence();
|
|
593
|
+
}
|
|
594
|
+
function failInvalidClockTimestamp(value) {
|
|
595
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
596
|
+
"Recorded clock row contained an invalid timestamp",
|
|
597
|
+
{ value }
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
var ZONELESS_DATETIME_PATTERN = /^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?$/;
|
|
601
|
+
var OFFSET_DATETIME_PATTERN = /^(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?)(Z|[+-]\d{2}(?::?\d{2})?)$/i;
|
|
602
|
+
function normalizeOffsetDesignator(offset) {
|
|
603
|
+
if (offset.toUpperCase() === "Z") return "Z";
|
|
604
|
+
if (/^[+-]\d{2}$/.test(offset)) return `${offset}:00`;
|
|
605
|
+
if (/^[+-]\d{4}$/.test(offset)) {
|
|
606
|
+
return `${offset.slice(0, 3)}:${offset.slice(3)}`;
|
|
607
|
+
}
|
|
608
|
+
return offset;
|
|
609
|
+
}
|
|
610
|
+
function clockTimestampMs(value) {
|
|
611
|
+
if (ZONELESS_DATETIME_PATTERN.test(value)) {
|
|
612
|
+
return Date.parse(`${value.replace(" ", "T")}Z`);
|
|
613
|
+
}
|
|
614
|
+
const offsetMatch = OFFSET_DATETIME_PATTERN.exec(value);
|
|
615
|
+
if (offsetMatch) {
|
|
616
|
+
const [, date, time, offset] = offsetMatch;
|
|
617
|
+
return Date.parse(`${date}T${time}${normalizeOffsetDesignator(offset)}`);
|
|
618
|
+
}
|
|
619
|
+
return Date.parse(value);
|
|
620
|
+
}
|
|
621
|
+
function toCanonicalIso(value) {
|
|
622
|
+
if (value instanceof Date) {
|
|
623
|
+
if (Number.isNaN(value.getTime())) return failInvalidClockTimestamp(value);
|
|
624
|
+
return value.toISOString();
|
|
625
|
+
}
|
|
626
|
+
if (typeof value === "string") {
|
|
627
|
+
const timestamp = clockTimestampMs(value);
|
|
628
|
+
if (Number.isNaN(timestamp)) return failInvalidClockTimestamp(value);
|
|
629
|
+
return new Date(timestamp).toISOString();
|
|
630
|
+
}
|
|
631
|
+
return failInvalidClockTimestamp(value);
|
|
632
|
+
}
|
|
633
|
+
function nextRecordedCommitTime(previous) {
|
|
634
|
+
const wallTime = Date.parse(chunkBLZDPRXT_cjs.nowIso());
|
|
635
|
+
return previous === void 0 ? wallTime : Math.max(wallTime, Date.parse(previous) + 1);
|
|
636
|
+
}
|
|
637
|
+
async function readRecordedClock(target, schema, graphId) {
|
|
638
|
+
const rows = await target.execute(
|
|
639
|
+
chunkEOLERH7Y_cjs.asCompiledRowsSql(drizzleOrm.sql`
|
|
640
|
+
SELECT recorded_at
|
|
641
|
+
FROM ${schema.recordedClockTable}
|
|
642
|
+
WHERE graph_id = ${graphId}
|
|
643
|
+
`)
|
|
644
|
+
);
|
|
645
|
+
const first = rows[0];
|
|
646
|
+
return first === void 0 ? void 0 : toCanonicalIso(first.recorded_at);
|
|
647
|
+
}
|
|
648
|
+
async function readRevisionOrigin(target, schema, graphId) {
|
|
649
|
+
const rows = await target.execute(
|
|
650
|
+
chunkEOLERH7Y_cjs.asCompiledRowsSql(drizzleOrm.sql`
|
|
651
|
+
SELECT origin
|
|
652
|
+
FROM ${schema.revisionOriginsTable}
|
|
653
|
+
WHERE graph_id = ${graphId}
|
|
654
|
+
`)
|
|
655
|
+
);
|
|
656
|
+
const first = rows[0];
|
|
657
|
+
if (first === void 0) return void 0;
|
|
658
|
+
if (typeof first.origin !== "string" || first.origin.length === 0) {
|
|
659
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
660
|
+
"Revision origin row contained an invalid origin",
|
|
661
|
+
{ graphId, origin: first.origin }
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
return first.origin;
|
|
665
|
+
}
|
|
666
|
+
async function ensureRevisionOrigin(target, schema, graphId) {
|
|
667
|
+
const ensureTable = target.ensureRevisionOriginsTable;
|
|
668
|
+
if (ensureTable === void 0) {
|
|
669
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
670
|
+
"Revision tracking requires a backend that can bootstrap revision origins.",
|
|
671
|
+
{ dialect: target.dialect },
|
|
672
|
+
{
|
|
673
|
+
suggestion: "Use a built-in SQLite/PostgreSQL backend, or implement ensureRevisionOriginsTable on the custom backend."
|
|
674
|
+
}
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
await ensureTable();
|
|
678
|
+
const existing = await readRevisionOrigin(target, schema, graphId);
|
|
679
|
+
if (existing !== void 0) return existing;
|
|
680
|
+
await executeStatement(
|
|
681
|
+
target,
|
|
682
|
+
drizzleOrm.sql`
|
|
683
|
+
INSERT INTO ${schema.revisionOriginsTable} (graph_id, origin)
|
|
684
|
+
VALUES (${graphId}, ${generateId()})
|
|
685
|
+
ON CONFLICT (graph_id) DO NOTHING
|
|
686
|
+
`
|
|
687
|
+
);
|
|
688
|
+
const origin = await readRevisionOrigin(target, schema, graphId);
|
|
689
|
+
if (origin !== void 0) return origin;
|
|
690
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
691
|
+
"Revision origin was not persisted after initialization.",
|
|
692
|
+
{ graphId, dialect: target.dialect }
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
async function writeRecordedClock(target, schema, graphId, recordedAt) {
|
|
696
|
+
await executeStatement(
|
|
697
|
+
target,
|
|
698
|
+
drizzleOrm.sql`
|
|
699
|
+
INSERT INTO ${schema.recordedClockTable} (graph_id, recorded_at)
|
|
700
|
+
VALUES (${graphId}, ${recordedAt})
|
|
701
|
+
ON CONFLICT (graph_id) DO UPDATE SET recorded_at = ${recordedAt}
|
|
702
|
+
`
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
async function lockRecordedClock(target, schema, graphId, ownsWriteLock) {
|
|
706
|
+
if (target.dialect === "postgres") {
|
|
707
|
+
await target.execute(
|
|
708
|
+
chunkEOLERH7Y_cjs.asCompiledRowsSql(recordedClockAdvisoryLockSql(graphId))
|
|
709
|
+
);
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
if (ownsWriteLock) return;
|
|
713
|
+
await executeStatement(
|
|
714
|
+
target,
|
|
715
|
+
drizzleOrm.sql`
|
|
716
|
+
INSERT INTO ${schema.recordedClockTable} (graph_id, recorded_at)
|
|
717
|
+
VALUES (${graphId}, ${RECORDED_MIN})
|
|
718
|
+
ON CONFLICT (graph_id) DO UPDATE SET recorded_at = recorded_at
|
|
719
|
+
`
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
async function allocateRecordedCommit(target, schema, graphId, ownsWriteLock, previousRevision) {
|
|
723
|
+
await lockRecordedClock(target, schema, graphId, ownsWriteLock);
|
|
724
|
+
const previous = previousRevision ?? await readRecordedClock(target, schema, graphId);
|
|
725
|
+
const recordedCommitTime = nextRecordedCommitTime(previous);
|
|
726
|
+
if (!Number.isFinite(recordedCommitTime) || recordedCommitTime >= RECORDED_MAX_TIME) {
|
|
727
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
728
|
+
`Recorded commit clock reached the open sentinel ${RECORDED_MAX}`,
|
|
729
|
+
{ graphId, recordedCommitTime },
|
|
730
|
+
{
|
|
731
|
+
suggestion: "Use a graph with a normal recorded-time clock; the open sentinel is reserved for relation intervals."
|
|
732
|
+
}
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
const recordedCommit = new Date(recordedCommitTime).toISOString();
|
|
736
|
+
await writeRecordedClock(target, schema, graphId, recordedCommit);
|
|
737
|
+
return recordedCommit;
|
|
738
|
+
}
|
|
739
|
+
async function advanceRevisionClock(target, schema, graphId, ownsWriteLock, previousRevision) {
|
|
740
|
+
return allocateRecordedCommit(
|
|
741
|
+
target,
|
|
742
|
+
schema,
|
|
743
|
+
graphId,
|
|
744
|
+
ownsWriteLock,
|
|
745
|
+
previousRevision
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// src/store/insert-dispatch.ts
|
|
750
|
+
function nodeInsertDispatch(backend) {
|
|
751
|
+
return {
|
|
752
|
+
one: (params) => backend.insertNode(params),
|
|
753
|
+
oneNoReturn: backend.insertNodeNoReturn === void 0 ? void 0 : (params) => backend.insertNodeNoReturn(params),
|
|
754
|
+
batch: backend.insertNodesBatch === void 0 ? void 0 : (params) => backend.insertNodesBatch(params),
|
|
755
|
+
batchReturning: backend.insertNodesBatchReturning === void 0 ? void 0 : (params) => backend.insertNodesBatchReturning(params)
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
function edgeInsertDispatch(backend) {
|
|
759
|
+
return {
|
|
760
|
+
one: (params) => backend.insertEdge(params),
|
|
761
|
+
oneNoReturn: backend.insertEdgeNoReturn === void 0 ? void 0 : (params) => backend.insertEdgeNoReturn(params),
|
|
762
|
+
batch: backend.insertEdgesBatch === void 0 ? void 0 : (params) => backend.insertEdgesBatch(params),
|
|
763
|
+
batchReturning: backend.insertEdgesBatchReturning === void 0 ? void 0 : (params) => backend.insertEdgesBatchReturning(params)
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
async function runInsertNoReturn(dispatch, params) {
|
|
767
|
+
if (dispatch.oneNoReturn !== void 0) {
|
|
768
|
+
await dispatch.oneNoReturn(params);
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
await dispatch.one(params);
|
|
772
|
+
}
|
|
773
|
+
async function runInsertBatch(dispatch, params) {
|
|
774
|
+
if (params.length === 0) return;
|
|
775
|
+
if (dispatch.batch !== void 0) {
|
|
776
|
+
await dispatch.batch(params);
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
for (const insertParams of params) {
|
|
780
|
+
await runInsertNoReturn(dispatch, insertParams);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
async function runInsertBatchReturning(dispatch, params) {
|
|
784
|
+
if (dispatch.batchReturning !== void 0) {
|
|
785
|
+
return dispatch.batchReturning(params);
|
|
786
|
+
}
|
|
787
|
+
const rows = [];
|
|
788
|
+
for (const insertParams of params) {
|
|
789
|
+
rows.push(await dispatch.one(insertParams));
|
|
790
|
+
}
|
|
791
|
+
return rows;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/store/row-fetch.ts
|
|
795
|
+
async function getRowsByIds(ids, policy) {
|
|
796
|
+
const rowsById = /* @__PURE__ */ new Map();
|
|
797
|
+
if (ids.length === 0) return rowsById;
|
|
798
|
+
if (policy.batch !== void 0) {
|
|
799
|
+
const rows2 = await policy.batch(ids);
|
|
800
|
+
for (const row of rows2) {
|
|
801
|
+
rowsById.set(row.id, row);
|
|
802
|
+
}
|
|
803
|
+
return rowsById;
|
|
804
|
+
}
|
|
805
|
+
const uniqueIds = [...new Set(ids)];
|
|
806
|
+
const rows = await Promise.all(uniqueIds.map((id) => policy.one(id)));
|
|
807
|
+
for (const row of rows) {
|
|
808
|
+
if (row !== void 0) rowsById.set(row.id, row);
|
|
809
|
+
}
|
|
810
|
+
return rowsById;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// src/store/edge-fetch.ts
|
|
814
|
+
async function getEdgeRowsByIds(backend, graphId, ids) {
|
|
815
|
+
return getRowsByIds(ids, {
|
|
816
|
+
batch: backend.getEdges === void 0 ? void 0 : (batchIds) => backend.getEdges(graphId, batchIds),
|
|
817
|
+
one: (id) => backend.getEdge(graphId, id)
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// src/store/node-fetch.ts
|
|
822
|
+
async function getNodeRowsByIds(backend, graphId, kind, ids) {
|
|
823
|
+
return getRowsByIds(ids, {
|
|
824
|
+
batch: backend.getNodes === void 0 ? void 0 : (batchIds) => backend.getNodes(graphId, kind, batchIds),
|
|
825
|
+
one: (id) => backend.getNode(graphId, kind, id)
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
var RECORDED_HISTORY_META = "{}";
|
|
829
|
+
var RECORDED_NODE_COLUMNS = [
|
|
830
|
+
"history_id",
|
|
831
|
+
"graph_id",
|
|
832
|
+
"kind",
|
|
833
|
+
"id",
|
|
834
|
+
"props",
|
|
835
|
+
"version",
|
|
836
|
+
"valid_from",
|
|
837
|
+
"valid_to",
|
|
838
|
+
"created_at",
|
|
839
|
+
"updated_at",
|
|
840
|
+
"deleted_at",
|
|
841
|
+
"recorded_from",
|
|
842
|
+
"recorded_to",
|
|
843
|
+
"op",
|
|
844
|
+
"schema_version",
|
|
845
|
+
"tx_id",
|
|
846
|
+
"meta"
|
|
847
|
+
];
|
|
848
|
+
var RECORDED_EDGE_COLUMNS = [
|
|
849
|
+
"history_id",
|
|
850
|
+
"graph_id",
|
|
851
|
+
"id",
|
|
852
|
+
"kind",
|
|
853
|
+
"from_kind",
|
|
854
|
+
"from_id",
|
|
855
|
+
"to_kind",
|
|
856
|
+
"to_id",
|
|
857
|
+
"props",
|
|
858
|
+
"valid_from",
|
|
859
|
+
"valid_to",
|
|
860
|
+
"created_at",
|
|
861
|
+
"updated_at",
|
|
862
|
+
"deleted_at",
|
|
863
|
+
"recorded_from",
|
|
864
|
+
"recorded_to",
|
|
865
|
+
"op",
|
|
866
|
+
"schema_version",
|
|
867
|
+
"tx_id",
|
|
868
|
+
"meta"
|
|
869
|
+
];
|
|
870
|
+
var RECORDED_NODE_COLUMN_LIST = drizzleOrm.sql.raw(RECORDED_NODE_COLUMNS.join(", "));
|
|
871
|
+
var RECORDED_EDGE_COLUMN_LIST = drizzleOrm.sql.raw(RECORDED_EDGE_COLUMNS.join(", "));
|
|
872
|
+
var RECORDED_BIND_PARAM_BUDGET = 900;
|
|
873
|
+
function recordedBindParamBudget(target) {
|
|
874
|
+
const budget = target.capabilities.maxBindParameters ?? RECORDED_BIND_PARAM_BUDGET;
|
|
875
|
+
if (!Number.isSafeInteger(budget) || budget < 1) {
|
|
876
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
877
|
+
`backend capabilities.maxBindParameters must be a positive integer, got: ${String(budget)}`,
|
|
878
|
+
{
|
|
879
|
+
code: "INVALID_BACKEND_CAPABILITY",
|
|
880
|
+
capability: "maxBindParameters",
|
|
881
|
+
value: budget
|
|
882
|
+
}
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
return budget;
|
|
886
|
+
}
|
|
887
|
+
function recordedChunkSize(target, columnCount) {
|
|
888
|
+
const budget = recordedBindParamBudget(target);
|
|
889
|
+
return Math.max(1, Math.floor(budget / columnCount));
|
|
890
|
+
}
|
|
891
|
+
function recordedCommonCells() {
|
|
892
|
+
return {
|
|
893
|
+
history_id: () => drizzleOrm.sql`${generateId()}`,
|
|
894
|
+
graph_id: (row) => drizzleOrm.sql`${row.graph_id}`,
|
|
895
|
+
id: (row) => drizzleOrm.sql`${row.id}`,
|
|
896
|
+
kind: (row) => drizzleOrm.sql`${row.kind}`,
|
|
897
|
+
props: (row) => drizzleOrm.sql`${chunk4TOD4LBZ_cjs.rowPropsToJsonText(row.props)}`,
|
|
898
|
+
valid_from: (row) => drizzleOrm.sql`${chunk7YSP4V4R_cjs.sqlNull(row.valid_from)}`,
|
|
899
|
+
valid_to: (row) => drizzleOrm.sql`${chunk7YSP4V4R_cjs.sqlNull(row.valid_to)}`,
|
|
900
|
+
created_at: (row) => drizzleOrm.sql`${row.created_at}`,
|
|
901
|
+
updated_at: (row) => drizzleOrm.sql`${row.updated_at}`,
|
|
902
|
+
deleted_at: (row) => drizzleOrm.sql`${chunk7YSP4V4R_cjs.sqlNull(row.deleted_at)}`,
|
|
903
|
+
recorded_from: (_row, recordedCommit) => drizzleOrm.sql`${recordedCommit}`,
|
|
904
|
+
recorded_to: () => drizzleOrm.sql`${RECORDED_MAX}`,
|
|
905
|
+
op: (_row, _recordedCommit, operation) => drizzleOrm.sql`${operation}`,
|
|
906
|
+
schema_version: () => drizzleOrm.sql`NULL`,
|
|
907
|
+
tx_id: () => drizzleOrm.sql`NULL`,
|
|
908
|
+
meta: () => drizzleOrm.sql`${RECORDED_HISTORY_META}`
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
var recordedNodeCells = {
|
|
912
|
+
...recordedCommonCells(),
|
|
913
|
+
version: (row) => drizzleOrm.sql`${row.version}`
|
|
914
|
+
};
|
|
915
|
+
var recordedEdgeCells = {
|
|
916
|
+
...recordedCommonCells(),
|
|
917
|
+
from_kind: (row) => drizzleOrm.sql`${row.from_kind}`,
|
|
918
|
+
from_id: (row) => drizzleOrm.sql`${row.from_id}`,
|
|
919
|
+
to_kind: (row) => drizzleOrm.sql`${row.to_kind}`,
|
|
920
|
+
to_id: (row) => drizzleOrm.sql`${row.to_id}`
|
|
921
|
+
};
|
|
922
|
+
function recordedValuesTuple(columns, cells, row, recordedCommit, operation) {
|
|
923
|
+
const tuple = columns.map(
|
|
924
|
+
(column) => cells[column](row, recordedCommit, operation)
|
|
925
|
+
);
|
|
926
|
+
return drizzleOrm.sql`(${drizzleOrm.sql.join(tuple, drizzleOrm.sql`, `)})`;
|
|
927
|
+
}
|
|
928
|
+
async function insertRecordedRows(target, table, columnList, columns, cells, inserts, recordedCommit) {
|
|
929
|
+
if (inserts.length === 0) return;
|
|
930
|
+
const values = inserts.map(
|
|
931
|
+
(insert) => recordedValuesTuple(
|
|
932
|
+
columns,
|
|
933
|
+
cells,
|
|
934
|
+
insert.row,
|
|
935
|
+
recordedCommit,
|
|
936
|
+
insert.operation
|
|
937
|
+
)
|
|
938
|
+
);
|
|
939
|
+
await executeStatement(
|
|
940
|
+
target,
|
|
941
|
+
drizzleOrm.sql`
|
|
942
|
+
INSERT INTO ${table} (${columnList})
|
|
943
|
+
VALUES ${drizzleOrm.sql.join(values, drizzleOrm.sql`, `)}
|
|
944
|
+
`
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
function recordedNodeChunkSize(target) {
|
|
948
|
+
return recordedChunkSize(target, RECORDED_NODE_COLUMNS.length);
|
|
949
|
+
}
|
|
950
|
+
function recordedEdgeChunkSize(target) {
|
|
951
|
+
return recordedChunkSize(target, RECORDED_EDGE_COLUMNS.length);
|
|
952
|
+
}
|
|
953
|
+
function insertRecordedNodeRows(target, table, inserts, recordedCommit) {
|
|
954
|
+
return insertRecordedRows(
|
|
955
|
+
target,
|
|
956
|
+
table,
|
|
957
|
+
RECORDED_NODE_COLUMN_LIST,
|
|
958
|
+
RECORDED_NODE_COLUMNS,
|
|
959
|
+
recordedNodeCells,
|
|
960
|
+
inserts,
|
|
961
|
+
recordedCommit
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
function insertRecordedEdgeRows(target, table, inserts, recordedCommit) {
|
|
965
|
+
return insertRecordedRows(
|
|
966
|
+
target,
|
|
967
|
+
table,
|
|
968
|
+
RECORDED_EDGE_COLUMN_LIST,
|
|
969
|
+
RECORDED_EDGE_COLUMNS,
|
|
970
|
+
recordedEdgeCells,
|
|
971
|
+
inserts,
|
|
972
|
+
recordedCommit
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
// src/store/recorded-capture/flush.ts
|
|
977
|
+
function entityKey(entity) {
|
|
978
|
+
switch (entity.entity) {
|
|
979
|
+
case "node": {
|
|
980
|
+
return `node\0${entity.graphId}\0${entity.kind}\0${entity.id}`;
|
|
981
|
+
}
|
|
982
|
+
case "edge": {
|
|
983
|
+
return `edge\0${entity.graphId}\0${entity.id}`;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
async function closeOpenReturning(target, table, graphId, ids, recordedCommit, kind) {
|
|
988
|
+
const kindFilter = kind === void 0 ? drizzleOrm.sql`` : drizzleOrm.sql`AND kind = ${kind}`;
|
|
989
|
+
const rows = await target.execute(
|
|
990
|
+
chunkEOLERH7Y_cjs.asCompiledRowsSql(drizzleOrm.sql`
|
|
991
|
+
UPDATE ${table}
|
|
992
|
+
SET recorded_to = ${recordedCommit}
|
|
993
|
+
WHERE graph_id = ${graphId}
|
|
994
|
+
${kindFilter}
|
|
995
|
+
AND recorded_to = ${RECORDED_MAX}
|
|
996
|
+
AND id IN (${chunk4TOD4LBZ_cjs.sqlValueList(ids)})
|
|
997
|
+
RETURNING id, deleted_at
|
|
998
|
+
`)
|
|
999
|
+
);
|
|
1000
|
+
return new Map(rows.map((row) => [row.id, chunk4TOD4LBZ_cjs.isPresent(row.deleted_at)]));
|
|
1001
|
+
}
|
|
1002
|
+
function recordedOp(hadOpenRow, priorRowWasTombstone, after) {
|
|
1003
|
+
if (chunk4TOD4LBZ_cjs.isPresent(after.deleted_at)) return "delete";
|
|
1004
|
+
if (!hadOpenRow || priorRowWasTombstone) return "create";
|
|
1005
|
+
return "update";
|
|
1006
|
+
}
|
|
1007
|
+
function groupNodesByKind(entities) {
|
|
1008
|
+
const byKind = /* @__PURE__ */ new Map();
|
|
1009
|
+
for (const entity of entities) {
|
|
1010
|
+
const group = byKind.get(entity.kind) ?? [];
|
|
1011
|
+
group.push(entity);
|
|
1012
|
+
byKind.set(entity.kind, group);
|
|
1013
|
+
}
|
|
1014
|
+
return byKind;
|
|
1015
|
+
}
|
|
1016
|
+
async function resolveAfterImages(entities, readMissing) {
|
|
1017
|
+
const afterById = /* @__PURE__ */ new Map();
|
|
1018
|
+
const needRead = [];
|
|
1019
|
+
for (const entity of entities) {
|
|
1020
|
+
if (entity.afterImage === void 0) {
|
|
1021
|
+
needRead.push(entity.id);
|
|
1022
|
+
} else {
|
|
1023
|
+
afterById.set(entity.id, entity.afterImage);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
if (needRead.length > 0) {
|
|
1027
|
+
for (const [id, row] of await readMissing(needRead)) afterById.set(id, row);
|
|
1028
|
+
}
|
|
1029
|
+
return afterById;
|
|
1030
|
+
}
|
|
1031
|
+
function recordedInsertsFor(afterById, closed) {
|
|
1032
|
+
return [...afterById.values()].map((row) => ({
|
|
1033
|
+
row,
|
|
1034
|
+
operation: recordedOp(closed.has(row.id), closed.get(row.id) ?? false, row)
|
|
1035
|
+
}));
|
|
1036
|
+
}
|
|
1037
|
+
async function flushNodes(target, schema, graphId, entities, recordedCommit) {
|
|
1038
|
+
const chunkSize = recordedNodeChunkSize(target);
|
|
1039
|
+
for (const [kind, group] of groupNodesByKind(entities)) {
|
|
1040
|
+
for (const entityChunk of chunk4TOD4LBZ_cjs.chunk(group, chunkSize)) {
|
|
1041
|
+
const ids = entityChunk.map((entity) => entity.id);
|
|
1042
|
+
const closed = await closeOpenReturning(
|
|
1043
|
+
target,
|
|
1044
|
+
schema.recordedNodesTable,
|
|
1045
|
+
graphId,
|
|
1046
|
+
ids,
|
|
1047
|
+
recordedCommit,
|
|
1048
|
+
kind
|
|
1049
|
+
);
|
|
1050
|
+
const afterById = await resolveAfterImages(
|
|
1051
|
+
entityChunk,
|
|
1052
|
+
(missing) => getNodeRowsByIds(target, graphId, kind, missing)
|
|
1053
|
+
);
|
|
1054
|
+
await insertRecordedNodeRows(
|
|
1055
|
+
target,
|
|
1056
|
+
schema.recordedNodesTable,
|
|
1057
|
+
recordedInsertsFor(afterById, closed),
|
|
1058
|
+
recordedCommit
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
async function flushEdges(target, schema, graphId, entities, recordedCommit) {
|
|
1064
|
+
const chunkSize = recordedEdgeChunkSize(target);
|
|
1065
|
+
for (const entityChunk of chunk4TOD4LBZ_cjs.chunk(entities, chunkSize)) {
|
|
1066
|
+
const ids = entityChunk.map((entity) => entity.id);
|
|
1067
|
+
const closed = await closeOpenReturning(
|
|
1068
|
+
target,
|
|
1069
|
+
schema.recordedEdgesTable,
|
|
1070
|
+
graphId,
|
|
1071
|
+
ids,
|
|
1072
|
+
recordedCommit
|
|
1073
|
+
);
|
|
1074
|
+
const afterById = await resolveAfterImages(
|
|
1075
|
+
entityChunk,
|
|
1076
|
+
(missing) => getEdgeRowsByIds(target, graphId, missing)
|
|
1077
|
+
);
|
|
1078
|
+
await insertRecordedEdgeRows(
|
|
1079
|
+
target,
|
|
1080
|
+
schema.recordedEdgesTable,
|
|
1081
|
+
recordedInsertsFor(afterById, closed),
|
|
1082
|
+
recordedCommit
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
async function closeOpenByKind(target, table, graphId, kind, recordedCommit) {
|
|
1087
|
+
await executeStatement(
|
|
1088
|
+
target,
|
|
1089
|
+
drizzleOrm.sql`
|
|
1090
|
+
UPDATE ${table}
|
|
1091
|
+
SET recorded_to = ${recordedCommit}
|
|
1092
|
+
WHERE graph_id = ${graphId}
|
|
1093
|
+
AND kind = ${kind}
|
|
1094
|
+
AND recorded_to = ${RECORDED_MAX}
|
|
1095
|
+
`
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
async function closeOpenEdgesByNodeKind(target, schema, graphId, nodeKind, recordedCommit) {
|
|
1099
|
+
await executeStatement(
|
|
1100
|
+
target,
|
|
1101
|
+
drizzleOrm.sql`
|
|
1102
|
+
UPDATE ${schema.recordedEdgesTable}
|
|
1103
|
+
SET recorded_to = ${recordedCommit}
|
|
1104
|
+
WHERE graph_id = ${graphId}
|
|
1105
|
+
AND (from_kind = ${nodeKind} OR to_kind = ${nodeKind})
|
|
1106
|
+
AND recorded_to = ${RECORDED_MAX}
|
|
1107
|
+
`
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
async function closeRecordedHardDeletedKind(target, schema, graphId, removal, ownsWriteLock) {
|
|
1111
|
+
const recordedCommit = await allocateRecordedCommit(
|
|
1112
|
+
target,
|
|
1113
|
+
schema,
|
|
1114
|
+
graphId,
|
|
1115
|
+
ownsWriteLock
|
|
1116
|
+
);
|
|
1117
|
+
if (removal.entity === "node") {
|
|
1118
|
+
await closeOpenByKind(
|
|
1119
|
+
target,
|
|
1120
|
+
schema.recordedNodesTable,
|
|
1121
|
+
graphId,
|
|
1122
|
+
removal.kind,
|
|
1123
|
+
recordedCommit
|
|
1124
|
+
);
|
|
1125
|
+
await closeOpenEdgesByNodeKind(
|
|
1126
|
+
target,
|
|
1127
|
+
schema,
|
|
1128
|
+
graphId,
|
|
1129
|
+
removal.kind,
|
|
1130
|
+
recordedCommit
|
|
1131
|
+
);
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
await closeOpenByKind(
|
|
1135
|
+
target,
|
|
1136
|
+
schema.recordedEdgesTable,
|
|
1137
|
+
graphId,
|
|
1138
|
+
removal.kind,
|
|
1139
|
+
recordedCommit
|
|
1140
|
+
);
|
|
1141
|
+
}
|
|
1142
|
+
async function queryConnectedEdgeIds(target, schema, params) {
|
|
1143
|
+
const rows = await target.execute(
|
|
1144
|
+
chunkEOLERH7Y_cjs.asCompiledRowsSql(drizzleOrm.sql`
|
|
1145
|
+
SELECT id
|
|
1146
|
+
FROM ${schema.edgesTable}
|
|
1147
|
+
WHERE graph_id = ${params.graphId}
|
|
1148
|
+
AND (
|
|
1149
|
+
(from_kind = ${params.kind} AND from_id = ${params.id})
|
|
1150
|
+
OR (to_kind = ${params.kind} AND to_id = ${params.id})
|
|
1151
|
+
)
|
|
1152
|
+
`)
|
|
1153
|
+
);
|
|
1154
|
+
return rows.map((row) => row.id);
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
// src/store/recorded-capture.ts
|
|
1158
|
+
var RECORDED_FLUSH_OBSERVER = /* @__PURE__ */ Symbol("typegraph.recordedFlushObserver");
|
|
1159
|
+
function readRecordedFlushObserver(options) {
|
|
1160
|
+
return options?.[RECORDED_FLUSH_OBSERVER];
|
|
1161
|
+
}
|
|
1162
|
+
function stripRecordedFlushObserver(options) {
|
|
1163
|
+
if (options === void 0) return void 0;
|
|
1164
|
+
const { [RECORDED_FLUSH_OBSERVER]: _observer, ...backendOptions } = options;
|
|
1165
|
+
return backendOptions;
|
|
1166
|
+
}
|
|
1167
|
+
function withRecordedFlushObserver(options, observer) {
|
|
1168
|
+
return {
|
|
1169
|
+
...stripRecordedFlushObserver(options),
|
|
1170
|
+
[RECORDED_FLUSH_OBSERVER]: observer
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
function nodeIdentityKey(graphId, kind, id) {
|
|
1174
|
+
return `${graphId}\0${kind}\0${id}`;
|
|
1175
|
+
}
|
|
1176
|
+
function nodeParamsIdentityKey(params) {
|
|
1177
|
+
return nodeIdentityKey(params.graphId, params.kind, params.id);
|
|
1178
|
+
}
|
|
1179
|
+
function nodeRowIdentityKey(row) {
|
|
1180
|
+
return nodeIdentityKey(row.graph_id, row.kind, row.id);
|
|
1181
|
+
}
|
|
1182
|
+
function edgeIdentityKey(graphId, id) {
|
|
1183
|
+
return `${graphId}\0${id}`;
|
|
1184
|
+
}
|
|
1185
|
+
function edgeParamsIdentityKey(params) {
|
|
1186
|
+
return edgeIdentityKey(params.graphId, params.id);
|
|
1187
|
+
}
|
|
1188
|
+
function edgeRowIdentityKey(row) {
|
|
1189
|
+
return edgeIdentityKey(row.graph_id, row.id);
|
|
1190
|
+
}
|
|
1191
|
+
function createRecordedCaptureSession() {
|
|
1192
|
+
const touched = /* @__PURE__ */ new Map();
|
|
1193
|
+
let sealed = false;
|
|
1194
|
+
function touch(entity) {
|
|
1195
|
+
if (sealed) {
|
|
1196
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
1197
|
+
"Recorded-time capture session is sealed: a graph write happened after the transaction's capture was flushed.",
|
|
1198
|
+
{ entity: entity.entity, graphId: entity.graphId, id: entity.id },
|
|
1199
|
+
{
|
|
1200
|
+
suggestion: "Perform all writes inside the withRecordedTransaction callback; do not reuse the transaction context after it returns."
|
|
1201
|
+
}
|
|
1202
|
+
);
|
|
1203
|
+
}
|
|
1204
|
+
touched.set(entityKey(entity), entity);
|
|
1205
|
+
}
|
|
1206
|
+
return {
|
|
1207
|
+
touchNode(graphId, kind, id, afterImage) {
|
|
1208
|
+
touch({ entity: "node", graphId, kind, id, afterImage });
|
|
1209
|
+
},
|
|
1210
|
+
touchEdge(graphId, id, afterImage) {
|
|
1211
|
+
touch({ entity: "edge", graphId, id, afterImage });
|
|
1212
|
+
},
|
|
1213
|
+
async flush(target, schema, ownsWriteLock) {
|
|
1214
|
+
if (sealed) {
|
|
1215
|
+
throw new chunkLGEALRC6_cjs.ConfigurationError(
|
|
1216
|
+
"Recorded-time capture session was already flushed.",
|
|
1217
|
+
{},
|
|
1218
|
+
{
|
|
1219
|
+
suggestion: "A capture scope flushes once at its terminal point; do not flush it twice."
|
|
1220
|
+
}
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
sealed = true;
|
|
1224
|
+
if (touched.size === 0) return /* @__PURE__ */ new Map();
|
|
1225
|
+
const recordedByGraph = /* @__PURE__ */ new Map();
|
|
1226
|
+
const byGraph = chunk4TOD4LBZ_cjs.groupBy(touched.values(), (entity) => entity.graphId);
|
|
1227
|
+
for (const [graphId, entities] of byGraph) {
|
|
1228
|
+
const recordedCommit = await allocateRecordedCommit(
|
|
1229
|
+
target,
|
|
1230
|
+
schema,
|
|
1231
|
+
graphId,
|
|
1232
|
+
ownsWriteLock
|
|
1233
|
+
);
|
|
1234
|
+
recordedByGraph.set(graphId, recordedCommit);
|
|
1235
|
+
const nodes = entities.filter(
|
|
1236
|
+
(entity) => entity.entity === "node"
|
|
1237
|
+
);
|
|
1238
|
+
const edges = entities.filter(
|
|
1239
|
+
(entity) => entity.entity === "edge"
|
|
1240
|
+
);
|
|
1241
|
+
await flushNodes(target, schema, graphId, nodes, recordedCommit);
|
|
1242
|
+
await flushEdges(target, schema, graphId, edges, recordedCommit);
|
|
1243
|
+
}
|
|
1244
|
+
touched.clear();
|
|
1245
|
+
return recordedByGraph;
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
function createRecordedTransactionBackend(target, session, schema) {
|
|
1250
|
+
const nodeDispatch = nodeInsertDispatch(target);
|
|
1251
|
+
const edgeDispatch = edgeInsertDispatch(target);
|
|
1252
|
+
const graphLocks = createRecordedGraphLockMemo();
|
|
1253
|
+
async function lockGraph(graphId) {
|
|
1254
|
+
await lockRecordedGraphWrite(target, graphId, graphLocks);
|
|
1255
|
+
}
|
|
1256
|
+
async function lockGraphs(params) {
|
|
1257
|
+
const graphIds = [
|
|
1258
|
+
...new Set(params.map((parameter) => parameter.graphId))
|
|
1259
|
+
].toSorted();
|
|
1260
|
+
for (const graphId of graphIds) {
|
|
1261
|
+
await lockRecordedGraphWrite(target, graphId, graphLocks);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
const overlay = chunk4TOD4LBZ_cjs.createBackendOverlay(target, {
|
|
1265
|
+
...rawWriteGuards(target, "tx.backend"),
|
|
1266
|
+
async insertNode(params) {
|
|
1267
|
+
await lockGraph(params.graphId);
|
|
1268
|
+
const row = await target.insertNode(params);
|
|
1269
|
+
session.touchNode(params.graphId, params.kind, params.id, row);
|
|
1270
|
+
return row;
|
|
1271
|
+
},
|
|
1272
|
+
...target.insertNodeNoReturn === void 0 ? {} : {
|
|
1273
|
+
async insertNodeNoReturn(params) {
|
|
1274
|
+
await lockGraph(params.graphId);
|
|
1275
|
+
await runInsertNoReturn(nodeDispatch, params);
|
|
1276
|
+
session.touchNode(params.graphId, params.kind, params.id);
|
|
1277
|
+
}
|
|
1278
|
+
},
|
|
1279
|
+
...target.insertNodesBatch === void 0 ? {} : {
|
|
1280
|
+
async insertNodesBatch(params) {
|
|
1281
|
+
await lockGraphs(params);
|
|
1282
|
+
await runInsertBatch(nodeDispatch, params);
|
|
1283
|
+
for (const node of params) {
|
|
1284
|
+
session.touchNode(node.graphId, node.kind, node.id);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
},
|
|
1288
|
+
...target.insertNodesBatchReturning === void 0 ? {} : {
|
|
1289
|
+
async insertNodesBatchReturning(params) {
|
|
1290
|
+
await lockGraphs(params);
|
|
1291
|
+
const rows = await runInsertBatchReturning(nodeDispatch, params);
|
|
1292
|
+
const rowsByIdentity = new Map(
|
|
1293
|
+
rows.map((row) => [nodeRowIdentityKey(row), row])
|
|
1294
|
+
);
|
|
1295
|
+
for (const node of params) {
|
|
1296
|
+
session.touchNode(
|
|
1297
|
+
node.graphId,
|
|
1298
|
+
node.kind,
|
|
1299
|
+
node.id,
|
|
1300
|
+
rowsByIdentity.get(nodeParamsIdentityKey(node))
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
return rows;
|
|
1304
|
+
}
|
|
1305
|
+
},
|
|
1306
|
+
async updateNode(params) {
|
|
1307
|
+
await lockGraph(params.graphId);
|
|
1308
|
+
const row = await target.updateNode(params);
|
|
1309
|
+
session.touchNode(params.graphId, params.kind, params.id, row);
|
|
1310
|
+
return row;
|
|
1311
|
+
},
|
|
1312
|
+
async deleteNode(params) {
|
|
1313
|
+
await lockGraph(params.graphId);
|
|
1314
|
+
await target.deleteNode(params);
|
|
1315
|
+
session.touchNode(params.graphId, params.kind, params.id);
|
|
1316
|
+
},
|
|
1317
|
+
async hardDeleteNode(params) {
|
|
1318
|
+
await lockGraph(params.graphId);
|
|
1319
|
+
const connectedEdgeIds = await queryConnectedEdgeIds(
|
|
1320
|
+
target,
|
|
1321
|
+
schema,
|
|
1322
|
+
params
|
|
1323
|
+
);
|
|
1324
|
+
await target.hardDeleteNode(params);
|
|
1325
|
+
session.touchNode(params.graphId, params.kind, params.id);
|
|
1326
|
+
for (const edgeId of connectedEdgeIds) {
|
|
1327
|
+
session.touchEdge(params.graphId, edgeId);
|
|
1328
|
+
}
|
|
1329
|
+
},
|
|
1330
|
+
async insertEdge(params) {
|
|
1331
|
+
await lockGraph(params.graphId);
|
|
1332
|
+
const row = await target.insertEdge(params);
|
|
1333
|
+
session.touchEdge(params.graphId, params.id, row);
|
|
1334
|
+
return row;
|
|
1335
|
+
},
|
|
1336
|
+
...target.insertEdgeNoReturn === void 0 ? {} : {
|
|
1337
|
+
async insertEdgeNoReturn(params) {
|
|
1338
|
+
await lockGraph(params.graphId);
|
|
1339
|
+
await runInsertNoReturn(edgeDispatch, params);
|
|
1340
|
+
session.touchEdge(params.graphId, params.id);
|
|
1341
|
+
}
|
|
1342
|
+
},
|
|
1343
|
+
...target.insertEdgesBatch === void 0 ? {} : {
|
|
1344
|
+
async insertEdgesBatch(params) {
|
|
1345
|
+
await lockGraphs(params);
|
|
1346
|
+
await runInsertBatch(edgeDispatch, params);
|
|
1347
|
+
for (const edge of params) {
|
|
1348
|
+
session.touchEdge(edge.graphId, edge.id);
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
},
|
|
1352
|
+
...target.insertEdgesBatchReturning === void 0 ? {} : {
|
|
1353
|
+
async insertEdgesBatchReturning(params) {
|
|
1354
|
+
await lockGraphs(params);
|
|
1355
|
+
const rows = await runInsertBatchReturning(edgeDispatch, params);
|
|
1356
|
+
const rowsByIdentity = new Map(
|
|
1357
|
+
rows.map((row) => [edgeRowIdentityKey(row), row])
|
|
1358
|
+
);
|
|
1359
|
+
for (const edge of params) {
|
|
1360
|
+
session.touchEdge(
|
|
1361
|
+
edge.graphId,
|
|
1362
|
+
edge.id,
|
|
1363
|
+
rowsByIdentity.get(edgeParamsIdentityKey(edge))
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
return rows;
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
async updateEdge(params) {
|
|
1370
|
+
await lockGraph(params.graphId);
|
|
1371
|
+
const row = await target.updateEdge(params);
|
|
1372
|
+
session.touchEdge(params.graphId, params.id, row);
|
|
1373
|
+
return row;
|
|
1374
|
+
},
|
|
1375
|
+
async deleteEdge(params) {
|
|
1376
|
+
await lockGraph(params.graphId);
|
|
1377
|
+
await target.deleteEdge(params);
|
|
1378
|
+
session.touchEdge(params.graphId, params.id);
|
|
1379
|
+
},
|
|
1380
|
+
async hardDeleteEdge(params) {
|
|
1381
|
+
await lockGraph(params.graphId);
|
|
1382
|
+
await target.hardDeleteEdge(params);
|
|
1383
|
+
session.touchEdge(params.graphId, params.id);
|
|
1384
|
+
},
|
|
1385
|
+
...target.deleteEdgesBatch === void 0 ? {} : {
|
|
1386
|
+
async deleteEdgesBatch(params) {
|
|
1387
|
+
await lockGraph(params.graphId);
|
|
1388
|
+
await target.deleteEdgesBatch(params);
|
|
1389
|
+
for (const id of params.ids) {
|
|
1390
|
+
session.touchEdge(params.graphId, id);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
},
|
|
1394
|
+
...target.hardDeleteEdgesBatch === void 0 ? {} : {
|
|
1395
|
+
async hardDeleteEdgesBatch(params) {
|
|
1396
|
+
await lockGraph(params.graphId);
|
|
1397
|
+
await target.hardDeleteEdgesBatch(params);
|
|
1398
|
+
for (const id of params.ids) {
|
|
1399
|
+
session.touchEdge(params.graphId, id);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
registerRecordedGraphLockMemo(overlay, graphLocks);
|
|
1405
|
+
return overlay;
|
|
1406
|
+
}
|
|
1407
|
+
function createRecordedTransactionScope(target, schema, ownsWriteLock = false) {
|
|
1408
|
+
requireCaptureStatements(target);
|
|
1409
|
+
const session = createRecordedCaptureSession();
|
|
1410
|
+
const resolvedSchema = schema ?? requireRecordedSchema(target);
|
|
1411
|
+
return {
|
|
1412
|
+
backend: createRecordedTransactionBackend(target, session, resolvedSchema),
|
|
1413
|
+
async flush() {
|
|
1414
|
+
return chunkBLZDPRXT_cjs.withRecordedRelationsPrecondition(
|
|
1415
|
+
session.flush(target, resolvedSchema, ownsWriteLock),
|
|
1416
|
+
{ dialect: target.dialect, surface: "capture-flush" }
|
|
1417
|
+
);
|
|
1418
|
+
}
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
async function runCapturedAutocommit(backend, schema, fn, options) {
|
|
1422
|
+
assertRequestedRecordedIsolation(backend, options);
|
|
1423
|
+
return backend.transaction(async (target) => {
|
|
1424
|
+
await assertRecordedCaptureTransactionIsolation(target);
|
|
1425
|
+
const scope = createRecordedTransactionScope(target, schema, true);
|
|
1426
|
+
const result = await fn(scope.backend);
|
|
1427
|
+
await scope.flush();
|
|
1428
|
+
return result;
|
|
1429
|
+
}, options);
|
|
1430
|
+
}
|
|
1431
|
+
function createRecordedBackend(backend, schema) {
|
|
1432
|
+
assertCapturableBackend(backend);
|
|
1433
|
+
const capture = (fn) => runCapturedAutocommit(backend, schema, fn);
|
|
1434
|
+
return chunk4TOD4LBZ_cjs.createBackendOverlay(backend, {
|
|
1435
|
+
...rawWriteGuards(backend, "backend"),
|
|
1436
|
+
async insertNode(params) {
|
|
1437
|
+
return capture((target) => target.insertNode(params));
|
|
1438
|
+
},
|
|
1439
|
+
...backend.insertNodeNoReturn === void 0 ? {} : {
|
|
1440
|
+
async insertNodeNoReturn(params) {
|
|
1441
|
+
await capture(
|
|
1442
|
+
(target) => runInsertNoReturn(nodeInsertDispatch(target), params)
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
},
|
|
1446
|
+
...backend.insertNodesBatch === void 0 ? {} : {
|
|
1447
|
+
async insertNodesBatch(params) {
|
|
1448
|
+
await capture(
|
|
1449
|
+
(target) => runInsertBatch(nodeInsertDispatch(target), params)
|
|
1450
|
+
);
|
|
1451
|
+
}
|
|
1452
|
+
},
|
|
1453
|
+
...backend.insertNodesBatchReturning === void 0 ? {} : {
|
|
1454
|
+
async insertNodesBatchReturning(params) {
|
|
1455
|
+
return capture(
|
|
1456
|
+
(target) => runInsertBatchReturning(nodeInsertDispatch(target), params)
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1460
|
+
async updateNode(params) {
|
|
1461
|
+
return capture((target) => target.updateNode(params));
|
|
1462
|
+
},
|
|
1463
|
+
async deleteNode(params) {
|
|
1464
|
+
await capture((target) => target.deleteNode(params));
|
|
1465
|
+
},
|
|
1466
|
+
async hardDeleteNode(params) {
|
|
1467
|
+
await capture((target) => target.hardDeleteNode(params));
|
|
1468
|
+
},
|
|
1469
|
+
async insertEdge(params) {
|
|
1470
|
+
return capture((target) => target.insertEdge(params));
|
|
1471
|
+
},
|
|
1472
|
+
...backend.insertEdgeNoReturn === void 0 ? {} : {
|
|
1473
|
+
async insertEdgeNoReturn(params) {
|
|
1474
|
+
await capture(
|
|
1475
|
+
(target) => runInsertNoReturn(edgeInsertDispatch(target), params)
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
},
|
|
1479
|
+
...backend.insertEdgesBatch === void 0 ? {} : {
|
|
1480
|
+
async insertEdgesBatch(params) {
|
|
1481
|
+
await capture(
|
|
1482
|
+
(target) => runInsertBatch(edgeInsertDispatch(target), params)
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
},
|
|
1486
|
+
...backend.insertEdgesBatchReturning === void 0 ? {} : {
|
|
1487
|
+
async insertEdgesBatchReturning(params) {
|
|
1488
|
+
return capture(
|
|
1489
|
+
(target) => runInsertBatchReturning(edgeInsertDispatch(target), params)
|
|
1490
|
+
);
|
|
1491
|
+
}
|
|
1492
|
+
},
|
|
1493
|
+
async updateEdge(params) {
|
|
1494
|
+
return capture((target) => target.updateEdge(params));
|
|
1495
|
+
},
|
|
1496
|
+
async deleteEdge(params) {
|
|
1497
|
+
await capture((target) => target.deleteEdge(params));
|
|
1498
|
+
},
|
|
1499
|
+
async hardDeleteEdge(params) {
|
|
1500
|
+
await capture((target) => target.hardDeleteEdge(params));
|
|
1501
|
+
},
|
|
1502
|
+
...backend.deleteEdgesBatch === void 0 ? {} : {
|
|
1503
|
+
async deleteEdgesBatch(params) {
|
|
1504
|
+
await capture((target) => target.deleteEdgesBatch(params));
|
|
1505
|
+
}
|
|
1506
|
+
},
|
|
1507
|
+
...backend.hardDeleteEdgesBatch === void 0 ? {} : {
|
|
1508
|
+
async hardDeleteEdgesBatch(params) {
|
|
1509
|
+
await capture((target) => target.hardDeleteEdgesBatch(params));
|
|
1510
|
+
}
|
|
1511
|
+
},
|
|
1512
|
+
async transaction(fn, options) {
|
|
1513
|
+
const observer = readRecordedFlushObserver(options);
|
|
1514
|
+
const backendOptions = stripRecordedFlushObserver(options);
|
|
1515
|
+
assertRequestedRecordedIsolation(backend, backendOptions);
|
|
1516
|
+
return backend.transaction(async (target) => {
|
|
1517
|
+
await assertRecordedCaptureTransactionIsolation(target);
|
|
1518
|
+
const scope = createRecordedTransactionScope(target, schema, true);
|
|
1519
|
+
const result = await fn(scope.backend, createHistoryUnsafeSqlRef());
|
|
1520
|
+
const instants = await scope.flush();
|
|
1521
|
+
observer?.(instants);
|
|
1522
|
+
return result;
|
|
1523
|
+
}, backendOptions);
|
|
1524
|
+
},
|
|
1525
|
+
...backend.adoptTransaction === void 0 ? {} : {
|
|
1526
|
+
adoptTransaction(externalTx) {
|
|
1527
|
+
throw recordedCaptureRequiresCallbackTransactionError({
|
|
1528
|
+
externalTxType: typeof externalTx
|
|
1529
|
+
});
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
// src/store/embedding-sync.ts
|
|
1536
|
+
var embeddingFieldsCache = /* @__PURE__ */ new WeakMap();
|
|
1537
|
+
function getEmbeddingFields(schema) {
|
|
1538
|
+
const cached = embeddingFieldsCache.get(schema);
|
|
1539
|
+
if (cached) return cached;
|
|
1540
|
+
const fields = chunkH7YNSMA7_cjs.resolveEmbeddingFields(schema);
|
|
1541
|
+
embeddingFieldsCache.set(schema, fields);
|
|
1542
|
+
return fields;
|
|
1543
|
+
}
|
|
1544
|
+
async function syncEmbeddings(ctx, schema, props) {
|
|
1545
|
+
const { backend } = ctx;
|
|
1546
|
+
if (!backend.upsertEmbedding || !backend.deleteEmbedding) {
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
const embeddingFields = getEmbeddingFields(schema);
|
|
1550
|
+
if (embeddingFields.length === 0) {
|
|
1551
|
+
return;
|
|
1552
|
+
}
|
|
1553
|
+
for (const field of embeddingFields) {
|
|
1554
|
+
const value = props[field.fieldPath];
|
|
1555
|
+
if (isValidEmbeddingValue(value)) {
|
|
1556
|
+
await backend.upsertEmbedding({
|
|
1557
|
+
graphId: ctx.graphId,
|
|
1558
|
+
nodeKind: ctx.nodeKind,
|
|
1559
|
+
nodeId: ctx.nodeId,
|
|
1560
|
+
fieldPath: field.fieldPath,
|
|
1561
|
+
embedding: value,
|
|
1562
|
+
dimensions: field.dimensions,
|
|
1563
|
+
metric: field.metric,
|
|
1564
|
+
indexType: field.indexType
|
|
1565
|
+
});
|
|
1566
|
+
} else if (value === void 0) {
|
|
1567
|
+
await backend.deleteEmbedding({
|
|
1568
|
+
graphId: ctx.graphId,
|
|
1569
|
+
nodeKind: ctx.nodeKind,
|
|
1570
|
+
nodeId: ctx.nodeId,
|
|
1571
|
+
fieldPath: field.fieldPath,
|
|
1572
|
+
dimensions: field.dimensions,
|
|
1573
|
+
metric: field.metric,
|
|
1574
|
+
indexType: field.indexType
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
async function syncEmbeddingsBatchForKind(args, schema, items) {
|
|
1580
|
+
const { graphId, nodeKind, backend } = args;
|
|
1581
|
+
if (!backend.upsertEmbedding || !backend.deleteEmbedding) {
|
|
1582
|
+
return;
|
|
1583
|
+
}
|
|
1584
|
+
const embeddingFields = getEmbeddingFields(schema);
|
|
1585
|
+
if (embeddingFields.length === 0) {
|
|
1586
|
+
return;
|
|
1587
|
+
}
|
|
1588
|
+
for (const field of embeddingFields) {
|
|
1589
|
+
const rows = [];
|
|
1590
|
+
const deletionIds = [];
|
|
1591
|
+
for (const item of items) {
|
|
1592
|
+
const value = item.props[field.fieldPath];
|
|
1593
|
+
if (isValidEmbeddingValue(value)) {
|
|
1594
|
+
rows.push({ nodeId: item.nodeId, embedding: value });
|
|
1595
|
+
} else if (value === void 0) {
|
|
1596
|
+
deletionIds.push(item.nodeId);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
if (rows.length > 0) {
|
|
1600
|
+
if (backend.upsertEmbeddingBatch === void 0) {
|
|
1601
|
+
for (const row of rows) {
|
|
1602
|
+
await backend.upsertEmbedding({
|
|
1603
|
+
graphId,
|
|
1604
|
+
nodeKind,
|
|
1605
|
+
nodeId: row.nodeId,
|
|
1606
|
+
fieldPath: field.fieldPath,
|
|
1607
|
+
embedding: row.embedding,
|
|
1608
|
+
dimensions: field.dimensions,
|
|
1609
|
+
metric: field.metric,
|
|
1610
|
+
indexType: field.indexType
|
|
1611
|
+
});
|
|
1612
|
+
}
|
|
1613
|
+
} else {
|
|
1614
|
+
await backend.upsertEmbeddingBatch({
|
|
1615
|
+
graphId,
|
|
1616
|
+
nodeKind,
|
|
1617
|
+
fieldPath: field.fieldPath,
|
|
1618
|
+
dimensions: field.dimensions,
|
|
1619
|
+
metric: field.metric,
|
|
1620
|
+
indexType: field.indexType,
|
|
1621
|
+
rows
|
|
1622
|
+
});
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
for (const nodeId of deletionIds) {
|
|
1626
|
+
await backend.deleteEmbedding({
|
|
1627
|
+
graphId,
|
|
1628
|
+
nodeKind,
|
|
1629
|
+
nodeId,
|
|
1630
|
+
fieldPath: field.fieldPath,
|
|
1631
|
+
dimensions: field.dimensions,
|
|
1632
|
+
metric: field.metric,
|
|
1633
|
+
indexType: field.indexType
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
async function deleteNodeEmbeddings(ctx, schema) {
|
|
1639
|
+
const { backend } = ctx;
|
|
1640
|
+
if (!backend.deleteEmbedding) {
|
|
1641
|
+
return;
|
|
1642
|
+
}
|
|
1643
|
+
const embeddingFields = getEmbeddingFields(schema);
|
|
1644
|
+
if (embeddingFields.length === 0) {
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
for (const field of embeddingFields) {
|
|
1648
|
+
await backend.deleteEmbedding({
|
|
1649
|
+
graphId: ctx.graphId,
|
|
1650
|
+
nodeKind: ctx.nodeKind,
|
|
1651
|
+
nodeId: ctx.nodeId,
|
|
1652
|
+
fieldPath: field.fieldPath,
|
|
1653
|
+
dimensions: field.dimensions,
|
|
1654
|
+
metric: field.metric,
|
|
1655
|
+
indexType: field.indexType
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
function isValidEmbeddingValue(value) {
|
|
1660
|
+
if (!Array.isArray(value)) {
|
|
1661
|
+
return false;
|
|
1662
|
+
}
|
|
1663
|
+
return value.every((n) => typeof n === "number" && Number.isFinite(n));
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
// src/store/fulltext-sync.ts
|
|
1667
|
+
var FIELD_SEPARATOR = "\n";
|
|
1668
|
+
function resolveCombinedLanguage(fields) {
|
|
1669
|
+
return fields[0]?.metadata.language ?? chunkH7YNSMA7_cjs.DEFAULT_SEARCHABLE_LANGUAGE;
|
|
1670
|
+
}
|
|
1671
|
+
function computeFulltextContent(schema, props) {
|
|
1672
|
+
const searchableFields = chunkH7YNSMA7_cjs.getSearchableFields(schema);
|
|
1673
|
+
if (searchableFields.length === 0) return void 0;
|
|
1674
|
+
const parts = [];
|
|
1675
|
+
for (const field of searchableFields) {
|
|
1676
|
+
const value = props[field.fieldPath];
|
|
1677
|
+
if (typeof value === "string" && value.length > 0) {
|
|
1678
|
+
parts.push(value);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
if (parts.length === 0) return void 0;
|
|
1682
|
+
return {
|
|
1683
|
+
content: parts.join(FIELD_SEPARATOR),
|
|
1684
|
+
language: resolveCombinedLanguage(searchableFields)
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
async function syncFulltext(ctx, schema, props) {
|
|
1688
|
+
const { backend } = ctx;
|
|
1689
|
+
if (!backend.upsertFulltext || !backend.deleteFulltext) {
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
const computed = computeFulltextContent(schema, props);
|
|
1693
|
+
if (computed !== void 0) {
|
|
1694
|
+
await backend.upsertFulltext({
|
|
1695
|
+
graphId: ctx.graphId,
|
|
1696
|
+
nodeKind: ctx.nodeKind,
|
|
1697
|
+
nodeId: ctx.nodeId,
|
|
1698
|
+
content: computed.content,
|
|
1699
|
+
language: computed.language
|
|
1700
|
+
});
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
if (chunkH7YNSMA7_cjs.getSearchableFields(schema).length === 0) return;
|
|
1704
|
+
await backend.deleteFulltext({
|
|
1705
|
+
graphId: ctx.graphId,
|
|
1706
|
+
nodeKind: ctx.nodeKind,
|
|
1707
|
+
nodeId: ctx.nodeId
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1710
|
+
async function syncFulltextBatchForKind(args, schema, items) {
|
|
1711
|
+
const { graphId, nodeKind, backend } = args;
|
|
1712
|
+
if (!backend.upsertFulltext || !backend.deleteFulltext) {
|
|
1713
|
+
return;
|
|
1714
|
+
}
|
|
1715
|
+
const rows = [];
|
|
1716
|
+
const emptyContentIds = [];
|
|
1717
|
+
const hasSearchableFields = chunkH7YNSMA7_cjs.getSearchableFields(schema).length > 0;
|
|
1718
|
+
for (const item of items) {
|
|
1719
|
+
const computed = computeFulltextContent(schema, item.props);
|
|
1720
|
+
if (computed !== void 0) {
|
|
1721
|
+
rows.push({
|
|
1722
|
+
nodeId: item.nodeId,
|
|
1723
|
+
content: computed.content,
|
|
1724
|
+
language: computed.language
|
|
1725
|
+
});
|
|
1726
|
+
} else if (hasSearchableFields) {
|
|
1727
|
+
emptyContentIds.push(item.nodeId);
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
if (rows.length > 0) {
|
|
1731
|
+
if (backend.upsertFulltextBatch === void 0) {
|
|
1732
|
+
for (const row of rows) {
|
|
1733
|
+
await backend.upsertFulltext({
|
|
1734
|
+
graphId,
|
|
1735
|
+
nodeKind,
|
|
1736
|
+
nodeId: row.nodeId,
|
|
1737
|
+
content: row.content,
|
|
1738
|
+
language: row.language
|
|
1739
|
+
});
|
|
1740
|
+
}
|
|
1741
|
+
} else {
|
|
1742
|
+
await backend.upsertFulltextBatch({ graphId, nodeKind, rows });
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
if (emptyContentIds.length > 0) {
|
|
1746
|
+
if (backend.deleteFulltextBatch === void 0) {
|
|
1747
|
+
for (const nodeId of emptyContentIds) {
|
|
1748
|
+
await backend.deleteFulltext({ graphId, nodeKind, nodeId });
|
|
1749
|
+
}
|
|
1750
|
+
} else {
|
|
1751
|
+
await backend.deleteFulltextBatch({
|
|
1752
|
+
graphId,
|
|
1753
|
+
nodeKind,
|
|
1754
|
+
nodeIds: emptyContentIds
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
async function deleteNodeFulltext(ctx, schema) {
|
|
1760
|
+
const { backend } = ctx;
|
|
1761
|
+
if (!backend.deleteFulltext) {
|
|
1762
|
+
return;
|
|
1763
|
+
}
|
|
1764
|
+
if (chunkH7YNSMA7_cjs.getSearchableFields(schema).length === 0) {
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
await backend.deleteFulltext({
|
|
1768
|
+
graphId: ctx.graphId,
|
|
1769
|
+
nodeKind: ctx.nodeKind,
|
|
1770
|
+
nodeId: ctx.nodeId
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
// src/constraints/index.ts
|
|
1775
|
+
var UNIQUE_KEY_SEPARATOR = "";
|
|
1776
|
+
var UNIQUE_KEY_NULL_MARKER = "";
|
|
1777
|
+
function computeUniqueKey(props, fields, collation) {
|
|
1778
|
+
const values = fields.map((field) => {
|
|
1779
|
+
const value = props[field];
|
|
1780
|
+
if (value === void 0 || value === null) {
|
|
1781
|
+
return UNIQUE_KEY_NULL_MARKER;
|
|
1782
|
+
}
|
|
1783
|
+
const stringValue = typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? value.toString() : JSON.stringify(value);
|
|
1784
|
+
return collation === "caseInsensitive" ? stringValue.toLowerCase() : stringValue;
|
|
1785
|
+
});
|
|
1786
|
+
return values.join(UNIQUE_KEY_SEPARATOR);
|
|
1787
|
+
}
|
|
1788
|
+
function checkWherePredicate(constraint, props) {
|
|
1789
|
+
if (!constraint.where) {
|
|
1790
|
+
return true;
|
|
1791
|
+
}
|
|
1792
|
+
const predicateBuilder = buildPredicateContext(props);
|
|
1793
|
+
const predicate = constraint.where(predicateBuilder);
|
|
1794
|
+
return evaluatePredicate(predicate, props);
|
|
1795
|
+
}
|
|
1796
|
+
function buildPredicateContext(props) {
|
|
1797
|
+
const context = {};
|
|
1798
|
+
for (const key of Object.keys(props)) {
|
|
1799
|
+
context[key] = {
|
|
1800
|
+
isNull: () => ({
|
|
1801
|
+
__type: "unique_predicate",
|
|
1802
|
+
field: key,
|
|
1803
|
+
op: "isNull"
|
|
1804
|
+
}),
|
|
1805
|
+
isNotNull: () => ({
|
|
1806
|
+
__type: "unique_predicate",
|
|
1807
|
+
field: key,
|
|
1808
|
+
op: "isNotNull"
|
|
1809
|
+
})
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1812
|
+
return context;
|
|
1813
|
+
}
|
|
1814
|
+
function evaluatePredicate(predicate, props) {
|
|
1815
|
+
if (typeof predicate !== "object" || predicate === null || !("__type" in predicate)) {
|
|
1816
|
+
return true;
|
|
1817
|
+
}
|
|
1818
|
+
const pred = predicate;
|
|
1819
|
+
if (pred.__type !== "unique_predicate") {
|
|
1820
|
+
return true;
|
|
1821
|
+
}
|
|
1822
|
+
const value = props[pred.field];
|
|
1823
|
+
if (pred.op === "isNull") {
|
|
1824
|
+
return value === null || value === void 0;
|
|
1825
|
+
}
|
|
1826
|
+
return chunk4TOD4LBZ_cjs.isPresent(value);
|
|
1827
|
+
}
|
|
1828
|
+
function getKindsForUniquenessCheck(baseKind, scope, registry) {
|
|
1829
|
+
if (scope === "kind") {
|
|
1830
|
+
return [baseKind];
|
|
1831
|
+
}
|
|
1832
|
+
const root = findRootAncestor(baseKind, registry);
|
|
1833
|
+
return registry.expandSubClasses(root);
|
|
1834
|
+
}
|
|
1835
|
+
function findRootAncestor(kind, registry) {
|
|
1836
|
+
const ancestors = registry.getAncestors(kind);
|
|
1837
|
+
if (ancestors.size === 0) {
|
|
1838
|
+
return kind;
|
|
1839
|
+
}
|
|
1840
|
+
for (const ancestor of ancestors) {
|
|
1841
|
+
if (registry.getAncestors(ancestor).size === 0) {
|
|
1842
|
+
return ancestor;
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
const firstAncestor = [...ancestors][0];
|
|
1846
|
+
return firstAncestor ? findRootAncestor(firstAncestor, registry) : kind;
|
|
1847
|
+
}
|
|
1848
|
+
function checkCardinality(edgeKind, fromKind, fromId, cardinality, existingEdgeCount, hasActiveEdge) {
|
|
1849
|
+
switch (cardinality) {
|
|
1850
|
+
case "many": {
|
|
1851
|
+
return void 0;
|
|
1852
|
+
}
|
|
1853
|
+
case "one": {
|
|
1854
|
+
if (existingEdgeCount > 0) {
|
|
1855
|
+
return new chunkLGEALRC6_cjs.CardinalityError({
|
|
1856
|
+
edgeKind,
|
|
1857
|
+
fromKind,
|
|
1858
|
+
fromId,
|
|
1859
|
+
cardinality: "one",
|
|
1860
|
+
existingCount: existingEdgeCount
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
return void 0;
|
|
1864
|
+
}
|
|
1865
|
+
case "unique": {
|
|
1866
|
+
return void 0;
|
|
1867
|
+
}
|
|
1868
|
+
case "oneActive": {
|
|
1869
|
+
if (hasActiveEdge) {
|
|
1870
|
+
return new chunkLGEALRC6_cjs.CardinalityError({
|
|
1871
|
+
edgeKind,
|
|
1872
|
+
fromKind,
|
|
1873
|
+
fromId,
|
|
1874
|
+
cardinality: "oneActive",
|
|
1875
|
+
existingCount: 1
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1878
|
+
return void 0;
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
function checkUniqueEdge(edgeKind, fromKind, fromId, _toKind, _toId, existingCount) {
|
|
1883
|
+
if (existingCount > 0) {
|
|
1884
|
+
return new chunkLGEALRC6_cjs.CardinalityError({
|
|
1885
|
+
edgeKind,
|
|
1886
|
+
fromKind,
|
|
1887
|
+
fromId,
|
|
1888
|
+
cardinality: "unique",
|
|
1889
|
+
existingCount
|
|
1890
|
+
});
|
|
1891
|
+
}
|
|
1892
|
+
return void 0;
|
|
1893
|
+
}
|
|
1894
|
+
function validateEdgeEndpoints(edgeKind, fromKind, toKind, registration, registry) {
|
|
1895
|
+
const validFromKinds = registration.from.map((node) => node.kind);
|
|
1896
|
+
if (!registry.isAssignableToAny(fromKind, validFromKinds)) {
|
|
1897
|
+
return new chunkLGEALRC6_cjs.EndpointError({
|
|
1898
|
+
edgeKind,
|
|
1899
|
+
endpoint: "from",
|
|
1900
|
+
actualKind: fromKind,
|
|
1901
|
+
expectedKinds: validFromKinds
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
const validToKinds = registration.to.map((node) => node.kind);
|
|
1905
|
+
if (!registry.isAssignableToAny(toKind, validToKinds)) {
|
|
1906
|
+
return new chunkLGEALRC6_cjs.EndpointError({
|
|
1907
|
+
edgeKind,
|
|
1908
|
+
endpoint: "to",
|
|
1909
|
+
actualKind: toKind,
|
|
1910
|
+
expectedKinds: validToKinds
|
|
1911
|
+
});
|
|
1912
|
+
}
|
|
1913
|
+
return void 0;
|
|
1914
|
+
}
|
|
1915
|
+
function checkDisjointness(nodeId, nodeKind, existingKinds, registry) {
|
|
1916
|
+
for (const existingKind of existingKinds) {
|
|
1917
|
+
if (registry.areDisjoint(nodeKind, existingKind)) {
|
|
1918
|
+
return new chunkLGEALRC6_cjs.DisjointError({
|
|
1919
|
+
nodeId,
|
|
1920
|
+
attemptedKind: nodeKind,
|
|
1921
|
+
conflictingKind: existingKind
|
|
1922
|
+
});
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
return void 0;
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
// src/store/uniqueness.ts
|
|
1929
|
+
function createUniquenessContext(graphId, registry, backend) {
|
|
1930
|
+
return { graphId, registry, backend };
|
|
1931
|
+
}
|
|
1932
|
+
async function checkUniquenessConstraints(ctx, kind, id, props, constraints) {
|
|
1933
|
+
for (const constraint of constraints) {
|
|
1934
|
+
if (!checkWherePredicate(constraint, props)) {
|
|
1935
|
+
continue;
|
|
1936
|
+
}
|
|
1937
|
+
const key = computeUniqueKey(
|
|
1938
|
+
props,
|
|
1939
|
+
constraint.fields,
|
|
1940
|
+
constraint.collation
|
|
1941
|
+
);
|
|
1942
|
+
const kindsToCheck = getKindsForUniquenessCheck(
|
|
1943
|
+
kind,
|
|
1944
|
+
constraint.scope,
|
|
1945
|
+
ctx.registry
|
|
1946
|
+
);
|
|
1947
|
+
for (const kindToCheck of kindsToCheck) {
|
|
1948
|
+
const existing = await ctx.backend.checkUnique({
|
|
1949
|
+
graphId: ctx.graphId,
|
|
1950
|
+
nodeKind: kindToCheck,
|
|
1951
|
+
constraintName: constraint.name,
|
|
1952
|
+
key
|
|
1953
|
+
});
|
|
1954
|
+
if (existing && existing.node_id !== id) {
|
|
1955
|
+
throw new chunkLGEALRC6_cjs.UniquenessError({
|
|
1956
|
+
constraintName: constraint.name,
|
|
1957
|
+
kind: kindToCheck,
|
|
1958
|
+
existingId: existing.node_id,
|
|
1959
|
+
newId: id,
|
|
1960
|
+
fields: constraint.fields
|
|
1961
|
+
});
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
async function insertUniquenessEntries(ctx, kind, id, props, constraints) {
|
|
1967
|
+
for (const constraint of constraints) {
|
|
1968
|
+
if (!checkWherePredicate(constraint, props)) {
|
|
1969
|
+
continue;
|
|
1970
|
+
}
|
|
1971
|
+
const key = computeUniqueKey(
|
|
1972
|
+
props,
|
|
1973
|
+
constraint.fields,
|
|
1974
|
+
constraint.collation
|
|
1975
|
+
);
|
|
1976
|
+
await ctx.backend.insertUnique({
|
|
1977
|
+
graphId: ctx.graphId,
|
|
1978
|
+
nodeKind: kind,
|
|
1979
|
+
constraintName: constraint.name,
|
|
1980
|
+
key,
|
|
1981
|
+
nodeId: id,
|
|
1982
|
+
concreteKind: kind
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
async function insertUniquenessEntriesBatch(ctx, items) {
|
|
1987
|
+
const entries = [];
|
|
1988
|
+
for (const item of items) {
|
|
1989
|
+
for (const constraint of item.constraints) {
|
|
1990
|
+
if (!checkWherePredicate(constraint, item.props)) {
|
|
1991
|
+
continue;
|
|
1992
|
+
}
|
|
1993
|
+
entries.push({
|
|
1994
|
+
graphId: ctx.graphId,
|
|
1995
|
+
nodeKind: item.kind,
|
|
1996
|
+
constraintName: constraint.name,
|
|
1997
|
+
key: computeUniqueKey(
|
|
1998
|
+
item.props,
|
|
1999
|
+
constraint.fields,
|
|
2000
|
+
constraint.collation
|
|
2001
|
+
),
|
|
2002
|
+
nodeId: item.id,
|
|
2003
|
+
concreteKind: item.kind
|
|
2004
|
+
});
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
if (entries.length === 0) return;
|
|
2008
|
+
if (ctx.backend.insertUniqueBatch !== void 0) {
|
|
2009
|
+
await ctx.backend.insertUniqueBatch(entries);
|
|
2010
|
+
return;
|
|
2011
|
+
}
|
|
2012
|
+
for (const entry of entries) {
|
|
2013
|
+
await ctx.backend.insertUnique(entry);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
async function deleteUniquenessEntries(ctx, kind, props, constraints) {
|
|
2017
|
+
for (const constraint of constraints) {
|
|
2018
|
+
if (!checkWherePredicate(constraint, props)) {
|
|
2019
|
+
continue;
|
|
2020
|
+
}
|
|
2021
|
+
const key = computeUniqueKey(
|
|
2022
|
+
props,
|
|
2023
|
+
constraint.fields,
|
|
2024
|
+
constraint.collation
|
|
2025
|
+
);
|
|
2026
|
+
await ctx.backend.deleteUnique({
|
|
2027
|
+
graphId: ctx.graphId,
|
|
2028
|
+
nodeKind: kind,
|
|
2029
|
+
constraintName: constraint.name,
|
|
2030
|
+
key
|
|
2031
|
+
});
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
async function updateUniquenessEntries(ctx, kind, id, oldProps, newProps, constraints) {
|
|
2035
|
+
const pending = [];
|
|
2036
|
+
for (const constraint of constraints) {
|
|
2037
|
+
const oldApplies = checkWherePredicate(constraint, oldProps);
|
|
2038
|
+
const newApplies = checkWherePredicate(constraint, newProps);
|
|
2039
|
+
const oldKey = oldApplies ? computeUniqueKey(oldProps, constraint.fields, constraint.collation) : void 0;
|
|
2040
|
+
const newKey = newApplies ? computeUniqueKey(newProps, constraint.fields, constraint.collation) : void 0;
|
|
2041
|
+
if (!oldApplies && !newApplies) {
|
|
2042
|
+
continue;
|
|
2043
|
+
}
|
|
2044
|
+
if (oldApplies && newApplies && oldKey === newKey) {
|
|
2045
|
+
continue;
|
|
2046
|
+
}
|
|
2047
|
+
if (newApplies && newKey !== void 0) {
|
|
2048
|
+
const kindsToCheck = getKindsForUniquenessCheck(
|
|
2049
|
+
kind,
|
|
2050
|
+
constraint.scope,
|
|
2051
|
+
ctx.registry
|
|
2052
|
+
);
|
|
2053
|
+
for (const kindToCheck of kindsToCheck) {
|
|
2054
|
+
const existing = await ctx.backend.checkUnique({
|
|
2055
|
+
graphId: ctx.graphId,
|
|
2056
|
+
nodeKind: kindToCheck,
|
|
2057
|
+
constraintName: constraint.name,
|
|
2058
|
+
key: newKey
|
|
2059
|
+
});
|
|
2060
|
+
if (existing && existing.node_id !== id) {
|
|
2061
|
+
throw new chunkLGEALRC6_cjs.UniquenessError({
|
|
2062
|
+
constraintName: constraint.name,
|
|
2063
|
+
kind: kindToCheck,
|
|
2064
|
+
existingId: existing.node_id,
|
|
2065
|
+
newId: id,
|
|
2066
|
+
fields: constraint.fields
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
pending.push({ constraintName: constraint.name, oldKey, newKey });
|
|
2072
|
+
}
|
|
2073
|
+
for (const mutation of pending) {
|
|
2074
|
+
if (mutation.oldKey !== void 0) {
|
|
2075
|
+
await ctx.backend.deleteUnique({
|
|
2076
|
+
graphId: ctx.graphId,
|
|
2077
|
+
nodeKind: kind,
|
|
2078
|
+
constraintName: mutation.constraintName,
|
|
2079
|
+
key: mutation.oldKey
|
|
2080
|
+
});
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
for (const mutation of pending) {
|
|
2084
|
+
if (mutation.newKey !== void 0) {
|
|
2085
|
+
await ctx.backend.insertUnique({
|
|
2086
|
+
graphId: ctx.graphId,
|
|
2087
|
+
nodeKind: kind,
|
|
2088
|
+
constraintName: mutation.constraintName,
|
|
2089
|
+
key: mutation.newKey,
|
|
2090
|
+
nodeId: id,
|
|
2091
|
+
concreteKind: kind
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
// src/store/operations/node-write-pipeline.ts
|
|
2098
|
+
function createNodeWriteContext(graphId, registry, lock) {
|
|
2099
|
+
return { graphId, registry, lock };
|
|
2100
|
+
}
|
|
2101
|
+
function uniquenessContext(ctx, backend) {
|
|
2102
|
+
return createUniquenessContext(ctx.graphId, ctx.registry, backend);
|
|
2103
|
+
}
|
|
2104
|
+
function nodeSyncContext(ctx, kind, id, backend) {
|
|
2105
|
+
return { graphId: ctx.graphId, nodeKind: kind, nodeId: id, backend };
|
|
2106
|
+
}
|
|
2107
|
+
async function enforceNodeDeleteBehavior(ctx, args, backend, policy) {
|
|
2108
|
+
if (policy?.enforceDeleteBehavior === false) return;
|
|
2109
|
+
const behavior = args.onDelete ?? "restrict";
|
|
2110
|
+
const connectedEdges = await backend.findEdgesConnectedTo({
|
|
2111
|
+
graphId: ctx.graphId,
|
|
2112
|
+
nodeKind: args.kind,
|
|
2113
|
+
nodeId: args.id
|
|
2114
|
+
});
|
|
2115
|
+
if (connectedEdges.length === 0) return;
|
|
2116
|
+
switch (behavior) {
|
|
2117
|
+
case "restrict": {
|
|
2118
|
+
throw new chunkLGEALRC6_cjs.RestrictedDeleteError({
|
|
2119
|
+
nodeKind: args.kind,
|
|
2120
|
+
nodeId: args.id,
|
|
2121
|
+
edgeCount: connectedEdges.length,
|
|
2122
|
+
edgeKinds: [...new Set(connectedEdges.map((edge) => edge.kind))]
|
|
2123
|
+
});
|
|
2124
|
+
}
|
|
2125
|
+
case "cascade":
|
|
2126
|
+
case "disconnect": {
|
|
2127
|
+
const batchDelete = args.mode === "hard" ? backend.hardDeleteEdgesBatch : backend.deleteEdgesBatch;
|
|
2128
|
+
if (batchDelete !== void 0) {
|
|
2129
|
+
await batchDelete.call(backend, {
|
|
2130
|
+
graphId: ctx.graphId,
|
|
2131
|
+
ids: connectedEdges.map((edge) => edge.id)
|
|
2132
|
+
});
|
|
2133
|
+
break;
|
|
2134
|
+
}
|
|
2135
|
+
for (const edge of connectedEdges) {
|
|
2136
|
+
await (args.mode === "hard" ? backend.hardDeleteEdge({ graphId: ctx.graphId, id: edge.id }) : backend.deleteEdge({ graphId: ctx.graphId, id: edge.id }));
|
|
2137
|
+
}
|
|
2138
|
+
break;
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
async function applyNodeInsertSideEffects(ctx, args, backend) {
|
|
2143
|
+
await insertUniquenessEntries(
|
|
2144
|
+
uniquenessContext(ctx, backend),
|
|
2145
|
+
args.kind,
|
|
2146
|
+
args.id,
|
|
2147
|
+
args.props,
|
|
2148
|
+
args.uniqueConstraints
|
|
2149
|
+
);
|
|
2150
|
+
await Promise.all([
|
|
2151
|
+
syncEmbeddings(
|
|
2152
|
+
nodeSyncContext(ctx, args.kind, args.id, backend),
|
|
2153
|
+
args.schema,
|
|
2154
|
+
args.props
|
|
2155
|
+
),
|
|
2156
|
+
syncFulltext(
|
|
2157
|
+
nodeSyncContext(ctx, args.kind, args.id, backend),
|
|
2158
|
+
args.schema,
|
|
2159
|
+
args.props
|
|
2160
|
+
)
|
|
2161
|
+
]);
|
|
2162
|
+
}
|
|
2163
|
+
async function applyNodeInsertSideEffectsBatch(ctx, items, backend) {
|
|
2164
|
+
if (items.length === 0) return;
|
|
2165
|
+
await insertUniquenessEntriesBatch(
|
|
2166
|
+
uniquenessContext(ctx, backend),
|
|
2167
|
+
items.map((item) => ({
|
|
2168
|
+
kind: item.kind,
|
|
2169
|
+
id: item.id,
|
|
2170
|
+
props: item.props,
|
|
2171
|
+
constraints: item.uniqueConstraints
|
|
2172
|
+
}))
|
|
2173
|
+
);
|
|
2174
|
+
const byKind = /* @__PURE__ */ new Map();
|
|
2175
|
+
for (const item of items) {
|
|
2176
|
+
const group = byKind.get(item.kind) ?? { schema: item.schema, rows: [] };
|
|
2177
|
+
group.rows.push({ nodeId: item.id, props: item.props });
|
|
2178
|
+
byKind.set(item.kind, group);
|
|
2179
|
+
}
|
|
2180
|
+
await Promise.all(
|
|
2181
|
+
[...byKind.entries()].flatMap(([kind, group]) => {
|
|
2182
|
+
const syncArguments = { graphId: ctx.graphId, nodeKind: kind, backend };
|
|
2183
|
+
return [
|
|
2184
|
+
syncEmbeddingsBatchForKind(syncArguments, group.schema, group.rows),
|
|
2185
|
+
syncFulltextBatchForKind(syncArguments, group.schema, group.rows)
|
|
2186
|
+
];
|
|
2187
|
+
})
|
|
2188
|
+
);
|
|
2189
|
+
}
|
|
2190
|
+
function parseRowProps(row) {
|
|
2191
|
+
return chunk4TOD4LBZ_cjs.rowPropsToObject(row.props);
|
|
2192
|
+
}
|
|
2193
|
+
async function applyNodeUpdate(ctx, args, backend) {
|
|
2194
|
+
const { kind, id } = args.existing;
|
|
2195
|
+
if (args.existing.deleted_at === void 0) {
|
|
2196
|
+
await updateUniquenessEntries(
|
|
2197
|
+
uniquenessContext(ctx, backend),
|
|
2198
|
+
kind,
|
|
2199
|
+
id,
|
|
2200
|
+
parseRowProps(args.existing),
|
|
2201
|
+
args.validatedProps,
|
|
2202
|
+
args.uniqueConstraints
|
|
2203
|
+
);
|
|
2204
|
+
} else {
|
|
2205
|
+
await checkUniquenessConstraints(
|
|
2206
|
+
uniquenessContext(ctx, backend),
|
|
2207
|
+
kind,
|
|
2208
|
+
id,
|
|
2209
|
+
args.validatedProps,
|
|
2210
|
+
args.uniqueConstraints
|
|
2211
|
+
);
|
|
2212
|
+
await insertUniquenessEntries(
|
|
2213
|
+
uniquenessContext(ctx, backend),
|
|
2214
|
+
kind,
|
|
2215
|
+
id,
|
|
2216
|
+
args.validatedProps,
|
|
2217
|
+
args.uniqueConstraints
|
|
2218
|
+
);
|
|
2219
|
+
}
|
|
2220
|
+
const updateParams = {
|
|
2221
|
+
graphId: ctx.graphId,
|
|
2222
|
+
kind,
|
|
2223
|
+
id,
|
|
2224
|
+
props: args.validatedProps,
|
|
2225
|
+
incrementVersion: true
|
|
2226
|
+
};
|
|
2227
|
+
if (args.validTo !== void 0) updateParams.validTo = args.validTo;
|
|
2228
|
+
if (args.clearDeleted) updateParams.clearDeleted = true;
|
|
2229
|
+
const row = await backend.updateNode(updateParams);
|
|
2230
|
+
await Promise.all([
|
|
2231
|
+
syncEmbeddings(
|
|
2232
|
+
nodeSyncContext(ctx, kind, id, backend),
|
|
2233
|
+
args.schema,
|
|
2234
|
+
args.validatedProps
|
|
2235
|
+
),
|
|
2236
|
+
syncFulltext(
|
|
2237
|
+
nodeSyncContext(ctx, kind, id, backend),
|
|
2238
|
+
args.schema,
|
|
2239
|
+
args.validatedProps
|
|
2240
|
+
)
|
|
2241
|
+
]);
|
|
2242
|
+
return row;
|
|
2243
|
+
}
|
|
2244
|
+
async function applyNodeSoftDelete(ctx, args, backend, policy) {
|
|
2245
|
+
const { kind, id } = args.existing;
|
|
2246
|
+
await enforceNodeDeleteBehavior(
|
|
2247
|
+
ctx,
|
|
2248
|
+
{ kind, id, mode: "soft", onDelete: args.onDelete },
|
|
2249
|
+
backend,
|
|
2250
|
+
policy
|
|
2251
|
+
);
|
|
2252
|
+
await backend.deleteNode({
|
|
2253
|
+
graphId: ctx.graphId,
|
|
2254
|
+
kind,
|
|
2255
|
+
id
|
|
2256
|
+
});
|
|
2257
|
+
await deleteUniquenessEntries(
|
|
2258
|
+
uniquenessContext(ctx, backend),
|
|
2259
|
+
kind,
|
|
2260
|
+
parseRowProps(args.existing),
|
|
2261
|
+
args.uniqueConstraints
|
|
2262
|
+
);
|
|
2263
|
+
await deleteNodeEmbeddings(
|
|
2264
|
+
nodeSyncContext(ctx, kind, id, backend),
|
|
2265
|
+
args.schema
|
|
2266
|
+
);
|
|
2267
|
+
await deleteNodeFulltext(
|
|
2268
|
+
nodeSyncContext(ctx, kind, id, backend),
|
|
2269
|
+
args.schema
|
|
2270
|
+
);
|
|
2271
|
+
}
|
|
2272
|
+
async function applyNodeHardDelete(ctx, args, backend) {
|
|
2273
|
+
await enforceNodeDeleteBehavior(
|
|
2274
|
+
ctx,
|
|
2275
|
+
{ kind: args.kind, id: args.id, mode: "hard", onDelete: args.onDelete },
|
|
2276
|
+
backend
|
|
2277
|
+
);
|
|
2278
|
+
await backend.hardDeleteNode({
|
|
2279
|
+
graphId: ctx.graphId,
|
|
2280
|
+
kind: args.kind,
|
|
2281
|
+
id: args.id
|
|
2282
|
+
});
|
|
2283
|
+
await deleteNodeEmbeddings(
|
|
2284
|
+
nodeSyncContext(ctx, args.kind, args.id, backend),
|
|
2285
|
+
args.schema
|
|
2286
|
+
);
|
|
2287
|
+
}
|
|
2288
|
+
async function applyNodeResurrect(ctx, args, backend) {
|
|
2289
|
+
const { kind, id } = args.existing;
|
|
2290
|
+
const props = parseRowProps(args.existing);
|
|
2291
|
+
await checkUniquenessConstraints(
|
|
2292
|
+
uniquenessContext(ctx, backend),
|
|
2293
|
+
kind,
|
|
2294
|
+
id,
|
|
2295
|
+
props,
|
|
2296
|
+
args.uniqueConstraints
|
|
2297
|
+
);
|
|
2298
|
+
await insertUniquenessEntries(
|
|
2299
|
+
uniquenessContext(ctx, backend),
|
|
2300
|
+
kind,
|
|
2301
|
+
id,
|
|
2302
|
+
props,
|
|
2303
|
+
args.uniqueConstraints
|
|
2304
|
+
);
|
|
2305
|
+
const row = await backend.updateNode({
|
|
2306
|
+
graphId: ctx.graphId,
|
|
2307
|
+
kind,
|
|
2308
|
+
id,
|
|
2309
|
+
props,
|
|
2310
|
+
incrementVersion: true,
|
|
2311
|
+
clearDeleted: true
|
|
2312
|
+
});
|
|
2313
|
+
await Promise.all([
|
|
2314
|
+
syncEmbeddings(nodeSyncContext(ctx, kind, id, backend), args.schema, props),
|
|
2315
|
+
syncFulltext(nodeSyncContext(ctx, kind, id, backend), args.schema, props)
|
|
2316
|
+
]);
|
|
2317
|
+
return row;
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
exports.ALIAS_CTE_PREFIX = ALIAS_CTE_PREFIX;
|
|
2321
|
+
exports.DEFAULT_SQL_SCHEMA = DEFAULT_SQL_SCHEMA;
|
|
2322
|
+
exports.EMBEDDINGS_CTE_ALIAS = EMBEDDINGS_CTE_ALIAS;
|
|
2323
|
+
exports.FULLTEXT_CTE_ALIAS = FULLTEXT_CTE_ALIAS;
|
|
2324
|
+
exports.HYBRID_CANDIDATES_CTE_ALIAS = HYBRID_CANDIDATES_CTE_ALIAS;
|
|
2325
|
+
exports.advanceRevisionClock = advanceRevisionClock;
|
|
2326
|
+
exports.applyNodeHardDelete = applyNodeHardDelete;
|
|
2327
|
+
exports.applyNodeInsertSideEffects = applyNodeInsertSideEffects;
|
|
2328
|
+
exports.applyNodeInsertSideEffectsBatch = applyNodeInsertSideEffectsBatch;
|
|
2329
|
+
exports.applyNodeResurrect = applyNodeResurrect;
|
|
2330
|
+
exports.applyNodeSoftDelete = applyNodeSoftDelete;
|
|
2331
|
+
exports.applyNodeUpdate = applyNodeUpdate;
|
|
2332
|
+
exports.asRecordedInstant = asRecordedInstant;
|
|
2333
|
+
exports.assertRecordedCaptureTransactionIsolation = assertRecordedCaptureTransactionIsolation;
|
|
2334
|
+
exports.assertRevisionTrackableBackend = assertRevisionTrackableBackend;
|
|
2335
|
+
exports.assertValidRecordedInstant = assertValidRecordedInstant;
|
|
2336
|
+
exports.checkCardinality = checkCardinality;
|
|
2337
|
+
exports.checkDisjointness = checkDisjointness;
|
|
2338
|
+
exports.checkUniqueEdge = checkUniqueEdge;
|
|
2339
|
+
exports.checkUniquenessConstraints = checkUniquenessConstraints;
|
|
2340
|
+
exports.checkWherePredicate = checkWherePredicate;
|
|
2341
|
+
exports.closeRecordedHardDeletedKind = closeRecordedHardDeletedKind;
|
|
2342
|
+
exports.computeFulltextContent = computeFulltextContent;
|
|
2343
|
+
exports.computeUniqueKey = computeUniqueKey;
|
|
2344
|
+
exports.coordinateContext = coordinateContext;
|
|
2345
|
+
exports.createHistoryUnsafeSqlRef = createHistoryUnsafeSqlRef;
|
|
2346
|
+
exports.createNodeWriteContext = createNodeWriteContext;
|
|
2347
|
+
exports.createRecordedBackend = createRecordedBackend;
|
|
2348
|
+
exports.createRecordedReadBinding = createRecordedReadBinding;
|
|
2349
|
+
exports.createRecordedTransactionScope = createRecordedTransactionScope;
|
|
2350
|
+
exports.createRevisionTrackingUnsafeSqlRef = createRevisionTrackingUnsafeSqlRef;
|
|
2351
|
+
exports.createSqlSchema = createSqlSchema;
|
|
2352
|
+
exports.createUniquenessContext = createUniquenessContext;
|
|
2353
|
+
exports.describeCoordinate = describeCoordinate;
|
|
2354
|
+
exports.edgeInsertDispatch = edgeInsertDispatch;
|
|
2355
|
+
exports.ensureRevisionOrigin = ensureRevisionOrigin;
|
|
2356
|
+
exports.generateId = generateId;
|
|
2357
|
+
exports.getEdgeRowsByIds = getEdgeRowsByIds;
|
|
2358
|
+
exports.getEmbeddingFields = getEmbeddingFields;
|
|
2359
|
+
exports.getKindsForUniquenessCheck = getKindsForUniquenessCheck;
|
|
2360
|
+
exports.getNodeRowsByIds = getNodeRowsByIds;
|
|
2361
|
+
exports.lockRecordedGraphWrite = lockRecordedGraphWrite;
|
|
2362
|
+
exports.nodeInsertDispatch = nodeInsertDispatch;
|
|
2363
|
+
exports.readRecordedClock = readRecordedClock;
|
|
2364
|
+
exports.readRevisionOrigin = readRevisionOrigin;
|
|
2365
|
+
exports.recordedBindParamBudget = recordedBindParamBudget;
|
|
2366
|
+
exports.recordedCaptureRequiresCallbackTransactionError = recordedCaptureRequiresCallbackTransactionError;
|
|
2367
|
+
exports.recordedReadSchemaFor = recordedReadSchemaFor;
|
|
2368
|
+
exports.recordedReadSqlSchema = recordedReadSqlSchema;
|
|
2369
|
+
exports.recordedRelation = recordedRelation;
|
|
2370
|
+
exports.requireExternalRecordedReadSource = requireExternalRecordedReadSource;
|
|
2371
|
+
exports.requireRecordedReadBinding = requireRecordedReadBinding;
|
|
2372
|
+
exports.requireSqlSchema = requireSqlSchema;
|
|
2373
|
+
exports.resolveReadCoordinate = resolveReadCoordinate;
|
|
2374
|
+
exports.runInsertBatch = runInsertBatch;
|
|
2375
|
+
exports.runInsertBatchReturning = runInsertBatchReturning;
|
|
2376
|
+
exports.runInsertNoReturn = runInsertNoReturn;
|
|
2377
|
+
exports.uncapturedGraphWriteLock = uncapturedGraphWriteLock;
|
|
2378
|
+
exports.validateEdgeEndpoints = validateEdgeEndpoints;
|
|
2379
|
+
exports.vectorSlotKey = vectorSlotKey;
|
|
2380
|
+
exports.withRecordedCoordinate = withRecordedCoordinate;
|
|
2381
|
+
exports.withRecordedFlushObserver = withRecordedFlushObserver;
|
|
2382
|
+
//# sourceMappingURL=chunk-XOX22WHL.cjs.map
|
|
2383
|
+
//# sourceMappingURL=chunk-XOX22WHL.cjs.map
|