@buoy-gg/shared-ui 7.0.35 → 7.0.38

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 (332) hide show
  1. package/README.md +33 -26
  2. package/floating.d.ts +1 -0
  3. package/floating.js +2 -0
  4. package/lib/commonjs/JsModal.js +16 -1
  5. package/lib/commonjs/JsModal.web.js +16 -1
  6. package/lib/commonjs/dataViewer/CyberpunkInput.js +6 -1
  7. package/lib/commonjs/dataViewer/LiveExplorer.js +28 -16
  8. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  9. package/lib/commonjs/icons/ReactQueryIcon.js +9 -161
  10. package/lib/commonjs/icons/SentryBugIcon.js +9 -171
  11. package/lib/commonjs/icons/index.js +7 -0
  12. package/lib/commonjs/index.js +105 -6
  13. package/lib/commonjs/license/AccountSetup.js +56 -0
  14. package/lib/commonjs/license/AccountSetup.web.js +81 -0
  15. package/lib/commonjs/license/FeatureGate.js +10 -43
  16. package/lib/commonjs/license/FreeAccountPrompt.js +35 -12
  17. package/lib/commonjs/license/index.js +0 -6
  18. package/lib/commonjs/license/licenseModule.js +56 -36
  19. package/lib/commonjs/license/tierLimits.js +12 -63
  20. package/lib/commonjs/storage/devToolsStorageKeys.js +8 -1
  21. package/lib/commonjs/stores/BaseEventStore.js +21 -5
  22. package/lib/commonjs/stores/createToolStore.js +21 -3
  23. package/lib/commonjs/stores/floatingToolStore.js +71 -0
  24. package/lib/commonjs/stores/floatingToolStore.test.js +112 -0
  25. package/lib/commonjs/sync/keyedArrays.js +209 -0
  26. package/lib/commonjs/sync/toolActionRegistry.js +85 -2
  27. package/lib/commonjs/sync/toolAttention.test.js +51 -0
  28. package/lib/commonjs/sync/toolUiBridge.js +58 -0
  29. package/lib/commonjs/sync/typedEdit.js +228 -0
  30. package/lib/commonjs/sync/valuePath.js +337 -0
  31. package/lib/commonjs/sync/valueShape.js +161 -0
  32. package/lib/commonjs/ui/backgrounds/README.md +52 -0
  33. package/lib/commonjs/ui/backgrounds/ToolBackground.js +4 -2
  34. package/lib/commonjs/ui/backgrounds/index.js +8 -1
  35. package/lib/commonjs/ui/backgrounds/registry.js +8 -0
  36. package/lib/commonjs/ui/backgrounds/variants/wormhole/motion.js +48 -0
  37. package/lib/commonjs/ui/backgrounds/variants/wormhole/textures.js +3 -0
  38. package/lib/commonjs/ui/backgrounds/variants/wormhole.js +133 -0
  39. package/lib/commonjs/ui/components/ClipboardHintBanner.js +5 -6
  40. package/lib/commonjs/ui/components/CompactRow.js +94 -74
  41. package/lib/commonjs/ui/components/DraggableHeader.js +16 -1
  42. package/lib/commonjs/ui/components/ExpandablePopover.js +38 -6
  43. package/lib/commonjs/ui/components/HeaderSearchButton.js +17 -4
  44. package/lib/commonjs/ui/floating/FloatingTool.js +1010 -0
  45. package/lib/commonjs/ui/floating/FloatingTool.web.js +591 -0
  46. package/lib/commonjs/ui/floating/FloatingToolHost.js +32 -0
  47. package/lib/commonjs/ui/floating/FloatingToolHost.web.js +28 -0
  48. package/lib/commonjs/ui/floating/index.js +105 -0
  49. package/lib/commonjs/ui/floating/index.web.js +105 -0
  50. package/lib/commonjs/ui/floating/onboardingConstants.js +70 -0
  51. package/lib/commonjs/ui/floating/onboardingConstants.web.js +34 -0
  52. package/lib/commonjs/ui/gameUI/constants/gameUIColors.js +3 -1
  53. package/lib/commonjs/ui/index.js +118 -2
  54. package/lib/commonjs/ui/night/nightTheme.js +10 -0
  55. package/lib/commonjs/ui/night/primitives.js +22 -5
  56. package/lib/commonjs/ui/otto/OttoSceneView.js +69 -0
  57. package/lib/commonjs/ui/otto/index.js +22 -0
  58. package/lib/commonjs/ui/otto/ottoEngine.js +10 -7
  59. package/lib/commonjs/ui/otto/ottoScenes.js +949 -0
  60. package/lib/commonjs/utils/minimalSuperJSON.js +13 -3
  61. package/lib/module/JsModal.js +16 -1
  62. package/lib/module/JsModal.web.js +16 -1
  63. package/lib/module/dataViewer/CyberpunkInput.js +6 -1
  64. package/lib/module/dataViewer/LiveExplorer.js +28 -16
  65. package/lib/module/hooks/safe-area-impl.js +1 -1
  66. package/lib/module/icons/ReactQueryIcon.js +9 -161
  67. package/lib/module/icons/SentryBugIcon.js +9 -171
  68. package/lib/module/icons/index.js +3 -1
  69. package/lib/module/index.js +8 -1
  70. package/lib/module/license/AccountSetup.js +52 -0
  71. package/lib/module/license/AccountSetup.web.js +77 -0
  72. package/lib/module/license/FeatureGate.js +10 -43
  73. package/lib/module/license/FreeAccountPrompt.js +35 -12
  74. package/lib/module/license/index.js +1 -1
  75. package/lib/module/license/licenseModule.js +50 -35
  76. package/lib/module/license/tierLimits.js +13 -63
  77. package/lib/module/storage/devToolsStorageKeys.js +8 -1
  78. package/lib/module/stores/BaseEventStore.js +21 -5
  79. package/lib/module/stores/createToolStore.js +21 -3
  80. package/lib/module/stores/floatingToolStore.js +61 -0
  81. package/lib/module/stores/floatingToolStore.test.js +111 -0
  82. package/lib/module/sync/keyedArrays.js +204 -0
  83. package/lib/module/sync/toolActionRegistry.js +84 -2
  84. package/lib/module/sync/toolAttention.test.js +50 -0
  85. package/lib/module/sync/toolUiBridge.js +55 -0
  86. package/lib/module/sync/typedEdit.js +220 -0
  87. package/lib/module/sync/valuePath.js +330 -0
  88. package/lib/module/sync/valueShape.js +153 -0
  89. package/lib/module/ui/backgrounds/README.md +52 -0
  90. package/lib/module/ui/backgrounds/ToolBackground.js +4 -2
  91. package/lib/module/ui/backgrounds/index.js +2 -1
  92. package/lib/module/ui/backgrounds/registry.js +8 -0
  93. package/lib/module/ui/backgrounds/variants/wormhole/motion.js +44 -0
  94. package/lib/module/ui/backgrounds/variants/wormhole/textures.js +3 -0
  95. package/lib/module/ui/backgrounds/variants/wormhole.js +129 -0
  96. package/lib/module/ui/components/ClipboardHintBanner.js +5 -6
  97. package/lib/module/ui/components/CompactRow.js +94 -74
  98. package/lib/module/ui/components/DraggableHeader.js +16 -1
  99. package/lib/module/ui/components/ExpandablePopover.js +38 -6
  100. package/lib/module/ui/components/HeaderSearchButton.js +17 -4
  101. package/lib/module/ui/floating/FloatingTool.js +1003 -0
  102. package/lib/module/ui/floating/FloatingTool.web.js +590 -0
  103. package/lib/module/ui/floating/FloatingToolHost.js +29 -0
  104. package/lib/module/ui/floating/FloatingToolHost.web.js +25 -0
  105. package/lib/module/ui/floating/index.js +6 -0
  106. package/lib/module/ui/floating/index.web.js +6 -0
  107. package/lib/module/ui/floating/onboardingConstants.js +64 -0
  108. package/lib/module/ui/floating/onboardingConstants.web.js +27 -0
  109. package/lib/module/ui/gameUI/constants/gameUIColors.js +3 -1
  110. package/lib/module/ui/index.js +5 -1
  111. package/lib/module/ui/night/nightTheme.js +10 -0
  112. package/lib/module/ui/night/primitives.js +22 -5
  113. package/lib/module/ui/otto/OttoSceneView.js +64 -0
  114. package/lib/module/ui/otto/index.js +3 -1
  115. package/lib/module/ui/otto/ottoEngine.js +10 -7
  116. package/lib/module/ui/otto/ottoScenes.js +942 -0
  117. package/lib/module/utils/minimalSuperJSON.js +13 -3
  118. package/lib/typescript/commonjs/JsModal.d.ts +43 -2
  119. package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
  120. package/lib/typescript/commonjs/JsModal.web.d.ts +5 -2
  121. package/lib/typescript/commonjs/JsModal.web.d.ts.map +1 -1
  122. package/lib/typescript/commonjs/dataViewer/CyberpunkInput.d.ts.map +1 -1
  123. package/lib/typescript/commonjs/dataViewer/LiveExplorer.d.ts.map +1 -1
  124. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  125. package/lib/typescript/commonjs/icons/ReactQueryIcon.d.ts +1 -2
  126. package/lib/typescript/commonjs/icons/ReactQueryIcon.d.ts.map +1 -1
  127. package/lib/typescript/commonjs/icons/SentryBugIcon.d.ts +1 -2
  128. package/lib/typescript/commonjs/icons/SentryBugIcon.d.ts.map +1 -1
  129. package/lib/typescript/commonjs/icons/index.d.ts +1 -1
  130. package/lib/typescript/commonjs/icons/index.d.ts.map +1 -1
  131. package/lib/typescript/commonjs/index.d.ts +8 -1
  132. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  133. package/lib/typescript/commonjs/license/AccountSetup.d.ts +4 -0
  134. package/lib/typescript/commonjs/license/AccountSetup.d.ts.map +1 -0
  135. package/lib/typescript/commonjs/license/AccountSetup.web.d.ts +2 -0
  136. package/lib/typescript/commonjs/license/AccountSetup.web.d.ts.map +1 -0
  137. package/lib/typescript/commonjs/license/FeatureGate.d.ts +3 -19
  138. package/lib/typescript/commonjs/license/FeatureGate.d.ts.map +1 -1
  139. package/lib/typescript/commonjs/license/FreeAccountPrompt.d.ts +8 -11
  140. package/lib/typescript/commonjs/license/FreeAccountPrompt.d.ts.map +1 -1
  141. package/lib/typescript/commonjs/license/index.d.ts +1 -1
  142. package/lib/typescript/commonjs/license/index.d.ts.map +1 -1
  143. package/lib/typescript/commonjs/license/licenseModule.d.ts +18 -31
  144. package/lib/typescript/commonjs/license/licenseModule.d.ts.map +1 -1
  145. package/lib/typescript/commonjs/license/tierLimits.d.ts +9 -52
  146. package/lib/typescript/commonjs/license/tierLimits.d.ts.map +1 -1
  147. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +6 -0
  148. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
  149. package/lib/typescript/commonjs/stores/BaseEventStore.d.ts.map +1 -1
  150. package/lib/typescript/commonjs/stores/createToolStore.d.ts.map +1 -1
  151. package/lib/typescript/commonjs/stores/floatingToolStore.d.ts +27 -0
  152. package/lib/typescript/commonjs/stores/floatingToolStore.d.ts.map +1 -0
  153. package/lib/typescript/commonjs/stores/floatingToolStore.test.d.ts +2 -0
  154. package/lib/typescript/commonjs/stores/floatingToolStore.test.d.ts.map +1 -0
  155. package/lib/typescript/commonjs/sync/keyedArrays.d.ts +35 -0
  156. package/lib/typescript/commonjs/sync/keyedArrays.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/sync/toolActionRegistry.d.ts +4 -32
  158. package/lib/typescript/commonjs/sync/toolActionRegistry.d.ts.map +1 -1
  159. package/lib/typescript/commonjs/sync/toolAttention.test.d.ts +2 -0
  160. package/lib/typescript/commonjs/sync/toolAttention.test.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/sync/toolUiBridge.d.ts +25 -0
  162. package/lib/typescript/commonjs/sync/toolUiBridge.d.ts.map +1 -1
  163. package/lib/typescript/commonjs/sync/typedEdit.d.ts +70 -0
  164. package/lib/typescript/commonjs/sync/typedEdit.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/sync/valuePath.d.ts +52 -0
  166. package/lib/typescript/commonjs/sync/valuePath.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/sync/valueShape.d.ts +77 -0
  168. package/lib/typescript/commonjs/sync/valueShape.d.ts.map +1 -0
  169. package/lib/typescript/commonjs/ui/backgrounds/ToolBackground.d.ts +7 -1
  170. package/lib/typescript/commonjs/ui/backgrounds/ToolBackground.d.ts.map +1 -1
  171. package/lib/typescript/commonjs/ui/backgrounds/index.d.ts +2 -1
  172. package/lib/typescript/commonjs/ui/backgrounds/index.d.ts.map +1 -1
  173. package/lib/typescript/commonjs/ui/backgrounds/registry.d.ts.map +1 -1
  174. package/lib/typescript/commonjs/ui/backgrounds/types.d.ts +11 -1
  175. package/lib/typescript/commonjs/ui/backgrounds/types.d.ts.map +1 -1
  176. package/lib/typescript/commonjs/ui/backgrounds/variants/wormhole/motion.d.ts +24 -0
  177. package/lib/typescript/commonjs/ui/backgrounds/variants/wormhole/motion.d.ts.map +1 -0
  178. package/lib/typescript/commonjs/ui/backgrounds/variants/wormhole/textures.d.ts +13 -0
  179. package/lib/typescript/commonjs/ui/backgrounds/variants/wormhole/textures.d.ts.map +1 -0
  180. package/lib/typescript/commonjs/ui/backgrounds/variants/wormhole.d.ts +3 -0
  181. package/lib/typescript/commonjs/ui/backgrounds/variants/wormhole.d.ts.map +1 -0
  182. package/lib/typescript/commonjs/ui/components/ClipboardHintBanner.d.ts.map +1 -1
  183. package/lib/typescript/commonjs/ui/components/CompactRow.d.ts +8 -1
  184. package/lib/typescript/commonjs/ui/components/CompactRow.d.ts.map +1 -1
  185. package/lib/typescript/commonjs/ui/components/DraggableHeader.d.ts +4 -1
  186. package/lib/typescript/commonjs/ui/components/DraggableHeader.d.ts.map +1 -1
  187. package/lib/typescript/commonjs/ui/components/ExpandablePopover.d.ts +14 -1
  188. package/lib/typescript/commonjs/ui/components/ExpandablePopover.d.ts.map +1 -1
  189. package/lib/typescript/commonjs/ui/components/HeaderSearchButton.d.ts +7 -1
  190. package/lib/typescript/commonjs/ui/components/HeaderSearchButton.d.ts.map +1 -1
  191. package/lib/typescript/commonjs/ui/floating/FloatingTool.d.ts +79 -0
  192. package/lib/typescript/commonjs/ui/floating/FloatingTool.d.ts.map +1 -0
  193. package/lib/typescript/commonjs/ui/floating/FloatingTool.web.d.ts +64 -0
  194. package/lib/typescript/commonjs/ui/floating/FloatingTool.web.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/ui/floating/FloatingToolHost.d.ts +3 -0
  196. package/lib/typescript/commonjs/ui/floating/FloatingToolHost.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/ui/floating/FloatingToolHost.web.d.ts +3 -0
  198. package/lib/typescript/commonjs/ui/floating/FloatingToolHost.web.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/ui/floating/index.d.ts +7 -0
  200. package/lib/typescript/commonjs/ui/floating/index.d.ts.map +1 -0
  201. package/lib/typescript/commonjs/ui/floating/index.web.d.ts +7 -0
  202. package/lib/typescript/commonjs/ui/floating/index.web.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/ui/floating/onboardingConstants.d.ts +30 -0
  204. package/lib/typescript/commonjs/ui/floating/onboardingConstants.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/ui/floating/onboardingConstants.web.d.ts +13 -0
  206. package/lib/typescript/commonjs/ui/floating/onboardingConstants.web.d.ts.map +1 -0
  207. package/lib/typescript/commonjs/ui/gameUI/constants/gameUIColors.d.ts +2 -0
  208. package/lib/typescript/commonjs/ui/gameUI/constants/gameUIColors.d.ts.map +1 -1
  209. package/lib/typescript/commonjs/ui/index.d.ts +6 -0
  210. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  211. package/lib/typescript/commonjs/ui/night/nightTheme.d.ts +10 -0
  212. package/lib/typescript/commonjs/ui/night/nightTheme.d.ts.map +1 -1
  213. package/lib/typescript/commonjs/ui/night/primitives.d.ts +10 -3
  214. package/lib/typescript/commonjs/ui/night/primitives.d.ts.map +1 -1
  215. package/lib/typescript/commonjs/ui/otto/OttoSceneView.d.ts +30 -0
  216. package/lib/typescript/commonjs/ui/otto/OttoSceneView.d.ts.map +1 -0
  217. package/lib/typescript/commonjs/ui/otto/index.d.ts +2 -0
  218. package/lib/typescript/commonjs/ui/otto/index.d.ts.map +1 -1
  219. package/lib/typescript/commonjs/ui/otto/ottoEngine.d.ts +1 -1
  220. package/lib/typescript/commonjs/ui/otto/ottoEngine.d.ts.map +1 -1
  221. package/lib/typescript/commonjs/ui/otto/ottoScenes.d.ts +75 -0
  222. package/lib/typescript/commonjs/ui/otto/ottoScenes.d.ts.map +1 -0
  223. package/lib/typescript/commonjs/utils/minimalSuperJSON.d.ts.map +1 -1
  224. package/lib/typescript/module/JsModal.d.ts +43 -2
  225. package/lib/typescript/module/JsModal.d.ts.map +1 -1
  226. package/lib/typescript/module/JsModal.web.d.ts +5 -2
  227. package/lib/typescript/module/JsModal.web.d.ts.map +1 -1
  228. package/lib/typescript/module/dataViewer/CyberpunkInput.d.ts.map +1 -1
  229. package/lib/typescript/module/dataViewer/LiveExplorer.d.ts.map +1 -1
  230. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  231. package/lib/typescript/module/icons/ReactQueryIcon.d.ts +1 -2
  232. package/lib/typescript/module/icons/ReactQueryIcon.d.ts.map +1 -1
  233. package/lib/typescript/module/icons/SentryBugIcon.d.ts +1 -2
  234. package/lib/typescript/module/icons/SentryBugIcon.d.ts.map +1 -1
  235. package/lib/typescript/module/icons/index.d.ts +1 -1
  236. package/lib/typescript/module/icons/index.d.ts.map +1 -1
  237. package/lib/typescript/module/index.d.ts +8 -1
  238. package/lib/typescript/module/index.d.ts.map +1 -1
  239. package/lib/typescript/module/license/AccountSetup.d.ts +4 -0
  240. package/lib/typescript/module/license/AccountSetup.d.ts.map +1 -0
  241. package/lib/typescript/module/license/AccountSetup.web.d.ts +2 -0
  242. package/lib/typescript/module/license/AccountSetup.web.d.ts.map +1 -0
  243. package/lib/typescript/module/license/FeatureGate.d.ts +3 -19
  244. package/lib/typescript/module/license/FeatureGate.d.ts.map +1 -1
  245. package/lib/typescript/module/license/FreeAccountPrompt.d.ts +8 -11
  246. package/lib/typescript/module/license/FreeAccountPrompt.d.ts.map +1 -1
  247. package/lib/typescript/module/license/index.d.ts +1 -1
  248. package/lib/typescript/module/license/index.d.ts.map +1 -1
  249. package/lib/typescript/module/license/licenseModule.d.ts +18 -31
  250. package/lib/typescript/module/license/licenseModule.d.ts.map +1 -1
  251. package/lib/typescript/module/license/tierLimits.d.ts +9 -52
  252. package/lib/typescript/module/license/tierLimits.d.ts.map +1 -1
  253. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +6 -0
  254. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
  255. package/lib/typescript/module/stores/BaseEventStore.d.ts.map +1 -1
  256. package/lib/typescript/module/stores/createToolStore.d.ts.map +1 -1
  257. package/lib/typescript/module/stores/floatingToolStore.d.ts +27 -0
  258. package/lib/typescript/module/stores/floatingToolStore.d.ts.map +1 -0
  259. package/lib/typescript/module/stores/floatingToolStore.test.d.ts +2 -0
  260. package/lib/typescript/module/stores/floatingToolStore.test.d.ts.map +1 -0
  261. package/lib/typescript/module/sync/keyedArrays.d.ts +35 -0
  262. package/lib/typescript/module/sync/keyedArrays.d.ts.map +1 -0
  263. package/lib/typescript/module/sync/toolActionRegistry.d.ts +4 -32
  264. package/lib/typescript/module/sync/toolActionRegistry.d.ts.map +1 -1
  265. package/lib/typescript/module/sync/toolAttention.test.d.ts +2 -0
  266. package/lib/typescript/module/sync/toolAttention.test.d.ts.map +1 -0
  267. package/lib/typescript/module/sync/toolUiBridge.d.ts +25 -0
  268. package/lib/typescript/module/sync/toolUiBridge.d.ts.map +1 -1
  269. package/lib/typescript/module/sync/typedEdit.d.ts +70 -0
  270. package/lib/typescript/module/sync/typedEdit.d.ts.map +1 -0
  271. package/lib/typescript/module/sync/valuePath.d.ts +52 -0
  272. package/lib/typescript/module/sync/valuePath.d.ts.map +1 -0
  273. package/lib/typescript/module/sync/valueShape.d.ts +77 -0
  274. package/lib/typescript/module/sync/valueShape.d.ts.map +1 -0
  275. package/lib/typescript/module/ui/backgrounds/ToolBackground.d.ts +7 -1
  276. package/lib/typescript/module/ui/backgrounds/ToolBackground.d.ts.map +1 -1
  277. package/lib/typescript/module/ui/backgrounds/index.d.ts +2 -1
  278. package/lib/typescript/module/ui/backgrounds/index.d.ts.map +1 -1
  279. package/lib/typescript/module/ui/backgrounds/registry.d.ts.map +1 -1
  280. package/lib/typescript/module/ui/backgrounds/types.d.ts +11 -1
  281. package/lib/typescript/module/ui/backgrounds/types.d.ts.map +1 -1
  282. package/lib/typescript/module/ui/backgrounds/variants/wormhole/motion.d.ts +24 -0
  283. package/lib/typescript/module/ui/backgrounds/variants/wormhole/motion.d.ts.map +1 -0
  284. package/lib/typescript/module/ui/backgrounds/variants/wormhole/textures.d.ts +13 -0
  285. package/lib/typescript/module/ui/backgrounds/variants/wormhole/textures.d.ts.map +1 -0
  286. package/lib/typescript/module/ui/backgrounds/variants/wormhole.d.ts +3 -0
  287. package/lib/typescript/module/ui/backgrounds/variants/wormhole.d.ts.map +1 -0
  288. package/lib/typescript/module/ui/components/ClipboardHintBanner.d.ts.map +1 -1
  289. package/lib/typescript/module/ui/components/CompactRow.d.ts +8 -1
  290. package/lib/typescript/module/ui/components/CompactRow.d.ts.map +1 -1
  291. package/lib/typescript/module/ui/components/DraggableHeader.d.ts +4 -1
  292. package/lib/typescript/module/ui/components/DraggableHeader.d.ts.map +1 -1
  293. package/lib/typescript/module/ui/components/ExpandablePopover.d.ts +14 -1
  294. package/lib/typescript/module/ui/components/ExpandablePopover.d.ts.map +1 -1
  295. package/lib/typescript/module/ui/components/HeaderSearchButton.d.ts +7 -1
  296. package/lib/typescript/module/ui/components/HeaderSearchButton.d.ts.map +1 -1
  297. package/lib/typescript/module/ui/floating/FloatingTool.d.ts +79 -0
  298. package/lib/typescript/module/ui/floating/FloatingTool.d.ts.map +1 -0
  299. package/lib/typescript/module/ui/floating/FloatingTool.web.d.ts +64 -0
  300. package/lib/typescript/module/ui/floating/FloatingTool.web.d.ts.map +1 -0
  301. package/lib/typescript/module/ui/floating/FloatingToolHost.d.ts +3 -0
  302. package/lib/typescript/module/ui/floating/FloatingToolHost.d.ts.map +1 -0
  303. package/lib/typescript/module/ui/floating/FloatingToolHost.web.d.ts +3 -0
  304. package/lib/typescript/module/ui/floating/FloatingToolHost.web.d.ts.map +1 -0
  305. package/lib/typescript/module/ui/floating/index.d.ts +7 -0
  306. package/lib/typescript/module/ui/floating/index.d.ts.map +1 -0
  307. package/lib/typescript/module/ui/floating/index.web.d.ts +7 -0
  308. package/lib/typescript/module/ui/floating/index.web.d.ts.map +1 -0
  309. package/lib/typescript/module/ui/floating/onboardingConstants.d.ts +30 -0
  310. package/lib/typescript/module/ui/floating/onboardingConstants.d.ts.map +1 -0
  311. package/lib/typescript/module/ui/floating/onboardingConstants.web.d.ts +13 -0
  312. package/lib/typescript/module/ui/floating/onboardingConstants.web.d.ts.map +1 -0
  313. package/lib/typescript/module/ui/gameUI/constants/gameUIColors.d.ts +2 -0
  314. package/lib/typescript/module/ui/gameUI/constants/gameUIColors.d.ts.map +1 -1
  315. package/lib/typescript/module/ui/index.d.ts +6 -0
  316. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  317. package/lib/typescript/module/ui/night/nightTheme.d.ts +10 -0
  318. package/lib/typescript/module/ui/night/nightTheme.d.ts.map +1 -1
  319. package/lib/typescript/module/ui/night/primitives.d.ts +10 -3
  320. package/lib/typescript/module/ui/night/primitives.d.ts.map +1 -1
  321. package/lib/typescript/module/ui/otto/OttoSceneView.d.ts +30 -0
  322. package/lib/typescript/module/ui/otto/OttoSceneView.d.ts.map +1 -0
  323. package/lib/typescript/module/ui/otto/index.d.ts +2 -0
  324. package/lib/typescript/module/ui/otto/index.d.ts.map +1 -1
  325. package/lib/typescript/module/ui/otto/ottoEngine.d.ts +1 -1
  326. package/lib/typescript/module/ui/otto/ottoEngine.d.ts.map +1 -1
  327. package/lib/typescript/module/ui/otto/ottoScenes.d.ts +75 -0
  328. package/lib/typescript/module/ui/otto/ottoScenes.d.ts.map +1 -0
  329. package/lib/typescript/module/utils/minimalSuperJSON.d.ts.map +1 -1
  330. package/package.json +25 -5
  331. package/scripts/generate-wormhole-textures.cjs +261 -0
  332. package/scripts/test-wormhole-motion.cjs +59 -0
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.findKeyPath = findKeyPath;
7
+ exports.refusalText = refusalText;
8
+ exports.shapeKind = shapeKind;
9
+ exports.suggestedPatch = suggestedPatch;
10
+ exports.typedEditViolations = typedEditViolations;
11
+ /**
12
+ * The typed-edit guard — ONE implementation, for every surface that takes a
13
+ * merge patch from a remote caller.
14
+ *
15
+ * The rule, which is the React Query devtools value-editor rule: you may change
16
+ * the VALUE of a field that already exists, to the same kind of thing. You may
17
+ * not add a field, change a field's type, or null a list or object the screen
18
+ * renders. A list may grow or shrink — carts are lists you add to — but every
19
+ * item in it must have the same fields as the items already there, because an
20
+ * item missing a field the others have is what crashes the list on render.
21
+ *
22
+ * WHY IT LIVES HERE. This existed twice, once in the zustand adapter and once in
23
+ * react-query, drifting slightly (one said "the ones already in the list", the
24
+ * other "the items"; only one had the did-you-mean hint). Jotai had NO copy at
25
+ * all, so `setAtom` accepted a string over a number or a one-item array over a
26
+ * fifty-item one with nothing to stop it. Three copies of a data-destroying
27
+ * safety rule is two more than anyone can keep in step — the same argument
28
+ * `keyedArrays.ts` makes about the expansion it owns.
29
+ *
30
+ * The one behavioural knob is `noun`: what to call the thing being edited in a
31
+ * refusal ("this store", "this data", "this atom"). Everything else is shared,
32
+ * deliberately — a rule that differs per surface is a rule nobody can state.
33
+ */
34
+
35
+ const isPlainObject = v => !!v && typeof v === "object" && !Array.isArray(v);
36
+
37
+ /** The shape category the screen depends on: array vs object vs the rest. */
38
+ function shapeKind(v) {
39
+ if (Array.isArray(v)) return "array";
40
+ if (v === null) return "null";
41
+ if (typeof v === "object") return "object";
42
+ return typeof v;
43
+ }
44
+ const SCALARS = ["string", "number", "boolean"];
45
+
46
+ /**
47
+ * Where a key actually lives in a nested value, as a dotted path — first match,
48
+ * breadth-first, capped so a huge payload cannot stall the walk.
49
+ *
50
+ * This is what turns "you put `name` at the top" into "`name` lives at
51
+ * `item.name`", which is the difference between a caller that gives up and one
52
+ * that fixes it. Ten of eleven measured `query` write failures were this exact
53
+ * mistake.
54
+ */
55
+ function findKeyPath(obj, key, maxNodes = 2000) {
56
+ const queue = [{
57
+ node: obj,
58
+ path: ""
59
+ }];
60
+ let seen = 0;
61
+ while (queue.length && seen < maxNodes) {
62
+ const {
63
+ node,
64
+ path
65
+ } = queue.shift();
66
+ seen++;
67
+ if (Array.isArray(node)) {
68
+ node.slice(0, 20).forEach((v, i) => queue.push({
69
+ node: v,
70
+ path: `${path}[${i}]`
71
+ }));
72
+ } else if (isPlainObject(node)) {
73
+ for (const [k, v] of Object.entries(node)) {
74
+ const p = path ? `${path}.${k}` : k;
75
+ if (k === key && path) return p; // path set => nested, not the top level
76
+ if (isPlainObject(v) || Array.isArray(v)) queue.push({
77
+ node: v,
78
+ path: p
79
+ });
80
+ }
81
+ }
82
+ }
83
+ return undefined;
84
+ }
85
+ /**
86
+ * Every way this patch would break the value it is merged into. Empty means the
87
+ * edit is safe to apply.
88
+ */
89
+ function typedEditViolations(current, patch, opts = {}, root = current, path = "", out = []) {
90
+ const noun = opts.noun ?? "data";
91
+ const here = path || "(root)";
92
+ if (Array.isArray(patch)) {
93
+ if (!Array.isArray(current)) {
94
+ out.push({
95
+ path: here,
96
+ kind: "type-change",
97
+ detail: `${shapeKind(current)} → array`
98
+ });
99
+ return out;
100
+ }
101
+ // Length may change — a cart is a list you add to and remove from — but each
102
+ // item must match the shape of the ones already there. The first item is the
103
+ // template; an added item missing a field the others have is what makes the
104
+ // list throw when it renders that field.
105
+ const template = current.length ? current[0] : undefined;
106
+ if (template !== undefined && (isPlainObject(template) || Array.isArray(template))) {
107
+ patch.forEach((el, i) => {
108
+ const ep = `${path}[${i}]`;
109
+ if (isPlainObject(template) && isPlainObject(el)) {
110
+ for (const k of Object.keys(template)) {
111
+ if (!(k in el)) {
112
+ out.push({
113
+ path: `${ep}.${k}`,
114
+ kind: "missing-key",
115
+ detail: `list items need \`${k}\` — the items already in the list have it`
116
+ });
117
+ }
118
+ }
119
+ }
120
+ typedEditViolations(template, el, opts, root, ep, out);
121
+ });
122
+ }
123
+ return out;
124
+ }
125
+ if (isPlainObject(patch)) {
126
+ if (!isPlainObject(current)) {
127
+ out.push({
128
+ path: here,
129
+ kind: "type-change",
130
+ detail: `${shapeKind(current)} → object`
131
+ });
132
+ return out;
133
+ }
134
+ for (const [k, v] of Object.entries(patch)) {
135
+ const p = path ? `${path}.${k}` : k;
136
+ if (!(k in current)) {
137
+ const elsewhere = findKeyPath(root, k);
138
+ out.push({
139
+ path: p,
140
+ kind: "add-key",
141
+ detail: elsewhere ? `no such field here — did you mean \`${elsewhere}\`?` : `no field named \`${k}\` exists in this ${noun}`,
142
+ ...(elsewhere ? {
143
+ movedTo: elsewhere
144
+ } : {})
145
+ });
146
+ } else {
147
+ typedEditViolations(current[k], v, opts, root, p, out);
148
+ }
149
+ }
150
+ return out;
151
+ }
152
+
153
+ // A leaf: the edit itself.
154
+ const ck = shapeKind(current);
155
+ const pk = shapeKind(patch);
156
+ // Filling an empty field and CLEARING one are the same kind of edit, and this
157
+ // guard used to allow only the first. That asymmetry had a cost: "take the
158
+ // promo off my bag" is `string → null`, the refusal named `force: true` as the
159
+ // only way through, and a model that anticipated it wrote the forced call
160
+ // pre-emptively — reaching for the one parameter that bypasses EVERY
161
+ // protection in order to do something completely ordinary. Measured on
162
+ // `cart/take-promo-off`: an S1 on an otherwise correct flow.
163
+ //
164
+ // Nulling a LIST or OBJECT the screen renders stays refused. That is the crash
165
+ // this guard exists for (`sizes.map` on null); a null scalar renders as empty.
166
+ const fillingNull = ck === "null" && SCALARS.includes(pk);
167
+ const clearingScalar = pk === "null" && SCALARS.includes(ck);
168
+ if (ck !== pk && !fillingNull && !clearingScalar) {
169
+ out.push({
170
+ path: here,
171
+ kind: "type-change",
172
+ detail: `${ck} → ${pk}`
173
+ });
174
+ }
175
+ return out;
176
+ }
177
+
178
+ /**
179
+ * The patch the caller should have sent, when every problem was a field written
180
+ * at the wrong DEPTH.
181
+ *
182
+ * The guard already worked out where each field really lives in order to say
183
+ * "did you mean `item.name`?", so it can rebuild the patch instead of leaving
184
+ * the caller to re-derive it from prose. Returns undefined unless EVERY
185
+ * violation is a relocatable add-key: a partial suggestion that silently drops
186
+ * the parts we could not fix would be worse than none, because the caller would
187
+ * send it, be refused again, and learn nothing.
188
+ */
189
+ function suggestedPatch(patch, violations) {
190
+ if (!violations.length || !violations.every(v => v.kind === "add-key" && v.movedTo)) return undefined;
191
+ const out = {};
192
+ for (const v of violations) {
193
+ const value = getAtDotted(patch, v.path);
194
+ if (value === undefined) return undefined;
195
+ // `movedTo` can name a list element (`results[0].name`); a merge patch
196
+ // cannot address one by index, and rewriting it to the id-addressed form
197
+ // needs the list itself. Leave those to the prose rather than suggest
198
+ // something that will not apply.
199
+ if (v.movedTo.includes("[")) return undefined;
200
+ let node = out;
201
+ const segs = v.movedTo.split(".");
202
+ segs.slice(0, -1).forEach(seg => {
203
+ node[seg] ??= {};
204
+ node = node[seg];
205
+ });
206
+ node[segs[segs.length - 1]] = value;
207
+ }
208
+ return out;
209
+ }
210
+ function getAtDotted(obj, path) {
211
+ let cur = obj;
212
+ for (const seg of path.split(".")) {
213
+ if (!isPlainObject(cur)) return undefined;
214
+ cur = cur[seg];
215
+ }
216
+ return cur;
217
+ }
218
+
219
+ /**
220
+ * The sentence a refusal ends with. Shared so every surface refuses in the same
221
+ * words — a caller that learns the rule on one tool should recognise it on the
222
+ * next.
223
+ */
224
+ function refusalText(violations, noun, suggestion) {
225
+ const listed = violations.slice(0, 6).map(v => `\`${v.path}\`: ${v.detail}`).join("; ");
226
+ const more = violations.length > 6 ? `; +${violations.length - 6} more` : "";
227
+ return `Refused: this isn't a same-type edit of existing fields (the rule the React Query devtools enforces). ${listed}${more}. ` + `You can only change the VALUE of a field that already exists, to the same type — you can't add fields, change a field's type, ` + `or null a list/object the screen renders. Clearing a scalar to null is fine. Send just the field(s) you're changing, nested to ` + `match the current shape of this ${noun}. Use force:true only to deliberately break that.` + (suggestion ? ` This is the same edit at the right depth — send it as the patch: ${JSON.stringify(suggestion)}` : "");
228
+ }
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parsePath = parsePath;
7
+ exports.patchFromPath = patchFromPath;
8
+ exports.readPath = readPath;
9
+ var _keyedArrays = require("./keyedArrays.js");
10
+ /**
11
+ * Addressing a single value inside cached data or a store — one implementation,
12
+ * shared by every adapter that reads or merges.
13
+ *
14
+ * WHY. The most common measured write failure is not a wrong value, it is a
15
+ * wrong DEPTH: ten of eleven `query` failures on the bench sent `{name: "x"}`
16
+ * for a payload shaped `{item: {name}}`. That is not a missing instruction — the
17
+ * system prompt says, verbatim, "if the value is {item:{name}} send
18
+ * {"item":{"name":"test123"}}, never {name}" — and models that had just called
19
+ * `getQueryData` still flattened it. The rule is being read past, not missed.
20
+ *
21
+ * So stop asking. `path: "item.name", value: "x"` has no depth to get wrong:
22
+ * there is exactly one way to write it and the adapter builds the nested patch.
23
+ * The same syntax on the READ side returns one slice instead of a payload that
24
+ * gets cut off at the engine's 24,000-character cap, which is the other half of
25
+ * the same problem — a caller cannot write a shape it was never able to see.
26
+ *
27
+ * Lists are addressed by IDENTITY, never by position. `lines[0]` is resolved to
28
+ * the id of whatever is at index 0 right now and rewritten as an id-addressed
29
+ * edit, because between the read and the write an item may have been removed and
30
+ * index 0 is then a different row. A list whose items carry no stable id is
31
+ * refused rather than guessed at — see keyedArrays.ts for why silently picking a
32
+ * row is the failure mode that loses data.
33
+ */
34
+
35
+ const isPlainObject = v => typeof v === "object" && v !== null && !Array.isArray(v);
36
+ /**
37
+ * Where a field of this name actually lives, as a dotted path — breadth-first,
38
+ * capped so a big payload cannot stall the walk.
39
+ *
40
+ * A wrong `path` is not the same mistake as a wrong depth, and `path` does not
41
+ * prevent it. Measured on TWO cases in one run: grok wrote
42
+ * `path: "item.name"` against the flat PokéAPI payload `{name, id, stats, …}`,
43
+ * having generalised the shape from a different screen it had seen. The value it
44
+ * wanted was at `name`, one segment, right there. A refusal that says so is a
45
+ * one-turn recovery; a refusal that only lists the available fields makes the
46
+ * caller re-derive it.
47
+ */
48
+ function findFieldPath(obj, key, maxNodes = 2000) {
49
+ const queue = [{
50
+ node: obj,
51
+ path: ""
52
+ }];
53
+ let seen = 0;
54
+ while (queue.length && seen < maxNodes) {
55
+ const {
56
+ node,
57
+ path
58
+ } = queue.shift();
59
+ seen++;
60
+ if (Array.isArray(node)) {
61
+ node.slice(0, 20).forEach((v, i) => queue.push({
62
+ node: v,
63
+ path: `${path}[${i}]`
64
+ }));
65
+ } else if (isPlainObject(node)) {
66
+ for (const [k, v] of Object.entries(node)) {
67
+ const p = path ? `${path}.${k}` : k;
68
+ if (k === key) return p;
69
+ if (isPlainObject(v) || Array.isArray(v)) queue.push({
70
+ node: v,
71
+ path: p
72
+ });
73
+ }
74
+ }
75
+ }
76
+ return undefined;
77
+ }
78
+
79
+ /**
80
+ * "No field X here" plus, when the field exists somewhere else, the path that
81
+ * would have worked. `leaf` is the segment the caller was ultimately after.
82
+ */
83
+ function missingFieldError(root, at, key, available, leaf) {
84
+ const elsewhere = findFieldPath(root, leaf ?? key);
85
+ const has = available.slice(0, 12).join(", ") || "(no fields)";
86
+ return elsewhere ? `No field "${key}" at "${at}" — did you mean path "${elsewhere}"? "${at}" has: ${has}.` : `No field "${key}" at "${at}". It has: ${has}.`;
87
+ }
88
+
89
+ /** Read a dotted field path inside one list item. */
90
+ function fieldOf(item, field) {
91
+ let cur = item;
92
+ for (const seg of field.split(".")) {
93
+ if (!isPlainObject(cur)) return undefined;
94
+ cur = cur[seg];
95
+ }
96
+ return cur;
97
+ }
98
+
99
+ /**
100
+ * `lines[0].addonIds`, `item.name`, `results[name=pikachu].url` → segments.
101
+ *
102
+ * Returns undefined for syntax it does not understand rather than doing
103
+ * something approximate with it.
104
+ */
105
+ function parsePath(path) {
106
+ if (!path.trim()) return undefined;
107
+ const out = [];
108
+ // Walk the string rather than splitting on ".", because a [field=value]
109
+ // selector may legitimately contain a dot ("results[url=a.b/c]").
110
+ let i = 0;
111
+ while (i < path.length) {
112
+ if (path[i] === ".") {
113
+ i++;
114
+ continue;
115
+ }
116
+ if (path[i] === "[") {
117
+ const end = path.indexOf("]", i);
118
+ if (end === -1) return undefined;
119
+ const inner = path.slice(i + 1, end);
120
+ if (/^\d+$/.test(inner)) out.push({
121
+ kind: "index",
122
+ index: Number(inner)
123
+ });else {
124
+ const eq = inner.indexOf("=");
125
+ if (eq <= 0) return undefined;
126
+ out.push({
127
+ kind: "match",
128
+ field: inner.slice(0, eq).trim(),
129
+ value: inner.slice(eq + 1).trim()
130
+ });
131
+ }
132
+ i = end + 1;
133
+ continue;
134
+ }
135
+ let j = i;
136
+ while (j < path.length && path[j] !== "." && path[j] !== "[") j++;
137
+ const key = path.slice(i, j);
138
+ if (!key) return undefined;
139
+ out.push({
140
+ kind: "key",
141
+ key
142
+ });
143
+ i = j;
144
+ }
145
+ return out.length ? out : undefined;
146
+ }
147
+
148
+ /** Read the value at `path`, or undefined if any step of it does not exist. */
149
+ function readPath(value, path) {
150
+ const segs = parsePath(path);
151
+ if (!segs) return {
152
+ ok: false,
153
+ error: `Could not read the path "${path}". Use dotted keys with optional [0] or [field=value], like "item.name" or "lines[lineId=seed-1].qty".`
154
+ };
155
+ let cur = value;
156
+ const walked = [];
157
+ for (const seg of segs) {
158
+ if (cur === null || cur === undefined) {
159
+ return {
160
+ ok: false,
161
+ error: `"${walked.join(".") || "(root)"}" is ${cur === null ? "null" : "not set"}, so there is nothing at "${path}".`
162
+ };
163
+ }
164
+ if (seg.kind === "key") {
165
+ if (!isPlainObject(cur)) return {
166
+ ok: false,
167
+ error: `"${walked.join(".") || "(root)"}" is not an object, so it has no field "${seg.key}".`
168
+ };
169
+ if (!(seg.key in cur)) {
170
+ const leafSeg = segs[segs.length - 1];
171
+ return {
172
+ ok: false,
173
+ error: missingFieldError(value, walked.join(".") || "(root)", seg.key, Object.keys(cur), leafSeg?.kind === "key" ? leafSeg.key : undefined)
174
+ };
175
+ }
176
+ cur = cur[seg.key];
177
+ walked.push(seg.key);
178
+ } else if (seg.kind === "index") {
179
+ if (!Array.isArray(cur)) return {
180
+ ok: false,
181
+ error: `"${walked.join(".") || "(root)"}" is not a list, so [${seg.index}] means nothing.`
182
+ };
183
+ cur = cur[seg.index];
184
+ walked.push(`[${seg.index}]`);
185
+ } else {
186
+ if (!Array.isArray(cur)) return {
187
+ ok: false,
188
+ error: `"${walked.join(".") || "(root)"}" is not a list, so [${seg.field}=${seg.value}] means nothing.`
189
+ };
190
+ const hit = cur.find(el => isPlainObject(el) && String(fieldOf(el, seg.field)) === seg.value);
191
+ if (hit === undefined) return {
192
+ ok: false,
193
+ error: `No item with ${seg.field}="${seg.value}" in "${walked.join(".") || "(root)"}".`
194
+ };
195
+ cur = hit;
196
+ walked.push(`[${seg.field}=${seg.value}]`);
197
+ }
198
+ }
199
+ return {
200
+ ok: true,
201
+ value: cur
202
+ };
203
+ }
204
+
205
+ /**
206
+ * Build the merge patch that sets `path` to `value`, against the data as it is
207
+ * now.
208
+ *
209
+ * The result is an ordinary merge patch, so it goes through the SAME typed-edit
210
+ * guard as a hand-written one and gains no new powers — `path` is a way to say
211
+ * the same thing without being able to get the depth wrong, not a way around
212
+ * the rules. A list step becomes the id-addressed form, so the write stays
213
+ * proof against a truncated read.
214
+ */
215
+ function patchFromPath(current, path, value) {
216
+ const segs = parsePath(path);
217
+ if (!segs) return {
218
+ ok: false,
219
+ error: `Could not read the path "${path}". Use dotted keys with optional [0] or [field=value], like "item.name" or "lines[lineId=seed-1].qty".`
220
+ };
221
+ if (segs[0]?.kind !== "key") return {
222
+ ok: false,
223
+ error: `A path must start with a field name, not a list index — "${path}" does not say which list.`
224
+ };
225
+ const build = (node, at) => {
226
+ if (at >= segs.length) return {
227
+ ok: true,
228
+ patch: value
229
+ };
230
+ const seg = segs[at];
231
+ if (seg.kind === "key") {
232
+ // A field that does not exist is left for the typed-edit guard, which owns
233
+ // that decision — EXCEPT when there are more segments to walk, because
234
+ // then the caller is describing a shape that is not there at all and the
235
+ // guard's message ("no field named `item`") would not say where the value
236
+ // it wanted actually lives.
237
+ if (isPlainObject(node) && !(seg.key in node) && at + 1 < segs.length) {
238
+ const leafSeg = segs[segs.length - 1];
239
+ return {
240
+ ok: false,
241
+ error: missingFieldError(current, pathUpTo(segs, at), seg.key, Object.keys(node), leafSeg?.kind === "key" ? leafSeg.key : undefined)
242
+ };
243
+ }
244
+ const child = isPlainObject(node) ? node[seg.key] : undefined;
245
+ const inner = build(child, at + 1);
246
+ return inner.ok ? {
247
+ ok: true,
248
+ patch: {
249
+ [seg.key]: inner.patch
250
+ }
251
+ } : inner;
252
+ }
253
+ if (!Array.isArray(node)) {
254
+ return {
255
+ ok: false,
256
+ error: `"${pathUpTo(segs, at)}" is not a list, so "${path}" cannot be resolved. Read it first — \`shape\` on the read says what each field holds.`
257
+ };
258
+ }
259
+ const index = seg.kind === "index" ? seg.index : node.findIndex(el => isPlainObject(el) && String(fieldOf(el, seg.field)) === seg.value);
260
+ const item = index >= 0 ? node[index] : undefined;
261
+ const missing = seg.kind === "index" ? index < 0 || index >= node.length : index < 0;
262
+ if (missing) {
263
+ return {
264
+ ok: false,
265
+ error: seg.kind === "index" ? `"${pathUpTo(segs, at)}" has ${node.length} item(s), so there is nothing at [${seg.index}].` : `No item with ${seg.field}="${seg.value}" in "${pathUpTo(segs, at)}".`
266
+ };
267
+ }
268
+ /**
269
+ * A list of PRIMITIVES, addressed by index — `tags[0]` on
270
+ * `["alpha","beta"]`.
271
+ *
272
+ * The guard below used to be `!isPlainObject(item)`, which folded this in
273
+ * with a genuinely out-of-range index and answered `"tags" has 2 item(s),
274
+ * so there is nothing at [0]` — a sentence that contradicts itself, for the
275
+ * commonest index there is. A model reading the data, seeing two items and
276
+ * being told [0] and [1] are both empty has nowhere left to go.
277
+ *
278
+ * There is nothing to descend into on a string, so the index IS the leaf:
279
+ * rebuild the list with that one element replaced, exactly as the no-stable-id
280
+ * branch below does. Anything deeper genuinely cannot be resolved, and says so.
281
+ */
282
+ if (!isPlainObject(item)) {
283
+ if (at < segs.length - 1) {
284
+ return {
285
+ ok: false,
286
+ error: `"${pathUpTo(segs, at)}[${seg.kind === "index" ? seg.index : `${seg.field}=${seg.value}`}]" holds ${item === null ? "null" : typeof item}, not an object, so "${path}" cannot go any deeper. Set the item itself.`
287
+ };
288
+ }
289
+ const replaced = node.slice();
290
+ replaced[index] = value;
291
+ return {
292
+ ok: true,
293
+ patch: replaced
294
+ };
295
+ }
296
+ const inner = build(item, at + 1);
297
+ if (!inner.ok) return inner;
298
+ const idField = (0, _keyedArrays.identityField)(node);
299
+ // Positions move; ids do not. Prefer the addressed form whichever way the
300
+ // caller named the row.
301
+ if (idField) return {
302
+ ok: true,
303
+ patch: {
304
+ [String(item[idField])]: inner.patch
305
+ }
306
+ };
307
+
308
+ // No stable id — a Pokémon's `stats` are `{stat: {name}, base_stat}`, with
309
+ // nothing flat and unique on the item itself, and that is an ordinary shape
310
+ // rather than a broken one. Rebuild the whole list here instead of refusing.
311
+ //
312
+ // This is safe in a way the SAME array coming from a model is not: we are
313
+ // holding the current list in memory, so nothing is being reconstructed from
314
+ // a truncated read and no row can be dropped by omission. The caller still
315
+ // only named one value. What it cannot be is proof against the list changing
316
+ // between this call and the write, which addressing by id would be — so the
317
+ // id form stays preferred wherever one exists.
318
+ const next = node.slice();
319
+ next[index] = isPlainObject(inner.patch) ? {
320
+ ...item,
321
+ ...inner.patch
322
+ } : inner.patch;
323
+ return {
324
+ ok: true,
325
+ patch: next
326
+ };
327
+ };
328
+ const built = build(current, 0);
329
+ if (!built.ok) return built;
330
+ return {
331
+ ok: true,
332
+ patch: built.patch
333
+ };
334
+ }
335
+ function pathUpTo(segs, at) {
336
+ return segs.slice(0, at).map(s => s.kind === "key" ? s.key : s.kind === "index" ? `[${s.index}]` : `[${s.field}=${s.value}]`).join(".").replace(/\.\[/g, "[") || "(root)";
337
+ }