cursedbelt 1.0.0 → 2.5.0

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 (537) hide show
  1. package/dist/client/index.js +1 -1
  2. package/dist/core/category/index.d.ts.map +1 -1
  3. package/dist/core/category/index.js +2 -1
  4. package/dist/core/category/index.js.map +1 -1
  5. package/dist/core/category/types.js +1 -1
  6. package/dist/core/category/types.js.map +1 -1
  7. package/dist/core/file-tree/fileTreeModel.d.ts +49 -0
  8. package/dist/core/file-tree/fileTreeModel.d.ts.map +1 -1
  9. package/dist/core/file-tree/fileTreeModel.js +84 -0
  10. package/dist/core/file-tree/fileTreeModel.js.map +1 -1
  11. package/dist/core/layout/index.js +1 -1
  12. package/dist/core/layout/index.js.map +1 -1
  13. package/dist/core/media/index.js +1 -1
  14. package/dist/core/media/index.js.map +1 -1
  15. package/dist/core/media/types.js +1 -1
  16. package/dist/core/media/types.js.map +1 -1
  17. package/dist/core/media/uploadLimits.js +1 -1
  18. package/dist/core/media/uploadLimits.js.map +1 -1
  19. package/dist/core/sharing/model.d.ts +1 -1
  20. package/dist/ctgr/index.js +1 -1
  21. package/dist/index.js +1 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/react/activity-bar/ActivityBar.d.ts +17 -0
  24. package/dist/react/activity-bar/ActivityBar.d.ts.map +1 -1
  25. package/dist/react/activity-bar/ActivityBar.js.map +1 -1
  26. package/dist/react/analytics/index.d.ts +1 -1
  27. package/dist/react/analytics/index.js +1 -1
  28. package/dist/react/chat/MessageComposer.d.ts.map +1 -1
  29. package/dist/react/chat/MessageComposer.js +5 -4
  30. package/dist/react/chat/MessageComposer.js.map +1 -1
  31. package/dist/react/components/Button.d.ts.map +1 -1
  32. package/dist/react/components/Button.js +3 -2
  33. package/dist/react/components/Button.js.map +1 -1
  34. package/dist/react/components/Checkbox.d.ts +19 -3
  35. package/dist/react/components/Checkbox.d.ts.map +1 -1
  36. package/dist/react/components/Checkbox.js +29 -12
  37. package/dist/react/components/Checkbox.js.map +1 -1
  38. package/dist/react/components/CodeArea.d.ts.map +1 -1
  39. package/dist/react/components/CodeArea.js +2 -1
  40. package/dist/react/components/CodeArea.js.map +1 -1
  41. package/dist/react/components/Collapsible.d.ts.map +1 -1
  42. package/dist/react/components/Collapsible.js +2 -1
  43. package/dist/react/components/Collapsible.js.map +1 -1
  44. package/dist/react/components/ComboboxField.d.ts.map +1 -1
  45. package/dist/react/components/ComboboxField.js +3 -2
  46. package/dist/react/components/ComboboxField.js.map +1 -1
  47. package/dist/react/components/CopyButton.d.ts.map +1 -1
  48. package/dist/react/components/CopyButton.js +2 -1
  49. package/dist/react/components/CopyButton.js.map +1 -1
  50. package/dist/react/components/DataTable/ColumnChecklist.d.ts.map +1 -1
  51. package/dist/react/components/DataTable/ColumnChecklist.js +2 -1
  52. package/dist/react/components/DataTable/ColumnChecklist.js.map +1 -1
  53. package/dist/react/components/DataTable/Pagination.d.ts.map +1 -1
  54. package/dist/react/components/DataTable/Pagination.js +2 -1
  55. package/dist/react/components/DataTable/Pagination.js.map +1 -1
  56. package/dist/react/components/DataTable/SortHeader.d.ts.map +1 -1
  57. package/dist/react/components/DataTable/SortHeader.js +2 -1
  58. package/dist/react/components/DataTable/SortHeader.js.map +1 -1
  59. package/dist/react/components/DataTable/TableFilterBuilder.d.ts +61 -0
  60. package/dist/react/components/DataTable/TableFilterBuilder.d.ts.map +1 -0
  61. package/dist/react/components/DataTable/{FilterBuilder.js → TableFilterBuilder.js} +26 -3
  62. package/dist/react/components/DataTable/TableFilterBuilder.js.map +1 -0
  63. package/dist/react/components/DataTable/Toolbar.d.ts +1 -1
  64. package/dist/react/components/DataTable/Toolbar.js +3 -3
  65. package/dist/react/components/DataTable/Toolbar.js.map +1 -1
  66. package/dist/react/components/DataTable/cells/LinkCell.d.ts.map +1 -1
  67. package/dist/react/components/DataTable/cells/LinkCell.js +2 -1
  68. package/dist/react/components/DataTable/cells/LinkCell.js.map +1 -1
  69. package/dist/react/components/DataTable/index.d.ts +1 -1
  70. package/dist/react/components/DataTable/index.d.ts.map +1 -1
  71. package/dist/react/components/DataTable/index.js +4 -1
  72. package/dist/react/components/DataTable/index.js.map +1 -1
  73. package/dist/react/components/DragHandle.d.ts.map +1 -1
  74. package/dist/react/components/DragHandle.js +2 -1
  75. package/dist/react/components/DragHandle.js.map +1 -1
  76. package/dist/react/components/EmojiField.d.ts.map +1 -1
  77. package/dist/react/components/EmojiField.js +2 -1
  78. package/dist/react/components/EmojiField.js.map +1 -1
  79. package/dist/react/components/EventTimeline.d.ts +3 -2
  80. package/dist/react/components/EventTimeline.d.ts.map +1 -1
  81. package/dist/react/components/EventTimeline.js +3 -2
  82. package/dist/react/components/EventTimeline.js.map +1 -1
  83. package/dist/react/components/IconButton.d.ts +1 -1
  84. package/dist/react/components/IconButton.js +1 -1
  85. package/dist/react/components/InfoHint.d.ts.map +1 -1
  86. package/dist/react/components/InfoHint.js +5 -4
  87. package/dist/react/components/InfoHint.js.map +1 -1
  88. package/dist/react/components/InheritBadge.js +1 -1
  89. package/dist/react/components/InheritBadge.js.map +1 -1
  90. package/dist/react/components/InlineEditableText.d.ts.map +1 -1
  91. package/dist/react/components/InlineEditableText.js +2 -1
  92. package/dist/react/components/InlineEditableText.js.map +1 -1
  93. package/dist/react/components/MeterList.d.ts.map +1 -1
  94. package/dist/react/components/MeterList.js +2 -1
  95. package/dist/react/components/MeterList.js.map +1 -1
  96. package/dist/react/components/PathText.d.ts +2 -2
  97. package/dist/react/components/PathText.d.ts.map +1 -1
  98. package/dist/react/components/PathText.js +2 -1
  99. package/dist/react/components/PathText.js.map +1 -1
  100. package/dist/react/components/RatingField.d.ts.map +1 -1
  101. package/dist/react/components/RatingField.js +2 -1
  102. package/dist/react/components/RatingField.js.map +1 -1
  103. package/dist/react/components/SecretInput.js +3 -2
  104. package/dist/react/components/SecretInput.js.map +1 -1
  105. package/dist/react/components/SegmentedControl.d.ts.map +1 -1
  106. package/dist/react/components/SegmentedControl.js +2 -1
  107. package/dist/react/components/SegmentedControl.js.map +1 -1
  108. package/dist/react/components/StarRating.d.ts.map +1 -1
  109. package/dist/react/components/StarRating.js +9 -5
  110. package/dist/react/components/StarRating.js.map +1 -1
  111. package/dist/react/components/StatStrip.d.ts.map +1 -1
  112. package/dist/react/components/StatStrip.js +2 -1
  113. package/dist/react/components/StatStrip.js.map +1 -1
  114. package/dist/react/components/StatTile.d.ts.map +1 -1
  115. package/dist/react/components/StatTile.js +3 -2
  116. package/dist/react/components/StatTile.js.map +1 -1
  117. package/dist/react/components/Tabs.d.ts.map +1 -1
  118. package/dist/react/components/Tabs.js +2 -1
  119. package/dist/react/components/Tabs.js.map +1 -1
  120. package/dist/react/components/TruncatedText.d.ts +2 -1
  121. package/dist/react/components/TruncatedText.d.ts.map +1 -1
  122. package/dist/react/components/TruncatedText.js +2 -1
  123. package/dist/react/components/TruncatedText.js.map +1 -1
  124. package/dist/react/components/calendar/MonthGrid.d.ts.map +1 -1
  125. package/dist/react/components/calendar/MonthGrid.js +2 -1
  126. package/dist/react/components/calendar/MonthGrid.js.map +1 -1
  127. package/dist/react/components/calendar/WeekView.d.ts.map +1 -1
  128. package/dist/react/components/calendar/WeekView.js +2 -1
  129. package/dist/react/components/calendar/WeekView.js.map +1 -1
  130. package/dist/react/components/revealOnHover.d.ts.map +1 -1
  131. package/dist/react/components/revealOnHover.js +2 -1
  132. package/dist/react/components/revealOnHover.js.map +1 -1
  133. package/dist/react/file-tree/FileTree.d.ts +50 -1
  134. package/dist/react/file-tree/FileTree.d.ts.map +1 -1
  135. package/dist/react/file-tree/FileTree.js +234 -6
  136. package/dist/react/file-tree/FileTree.js.map +1 -1
  137. package/dist/react/file-tree/fileTree.css +52 -0
  138. package/dist/react/filter-rail/FilterRail.d.ts.map +1 -1
  139. package/dist/react/filter-rail/FilterRail.js +5 -4
  140. package/dist/react/filter-rail/FilterRail.js.map +1 -1
  141. package/dist/react/folder-tree/FolderTreeRail.d.ts.map +1 -1
  142. package/dist/react/folder-tree/FolderTreeRail.js +2 -1
  143. package/dist/react/folder-tree/FolderTreeRail.js.map +1 -1
  144. package/dist/react/index.d.ts +5 -1
  145. package/dist/react/index.d.ts.map +1 -1
  146. package/dist/react/index.js +5 -1
  147. package/dist/react/index.js.map +1 -1
  148. package/dist/react/layoutEngine/index.js +1 -1
  149. package/dist/react/layoutEngine/index.js.map +1 -1
  150. package/dist/react/lib/field.d.ts.map +1 -1
  151. package/dist/react/lib/field.js +3 -2
  152. package/dist/react/lib/field.js.map +1 -1
  153. package/dist/react/lib/floatingStyles.d.ts.map +1 -1
  154. package/dist/react/lib/floatingStyles.js +2 -1
  155. package/dist/react/lib/floatingStyles.js.map +1 -1
  156. package/dist/react/lib/tapTarget.d.ts +96 -0
  157. package/dist/react/lib/tapTarget.d.ts.map +1 -0
  158. package/dist/react/lib/tapTarget.js +96 -0
  159. package/dist/react/lib/tapTarget.js.map +1 -0
  160. package/dist/react/media/VideoTrimmer.d.ts +1 -1
  161. package/dist/react/media/VideoTrimmer.js +1 -1
  162. package/dist/react/media/denseGallery.css +3 -3
  163. package/dist/react/media/ffmpegWasm.js +2 -2
  164. package/dist/react/media/ffmpegWasm.js.map +1 -1
  165. package/dist/react/media/videoPlayer.css +42 -0
  166. package/dist/react/namespace/NamespaceTargetCapsule.d.ts +2 -2
  167. package/dist/react/namespace/NamespaceTargetCapsule.d.ts.map +1 -1
  168. package/dist/react/nav/BreadcrumbTrail.d.ts.map +1 -1
  169. package/dist/react/nav/BreadcrumbTrail.js +4 -3
  170. package/dist/react/nav/BreadcrumbTrail.js.map +1 -1
  171. package/dist/react/nav/HubTileGrid.d.ts.map +1 -1
  172. package/dist/react/nav/HubTileGrid.js +2 -1
  173. package/dist/react/nav/HubTileGrid.js.map +1 -1
  174. package/dist/react/nav/SideNav.d.ts.map +1 -1
  175. package/dist/react/nav/SideNav.js +4 -3
  176. package/dist/react/nav/SideNav.js.map +1 -1
  177. package/dist/react/nav/SideNavCustomize.d.ts.map +1 -1
  178. package/dist/react/nav/SideNavCustomize.js +2 -1
  179. package/dist/react/nav/SideNavCustomize.js.map +1 -1
  180. package/dist/react/palette/CommandPalette.d.ts.map +1 -1
  181. package/dist/react/palette/CommandPalette.js +3 -2
  182. package/dist/react/palette/CommandPalette.js.map +1 -1
  183. package/dist/server/drivers/pooledControlStores.pg.test.js +1 -0
  184. package/dist/server/drivers/pooledControlStores.pg.test.js.map +1 -1
  185. package/dist/server/drivers/pooledIdentityStore.pg.test.js +1 -0
  186. package/dist/server/drivers/pooledIdentityStore.pg.test.js.map +1 -1
  187. package/dist/server/drivers/retentionPolicy.pg.test.js +1 -0
  188. package/dist/server/drivers/retentionPolicy.pg.test.js.map +1 -1
  189. package/dist/server/guard/argon2Binding.d.ts +1 -1
  190. package/dist/server/guard/argon2Binding.js +1 -1
  191. package/dist/server/incidents/store.d.ts +3 -3
  192. package/dist/server/index.js +1 -1
  193. package/dist/server/index.js.map +1 -1
  194. package/dist/server/master-lock/masterLock.d.ts +1 -1
  195. package/dist/server/media-bun/index.js +1 -1
  196. package/dist/server/media-bun/index.js.map +1 -1
  197. package/dist/server/paths/appDataHome.d.ts +20 -0
  198. package/dist/server/paths/appDataHome.d.ts.map +1 -0
  199. package/dist/server/paths/appDataHome.js +69 -0
  200. package/dist/server/paths/appDataHome.js.map +1 -0
  201. package/dist/server/retention/archive.d.ts +3 -4
  202. package/dist/server/retention/archive.d.ts.map +1 -1
  203. package/dist/server/retention/archive.js +20 -15
  204. package/dist/server/retention/archive.js.map +1 -1
  205. package/dist/server/retention/index.d.ts +1 -1
  206. package/dist/server/retention/index.js +1 -1
  207. package/dist/server/retention/policy.d.ts +2 -2
  208. package/dist/server/retention/policy.d.ts.map +1 -1
  209. package/dist/server/retention/policy.js +1 -1
  210. package/dist/server/retention/store.d.ts.map +1 -1
  211. package/dist/server/retention/store.js +27 -20
  212. package/dist/server/retention/store.js.map +1 -1
  213. package/dist/server/runtime/localHost.d.ts +10 -5
  214. package/dist/server/runtime/localHost.d.ts.map +1 -1
  215. package/dist/server/runtime/localHost.js +12 -8
  216. package/dist/server/runtime/localHost.js.map +1 -1
  217. package/dist/server/runtime/meterRollup.pg.test.js +1 -0
  218. package/dist/server/runtime/meterRollup.pg.test.js.map +1 -1
  219. package/dist/server/runtime/recipe.d.ts +4 -4
  220. package/dist/server/runtime/retentionJob.pg.test.js +1 -0
  221. package/dist/server/runtime/retentionJob.pg.test.js.map +1 -1
  222. package/dist/server/search/pgSearchProvider.pg.test.js +1 -0
  223. package/dist/server/search/pgSearchProvider.pg.test.js.map +1 -1
  224. package/dist/shared/errors.d.ts +1 -1
  225. package/dist/shared/errors.js +1 -1
  226. package/dist/styles-static.css +413 -0
  227. package/dist/styles-utilities.css +5074 -0
  228. package/dist/styles.css +49 -0
  229. package/package.json +30 -168
  230. package/scripts/generateStaticStyles.ts +122 -0
  231. package/scripts/generateUtilityStyles.ts +215 -0
  232. package/scripts/publicSurface.ts +455 -0
  233. package/scripts/testTmpRoot.ts +34 -5
  234. package/src/client/index.ts +1 -1
  235. package/src/core/category/index.ts +2 -1
  236. package/src/core/category/types.ts +1 -1
  237. package/src/core/file-tree/fileTreeModel.spec.ts +134 -0
  238. package/src/core/file-tree/fileTreeModel.ts +104 -0
  239. package/src/core/layout/index.ts +1 -1
  240. package/src/core/media/index.ts +1 -1
  241. package/src/core/media/types.ts +1 -1
  242. package/src/core/media/uploadLimits.ts +1 -1
  243. package/src/core/sharing/model.ts +1 -1
  244. package/src/ctgr/index.ts +1 -1
  245. package/src/declaredDepsAreImported.spec.ts +87 -0
  246. package/src/demoFixture.spec.ts +133 -0
  247. package/src/index.ts +1 -1
  248. package/src/lockfileIsTracked.spec.ts +50 -0
  249. package/src/namedSubpathsResolve.spec.ts +119 -0
  250. package/src/publicSurface.spec.ts +72 -0
  251. package/src/react/activity-bar/ActivityBar.tsx +17 -0
  252. package/src/react/analytics/index.ts +1 -1
  253. package/src/react/chat/MessageComposer.tsx +5 -4
  254. package/src/react/components/Button.tsx +3 -2
  255. package/src/react/components/Checkbox.spec.tsx +51 -0
  256. package/src/react/components/Checkbox.tsx +68 -26
  257. package/src/react/components/CodeArea.tsx +2 -1
  258. package/src/react/components/CodeChip.spec.tsx +2 -2
  259. package/src/react/components/Collapsible.tsx +2 -1
  260. package/src/react/components/ComboboxField.tsx +3 -2
  261. package/src/react/components/CopyButton.tsx +2 -1
  262. package/src/react/components/CopyableText.spec.tsx +1 -1
  263. package/src/react/components/DataTable/ColumnChecklist.tsx +2 -1
  264. package/src/react/components/DataTable/Pagination.tsx +2 -1
  265. package/src/react/components/DataTable/SortHeader.tsx +2 -1
  266. package/src/react/components/DataTable/{FilterBuilder.tsx → TableFilterBuilder.tsx} +33 -5
  267. package/src/react/components/DataTable/Toolbar.tsx +3 -3
  268. package/src/react/components/DataTable/cells/LinkCell.tsx +2 -1
  269. package/src/react/components/DataTable/index.ts +8 -1
  270. package/src/react/components/DragHandle.tsx +2 -1
  271. package/src/react/components/EmojiField.tsx +2 -1
  272. package/src/react/components/EventTimeline.tsx +3 -2
  273. package/src/react/components/FileLocation.spec.tsx +1 -1
  274. package/src/react/components/IconButton.tsx +1 -1
  275. package/src/react/components/InfoHint.tsx +5 -4
  276. package/src/react/components/InheritBadge.tsx +1 -1
  277. package/src/react/components/InlineEditableText.tsx +2 -1
  278. package/src/react/components/MeterList.tsx +2 -1
  279. package/src/react/components/PathText.tsx +4 -3
  280. package/src/react/components/RatingField.tsx +2 -1
  281. package/src/react/components/SecretInput.tsx +3 -3
  282. package/src/react/components/SegmentedControl.tsx +2 -2
  283. package/src/react/components/StarRating.spec.tsx +2 -2
  284. package/src/react/components/StarRating.tsx +9 -5
  285. package/src/react/components/StatStrip.tsx +2 -1
  286. package/src/react/components/StatTile.tsx +3 -3
  287. package/src/react/components/Tabs.spec.tsx +3 -2
  288. package/src/react/components/Tabs.tsx +2 -1
  289. package/src/react/components/TruncatedText.tsx +2 -1
  290. package/src/react/components/calendar/MonthGrid.spec.tsx +2 -1
  291. package/src/react/components/calendar/MonthGrid.tsx +2 -1
  292. package/src/react/components/calendar/WeekView.tsx +2 -1
  293. package/src/react/components/revealOnHover.ts +3 -2
  294. package/src/react/file-tree/FileTree.spec.tsx +248 -0
  295. package/src/react/file-tree/FileTree.tsx +304 -4
  296. package/src/react/file-tree/fileTree.css +52 -0
  297. package/src/react/file-tree/fileTreeGeometry.fixture.json +151 -0
  298. package/src/react/file-tree/fileTreeGeometry.spec.ts +33 -52
  299. package/src/react/filter-rail/FilterRail.spec.tsx +2 -1
  300. package/src/react/filter-rail/FilterRail.tsx +5 -4
  301. package/src/react/folder-tree/FolderTreeRail.tsx +2 -1
  302. package/src/react/index.ts +13 -3
  303. package/src/react/layoutEngine/index.ts +1 -1
  304. package/src/react/layoutEngine/types.ts +1 -1
  305. package/src/react/lib/field.ts +4 -2
  306. package/src/react/lib/floatingStyles.spec.ts +2 -1
  307. package/src/react/lib/floatingStyles.ts +3 -1
  308. package/src/react/lib/tapTarget.ts +100 -0
  309. package/src/react/media/MaskPainter.tsx +2 -2
  310. package/src/react/media/VideoTrimmer.tsx +1 -1
  311. package/src/react/media/denseGallery.css +3 -3
  312. package/src/react/media/ffmpegWasm.ts +2 -2
  313. package/src/react/media/videoPlayer.css +42 -0
  314. package/src/react/namespace/NamespaceTargetCapsule.tsx +2 -2
  315. package/src/react/nav/BreadcrumbTrail.tsx +4 -3
  316. package/src/react/nav/HubTileGrid.tsx +2 -1
  317. package/src/react/nav/SideNav.tsx +4 -3
  318. package/src/react/nav/SideNavCustomize.tsx +2 -1
  319. package/src/react/palette/CommandPalette.tsx +3 -2
  320. package/src/server/ctgr.ts +1 -1
  321. package/src/server/drivers/pooledControlStores.pg.test.ts +1 -0
  322. package/src/server/drivers/pooledIdentityStore.pg.test.ts +1 -0
  323. package/src/server/drivers/retentionPolicy.pg.test.ts +1 -0
  324. package/src/server/guard/argon2Binding.ts +1 -1
  325. package/src/server/incidents/store.ts +3 -3
  326. package/src/server/index.ts +1 -1
  327. package/src/server/master-lock/masterLock.spec.ts +18 -2
  328. package/src/server/master-lock/masterLock.ts +1 -1
  329. package/src/server/media-bun/image.spec.ts +1 -0
  330. package/src/server/media-bun/index.ts +1 -1
  331. package/src/server/media-bun/video.spec.ts +1 -0
  332. package/src/server/paths/appDataHome.spec.ts +87 -0
  333. package/src/server/paths/appDataHome.ts +84 -0
  334. package/src/server/retention/archive.spec.ts +26 -4
  335. package/src/server/retention/archive.ts +20 -15
  336. package/src/server/retention/index.ts +1 -1
  337. package/src/server/retention/policy.ts +2 -2
  338. package/src/server/retention/store.spec.ts +38 -10
  339. package/src/server/retention/store.ts +26 -19
  340. package/src/server/runtime/localHost.spec.ts +22 -3
  341. package/src/server/runtime/localHost.ts +12 -9
  342. package/src/server/runtime/meterRollup.pg.test.ts +1 -0
  343. package/src/server/runtime/recipe.ts +4 -4
  344. package/src/server/runtime/retentionJob.pg.test.ts +1 -0
  345. package/src/server/search/pgSearchProvider.pg.test.ts +1 -0
  346. package/src/server/storage/binaryServerProcessing.integration.spec.ts +6 -2
  347. package/src/server/storage/chunked.integration.spec.ts +5 -2
  348. package/src/server/storage/fileUploadClient-chunked.integration.spec.ts +5 -2
  349. package/src/server/storage/files/adapter.photo.display.spec.ts +1 -0
  350. package/src/server/storage/imageThumbnail.spec.ts +1 -0
  351. package/src/server/storage/transcode.integration.spec.ts +5 -2
  352. package/src/server/storage/videoProcessor.posterOnly.spec.ts +1 -0
  353. package/src/shared/errors.ts +1 -1
  354. package/src/skippedTestsAreAnswered.spec.ts +215 -0
  355. package/src/styles-static.css +413 -0
  356. package/src/styles-utilities.css +5074 -0
  357. package/src/styles.css +49 -0
  358. package/src/stylesStaticMatches.spec.ts +134 -0
  359. package/src/stylesUtilitiesMatches.spec.ts +314 -0
  360. package/src/tapTargetStylesheet.spec.ts +150 -0
  361. package/src/testTmpRoot.spec.ts +102 -0
  362. package/dist/core/duplicates/index.d.ts +0 -116
  363. package/dist/core/duplicates/index.d.ts.map +0 -1
  364. package/dist/core/duplicates/index.js +0 -178
  365. package/dist/core/duplicates/index.js.map +0 -1
  366. package/dist/core/namespace/helpers.d.ts +0 -14
  367. package/dist/core/namespace/helpers.d.ts.map +0 -1
  368. package/dist/core/namespace/helpers.js +0 -29
  369. package/dist/core/namespace/helpers.js.map +0 -1
  370. package/dist/core/namespace/index.d.ts +0 -4
  371. package/dist/core/namespace/index.d.ts.map +0 -1
  372. package/dist/core/namespace/index.js +0 -6
  373. package/dist/core/namespace/index.js.map +0 -1
  374. package/dist/core/namespace/memoryStore.d.ts +0 -19
  375. package/dist/core/namespace/memoryStore.d.ts.map +0 -1
  376. package/dist/core/namespace/memoryStore.js +0 -70
  377. package/dist/core/namespace/memoryStore.js.map +0 -1
  378. package/dist/core/namespace/types.d.ts +0 -44
  379. package/dist/core/namespace/types.d.ts.map +0 -1
  380. package/dist/core/namespace/types.js +0 -8
  381. package/dist/core/namespace/types.js.map +0 -1
  382. package/dist/game/core/DisposeRegistry.d.ts +0 -42
  383. package/dist/game/core/DisposeRegistry.d.ts.map +0 -1
  384. package/dist/game/core/DisposeRegistry.js +0 -67
  385. package/dist/game/core/DisposeRegistry.js.map +0 -1
  386. package/dist/game/core/drawBudget.d.ts +0 -26
  387. package/dist/game/core/drawBudget.d.ts.map +0 -1
  388. package/dist/game/core/drawBudget.js +0 -55
  389. package/dist/game/core/drawBudget.js.map +0 -1
  390. package/dist/game/core/fixedTimestep.d.ts +0 -38
  391. package/dist/game/core/fixedTimestep.d.ts.map +0 -1
  392. package/dist/game/core/fixedTimestep.js +0 -47
  393. package/dist/game/core/fixedTimestep.js.map +0 -1
  394. package/dist/game/core/index.d.ts +0 -9
  395. package/dist/game/core/index.d.ts.map +0 -1
  396. package/dist/game/core/index.js +0 -8
  397. package/dist/game/core/index.js.map +0 -1
  398. package/dist/game/core/inputCollector.d.ts +0 -82
  399. package/dist/game/core/inputCollector.d.ts.map +0 -1
  400. package/dist/game/core/inputCollector.js +0 -176
  401. package/dist/game/core/inputCollector.js.map +0 -1
  402. package/dist/game/core/resizeCanvas.d.ts +0 -19
  403. package/dist/game/core/resizeCanvas.d.ts.map +0 -1
  404. package/dist/game/core/resizeCanvas.js +0 -29
  405. package/dist/game/core/resizeCanvas.js.map +0 -1
  406. package/dist/game/react/index.d.ts +0 -3
  407. package/dist/game/react/index.d.ts.map +0 -1
  408. package/dist/game/react/index.js +0 -5
  409. package/dist/game/react/index.js.map +0 -1
  410. package/dist/game/react/useGameEngine.d.ts +0 -64
  411. package/dist/game/react/useGameEngine.d.ts.map +0 -1
  412. package/dist/game/react/useGameEngine.js +0 -78
  413. package/dist/game/react/useGameEngine.js.map +0 -1
  414. package/dist/react/canvas/CanvasNavHUD.d.ts +0 -64
  415. package/dist/react/canvas/CanvasNavHUD.d.ts.map +0 -1
  416. package/dist/react/canvas/CanvasNavHUD.js +0 -58
  417. package/dist/react/canvas/CanvasNavHUD.js.map +0 -1
  418. package/dist/react/canvas/fitLabel.d.ts +0 -53
  419. package/dist/react/canvas/fitLabel.d.ts.map +0 -1
  420. package/dist/react/canvas/fitLabel.js +0 -104
  421. package/dist/react/canvas/fitLabel.js.map +0 -1
  422. package/dist/react/canvas/index.d.ts +0 -4
  423. package/dist/react/canvas/index.d.ts.map +0 -1
  424. package/dist/react/canvas/index.js +0 -4
  425. package/dist/react/canvas/index.js.map +0 -1
  426. package/dist/react/canvas/lod.d.ts +0 -40
  427. package/dist/react/canvas/lod.d.ts.map +0 -1
  428. package/dist/react/canvas/lod.js +0 -37
  429. package/dist/react/canvas/lod.js.map +0 -1
  430. package/dist/react/components/DataTable/FilterBuilder.d.ts +0 -38
  431. package/dist/react/components/DataTable/FilterBuilder.d.ts.map +0 -1
  432. package/dist/react/components/DataTable/FilterBuilder.js.map +0 -1
  433. package/dist/react/seo/HeadProvider.d.ts +0 -14
  434. package/dist/react/seo/HeadProvider.d.ts.map +0 -1
  435. package/dist/react/seo/HeadProvider.js +0 -44
  436. package/dist/react/seo/HeadProvider.js.map +0 -1
  437. package/dist/react/seo/applyHeadToDocument.d.ts +0 -3
  438. package/dist/react/seo/applyHeadToDocument.d.ts.map +0 -1
  439. package/dist/react/seo/applyHeadToDocument.js +0 -66
  440. package/dist/react/seo/applyHeadToDocument.js.map +0 -1
  441. package/dist/react/seo/index.d.ts +0 -3
  442. package/dist/react/seo/index.d.ts.map +0 -1
  443. package/dist/react/seo/index.js +0 -7
  444. package/dist/react/seo/index.js.map +0 -1
  445. package/dist/react/timeline/ClipView.d.ts +0 -29
  446. package/dist/react/timeline/ClipView.d.ts.map +0 -1
  447. package/dist/react/timeline/ClipView.js +0 -53
  448. package/dist/react/timeline/ClipView.js.map +0 -1
  449. package/dist/react/timeline/Playhead.d.ts +0 -16
  450. package/dist/react/timeline/Playhead.d.ts.map +0 -1
  451. package/dist/react/timeline/Playhead.js +0 -26
  452. package/dist/react/timeline/Playhead.js.map +0 -1
  453. package/dist/react/timeline/TimeRuler.d.ts +0 -21
  454. package/dist/react/timeline/TimeRuler.d.ts.map +0 -1
  455. package/dist/react/timeline/TimeRuler.js +0 -31
  456. package/dist/react/timeline/TimeRuler.js.map +0 -1
  457. package/dist/react/timeline/TimelineSurface.d.ts +0 -29
  458. package/dist/react/timeline/TimelineSurface.d.ts.map +0 -1
  459. package/dist/react/timeline/TimelineSurface.js +0 -56
  460. package/dist/react/timeline/TimelineSurface.js.map +0 -1
  461. package/dist/react/timeline/TrackLane.d.ts +0 -31
  462. package/dist/react/timeline/TrackLane.d.ts.map +0 -1
  463. package/dist/react/timeline/TrackLane.js +0 -32
  464. package/dist/react/timeline/TrackLane.js.map +0 -1
  465. package/dist/react/timeline/index.d.ts +0 -6
  466. package/dist/react/timeline/index.d.ts.map +0 -1
  467. package/dist/react/timeline/index.js +0 -12
  468. package/dist/react/timeline/index.js.map +0 -1
  469. package/dist/server/private-media/index.d.ts +0 -7
  470. package/dist/server/private-media/index.d.ts.map +0 -1
  471. package/dist/server/private-media/index.js +0 -13
  472. package/dist/server/private-media/index.js.map +0 -1
  473. package/dist/server/seo/index.d.ts +0 -3
  474. package/dist/server/seo/index.d.ts.map +0 -1
  475. package/dist/server/seo/index.js +0 -6
  476. package/dist/server/seo/index.js.map +0 -1
  477. package/dist/server/seo/mountSeoRoutes.d.ts +0 -9
  478. package/dist/server/seo/mountSeoRoutes.d.ts.map +0 -1
  479. package/dist/server/seo/mountSeoRoutes.js +0 -19
  480. package/dist/server/seo/mountSeoRoutes.js.map +0 -1
  481. package/dist/server/seo/serveHeadInjectedIndex.d.ts +0 -9
  482. package/dist/server/seo/serveHeadInjectedIndex.d.ts.map +0 -1
  483. package/dist/server/seo/serveHeadInjectedIndex.js +0 -20
  484. package/dist/server/seo/serveHeadInjectedIndex.js.map +0 -1
  485. package/dist/upload.d.ts +0 -148
  486. package/dist/upload.d.ts.map +0 -1
  487. package/dist/upload.js +0 -159
  488. package/dist/upload.js.map +0 -1
  489. package/dist/verify/runtime/index.d.ts +0 -16
  490. package/dist/verify/runtime/index.d.ts.map +0 -1
  491. package/dist/verify/runtime/index.js +0 -16
  492. package/dist/verify/runtime/index.js.map +0 -1
  493. package/scripts/demoCheck.ts +0 -42
  494. package/src/core/duplicates/index.spec.ts +0 -116
  495. package/src/core/duplicates/index.ts +0 -203
  496. package/src/core/namespace/helpers.ts +0 -31
  497. package/src/core/namespace/index.ts +0 -12
  498. package/src/core/namespace/memoryStore.ts +0 -77
  499. package/src/core/namespace/namespace.spec.ts +0 -117
  500. package/src/core/namespace/types.ts +0 -53
  501. package/src/game/core/DisposeRegistry.spec.ts +0 -53
  502. package/src/game/core/DisposeRegistry.ts +0 -70
  503. package/src/game/core/drawBudget.spec.ts +0 -51
  504. package/src/game/core/drawBudget.ts +0 -75
  505. package/src/game/core/fixedTimestep.spec.ts +0 -91
  506. package/src/game/core/fixedTimestep.ts +0 -79
  507. package/src/game/core/index.ts +0 -16
  508. package/src/game/core/inputCollector.spec.ts +0 -29
  509. package/src/game/core/inputCollector.ts +0 -245
  510. package/src/game/core/resizeCanvas.ts +0 -31
  511. package/src/game/react/index.ts +0 -10
  512. package/src/game/react/useGameEngine.ts +0 -125
  513. package/src/react/canvas/CanvasNavHUD.spec.tsx +0 -62
  514. package/src/react/canvas/CanvasNavHUD.tsx +0 -210
  515. package/src/react/canvas/fitLabel.spec.ts +0 -82
  516. package/src/react/canvas/fitLabel.ts +0 -150
  517. package/src/react/canvas/index.ts +0 -15
  518. package/src/react/canvas/lod.ts +0 -53
  519. package/src/react/seo/HeadProvider.tsx +0 -67
  520. package/src/react/seo/applyHeadToDocument.ts +0 -73
  521. package/src/react/seo/index.ts +0 -12
  522. package/src/react/seo/seo.spec.tsx +0 -101
  523. package/src/react/timeline/ClipView.tsx +0 -146
  524. package/src/react/timeline/Playhead.tsx +0 -63
  525. package/src/react/timeline/TimeRuler.tsx +0 -85
  526. package/src/react/timeline/TimelineSurface.tsx +0 -157
  527. package/src/react/timeline/TrackLane.tsx +0 -87
  528. package/src/react/timeline/index.ts +0 -12
  529. package/src/react/timeline/timeline.spec.tsx +0 -175
  530. package/src/server/private-media/index.ts +0 -45
  531. package/src/server/seo/index.ts +0 -8
  532. package/src/server/seo/mountSeoRoutes.ts +0 -37
  533. package/src/server/seo/seo.spec.ts +0 -128
  534. package/src/server/seo/serveHeadInjectedIndex.ts +0 -36
  535. package/src/upload.spec.ts +0 -300
  536. package/src/upload.ts +0 -288
  537. package/src/verify/runtime/index.ts +0 -64
@@ -1,36 +0,0 @@
1
- import type { HeadModel } from 'cwip/seo';
2
- import { injectHead, renderHead, stripBaseTitleAndDescription } from 'cwip/seo';
3
- import type { Context } from 'hono';
4
-
5
- export interface ServeHeadInjectedIndexOptions {
6
- // The SPA's index.html, or a (possibly async) loader for it — read once per
7
- // request so a caller can hot-reload the file in dev without restarting.
8
- html: string | (() => string | Promise<string>);
9
- // Looks up the HeadModel for a request path; return undefined to serve the base
10
- // shell untouched (no injection) for an unmapped route.
11
- resolve: (path: string) => HeadModel | undefined;
12
- // Strip the base <title>/<meta name="description"> out of the shell before
13
- // injecting the route's own (default true) — otherwise the shell's baseline
14
- // title/description would sit alongside the injected ones.
15
- stripBase?: boolean;
16
- }
17
-
18
- // Builds a Hono handler that serves `opts.html` with a per-route HeadModel spliced
19
- // into <head> via cwip's `injectHead`/`renderHead` — a pure string transform, so it
20
- // runs anywhere Bun does (this repo's Hono/Bun.serve host). An HTMLRewriter-based
21
- // streaming variant for Cloudflare Workers/Pages Functions can reuse the exact same
22
- // `renderHead` output later; that seam is intentionally left for a future target
23
- // rather than built here (see seo-reusable-plan.md §4/§6).
24
- export const serveHeadInjectedIndex = (opts: ServeHeadInjectedIndexOptions) => {
25
- const stripBase = opts.stripBase ?? true;
26
-
27
- return async (c: Context) => {
28
- const html = typeof opts.html === 'function' ? await opts.html() : opts.html;
29
- const model = opts.resolve(c.req.path);
30
- if (!model) return c.html(html);
31
-
32
- const shell = stripBase ? stripBaseTitleAndDescription(html) : html;
33
- const headHtml = renderHead(model, { marker: true, indent: ' ' });
34
- return c.html(injectHead(shell, headHtml));
35
- };
36
- };
@@ -1,300 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import {
3
- createDropZoneHandlers,
4
- formatValidationError,
5
- isHeicFile,
6
- type UploadProgress,
7
- type UploadTransport,
8
- uploadFile,
9
- uploadFiles,
10
- validateFile,
11
- } from './upload';
12
-
13
- // ── validateFile ──────────────────────────────────────────────────────────────
14
-
15
- describe('validateFile', () => {
16
- const jpegFile = new File(['bytes'], 'photo.jpg', { type: 'image/jpeg' });
17
- const bigFile = new File([new Uint8Array(20 * 1024 * 1024 + 1)], 'big.bin', {
18
- type: 'application/octet-stream',
19
- });
20
-
21
- test('passes with no constraints', () => {
22
- expect(validateFile(jpegFile, {})).toEqual({ ok: true });
23
- });
24
-
25
- test('passes when MIME matches exact pattern', () => {
26
- expect(validateFile(jpegFile, { accept: ['image/jpeg'] })).toEqual({ ok: true });
27
- });
28
-
29
- test('passes when MIME matches glob prefix image/*', () => {
30
- expect(validateFile(jpegFile, { accept: ['image/*'] })).toEqual({ ok: true });
31
- });
32
-
33
- test('fails when MIME does not match any pattern', () => {
34
- const res = validateFile(jpegFile, { accept: ['video/*'] });
35
- expect(res.ok).toBe(false);
36
- if (res.ok) return;
37
- expect(res.error.kind).toBe('type');
38
- });
39
-
40
- test('fails when file exceeds maxBytes', () => {
41
- const res = validateFile(bigFile, { maxBytes: 10 * 1024 * 1024 });
42
- expect(res.ok).toBe(false);
43
- if (res.ok) return;
44
- expect(res.error.kind).toBe('size');
45
- });
46
-
47
- test('passes size when file is exactly maxBytes', () => {
48
- const exact = new File([new Uint8Array(1024)], 'exact.bin', {
49
- type: 'application/octet-stream',
50
- });
51
- expect(validateFile(exact, { maxBytes: 1024 })).toEqual({ ok: true });
52
- });
53
-
54
- test('formatValidationError returns human-readable messages', () => {
55
- const typeErr = validateFile(jpegFile, { accept: ['video/*'] });
56
- if (typeErr.ok) throw new Error('expected error');
57
- expect(formatValidationError(typeErr.error)).toContain('image/jpeg');
58
-
59
- const sizeErr = validateFile(bigFile, { maxBytes: 1024 });
60
- if (sizeErr.ok) throw new Error('expected error');
61
- expect(formatValidationError(sizeErr.error)).toContain('MB');
62
- });
63
- });
64
-
65
- // ── isHeicFile ────────────────────────────────────────────────────────────────
66
-
67
- describe('isHeicFile', () => {
68
- test('detects image/heic MIME', () => {
69
- expect(isHeicFile(new File([''], 'photo.heic', { type: 'image/heic' }))).toBe(true);
70
- });
71
-
72
- test('detects image/heif MIME', () => {
73
- expect(isHeicFile(new File([''], 'photo.heif', { type: 'image/heif' }))).toBe(true);
74
- });
75
-
76
- test('detects .heic extension when MIME is missing', () => {
77
- expect(isHeicFile(new File([''], 'photo.heic', { type: '' }))).toBe(true);
78
- });
79
-
80
- test('returns false for normal JPEG', () => {
81
- expect(isHeicFile(new File([''], 'photo.jpg', { type: 'image/jpeg' }))).toBe(false);
82
- });
83
- });
84
-
85
- // ── uploadFile ────────────────────────────────────────────────────────────────
86
-
87
- function makeTransport(
88
- outcome: Awaited<ReturnType<UploadTransport['uploadAuto']>>,
89
- ): UploadTransport {
90
- return {
91
- uploadAuto: async (_file, _opts) => outcome,
92
- upload: async (_file, _opts) => outcome,
93
- };
94
- }
95
-
96
- const FAKE_FILE_RECORD = {
97
- id: 'f1',
98
- name: 'photo.jpg',
99
- mime: 'image/jpeg',
100
- size: 100,
101
- fileType: 'image',
102
- tags: [],
103
- processingStatus: 'ready',
104
- };
105
-
106
- describe('uploadFile', () => {
107
- test('returns ok:true with file record on success', async () => {
108
- const transport = makeTransport({ ok: true, file: FAKE_FILE_RECORD });
109
- const res = await uploadFile(new File(['x'], 'photo.jpg', { type: 'image/jpeg' }), {
110
- transport,
111
- });
112
- expect(res.ok).toBe(true);
113
- if (!res.ok) return;
114
- expect(res.file.id).toBe('f1');
115
- });
116
-
117
- test('emits progress events: validating → uploading → done', async () => {
118
- const transport = makeTransport({ ok: true, file: FAKE_FILE_RECORD });
119
- const phases: string[] = [];
120
- await uploadFile(new File(['x'], 'photo.jpg', { type: 'image/jpeg' }), {
121
- transport,
122
- onProgress: (p: UploadProgress) => phases.push(p.phase),
123
- });
124
- expect(phases).toEqual(['validating', 'uploading', 'done']);
125
- });
126
-
127
- test('rejects invalid MIME before calling transport', async () => {
128
- let called = false;
129
- const transport: UploadTransport = {
130
- uploadAuto: async () => {
131
- called = true;
132
- return { ok: true, file: FAKE_FILE_RECORD };
133
- },
134
- upload: async () => {
135
- called = true;
136
- return { ok: true, file: FAKE_FILE_RECORD };
137
- },
138
- };
139
- const res = await uploadFile(new File(['x'], 'vid.mp4', { type: 'video/mp4' }), {
140
- transport,
141
- constraints: { accept: ['image/*'] },
142
- });
143
- expect(res.ok).toBe(false);
144
- expect(called).toBe(false);
145
- });
146
-
147
- test('rejects oversized file before calling transport', async () => {
148
- let called = false;
149
- const transport: UploadTransport = {
150
- uploadAuto: async () => {
151
- called = true;
152
- return { ok: true, file: FAKE_FILE_RECORD };
153
- },
154
- upload: async () => {
155
- called = true;
156
- return { ok: true, file: FAKE_FILE_RECORD };
157
- },
158
- };
159
- const big = new File([new Uint8Array(1025)], 'big.jpg', { type: 'image/jpeg' });
160
- const res = await uploadFile(big, { transport, constraints: { maxBytes: 1024 } });
161
- expect(res.ok).toBe(false);
162
- expect(called).toBe(false);
163
- });
164
-
165
- test('propagates transport error as ok:false', async () => {
166
- const transport = makeTransport({ ok: false, error: 'network failure' });
167
- const res = await uploadFile(new File(['x'], 'x.jpg', { type: 'image/jpeg' }), { transport });
168
- expect(res.ok).toBe(false);
169
- if (res.ok) return;
170
- expect(res.error).toBe('network failure');
171
- });
172
-
173
- test('marks heicConverted:true for HEIC files', async () => {
174
- const transport = makeTransport({
175
- ok: true,
176
- file: { ...FAKE_FILE_RECORD, mime: 'image/heic' },
177
- });
178
- const res = await uploadFile(new File(['x'], 'photo.heic', { type: 'image/heic' }), {
179
- transport,
180
- });
181
- expect(res.ok).toBe(true);
182
- if (!res.ok) return;
183
- expect(res.file.heicConverted).toBe(true);
184
- });
185
-
186
- test('passes tags to transport', async () => {
187
- let capturedTags: string[] | undefined;
188
- const transport: UploadTransport = {
189
- uploadAuto: async (_file, opts) => {
190
- capturedTags = opts?.tags;
191
- return { ok: true, file: FAKE_FILE_RECORD };
192
- },
193
- upload: async () => ({ ok: true, file: FAKE_FILE_RECORD }),
194
- };
195
- await uploadFile(new File(['x'], 'x.jpg', { type: 'image/jpeg' }), {
196
- transport,
197
- tags: ['travel', 'portrait'],
198
- });
199
- expect(capturedTags).toEqual(['travel', 'portrait']);
200
- });
201
- });
202
-
203
- // ── uploadFiles ───────────────────────────────────────────────────────────────
204
-
205
- describe('uploadFiles', () => {
206
- test('returns all results when all succeed', async () => {
207
- const transport = makeTransport({ ok: true, file: FAKE_FILE_RECORD });
208
- const files = [
209
- new File(['a'], 'a.jpg', { type: 'image/jpeg' }),
210
- new File(['b'], 'b.jpg', { type: 'image/jpeg' }),
211
- ];
212
- const { results, firstError } = await uploadFiles(files, { transport });
213
- expect(results).toHaveLength(2);
214
- expect(firstError).toBeNull();
215
- });
216
-
217
- test('stops at the first error and reports it', async () => {
218
- let callCount = 0;
219
- const transport: UploadTransport = {
220
- uploadAuto: async () => {
221
- callCount++;
222
- return callCount === 1
223
- ? { ok: false, error: 'failed' }
224
- : { ok: true, file: FAKE_FILE_RECORD };
225
- },
226
- upload: async () => ({ ok: true, file: FAKE_FILE_RECORD }),
227
- };
228
- const files = [
229
- new File(['a'], 'a.jpg', { type: 'image/jpeg' }),
230
- new File(['b'], 'b.jpg', { type: 'image/jpeg' }),
231
- ];
232
- const { results, firstError } = await uploadFiles(files, { transport });
233
- expect(firstError).toBe('failed');
234
- expect(results).toHaveLength(1);
235
- expect(callCount).toBe(1);
236
- });
237
- });
238
-
239
- // ── createDropZoneHandlers ────────────────────────────────────────────────────
240
-
241
- describe('createDropZoneHandlers', () => {
242
- function makeDropEvent(files: File[]): DragEvent {
243
- const dt = {
244
- files: Object.assign(files, {
245
- item: (i: number) => files[i] ?? null,
246
- [Symbol.iterator]: files[Symbol.iterator].bind(files),
247
- }) as unknown as FileList,
248
- };
249
- return {
250
- preventDefault: () => {},
251
- dataTransfer: dt,
252
- } as unknown as DragEvent;
253
- }
254
-
255
- test('onDrop delivers files to onFiles', () => {
256
- const received: File[] = [];
257
- const { onDrop } = createDropZoneHandlers({ onFiles: (fs) => received.push(...fs) });
258
- const file = new File(['x'], 'x.txt', { type: 'text/plain' });
259
- onDrop(makeDropEvent([file]));
260
- expect(received).toHaveLength(1);
261
- expect(received[0]!.name).toBe('x.txt');
262
- });
263
-
264
- test('onDrop filters by accept when provided', () => {
265
- const received: File[] = [];
266
- const { onDrop } = createDropZoneHandlers({
267
- onFiles: (fs) => received.push(...fs),
268
- accept: ['image/*'],
269
- });
270
- const img = new File([''], 'a.jpg', { type: 'image/jpeg' });
271
- const doc = new File([''], 'b.txt', { type: 'text/plain' });
272
- onDrop(makeDropEvent([img, doc]));
273
- expect(received).toHaveLength(1);
274
- expect(received[0]!.name).toBe('a.jpg');
275
- });
276
-
277
- test('onDragOver calls onEnter', () => {
278
- let entered = false;
279
- const { onDragOver } = createDropZoneHandlers({
280
- onFiles: () => {},
281
- onEnter: () => {
282
- entered = true;
283
- },
284
- });
285
- onDragOver({ preventDefault: () => {} } as DragEvent);
286
- expect(entered).toBe(true);
287
- });
288
-
289
- test('onDragLeave calls onLeave', () => {
290
- let left = false;
291
- const { onDragLeave } = createDropZoneHandlers({
292
- onFiles: () => {},
293
- onLeave: () => {
294
- left = true;
295
- },
296
- });
297
- onDragLeave({ preventDefault: () => {} } as DragEvent);
298
- expect(left).toBe(true);
299
- });
300
- });
package/src/upload.ts DELETED
@@ -1,288 +0,0 @@
1
- // cursedbelt/upload — framework-agnostic upload primitive
2
- //
3
- // Sits above the transport (fileUploadClient) and below the UI layer. Provides:
4
- // • Client-side validation (MIME type + byte size)
5
- // • Progress events during upload
6
- // • Drag-and-drop drop-zone wiring (pure DOM, no React)
7
- // • HEIC/HEIF mobile-photo detection (conversion is server-side)
8
- // • Typed UploadResult contract consumed by MediaUploadControl and app plugins
9
- //
10
- // Consumers that want the raw transport client import createFileUploadClient from
11
- // 'cursedbelt/react/media'; this module layers validation + progress on top.
12
-
13
- // ── MIME / HEIC ──────────────────────────────────────────────────────────────
14
-
15
- /** True for iPhone HEIC/HEIF images — the server converts these to JPEG. */
16
- export function isHeicFile(file: File): boolean {
17
- const mime = file.type.toLowerCase();
18
- if (mime === 'image/heic' || mime === 'image/heif') return true;
19
- const name = file.name.toLowerCase();
20
- return name.endsWith('.heic') || name.endsWith('.heif');
21
- }
22
-
23
- // ── Validation ───────────────────────────────────────────────────────────────
24
-
25
- export interface UploadConstraints {
26
- /** Allowed MIME types (exact match or glob prefix, e.g. 'image/*'). If omitted, any type. */
27
- accept?: string[];
28
- /** Maximum file size in bytes. If omitted, no cap. */
29
- maxBytes?: number;
30
- }
31
-
32
- export type ValidationError =
33
- | { kind: 'type'; file: string; mime: string; accept: string[] }
34
- | { kind: 'size'; file: string; bytes: number; maxBytes: number };
35
-
36
- export type ValidationResult = { ok: true } | { ok: false; error: ValidationError };
37
-
38
- function mimeMatches(mime: string, pattern: string): boolean {
39
- if (pattern === mime) return true;
40
- if (pattern.endsWith('/*')) {
41
- return mime.startsWith(pattern.slice(0, -1));
42
- }
43
- return false;
44
- }
45
-
46
- export function validateFile(file: File, constraints: UploadConstraints): ValidationResult {
47
- if (constraints.accept?.length) {
48
- const mime = file.type || 'application/octet-stream';
49
- const ok = constraints.accept.some((p) => mimeMatches(mime, p));
50
- if (!ok)
51
- return {
52
- ok: false,
53
- error: { kind: 'type', file: file.name, mime, accept: constraints.accept },
54
- };
55
- }
56
- if (constraints.maxBytes !== undefined && file.size > constraints.maxBytes) {
57
- return {
58
- ok: false,
59
- error: { kind: 'size', file: file.name, bytes: file.size, maxBytes: constraints.maxBytes },
60
- };
61
- }
62
- return { ok: true };
63
- }
64
-
65
- export function formatValidationError(error: ValidationError): string {
66
- if (error.kind === 'type') {
67
- return `"${error.file}" is not an accepted file type (${error.mime}). Accepted: ${error.accept.join(', ')}.`;
68
- }
69
- return `"${error.file}" is too large (${(error.bytes / 1024 / 1024).toFixed(1)} MB). Max: ${(error.maxBytes / 1024 / 1024).toFixed(1)} MB.`;
70
- }
71
-
72
- // ── Progress ──────────────────────────────────────────────────────────────────
73
-
74
- export type UploadProgress =
75
- | { phase: 'validating' }
76
- | { phase: 'uploading'; loaded: number; total: number }
77
- | { phase: 'chunking'; chunk: number; total: number }
78
- | { phase: 'done' }
79
- | { phase: 'error'; message: string };
80
-
81
- // ── Result contract ───────────────────────────────────────────────────────────
82
-
83
- /** Subset of the server FileRecord that upload consumers care about. */
84
- export interface UploadedFile {
85
- id: string;
86
- name: string;
87
- mime: string;
88
- size: number;
89
- fileType: string;
90
- tags: string[];
91
- processingStatus: string;
92
- /** True when the server accepted a HEIC/HEIF file for conversion. */
93
- heicConverted?: boolean;
94
- }
95
-
96
- export type UploadResult =
97
- | { ok: true; file: UploadedFile }
98
- | { ok: false; error: string; validationError?: ValidationError };
99
-
100
- // ── Transport interface (injected — keeps this module framework-agnostic) ─────
101
-
102
- /** Minimal transport interface the pipeline requires — satisfied by FileUploadClient. */
103
- export interface UploadTransport {
104
- uploadAuto(
105
- file: File,
106
- opts?: { tags?: string[] },
107
- ): Promise<
108
- | {
109
- ok: true;
110
- file?: {
111
- id: string;
112
- name: string;
113
- mime: string;
114
- size: number;
115
- fileType: string;
116
- tags: string[];
117
- processingStatus: string;
118
- };
119
- }
120
- | { ok: false; error: string }
121
- >;
122
- upload(
123
- file: File | Blob,
124
- opts?: { name?: string; tags?: string[] },
125
- ): Promise<
126
- | {
127
- ok: true;
128
- file?: {
129
- id: string;
130
- name: string;
131
- mime: string;
132
- size: number;
133
- fileType: string;
134
- tags: string[];
135
- processingStatus: string;
136
- };
137
- }
138
- | { ok: false; error: string }
139
- >;
140
- }
141
-
142
- // ── Upload pipeline ───────────────────────────────────────────────────────────
143
-
144
- export interface UploadPipelineOptions {
145
- transport: UploadTransport;
146
- constraints?: UploadConstraints;
147
- tags?: string[];
148
- onProgress?: (progress: UploadProgress) => void;
149
- }
150
-
151
- export async function uploadFile(file: File, opts: UploadPipelineOptions): Promise<UploadResult> {
152
- const { transport, constraints = {}, tags, onProgress } = opts;
153
- const emit = (p: UploadProgress): void => {
154
- onProgress?.(p);
155
- };
156
-
157
- emit({ phase: 'validating' });
158
- const validation = validateFile(file, constraints);
159
- if (!validation.ok) {
160
- const msg = formatValidationError(validation.error);
161
- emit({ phase: 'error', message: msg });
162
- return { ok: false, error: msg, validationError: validation.error };
163
- }
164
-
165
- emit({ phase: 'uploading', loaded: 0, total: file.size });
166
- const heic = isHeicFile(file);
167
-
168
- const res = await transport.uploadAuto(file, { tags }).catch((e: unknown) => ({
169
- ok: false as const,
170
- error: e instanceof Error ? e.message : 'upload failed',
171
- }));
172
-
173
- if (!res.ok) {
174
- emit({ phase: 'error', message: res.error });
175
- return { ok: false, error: res.error };
176
- }
177
-
178
- const f = res.file;
179
- if (!f) {
180
- emit({ phase: 'error', message: 'upload succeeded but no file record returned' });
181
- return { ok: false, error: 'upload succeeded but no file record returned' };
182
- }
183
-
184
- emit({ phase: 'done' });
185
- return {
186
- ok: true,
187
- file: {
188
- id: f.id,
189
- name: f.name,
190
- mime: f.mime,
191
- size: f.size,
192
- fileType: f.fileType,
193
- tags: f.tags,
194
- processingStatus: f.processingStatus,
195
- heicConverted: heic,
196
- },
197
- };
198
- }
199
-
200
- /** Upload multiple files sequentially, stopping on the first error. */
201
- export async function uploadFiles(
202
- files: File[],
203
- opts: UploadPipelineOptions,
204
- ): Promise<{ results: UploadResult[]; firstError: string | null }> {
205
- const results: UploadResult[] = [];
206
- for (const file of files) {
207
- const result = await uploadFile(file, opts);
208
- results.push(result);
209
- if (!result.ok) return { results, firstError: result.error };
210
- }
211
- return { results, firstError: null };
212
- }
213
-
214
- // ── Drag-and-drop helpers (pure DOM, no framework) ────────────────────────────
215
-
216
- export interface DropZoneHandlers {
217
- onDragOver: (e: DragEvent) => void;
218
- onDragLeave: (e: DragEvent) => void;
219
- onDrop: (e: DragEvent) => void;
220
- }
221
-
222
- export interface DropZoneOptions {
223
- /** Invoked with accepted files dropped onto the zone. */
224
- onFiles: (files: File[]) => void;
225
- /** Invoked when a drag enters the zone (for visual feedback). */
226
- onEnter?: () => void;
227
- /** Invoked when a drag leaves or is dropped (for visual feedback). */
228
- onLeave?: () => void;
229
- /** Optionally filter dropped items by MIME — mismatched files are silently excluded. */
230
- accept?: string[];
231
- }
232
-
233
- /**
234
- * Returns plain event handler objects that wire a DOM element as a drop zone.
235
- * Attach them with addEventListener or pass to a React component's onDrag* props.
236
- *
237
- * @example
238
- * const { onDragOver, onDragLeave, onDrop } = createDropZoneHandlers({ onFiles });
239
- * el.addEventListener('dragover', onDragOver);
240
- * el.addEventListener('dragleave', onDragLeave);
241
- * el.addEventListener('drop', onDrop);
242
- */
243
- export function createDropZoneHandlers(opts: DropZoneOptions): DropZoneHandlers {
244
- const { onFiles, onEnter, onLeave, accept } = opts;
245
-
246
- const onDragOver = (e: DragEvent): void => {
247
- e.preventDefault();
248
- onEnter?.();
249
- };
250
-
251
- const onDragLeave = (e: DragEvent): void => {
252
- e.preventDefault();
253
- onLeave?.();
254
- };
255
-
256
- const onDrop = (e: DragEvent): void => {
257
- e.preventDefault();
258
- onLeave?.();
259
- const items = e.dataTransfer?.files;
260
- if (!items?.length) return;
261
- let files = Array.from(items);
262
- if (accept?.length) {
263
- files = files.filter((f) => accept.some((p) => mimeMatches(f.type || '', p)));
264
- }
265
- if (files.length) onFiles(files);
266
- };
267
-
268
- return { onDragOver, onDragLeave, onDrop };
269
- }
270
-
271
- /**
272
- * Mount a drop zone on `el`, returning an unmount function.
273
- *
274
- * @example
275
- * const unmount = mountDropZone(containerEl, { onFiles, accept: ['image/*'] });
276
- * // later: unmount();
277
- */
278
- export function mountDropZone(el: HTMLElement, opts: DropZoneOptions): () => void {
279
- const { onDragOver, onDragLeave, onDrop } = createDropZoneHandlers(opts);
280
- el.addEventListener('dragover', onDragOver);
281
- el.addEventListener('dragleave', onDragLeave);
282
- el.addEventListener('drop', onDrop);
283
- return () => {
284
- el.removeEventListener('dragover', onDragOver);
285
- el.removeEventListener('dragleave', onDragLeave);
286
- el.removeEventListener('drop', onDrop);
287
- };
288
- }
@@ -1,64 +0,0 @@
1
- /**
2
- * `cursedbelt/verify/runtime` — V7: verify-mode boot, the probe suite, and the
3
- * PID jail that guarantees a run leaves nothing behind (04 §2 V7, §5.7).
4
- *
5
- * Server-side only (Bun + Hono); the static V0–V6 compiler in `cursedbelt/verify`
6
- * has no runtime dependencies and runs anywhere.
7
- */
8
- export {
9
- type CliOptions,
10
- type CliResult,
11
- type CorpusFailure,
12
- parseArgs,
13
- runCli,
14
- runCorpus,
15
- writeArtifacts,
16
- } from './cli';
17
- export { type HostProbeOptions, probeHostCapabilities } from './hostCapabilities';
18
- export {
19
- createFakeSpawn,
20
- createVerifyContext,
21
- createVerifyGuard,
22
- createVerifyExec,
23
- createVerifyJobBroker,
24
- createVerifyCognitiveDriver,
25
- createVerifyStorage,
26
- createVerifyTelemetry,
27
- VERIFY_COMMANDS,
28
- type VerifyContext,
29
- type VerifyContextOptions,
30
- type VerifyGuard,
31
- } from './verifyContext';
32
- export {
33
- createVerifyAssetService,
34
- createVerifyDevService,
35
- createVerifyGuardService,
36
- createVerifyKnowledgeService,
37
- createVerifySystemService,
38
- PRIVATE_ITEM_IDS,
39
- PUBLIC_ITEM_IDS,
40
- } from './verifyServices';
41
- export {
42
- CORE_PROBES,
43
- crossTabLockProbe,
44
- deepLinkTenantProbe,
45
- eventLoopGuardProbe,
46
- execJailProbe,
47
- injectionGuardProbe,
48
- instanceIsolationProbe,
49
- integrityTamperProbe,
50
- lastGoodProbe,
51
- layoutProbe,
52
- lifecycleProbe,
53
- type Probe,
54
- type ProbeContext,
55
- privateModeProbe,
56
- rbacProbe,
57
- reconnectProbe,
58
- routeSurfaceProbe,
59
- securityHeaderProbe,
60
- wireSmokeProbe,
61
- } from './probes';
62
- export { isPortBound, ProcessJail, runJailed, type SweepReport, type TrackedChild } from './processJail';
63
- export { type ProbeRunResult, type RunProbesOptions, runVerifyProbes, VERIFY_TIMEOUT_MS } from './runner';
64
- export { createVerifyServer, type Role, type VerifyClaims, type VerifyServer, type VerifyServerOptions } from './verifyServer';