@overdeck/desktop 0.45.22 → 0.45.24
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/drizzle/overdeck/0000_overdeck_init.sql +2 -0
- package/package.json +1 -1
- package/server/{acceptance-criteria-BH7ac_1G.js → acceptance-criteria-DDCnXF58.js} +5 -5
- package/server/{advancing-selfheal-cSvXNZLZ.js → advancing-selfheal-BVwW4qRn.js} +6 -6
- package/server/{agent-gc-Dj2gncak.js → agent-gc-CHcnvonI.js} +4 -4
- package/server/agent-state-Bc3tzUC8.js +3 -0
- package/server/{agent-state-service-DistflNn.js → agent-state-service-BsgWxZuB.js} +5 -5
- package/server/{agent-state-service-CsQ07Pxe.js → agent-state-service-D5UGKIJL.js} +1 -1
- package/server/{agents-DXdHmRTC.js → agents-EbI0zCJl.js} +4 -4
- package/server/agents-wi9NWzs2.js +3 -0
- package/server/{archive-planning-Cp_DC1j-.js → archive-planning-BZDgzoEj.js} +1 -1
- package/server/{archive-planning-BvDuWNMo.js → archive-planning-Du25Jtst.js} +30 -6
- package/server/{artifact-index-jobs-CDBFL4OU.js → artifact-index-jobs-CbEDfCDu.js} +2 -2
- package/server/assemble-J2ZZ2C15.js +339 -0
- package/server/{backlog-auto-trigger-DmA1IbYf.js → backlog-auto-trigger-2R2jog7n.js} +3 -3
- package/server/{behavior-CGj16clS.js → behavior-B3exJ42O.js} +2 -2
- package/server/{briefing-freshness-C12WgkaB.js → briefing-freshness-D1wzUIWv.js} +2 -2
- package/server/{build-info-BRpqQvNd.js → build-info-CZk_TITh.js} +1 -1
- package/server/{build-info-NU3KbXYw.js → build-info-Ie_D0_BT.js} +3 -3
- package/server/{checkpoint-manager-CTPjAmtH.js → checkpoint-manager-BI1Wxoku.js} +2 -2
- package/server/{checkpoint-manager-rOgT98WY.js → checkpoint-manager-DwbQoqrC.js} +1 -1
- package/server/checkpoint-worker.js +1 -1
- package/server/{checkpoints-B5jFNi2G.js → checkpoints-BJIs5QIA.js} +1 -1
- package/server/{checkpoints-BJum14fs.js → checkpoints-CQB1h765.js} +2 -2
- package/server/{claude-hooks-provision-BhwWK-TQ.js → claude-hooks-provision-8Ngo8TpT.js} +1 -1
- package/server/{claude-hooks-provision-D7p5WcKZ.js → claude-hooks-provision-D8GXF3_s.js} +2 -2
- package/server/{claude-permissions-nSFKH78M.js → claude-permissions-DNWEVV6z.js} +2 -2
- package/server/{claude-settings-overlay-BI_UIke0.js → claude-settings-overlay-CEdaqpWI.js} +2 -2
- package/server/{claude-settings-overlay-DHBwjS1X.js → claude-settings-overlay-DWy-Bb4Y.js} +1 -1
- package/server/cli-B86rejVV.js +3 -0
- package/server/{cli-CbKNkFE5.js → cli-RoOx5DUf.js} +9 -9
- package/server/{cliproxy-Brf_5MuG.js → cliproxy-C8a1vtTU.js} +2 -2
- package/server/{cliproxy-bONZDBbC.js → cliproxy-fHfIeiGd.js} +1 -1
- package/server/{close-issue-CxReRxIc.js → close-issue-DoOifFIK.js} +5 -5
- package/server/{closed-issue-reaper-CQ3kqha7.js → closed-issue-reaper-Bk3SU4RC.js} +9 -9
- package/server/{closed-issue-reaper-DXP2Xyv3.js → closed-issue-reaper-CktPXo8m.js} +1 -1
- package/server/{codex-CbmztVcc.js → codex-BZXGhUVB.js} +27 -8
- package/server/codex-GcHuUF-k.js +3 -0
- package/server/{codex-parser-jl8AeAmB.js → codex-parser-CFZ1_1Jl.js} +2 -2
- package/server/{config-q4Gvd8dq.js → config-BZ0sHTju.js} +2 -2
- package/server/{config-DeTsoZdR.js → config-CKxYiCmX.js} +2 -2
- package/server/{config-BJKocXKd.js → config-DzV30TOm.js} +1 -1
- package/server/{config-yaml-ig8Nwtiw.js → config-yaml-DySPNmKN.js} +77 -194
- package/server/{conflict-gate-CFqPVxEg.js → conflict-gate-BaCVrH-N.js} +3 -3
- package/server/{conflict-gate-CHU9K1vU.js → conflict-gate-BhAY7TUd.js} +1 -1
- package/server/context-layers-BrPmE__h.js +4 -0
- package/server/context-layers-igZ4FI4_.js +37 -0
- package/server/{control-settings-D_odMIaC.js → control-settings-BQp7_4uD.js} +4 -4
- package/server/{conversation-compaction-B6YSRLda.js → conversation-compaction-CgrR8YYp.js} +8 -8
- package/server/{conversation-compaction-CN4-5YYt.js → conversation-compaction-eQB5CkOe.js} +1 -1
- package/server/{conversation-service-Dq33SYEj.js → conversation-service-BLd3MYsG.js} +1 -1
- package/server/{conversation-service-C3avRVEr.js → conversation-service-DPJ71F33.js} +329 -19
- package/server/{conversations-bYpM9-kZ.js → conversations-6AfUfbwc.js} +5 -5
- package/server/{conversations-H9if0bCQ.js → conversations-CAsJF9kh.js} +1 -1
- package/server/{cost-Codk1pc2.js → cost-B2ddP6wq.js} +18 -2
- package/server/{cost-wH46-WsJ.js → cost-R-m6Yi-W.js} +3 -3
- package/server/{cost-sync-D_cre6WM.js → cost-sync-BsN6ER0n.js} +3 -3
- package/server/{dag-CJpgf9A3.js → dag-B1ucnjDU.js} +9 -9
- package/server/{dangerous-git-ops-D6AF-Hg_.js → dangerous-git-ops-BXqeWVSf.js} +1 -1
- package/server/dashboard-db-worker.js +7 -7
- package/server/{deacon-CkT_kznS.js → deacon-CU_cAYSR.js} +406 -607
- package/server/{deacon-B8HbQdqU.js → deacon-kiQrb4ZT.js} +3 -3
- package/server/{deacon-nudge-log-D6K9K-rE.js → deacon-nudge-log-6wVqAaqz.js} +3 -3
- package/server/{deacon-swarm-BryRr6AO.js → deacon-swarm-BXZZ1Z2-.js} +17 -17
- package/server/deacon-swarm-C-GwfjJy.js +2 -0
- package/server/deacon.js +8 -8
- package/server/{deploy-patrol-1IrZxicY.js → deploy-patrol-AiFoP8dw.js} +136 -19
- package/server/{deploy-window-wDf4UgHt.js → deploy-window-C3F-tihF.js} +77 -10
- package/server/{deploy-window-7ZYHh7Zp.js → deploy-window-DkZraDyj.js} +1 -1
- package/server/{dev-supervisor-C7p9kEpc.js → dev-supervisor-bcOWqdQE.js} +2 -2
- package/server/{devcontainer-renderer-CNmQy0pL.js → devcontainer-renderer-_d6XhyND.js} +3 -3
- package/server/dist-Bzy0y69j.js +3 -0
- package/server/{dist-D-Ed5yVw.js → dist-Cb_0uvpS.js} +1 -1
- package/server/{docker-BCZ89M9X.js → docker-DcMTFTUC.js} +2 -2
- package/server/{dod-DbJLYcHv.js → dod-C6n9RV3G.js} +1 -1
- package/server/{ensure-devcontainer-Cs6W9Yzj.js → ensure-devcontainer-BZgOhRo7.js} +1 -1
- package/server/{ensure-devcontainer-V5JWaAva.js → ensure-devcontainer-DNi-ono3.js} +4 -4
- package/server/{esm-shims-dTeNdq7X.js → esm-shims-OSHAYaS1.js} +1 -1
- package/server/{event-store-TnWdydfB.js → event-store-CQL6NeqB.js} +3 -3
- package/server/{event-store-CpBGsO6_.js → event-store-EV2cMiXj.js} +1 -1
- package/server/{events-Dsuv6qyB.js → events-BTdrdEq8.js} +1 -1
- package/server/{events-DSUdR-04.js → events-DTfAe4My.js} +3 -3
- package/server/{factory-BMrK4TrE.js → factory-CFibJuaw.js} +50 -13
- package/server/{feature-registry-population-B-CI9hgE.js → feature-registry-population-DKZFMbFt.js} +4 -4
- package/server/{feature-registry-storage-B972ph_A.js → feature-registry-storage-BdPuLcBX.js} +2 -2
- package/server/{features-Bc-Bmiye.js → features-ez2271oH.js} +2 -2
- package/server/{feedback-target-DZ-iAnAa.js → feedback-target-7mqqwrX6.js} +7 -7
- package/server/{feedback-target-DS6NUuSs.js → feedback-target-CoFDHiM8.js} +1 -1
- package/server/{feedback-writer-BXP6g75N.js → feedback-writer-CY5L1lB7.js} +6 -5
- package/server/{feedback-writer-Bx5z11mF.js → feedback-writer-D3a22RCd.js} +1 -1
- package/server/flywheel-DHrgCphM.js +1084 -0
- package/server/flywheel-DzGtWnJ1.js +477 -0
- package/server/flywheel-SVF02Jpq.js +2 -0
- package/server/{flywheel-merge-order-CTgHeg-W.js → flywheel-merge-order-UU0tiUld.js} +10 -9
- package/server/{flywheel-merge-order-CNKAY489.js → flywheel-merge-order-UUcsCDb6.js} +1 -1
- package/server/{forge-B1S_KZv4.js → forge-CNFnyqps.js} +2 -2
- package/server/forge-DXnS_YFH.js +2 -0
- package/server/{from-DpwQ-sc3.js → from-kNxT0bZC.js} +1 -1
- package/server/{fts-db-DmAcuCkV.js → fts-db-CE46vDkZ.js} +2 -2
- package/server/{fts-operations-7d_RkmWp.js → fts-operations-CqY6zl-i.js} +2 -2
- package/server/{git-utils-Cc3FHDKd.js → git-utils-CRw2zLPC.js} +68 -3
- package/server/git-utils-D0_yhCgF.js +3 -0
- package/server/{github-app-CDPtGF7J.js → github-app-C3QrAUd0.js} +27 -8
- package/server/{github-app-CU14oYzP.js → github-app-ClZ2lk8D.js} +1 -1
- package/server/{github-client-XjTJbBm7.js → github-client-BnIsSrEN.js} +2 -2
- package/server/{github-client-CwBZZ3t7.js → github-client-DfQYVUaw.js} +1 -1
- package/server/{github-pr-lookup-CFGeVhqv.js → github-pr-lookup-D16NGsSO.js} +2 -2
- package/server/{harness-binary-B2CTcD84.js → harness-binary-DPUi-Pv8.js} +32 -6
- package/server/{harness-resolve-D5FVQTmy.js → harness-resolve-3lNZkyT4.js} +18 -9
- package/server/{health-events-DREeevle.js → health-events-BBcTYQKU.js} +2 -2
- package/server/{health-events-C1whmd58.js → health-events-BDOHby5Q.js} +1 -1
- package/server/{hooks-yxRsjk-z.js → hooks-CKZgXlJb.js} +2 -2
- package/server/{hooks-B-HItBiS.js → hooks-DPVX1rwQ.js} +1 -1
- package/server/{hume-Dz_OymXE.js → hume-Cz8igP9E.js} +2 -2
- package/server/hume-ccTf4wTX.js +3 -0
- package/server/{idle-stack-reaper-DrCv0OAG.js → idle-stack-reaper-CuLF0j2H.js} +1 -1
- package/server/{idle-stack-reaper-Yf34xXxY.js → idle-stack-reaper-DDIRwxUY.js} +2 -2
- package/server/{in-flight-guard-BoWm66Kh.js → in-flight-guard-CAAkqPLu.js} +2 -2
- package/server/{infra-D4iNWMA5.js → infra-BEqFxlJc.js} +14 -4
- package/server/{injection-D7T75Pye.js → injection-C8aiVJrF.js} +191 -183
- package/server/{injection-BVNa4MQW.js → injection-CPUIqNhI.js} +1 -1
- package/server/{inspect-agent-BXCgNeZ4.js → inspect-agent-BLuJ1AkT.js} +137 -81
- package/server/inspect-agent-Brtz0URj.js +2 -0
- package/server/{internal-token-C9DdEOKY.js → internal-token-BrcU6qfe.js} +1 -1
- package/server/{internal-token-CXsfxslp.js → internal-token-s0-oKybJ.js} +2 -2
- package/server/{io-DQR9PMgS.js → io-C9kF1wtJ.js} +160 -184
- package/server/{issue-closed-DtmJM0D0.js → issue-closed-CDJk4pIp.js} +7 -7
- package/server/{issue-lifecycle-8PSS9Anq.js → issue-lifecycle-B8sZHVHh.js} +1 -1
- package/server/{issue-lifecycle-CeyW_HoD.js → issue-lifecycle-ojZAzDBP.js} +22 -22
- package/server/{issue-service-singleton-DBZabEl7.js → issue-service-singleton-BvJ09SaR.js} +1 -1
- package/server/{issue-service-singleton-D_RVYBuL.js → issue-service-singleton-Yx5DdmVJ.js} +8 -8
- package/server/{issues-pDW9VUNz.js → issues-BMmP_77e.js} +2 -2
- package/server/{jsonl-parser-C3HVNR5d.js → jsonl-parser-BXSlHwEh.js} +3 -3
- package/server/{label-cleanup-DPwiZlWo.js → label-cleanup-B0UJwnv5.js} +3 -3
- package/server/{label-reconciler-Df1ZduPH.js → label-reconciler-B4iOAjlC.js} +4 -4
- package/server/{launcher-generator-COgR2By1.js → launcher-generator-BBWG_SiS.js} +105 -10
- package/server/{lifecycle-io-taIb0PoH.js → lifecycle-io-BREGpnLk.js} +37 -37
- package/server/lifecycle-io-DPo7x11I.js +3 -0
- package/server/{lifecycle-CtPDcZ9u.js → lifecycle-xmBfK2GJ.js} +6 -6
- package/server/lifecycle-yPd___5E.js +121 -0
- package/server/{linear-client-DsFkIxee.js → linear-client-BsuUvkdA.js} +2 -2
- package/server/{linear-client-YwZMDIwQ.js → linear-client-CTskEeT_.js} +1 -1
- package/server/memory-fts-worker.js +1 -1
- package/server/{merge-BwsyNRJV.js → merge-B1DiziGU.js} +1 -1
- package/server/{merge-C1t-bspg.js → merge-CefQNAnq.js} +3 -3
- package/server/{merge-agent-DDiIjzk-.js → merge-agent-4WOWlSYA.js} +28 -28
- package/server/{merge-agent-B-SnXOoc.js → merge-agent-CKkgIBPB.js} +1 -1
- package/server/{merge-batch-Byt-QnEl.js → merge-batch-ClFn2T-y.js} +1 -1
- package/server/merge-ops-CR44oU9-.js +2 -0
- package/server/{merge-rebase-Cm6fXaZN.js → merge-rebase-BfaTyXsw.js} +2 -2
- package/server/merge-set-DJ8-UErs.js +83 -0
- package/server/{merge-set-6LEglm6o.js → merge-set-bUqbm3yc.js} +1 -1
- package/server/{merge-sync-B95_4in_.js → merge-sync-BJYeOODr.js} +1 -1
- package/server/{merge-sync-Do8_q32h.js → merge-sync-VPV28g0g.js} +2 -2
- package/server/{merge-train-CKana8EH.js → merge-train-CHopycP0.js} +3 -3
- package/server/{merge-train-deps-BgmqwIfA.js → merge-train-deps-D1cOZzy2.js} +4 -4
- package/server/{merge-verification-CqnUzGEK.js → merge-verification-BkaOqPsw.js} +4 -4
- package/server/{multipart-parser-tdOQDJ3o.js → multipart-parser-duPAfSBw.js} +2 -2
- package/server/{no-resume-mode-BWOSZjWd.js → no-resume-mode-Nw29vaFb.js} +11 -8
- package/server/node_modules/.package-lock.json +8 -8
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +3 -3
- package/server/node_modules/undici/README.md +5 -0
- package/server/node_modules/undici/docs/docs/api/Client.md +4 -0
- package/server/node_modules/undici/docs/docs/api/Dispatcher.md +6 -0
- package/server/node_modules/undici/docs/docs/api/Interceptors.md +59 -0
- package/server/node_modules/undici/docs/docs/api/MockAgent.md +27 -0
- package/server/node_modules/undici/docs/docs/api/MockPool.md +28 -1
- package/server/node_modules/undici/docs/docs/index.md +5 -0
- package/server/node_modules/undici/lib/core/request.js +1 -1
- package/server/node_modules/undici/lib/core/util.js +6 -1
- package/server/node_modules/undici/lib/dispatcher/agent.js +3 -3
- package/server/node_modules/undici/lib/dispatcher/client-h1.js +31 -6
- package/server/node_modules/undici/lib/dispatcher/client-h2.js +34 -43
- package/server/node_modules/undici/lib/handler/cache-handler.js +93 -5
- package/server/node_modules/undici/lib/handler/cache-revalidation-handler.js +10 -0
- package/server/node_modules/undici/lib/handler/redirect-handler.js +5 -2
- package/server/node_modules/undici/lib/handler/retry-handler.js +6 -4
- package/server/node_modules/undici/lib/interceptor/cache.js +21 -4
- package/server/node_modules/undici/lib/interceptor/decompress.js +4 -0
- package/server/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
- package/server/node_modules/undici/lib/mock/mock-utils.js +39 -10
- package/server/node_modules/undici/lib/util/cache.js +49 -7
- package/server/node_modules/undici/lib/web/fetch/body.js +2 -1
- package/server/node_modules/undici/lib/web/fetch/response.js +1 -3
- package/server/node_modules/undici/package.json +2 -2
- package/server/node_modules/undici/types/client.d.ts +2 -2
- package/server/node_modules/undici/types/dispatcher.d.ts +3 -3
- package/server/node_modules/undici/types/mock-interceptor.d.ts +5 -1
- package/server/{orphan-proposed-reconciler-xklgvNA7.js → orphan-proposed-reconciler-BvKkWMJQ.js} +15 -13
- package/server/{orphan-proposed-reconciler-DSvsJ5M7.js → orphan-proposed-reconciler-CTSGcK8p.js} +1 -1
- package/server/package-lock.json +9 -9
- package/server/package.json +1 -1
- package/server/{pan-dir-DOcf6ug3.js → pan-dir-B0c3w0Ya.js} +78 -58
- package/server/{paths-DooHpt9p.js → paths-D-xWGHdh.js} +2 -2
- package/server/{pickup-CaskQ7j6.js → pickup-DUCLWrJY.js} +17 -16
- package/server/{pipeline-membership-1LGRjo-k.js → pipeline-membership-mY3GprlK.js} +186 -67
- package/server/{pipeline-notifier-CZsrU_nj.js → pipeline-notifier-BJr8gQX6.js} +1 -1
- package/server/{pipeline-notifier-B6FVsYF9.js → pipeline-notifier-BXkJzDC4.js} +2 -2
- package/server/{project-pipelines-CtNG_rvs.js → project-pipelines-C0MWUeCU.js} +2 -2
- package/server/project-repos-B6GycDh9.js +94 -0
- package/server/project-repos-DXKQsc_m.js +3 -0
- package/server/projects-vjjcmiN8.js +3 -0
- package/server/{prompts-EvhMeeHG.js → prompts-DxzFXuLl.js} +2 -2
- package/server/{providers-BDDPULlp.js → providers-qQAwGQDW.js} +7 -7
- package/server/{providers-DNSQqy2V.js → providers-u4Ga0jOr.js} +1 -1
- package/server/public/assets/{chunk-BO2N2NFS-sym_ufXe.js → chunk-BO2N2NFS-BamJdinX.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-CQJPBNBu.js → diagram-OG6HWLK6-DfOB8-w4.js} +1 -1
- package/server/public/assets/{dist-DukGS2YZ.js → dist-ByIuzMQW.js} +3 -3
- package/server/public/assets/{dist-Bio7THQU.js → dist-D7zYSEA6.js} +1 -1
- package/server/public/assets/{ganttDiagram-6RSMTGT7-D4lWwte3.js → ganttDiagram-6RSMTGT7-EdmRyXL3.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62-CaLboCt5.js → highlighted-body-OFNGDK62-MerOfTX8.js} +1 -1
- package/server/public/assets/{index-Bwejq-5s.js → index-CWeMerGO.js} +147 -144
- package/server/public/assets/index-CenuJ3Cw.css +1 -0
- package/server/public/assets/{linear-qUWmMZ-c.js → linear-BBbArIcK.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-CpPWAFwE.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-C4zYulEm.js → pieDiagram-4H26LBE5-BKIddiJN.js} +1 -1
- package/server/public/assets/{prod-C8VtLuWC.js → prod-B8vYiu52.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-qP04zyZC.js → quadrantDiagram-W4KKPZXB-D6RtoULk.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-eMPTX_cG.js → sankeyDiagram-5OEKKPKP-CLrCedZX.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-Dme1PIt6.js → xychartDiagram-2RQKCTM6-hznR8DYl.js} +1 -1
- package/server/public/index.html +2 -2
- package/server/{pull-requests-By_BteaL.js → pull-requests-7N8WKseP.js} +1 -1
- package/server/{pull-requests-8z2N1UOV.js → pull-requests-_lHueOHW.js} +13 -11
- package/server/{queries-ZABd5aXP.js → queries-CjNIf-Ub.js} +1200 -201
- package/server/{rally-i_goYmiA.js → rally-CyWT_lNO.js} +3 -3
- package/server/{rally-api-DqKqIMNR.js → rally-api-C8e_1JRi.js} +2 -2
- package/server/{rally-api-xHazRk0d.js → rally-api-ClOSd-Tt.js} +1 -1
- package/server/{rally-client-COYz1vYR.js → rally-client-lc-nokqr.js} +4 -4
- package/server/{rally-client-CGWEHaPd.js → rally-client-sgtVqzNU.js} +1 -1
- package/server/rally-zhhtXuDP.js +3 -0
- package/server/{reap-terminal-sessions-CaMkFOIH.js → reap-terminal-sessions-7KeHv1R1.js} +1 -1
- package/server/{reap-terminal-sessions-DG9eiMVz.js → reap-terminal-sessions-BtHPo6Xc.js} +1 -1
- package/server/rebuild-stack-CFvcBHsS.js +4 -0
- package/server/{rebuild-stack-JUm0jqYP.js → rebuild-stack-lwtsW0GO.js} +26 -35
- package/server/{reconstruct-cache-wU79aCee.js → reconstruct-cache-C3Ui7ojV.js} +6 -6
- package/server/record-CN0pj4_5.js +3 -0
- package/server/{record-update-D3N6WMFR.js → record-update-bLJxAXH4.js} +1 -1
- package/server/record-update-dE1Aw83j.js +310 -0
- package/server/{recovery-trip-DkzJSej9.js → recovery-trip-BvRWfUXM.js} +2 -2
- package/server/{release-engine-DMINVN8S.js → release-engine-Cx48W7z8.js} +5 -5
- package/server/{release-set-DeUSOEHy.js → release-set-CQfuN9-v.js} +3 -3
- package/server/{remote-b-c5bOce.js → remote-C_2hasl7.js} +3 -3
- package/server/{remote-Dr5kGYSZ.js → remote-ChgimyYa.js} +3 -3
- package/server/{remote-agents-Ct_WOyke.js → remote-agents-By1ige5O.js} +6 -6
- package/server/{remote-agents-D6O_zETW.js → remote-agents-CA3Ihlxj.js} +1 -1
- package/server/{remote-completion-Dca3hAaa.js → remote-completion-fVe9e_3u.js} +12 -12
- package/server/resume-BFv1PGpA.js +3 -0
- package/server/{review-agent-CThvgK2r.js → review-agent-CIGOQYBD.js} +29 -25
- package/server/{review-agent-CCum8sGe.js → review-agent-DNboMyW4.js} +1 -1
- package/server/{review-artifacts-CXywD0F2.js → review-artifacts-nRDPuMxd.js} +5 -5
- package/server/{review-context-OYfKUprb.js → review-context-2uj-YQ8J.js} +70 -26
- package/server/review-status-btEYlaxA.js +3 -0
- package/server/{review-status-enrichment-crNAtIpL.js → review-status-enrichment-Dci-ZwEt.js} +3 -3
- package/server/{review-status-DFRjDFef.js → review-status-kZj_KyCk.js} +77 -28
- package/server/{review-status-sync-DpAMD_WO.js → review-status-sync-BTOpxtTC.js} +10 -5
- package/server/{review-status-sync-D60PJWNL.js → review-status-sync-DSDK3OMy.js} +1 -1
- package/server/{review-verdict-feedback-CpUZl5aE.js → review-verdict-feedback-CCjVA7Uk.js} +6 -6
- package/server/{review-verdict-feedback-JImjut0z.js → review-verdict-feedback-CTd4QMBu.js} +1 -1
- package/server/{rollup-CZ02qgxk.js → rollup-BKQC7jp4.js} +1 -1
- package/server/{rollup-SyuF09e4.js → rollup-FGsKki9R.js} +8 -8
- package/server/{scanner-Br0Z5S6R.js → scanner-CnqEZeDy.js} +45 -14
- package/server/{sequence-io-fxU0DlwW.js → sequence-io-D909zgeH.js} +4 -4
- package/server/{sequencer-agent-B5YC5XVP.js → sequencer-agent-CzkcK6P5.js} +5 -5
- package/server/server.js +2961 -919
- package/server/{service-Bagb90KZ.js → service-CLeAoU6G.js} +55 -54
- package/server/{session-fork-BqQxd-V6.js → session-fork-CHI1XvL9.js} +2 -2
- package/server/{session-history-XdS0JKp3.js → session-history-BT3IvqhC.js} +4 -4
- package/server/settings-66A6uvIA.js +2 -0
- package/server/{settings-BNbocWOg.js → settings-BTMvpNFU.js} +3 -3
- package/server/{settings-uLc6DEYI.js → settings-C0zgxOGf.js} +2 -2
- package/server/{shadow-engineering-D4X_s3fA.js → shadow-engineering-BJfgm-hX.js} +2 -2
- package/server/{shadow-state-C_NkP-sa.js → shadow-state-7a-524T8.js} +2 -2
- package/server/{shadow-state-CbvsN3qG.js → shadow-state-DnDyjujH.js} +1 -1
- package/server/{shadow-utils-CYMRPeRT.js → shadow-utils-Db3oroFG.js} +2 -2
- package/server/{ship-log-__QtAFXG.js → ship-log-D9MlVzYU.js} +1 -1
- package/server/{smart-compaction-jdMkG1vo.js → smart-compaction-CV2ukKND.js} +1 -1
- package/server/{smart-compaction-CLZOWin1.js → smart-compaction-KCYScAU1.js} +7 -7
- package/server/{spawn-planning-session-D5OXo8pT.js → spawn-planning-session-DKpdFyOC.js} +35 -27
- package/server/{spawn-planning-session-8D6mE033.js → spawn-planning-session-qUC2VWu3.js} +1 -1
- package/server/{specialist-completion-CqmduO92.js → specialist-completion-Ky9wCDpb.js} +1 -1
- package/server/{specialist-context-CJ-QjFR-.js → specialist-context-Bn3dCGS2.js} +5 -5
- package/server/{specialist-handoff-logger-Dnjlwt7g.js → specialist-handoff-logger-CMEwYxa2.js} +2 -2
- package/server/{specialist-logs-CQnKzuZs.js → specialist-logs-C5p8G7tx.js} +3 -3
- package/server/{specialists-Bg9v4z3F.js → specialists-CC4r-c2s.js} +1015 -460
- package/server/{specialists-D0gGXMZx.js → specialists-CShuVGWT.js} +1 -1
- package/server/specialists-DM6bWjsi.js +3 -0
- package/server/{specialists-CwZHb5cb.js → specialists-jiuuyVkp.js} +66 -74
- package/server/specs-C8Wsn2XO.js +3 -0
- package/server/{src-BMMoA_ba.js → src-CXmtj0im.js} +6 -6
- package/server/{src-Bqdtd6po.js → src-CdmnTM2m.js} +5 -5
- package/server/{src-k039WVYY.js → src-DtcUOZCq.js} +112 -18
- package/server/stack-health-Bn3o8FBX.js +3 -0
- package/server/{stack-health-C-ifC7b0.js → stack-health-DxSdG9cW.js} +63 -9
- package/server/{stale-task-claims-L7pJkQFL.js → stale-task-claims-KJKxxiiQ.js} +4 -4
- package/server/{staleness-_Tr-GwdA.js → staleness-CT34nwr9.js} +1 -1
- package/server/{staleness-BID1BKdr.js → staleness-DPm7ClwA.js} +15 -3
- package/server/{state-home-CONQvZR0.js → state-home-Cn_Qu8IX.js} +96 -44
- package/server/{state-migrate-BeBW0KXA.js → state-migrate-BGg2ZaOt.js} +12 -3
- package/server/{stuck-remediation-CKnIryGT.js → stuck-remediation-DYuPRYYw.js} +307 -26
- package/server/{stuck-remediation-CsGD5Ksb.js → stuck-remediation-s9_2qfi6.js} +1 -1
- package/server/{substrate-bug-weights-service-CpIZILj9.js → substrate-bug-weights-service-B-FwCs5V.js} +3 -3
- package/server/{summary-fork-bX6ax6X7.js → summary-fork-D1RAk9rJ.js} +78 -12
- package/server/{summary-fork-agEMsPSo.js → summary-fork-DpcxN9tf.js} +2 -2
- package/server/supervisor/{injection-budget-C1iPirFS.js → injection-budget-Csw5tqfJ.js} +2 -41
- package/server/supervisor/pty-supervisor.js +2 -1
- package/server/supervisor/pty-token-x-ea28Us.js +43 -0
- package/server/supervisor-FTJAIsAK.js +2 -0
- package/server/{supervisor-Ctt4eRYz.js → supervisor-wM4ooB5O.js} +3 -3
- package/server/{swarm-readiness-DdmJVX7y.js → swarm-readiness-DlP_UjHq.js} +4 -4
- package/server/{system-prerequisites-DSXBvffY.js → system-prerequisites-DUDj1YHf.js} +56 -29
- package/server/{teardown-workspace-DDCf5n-a.js → teardown-workspace-DeTTImn-.js} +15 -15
- package/server/{test-agent-queue-BJZ9Nfcc.js → test-agent-queue-MbxX5vqq.js} +7 -7
- package/server/{test-verdict-Cp5tljlJ.js → test-verdict-bWYBtqBg.js} +1 -1
- package/server/{test-verdict-D_-sXIz_.js → test-verdict-gscuksPv.js} +1 -1
- package/server/{tldr-daemon-B8_oT5gx.js → tldr-daemon-BYFkts95.js} +1 -1
- package/server/{tldr-daemon-BQFmmFp0.js → tldr-daemon-C-69c3OI.js} +2 -2
- package/server/tmux-B6z7h_vZ.js +3 -0
- package/server/{tmux-L5LgvGLp.js → tmux-R7N7y-Mh.js} +76 -44
- package/server/{token-BkQLy4yS.js → token-BK6t8BIT.js} +2 -2
- package/server/token-util-DuPuNriz.js +3 -0
- package/server/{token-util-DI8sGlmF.js → token-util-DxXu-vd1.js} +1 -1
- package/server/{tracker-config-DdT-nUAM.js → tracker-config-G6latr8C.js} +2 -2
- package/server/{tracker-utils-DV3h1FYG.js → tracker-utils-B4ylXZQK.js} +1 -1
- package/server/{tracker-utils-CawsPSS2.js → tracker-utils-DHv5pSDT.js} +2 -2
- package/server/{traefik-connect-C6mJckNs.js → traefik-connect-Df2uXPsQ.js} +1 -1
- package/server/{tunnel-IdK1iTHx.js → tunnel-CDVKJpRv.js} +3 -3
- package/server/{tunnel-BIFl98rc.js → tunnel-DGdUkGoZ.js} +1 -1
- package/server/{types-7-GnJn0t.js → types-5M0lupud.js} +1 -1
- package/server/{uat-train-0Ujk8GCv.js → uat-train-B05BWkp-.js} +1 -1
- package/server/{uat-train-j0cPeMSj.js → uat-train-DDSrSoV1.js} +28 -28
- package/server/validate-IfDGkaVR.js +177 -0
- package/server/{validation-DcAgXTQp.js → validation-CC9OPqJZ.js} +1 -1
- package/server/{validation-CabEISJT.js → validation-Dw1pzDzr.js} +259 -9
- package/server/{verification-artifact-Ck1tefmz.js → verification-artifact-B3itKTxu.js} +1 -1
- package/server/{verification-artifact-BuTA1QbL.js → verification-artifact-TVFSz_q1.js} +1 -1
- package/server/{verification-runner-DlJezzef.js → verification-runner-BW4HOKAz.js} +1 -1
- package/server/{verification-runner-FiuAZ-H2.js → verification-runner-CkgX6EtI.js} +174 -124
- package/server/{vtt-parser-BnRsYzcz.js → vtt-parser-DYPbKcIJ.js} +1 -1
- package/server/{work-agent-prompt-DLthEPAq.js → work-agent-prompt-Du8Vh2aJ.js} +13 -13
- package/server/workflows-BQu4RFQ-.js +2 -0
- package/server/{workflows-BZNNYkGC.js → workflows-mbQzh6mQ.js} +39 -77
- package/server/{workspace-3IC-UkAi.js → workspace--8tnhDI0.js} +1 -1
- package/server/{workspace-D9ppycdg.js → workspace-BPUws1-_.js} +3 -3
- package/server/{workspace-config-Bigl_-Lk.js → workspace-config-CIVWZOQr.js} +1 -1
- package/server/{workspace-manager-ClkCIWTe.js → workspace-manager-CBhNdzE4.js} +76 -18
- package/server/workspace-manager-CWT55qeI.js +3 -0
- package/server/{workspace-metadata-BE0efUv_.js → workspace-metadata-BzHnwwX4.js} +1 -1
- package/server/{workspace-metadata-tiSRIWJP.js → workspace-metadata-_WygnyoX.js} +2 -2
- package/server/{workspaces-CFPcL0vl.js → workspaces-Do_9J0LQ.js} +309 -124
- package/sync-sources/agents/pan-inspect-agent.md +1 -1
- package/sync-sources/agents/pan-merge-agent.md +1 -1
- package/sync-sources/agents/pan-planning-agent.md +4 -4
- package/sync-sources/agents/pan-work-agent.md +1 -1
- package/sync-sources/dev-skills/pan-commit/SKILL.md +1 -1
- package/sync-sources/dev-skills/test-specialist-workflow/SKILL.md +1 -1
- package/sync-sources/hooks/record-cost-event.js +369 -75
- package/sync-sources/hooks/session-start-hook +7 -0
- package/sync-sources/hooks/work-agent-stop-hook +1 -1
- package/sync-sources/rules/per-bead-durability.md +1 -1
- package/sync-sources/rules/prd-authoring.md +1 -1
- package/sync-sources/skills/feature-work/SKILL.md +1 -1
- package/sync-sources/skills/okf/README.md +11 -3
- package/sync-sources/skills/okf/SKILL.md +12 -1
- package/sync-sources/skills/okf/docs/USAGE.md +15 -0
- package/sync-sources/skills/okf/references/overdeck.md +28 -0
- package/sync-sources/skills/pan/SKILL.md +2 -2
- package/sync-sources/skills/pan-admin-config/SKILL.md +1 -0
- package/sync-sources/skills/pan-approve/SKILL.md +1 -1
- package/sync-sources/skills/pan-close/SKILL.md +1 -1
- package/sync-sources/skills/pan-doctor/SKILL.md +1 -1
- package/sync-sources/skills/pan-flywheel/SKILL.md +18 -1
- package/sync-sources/skills/pan-knowledge/SKILL.md +10 -0
- package/sync-sources/skills/pan-new-project/SKILL.md +9 -11
- package/sync-sources/skills/pan-orders/SKILL.md +33 -0
- package/sync-sources/skills/pan-oversee/SKILL.md +5 -5
- package/sync-sources/skills/pan-plan/SKILL.md +6 -6
- package/sync-sources/skills/pan-quickstart/SKILL.md +1 -1
- package/sync-sources/skills/pan-recap/SKILL.md +2 -2
- package/sync-sources/skills/pan-review/SKILL.md +1 -1
- package/sync-sources/skills/pan-start/SKILL.md +7 -3
- package/sync-sources/skills/pan-swarm/SKILL.md +1 -1
- package/sync-sources/skills/pan-sync/SKILL.md +1 -1
- package/sync-sources/skills/pan-task/SKILL.md +2 -2
- package/sync-sources/skills/pan-wipe/SKILL.md +2 -2
- package/sync-sources/skills/pipeline-list/SKILL.md +1 -1
- package/sync-sources/skills/pipeline-status/SKILL.md +2 -2
- package/sync-sources/skills/plan/SKILL.md +11 -11
- package/sync-sources/skills/write-vbrief/SKILL.md +7 -282
- package/sync-sources/skills/write-xbrief/SKILL.md +295 -0
- package/sync-sources/templates/claude-md/sections/warnings.md +1 -1
- package/sync-sources/templates/traefik/dynamic/overdeck.yml.template +10 -0
- package/server/agent-state-Co5Sy2Fw.js +0 -3
- package/server/agents-DyHKlq1I.js +0 -3
- package/server/cli-BRORS9qY.js +0 -3
- package/server/codex-DNyiQDKW.js +0 -3
- package/server/context-layers-15gDOk20.js +0 -165
- package/server/context-layers-DlQKkHH2.js +0 -4
- package/server/deacon-swarm-CV54eNmU.js +0 -2
- package/server/dist-j64RzSrQ.js +0 -3
- package/server/flywheel-6WHU4O7A.js +0 -207
- package/server/flywheel-COR0mbRI.js +0 -522
- package/server/flywheel-Ctr5uuvo.js +0 -2
- package/server/forge-B0_opi-V.js +0 -2
- package/server/git-utils-CsKGnzFA.js +0 -3
- package/server/hume-BmhvfVbV.js +0 -3
- package/server/inspect-agent-Dq0z1k3H.js +0 -2
- package/server/layers-Cp1To4L8.js +0 -93
- package/server/lifecycle-io-DmY2qwCn.js +0 -3
- package/server/merge-blockers-BYjeXrVN.js +0 -41
- package/server/merge-ops-DwWCkSgo.js +0 -2
- package/server/merge-set-DiISXcC-.js +0 -139
- package/server/projects-BKkwpH6q.js +0 -3
- package/server/public/assets/index-Bdc4V9ba.css +0 -1
- package/server/public/assets/mermaid-GHXKKRXX-B5v_r7cI.js +0 -1
- package/server/rally-OSJXdiHK.js +0 -3
- package/server/rebuild-stack-CKjJAI8L.js +0 -3
- package/server/record-rwK-nKv_.js +0 -3
- package/server/record-update-Crz74r-6.js +0 -168
- package/server/resume-wZZsWtzz.js +0 -3
- package/server/review-status-Bnh-rdkY.js +0 -3
- package/server/settings-BlUsVaUc.js +0 -2
- package/server/specialists-Dqe6_HE5.js +0 -3
- package/server/specs-BhOKBzqk.js +0 -3
- package/server/stack-health-Bd06frFn.js +0 -3
- package/server/supervisor-COVHrBTg.js +0 -2
- package/server/tmux-BAvtac_u.js +0 -3
- package/server/token-util-BArZLN6w.js +0 -3
- package/server/workflows-C4mR0Reb.js +0 -2
- package/server/workspace-manager-B1WOfKvB.js +0 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/platform-node-shared",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.0.0-beta.
|
|
4
|
+
"version": "4.0.0-beta.101",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Unified interfaces for common platform-specific services",
|
|
7
7
|
"homepage": "https://effect.website",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"provenance": true
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"effect": "^4.0.0-beta.
|
|
49
|
+
"effect": "^4.0.0-beta.101"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/node": "^26.1.1",
|
|
53
53
|
"tar": "^7.5.19",
|
|
54
|
-
"effect": "^4.0.0-beta.
|
|
54
|
+
"effect": "^4.0.0-beta.101"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@types/ws": "^8.18.1",
|
|
@@ -408,6 +408,11 @@ For more information about their behavior, please reference the body mixin from
|
|
|
408
408
|
|
|
409
409
|
This section documents our most commonly used API methods. Additional APIs are documented in their own files within the [docs](./docs/) folder and are accessible via the navigation list on the left side of the docs site.
|
|
410
410
|
|
|
411
|
+
For the top-level APIs below, the `url` argument supplies the request origin and
|
|
412
|
+
path. Do not pass `origin` or `path` in the second `options` argument. The linked
|
|
413
|
+
`Dispatcher` option types include those fields because dispatcher methods are
|
|
414
|
+
lower-level APIs that do not receive a separate `url` argument.
|
|
415
|
+
|
|
411
416
|
### `undici.request([url, options]): Promise`
|
|
412
417
|
|
|
413
418
|
Arguments:
|
|
@@ -49,6 +49,10 @@ added: v1.0.0
|
|
|
49
49
|
* `headersTimeout` {number|null} The timeout, in milliseconds, the parser
|
|
50
50
|
waits to receive the complete HTTP headers before the request times out. Use
|
|
51
51
|
`0` to disable it entirely. **Default:** `300e3`.
|
|
52
|
+
HTTP/1.1 headers/body parser timeouts are not guaranteed to fire with exact
|
|
53
|
+
millisecond precision: delays up to 1000ms use native timers, while larger
|
|
54
|
+
delays use undici's lower-overhead fast timers with a target resolution
|
|
55
|
+
around 500ms.
|
|
52
56
|
* `connectTimeout` {number|null} The timeout, in milliseconds, for
|
|
53
57
|
establishing a socket connection. Use `0` to disable it entirely.
|
|
54
58
|
**Default:** `10e3`.
|
|
@@ -228,6 +228,10 @@ added: v4.0.0
|
|
|
228
228
|
* `bodyTimeout` {number|null} The time, in milliseconds, after which the request
|
|
229
229
|
times out while receiving body data. Monitors the time between body chunks.
|
|
230
230
|
Use `0` to disable it entirely. Defaults to 300 seconds.
|
|
231
|
+
HTTP/1.1 headers/body parser timeouts are not guaranteed to fire with exact
|
|
232
|
+
millisecond precision: delays up to 1000ms use native timers, while larger
|
|
233
|
+
delays use undici's lower-overhead fast timers with a target resolution
|
|
234
|
+
around 500ms.
|
|
231
235
|
* `reset` {boolean} Whether the request should establish a keep-alive
|
|
232
236
|
connection. **Default:** `false`.
|
|
233
237
|
* `expectContinue` {boolean} For HTTP/2, appends the `expect: 100-continue`
|
|
@@ -729,6 +733,8 @@ await client.request({ path: '/', method: 'GET' })
|
|
|
729
733
|
```
|
|
730
734
|
|
|
731
735
|
For the full list of built-in interceptors provided by undici, see [Interceptors](Interceptors.md).
|
|
736
|
+
For an example of a custom interceptor that wraps handler callbacks, see
|
|
737
|
+
[Custom interceptors](Interceptors.md#custom-interceptors).
|
|
732
738
|
|
|
733
739
|
### Event: `'connect'`
|
|
734
740
|
|
|
@@ -32,6 +32,65 @@ const client = new Client('https://example.com').compose(
|
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
+
## Custom interceptors
|
|
36
|
+
|
|
37
|
+
Custom interceptors use the same shape as
|
|
38
|
+
[`dispatcher.compose()`](./Dispatcher.md#dispatchercomposeinterceptors-interceptor):
|
|
39
|
+
an interceptor takes a `dispatch` function and returns another dispatch-like
|
|
40
|
+
function with the same `(options, handler)` signature.
|
|
41
|
+
|
|
42
|
+
When an interceptor wraps the handler, forward the callbacks that it does not
|
|
43
|
+
handle itself. The complete handler callback list is documented under
|
|
44
|
+
[`dispatcher.dispatch(options, handler)`](./Dispatcher.md#dispatcherdispatchoptions-handler).
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
import { Agent } from 'undici'
|
|
48
|
+
|
|
49
|
+
const timingInterceptor = dispatch => {
|
|
50
|
+
return (options, handler) => {
|
|
51
|
+
const started = performance.now()
|
|
52
|
+
|
|
53
|
+
return dispatch(options, {
|
|
54
|
+
...handler,
|
|
55
|
+
onResponseStart (controller, statusCode, headers, statusMessage) {
|
|
56
|
+
const duration = Math.round(performance.now() - started)
|
|
57
|
+
const method = options.method ?? 'GET'
|
|
58
|
+
const origin = options.origin ?? ''
|
|
59
|
+
|
|
60
|
+
console.log(`${method} ${origin}${options.path} -> ${statusCode} in ${duration}ms`)
|
|
61
|
+
|
|
62
|
+
return handler.onResponseStart?.(
|
|
63
|
+
controller,
|
|
64
|
+
statusCode,
|
|
65
|
+
headers,
|
|
66
|
+
statusMessage
|
|
67
|
+
)
|
|
68
|
+
},
|
|
69
|
+
onResponseError (controller, error) {
|
|
70
|
+
const duration = Math.round(performance.now() - started)
|
|
71
|
+
|
|
72
|
+
console.error(`request failed after ${duration}ms`, error)
|
|
73
|
+
|
|
74
|
+
return handler.onResponseError?.(controller, error)
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const dispatcher = new Agent().compose(timingInterceptor)
|
|
81
|
+
|
|
82
|
+
const { body } = await dispatcher.request({
|
|
83
|
+
origin: 'https://example.com',
|
|
84
|
+
path: '/',
|
|
85
|
+
method: 'GET'
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
await body.dump()
|
|
89
|
+
await dispatcher.close()
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
35
94
|
## `interceptors.dump([opts])`
|
|
36
95
|
|
|
37
96
|
Reads and discards the response body up to a configurable size limit. Useful
|
|
@@ -17,6 +17,13 @@ registered on the {MockClient} or {MockPool} instances returned by
|
|
|
17
17
|
`MockAgent` is set as the dispatcher (for example through
|
|
18
18
|
[`setGlobalDispatcher()`][] or a per-request `dispatcher` option).
|
|
19
19
|
|
|
20
|
+
> [!NOTE]
|
|
21
|
+
> [`setGlobalDispatcher()`][] only affects undici APIs that use the global
|
|
22
|
+
> dispatcher, such as `request()` and `fetch()`. It does not replace or
|
|
23
|
+
> monkeypatch {Pool} or {Client} instances that were created separately. To test
|
|
24
|
+
> code that accepts or creates a pool/client directly, pass the {MockPool} or
|
|
25
|
+
> {MockClient} returned by [`mockAgent.get(origin)`][] into that code.
|
|
26
|
+
|
|
20
27
|
```mjs
|
|
21
28
|
import { MockAgent } from 'undici'
|
|
22
29
|
|
|
@@ -139,6 +146,26 @@ for await (const data of body) {
|
|
|
139
146
|
}
|
|
140
147
|
```
|
|
141
148
|
|
|
149
|
+
```mjs displayName="Testing code that accepts a pool"
|
|
150
|
+
import { MockAgent } from 'undici'
|
|
151
|
+
|
|
152
|
+
async function getStatus (pool) {
|
|
153
|
+
const { statusCode } = await pool.request({
|
|
154
|
+
path: '/foo',
|
|
155
|
+
method: 'GET'
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
return statusCode
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const mockAgent = new MockAgent()
|
|
162
|
+
const mockPool = mockAgent.get('http://localhost:3000')
|
|
163
|
+
|
|
164
|
+
mockPool.intercept({ path: '/foo', method: 'GET' }).reply(200)
|
|
165
|
+
|
|
166
|
+
console.log(await getStatus(mockPool)) // 200
|
|
167
|
+
```
|
|
168
|
+
|
|
142
169
|
```mjs displayName="Returning a MockClient"
|
|
143
170
|
import { MockAgent, request } from 'undici'
|
|
144
171
|
|
|
@@ -136,7 +136,8 @@ The reply behaviour of a matching request is defined through the returned
|
|
|
136
136
|
computing all reply options dynamically rather than just the body.
|
|
137
137
|
* `callback` {Function} A `(opts: MockResponseCallbackOptions) =>
|
|
138
138
|
{ statusCode, data, responseOptions }` function invoked with the incoming
|
|
139
|
-
request.
|
|
139
|
+
request. The callback may be asynchronous; a returned promise is awaited
|
|
140
|
+
and must resolve to the same shape.
|
|
140
141
|
* Returns: {MockScope}
|
|
141
142
|
* `replyWithError(error)` {Function} Defines an error for a matching request to
|
|
142
143
|
throw.
|
|
@@ -263,6 +264,32 @@ for await (const data of body) {
|
|
|
263
264
|
}
|
|
264
265
|
```
|
|
265
266
|
|
|
267
|
+
```mjs displayName="Reply with an asynchronous options callback"
|
|
268
|
+
import { readFile } from 'node:fs/promises'
|
|
269
|
+
import { MockAgent, setGlobalDispatcher, request } from 'undici'
|
|
270
|
+
|
|
271
|
+
const mockAgent = new MockAgent()
|
|
272
|
+
setGlobalDispatcher(mockAgent)
|
|
273
|
+
|
|
274
|
+
const mockPool = mockAgent.get('http://localhost:3000')
|
|
275
|
+
|
|
276
|
+
mockPool.intercept({
|
|
277
|
+
path: '/fixture',
|
|
278
|
+
method: 'GET'
|
|
279
|
+
}).reply(async ({ path }) => ({
|
|
280
|
+
statusCode: 200,
|
|
281
|
+
data: await readFile(new URL('./fixture.json', import.meta.url))
|
|
282
|
+
}))
|
|
283
|
+
|
|
284
|
+
const { statusCode, body } = await request('http://localhost:3000/fixture')
|
|
285
|
+
|
|
286
|
+
console.log('response received', statusCode) // response received 200
|
|
287
|
+
|
|
288
|
+
for await (const data of body) {
|
|
289
|
+
console.log('data', data.toString('utf8')) // contents of fixture.json
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
266
293
|
```mjs displayName="Multiple intercepts"
|
|
267
294
|
import { MockAgent, setGlobalDispatcher, request } from 'undici'
|
|
268
295
|
|
|
@@ -410,6 +410,11 @@ For more information about their behavior, please reference the body mixin from
|
|
|
410
410
|
|
|
411
411
|
This section documents our most commonly used API methods. Additional APIs are documented in their own files within the [docs](./docs/) folder and are accessible via the navigation list on the left side of the docs site.
|
|
412
412
|
|
|
413
|
+
For the top-level APIs below, the `url` argument supplies the request origin and
|
|
414
|
+
path. Do not pass `origin` or `path` in the second `options` argument. The linked
|
|
415
|
+
`Dispatcher` option types include those fields because dispatcher methods are
|
|
416
|
+
lower-level APIs that do not receive a separate `url` argument.
|
|
417
|
+
|
|
413
418
|
### `undici.request([url, options])`
|
|
414
419
|
|
|
415
420
|
* `url` {string|URL|UrlObject}
|
|
@@ -370,7 +370,12 @@ function destroy (stream, err) {
|
|
|
370
370
|
stream.socket = null
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
-
|
|
373
|
+
try {
|
|
374
|
+
stream.destroy(err)
|
|
375
|
+
} catch {
|
|
376
|
+
// stream.destroy may throw on managed sockets (e.g., http2).
|
|
377
|
+
// Silently ignore — the socket lifecycle is handled by the subsystem.
|
|
378
|
+
}
|
|
374
379
|
} else if (err) {
|
|
375
380
|
queueMicrotask(() => {
|
|
376
381
|
stream.emit('error', err)
|
|
@@ -107,15 +107,15 @@ class Agent extends DispatcherBase {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
let hasOrigin = false
|
|
110
|
-
for (const
|
|
111
|
-
if (
|
|
110
|
+
for (const k of this[kClients].keys()) {
|
|
111
|
+
if (k === origin || k === `${origin}#http1-only`) {
|
|
112
112
|
hasOrigin = true
|
|
113
113
|
break
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
if (!hasOrigin) {
|
|
118
|
-
this[kOrigins].delete(
|
|
118
|
+
this[kOrigins].delete(origin)
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
@@ -60,6 +60,7 @@ const removeAllListeners = util.removeAllListeners
|
|
|
60
60
|
const kIdleSocketValidation = Symbol('kIdleSocketValidation')
|
|
61
61
|
const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout')
|
|
62
62
|
const kSocketUsed = Symbol('kSocketUsed')
|
|
63
|
+
const kTypeOfService = Symbol('kTypeOfService')
|
|
63
64
|
|
|
64
65
|
let extractBody
|
|
65
66
|
|
|
@@ -1050,7 +1051,7 @@ function onSocketClose () {
|
|
|
1050
1051
|
|
|
1051
1052
|
function clearIdleSocketValidation (socket) {
|
|
1052
1053
|
if (socket[kIdleSocketValidationTimeout]) {
|
|
1053
|
-
|
|
1054
|
+
clearImmediate(socket[kIdleSocketValidationTimeout])
|
|
1054
1055
|
socket[kIdleSocketValidationTimeout] = null
|
|
1055
1056
|
}
|
|
1056
1057
|
|
|
@@ -1059,14 +1060,14 @@ function clearIdleSocketValidation (socket) {
|
|
|
1059
1060
|
|
|
1060
1061
|
function scheduleIdleSocketValidation (client, socket) {
|
|
1061
1062
|
socket[kIdleSocketValidation] = 1
|
|
1062
|
-
socket[kIdleSocketValidationTimeout] =
|
|
1063
|
+
socket[kIdleSocketValidationTimeout] = setImmediate(() => {
|
|
1063
1064
|
socket[kIdleSocketValidationTimeout] = null
|
|
1064
1065
|
socket[kIdleSocketValidation] = 2
|
|
1065
1066
|
|
|
1066
1067
|
if (client[kSocket] === socket && !socket.destroyed) {
|
|
1067
1068
|
client[kResume]()
|
|
1068
1069
|
}
|
|
1069
|
-
}
|
|
1070
|
+
})
|
|
1070
1071
|
socket[kIdleSocketValidationTimeout].unref?.()
|
|
1071
1072
|
}
|
|
1072
1073
|
|
|
@@ -1134,6 +1135,32 @@ function shouldSendContentLength (method) {
|
|
|
1134
1135
|
return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT'
|
|
1135
1136
|
}
|
|
1136
1137
|
|
|
1138
|
+
function setTypeOfService (socket, request) {
|
|
1139
|
+
if (typeof socket.setTypeOfService !== 'function') {
|
|
1140
|
+
return
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
const typeOfService = request.typeOfService
|
|
1144
|
+
|
|
1145
|
+
if (typeOfService === undefined) {
|
|
1146
|
+
return
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
const currentTypeOfService = socket[kTypeOfService]
|
|
1150
|
+
|
|
1151
|
+
if (currentTypeOfService === typeOfService) {
|
|
1152
|
+
return
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
try {
|
|
1156
|
+
socket.setTypeOfService(typeOfService)
|
|
1157
|
+
socket[kTypeOfService] = typeOfService
|
|
1158
|
+
} catch {
|
|
1159
|
+
// QoS marking is best-effort. setTypeOfService() can throw synchronously on
|
|
1160
|
+
// some platforms depending on socket state, but that must not abort the request.
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1137
1164
|
/**
|
|
1138
1165
|
* @param {import('./client.js')} client
|
|
1139
1166
|
* @param {import('../core/request.js')} request
|
|
@@ -1265,9 +1292,7 @@ function writeH1 (client, request) {
|
|
|
1265
1292
|
socket[kBlocking] = true
|
|
1266
1293
|
}
|
|
1267
1294
|
|
|
1268
|
-
|
|
1269
|
-
socket.setTypeOfService(request.typeOfService)
|
|
1270
|
-
}
|
|
1295
|
+
setTypeOfService(socket, request)
|
|
1271
1296
|
|
|
1272
1297
|
let header = `${method} ${path} HTTP/1.1\r\n`
|
|
1273
1298
|
|
|
@@ -157,9 +157,10 @@ function completeRequest (client, request, resetPendingIdx = false) {
|
|
|
157
157
|
const queue = client[kQueue]
|
|
158
158
|
const runningIdx = client[kRunningIdx]
|
|
159
159
|
|
|
160
|
-
// In-order completion:
|
|
161
|
-
// The client's resume loop compacts
|
|
160
|
+
// In-order completion: clear the request and advance without splicing.
|
|
161
|
+
// The client's resume loop compacts cleared slots once the index grows.
|
|
162
162
|
if (runningIdx < client[kPendingIdx] && queue[runningIdx] === request) {
|
|
163
|
+
queue[runningIdx] = null
|
|
163
164
|
client[kRunningIdx] = runningIdx + 1
|
|
164
165
|
return
|
|
165
166
|
}
|
|
@@ -246,7 +247,6 @@ function connectH2 (client, socket) {
|
|
|
246
247
|
|
|
247
248
|
util.addListener(session, 'error', onHttp2SessionError)
|
|
248
249
|
util.addListener(session, 'frameError', onHttp2FrameError)
|
|
249
|
-
util.addListener(session, 'end', onHttp2SessionEnd)
|
|
250
250
|
util.addListener(session, 'goaway', onHttp2SessionGoAway)
|
|
251
251
|
util.addListener(session, 'close', onHttp2SessionClose)
|
|
252
252
|
util.addListener(session, 'remoteSettings', onHttp2RemoteSettings)
|
|
@@ -322,16 +322,6 @@ function connectH2 (client, socket) {
|
|
|
322
322
|
// Don't dispatch an upgrade until all preceding requests have completed.
|
|
323
323
|
// Possibly, we do not have remote settings confirmed yet.
|
|
324
324
|
if ((request.upgrade === 'websocket' || request.method === 'CONNECT') && session[kRemoteSettings] === false) return true
|
|
325
|
-
// Request with stream or iterator body can error while other requests
|
|
326
|
-
// are inflight and indirectly error those as well.
|
|
327
|
-
// Ensure this doesn't happen by waiting for inflight
|
|
328
|
-
// to complete before dispatching.
|
|
329
|
-
|
|
330
|
-
// Request with stream or iterator body cannot be retried.
|
|
331
|
-
// Ensure that no other requests are inflight and
|
|
332
|
-
// could cause failure.
|
|
333
|
-
if (util.bodyLength(request.body) !== 0 &&
|
|
334
|
-
(util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) return true
|
|
335
325
|
} else {
|
|
336
326
|
return (request.upgrade === 'websocket' || request.method === 'CONNECT') && session[kRemoteSettings] === false
|
|
337
327
|
}
|
|
@@ -505,12 +495,6 @@ function onHttp2FrameError (type, code, id) {
|
|
|
505
495
|
}
|
|
506
496
|
}
|
|
507
497
|
|
|
508
|
-
function onHttp2SessionEnd () {
|
|
509
|
-
const err = new SocketError('other side closed', util.getSocketInfo(this[kSocket]))
|
|
510
|
-
this.destroy(err)
|
|
511
|
-
util.destroy(this[kSocket], err)
|
|
512
|
-
}
|
|
513
|
-
|
|
514
498
|
/**
|
|
515
499
|
* This is the root cause of #3011
|
|
516
500
|
* We need to handle GOAWAY frames properly, and trigger the session close
|
|
@@ -654,7 +638,7 @@ function onHttp2SocketError (err) {
|
|
|
654
638
|
return
|
|
655
639
|
}
|
|
656
640
|
|
|
657
|
-
this[kClient][kOnError](err)
|
|
641
|
+
this[kHTTP2Session]?.[kClient]?.[kOnError](err)
|
|
658
642
|
}
|
|
659
643
|
|
|
660
644
|
function onHttp2SocketEnd () {
|
|
@@ -688,20 +672,24 @@ function onUpgradeStreamClose () {
|
|
|
688
672
|
closeStreamSession(this)
|
|
689
673
|
}
|
|
690
674
|
|
|
691
|
-
|
|
675
|
+
// Idempotent terminal cleanup, called from both 'end' and 'close': the
|
|
676
|
+
// null-state guard no-ops the later call.
|
|
677
|
+
function completeRequestStream () {
|
|
692
678
|
const state = this[kRequestStreamState]
|
|
693
679
|
|
|
694
|
-
if (state) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
680
|
+
if (state == null) {
|
|
681
|
+
return
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Release the stream first so request references are cleared,
|
|
685
|
+
// then complete the response with trailers if available.
|
|
686
|
+
releaseRequestStream(this)
|
|
698
687
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
finalizeRequest(state)
|
|
702
|
-
}
|
|
688
|
+
if (state.pendingEnd && !state.request.aborted && !state.request.completed) {
|
|
689
|
+
state.request.onResponseEnd(state.trailers || {})
|
|
703
690
|
}
|
|
704
691
|
|
|
692
|
+
finalizeRequest(state)
|
|
705
693
|
closeStreamSession(this)
|
|
706
694
|
this[kRequestStreamState] = null
|
|
707
695
|
}
|
|
@@ -943,14 +931,14 @@ function writeH2 (client, request) {
|
|
|
943
931
|
// close() alone leaves cleanup waiting on the 'close' event; on a busy,
|
|
944
932
|
// long-lived multiplexed session that event can fail to fire, leaving the
|
|
945
933
|
// native Http2Stream (and the whole request graph it pins) alive for the
|
|
946
|
-
// session's life. Destroy the stream to release the handle
|
|
947
|
-
// deterministically
|
|
948
|
-
//
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
}
|
|
934
|
+
// session's life. Destroy the stream synchronously to release the handle
|
|
935
|
+
// deterministically. Deferring the destroy (e.g. via setImmediate) leaks
|
|
936
|
+
// the same way when the event loop is stalled and the callback never runs
|
|
937
|
+
// under abort churn (#5558); close() has already queued the RST_STREAM
|
|
938
|
+
// frame on the native session, so a synchronous destroy still sends it.
|
|
939
|
+
if (!stream.destroyed) {
|
|
940
|
+
util.destroy(stream)
|
|
941
|
+
}
|
|
954
942
|
|
|
955
943
|
// We move the running index to the next request
|
|
956
944
|
client[kOnError](err)
|
|
@@ -1137,7 +1125,7 @@ function writeH2 (client, request) {
|
|
|
1137
1125
|
}
|
|
1138
1126
|
|
|
1139
1127
|
stream[kHTTP2Session] = session
|
|
1140
|
-
stream.on('close',
|
|
1128
|
+
stream.on('close', completeRequestStream)
|
|
1141
1129
|
|
|
1142
1130
|
bindRequestToStream(request, stream, releaseRequestStream)
|
|
1143
1131
|
if (expectContinue) {
|
|
@@ -1280,13 +1268,16 @@ function onEnd () {
|
|
|
1280
1268
|
|
|
1281
1269
|
stream.off('end', onEnd)
|
|
1282
1270
|
|
|
1283
|
-
//
|
|
1284
|
-
//
|
|
1285
|
-
// onTrailers (which may fire after 'end' on Windows) can
|
|
1286
|
-
// store trailers first.
|
|
1271
|
+
// onTrailers (which may fire after 'end' on Windows) has already stored
|
|
1272
|
+
// trailers on the state by now, so completing here still delivers them.
|
|
1287
1273
|
if (state.responseReceived) {
|
|
1288
1274
|
if (!request.aborted && !request.completed) {
|
|
1289
1275
|
state.pendingEnd = true
|
|
1276
|
+
|
|
1277
|
+
// Complete on 'end': a blocked event loop can keep the stream's 'close'
|
|
1278
|
+
// from firing, stranding its buffers until OOM. Idempotent, so a later
|
|
1279
|
+
// 'close' no-ops.
|
|
1280
|
+
completeRequestStream.call(stream)
|
|
1290
1281
|
}
|
|
1291
1282
|
} else {
|
|
1292
1283
|
// Stream ended without receiving a response - this is an error
|
|
@@ -1357,7 +1348,7 @@ function onTrailers (trailers) {
|
|
|
1357
1348
|
return
|
|
1358
1349
|
}
|
|
1359
1350
|
|
|
1360
|
-
// Store trailers for
|
|
1351
|
+
// Store trailers for completeRequestStream to use when completing
|
|
1361
1352
|
state.trailers = trailers
|
|
1362
1353
|
}
|
|
1363
1354
|
|
|
@@ -26,6 +26,10 @@ const NOT_UNDERSTOOD_STATUS_CODES = [
|
|
|
26
26
|
|
|
27
27
|
const MAX_RESPONSE_AGE = 2147483647000
|
|
28
28
|
|
|
29
|
+
// Retention for revalidation-only entries (zero freshness lifetime but a
|
|
30
|
+
// validator present); each successful revalidation re-stores the entry.
|
|
31
|
+
const REVALIDATION_ONLY_RETENTION = 86400000 // 24 hours
|
|
32
|
+
|
|
29
33
|
/**
|
|
30
34
|
* @typedef {import('../../types/dispatcher.d.ts').default.DispatchHandler} DispatchHandler
|
|
31
35
|
*
|
|
@@ -118,6 +122,7 @@ class CacheHandler {
|
|
|
118
122
|
} catch {
|
|
119
123
|
// Fail silently
|
|
120
124
|
}
|
|
125
|
+
this.#deleteLocationHeaderEntries(resHeaders)
|
|
121
126
|
return downstreamOnHeaders()
|
|
122
127
|
}
|
|
123
128
|
|
|
@@ -150,8 +155,12 @@ class CacheHandler {
|
|
|
150
155
|
? parseHttpDate(resHeaders.date)
|
|
151
156
|
: undefined
|
|
152
157
|
|
|
158
|
+
const hasValidator =
|
|
159
|
+
(typeof resHeaders.etag === 'string' && isEtagUsable(resHeaders.etag)) ||
|
|
160
|
+
typeof resHeaders['last-modified'] === 'string'
|
|
161
|
+
|
|
153
162
|
const staleAt =
|
|
154
|
-
determineStaleAt(this.#cacheType, now, resAge, resHeaders, resDate, cacheControlDirectives) ??
|
|
163
|
+
determineStaleAt(this.#cacheType, now, resAge, resHeaders, resDate, cacheControlDirectives, hasValidator) ??
|
|
155
164
|
this.#cacheByDefault
|
|
156
165
|
if (staleAt === undefined || (resAge && resAge > staleAt)) {
|
|
157
166
|
return downstreamOnHeaders()
|
|
@@ -159,7 +168,11 @@ class CacheHandler {
|
|
|
159
168
|
|
|
160
169
|
const baseTime = resDate ? resDate.getTime() : now
|
|
161
170
|
const absoluteStaleAt = staleAt + baseTime
|
|
162
|
-
|
|
171
|
+
// Zero freshness lifetime but a validator: stale from the start, yet still
|
|
172
|
+
// storable since each reuse is preceded by a revalidation request.
|
|
173
|
+
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.4
|
|
174
|
+
const revalidationOnly = staleAt === 0 && hasValidator
|
|
175
|
+
if (now >= absoluteStaleAt && !revalidationOnly) {
|
|
163
176
|
// Response is already stale
|
|
164
177
|
return downstreamOnHeaders()
|
|
165
178
|
}
|
|
@@ -314,6 +327,58 @@ class CacheHandler {
|
|
|
314
327
|
}
|
|
315
328
|
}
|
|
316
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Deletes the cache entries for the URIs in the response's Location and
|
|
332
|
+
* Content-Location headers when they share the request URI's origin
|
|
333
|
+
* https://www.rfc-editor.org/rfc/rfc9111.html#section-4.4
|
|
334
|
+
*
|
|
335
|
+
* @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders
|
|
336
|
+
*/
|
|
337
|
+
#deleteLocationHeaderEntries (resHeaders) {
|
|
338
|
+
let requestUrl
|
|
339
|
+
try {
|
|
340
|
+
requestUrl = new URL(this.#cacheKey.path, this.#cacheKey.origin)
|
|
341
|
+
} catch {
|
|
342
|
+
// Can't resolve the request URI, don't invalidate anything else
|
|
343
|
+
return
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const invalidatedPaths = new Set([this.#cacheKey.path])
|
|
347
|
+
|
|
348
|
+
for (const headerName of ['location', 'content-location']) {
|
|
349
|
+
const header = resHeaders[headerName]
|
|
350
|
+
const value = Array.isArray(header) ? header[0] : header
|
|
351
|
+
if (typeof value !== 'string' || value === '') {
|
|
352
|
+
continue
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
let url
|
|
356
|
+
try {
|
|
357
|
+
url = new URL(value, requestUrl)
|
|
358
|
+
} catch {
|
|
359
|
+
continue
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (url.origin !== requestUrl.origin) {
|
|
363
|
+
// Only invalidate URIs sharing the request URI's origin, invalidating
|
|
364
|
+
// cross-origin URIs could be used for cache poisoning
|
|
365
|
+
continue
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const path = `${url.pathname}${url.search}`
|
|
369
|
+
if (invalidatedPaths.has(path)) {
|
|
370
|
+
continue
|
|
371
|
+
}
|
|
372
|
+
invalidatedPaths.add(path)
|
|
373
|
+
|
|
374
|
+
try {
|
|
375
|
+
this.#store.delete({ ...this.#cacheKey, path })?.catch?.(noop)
|
|
376
|
+
} catch {
|
|
377
|
+
// Fail silently
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
317
382
|
onResponseData (controller, chunk) {
|
|
318
383
|
if (this.#writeStream?.write(chunk) === false) {
|
|
319
384
|
controller.pause()
|
|
@@ -422,23 +487,35 @@ function getAge (ageHeader) {
|
|
|
422
487
|
* @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders
|
|
423
488
|
* @param {Date | undefined} responseDate
|
|
424
489
|
* @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives
|
|
490
|
+
* @param {boolean} hasValidator whether the response has a validator (etag or
|
|
491
|
+
* last-modified) that revalidation requests can be made with
|
|
425
492
|
*
|
|
426
493
|
* @returns {number | undefined} time that the value is stale at in seconds or undefined if it shouldn't be cached
|
|
427
494
|
*/
|
|
428
|
-
function determineStaleAt (cacheType, now, age, resHeaders, responseDate, cacheControlDirectives) {
|
|
495
|
+
function determineStaleAt (cacheType, now, age, resHeaders, responseDate, cacheControlDirectives, hasValidator) {
|
|
429
496
|
if (cacheType === 'shared') {
|
|
430
497
|
// Prioritize s-maxage since we're a shared cache
|
|
431
498
|
// s-maxage > max-age > Expire
|
|
432
499
|
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.10-3
|
|
433
500
|
const sMaxAge = cacheControlDirectives['s-maxage']
|
|
434
501
|
if (sMaxAge !== undefined) {
|
|
435
|
-
|
|
502
|
+
if (sMaxAge > 0) {
|
|
503
|
+
return sMaxAge * 1000
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Immediately stale, but storable if we can revalidate it before reuse.
|
|
507
|
+
return sMaxAge === 0 && hasValidator ? 0 : undefined
|
|
436
508
|
}
|
|
437
509
|
}
|
|
438
510
|
|
|
439
511
|
const maxAge = cacheControlDirectives['max-age']
|
|
440
512
|
if (maxAge !== undefined) {
|
|
441
|
-
|
|
513
|
+
if (maxAge > 0) {
|
|
514
|
+
return maxAge * 1000
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Immediately stale, but storable if we can revalidate it before reuse.
|
|
518
|
+
return maxAge === 0 && hasValidator ? 0 : undefined
|
|
442
519
|
}
|
|
443
520
|
|
|
444
521
|
if (typeof resHeaders.expires === 'string') {
|
|
@@ -482,6 +559,12 @@ function determineStaleAt (cacheType, now, age, resHeaders, responseDate, cacheC
|
|
|
482
559
|
return 31536000000
|
|
483
560
|
}
|
|
484
561
|
|
|
562
|
+
if (cacheControlDirectives['no-cache'] === true && hasValidator) {
|
|
563
|
+
// No freshness source, but a validator lets us revalidate before reuse.
|
|
564
|
+
// https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.4
|
|
565
|
+
return 0
|
|
566
|
+
}
|
|
567
|
+
|
|
485
568
|
return undefined
|
|
486
569
|
}
|
|
487
570
|
|
|
@@ -518,6 +601,11 @@ function determineDeleteAt (baseTime, cachedAt, cacheControlDirectives, staleAt)
|
|
|
518
601
|
// revalidated.
|
|
519
602
|
if (staleWhileRevalidate === -Infinity && staleIfError === -Infinity && immutable === -Infinity) {
|
|
520
603
|
const freshnessLifetime = staleAt - baseTime
|
|
604
|
+
if (freshnessLifetime <= 0) {
|
|
605
|
+
// Revalidation-only entry: no freshness lifetime to size the buffer on,
|
|
606
|
+
// so retain it for a bounded window instead.
|
|
607
|
+
return cachedAt + REVALIDATION_ONLY_RETENTION
|
|
608
|
+
}
|
|
521
609
|
const datePrecisionPadding = Math.min(Math.max(cachedAt - baseTime, 0), 1000)
|
|
522
610
|
return staleAt + freshnessLifetime + datePrecisionPadding
|
|
523
611
|
}
|