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.
- package/dist/client/index.js +1 -1
- package/dist/core/category/index.d.ts.map +1 -1
- package/dist/core/category/index.js +2 -1
- package/dist/core/category/index.js.map +1 -1
- package/dist/core/category/types.js +1 -1
- package/dist/core/category/types.js.map +1 -1
- package/dist/core/file-tree/fileTreeModel.d.ts +49 -0
- package/dist/core/file-tree/fileTreeModel.d.ts.map +1 -1
- package/dist/core/file-tree/fileTreeModel.js +84 -0
- package/dist/core/file-tree/fileTreeModel.js.map +1 -1
- package/dist/core/layout/index.js +1 -1
- package/dist/core/layout/index.js.map +1 -1
- package/dist/core/media/index.js +1 -1
- package/dist/core/media/index.js.map +1 -1
- package/dist/core/media/types.js +1 -1
- package/dist/core/media/types.js.map +1 -1
- package/dist/core/media/uploadLimits.js +1 -1
- package/dist/core/media/uploadLimits.js.map +1 -1
- package/dist/core/sharing/model.d.ts +1 -1
- package/dist/ctgr/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react/activity-bar/ActivityBar.d.ts +17 -0
- package/dist/react/activity-bar/ActivityBar.d.ts.map +1 -1
- package/dist/react/activity-bar/ActivityBar.js.map +1 -1
- package/dist/react/analytics/index.d.ts +1 -1
- package/dist/react/analytics/index.js +1 -1
- package/dist/react/chat/MessageComposer.d.ts.map +1 -1
- package/dist/react/chat/MessageComposer.js +5 -4
- package/dist/react/chat/MessageComposer.js.map +1 -1
- package/dist/react/components/Button.d.ts.map +1 -1
- package/dist/react/components/Button.js +3 -2
- package/dist/react/components/Button.js.map +1 -1
- package/dist/react/components/Checkbox.d.ts +19 -3
- package/dist/react/components/Checkbox.d.ts.map +1 -1
- package/dist/react/components/Checkbox.js +29 -12
- package/dist/react/components/Checkbox.js.map +1 -1
- package/dist/react/components/CodeArea.d.ts.map +1 -1
- package/dist/react/components/CodeArea.js +2 -1
- package/dist/react/components/CodeArea.js.map +1 -1
- package/dist/react/components/Collapsible.d.ts.map +1 -1
- package/dist/react/components/Collapsible.js +2 -1
- package/dist/react/components/Collapsible.js.map +1 -1
- package/dist/react/components/ComboboxField.d.ts.map +1 -1
- package/dist/react/components/ComboboxField.js +3 -2
- package/dist/react/components/ComboboxField.js.map +1 -1
- package/dist/react/components/CopyButton.d.ts.map +1 -1
- package/dist/react/components/CopyButton.js +2 -1
- package/dist/react/components/CopyButton.js.map +1 -1
- package/dist/react/components/DataTable/ColumnChecklist.d.ts.map +1 -1
- package/dist/react/components/DataTable/ColumnChecklist.js +2 -1
- package/dist/react/components/DataTable/ColumnChecklist.js.map +1 -1
- package/dist/react/components/DataTable/Pagination.d.ts.map +1 -1
- package/dist/react/components/DataTable/Pagination.js +2 -1
- package/dist/react/components/DataTable/Pagination.js.map +1 -1
- package/dist/react/components/DataTable/SortHeader.d.ts.map +1 -1
- package/dist/react/components/DataTable/SortHeader.js +2 -1
- package/dist/react/components/DataTable/SortHeader.js.map +1 -1
- package/dist/react/components/DataTable/TableFilterBuilder.d.ts +61 -0
- package/dist/react/components/DataTable/TableFilterBuilder.d.ts.map +1 -0
- package/dist/react/components/DataTable/{FilterBuilder.js → TableFilterBuilder.js} +26 -3
- package/dist/react/components/DataTable/TableFilterBuilder.js.map +1 -0
- package/dist/react/components/DataTable/Toolbar.d.ts +1 -1
- package/dist/react/components/DataTable/Toolbar.js +3 -3
- package/dist/react/components/DataTable/Toolbar.js.map +1 -1
- package/dist/react/components/DataTable/cells/LinkCell.d.ts.map +1 -1
- package/dist/react/components/DataTable/cells/LinkCell.js +2 -1
- package/dist/react/components/DataTable/cells/LinkCell.js.map +1 -1
- package/dist/react/components/DataTable/index.d.ts +1 -1
- package/dist/react/components/DataTable/index.d.ts.map +1 -1
- package/dist/react/components/DataTable/index.js +4 -1
- package/dist/react/components/DataTable/index.js.map +1 -1
- package/dist/react/components/DragHandle.d.ts.map +1 -1
- package/dist/react/components/DragHandle.js +2 -1
- package/dist/react/components/DragHandle.js.map +1 -1
- package/dist/react/components/EmojiField.d.ts.map +1 -1
- package/dist/react/components/EmojiField.js +2 -1
- package/dist/react/components/EmojiField.js.map +1 -1
- package/dist/react/components/EventTimeline.d.ts +3 -2
- package/dist/react/components/EventTimeline.d.ts.map +1 -1
- package/dist/react/components/EventTimeline.js +3 -2
- package/dist/react/components/EventTimeline.js.map +1 -1
- package/dist/react/components/IconButton.d.ts +1 -1
- package/dist/react/components/IconButton.js +1 -1
- package/dist/react/components/InfoHint.d.ts.map +1 -1
- package/dist/react/components/InfoHint.js +5 -4
- package/dist/react/components/InfoHint.js.map +1 -1
- package/dist/react/components/InheritBadge.js +1 -1
- package/dist/react/components/InheritBadge.js.map +1 -1
- package/dist/react/components/InlineEditableText.d.ts.map +1 -1
- package/dist/react/components/InlineEditableText.js +2 -1
- package/dist/react/components/InlineEditableText.js.map +1 -1
- package/dist/react/components/MeterList.d.ts.map +1 -1
- package/dist/react/components/MeterList.js +2 -1
- package/dist/react/components/MeterList.js.map +1 -1
- package/dist/react/components/PathText.d.ts +2 -2
- package/dist/react/components/PathText.d.ts.map +1 -1
- package/dist/react/components/PathText.js +2 -1
- package/dist/react/components/PathText.js.map +1 -1
- package/dist/react/components/RatingField.d.ts.map +1 -1
- package/dist/react/components/RatingField.js +2 -1
- package/dist/react/components/RatingField.js.map +1 -1
- package/dist/react/components/SecretInput.js +3 -2
- package/dist/react/components/SecretInput.js.map +1 -1
- package/dist/react/components/SegmentedControl.d.ts.map +1 -1
- package/dist/react/components/SegmentedControl.js +2 -1
- package/dist/react/components/SegmentedControl.js.map +1 -1
- package/dist/react/components/StarRating.d.ts.map +1 -1
- package/dist/react/components/StarRating.js +9 -5
- package/dist/react/components/StarRating.js.map +1 -1
- package/dist/react/components/StatStrip.d.ts.map +1 -1
- package/dist/react/components/StatStrip.js +2 -1
- package/dist/react/components/StatStrip.js.map +1 -1
- package/dist/react/components/StatTile.d.ts.map +1 -1
- package/dist/react/components/StatTile.js +3 -2
- package/dist/react/components/StatTile.js.map +1 -1
- package/dist/react/components/Tabs.d.ts.map +1 -1
- package/dist/react/components/Tabs.js +2 -1
- package/dist/react/components/Tabs.js.map +1 -1
- package/dist/react/components/TruncatedText.d.ts +2 -1
- package/dist/react/components/TruncatedText.d.ts.map +1 -1
- package/dist/react/components/TruncatedText.js +2 -1
- package/dist/react/components/TruncatedText.js.map +1 -1
- package/dist/react/components/calendar/MonthGrid.d.ts.map +1 -1
- package/dist/react/components/calendar/MonthGrid.js +2 -1
- package/dist/react/components/calendar/MonthGrid.js.map +1 -1
- package/dist/react/components/calendar/WeekView.d.ts.map +1 -1
- package/dist/react/components/calendar/WeekView.js +2 -1
- package/dist/react/components/calendar/WeekView.js.map +1 -1
- package/dist/react/components/revealOnHover.d.ts.map +1 -1
- package/dist/react/components/revealOnHover.js +2 -1
- package/dist/react/components/revealOnHover.js.map +1 -1
- package/dist/react/file-tree/FileTree.d.ts +50 -1
- package/dist/react/file-tree/FileTree.d.ts.map +1 -1
- package/dist/react/file-tree/FileTree.js +234 -6
- package/dist/react/file-tree/FileTree.js.map +1 -1
- package/dist/react/file-tree/fileTree.css +52 -0
- package/dist/react/filter-rail/FilterRail.d.ts.map +1 -1
- package/dist/react/filter-rail/FilterRail.js +5 -4
- package/dist/react/filter-rail/FilterRail.js.map +1 -1
- package/dist/react/folder-tree/FolderTreeRail.d.ts.map +1 -1
- package/dist/react/folder-tree/FolderTreeRail.js +2 -1
- package/dist/react/folder-tree/FolderTreeRail.js.map +1 -1
- package/dist/react/index.d.ts +5 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/layoutEngine/index.js +1 -1
- package/dist/react/layoutEngine/index.js.map +1 -1
- package/dist/react/lib/field.d.ts.map +1 -1
- package/dist/react/lib/field.js +3 -2
- package/dist/react/lib/field.js.map +1 -1
- package/dist/react/lib/floatingStyles.d.ts.map +1 -1
- package/dist/react/lib/floatingStyles.js +2 -1
- package/dist/react/lib/floatingStyles.js.map +1 -1
- package/dist/react/lib/tapTarget.d.ts +96 -0
- package/dist/react/lib/tapTarget.d.ts.map +1 -0
- package/dist/react/lib/tapTarget.js +96 -0
- package/dist/react/lib/tapTarget.js.map +1 -0
- package/dist/react/media/VideoTrimmer.d.ts +1 -1
- package/dist/react/media/VideoTrimmer.js +1 -1
- package/dist/react/media/denseGallery.css +3 -3
- package/dist/react/media/ffmpegWasm.js +2 -2
- package/dist/react/media/ffmpegWasm.js.map +1 -1
- package/dist/react/media/videoPlayer.css +42 -0
- package/dist/react/namespace/NamespaceTargetCapsule.d.ts +2 -2
- package/dist/react/namespace/NamespaceTargetCapsule.d.ts.map +1 -1
- package/dist/react/nav/BreadcrumbTrail.d.ts.map +1 -1
- package/dist/react/nav/BreadcrumbTrail.js +4 -3
- package/dist/react/nav/BreadcrumbTrail.js.map +1 -1
- package/dist/react/nav/HubTileGrid.d.ts.map +1 -1
- package/dist/react/nav/HubTileGrid.js +2 -1
- package/dist/react/nav/HubTileGrid.js.map +1 -1
- package/dist/react/nav/SideNav.d.ts.map +1 -1
- package/dist/react/nav/SideNav.js +4 -3
- package/dist/react/nav/SideNav.js.map +1 -1
- package/dist/react/nav/SideNavCustomize.d.ts.map +1 -1
- package/dist/react/nav/SideNavCustomize.js +2 -1
- package/dist/react/nav/SideNavCustomize.js.map +1 -1
- package/dist/react/palette/CommandPalette.d.ts.map +1 -1
- package/dist/react/palette/CommandPalette.js +3 -2
- package/dist/react/palette/CommandPalette.js.map +1 -1
- package/dist/server/drivers/pooledControlStores.pg.test.js +1 -0
- package/dist/server/drivers/pooledControlStores.pg.test.js.map +1 -1
- package/dist/server/drivers/pooledIdentityStore.pg.test.js +1 -0
- package/dist/server/drivers/pooledIdentityStore.pg.test.js.map +1 -1
- package/dist/server/drivers/retentionPolicy.pg.test.js +1 -0
- package/dist/server/drivers/retentionPolicy.pg.test.js.map +1 -1
- package/dist/server/guard/argon2Binding.d.ts +1 -1
- package/dist/server/guard/argon2Binding.js +1 -1
- package/dist/server/incidents/store.d.ts +3 -3
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/master-lock/masterLock.d.ts +1 -1
- package/dist/server/media-bun/index.js +1 -1
- package/dist/server/media-bun/index.js.map +1 -1
- package/dist/server/paths/appDataHome.d.ts +20 -0
- package/dist/server/paths/appDataHome.d.ts.map +1 -0
- package/dist/server/paths/appDataHome.js +69 -0
- package/dist/server/paths/appDataHome.js.map +1 -0
- package/dist/server/retention/archive.d.ts +3 -4
- package/dist/server/retention/archive.d.ts.map +1 -1
- package/dist/server/retention/archive.js +20 -15
- package/dist/server/retention/archive.js.map +1 -1
- package/dist/server/retention/index.d.ts +1 -1
- package/dist/server/retention/index.js +1 -1
- package/dist/server/retention/policy.d.ts +2 -2
- package/dist/server/retention/policy.d.ts.map +1 -1
- package/dist/server/retention/policy.js +1 -1
- package/dist/server/retention/store.d.ts.map +1 -1
- package/dist/server/retention/store.js +27 -20
- package/dist/server/retention/store.js.map +1 -1
- package/dist/server/runtime/localHost.d.ts +10 -5
- package/dist/server/runtime/localHost.d.ts.map +1 -1
- package/dist/server/runtime/localHost.js +12 -8
- package/dist/server/runtime/localHost.js.map +1 -1
- package/dist/server/runtime/meterRollup.pg.test.js +1 -0
- package/dist/server/runtime/meterRollup.pg.test.js.map +1 -1
- package/dist/server/runtime/recipe.d.ts +4 -4
- package/dist/server/runtime/retentionJob.pg.test.js +1 -0
- package/dist/server/runtime/retentionJob.pg.test.js.map +1 -1
- package/dist/server/search/pgSearchProvider.pg.test.js +1 -0
- package/dist/server/search/pgSearchProvider.pg.test.js.map +1 -1
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.js +1 -1
- package/dist/styles-static.css +413 -0
- package/dist/styles-utilities.css +5074 -0
- package/dist/styles.css +49 -0
- package/package.json +30 -168
- package/scripts/generateStaticStyles.ts +122 -0
- package/scripts/generateUtilityStyles.ts +215 -0
- package/scripts/publicSurface.ts +455 -0
- package/scripts/testTmpRoot.ts +34 -5
- package/src/client/index.ts +1 -1
- package/src/core/category/index.ts +2 -1
- package/src/core/category/types.ts +1 -1
- package/src/core/file-tree/fileTreeModel.spec.ts +134 -0
- package/src/core/file-tree/fileTreeModel.ts +104 -0
- package/src/core/layout/index.ts +1 -1
- package/src/core/media/index.ts +1 -1
- package/src/core/media/types.ts +1 -1
- package/src/core/media/uploadLimits.ts +1 -1
- package/src/core/sharing/model.ts +1 -1
- package/src/ctgr/index.ts +1 -1
- package/src/declaredDepsAreImported.spec.ts +87 -0
- package/src/demoFixture.spec.ts +133 -0
- package/src/index.ts +1 -1
- package/src/lockfileIsTracked.spec.ts +50 -0
- package/src/namedSubpathsResolve.spec.ts +119 -0
- package/src/publicSurface.spec.ts +72 -0
- package/src/react/activity-bar/ActivityBar.tsx +17 -0
- package/src/react/analytics/index.ts +1 -1
- package/src/react/chat/MessageComposer.tsx +5 -4
- package/src/react/components/Button.tsx +3 -2
- package/src/react/components/Checkbox.spec.tsx +51 -0
- package/src/react/components/Checkbox.tsx +68 -26
- package/src/react/components/CodeArea.tsx +2 -1
- package/src/react/components/CodeChip.spec.tsx +2 -2
- package/src/react/components/Collapsible.tsx +2 -1
- package/src/react/components/ComboboxField.tsx +3 -2
- package/src/react/components/CopyButton.tsx +2 -1
- package/src/react/components/CopyableText.spec.tsx +1 -1
- package/src/react/components/DataTable/ColumnChecklist.tsx +2 -1
- package/src/react/components/DataTable/Pagination.tsx +2 -1
- package/src/react/components/DataTable/SortHeader.tsx +2 -1
- package/src/react/components/DataTable/{FilterBuilder.tsx → TableFilterBuilder.tsx} +33 -5
- package/src/react/components/DataTable/Toolbar.tsx +3 -3
- package/src/react/components/DataTable/cells/LinkCell.tsx +2 -1
- package/src/react/components/DataTable/index.ts +8 -1
- package/src/react/components/DragHandle.tsx +2 -1
- package/src/react/components/EmojiField.tsx +2 -1
- package/src/react/components/EventTimeline.tsx +3 -2
- package/src/react/components/FileLocation.spec.tsx +1 -1
- package/src/react/components/IconButton.tsx +1 -1
- package/src/react/components/InfoHint.tsx +5 -4
- package/src/react/components/InheritBadge.tsx +1 -1
- package/src/react/components/InlineEditableText.tsx +2 -1
- package/src/react/components/MeterList.tsx +2 -1
- package/src/react/components/PathText.tsx +4 -3
- package/src/react/components/RatingField.tsx +2 -1
- package/src/react/components/SecretInput.tsx +3 -3
- package/src/react/components/SegmentedControl.tsx +2 -2
- package/src/react/components/StarRating.spec.tsx +2 -2
- package/src/react/components/StarRating.tsx +9 -5
- package/src/react/components/StatStrip.tsx +2 -1
- package/src/react/components/StatTile.tsx +3 -3
- package/src/react/components/Tabs.spec.tsx +3 -2
- package/src/react/components/Tabs.tsx +2 -1
- package/src/react/components/TruncatedText.tsx +2 -1
- package/src/react/components/calendar/MonthGrid.spec.tsx +2 -1
- package/src/react/components/calendar/MonthGrid.tsx +2 -1
- package/src/react/components/calendar/WeekView.tsx +2 -1
- package/src/react/components/revealOnHover.ts +3 -2
- package/src/react/file-tree/FileTree.spec.tsx +248 -0
- package/src/react/file-tree/FileTree.tsx +304 -4
- package/src/react/file-tree/fileTree.css +52 -0
- package/src/react/file-tree/fileTreeGeometry.fixture.json +151 -0
- package/src/react/file-tree/fileTreeGeometry.spec.ts +33 -52
- package/src/react/filter-rail/FilterRail.spec.tsx +2 -1
- package/src/react/filter-rail/FilterRail.tsx +5 -4
- package/src/react/folder-tree/FolderTreeRail.tsx +2 -1
- package/src/react/index.ts +13 -3
- package/src/react/layoutEngine/index.ts +1 -1
- package/src/react/layoutEngine/types.ts +1 -1
- package/src/react/lib/field.ts +4 -2
- package/src/react/lib/floatingStyles.spec.ts +2 -1
- package/src/react/lib/floatingStyles.ts +3 -1
- package/src/react/lib/tapTarget.ts +100 -0
- package/src/react/media/MaskPainter.tsx +2 -2
- package/src/react/media/VideoTrimmer.tsx +1 -1
- package/src/react/media/denseGallery.css +3 -3
- package/src/react/media/ffmpegWasm.ts +2 -2
- package/src/react/media/videoPlayer.css +42 -0
- package/src/react/namespace/NamespaceTargetCapsule.tsx +2 -2
- package/src/react/nav/BreadcrumbTrail.tsx +4 -3
- package/src/react/nav/HubTileGrid.tsx +2 -1
- package/src/react/nav/SideNav.tsx +4 -3
- package/src/react/nav/SideNavCustomize.tsx +2 -1
- package/src/react/palette/CommandPalette.tsx +3 -2
- package/src/server/ctgr.ts +1 -1
- package/src/server/drivers/pooledControlStores.pg.test.ts +1 -0
- package/src/server/drivers/pooledIdentityStore.pg.test.ts +1 -0
- package/src/server/drivers/retentionPolicy.pg.test.ts +1 -0
- package/src/server/guard/argon2Binding.ts +1 -1
- package/src/server/incidents/store.ts +3 -3
- package/src/server/index.ts +1 -1
- package/src/server/master-lock/masterLock.spec.ts +18 -2
- package/src/server/master-lock/masterLock.ts +1 -1
- package/src/server/media-bun/image.spec.ts +1 -0
- package/src/server/media-bun/index.ts +1 -1
- package/src/server/media-bun/video.spec.ts +1 -0
- package/src/server/paths/appDataHome.spec.ts +87 -0
- package/src/server/paths/appDataHome.ts +84 -0
- package/src/server/retention/archive.spec.ts +26 -4
- package/src/server/retention/archive.ts +20 -15
- package/src/server/retention/index.ts +1 -1
- package/src/server/retention/policy.ts +2 -2
- package/src/server/retention/store.spec.ts +38 -10
- package/src/server/retention/store.ts +26 -19
- package/src/server/runtime/localHost.spec.ts +22 -3
- package/src/server/runtime/localHost.ts +12 -9
- package/src/server/runtime/meterRollup.pg.test.ts +1 -0
- package/src/server/runtime/recipe.ts +4 -4
- package/src/server/runtime/retentionJob.pg.test.ts +1 -0
- package/src/server/search/pgSearchProvider.pg.test.ts +1 -0
- package/src/server/storage/binaryServerProcessing.integration.spec.ts +6 -2
- package/src/server/storage/chunked.integration.spec.ts +5 -2
- package/src/server/storage/fileUploadClient-chunked.integration.spec.ts +5 -2
- package/src/server/storage/files/adapter.photo.display.spec.ts +1 -0
- package/src/server/storage/imageThumbnail.spec.ts +1 -0
- package/src/server/storage/transcode.integration.spec.ts +5 -2
- package/src/server/storage/videoProcessor.posterOnly.spec.ts +1 -0
- package/src/shared/errors.ts +1 -1
- package/src/skippedTestsAreAnswered.spec.ts +215 -0
- package/src/styles-static.css +413 -0
- package/src/styles-utilities.css +5074 -0
- package/src/styles.css +49 -0
- package/src/stylesStaticMatches.spec.ts +134 -0
- package/src/stylesUtilitiesMatches.spec.ts +314 -0
- package/src/tapTargetStylesheet.spec.ts +150 -0
- package/src/testTmpRoot.spec.ts +102 -0
- package/dist/core/duplicates/index.d.ts +0 -116
- package/dist/core/duplicates/index.d.ts.map +0 -1
- package/dist/core/duplicates/index.js +0 -178
- package/dist/core/duplicates/index.js.map +0 -1
- package/dist/core/namespace/helpers.d.ts +0 -14
- package/dist/core/namespace/helpers.d.ts.map +0 -1
- package/dist/core/namespace/helpers.js +0 -29
- package/dist/core/namespace/helpers.js.map +0 -1
- package/dist/core/namespace/index.d.ts +0 -4
- package/dist/core/namespace/index.d.ts.map +0 -1
- package/dist/core/namespace/index.js +0 -6
- package/dist/core/namespace/index.js.map +0 -1
- package/dist/core/namespace/memoryStore.d.ts +0 -19
- package/dist/core/namespace/memoryStore.d.ts.map +0 -1
- package/dist/core/namespace/memoryStore.js +0 -70
- package/dist/core/namespace/memoryStore.js.map +0 -1
- package/dist/core/namespace/types.d.ts +0 -44
- package/dist/core/namespace/types.d.ts.map +0 -1
- package/dist/core/namespace/types.js +0 -8
- package/dist/core/namespace/types.js.map +0 -1
- package/dist/game/core/DisposeRegistry.d.ts +0 -42
- package/dist/game/core/DisposeRegistry.d.ts.map +0 -1
- package/dist/game/core/DisposeRegistry.js +0 -67
- package/dist/game/core/DisposeRegistry.js.map +0 -1
- package/dist/game/core/drawBudget.d.ts +0 -26
- package/dist/game/core/drawBudget.d.ts.map +0 -1
- package/dist/game/core/drawBudget.js +0 -55
- package/dist/game/core/drawBudget.js.map +0 -1
- package/dist/game/core/fixedTimestep.d.ts +0 -38
- package/dist/game/core/fixedTimestep.d.ts.map +0 -1
- package/dist/game/core/fixedTimestep.js +0 -47
- package/dist/game/core/fixedTimestep.js.map +0 -1
- package/dist/game/core/index.d.ts +0 -9
- package/dist/game/core/index.d.ts.map +0 -1
- package/dist/game/core/index.js +0 -8
- package/dist/game/core/index.js.map +0 -1
- package/dist/game/core/inputCollector.d.ts +0 -82
- package/dist/game/core/inputCollector.d.ts.map +0 -1
- package/dist/game/core/inputCollector.js +0 -176
- package/dist/game/core/inputCollector.js.map +0 -1
- package/dist/game/core/resizeCanvas.d.ts +0 -19
- package/dist/game/core/resizeCanvas.d.ts.map +0 -1
- package/dist/game/core/resizeCanvas.js +0 -29
- package/dist/game/core/resizeCanvas.js.map +0 -1
- package/dist/game/react/index.d.ts +0 -3
- package/dist/game/react/index.d.ts.map +0 -1
- package/dist/game/react/index.js +0 -5
- package/dist/game/react/index.js.map +0 -1
- package/dist/game/react/useGameEngine.d.ts +0 -64
- package/dist/game/react/useGameEngine.d.ts.map +0 -1
- package/dist/game/react/useGameEngine.js +0 -78
- package/dist/game/react/useGameEngine.js.map +0 -1
- package/dist/react/canvas/CanvasNavHUD.d.ts +0 -64
- package/dist/react/canvas/CanvasNavHUD.d.ts.map +0 -1
- package/dist/react/canvas/CanvasNavHUD.js +0 -58
- package/dist/react/canvas/CanvasNavHUD.js.map +0 -1
- package/dist/react/canvas/fitLabel.d.ts +0 -53
- package/dist/react/canvas/fitLabel.d.ts.map +0 -1
- package/dist/react/canvas/fitLabel.js +0 -104
- package/dist/react/canvas/fitLabel.js.map +0 -1
- package/dist/react/canvas/index.d.ts +0 -4
- package/dist/react/canvas/index.d.ts.map +0 -1
- package/dist/react/canvas/index.js +0 -4
- package/dist/react/canvas/index.js.map +0 -1
- package/dist/react/canvas/lod.d.ts +0 -40
- package/dist/react/canvas/lod.d.ts.map +0 -1
- package/dist/react/canvas/lod.js +0 -37
- package/dist/react/canvas/lod.js.map +0 -1
- package/dist/react/components/DataTable/FilterBuilder.d.ts +0 -38
- package/dist/react/components/DataTable/FilterBuilder.d.ts.map +0 -1
- package/dist/react/components/DataTable/FilterBuilder.js.map +0 -1
- package/dist/react/seo/HeadProvider.d.ts +0 -14
- package/dist/react/seo/HeadProvider.d.ts.map +0 -1
- package/dist/react/seo/HeadProvider.js +0 -44
- package/dist/react/seo/HeadProvider.js.map +0 -1
- package/dist/react/seo/applyHeadToDocument.d.ts +0 -3
- package/dist/react/seo/applyHeadToDocument.d.ts.map +0 -1
- package/dist/react/seo/applyHeadToDocument.js +0 -66
- package/dist/react/seo/applyHeadToDocument.js.map +0 -1
- package/dist/react/seo/index.d.ts +0 -3
- package/dist/react/seo/index.d.ts.map +0 -1
- package/dist/react/seo/index.js +0 -7
- package/dist/react/seo/index.js.map +0 -1
- package/dist/react/timeline/ClipView.d.ts +0 -29
- package/dist/react/timeline/ClipView.d.ts.map +0 -1
- package/dist/react/timeline/ClipView.js +0 -53
- package/dist/react/timeline/ClipView.js.map +0 -1
- package/dist/react/timeline/Playhead.d.ts +0 -16
- package/dist/react/timeline/Playhead.d.ts.map +0 -1
- package/dist/react/timeline/Playhead.js +0 -26
- package/dist/react/timeline/Playhead.js.map +0 -1
- package/dist/react/timeline/TimeRuler.d.ts +0 -21
- package/dist/react/timeline/TimeRuler.d.ts.map +0 -1
- package/dist/react/timeline/TimeRuler.js +0 -31
- package/dist/react/timeline/TimeRuler.js.map +0 -1
- package/dist/react/timeline/TimelineSurface.d.ts +0 -29
- package/dist/react/timeline/TimelineSurface.d.ts.map +0 -1
- package/dist/react/timeline/TimelineSurface.js +0 -56
- package/dist/react/timeline/TimelineSurface.js.map +0 -1
- package/dist/react/timeline/TrackLane.d.ts +0 -31
- package/dist/react/timeline/TrackLane.d.ts.map +0 -1
- package/dist/react/timeline/TrackLane.js +0 -32
- package/dist/react/timeline/TrackLane.js.map +0 -1
- package/dist/react/timeline/index.d.ts +0 -6
- package/dist/react/timeline/index.d.ts.map +0 -1
- package/dist/react/timeline/index.js +0 -12
- package/dist/react/timeline/index.js.map +0 -1
- package/dist/server/private-media/index.d.ts +0 -7
- package/dist/server/private-media/index.d.ts.map +0 -1
- package/dist/server/private-media/index.js +0 -13
- package/dist/server/private-media/index.js.map +0 -1
- package/dist/server/seo/index.d.ts +0 -3
- package/dist/server/seo/index.d.ts.map +0 -1
- package/dist/server/seo/index.js +0 -6
- package/dist/server/seo/index.js.map +0 -1
- package/dist/server/seo/mountSeoRoutes.d.ts +0 -9
- package/dist/server/seo/mountSeoRoutes.d.ts.map +0 -1
- package/dist/server/seo/mountSeoRoutes.js +0 -19
- package/dist/server/seo/mountSeoRoutes.js.map +0 -1
- package/dist/server/seo/serveHeadInjectedIndex.d.ts +0 -9
- package/dist/server/seo/serveHeadInjectedIndex.d.ts.map +0 -1
- package/dist/server/seo/serveHeadInjectedIndex.js +0 -20
- package/dist/server/seo/serveHeadInjectedIndex.js.map +0 -1
- package/dist/upload.d.ts +0 -148
- package/dist/upload.d.ts.map +0 -1
- package/dist/upload.js +0 -159
- package/dist/upload.js.map +0 -1
- package/dist/verify/runtime/index.d.ts +0 -16
- package/dist/verify/runtime/index.d.ts.map +0 -1
- package/dist/verify/runtime/index.js +0 -16
- package/dist/verify/runtime/index.js.map +0 -1
- package/scripts/demoCheck.ts +0 -42
- package/src/core/duplicates/index.spec.ts +0 -116
- package/src/core/duplicates/index.ts +0 -203
- package/src/core/namespace/helpers.ts +0 -31
- package/src/core/namespace/index.ts +0 -12
- package/src/core/namespace/memoryStore.ts +0 -77
- package/src/core/namespace/namespace.spec.ts +0 -117
- package/src/core/namespace/types.ts +0 -53
- package/src/game/core/DisposeRegistry.spec.ts +0 -53
- package/src/game/core/DisposeRegistry.ts +0 -70
- package/src/game/core/drawBudget.spec.ts +0 -51
- package/src/game/core/drawBudget.ts +0 -75
- package/src/game/core/fixedTimestep.spec.ts +0 -91
- package/src/game/core/fixedTimestep.ts +0 -79
- package/src/game/core/index.ts +0 -16
- package/src/game/core/inputCollector.spec.ts +0 -29
- package/src/game/core/inputCollector.ts +0 -245
- package/src/game/core/resizeCanvas.ts +0 -31
- package/src/game/react/index.ts +0 -10
- package/src/game/react/useGameEngine.ts +0 -125
- package/src/react/canvas/CanvasNavHUD.spec.tsx +0 -62
- package/src/react/canvas/CanvasNavHUD.tsx +0 -210
- package/src/react/canvas/fitLabel.spec.ts +0 -82
- package/src/react/canvas/fitLabel.ts +0 -150
- package/src/react/canvas/index.ts +0 -15
- package/src/react/canvas/lod.ts +0 -53
- package/src/react/seo/HeadProvider.tsx +0 -67
- package/src/react/seo/applyHeadToDocument.ts +0 -73
- package/src/react/seo/index.ts +0 -12
- package/src/react/seo/seo.spec.tsx +0 -101
- package/src/react/timeline/ClipView.tsx +0 -146
- package/src/react/timeline/Playhead.tsx +0 -63
- package/src/react/timeline/TimeRuler.tsx +0 -85
- package/src/react/timeline/TimelineSurface.tsx +0 -157
- package/src/react/timeline/TrackLane.tsx +0 -87
- package/src/react/timeline/index.ts +0 -12
- package/src/react/timeline/timeline.spec.tsx +0 -175
- package/src/server/private-media/index.ts +0 -45
- package/src/server/seo/index.ts +0 -8
- package/src/server/seo/mountSeoRoutes.ts +0 -37
- package/src/server/seo/seo.spec.ts +0 -128
- package/src/server/seo/serveHeadInjectedIndex.ts +0 -36
- package/src/upload.spec.ts +0 -300
- package/src/upload.ts +0 -288
- package/src/verify/runtime/index.ts +0 -64
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
clampZoom,
|
|
3
|
-
secondsToPx,
|
|
4
|
-
type TimelineTrack,
|
|
5
|
-
totalDuration,
|
|
6
|
-
ZOOM_RANGE,
|
|
7
|
-
zoomAnchoredScrollLeft,
|
|
8
|
-
} from 'cwip/timeline';
|
|
9
|
-
import { Minus, Plus } from 'lucide-react';
|
|
10
|
-
import { type ReactNode, useEffect, useRef } from 'react';
|
|
11
|
-
import { IconButton } from '../components/IconButton';
|
|
12
|
-
import { ScrollArea } from '../components/ScrollArea';
|
|
13
|
-
import { Slider } from '../components/Slider';
|
|
14
|
-
import { Tooltip } from '../components/Tooltip';
|
|
15
|
-
import { cn } from '../lib/cn';
|
|
16
|
-
import { Playhead } from './Playhead';
|
|
17
|
-
import { TimeRuler } from './TimeRuler';
|
|
18
|
-
|
|
19
|
-
export interface TimelineSurfaceProps {
|
|
20
|
-
tracks: TimelineTrack[];
|
|
21
|
-
zoomScale: number;
|
|
22
|
-
currentTime: number;
|
|
23
|
-
onScrub: (seconds: number) => void;
|
|
24
|
-
onScrubStart?: () => void;
|
|
25
|
-
onScrubEnd?: () => void;
|
|
26
|
-
/** Zoom changes arrive pre-clamped; scroll is re-anchored on the playhead. */
|
|
27
|
-
onZoomChange?: (zoomScale: number) => void;
|
|
28
|
-
/** Renders each track's lane (TrackLane + ClipViews) — the owner wires ops. */
|
|
29
|
-
renderTrack: (track: TimelineTrack, durationSeconds: number) => ReactNode;
|
|
30
|
-
/** Extra tail beyond the last clip so there's room to drop/extend (default 10s). */
|
|
31
|
-
tailSeconds?: number;
|
|
32
|
-
/** Auto-scroll so the playhead stays in view as `currentTime` advances (e.g. during
|
|
33
|
-
* playback) — once it nears the viewport edge, the view pages forward to keep it
|
|
34
|
-
* visible, rather than scrolling every frame. */
|
|
35
|
-
followPlayhead?: boolean;
|
|
36
|
-
className?: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* The composed timeline scroller: ruler + track lanes + playhead in one
|
|
41
|
-
* horizontally-scrolling keyboard-inset-safe surface (ScrollArea — no raw
|
|
42
|
-
* overflow), with zoom controls that keep the playhead visually anchored.
|
|
43
|
-
* Fully controlled; owns NO timeline state.
|
|
44
|
-
*/
|
|
45
|
-
export function TimelineSurface({
|
|
46
|
-
tracks,
|
|
47
|
-
zoomScale,
|
|
48
|
-
currentTime,
|
|
49
|
-
onScrub,
|
|
50
|
-
onScrubStart,
|
|
51
|
-
onScrubEnd,
|
|
52
|
-
onZoomChange,
|
|
53
|
-
renderTrack,
|
|
54
|
-
tailSeconds = 10,
|
|
55
|
-
followPlayhead = false,
|
|
56
|
-
className,
|
|
57
|
-
}: TimelineSurfaceProps) {
|
|
58
|
-
const scrollRef = useRef<HTMLDivElement | null>(null);
|
|
59
|
-
const durationSeconds = totalDuration(tracks) + tailSeconds;
|
|
60
|
-
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
if (!followPlayhead) return;
|
|
63
|
-
const el = scrollRef.current;
|
|
64
|
-
if (!el) return;
|
|
65
|
-
const playheadPx = secondsToPx(currentTime, zoomScale);
|
|
66
|
-
const viewportX = playheadPx - el.scrollLeft;
|
|
67
|
-
// Only page the view forward/back once the playhead nears an edge — scrolling every
|
|
68
|
-
// frame during playback would fight the user's ability to glance elsewhere.
|
|
69
|
-
const margin = el.clientWidth * 0.1;
|
|
70
|
-
if (viewportX < margin || viewportX > el.clientWidth - margin) {
|
|
71
|
-
el.scrollLeft = Math.max(0, playheadPx - el.clientWidth * 0.2);
|
|
72
|
-
}
|
|
73
|
-
}, [followPlayhead, currentTime, zoomScale]);
|
|
74
|
-
|
|
75
|
-
const changeZoom = (next: number) => {
|
|
76
|
-
if (!onZoomChange) return;
|
|
77
|
-
const clamped = clampZoom(next);
|
|
78
|
-
const el = scrollRef.current;
|
|
79
|
-
if (el) {
|
|
80
|
-
const anchorViewportPx = secondsToPx(currentTime, zoomScale) - el.scrollLeft;
|
|
81
|
-
// after the re-render at the new zoom, restore the playhead's viewport x
|
|
82
|
-
requestAnimationFrame(() => {
|
|
83
|
-
el.scrollLeft = zoomAnchoredScrollLeft(currentTime, anchorViewportPx, clamped);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
onZoomChange(clamped);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<div className={cn('flex flex-col', className)}>
|
|
91
|
-
{onZoomChange && (
|
|
92
|
-
<div className='flex items-center justify-end gap-2 border-b border-border px-2 py-1'>
|
|
93
|
-
<Tooltip content='Zoom out'>
|
|
94
|
-
<IconButton
|
|
95
|
-
label='Zoom out'
|
|
96
|
-
onClick={() => changeZoom(zoomScale / 1.4)}
|
|
97
|
-
disabled={zoomScale <= ZOOM_RANGE.min}
|
|
98
|
-
>
|
|
99
|
-
<Minus aria-hidden className='size-4' />
|
|
100
|
-
</IconButton>
|
|
101
|
-
</Tooltip>
|
|
102
|
-
<Slider
|
|
103
|
-
value={zoomScale}
|
|
104
|
-
min={ZOOM_RANGE.min}
|
|
105
|
-
max={ZOOM_RANGE.max}
|
|
106
|
-
// A coarse step of 1 would swallow the whole low end (0.05–1) in a single
|
|
107
|
-
// increment, making the zoomed-out-enough-to-fit-a-long-clip range
|
|
108
|
-
// unreachable by dragging — 0.5 keeps that end usable too.
|
|
109
|
-
step={0.5}
|
|
110
|
-
aria-label='Timeline zoom'
|
|
111
|
-
className='w-24'
|
|
112
|
-
onChange={changeZoom}
|
|
113
|
-
/>
|
|
114
|
-
<span className='w-14 text-center text-caption tabular-nums text-muted-foreground'>
|
|
115
|
-
{Math.round(zoomScale)} px/s
|
|
116
|
-
</span>
|
|
117
|
-
<Tooltip content='Zoom in'>
|
|
118
|
-
<IconButton
|
|
119
|
-
label='Zoom in'
|
|
120
|
-
onClick={() => changeZoom(zoomScale * 1.4)}
|
|
121
|
-
disabled={zoomScale >= ZOOM_RANGE.max}
|
|
122
|
-
>
|
|
123
|
-
<Plus aria-hidden className='size-4' />
|
|
124
|
-
</IconButton>
|
|
125
|
-
</Tooltip>
|
|
126
|
-
</div>
|
|
127
|
-
)}
|
|
128
|
-
<ScrollArea axis='x' space='none' scrollRef={scrollRef} className='grow'>
|
|
129
|
-
<div className='relative w-max min-w-full'>
|
|
130
|
-
{/* ruler is offset by the sticky lane-header width so times align */}
|
|
131
|
-
<div className='ml-28'>
|
|
132
|
-
<TimeRuler
|
|
133
|
-
durationSeconds={durationSeconds}
|
|
134
|
-
zoomScale={zoomScale}
|
|
135
|
-
currentTimeSeconds={currentTime}
|
|
136
|
-
onScrub={onScrub}
|
|
137
|
-
onScrubStart={onScrubStart}
|
|
138
|
-
onScrubEnd={onScrubEnd}
|
|
139
|
-
/>
|
|
140
|
-
</div>
|
|
141
|
-
{tracks.map((track) => renderTrack(track, durationSeconds))}
|
|
142
|
-
<div className='pointer-events-none absolute inset-y-0 left-28 right-0'>
|
|
143
|
-
<div className='relative h-full'>
|
|
144
|
-
<Playhead
|
|
145
|
-
timeSeconds={currentTime}
|
|
146
|
-
zoomScale={zoomScale}
|
|
147
|
-
onScrub={onScrub}
|
|
148
|
-
onScrubStart={onScrubStart}
|
|
149
|
-
onScrubEnd={onScrubEnd}
|
|
150
|
-
/>
|
|
151
|
-
</div>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
</ScrollArea>
|
|
155
|
-
</div>
|
|
156
|
-
);
|
|
157
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { pxToSeconds, secondsToPx, type TimelineTrack } from 'cwip/timeline';
|
|
2
|
-
import { AudioLines, Film } from 'lucide-react';
|
|
3
|
-
import type { DragEvent, ReactNode } from 'react';
|
|
4
|
-
import { useRef } from 'react';
|
|
5
|
-
import { cn } from '../lib/cn';
|
|
6
|
-
|
|
7
|
-
export const TRACK_LANE_HEIGHT_PX = 108;
|
|
8
|
-
|
|
9
|
-
export interface TrackLaneProps {
|
|
10
|
-
track: TimelineTrack;
|
|
11
|
-
zoomScale: number;
|
|
12
|
-
/** Lane runway width (seconds) — the surface passes one shared duration. */
|
|
13
|
-
durationSeconds: number;
|
|
14
|
-
/** Rendered `ClipView`s (the owner maps clips so it controls the wiring). */
|
|
15
|
-
children: ReactNode;
|
|
16
|
-
/** Lane height in px (default {@link TRACK_LANE_HEIGHT_PX}). Owners can shrink
|
|
17
|
-
* a rarely-used lane (e.g. an empty audio track) and grow it once it holds a
|
|
18
|
-
* clip, so unused lanes don't waste vertical space. */
|
|
19
|
-
laneHeightPx?: number;
|
|
20
|
-
/** Click on empty runway — typically seek + deselect. */
|
|
21
|
-
onRunwayClick?: (seconds: number) => void;
|
|
22
|
-
/** A `dataTransfer` drop on the runway (asset from a library/palette). */
|
|
23
|
-
onDropData?: (payload: { atSeconds: number; dataTransfer: DataTransfer }) => void;
|
|
24
|
-
className?: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* One track row: a sticky header (name + kind icon) and the clip runway. The
|
|
29
|
-
* runway is the `relative` positioning context `ClipView`s place themselves
|
|
30
|
-
* in, and the drop target for library assets (drop position is reported in
|
|
31
|
-
* SECONDS, scroll offset already accounted for via the runway's own rect).
|
|
32
|
-
*/
|
|
33
|
-
export function TrackLane({
|
|
34
|
-
track,
|
|
35
|
-
zoomScale,
|
|
36
|
-
durationSeconds,
|
|
37
|
-
children,
|
|
38
|
-
laneHeightPx = TRACK_LANE_HEIGHT_PX,
|
|
39
|
-
onRunwayClick,
|
|
40
|
-
onDropData,
|
|
41
|
-
className,
|
|
42
|
-
}: TrackLaneProps) {
|
|
43
|
-
const runwayRef = useRef<HTMLDivElement>(null);
|
|
44
|
-
|
|
45
|
-
const secondsAt = (clientX: number): number => {
|
|
46
|
-
const rect = runwayRef.current?.getBoundingClientRect();
|
|
47
|
-
if (!rect) return 0;
|
|
48
|
-
return Math.max(0, pxToSeconds(clientX - rect.left, zoomScale));
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const onDrop = (e: DragEvent) => {
|
|
52
|
-
if (!onDropData) return;
|
|
53
|
-
e.preventDefault();
|
|
54
|
-
onDropData({ atSeconds: secondsAt(e.clientX), dataTransfer: e.dataTransfer });
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<div
|
|
59
|
-
className={cn('flex border-b border-border/60 transition-[min-height]', className)}
|
|
60
|
-
style={{ minHeight: laneHeightPx }}
|
|
61
|
-
>
|
|
62
|
-
<div className='sticky left-0 z-30 flex w-28 shrink-0 items-center gap-1.5 border-r border-border bg-muted/60 px-2 backdrop-blur-sm'>
|
|
63
|
-
{track.type === 'video' ? (
|
|
64
|
-
<Film aria-hidden className='size-3.5 text-muted-foreground' />
|
|
65
|
-
) : (
|
|
66
|
-
<AudioLines aria-hidden className='size-3.5 text-muted-foreground' />
|
|
67
|
-
)}
|
|
68
|
-
<span className='truncate text-xs text-foreground'>{track.name}</span>
|
|
69
|
-
</div>
|
|
70
|
-
{/* biome-ignore lint/a11y/useKeyWithClickEvents: seek-on-click pointer convenience — the ruler is the accessible seek control */}
|
|
71
|
-
{/* biome-ignore lint/a11y/noStaticElementInteractions: same — decorative runway, real controls live on the clips/ruler */}
|
|
72
|
-
<div
|
|
73
|
-
ref={runwayRef}
|
|
74
|
-
className='relative'
|
|
75
|
-
style={{ width: secondsToPx(durationSeconds, zoomScale) }}
|
|
76
|
-
onClick={(e) => onRunwayClick?.(secondsAt(e.clientX))}
|
|
77
|
-
onDragOver={(e) => {
|
|
78
|
-
if (onDropData) e.preventDefault(); // required for `drop` to fire
|
|
79
|
-
}}
|
|
80
|
-
onDrop={onDrop}
|
|
81
|
-
data-track-id={track.id}
|
|
82
|
-
>
|
|
83
|
-
{children}
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
);
|
|
87
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// cursedbelt/react/timeline — the generic multi-track timeline editor surface.
|
|
2
|
-
// Controlled/presentational components over the cwip/timeline engine: they
|
|
3
|
-
// translate pixels to seconds and report INTENT (select/move/trim/scrub); the
|
|
4
|
-
// owner applies cwip ops (clamping, ripple, snapping) and passes state back
|
|
5
|
-
// down. Reusable for any lane-based editor (video NLE, audio arrangement,
|
|
6
|
-
// schedule lanes) — the cursedshell video-editor plugin is the reference user.
|
|
7
|
-
|
|
8
|
-
export { ClipView, type ClipViewProps, type TrimEdge } from './ClipView';
|
|
9
|
-
export { Playhead, type PlayheadProps } from './Playhead';
|
|
10
|
-
export { TimelineSurface, type TimelineSurfaceProps } from './TimelineSurface';
|
|
11
|
-
export { TimeRuler, type TimeRulerProps } from './TimeRuler';
|
|
12
|
-
export { TRACK_LANE_HEIGHT_PX, TrackLane, type TrackLaneProps } from './TrackLane';
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, test } from 'bun:test';
|
|
2
|
-
import { cleanup, createEvent, fireEvent, render } from '@testing-library/react';
|
|
3
|
-
import type { TimelineClip, TimelineTrack } from 'cwip/timeline';
|
|
4
|
-
import { ClipView } from './ClipView';
|
|
5
|
-
import { TimelineSurface } from './TimelineSurface';
|
|
6
|
-
import { TimeRuler } from './TimeRuler';
|
|
7
|
-
import { TrackLane } from './TrackLane';
|
|
8
|
-
|
|
9
|
-
afterEach(cleanup);
|
|
10
|
-
|
|
11
|
-
const clip = (partial: Partial<TimelineClip> & { id: string }): TimelineClip => ({
|
|
12
|
-
name: partial.id,
|
|
13
|
-
sourceAssetId: 'a1',
|
|
14
|
-
trackIn: 0,
|
|
15
|
-
trackOut: 10,
|
|
16
|
-
timelineStart: 0,
|
|
17
|
-
timelineEnd: 10,
|
|
18
|
-
speed: 1,
|
|
19
|
-
volume: 1,
|
|
20
|
-
...partial,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const track = (
|
|
24
|
-
id: string,
|
|
25
|
-
clips: TimelineClip[] = [],
|
|
26
|
-
type: 'video' | 'audio' = 'video',
|
|
27
|
-
): TimelineTrack => ({
|
|
28
|
-
id,
|
|
29
|
-
name: id,
|
|
30
|
-
type,
|
|
31
|
-
clips,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const noopClipHandlers = {
|
|
35
|
-
onSelect: () => {},
|
|
36
|
-
onMovePreview: () => {},
|
|
37
|
-
onMoveCommit: () => {},
|
|
38
|
-
onTrimPreview: () => {},
|
|
39
|
-
onTrimCommit: () => {},
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
describe('ClipView', () => {
|
|
43
|
-
test('positions by timeline seconds × zoom and shows name + source window', () => {
|
|
44
|
-
const c = clip({ id: 'intro', timelineStart: 2, timelineEnd: 6, trackIn: 1, trackOut: 5 });
|
|
45
|
-
const { getByRole, getByText } = render(
|
|
46
|
-
<ClipView clip={c} zoomScale={25} selected={false} {...noopClipHandlers} />,
|
|
47
|
-
);
|
|
48
|
-
const block = getByRole('button', { name: 'Clip intro' });
|
|
49
|
-
expect(block.style.left).toBe('50px');
|
|
50
|
-
expect(block.style.width).toBe('98px'); // 100px minus the 2px seam
|
|
51
|
-
expect(getByText('intro')).toBeDefined();
|
|
52
|
-
expect(getByText('0:01–0:05')).toBeDefined();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test('click selects (and stops at the clip, not the lane behind)', () => {
|
|
56
|
-
let selected = 0;
|
|
57
|
-
let laneClicks = 0;
|
|
58
|
-
const { getByRole } = render(
|
|
59
|
-
<TrackLane
|
|
60
|
-
track={track('v1')}
|
|
61
|
-
zoomScale={25}
|
|
62
|
-
durationSeconds={20}
|
|
63
|
-
onRunwayClick={() => {
|
|
64
|
-
laneClicks += 1;
|
|
65
|
-
}}
|
|
66
|
-
>
|
|
67
|
-
<ClipView
|
|
68
|
-
clip={clip({ id: 'c1' })}
|
|
69
|
-
zoomScale={25}
|
|
70
|
-
selected={false}
|
|
71
|
-
{...noopClipHandlers}
|
|
72
|
-
onSelect={() => {
|
|
73
|
-
selected += 1;
|
|
74
|
-
}}
|
|
75
|
-
/>
|
|
76
|
-
</TrackLane>,
|
|
77
|
-
);
|
|
78
|
-
fireEvent.click(getByRole('button', { name: 'Clip c1' }));
|
|
79
|
-
expect(selected).toBe(1);
|
|
80
|
-
expect(laneClicks).toBe(0);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test('shows a speed badge only when speed ≠ 1', () => {
|
|
84
|
-
const { queryByText, rerender } = render(
|
|
85
|
-
<ClipView clip={clip({ id: 'c1' })} zoomScale={25} selected={false} {...noopClipHandlers} />,
|
|
86
|
-
);
|
|
87
|
-
expect(queryByText('1x')).toBeNull();
|
|
88
|
-
rerender(
|
|
89
|
-
<ClipView
|
|
90
|
-
clip={clip({ id: 'c1', speed: 2, timelineEnd: 5 })}
|
|
91
|
-
zoomScale={25}
|
|
92
|
-
selected={false}
|
|
93
|
-
{...noopClipHandlers}
|
|
94
|
-
/>,
|
|
95
|
-
);
|
|
96
|
-
expect(queryByText('2x')).toBeDefined();
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('TimeRuler', () => {
|
|
101
|
-
test('thins tick labels as zoom drops', () => {
|
|
102
|
-
const dense = render(<TimeRuler durationSeconds={10} zoomScale={100} onScrub={() => {}} />);
|
|
103
|
-
// 100 px/s → 1s ticks: 0..10 = 11 labels
|
|
104
|
-
expect(dense.container.querySelectorAll('span').length).toBe(11);
|
|
105
|
-
dense.unmount();
|
|
106
|
-
const sparse = render(<TimeRuler durationSeconds={10} zoomScale={10} onScrub={() => {}} />);
|
|
107
|
-
// 10 px/s → 10s ticks: 0, 10
|
|
108
|
-
expect(sparse.container.querySelectorAll('span').length).toBe(2);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('TrackLane', () => {
|
|
113
|
-
test('reports drops in seconds using the runway rect and zoom', () => {
|
|
114
|
-
let dropped: { atSeconds: number } | null = null;
|
|
115
|
-
const { container } = render(
|
|
116
|
-
<TrackLane
|
|
117
|
-
track={track('v1')}
|
|
118
|
-
zoomScale={25}
|
|
119
|
-
durationSeconds={20}
|
|
120
|
-
onDropData={(payload) => {
|
|
121
|
-
dropped = payload;
|
|
122
|
-
}}
|
|
123
|
-
>
|
|
124
|
-
<div />
|
|
125
|
-
</TrackLane>,
|
|
126
|
-
);
|
|
127
|
-
const runway = container.querySelector('[data-track-id="v1"]') as HTMLElement;
|
|
128
|
-
runway.getBoundingClientRect = () =>
|
|
129
|
-
({
|
|
130
|
-
left: 100,
|
|
131
|
-
top: 0,
|
|
132
|
-
width: 500,
|
|
133
|
-
height: 64,
|
|
134
|
-
right: 600,
|
|
135
|
-
bottom: 64,
|
|
136
|
-
x: 100,
|
|
137
|
-
y: 0,
|
|
138
|
-
}) as DOMRect;
|
|
139
|
-
// happy-dom's DragEvent constructor ignores mouse-init fields — set them directly
|
|
140
|
-
const drop = createEvent.drop(runway);
|
|
141
|
-
Object.defineProperty(drop, 'clientX', { value: 200 });
|
|
142
|
-
Object.defineProperty(drop, 'dataTransfer', { value: { getData: () => '' } });
|
|
143
|
-
fireEvent(runway, drop);
|
|
144
|
-
expect(dropped).not.toBeNull();
|
|
145
|
-
expect((dropped as unknown as { atSeconds: number }).atSeconds).toBe(4); // (200-100)/25
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
describe('TimelineSurface', () => {
|
|
150
|
-
test('renders ruler, lanes, playhead, and zoom controls together', () => {
|
|
151
|
-
const tracks = [track('v1', [clip({ id: 'c1' })]), track('a1', [], 'audio')];
|
|
152
|
-
const { getByRole, getAllByRole, getByText } = render(
|
|
153
|
-
<TimelineSurface
|
|
154
|
-
tracks={tracks}
|
|
155
|
-
zoomScale={25}
|
|
156
|
-
currentTime={3}
|
|
157
|
-
onScrub={() => {}}
|
|
158
|
-
onZoomChange={() => {}}
|
|
159
|
-
renderTrack={(t, duration) => (
|
|
160
|
-
<TrackLane key={t.id} track={t} zoomScale={25} durationSeconds={duration}>
|
|
161
|
-
{t.clips.map((c) => (
|
|
162
|
-
<ClipView key={c.id} clip={c} zoomScale={25} selected={false} {...noopClipHandlers} />
|
|
163
|
-
))}
|
|
164
|
-
</TrackLane>
|
|
165
|
-
)}
|
|
166
|
-
/>,
|
|
167
|
-
);
|
|
168
|
-
expect(getByRole('slider', { name: 'Timeline position' })).toBeDefined();
|
|
169
|
-
expect(getByRole('slider', { name: 'Playhead' })).toBeDefined();
|
|
170
|
-
expect(getByRole('button', { name: 'Zoom in' })).toBeDefined();
|
|
171
|
-
expect(getByText('v1')).toBeDefined();
|
|
172
|
-
expect(getByText('a1')).toBeDefined();
|
|
173
|
-
expect(getAllByRole('button', { name: 'Clip c1' })).toHaveLength(1);
|
|
174
|
-
});
|
|
175
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// cursedbelt/server/private-media — encrypted private media: a multi-password, semi-deniable
|
|
2
|
-
// layer over server/storage. Bytes are AES-128-encrypted HLS (fast, edge-cacheable, client-
|
|
3
|
-
// decrypted); the per-item content key is wrapped under a set key that is either server-held
|
|
4
|
-
// (standard, recoverable) or password-derived (deniable, zero-knowledge). A clear index exposes
|
|
5
|
-
// only size + created-at so users can prune forgotten-password media; title/thumb/notes stay in
|
|
6
|
-
// an encrypted envelope revealed only by the right password. Builds on cwip secretBox (scrypt +
|
|
7
|
-
// AES-GCM) + server/auth (jose) + server/media (the encrypted-HLS pipeline).
|
|
8
|
-
|
|
9
|
-
export type { ContentKey, KeyMode } from './crypto';
|
|
10
|
-
export {
|
|
11
|
-
cryptBlobStream,
|
|
12
|
-
derivePasswordSetKey,
|
|
13
|
-
deriveServerSetKey,
|
|
14
|
-
generateContentKey,
|
|
15
|
-
generateUserSalt,
|
|
16
|
-
openMeta,
|
|
17
|
-
sealMeta,
|
|
18
|
-
unwrapContentKey,
|
|
19
|
-
wrapContentKey,
|
|
20
|
-
} from './crypto';
|
|
21
|
-
export {
|
|
22
|
-
createMemoryPrivateIndex,
|
|
23
|
-
type PrivateIndex,
|
|
24
|
-
type PrivateIndexRow,
|
|
25
|
-
type PrivateItem,
|
|
26
|
-
toPublic,
|
|
27
|
-
} from './index-store';
|
|
28
|
-
export {
|
|
29
|
-
type CorsResolver,
|
|
30
|
-
type MountPrivateOptions,
|
|
31
|
-
mountPrivateRoutes,
|
|
32
|
-
} from './mountPrivateRoutes';
|
|
33
|
-
export {
|
|
34
|
-
type PrivateBlobResult,
|
|
35
|
-
type PrivateProcessOptions,
|
|
36
|
-
type PrivateProcessResult,
|
|
37
|
-
processPrivateBlob,
|
|
38
|
-
processPrivateVideo,
|
|
39
|
-
} from './pipeline';
|
|
40
|
-
export {
|
|
41
|
-
createUnlockService,
|
|
42
|
-
type UnlockGrant,
|
|
43
|
-
type UnlockPasswordPolicy,
|
|
44
|
-
type UnlockService,
|
|
45
|
-
} from './unlock';
|
package/src/server/seo/index.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// cursedbelt/server/seo — Hono wiring for cwip's SEO core: sitemap.xml/robots.txt
|
|
2
|
-
// routes and a static-HTML head-injection handler. See seo-reusable-plan.md for the
|
|
3
|
-
// wider architecture (visibility model, delivery targets, cursedshell aggregation).
|
|
4
|
-
export { type MountSeoOptions, mountSeoRoutes } from './mountSeoRoutes';
|
|
5
|
-
export {
|
|
6
|
-
type ServeHeadInjectedIndexOptions,
|
|
7
|
-
serveHeadInjectedIndex,
|
|
8
|
-
} from './serveHeadInjectedIndex';
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { SeoPolicy } from 'cwip/seo';
|
|
2
|
-
import { buildRobots, buildSitemap } from 'cwip/seo';
|
|
3
|
-
import type { Hono } from 'hono';
|
|
4
|
-
|
|
5
|
-
export interface MountSeoOptions {
|
|
6
|
-
// Path the sitemap is served at (default '/sitemap.xml'); also what buildRobots
|
|
7
|
-
// points its `Sitemap:` line at.
|
|
8
|
-
sitemapPath?: string;
|
|
9
|
-
// Path robots.txt is served at (default '/robots.txt').
|
|
10
|
-
robotsPath?: string;
|
|
11
|
-
// Cache-Control header applied to both responses (default 'public, max-age=3600').
|
|
12
|
-
cacheControl?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Registers GET /sitemap.xml and GET /robots.txt from a SeoPolicy. These serve raw
|
|
16
|
-
// text bytes, so — per cursedbelt STANDARDS.md §5 — they are registered DIRECTLY
|
|
17
|
-
// with `app.get`, never through `buildRoutes`: routing them through the ctgr
|
|
18
|
-
// GET-tunnel would base64url-encode the response body instead of serving it as-is.
|
|
19
|
-
export const mountSeoRoutes = (
|
|
20
|
-
app: Hono,
|
|
21
|
-
policy: SeoPolicy,
|
|
22
|
-
options: MountSeoOptions = {},
|
|
23
|
-
): void => {
|
|
24
|
-
const sitemapPath = options.sitemapPath ?? '/sitemap.xml';
|
|
25
|
-
const robotsPath = options.robotsPath ?? '/robots.txt';
|
|
26
|
-
const cacheControl = options.cacheControl ?? 'public, max-age=3600';
|
|
27
|
-
|
|
28
|
-
app.get(sitemapPath, (c) => {
|
|
29
|
-
c.header('Cache-Control', cacheControl);
|
|
30
|
-
return c.body(buildSitemap(policy), 200, { 'Content-Type': 'application/xml' });
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
app.get(robotsPath, (c) => {
|
|
34
|
-
c.header('Cache-Control', cacheControl);
|
|
35
|
-
return c.body(buildRobots(policy, { sitemapPath }), 200, { 'Content-Type': 'text/plain' });
|
|
36
|
-
});
|
|
37
|
-
};
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test';
|
|
2
|
-
import type { SeoPolicy } from 'cwip/seo';
|
|
3
|
-
import { Hono } from 'hono';
|
|
4
|
-
import { mountSeoRoutes } from './mountSeoRoutes';
|
|
5
|
-
import { serveHeadInjectedIndex } from './serveHeadInjectedIndex';
|
|
6
|
-
|
|
7
|
-
const policy: SeoPolicy = {
|
|
8
|
-
siteUrl: 'https://example.com',
|
|
9
|
-
defaultVisibility: 'private',
|
|
10
|
-
disallow: ['/api'],
|
|
11
|
-
entries: [
|
|
12
|
-
{
|
|
13
|
-
path: '/',
|
|
14
|
-
visibility: 'public',
|
|
15
|
-
head: { title: 'Home', description: 'Welcome' },
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
path: '/articles/free-monads',
|
|
19
|
-
visibility: 'public',
|
|
20
|
-
head: {
|
|
21
|
-
title: 'Free monads',
|
|
22
|
-
description: 'An article about free monads',
|
|
23
|
-
openGraph: { type: 'article' },
|
|
24
|
-
},
|
|
25
|
-
lastmod: '2026-01-01',
|
|
26
|
-
},
|
|
27
|
-
{ path: '/notes', visibility: 'private' },
|
|
28
|
-
],
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
describe('mountSeoRoutes', () => {
|
|
32
|
-
test('serves sitemap.xml with public entries and the right content-type', async () => {
|
|
33
|
-
const app = new Hono();
|
|
34
|
-
mountSeoRoutes(app, policy);
|
|
35
|
-
const res = await app.request('/sitemap.xml');
|
|
36
|
-
expect(res.status).toBe(200);
|
|
37
|
-
expect(res.headers.get('Content-Type')).toContain('application/xml');
|
|
38
|
-
const body = await res.text();
|
|
39
|
-
expect(body).toContain('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');
|
|
40
|
-
expect(body).toContain('https://example.com/articles/free-monads');
|
|
41
|
-
expect(body).not.toContain('/notes');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('serves robots.txt disallowing private entries and explicit paths', async () => {
|
|
45
|
-
const app = new Hono();
|
|
46
|
-
mountSeoRoutes(app, policy);
|
|
47
|
-
const res = await app.request('/robots.txt');
|
|
48
|
-
expect(res.status).toBe(200);
|
|
49
|
-
expect(res.headers.get('Content-Type')).toContain('text/plain');
|
|
50
|
-
const body = await res.text();
|
|
51
|
-
expect(body).toContain('Disallow: /api');
|
|
52
|
-
expect(body).toContain('Disallow: /notes');
|
|
53
|
-
expect(body).toContain('Sitemap: https://example.com/sitemap.xml');
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('honors custom sitemapPath/robotsPath/cacheControl', async () => {
|
|
57
|
-
const app = new Hono();
|
|
58
|
-
mountSeoRoutes(app, policy, {
|
|
59
|
-
sitemapPath: '/custom-sitemap.xml',
|
|
60
|
-
robotsPath: '/custom-robots.txt',
|
|
61
|
-
cacheControl: 'no-cache',
|
|
62
|
-
});
|
|
63
|
-
const sitemap = await app.request('/custom-sitemap.xml');
|
|
64
|
-
const robots = await app.request('/custom-robots.txt');
|
|
65
|
-
expect(sitemap.status).toBe(200);
|
|
66
|
-
expect(sitemap.headers.get('Cache-Control')).toBe('no-cache');
|
|
67
|
-
expect(robots.status).toBe(200);
|
|
68
|
-
expect(await robots.text()).toContain('Sitemap: https://example.com/custom-sitemap.xml');
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const baseHtml = `<!doctype html>
|
|
73
|
-
<html>
|
|
74
|
-
<head>
|
|
75
|
-
<title>Base Title</title>
|
|
76
|
-
<meta name="description" content="Base description">
|
|
77
|
-
</head>
|
|
78
|
-
<body><div id="root"></div></body>
|
|
79
|
-
</html>
|
|
80
|
-
`;
|
|
81
|
-
|
|
82
|
-
describe('serveHeadInjectedIndex', () => {
|
|
83
|
-
test('injects the resolved head and strips the base title/description for a mapped path', async () => {
|
|
84
|
-
const app = new Hono();
|
|
85
|
-
app.get('*', (c) =>
|
|
86
|
-
serveHeadInjectedIndex({
|
|
87
|
-
html: baseHtml,
|
|
88
|
-
resolve: (path) =>
|
|
89
|
-
path === '/articles/free-monads'
|
|
90
|
-
? { title: 'Free monads', description: 'An article about free monads' }
|
|
91
|
-
: undefined,
|
|
92
|
-
})(c),
|
|
93
|
-
);
|
|
94
|
-
const res = await app.request('/articles/free-monads');
|
|
95
|
-
const body = await res.text();
|
|
96
|
-
expect(body).toContain('<title data-cwip-seo>Free monads</title>');
|
|
97
|
-
expect(body).toContain('An article about free monads');
|
|
98
|
-
expect(body).not.toContain('Base Title');
|
|
99
|
-
expect(body).not.toContain('Base description');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test('serves the base shell untouched for an unmapped path', async () => {
|
|
103
|
-
const app = new Hono();
|
|
104
|
-
app.get('*', (c) =>
|
|
105
|
-
serveHeadInjectedIndex({
|
|
106
|
-
html: baseHtml,
|
|
107
|
-
resolve: () => undefined,
|
|
108
|
-
})(c),
|
|
109
|
-
);
|
|
110
|
-
const res = await app.request('/some/authorized/path');
|
|
111
|
-
const body = await res.text();
|
|
112
|
-
expect(body).toContain('<title>Base Title</title>');
|
|
113
|
-
expect(body).toContain('Base description');
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test('accepts an async html loader', async () => {
|
|
117
|
-
const app = new Hono();
|
|
118
|
-
app.get('*', (c) =>
|
|
119
|
-
serveHeadInjectedIndex({
|
|
120
|
-
html: async () => baseHtml,
|
|
121
|
-
resolve: () => ({ title: 'Loaded' }),
|
|
122
|
-
})(c),
|
|
123
|
-
);
|
|
124
|
-
const res = await app.request('/');
|
|
125
|
-
const body = await res.text();
|
|
126
|
-
expect(body).toContain('Loaded');
|
|
127
|
-
});
|
|
128
|
-
});
|