@cardstack/boxel-cli 0.13.0-unstable.4 → 0.13.0-unstable.6

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 (1058) hide show
  1. package/bundled-realms/pretui/components/doc-report.gts +2 -2
  2. package/bundled-realms/pretui/components/doc-report.usage.gts +3 -3
  3. package/bundled-realms/pretui/components/form-field.md +1 -1
  4. package/bundled-realms/pretui/components/icon-button.md +1 -1
  5. package/bundled-realms/pretui/components/popup.md +1 -1
  6. package/bundled-realms/pretui/components/switch.gts +13 -0
  7. package/bundled-realms/pretui/components/switch.md +5 -3
  8. package/bundled-realms/pretui/components/theme-frame.gts +49 -22
  9. package/bundled-realms/pretui/components/tooltip.gts +141 -42
  10. package/bundled-realms/pretui/components/tooltip.md +10 -12
  11. package/bundled-realms/pretui/components/tooltip.usage.gts +3 -5
  12. package/bundled-realms/pretui/docs/structure.md +1 -1
  13. package/bundled-realms/pretui/internal/overlay.gts +4 -2
  14. package/bundled-realms/pretui/pretui-css.gts +6 -2
  15. package/bundled-realms/pretui/theme-scoped-css.gts +262 -0
  16. package/bundled-test-harness/assets/account-switch-failed-test-DwAZq6Sc.js +45 -0
  17. package/bundled-test-harness/assets/adapter-C_6pnsx1.js +2 -0
  18. package/bundled-test-harness/assets/add-field-to-card-definition-tool-test-zMYtJWBv.js +112 -0
  19. package/bundled-test-harness/assets/ai-assistant-create-workspace-test-CwhAV-Ow.js +130 -0
  20. package/bundled-test-harness/assets/ai-assistant-panel-relogin-test-DNgclkGJ.js +46 -0
  21. package/bundled-test-harness/assets/ai-assistant-test-DGYFiRTb.js +2223 -0
  22. package/bundled-test-harness/assets/ai-function-generation-test-Dj6WzKkh.js +1176 -0
  23. package/bundled-test-harness/assets/ai-module-creation-test-C4zhhxaZ.js +151 -0
  24. package/bundled-test-harness/assets/aibot-message-BShcljQ9.js +1312 -0
  25. package/bundled-test-harness/assets/app-DiEYqT6T.js +14146 -0
  26. package/bundled-test-harness/assets/apply-markdown-edit-test-CPhfeg1i.js +230 -0
  27. package/bundled-test-harness/assets/ask-user-picker-NVRkhKwt.js +370 -0
  28. package/bundled-test-harness/assets/ask-user-picker-test-SsZqFm9W.js +39 -0
  29. package/bundled-test-harness/assets/assistant-transcript-test-DesuBCIB.js +57 -0
  30. package/bundled-test-harness/assets/audio-metadata-extractor-test-8JM6oZXG.js +1176 -0
  31. package/bundled-test-harness/assets/authed-fetch-test-yPTMe-9V.js +73 -0
  32. package/bundled-test-harness/assets/avif-image-def-test-Kyknj908.js +187 -0
  33. package/bundled-test-harness/assets/basic-test-D9OrrMaq.js +139 -0
  34. package/bundled-test-harness/assets/binary-upload-dedupe-test-C0RFmHma.js +308 -0
  35. package/bundled-test-harness/assets/bot-registration-test-Bk2lTaCW.js +97 -0
  36. package/bundled-test-harness/assets/box-test-BbV9sMyU.js +50 -0
  37. package/bundled-test-harness/assets/brand-guide-attachments-test-z4wTsKbI.js +84 -0
  38. package/bundled-test-harness/assets/brand-guide-custom-css-test-BlSJE8xo.js +196 -0
  39. package/bundled-test-harness/assets/brand-guide-edit-test-DJ1OQ6IB.js +140 -0
  40. package/bundled-test-harness/assets/brand-logo-mark-field-test-ux7eetkO.js +86 -0
  41. package/bundled-test-harness/assets/broken-link-template-test-CqB3MWyw.js +192 -0
  42. package/bundled-test-harness/assets/bundled-base-modules-test-B2oNLZSJ.js +54 -0
  43. package/bundled-test-harness/assets/bundled-base-oracle-test-DelPfFjn.js +37 -0
  44. package/bundled-test-harness/assets/buried-stack-item-scroll-test-Ixsl1tS0.js +236 -0
  45. package/bundled-test-harness/assets/button-BvYQm_A1.js +141 -0
  46. package/bundled-test-harness/assets/bxl-cyclic-graph-test-p23WCLRW.js +47 -0
  47. package/bundled-test-harness/assets/bxl-expression-test-CVTQYT_C.js +250 -0
  48. package/bundled-test-harness/assets/bxl-indexing-test-D_A7X2sr.js +212 -0
  49. package/bundled-test-harness/assets/bxl-platform-module-test-Cltfyybp.js +71 -0
  50. package/bundled-test-harness/assets/can-invoke-test-CVfE1l1V.js +455 -0
  51. package/bundled-test-harness/assets/can-read-realm-test-CIz6WX_K.js +56 -0
  52. package/bundled-test-harness/assets/cancel-indexing-job-test-0LlrOgYK.js +69 -0
  53. package/bundled-test-harness/assets/capture-test-diHIWmh0.js +360 -0
  54. package/bundled-test-harness/assets/card-api-test-Ci9b0ghP.js +198 -0
  55. package/bundled-test-harness/assets/card-basics-test-RKQoQWZD.js +5364 -0
  56. package/bundled-test-harness/assets/card-chooser-paging-test-BN21sDpP.js +235 -0
  57. package/bundled-test-harness/assets/card-chooser-test-C9jDiIgM.js +393 -0
  58. package/bundled-test-harness/assets/card-context-search-results-KmkXJbmC.js +30 -0
  59. package/bundled-test-harness/assets/card-context-search-results-test-CpMr8OlX.js +184 -0
  60. package/bundled-test-harness/assets/card-def-field-def-relationships-test-D_30xak6.js +562 -0
  61. package/bundled-test-harness/assets/card-def-menu-items-test-ohuHc0b4.js +228 -0
  62. package/bundled-test-harness/assets/card-delete-test-BlsD9Xw4.js +466 -0
  63. package/bundled-test-harness/assets/card-error-3q1o3i0e.js +72 -0
  64. package/bundled-test-harness/assets/card-error-awaiting-index-test-DPgYKfbF.js +53 -0
  65. package/bundled-test-harness/assets/card-info-thumbnail-picker-test-CVfeJyjt.js +219 -0
  66. package/bundled-test-harness/assets/card-playground-test-D-7bi4PQ.js +1491 -0
  67. package/bundled-test-harness/assets/card-prerender-DemTfK_a.js +12939 -0
  68. package/bundled-test-harness/assets/card-thunk-error-test-DCBh1vRT.js +48 -0
  69. package/bundled-test-harness/assets/card-type-service-test-DXPrfVYk.js +161 -0
  70. package/bundled-test-harness/assets/check-correctness-test-DjE7r1X2.js +1093 -0
  71. package/bundled-test-harness/assets/check-domain-availability-test-U10xSKbY.js +98 -0
  72. package/bundled-test-harness/assets/chip-0r_r9SC8.js +44 -0
  73. package/bundled-test-harness/assets/choreo-CZUXQKjf.js +1110 -0
  74. package/bundled-test-harness/assets/choreo-D8RcLuoq.js +2 -0
  75. package/bundled-test-harness/assets/choreo-feature-reel-test-DRGloCAJ.js +155 -0
  76. package/bundled-test-harness/assets/choreo-gallery-build-order-test-BR-r7gaw.js +436 -0
  77. package/bundled-test-harness/assets/choreo-gallery-compositor-test-CWRLfcNT.js +399 -0
  78. package/bundled-test-harness/assets/choreo-gallery-cover-test-BT05gNKC.js +214 -0
  79. package/bundled-test-harness/assets/choreo-gallery-crossing-stage-test-WJ7FmjYi.js +133 -0
  80. package/bundled-test-harness/assets/choreo-gallery-demos-alive-test-C-yxdVT_.js +42 -0
  81. package/bundled-test-harness/assets/choreo-gallery-drift-test-HX1mK3od.js +620 -0
  82. package/bundled-test-harness/assets/choreo-gallery-escort-test-jZEVk_V4.js +187 -0
  83. package/bundled-test-harness/assets/choreo-gallery-films-test-DLDQzsxb.js +140 -0
  84. package/bundled-test-harness/assets/choreo-gallery-filter-test-BJv8KEeP.js +46 -0
  85. package/bundled-test-harness/assets/choreo-gallery-fold-test-BssKC8A8.js +180 -0
  86. package/bundled-test-harness/assets/choreo-gallery-guide-pages-test-DS41eNNV.js +114 -0
  87. package/bundled-test-harness/assets/choreo-gallery-guides-test-DTj7yEKp.js +321 -0
  88. package/bundled-test-harness/assets/choreo-gallery-hang-test-BqJLmeFF.js +426 -0
  89. package/bundled-test-harness/assets/choreo-gallery-highlight-test-B1Q7-ICm.js +60 -0
  90. package/bundled-test-harness/assets/choreo-gallery-inline-edit-test-7My9lVam.js +370 -0
  91. package/bundled-test-harness/assets/choreo-gallery-interruption-test-BlIAaGrw.js +176 -0
  92. package/bundled-test-harness/assets/choreo-gallery-lone-stack-test-C9NnYIP8.js +104 -0
  93. package/bundled-test-harness/assets/choreo-gallery-navigation-test-CWzXkvbW.js +193 -0
  94. package/bundled-test-harness/assets/choreo-gallery-playhead-transport-test-CwdiZWeI.js +111 -0
  95. package/bundled-test-harness/assets/choreo-gallery-poplayout-subtree-test-D55fxwTn.js +127 -0
  96. package/bundled-test-harness/assets/choreo-gallery-presence-modes-test-D8Wxv0lb.js +100 -0
  97. package/bundled-test-harness/assets/choreo-gallery-presentation-test-BLoWfp6G.js +157 -0
  98. package/bundled-test-harness/assets/choreo-gallery-reduced-motion-test-D5XxTBDS.js +145 -0
  99. package/bundled-test-harness/assets/choreo-gallery-sheet-standalone-test-DrHTTvss.js +89 -0
  100. package/bundled-test-harness/assets/choreo-gallery-sheet-test-BFVdnM_b.js +48 -0
  101. package/bundled-test-harness/assets/choreo-gallery-site-test-BhEBHdvI.js +237 -0
  102. package/bundled-test-harness/assets/choreo-gallery-stage-DcKKsdcu.js +256 -0
  103. package/bundled-test-harness/assets/choreo-gallery-stage-keyboard-test-Fcc6SC3F.js +102 -0
  104. package/bundled-test-harness/assets/choreo-gallery-stages-test-Cb-ADpxK.js +35 -0
  105. package/bundled-test-harness/assets/choreo-gallery-subdivision-test-DMJ6C9FW.js +138 -0
  106. package/bundled-test-harness/assets/choreo-gallery-table-plan-test-CAjSUdLJ.js +144 -0
  107. package/bundled-test-harness/assets/choreo-gallery-theater-test-B-3IZMj9.js +252 -0
  108. package/bundled-test-harness/assets/choreo-gallery-tuning-test-BVxK5Ry_.js +95 -0
  109. package/bundled-test-harness/assets/choreo-gallery-widget-room-test-uWBH1EKE.js +88 -0
  110. package/bundled-test-harness/assets/choreo-gallery-wires-test-Bo4Sd1Vn.js +148 -0
  111. package/bundled-test-harness/assets/client-telemetry-test-DFM4mML2.js +340 -0
  112. package/bundled-test-harness/assets/clip-DY6N6K67.js +92 -0
  113. package/bundled-test-harness/assets/clip-DzXoPdp-.js +2 -0
  114. package/bundled-test-harness/assets/code-block-DRE8KQZQ.js +502 -0
  115. package/bundled-test-harness/assets/code-ref-test-CDcqE8_C.js +163 -0
  116. package/bundled-test-harness/assets/code-submode-availability-test-DPTqZYYm.js +198 -0
  117. package/bundled-test-harness/assets/code-submode-test-AHV4mzJ4.js +1839 -0
  118. package/bundled-test-harness/assets/codeblocks-test-D6ijVvEL.js +418 -0
  119. package/bundled-test-harness/assets/codemirror-editor-test-BeAMVivu.js +1512 -0
  120. package/bundled-test-harness/assets/codemirror-embed-toolbar-test-Bnb7_KUT.js +366 -0
  121. package/bundled-test-harness/assets/color-field-test-CR6gGEqE.js +212 -0
  122. package/bundled-test-harness/assets/compaction-test-CjEsY0uG.js +150 -0
  123. package/bundled-test-harness/assets/computed-test-DtyZGgdc.js +1320 -0
  124. package/bundled-test-harness/assets/container-BYGZImLU.css +5101 -0
  125. package/bundled-test-harness/assets/container-CBZZ8uFw.js +10925 -0
  126. package/bundled-test-harness/assets/content-preview-components-test-BztI4fz-.js +462 -0
  127. package/bundled-test-harness/assets/copy-and-edit-test-Cqw7kcur.js +292 -0
  128. package/bundled-test-harness/assets/copy-card-test-D5m3eVEH.js +218 -0
  129. package/bundled-test-harness/assets/copy-file-to-realm-test-FPY-6Ddm.js +148 -0
  130. package/bundled-test-harness/assets/copy-source-test-9pJD-qey.js +56 -0
  131. package/bundled-test-harness/assets/create-file-test-DjMf88u_.js +1086 -0
  132. package/bundled-test-harness/assets/create-file-test-XbgOqg38.js +464 -0
  133. package/bundled-test-harness/assets/create-listing-modal-test-De7b4vu3.js +273 -0
  134. package/bundled-test-harness/assets/create-listing-pr-request-test-CBtIV0Z8.js +117 -0
  135. package/bundled-test-harness/assets/create-spec-test-4xR0gM7E.js +256 -0
  136. package/bundled-test-harness/assets/create-submission-workflow-test-DQpWrpGT.js +132 -0
  137. package/bundled-test-harness/assets/create-workspace-test-BQAudgpS.js +104 -0
  138. package/bundled-test-harness/assets/credential-fields-test-DXKBdbZD.js +200 -0
  139. package/bundled-test-harness/assets/csv-file-def-test-Cnp4y834.js +102 -0
  140. package/bundled-test-harness/assets/dashboard-CmuOhIYC.js +3628 -0
  141. package/bundled-test-harness/assets/dashboard-CzN49x74.css +2400 -0
  142. package/bundled-test-harness/assets/dashboard-add-workspace-test-T32hWB-g.js +50 -0
  143. package/bundled-test-harness/assets/dashboard-agents-test-BN5maCgQ.js +334 -0
  144. package/bundled-test-harness/assets/dashboard-archive-test-BzwUte_Z.js +128 -0
  145. package/bundled-test-harness/assets/dashboard-delete-test-D2Gcp81V.js +163 -0
  146. package/bundled-test-harness/assets/dashboard-duplicate-offer-test-BgKNIr35.js +71 -0
  147. package/bundled-test-harness/assets/dashboard-duplicate-test-D7JEWylc.js +222 -0
  148. package/bundled-test-harness/assets/dashboard-get-started-test-DOGPzGoA.js +374 -0
  149. package/bundled-test-harness/assets/dashboard-ir2bakJS.js +142 -0
  150. package/bundled-test-harness/assets/dashboard-pinned-cards-test-Bn_P9xJU.js +220 -0
  151. package/bundled-test-harness/assets/dashboard-publish-test-64sGQ0nG.js +70 -0
  152. package/bundled-test-harness/assets/dashboard-reindex-test-DJjYq1ct.js +115 -0
  153. package/bundled-test-harness/assets/dashboard-section-rail-test-ZkAhWu5V.js +169 -0
  154. package/bundled-test-harness/assets/dashboard-state-test-BbkpPB5L.js +162 -0
  155. package/bundled-test-harness/assets/dashboard-test-CBLdPrSt.js +545 -0
  156. package/bundled-test-harness/assets/dashboard-unreachable-notice-test-DFT3R1Zx.js +62 -0
  157. package/bundled-test-harness/assets/dashboard-workspace-test-DqBdCFo2.js +537 -0
  158. package/bundled-test-harness/assets/dashboard-workspaces-section-test-CH1HDfxR.js +410 -0
  159. package/bundled-test-harness/assets/data-file-def-preview-test-CNsZwQEJ.js +155 -0
  160. package/bundled-test-harness/assets/date-time-fields-test-CEFaZTnF.js +359 -0
  161. package/bundled-test-harness/assets/debug-message-test-Ck3BfFv3.js +117 -0
  162. package/bundled-test-harness/assets/declared-captures-test-C-0yPRU7.js +879 -0
  163. package/bundled-test-harness/assets/delete-workspace-test-CZOwGy78.js +102 -0
  164. package/bundled-test-harness/assets/diffing-test-BEKI905O.js +210 -0
  165. package/bundled-test-harness/assets/download-file-to-realm-test-C1kAGDll.js +119 -0
  166. package/bundled-test-harness/assets/editor-test-C9x5ZY6g.js +688 -0
  167. package/bundled-test-harness/assets/edits-D76-aanh.js +651 -0
  168. package/bundled-test-harness/assets/email-field-test-LGkrB_2B.js +75 -0
  169. package/bundled-test-harness/assets/enum-field-test-CPyV1J-m.js +935 -0
  170. package/bundled-test-harness/assets/error-display-test-bWuUtfIG.js +343 -0
  171. package/bundled-test-harness/assets/evaluate-module-test-CbS5h8t3.js +91 -0
  172. package/bundled-test-harness/assets/execute-atomic-operations-test-B4Kfco0k.js +113 -0
  173. package/bundled-test-harness/assets/externals-k-2ZBepK.js +4393 -0
  174. package/bundled-test-harness/assets/fallback-banner-live-delete-test-CuFiH1D8.js +207 -0
  175. package/bundled-test-harness/assets/fallback-banner-test-CqSRN7D8.js +225 -0
  176. package/bundled-test-harness/assets/fallback-banner-test-DQkrFE4-.js +53 -0
  177. package/bundled-test-harness/assets/fallback-models-test-BWekNxC0.js +161 -0
  178. package/bundled-test-harness/assets/fetch-card-json-test-DULUqUEu.js +61 -0
  179. package/bundled-test-harness/assets/field-configuration-test-BXZq28xa.js +551 -0
  180. package/bundled-test-harness/assets/field-markdown-domain-test-DdXCifs6.js +616 -0
  181. package/bundled-test-harness/assets/field-markdown-oversize-test-DouPPTHX.js +88 -0
  182. package/bundled-test-harness/assets/field-markdown-primitives-test-DSRGJeyl.js +365 -0
  183. package/bundled-test-harness/assets/field-markdown-specialized-test-DlTYLl_s.js +534 -0
  184. package/bundled-test-harness/assets/field-playground-test-NhS4VvoN.js +894 -0
  185. package/bundled-test-harness/assets/field-support-predicates-test-DWpyT1Qf.js +167 -0
  186. package/bundled-test-harness/assets/file-attachment-test-LwZf-BSY.js +796 -0
  187. package/bundled-test-harness/assets/file-chooser-panel-test-DuAqD9bn.js +153 -0
  188. package/bundled-test-harness/assets/file-chooser-test-CjaXXwpT.js +504 -0
  189. package/bundled-test-harness/assets/file-def-format-templates-test-BDs4OmHq.js +380 -0
  190. package/bundled-test-harness/assets/file-def-live-reload-test-BqTdnq-W.js +124 -0
  191. package/bundled-test-harness/assets/file-def-menu-items-test-DqdINXsD.js +138 -0
  192. package/bundled-test-harness/assets/file-def-navigation-test-BPGr0SQy.js +109 -0
  193. package/bundled-test-harness/assets/file-def-serialization-test-CvjW-FlC.js +89 -0
  194. package/bundled-test-harness/assets/file-def-test-C-Yv_NjS.js +216 -0
  195. package/bundled-test-harness/assets/file-preview-live-reload-test-MzwGwasU.js +310 -0
  196. package/bundled-test-harness/assets/file-resource-primitives-test-D3GmfqNs.js +255 -0
  197. package/bundled-test-harness/assets/file-tree-from-index-test-CfldnUgm.js +96 -0
  198. package/bundled-test-harness/assets/file-tree-test--0ZCPRe9.js +851 -0
  199. package/bundled-test-harness/assets/file-view-model-test-BDIAeBV8.js +346 -0
  200. package/bundled-test-harness/assets/filedef-export-shape-test-B2tgU404.js +61 -0
  201. package/bundled-test-harness/assets/film-Bf73ypzi.js +4074 -0
  202. package/bundled-test-harness/assets/film-C54lhaiU.js +2 -0
  203. package/bundled-test-harness/assets/film-DPcMEHYu.js +13 -0
  204. package/bundled-test-harness/assets/flac-audio-def-test-ByoXMoQ1.js +143 -0
  205. package/bundled-test-harness/assets/font-metadata-extractor-test-hawLTDTG.js +415 -0
  206. package/bundled-test-harness/assets/formatted-aibot-message-test-BahBj3x8.js +109 -0
  207. package/bundled-test-harness/assets/formatted-user-message-test-CodbrU3t.js +43 -0
  208. package/bundled-test-harness/assets/freestyle-test-faQhSciz.js +17 -0
  209. package/bundled-test-harness/assets/full-reindex-realm-test-CE5RJTIC.js +101 -0
  210. package/bundled-test-harness/assets/garbage-collection-test-v-3sev77.js +403 -0
  211. package/bundled-test-harness/assets/general-test-DKZPBtSb.js +923 -0
  212. package/bundled-test-harness/assets/generate-example-cards-one-shot-test-CucWyrkH.js +65 -0
  213. package/bundled-test-harness/assets/generic-file-def-preview-test-_EDRsebi.js +71 -0
  214. package/bundled-test-harness/assets/get-available-realm-identifiers-test-CV023yek.js +47 -0
  215. package/bundled-test-harness/assets/get-catalog-realm-identifiers-test--DOu3DyV.js +47 -0
  216. package/bundled-test-harness/assets/get-default-writable-realm-test-Bic8jl6R.js +54 -0
  217. package/bundled-test-harness/assets/get-published-realms-test-DrA5YcFN.js +71 -0
  218. package/bundled-test-harness/assets/get-realm-of-resource-identifier-test-jfU6SIWn.js +54 -0
  219. package/bundled-test-harness/assets/get-relationship-membership-state-test-Ccy2Z7MN.js +1308 -0
  220. package/bundled-test-harness/assets/get-user-system-card-test-Bmq2lmWv.js +67 -0
  221. package/bundled-test-harness/assets/gif-image-def-test-N1mMQC-X.js +188 -0
  222. package/bundled-test-harness/assets/glimmer-motion-and-choreo-in-cards-test-BkUDjiTs.js +160 -0
  223. package/bundled-test-harness/assets/glimmer-motion-and-choreo-test-DsFWCzTs.js +74 -0
  224. package/bundled-test-harness/assets/gts-file-def-test-BL1jpQ9J.js +100 -0
  225. package/bundled-test-harness/assets/head-format-preview-test-BVCaPQqc.js +158 -0
  226. package/bundled-test-harness/assets/helpers-Ds68JxHe.js +5 -0
  227. package/bundled-test-harness/assets/host-mode-service-B4bisRdR.js +262 -0
  228. package/bundled-test-harness/assets/host-mode-test-BmkN2PCJ.js +831 -0
  229. package/bundled-test-harness/assets/host-submode-test-C6SxQ796.js +1392 -0
  230. package/bundled-test-harness/assets/html-component-test-CNQ9wF0Q.js +65 -0
  231. package/bundled-test-harness/assets/html-def-test-BcaCVVQq.js +160 -0
  232. package/bundled-test-harness/assets/html-meta-extractor-test-BU1hjkTp.js +60 -0
  233. package/bundled-test-harness/assets/hydratable-card-test-CX6MWiti.js +426 -0
  234. package/bundled-test-harness/assets/icon-button-C1zH38Nc.js +67 -0
  235. package/bundled-test-harness/assets/image-metadata-extractor-test-CakSBPZ_.js +1109 -0
  236. package/bundled-test-harness/assets/index-changes-test-D8RtgfyG.js +367 -0
  237. package/bundled-test-harness/assets/index-query-engine-test-BETfoYOK.js +2593 -0
  238. package/bundled-test-harness/assets/index-writer-test-B_bR2fjw.js +3040 -0
  239. package/bundled-test-harness/assets/inspector-test-BwPXJj1S.js +2058 -0
  240. package/bundled-test-harness/assets/instance-filter-matcher-test-BSVCg59b.js +788 -0
  241. package/bundled-test-harness/assets/instantiate-card-test-BVQhZjpq.js +164 -0
  242. package/bundled-test-harness/assets/interact-submode-creation-and-permissions-test-DzQLG41H.js +475 -0
  243. package/bundled-test-harness/assets/interact-submode-setup-C5bKXq73.js +566 -0
  244. package/bundled-test-harness/assets/invalidate-realm-identifiers-test-Cd3dpjhB.js +99 -0
  245. package/bundled-test-harness/assets/invite-user-to-room-test-Brabz1tt.js +142 -0
  246. package/bundled-test-harness/assets/invoke-card-operation-test-C1Q1FUf4.js +333 -0
  247. package/bundled-test-harness/assets/isolated-render-test-BLJfS7BU.js +51 -0
  248. package/bundled-test-harness/assets/job-scoped-doc-cache-test-Bgv5woaB.js +181 -0
  249. package/bundled-test-harness/assets/job-scoped-instance-residency-test-C_bB6KpR.js +103 -0
  250. package/bundled-test-harness/assets/jpg-image-def-test-gdLIKocD.js +697 -0
  251. package/bundled-test-harness/assets/json-file-def-test-CPYMRBY-.js +95 -0
  252. package/bundled-test-harness/assets/key-notices-badge-test-DemslfLw.js +155 -0
  253. package/bundled-test-harness/assets/key-readiness-test-5tq5JycL.js +190 -0
  254. package/bundled-test-harness/assets/linksto-broken-link-placeholder-test-BbhDZ2PH.js +398 -0
  255. package/bundled-test-harness/assets/linksto-error-sentinel-test-C2t7fFPi.js +238 -0
  256. package/bundled-test-harness/assets/linksto-many-broken-link-placeholder-test--U_UvUty.js +354 -0
  257. package/bundled-test-harness/assets/linksto-many-per-slot-access-test-Dj3Xy0ZF.js +303 -0
  258. package/bundled-test-harness/assets/linksto-sentinel-reload-test-D0dK4Jjs.js +197 -0
  259. package/bundled-test-harness/assets/linksto-sentinel-roundtrip-test---IYiXok.js +260 -0
  260. package/bundled-test-harness/assets/linksto-singular-js-access-contract-test-CT04MhES.js +196 -0
  261. package/bundled-test-harness/assets/lint-and-fix-test-aadgx7rX.js +51 -0
  262. package/bundled-test-harness/assets/live-test-BGij_vuc.js +100 -0
  263. package/bundled-test-harness/assets/live-test-CppvValf.js +2 -0
  264. package/bundled-test-harness/assets/load-default-skills-test-Cp2m_ebp.js +74 -0
  265. package/bundled-test-harness/assets/loader-parallel-prefetch-test-vU_26Jqu.js +257 -0
  266. package/bundled-test-harness/assets/loader-test-CTaw8K_B.js +482 -0
  267. package/bundled-test-harness/assets/loading-test-DGGt4qZZ.js +63 -0
  268. package/bundled-test-harness/assets/m4a-audio-def-test-DAiReOXH.js +190 -0
  269. package/bundled-test-harness/assets/main-bXHwJ0CN.js +5 -0
  270. package/bundled-test-harness/assets/markdown-embed-chooser-modal-test-CIXq9FqR.js +470 -0
  271. package/bundled-test-harness/assets/markdown-embed-chooser-test-zFGh9WfP.js +334 -0
  272. package/bundled-test-harness/assets/markdown-embed-preview-pane-test-Byn_WFwY.js +447 -0
  273. package/bundled-test-harness/assets/markdown-embed-preview-test-Y3iFMttg.js +368 -0
  274. package/bundled-test-harness/assets/markdown-fallback-test-Br1TPkLZ.js +316 -0
  275. package/bundled-test-harness/assets/markdown-file-def-test-Crm2MAnq.js +380 -0
  276. package/bundled-test-harness/assets/markdown-helpers-test-CZ9Vvywc.js +188 -0
  277. package/bundled-test-harness/assets/markdown-highlighting-test-CFMkoVDl.js +244 -0
  278. package/bundled-test-harness/assets/markdown-preview-lOh-MyqF.js +72 -0
  279. package/bundled-test-harness/assets/markdown-preview-test-B8w0fFIy.js +238 -0
  280. package/bundled-test-harness/assets/markdown-skill-frontmatter-test-aH6HQly1.js +146 -0
  281. package/bundled-test-harness/assets/markdown-skill-search-test-CiNLQs-5.js +80 -0
  282. package/bundled-test-harness/assets/matrix-service-account-switch-sessions-test-DaA8w1Jj.js +63 -0
  283. package/bundled-test-harness/assets/matrix-service-boot-assembly-test-21GIlf55.js +300 -0
  284. package/bundled-test-harness/assets/matrix-service-personal-realm-test-jn9DUENm.js +125 -0
  285. package/bundled-test-harness/assets/matrix-service-realm-servers-test-eNZVJakl.js +55 -0
  286. package/bundled-test-harness/assets/matrix-service-realms-list-updated-test-Cabm8_dY.js +132 -0
  287. package/bundled-test-harness/assets/matrix-service-relogin-test-C77EFgjc.js +59 -0
  288. package/bundled-test-harness/assets/matrix-service-sliding-sync-test-BgM0fPiO.js +35 -0
  289. package/bundled-test-harness/assets/menu-Cl50TSFe.js +3561 -0
  290. package/bundled-test-harness/assets/message-service-subscription-test-CfEqH2jP.js +110 -0
  291. package/bundled-test-harness/assets/message-service-test-DsTzH1In.js +144 -0
  292. package/bundled-test-harness/assets/message-tool-test-C5xVfTtj.js +33 -0
  293. package/bundled-test-harness/assets/midi-audio-def-test-goLRCNCZ.js +182 -0
  294. package/bundled-test-harness/assets/migrate-skill-test-yPCbVfxG.js +161 -0
  295. package/bundled-test-harness/assets/mini-YXjrY_tH.js +1404 -0
  296. package/bundled-test-harness/assets/mini-card-chooser-test-DrllikHB.js +272 -0
  297. package/bundled-test-harness/assets/mini-file-chooser-test-BfqayhmI.js +201 -0
  298. package/bundled-test-harness/assets/mock-matrix-C7BrPS6S.js +2 -0
  299. package/bundled-test-harness/assets/mock-matrix-FjsXmU7-.js +15107 -0
  300. package/bundled-test-harness/assets/modal-BgaZavcs.js +322 -0
  301. package/bundled-test-harness/assets/model-cost-tier-test-BGg-sJML.js +174 -0
  302. package/bundled-test-harness/assets/model-file-extract-test-CjEBupY5.js +206 -0
  303. package/bundled-test-harness/assets/module-transpile-cache-test-XW6DDsmz.js +67 -0
  304. package/bundled-test-harness/assets/monaco-test-DkoRuFiQ.js +100 -0
  305. package/bundled-test-harness/assets/mp3-audio-def-test-v369NNsQ.js +133 -0
  306. package/bundled-test-harness/assets/multiple-stacks-test-CJpYPWdM.js +208 -0
  307. package/bundled-test-harness/assets/nested-query-field-render-test-CfDrBcUN.js +249 -0
  308. package/bundled-test-harness/assets/no-stacks-test-MmsJeLpz.js +48 -0
  309. package/bundled-test-harness/assets/number-field-test-A7B2r0M5.js +184 -0
  310. package/bundled-test-harness/assets/office-file-def-test-BNRvFmCB.js +263 -0
  311. package/bundled-test-harness/assets/office-metadata-extractor-test-zlDoEIEp.js +218 -0
  312. package/bundled-test-harness/assets/office-poster-capture-test-DdFEaOxR.js +203 -0
  313. package/bundled-test-harness/assets/ogg-audio-def-test-kk91BzQY.js +196 -0
  314. package/bundled-test-harness/assets/open-create-listing-modal-test-D1Dl1pov.js +131 -0
  315. package/bundled-test-harness/assets/open-image-in-new-tab-test-DyCmdMyO.js +52 -0
  316. package/bundled-test-harness/assets/open-secure-window-test-dz1vPudF.js +253 -0
  317. package/bundled-test-harness/assets/open-workspace-test-BvTcskzP.js +46 -0
  318. package/bundled-test-harness/assets/operation-lowering-test-omU66bkJ.js +2957 -0
  319. package/bundled-test-harness/assets/operations-invocation-test-BMj42rQe.js +523 -0
  320. package/bundled-test-harness/assets/operations-optimistic-test-KJLyzT8v.js +203 -0
  321. package/bundled-test-harness/assets/operations-query-test-J3HcnaoK.js +459 -0
  322. package/bundled-test-harness/assets/operations-store-reconciliation-test-CkbGBMBQ.js +406 -0
  323. package/bundled-test-harness/assets/operations-test-C7zXXpRW.js +2518 -0
  324. package/bundled-test-harness/assets/operator-mode-acceptance-test-BPolI_RD.js +1195 -0
  325. package/bundled-test-harness/assets/operator-mode-card-chooser-test-DjTQgizt.js +1036 -0
  326. package/bundled-test-harness/assets/operator-mode-links-test-DSEqy5Db.js +797 -0
  327. package/bundled-test-harness/assets/operator-mode-test-CB7BNDNE.js +696 -0
  328. package/bundled-test-harness/assets/operator-mode-ui-test-C1OhF1il.js +1045 -0
  329. package/bundled-test-harness/assets/overlay-D2rQi8lJ.js +427 -0
  330. package/bundled-test-harness/assets/overlay-menu-items-test-CPN31yBJ.js +331 -0
  331. package/bundled-test-harness/assets/overlays-B-qMEPhY.js +2 -0
  332. package/bundled-test-harness/assets/overlays-DSf2je0c.js +75 -0
  333. package/bundled-test-harness/assets/overlays-detached-element-test-C73nMXes.js +56 -0
  334. package/bundled-test-harness/assets/panel-DjrC7DxA.js +15124 -0
  335. package/bundled-test-harness/assets/past-sessions-test-BSIS2Hlq.js +321 -0
  336. package/bundled-test-harness/assets/patch-fields-test-Bp2IE0Jw.js +1014 -0
  337. package/bundled-test-harness/assets/patch-instance-test-DssuRGKP.js +348 -0
  338. package/bundled-test-harness/assets/pdf-file-def-test-Barj9ffD.js +111 -0
  339. package/bundled-test-harness/assets/pdf-metadata-extractor-test-B7KnXcIm.js +130 -0
  340. package/bundled-test-harness/assets/permission-checking-realm-test-BD4O0nen.js +306 -0
  341. package/bundled-test-harness/assets/persist-module-inspector-view-test-BIdbkdPr.js +60 -0
  342. package/bundled-test-harness/assets/persist-scroll-position-test-Bhb7wJiy.js +254 -0
  343. package/bundled-test-harness/assets/phone-number-field-test-C2yuCrXY.js +73 -0
  344. package/bundled-test-harness/assets/pill-menu-test-BIp91YXi.js +60 -0
  345. package/bundled-test-harness/assets/plate-CJq1veVA.js +41 -0
  346. package/bundled-test-harness/assets/plate-CwAvOUfL.js +2 -0
  347. package/bundled-test-harness/assets/player-Digk7omr.js +2 -0
  348. package/bundled-test-harness/assets/player-vsjosoN_.js +82 -0
  349. package/bundled-test-harness/assets/playground-B02e8uqB.js +58 -0
  350. package/bundled-test-harness/assets/plural-field-components-test-C1acuN-A.js +198 -0
  351. package/bundled-test-harness/assets/png-image-def-test-B9QeVo1f.js +266 -0
  352. package/bundled-test-harness/assets/policy-audit-confirmation-test-CeVquvc_.js +155 -0
  353. package/bundled-test-harness/assets/policy-scoped-search-test-SFPiIqR3.js +339 -0
  354. package/bundled-test-harness/assets/prerender-file-extract-test-HSJKAHyO.js +346 -0
  355. package/bundled-test-harness/assets/prerender-html-test-BTAcFCme.js +670 -0
  356. package/bundled-test-harness/assets/prerender-meta-test-Csyz2b21.js +614 -0
  357. package/bundled-test-harness/assets/prerender-module-test-DpTYAbmI.js +409 -0
  358. package/bundled-test-harness/assets/prerender-persistence-block-test-BhIt-7kK.js +124 -0
  359. package/bundled-test-harness/assets/prerender-pre-model-error-test-DxKPQKqx.js +61 -0
  360. package/bundled-test-harness/assets/prerender-serialize-cycle-test-C8V5YWQO.js +134 -0
  361. package/bundled-test-harness/assets/prerendered-html-read-test-Cq7JVGwg.js +191 -0
  362. package/bundled-test-harness/assets/pretui-components-test-Ducr9fLT.css +743 -0
  363. package/bundled-test-harness/assets/pretui-components-test-Hs0uyIUQ.js +992 -0
  364. package/bundled-test-harness/assets/pretui-primitives-CRs8NRm0.js +69 -0
  365. package/bundled-test-harness/assets/preview-format-test-cCqLrfdY.js +103 -0
  366. package/bundled-test-harness/assets/preview-test-BMqJSoR1.js +474 -0
  367. package/bundled-test-harness/assets/process-card-test-578tfDvr.js +94 -0
  368. package/bundled-test-harness/assets/profile-settings-modal-CVnNl7Yu.js +990 -0
  369. package/bundled-test-harness/assets/publish-realm-COoeWexp.js +82 -0
  370. package/bundled-test-harness/assets/publish-realm-test-a5nkx0Ov.js +210 -0
  371. package/bundled-test-harness/assets/query-field-barrier-test-qX3xVPfk.js +113 -0
  372. package/bundled-test-harness/assets/query-field-error-sentinel-test-V6JDPFLX.js +201 -0
  373. package/bundled-test-harness/assets/query-field-membership-status-test-CK7eDf-K.js +323 -0
  374. package/bundled-test-harness/assets/query-field-page-optin-test-B5YBHUvU.js +126 -0
  375. package/bundled-test-harness/assets/query-field-schema-test-D4SjOGlK.js +231 -0
  376. package/bundled-test-harness/assets/query-field-search-throttle-test-BVkm1-D8.js +154 -0
  377. package/bundled-test-harness/assets/query-field-stale-prerender-test-9g7hcD91.js +152 -0
  378. package/bundled-test-harness/assets/query-fields-test-CQYqhzpN.js +535 -0
  379. package/bundled-test-harness/assets/quick-look-test-CE0o6lJ4.js +139 -0
  380. package/bundled-test-harness/assets/read-card-for-ai-assistant-test-D0mJorwH.js +91 -0
  381. package/bundled-test-harness/assets/read-file-for-ai-assistant-test-B_F_2GEB.js +45 -0
  382. package/bundled-test-harness/assets/read-source-test-BgJV4B4F.js +67 -0
  383. package/bundled-test-harness/assets/read-text-file-test-DaeLzg4u.js +124 -0
  384. package/bundled-test-harness/assets/realm-C_a9su1j.js +2858 -0
  385. package/bundled-test-harness/assets/realm-api-keys-D5USFOoS.js +2 -0
  386. package/bundled-test-harness/assets/realm-api-keys-m_VOcixC.js +578 -0
  387. package/bundled-test-harness/assets/realm-api-keys-test-BVs7f5Dz.js +109 -0
  388. package/bundled-test-harness/assets/realm-api-keys-test-C_uZnTmq.js +588 -0
  389. package/bundled-test-harness/assets/realm-config-m5eccPW8.js +833 -0
  390. package/bundled-test-harness/assets/realm-config-policy-standing-test-Ber-IXpc.js +290 -0
  391. package/bundled-test-harness/assets/realm-config-routing-rule-edit-test-3Xqt5VlM.js +274 -0
  392. package/bundled-test-harness/assets/realm-config-settings-test-CkalhbDF.js +187 -0
  393. package/bundled-test-harness/assets/realm-field-test-B_PUoqnk.js +100 -0
  394. package/bundled-test-harness/assets/realm-indexing-test-8iLjeV_e.js +4380 -0
  395. package/bundled-test-harness/assets/realm-policy-fitted-test-Bptvra0U.js +206 -0
  396. package/bundled-test-harness/assets/realm-policy-test-DwG0qqXE.js +1141 -0
  397. package/bundled-test-harness/assets/realm-querying-test-Dvw26A6Q.js +1067 -0
  398. package/bundled-test-harness/assets/realm-server-form-agnostic-test-DrXQH0UP.js +96 -0
  399. package/bundled-test-harness/assets/realm-server-subscriber-test-Dkj23vQK.js +46 -0
  400. package/bundled-test-harness/assets/realm-service-info-test-CdRlDhj-.js +67 -0
  401. package/bundled-test-harness/assets/realm-test-DGYN48Qx.js +2364 -0
  402. package/bundled-test-harness/assets/realm-token-refresh-test-CEWATL9h.js +153 -0
  403. package/bundled-test-harness/assets/realm-url-tooltip-test-8ZjTNPuy.js +78 -0
  404. package/bundled-test-harness/assets/reasoning-test-BV49AYg2.js +221 -0
  405. package/bundled-test-harness/assets/recent-files-test-Dc6L6Dm4.js +450 -0
  406. package/bundled-test-harness/assets/reindex-realm-test-CFRSt39u.js +117 -0
  407. package/bundled-test-harness/assets/relationship-loading-state-test-FKbtOFUr.js +290 -0
  408. package/bundled-test-harness/assets/remix-card-test-CKGC_Sgq.js +58 -0
  409. package/bundled-test-harness/assets/rendered-markdown-DXiDN91F.js +292 -0
  410. package/bundled-test-harness/assets/rendered-markdown-test-n3MlXmmu.js +587 -0
  411. package/bundled-test-harness/assets/resident-instance-reuse-test-BjdhE6CM.js +82 -0
  412. package/bundled-test-harness/assets/result-tile-o6dtjgX4.js +144 -0
  413. package/bundled-test-harness/assets/rich-markdown-field-test-VXr6l20h.js +1647 -0
  414. package/bundled-test-harness/assets/room-message-test-BrjJ2wMs.js +484 -0
  415. package/bundled-test-harness/assets/run-P_7TsreC.js +4017 -0
  416. package/bundled-test-harness/assets/run-realm-code-DsBUf1si.js +2964 -0
  417. package/bundled-test-harness/assets/run-realm-code-test-cS0DzaKo.js +3844 -0
  418. package/bundled-test-harness/assets/sanitize-module-list-test-CvuOOiUY.js +85 -0
  419. package/bundled-test-harness/assets/save-card-skip-index-wait-test-fpJ1eq32.js +89 -0
  420. package/bundled-test-harness/assets/schema-editor-test-NkKjCgyf.js +785 -0
  421. package/bundled-test-harness/assets/schema-generation-test-Dmg3lWl7.js +28 -0
  422. package/bundled-test-harness/assets/scrolling-test-B0GNYGYc.js +412 -0
  423. package/bundled-test-harness/assets/search-adorn-test-CZebk7_y.js +136 -0
  424. package/bundled-test-harness/assets/search-and-choose-test-Bd4NZUup.js +154 -0
  425. package/bundled-test-harness/assets/search-correlation-id-test-DXKlEO55.js +139 -0
  426. package/bundled-test-harness/assets/search-entries-result-test-QQawA8Fm.js +234 -0
  427. package/bundled-test-harness/assets/search-entries-test-3DlqGPQq.js +1486 -0
  428. package/bundled-test-harness/assets/search-entries-tool-test-D1TvDE9D.js +504 -0
  429. package/bundled-test-harness/assets/search-google-images-test-DqsoQGr1.js +166 -0
  430. package/bundled-test-harness/assets/search-results-DGrNaPxh.js +266 -0
  431. package/bundled-test-harness/assets/search-results-test-CqVHYNRt.js +578 -0
  432. package/bundled-test-harness/assets/search-selection-menu-test-D6bIjKiH.js +108 -0
  433. package/bundled-test-harness/assets/search-sheet-files-test-Bf37TQXo.js +126 -0
  434. package/bundled-test-harness/assets/search-sheet-persistence-test-CV4_XdxR.js +131 -0
  435. package/bundled-test-harness/assets/search-test-Dlb-wg3a.js +2249 -0
  436. package/bundled-test-harness/assets/search-tool-test-BJLgVMoL.js +156 -0
  437. package/bundled-test-harness/assets/searchable-option-test-CcbfMqIL.js +322 -0
  438. package/bundled-test-harness/assets/searchable-search-doc-test-yH9fLGNS.js +1271 -0
  439. package/bundled-test-harness/assets/section-rail-CNFCebtT.js +113 -0
  440. package/bundled-test-harness/assets/section-rail-test-KNJAWWl6.js +256 -0
  441. package/bundled-test-harness/assets/secure-sign-in-Dyljp0Th.js +174 -0
  442. package/bundled-test-harness/assets/secure-sign-in-test-QnqNuTP3.js +373 -0
  443. package/bundled-test-harness/assets/segmented-control-DxJdoJ4Z.js +173 -0
  444. package/bundled-test-harness/assets/select-BiQTg2ts.js +175 -0
  445. package/bundled-test-harness/assets/send-ai-assistant-message-test-CAn7M2dZ.js +52 -0
  446. package/bundled-test-harness/assets/send-bot-trigger-event-test-qBu5E_jy.js +56 -0
  447. package/bundled-test-harness/assets/send-request-via-proxy-test-CLuwLBq_.js +380 -0
  448. package/bundled-test-harness/assets/sending-test-H0AaBSgi.js +659 -0
  449. package/bundled-test-harness/assets/serialization-rri-form-audit-test-hMJukiKt.js +136 -0
  450. package/bundled-test-harness/assets/serialization-test-W5e3wKbz.js +8758 -0
  451. package/bundled-test-harness/assets/set-user-system-card-test-CjgWLkNV.js +59 -0
  452. package/bundled-test-harness/assets/setup-CssMNvui.js +772 -0
  453. package/bundled-test-harness/assets/setup-D8YXvK-p.js +2 -0
  454. package/bundled-test-harness/assets/shared-link-target-reuse-test-D42UO8DC.js +207 -0
  455. package/bundled-test-harness/assets/show-card-test-CHEaS514.js +365 -0
  456. package/bundled-test-harness/assets/signed-capture-link-test-BgEu0F-S.js +132 -0
  457. package/bundled-test-harness/assets/single-stack-test-DYcu_v7Z.js +652 -0
  458. package/bundled-test-harness/assets/skills-test-ChmKhADX.js +648 -0
  459. package/bundled-test-harness/assets/skip-boot-index-guard-test-BzRIncDN.js +46 -0
  460. package/bundled-test-harness/assets/spec-test-BYvFR6Xb.js +1077 -0
  461. package/bundled-test-harness/assets/spinner-Bx9x55NA.js +49 -0
  462. package/bundled-test-harness/assets/src-C1hYFgVl.js +216 -0
  463. package/bundled-test-harness/assets/src-CIlLx7Lu.js +5 -0
  464. package/bundled-test-harness/assets/stick-to-bottom-resize-test-DMHsAG0v.js +56 -0
  465. package/bundled-test-harness/assets/store-add-test-D_9IHQjZ.js +50 -0
  466. package/bundled-test-harness/assets/store-module-rebuild-test-BRGZoLRV.js +454 -0
  467. package/bundled-test-harness/assets/store-search-test-3G8JHuj2.js +175 -0
  468. package/bundled-test-harness/assets/store-test-BiKKDqqW.js +3672 -0
  469. package/bundled-test-harness/assets/structured-theme-test-11TNsgUW.js +377 -0
  470. package/bundled-test-harness/assets/summarize-session-test-CwzD_ZbD.js +172 -0
  471. package/bundled-test-harness/assets/svg-image-def-test-zV6aMK9q.js +167 -0
  472. package/bundled-test-harness/assets/switch-submode-test-DQU2cP5_.js +168 -0
  473. package/bundled-test-harness/assets/sync-openrouter-models-test-xrXVaC2H.js +97 -0
  474. package/bundled-test-harness/assets/test-support-BGl3rthw.js +3 -0
  475. package/bundled-test-harness/assets/test-support-BcBv__98.js +99 -0
  476. package/bundled-test-harness/assets/tests-CmM9imwB.js +3598 -0
  477. package/bundled-test-harness/assets/text-file-def-test-Cyq78UFY.js +94 -0
  478. package/bundled-test-harness/assets/text-input-validator-test-DBj7TaM_.js +156 -0
  479. package/bundled-test-harness/assets/text-suggestion-test-C4XAqWqY.js +340 -0
  480. package/bundled-test-harness/assets/theme-card-test-dVNz4tgU.js +621 -0
  481. package/bundled-test-harness/assets/theme-dashboard-nav-test-DYSn5pqo.js +196 -0
  482. package/bundled-test-harness/assets/theme-scheme-island-test-C1WpkfEP.js +264 -0
  483. package/bundled-test-harness/assets/theme-scoped-css-parity-test-BVluppsE.js +176 -0
  484. package/bundled-test-harness/assets/titles-DCvAhECF.js +52 -0
  485. package/bundled-test-harness/assets/titles-ZPeArtS1.js +2 -0
  486. package/bundled-test-harness/assets/to-device-streaming-test-BJ4J1cXe.js +163 -0
  487. package/bundled-test-harness/assets/token-usage-test-WUf4r4fQ.js +160 -0
  488. package/bundled-test-harness/assets/tools-J_Knr_W6.js +774 -0
  489. package/bundled-test-harness/assets/tools-calling-test-CfqZX0Ed.js +200 -0
  490. package/bundled-test-harness/assets/tools-test-B4x58ZmI.js +1624 -0
  491. package/bundled-test-harness/assets/tools-test-Cvau5219.js +3204 -0
  492. package/bundled-test-harness/assets/tooltip-B0rEgyMW.css +66 -0
  493. package/bundled-test-harness/assets/tooltip-DvUMUgVX.js +195 -0
  494. package/bundled-test-harness/assets/transform-cards-test-CYQbZeD9.js +341 -0
  495. package/bundled-test-harness/assets/ts-file-def-preview-test-m39f8Zio.js +95 -0
  496. package/bundled-test-harness/assets/ts-file-def-test-xIcL5xWe.js +92 -0
  497. package/bundled-test-harness/assets/ttf-font-def-test-ClQ2SzFF.js +206 -0
  498. package/bundled-test-harness/assets/turn-settling-test-DZoL2mRT.js +160 -0
  499. package/bundled-test-harness/assets/turn-summary-Bmt7ZxTS.js +1039 -0
  500. package/bundled-test-harness/assets/unpublish-realm-test-0ToTJczx.js +102 -0
  501. package/bundled-test-harness/assets/update-room-skills-test-o_j8NOUV.js +240 -0
  502. package/bundled-test-harness/assets/use-ai-assistant-test-D7HFpxKJ.js +384 -0
  503. package/bundled-test-harness/assets/user-message-BAOt1hS3.js +262 -0
  504. package/bundled-test-harness/assets/validate-realm-test-e3xIbNLB.js +67 -0
  505. package/bundled-test-harness/assets/video-metadata-extractor-test-D8naLSlg.js +520 -0
  506. package/bundled-test-harness/assets/view-visually-test-BuhGau5E.js +335 -0
  507. package/bundled-test-harness/assets/virtual-network-reset-test-CgaFNGPi.js +96 -0
  508. package/bundled-test-harness/assets/wav-audio-def-test-CWG_UdCh.js +160 -0
  509. package/bundled-test-harness/assets/webp-image-def-test-sN4yw8Zu.js +226 -0
  510. package/bundled-test-harness/assets/workspace-0LfPqbYB.js +445 -0
  511. package/bundled-test-harness/assets/workspace-a11y-test-DQxYDRAP.js +197 -0
  512. package/bundled-test-harness/assets/workspace-actions-jGJSfl8M.js +588 -0
  513. package/bundled-test-harness/assets/workspace-behavior-test-BnF-bmBN.js +338 -0
  514. package/bundled-test-harness/assets/workspace-delete-multiple-test-D-rxPDuT.js +212 -0
  515. package/bundled-test-harness/assets/workspace-delete-summary-test-C2-Mve5R.js +63 -0
  516. package/bundled-test-harness/assets/workspace-hosting-test-BvDKdlOb.js +138 -0
  517. package/bundled-test-harness/assets/workspace-indexing-test-B34T3kqD.js +71 -0
  518. package/bundled-test-harness/assets/workspace-test-CJivgv-m.js +51 -0
  519. package/bundled-test-harness/assets/workspace-test-CuSRpPnQ.js +385 -0
  520. package/bundled-test-harness/assets/workspace-timestamp-labels-test-aWgjdbCp.js +68 -0
  521. package/bundled-test-harness/assets/workspace-unit-test-DHMUf2KT.js +122 -0
  522. package/bundled-test-harness/assets/write-binary-file-test-P-hVQuin.js +124 -0
  523. package/bundled-test-harness/assets/write-text-file-test-fXvJueDd.js +191 -0
  524. package/bundled-test-harness/assets/zip-archive-test-C2P5CUSR.js +285 -0
  525. package/bundled-test-harness/assets/zip-file-def-test-BfJZAmGt.js +164 -0
  526. package/bundled-test-harness/boxel-ui-checksum.txt +1 -1
  527. package/bundled-test-harness/index.html +48 -48
  528. package/bundled-test-harness/tests/index.html +50 -50
  529. package/bundled-types/boxel-ui/helpers/theme-scoped-css.ts +4 -0
  530. package/bundled-types/choreo/choreo.gts +58 -2
  531. package/bundled-types/choreo/compile.ts +5 -0
  532. package/bundled-types/choreo/layout-probe.ts +100 -0
  533. package/bundled-types/choreo/run.ts +99 -4
  534. package/bundled-types/host-app/components/operator-mode/dashboard/get-started.gts +152 -7
  535. package/bundled-types/host-app/components/operator-mode/dashboard/index.gts +2 -0
  536. package/bundled-types/host-app/components/operator-mode/dashboard/workspace.gts +5 -3
  537. package/bundled-types/host-app/components/operator-mode/dashboard-modals/workspace-modals.gts +5 -22
  538. package/bundled-types/host-app/components/operator-mode/host-submode/publishing-realm-popover.gts +1 -1
  539. package/bundled-types/host-app/components/operator-mode/host-submode.gts +111 -37
  540. package/bundled-types/host-app/components/operator-mode/motion/stack-motion.gts +92 -33
  541. package/bundled-types/host-app/components/operator-mode/publish-realm-modal.gts +1 -0
  542. package/bundled-types/host-app/components/operator-mode/stack-item.gts +2 -2
  543. package/bundled-types/host-app/components/operator-mode/stack.gts +36 -25
  544. package/bundled-types/host-app/components/operator-mode/submode-layout.gts +2 -2
  545. package/bundled-types/host-app/lib/modal-focus-trap.ts +33 -0
  546. package/bundled-types/host-app/lib/workspace-actions.ts +21 -0
  547. package/bundled-types/host-app/services/host-mode-service.ts +39 -0
  548. package/bundled-types/host-app/services/realm.ts +14 -0
  549. package/bundled-types/host-tests/helpers/dashboard.ts +67 -0
  550. package/package.json +1 -1
  551. package/bundled-test-harness/assets/account-switch-failed-test-FytUFiPO.js +0 -45
  552. package/bundled-test-harness/assets/adapter-DvmPwSZv.js +0 -2
  553. package/bundled-test-harness/assets/add-field-to-card-definition-tool-test-DN525jiY.js +0 -112
  554. package/bundled-test-harness/assets/ai-assistant-create-workspace-test-q3tKqVJQ.js +0 -130
  555. package/bundled-test-harness/assets/ai-assistant-panel-relogin-test-DgeXcCyi.js +0 -46
  556. package/bundled-test-harness/assets/ai-assistant-test-lDIGPKFP.js +0 -2223
  557. package/bundled-test-harness/assets/ai-function-generation-test-D5GbLyvL.js +0 -1176
  558. package/bundled-test-harness/assets/ai-module-creation-test-I3-j2beD.js +0 -151
  559. package/bundled-test-harness/assets/aibot-message-Dmsjifs6.js +0 -1312
  560. package/bundled-test-harness/assets/app-BS9_-DhN.js +0 -14146
  561. package/bundled-test-harness/assets/apply-markdown-edit-test-4zlwt0Db.js +0 -230
  562. package/bundled-test-harness/assets/ask-user-picker-Dr-0qpNr.js +0 -370
  563. package/bundled-test-harness/assets/ask-user-picker-test-633AFdmS.js +0 -39
  564. package/bundled-test-harness/assets/assistant-transcript-test-BgRnLvMg.js +0 -57
  565. package/bundled-test-harness/assets/audio-metadata-extractor-test-4xsQqL-0.js +0 -1176
  566. package/bundled-test-harness/assets/authed-fetch-test-663mT5_N.js +0 -73
  567. package/bundled-test-harness/assets/avif-image-def-test-h01BPIJy.js +0 -187
  568. package/bundled-test-harness/assets/basic-test-DiD6T-8Q.js +0 -139
  569. package/bundled-test-harness/assets/binary-upload-dedupe-test-CkjMPO_e.js +0 -308
  570. package/bundled-test-harness/assets/bot-registration-test-CFZHpwdj.js +0 -97
  571. package/bundled-test-harness/assets/box-test-C3pSy5ED.js +0 -50
  572. package/bundled-test-harness/assets/brand-guide-attachments-test-EoC_u7Vc.js +0 -84
  573. package/bundled-test-harness/assets/brand-guide-custom-css-test-Dn3fvblr.js +0 -196
  574. package/bundled-test-harness/assets/brand-guide-edit-test-NeiT3MyK.js +0 -140
  575. package/bundled-test-harness/assets/brand-logo-mark-field-test-C2A1EnBB.js +0 -86
  576. package/bundled-test-harness/assets/broken-link-template-test-CWn6V5zZ.js +0 -192
  577. package/bundled-test-harness/assets/bundled-base-modules-test-D7mLzpsw.js +0 -54
  578. package/bundled-test-harness/assets/bundled-base-oracle-test-I7xCId_k.js +0 -37
  579. package/bundled-test-harness/assets/buried-stack-item-scroll-test-DFBev0h-.js +0 -236
  580. package/bundled-test-harness/assets/button-BeSuhveJ.js +0 -207
  581. package/bundled-test-harness/assets/bxl-cyclic-graph-test-DPykwvvx.js +0 -47
  582. package/bundled-test-harness/assets/bxl-expression-test-LBWJiFb9.js +0 -250
  583. package/bundled-test-harness/assets/bxl-indexing-test-BuZmLk7y.js +0 -212
  584. package/bundled-test-harness/assets/bxl-platform-module-test-BNIvlkCM.js +0 -71
  585. package/bundled-test-harness/assets/can-invoke-test-t-bFIIeX.js +0 -455
  586. package/bundled-test-harness/assets/can-read-realm-test-2Q_MzRT9.js +0 -56
  587. package/bundled-test-harness/assets/cancel-indexing-job-test-QeYxEukn.js +0 -69
  588. package/bundled-test-harness/assets/capture-test-CJmJG8YR.js +0 -360
  589. package/bundled-test-harness/assets/card-api-test-B43I510H.js +0 -198
  590. package/bundled-test-harness/assets/card-basics-test-CBClzP2y.js +0 -5364
  591. package/bundled-test-harness/assets/card-chooser-paging-test-HEVzf6pR.js +0 -235
  592. package/bundled-test-harness/assets/card-chooser-test-GfjBRPFI.js +0 -393
  593. package/bundled-test-harness/assets/card-context-search-results-CoSr4EdS.js +0 -30
  594. package/bundled-test-harness/assets/card-context-search-results-test-BLMlZu9t.js +0 -184
  595. package/bundled-test-harness/assets/card-def-field-def-relationships-test-DEBOzKan.js +0 -562
  596. package/bundled-test-harness/assets/card-def-menu-items-test-88_h8o0D.js +0 -228
  597. package/bundled-test-harness/assets/card-delete-test-DKom1phy.js +0 -466
  598. package/bundled-test-harness/assets/card-error-awaiting-index-test-DEwgFZMP.js +0 -53
  599. package/bundled-test-harness/assets/card-error-r6_cXst9.js +0 -72
  600. package/bundled-test-harness/assets/card-info-thumbnail-picker-test-B7LiY15e.js +0 -219
  601. package/bundled-test-harness/assets/card-playground-test-CgyIJHui.js +0 -1491
  602. package/bundled-test-harness/assets/card-prerender-rPfzpIOU.js +0 -12939
  603. package/bundled-test-harness/assets/card-thunk-error-test-L0pvg4Ce.js +0 -48
  604. package/bundled-test-harness/assets/card-type-service-test-B2dhqxSD.js +0 -161
  605. package/bundled-test-harness/assets/check-correctness-test-DgqaLlCW.js +0 -1093
  606. package/bundled-test-harness/assets/check-domain-availability-test-B0hJHY5l.js +0 -98
  607. package/bundled-test-harness/assets/chip-D01NW3WH.js +0 -44
  608. package/bundled-test-harness/assets/choreo-D2Jl79RU.js +0 -1019
  609. package/bundled-test-harness/assets/choreo-_E8SOEe-.js +0 -2
  610. package/bundled-test-harness/assets/choreo-feature-reel-test-WLjsZDmS.js +0 -155
  611. package/bundled-test-harness/assets/choreo-gallery-build-order-test-6jnS8PsS.js +0 -436
  612. package/bundled-test-harness/assets/choreo-gallery-compositor-test-CbUZsVB6.js +0 -399
  613. package/bundled-test-harness/assets/choreo-gallery-cover-test-CbvAStgk.js +0 -214
  614. package/bundled-test-harness/assets/choreo-gallery-crossing-stage-test-tdjvUSa6.js +0 -133
  615. package/bundled-test-harness/assets/choreo-gallery-demos-alive-test-CsnM3hQK.js +0 -42
  616. package/bundled-test-harness/assets/choreo-gallery-drift-test-DG2LQTa7.js +0 -620
  617. package/bundled-test-harness/assets/choreo-gallery-escort-test-mn3-qXP1.js +0 -187
  618. package/bundled-test-harness/assets/choreo-gallery-films-test-BuktaC0D.js +0 -140
  619. package/bundled-test-harness/assets/choreo-gallery-filter-test-Dd-zpps0.js +0 -46
  620. package/bundled-test-harness/assets/choreo-gallery-fold-test-CWc1ijGc.js +0 -180
  621. package/bundled-test-harness/assets/choreo-gallery-guide-pages-test-tk2QmYPU.js +0 -114
  622. package/bundled-test-harness/assets/choreo-gallery-guides-test-DVbf1zM4.js +0 -321
  623. package/bundled-test-harness/assets/choreo-gallery-hang-test-B7EFp2dx.js +0 -426
  624. package/bundled-test-harness/assets/choreo-gallery-highlight-test-BFgbdesP.js +0 -60
  625. package/bundled-test-harness/assets/choreo-gallery-inline-edit-test-DJb8FC5R.js +0 -370
  626. package/bundled-test-harness/assets/choreo-gallery-interruption-test-DWyMXo5D.js +0 -176
  627. package/bundled-test-harness/assets/choreo-gallery-lone-stack-test-D3b8LsJ6.js +0 -104
  628. package/bundled-test-harness/assets/choreo-gallery-navigation-test-CjjU6Rvn.js +0 -193
  629. package/bundled-test-harness/assets/choreo-gallery-playhead-transport-test-Le_h3QWU.js +0 -111
  630. package/bundled-test-harness/assets/choreo-gallery-poplayout-subtree-test-Cp-DlWj4.js +0 -127
  631. package/bundled-test-harness/assets/choreo-gallery-presence-modes-test-DayS4GCJ.js +0 -100
  632. package/bundled-test-harness/assets/choreo-gallery-presentation-test-DeAfuFS7.js +0 -157
  633. package/bundled-test-harness/assets/choreo-gallery-reduced-motion-test-BgPWpggq.js +0 -145
  634. package/bundled-test-harness/assets/choreo-gallery-sheet-standalone-test-PzyoMNYv.js +0 -89
  635. package/bundled-test-harness/assets/choreo-gallery-sheet-test-CxaiNBkL.js +0 -48
  636. package/bundled-test-harness/assets/choreo-gallery-site-test-6xtSntS5.js +0 -237
  637. package/bundled-test-harness/assets/choreo-gallery-stage-E6Q5r-zU.js +0 -256
  638. package/bundled-test-harness/assets/choreo-gallery-stage-keyboard-test-C7aWMr9a.js +0 -102
  639. package/bundled-test-harness/assets/choreo-gallery-stages-test-CDWWgC61.js +0 -35
  640. package/bundled-test-harness/assets/choreo-gallery-subdivision-test-Bkp15XJv.js +0 -138
  641. package/bundled-test-harness/assets/choreo-gallery-table-plan-test-CcGRi_3O.js +0 -144
  642. package/bundled-test-harness/assets/choreo-gallery-theater-test-Qph5pLT_.js +0 -252
  643. package/bundled-test-harness/assets/choreo-gallery-tuning-test-C4DhFLVA.js +0 -95
  644. package/bundled-test-harness/assets/choreo-gallery-widget-room-test-LK493r1M.js +0 -88
  645. package/bundled-test-harness/assets/choreo-gallery-wires-test-B7SeUCc8.js +0 -148
  646. package/bundled-test-harness/assets/client-telemetry-test-DGmHzAFx.js +0 -340
  647. package/bundled-test-harness/assets/clip-BpYQPVz_.js +0 -2
  648. package/bundled-test-harness/assets/clip-CNaYbIwL.js +0 -92
  649. package/bundled-test-harness/assets/code-block-Cp2CJo5-.js +0 -502
  650. package/bundled-test-harness/assets/code-ref-test-C8JBHDb-.js +0 -163
  651. package/bundled-test-harness/assets/code-submode-availability-test-CzG1Tv6L.js +0 -198
  652. package/bundled-test-harness/assets/code-submode-test-BclVWjm5.js +0 -1839
  653. package/bundled-test-harness/assets/codeblocks-test-CmQlyxN7.js +0 -418
  654. package/bundled-test-harness/assets/codemirror-editor-test-B74H_yn8.js +0 -1512
  655. package/bundled-test-harness/assets/codemirror-embed-toolbar-test-Bz6VEysU.js +0 -366
  656. package/bundled-test-harness/assets/color-field-test-DMCPQKIP.js +0 -212
  657. package/bundled-test-harness/assets/compaction-test-saQCLBrQ.js +0 -150
  658. package/bundled-test-harness/assets/computed-test-C05HliJC.js +0 -1320
  659. package/bundled-test-harness/assets/container-Cqcwrd-m.js +0 -10857
  660. package/bundled-test-harness/assets/container-h3Wc26qn.css +0 -5097
  661. package/bundled-test-harness/assets/content-preview-components-test-DZPj4_CU.js +0 -462
  662. package/bundled-test-harness/assets/copy-and-edit-test-DiXTQNTF.js +0 -292
  663. package/bundled-test-harness/assets/copy-card-test-ys7GquUY.js +0 -218
  664. package/bundled-test-harness/assets/copy-file-to-realm-test-Gn0Wn4vT.js +0 -148
  665. package/bundled-test-harness/assets/copy-source-test-BTLrOmPm.js +0 -56
  666. package/bundled-test-harness/assets/create-file-test-BCeIW-Rt.js +0 -464
  667. package/bundled-test-harness/assets/create-file-test-DbHQ5JsS.js +0 -1086
  668. package/bundled-test-harness/assets/create-listing-modal-test-CeHc4ter.js +0 -273
  669. package/bundled-test-harness/assets/create-listing-pr-request-test-DXbJNfMh.js +0 -117
  670. package/bundled-test-harness/assets/create-spec-test-BDIZoyHT.js +0 -256
  671. package/bundled-test-harness/assets/create-submission-workflow-test-Bix5J-3A.js +0 -132
  672. package/bundled-test-harness/assets/create-workspace-test-BmNnLHwC.js +0 -104
  673. package/bundled-test-harness/assets/credential-fields-test-NK1F4QWn.js +0 -200
  674. package/bundled-test-harness/assets/csv-file-def-test-BSfs4TTP.js +0 -102
  675. package/bundled-test-harness/assets/dashboard-C4T7ffKY.js +0 -3576
  676. package/bundled-test-harness/assets/dashboard-CFeHuP5-.js +0 -81
  677. package/bundled-test-harness/assets/dashboard-DQlpW-ux.css +0 -2392
  678. package/bundled-test-harness/assets/dashboard-add-workspace-test--rr6objf.js +0 -50
  679. package/bundled-test-harness/assets/dashboard-agents-test-D1y8H4xH.js +0 -334
  680. package/bundled-test-harness/assets/dashboard-archive-test-bN4EQaXv.js +0 -128
  681. package/bundled-test-harness/assets/dashboard-delete-test-BvsASb8B.js +0 -163
  682. package/bundled-test-harness/assets/dashboard-duplicate-offer-test-DEsd5ZzZ.js +0 -71
  683. package/bundled-test-harness/assets/dashboard-duplicate-test-BnR0sTgB.js +0 -222
  684. package/bundled-test-harness/assets/dashboard-get-started-test-DG4uUXLv.js +0 -246
  685. package/bundled-test-harness/assets/dashboard-pinned-cards-test-AoGGVRAS.js +0 -220
  686. package/bundled-test-harness/assets/dashboard-reindex-test-BN9a96Xp.js +0 -115
  687. package/bundled-test-harness/assets/dashboard-section-rail-test-B3OT9V2T.js +0 -169
  688. package/bundled-test-harness/assets/dashboard-state-test-BY0Zqrmj.js +0 -162
  689. package/bundled-test-harness/assets/dashboard-test-C13oNpWt.js +0 -545
  690. package/bundled-test-harness/assets/dashboard-unreachable-notice-test-DZIV4x5j.js +0 -62
  691. package/bundled-test-harness/assets/dashboard-workspace-test-CBnOQViI.js +0 -537
  692. package/bundled-test-harness/assets/dashboard-workspaces-section-test-KU8ZVOYp.js +0 -396
  693. package/bundled-test-harness/assets/data-file-def-preview-test-CI5gcdtK.js +0 -155
  694. package/bundled-test-harness/assets/date-time-fields-test-D2CpR_Pb.js +0 -359
  695. package/bundled-test-harness/assets/debug-message-test-Df1kHesw.js +0 -117
  696. package/bundled-test-harness/assets/declared-captures-test-hQ43zuox.js +0 -879
  697. package/bundled-test-harness/assets/delete-workspace-test-BhfMKsix.js +0 -102
  698. package/bundled-test-harness/assets/diffing-test-CHRh55mC.js +0 -210
  699. package/bundled-test-harness/assets/download-file-to-realm-test-CC1HURCi.js +0 -119
  700. package/bundled-test-harness/assets/editor-test-DkeCv28f.js +0 -688
  701. package/bundled-test-harness/assets/edits-BSJqtUXM.js +0 -651
  702. package/bundled-test-harness/assets/email-field-test-DihK0suO.js +0 -75
  703. package/bundled-test-harness/assets/enum-field-test-Gja3bzt5.js +0 -935
  704. package/bundled-test-harness/assets/error-display-test-GhYZu7cp.js +0 -343
  705. package/bundled-test-harness/assets/evaluate-module-test-D_t4CiUq.js +0 -91
  706. package/bundled-test-harness/assets/execute-atomic-operations-test-xtou8Zeg.js +0 -113
  707. package/bundled-test-harness/assets/externals-B02-sD_L.js +0 -4393
  708. package/bundled-test-harness/assets/fallback-banner-live-delete-test-DtxzNXdE.js +0 -207
  709. package/bundled-test-harness/assets/fallback-banner-test-BfmiQ_68.js +0 -53
  710. package/bundled-test-harness/assets/fallback-banner-test-DLtTdmvn.js +0 -225
  711. package/bundled-test-harness/assets/fallback-models-test-BxNJxhfd.js +0 -161
  712. package/bundled-test-harness/assets/fetch-card-json-test-DofKbzvC.js +0 -61
  713. package/bundled-test-harness/assets/field-configuration-test-SUoPaXWy.js +0 -551
  714. package/bundled-test-harness/assets/field-markdown-domain-test-BwtR0dPP.js +0 -616
  715. package/bundled-test-harness/assets/field-markdown-oversize-test-D8UJcBc3.js +0 -88
  716. package/bundled-test-harness/assets/field-markdown-primitives-test-D5_ZdoDO.js +0 -365
  717. package/bundled-test-harness/assets/field-markdown-specialized-test-Dpd5hs04.js +0 -534
  718. package/bundled-test-harness/assets/field-playground-test-CzhYzKGv.js +0 -894
  719. package/bundled-test-harness/assets/field-support-predicates-test-BSvVOFth.js +0 -167
  720. package/bundled-test-harness/assets/file-attachment-test-fM-yFedm.js +0 -796
  721. package/bundled-test-harness/assets/file-chooser-panel-test-CKj8YTdY.js +0 -153
  722. package/bundled-test-harness/assets/file-chooser-test-Bs8jFXqa.js +0 -504
  723. package/bundled-test-harness/assets/file-def-format-templates-test-CxrRoWoD.js +0 -380
  724. package/bundled-test-harness/assets/file-def-live-reload-test-X_8YEkve.js +0 -124
  725. package/bundled-test-harness/assets/file-def-menu-items-test-Dx879o_o.js +0 -138
  726. package/bundled-test-harness/assets/file-def-navigation-test-MMI_EEO1.js +0 -109
  727. package/bundled-test-harness/assets/file-def-serialization-test-B5lguBQD.js +0 -89
  728. package/bundled-test-harness/assets/file-def-test-Di9QWcrj.js +0 -216
  729. package/bundled-test-harness/assets/file-preview-live-reload-test-aqx93A7c.js +0 -310
  730. package/bundled-test-harness/assets/file-resource-primitives-test-a5abpcSB.js +0 -255
  731. package/bundled-test-harness/assets/file-tree-from-index-test-CnruGxJ8.js +0 -96
  732. package/bundled-test-harness/assets/file-tree-test-BCyWDdSE.js +0 -851
  733. package/bundled-test-harness/assets/file-view-model-test-BfpLa01Y.js +0 -346
  734. package/bundled-test-harness/assets/filedef-export-shape-test-CQ9XbrzS.js +0 -61
  735. package/bundled-test-harness/assets/film-CL1zj_bJ.js +0 -2
  736. package/bundled-test-harness/assets/film-Dq_quZ31.js +0 -13
  737. package/bundled-test-harness/assets/film-xbkQa060.js +0 -4074
  738. package/bundled-test-harness/assets/flac-audio-def-test-BmVp9dMx.js +0 -143
  739. package/bundled-test-harness/assets/focus-Dm4wkM72.js +0 -306
  740. package/bundled-test-harness/assets/font-metadata-extractor-test-OWEh9_MS.js +0 -415
  741. package/bundled-test-harness/assets/formatted-aibot-message-test-BpHsWpuV.js +0 -109
  742. package/bundled-test-harness/assets/formatted-user-message-test-DZW5TAr0.js +0 -43
  743. package/bundled-test-harness/assets/freestyle-test-D_uaPU_3.js +0 -17
  744. package/bundled-test-harness/assets/full-reindex-realm-test-C6vHL5kC.js +0 -101
  745. package/bundled-test-harness/assets/garbage-collection-test-D-Ao4t2n.js +0 -403
  746. package/bundled-test-harness/assets/general-test-PSGI8W0z.js +0 -923
  747. package/bundled-test-harness/assets/generate-example-cards-one-shot-test-J-m-0E6W.js +0 -65
  748. package/bundled-test-harness/assets/generic-file-def-preview-test-BAsOhTYU.js +0 -71
  749. package/bundled-test-harness/assets/get-available-realm-identifiers-test-D5PBOr97.js +0 -47
  750. package/bundled-test-harness/assets/get-catalog-realm-identifiers-test-NM9UURHE.js +0 -47
  751. package/bundled-test-harness/assets/get-default-writable-realm-test-BxXc9a3J.js +0 -54
  752. package/bundled-test-harness/assets/get-published-realms-test-C8TJEc4-.js +0 -71
  753. package/bundled-test-harness/assets/get-realm-of-resource-identifier-test-Dt8CB6lS.js +0 -54
  754. package/bundled-test-harness/assets/get-relationship-membership-state-test-9_8x3myJ.js +0 -1308
  755. package/bundled-test-harness/assets/get-user-system-card-test-k0UO-uba.js +0 -67
  756. package/bundled-test-harness/assets/gif-image-def-test-BWrqPGDX.js +0 -188
  757. package/bundled-test-harness/assets/glimmer-motion-and-choreo-in-cards-test-BgG8QI9E.js +0 -160
  758. package/bundled-test-harness/assets/glimmer-motion-and-choreo-test-BKOvNyCN.js +0 -74
  759. package/bundled-test-harness/assets/gts-file-def-test-BCRHwDeZ.js +0 -100
  760. package/bundled-test-harness/assets/head-format-preview-test-DnfUhniI.js +0 -158
  761. package/bundled-test-harness/assets/helpers-DklkegO_.js +0 -5
  762. package/bundled-test-harness/assets/host-mode-service-vOfN0smp.js +0 -232
  763. package/bundled-test-harness/assets/host-mode-test-CCCJFz6_.js +0 -831
  764. package/bundled-test-harness/assets/host-submode-test-CtCfbuPA.js +0 -1342
  765. package/bundled-test-harness/assets/html-component-test-CWyhb5ZX.js +0 -65
  766. package/bundled-test-harness/assets/html-def-test-Cb8C2lUx.js +0 -160
  767. package/bundled-test-harness/assets/html-meta-extractor-test-BHT9Rtir.js +0 -60
  768. package/bundled-test-harness/assets/hydratable-card-test-DpgpdesD.js +0 -426
  769. package/bundled-test-harness/assets/icon-button-ABCGVF3C.js +0 -67
  770. package/bundled-test-harness/assets/image-metadata-extractor-test-ClhPTouq.js +0 -1109
  771. package/bundled-test-harness/assets/index-changes-test-CgnVr3LH.js +0 -367
  772. package/bundled-test-harness/assets/index-query-engine-test-CQTwju5_.js +0 -2593
  773. package/bundled-test-harness/assets/index-writer-test-IoVOoZT2.js +0 -3040
  774. package/bundled-test-harness/assets/inspector-test-BN2Ieb77.js +0 -2058
  775. package/bundled-test-harness/assets/instance-filter-matcher-test-Bq-_Sy89.js +0 -788
  776. package/bundled-test-harness/assets/instantiate-card-test-DEeDTzFV.js +0 -164
  777. package/bundled-test-harness/assets/interact-submode-creation-and-permissions-test-DP6kOyJS.js +0 -475
  778. package/bundled-test-harness/assets/interact-submode-setup-B0_cHqH-.js +0 -566
  779. package/bundled-test-harness/assets/invalidate-realm-identifiers-test-9uUD91Pw.js +0 -99
  780. package/bundled-test-harness/assets/invite-user-to-room-test-CcDA45Ac.js +0 -142
  781. package/bundled-test-harness/assets/invoke-card-operation-test-DmUtgueM.js +0 -333
  782. package/bundled-test-harness/assets/isolated-render-test-B2eXNHu6.js +0 -51
  783. package/bundled-test-harness/assets/job-scoped-doc-cache-test-DF9D7cOc.js +0 -181
  784. package/bundled-test-harness/assets/job-scoped-instance-residency-test-CSS8xUU5.js +0 -103
  785. package/bundled-test-harness/assets/jpg-image-def-test-voECMTht.js +0 -697
  786. package/bundled-test-harness/assets/json-file-def-test-8Y4KLjUC.js +0 -95
  787. package/bundled-test-harness/assets/key-notices-badge-test-d1mYqx0e.js +0 -155
  788. package/bundled-test-harness/assets/key-readiness-test-BtCg7PCk.js +0 -190
  789. package/bundled-test-harness/assets/linksto-broken-link-placeholder-test-CyCMbJnN.js +0 -398
  790. package/bundled-test-harness/assets/linksto-error-sentinel-test-BDW572-v.js +0 -238
  791. package/bundled-test-harness/assets/linksto-many-broken-link-placeholder-test-B4wM97hD.js +0 -354
  792. package/bundled-test-harness/assets/linksto-many-per-slot-access-test-BhJmtJ0_.js +0 -303
  793. package/bundled-test-harness/assets/linksto-sentinel-reload-test-BpBQ5V_i.js +0 -197
  794. package/bundled-test-harness/assets/linksto-sentinel-roundtrip-test-pkBBl4e9.js +0 -260
  795. package/bundled-test-harness/assets/linksto-singular-js-access-contract-test-Bb6wjUdD.js +0 -196
  796. package/bundled-test-harness/assets/lint-and-fix-test-CcMLn-co.js +0 -51
  797. package/bundled-test-harness/assets/live-test-AyBnq7BX.js +0 -2
  798. package/bundled-test-harness/assets/live-test-CgnAcIDw.js +0 -100
  799. package/bundled-test-harness/assets/load-default-skills-test-BIOwtx0Y.js +0 -74
  800. package/bundled-test-harness/assets/loader-parallel-prefetch-test-D5_oRSER.js +0 -257
  801. package/bundled-test-harness/assets/loader-test-DSc_jR1c.js +0 -482
  802. package/bundled-test-harness/assets/loading-test-8pldx7S-.js +0 -63
  803. package/bundled-test-harness/assets/m4a-audio-def-test-BDI5apzM.js +0 -190
  804. package/bundled-test-harness/assets/main-5kHyCkdm.js +0 -5
  805. package/bundled-test-harness/assets/markdown-embed-chooser-modal-test-Wud0s7WZ.js +0 -470
  806. package/bundled-test-harness/assets/markdown-embed-chooser-test-DVzzS-0C.js +0 -334
  807. package/bundled-test-harness/assets/markdown-embed-preview-pane-test-B5W_iqsi.js +0 -447
  808. package/bundled-test-harness/assets/markdown-embed-preview-test-CZF_s0fB.js +0 -368
  809. package/bundled-test-harness/assets/markdown-fallback-test-fT6BS4W7.js +0 -316
  810. package/bundled-test-harness/assets/markdown-file-def-test-B1aTzazR.js +0 -380
  811. package/bundled-test-harness/assets/markdown-helpers-test-gNKZf7Mw.js +0 -188
  812. package/bundled-test-harness/assets/markdown-highlighting-test-Du5_CQmD.js +0 -244
  813. package/bundled-test-harness/assets/markdown-preview-h-_aJhRc.js +0 -72
  814. package/bundled-test-harness/assets/markdown-preview-test-DJvoVsXw.js +0 -238
  815. package/bundled-test-harness/assets/markdown-skill-frontmatter-test-VwJi3Paj.js +0 -146
  816. package/bundled-test-harness/assets/markdown-skill-search-test-ysCdf0xM.js +0 -80
  817. package/bundled-test-harness/assets/matrix-service-account-switch-sessions-test-K2JuMy36.js +0 -63
  818. package/bundled-test-harness/assets/matrix-service-boot-assembly-test-CkdL_-os.js +0 -300
  819. package/bundled-test-harness/assets/matrix-service-personal-realm-test-Dy1DultK.js +0 -125
  820. package/bundled-test-harness/assets/matrix-service-realm-servers-test-DHDDKuEg.js +0 -55
  821. package/bundled-test-harness/assets/matrix-service-realms-list-updated-test-DcTbZpMl.js +0 -132
  822. package/bundled-test-harness/assets/matrix-service-relogin-test-D3NQktoa.js +0 -59
  823. package/bundled-test-harness/assets/matrix-service-sliding-sync-test-6CAflWOA.js +0 -35
  824. package/bundled-test-harness/assets/menu-kUSaJIPq.js +0 -3562
  825. package/bundled-test-harness/assets/message-service-subscription-test-DaQdgDWi.js +0 -110
  826. package/bundled-test-harness/assets/message-service-test-BsGEgM_m.js +0 -144
  827. package/bundled-test-harness/assets/message-tool-test-BB_4kw1V.js +0 -33
  828. package/bundled-test-harness/assets/midi-audio-def-test-BbbkFjqf.js +0 -182
  829. package/bundled-test-harness/assets/migrate-skill-test-X9xImDuq.js +0 -161
  830. package/bundled-test-harness/assets/mini-AwF31elJ.js +0 -1404
  831. package/bundled-test-harness/assets/mini-card-chooser-test-BZtrEiWu.js +0 -272
  832. package/bundled-test-harness/assets/mini-file-chooser-test-MIHW3kCI.js +0 -201
  833. package/bundled-test-harness/assets/mock-matrix-Dd8k0DNa.js +0 -15107
  834. package/bundled-test-harness/assets/mock-matrix-DhPN_34j.js +0 -2
  835. package/bundled-test-harness/assets/modal-LTh3_oHK.js +0 -322
  836. package/bundled-test-harness/assets/model-cost-tier-test-h1IkU9mp.js +0 -174
  837. package/bundled-test-harness/assets/model-file-extract-test-ntSo0wZF.js +0 -206
  838. package/bundled-test-harness/assets/module-transpile-cache-test-CDeRaaeP.js +0 -67
  839. package/bundled-test-harness/assets/monaco-test-C0Fa744D.js +0 -100
  840. package/bundled-test-harness/assets/mp3-audio-def-test-B4j4qR9H.js +0 -133
  841. package/bundled-test-harness/assets/multiple-stacks-test-BhA25ywL.js +0 -208
  842. package/bundled-test-harness/assets/nested-query-field-render-test-S9Y8YNKB.js +0 -249
  843. package/bundled-test-harness/assets/no-stacks-test-B7VciWyg.js +0 -48
  844. package/bundled-test-harness/assets/number-field-test-CS74lDPN.js +0 -184
  845. package/bundled-test-harness/assets/office-file-def-test-2cKc1pmd.js +0 -263
  846. package/bundled-test-harness/assets/office-metadata-extractor-test-DC8Fo-OW.js +0 -218
  847. package/bundled-test-harness/assets/office-poster-capture-test-Ba0_5UrT.js +0 -203
  848. package/bundled-test-harness/assets/ogg-audio-def-test-CIPQ1d4w.js +0 -196
  849. package/bundled-test-harness/assets/open-create-listing-modal-test-bmQkY5Zl.js +0 -131
  850. package/bundled-test-harness/assets/open-image-in-new-tab-test-DBD7_vMH.js +0 -52
  851. package/bundled-test-harness/assets/open-secure-window-test-BgeuYAqz.js +0 -253
  852. package/bundled-test-harness/assets/open-workspace-test-DRHGljV0.js +0 -46
  853. package/bundled-test-harness/assets/operation-lowering-test-CH1c0pSH.js +0 -2957
  854. package/bundled-test-harness/assets/operations-invocation-test-B1YkCLrv.js +0 -523
  855. package/bundled-test-harness/assets/operations-optimistic-test-DAbtOwsC.js +0 -203
  856. package/bundled-test-harness/assets/operations-query-test-9p1ZIDe-.js +0 -459
  857. package/bundled-test-harness/assets/operations-store-reconciliation-test-D0EQh3w2.js +0 -406
  858. package/bundled-test-harness/assets/operations-test-BQhlrfe3.js +0 -2518
  859. package/bundled-test-harness/assets/operator-mode-acceptance-test-DtHnonEb.js +0 -1195
  860. package/bundled-test-harness/assets/operator-mode-card-chooser-test-DQUxZxaq.js +0 -1036
  861. package/bundled-test-harness/assets/operator-mode-links-test-BJ26HllS.js +0 -797
  862. package/bundled-test-harness/assets/operator-mode-test-DIPDI0qt.js +0 -696
  863. package/bundled-test-harness/assets/operator-mode-ui-test-CfA-fAh4.js +0 -1045
  864. package/bundled-test-harness/assets/overlay-DecPh3nt.js +0 -123
  865. package/bundled-test-harness/assets/overlay-menu-items-test-C6XqjLtu.js +0 -331
  866. package/bundled-test-harness/assets/overlays-Ctp8ePzZ.js +0 -75
  867. package/bundled-test-harness/assets/overlays-CzWpSg5T.js +0 -2
  868. package/bundled-test-harness/assets/overlays-detached-element-test-DvL_8Bb5.js +0 -56
  869. package/bundled-test-harness/assets/panel-CImumikB.js +0 -15124
  870. package/bundled-test-harness/assets/past-sessions-test-N6riGN_I.js +0 -321
  871. package/bundled-test-harness/assets/patch-fields-test-D30_-KwQ.js +0 -1014
  872. package/bundled-test-harness/assets/patch-instance-test-C5rGscZq.js +0 -348
  873. package/bundled-test-harness/assets/pdf-file-def-test-DtiqGRvZ.js +0 -111
  874. package/bundled-test-harness/assets/pdf-metadata-extractor-test-FU02KmdV.js +0 -130
  875. package/bundled-test-harness/assets/permission-checking-realm-test-DqdNJDwU.js +0 -306
  876. package/bundled-test-harness/assets/persist-module-inspector-view-test-BHOAgPVy.js +0 -60
  877. package/bundled-test-harness/assets/persist-scroll-position-test-qtmS518r.js +0 -254
  878. package/bundled-test-harness/assets/phone-number-field-test-DhdaM7uL.js +0 -73
  879. package/bundled-test-harness/assets/pill-menu-test-C9Mrrepl.js +0 -60
  880. package/bundled-test-harness/assets/plate-9n-sXyCw.js +0 -41
  881. package/bundled-test-harness/assets/plate-BnZcAk-_.js +0 -2
  882. package/bundled-test-harness/assets/player-Cu5b4LEJ.js +0 -82
  883. package/bundled-test-harness/assets/player-unk2mkxV.js +0 -2
  884. package/bundled-test-harness/assets/playground-BwA8wFGK.js +0 -58
  885. package/bundled-test-harness/assets/plural-field-components-test-CFNQKETg.js +0 -198
  886. package/bundled-test-harness/assets/png-image-def-test-DG5Vhlqb.js +0 -266
  887. package/bundled-test-harness/assets/policy-audit-confirmation-test-yfKU47LR.js +0 -155
  888. package/bundled-test-harness/assets/policy-scoped-search-test-BjQRDYqR.js +0 -339
  889. package/bundled-test-harness/assets/prerender-file-extract-test-CEU4SaAZ.js +0 -346
  890. package/bundled-test-harness/assets/prerender-html-test-CGB3ClCS.js +0 -670
  891. package/bundled-test-harness/assets/prerender-meta-test-xqc4fW_0.js +0 -614
  892. package/bundled-test-harness/assets/prerender-module-test-CI1TmZw-.js +0 -409
  893. package/bundled-test-harness/assets/prerender-persistence-block-test-Da0dJO_N.js +0 -124
  894. package/bundled-test-harness/assets/prerender-pre-model-error-test-BVLyhk8R.js +0 -61
  895. package/bundled-test-harness/assets/prerender-serialize-cycle-test-glJFfxHU.js +0 -134
  896. package/bundled-test-harness/assets/prerendered-html-read-test-Mp4L0VHQ.js +0 -191
  897. package/bundled-test-harness/assets/pretui-components-test-BBpA9UnA.js +0 -991
  898. package/bundled-test-harness/assets/pretui-components-test-BqFq7rw_.css +0 -730
  899. package/bundled-test-harness/assets/preview-format-test-C55Bwcur.js +0 -103
  900. package/bundled-test-harness/assets/preview-test-CTAhRGU8.js +0 -474
  901. package/bundled-test-harness/assets/process-card-test-UjqpuxB7.js +0 -94
  902. package/bundled-test-harness/assets/profile-settings-modal-C8bCgTMK.js +0 -989
  903. package/bundled-test-harness/assets/publish-realm-ixUB4FPK.js +0 -82
  904. package/bundled-test-harness/assets/publish-realm-test-CrrsdL4W.js +0 -210
  905. package/bundled-test-harness/assets/query-field-barrier-test-DjivFE93.js +0 -113
  906. package/bundled-test-harness/assets/query-field-error-sentinel-test-0HwnV4Mw.js +0 -201
  907. package/bundled-test-harness/assets/query-field-membership-status-test-C8yTTBkc.js +0 -323
  908. package/bundled-test-harness/assets/query-field-page-optin-test-D4l_GcII.js +0 -126
  909. package/bundled-test-harness/assets/query-field-schema-test-DDbcNNm5.js +0 -231
  910. package/bundled-test-harness/assets/query-field-search-throttle-test-CXp50Ax0.js +0 -154
  911. package/bundled-test-harness/assets/query-field-stale-prerender-test-DErzt-Cv.js +0 -152
  912. package/bundled-test-harness/assets/query-fields-test-Dz67fdSl.js +0 -535
  913. package/bundled-test-harness/assets/quick-look-test-B1ijDsh_.js +0 -139
  914. package/bundled-test-harness/assets/read-card-for-ai-assistant-test-DJxZ16H_.js +0 -91
  915. package/bundled-test-harness/assets/read-file-for-ai-assistant-test-BoRQkZ8c.js +0 -45
  916. package/bundled-test-harness/assets/read-source-test-Bl-NjchO.js +0 -67
  917. package/bundled-test-harness/assets/read-text-file-test-CP37CZoo.js +0 -124
  918. package/bundled-test-harness/assets/realm-CaK5mkT-.js +0 -2852
  919. package/bundled-test-harness/assets/realm-api-keys-BNUFWbGR.js +0 -579
  920. package/bundled-test-harness/assets/realm-api-keys-CkshxhXC.js +0 -2
  921. package/bundled-test-harness/assets/realm-api-keys-test-BP8xifjn.js +0 -109
  922. package/bundled-test-harness/assets/realm-api-keys-test-CwdK9YXp.js +0 -588
  923. package/bundled-test-harness/assets/realm-config-iKwE3Htp.js +0 -833
  924. package/bundled-test-harness/assets/realm-config-policy-standing-test-BgVEIDnB.js +0 -290
  925. package/bundled-test-harness/assets/realm-config-routing-rule-edit-test-BoJoKzmX.js +0 -274
  926. package/bundled-test-harness/assets/realm-config-settings-test-Kxw-GHye.js +0 -187
  927. package/bundled-test-harness/assets/realm-field-test-CdGOxrFb.js +0 -100
  928. package/bundled-test-harness/assets/realm-indexing-test-CHtsBV2b.js +0 -4380
  929. package/bundled-test-harness/assets/realm-policy-fitted-test--DhNZSdC.js +0 -206
  930. package/bundled-test-harness/assets/realm-policy-test-D7714iVa.js +0 -1141
  931. package/bundled-test-harness/assets/realm-querying-test-Cj1ekZ0H.js +0 -1067
  932. package/bundled-test-harness/assets/realm-server-form-agnostic-test-CZFPNJfD.js +0 -96
  933. package/bundled-test-harness/assets/realm-server-subscriber-test-C86WmBp0.js +0 -46
  934. package/bundled-test-harness/assets/realm-service-info-test-CdgcwKDR.js +0 -67
  935. package/bundled-test-harness/assets/realm-test-DPoLsvKz.js +0 -2364
  936. package/bundled-test-harness/assets/realm-token-refresh-test-Ch35Siwi.js +0 -153
  937. package/bundled-test-harness/assets/realm-url-tooltip-test-x8xWOENK.js +0 -78
  938. package/bundled-test-harness/assets/reasoning-test-BxpE8Jvf.js +0 -221
  939. package/bundled-test-harness/assets/recent-files-test-DTmEzPLq.js +0 -450
  940. package/bundled-test-harness/assets/reindex-realm-test-BQ8KULn4.js +0 -117
  941. package/bundled-test-harness/assets/relationship-loading-state-test-BJoArPWf.js +0 -290
  942. package/bundled-test-harness/assets/remix-card-test-DsTA1KoG.js +0 -58
  943. package/bundled-test-harness/assets/rendered-markdown-DvukulDO.js +0 -292
  944. package/bundled-test-harness/assets/rendered-markdown-test-DxGptXSV.js +0 -587
  945. package/bundled-test-harness/assets/resident-instance-reuse-test-ZWnVu8uj.js +0 -82
  946. package/bundled-test-harness/assets/result-tile-CPyI6Vmv.js +0 -144
  947. package/bundled-test-harness/assets/rich-markdown-field-test-CdygoXIO.js +0 -1647
  948. package/bundled-test-harness/assets/room-message-test-D3NfMqH0.js +0 -484
  949. package/bundled-test-harness/assets/run-D_Px28eF.js +0 -3956
  950. package/bundled-test-harness/assets/run-realm-code-qWCZxmJ7.js +0 -2964
  951. package/bundled-test-harness/assets/run-realm-code-test-UzyeEJq6.js +0 -3844
  952. package/bundled-test-harness/assets/sanitize-module-list-test-Babq44bP.js +0 -85
  953. package/bundled-test-harness/assets/save-card-skip-index-wait-test-BcELXlQ_.js +0 -89
  954. package/bundled-test-harness/assets/schema-editor-test-CEvruZbt.js +0 -785
  955. package/bundled-test-harness/assets/schema-generation-test-hYAMdCrn.js +0 -28
  956. package/bundled-test-harness/assets/scrolling-test-DVIsh-_1.js +0 -412
  957. package/bundled-test-harness/assets/search-adorn-test-CkVhqFd0.js +0 -136
  958. package/bundled-test-harness/assets/search-and-choose-test-DUhOB3FV.js +0 -154
  959. package/bundled-test-harness/assets/search-correlation-id-test-Drn4r26N.js +0 -139
  960. package/bundled-test-harness/assets/search-entries-result-test-DTCRJ_wc.js +0 -234
  961. package/bundled-test-harness/assets/search-entries-test-CE0B47pw.js +0 -1486
  962. package/bundled-test-harness/assets/search-entries-tool-test-C4aG0ckM.js +0 -504
  963. package/bundled-test-harness/assets/search-google-images-test-LyhcB2f3.js +0 -166
  964. package/bundled-test-harness/assets/search-results-D4pSne0x.js +0 -266
  965. package/bundled-test-harness/assets/search-results-test-CRZHhqhn.js +0 -578
  966. package/bundled-test-harness/assets/search-selection-menu-test-B7Y3E_nj.js +0 -108
  967. package/bundled-test-harness/assets/search-sheet-files-test-C2y534g8.js +0 -126
  968. package/bundled-test-harness/assets/search-sheet-persistence-test-DePC59Bk.js +0 -131
  969. package/bundled-test-harness/assets/search-test-Dy8NxFkU.js +0 -2249
  970. package/bundled-test-harness/assets/search-tool-test-lctDaMH3.js +0 -156
  971. package/bundled-test-harness/assets/searchable-option-test-CE64M8oM.js +0 -322
  972. package/bundled-test-harness/assets/searchable-search-doc-test-C6u3mVvT.js +0 -1271
  973. package/bundled-test-harness/assets/section-rail-B_UQX00B.js +0 -113
  974. package/bundled-test-harness/assets/section-rail-test-DIda7MIw.js +0 -256
  975. package/bundled-test-harness/assets/secure-sign-in-CqqqfQG8.js +0 -174
  976. package/bundled-test-harness/assets/secure-sign-in-test-DimbVr_W.js +0 -373
  977. package/bundled-test-harness/assets/segmented-control-iePxSdTS.js +0 -173
  978. package/bundled-test-harness/assets/select-tNs6_xwW.js +0 -175
  979. package/bundled-test-harness/assets/send-ai-assistant-message-test-2GVrMF9Z.js +0 -52
  980. package/bundled-test-harness/assets/send-bot-trigger-event-test-B_3dKfGN.js +0 -56
  981. package/bundled-test-harness/assets/send-request-via-proxy-test-_clNWyYc.js +0 -380
  982. package/bundled-test-harness/assets/sending-test-DCPFXUVg.js +0 -659
  983. package/bundled-test-harness/assets/serialization-rri-form-audit-test-BI0zCs8Y.js +0 -136
  984. package/bundled-test-harness/assets/serialization-test-bjdtVlZL.js +0 -8758
  985. package/bundled-test-harness/assets/set-user-system-card-test-BUv1vL08.js +0 -59
  986. package/bundled-test-harness/assets/setup-BW1mmC7C.js +0 -772
  987. package/bundled-test-harness/assets/setup-DsIcFT-T.js +0 -2
  988. package/bundled-test-harness/assets/shared-link-target-reuse-test-9NeJEjkb.js +0 -207
  989. package/bundled-test-harness/assets/show-card-test-mfyLwusD.js +0 -365
  990. package/bundled-test-harness/assets/signed-capture-link-test-BOtKNCAM.js +0 -132
  991. package/bundled-test-harness/assets/single-stack-test-B4MGjaLk.js +0 -652
  992. package/bundled-test-harness/assets/skills-test-BuP-Yzk1.js +0 -648
  993. package/bundled-test-harness/assets/skip-boot-index-guard-test-Cmrx2-K7.js +0 -46
  994. package/bundled-test-harness/assets/spec-test-BhZDdhVQ.js +0 -1077
  995. package/bundled-test-harness/assets/spinner-CpIBUG9m.js +0 -49
  996. package/bundled-test-harness/assets/src-DGHttmW-.js +0 -216
  997. package/bundled-test-harness/assets/src-DaNDSbp7.js +0 -5
  998. package/bundled-test-harness/assets/stick-to-bottom-resize-test-Dpy3OVum.js +0 -56
  999. package/bundled-test-harness/assets/store-add-test-_IYS8o74.js +0 -50
  1000. package/bundled-test-harness/assets/store-module-rebuild-test-B5VMaICy.js +0 -454
  1001. package/bundled-test-harness/assets/store-search-test-C2VZabrH.js +0 -175
  1002. package/bundled-test-harness/assets/store-test-D6PObxoD.js +0 -3672
  1003. package/bundled-test-harness/assets/structured-theme-test-BHjVeMf-.js +0 -377
  1004. package/bundled-test-harness/assets/summarize-session-test-BFtTuhe0.js +0 -172
  1005. package/bundled-test-harness/assets/svg-image-def-test-BL6lkWUX.js +0 -167
  1006. package/bundled-test-harness/assets/switch-submode-test-6Uv3bZMl.js +0 -168
  1007. package/bundled-test-harness/assets/sync-openrouter-models-test-Dp9E05tL.js +0 -97
  1008. package/bundled-test-harness/assets/test-support-DYm8XZ0E.js +0 -3
  1009. package/bundled-test-harness/assets/test-support-DfnhiIMV.js +0 -99
  1010. package/bundled-test-harness/assets/tests-CZk0Iag2.js +0 -3596
  1011. package/bundled-test-harness/assets/text-file-def-test-CHdC0yIU.js +0 -94
  1012. package/bundled-test-harness/assets/text-input-validator-test-B9ZR8XPU.js +0 -156
  1013. package/bundled-test-harness/assets/text-suggestion-test-CGLspKFQ.js +0 -340
  1014. package/bundled-test-harness/assets/theme-card-test-CXZvSEvG.js +0 -621
  1015. package/bundled-test-harness/assets/theme-dashboard-nav-test-CkEE0ILk.js +0 -196
  1016. package/bundled-test-harness/assets/theme-scheme-island-test-URXTjipF.js +0 -264
  1017. package/bundled-test-harness/assets/titles-C6enAdIv.js +0 -2
  1018. package/bundled-test-harness/assets/titles-Dft1HoUT.js +0 -52
  1019. package/bundled-test-harness/assets/to-device-streaming-test-D33ZOc9o.js +0 -163
  1020. package/bundled-test-harness/assets/token-usage-test-BHQlU4J4.js +0 -160
  1021. package/bundled-test-harness/assets/tools-CrudqfS3.js +0 -774
  1022. package/bundled-test-harness/assets/tools-calling-test-jo7IREau.js +0 -200
  1023. package/bundled-test-harness/assets/tools-test-D1wMfUa0.js +0 -1624
  1024. package/bundled-test-harness/assets/tools-test-Dn1LYsXp.js +0 -3204
  1025. package/bundled-test-harness/assets/tooltip-8Wyz4IIn.css +0 -68
  1026. package/bundled-test-harness/assets/tooltip-CqwLzRz5.js +0 -134
  1027. package/bundled-test-harness/assets/transform-cards-test-BPhwPFtp.js +0 -341
  1028. package/bundled-test-harness/assets/ts-file-def-preview-test-Bq3zTgw8.js +0 -95
  1029. package/bundled-test-harness/assets/ts-file-def-test-GLswMl7O.js +0 -92
  1030. package/bundled-test-harness/assets/ttf-font-def-test-DQulvUWs.js +0 -206
  1031. package/bundled-test-harness/assets/turn-settling-test-BspmOUQP.js +0 -160
  1032. package/bundled-test-harness/assets/turn-summary-9A8nvC0-.js +0 -1039
  1033. package/bundled-test-harness/assets/unpublish-realm-test-SkYPEhDz.js +0 -102
  1034. package/bundled-test-harness/assets/update-room-skills-test-cTxb-WU6.js +0 -240
  1035. package/bundled-test-harness/assets/use-ai-assistant-test-uaqW1T_A.js +0 -384
  1036. package/bundled-test-harness/assets/user-message-BudkIP-3.js +0 -262
  1037. package/bundled-test-harness/assets/validate-realm-test-DxrGgH9n.js +0 -67
  1038. package/bundled-test-harness/assets/video-metadata-extractor-test-B2pe-Iqa.js +0 -520
  1039. package/bundled-test-harness/assets/view-visually-test-PNon6fUo.js +0 -335
  1040. package/bundled-test-harness/assets/virtual-network-reset-test-uYJLaQHf.js +0 -96
  1041. package/bundled-test-harness/assets/wav-audio-def-test-F4OrFFR4.js +0 -160
  1042. package/bundled-test-harness/assets/webp-image-def-test-B0a_-Vya.js +0 -226
  1043. package/bundled-test-harness/assets/workspace-Cyftysy9.js +0 -440
  1044. package/bundled-test-harness/assets/workspace-a11y-test-sKiPDcbl.js +0 -197
  1045. package/bundled-test-harness/assets/workspace-actions-BuawjFmZ.js +0 -561
  1046. package/bundled-test-harness/assets/workspace-behavior-test-CKa-pb3T.js +0 -338
  1047. package/bundled-test-harness/assets/workspace-delete-multiple-test-Dt2weG5R.js +0 -212
  1048. package/bundled-test-harness/assets/workspace-delete-summary-test-CkqgFqZ8.js +0 -63
  1049. package/bundled-test-harness/assets/workspace-hosting-test-Ci7EEtHP.js +0 -138
  1050. package/bundled-test-harness/assets/workspace-indexing-test-BPVxxY6W.js +0 -71
  1051. package/bundled-test-harness/assets/workspace-test-CWr7vFbg.js +0 -385
  1052. package/bundled-test-harness/assets/workspace-test-INNpQovc.js +0 -51
  1053. package/bundled-test-harness/assets/workspace-timestamp-labels-test-CigQb5wr.js +0 -68
  1054. package/bundled-test-harness/assets/workspace-unit-test-BwVKpuXT.js +0 -122
  1055. package/bundled-test-harness/assets/write-binary-file-test-BKP3gv1k.js +0 -124
  1056. package/bundled-test-harness/assets/write-text-file-test-B6ijTKTa.js +0 -191
  1057. package/bundled-test-harness/assets/zip-archive-test-C-PBzkTn.js +0 -285
  1058. package/bundled-test-harness/assets/zip-file-def-test-FyCzJT-9.js +0 -164
@@ -1,3672 +0,0 @@
1
- import { s as __toESM } from "./chunk-Rp0pCe6z.js";
2
- import { n as decorateMethodV2, r as initializeDeferredDecorator, t as decorateFieldV2 } from "./runtime--fcdnjmJ-BoCBNIsz.js";
3
- import { Br as testRealmURL, Co as SupportedMimeType, Ec as CardError, Jo as isCardInstance, Lr as testRRI, Qo as isFileDefInstance, Rc as Deferred, Xn as APP_BOXEL_REALM_EVENT_TYPE } from "./runtime-common-BTaLJEw-.js";
4
- import { B as localId, G as realmURL, w as baseCardRef } from "./constants-Icc0nFW-.js";
5
- import { wt as setComponentTemplate } from "./cache-DtDz7X5V-Wn8jRDfL.js";
6
- import { r as service } from "./service-LFpJ8EEP.js";
7
- import { H as templateFactory } from "./index-DaCZcoCY-CgzbilMy.js";
8
- import "./component-BJO47HTh.js";
9
- import { t as Component } from "./dist-CkA1rgqO.js";
10
- import { n as tracked, t as cached } from "./tracking-800VJb8b.js";
11
- import "./template-factory-ds9s0u8l.js";
12
- import { n as getCardCollection } from "./card-collection-BQMglA2Y.js";
13
- import { n as getCard } from "./card-resource-9nZR8YyO.js";
14
- import { t as OperatorModeContainer } from "./container-Cqcwrd-m.js";
15
- import { M as waitUntil, T as settled, a as find, d as click, o as waitFor, r as typeIn } from "./dist-BOAdzfkP.js";
16
- import { t as require_qunit } from "./qunit-C-Foo4Nd.js";
17
- import { $ as withSavesHeldOpen, F as setupLocalIndexing, I as setupOnSave, L as setupRealmCacheTeardown, M as setupCardLogs, P as setupIntegrationTestRealm, Z as withCachedRealmSetup, et as withSlowSave, lt as setupRenderingTest, ot as setupOperatorModeStateCleanup, t as setupMockMatrix, vt as registerDefaultRoutes, yt as registerRealmServerRoute } from "./mock-matrix-Dd8k0DNa.js";
18
- import { r as getService } from "./dist-CPfIHBla.js";
19
- import { A as field, H as linksTo, U as linksToMany, a as CardDef, d as FileDef, s as Component$1, w as contains } from "./card-api-Cc8uZunB.js";
20
- import "./file-api-BsT3Q6C9.js";
21
- import { t as BooleanField } from "./boolean-Dk3JuO7r.js";
22
- import { t as string_default } from "./string-5IAMEUit.js";
23
- import { n as renderComponent } from "./render-component-B15Z0e2v.js";
24
- //#region tests/integration/store-test.gts
25
- var import_qunit = /* @__PURE__ */ __toESM(require_qunit());
26
- (0, import_qunit.module)("Integration | Store", function(hooks) {
27
- setupRenderingTest(hooks);
28
- setupOperatorModeStateCleanup(hooks);
29
- let api;
30
- let loader;
31
- let loaderService;
32
- let testRealm;
33
- let testRealmAdapter;
34
- let storeService;
35
- let operatorModeStateService;
36
- let cardStore;
37
- let PersonDef;
38
- let BoomPersonDef;
39
- let EmployeeDef;
40
- let ManagerDef;
41
- let realmService;
42
- setupLocalIndexing(hooks);
43
- setupRealmCacheTeardown(hooks);
44
- setupOnSave(hooks);
45
- setupCardLogs(hooks, async () => await loader.import("@cardstack/base/card-api"));
46
- let mockMatrixUtils = setupMockMatrix(hooks, {
47
- loggedInAs: "@testuser:localhost",
48
- activeRealms: [testRealmURL],
49
- autostart: true
50
- });
51
- function forceGC() {
52
- cardStore.sweep(api);
53
- cardStore.sweep(api);
54
- }
55
- function setCardInOperatorModeState(cardURL, format = "isolated") {
56
- operatorModeStateService.restore({ stacks: cardURL ? [[{
57
- id: cardURL,
58
- format
59
- }]] : [[]] });
60
- }
61
- const noop = () => {};
62
- async function writePerson(path, name) {
63
- await testRealm.write(path, JSON.stringify({ data: {
64
- attributes: { name },
65
- meta: { adoptsFrom: {
66
- module: testRRI("person"),
67
- name: "Person"
68
- } }
69
- } }));
70
- }
71
- function interceptRealmEvents() {
72
- let messageService = getService("message-service");
73
- let deliver = messageService.relayRealmEvent.bind(messageService);
74
- let captured = [];
75
- messageService.relayRealmEvent = (event) => {
76
- captured.push(event);
77
- };
78
- function find(url) {
79
- return captured.find((event) => event.eventName === "index" && event.indexType === "incremental" && event.invalidations.includes(url));
80
- }
81
- return {
82
- deliver,
83
- async nextEventFor(url) {
84
- await waitUntil(() => find(url) !== void 0, {
85
- timeout: 1e4,
86
- timeoutMessage: `the realm broadcast no incremental index event naming ${url}; observed events: ${JSON.stringify(captured)}`
87
- });
88
- let event = find(url);
89
- captured.length = 0;
90
- return event;
91
- },
92
- restore() {
93
- messageService.relayRealmEvent = deliver;
94
- }
95
- };
96
- }
97
- function countCardReads(pathFragment) {
98
- let cardService = getService("card-service");
99
- let originalFetchJSON = cardService.fetchJSON.bind(cardService);
100
- let count = 0;
101
- cardService.fetchJSON = async (fetchUrl, args) => {
102
- if (String(fetchUrl).includes(pathFragment) && (args?.method ?? "GET") === "GET") count++;
103
- return originalFetchJSON(fetchUrl, args);
104
- };
105
- return {
106
- get count() {
107
- return count;
108
- },
109
- stop() {
110
- delete cardService.fetchJSON;
111
- }
112
- };
113
- }
114
- function withholdSource(pathFragment) {
115
- let loadCardDocument = cardStore.loadCardDocument.bind(cardStore);
116
- cardStore.loadCardDocument = async (url, opts) => {
117
- if (url.includes(pathFragment)) return new CardError(`${url} is withheld by this test`, { status: 404 });
118
- return loadCardDocument(url, opts);
119
- };
120
- }
121
- hooks.afterEach(function() {
122
- if (cardStore) delete cardStore.loadCardDocument;
123
- });
124
- async function settleCardRender(assert, id, selector, opts) {
125
- let start = performance.now();
126
- await settled();
127
- let elapsedMs = Math.round(performance.now() - start);
128
- if (!find(selector)) {
129
- let held = storeService.peek(id, { type: opts?.type });
130
- let error = storeService.peekError(id, { type: opts?.type });
131
- console.error([
132
- `[card-render-diag] ${selector} is not rendered after settled() (${elapsedMs}ms)`,
133
- `reference count: ${storeService.getReferenceCount(id)}`,
134
- `peek: ${held === void 0 ? "<nothing>" : isCardInstance(held) || isFileDefInstance(held) ? `instance ${held.id}` : `error ${JSON.stringify(held)}`}`,
135
- `peekError: ${error ? JSON.stringify(error) : "<none>"}`
136
- ].join("\n"));
137
- } else if (elapsedMs > 1e3) console.warn(`[card-render-diag] ${selector} took ${elapsedMs}ms to load and render`);
138
- assert.dom(selector).exists(`${id} is rendered`);
139
- }
140
- hooks.beforeEach(async function() {
141
- class Person extends CardDef {
142
- static {
143
- decorateFieldV2(this.prototype, "name", [field], function() {
144
- return contains(string_default);
145
- });
146
- }
147
- #name = (initializeDeferredDecorator(this, "name"), void 0);
148
- static {
149
- decorateFieldV2(this.prototype, "hasError", [field], function() {
150
- return contains(BooleanField);
151
- });
152
- }
153
- #hasError = (initializeDeferredDecorator(this, "hasError"), void 0);
154
- static {
155
- decorateFieldV2(this.prototype, "bestFriend", [field], function() {
156
- return linksTo(() => Person);
157
- });
158
- }
159
- #bestFriend = (initializeDeferredDecorator(this, "bestFriend"), void 0);
160
- static {
161
- decorateFieldV2(this.prototype, "friends", [field], function() {
162
- return linksToMany(() => Person);
163
- });
164
- }
165
- #friends = (initializeDeferredDecorator(this, "friends"), void 0);
166
- static {
167
- decorateFieldV2(this.prototype, "boom", [field], function() {
168
- return contains(string_default, { computeVia: function() {
169
- if (this.hasError) throw new Error("intentional error thrown");
170
- return "boom";
171
- } });
172
- });
173
- }
174
- #boom = (initializeDeferredDecorator(this, "boom"), void 0);
175
- }
176
- PersonDef = Person;
177
- class BoomPerson extends CardDef {
178
- static displayName = "Boom Person";
179
- static {
180
- decorateFieldV2(this.prototype, "name", [field], function() {
181
- return contains(string_default);
182
- });
183
- }
184
- #name = (initializeDeferredDecorator(this, "name"), void 0);
185
- static isolated = class Isolated extends Component$1 {
186
- static {
187
- setComponentTemplate(templateFactory({
188
- "id": "I6b4/CsV",
189
- "block": "[[[1,\"Hello\\n\"],[8,[30,1,[\"name\"]],null,null,null],[1,\"!\\n\"],[1,[30,0,[\"boom\"]]]],[\"@fields\"],[]]",
190
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
191
- "isStrictMode": true
192
- }), this);
193
- }
194
- boom = () => intentionallyNotDefined();
195
- };
196
- }
197
- BoomPersonDef = BoomPerson;
198
- class Employee extends CardDef {
199
- static displayName = "Employee";
200
- static {
201
- decorateFieldV2(this.prototype, "name", [field], function() {
202
- return contains(string_default);
203
- });
204
- }
205
- #name = (initializeDeferredDecorator(this, "name"), void 0);
206
- static isolated = class Isolated extends Component$1 {
207
- static {
208
- setComponentTemplate(templateFactory({
209
- "id": "TyvrA1L5",
210
- "block": "[[[10,0],[14,\"data-test-employee-badge\",\"\"],[12],[1,\"Employee: \"],[8,[30,1,[\"name\"]],null,null,null],[13]],[\"@fields\"],[]]",
211
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
212
- "isStrictMode": true
213
- }), this);
214
- }
215
- };
216
- }
217
- EmployeeDef = Employee;
218
- class Manager extends Employee {
219
- static displayName = "Manager";
220
- static isolated = class Isolated extends Component$1 {
221
- static {
222
- setComponentTemplate(templateFactory({
223
- "id": "3Gw4m0Y6",
224
- "block": "[[[10,0],[14,\"data-test-manager-badge\",\"\"],[12],[1,\"Manager: \"],[8,[30,1,[\"name\"]],null,null,null],[13]],[\"@fields\"],[]]",
225
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
226
- "isStrictMode": true
227
- }), this);
228
- }
229
- };
230
- }
231
- ManagerDef = Manager;
232
- loaderService = getService("loader-service");
233
- loader = loaderService.loader;
234
- api = await loader.import("@cardstack/base/card-api");
235
- storeService = getService("store");
236
- operatorModeStateService = getService("operator-mode-state-service");
237
- cardStore = storeService.store;
238
- realmService = getService("realm");
239
- await withCachedRealmSetup(async () => {
240
- ({adapter: testRealmAdapter, realm: testRealm} = await setupIntegrationTestRealm({
241
- mockMatrixUtils,
242
- contents: {
243
- "person.gts": { Person },
244
- "boom-person.gts": { BoomPerson },
245
- "employee.gts": { Employee },
246
- "manager.gts": { Manager },
247
- "Person/hassan.json": new Person({ name: "Hassan" }),
248
- "Person/jade.json": new Person({ name: "Jade" }),
249
- "Person/queenzy.json": new Person({ name: "Queenzy" }),
250
- "Person/germaine.json": new Person({ name: "Germaine" }),
251
- "Person/boris.json": new Person({ name: "Boris" })
252
- }
253
- }));
254
- });
255
- await realmService.login(testRealmURL);
256
- });
257
- hooks.afterEach(function() {
258
- getService("network").virtualNetwork.removeRealmMapping("@test-prefix/");
259
- });
260
- (0, import_qunit.test)("can peek a card instance", async function(assert) {
261
- storeService.addReference(`${testRealmURL}Person/hassan`);
262
- await storeService.flush();
263
- let instance = storeService.peek(`${testRealmURL}Person/hassan`);
264
- assert.true(isCardInstance(instance), "peeked item is a card instance");
265
- });
266
- (0, import_qunit.test)("can peek a card by local id", async function(assert) {
267
- storeService.addReference(`${testRealmURL}Person/hassan`);
268
- await storeService.flush();
269
- let instanceA = storeService.peek(`${testRealmURL}Person/hassan`);
270
- let instanceB = storeService.peek(instanceA[localId]);
271
- assert.true(isCardInstance(instanceB), "peeked item is a card instance");
272
- assert.strictEqual(instanceA, instanceB, "the same instance is returned by both remote ID and local ID");
273
- });
274
- (0, import_qunit.test)("can peek a card error when no stale instance exists", async function(assert) {
275
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
276
- attributes: {
277
- name: "Hassan",
278
- hasError: true
279
- },
280
- meta: { adoptsFrom: {
281
- module: testRRI("person"),
282
- name: "Person"
283
- } }
284
- } }));
285
- storeService.addReference(`${testRealmURL}Person/hassan`);
286
- await storeService.flush();
287
- let error = storeService.peek(`${testRealmURL}Person/hassan`);
288
- assert.false(isCardInstance(error), "error is not a card instance");
289
- assert.ok(error.message.includes("intentional error thrown"), "error message is correct");
290
- });
291
- (0, import_qunit.test)("peek returns a stale instance when the server state reflects an error", async function(assert) {
292
- storeService.addReference(`${testRealmURL}Person/hassan`);
293
- await storeService.flush();
294
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
295
- attributes: {
296
- name: "Hassan",
297
- hasError: true
298
- },
299
- meta: { adoptsFrom: {
300
- module: testRRI("person"),
301
- name: "Person"
302
- } }
303
- } }));
304
- await waitUntil(() => storeService.peekError(`${testRealmURL}Person/hassan`));
305
- let staleInstance = storeService.peek(`${testRealmURL}Person/hassan`);
306
- assert.true(isCardInstance(staleInstance), "the peek-ed instance is not an error");
307
- });
308
- (0, import_qunit.test)("peek for an uncached returns undefined", async function(assert) {
309
- let instance = storeService.peek(`${testRealmURL}Person/does-not-exist`);
310
- assert.strictEqual(instance, void 0, "instance is undefined");
311
- });
312
- (0, import_qunit.test)("can use registered prefix ids across store APIs", async function(assert) {
313
- getService("network").virtualNetwork.addRealmMapping("@test-prefix/", testRealmURL);
314
- storeService.addReference("@test-prefix/Person/hassan");
315
- await storeService.flush();
316
- let byPrefix = storeService.peek("@test-prefix/Person/hassan");
317
- let byUrl = storeService.peek(`${testRealmURL}Person/hassan`);
318
- assert.true(isCardInstance(byPrefix), "prefix id resolves to a card");
319
- assert.strictEqual(byPrefix, byUrl, "prefix id and resolved URL return the same instance");
320
- assert.strictEqual(storeService.getReferenceCount("@test-prefix/Person/hassan"), 1, "prefix id and resolved URL share a single reference count");
321
- assert.strictEqual(storeService.getReferenceCount(`${testRealmURL}Person/hassan`), 1, "resolved URL sees the same reference count");
322
- storeService.dropReference("@test-prefix/Person/hassan");
323
- assert.strictEqual(storeService.getReferenceCount(`${testRealmURL}Person/hassan`), 0, "dropping a prefix reference clears the resolved URL reference count");
324
- let countsDuringSave;
325
- this.onSave((url) => {
326
- if (url.href === `${testRealmURL}Person/hassan`) countsDuringSave = {
327
- url: storeService.getReferenceCount(`${testRealmURL}Person/hassan`),
328
- prefix: storeService.getReferenceCount("@test-prefix/Person/hassan")
329
- };
330
- });
331
- storeService.save("@test-prefix/Person/hassan");
332
- await settled();
333
- let saveError = storeService.getSaveState(byPrefix[localId])?.lastSaveError;
334
- assert.strictEqual(saveError, void 0, `save() persists the card${saveError ? `: ${saveError instanceof Error ? saveError.message : JSON.stringify(saveError)}` : ""}`);
335
- assert.deepEqual(countsDuringSave, {
336
- url: 1,
337
- prefix: 1
338
- }, "save() holds exactly one reference while it runs, read the same through the prefix id and the resolved URL");
339
- assert.strictEqual(storeService.getReferenceCount("@test-prefix/Person/hassan"), 0, "save() releases its hold once it lands");
340
- storeService.addReference("@test-prefix/Person/boris");
341
- await storeService.flush();
342
- await storeService.delete("@test-prefix/Person/boris");
343
- assert.strictEqual(storeService.peek("@test-prefix/Person/boris"), void 0, "delete() clears the prefix-form card identity from the store");
344
- assert.strictEqual(storeService.peek(`${testRealmURL}Person/boris`), void 0, "delete() clears the resolved card identity from the store");
345
- let file = await testRealmAdapter.openFile(`Person/boris.json`);
346
- assert.strictEqual(file, void 0, "delete() removes the remote card");
347
- });
348
- (0, import_qunit.test)("deleting a linked target rewrites a loaded consumer linksTo slot to a broken-link sentinel", async function(assert) {
349
- storeService.addReference(`${testRealmURL}Person/hassan`);
350
- storeService.addReference(`${testRealmURL}Person/boris`);
351
- await storeService.flush();
352
- let hassan = storeService.peek(`${testRealmURL}Person/hassan`);
353
- hassan.bestFriend = storeService.peek(`${testRealmURL}Person/boris`);
354
- await settled();
355
- assert.strictEqual(api.getRelationshipMembershipState(hassan, "bestFriend").membership[0].kind, "present", "the consumer link resolves to the target before the delete");
356
- await storeService.delete(`${testRealmURL}Person/boris`);
357
- let after = api.getRelationshipMembershipState(hassan, "bestFriend").membership[0];
358
- assert.strictEqual(after.kind, "not-found", "deleting the target rewrites the consumer slot to a broken-link sentinel without a reload");
359
- assert.strictEqual(after.reference, `${testRealmURL}Person/boris`, "the sentinel preserves the deleted target reference for the placeholder");
360
- });
361
- (0, import_qunit.test)("deleting a linked target rewrites only the matching element of a loaded consumer linksToMany slot", async function(assert) {
362
- storeService.addReference(`${testRealmURL}Person/hassan`);
363
- storeService.addReference(`${testRealmURL}Person/boris`);
364
- storeService.addReference(`${testRealmURL}Person/jade`);
365
- await storeService.flush();
366
- let hassan = storeService.peek(`${testRealmURL}Person/hassan`);
367
- let boris = storeService.peek(`${testRealmURL}Person/boris`);
368
- hassan.friends = [storeService.peek(`${testRealmURL}Person/jade`), boris];
369
- await settled();
370
- let before = api.getRelationshipMembershipState(hassan, "friends").membership;
371
- assert.deepEqual(before.map((s) => s.kind), ["present", "present"], "both linksToMany elements resolve before the delete");
372
- await storeService.delete(`${testRealmURL}Person/boris`);
373
- let after = api.getRelationshipMembershipState(hassan, "friends").membership;
374
- let borisEntry = after.find((s) => s.reference === `${testRealmURL}Person/boris`);
375
- let jadeEntry = after.find((s) => s.reference === `${testRealmURL}Person/jade`);
376
- assert.strictEqual(borisEntry?.kind, "not-found", "the deleted element becomes a broken-link sentinel");
377
- assert.strictEqual(jadeEntry?.kind, "present", "the surviving element is left untouched");
378
- });
379
- (0, import_qunit.test)("peekError returns the server state error when a stale instance exists", async function(assert) {
380
- storeService.addReference(`${testRealmURL}Person/hassan`);
381
- await storeService.flush();
382
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
383
- attributes: {
384
- name: "Hassan",
385
- hasError: true
386
- },
387
- meta: { adoptsFrom: {
388
- module: testRRI("person"),
389
- name: "Person"
390
- } }
391
- } }));
392
- await waitUntil(() => storeService.peekError(`${testRealmURL}Person/hassan`));
393
- let error = storeService.peekError(`${testRealmURL}Person/hassan`);
394
- assert.false(isCardInstance(error), "error is not a card instance");
395
- assert.ok(error.message.includes("intentional error thrown"), "error message is correct");
396
- });
397
- (0, import_qunit.test)("can add reference to a card url", async function(assert) {
398
- let instance = storeService.peek(`${testRealmURL}hassan`);
399
- assert.strictEqual(instance, void 0, "instance is not in store yet");
400
- storeService.addReference(`${testRealmURL}Person/hassan`);
401
- await storeService.flush();
402
- instance = storeService.peek(`${testRealmURL}Person/hassan`);
403
- if (isCardInstance(instance)) assert.strictEqual(instance.name, "Hassan", "instance is cached in store");
404
- else assert.ok(false, `expected instance to be a card:${JSON.stringify(instance, null, 2)}`);
405
- forceGC();
406
- instance = storeService.peek(`${testRealmURL}Person/hassan`);
407
- if (isCardInstance(instance)) assert.strictEqual(instance.name, "Hassan", "instance is cached in store after GC");
408
- else assert.ok(false, `expected instance to be a card:${JSON.stringify(instance, null, 2)} after GC`);
409
- });
410
- (0, import_qunit.test)("can add reference to a local id", async function(assert) {
411
- let instance = new PersonDef({ name: "Andrea" });
412
- await storeService.addWithoutPersisting(instance);
413
- storeService.addReference(instance[localId]);
414
- forceGC();
415
- let peekedInstance = storeService.peek(instance[localId]);
416
- assert.strictEqual(peekedInstance, instance, "instance is not garbage collected");
417
- });
418
- (0, import_qunit.test)("a render-context load does not set up the autosave change subscription", async function(assert) {
419
- let cardService = getService("card-service");
420
- let originalGetAPI = cardService.getAPI.bind(cardService);
421
- let realApi = await originalGetAPI();
422
- let trueSubscribe = realApi.subscribeToChanges;
423
- let subscribeCount = 0;
424
- cardService.getAPI = async () => new Proxy(realApi, { get(target, prop, receiver) {
425
- if (prop === "subscribeToChanges") return (...args) => {
426
- subscribeCount++;
427
- return trueSubscribe(...args);
428
- };
429
- return Reflect.get(target, prop, receiver);
430
- } });
431
- try {
432
- await storeService.addWithoutPersisting(new PersonDef({ name: "Mango" }));
433
- assert.true(subscribeCount > 0, "the live store subscribes a loaded instance for autosave");
434
- subscribeCount = 0;
435
- globalThis.__boxelRenderContext = true;
436
- await getService("render-store").addWithoutPersisting(new PersonDef({ name: "Van Gogh" }));
437
- assert.strictEqual(subscribeCount, 0, "the render store does not subscribe a loaded instance for autosave");
438
- } finally {
439
- cardService.getAPI = originalGetAPI;
440
- delete globalThis.__boxelRenderContext;
441
- }
442
- });
443
- (0, import_qunit.test)("a card render absorbs a blocked write, a headless command reports it", async function(assert) {
444
- globalThis.__boxelPrerenderApp = true;
445
- try {
446
- let rendered = new PersonDef({ name: "Andrea" });
447
- assert.strictEqual(await storeService.add(rendered), rendered, "a render keeps the instance rather than failing");
448
- globalThis.__boxelHeadlessCommand = true;
449
- await assert.rejects(storeService.add(new PersonDef({ name: "Van Gogh" })), /persistence block still raised/, "a command reports the blocked write");
450
- let ephemeral = new PersonDef({ name: "Mango" });
451
- assert.strictEqual(await storeService.addWithoutPersisting(ephemeral), ephemeral, "a memory-only add is served as asked");
452
- } finally {
453
- delete globalThis.__boxelHeadlessCommand;
454
- delete globalThis.__boxelPrerenderApp;
455
- }
456
- });
457
- (0, import_qunit.test)("restoring sessions from storage skips the re-walk when the session blob is unchanged", function(assert) {
458
- let walks = 0;
459
- let originalGetOrCreate = realmService.getOrCreateRealmResource.bind(realmService);
460
- realmService.getOrCreateRealmResource = (...args) => {
461
- walks++;
462
- return originalGetOrCreate(...args);
463
- };
464
- try {
465
- realmService.lastRestoredSessionsString = void 0;
466
- let before = walks;
467
- realmService.restoreSessionsFromStorage();
468
- assert.true(walks - before > 0, "the first restore walks the stored sessions");
469
- before = walks;
470
- realmService.restoreSessionsFromStorage();
471
- assert.strictEqual(walks - before, 0, "a restore with an unchanged blob does not re-walk");
472
- realmService.lastRestoredSessionsString = "stale-sentinel";
473
- before = walks;
474
- realmService.restoreSessionsFromStorage();
475
- assert.true(walks - before > 0, "a restore re-walks once the stored blob no longer matches the memo");
476
- } finally {
477
- realmService.getOrCreateRealmResource = originalGetOrCreate;
478
- }
479
- });
480
- (0, import_qunit.test)("getFields is memoized per instance in the render context and invalidates as the instance grows", function(assert) {
481
- let person = new PersonDef({ name: "Mango" });
482
- try {
483
- globalThis.__boxelRenderContext = true;
484
- let first = api.getFields(person, { usedLinksToFieldsOnly: true });
485
- let second = api.getFields(person, { usedLinksToFieldsOnly: true });
486
- assert.strictEqual(first, second, "a repeat call in the render context returns the memoized field map");
487
- assert.notOk("bestFriend" in first, "an unused linksTo field is absent before it is populated");
488
- person.bestFriend = new PersonDef({ name: "Van Gogh" });
489
- let third = api.getFields(person, { usedLinksToFieldsOnly: true });
490
- assert.notStrictEqual(third, first, "growing the instance invalidates the memo");
491
- assert.ok("bestFriend" in third, "the now-used linksTo field appears after the bucket grows");
492
- delete globalThis.__boxelRenderContext;
493
- let live1 = api.getFields(person, { usedLinksToFieldsOnly: true });
494
- let live2 = api.getFields(person, { usedLinksToFieldsOnly: true });
495
- assert.notStrictEqual(live1, live2, "the live app always gets a fresh field map");
496
- } finally {
497
- delete globalThis.__boxelRenderContext;
498
- }
499
- });
500
- (0, import_qunit.test)("can drop reference to a card url", async function(assert) {
501
- storeService.addReference(`${testRealmURL}Person/hassan`);
502
- await storeService.flush();
503
- let instance = storeService.peek(`${testRealmURL}Person/hassan`);
504
- assert.ok(instance, "instance is in store");
505
- storeService.dropReference(`${testRealmURL}Person/hassan`);
506
- forceGC();
507
- assert.strictEqual(storeService.peek(`${testRealmURL}Person/hassan`), void 0, "instance has been garbage collected from the store");
508
- });
509
- (0, import_qunit.test)("can drop reference to a local id", async function(assert) {
510
- let instance = new PersonDef({ name: "Andrea" });
511
- await storeService.addWithoutPersisting(instance);
512
- storeService.addReference(instance[localId]);
513
- storeService.dropReference(instance[localId]);
514
- forceGC();
515
- let peekedInstance = storeService.peek(instance[localId]);
516
- assert.strictEqual(peekedInstance, void 0, "instance is garbage collected");
517
- });
518
- (0, import_qunit.test)("file-meta instance is retained when referenced", async function(assert) {
519
- await testRealm.write("hero.png", "mock hero image");
520
- let fileUrl = `${testRealmURL}hero.png`;
521
- let fileInstance = await storeService.get(fileUrl, { type: "file-meta" });
522
- assert.ok(fileInstance, "file meta instance is loaded");
523
- assert.ok(fileInstance.constructor?.isFileDef, "file meta instance is a FileDef");
524
- storeService.addReference(fileUrl);
525
- forceGC();
526
- let peekedInstance = cardStore.getFileMeta(fileUrl);
527
- assert.strictEqual(peekedInstance, fileInstance, "file meta instance is retained after GC with reference");
528
- });
529
- (0, import_qunit.test)("file-meta instance is garbage collected when references drop", async function(assert) {
530
- await testRealm.write("hero.png", "mock hero image");
531
- let fileUrl = `${testRealmURL}hero.png`;
532
- await storeService.get(fileUrl, { type: "file-meta" });
533
- storeService.addReference(fileUrl);
534
- storeService.dropReference(fileUrl);
535
- forceGC();
536
- assert.strictEqual(cardStore.getFileMeta(fileUrl), void 0, "file meta instance is garbage collected after reference drop");
537
- });
538
- (0, import_qunit.test)("realm subscription is removed when file-meta reference count drops to zero", async function(assert) {
539
- await testRealm.write("hero.png", "mock hero image");
540
- let fileUrl = `${testRealmURL}hero.png`;
541
- let subscriptions = storeService.subscriptions;
542
- assert.false(subscriptions.has(testRealmURL), "realm is not subscribed before adding file-meta reference");
543
- storeService.addReference(fileUrl, { type: "file-meta" });
544
- assert.true(subscriptions.has(testRealmURL), "realm subscription is created for file-meta reference");
545
- storeService.dropReference(fileUrl);
546
- assert.false(subscriptions.has(testRealmURL), "realm subscription is removed when file-meta reference reaches zero");
547
- });
548
- (0, import_qunit.test)("add stores FileDef dependencies", async function(assert) {
549
- class FileCard extends CardDef {
550
- static {
551
- decorateFieldV2(this.prototype, "attachment", [field], function() {
552
- return linksTo(FileDef);
553
- });
554
- }
555
- #attachment = (initializeDeferredDecorator(this, "attachment"), void 0);
556
- }
557
- let fileUrl = `${testRealmURL}hero.png`;
558
- let fileDef = new FileDef({
559
- id: fileUrl,
560
- sourceUrl: fileUrl,
561
- url: fileUrl,
562
- name: "hero.png",
563
- contentType: "image/png"
564
- });
565
- let card = new FileCard({ attachment: fileDef });
566
- await storeService.addWithoutPersisting(card);
567
- assert.strictEqual(storeService.peek(fileUrl, { type: "file-meta" }), fileDef, "file meta dependency is cached in file-meta store");
568
- });
569
- (0, import_qunit.test)("card read of a binary file URL is rerouted to file-meta", async function(assert) {
570
- await testRealm.write("hero.png", "mock hero image");
571
- let fileUrl = `${testRealmURL}hero.png`;
572
- let result = await storeService.get(fileUrl);
573
- assert.ok(result.constructor?.isFileDef, "card read returns a FileDef via the safety-net reroute");
574
- let fileInstance = await storeService.get(fileUrl, { type: "file-meta" });
575
- assert.ok(fileInstance.constructor?.isFileDef, "file-meta read returns a FileDef");
576
- assert.strictEqual(storeService.peekError(fileUrl), void 0, "no error cached on the card bucket");
577
- assert.strictEqual(storeService.peekError(fileUrl, { type: "file-meta" }), void 0, "no error cached on the file-meta bucket");
578
- });
579
- (0, import_qunit.test)("a file the realm does not hold is reported as a missing file", async function(assert) {
580
- let missingFileUrl = `${testRealmURL}missing.png`;
581
- let error = await storeService.get(missingFileUrl, { type: "file-meta" });
582
- assert.strictEqual(error.status, 404, "the error carries the HTTP status");
583
- assert.strictEqual(error.title, "File Not Found", "a missing file is titled as a missing file, not a missing card");
584
- assert.strictEqual(error.message, `The file ${missingFileUrl} does not exist`, "the message names a file, not a card");
585
- });
586
- (0, import_qunit.test)("garbage collects cards that only consume each other", async function(assert) {
587
- let alpha = new PersonDef({ name: "Alpha" });
588
- let beta = new PersonDef({ name: "Beta" });
589
- alpha.bestFriend = beta;
590
- beta.bestFriend = alpha;
591
- await storeService.addWithoutPersisting(alpha);
592
- await storeService.addWithoutPersisting(beta);
593
- assert.strictEqual(storeService.peek(alpha[localId]), alpha, "alpha is present before GC");
594
- assert.strictEqual(storeService.peek(beta[localId]), beta, "beta is present before GC");
595
- forceGC();
596
- assert.strictEqual(storeService.peek(alpha[localId]), void 0, "alpha is garbage collected");
597
- assert.strictEqual(storeService.peek(beta[localId]), void 0, "beta is garbage collected");
598
- });
599
- (0, import_qunit.test)("can manually save an instance", async function(assert) {
600
- assert.expect(2);
601
- storeService.addReference(`${testRealmURL}Person/hassan`);
602
- await storeService.flush();
603
- this.onSave((url, doc) => {
604
- assert.strictEqual(url.href, `${testRealmURL}Person/hassan`, "the saved card id is correct");
605
- assert.strictEqual(doc.data.attributes?.name, "Hassan", "save data is correct");
606
- });
607
- storeService.save(`${testRealmURL}Person/hassan`);
608
- });
609
- (0, import_qunit.test)("can create an instance", async function(assert) {
610
- let url = await storeService.create({ data: {
611
- attributes: { name: "Andrea" },
612
- meta: { adoptsFrom: {
613
- module: testRRI("person"),
614
- name: "Person"
615
- } }
616
- } });
617
- assert.strictEqual(typeof url, "string", "received a url for new instance");
618
- let instance = storeService.peek(url);
619
- assert.strictEqual(instance.id, url);
620
- assert.strictEqual(instance.name, "Andrea");
621
- let file = await testRealmAdapter.openFile(`${instance.id.substring(testRealmURL.length)}.json`);
622
- assert.ok(file, "file exists");
623
- let fileJSON = JSON.parse(file.content);
624
- assert.strictEqual(fileJSON.data.attributes.name, "Andrea", "file exists");
625
- });
626
- (0, import_qunit.test)("can handle card error when creating an instance", async function(assert) {
627
- let error = await storeService.create({ data: {
628
- attributes: {
629
- name: "Andrea",
630
- hasError: true
631
- },
632
- meta: { adoptsFrom: {
633
- module: testRRI("person"),
634
- name: "Person"
635
- } }
636
- } });
637
- assert.strictEqual(typeof error, "object", "received a error for new instance");
638
- assert.ok(error.message.includes("intentional error thrown", "the error message is correct"));
639
- });
640
- (0, import_qunit.test)("can handle a rendering card error when creating an instance", async function(assert) {
641
- let instance = new BoomPersonDef({ name: "Andrea" });
642
- let error = await storeService.add(instance, { realm: testRealmURL });
643
- storeService.addReference(instance[localId]);
644
- await storeService.flush();
645
- let stale = storeService.peek(instance[localId]);
646
- if (isCardInstance(stale)) assert.strictEqual(stale.name, "Andrea", "the stale card state is correct");
647
- else assert.ok(false, `expected an instance but got a card error: "${stale.message}"`);
648
- let peekedError = storeService.peekError(instance[localId]);
649
- assert.strictEqual(peekedError, error, "the output of store.add is the peek-ed error");
650
- if (!isCardInstance(error)) {
651
- assert.strictEqual(error.id, instance[localId], "the error doc id is the local id of the instance");
652
- assert.ok(error.message.includes("intentionallyNotDefined is not defined"));
653
- loaderService.resetLoader();
654
- await testRealm.write(`boom-person.gts`, `
655
- import { contains, field, CardDef, Component, StringField } from '@cardstack/base/card-api';
656
-
657
- export class BoomPerson extends CardDef {
658
- static displayName = 'Boom Person';
659
- @field name = contains(StringField);
660
- static isolated = class Isolated extends Component<typeof this> {
661
- <template>
662
- Hello
663
- <@fields.firstName />!
664
- </template>
665
- };
666
- }
667
- `.trim());
668
- await waitUntil(() => !storeService.peekError(instance[localId]), { timeout: 5e3 });
669
- await waitUntil(() => {
670
- let card = storeService.peek(instance[localId]);
671
- return Boolean(card && isCardInstance(card));
672
- }, { timeout: 5e3 });
673
- let peek = storeService.peek(instance[localId]);
674
- assert.strictEqual(peek.name, "Andrea", "peek-ed value has been updated to be the fixed card instance");
675
- } else assert.ok(false, "expected a card error but got a running instance");
676
- });
677
- (0, import_qunit.test)("can add a running instance to the store", async function(assert) {
678
- assert.expect(5);
679
- this.onSave((_, doc) => {
680
- assert.strictEqual(doc.data.attributes?.name, "Andrea", "card data is correct");
681
- });
682
- let instance = new PersonDef({ name: "Andrea" });
683
- await storeService.add(instance);
684
- assert.ok(instance.id, "instance has been assigned remote id");
685
- let peekedInstance = storeService.peek(instance.id);
686
- assert.strictEqual(instance, peekedInstance, "instance is the same");
687
- let file = await testRealmAdapter.openFile(`${instance.id.substring(testRealmURL.length)}.json`);
688
- assert.ok(file, "file exists");
689
- let fileJSON = JSON.parse(file.content);
690
- assert.strictEqual(fileJSON.data.attributes.name, "Andrea", "file exists");
691
- });
692
- (0, import_qunit.test)("add() does not persist an existing card when the realm is read-only", async function(assert) {
693
- storeService.realm.permissions = () => ({
694
- get canRead() {
695
- return true;
696
- },
697
- get canWrite() {
698
- return false;
699
- }
700
- });
701
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
702
- let writes = [];
703
- this.onSave((url) => writes.push(url.href));
704
- instance.name = "Hassan Updated";
705
- let result = await storeService.add(instance);
706
- await settled();
707
- assert.deepEqual(writes, [], "no write is attempted without permission");
708
- assert.true(isCardInstance(result), "add() still resolves with the instance rather than a permission error");
709
- let file = await testRealmAdapter.openFile("Person/hassan.json");
710
- assert.strictEqual(JSON.parse(file.content).data.attributes.name, "Hassan", "the durable document is untouched");
711
- });
712
- (0, import_qunit.test)("add() reports its save in the card save state", async function(assert) {
713
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
714
- instance.name = "Hassan Updated";
715
- await storeService.add(instance);
716
- let saveState = storeService.getSaveState(instance.id);
717
- assert.false(saveState.hasUnsavedChanges, "the card no longer reports unsaved changes");
718
- assert.ok(saveState.lastSaved, "lastSaved reflects the add()-driven save");
719
- assert.strictEqual(saveState.lastSaveError, void 0, "no save error is reported");
720
- assert.false(saveState.isSaving, "the save is no longer in flight");
721
- });
722
- (0, import_qunit.test)("add() records a persistence failure in the card save state", async function(assert) {
723
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
724
- instance.name = "Hassan Updated";
725
- let store = storeService;
726
- store.saveCardDocument = async () => {
727
- throw new Error("intentional persistence failure");
728
- };
729
- try {
730
- await storeService.add(instance);
731
- } finally {
732
- delete store.saveCardDocument;
733
- }
734
- let saveState = storeService.getSaveState(instance.id);
735
- assert.ok(saveState.lastSaveError, "the failure is visible to the save indicator, not only to the caller");
736
- assert.false(saveState.isSaving, "the save is no longer in flight");
737
- });
738
- (0, import_qunit.test)("add() awaits durable persistence for an existing card", async function(assert) {
739
- let queenzy = await storeService.get(`${testRealmURL}Person/queenzy`);
740
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
741
- instance.name = "Hassan Updated";
742
- instance.bestFriend = queenzy;
743
- let result = await storeService.add(instance);
744
- assert.true(isCardInstance(result), "add() resolves with the card instance");
745
- let file = await testRealmAdapter.openFile("Person/hassan.json");
746
- let fileJSON = JSON.parse(file.content);
747
- assert.strictEqual(fileJSON.data.attributes.name, "Hassan Updated", "the scalar mutation is durable as soon as add() resolves");
748
- assert.ok(fileJSON.data.relationships.bestFriend.links.self.endsWith("queenzy"), "the link mutation is durable as soon as add() resolves");
749
- });
750
- (0, import_qunit.test)("add() stays pending until an existing card is durably persisted", async function(assert) {
751
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
752
- instance.name = "Hassan Updated";
753
- let store = storeService;
754
- let gate = new Deferred();
755
- let originalPersist = store.persistAndUpdate;
756
- store.persistAndUpdate = async (...args) => {
757
- await gate.promise;
758
- return await originalPersist.call(store, ...args);
759
- };
760
- try {
761
- let resolved = false;
762
- let addPromise = storeService.add(instance).then((r) => {
763
- resolved = true;
764
- return r;
765
- });
766
- for (let i = 0; i < 10; i++) await Promise.resolve();
767
- assert.false(resolved, "add() has not resolved while persistence is gated");
768
- gate.fulfill();
769
- await addPromise;
770
- assert.true(resolved, "add() resolves once persistence completes");
771
- } finally {
772
- delete store.persistAndUpdate;
773
- }
774
- let file = await testRealmAdapter.openFile("Person/hassan.json");
775
- assert.strictEqual(JSON.parse(file.content).data.attributes.name, "Hassan Updated", "the mutation is durably persisted");
776
- });
777
- (0, import_qunit.test)("add() surfaces persistence failures for an existing card", async function(assert) {
778
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
779
- instance.name = "Hassan Updated";
780
- let store = storeService;
781
- store.saveCardDocument = async () => {
782
- throw new Error("intentional persistence failure");
783
- };
784
- let result;
785
- try {
786
- result = await storeService.add(instance);
787
- } finally {
788
- delete store.saveCardDocument;
789
- }
790
- assert.false(isCardInstance(result), "add() resolves with a card error rather than the instance when persistence fails");
791
- assert.ok(result.message.includes("intentional persistence failure"), "the persistence error propagates to the caller instead of being swallowed");
792
- });
793
- (0, import_qunit.test)("can add a serialized instance to the store", async function(assert) {
794
- assert.expect(6);
795
- this.onSave((_, doc) => {
796
- assert.strictEqual(doc.data.attributes?.name, "Andrea", "card data is correct");
797
- });
798
- let instance = await storeService.add({ data: {
799
- attributes: { name: "Andrea" },
800
- meta: { adoptsFrom: {
801
- module: testRRI("person"),
802
- name: "Person"
803
- } }
804
- } });
805
- assert.ok(instance.id, "instance has been assigned remote id");
806
- let peekedInstance = storeService.peek(instance.id);
807
- assert.strictEqual(instance, peekedInstance, "instance is the same");
808
- assert.strictEqual(instance.name, "Andrea", "instance data is correct");
809
- let file = await testRealmAdapter.openFile(`${instance.id.substring(testRealmURL.length)}.json`);
810
- assert.ok(file, "file exists");
811
- let fileJSON = JSON.parse(file.content);
812
- assert.strictEqual(fileJSON.data.attributes.name, "Andrea", "file exists");
813
- });
814
- (0, import_qunit.test)("can skip saving when adding to the store", async function(assert) {
815
- assert.expect(3);
816
- this.onSave(() => {
817
- assert.ok(false, "save should not happen");
818
- });
819
- let instance = await storeService.addWithoutPersisting({ data: {
820
- attributes: { name: "Andrea" },
821
- meta: { adoptsFrom: {
822
- module: testRRI("person"),
823
- name: "Person"
824
- } }
825
- } }, {});
826
- assert.strictEqual(instance.id, void 0, "instance has NOT been assigned remote id");
827
- let peekedInstance = storeService.peek(instance[localId]);
828
- assert.strictEqual(instance, peekedInstance, "instance is the same");
829
- assert.strictEqual(instance.name, "Andrea", "instance data is correct");
830
- });
831
- (0, import_qunit.test)("can skip waiting for the save when adding to the store", async function(assert) {
832
- assert.expect(6);
833
- let didSave = false;
834
- this.onSave((_, doc) => {
835
- didSave = true;
836
- assert.strictEqual(doc.data.attributes?.name, "Andrea", "card data is correct");
837
- });
838
- let instance = new PersonDef({ name: "Andrea" });
839
- await storeService.addWithoutWaiting(instance);
840
- assert.false(didSave, "the instance has not saved yet");
841
- await waitUntil(() => didSave, { timeout: 1e4 });
842
- assert.ok(instance.id, "instance has been assigned remote id");
843
- let peekedInstance = storeService.peek(instance.id);
844
- assert.strictEqual(instance, peekedInstance, "instance is the same");
845
- let file = await testRealmAdapter.openFile(`${instance.id.substring(testRealmURL.length)}.json`);
846
- assert.ok(file, "file exists");
847
- let fileJSON = JSON.parse(file.content);
848
- assert.strictEqual(fileJSON.data.attributes.name, "Andrea", "file exists");
849
- });
850
- (0, import_qunit.test)("can set realmURL when adding to the store", async function(assert) {
851
- let instance = new PersonDef({ name: "Andrea" });
852
- assert.strictEqual(instance[realmURL]?.href, void 0, "realmURL meta is not set on the instance");
853
- await storeService.addWithoutPersisting(instance, { realm: testRealmURL });
854
- assert.strictEqual(instance[realmURL]?.href, testRealmURL, "realmURL meta was set on the instance");
855
- });
856
- (0, import_qunit.test)("can add linked cards to the store when adding a card", async function(assert) {
857
- let wu = new PersonDef({ name: "Wu" });
858
- let michael = new PersonDef({ name: "Michael" });
859
- let lin = new PersonDef({
860
- name: "Lin",
861
- bestFriend: wu,
862
- friends: [michael]
863
- });
864
- await storeService.addWithoutPersisting(lin);
865
- let peekedMichael = storeService.peek(michael[localId]);
866
- assert.strictEqual(peekedMichael, michael, "michael instance added to store");
867
- let peekedWu = storeService.peek(wu[localId]);
868
- assert.strictEqual(peekedWu, wu, "wu instance added to store");
869
- });
870
- (0, import_qunit.test)("can reject a card added to the store that has a conflicting local ID for a given URL", async function(assert) {
871
- storeService.addReference(`${testRealmURL}Person/hassan`);
872
- await storeService.flush();
873
- let doc = { data: {
874
- type: "card",
875
- id: testRRI("Person/hassan"),
876
- attributes: { name: "Hassan" },
877
- meta: { adoptsFrom: {
878
- module: testRRI("person"),
879
- name: "Person"
880
- } }
881
- } };
882
- let conflictingInstance = await api.createFromSerialized(doc.data, doc, void 0);
883
- try {
884
- await storeService.addWithoutPersisting(conflictingInstance);
885
- throw new Error("expected exception to be thrown");
886
- } catch (err) {
887
- assert.ok(err.message.includes("has conflicting instance id in store"), "the expected error was thrown");
888
- }
889
- });
890
- (0, import_qunit.test)("added instance that was previously not saved will begin to auto save after being added", async function(assert) {
891
- assert.expect(2);
892
- let instance = new PersonDef({ name: "Andrea" });
893
- await storeService.add(instance);
894
- this.onSave((url, doc) => {
895
- assert.strictEqual(url.href, instance.id, "the instance URL is correct");
896
- assert.strictEqual(doc.data.attributes?.name, "Air", "card data is correct");
897
- });
898
- instance.name = "Air";
899
- });
900
- (0, import_qunit.test)("an instance will auto save when its data changes", async function(assert) {
901
- assert.expect(2);
902
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
903
- this.onSave((url, doc) => {
904
- assert.strictEqual(url.href, instance.id, "the instance URL is correct");
905
- assert.strictEqual(doc.data.attributes?.name, "Paper", "card data is correct");
906
- });
907
- instance.name = "Paper";
908
- });
909
- (0, import_qunit.test)("an unsaved instance will auto save when its data changes", async function(assert) {
910
- assert.expect(2);
911
- let instance = new PersonDef({ name: "Andrea" });
912
- await storeService.addWithoutPersisting(instance);
913
- this.onSave((url, doc) => {
914
- assert.strictEqual(url.href.split("/").pop(), instance[localId], "the new card url ends with the local id");
915
- assert.strictEqual(doc.data.attributes?.name, "Air", "card data is correct");
916
- });
917
- instance.name = "Air";
918
- });
919
- (0, import_qunit.test)("an instance will NOT auto save when its data changes, if the user does not have write permissions", async function(assert) {
920
- storeService.realm.permissions = () => ({
921
- get canRead() {
922
- return true;
923
- },
924
- get canWrite() {
925
- return false;
926
- }
927
- });
928
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
929
- this.onSave(() => {
930
- assert.ok(false, "should not save");
931
- });
932
- instance.name = "Paper";
933
- assert.strictEqual(instance.name, "Paper");
934
- let id = instance.id;
935
- assert.deepEqual(storeService.getSaveState(id), {
936
- hasUnsavedChanges: true,
937
- isSaving: false,
938
- lastSaveError: void 0,
939
- lastSaved: void 0,
940
- lastSavedErrorMsg: void 0
941
- });
942
- });
943
- (0, import_qunit.test)("an instance can debounce auto saves", async function(assert) {
944
- assert.expect(5);
945
- setCardInOperatorModeState(`${testRealmURL}Person/hassan`, "edit");
946
- await renderComponent(class TestDriver extends Component {
947
- static {
948
- setComponentTemplate(templateFactory({
949
- "id": "ZD1xwmB+",
950
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
951
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
952
- "scope": () => [OperatorModeContainer, noop],
953
- "isStrictMode": true
954
- }), this);
955
- }
956
- });
957
- let nameInput = `[data-test-stack-card="${testRealmURL}Person/hassan"] [data-test-field="name"] input`;
958
- let typedSoFar = () => find(nameInput)?.value;
959
- let typedWhenIssued = [];
960
- let saveLog = [];
961
- let saveTrace = () => `saves so far: ${saveLog.join(" | ")}`;
962
- let saveCount = 0;
963
- this.onSave((url, doc) => {
964
- saveCount++;
965
- let savedName = doc.data?.attributes?.name;
966
- saveLog.push(`#${saveCount} issuedAfter=${JSON.stringify(typedWhenIssued[saveCount - 1])} saved=${JSON.stringify(savedName)}`);
967
- assert.strictEqual(url.href, `${testRealmURL}Person/hassan`, "correct document is saved");
968
- switch (saveCount) {
969
- case 1:
970
- assert.strictEqual(savedName, "Hassan ", `the initial instance mutation event is saved (${saveTrace()})`);
971
- break;
972
- case 2:
973
- assert.strictEqual(savedName, "Hassan Paper", `the final instance mutation event is saved (${saveTrace()})`);
974
- break;
975
- default: assert.ok(false, `unexpected number of saves: ${saveCount} (${saveTrace()})`);
976
- }
977
- });
978
- await withSavesHeldOpen(async (release) => {
979
- let keystrokes = typeIn(nameInput, " Paper");
980
- keystrokes.catch(() => {});
981
- try {
982
- await Promise.race([keystrokes, waitUntil(() => typedSoFar() === "Hassan Paper", { timeout: 3e3 })]);
983
- } catch (err) {
984
- throw new Error(`the keystrokes did not land, input holds ${JSON.stringify(typedSoFar())} (${saveTrace()})`, { cause: err });
985
- }
986
- release();
987
- await keystrokes;
988
- }, { onSaveIssued: () => typedWhenIssued.push(typedSoFar()) });
989
- assert.strictEqual(saveCount, 2, `the number of auto-saves is correct (${saveTrace()})`);
990
- });
991
- (0, import_qunit.test)("a non-immediate auto save stays in flight for the save-indicator floor", async function(assert) {
992
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
993
- let id = instance.id;
994
- let store = storeService;
995
- let originalPersist = store.persistAndUpdate;
996
- store.persistAndUpdate = async () => instance;
997
- try {
998
- let startedAt = Date.now();
999
- instance.name = "Paper";
1000
- await waitUntil(() => storeService.getSaveState(id)?.lastSaved, { timeout: 5e3 });
1001
- let heldMs = Date.now() - startedAt;
1002
- assert.ok(heldMs >= 500, `the save is held in flight for the floor (held ${heldMs}ms)`);
1003
- } finally {
1004
- store.persistAndUpdate = originalPersist;
1005
- }
1006
- });
1007
- (0, import_qunit.test)("getSaveState works for initially unsaved instance", async function(assert) {
1008
- let instance = new PersonDef({ name: "Andrea" });
1009
- await storeService.addWithoutPersisting(instance);
1010
- assert.strictEqual(storeService.getSaveState(instance[localId]), void 0, "save state is undefined");
1011
- instance.name = "Air";
1012
- assert.true(storeService.getSaveState(instance[localId])?.hasUnsavedChanges, "hasUnsavedChanges state is correct");
1013
- await waitUntil(() => storeService.getSaveState(instance[localId])?.isSaving, { timeout: 1e4 });
1014
- await waitUntil(() => storeService.getSaveState(instance[localId])?.lastSaved, { timeout: 1e4 });
1015
- assert.false(storeService.getSaveState(instance[localId])?.isSaving, "isSaving state is correct");
1016
- assert.false(storeService.getSaveState(instance.id)?.isSaving, "isSaving state is correct (by remote id)");
1017
- assert.ok(storeService.getSaveState(instance.id)?.lastSaved, "lastSaved state is correct (by remote id)");
1018
- });
1019
- (0, import_qunit.test)("can capture error when auto saving", async function(assert) {
1020
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
1021
- try {
1022
- globalThis.__emulateServerPatchFailure = true;
1023
- instance.hasError = true;
1024
- await waitUntil(() => storeService.getSaveState(`${testRealmURL}Person/hassan`)?.lastSaveError, { timeout: 1e4 });
1025
- let saveState = storeService.getSaveState(`${testRealmURL}Person/hassan`);
1026
- assert.ok(saveState.lastSavedErrorMsg?.includes("intentional error thrown"), "error message is correct");
1027
- } finally {
1028
- delete globalThis.__emulateServerPatchFailure;
1029
- }
1030
- });
1031
- (0, import_qunit.module)("auto save waits for edits to pause", function(hooks) {
1032
- let saves;
1033
- let originalQuietPeriodMs;
1034
- let originalMaxWaitMs;
1035
- function recordSave(url, doc) {
1036
- saves.push({
1037
- url: url.href,
1038
- name: doc.data?.attributes?.name
1039
- });
1040
- }
1041
- hooks.beforeEach(function() {
1042
- saves = [];
1043
- this.onSave(recordSave);
1044
- let environment = getService("environment-service");
1045
- originalQuietPeriodMs = environment.autoSaveQuietPeriodMs;
1046
- originalMaxWaitMs = environment.autoSaveMaxWaitMs;
1047
- setAutoSaveTiming(NEVER, NEVER);
1048
- });
1049
- hooks.afterEach(function() {
1050
- let environment = getService("environment-service");
1051
- environment.autoSaveQuietPeriodMs = originalQuietPeriodMs;
1052
- environment.autoSaveMaxWaitMs = originalMaxWaitMs;
1053
- });
1054
- function setAutoSaveTiming(quietPeriodMs, maxWaitMs) {
1055
- let environment = getService("environment-service");
1056
- environment.autoSaveQuietPeriodMs = quietPeriodMs;
1057
- environment.autoSaveMaxWaitMs = maxWaitMs;
1058
- }
1059
- const NEVER = 10 * 6e4;
1060
- function pause(ms) {
1061
- return new Promise((resolve) => setTimeout(resolve, ms));
1062
- }
1063
- async function waitForSaves(count, message) {
1064
- try {
1065
- await waitUntil(() => saves.length >= count, { timeout: 5e3 });
1066
- } catch (err) {
1067
- throw new Error(`${message}: expected ${count} save(s), saw ${JSON.stringify(saves)}`, { cause: err });
1068
- }
1069
- }
1070
- function recordWrites(onWrite) {
1071
- let virtualNetwork = getService("network").virtualNetwork;
1072
- let originalFetch = virtualNetwork.fetch;
1073
- let writes = [];
1074
- virtualNetwork.fetch = async (input, init) => {
1075
- let request = input instanceof Request ? input : void 0;
1076
- let method = init?.method ?? request?.method ?? "GET";
1077
- if (method === "PATCH" || method === "POST") {
1078
- let url = request?.url ?? String(input);
1079
- writes.push({
1080
- url,
1081
- keepalive: init?.keepalive ?? request?.keepalive ?? false
1082
- });
1083
- onWrite?.(url);
1084
- }
1085
- return await originalFetch.call(virtualNetwork, input, init);
1086
- };
1087
- return {
1088
- writes,
1089
- restore: () => virtualNetwork.fetch = originalFetch
1090
- };
1091
- }
1092
- function hidePage() {
1093
- Object.defineProperty(document, "visibilityState", {
1094
- configurable: true,
1095
- get: () => "hidden"
1096
- });
1097
- try {
1098
- document.dispatchEvent(new Event("visibilitychange"));
1099
- } finally {
1100
- delete document.visibilityState;
1101
- }
1102
- }
1103
- (0, import_qunit.test)("edits are saved once, after they pause", async function(assert) {
1104
- setAutoSaveTiming(300, NEVER);
1105
- let id = `${testRealmURL}Person/hassan`;
1106
- let instance = await storeService.get(id);
1107
- for (let name of [
1108
- "H",
1109
- "Ha",
1110
- "Has",
1111
- "Hass",
1112
- "Hassa"
1113
- ]) {
1114
- instance.name = name;
1115
- await pause(50);
1116
- }
1117
- assert.strictEqual(saves.length, 0, "nothing is saved while editing");
1118
- let saveState = storeService.getSaveState(id);
1119
- assert.true(saveState.hasUnsavedChanges, "the card has unsaved changes");
1120
- assert.false(saveState.isSaving, "the card is not saving yet");
1121
- assert.strictEqual(saveState.lastSavedErrorMsg, "Unsaved changes", "the indicator reports unsaved changes");
1122
- await waitForSaves(1, "the edits are saved once they pause");
1123
- await storeService.flushSaves();
1124
- assert.deepEqual(saves, [{
1125
- url: id,
1126
- name: "Hassa"
1127
- }], "one save carries the last edit");
1128
- assert.false(storeService.getSaveState(id).hasUnsavedChanges, "nothing is left unsaved");
1129
- assert.ok(storeService.getSaveState(id).lastSavedErrorMsg?.startsWith("Saved"), "the indicator reports the save");
1130
- });
1131
- (0, import_qunit.test)("editing without a pause is saved at the maximum wait", async function(assert) {
1132
- setAutoSaveTiming(300, 600);
1133
- let id = `${testRealmURL}Person/hassan`;
1134
- let instance = await storeService.get(id);
1135
- let maxWaitMs = 600;
1136
- let edits = 30;
1137
- let startedAt = Date.now();
1138
- let timeline = [];
1139
- this.onSave((url, doc) => {
1140
- recordSave(url, doc);
1141
- timeline.push(`saved@${Date.now() - startedAt}`);
1142
- });
1143
- let { writes, restore } = recordWrites((url) => timeline.push(`${url === id ? "sent" : `sent ${url}`}@${Date.now() - startedAt}`));
1144
- let editingMs;
1145
- let sentWhileEditing;
1146
- try {
1147
- for (let i = 1; i <= edits; i++) {
1148
- instance.name = `Hassan ${i}`;
1149
- await pause(100);
1150
- }
1151
- editingMs = Date.now() - startedAt;
1152
- sentWhileEditing = writes.filter((w) => w.url === id).length;
1153
- timeline.push(`editing-ended@${editingMs}`);
1154
- await storeService.flushSaves();
1155
- } finally {
1156
- restore();
1157
- }
1158
- assert.ok(sentWhileEditing >= 1, `edits are saved while editing goes on (${sentWhileEditing} sent; ${timeline.join(", ")})`);
1159
- let bound = Math.ceil(editingMs / maxWaitMs) + 1;
1160
- assert.ok(saves.length <= bound, `${edits} edits over ${editingMs}ms take at most ${bound} saves (${saves.length} saved; ${timeline.join(", ")})`);
1161
- assert.ok(saves.length < edits / 3, `${edits} edits take far fewer saves than edits (${saves.length} saved; ${timeline.join(", ")})`);
1162
- assert.strictEqual(saves[saves.length - 1]?.name, `Hassan ${edits}`, "the last save carries the last edit");
1163
- });
1164
- (0, import_qunit.test)("an edit made while its save runs stays unsaved until the next save", async function(assert) {
1165
- let id = `${testRealmURL}Person/hassan`;
1166
- let instance = await storeService.get(id);
1167
- await withSavesHeldOpen(async (release) => {
1168
- instance.name = "Paper";
1169
- document.body.dispatchEvent(new FocusEvent("focusout", { bubbles: true }));
1170
- await waitUntil(() => storeService.getSaveState(id)?.isSaving);
1171
- instance.name = "Paper Hassan";
1172
- release();
1173
- await waitUntil(() => !storeService.getSaveState(id)?.isSaving);
1174
- let saveState = storeService.getSaveState(id);
1175
- assert.true(saveState.hasUnsavedChanges, "the edit made during the save is still unsaved");
1176
- assert.strictEqual(saveState.lastSavedErrorMsg, "Unsaved changes", "the indicator does not report the edit as saved");
1177
- });
1178
- await storeService.flushSaves();
1179
- assert.deepEqual(saves.map((s) => s.name), ["Paper", "Paper Hassan"], "both edits are saved, in order");
1180
- assert.false(storeService.getSaveState(id).hasUnsavedChanges);
1181
- });
1182
- (0, import_qunit.test)("a pending save is sent when the last reference to its card is dropped", async function(assert) {
1183
- let id = `${testRealmURL}Person/hassan`;
1184
- storeService.addReference(id);
1185
- await storeService.flush();
1186
- let instance = storeService.peek(id);
1187
- instance.name = "Paper";
1188
- storeService.dropReference(id);
1189
- await waitForSaves(1, "dropping the last reference sends the save");
1190
- assert.deepEqual(saves, [{
1191
- url: id,
1192
- name: "Paper"
1193
- }]);
1194
- await storeService.flushSaves();
1195
- assert.strictEqual(storeService.getReferenceCount(id), 0, "the save's hold on the card is released once it lands");
1196
- });
1197
- (0, import_qunit.test)("a pending save is not sent early while something still shows its card", async function(assert) {
1198
- let id = `${testRealmURL}Person/hassan`;
1199
- storeService.addReference(id);
1200
- storeService.addReference(id);
1201
- await storeService.flush();
1202
- let instance = storeService.peek(id);
1203
- instance.name = "Paper";
1204
- storeService.dropReference(id);
1205
- await pause(1e3);
1206
- assert.strictEqual(saves.length, 0, "the save keeps waiting");
1207
- storeService.dropReference(id);
1208
- await waitForSaves(1, "dropping the last reference sends the save");
1209
- assert.deepEqual(saves, [{
1210
- url: id,
1211
- name: "Paper"
1212
- }]);
1213
- });
1214
- (0, import_qunit.test)("garbage collection keeps a card whose save is pending", async function(assert) {
1215
- let id = `${testRealmURL}Person/hassan`;
1216
- let controlId = `${testRealmURL}Person/jade`;
1217
- let instance = await storeService.get(id);
1218
- let control = await storeService.get(controlId);
1219
- assert.strictEqual(storeService.getReferenceCount(id), 0);
1220
- assert.strictEqual(storeService.getReferenceCount(controlId), 0);
1221
- instance.name = "Paper";
1222
- forceGC();
1223
- assert.strictEqual(storeService.peek(controlId), void 0, "an unreferenced card without a pending save is collected");
1224
- assert.notStrictEqual(control, void 0);
1225
- assert.strictEqual(storeService.peek(id), instance, "the card with a pending save is kept");
1226
- await storeService.flushSaves();
1227
- assert.deepEqual(saves, [{
1228
- url: id,
1229
- name: "Paper"
1230
- }]);
1231
- });
1232
- (0, import_qunit.test)("flushSaves sends pending saves and waits for them", async function(assert) {
1233
- let id = `${testRealmURL}Person/hassan`;
1234
- let instance = await storeService.get(id);
1235
- instance.name = "Paper";
1236
- await storeService.flushSaves();
1237
- assert.deepEqual(saves, [{
1238
- url: id,
1239
- name: "Paper"
1240
- }]);
1241
- assert.false(storeService.hasUnsavedEdits);
1242
- });
1243
- (0, import_qunit.test)("ending the session drops saves still waiting for typing to pause", async function(assert) {
1244
- let id = `${testRealmURL}Person/hassan`;
1245
- let instance = await storeService.get(id);
1246
- instance.name = "Paper";
1247
- storeService.resetState();
1248
- storeService._onSave(recordSave);
1249
- await pause(1e3);
1250
- assert.deepEqual(saves, [], "nothing is written after the session ends");
1251
- assert.false(storeService.hasUnsavedEdits, "nothing is left pending");
1252
- });
1253
- (0, import_qunit.test)("a save queued behind a running one does not write once the session ends", async function(assert) {
1254
- let id = `${testRealmURL}Person/hassan`;
1255
- let instance = await storeService.get(id);
1256
- await withSavesHeldOpen(async (release) => {
1257
- instance.name = "Paper";
1258
- storeService.flushSaves();
1259
- await waitUntil(() => storeService.getSaveState(id)?.isSaving);
1260
- instance.name = "Paper Hassan";
1261
- storeService.flushSaves();
1262
- storeService.resetState();
1263
- storeService._onSave(recordSave);
1264
- release();
1265
- await waitUntil(() => !storeService.hasUnsavedEdits, { timeout: 5e3 });
1266
- });
1267
- assert.deepEqual(saves.map((s) => s.name), ["Paper"], "only the save that started before the session ended is written");
1268
- });
1269
- (0, import_qunit.test)("logout saves pending edits before the session ends", async function(assert) {
1270
- let id = `${testRealmURL}Person/hassan`;
1271
- let instance = await storeService.get(id);
1272
- instance.name = "Paper";
1273
- let matrixService = getService("matrix-service");
1274
- let originalClearAuth = matrixService.clearAuth;
1275
- let originalResetState = matrixService.resetState;
1276
- let savedWhenAuthCleared;
1277
- matrixService.clearAuth = () => {
1278
- savedWhenAuthCleared = [...saves];
1279
- throw new Error("stop logout here");
1280
- };
1281
- matrixService.resetState = () => {};
1282
- try {
1283
- await matrixService.logout({ skipIndexTransition: true });
1284
- } finally {
1285
- matrixService.clearAuth = originalClearAuth;
1286
- matrixService.resetState = originalResetState;
1287
- }
1288
- assert.deepEqual(savedWhenAuthCleared, [{
1289
- url: id,
1290
- name: "Paper"
1291
- }], "the edit is saved before auth is cleared");
1292
- });
1293
- (0, import_qunit.test)("resetting the store cache sends pending saves", async function(assert) {
1294
- let id = `${testRealmURL}Person/hassan`;
1295
- let instance = await storeService.get(id);
1296
- instance.name = "Paper";
1297
- storeService.resetCache();
1298
- await waitForSaves(1, "the reset sends the save");
1299
- assert.deepEqual(saves, [{
1300
- url: id,
1301
- name: "Paper"
1302
- }]);
1303
- await storeService.flushSaves();
1304
- });
1305
- (0, import_qunit.test)("hiding the page sends pending saves as requests that outlive the page", async function(assert) {
1306
- let id = `${testRealmURL}Person/hassan`;
1307
- let instance = await storeService.get(id);
1308
- instance.name = "Paper";
1309
- let { writes, restore } = recordWrites();
1310
- try {
1311
- hidePage();
1312
- await waitForSaves(1, "hiding the page sends the save");
1313
- } finally {
1314
- restore();
1315
- }
1316
- assert.deepEqual(saves, [{
1317
- url: id,
1318
- name: "Paper"
1319
- }]);
1320
- assert.deepEqual(writes, [{
1321
- url: id,
1322
- keepalive: true
1323
- }]);
1324
- });
1325
- (0, import_qunit.test)("pagehide sends pending saves as requests that outlive the page", async function(assert) {
1326
- let id = `${testRealmURL}Person/hassan`;
1327
- let instance = await storeService.get(id);
1328
- instance.name = "Paper";
1329
- let { writes, restore } = recordWrites();
1330
- try {
1331
- window.dispatchEvent(new PageTransitionEvent("pagehide"));
1332
- await waitForSaves(1, "pagehide sends the save");
1333
- await storeService.flushSaves();
1334
- } finally {
1335
- restore();
1336
- }
1337
- assert.deepEqual(saves, [{
1338
- url: id,
1339
- name: "Paper"
1340
- }]);
1341
- assert.deepEqual(writes, [{
1342
- url: id,
1343
- keepalive: true
1344
- }]);
1345
- });
1346
- (0, import_qunit.test)("saves past the keepalive budget are still sent, without keepalive", async function(assert) {
1347
- let ids = [`${testRealmURL}Person/hassan`, `${testRealmURL}Person/jade`];
1348
- let longName = "x".repeat(4e4);
1349
- for (let id of ids) {
1350
- let instance = await storeService.get(id);
1351
- instance.name = longName;
1352
- }
1353
- let { writes, restore } = recordWrites();
1354
- try {
1355
- window.dispatchEvent(new PageTransitionEvent("pagehide"));
1356
- await waitForSaves(2, "pagehide sends both saves");
1357
- await storeService.flushSaves();
1358
- } finally {
1359
- restore();
1360
- }
1361
- assert.deepEqual(saves.map((s) => s.url).sort(), [...ids].sort(), "both cards are saved");
1362
- assert.deepEqual(writes.map((w) => w.keepalive).sort(), [false, true], "one save fits the budget and the other is sent as an ordinary request");
1363
- });
1364
- (0, import_qunit.test)("an edit after a flush gives up still waits for typing to pause", async function(assert) {
1365
- let id = `${testRealmURL}Person/hassan`;
1366
- let jade = `${testRealmURL}Person/jade`;
1367
- let instance = await storeService.get(id);
1368
- let other = await storeService.get(jade);
1369
- await withSavesHeldOpen(async (release) => {
1370
- instance.name = "Paper";
1371
- await storeService.flushSaves({ timeoutMs: 100 });
1372
- assert.true(storeService.hasUnsavedEdits, "the held save is running");
1373
- other.name = "Jade Paper";
1374
- release();
1375
- await waitUntil(() => saves.length === 1, { timeout: 5e3 });
1376
- await pause(500);
1377
- });
1378
- assert.deepEqual(saves.map((s) => s.name), ["Paper"], "the later edit is not sent when the flush's save lands");
1379
- await storeService.flushSaves();
1380
- assert.deepEqual(saves.map((s) => s.name), ["Paper", "Jade Paper"]);
1381
- });
1382
- (0, import_qunit.test)("focus leaving a field sends pending saves", async function(assert) {
1383
- let id = `${testRealmURL}Person/hassan`;
1384
- let instance = await storeService.get(id);
1385
- instance.name = "Paper";
1386
- document.body.dispatchEvent(new FocusEvent("focusout", { bubbles: true }));
1387
- await waitForSaves(1, "focus leaving sends the save");
1388
- assert.deepEqual(saves, [{
1389
- url: id,
1390
- name: "Paper"
1391
- }]);
1392
- });
1393
- (0, import_qunit.test)("closing a card in the stack sends the save its edit is waiting on", async function(assert) {
1394
- let id = `${testRealmURL}Person/hassan`;
1395
- setCardInOperatorModeState(id, "edit");
1396
- await renderComponent(class TestDriver extends Component {
1397
- static {
1398
- setComponentTemplate(templateFactory({
1399
- "id": "ZD1xwmB+",
1400
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
1401
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
1402
- "scope": () => [OperatorModeContainer, noop],
1403
- "isStrictMode": true
1404
- }), this);
1405
- }
1406
- });
1407
- let input = find(`[data-test-stack-card="${id}"] [data-test-field="name"] input`);
1408
- input.value = "Hassan Paper";
1409
- input.dispatchEvent(new Event("input", { bubbles: true }));
1410
- assert.strictEqual(saves.length, 0, "the edit waits to be saved");
1411
- let closed = click(`[data-test-stack-card="${id}"] [data-test-close-button]`);
1412
- await waitForSaves(1, "closing the card sends the save");
1413
- await closed;
1414
- assert.deepEqual(saves, [{
1415
- url: id,
1416
- name: "Hassan Paper"
1417
- }]);
1418
- });
1419
- });
1420
- (0, import_qunit.test)("can delete card from the store", async function(assert) {
1421
- storeService.addReference(`${testRealmURL}Person/boris`);
1422
- await storeService.flush();
1423
- let instance = storeService.peek(`${testRealmURL}Person/boris`);
1424
- await storeService.delete(`${testRealmURL}Person/boris`);
1425
- assert.strictEqual(storeService.peek(instance.id), void 0, "the instance is no longer in the store");
1426
- assert.strictEqual(storeService.peek(instance[localId]), void 0, "the instance is no longer in the store (via local id)");
1427
- let file = await testRealmAdapter.openFile(`Person/boris.json`);
1428
- assert.strictEqual(file, void 0, "file no longer exists");
1429
- });
1430
- (0, import_qunit.test)("subscribeToCardInvalidation fires the callback when the card is deleted", async function(assert) {
1431
- storeService.addReference(`${testRealmURL}Person/boris`);
1432
- await storeService.flush();
1433
- let fired = 0;
1434
- let unsubscribe = storeService.subscribeToCardInvalidation(`${testRealmURL}Person/boris`, () => {
1435
- fired += 1;
1436
- });
1437
- await storeService.delete(`${testRealmURL}Person/boris`);
1438
- assert.strictEqual(fired, 1, "the invalidation subscriber fires exactly once on delete");
1439
- unsubscribe();
1440
- });
1441
- (0, import_qunit.test)("subscribeToCardInvalidation unsubscribe stops firing the callback", async function(assert) {
1442
- storeService.addReference(`${testRealmURL}Person/boris`);
1443
- await storeService.flush();
1444
- let fired = 0;
1445
- storeService.subscribeToCardInvalidation(`${testRealmURL}Person/boris`, () => {
1446
- fired += 1;
1447
- })();
1448
- await storeService.delete(`${testRealmURL}Person/boris`);
1449
- assert.strictEqual(fired, 0, "no callbacks fire after unsubscribe");
1450
- });
1451
- (0, import_qunit.test)("a synchronously throwing invalidation subscriber does not break siblings", async function(assert) {
1452
- storeService.addReference(`${testRealmURL}Person/boris`);
1453
- await storeService.flush();
1454
- let originalError = console.error;
1455
- let captured = [];
1456
- console.error = (...args) => {
1457
- if (typeof args[0] === "string" && args[0].includes("card invalidation subscriber")) captured.push(args);
1458
- else originalError(...args);
1459
- };
1460
- let secondFired = 0;
1461
- let unsubscribeA = storeService.subscribeToCardInvalidation(`${testRealmURL}Person/boris`, () => {
1462
- throw new Error("intentional sync throw from invalidation subscriber");
1463
- });
1464
- let unsubscribeB = storeService.subscribeToCardInvalidation(`${testRealmURL}Person/boris`, () => {
1465
- secondFired += 1;
1466
- });
1467
- try {
1468
- await storeService.delete(`${testRealmURL}Person/boris`);
1469
- assert.strictEqual(secondFired, 1, "the second subscriber still runs after the first one throws");
1470
- assert.strictEqual(captured.length, 1, "the synchronous throw is reported via console.error exactly once");
1471
- } finally {
1472
- unsubscribeA();
1473
- unsubscribeB();
1474
- console.error = originalError;
1475
- }
1476
- });
1477
- (0, import_qunit.test)("an async-rejecting invalidation subscriber does not break siblings and does not surface as an unhandled rejection", async function(assert) {
1478
- storeService.addReference(`${testRealmURL}Person/boris`);
1479
- await storeService.flush();
1480
- let originalError = console.error;
1481
- let captured = [];
1482
- console.error = (...args) => {
1483
- if (typeof args[0] === "string" && args[0].includes("card invalidation subscriber")) captured.push(args);
1484
- else originalError(...args);
1485
- };
1486
- let secondFired = 0;
1487
- let unsubscribeA = storeService.subscribeToCardInvalidation(`${testRealmURL}Person/boris`, async () => {
1488
- await Promise.resolve();
1489
- throw new Error("intentional async rejection from invalidation subscriber");
1490
- });
1491
- let unsubscribeB = storeService.subscribeToCardInvalidation(`${testRealmURL}Person/boris`, () => {
1492
- secondFired += 1;
1493
- });
1494
- try {
1495
- await storeService.delete(`${testRealmURL}Person/boris`);
1496
- await settled();
1497
- assert.strictEqual(secondFired, 1, "the second subscriber still runs alongside the async-rejecting one");
1498
- assert.strictEqual(captured.length, 1, "the async rejection is reported via console.error exactly once");
1499
- } finally {
1500
- unsubscribeA();
1501
- unsubscribeB();
1502
- console.error = originalError;
1503
- }
1504
- });
1505
- (0, import_qunit.test)("can patch an instance", async function(assert) {
1506
- let instance = await storeService.patch(`${testRealmURL}Person/hassan`, {
1507
- attributes: { name: "Hassan Updated" },
1508
- relationships: {
1509
- bestFriend: { links: { self: `${testRealmURL}Person/jade` } },
1510
- "friends.0": { links: { self: `${testRealmURL}Person/germaine` } }
1511
- }
1512
- });
1513
- let peekedInstance = storeService.peek(`${testRealmURL}Person/hassan`);
1514
- let jade = storeService.peek(`${testRealmURL}Person/jade`);
1515
- let germaine = storeService.peek(`${testRealmURL}Person/germaine`);
1516
- assert.strictEqual(peekedInstance, instance, "the patched instance is in the store");
1517
- assert.ok(isCardInstance(jade), "jade is in the store");
1518
- assert.ok(isCardInstance(germaine), "germaine is in the store");
1519
- assert.strictEqual(instance.name, "Hassan Updated", "the contains field was patched");
1520
- assert.strictEqual(instance.bestFriend, jade, "the linksTo field was patched");
1521
- assert.deepEqual(instance.friends, [germaine], "the linksToMany field was patched");
1522
- });
1523
- (0, import_qunit.test)("a patch that gives a primitive field an object replaces its value", async function(assert) {
1524
- await testRealm.write("Settings/one.json", JSON.stringify({ data: {
1525
- type: "card",
1526
- attributes: {
1527
- cardInfo: {
1528
- name: "Settings",
1529
- summary: "Kept"
1530
- },
1531
- config: {
1532
- approver: "@mae:localhost",
1533
- retired: true
1534
- }
1535
- },
1536
- meta: { adoptsFrom: {
1537
- module: "@cardstack/base/realm-config",
1538
- name: "RealmConfig"
1539
- } }
1540
- } }));
1541
- let id = `${testRealmURL}Settings/one`;
1542
- let instance = await storeService.patch(id, { attributes: {
1543
- cardInfo: { name: "Renamed" },
1544
- config: { approvers: "@mae:localhost" }
1545
- } });
1546
- assert.deepEqual(instance.config, { approvers: "@mae:localhost" }, "the instance holds the map the patch sent");
1547
- let file = await testRealmAdapter.openFile("Settings/one.json");
1548
- let { attributes } = JSON.parse(file.content).data;
1549
- assert.deepEqual(attributes.config, { approvers: "@mae:localhost" }, "and so does the saved file, without the renamed or dropped keys");
1550
- assert.strictEqual(attributes.cardInfo.summary, "Kept", "the compound field keeps the nested value the patch leaves out");
1551
- });
1552
- (0, import_qunit.test)("resolving a linksTo lazily issues no save", async function(assert) {
1553
- let hassanId = `${testRealmURL}Person/hassan`;
1554
- await testRealm.write("Person/ghost-friend.json", JSON.stringify({ data: {
1555
- attributes: { name: "Ghost" },
1556
- meta: { adoptsFrom: {
1557
- module: testRRI("person"),
1558
- name: "Person"
1559
- } }
1560
- } }));
1561
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
1562
- attributes: { name: "Hassan" },
1563
- relationships: { bestFriend: { links: { self: `${testRealmURL}Person/ghost-friend` } } },
1564
- meta: { adoptsFrom: {
1565
- module: testRRI("person"),
1566
- name: "Person"
1567
- } }
1568
- } }));
1569
- let cardService = getService("card-service");
1570
- let fetchJSON = cardService.fetchJSON.bind(cardService);
1571
- let intercepted = 0;
1572
- cardService.fetchJSON = async (url, args) => {
1573
- let doc = await fetchJSON(url, args);
1574
- if (String(url).replace(/\.json$/, "") === hassanId) {
1575
- intercepted++;
1576
- delete doc?.included;
1577
- }
1578
- return doc;
1579
- };
1580
- let saved = [];
1581
- this.onSave((url) => {
1582
- saved.push(url.href);
1583
- });
1584
- try {
1585
- let instance = await storeService.get(hassanId);
1586
- assert.ok(intercepted > 0, "the card fetch was intercepted");
1587
- assert.strictEqual(instance.bestFriend, void 0, "the link is not loaded yet, so reading it takes the lazy path");
1588
- await storeService.flush();
1589
- await settled();
1590
- assert.strictEqual(instance.bestFriend?.name, "Ghost", "the lazy load resolved the target and assigned it to the field");
1591
- assert.deepEqual(saved, [], "no save was issued while loading");
1592
- } finally {
1593
- cardService.fetchJSON = fetchJSON;
1594
- }
1595
- });
1596
- (0, import_qunit.test)("resolving a linksToMany lazily issues no save", async function(assert) {
1597
- let hassanId = `${testRealmURL}Person/hassan`;
1598
- await testRealm.write("Person/ghost-friend.json", JSON.stringify({ data: {
1599
- attributes: { name: "Ghost" },
1600
- meta: { adoptsFrom: {
1601
- module: testRRI("person"),
1602
- name: "Person"
1603
- } }
1604
- } }));
1605
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
1606
- attributes: { name: "Hassan" },
1607
- relationships: { "friends.0": { links: { self: `${testRealmURL}Person/ghost-friend` } } },
1608
- meta: { adoptsFrom: {
1609
- module: testRRI("person"),
1610
- name: "Person"
1611
- } }
1612
- } }));
1613
- let cardService = getService("card-service");
1614
- let fetchJSON = cardService.fetchJSON.bind(cardService);
1615
- let intercepted = 0;
1616
- cardService.fetchJSON = async (url, args) => {
1617
- let doc = await fetchJSON(url, args);
1618
- if (String(url).replace(/\.json$/, "") === hassanId) {
1619
- intercepted++;
1620
- delete doc?.included;
1621
- }
1622
- return doc;
1623
- };
1624
- let saved = [];
1625
- this.onSave((url) => {
1626
- saved.push(url.href);
1627
- });
1628
- try {
1629
- let instance = await storeService.get(hassanId);
1630
- assert.ok(intercepted > 0, "the card fetch was intercepted");
1631
- assert.deepEqual(instance.friends.map((f) => f?.name), [void 0], "the element is not loaded yet, so reading it takes the lazy path");
1632
- await storeService.flush();
1633
- await settled();
1634
- assert.deepEqual(instance.friends.map((f) => f?.name), ["Ghost"], "the lazy load resolved the target into its slot");
1635
- assert.deepEqual(saved, [], "no save was issued while loading");
1636
- } finally {
1637
- cardService.fetchJSON = fetchJSON;
1638
- }
1639
- });
1640
- (0, import_qunit.test)("a concurrent field write during store.patch is not clobbered by the patch’s stale snapshot", async function(assert) {
1641
- let targetId = `${testRealmURL}Person/hassan`;
1642
- let instance = await storeService.get(targetId);
1643
- let gate = new Deferred();
1644
- let enteredGate = new Deferred();
1645
- let originalLoadPatchedInstances = storeService.loadPatchedInstances;
1646
- storeService.loadPatchedInstances = async function(...args) {
1647
- let result = await originalLoadPatchedInstances.apply(this, args);
1648
- enteredGate.fulfill();
1649
- await gate.promise;
1650
- return result;
1651
- };
1652
- try {
1653
- let patchPromise = storeService.patch(targetId, { relationships: { bestFriend: { links: { self: `${testRealmURL}Person/jade` } } } });
1654
- await enteredGate.promise;
1655
- instance.name = "Race Winner";
1656
- gate.fulfill();
1657
- await patchPromise;
1658
- } finally {
1659
- storeService.loadPatchedInstances = originalLoadPatchedInstances;
1660
- }
1661
- assert.strictEqual(instance.name, "Race Winner", "the concurrent field write is not clobbered by the patch's stale snapshot");
1662
- assert.strictEqual(instance.bestFriend?.id, `${testRealmURL}Person/jade`, "the patch itself was still applied");
1663
- });
1664
- (0, import_qunit.test)("a create gives the instance a remote identity the rest of the store can use", async function(assert) {
1665
- let instance = new PersonDef({ name: "Sequence" });
1666
- let instanceLocalId = instance[localId];
1667
- let subscriptions = storeService.subscriptions;
1668
- assert.false(subscriptions.has(testRealmURL), "the realm is not subscribed before the create");
1669
- let result = await storeService.persistAndUpdate(instance);
1670
- assert.true(isCardInstance(result), "the create resolved to the instance");
1671
- assert.ok(instance.id?.startsWith(testRealmURL), "the instance took a remote id in the realm");
1672
- assert.strictEqual(storeService.peek(instanceLocalId), instance, "the local id still resolves to this instance");
1673
- assert.strictEqual(storeService.peek(instance.id), instance, "the remote id resolves to the same instance");
1674
- assert.true(subscriptions.has(testRealmURL), "the store is listening for the realm's index events");
1675
- let cardPath = `${instance.id.substring(testRealmURL.length)}.json`;
1676
- assert.ok(await testRealmAdapter.openFile(cardPath), "the realm holds the created card");
1677
- instance.name = "Sequence Edited";
1678
- await waitUntil(() => storeService.getSaveState(instanceLocalId)?.lastSaved, { timeout: 1e4 });
1679
- await settled();
1680
- let file = await testRealmAdapter.openFile(cardPath);
1681
- assert.strictEqual(JSON.parse(file.content).data.attributes.name, "Sequence Edited", "an edit after the create autosaves to the realm");
1682
- });
1683
- (0, import_qunit.test)("a small new card saves even when its resident linked graph would overflow the size limit if inlined", async function(assert) {
1684
- let environmentService = getService("environment-service");
1685
- let originalMaxSize = environmentService.cardSizeLimitBytes;
1686
- try {
1687
- let bigFriend = new PersonDef({ name: "x".repeat(6e3) });
1688
- let savedFriend = await storeService.persistAndUpdate(bigFriend);
1689
- assert.true(isCardInstance(savedFriend), "the large linked card saved");
1690
- environmentService.cardSizeLimitBytes = 2500;
1691
- let instance = new PersonDef({ name: "Small" });
1692
- instance.bestFriend = bigFriend;
1693
- let result = await storeService.persistAndUpdate(instance);
1694
- assert.true(isCardInstance(result), "a new card whose own document is under the limit saves regardless of how large a graph it links to — the check measures what the realm stores, not the tab's loaded `included`");
1695
- let cardPath = `${instance.id.substring(testRealmURL.length)}.json`;
1696
- assert.ok(await testRealmAdapter.openFile(cardPath), "the realm holds the created card");
1697
- } finally {
1698
- environmentService.cardSizeLimitBytes = originalMaxSize;
1699
- }
1700
- });
1701
- (0, import_qunit.test)("includedScope controls which link targets the serializer builds", async function(assert) {
1702
- let cardService = getService("card-service");
1703
- let api = await cardService.getAPI();
1704
- let saved = new PersonDef({ name: "Saved" });
1705
- await storeService.persistAndUpdate(saved);
1706
- let unsaved = new PersonDef({ name: "Unsaved" });
1707
- let instance = new PersonDef({ name: "Consumer" });
1708
- instance.bestFriend = saved;
1709
- instance.friends = [unsaved];
1710
- let all = api.serializeCard(instance, {
1711
- useAbsoluteURL: true,
1712
- includedScope: "all"
1713
- });
1714
- assert.ok((all.included ?? []).find((r) => r.id === saved.id), "'all' serializes saved targets into included");
1715
- assert.ok((all.included ?? []).find((r) => r.lid === unsaved[localId]), "'all' serializes local targets into included");
1716
- let local = api.serializeCard(instance, {
1717
- useAbsoluteURL: true,
1718
- includedScope: "local"
1719
- });
1720
- assert.notOk((local.included ?? []).find((r) => r.id === saved.id), "'local' does not serialize saved targets");
1721
- assert.ok((local.included ?? []).find((r) => r.lid === unsaved[localId]), "'local' serializes local targets — the write's co-creation manifest");
1722
- let none = api.serializeCard(instance, {
1723
- useAbsoluteURL: true,
1724
- includedScope: "none"
1725
- });
1726
- assert.strictEqual(none.included, void 0, "'none' builds no included at all");
1727
- assert.deepEqual(local.data, all.data, "'local' leaves the primary resource identical to 'all'");
1728
- assert.deepEqual(none.data, all.data, "'none' leaves the primary resource identical to 'all'");
1729
- let viaCardService = await cardService.serializeCard(instance, {
1730
- useAbsoluteURL: true,
1731
- withLocalResourcesIncluded: true
1732
- });
1733
- assert.deepEqual(viaCardService, local, "withLocalResourcesIncluded serializes at the 'local' scope");
1734
- });
1735
- (0, import_qunit.test)("an oversized unsaved link created alongside a card still fails the size check", async function(assert) {
1736
- let environmentService = getService("environment-service");
1737
- let originalMaxSize = environmentService.cardSizeLimitBytes;
1738
- try {
1739
- environmentService.cardSizeLimitBytes = 2500;
1740
- let bigUnsaved = new PersonDef({ name: "x".repeat(6e3) });
1741
- let instance = new PersonDef({ name: "Small" });
1742
- instance.bestFriend = bigUnsaved;
1743
- let result = await storeService.persistAndUpdate(instance);
1744
- assert.false(isCardInstance(result), "the save is refused: the unsaved link is co-created as its own file and is over the ceiling");
1745
- assert.ok(String(result?.message).includes("exceeds maximum allowed size"), `the error names the size limit (got: ${result?.message})`);
1746
- } finally {
1747
- environmentService.cardSizeLimitBytes = originalMaxSize;
1748
- }
1749
- });
1750
- (0, import_qunit.test)("a save overlapping a create PATCHes instead of issuing a second POST", async function(assert) {
1751
- let instance = new PersonDef({ name: "Overlap" });
1752
- await storeService.addWithoutPersisting(instance);
1753
- let cardService = getService("card-service");
1754
- let originalFetchJSON = cardService.fetchJSON.bind(cardService);
1755
- let methods = [];
1756
- let reachedPost = new Deferred();
1757
- let releasePost = new Deferred();
1758
- cardService.fetchJSON = async (url, args) => {
1759
- if (args?.method !== "POST" && args?.method !== "PATCH") return originalFetchJSON(url, args);
1760
- methods.push(args.method);
1761
- if (args.method === "POST") {
1762
- reachedPost.fulfill();
1763
- await releasePost.promise;
1764
- }
1765
- return originalFetchJSON(url, args);
1766
- };
1767
- try {
1768
- let creating = storeService.persistAndUpdate(instance);
1769
- let reachedPostFirst = await Promise.race([reachedPost.promise.then(() => true), creating.then(() => false)]);
1770
- assert.true(reachedPostFirst, `the create reached its POST (resolved early as: ${JSON.stringify(await Promise.race([creating, Promise.resolve("still in flight")]))})`);
1771
- let overlapping = storeService.persistAndUpdate(instance);
1772
- releasePost.fulfill();
1773
- await Promise.all([creating, overlapping]);
1774
- } finally {
1775
- releasePost.fulfill();
1776
- delete cardService.fetchJSON;
1777
- }
1778
- await settled();
1779
- assert.deepEqual(methods, ["POST", "PATCH"], "the overlapping save waited for the remote id and updated the created card");
1780
- assert.ok(await testRealmAdapter.openFile(`${instance.id.substring(testRealmURL.length)}.json`), "the realm holds the created card");
1781
- });
1782
- function holdCreateResponse(held, opts) {
1783
- let cardService = getService("card-service");
1784
- let originalFetchJSON = cardService.fetchJSON.bind(cardService);
1785
- let writes = [];
1786
- let stored = new Deferred();
1787
- let release = new Deferred();
1788
- cardService.fetchJSON = async (url, args) => {
1789
- if (args?.method !== "POST" && args?.method !== "PATCH") return originalFetchJSON(url, args);
1790
- let body = JSON.parse(args.body);
1791
- writes.push({
1792
- method: args.method,
1793
- body
1794
- });
1795
- if (args.method !== "POST" || body.data.lid !== held[localId]) return originalFetchJSON(url, args);
1796
- let response = await originalFetchJSON(url, args);
1797
- stored.fulfill();
1798
- await release.promise;
1799
- if (opts?.fail) throw new Error("the create response never arrived");
1800
- return response;
1801
- };
1802
- return {
1803
- writes,
1804
- stored: stored.promise,
1805
- release: () => release.fulfill(),
1806
- restore() {
1807
- release.fulfill();
1808
- delete cardService.fetchJSON;
1809
- }
1810
- };
1811
- }
1812
- function includedLids(body) {
1813
- return (body.included ?? []).flatMap((resource) => "lid" in resource && resource.lid ? [resource.lid] : []);
1814
- }
1815
- (0, import_qunit.test)("a save does not send a linked card whose create is still in flight as a card to create", async function(assert) {
1816
- let friend = new PersonDef({ name: "Friend" });
1817
- await storeService.addWithoutPersisting(friend);
1818
- let person = new PersonDef({ name: "Person" });
1819
- person.bestFriend = friend;
1820
- await storeService.addWithoutPersisting(person);
1821
- let hold = holdCreateResponse(friend);
1822
- let personResult;
1823
- try {
1824
- let creatingFriend = storeService.persistAndUpdate(friend);
1825
- await hold.stored;
1826
- let savingPerson = storeService.persistAndUpdate(person);
1827
- let personSettledWhileFriendHeld = await Promise.race([savingPerson.then(() => true), new Promise((r) => setTimeout(() => r(false), 500))]);
1828
- assert.false(personSettledWhileFriendHeld, "the save waits while the linked card's create is unanswered");
1829
- assert.deepEqual(hold.writes.map((w) => w.method), ["POST"], "nothing but the linked card's own create went out while it was unanswered");
1830
- hold.release();
1831
- [, personResult] = await Promise.all([creatingFriend, savingPerson]);
1832
- } finally {
1833
- hold.restore();
1834
- }
1835
- await settled();
1836
- assert.true(isCardInstance(personResult), `the save succeeded (resolved as: ${JSON.stringify(personResult)})`);
1837
- let personWrite = hold.writes.find((w) => w.body.data.lid === person[localId]);
1838
- assert.ok(personWrite, "the card linking to it was saved");
1839
- assert.deepEqual(includedLids(personWrite.body), [], "the save carried no card to create");
1840
- assert.strictEqual(personWrite.body.data.relationships?.bestFriend?.links?.self, friend.id, "the save linked to the id the realm assigned the linked card");
1841
- let file = await testRealmAdapter.openFile(`${person.id.substring(testRealmURL.length)}.json`);
1842
- assert.ok(file, "the realm holds the saved card");
1843
- });
1844
- (0, import_qunit.test)("a save started in the same turn as a linked card's create does not send that card again", async function(assert) {
1845
- let friend = new PersonDef({ name: "Friend" });
1846
- await storeService.addWithoutPersisting(friend);
1847
- let person = new PersonDef({ name: "Person" });
1848
- person.bestFriend = friend;
1849
- await storeService.addWithoutPersisting(person);
1850
- let hold = holdCreateResponse(friend);
1851
- let results;
1852
- try {
1853
- let creatingFriend = storeService.persistAndUpdate(friend);
1854
- let savingPerson = storeService.persistAndUpdate(person);
1855
- await hold.stored;
1856
- hold.release();
1857
- results = await Promise.all([creatingFriend, savingPerson]);
1858
- } finally {
1859
- hold.restore();
1860
- }
1861
- await settled();
1862
- assert.true(results.every((r) => isCardInstance(r)), `both saves succeeded (resolved as: ${JSON.stringify(results)})`);
1863
- assert.deepEqual(hold.writes.map((w) => includedLids(w.body)), [[], []], "neither request carried a card to create besides its own");
1864
- });
1865
- (0, import_qunit.test)("a save still creates a linked card that was never saved alongside it", async function(assert) {
1866
- let friend = new PersonDef({ name: "Friend" });
1867
- let person = new PersonDef({ name: "Person" });
1868
- person.bestFriend = friend;
1869
- await storeService.addWithoutPersisting(person);
1870
- let hold = holdCreateResponse(friend);
1871
- let personResult;
1872
- try {
1873
- personResult = await storeService.persistAndUpdate(person);
1874
- } finally {
1875
- hold.restore();
1876
- }
1877
- await settled();
1878
- assert.true(isCardInstance(personResult), `the save succeeded (resolved as: ${JSON.stringify(personResult)})`);
1879
- assert.deepEqual(hold.writes.map((w) => includedLids(w.body)), [[friend[localId]]], "one request carried the unsaved linked card as a card to create");
1880
- let personFile = await testRealmAdapter.openFile(`${person.id.substring(testRealmURL.length)}.json`);
1881
- let friendPath = JSON.parse(personFile.content).data.relationships.bestFriend.links.self;
1882
- assert.ok(await testRealmAdapter.openFile(`${new URL(friendPath, person.id).href.substring(testRealmURL.length)}.json`), "the realm holds the linked card, created with the save");
1883
- });
1884
- (0, import_qunit.test)("a save waiting on a linked card whose create fails does not hang", async function(assert) {
1885
- let friend = new PersonDef({ name: "Friend" });
1886
- await storeService.addWithoutPersisting(friend);
1887
- let person = new PersonDef({ name: "Person" });
1888
- person.bestFriend = friend;
1889
- await storeService.addWithoutPersisting(person);
1890
- let hold = holdCreateResponse(friend, { fail: true });
1891
- let friendResult;
1892
- let personResult;
1893
- try {
1894
- let creatingFriend = storeService.persistAndUpdate(friend);
1895
- await hold.stored;
1896
- let savingPerson = storeService.persistAndUpdate(person);
1897
- let personSettledWhileFriendHeld = await Promise.race([savingPerson.then(() => true), new Promise((r) => setTimeout(() => r(false), 500))]);
1898
- assert.false(personSettledWhileFriendHeld, "the save waits while the linked card's create is unanswered");
1899
- assert.deepEqual(hold.writes.map((w) => w.method), ["POST"], "nothing but the linked card's own create went out while it was unanswered");
1900
- hold.release();
1901
- [friendResult, personResult] = await Promise.all([creatingFriend, savingPerson]);
1902
- } finally {
1903
- hold.restore();
1904
- }
1905
- await settled();
1906
- assert.false(isCardInstance(friendResult), "the linked card's create reported its failure");
1907
- assert.true(isCardInstance(personResult), `the save answered, linked to the already-stored card (resolved as: ${JSON.stringify(personResult)})`);
1908
- assert.deepEqual(includedLids(hold.writes.find((w) => w.body.data.lid === person[localId]).body), [friend[localId]], "with no create left on the wire, the save sent the linked card as a card to create");
1909
- });
1910
- (0, import_qunit.test)("loads FileDef links from included resources", async function(assert) {
1911
- await testRealm.writeMany(new Map([
1912
- ["gallery.gts", `
1913
- import { CardDef, field, linksTo, linksToMany } from "@cardstack/base/card-api";
1914
- import { FileDef } from "@cardstack/base/file-api";
1915
-
1916
- export class Gallery extends CardDef {
1917
- @field hero = linksTo(FileDef);
1918
- @field attachments = linksToMany(FileDef);
1919
- }
1920
- `],
1921
- ["Gallery/hero.json", JSON.stringify({
1922
- data: {
1923
- attributes: { cardInfo: {} },
1924
- relationships: {
1925
- hero: {
1926
- links: { self: `${testRealmURL}hero.png` },
1927
- data: {
1928
- type: "file-meta",
1929
- id: `${testRealmURL}hero.png`
1930
- }
1931
- },
1932
- "attachments.0": {
1933
- links: { self: `${testRealmURL}first.png` },
1934
- data: {
1935
- type: "file-meta",
1936
- id: `${testRealmURL}first.png`
1937
- }
1938
- },
1939
- "attachments.1": {
1940
- links: { self: `${testRealmURL}second.png` },
1941
- data: {
1942
- type: "file-meta",
1943
- id: `${testRealmURL}second.png`
1944
- }
1945
- }
1946
- },
1947
- meta: { adoptsFrom: {
1948
- module: testRRI("gallery"),
1949
- name: "Gallery"
1950
- } }
1951
- },
1952
- included: [
1953
- {
1954
- type: "file-meta",
1955
- id: `${testRealmURL}hero.png`,
1956
- attributes: {
1957
- name: "hero.png",
1958
- url: `${testRealmURL}hero.png`,
1959
- sourceUrl: `${testRealmURL}hero.png`,
1960
- contentType: "image/png"
1961
- },
1962
- meta: { adoptsFrom: {
1963
- module: "@cardstack/base/card-api",
1964
- name: "FileDef"
1965
- } }
1966
- },
1967
- {
1968
- type: "file-meta",
1969
- id: `${testRealmURL}first.png`,
1970
- attributes: {
1971
- name: "first.png",
1972
- url: `${testRealmURL}first.png`,
1973
- sourceUrl: `${testRealmURL}first.png`,
1974
- contentType: "image/png"
1975
- },
1976
- meta: { adoptsFrom: {
1977
- module: "@cardstack/base/card-api",
1978
- name: "FileDef"
1979
- } }
1980
- },
1981
- {
1982
- type: "file-meta",
1983
- id: `${testRealmURL}second.png`,
1984
- attributes: {
1985
- name: "second.png",
1986
- url: `${testRealmURL}second.png`,
1987
- sourceUrl: `${testRealmURL}second.png`,
1988
- contentType: "image/png"
1989
- },
1990
- meta: { adoptsFrom: {
1991
- module: "@cardstack/base/card-api",
1992
- name: "FileDef"
1993
- } }
1994
- }
1995
- ]
1996
- })],
1997
- ["hero.png", "mock hero image"],
1998
- ["first.png", "mock first image"],
1999
- ["second.png", "mock second image"]
2000
- ]));
2001
- let gallery = await storeService.get(`${testRealmURL}Gallery/hero`);
2002
- assert.ok(gallery.hero, "hero is loaded from included resources");
2003
- assert.strictEqual(gallery.hero?.id, `${testRealmURL}hero.png`, "hero FileDef has id set from file meta");
2004
- assert.strictEqual(gallery.hero?.name, "hero.png", "hero FileDef uses file meta name");
2005
- assert.strictEqual(gallery.hero?.url, `${testRealmURL}hero.png`, "hero FileDef uses file meta url");
2006
- let attachments = gallery.attachments ?? [];
2007
- assert.strictEqual(attachments.length, 2, "attachments are loaded from included resources");
2008
- assert.strictEqual(attachments[0]?.id, `${testRealmURL}first.png`, "first attachment has id set from file meta");
2009
- assert.strictEqual(attachments[0]?.name, "first.png", "first attachment uses file meta name");
2010
- assert.strictEqual(attachments[1]?.id, `${testRealmURL}second.png`, "second attachment has id set from file meta");
2011
- assert.strictEqual(attachments[1]?.name, "second.png", "second attachment uses file meta name");
2012
- });
2013
- (0, import_qunit.test)("uses cached FileDef for links.self when field expects FileDef", async function(assert) {
2014
- await testRealm.writeMany(new Map([
2015
- ["gallery.gts", `
2016
- import { CardDef, field, linksTo } from "@cardstack/base/card-api";
2017
- import { FileDef } from "@cardstack/base/file-api";
2018
-
2019
- export class Gallery extends CardDef {
2020
- @field hero = linksTo(FileDef);
2021
- }
2022
- `],
2023
- ["Gallery/cached.json", JSON.stringify({ data: {
2024
- attributes: { cardInfo: {} },
2025
- relationships: { hero: {
2026
- links: { self: `${testRealmURL}hero.png` },
2027
- data: {
2028
- type: "file-meta",
2029
- id: `${testRealmURL}hero.png`
2030
- }
2031
- } },
2032
- meta: { adoptsFrom: {
2033
- module: testRRI("gallery"),
2034
- name: "Gallery"
2035
- } }
2036
- } })],
2037
- ["hero.png", "mock hero image"]
2038
- ]));
2039
- let cachedFile = await storeService.get(`${testRealmURL}hero.png`, { type: "file-meta" });
2040
- let gallery = await storeService.get(`${testRealmURL}Gallery/cached`);
2041
- assert.strictEqual(gallery.hero, cachedFile, "links.self resolves to cached FileDef for FileDef fields");
2042
- });
2043
- (0, import_qunit.test)("can skip waiting for the save when patching an instance", async function(assert) {
2044
- assert.expect(4);
2045
- let targetId = `${testRealmURL}Person/hassan`;
2046
- let instance = await storeService.get(targetId);
2047
- let didSave = false;
2048
- this.onSave((url, doc) => {
2049
- if (url.href === targetId) {
2050
- didSave = true;
2051
- assert.strictEqual(doc.data.attributes?.name, "Hassan Updated", "patched data is persisted");
2052
- }
2053
- });
2054
- await storeService.patch(targetId, { attributes: { name: "Hassan Updated" } }, { doNotWaitForPersist: true });
2055
- assert.strictEqual(instance.name, "Hassan Updated", "local instance updated immediately");
2056
- assert.false(didSave, "instance has not been persisted yet");
2057
- await waitUntil(() => didSave, { timeout: 1e4 });
2058
- let file = await testRealmAdapter.openFile("Person/hassan.json");
2059
- assert.strictEqual(JSON.parse(file.content).data.attributes.name, "Hassan Updated", "remote document reflects patch after persistence completes");
2060
- });
2061
- (0, import_qunit.test)("can patch an unsaved instance", async function(assert) {
2062
- let instance = new PersonDef({ name: "Andrea" });
2063
- await storeService.addWithoutPersisting(instance, { realm: testRealmURL });
2064
- await storeService.patch(instance[localId], {
2065
- attributes: { name: "Andrea Updated" },
2066
- relationships: {
2067
- bestFriend: { links: { self: `${testRealmURL}Person/queenzy` } },
2068
- "friends.0": { links: { self: `${testRealmURL}Person/germaine` } }
2069
- }
2070
- });
2071
- let peekedInstance = storeService.peek(instance[localId]);
2072
- let queenzy = storeService.peek(`${testRealmURL}Person/queenzy`);
2073
- let germaine = storeService.peek(`${testRealmURL}Person/germaine`);
2074
- assert.strictEqual(peekedInstance, instance, "the patched instance is in the store");
2075
- assert.ok(isCardInstance(queenzy), "queenzy is in the store");
2076
- assert.ok(isCardInstance(germaine), "germaine is in the store");
2077
- assert.strictEqual(instance[realmURL]?.href, testRealmURL, "the realm config on the instance is preserved");
2078
- assert.strictEqual(instance.name, "Andrea Updated", "the contains field was patched");
2079
- assert.strictEqual(instance.bestFriend, queenzy, "the linksTo field was patched");
2080
- assert.deepEqual(instance.friends, [germaine], "the linksToMany field was patched");
2081
- await waitUntil(() => instance.id, { timeoutMessage: "waiting for instance to get assigned an id" });
2082
- assert.ok(instance.id, "instance was assigned a remote id");
2083
- });
2084
- (0, import_qunit.test)("can skip save when patching an instance", async function(assert) {
2085
- this.onSave(() => {
2086
- assert.ok(false, "should not save");
2087
- });
2088
- let instance = await storeService.patch(`${testRealmURL}Person/hassan`, {
2089
- attributes: { name: "Hassan Updated" },
2090
- relationships: {
2091
- bestFriend: { links: { self: `${testRealmURL}Person/jade` } },
2092
- "friends.0": { links: { self: `${testRealmURL}Person/germaine` } }
2093
- }
2094
- }, { doNotPersist: true });
2095
- let peekedInstance = storeService.peek(`${testRealmURL}Person/hassan`);
2096
- let jade = storeService.peek(`${testRealmURL}Person/jade`);
2097
- let germaine = storeService.peek(`${testRealmURL}Person/germaine`);
2098
- assert.strictEqual(peekedInstance, instance, "the patched instance is in the store");
2099
- assert.ok(isCardInstance(jade), "jade is in the store");
2100
- assert.ok(isCardInstance(germaine), "germaine is in the store");
2101
- assert.strictEqual(instance.name, "Hassan Updated", "the contains field was patched");
2102
- assert.strictEqual(instance.bestFriend, jade, "the linksTo field was patched");
2103
- assert.deepEqual(instance.friends, [germaine], "the linksToMany field was patched");
2104
- });
2105
- (0, import_qunit.test)("can search", async function(assert) {
2106
- let results = await storeService.search({ filter: {
2107
- on: {
2108
- module: testRRI("person"),
2109
- name: "Person"
2110
- },
2111
- eq: { name: "Hassan" }
2112
- } }, [testRealmURL]);
2113
- assert.strictEqual(results.length, 1, "the correct number of results are returned");
2114
- assert.strictEqual(results[0].id, `${testRealmURL}Person/hassan`, "the result is correct");
2115
- });
2116
- function overrideSearchWith(doc) {
2117
- registerRealmServerRoute({
2118
- path: "/_federated-search",
2119
- handler: async () => new Response(JSON.stringify(doc), {
2120
- status: 200,
2121
- headers: { "content-type": SupportedMimeType.CardJson }
2122
- })
2123
- });
2124
- }
2125
- function htmlOnlyEntryDoc(id, opts) {
2126
- let htmlId = opts?.isFileMeta ? `${id}#fitted` : `${id}#fitted#${testRealmURL}person/Person`;
2127
- return {
2128
- data: [{
2129
- type: "entry",
2130
- id,
2131
- relationships: { html: { data: [{
2132
- type: "html",
2133
- id: htmlId
2134
- }] } }
2135
- }],
2136
- included: [{
2137
- type: "html",
2138
- id: htmlId,
2139
- attributes: {
2140
- html: "<div>prerendered</div>",
2141
- cardType: "Person",
2142
- format: "fitted"
2143
- },
2144
- relationships: { styles: { data: [] } }
2145
- }],
2146
- meta: { page: { total: 1 } }
2147
- };
2148
- }
2149
- let personQuery = { filter: {
2150
- on: {
2151
- module: testRRI("person"),
2152
- name: "Person"
2153
- },
2154
- eq: { name: "Hassan" }
2155
- } };
2156
- (0, import_qunit.test)("a search result with no item serialization is not deposited into the Store", async function(assert) {
2157
- let id = `${testRealmURL}Person/html-only`;
2158
- overrideSearchWith(htmlOnlyEntryDoc(id));
2159
- try {
2160
- let results = await storeService.search(personQuery, [testRealmURL]);
2161
- assert.strictEqual(results.length, 0, "the html-only entry is not returned as a hydrated instance");
2162
- assert.notOk(isCardInstance(storeService.peek(id)), "the html-only entry is not deposited in the Store");
2163
- } finally {
2164
- registerDefaultRoutes();
2165
- }
2166
- });
2167
- (0, import_qunit.test)("a search result with no item serialization leaves a resident full instance untouched", async function(assert) {
2168
- let id = `${testRealmURL}Person/hassan`;
2169
- storeService.addReference(id);
2170
- await storeService.flush();
2171
- let before = storeService.peek(id);
2172
- assert.true(isCardInstance(before), "the full instance is resident before the search");
2173
- overrideSearchWith(htmlOnlyEntryDoc(id));
2174
- try {
2175
- let results = await storeService.search(personQuery, [testRealmURL]);
2176
- assert.strictEqual(results.length, 0, "an entry with no serialization contributes no instance");
2177
- let after = storeService.peek(id);
2178
- assert.strictEqual(after, before, "the html-only entry left the resident full instance untouched");
2179
- assert.true(isCardInstance(after), "still a full card instance");
2180
- } finally {
2181
- registerDefaultRoutes();
2182
- }
2183
- });
2184
- (0, import_qunit.test)("a file-meta search result with no item serialization leaves a resident FileDef untouched", async function(assert) {
2185
- await testRealm.write("hero.png", "mock hero image");
2186
- let fileUrl = `${testRealmURL}hero.png`;
2187
- let before = await storeService.get(fileUrl, { type: "file-meta" });
2188
- storeService.addReference(fileUrl, { type: "file-meta" });
2189
- assert.true(before?.constructor?.isFileDef, "the live FileDef is resident before the search");
2190
- overrideSearchWith(htmlOnlyEntryDoc(fileUrl, { isFileMeta: true }));
2191
- try {
2192
- let results = await storeService.search(personQuery, [testRealmURL]);
2193
- assert.strictEqual(results.length, 0, "an entry with no serialization contributes no instance");
2194
- assert.true(storeService.peek(fileUrl, { type: "file-meta" })?.constructor?.isFileDef, "the resident live FileDef is untouched");
2195
- assert.ok(Object.is(storeService.peek(fileUrl, { type: "file-meta" }), before), "still the same resident FileDef");
2196
- } finally {
2197
- storeService.dropReference(fileUrl);
2198
- registerDefaultRoutes();
2199
- }
2200
- });
2201
- (0, import_qunit.test)("an instance live updates from indexing events for an instance update", async function(assert) {
2202
- assert.expect(2);
2203
- let url = `${testRealmURL}Person/hassan`;
2204
- let didSave = false;
2205
- this.onSave(() => {
2206
- didSave = true;
2207
- });
2208
- setCardInOperatorModeState(url);
2209
- await renderComponent(class TestDriver extends Component {
2210
- static {
2211
- setComponentTemplate(templateFactory({
2212
- "id": "ZD1xwmB+",
2213
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
2214
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
2215
- "scope": () => [OperatorModeContainer, noop],
2216
- "isStrictMode": true
2217
- }), this);
2218
- }
2219
- });
2220
- let events = interceptRealmEvents();
2221
- try {
2222
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
2223
- attributes: { name: "Hassan updated" },
2224
- meta: { adoptsFrom: {
2225
- module: testRRI("person"),
2226
- name: "Person"
2227
- } }
2228
- } }));
2229
- let event = await events.nextEventFor(url);
2230
- events.deliver(event);
2231
- await settled();
2232
- } finally {
2233
- events.restore();
2234
- }
2235
- await storeService.flushSaves();
2236
- assert.dom("[data-test-stack-card] [data-test-field=\"name\"]").containsText("Hassan updated", "card live updated");
2237
- assert.false(didSave, "indexing updates do not auto save instances");
2238
- });
2239
- (0, import_qunit.test)("an instance live updates from indexing events for a code update", async function(assert) {
2240
- setCardInOperatorModeState(`${testRealmURL}Person/hassan`);
2241
- await renderComponent(class TestDriver extends Component {
2242
- static {
2243
- setComponentTemplate(templateFactory({
2244
- "id": "ZD1xwmB+",
2245
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
2246
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
2247
- "scope": () => [OperatorModeContainer, noop],
2248
- "isStrictMode": true
2249
- }), this);
2250
- }
2251
- });
2252
- let instance = await storeService.get(`${testRealmURL}Person/hassan`);
2253
- await testRealm.write(`person.gts`, `
2254
- import { contains, field, Component, CardDef, } from '@cardstack/base/card-api';
2255
- import StringField from '@cardstack/base/string';
2256
-
2257
- export class Person extends CardDef {
2258
- @field name = contains(StringField);
2259
- static isolated = class Isolated extends Component<typeof this> {
2260
- <template>
2261
- <div test-update>Hello</div>
2262
- <@fields.firstName />
2263
- </template>
2264
- };
2265
- }`.trim());
2266
- await waitFor("[test-update]", { timeout: 5e3 });
2267
- assert.dom("[test-update]").containsText("Hello", "the instance rendered with the new code");
2268
- let newInstance = storeService.peek(`${testRealmURL}Person/hassan`);
2269
- assert.notStrictEqual(instance[localId], newInstance[localId], "the updated instance is a different object than the original instance");
2270
- });
2271
- (0, import_qunit.test)("an instance live updates to a new type when its adoptsFrom changes", async function(assert) {
2272
- setCardInOperatorModeState(`${testRealmURL}Person/hassan`);
2273
- await renderComponent(class TestDriver extends Component {
2274
- static {
2275
- setComponentTemplate(templateFactory({
2276
- "id": "ZD1xwmB+",
2277
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
2278
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
2279
- "scope": () => [OperatorModeContainer, noop],
2280
- "isStrictMode": true
2281
- }), this);
2282
- }
2283
- });
2284
- let original = storeService.peek(`${testRealmURL}Person/hassan`);
2285
- assert.true(original instanceof PersonDef, "the card starts out as a Person");
2286
- assert.dom("[data-test-employee-badge]").doesNotExist();
2287
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
2288
- attributes: { name: "Hassan" },
2289
- meta: { adoptsFrom: {
2290
- module: testRRI("employee"),
2291
- name: "Employee"
2292
- } }
2293
- } }));
2294
- await waitUntil(() => storeService.peek(`${testRealmURL}Person/hassan`) instanceof EmployeeDef, { timeout: 5e3 });
2295
- let reloaded = storeService.peek(`${testRealmURL}Person/hassan`);
2296
- assert.true(reloaded instanceof EmployeeDef, "the store now holds an Employee instance for the same id");
2297
- await waitFor("[data-test-employee-badge]", { timeout: 5e3 });
2298
- assert.dom("[data-test-employee-badge]").containsText("Employee: Hassan", "the card re-rendered using the new type");
2299
- });
2300
- (0, import_qunit.test)("an instance rebuilds when its adoptsFrom changes to an ancestor type", async function(assert) {
2301
- await testRealm.write("Manager/m1.json", JSON.stringify({ data: {
2302
- attributes: { name: "Hassan" },
2303
- meta: { adoptsFrom: {
2304
- module: testRRI("manager"),
2305
- name: "Manager"
2306
- } }
2307
- } }));
2308
- setCardInOperatorModeState(`${testRealmURL}Manager/m1`);
2309
- await renderComponent(class TestDriver extends Component {
2310
- static {
2311
- setComponentTemplate(templateFactory({
2312
- "id": "ZD1xwmB+",
2313
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
2314
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
2315
- "scope": () => [OperatorModeContainer, noop],
2316
- "isStrictMode": true
2317
- }), this);
2318
- }
2319
- });
2320
- await waitFor("[data-test-manager-badge]");
2321
- let original = storeService.peek(`${testRealmURL}Manager/m1`);
2322
- assert.true(original instanceof ManagerDef, "the card starts as a Manager");
2323
- await testRealm.write("Manager/m1.json", JSON.stringify({ data: {
2324
- attributes: { name: "Hassan" },
2325
- meta: { adoptsFrom: {
2326
- module: testRRI("employee"),
2327
- name: "Employee"
2328
- } }
2329
- } }));
2330
- await waitUntil(() => {
2331
- let c = storeService.peek(`${testRealmURL}Manager/m1`);
2332
- return c instanceof EmployeeDef && !(c instanceof ManagerDef);
2333
- }, { timeout: 5e3 });
2334
- await waitFor("[data-test-employee-badge]", { timeout: 5e3 });
2335
- assert.dom("[data-test-employee-badge]").containsText("Employee: Hassan", "rebuilt as the ancestor type");
2336
- assert.dom("[data-test-manager-badge]").doesNotExist("no longer rendered as the Manager subclass");
2337
- });
2338
- (0, import_qunit.test)("an instance can live update thru an error state", async function(assert) {
2339
- setCardInOperatorModeState(`${testRealmURL}Person/hassan`);
2340
- await renderComponent(class TestDriver extends Component {
2341
- static {
2342
- setComponentTemplate(templateFactory({
2343
- "id": "ZD1xwmB+",
2344
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
2345
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
2346
- "scope": () => [OperatorModeContainer, noop],
2347
- "isStrictMode": true
2348
- }), this);
2349
- }
2350
- });
2351
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
2352
- attributes: {
2353
- name: "Hassan",
2354
- hasError: true
2355
- },
2356
- meta: { adoptsFrom: {
2357
- module: testRRI("person"),
2358
- name: "Person"
2359
- } }
2360
- } }));
2361
- await settled();
2362
- assert.dom("[data-test-card-error]").exists("the card error is shown");
2363
- assert.dom("[data-test-error-message]").containsText("intentional error thrown");
2364
- await click("[data-test-toggle-details]");
2365
- assert.dom("[data-test-error-details]").includesText("Stack trace: Error: Encountered error rendering HTML");
2366
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
2367
- attributes: {
2368
- name: "Hassan",
2369
- hasError: false
2370
- },
2371
- meta: { adoptsFrom: {
2372
- module: testRRI("person"),
2373
- name: "Person"
2374
- } }
2375
- } }));
2376
- await settled();
2377
- assert.dom("[data-test-card-error]").doesNotExist("the error is dismissed");
2378
- assert.dom("[data-test-stack-card] [data-test-field=\"name\"]").containsText("Hassan", "card is still rendered");
2379
- });
2380
- (0, import_qunit.test)("a card the realm has not indexed renders from its source, with its computed fields, and takes the indexed state once indexing lands", async function(assert) {
2381
- let url = `${testRealmURL}Person/unindexed`;
2382
- await testRealmAdapter.write("Person/unindexed.json", JSON.stringify({ data: {
2383
- attributes: { name: "Unindexed" },
2384
- meta: { adoptsFrom: {
2385
- module: testRRI("person"),
2386
- name: "Person"
2387
- } }
2388
- } }));
2389
- setCardInOperatorModeState(url);
2390
- await renderComponent(class TestDriver extends Component {
2391
- static {
2392
- setComponentTemplate(templateFactory({
2393
- "id": "ZD1xwmB+",
2394
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
2395
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
2396
- "scope": () => [OperatorModeContainer, noop],
2397
- "isStrictMode": true
2398
- }), this);
2399
- }
2400
- });
2401
- await settleCardRender(assert, url, `[data-stack-card="${url}"] [data-test-field="name"]`);
2402
- assert.dom("[data-test-card-awaiting-index]").doesNotExist("no placeholder stands in for a card whose source is there");
2403
- assert.dom(`[data-stack-card="${url}"] [data-test-field="name"]`).containsText("Unindexed", "the card renders from its source");
2404
- let instance = storeService.peek(url);
2405
- assert.true(isCardInstance(instance), "the store holds a running card");
2406
- assert.strictEqual(instance.boom, "boom", "its computed field evaluates in the tab");
2407
- await writePerson("Person/unindexed.json", "Indexed Person");
2408
- await settled();
2409
- assert.dom(`[data-stack-card="${url}"] [data-test-field="name"]`).containsText("Indexed Person", "the index event brings the indexed state");
2410
- assert.strictEqual(storeService.peek(url), instance, "into the same instance, so nothing the user holds is swapped out");
2411
- });
2412
- (0, import_qunit.test)("a full reindex re-reads a card built from its source in place", async function(assert) {
2413
- storeService.addReference(`${testRealmURL}Person/hassan`);
2414
- await storeService.flush();
2415
- let url = `${testRealmURL}Person/from-source`;
2416
- await testRealmAdapter.write("Person/from-source.json", JSON.stringify({ data: {
2417
- attributes: { name: "From Source" },
2418
- meta: { adoptsFrom: {
2419
- module: testRRI("person"),
2420
- name: "Person"
2421
- } }
2422
- } }));
2423
- let instance = await storeService.get(url);
2424
- assert.true(isCardInstance(instance), "the read returns a running card rather than a placeholder");
2425
- assert.strictEqual(storeService.peekError(url), void 0, "and records no error for it");
2426
- let events = interceptRealmEvents();
2427
- try {
2428
- await writePerson("Person/from-source.json", "From Source Indexed");
2429
- events.deliver({
2430
- eventName: "index",
2431
- indexType: "full",
2432
- realmURL: testRealmURL
2433
- });
2434
- await settled();
2435
- } finally {
2436
- events.restore();
2437
- }
2438
- assert.strictEqual(storeService.peek(url), instance, "the same instance is still the one the store hands out");
2439
- assert.strictEqual(instance.name, "From Source Indexed", "and it now holds the indexed state");
2440
- });
2441
- (0, import_qunit.test)("a read that reports the index state answers awaiting-index without changing what other reads of the card get", async function(assert) {
2442
- async function writeUnindexed(path, name) {
2443
- await testRealmAdapter.write(path, JSON.stringify({ data: {
2444
- attributes: { name },
2445
- meta: { adoptsFrom: {
2446
- module: testRRI("person"),
2447
- name: "Person"
2448
- } }
2449
- } }));
2450
- }
2451
- let readFirst = `${testRealmURL}Person/report-first`;
2452
- await writeUnindexed("Person/report-first.json", "Report First");
2453
- let reported = await storeService.getWithoutCache(readFirst);
2454
- assert.true(reported.awaitingIndex, "the index-state read reports the card as awaiting index");
2455
- assert.strictEqual(storeService.peekError(readFirst), void 0, "and records nothing in the store");
2456
- assert.true(isCardInstance(await storeService.get(readFirst)), "so opening the card afterwards still builds it from its source");
2457
- let openedFirst = `${testRealmURL}Person/opened-first`;
2458
- await writeUnindexed("Person/opened-first.json", "Opened First");
2459
- let opened = await storeService.get(openedFirst);
2460
- assert.true(isCardInstance(opened), "the opened card is running");
2461
- reported = await storeService.getWithoutCache(openedFirst);
2462
- assert.true(reported.awaitingIndex, "the index-state read is not handed the card built from source");
2463
- assert.strictEqual(storeService.peek(openedFirst), opened, "and the running card stays in place");
2464
- let concurrent = `${testRealmURL}Person/concurrent`;
2465
- await writeUnindexed("Person/concurrent.json", "Concurrent");
2466
- let [got, reportedConcurrently] = await Promise.all([storeService.get(concurrent), storeService.getWithoutCache(concurrent)]);
2467
- assert.true(isCardInstance(got), "the plain read gets the card");
2468
- assert.true(reportedConcurrently.awaitingIndex, "the index-state read gets the awaiting-index answer");
2469
- });
2470
- (0, import_qunit.test)("a read that reports the index state is not handed a card still being built from its source", async function(assert) {
2471
- let url = `${testRealmURL}Person/half-built`;
2472
- await testRealmAdapter.write("Person/half-built.json", JSON.stringify({ data: {
2473
- attributes: { name: "Half Built" },
2474
- meta: { adoptsFrom: {
2475
- module: testRRI("person"),
2476
- name: "Person"
2477
- } }
2478
- } }));
2479
- let reachedBuilt = new Deferred();
2480
- let releaseBuilt = new Deferred();
2481
- let service = storeService;
2482
- let createFromSerialized = service.createFromSerialized.bind(service);
2483
- service.createFromSerialized = async (resource, ...rest) => {
2484
- let instance = await createFromSerialized(resource, ...rest);
2485
- if (String(resource?.id ?? "").includes("Person/half-built")) {
2486
- reachedBuilt.fulfill();
2487
- await releaseBuilt.promise;
2488
- }
2489
- return instance;
2490
- };
2491
- let reported;
2492
- let opening;
2493
- try {
2494
- opening = storeService.get(url);
2495
- await reachedBuilt.promise;
2496
- assert.true(isCardInstance(storeService.peek(url)), "the card being built is already in the identity map");
2497
- reported = await storeService.getWithoutCache(url);
2498
- } finally {
2499
- releaseBuilt.fulfill();
2500
- delete service.createFromSerialized;
2501
- }
2502
- assert.true(reported?.awaitingIndex, "the index-state read gets the awaiting-index answer, not the card being built");
2503
- assert.true(isCardInstance(await opening), "and the read that was building the card still gets it");
2504
- });
2505
- (0, import_qunit.test)("an index event that lands while a card is being built from its source re-reads it once it is built", async function(assert) {
2506
- storeService.addReference(`${testRealmURL}Person/hassan`);
2507
- await storeService.flush();
2508
- let url = `${testRealmURL}Person/source-racing`;
2509
- await testRealmAdapter.write("Person/source-racing.json", JSON.stringify({ data: {
2510
- attributes: { name: "Source Racing" },
2511
- meta: { adoptsFrom: {
2512
- module: testRRI("person"),
2513
- name: "Person"
2514
- } }
2515
- } }));
2516
- let reachedSource = new Deferred();
2517
- let releaseSource = new Deferred();
2518
- let loadCardDocument = cardStore.loadCardDocument.bind(cardStore);
2519
- cardStore.loadCardDocument = async (sourceURL, opts) => {
2520
- let doc = await loadCardDocument(sourceURL, opts);
2521
- if (sourceURL.includes("Person/source-racing")) {
2522
- reachedSource.fulfill();
2523
- await releaseSource.promise;
2524
- }
2525
- return doc;
2526
- };
2527
- let events = interceptRealmEvents();
2528
- try {
2529
- let reading = storeService.get(url);
2530
- await reachedSource.promise;
2531
- await writePerson("Person/source-racing.json", "Source Racing Person");
2532
- events.deliver({
2533
- eventName: "index",
2534
- indexType: "incremental",
2535
- invalidations: [url],
2536
- realmURL: testRealmURL
2537
- });
2538
- releaseSource.fulfill();
2539
- await reading;
2540
- await settled();
2541
- } finally {
2542
- releaseSource.fulfill();
2543
- delete cardStore.loadCardDocument;
2544
- events.restore();
2545
- }
2546
- assert.strictEqual(storeService.peek(url)?.name, "Source Racing Person", "the store re-reads the card rather than keeping the source it read before the write");
2547
- });
2548
- (0, import_qunit.test)("a card the realm has not indexed and whose source cannot be read shows as being prepared, then renders once indexing lands", async function(assert) {
2549
- withholdSource("Person/pending");
2550
- await testRealmAdapter.write("Person/pending.json", JSON.stringify({ data: {
2551
- attributes: { name: "Pending" },
2552
- meta: { adoptsFrom: {
2553
- module: testRRI("person"),
2554
- name: "Person"
2555
- } }
2556
- } }));
2557
- setCardInOperatorModeState(`${testRealmURL}Person/pending`);
2558
- await renderComponent(class TestDriver extends Component {
2559
- static {
2560
- setComponentTemplate(templateFactory({
2561
- "id": "ZD1xwmB+",
2562
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
2563
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
2564
- "scope": () => [OperatorModeContainer, noop],
2565
- "isStrictMode": true
2566
- }), this);
2567
- }
2568
- });
2569
- await waitFor("[data-test-card-awaiting-index]");
2570
- assert.dom("[data-test-card-awaiting-index]").containsText("Preparing this card", "the card reads as on its way rather than missing");
2571
- assert.dom("[data-test-card-error]").doesNotExist("no card error is reported");
2572
- await testRealm.write("Person/pending.json", JSON.stringify({ data: {
2573
- attributes: { name: "Pending Person" },
2574
- meta: { adoptsFrom: {
2575
- module: testRRI("person"),
2576
- name: "Person"
2577
- } }
2578
- } }));
2579
- await settled();
2580
- let id = `${testRealmURL}Person/pending`;
2581
- if (document.querySelector("[data-test-card-awaiting-index]")) {
2582
- let realmEvents = mockMatrixUtils.getRoomIds().flatMap((roomId) => mockMatrixUtils.getRoomEvents(roomId)).filter((event) => event.type === APP_BOXEL_REALM_EVENT_TYPE).sort((a, b) => a.origin_server_ts - b.origin_server_ts).slice(-5).map((event) => event.content);
2583
- console.warn(`[awaiting-index-placeholder flake-probe] placeholder still shown after settled(). store error=${JSON.stringify(storeService.peekError(id) ?? null)}; store holds instance=${isCardInstance(storeService.peek(id))}; last realm events in mock homeserver=${JSON.stringify(realmEvents)}.`);
2584
- }
2585
- assert.dom("[data-test-card-awaiting-index]").doesNotExist("the placeholder is gone once the card is indexed");
2586
- assert.dom(`[data-stack-card="${testRealmURL}Person/pending"] [data-test-field="name"]`).containsText("Pending Person", "the real card takes over once it is indexed");
2587
- });
2588
- (0, import_qunit.test)("an index event that lands while the first read is in flight still resolves the placeholder", async function(assert) {
2589
- withholdSource("Person/racing");
2590
- storeService.addReference(`${testRealmURL}Person/hassan`);
2591
- await storeService.flush();
2592
- await testRealmAdapter.write("Person/racing.json", JSON.stringify({ data: {
2593
- attributes: { name: "Racing" },
2594
- meta: { adoptsFrom: {
2595
- module: testRRI("person"),
2596
- name: "Person"
2597
- } }
2598
- } }));
2599
- let cardService = getService("card-service");
2600
- let originalFetchJSON = cardService.fetchJSON.bind(cardService);
2601
- let reached404 = new Deferred();
2602
- let release404 = new Deferred();
2603
- cardService.fetchJSON = async (url, args) => {
2604
- if (!String(url).includes("Person/racing")) return originalFetchJSON(url, args);
2605
- try {
2606
- return await originalFetchJSON(url, args);
2607
- } catch (err) {
2608
- reached404.fulfill();
2609
- await release404.promise;
2610
- throw err;
2611
- }
2612
- };
2613
- let messageService = getService("message-service");
2614
- let deliverRealmEvents = messageService.relayRealmEvent.bind(messageService);
2615
- messageService.relayRealmEvent = () => {};
2616
- try {
2617
- let reading = storeService.get(`${testRealmURL}Person/racing`);
2618
- await reached404.promise;
2619
- await testRealm.write("Person/racing.json", JSON.stringify({ data: {
2620
- attributes: { name: "Racing Person" },
2621
- meta: { adoptsFrom: {
2622
- module: testRRI("person"),
2623
- name: "Person"
2624
- } }
2625
- } }));
2626
- deliverRealmEvents({
2627
- eventName: "index",
2628
- indexType: "incremental",
2629
- invalidations: [`${testRealmURL}Person/racing`],
2630
- realmURL: testRealmURL
2631
- });
2632
- release404.fulfill();
2633
- await reading;
2634
- await settled();
2635
- } finally {
2636
- release404.fulfill();
2637
- delete cardService.fetchJSON;
2638
- messageService.relayRealmEvent = deliverRealmEvents;
2639
- }
2640
- let instance = storeService.peek(`${testRealmURL}Person/racing`);
2641
- assert.true(isCardInstance(instance), "the store holds the card rather than the stale placeholder");
2642
- assert.strictEqual(instance.name, "Racing Person", "and it is the indexed state");
2643
- });
2644
- (0, import_qunit.test)("a full reindex resolves a placeholder even though it names no cards", async function(assert) {
2645
- withholdSource("Person/swept");
2646
- storeService.addReference(`${testRealmURL}Person/hassan`);
2647
- await storeService.flush();
2648
- await testRealmAdapter.write("Person/swept.json", JSON.stringify({ data: {
2649
- attributes: { name: "Swept" },
2650
- meta: { adoptsFrom: {
2651
- module: testRRI("person"),
2652
- name: "Person"
2653
- } }
2654
- } }));
2655
- let placeholder = await storeService.get(`${testRealmURL}Person/swept`);
2656
- assert.true(placeholder.awaitingIndex, "the read leaves an awaiting-index placeholder");
2657
- let messageService = getService("message-service");
2658
- let deliverRealmEvents = messageService.relayRealmEvent.bind(messageService);
2659
- messageService.relayRealmEvent = () => {};
2660
- try {
2661
- await testRealm.write("Person/swept.json", JSON.stringify({ data: {
2662
- attributes: { name: "Swept Person" },
2663
- meta: { adoptsFrom: {
2664
- module: testRRI("person"),
2665
- name: "Person"
2666
- } }
2667
- } }));
2668
- deliverRealmEvents({
2669
- eventName: "index",
2670
- indexType: "full",
2671
- realmURL: testRealmURL
2672
- });
2673
- await settled();
2674
- } finally {
2675
- messageService.relayRealmEvent = deliverRealmEvents;
2676
- }
2677
- let instance = storeService.peek(`${testRealmURL}Person/swept`);
2678
- assert.true(isCardInstance(instance), "the sweep replaced the placeholder with the card");
2679
- assert.strictEqual(instance.name, "Swept Person", "and it is the indexed state");
2680
- });
2681
- (0, import_qunit.test)("a reload that 404s while the row is being rebuilt keeps the card instead of deleting it", async function(assert) {
2682
- let url = `${testRealmURL}Person/rebuilt`;
2683
- await testRealm.write("Person/rebuilt.json", JSON.stringify({ data: {
2684
- attributes: { name: "Rebuilt" },
2685
- meta: { adoptsFrom: {
2686
- module: testRRI("person"),
2687
- name: "Person"
2688
- } }
2689
- } }));
2690
- storeService.addReference(url);
2691
- await storeService.flush();
2692
- assert.true(isCardInstance(storeService.peek(url)), "the card starts out loaded");
2693
- let messageService = getService("message-service");
2694
- let deliverRealmEvents = messageService.relayRealmEvent.bind(messageService);
2695
- messageService.relayRealmEvent = () => {};
2696
- try {
2697
- await testRealm.delete("Person/rebuilt.json");
2698
- await testRealmAdapter.write("Person/rebuilt.json", JSON.stringify({ data: {
2699
- attributes: { name: "Rebuilt" },
2700
- meta: { adoptsFrom: {
2701
- module: testRRI("person"),
2702
- name: "Person"
2703
- } }
2704
- } }));
2705
- deliverRealmEvents({
2706
- eventName: "index",
2707
- indexType: "incremental",
2708
- invalidations: [url],
2709
- realmURL: testRealmURL
2710
- });
2711
- await settled();
2712
- } finally {
2713
- messageService.relayRealmEvent = deliverRealmEvents;
2714
- }
2715
- assert.true(isCardInstance(storeService.peek(url)), "the card is still in the store — nothing was deleted");
2716
- assert.strictEqual(storeService.peekError(url), void 0, "and it is left alone rather than covered by a placeholder");
2717
- });
2718
- (0, import_qunit.test)("a card already running in the store is never displaced by the awaiting-index placeholder", async function(assert) {
2719
- let instance = await storeService.add(new PersonDef({ name: "Brand New" }));
2720
- let url = instance.id;
2721
- assert.ok(url, "the new card was assigned a remote id");
2722
- let messageService = getService("message-service");
2723
- let deliverRealmEvents = messageService.relayRealmEvent.bind(messageService);
2724
- messageService.relayRealmEvent = () => {};
2725
- let cardService = getService("card-service");
2726
- let originalFetchJSON = cardService.fetchJSON.bind(cardService);
2727
- cardService.fetchJSON = async (fetchUrl, args) => {
2728
- if (String(fetchUrl).includes(url)) {
2729
- let err = /* @__PURE__ */ new Error("awaiting index");
2730
- err.status = 404;
2731
- err.responseText = JSON.stringify({ errors: [{
2732
- id: url,
2733
- status: 404,
2734
- title: "Not Found",
2735
- message: `${url} has not finished indexing`,
2736
- isCardError: true,
2737
- awaitingIndex: true,
2738
- additionalErrors: null
2739
- }] });
2740
- throw err;
2741
- }
2742
- return originalFetchJSON(fetchUrl, args);
2743
- };
2744
- try {
2745
- deliverRealmEvents({
2746
- eventName: "index",
2747
- indexType: "incremental",
2748
- invalidations: [url],
2749
- realmURL: testRealmURL
2750
- });
2751
- await settled();
2752
- } finally {
2753
- delete cardService.fetchJSON;
2754
- messageService.relayRealmEvent = deliverRealmEvents;
2755
- }
2756
- assert.strictEqual(storeService.peek(url), instance, "the running instance is still the one the store hands out");
2757
- assert.strictEqual(storeService.peekError(url), void 0, "no placeholder stands in front of it");
2758
- assert.ok(storeService.getSaveState(url), "and it is still autosaving, so the user can keep editing");
2759
- });
2760
- (0, import_qunit.test)("a full reindex resolves a placeholder whose read was still in flight when it landed", async function(assert) {
2761
- withholdSource("Person/swept-inflight");
2762
- storeService.addReference(`${testRealmURL}Person/hassan`);
2763
- await storeService.flush();
2764
- await testRealmAdapter.write("Person/swept-inflight.json", JSON.stringify({ data: {
2765
- attributes: { name: "Swept In Flight" },
2766
- meta: { adoptsFrom: {
2767
- module: testRRI("person"),
2768
- name: "Person"
2769
- } }
2770
- } }));
2771
- let url = `${testRealmURL}Person/swept-inflight`;
2772
- let cardService = getService("card-service");
2773
- let originalFetchJSON = cardService.fetchJSON.bind(cardService);
2774
- let reached404 = new Deferred();
2775
- let release404 = new Deferred();
2776
- cardService.fetchJSON = async (fetchUrl, args) => {
2777
- if (!String(fetchUrl).includes("Person/swept-inflight")) return originalFetchJSON(fetchUrl, args);
2778
- try {
2779
- return await originalFetchJSON(fetchUrl, args);
2780
- } catch (err) {
2781
- reached404.fulfill();
2782
- await release404.promise;
2783
- throw err;
2784
- }
2785
- };
2786
- let messageService = getService("message-service");
2787
- let deliverRealmEvents = messageService.relayRealmEvent.bind(messageService);
2788
- messageService.relayRealmEvent = () => {};
2789
- try {
2790
- let reading = storeService.get(url);
2791
- await reached404.promise;
2792
- await testRealm.write("Person/swept-inflight.json", JSON.stringify({ data: {
2793
- attributes: { name: "Swept In Flight Person" },
2794
- meta: { adoptsFrom: {
2795
- module: testRRI("person"),
2796
- name: "Person"
2797
- } }
2798
- } }));
2799
- deliverRealmEvents({
2800
- eventName: "index",
2801
- indexType: "full",
2802
- realmURL: testRealmURL
2803
- });
2804
- release404.fulfill();
2805
- await reading;
2806
- await settled();
2807
- } finally {
2808
- release404.fulfill();
2809
- delete cardService.fetchJSON;
2810
- messageService.relayRealmEvent = deliverRealmEvents;
2811
- }
2812
- let instance = storeService.peek(url);
2813
- assert.true(isCardInstance(instance), "the card takes over rather than the placeholder being stranded");
2814
- assert.strictEqual(instance.name, "Swept In Flight Person", "and it is the indexed state");
2815
- });
2816
- (0, import_qunit.test)("a duplicate incremental event does not reload a card the store already holds at that generation", async function(assert) {
2817
- let url = `${testRealmURL}Person/echoed`;
2818
- let events = interceptRealmEvents();
2819
- let reads;
2820
- try {
2821
- await writePerson("Person/echoed.json", "Echoed");
2822
- await events.nextEventFor(url);
2823
- storeService.addReference(url);
2824
- await storeService.flush();
2825
- await writePerson("Person/echoed.json", "Echoed Again");
2826
- let event = await events.nextEventFor(url);
2827
- assert.strictEqual(typeof event.generation, "number", "the realm reported the generation its pass committed");
2828
- let { versions: _versions, ...onGeneration } = event;
2829
- reads = countCardReads("Person/echoed");
2830
- events.deliver(onGeneration);
2831
- await settled();
2832
- assert.strictEqual(reads.count, 1, "the event is acted on once");
2833
- assert.strictEqual(storeService.peek(url).name, "Echoed Again", "and the store holds what the pass wrote");
2834
- events.deliver(onGeneration);
2835
- await settled();
2836
- assert.strictEqual(reads.count, 1, "the same event delivered a second time is a no-op");
2837
- let { generation: _generation, ...withoutGeneration } = onGeneration;
2838
- events.deliver(withoutGeneration);
2839
- await settled();
2840
- assert.strictEqual(reads.count, 2, "while an otherwise identical event carrying no generation does reload");
2841
- } finally {
2842
- reads?.stop();
2843
- events.restore();
2844
- }
2845
- });
2846
- (0, import_qunit.test)("a duplicate arriving while the first reload is still in flight is coalesced into it", async function(assert) {
2847
- let url = `${testRealmURL}Person/coalesced`;
2848
- let events = interceptRealmEvents();
2849
- let reads;
2850
- try {
2851
- await writePerson("Person/coalesced.json", "Coalesced");
2852
- await events.nextEventFor(url);
2853
- storeService.addReference(url);
2854
- await storeService.flush();
2855
- await writePerson("Person/coalesced.json", "Coalesced Again");
2856
- let event = await events.nextEventFor(url);
2857
- reads = countCardReads("Person/coalesced");
2858
- events.deliver(event);
2859
- events.deliver(event);
2860
- await settled();
2861
- assert.strictEqual(reads.count, 1, "the duplicate is answered by the reload already in flight");
2862
- assert.strictEqual(storeService.peek(url).name, "Coalesced Again", "and that reload still brought the state the pass wrote");
2863
- let { generation: _generation, versions: _versions, ...bare } = event;
2864
- events.deliver(bare);
2865
- events.deliver(bare);
2866
- await settled();
2867
- assert.strictEqual(reads.count, 3, "while a pair carrying neither member reloads twice");
2868
- } finally {
2869
- reads?.stop();
2870
- events.restore();
2871
- }
2872
- });
2873
- (0, import_qunit.test)("an incremental event overtaken by a newer one does not reload", async function(assert) {
2874
- let url = `${testRealmURL}Person/overtaken`;
2875
- let events = interceptRealmEvents();
2876
- let reads;
2877
- try {
2878
- await writePerson("Person/overtaken.json", "Overtaken");
2879
- await events.nextEventFor(url);
2880
- storeService.addReference(url);
2881
- await storeService.flush();
2882
- await writePerson("Person/overtaken.json", "Second");
2883
- let earlier = await events.nextEventFor(url);
2884
- await writePerson("Person/overtaken.json", "Third");
2885
- let later = await events.nextEventFor(url);
2886
- assert.true(later.generation > earlier.generation, "the two passes are ordered by generation");
2887
- reads = countCardReads("Person/overtaken");
2888
- events.deliver(later);
2889
- await settled();
2890
- assert.strictEqual(reads.count, 1, "the newer event is acted on");
2891
- assert.strictEqual(storeService.peek(url).name, "Third", "and the store holds the state that pass wrote");
2892
- events.deliver(earlier);
2893
- await settled();
2894
- assert.strictEqual(reads.count, 1, "the older event arriving after it is ignored");
2895
- } finally {
2896
- reads?.stop();
2897
- events.restore();
2898
- }
2899
- });
2900
- (0, import_qunit.test)("a write's echo is recognized by its version once the request id has aged out of this client's memory", async function(assert) {
2901
- let url = `${testRealmURL}Person/aged-out`;
2902
- let events = interceptRealmEvents();
2903
- let reads;
2904
- try {
2905
- await writePerson("Person/aged-out.json", "Aged Out");
2906
- await events.nextEventFor(url);
2907
- storeService.addReference(url);
2908
- await storeService.flush();
2909
- let instance = storeService.peek(url);
2910
- instance.name = "Aged Out Edit";
2911
- storeService.save(url);
2912
- await settled();
2913
- let event = await events.nextEventFor(url);
2914
- assert.true(event.generation > api.getCardMeta(instance, "generation"), "the event names a generation past the one the store holds");
2915
- assert.strictEqual(api.getCardMeta(instance, "version"), event.versions?.[url], "and the store recorded the version its own write returned");
2916
- let agedOut = {
2917
- ...event,
2918
- clientRequestId: "instance:aged-out-of-this-clients-memory"
2919
- };
2920
- reads = countCardReads("Person/aged-out");
2921
- events.deliver(agedOut);
2922
- await settled();
2923
- assert.strictEqual(reads.count, 0, "the echo of our own write is not read back");
2924
- assert.strictEqual(storeService.peek(url).name, "Aged Out Edit", "and the edit stands");
2925
- let { versions: _versions, ...withoutVersions } = agedOut;
2926
- events.deliver(withoutVersions);
2927
- await settled();
2928
- assert.strictEqual(reads.count, 1, "while the same event without the map does reload");
2929
- } finally {
2930
- reads?.stop();
2931
- events.restore();
2932
- }
2933
- });
2934
- (0, import_qunit.test)("a reload still in flight when the store is reset leaves the replacement identity map alone", async function(assert) {
2935
- let url = `${testRealmURL}Person/reset-mid-reload`;
2936
- let events = interceptRealmEvents();
2937
- let cardService = getService("card-service");
2938
- let originalFetchJSON = cardService.fetchJSON.bind(cardService);
2939
- let readHeld = new Deferred();
2940
- let releaseRead = new Deferred();
2941
- let holding = false;
2942
- try {
2943
- await writePerson("Person/reset-mid-reload.json", "Before Reset");
2944
- await events.nextEventFor(url);
2945
- storeService.addReference(url);
2946
- await storeService.flush();
2947
- let preReset = storeService.peek(url);
2948
- await writePerson("Person/reset-mid-reload.json", "After Reset");
2949
- let event = await events.nextEventFor(url);
2950
- holding = true;
2951
- cardService.fetchJSON = async (fetchUrl, args) => {
2952
- if (holding && String(fetchUrl).includes("Person/reset-mid-reload") && (args?.method ?? "GET") === "GET") {
2953
- holding = false;
2954
- readHeld.fulfill();
2955
- await releaseRead.promise;
2956
- }
2957
- return originalFetchJSON(fetchUrl, args);
2958
- };
2959
- events.deliver(event);
2960
- await readHeld.promise;
2961
- storeService.resetCache();
2962
- let replacement = await storeService.get(url);
2963
- assert.notStrictEqual(replacement[localId], preReset[localId], "the replacement identity map loads its own instance of the card");
2964
- releaseRead.fulfill();
2965
- await settled();
2966
- assert.strictEqual(storeService.peek(url), replacement, "the resumed reload leaves the replacement instance in place");
2967
- assert.strictEqual(storeService.peekError(url)?.message, void 0, "and records no error for the card");
2968
- assert.strictEqual(replacement.name, "After Reset", "the replacement holds the state the realm wrote");
2969
- } finally {
2970
- releaseRead.fulfill();
2971
- delete cardService.fetchJSON;
2972
- events.restore();
2973
- }
2974
- });
2975
- (0, import_qunit.test)("a reload still in flight when a code change resets identity in place leaves the re-established instance alone", async function(assert) {
2976
- let url = `${testRealmURL}Person/code-change-mid-reload`;
2977
- let events = interceptRealmEvents();
2978
- let cardService = getService("card-service");
2979
- let originalFetchJSON = cardService.fetchJSON.bind(cardService);
2980
- let readHeld = new Deferred();
2981
- let releaseRead = new Deferred();
2982
- let holding = false;
2983
- try {
2984
- await writePerson("Person/code-change-mid-reload.json", "Before Reset");
2985
- await events.nextEventFor(url);
2986
- storeService.addReference(url);
2987
- await storeService.flush();
2988
- let preReset = storeService.peek(url);
2989
- await writePerson("Person/code-change-mid-reload.json", "After Reset");
2990
- let event = await events.nextEventFor(url);
2991
- holding = true;
2992
- cardService.fetchJSON = async (fetchUrl, args) => {
2993
- if (holding && String(fetchUrl).includes("Person/code-change-mid-reload") && (args?.method ?? "GET") === "GET") {
2994
- holding = false;
2995
- readHeld.fulfill();
2996
- await releaseRead.promise;
2997
- }
2998
- return originalFetchJSON(fetchUrl, args);
2999
- };
3000
- events.deliver(event);
3001
- await readHeld.promise;
3002
- storeService.refreshReferencesForCodeChange("test code change");
3003
- let reestablished = await storeService.get(url);
3004
- assert.strictEqual(storeService.peek(url), reestablished, "the store holds the instance the code change re-established");
3005
- assert.notStrictEqual(reestablished[localId], preReset[localId], "the code change re-establishes the card as a fresh instance");
3006
- releaseRead.fulfill();
3007
- await settled();
3008
- assert.strictEqual(storeService.peek(url), reestablished, "the resumed reload leaves the re-established instance in place");
3009
- assert.strictEqual(storeService.peekError(url)?.message, void 0, "and records no error for the card");
3010
- assert.strictEqual(reestablished.name, "After Reset", "the re-established instance holds the state the realm wrote");
3011
- } finally {
3012
- releaseRead.fulfill();
3013
- delete cardService.fetchJSON;
3014
- events.restore();
3015
- }
3016
- });
3017
- async function holdIndexQueue() {
3018
- let { queue } = getService("queue");
3019
- let started = new Deferred();
3020
- let release = new Deferred();
3021
- queue.register("hold-index-queue", async () => {
3022
- started.fulfill();
3023
- await release.promise;
3024
- return null;
3025
- });
3026
- let holder = await queue.publish({
3027
- jobType: "hold-index-queue",
3028
- concurrencyGroup: null,
3029
- timeout: 30,
3030
- args: null
3031
- });
3032
- await started.promise;
3033
- let pendingCallers = () => queue.jobs.filter((job) => job.jobType === "incremental-index").flatMap((job) => (job.args?.coalescedCallers ?? []).map((caller) => caller.clientRequestId));
3034
- let published = [];
3035
- let arrivals = [];
3036
- let heldAt = performance.now();
3037
- let publish = queue.publish.bind(queue);
3038
- queue.publish = async (args) => {
3039
- let job = await publish(args);
3040
- published.push({
3041
- jobType: args.jobType,
3042
- at: Math.round(performance.now() - heldAt)
3043
- });
3044
- for (let arrival of [...arrivals]) if (arrival.ready()) {
3045
- arrivals.splice(arrivals.indexOf(arrival), 1);
3046
- arrival.deferred.fulfill();
3047
- }
3048
- return job;
3049
- };
3050
- let callersArrive = async (description, ready) => {
3051
- if (ready(pendingCallers())) return;
3052
- let deferred = new Deferred();
3053
- let arrival = {
3054
- ready: () => ready(pendingCallers()),
3055
- deferred
3056
- };
3057
- arrivals.push(arrival);
3058
- let guard = setTimeout(() => {
3059
- arrivals.splice(arrivals.indexOf(arrival), 1);
3060
- deferred.reject(/* @__PURE__ */ new Error(`the held index pass never had ${description}: callers=${JSON.stringify(pendingCallers())} publishes=${JSON.stringify(published)}`));
3061
- }, 2e4);
3062
- try {
3063
- await deferred.promise;
3064
- } finally {
3065
- clearTimeout(guard);
3066
- }
3067
- };
3068
- return {
3069
- holder,
3070
- release,
3071
- pendingCallers,
3072
- callersArrive
3073
- };
3074
- }
3075
- (0, import_qunit.test)("this client's own write, announced under another writer's id in a pass they shared, is not read back", async function(assert) {
3076
- let mine = `${testRealmURL}Person/shared-mine`;
3077
- let theirs = `${testRealmURL}Person/shared-theirs`;
3078
- let events = interceptRealmEvents();
3079
- let reads;
3080
- let theirReads;
3081
- let hold;
3082
- try {
3083
- await writePerson("Person/shared-mine.json", "Mine");
3084
- await events.nextEventFor(mine);
3085
- await writePerson("Person/shared-theirs.json", "Theirs");
3086
- await events.nextEventFor(theirs);
3087
- storeService.addReference(mine);
3088
- storeService.addReference(theirs);
3089
- await storeService.flush();
3090
- hold = await holdIndexQueue();
3091
- let theirWrite = testRealm.write("Person/shared-theirs.json", JSON.stringify({ data: {
3092
- attributes: { name: "Theirs Edited" },
3093
- meta: { adoptsFrom: {
3094
- module: testRRI("person"),
3095
- name: "Person"
3096
- } }
3097
- } }), { clientRequestId: "instance:another-tab" });
3098
- await hold.callersArrive("the other writer's write", (callers) => callers.includes("instance:another-tab"));
3099
- let instance = storeService.peek(mine);
3100
- instance.name = "Mine Edited";
3101
- let ownSave = storeService.save(mine);
3102
- await hold.callersArrive("this client's save", (callers) => callers.length === 2);
3103
- hold.release.fulfill();
3104
- await Promise.all([
3105
- theirWrite,
3106
- ownSave,
3107
- hold.holder.done
3108
- ]);
3109
- await settled();
3110
- let event = await events.nextEventFor(mine);
3111
- assert.strictEqual(event.clientRequestId, "instance:another-tab", "the pass is announced under the other writer's id");
3112
- assert.deepEqual([...event.invalidations].sort(), [mine, theirs].sort(), "and it carries both writes");
3113
- assert.strictEqual(event.coalescedWrites?.length, 2, "with both writers among its coalesced writes");
3114
- reads = countCardReads("Person/shared-mine");
3115
- theirReads = countCardReads("Person/shared-theirs");
3116
- events.deliver(event);
3117
- await settled();
3118
- assert.strictEqual(reads.count, 0, "the card this client wrote is not read back");
3119
- assert.strictEqual(storeService.peek(mine).name, "Mine Edited", "and its edit stands");
3120
- assert.strictEqual(theirReads.count, 1, "while the card the other writer changed is");
3121
- assert.strictEqual(storeService.peek(theirs).name, "Theirs Edited", "and the store holds what that writer wrote");
3122
- let { coalescedWrites: _coalescedWrites, ...announcedAlone } = event;
3123
- events.deliver(announcedAlone);
3124
- await settled();
3125
- assert.strictEqual(reads.count, 1, "while the same event without its coalesced writes reads it back");
3126
- } finally {
3127
- hold?.release.fulfill();
3128
- reads?.stop();
3129
- theirReads?.stop();
3130
- events.restore();
3131
- }
3132
- });
3133
- (0, import_qunit.test)("an instance can be restored after a loader reset", async function(assert) {
3134
- setCardInOperatorModeState(`${testRealmURL}Person/hassan`);
3135
- await renderComponent(class TestDriver extends Component {
3136
- static {
3137
- setComponentTemplate(templateFactory({
3138
- "id": "ZD1xwmB+",
3139
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
3140
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3141
- "scope": () => [OperatorModeContainer, noop],
3142
- "isStrictMode": true
3143
- }), this);
3144
- }
3145
- });
3146
- assert.dom(`[data-stack-card="${testRealmURL}Person/hassan"] [data-test-field="name"]`).containsText("Hassan", "the card data is correct");
3147
- await testRealm.write(`foo.gts`, `
3148
- import { contains, CardDef } from '@cardstack/base/card-api';
3149
- export class Foo extends CardDef {}
3150
- `.trim());
3151
- await waitFor("[data-test-stack-item-loading-card]", {
3152
- count: 0,
3153
- timeout: 5e3
3154
- });
3155
- assert.dom("[data-test-stack-item-loading-card]").doesNotExist("loading state is not displayed");
3156
- assert.dom(`[data-stack-card="${testRealmURL}Person/hassan"] [data-test-field="name"]`).containsText("Hassan", "the card data is correct");
3157
- });
3158
- (0, import_qunit.test)("an instance that started out with a local ID can be restored after a loader reset", async function(assert) {
3159
- let newInstance = new PersonDef({ name: "Andrea" });
3160
- await storeService.add(newInstance, { realm: testRealmURL });
3161
- setCardInOperatorModeState(newInstance[localId]);
3162
- await renderComponent(class TestDriver extends Component {
3163
- static {
3164
- setComponentTemplate(templateFactory({
3165
- "id": "ZD1xwmB+",
3166
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
3167
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3168
- "scope": () => [OperatorModeContainer, noop],
3169
- "isStrictMode": true
3170
- }), this);
3171
- }
3172
- });
3173
- assert.dom(`[data-stack-card="${newInstance.id}"] [data-test-field="name"]`).containsText("Andrea", "the card data is correct");
3174
- await testRealm.write(`foo.gts`, `
3175
- import { contains, CardDef } from '@cardstack/base/card-api';
3176
- export class Foo extends CardDef {}
3177
- `.trim());
3178
- await waitFor("[data-test-stack-item-loading-card]", {
3179
- count: 0,
3180
- timeout: 5e3
3181
- });
3182
- assert.dom("[data-test-stack-item-loading-card]").doesNotExist("loading state is not displayed");
3183
- assert.dom(`[data-stack-card="${newInstance.id}"] [data-test-field="name"]`).containsText("Andrea", "the card data is correct");
3184
- });
3185
- (0, import_qunit.test)("an unsaved instance live updates when realm event matching local ID is received", async function(assert) {
3186
- let newInstance = new PersonDef({ name: "Andrea" });
3187
- await storeService.addWithoutPersisting(newInstance);
3188
- storeService.addReference(`${testRealmURL}Person/hassan`);
3189
- await storeService.flush();
3190
- let instance = storeService.peek(`${testRealmURL}Person/hassan`);
3191
- instance.friends = [newInstance];
3192
- await waitUntil(() => newInstance.id, { timeout: 5e3 });
3193
- assert.strictEqual(newInstance.id.split("/").pop(), newInstance[localId], "the new instance was live updated with a remote id");
3194
- });
3195
- (0, import_qunit.test)("an unsaved instance will auto save after it has been assigned a remote ID", async function(assert) {
3196
- assert.expect(2);
3197
- let newInstance = new PersonDef({ name: "Andrea" });
3198
- await storeService.addWithoutPersisting(newInstance);
3199
- storeService.addReference(`${testRealmURL}Person/hassan`);
3200
- await storeService.flush();
3201
- let instance = storeService.peek(`${testRealmURL}Person/hassan`);
3202
- instance.friends = [newInstance];
3203
- await waitUntil(() => newInstance.id, { timeout: 5e3 });
3204
- this.onSave((url, doc) => {
3205
- if (url.href === newInstance.id) {
3206
- assert.strictEqual(url.href, newInstance.id, "the save url is correct");
3207
- assert.strictEqual(doc.data.attributes?.name, "Air", "card data is correct");
3208
- }
3209
- });
3210
- newInstance.name = "Air";
3211
- });
3212
- (0, import_qunit.test)("reference count is balanced when used with CardResource that is destroyed", async function(assert) {
3213
- class Driver {
3214
- static {
3215
- decorateFieldV2(this.prototype, "showComponent", [tracked], function() {
3216
- return false;
3217
- });
3218
- }
3219
- #showComponent = (initializeDeferredDecorator(this, "showComponent"), void 0);
3220
- static {
3221
- decorateFieldV2(this.prototype, "id", [tracked]);
3222
- }
3223
- #id = (initializeDeferredDecorator(this, "id"), void 0);
3224
- }
3225
- let driver = new Driver();
3226
- class ResourceConsumer extends Component {
3227
- resource = getCard(this, () => driver.id);
3228
- get renderedCard() {
3229
- return this.resource.card?.constructor.getComponent(this.resource.card);
3230
- }
3231
- static {
3232
- setComponentTemplate(templateFactory({
3233
- "id": "XWrL4bCI",
3234
- "block": "[[[41,[30,0,[\"resource\",\"card\"]],[[[1,\" \"],[8,[30,0,[\"renderedCard\"]],[[16,\"data-test-rendered-card\",[30,0,[\"resource\",\"id\"]]]],null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3235
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3236
- "isStrictMode": true
3237
- }), this);
3238
- }
3239
- }
3240
- await renderComponent(class TestDriver extends Component {
3241
- static {
3242
- setComponentTemplate(templateFactory({
3243
- "id": "hNRtWalG",
3244
- "block": "[[[41,[32,0,[\"showComponent\"]],[[[1,\" \"],[8,[32,1],null,null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3245
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3246
- "scope": () => [driver, ResourceConsumer],
3247
- "isStrictMode": true
3248
- }), this);
3249
- }
3250
- });
3251
- driver.showComponent = true;
3252
- let jade = `${testRealmURL}Person/jade`;
3253
- let hassan = `${testRealmURL}Person/hassan`;
3254
- driver.id = hassan;
3255
- await settleCardRender(assert, hassan, `[data-test-rendered-card="${hassan}"]`);
3256
- assert.strictEqual(storeService.getReferenceCount(jade), 0, `reference count for ${jade} is 0`);
3257
- assert.strictEqual(storeService.getReferenceCount(hassan), 1, `reference count for ${hassan} is 1`);
3258
- driver.id = jade;
3259
- await settleCardRender(assert, jade, `[data-test-rendered-card="${jade}"]`);
3260
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3261
- assert.strictEqual(storeService.getReferenceCount(hassan), 0, `reference count for ${hassan} is 0`);
3262
- driver.showComponent = false;
3263
- await waitFor(`[data-test-rendered-card]`, { count: 0 });
3264
- assert.strictEqual(storeService.getReferenceCount(jade), 0, `reference count for ${jade} is 0`);
3265
- assert.strictEqual(storeService.getReferenceCount(hassan), 0, `reference count for ${hassan} is 0`);
3266
- });
3267
- (0, import_qunit.test)("reference count is balanced when used with CardResource for file-meta that is destroyed", async function(assert) {
3268
- class Driver {
3269
- static {
3270
- decorateFieldV2(this.prototype, "showComponent", [tracked], function() {
3271
- return false;
3272
- });
3273
- }
3274
- #showComponent = (initializeDeferredDecorator(this, "showComponent"), void 0);
3275
- static {
3276
- decorateFieldV2(this.prototype, "id", [tracked]);
3277
- }
3278
- #id = (initializeDeferredDecorator(this, "id"), void 0);
3279
- }
3280
- let driver = new Driver();
3281
- let firstFile = `${testRealmURL}notes.txt`;
3282
- let secondFile = `${testRealmURL}README.txt`;
3283
- await testRealm.write("notes.txt", "notes");
3284
- await testRealm.write("README.txt", "readme");
3285
- class ResourceConsumer extends Component {
3286
- resource = getCard(this, () => driver.id, { type: "file-meta" });
3287
- static {
3288
- setComponentTemplate(templateFactory({
3289
- "id": "5jWS7tbo",
3290
- "block": "[[[41,[30,0,[\"resource\",\"card\"]],[[[1,\" \"],[10,0],[15,\"data-test-rendered-file\",[30,0,[\"resource\",\"id\"]]],[12],[13],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3291
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3292
- "isStrictMode": true
3293
- }), this);
3294
- }
3295
- }
3296
- await renderComponent(class TestDriver extends Component {
3297
- static {
3298
- setComponentTemplate(templateFactory({
3299
- "id": "hNRtWalG",
3300
- "block": "[[[41,[32,0,[\"showComponent\"]],[[[1,\" \"],[8,[32,1],null,null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3301
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3302
- "scope": () => [driver, ResourceConsumer],
3303
- "isStrictMode": true
3304
- }), this);
3305
- }
3306
- });
3307
- driver.showComponent = true;
3308
- driver.id = firstFile;
3309
- await settleCardRender(assert, firstFile, `[data-test-rendered-file="${firstFile}"]`, { type: "file-meta" });
3310
- assert.strictEqual(storeService.getReferenceCount(firstFile), 1, `reference count for ${firstFile} is 1`);
3311
- assert.strictEqual(storeService.getReferenceCount(secondFile), 0, `reference count for ${secondFile} is 0`);
3312
- driver.id = secondFile;
3313
- await settleCardRender(assert, secondFile, `[data-test-rendered-file="${secondFile}"]`, { type: "file-meta" });
3314
- assert.strictEqual(storeService.getReferenceCount(firstFile), 0, `reference count for ${firstFile} is 0`);
3315
- assert.strictEqual(storeService.getReferenceCount(secondFile), 1, `reference count for ${secondFile} is 1`);
3316
- driver.showComponent = false;
3317
- await waitFor(`[data-test-rendered-file]`, { count: 0 });
3318
- assert.strictEqual(storeService.getReferenceCount(firstFile), 0, `reference count for ${firstFile} is 0`);
3319
- assert.strictEqual(storeService.getReferenceCount(secondFile), 0, `reference count for ${secondFile} is 0`);
3320
- });
3321
- (0, import_qunit.test)("reference count is balanced during auto saving", async function(assert) {
3322
- let hassan = `${testRealmURL}Person/hassan`;
3323
- setCardInOperatorModeState(hassan, "edit");
3324
- await renderComponent(class TestDriver extends Component {
3325
- static {
3326
- setComponentTemplate(templateFactory({
3327
- "id": "ZD1xwmB+",
3328
- "block": "[[[8,[32,0],null,[[\"@onClose\"],[[32,1]]],null]],[],[]]",
3329
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3330
- "scope": () => [OperatorModeContainer, noop],
3331
- "isStrictMode": true
3332
- }), this);
3333
- }
3334
- });
3335
- assert.strictEqual(storeService.getReferenceCount(hassan), 1, `reference count for ${hassan} is 1`);
3336
- await withSlowSave(1e3, async () => {
3337
- await typeIn(`[data-test-stack-card="${testRealmURL}Person/hassan"] [data-test-field="name"] input`, " Paper");
3338
- assert.strictEqual(storeService.getReferenceCount(hassan), 1, `reference count for ${hassan} is 1`);
3339
- });
3340
- assert.strictEqual(storeService.getReferenceCount(hassan), 1, `reference count for ${hassan} is 1`);
3341
- });
3342
- (0, import_qunit.test)("reference count is balanced when used with CardCollectionResource that is destroyed", async function(assert) {
3343
- class Driver {
3344
- static {
3345
- decorateFieldV2(this.prototype, "showComponent", [tracked], function() {
3346
- return false;
3347
- });
3348
- }
3349
- #showComponent = (initializeDeferredDecorator(this, "showComponent"), void 0);
3350
- static {
3351
- decorateFieldV2(this.prototype, "id", [tracked]);
3352
- }
3353
- #id = (initializeDeferredDecorator(this, "id"), void 0);
3354
- }
3355
- let driver = new Driver();
3356
- class ResourceConsumer extends Component {
3357
- resource = getCardCollection(this, () => driver.id ? [driver.id] : []);
3358
- get card() {
3359
- return this.resource.cards[0];
3360
- }
3361
- get renderedCard() {
3362
- return this.card?.constructor.getComponent(this.card);
3363
- }
3364
- static {
3365
- setComponentTemplate(templateFactory({
3366
- "id": "99aOV2w7",
3367
- "block": "[[[41,[30,0,[\"card\"]],[[[1,\" \"],[8,[30,0,[\"renderedCard\"]],[[16,\"data-test-rendered-card\",[30,0,[\"card\",\"id\"]]]],null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3368
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3369
- "isStrictMode": true
3370
- }), this);
3371
- }
3372
- }
3373
- await renderComponent(class TestDriver extends Component {
3374
- static {
3375
- setComponentTemplate(templateFactory({
3376
- "id": "hNRtWalG",
3377
- "block": "[[[41,[32,0,[\"showComponent\"]],[[[1,\" \"],[8,[32,1],null,null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3378
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3379
- "scope": () => [driver, ResourceConsumer],
3380
- "isStrictMode": true
3381
- }), this);
3382
- }
3383
- });
3384
- driver.showComponent = true;
3385
- let jade = `${testRealmURL}Person/jade`;
3386
- let hassan = `${testRealmURL}Person/hassan`;
3387
- driver.id = hassan;
3388
- await settleCardRender(assert, hassan, `[data-test-rendered-card="${hassan}"]`);
3389
- assert.strictEqual(storeService.getReferenceCount(jade), 0, `reference count for ${jade} is 0`);
3390
- assert.strictEqual(storeService.getReferenceCount(hassan), 1, `reference count for ${hassan} is 1`);
3391
- driver.id = jade;
3392
- await settleCardRender(assert, jade, `[data-test-rendered-card="${jade}"]`);
3393
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3394
- assert.strictEqual(storeService.getReferenceCount(hassan), 0, `reference count for ${hassan} is 0`);
3395
- driver.showComponent = false;
3396
- await waitFor(`[data-test-rendered-card]`, { count: 0 });
3397
- assert.strictEqual(storeService.getReferenceCount(jade), 0, `reference count for ${jade} is 0`);
3398
- assert.strictEqual(storeService.getReferenceCount(hassan), 0, `reference count for ${hassan} is 0`);
3399
- });
3400
- (0, import_qunit.test)("reference count is balanced when used with SearchResource that is destroyed", async function(assert) {
3401
- class Driver {
3402
- static {
3403
- decorateFieldV2(this.prototype, "showComponent", [tracked], function() {
3404
- return false;
3405
- });
3406
- }
3407
- #showComponent = (initializeDeferredDecorator(this, "showComponent"), void 0);
3408
- static {
3409
- decorateFieldV2(this.prototype, "id", [tracked]);
3410
- }
3411
- #id = (initializeDeferredDecorator(this, "id"), void 0);
3412
- }
3413
- let driver = new Driver();
3414
- class ResourceConsumer extends Component {
3415
- static {
3416
- decorateFieldV2(this.prototype, "store", [service]);
3417
- }
3418
- #store = (initializeDeferredDecorator(this, "store"), void 0);
3419
- get resource() {
3420
- return this.store.getSearchResource(this, () => driver.id ? { filter: {
3421
- on: baseCardRef,
3422
- eq: { id: driver.id }
3423
- } } : void 0);
3424
- }
3425
- static {
3426
- decorateMethodV2(this.prototype, "resource", [cached]);
3427
- }
3428
- get card() {
3429
- return this.resource.instances[0];
3430
- }
3431
- static {
3432
- setComponentTemplate(templateFactory({
3433
- "id": "F3i58yQO",
3434
- "block": "[[[41,[30,0,[\"card\"]],[[[1,\" \"],[10,0],[15,\"data-test-rendered-card\",[30,0,[\"card\",\"id\"]]],[12],[1,\"\\n \"],[1,[30,0,[\"card\",\"id\"]]],[1,\"\\n \"],[13],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3435
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3436
- "isStrictMode": true
3437
- }), this);
3438
- }
3439
- }
3440
- await renderComponent(class TestDriver extends Component {
3441
- static {
3442
- setComponentTemplate(templateFactory({
3443
- "id": "hNRtWalG",
3444
- "block": "[[[41,[32,0,[\"showComponent\"]],[[[1,\" \"],[8,[32,1],null,null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3445
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3446
- "scope": () => [driver, ResourceConsumer],
3447
- "isStrictMode": true
3448
- }), this);
3449
- }
3450
- });
3451
- driver.showComponent = true;
3452
- let jade = `${testRealmURL}Person/jade`;
3453
- let hassan = `${testRealmURL}Person/hassan`;
3454
- driver.id = hassan;
3455
- await waitUntil(() => storeService.getReferenceCount(hassan) === 1 && storeService.getReferenceCount(jade) === 0, { timeout: 1e4 });
3456
- assert.strictEqual(storeService.getReferenceCount(jade), 0, `reference count for ${jade} is 0`);
3457
- assert.strictEqual(storeService.getReferenceCount(hassan), 1, `reference count for ${hassan} is 1`);
3458
- driver.id = jade;
3459
- await waitUntil(() => storeService.getReferenceCount(jade) === 1 && storeService.getReferenceCount(hassan) === 0, { timeout: 1e4 });
3460
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3461
- assert.strictEqual(storeService.getReferenceCount(hassan), 0, `reference count for ${hassan} is 0`);
3462
- driver.showComponent = false;
3463
- await waitUntil(() => storeService.getReferenceCount(jade) === 0 && storeService.getReferenceCount(hassan) === 0, { timeout: 1e4 });
3464
- assert.strictEqual(storeService.getReferenceCount(jade), 0, `reference count for ${jade} is 0`);
3465
- assert.strictEqual(storeService.getReferenceCount(hassan), 0, `reference count for ${hassan} is 0`);
3466
- });
3467
- (0, import_qunit.test)("reference count is balanced when used with SearchResource that live updates when there is a index event", async function(assert) {
3468
- class Driver {
3469
- static {
3470
- decorateFieldV2(this.prototype, "id", [tracked]);
3471
- }
3472
- #id = (initializeDeferredDecorator(this, "id"), void 0);
3473
- }
3474
- let driver = new Driver();
3475
- class ResourceConsumer extends Component {
3476
- static {
3477
- decorateFieldV2(this.prototype, "store", [service]);
3478
- }
3479
- #store = (initializeDeferredDecorator(this, "store"), void 0);
3480
- get resource() {
3481
- return this.store.getSearchResource(this, () => driver.id ? { filter: {
3482
- on: baseCardRef,
3483
- eq: { id: driver.id }
3484
- } } : void 0, void 0, { isLive: true });
3485
- }
3486
- static {
3487
- decorateMethodV2(this.prototype, "resource", [cached]);
3488
- }
3489
- get card() {
3490
- return this.resource.instances[0];
3491
- }
3492
- get renderedCard() {
3493
- return this.card?.constructor.getComponent(this.card);
3494
- }
3495
- static {
3496
- setComponentTemplate(templateFactory({
3497
- "id": "99aOV2w7",
3498
- "block": "[[[41,[30,0,[\"card\"]],[[[1,\" \"],[8,[30,0,[\"renderedCard\"]],[[16,\"data-test-rendered-card\",[30,0,[\"card\",\"id\"]]]],null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3499
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3500
- "isStrictMode": true
3501
- }), this);
3502
- }
3503
- }
3504
- await renderComponent(class TestDriver extends Component {
3505
- static {
3506
- setComponentTemplate(templateFactory({
3507
- "id": "HtmuKyv7",
3508
- "block": "[[[8,[32,0],null,null,null]],[],[]]",
3509
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3510
- "scope": () => [ResourceConsumer],
3511
- "isStrictMode": true
3512
- }), this);
3513
- }
3514
- });
3515
- let jade = `${testRealmURL}Person/jade`;
3516
- driver.id = jade;
3517
- await waitFor(`[data-test-rendered-card="${jade}"]`, { timeout: 5e3 });
3518
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3519
- let deferred = new Deferred();
3520
- let unsubscribe = getService("message-service").subscribe(testRealmURL, (ev) => {
3521
- if (ev.eventName === "index" && ev.indexType === "incremental") {
3522
- unsubscribe();
3523
- deferred.fulfill();
3524
- }
3525
- });
3526
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
3527
- attributes: { name: "Paper" },
3528
- meta: { adoptsFrom: {
3529
- module: testRRI("person"),
3530
- name: "Person"
3531
- } }
3532
- } }));
3533
- await deferred.promise;
3534
- deferred = new Deferred();
3535
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
3536
- attributes: { name: "Paper" },
3537
- meta: { adoptsFrom: {
3538
- module: testRRI("person"),
3539
- name: "Person"
3540
- } }
3541
- } }));
3542
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3543
- });
3544
- (0, import_qunit.test)("reference count is balanced when used with CardCollectionResource when there is a index event", async function(assert) {
3545
- class Driver {
3546
- static {
3547
- decorateFieldV2(this.prototype, "id", [tracked]);
3548
- }
3549
- #id = (initializeDeferredDecorator(this, "id"), void 0);
3550
- }
3551
- let driver = new Driver();
3552
- class ResourceConsumer extends Component {
3553
- resource = getCardCollection(this, () => driver.id ? [driver.id] : []);
3554
- get card() {
3555
- return this.resource.cards[0];
3556
- }
3557
- get renderedCard() {
3558
- return this.card?.constructor.getComponent(this.card);
3559
- }
3560
- static {
3561
- setComponentTemplate(templateFactory({
3562
- "id": "99aOV2w7",
3563
- "block": "[[[41,[30,0,[\"card\"]],[[[1,\" \"],[8,[30,0,[\"renderedCard\"]],[[16,\"data-test-rendered-card\",[30,0,[\"card\",\"id\"]]]],null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3564
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3565
- "isStrictMode": true
3566
- }), this);
3567
- }
3568
- }
3569
- await renderComponent(class TestDriver extends Component {
3570
- static {
3571
- setComponentTemplate(templateFactory({
3572
- "id": "HtmuKyv7",
3573
- "block": "[[[8,[32,0],null,null,null]],[],[]]",
3574
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3575
- "scope": () => [ResourceConsumer],
3576
- "isStrictMode": true
3577
- }), this);
3578
- }
3579
- });
3580
- let jade = `${testRealmURL}Person/jade`;
3581
- driver.id = jade;
3582
- await waitFor(`[data-test-rendered-card="${jade}"]`, { timeout: 5e3 });
3583
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3584
- let deferred = new Deferred();
3585
- let unsubscribe = getService("message-service").subscribe(testRealmURL, (ev) => {
3586
- if (ev.eventName === "index" && ev.indexType === "incremental") {
3587
- unsubscribe();
3588
- deferred.fulfill();
3589
- }
3590
- });
3591
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
3592
- attributes: { name: "Paper" },
3593
- meta: { adoptsFrom: {
3594
- module: testRRI("person"),
3595
- name: "Person"
3596
- } }
3597
- } }));
3598
- await deferred.promise;
3599
- deferred = new Deferred();
3600
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
3601
- attributes: { name: "Paper" },
3602
- meta: { adoptsFrom: {
3603
- module: testRRI("person"),
3604
- name: "Person"
3605
- } }
3606
- } }));
3607
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3608
- });
3609
- (0, import_qunit.test)("reference count is balanced when used with CardResource when there is a index event", async function(assert) {
3610
- class Driver {
3611
- static {
3612
- decorateFieldV2(this.prototype, "id", [tracked]);
3613
- }
3614
- #id = (initializeDeferredDecorator(this, "id"), void 0);
3615
- }
3616
- let driver = new Driver();
3617
- class ResourceConsumer extends Component {
3618
- resource = getCard(this, () => driver.id);
3619
- get renderedCard() {
3620
- return this.resource.card?.constructor.getComponent(this.resource.card);
3621
- }
3622
- static {
3623
- setComponentTemplate(templateFactory({
3624
- "id": "XWrL4bCI",
3625
- "block": "[[[41,[30,0,[\"resource\",\"card\"]],[[[1,\" \"],[8,[30,0,[\"renderedCard\"]],[[16,\"data-test-rendered-card\",[30,0,[\"resource\",\"id\"]]]],null,null],[1,\"\\n\"]],[]],null]],[],[\"if\"]]",
3626
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3627
- "isStrictMode": true
3628
- }), this);
3629
- }
3630
- }
3631
- await renderComponent(class TestDriver extends Component {
3632
- static {
3633
- setComponentTemplate(templateFactory({
3634
- "id": "HtmuKyv7",
3635
- "block": "[[[8,[32,0],null,null,null]],[],[]]",
3636
- "moduleName": "/home/runner/work/boxel/boxel/packages/host/tests/integration/store-test.gts",
3637
- "scope": () => [ResourceConsumer],
3638
- "isStrictMode": true
3639
- }), this);
3640
- }
3641
- });
3642
- let jade = `${testRealmURL}Person/jade`;
3643
- driver.id = jade;
3644
- await waitFor(`[data-test-rendered-card="${jade}"]`, { timeout: 5e3 });
3645
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3646
- let deferred = new Deferred();
3647
- let unsubscribe = getService("message-service").subscribe(testRealmURL, (ev) => {
3648
- if (ev.eventName === "index" && ev.indexType === "incremental") {
3649
- unsubscribe();
3650
- deferred.fulfill();
3651
- }
3652
- });
3653
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
3654
- attributes: { name: "Paper" },
3655
- meta: { adoptsFrom: {
3656
- module: testRRI("person"),
3657
- name: "Person"
3658
- } }
3659
- } }));
3660
- await deferred.promise;
3661
- deferred = new Deferred();
3662
- await testRealm.write("Person/hassan.json", JSON.stringify({ data: {
3663
- attributes: { name: "Paper" },
3664
- meta: { adoptsFrom: {
3665
- module: testRRI("person"),
3666
- name: "Person"
3667
- } }
3668
- } }));
3669
- assert.strictEqual(storeService.getReferenceCount(jade), 1, `reference count for ${jade} is 1`);
3670
- });
3671
- });
3672
- //#endregion