@mistriwork/mistri 1.0.0-rc.12 → 1.0.0-rc.13

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.
Files changed (221) hide show
  1. package/README.md +4 -3
  2. package/dist/client/assets/LayoutBuilder-MPzkVU2e.js.map +1 -1
  3. package/dist/client/assets/index-D2dHI6hR.js.map +1 -1
  4. package/dist/client/assets/shell-TreN_uLs.js.map +1 -1
  5. package/dist/docs/access-model.md +1 -1
  6. package/dist/docs/build-and-deploy.md +0 -1
  7. package/dist/docs/cli.md +1 -1
  8. package/dist/docs/glossary.md +3 -3
  9. package/dist/docs/query.md +9 -21
  10. package/dist/docs/status.md +3 -3
  11. package/dist/embed/react/chunks/LayoutBuilder-Cbxa_wve.js.map +1 -1
  12. package/dist/embed/react/chunks/app-0UZ1Re1k.js.map +1 -1
  13. package/dist/embed/react/chunks/page-Bx4o1kpQ.js.map +1 -1
  14. package/dist/embed/react/chunks/palette-Bb7Lf6eo.js.map +1 -1
  15. package/dist/embed/react/chunks/shell-DZRACiB9.js.map +1 -1
  16. package/dist/embed/react/chunks/write-BQO4CFc9.js.map +1 -1
  17. package/dist/embed/react/index.js +1 -1
  18. package/dist/server/build/dockerfile.js +1 -1
  19. package/dist/server/cli/usage.js +2 -2
  20. package/dist/ui/index.js +2 -2
  21. package/dist/ui/page.js +2 -2
  22. package/dist/ui/{shared-N4Ej8yRD.js → shared-1PD7TOTJ.js} +5 -5
  23. package/dist/ui/{shared-N4Ej8yRD.js.map → shared-1PD7TOTJ.js.map} +1 -1
  24. package/dist/ui/{shared-D5m86-4o.js → shared-1gMnOu9J.js} +6 -6
  25. package/dist/ui/{shared-D5m86-4o.js.map → shared-1gMnOu9J.js.map} +1 -1
  26. package/dist/ui/{shared-Ctaj8mR2.js → shared-5RQMi4BR.js} +3 -3
  27. package/dist/ui/{shared-Ctaj8mR2.js.map → shared-5RQMi4BR.js.map} +1 -1
  28. package/dist/ui/{shared-DpLeIATZ.js → shared-B-BUF9fx.js} +2 -2
  29. package/dist/ui/{shared-DpLeIATZ.js.map → shared-B-BUF9fx.js.map} +1 -1
  30. package/dist/ui/{shared-DWYnjItP.js → shared-B-MhiPIN.js} +9 -9
  31. package/dist/ui/{shared-DWYnjItP.js.map → shared-B-MhiPIN.js.map} +1 -1
  32. package/dist/ui/{shared-0fNuhSbG.js → shared-B07qIMlE.js} +5 -5
  33. package/dist/ui/{shared-0fNuhSbG.js.map → shared-B07qIMlE.js.map} +1 -1
  34. package/dist/ui/{shared-lYtMadRU.js → shared-B1SAS_J-.js} +3 -3
  35. package/dist/ui/{shared-lYtMadRU.js.map → shared-B1SAS_J-.js.map} +1 -1
  36. package/dist/ui/{shared-CpI0Y8M5.js → shared-B4jgU8h9.js} +6 -6
  37. package/dist/ui/{shared-CpI0Y8M5.js.map → shared-B4jgU8h9.js.map} +1 -1
  38. package/dist/ui/{shared-Cxu1c35l.js → shared-B5aBCUi7.js} +30 -30
  39. package/dist/ui/{shared-Cxu1c35l.js.map → shared-B5aBCUi7.js.map} +1 -1
  40. package/dist/ui/{shared-CAe-US1q.js → shared-B9H7_Pji.js} +5 -5
  41. package/dist/ui/{shared-CAe-US1q.js.map → shared-B9H7_Pji.js.map} +1 -1
  42. package/dist/ui/{shared-Q2bgBaYo.js → shared-BAXr20S-.js} +4 -4
  43. package/dist/ui/{shared-Q2bgBaYo.js.map → shared-BAXr20S-.js.map} +1 -1
  44. package/dist/ui/{shared-CyEefFFb.js → shared-BDDUzH-f.js} +19 -19
  45. package/dist/ui/{shared-CyEefFFb.js.map → shared-BDDUzH-f.js.map} +1 -1
  46. package/dist/ui/{shared-BdhPI6dq.js → shared-BGmkeDeW.js} +3 -3
  47. package/dist/ui/{shared-BdhPI6dq.js.map → shared-BGmkeDeW.js.map} +1 -1
  48. package/dist/ui/{shared-DONIpq2q.js → shared-BHCQ60yN.js} +2 -2
  49. package/dist/ui/{shared-DONIpq2q.js.map → shared-BHCQ60yN.js.map} +1 -1
  50. package/dist/ui/{shared-CNmaAv64.js → shared-BHsjawAG.js} +8 -8
  51. package/dist/ui/{shared-CNmaAv64.js.map → shared-BHsjawAG.js.map} +1 -1
  52. package/dist/ui/{shared-DgjU9kOy.js → shared-BIQuK_nq.js} +4 -4
  53. package/dist/ui/{shared-DgjU9kOy.js.map → shared-BIQuK_nq.js.map} +1 -1
  54. package/dist/ui/{shared-icSQAj21.js → shared-BOe4W2FI.js} +3 -3
  55. package/dist/ui/{shared-icSQAj21.js.map → shared-BOe4W2FI.js.map} +1 -1
  56. package/dist/ui/{shared-BlxoOJSk.js → shared-BPpC08ip.js} +3 -3
  57. package/dist/ui/{shared-BlxoOJSk.js.map → shared-BPpC08ip.js.map} +1 -1
  58. package/dist/ui/{shared-BtiFL37J.js → shared-BdA3LPCB.js} +2 -2
  59. package/dist/ui/{shared-BtiFL37J.js.map → shared-BdA3LPCB.js.map} +1 -1
  60. package/dist/ui/{shared-CvR94vn4.js → shared-Be3nbWsd.js} +11 -11
  61. package/dist/ui/{shared-CvR94vn4.js.map → shared-Be3nbWsd.js.map} +1 -1
  62. package/dist/ui/{shared-Bl_nF_IH.js → shared-Bf30ZLoS.js} +8 -4
  63. package/dist/ui/shared-Bf30ZLoS.js.map +1 -0
  64. package/dist/ui/{shared-DijrJ_V-.js → shared-BguP_BaR.js} +7 -7
  65. package/dist/ui/{shared-DijrJ_V-.js.map → shared-BguP_BaR.js.map} +1 -1
  66. package/dist/ui/{shared-DPAVoWY0.js → shared-BoLbc2WD.js} +17 -2
  67. package/dist/ui/{shared-DPAVoWY0.js.map → shared-BoLbc2WD.js.map} +1 -1
  68. package/dist/ui/{shared-BkdBTYwx.js → shared-BttyOW4W.js} +3 -3
  69. package/dist/ui/{shared-BkdBTYwx.js.map → shared-BttyOW4W.js.map} +1 -1
  70. package/dist/ui/{shared-CQWLz8uT.js → shared-BumxsBlA.js} +10 -10
  71. package/dist/ui/{shared-CQWLz8uT.js.map → shared-BumxsBlA.js.map} +1 -1
  72. package/dist/ui/{shared-Dzu7tFiC.js → shared-Bw73ktBk.js} +3 -3
  73. package/dist/ui/{shared-Dzu7tFiC.js.map → shared-Bw73ktBk.js.map} +1 -1
  74. package/dist/ui/{shared-BhAYErSx.js → shared-C1B0GH0e.js} +4 -4
  75. package/dist/ui/{shared-BhAYErSx.js.map → shared-C1B0GH0e.js.map} +1 -1
  76. package/dist/ui/{shared-BQJQcGgj.js → shared-C2FsyYr7.js} +4 -4
  77. package/dist/ui/{shared-BQJQcGgj.js.map → shared-C2FsyYr7.js.map} +1 -1
  78. package/dist/ui/{shared-B9lw2Ryh.js → shared-C2RU1qjv.js} +4 -4
  79. package/dist/ui/{shared-B9lw2Ryh.js.map → shared-C2RU1qjv.js.map} +1 -1
  80. package/dist/ui/{shared-DQYNI9wO.js → shared-C42f07hJ.js} +5 -5
  81. package/dist/ui/{shared-DQYNI9wO.js.map → shared-C42f07hJ.js.map} +1 -1
  82. package/dist/ui/{shared-CqCZ8wMY.js → shared-C4LkPCU4.js} +3 -3
  83. package/dist/ui/{shared-CqCZ8wMY.js.map → shared-C4LkPCU4.js.map} +1 -1
  84. package/dist/ui/{shared-BhtpgOpa.js → shared-C4wSfz6k.js} +9 -9
  85. package/dist/ui/{shared-BhtpgOpa.js.map → shared-C4wSfz6k.js.map} +1 -1
  86. package/dist/ui/{shared-BHc2Izkj.js → shared-C9DZtSFH.js} +2 -2
  87. package/dist/ui/{shared-BHc2Izkj.js.map → shared-C9DZtSFH.js.map} +1 -1
  88. package/dist/ui/{shared-DW1YuiNS.js → shared-CA52ClGo.js} +2 -2
  89. package/dist/ui/{shared-DW1YuiNS.js.map → shared-CA52ClGo.js.map} +1 -1
  90. package/dist/ui/{shared-BbSbilkh.js → shared-CBciTwm6.js} +9 -9
  91. package/dist/ui/{shared-BbSbilkh.js.map → shared-CBciTwm6.js.map} +1 -1
  92. package/dist/ui/{shared-C-J32eBn.js → shared-CL3RLKDA.js} +16 -16
  93. package/dist/ui/{shared-C-J32eBn.js.map → shared-CL3RLKDA.js.map} +1 -1
  94. package/dist/ui/{shared-Ck8S4OxW.js → shared-CLq3-_hW.js} +3 -3
  95. package/dist/ui/{shared-Ck8S4OxW.js.map → shared-CLq3-_hW.js.map} +1 -1
  96. package/dist/ui/{shared-Q5WefT7G.js → shared-CMjK-Ucd.js} +3 -3
  97. package/dist/ui/{shared-Q5WefT7G.js.map → shared-CMjK-Ucd.js.map} +1 -1
  98. package/dist/ui/{shared-D3MAuEA3.js → shared-CPjpSFGh.js} +2 -2
  99. package/dist/ui/{shared-D3MAuEA3.js.map → shared-CPjpSFGh.js.map} +1 -1
  100. package/dist/ui/{shared-VshXGwXP.js → shared-CSPhENq3.js} +2 -2
  101. package/dist/ui/{shared-VshXGwXP.js.map → shared-CSPhENq3.js.map} +1 -1
  102. package/dist/ui/{shared-DJrJaE73.js → shared-CZJE4Bmp.js} +3 -3
  103. package/dist/ui/{shared-DJrJaE73.js.map → shared-CZJE4Bmp.js.map} +1 -1
  104. package/dist/ui/{shared-D7ONOwI7.js → shared-C_BhUL2I.js} +7 -7
  105. package/dist/ui/{shared-D7ONOwI7.js.map → shared-C_BhUL2I.js.map} +1 -1
  106. package/dist/ui/{shared-j-2peBIB.js → shared-CbeujwdU.js} +4 -4
  107. package/dist/ui/{shared-j-2peBIB.js.map → shared-CbeujwdU.js.map} +1 -1
  108. package/dist/ui/{shared-D5GrOEa2.js → shared-Cbf-o4Dt.js} +4 -4
  109. package/dist/ui/{shared-D5GrOEa2.js.map → shared-Cbf-o4Dt.js.map} +1 -1
  110. package/dist/ui/{shared-HwiPIajr.js → shared-CdNmeNHh.js} +3 -3
  111. package/dist/ui/{shared-HwiPIajr.js.map → shared-CdNmeNHh.js.map} +1 -1
  112. package/dist/ui/{shared-ZCFt-CPb.js → shared-CdQOMD8J.js} +3 -3
  113. package/dist/ui/{shared-ZCFt-CPb.js.map → shared-CdQOMD8J.js.map} +1 -1
  114. package/dist/ui/{shared-ClhXSGGK.js → shared-CdiPYlTh.js} +2 -2
  115. package/dist/ui/{shared-ClhXSGGK.js.map → shared-CdiPYlTh.js.map} +1 -1
  116. package/dist/ui/{shared-DA8_pVRZ.js → shared-CepLAhwm.js} +2 -2
  117. package/dist/ui/{shared-DA8_pVRZ.js.map → shared-CepLAhwm.js.map} +1 -1
  118. package/dist/ui/{shared-BrYKjrnM.js → shared-Ch82h_Fu.js} +6 -6
  119. package/dist/ui/{shared-BrYKjrnM.js.map → shared-Ch82h_Fu.js.map} +1 -1
  120. package/dist/ui/{shared-C4UrE8Fb.js → shared-Chp88all.js} +3 -3
  121. package/dist/ui/{shared-C4UrE8Fb.js.map → shared-Chp88all.js.map} +1 -1
  122. package/dist/ui/{shared-CWa80DTO.js → shared-Ci16s2rN.js} +9 -9
  123. package/dist/ui/{shared-CWa80DTO.js.map → shared-Ci16s2rN.js.map} +1 -1
  124. package/dist/ui/{shared-tksTLD6Q.js → shared-CiqNkoE1.js} +5 -5
  125. package/dist/ui/{shared-tksTLD6Q.js.map → shared-CiqNkoE1.js.map} +1 -1
  126. package/dist/ui/{shared-yt7DjSrq.js → shared-CpMhOq8F.js} +2 -2
  127. package/dist/ui/{shared-yt7DjSrq.js.map → shared-CpMhOq8F.js.map} +1 -1
  128. package/dist/ui/{shared-Dm0z5WUl.js → shared-CrWv5JKH.js} +6 -6
  129. package/dist/ui/{shared-Dm0z5WUl.js.map → shared-CrWv5JKH.js.map} +1 -1
  130. package/dist/ui/{shared-CQL3FGHc.js → shared-Csfi3Pti.js} +2 -2
  131. package/dist/ui/{shared-CQL3FGHc.js.map → shared-Csfi3Pti.js.map} +1 -1
  132. package/dist/ui/{shared-BKNRbm-V.js → shared-CuZt26rm.js} +2 -2
  133. package/dist/ui/{shared-BKNRbm-V.js.map → shared-CuZt26rm.js.map} +1 -1
  134. package/dist/ui/{shared-Guq3upiR.js → shared-Cws_z-TS.js} +2 -2
  135. package/dist/ui/{shared-Guq3upiR.js.map → shared-Cws_z-TS.js.map} +1 -1
  136. package/dist/ui/{shared-Bw_qZeIj.js → shared-D1KWuCg6.js} +2 -2
  137. package/dist/ui/{shared-Bw_qZeIj.js.map → shared-D1KWuCg6.js.map} +1 -1
  138. package/dist/ui/{shared-CuCZKwXW.js → shared-D66ju_Cb.js} +23 -23
  139. package/dist/ui/{shared-CuCZKwXW.js.map → shared-D66ju_Cb.js.map} +1 -1
  140. package/dist/ui/{shared-DYfX7NSM.js → shared-DGaQZXnw.js} +2 -2
  141. package/dist/ui/{shared-DYfX7NSM.js.map → shared-DGaQZXnw.js.map} +1 -1
  142. package/dist/ui/{shared-B3Hp8tOv.js → shared-DHy41sET.js} +6 -6
  143. package/dist/ui/{shared-B3Hp8tOv.js.map → shared-DHy41sET.js.map} +1 -1
  144. package/dist/ui/{shared-CXyd7IKi.js → shared-DKEOMQ6l.js} +2 -2
  145. package/dist/ui/{shared-CXyd7IKi.js.map → shared-DKEOMQ6l.js.map} +1 -1
  146. package/dist/ui/{shared-Ccmc8YO0.js → shared-DSUICuaJ.js} +33 -33
  147. package/dist/ui/{shared-Ccmc8YO0.js.map → shared-DSUICuaJ.js.map} +1 -1
  148. package/dist/ui/{shared-CL2iw_js.js → shared-DUPMRoO0.js} +13 -13
  149. package/dist/ui/{shared-CL2iw_js.js.map → shared-DUPMRoO0.js.map} +1 -1
  150. package/dist/ui/{shared-Dtp4eRul.js → shared-DVfdm6ah.js} +2 -2
  151. package/dist/ui/{shared-Dtp4eRul.js.map → shared-DVfdm6ah.js.map} +1 -1
  152. package/dist/ui/{shared-BJ5Ex32G.js → shared-DXM7d7lJ.js} +3 -3
  153. package/dist/ui/{shared-BJ5Ex32G.js.map → shared-DXM7d7lJ.js.map} +1 -1
  154. package/dist/ui/{shared-BFr6ld0e.js → shared-DXbMlcev.js} +2 -2
  155. package/dist/ui/{shared-BFr6ld0e.js.map → shared-DXbMlcev.js.map} +1 -1
  156. package/dist/ui/{shared-BUp3jv-N.js → shared-D_SkPtJ9.js} +6 -6
  157. package/dist/ui/{shared-BUp3jv-N.js.map → shared-D_SkPtJ9.js.map} +1 -1
  158. package/dist/ui/{shared-CdNomVzH.js → shared-Dd21k2ic.js} +4 -4
  159. package/dist/ui/{shared-CdNomVzH.js.map → shared-Dd21k2ic.js.map} +1 -1
  160. package/dist/ui/{shared-gRMbxmpu.js → shared-Dh0nHtLZ.js} +8 -8
  161. package/dist/ui/{shared-gRMbxmpu.js.map → shared-Dh0nHtLZ.js.map} +1 -1
  162. package/dist/ui/{shared-BKGJgjog.js → shared-DkOdSpSK.js} +3 -3
  163. package/dist/ui/{shared-BKGJgjog.js.map → shared-DkOdSpSK.js.map} +1 -1
  164. package/dist/ui/{shared-BMsh72Uq.js → shared-Dkph5ckT.js} +2 -2
  165. package/dist/ui/{shared-BMsh72Uq.js.map → shared-Dkph5ckT.js.map} +1 -1
  166. package/dist/ui/{shared-Be1HpDOB.js → shared-Dl1_Nx--.js} +3 -3
  167. package/dist/ui/{shared-Be1HpDOB.js.map → shared-Dl1_Nx--.js.map} +1 -1
  168. package/dist/ui/{shared-BQIZWOoJ.js → shared-Dm0IGbAf.js} +2 -2
  169. package/dist/ui/{shared-BQIZWOoJ.js.map → shared-Dm0IGbAf.js.map} +1 -1
  170. package/dist/ui/{shared-DSUtcU5S.js → shared-DnIkTpPr.js} +5 -5
  171. package/dist/ui/{shared-DSUtcU5S.js.map → shared-DnIkTpPr.js.map} +1 -1
  172. package/dist/ui/{shared-DsxGbYlV.js → shared-Docl_0tq.js} +3 -3
  173. package/dist/ui/{shared-DsxGbYlV.js.map → shared-Docl_0tq.js.map} +1 -1
  174. package/dist/ui/{shared-DZskrV26.js → shared-DprrHC72.js} +2 -2
  175. package/dist/ui/{shared-DZskrV26.js.map → shared-DprrHC72.js.map} +1 -1
  176. package/dist/ui/{shared-Bmw43Hwf.js → shared-DyKsJTZs.js} +2 -2
  177. package/dist/ui/{shared-Bmw43Hwf.js.map → shared-DyKsJTZs.js.map} +1 -1
  178. package/dist/ui/{shared-BLG88Pya.js → shared-FO7vfI3F.js} +4 -4
  179. package/dist/ui/{shared-BLG88Pya.js.map → shared-FO7vfI3F.js.map} +1 -1
  180. package/dist/ui/{shared-DLSd80D1.js → shared-HalAVHjv.js} +3 -3
  181. package/dist/ui/{shared-DLSd80D1.js.map → shared-HalAVHjv.js.map} +1 -1
  182. package/dist/ui/{shared-D1mMBLdj.js → shared-JvcI-LWp.js} +15 -15
  183. package/dist/ui/{shared-D1mMBLdj.js.map → shared-JvcI-LWp.js.map} +1 -1
  184. package/dist/ui/{shared-C6Hv_4O0.js → shared-K7Ym27yg.js} +2 -2
  185. package/dist/ui/{shared-C6Hv_4O0.js.map → shared-K7Ym27yg.js.map} +1 -1
  186. package/dist/ui/{shared-B39ln7oi.js → shared-SzlnwfJO.js} +3 -3
  187. package/dist/ui/{shared-B39ln7oi.js.map → shared-SzlnwfJO.js.map} +1 -1
  188. package/dist/ui/{shared-DgPn_Jll.js → shared-TrGbd1FY.js} +3 -3
  189. package/dist/ui/{shared-DgPn_Jll.js.map → shared-TrGbd1FY.js.map} +1 -1
  190. package/dist/ui/{shared-DrFb-XtA.js → shared-WhbuObEW.js} +2 -2
  191. package/dist/ui/{shared-DrFb-XtA.js.map → shared-WhbuObEW.js.map} +1 -1
  192. package/dist/ui/{shared-DiFQljcq.js → shared-XcSKDp6N.js} +11 -11
  193. package/dist/ui/{shared-DiFQljcq.js.map → shared-XcSKDp6N.js.map} +1 -1
  194. package/dist/ui/{shared-CMAg58rY.js → shared-Z4uBJU6I.js} +7 -6
  195. package/dist/ui/shared-Z4uBJU6I.js.map +1 -0
  196. package/dist/ui/{shared-BnUptuUp.js → shared-bAgeiRa5.js} +2 -2
  197. package/dist/ui/{shared-BnUptuUp.js.map → shared-bAgeiRa5.js.map} +1 -1
  198. package/dist/ui/{shared-BxMvSjey.js → shared-cgXG7OgZ.js} +5 -5
  199. package/dist/ui/{shared-BxMvSjey.js.map → shared-cgXG7OgZ.js.map} +1 -1
  200. package/dist/ui/{shared-u4CG2kQJ.js → shared-eZ0SB_zm.js} +2 -2
  201. package/dist/ui/{shared-u4CG2kQJ.js.map → shared-eZ0SB_zm.js.map} +1 -1
  202. package/dist/ui/{shared-L90bWW8e.js → shared-frKFb79C.js} +2 -2
  203. package/dist/ui/{shared-L90bWW8e.js.map → shared-frKFb79C.js.map} +1 -1
  204. package/dist/ui/{shared-Dd34nhkw.js → shared-hAayNSRA.js} +3 -3
  205. package/dist/ui/{shared-Dd34nhkw.js.map → shared-hAayNSRA.js.map} +1 -1
  206. package/dist/ui/{shared-DzC64cpp.js → shared-j_J16p2B.js} +2 -2
  207. package/dist/ui/{shared-DzC64cpp.js.map → shared-j_J16p2B.js.map} +1 -1
  208. package/dist/ui/{shared-DX7HRIV-.js → shared-tqpl5N3g.js} +6 -6
  209. package/dist/ui/{shared-DX7HRIV-.js.map → shared-tqpl5N3g.js.map} +1 -1
  210. package/dist/ui/{shared-BS5dBMpA.js → shared-y-6_ZDts.js} +2 -2
  211. package/dist/ui/{shared-BS5dBMpA.js.map → shared-y-6_ZDts.js.map} +1 -1
  212. package/dist/ui/{shared-Cv5v_MP1.js → shared-zG6e1Rhz.js} +13 -13
  213. package/dist/ui/{shared-Cv5v_MP1.js.map → shared-zG6e1Rhz.js.map} +1 -1
  214. package/dist/ui/testing.js +1 -1
  215. package/package.json +4 -4
  216. package/dist/docs/cli-browser.md +0 -232
  217. package/dist/docs/database-browser.md +0 -115
  218. package/dist/docs/keyboard.md +0 -63
  219. package/dist/docs/mcp.md +0 -86
  220. package/dist/ui/shared-Bl_nF_IH.js.map +0 -1
  221. package/dist/ui/shared-CMAg58rY.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"shared-j-2peBIB.js","names":["say","say","_Fragment","say","say","say","say","_Fragment","_Fragment"],"sources":["../../../kit/src/client/components/diagramModel.ts","../../../kit/src/client/components/paletteModel.ts","../../../kit/src/client/copy/forms/components/Picker.ts","../../../kit/src/client/components/Picker.tsx","../../../engine/src/shared/schematext.js","../../../kit/src/client/copy/workbench/schemaexport.ts","../../../kit/src/client/schemaexport.js","../../../kit/src/client/copy/workbench/components/SchemaExport.ts","../../../kit/src/client/components/SchemaExport.tsx","../../../kit/src/client/copy/workbench/components/Diagram.ts","../../../kit/src/client/components/Diagram.tsx"],"sourcesContent":["/**\n * The diagram's geometry, as numbers: which columns a node lists and how\n * tall that makes it, where the neighbourhood's three columns sit, and\n * the dependency-depth layout of the whole schema. Pure, so the drawing\n * can be tested without drawing.\n */\nimport { labelColumn } from '../core.js';\nimport type { ColumnMeta, TableMeta } from '@mistriwork/engine/shared/schema.js';\n\nexport interface Fk {\n name: string;\n from: { table: string; columns: string[] };\n to: { table: string; columns: string[] };\n}\nexport interface Schema {\n label?: string;\n tables: TableMeta[];\n foreignKeys: Fk[];\n}\n\nexport const NODE_W = 216;\nexport const HEAD_H = 30;\nexport const FIELD_H = 17;\nexport const NODE_PAD = 5;\nconst ROW_GAP = 18;\nexport const COL_GAP = 156;\nexport const PREVIEW_FIELDS = 5;\n/** Characters an edge label can carry before it would reach a node. */\nexport const EDGE_LABEL_BUDGET = 22;\nexport const NAME_BUDGET = 18;\nconst TYPE_BUDGET = 12;\nexport const S_COL_GAP = 96;\nconst S_ROW_GAP = 18;\nexport const DENSE_SCHEMA = 24;\n/** How many of a dense schema's tables the overview opens with. */\nexport const HUB_TABLES = 12;\n\n/** Key, references, the label column, then the rest, each in declared order. */\nexport function orderedColumns(table: TableMeta): ColumnMeta[] {\n const label = labelColumn(table) as string | undefined;\n const rank = (c: ColumnMeta) => (c.primaryKey ? 0 : c.references ? 1 : c.name === label ? 2 : 3);\n return [...table.columns]\n .map((c, i) => ({ c, i }))\n .sort((a, b) => rank(a.c) - rank(b.c) || a.i - b.i)\n .map(({ c }) => c);\n}\n\nconst TYPE_ALIAS = new Map([\n ['timestamp with time zone', 'timestamptz'],\n ['timestamp without time zone', 'timestamp'],\n ['time with time zone', 'timetz'],\n ['time without time zone', 'time'],\n ['character varying', 'varchar'],\n ['character', 'char'],\n ['double precision', 'float8'],\n ['integer', 'int'],\n ['boolean', 'bool'],\n]);\n\nexport const clip = (text: string, max: number) => (text.length > max ? `${text.slice(0, max - 1)}…` : text);\n\nexport function shortType(type?: string): string {\n if (!type) return '';\n const lower = type.toLowerCase();\n const alias = TYPE_ALIAS.get(lower) ?? TYPE_ALIAS.get(lower.replace(/\\(.*\\)$/, '').trim());\n return clip(alias ?? type, TYPE_BUDGET);\n}\n\nexport function nodeHeight(table: TableMeta | undefined, open: boolean, preview = PREVIEW_FIELDS): number {\n if (!table?.columns.length) return HEAD_H;\n const total = table.columns.length;\n const shown = open ? total : Math.min(preview, total);\n const more = shown < total || open ? 1 : 0;\n if (!shown && !more) return HEAD_H;\n return HEAD_H + NODE_PAD + (shown + more) * FIELD_H + NODE_PAD;\n}\n\ninterface Neighbour {\n table: string;\n columns: string[];\n}\ninterface NeighbourhoodLayout {\n left: Array<Neighbour & { top: number }>;\n right: Array<Neighbour & { top: number }>;\n self: Fk[];\n width: number;\n height: number;\n leftX: number;\n midX: number;\n rightX: number;\n focusTop: number;\n focusAnchor: number;\n drawn: Set<string>;\n}\n\n/** One table and what it touches, laid out from measured heights rather than a fixed row pitch. */\nexport function neighbourhoodLayout(schema: Schema, tableId: string, heightOf: (id: string) => number): NeighbourhoodLayout | null {\n const out = schema.foreignKeys.filter((fk) => fk.from.table === tableId && fk.to.table !== tableId);\n const back = schema.foreignKeys.filter((fk) => fk.to.table === tableId && fk.from.table !== tableId);\n const self = schema.foreignKeys.filter((fk) => fk.from.table === tableId && fk.to.table === tableId);\n /* Several keys can join the same pair of tables; one node per table, with the columns collected onto the edge. */\n const group = (keys: Fk[], side: 'out' | 'in'): Neighbour[] => {\n const byTable = new Map<string, Neighbour>();\n for (const fk of keys) {\n const other = side === 'out' ? fk.to.table : fk.from.table;\n const entry = byTable.get(other) ?? { table: other, columns: [] };\n entry.columns.push(fk.from.columns.join(', '));\n byTable.set(other, entry);\n }\n return [...byTable.values()];\n };\n const left = group(out, 'out');\n const right = group(back, 'in');\n if (!left.length && !right.length && !self.length) return null;\n const stack = (nodes: Neighbour[]) => {\n const heights = nodes.map((n) => heightOf(n.table));\n const total = heights.reduce((a, b) => a + b, 0) + Math.max(0, nodes.length - 1) * ROW_GAP;\n let offset = 0;\n const tops = heights.map((h) => {\n const at = offset;\n offset += h + ROW_GAP;\n return at;\n });\n return { total, tops };\n };\n const l = stack(left);\n const r = stack(right);\n const focusHeight = heightOf(tableId);\n const selfRoom = self.length ? 46 : 0;\n const extent = Math.max(l.total, r.total, focusHeight);\n const height = extent + selfRoom + 30;\n const columns = 1 + (left.length ? 1 : 0) + (right.length ? 1 : 0);\n const width = NODE_W * columns + COL_GAP * (columns - 1);\n const top = (blockTotal: number) => selfRoom + 15 + (extent - blockTotal) / 2;\n const midX = left.length ? NODE_W + COL_GAP : 0;\n const focusTop = top(focusHeight);\n return {\n left: left.map((n, i) => ({ ...n, top: top(l.total) + l.tops[i] })),\n right: right.map((n, i) => ({ ...n, top: top(r.total) + r.tops[i] })),\n self,\n width,\n height,\n leftX: 0,\n midX,\n rightX: midX + NODE_W + COL_GAP,\n focusTop,\n /* Edges meet a node at its header, which stays put as the body grows. */\n focusAnchor: focusTop + HEAD_H / 2,\n drawn: new Set([tableId, ...out.map((fk) => fk.to.table), ...back.map((fk) => fk.from.table)]),\n };\n}\n\n/** Longest chain of references out of each table, capped against cycles. */\nexport function dependencyDepth(tables: TableMeta[], keys: Fk[]): Map<string, number> {\n const out = new Map(tables.map((t) => [t.id, [] as string[]]));\n for (const fk of keys) {\n if (fk.from.table === fk.to.table) continue; // a self-reference adds no depth\n out.get(fk.from.table)?.push(fk.to.table);\n }\n const depth = new Map<string, number>();\n const visiting = new Set<string>();\n const walk = (id: string): number => {\n if (depth.has(id)) return depth.get(id)!;\n /* A cycle has no well-defined depth; breaking it at 0 keeps the layout stable. */\n if (visiting.has(id)) return 0;\n visiting.add(id);\n const targets = out.get(id) ?? [];\n const d = targets.length ? 1 + Math.max(...targets.map(walk)) : 0;\n visiting.delete(id);\n depth.set(id, d);\n return d;\n };\n for (const t of tables) walk(t.id);\n return depth;\n}\n\n/** The most-connected tables, name as the tiebreak so the same schema always opens on the same picture. */\nfunction hubTables(tables: TableMeta[], foreignKeys: Fk[]): TableMeta[] {\n const degree = new Map<string, number>();\n const bump = (id: string) => degree.set(id, (degree.get(id) ?? 0) + 1);\n for (const fk of foreignKeys) {\n bump(fk.from.table);\n if (fk.to.table !== fk.from.table) bump(fk.to.table);\n }\n return [...tables].sort((a, b) => (degree.get(b.id) ?? 0) - (degree.get(a.id) ?? 0) || a.id.localeCompare(b.id)).slice(0, HUB_TABLES);\n}\n\n/** The focused tables and one hop out from each. */\nexport function inScope(tables: TableMeta[], foreignKeys: Fk[], focused: Set<string>): TableMeta[] {\n if (!focused.size) return tables;\n const keep = new Set(focused);\n for (const fk of foreignKeys) {\n if (focused.has(fk.from.table)) keep.add(fk.to.table);\n if (focused.has(fk.to.table)) keep.add(fk.from.table);\n }\n return tables.filter((t) => keep.has(t.id));\n}\n\ninterface SchemaLayout {\n tables: TableMeta[];\n foreignKeys: Fk[];\n pos: Map<string, { x: number; top: number; y: number }>;\n width: number;\n height: number;\n levels: number;\n preview: number;\n trimmed: boolean;\n}\n\n/**\n * Every table at once, ranked by dependency depth: tables that reference\n * nothing in the first column, tables that reference only those in the\n * second, and so on. Reading left to right is the order you would insert in.\n */\nexport function schemaLayout(\n schema: Schema,\n focused: Set<string>,\n showEverything: boolean,\n heightOf: (table: TableMeta, preview: number) => number,\n): SchemaLayout | null {\n const { tables: allTables, foreignKeys: allKeys } = schema;\n if (!allTables.length) return null;\n /* Dense and unfocused opens on the hubs, not the hairball. */\n const trimmed = !focused.size && !showEverything && allTables.length > DENSE_SCHEMA;\n const tables = trimmed ? hubTables(allTables, allKeys) : inScope(allTables, allKeys, focused);\n const visible = new Set(tables.map((t) => t.id));\n const foreignKeys = allKeys.filter((fk) => visible.has(fk.from.table) && visible.has(fk.to.table));\n const preview = tables.length > DENSE_SCHEMA ? 0 : PREVIEW_FIELDS;\n const depth = dependencyDepth(tables, foreignKeys);\n const columns = new Map<number, TableMeta[]>();\n for (const t of tables) {\n const d = depth.get(t.id) ?? 0;\n if (!columns.has(d)) columns.set(d, []);\n columns.get(d)!.push(t);\n }\n const order = [...columns.keys()].sort((a, b) => a - b);\n for (const d of order) columns.get(d)!.sort((a, b) => a.id.localeCompare(b.id));\n const heights = new Map(tables.map((t) => [t.id, heightOf(t, preview)]));\n const columnTotal = (list: TableMeta[]) =>\n list.reduce((sum, t) => sum + heights.get(t.id)!, 0) + Math.max(0, list.length - 1) * S_ROW_GAP;\n const tallest = Math.max(...order.map((d) => columnTotal(columns.get(d)!)));\n const width = order.length * NODE_W + (order.length - 1) * S_COL_GAP;\n const height = tallest + 24;\n const pos = new Map<string, { x: number; top: number; y: number }>();\n order.forEach((d, col) => {\n const list = columns.get(d)!;\n let top = 12 + (tallest - columnTotal(list)) / 2;\n for (const t of list) {\n pos.set(t.id, { x: col * (NODE_W + S_COL_GAP), top, y: top + HEAD_H / 2 });\n top += heights.get(t.id)! + S_ROW_GAP;\n }\n });\n return { tables, foreignKeys, pos, width, height, levels: order.length, preview, trimmed };\n}\n","/**\n * Score `text` against a typed query. Higher is better; 0 means no match.\n *\n * The tiers matter more than the numbers: an exact name beats a prefix beats\n * a substring beats a scattered subsequence. Within a tier, shorter names win\n * — `site` should outrank `site_visit_note` for the query \"site\", because the\n * shorter one is what someone typing four letters usually meant.\n */\nexport function score(text: string, query: string): number {\n if (!query) return 1;\n const haystack = text.toLowerCase();\n const needle = query.toLowerCase();\n\n if (haystack === needle) return 1000;\n if (haystack.startsWith(needle)) return 800 - haystack.length;\n const at = haystack.indexOf(needle);\n if (at >= 0) return 600 - at - haystack.length / 10;\n\n /* Subsequence: every character of the query, in order, anywhere. Two things\n are rewarded, and between them they are what make `pol` mean\n `purchase_order_line` rather than `employee_skill`: a match at the start\n of a word (the beginning of the name, or the letter after an underscore),\n because initials are how people abbreviate a snake_case name in their\n head; and runs of adjacent characters, so `porder` prefers\n `purchase_order` over a name where those letters merely occur in order.\n Length is a small penalty rather than a large one. */\n let i = 0;\n let run = 0;\n let points = 0;\n for (let index = 0; index < haystack.length; index += 1) {\n const char = haystack[index];\n if (char !== needle[i]) {\n run = 0;\n continue;\n }\n const boundary = index === 0 || /[^a-z0-9]/.test(haystack[index - 1]);\n run += 1;\n points += run + (boundary ? 12 : 0);\n i += 1;\n if (i === needle.length) break;\n }\n return i === needle.length ? 100 + points - haystack.length / 20 : 0;\n}\n","/** What Picker says, in the forms room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n searchMore: 'Search…',\n noTableMatches: 'No table matches.',\n});\n","/**\n * A typeahead over a short list of named things — the tables the diagram\n * can be limited to. Ranked by the palette's own `score`, so the same\n * letters find the same table here and in ⌘K; the list and its keyboard\n * are Typeahead's.\n */\nimport { useState } from 'react';\nimport { score } from './paletteModel.js';\nimport { Typeahead } from '@mistriwork/ui/Typeahead.js';\nimport { say } from '../copy/forms/components/Picker.js';\n\ninterface PickerItem {\n value: string;\n label: string;\n detail?: string;\n}\n\nexport function Picker({\n items,\n onPick,\n placeholder = say('searchMore'),\n ariaLabel = say('navigation.search'),\n max = 8,\n}: {\n items: PickerItem[];\n onPick: (value: string) => void;\n placeholder?: string;\n ariaLabel?: string;\n max?: number;\n}) {\n const [query, setQuery] = useState('');\n const [open, setOpen] = useState(false);\n const shown = items\n .map((item) => ({ item, points: score(`${item.label} ${item.detail ?? ''}`.trim(), query.trim()) }))\n .filter(({ points }) => points > 0)\n .sort((a, b) => b.points - a.points)\n .slice(0, max)\n .map(({ item }) => item);\n return (\n <div className=\"picker\">\n <Typeahead\n text={query}\n onText={setQuery}\n open={open}\n onOpenChange={setOpen}\n items={shown}\n itemKey={(item) => item.value}\n itemLabel={(item) => item.label}\n itemClassName={(_item, highlighted) => `picker-option${highlighted ? ' active' : ''}`}\n renderItem={(item) => (\n <>\n <span className=\"picker-label\">{item.label}</span>\n {item.detail ? <span className=\"picker-detail\">{item.detail}</span> : null}\n </>\n )}\n onPick={(item) => {\n setQuery('');\n setOpen(false);\n onPick(item.value);\n }}\n inputProps={{\n type: 'text',\n className: 'picker-input',\n placeholder,\n 'aria-label': ariaLabel,\n autoComplete: 'off',\n spellCheck: false,\n }}\n popupClassName=\"picker-popup\"\n listClassName=\"picker-list\"\n empty={say('noTableMatches')}\n emptyClassName=\"picker-empty\"\n />\n </div>\n );\n}\n","/**\n * The schema as text — Mermaid, Markdown, JSON — with no DOM and no state.\n *\n * Split from schemaexport.js so the server can speak these formats too:\n * `tablewalk --export md` prints the same brief the browser downloads, and a\n * committed CLAUDE.md schema section costs one command. Pure on purpose, the\n * way shape.js is pure — a schema in, text out, importable from anywhere.\n */\n\n/**\n * The tables to export, and the keys wholly between them.\n *\n * @param {any} schema\n * @param {ReadonlySet<string> | null} [only] the tables to export, by id; every table when absent or empty\n */\nexport function selection(schema, only) {\n const wanted = only?.size ? schema.tables.filter((t) => only.has(t.id)) : schema.tables;\n const ids = new Set(wanted.map((t) => t.id));\n /* Only keys with both ends in the selection. A reference to a table that is\n not in the export is an edge pointing at nothing, which renders as a\n dangling arrow and imports as a broken constraint. */\n const keys = schema.foreignKeys.filter((fk) => ids.has(fk.from.table) && ids.has(fk.to.table));\n return { tables: wanted, keys };\n}\n\n/* ---------- text formats ---------- */\n\n/**\n * Mermaid `erDiagram`.\n *\n * Cardinality is stated as far as the catalog knows it, which is not very far:\n * a foreign key says the child *may* point at one parent, and says nothing\n * about whether a parent must have children. So every relationship is written\n * `}o--||` — many-optional to exactly-one — which is what a nullable foreign\n * key actually guarantees. Claiming more precision would be inventing it.\n *\n * Mermaid identifiers cannot contain a dot, so `app.invoice` becomes\n * `app_invoice`. Said in a comment at the top of the output rather than\n * silently, because someone comparing the diagram to their database will\n * notice.\n *\n * @param {any} schema\n * @param {ReadonlySet<string> | null} [only] the tables to export, by id; every table when absent or empty\n */\nexport function toMermaid(schema, only) {\n const { tables, keys } = selection(schema, only);\n const safe = (id) => id.replace(/[^\\w]/g, '_');\n const lines = ['erDiagram'];\n\n for (const table of tables) {\n lines.push(` ${safe(table.id)} {`);\n for (const column of table.columns) {\n const type = (column.type || 'unknown').replace(/[^\\w]/g, '_') || 'unknown';\n const marks = [column.primaryKey ? 'PK' : '', column.references ? 'FK' : ''].filter(Boolean).join(',');\n lines.push(` ${type} ${column.name}${marks ? ` ${marks}` : ''}`);\n }\n lines.push(' }');\n }\n\n for (const fk of keys) {\n const label = fk.from.columns.join(', ');\n lines.push(` ${safe(fk.to.table)} ||--o{ ${safe(fk.from.table)} : \"${label}\"`);\n }\n\n const renamed = tables.some((t) => safe(t.id) !== t.id);\n return (\n (renamed ? '%% Names containing a dot are written with an underscore: Mermaid ids cannot hold one.\\n' : '') + lines.join('\\n') + '\\n'\n );\n}\n\n/**\n * A readable reference document, of the kind that belongs in a repository.\n *\n * @param {any} schema\n * @param {ReadonlySet<string> | null} [only] the tables to export, by id; every table when absent or empty\n */\nexport function toMarkdown(schema, only) {\n const { tables, keys } = selection(schema, only);\n const out = [`# ${schema.label}`, ''];\n out.push(`${tables.length} table${tables.length === 1 ? '' : 's'}, ` + `${keys.length} foreign key${keys.length === 1 ? '' : 's'}.`, '');\n\n for (const table of tables) {\n out.push(`## ${table.id}${table.isView ? ' *(view)*' : ''}`, '');\n if (table.comment) out.push(table.comment, '');\n\n out.push('| Column | Type | | References |', '| --- | --- | --- | --- |');\n for (const c of table.columns) {\n const marks = [c.primaryKey ? '**key**' : '', c.nullable ? '' : 'required'].filter(Boolean).join(', ');\n const ref = c.references ? `→ \\`${c.references.table}.${c.references.column}\\`` : '';\n out.push(`| \\`${c.name}\\` | ${c.type} | ${marks} | ${ref} |`);\n }\n out.push('');\n\n /* What points *at* this table, which is the half a schema document\n usually leaves out and the half tablewalk exists to show. */\n const incoming = keys.filter((fk) => fk.to.table === table.id);\n if (incoming.length) {\n out.push('Referenced by:', '');\n for (const fk of incoming) {\n out.push(`- \\`${fk.from.table}\\` via \\`${fk.from.columns.join(', ')}\\`` + (fk.onDelete ? ` — on delete ${fk.onDelete}` : ''));\n }\n out.push('');\n }\n }\n return out.join('\\n');\n}\n\n/**\n * The structured form.\n *\n * Deliberately the shape tablewalk itself uses rather than a format invented\n * for export — anything that reads it is reading the same model the tool\n * reasons about, and there is no second definition to keep in step.\n *\n * @param {any} schema\n * @param {ReadonlySet<string> | null} [only] the tables to export, by id; every table when absent or empty\n */\nexport function toSchemaJson(schema, only) {\n const { tables, keys } = selection(schema, only);\n return JSON.stringify(\n {\n label: schema.label,\n dialect: schema.dialect,\n readAt: schema.readAt,\n exportedAt: new Date().toISOString(),\n partial: Boolean(only?.size) && tables.length < schema.tables.length,\n tables,\n foreignKeys: keys,\n },\n null,\n 2,\n );\n}\n","/** What schemaexport says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n theDiagramCouldNotBeRendered: 'The diagram could not be rendered as an image.',\n thereIsNoDiagram: 'There is no diagram to export.',\n unknownExportFormat: 'Unknown export format: {kind}',\n});\n","/**\n * The schema, taken out of tablewalk.\n *\n * A diagram you can only look at inside the tool is a diagram that never\n * reaches the design review, the pull request, or the person who asked what\n * this database looks like. The whole point of drawing it is to be able to\n * hand it to someone.\n *\n * Four formats, because they answer four different questions:\n *\n * - **SVG** for the picture, at any size, still readable when someone zooms\n * into the corner of it.\n * - **PNG** for the places that will not take an SVG — a chat message, a\n * slide, an issue comment.\n * - **Mermaid** for a repository. GitHub renders it inline, so an ER diagram\n * in a README stays a diagram and, more importantly, diffs as text when\n * the schema changes.\n * - **Markdown** and **JSON** for reading and for feeding to something else.\n *\n * All of them export *what is selected*. The diagram's focus filter already\n * narrows sixty-six tables to the eight someone cares about, and an export\n * that ignored that would hand back the hairball they had just finished\n * escaping.\n */\nimport { download } from './export.js';\nimport { selection, toMarkdown, toMermaid, toSchemaJson } from '@mistriwork/engine/shared/schematext.js';\nimport { say } from './copy/workbench/schemaexport.js';\n\nexport { selection, toMarkdown, toMermaid, toSchemaJson };\nimport { state } from './core.js';\nimport { shellBody } from './shellHost.js';\n\n/* ---------- the picture ---------- */\n\n/* Properties worth carrying into a standalone file. Everything the diagram's\n appearance depends on and nothing else — a full computed-style dump would\n inline several hundred declarations per node and produce a file too large to\n open. */\nconst PAINTED = [\n 'fill-opacity',\n 'stroke-width',\n 'stroke-dasharray',\n 'font-family',\n 'font-size',\n 'font-weight',\n 'letter-spacing',\n 'opacity',\n 'text-anchor',\n 'text-transform',\n];\n\n/* Written even when the value is `none`, which the rest are not.\n `fill: none` on an edge is not the absence of a fill — SVG's initial fill is\n black, so dropping the declaration as a default turned every curve into a\n solid black wedge and the diagram into an inkblot. */\nconst ALWAYS = ['fill', 'stroke'];\n\n/**\n * A copy of the drawing that stands on its own.\n *\n * The diagram on screen gets its colours from the page's stylesheet, so\n * serialising the live SVG produces a file of black-on-transparent shapes —\n * technically the same drawing and unrecognisable as it. Every painted\n * property is read off the rendered element and written onto the clone, which\n * is the only way to get a file that looks like what was on screen.\n *\n * The pan-and-zoom transform is dropped and the viewBox set to the drawing's\n * own extent, so the export is the whole diagram rather than the part of it\n * that happened to be in the window.\n */\nfunction standaloneSvg(svg, size) {\n const clone = svg.cloneNode(true);\n const from = svg.querySelectorAll('*');\n const to = clone.querySelectorAll('*');\n\n for (let i = 0; i < from.length; i += 1) {\n const computed = getComputedStyle(from[i]);\n const declarations = [...ALWAYS, ...PAINTED]\n .map((property) => {\n const value = computed.getPropertyValue(property);\n if (!value) return '';\n if (ALWAYS.includes(property)) return `${property}:${value}`;\n return value !== 'none' && value !== 'normal' ? `${property}:${value}` : '';\n })\n .filter(Boolean)\n .join(';');\n if (declarations) to[i].setAttribute('style', declarations);\n }\n\n const content = clone.querySelector('g');\n if (content) content.removeAttribute('transform');\n clone.setAttribute('viewBox', `0 0 ${Math.ceil(size.width)} ${Math.ceil(size.height)}`);\n clone.setAttribute('width', String(Math.ceil(size.width)));\n clone.setAttribute('height', String(Math.ceil(size.height)));\n clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n clone.style.removeProperty('width');\n clone.style.removeProperty('height');\n\n /* An explicit background. SVG has none, so a diagram exported from a light\n page and opened on a dark one is invisible ink. */\n const page = getComputedStyle(shellBody()).backgroundColor;\n const backing = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n backing.setAttribute('width', '100%');\n backing.setAttribute('height', '100%');\n backing.setAttribute('fill', page || '#ffffff');\n clone.insertBefore(backing, clone.firstChild);\n\n return new XMLSerializer().serializeToString(clone);\n}\n\n/**\n * The same drawing, rasterised.\n *\n * At twice the size, because a PNG of a diagram is nearly always looked at on\n * a display with more pixels than CSS says, and one rendered at 1× is the\n * blurry screenshot this feature exists to replace.\n */\nasync function svgToPng(markup, size, scale = 2) {\n const blob = new Blob([markup], { type: 'image/svg+xml;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n try {\n const image = await new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(say('theDiagramCouldNotBeRendered')));\n img.src = url;\n });\n const canvas = document.createElement('canvas');\n canvas.width = Math.ceil(size.width * scale);\n canvas.height = Math.ceil(size.height * scale);\n const context = canvas.getContext('2d');\n context.drawImage(image, 0, 0, canvas.width, canvas.height);\n return await new Promise((resolve) => canvas.toBlob(resolve, 'image/png'));\n } finally {\n URL.revokeObjectURL(url);\n }\n}\n\n/* ---------- saving ---------- */\n\nconst stamp = () => new Date().toISOString().slice(0, 10);\n\nfunction base(schema, only) {\n const slug = String(schema.label ?? 'schema')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n /* The filename says it is a subset. A file called `erp-schema.md` holding\n eight of sixty-five tables misleads whoever opens it next week, and they\n have no way to tell. */\n const part = only?.size ? `-${only.size}-tables` : '';\n return `${slug || 'schema'}${part}-${stamp()}`;\n}\n\n/** @param {string} kind\n * @param {{schema?: import('@mistriwork/engine/shared/schema.js').SchemaSubset, only?: Set<string> | null, svg?: SVGSVGElement, size?: {width: number, height: number}}} options\n */\nexport async function exportSchema(kind, { schema = state.schema, only, svg, size } = {}) {\n const name = base(schema, only);\n switch (kind) {\n case 'markdown':\n download(`${name}.md`, toMarkdown(schema, only), 'text/markdown');\n return;\n case 'json':\n download(`${name}.json`, toSchemaJson(schema, only), 'application/json');\n return;\n case 'mermaid':\n download(`${name}.mmd`, toMermaid(schema, only), 'text/plain');\n return;\n case 'svg': {\n if (!svg) throw new Error(say('thereIsNoDiagram'));\n download(`${name}.svg`, standaloneSvg(svg, size), 'image/svg+xml');\n return;\n }\n case 'png': {\n if (!svg) throw new Error(say('thereIsNoDiagram'));\n const blob = await svgToPng(standaloneSvg(svg, size), size);\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `${name}.png`;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n return;\n }\n default:\n throw new Error(say('unknownExportFormat', { kind }));\n }\n}\n","/** What SchemaExport says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n export: 'Export',\n theDrawingAnySize: 'the drawing, any size',\n forChatAndSlides: 'for chat and slides',\n mermaid: 'Mermaid',\n rendersInAReadme: 'renders in a README',\n markdown: 'Markdown',\n columnsAndKeys: 'columns and keys',\n theStructuredSchema: 'the structured schema',\n exported: 'Exported {what} as {kind}.',\n theExportFailed: 'The export failed.',\n tablesWhatTheDiagram: { one: '{count} table — what the diagram is showing', other: '{count} tables — what the diagram is showing' },\n exportThisSchema: 'Export this schema',\n exporting: 'Exporting…',\n tables: { one: '{count} table', other: '{count} tables' },\n allTables: 'all {tables}',\n theSchema: 'the schema',\n});\n","/**\n * Export the diagram. Deliberately the same `.export` menu\n * chrome the result-table Export uses: two menus that do the same kind of\n * thing in the same product should not have to be learned twice. The\n * writers stay in `schemaexport.js`.\n */\nimport { useState } from 'react';\nimport { toast } from '../core.js';\nimport { exportSchema } from '../schemaexport.js';\nimport type { SchemaSubset } from '@mistriwork/engine/shared/schema.js';\nimport { DropItem, DropMenu } from '@mistriwork/ui/DropMenu.js';\nimport { say } from '../copy/workbench/components/SchemaExport.js';\n\nconst FORMATS: Array<[string, string, string]> = [\n ['svg', 'SVG', say('theDrawingAnySize')],\n ['png', 'PNG', say('forChatAndSlides')],\n ['mermaid', say('mermaid'), say('rendersInAReadme')],\n ['markdown', say('markdown'), say('columnsAndKeys')],\n ['json', 'JSON', say('theStructuredSchema')],\n];\n\ninterface SchemaExportProps {\n schema: SchemaSubset;\n only?: Set<string> | null;\n /** Called at click time rather than captured: the diagram is rebuilt on every focus change. */\n picture?: () => { svg?: SVGSVGElement; size?: { width: number; height: number } };\n}\n\nexport function SchemaExportControl({ schema, only, picture }: SchemaExportProps) {\n const [open, setOpen] = useState(false);\n const [busy, setBusy] = useState<string | null>(null);\n const run = async (kind: string) => {\n setBusy(kind);\n try {\n await exportSchema(kind, { schema, only, ...(picture?.() ?? {}) });\n setOpen(false);\n toast(say('exported', { what: only?.size ? say('tables', { count: only.size }) : say('theSchema'), kind: kind.toUpperCase() }));\n } catch (error) {\n toast((error as Error).message ?? say('theExportFailed'), 'error');\n } finally {\n setBusy(null);\n }\n };\n /* Said once, at the top: whichever format you pick, you get what is on screen. */\n const scope = only?.size\n ? say('tablesWhatTheDiagram', { count: only.size })\n : say('allTables', { tables: say('tables', { count: schema.tables.length }) });\n return (\n <DropMenu\n className=\"export schema-export\"\n triggerClassName=\"export-summary\"\n triggerTitle={say('exportThisSchema')}\n label={say('export')}\n popupClassName=\"export-menu\"\n open={open}\n onOpenChange={setOpen}\n >\n <p className=\"export-note export-scope\">{scope}</p>\n {FORMATS.map(([kind, name, detail]) => (\n <DropItem key={kind} className=\"export-item\" disabled={busy === kind} closeOnClick={false} onClick={() => void run(kind)}>\n {busy === kind ? (\n say('exporting')\n ) : (\n <>\n <span className=\"export-kind\">{name}</span>\n <span className=\"export-count\">{detail}</span>\n </>\n )}\n </DropItem>\n ))}\n </DropMenu>\n );\n}\n","/** What Diagram says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n tables: { one: '{count} table', other: '{count} tables' },\n showLess: '− show less',\n diagram: 'diagram',\n zoomOut: 'Zoom out',\n zoom: 'Zoom in',\n fitTheWholeDiagram: 'Fit the whole diagram',\n fit: 'Fit',\n actualSize: 'Actual size',\n fullScreen: 'Full screen',\n openTheDiagramFull: 'Open the diagram full screen',\n closeTheFullScreen: 'Close the full-screen diagram',\n closeEsc: 'Close esc',\n unknownTable: 'Unknown table.',\n hasNoForeignKeys: '{tableId} has no foreign keys in either direction.',\n andWhatItTouches: '{name} and what it touches',\n foreignKeyNeighbourhood: 'Foreign key neighbourhood of {tableId}',\n points: 'points at →',\n pointed: '← pointed at by',\n thisDatabaseHasNoTables: 'This database has no tables.',\n stopLimiting: 'Stop limiting to {name}',\n showAll: 'Show all',\n limitTheDiagramToThese: 'Limit the diagram to these tables',\n addAnotherTable: 'Add another table…',\n showOnly: 'Show only…',\n entityDiagram: 'Entity diagram of {label}',\n levelsDeepLeftToRight: {\n one: '{count} level deep, left to right in reference order',\n other: '{count} levels deep, left to right in reference order',\n },\n showAllTables: 'Show all {count}',\n showTheHubs: 'Show the {count} hubs',\n columns: { one: '{count} column', other: '{count} columns' },\n cols: { one: '{count} col', other: '{count} cols' },\n foreignKeys: { one: '{count} foreign key', other: '{count} foreign keys' },\n mostConnectedOf: 'the {shown} most-connected of {tables} · {keys} between them · ',\n focusedOf: '{shown} of {tables} · {keys} · ',\n tablesWithNoForeignKeys: {\n one: '{count} table with no foreign keys at all: {names}',\n other: '{count} tables with no foreign keys at all: {names}',\n },\n plusMore: '+ {count} more',\n plusColumns: '+ {count} columns',\n});\n","/**\n * The schema drawn: one table and what it touches, or every table at once\n * ranked by dependency depth. Nodes list their columns and open to show\n * the rest; clicking a node walks there, so the diagram is navigation and\n * not just a picture. The geometry is `diagramModel.ts`; this draws it,\n * pans and zooms it, and exports it.\n */\nimport { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { findTable, go, state, tableView, viewportBox, viewportScale } from '../core.js';\nimport type { TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport {\n DENSE_SCHEMA,\n EDGE_LABEL_BUDGET,\n FIELD_H,\n HEAD_H,\n HUB_TABLES,\n NAME_BUDGET,\n NODE_PAD,\n NODE_W,\n PREVIEW_FIELDS,\n clip,\n neighbourhoodLayout,\n nodeHeight,\n orderedColumns,\n schemaLayout,\n shortType,\n type Fk,\n type Schema,\n} from './diagramModel.js';\nimport { Picker } from './Picker.js';\nimport { SchemaExportControl } from './SchemaExport.js';\nimport { formatNumber } from '../locale.js';\nimport { say } from '../copy/workbench/components/Diagram.js';\nimport { addHostListener, portalRoot, removeHostListener } from '../shellHost.js';\n\n/* Session state that a repaint must not forget: which nodes the reader has\n opened, which tables the overview is limited to, and whether they asked for\n the whole picture despite its density. */\nconst expanded = new Set<string>();\nconst focused = new Set<string>();\nlet showEverything = false;\n\nconst schemaOf = () => (state as { schema: Schema }).schema;\nconst heightOf = (id: string, preview = PREVIEW_FIELDS) => nodeHeight(findTable(id) as TableMeta | undefined, expanded.has(id), preview);\n\n/* ---------- pieces ---------- */\n\nfunction Node({\n tableId,\n x,\n y,\n role,\n preview = PREVIEW_FIELDS,\n repaint,\n extra,\n}: {\n tableId: string;\n x: number;\n y: number;\n role: string;\n preview?: number;\n repaint: () => void;\n extra?: { className?: string; onMouseEnter?: () => void; onMouseLeave?: () => void };\n}) {\n const table = findTable(tableId) as TableMeta | undefined;\n const height = heightOf(tableId, preview);\n const open = expanded.has(tableId);\n const ordered = table ? orderedColumns(table) : [];\n const shown = open ? ordered : ordered.slice(0, preview);\n const hidden = ordered.length - shown.length;\n const toggle = () => {\n if (open) expanded.delete(tableId);\n else expanded.add(tableId);\n repaint();\n };\n const walk = (mode: string) => go(tableView(tableId), mode);\n const label = tableId.length > 22 ? `${tableId.slice(0, 21)}…` : tableId;\n return (\n <g\n className={`node node-${role}${extra?.className ?? ''}`}\n data-table={tableId}\n onMouseEnter={extra?.onMouseEnter}\n onMouseLeave={extra?.onMouseLeave}\n >\n <rect x={x} y={y} width={NODE_W} height={height} rx={5} />\n <g\n className=\"node-head\"\n role=\"button\"\n tabIndex={0}\n onClick={() => walk(role === 'focus' ? 'replace' : 'reset')}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n walk('reset');\n }\n }}\n >\n <rect x={x} y={y} width={NODE_W} height={HEAD_H} rx={5} className=\"node-head-hit\" />\n <title>{table ? `${tableId} — ${say('columns', { count: table.columns.length })}` : tableId}</title>\n <text x={x + 10} y={y + HEAD_H / 2 + 4}>\n {label}\n </text>\n </g>\n {shown.length ? <line className=\"node-rule\" x1={x} x2={x + NODE_W} y1={y + HEAD_H} y2={y + HEAD_H} /> : null}\n {shown.map((col, i) => {\n const cy = y + HEAD_H + NODE_PAD + i * FIELD_H + FIELD_H - 5;\n const mark = col.primaryKey ? '◆' : col.references ? '→' : '';\n return (\n <g key={col.name}>\n <text x={x + 10} y={cy} className={`node-field${col.primaryKey ? ' is-key' : ''}${col.references ? ' is-ref' : ''}`}>\n {`${mark ? `${mark} ` : ''}${clip(col.name, NAME_BUDGET)}`}\n {/* The full name and type stay reachable even when both are shortened. */}\n <title>{`${col.name} ${col.type ?? ''}`.trim()}</title>\n </text>\n <text x={x + NODE_W - 10} y={cy} className=\"node-type\" textAnchor=\"end\">\n {shortType(col.type)}\n </text>\n </g>\n );\n })}\n {/* The toggle only exists when there is something behind it. */}\n {hidden > 0 || open\n ? (() => {\n const cy = y + HEAD_H + NODE_PAD + shown.length * FIELD_H + FIELD_H - 5;\n return (\n <g\n className=\"node-more\"\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n toggle();\n }}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n e.preventDefault();\n toggle();\n }}\n >\n <rect x={x} y={cy - FIELD_H + 4} width={NODE_W} height={FIELD_H} className=\"node-more-hit\" />\n <text x={x + 10} y={cy}>\n {open ? say('showLess') : shown.length ? say('plusMore', { count: hidden }) : say('plusColumns', { count: hidden })}\n </text>\n </g>\n );\n })()\n : null}\n </g>\n );\n}\n\nfunction Edge({ x1, y1, x2, y2, label, marker }: { x1: number; y1: number; x2: number; y2: number; label?: string; marker: string }) {\n const mid = (x1 + x2) / 2;\n return (\n <g>\n <path className=\"edge\" markerEnd={`url(#${marker})`} d={`M${x1},${y1} C${mid},${y1} ${mid},${y2} ${x2},${y2}`} />\n {label ? (\n <text x={mid} y={y1 - 6} className=\"edge-label\" textAnchor=\"middle\">\n {label.length > EDGE_LABEL_BUDGET ? `${label.slice(0, EDGE_LABEL_BUDGET - 1)}…` : label}\n <title>{label}</title>\n </text>\n ) : null}\n </g>\n );\n}\n\nconst Arrow = ({ id, size }: { id: string; size: number }) => (\n <defs>\n <marker id={id} viewBox=\"0 0 8 8\" refX={7} refY={4} markerWidth={size} markerHeight={size} orient=\"auto-start-reverse\">\n <path d=\"M0,0 L8,4 L0,8 z\" className=\"edge-head\" />\n </marker>\n </defs>\n);\n\n/**\n * Pan and zoom, imperative on purpose: the transform changes on every wheel\n * tick and pointer move, and a state update per pixel would be a render per\n * pixel. Opens fitted when fitting is readable, centred on the focus\n * otherwise; wheel zooms about the pointer; dragging the background pans.\n */\nfunction PanZoom({\n size,\n focus,\n expand,\n svgRef,\n label,\n svgClassName,\n children,\n}: {\n size: { width: number; height: number };\n focus?: { x: number; y: number };\n expand?: () => void;\n svgRef: React.RefObject<SVGSVGElement | null>;\n label: string;\n svgClassName?: string;\n children: ReactNode;\n}) {\n const viewport = useRef<HTMLDivElement>(null);\n const content = useRef<SVGGElement>(null);\n const [readout, setReadout] = useState('100%');\n const view = useRef({ scale: 1, x: 0, y: 0 });\n const MIN = 0.15;\n const MAX = 3;\n const apply = () => {\n const { x, y, scale } = view.current;\n content.current?.setAttribute('transform', `translate(${x} ${y}) scale(${scale})`);\n setReadout(`${Math.round(scale * 100)}%`);\n };\n const zoomAt = (factor: number, px: number, py: number) => {\n const v = view.current;\n const next = Math.min(MAX, Math.max(MIN, v.scale * factor));\n if (next === v.scale) return;\n v.x = px - ((px - v.x) * next) / v.scale;\n v.y = py - ((py - v.y) * next) / v.scale;\n v.scale = next;\n apply();\n };\n /* Never enlarges: fitting is about getting the whole thing on screen. Centred on both axes. */\n const fit = () => {\n const box = viewportBox(viewport.current!);\n if (!box.width) return false;\n const v = view.current;\n v.scale = Math.min(1, Math.max(MIN, Math.min((box.width - 24) / size.width, (box.height - 24) / size.height)));\n v.x = (box.width - size.width * v.scale) / 2;\n v.y = (box.height - size.height * v.scale) / 2;\n apply();\n return true;\n };\n const reset = () => {\n const box = viewportBox(viewport.current!);\n const v = view.current;\n v.scale = 1;\n v.x = Math.min(12, (box.width - size.width) / 2);\n v.y = Math.min(12, (box.height - size.height) / 2);\n apply();\n };\n useLayoutEffect(() => {\n const node = viewport.current!;\n const READABLE = 0.5;\n const open = () => {\n const box = viewportBox(node);\n if (!box.width) return false;\n const fitted = Math.min((box.width - 24) / size.width, (box.height - 24) / size.height);\n if (!focus || fitted >= READABLE) return fit();\n view.current = { scale: 1, x: box.width / 2 - focus.x, y: box.height / 2 - focus.y };\n apply();\n return true;\n };\n /* Opening needs a measured viewport, which does not exist until the node is laid out. */\n let watch: ResizeObserver | null = null;\n if (!open() && typeof ResizeObserver !== 'undefined') {\n watch = new ResizeObserver(() => {\n if (open()) watch?.disconnect();\n });\n watch.observe(node);\n }\n /* Wheel zooms rather than scrolls; shift pans sideways. Non-passive, so the page does not scroll too. */\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n const z = viewportScale() as number;\n const box = viewportBox(node);\n const px = e.clientX / z - box.left;\n const py = e.clientY / z - box.top;\n if (e.shiftKey && !e.ctrlKey) {\n view.current.x -= (e.deltaY || e.deltaX) / z;\n apply();\n return;\n }\n zoomAt(Math.exp(-e.deltaY / 400), px, py);\n };\n node.addEventListener('wheel', onWheel, { passive: false });\n return () => {\n watch?.disconnect();\n node.removeEventListener('wheel', onWheel);\n };\n }, [size.width, size.height]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const dragging = useRef<{ px: number; py: number; x: number; y: number } | null>(null);\n const centre = () => {\n const b = viewportBox(viewport.current!);\n return [b.width / 2, b.height / 2] as const;\n };\n return (\n <div\n ref={viewport}\n className=\"diagram-viewport\"\n onPointerDown={(e) => {\n if (e.button !== 0) return;\n /* The controls sit inside the viewport; a press on one must not start a pan. */\n if ((e.target as Element).closest('.node-head, .node-more, .zoom-controls')) return;\n dragging.current = { px: e.clientX, py: e.clientY, x: view.current.x, y: view.current.y };\n viewport.current!.setPointerCapture(e.pointerId);\n viewport.current!.classList.add('dragging');\n }}\n onPointerMove={(e) => {\n const d = dragging.current;\n if (!d) return;\n const z = viewportScale() as number;\n view.current.x = d.x + (e.clientX - d.px) / z;\n view.current.y = d.y + (e.clientY - d.py) / z;\n apply();\n }}\n onPointerUp={() => {\n dragging.current = null;\n viewport.current?.classList.remove('dragging');\n }}\n onPointerCancel={() => {\n dragging.current = null;\n viewport.current?.classList.remove('dragging');\n }}\n >\n {/* No viewBox: the group's transform is the camera, so it fills its box and the numbers stay layout pixels. */}\n {/* A group, not an image: its tables are Tab stops, and an image's\n children are hidden from assistive technology, focusable or not. */}\n <svg\n ref={svgRef}\n role=\"group\"\n aria-roledescription={say('diagram')}\n style={{ width: '100%', height: '100%' }}\n aria-label={label}\n className={svgClassName}\n >\n <g ref={content}>{children}</g>\n </svg>\n <div className=\"zoom-controls\">\n <button\n type=\"button\"\n className=\"ghost\"\n title={say('zoomOut')}\n aria-label={say('zoomOut')}\n onClick={() => {\n const [cx, cy] = centre();\n zoomAt(1 / 1.25, cx, cy);\n }}\n >\n −\n </button>\n <span className=\"zoom-readout\">{readout}</span>\n <button\n type=\"button\"\n className=\"ghost\"\n title={say('zoom')}\n aria-label={say('zoom')}\n onClick={() => {\n const [cx, cy] = centre();\n zoomAt(1.25, cx, cy);\n }}\n >\n +\n </button>\n <button type=\"button\" className=\"ghost\" title={say('fitTheWholeDiagram')} onClick={fit}>\n {say('fit')}\n </button>\n <button type=\"button\" className=\"ghost\" title={say('actualSize')} onClick={reset}>\n 1:1\n </button>\n {expand ? (\n <button type=\"button\" className=\"ghost\" title={say('fullScreen')} aria-label={say('openTheDiagramFull')} onClick={expand}>\n ⛶\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\n/** The same diagram over everything, with Escape captured so the page's own habits do not fire underneath. */\nfunction Fullscreen({ onClose, children }: { onClose: () => void; children: ReactNode }) {\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n e.stopPropagation();\n e.preventDefault();\n onClose();\n };\n addHostListener(document, 'keydown', onKey, true);\n return () => removeHostListener(document, 'keydown', onKey, true);\n }, [onClose]);\n return createPortal(\n <div className=\"diagram-full\">\n <button type=\"button\" className=\"ghost diagram-full-close\" aria-label={say('closeTheFullScreen')} onClick={onClose}>\n {say('closeEsc')}\n </button>\n {children}\n </div>,\n portalRoot(),\n );\n}\n\n/* ---------- one table and its neighbours ---------- */\n\nexport function NeighbourhoodDiagram({ tableId, expandable = true }: { tableId: string; expandable?: boolean }) {\n const [, bump] = useState(0);\n const repaint = () => bump((n) => n + 1);\n const [full, setFull] = useState(false);\n const svg = useRef<SVGSVGElement>(null);\n const focus = findTable(tableId) as TableMeta | undefined;\n if (!focus) return <p className=\"note\">{say('unknownTable')}</p>;\n const layout = neighbourhoodLayout(schemaOf(), tableId, (id) => heightOf(id));\n if (!layout) return <p className=\"note\">{say('hasNoForeignKeys', { tableId })}</p>;\n const { left, right, self, width, height, leftX, midX, rightX, focusTop, focusAnchor, drawn } = layout;\n const drawing = (\n <>\n <Arrow id=\"arrow\" size={7} />\n {left.map((node) => (\n <g key={node.table}>\n <Edge x1={leftX + NODE_W} y1={node.top + HEAD_H / 2} x2={midX} y2={focusAnchor} label={node.columns.join(' · ')} marker=\"arrow\" />\n <Node tableId={node.table} x={leftX} y={node.top} role=\"out\" repaint={repaint} />\n </g>\n ))}\n {right.map((node) => (\n <g key={node.table}>\n <Edge\n x1={rightX}\n y1={node.top + HEAD_H / 2}\n x2={midX + NODE_W}\n y2={focusAnchor}\n label={node.columns.join(' · ')}\n marker=\"arrow\"\n />\n <Node tableId={node.table} x={rightX} y={node.top} role=\"in\" repaint={repaint} />\n </g>\n ))}\n {self.length ? (\n /* A self-reference has nowhere else to go, so it loops above the node. */\n <>\n <path\n className=\"edge\"\n markerEnd=\"url(#arrow)\"\n d={`M${midX + NODE_W * 0.3},${focusTop} C${midX + NODE_W * 0.1},${focusTop - 34} ${midX + NODE_W * 0.9},${focusTop - 34} ${midX + NODE_W * 0.7},${focusTop}`}\n />\n <text x={midX + NODE_W / 2} y={focusTop - 22} className=\"edge-label\" textAnchor=\"middle\">\n {self.map((fk) => fk.from.columns.join(', ')).join(' · ')}\n </text>\n </>\n ) : null}\n <Node tableId={tableId} x={midX} y={focusTop} role=\"focus\" repaint={repaint} />\n </>\n );\n return (\n <>\n <div className=\"diagram-head\">\n <h2 className=\"diagram-title\">{say('andWhatItTouches', { name: focus.name })}</h2>\n <SchemaExportControl\n schema={schemaOf()}\n only={drawn}\n picture={() => ({ svg: svg.current ?? undefined, size: { width, height } })}\n />\n </div>\n <PanZoom\n size={{ width, height }}\n focus={{ x: midX + NODE_W / 2, y: focusAnchor }}\n svgRef={svg}\n label={say('foreignKeyNeighbourhood', { tableId })}\n expand={expandable ? () => setFull(true) : undefined}\n >\n {drawing}\n </PanZoom>\n <p className=\"diagram-legend\">\n <span className=\"legend-out\">{say('points')}</span>\n <span>{` ${focus.name} `}</span>\n <span className=\"legend-in\">{say('pointed')}</span>\n </p>\n {/* The overlay's own instance offers no second overlay. */}\n {full ? (\n <Fullscreen onClose={() => setFull(false)}>\n <div className=\"diagram\">\n <NeighbourhoodDiagram tableId={tableId} expandable={false} />\n </div>\n </Fullscreen>\n ) : null}\n </>\n );\n}\n\n/* ---------- the whole schema ---------- */\n\nexport function SchemaDiagram({ expandable = true }: { expandable?: boolean }) {\n const [, bump] = useState(0);\n const repaint = () => bump((n) => n + 1);\n const [full, setFull] = useState(false);\n const [lit, setLit] = useState<string | null>(null);\n const svg = useRef<SVGSVGElement>(null);\n const schema = schemaOf();\n const layout = schemaLayout(schema, focused, showEverything, (table, preview) => nodeHeight(table, expanded.has(table.id), preview));\n if (!layout) return <p className=\"note\">{say('thisDatabaseHasNoTables')}</p>;\n const { tables, foreignKeys, pos, width, height, levels, preview, trimmed } = layout;\n const allTables = schema.tables;\n const visible = new Set(tables.map((t) => t.id));\n /* Hovering a table dims everything it is not connected to: on a hundred tables, the difference between a picture and an answer. */\n const connected = new Set<string>();\n if (lit) {\n connected.add(lit);\n for (const fk of schema.foreignKeys) {\n if (fk.from.table === lit) connected.add(fk.to.table);\n if (fk.to.table === lit) connected.add(fk.from.table);\n }\n }\n const orphans = tables.filter((t) => !foreignKeys.some((fk) => fk.from.table === t.id || fk.to.table === t.id));\n const edgeOf = (fk: Fk, i: number) => {\n const from = pos.get(fk.from.table);\n const to = pos.get(fk.to.table);\n if (!from || !to) return null;\n const dim = Boolean(lit) && fk.from.table !== lit && fk.to.table !== lit;\n if (fk.from.table === fk.to.table) {\n const x = from.x + NODE_W / 2;\n const y = from.top;\n return (\n <path\n key={i}\n className={`edge${dim ? ' dim' : ''}`}\n markerEnd=\"url(#arrow-s)\"\n d={`M${x - 18},${y} C${x - 24},${y - 22} ${x + 24},${y - 22} ${x + 18},${y}`}\n data-from={fk.from.table}\n data-to={fk.to.table}\n />\n );\n }\n /* Leaving from whichever side faces the target keeps lines from doubling back across their own node. */\n const leftToRight = to.x >= from.x;\n const x1 = leftToRight ? from.x + NODE_W : from.x;\n const x2 = leftToRight ? to.x : to.x + NODE_W;\n const mid = (x1 + x2) / 2;\n return (\n <path\n key={i}\n className={`edge${dim ? ' dim' : ''}`}\n markerEnd=\"url(#arrow-s)\"\n d={`M${x1},${from.y} C${mid},${from.y} ${mid},${to.y} ${x2},${to.y}`}\n data-from={fk.from.table}\n data-to={fk.to.table}\n />\n );\n };\n const drawing = (\n <>\n <Arrow id=\"arrow-s\" size={6} />\n <g className=\"schema-edges\">{foreignKeys.map(edgeOf)}</g>\n {tables.map((table) => {\n const p = pos.get(table.id)!;\n const className = lit ? (table.id === lit ? ' lit' : connected.has(table.id) ? '' : ' dim') : '';\n return (\n <Node\n key={table.id}\n tableId={table.id}\n x={p.x}\n y={p.top}\n role={table.isView ? 'view' : 'out'}\n preview={preview}\n repaint={repaint}\n extra={{ className, onMouseEnter: () => setLit(table.id), onMouseLeave: () => setLit(null) }}\n />\n );\n })}\n </>\n );\n return (\n <>\n <div className=\"diagram-head\">\n <h2 className=\"diagram-title\">{schema.label}</h2>\n <div className=\"diagram-focus\">\n {[...focused].map((id) => {\n const table = allTables.find((t) => t.id === id);\n return (\n <button\n key={id}\n type=\"button\"\n className=\"diagram-chip\"\n title={say('stopLimiting', { name: table?.name ?? id })}\n onClick={() => {\n focused.delete(id);\n repaint();\n }}\n >\n <span>{table?.name ?? id}</span>\n <span className=\"chip-x\" aria-hidden=\"true\">\n ×\n </span>\n </button>\n );\n })}\n {focused.size ? (\n <button\n type=\"button\"\n className=\"ghost diagram-clear\"\n onClick={() => {\n focused.clear();\n repaint();\n }}\n >\n {say('showAll')}\n </button>\n ) : null}\n <Picker\n items={allTables\n .filter((t) => !focused.has(t.id))\n .map((t) => ({ value: t.id, label: t.name, detail: say('cols', { count: t.columns.length }) }))}\n onPick={(id) => {\n if (allTables.some((t) => t.id === id)) {\n focused.add(id);\n repaint();\n }\n }}\n ariaLabel={say('limitTheDiagramToThese')}\n placeholder={focused.size ? say('addAnotherTable') : say('showOnly')}\n />\n </div>\n {/* `visible`, not `focused`: the diagram draws one hop past the chips, and the export should hold what is on screen. */}\n <SchemaExportControl\n schema={schema}\n only={focused.size || trimmed ? visible : undefined}\n picture={() => ({ svg: svg.current ?? undefined, size: { width, height } })}\n />\n </div>\n <PanZoom\n size={{ width, height }}\n svgRef={svg}\n label={say('entityDiagram', { label: schema.label ?? '' })}\n svgClassName={lit ? 'has-focus' : undefined}\n expand={expandable ? () => setFull(true) : undefined}\n >\n {drawing}\n </PanZoom>\n <p className=\"diagram-legend\">\n <span>\n {trimmed\n ? say('mostConnectedOf', {\n shown: formatNumber(tables.length),\n tables: say('tables', { count: allTables.length }),\n keys: say('foreignKeys', { count: foreignKeys.length }),\n })\n : focused.size\n ? say('focusedOf', {\n shown: formatNumber(tables.length),\n tables: say('tables', { count: allTables.length }),\n keys: say('foreignKeys', { count: foreignKeys.length }),\n })\n : `${say('tables', { count: tables.length })} · ${say('foreignKeys', { count: foreignKeys.length })} · `}\n </span>\n <span>{say('levelsDeepLeftToRight', { count: levels })}</span>\n {trimmed ? (\n <button\n type=\"button\"\n className=\"ghost diagram-scope\"\n onClick={() => {\n showEverything = true;\n repaint();\n }}\n >\n {say('showAllTables', { count: allTables.length })}\n </button>\n ) : null}\n {!trimmed && !focused.size && showEverything && allTables.length > DENSE_SCHEMA ? (\n <button\n type=\"button\"\n className=\"ghost diagram-scope\"\n onClick={() => {\n showEverything = false;\n repaint();\n }}\n >\n {say('showTheHubs', { count: Math.min(HUB_TABLES, allTables.length) })}\n </button>\n ) : null}\n </p>\n {orphans.length ? (\n <p className=\"diagram-legend\">{`${say('tablesWithNoForeignKeys', {\n count: orphans.length,\n names: orphans\n .slice(0, 6)\n .map((t) => t.name)\n .join(', '),\n })}${orphans.length > 6 ? '…' : ''}`}</p>\n ) : null}\n {full ? (\n <Fullscreen onClose={() => setFull(false)}>\n <div className=\"diagram diagram-schema\">\n <SchemaDiagram expandable={false} />\n </div>\n </Fullscreen>\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shared-CbeujwdU.js","names":["say","say","_Fragment","say","say","say","say","_Fragment","_Fragment"],"sources":["../../../kit/src/client/components/diagramModel.ts","../../../kit/src/client/components/paletteModel.ts","../../../kit/src/client/copy/forms/components/Picker.ts","../../../kit/src/client/components/Picker.tsx","../../../engine/src/shared/schematext.js","../../../kit/src/client/copy/workbench/schemaexport.ts","../../../kit/src/client/schemaexport.js","../../../kit/src/client/copy/workbench/components/SchemaExport.ts","../../../kit/src/client/components/SchemaExport.tsx","../../../kit/src/client/copy/workbench/components/Diagram.ts","../../../kit/src/client/components/Diagram.tsx"],"sourcesContent":["/**\n * The diagram's geometry, as numbers: which columns a node lists and how\n * tall that makes it, where the neighbourhood's three columns sit, and\n * the dependency-depth layout of the whole schema. Pure, so the drawing\n * can be tested without drawing.\n */\nimport { labelColumn } from '../core.js';\nimport type { ColumnMeta, TableMeta } from '@mistriwork/engine/shared/schema.js';\n\nexport interface Fk {\n name: string;\n from: { table: string; columns: string[] };\n to: { table: string; columns: string[] };\n}\nexport interface Schema {\n label?: string;\n tables: TableMeta[];\n foreignKeys: Fk[];\n}\n\nexport const NODE_W = 216;\nexport const HEAD_H = 30;\nexport const FIELD_H = 17;\nexport const NODE_PAD = 5;\nconst ROW_GAP = 18;\nexport const COL_GAP = 156;\nexport const PREVIEW_FIELDS = 5;\n/** Characters an edge label can carry before it would reach a node. */\nexport const EDGE_LABEL_BUDGET = 22;\nexport const NAME_BUDGET = 18;\nconst TYPE_BUDGET = 12;\nexport const S_COL_GAP = 96;\nconst S_ROW_GAP = 18;\nexport const DENSE_SCHEMA = 24;\n/** How many of a dense schema's tables the overview opens with. */\nexport const HUB_TABLES = 12;\n\n/** Key, references, the label column, then the rest, each in declared order. */\nexport function orderedColumns(table: TableMeta): ColumnMeta[] {\n const label = labelColumn(table) as string | undefined;\n const rank = (c: ColumnMeta) => (c.primaryKey ? 0 : c.references ? 1 : c.name === label ? 2 : 3);\n return [...table.columns]\n .map((c, i) => ({ c, i }))\n .sort((a, b) => rank(a.c) - rank(b.c) || a.i - b.i)\n .map(({ c }) => c);\n}\n\nconst TYPE_ALIAS = new Map([\n ['timestamp with time zone', 'timestamptz'],\n ['timestamp without time zone', 'timestamp'],\n ['time with time zone', 'timetz'],\n ['time without time zone', 'time'],\n ['character varying', 'varchar'],\n ['character', 'char'],\n ['double precision', 'float8'],\n ['integer', 'int'],\n ['boolean', 'bool'],\n]);\n\nexport const clip = (text: string, max: number) => (text.length > max ? `${text.slice(0, max - 1)}…` : text);\n\nexport function shortType(type?: string): string {\n if (!type) return '';\n const lower = type.toLowerCase();\n const alias = TYPE_ALIAS.get(lower) ?? TYPE_ALIAS.get(lower.replace(/\\(.*\\)$/, '').trim());\n return clip(alias ?? type, TYPE_BUDGET);\n}\n\nexport function nodeHeight(table: TableMeta | undefined, open: boolean, preview = PREVIEW_FIELDS): number {\n if (!table?.columns.length) return HEAD_H;\n const total = table.columns.length;\n const shown = open ? total : Math.min(preview, total);\n const more = shown < total || open ? 1 : 0;\n if (!shown && !more) return HEAD_H;\n return HEAD_H + NODE_PAD + (shown + more) * FIELD_H + NODE_PAD;\n}\n\ninterface Neighbour {\n table: string;\n columns: string[];\n}\ninterface NeighbourhoodLayout {\n left: Array<Neighbour & { top: number }>;\n right: Array<Neighbour & { top: number }>;\n self: Fk[];\n width: number;\n height: number;\n leftX: number;\n midX: number;\n rightX: number;\n focusTop: number;\n focusAnchor: number;\n drawn: Set<string>;\n}\n\n/** One table and what it touches, laid out from measured heights rather than a fixed row pitch. */\nexport function neighbourhoodLayout(schema: Schema, tableId: string, heightOf: (id: string) => number): NeighbourhoodLayout | null {\n const out = schema.foreignKeys.filter((fk) => fk.from.table === tableId && fk.to.table !== tableId);\n const back = schema.foreignKeys.filter((fk) => fk.to.table === tableId && fk.from.table !== tableId);\n const self = schema.foreignKeys.filter((fk) => fk.from.table === tableId && fk.to.table === tableId);\n /* Several keys can join the same pair of tables; one node per table, with the columns collected onto the edge. */\n const group = (keys: Fk[], side: 'out' | 'in'): Neighbour[] => {\n const byTable = new Map<string, Neighbour>();\n for (const fk of keys) {\n const other = side === 'out' ? fk.to.table : fk.from.table;\n const entry = byTable.get(other) ?? { table: other, columns: [] };\n entry.columns.push(fk.from.columns.join(', '));\n byTable.set(other, entry);\n }\n return [...byTable.values()];\n };\n const left = group(out, 'out');\n const right = group(back, 'in');\n if (!left.length && !right.length && !self.length) return null;\n const stack = (nodes: Neighbour[]) => {\n const heights = nodes.map((n) => heightOf(n.table));\n const total = heights.reduce((a, b) => a + b, 0) + Math.max(0, nodes.length - 1) * ROW_GAP;\n let offset = 0;\n const tops = heights.map((h) => {\n const at = offset;\n offset += h + ROW_GAP;\n return at;\n });\n return { total, tops };\n };\n const l = stack(left);\n const r = stack(right);\n const focusHeight = heightOf(tableId);\n const selfRoom = self.length ? 46 : 0;\n const extent = Math.max(l.total, r.total, focusHeight);\n const height = extent + selfRoom + 30;\n const columns = 1 + (left.length ? 1 : 0) + (right.length ? 1 : 0);\n const width = NODE_W * columns + COL_GAP * (columns - 1);\n const top = (blockTotal: number) => selfRoom + 15 + (extent - blockTotal) / 2;\n const midX = left.length ? NODE_W + COL_GAP : 0;\n const focusTop = top(focusHeight);\n return {\n left: left.map((n, i) => ({ ...n, top: top(l.total) + l.tops[i] })),\n right: right.map((n, i) => ({ ...n, top: top(r.total) + r.tops[i] })),\n self,\n width,\n height,\n leftX: 0,\n midX,\n rightX: midX + NODE_W + COL_GAP,\n focusTop,\n /* Edges meet a node at its header, which stays put as the body grows. */\n focusAnchor: focusTop + HEAD_H / 2,\n drawn: new Set([tableId, ...out.map((fk) => fk.to.table), ...back.map((fk) => fk.from.table)]),\n };\n}\n\n/** Longest chain of references out of each table, capped against cycles. */\nexport function dependencyDepth(tables: TableMeta[], keys: Fk[]): Map<string, number> {\n const out = new Map(tables.map((t) => [t.id, [] as string[]]));\n for (const fk of keys) {\n if (fk.from.table === fk.to.table) continue; // a self-reference adds no depth\n out.get(fk.from.table)?.push(fk.to.table);\n }\n const depth = new Map<string, number>();\n const visiting = new Set<string>();\n const walk = (id: string): number => {\n if (depth.has(id)) return depth.get(id)!;\n /* A cycle has no well-defined depth; breaking it at 0 keeps the layout stable. */\n if (visiting.has(id)) return 0;\n visiting.add(id);\n const targets = out.get(id) ?? [];\n const d = targets.length ? 1 + Math.max(...targets.map(walk)) : 0;\n visiting.delete(id);\n depth.set(id, d);\n return d;\n };\n for (const t of tables) walk(t.id);\n return depth;\n}\n\n/** The most-connected tables, name as the tiebreak so the same schema always opens on the same picture. */\nfunction hubTables(tables: TableMeta[], foreignKeys: Fk[]): TableMeta[] {\n const degree = new Map<string, number>();\n const bump = (id: string) => degree.set(id, (degree.get(id) ?? 0) + 1);\n for (const fk of foreignKeys) {\n bump(fk.from.table);\n if (fk.to.table !== fk.from.table) bump(fk.to.table);\n }\n return [...tables].sort((a, b) => (degree.get(b.id) ?? 0) - (degree.get(a.id) ?? 0) || a.id.localeCompare(b.id)).slice(0, HUB_TABLES);\n}\n\n/** The focused tables and one hop out from each. */\nexport function inScope(tables: TableMeta[], foreignKeys: Fk[], focused: Set<string>): TableMeta[] {\n if (!focused.size) return tables;\n const keep = new Set(focused);\n for (const fk of foreignKeys) {\n if (focused.has(fk.from.table)) keep.add(fk.to.table);\n if (focused.has(fk.to.table)) keep.add(fk.from.table);\n }\n return tables.filter((t) => keep.has(t.id));\n}\n\ninterface SchemaLayout {\n tables: TableMeta[];\n foreignKeys: Fk[];\n pos: Map<string, { x: number; top: number; y: number }>;\n width: number;\n height: number;\n levels: number;\n preview: number;\n trimmed: boolean;\n}\n\n/**\n * Every table at once, ranked by dependency depth: tables that reference\n * nothing in the first column, tables that reference only those in the\n * second, and so on. Reading left to right is the order you would insert in.\n */\nexport function schemaLayout(\n schema: Schema,\n focused: Set<string>,\n showEverything: boolean,\n heightOf: (table: TableMeta, preview: number) => number,\n): SchemaLayout | null {\n const { tables: allTables, foreignKeys: allKeys } = schema;\n if (!allTables.length) return null;\n /* Dense and unfocused opens on the hubs, not the hairball. */\n const trimmed = !focused.size && !showEverything && allTables.length > DENSE_SCHEMA;\n const tables = trimmed ? hubTables(allTables, allKeys) : inScope(allTables, allKeys, focused);\n const visible = new Set(tables.map((t) => t.id));\n const foreignKeys = allKeys.filter((fk) => visible.has(fk.from.table) && visible.has(fk.to.table));\n const preview = tables.length > DENSE_SCHEMA ? 0 : PREVIEW_FIELDS;\n const depth = dependencyDepth(tables, foreignKeys);\n const columns = new Map<number, TableMeta[]>();\n for (const t of tables) {\n const d = depth.get(t.id) ?? 0;\n if (!columns.has(d)) columns.set(d, []);\n columns.get(d)!.push(t);\n }\n const order = [...columns.keys()].sort((a, b) => a - b);\n for (const d of order) columns.get(d)!.sort((a, b) => a.id.localeCompare(b.id));\n const heights = new Map(tables.map((t) => [t.id, heightOf(t, preview)]));\n const columnTotal = (list: TableMeta[]) =>\n list.reduce((sum, t) => sum + heights.get(t.id)!, 0) + Math.max(0, list.length - 1) * S_ROW_GAP;\n const tallest = Math.max(...order.map((d) => columnTotal(columns.get(d)!)));\n const width = order.length * NODE_W + (order.length - 1) * S_COL_GAP;\n const height = tallest + 24;\n const pos = new Map<string, { x: number; top: number; y: number }>();\n order.forEach((d, col) => {\n const list = columns.get(d)!;\n let top = 12 + (tallest - columnTotal(list)) / 2;\n for (const t of list) {\n pos.set(t.id, { x: col * (NODE_W + S_COL_GAP), top, y: top + HEAD_H / 2 });\n top += heights.get(t.id)! + S_ROW_GAP;\n }\n });\n return { tables, foreignKeys, pos, width, height, levels: order.length, preview, trimmed };\n}\n","/**\n * Score `text` against a typed query. Higher is better; 0 means no match.\n *\n * The tiers matter more than the numbers: an exact name beats a prefix beats\n * a substring beats a scattered subsequence. Within a tier, shorter names win\n * — `site` should outrank `site_visit_note` for the query \"site\", because the\n * shorter one is what someone typing four letters usually meant.\n */\nexport function score(text: string, query: string): number {\n if (!query) return 1;\n const haystack = text.toLowerCase();\n const needle = query.toLowerCase();\n\n if (haystack === needle) return 1000;\n if (haystack.startsWith(needle)) return 800 - haystack.length;\n const at = haystack.indexOf(needle);\n if (at >= 0) return 600 - at - haystack.length / 10;\n\n /* Subsequence: every character of the query, in order, anywhere. Two things\n are rewarded, and between them they are what make `pol` mean\n `purchase_order_line` rather than `employee_skill`: a match at the start\n of a word (the beginning of the name, or the letter after an underscore),\n because initials are how people abbreviate a snake_case name in their\n head; and runs of adjacent characters, so `porder` prefers\n `purchase_order` over a name where those letters merely occur in order.\n Length is a small penalty rather than a large one. */\n let i = 0;\n let run = 0;\n let points = 0;\n for (let index = 0; index < haystack.length; index += 1) {\n const char = haystack[index];\n if (char !== needle[i]) {\n run = 0;\n continue;\n }\n const boundary = index === 0 || /[^a-z0-9]/.test(haystack[index - 1]);\n run += 1;\n points += run + (boundary ? 12 : 0);\n i += 1;\n if (i === needle.length) break;\n }\n return i === needle.length ? 100 + points - haystack.length / 20 : 0;\n}\n","/** What Picker says, in the forms room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n searchMore: 'Search…',\n noTableMatches: 'No table matches.',\n});\n","/**\n * A typeahead over a short list of named things — the tables the diagram\n * can be limited to. Ranked by the palette's own `score`, so the same\n * letters find the same table here and in ⌘K; the list and its keyboard\n * are Typeahead's.\n */\nimport { useState } from 'react';\nimport { score } from './paletteModel.js';\nimport { Typeahead } from '@mistriwork/ui/Typeahead.js';\nimport { say } from '../copy/forms/components/Picker.js';\n\ninterface PickerItem {\n value: string;\n label: string;\n detail?: string;\n}\n\nexport function Picker({\n items,\n onPick,\n placeholder = say('searchMore'),\n ariaLabel = say('navigation.search'),\n max = 8,\n}: {\n items: PickerItem[];\n onPick: (value: string) => void;\n placeholder?: string;\n ariaLabel?: string;\n max?: number;\n}) {\n const [query, setQuery] = useState('');\n const [open, setOpen] = useState(false);\n const shown = items\n .map((item) => ({ item, points: score(`${item.label} ${item.detail ?? ''}`.trim(), query.trim()) }))\n .filter(({ points }) => points > 0)\n .sort((a, b) => b.points - a.points)\n .slice(0, max)\n .map(({ item }) => item);\n return (\n <div className=\"picker\">\n <Typeahead\n text={query}\n onText={setQuery}\n open={open}\n onOpenChange={setOpen}\n items={shown}\n itemKey={(item) => item.value}\n itemLabel={(item) => item.label}\n itemClassName={(_item, highlighted) => `picker-option${highlighted ? ' active' : ''}`}\n renderItem={(item) => (\n <>\n <span className=\"picker-label\">{item.label}</span>\n {item.detail ? <span className=\"picker-detail\">{item.detail}</span> : null}\n </>\n )}\n onPick={(item) => {\n setQuery('');\n setOpen(false);\n onPick(item.value);\n }}\n inputProps={{\n type: 'text',\n className: 'picker-input',\n placeholder,\n 'aria-label': ariaLabel,\n autoComplete: 'off',\n spellCheck: false,\n }}\n popupClassName=\"picker-popup\"\n listClassName=\"picker-list\"\n empty={say('noTableMatches')}\n emptyClassName=\"picker-empty\"\n />\n </div>\n );\n}\n","/**\n * The schema as text — Mermaid, Markdown, JSON — with no DOM and no state.\n *\n * Split from schemaexport.js so the server can speak these formats too:\n * `tablewalk --export md` prints the same brief the browser downloads, and a\n * committed CLAUDE.md schema section costs one command. Pure on purpose, the\n * way shape.js is pure — a schema in, text out, importable from anywhere.\n */\n\n/**\n * The tables to export, and the keys wholly between them.\n *\n * @param {any} schema\n * @param {ReadonlySet<string> | null} [only] the tables to export, by id; every table when absent or empty\n */\nexport function selection(schema, only) {\n const wanted = only?.size ? schema.tables.filter((t) => only.has(t.id)) : schema.tables;\n const ids = new Set(wanted.map((t) => t.id));\n /* Only keys with both ends in the selection. A reference to a table that is\n not in the export is an edge pointing at nothing, which renders as a\n dangling arrow and imports as a broken constraint. */\n const keys = schema.foreignKeys.filter((fk) => ids.has(fk.from.table) && ids.has(fk.to.table));\n return { tables: wanted, keys };\n}\n\n/* ---------- text formats ---------- */\n\n/**\n * Mermaid `erDiagram`.\n *\n * Cardinality is stated as far as the catalog knows it, which is not very far:\n * a foreign key says the child *may* point at one parent, and says nothing\n * about whether a parent must have children. So every relationship is written\n * `}o--||` — many-optional to exactly-one — which is what a nullable foreign\n * key actually guarantees. Claiming more precision would be inventing it.\n *\n * Mermaid identifiers cannot contain a dot, so `app.invoice` becomes\n * `app_invoice`. Said in a comment at the top of the output rather than\n * silently, because someone comparing the diagram to their database will\n * notice.\n *\n * @param {any} schema\n * @param {ReadonlySet<string> | null} [only] the tables to export, by id; every table when absent or empty\n */\nexport function toMermaid(schema, only) {\n const { tables, keys } = selection(schema, only);\n const safe = (id) => id.replace(/[^\\w]/g, '_');\n const lines = ['erDiagram'];\n\n for (const table of tables) {\n lines.push(` ${safe(table.id)} {`);\n for (const column of table.columns) {\n const type = (column.type || 'unknown').replace(/[^\\w]/g, '_') || 'unknown';\n const marks = [column.primaryKey ? 'PK' : '', column.references ? 'FK' : ''].filter(Boolean).join(',');\n lines.push(` ${type} ${column.name}${marks ? ` ${marks}` : ''}`);\n }\n lines.push(' }');\n }\n\n for (const fk of keys) {\n const label = fk.from.columns.join(', ');\n lines.push(` ${safe(fk.to.table)} ||--o{ ${safe(fk.from.table)} : \"${label}\"`);\n }\n\n const renamed = tables.some((t) => safe(t.id) !== t.id);\n return (\n (renamed ? '%% Names containing a dot are written with an underscore: Mermaid ids cannot hold one.\\n' : '') + lines.join('\\n') + '\\n'\n );\n}\n\n/**\n * A readable reference document, of the kind that belongs in a repository.\n *\n * @param {any} schema\n * @param {ReadonlySet<string> | null} [only] the tables to export, by id; every table when absent or empty\n */\nexport function toMarkdown(schema, only) {\n const { tables, keys } = selection(schema, only);\n const out = [`# ${schema.label}`, ''];\n out.push(`${tables.length} table${tables.length === 1 ? '' : 's'}, ` + `${keys.length} foreign key${keys.length === 1 ? '' : 's'}.`, '');\n\n for (const table of tables) {\n out.push(`## ${table.id}${table.isView ? ' *(view)*' : ''}`, '');\n if (table.comment) out.push(table.comment, '');\n\n out.push('| Column | Type | | References |', '| --- | --- | --- | --- |');\n for (const c of table.columns) {\n const marks = [c.primaryKey ? '**key**' : '', c.nullable ? '' : 'required'].filter(Boolean).join(', ');\n const ref = c.references ? `→ \\`${c.references.table}.${c.references.column}\\`` : '';\n out.push(`| \\`${c.name}\\` | ${c.type} | ${marks} | ${ref} |`);\n }\n out.push('');\n\n /* What points *at* this table, which is the half a schema document\n usually leaves out and the half tablewalk exists to show. */\n const incoming = keys.filter((fk) => fk.to.table === table.id);\n if (incoming.length) {\n out.push('Referenced by:', '');\n for (const fk of incoming) {\n out.push(`- \\`${fk.from.table}\\` via \\`${fk.from.columns.join(', ')}\\`` + (fk.onDelete ? ` — on delete ${fk.onDelete}` : ''));\n }\n out.push('');\n }\n }\n return out.join('\\n');\n}\n\n/**\n * The structured form.\n *\n * Deliberately the shape tablewalk itself uses rather than a format invented\n * for export — anything that reads it is reading the same model the tool\n * reasons about, and there is no second definition to keep in step.\n *\n * @param {any} schema\n * @param {ReadonlySet<string> | null} [only] the tables to export, by id; every table when absent or empty\n */\nexport function toSchemaJson(schema, only) {\n const { tables, keys } = selection(schema, only);\n return JSON.stringify(\n {\n label: schema.label,\n dialect: schema.dialect,\n readAt: schema.readAt,\n exportedAt: new Date().toISOString(),\n partial: Boolean(only?.size) && tables.length < schema.tables.length,\n tables,\n foreignKeys: keys,\n },\n null,\n 2,\n );\n}\n","/** What schemaexport says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n theDiagramCouldNotBeRendered: 'The diagram could not be rendered as an image.',\n thereIsNoDiagram: 'There is no diagram to export.',\n unknownExportFormat: 'Unknown export format: {kind}',\n});\n","/**\n * The schema, taken out of tablewalk.\n *\n * A diagram you can only look at inside the tool is a diagram that never\n * reaches the design review, the pull request, or the person who asked what\n * this database looks like. The whole point of drawing it is to be able to\n * hand it to someone.\n *\n * Four formats, because they answer four different questions:\n *\n * - **SVG** for the picture, at any size, still readable when someone zooms\n * into the corner of it.\n * - **PNG** for the places that will not take an SVG — a chat message, a\n * slide, an issue comment.\n * - **Mermaid** for a repository. GitHub renders it inline, so an ER diagram\n * in a README stays a diagram and, more importantly, diffs as text when\n * the schema changes.\n * - **Markdown** and **JSON** for reading and for feeding to something else.\n *\n * All of them export *what is selected*. The diagram's focus filter already\n * narrows sixty-six tables to the eight someone cares about, and an export\n * that ignored that would hand back the hairball they had just finished\n * escaping.\n */\nimport { download } from './export.js';\nimport { selection, toMarkdown, toMermaid, toSchemaJson } from '@mistriwork/engine/shared/schematext.js';\nimport { say } from './copy/workbench/schemaexport.js';\n\nexport { selection, toMarkdown, toMermaid, toSchemaJson };\nimport { state } from './core.js';\nimport { shellBody } from './shellHost.js';\n\n/* ---------- the picture ---------- */\n\n/* Properties worth carrying into a standalone file. Everything the diagram's\n appearance depends on and nothing else — a full computed-style dump would\n inline several hundred declarations per node and produce a file too large to\n open. */\nconst PAINTED = [\n 'fill-opacity',\n 'stroke-width',\n 'stroke-dasharray',\n 'font-family',\n 'font-size',\n 'font-weight',\n 'letter-spacing',\n 'opacity',\n 'text-anchor',\n 'text-transform',\n];\n\n/* Written even when the value is `none`, which the rest are not.\n `fill: none` on an edge is not the absence of a fill — SVG's initial fill is\n black, so dropping the declaration as a default turned every curve into a\n solid black wedge and the diagram into an inkblot. */\nconst ALWAYS = ['fill', 'stroke'];\n\n/**\n * A copy of the drawing that stands on its own.\n *\n * The diagram on screen gets its colours from the page's stylesheet, so\n * serialising the live SVG produces a file of black-on-transparent shapes —\n * technically the same drawing and unrecognisable as it. Every painted\n * property is read off the rendered element and written onto the clone, which\n * is the only way to get a file that looks like what was on screen.\n *\n * The pan-and-zoom transform is dropped and the viewBox set to the drawing's\n * own extent, so the export is the whole diagram rather than the part of it\n * that happened to be in the window.\n */\nfunction standaloneSvg(svg, size) {\n const clone = svg.cloneNode(true);\n const from = svg.querySelectorAll('*');\n const to = clone.querySelectorAll('*');\n\n for (let i = 0; i < from.length; i += 1) {\n const computed = getComputedStyle(from[i]);\n const declarations = [...ALWAYS, ...PAINTED]\n .map((property) => {\n const value = computed.getPropertyValue(property);\n if (!value) return '';\n if (ALWAYS.includes(property)) return `${property}:${value}`;\n return value !== 'none' && value !== 'normal' ? `${property}:${value}` : '';\n })\n .filter(Boolean)\n .join(';');\n if (declarations) to[i].setAttribute('style', declarations);\n }\n\n const content = clone.querySelector('g');\n if (content) content.removeAttribute('transform');\n clone.setAttribute('viewBox', `0 0 ${Math.ceil(size.width)} ${Math.ceil(size.height)}`);\n clone.setAttribute('width', String(Math.ceil(size.width)));\n clone.setAttribute('height', String(Math.ceil(size.height)));\n clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n clone.style.removeProperty('width');\n clone.style.removeProperty('height');\n\n /* An explicit background. SVG has none, so a diagram exported from a light\n page and opened on a dark one is invisible ink. */\n const page = getComputedStyle(shellBody()).backgroundColor;\n const backing = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n backing.setAttribute('width', '100%');\n backing.setAttribute('height', '100%');\n backing.setAttribute('fill', page || '#ffffff');\n clone.insertBefore(backing, clone.firstChild);\n\n return new XMLSerializer().serializeToString(clone);\n}\n\n/**\n * The same drawing, rasterised.\n *\n * At twice the size, because a PNG of a diagram is nearly always looked at on\n * a display with more pixels than CSS says, and one rendered at 1× is the\n * blurry screenshot this feature exists to replace.\n */\nasync function svgToPng(markup, size, scale = 2) {\n const blob = new Blob([markup], { type: 'image/svg+xml;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n try {\n const image = await new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(say('theDiagramCouldNotBeRendered')));\n img.src = url;\n });\n const canvas = document.createElement('canvas');\n canvas.width = Math.ceil(size.width * scale);\n canvas.height = Math.ceil(size.height * scale);\n const context = canvas.getContext('2d');\n context.drawImage(image, 0, 0, canvas.width, canvas.height);\n return await new Promise((resolve) => canvas.toBlob(resolve, 'image/png'));\n } finally {\n URL.revokeObjectURL(url);\n }\n}\n\n/* ---------- saving ---------- */\n\nconst stamp = () => new Date().toISOString().slice(0, 10);\n\nfunction base(schema, only) {\n const slug = String(schema.label ?? 'schema')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n /* The filename says it is a subset. A file called `erp-schema.md` holding\n eight of sixty-five tables misleads whoever opens it next week, and they\n have no way to tell. */\n const part = only?.size ? `-${only.size}-tables` : '';\n return `${slug || 'schema'}${part}-${stamp()}`;\n}\n\n/** @param {string} kind\n * @param {{schema?: import('@mistriwork/engine/shared/schema.js').SchemaSubset, only?: Set<string> | null, svg?: SVGSVGElement, size?: {width: number, height: number}}} options\n */\nexport async function exportSchema(kind, { schema = state.schema, only, svg, size } = {}) {\n const name = base(schema, only);\n switch (kind) {\n case 'markdown':\n download(`${name}.md`, toMarkdown(schema, only), 'text/markdown');\n return;\n case 'json':\n download(`${name}.json`, toSchemaJson(schema, only), 'application/json');\n return;\n case 'mermaid':\n download(`${name}.mmd`, toMermaid(schema, only), 'text/plain');\n return;\n case 'svg': {\n if (!svg) throw new Error(say('thereIsNoDiagram'));\n download(`${name}.svg`, standaloneSvg(svg, size), 'image/svg+xml');\n return;\n }\n case 'png': {\n if (!svg) throw new Error(say('thereIsNoDiagram'));\n const blob = await svgToPng(standaloneSvg(svg, size), size);\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `${name}.png`;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n return;\n }\n default:\n throw new Error(say('unknownExportFormat', { kind }));\n }\n}\n","/** What SchemaExport says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n export: 'Export',\n theDrawingAnySize: 'the drawing, any size',\n forChatAndSlides: 'for chat and slides',\n mermaid: 'Mermaid',\n rendersInAReadme: 'renders in a README',\n markdown: 'Markdown',\n columnsAndKeys: 'columns and keys',\n theStructuredSchema: 'the structured schema',\n exported: 'Exported {what} as {kind}.',\n theExportFailed: 'The export failed.',\n tablesWhatTheDiagram: { one: '{count} table — what the diagram is showing', other: '{count} tables — what the diagram is showing' },\n exportThisSchema: 'Export this schema',\n exporting: 'Exporting…',\n tables: { one: '{count} table', other: '{count} tables' },\n allTables: 'all {tables}',\n theSchema: 'the schema',\n});\n","/**\n * Export the diagram. Deliberately the same `.export` menu\n * chrome the result-table Export uses: two menus that do the same kind of\n * thing in the same product should not have to be learned twice. The\n * writers stay in `schemaexport.js`.\n */\nimport { useState } from 'react';\nimport { toast } from '../core.js';\nimport { exportSchema } from '../schemaexport.js';\nimport type { SchemaSubset } from '@mistriwork/engine/shared/schema.js';\nimport { DropItem, DropMenu } from '@mistriwork/ui/DropMenu.js';\nimport { say } from '../copy/workbench/components/SchemaExport.js';\n\nconst FORMATS: Array<[string, string, string]> = [\n ['svg', 'SVG', say('theDrawingAnySize')],\n ['png', 'PNG', say('forChatAndSlides')],\n ['mermaid', say('mermaid'), say('rendersInAReadme')],\n ['markdown', say('markdown'), say('columnsAndKeys')],\n ['json', 'JSON', say('theStructuredSchema')],\n];\n\ninterface SchemaExportProps {\n schema: SchemaSubset;\n only?: Set<string> | null;\n /** Called at click time rather than captured: the diagram is rebuilt on every focus change. */\n picture?: () => { svg?: SVGSVGElement; size?: { width: number; height: number } };\n}\n\nexport function SchemaExportControl({ schema, only, picture }: SchemaExportProps) {\n const [open, setOpen] = useState(false);\n const [busy, setBusy] = useState<string | null>(null);\n const run = async (kind: string) => {\n setBusy(kind);\n try {\n await exportSchema(kind, { schema, only, ...(picture?.() ?? {}) });\n setOpen(false);\n toast(say('exported', { what: only?.size ? say('tables', { count: only.size }) : say('theSchema'), kind: kind.toUpperCase() }));\n } catch (error) {\n toast((error as Error).message ?? say('theExportFailed'), 'error');\n } finally {\n setBusy(null);\n }\n };\n /* Said once, at the top: whichever format you pick, you get what is on screen. */\n const scope = only?.size\n ? say('tablesWhatTheDiagram', { count: only.size })\n : say('allTables', { tables: say('tables', { count: schema.tables.length }) });\n return (\n <DropMenu\n className=\"export schema-export\"\n triggerClassName=\"export-summary\"\n triggerTitle={say('exportThisSchema')}\n label={say('export')}\n popupClassName=\"export-menu\"\n open={open}\n onOpenChange={setOpen}\n >\n <p className=\"export-note export-scope\">{scope}</p>\n {FORMATS.map(([kind, name, detail]) => (\n <DropItem key={kind} className=\"export-item\" disabled={busy === kind} closeOnClick={false} onClick={() => void run(kind)}>\n {busy === kind ? (\n say('exporting')\n ) : (\n <>\n <span className=\"export-kind\">{name}</span>\n <span className=\"export-count\">{detail}</span>\n </>\n )}\n </DropItem>\n ))}\n </DropMenu>\n );\n}\n","/** What Diagram says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n tables: { one: '{count} table', other: '{count} tables' },\n showLess: '− show less',\n diagram: 'diagram',\n zoomOut: 'Zoom out',\n zoom: 'Zoom in',\n fitTheWholeDiagram: 'Fit the whole diagram',\n fit: 'Fit',\n actualSize: 'Actual size',\n fullScreen: 'Full screen',\n openTheDiagramFull: 'Open the diagram full screen',\n closeTheFullScreen: 'Close the full-screen diagram',\n closeEsc: 'Close esc',\n unknownTable: 'Unknown table.',\n hasNoForeignKeys: '{tableId} has no foreign keys in either direction.',\n andWhatItTouches: '{name} and what it touches',\n foreignKeyNeighbourhood: 'Foreign key neighbourhood of {tableId}',\n points: 'points at →',\n pointed: '← pointed at by',\n thisDatabaseHasNoTables: 'This database has no tables.',\n stopLimiting: 'Stop limiting to {name}',\n showAll: 'Show all',\n limitTheDiagramToThese: 'Limit the diagram to these tables',\n addAnotherTable: 'Add another table…',\n showOnly: 'Show only…',\n entityDiagram: 'Entity diagram of {label}',\n levelsDeepLeftToRight: {\n one: '{count} level deep, left to right in reference order',\n other: '{count} levels deep, left to right in reference order',\n },\n showAllTables: 'Show all {count}',\n showTheHubs: 'Show the {count} hubs',\n columns: { one: '{count} column', other: '{count} columns' },\n cols: { one: '{count} col', other: '{count} cols' },\n foreignKeys: { one: '{count} foreign key', other: '{count} foreign keys' },\n mostConnectedOf: 'the {shown} most-connected of {tables} · {keys} between them · ',\n focusedOf: '{shown} of {tables} · {keys} · ',\n tablesWithNoForeignKeys: {\n one: '{count} table with no foreign keys at all: {names}',\n other: '{count} tables with no foreign keys at all: {names}',\n },\n plusMore: '+ {count} more',\n plusColumns: '+ {count} columns',\n});\n","/**\n * The schema drawn: one table and what it touches, or every table at once\n * ranked by dependency depth. Nodes list their columns and open to show\n * the rest; clicking a node walks there, so the diagram is navigation and\n * not just a picture. The geometry is `diagramModel.ts`; this draws it,\n * pans and zooms it, and exports it.\n */\nimport { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { findTable, go, state, tableView, viewportBox, viewportScale } from '../core.js';\nimport type { TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport {\n DENSE_SCHEMA,\n EDGE_LABEL_BUDGET,\n FIELD_H,\n HEAD_H,\n HUB_TABLES,\n NAME_BUDGET,\n NODE_PAD,\n NODE_W,\n PREVIEW_FIELDS,\n clip,\n neighbourhoodLayout,\n nodeHeight,\n orderedColumns,\n schemaLayout,\n shortType,\n type Fk,\n type Schema,\n} from './diagramModel.js';\nimport { Picker } from './Picker.js';\nimport { SchemaExportControl } from './SchemaExport.js';\nimport { formatNumber } from '../locale.js';\nimport { say } from '../copy/workbench/components/Diagram.js';\nimport { addHostListener, portalRoot, removeHostListener } from '../shellHost.js';\n\n/* Session state that a repaint must not forget: which nodes the reader has\n opened, which tables the overview is limited to, and whether they asked for\n the whole picture despite its density. */\nconst expanded = new Set<string>();\nconst focused = new Set<string>();\nlet showEverything = false;\n\nconst schemaOf = () => (state as { schema: Schema }).schema;\nconst heightOf = (id: string, preview = PREVIEW_FIELDS) => nodeHeight(findTable(id) as TableMeta | undefined, expanded.has(id), preview);\n\n/* ---------- pieces ---------- */\n\nfunction Node({\n tableId,\n x,\n y,\n role,\n preview = PREVIEW_FIELDS,\n repaint,\n extra,\n}: {\n tableId: string;\n x: number;\n y: number;\n role: string;\n preview?: number;\n repaint: () => void;\n extra?: { className?: string; onMouseEnter?: () => void; onMouseLeave?: () => void };\n}) {\n const table = findTable(tableId) as TableMeta | undefined;\n const height = heightOf(tableId, preview);\n const open = expanded.has(tableId);\n const ordered = table ? orderedColumns(table) : [];\n const shown = open ? ordered : ordered.slice(0, preview);\n const hidden = ordered.length - shown.length;\n const toggle = () => {\n if (open) expanded.delete(tableId);\n else expanded.add(tableId);\n repaint();\n };\n const walk = (mode: string) => go(tableView(tableId), mode);\n const label = tableId.length > 22 ? `${tableId.slice(0, 21)}…` : tableId;\n return (\n <g\n className={`node node-${role}${extra?.className ?? ''}`}\n data-table={tableId}\n onMouseEnter={extra?.onMouseEnter}\n onMouseLeave={extra?.onMouseLeave}\n >\n <rect x={x} y={y} width={NODE_W} height={height} rx={5} />\n <g\n className=\"node-head\"\n role=\"button\"\n tabIndex={0}\n onClick={() => walk(role === 'focus' ? 'replace' : 'reset')}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n walk('reset');\n }\n }}\n >\n <rect x={x} y={y} width={NODE_W} height={HEAD_H} rx={5} className=\"node-head-hit\" />\n <title>{table ? `${tableId} — ${say('columns', { count: table.columns.length })}` : tableId}</title>\n <text x={x + 10} y={y + HEAD_H / 2 + 4}>\n {label}\n </text>\n </g>\n {shown.length ? <line className=\"node-rule\" x1={x} x2={x + NODE_W} y1={y + HEAD_H} y2={y + HEAD_H} /> : null}\n {shown.map((col, i) => {\n const cy = y + HEAD_H + NODE_PAD + i * FIELD_H + FIELD_H - 5;\n const mark = col.primaryKey ? '◆' : col.references ? '→' : '';\n return (\n <g key={col.name}>\n <text x={x + 10} y={cy} className={`node-field${col.primaryKey ? ' is-key' : ''}${col.references ? ' is-ref' : ''}`}>\n {`${mark ? `${mark} ` : ''}${clip(col.name, NAME_BUDGET)}`}\n {/* The full name and type stay reachable even when both are shortened. */}\n <title>{`${col.name} ${col.type ?? ''}`.trim()}</title>\n </text>\n <text x={x + NODE_W - 10} y={cy} className=\"node-type\" textAnchor=\"end\">\n {shortType(col.type)}\n </text>\n </g>\n );\n })}\n {/* The toggle only exists when there is something behind it. */}\n {hidden > 0 || open\n ? (() => {\n const cy = y + HEAD_H + NODE_PAD + shown.length * FIELD_H + FIELD_H - 5;\n return (\n <g\n className=\"node-more\"\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n toggle();\n }}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n e.preventDefault();\n toggle();\n }}\n >\n <rect x={x} y={cy - FIELD_H + 4} width={NODE_W} height={FIELD_H} className=\"node-more-hit\" />\n <text x={x + 10} y={cy}>\n {open ? say('showLess') : shown.length ? say('plusMore', { count: hidden }) : say('plusColumns', { count: hidden })}\n </text>\n </g>\n );\n })()\n : null}\n </g>\n );\n}\n\nfunction Edge({ x1, y1, x2, y2, label, marker }: { x1: number; y1: number; x2: number; y2: number; label?: string; marker: string }) {\n const mid = (x1 + x2) / 2;\n return (\n <g>\n <path className=\"edge\" markerEnd={`url(#${marker})`} d={`M${x1},${y1} C${mid},${y1} ${mid},${y2} ${x2},${y2}`} />\n {label ? (\n <text x={mid} y={y1 - 6} className=\"edge-label\" textAnchor=\"middle\">\n {label.length > EDGE_LABEL_BUDGET ? `${label.slice(0, EDGE_LABEL_BUDGET - 1)}…` : label}\n <title>{label}</title>\n </text>\n ) : null}\n </g>\n );\n}\n\nconst Arrow = ({ id, size }: { id: string; size: number }) => (\n <defs>\n <marker id={id} viewBox=\"0 0 8 8\" refX={7} refY={4} markerWidth={size} markerHeight={size} orient=\"auto-start-reverse\">\n <path d=\"M0,0 L8,4 L0,8 z\" className=\"edge-head\" />\n </marker>\n </defs>\n);\n\n/**\n * Pan and zoom, imperative on purpose: the transform changes on every wheel\n * tick and pointer move, and a state update per pixel would be a render per\n * pixel. Opens fitted when fitting is readable, centred on the focus\n * otherwise; wheel zooms about the pointer; dragging the background pans.\n */\nfunction PanZoom({\n size,\n focus,\n expand,\n svgRef,\n label,\n svgClassName,\n children,\n}: {\n size: { width: number; height: number };\n focus?: { x: number; y: number };\n expand?: () => void;\n svgRef: React.RefObject<SVGSVGElement | null>;\n label: string;\n svgClassName?: string;\n children: ReactNode;\n}) {\n const viewport = useRef<HTMLDivElement>(null);\n const content = useRef<SVGGElement>(null);\n const [readout, setReadout] = useState('100%');\n const view = useRef({ scale: 1, x: 0, y: 0 });\n const MIN = 0.15;\n const MAX = 3;\n const apply = () => {\n const { x, y, scale } = view.current;\n content.current?.setAttribute('transform', `translate(${x} ${y}) scale(${scale})`);\n setReadout(`${Math.round(scale * 100)}%`);\n };\n const zoomAt = (factor: number, px: number, py: number) => {\n const v = view.current;\n const next = Math.min(MAX, Math.max(MIN, v.scale * factor));\n if (next === v.scale) return;\n v.x = px - ((px - v.x) * next) / v.scale;\n v.y = py - ((py - v.y) * next) / v.scale;\n v.scale = next;\n apply();\n };\n /* Never enlarges: fitting is about getting the whole thing on screen. Centred on both axes. */\n const fit = () => {\n const box = viewportBox(viewport.current!);\n if (!box.width) return false;\n const v = view.current;\n v.scale = Math.min(1, Math.max(MIN, Math.min((box.width - 24) / size.width, (box.height - 24) / size.height)));\n v.x = (box.width - size.width * v.scale) / 2;\n v.y = (box.height - size.height * v.scale) / 2;\n apply();\n return true;\n };\n const reset = () => {\n const box = viewportBox(viewport.current!);\n const v = view.current;\n v.scale = 1;\n v.x = Math.min(12, (box.width - size.width) / 2);\n v.y = Math.min(12, (box.height - size.height) / 2);\n apply();\n };\n useLayoutEffect(() => {\n const node = viewport.current!;\n const READABLE = 0.5;\n const open = () => {\n const box = viewportBox(node);\n if (!box.width) return false;\n const fitted = Math.min((box.width - 24) / size.width, (box.height - 24) / size.height);\n if (!focus || fitted >= READABLE) return fit();\n view.current = { scale: 1, x: box.width / 2 - focus.x, y: box.height / 2 - focus.y };\n apply();\n return true;\n };\n /* Opening needs a measured viewport, which does not exist until the node is laid out. */\n let watch: ResizeObserver | null = null;\n if (!open() && typeof ResizeObserver !== 'undefined') {\n watch = new ResizeObserver(() => {\n if (open()) watch?.disconnect();\n });\n watch.observe(node);\n }\n /* Wheel zooms rather than scrolls; shift pans sideways. Non-passive, so the page does not scroll too. */\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n const z = viewportScale() as number;\n const box = viewportBox(node);\n const px = e.clientX / z - box.left;\n const py = e.clientY / z - box.top;\n if (e.shiftKey && !e.ctrlKey) {\n view.current.x -= (e.deltaY || e.deltaX) / z;\n apply();\n return;\n }\n zoomAt(Math.exp(-e.deltaY / 400), px, py);\n };\n node.addEventListener('wheel', onWheel, { passive: false });\n return () => {\n watch?.disconnect();\n node.removeEventListener('wheel', onWheel);\n };\n }, [size.width, size.height]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const dragging = useRef<{ px: number; py: number; x: number; y: number } | null>(null);\n const centre = () => {\n const b = viewportBox(viewport.current!);\n return [b.width / 2, b.height / 2] as const;\n };\n return (\n <div\n ref={viewport}\n className=\"diagram-viewport\"\n onPointerDown={(e) => {\n if (e.button !== 0) return;\n /* The controls sit inside the viewport; a press on one must not start a pan. */\n if ((e.target as Element).closest('.node-head, .node-more, .zoom-controls')) return;\n dragging.current = { px: e.clientX, py: e.clientY, x: view.current.x, y: view.current.y };\n viewport.current!.setPointerCapture(e.pointerId);\n viewport.current!.classList.add('dragging');\n }}\n onPointerMove={(e) => {\n const d = dragging.current;\n if (!d) return;\n const z = viewportScale() as number;\n view.current.x = d.x + (e.clientX - d.px) / z;\n view.current.y = d.y + (e.clientY - d.py) / z;\n apply();\n }}\n onPointerUp={() => {\n dragging.current = null;\n viewport.current?.classList.remove('dragging');\n }}\n onPointerCancel={() => {\n dragging.current = null;\n viewport.current?.classList.remove('dragging');\n }}\n >\n {/* No viewBox: the group's transform is the camera, so it fills its box and the numbers stay layout pixels. */}\n {/* A group, not an image: its tables are Tab stops, and an image's\n children are hidden from assistive technology, focusable or not. */}\n <svg\n ref={svgRef}\n role=\"group\"\n aria-roledescription={say('diagram')}\n style={{ width: '100%', height: '100%' }}\n aria-label={label}\n className={svgClassName}\n >\n <g ref={content}>{children}</g>\n </svg>\n <div className=\"zoom-controls\">\n <button\n type=\"button\"\n className=\"ghost\"\n title={say('zoomOut')}\n aria-label={say('zoomOut')}\n onClick={() => {\n const [cx, cy] = centre();\n zoomAt(1 / 1.25, cx, cy);\n }}\n >\n −\n </button>\n <span className=\"zoom-readout\">{readout}</span>\n <button\n type=\"button\"\n className=\"ghost\"\n title={say('zoom')}\n aria-label={say('zoom')}\n onClick={() => {\n const [cx, cy] = centre();\n zoomAt(1.25, cx, cy);\n }}\n >\n +\n </button>\n <button type=\"button\" className=\"ghost\" title={say('fitTheWholeDiagram')} onClick={fit}>\n {say('fit')}\n </button>\n <button type=\"button\" className=\"ghost\" title={say('actualSize')} onClick={reset}>\n 1:1\n </button>\n {expand ? (\n <button type=\"button\" className=\"ghost\" title={say('fullScreen')} aria-label={say('openTheDiagramFull')} onClick={expand}>\n ⛶\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\n/** The same diagram over everything, with Escape captured so the page's own habits do not fire underneath. */\nfunction Fullscreen({ onClose, children }: { onClose: () => void; children: ReactNode }) {\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n e.stopPropagation();\n e.preventDefault();\n onClose();\n };\n addHostListener(document, 'keydown', onKey, true);\n return () => removeHostListener(document, 'keydown', onKey, true);\n }, [onClose]);\n return createPortal(\n <div className=\"diagram-full\">\n <button type=\"button\" className=\"ghost diagram-full-close\" aria-label={say('closeTheFullScreen')} onClick={onClose}>\n {say('closeEsc')}\n </button>\n {children}\n </div>,\n portalRoot(),\n );\n}\n\n/* ---------- one table and its neighbours ---------- */\n\nexport function NeighbourhoodDiagram({ tableId, expandable = true }: { tableId: string; expandable?: boolean }) {\n const [, bump] = useState(0);\n const repaint = () => bump((n) => n + 1);\n const [full, setFull] = useState(false);\n const svg = useRef<SVGSVGElement>(null);\n const focus = findTable(tableId) as TableMeta | undefined;\n if (!focus) return <p className=\"note\">{say('unknownTable')}</p>;\n const layout = neighbourhoodLayout(schemaOf(), tableId, (id) => heightOf(id));\n if (!layout) return <p className=\"note\">{say('hasNoForeignKeys', { tableId })}</p>;\n const { left, right, self, width, height, leftX, midX, rightX, focusTop, focusAnchor, drawn } = layout;\n const drawing = (\n <>\n <Arrow id=\"arrow\" size={7} />\n {left.map((node) => (\n <g key={node.table}>\n <Edge x1={leftX + NODE_W} y1={node.top + HEAD_H / 2} x2={midX} y2={focusAnchor} label={node.columns.join(' · ')} marker=\"arrow\" />\n <Node tableId={node.table} x={leftX} y={node.top} role=\"out\" repaint={repaint} />\n </g>\n ))}\n {right.map((node) => (\n <g key={node.table}>\n <Edge\n x1={rightX}\n y1={node.top + HEAD_H / 2}\n x2={midX + NODE_W}\n y2={focusAnchor}\n label={node.columns.join(' · ')}\n marker=\"arrow\"\n />\n <Node tableId={node.table} x={rightX} y={node.top} role=\"in\" repaint={repaint} />\n </g>\n ))}\n {self.length ? (\n /* A self-reference has nowhere else to go, so it loops above the node. */\n <>\n <path\n className=\"edge\"\n markerEnd=\"url(#arrow)\"\n d={`M${midX + NODE_W * 0.3},${focusTop} C${midX + NODE_W * 0.1},${focusTop - 34} ${midX + NODE_W * 0.9},${focusTop - 34} ${midX + NODE_W * 0.7},${focusTop}`}\n />\n <text x={midX + NODE_W / 2} y={focusTop - 22} className=\"edge-label\" textAnchor=\"middle\">\n {self.map((fk) => fk.from.columns.join(', ')).join(' · ')}\n </text>\n </>\n ) : null}\n <Node tableId={tableId} x={midX} y={focusTop} role=\"focus\" repaint={repaint} />\n </>\n );\n return (\n <>\n <div className=\"diagram-head\">\n <h2 className=\"diagram-title\">{say('andWhatItTouches', { name: focus.name })}</h2>\n <SchemaExportControl\n schema={schemaOf()}\n only={drawn}\n picture={() => ({ svg: svg.current ?? undefined, size: { width, height } })}\n />\n </div>\n <PanZoom\n size={{ width, height }}\n focus={{ x: midX + NODE_W / 2, y: focusAnchor }}\n svgRef={svg}\n label={say('foreignKeyNeighbourhood', { tableId })}\n expand={expandable ? () => setFull(true) : undefined}\n >\n {drawing}\n </PanZoom>\n <p className=\"diagram-legend\">\n <span className=\"legend-out\">{say('points')}</span>\n <span>{` ${focus.name} `}</span>\n <span className=\"legend-in\">{say('pointed')}</span>\n </p>\n {/* The overlay's own instance offers no second overlay. */}\n {full ? (\n <Fullscreen onClose={() => setFull(false)}>\n <div className=\"diagram\">\n <NeighbourhoodDiagram tableId={tableId} expandable={false} />\n </div>\n </Fullscreen>\n ) : null}\n </>\n );\n}\n\n/* ---------- the whole schema ---------- */\n\nexport function SchemaDiagram({ expandable = true }: { expandable?: boolean }) {\n const [, bump] = useState(0);\n const repaint = () => bump((n) => n + 1);\n const [full, setFull] = useState(false);\n const [lit, setLit] = useState<string | null>(null);\n const svg = useRef<SVGSVGElement>(null);\n const schema = schemaOf();\n const layout = schemaLayout(schema, focused, showEverything, (table, preview) => nodeHeight(table, expanded.has(table.id), preview));\n if (!layout) return <p className=\"note\">{say('thisDatabaseHasNoTables')}</p>;\n const { tables, foreignKeys, pos, width, height, levels, preview, trimmed } = layout;\n const allTables = schema.tables;\n const visible = new Set(tables.map((t) => t.id));\n /* Hovering a table dims everything it is not connected to: on a hundred tables, the difference between a picture and an answer. */\n const connected = new Set<string>();\n if (lit) {\n connected.add(lit);\n for (const fk of schema.foreignKeys) {\n if (fk.from.table === lit) connected.add(fk.to.table);\n if (fk.to.table === lit) connected.add(fk.from.table);\n }\n }\n const orphans = tables.filter((t) => !foreignKeys.some((fk) => fk.from.table === t.id || fk.to.table === t.id));\n const edgeOf = (fk: Fk, i: number) => {\n const from = pos.get(fk.from.table);\n const to = pos.get(fk.to.table);\n if (!from || !to) return null;\n const dim = Boolean(lit) && fk.from.table !== lit && fk.to.table !== lit;\n if (fk.from.table === fk.to.table) {\n const x = from.x + NODE_W / 2;\n const y = from.top;\n return (\n <path\n key={i}\n className={`edge${dim ? ' dim' : ''}`}\n markerEnd=\"url(#arrow-s)\"\n d={`M${x - 18},${y} C${x - 24},${y - 22} ${x + 24},${y - 22} ${x + 18},${y}`}\n data-from={fk.from.table}\n data-to={fk.to.table}\n />\n );\n }\n /* Leaving from whichever side faces the target keeps lines from doubling back across their own node. */\n const leftToRight = to.x >= from.x;\n const x1 = leftToRight ? from.x + NODE_W : from.x;\n const x2 = leftToRight ? to.x : to.x + NODE_W;\n const mid = (x1 + x2) / 2;\n return (\n <path\n key={i}\n className={`edge${dim ? ' dim' : ''}`}\n markerEnd=\"url(#arrow-s)\"\n d={`M${x1},${from.y} C${mid},${from.y} ${mid},${to.y} ${x2},${to.y}`}\n data-from={fk.from.table}\n data-to={fk.to.table}\n />\n );\n };\n const drawing = (\n <>\n <Arrow id=\"arrow-s\" size={6} />\n <g className=\"schema-edges\">{foreignKeys.map(edgeOf)}</g>\n {tables.map((table) => {\n const p = pos.get(table.id)!;\n const className = lit ? (table.id === lit ? ' lit' : connected.has(table.id) ? '' : ' dim') : '';\n return (\n <Node\n key={table.id}\n tableId={table.id}\n x={p.x}\n y={p.top}\n role={table.isView ? 'view' : 'out'}\n preview={preview}\n repaint={repaint}\n extra={{ className, onMouseEnter: () => setLit(table.id), onMouseLeave: () => setLit(null) }}\n />\n );\n })}\n </>\n );\n return (\n <>\n <div className=\"diagram-head\">\n <h2 className=\"diagram-title\">{schema.label}</h2>\n <div className=\"diagram-focus\">\n {[...focused].map((id) => {\n const table = allTables.find((t) => t.id === id);\n return (\n <button\n key={id}\n type=\"button\"\n className=\"diagram-chip\"\n title={say('stopLimiting', { name: table?.name ?? id })}\n onClick={() => {\n focused.delete(id);\n repaint();\n }}\n >\n <span>{table?.name ?? id}</span>\n <span className=\"chip-x\" aria-hidden=\"true\">\n ×\n </span>\n </button>\n );\n })}\n {focused.size ? (\n <button\n type=\"button\"\n className=\"ghost diagram-clear\"\n onClick={() => {\n focused.clear();\n repaint();\n }}\n >\n {say('showAll')}\n </button>\n ) : null}\n <Picker\n items={allTables\n .filter((t) => !focused.has(t.id))\n .map((t) => ({ value: t.id, label: t.name, detail: say('cols', { count: t.columns.length }) }))}\n onPick={(id) => {\n if (allTables.some((t) => t.id === id)) {\n focused.add(id);\n repaint();\n }\n }}\n ariaLabel={say('limitTheDiagramToThese')}\n placeholder={focused.size ? say('addAnotherTable') : say('showOnly')}\n />\n </div>\n {/* `visible`, not `focused`: the diagram draws one hop past the chips, and the export should hold what is on screen. */}\n <SchemaExportControl\n schema={schema}\n only={focused.size || trimmed ? visible : undefined}\n picture={() => ({ svg: svg.current ?? undefined, size: { width, height } })}\n />\n </div>\n <PanZoom\n size={{ width, height }}\n svgRef={svg}\n label={say('entityDiagram', { label: schema.label ?? '' })}\n svgClassName={lit ? 'has-focus' : undefined}\n expand={expandable ? () => setFull(true) : undefined}\n >\n {drawing}\n </PanZoom>\n <p className=\"diagram-legend\">\n <span>\n {trimmed\n ? say('mostConnectedOf', {\n shown: formatNumber(tables.length),\n tables: say('tables', { count: allTables.length }),\n keys: say('foreignKeys', { count: foreignKeys.length }),\n })\n : focused.size\n ? say('focusedOf', {\n shown: formatNumber(tables.length),\n tables: say('tables', { count: allTables.length }),\n keys: say('foreignKeys', { count: foreignKeys.length }),\n })\n : `${say('tables', { count: tables.length })} · ${say('foreignKeys', { count: foreignKeys.length })} · `}\n </span>\n <span>{say('levelsDeepLeftToRight', { count: levels })}</span>\n {trimmed ? (\n <button\n type=\"button\"\n className=\"ghost diagram-scope\"\n onClick={() => {\n showEverything = true;\n repaint();\n }}\n >\n {say('showAllTables', { count: allTables.length })}\n </button>\n ) : null}\n {!trimmed && !focused.size && showEverything && allTables.length > DENSE_SCHEMA ? (\n <button\n type=\"button\"\n className=\"ghost diagram-scope\"\n onClick={() => {\n showEverything = false;\n repaint();\n }}\n >\n {say('showTheHubs', { count: Math.min(HUB_TABLES, allTables.length) })}\n </button>\n ) : null}\n </p>\n {orphans.length ? (\n <p className=\"diagram-legend\">{`${say('tablesWithNoForeignKeys', {\n count: orphans.length,\n names: orphans\n .slice(0, 6)\n .map((t) => t.name)\n .join(', '),\n })}${orphans.length > 6 ? '…' : ''}`}</p>\n ) : null}\n {full ? (\n <Fullscreen onClose={() => setFull(false)}>\n <div className=\"diagram diagram-schema\">\n <SchemaDiagram expandable={false} />\n </div>\n </Fullscreen>\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { ht as Icon, it as useQuery } from "./shared-poc11xxo.js";
2
2
  import { F as primaryKey, Jt as formatNumber, gt as defineMessages } from "./shared-DJZjSi3J.js";
3
- import { L as state, _ as openRecord, i as api, p as keyOf, st as ownedBy } from "./shared-DPAVoWY0.js";
3
+ import { L as state, _ as openRecord, i as api, p as keyOf, st as ownedBy } from "./shared-BoLbc2WD.js";
4
4
  import { t as listPresentationColumns, u as splitQuery } from "./shared-DOvMIC4W.js";
5
- import { f as Value, r as bulkKey } from "./shared-C4UrE8Fb.js";
6
- import { n as namedCell } from "./shared-Bmw43Hwf.js";
5
+ import { f as Value, r as bulkKey } from "./shared-Chp88all.js";
6
+ import { n as namedCell } from "./shared-DyKsJTZs.js";
7
7
  import { useMemo, useRef, useState } from "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  // packages/mistri/src/client/copy/lists/components/TreeList.ts
@@ -242,4 +242,4 @@ function TreeList({ table, spec, entry, interactive = true, label, referenceLabe
242
242
  }
243
243
  export { TreeList, forestOf };
244
244
 
245
- //# sourceMappingURL=shared-D5GrOEa2.js.map
245
+ //# sourceMappingURL=shared-Cbf-o4Dt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-D5GrOEa2.js","names":["sayCopy"],"sources":["../../src/client/copy/lists/components/TreeList.ts","../../src/client/components/TreeList.tsx"],"sourcesContent":["/** What TreeList says, in the lists and grid room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n untitled: 'Untitled',\n nothingHere: 'Nothing to show here.',\n firstOnly: 'Showing the first {count}; narrow the list to see the rest of the tree.',\n});\n","/**\n * Records as the tree their parent column makes: each record with no parent\n * (or whose parent the list's question leaves out) a root, its children\n * folded under it. The list's own question is asked once for the whole tree\n * — a page of a tree would cut branches — up to LIMIT records, and the tree\n * says when there are more.\n *\n * The keyboard's tree pattern (APG): one Tab stop, the item last visited;\n * Up and Down move through what is open, Right opens a branch or steps into\n * it, Left folds it or steps out to the parent, Home and End go to the ends,\n * and Enter opens the record. A click on the caret folds; on the name, opens.\n * Nothing slides open (motion rule 8): a branch is there or it is not.\n */\nimport './TreeList.css';\nimport { useMemo, useRef, useState, type KeyboardEvent } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { api, keyOf, openRecord, state } from '@mistriwork/kit/client/core.js';\nimport { ownedBy } from '@mistriwork/kit/client/requestIdentity.js';\nimport { splitQuery } from '@mistriwork/kit/client/clauses.js';\nimport { primaryKey, type TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport type { AppTreeList } from '@mistriwork/engine/shared/listPresentations.js';\nimport { listPresentationColumns } from '@mistriwork/engine/shared/appListColumns.js';\nimport { bulkKey } from '@mistriwork/kit/client/bulkActions.js';\nimport { formatNumber } from '@mistriwork/kit/client/locale.js';\nimport { namedCell } from '@mistriwork/kit/client/components/listColumn.js';\nimport { Value } from '@mistriwork/kit/client/components/Value.js';\nimport { Icon } from '@mistriwork/kit/client/components/Icon.js';\nimport type { ModalRecord } from './RecordModal.js';\nimport type { TableEntry } from '@mistriwork/kit/client/components/TableView.js';\nimport { say as sayCopy } from '../copy/lists/components/TreeList.js';\n\n/** A tree is read whole; past this it says so rather than silently dropping branches. */\nconst LIMIT = 2000;\n\ninterface TreeNode {\n id: string;\n key: Record<string, unknown>;\n title: string;\n row: Record<string, unknown>;\n children: TreeNode[];\n depth: number;\n}\n\n/**\n * The rows as a forest: a row hangs under the row its parent column names,\n * and is a root where that is empty, missing from the answer, or would close\n * a loop (a record that is its own ancestor is a data error, drawn rather\n * than hidden). Siblings read in title order.\n */\nexport function forestOf(\n rows: Array<Record<string, unknown>>,\n idOf: (row: Record<string, unknown>) => string | null,\n parentOf: (row: Record<string, unknown>) => string | null,\n titleOf: (row: Record<string, unknown>) => string,\n keyFor: (row: Record<string, unknown>) => Record<string, unknown> | null,\n): TreeNode[] {\n const nodes = new Map<string, TreeNode>();\n const parents = new Map<string, string | null>();\n for (const row of rows) {\n const id = idOf(row);\n const key = keyFor(row);\n if (id === null || !key || nodes.has(id)) continue;\n nodes.set(id, { id, key, title: titleOf(row), row, children: [], depth: 0 });\n parents.set(id, parentOf(row));\n }\n const loops = (id: string) => {\n const seen = new Set([id]);\n for (let at = parents.get(id); at != null && nodes.has(at); at = parents.get(at)) {\n if (seen.has(at)) return true;\n seen.add(at);\n }\n return false;\n };\n const roots: TreeNode[] = [];\n for (const node of nodes.values()) {\n const parent = parents.get(node.id);\n const above = parent == null ? undefined : nodes.get(parent);\n if (above && above !== node && !loops(node.id)) above.children.push(node);\n else roots.push(node);\n }\n const order = (list: TreeNode[], depth: number) => {\n list.sort((a, b) => a.title.localeCompare(b.title, undefined, { numeric: true }));\n for (const node of list) {\n node.depth = depth;\n order(node.children, depth + 1);\n }\n };\n order(roots, 1);\n return roots;\n}\n\n/** What is drawn, in order: every root, and every child of an open node. */\nfunction shownOf(roots: TreeNode[], open: ReadonlySet<string>): TreeNode[] {\n const out: TreeNode[] = [];\n const walk = (list: TreeNode[]) => {\n for (const node of list) {\n out.push(node);\n if (open.has(node.id)) walk(node.children);\n }\n };\n walk(roots);\n return out;\n}\n\ninterface TreeListProps {\n table: TableMeta;\n spec: AppTreeList;\n entry: TableEntry;\n interactive?: boolean;\n label?: string;\n referenceLabels?: Record<string, string>;\n}\n\nexport function TreeList({ table, spec, entry, interactive = true, label, referenceLabels }: TreeListProps) {\n const connection = state.activeConnection ?? null;\n const key = primaryKey(table);\n const columns = [...new Set([...key, ...listPresentationColumns(spec), ...Object.values(referenceLabels ?? {})])];\n const filter = splitQuery(entry.query).filter;\n const text = `${table.id}${filter ? ` ${filter}` : ''} show ${columns.join(', ')}`;\n const answer = useQuery({\n queryKey: ['run', connection ?? '', 'tree', text],\n queryFn: async () => {\n const data = (await api('/api/run', {\n q: text,\n limit: LIMIT,\n offset: 0,\n count: 'none',\n ...(connection ? ownedBy(connection) : {}),\n })) as {\n rows?: Array<Record<string, unknown>>;\n errors?: Array<{ message: string }>;\n more?: boolean;\n };\n if (data.errors?.length) throw new Error(data.errors[0].message);\n return { rows: data.rows ?? [], more: Boolean(data.more) };\n },\n });\n /* The parent column names the record above by its key: a tree is over a single-column key. */\n const single = key.length === 1 ? key[0] : undefined;\n const roots = useMemo(\n () =>\n forestOf(\n answer.data?.rows ?? [],\n (row) => (single === undefined || row[single] == null ? null : String(row[single])),\n (row) => (row[spec.parent] == null || row[spec.parent] === '' ? null : String(row[spec.parent])),\n (row) => String(namedCell(table, spec.primary, row, referenceLabels).value ?? sayCopy('untitled')),\n (row) => keyOf(table, row) as Record<string, unknown> | null,\n ),\n [answer.data, single, spec, table, referenceLabels],\n );\n /* Every root opens on its first level, so the tree reads as more than a list of tops. */\n const [open, setOpen] = useState<ReadonlySet<string> | null>(null);\n const opened = open ?? new Set(roots.filter((root) => root.children.length).map((root) => root.id));\n const shown = shownOf(roots, opened);\n const [active, setActive] = useState<string>();\n const current = shown.find((node) => node.id === active) ?? shown[0];\n const items = useRef(new Map<string, HTMLLIElement>());\n const parentOf = useMemo(() => {\n const map = new Map<string, TreeNode>();\n const walk = (list: TreeNode[]) => list.forEach((node) => node.children.forEach((child) => (map.set(child.id, node), walk([child]))));\n walk(roots);\n return map;\n }, [roots]);\n\n const toggle = (node: TreeNode, to?: boolean) => {\n const next = new Set(opened);\n if (to ?? !next.has(node.id)) next.add(node.id);\n else next.delete(node.id);\n setOpen(next);\n };\n const go = (node: TreeNode | undefined) => {\n if (!node) return;\n setActive(node.id);\n items.current.get(node.id)?.focus();\n };\n const records: ModalRecord[] = shown.map((node) => ({ table: table.id, key: node.key, label: node.title }));\n const openIt = (node: TreeNode) => {\n if (interactive) void openRecord(table.id, node.key, node.title, 'push', { records });\n };\n const onKey = (event: KeyboardEvent<HTMLUListElement>) => {\n if (!current) return;\n const at = shown.indexOf(current);\n const moves: Record<string, () => void> = {\n ArrowDown: () => go(shown[at + 1]),\n ArrowUp: () => go(shown[at - 1]),\n Home: () => go(shown[0]),\n End: () => go(shown[shown.length - 1]),\n ArrowRight: () => (current.children.length && !opened.has(current.id) ? toggle(current, true) : go(current.children[0])),\n ArrowLeft: () => (opened.has(current.id) ? toggle(current, false) : go(parentOf.get(current.id))),\n Enter: () => openIt(current),\n };\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n move();\n };\n\n if (answer.isError) return <p className=\"tree-note\">{(answer.error as Error).message}</p>;\n if (!answer.data) return <div className=\"tree-list\" aria-busy=\"true\" />;\n if (!roots.length) return <p className=\"tree-note\">{sayCopy('nothingHere')}</p>;\n return (\n <div className=\"tree-list\">\n <ul role=\"tree\" aria-label={label ?? table.name} className=\"tree-items\" onKeyDown={onKey}>\n {shown.map((node) => {\n const branch = node.children.length > 0;\n const line = spec.lines?.[0];\n const said = line ? namedCell(table, line, node.row, referenceLabels) : undefined;\n return (\n <li\n key={node.id}\n ref={(element) => {\n if (element) items.current.set(node.id, element);\n else items.current.delete(node.id);\n }}\n role=\"treeitem\"\n aria-level={node.depth}\n aria-expanded={branch ? opened.has(node.id) : undefined}\n aria-selected={node === current}\n tabIndex={node === current ? 0 : -1}\n className=\"tree-item\"\n style={{ paddingInlineStart: `${(node.depth - 1) * 20 + 4}px` }}\n onFocus={() => setActive(node.id)}\n data-key={bulkKey(table, node.key)}\n >\n <span\n className={`tree-caret${branch ? '' : ' is-leaf'}`}\n aria-hidden=\"true\"\n onClick={(event) => {\n event.stopPropagation();\n if (branch) toggle(node);\n }}\n >\n {branch && <Icon name={opened.has(node.id) ? 'caret-down' : 'caret-right'} size={12} />}\n </span>\n <span className=\"tree-title\" onClick={() => openIt(node)}>\n {node.title}\n </span>\n {said && said.value !== null && said.value !== undefined && said.value !== '' && (\n <span className=\"tree-line\">\n <Value col={said.column} value={said.value} tableId={table.id} compact />\n </span>\n )}\n {branch && <span className=\"tree-count\">{formatNumber(node.children.length)}</span>}\n </li>\n );\n })}\n </ul>\n {answer.data.more && <p className=\"tree-note\">{sayCopy('firstOnly', { count: formatNumber(LIMIT) })}</p>}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shared-Cbf-o4Dt.js","names":["sayCopy"],"sources":["../../src/client/copy/lists/components/TreeList.ts","../../src/client/components/TreeList.tsx"],"sourcesContent":["/** What TreeList says, in the lists and grid room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n untitled: 'Untitled',\n nothingHere: 'Nothing to show here.',\n firstOnly: 'Showing the first {count}; narrow the list to see the rest of the tree.',\n});\n","/**\n * Records as the tree their parent column makes: each record with no parent\n * (or whose parent the list's question leaves out) a root, its children\n * folded under it. The list's own question is asked once for the whole tree\n * — a page of a tree would cut branches — up to LIMIT records, and the tree\n * says when there are more.\n *\n * The keyboard's tree pattern (APG): one Tab stop, the item last visited;\n * Up and Down move through what is open, Right opens a branch or steps into\n * it, Left folds it or steps out to the parent, Home and End go to the ends,\n * and Enter opens the record. A click on the caret folds; on the name, opens.\n * Nothing slides open (motion rule 8): a branch is there or it is not.\n */\nimport './TreeList.css';\nimport { useMemo, useRef, useState, type KeyboardEvent } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { api, keyOf, openRecord, state } from '@mistriwork/kit/client/core.js';\nimport { ownedBy } from '@mistriwork/kit/client/requestIdentity.js';\nimport { splitQuery } from '@mistriwork/kit/client/clauses.js';\nimport { primaryKey, type TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport type { AppTreeList } from '@mistriwork/engine/shared/listPresentations.js';\nimport { listPresentationColumns } from '@mistriwork/engine/shared/appListColumns.js';\nimport { bulkKey } from '@mistriwork/kit/client/bulkActions.js';\nimport { formatNumber } from '@mistriwork/kit/client/locale.js';\nimport { namedCell } from '@mistriwork/kit/client/components/listColumn.js';\nimport { Value } from '@mistriwork/kit/client/components/Value.js';\nimport { Icon } from '@mistriwork/kit/client/components/Icon.js';\nimport type { ModalRecord } from './RecordModal.js';\nimport type { TableEntry } from '@mistriwork/kit/client/components/TableView.js';\nimport { say as sayCopy } from '../copy/lists/components/TreeList.js';\n\n/** A tree is read whole; past this it says so rather than silently dropping branches. */\nconst LIMIT = 2000;\n\ninterface TreeNode {\n id: string;\n key: Record<string, unknown>;\n title: string;\n row: Record<string, unknown>;\n children: TreeNode[];\n depth: number;\n}\n\n/**\n * The rows as a forest: a row hangs under the row its parent column names,\n * and is a root where that is empty, missing from the answer, or would close\n * a loop (a record that is its own ancestor is a data error, drawn rather\n * than hidden). Siblings read in title order.\n */\nexport function forestOf(\n rows: Array<Record<string, unknown>>,\n idOf: (row: Record<string, unknown>) => string | null,\n parentOf: (row: Record<string, unknown>) => string | null,\n titleOf: (row: Record<string, unknown>) => string,\n keyFor: (row: Record<string, unknown>) => Record<string, unknown> | null,\n): TreeNode[] {\n const nodes = new Map<string, TreeNode>();\n const parents = new Map<string, string | null>();\n for (const row of rows) {\n const id = idOf(row);\n const key = keyFor(row);\n if (id === null || !key || nodes.has(id)) continue;\n nodes.set(id, { id, key, title: titleOf(row), row, children: [], depth: 0 });\n parents.set(id, parentOf(row));\n }\n const loops = (id: string) => {\n const seen = new Set([id]);\n for (let at = parents.get(id); at != null && nodes.has(at); at = parents.get(at)) {\n if (seen.has(at)) return true;\n seen.add(at);\n }\n return false;\n };\n const roots: TreeNode[] = [];\n for (const node of nodes.values()) {\n const parent = parents.get(node.id);\n const above = parent == null ? undefined : nodes.get(parent);\n if (above && above !== node && !loops(node.id)) above.children.push(node);\n else roots.push(node);\n }\n const order = (list: TreeNode[], depth: number) => {\n list.sort((a, b) => a.title.localeCompare(b.title, undefined, { numeric: true }));\n for (const node of list) {\n node.depth = depth;\n order(node.children, depth + 1);\n }\n };\n order(roots, 1);\n return roots;\n}\n\n/** What is drawn, in order: every root, and every child of an open node. */\nfunction shownOf(roots: TreeNode[], open: ReadonlySet<string>): TreeNode[] {\n const out: TreeNode[] = [];\n const walk = (list: TreeNode[]) => {\n for (const node of list) {\n out.push(node);\n if (open.has(node.id)) walk(node.children);\n }\n };\n walk(roots);\n return out;\n}\n\ninterface TreeListProps {\n table: TableMeta;\n spec: AppTreeList;\n entry: TableEntry;\n interactive?: boolean;\n label?: string;\n referenceLabels?: Record<string, string>;\n}\n\nexport function TreeList({ table, spec, entry, interactive = true, label, referenceLabels }: TreeListProps) {\n const connection = state.activeConnection ?? null;\n const key = primaryKey(table);\n const columns = [...new Set([...key, ...listPresentationColumns(spec), ...Object.values(referenceLabels ?? {})])];\n const filter = splitQuery(entry.query).filter;\n const text = `${table.id}${filter ? ` ${filter}` : ''} show ${columns.join(', ')}`;\n const answer = useQuery({\n queryKey: ['run', connection ?? '', 'tree', text],\n queryFn: async () => {\n const data = (await api('/api/run', {\n q: text,\n limit: LIMIT,\n offset: 0,\n count: 'none',\n ...(connection ? ownedBy(connection) : {}),\n })) as {\n rows?: Array<Record<string, unknown>>;\n errors?: Array<{ message: string }>;\n more?: boolean;\n };\n if (data.errors?.length) throw new Error(data.errors[0].message);\n return { rows: data.rows ?? [], more: Boolean(data.more) };\n },\n });\n /* The parent column names the record above by its key: a tree is over a single-column key. */\n const single = key.length === 1 ? key[0] : undefined;\n const roots = useMemo(\n () =>\n forestOf(\n answer.data?.rows ?? [],\n (row) => (single === undefined || row[single] == null ? null : String(row[single])),\n (row) => (row[spec.parent] == null || row[spec.parent] === '' ? null : String(row[spec.parent])),\n (row) => String(namedCell(table, spec.primary, row, referenceLabels).value ?? sayCopy('untitled')),\n (row) => keyOf(table, row) as Record<string, unknown> | null,\n ),\n [answer.data, single, spec, table, referenceLabels],\n );\n /* Every root opens on its first level, so the tree reads as more than a list of tops. */\n const [open, setOpen] = useState<ReadonlySet<string> | null>(null);\n const opened = open ?? new Set(roots.filter((root) => root.children.length).map((root) => root.id));\n const shown = shownOf(roots, opened);\n const [active, setActive] = useState<string>();\n const current = shown.find((node) => node.id === active) ?? shown[0];\n const items = useRef(new Map<string, HTMLLIElement>());\n const parentOf = useMemo(() => {\n const map = new Map<string, TreeNode>();\n const walk = (list: TreeNode[]) => list.forEach((node) => node.children.forEach((child) => (map.set(child.id, node), walk([child]))));\n walk(roots);\n return map;\n }, [roots]);\n\n const toggle = (node: TreeNode, to?: boolean) => {\n const next = new Set(opened);\n if (to ?? !next.has(node.id)) next.add(node.id);\n else next.delete(node.id);\n setOpen(next);\n };\n const go = (node: TreeNode | undefined) => {\n if (!node) return;\n setActive(node.id);\n items.current.get(node.id)?.focus();\n };\n const records: ModalRecord[] = shown.map((node) => ({ table: table.id, key: node.key, label: node.title }));\n const openIt = (node: TreeNode) => {\n if (interactive) void openRecord(table.id, node.key, node.title, 'push', { records });\n };\n const onKey = (event: KeyboardEvent<HTMLUListElement>) => {\n if (!current) return;\n const at = shown.indexOf(current);\n const moves: Record<string, () => void> = {\n ArrowDown: () => go(shown[at + 1]),\n ArrowUp: () => go(shown[at - 1]),\n Home: () => go(shown[0]),\n End: () => go(shown[shown.length - 1]),\n ArrowRight: () => (current.children.length && !opened.has(current.id) ? toggle(current, true) : go(current.children[0])),\n ArrowLeft: () => (opened.has(current.id) ? toggle(current, false) : go(parentOf.get(current.id))),\n Enter: () => openIt(current),\n };\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n move();\n };\n\n if (answer.isError) return <p className=\"tree-note\">{(answer.error as Error).message}</p>;\n if (!answer.data) return <div className=\"tree-list\" aria-busy=\"true\" />;\n if (!roots.length) return <p className=\"tree-note\">{sayCopy('nothingHere')}</p>;\n return (\n <div className=\"tree-list\">\n <ul role=\"tree\" aria-label={label ?? table.name} className=\"tree-items\" onKeyDown={onKey}>\n {shown.map((node) => {\n const branch = node.children.length > 0;\n const line = spec.lines?.[0];\n const said = line ? namedCell(table, line, node.row, referenceLabels) : undefined;\n return (\n <li\n key={node.id}\n ref={(element) => {\n if (element) items.current.set(node.id, element);\n else items.current.delete(node.id);\n }}\n role=\"treeitem\"\n aria-level={node.depth}\n aria-expanded={branch ? opened.has(node.id) : undefined}\n aria-selected={node === current}\n tabIndex={node === current ? 0 : -1}\n className=\"tree-item\"\n style={{ paddingInlineStart: `${(node.depth - 1) * 20 + 4}px` }}\n onFocus={() => setActive(node.id)}\n data-key={bulkKey(table, node.key)}\n >\n <span\n className={`tree-caret${branch ? '' : ' is-leaf'}`}\n aria-hidden=\"true\"\n onClick={(event) => {\n event.stopPropagation();\n if (branch) toggle(node);\n }}\n >\n {branch && <Icon name={opened.has(node.id) ? 'caret-down' : 'caret-right'} size={12} />}\n </span>\n <span className=\"tree-title\" onClick={() => openIt(node)}>\n {node.title}\n </span>\n {said && said.value !== null && said.value !== undefined && said.value !== '' && (\n <span className=\"tree-line\">\n <Value col={said.column} value={said.value} tableId={table.id} compact />\n </span>\n )}\n {branch && <span className=\"tree-count\">{formatNumber(node.children.length)}</span>}\n </li>\n );\n })}\n </ul>\n {answer.data.more && <p className=\"tree-note\">{sayCopy('firstOnly', { count: formatNumber(LIMIT) })}</p>}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { Ot as popupContainer, et as richTextHref, gt as defineMessages, rt as richTextPlain } from "./shared-DJZjSi3J.js";
2
- import { L as DropItem, R as DropMenu } from "./shared-CNmaAv64.js";
3
- import "./shared-DPAVoWY0.js";
2
+ import { L as DropItem, R as DropMenu } from "./shared-BHsjawAG.js";
3
+ import "./shared-BoLbc2WD.js";
4
4
  import { G as autoUpdate, Gn as viewportScale, J as offset, K as computePosition, Mn as require_with_selector, Nn as require_shim, q as flip, r as layoutViewport } from "./shared-CRr4kJXB.js";
5
5
  import { i as PopoverRoot, n as PopoverPositioner, r as PopoverPortal, t as PopoverPopup } from "./shared-QCeL-Jxu.js";
6
6
  import React, { createContext, forwardRef, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -29084,4 +29084,4 @@ function MentionList({ suggesting, onPick }) {
29084
29084
  }
29085
29085
  export { RichTextEditor, cleanPastedHtml };
29086
29086
 
29087
- //# sourceMappingURL=shared-HwiPIajr.js.map
29087
+ //# sourceMappingURL=shared-CdNmeNHh.js.map