@sixb/core 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/index.js +77 -89
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/run-dispatch.d.ts.map +1 -1
- package/dist/actions/types/context.d.ts +2 -0
- package/dist/actions/types/context.d.ts.map +1 -1
- package/dist/actions/validation.d.ts +1 -1
- package/dist/actions/validation.d.ts.map +1 -1
- package/dist/actions/worker.js +33 -37
- package/dist/actions/worker.js.map +2 -2
- package/dist/agents/adapters.d.ts +3 -3
- package/dist/agents/{context.d.ts → context/entries.d.ts} +3 -3
- package/dist/agents/context/entries.d.ts.map +1 -0
- package/dist/agents/context/index.d.ts +4 -0
- package/dist/agents/context/index.d.ts.map +1 -0
- package/dist/agents/context/index.js +19 -0
- package/dist/agents/{streams.js.map → context/index.js.map} +1 -1
- package/dist/agents/context-model.d.ts +1 -1
- package/dist/agents/context-model.d.ts.map +1 -1
- package/dist/agents/context-resolution.d.ts +1 -1
- package/dist/agents/context-resolution.d.ts.map +1 -1
- package/dist/agents/index.d.ts +4 -4
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +193 -204
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/message.d.ts +1 -1
- package/dist/agents/message.d.ts.map +1 -1
- package/dist/agents/model-loop.d.ts +2 -0
- package/dist/agents/model-loop.d.ts.map +1 -1
- package/dist/agents/request.d.ts +1 -1
- package/dist/agents/request.d.ts.map +1 -1
- package/dist/agents/streams/index.d.ts +4 -0
- package/dist/agents/streams/index.d.ts.map +1 -0
- package/dist/agents/streams/index.js +20 -0
- package/dist/{chunk-y64skrwp.js.map → agents/streams/index.js.map} +1 -1
- package/dist/agents/streams/internal.d.ts +3 -0
- package/dist/agents/streams/internal.d.ts.map +1 -0
- package/dist/agents/streams/internal.js +40 -0
- package/dist/agents/{context.js.map → streams/internal.js.map} +1 -1
- package/dist/agents/{streams.d.ts → streams/protocol.d.ts} +5 -5
- package/dist/agents/streams/protocol.d.ts.map +1 -0
- package/dist/agents/types.d.ts +1 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +96 -108
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/strategy.js +8 -9
- package/dist/auth/strategy.js.map +1 -1
- package/dist/authorization/index.js +51 -56
- package/dist/authorization/index.js.map +1 -1
- package/dist/blob-storage/browser.js +15 -17
- package/dist/blob-storage/browser.js.map +1 -1
- package/dist/blob-storage/index.js +36 -38
- package/dist/blob-storage/index.js.map +1 -1
- package/dist/bootstrap/discovery.d.ts +14 -1
- package/dist/bootstrap/discovery.d.ts.map +1 -1
- package/dist/bootstrap/index.d.ts +2 -2
- package/dist/bootstrap/index.d.ts.map +1 -1
- package/dist/bootstrap/index.js +80 -88
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/broker/in-memory.d.ts +8 -2
- package/dist/broker/in-memory.d.ts.map +1 -1
- package/dist/broker/index.d.ts +4 -2
- package/dist/broker/index.d.ts.map +1 -1
- package/dist/broker/index.js +12 -10
- package/dist/broker/index.js.map +1 -1
- package/dist/broker/retention.d.ts +4 -0
- package/dist/broker/retention.d.ts.map +1 -0
- package/dist/broker/subscriber.d.ts +10 -0
- package/dist/broker/subscriber.d.ts.map +1 -0
- package/dist/broker/types.d.ts +14 -1
- package/dist/broker/types.d.ts.map +1 -1
- package/dist/chunk-0y39rgsb.js +43 -0
- package/dist/{chunk-c15dr03f.js.map → chunk-0y39rgsb.js.map} +2 -2
- package/dist/{chunk-k522z7v6.js → chunk-17kfctj6.js} +16 -11
- package/dist/chunk-17kfctj6.js.map +10 -0
- package/dist/{chunk-ajnan18g.js → chunk-1824gssz.js} +74 -106
- package/dist/chunk-1824gssz.js.map +12 -0
- package/dist/chunk-28ja2cjs.js +602 -0
- package/dist/chunk-28ja2cjs.js.map +18 -0
- package/dist/{chunk-5gd7tpv6.js → chunk-2c4j899j.js} +4 -4
- package/dist/chunk-2c4j899j.js.map +11 -0
- package/dist/{chunk-rv2hkwwa.js → chunk-358caqf5.js} +157 -180
- package/dist/chunk-358caqf5.js.map +12 -0
- package/dist/{chunk-fvt9rjsa.js → chunk-38zv5rkr.js} +4 -4
- package/dist/{chunk-fvt9rjsa.js.map → chunk-38zv5rkr.js.map} +1 -1
- package/dist/{chunk-w3e09qqk.js → chunk-39tqv9hz.js} +24 -24
- package/dist/{chunk-w3e09qqk.js.map → chunk-39tqv9hz.js.map} +2 -2
- package/dist/{chunk-04b07a9q.js → chunk-3bh94gbw.js} +13 -13
- package/dist/{chunk-04b07a9q.js.map → chunk-3bh94gbw.js.map} +2 -2
- package/dist/{chunk-s5y30bc9.js → chunk-3qms4nax.js} +52 -50
- package/dist/{chunk-s5y30bc9.js.map → chunk-3qms4nax.js.map} +5 -5
- package/dist/{chunk-nf4r78r4.js → chunk-5a4a52tq.js} +4 -4
- package/dist/{chunk-nf4r78r4.js.map → chunk-5a4a52tq.js.map} +2 -2
- package/dist/{chunk-wtf06et8.js → chunk-5c7ga8zz.js} +54 -177
- package/dist/chunk-5c7ga8zz.js.map +12 -0
- package/dist/{chunk-rte5sm3z.js → chunk-5hz0fnca.js} +23 -23
- package/dist/{chunk-rte5sm3z.js.map → chunk-5hz0fnca.js.map} +2 -2
- package/dist/{chunk-xajtptbw.js → chunk-5p1v802y.js} +1401 -445
- package/dist/chunk-5p1v802y.js.map +44 -0
- package/dist/chunk-653vwrzr.js +39 -0
- package/dist/chunk-653vwrzr.js.map +10 -0
- package/dist/{chunk-qw9gvjv5.js → chunk-72w2pxk7.js} +13 -13
- package/dist/{chunk-qw9gvjv5.js.map → chunk-72w2pxk7.js.map} +2 -2
- package/dist/chunk-7apz6hg4.js +50 -0
- package/dist/{chunk-jq43kdvk.js.map → chunk-7apz6hg4.js.map} +2 -2
- package/dist/chunk-7bs40fe1.js +218 -0
- package/dist/{chunk-p1rzczbt.js.map → chunk-7bs40fe1.js.map} +3 -3
- package/dist/chunk-7zgecwy1.js +113 -0
- package/dist/chunk-7zgecwy1.js.map +10 -0
- package/dist/{chunk-xhy826cz.js → chunk-85cd7e8c.js} +8 -7
- package/dist/chunk-85cd7e8c.js.map +10 -0
- package/dist/{chunk-pc7ys28c.js → chunk-860dwwy0.js} +29 -29
- package/dist/{chunk-pc7ys28c.js.map → chunk-860dwwy0.js.map} +2 -2
- package/dist/chunk-8vj0rjgs.js +165 -0
- package/dist/chunk-8vj0rjgs.js.map +15 -0
- package/dist/{chunk-7y0f6rf1.js → chunk-92vk7gta.js} +58 -58
- package/dist/chunk-92vk7gta.js.map +10 -0
- package/dist/{chunk-rafagrwr.js → chunk-93csa55g.js} +45 -17
- package/dist/chunk-93csa55g.js.map +11 -0
- package/dist/{chunk-aa2pen2v.js → chunk-976rxdpx.js} +188 -175
- package/dist/{chunk-aa2pen2v.js.map → chunk-976rxdpx.js.map} +2 -2
- package/dist/{chunk-d8qkxt2v.js → chunk-98cw09sw.js} +7 -7
- package/dist/chunk-98cw09sw.js.map +10 -0
- package/dist/{chunk-n4khvw9n.js → chunk-9qsh3p5y.js} +17 -17
- package/dist/{chunk-n4khvw9n.js.map → chunk-9qsh3p5y.js.map} +2 -2
- package/dist/{chunk-4a849fr1.js → chunk-9tc8dxmn.js} +1 -1
- package/dist/{chunk-9nbmsvn5.js → chunk-9vx5e9g1.js} +9 -9
- package/dist/{chunk-9nbmsvn5.js.map → chunk-9vx5e9g1.js.map} +2 -2
- package/dist/{chunk-8m5ejdpn.js → chunk-9x8dybsb.js} +5 -5
- package/dist/chunk-9x8dybsb.js.map +10 -0
- package/dist/chunk-aa6z4a19.js +358 -0
- package/dist/chunk-aa6z4a19.js.map +12 -0
- package/dist/{chunk-3xep5cjx.js → chunk-agbbygvh.js} +104 -86
- package/dist/chunk-agbbygvh.js.map +15 -0
- package/dist/{chunk-2dw777qw.js → chunk-ap0g1g74.js} +37 -82
- package/dist/{chunk-2dw777qw.js.map → chunk-ap0g1g74.js.map} +3 -4
- package/dist/{chunk-v4en4jc2.js → chunk-awbhdqyc.js} +7 -7
- package/dist/{chunk-v4en4jc2.js.map → chunk-awbhdqyc.js.map} +2 -2
- package/dist/{chunk-w9tg6yyb.js → chunk-b0ec55a1.js} +54 -37
- package/dist/chunk-b0ec55a1.js.map +12 -0
- package/dist/{chunk-ka3a2ft3.js → chunk-b19g04jk.js} +12 -12
- package/dist/{chunk-ka3a2ft3.js.map → chunk-b19g04jk.js.map} +2 -2
- package/dist/{chunk-gbejpkex.js → chunk-bn138h9w.js} +27 -28
- package/dist/{chunk-gbejpkex.js.map → chunk-bn138h9w.js.map} +3 -3
- package/dist/{chunk-nx7k8tpr.js → chunk-br3k6qbf.js} +23 -23
- package/dist/{chunk-nx7k8tpr.js.map → chunk-br3k6qbf.js.map} +2 -2
- package/dist/{chunk-dbc80ad7.js → chunk-c5rkjrgp.js} +28 -28
- package/dist/{chunk-dbc80ad7.js.map → chunk-c5rkjrgp.js.map} +2 -2
- package/dist/{chunk-dktq02ne.js → chunk-cqr3acm1.js} +4 -4
- package/dist/{chunk-dktq02ne.js.map → chunk-cqr3acm1.js.map} +2 -2
- package/dist/chunk-d62kjtbg.js +7 -0
- package/dist/{chunk-zcnhxkvd.js.map → chunk-d62kjtbg.js.map} +2 -2
- package/dist/{chunk-74drx9gd.js → chunk-dfm066qg.js} +10 -10
- package/dist/{chunk-74drx9gd.js.map → chunk-dfm066qg.js.map} +2 -2
- package/dist/{chunk-5e3pq99w.js → chunk-dmn70ztd.js} +30 -30
- package/dist/chunk-dmn70ztd.js.map +11 -0
- package/dist/{chunk-p1x242ad.js → chunk-dz5h08xv.js} +175 -175
- package/dist/{chunk-p1x242ad.js.map → chunk-dz5h08xv.js.map} +2 -2
- package/dist/{chunk-p2vqaxkc.js → chunk-e0d1rzef.js} +27 -22
- package/dist/{chunk-p2vqaxkc.js.map → chunk-e0d1rzef.js.map} +3 -3
- package/dist/{chunk-5sz8ta9r.js → chunk-e1c18xjx.js} +52 -52
- package/dist/{chunk-5sz8ta9r.js.map → chunk-e1c18xjx.js.map} +2 -2
- package/dist/{chunk-19jp6g9d.js → chunk-f0rwz2vh.js} +54 -33
- package/dist/chunk-f0rwz2vh.js.map +11 -0
- package/dist/{chunk-2xns679x.js → chunk-f4w3yp4f.js} +171 -36
- package/dist/chunk-f4w3yp4f.js.map +12 -0
- package/dist/{chunk-979ww6b3.js → chunk-fb3feg1e.js} +29 -29
- package/dist/{chunk-979ww6b3.js.map → chunk-fb3feg1e.js.map} +2 -2
- package/dist/{chunk-f26bck4t.js → chunk-ftv470j8.js} +393 -355
- package/dist/{chunk-f26bck4t.js.map → chunk-ftv470j8.js.map} +7 -7
- package/dist/{chunk-4sm0aznx.js → chunk-g00bfdq6.js} +254 -256
- package/dist/{chunk-4sm0aznx.js.map → chunk-g00bfdq6.js.map} +3 -3
- package/dist/{chunk-p03r0h5s.js → chunk-g53f0e4j.js} +76 -202
- package/dist/chunk-g53f0e4j.js.map +15 -0
- package/dist/chunk-g6cke204.js +124 -0
- package/dist/chunk-g6cke204.js.map +10 -0
- package/dist/{chunk-q0k9nc5a.js → chunk-g7knyczr.js} +98 -98
- package/dist/{chunk-q0k9nc5a.js.map → chunk-g7knyczr.js.map} +2 -2
- package/dist/{chunk-51fjndv0.js → chunk-gfdh9kqa.js} +4 -4
- package/dist/{chunk-51fjndv0.js.map → chunk-gfdh9kqa.js.map} +2 -2
- package/dist/{chunk-8tsf6dmc.js → chunk-gqh45d2n.js} +244 -205
- package/dist/chunk-gqh45d2n.js.map +15 -0
- package/dist/chunk-h3v76ams.js +32 -0
- package/dist/{chunk-08m3b6w8.js.map → chunk-h3v76ams.js.map} +2 -2
- package/dist/{chunk-jecn6t54.js → chunk-jgwb25gc.js} +74 -74
- package/dist/{chunk-jecn6t54.js.map → chunk-jgwb25gc.js.map} +2 -2
- package/dist/{chunk-wdage1eb.js → chunk-jmfet9r4.js} +6 -6
- package/dist/{chunk-wdage1eb.js.map → chunk-jmfet9r4.js.map} +2 -2
- package/dist/{chunk-k34z5rvh.js → chunk-kfee1h52.js} +132 -48
- package/dist/chunk-kfee1h52.js.map +13 -0
- package/dist/{chunk-2ab72m2h.js → chunk-m2ca93my.js} +3 -3
- package/dist/{chunk-2ab72m2h.js.map → chunk-m2ca93my.js.map} +2 -2
- package/dist/{chunk-4jjp5k14.js → chunk-mmagke4x.js} +6 -6
- package/dist/{chunk-4jjp5k14.js.map → chunk-mmagke4x.js.map} +2 -2
- package/dist/{chunk-359jm1jw.js → chunk-mrp7k0pw.js} +20 -20
- package/dist/{chunk-359jm1jw.js.map → chunk-mrp7k0pw.js.map} +2 -2
- package/dist/{chunk-h0k55pc7.js → chunk-ms2tmn1k.js} +139 -139
- package/dist/{chunk-h0k55pc7.js.map → chunk-ms2tmn1k.js.map} +2 -2
- package/dist/{chunk-h5vqbfmd.js → chunk-nmbxcaqx.js} +117 -117
- package/dist/{chunk-h5vqbfmd.js.map → chunk-nmbxcaqx.js.map} +3 -3
- package/dist/{chunk-n2w475r0.js → chunk-nt99sxd6.js} +82 -82
- package/dist/{chunk-n2w475r0.js.map → chunk-nt99sxd6.js.map} +3 -3
- package/dist/{chunk-v1xppd0y.js → chunk-p5vcsw9c.js} +60 -60
- package/dist/{chunk-v1xppd0y.js.map → chunk-p5vcsw9c.js.map} +2 -2
- package/dist/{chunk-sbzzr4kx.js → chunk-p6a4npdx.js} +1260 -1289
- package/dist/chunk-p6a4npdx.js.map +58 -0
- package/dist/{chunk-trxxmgnf.js → chunk-pqajwytd.js} +10 -10
- package/dist/{chunk-trxxmgnf.js.map → chunk-pqajwytd.js.map} +3 -3
- package/dist/{chunk-nn0tekr1.js → chunk-pr2h4bv4.js} +33 -33
- package/dist/{chunk-nn0tekr1.js.map → chunk-pr2h4bv4.js.map} +2 -2
- package/dist/{chunk-xwnf87e1.js → chunk-q5gz3g2j.js} +64 -64
- package/dist/{chunk-xwnf87e1.js.map → chunk-q5gz3g2j.js.map} +2 -2
- package/dist/{chunk-5ntny1qx.js → chunk-qf954wje.js} +6 -6
- package/dist/{chunk-5ntny1qx.js.map → chunk-qf954wje.js.map} +2 -2
- package/dist/chunk-qma80ych.js +30 -0
- package/dist/chunk-qma80ych.js.map +11 -0
- package/dist/{chunk-mth82m8t.js → chunk-qyeptdyv.js} +171 -77
- package/dist/chunk-qyeptdyv.js.map +15 -0
- package/dist/{chunk-b49dgvsj.js → chunk-r2y23egw.js} +3 -3
- package/dist/{chunk-b49dgvsj.js.map → chunk-r2y23egw.js.map} +2 -2
- package/dist/{chunk-mwsxn98e.js → chunk-r7fj830t.js} +253 -200
- package/dist/chunk-r7fj830t.js.map +36 -0
- package/dist/{chunk-4rh2m6zg.js → chunk-rb1xx120.js} +13 -13
- package/dist/{chunk-4rh2m6zg.js.map → chunk-rb1xx120.js.map} +2 -2
- package/dist/{chunk-gzasd5b6.js → chunk-rtk71jzp.js} +22 -22
- package/dist/{chunk-gzasd5b6.js.map → chunk-rtk71jzp.js.map} +2 -2
- package/dist/chunk-s3csryxe.js +152 -0
- package/dist/chunk-s3csryxe.js.map +11 -0
- package/dist/chunk-s670k14v.js +60 -0
- package/dist/{chunk-407j3msh.js.map → chunk-s670k14v.js.map} +2 -2
- package/dist/chunk-skz0hst3.js +788 -0
- package/dist/chunk-skz0hst3.js.map +19 -0
- package/dist/{chunk-3z1qec12.js → chunk-t1f4f1ve.js} +107 -64
- package/dist/{chunk-3z1qec12.js.map → chunk-t1f4f1ve.js.map} +3 -3
- package/dist/chunk-v2vcg0w6.js +151 -0
- package/dist/chunk-v2vcg0w6.js.map +11 -0
- package/dist/{chunk-r8jrnexe.js → chunk-v4jbb3rs.js} +4 -4
- package/dist/{chunk-r8jrnexe.js.map → chunk-v4jbb3rs.js.map} +2 -2
- package/dist/{chunk-w1tvjszy.js → chunk-vsj3mdfj.js} +8 -8
- package/dist/{chunk-w1tvjszy.js.map → chunk-vsj3mdfj.js.map} +2 -2
- package/dist/{chunk-9dzba0f2.js → chunk-wjasrj67.js} +8 -8
- package/dist/{chunk-9dzba0f2.js.map → chunk-wjasrj67.js.map} +2 -2
- package/dist/{chunk-1evzqhks.js → chunk-wr8qp979.js} +6 -6
- package/dist/{chunk-1evzqhks.js.map → chunk-wr8qp979.js.map} +2 -2
- package/dist/{chunk-n6jxh8sw.js → chunk-wy0qdqfm.js} +18 -18
- package/dist/{chunk-n6jxh8sw.js.map → chunk-wy0qdqfm.js.map} +2 -2
- package/dist/{chunk-z4ccwbkz.js → chunk-x9v4cx1d.js} +1 -1
- package/dist/{chunk-ry24jbr1.js → chunk-yv79ncbv.js} +10 -10
- package/dist/{chunk-ry24jbr1.js.map → chunk-yv79ncbv.js.map} +2 -2
- package/dist/{chunk-yp8ee62z.js → chunk-z30bv4ga.js} +35 -35
- package/dist/{chunk-yp8ee62z.js.map → chunk-z30bv4ga.js.map} +2 -2
- package/dist/{chunk-8ydjhh27.js → chunk-z3y411fq.js} +11 -7
- package/dist/{chunk-8ydjhh27.js.map → chunk-z3y411fq.js.map} +3 -3
- package/dist/{chunk-9t8f5xfx.js → chunk-z5rnrmz1.js} +10 -10
- package/dist/{chunk-9t8f5xfx.js.map → chunk-z5rnrmz1.js.map} +2 -2
- package/dist/{chunk-96swp2wd.js → chunk-z667z3sg.js} +3 -3
- package/dist/{chunk-96swp2wd.js.map → chunk-z667z3sg.js.map} +2 -2
- package/dist/{chunk-4yqmp43v.js → chunk-z8fx5cgb.js} +12 -12
- package/dist/{chunk-4yqmp43v.js.map → chunk-z8fx5cgb.js.map} +2 -2
- package/dist/{chunk-yt8wphsx.js → chunk-zvx7h87b.js} +3 -3
- package/dist/{chunk-yt8wphsx.js.map → chunk-zvx7h87b.js.map} +2 -2
- package/dist/connectors/connections/authorizations.d.ts.map +1 -1
- package/dist/connectors/connections/contracts.d.ts +3 -0
- package/dist/connectors/connections/contracts.d.ts.map +1 -1
- package/dist/connectors/connections/internal.js +9 -10
- package/dist/connectors/connections/internal.js.map +1 -1
- package/dist/connectors/connections/request.d.ts +3 -1
- package/dist/connectors/connections/request.d.ts.map +1 -1
- package/dist/connectors/connections/runs.d.ts.map +1 -1
- package/dist/connectors/connections/tokens.d.ts.map +1 -1
- package/dist/connectors/connections/validation.d.ts +5 -1
- package/dist/connectors/connections/validation.d.ts.map +1 -1
- package/dist/connectors/types.d.ts +19 -4
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/datasets/write.js +8 -12
- package/dist/datasets/write.js.map +1 -1
- package/dist/edits/index.js +7 -8
- package/dist/edits/index.js.map +1 -1
- package/dist/error-reporting/internal.js +22 -24
- package/dist/error-reporting/internal.js.map +1 -1
- package/dist/errors/internal.d.ts +1 -1
- package/dist/errors/internal.d.ts.map +1 -1
- package/dist/errors/internal.js +22 -24
- package/dist/errors/internal.js.map +1 -1
- package/dist/errors/redaction.d.ts +8 -0
- package/dist/errors/redaction.d.ts.map +1 -0
- package/dist/errors/types.d.ts +4 -0
- package/dist/errors/types.d.ts.map +1 -1
- package/dist/events/execution.d.ts +1 -1
- package/dist/events/execution.d.ts.map +1 -1
- package/dist/events/index.js +60 -63
- package/dist/events/index.js.map +1 -1
- package/dist/events/scope.js +4 -5
- package/dist/events/scope.js.map +1 -1
- package/dist/events/selectors/index.js +9 -10
- package/dist/events/selectors/index.js.map +1 -1
- package/dist/events/service.d.ts +2 -2
- package/dist/events/service.d.ts.map +1 -1
- package/dist/execution/agent.d.ts +3 -3
- package/dist/execution/agent.d.ts.map +1 -1
- package/dist/execution/agent.js +71 -82
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/durable.d.ts +1 -0
- package/dist/execution/durable.d.ts.map +1 -1
- package/dist/execution/primitive.d.ts +2 -0
- package/dist/execution/primitive.d.ts.map +1 -1
- package/dist/execution/primitive.js +64 -71
- package/dist/execution/primitive.js.map +3 -3
- package/dist/execution/request.d.ts +1 -0
- package/dist/execution/request.d.ts.map +1 -1
- package/dist/execution/request.js +66 -75
- package/dist/execution/request.js.map +3 -3
- package/dist/http/index.js +10 -11
- package/dist/http/index.js.map +1 -1
- package/dist/index.d.ts +17 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +457 -477
- package/dist/index.js.map +1 -1
- package/dist/lake-storage/changes.d.ts +5 -0
- package/dist/lake-storage/changes.d.ts.map +1 -0
- package/dist/lake-storage/in-memory.d.ts +2 -1
- package/dist/lake-storage/in-memory.d.ts.map +1 -1
- package/dist/lake-storage/index.d.ts +2 -1
- package/dist/lake-storage/index.d.ts.map +1 -1
- package/dist/lake-storage/index.js +40 -42
- package/dist/lake-storage/index.js.map +1 -1
- package/dist/lake-storage/types.d.ts +36 -0
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/logging/index.d.ts +3 -4
- package/dist/logging/index.d.ts.map +1 -1
- package/dist/logging/index.js +18 -40
- package/dist/logging/index.js.map +1 -1
- package/dist/logging/internal.d.ts +5 -0
- package/dist/logging/internal.d.ts.map +1 -0
- package/dist/logging/internal.js +43 -0
- package/dist/logging/internal.js.map +9 -0
- package/dist/materialization/index.d.ts +1 -1
- package/dist/materialization/index.d.ts.map +1 -1
- package/dist/materialization/index.js +46 -49
- package/dist/materialization/index.js.map +1 -1
- package/dist/materialization/model.d.ts +12 -1
- package/dist/materialization/model.d.ts.map +1 -1
- package/dist/materializer/index.d.ts +1 -1
- package/dist/materializer/index.d.ts.map +1 -1
- package/dist/materializer/index.js +137 -145
- package/dist/materializer/index.js.map +1 -1
- package/dist/materializer/materializer.d.ts +5 -1
- package/dist/materializer/materializer.d.ts.map +1 -1
- package/dist/materializer/projections/entry-validator.d.ts +2 -1
- package/dist/materializer/projections/entry-validator.d.ts.map +1 -1
- package/dist/materializer/projections/replace.d.ts.map +1 -1
- package/dist/materializer/projections/source-materialization.d.ts +4 -3
- package/dist/materializer/projections/source-materialization.d.ts.map +1 -1
- package/dist/materializer/shared/normalize.d.ts +2 -1
- package/dist/materializer/shared/normalize.d.ts.map +1 -1
- package/dist/models/errors.d.ts +4 -0
- package/dist/models/errors.d.ts.map +1 -1
- package/dist/models/execution/binding.d.ts +9 -0
- package/dist/models/execution/binding.d.ts.map +1 -0
- package/dist/models/execution/errors.d.ts +9 -0
- package/dist/models/execution/errors.d.ts.map +1 -0
- package/dist/models/execution/index.d.ts +11 -0
- package/dist/models/execution/index.d.ts.map +1 -0
- package/dist/models/execution/index.js +55 -0
- package/dist/models/execution/index.js.map +9 -0
- package/dist/models/execution/model-call-accounting.d.ts +17 -0
- package/dist/models/execution/model-call-accounting.d.ts.map +1 -0
- package/dist/models/execution/model-call-admission.d.ts +47 -0
- package/dist/models/execution/model-call-admission.d.ts.map +1 -0
- package/dist/models/execution/model-call-limits.d.ts +15 -0
- package/dist/models/execution/model-call-limits.d.ts.map +1 -0
- package/dist/models/execution/model-call-recorder.d.ts +40 -0
- package/dist/models/execution/model-call-recorder.d.ts.map +1 -0
- package/dist/models/execution/model-call-recovery.d.ts +12 -0
- package/dist/models/execution/model-call-recovery.d.ts.map +1 -0
- package/dist/models/execution/recovery-queue.d.ts +5 -0
- package/dist/models/execution/recovery-queue.d.ts.map +1 -0
- package/dist/models/execution/types.d.ts +44 -0
- package/dist/models/execution/types.d.ts.map +1 -0
- package/dist/models/execution/usage.d.ts +5 -0
- package/dist/models/execution/usage.d.ts.map +1 -0
- package/dist/models/execution.d.ts +6 -0
- package/dist/models/execution.d.ts.map +1 -0
- package/dist/models/generation-types.d.ts +40 -0
- package/dist/models/generation-types.d.ts.map +1 -0
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +42 -43
- package/dist/models/index.js.map +1 -1
- package/dist/models/language-model.d.ts +3 -0
- package/dist/models/language-model.d.ts.map +1 -1
- package/dist/models/output.d.ts +5 -0
- package/dist/models/output.d.ts.map +1 -0
- package/dist/models/resolve.d.ts +4 -0
- package/dist/models/resolve.d.ts.map +1 -0
- package/dist/objects/execution.d.ts.map +1 -1
- package/dist/objects/index.js +75 -87
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/query/index.js +67 -76
- package/dist/objects/query/index.js.map +1 -1
- package/dist/ontology/index.d.ts +1 -2
- package/dist/ontology/index.d.ts.map +1 -1
- package/dist/ontology/index.js +62 -113
- package/dist/ontology/index.js.map +1 -1
- package/dist/ontology/internal.d.ts +7 -0
- package/dist/ontology/internal.d.ts.map +1 -1
- package/dist/ontology/internal.js +65 -116
- package/dist/ontology/internal.js.map +3 -4
- package/dist/pipelines/index.js +57 -66
- package/dist/pipelines/index.js.map +1 -1
- package/dist/pipelines/run-dispatch.d.ts.map +1 -1
- package/dist/projections/internal.js +56 -67
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/run-dispatch.d.ts.map +1 -1
- package/dist/query.d.ts +0 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +11 -15
- package/dist/query.js.map +1 -1
- package/dist/queues/in-memory.d.ts +7 -3
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/queues/index.d.ts +2 -1
- package/dist/queues/index.d.ts.map +1 -1
- package/dist/queues/index.js +6 -7
- package/dist/queues/index.js.map +1 -1
- package/dist/queues/indexed-heap.d.ts +15 -0
- package/dist/queues/indexed-heap.d.ts.map +1 -0
- package/dist/queues/types.d.ts +3 -20
- package/dist/queues/types.d.ts.map +1 -1
- package/dist/rules/internal.js +4 -5
- package/dist/rules/internal.js.map +1 -1
- package/dist/runtime/create.d.ts +2 -1
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +2 -1
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/internal.js +13 -14
- package/dist/runtime/internal.js.map +1 -1
- package/dist/runtime/ontology-mutations.d.ts +3 -1
- package/dist/runtime/ontology-mutations.d.ts.map +1 -1
- package/dist/runtime/sixb.d.ts +2 -0
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/sandboxes/errors.d.ts +4 -0
- package/dist/sandboxes/errors.d.ts.map +1 -1
- package/dist/sandboxes/index.d.ts +2 -2
- package/dist/sandboxes/index.d.ts.map +1 -1
- package/dist/sandboxes/index.js +14 -13
- package/dist/sandboxes/index.js.map +1 -1
- package/dist/sandboxes/sandbox.d.ts +35 -7
- package/dist/sandboxes/sandbox.d.ts.map +1 -1
- package/dist/scheduler/index.js +9 -10
- package/dist/scheduler/index.js.map +1 -1
- package/dist/schedules/index.js +31 -33
- package/dist/schedules/index.js.map +1 -1
- package/dist/shares/internal.js +46 -54
- package/dist/shares/internal.js.map +2 -2
- package/dist/storage/action-runs/failure.js +7 -9
- package/dist/storage/action-runs/failure.js.map +1 -1
- package/dist/storage/action-runs/provider.js +4 -8
- package/dist/storage/action-runs/provider.js.map +1 -1
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +26 -30
- package/dist/storage/agents/provider.js.map +1 -1
- package/dist/storage/agents/types.d.ts +0 -3
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/attribution.d.ts +4 -0
- package/dist/storage/ai-cost/attribution.d.ts.map +1 -0
- package/dist/storage/ai-cost/groups.d.ts +3 -0
- package/dist/storage/ai-cost/groups.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.d.ts +1 -0
- package/dist/storage/ai-cost/provider.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.js +30 -143
- package/dist/storage/ai-cost/provider.js.map +3 -4
- package/dist/storage/ai-cost/types.d.ts +15 -0
- package/dist/storage/ai-cost/types.d.ts.map +1 -1
- package/dist/storage/ai-limits/enforcement.js +14 -16
- package/dist/storage/ai-limits/enforcement.js.map +1 -1
- package/dist/storage/ai-limits/provider.js +56 -57
- package/dist/storage/ai-limits/provider.js.map +1 -1
- package/dist/storage/auth/in-memory.d.ts +1 -1
- package/dist/storage/auth/in-memory.d.ts.map +1 -1
- package/dist/storage/connector-connections/in-memory.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider/runs.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.js +35 -37
- package/dist/storage/connector-connections/provider.js.map +3 -3
- package/dist/storage/connector-connections/types.d.ts +3 -2
- package/dist/storage/connector-connections/types.d.ts.map +1 -1
- package/dist/storage/executions/in-memory.d.ts.map +1 -1
- package/dist/storage/executions/provider.d.ts +2 -1
- package/dist/storage/executions/provider.d.ts.map +1 -1
- package/dist/storage/executions/provider.js +14 -11
- package/dist/storage/executions/provider.js.map +3 -3
- package/dist/storage/executions/types.d.ts +6 -2
- package/dist/storage/executions/types.d.ts.map +1 -1
- package/dist/storage/executions/validation.d.ts +2 -0
- package/dist/storage/executions/validation.d.ts.map +1 -1
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +7 -8
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +221 -256
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/internal.d.ts +10 -0
- package/dist/storage/internal.d.ts.map +1 -0
- package/dist/storage/internal.js +47 -0
- package/dist/storage/internal.js.map +9 -0
- package/dist/storage/ontology/in-memory/materializations-state.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/shared-state.d.ts +15 -2
- package/dist/storage/ontology/in-memory/shared-state.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/source-roots.d.ts +6 -0
- package/dist/storage/ontology/in-memory/source-roots.d.ts.map +1 -0
- package/dist/storage/ontology/in-memory/sources.d.ts.map +1 -1
- package/dist/storage/ontology/index.d.ts +1 -1
- package/dist/storage/ontology/index.d.ts.map +1 -1
- package/dist/storage/ontology/provider.d.ts +16 -0
- package/dist/storage/ontology/provider.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +107 -109
- package/dist/storage/ontology/provider.js.map +1 -1
- package/dist/storage/ontology/sources.d.ts +13 -4
- package/dist/storage/ontology/sources.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +18 -19
- package/dist/storage/operation-scope.js.map +1 -1
- package/dist/storage/pipeline-runs/provider.js +4 -6
- package/dist/storage/pipeline-runs/provider.js.map +1 -1
- package/dist/storage/projection-runs/lifecycle.d.ts.map +1 -1
- package/dist/storage/projection-runs/provider.js +66 -70
- package/dist/storage/projection-runs/provider.js.map +1 -1
- package/dist/storage/projection-runs/types.d.ts +2 -0
- package/dist/storage/projection-runs/types.d.ts.map +1 -1
- package/dist/storage/share-grants/provider.js +17 -19
- package/dist/storage/share-grants/provider.js.map +1 -1
- package/dist/storage/share-sessions/provider.js +14 -15
- package/dist/storage/share-sessions/provider.js.map +1 -1
- package/dist/storage/sync-runs/provider.js +4 -6
- package/dist/storage/sync-runs/provider.js.map +1 -1
- package/dist/storage/webhook-runs/provider.js +4 -6
- package/dist/storage/webhook-runs/provider.js.map +1 -1
- package/dist/storage/workflow-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.js +13 -21
- package/dist/storage/workflow-runs/provider.js.map +1 -1
- package/dist/storage/workflow-runs/types.d.ts +0 -3
- package/dist/storage/workflow-runs/types.d.ts.map +1 -1
- package/dist/syncs/index.js +56 -65
- package/dist/syncs/index.js.map +1 -1
- package/dist/syncs/run-dispatch.d.ts.map +1 -1
- package/dist/testing/action-execution.d.ts +4 -1
- package/dist/testing/action-execution.d.ts.map +1 -1
- package/dist/testing/agent-execution.d.ts +1 -0
- package/dist/testing/agent-execution.d.ts.map +1 -1
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-model-call-groups-contract.d.ts.map +1 -1
- package/dist/testing/broker-contract.d.ts.map +1 -1
- package/dist/testing/connector-connection-storage-contract.d.ts.map +1 -1
- package/dist/testing/execution-storage-contract.d.ts.map +1 -1
- package/dist/testing/execution.d.ts +1 -0
- package/dist/testing/execution.d.ts.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2282 -1662
- package/dist/testing/index.js.map +16 -15
- package/dist/testing/lake-changes-contract.d.ts +6 -0
- package/dist/testing/lake-changes-contract.d.ts.map +1 -0
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
- package/dist/testing/projection-run-storage-contract.d.ts.map +1 -1
- package/dist/testing/workflow-execution.d.ts +1 -0
- package/dist/testing/workflow-execution.d.ts.map +1 -1
- package/dist/webhooks/connections.d.ts +6 -0
- package/dist/webhooks/connections.d.ts.map +1 -0
- package/dist/webhooks/index.d.ts +1 -1
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/internal.d.ts +2 -0
- package/dist/webhooks/internal.d.ts.map +1 -1
- package/dist/webhooks/internal.js +98 -61
- package/dist/webhooks/internal.js.map +4 -3
- package/dist/webhooks/registry.d.ts +1 -1
- package/dist/webhooks/registry.d.ts.map +1 -1
- package/dist/webhooks/types.d.ts +15 -4
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/workers/index.js +11 -13
- package/dist/workers/index.js.map +2 -2
- package/dist/workflows/failure.d.ts +2 -0
- package/dist/workflows/failure.d.ts.map +1 -1
- package/dist/workflows/index.js +136 -147
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/request.d.ts.map +1 -1
- package/dist/workflows/run-dispatch.d.ts +3 -2
- package/dist/workflows/run-dispatch.d.ts.map +1 -1
- package/dist/workflows/types.d.ts +2 -0
- package/dist/workflows/types.d.ts.map +1 -1
- package/package.json +48 -30
- package/src/actions/run-dispatch.ts +2 -6
- package/src/actions/types/context.ts +2 -0
- package/src/actions/validation.ts +2 -1
- package/src/agents/adapters.ts +4 -9
- package/src/agents/{context.ts → context/entries.ts} +4 -4
- package/src/agents/context/index.ts +15 -0
- package/src/agents/context-model.ts +1 -1
- package/src/agents/context-resolution.ts +1 -1
- package/src/agents/index.ts +4 -4
- package/src/agents/message.ts +1 -1
- package/src/agents/model-loop.ts +8 -0
- package/src/agents/request.ts +11 -26
- package/src/agents/streams/index.ts +18 -0
- package/src/agents/streams/internal.ts +19 -0
- package/src/agents/{streams.ts → streams/protocol.ts} +5 -5
- package/src/agents/types.ts +1 -1
- package/src/agents/validation.ts +3 -7
- package/src/auth/index.ts +0 -1
- package/src/bootstrap/discovery.ts +81 -24
- package/src/bootstrap/index.ts +8 -1
- package/src/broker/in-memory.ts +104 -39
- package/src/broker/index.ts +4 -1
- package/src/broker/retention.ts +28 -0
- package/src/broker/subscriber.ts +21 -0
- package/src/broker/types.ts +15 -1
- package/src/connectors/builders.ts +0 -6
- package/src/connectors/connections/authorizations.ts +11 -5
- package/src/connectors/connections/contracts.ts +3 -0
- package/src/connectors/connections/request.ts +56 -22
- package/src/connectors/connections/runs.ts +1 -0
- package/src/connectors/connections/tokens.ts +4 -0
- package/src/connectors/connections/validation.ts +91 -5
- package/src/connectors/types.ts +19 -4
- package/src/errors/internal.ts +90 -10
- package/src/errors/redaction.ts +98 -0
- package/src/errors/types.ts +4 -0
- package/src/events/execution.ts +2 -2
- package/src/events/service.ts +3 -3
- package/src/execution/agent.ts +5 -3
- package/src/execution/durable.ts +11 -1
- package/src/execution/primitive.ts +5 -1
- package/src/execution/request.ts +3 -0
- package/src/index.ts +30 -20
- package/src/lake-storage/changes.ts +43 -0
- package/src/lake-storage/in-memory.ts +73 -0
- package/src/lake-storage/index.ts +4 -0
- package/src/lake-storage/types.ts +40 -0
- package/src/logging/index.ts +2 -33
- package/src/logging/internal.ts +43 -0
- package/src/logging/service.ts +1 -1
- package/src/materialization/index.ts +2 -0
- package/src/materialization/model.ts +14 -1
- package/src/materializer/index.ts +2 -0
- package/src/materializer/materializer.ts +10 -0
- package/src/materializer/projections/entry-validator.ts +19 -1
- package/src/materializer/projections/replace.ts +36 -1
- package/src/materializer/projections/source-materialization.ts +26 -6
- package/src/materializer/shared/normalize.ts +1 -1
- package/src/models/errors.ts +12 -0
- package/src/models/execution/binding.ts +29 -0
- package/src/models/execution/errors.ts +18 -0
- package/src/models/execution/index.ts +26 -0
- package/src/models/execution/model-call-accounting.ts +211 -0
- package/src/models/execution/model-call-admission.ts +127 -0
- package/src/models/execution/model-call-limits.ts +135 -0
- package/src/models/execution/model-call-recorder.ts +235 -0
- package/src/models/execution/model-call-recovery.ts +125 -0
- package/src/models/execution/recovery-queue.ts +31 -0
- package/src/models/execution/types.ts +58 -0
- package/src/models/execution/usage.ts +23 -0
- package/src/models/execution.ts +207 -0
- package/src/models/generation-types.ts +50 -0
- package/src/models/index.ts +8 -0
- package/src/models/language-model.ts +3 -0
- package/src/models/output.ts +45 -0
- package/src/models/resolve.ts +27 -0
- package/src/objects/execution.ts +1 -1
- package/src/ontology/index.ts +1 -2
- package/src/ontology/internal.ts +35 -0
- package/src/pipelines/run-dispatch.ts +21 -1
- package/src/projections/run-dispatch.ts +31 -68
- package/src/query.ts +0 -1
- package/src/queues/in-memory.ts +105 -62
- package/src/queues/index.ts +4 -2
- package/src/queues/indexed-heap.ts +74 -0
- package/src/queues/types.ts +6 -25
- package/src/runtime/create.ts +2 -1
- package/src/runtime/host.ts +2 -15
- package/src/runtime/ontology-mutations.ts +4 -0
- package/src/runtime/sixb.ts +4 -0
- package/src/sandboxes/errors.ts +5 -0
- package/src/sandboxes/index.ts +3 -0
- package/src/sandboxes/sandbox.ts +35 -7
- package/src/storage/agents/in-memory.ts +0 -3
- package/src/storage/agents/types.ts +0 -3
- package/src/storage/ai-cost/analytics.ts +1 -1
- package/src/storage/ai-cost/attribution.ts +15 -0
- package/src/storage/ai-cost/groups.ts +5 -1
- package/src/storage/ai-cost/provider.ts +1 -0
- package/src/storage/ai-cost/types.ts +7 -0
- package/src/storage/auth/in-memory.ts +1 -1
- package/src/storage/connector-connections/in-memory.ts +3 -1
- package/src/storage/connector-connections/provider/runs.ts +3 -1
- package/src/storage/connector-connections/types.ts +3 -2
- package/src/storage/executions/in-memory.ts +4 -9
- package/src/storage/executions/provider.ts +4 -0
- package/src/storage/executions/types.ts +6 -2
- package/src/storage/executions/validation.ts +32 -0
- package/src/storage/in-memory/index.ts +16 -1
- package/src/storage/index.ts +4 -29
- package/src/storage/internal.ts +20 -0
- package/src/storage/ontology/in-memory/materializations-state.ts +5 -18
- package/src/storage/ontology/in-memory/materializations.ts +73 -92
- package/src/storage/ontology/in-memory/shared-state.ts +26 -1
- package/src/storage/ontology/in-memory/source-roots.ts +123 -0
- package/src/storage/ontology/in-memory/sources.ts +78 -23
- package/src/storage/ontology/index.ts +1 -0
- package/src/storage/ontology/provider.ts +70 -0
- package/src/storage/ontology/sources.ts +14 -3
- package/src/storage/projection-runs/lifecycle.ts +5 -2
- package/src/storage/projection-runs/types.ts +4 -3
- package/src/storage/workflow-runs/in-memory.ts +0 -2
- package/src/storage/workflow-runs/types.ts +0 -3
- package/src/syncs/run-dispatch.ts +19 -1
- package/src/testing/action-execution.ts +9 -2
- package/src/testing/agent-execution.ts +3 -0
- package/src/testing/agent-storage-contract.ts +0 -5
- package/src/testing/ai-model-call-groups-contract.ts +74 -2
- package/src/testing/broker-contract.ts +95 -0
- package/src/testing/connector-connection-storage-contract.ts +18 -1
- package/src/testing/execution-storage-contract.ts +59 -1
- package/src/testing/execution.ts +6 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/lake-changes-contract.ts +240 -0
- package/src/testing/materializer-storage-contract.ts +172 -1
- package/src/testing/ontology-storage-contract.ts +7 -0
- package/src/testing/projection-run-storage-contract.ts +34 -0
- package/src/testing/workflow-execution.ts +4 -0
- package/src/webhooks/connections.ts +56 -0
- package/src/webhooks/index.ts +2 -0
- package/src/webhooks/internal.ts +2 -0
- package/src/webhooks/registry.ts +3 -4
- package/src/webhooks/types.ts +17 -4
- package/src/workflows/failure.ts +62 -1
- package/src/workflows/request.ts +0 -9
- package/src/workflows/run-dispatch.ts +42 -32
- package/src/workflows/types.ts +2 -0
- package/src/workflows/validation.ts +1 -1
- package/dist/agents/context.d.ts.map +0 -1
- package/dist/agents/context.js +0 -23
- package/dist/agents/streams.d.ts.map +0 -1
- package/dist/agents/streams.js +0 -55
- package/dist/chunk-08m3b6w8.js +0 -32
- package/dist/chunk-19jp6g9d.js.map +0 -11
- package/dist/chunk-2xns679x.js.map +0 -11
- package/dist/chunk-3xep5cjx.js.map +0 -15
- package/dist/chunk-407j3msh.js +0 -60
- package/dist/chunk-4qfkag59.js +0 -1568
- package/dist/chunk-4qfkag59.js.map +0 -20
- package/dist/chunk-5e3pq99w.js.map +0 -11
- package/dist/chunk-5gd7tpv6.js.map +0 -11
- package/dist/chunk-7y0f6rf1.js.map +0 -10
- package/dist/chunk-8m5ejdpn.js.map +0 -10
- package/dist/chunk-8tsf6dmc.js.map +0 -15
- package/dist/chunk-ajnan18g.js.map +0 -12
- package/dist/chunk-c15dr03f.js +0 -43
- package/dist/chunk-d8qkxt2v.js.map +0 -10
- package/dist/chunk-jq43kdvk.js +0 -50
- package/dist/chunk-k34z5rvh.js.map +0 -11
- package/dist/chunk-k522z7v6.js.map +0 -10
- package/dist/chunk-mth82m8t.js.map +0 -14
- package/dist/chunk-mwsxn98e.js.map +0 -36
- package/dist/chunk-p03r0h5s.js.map +0 -16
- package/dist/chunk-p1rzczbt.js +0 -218
- package/dist/chunk-rafagrwr.js.map +0 -11
- package/dist/chunk-rv2hkwwa.js.map +0 -14
- package/dist/chunk-sbzzr4kx.js.map +0 -63
- package/dist/chunk-tpnd31c1.js +0 -242
- package/dist/chunk-tpnd31c1.js.map +0 -11
- package/dist/chunk-w9tg6yyb.js.map +0 -12
- package/dist/chunk-wtf06et8.js.map +0 -14
- package/dist/chunk-xajtptbw.js.map +0 -40
- package/dist/chunk-xhy826cz.js.map +0 -10
- package/dist/chunk-y64skrwp.js +0 -19
- package/dist/chunk-zcnhxkvd.js +0 -7
- package/dist/logging/types.js +0 -27
- package/dist/logging/types.js.map +0 -9
- /package/dist/{chunk-zqqz8052.js → chunk-7n30ybym.js} +0 -0
- /package/dist/{chunk-zqqz8052.js.map → chunk-7n30ybym.js.map} +0 -0
- /package/dist/{chunk-4a849fr1.js.map → chunk-9tc8dxmn.js.map} +0 -0
- /package/dist/{chunk-j1sbhm7p.js → chunk-ey1nk510.js} +0 -0
- /package/dist/{chunk-j1sbhm7p.js.map → chunk-ey1nk510.js.map} +0 -0
- /package/dist/{chunk-z4ccwbkz.js.map → chunk-x9v4cx1d.js.map} +0 -0
|
@@ -1,75 +1,75 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
normalizeObjectRef2,
|
|
4
|
+
normalizeLinkRef2,
|
|
5
|
+
objectRefKey2,
|
|
6
|
+
linkRefKey2,
|
|
7
|
+
projectionEntityKey2,
|
|
8
|
+
linkOwnershipKey,
|
|
9
|
+
telemetryOwnershipKey,
|
|
10
|
+
telemetryPointKey2,
|
|
11
|
+
utf8JsonByteLength,
|
|
12
|
+
objectRefSortKey2,
|
|
13
|
+
linkRefSortKey2,
|
|
14
|
+
linkScopeKey,
|
|
15
|
+
linkScopeSortKey2,
|
|
16
|
+
telemetryPointSortKey2,
|
|
17
|
+
compareObjectRefs2,
|
|
18
|
+
compareLinkRefs2
|
|
19
|
+
} from "./chunk-c5rkjrgp.js";
|
|
5
20
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
21
|
+
normalizeObjectProperties2,
|
|
22
|
+
normalizeSchemaValue2,
|
|
23
|
+
assertKnownProperties2,
|
|
24
|
+
validateObjectProperties2,
|
|
25
|
+
validatePropertyValue2,
|
|
26
|
+
normalizeLinkProperties2,
|
|
27
|
+
validateLinkProperties2,
|
|
28
|
+
validateTelemetryUnit2
|
|
29
|
+
} from "./chunk-ms2tmn1k.js";
|
|
9
30
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
31
|
+
materializationEventKindOrdinal2,
|
|
32
|
+
sha256Canonical2,
|
|
33
|
+
createRequestHash2,
|
|
34
|
+
createCommitId2,
|
|
35
|
+
createEventId2,
|
|
36
|
+
materializationApplyPhase
|
|
37
|
+
} from "./chunk-gqh45d2n.js";
|
|
12
38
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
sha256Canonical
|
|
19
|
-
} from "./chunk-8tsf6dmc.js";
|
|
39
|
+
ProjectionValidationError2,
|
|
40
|
+
validateProjectionsAtStartup,
|
|
41
|
+
isProjectionDefinition2,
|
|
42
|
+
resolveExecutionScopeAuthorization
|
|
43
|
+
} from "./chunk-dz5h08xv.js";
|
|
20
44
|
import {
|
|
21
|
-
|
|
22
|
-
} from "./chunk-
|
|
45
|
+
isStorageSerializationFailure2
|
|
46
|
+
} from "./chunk-8vj0rjgs.js";
|
|
23
47
|
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
linkOwnershipKey,
|
|
27
|
-
linkRefKey,
|
|
28
|
-
linkRefSortKey,
|
|
29
|
-
linkScopeKey,
|
|
30
|
-
linkScopeSortKey,
|
|
31
|
-
normalizeLinkRef,
|
|
32
|
-
normalizeObjectRef,
|
|
33
|
-
objectRefKey,
|
|
34
|
-
objectRefSortKey,
|
|
35
|
-
projectionEntityKey,
|
|
36
|
-
telemetryOwnershipKey,
|
|
37
|
-
telemetryPointKey,
|
|
38
|
-
telemetryPointSortKey,
|
|
39
|
-
utf8JsonByteLength
|
|
40
|
-
} from "./chunk-dbc80ad7.js";
|
|
48
|
+
parseDatasetTimestamp2
|
|
49
|
+
} from "./chunk-z667z3sg.js";
|
|
41
50
|
import {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
MaterializationValidationError
|
|
46
|
-
} from "./chunk-ry24jbr1.js";
|
|
51
|
+
executionRecordInputFromRuntime,
|
|
52
|
+
ensureExecutionRecord2
|
|
53
|
+
} from "./chunk-17kfctj6.js";
|
|
47
54
|
import {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
resolveExecutionScopeAuthorization,
|
|
51
|
-
validateProjectionsAtStartup
|
|
52
|
-
} from "./chunk-p1x242ad.js";
|
|
55
|
+
assertPinnedDatasetWatermark2
|
|
56
|
+
} from "./chunk-wjasrj67.js";
|
|
53
57
|
import {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
validateObjectProperties,
|
|
60
|
-
validatePropertyValue,
|
|
61
|
-
validateTelemetryUnit
|
|
62
|
-
} from "./chunk-h0k55pc7.js";
|
|
58
|
+
MaterializationValidationError2,
|
|
59
|
+
MaterializationObjectNotFoundError2,
|
|
60
|
+
MaterializationCancellationError2,
|
|
61
|
+
MaterializationConflictError2
|
|
62
|
+
} from "./chunk-yv79ncbv.js";
|
|
63
63
|
import {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
} from "./chunk-
|
|
64
|
+
assertJsonValue2,
|
|
65
|
+
cloneJsonValue2,
|
|
66
|
+
stableJsonStringify2,
|
|
67
|
+
compareStrings
|
|
68
|
+
} from "./chunk-wy0qdqfm.js";
|
|
69
69
|
// src/projections/revision.ts
|
|
70
|
-
function
|
|
70
|
+
function computeOntologyRevision2(ontology) {
|
|
71
71
|
const referencedValueTypeIds = collectOntologyValueTypeDependencies(ontology);
|
|
72
|
-
return
|
|
72
|
+
return sha256Canonical2({
|
|
73
73
|
objectTypes: normalizeOntologyObjectTypes(ontology),
|
|
74
74
|
valueTypes: normalizeOntologyValueTypes(ontology, referencedValueTypeIds)
|
|
75
75
|
});
|
|
@@ -143,20 +143,20 @@ function collectReferencedValueTypeIds(schema, valueTypeIds) {
|
|
|
143
143
|
collectReferencedValueTypeIds(field.schema, valueTypeIds);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
|
-
function
|
|
146
|
+
function computeProjectionRevision2(projection, dataset) {
|
|
147
147
|
const referencedColumns = projectionColumns(projection);
|
|
148
148
|
const columns = dataset.schema.columns.filter((column) => referencedColumns.has(column.name)).map((column) => ({
|
|
149
149
|
name: column.name,
|
|
150
150
|
type: column.type,
|
|
151
151
|
nullable: column.nullable ?? false
|
|
152
152
|
})).sort((left, right) => compareStrings(left.name, right.name));
|
|
153
|
-
return
|
|
153
|
+
return sha256Canonical2({
|
|
154
154
|
mapping: normalizeProjectionDefinition(projection),
|
|
155
155
|
columns
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
|
-
function
|
|
159
|
-
return
|
|
158
|
+
function computeProjectionOwnershipHash2(ownership) {
|
|
159
|
+
return sha256Canonical2(ownership);
|
|
160
160
|
}
|
|
161
161
|
function normalizeProjectionDefinition(projection) {
|
|
162
162
|
if (projection._tag === "ObjectProjectionDefinition") {
|
|
@@ -282,7 +282,7 @@ function normalizeField(field) {
|
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
// src/projections/registry.ts
|
|
285
|
-
class
|
|
285
|
+
class ProjectionRegistry2 {
|
|
286
286
|
ontologyRevision;
|
|
287
287
|
objectProjections;
|
|
288
288
|
linkProjections;
|
|
@@ -297,8 +297,8 @@ class ProjectionRegistry {
|
|
|
297
297
|
const linkProjections = [];
|
|
298
298
|
const telemetryProjections = [];
|
|
299
299
|
for (const projection of input.projections) {
|
|
300
|
-
if (!
|
|
301
|
-
throw new
|
|
300
|
+
if (!isProjectionDefinition2(projection)) {
|
|
301
|
+
throw new ProjectionValidationError2("[Sixb] Invalid projection definition.");
|
|
302
302
|
}
|
|
303
303
|
switch (projection._tag) {
|
|
304
304
|
case "ObjectProjectionDefinition":
|
|
@@ -326,7 +326,7 @@ class ProjectionRegistry {
|
|
|
326
326
|
linkProjections: this.linkProjections,
|
|
327
327
|
telemetryProjections: this.telemetryProjections
|
|
328
328
|
}, input.ontology, input.datasetsById);
|
|
329
|
-
this.ontologyRevision =
|
|
329
|
+
this.ontologyRevision = computeOntologyRevision2(input.ontology);
|
|
330
330
|
const dispatchDescriptors = [];
|
|
331
331
|
for (const record of validated.objectProjections) {
|
|
332
332
|
const resolved = createResolvedProjection(record);
|
|
@@ -373,15 +373,15 @@ class ProjectionRegistry {
|
|
|
373
373
|
const descriptor = this.dispatchById.get(projectionId);
|
|
374
374
|
if (descriptor)
|
|
375
375
|
return descriptor;
|
|
376
|
-
throw new
|
|
376
|
+
throw new ProjectionValidationError2(`[Sixb] Unknown projection '${projectionId}'.`);
|
|
377
377
|
}
|
|
378
378
|
resolveSource(projectionId) {
|
|
379
379
|
const resolved = this.sourceById.get(projectionId);
|
|
380
380
|
if (!resolved) {
|
|
381
381
|
if (this.telemetryById.has(projectionId)) {
|
|
382
|
-
throw new
|
|
382
|
+
throw new ProjectionValidationError2(`[Sixb] Projection '${projectionId}' is telemetry-only and cannot replace source state.`);
|
|
383
383
|
}
|
|
384
|
-
throw new
|
|
384
|
+
throw new ProjectionValidationError2(`[Sixb] Unknown source projection '${projectionId}'.`);
|
|
385
385
|
}
|
|
386
386
|
return resolved;
|
|
387
387
|
}
|
|
@@ -389,9 +389,9 @@ class ProjectionRegistry {
|
|
|
389
389
|
const resolved = this.telemetryById.get(projectionId);
|
|
390
390
|
if (!resolved) {
|
|
391
391
|
if (this.sourceById.has(projectionId)) {
|
|
392
|
-
throw new
|
|
392
|
+
throw new ProjectionValidationError2(`[Sixb] Projection '${projectionId}' does not own a telemetry source.`);
|
|
393
393
|
}
|
|
394
|
-
throw new
|
|
394
|
+
throw new ProjectionValidationError2(`[Sixb] Unknown telemetry projection '${projectionId}'.`);
|
|
395
395
|
}
|
|
396
396
|
return resolved;
|
|
397
397
|
}
|
|
@@ -417,7 +417,7 @@ function assertUniqueProjectionIds(projections) {
|
|
|
417
417
|
const ids = new Set;
|
|
418
418
|
for (const projection of projections) {
|
|
419
419
|
if (ids.has(projection.id)) {
|
|
420
|
-
throw new
|
|
420
|
+
throw new ProjectionValidationError2(`[Sixb] Duplicate projection id: ${projection.id}`);
|
|
421
421
|
}
|
|
422
422
|
ids.add(projection.id);
|
|
423
423
|
}
|
|
@@ -427,8 +427,8 @@ function createResolvedProjection(validated) {
|
|
|
427
427
|
return deepFreeze({
|
|
428
428
|
projectionId: definition.id,
|
|
429
429
|
datasetId: definition.datasetId,
|
|
430
|
-
projectionRevision:
|
|
431
|
-
ownershipHash:
|
|
430
|
+
projectionRevision: computeProjectionRevision2(definition, dataset),
|
|
431
|
+
ownershipHash: computeProjectionOwnershipHash2(ownership),
|
|
432
432
|
ownership,
|
|
433
433
|
definition
|
|
434
434
|
});
|
|
@@ -504,7 +504,7 @@ function resolveMaterializationBatching(overrides = {}) {
|
|
|
504
504
|
const resolved = { ...DEFAULT_MATERIALIZATION_BATCHING, ...overrides };
|
|
505
505
|
for (const [name, value] of Object.entries(resolved)) {
|
|
506
506
|
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
507
|
-
throw new
|
|
507
|
+
throw new MaterializationValidationError2(`Materialization batching '${name}' must be a positive safe integer.`);
|
|
508
508
|
}
|
|
509
509
|
}
|
|
510
510
|
return Object.freeze(resolved);
|
|
@@ -512,10 +512,10 @@ function resolveMaterializationBatching(overrides = {}) {
|
|
|
512
512
|
|
|
513
513
|
// src/materializer/shared/identity.ts
|
|
514
514
|
import { randomUUID } from "crypto";
|
|
515
|
-
function
|
|
515
|
+
function createActionIdempotencyKey2(runId) {
|
|
516
516
|
return `action:${runId}:edits`;
|
|
517
517
|
}
|
|
518
|
-
function
|
|
518
|
+
function createRuntimeIdempotencyKey2(requestId) {
|
|
519
519
|
return `runtime:${requestId}`;
|
|
520
520
|
}
|
|
521
521
|
function projectionIdentityTuple(input) {
|
|
@@ -531,47 +531,47 @@ function projectionIdentityTuple(input) {
|
|
|
531
531
|
input.ownershipHash
|
|
532
532
|
];
|
|
533
533
|
}
|
|
534
|
-
function
|
|
535
|
-
return `projection:replace:${
|
|
534
|
+
function createProjectionIdempotencyKey2(identity) {
|
|
535
|
+
return `projection:replace:${sha256Canonical2(projectionIdentityTuple(identity))}`;
|
|
536
536
|
}
|
|
537
|
-
function
|
|
537
|
+
function createRuntimeTelemetryIdempotencyKey2(requestId) {
|
|
538
538
|
return `telemetry:runtime:${requestId}`;
|
|
539
539
|
}
|
|
540
|
-
function
|
|
541
|
-
return `telemetry:projection:${
|
|
540
|
+
function createProjectionTelemetryIdempotencyKey2(identity, batchOrdinal) {
|
|
541
|
+
return `telemetry:projection:${sha256Canonical2([
|
|
542
542
|
...projectionIdentityTuple(identity),
|
|
543
543
|
batchOrdinal
|
|
544
544
|
])}`;
|
|
545
545
|
}
|
|
546
|
-
function
|
|
546
|
+
function createCommitIdentity2(input) {
|
|
547
547
|
return Object.freeze({
|
|
548
548
|
idempotencyKey: input.idempotencyKey,
|
|
549
|
-
requestHash:
|
|
550
|
-
commitId:
|
|
549
|
+
requestHash: createRequestHash2(input.normalizedCallerIntent),
|
|
550
|
+
commitId: createCommitId2(input.projectId, input.idempotencyKey)
|
|
551
551
|
});
|
|
552
552
|
}
|
|
553
|
-
function
|
|
553
|
+
function timestampCommitIdentity2(identity, now = new Date) {
|
|
554
554
|
const committedAt = new Date(now);
|
|
555
555
|
if (Number.isNaN(committedAt.getTime())) {
|
|
556
|
-
throw new
|
|
556
|
+
throw new MaterializationValidationError2("Materialization commit time must be a valid date.");
|
|
557
557
|
}
|
|
558
558
|
return Object.freeze({
|
|
559
559
|
...identity,
|
|
560
560
|
committedAt: committedAt.toISOString()
|
|
561
561
|
});
|
|
562
562
|
}
|
|
563
|
-
function
|
|
564
|
-
return
|
|
563
|
+
function createTimedCommitIdentity2(input) {
|
|
564
|
+
return timestampCommitIdentity2(createCommitIdentity2({
|
|
565
565
|
projectId: input.projectId,
|
|
566
566
|
idempotencyKey: input.idempotencyKey,
|
|
567
567
|
normalizedCallerIntent: input.normalizedCallerIntent
|
|
568
568
|
}), input.now);
|
|
569
569
|
}
|
|
570
|
-
function
|
|
570
|
+
function createProjectionMaterializationId2() {
|
|
571
571
|
return randomUUID();
|
|
572
572
|
}
|
|
573
|
-
function
|
|
574
|
-
return
|
|
573
|
+
function createLinkScopeFingerprint2(links) {
|
|
574
|
+
return sha256Canonical2([...links].sort((left, right) => compareLinkRefs2(left.ref, right.ref)).map((link) => ({
|
|
575
575
|
ref: link.ref,
|
|
576
576
|
properties: link.properties ?? {},
|
|
577
577
|
lastCommitId: link.lastCommitId
|
|
@@ -581,18 +581,18 @@ function createLinkScopeFingerprint(links) {
|
|
|
581
581
|
// src/materializer/context.ts
|
|
582
582
|
function createMaterializerContext(input) {
|
|
583
583
|
if (input.projectId.trim().length === 0) {
|
|
584
|
-
throw new
|
|
584
|
+
throw new MaterializationValidationError2("Materializer project id must be nonblank.");
|
|
585
585
|
}
|
|
586
586
|
if (!input.storage?.ontology) {
|
|
587
|
-
throw new
|
|
587
|
+
throw new MaterializationValidationError2("Storage does not provide ontology capabilities.");
|
|
588
588
|
}
|
|
589
|
-
if (
|
|
590
|
-
throw new
|
|
589
|
+
if (computeOntologyRevision2(input.ontology) !== input.projections.ontologyRevision) {
|
|
590
|
+
throw new MaterializationValidationError2("Materializer Ontology does not match the Ontology pinned by its projection registry.");
|
|
591
591
|
}
|
|
592
592
|
const dependencies = input.dependencies ?? {};
|
|
593
593
|
const maxSerializationRetries = dependencies.maxSerializationRetries ?? 2;
|
|
594
594
|
if (!Number.isSafeInteger(maxSerializationRetries) || maxSerializationRetries < 0) {
|
|
595
|
-
throw new
|
|
595
|
+
throw new MaterializationValidationError2("Materializer serialization retry count must be a nonnegative safe integer.");
|
|
596
596
|
}
|
|
597
597
|
return {
|
|
598
598
|
projectId: input.projectId,
|
|
@@ -601,7 +601,7 @@ function createMaterializerContext(input) {
|
|
|
601
601
|
storage: input.storage,
|
|
602
602
|
batching: resolveMaterializationBatching(dependencies.batching),
|
|
603
603
|
clock: dependencies.clock ?? (() => new Date),
|
|
604
|
-
materializationId: dependencies.materializationId ??
|
|
604
|
+
materializationId: dependencies.materializationId ?? createProjectionMaterializationId2,
|
|
605
605
|
maxSerializationRetries,
|
|
606
606
|
...dependencies.onSerializationRetry !== undefined ? { onSerializationRetry: dependencies.onSerializationRetry } : {},
|
|
607
607
|
...dependencies.observeCoreBuffer !== undefined ? { observeCoreBuffer: dependencies.observeCoreBuffer } : {}
|
|
@@ -617,10 +617,10 @@ async function replayCommitRecord(context, identity, executionId, storage = cont
|
|
|
617
617
|
if (!existing)
|
|
618
618
|
return null;
|
|
619
619
|
if (existing.requestHash !== identity.requestHash) {
|
|
620
|
-
throw new
|
|
620
|
+
throw new MaterializationConflictError2("idempotency", `Idempotency key '${identity.idempotencyKey}' was reused with different intent.`);
|
|
621
621
|
}
|
|
622
622
|
if (existing.executionId !== executionId) {
|
|
623
|
-
throw new
|
|
623
|
+
throw new MaterializationConflictError2("idempotency", `Idempotency key '${identity.idempotencyKey}' belongs to execution '${existing.executionId}', not '${executionId}'.`);
|
|
624
624
|
}
|
|
625
625
|
return existing;
|
|
626
626
|
}
|
|
@@ -635,7 +635,7 @@ async function withSerializationRetry(context, run) {
|
|
|
635
635
|
try {
|
|
636
636
|
return await run();
|
|
637
637
|
} catch (error) {
|
|
638
|
-
if (!
|
|
638
|
+
if (!isStorageSerializationFailure2(error) || attempt >= context.maxSerializationRetries) {
|
|
639
639
|
throw error;
|
|
640
640
|
}
|
|
641
641
|
context.onSerializationRetry?.(attempt + 1, error);
|
|
@@ -660,30 +660,30 @@ function prepareMaterializerExecution(projectId, scope) {
|
|
|
660
660
|
return { ...base, actor: authorization.context.principal };
|
|
661
661
|
}
|
|
662
662
|
function ensureMaterializerExecution(executions, execution) {
|
|
663
|
-
return
|
|
663
|
+
return ensureExecutionRecord2(executions, execution.record);
|
|
664
664
|
}
|
|
665
665
|
function assertRuntimeMutationExecution(execution) {
|
|
666
666
|
if (execution.scope.execution.executor.type !== "kernel")
|
|
667
667
|
return;
|
|
668
|
-
throw new
|
|
668
|
+
throw new MaterializationValidationError2(`Kernel execution '${execution.executionId}' cannot enter the runtime mutation boundary.`);
|
|
669
669
|
}
|
|
670
670
|
function assertTrustedPrimitiveMutationExecution(execution, primitive) {
|
|
671
671
|
const executor = execution.scope.execution.executor;
|
|
672
672
|
if (executor.type === "primitive" && executor.kind === primitive.kind && executor.id === primitive.id && executor.runId === primitive.runId) {
|
|
673
673
|
return;
|
|
674
674
|
}
|
|
675
|
-
throw new
|
|
675
|
+
throw new MaterializationConflictError2("run-correlation", `Execution '${execution.executionId}' does not own ${primitive.kind} run '${primitive.runId}'.`);
|
|
676
676
|
}
|
|
677
677
|
function assertMaterializerRunExecution(execution, runExecutionId, label) {
|
|
678
678
|
if (runExecutionId === execution.executionId)
|
|
679
679
|
return;
|
|
680
|
-
throw new
|
|
680
|
+
throw new MaterializationConflictError2("run-correlation", `${label} belongs to execution '${runExecutionId}', not '${execution.executionId}'.`);
|
|
681
681
|
}
|
|
682
682
|
|
|
683
683
|
// src/materializer/effective/build-events.ts
|
|
684
684
|
function buildObjectMaterializationEventDraft(input) {
|
|
685
685
|
const draft = buildObjectEventDraft(input, input.change);
|
|
686
|
-
return orderedDraft(
|
|
686
|
+
return orderedDraft(objectRefSortKey2(input.change.ref), draft);
|
|
687
687
|
}
|
|
688
688
|
function buildObjectEventDraft(context, change) {
|
|
689
689
|
const base = eventDraftBase(context);
|
|
@@ -722,7 +722,7 @@ function objectEventType(change) {
|
|
|
722
722
|
}
|
|
723
723
|
function buildLinkMaterializationEventDraft(input) {
|
|
724
724
|
const draft = buildLinkEventDraft(input, input.change);
|
|
725
|
-
return orderedDraft(
|
|
725
|
+
return orderedDraft(linkRefSortKey2(input.change.ref), draft);
|
|
726
726
|
}
|
|
727
727
|
function buildLinkEventDraft(context, change) {
|
|
728
728
|
const base = eventDraftBase(context);
|
|
@@ -763,7 +763,7 @@ function linkEventType(change) {
|
|
|
763
763
|
}
|
|
764
764
|
function buildTelemetryMaterializationEventDraft(input) {
|
|
765
765
|
const draft = buildTelemetryEventDraft(input, input.point);
|
|
766
|
-
return orderedDraft(
|
|
766
|
+
return orderedDraft(telemetryPointSortKey2(input.point.series, input.point.at), draft);
|
|
767
767
|
}
|
|
768
768
|
function buildTelemetryEventDraft(context, point) {
|
|
769
769
|
const base = eventDraftBase(context);
|
|
@@ -801,14 +801,14 @@ function eventDraftBase(context) {
|
|
|
801
801
|
}
|
|
802
802
|
function orderedDraft(sortKey, draft) {
|
|
803
803
|
return {
|
|
804
|
-
kindRank:
|
|
804
|
+
kindRank: materializationEventKindOrdinal2(draft.type),
|
|
805
805
|
sortKey,
|
|
806
806
|
draft
|
|
807
807
|
};
|
|
808
808
|
}
|
|
809
809
|
function sequenceMaterializationEvent(projectId, commitId, commitOrdinal, draft) {
|
|
810
810
|
const sequence = {
|
|
811
|
-
id:
|
|
811
|
+
id: createEventId2(projectId, commitId, commitOrdinal),
|
|
812
812
|
commitOrdinal
|
|
813
813
|
};
|
|
814
814
|
return { ...draft, ...sequence };
|
|
@@ -914,7 +914,7 @@ function appendItem(chunk, item) {
|
|
|
914
914
|
|
|
915
915
|
// src/materializer/execution/work-records.ts
|
|
916
916
|
function appendObjectOverrideWork(items, working, identity) {
|
|
917
|
-
if (
|
|
917
|
+
if (stableJsonStringify2(working.originalOverride?.value ?? null) === stableJsonStringify2(working.override) && stableJsonStringify2(working.originalEditedAt) === stableJsonStringify2(working.editedAt)) {
|
|
918
918
|
return;
|
|
919
919
|
}
|
|
920
920
|
if (working.override) {
|
|
@@ -937,7 +937,7 @@ function appendObjectOverrideWork(items, working, identity) {
|
|
|
937
937
|
}
|
|
938
938
|
}
|
|
939
939
|
function appendLinkEdgeOverrideWork(items, working, identity) {
|
|
940
|
-
if (
|
|
940
|
+
if (stableJsonStringify2(working.originalOverride?.value ?? null) === stableJsonStringify2(working.override)) {
|
|
941
941
|
return;
|
|
942
942
|
}
|
|
943
943
|
if (working.override) {
|
|
@@ -959,7 +959,7 @@ function appendLinkEdgeOverrideWork(items, working, identity) {
|
|
|
959
959
|
}
|
|
960
960
|
}
|
|
961
961
|
function appendLinkSlotOverrideWork(items, working, identity) {
|
|
962
|
-
if (
|
|
962
|
+
if (stableJsonStringify2(working.originalOverride?.value ?? null) === stableJsonStringify2(working.override)) {
|
|
963
963
|
return;
|
|
964
964
|
}
|
|
965
965
|
if (working.override) {
|
|
@@ -1100,7 +1100,7 @@ async function drainStagedWork(context, storage, session, signal) {
|
|
|
1100
1100
|
})) {
|
|
1101
1101
|
for (const record of page.records) {
|
|
1102
1102
|
if (record.kind !== "plan") {
|
|
1103
|
-
throw new
|
|
1103
|
+
throw new MaterializationValidationError2("Provider returned non-plan apply work.");
|
|
1104
1104
|
}
|
|
1105
1105
|
if (phase !== null && record.applyPhase !== phase)
|
|
1106
1106
|
await flush();
|
|
@@ -1124,7 +1124,7 @@ async function validateStagedCardinality(context, storage, session, signal) {
|
|
|
1124
1124
|
throwIfAborted(signal);
|
|
1125
1125
|
for (const record of page.records) {
|
|
1126
1126
|
if (record.kind !== "cardinality") {
|
|
1127
|
-
throw new
|
|
1127
|
+
throw new MaterializationValidationError2("Provider returned non-cardinality cardinality work.");
|
|
1128
1128
|
}
|
|
1129
1129
|
if (record.view !== currentView || record.scopeSortKey !== currentScope) {
|
|
1130
1130
|
currentView = record.view;
|
|
@@ -1134,7 +1134,7 @@ async function validateStagedCardinality(context, storage, session, signal) {
|
|
|
1134
1134
|
if (!record.occupied)
|
|
1135
1135
|
continue;
|
|
1136
1136
|
if (occupant && occupant !== record.linkSortKey) {
|
|
1137
|
-
throw new
|
|
1137
|
+
throw new MaterializationValidationError2(record.view === "candidate" ? `Projection source scope '${record.ref.source.objectTypeId}.${record.ref.linkId}' has cardinality one.` : `Link scope '${record.ref.source.objectTypeId}.${record.ref.linkId}' has cardinality one.`);
|
|
1138
1138
|
}
|
|
1139
1139
|
occupant = record.linkSortKey;
|
|
1140
1140
|
}
|
|
@@ -1150,7 +1150,7 @@ async function drainStagedEvents(context, storage, session, identity, signal) {
|
|
|
1150
1150
|
const items = [];
|
|
1151
1151
|
for (const record of page.records) {
|
|
1152
1152
|
if (record.kind !== "event") {
|
|
1153
|
-
throw new
|
|
1153
|
+
throw new MaterializationValidationError2("Provider returned non-event event work.");
|
|
1154
1154
|
}
|
|
1155
1155
|
const event = sequenceMaterializationEvent(context.projectId, identity.commitId, ordinal++, record.draft);
|
|
1156
1156
|
items.push(outboxItem(event, identity.committedAt));
|
|
@@ -1161,42 +1161,42 @@ async function drainStagedEvents(context, storage, session, identity, signal) {
|
|
|
1161
1161
|
}
|
|
1162
1162
|
|
|
1163
1163
|
// src/materializer/shared/normalize.ts
|
|
1164
|
-
function
|
|
1164
|
+
function normalizeJsonProperties2(properties, label = "Properties") {
|
|
1165
1165
|
if (typeof properties !== "object" || properties === null || Array.isArray(properties)) {
|
|
1166
|
-
throw new
|
|
1166
|
+
throw new MaterializationValidationError2(`${label} must be a JSON object.`);
|
|
1167
1167
|
}
|
|
1168
1168
|
const normalized = {};
|
|
1169
1169
|
for (const propertyId of Object.keys(properties).sort(compareStrings)) {
|
|
1170
1170
|
if (propertyId.trim().length === 0) {
|
|
1171
|
-
throw new
|
|
1171
|
+
throw new MaterializationValidationError2(`${label} contains a blank property id.`);
|
|
1172
1172
|
}
|
|
1173
1173
|
const value = properties[propertyId];
|
|
1174
1174
|
try {
|
|
1175
|
-
|
|
1175
|
+
assertJsonValue2(value, `${label}.${propertyId}`);
|
|
1176
1176
|
} catch (error) {
|
|
1177
|
-
throw new
|
|
1177
|
+
throw new MaterializationValidationError2(error instanceof Error ? error.message : `${label}.${propertyId} must be JSON.`);
|
|
1178
1178
|
}
|
|
1179
|
-
normalized[propertyId] =
|
|
1179
|
+
normalized[propertyId] = cloneJsonValue2(value);
|
|
1180
1180
|
}
|
|
1181
1181
|
return Object.freeze(normalized);
|
|
1182
1182
|
}
|
|
1183
1183
|
function normalizeNonblank(value, label) {
|
|
1184
1184
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
1185
|
-
throw new
|
|
1185
|
+
throw new MaterializationValidationError2(`${label} must be a nonblank string.`);
|
|
1186
1186
|
}
|
|
1187
1187
|
return value;
|
|
1188
1188
|
}
|
|
1189
1189
|
function normalizeTimestamp(value, label) {
|
|
1190
1190
|
const milliseconds = Date.parse(value);
|
|
1191
1191
|
if (!Number.isFinite(milliseconds)) {
|
|
1192
|
-
throw new
|
|
1192
|
+
throw new MaterializationValidationError2(`${label} must be a valid timestamp.`);
|
|
1193
1193
|
}
|
|
1194
1194
|
return new Date(milliseconds).toISOString();
|
|
1195
1195
|
}
|
|
1196
1196
|
function normalizeProjectionSourceTimestamp(value) {
|
|
1197
|
-
const timestamp =
|
|
1197
|
+
const timestamp = parseDatasetTimestamp2(value);
|
|
1198
1198
|
if (!timestamp) {
|
|
1199
|
-
throw new
|
|
1199
|
+
throw new MaterializationValidationError2("Projection source update timestamp must be a valid timestamp.");
|
|
1200
1200
|
}
|
|
1201
1201
|
return timestamp.toISOString();
|
|
1202
1202
|
}
|
|
@@ -1206,7 +1206,7 @@ function normalizePropertyIds(values, label) {
|
|
|
1206
1206
|
for (const value of values) {
|
|
1207
1207
|
normalizeNonblank(value, label);
|
|
1208
1208
|
if (seen.has(value)) {
|
|
1209
|
-
throw new
|
|
1209
|
+
throw new MaterializationValidationError2(`${label} contains duplicate '${value}'.`);
|
|
1210
1210
|
}
|
|
1211
1211
|
seen.add(value);
|
|
1212
1212
|
normalized.push(value);
|
|
@@ -1219,29 +1219,29 @@ function normalizeOperation(operation) {
|
|
|
1219
1219
|
return Object.freeze({
|
|
1220
1220
|
id: operation.id,
|
|
1221
1221
|
kind: operation.kind,
|
|
1222
|
-
ref:
|
|
1223
|
-
properties:
|
|
1222
|
+
ref: normalizeObjectRef2(operation.ref),
|
|
1223
|
+
properties: normalizeJsonProperties2(operation.properties)
|
|
1224
1224
|
});
|
|
1225
1225
|
}
|
|
1226
1226
|
if (operation.kind === "object.patch") {
|
|
1227
|
-
const set =
|
|
1227
|
+
const set = normalizeJsonProperties2(operation.set, `Operation '${operation.id}' set`);
|
|
1228
1228
|
const unset = normalizePropertyIds(operation.unset, `Operation '${operation.id}' unset`);
|
|
1229
1229
|
const reset = normalizePropertyIds(operation.reset, `Operation '${operation.id}' reset`);
|
|
1230
1230
|
const setIds = new Set(Object.keys(set));
|
|
1231
1231
|
for (const propertyId of [...unset, ...reset]) {
|
|
1232
1232
|
if (setIds.has(propertyId)) {
|
|
1233
|
-
throw new
|
|
1233
|
+
throw new MaterializationValidationError2(`Operation '${operation.id}' property '${propertyId}' appears in set and unset/reset.`);
|
|
1234
1234
|
}
|
|
1235
1235
|
}
|
|
1236
1236
|
for (const propertyId of unset) {
|
|
1237
1237
|
if (reset.includes(propertyId)) {
|
|
1238
|
-
throw new
|
|
1238
|
+
throw new MaterializationValidationError2(`Operation '${operation.id}' property '${propertyId}' appears in unset and reset.`);
|
|
1239
1239
|
}
|
|
1240
1240
|
}
|
|
1241
1241
|
return Object.freeze({
|
|
1242
1242
|
id: operation.id,
|
|
1243
1243
|
kind: operation.kind,
|
|
1244
|
-
ref:
|
|
1244
|
+
ref: normalizeObjectRef2(operation.ref),
|
|
1245
1245
|
set,
|
|
1246
1246
|
unset,
|
|
1247
1247
|
reset
|
|
@@ -1251,44 +1251,44 @@ function normalizeOperation(operation) {
|
|
|
1251
1251
|
return Object.freeze({
|
|
1252
1252
|
id: operation.id,
|
|
1253
1253
|
kind: operation.kind,
|
|
1254
|
-
ref:
|
|
1254
|
+
ref: normalizeObjectRef2(operation.ref)
|
|
1255
1255
|
});
|
|
1256
1256
|
}
|
|
1257
1257
|
if (operation.kind === "link.upsert") {
|
|
1258
1258
|
return Object.freeze({
|
|
1259
1259
|
id: operation.id,
|
|
1260
1260
|
kind: operation.kind,
|
|
1261
|
-
ref:
|
|
1262
|
-
...operation.properties !== undefined ? { properties:
|
|
1261
|
+
ref: normalizeLinkRef2(operation.ref),
|
|
1262
|
+
...operation.properties !== undefined ? { properties: normalizeJsonProperties2(operation.properties) } : {}
|
|
1263
1263
|
});
|
|
1264
1264
|
}
|
|
1265
1265
|
if (operation.kind === "link.delete" || operation.kind === "link.reset") {
|
|
1266
1266
|
return Object.freeze({
|
|
1267
1267
|
id: operation.id,
|
|
1268
1268
|
kind: operation.kind,
|
|
1269
|
-
ref:
|
|
1269
|
+
ref: normalizeLinkRef2(operation.ref)
|
|
1270
1270
|
});
|
|
1271
1271
|
}
|
|
1272
|
-
throw new
|
|
1272
|
+
throw new MaterializationValidationError2("Unknown ontology edit operation kind.");
|
|
1273
1273
|
}
|
|
1274
1274
|
function deduplicateExpectations(values, keyOf, label) {
|
|
1275
1275
|
const byKey = new Map;
|
|
1276
1276
|
for (const value of values) {
|
|
1277
1277
|
const key = keyOf(value);
|
|
1278
1278
|
const existing = byKey.get(key);
|
|
1279
|
-
if (existing &&
|
|
1280
|
-
throw new
|
|
1279
|
+
if (existing && stableJsonStringify2(existing) !== stableJsonStringify2(value)) {
|
|
1280
|
+
throw new MaterializationValidationError2(`${label} has contradictory values for ${key}.`);
|
|
1281
1281
|
}
|
|
1282
1282
|
byKey.set(key, value);
|
|
1283
1283
|
}
|
|
1284
1284
|
return Object.freeze([...byKey.entries()].sort(([left], [right]) => compareStrings(left, right)).map(([, value]) => value));
|
|
1285
1285
|
}
|
|
1286
1286
|
function normalizeExpectedObject(value) {
|
|
1287
|
-
const ref =
|
|
1287
|
+
const ref = normalizeObjectRef2(value.ref);
|
|
1288
1288
|
if (!value.exists)
|
|
1289
1289
|
return Object.freeze({ ref, exists: false });
|
|
1290
1290
|
if (!Number.isSafeInteger(value.version) || value.version < 1) {
|
|
1291
|
-
throw new
|
|
1291
|
+
throw new MaterializationValidationError2("Expected object version must be a positive integer.");
|
|
1292
1292
|
}
|
|
1293
1293
|
return Object.freeze({
|
|
1294
1294
|
ref,
|
|
@@ -1298,7 +1298,7 @@ function normalizeExpectedObject(value) {
|
|
|
1298
1298
|
});
|
|
1299
1299
|
}
|
|
1300
1300
|
function normalizeExpectedLink(value) {
|
|
1301
|
-
const ref =
|
|
1301
|
+
const ref = normalizeLinkRef2(value.ref);
|
|
1302
1302
|
if (!value.exists)
|
|
1303
1303
|
return Object.freeze({ ref, exists: false });
|
|
1304
1304
|
return Object.freeze({
|
|
@@ -1309,7 +1309,7 @@ function normalizeExpectedLink(value) {
|
|
|
1309
1309
|
}
|
|
1310
1310
|
function normalizeExpectedLinkScope(value) {
|
|
1311
1311
|
return Object.freeze({
|
|
1312
|
-
source:
|
|
1312
|
+
source: normalizeObjectRef2(value.source),
|
|
1313
1313
|
linkId: normalizeNonblank(value.linkId, "Expected link scope link id"),
|
|
1314
1314
|
fingerprint: normalizeNonblank(value.fingerprint, "Expected link scope fingerprint")
|
|
1315
1315
|
});
|
|
@@ -1318,34 +1318,34 @@ function normalizeOperationGroups(groups, operationIds) {
|
|
|
1318
1318
|
const grouped = new Set;
|
|
1319
1319
|
const normalized = groups.map((group) => {
|
|
1320
1320
|
if (group.length < 2) {
|
|
1321
|
-
throw new
|
|
1321
|
+
throw new MaterializationValidationError2("Operation groups must contain at least two operations.");
|
|
1322
1322
|
}
|
|
1323
1323
|
const positions = group.map((id) => {
|
|
1324
1324
|
const position = operationIds.get(id);
|
|
1325
1325
|
if (position === undefined) {
|
|
1326
|
-
throw new
|
|
1326
|
+
throw new MaterializationValidationError2(`Operation group references unknown operation id '${id}'.`);
|
|
1327
1327
|
}
|
|
1328
1328
|
if (grouped.has(id)) {
|
|
1329
|
-
throw new
|
|
1329
|
+
throw new MaterializationValidationError2(`Operation id '${id}' appears in more than one operation group.`);
|
|
1330
1330
|
}
|
|
1331
1331
|
grouped.add(id);
|
|
1332
1332
|
return position;
|
|
1333
1333
|
});
|
|
1334
1334
|
const first = positions[0];
|
|
1335
1335
|
if (positions.some((position, index) => position !== first + index)) {
|
|
1336
|
-
throw new
|
|
1336
|
+
throw new MaterializationValidationError2("Operation groups must list a contiguous run in operation order.");
|
|
1337
1337
|
}
|
|
1338
1338
|
return { first, ids: Object.freeze([...group]) };
|
|
1339
1339
|
});
|
|
1340
1340
|
normalized.sort((left, right) => left.first - right.first);
|
|
1341
1341
|
return Object.freeze(normalized.map(({ ids }) => ids));
|
|
1342
1342
|
}
|
|
1343
|
-
function
|
|
1343
|
+
function normalizeOntologyEditCommit2(input) {
|
|
1344
1344
|
const operationIds = new Map;
|
|
1345
1345
|
const operations = input.operations.map((operation, index) => {
|
|
1346
1346
|
const normalized = normalizeOperation(operation);
|
|
1347
1347
|
if (operationIds.has(normalized.id)) {
|
|
1348
|
-
throw new
|
|
1348
|
+
throw new MaterializationValidationError2(`Duplicate operation id '${normalized.id}'.`);
|
|
1349
1349
|
}
|
|
1350
1350
|
operationIds.set(normalized.id, index);
|
|
1351
1351
|
return normalized;
|
|
@@ -1376,8 +1376,8 @@ function normalizeOntologyEditCommit(input) {
|
|
|
1376
1376
|
mode: "atomic",
|
|
1377
1377
|
source,
|
|
1378
1378
|
operations: Object.freeze(operations),
|
|
1379
|
-
expectedObjects: deduplicateExpectations(expectedObjects, (value) =>
|
|
1380
|
-
expectedLinks: deduplicateExpectations(expectedLinks, (value) =>
|
|
1379
|
+
expectedObjects: deduplicateExpectations(expectedObjects, (value) => objectRefKey2(value.ref), "Expected objects"),
|
|
1380
|
+
expectedLinks: deduplicateExpectations(expectedLinks, (value) => linkRefKey2(value.ref), "Expected links"),
|
|
1381
1381
|
expectedLinkScopes: deduplicateExpectations(expectedLinkScopes, (value) => linkScopeKey(value.source, value.linkId), "Expected link scopes")
|
|
1382
1382
|
});
|
|
1383
1383
|
}
|
|
@@ -1396,90 +1396,90 @@ function normalizePinnedDatasetVersion(version) {
|
|
|
1396
1396
|
function normalizeProjectionRunId(runId) {
|
|
1397
1397
|
return normalizeNonblank(runId, "Projection run id");
|
|
1398
1398
|
}
|
|
1399
|
-
function
|
|
1399
|
+
function normalizeProjectionExecution2(input) {
|
|
1400
1400
|
return Object.freeze({
|
|
1401
1401
|
projectionRunId: normalizeProjectionRunId(input.projectionRunId),
|
|
1402
1402
|
executionToken: normalizeNonblank(input.executionToken, "Projection execution token")
|
|
1403
1403
|
});
|
|
1404
1404
|
}
|
|
1405
1405
|
function normalizeProjectionEntity(entity) {
|
|
1406
|
-
return entity.kind === "object" ? Object.freeze({ kind: "object", ref:
|
|
1406
|
+
return entity.kind === "object" ? Object.freeze({ kind: "object", ref: normalizeObjectRef2(entity.ref) }) : Object.freeze({ kind: "link", ref: normalizeLinkRef2(entity.ref) });
|
|
1407
1407
|
}
|
|
1408
1408
|
function normalizeProjectionAssertion(assertion) {
|
|
1409
1409
|
return assertion.kind === "object" ? Object.freeze({
|
|
1410
1410
|
kind: "object",
|
|
1411
|
-
ref:
|
|
1412
|
-
properties:
|
|
1411
|
+
ref: normalizeObjectRef2(assertion.ref),
|
|
1412
|
+
properties: normalizeJsonProperties2(assertion.properties),
|
|
1413
1413
|
...assertion.sourceUpdatedAt !== undefined ? {
|
|
1414
1414
|
sourceUpdatedAt: normalizeProjectionSourceTimestamp(assertion.sourceUpdatedAt)
|
|
1415
1415
|
} : {}
|
|
1416
1416
|
}) : Object.freeze({
|
|
1417
1417
|
kind: "link",
|
|
1418
|
-
ref:
|
|
1419
|
-
...assertion.properties !== undefined ? { properties:
|
|
1418
|
+
ref: normalizeLinkRef2(assertion.ref),
|
|
1419
|
+
...assertion.properties !== undefined ? { properties: normalizeJsonProperties2(assertion.properties) } : {}
|
|
1420
1420
|
});
|
|
1421
1421
|
}
|
|
1422
|
-
function
|
|
1422
|
+
function normalizeProjectionSourceEntry2(input) {
|
|
1423
1423
|
const root = normalizeProjectionEntity(input.root);
|
|
1424
1424
|
const seen = new Set;
|
|
1425
1425
|
const assertions = input.assertions.map((assertion) => {
|
|
1426
1426
|
const normalized = normalizeProjectionAssertion(assertion);
|
|
1427
|
-
const key =
|
|
1427
|
+
const key = projectionEntityKey2(normalized);
|
|
1428
1428
|
if (seen.has(key)) {
|
|
1429
|
-
throw new
|
|
1429
|
+
throw new MaterializationValidationError2(`Projection entry repeats asserted entity ${key}.`);
|
|
1430
1430
|
}
|
|
1431
1431
|
seen.add(key);
|
|
1432
1432
|
return normalized;
|
|
1433
1433
|
});
|
|
1434
|
-
const rootKey =
|
|
1434
|
+
const rootKey = projectionEntityKey2(root);
|
|
1435
1435
|
if (!seen.has(rootKey)) {
|
|
1436
|
-
throw new
|
|
1436
|
+
throw new MaterializationValidationError2(`Projection entry must contain an assertion matching root ${rootKey}.`);
|
|
1437
1437
|
}
|
|
1438
1438
|
if (root.kind === "object") {
|
|
1439
1439
|
const objectAssertions = assertions.filter((assertion) => assertion.kind === "object");
|
|
1440
|
-
if (objectAssertions.length !== 1 ||
|
|
1441
|
-
throw new
|
|
1440
|
+
if (objectAssertions.length !== 1 || projectionEntityKey2(objectAssertions[0]) !== rootKey) {
|
|
1441
|
+
throw new MaterializationValidationError2("An object projection root must contain exactly its matching object assertion plus links.");
|
|
1442
1442
|
}
|
|
1443
1443
|
for (const assertion of assertions) {
|
|
1444
|
-
if (assertion.kind === "link" &&
|
|
1445
|
-
throw new
|
|
1444
|
+
if (assertion.kind === "link" && objectRefKey2(assertion.ref.source) !== objectRefKey2(root.ref)) {
|
|
1445
|
+
throw new MaterializationValidationError2("An object projection root may contain only links sourced from that root.");
|
|
1446
1446
|
}
|
|
1447
1447
|
}
|
|
1448
|
-
} else if (assertions.length !== 1 || assertions[0].kind !== "link" ||
|
|
1449
|
-
throw new
|
|
1448
|
+
} else if (assertions.length !== 1 || assertions[0].kind !== "link" || projectionEntityKey2(assertions[0]) !== rootKey) {
|
|
1449
|
+
throw new MaterializationValidationError2("A link projection root must contain exactly its matching link assertion.");
|
|
1450
1450
|
}
|
|
1451
1451
|
return Object.freeze({
|
|
1452
1452
|
root,
|
|
1453
|
-
assertions: Object.freeze(assertions.sort((left, right) => compareStrings(
|
|
1453
|
+
assertions: Object.freeze(assertions.sort((left, right) => compareStrings(projectionEntityKey2(left), projectionEntityKey2(right))))
|
|
1454
1454
|
});
|
|
1455
1455
|
}
|
|
1456
1456
|
function normalizeTelemetrySeries(series) {
|
|
1457
1457
|
return Object.freeze({
|
|
1458
|
-
object:
|
|
1458
|
+
object: normalizeObjectRef2(series.object),
|
|
1459
1459
|
propertyId: normalizeNonblank(series.propertyId, "Telemetry property id")
|
|
1460
1460
|
});
|
|
1461
1461
|
}
|
|
1462
1462
|
function normalizeTelemetryPoint(point) {
|
|
1463
1463
|
try {
|
|
1464
|
-
|
|
1464
|
+
assertJsonValue2(point.value, "Telemetry point value");
|
|
1465
1465
|
} catch (error) {
|
|
1466
|
-
throw new
|
|
1466
|
+
throw new MaterializationValidationError2(error instanceof Error ? error.message : "Telemetry point value must be JSON.");
|
|
1467
1467
|
}
|
|
1468
1468
|
return Object.freeze({
|
|
1469
1469
|
series: normalizeTelemetrySeries(point.series),
|
|
1470
|
-
value:
|
|
1470
|
+
value: cloneJsonValue2(point.value),
|
|
1471
1471
|
...point.unit !== undefined ? { unit: normalizeNonblank(point.unit, "Telemetry point unit") } : {},
|
|
1472
1472
|
at: normalizeTimestamp(point.at, "Telemetry point timestamp")
|
|
1473
1473
|
});
|
|
1474
1474
|
}
|
|
1475
|
-
function
|
|
1475
|
+
function normalizeTelemetryAppend2(input) {
|
|
1476
1476
|
const pointsByKey = new Map;
|
|
1477
1477
|
for (const point of input.points) {
|
|
1478
1478
|
const normalized = normalizeTelemetryPoint(point);
|
|
1479
|
-
const key =
|
|
1479
|
+
const key = telemetryPointKey2(normalized.series, normalized.at);
|
|
1480
1480
|
const existing = pointsByKey.get(key);
|
|
1481
|
-
if (input.source.kind === "runtime" && existing &&
|
|
1482
|
-
throw new
|
|
1481
|
+
if (input.source.kind === "runtime" && existing && stableJsonStringify2(existing) !== stableJsonStringify2(normalized)) {
|
|
1482
|
+
throw new MaterializationValidationError2(`Conflicting telemetry points for ${key}.`);
|
|
1483
1483
|
}
|
|
1484
1484
|
pointsByKey.set(key, normalized);
|
|
1485
1485
|
}
|
|
@@ -1491,7 +1491,7 @@ function normalizeTelemetryAppend(input) {
|
|
|
1491
1491
|
kind: "projection",
|
|
1492
1492
|
projection: normalizeProjectionSourceRef(input.source.projection),
|
|
1493
1493
|
datasetVersion: normalizePinnedDatasetVersion(input.source.datasetVersion),
|
|
1494
|
-
execution:
|
|
1494
|
+
execution: normalizeProjectionExecution2(input.source.execution),
|
|
1495
1495
|
batchOrdinal: input.source.batchOrdinal,
|
|
1496
1496
|
sourceRowCount: input.source.sourceRowCount,
|
|
1497
1497
|
sourceRowsSkipped: input.source.sourceRowsSkipped,
|
|
@@ -1499,19 +1499,19 @@ function normalizeTelemetryAppend(input) {
|
|
|
1499
1499
|
});
|
|
1500
1500
|
if (source.kind === "projection") {
|
|
1501
1501
|
if (!Number.isSafeInteger(source.batchOrdinal) || source.batchOrdinal < 0) {
|
|
1502
|
-
throw new
|
|
1502
|
+
throw new MaterializationValidationError2("Telemetry projection batch ordinal must be a nonnegative safe integer.");
|
|
1503
1503
|
}
|
|
1504
1504
|
if (!Number.isSafeInteger(source.sourceRowCount) || source.sourceRowCount < 0) {
|
|
1505
|
-
throw new
|
|
1505
|
+
throw new MaterializationValidationError2("Telemetry projection sourceRowCount must be a nonnegative safe integer.");
|
|
1506
1506
|
}
|
|
1507
1507
|
if (!Number.isSafeInteger(source.sourceRowsSkipped) || source.sourceRowsSkipped < 0) {
|
|
1508
|
-
throw new
|
|
1508
|
+
throw new MaterializationValidationError2("Telemetry projection sourceRowsSkipped must be a nonnegative safe integer.");
|
|
1509
1509
|
}
|
|
1510
1510
|
if (source.sourceRowsSkipped > source.sourceRowCount) {
|
|
1511
|
-
throw new
|
|
1511
|
+
throw new MaterializationValidationError2("Telemetry projection sourceRowsSkipped cannot exceed sourceRowCount.");
|
|
1512
1512
|
}
|
|
1513
1513
|
if (typeof source.inputExhausted !== "boolean") {
|
|
1514
|
-
throw new
|
|
1514
|
+
throw new MaterializationValidationError2("Telemetry projection inputExhausted must be a boolean.");
|
|
1515
1515
|
}
|
|
1516
1516
|
}
|
|
1517
1517
|
return Object.freeze({
|
|
@@ -1566,7 +1566,7 @@ function usableLinkSlotOverride(stored) {
|
|
|
1566
1566
|
return stored.value;
|
|
1567
1567
|
const { source, linkId } = stored.ref;
|
|
1568
1568
|
const scopeLabel = JSON.stringify([source.objectTypeId, source.primaryId, linkId]);
|
|
1569
|
-
throw new
|
|
1569
|
+
throw new MaterializationConflictError2("effective-state", `Cardinality-one link slot ${scopeLabel} could not be migrated automatically because it ` + "contains multiple legacy upsert overrides. Consolidate the stored overrides and clear " + "the migration conflict marker before materializing this scope.");
|
|
1570
1570
|
}
|
|
1571
1571
|
function resolveEffectiveObject(input) {
|
|
1572
1572
|
const properties = resolveObjectAuthority(input.source, input.override, input.editedAt);
|
|
@@ -1680,7 +1680,7 @@ function resolveEffectiveLinkSlotMember(input) {
|
|
|
1680
1680
|
override: input.override,
|
|
1681
1681
|
endpointExists: input.endpointExists
|
|
1682
1682
|
});
|
|
1683
|
-
return resolved &&
|
|
1683
|
+
return resolved && linkRefKey2(resolved.ref) === linkRefKey2(input.ref) ? resolved : null;
|
|
1684
1684
|
}
|
|
1685
1685
|
function resolvedLink(ref, properties) {
|
|
1686
1686
|
if (properties === undefined)
|
|
@@ -1698,27 +1698,27 @@ function buildEditReadSet(ontology, operations) {
|
|
|
1698
1698
|
if (isObjectOperation(operation)) {
|
|
1699
1699
|
if (!ontology.getObjectTypeById(operation.ref.objectTypeId))
|
|
1700
1700
|
continue;
|
|
1701
|
-
objects.set(
|
|
1701
|
+
objects.set(objectRefKey2(operation.ref), operation.ref);
|
|
1702
1702
|
if (operation.kind !== "object.patch") {
|
|
1703
|
-
incidentObjects.set(
|
|
1703
|
+
incidentObjects.set(objectRefKey2(operation.ref), operation.ref);
|
|
1704
1704
|
}
|
|
1705
1705
|
continue;
|
|
1706
1706
|
}
|
|
1707
1707
|
if (!isKnownLinkRef(ontology, operation.ref))
|
|
1708
1708
|
continue;
|
|
1709
|
-
links.set(
|
|
1710
|
-
objects.set(
|
|
1711
|
-
objects.set(
|
|
1709
|
+
links.set(linkRefKey2(operation.ref), operation.ref);
|
|
1710
|
+
objects.set(objectRefKey2(operation.ref.source), operation.ref.source);
|
|
1711
|
+
objects.set(objectRefKey2(operation.ref.target), operation.ref.target);
|
|
1712
1712
|
if (linkCardinality(ontology, operation.ref) === "one") {
|
|
1713
1713
|
const scope = { source: operation.ref.source, linkId: operation.ref.linkId };
|
|
1714
1714
|
scopes.set(linkScopeKey(scope.source, scope.linkId), scope);
|
|
1715
1715
|
}
|
|
1716
1716
|
}
|
|
1717
1717
|
return {
|
|
1718
|
-
objects: [...objects.values()].sort(
|
|
1719
|
-
links: [...links.values()].sort(
|
|
1718
|
+
objects: [...objects.values()].sort(compareObjectRefs2),
|
|
1719
|
+
links: [...links.values()].sort(compareLinkRefs2),
|
|
1720
1720
|
linkScopes: [...scopes.values()].sort((left, right) => linkScopeKey(left.source, left.linkId).localeCompare(linkScopeKey(right.source, right.linkId))),
|
|
1721
|
-
incidentObjects: [...incidentObjects.values()].sort(
|
|
1721
|
+
incidentObjects: [...incidentObjects.values()].sort(compareObjectRefs2),
|
|
1722
1722
|
points: []
|
|
1723
1723
|
};
|
|
1724
1724
|
}
|
|
@@ -1740,13 +1740,13 @@ function isObjectOperation(operation) {
|
|
|
1740
1740
|
// src/materializer/edits/working-state.ts
|
|
1741
1741
|
function mergeWorkingState(ontology, working, state) {
|
|
1742
1742
|
for (const object of state.objects) {
|
|
1743
|
-
if (!working.objects.has(
|
|
1744
|
-
working.objects.set(
|
|
1743
|
+
if (!working.objects.has(objectRefKey2(object.ref))) {
|
|
1744
|
+
working.objects.set(objectRefKey2(object.ref), workingObjectFromState(object));
|
|
1745
1745
|
}
|
|
1746
1746
|
}
|
|
1747
1747
|
for (const link of state.links) {
|
|
1748
|
-
if (linkCardinality(ontology, link.ref) !== "one" && !working.links.edges.has(
|
|
1749
|
-
working.links.edges.set(
|
|
1748
|
+
if (linkCardinality(ontology, link.ref) !== "one" && !working.links.edges.has(linkRefKey2(link.ref))) {
|
|
1749
|
+
working.links.edges.set(linkRefKey2(link.ref), workingLinkEdgeFromState(link));
|
|
1750
1750
|
}
|
|
1751
1751
|
}
|
|
1752
1752
|
for (const scope of state.linkScopes) {
|
|
@@ -1799,8 +1799,8 @@ function resolveObject(ontology, working) {
|
|
|
1799
1799
|
});
|
|
1800
1800
|
}
|
|
1801
1801
|
function resolveLinkEdge(ontology, working, objects) {
|
|
1802
|
-
const source = objects.get(
|
|
1803
|
-
const target = objects.get(
|
|
1802
|
+
const source = objects.get(objectRefKey2(working.ref.source));
|
|
1803
|
+
const target = objects.get(objectRefKey2(working.ref.target));
|
|
1804
1804
|
return resolveEffectiveLink({
|
|
1805
1805
|
ref: working.ref,
|
|
1806
1806
|
source: working.source,
|
|
@@ -1815,7 +1815,7 @@ function resolveLinkSlot(ontology, working, objects) {
|
|
|
1815
1815
|
source: working.source,
|
|
1816
1816
|
override: working.override,
|
|
1817
1817
|
endpointExists: (ref) => {
|
|
1818
|
-
const object = objects.get(
|
|
1818
|
+
const object = objects.get(objectRefKey2(ref));
|
|
1819
1819
|
return Boolean(object && resolveObject(ontology, object));
|
|
1820
1820
|
}
|
|
1821
1821
|
});
|
|
@@ -1834,7 +1834,7 @@ function validateWorkingCardinality(slots) {
|
|
|
1834
1834
|
for (const { effectiveCount, ref } of slots.values()) {
|
|
1835
1835
|
if (effectiveCount <= 1)
|
|
1836
1836
|
continue;
|
|
1837
|
-
throw new
|
|
1837
|
+
throw new MaterializationValidationError2(`Link scope '${ref.source.objectTypeId}.${ref.linkId}' has cardinality one.`);
|
|
1838
1838
|
}
|
|
1839
1839
|
}
|
|
1840
1840
|
|
|
@@ -1848,7 +1848,7 @@ async function loadEditWorkingState(context, storage, session, operations) {
|
|
|
1848
1848
|
}
|
|
1849
1849
|
};
|
|
1850
1850
|
const readSet = buildEditReadSet(context.ontology, operations);
|
|
1851
|
-
const explicitLinkKeys = new Set(readSet.links.map(
|
|
1851
|
+
const explicitLinkKeys = new Set(readSet.links.map(linkRefKey2));
|
|
1852
1852
|
const incidentLinks = new Map;
|
|
1853
1853
|
const loadedState = {
|
|
1854
1854
|
objects: state.objects,
|
|
@@ -1857,7 +1857,7 @@ async function loadEditWorkingState(context, storage, session, operations) {
|
|
|
1857
1857
|
slots: state.links.slots
|
|
1858
1858
|
}
|
|
1859
1859
|
};
|
|
1860
|
-
const revivingObjects = new Set(operations.filter(isRevivingObjectOperation).map((operation) =>
|
|
1860
|
+
const revivingObjects = new Set(operations.filter(isRevivingObjectOperation).map((operation) => objectRefKey2(operation.ref)));
|
|
1861
1861
|
for await (const page of storage.streamState({
|
|
1862
1862
|
session,
|
|
1863
1863
|
requests: oneStateRequest(readSet),
|
|
@@ -1865,7 +1865,7 @@ async function loadEditWorkingState(context, storage, session, operations) {
|
|
|
1865
1865
|
})) {
|
|
1866
1866
|
mergeWorkingState(context.ontology, loadedState, page);
|
|
1867
1867
|
for (const link of page.links) {
|
|
1868
|
-
const key =
|
|
1868
|
+
const key = linkRefKey2(link.ref);
|
|
1869
1869
|
if (linkCardinality(context.ontology, link.ref) !== "one" && explicitLinkKeys.has(key) && !state.links.edges.has(key)) {
|
|
1870
1870
|
state.links.edges.set(key, workingLinkEdgeFromState(link));
|
|
1871
1871
|
}
|
|
@@ -1885,8 +1885,8 @@ async function mergeIncidentState(context, storage, session, state, incidentStat
|
|
|
1885
1885
|
const missingEndpoints = new Map;
|
|
1886
1886
|
for (const link of knownIncidentStates) {
|
|
1887
1887
|
for (const ref of [link.ref.source, link.ref.target]) {
|
|
1888
|
-
if (!state.objects.has(
|
|
1889
|
-
missingEndpoints.set(
|
|
1888
|
+
if (!state.objects.has(objectRefKey2(ref)))
|
|
1889
|
+
missingEndpoints.set(objectRefKey2(ref), ref);
|
|
1890
1890
|
}
|
|
1891
1891
|
}
|
|
1892
1892
|
if (missingEndpoints.size > 0) {
|
|
@@ -1901,7 +1901,7 @@ async function mergeIncidentState(context, storage, session, state, incidentStat
|
|
|
1901
1901
|
const relevantStates = knownIncidentStates.filter((link) => {
|
|
1902
1902
|
if (link.effective)
|
|
1903
1903
|
return true;
|
|
1904
|
-
if (revivingObjects.has(
|
|
1904
|
+
if (revivingObjects.has(objectRefKey2(link.ref.source)) || revivingObjects.has(objectRefKey2(link.ref.target))) {
|
|
1905
1905
|
return true;
|
|
1906
1906
|
}
|
|
1907
1907
|
if (linkCardinality(context.ontology, link.ref) === "one") {
|
|
@@ -1910,7 +1910,7 @@ async function mergeIncidentState(context, storage, session, state, incidentStat
|
|
|
1910
1910
|
source: link.source,
|
|
1911
1911
|
override: usableLinkSlotOverride(link.slotOverride),
|
|
1912
1912
|
endpointExists: (ref) => {
|
|
1913
|
-
const object = state.objects.get(
|
|
1913
|
+
const object = state.objects.get(objectRefKey2(ref));
|
|
1914
1914
|
return Boolean(object && resolveObject(context.ontology, object));
|
|
1915
1915
|
}
|
|
1916
1916
|
}));
|
|
@@ -1931,7 +1931,7 @@ async function mergeIncidentState(context, storage, session, state, incidentStat
|
|
|
1931
1931
|
for (const link of relevantStates) {
|
|
1932
1932
|
if (linkCardinality(context.ontology, link.ref) === "one")
|
|
1933
1933
|
continue;
|
|
1934
|
-
const key =
|
|
1934
|
+
const key = linkRefKey2(link.ref);
|
|
1935
1935
|
if (state.links.edges.has(key))
|
|
1936
1936
|
continue;
|
|
1937
1937
|
state.links.edges.set(key, workingLinkEdgeFromState(link));
|
|
@@ -1948,8 +1948,8 @@ async function mergeMissingLinkSlotEndpoints(context, storage, session, state) {
|
|
|
1948
1948
|
working.before?.ref.target
|
|
1949
1949
|
];
|
|
1950
1950
|
for (const ref of refs) {
|
|
1951
|
-
if (ref && !state.objects.has(
|
|
1952
|
-
missing.set(
|
|
1951
|
+
if (ref && !state.objects.has(objectRefKey2(ref)))
|
|
1952
|
+
missing.set(objectRefKey2(ref), ref);
|
|
1953
1953
|
}
|
|
1954
1954
|
}
|
|
1955
1955
|
if (missing.size === 0)
|
|
@@ -2034,7 +2034,7 @@ function diffEffectiveLink(input) {
|
|
|
2034
2034
|
return updateLinkChange(input.before, input.resolved, input.commitId, input.committedAt);
|
|
2035
2035
|
}
|
|
2036
2036
|
function diffEffectiveLinkSlot(input) {
|
|
2037
|
-
if (input.before && input.resolved &&
|
|
2037
|
+
if (input.before && input.resolved && linkRefKey2(input.before.ref) !== linkRefKey2(input.resolved.ref)) {
|
|
2038
2038
|
return [
|
|
2039
2039
|
diffEffectiveLink({ ...input, resolved: null }),
|
|
2040
2040
|
diffEffectiveLink({ ...input, before: null })
|
|
@@ -2083,7 +2083,7 @@ function updateLinkChange(before, resolved, commitId, committedAt) {
|
|
|
2083
2083
|
};
|
|
2084
2084
|
}
|
|
2085
2085
|
function sameProperties(left, right) {
|
|
2086
|
-
return
|
|
2086
|
+
return stableJsonStringify2(left) === stableJsonStringify2(right);
|
|
2087
2087
|
}
|
|
2088
2088
|
function propertyChanges(before, after) {
|
|
2089
2089
|
const changes = {};
|
|
@@ -2093,7 +2093,7 @@ function propertyChanges(before, after) {
|
|
|
2093
2093
|
changes[id] = { operation: "created", after: after[id] };
|
|
2094
2094
|
else if (!(id in after))
|
|
2095
2095
|
changes[id] = { operation: "cleared", before: before[id], after: null };
|
|
2096
|
-
else if (
|
|
2096
|
+
else if (stableJsonStringify2(before[id]) !== stableJsonStringify2(after[id])) {
|
|
2097
2097
|
changes[id] = { operation: "updated", before: before[id], after: after[id] };
|
|
2098
2098
|
}
|
|
2099
2099
|
}
|
|
@@ -2121,7 +2121,7 @@ function validateLinkRef(ontology, ref) {
|
|
|
2121
2121
|
function validateObjectAuthorityProperties(ontology, ref, properties) {
|
|
2122
2122
|
return materializationValidation(() => {
|
|
2123
2123
|
const objectType = ontology.resolveObjectType(ref.objectTypeId);
|
|
2124
|
-
|
|
2124
|
+
assertKnownProperties2(objectType, properties);
|
|
2125
2125
|
const primaryId = ontology.getPrimaryPropertyId(ref.objectTypeId);
|
|
2126
2126
|
const result = { ...properties };
|
|
2127
2127
|
if (primaryId in result) {
|
|
@@ -2137,8 +2137,8 @@ function validateObjectAuthorityProperties(ontology, ref, properties) {
|
|
|
2137
2137
|
}
|
|
2138
2138
|
}
|
|
2139
2139
|
const valueTypesById = ontology.getValueTypesById();
|
|
2140
|
-
|
|
2141
|
-
return
|
|
2140
|
+
validateObjectProperties2(objectType, result, valueTypesById);
|
|
2141
|
+
return normalizeObjectProperties2(objectType.properties, result, valueTypesById, objectType.id);
|
|
2142
2142
|
});
|
|
2143
2143
|
}
|
|
2144
2144
|
function validateObjectPatchPropertyIds(ontology, ref, propertyIds, label) {
|
|
@@ -2162,13 +2162,13 @@ function validateObjectPatchPropertyIds(ontology, ref, propertyIds, label) {
|
|
|
2162
2162
|
function validateEffectiveObject(ontology, ref, properties) {
|
|
2163
2163
|
materializationValidation(() => {
|
|
2164
2164
|
const objectType = ontology.resolveObjectType(ref.objectTypeId);
|
|
2165
|
-
|
|
2165
|
+
assertKnownProperties2(objectType, properties);
|
|
2166
2166
|
for (const property of objectType.properties) {
|
|
2167
2167
|
if (property.mode !== "telemetry" && property.required && properties[property.id] === undefined) {
|
|
2168
2168
|
throw new Error(`[Sixb] Missing required property '${property.id}' for object type '${objectType.id}'`);
|
|
2169
2169
|
}
|
|
2170
2170
|
}
|
|
2171
|
-
|
|
2171
|
+
validateObjectProperties2(objectType, properties, ontology.getValueTypesById());
|
|
2172
2172
|
});
|
|
2173
2173
|
}
|
|
2174
2174
|
function validateLinkAuthorityProperties(ontology, ref, properties) {
|
|
@@ -2181,8 +2181,8 @@ function validateLinkAuthorityProperties(ontology, ref, properties) {
|
|
|
2181
2181
|
throw new Error(`[Sixb] Link '${ref.source.objectTypeId}.${ref.linkId}' cannot target '${ref.target.objectTypeId}'.`);
|
|
2182
2182
|
}
|
|
2183
2183
|
const valueTypesById = ontology.getValueTypesById();
|
|
2184
|
-
|
|
2185
|
-
return
|
|
2184
|
+
validateLinkProperties2(objectType, link, properties, undefined, valueTypesById);
|
|
2185
|
+
return normalizeLinkProperties2(objectType, link, properties, valueTypesById);
|
|
2186
2186
|
});
|
|
2187
2187
|
}
|
|
2188
2188
|
function validateTelemetryPoint(ontology, point) {
|
|
@@ -2194,11 +2194,11 @@ function validateTelemetryPoint(ontology, point) {
|
|
|
2194
2194
|
}
|
|
2195
2195
|
const path = `${objectType.id}.${property.id}`;
|
|
2196
2196
|
const valueTypesById = ontology.getValueTypesById();
|
|
2197
|
-
|
|
2198
|
-
|
|
2197
|
+
validatePropertyValue2(property, point.value, path, valueTypesById);
|
|
2198
|
+
validateTelemetryUnit2(property, path, point.unit, valueTypesById);
|
|
2199
2199
|
return {
|
|
2200
2200
|
...point,
|
|
2201
|
-
value: point.value === null ? null :
|
|
2201
|
+
value: point.value === null ? null : normalizeSchemaValue2(property.schema, point.value, path, valueTypesById)
|
|
2202
2202
|
};
|
|
2203
2203
|
});
|
|
2204
2204
|
}
|
|
@@ -2206,9 +2206,9 @@ function materializationValidation(run) {
|
|
|
2206
2206
|
try {
|
|
2207
2207
|
return run();
|
|
2208
2208
|
} catch (error) {
|
|
2209
|
-
if (error instanceof
|
|
2209
|
+
if (error instanceof MaterializationValidationError2)
|
|
2210
2210
|
throw error;
|
|
2211
|
-
throw new
|
|
2211
|
+
throw new MaterializationValidationError2(error instanceof Error ? error.message : String(error));
|
|
2212
2212
|
}
|
|
2213
2213
|
}
|
|
2214
2214
|
|
|
@@ -2233,7 +2233,7 @@ function applyObjectEdit(input) {
|
|
|
2233
2233
|
next = applyObjectRestore(input);
|
|
2234
2234
|
break;
|
|
2235
2235
|
default:
|
|
2236
|
-
throw new
|
|
2236
|
+
throw new MaterializationValidationError2("Expected an object edit operation.");
|
|
2237
2237
|
}
|
|
2238
2238
|
const editedAt = applyObjectEditTimes(input, next);
|
|
2239
2239
|
const authority = transition(current, next);
|
|
@@ -2279,7 +2279,7 @@ function sameStringRecord(left, right) {
|
|
|
2279
2279
|
}
|
|
2280
2280
|
function applyObjectCreate(input, operation) {
|
|
2281
2281
|
if (input.sourceProperties || input.authority) {
|
|
2282
|
-
throw new
|
|
2282
|
+
throw new MaterializationValidationError2(`Object create requires complete authority absence for ${operation.ref.objectTypeId}:${operation.ref.primaryId}.`);
|
|
2283
2283
|
}
|
|
2284
2284
|
return { kind: "create", properties: input.normalizedProperties ?? operation.properties };
|
|
2285
2285
|
}
|
|
@@ -2309,7 +2309,7 @@ function mergeUpsertIntoPatch(current, properties, hasSource) {
|
|
|
2309
2309
|
function applyObjectPatch(input, operation) {
|
|
2310
2310
|
const current = input.authority;
|
|
2311
2311
|
if (!input.effectiveExists && current?.kind !== "patch") {
|
|
2312
|
-
throw new
|
|
2312
|
+
throw new MaterializationValidationError2(`Object patch requires an effective object for ${operation.ref.objectTypeId}:${operation.ref.primaryId}.`);
|
|
2313
2313
|
}
|
|
2314
2314
|
const setInput = input.normalizedSet ?? operation.set;
|
|
2315
2315
|
if (current?.kind === "create" && !input.sourceProperties) {
|
|
@@ -2377,7 +2377,7 @@ function applyLinkEdit(input) {
|
|
|
2377
2377
|
next = null;
|
|
2378
2378
|
break;
|
|
2379
2379
|
default:
|
|
2380
|
-
throw new
|
|
2380
|
+
throw new MaterializationValidationError2("Expected a link edit operation.");
|
|
2381
2381
|
}
|
|
2382
2382
|
return transition(current, next);
|
|
2383
2383
|
}
|
|
@@ -2401,7 +2401,7 @@ function transition(current, next) {
|
|
|
2401
2401
|
return { next, changed: !sameAuthority(current, next) };
|
|
2402
2402
|
}
|
|
2403
2403
|
function sameAuthority(left, right) {
|
|
2404
|
-
return
|
|
2404
|
+
return stableJsonStringify2(left) === stableJsonStringify2(right);
|
|
2405
2405
|
}
|
|
2406
2406
|
|
|
2407
2407
|
// src/materializer/edits/operations.ts
|
|
@@ -2428,7 +2428,7 @@ function applyObjectOperation(context, state, operation, identity, journal) {
|
|
|
2428
2428
|
const working = requireWorkingObject(state, operation);
|
|
2429
2429
|
const normalized = validateObjectOperation(context, operation);
|
|
2430
2430
|
const currentEffective = resolveObject(context.ontology, working);
|
|
2431
|
-
const
|
|
2431
|
+
const transition = applyObjectEdit({
|
|
2432
2432
|
operation,
|
|
2433
2433
|
sourceProperties: working.source?.assertion.properties ?? null,
|
|
2434
2434
|
authority: working.override,
|
|
@@ -2437,13 +2437,13 @@ function applyObjectOperation(context, state, operation, identity, journal) {
|
|
|
2437
2437
|
effectiveExists: currentEffective !== null,
|
|
2438
2438
|
...normalized
|
|
2439
2439
|
});
|
|
2440
|
-
applyObjectTransition(context, state, working,
|
|
2441
|
-
return objectOperationOutcome(operation, working,
|
|
2440
|
+
applyObjectTransition(context, state, working, transition.next, transition.editedAt, journal);
|
|
2441
|
+
return objectOperationOutcome(operation, working, transition.changed, context, identity);
|
|
2442
2442
|
}
|
|
2443
2443
|
function requireWorkingObject(state, operation) {
|
|
2444
|
-
const working = state.objects.get(
|
|
2444
|
+
const working = state.objects.get(objectRefKey2(operation.ref));
|
|
2445
2445
|
if (!working)
|
|
2446
|
-
throw new
|
|
2446
|
+
throw new MaterializationValidationError2("Object state was not loaded.");
|
|
2447
2447
|
return working;
|
|
2448
2448
|
}
|
|
2449
2449
|
function validateObjectOperation(context, operation) {
|
|
@@ -2503,7 +2503,7 @@ function objectOperationOutcome(operation, working, changed, context, identity)
|
|
|
2503
2503
|
});
|
|
2504
2504
|
const object = change?.after ?? working.before;
|
|
2505
2505
|
if (!object) {
|
|
2506
|
-
throw new
|
|
2506
|
+
throw new MaterializationValidationError2("Effective object outcome could not be resolved.");
|
|
2507
2507
|
}
|
|
2508
2508
|
return { ...outcome, object };
|
|
2509
2509
|
}
|
|
@@ -2521,23 +2521,23 @@ function applyLinkOperation(context, state, operation, cardinality, journal) {
|
|
|
2521
2521
|
authority: working.override,
|
|
2522
2522
|
effectiveExists: currentEffective !== null
|
|
2523
2523
|
};
|
|
2524
|
-
const
|
|
2525
|
-
applyLinkEdgeTransition(working,
|
|
2526
|
-
return { id: operation.id, ok: true, authority: authorityOutcome(
|
|
2524
|
+
const transition = applyLinkEdit({ ...transitionInput, normalizedProperties });
|
|
2525
|
+
applyLinkEdgeTransition(working, transition.next, journal);
|
|
2526
|
+
return { id: operation.id, ok: true, authority: authorityOutcome(transition.changed) };
|
|
2527
2527
|
}
|
|
2528
2528
|
function applyLinkSlotOperation(context, state, operation, normalizedProperties, journal) {
|
|
2529
2529
|
const key = linkScopeKey(operation.ref.source, operation.ref.linkId);
|
|
2530
2530
|
const working = state.links.slots.get(key);
|
|
2531
2531
|
if (!working) {
|
|
2532
|
-
throw new
|
|
2532
|
+
throw new MaterializationValidationError2("Link slot state was not loaded.");
|
|
2533
2533
|
}
|
|
2534
2534
|
const current = resolveLinkSlot(context.ontology, working, state.objects);
|
|
2535
2535
|
const previous = working.override;
|
|
2536
2536
|
let next = previous;
|
|
2537
2537
|
switch (operation.kind) {
|
|
2538
2538
|
case "link.upsert":
|
|
2539
|
-
if (current &&
|
|
2540
|
-
throw new
|
|
2539
|
+
if (current && linkRefKey2(current.ref) !== linkRefKey2(operation.ref)) {
|
|
2540
|
+
throw new MaterializationValidationError2(`Link scope '${operation.ref.source.objectTypeId}.${operation.ref.linkId}' has cardinality one.`);
|
|
2541
2541
|
}
|
|
2542
2542
|
next = {
|
|
2543
2543
|
kind: "set",
|
|
@@ -2546,17 +2546,17 @@ function applyLinkSlotOperation(context, state, operation, normalizedProperties,
|
|
|
2546
2546
|
};
|
|
2547
2547
|
break;
|
|
2548
2548
|
case "link.delete":
|
|
2549
|
-
if (current &&
|
|
2549
|
+
if (current && linkRefKey2(current.ref) === linkRefKey2(operation.ref)) {
|
|
2550
2550
|
next = { kind: "clear", target: operation.ref.target };
|
|
2551
2551
|
}
|
|
2552
2552
|
break;
|
|
2553
2553
|
case "link.reset":
|
|
2554
|
-
if (previous &&
|
|
2554
|
+
if (previous && objectRefKey2(previous.target) === objectRefKey2(operation.ref.target)) {
|
|
2555
2555
|
next = null;
|
|
2556
2556
|
}
|
|
2557
2557
|
break;
|
|
2558
2558
|
}
|
|
2559
|
-
const changed =
|
|
2559
|
+
const changed = stableJsonStringify2(previous) !== stableJsonStringify2(next);
|
|
2560
2560
|
working.override = next;
|
|
2561
2561
|
journal?.push({
|
|
2562
2562
|
restore: () => {
|
|
@@ -2566,21 +2566,21 @@ function applyLinkSlotOperation(context, state, operation, normalizedProperties,
|
|
|
2566
2566
|
return { id: operation.id, ok: true, authority: authorityOutcome(changed) };
|
|
2567
2567
|
}
|
|
2568
2568
|
function requireWorkingLinkEdge(state, operation) {
|
|
2569
|
-
const working = state.links.edges.get(
|
|
2569
|
+
const working = state.links.edges.get(linkRefKey2(operation.ref));
|
|
2570
2570
|
if (!working)
|
|
2571
|
-
throw new
|
|
2571
|
+
throw new MaterializationValidationError2("Link state was not loaded.");
|
|
2572
2572
|
return working;
|
|
2573
2573
|
}
|
|
2574
2574
|
function validateLinkEndpoints(context, state, operation) {
|
|
2575
2575
|
if (operation.kind !== "link.upsert")
|
|
2576
2576
|
return;
|
|
2577
|
-
const source = state.objects.get(
|
|
2578
|
-
const target = state.objects.get(
|
|
2577
|
+
const source = state.objects.get(objectRefKey2(operation.ref.source));
|
|
2578
|
+
const target = state.objects.get(objectRefKey2(operation.ref.target));
|
|
2579
2579
|
const sourceExists = source && resolveObject(context.ontology, source);
|
|
2580
2580
|
const targetExists = target && resolveObject(context.ontology, target);
|
|
2581
2581
|
if (sourceExists && targetExists)
|
|
2582
2582
|
return;
|
|
2583
|
-
throw new
|
|
2583
|
+
throw new MaterializationValidationError2("Link upsert requires both endpoints to be effective.");
|
|
2584
2584
|
}
|
|
2585
2585
|
function validateLinkOperation(context, operation) {
|
|
2586
2586
|
if (operation.kind !== "link.upsert")
|
|
@@ -2651,15 +2651,15 @@ async function stageLinkSlot(context, storage, session, objects, working, planCo
|
|
|
2651
2651
|
linkId: working.ref.linkId,
|
|
2652
2652
|
target: working.override.target
|
|
2653
2653
|
} : null);
|
|
2654
|
-
const scopeSortKey =
|
|
2654
|
+
const scopeSortKey = linkScopeSortKey2(working.ref.source, working.ref.linkId);
|
|
2655
2655
|
const work = overrideItems.map((item) => planWork(item, scopeSortKey));
|
|
2656
2656
|
if (representative) {
|
|
2657
|
-
work.push(classificationWork("link",
|
|
2657
|
+
work.push(classificationWork("link", linkRefKey2(representative), linkRefSortKey2(representative)));
|
|
2658
2658
|
}
|
|
2659
2659
|
for (const change of changes) {
|
|
2660
2660
|
const effectiveItems = [];
|
|
2661
2661
|
appendEffectiveLinkWork(effectiveItems, change);
|
|
2662
|
-
const sortKey =
|
|
2662
|
+
const sortKey = linkRefSortKey2(change.ref);
|
|
2663
2663
|
work.push(...effectiveItems.map((item) => planWork(item, sortKey)));
|
|
2664
2664
|
work.push(eventWork(buildLinkEvent(context, planContext, change)));
|
|
2665
2665
|
}
|
|
@@ -2680,9 +2680,9 @@ async function stageObject(context, storage, session, working, planContext) {
|
|
|
2680
2680
|
});
|
|
2681
2681
|
if (change)
|
|
2682
2682
|
appendEffectiveObjectWork(items, change);
|
|
2683
|
-
const sortKey =
|
|
2683
|
+
const sortKey = objectRefSortKey2(working.ref);
|
|
2684
2684
|
const work = [
|
|
2685
|
-
classificationWork("object",
|
|
2685
|
+
classificationWork("object", objectRefKey2(working.ref), sortKey),
|
|
2686
2686
|
...items.map((item) => planWork(item, sortKey))
|
|
2687
2687
|
];
|
|
2688
2688
|
if (change) {
|
|
@@ -2703,9 +2703,9 @@ async function stageLinkEdge(context, storage, session, objects, working, planCo
|
|
|
2703
2703
|
});
|
|
2704
2704
|
if (change)
|
|
2705
2705
|
appendEffectiveLinkWork(items, change);
|
|
2706
|
-
const sortKey =
|
|
2706
|
+
const sortKey = linkRefSortKey2(working.ref);
|
|
2707
2707
|
const work = [
|
|
2708
|
-
classificationWork("link",
|
|
2708
|
+
classificationWork("link", linkRefKey2(working.ref), sortKey),
|
|
2709
2709
|
...items.map((item) => planWork(item, sortKey))
|
|
2710
2710
|
];
|
|
2711
2711
|
if (change) {
|
|
@@ -2735,10 +2735,10 @@ function materializationEventContext(context, planContext) {
|
|
|
2735
2735
|
return { ...base, actor: planContext.actor };
|
|
2736
2736
|
}
|
|
2737
2737
|
function sortedObjects(objects) {
|
|
2738
|
-
return [...objects.values()].sort((left, right) =>
|
|
2738
|
+
return [...objects.values()].sort((left, right) => compareObjectRefs2(left.ref, right.ref));
|
|
2739
2739
|
}
|
|
2740
2740
|
function sortedLinkEdges(edges) {
|
|
2741
|
-
return [...edges.values()].sort((left, right) =>
|
|
2741
|
+
return [...edges.values()].sort((left, right) => compareLinkRefs2(left.ref, right.ref));
|
|
2742
2742
|
}
|
|
2743
2743
|
function sortedLinkSlots(slots) {
|
|
2744
2744
|
return [...slots.values()].sort((left, right) => linkScopeKey(left.ref.source, left.ref.linkId).localeCompare(linkScopeKey(right.ref.source, right.ref.linkId)));
|
|
@@ -2750,9 +2750,9 @@ async function commitEdits(context, raw) {
|
|
|
2750
2750
|
return executeEditCommit(context, command);
|
|
2751
2751
|
}
|
|
2752
2752
|
function prepareEditCommit(context, raw) {
|
|
2753
|
-
const input =
|
|
2753
|
+
const input = normalizeOntologyEditCommit2(raw.input);
|
|
2754
2754
|
const idempotencyKey = editIdempotencyKey(input);
|
|
2755
|
-
const identity =
|
|
2755
|
+
const identity = createTimedCommitIdentity2({
|
|
2756
2756
|
projectId: context.projectId,
|
|
2757
2757
|
idempotencyKey,
|
|
2758
2758
|
normalizedCallerIntent: input,
|
|
@@ -2767,15 +2767,15 @@ function prepareEditCommit(context, raw) {
|
|
|
2767
2767
|
}
|
|
2768
2768
|
function editIdempotencyKey(input) {
|
|
2769
2769
|
if (input.source.kind === "action") {
|
|
2770
|
-
return
|
|
2770
|
+
return createActionIdempotencyKey2(input.source.runId);
|
|
2771
2771
|
}
|
|
2772
|
-
return
|
|
2772
|
+
return createRuntimeIdempotencyKey2(input.source.requestId);
|
|
2773
2773
|
}
|
|
2774
2774
|
async function lockActionRunForMaterialization(storage, projectId, input, execution) {
|
|
2775
2775
|
if (input.source.kind !== "action")
|
|
2776
2776
|
return;
|
|
2777
2777
|
if (!storage.actionRuns) {
|
|
2778
|
-
throw new
|
|
2778
|
+
throw new MaterializationValidationError2("Storage does not provide Action run capabilities required by this commit.");
|
|
2779
2779
|
}
|
|
2780
2780
|
const run = await storage.actionRuns.lockForMaterialization({
|
|
2781
2781
|
projectId,
|
|
@@ -2795,14 +2795,14 @@ async function validateMutationExecution(storage, projectId, input, execution) {
|
|
|
2795
2795
|
runId: input.source.runId
|
|
2796
2796
|
});
|
|
2797
2797
|
if (!storage.actionRuns) {
|
|
2798
|
-
throw new
|
|
2798
|
+
throw new MaterializationValidationError2("Storage does not provide Action run capabilities required by this commit.");
|
|
2799
2799
|
}
|
|
2800
2800
|
const run = await storage.actionRuns.getById({ projectId, id: input.source.runId });
|
|
2801
2801
|
if (!run) {
|
|
2802
|
-
throw new
|
|
2802
|
+
throw new MaterializationValidationError2(`Action run '${input.source.runId}' was not found.`);
|
|
2803
2803
|
}
|
|
2804
2804
|
if (run.actionId !== input.source.actionId) {
|
|
2805
|
-
throw new
|
|
2805
|
+
throw new MaterializationConflictError2("run-correlation", `Action run '${run.id}' does not belong to action '${input.source.actionId}'.`);
|
|
2806
2806
|
}
|
|
2807
2807
|
assertMaterializerRunExecution(execution, run.executionId, `Action run '${run.id}'`);
|
|
2808
2808
|
}
|
|
@@ -2930,7 +2930,7 @@ function failedEditGroup(group, message) {
|
|
|
2930
2930
|
function isRecoverableEditValidation(input, error) {
|
|
2931
2931
|
if (input.mode === "atomic")
|
|
2932
2932
|
return false;
|
|
2933
|
-
return error instanceof
|
|
2933
|
+
return error instanceof MaterializationValidationError2;
|
|
2934
2934
|
}
|
|
2935
2935
|
function editPlanContext(command) {
|
|
2936
2936
|
const context = {
|
|
@@ -2954,7 +2954,7 @@ async function finalizeEditMaterialization(storage, session, result) {
|
|
|
2954
2954
|
async function lockProjectionRunForMaterialization(storage, input) {
|
|
2955
2955
|
const projectionRuns = storage.projectionRuns;
|
|
2956
2956
|
if (!projectionRuns) {
|
|
2957
|
-
throw new
|
|
2957
|
+
throw new MaterializationValidationError2(input.capabilityErrorMessage ?? "Storage transaction does not provide projection run capabilities.");
|
|
2958
2958
|
}
|
|
2959
2959
|
const run = await projectionRuns.lockForMaterialization({
|
|
2960
2960
|
id: input.projectionRunId,
|
|
@@ -2968,7 +2968,7 @@ async function lockProjectionRunForMaterialization(storage, input) {
|
|
|
2968
2968
|
function assertProjectionRunTargets(run, resolved) {
|
|
2969
2969
|
if (projectionRunTargetsMatch(run, resolved.definition))
|
|
2970
2970
|
return;
|
|
2971
|
-
throw new
|
|
2971
|
+
throw new MaterializationConflictError2("run-correlation", `Projection run '${run.id}' target object types do not match projection '${resolved.projectionId}'.`);
|
|
2972
2972
|
}
|
|
2973
2973
|
function projectionRunTargetsMatch(run, definition) {
|
|
2974
2974
|
switch (definition._tag) {
|
|
@@ -2997,7 +2997,7 @@ function createProjectionRunMaterializationIdentity(input) {
|
|
|
2997
2997
|
case "TelemetryProjectionDefinition":
|
|
2998
2998
|
return { ...base, projectionKind: "telemetry", protocol: "telemetry" };
|
|
2999
2999
|
default:
|
|
3000
|
-
throw new
|
|
3000
|
+
throw new MaterializationValidationError2("Expected a supported projection definition.");
|
|
3001
3001
|
}
|
|
3002
3002
|
}
|
|
3003
3003
|
|
|
@@ -3012,10 +3012,10 @@ function prepareProjectionRunFinish(context, raw) {
|
|
|
3012
3012
|
assertValidTerminalDecision(raw.input);
|
|
3013
3013
|
const source = normalizeProjectionSourceRef(raw.input.source);
|
|
3014
3014
|
const datasetVersion = normalizePinnedDatasetVersion(raw.input.datasetVersion);
|
|
3015
|
-
const projectionExecution =
|
|
3015
|
+
const projectionExecution = normalizeProjectionExecution2(raw.input.execution);
|
|
3016
3016
|
const resolved = raw.input.protocol === "replacement" ? context.projectionRegistry.resolveSource(source.projectionId) : context.projectionRegistry.resolveTelemetry(source.projectionId);
|
|
3017
3017
|
if (resolved.datasetId !== datasetVersion.datasetId) {
|
|
3018
|
-
throw new
|
|
3018
|
+
throw new MaterializationValidationError2(`Projection '${resolved.projectionId}' requires dataset '${resolved.datasetId}'.`);
|
|
3019
3019
|
}
|
|
3020
3020
|
const identity = createProjectionRunMaterializationIdentity({
|
|
3021
3021
|
resolved,
|
|
@@ -3060,19 +3060,19 @@ async function finishProjectionRunTransaction(storage, command) {
|
|
|
3060
3060
|
}
|
|
3061
3061
|
function assertValidTerminalDecision(input) {
|
|
3062
3062
|
if (input.protocol !== "replacement" && input.protocol !== "telemetry") {
|
|
3063
|
-
throw new
|
|
3063
|
+
throw new MaterializationValidationError2("Projection finish protocol is invalid.");
|
|
3064
3064
|
}
|
|
3065
3065
|
if (input.status !== "succeeded" && input.status !== "failed" && input.status !== "cancelled") {
|
|
3066
|
-
throw new
|
|
3066
|
+
throw new MaterializationValidationError2("Projection finish status must be terminal.");
|
|
3067
3067
|
}
|
|
3068
3068
|
const inputExhausted = "inputExhausted" in input ? input.inputExhausted : undefined;
|
|
3069
3069
|
if (input.status === "succeeded" && input.protocol === "telemetry") {
|
|
3070
3070
|
if (inputExhausted === true)
|
|
3071
3071
|
return;
|
|
3072
|
-
throw new
|
|
3072
|
+
throw new MaterializationValidationError2("Telemetry projection success requires an explicit exhausted-input acknowledgement.");
|
|
3073
3073
|
}
|
|
3074
3074
|
if (inputExhausted !== undefined) {
|
|
3075
|
-
throw new
|
|
3075
|
+
throw new MaterializationValidationError2("Only telemetry projection success can acknowledge exhausted input.");
|
|
3076
3076
|
}
|
|
3077
3077
|
}
|
|
3078
3078
|
function terminalDecision(input) {
|
|
@@ -3098,19 +3098,19 @@ async function assertReplacementTerminalDecision(storage, command) {
|
|
|
3098
3098
|
});
|
|
3099
3099
|
if (command.input.status === "succeeded") {
|
|
3100
3100
|
if (!commit) {
|
|
3101
|
-
throw new
|
|
3101
|
+
throw new MaterializationConflictError2("run-correlation", `Projection replacement run '${command.input.execution.projectionRunId}' cannot succeed before its ontology commit exists.`);
|
|
3102
3102
|
}
|
|
3103
3103
|
assertReplacementCommitCorrelation(commit, command);
|
|
3104
3104
|
return;
|
|
3105
3105
|
}
|
|
3106
3106
|
if (commit) {
|
|
3107
|
-
throw new
|
|
3107
|
+
throw new MaterializationConflictError2("run-correlation", `Projection replacement run '${command.input.execution.projectionRunId}' cannot finish as '${command.input.status}' after its ontology commit exists.`);
|
|
3108
3108
|
}
|
|
3109
3109
|
}
|
|
3110
3110
|
function assertReplacementCommitCorrelation(commit, command) {
|
|
3111
3111
|
const { input, identity } = command;
|
|
3112
3112
|
if (commit.origin.kind !== "projection" || commit.executionId !== command.execution.executionId || commit.intent.kind !== "projection" || commit.result.kind !== "projection" || commit.origin.projectionRunId !== input.execution.projectionRunId || commit.origin.projectionId !== input.source.projectionId || commit.intent.source.projectionId !== input.source.projectionId || !datasetVersionsEqual(commit.intent.datasetVersion, input.datasetVersion) || commit.ontologyRevision !== identity.ontologyRevision || commit.projectionRevision !== identity.projectionRevision || commit.ownershipHash !== identity.ownershipHash) {
|
|
3113
|
-
throw new
|
|
3113
|
+
throw new MaterializationConflictError2("run-correlation", `Projection replacement run '${input.execution.projectionRunId}' commit identity does not match.`);
|
|
3114
3114
|
}
|
|
3115
3115
|
}
|
|
3116
3116
|
function datasetVersionsEqual(left, right) {
|
|
@@ -3122,6 +3122,12 @@ function createProjectionEntryValidator(ontology, resolved) {
|
|
|
3122
3122
|
const policy = createValidationPolicy(resolved);
|
|
3123
3123
|
return (entry) => validateProjectionEntry(ontology, resolved, policy, entry);
|
|
3124
3124
|
}
|
|
3125
|
+
function validateProjectionRootRef(resolved, root) {
|
|
3126
|
+
const definition = resolved.definition;
|
|
3127
|
+
const owned = definition._tag === "ObjectProjectionDefinition" ? root.kind === "object" && root.ref.objectTypeId === definition.objectTypeId : root.kind === "link" && root.ref.source.objectTypeId === definition.sourceObjectTypeId && root.ref.target.objectTypeId === definition.targetObjectTypeId && root.ref.linkId === definition.linkId;
|
|
3128
|
+
if (!owned)
|
|
3129
|
+
throw new MaterializationValidationError2("Projection root is outside its owned type or link scope.");
|
|
3130
|
+
}
|
|
3125
3131
|
function createValidationPolicy(resolved) {
|
|
3126
3132
|
const ownedProperties = new Map(resolved.ownership.objects.map((object) => [object.objectTypeId, new Set(object.propertyIds)]));
|
|
3127
3133
|
const ownedLinks = new Set(resolved.ownership.links.map((link) => linkOwnershipKey(link.sourceObjectTypeId, link.linkId)));
|
|
@@ -3150,7 +3156,7 @@ function validateProjectionEntry(ontology, resolved, policy, entry) {
|
|
|
3150
3156
|
function validateProjectionRoot(resolved, policy, entry) {
|
|
3151
3157
|
if (entry.root.kind === policy.expectedRootKind)
|
|
3152
3158
|
return;
|
|
3153
|
-
throw new
|
|
3159
|
+
throw new MaterializationValidationError2(`Projection '${resolved.projectionId}' requires ${policy.expectedRootDescription} root.`);
|
|
3154
3160
|
}
|
|
3155
3161
|
function validateProjectionAssertion(ontology, resolved, policy, assertion) {
|
|
3156
3162
|
if (assertion.kind === "object") {
|
|
@@ -3160,21 +3166,21 @@ function validateProjectionAssertion(ontology, resolved, policy, assertion) {
|
|
|
3160
3166
|
}
|
|
3161
3167
|
function validateObjectAssertion(ontology, resolved, policy, assertion) {
|
|
3162
3168
|
if (resolved.definition._tag !== "ObjectProjectionDefinition" || assertion.ref.objectTypeId !== resolved.definition.objectTypeId) {
|
|
3163
|
-
throw new
|
|
3169
|
+
throw new MaterializationValidationError2("Projection asserted an object outside its owned type.");
|
|
3164
3170
|
}
|
|
3165
3171
|
const properties = validateObjectAuthorityProperties(ontology, assertion.ref, assertion.properties);
|
|
3166
3172
|
const owned = policy.ownedProperties.get(assertion.ref.objectTypeId) ?? new Set;
|
|
3167
3173
|
for (const propertyId of Object.keys(properties)) {
|
|
3168
3174
|
if (owned.has(propertyId))
|
|
3169
3175
|
continue;
|
|
3170
|
-
throw new
|
|
3176
|
+
throw new MaterializationValidationError2(`Projection '${resolved.projectionId}' asserted unowned property '${assertion.ref.objectTypeId}.${propertyId}'.`);
|
|
3171
3177
|
}
|
|
3172
3178
|
const conflictResolution = resolved.definition.conflictResolution ?? { strategy: "editsWin" };
|
|
3173
3179
|
if (conflictResolution.strategy !== "mostRecent") {
|
|
3174
3180
|
return { kind: "object", ref: assertion.ref, properties };
|
|
3175
3181
|
}
|
|
3176
3182
|
if (assertion.sourceUpdatedAt === undefined) {
|
|
3177
|
-
throw new
|
|
3183
|
+
throw new MaterializationValidationError2(`Projection '${resolved.projectionId}' requires source update timestamp ` + `'${conflictResolution.sourceTimestamp}' on every object assertion.`);
|
|
3178
3184
|
}
|
|
3179
3185
|
const primaryPropertyId = ontology.getPrimaryPropertyId(assertion.ref.objectTypeId);
|
|
3180
3186
|
const absentSourcePropertyIds = [...owned].filter((propertyId) => propertyId !== primaryPropertyId && !Object.hasOwn(properties, propertyId)).sort();
|
|
@@ -3189,15 +3195,15 @@ function validateObjectAssertion(ontology, resolved, policy, assertion) {
|
|
|
3189
3195
|
function validateLinkAssertion(ontology, resolved, policy, assertion) {
|
|
3190
3196
|
const ownershipKey = linkOwnershipKey(assertion.ref.source.objectTypeId, assertion.ref.linkId);
|
|
3191
3197
|
if (!policy.ownedLinks.has(ownershipKey)) {
|
|
3192
|
-
throw new
|
|
3198
|
+
throw new MaterializationValidationError2("Projection asserted a link outside its owned scope.");
|
|
3193
3199
|
}
|
|
3194
3200
|
const expectedTargetTypeId = projectionLinkTargetType(resolved, assertion);
|
|
3195
3201
|
if (expectedTargetTypeId !== assertion.ref.target.objectTypeId) {
|
|
3196
|
-
throw new
|
|
3202
|
+
throw new MaterializationValidationError2(`Projection '${resolved.projectionId}' asserted link target type '${assertion.ref.target.objectTypeId}' outside its mapping.`);
|
|
3197
3203
|
}
|
|
3198
3204
|
validateLinkAuthorityProperties(ontology, assertion.ref, assertion.properties);
|
|
3199
3205
|
if (assertion.properties !== undefined) {
|
|
3200
|
-
throw new
|
|
3206
|
+
throw new MaterializationValidationError2(`Projection '${resolved.projectionId}' does not map link assertion properties.`);
|
|
3201
3207
|
}
|
|
3202
3208
|
return { ...assertion };
|
|
3203
3209
|
}
|
|
@@ -3251,9 +3257,9 @@ function planReplacementObject(context, input, state, counts) {
|
|
|
3251
3257
|
commitId: input.identity.commitId,
|
|
3252
3258
|
committedAt: input.identity.committedAt
|
|
3253
3259
|
});
|
|
3254
|
-
const sortKey =
|
|
3260
|
+
const sortKey = objectRefSortKey2(state.ref);
|
|
3255
3261
|
const work = [
|
|
3256
|
-
classificationWork("object",
|
|
3262
|
+
classificationWork("object", objectRefKey2(state.ref), sortKey),
|
|
3257
3263
|
{
|
|
3258
3264
|
kind: "object-existence",
|
|
3259
3265
|
recordKey: `existence:${sortKey}`,
|
|
@@ -3307,9 +3313,9 @@ async function loadEndpointExistence(context, storage, session, page) {
|
|
|
3307
3313
|
session,
|
|
3308
3314
|
refs: [...endpointRefs.values()]
|
|
3309
3315
|
})) {
|
|
3310
|
-
endpointExistence.set(
|
|
3316
|
+
endpointExistence.set(objectRefKey2(value.ref), value.exists);
|
|
3311
3317
|
}
|
|
3312
|
-
const missingEndpoints = [...endpointRefs.values()].filter((ref) => !endpointExistence.has(
|
|
3318
|
+
const missingEndpoints = [...endpointRefs.values()].filter((ref) => !endpointExistence.has(objectRefKey2(ref)));
|
|
3313
3319
|
if (missingEndpoints.length === 0)
|
|
3314
3320
|
return endpointExistence;
|
|
3315
3321
|
for await (const endpointPage of storage.streamState({
|
|
@@ -3324,7 +3330,7 @@ async function loadEndpointExistence(context, storage, session, page) {
|
|
|
3324
3330
|
pageRows: context.batching.statePageRows
|
|
3325
3331
|
})) {
|
|
3326
3332
|
for (const endpoint of endpointPage.objects) {
|
|
3327
|
-
endpointExistence.set(
|
|
3333
|
+
endpointExistence.set(objectRefKey2(endpoint.ref), endpoint.effective !== null);
|
|
3328
3334
|
}
|
|
3329
3335
|
}
|
|
3330
3336
|
return endpointExistence;
|
|
@@ -3332,8 +3338,8 @@ async function loadEndpointExistence(context, storage, session, page) {
|
|
|
3332
3338
|
function collectEndpointRefs(links) {
|
|
3333
3339
|
const refs = new Map;
|
|
3334
3340
|
for (const state of links) {
|
|
3335
|
-
refs.set(
|
|
3336
|
-
refs.set(
|
|
3341
|
+
refs.set(objectRefKey2(state.ref.source), state.ref.source);
|
|
3342
|
+
refs.set(objectRefKey2(state.ref.target), state.ref.target);
|
|
3337
3343
|
}
|
|
3338
3344
|
return refs;
|
|
3339
3345
|
}
|
|
@@ -3355,8 +3361,8 @@ function planReplacementLink(context, input, state, endpointExistence, counts) {
|
|
|
3355
3361
|
commitId: input.identity.commitId,
|
|
3356
3362
|
committedAt: input.identity.committedAt
|
|
3357
3363
|
});
|
|
3358
|
-
const sortKey =
|
|
3359
|
-
work.push(classificationWork("link",
|
|
3364
|
+
const sortKey = linkRefSortKey2(state.ref);
|
|
3365
|
+
work.push(classificationWork("link", linkRefKey2(state.ref), sortKey));
|
|
3360
3366
|
if (!change) {
|
|
3361
3367
|
counts.linksUnchanged += 1;
|
|
3362
3368
|
return work;
|
|
@@ -3374,23 +3380,23 @@ function resolveReplacementLink(context, state, endpointExistence) {
|
|
|
3374
3380
|
ref: state.ref,
|
|
3375
3381
|
source: state.candidateSource,
|
|
3376
3382
|
override: usableLinkSlotOverride(state.slotOverride),
|
|
3377
|
-
endpointExists: (ref) => endpointExistence.get(
|
|
3383
|
+
endpointExists: (ref) => endpointExistence.get(objectRefKey2(ref)) ?? false
|
|
3378
3384
|
});
|
|
3379
3385
|
}
|
|
3380
3386
|
return resolveEffectiveLink({
|
|
3381
3387
|
ref: state.ref,
|
|
3382
3388
|
source: state.candidateSource,
|
|
3383
3389
|
override: state.override?.value ?? null,
|
|
3384
|
-
sourceEndpointExists: endpointExistence.get(
|
|
3385
|
-
targetEndpointExists: endpointExistence.get(
|
|
3390
|
+
sourceEndpointExists: endpointExistence.get(objectRefKey2(state.ref.source)) ?? false,
|
|
3391
|
+
targetEndpointExists: endpointExistence.get(objectRefKey2(state.ref.target)) ?? false
|
|
3386
3392
|
});
|
|
3387
3393
|
}
|
|
3388
3394
|
function cardinalityWork(context, state, occupied) {
|
|
3389
3395
|
const definition = context.ontology.resolveObjectType(state.ref.source.objectTypeId).links.find((candidate) => candidate.id === state.ref.linkId);
|
|
3390
3396
|
if (definition?.cardinality !== "one")
|
|
3391
3397
|
return [];
|
|
3392
|
-
const scopeSortKey =
|
|
3393
|
-
const linkSortKey =
|
|
3398
|
+
const scopeSortKey = linkScopeSortKey2(state.ref.source, state.ref.linkId);
|
|
3399
|
+
const linkSortKey = linkRefSortKey2(state.ref);
|
|
3394
3400
|
return [
|
|
3395
3401
|
{
|
|
3396
3402
|
kind: "cardinality",
|
|
@@ -3478,14 +3484,24 @@ async function stageProjectionMaterialization(context, input) {
|
|
|
3478
3484
|
projectionRevision: input.projectionRevision,
|
|
3479
3485
|
ownershipHash: input.ownershipHash,
|
|
3480
3486
|
ontologyRevision: context.projectionRegistry.ontologyRevision,
|
|
3481
|
-
createdAt: input.createdAt
|
|
3487
|
+
createdAt: input.createdAt,
|
|
3488
|
+
...input.base ? { base: input.base } : {}
|
|
3482
3489
|
});
|
|
3483
3490
|
let rootCount = 0;
|
|
3484
3491
|
let assertionCount = 0;
|
|
3485
3492
|
async function* assertions() {
|
|
3486
3493
|
for await (const rawEntry of input.entries) {
|
|
3487
3494
|
throwIfAborted(input.signal);
|
|
3488
|
-
|
|
3495
|
+
if ("deleted" in rawEntry) {
|
|
3496
|
+
if (!input.base || rawEntry.deleted !== true) {
|
|
3497
|
+
throw new MaterializationValidationError2("Explicit root deletions require a pinned source base.");
|
|
3498
|
+
}
|
|
3499
|
+
const root = normalizeProjectionEntity(rawEntry.root);
|
|
3500
|
+
validateProjectionRootRef(context.projectionRegistry.resolveSource(input.source.projectionId), root);
|
|
3501
|
+
yield { root, stagingOrdinal: rootCount++ };
|
|
3502
|
+
continue;
|
|
3503
|
+
}
|
|
3504
|
+
const entry = input.validateEntry(normalizeProjectionSourceEntry2(rawEntry));
|
|
3489
3505
|
const stagingOrdinal = rootCount;
|
|
3490
3506
|
for (const assertion of entry.assertions) {
|
|
3491
3507
|
assertionCount += 1;
|
|
@@ -3505,7 +3521,8 @@ async function stageProjectionMaterialization(context, input) {
|
|
|
3505
3521
|
source: input.source,
|
|
3506
3522
|
materializationId: input.materializationId,
|
|
3507
3523
|
execution: input.execution,
|
|
3508
|
-
rows
|
|
3524
|
+
rows: rows.filter((row) => ("assertion" in row)),
|
|
3525
|
+
deletions: rows.filter((row) => !("assertion" in row))
|
|
3509
3526
|
});
|
|
3510
3527
|
}
|
|
3511
3528
|
await context.storage.ontology.sources.markReady({
|
|
@@ -3538,7 +3555,7 @@ async function replaceProjection(context, raw) {
|
|
|
3538
3555
|
function prepareProjectionReplacement(context, raw) {
|
|
3539
3556
|
const source = normalizeProjectionSourceRef(raw.input.source);
|
|
3540
3557
|
const datasetVersion = normalizePinnedDatasetVersion(raw.input.datasetVersion);
|
|
3541
|
-
const execution =
|
|
3558
|
+
const execution = normalizeProjectionExecution2(raw.input.execution);
|
|
3542
3559
|
const resolved = context.projectionRegistry.resolveSource(source.projectionId);
|
|
3543
3560
|
validateProjectionDataset(resolved, datasetVersion);
|
|
3544
3561
|
const projectionKind = sourceProjectionKind(resolved);
|
|
@@ -3547,9 +3564,9 @@ function prepareProjectionReplacement(context, raw) {
|
|
|
3547
3564
|
datasetVersion,
|
|
3548
3565
|
ontologyRevision: context.projectionRegistry.ontologyRevision
|
|
3549
3566
|
});
|
|
3550
|
-
const identity =
|
|
3567
|
+
const identity = createCommitIdentity2({
|
|
3551
3568
|
projectId: context.projectId,
|
|
3552
|
-
idempotencyKey:
|
|
3569
|
+
idempotencyKey: createProjectionIdempotencyKey2(runIdentity),
|
|
3553
3570
|
normalizedCallerIntent: { source, datasetVersion }
|
|
3554
3571
|
});
|
|
3555
3572
|
const command = {
|
|
@@ -3557,6 +3574,7 @@ function prepareProjectionReplacement(context, raw) {
|
|
|
3557
3574
|
datasetVersion,
|
|
3558
3575
|
execution,
|
|
3559
3576
|
entries: raw.input.entries,
|
|
3577
|
+
...raw.input.base ? { base: Object.freeze({ ...raw.input.base }) } : {},
|
|
3560
3578
|
resolved,
|
|
3561
3579
|
projectionKind,
|
|
3562
3580
|
runIdentity,
|
|
@@ -3570,7 +3588,7 @@ function prepareProjectionReplacement(context, raw) {
|
|
|
3570
3588
|
function validateProjectionDataset(resolved, datasetVersion) {
|
|
3571
3589
|
if (datasetVersion.datasetId === resolved.datasetId)
|
|
3572
3590
|
return;
|
|
3573
|
-
throw new
|
|
3591
|
+
throw new MaterializationValidationError2(`Projection '${resolved.projectionId}' requires dataset '${resolved.datasetId}'.`);
|
|
3574
3592
|
}
|
|
3575
3593
|
function sourceProjectionKind(resolved) {
|
|
3576
3594
|
if (resolved.definition._tag === "ObjectProjectionDefinition")
|
|
@@ -3605,7 +3623,7 @@ async function admitProjectionExecution(context, command) {
|
|
|
3605
3623
|
}
|
|
3606
3624
|
function projectionReplayResult(commit, command) {
|
|
3607
3625
|
if (commit.origin.kind !== "projection" || commit.origin.projectionRunId !== command.execution.projectionRunId || commit.result.kind !== "projection") {
|
|
3608
|
-
throw new
|
|
3626
|
+
throw new MaterializationConflictError2("run-correlation", `Projection commit '${commit.id}' belongs to a different logical run.`);
|
|
3609
3627
|
}
|
|
3610
3628
|
return { ...structuredClone(commit.result), created: false };
|
|
3611
3629
|
}
|
|
@@ -3622,6 +3640,7 @@ async function prepareProjectionCandidate(context, command) {
|
|
|
3622
3640
|
source: command.source
|
|
3623
3641
|
});
|
|
3624
3642
|
validateProjectionWatermark(active, command.datasetVersion);
|
|
3643
|
+
assertDeltaBase(active, command);
|
|
3625
3644
|
return {
|
|
3626
3645
|
materializationId: context.materializationId(),
|
|
3627
3646
|
createdAt: context.clock().toISOString(),
|
|
@@ -3643,13 +3662,14 @@ async function stageProjectionCandidate(context, command, candidate) {
|
|
|
3643
3662
|
ownershipHash: command.resolved.ownershipHash,
|
|
3644
3663
|
createdAt: candidate.createdAt,
|
|
3645
3664
|
entries: command.entries,
|
|
3665
|
+
...command.base ? { base: command.base } : {},
|
|
3646
3666
|
validateEntry: createProjectionEntryValidator(context.ontology, command.resolved)
|
|
3647
3667
|
};
|
|
3648
3668
|
const staged = await stageCandidateEntries(context, input, command.signal);
|
|
3649
3669
|
return {
|
|
3650
3670
|
...candidate,
|
|
3651
3671
|
staged,
|
|
3652
|
-
identity:
|
|
3672
|
+
identity: timestampCommitIdentity2(command.identity, context.clock())
|
|
3653
3673
|
};
|
|
3654
3674
|
}
|
|
3655
3675
|
async function stageCandidateEntries(context, input, signal) {
|
|
@@ -3666,6 +3686,14 @@ async function executeProjectionTransaction(context, storage, command, ready) {
|
|
|
3666
3686
|
const replay = await replayCommitRecord(context, command.identity, command.scopeExecution.executionId, storage);
|
|
3667
3687
|
if (replay)
|
|
3668
3688
|
return projectionReplayResult(replay, command);
|
|
3689
|
+
if (command.base) {
|
|
3690
|
+
const active = await storage.ontology.sources.getActive({
|
|
3691
|
+
projectId: context.projectId,
|
|
3692
|
+
source: command.source
|
|
3693
|
+
});
|
|
3694
|
+
validateProjectionWatermark(active, command.datasetVersion);
|
|
3695
|
+
assertDeltaBase(active, command);
|
|
3696
|
+
}
|
|
3669
3697
|
const origin = projectionOrigin(command);
|
|
3670
3698
|
throwIfAborted(command.signal);
|
|
3671
3699
|
const session = await storage.ontology.materializations.begin({
|
|
@@ -3772,16 +3800,21 @@ async function abandonFailedCandidate(context, command, candidate, error) {
|
|
|
3772
3800
|
});
|
|
3773
3801
|
}
|
|
3774
3802
|
function shouldAbandonCandidate(error) {
|
|
3775
|
-
if (error instanceof
|
|
3803
|
+
if (error instanceof MaterializationValidationError2)
|
|
3776
3804
|
return true;
|
|
3777
|
-
if (error instanceof
|
|
3805
|
+
if (error instanceof MaterializationCancellationError2)
|
|
3778
3806
|
return true;
|
|
3779
|
-
return error instanceof
|
|
3807
|
+
return error instanceof MaterializationConflictError2 && (error.kind === "run-correlation" || error.kind === "idempotency");
|
|
3780
3808
|
}
|
|
3781
3809
|
function validateProjectionWatermark(active, next) {
|
|
3782
3810
|
if (!active)
|
|
3783
3811
|
return;
|
|
3784
|
-
|
|
3812
|
+
assertPinnedDatasetWatermark2(active.datasetVersion, next, "Projection replacement");
|
|
3813
|
+
}
|
|
3814
|
+
function assertDeltaBase(active, command) {
|
|
3815
|
+
if (command.base && (!active || active.materializationId !== command.base.materializationId || active.lastCommitId !== command.base.lastCommitId || active.projectionRevision !== command.runIdentity.projectionRevision || active.ontologyRevision !== command.runIdentity.ontologyRevision || active.ownershipHash !== command.runIdentity.ownershipHash)) {
|
|
3816
|
+
throw new MaterializationConflictError2("source-materialization", "Projection delta no longer matches the active source or its definition.");
|
|
3817
|
+
}
|
|
3785
3818
|
}
|
|
3786
3819
|
|
|
3787
3820
|
// src/materializer/telemetry/plan.ts
|
|
@@ -3791,9 +3824,9 @@ async function planTelemetryAppend(context, storage, session, input, identity, o
|
|
|
3791
3824
|
const objects = await loadTelemetryObjects(context, storage, session, input.points);
|
|
3792
3825
|
const existingPoints = await loadExistingPoints(context, storage, session, input.points);
|
|
3793
3826
|
for (const group of telemetryObjectGroups(input.points)) {
|
|
3794
|
-
const storedObject = objects.get(
|
|
3827
|
+
const storedObject = objects.get(objectRefKey2(group.objectRef));
|
|
3795
3828
|
if (!storedObject?.effective) {
|
|
3796
|
-
throw new
|
|
3829
|
+
throw new MaterializationObjectNotFoundError2(group.objectRef.objectTypeId, group.objectRef.primaryId);
|
|
3797
3830
|
}
|
|
3798
3831
|
await planTelemetryObject(context, storage, session, planContext, group, workingObjectFromState(storedObject), existingPoints, counts);
|
|
3799
3832
|
}
|
|
@@ -3803,9 +3836,9 @@ function* telemetryObjectGroups(points) {
|
|
|
3803
3836
|
let start = 0;
|
|
3804
3837
|
while (start < points.length) {
|
|
3805
3838
|
const objectRef = points[start].series.object;
|
|
3806
|
-
const objectKey =
|
|
3839
|
+
const objectKey = objectRefKey2(objectRef);
|
|
3807
3840
|
let end = start + 1;
|
|
3808
|
-
while (end < points.length &&
|
|
3841
|
+
while (end < points.length && objectRefKey2(points[end].series.object) === objectKey) {
|
|
3809
3842
|
end += 1;
|
|
3810
3843
|
}
|
|
3811
3844
|
yield { objectRef, start, end };
|
|
@@ -3826,7 +3859,7 @@ async function planTelemetryObject(context, storage, session, planContext, group
|
|
|
3826
3859
|
async function loadTelemetryObjects(context, storage, session, points) {
|
|
3827
3860
|
const refs = new Map;
|
|
3828
3861
|
for (const point of points)
|
|
3829
|
-
refs.set(
|
|
3862
|
+
refs.set(objectRefKey2(point.series.object), point.series.object);
|
|
3830
3863
|
const objectState = await loadState(context, storage, session, {
|
|
3831
3864
|
objects: [...refs.values()],
|
|
3832
3865
|
links: [],
|
|
@@ -3834,7 +3867,7 @@ async function loadTelemetryObjects(context, storage, session, points) {
|
|
|
3834
3867
|
incidentObjects: [],
|
|
3835
3868
|
points: []
|
|
3836
3869
|
});
|
|
3837
|
-
return new Map(objectState.objects.map((object) => [
|
|
3870
|
+
return new Map(objectState.objects.map((object) => [objectRefKey2(object.ref), object]));
|
|
3838
3871
|
}
|
|
3839
3872
|
function planTelemetryChunk(context, planContext, points, existingPoints, latest, counts) {
|
|
3840
3873
|
const work = [];
|
|
@@ -3857,15 +3890,15 @@ async function loadExistingPoints(context, storage, session, points) {
|
|
|
3857
3890
|
pageRows: context.batching.statePageRows
|
|
3858
3891
|
})) {
|
|
3859
3892
|
for (const existing of page.points) {
|
|
3860
|
-
existingPoints.set(
|
|
3893
|
+
existingPoints.set(telemetryPointKey2(existing.series, existing.at), existing);
|
|
3861
3894
|
}
|
|
3862
3895
|
}
|
|
3863
3896
|
context.observeCoreBuffer?.("telemetry.existing-points", existingPoints.size);
|
|
3864
3897
|
return existingPoints;
|
|
3865
3898
|
}
|
|
3866
3899
|
function planTelemetryPoint(context, planContext, point, existingPoints, latest, counts) {
|
|
3867
|
-
const identityKey =
|
|
3868
|
-
const sortKey =
|
|
3900
|
+
const identityKey = telemetryPointKey2(point.series, point.at);
|
|
3901
|
+
const sortKey = telemetryPointSortKey2(point.series, point.at);
|
|
3869
3902
|
const existing = existingPoints.get(identityKey);
|
|
3870
3903
|
const unchanged = telemetryPointUnchanged(existing, point);
|
|
3871
3904
|
const work = [classificationWork("point", identityKey, sortKey)];
|
|
@@ -3882,7 +3915,7 @@ function planTelemetryPoint(context, planContext, point, existingPoints, latest,
|
|
|
3882
3915
|
function telemetryPointUnchanged(existing, point) {
|
|
3883
3916
|
if (!existing)
|
|
3884
3917
|
return false;
|
|
3885
|
-
return
|
|
3918
|
+
return stableJsonStringify2({ value: existing.value, unit: existing.unit ?? null }) === stableJsonStringify2({ value: point.value, unit: point.unit ?? null });
|
|
3886
3919
|
}
|
|
3887
3920
|
function countTelemetryPointChange(counts, existing) {
|
|
3888
3921
|
if (existing)
|
|
@@ -3948,9 +3981,9 @@ async function stageTelemetryObjectPlan(context, storage, session, planContext,
|
|
|
3948
3981
|
commitId: planContext.identity.commitId,
|
|
3949
3982
|
committedAt: planContext.identity.committedAt
|
|
3950
3983
|
});
|
|
3951
|
-
const sortKey =
|
|
3984
|
+
const sortKey = objectRefSortKey2(working.ref);
|
|
3952
3985
|
const work = [
|
|
3953
|
-
classificationWork("object",
|
|
3986
|
+
classificationWork("object", objectRefKey2(working.ref), sortKey)
|
|
3954
3987
|
];
|
|
3955
3988
|
if (change) {
|
|
3956
3989
|
counts.latestObjectsChanged += 1;
|
|
@@ -3990,7 +4023,7 @@ async function appendTelemetry(context, raw) {
|
|
|
3990
4023
|
}
|
|
3991
4024
|
function prepareTelemetryAppend(context, raw) {
|
|
3992
4025
|
const rawInputPointCount = raw.input.points.length;
|
|
3993
|
-
const input =
|
|
4026
|
+
const input = normalizeTelemetryAppend2({
|
|
3994
4027
|
...raw.input,
|
|
3995
4028
|
points: raw.input.points.map((point) => validateTelemetryPoint(context.ontology, point))
|
|
3996
4029
|
});
|
|
@@ -4014,9 +4047,9 @@ function telemetryInputPointCount(input, rawInputPointCount) {
|
|
|
4014
4047
|
return input.points.length;
|
|
4015
4048
|
}
|
|
4016
4049
|
function prepareRuntimeTelemetry(context, input, source, inputPointCount, ontologyRevision) {
|
|
4017
|
-
const identity =
|
|
4050
|
+
const identity = createTimedCommitIdentity2({
|
|
4018
4051
|
projectId: context.projectId,
|
|
4019
|
-
idempotencyKey:
|
|
4052
|
+
idempotencyKey: createRuntimeTelemetryIdempotencyKey2(source.requestId),
|
|
4020
4053
|
normalizedCallerIntent: input,
|
|
4021
4054
|
now: context.clock()
|
|
4022
4055
|
});
|
|
@@ -4032,9 +4065,9 @@ function prepareProjectionTelemetry(context, input, source, inputPointCount, ont
|
|
|
4032
4065
|
datasetVersion: source.datasetVersion,
|
|
4033
4066
|
ontologyRevision
|
|
4034
4067
|
});
|
|
4035
|
-
const identity =
|
|
4068
|
+
const identity = createTimedCommitIdentity2({
|
|
4036
4069
|
projectId: context.projectId,
|
|
4037
|
-
idempotencyKey:
|
|
4070
|
+
idempotencyKey: createProjectionTelemetryIdempotencyKey2(runIdentity, source.batchOrdinal),
|
|
4038
4071
|
normalizedCallerIntent: projectionTelemetryCallerIntent(input, source, inputPointCount),
|
|
4039
4072
|
now: context.clock()
|
|
4040
4073
|
});
|
|
@@ -4051,25 +4084,25 @@ function prepareProjectionTelemetry(context, input, source, inputPointCount, ont
|
|
|
4051
4084
|
}
|
|
4052
4085
|
function validateTelemetryBatchCardinality(resolved, source, inputPointCount) {
|
|
4053
4086
|
if (source.sourceRowCount === 0) {
|
|
4054
|
-
throw new
|
|
4087
|
+
throw new MaterializationValidationError2("Projection telemetry batches must consume at least one source row; an empty dataset produces no batch commit.");
|
|
4055
4088
|
}
|
|
4056
4089
|
const mappedPropertyCount = resolved.ownership.telemetry.length;
|
|
4057
4090
|
if (mappedPropertyCount === 0) {
|
|
4058
|
-
throw new
|
|
4091
|
+
throw new MaterializationValidationError2(`Telemetry projection '${resolved.projectionId}' must own at least one telemetry property.`);
|
|
4059
4092
|
}
|
|
4060
4093
|
const sourceRowsEmitted = source.sourceRowCount - source.sourceRowsSkipped;
|
|
4061
4094
|
const maximumPointCount = sourceRowsEmitted * mappedPropertyCount;
|
|
4062
4095
|
if (!Number.isSafeInteger(maximumPointCount)) {
|
|
4063
|
-
throw new
|
|
4096
|
+
throw new MaterializationValidationError2(`Telemetry projection '${resolved.projectionId}' batch point capacity exceeds the safe integer range.`);
|
|
4064
4097
|
}
|
|
4065
4098
|
if (inputPointCount < sourceRowsEmitted || inputPointCount > maximumPointCount) {
|
|
4066
|
-
throw new
|
|
4099
|
+
throw new MaterializationValidationError2(`Telemetry projection '${resolved.projectionId}' must emit between ${sourceRowsEmitted} and ${maximumPointCount} points for ${source.sourceRowCount} source rows with ${source.sourceRowsSkipped} skipped.`);
|
|
4067
4100
|
}
|
|
4068
4101
|
}
|
|
4069
4102
|
function validateTelemetryProjectionDataset(resolved, source) {
|
|
4070
4103
|
if (resolved.datasetId === source.datasetVersion.datasetId)
|
|
4071
4104
|
return;
|
|
4072
|
-
throw new
|
|
4105
|
+
throw new MaterializationValidationError2(`Telemetry projection '${resolved.projectionId}' requires dataset '${resolved.datasetId}'.`);
|
|
4073
4106
|
}
|
|
4074
4107
|
function validateTelemetryOwnership(resolved, input) {
|
|
4075
4108
|
const ownedSeries = new Set(resolved.ownership.telemetry.map(({ objectTypeId, propertyId }) => telemetryOwnershipKey(objectTypeId, propertyId)));
|
|
@@ -4077,7 +4110,7 @@ function validateTelemetryOwnership(resolved, input) {
|
|
|
4077
4110
|
const scope = telemetryOwnershipKey(point.series.object.objectTypeId, point.series.propertyId);
|
|
4078
4111
|
if (ownedSeries.has(scope))
|
|
4079
4112
|
continue;
|
|
4080
|
-
throw new
|
|
4113
|
+
throw new MaterializationValidationError2(`Telemetry projection '${resolved.projectionId}' does not own series '${point.series.object.objectTypeId}.${point.series.propertyId}'.`);
|
|
4081
4114
|
}
|
|
4082
4115
|
}
|
|
4083
4116
|
function projectionTelemetryCallerIntent(input, source, inputPointCount) {
|
|
@@ -4121,30 +4154,30 @@ async function assertTelemetryExecution(storage, projectId, command) {
|
|
|
4121
4154
|
function assertTelemetryBatchPosition(run, batchOrdinal, sourceRowCount, inputExhausted) {
|
|
4122
4155
|
const checkpoint = run.telemetryCheckpoint;
|
|
4123
4156
|
if (!checkpoint) {
|
|
4124
|
-
throw new
|
|
4157
|
+
throw new MaterializationValidationError2(`Telemetry projection run '${run.id}' has incomplete checkpoint state.`);
|
|
4125
4158
|
}
|
|
4126
4159
|
if (batchOrdinal > checkpoint.nextBatchOrdinal) {
|
|
4127
|
-
throw new
|
|
4160
|
+
throw new MaterializationValidationError2(`Telemetry projection run '${run.id}' expected batch ordinal ${checkpoint.nextBatchOrdinal}, got ${batchOrdinal}.`);
|
|
4128
4161
|
}
|
|
4129
4162
|
if (checkpoint.inputExhausted && batchOrdinal >= checkpoint.nextBatchOrdinal) {
|
|
4130
|
-
throw new
|
|
4163
|
+
throw new MaterializationValidationError2(`Telemetry projection run '${run.id}' has already exhausted its input.`);
|
|
4131
4164
|
}
|
|
4132
4165
|
if (sourceRowCount > checkpoint.fixedBatchSize) {
|
|
4133
|
-
throw new
|
|
4166
|
+
throw new MaterializationValidationError2(`Telemetry projection run '${run.id}' batch exceeds its fixed size.`);
|
|
4134
4167
|
}
|
|
4135
4168
|
if (!inputExhausted && sourceRowCount !== checkpoint.fixedBatchSize) {
|
|
4136
|
-
throw new
|
|
4169
|
+
throw new MaterializationValidationError2(`Telemetry projection run '${run.id}' cannot advance past a partial non-final batch.`);
|
|
4137
4170
|
}
|
|
4138
4171
|
}
|
|
4139
4172
|
function assertTelemetryReplayCheckpoint(run, batchOrdinal) {
|
|
4140
4173
|
if (!run.telemetryCheckpoint || batchOrdinal >= run.telemetryCheckpoint.nextBatchOrdinal) {
|
|
4141
|
-
throw new
|
|
4174
|
+
throw new MaterializationValidationError2(`Telemetry commit batch ${batchOrdinal} exists without an advanced run checkpoint.`);
|
|
4142
4175
|
}
|
|
4143
4176
|
}
|
|
4144
4177
|
function telemetryProjectionReplayResult(commit, command) {
|
|
4145
4178
|
const origin = commit.origin;
|
|
4146
4179
|
if (origin.kind !== "telemetry" || origin.source.kind !== "projection" || origin.source.projectionRunId !== command.source.execution.projectionRunId || origin.source.batchOrdinal !== command.source.batchOrdinal || commit.result.kind !== "telemetry") {
|
|
4147
|
-
throw new
|
|
4180
|
+
throw new MaterializationConflictError2("run-correlation", `Telemetry commit '${commit.id}' belongs to a different logical run or batch.`);
|
|
4148
4181
|
}
|
|
4149
4182
|
return { ...structuredClone(commit.result), created: false };
|
|
4150
4183
|
}
|
|
@@ -4164,7 +4197,7 @@ async function executeTelemetryTransaction(context, storage, command) {
|
|
|
4164
4197
|
}
|
|
4165
4198
|
if (command.kind === "projection") {
|
|
4166
4199
|
if (!execution?.run.telemetryCheckpoint || execution.run.telemetryCheckpoint.nextBatchOrdinal !== command.source.batchOrdinal) {
|
|
4167
|
-
throw new
|
|
4200
|
+
throw new MaterializationValidationError2(`Telemetry projection batch ${command.source.batchOrdinal} is behind its run checkpoint.`);
|
|
4168
4201
|
}
|
|
4169
4202
|
}
|
|
4170
4203
|
const origin = telemetryOrigin(command);
|
|
@@ -4270,7 +4303,7 @@ async function finalizeTelemetryMaterialization(storage, session, command, resul
|
|
|
4270
4303
|
});
|
|
4271
4304
|
if (command.kind === "projection") {
|
|
4272
4305
|
if (!projectionRuns) {
|
|
4273
|
-
throw new
|
|
4306
|
+
throw new MaterializationValidationError2("Expected an asserted telemetry projection run.");
|
|
4274
4307
|
}
|
|
4275
4308
|
await projectionRuns.advanceTelemetryCheckpoint({
|
|
4276
4309
|
id: command.source.execution.projectionRunId,
|
|
@@ -4287,11 +4320,15 @@ async function finalizeTelemetryMaterialization(storage, session, command, resul
|
|
|
4287
4320
|
}
|
|
4288
4321
|
|
|
4289
4322
|
// src/materializer/materializer.ts
|
|
4290
|
-
class
|
|
4323
|
+
class OntologyMaterializer2 {
|
|
4291
4324
|
edits = {
|
|
4292
4325
|
commit: (command) => commitEdits(this.context, command)
|
|
4293
4326
|
};
|
|
4294
4327
|
projections = {
|
|
4328
|
+
getActive: (source) => this.context.storage.ontology.sources.getActive({
|
|
4329
|
+
projectId: this.context.projectId,
|
|
4330
|
+
source
|
|
4331
|
+
}),
|
|
4295
4332
|
replace: (command) => replaceProjection(this.context, command),
|
|
4296
4333
|
finishRun: (command) => finishProjectionRun(this.context, command)
|
|
4297
4334
|
};
|
|
@@ -4304,6 +4341,7 @@ class OntologyMaterializer {
|
|
|
4304
4341
|
commit: (input) => this.edits.commit({ scope, input })
|
|
4305
4342
|
}),
|
|
4306
4343
|
projections: Object.freeze({
|
|
4344
|
+
getActive: (source) => this.projections.getActive(source),
|
|
4307
4345
|
replace: (input) => this.projections.replace({ scope, input }),
|
|
4308
4346
|
finishRun: (input) => this.projections.finishRun({ scope, input })
|
|
4309
4347
|
}),
|
|
@@ -4323,9 +4361,9 @@ class OntologyMaterializer {
|
|
|
4323
4361
|
});
|
|
4324
4362
|
}
|
|
4325
4363
|
}
|
|
4326
|
-
function
|
|
4327
|
-
return new
|
|
4364
|
+
function createOntologyMaterializer2(input) {
|
|
4365
|
+
return new OntologyMaterializer2(input.projectId, input.ontology, input.projections, input.storage, input.dependencies);
|
|
4328
4366
|
}
|
|
4329
|
-
export {
|
|
4367
|
+
export { computeOntologyRevision2, computeProjectionRevision2, computeProjectionOwnershipHash2, ProjectionRegistry2, createActionIdempotencyKey2, createRuntimeIdempotencyKey2, createProjectionIdempotencyKey2, createRuntimeTelemetryIdempotencyKey2, createProjectionTelemetryIdempotencyKey2, createCommitIdentity2, timestampCommitIdentity2, createTimedCommitIdentity2, createProjectionMaterializationId2, createLinkScopeFingerprint2, normalizeJsonProperties2, normalizeOntologyEditCommit2, normalizeProjectionExecution2, normalizeProjectionSourceEntry2, normalizeTelemetryAppend2, OntologyMaterializer2, createOntologyMaterializer2 };
|
|
4330
4368
|
|
|
4331
|
-
//# debugId=
|
|
4369
|
+
//# debugId=45B690D58E462D3C64756E2164756E21
|