@tangle-network/agent-eval 0.187.2 → 0.189.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +95 -0
- package/dist/adapters/http.d.ts +2 -2
- package/dist/{agent-profile-uAIQK3Nr.d.ts → agent-profile-DNV_U6QR.d.ts} +4 -4
- package/dist/{agent-profile-uAIQK3Nr.d.ts.map → agent-profile-DNV_U6QR.d.ts.map} +1 -1
- package/dist/analyst/index.d.ts +12 -12
- package/dist/analyst/index.d.ts.map +1 -1
- package/dist/analyst/index.js +7 -7
- package/dist/{analyze-runs-DapYZz02.d.ts → analyze-runs-BvK4-wSs.d.ts} +5 -5
- package/dist/{analyze-runs-DapYZz02.d.ts.map → analyze-runs-BvK4-wSs.d.ts.map} +1 -1
- package/dist/{analyze-runs-DCY7LMt4.js → analyze-runs-SCSWYpy0.js} +17 -9
- package/dist/analyze-runs-SCSWYpy0.js.map +1 -0
- package/dist/{benchmark-command-DGokT8zd.js → benchmark-command-BhhAYstU.js} +14 -14
- package/dist/benchmark-command-BhhAYstU.js.map +1 -0
- package/dist/benchmarks/index.d.ts +4 -4
- package/dist/benchmarks/index.js +3 -3
- package/dist/builder-eval/index.d.ts +3 -3
- package/dist/builder-eval/index.js +1 -1
- package/dist/campaign/index.d.ts +5 -5
- package/dist/campaign/index.js +7 -7
- package/dist/{campaign-DlxdTOvw.js → campaign-BWoSQPSU.js} +10 -10
- package/dist/{campaign-DlxdTOvw.js.map → campaign-BWoSQPSU.js.map} +1 -1
- package/dist/{campaign-evidence-IF1p0oDa.js → campaign-evidence-CBlGJ3kC.js} +5 -5
- package/dist/campaign-evidence-CBlGJ3kC.js.map +1 -0
- package/dist/{chat-client-DqPqWzVV.js → chat-client-C4dg7Ng_.js} +2 -2
- package/dist/{chat-client-DqPqWzVV.js.map → chat-client-C4dg7Ng_.js.map} +1 -1
- package/dist/{chat-json-call-C-DnDxEy.js → chat-json-call-JVGbfx95.js} +2 -2
- package/dist/{chat-json-call-C-DnDxEy.js.map → chat-json-call-JVGbfx95.js.map} +1 -1
- package/dist/cli.js +4 -4
- package/dist/{client-DCc7a8ZC.d.ts → client-BhEyAdfe.d.ts} +4 -4
- package/dist/{client-DCc7a8ZC.d.ts.map → client-BhEyAdfe.d.ts.map} +1 -1
- package/dist/{client-CXE-U1SA.js → client-QwJpsNYU.js} +5 -1
- package/dist/client-QwJpsNYU.js.map +1 -0
- package/dist/contract/index.d.ts +11 -11
- package/dist/contract/index.js +22 -13
- package/dist/contract/index.js.map +1 -1
- package/dist/{counterfactual-CLgrwhkY.d.ts → counterfactual-CPaWN99-.d.ts} +4 -4
- package/dist/{counterfactual-CLgrwhkY.d.ts.map → counterfactual-CPaWN99-.d.ts.map} +1 -1
- package/dist/{counterfactual-Bjq1mlUu.js → counterfactual-DtMWvn7D.js} +2 -2
- package/dist/{counterfactual-Bjq1mlUu.js.map → counterfactual-DtMWvn7D.js.map} +1 -1
- package/dist/deep-freeze-CurcOQg3.js +16 -0
- package/dist/deep-freeze-CurcOQg3.js.map +1 -0
- package/dist/{default-registry-DMxeb4GD.d.ts → default-registry-B5HrwrPM.d.ts} +6 -6
- package/dist/{default-registry-DMxeb4GD.d.ts.map → default-registry-B5HrwrPM.d.ts.map} +1 -1
- package/dist/{default-registry-Ca2IWH1X.js → default-registry-m2jhbG6Q.js} +4 -3
- package/dist/default-registry-m2jhbG6Q.js.map +1 -0
- package/dist/{define-agent-eval-C0EqJ9Gz.js → define-agent-eval-98sgUaC1.js} +8 -8
- package/dist/{define-agent-eval-C0EqJ9Gz.js.map → define-agent-eval-98sgUaC1.js.map} +1 -1
- package/dist/{define-agent-eval-CGBwPPaq.d.ts → define-agent-eval-q6890HU4.d.ts} +7 -7
- package/dist/{define-agent-eval-CGBwPPaq.d.ts.map → define-agent-eval-q6890HU4.d.ts.map} +1 -1
- package/dist/diagnosis/index.d.ts +38 -96
- package/dist/diagnosis/index.d.ts.map +1 -1
- package/dist/diagnosis/index.js +84 -135
- package/dist/diagnosis/index.js.map +1 -1
- package/dist/{dspy-rlm-engine-BE9lCzzL.js → dspy-rlm-engine-DLYttKBm.js} +3 -3
- package/dist/{dspy-rlm-engine-BE9lCzzL.js.map → dspy-rlm-engine-DLYttKBm.js.map} +1 -1
- package/dist/emitter-DbMXUIVP.js +334 -0
- package/dist/emitter-DbMXUIVP.js.map +1 -0
- package/dist/{emitter-Cs0egaFd.d.ts → emitter-HcCmFQl_.d.ts} +37 -6
- package/dist/emitter-HcCmFQl_.d.ts.map +1 -0
- package/dist/{engine-DNlKhIm0.d.ts → engine-BkLCnZQX.d.ts} +15 -5
- package/dist/engine-BkLCnZQX.d.ts.map +1 -0
- package/dist/{eval-campaign-XFHEpN86.js → eval-campaign-C0Q1Eeo_.js} +8 -5
- package/dist/{eval-campaign-XFHEpN86.js.map → eval-campaign-C0Q1Eeo_.js.map} +1 -1
- package/dist/evaluation.d.ts +2 -2
- package/dist/{exact-types-BEHN7tnq.d.ts → exact-types-CfpP2A4Z.d.ts} +2 -2
- package/dist/{exact-types-BEHN7tnq.d.ts.map → exact-types-CfpP2A4Z.d.ts.map} +1 -1
- package/dist/experiment/index.d.ts +3 -3
- package/dist/experiment/index.js +2 -3
- package/dist/experiment/index.js.map +1 -1
- package/dist/{external-optimizer-process-BbhvXTFx.js → external-optimizer-process-C3quNeKV.js} +3 -3
- package/dist/{external-optimizer-process-BbhvXTFx.js.map → external-optimizer-process-C3quNeKV.js.map} +1 -1
- package/dist/{external-optimizer-subprocess-DMgmqTB6.js → external-optimizer-subprocess-BDwgKLO1.js} +3 -3
- package/dist/{external-optimizer-subprocess-DMgmqTB6.js.map → external-optimizer-subprocess-BDwgKLO1.js.map} +1 -1
- package/dist/{failure-cluster-OldNRoAt.d.ts → failure-cluster-CbgEDcFJ.d.ts} +3 -3
- package/dist/{failure-cluster-OldNRoAt.d.ts.map → failure-cluster-CbgEDcFJ.d.ts.map} +1 -1
- package/dist/failure-taxonomy-CjabTATj.js +538 -0
- package/dist/failure-taxonomy-CjabTATj.js.map +1 -0
- package/dist/{feedback-trajectory-CytTR7u4.d.ts → feedback-trajectory-B3ZSkfAq.d.ts} +6 -6
- package/dist/{feedback-trajectory-CytTR7u4.d.ts.map → feedback-trajectory-B3ZSkfAq.d.ts.map} +1 -1
- package/dist/hosted/index.d.ts +2 -2
- package/dist/hosted/index.d.ts.map +1 -1
- package/dist/hosted/index.js +1 -1
- package/dist/{index-vYNHCV2G.d.ts → index-2e_MTznj.d.ts} +8 -8
- package/dist/{index-vYNHCV2G.d.ts.map → index-2e_MTznj.d.ts.map} +1 -1
- package/dist/{index-CKZa_rnt.d.ts → index-Bcc9PkOz.d.ts} +3 -3
- package/dist/{index-CKZa_rnt.d.ts.map → index-Bcc9PkOz.d.ts.map} +1 -1
- package/dist/{index-u0d1Jp4F.d.ts → index-BqDJ6fUK.d.ts} +45 -24
- package/dist/index-BqDJ6fUK.d.ts.map +1 -0
- package/dist/{index-BRsrfSHT.d.ts → index-CnJOPR_E.d.ts} +10 -10
- package/dist/{index-BRsrfSHT.d.ts.map → index-CnJOPR_E.d.ts.map} +1 -1
- package/dist/{index-YZrbnBSV.d.ts → index-Dk1dOUfm.d.ts} +11 -11
- package/dist/{index-YZrbnBSV.d.ts.map → index-Dk1dOUfm.d.ts.map} +1 -1
- package/dist/index.d.ts +384 -69
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1492 -217
- package/dist/index.js.map +1 -1
- package/dist/{insight-report-DpOo-3iL.d.ts → insight-report-CvPkEIcC.d.ts} +14 -7
- package/dist/insight-report-CvPkEIcC.d.ts.map +1 -0
- package/dist/{integrity-Cy9WHAtb.js → integrity-BFP4kjGj.js} +6 -1
- package/dist/integrity-BFP4kjGj.js.map +1 -0
- package/dist/{integrity-rGOfSUle.d.ts → integrity-CaeNeusS.d.ts} +4 -4
- package/dist/integrity-CaeNeusS.d.ts.map +1 -0
- package/dist/jev.d.ts +2 -2
- package/dist/jev.js +2 -1
- package/dist/jev.js.map +1 -1
- package/dist/{journal-BuRLm6ho.js → journal-CDP0Vhx_.js} +262 -115
- package/dist/journal-CDP0Vhx_.js.map +1 -0
- package/dist/{kind-factory-V79Hw0AU.js → kind-factory-BGwN0nE6.js} +17 -5
- package/dist/{kind-factory-V79Hw0AU.js.map → kind-factory-BGwN0nE6.js.map} +1 -1
- package/dist/ledger-core/index.d.ts +2 -2
- package/dist/ledger-core/index.js +1 -1
- package/dist/{llm-client-DDhZ29Vm.js → llm-client-DF9bPNYA.js} +2 -2
- package/dist/{llm-client-DDhZ29Vm.js.map → llm-client-DF9bPNYA.js.map} +1 -1
- package/dist/{llm-judge-BVso5x-u.js → llm-judge-M_l_WXw2.js} +26 -24
- package/dist/llm-judge-M_l_WXw2.js.map +1 -0
- package/dist/{matrix-CPKsRY8Y.d.ts → matrix-CNypzP-v.d.ts} +2 -2
- package/dist/{matrix-CPKsRY8Y.d.ts.map → matrix-CNypzP-v.d.ts.map} +1 -1
- package/dist/meta-eval/index.d.ts +4 -4
- package/dist/{mint-BI14xehJ.d.ts → mint-DsS38v5c.d.ts} +25 -5
- package/dist/{mint-BI14xehJ.d.ts.map → mint-DsS38v5c.d.ts.map} +1 -1
- package/dist/{mint-B4zgSAJW.js → mint-iCD-W43s.js} +30 -12
- package/dist/mint-iCD-W43s.js.map +1 -0
- package/dist/multishot/golden/index.d.ts +1 -1
- package/dist/multishot/index.d.ts +2 -2
- package/dist/openapi.json +1 -1
- package/dist/pipelines/index.d.ts +67 -12
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +178 -41
- package/dist/pipelines/index.js.map +1 -1
- package/dist/{prime-protocol-CDBcL9NM.d.ts → prime-protocol-Fwvctmhm.d.ts} +2 -2
- package/dist/{prime-protocol-CDBcL9NM.d.ts.map → prime-protocol-Fwvctmhm.d.ts.map} +1 -1
- package/dist/{produced-state-Cn9ECr4v.js → produced-state-BOY98IJO.js} +4 -4
- package/dist/{produced-state-Cn9ECr4v.js.map → produced-state-BOY98IJO.js.map} +1 -1
- package/dist/{query-D6W6MaGx.d.ts → query-DBUQhehH.d.ts} +3 -3
- package/dist/{query-D6W6MaGx.d.ts.map → query-DBUQhehH.d.ts.map} +1 -1
- package/dist/random-DGEyr3zG.d.ts +83 -0
- package/dist/random-DGEyr3zG.d.ts.map +1 -0
- package/dist/{raw-provider-sink-BQd7mzyT.js → raw-provider-sink-C96CcqeG.js} +19 -56
- package/dist/raw-provider-sink-C96CcqeG.js.map +1 -0
- package/dist/redact-DPoH1-OW.d.ts +158 -0
- package/dist/redact-DPoH1-OW.d.ts.map +1 -0
- package/dist/redact-DxwlUAvh.js +824 -0
- package/dist/redact-DxwlUAvh.js.map +1 -0
- package/dist/{registry-D5Ly3GRV.d.ts → registry-mAQVtuLx.d.ts} +4 -4
- package/dist/{registry-D5Ly3GRV.d.ts.map → registry-mAQVtuLx.d.ts.map} +1 -1
- package/dist/{release-confidence-CSp3MsU4.d.ts → release-confidence-CkoXFx9I.d.ts} +4 -4
- package/dist/{release-confidence-CSp3MsU4.d.ts.map → release-confidence-CkoXFx9I.d.ts.map} +1 -1
- package/dist/{release-confidence-RanRUXRW.js → release-confidence-XQm_xjhR.js} +3 -3
- package/dist/release-confidence-XQm_xjhR.js.map +1 -0
- package/dist/{report-command-CSTjzFGY.js → report-command-DKJ_yAIj.js} +21 -12
- package/dist/{report-command-CSTjzFGY.js.map → report-command-DKJ_yAIj.js.map} +1 -1
- package/dist/reporting.d.ts +3 -3
- package/dist/reporting.js +1 -1
- package/dist/{researcher-D7E92STT.d.ts → researcher-DojEMb7E.d.ts} +7 -7
- package/dist/{researcher-D7E92STT.d.ts.map → researcher-DojEMb7E.d.ts.map} +1 -1
- package/dist/{reward-hacking-BIQ2BWLG.d.ts → reward-hacking-Cyk-QHk9.d.ts} +2 -2
- package/dist/{reward-hacking-BIQ2BWLG.d.ts.map → reward-hacking-Cyk-QHk9.d.ts.map} +1 -1
- package/dist/rl.d.ts +11 -10
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +7 -6
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +4 -4
- package/dist/rollout/index.js +2 -2
- package/dist/{rollout-C0Ifk3vK.js → rollout-B-XBReTC.js} +2 -2
- package/dist/{rollout-C0Ifk3vK.js.map → rollout-B-XBReTC.js.map} +1 -1
- package/dist/{rubric-predictive-validity-CTU8y8Cv.d.ts → rubric-predictive-validity-DIUwJJ9Y.d.ts} +2 -2
- package/dist/{rubric-predictive-validity-CTU8y8Cv.d.ts.map → rubric-predictive-validity-DIUwJJ9Y.d.ts.map} +1 -1
- package/dist/{run-record-tg_5H2IK.js → run-record-BRlM99rX.js} +41 -3
- package/dist/run-record-BRlM99rX.js.map +1 -0
- package/dist/{run-record-D9wS35fK.d.ts → run-record-DF-fuu31.d.ts} +59 -7
- package/dist/run-record-DF-fuu31.d.ts.map +1 -0
- package/dist/{run-record-CNNzWGpB.js → run-record-DnMFyg_g.js} +26 -13
- package/dist/run-record-DnMFyg_g.js.map +1 -0
- package/dist/{schema-CR5cpjQ3.d.ts → schema-2g7trUwH.d.ts} +17 -2
- package/dist/schema-2g7trUwH.d.ts.map +1 -0
- package/dist/{schema-BzWDXhOR.d.ts → schema-B5LtYvn9.d.ts} +7 -5
- package/dist/{schema-BzWDXhOR.d.ts.map → schema-B5LtYvn9.d.ts.map} +1 -1
- package/dist/schema-C1aaAxTf.js.map +1 -1
- package/dist/schema-CSf6qWgZ.js.map +1 -1
- package/dist/{semantic-concept-judge-Cnt0TWp0.js → semantic-concept-judge-Cm2K2wAo.js} +6 -6
- package/dist/{semantic-concept-judge-Cnt0TWp0.js.map → semantic-concept-judge-Cm2K2wAo.js.map} +1 -1
- package/dist/{series-convergence-BnMs_uAr.d.ts → series-convergence-DY7ha0kx.d.ts} +2 -2
- package/dist/{series-convergence-BnMs_uAr.d.ts.map → series-convergence-DY7ha0kx.d.ts.map} +1 -1
- package/dist/{server-DmpcFiVK.js → server-C8XvqCg8.js} +2 -2
- package/dist/{server-DmpcFiVK.js.map → server-C8XvqCg8.js.map} +1 -1
- package/dist/{skillopt-optimization-method-Cc9SVLqi.js → skillopt-optimization-method-BVSB676o.js} +7 -7
- package/dist/{skillopt-optimization-method-Cc9SVLqi.js.map → skillopt-optimization-method-BVSB676o.js.map} +1 -1
- package/dist/spans-W0o8pbEg.d.ts +60 -0
- package/dist/spans-W0o8pbEg.d.ts.map +1 -0
- package/dist/{statistical-heldout-DTmhTW8P.d.ts → statistical-heldout-plAHG82H.d.ts} +3 -3
- package/dist/{statistical-heldout-DTmhTW8P.d.ts.map → statistical-heldout-plAHG82H.d.ts.map} +1 -1
- package/dist/{store-BErPvYBr.d.ts → store-C4avFjIi.d.ts} +2 -2
- package/dist/{store-BErPvYBr.d.ts.map → store-C4avFjIi.d.ts.map} +1 -1
- package/dist/{store-otlp-2gYCy-v0.js → store-otlp-D0AV4cvB.js} +2 -2
- package/dist/{store-otlp-2gYCy-v0.js.map → store-otlp-D0AV4cvB.js.map} +1 -1
- package/dist/{store-tool-spans-B3bX9yqn.d.ts → store-tool-spans-8PAyhRqb.d.ts} +9 -54
- package/dist/store-tool-spans-8PAyhRqb.d.ts.map +1 -0
- package/dist/{store-tool-spans-B1e6Auc2.js → store-tool-spans-B_0mXvYl.js} +4 -4
- package/dist/{store-tool-spans-B1e6Auc2.js.map → store-tool-spans-B_0mXvYl.js.map} +1 -1
- package/dist/storyboard/index.d.ts +1 -1
- package/dist/{summary-report-Iy6kXo8x.d.ts → summary-report-DvvesgR_.d.ts} +6 -5
- package/dist/summary-report-DvvesgR_.d.ts.map +1 -0
- package/dist/supervisor-run/index.d.ts +2 -2
- package/dist/supervisor-run/index.d.ts.map +1 -1
- package/dist/supervisor-run/index.js +1 -1
- package/dist/{tool-groups-veQYPiTy.d.ts → tool-groups-W7MJobX_.d.ts} +3 -3
- package/dist/tool-groups-W7MJobX_.d.ts.map +1 -0
- package/dist/{tool-waste-nbHPAxei.js → tool-waste-CJDfxH45.js} +3 -537
- package/dist/tool-waste-CJDfxH45.js.map +1 -0
- package/dist/{tool-waste-D23I0zWm.d.ts → tool-waste-CP5DO383.d.ts} +4 -4
- package/dist/{tool-waste-D23I0zWm.d.ts.map → tool-waste-CP5DO383.d.ts.map} +1 -1
- package/dist/trace-repair/index.d.ts +2 -2
- package/dist/traces.d.ts +12 -11
- package/dist/traces.d.ts.map +1 -1
- package/dist/traces.js +9 -9
- package/dist/{trajectory-D7qrNvaN.d.ts → trajectory-Y1fmdlw7.d.ts} +3 -3
- package/dist/{trajectory-D7qrNvaN.d.ts.map → trajectory-Y1fmdlw7.d.ts.map} +1 -1
- package/dist/trajectory-replay/index.d.ts +3 -3
- package/dist/trajectory-replay/index.js +2 -2
- package/dist/{types-BjB2wZM9.d.ts → types-Bay1dh2o.d.ts} +6 -6
- package/dist/{types-BjB2wZM9.d.ts.map → types-Bay1dh2o.d.ts.map} +1 -1
- package/dist/{types-BTRcIqFr.d.ts → types-BvmWNjjs.d.ts} +4 -4
- package/dist/{types-BTRcIqFr.d.ts.map → types-BvmWNjjs.d.ts.map} +1 -1
- package/dist/{types-CBbLtr2J.d.ts → types-C0bWoSKC.d.ts} +10 -11
- package/dist/types-C0bWoSKC.d.ts.map +1 -0
- package/dist/{types-C8VBbiw6.js → types-CW5b90JH.js} +2 -15
- package/dist/types-CW5b90JH.js.map +1 -0
- package/dist/{types--18oHwVF.d.ts → types-Cvqy7asY.d.ts} +3 -3
- package/dist/{types--18oHwVF.d.ts.map → types-Cvqy7asY.d.ts.map} +1 -1
- package/dist/{types-Tp5WhYL9.d.ts → types-DRNlLbBR.d.ts} +2 -2
- package/dist/{types-Tp5WhYL9.d.ts.map → types-DRNlLbBR.d.ts.map} +1 -1
- package/dist/wire/index.d.ts +3 -3
- package/dist/wire/index.js +1 -1
- package/docs/code-agent-intake.md +1 -1
- package/docs/diagnosis.md +2 -3
- package/docs/eval-surface-map.md +1 -1
- package/docs/experiment.md +0 -1
- package/docs/insight-report.md +3 -2
- package/docs/public-api.md +2 -2
- package/docs/redaction.md +59 -0
- package/docs/rollout.md +5 -5
- package/docs/search-history-receipts.md +1 -0
- package/docs/trace-contracts.md +102 -0
- package/docs/verdicts.md +1 -1
- package/package.json +3 -2
- package/dist/analyze-runs-DCY7LMt4.js.map +0 -1
- package/dist/benchmark-command-DGokT8zd.js.map +0 -1
- package/dist/campaign-evidence-IF1p0oDa.js.map +0 -1
- package/dist/client-CXE-U1SA.js.map +0 -1
- package/dist/default-registry-Ca2IWH1X.js.map +0 -1
- package/dist/emitter-Cs0egaFd.d.ts.map +0 -1
- package/dist/emitter-DeQHiDMm.js +0 -257
- package/dist/emitter-DeQHiDMm.js.map +0 -1
- package/dist/engine-DNlKhIm0.d.ts.map +0 -1
- package/dist/experiment-tracker-BKEumQug.js +0 -280
- package/dist/experiment-tracker-BKEumQug.js.map +0 -1
- package/dist/experiment-tracker-URRGP9ek.d.ts +0 -237
- package/dist/experiment-tracker-URRGP9ek.d.ts.map +0 -1
- package/dist/index-u0d1Jp4F.d.ts.map +0 -1
- package/dist/insight-report-DpOo-3iL.d.ts.map +0 -1
- package/dist/integrity-Cy9WHAtb.js.map +0 -1
- package/dist/integrity-rGOfSUle.d.ts.map +0 -1
- package/dist/journal-BuRLm6ho.js.map +0 -1
- package/dist/llm-judge-BVso5x-u.js.map +0 -1
- package/dist/mint-B4zgSAJW.js.map +0 -1
- package/dist/raw-provider-sink-BQd7mzyT.js.map +0 -1
- package/dist/redact-7Aq1ukl-.js +0 -107
- package/dist/redact-7Aq1ukl-.js.map +0 -1
- package/dist/release-confidence-RanRUXRW.js.map +0 -1
- package/dist/run-record-CNNzWGpB.js.map +0 -1
- package/dist/run-record-D9wS35fK.d.ts.map +0 -1
- package/dist/run-record-tg_5H2IK.js.map +0 -1
- package/dist/schema-CR5cpjQ3.d.ts.map +0 -1
- package/dist/store-tool-spans-B3bX9yqn.d.ts.map +0 -1
- package/dist/summary-report-Iy6kXo8x.d.ts.map +0 -1
- package/dist/tool-groups-veQYPiTy.d.ts.map +0 -1
- package/dist/tool-waste-nbHPAxei.js.map +0 -1
- package/dist/types-C8VBbiw6.js.map +0 -1
- package/dist/types-CBbLtr2J.d.ts.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { a as hashCanonical, r as canonicalString, t as LEDGER_HASH_PATTERN } from "./canonical-BsZVgBhW.js";
|
|
2
|
+
import { t as deepFreezeCanonicalJson } from "./deep-freeze-CurcOQg3.js";
|
|
2
3
|
import { randomUUID } from "node:crypto";
|
|
3
4
|
import { closeSync, constants, existsSync, fstatSync, fsyncSync, linkSync, mkdirSync, openSync, readFileSync, readSync, renameSync, rmSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
4
5
|
import { dirname, resolve } from "node:path";
|
|
@@ -623,11 +624,13 @@ function clearTrustedHeadFile(path, context) {
|
|
|
623
624
|
}
|
|
624
625
|
/** The entry at exactly `head.sequence` must still carry `head.entryHash`.
|
|
625
626
|
* Entries must already have passed chain verification, which is what makes
|
|
626
|
-
* index and sequence interchangeable here.
|
|
627
|
+
* index and sequence interchangeable here. An array serves as `entries`; a
|
|
628
|
+
* journal that keeps no entries in memory passes a reader with the same
|
|
629
|
+
* `length` and `at`. */
|
|
627
630
|
function verifyEntriesAgainstTrustedHead(entries, head, context, naming) {
|
|
628
631
|
if (typeof naming !== "object" || naming === null) throw new TypeError("verifyEntriesAgainstTrustedHead expects { subject, trustedHeadPath } as its fourth argument");
|
|
629
632
|
const { subject, trustedHeadPath } = naming;
|
|
630
|
-
const pinned = entries
|
|
633
|
+
const pinned = entries.at(head.sequence);
|
|
631
634
|
if (pinned === void 0) throw context.integrityError(`${subject} trusted head ${trustedHeadPath} pins sequence ${head.sequence} (${head.entryHash}) but the journal has ${entries.length} entries — pinned history is missing (truncation, rollback, or rewrite). Restore the journal, or abandon the pinned history on purpose with clearTrustedHead().`);
|
|
632
635
|
if (pinned.sequence !== head.sequence) throw context.integrityError(`${subject} entry at index ${head.sequence} carries sequence ${pinned.sequence}; the chain was not verified before the trusted head ${trustedHeadPath}`);
|
|
633
636
|
if (pinned.entryHash !== head.entryHash) throw context.integrityError(`${subject} entry at pinned sequence ${head.sequence} carries ${pinned.entryHash} but the trusted head ${trustedHeadPath} recorded ${head.entryHash} — the journal was rewritten. Restore the journal, or abandon the pinned history on purpose with clearTrustedHead().`);
|
|
@@ -652,6 +655,16 @@ function verifyEntriesAgainstTrustedHead(entries, head, context, naming) {
|
|
|
652
655
|
* so truncation and wholesale rewrite are refused. `trusted-head.ts` carries
|
|
653
656
|
* the full threat model, including what a pin does not defend against.
|
|
654
657
|
*
|
|
658
|
+
* Verification is incremental. A journal instance verifies its whole file once,
|
|
659
|
+
* on its first call, and keeps the verified head, the live projector, and an
|
|
660
|
+
* eventId index. Every later call checks that the head line it verified is
|
|
661
|
+
* still in place, then reads, verifies, and projects only the bytes past it, so
|
|
662
|
+
* an append reads one entry however long the journal is. Rows another writer
|
|
663
|
+
* appended are verified as that tail. A file that was replaced, shrank, or no
|
|
664
|
+
* longer carries the verified head is verified whole again. What an open
|
|
665
|
+
* instance cannot see is a same-length rewrite of rows before its head; a new
|
|
666
|
+
* instance verifies every row and refuses one.
|
|
667
|
+
*
|
|
655
668
|
* Domain vocabulary lives entirely in the consumer's codec: entry schema
|
|
656
669
|
* validation, the constant header fields stamped into every entry, the error
|
|
657
670
|
* taxonomy, and the state machine replayed over verified entries.
|
|
@@ -664,8 +677,9 @@ function mutexFor(path) {
|
|
|
664
677
|
journalMutexes.set(path, mutex);
|
|
665
678
|
return mutex;
|
|
666
679
|
}
|
|
667
|
-
/** Durable filesystem journal. Construction performs no I/O
|
|
668
|
-
*
|
|
680
|
+
/** Durable filesystem journal. Construction performs no I/O. The first call
|
|
681
|
+
* verifies the complete file under the locks; later calls verify the retained
|
|
682
|
+
* head and only the bytes past it (see the module comment). */
|
|
669
683
|
var FileLedgerJournal = class {
|
|
670
684
|
path;
|
|
671
685
|
/** Sibling file holding this journal's trusted head. */
|
|
@@ -673,6 +687,7 @@ var FileLedgerJournal = class {
|
|
|
673
687
|
codec;
|
|
674
688
|
mutex;
|
|
675
689
|
requireTrustedHead;
|
|
690
|
+
verified = null;
|
|
676
691
|
constructor(path, codec, options = {}) {
|
|
677
692
|
this.path = resolve(path);
|
|
678
693
|
this.trustedHeadPath = trustedHeadPathFor(this.path);
|
|
@@ -681,43 +696,53 @@ var FileLedgerJournal = class {
|
|
|
681
696
|
this.requireTrustedHead = options.requireTrustedHead === true;
|
|
682
697
|
}
|
|
683
698
|
async replay() {
|
|
684
|
-
return this.
|
|
699
|
+
return this.locked(() => this.sync(this.requireTrustedHead).projector.snapshot());
|
|
685
700
|
}
|
|
686
701
|
async append(event, options = {}) {
|
|
687
|
-
return this.
|
|
688
|
-
const
|
|
689
|
-
const
|
|
690
|
-
if (
|
|
702
|
+
return this.locked(() => {
|
|
703
|
+
const state = this.sync(this.requireTrustedHead);
|
|
704
|
+
const existingSequence = state.sequenceByEventId.get(event.eventId);
|
|
705
|
+
if (existingSequence !== void 0) {
|
|
706
|
+
const existing = this.entryAt(state, existingSequence);
|
|
691
707
|
if (canonicalString(existing.event) !== canonicalString(event)) throw this.codec.conflictError(`eventId ${event.eventId} already exists with different content`);
|
|
692
|
-
if (options.pinHead === true) this.pinAcknowledged(
|
|
708
|
+
if (options.pinHead === true) this.pinAcknowledged(state, existing);
|
|
693
709
|
return {
|
|
694
710
|
entry: existing,
|
|
695
711
|
appended: false,
|
|
696
|
-
projection:
|
|
712
|
+
projection: state.projector.snapshot()
|
|
697
713
|
};
|
|
698
714
|
}
|
|
715
|
+
const sequence = state.offsets.length;
|
|
699
716
|
const material = {
|
|
700
717
|
...this.codec.header,
|
|
701
|
-
sequence
|
|
702
|
-
previousHash:
|
|
718
|
+
sequence,
|
|
719
|
+
previousHash: state.head?.entry.entryHash ?? null,
|
|
703
720
|
event
|
|
704
721
|
};
|
|
705
|
-
const
|
|
722
|
+
const text = canonicalString({
|
|
706
723
|
...material,
|
|
707
724
|
entryHash: hashCanonical(material)
|
|
708
|
-
};
|
|
709
|
-
const
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
sequence: entry.sequence,
|
|
713
|
-
entryHash: entry.entryHash
|
|
725
|
+
});
|
|
726
|
+
const entry = parseRow(text, {
|
|
727
|
+
path: this.path,
|
|
728
|
+
line: sequence + 1
|
|
714
729
|
}, this.codec);
|
|
730
|
+
admitEntry(state, entry, Buffer.from(`${text}\n`, "utf8"), this.codec);
|
|
731
|
+
appendLedgerLine(this.path, `${text}\n`, this.codec);
|
|
732
|
+
if (options.pinHead === true) {
|
|
733
|
+
const head = {
|
|
734
|
+
sequence: entry.sequence,
|
|
735
|
+
entryHash: entry.entryHash
|
|
736
|
+
};
|
|
737
|
+
writeTrustedHeadFile(this.trustedHeadPath, head, this.codec);
|
|
738
|
+
state.pin = head;
|
|
739
|
+
}
|
|
715
740
|
return {
|
|
716
741
|
entry,
|
|
717
742
|
appended: true,
|
|
718
|
-
projection
|
|
743
|
+
projection: state.projector.snapshot()
|
|
719
744
|
};
|
|
720
|
-
})
|
|
745
|
+
});
|
|
721
746
|
}
|
|
722
747
|
/** The pinned head, or null when this journal has never been pinned. */
|
|
723
748
|
async trustedHead() {
|
|
@@ -727,19 +752,17 @@ var FileLedgerJournal = class {
|
|
|
727
752
|
* first, so the pin only ever moves forward along a journal that still
|
|
728
753
|
* carries the history it already recorded. */
|
|
729
754
|
async pinTrustedHead() {
|
|
730
|
-
return this.
|
|
731
|
-
const
|
|
732
|
-
this.
|
|
733
|
-
this.verifyTrustedHead(entries, false);
|
|
734
|
-
const last = entries.at(-1);
|
|
735
|
-
if (last === void 0) throw this.codec.integrityError(`${this.codec.subject} ${this.path} is empty; there is no head to pin`);
|
|
755
|
+
return this.locked(() => {
|
|
756
|
+
const state = this.sync(false);
|
|
757
|
+
if (state.head === null) throw this.codec.integrityError(`${this.codec.subject} ${this.path} is empty; there is no head to pin`);
|
|
736
758
|
const head = {
|
|
737
|
-
sequence:
|
|
738
|
-
entryHash:
|
|
759
|
+
sequence: state.head.entry.sequence,
|
|
760
|
+
entryHash: state.head.entry.entryHash
|
|
739
761
|
};
|
|
740
762
|
writeTrustedHeadFile(this.trustedHeadPath, head, this.codec);
|
|
763
|
+
state.pin = head;
|
|
741
764
|
return head;
|
|
742
|
-
})
|
|
765
|
+
});
|
|
743
766
|
}
|
|
744
767
|
/** Discard this journal's pin, reporting what was discarded. The journal file
|
|
745
768
|
* is untouched and reads as unpinned afterwards, so the next pinning append
|
|
@@ -749,115 +772,239 @@ var FileLedgerJournal = class {
|
|
|
749
772
|
* is indistinguishable from a deletion. Clearing removes the deletion
|
|
750
773
|
* guarantee for every entry the pin covered. */
|
|
751
774
|
async clearTrustedHead() {
|
|
752
|
-
return this.
|
|
775
|
+
return this.locked(() => {
|
|
776
|
+
const removal = clearTrustedHeadFile(this.trustedHeadPath, this.codec);
|
|
777
|
+
if (this.verified !== null) this.verified.pin = null;
|
|
778
|
+
return removal;
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
/** Run under both locks. Any failure discards the verified state, because a
|
|
782
|
+
* throw can leave it describing bytes the file does not hold: a projector
|
|
783
|
+
* half way through a rejected transition, or a row whose write failed. */
|
|
784
|
+
locked(run) {
|
|
785
|
+
return this.mutex.runExclusive(() => withLedgerFileLock(this.path, this.codec, () => {
|
|
786
|
+
try {
|
|
787
|
+
return run();
|
|
788
|
+
} catch (error) {
|
|
789
|
+
this.verified = null;
|
|
790
|
+
throw error;
|
|
791
|
+
}
|
|
792
|
+
}));
|
|
793
|
+
}
|
|
794
|
+
/** Bring the verified state up to the file: keep it when its head row is
|
|
795
|
+
* still where it was verified, else start over from byte 0; then verify and
|
|
796
|
+
* apply every row past it, and check the pin. */
|
|
797
|
+
sync(requirePin) {
|
|
798
|
+
let state = this.verified;
|
|
799
|
+
const fd = openForReading(this.path, this.codec);
|
|
800
|
+
if (fd === null) {
|
|
801
|
+
if (state === null || state.size > 0) state = emptyJournal(this.codec);
|
|
802
|
+
this.verified = state;
|
|
803
|
+
this.verifyPin(state, requirePin);
|
|
804
|
+
return state;
|
|
805
|
+
}
|
|
806
|
+
try {
|
|
807
|
+
const stats = fstatSync(fd, { bigint: true });
|
|
808
|
+
const size = Number(stats.size);
|
|
809
|
+
const identity = {
|
|
810
|
+
dev: stats.dev,
|
|
811
|
+
ino: stats.ino
|
|
812
|
+
};
|
|
813
|
+
if (state === null || state.identity !== null && (state.identity.dev !== identity.dev || state.identity.ino !== identity.ino) || size < state.size || !headInPlace(fd, state.size, state.head?.row ?? null)) state = emptyJournal(this.codec);
|
|
814
|
+
state.identity = identity;
|
|
815
|
+
this.verified = state;
|
|
816
|
+
if (size > state.size) extendJournal(state, readRange(fd, state.size, size), this.path, this.codec);
|
|
817
|
+
} finally {
|
|
818
|
+
closeSync(fd);
|
|
819
|
+
}
|
|
820
|
+
this.verifyPin(state, requirePin);
|
|
821
|
+
return state;
|
|
822
|
+
}
|
|
823
|
+
verifyPin(state, requirePin) {
|
|
824
|
+
const pinned = readTrustedHeadFile(this.trustedHeadPath, this.codec);
|
|
825
|
+
const count = state.offsets.length;
|
|
826
|
+
if (pinned === null) {
|
|
827
|
+
state.pin = null;
|
|
828
|
+
if (requirePin && count > 0) throw this.codec.integrityError(`${this.codec.subject} ${this.path} has ${count} entries but no trusted head at ${this.trustedHeadPath} — without its pin the journal cannot prove nothing was deleted. Restore the pin file, or adopt the current head with pinTrustedHead().`);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (state.pin?.sequence === pinned.sequence && state.pin.entryHash === pinned.entryHash) return;
|
|
832
|
+
verifyEntriesAgainstTrustedHead({
|
|
833
|
+
length: count,
|
|
834
|
+
at: (sequence) => this.entryAt(state, sequence)
|
|
835
|
+
}, pinned, this.codec, {
|
|
836
|
+
subject: `${this.codec.subject} ${this.path}`,
|
|
837
|
+
trustedHeadPath: this.trustedHeadPath
|
|
838
|
+
});
|
|
839
|
+
state.pin = pinned;
|
|
753
840
|
}
|
|
754
841
|
/** Move the pin up to an entry this caller just acknowledged on the
|
|
755
842
|
* idempotent path, when a pin write that failed after its row was already
|
|
756
843
|
* fsynced left the pin behind. The move is safe because it is forward-only
|
|
757
|
-
* along a chain `
|
|
758
|
-
*
|
|
759
|
-
*
|
|
844
|
+
* along a chain `sync` has just verified: every entry up to this one is bound
|
|
845
|
+
* to it by hash, so the pin can only ever come to name more history than it
|
|
846
|
+
* did, never different history.
|
|
760
847
|
*
|
|
761
848
|
* With no pin at all this only pins the journal's current head. An entry in
|
|
762
849
|
* the middle would publish a pin that reads as protection while leaving every
|
|
763
850
|
* later entry silently truncatable, which is a worse state to hand an auditor
|
|
764
851
|
* than the honest absence of a pin; `pinTrustedHead()` is the way to pin an
|
|
765
852
|
* unpinned journal on purpose. */
|
|
766
|
-
pinAcknowledged(
|
|
767
|
-
const pinned =
|
|
853
|
+
pinAcknowledged(state, entry) {
|
|
854
|
+
const pinned = state.pin;
|
|
768
855
|
if (pinned === null) {
|
|
769
|
-
if (entry.sequence !==
|
|
856
|
+
if (entry.sequence !== state.offsets.length - 1) return;
|
|
770
857
|
} else if (pinned.sequence >= entry.sequence) return;
|
|
771
|
-
|
|
858
|
+
const head = {
|
|
772
859
|
sequence: entry.sequence,
|
|
773
860
|
entryHash: entry.entryHash
|
|
774
|
-
}, this.codec);
|
|
775
|
-
}
|
|
776
|
-
replayLocked() {
|
|
777
|
-
const entries = this.readEntries();
|
|
778
|
-
const projection = this.project(entries);
|
|
779
|
-
this.verifyTrustedHead(entries, this.requireTrustedHead);
|
|
780
|
-
return {
|
|
781
|
-
entries,
|
|
782
|
-
projection
|
|
783
861
|
};
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
862
|
+
writeTrustedHeadFile(this.trustedHeadPath, head, this.codec);
|
|
863
|
+
state.pin = head;
|
|
864
|
+
}
|
|
865
|
+
/** The verified entry at `sequence`, read back from the file. The rows from
|
|
866
|
+
* it to the head are re-read and must chain to the verified head hash, which
|
|
867
|
+
* binds the returned entry to the history this instance verified. Callers ask
|
|
868
|
+
* for recent entries — an idempotent retry, a pin one entry behind — so this
|
|
869
|
+
* usually reads nothing or one row. */
|
|
870
|
+
entryAt(state, sequence) {
|
|
871
|
+
const count = state.offsets.length;
|
|
872
|
+
if (!Number.isSafeInteger(sequence) || sequence < 0 || sequence >= count) return void 0;
|
|
873
|
+
if (sequence === count - 1) return state.head.entry;
|
|
874
|
+
const changed = () => this.codec.integrityError(`${this.codec.subject} ${this.path} changed at or after sequence ${sequence} since this reader verified it`);
|
|
875
|
+
const fd = openForReading(this.path, this.codec);
|
|
876
|
+
if (fd === null) throw changed();
|
|
877
|
+
let bytes;
|
|
878
|
+
try {
|
|
879
|
+
bytes = readRange(fd, state.offsets[sequence], state.size);
|
|
880
|
+
} finally {
|
|
881
|
+
closeSync(fd);
|
|
790
882
|
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
883
|
+
const rows = splitRows(bytes, this.path, this.codec);
|
|
884
|
+
if (rows.length !== count - sequence) throw changed();
|
|
885
|
+
let first;
|
|
886
|
+
let previous;
|
|
887
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
888
|
+
const entry = parseRow(rows[index].text, {
|
|
889
|
+
path: this.path,
|
|
890
|
+
line: sequence + index + 1
|
|
891
|
+
}, this.codec);
|
|
892
|
+
const { entryHash, ...material } = entry;
|
|
893
|
+
if (entry.sequence !== sequence + index || hashCanonical(material) !== entryHash || previous !== void 0 && entry.previousHash !== previous.entryHash) throw changed();
|
|
894
|
+
first ??= entry;
|
|
895
|
+
previous = entry;
|
|
896
|
+
}
|
|
897
|
+
if (previous?.entryHash !== state.head.entry.entryHash) throw changed();
|
|
898
|
+
return first;
|
|
802
899
|
}
|
|
803
900
|
};
|
|
804
901
|
/** Verify and replay resolved immutable journal bytes without filesystem I/O. */
|
|
805
902
|
function replayLedgerText(text, path, codec) {
|
|
806
|
-
const
|
|
903
|
+
const state = emptyJournal(codec);
|
|
904
|
+
extendJournal(state, Buffer.from(text, "utf8"), path, codec);
|
|
905
|
+
return state.projector.snapshot();
|
|
906
|
+
}
|
|
907
|
+
function emptyJournal(codec) {
|
|
807
908
|
return {
|
|
808
|
-
|
|
809
|
-
|
|
909
|
+
identity: null,
|
|
910
|
+
size: 0,
|
|
911
|
+
offsets: [],
|
|
912
|
+
head: null,
|
|
913
|
+
sequenceByEventId: /* @__PURE__ */ new Map(),
|
|
914
|
+
projector: codec.createProjector(),
|
|
915
|
+
pin: null
|
|
810
916
|
};
|
|
811
917
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
const
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
918
|
+
/** Verify and apply the rows in `bytes`, which start at the state's verified
|
|
919
|
+
* length. */
|
|
920
|
+
function extendJournal(state, bytes, path, codec) {
|
|
921
|
+
const rows = splitRows(bytes, path, codec);
|
|
922
|
+
for (const { text, start, end } of rows) admitEntry(state, parseRow(text, {
|
|
923
|
+
path,
|
|
924
|
+
line: state.offsets.length + 1
|
|
925
|
+
}, codec), Buffer.from(bytes.subarray(start, end)), codec);
|
|
926
|
+
}
|
|
927
|
+
/** Check one parsed entry against the chain and apply it. Every row, read or
|
|
928
|
+
* about to be written, enters the verified state here. */
|
|
929
|
+
function admitEntry(state, entry, row, codec) {
|
|
930
|
+
const index = state.offsets.length;
|
|
931
|
+
codec.checkEntryHeader(entry, index);
|
|
932
|
+
if (entry.sequence !== index) throw codec.integrityError(`entry ${entry.event.eventId} has sequence ${entry.sequence}, expected ${index}`);
|
|
933
|
+
if (entry.previousHash !== (state.head?.entry.entryHash ?? null)) throw codec.integrityError(`entry ${entry.event.eventId} does not extend the previous hash`);
|
|
934
|
+
const { entryHash: _entryHash, ...material } = entry;
|
|
935
|
+
const expectedHash = hashCanonical(material);
|
|
936
|
+
if (entry.entryHash !== expectedHash) throw codec.integrityError(`entry ${entry.event.eventId} hash mismatch: expected ${expectedHash}, got ${entry.entryHash}`);
|
|
937
|
+
if (state.sequenceByEventId.has(entry.event.eventId)) throw codec.integrityError(`duplicate eventId ${entry.event.eventId} in durable ledger`);
|
|
938
|
+
state.projector.apply(entry, index);
|
|
939
|
+
state.sequenceByEventId.set(entry.event.eventId, index);
|
|
940
|
+
state.offsets.push(state.size);
|
|
941
|
+
state.size += row.byteLength;
|
|
942
|
+
state.head = {
|
|
943
|
+
entry,
|
|
944
|
+
row
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
/** Parse one canonical row into a frozen entry. The projector and every caller
|
|
948
|
+
* share entries, so none of them can change what the journal verified. */
|
|
949
|
+
function parseRow(text, context, codec) {
|
|
950
|
+
const { path, line } = context;
|
|
951
|
+
let raw;
|
|
952
|
+
try {
|
|
953
|
+
raw = JSON.parse(text);
|
|
954
|
+
} catch (error) {
|
|
955
|
+
throw codec.integrityError(`${codec.subject} ${path} has invalid JSON at line ${line}`, { cause: error });
|
|
956
|
+
}
|
|
957
|
+
const entry = codec.parseEntry(raw, context);
|
|
958
|
+
let canonical;
|
|
959
|
+
try {
|
|
960
|
+
canonical = canonicalString(entry);
|
|
961
|
+
} catch (error) {
|
|
962
|
+
throw codec.integrityError(`${codec.subject} ${path} has a row with no canonical JSON form at line ${line}`, { cause: error });
|
|
963
|
+
}
|
|
964
|
+
if (text !== canonical) throw codec.integrityError(`${codec.subject} ${path} has non-canonical bytes at line ${line}`);
|
|
965
|
+
return deepFreezeCanonicalJson(entry);
|
|
966
|
+
}
|
|
967
|
+
function splitRows(bytes, path, context) {
|
|
968
|
+
if (bytes.byteLength === 0) return [];
|
|
969
|
+
if (bytes[bytes.byteLength - 1] !== 10) throw context.integrityError(`${context.subject} ${path} has a truncated final record (missing newline)`);
|
|
970
|
+
const rows = [];
|
|
971
|
+
let start = 0;
|
|
972
|
+
while (start < bytes.byteLength) {
|
|
973
|
+
const newline = bytes.indexOf(10, start);
|
|
974
|
+
if (newline === start) throw context.integrityError(`${context.subject} ${path} has a blank row at line ${rows.length + 1}`);
|
|
975
|
+
rows.push({
|
|
976
|
+
text: bytes.toString("utf8", start, newline),
|
|
977
|
+
start,
|
|
978
|
+
end: newline + 1
|
|
829
979
|
});
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
const
|
|
852
|
-
if (
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
projector.apply(entry, index);
|
|
857
|
-
}
|
|
858
|
-
return projector.finish(entries);
|
|
980
|
+
start = newline + 1;
|
|
981
|
+
}
|
|
982
|
+
return rows;
|
|
983
|
+
}
|
|
984
|
+
/** True when the verified head row still ends the verified length of the file. */
|
|
985
|
+
function headInPlace(fd, size, row) {
|
|
986
|
+
return row === null || readRange(fd, size - row.byteLength, size).equals(row);
|
|
987
|
+
}
|
|
988
|
+
/** A read-only descriptor, or null when the file does not exist. */
|
|
989
|
+
function openForReading(path, context) {
|
|
990
|
+
try {
|
|
991
|
+
return openSync(path, constants.O_RDONLY);
|
|
992
|
+
} catch (error) {
|
|
993
|
+
if (error.code === "ENOENT") return null;
|
|
994
|
+
throw context.integrityError(`${context.subject} ${path} could not be opened for reading`, { cause: error });
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
function readRange(fd, start, end) {
|
|
998
|
+
const bytes = Buffer.allocUnsafe(end - start);
|
|
999
|
+
let offset = 0;
|
|
1000
|
+
while (offset < bytes.byteLength) {
|
|
1001
|
+
const read = readSync(fd, bytes, offset, bytes.byteLength - offset, start + offset);
|
|
1002
|
+
if (read === 0) return bytes.subarray(0, offset);
|
|
1003
|
+
offset += read;
|
|
1004
|
+
}
|
|
1005
|
+
return bytes;
|
|
859
1006
|
}
|
|
860
1007
|
//#endregion
|
|
861
1008
|
export { verifyEntriesAgainstTrustedHead as a, withLedgerFileLock as c, mapConcurrent as d, mapConcurrentRange as f, tryAcquireAtomicFileLock as h, trustedHeadPathFor as i, writeLedgerFileAtomically as l, probeAtomicFileLock as m, replayLedgerText as n, appendLedgerLine as o, AtomicFileLockError as p, readTrustedHeadFile as r, tryWithLedgerFileLock as s, FileLedgerJournal as t, Mutex as u };
|
|
862
1009
|
|
|
863
|
-
//# sourceMappingURL=journal-
|
|
1010
|
+
//# sourceMappingURL=journal-CDP0Vhx_.js.map
|