@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":"page-Bx4o1kpQ.js","names":["say","subscribeSessionIdentity","defineMessages","state","appRequestScope","api","connectionGeneration","loadJson","shell","findTable","resourceOf","KEY","storeKey","connection","mirrors","loads","mirrorFor","savedPages","all","pages","tableId","p","say","cache","pageOwner","assertCurrent","owner","early","prefetchPages","promise","configuredPages","adopted","data","page","appPagesOnly","browserPages","recordPageId","pagesFor","built","named","first","chosen","listener","whenPagesChange","fn","forgetPages","pageById","suggested","base","mine","id","authored","found","pageSlug","mineFirst","asTable","pageToken","pageId","known","slug","clashes"],"sources":["../../../../../kit/src/client/copy/record/savedPages.ts","../../../../../kit/src/client/savedPages.js","../../../../../kit/src/client/copy/record/page.ts","../../../../../kit/src/client/page.js"],"sourcesContent":["/** What savedPages says, in the record room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n theServerDidNotConfirm: 'The server did not confirm the change within 30 seconds. It may still complete.',\n noDatabaseConnectionIsSelected: 'No database connection is selected.',\n});\n","/**\n * The pages saved for a connection, as a synchronous mirror of the server's\n * file: what the record page's page list reads (page.js) in either shell, and\n * what the Workbench's page builder (pagebuilder.js) writes. An App reads\n * none — its pages are its definition — and a public visitor has none.\n */\nimport { appRequestScope, ownedBy } from './requestIdentity.js';\nimport { api, loadJson, saveJson, state } from './core.js';\nimport { sessionIdentity, subscribeSessionIdentity } from './sessionIdentity.js';\nimport { shell } from './shellMode.js';\nimport { say } from './copy/record/savedPages.js';\n\nconst KEY = 'mistri.pages.saved';\n\n/**\n * Told when a page is saved or deleted, so the record-page cache and the menu\n * can be rebuilt. A callback rather than an import: page.js reads the saved\n * pages from here, and an import back made a cycle. page.js registers itself.\n * @type {(() => void) | null}\n */\nlet pagesChanged = null;\n/** @param {() => void} fn */\nexport function whenSavedPagesChange(fn) {\n pagesChanged = fn;\n}\n\nconst storeKey = (connection) => `${KEY}.${connection ?? ''}`;\n/** @type {Map<string, Record<string, import('@mistriwork/engine/shared/page.js').PageDef>>} */\nconst mirrors = new Map();\nconst loads = new Map();\n\n/* Another person's pages are not this one's: a change of who is signed in forgets the mirror and any read in flight. */\nsubscribeSessionIdentity(() => {\n mirrors.clear();\n loads.clear();\n});\n\nfunction mirrorFor(connection) {\n if (!mirrors.has(connection)) mirrors.set(connection, loadJson(storeKey(connection), {}));\n return mirrors.get(connection);\n}\n\nfunction updateMirror(connection, pages) {\n mirrors.set(connection, pages);\n // Disk acknowledgement is authoritative; unavailable browser storage is only a cache miss.\n saveJson(storeKey(connection), pages);\n}\n\nasync function writePage(id, page, connection) {\n let timer;\n try {\n await Promise.race([\n api('/api/pages/save', { id, page, ...ownedBy(connection) }),\n new Promise((_resolve, reject) => {\n timer = setTimeout(() => reject(new Error(say('theServerDidNotConfirm'))), 30_000);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** Pages saved for the connection in hand, read from the local mirror. */\nexport function savedPages(tableId) {\n const all = mirrorFor(state.activeConnection);\n const pages = Object.values(all);\n return tableId ? pages.filter((p) => p.base === tableId) : pages;\n}\n\n/**\n * Pull this connection's saved pages from the server into the mirror.\n *\n * The same arrangement record layouts have, for the same reason: the mirror\n * is what makes reads synchronous, the file is what makes the work outlive\n * this browser. A failure is silent — the mirror already holds whatever this\n * browser saved.\n */\nexport async function loadSavedPages() {\n // A public visitor has none to read (the shell's publicVisitor), and saved pages are\n // the database browser's: an App's pages are its definition.\n if (shell().publicVisitor() || appRequestScope() !== false) return;\n const owner = sessionIdentity();\n const connection = state.activeConnection;\n const before = mirrorFor(connection);\n const load = Symbol();\n loads.set(connection, load);\n try {\n const { pages } = await api('/api/pages/saved');\n // A late read must not undo an acknowledged write or a newer read.\n if (\n owner === sessionIdentity() &&\n pages &&\n typeof pages === 'object' &&\n !Array.isArray(pages) &&\n mirrors.get(connection) === before &&\n loads.get(connection) === load\n )\n updateMirror(connection, pages);\n } catch {\n /* Server-side pages unavailable; the mirror stands. */\n }\n}\n\nexport async function savePage(page, connection = state.activeConnection) {\n const owner = sessionIdentity();\n if (!connection) throw new Error(say('noDatabaseConnectionIsSelected'));\n const saved = structuredClone(page);\n await writePage(saved.id, saved, connection);\n if (owner !== sessionIdentity()) return;\n updateMirror(connection, { ...mirrorFor(connection), [saved.id]: saved });\n /* Also tells the menu to rebuild: it was registered once at boot, so a page\n built afterwards was reachable only from the link you were already on,\n and a deleted one stayed listed as a command that opened nothing. */\n if (state.activeConnection === connection) pagesChanged?.();\n}\n\nexport async function deletePage(id, connection = state.activeConnection) {\n const owner = sessionIdentity();\n if (!connection) throw new Error(say('noDatabaseConnectionIsSelected'));\n await writePage(id, null, connection);\n if (owner !== sessionIdentity()) return;\n const all = { ...mirrorFor(connection) };\n delete all[id];\n updateMirror(connection, all);\n if (state.activeConnection === connection) pagesChanged?.();\n}\n","/** What page says, in the record page room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n theConnectionOrPage: 'The connection or page definitions changed while loading.',\n thereIsNoPage: 'There is no page called \"{id}\".',\n});\n","/**\n * Pages, as the vanilla client reaches them.\n *\n * The page is a component (components/Page.tsx) and the room around it —\n * which definition a link names, the root, the probe, the plan, the crumb —\n * is components/PageRoom.tsx. What stays here is the registry of pages every\n * other module asks: the config's, the suggested one every table has, and\n * the ones this browser built; and how a page is spelled in a link.\n */\nimport { api, findTable, state } from './core.js';\nimport { savedPages, whenSavedPagesChange } from './savedPages.js';\nimport { shell } from './shellMode.js';\nimport { appRequestScope } from './requestIdentity.js';\nimport { resourceOf } from './components/appRooms.js';\nimport { connectionGeneration } from './connectionTransition.js';\nimport { say } from './copy/record/page.js';\n\nexport { rootMatches } from './components/pageModel.js';\n\n/* ---------- lookup ---------- */\n\n/** @typedef {{connection: string | null | undefined, schema: import('@mistriwork/engine/shared/schema.js').DatabaseSchema | null, pages?: import('@mistriwork/engine/shared/page.js').PageDef[], pending?: Promise<import('@mistriwork/engine/shared/page.js').PageDef[]>}} PageCache */\n/** @type {PageCache | undefined} */\nlet cache;\n\n// Cache identity is also the load generation: invalidation retires every reader of it.\nfunction pageOwner() {\n if (!cache || cache.connection !== state.activeConnection || cache.schema !== state.schema) {\n cache = { connection: state.activeConnection, schema: state.schema };\n }\n return cache;\n}\n\n/** @param {PageCache} owner */\nfunction assertCurrent(owner) {\n if (cache !== owner || owner.connection !== state.activeConnection || owner.schema !== state.schema) {\n throw new Error(say('theConnectionOrPage'));\n }\n}\n\n/* The configured pages asked for at start beside the schema and the App,\n not after them: adopted by the first cache of the same connection in the\n same connection generation, and dropped with the cache otherwise. The\n answer is the server's for this connection either way; asking it a round\n trip earlier changes only when it arrives. */\n/** @type {{ connection: string | null | undefined, generation: number, promise: Promise<{ pages?: import('@mistriwork/engine/shared/page.js').PageDef[] }> } | undefined} */\nlet early;\nexport function prefetchPages() {\n const promise = api('/api/pages');\n promise.catch(() => {});\n early = { connection: state.activeConnection, generation: connectionGeneration(), promise };\n}\n\n/** @param {PageCache} owner */\nasync function configuredPages(owner) {\n assertCurrent(owner);\n if (owner.pages) return owner.pages;\n if (!owner.pending) {\n const adopted =\n early && early.connection === owner.connection && early.generation === connectionGeneration() ? early.promise : undefined;\n early = undefined;\n owner.pending = (adopted ?? api('/api/pages'))\n .then((data) => {\n assertCurrent(owner);\n /* A document is a page put on paper, reached from its record as a verb (documents.ts): never a\n page a record opens through, nor one offered beside the record's own. */\n return (owner.pages = (data.pages ?? []).filter((page) => page.document === undefined));\n })\n .finally(() => {\n owner.pending = undefined;\n });\n }\n return owner.pending;\n}\n\n// Saved layouts belong to the standalone browser, including while an App's\n// payload is loading. Never even read an App's stale/malformed local mirror.\nconst appPagesOnly = () => Boolean(shell().app()) || appRequestScope() !== false;\nconst browserPages = () => (appPagesOnly() ? [] : savedPages());\n\n/* App records use their authored page, or a suggestion only when none exists.\n The standalone browser retains its own saved-page precedence. The walk asks\n it through the shell, which names it at boot (app.js, `resolvePage`). */\n/** @param {string} tableId */\nexport async function recordPageId(tableId) {\n const pages = await pagesFor(tableId);\n const built = new Set(browserPages().map((p) => p.id));\n const named = resourceOf(shell().app(), tableId)?.page;\n const [first] = pages;\n const chosen = first && built.has(first.id) ? first : (named && pages.find((p) => p.id === named)) || first;\n if (appPagesOnly() && chosen?.error) throw new Error(chosen.error);\n return chosen && !chosen.error ? chosen.id : `suggested:${tableId}`;\n}\n\n/** Every page for this connection; standalone Workbench includes its saved pages first. */\nexport async function pagesFor(tableId) {\n const owner = pageOwner();\n const pages = await configuredPages(owner);\n assertCurrent(owner);\n const all = [...browserPages(), ...pages];\n return tableId ? all.filter((p) => p.base === tableId) : all;\n}\n\n/**\n * Told when the set of pages changes, so the menu can be rebuilt. A\n * callback rather than an import: the builder announces, and whoever cares\n * listens — an import the other way made a cycle.\n */\nlet listener = null;\n\nexport function whenPagesChange(fn) {\n listener = fn;\n}\n\nexport function forgetPages() {\n cache = undefined;\n early = undefined;\n listener?.();\n}\nwhenSavedPagesChange(forgetPages);\n\nexport async function pageById(id, tableId) {\n const owner = pageOwner();\n const suggested = async (base) => {\n assertCurrent(owner);\n const data = await api(`/api/pages/suggested?table=${encodeURIComponent(base)}`);\n assertCurrent(owner);\n return data.page;\n };\n const mine = browserPages().find((p) => p.id === id);\n if (mine) return mine;\n if (id?.startsWith('suggested:')) {\n const base = id.slice('suggested:'.length);\n if (appPagesOnly()) {\n const authored = await recordPageId(base);\n assertCurrent(owner);\n if (authored !== id) return pageById(authored, base);\n }\n return suggested(base);\n }\n const pages = await pagesFor();\n assertCurrent(owner);\n const found = pages.find((p) => p.id === id);\n if (found) return found;\n\n /* A link may name the page rather than identify it — `@customer-overview`\n rather than `@saved:customer:1787509869158`. Ids are tried first. */\n const named = pages.filter((p) => pageSlug(p) === id);\n const mineFirst = named.find((p) => !tableId || p.base === tableId) ?? named[0];\n if (mineFirst) return mineFirst;\n\n /* Legacy bare table links use the App's page, or the browser's suggestion. */\n const asTable = findTable(id);\n if (asTable) {\n if (appPagesOnly()) {\n const authored = await recordPageId(asTable.id);\n assertCurrent(owner);\n return pageById(authored, asTable.id);\n }\n return suggested(asTable.id);\n }\n if (tableId) {\n if (appPagesOnly()) throw new Error(say('thereIsNoPage', { id }));\n return suggested(tableId);\n }\n throw new Error(say('thereIsNoPage', { id }));\n}\n\n/**\n * A page's name as it is written in a link: the readable half of an id\n * that would otherwise carry a timestamp into every pasted ticket.\n */\nfunction pageSlug(page) {\n return String(page?.name ?? '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\n/**\n * The token a page is written as in the hash: its slug where that names it\n * unambiguously, its id otherwise. Synchronous, because the address bar is\n * stamped during a render.\n */\nexport function pageToken(pageId) {\n if (!pageId) return pageId;\n if (pageId.startsWith('suggested:')) return pageId.slice('suggested:'.length);\n const known = [...browserPages(), ...(pageOwner().pages ?? [])];\n const page = known.find((p) => p.id === pageId);\n if (!page) return pageId;\n const slug = pageSlug(page);\n /* Ambiguity keeps the id: two pages called \"Overview\" would otherwise both\n answer to `@overview`. A table of the same name counts too. */\n const clashes = known.filter((p) => pageSlug(p) === slug).length > 1 || Boolean(findTable(slug));\n return slug && !clashes ? slug : pageId;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"page-Bx4o1kpQ.js","names":["say","subscribeSessionIdentity","defineMessages","state","appRequestScope","api","connectionGeneration","loadJson","shell","findTable","resourceOf","KEY","storeKey","connection","mirrors","loads","mirrorFor","savedPages","all","pages","tableId","p","say","cache","pageOwner","assertCurrent","owner","early","prefetchPages","promise","configuredPages","adopted","data","page","appPagesOnly","browserPages","recordPageId","pagesFor","built","named","first","chosen","listener","whenPagesChange","fn","forgetPages","pageById","suggested","base","mine","id","authored","found","pageSlug","mineFirst","asTable","pageToken","pageId","known","slug","clashes"],"sources":["../../../../../kit/src/client/copy/record/savedPages.ts","../../../../../kit/src/client/savedPages.js","../../../../../kit/src/client/copy/record/page.ts","../../../../../kit/src/client/page.js"],"sourcesContent":["/** What savedPages says, in the record room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n theServerDidNotConfirm: 'The server did not confirm the change within 30 seconds. It may still complete.',\n noDatabaseConnectionIsSelected: 'No database connection is selected.',\n});\n","/**\n * The pages saved for a connection, as a synchronous mirror of the server's\n * file: what the record page's page list reads (page.js) in either shell, and\n * what the Workbench's page builder (pagebuilder.js) writes. An App reads\n * none — its pages are its definition — and a public visitor has none.\n */\nimport { appRequestScope, ownedBy } from './requestIdentity.js';\nimport { api, loadJson, saveJson, state } from './core.js';\nimport { sessionIdentity, subscribeSessionIdentity } from './sessionIdentity.js';\nimport { shell } from './shellMode.js';\nimport { say } from './copy/record/savedPages.js';\n\nconst KEY = 'mistri.pages.saved';\n\n/**\n * Told when a page is saved or deleted, so the record-page cache and the menu\n * can be rebuilt. A callback rather than an import: page.js reads the saved\n * pages from here, and an import back made a cycle. page.js registers itself.\n * @type {(() => void) | null}\n */\nlet pagesChanged = null;\n/** @param {() => void} fn */\nexport function whenSavedPagesChange(fn) {\n pagesChanged = fn;\n}\n\nconst storeKey = (connection) => `${KEY}.${connection ?? ''}`;\n/** @type {Map<string, Record<string, import('@mistriwork/engine/shared/page.js').PageDef>>} */\nconst mirrors = new Map();\nconst loads = new Map();\n\n/* Another person's pages are not this one's: a change of who is signed in forgets the mirror and any read in flight. */\nsubscribeSessionIdentity(() => {\n mirrors.clear();\n loads.clear();\n});\n\nfunction mirrorFor(connection) {\n if (!mirrors.has(connection)) mirrors.set(connection, loadJson(storeKey(connection), {}));\n return mirrors.get(connection);\n}\n\nfunction updateMirror(connection, pages) {\n mirrors.set(connection, pages);\n // Disk acknowledgement is authoritative; unavailable browser storage is only a cache miss.\n saveJson(storeKey(connection), pages);\n}\n\nasync function writePage(id, page, connection) {\n let timer;\n try {\n await Promise.race([\n api('/api/pages/save', { id, page, ...ownedBy(connection) }),\n new Promise((_resolve, reject) => {\n timer = setTimeout(() => reject(new Error(say('theServerDidNotConfirm'))), 30_000);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Pages saved for the connection in hand, read from the local mirror.\n *\n * @param {*} [tableId] only the pages based on this table\n */\nexport function savedPages(tableId) {\n const all = mirrorFor(state.activeConnection);\n const pages = Object.values(all);\n return tableId ? pages.filter((p) => p.base === tableId) : pages;\n}\n\n/**\n * Pull this connection's saved pages from the server into the mirror.\n *\n * The same arrangement record layouts have, for the same reason: the mirror\n * is what makes reads synchronous, the file is what makes the work outlive\n * this browser. A failure is silent — the mirror already holds whatever this\n * browser saved.\n */\nexport async function loadSavedPages() {\n // A public visitor has none to read (the shell's publicVisitor), and saved pages are\n // the database browser's: an App's pages are its definition.\n if (shell().publicVisitor() || appRequestScope() !== false) return;\n const owner = sessionIdentity();\n const connection = state.activeConnection;\n const before = mirrorFor(connection);\n const load = Symbol();\n loads.set(connection, load);\n try {\n const { pages } = await api('/api/pages/saved');\n // A late read must not undo an acknowledged write or a newer read.\n if (\n owner === sessionIdentity() &&\n pages &&\n typeof pages === 'object' &&\n !Array.isArray(pages) &&\n mirrors.get(connection) === before &&\n loads.get(connection) === load\n )\n updateMirror(connection, pages);\n } catch {\n /* Server-side pages unavailable; the mirror stands. */\n }\n}\n\n/**\n * @param {*} page\n * @param {string | null} [connection] the connection written to; the one in hand, unless given\n */\nexport async function savePage(page, connection = state.activeConnection) {\n const owner = sessionIdentity();\n if (!connection) throw new Error(say('noDatabaseConnectionIsSelected'));\n const saved = structuredClone(page);\n await writePage(saved.id, saved, connection);\n if (owner !== sessionIdentity()) return;\n updateMirror(connection, { ...mirrorFor(connection), [saved.id]: saved });\n /* Also tells the menu to rebuild: it was registered once at boot, so a page\n built afterwards was reachable only from the link you were already on,\n and a deleted one stayed listed as a command that opened nothing. */\n if (state.activeConnection === connection) pagesChanged?.();\n}\n\n/**\n * @param {*} id\n * @param {string | null} [connection] the connection written to; the one in hand, unless given\n */\nexport async function deletePage(id, connection = state.activeConnection) {\n const owner = sessionIdentity();\n if (!connection) throw new Error(say('noDatabaseConnectionIsSelected'));\n await writePage(id, null, connection);\n if (owner !== sessionIdentity()) return;\n const all = { ...mirrorFor(connection) };\n delete all[id];\n updateMirror(connection, all);\n if (state.activeConnection === connection) pagesChanged?.();\n}\n","/** What page says, in the record page room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n theConnectionOrPage: 'The connection or page definitions changed while loading.',\n thereIsNoPage: 'There is no page called \"{id}\".',\n});\n","/**\n * Pages, as the vanilla client reaches them.\n *\n * The page is a component (components/Page.tsx) and the room around it —\n * which definition a link names, the root, the probe, the plan, the crumb —\n * is components/PageRoom.tsx. What stays here is the registry of pages every\n * other module asks: the config's, the suggested one every table has, and\n * the ones this browser built; and how a page is spelled in a link.\n */\nimport { api, findTable, state } from './core.js';\nimport { savedPages, whenSavedPagesChange } from './savedPages.js';\nimport { shell } from './shellMode.js';\nimport { appRequestScope } from './requestIdentity.js';\nimport { resourceOf } from './components/appRooms.js';\nimport { connectionGeneration } from './connectionTransition.js';\nimport { say } from './copy/record/page.js';\n\nexport { rootMatches } from './components/pageModel.js';\n\n/* ---------- lookup ---------- */\n\n/** @typedef {{connection: string | null | undefined, schema: import('@mistriwork/engine/shared/schema.js').DatabaseSchema | null, pages?: import('@mistriwork/engine/shared/page.js').PageDef[], pending?: Promise<import('@mistriwork/engine/shared/page.js').PageDef[]>}} PageCache */\n/** @type {PageCache | undefined} */\nlet cache;\n\n// Cache identity is also the load generation: invalidation retires every reader of it.\nfunction pageOwner() {\n if (!cache || cache.connection !== state.activeConnection || cache.schema !== state.schema) {\n cache = { connection: state.activeConnection, schema: state.schema };\n }\n return cache;\n}\n\n/** @param {PageCache} owner */\nfunction assertCurrent(owner) {\n if (cache !== owner || owner.connection !== state.activeConnection || owner.schema !== state.schema) {\n throw new Error(say('theConnectionOrPage'));\n }\n}\n\n/* The configured pages asked for at start beside the schema and the App,\n not after them: adopted by the first cache of the same connection in the\n same connection generation, and dropped with the cache otherwise. The\n answer is the server's for this connection either way; asking it a round\n trip earlier changes only when it arrives. */\n/** @type {{ connection: string | null | undefined, generation: number, promise: Promise<{ pages?: import('@mistriwork/engine/shared/page.js').PageDef[] }> } | undefined} */\nlet early;\nexport function prefetchPages() {\n const promise = api('/api/pages');\n promise.catch(() => {});\n early = { connection: state.activeConnection, generation: connectionGeneration(), promise };\n}\n\n/** @param {PageCache} owner */\nasync function configuredPages(owner) {\n assertCurrent(owner);\n if (owner.pages) return owner.pages;\n if (!owner.pending) {\n const adopted =\n early && early.connection === owner.connection && early.generation === connectionGeneration() ? early.promise : undefined;\n early = undefined;\n owner.pending = (adopted ?? api('/api/pages'))\n .then((data) => {\n assertCurrent(owner);\n /* A document is a page put on paper, reached from its record as a verb (documents.ts): never a\n page a record opens through, nor one offered beside the record's own. */\n return (owner.pages = (data.pages ?? []).filter((page) => page.document === undefined));\n })\n .finally(() => {\n owner.pending = undefined;\n });\n }\n return owner.pending;\n}\n\n// Saved layouts belong to the standalone browser, including while an App's\n// payload is loading. Never even read an App's stale/malformed local mirror.\nconst appPagesOnly = () => Boolean(shell().app()) || appRequestScope() !== false;\nconst browserPages = () => (appPagesOnly() ? [] : savedPages());\n\n/* App records use their authored page, or a suggestion only when none exists.\n The standalone browser retains its own saved-page precedence. The walk asks\n it through the shell, which names it at boot (app.js, `resolvePage`). */\n/** @param {string} tableId */\nexport async function recordPageId(tableId) {\n const pages = await pagesFor(tableId);\n const built = new Set(browserPages().map((p) => p.id));\n const named = resourceOf(shell().app(), tableId)?.page;\n const [first] = pages;\n const chosen = first && built.has(first.id) ? first : (named && pages.find((p) => p.id === named)) || first;\n if (appPagesOnly() && chosen?.error) throw new Error(chosen.error);\n return chosen && !chosen.error ? chosen.id : `suggested:${tableId}`;\n}\n\n/** Every page for this connection; standalone Workbench includes its saved pages first. */\nexport async function pagesFor(tableId) {\n const owner = pageOwner();\n const pages = await configuredPages(owner);\n assertCurrent(owner);\n const all = [...browserPages(), ...pages];\n return tableId ? all.filter((p) => p.base === tableId) : all;\n}\n\n/**\n * Told when the set of pages changes, so the menu can be rebuilt. A\n * callback rather than an import: the builder announces, and whoever cares\n * listens — an import the other way made a cycle.\n */\nlet listener = null;\n\nexport function whenPagesChange(fn) {\n listener = fn;\n}\n\nexport function forgetPages() {\n cache = undefined;\n early = undefined;\n listener?.();\n}\nwhenSavedPagesChange(forgetPages);\n\nexport async function pageById(id, tableId) {\n const owner = pageOwner();\n const suggested = async (base) => {\n assertCurrent(owner);\n const data = await api(`/api/pages/suggested?table=${encodeURIComponent(base)}`);\n assertCurrent(owner);\n return data.page;\n };\n const mine = browserPages().find((p) => p.id === id);\n if (mine) return mine;\n if (id?.startsWith('suggested:')) {\n const base = id.slice('suggested:'.length);\n if (appPagesOnly()) {\n const authored = await recordPageId(base);\n assertCurrent(owner);\n if (authored !== id) return pageById(authored, base);\n }\n return suggested(base);\n }\n const pages = await pagesFor();\n assertCurrent(owner);\n const found = pages.find((p) => p.id === id);\n if (found) return found;\n\n /* A link may name the page rather than identify it — `@customer-overview`\n rather than `@saved:customer:1787509869158`. Ids are tried first. */\n const named = pages.filter((p) => pageSlug(p) === id);\n const mineFirst = named.find((p) => !tableId || p.base === tableId) ?? named[0];\n if (mineFirst) return mineFirst;\n\n /* Legacy bare table links use the App's page, or the browser's suggestion. */\n const asTable = findTable(id);\n if (asTable) {\n if (appPagesOnly()) {\n const authored = await recordPageId(asTable.id);\n assertCurrent(owner);\n return pageById(authored, asTable.id);\n }\n return suggested(asTable.id);\n }\n if (tableId) {\n if (appPagesOnly()) throw new Error(say('thereIsNoPage', { id }));\n return suggested(tableId);\n }\n throw new Error(say('thereIsNoPage', { id }));\n}\n\n/**\n * A page's name as it is written in a link: the readable half of an id\n * that would otherwise carry a timestamp into every pasted ticket.\n */\nfunction pageSlug(page) {\n return String(page?.name ?? '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\n/**\n * The token a page is written as in the hash: its slug where that names it\n * unambiguously, its id otherwise. Synchronous, because the address bar is\n * stamped during a render.\n */\nexport function pageToken(pageId) {\n if (!pageId) return pageId;\n if (pageId.startsWith('suggested:')) return pageId.slice('suggested:'.length);\n const known = [...browserPages(), ...(pageOwner().pages ?? [])];\n const page = known.find((p) => p.id === pageId);\n if (!page) return pageId;\n const slug = pageSlug(page);\n /* Ambiguity keeps the id: two pages called \"Overview\" would otherwise both\n answer to `@overview`. A table of the same name counts too. */\n const clashes = known.filter((p) => pageSlug(p) === slug).length > 1 || Boolean(findTable(slug));\n return slug && !clashes ? slug : pageId;\n}\n"],"mappings":"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"}