@harperfast/harper 5.2.5 → 5.2.7
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/bin/restart.ts +48 -23
- package/bin/restartExitWatchdog.ts +99 -0
- package/bin/run.ts +16 -10
- package/dist/bin/restart.js +39 -21
- package/dist/bin/restart.js.map +1 -1
- package/dist/bin/restartExitWatchdog.d.ts +5 -0
- package/dist/bin/restartExitWatchdog.js +100 -0
- package/dist/bin/restartExitWatchdog.js.map +1 -0
- package/dist/bin/run.d.ts +2 -0
- package/dist/bin/run.js +17 -10
- package/dist/bin/run.js.map +1 -1
- package/dist/resources/DatabaseTransaction.d.ts +18 -1
- package/dist/resources/DatabaseTransaction.js +63 -1
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/LMDBTransaction.d.ts +2 -0
- package/dist/resources/LMDBTransaction.js +7 -1
- package/dist/resources/LMDBTransaction.js.map +1 -1
- package/dist/resources/PrimaryRocksDatabase.js +2 -3
- package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
- package/dist/resources/RecordEncoder.d.ts +16 -0
- package/dist/resources/RecordEncoder.js +93 -3
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/Resource.js +5 -4
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/ResourceInterface.d.ts +5 -0
- package/dist/resources/ResourceInterface.js.map +1 -1
- package/dist/resources/Table.js +106 -9
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/graphql.js +1 -1
- package/dist/resources/graphql.js.map +1 -1
- package/dist/resources/tracked.js +5 -0
- package/dist/resources/tracked.js.map +1 -1
- package/dist/resources/transaction.js +1 -1
- package/dist/resources/transaction.js.map +1 -1
- package/dist/server/threads/manageThreads.d.ts +1 -0
- package/dist/server/threads/manageThreads.js +20 -3
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/utility/processManagement/processManagement.js +21 -3
- package/dist/utility/processManagement/processManagement.js.map +1 -1
- package/npm-shrinkwrap.json +6 -6
- package/package.json +2 -2
- package/resources/DESIGN.md +24 -19
- package/resources/DatabaseTransaction.ts +63 -2
- package/resources/LMDBTransaction.ts +7 -1
- package/resources/PrimaryRocksDatabase.ts +3 -3
- package/resources/RecordEncoder.ts +85 -3
- package/resources/Resource.ts +6 -5
- package/resources/ResourceInterface.ts +5 -0
- package/resources/Table.ts +117 -9
- package/resources/graphql.ts +1 -1
- package/resources/tracked.ts +4 -0
- package/resources/transaction.ts +2 -2
- package/server/DESIGN.md +6 -0
- package/server/threads/manageThreads.js +17 -3
- package/studio/web/assets/{Chat-Lgj1d-8d.js → Chat-etJeJv4a.js} +71 -95
- package/studio/web/assets/FloatingChat-BvmHsuVo.js +23 -0
- package/studio/web/assets/abnfDiagram-VCTEODGH-C0_BAZyO.js +1 -0
- package/studio/web/assets/{alertDialog-BaBrZQ4M.js → alertDialog-DIHt7Z0r.js} +1 -1
- package/studio/web/assets/apiToken-Bl5LC8EH.js +1 -0
- package/studio/web/assets/applications-Dta6Y0Rg.js +296 -0
- package/studio/web/assets/arc-CVRByUzA.js +1 -0
- package/studio/web/assets/architecture-7GRP2DOG-DNdx5tEU.js +1 -0
- package/studio/web/assets/architectureDiagram-5GKGNRK7-BWzrASgm.js +36 -0
- package/studio/web/assets/authStore-qKmCZcaf.js +3 -0
- package/studio/web/assets/blockDiagram-NRAW4CY4-BdJX9Khj.js +129 -0
- package/studio/web/assets/{button-DfBmT4rc.js → button-DhiX-njv.js} +1 -1
- package/studio/web/assets/c4Diagram-UCG6FXSJ-CI6MzGmQ.js +38 -0
- package/studio/web/assets/channel-DtCV8PTL.js +1 -0
- package/studio/web/assets/chevron-up-Df2c8uoU.js +1 -0
- package/studio/web/assets/chunk-75Z2AOVW-BT8tVmks.js +2 -0
- package/studio/web/assets/chunk-DU6HZSFF-9kAOOmI6.js +127 -0
- package/studio/web/assets/{chunk-2GRJ4B5K-DtwG__pv.js → chunk-F27PBJKO-BW7ao8AY.js} +1 -1
- package/studio/web/assets/{chunk-KEIR6QF5-BICK3FdT.js → chunk-FOHPRMQF-DHwB1DNv.js} +2 -2
- package/studio/web/assets/{chunk-5RXB4S5H-D3c7okHC.js → chunk-G27WJ6UU-COyLMcgK.js} +2 -2
- package/studio/web/assets/chunk-GMAD6QVW-BNyXpoQO.js +72 -0
- package/studio/web/assets/chunk-JQ64N6SF-Cyz1IeLf.js +1 -0
- package/studio/web/assets/{chunk-GF5L2VYU-DreJ7Snz.js → chunk-LCL6LL3I-HOzK_ppE.js} +3 -3
- package/studio/web/assets/chunk-OBVCFTLP-D4wWOqDQ.js +1 -0
- package/studio/web/assets/chunk-P2QGCYS3-DmIFY4d7.js +1 -0
- package/studio/web/assets/{chunk-KBJHAD2P-CLDPbAA-.js → chunk-POPQ4Y6H-BPrvMyKz.js} +1 -1
- package/studio/web/assets/{chunk-4I5QYGJK-D1FhvtQq.js → chunk-PWAF6VOD-2zB6IW9i.js} +1 -1
- package/studio/web/assets/chunk-R7TYR2AO-Irip67yr.js +10 -0
- package/studio/web/assets/chunk-RHFEMEQ7-2FgyI8YU.js +168 -0
- package/studio/web/assets/{chunk-6Q2QTUOP-QviMM6bR.js → chunk-SVP7TREG-FwtbH2QC.js} +1 -1
- package/studio/web/assets/chunk-TEH6E4GO-P87k5mNi.js +62 -0
- package/studio/web/assets/{chunk-XXDRQBXY-CaP_jixK.js → chunk-XXDRQBXY-BoGZu3HH.js} +1 -1
- package/studio/web/assets/classDiagram-DTDB5LWJ-DbO_dCNE.js +1 -0
- package/studio/web/assets/classDiagram-v2-JRS7N3AN-DbO_dCNE.js +1 -0
- package/studio/web/assets/{cose-bilkent-JH36ORCC-BVTNhTKD.js → cose-bilkent-JH36ORCC-Cuuf67Bh.js} +1 -1
- package/studio/web/assets/{createLucideIcon-BMkDbMrz.js → createLucideIcon-BKGPfjm2.js} +1 -1
- package/studio/web/assets/cssMode-IAbO_2KK.js +1 -0
- package/studio/web/assets/cynefin-OW5HDTMX-BRkpLFQV.js +1 -0
- package/studio/web/assets/cynefinDiagram-5FMLGOSQ-CHT1DaX6.js +62 -0
- package/studio/web/assets/cytoscape.esm-C2x7inlt.js +321 -0
- package/studio/web/assets/dagre-3AP2YEHR-DpUXBh63.js +4 -0
- package/studio/web/assets/dagre-PrKaheQc.js +1 -0
- package/studio/web/assets/diagram-S7CK7UJ4-BuymVFZT.js +30 -0
- package/studio/web/assets/diagram-UQ7AKVKN-CyP148RM.js +41 -0
- package/studio/web/assets/diagram-VSXAHHWV-CoCAg3M9.js +3 -0
- package/studio/web/assets/diagram-VX7I27RA-BpOqCFca.js +24 -0
- package/studio/web/assets/diagram-Z3DM3KII-Bfpw7Vbj.js +24 -0
- package/studio/web/assets/dialog-CBf0Mr1d.js +1 -0
- package/studio/web/assets/{dist-CeoU7cfW.js → dist-kYfyPZP9.js} +1 -1
- package/studio/web/assets/{dist-cY0BPcz0.js → dist-lkA3O3eM.js} +1 -1
- package/studio/web/assets/download-BtTOBem-.js +1 -0
- package/studio/web/assets/ebnfDiagram-PWID7BFC-DS_6aWqL.js +1 -0
- package/studio/web/assets/editor-CeRXEhRl.js +1 -0
- package/studio/web/assets/erDiagram-SSCWMZ5O-DJNk6Fgw.js +99 -0
- package/studio/web/assets/eventmodeling-NTZA5JFV-5jbe4A5P.js +1 -0
- package/studio/web/assets/flowDiagram-A5DVABFB-Dp9Ezlow.js +1 -0
- package/studio/web/assets/{ganttDiagram-PKOTCBZU-Cit41Zp3.js → ganttDiagram-EL5Y4UJY-2pOExxMY.js} +2 -2
- package/studio/web/assets/{getAnalytics-rTxZLIM5.js → getAnalytics-D4LKGeVy.js} +1 -1
- package/studio/web/assets/gitGraph-4MIJSDKK-CH5ZxwzF.js +1 -0
- package/studio/web/assets/gitGraphDiagram-WWUBYQGX-DVIsIhbO.js +106 -0
- package/studio/web/assets/html-DOV4s_YT.js +1 -0
- package/studio/web/assets/htmlMode-CdqjnAh4.js +1 -0
- package/studio/web/assets/index-CTqasm6g.js +824 -0
- package/studio/web/assets/index-Cxj2_wsl.css +1 -0
- package/studio/web/assets/index.lazy-VmcKgiEy.js +2 -0
- package/studio/web/assets/info-A6RAGUB7-CPQfTnaG.js +1 -0
- package/studio/web/assets/infoDiagram-RXCK75RN-DlwLYlwm.js +2 -0
- package/studio/web/assets/{ishikawaDiagram-WSZJBQD7-BJYRB-hU.js → ishikawaDiagram-5VMMS53U-BRXRp29U.js} +2 -2
- package/studio/web/assets/{javascript-CGzSV8Sd.js → javascript-Dj7yXfx5.js} +1 -1
- package/studio/web/assets/{journeyDiagram-NVQOT4AX-B8K4wuMz.js → journeyDiagram-EYS64GPL-B0ou8k0n.js} +1 -1
- package/studio/web/assets/jsonMode-khk65qzx.js +1 -0
- package/studio/web/assets/{kanban-definition-27J2QSJJ-DKFV1ovM.js → kanban-definition-3QL26DDD-uYg7iYzp.js} +11 -11
- package/studio/web/assets/languageServices-D_06p7dw.js +1 -0
- package/studio/web/assets/linear-Cnt8506Q.js +1 -0
- package/studio/web/assets/lspLanguageFeatures-DTA6wyQw.js +4 -0
- package/studio/web/assets/mermaid-parser.core-Ck-fC8b7.js +7 -0
- package/studio/web/assets/mermaid.core-CP8aNNYm.js +44 -0
- package/studio/web/assets/{mindmap-definition-FAOFIHXS-CKL4PdAv.js → mindmap-definition-FBJOCRG2-CgTZ-rit.js} +25 -25
- package/studio/web/assets/notifications-Bah46LXX.js +1 -0
- package/studio/web/assets/notifications-CBZXgxVc.js +1 -0
- package/studio/web/assets/packet-AYTQ26CC-DEyoPtPb.js +1 -0
- package/studio/web/assets/pegDiagram-XKGWAZYB-DrD-7sD9.js +1 -0
- package/studio/web/assets/pie-WAS4IAKB-wjj-EI1d.js +1 -0
- package/studio/web/assets/pieDiagram-E7YTZNPT-GntqDCzv.js +39 -0
- package/studio/web/assets/profile-QspOun_j.js +1 -0
- package/studio/web/assets/{quadrantDiagram-CIZ2JOQS-CSbsuWtH.js → quadrantDiagram-AXDQQJYC-0UeqXQGd.js} +1 -1
- package/studio/web/assets/radar-RG4KPBEZ-DFSA5h7k.js +1 -0
- package/studio/web/assets/railroad-74A4TZTK-CaOUG9wR.js +1 -0
- package/studio/web/assets/railroad-abnf-HS5TGJTU-Bc0Qi0WH.js +1 -0
- package/studio/web/assets/railroad-ebnf-LZEXJU2U-G8rVVZ2C.js +1 -0
- package/studio/web/assets/railroad-peg-WCYAUIDC-CrehKBhC.js +1 -0
- package/studio/web/assets/railroadDiagram-O6MQD6OU-yHUELZaV.js +1 -0
- package/studio/web/assets/regions-QdUi7bQ9.js +1 -0
- package/studio/web/assets/{editor.api-eUd8PqEu.js → register-Buvoxmb8.js} +139 -138
- package/studio/web/assets/{requirementDiagram-LRYGKXZP-ZIF0Wlho.js → requirementDiagram-EFPCY7ZU-DNEGFjuW.js} +2 -2
- package/studio/web/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/studio/web/assets/safeParse-DeaoCCWH.js +1 -0
- package/studio/web/assets/{sankeyDiagram-W5VNT64P-BcRESt9x.js → sankeyDiagram-P5KCCOFB-DpyAmSVR.js} +1 -1
- package/studio/web/assets/{sequenceDiagram-SI44F4Z6-OpgTeJNU.js → sequenceDiagram-WJ2MYXX4-TyaT7xNk.js} +1 -1
- package/studio/web/assets/setComponentFile-BI4E_iDe.js +1 -0
- package/studio/web/assets/setLocalStorage-D_kflv4U.js +1 -0
- package/studio/web/assets/setSessionStorage-B0bf71m4.js +1 -0
- package/studio/web/assets/setup-Cop6LBQN.js +2 -0
- package/studio/web/assets/src-CMc7m_Ut.js +1 -0
- package/studio/web/assets/stateDiagram-HBIQ2CUA-CeEdTArZ.js +1 -0
- package/studio/web/assets/stateDiagram-v2-4QOOHH4V-D4tuw9Su.js +1 -0
- package/studio/web/assets/status-DRu3zRgl.js +61 -0
- package/studio/web/assets/step-vX8bovaY.js +1 -0
- package/studio/web/assets/swimlanes-XN3QIQJK-B54FmF46.js +1 -0
- package/studio/web/assets/swimlanesDiagram-VK2B7HYN-XOhmNEvq.js +8 -0
- package/studio/web/assets/tabs-B_G5zscN.js +1 -0
- package/studio/web/assets/{time-D55sDum-.js → time-Cclkb7kQ.js} +1 -1
- package/studio/web/assets/{timeline-definition-Z64GVDOM-Dy5A_tK2.js → timeline-definition-24CTP7MA-D-a9ujbo.js} +5 -5
- package/studio/web/assets/toggleHighContrast-C0dJLmZ0.js +49 -0
- package/studio/web/assets/treeView-Q6P3EWNA-CrW_6JnS.js +1 -0
- package/studio/web/assets/treemap-WGGIJYW6-BxyYLdP_.js +1 -0
- package/studio/web/assets/tsMode-dbDiapTA.js +11 -0
- package/studio/web/assets/typescript-CT1826cL.js +1 -0
- package/studio/web/assets/useEntityRestURL-D1u1X_gE.js +1 -0
- package/studio/web/assets/useLocalStorage-Dtj1QS8_.js +1 -0
- package/studio/web/assets/{vendor-core-CddkYGh5.js → vendor-core-RCcadM3e.js} +1 -1
- package/studio/web/assets/vendor-datadog-BRv-mOv1.js +6 -0
- package/studio/web/assets/{vendor-react-BhazFIp8.js → vendor-react-Dyj4O3HE.js} +1 -1
- package/studio/web/assets/vendor-tanstack-BiFWSB3W.js +1 -0
- package/studio/web/assets/{vendor-ui-BLIveqaL.js → vendor-ui-vhu-UHhF.js} +11 -11
- package/studio/web/assets/{vennDiagram-T6HMQDX7-DRvMIiSo.js → vennDiagram-4TSXK5OY-Cy7s7Mpy.js} +3 -3
- package/studio/web/assets/wardley-WFR3VGLG-BeBL35g2.js +1 -0
- package/studio/web/assets/{wardleyDiagram-T6FBY63Y-B04FSA0i.js → wardleyDiagram-VM6X3IG4-BylmIGSg.js} +3 -3
- package/studio/web/assets/workers-FpR9_D2K.js +3 -0
- package/studio/web/assets/x-B9o9hsep.js +1 -0
- package/studio/web/assets/xml-ZjKUMjth.js +1 -0
- package/studio/web/assets/{xychartDiagram-ELKLHX3M-BE0X7RA7.js → xychartDiagram-S5SC5T6Z-CoKALMXr.js} +3 -3
- package/studio/web/assets/yaml-B6gXbZU6.js +1 -0
- package/studio/web/assets/{yaml.worker-Iyy2Pf1T.js → yaml.worker-BDL8_iuk.js} +153 -153
- package/studio/web/harper-studio_black.png +0 -0
- package/studio/web/index.html +18 -24
- package/utility/processManagement/processManagement.js +19 -3
- package/studio/web/assets/FloatingChat-jLWvR4kI.js +0 -23
- package/studio/web/assets/abnfDiagram-N423BO3Z-BRuH0ywn.js +0 -1
- package/studio/web/assets/apiToken-DYI4DqWa.js +0 -1
- package/studio/web/assets/applications-DCmc9-lk.js +0 -296
- package/studio/web/assets/arc-3Xw6uabx.js +0 -1
- package/studio/web/assets/architecture-TIHT7OUA-CsHfPErM.js +0 -1
- package/studio/web/assets/architectureDiagram-T3A2C74G-DrwbS7Gp.js +0 -36
- package/studio/web/assets/array-BifhSqXX.js +0 -1
- package/studio/web/assets/authStore-B3IhXrn6.js +0 -3
- package/studio/web/assets/blockDiagram-VBNYF7ZC-DKN1mht5.js +0 -132
- package/studio/web/assets/c4Diagram-5PPSVZJV-CT9bmjm_.js +0 -10
- package/studio/web/assets/card-ByrPS_wa.js +0 -1
- package/studio/web/assets/channel-mnKBfsP-.js +0 -1
- package/studio/web/assets/chevron-right-CY-tr2sG.js +0 -1
- package/studio/web/assets/chunk-3NCLNEKW-BVj72ixc.js +0 -1
- package/studio/web/assets/chunk-5FCAYU7R-Dh5nylU8.js +0 -1
- package/studio/web/assets/chunk-5HE753X5-Bw-yg4kO.js +0 -1
- package/studio/web/assets/chunk-5JV3BV7I-Cy5pj3QY.js +0 -1
- package/studio/web/assets/chunk-5TONJI2A-DQOY3q1H.js +0 -2
- package/studio/web/assets/chunk-7BUUIJ7U-Bb538aSH.js +0 -1
- package/studio/web/assets/chunk-7Z6QIM7H-BJhESwQK.js +0 -10
- package/studio/web/assets/chunk-BIQX33UG-DZEsGuSn.js +0 -1
- package/studio/web/assets/chunk-CQNSW5MT-B8S09OIh.js +0 -1
- package/studio/web/assets/chunk-CYSBUYHQ-C1Rf4art.js +0 -1
- package/studio/web/assets/chunk-EMLP6XTP-RLD4nXpI.js +0 -1
- package/studio/web/assets/chunk-I66GZJ75-DHPYnKNr.js +0 -125
- package/studio/web/assets/chunk-J7OUQ5F2-DcY_kb6i.js +0 -2
- package/studio/web/assets/chunk-JG7HCLWE-BYfiSaVt.js +0 -2
- package/studio/web/assets/chunk-JQJVKLGR-DtEmbHZj.js +0 -156
- package/studio/web/assets/chunk-MOZMSUNE-XVucA-n6.js +0 -1
- package/studio/web/assets/chunk-NSK5VX7P-DDFNzCU_.js +0 -2
- package/studio/web/assets/chunk-OSBZ3O6U-CrKZOUOr.js +0 -1
- package/studio/web/assets/chunk-QBLGF6JB-CxAyS2mW.js +0 -1
- package/studio/web/assets/chunk-QR6OTTB3-Df7OCENk.js +0 -62
- package/studio/web/assets/chunk-R7FJI6CG-Cnn3gE-Y.js +0 -1
- package/studio/web/assets/chunk-RYQCIY6F-N0MDKk5G.js +0 -1
- package/studio/web/assets/chunk-U6XO7XAA-BFxjP5U3.js +0 -2
- package/studio/web/assets/chunk-UBXNYLIW-rn0yw1mp.js +0 -1
- package/studio/web/assets/chunk-W5SLKNZC-DKMlAWZk.js +0 -1
- package/studio/web/assets/chunk-WRU74C26-Dg10j8Pf.js +0 -70
- package/studio/web/assets/chunk-YOTPTUD7-D0vRKqYp.js +0 -1
- package/studio/web/assets/chunk-ZIRB5QZD-O39ZBUk3.js +0 -32
- package/studio/web/assets/classDiagram-JCYQIIEL-BrXNP4fl.js +0 -1
- package/studio/web/assets/classDiagram-v2-OCEON4UE-BrXNP4fl.js +0 -1
- package/studio/web/assets/cssMode-DipmMR_-.js +0 -1
- package/studio/web/assets/cynefin-VYW2F7L2-Ds2Fw2Y0.js +0 -1
- package/studio/web/assets/cynefinDiagram-MW4NZA55-DcTzrsC5.js +0 -62
- package/studio/web/assets/cytoscape.esm-B-NFISlW.js +0 -321
- package/studio/web/assets/dagre-Buvkdvvj.js +0 -1
- package/studio/web/assets/dagre-VZM6K2ZE-CMyJ9QPU.js +0 -4
- package/studio/web/assets/diagram-7IWD3JNH-jEGuzdp3.js +0 -30
- package/studio/web/assets/diagram-B4RE2ZJO-Ba7wC7iw.js +0 -3
- package/studio/web/assets/diagram-LBJQPF4R-Bm7Wj_dF.js +0 -24
- package/studio/web/assets/diagram-Q27KOJAE-C-gdktLC.js +0 -24
- package/studio/web/assets/diagram-UB23O5K3-COBVIEEk.js +0 -41
- package/studio/web/assets/ebnfDiagram-BXEA7PRR-G-t56mVV.js +0 -1
- package/studio/web/assets/editor-BDfNodZS.js +0 -1
- package/studio/web/assets/erDiagram-JOGREHBK-DpHzpqx1.js +0 -85
- package/studio/web/assets/eventmodeling-45OFAUF4-CLEiVx5s.js +0 -1
- package/studio/web/assets/flowDiagram-UKHOOZJN-CIxxUUxn.js +0 -1
- package/studio/web/assets/getRegistrationInfo--NLLrics.js +0 -1
- package/studio/web/assets/gitGraph-TEB2WS4Q-CZFBqwW-.js +0 -1
- package/studio/web/assets/gitGraphDiagram-DS77QQ5N-DuGnRv2R.js +0 -106
- package/studio/web/assets/html-DmSSmgE8.js +0 -1
- package/studio/web/assets/htmlMode-B2LqJw1z.js +0 -1
- package/studio/web/assets/index-BO3NaEw8.css +0 -1
- package/studio/web/assets/index-BnYZFLIB.css +0 -1
- package/studio/web/assets/index-CqbCnqsT.js +0 -810
- package/studio/web/assets/index.lazy-BNqr3j0f.js +0 -13
- package/studio/web/assets/info-DKCQHKI2--1InqQeT.js +0 -1
- package/studio/web/assets/infoDiagram-6WML65LV-DliK38kp.js +0 -2
- package/studio/web/assets/isArrayLikeObject-BHDnhloL.js +0 -1
- package/studio/web/assets/jsonMode-BVS6P5Xk.js +0 -1
- package/studio/web/assets/languageServices-Bl-BvoAb.js +0 -1
- package/studio/web/assets/line-Bom3IjHi.js +0 -1
- package/studio/web/assets/linear-DwB_ruUT.js +0 -1
- package/studio/web/assets/lspLanguageFeatures-C7XtZA_w.js +0 -4
- package/studio/web/assets/map-BaFkSB1l.js +0 -1
- package/studio/web/assets/math-Bi_r_ZWc.js +0 -1
- package/studio/web/assets/mermaid-parser.core-Dd4RYr9Q.js +0 -4
- package/studio/web/assets/mermaid.core-Bbo24DGo.js +0 -11
- package/studio/web/assets/notifications-Bb2cj14_.js +0 -1
- package/studio/web/assets/notifications-DVlKonbI.js +0 -1
- package/studio/web/assets/packet-7NZHBO7P-BGMXB0XL.js +0 -1
- package/studio/web/assets/path-fybaL0A-.js +0 -1
- package/studio/web/assets/pegDiagram-VL7TDLO6-CWEktcBB.js +0 -1
- package/studio/web/assets/pie-RZYD4A2V-DgYg3tCt.js +0 -1
- package/studio/web/assets/pieDiagram-7S7Q4E2Y-DEAmZOqY.js +0 -39
- package/studio/web/assets/pollUnlessForbidden-DIDXGBc5.js +0 -1
- package/studio/web/assets/profile-BSQWfYfq.js +0 -1
- package/studio/web/assets/purify.es-DrVcFY1Q.js +0 -3
- package/studio/web/assets/queryClient-BLhQvmWC.js +0 -1
- package/studio/web/assets/radar-I7S5WNFK-Ag-zp_Rq.js +0 -1
- package/studio/web/assets/railroad-3IZDKUUU-aibJDIDV.js +0 -1
- package/studio/web/assets/railroad-abnf-AHOZXSZD-BBMEuvIl.js +0 -1
- package/studio/web/assets/railroad-ebnf-EBAXGLYW-Be1nseej.js +0 -1
- package/studio/web/assets/railroad-peg-LSFZ7HO6-DIvD-Eyb.js +0 -1
- package/studio/web/assets/railroadDiagram-AXF67PYL-BJWrgR10.js +0 -1
- package/studio/web/assets/react-VeAY02s6.js +0 -1
- package/studio/web/assets/react-redux-Ds7wf7Ax.js +0 -5
- package/studio/web/assets/regions-Dk3g8bBF.js +0 -1
- package/studio/web/assets/register-3F1Tje_F.js +0 -2
- package/studio/web/assets/register-S_PdXsoi.js +0 -2
- package/studio/web/assets/rolldown-runtime-B0Z9INg1.js +0 -1
- package/studio/web/assets/select-CKgJgpkn.js +0 -1
- package/studio/web/assets/setComponentFile-DoITgNLb.js +0 -1
- package/studio/web/assets/setLocalStorage-CD_L8p_D.js +0 -1
- package/studio/web/assets/setup-CiEALLa7.js +0 -2
- package/studio/web/assets/src-DUvBCJIr.js +0 -1
- package/studio/web/assets/stateDiagram-OKZ733FA-D9oPLTjO.js +0 -1
- package/studio/web/assets/stateDiagram-v2-UEYNNEHI-CSD1wbuZ.js +0 -1
- package/studio/web/assets/status-CK9tD-Nd.js +0 -61
- package/studio/web/assets/string-f6JzSHaO.js +0 -1
- package/studio/web/assets/swagger-ui-react-CxjCDFB-.js +0 -240
- package/studio/web/assets/swimlanes-SLNWSIFB-BpeoNE9k.js +0 -2
- package/studio/web/assets/swimlanesDiagram-ULZ7WXOC-DHxwzxpp.js +0 -8
- package/studio/web/assets/table-BvFflPWi.js +0 -1
- package/studio/web/assets/tabs-Dd_ElZ36.js +0 -1
- package/studio/web/assets/textarea-a3RnTY31.js +0 -9
- package/studio/web/assets/toggleHighContrast-CyNC3SCQ.js +0 -49
- package/studio/web/assets/tokenization-CWuvR2gh.js +0 -7
- package/studio/web/assets/treeView-QDETBFTQ-uHZ-3Fz8.js +0 -1
- package/studio/web/assets/treemap-6X3UGDF4-BnUKyy3l.js +0 -1
- package/studio/web/assets/tsMode-CslzhcVk.js +0 -11
- package/studio/web/assets/typescript-Dtnury3t.js +0 -1
- package/studio/web/assets/useAuth-DiJUZS1C.js +0 -1
- package/studio/web/assets/useEntityRestURL-Cy-0i1UZ.js +0 -1
- package/studio/web/assets/useLocalStorage-DetQlhBe.js +0 -1
- package/studio/web/assets/vendor-datadog-XDrpA25D.js +0 -6
- package/studio/web/assets/vendor-tanstack-FsM5XZNE.js +0 -1
- package/studio/web/assets/wardley-OPB4EBWU-Da7TLC2F.js +0 -1
- package/studio/web/assets/workers-BtibQGyk.js +0 -3
- package/studio/web/assets/x-D39AGKMb.js +0 -1
- package/studio/web/assets/xml-D41zWqPl.js +0 -1
- package/studio/web/assets/yaml-BFQ3mF1U.js +0 -1
- /package/studio/web/assets/{editor-jjEx9u7D.css → register-jjEx9u7D.css} +0 -0
package/resources/Table.ts
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
DatabaseTransaction,
|
|
37
37
|
ImmediateTransaction,
|
|
38
38
|
priorStagedWrite,
|
|
39
|
+
isJoinableScope,
|
|
39
40
|
isReleasedTransaction,
|
|
40
41
|
TRANSACTION_STATE,
|
|
41
42
|
writeKeyId,
|
|
@@ -71,7 +72,15 @@ import { getWorkerIndex, getWorkerCount } from '../server/threads/manageThreads.
|
|
|
71
72
|
import { HAS_BLOBS, auditRetention, removeAuditEntry } from './auditStore.ts';
|
|
72
73
|
import { buildEmbedBefore, createDefaultEmbedder, type EmbedAttribute, type Embedder } from './models/embedHook.ts';
|
|
73
74
|
import { autoCast, autoCastBooleanStrict } from '../utility/common_utils.ts';
|
|
74
|
-
import {
|
|
75
|
+
import {
|
|
76
|
+
recordUpdater,
|
|
77
|
+
removeEntry,
|
|
78
|
+
PENDING_LOCAL_TIME,
|
|
79
|
+
RecordObject,
|
|
80
|
+
type Entry,
|
|
81
|
+
entryMap,
|
|
82
|
+
storedFieldsOnly,
|
|
83
|
+
} from './RecordEncoder.ts';
|
|
75
84
|
import { recordAction, recordActionBinary } from './analytics/write.ts';
|
|
76
85
|
import { rebuildUpdateBefore } from './crdt.ts';
|
|
77
86
|
import { appendHeader } from '../server/serverHelpers/Headers.ts';
|
|
@@ -452,6 +461,18 @@ export function makeTable(options) {
|
|
|
452
461
|
// it, so such a table takes the guarded serialization path rather than the raw fast path.
|
|
453
462
|
let hasSurfacedComputed = false;
|
|
454
463
|
let runningRecordExpiration: boolean;
|
|
464
|
+
const reportedResolverCollisions = new Set<string>();
|
|
465
|
+
// Reached from record materialization, so it can never be the reason a record fails to load: the
|
|
466
|
+
// name is marked before the log call, and a throwing log sink is swallowed.
|
|
467
|
+
function reportResolverCollision(name: string) {
|
|
468
|
+
if (reportedResolverCollisions.has(name)) return;
|
|
469
|
+
reportedResolverCollisions.add(name);
|
|
470
|
+
try {
|
|
471
|
+
logger.warn?.(
|
|
472
|
+
`Table "${tableName}" has a stored value under "${name}", which is a computed attribute; the stored value is being discarded and the computed value used instead`
|
|
473
|
+
);
|
|
474
|
+
} catch {}
|
|
475
|
+
}
|
|
455
476
|
const isRocksDB = primaryStore instanceof RocksDatabase;
|
|
456
477
|
type BigInt64ArrayAndMaxSafeId = BigInt64Array & { maxSafeId: number };
|
|
457
478
|
let idIncrementer: BigInt64ArrayAndMaxSafeId;
|
|
@@ -1873,7 +1894,28 @@ export function makeTable(options) {
|
|
|
1873
1894
|
}
|
|
1874
1895
|
#saveOperation(operation: any) {
|
|
1875
1896
|
const transaction = txnForContext(this.getContext());
|
|
1876
|
-
|
|
1897
|
+
const holder = operation.stagedIn;
|
|
1898
|
+
// never-drop-on-conflict lives on the transaction and would not travel with the write, so an
|
|
1899
|
+
// apply or a replay keeps it (harper-pro#348)
|
|
1900
|
+
const holderOwnsPolicy = holder?.sourceApply || holder?.isReplay;
|
|
1901
|
+
// stagesWriteOnSave: LMDBTransaction's addWrite never runs the write (its commit applies
|
|
1902
|
+
// `writes`), so handing it one is a dead end
|
|
1903
|
+
if (
|
|
1904
|
+
holder &&
|
|
1905
|
+
holder !== transaction &&
|
|
1906
|
+
!holderOwnsPolicy &&
|
|
1907
|
+
transaction.stagesWriteOnSave &&
|
|
1908
|
+
isJoinableScope(transaction)
|
|
1909
|
+
) {
|
|
1910
|
+
holder.detachWrite(operation);
|
|
1911
|
+
// The basis chain belongs to the holder: derived from a write this scope cannot commit, the
|
|
1912
|
+
// merge and index diff would be relative to a record that may never land.
|
|
1913
|
+
operation.priorWrite = undefined;
|
|
1914
|
+
operation.deferSave = false;
|
|
1915
|
+
return when(transaction.addWrite(operation), () => operation.promise ?? operation.result);
|
|
1916
|
+
}
|
|
1917
|
+
const owner = holder ?? transaction;
|
|
1918
|
+
if (owner.save) return owner.save(operation) || operation.promise || operation.result;
|
|
1877
1919
|
}
|
|
1878
1920
|
|
|
1879
1921
|
addTo(property: any, value: any) {
|
|
@@ -2314,11 +2356,11 @@ export function makeTable(options) {
|
|
|
2314
2356
|
nodeName: (context as any)?.nodeName,
|
|
2315
2357
|
fullUpdate,
|
|
2316
2358
|
deferSave: true,
|
|
2317
|
-
validate: (txnTime) => {
|
|
2359
|
+
validate: (txnTime, committedBy = transaction) => {
|
|
2318
2360
|
if (!recordUpdate) recordUpdate = this.#changes;
|
|
2319
2361
|
if (fullUpdate || (recordUpdate && hasChanges(this.#changes === recordUpdate ? this : recordUpdate))) {
|
|
2320
2362
|
if (!(context as any)?.source) {
|
|
2321
|
-
|
|
2363
|
+
committedBy.checkOverloaded();
|
|
2322
2364
|
// A record must be a plain object. Reject primitive, string/number, bare-binary,
|
|
2323
2365
|
// and bare-array roots — e.g. a raw Buffer from an application/octet-stream PUT, a
|
|
2324
2366
|
// JSON string/number body, or a top-level JSON array. Such roots carry no primary
|
|
@@ -2356,7 +2398,7 @@ export function makeTable(options) {
|
|
|
2356
2398
|
// by replayLogs). Records were valid when originally written; post-crash schema
|
|
2357
2399
|
// evolution (e.g. newly required fields) must not prevent replaying them
|
|
2358
2400
|
// (harper#1316, facet b).
|
|
2359
|
-
if (!
|
|
2401
|
+
if (!committedBy.isReplay) this.validate(recordUpdate, !fullUpdate);
|
|
2360
2402
|
if (updatedTimeProperty) {
|
|
2361
2403
|
recordUpdate[updatedTimeProperty.name] =
|
|
2362
2404
|
updatedTimeProperty.type === 'Date'
|
|
@@ -2391,7 +2433,7 @@ export function makeTable(options) {
|
|
|
2391
2433
|
// TODO: else freeze after we have applied the changes
|
|
2392
2434
|
}
|
|
2393
2435
|
} else {
|
|
2394
|
-
(
|
|
2436
|
+
(committedBy as any).removeWrite?.(write);
|
|
2395
2437
|
return false;
|
|
2396
2438
|
}
|
|
2397
2439
|
},
|
|
@@ -2434,6 +2476,7 @@ export function makeTable(options) {
|
|
|
2434
2476
|
let incrementalUpdateToApply: boolean;
|
|
2435
2477
|
|
|
2436
2478
|
this.#savingOperation = null;
|
|
2479
|
+
write.stagedIn = undefined; // nothing may pin this write's transaction past its commit
|
|
2437
2480
|
let omitLocalRecord = false;
|
|
2438
2481
|
// we use optimistic locking to only commit if the existing record state still holds true.
|
|
2439
2482
|
// this is superior to using an async transaction since it doesn't require JS execution
|
|
@@ -4967,6 +5010,9 @@ export function makeTable(options) {
|
|
|
4967
5010
|
for (const attribute of this.attributes) {
|
|
4968
5011
|
if (attribute.isPrimaryKey) primaryKeyAttribute = attribute;
|
|
4969
5012
|
attribute.resolve = null; // reset this
|
|
5013
|
+
// Also the setter, or a reload that turns a @relationship into a @computed keeps the
|
|
5014
|
+
// relationship's setter and writes a foreign key from a computed assignment.
|
|
5015
|
+
attribute.set = null;
|
|
4970
5016
|
const relationship = attribute.relationship;
|
|
4971
5017
|
const computed = attribute.computed;
|
|
4972
5018
|
// Register the default embedder unless an author override is set. Sits outside
|
|
@@ -5128,14 +5174,19 @@ export function makeTable(options) {
|
|
|
5128
5174
|
enumerableAttributeNames = [];
|
|
5129
5175
|
enumerableRelationDefs.clear();
|
|
5130
5176
|
hasSurfacedComputed = false;
|
|
5177
|
+
const resolvedAttributeNames: string[] = [];
|
|
5131
5178
|
for (const attribute of attributes) {
|
|
5132
5179
|
const name = attribute.name;
|
|
5133
5180
|
if (attribute.resolve) {
|
|
5181
|
+
resolvedAttributeNames.push(name);
|
|
5134
5182
|
Object.defineProperty(primaryStore.encoder.structPrototype, name, {
|
|
5135
5183
|
get() {
|
|
5136
5184
|
return attribute.resolve(this, contextStorage.getStore()); // it is only possible to get the context from ALS, we don't have a direct reference to the current context
|
|
5137
5185
|
},
|
|
5138
5186
|
set(related) {
|
|
5187
|
+
// A read-only resolver must never be the reason a record fails to materialize — the
|
|
5188
|
+
// same reason the one-to-many branch above installs a no-op.
|
|
5189
|
+
if (!attribute.set) return reportResolverCollision(name);
|
|
5139
5190
|
return attribute.set(this, related);
|
|
5140
5191
|
},
|
|
5141
5192
|
configurable: true,
|
|
@@ -5161,6 +5212,12 @@ export function makeTable(options) {
|
|
|
5161
5212
|
if (enumerableAttributeNames.length > 0)
|
|
5162
5213
|
installEnumerableToJSON(primaryStore.encoder.structPrototype, this, hasSurfacedComputed);
|
|
5163
5214
|
else if (primaryStore.encoder.structPrototype.toJSON) delete primaryStore.encoder.structPrototype.toJSON;
|
|
5215
|
+
// Undefined rather than an empty set for a table with no resolved attributes: that is the
|
|
5216
|
+
// check which keeps the projection off an unaffected store's write path.
|
|
5217
|
+
primaryStore.encoder.resolvedAttributeNames =
|
|
5218
|
+
resolvedAttributeNames.length > 0 ? new Set(resolvedAttributeNames) : undefined;
|
|
5219
|
+
primaryStore.encoder.resolvedAttributeNamesList = resolvedAttributeNames;
|
|
5220
|
+
primaryStore.encoder.surfacedToJSON = primaryStore.encoder.structPrototype.toJSON;
|
|
5164
5221
|
}
|
|
5165
5222
|
// #section: computed-history
|
|
5166
5223
|
static setComputedAttribute(attribute_name, resolver) {
|
|
@@ -5645,10 +5702,33 @@ export function makeTable(options) {
|
|
|
5645
5702
|
// See if this is a transaction for our database and if so, use it
|
|
5646
5703
|
if (transaction.db?.path === primaryStore.path) return transaction;
|
|
5647
5704
|
// try the next one:
|
|
5648
|
-
|
|
5705
|
+
let nextTxn = transaction.next;
|
|
5706
|
+
// A self-committing link is CLOSED once it has committed, and a further write through it
|
|
5707
|
+
// commits on a native handle nothing awaits (#2323). Spent — closed, handle detached, none of
|
|
5708
|
+
// its OWN writes left (hasPendingWrites walks successors, which is not this question) — it
|
|
5709
|
+
// holds nothing, so drop it. A run of them can be spent, hence the loop. A timeout-poisoned
|
|
5710
|
+
// link is kept: reusing it is what makes the rest of the operation fail atomically (#1411).
|
|
5711
|
+
while (
|
|
5712
|
+
nextTxn?.saveCommits &&
|
|
5713
|
+
nextTxn.open !== TRANSACTION_STATE.OPEN &&
|
|
5714
|
+
!nextTxn.timedOut &&
|
|
5715
|
+
!nextTxn.transaction &&
|
|
5716
|
+
!nextTxn.writes.some((write) => write)
|
|
5717
|
+
) {
|
|
5718
|
+
transaction.next = nextTxn.next;
|
|
5719
|
+
nextTxn = transaction.next;
|
|
5720
|
+
}
|
|
5649
5721
|
if (!nextTxn) {
|
|
5650
5722
|
// no next one, then add our database
|
|
5651
|
-
|
|
5723
|
+
// A staging link under a self-committing head is committed only if the head's own database
|
|
5724
|
+
// is written again and cascades the chain, so a handler writing this one last loses it (#2292).
|
|
5725
|
+
transaction.next = transaction.saveCommits
|
|
5726
|
+
? ((isRocksDB
|
|
5727
|
+
? new ImmediateTransaction(primaryStore as any)
|
|
5728
|
+
: new ImmediateLMDBTransaction(primaryStore as any)) as any)
|
|
5729
|
+
: isRocksDB
|
|
5730
|
+
? new DatabaseTransaction()
|
|
5731
|
+
: new LMDBTransaction();
|
|
5652
5732
|
// The chain root, so a link that only ever receives a blind write is supervised by the
|
|
5653
5733
|
// long-transaction monitor as part of its logical transaction rather than as its own
|
|
5654
5734
|
// timeout root (issue #2231).
|
|
@@ -5670,8 +5750,11 @@ export function makeTable(options) {
|
|
|
5670
5750
|
// A second database joined after a mid-scope commit belongs to the same snapshot-free
|
|
5671
5751
|
// generation as the head, or its reads would re-pin what the commit just unpinned.
|
|
5672
5752
|
transaction.next.snapshotFree = transaction.snapshotFree;
|
|
5673
|
-
if (transaction.open === TRANSACTION_STATE.CLOSED) {
|
|
5753
|
+
if (transaction.open === TRANSACTION_STATE.CLOSED && !transaction.next.saveCommits) {
|
|
5674
5754
|
// if the current transaction is already closed, we need to retain that state on new databases we work with
|
|
5755
|
+
// Never onto a self-committing link: CLOSED is what routes its first write through the
|
|
5756
|
+
// commit re-entry that drops the native commit promise (#2323), and it commits per write
|
|
5757
|
+
// regardless of this state.
|
|
5675
5758
|
transaction.next.open = TRANSACTION_STATE.CLOSED;
|
|
5676
5759
|
}
|
|
5677
5760
|
transaction = transaction.next;
|
|
@@ -5948,6 +6031,31 @@ export function makeTable(options) {
|
|
|
5948
6031
|
// before stamping the primary key and created/updated times below (records are immutable —
|
|
5949
6032
|
// 5.2 record caching relies on it — so we must not write through the frozen object).
|
|
5950
6033
|
if (isFrozenRecordObject(updatedRecord)) updatedRecord = { ...updatedRecord };
|
|
6034
|
+
// A writable resolver (a relationship) keeps its meaning for source payloads: a source
|
|
6035
|
+
// returning the related object instead of the foreign key gets the key derived, the way
|
|
6036
|
+
// the promotion setter used to. Derivation runs against a probe first — a malformed
|
|
6037
|
+
// value (a scalar, an object without the related primary key) derives undefined, and
|
|
6038
|
+
// applying that would durably wipe the foreign key. The projection then drops the
|
|
6039
|
+
// resolver-owned key itself, so the cache-fill response cannot be the one read
|
|
6040
|
+
// reporting the source's value.
|
|
6041
|
+
const resolvedNames = primaryStore.encoder.resolvedAttributeNamesList;
|
|
6042
|
+
if (resolvedNames) {
|
|
6043
|
+
for (const name of resolvedNames) {
|
|
6044
|
+
if (Object.hasOwn(updatedRecord, name)) {
|
|
6045
|
+
const resolvedAttribute = findAttribute(attributes, name);
|
|
6046
|
+
if (resolvedAttribute?.set && updatedRecord[name] != null) {
|
|
6047
|
+
const probe = {};
|
|
6048
|
+
resolvedAttribute.set(probe, updatedRecord[name]);
|
|
6049
|
+
for (const key in probe) {
|
|
6050
|
+
const derived = probe[key];
|
|
6051
|
+
const usable = Array.isArray(derived) ? derived.every((one) => one != null) : derived != null;
|
|
6052
|
+
if (usable) updatedRecord[key] = derived;
|
|
6053
|
+
}
|
|
6054
|
+
}
|
|
6055
|
+
}
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
6058
|
+
updatedRecord = storedFieldsOnly(primaryStore.encoder, updatedRecord);
|
|
5951
6059
|
if (primaryKey && updatedRecord[primaryKey] !== id) updatedRecord[primaryKey] = id;
|
|
5952
6060
|
}
|
|
5953
6061
|
resolved = true;
|
package/resources/graphql.ts
CHANGED
|
@@ -351,4 +351,4 @@ async function processGraphQLSchema(gqlContent, urlPath, filePath, resources) {
|
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
// useful for testing
|
|
354
|
-
export const loadGQLSchema = (content) => processGraphQLSchema(content, null,
|
|
354
|
+
export const loadGQLSchema = (content) => processGraphQLSchema(content, null, '<inline-schema>', new Resources());
|
package/resources/tracked.ts
CHANGED
|
@@ -45,6 +45,10 @@ export function assignTrackedAccessors(Target, typeDef, useFullPropertyProxy = f
|
|
|
45
45
|
return attribute.resolve(this, this.getContext?.());
|
|
46
46
|
},
|
|
47
47
|
set(related) {
|
|
48
|
+
// Unlike the struct-prototype accessor (which tolerates a stored collision so a record can
|
|
49
|
+
// still load), this is a user assignment to a resolved attribute, and a read-only resolver
|
|
50
|
+
// (a scalar @computed has no attribute.set) has nowhere to put it (harper#2359).
|
|
51
|
+
if (!attribute.set) throw new ClientError(`${name} is a computed attribute and can not be assigned`);
|
|
48
52
|
return attribute.set(this, related);
|
|
49
53
|
},
|
|
50
54
|
configurable: true,
|
package/resources/transaction.ts
CHANGED
|
@@ -2,9 +2,9 @@ import type { Context } from './ResourceInterface.ts';
|
|
|
2
2
|
import { _assignPackageExport } from '../globals.js';
|
|
3
3
|
import {
|
|
4
4
|
DatabaseTransaction,
|
|
5
|
+
isJoinableScope,
|
|
5
6
|
isReleasedTransaction,
|
|
6
7
|
type Transaction,
|
|
7
|
-
TRANSACTION_STATE,
|
|
8
8
|
} from './DatabaseTransaction.ts';
|
|
9
9
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
10
10
|
|
|
@@ -41,7 +41,7 @@ export function transaction<T>(
|
|
|
41
41
|
if (typeof callback !== 'function') {
|
|
42
42
|
throw new TypeError('Callback function must be provided to transaction');
|
|
43
43
|
}
|
|
44
|
-
if (context?.transaction
|
|
44
|
+
if (isJoinableScope(context?.transaction) && typeof callback === 'function') {
|
|
45
45
|
return callback(context.transaction); // nothing to be done, already in open transaction
|
|
46
46
|
}
|
|
47
47
|
|
package/server/DESIGN.md
CHANGED
|
@@ -68,6 +68,12 @@ A request entering `http.ts` does **not** go through Fastify. The two `handleApp
|
|
|
68
68
|
| `threads/itc.js` | Inter-thread comms primitives. |
|
|
69
69
|
| `transactionLogCooling.ts` | Main-thread timer that cools transaction-log mmaps. |
|
|
70
70
|
|
|
71
|
+
Process-wide shutdown begins by calling `beginProcessShutdown()` in `threads/manageThreads.js`.
|
|
72
|
+
Once set, this terminal state prevents every worker replacement path and makes new `startWorker()`
|
|
73
|
+
calls fail with `ERR_HARPER_PROCESS_SHUTTING_DOWN`; scoped worker-type restarts do not set it.
|
|
74
|
+
`shutdownWorkersNow()` remains an immediate teardown: its worker shutdown messages are best-effort,
|
|
75
|
+
and it force-terminates the remaining worker set rather than waiting for application drain hooks.
|
|
76
|
+
|
|
71
77
|
> Workers receive `workerData.noServerStart = true` — never start the server inside a worker.
|
|
72
78
|
>
|
|
73
79
|
> `threadServer.listenOnDomainSocket()` skips a listener only when its path exceeds the platform's
|
|
@@ -46,6 +46,7 @@ const chokidar = require('chokidar');
|
|
|
46
46
|
const isBun = typeof globalThis.Bun !== 'undefined';
|
|
47
47
|
const MB = 1024 * 1024;
|
|
48
48
|
const workers = []; // these are our child workers that we are managing
|
|
49
|
+
let processShuttingDown = false;
|
|
49
50
|
const connectedPorts = []; // these are all known connected worker ports (siblings, children, parents)
|
|
50
51
|
const MAX_UNEXPECTED_RESTARTS = 50;
|
|
51
52
|
// Threads get 10s to die before they're forced. In dev (`harper dev`) we widen this: a reload's old
|
|
@@ -150,6 +151,7 @@ module.exports = {
|
|
|
150
151
|
setTerminateTimeout,
|
|
151
152
|
extendShutdownDeadline,
|
|
152
153
|
restoreShutdownDeadline,
|
|
154
|
+
beginProcessShutdown,
|
|
153
155
|
registerWorkerDataProvider,
|
|
154
156
|
onThreadExit,
|
|
155
157
|
registerProcessGroup,
|
|
@@ -324,6 +326,11 @@ listenersByType.set(THREAD_INFO, null);
|
|
|
324
326
|
listenersByType.set(PROCESS_GROUP_TERMINATION_CONFIRMED, null);
|
|
325
327
|
|
|
326
328
|
function startWorker(path, options = {}) {
|
|
329
|
+
if (processShuttingDown) {
|
|
330
|
+
const error = new Error('Cannot start a worker while the Harper process is shutting down');
|
|
331
|
+
error.code = 'ERR_HARPER_PROCESS_SHUTTING_DOWN';
|
|
332
|
+
throw error;
|
|
333
|
+
}
|
|
327
334
|
// Take a percentage of total memory to determine the max memory for each thread. The percentage is based
|
|
328
335
|
// on the thread count. Generally, it is unrealistic to efficiently use the majority of total memory for a single
|
|
329
336
|
// NodeJS worker since it would lead to massive swap space usage with other processes and there is significant
|
|
@@ -435,7 +442,7 @@ function startWorker(path, options = {}) {
|
|
|
435
442
|
});
|
|
436
443
|
worker.on('exit', (_code) => {
|
|
437
444
|
workers.splice(workers.indexOf(worker), 1);
|
|
438
|
-
if (!worker.wasShutdown && options.autoRestart !== false) {
|
|
445
|
+
if (!processShuttingDown && !worker.wasShutdown && options.autoRestart !== false) {
|
|
439
446
|
// if this wasn't an intentional shutdown, restart now (unless we have tried too many times)
|
|
440
447
|
if (worker.unexpectedRestarts < MAX_UNEXPECTED_RESTARTS) {
|
|
441
448
|
options.unexpectedRestarts = worker.unexpectedRestarts + 1;
|
|
@@ -469,6 +476,7 @@ async function restartWorkers(
|
|
|
469
476
|
startReplacementThreads = true
|
|
470
477
|
) {
|
|
471
478
|
if (isMainThread) {
|
|
479
|
+
if (processShuttingDown && startReplacementThreads) return;
|
|
472
480
|
try {
|
|
473
481
|
// we do this because it is possible for a component to chdir to itself, get re-deployed and then the cwd
|
|
474
482
|
// inode link is invalid and it can cause a lot of problems. But process.cwd() still returns the path, for
|
|
@@ -506,6 +514,8 @@ async function restartWorkers(
|
|
|
506
514
|
// listenOnPorts() treat a dedicated listener's EADDRINUSE as an external conflict.
|
|
507
515
|
const canPreStartReplacement = process.platform !== 'win32' && process.platform !== 'darwin' && !isBun;
|
|
508
516
|
for (let worker of workers.slice(0)) {
|
|
517
|
+
// Terminal shutdown: stop replacing workers mid-loop — the guard for every replacement start below.
|
|
518
|
+
if (processShuttingDown && startReplacementThreads) break;
|
|
509
519
|
if ((name && worker.name !== name) || worker.wasShutdown) continue; // filter by type, if specified
|
|
510
520
|
const overlapping = OVERLAPPING_RESTART_TYPES.indexOf(worker.name) > -1;
|
|
511
521
|
if (overlapping && startReplacementThreads && canPreStartReplacement) {
|
|
@@ -590,7 +600,7 @@ async function restartWorkers(
|
|
|
590
600
|
// Overlapping types we couldn't pre-start (Windows/Bun): start the replacement now that the old
|
|
591
601
|
// worker is releasing its port. server.close() stops accepting immediately, so the port frees up
|
|
592
602
|
// well before the replacement finishes booting and binds.
|
|
593
|
-
if (overlapping && startReplacementThreads && !canPreStartReplacement) worker.startCopy();
|
|
603
|
+
if (overlapping && startReplacementThreads && !canPreStartReplacement && !processShuttingDown) worker.startCopy();
|
|
594
604
|
let whenDone = new Promise((resolve) => {
|
|
595
605
|
// in case the exit inside the thread doesn't timeout, force it from the outside
|
|
596
606
|
const armTerminate = (delay) =>
|
|
@@ -627,7 +637,7 @@ async function restartWorkers(
|
|
|
627
637
|
const index = waitingToFinish.indexOf(whenDone);
|
|
628
638
|
if (index > -1) waitingToFinish.splice(index, 1);
|
|
629
639
|
// non-overlapping types have no advance replacement, so start it once the old one is gone
|
|
630
|
-
if (!overlapping && startReplacementThreads) worker.startCopy();
|
|
640
|
+
if (!overlapping && startReplacementThreads && !processShuttingDown) worker.startCopy();
|
|
631
641
|
resolve();
|
|
632
642
|
});
|
|
633
643
|
});
|
|
@@ -650,7 +660,11 @@ async function restartWorkers(
|
|
|
650
660
|
function shutdownWorkers(name) {
|
|
651
661
|
return restartWorkers(name, Infinity, false);
|
|
652
662
|
}
|
|
663
|
+
function beginProcessShutdown() {
|
|
664
|
+
processShuttingDown = true;
|
|
665
|
+
}
|
|
653
666
|
async function shutdownWorkersNow(name) {
|
|
667
|
+
if (name == null) beginProcessShutdown();
|
|
654
668
|
shutdownWorkers(name); // set the state of all the workers to shut down. this should finish the important stuff synchronously
|
|
655
669
|
if (isBun) {
|
|
656
670
|
// worker.terminate() triggers a NAPI segfault in Bun; ask workers to self-exit instead
|