@50arms/ui 0.0.0-stage → 35.1.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/LICENSE +21 -0
- package/README.md +193 -2
- package/dist/components/Accordion.js +68 -0
- package/dist/components/Accordion.js.map +1 -0
- package/dist/components/AgentWorkingSpinner.js +46 -0
- package/dist/components/AgentWorkingSpinner.js.map +1 -0
- package/dist/components/AppShell.js +228 -0
- package/dist/components/AppShell.js.map +1 -0
- package/dist/components/Attention.js +130 -0
- package/dist/components/Attention.js.map +1 -0
- package/dist/components/Avatar.js +99 -0
- package/dist/components/Avatar.js.map +1 -0
- package/dist/components/Badge.js +143 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Board.js +292 -0
- package/dist/components/Board.js.map +1 -0
- package/dist/components/Button.js +327 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Callout.js +106 -0
- package/dist/components/Callout.js.map +1 -0
- package/dist/components/Card.js +140 -0
- package/dist/components/Card.js.map +1 -0
- package/dist/components/Choice.js +361 -0
- package/dist/components/Choice.js.map +1 -0
- package/dist/components/CodeEditor.js +384 -0
- package/dist/components/CodeEditor.js.map +1 -0
- package/dist/components/ColorPicker.js +174 -0
- package/dist/components/ColorPicker.js.map +1 -0
- package/dist/components/Combobox.js +212 -0
- package/dist/components/Combobox.js.map +1 -0
- package/dist/components/CommandPalette.js +163 -0
- package/dist/components/CommandPalette.js.map +1 -0
- package/dist/components/ConcentricRing.js +60 -0
- package/dist/components/ConcentricRing.js.map +1 -0
- package/dist/components/ConnectionCard.js +98 -0
- package/dist/components/ConnectionCard.js.map +1 -0
- package/dist/components/ContextItemRow.js +49 -0
- package/dist/components/ContextItemRow.js.map +1 -0
- package/dist/components/CopyValue.js +57 -0
- package/dist/components/CopyValue.js.map +1 -0
- package/dist/components/CountBadge.js +26 -0
- package/dist/components/CountBadge.js.map +1 -0
- package/dist/components/DateCalendar.js +156 -0
- package/dist/components/DateCalendar.js.map +1 -0
- package/dist/components/DateField.js +166 -0
- package/dist/components/DateField.js.map +1 -0
- package/dist/components/DatePicker.js +56 -0
- package/dist/components/DatePicker.js.map +1 -0
- package/dist/components/DateTimeText.js +19 -0
- package/dist/components/DateTimeText.js.map +1 -0
- package/dist/components/DescriptionList.js +25 -0
- package/dist/components/DescriptionList.js.map +1 -0
- package/dist/components/Dialog.js +332 -0
- package/dist/components/Dialog.js.map +1 -0
- package/dist/components/DragDrop.js +395 -0
- package/dist/components/DragDrop.js.map +1 -0
- package/dist/components/Drawer.js +100 -0
- package/dist/components/Drawer.js.map +1 -0
- package/dist/components/EditGutter.js +110 -0
- package/dist/components/EditGutter.js.map +1 -0
- package/dist/components/EmojiPicker.js +174 -0
- package/dist/components/EmojiPicker.js.map +1 -0
- package/dist/components/ErrorBoundary.js +47 -0
- package/dist/components/ErrorBoundary.js.map +1 -0
- package/dist/components/Field.js +115 -0
- package/dist/components/Field.js.map +1 -0
- package/dist/components/FileUpload.js +128 -0
- package/dist/components/FileUpload.js.map +1 -0
- package/dist/components/FilterMenu.js +256 -0
- package/dist/components/FilterMenu.js.map +1 -0
- package/dist/components/GatesSection.js +79 -0
- package/dist/components/GatesSection.js.map +1 -0
- package/dist/components/Icon.js +50 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/IconButton.js +59 -0
- package/dist/components/IconButton.js.map +1 -0
- package/dist/components/IconStack.js +69 -0
- package/dist/components/IconStack.js.map +1 -0
- package/dist/components/ImageUploadField.js +146 -0
- package/dist/components/ImageUploadField.js.map +1 -0
- package/dist/components/InlineEdit.js +432 -0
- package/dist/components/InlineEdit.js.map +1 -0
- package/dist/components/InlineMarkdownEdit.js +184 -0
- package/dist/components/InlineMarkdownEdit.js.map +1 -0
- package/dist/components/Input.js +156 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/LegalDocument.js +155 -0
- package/dist/components/LegalDocument.js.map +1 -0
- package/dist/components/LineDiff.js +95 -0
- package/dist/components/LineDiff.js.map +1 -0
- package/dist/components/ListHeader.js +72 -0
- package/dist/components/ListHeader.js.map +1 -0
- package/dist/components/Loading.js +111 -0
- package/dist/components/Loading.js.map +1 -0
- package/dist/components/Markdown.js +28 -0
- package/dist/components/Markdown.js.map +1 -0
- package/dist/components/MarkdownEditor.js +467 -0
- package/dist/components/MarkdownEditor.js.map +1 -0
- package/dist/components/Menu.js +185 -0
- package/dist/components/Menu.js.map +1 -0
- package/dist/components/Navigation.js +87 -0
- package/dist/components/Navigation.js.map +1 -0
- package/dist/components/NumberInput.js +119 -0
- package/dist/components/NumberInput.js.map +1 -0
- package/dist/components/OTPInput.js +71 -0
- package/dist/components/OTPInput.js.map +1 -0
- package/dist/components/OrderedEntityManager.js +170 -0
- package/dist/components/OrderedEntityManager.js.map +1 -0
- package/dist/components/PagedWindowList.js +74 -0
- package/dist/components/PagedWindowList.js.map +1 -0
- package/dist/components/PaginationBar.js +95 -0
- package/dist/components/PaginationBar.js.map +1 -0
- package/dist/components/Panel.js +396 -0
- package/dist/components/Panel.js.map +1 -0
- package/dist/components/PasswordInput.js +32 -0
- package/dist/components/PasswordInput.js.map +1 -0
- package/dist/components/PasswordRequirements.js +25 -0
- package/dist/components/PasswordRequirements.js.map +1 -0
- package/dist/components/PatchDiff.js +96 -0
- package/dist/components/PatchDiff.js.map +1 -0
- package/dist/components/PendingVeil.js +18 -0
- package/dist/components/PendingVeil.js.map +1 -0
- package/dist/components/Popover.js +214 -0
- package/dist/components/Popover.js.map +1 -0
- package/dist/components/Progress.js +419 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/RatingScale.js +89 -0
- package/dist/components/RatingScale.js.map +1 -0
- package/dist/components/ReadMore.js +232 -0
- package/dist/components/ReadMore.js.map +1 -0
- package/dist/components/RecordCard.js +202 -0
- package/dist/components/RecordCard.js.map +1 -0
- package/dist/components/RelativeTime.js +29 -0
- package/dist/components/RelativeTime.js.map +1 -0
- package/dist/components/SandboxedFrame.js +135 -0
- package/dist/components/SandboxedFrame.js.map +1 -0
- package/dist/components/SearchInput.js +38 -0
- package/dist/components/SearchInput.js.map +1 -0
- package/dist/components/SecretField.js +228 -0
- package/dist/components/SecretField.js.map +1 -0
- package/dist/components/SectionNav.js +42 -0
- package/dist/components/SectionNav.js.map +1 -0
- package/dist/components/Select.js +172 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/SequenceDiagram.js +109 -0
- package/dist/components/SequenceDiagram.js.map +1 -0
- package/dist/components/SettingRow.js +124 -0
- package/dist/components/SettingRow.js.map +1 -0
- package/dist/components/SignOffRings.js +36 -0
- package/dist/components/SignOffRings.js.map +1 -0
- package/dist/components/Slider.js +353 -0
- package/dist/components/Slider.js.map +1 -0
- package/dist/components/SolutionChoice.js +89 -0
- package/dist/components/SolutionChoice.js.map +1 -0
- package/dist/components/SortMenu.js +75 -0
- package/dist/components/SortMenu.js.map +1 -0
- package/dist/components/Spinner.js +42 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/Stat.js +148 -0
- package/dist/components/Stat.js.map +1 -0
- package/dist/components/StatusSelect.js +119 -0
- package/dist/components/StatusSelect.js.map +1 -0
- package/dist/components/Surface.js +210 -0
- package/dist/components/Surface.js.map +1 -0
- package/dist/components/Table.js +300 -0
- package/dist/components/Table.js.map +1 -0
- package/dist/components/Tabs.js +288 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/components/ThemeMenu.js +198 -0
- package/dist/components/ThemeMenu.js.map +1 -0
- package/dist/components/Toast.js +217 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/Toggle.js +147 -0
- package/dist/components/Toggle.js.map +1 -0
- package/dist/components/ToggleMatrix.js +157 -0
- package/dist/components/ToggleMatrix.js.map +1 -0
- package/dist/components/Tree.js +125 -0
- package/dist/components/Tree.js.map +1 -0
- package/dist/components/TriStateSwitch.js +111 -0
- package/dist/components/TriStateSwitch.js.map +1 -0
- package/dist/components/VideoPlayer.js +64 -0
- package/dist/components/VideoPlayer.js.map +1 -0
- package/dist/components/auth/AcceptInvitationCard.js +110 -0
- package/dist/components/auth/AcceptInvitationCard.js.map +1 -0
- package/dist/components/auth/AuthLayout.js +18 -0
- package/dist/components/auth/AuthLayout.js.map +1 -0
- package/dist/components/auth/ForgotPasswordForm.js +44 -0
- package/dist/components/auth/ForgotPasswordForm.js.map +1 -0
- package/dist/components/auth/LoginForm.js +76 -0
- package/dist/components/auth/LoginForm.js.map +1 -0
- package/dist/components/auth/ResetPasswordForm.js +69 -0
- package/dist/components/auth/ResetPasswordForm.js.map +1 -0
- package/dist/components/auth/SignInProviders.js +45 -0
- package/dist/components/auth/SignInProviders.js.map +1 -0
- package/dist/components/auth/SignupCard.js +204 -0
- package/dist/components/auth/SignupCard.js.map +1 -0
- package/dist/components/auth/TermsAcceptance.js +43 -0
- package/dist/components/auth/TermsAcceptance.js.map +1 -0
- package/dist/components/board/context.js +32 -0
- package/dist/components/board/context.js.map +1 -0
- package/dist/components/board/recipe.js +94 -0
- package/dist/components/board/recipe.js.map +1 -0
- package/dist/components/calendar/CalendarMonth.js +299 -0
- package/dist/components/calendar/CalendarMonth.js.map +1 -0
- package/dist/components/calendar/CalendarTimeGrid.js +430 -0
- package/dist/components/calendar/CalendarTimeGrid.js.map +1 -0
- package/dist/components/calendar/EventActions.js +101 -0
- package/dist/components/calendar/EventActions.js.map +1 -0
- package/dist/components/calendar/format.js +73 -0
- package/dist/components/calendar/format.js.map +1 -0
- package/dist/components/calendar/palette.js +31 -0
- package/dist/components/calendar/palette.js.map +1 -0
- package/dist/components/calendar/use-calendar-drag.js +149 -0
- package/dist/components/calendar/use-calendar-drag.js.map +1 -0
- package/dist/components/calendar/use-event-keyboard.js +87 -0
- package/dist/components/calendar/use-event-keyboard.js.map +1 -0
- package/dist/components/calendar/use-grid-navigation.js +79 -0
- package/dist/components/calendar/use-grid-navigation.js.map +1 -0
- package/dist/components/calendar/use-now.js +27 -0
- package/dist/components/calendar/use-now.js.map +1 -0
- package/dist/components/card-face/AcRingGlyph.js +39 -0
- package/dist/components/card-face/AcRingGlyph.js.map +1 -0
- package/dist/components/card-face/BoardCardAgentSlot.js +17 -0
- package/dist/components/card-face/BoardCardAgentSlot.js.map +1 -0
- package/dist/components/card-face/CardFace.js +109 -0
- package/dist/components/card-face/CardFace.js.map +1 -0
- package/dist/components/card-face/CardTypeBadge.js +17 -0
- package/dist/components/card-face/CardTypeBadge.js.map +1 -0
- package/dist/components/card-face/EffortBadge.js +11 -0
- package/dist/components/card-face/EffortBadge.js.map +1 -0
- package/dist/components/card-face/GateRingGlyph.js +31 -0
- package/dist/components/card-face/GateRingGlyph.js.map +1 -0
- package/dist/components/card-face/OverflowRow.js +70 -0
- package/dist/components/card-face/OverflowRow.js.map +1 -0
- package/dist/components/card-face/TapTip.js +32 -0
- package/dist/components/card-face/TapTip.js.map +1 -0
- package/dist/components/card-face/hit-area.js +6 -0
- package/dist/components/card-face/hit-area.js.map +1 -0
- package/dist/components/card-face/vocabulary.js +102 -0
- package/dist/components/card-face/vocabulary.js.map +1 -0
- package/dist/components/chart/BarList.js +78 -0
- package/dist/components/chart/BarList.js.map +1 -0
- package/dist/components/chart/LineChart.js +310 -0
- package/dist/components/chart/LineChart.js.map +1 -0
- package/dist/components/chart/ShareBar.js +141 -0
- package/dist/components/chart/ShareBar.js.map +1 -0
- package/dist/components/chart/TimeSeriesChart.js +305 -0
- package/dist/components/chart/TimeSeriesChart.js.map +1 -0
- package/dist/components/chart/label-metrics.js +17 -0
- package/dist/components/chart/label-metrics.js.map +1 -0
- package/dist/components/chart/line-chart-axis.js +38 -0
- package/dist/components/chart/line-chart-axis.js.map +1 -0
- package/dist/components/chart/line-chart-scale.js +132 -0
- package/dist/components/chart/line-chart-scale.js.map +1 -0
- package/dist/components/chart/line-series-style.js +22 -0
- package/dist/components/chart/line-series-style.js.map +1 -0
- package/dist/components/chart/share-bar-labels.js +14 -0
- package/dist/components/chart/share-bar-labels.js.map +1 -0
- package/dist/components/chart/shared.js +157 -0
- package/dist/components/chart/shared.js.map +1 -0
- package/dist/components/chart/time-series-scale.js +51 -0
- package/dist/components/chart/time-series-scale.js.map +1 -0
- package/dist/components/chat/Attachment.js +316 -0
- package/dist/components/chat/Attachment.js.map +1 -0
- package/dist/components/chat/Chat.js +171 -0
- package/dist/components/chat/Chat.js.map +1 -0
- package/dist/components/chat/Composer.js +274 -0
- package/dist/components/chat/Composer.js.map +1 -0
- package/dist/components/chat/ContextMeter.js +202 -0
- package/dist/components/chat/ContextMeter.js.map +1 -0
- package/dist/components/chat/EffortControl.js +116 -0
- package/dist/components/chat/EffortControl.js.map +1 -0
- package/dist/components/chat/FileCover.js +78 -0
- package/dist/components/chat/FileCover.js.map +1 -0
- package/dist/components/chat/Message.js +356 -0
- package/dist/components/chat/Message.js.map +1 -0
- package/dist/components/chat/MessageScroller.js +104 -0
- package/dist/components/chat/MessageScroller.js.map +1 -0
- package/dist/components/chat/ModelSelector.js +156 -0
- package/dist/components/chat/ModelSelector.js.map +1 -0
- package/dist/components/chat/StreamingMarkdown.js +42 -0
- package/dist/components/chat/StreamingMarkdown.js.map +1 -0
- package/dist/components/chat/download-file.js +9 -0
- package/dist/components/chat/download-file.js.map +1 -0
- package/dist/components/chat/file-icon.js +39 -0
- package/dist/components/chat/file-icon.js.map +1 -0
- package/dist/components/checklist/StatusChecklist.js +103 -0
- package/dist/components/checklist/StatusChecklist.js.map +1 -0
- package/dist/components/checklist/tally.js +29 -0
- package/dist/components/checklist/tally.js.map +1 -0
- package/dist/components/code-editor/context.js +13 -0
- package/dist/components/code-editor/context.js.map +1 -0
- package/dist/components/code-editor/editing.js +93 -0
- package/dist/components/code-editor/editing.js.map +1 -0
- package/dist/components/code-editor/highlight.js +27 -0
- package/dist/components/code-editor/highlight.js.map +1 -0
- package/dist/components/code-editor/recipe.js +75 -0
- package/dist/components/code-editor/recipe.js.map +1 -0
- package/dist/components/date-timeline/DateTimeline.js +358 -0
- package/dist/components/date-timeline/DateTimeline.js.map +1 -0
- package/dist/components/date-timeline/TimelineRow.js +100 -0
- package/dist/components/date-timeline/TimelineRow.js.map +1 -0
- package/dist/components/date-timeline/useBarDrag.js +44 -0
- package/dist/components/date-timeline/useBarDrag.js.map +1 -0
- package/dist/components/date-timeline/useMarkerDrag.js +40 -0
- package/dist/components/date-timeline/useMarkerDrag.js.map +1 -0
- package/dist/components/date-timeline/useTimelineZoom.js +44 -0
- package/dist/components/date-timeline/useTimelineZoom.js.map +1 -0
- package/dist/components/drag-drop/context.js +37 -0
- package/dist/components/drag-drop/context.js.map +1 -0
- package/dist/components/drag-drop/recipe.js +270 -0
- package/dist/components/drag-drop/recipe.js.map +1 -0
- package/dist/components/drag-drop/shift.js +157 -0
- package/dist/components/drag-drop/shift.js.map +1 -0
- package/dist/components/edit/activation.js +10 -0
- package/dist/components/edit/activation.js.map +1 -0
- package/dist/components/edit/outcome.js +47 -0
- package/dist/components/edit/outcome.js.map +1 -0
- package/dist/components/edit/use-edit-session.js +146 -0
- package/dist/components/edit/use-edit-session.js.map +1 -0
- package/dist/components/file-viewer/FileViewer.js +97 -0
- package/dist/components/file-viewer/FileViewer.js.map +1 -0
- package/dist/components/file-viewer/PageNumberJumpField.js +47 -0
- package/dist/components/file-viewer/PageNumberJumpField.js.map +1 -0
- package/dist/components/file-viewer/ViewerControls.js +122 -0
- package/dist/components/file-viewer/ViewerControls.js.map +1 -0
- package/dist/components/file-viewer/ViewerRail.js +57 -0
- package/dist/components/file-viewer/ViewerRail.js.map +1 -0
- package/dist/components/file-viewer/ViewerStage.js +112 -0
- package/dist/components/file-viewer/ViewerStage.js.map +1 -0
- package/dist/components/file-viewer/frames.js +37 -0
- package/dist/components/file-viewer/frames.js.map +1 -0
- package/dist/components/file-viewer/use-frame-cursor.js +32 -0
- package/dist/components/file-viewer/use-frame-cursor.js.map +1 -0
- package/dist/components/file-viewer/use-viewer-keys.js +50 -0
- package/dist/components/file-viewer/use-viewer-keys.js.map +1 -0
- package/dist/components/file-viewer/use-viewer-zoom.js +68 -0
- package/dist/components/file-viewer/use-viewer-zoom.js.map +1 -0
- package/dist/components/focus-web/FocusWeb.js +322 -0
- package/dist/components/focus-web/FocusWeb.js.map +1 -0
- package/dist/components/focus-web/layout.js +34 -0
- package/dist/components/focus-web/layout.js.map +1 -0
- package/dist/components/graph-explorer/GraphExplorer.js +441 -0
- package/dist/components/graph-explorer/GraphExplorer.js.map +1 -0
- package/dist/components/graph-explorer/camera-math.js +102 -0
- package/dist/components/graph-explorer/camera-math.js.map +1 -0
- package/dist/components/graph-explorer/tree-layout.js +103 -0
- package/dist/components/graph-explorer/tree-layout.js.map +1 -0
- package/dist/components/graph-explorer/use-camera.js +82 -0
- package/dist/components/graph-explorer/use-camera.js.map +1 -0
- package/dist/components/graph-explorer/viewport-gesture.js +107 -0
- package/dist/components/graph-explorer/viewport-gesture.js.map +1 -0
- package/dist/components/kanban/KanbanBoard.js +219 -0
- package/dist/components/kanban/KanbanBoard.js.map +1 -0
- package/dist/components/kanban/recipe.js +144 -0
- package/dist/components/kanban/recipe.js.map +1 -0
- package/dist/components/markdown/Affordances.js +398 -0
- package/dist/components/markdown/Affordances.js.map +1 -0
- package/dist/components/markdown/AttachmentStrip.js +128 -0
- package/dist/components/markdown/AttachmentStrip.js.map +1 -0
- package/dist/components/markdown/ImageUpload.js +45 -0
- package/dist/components/markdown/ImageUpload.js.map +1 -0
- package/dist/components/media-error.js +7 -0
- package/dist/components/media-error.js.map +1 -0
- package/dist/components/nav-sections.js +61 -0
- package/dist/components/nav-sections.js.map +1 -0
- package/dist/components/node-canvas/NodeCanvas.js +384 -0
- package/dist/components/node-canvas/NodeCanvas.js.map +1 -0
- package/dist/components/node-canvas/layout.js +237 -0
- package/dist/components/node-canvas/layout.js.map +1 -0
- package/dist/components/node-canvas/use-canvas-gestures.js +143 -0
- package/dist/components/node-canvas/use-canvas-gestures.js.map +1 -0
- package/dist/components/openapi/OpenApiViewer.js +137 -0
- package/dist/components/openapi/OpenApiViewer.js.map +1 -0
- package/dist/components/openapi/OperationCard.js +145 -0
- package/dist/components/openapi/OperationCard.js.map +1 -0
- package/dist/components/openapi/SchemaView.js +68 -0
- package/dist/components/openapi/SchemaView.js.map +1 -0
- package/dist/components/openapi/resolve.js +102 -0
- package/dist/components/openapi/resolve.js.map +1 -0
- package/dist/components/openapi/types.js +5 -0
- package/dist/components/openapi/types.js.map +1 -0
- package/dist/components/overlay-shell.js +29 -0
- package/dist/components/overlay-shell.js.map +1 -0
- package/dist/components/overlay-stack.js +27 -0
- package/dist/components/overlay-stack.js.map +1 -0
- package/dist/components/paged-window/PageBlock.js +50 -0
- package/dist/components/paged-window/PageBlock.js.map +1 -0
- package/dist/components/provenance/ConfidenceBar.js +60 -0
- package/dist/components/provenance/ConfidenceBar.js.map +1 -0
- package/dist/components/provenance/ConfidenceMeter.js +36 -0
- package/dist/components/provenance/ConfidenceMeter.js.map +1 -0
- package/dist/components/provenance/ConfidenceReadout.js +31 -0
- package/dist/components/provenance/ConfidenceReadout.js.map +1 -0
- package/dist/components/provenance/ProvenanceBadge.js +44 -0
- package/dist/components/provenance/ProvenanceBadge.js.map +1 -0
- package/dist/components/provenance/ProvenanceDetail.js +114 -0
- package/dist/components/provenance/ProvenanceDetail.js.map +1 -0
- package/dist/components/provenance/ProvenanceDisclosure.js +111 -0
- package/dist/components/provenance/ProvenanceDisclosure.js.map +1 -0
- package/dist/components/provenance/absence.js +31 -0
- package/dist/components/provenance/absence.js.map +1 -0
- package/dist/components/provenance/types.js +30 -0
- package/dist/components/provenance/types.js.map +1 -0
- package/dist/components/rbac/AccessRequestPanel.js +153 -0
- package/dist/components/rbac/AccessRequestPanel.js.map +1 -0
- package/dist/components/rbac/AccountMenu.js +118 -0
- package/dist/components/rbac/AccountMenu.js.map +1 -0
- package/dist/components/rbac/AgentKeysList.js +20 -0
- package/dist/components/rbac/AgentKeysList.js.map +1 -0
- package/dist/components/rbac/ApiKeysPanel.js +172 -0
- package/dist/components/rbac/ApiKeysPanel.js.map +1 -0
- package/dist/components/rbac/ApiKeysTable.js +167 -0
- package/dist/components/rbac/ApiKeysTable.js.map +1 -0
- package/dist/components/rbac/Brand.js +13 -0
- package/dist/components/rbac/Brand.js.map +1 -0
- package/dist/components/rbac/Can.js +18 -0
- package/dist/components/rbac/Can.js.map +1 -0
- package/dist/components/rbac/ChangePasswordForm.js +73 -0
- package/dist/components/rbac/ChangePasswordForm.js.map +1 -0
- package/dist/components/rbac/DangerZone.js +27 -0
- package/dist/components/rbac/DangerZone.js.map +1 -0
- package/dist/components/rbac/DevToolsPopover.js +140 -0
- package/dist/components/rbac/DevToolsPopover.js.map +1 -0
- package/dist/components/rbac/EndedLine.js +24 -0
- package/dist/components/rbac/EndedLine.js.map +1 -0
- package/dist/components/rbac/InvitationsList.js +148 -0
- package/dist/components/rbac/InvitationsList.js.map +1 -0
- package/dist/components/rbac/InviteMembersDialog.js +97 -0
- package/dist/components/rbac/InviteMembersDialog.js.map +1 -0
- package/dist/components/rbac/MembersPanel.js +138 -0
- package/dist/components/rbac/MembersPanel.js.map +1 -0
- package/dist/components/rbac/PermissionRequestPanel.js +141 -0
- package/dist/components/rbac/PermissionRequestPanel.js.map +1 -0
- package/dist/components/rbac/ProfileForm.js +86 -0
- package/dist/components/rbac/ProfileForm.js.map +1 -0
- package/dist/components/rbac/ProfilePage.js +58 -0
- package/dist/components/rbac/ProfilePage.js.map +1 -0
- package/dist/components/rbac/RBACProvider.js +82 -0
- package/dist/components/rbac/RBACProvider.js.map +1 -0
- package/dist/components/rbac/RoleEditorDialog.js +90 -0
- package/dist/components/rbac/RoleEditorDialog.js.map +1 -0
- package/dist/components/rbac/RoleKeyPicker.js +77 -0
- package/dist/components/rbac/RoleKeyPicker.js.map +1 -0
- package/dist/components/rbac/RolePermissionMatrix.js +37 -0
- package/dist/components/rbac/RolePermissionMatrix.js.map +1 -0
- package/dist/components/rbac/RolesPermissionsPage.js +142 -0
- package/dist/components/rbac/RolesPermissionsPage.js.map +1 -0
- package/dist/components/rbac/SessionsList.js +146 -0
- package/dist/components/rbac/SessionsList.js.map +1 -0
- package/dist/components/rbac/TeamSettingsForm.js +69 -0
- package/dist/components/rbac/TeamSettingsForm.js.map +1 -0
- package/dist/components/rbac/TeamSwitcher.js +66 -0
- package/dist/components/rbac/TeamSwitcher.js.map +1 -0
- package/dist/components/rbac/approvalPanelParts.js +130 -0
- package/dist/components/rbac/approvalPanelParts.js.map +1 -0
- package/dist/components/rbac/permissionSections.js +8 -0
- package/dist/components/rbac/permissionSections.js.map +1 -0
- package/dist/components/rbac/stagedForm.js +42 -0
- package/dist/components/rbac/stagedForm.js.map +1 -0
- package/dist/components/rbac/useStagedImage.js +21 -0
- package/dist/components/rbac/useStagedImage.js.map +1 -0
- package/dist/components/roadmap/PhaseManager.js +48 -0
- package/dist/components/roadmap/PhaseManager.js.map +1 -0
- package/dist/components/roadmap/RoadmapItemCard.js +96 -0
- package/dist/components/roadmap/RoadmapItemCard.js.map +1 -0
- package/dist/components/roadmap/RoadmapPage.js +34 -0
- package/dist/components/roadmap/RoadmapPage.js.map +1 -0
- package/dist/components/roadmap/RoadmapSwimlaneBoard.js +91 -0
- package/dist/components/roadmap/RoadmapSwimlaneBoard.js.map +1 -0
- package/dist/components/roadmap/TrackManager.js +58 -0
- package/dist/components/roadmap/TrackManager.js.map +1 -0
- package/dist/components/roadmap/UseCaseCard.js +93 -0
- package/dist/components/roadmap/UseCaseCard.js.map +1 -0
- package/dist/components/roadmap/UseCaseLedgerPage.js +98 -0
- package/dist/components/roadmap/UseCaseLedgerPage.js.map +1 -0
- package/dist/components/roadmap/chip-tones.js +9 -0
- package/dist/components/roadmap/chip-tones.js.map +1 -0
- package/dist/components/roadmap/derive.js +28 -0
- package/dist/components/roadmap/derive.js.map +1 -0
- package/dist/components/stepper/Stepper.js +276 -0
- package/dist/components/stepper/Stepper.js.map +1 -0
- package/dist/components/stepper/derive.js +53 -0
- package/dist/components/stepper/derive.js.map +1 -0
- package/dist/confidence.css +222 -0
- package/dist/fonts/bricolage-grotesque-0.woff2 +0 -0
- package/dist/fonts/bricolage-grotesque-1.woff2 +0 -0
- package/dist/fonts/bricolage-grotesque-2.woff2 +0 -0
- package/dist/fonts/figtree-0.woff2 +0 -0
- package/dist/fonts/figtree-1.woff2 +0 -0
- package/dist/fonts/figtree-2.woff2 +0 -0
- package/dist/fonts/figtree-3.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-0.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-1.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-10.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-11.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-2.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-3.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-4.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-5.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-6.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-7.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-8.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-9.woff2 +0 -0
- package/dist/fonts.css +187 -0
- package/dist/icons/data.js +233 -0
- package/dist/icons/data.js.map +1 -0
- package/dist/index.js +942 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/attention.js +75 -0
- package/dist/lib/attention.js.map +1 -0
- package/dist/lib/board/anchor.js +14 -0
- package/dist/lib/board/anchor.js.map +1 -0
- package/dist/lib/board/model.js +41 -0
- package/dist/lib/board/model.js.map +1 -0
- package/dist/lib/board/move.js +161 -0
- package/dist/lib/board/move.js.map +1 -0
- package/dist/lib/board/position.js +11 -0
- package/dist/lib/board/position.js.map +1 -0
- package/dist/lib/board/rejection.js +22 -0
- package/dist/lib/board/rejection.js.map +1 -0
- package/dist/lib/board/use-board.js +43 -0
- package/dist/lib/board/use-board.js.map +1 -0
- package/dist/lib/calendar/band-packer.js +44 -0
- package/dist/lib/calendar/band-packer.js.map +1 -0
- package/dist/lib/calendar/drag.js +74 -0
- package/dist/lib/calendar/drag.js.map +1 -0
- package/dist/lib/calendar/lane-packer.js +67 -0
- package/dist/lib/calendar/lane-packer.js.map +1 -0
- package/dist/lib/calendar/segments.js +82 -0
- package/dist/lib/calendar/segments.js.map +1 -0
- package/dist/lib/calendar/types.js +7 -0
- package/dist/lib/calendar/types.js.map +1 -0
- package/dist/lib/chart-palette.js +27 -0
- package/dist/lib/chart-palette.js.map +1 -0
- package/dist/lib/clipboard.js +30 -0
- package/dist/lib/clipboard.js.map +1 -0
- package/dist/lib/cn.js +9 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/color.js +24 -0
- package/dist/lib/color.js.map +1 -0
- package/dist/lib/component-guidance.js +297 -0
- package/dist/lib/component-guidance.js.map +1 -0
- package/dist/lib/confidence.js +22 -0
- package/dist/lib/confidence.js.map +1 -0
- package/dist/lib/date-timeline/scale.js +197 -0
- package/dist/lib/date-timeline/scale.js.map +1 -0
- package/dist/lib/design-frame/document.js +44 -0
- package/dist/lib/design-frame/document.js.map +1 -0
- package/dist/lib/design-frame/mini-app-script.js +107 -0
- package/dist/lib/design-frame/mini-app-script.js.map +1 -0
- package/dist/lib/design-frame/mini-app.js +12 -0
- package/dist/lib/design-frame/mini-app.js.map +1 -0
- package/dist/lib/design-frame/protocol.js +46 -0
- package/dist/lib/design-frame/protocol.js.map +1 -0
- package/dist/lib/dev-warn.js +17 -0
- package/dist/lib/dev-warn.js.map +1 -0
- package/dist/lib/dnd/announce.js +120 -0
- package/dist/lib/dnd/announce.js.map +1 -0
- package/dist/lib/dnd/autoscroll.js +123 -0
- package/dist/lib/dnd/autoscroll.js.map +1 -0
- package/dist/lib/dnd/cross-drop.js +11 -0
- package/dist/lib/dnd/cross-drop.js.map +1 -0
- package/dist/lib/dnd/geometry.js +99 -0
- package/dist/lib/dnd/geometry.js.map +1 -0
- package/dist/lib/dnd/sensors/gesture.js +86 -0
- package/dist/lib/dnd/sensors/gesture.js.map +1 -0
- package/dist/lib/dnd/sensors/keyboard.js +47 -0
- package/dist/lib/dnd/sensors/keyboard.js.map +1 -0
- package/dist/lib/dnd/sensors/pointer.js +32 -0
- package/dist/lib/dnd/sensors/pointer.js.map +1 -0
- package/dist/lib/dnd/session.js +256 -0
- package/dist/lib/dnd/session.js.map +1 -0
- package/dist/lib/dnd/use-drag.js +90 -0
- package/dist/lib/dnd/use-drag.js.map +1 -0
- package/dist/lib/dom/scroll-ancestor.js +18 -0
- package/dist/lib/dom/scroll-ancestor.js.map +1 -0
- package/dist/lib/format.js +23 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/group-in-order.js +13 -0
- package/dist/lib/group-in-order.js.map +1 -0
- package/dist/lib/header-fold.js +11 -0
- package/dist/lib/header-fold.js.map +1 -0
- package/dist/lib/i18n/areas/auth-provenance-flows.js +156 -0
- package/dist/lib/i18n/areas/auth-provenance-flows.js.map +1 -0
- package/dist/lib/i18n/areas/board.js +35 -0
- package/dist/lib/i18n/areas/board.js.map +1 -0
- package/dist/lib/i18n/areas/card-face.js +10 -0
- package/dist/lib/i18n/areas/card-face.js.map +1 -0
- package/dist/lib/i18n/areas/chat-chart.js +118 -0
- package/dist/lib/i18n/areas/chat-chart.js.map +1 -0
- package/dist/lib/i18n/areas/code-editor.js +24 -0
- package/dist/lib/i18n/areas/code-editor.js.map +1 -0
- package/dist/lib/i18n/areas/date-timeline.js +21 -0
- package/dist/lib/i18n/areas/date-timeline.js.map +1 -0
- package/dist/lib/i18n/areas/dates.js +71 -0
- package/dist/lib/i18n/areas/dates.js.map +1 -0
- package/dist/lib/i18n/areas/docs-views.js +183 -0
- package/dist/lib/i18n/areas/docs-views.js.map +1 -0
- package/dist/lib/i18n/areas/feedback.js +75 -0
- package/dist/lib/i18n/areas/feedback.js.map +1 -0
- package/dist/lib/i18n/areas/formats.js +24 -0
- package/dist/lib/i18n/areas/formats.js.map +1 -0
- package/dist/lib/i18n/areas/forms.js +110 -0
- package/dist/lib/i18n/areas/forms.js.map +1 -0
- package/dist/lib/i18n/areas/keys.js +25 -0
- package/dist/lib/i18n/areas/keys.js.map +1 -0
- package/dist/lib/i18n/areas/markdown.js +136 -0
- package/dist/lib/i18n/areas/markdown.js.map +1 -0
- package/dist/lib/i18n/areas/move-rejected.js +14 -0
- package/dist/lib/i18n/areas/move-rejected.js.map +1 -0
- package/dist/lib/i18n/areas/navigation.js +104 -0
- package/dist/lib/i18n/areas/navigation.js.map +1 -0
- package/dist/lib/i18n/areas/rbac.js +331 -0
- package/dist/lib/i18n/areas/rbac.js.map +1 -0
- package/dist/lib/i18n/emphasis.js +6 -0
- package/dist/lib/i18n/emphasis.js.map +1 -0
- package/dist/lib/i18n/number-format.js +9 -0
- package/dist/lib/i18n/number-format.js.map +1 -0
- package/dist/lib/i18n/plural.js +9 -0
- package/dist/lib/i18n/plural.js.map +1 -0
- package/dist/lib/i18n/provider.js +27 -0
- package/dist/lib/i18n/provider.js.map +1 -0
- package/dist/lib/i18n/strings.js +38 -0
- package/dist/lib/i18n/strings.js.map +1 -0
- package/dist/lib/icons.js +17 -0
- package/dist/lib/icons.js.map +1 -0
- package/dist/lib/interactive-target.js +9 -0
- package/dist/lib/interactive-target.js.map +1 -0
- package/dist/lib/intl-cache.js +69 -0
- package/dist/lib/intl-cache.js.map +1 -0
- package/dist/lib/legal-document.js +37 -0
- package/dist/lib/legal-document.js.map +1 -0
- package/dist/lib/line-diff-model.js +51 -0
- package/dist/lib/line-diff-model.js.map +1 -0
- package/dist/lib/markdown/attachments.js +71 -0
- package/dist/lib/markdown/attachments.js.map +1 -0
- package/dist/lib/markdown/caret-map.js +153 -0
- package/dist/lib/markdown/caret-map.js.map +1 -0
- package/dist/lib/markdown/caret.js +35 -0
- package/dist/lib/markdown/caret.js.map +1 -0
- package/dist/lib/markdown/commands.js +443 -0
- package/dist/lib/markdown/commands.js.map +1 -0
- package/dist/lib/markdown/convert.js +153 -0
- package/dist/lib/markdown/convert.js.map +1 -0
- package/dist/lib/markdown/dom.js +89 -0
- package/dist/lib/markdown/dom.js.map +1 -0
- package/dist/lib/markdown/edit.js +92 -0
- package/dist/lib/markdown/edit.js.map +1 -0
- package/dist/lib/markdown/history.js +79 -0
- package/dist/lib/markdown/history.js.map +1 -0
- package/dist/lib/markdown/hotkeys.js +63 -0
- package/dist/lib/markdown/hotkeys.js.map +1 -0
- package/dist/lib/markdown/image-pipeline.js +236 -0
- package/dist/lib/markdown/image-pipeline.js.map +1 -0
- package/dist/lib/markdown/images.js +85 -0
- package/dist/lib/markdown/images.js.map +1 -0
- package/dist/lib/markdown/input.js +210 -0
- package/dist/lib/markdown/input.js.map +1 -0
- package/dist/lib/markdown/keys.js +37 -0
- package/dist/lib/markdown/keys.js.map +1 -0
- package/dist/lib/markdown/paste.js +180 -0
- package/dist/lib/markdown/paste.js.map +1 -0
- package/dist/lib/markdown/position.js +111 -0
- package/dist/lib/markdown/position.js.map +1 -0
- package/dist/lib/markdown/project.js +108 -0
- package/dist/lib/markdown/project.js.map +1 -0
- package/dist/lib/markdown/reconcile.js +127 -0
- package/dist/lib/markdown/reconcile.js.map +1 -0
- package/dist/lib/markdown/surface.js +373 -0
- package/dist/lib/markdown/surface.js.map +1 -0
- package/dist/lib/motion.js +22 -0
- package/dist/lib/motion.js.map +1 -0
- package/dist/lib/pad.js +7 -0
- package/dist/lib/pad.js.map +1 -0
- package/dist/lib/paged-window/layout.js +15 -0
- package/dist/lib/paged-window/layout.js.map +1 -0
- package/dist/lib/paged-window/list-owner.js +21 -0
- package/dist/lib/paged-window/list-owner.js.map +1 -0
- package/dist/lib/paged-window/records-binding.js +239 -0
- package/dist/lib/paged-window/records-binding.js.map +1 -0
- package/dist/lib/paged-window/store.js +562 -0
- package/dist/lib/paged-window/store.js.map +1 -0
- package/dist/lib/paged-window/use-measured-pitch.js +38 -0
- package/dist/lib/paged-window/use-measured-pitch.js.map +1 -0
- package/dist/lib/paged-window/use-page-visibility.js +36 -0
- package/dist/lib/paged-window/use-page-visibility.js.map +1 -0
- package/dist/lib/paged-window/use-paged-window.js +43 -0
- package/dist/lib/paged-window/use-paged-window.js.map +1 -0
- package/dist/lib/paged-window/use-scroll-root.js +12 -0
- package/dist/lib/paged-window/use-scroll-root.js.map +1 -0
- package/dist/lib/persist.js +84 -0
- package/dist/lib/persist.js.map +1 -0
- package/dist/lib/preference-values.js +13 -0
- package/dist/lib/preference-values.js.map +1 -0
- package/dist/lib/preferences.js +86 -0
- package/dist/lib/preferences.js.map +1 -0
- package/dist/lib/reads/hooks.js +156 -0
- package/dist/lib/reads/hooks.js.map +1 -0
- package/dist/lib/reads/optimistic.js +169 -0
- package/dist/lib/reads/optimistic.js.map +1 -0
- package/dist/lib/reads/refetch.js +108 -0
- package/dist/lib/reads/refetch.js.map +1 -0
- package/dist/lib/reads/slots.js +215 -0
- package/dist/lib/reads/slots.js.map +1 -0
- package/dist/lib/realtime/hooks.js +40 -0
- package/dist/lib/realtime/hooks.js.map +1 -0
- package/dist/lib/realtime/provider.js +25 -0
- package/dist/lib/realtime/provider.js.map +1 -0
- package/dist/lib/realtime/registry.js +472 -0
- package/dist/lib/realtime/registry.js.map +1 -0
- package/dist/lib/records/define-record-type.js +33 -0
- package/dist/lib/records/define-record-type.js.map +1 -0
- package/dist/lib/records/hooks.js +39 -0
- package/dist/lib/records/hooks.js.map +1 -0
- package/dist/lib/records/store.js +572 -0
- package/dist/lib/records/store.js.map +1 -0
- package/dist/lib/records/wire.js +58 -0
- package/dist/lib/records/wire.js.map +1 -0
- package/dist/lib/reduced-motion-help.js +19 -0
- package/dist/lib/reduced-motion-help.js.map +1 -0
- package/dist/lib/scroll-caret.js +18 -0
- package/dist/lib/scroll-caret.js.map +1 -0
- package/dist/lib/sim/createSimStore.js +54 -0
- package/dist/lib/sim/createSimStore.js.map +1 -0
- package/dist/lib/sim/latency.js +28 -0
- package/dist/lib/sim/latency.js.map +1 -0
- package/dist/lib/sim/registry.js +13 -0
- package/dist/lib/sim/registry.js.map +1 -0
- package/dist/lib/sim/settings.js +41 -0
- package/dist/lib/sim/settings.js.map +1 -0
- package/dist/lib/submit-shortcut.js +25 -0
- package/dist/lib/submit-shortcut.js.map +1 -0
- package/dist/lib/syntax/index.js +33 -0
- package/dist/lib/syntax/index.js.map +1 -0
- package/dist/lib/syntax/languages/bash.js +77 -0
- package/dist/lib/syntax/languages/bash.js.map +1 -0
- package/dist/lib/syntax/languages/css.js +81 -0
- package/dist/lib/syntax/languages/css.js.map +1 -0
- package/dist/lib/syntax/languages/html.js +91 -0
- package/dist/lib/syntax/languages/html.js.map +1 -0
- package/dist/lib/syntax/languages/index.js +49 -0
- package/dist/lib/syntax/languages/index.js.map +1 -0
- package/dist/lib/syntax/languages/javascript.js +133 -0
- package/dist/lib/syntax/languages/javascript.js.map +1 -0
- package/dist/lib/syntax/languages/json.js +45 -0
- package/dist/lib/syntax/languages/json.js.map +1 -0
- package/dist/lib/syntax/languages/mongodb.js +24 -0
- package/dist/lib/syntax/languages/mongodb.js.map +1 -0
- package/dist/lib/syntax/languages/plain.js +10 -0
- package/dist/lib/syntax/languages/plain.js.map +1 -0
- package/dist/lib/syntax/languages/sql.js +113 -0
- package/dist/lib/syntax/languages/sql.js.map +1 -0
- package/dist/lib/syntax/languages/vue.js +31 -0
- package/dist/lib/syntax/languages/vue.js.map +1 -0
- package/dist/lib/syntax/languages/yaml.js +55 -0
- package/dist/lib/syntax/languages/yaml.js.map +1 -0
- package/dist/lib/syntax/markdown/grammar.js +52 -0
- package/dist/lib/syntax/markdown/grammar.js.map +1 -0
- package/dist/lib/syntax/markdown/inline.js +477 -0
- package/dist/lib/syntax/markdown/inline.js.map +1 -0
- package/dist/lib/syntax/markdown/parse.js +464 -0
- package/dist/lib/syntax/markdown/parse.js.map +1 -0
- package/dist/lib/syntax/markdown/refs.js +94 -0
- package/dist/lib/syntax/markdown/refs.js.map +1 -0
- package/dist/lib/syntax/markdown/render.js +230 -0
- package/dist/lib/syntax/markdown/render.js.map +1 -0
- package/dist/lib/syntax/markdown/spans.js +40 -0
- package/dist/lib/syntax/markdown/spans.js.map +1 -0
- package/dist/lib/syntax/registry.js +55 -0
- package/dist/lib/syntax/registry.js.map +1 -0
- package/dist/lib/syntax/tokenize.js +96 -0
- package/dist/lib/syntax/tokenize.js.map +1 -0
- package/dist/lib/time/instant.js +7 -0
- package/dist/lib/time/instant.js.map +1 -0
- package/dist/lib/time/plain.js +83 -0
- package/dist/lib/time/plain.js.map +1 -0
- package/dist/lib/time/relativeAge.js +20 -0
- package/dist/lib/time/relativeAge.js.map +1 -0
- package/dist/lib/time/relativeClock.js +59 -0
- package/dist/lib/time/relativeClock.js.map +1 -0
- package/dist/lib/time/types.js +23 -0
- package/dist/lib/time/types.js.map +1 -0
- package/dist/lib/time/zone.js +148 -0
- package/dist/lib/time/zone.js.map +1 -0
- package/dist/lib/use-controllable.js +16 -0
- package/dist/lib/use-controllable.js.map +1 -0
- package/dist/lib/use-fill-height.js +49 -0
- package/dist/lib/use-fill-height.js.map +1 -0
- package/dist/lib/use-hydrated.js +14 -0
- package/dist/lib/use-hydrated.js.map +1 -0
- package/dist/lib/use-media-query.js +30 -0
- package/dist/lib/use-media-query.js.map +1 -0
- package/dist/lib/use-relabel-base-ui-dismiss.js +26 -0
- package/dist/lib/use-relabel-base-ui-dismiss.js.map +1 -0
- package/dist/lib/use-release-snap-drag.js +29 -0
- package/dist/lib/use-release-snap-drag.js.map +1 -0
- package/dist/lib/use-roving-options.js +18 -0
- package/dist/lib/use-roving-options.js.map +1 -0
- package/dist/lib/values/absent.js +5 -0
- package/dist/lib/values/absent.js.map +1 -0
- package/dist/lib/values/boolean.js +13 -0
- package/dist/lib/values/boolean.js.map +1 -0
- package/dist/lib/values/currency.js +23 -0
- package/dist/lib/values/currency.js.map +1 -0
- package/dist/lib/values/date.js +35 -0
- package/dist/lib/values/date.js.map +1 -0
- package/dist/lib/values/datetime.js +54 -0
- package/dist/lib/values/datetime.js.map +1 -0
- package/dist/lib/values/locale-date.js +60 -0
- package/dist/lib/values/locale-date.js.map +1 -0
- package/dist/lib/values/number.js +16 -0
- package/dist/lib/values/number.js.map +1 -0
- package/dist/pure.js +379 -0
- package/dist/pure.js.map +1 -0
- package/dist/styles.css +190 -0
- package/dist/theme.css +360 -0
- package/dist/types/components/Accordion.d.ts +15 -0
- package/dist/types/components/AgentWorkingSpinner.d.ts +23 -0
- package/dist/types/components/AppShell.d.ts +164 -0
- package/dist/types/components/Attention.d.ts +87 -0
- package/dist/types/components/Avatar.d.ts +154 -0
- package/dist/types/components/Badge.d.ts +131 -0
- package/dist/types/components/Board.d.ts +239 -0
- package/dist/types/components/Button.d.ts +208 -0
- package/dist/types/components/Callout.d.ts +163 -0
- package/dist/types/components/Card.d.ts +219 -0
- package/dist/types/components/Choice.d.ts +127 -0
- package/dist/types/components/CodeEditor.d.ts +86 -0
- package/dist/types/components/ColorPicker.d.ts +14 -0
- package/dist/types/components/Combobox.d.ts +43 -0
- package/dist/types/components/CommandPalette.d.ts +35 -0
- package/dist/types/components/ConcentricRing.d.ts +61 -0
- package/dist/types/components/ConnectionCard.d.ts +64 -0
- package/dist/types/components/ContextItemRow.d.ts +35 -0
- package/dist/types/components/CopyValue.d.ts +14 -0
- package/dist/types/components/CountBadge.d.ts +14 -0
- package/dist/types/components/DateCalendar.d.ts +30 -0
- package/dist/types/components/DateField.d.ts +29 -0
- package/dist/types/components/DatePicker.d.ts +20 -0
- package/dist/types/components/DateTimeText.d.ts +9 -0
- package/dist/types/components/DescriptionList.d.ts +40 -0
- package/dist/types/components/Dialog.d.ts +269 -0
- package/dist/types/components/DragDrop.d.ts +196 -0
- package/dist/types/components/Drawer.d.ts +163 -0
- package/dist/types/components/EditGutter.d.ts +44 -0
- package/dist/types/components/EmojiPicker.d.ts +30 -0
- package/dist/types/components/ErrorBoundary.d.ts +43 -0
- package/dist/types/components/Field.d.ts +37 -0
- package/dist/types/components/FileUpload.d.ts +22 -0
- package/dist/types/components/FilterMenu.d.ts +120 -0
- package/dist/types/components/GatesSection.d.ts +79 -0
- package/dist/types/components/Icon.d.ts +40 -0
- package/dist/types/components/IconButton.d.ts +69 -0
- package/dist/types/components/IconStack.d.ts +28 -0
- package/dist/types/components/ImageUploadField.d.ts +38 -0
- package/dist/types/components/InlineEdit.d.ts +183 -0
- package/dist/types/components/InlineMarkdownEdit.d.ts +100 -0
- package/dist/types/components/Input.d.ts +128 -0
- package/dist/types/components/LegalDocument.d.ts +23 -0
- package/dist/types/components/LineDiff.d.ts +53 -0
- package/dist/types/components/ListHeader.d.ts +45 -0
- package/dist/types/components/Loading.d.ts +131 -0
- package/dist/types/components/Markdown.d.ts +35 -0
- package/dist/types/components/MarkdownEditor.d.ts +129 -0
- package/dist/types/components/Menu.d.ts +157 -0
- package/dist/types/components/Navigation.d.ts +67 -0
- package/dist/types/components/NumberInput.d.ts +177 -0
- package/dist/types/components/OTPInput.d.ts +13 -0
- package/dist/types/components/OrderedEntityManager.d.ts +64 -0
- package/dist/types/components/PagedWindowList.d.ts +23 -0
- package/dist/types/components/PaginationBar.d.ts +31 -0
- package/dist/types/components/Panel.d.ts +94 -0
- package/dist/types/components/PasswordInput.d.ts +7 -0
- package/dist/types/components/PasswordRequirements.d.ts +11 -0
- package/dist/types/components/PatchDiff.d.ts +38 -0
- package/dist/types/components/PendingVeil.d.ts +8 -0
- package/dist/types/components/Popover.d.ts +231 -0
- package/dist/types/components/Progress.d.ts +580 -0
- package/dist/types/components/RatingScale.d.ts +30 -0
- package/dist/types/components/ReadMore.d.ts +26 -0
- package/dist/types/components/RecordCard.d.ts +413 -0
- package/dist/types/components/RelativeTime.d.ts +17 -0
- package/dist/types/components/SandboxedFrame.d.ts +37 -0
- package/dist/types/components/SearchInput.d.ts +6 -0
- package/dist/types/components/SecretField.d.ts +90 -0
- package/dist/types/components/SectionNav.d.ts +15 -0
- package/dist/types/components/Select.d.ts +53 -0
- package/dist/types/components/SequenceDiagram.d.ts +15 -0
- package/dist/types/components/SettingRow.d.ts +144 -0
- package/dist/types/components/SignOffRings.d.ts +29 -0
- package/dist/types/components/Slider.d.ts +255 -0
- package/dist/types/components/SolutionChoice.d.ts +49 -0
- package/dist/types/components/SortMenu.d.ts +45 -0
- package/dist/types/components/Spinner.d.ts +29 -0
- package/dist/types/components/Stat.d.ts +136 -0
- package/dist/types/components/StatusSelect.d.ts +93 -0
- package/dist/types/components/Surface.d.ts +145 -0
- package/dist/types/components/Table.d.ts +164 -0
- package/dist/types/components/Tabs.d.ts +142 -0
- package/dist/types/components/ThemeMenu.d.ts +56 -0
- package/dist/types/components/Toast.d.ts +63 -0
- package/dist/types/components/Toggle.d.ts +168 -0
- package/dist/types/components/ToggleMatrix.d.ts +51 -0
- package/dist/types/components/Tree.d.ts +20 -0
- package/dist/types/components/TriStateSwitch.d.ts +63 -0
- package/dist/types/components/VideoPlayer.d.ts +26 -0
- package/dist/types/components/auth/AcceptInvitationCard.d.ts +54 -0
- package/dist/types/components/auth/AuthLayout.d.ts +12 -0
- package/dist/types/components/auth/ForgotPasswordForm.d.ts +6 -0
- package/dist/types/components/auth/LoginForm.d.ts +13 -0
- package/dist/types/components/auth/ResetPasswordForm.d.ts +9 -0
- package/dist/types/components/auth/SignInProviders.d.ts +56 -0
- package/dist/types/components/auth/SignupCard.d.ts +62 -0
- package/dist/types/components/auth/TermsAcceptance.d.ts +14 -0
- package/dist/types/components/auth/index.d.ts +8 -0
- package/dist/types/components/board/context.d.ts +65 -0
- package/dist/types/components/board/recipe.d.ts +97 -0
- package/dist/types/components/calendar/CalendarMonth.d.ts +32 -0
- package/dist/types/components/calendar/CalendarTimeGrid.d.ts +74 -0
- package/dist/types/components/calendar/EventActions.d.ts +16 -0
- package/dist/types/components/calendar/format.d.ts +42 -0
- package/dist/types/components/calendar/palette.d.ts +17 -0
- package/dist/types/components/calendar/use-calendar-drag.d.ts +53 -0
- package/dist/types/components/calendar/use-event-keyboard.d.ts +23 -0
- package/dist/types/components/calendar/use-grid-navigation.d.ts +47 -0
- package/dist/types/components/calendar/use-now.d.ts +20 -0
- package/dist/types/components/card-face/AcRingGlyph.d.ts +20 -0
- package/dist/types/components/card-face/BoardCardAgentSlot.d.ts +19 -0
- package/dist/types/components/card-face/CardFace.d.ts +106 -0
- package/dist/types/components/card-face/CardTypeBadge.d.ts +21 -0
- package/dist/types/components/card-face/EffortBadge.d.ts +9 -0
- package/dist/types/components/card-face/GateRingGlyph.d.ts +22 -0
- package/dist/types/components/card-face/OverflowRow.d.ts +40 -0
- package/dist/types/components/card-face/TapTip.d.ts +15 -0
- package/dist/types/components/card-face/hit-area.d.ts +20 -0
- package/dist/types/components/card-face/vocabulary.d.ts +83 -0
- package/dist/types/components/chart/BarList.d.ts +27 -0
- package/dist/types/components/chart/LineChart.d.ts +64 -0
- package/dist/types/components/chart/ShareBar.d.ts +26 -0
- package/dist/types/components/chart/TimeSeriesChart.d.ts +60 -0
- package/dist/types/components/chart/label-metrics.d.ts +9 -0
- package/dist/types/components/chart/line-chart-axis.d.ts +14 -0
- package/dist/types/components/chart/line-chart-scale.d.ts +55 -0
- package/dist/types/components/chart/line-series-style.d.ts +14 -0
- package/dist/types/components/chart/share-bar-labels.d.ts +17 -0
- package/dist/types/components/chart/shared.d.ts +122 -0
- package/dist/types/components/chart/time-series-scale.d.ts +29 -0
- package/dist/types/components/chat/Attachment.d.ts +125 -0
- package/dist/types/components/chat/Chat.d.ts +60 -0
- package/dist/types/components/chat/Composer.d.ts +62 -0
- package/dist/types/components/chat/ContextMeter.d.ts +45 -0
- package/dist/types/components/chat/EffortControl.d.ts +23 -0
- package/dist/types/components/chat/FileCover.d.ts +14 -0
- package/dist/types/components/chat/Message.d.ts +66 -0
- package/dist/types/components/chat/MessageScroller.d.ts +18 -0
- package/dist/types/components/chat/ModelSelector.d.ts +44 -0
- package/dist/types/components/chat/StreamingMarkdown.d.ts +11 -0
- package/dist/types/components/chat/download-file.d.ts +7 -0
- package/dist/types/components/chat/file-icon.d.ts +29 -0
- package/dist/types/components/chat/types.d.ts +165 -0
- package/dist/types/components/checklist/StatusChecklist.d.ts +37 -0
- package/dist/types/components/checklist/index.d.ts +3 -0
- package/dist/types/components/checklist/tally.d.ts +19 -0
- package/dist/types/components/checklist/types.d.ts +28 -0
- package/dist/types/components/code-editor/context.d.ts +32 -0
- package/dist/types/components/code-editor/editing.d.ts +39 -0
- package/dist/types/components/code-editor/highlight.d.ts +20 -0
- package/dist/types/components/code-editor/recipe.d.ts +109 -0
- package/dist/types/components/date-timeline/DateTimeline.d.ts +99 -0
- package/dist/types/components/date-timeline/TimelineRow.d.ts +22 -0
- package/dist/types/components/date-timeline/useBarDrag.d.ts +15 -0
- package/dist/types/components/date-timeline/useMarkerDrag.d.ts +14 -0
- package/dist/types/components/date-timeline/useTimelineZoom.d.ts +23 -0
- package/dist/types/components/drag-drop/context.d.ts +85 -0
- package/dist/types/components/drag-drop/recipe.d.ts +163 -0
- package/dist/types/components/drag-drop/shift.d.ts +153 -0
- package/dist/types/components/edit/activation.d.ts +21 -0
- package/dist/types/components/edit/outcome.d.ts +29 -0
- package/dist/types/components/edit/use-edit-session.d.ts +77 -0
- package/dist/types/components/file-viewer/FileViewer.d.ts +2 -0
- package/dist/types/components/file-viewer/PageNumberJumpField.d.ts +9 -0
- package/dist/types/components/file-viewer/ViewerControls.d.ts +20 -0
- package/dist/types/components/file-viewer/ViewerRail.d.ts +10 -0
- package/dist/types/components/file-viewer/ViewerStage.d.ts +22 -0
- package/dist/types/components/file-viewer/frames.d.ts +28 -0
- package/dist/types/components/file-viewer/index.d.ts +3 -0
- package/dist/types/components/file-viewer/types.d.ts +70 -0
- package/dist/types/components/file-viewer/use-frame-cursor.d.ts +13 -0
- package/dist/types/components/file-viewer/use-viewer-keys.d.ts +24 -0
- package/dist/types/components/file-viewer/use-viewer-zoom.d.ts +29 -0
- package/dist/types/components/focus-web/FocusWeb.d.ts +3 -0
- package/dist/types/components/focus-web/index.d.ts +4 -0
- package/dist/types/components/focus-web/layout.d.ts +55 -0
- package/dist/types/components/focus-web/types.d.ts +131 -0
- package/dist/types/components/graph-explorer/GraphExplorer.d.ts +42 -0
- package/dist/types/components/graph-explorer/camera-math.d.ts +119 -0
- package/dist/types/components/graph-explorer/index.d.ts +5 -0
- package/dist/types/components/graph-explorer/tree-layout.d.ts +67 -0
- package/dist/types/components/graph-explorer/types.d.ts +62 -0
- package/dist/types/components/graph-explorer/use-camera.d.ts +81 -0
- package/dist/types/components/graph-explorer/viewport-gesture.d.ts +32 -0
- package/dist/types/components/kanban/KanbanBoard.d.ts +72 -0
- package/dist/types/components/kanban/recipe.d.ts +73 -0
- package/dist/types/components/kanban/types.d.ts +55 -0
- package/dist/types/components/markdown/Affordances.d.ts +105 -0
- package/dist/types/components/markdown/AttachmentStrip.d.ts +25 -0
- package/dist/types/components/markdown/ImageUpload.d.ts +56 -0
- package/dist/types/components/media-error.d.ts +11 -0
- package/dist/types/components/nav-sections.d.ts +10 -0
- package/dist/types/components/node-canvas/NodeCanvas.d.ts +66 -0
- package/dist/types/components/node-canvas/index.d.ts +3 -0
- package/dist/types/components/node-canvas/layout.d.ts +29 -0
- package/dist/types/components/node-canvas/types.d.ts +207 -0
- package/dist/types/components/node-canvas/use-canvas-gestures.d.ts +39 -0
- package/dist/types/components/openapi/OpenApiViewer.d.ts +14 -0
- package/dist/types/components/openapi/OperationCard.d.ts +33 -0
- package/dist/types/components/openapi/SchemaView.d.ts +14 -0
- package/dist/types/components/openapi/index.d.ts +6 -0
- package/dist/types/components/openapi/resolve.d.ts +72 -0
- package/dist/types/components/openapi/types.d.ts +128 -0
- package/dist/types/components/overlay-shell.d.ts +48 -0
- package/dist/types/components/overlay-stack.d.ts +18 -0
- package/dist/types/components/paged-window/PageBlock.d.ts +31 -0
- package/dist/types/components/provenance/ConfidenceBar.d.ts +118 -0
- package/dist/types/components/provenance/ConfidenceMeter.d.ts +21 -0
- package/dist/types/components/provenance/ConfidenceReadout.d.ts +17 -0
- package/dist/types/components/provenance/ProvenanceBadge.d.ts +23 -0
- package/dist/types/components/provenance/ProvenanceDetail.d.ts +109 -0
- package/dist/types/components/provenance/ProvenanceDisclosure.d.ts +107 -0
- package/dist/types/components/provenance/absence.d.ts +37 -0
- package/dist/types/components/provenance/index.d.ts +7 -0
- package/dist/types/components/provenance/types.d.ts +137 -0
- package/dist/types/components/rbac/AccessRequestPanel.d.ts +92 -0
- package/dist/types/components/rbac/AccountMenu.d.ts +46 -0
- package/dist/types/components/rbac/AgentKeysList.d.ts +20 -0
- package/dist/types/components/rbac/ApiKeysPanel.d.ts +26 -0
- package/dist/types/components/rbac/ApiKeysTable.d.ts +63 -0
- package/dist/types/components/rbac/Brand.d.ts +8 -0
- package/dist/types/components/rbac/Can.d.ts +19 -0
- package/dist/types/components/rbac/ChangePasswordForm.d.ts +18 -0
- package/dist/types/components/rbac/DangerZone.d.ts +8 -0
- package/dist/types/components/rbac/DevToolsPopover.d.ts +36 -0
- package/dist/types/components/rbac/EndedLine.d.ts +21 -0
- package/dist/types/components/rbac/InvitationsList.d.ts +39 -0
- package/dist/types/components/rbac/InviteMembersDialog.d.ts +21 -0
- package/dist/types/components/rbac/MembersPanel.d.ts +31 -0
- package/dist/types/components/rbac/PermissionRequestPanel.d.ts +36 -0
- package/dist/types/components/rbac/ProfileForm.d.ts +27 -0
- package/dist/types/components/rbac/ProfilePage.d.ts +16 -0
- package/dist/types/components/rbac/RBACProvider.d.ts +69 -0
- package/dist/types/components/rbac/RoleEditorDialog.d.ts +28 -0
- package/dist/types/components/rbac/RoleKeyPicker.d.ts +24 -0
- package/dist/types/components/rbac/RolePermissionMatrix.d.ts +21 -0
- package/dist/types/components/rbac/RolesPermissionsPage.d.ts +24 -0
- package/dist/types/components/rbac/SessionsList.d.ts +35 -0
- package/dist/types/components/rbac/TeamSettingsForm.d.ts +22 -0
- package/dist/types/components/rbac/TeamSwitcher.d.ts +5 -0
- package/dist/types/components/rbac/approvalPanelParts.d.ts +69 -0
- package/dist/types/components/rbac/index.d.ts +25 -0
- package/dist/types/components/rbac/permissionSections.d.ts +8 -0
- package/dist/types/components/rbac/stagedForm.d.ts +25 -0
- package/dist/types/components/rbac/types.d.ts +65 -0
- package/dist/types/components/rbac/useStagedImage.d.ts +15 -0
- package/dist/types/components/roadmap/PhaseManager.d.ts +19 -0
- package/dist/types/components/roadmap/RoadmapItemCard.d.ts +51 -0
- package/dist/types/components/roadmap/RoadmapPage.d.ts +12 -0
- package/dist/types/components/roadmap/RoadmapSwimlaneBoard.d.ts +15 -0
- package/dist/types/components/roadmap/TrackManager.d.ts +19 -0
- package/dist/types/components/roadmap/UseCaseCard.d.ts +30 -0
- package/dist/types/components/roadmap/UseCaseLedgerPage.d.ts +29 -0
- package/dist/types/components/roadmap/chip-tones.d.ts +2 -0
- package/dist/types/components/roadmap/derive.d.ts +39 -0
- package/dist/types/components/roadmap/index.d.ts +10 -0
- package/dist/types/components/roadmap/types.d.ts +86 -0
- package/dist/types/components/stepper/Stepper.d.ts +79 -0
- package/dist/types/components/stepper/derive.d.ts +49 -0
- package/dist/types/components/stepper/index.d.ts +3 -0
- package/dist/types/components/stepper/types.d.ts +118 -0
- package/dist/types/icons/data.d.ts +2054 -0
- package/dist/types/index.d.ts +209 -0
- package/dist/types/lib/attention.d.ts +62 -0
- package/dist/types/lib/board/anchor.d.ts +69 -0
- package/dist/types/lib/board/index.d.ts +17 -0
- package/dist/types/lib/board/model.d.ts +43 -0
- package/dist/types/lib/board/move.d.ts +181 -0
- package/dist/types/lib/board/position.d.ts +22 -0
- package/dist/types/lib/board/rejection.d.ts +8 -0
- package/dist/types/lib/board/types.d.ts +294 -0
- package/dist/types/lib/board/use-board.d.ts +47 -0
- package/dist/types/lib/calendar/band-packer.d.ts +53 -0
- package/dist/types/lib/calendar/drag.d.ts +125 -0
- package/dist/types/lib/calendar/index.d.ts +4 -0
- package/dist/types/lib/calendar/lane-packer.d.ts +88 -0
- package/dist/types/lib/calendar/segments.d.ts +91 -0
- package/dist/types/lib/calendar/types.d.ts +166 -0
- package/dist/types/lib/chart-palette.d.ts +14 -0
- package/dist/types/lib/clipboard.d.ts +12 -0
- package/dist/types/lib/cn.d.ts +7 -0
- package/dist/types/lib/color.d.ts +14 -0
- package/dist/types/lib/component-guidance.d.ts +15 -0
- package/dist/types/lib/confidence.d.ts +28 -0
- package/dist/types/lib/date-timeline/scale.d.ts +143 -0
- package/dist/types/lib/design-frame/document.d.ts +39 -0
- package/dist/types/lib/design-frame/mini-app-script.d.ts +29 -0
- package/dist/types/lib/design-frame/mini-app.d.ts +17 -0
- package/dist/types/lib/design-frame/protocol.d.ts +78 -0
- package/dist/types/lib/dev-warn.d.ts +10 -0
- package/dist/types/lib/dnd/announce.d.ts +124 -0
- package/dist/types/lib/dnd/autoscroll.d.ts +88 -0
- package/dist/types/lib/dnd/cross-drop.d.ts +18 -0
- package/dist/types/lib/dnd/geometry.d.ts +126 -0
- package/dist/types/lib/dnd/index.d.ts +17 -0
- package/dist/types/lib/dnd/sensors/gesture.d.ts +37 -0
- package/dist/types/lib/dnd/sensors/keyboard.d.ts +54 -0
- package/dist/types/lib/dnd/sensors/pointer.d.ts +59 -0
- package/dist/types/lib/dnd/session.d.ts +124 -0
- package/dist/types/lib/dnd/types.d.ts +226 -0
- package/dist/types/lib/dnd/use-drag.d.ts +82 -0
- package/dist/types/lib/dom/scroll-ancestor.d.ts +15 -0
- package/dist/types/lib/format.d.ts +33 -0
- package/dist/types/lib/group-in-order.d.ts +13 -0
- package/dist/types/lib/header-fold.d.ts +10 -0
- package/dist/types/lib/i18n/areas/auth-provenance-flows.d.ts +287 -0
- package/dist/types/lib/i18n/areas/board.d.ts +51 -0
- package/dist/types/lib/i18n/areas/card-face.d.ts +8 -0
- package/dist/types/lib/i18n/areas/chat-chart.d.ts +202 -0
- package/dist/types/lib/i18n/areas/code-editor.d.ts +40 -0
- package/dist/types/lib/i18n/areas/date-timeline.d.ts +36 -0
- package/dist/types/lib/i18n/areas/dates.d.ts +103 -0
- package/dist/types/lib/i18n/areas/docs-views.d.ts +297 -0
- package/dist/types/lib/i18n/areas/feedback.d.ts +132 -0
- package/dist/types/lib/i18n/areas/formats.d.ts +30 -0
- package/dist/types/lib/i18n/areas/forms.d.ts +182 -0
- package/dist/types/lib/i18n/areas/keys.d.ts +15 -0
- package/dist/types/lib/i18n/areas/markdown.d.ts +150 -0
- package/dist/types/lib/i18n/areas/move-rejected.d.ts +16 -0
- package/dist/types/lib/i18n/areas/navigation.d.ts +185 -0
- package/dist/types/lib/i18n/areas/rbac.d.ts +633 -0
- package/dist/types/lib/i18n/emphasis.d.ts +3 -0
- package/dist/types/lib/i18n/index.d.ts +10 -0
- package/dist/types/lib/i18n/number-format.d.ts +5 -0
- package/dist/types/lib/i18n/plural.d.ts +7 -0
- package/dist/types/lib/i18n/provider.d.ts +16 -0
- package/dist/types/lib/i18n/strings.d.ts +18 -0
- package/dist/types/lib/icons.d.ts +22 -0
- package/dist/types/lib/interactive-target.d.ts +3 -0
- package/dist/types/lib/intl-cache.d.ts +31 -0
- package/dist/types/lib/legal-document.d.ts +82 -0
- package/dist/types/lib/line-diff-model.d.ts +39 -0
- package/dist/types/lib/markdown/attachments.d.ts +50 -0
- package/dist/types/lib/markdown/caret-map.d.ts +69 -0
- package/dist/types/lib/markdown/caret.d.ts +6 -0
- package/dist/types/lib/markdown/commands.d.ts +186 -0
- package/dist/types/lib/markdown/convert.d.ts +99 -0
- package/dist/types/lib/markdown/dom.d.ts +30 -0
- package/dist/types/lib/markdown/edit.d.ts +16 -0
- package/dist/types/lib/markdown/history.d.ts +59 -0
- package/dist/types/lib/markdown/hotkeys.d.ts +63 -0
- package/dist/types/lib/markdown/image-pipeline.d.ts +173 -0
- package/dist/types/lib/markdown/images.d.ts +138 -0
- package/dist/types/lib/markdown/input.d.ts +38 -0
- package/dist/types/lib/markdown/keys.d.ts +34 -0
- package/dist/types/lib/markdown/paste.d.ts +9 -0
- package/dist/types/lib/markdown/position.d.ts +43 -0
- package/dist/types/lib/markdown/project.d.ts +88 -0
- package/dist/types/lib/markdown/reconcile.d.ts +63 -0
- package/dist/types/lib/markdown/surface.d.ts +236 -0
- package/dist/types/lib/motion.d.ts +30 -0
- package/dist/types/lib/pad.d.ts +6 -0
- package/dist/types/lib/paged-window/index.d.ts +2 -0
- package/dist/types/lib/paged-window/layout.d.ts +21 -0
- package/dist/types/lib/paged-window/list-owner.d.ts +12 -0
- package/dist/types/lib/paged-window/records-binding.d.ts +102 -0
- package/dist/types/lib/paged-window/store.d.ts +307 -0
- package/dist/types/lib/paged-window/use-measured-pitch.d.ts +34 -0
- package/dist/types/lib/paged-window/use-page-visibility.d.ts +20 -0
- package/dist/types/lib/paged-window/use-paged-window.d.ts +61 -0
- package/dist/types/lib/paged-window/use-scroll-root.d.ts +18 -0
- package/dist/types/lib/persist.d.ts +57 -0
- package/dist/types/lib/preference-values.d.ts +72 -0
- package/dist/types/lib/preferences.d.ts +26 -0
- package/dist/types/lib/reads/hooks.d.ts +49 -0
- package/dist/types/lib/reads/index.d.ts +5 -0
- package/dist/types/lib/reads/optimistic.d.ts +119 -0
- package/dist/types/lib/reads/refetch.d.ts +83 -0
- package/dist/types/lib/reads/slots.d.ts +137 -0
- package/dist/types/lib/reads/types.d.ts +155 -0
- package/dist/types/lib/realtime/hooks.d.ts +38 -0
- package/dist/types/lib/realtime/index.d.ts +4 -0
- package/dist/types/lib/realtime/provider.d.ts +38 -0
- package/dist/types/lib/realtime/registry.d.ts +225 -0
- package/dist/types/lib/realtime/types.d.ts +242 -0
- package/dist/types/lib/records/define-record-type.d.ts +29 -0
- package/dist/types/lib/records/hooks.d.ts +46 -0
- package/dist/types/lib/records/index.d.ts +5 -0
- package/dist/types/lib/records/store.d.ts +289 -0
- package/dist/types/lib/records/types.d.ts +195 -0
- package/dist/types/lib/records/wire.d.ts +96 -0
- package/dist/types/lib/reduced-motion-help.d.ts +23 -0
- package/dist/types/lib/scroll-caret.d.ts +6 -0
- package/dist/types/lib/sim/createSimStore.d.ts +18 -0
- package/dist/types/lib/sim/index.d.ts +5 -0
- package/dist/types/lib/sim/latency.d.ts +10 -0
- package/dist/types/lib/sim/registry.d.ts +14 -0
- package/dist/types/lib/sim/settings.d.ts +11 -0
- package/dist/types/lib/sim/types.d.ts +3 -0
- package/dist/types/lib/submit-shortcut.d.ts +24 -0
- package/dist/types/lib/syntax/index.d.ts +16 -0
- package/dist/types/lib/syntax/languages/bash.d.ts +1 -0
- package/dist/types/lib/syntax/languages/css.d.ts +1 -0
- package/dist/types/lib/syntax/languages/html.d.ts +17 -0
- package/dist/types/lib/syntax/languages/index.d.ts +33 -0
- package/dist/types/lib/syntax/languages/javascript.d.ts +22 -0
- package/dist/types/lib/syntax/languages/json.d.ts +1 -0
- package/dist/types/lib/syntax/languages/mongodb.d.ts +1 -0
- package/dist/types/lib/syntax/languages/plain.d.ts +9 -0
- package/dist/types/lib/syntax/languages/sql.d.ts +4 -0
- package/dist/types/lib/syntax/languages/vue.d.ts +1 -0
- package/dist/types/lib/syntax/languages/yaml.d.ts +1 -0
- package/dist/types/lib/syntax/markdown/frames.d.ts +145 -0
- package/dist/types/lib/syntax/markdown/grammar.d.ts +1 -0
- package/dist/types/lib/syntax/markdown/index.d.ts +5 -0
- package/dist/types/lib/syntax/markdown/inline.d.ts +21 -0
- package/dist/types/lib/syntax/markdown/parse.d.ts +15 -0
- package/dist/types/lib/syntax/markdown/refs.d.ts +47 -0
- package/dist/types/lib/syntax/markdown/render.d.ts +25 -0
- package/dist/types/lib/syntax/markdown/spans.d.ts +84 -0
- package/dist/types/lib/syntax/markdown/types.d.ts +108 -0
- package/dist/types/lib/syntax/registry.d.ts +37 -0
- package/dist/types/lib/syntax/tokenize.d.ts +17 -0
- package/dist/types/lib/syntax/types.d.ts +119 -0
- package/dist/types/lib/time/index.d.ts +4 -0
- package/dist/types/lib/time/instant.d.ts +2 -0
- package/dist/types/lib/time/plain.d.ts +61 -0
- package/dist/types/lib/time/relativeAge.d.ts +18 -0
- package/dist/types/lib/time/relativeClock.d.ts +8 -0
- package/dist/types/lib/time/types.d.ts +87 -0
- package/dist/types/lib/time/zone.d.ts +106 -0
- package/dist/types/lib/use-controllable.d.ts +14 -0
- package/dist/types/lib/use-fill-height.d.ts +26 -0
- package/dist/types/lib/use-hydrated.d.ts +8 -0
- package/dist/types/lib/use-media-query.d.ts +29 -0
- package/dist/types/lib/use-relabel-base-ui-dismiss.d.ts +6 -0
- package/dist/types/lib/use-release-snap-drag.d.ts +25 -0
- package/dist/types/lib/use-roving-options.d.ts +10 -0
- package/dist/types/lib/values/absent.d.ts +7 -0
- package/dist/types/lib/values/boolean.d.ts +29 -0
- package/dist/types/lib/values/currency.d.ts +22 -0
- package/dist/types/lib/values/date.d.ts +30 -0
- package/dist/types/lib/values/datetime.d.ts +48 -0
- package/dist/types/lib/values/index.d.ts +5 -0
- package/dist/types/lib/values/locale-date.d.ts +34 -0
- package/dist/types/lib/values/number.d.ts +27 -0
- package/dist/types/pure.d.ts +48 -0
- package/package.json +136 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sources":["../../../src/lib/paged-window/store.ts"],"sourcesContent":["/* ============================================================================\n PAGED WINDOW — the headless model behind a list that renders only a few pages\n of a much longer server-side list, and remembers the rows it has loaded.\n DX-4540, DX-5521.\n\n WHAT IT IS FOR. A board lane can hold hundreds of cards. Loading every one\n makes the board slow to open and heavy to render; loading none until asked\n makes the lane's length (the scrollbar) a lie. This keeps the TRUTH about the\n length (`total`, which the server reports) and renders only the CONTENT of the\n few pages near the viewer. A scrollbar jump to the middle loads the pages\n there and renders only them; the pages loaded before are kept, not rendered.\n\n THE WINDOW. `windowPages` pages are resident (rendered), centred on the\n `anchorPage` (the page the viewer is looking at): the anchor, the page before\n and the page after, for the default of three. A page outside it is not\n resident: it keeps its rows (see ROWS ARE KEPT) and a read of it still in\n flight is aborted (at the settle, see THE WINDOW SETTLES BEFORE ITS READS MOVE).\n The after-page and before-page are the PREFETCH — there is no separate\n prefetch rule — so scrolling in either direction meets content that is\n already there.\n\n ROWS ARE KEPT, THE WINDOW BOUNDS WHAT IS RENDERED (DX-5521). A page that\n leaves the window keeps its rows: they move from the resident pages to a\n `retained` map (no request). The snapshot's `pages`, `items` and `offset` -\n what a view draws - are only the resident window, so the DOM stays the page in\n view and its neighbours however long the lane is. A retained page that\n re-enters the window is resident again at once, `ready`, with its old rows: no\n loading status (no skeleton) and no request. Rows are dropped only on\n `reset()` (a query change), when the list shrinks beneath them, and on\n `setMode(\"count\")`, which tracks no rows at all. A page that was never loaded\n is `loading` when it enters the window, as before.\n NO EXTRA CAP ON WHAT IS KEPT (DX-5521): a card's row is small and a lane is\n bounded by the cards its board holds, so memory grows with the lane's length\n only as far as the viewer has scrolled; revisit if a list ever holds tens of\n thousands of rows.\n FRESHNESS OF A RETAINED PAGE. `invalidatePage` / `invalidateAll` reach it too,\n as STALE (a flag, no request: nobody is looking at it). When a stale page\n re-enters the window it is re-read in place, stale-while-revalidate: it stays\n `ready` and keeps drawing its old rows with `refreshing: true` until the new\n ones arrive, never a skeleton for a page that has rows. A response that\n changes the list's total marks every other page that has no read in flight\n stale: everything past the change shifted.\n INVALIDATING BY ROW. `invalidateWhere(test)` marks stale every page, resident\n or retained, that has a row passing `test`: a resident one is re-read in place\n now, a retained one is re-read when it returns. It is how a consumer reaches\n the pages it cannot name (a card's event has no page number, and the page that\n shows the card may be outside the window). `holdsRow(test)` asks which loaded\n rows are CURRENT: a stale page, kept or in the window (one drawn back from\n memory before its re-read, or one a changed total marked), is out of date by\n definition (an event already said something on it changed), so its rows do\n not count.\n\n ONE ROW KEY, ONE PAGE (DX-5521). Pages are read at different moments, so\n after a card is created or moved above the viewer, a page drawn from its old\n rows (stale, or refreshing) and a page read since can both hold the same row:\n the old page's last row is the new page's first. A view draws one element per\n row, so the snapshot never names one key (`getKey`) on two pages: the copy on\n the page whose rows are current wins, a current page over an out-of-date one,\n then the newer read over the older. The other copy is left out of its page,\n which is one row short until its own re-read answers. A page that loses no row\n keeps its items array, so nothing re-renders for it.\n A CURRENT page that loses a row is provably out of date (two pages that are both\n right cannot share a row), so it is re-read in place (out of date while it is, so\n it ranks below the current pages and the page it lost to keeps the row), which\n closes the gap. Every such page is found in one pass: marking a page out of date\n only lowers its rank, so it never makes another page lose a row. The re-read\n follows the settle rule like any other read: at once when the window is\n settled; while the viewer is still moving the page is marked stale and read at\n the settle (as `drawFromMemory` does), so no read starts before it. Frozen, no\n page can lose a row (every answer is held), so nothing is looked for.\n ONE RE-READ PER LOSS UNTIL SOMETHING ELSE INVALIDATES IT. A server whose paging\n is not a total order (two rows tie on the sort key, and two reads break the tie\n differently) can answer the same row on two pages every time; each answer then\n makes the other page lose it, and re-reading the loser would loop for as long\n as the pages are in view. So a page whose latest read was sent because it lost a\n row (`lossRead`) is not re-read for a loss again: it stays one row short and the\n dedup alone decides, until an invalidation reads it (`invalidatePage`,\n `invalidateWhere`, `invalidateAll`, or a changed total marking it stale). Each\n invalidation of a page therefore buys it at most one loss re-read. The cost: a\n later, real shift that makes such a page lose a row without invalidating it\n leaves it one row short until its next invalidation, as before this re-read\n existed.\n\n THE LOADED RUN. What a board is handed (`items`) is ONE CONTIGUOUS RUN of\n ready pages, with the global position of its first item (`offset`). Pages\n arrive in any order, so {ready, loading, ready} happens; the run is then the\n longest unbroken stretch (the lowest on a tie) and the page past the hole\n waits, unshown, for the page that closes it. That is what makes \"the card at\n local index i is at global position offset + i\" TRUE, which every position a\n person is told (\"position 221 of 500\") and every neighbour a server is sent\n depends on.\n THE ONE EXCEPTION: while a page is one row short (it lost a row it shares with\n another page, see ONE ROW KEY, ONE PAGE), the rows after it in the run are one\n position off offset + i, so a position or neighbour taken from an index there is\n one off until a read of the page closes the gap: its loss re-read, or, for a\n page whose loss re-read already answered (ONE RE-READ PER LOSS), its next\n invalidation.\n\n TWO MODES. `pages` (the default) loads cards. `count` loads NOTHING but the\n list's length, through a separate `loadCount`, and keeps it live: a hidden\n lane still needs a true badge and a true \"is it empty\", and `invalidateAll`\n refreshes it. Switching to `count` drops every page (and aborts their\n requests) but never leaves a stale length behind — the count is re-asked.\n\n THE WINDOW SETTLES BEFORE ITS READS MOVE (DX-4614). The viewer's page is\n reported continuously while they scroll, and a fast scroll or a scrollbar drag\n passes through every page between where they were and where they stop. Loading\n each one would send a read per page crossed and, by the time it answered, the\n view would be somewhere else. So `setAnchorPage` records where the viewer is\n (`anchorPage` follows at once) and the READS follow once the anchor has been\n still for `settleMs` (`PAGED_WINDOW_SETTLE_MS`, 200): until then no page of\n the new position is requested and no read already running is aborted, so pages\n passed through are never requested and a return costs no request. At the\n settle the window changes in one step: the pages that left it are released\n (their reads aborted through their `signal`, their rows kept), the\n destination's missing pages are requested, and a stale page back in it is\n re-read. `settleMs: 0` moves the window synchronously. Only the anchor\n settles: the first load, a reset, a thaw after a drag and a refresh act at\n once, because none of them is the viewer still moving.\n WHAT IS DRAWN DOES NOT WAIT FOR THE SETTLE (DX-5521). A page already in memory\n costs no read to draw, so when the viewer moves (`drawFromMemory`) the retained\n pages of the destination window become resident at once, a stale one with its\n old rows and its re-read waiting for the settle, and the pages outside that\n window leave the drawing: a ready one goes to `retained`; one whose read is\n still in flight stays resident, undrawn, until it answers or the settle comes\n (the viewer may be back before then, and a return must cost nothing). A\n never-loaded neighbour is not requested until the viewer is still. If nothing\n of the destination is in memory the old window stays on screen until the\n settle. A window entirely in memory is drawn at once like any other, and its\n settle has only the stale pages to read.\n\n RECORD MODE (DXUI-77, PLAN-32 R-1). With the `records` option the window keeps no row copies: each page's rows are written into the\n record store (`records-binding.ts`) and the window holds their KEYS. Everything above is about keys either way: ONE ROW KEY, ONE PAGE, the\n loaded run, the settle, freeze and the loss re-read read a row through `getKey` on the row the store hands back. What changes is where a\n row comes from (the store, at build time, so an edit to a record shows with no page read) and what the window must do about it: subscribe\n to the keys of its resident pages, retain every key it holds, draw a record moved by an optimistic layer where `membership.placeIn` says it\n belongs (a `count` window draws nothing but still counts the arrivals), and re-read itself when the store was cleared under it. The tenant a page is written under is read when its request is SENT.\n\n FRAMEWORK-AGNOSTIC ON PURPOSE, the way `lib/dnd/session.ts` is: a plain\n subscribable store. `useSyncExternalStore` consumes it, and the tests drive\n the machine without React.\n\n WHAT STALE MEANS. A page is re-read IN PLACE (`invalidatePage`): its old\n items stay visible until the new ones arrive, because swapping real cards for\n a skeleton while someone reads them destroys the context they were reading.\n A response is applied only if its request is still the current one; an\n invalidate, a release or a reset all abandon the in-flight request (and abort\n its `signal`), so a slow answer can never overwrite a newer one. A page drawn\n from memory whose re-read waits for the settle is not re-read by an\n invalidation in between: its read is already due. A page that left the drawing\n and only stays to finish a read is not re-requested either: nobody can see it,\n so the read (whose answer predates the invalidation) is abandoned and the page\n is kept stale.\n\n A FAILED PAGE STAYS FAILED until someone retries it. Re-requesting on the\n next sync would be a retry loop against a server that is already refusing.\n A REFRESH THAT FAILS DROPS THE PAGE'S OLD ITEMS: the page is now `error` and\n shows a Retry row, and cards the server has since changed, shown next to a\n Retry row, would present stale data as current.\n\n WHILE FROZEN NOTHING CHANGES. Nothing is loaded or released (not because the\n viewer moved, not because the list shrank), no refresh starts, and no response\n is applied: an `invalidatePage` / `invalidateAll` is queued, and an answer that\n arrives is held. A drag has a card in the air over a layout it measured at\n pickup; a refresh that empties a page, a response that shrinks the total and\n hides the pages past it, or a page of cards arriving above the carried one would\n each move what the drag is dropping onto. On thaw everything is applied in one\n order: every held answer is applied (they may change the total) and only then\n is the window brought to the anchor, ONCE (releases and loads), then the queued\n refreshes run — of the pages that are still resident. A page that leaves in that\n one move with a refresh queued is kept STALE, so the refresh is not lost with\n the queue: it is re-read in place when the page returns.\n\n THE ONE EXCEPTION IS `reset()`. A query change makes a different list, so the\n resident pages, the retained rows, queued refreshes and the frozen layout they\n belonged to are gone: it drops everything and starts the new list's first\n request at once, frozen or not. The new list's own answers are held like any\n other until thaw; a held answer of the OLD list is inert, because every\n request carries a token and the new pages have new ones.\n ========================================================================= */\n\nimport { getRecordStoreTenant, recordStoreVersion } from \"../records/store\";\nimport { RecordsBinding, type PagedWindowRecordsOptions, type RunRow } from \"./records-binding\";\n\nexport type { PagedWindowRecordsOptions, PlacementEdges } from \"./records-binding\";\n\nexport interface PageResponse<T> {\n /** This page's items, in order. Fewer than `pageSize` only for the last page. */\n items: readonly T[];\n /** The WHOLE list's length right now. Every response refreshes it. */\n total: number;\n}\n\nexport interface LoadPageContext {\n /** Aborted when the page is dropped, re-requested or the window is reset. */\n signal: AbortSignal;\n}\n\nexport type LoadPage<T> = (page: number, context: LoadPageContext) => Promise<PageResponse<T>>;\n\n/** Answers the list's length alone — no items. What a hidden (`count` mode) lane asks. */\nexport type LoadCount = (context: LoadPageContext) => Promise<number>;\n\nexport type PagedWindowMode = \"pages\" | \"count\";\n\n/** How long the viewer's page must stay put before the window moves to it, in ms. */\nexport const PAGED_WINDOW_SETTLE_MS = 200;\n\nexport type PageStatus = \"loading\" | \"ready\" | \"error\";\n\nexport interface PageSnapshot<T> {\n page: number;\n status: PageStatus;\n /**\n * Empty unless `ready`. A page being re-read keeps its old items and stays `ready`, less any row a page with current rows also holds: one\n * key is never on two pages (DX-5521).\n */\n items: readonly T[];\n /** True while a `ready` page is being re-read in place. */\n refreshing: boolean;\n /** What the load rejected with. Only on `error`. */\n error: unknown;\n /** Part of the loaded run — its items are in `items`. A ready page past a hole is not, until the hole closes. */\n shown: boolean;\n}\n\nexport interface PagedWindowSnapshot<T> {\n mode: PagedWindowMode;\n /** The list's length as the latest response reported it; null before the first. */\n total: number | null;\n pageSize: number;\n /** 0 until `total` is known, then `ceil(total / pageSize)`. */\n pageCount: number;\n /** The page the viewer is looking at. */\n anchorPage: number;\n /** Counts resets, so a view can scroll back to the top when the query changed. */\n epoch: number;\n /** The resident pages (the window), ascending. At most `windowPages` of them; retained pages outside it are not listed. */\n pages: readonly PageSnapshot<T>[];\n /** The loaded run: the items of the shown pages, in list order. At most `windowPages * pageSize`. */\n items: readonly T[];\n /** The position in the whole list of `items[0]`; 0 when nothing is loaded. */\n offset: number;\n /** What the last `loadCount` rejected with; undefined otherwise. */\n countError: unknown;\n}\n\nexport interface PagedWindowOptions<T> {\n pageSize: number;\n /**\n * A row's identity. One key is never on two pages of a snapshot (see ONE ROW KEY, ONE PAGE in the store's header). It is read once, when the\n * store is created, and called on any row at any time: it must be a pure function of the row (the same row always gives the same key, with no\n * state of its own or from the caller's render).\n */\n getKey: (row: T) => string | number;\n /** How many pages are resident (rendered) at once; the rows of pages outside it are kept, see the store's header. @default 3 */\n windowPages?: number;\n loadPage: LoadPage<T>;\n /** Required to use `count` mode. */\n loadCount?: LoadCount;\n /** @default \"pages\" */\n mode?: PagedWindowMode;\n /**\n * How long the viewer's page must stay put before the window moves to it; 0\n * moves it synchronously. A negative or fractional value throws.\n * @default PAGED_WINDOW_SETTLE_MS\n */\n settleMs?: number;\n /**\n * DXUI-77: hold record keys, not row copies. Each page's rows are written into the record store and the window keeps only their keys; `items` and\n * `pages[].items` are read back from the store, so an edit to a record shows with no page read (PLAN-32 R-1). See `records-binding.ts`. Without it\n * the window holds its rows itself, as it always has.\n */\n records?: PagedWindowRecordsOptions<T>;\n}\n\nconst NO_KEYS: readonly string[] = Object.freeze([]);\n\ninterface ResidentPage<T> {\n status: PageStatus;\n /** The page's rows. Empty in record mode, where `keys` holds them. */\n items: readonly T[];\n /** DXUI-77: record mode's `items`: the record keys of the page, in page order. */\n keys: readonly string[];\n /** DXUI-77: the tenant read when this page's request was SENT; what its answer is written under. */\n tenant: string | number | undefined;\n refreshing: boolean;\n /** DX-5521: the rows may be out of date and no read is in flight; they stay drawn, and carry this to `retained` if the page leaves. */\n stale: boolean;\n /** DX-5521: a retained stale page drawn at once by a move; its read waits for the settle. */\n readDue: boolean;\n /** DX-5521: left the drawn window by a move that has not settled, and stays resident only until its read in flight answers or the settle comes; not part of the snapshot. */\n outside: boolean;\n /**\n * DX-5521: the page's latest read (sent, or due at the settle) was asked for because the page lost a row, and nothing has invalidated it\n * since; it is not re-read for a loss again (ONE RE-READ PER LOSS in the header).\n */\n lossRead: boolean;\n error: unknown;\n /**\n * DX-5521: the token of the read `items` came from (0 before any); the newer read keeps a row two pages share. Tokens are handed out when a\n * read is SENT, so this orders reads by when they were sent, not by when they were answered.\n */\n readSeq: number;\n /** Identifies the current request; a response carrying another token is dropped. */\n token: number;\n controller: AbortController | null;\n}\n\n/** DX-5521: the rows of a page that left the window; `stale` once something invalidated it, so it is re-read when it re-enters. */\ninterface RetainedPage<T> {\n items: readonly T[];\n keys: readonly string[];\n stale: boolean;\n /** DX-5521: as `ResidentPage.lossRead`, carried through leaving the window and coming back. */\n lossRead: boolean;\n readSeq: number;\n}\n\n/** DX-5521: something said a page's rows changed: they are stale, and the read that follows answers that, not a loss, so its damping is lifted. */\nfunction markInvalidated(page: { stale: boolean; lossRead: boolean }): void {\n page.stale = true;\n page.lossRead = false;\n}\n\n/**\n * The pages to hold for an anchor: `windowPages` of them centred on it (the\n * extra page of an even window goes after), clipped to `[0, pageCount)`. Pure,\n * so the rule is testable without a store.\n */\nexport function windowPageNumbers(\n anchorPage: number,\n pageCount: number,\n windowPages: number,\n): number[] {\n const before = Math.floor((windowPages - 1) / 2);\n const first = Math.max(0, anchorPage - before);\n const last = Math.min(pageCount - 1, anchorPage + (windowPages - 1 - before));\n const pages: number[] = [];\n for (let page = first; page <= last; page++) pages.push(page);\n return pages;\n}\n\n/** DX-5521: the page's rows may be behind the list: marked stale, or being re-read. */\nfunction isOutOfDate<T>(entry: ResidentPage<T>): boolean {\n return entry.stale || entry.refreshing;\n}\n\nexport class PagedWindowStore<T> {\n private readonly pageSize: number;\n private readonly windowPages: number;\n private readonly settleMs: number;\n private readonly getKey: (row: T) => string | number;\n private loadPage: LoadPage<T>;\n private loadCount: LoadCount | undefined;\n\n /** The resident pages: the window around the applied anchor. */\n private resident = new Map<number, ResidentPage<T>>();\n /** DX-5521: ready pages outside the window, rows kept (see the header). */\n private retained = new Map<number, RetainedPage<T>>();\n private total: number | null = null;\n /** Where the viewer is; moves the instant they do. */\n private anchor = 0;\n /** The anchor the resident pages' READS were last synced to; differs from `anchor` while the viewer is still moving, or frozen. */\n private appliedAnchor = 0;\n /** Moves the window to `anchor` once it has been still for `settleMs`; null when no move is waiting. */\n private settleTimer: ReturnType<typeof setTimeout> | null = null;\n private mode: PagedWindowMode;\n private frozen = false;\n private epoch = 0;\n private nextToken = 1;\n private countRequest: { token: number; controller: AbortController } | null = null;\n /** Answers that arrived while frozen, applied in arrival order on thaw. */\n private heldAnswers: (() => void)[] = [];\n /** Pages whose refresh was asked for while frozen. */\n private queuedPages = new Set<number>();\n /** The length's refresh (count mode) was asked for while frozen. */\n private queuedCount = false;\n private countError: unknown = undefined;\n /** DXUI-83: the token of the last count read that settled, answered or failed; a count window's placed rows wait on it like a page window's on its pages' `readSeq`. */\n private countSettledSeq = 0;\n private snapshot: PagedWindowSnapshot<T>;\n private listeners = new Set<() => void>();\n /** DXUI-77: the record mode, or null when the window holds its rows itself. */\n private readonly rec: RecordsBinding<T> | null;\n /** DXUI-77: a record changed while frozen; the thaw looks at it once. */\n private recordsPending = false;\n /** DXUI-77: the store tenant the pages were last requested under; a different one now means the store was cleared under them. */\n private tenantSeen: string | number | undefined = undefined;\n /** DXUI-77: the store version the window last looked at; one flush calls the handler once per changed key, and one look covers them all. */\n private recordsVersion = -1;\n /** DXUI-77: a held key unknown to the store already sent the window to re-read; no answer has made every key known since. */\n private unknownReread = false;\n\n constructor({\n pageSize,\n getKey,\n windowPages = 3,\n loadPage,\n loadCount,\n mode = \"pages\",\n settleMs = PAGED_WINDOW_SETTLE_MS,\n records,\n }: PagedWindowOptions<T>) {\n if (!Number.isInteger(pageSize) || pageSize < 1) {\n throw new Error(`PagedWindowStore: pageSize must be a positive integer, got ${pageSize}.`);\n }\n if (!Number.isInteger(windowPages) || windowPages < 1) {\n throw new Error(`PagedWindowStore: windowPages must be a positive integer, got ${windowPages}.`);\n }\n if (typeof getKey !== \"function\") {\n throw new Error(\"PagedWindowStore: getKey is required; it names a row so one row is never drawn on two pages.\");\n }\n if (!Number.isInteger(settleMs) || settleMs < 0) {\n throw new Error(`PagedWindowStore: settleMs must be a non-negative integer, got ${settleMs}.`);\n }\n this.pageSize = pageSize;\n this.windowPages = windowPages;\n this.settleMs = settleMs;\n this.getKey = getKey;\n this.loadPage = loadPage;\n this.loadCount = loadCount;\n this.requireCountLoader(mode);\n this.mode = mode;\n this.rec = records ? new RecordsBinding(records, this.onRecordsChanged, getKey) : null;\n this.snapshot = this.build();\n }\n\n /**\n * Replace the loaders. The React binding calls this after every commit so a\n * consumer's loaders can close over fresh state without the store being\n * rebuilt (rebuilding drops every resident page). A change in WHAT is loaded is a\n * `reset`, never this.\n */\n setLoaders(loadPage: LoadPage<T>, loadCount: LoadCount | undefined, records?: PagedWindowRecordsOptions<T>): void {\n this.loadPage = loadPage;\n this.loadCount = loadCount;\n if (records === undefined) return;\n if (!this.rec) throw new Error(\"PagedWindowStore: records cannot be added after the window is created; mount a new list.\");\n this.rec.update(records);\n }\n\n getSnapshot = (): PagedWindowSnapshot<T> => this.snapshot;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n /**\n * The viewer moved to another page. The window follows once they have stayed\n * there for `settleMs`; while frozen it follows on thaw.\n */\n setAnchorPage(page: number): void {\n if (!Number.isInteger(page) || page < 0) {\n throw new Error(`PagedWindowStore: anchor page must be a non-negative integer, got ${page}.`);\n }\n if (page === this.anchor) return;\n this.anchor = page;\n this.clearSettle();\n if (this.frozen) return this.publish();\n if (page === this.appliedAnchor || this.settleMs === 0) return this.applyAnchor();\n this.drawFromMemory();\n this.settleTimer = setTimeout(() => {\n this.settleTimer = null;\n this.applyAnchor();\n }, this.settleMs);\n this.publish();\n }\n\n /**\n * While true nothing about the window changes: it neither loads nor drops\n * pages, starts no refresh and applies no answer, whatever the anchor or the\n * total does (all of it waits for the thaw). A drag needs it: the carried card\n * is mounted in its page, and dropping that page mid-drag would unmount the\n * card and cancel the drag. Only `reset()` ignores it — a query change is a\n * different list.\n */\n setFrozen(frozen: boolean): void {\n if (frozen === this.frozen) return;\n this.frozen = frozen;\n /* A move waiting for the viewer to be still is the thaw's to make, at once: the drag is over. */\n this.clearSettle();\n if (!frozen) this.thaw();\n this.publish();\n }\n\n /** `count` holds and requests no cards, only the length (see the file header). */\n setMode(mode: PagedWindowMode): void {\n if (mode === this.mode) return;\n this.requireCountLoader(mode);\n this.mode = mode;\n if (mode === \"count\") {\n this.rec?.reset();\n this.requestCount();\n } else {\n this.abortCount();\n this.queuedCount = false;\n }\n this.sync();\n }\n\n /** The query changed: forget everything, return to the first page. */\n reset(): void {\n this.dropAll();\n this.total = null;\n this.anchor = 0;\n this.appliedAnchor = 0;\n this.epoch += 1;\n if (this.mode === \"count\") this.requestCount();\n this.reconcile(true);\n this.publish();\n }\n\n /** Re-read one resident page in place. A retained page is marked stale and re-read in place when it re-enters the window; a page never loaded loads fresh when it is next wanted. */\n invalidatePage(page: number): void {\n const entry = this.resident.get(page);\n if (!entry) {\n const kept = this.retained.get(page);\n if (kept) markInvalidated(kept);\n return;\n }\n this.refreshResident(page, entry);\n this.publishUnlessFrozen();\n }\n\n /**\n * DX-5521: invalidate every page, resident or retained, that has a row passing `rowTest`: a resident one is re-read in place, a retained\n * one is marked stale and re-read when it re-enters the window. Returns whether any page matched.\n */\n invalidateWhere(rowTest: (row: T) => boolean): boolean {\n let matched = false;\n for (const [page, entry] of this.resident) {\n if (!this.loadedRows(entry).some(rowTest)) continue;\n matched = true;\n this.refreshResident(page, entry);\n }\n for (const kept of this.retained.values()) {\n if (!this.loadedRows(kept).some(rowTest)) continue;\n matched = true;\n markInvalidated(kept);\n }\n if (matched) this.publishUnlessFrozen();\n return matched;\n }\n\n /**\n * DX-5521: whether any CURRENT loaded row, resident or retained, passes `rowTest`. A stale page, in the window or kept, does not count:\n * something already said its rows changed, so a row it shows may no longer be where it shows it (`invalidateWhere` still marks it). Changes\n * nothing.\n */\n holdsRow(rowTest: (row: T) => boolean): boolean {\n for (const entry of this.resident.values()) if (!entry.stale && this.loadedRows(entry).some(rowTest)) return true;\n for (const kept of this.retained.values()) if (!kept.stale && this.loadedRows(kept).some(rowTest)) return true;\n return false;\n }\n\n /** Re-read every resident page in place and mark every retained one stale; in `count` mode, re-ask the length. */\n invalidateAll(): void {\n for (const kept of this.retained.values()) markInvalidated(kept);\n if (this.mode === \"count\") {\n if (this.frozen) this.queuedCount = true;\n else this.requestCount();\n }\n for (const [page, entry] of this.resident) this.refreshResident(page, entry);\n this.publishUnlessFrozen();\n }\n\n /**\n * A resident page's rows are out of date: read it again now, or at the thaw when frozen (a page that leaves the window by then is kept stale,\n * see `release`). No notification: callers publish. A page drawn from memory by a move (`readDue`) is read at the settle already, so it is not\n * read earlier. A page outside the drawing that is only finishing a read (`outside`) is nobody's to look at: the read, whose answer now\n * predates the invalidation, is abandoned and the page is kept stale, to be re-read if the viewer returns. Whichever read follows answers an\n * invalidation, so a loss re-read's damping is lifted (`lossRead`).\n */\n private refreshResident(page: number, entry: ResidentPage<T>): void {\n entry.lossRead = false;\n if (entry.readDue) return;\n if (this.frozen) this.queuedPages.add(page);\n else if (entry.outside) this.leave(page, entry, true);\n else this.request(page, entry);\n }\n\n /** Nothing a view draws changes while frozen (the refreshes wait for the thaw), so nobody is told. */\n private publishUnlessFrozen(): void {\n if (!this.frozen) this.publish();\n }\n\n /** Load the first window (or the length). The binding calls it on mount, and again after a `stop`. */\n start(): void {\n this.rec?.attach(() => [...this.heldKeys()], () => this.invalidateAll());\n if (this.mode === \"count\") this.requestCount();\n this.applyAnchor();\n }\n\n /** Abort every request and release every page. The binding calls it on unmount. */\n stop(): void {\n this.dropAll();\n this.rec?.detach();\n }\n\n private requireCountLoader(mode: PagedWindowMode): void {\n if (mode === \"count\" && this.loadCount === undefined) {\n throw new Error(\"PagedWindowStore: count mode needs a loadCount; none was given.\");\n }\n }\n\n private pageCount(): number {\n return this.total === null ? 0 : Math.ceil(this.total / this.pageSize);\n }\n\n /**\n * Pages to hold now. None in `count` mode. Page 0 alone before the first\n * response (the count is unknown) and for an empty list: an empty page is\n * still resident, because it is what `invalidateAll` re-reads when the list gets\n * its first item — an empty lane that holds nothing could never find out it\n * was no longer empty.\n */\n private wanted(viewerPage = this.appliedAnchor): number[] {\n if (this.mode === \"count\") return [];\n if (this.total === null || this.total === 0) return [0];\n /* A list that shrank under the viewer leaves the anchor past its new end;\n the window follows the last page until the view reports a real one. */\n const anchor = Math.min(viewerPage, this.pageCount() - 1);\n return windowPageNumbers(anchor, this.pageCount(), this.windowPages);\n }\n\n /** Bring the resident pages to the wanted ones — unless frozen, when that waits for the thaw. */\n private sync(): void {\n this.reconcile();\n this.publish();\n }\n\n /** The viewer has settled on `anchor`: the window moves to it, in one step. */\n private applyAnchor(): void {\n this.clearSettle();\n if (this.frozen) return;\n this.appliedAnchor = this.anchor;\n this.sync();\n }\n\n private clearSettle(): void {\n if (this.settleTimer === null) return;\n clearTimeout(this.settleTimer);\n this.settleTimer = null;\n }\n\n /**\n * Moves the resident pages to the window around `appliedAnchor` - which only\n * `applyAnchor`, `thaw` and `reset` move, so a response arriving while the\n * viewer is still moving brings in no READ for a page of the unsettled position\n * (it only draws what memory already holds, `drawFromMemory`).\n * `force` is `reset()`'s alone: it brings the window to its (new) list even\n * while frozen.\n */\n private reconcile(force = false): void {\n if (this.frozen && !force) return;\n if (this.anchor !== this.appliedAnchor && !force) return this.drawFromMemory();\n const wanted = new Set(this.wanted());\n this.release((page) => !wanted.has(page), false);\n for (const page of wanted) {\n const entry = this.resident.get(page);\n if (entry) {\n /* DX-5521: drawn from memory by a move that was still settling, or marked by a loss before the settle; its read was waiting for this. */\n if (entry.readDue) this.request(page, entry, entry.lossRead);\n continue;\n }\n const resident = this.promote(page);\n if (resident) {\n if (resident.stale) this.request(page, resident, resident.lossRead);\n continue;\n }\n const fresh: ResidentPage<T> = { status: \"loading\", items: [], keys: NO_KEYS, tenant: undefined, refreshing: false, stale: false, readDue: false, outside: false, lossRead: false, error: undefined, readSeq: 0, token: 0, controller: null };\n this.resident.set(page, fresh);\n this.request(page, fresh);\n }\n }\n\n /**\n * DX-5521: a move the viewer has not settled on draws what memory already holds for it: the retained pages of the destination window become\n * resident (a stale one with its old rows and its read due at the settle) and the pages outside that window leave the drawing. No read starts\n * and none is aborted, so a return before the settle costs nothing (DX-4614). When nothing of the destination is in memory the window stays\n * where it is, so the old pages remain on screen until the settle.\n */\n private drawFromMemory(): void {\n const wanted = new Set(this.wanted(this.anchor));\n const inMemory = [...wanted].filter((page) => this.resident.has(page) || this.retained.has(page));\n if (inMemory.length === 0) return;\n this.release((page) => !wanted.has(page), true);\n for (const page of inMemory) {\n const resident = this.promote(page);\n if (resident?.stale) resident.readDue = true;\n }\n }\n\n /**\n * Resident pages that fail `leaves` go: a ready one keeps its rows in `retained` (stale if they may be out of date); one never loaded has\n * none to keep. A read in flight is aborted, unless `keepReads` (a move not yet settled): that page stays resident but `outside` the drawing,\n * so the viewer coming back finds its read still running. Then the rows past the list's end (it shrank), and every row in count mode (no rows\n * are tracked there), are dropped: they belong to no list anyone can scroll.\n */\n private release(leaves: (page: number) => boolean, keepReads: boolean): void {\n for (const [page, entry] of this.resident) {\n entry.outside = false;\n if (!leaves(page)) continue;\n if (keepReads && entry.controller !== null) {\n entry.outside = true;\n continue;\n }\n this.leave(page, entry, false);\n }\n if (this.mode === \"count\") this.retained.clear();\n else if (this.total !== null) {\n for (const page of [...this.retained.keys()]) if (page >= this.pageCount()) this.retained.delete(page);\n }\n }\n\n /**\n * DX-5521: a resident page goes: a read in flight is aborted, a ready page keeps its rows in `retained`. They are stale if a read was cut short,\n * if the page was already stale, if an invalidation was queued for it while frozen (the queue is dropped with the page, so the mark is the only\n * trace), or if `stale` says an invalidation has just arrived. A page never loaded has no rows to keep. A loss re-read's damping goes with\n * the rows unless one of those invalidations lifts it.\n */\n private leave(page: number, entry: ResidentPage<T>, stale: boolean): void {\n entry.controller?.abort();\n this.resident.delete(page);\n const queued = this.queuedPages.delete(page);\n if (entry.status !== \"ready\") return;\n const invalidated = stale || queued;\n this.retained.set(page, {\n items: entry.items,\n keys: entry.keys,\n stale: invalidated || entry.refreshing || entry.stale,\n lossRead: !invalidated && entry.lossRead,\n readSeq: entry.readSeq,\n });\n }\n\n /** DX-5521: a retained page back in the window: resident at once and `ready` with its old rows, never `loading`. Undefined when nothing is kept for it. */\n private promote(page: number): ResidentPage<T> | undefined {\n const kept = this.retained.get(page);\n if (!kept) return undefined;\n this.retained.delete(page);\n const resident: ResidentPage<T> = { status: \"ready\", items: kept.items, keys: kept.keys, tenant: undefined, refreshing: false, stale: kept.stale, readDue: false, outside: false, lossRead: kept.lossRead, error: undefined, readSeq: kept.readSeq, token: 0, controller: null };\n this.resident.set(page, resident);\n return resident;\n }\n\n /** Everything the frozen window put off, in the order the header promises. */\n private thaw(): void {\n const answers = this.heldAnswers;\n this.heldAnswers = [];\n for (const apply of answers) apply();\n /* Once, after every answer is in: the window is brought to a total that\n already reflects all of them, never to an intermediate one. */\n this.appliedAnchor = this.anchor;\n this.reconcile();\n const pages = [...this.queuedPages];\n this.queuedPages.clear();\n for (const page of pages) {\n const entry = this.resident.get(page);\n if (entry) this.request(page, entry);\n }\n if (this.queuedCount) {\n this.queuedCount = false;\n this.requestCount();\n }\n /* A record changed while nothing could (DXUI-77): look at it once, now. */\n if (this.recordsPending) {\n this.recordsPending = false;\n this.applyRecordsChange();\n }\n }\n\n /** Start (or restart) a page's request; whatever was in flight is abandoned. `forLoss`: it is sent because the page lost a row (DX-5521). */\n private request(page: number, entry: ResidentPage<T>, forLoss = false): void {\n entry.controller?.abort();\n const controller = new AbortController();\n const token = this.nextToken++;\n entry.controller = controller;\n entry.token = token;\n if (this.rec) {\n /* DXUI-77: the tenant is read when the request goes out, never when it answers (a team-A answer that lands after a switch to B must not\n write into B), and it travels with the request's token to the write. */\n entry.tenant = getRecordStoreTenant();\n this.tenantSeen = entry.tenant;\n }\n entry.stale = false;\n entry.readDue = false;\n entry.lossRead = forLoss;\n if (entry.status === \"ready\") entry.refreshing = true;\n else {\n entry.status = \"loading\";\n entry.error = undefined;\n }\n this.loadPage(page, { signal: controller.signal }).then(\n (response) => this.settle(page, token, { ok: true, response }),\n (error: unknown) => this.settle(page, token, { ok: false, error }),\n );\n }\n\n private settle(\n page: number,\n token: number,\n outcome: { ok: true; response: PageResponse<T> } | { ok: false; error: unknown },\n ): void {\n /* An answer to a request that was since abandoned (re-requested, dropped,\n reset) changes nothing, so it costs nothing: no reconcile, no publish. */\n const entry = this.resident.get(page);\n if (!entry || entry.token !== token) return;\n if (this.frozen) {\n this.heldAnswers.push(() => this.applyPage(page, token, outcome));\n return;\n }\n /* The first response is what makes `total` known, and with it the pages\n around the anchor; a shrunken total is what drops the pages past its end.\n Both are `sync`'s. */\n this.applyPage(page, token, outcome);\n this.sync();\n }\n\n /**\n * Record an answer on its page — no window change, no notification: callers\n * sync once. Re-checks the token because a entry answer is replayed on thaw,\n * after which its request may have been abandoned.\n */\n private applyPage(\n page: number,\n token: number,\n outcome: { ok: true; response: PageResponse<T> } | { ok: false; error: unknown },\n ): void {\n const entry = this.resident.get(page);\n if (!entry || entry.token !== token) return;\n entry.controller = null;\n if (outcome.ok) {\n let keys: readonly string[] = NO_KEYS;\n if (this.rec) {\n /* DXUI-77: an answer for a tenant the store no longer serves is discarded whole, its `total` too, and the page asked again under the\n current one (the new request stamps it, so this cannot loop). */\n if (!RecordsBinding.tenantIsCurrent(entry.tenant)) return this.request(page, entry);\n keys = this.rec.write(outcome.response.items, entry.tenant);\n if (this.unknownReread && !keys.some((key) => this.rec!.isUnknown(key))) this.unknownReread = false;\n }\n entry.status = \"ready\";\n entry.items = this.rec ? [] : outcome.response.items;\n entry.keys = keys;\n entry.readSeq = token;\n entry.refreshing = false;\n entry.error = undefined;\n /* DX-5521: a new length shifts every page past the change; the rows kept outside the window are no longer the list's. A page whose\n read is in flight is not marked: its own answer is about to replace its rows, and the flag would outlive it. */\n if (this.total !== null && this.total !== outcome.response.total) {\n for (const kept of this.retained.values()) markInvalidated(kept);\n for (const [other, resident] of this.resident) if (other !== page && resident.controller === null) markInvalidated(resident);\n }\n this.total = outcome.response.total;\n return;\n }\n entry.status = \"error\";\n entry.items = [];\n entry.keys = NO_KEYS;\n entry.refreshing = false;\n entry.error = outcome.error;\n }\n\n private requestCount(): void {\n this.requireCountLoader(\"count\");\n this.countRequest?.controller.abort();\n const controller = new AbortController();\n const token = this.nextToken++;\n this.countRequest = { token, controller };\n /* DXUI-83: as a page's request does (`request`): without it, under a tenant, the first layer of the type reads as a store cleared under the window. */\n if (this.rec) this.tenantSeen = getRecordStoreTenant();\n this.loadCount!({ signal: controller.signal }).then(\n (total) => this.settleCount(token, { ok: true, total }),\n (error: unknown) => this.settleCount(token, { ok: false, error }),\n );\n }\n\n private settleCount(token: number, outcome: { ok: true; total: number } | { ok: false; error: unknown }): void {\n if (this.countRequest?.token !== token) return;\n if (this.frozen) {\n this.heldAnswers.push(() => this.applyCount(token, outcome));\n return;\n }\n this.applyCount(token, outcome);\n this.publish();\n }\n\n private applyCount(token: number, outcome: { ok: true; total: number } | { ok: false; error: unknown }): void {\n if (this.countRequest?.token !== token) return;\n this.countRequest = null;\n /* DXUI-83: answered or failed, the read is over: a placed row waits for nothing more from it. */\n this.countSettledSeq = token;\n if (outcome.ok) {\n this.total = outcome.total;\n this.countError = undefined;\n } else {\n this.countError = outcome.error;\n }\n }\n\n private abortCount(): void {\n this.countRequest?.controller.abort();\n this.countRequest = null;\n }\n\n private dropAll(): void {\n this.clearSettle();\n for (const entry of this.resident.values()) entry.controller?.abort();\n this.resident.clear();\n this.retained.clear();\n this.abortCount();\n this.queuedPages.clear();\n this.queuedCount = false;\n this.recordsPending = false;\n this.rec?.reset();\n }\n\n /* --- Record mode (DXUI-77) --------------------------------------------------- */\n\n /** A held record changed, or a layer moved on a record of the type. */\n private readonly onRecordsChanged = (): void => {\n if (this.frozen) {\n /* WHILE FROZEN NOTHING CHANGES: the thaw looks at it once. */\n this.recordsPending = true;\n return;\n }\n if (recordStoreVersion() === this.recordsVersion) return;\n this.applyRecordsChange();\n };\n\n private applyRecordsChange(): void {\n const rec = this.rec;\n if (!rec) return;\n this.recordsVersion = recordStoreVersion();\n const reload = rec.followLayers(this.heldKeys(), this.nextToken);\n if (reload || this.storeWasCleared(rec)) this.invalidateAll();\n else this.publish();\n }\n\n /**\n * A tenant change or a clear leaves the window holding keys to nothing, and `reissueMountedReads` does not cover it (it runs on the realtime\n * epoch, which neither bumps). So the window looks for itself: the store serves another tenant than the pages were requested under, or a page\n * that is current (not being read) holds a key the store knows nothing of.\n */\n private storeWasCleared(rec: RecordsBinding<T>): boolean {\n const tenant = getRecordStoreTenant();\n if (tenant !== this.tenantSeen) {\n this.tenantSeen = tenant;\n return true;\n }\n if (this.unknownReread) return false;\n for (const entry of this.resident.values()) {\n if (entry.status !== \"ready\" || entry.refreshing || entry.stale) continue;\n if (entry.keys.some((key) => rec.isUnknown(key))) {\n this.unknownReread = true;\n return true;\n }\n }\n return false;\n }\n\n /** Every key a page holds, resident or retained. */\n private heldKeys(): Set<string> {\n const held = new Set<string>();\n for (const entry of this.resident.values()) for (const key of entry.keys) held.add(key);\n for (const kept of this.retained.values()) for (const key of kept.keys) held.add(key);\n return held;\n }\n\n /** The rows a page draws from its own position: its held rows, or in record mode the held keys read from the store. */\n private pageRows(entry: { items: readonly T[]; keys: readonly string[] }): readonly T[] {\n return this.rec ? this.rec.rowsOf(entry.keys) : entry.items;\n }\n\n /** Every loaded row of a page, for a consumer's row test: whether or not it belongs here now. */\n private loadedRows(entry: { items: readonly T[]; keys: readonly string[] }): readonly T[] {\n return this.rec ? this.rec.loadedRowsOf(entry.keys) : entry.items;\n }\n\n /** Every resident page (a count window: its length) has been answered by a read sent at or after `seq` (a read that failed has nothing to wait for). */\n private answeredSince(seq: number): boolean {\n if (this.mode === \"count\") return this.countSettledSeq >= seq;\n for (const entry of this.resident.values()) {\n if (entry.status === \"error\") continue;\n if (entry.status !== \"ready\" || entry.readSeq < seq) return false;\n }\n return true;\n }\n\n /** The list's length as the window shows it: the server's, less each held row that left its page, plus each arrived row no page holds yet (a count window holds no row: it adds arrivals only). */\n private visibleTotal(): number | null {\n if (this.total === null || !this.rec) return this.total;\n const held = this.heldKeys();\n return Math.max(0, this.total - this.rec.countLeftOut(held) + this.rec.countArrived(held));\n }\n\n /** Placement and the store subscriptions follow the keys the window holds now. */\n private syncRecords(): void {\n const rec = this.rec;\n if (!rec) return;\n const held = this.heldKeys();\n rec.refreshPlacement(held);\n rec.settlePlacement((seq) => this.answeredSince(seq));\n const placed = rec.placedKeys();\n const subscribe = new Set(placed);\n for (const entry of this.resident.values()) for (const key of entry.keys) subscribe.add(key);\n rec.reconcile(subscribe, new Set([...held, ...placed]));\n }\n\n /** The resident pages the snapshot draws: the window, without the pages that only stay to finish a read (`outside`). */\n private drawn(): [number, ResidentPage<T>][] {\n return [...this.resident.entries()].filter(([, entry]) => !entry.outside);\n }\n\n /**\n * The longest unbroken stretch of ready pages inside the list, lowest on a\n * tie. Pages past the list's end (it shrank while the window was frozen) are\n * not part of any run.\n */\n private loadedRun(): number[] {\n const limit = Math.max(1, this.pageCount());\n const ready = this.drawn()\n .filter(([page, entry]) => entry.status === \"ready\" && page < limit)\n .map(([page]) => page)\n .sort((a, b) => a - b);\n let best: number[] = [];\n let current: number[] = [];\n for (const page of ready) {\n current = current.length > 0 && page === current[current.length - 1] + 1 ? [...current, page] : [page];\n if (current.length > best.length) best = current;\n }\n return best;\n }\n\n /**\n * DX-5521: each drawn page's items with every row key on one page only (ONE ROW KEY, ONE PAGE in the header). Pages claim their rows in\n * order of how current they are - a page with current rows before a stale or refreshing one, then the newer read first - and a row whose\n * key an earlier claimant took is left out. A page that loses nothing keeps its own array.\n */\n private uniqueItems(drawn: [number, ResidentPage<T>][], rows: Map<number, readonly T[]>): Map<number, readonly T[]> {\n const claimants = [...drawn].sort(([, a], [, b]) => Number(isOutOfDate(a)) - Number(isOutOfDate(b)) || b.readSeq - a.readSeq);\n const claimed = new Set<string | number>();\n const result = new Map<number, readonly T[]>();\n for (const [page] of claimants) {\n const own = rows.get(page)!;\n const kept = own.filter((row) => {\n const key = this.getKey(row);\n if (claimed.has(key)) return false;\n claimed.add(key);\n return true;\n });\n result.set(page, kept.length === own.length ? own : kept);\n }\n return result;\n }\n\n /**\n * DX-5521: a drawn page whose rows are current but lost a row to another page is out of date, since two right pages cannot share a row:\n * re-read it in place, so the page is not left one row short until some other event. One pass finds every such page: marking a page out of\n * date only lowers its rank, so it never makes another page lose a row. A page whose latest read was already a loss re-read is not re-read\n * again (ONE RE-READ PER LOSS in the header). Settled, the read starts now; while the viewer is still moving the page is marked stale and read\n * at the settle (DX-4614). Frozen, it looks for nothing: every answer is held, so no page can lose a row until the thaw publishes again.\n */\n private rereadLosers(): void {\n if (this.frozen) return;\n const drawn = this.drawn();\n const rows = this.rowsByPage(drawn);\n const kept = this.uniqueItems(drawn, rows);\n const settled = this.anchor === this.appliedAnchor;\n for (const [page, entry] of drawn) {\n if (isOutOfDate(entry) || entry.lossRead) continue;\n /* `uniqueItems` returns an entry for every page of `drawn`, so the lookup cannot miss. */\n if (kept.get(page)!.length === rows.get(page)!.length) continue;\n if (settled) this.request(page, entry, true);\n else {\n entry.stale = true;\n entry.readDue = true;\n entry.lossRead = true;\n }\n }\n }\n\n /** Each drawn page's rows, before the one-key-one-page rule: its held rows, or its keys read from the store. */\n private rowsByPage(drawn: [number, ResidentPage<T>][]): Map<number, readonly T[]> {\n return new Map(drawn.map(([page, entry]) => [page, this.pageRows(entry)]));\n }\n\n /**\n * DXUI-77: the loaded run with the placed rows (arrived and moved) drawn at the place `placeIn` gives. Returns `items` itself when nothing\n * moved, else the same map with each shown page's rows regrouped by the page a row now sits in.\n */\n private withPlacedRows(items: Map<number, readonly T[]>, run: ReadonlySet<number>): Map<number, readonly T[]> {\n const rec = this.rec;\n if (!rec || this.mode !== \"pages\" || run.size === 0) return items;\n const shownPages = [...run].sort((a, b) => a - b);\n const flat: RunRow<T>[] = shownPages.flatMap((page) => items.get(page)!.map((row) => ({ row, page })));\n const lastPageOfList = Math.max(0, this.pageCount() - 1);\n const placed = rec.place(flat, shownPages[0], shownPages[shownPages.length - 1], lastPageOfList);\n if (placed === flat) return items;\n const regrouped = new Map(items);\n for (const page of shownPages) regrouped.set(page, placed.filter((each) => each.page === page).map((each) => each.row));\n return regrouped;\n }\n\n /** DXUI-77: a page whose rows did not change keeps its items array, which `useSyncExternalStore` needs from a snapshot it did not change. */\n private static sameRows<R>(a: readonly R[], b: readonly R[]): boolean {\n return a.length === b.length && a.every((row, index) => row === b[index]);\n }\n\n private build(): PagedWindowSnapshot<T> {\n const run = new Set(this.loadedRun());\n const drawn = this.drawn();\n const items = this.withPlacedRows(this.uniqueItems(drawn, this.rowsByPage(drawn)), run);\n const before = this.snapshot as PagedWindowSnapshot<T> | undefined;\n const keepArray = <R,>(now: readonly R[], then: readonly R[] | undefined): readonly R[] =>\n this.rec && then && PagedWindowStore.sameRows(now, then) ? then : now;\n const pages = drawn\n .sort(([a], [b]) => a - b)\n .map(([page, entry]): PageSnapshot<T> => ({\n page,\n status: entry.status,\n items: keepArray(items.get(page)!, before?.pages.find((each) => each.page === page)?.items),\n refreshing: entry.refreshing,\n error: entry.error,\n shown: run.has(page),\n }));\n const shown = pages.filter((p) => p.shown);\n return {\n mode: this.mode,\n total: this.visibleTotal(),\n pageSize: this.pageSize,\n pageCount: this.pageCount(),\n anchorPage: this.anchor,\n epoch: this.epoch,\n pages,\n items: keepArray(shown.flatMap((p) => p.items), before?.items),\n offset: shown.length > 0 ? shown[0].page * this.pageSize : 0,\n countError: this.countError,\n };\n }\n\n private publish(): void {\n this.syncRecords();\n this.rereadLosers();\n this.snapshot = this.build();\n for (const listener of this.listeners) listener();\n }\n}\n"],"names":["PAGED_WINDOW_SETTLE_MS","NO_KEYS","markInvalidated","page","windowPageNumbers","anchorPage","pageCount","windowPages","before","first","last","pages","isOutOfDate","entry","PagedWindowStore","pageSize","getKey","loadPage","loadCount","mode","settleMs","records","RecordsBinding","listener","frozen","kept","rowTest","matched","viewerPage","anchor","force","wanted","resident","fresh","inMemory","leaves","keepReads","stale","queued","invalidated","answers","apply","forLoss","controller","token","getRecordStoreTenant","response","error","outcome","keys","key","other","total","recordStoreVersion","rec","tenant","held","seq","placed","subscribe","limit","ready","a","b","best","current","drawn","rows","claimants","claimed","result","own","row","settled","items","run","shownPages","flat","lastPageOfList","regrouped","each","index","keepArray","now","then","shown","p"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useState as P, useRef as s, useCallback as d, useEffect as k } from "react";
|
|
2
|
+
const w = 0.5;
|
|
3
|
+
function R(g) {
|
|
4
|
+
const [v, m] = P(g), h = s(/* @__PURE__ */ new Set()), n = s(/* @__PURE__ */ new Map()), c = s({ height: 0, count: 0 }), o = s(null), u = d((t) => {
|
|
5
|
+
const r = n.current.get(t);
|
|
6
|
+
r && (c.current.height += r.height, c.current.count += r.count, n.current.delete(t));
|
|
7
|
+
}, []);
|
|
8
|
+
k(() => {
|
|
9
|
+
const t = new ResizeObserver((r) => {
|
|
10
|
+
for (const e of r) {
|
|
11
|
+
const a = e.target, l = Number(a.dataset.count ?? 0);
|
|
12
|
+
l > 0 ? n.current.set(a, { height: e.contentRect.height, count: l }) : u(a);
|
|
13
|
+
}
|
|
14
|
+
let f = c.current.height, i = c.current.count;
|
|
15
|
+
for (const e of n.current.values())
|
|
16
|
+
f += e.height, i += e.count;
|
|
17
|
+
if (i === 0) return;
|
|
18
|
+
const b = f / i;
|
|
19
|
+
m((e) => Math.abs(e - b) < w ? e : b);
|
|
20
|
+
});
|
|
21
|
+
o.current = t;
|
|
22
|
+
for (const r of h.current) t.observe(r);
|
|
23
|
+
return () => {
|
|
24
|
+
t.disconnect(), o.current = null;
|
|
25
|
+
};
|
|
26
|
+
}, [u]);
|
|
27
|
+
const p = d(
|
|
28
|
+
(t) => (h.current.add(t), o.current?.observe(t), () => {
|
|
29
|
+
h.current.delete(t), o.current?.unobserve(t), u(t);
|
|
30
|
+
}),
|
|
31
|
+
[u]
|
|
32
|
+
);
|
|
33
|
+
return { pitch: v, observe: p };
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
R as useMeasuredPitch
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=use-measured-pitch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-measured-pitch.js","sources":["../../../src/lib/paged-window/use-measured-pitch.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\n/** Under this many pixels a new mean is not worth re-laying-out the list for. */\nconst PITCH_EPSILON_PX = 0.5;\n\n/**\n * How tall one item really is — measured, not guessed. DX-4540.\n *\n * A page that is not resident is drawn as a placeholder of `items x pitch`, so the\n * scrollbar is only as true as the pitch. `estimated` stands in until pages\n * have been seen; after that the pitch is the MEAN over every item measured,\n * which is a ResizeObserver over the page blocks.\n *\n * EVERY block is observed, because a block turns from placeholder to cards (and\n * back) without its element being replaced: only a block that currently holds\n * cards (`data-count`) is a measurement of what a card costs; a placeholder's\n * own size is the estimate drawn back at us. A block that stops holding cards,\n * or is removed, leaves its LAST reading in the mean (`departed`), so dropping\n * a page does not make the estimate lurch and every placeholder above the\n * viewer resize with it.\n *\n * A change under half a pixel is not published: re-laying-out every placeholder\n * in a long list for sub-pixel drift is cost with no picture.\n *\n * NOTHING IS EVER RESET, AND THAT IS DELIBERATE. A new query (another sort, a\n * different time range) lists the same kind of card, so what was learned about\n * its height still holds; clearing it would snap every placeholder back to the\n * estimate and make the first screen of the new query jump. The measurement is\n * only a sizing aid for space no card occupies, and the mean keeps correcting\n * itself from every page that is shown.\n *\n * A block whose size does not change when it turns from placeholder to cards\n * (or back) fires no resize, so its reading is picked up at the next size change;\n * a placeholder is sized from the estimate in the first place.\n */\nexport function useMeasuredPitch(estimated: number): { pitch: number; observe: (el: HTMLElement) => () => void } {\n const [pitch, setPitch] = useState(estimated);\n const blocks = useRef(new Set<HTMLElement>());\n const measured = useRef(new Map<HTMLElement, { height: number; count: number }>());\n const departed = useRef({ height: 0, count: 0 });\n const observer = useRef<ResizeObserver | null>(null);\n\n const retire = useCallback((el: HTMLElement) => {\n const last = measured.current.get(el);\n if (!last) return;\n departed.current.height += last.height;\n departed.current.count += last.count;\n measured.current.delete(el);\n }, []);\n\n useEffect(() => {\n const ro = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const el = entry.target as HTMLElement;\n const count = Number(el.dataset.count ?? 0);\n if (count > 0) measured.current.set(el, { height: entry.contentRect.height, count });\n else retire(el);\n }\n let height = departed.current.height;\n let count = departed.current.count;\n for (const m of measured.current.values()) {\n height += m.height;\n count += m.count;\n }\n if (count === 0) return;\n const mean = height / count;\n setPitch((current) => (Math.abs(current - mean) < PITCH_EPSILON_PX ? current : mean));\n });\n observer.current = ro;\n for (const block of blocks.current) ro.observe(block);\n return () => {\n ro.disconnect();\n observer.current = null;\n };\n }, [retire]);\n\n const observe = useCallback(\n (el: HTMLElement) => {\n blocks.current.add(el);\n observer.current?.observe(el);\n return () => {\n blocks.current.delete(el);\n observer.current?.unobserve(el);\n retire(el);\n };\n },\n [retire],\n );\n\n return { pitch, observe };\n}\n"],"names":["PITCH_EPSILON_PX","useMeasuredPitch","estimated","pitch","setPitch","useState","blocks","useRef","measured","departed","observer","retire","useCallback","el","last","useEffect","ro","entries","entry","count","height","m","mean","current","block","observe"],"mappings":";AAGA,MAAMA,IAAmB;AAgClB,SAASC,EAAiBC,GAAgF;AAC/G,QAAM,CAACC,GAAOC,CAAQ,IAAIC,EAASH,CAAS,GACtCI,IAASC,EAAO,oBAAI,KAAkB,GACtCC,IAAWD,EAAO,oBAAI,KAAqD,GAC3EE,IAAWF,EAAO,EAAE,QAAQ,GAAG,OAAO,GAAG,GACzCG,IAAWH,EAA8B,IAAI,GAE7CI,IAASC,EAAY,CAACC,MAAoB;AAC9C,UAAMC,IAAON,EAAS,QAAQ,IAAIK,CAAE;AACpC,IAAKC,MACLL,EAAS,QAAQ,UAAUK,EAAK,QAChCL,EAAS,QAAQ,SAASK,EAAK,OAC/BN,EAAS,QAAQ,OAAOK,CAAE;AAAA,EAC5B,GAAG,CAAA,CAAE;AAEL,EAAAE,EAAU,MAAM;AACd,UAAMC,IAAK,IAAI,eAAe,CAACC,MAAY;AACzC,iBAAWC,KAASD,GAAS;AAC3B,cAAMJ,IAAKK,EAAM,QACXC,IAAQ,OAAON,EAAG,QAAQ,SAAS,CAAC;AAC1C,QAAIM,IAAQ,IAAGX,EAAS,QAAQ,IAAIK,GAAI,EAAE,QAAQK,EAAM,YAAY,QAAQ,OAAAC,GAAO,MACvEN,CAAE;AAAA,MAChB;AACA,UAAIO,IAASX,EAAS,QAAQ,QAC1BU,IAAQV,EAAS,QAAQ;AAC7B,iBAAWY,KAAKb,EAAS,QAAQ,OAAA;AAC/B,QAAAY,KAAUC,EAAE,QACZF,KAASE,EAAE;AAEb,UAAIF,MAAU,EAAG;AACjB,YAAMG,IAAOF,IAASD;AACtB,MAAAf,EAAS,CAACmB,MAAa,KAAK,IAAIA,IAAUD,CAAI,IAAItB,IAAmBuB,IAAUD,CAAK;AAAA,IACtF,CAAC;AACD,IAAAZ,EAAS,UAAUM;AACnB,eAAWQ,KAASlB,EAAO,QAAS,CAAAU,EAAG,QAAQQ,CAAK;AACpD,WAAO,MAAM;AACX,MAAAR,EAAG,WAAA,GACHN,EAAS,UAAU;AAAA,IACrB;AAAA,EACF,GAAG,CAACC,CAAM,CAAC;AAEX,QAAMc,IAAUb;AAAA,IACd,CAACC,OACCP,EAAO,QAAQ,IAAIO,CAAE,GACrBH,EAAS,SAAS,QAAQG,CAAE,GACrB,MAAM;AACX,MAAAP,EAAO,QAAQ,OAAOO,CAAE,GACxBH,EAAS,SAAS,UAAUG,CAAE,GAC9BF,EAAOE,CAAE;AAAA,IACX;AAAA,IAEF,CAACF,CAAM;AAAA,EAAA;AAGT,SAAO,EAAE,OAAAR,GAAO,SAAAsB,EAAA;AAClB;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useRef as i, useEffect as a, useCallback as l } from "react";
|
|
2
|
+
function b(r) {
|
|
3
|
+
return Number(r.dataset.page);
|
|
4
|
+
}
|
|
5
|
+
function d(r) {
|
|
6
|
+
if (r.size === 0) return null;
|
|
7
|
+
const n = [...r].map(b).sort((c, t) => c - t);
|
|
8
|
+
return n[Math.floor((n.length - 1) / 2)];
|
|
9
|
+
}
|
|
10
|
+
function p(r, n) {
|
|
11
|
+
const c = i(/* @__PURE__ */ new Set()), t = i(/* @__PURE__ */ new Set()), o = i(null);
|
|
12
|
+
return a(() => {
|
|
13
|
+
if (!r) return;
|
|
14
|
+
const e = new IntersectionObserver(
|
|
15
|
+
(u) => {
|
|
16
|
+
for (const s of u)
|
|
17
|
+
s.isIntersecting ? t.current.add(s.target) : t.current.delete(s.target);
|
|
18
|
+
const f = d(t.current);
|
|
19
|
+
f !== null && n(f);
|
|
20
|
+
},
|
|
21
|
+
{ root: r.el }
|
|
22
|
+
);
|
|
23
|
+
o.current = e;
|
|
24
|
+
for (const u of c.current) e.observe(u);
|
|
25
|
+
return () => {
|
|
26
|
+
e.disconnect(), o.current = null, t.current.clear();
|
|
27
|
+
};
|
|
28
|
+
}, [r, n]), { observe: l((e) => (c.current.add(e), o.current?.observe(e), () => {
|
|
29
|
+
c.current.delete(e), o.current?.unobserve(e), t.current.delete(e);
|
|
30
|
+
}), []) };
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
d as centrePage,
|
|
34
|
+
p as usePageVisibility
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=use-page-visibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-page-visibility.js","sources":["../../../src/lib/paged-window/use-page-visibility.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\nimport type { ScrollRoot } from \"./use-scroll-root\";\n\n/** The page number a block stands for, read off the element the observer hands back. */\nfunction pageOf(el: Element): number {\n return Number((el as HTMLElement).dataset.page);\n}\n\n/**\n * The page the window should centre on: the middle one (lower middle when\n * even) of the pages whose blocks intersect the root. A viewport shorter than\n * a page sees one or two; the window of three covers either. Null when nothing\n * is in view (a hidden scroller), so the window keeps where it was.\n */\nexport function centrePage(visible: ReadonlySet<Element>): number | null {\n if (visible.size === 0) return null;\n const pages = [...visible].map(pageOf).sort((a, b) => a - b);\n return pages[Math.floor((pages.length - 1) / 2)];\n}\n\n/**\n * Which pages are in view, from one IntersectionObserver over every page block,\n * rooted at the scroller — no scroll listener, no polling. DX-4540.\n *\n * `observe(el)` is what a block's ref calls; it returns the cleanup. It is\n * stable, and blocks that mount before the observer exists (it needs the\n * resolved scroller) are picked up when it does. Whenever the set in view\n * changes, `onCentre` is told the page to centre on.\n */\nexport function usePageVisibility(\n scroller: ScrollRoot | null,\n onCentre: (page: number) => void,\n): { observe: (el: HTMLElement) => () => void } {\n const blocks = useRef(new Set<HTMLElement>());\n const visible = useRef(new Set<Element>());\n const observer = useRef<IntersectionObserver | null>(null);\n\n useEffect(() => {\n if (!scroller) return;\n const io = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) visible.current.add(entry.target);\n else visible.current.delete(entry.target);\n }\n const centre = centrePage(visible.current);\n if (centre !== null) onCentre(centre);\n },\n { root: scroller.el },\n );\n observer.current = io;\n for (const block of blocks.current) io.observe(block);\n return () => {\n io.disconnect();\n observer.current = null;\n visible.current.clear();\n };\n }, [scroller, onCentre]);\n\n const observe = useCallback((el: HTMLElement) => {\n blocks.current.add(el);\n observer.current?.observe(el);\n return () => {\n blocks.current.delete(el);\n observer.current?.unobserve(el);\n visible.current.delete(el);\n };\n }, []);\n\n return { observe };\n}\n"],"names":["pageOf","el","centrePage","visible","pages","a","b","usePageVisibility","scroller","onCentre","blocks","useRef","observer","useEffect","io","entries","entry","centre","block","useCallback"],"mappings":";AAIA,SAASA,EAAOC,GAAqB;AACnC,SAAO,OAAQA,EAAmB,QAAQ,IAAI;AAChD;AAQO,SAASC,EAAWC,GAA8C;AACvE,MAAIA,EAAQ,SAAS,EAAG,QAAO;AAC/B,QAAMC,IAAQ,CAAC,GAAGD,CAAO,EAAE,IAAIH,CAAM,EAAE,KAAK,CAACK,GAAGC,MAAMD,IAAIC,CAAC;AAC3D,SAAOF,EAAM,KAAK,OAAOA,EAAM,SAAS,KAAK,CAAC,CAAC;AACjD;AAWO,SAASG,EACdC,GACAC,GAC8C;AAC9C,QAAMC,IAASC,EAAO,oBAAI,KAAkB,GACtCR,IAAUQ,EAAO,oBAAI,KAAc,GACnCC,IAAWD,EAAoC,IAAI;AAEzD,SAAAE,EAAU,MAAM;AACd,QAAI,CAACL,EAAU;AACf,UAAMM,IAAK,IAAI;AAAA,MACb,CAACC,MAAY;AACX,mBAAWC,KAASD;AAClB,UAAIC,EAAM,iBAAgBb,EAAQ,QAAQ,IAAIa,EAAM,MAAM,IACrDb,EAAQ,QAAQ,OAAOa,EAAM,MAAM;AAE1C,cAAMC,IAASf,EAAWC,EAAQ,OAAO;AACzC,QAAIc,MAAW,QAAMR,EAASQ,CAAM;AAAA,MACtC;AAAA,MACA,EAAE,MAAMT,EAAS,GAAA;AAAA,IAAG;AAEtB,IAAAI,EAAS,UAAUE;AACnB,eAAWI,KAASR,EAAO,QAAS,CAAAI,EAAG,QAAQI,CAAK;AACpD,WAAO,MAAM;AACX,MAAAJ,EAAG,WAAA,GACHF,EAAS,UAAU,MACnBT,EAAQ,QAAQ,MAAA;AAAA,IAClB;AAAA,EACF,GAAG,CAACK,GAAUC,CAAQ,CAAC,GAYhB,EAAE,SAVOU,EAAY,CAAClB,OAC3BS,EAAO,QAAQ,IAAIT,CAAE,GACrBW,EAAS,SAAS,QAAQX,CAAE,GACrB,MAAM;AACX,IAAAS,EAAO,QAAQ,OAAOT,CAAE,GACxBW,EAAS,SAAS,UAAUX,CAAE,GAC9BE,EAAQ,QAAQ,OAAOF,CAAE;AAAA,EAC3B,IACC,CAAA,CAAE,EAEI;AACX;"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useRef as u, useSyncExternalStore as P, useLayoutEffect as S, useEffect as d, useMemo as v } from "react";
|
|
2
|
+
import { PagedWindowStore as W } from "./store.js";
|
|
3
|
+
function E({
|
|
4
|
+
pageSize: o,
|
|
5
|
+
getKey: R,
|
|
6
|
+
windowPages: a,
|
|
7
|
+
loadPage: l,
|
|
8
|
+
loadCount: h,
|
|
9
|
+
queryKey: n,
|
|
10
|
+
mode: i = "pages",
|
|
11
|
+
settleMs: c,
|
|
12
|
+
records: r
|
|
13
|
+
}) {
|
|
14
|
+
const f = u(null);
|
|
15
|
+
f.current ??= new W({ pageSize: o, getKey: R, windowPages: a, loadPage: l, loadCount: h, mode: i, settleMs: c, records: r });
|
|
16
|
+
const e = f.current, s = u({ pageSize: o, windowPages: a, settleMs: c, hasRecords: r !== void 0 });
|
|
17
|
+
if (s.current.pageSize !== o || s.current.windowPages !== a || s.current.settleMs !== c || s.current.hasRecords !== (r !== void 0))
|
|
18
|
+
throw new Error(
|
|
19
|
+
"usePagedWindow: pageSize, windowPages, settleMs and whether `records` is given cannot change after mount. Mount a new list (a React `key`) for a differently-paged list."
|
|
20
|
+
);
|
|
21
|
+
const g = P(e.subscribe, e.getSnapshot, e.getSnapshot);
|
|
22
|
+
S(() => e.setLoaders(l, h, r)), d(() => e.setMode(i), [e, i]);
|
|
23
|
+
const p = u(n);
|
|
24
|
+
d(() => {
|
|
25
|
+
p.current !== n && (p.current = n, e.reset());
|
|
26
|
+
}, [e, n]), d(() => (e.start(), () => e.stop()), [e]);
|
|
27
|
+
const w = v(
|
|
28
|
+
() => ({
|
|
29
|
+
setAnchorPage: (t) => e.setAnchorPage(t),
|
|
30
|
+
invalidatePage: (t) => e.invalidatePage(t),
|
|
31
|
+
invalidateAll: () => e.invalidateAll(),
|
|
32
|
+
invalidateWhere: (t) => e.invalidateWhere(t),
|
|
33
|
+
holdsRow: (t) => e.holdsRow(t),
|
|
34
|
+
setFrozen: (t) => e.setFrozen(t)
|
|
35
|
+
}),
|
|
36
|
+
[e]
|
|
37
|
+
);
|
|
38
|
+
return v(() => ({ ...g, ...w }), [g, w]);
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
E as usePagedWindow
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=use-paged-window.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-paged-window.js","sources":["../../../src/lib/paged-window/use-paged-window.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport {\n PagedWindowStore,\n type PagedWindowMode,\n type PagedWindowOptions,\n type PagedWindowSnapshot,\n} from \"./store\";\n\nexport interface UsePagedWindowOptions<T> extends PagedWindowOptions<T> {\n /**\n * Names WHAT is being listed: the filter, the sort, the time range. When it\n * changes the window forgets every page, returns to the first and the list\n * scrolls back to the top. A change in a loader's identity alone does not:\n * a loader closing over fresh state must not throw away what is resident.\n */\n queryKey: string;\n /**\n * `\"count\"` loads no cards, only the list's length (through `loadCount`), and\n * keeps it live: a hidden lane that still needs a true badge. Back to\n * `\"pages\"`, the window loads again.\n * @default \"pages\"\n */\n mode?: PagedWindowMode;\n}\n\nexport interface PagedWindow<T> extends PagedWindowSnapshot<T> {\n /** The viewer moved to this page. `PagedWindowList` reports it; a custom view may too. */\n setAnchorPage: (page: number) => void;\n /** Re-read one resident page in place — a card on it changed. A retained page (rows kept, outside the window) is marked stale and re-read in place when it re-enters the window. */\n invalidatePage: (page: number) => void;\n /**\n * Invalidate every page (resident or retained) that has a row passing `rowTest` - a card changed and the page that shows it may be outside the\n * window, which `invalidatePage` cannot name. A resident page is re-read in place now; a retained one when it re-enters the window. Returns\n * whether any page matched.\n */\n invalidateWhere: (rowTest: (row: T) => boolean) => boolean;\n /**\n * Whether any CURRENT loaded row, resident or retained, passes `rowTest`. The rows of a stale page are known to be out of date and do not\n * count, whether it is kept outside the window or drawn in it (drawn back from memory before its re-read, or marked by a changed total).\n * Reads the store as it is now; changes nothing.\n */\n holdsRow: (rowTest: (row: T) => boolean) => boolean;\n /** Re-read every resident page in place and mark every retained page stale — a card was created, moved or removed. In `count` mode, re-ask the length. */\n invalidateAll: () => void;\n /**\n * While true the window neither loads nor drops pages. `PagedWindowList`\n * sets it for the length of a drag: the carried card is mounted in its page,\n * and dropping that page mid-drag would unmount the card and cancel the drag.\n */\n setFrozen: (frozen: boolean) => void;\n}\n\n/**\n * Keeps the rows of every page it has loaded (DX-5521) and tells a view which\n * `windowPages` (default 3) of them to render. `loadPage` answers one page AND the list's current\n * length, so the scrollbar can span `total` before most of it is loaded.\n *\n * The window moves to the viewer's page only after it has stayed put for\n * `settleMs` (200 ms by default), so a fast scroll loads the pages it lands\n * on, never the ones it passes (DX-4614); a read for a page that leaves the\n * window is aborted through its `signal`, and an aborted read is never an error.\n *\n * `pageSize` and `windowPages` are fixed for the life of the hook: changing one\n * means every resident page is cut differently, which is a different list — give it\n * a new `queryKey` and a new mount instead. `settleMs` is fixed too: the store\n * reads it once. All three throw rather than guess. `getKey` is read once as well\n * (a different function passed on a later render is ignored), so it must be a pure\n * function of the row: the same row always gives the same key.\n */\nexport function usePagedWindow<T>({\n pageSize,\n getKey,\n windowPages,\n loadPage,\n loadCount,\n queryKey,\n mode = \"pages\",\n settleMs,\n records,\n}: UsePagedWindowOptions<T>): PagedWindow<T> {\n const storeRef = useRef<PagedWindowStore<T> | null>(null);\n storeRef.current ??= new PagedWindowStore({ pageSize, getKey, windowPages, loadPage, loadCount, mode, settleMs, records });\n const store = storeRef.current;\n\n const shape = useRef({ pageSize, windowPages, settleMs, hasRecords: records !== undefined });\n if (\n shape.current.pageSize !== pageSize ||\n shape.current.windowPages !== windowPages ||\n shape.current.settleMs !== settleMs ||\n shape.current.hasRecords !== (records !== undefined)\n ) {\n throw new Error(\n \"usePagedWindow: pageSize, windowPages, settleMs and whether `records` is given cannot change after mount. \" +\n \"Mount a new list (a React `key`) for a differently-paged list.\",\n );\n }\n\n const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\n /* THE LATEST-LOADERS PATTERN, done in a layout effect rather than during\n render. A consumer writes `loadPage` inline, so its identity changes every\n render and the store must call the CURRENT one — but a render that is thrown\n away (Suspense, StrictMode's second pass) must not leave the store pointing\n at a closure from it. A layout effect runs only for a committed render, and\n before any passive effect or observer callback that could call a loader, so\n the store never calls a stale one. */\n useLayoutEffect(() => store.setLoaders(loadPage, loadCount, records));\n\n /* Declared before `start`, so a list that mounts in `count` mode never fires a page request. */\n useEffect(() => store.setMode(mode), [store, mode]);\n\n const lastQuery = useRef(queryKey);\n useEffect(() => {\n if (lastQuery.current === queryKey) return;\n lastQuery.current = queryKey;\n store.reset();\n }, [store, queryKey]);\n\n useEffect(() => {\n store.start();\n return () => store.stop();\n }, [store]);\n\n /* Stable for the life of the hook, so a view can list them as effect\n dependencies without re-running on every page that arrives. */\n const actions = useMemo(\n () => ({\n setAnchorPage: (page: number) => store.setAnchorPage(page),\n invalidatePage: (page: number) => store.invalidatePage(page),\n invalidateAll: () => store.invalidateAll(),\n invalidateWhere: (rowTest: (row: T) => boolean) => store.invalidateWhere(rowTest),\n holdsRow: (rowTest: (row: T) => boolean) => store.holdsRow(rowTest),\n setFrozen: (frozen: boolean) => store.setFrozen(frozen),\n }),\n [store],\n );\n\n return useMemo(() => ({ ...snapshot, ...actions }), [snapshot, actions]);\n}\n"],"names":["usePagedWindow","pageSize","getKey","windowPages","loadPage","loadCount","queryKey","mode","settleMs","records","storeRef","useRef","PagedWindowStore","store","shape","snapshot","useSyncExternalStore","useLayoutEffect","useEffect","lastQuery","actions","useMemo","page","rowTest","frozen"],"mappings":";;AAqEO,SAASA,EAAkB;AAAA,EAChC,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,UAAAC;AAAA,EACA,SAAAC;AACF,GAA6C;AAC3C,QAAMC,IAAWC,EAAmC,IAAI;AACxD,EAAAD,EAAS,YAAY,IAAIE,EAAiB,EAAE,UAAAX,GAAU,QAAAC,GAAQ,aAAAC,GAAa,UAAAC,GAAU,WAAAC,GAAW,MAAAE,GAAM,UAAAC,GAAU,SAAAC,EAAA,CAAS;AACzH,QAAMI,IAAQH,EAAS,SAEjBI,IAAQH,EAAO,EAAE,UAAAV,GAAU,aAAAE,GAAa,UAAAK,GAAU,YAAYC,MAAY,QAAW;AAC3F,MACEK,EAAM,QAAQ,aAAab,KAC3Ba,EAAM,QAAQ,gBAAgBX,KAC9BW,EAAM,QAAQ,aAAaN,KAC3BM,EAAM,QAAQ,gBAAgBL,MAAY;AAE1C,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAKJ,QAAMM,IAAWC,EAAqBH,EAAM,WAAWA,EAAM,aAAaA,EAAM,WAAW;AAS3F,EAAAI,EAAgB,MAAMJ,EAAM,WAAWT,GAAUC,GAAWI,CAAO,CAAC,GAGpES,EAAU,MAAML,EAAM,QAAQN,CAAI,GAAG,CAACM,GAAON,CAAI,CAAC;AAElD,QAAMY,IAAYR,EAAOL,CAAQ;AACjC,EAAAY,EAAU,MAAM;AACd,IAAIC,EAAU,YAAYb,MAC1Ba,EAAU,UAAUb,GACpBO,EAAM,MAAA;AAAA,EACR,GAAG,CAACA,GAAOP,CAAQ,CAAC,GAEpBY,EAAU,OACRL,EAAM,MAAA,GACC,MAAMA,EAAM,KAAA,IAClB,CAACA,CAAK,CAAC;AAIV,QAAMO,IAAUC;AAAA,IACd,OAAO;AAAA,MACL,eAAe,CAACC,MAAiBT,EAAM,cAAcS,CAAI;AAAA,MACzD,gBAAgB,CAACA,MAAiBT,EAAM,eAAeS,CAAI;AAAA,MAC3D,eAAe,MAAMT,EAAM,cAAA;AAAA,MAC3B,iBAAiB,CAACU,MAAiCV,EAAM,gBAAgBU,CAAO;AAAA,MAChF,UAAU,CAACA,MAAiCV,EAAM,SAASU,CAAO;AAAA,MAClE,WAAW,CAACC,MAAoBX,EAAM,UAAUW,CAAM;AAAA,IAAA;AAAA,IAExD,CAACX,CAAK;AAAA,EAAA;AAGR,SAAOQ,EAAQ,OAAO,EAAE,GAAGN,GAAU,GAAGK,EAAA,IAAY,CAACL,GAAUK,CAAO,CAAC;AACzE;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useState as o, useCallback as t } from "react";
|
|
2
|
+
import { nearestScrollAncestor as c } from "../dom/scroll-ancestor.js";
|
|
3
|
+
function f() {
|
|
4
|
+
const [e, l] = o(null);
|
|
5
|
+
return { ref: t((r) => {
|
|
6
|
+
l(r ? { el: c(r, { includeSelf: !0 }) } : null);
|
|
7
|
+
}, []), scroller: e };
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
f as useScrollRoot
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=use-scroll-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-scroll-root.js","sources":["../../../src/lib/paged-window/use-scroll-root.ts"],"sourcesContent":["import { useCallback, useState } from \"react\";\nimport { nearestScrollAncestor } from \"../dom/scroll-ancestor\";\n\n/** The element a list scrolls in: `el` is null when the page itself scrolls (the viewport). */\nexport interface ScrollRoot {\n el: HTMLElement | null;\n}\n\n/**\n * Finds the box a list scrolls in, once the list is in the DOM. DX-4540.\n *\n * Returns a ref callback for the list's root and the root it resolved (null\n * until mounted). The list's OWN element counts: a list whose class sets\n * `overflow-y-auto` is its own scroller, and one dropped into a board lane\n * finds the lane's container above it. Resolved on mount only — a list does\n * not change scroller during its life, and re-walking on every render would\n * make the IntersectionObserver rooted at it be torn down and rebuilt.\n */\nexport function useScrollRoot(): { ref: (el: HTMLElement | null) => void; scroller: ScrollRoot | null } {\n const [scroller, setScroller] = useState<ScrollRoot | null>(null);\n const ref = useCallback((el: HTMLElement | null) => {\n setScroller(el ? { el: nearestScrollAncestor(el, { includeSelf: true }) } : null);\n }, []);\n return { ref, scroller };\n}\n"],"names":["useScrollRoot","scroller","setScroller","useState","useCallback","el","nearestScrollAncestor"],"mappings":";;AAkBO,SAASA,IAAwF;AACtG,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAA4B,IAAI;AAIhE,SAAO,EAAE,KAHGC,EAAY,CAACC,MAA2B;AAClD,IAAAH,EAAYG,IAAK,EAAE,IAAIC,EAAsBD,GAAI,EAAE,aAAa,GAAA,CAAM,EAAA,IAAM,IAAI;AAAA,EAClF,GAAG,CAAA,CAAE,GACS,UAAAJ,EAAA;AAChB;"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { useCallback as s, useState as a, useRef as S, useEffect as y } from "react";
|
|
2
|
+
const w = "danxbot-";
|
|
3
|
+
function n(t) {
|
|
4
|
+
return t.startsWith(w) ? t : w + t;
|
|
5
|
+
}
|
|
6
|
+
function g(t, e) {
|
|
7
|
+
if (typeof window > "u") return;
|
|
8
|
+
let o;
|
|
9
|
+
try {
|
|
10
|
+
o = window.localStorage.getItem(n(t));
|
|
11
|
+
} catch {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (o !== null)
|
|
15
|
+
try {
|
|
16
|
+
const r = JSON.parse(o);
|
|
17
|
+
return e(r) ? r : void 0;
|
|
18
|
+
} catch {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function p(t, e) {
|
|
23
|
+
if (!(typeof window > "u"))
|
|
24
|
+
try {
|
|
25
|
+
window.localStorage.setItem(n(t), JSON.stringify(e));
|
|
26
|
+
} catch {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function I(t) {
|
|
30
|
+
if (typeof window > "u") return null;
|
|
31
|
+
try {
|
|
32
|
+
return window.localStorage.getItem(n(t));
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function x(t, e) {
|
|
38
|
+
if (!(typeof window > "u"))
|
|
39
|
+
try {
|
|
40
|
+
window.localStorage.setItem(n(t), e);
|
|
41
|
+
} catch {
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function v(t) {
|
|
45
|
+
if (!(typeof window > "u"))
|
|
46
|
+
try {
|
|
47
|
+
window.localStorage.removeItem(n(t));
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function E(t, e, { isValid: o, enabled: r = !0 }) {
|
|
52
|
+
const u = s(
|
|
53
|
+
() => typeof e == "function" ? e() : e,
|
|
54
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- initial is read once, by design
|
|
55
|
+
[]
|
|
56
|
+
), [i, c] = a(() => {
|
|
57
|
+
if (!t || !r) return u();
|
|
58
|
+
const f = g(t, o);
|
|
59
|
+
return f === void 0 ? u() : f;
|
|
60
|
+
}), d = S(!1);
|
|
61
|
+
y(() => {
|
|
62
|
+
if (!(!t || !r)) {
|
|
63
|
+
if (!d.current) {
|
|
64
|
+
d.current = !0;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
p(t, i);
|
|
68
|
+
}
|
|
69
|
+
}, [t, r, i]);
|
|
70
|
+
const l = s(() => {
|
|
71
|
+
t && v(t), c(u());
|
|
72
|
+
}, [t, u]);
|
|
73
|
+
return [i, c, l];
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
v as clearStored,
|
|
77
|
+
g as readStored,
|
|
78
|
+
I as readStoredString,
|
|
79
|
+
n as storageKey,
|
|
80
|
+
E as usePersistedState,
|
|
81
|
+
p as writeStored,
|
|
82
|
+
x as writeStoredString
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=persist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persist.js","sources":["../../src/lib/persist.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\n/**\n * Session-scoped UI state that survives a refresh: panel layouts, open/closed\n * rails, whatever a person arranged and would be annoyed to rearrange.\n *\n * Kept separate from `preferences.ts` on purpose. A preference is one of a few\n * known strings, lives on `<html data-*>` so plain CSS can read it, and is\n * validated by membership. This is arbitrary JSON that only React reads, and is\n * validated by a caller-supplied predicate. Folding them into one generic would\n * mean every caller carrying parameters the other half needs — the abstraction\n * would cost more than the duplication it removes. What they DO share, the\n * namespace and the guarded read/write, is shared below.\n */\n\n/** One namespace for everything this library persists, so a host page's own\n localStorage keys can never collide with ours. */\nconst PREFIX = \"danxbot-\";\n\nexport function storageKey(name: string) {\n return name.startsWith(PREFIX) ? name : PREFIX + name;\n}\n\n/**\n * Read and parse, returning undefined for every failure mode.\n *\n * localStorage throws rather than returning null in two real situations —\n * Safari private browsing, and any embedding where storage is blocked by\n * policy. An unhandled throw here happens during the useState initializer,\n * which unmounts the tree: the whole app disappears because a panel wanted to\n * remember its width. Persistence is a convenience and must degrade to \"use\n * the default\", never to a blank page.\n */\nexport function readStored<T>(name: string, isValid: (value: unknown) => value is T): T | undefined {\n if (typeof window === \"undefined\") return undefined;\n let raw: string | null;\n try {\n raw = window.localStorage.getItem(storageKey(name));\n } catch {\n return undefined;\n }\n if (raw === null) return undefined;\n try {\n const parsed: unknown = JSON.parse(raw);\n return isValid(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function writeStored(name: string, value: unknown) {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKey(name), JSON.stringify(value));\n } catch {\n /* Quota exceeded or storage blocked. The app keeps working; it just\n forgets. Nothing here is important enough to interrupt anyone over. */\n }\n}\n\n/**\n * The same guarded read and write, for a value that is stored as a PLAIN\n * STRING rather than as JSON — `preferences.ts`'s three, whose values are one\n * of a few known words and are validated by membership rather than by a\n * predicate. JSON-encoding them would put quotes in storage for no reason and\n * break every entry a person already has.\n *\n * These exist because the guard did not reach that module and the failure was\n * total: all three preferences read in a `useState` INITIALIZER, so the throw\n * propagated out of render and React unmounted the tree — a blank page,\n * because the app wanted to remember a colour scheme. The header above has\n * claimed since it was written that \"the namespace and the guarded read/write\"\n * were shared with `preferences.ts`; they were not, in either direction, and\n * that sentence is only true now.\n */\nexport function readStoredString(name: string): string | null {\n if (typeof window === \"undefined\") return null;\n try {\n return window.localStorage.getItem(storageKey(name));\n } catch {\n return null;\n }\n}\n\nexport function writeStoredString(name: string, value: string) {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKey(name), value);\n } catch {\n /* See writeStored. */\n }\n}\n\nexport function clearStored(name: string) {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.removeItem(storageKey(name));\n } catch {\n /* See writeStored. */\n }\n}\n\n/** Accepts anything — for callers whose stored shape needs no narrowing. */\nexport const anyValue = (value: unknown): value is unknown => value !== undefined;\n\nexport type PersistedStateOptions<T> = {\n /**\n * Rejects a stored value that no longer fits. REQUIRED thinking, not\n * boilerplate: stored state outlives the code that wrote it, so a layout\n * saved against three panels will be read back by a two-panel group after a\n * refactor. Spreading it produces a broken layout that persists forever\n * because it keeps being written back. Returning false throws it away and\n * falls back to the default — the only recovery a user can't perform for\n * themselves.\n */\n isValid: (value: unknown) => value is T;\n /** Set false to stop persisting without changing any call site. */\n enabled?: boolean;\n};\n\n/**\n * `useState`, plus localStorage.\n *\n * The stored value is read in the INITIALIZER, not in an effect. Reading it in\n * an effect paints the default first and then jumps — the panel visibly snaps\n * from 50% to the 30% you left it at, on every single load. That flash is the\n * entire reason people call persisted layouts janky, and it is avoidable by\n * reading one frame earlier.\n */\nexport function usePersistedState<T>(\n name: string | undefined,\n initial: T | (() => T),\n { isValid, enabled = true }: PersistedStateOptions<T>,\n) {\n const resolveInitial = useCallback(\n () => (typeof initial === \"function\" ? (initial as () => T)() : initial),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- initial is read once, by design\n [],\n );\n\n const [value, setValue] = useState<T>(() => {\n if (!name || !enabled) return resolveInitial();\n const stored = readStored(name, isValid);\n return stored === undefined ? resolveInitial() : stored;\n });\n\n /* Skip the write on mount. Without this, a group that read nothing from\n storage immediately writes its default back — which looks harmless until\n you realise it means \"never touched\" and \"deliberately left at the\n default\" become indistinguishable on the next read. */\n const mounted = useRef(false);\n useEffect(() => {\n if (!name || !enabled) return;\n if (!mounted.current) {\n mounted.current = true;\n return;\n }\n writeStored(name, value);\n }, [name, enabled, value]);\n\n const reset = useCallback(() => {\n if (name) clearStored(name);\n setValue(resolveInitial());\n }, [name, resolveInitial]);\n\n return [value, setValue, reset] as const;\n}\n"],"names":["PREFIX","storageKey","name","readStored","isValid","raw","parsed","writeStored","value","readStoredString","writeStoredString","clearStored","usePersistedState","initial","enabled","resolveInitial","useCallback","setValue","useState","stored","mounted","useRef","useEffect","reset"],"mappings":";AAiBA,MAAMA,IAAS;AAER,SAASC,EAAWC,GAAc;AACvC,SAAOA,EAAK,WAAWF,CAAM,IAAIE,IAAOF,IAASE;AACnD;AAYO,SAASC,EAAcD,GAAcE,GAAwD;AAClG,MAAI,OAAO,SAAW,IAAa;AACnC,MAAIC;AACJ,MAAI;AACF,IAAAA,IAAM,OAAO,aAAa,QAAQJ,EAAWC,CAAI,CAAC;AAAA,EACpD,QAAQ;AACN;AAAA,EACF;AACA,MAAIG,MAAQ;AACZ,QAAI;AACF,YAAMC,IAAkB,KAAK,MAAMD,CAAG;AACtC,aAAOD,EAAQE,CAAM,IAAIA,IAAS;AAAA,IACpC,QAAQ;AACN;AAAA,IACF;AACF;AAEO,SAASC,EAAYL,GAAcM,GAAgB;AACxD,MAAI,SAAO,SAAW;AACtB,QAAI;AACF,aAAO,aAAa,QAAQP,EAAWC,CAAI,GAAG,KAAK,UAAUM,CAAK,CAAC;AAAA,IACrE,QAAQ;AAAA,IAGR;AACF;AAiBO,SAASC,EAAiBP,GAA6B;AAC5D,MAAI,OAAO,SAAW,IAAa,QAAO;AAC1C,MAAI;AACF,WAAO,OAAO,aAAa,QAAQD,EAAWC,CAAI,CAAC;AAAA,EACrD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAASQ,EAAkBR,GAAcM,GAAe;AAC7D,MAAI,SAAO,SAAW;AACtB,QAAI;AACF,aAAO,aAAa,QAAQP,EAAWC,CAAI,GAAGM,CAAK;AAAA,IACrD,QAAQ;AAAA,IAER;AACF;AAEO,SAASG,EAAYT,GAAc;AACxC,MAAI,SAAO,SAAW;AACtB,QAAI;AACF,aAAO,aAAa,WAAWD,EAAWC,CAAI,CAAC;AAAA,IACjD,QAAQ;AAAA,IAER;AACF;AA6BO,SAASU,EACdV,GACAW,GACA,EAAE,SAAAT,GAAS,SAAAU,IAAU,MACrB;AACA,QAAMC,IAAiBC;AAAA,IACrB,MAAO,OAAOH,KAAY,aAAcA,MAAwBA;AAAA;AAAA,IAEhE,CAAA;AAAA,EAAC,GAGG,CAACL,GAAOS,CAAQ,IAAIC,EAAY,MAAM;AAC1C,QAAI,CAAChB,KAAQ,CAACY,UAAgBC,EAAA;AAC9B,UAAMI,IAAShB,EAAWD,GAAME,CAAO;AACvC,WAAOe,MAAW,SAAYJ,EAAA,IAAmBI;AAAA,EACnD,CAAC,GAMKC,IAAUC,EAAO,EAAK;AAC5B,EAAAC,EAAU,MAAM;AACd,QAAI,GAACpB,KAAQ,CAACY,IACd;AAAA,UAAI,CAACM,EAAQ,SAAS;AACpB,QAAAA,EAAQ,UAAU;AAClB;AAAA,MACF;AACA,MAAAb,EAAYL,GAAMM,CAAK;AAAA;AAAA,EACzB,GAAG,CAACN,GAAMY,GAASN,CAAK,CAAC;AAEzB,QAAMe,IAAQP,EAAY,MAAM;AAC9B,IAAId,OAAkBA,CAAI,GAC1Be,EAASF,GAAgB;AAAA,EAC3B,GAAG,CAACb,GAAMa,CAAc,CAAC;AAEzB,SAAO,CAACP,GAAOS,GAAUM,CAAK;AAChC;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function n(e, o) {
|
|
2
|
+
const t = document.documentElement;
|
|
3
|
+
t.getAttribute(`data-${e}`) !== o && (t.setAttribute("data-motion-suspend", ""), t.setAttribute(`data-${e}`, o), getComputedStyle(t).backgroundColor, t.removeAttribute("data-motion-suspend"));
|
|
4
|
+
}
|
|
5
|
+
const d = ["light", "dark"], s = ["sm", "md", "lg"], r = ["design", "aa"], u = ["system", "full", "reduced"];
|
|
6
|
+
export {
|
|
7
|
+
r as CONTRAST,
|
|
8
|
+
u as MOTION,
|
|
9
|
+
s as SCALES,
|
|
10
|
+
d as THEMES,
|
|
11
|
+
n as applyPreference
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=preference-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preference-values.js","sources":["../../src/lib/preference-values.ts"],"sourcesContent":["/**\n * The vocabulary of the document-level display preferences, and the one way a\n * value is written onto `<html>`.\n *\n * DX-4075: REACT-FREE ON PURPOSE. `preferences.ts` holds the hooks, so it imports\n * React; `@50arms/ui/pure` may not reach React (`pure-entry.test.ts`). The framed\n * side of `SandboxedFrame` (the injected `window.danxMiniApp` script, built from these\n * lists, which mirrors `applyPreference`) has to apply the host's\n * appearance with the very same write the host used and accept exactly the same\n * values, so the unions, the value lists and `applyPreference` live here, imported\n * by both. Two copies would be two chances for the host and the frame to drift.\n */\n\n/**\n * Writes one preference onto `<html>` with document-wide motion suspended for\n * the duration of the change.\n *\n * WHY THIS IS NOT JUST `setAttribute`. Colour transitions are a foundation in\n * this system: every element has one. That is right for an interaction — a\n * control easing as you hover it — and wrong for a preference, because\n * switching theme changes the computed colour of EVERY element at once.\n * Measured on this demo: 2,360 transitions started simultaneously and the page\n * took **957ms** to settle, 1,560ms on the chat route, for a token whose\n * duration is 110ms. A theme switch should be a cut, not a dissolve; what it\n * actually looked like was the whole document struggling.\n *\n * `--motion-scale: 0` is how it is suspended, rather than a blanket\n * `transition: none !important`. Every duration in the system is already\n * pre-multiplied by that scalar, so zeroing it turns them all off through the\n * layer that exists for the purpose, overrides nothing a component declared,\n * and cannot be forgotten by a component author.\n *\n * THE FORCED READ IS LOAD-BEARING. Style is normally recalculated once, after\n * this function has returned — by which time the attribute is gone and the\n * durations are back. Reading a computed value flushes the recalculation\n * synchronously, so the new colours are committed WHILE durations are still\n * zero, and no transition is ever started. Delete that line and the suspension\n * silently does nothing at all, which is why `audit:motion` measures the settle\n * time rather than the presence of the attribute.\n *\n * DX-5526: A VALUE <html> ALREADY HOLDS WRITES NOTHING. Every preference hook\n * applies its value once the page has hydrated, and a prerendered page has\n * already written each value before first paint. The suspension and the forced\n * read are not free: `--motion-scale` is inherited, so flipping it restyles\n * every element, twice (on and off). For a write that changes nothing that was\n * two full-document style recalculations on every load (~1.1 s of throttled\n * main thread on the 50arms.ai homepage) to suppress transitions that could\n * never start.\n */\nexport function applyPreference(attribute: string, value: string) {\n const root = document.documentElement;\n if (root.getAttribute(`data-${attribute}`) === value) return;\n root.setAttribute(\"data-motion-suspend\", \"\");\n root.setAttribute(`data-${attribute}`, value);\n void getComputedStyle(root).backgroundColor;\n root.removeAttribute(\"data-motion-suspend\");\n}\n\nexport type Theme = \"light\" | \"dark\";\nexport const THEMES = [\"light\", \"dark\"] as const;\n\nexport type UiScale = \"sm\" | \"md\" | \"lg\";\nexport const SCALES = [\"sm\", \"md\", \"lg\"] as const;\n\n/**\n * `design` is the palette as drawn; `aa` raises every token to the 4.5:1 floor.\n *\n * Opt-IN, not enforced, because enforcing the floor everywhere flattens the\n * hierarchy for everyone: de-emphasised text stops being de-emphasised, and in\n * this palette light-theme tertiary collapsed onto the same ramp step as\n * secondary. A floor is a floor — reachable in one click by anyone who needs\n * it, not a target that drags the whole design up to meet it.\n */\nexport type ContrastPreference = \"design\" | \"aa\";\nexport const CONTRAST = [\"design\", \"aa\"] as const;\n\n/**\n * `system` is a real third state, not a synonym for \"full\": it means defer to\n * the OS, which is what most people want and what the OS-level preference\n * exists to express. Collapsing it into a boolean would make an app-level\n * control that says \"full\" override a user who set reduced motion system-wide.\n */\nexport type MotionPreference = \"system\" | \"full\" | \"reduced\";\nexport const MOTION = [\"system\", \"full\", \"reduced\"] as const;\n"],"names":["applyPreference","attribute","value","root","THEMES","SCALES","CONTRAST","MOTION"],"mappings":"AAiDO,SAASA,EAAgBC,GAAmBC,GAAe;AAChE,QAAMC,IAAO,SAAS;AACtB,EAAIA,EAAK,aAAa,QAAQF,CAAS,EAAE,MAAMC,MAC/CC,EAAK,aAAa,uBAAuB,EAAE,GAC3CA,EAAK,aAAa,QAAQF,CAAS,IAAIC,CAAK,GACvC,iBAAiBC,CAAI,EAAE,iBAC5BA,EAAK,gBAAgB,qBAAqB;AAC5C;AAGO,MAAMC,IAAS,CAAC,SAAS,MAAM,GAGzBC,IAAS,CAAC,MAAM,MAAM,IAAI,GAY1BC,IAAW,CAAC,UAAU,IAAI,GAS1BC,IAAS,CAAC,UAAU,QAAQ,SAAS;"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createElement as y, useContext as S, createContext as g, useSyncExternalStore as v, useState as k, useEffect as p, useCallback as u } from "react";
|
|
2
|
+
import { readStoredString as x, writeStoredString as C } from "./persist.js";
|
|
3
|
+
import { useHydrated as T } from "./use-hydrated.js";
|
|
4
|
+
import { applyPreference as w, CONTRAST as E, MOTION as M, THEMES as P, SCALES as V } from "./preference-values.js";
|
|
5
|
+
const F = () => () => {
|
|
6
|
+
};
|
|
7
|
+
function a({
|
|
8
|
+
attribute: e,
|
|
9
|
+
storageKey: t,
|
|
10
|
+
values: r,
|
|
11
|
+
fallback: s,
|
|
12
|
+
serverFallback: d
|
|
13
|
+
}) {
|
|
14
|
+
const m = v(
|
|
15
|
+
F,
|
|
16
|
+
() => {
|
|
17
|
+
const o = x(t);
|
|
18
|
+
return r.includes(o ?? "") ? o : s();
|
|
19
|
+
},
|
|
20
|
+
() => d
|
|
21
|
+
), [f, c] = k(null), n = f ?? m, l = T();
|
|
22
|
+
p(() => {
|
|
23
|
+
l && (w(e, n), C(t, n));
|
|
24
|
+
}, [e, t, n, l]);
|
|
25
|
+
const h = u((o) => c(o), []), b = u(() => {
|
|
26
|
+
c((o) => r[(r.indexOf(o ?? n) + 1) % r.length]);
|
|
27
|
+
}, [r, n]);
|
|
28
|
+
return { value: n, setValue: h, cycle: b };
|
|
29
|
+
}
|
|
30
|
+
const i = g(null);
|
|
31
|
+
function K({ theme: e, children: t }) {
|
|
32
|
+
return y(i.Provider, { value: e }, t);
|
|
33
|
+
}
|
|
34
|
+
function N() {
|
|
35
|
+
const e = S(i), { value: t, setValue: r, cycle: s } = a({
|
|
36
|
+
attribute: "theme",
|
|
37
|
+
storageKey: "danxbot-theme",
|
|
38
|
+
values: P,
|
|
39
|
+
fallback: () => e ?? (window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark"),
|
|
40
|
+
serverFallback: e ?? "dark"
|
|
41
|
+
});
|
|
42
|
+
return { theme: t, setTheme: r, toggle: s };
|
|
43
|
+
}
|
|
44
|
+
function I() {
|
|
45
|
+
const { value: e, setValue: t, cycle: r } = a({
|
|
46
|
+
attribute: "ui-scale",
|
|
47
|
+
storageKey: "danxbot-ui-scale",
|
|
48
|
+
values: V,
|
|
49
|
+
fallback: () => "md",
|
|
50
|
+
serverFallback: "md"
|
|
51
|
+
});
|
|
52
|
+
return { scale: e, setScale: t, cycle: r };
|
|
53
|
+
}
|
|
54
|
+
function L() {
|
|
55
|
+
const { value: e, setValue: t, cycle: r } = a({
|
|
56
|
+
attribute: "contrast",
|
|
57
|
+
storageKey: "danxbot-contrast",
|
|
58
|
+
values: E,
|
|
59
|
+
fallback: () => (
|
|
60
|
+
/* Someone who has asked their OS for more contrast has already answered
|
|
61
|
+
this question; honouring it silently is better than making them find
|
|
62
|
+
a second switch. */
|
|
63
|
+
typeof window < "u" && window.matchMedia("(prefers-contrast: more)").matches ? "aa" : "design"
|
|
64
|
+
),
|
|
65
|
+
serverFallback: "design"
|
|
66
|
+
});
|
|
67
|
+
return { contrast: e, setContrast: t, toggle: r };
|
|
68
|
+
}
|
|
69
|
+
function R() {
|
|
70
|
+
const { value: e, setValue: t, cycle: r } = a({
|
|
71
|
+
attribute: "motion",
|
|
72
|
+
storageKey: "danxbot-motion",
|
|
73
|
+
values: M,
|
|
74
|
+
fallback: () => "system",
|
|
75
|
+
serverFallback: "system"
|
|
76
|
+
});
|
|
77
|
+
return { motion: e, setMotion: t, cycle: r };
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
K as ThemeDefaultProvider,
|
|
81
|
+
L as useContrast,
|
|
82
|
+
R as useMotionPreference,
|
|
83
|
+
N as useTheme,
|
|
84
|
+
I as useUiScale
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.js","sources":["../../src/lib/preferences.ts"],"sourcesContent":["import { createContext, createElement, useCallback, useContext, useEffect, useState, useSyncExternalStore, type ReactNode } from \"react\";\nimport { readStoredString, writeStoredString } from \"./persist\";\nimport { useHydrated } from \"./use-hydrated\";\nimport {\n applyPreference,\n CONTRAST,\n MOTION,\n SCALES,\n THEMES,\n type ContrastPreference,\n type MotionPreference,\n type Theme,\n type UiScale,\n} from \"./preference-values\";\n\n/**\n * Document-level display preferences.\n *\n * All three of theme, size scale and motion work the same way: a value lives on\n * `<html data-*>`, CSS reads it, and localStorage remembers it. Writing that\n * three times would be three chances to diverge — so it is written once and\n * specialised below.\n *\n * WHY `<html>` AND NOT REACT CONTEXT: the value has to reach plain CSS, not\n * just components. Portalled content (dialogs, popovers, toasts) renders\n * outside the React tree that would hold the context, and a preference that\n * fails on exactly the overlay layers is worse than no preference at all.\n */\n\ntype PreferenceSpec<T extends string> = {\n /** The `data-*` attribute name, minus the `data-` prefix. */\n attribute: string;\n storageKey: string;\n values: readonly T[];\n /** Resolves the value to use in a browser when nothing is stored yet. */\n fallback: () => T;\n /** The value a server draws, and a hydrating client's first render: it has no storage and no media query. */\n serverFallback: T;\n};\n\nconst noSubscription = () => () => {};\n\nfunction usePreference<T extends string>({\n attribute,\n storageKey,\n values,\n fallback,\n serverFallback,\n}: PreferenceSpec<T>) {\n /* THROUGH `lib/persist`, NOT `window.localStorage` DIRECTLY, and the\n difference is the whole page. `localStorage` THROWS rather than returning\n null in Safari private browsing and wherever storage is blocked by policy\n — and this read happens during render, so an unhandled throw\n propagates out of render and React unmounts the tree. The symptom is not a\n forgotten theme; it is a blank page in a browser that works perfectly well\n otherwise. Found by blocking the `danxbot-` namespace in a real browser and\n watching a signed-in app render nothing at all.\n\n DX-5411: THE READ IS A SYNC-EXTERNAL-STORE SNAPSHOT, NOT A `useState` INITIALIZER. A server render cannot touch `window`,\n and a hydrating client must draw what the server drew, so both take `serverFallback`; a client that is not hydrating reads\n storage on its first render, and a hydrating one re-reads right after, which React does without a mismatch error. */\n const stored = useSyncExternalStore(\n noSubscription,\n () => {\n const raw = readStoredString(storageKey);\n return (values as readonly string[]).includes(raw ?? \"\") ? (raw as T) : fallback();\n },\n () => serverFallback,\n );\n const [chosen, setChosen] = useState<T | null>(null);\n const value = chosen ?? stored;\n const hydrated = useHydrated();\n\n /* Not before hydration: the first render's value is the server's guess, and writing it would overwrite the visitor's stored choice. */\n useEffect(() => {\n if (!hydrated) return;\n applyPreference(attribute, value);\n writeStoredString(storageKey, value);\n }, [attribute, storageKey, value, hydrated]);\n\n const setValue = useCallback((next: T) => setChosen(next), []);\n\n /** Step to the next value, wrapping — what a cycling toggle button needs. */\n const cycle = useCallback(() => {\n setChosen((current) => values[(values.indexOf(current ?? value) + 1) % values.length]);\n }, [values, value]);\n\n return { value, setValue, cycle };\n}\n\n/* ---------------------------------------------------------------------------\n THEME\n -------------------------------------------------------------------------- */\n\n/**\n * DX-5425 — the theme of a first visit, set ONCE for a whole app (an app that is dark by default says `\"dark\"`), in place\n * of the OS preference. A stored choice still wins. Every `useTheme` below it (each `ThemeMenu`, `ThemePanel`, a header's\n * icon) reads the same value, so two of them can never disagree on a first visit. Without it the browser asks the OS, and\n * a server, which has no OS, draws dark.\n */\nconst ThemeDefaultContext = createContext<Theme | null>(null);\n\nexport function ThemeDefaultProvider({ theme, children }: { theme: Theme; children: ReactNode }) {\n return createElement(ThemeDefaultContext.Provider, { value: theme }, children);\n}\n\nexport function useTheme() {\n const defaultTheme = useContext(ThemeDefaultContext);\n const { value, setValue, cycle } = usePreference<Theme>({\n attribute: \"theme\",\n storageKey: \"danxbot-theme\",\n values: THEMES,\n fallback: () =>\n defaultTheme ?? (window.matchMedia(\"(prefers-color-scheme: light)\").matches ? \"light\" : \"dark\"),\n serverFallback: defaultTheme ?? \"dark\",\n });\n return { theme: value, setTheme: setValue, toggle: cycle };\n}\n\n/* ---------------------------------------------------------------------------\n SIZE SCALE\n -------------------------------------------------------------------------- */\n\nexport function useUiScale() {\n const { value, setValue, cycle } = usePreference<UiScale>({\n attribute: \"ui-scale\",\n storageKey: \"danxbot-ui-scale\",\n values: SCALES,\n fallback: () => \"md\",\n serverFallback: \"md\",\n });\n return { scale: value, setScale: setValue, cycle };\n}\n\n/* ---------------------------------------------------------------------------\n CONTRAST\n -------------------------------------------------------------------------- */\n\nexport function useContrast() {\n const { value, setValue, cycle } = usePreference<ContrastPreference>({\n attribute: \"contrast\",\n storageKey: \"danxbot-contrast\",\n values: CONTRAST,\n fallback: () =>\n /* Someone who has asked their OS for more contrast has already answered\n this question; honouring it silently is better than making them find\n a second switch. */\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-contrast: more)\").matches\n ? \"aa\"\n : \"design\",\n serverFallback: \"design\",\n });\n return { contrast: value, setContrast: setValue, toggle: cycle };\n}\n\n/* ---------------------------------------------------------------------------\n MOTION\n -------------------------------------------------------------------------- */\n\nexport function useMotionPreference() {\n const { value, setValue, cycle } = usePreference<MotionPreference>({\n attribute: \"motion\",\n storageKey: \"danxbot-motion\",\n values: MOTION,\n fallback: () => \"system\",\n serverFallback: \"system\",\n });\n return { motion: value, setMotion: setValue, cycle };\n}\n"],"names":["noSubscription","usePreference","attribute","storageKey","values","fallback","serverFallback","stored","useSyncExternalStore","raw","readStoredString","chosen","setChosen","useState","value","hydrated","useHydrated","useEffect","applyPreference","writeStoredString","setValue","useCallback","next","cycle","current","ThemeDefaultContext","createContext","ThemeDefaultProvider","theme","children","createElement","useTheme","defaultTheme","useContext","THEMES","useUiScale","SCALES","useContrast","CONTRAST","useMotionPreference","MOTION"],"mappings":"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"}
|