@50arms/ui 0.0.0-stage → 35.2.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 +169 -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 +332 -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 +22 -0
- package/dist/types/components/rbac/ApiKeysPanel.d.ts +26 -0
- package/dist/types/components/rbac/ApiKeysTable.d.ts +65 -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 +635 -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,156 @@
|
|
|
1
|
+
import { useRef as n, useSyncExternalStore as L, useState as O, useEffect as p, useCallback as A, useMemo as U } from "react";
|
|
2
|
+
import { RefetchRunner as j, registerActiveRead as X, MAX_DROPPED_RERUNS as Z } from "./refetch.js";
|
|
3
|
+
import { acquireSlot as ee, clearSlotMeta as te, subscribeToSlot as re, readSlot as ne, emptySlotSnapshot as se, slotPendingKeys as ue, writeSlot as oe, slotKeys as ce, slotAnswerMark as ae } from "./slots.js";
|
|
4
|
+
import { write as B, getRecordStoreTenant as _, subscribeToTenant as ie, writeAll as le, sweepRecords as de } from "../records/store.js";
|
|
5
|
+
import { normalizeScope as fe, scopeKey as ge } from "../realtime/registry.js";
|
|
6
|
+
import { useUiStrings as G } from "../i18n/provider.js";
|
|
7
|
+
import { recordKey as H } from "../records/wire.js";
|
|
8
|
+
import { useRecord as pe } from "../records/hooks.js";
|
|
9
|
+
const $ = { inFlight: !1, settled: !1, error: void 0 };
|
|
10
|
+
function be(e, r, t) {
|
|
11
|
+
const { tag: u, tenant: F, enabled: f = !0, minRefetchIntervalMs: q } = t, h = r == null ? null : H(e.type, r), s = pe(e, r, { needs: u }), [m, y] = O($), i = n(t.fetch);
|
|
12
|
+
i.current = t.fetch;
|
|
13
|
+
const l = G().readError.error, E = n(l);
|
|
14
|
+
E.current = l;
|
|
15
|
+
const K = n(F);
|
|
16
|
+
K.current = F;
|
|
17
|
+
const o = n(!0);
|
|
18
|
+
p(() => (o.current = !0, () => {
|
|
19
|
+
o.current = !1;
|
|
20
|
+
}), []);
|
|
21
|
+
const d = n(null);
|
|
22
|
+
p(() => {
|
|
23
|
+
if (h === null || !f) {
|
|
24
|
+
d.current = null;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const c = new j(async () => {
|
|
28
|
+
const C = K.current ?? _();
|
|
29
|
+
y((g) => ({ ...g, inFlight: !0 }));
|
|
30
|
+
try {
|
|
31
|
+
const g = await i.current(), R = B(g, { source: "fetch", tag: u, tenant: C });
|
|
32
|
+
if (c.answered(R.verdict === "dropped-older" || R.refusedNested.length > 0) && R.refusedNested.length > 0) throw new P(R.refusedNested);
|
|
33
|
+
o.current && y({ inFlight: !1, settled: !0, error: void 0 });
|
|
34
|
+
} catch (g) {
|
|
35
|
+
o.current && y({ inFlight: !1, settled: !0, error: J(g, E.current) });
|
|
36
|
+
}
|
|
37
|
+
}, { minIntervalMs: q });
|
|
38
|
+
d.current = c, c.runNow();
|
|
39
|
+
const k = [h], S = X({ roots: () => k, request: () => c.request() });
|
|
40
|
+
return () => {
|
|
41
|
+
S(), c.dispose(), d.current === c && (d.current = null);
|
|
42
|
+
};
|
|
43
|
+
}, [h, u, f, q]);
|
|
44
|
+
const M = A(() => d.current?.runNow(), []);
|
|
45
|
+
return U(
|
|
46
|
+
() => ({
|
|
47
|
+
state: s,
|
|
48
|
+
data: s.status === "present" ? s.record : void 0,
|
|
49
|
+
loading: m.inFlight && s.status === "unknown",
|
|
50
|
+
refreshing: m.inFlight && s.status !== "unknown",
|
|
51
|
+
error: m.error,
|
|
52
|
+
refetch: M
|
|
53
|
+
}),
|
|
54
|
+
[s, m, M]
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
function Ne(e, r) {
|
|
58
|
+
const { key: t, tag: u, tenant: F, enabled: f = !0, minRefetchIntervalMs: q, createdScope: h } = r, s = h === void 0 ? void 0 : fe(h), m = s === void 0 ? "" : ge(s), y = n(s);
|
|
59
|
+
y.current = s;
|
|
60
|
+
const i = L(ie, _, _), l = `${String(i)}\0${t}`, [E, K] = O({ slot: l, status: $ }), o = E.slot === l ? E.status : $, d = n(r.fetch);
|
|
61
|
+
d.current = r.fetch;
|
|
62
|
+
const M = G().readError.error, c = n(M);
|
|
63
|
+
c.current = M;
|
|
64
|
+
const k = n(F);
|
|
65
|
+
k.current = F;
|
|
66
|
+
const S = n(!0);
|
|
67
|
+
p(() => (S.current = !0, () => {
|
|
68
|
+
S.current = !1;
|
|
69
|
+
}), []), p(
|
|
70
|
+
() => ee(t, { type: e.type, tag: u, createdScope: y.current }),
|
|
71
|
+
[t, e.type, u, m]
|
|
72
|
+
);
|
|
73
|
+
const C = n(i);
|
|
74
|
+
p(() => {
|
|
75
|
+
C.current !== i && (C.current = i, te(t));
|
|
76
|
+
}, [t, i]);
|
|
77
|
+
const g = A((N) => re(t, N), [t]), R = A(() => ne(t), [t]), w = L(g, R, se), b = n(null);
|
|
78
|
+
p(() => {
|
|
79
|
+
if (!f) {
|
|
80
|
+
b.current = null;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
let N = !0;
|
|
84
|
+
const v = new j(async () => {
|
|
85
|
+
const V = k.current ?? _(), W = ue(t), Y = ae(), x = (a) => K((I) => ({ slot: l, status: a(I.slot === l ? I.status : $) }));
|
|
86
|
+
x((a) => ({ ...a, inFlight: !0 }));
|
|
87
|
+
try {
|
|
88
|
+
const a = await d.current(), { results: I } = le(a.items, { source: "fetch", tag: u, tenant: V }), D = I.flatMap((T) => T.refusedNested);
|
|
89
|
+
if (v.answered(D.length > 0 || I.some((T) => T.verdict === "dropped-older")) && D.length > 0) throw new P(D);
|
|
90
|
+
if (!N) return;
|
|
91
|
+
oe(t, a.items.map((T) => he(T, e.type)).filter(me), a.meta, W, Y), S.current && x(() => ({ inFlight: !1, settled: !0, error: void 0 }));
|
|
92
|
+
} catch (a) {
|
|
93
|
+
N && S.current && x(() => ({ inFlight: !1, settled: !0, error: J(a, c.current) }));
|
|
94
|
+
}
|
|
95
|
+
}, { minIntervalMs: q });
|
|
96
|
+
b.current = v, v.runNow();
|
|
97
|
+
const Q = X({ roots: () => ce(t), request: () => v.request() });
|
|
98
|
+
return () => {
|
|
99
|
+
N = !1, Q(), v.dispose(), b.current === v && (b.current = null);
|
|
100
|
+
};
|
|
101
|
+
}, [t, l, u, f, q, e.type]);
|
|
102
|
+
const z = A(() => b.current?.runNow(), []);
|
|
103
|
+
return U(
|
|
104
|
+
() => ({
|
|
105
|
+
items: w.items,
|
|
106
|
+
pending: w.pending,
|
|
107
|
+
pendingCount: w.pendingCount,
|
|
108
|
+
meta: w.meta,
|
|
109
|
+
/* From the first render, not from the first effect: until this slot's first answer lands,
|
|
110
|
+
an enabled list is loading — never "ready, zero rows" for the frame before its fetch. */
|
|
111
|
+
loading: f && !o.settled,
|
|
112
|
+
refreshing: o.inFlight && o.settled,
|
|
113
|
+
error: o.error,
|
|
114
|
+
refetch: z
|
|
115
|
+
}),
|
|
116
|
+
[w, o, f, z]
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function Ie(e, r) {
|
|
120
|
+
return B(e, {
|
|
121
|
+
source: "fetch",
|
|
122
|
+
tag: r.tag,
|
|
123
|
+
tenant: r.tenant ?? _()
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function Te(e = 6e4) {
|
|
127
|
+
p(() => {
|
|
128
|
+
const r = setInterval(() => de(), e);
|
|
129
|
+
return () => clearInterval(r);
|
|
130
|
+
}, [e]);
|
|
131
|
+
}
|
|
132
|
+
function he(e, r) {
|
|
133
|
+
const t = e.id;
|
|
134
|
+
if (typeof t != "string" && typeof t != "number") return;
|
|
135
|
+
const u = typeof e.__type == "string" && e.__type !== "" ? e.__type : r;
|
|
136
|
+
return H(u, t);
|
|
137
|
+
}
|
|
138
|
+
function me(e) {
|
|
139
|
+
return e !== void 0;
|
|
140
|
+
}
|
|
141
|
+
class P extends Error {
|
|
142
|
+
constructor(r) {
|
|
143
|
+
super(`${r.join(", ")} stayed older than a change that reached the store, after ${Z} re-reads`), this.refused = r;
|
|
144
|
+
}
|
|
145
|
+
refused;
|
|
146
|
+
}
|
|
147
|
+
function J(e, r) {
|
|
148
|
+
return e instanceof P ? { message: e.message, cause: e, refused: e.refused } : e instanceof Error ? { message: e.message, cause: e, refused: [] } : typeof e == "string" ? { message: e, cause: e, refused: [] } : { message: r, cause: e, refused: [] };
|
|
149
|
+
}
|
|
150
|
+
export {
|
|
151
|
+
Ie as applyMutationResult,
|
|
152
|
+
Ne as useRecordListRead,
|
|
153
|
+
be as useRecordRead,
|
|
154
|
+
Te as useRecordStoreSweep
|
|
155
|
+
};
|
|
156
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sources":["../../../src/lib/reads/hooks.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from \"react\";\nimport {\n getRecordStoreTenant,\n subscribeToTenant,\n recordKey,\n sweepRecords,\n useRecord,\n write,\n writeAll,\n type RecordPayload,\n type RecordTypeToken,\n type WriteResult,\n} from \"../records\";\nimport { useUiStrings } from \"../i18n\";\nimport { MAX_DROPPED_RERUNS, registerActiveRead, RefetchRunner } from \"./refetch\";\nimport { acquireSlot, clearSlotMeta, emptySlotSnapshot, readSlot, slotAnswerMark, slotKeys, slotPendingKeys, subscribeToSlot, writeSlot } from \"./slots\";\nimport { normalizeScope, scopeKey } from \"../realtime\";\nimport type {\n ListReadOptions,\n ListReadResult,\n ReadError,\n RecordReadOptions,\n RecordReadResult,\n} from \"./types\";\n\n/* ============================================================================\n THE READ BINDING — the hooks an application actually calls.\n\n THE RULE THAT MAKES ALL THREE MODULES ADD UP TO SOMETHING: a read's answer\n comes from the STORE, never from this hook's own state. This hook owns the\n request and the triple around it; the store owns the data. Keeping a settled\n copy here would be the exact failure the whole design exists to remove — a\n record present in the store, updated by a broadcast, and rendered from a\n private copy that never hears about it.\n ========================================================================= */\n\ninterface RequestStatus {\n readonly inFlight: boolean;\n readonly settled: boolean;\n readonly error: ReadError | undefined;\n}\n\nconst IDLE: RequestStatus = { inFlight: false, settled: false, error: undefined };\n\n/**\n * Read one record: fetch it, write it into the store tagged with the field set\n * it asked for, and return the store's answer.\n *\n * `id` may be null for a conditional read — the hook then fetches nothing and\n * reports `unknown`, rather than forcing a caller around a rule of hooks.\n */\nexport function useRecordRead<T>(\n token: RecordTypeToken<T>,\n id: string | number | null | undefined,\n options: RecordReadOptions,\n): RecordReadResult<T> {\n const { tag, tenant, enabled = true, minRefetchIntervalMs } = options;\n const key = id === null || id === undefined ? null : recordKey(token.type, id);\n const state = useRecord(token, id, { needs: tag });\n\n const [status, setStatus] = useState<RequestStatus>(IDLE);\n /* The latest fetch function without making it a dependency: a caller writing\n `fetch: () => api.get(id)` inline hands over a new function on every\n render, and depending on its identity would refetch forever. */\n const latestFetch = useRef(options.fetch);\n latestFetch.current = options.fetch;\n /* A ref, like the fetch: a language switch must not rebuild the runner and refetch. */\n const requestFailedMessage = useUiStrings().readError.error;\n const requestFailed = useRef(requestFailedMessage);\n requestFailed.current = requestFailedMessage;\n const tenantRef = useRef(tenant);\n tenantRef.current = tenant;\n\n const live = useRef(true);\n useEffect(() => {\n live.current = true;\n return () => {\n live.current = false;\n };\n }, []);\n\n /**\n * The runner lives in a REF, created and disposed INSIDE one effect — never\n * via `useMemo`. This must stay this way; the previous shape (a `useMemo`\n * runner, disposed by a separate `useEffect` keyed on it) is a real,\n * confirmed bug, not a style preference.\n *\n * `useMemo` is a caching hint React is free to recompute; it is NOT tied to\n * an effect's mount/cleanup pair the way a ref written inside an effect is.\n * Under StrictMode's dev-only double-invoke (mount → cleanup → mount, done\n * deliberately to surface exactly this class of bug), the MEMOIZED runner\n * survives the simulated remount unchanged — React only re-runs effects, it\n * does not recompute a `useMemo` whose deps did not change. So the\n * simulated unmount's cleanup calls `runner.dispose()` on the one and only\n * instance, and the simulated remount's effect body reuses that SAME\n * now-disposed instance instead of getting a fresh one. `RefetchRunner\n * .request()`/`.runNow()` both no-op once `disposed`, so the read still\n * registers successfully with the staleness driver, but the `request`\n * closure it registers is permanently inert: the record gets its FIRST\n * fetch and then never refetches again, no matter how many staleness\n * signals the driver delivers afterward.\n *\n * Measured against the Demand Desk's live extraction toast (`extraction_\n * percent`/`extraction_phase`, both declared `staleFields` on the run\n * type): the store correctly detected and flagged staleness with the\n * correct root on every real broadcast, and a `registerActiveRead` call\n * made directly against the same store fired correctly on every cycle —\n * but this hook's OWN registration never fired again after the initial\n * mount fetch, for the entire lifetime of a real, multi-minute run. That\n * is the StrictMode zombie-runner bug above, not a defect in the\n * staleness/dependency tracking itself.\n *\n * Creating the runner INSIDE the effect ties its lifetime exactly to that\n * effect's own mount/cleanup pair, so a StrictMode-simulated remount (or a\n * real one) always gets a genuinely fresh, live runner rather than a\n * disposed corpse still sitting in the driver's registry.\n */\n const runnerRef = useRef<RefetchRunner | null>(null);\n\n useEffect(() => {\n if (key === null || !enabled) {\n runnerRef.current = null;\n return;\n }\n\n const runner = new RefetchRunner(async () => {\n /* THE TENANT IS READ HERE, AT REQUEST TIME, and carried through the\n response. Reading it when the response arrives reads the tenant as it\n is THEN — so a team-A answer landing after a switch would be stamped\n team B and merged into team B's store, which is the single worst thing\n a multi-tenant screen can do. */\n const requestTenant = tenantRef.current ?? getRecordStoreTenant();\n setStatus((previous) => ({ ...previous, inFlight: true }));\n try {\n const payload = await latestFetch.current();\n const result = write(payload, { source: \"fetch\", tag, tenant: requestTenant });\n /* A newer version of this record arrived while this read was in flight, so this answer was\n refused as older and nothing else will fetch it: ask again, after this request ends. */\n const spent = runner.answered(result.verdict === \"dropped-older\" || result.refusedNested.length > 0);\n if (spent && result.refusedNested.length > 0) throw new NestedRecordRefusedError(result.refusedNested);\n if (live.current) setStatus({ inFlight: false, settled: true, error: undefined });\n } catch (error) {\n if (live.current) setStatus({ inFlight: false, settled: true, error: toReadError(error, requestFailed.current) });\n }\n }, { minIntervalMs: minRefetchIntervalMs });\n\n runnerRef.current = runner;\n runner.runNow();\n\n /* The staleness driver reaches this read through its root — the one key it\n is responsible for — and the refetch it performs is the request it\n already made, with the field set it already asked for. */\n const roots = [key];\n const unregister = registerActiveRead({ roots: () => roots, request: () => runner.request() });\n\n return () => {\n unregister();\n runner.dispose();\n if (runnerRef.current === runner) runnerRef.current = null;\n };\n }, [key, tag, enabled, minRefetchIntervalMs]);\n\n const refetch = useCallback(() => runnerRef.current?.runNow(), []);\n\n return useMemo(\n () => ({\n state,\n data: state.status === \"present\" ? state.record : undefined,\n loading: status.inFlight && state.status === \"unknown\",\n refreshing: status.inFlight && state.status !== \"unknown\",\n error: status.error,\n refetch,\n }),\n [state, status, refetch],\n );\n}\n\n/**\n * Read a page: fetch it, write every row into the store, and record which keys\n * answered the query in a LIST SLOT.\n *\n * The slot is what makes a `created` broadcast visible and a tombstone\n * removable without a fetch — and it is where `meta` lives, because pagination\n * has no identity and can never be a record.\n */\nexport function useRecordListRead<T, TMeta = unknown>(\n token: RecordTypeToken<T>,\n options: ListReadOptions<TMeta>,\n): ListReadResult<T, TMeta> {\n const { key: slotId, tag, tenant, enabled = true, minRefetchIntervalMs, createdScope } = options;\n\n /* A SIGNATURE, not the scope object, in the slot effect's deps — the natural\n call site builds `{ filter }` fresh on every render, and depending on its\n identity would release and re-claim the slot on every render. The same\n reasoning, and the same shape, as `useRealtime`'s own scope signature. */\n const normalizedCreatedScope = createdScope === undefined ? undefined : normalizeScope(createdScope);\n const createdSignature = normalizedCreatedScope === undefined ? \"\" : scopeKey(normalizedCreatedScope);\n const latestCreatedScope = useRef(normalizedCreatedScope);\n latestCreatedScope.current = normalizedCreatedScope;\n\n /* THE STATUS BELONGS TO ONE SLOT. Held unkeyed, a list whose `key` changed (a new page, a\n new team) kept the PREVIOUS key's `settled: true`, so its first fetch for the new key read\n as a refresh of rows it had never had — `loading` false over an empty list. A status for a\n different slot reads as IDLE. */\n /* DXUI-86: the status belongs to one slot AND one store tenant. A team switch clears the store\n but leaves the slot id (and so the old status) in place; without the tenant in the status key\n the list read as settled over an empty store until the new team's read answered. */\n const storeTenant = useSyncExternalStore(subscribeToTenant, getRecordStoreTenant, getRecordStoreTenant);\n const statusKey = `${String(storeTenant)}\\u0000${slotId}`;\n const [keyedStatus, setKeyedStatus] = useState<{ slot: string; status: RequestStatus }>({ slot: statusKey, status: IDLE });\n const status = keyedStatus.slot === statusKey ? keyedStatus.status : IDLE;\n const latestFetch = useRef(options.fetch);\n latestFetch.current = options.fetch;\n /* A ref, like the fetch: a language switch must not rebuild the runner and refetch. */\n const requestFailedMessage = useUiStrings().readError.error;\n const requestFailed = useRef(requestFailedMessage);\n requestFailed.current = requestFailedMessage;\n const tenantRef = useRef(tenant);\n tenantRef.current = tenant;\n\n const live = useRef(true);\n useEffect(() => {\n live.current = true;\n return () => {\n live.current = false;\n };\n }, []);\n\n /* The slot is claimed BEFORE the subscription below is established, in hook\n order, so the two never disagree about whether it exists. */\n useEffect(\n () => acquireSlot(slotId, { type: token.type, tag, createdScope: latestCreatedScope.current }),\n [slotId, token.type, tag, createdSignature],\n );\n\n /* DXUI-87: a team switch empties the store but not the slot, so the slot's `meta` is the old\n team's until the new team answers. Cleared on a tenant CHANGE only: a mount must not wipe the\n meta of a slot another reader already holds. Declared before the runner effect, so the new\n read's answer always lands after the clear. */\n const seenTenant = useRef(storeTenant);\n useEffect(() => {\n if (seenTenant.current === storeTenant) return;\n seenTenant.current = storeTenant;\n clearSlotMeta(slotId);\n }, [slotId, storeTenant]);\n\n const subscribe = useCallback((listener: () => void) => subscribeToSlot(slotId, listener), [slotId]);\n const getSnapshot = useCallback(() => readSlot(slotId), [slotId]);\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, emptySlotSnapshot);\n\n /* The runner lives in a ref, created and disposed inside ONE effect — never\n via `useMemo`. See the matching, fully-explained comment above\n `useRecordRead`'s own `runnerRef`: a `useMemo`-cached runner survives\n React StrictMode's dev-only double-invoke of effects unchanged, so the\n simulated unmount's `dispose()` permanently kills the one instance the\n simulated remount then reuses — the read keeps registering successfully\n with the staleness driver, but its `request` callback is a silent no-op\n forever after. Owning the runner in a ref written inside the effect ties\n its lifetime to that effect's own mount/cleanup, so every remount —\n StrictMode-simulated or real — gets a genuinely fresh, live runner. */\n const runnerRef = useRef<RefetchRunner | null>(null);\n\n useEffect(() => {\n if (!enabled) {\n runnerRef.current = null;\n return;\n }\n\n /* DXUI-86: set false by this effect's cleanup. A request this effect's runner started under\n the old tenant or slot can answer after the new one's: it must not write its slot or status. */\n let current = true;\n const runner = new RefetchRunner(async () => {\n const requestTenant = tenantRef.current ?? getRecordStoreTenant();\n /* Read BEFORE the request, like the tenant: this answer settles exactly\n the rows that were pending when it was asked for, and none that arrive\n while it is in flight. */\n const settled = slotPendingKeys(slotId);\n const mark = slotAnswerMark();\n const setStatus = (next: (previous: RequestStatus) => RequestStatus) =>\n setKeyedStatus((current) => ({ slot: statusKey, status: next(current.slot === statusKey ? current.status : IDLE) }));\n setStatus((previous) => ({ ...previous, inFlight: true }));\n try {\n const page = await latestFetch.current();\n /* ONE notification for the whole page. Fifty singular writes are fifty\n notification passes and fifty render passes for one page load. */\n const { results } = writeAll(page.items, { source: \"fetch\", tag, tenant: requestTenant });\n /* Any row refused as older means the page is stale against the store: run it again, as a\n single-record read does, so the list cannot settle on an answer the store already outran. */\n const refused = results.flatMap((result) => result.refusedNested);\n const spent = runner.answered(refused.length > 0 || results.some((result) => result.verdict === \"dropped-older\"));\n if (spent && refused.length > 0) throw new NestedRecordRefusedError(refused);\n if (!current) return;\n writeSlot(slotId, page.items.map((item) => keyOf(item, token.type)).filter(isString), page.meta, settled, mark);\n if (live.current) setStatus(() => ({ inFlight: false, settled: true, error: undefined }));\n } catch (error) {\n if (current && live.current) setStatus(() => ({ inFlight: false, settled: true, error: toReadError(error, requestFailed.current) }));\n }\n }, { minIntervalMs: minRefetchIntervalMs });\n\n runnerRef.current = runner;\n runner.runNow();\n\n /* THE ROOTS ARE READ PER SIGNAL, not captured once: a slot's membership\n changes with every page, and a stale run under a demand resolves to the\n demand — which is a key this slot holds only because the fetch put it\n there. Twenty-five of them going stale in one burst match this one read\n once, which is breadth-coalescing falling out of the shape rather than\n being bolted on. */\n const unregister = registerActiveRead({ roots: () => slotKeys(slotId), request: () => runner.request() });\n\n return () => {\n current = false;\n unregister();\n runner.dispose();\n if (runnerRef.current === runner) runnerRef.current = null;\n };\n }, [slotId, statusKey, tag, enabled, minRefetchIntervalMs, token.type]);\n\n const refetch = useCallback(() => runnerRef.current?.runNow(), []);\n\n return useMemo(\n () => ({\n items: snapshot.items as readonly T[],\n pending: snapshot.pending as readonly T[],\n pendingCount: snapshot.pendingCount,\n meta: snapshot.meta as TMeta | undefined,\n /* From the first render, not from the first effect: until this slot's first answer lands,\n an enabled list is loading — never \"ready, zero rows\" for the frame before its fetch. */\n loading: enabled && !status.settled,\n refreshing: status.inFlight && status.settled,\n error: status.error,\n refetch,\n }),\n [snapshot, status, enabled, refetch],\n );\n}\n\n/**\n * Write a mutation's returned item into the store.\n *\n * A MUTATION RESPONSE IS A FETCH, and this exists because that is a question an\n * implementer will otherwise answer by coin flip. It is a full server answer to\n * a request this client made: it may satisfy a field-set tag, it clears\n * staleness on every field it carries, and it must NEVER be dropped by the\n * self-echo filter — that filter applies to broadcasts, and dropping a\n * mutation's own response would discard the server-computed fields the caller\n * asked for. Structurally it cannot be dropped, because the filter lives on the\n * broadcast path and this does not go through it.\n */\nexport function applyMutationResult(\n payload: RecordPayload,\n options: { tag: string; tenant?: string | number },\n): WriteResult {\n return write(payload, {\n source: \"fetch\",\n tag: options.tag,\n tenant: options.tenant ?? getRecordStoreTenant(),\n });\n}\n\n/**\n * Sweep unreachable records on a bounded schedule, for as long as this is\n * mounted.\n *\n * IT IS A HOOK, NOT AN INTERVAL STARTED ON IMPORT. A design-system module that\n * schedules work because somebody imported it is a worse defect than the leak\n * it prevents — it runs in every consumer, including ones with no store at all.\n * So the library exports the sweep and the CONSUMER decides when: this hook at\n * an app root, a call at a navigation boundary, or both. A navigation boundary\n * alone is not enough, because a broadcast can create a key no root reaches and\n * a screen nobody navigates away from accumulates those for as long as the tab\n * is open.\n */\nexport function useRecordStoreSweep(intervalMs = 60_000): void {\n useEffect(() => {\n const timer = setInterval(() => sweepRecords(), intervalMs);\n return () => clearInterval(timer);\n }, [intervalMs]);\n}\n\n/* --- Helpers ---------------------------------------------------------------- */\n\nfunction keyOf(payload: RecordPayload, fallbackType: string): string | undefined {\n const id = payload.id;\n if (typeof id !== \"string\" && typeof id !== \"number\") return undefined;\n const type = typeof payload.__type === \"string\" && payload.__type !== \"\" ? payload.__type : fallbackType;\n return recordKey(type, id);\n}\n\nfunction isString(value: string | undefined): value is string {\n return value !== undefined;\n}\n\n/** A read's re-runs were spent and the store still refused a nested record of its answer as older (DXUI-90). */\nclass NestedRecordRefusedError extends Error {\n constructor(readonly refused: readonly string[]) {\n super(`${refused.join(\", \")} stayed older than a change that reached the store, after ${MAX_DROPPED_RERUNS} re-reads`);\n }\n}\n\nfunction toReadError(error: unknown, requestFailed: string): ReadError {\n if (error instanceof NestedRecordRefusedError) return { message: error.message, cause: error, refused: error.refused };\n if (error instanceof Error) return { message: error.message, cause: error, refused: [] };\n if (typeof error === \"string\") return { message: error, cause: error, refused: [] };\n return { message: requestFailed, cause: error, refused: [] };\n}\n"],"names":["IDLE","useRecordRead","token","id","options","tag","tenant","enabled","minRefetchIntervalMs","key","recordKey","state","useRecord","status","setStatus","useState","latestFetch","useRef","requestFailedMessage","useUiStrings","requestFailed","tenantRef","live","useEffect","runnerRef","runner","RefetchRunner","requestTenant","getRecordStoreTenant","previous","payload","result","write","NestedRecordRefusedError","error","toReadError","roots","unregister","registerActiveRead","refetch","useCallback","useMemo","useRecordListRead","slotId","createdScope","normalizedCreatedScope","normalizeScope","createdSignature","scopeKey","latestCreatedScope","storeTenant","useSyncExternalStore","subscribeToTenant","statusKey","keyedStatus","setKeyedStatus","acquireSlot","seenTenant","clearSlotMeta","subscribe","listener","subscribeToSlot","getSnapshot","readSlot","snapshot","emptySlotSnapshot","current","settled","slotPendingKeys","mark","slotAnswerMark","next","page","results","writeAll","refused","writeSlot","item","keyOf","isString","slotKeys","applyMutationResult","useRecordStoreSweep","intervalMs","timer","sweepRecords","fallbackType","type","value","MAX_DROPPED_RERUNS"],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { devWarn as J } from "../dev-warn.js";
|
|
2
|
+
import { getRecordStoreTenant as B, pushOptimisticLayer as N, flushRecordNotifications as k, removeOptimisticLayer as j, write as b, keepOptimisticLayer as R, trimSupersededFields as C, readBaseField as A, trimOptimisticLayers as D, pushKeptAnswerLayer as q, storedShape as G } from "../records/store.js";
|
|
3
|
+
import { recordKey as T, payloadIdentity as I, isEnvelopeKey as H, normalizeTimestamp as P } from "../records/wire.js";
|
|
4
|
+
import { addOptimisticMember as Q, settleOptimisticMember as W } from "./slots.js";
|
|
5
|
+
let E = 0;
|
|
6
|
+
const L = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map();
|
|
7
|
+
function U(e, r) {
|
|
8
|
+
return r === void 0 ? e : `${e}\0${r}`;
|
|
9
|
+
}
|
|
10
|
+
function V(e, r, o) {
|
|
11
|
+
const i = {}, n = o === void 0 ? void 0 : x(A(e, o));
|
|
12
|
+
for (const t of r) i[t] = n === void 0 ? A(e, t) : n[t];
|
|
13
|
+
return i;
|
|
14
|
+
}
|
|
15
|
+
function F(e, r, o, i, n, t, d, s, h) {
|
|
16
|
+
if (!d) return;
|
|
17
|
+
const c = g(s) && I(s)?.key === e, u = c ? i === void 0 ? s : x(s[i]) : {}, l = V(e, n, i), m = {};
|
|
18
|
+
for (const a of n) {
|
|
19
|
+
if (!(a in d.values) || K(l[a], d.values[a])) continue;
|
|
20
|
+
(c ? a in u && K(l[a], G(u[a])) : t.includes(a)) && (m[a] = d.values[a]);
|
|
21
|
+
}
|
|
22
|
+
if (Object.keys(m).length === 0) return;
|
|
23
|
+
const y = i === void 0 ? m : { [i]: { ...x(A(e, i)), ...m } };
|
|
24
|
+
b({ ...y, __type: r, id: o }, { source: "fetch", tenant: h });
|
|
25
|
+
}
|
|
26
|
+
function K(e, r) {
|
|
27
|
+
return JSON.stringify(e) === JSON.stringify(r);
|
|
28
|
+
}
|
|
29
|
+
function X(e, r, o, i) {
|
|
30
|
+
if (r.length === 0) return e;
|
|
31
|
+
const n = { ...e };
|
|
32
|
+
if (o === void 0) {
|
|
33
|
+
for (const s of r) delete n[s];
|
|
34
|
+
return n;
|
|
35
|
+
}
|
|
36
|
+
const t = n[o];
|
|
37
|
+
if (typeof t != "object" || t === null || Array.isArray(t)) return e;
|
|
38
|
+
const d = { ...t };
|
|
39
|
+
for (const s of r)
|
|
40
|
+
i && s in i.values ? d[s] = i.values[s] : delete d[s];
|
|
41
|
+
return n[o] = d, n;
|
|
42
|
+
}
|
|
43
|
+
function x(e) {
|
|
44
|
+
return typeof e == "object" && e !== null && !Array.isArray(e) ? e : {};
|
|
45
|
+
}
|
|
46
|
+
async function se(e, r, o = {}) {
|
|
47
|
+
const i = Y(e, o);
|
|
48
|
+
let n, t;
|
|
49
|
+
try {
|
|
50
|
+
n = await r(), t = o.answer ? o.answer(n) : n;
|
|
51
|
+
} catch (d) {
|
|
52
|
+
throw i.rollback(), d;
|
|
53
|
+
}
|
|
54
|
+
return i.commit(t), n;
|
|
55
|
+
}
|
|
56
|
+
function Y(e, r = {}) {
|
|
57
|
+
const o = r.tenant ?? B(), i = e.type.type;
|
|
58
|
+
if (e.kind === "create") return Z(e, i, o, r.tag);
|
|
59
|
+
const n = e.id, t = T(i, n), d = e.kind === "update" ? e.at : void 0, s = e.kind !== "update" ? {} : d === void 0 ? $(e.patch) : ee(e.patch), h = e.kind === "delete" ? (/* @__PURE__ */ new Date()).toISOString() : void 0, c = N(i, n, { fields: s, at: d, tombstone: h });
|
|
60
|
+
k();
|
|
61
|
+
let u = !1;
|
|
62
|
+
return {
|
|
63
|
+
id: n,
|
|
64
|
+
key: t,
|
|
65
|
+
commit(l, m) {
|
|
66
|
+
if (u) return;
|
|
67
|
+
u = !0;
|
|
68
|
+
let y;
|
|
69
|
+
if (r.revOrdered && e.kind === "update" && (y = te(l, t), y === void 0))
|
|
70
|
+
throw j(t, c), k(), new Error(`a rev-ordered ${i} write needs its own record's answer with a version, or nothing can order it`);
|
|
71
|
+
const a = U(t, d), f = L.get(a), v = w.get(t), _ = f === void 0 || r.revOrdered ? [] : Object.keys(f.through).filter((p) => f.through[p] > c), z = e.kind === "delete" ? v !== void 0 && v.last > c : v !== void 0 && v.deleted > c, S = Object.fromEntries(Object.entries(s).filter(([p]) => !_.includes(p)));
|
|
72
|
+
let M;
|
|
73
|
+
if (z)
|
|
74
|
+
r.answerStored && e.kind !== "delete" && F(t, i, n, d, _, Object.keys(s), f, l, o);
|
|
75
|
+
else {
|
|
76
|
+
if (e.kind === "delete")
|
|
77
|
+
b({ __type: i, id: n, deleted_at: h }, { source: "fetch", tenant: o });
|
|
78
|
+
else if (r.answerStored)
|
|
79
|
+
F(t, i, n, d, _, Object.keys(s), f, l, o), m?.verdict === "dropped-older" && g(l) && (M = R(t, c, l, o));
|
|
80
|
+
else if (g(l)) {
|
|
81
|
+
const O = X(l, _, d, f);
|
|
82
|
+
b(O, { source: "fetch", tag: r.tag, tenant: o }).verdict === "dropped-older" && (y !== void 0 && C(t, c, y), M = R(t, c, O, o));
|
|
83
|
+
} else d === void 0 ? b({ ...S, __type: i, id: n }, { source: "fetch", tenant: o }) : b({ __type: i, id: n, [d]: { ...x(A(t, d)), ...S } }, { source: "fetch", tenant: o });
|
|
84
|
+
const p = { ...f?.through ?? {} };
|
|
85
|
+
for (const O of Object.keys(S)) p[O] = Math.max(p[O] ?? 0, c);
|
|
86
|
+
L.set(a, {
|
|
87
|
+
through: p,
|
|
88
|
+
/* What each field settled at: the base's value, or the kept layer's where the base refused it. */
|
|
89
|
+
values: { ...f?.values ?? {}, ...V(t, Object.keys(S), d), ...M }
|
|
90
|
+
}), w.set(t, {
|
|
91
|
+
last: Math.max(v?.last ?? 0, c),
|
|
92
|
+
deleted: e.kind === "delete" ? Math.max(v?.deleted ?? 0, c) : v?.deleted ?? 0
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
D(t, c, Object.keys(s), d), M === void 0 && j(t, c), k();
|
|
96
|
+
},
|
|
97
|
+
rollback() {
|
|
98
|
+
u || (u = !0, j(t, c), k());
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function Z(e, r, o, i) {
|
|
103
|
+
E -= 1;
|
|
104
|
+
const n = E, t = T(r, n), d = N(r, n, {
|
|
105
|
+
fields: { ...$(e.fields), id: n },
|
|
106
|
+
created: !0
|
|
107
|
+
}), s = Q(t, r, e.lists, e.position ?? "start");
|
|
108
|
+
k();
|
|
109
|
+
let h = !1;
|
|
110
|
+
const c = () => {
|
|
111
|
+
W(t, null), j(t, d), k();
|
|
112
|
+
};
|
|
113
|
+
return {
|
|
114
|
+
id: n,
|
|
115
|
+
key: t,
|
|
116
|
+
commit(u) {
|
|
117
|
+
if (h) return;
|
|
118
|
+
h = !0;
|
|
119
|
+
const l = g(u) ? I(u) : void 0;
|
|
120
|
+
if (!g(u) || !l) {
|
|
121
|
+
J(
|
|
122
|
+
"optimisticWrite",
|
|
123
|
+
`a ${r} create succeeded but its answer carried no __type and id, so the pending row cannot become the real one — pass \`answer\` to pick the record out of the result.`
|
|
124
|
+
), c();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const m = new Set([i, ...s.map((f) => f.tag)].filter((f) => f !== void 0));
|
|
128
|
+
m.size === 0 && m.add(void 0);
|
|
129
|
+
let y = !1;
|
|
130
|
+
for (const f of m)
|
|
131
|
+
b(u, { source: "fetch", tag: f, tenant: o }).verdict === "dropped-older" && (y = !0);
|
|
132
|
+
y && q(l.key, r, l.id, u, o);
|
|
133
|
+
const a = w.get(l.key);
|
|
134
|
+
w.set(l.key, {
|
|
135
|
+
last: Math.max(a?.last ?? 0, d),
|
|
136
|
+
deleted: a?.deleted ?? 0
|
|
137
|
+
}), W(t, l.key), j(t, d), k();
|
|
138
|
+
},
|
|
139
|
+
rollback() {
|
|
140
|
+
h || (h = !0, c());
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function $(e) {
|
|
145
|
+
const r = {};
|
|
146
|
+
for (const [o, i] of Object.entries(e))
|
|
147
|
+
i === void 0 || H(o) || o === "id" || (r[o] = i);
|
|
148
|
+
return r;
|
|
149
|
+
}
|
|
150
|
+
function ee(e) {
|
|
151
|
+
const r = {};
|
|
152
|
+
for (const [o, i] of Object.entries(e)) i !== void 0 && (r[o] = i);
|
|
153
|
+
return r;
|
|
154
|
+
}
|
|
155
|
+
function g(e) {
|
|
156
|
+
return typeof e == "object" && e !== null && I(e) !== void 0;
|
|
157
|
+
}
|
|
158
|
+
function te(e, r) {
|
|
159
|
+
return g(e) && I(e)?.key === r ? P(e.__timestamp) : void 0;
|
|
160
|
+
}
|
|
161
|
+
function ce() {
|
|
162
|
+
L.clear(), w.clear();
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
Y as beginOptimisticWrite,
|
|
166
|
+
se as optimisticWrite,
|
|
167
|
+
ce as resetOptimisticWrites
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=optimistic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimistic.js","sources":["../../../src/lib/reads/optimistic.ts"],"sourcesContent":["import { devWarn } from \"../dev-warn\";\nimport {\n flushRecordNotifications,\n getRecordStoreTenant,\n recordKey,\n write,\n type RecordPayload,\n type RecordTypeToken,\n type WriteResult,\n} from \"../records\";\nimport {\n keepOptimisticLayer,\n pushKeptAnswerLayer,\n pushOptimisticLayer,\n readBaseField,\n storedShape,\n removeOptimisticLayer,\n trimOptimisticLayers,\n trimSupersededFields,\n} from \"../records/store\";\nimport { isEnvelopeKey, normalizeTimestamp, payloadIdentity } from \"../records/wire\";\nimport { addOptimisticMember, settleOptimisticMember, type SlotDescriptor } from \"./slots\";\n\n/* ============================================================================\n THE OPTIMISTIC WRITE — the one way a user-initiated write reaches the store.\n\n Apply the change the instant the reader acts, send the request, replace the belief with the\n server's answer, and on failure put back exactly what was there before and rethrow — for an\n update, a create and a delete alike. The caller keeps its own refusal handling; it only has\n to stop hand-rolling this part.\n\n FOUR GUARANTEES, each of which a hand-rolled copy of this got wrong at least once:\n\n 1. SUBSCRIBERS HEAR ABOUT IT SYNCHRONOUSLY. The store batches notification on an animation\n frame, and a hidden page never schedules one — so a write made there reached nobody until\n something unrelated re-rendered. Every step here (apply, commit, rollback) flushes before\n it returns. A user's own action is one change, not a burst, so there is nothing to batch.\n\n 2. A ROLLBACK CAN NEVER LOSE TO TIMESTAMP ORDERING. The belief is an optimistic LAYER over the\n record's base (`store.ts`, \"Optimistic layers\"), not a write into it. The base — the only\n thing the ordering guard adjudicates — is untouched, so a rollback is a removal that has\n nothing to outrank, and no client clock ever enters the store to outrank the server.\n\n 3. A LATER WRITE BEATS AN EARLIER ONE, whatever order the answers arrive in. Layers apply in\n issue order, so the newest belief is what a reader sees until its own answer lands. When a\n write's answer lands, older writes' beliefs about the same fields are retired, and an older\n write's answer arriving after a newer one has committed is not applied over the fields that newer\n write settled — and a caller using `answerStored` has the newer write's values put back over\n what it stored. A set,\n clear, set, clear on one field therefore shows the last clear from the moment it is made.\n A write naming `revOrdered` leaves this to the server: its answer's version alone decides.\n\n A write to ONE ENTRY of a keyed map field (`data_points`, `attributes`) names the field as `at`,\n so concurrent beliefs about different entries stay independent and a read that rewrites the map\n underneath shows through every entry no belief is about.\n\n 4. THE ENVELOPE TAKES CARE OF ITSELF. The type comes from the token and the id from the call,\n so no caller patches `__type` back into anything, and reads carry `__type` on their own.\n ========================================================================= */\n\n/** Which records to change, and how. */\nexport type OptimisticWriteSpec<T> =\n | {\n readonly kind: \"update\";\n readonly type: RecordTypeToken<T>;\n readonly id: string | number;\n /** Only the fields that change. A present `null` clears; an `undefined` value is ignored. */\n readonly patch: Partial<T>;\n readonly at?: undefined;\n }\n | {\n readonly kind: \"update\";\n readonly type: RecordTypeToken<T>;\n readonly id: string | number;\n /**\n * A field holding a keyed map (`data_points`, `attributes`): `patch` then names KEYS OF\n * THAT MAP, merged over whatever it holds. Use it whenever a write changes one entry of a\n * map — patching the whole field instead would pin every other entry at its value as of\n * the click, and undoing one of two concurrent writes would undo both.\n */\n readonly at: Extract<keyof T, string>;\n readonly patch: Readonly<Record<string, unknown>>;\n }\n | {\n readonly kind: \"create\";\n readonly type: RecordTypeToken<T>;\n /** The record as the reader will see it until the server answers. Its `id` is assigned. */\n readonly fields: Partial<T>;\n /**\n * Which live list reads show the pending row. Default: every list of this record type —\n * the library cannot evaluate a server-side filter, so narrow it when a list is filtered.\n */\n readonly lists?: (slot: SlotDescriptor) => boolean;\n /** Above the fetched page (default) or below it. */\n readonly position?: \"start\" | \"end\";\n }\n | {\n readonly kind: \"delete\";\n readonly type: RecordTypeToken<T>;\n readonly id: string | number;\n };\n\n/**\n * Who stores the answer and what orders it. The two options exclude each other: `answerStored`\n * says the library never sees the store's verdict on the answer, and `revOrdered` needs it.\n */\ntype AnswerHandling =\n | {\n /**\n * The request stores its own answer — an API layer that writes every response into the store,\n * or a caller that normalizes the answer before storing it. Commit then only retires the belief:\n * nothing is written, so the stored answer is exactly what shows.\n */\n readonly answerStored?: boolean;\n readonly revOrdered?: undefined;\n }\n | {\n readonly answerStored?: undefined;\n /**\n * DXUI-96: the server orders every save of this record strictly by version, and every save,\n * this option or not, answers a versioned row: the record as that save left it, never built\n * from the record as held. Guarantee 3 is then wrong: a later-sent write can run first, so its\n * answer can be the older one, and the version alone decides. An update's answer is stored\n * whole by the store's comparison, whatever a crossing write settled. One refused as older\n * gives up every field the record holds at or above its version, and the rest of its belief\n * stays on screen until a read. A later-sent write's answer has already retired an older\n * belief about its fields, so that older write can have nothing left to keep: if a partial\n * event then raises the version past its answer, the later write's value shows until a read.\n * An answer that is not this record's, or carries no version, cannot be ordered: the write is\n * put back and rejects. A create or a delete has no fields to order and ignores this.\n */\n readonly revOrdered: true;\n };\n\nexport type OptimisticWriteOptions<A = unknown> = AnswerHandling & {\n /**\n * The field-set tag the server's answer satisfies, as `applyMutationResult` takes it. A\n * create's answer ALSO satisfies the tag of every list it was shown in, or the real row would\n * be held but not rendered the moment it replaced the pending one.\n */\n readonly tag?: string;\n /** The tenant the request is issued under. Captured now, never when the answer lands. */\n readonly tenant?: string | number;\n /**\n * Pick the record out of the request's result, when the result is an envelope rather than the\n * record itself. Default: the result, if it carries `__type` and `id`.\n */\n readonly answer?: (result: A) => unknown;\n};\n\n/** An applied write whose request the caller runs itself — `beginOptimisticWrite`'s handle. */\nexport interface OptimisticHandle {\n /** The record's id — for a create, the temporary one the pending row carries. */\n readonly id: string | number;\n /** `Type:id`, as the store keys it. */\n readonly key: string;\n /**\n * The request succeeded. `answer` is the server's record, if it sent one. Idempotent.\n * `stored` is the result of the `write()` that stored the answer, for a caller that stored it\n * itself (`answerStored`): a `dropped-older` one keeps the written value on screen.\n * Under `revOrdered`, an update's `answer` must be its own record's with a version: anything\n * else puts the write back, as `rollback` does, and throws.\n */\n commit(answer?: unknown, stored?: WriteResult): void;\n /** The request failed: put back exactly what was there before. Idempotent. */\n rollback(): void;\n}\n\n/** A temporary id: negative, so it can never be a real row's, and unique for the session. */\nlet lastTemporaryId = 0;\n\n/**\n * Per record key (and map field, for a keyed write): for each field a write settled, the newest\n * write that settled it, and the base value that field settled at.\n *\n * ORDERING IS PER FIELD (DXUI-89, DEC-372). A write's answer loses only the fields a newer write\n * settled; every other field applies and is recorded here, so a newer write on another field\n * says nothing about it, and an older write can never land over a field a newer one settled.\n *\n * THE VALUES ARE WHAT MAKES \"A LATER WRITE BEATS AN EARLIER ONE\" HOLD FOR `answerStored`. This\n * primitive never applies a superseded answer — but a caller using `answerStored` has already\n * written that stale answer by the time its write settles, and an equal timestamp lets it merge over\n * the newer one. So such a write that settles after a newer write on the same fields puts those\n * fields back to what the newer write left, but only where the base still holds the stale answer's\n * value (anything else, a read or a broadcast, is newer than both writes and stays), or, when the\n * caller passes no answer, for the write's own fields.\n */\ninterface Committed {\n readonly through: Readonly<Record<string, number>>;\n readonly values: Readonly<Record<string, unknown>>;\n}\nconst committedThrough = new Map<string, Committed>();\n\n/**\n * Per record key: the newest write of any kind that settled, and the newest delete. A delete has\n * no fields, so the per-field check cannot order it: it is superseded by any newer settled write\n * on the record (a restore, the row added back), and it supersedes any older write, whose answer\n * would otherwise undelete the row.\n */\ninterface RecordSettled {\n readonly last: number;\n readonly deleted: number;\n}\nconst recordSettled = new Map<string, RecordSettled>();\n\nfunction committedKey(key: string, at: string | undefined): string {\n return at === undefined ? key : `${key}\u0000${at}`;\n}\n\n/** The base value of each of `fields`, as stored — top-level fields, or keys of the map at `at`. */\nfunction baseValues(key: string, fields: readonly string[], at: string | undefined): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n const map = at === undefined ? undefined : asMap(readBaseField(key, at));\n for (const field of fields) out[field] = map === undefined ? readBaseField(key, field) : map[field];\n return out;\n}\n\n/**\n * Put back, for an `answerStored` write, the fields a newer write settled that the caller's stored\n * answer can have overwritten. With an answer: a field the answer carries and the base still holds\n * the value of; anything else was moved on by a read or a broadcast, newer than both writes. With\n * no answer: the write's own fields, as nothing tells a stale store from a read.\n */\nfunction restoreNewer(\n key: string,\n type: string,\n id: string | number,\n at: string | undefined,\n fields: readonly string[],\n own: readonly string[],\n committed: Committed | undefined,\n answer: unknown,\n tenant: string | number | undefined,\n): void {\n if (!committed) return;\n /* Only this record's own answer says what the caller stored; another record's is no answer. */\n const answered = isRecordAnswer(answer) && payloadIdentity(answer)?.key === key;\n const carried = !answered ? {} : at === undefined ? answer : asMap((answer as Record<string, unknown>)[at]);\n const held = baseValues(key, fields, at);\n const restore: Record<string, unknown> = {};\n for (const field of fields) {\n if (!(field in committed.values) || sameValue(held[field], committed.values[field])) continue;\n /* An answer decides: the base must hold the value it carries, compared in the stored shape.\n With no answer nothing tells a stale store from a read, so the write's own fields go back. */\n const stale = answered ? field in carried && sameValue(held[field], storedShape(carried[field])) : own.includes(field);\n if (stale) restore[field] = committed.values[field];\n }\n if (Object.keys(restore).length === 0) return;\n const payload = at === undefined ? restore : { [at]: { ...asMap(readBaseField(key, at)), ...restore } };\n write({ ...payload, __type: type, id }, { source: \"fetch\", tenant });\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/**\n * The answer without the fields a newer write settled — top-level fields, or keys of the map at\n * `at`. The store replaces a map whole, so a stripped map key takes the newer write's value rather\n * than going missing; an answer carrying no map is left alone.\n */\nfunction withoutFields(\n answer: RecordPayload,\n fields: readonly string[],\n at: string | undefined,\n committed: Committed | undefined,\n): RecordPayload {\n if (fields.length === 0) return answer;\n const out: Record<string, unknown> = { ...answer };\n if (at === undefined) {\n for (const field of fields) delete out[field];\n return out as RecordPayload;\n }\n const carried = out[at];\n if (typeof carried !== \"object\" || carried === null || Array.isArray(carried)) return answer;\n const map = { ...(carried as Record<string, unknown>) };\n for (const field of fields) {\n if (committed && field in committed.values) map[field] = committed.values[field];\n else delete map[field];\n }\n out[at] = map;\n return out as RecordPayload;\n}\n\nfunction asMap(value: unknown): Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\n/**\n * Apply an optimistic write and run its request.\n *\n * Applies synchronously — before `request` is even called — so the reader sees the change in\n * the same tick as their click, hidden page or not. On success the server's answer replaces the\n * belief and the request's own result is returned untouched. On failure the belief is removed\n * and the error is rethrown for the caller's refusal handling.\n */\nexport async function optimisticWrite<T, A>(\n spec: OptimisticWriteSpec<T>,\n request: () => Promise<A>,\n options: OptimisticWriteOptions<A> = {},\n): Promise<A> {\n const handle = beginOptimisticWrite(spec, options);\n let result: A;\n let answer: unknown;\n try {\n result = await request();\n /* DXUI-91: the caller's `answer` runs inside the guard, so one that throws (an answer it\n refuses) puts the belief back exactly as a failed request does. */\n answer = options.answer ? options.answer(result) : result;\n } catch (error) {\n handle.rollback();\n throw error;\n }\n handle.commit(answer);\n return result;\n}\n\n/** Every option but `answer`: this caller picks the record out of the result itself. */\ntype BeginOptions = AnswerHandling & Pick<OptimisticWriteOptions, \"tag\" | \"tenant\">;\n\n/**\n * The same write, for a caller that owns its request lifecycle — apply now, and call `commit`\n * or `rollback` on the handle when the request settles.\n */\nexport function beginOptimisticWrite<T>(\n spec: OptimisticWriteSpec<T>,\n options: BeginOptions = {},\n): OptimisticHandle {\n const tenant = options.tenant ?? getRecordStoreTenant();\n const type = spec.type.type;\n\n if (spec.kind === \"create\") return beginCreate(spec, type, tenant, options.tag);\n\n const id = spec.id;\n const key = recordKey(type, id);\n const at = spec.kind === \"update\" ? spec.at : undefined;\n const fields =\n spec.kind !== \"update\"\n ? {}\n : at === undefined\n ? dataFields(spec.patch as Record<string, unknown>)\n : mapEntries(spec.patch as Record<string, unknown>);\n const tombstone = spec.kind === \"delete\" ? new Date().toISOString() : undefined;\n const layerId = pushOptimisticLayer(type, id, { fields, at, tombstone });\n flushRecordNotifications();\n\n let settled = false;\n return {\n id,\n key,\n commit(answer, stored) {\n if (settled) return;\n settled = true;\n /* Set only for a rev-ordered update: a create or a delete has no fields to order (DXUI-96). */\n let version: number | undefined;\n if (options.revOrdered && spec.kind === \"update\") {\n version = answerVersion(answer, key);\n if (version === undefined) {\n removeOptimisticLayer(key, layerId);\n flushRecordNotifications();\n throw new Error(`a rev-ordered ${type} write needs its own record's answer with a version, or nothing can order it`);\n }\n }\n const slot = committedKey(key, at);\n const committed = committedThrough.get(slot);\n const settledRecord = recordSettled.get(key);\n /* Ordering is per field (DXUI-89, DEC-372): every field a newer write already settled is\n taken out of this write's answer, and what is left applies. Only a delete, which has no\n fields, is ordered against the whole record. A rev-ordered answer takes nothing out: the\n store's comparison decides it whole (DXUI-96). */\n const newer =\n committed === undefined || options.revOrdered ? [] : Object.keys(committed.through).filter((field) => committed.through[field] > layerId);\n const skipped =\n spec.kind === \"delete\"\n ? settledRecord !== undefined && settledRecord.last > layerId\n : settledRecord !== undefined && settledRecord.deleted > layerId;\n const live = Object.fromEntries(Object.entries(fields).filter(([field]) => !newer.includes(field)));\n let keptValues: Record<string, unknown> | undefined;\n if (skipped) {\n if (options.answerStored && spec.kind !== \"delete\") restoreNewer(key, type, id, at, newer, Object.keys(fields), committed, answer, tenant);\n } else {\n if (spec.kind === \"delete\") {\n /* The tombstone, not the answer: a delete's answer may describe the row as it was, with\n `__deleted_at: null`, which the store reads as an explicit un-delete. */\n write({ __type: type, id, deleted_at: tombstone }, { source: \"fetch\", tenant });\n } else if (options.answerStored) {\n /* The caller's request stored its own answer; whatever it stored for a field a newer\n write settled is stale, so those fields are put back. */\n restoreNewer(key, type, id, at, newer, Object.keys(fields), committed, answer, tenant);\n if (stored?.verdict === \"dropped-older\" && isRecordAnswer(answer)) keptValues = keepOptimisticLayer(key, layerId, answer, tenant);\n } else if (isRecordAnswer(answer)) {\n const surviving = withoutFields(answer, newer, at, committed);\n const result = write(surviving, { source: \"fetch\", tag: options.tag, tenant });\n if (result.verdict === \"dropped-older\") {\n if (version !== undefined) trimSupersededFields(key, layerId, version);\n keptValues = keepOptimisticLayer(key, layerId, surviving, tenant);\n }\n } else if (at === undefined) {\n /* No answer to read: the server accepted the patch, so the base takes it. No\n timestamp — a client clock never enters the store. */\n write({ ...live, __type: type, id }, { source: \"fetch\", tenant });\n } else {\n /* The same, for keys of one map: merged into the map the base holds right now. */\n write({ __type: type, id, [at]: { ...asMap(readBaseField(key, at)), ...live } }, { source: \"fetch\", tenant });\n }\n const through: Record<string, number> = { ...(committed?.through ?? {}) };\n /* A rev-ordered write can settle after a newer one (DXUI-96); the mark never moves back. */\n for (const field of Object.keys(live)) through[field] = Math.max(through[field] ?? 0, layerId);\n committedThrough.set(slot, {\n through,\n /* What each field settled at: the base's value, or the kept layer's where the base refused it. */\n values: { ...(committed?.values ?? {}), ...baseValues(key, Object.keys(live), at), ...keptValues },\n });\n recordSettled.set(key, {\n last: Math.max(settledRecord?.last ?? 0, layerId),\n deleted: spec.kind === \"delete\" ? Math.max(settledRecord?.deleted ?? 0, layerId) : (settledRecord?.deleted ?? 0),\n });\n }\n trimOptimisticLayers(key, layerId, Object.keys(fields), at);\n /* A dropped answer keeps its layer (DXUI-78, DEC-285): the base refused it as older, and\n removing the layer would bring the old value back until a read lands. A layer with no\n field left to keep has nothing to bring back. */\n if (keptValues === undefined) removeOptimisticLayer(key, layerId);\n flushRecordNotifications();\n },\n rollback() {\n if (settled) return;\n settled = true;\n removeOptimisticLayer(key, layerId);\n flushRecordNotifications();\n },\n };\n}\n\nfunction beginCreate<T>(\n spec: Extract<OptimisticWriteSpec<T>, { kind: \"create\" }>,\n type: string,\n tenant: string | number | undefined,\n tag: string | undefined,\n): OptimisticHandle {\n lastTemporaryId -= 1;\n const id = lastTemporaryId;\n const key = recordKey(type, id);\n const layerId = pushOptimisticLayer(type, id, {\n fields: { ...dataFields(spec.fields as Record<string, unknown>), id },\n created: true,\n });\n const joined = addOptimisticMember(key, type, spec.lists, spec.position ?? \"start\");\n flushRecordNotifications();\n\n let settled = false;\n const discard = () => {\n settleOptimisticMember(key, null);\n removeOptimisticLayer(key, layerId);\n flushRecordNotifications();\n };\n\n return {\n id,\n key,\n commit(answer) {\n if (settled) return;\n settled = true;\n const identity = isRecordAnswer(answer) ? payloadIdentity(answer) : undefined;\n if (!isRecordAnswer(answer) || !identity) {\n devWarn(\n \"optimisticWrite\",\n `a ${type} create succeeded but its answer carried no __type and id, so the pending row ` +\n \"cannot become the real one — pass `answer` to pick the record out of the result.\",\n );\n discard();\n return;\n }\n /* Real row in first, then swapped into the lists, then the pending row out — all before\n one flush, so no reader ever sees the list without the row. */\n const tags = new Set<string | undefined>([tag, ...joined.map((slot) => slot.tag)].filter((t) => t !== undefined));\n if (tags.size === 0) tags.add(undefined);\n let dropped = false;\n for (const each of tags) {\n if (write(answer, { source: \"fetch\", tag: each, tenant }).verdict === \"dropped-older\") dropped = true;\n }\n /* The real row already holds something newer than this answer: keep the answer's fields on\n it, so the row never shows empty once the pending one goes (DXUI-78, DEC-285). */\n if (dropped) pushKeptAnswerLayer(identity.key, type, identity.id, answer, tenant);\n /* The row exists under its real key from this layer on: a delete of that id issued before\n the create is older than it (DXUI-89). */\n const settledRecord = recordSettled.get(identity.key);\n recordSettled.set(identity.key, {\n last: Math.max(settledRecord?.last ?? 0, layerId),\n deleted: settledRecord?.deleted ?? 0,\n });\n settleOptimisticMember(key, identity.key);\n removeOptimisticLayer(key, layerId);\n flushRecordNotifications();\n },\n rollback() {\n if (settled) return;\n settled = true;\n discard();\n },\n };\n}\n\n/** The data fields of a patch: envelope keys and `undefined` values carry nothing to show. */\nfunction dataFields(patch: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(patch)) {\n if (value === undefined || isEnvelopeKey(field) || field === \"id\") continue;\n out[field] = value;\n }\n return out;\n}\n\n/** The entries of a keyed-map patch: every key is data here, only `undefined` carries nothing. */\nfunction mapEntries(patch: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(patch)) if (value !== undefined) out[field] = value;\n return out;\n}\n\nfunction isRecordAnswer(value: unknown): value is RecordPayload {\n return typeof value === \"object\" && value !== null && payloadIdentity(value as RecordPayload) !== undefined;\n}\n\n/** The version of `value` when it is `key`'s own record at one the store can compare. */\nfunction answerVersion(value: unknown, key: string): number | undefined {\n return isRecordAnswer(value) && payloadIdentity(value)?.key === key ? normalizeTimestamp(value.__timestamp) : undefined;\n}\n\n/** Test seam. Nothing in the library calls this. */\nexport function resetOptimisticWrites(): void {\n committedThrough.clear();\n recordSettled.clear();\n}\n"],"names":["lastTemporaryId","committedThrough","recordSettled","committedKey","key","at","baseValues","fields","out","map","asMap","readBaseField","field","restoreNewer","type","id","own","committed","answer","tenant","answered","isRecordAnswer","payloadIdentity","carried","held","restore","sameValue","storedShape","payload","write","a","b","withoutFields","value","optimisticWrite","spec","request","options","handle","beginOptimisticWrite","result","error","getRecordStoreTenant","beginCreate","recordKey","dataFields","mapEntries","tombstone","layerId","pushOptimisticLayer","flushRecordNotifications","settled","stored","version","answerVersion","removeOptimisticLayer","slot","settledRecord","newer","skipped","live","keptValues","keepOptimisticLayer","surviving","trimSupersededFields","through","trimOptimisticLayers","tag","joined","addOptimisticMember","discard","settleOptimisticMember","identity","devWarn","tags","t","dropped","each","patch","isEnvelopeKey","normalizeTimestamp","resetOptimisticWrites"],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { devWarn as c } from "../dev-warn.js";
|
|
2
|
+
import { readStaleness as a, takeStaleEvents as h, subscribeToStaleness as m } from "../records/store.js";
|
|
3
|
+
import { subscribeToRealtimeEpoch as p } from "../realtime/registry.js";
|
|
4
|
+
const v = 1e3, o = 3;
|
|
5
|
+
class x {
|
|
6
|
+
constructor(e, s = {}) {
|
|
7
|
+
this.run = e, this.minIntervalMs = s.minIntervalMs ?? v, this.now = s.now ?? Date.now;
|
|
8
|
+
}
|
|
9
|
+
run;
|
|
10
|
+
inFlight = !1;
|
|
11
|
+
rerun = !1;
|
|
12
|
+
droppedReruns = 0;
|
|
13
|
+
lastFinishedAt = 0;
|
|
14
|
+
timer = null;
|
|
15
|
+
disposed = !1;
|
|
16
|
+
minIntervalMs;
|
|
17
|
+
now;
|
|
18
|
+
/**
|
|
19
|
+
* Report how the store took this run's answer. A refused one runs again, up to
|
|
20
|
+
* `MAX_DROPPED_RERUNS` in a row; an accepted one clears the count.
|
|
21
|
+
*
|
|
22
|
+
* @returns true when the re-runs are spent and this answer was refused anyway: the caller owes
|
|
23
|
+
* its reader a loud failure, since the runner will not ask again until the next signal.
|
|
24
|
+
*/
|
|
25
|
+
answered(e) {
|
|
26
|
+
return e ? this.droppedReruns >= o ? (c("refetch", `a read was refused as older ${o + 1} times in a row, so it stopped asking until the next signal`), !0) : (this.droppedReruns += 1, this.request(), !1) : (this.droppedReruns = 0, !1);
|
|
27
|
+
}
|
|
28
|
+
/** Ask for a refetch. Respects the floor and the in-flight request. */
|
|
29
|
+
request() {
|
|
30
|
+
if (this.disposed) return;
|
|
31
|
+
if (this.inFlight) {
|
|
32
|
+
this.rerun = !0;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (this.timer !== null) return;
|
|
36
|
+
const e = this.minIntervalMs - (this.now() - this.lastFinishedAt);
|
|
37
|
+
if (e > 0) {
|
|
38
|
+
this.timer = setTimeout(() => {
|
|
39
|
+
this.timer = null, this.execute();
|
|
40
|
+
}, e);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.execute();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run now, floor and all.
|
|
47
|
+
*
|
|
48
|
+
* For the FIRST fetch and for a key change — neither is a refetch, and making
|
|
49
|
+
* a fresh screen wait out an interval that exists to damp a broadcast stream
|
|
50
|
+
* would be the floor working against its own purpose.
|
|
51
|
+
*/
|
|
52
|
+
runNow() {
|
|
53
|
+
if (!this.disposed) {
|
|
54
|
+
if (this.timer !== null && (clearTimeout(this.timer), this.timer = null), this.inFlight) {
|
|
55
|
+
this.rerun = !0;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.execute();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
execute() {
|
|
62
|
+
this.inFlight = !0, this.run().finally(() => {
|
|
63
|
+
this.inFlight = !1, this.lastFinishedAt = this.now(), !(this.disposed || !this.rerun) && (this.rerun = !1, this.request());
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
dispose() {
|
|
67
|
+
this.disposed = !0, this.timer !== null && (clearTimeout(this.timer), this.timer = null);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let R = 1;
|
|
71
|
+
const i = /* @__PURE__ */ new Map();
|
|
72
|
+
let n = null, l = null, u = null;
|
|
73
|
+
function E(t) {
|
|
74
|
+
const e = R++;
|
|
75
|
+
return i.set(e, t), w(), () => {
|
|
76
|
+
i.delete(e), i.size === 0 && d();
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function w() {
|
|
80
|
+
n || (u = a(), h(), n = m(F), l = p(M));
|
|
81
|
+
}
|
|
82
|
+
function d() {
|
|
83
|
+
n?.(), l?.(), n = null, l = null, u = null;
|
|
84
|
+
}
|
|
85
|
+
function F() {
|
|
86
|
+
const t = h(), e = a(), s = new Set(t);
|
|
87
|
+
if (e !== u) {
|
|
88
|
+
u = e;
|
|
89
|
+
for (const r of e) s.add(r.key);
|
|
90
|
+
}
|
|
91
|
+
if (s.size !== 0)
|
|
92
|
+
for (const r of [...i.values()])
|
|
93
|
+
r.roots().some((f) => s.has(f)) && r.request();
|
|
94
|
+
}
|
|
95
|
+
function M() {
|
|
96
|
+
for (const t of [...i.values()]) t.request();
|
|
97
|
+
}
|
|
98
|
+
function I() {
|
|
99
|
+
i.clear(), d();
|
|
100
|
+
}
|
|
101
|
+
export {
|
|
102
|
+
o as MAX_DROPPED_RERUNS,
|
|
103
|
+
x as RefetchRunner,
|
|
104
|
+
E as registerActiveRead,
|
|
105
|
+
M as reissueMountedReads,
|
|
106
|
+
I as resetActiveReads
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=refetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refetch.js","sources":["../../../src/lib/reads/refetch.ts"],"sourcesContent":["import { devWarn } from \"../dev-warn\";\nimport { readStaleness, subscribeToStaleness } from \"../records\";\nimport { takeStaleEvents } from \"../records/store\";\nimport { subscribeToRealtimeEpoch } from \"../realtime\";\n\n/* ============================================================================\n TARGETED REFETCH — who performs it, on what, with which field set.\n\n THE QUESTION THIS ANSWERS was asked nine times in the design and answered\n none of them: every rule that ends \"and then it triggers a targeted refetch\"\n was standing on a mechanism that did not exist.\n\n THE ANSWER IS THAT THIS LAYER ALREADY HAS EVERYTHING IT NEEDS. It performed\n the original fetch and still holds it, so it needs no registry of loaders and\n no map from type to endpoint — \"which field set\" is not a question it has to\n answer, it is the one it already asked. The library contributes only the\n signal; every endpoint stays in the application's own api layer.\n\n THE SIGNAL NAMES ROOTS, NOT THE KEY THAT WENT STALE, and that distinction is\n the whole reason it works: on a list of demands the key that goes stale is a\n RUN, and a list holding demand keys would never match one. Roots come from\n the hydration memo's deps map — a reverse lookup that is safe precisely\n because it is rebuilt by the same walk that reads it, rather than maintained\n alongside writes.\n\n COALESCED IN BREADTH AND IN TIME. Breadth: twenty-five rows going stale in\n one burst is ONE list refetch, because they all resolve to roots one read\n holds. Time: a minimum interval plus dedup against a request already in\n flight, because at least one real broadcast source has no change guard at all\n and streams continuously during a long job rather than arriving in bursts.\n\n SELF-LIMITING BY CONSTRUCTION. A refetch writes; a write could mark something\n stale; that could refetch. It terminates because only a BROADCAST marks a\n field stale and a fetch CLEARS unconditionally — including when the refetched\n value is identical to what was already there.\n\n NO TIMER IS INSTALLED ON IMPORT. The driver is wired on the first registered\n read and unwired with the last.\n ========================================================================= */\n\nconst DEFAULT_MIN_INTERVAL_MS = 1_000;\n\n/**\n * How many times in a row a read runs again because its answer was refused as older.\n *\n * ONE RACE IS SETTLED BY ONE RE-RUN, so a few cover a busy record. A BOUND IS REQUIRED: a server\n * whose answer stays older than the stored stamp (a clock that disagrees, a wrong stamp) would\n * otherwise re-run forever, which is polling by accident.\n */\nexport const MAX_DROPPED_RERUNS = 3;\n\nexport interface RunnerOptions {\n readonly minIntervalMs?: number;\n /** Test seam. Defaults to `Date.now`. */\n readonly now?: () => number;\n}\n\n/**\n * One read's refetch discipline: a floor between runs, and one request in\n * flight at a time.\n *\n * A SECOND SIGNAL ARRIVING MID-FLIGHT SETS A RE-RUN FLAG rather than issuing a\n * second request. Two overlapping refetches of the same target are not twice as\n * fresh; they are two answers racing to write, and the loser can be the newer\n * one.\n */\nexport class RefetchRunner {\n private inFlight = false;\n private rerun = false;\n private droppedReruns = 0;\n private lastFinishedAt = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n private readonly minIntervalMs: number;\n private readonly now: () => number;\n\n constructor(\n private readonly run: () => Promise<void>,\n options: RunnerOptions = {},\n ) {\n this.minIntervalMs = options.minIntervalMs ?? DEFAULT_MIN_INTERVAL_MS;\n this.now = options.now ?? Date.now;\n }\n\n /**\n * Report how the store took this run's answer. A refused one runs again, up to\n * `MAX_DROPPED_RERUNS` in a row; an accepted one clears the count.\n *\n * @returns true when the re-runs are spent and this answer was refused anyway: the caller owes\n * its reader a loud failure, since the runner will not ask again until the next signal.\n */\n answered(droppedOlder: boolean): boolean {\n if (!droppedOlder) {\n this.droppedReruns = 0;\n return false;\n }\n if (this.droppedReruns >= MAX_DROPPED_RERUNS) {\n devWarn(\"refetch\", `a read was refused as older ${MAX_DROPPED_RERUNS + 1} times in a row, so it stopped asking until the next signal`);\n return true;\n }\n this.droppedReruns += 1;\n this.request();\n return false;\n }\n\n /** Ask for a refetch. Respects the floor and the in-flight request. */\n request(): void {\n if (this.disposed) return;\n if (this.inFlight) {\n this.rerun = true;\n return;\n }\n if (this.timer !== null) return;\n\n const wait = this.minIntervalMs - (this.now() - this.lastFinishedAt);\n if (wait > 0) {\n this.timer = setTimeout(() => {\n this.timer = null;\n this.execute();\n }, wait);\n return;\n }\n this.execute();\n }\n\n /**\n * Run now, floor and all.\n *\n * For the FIRST fetch and for a key change — neither is a refetch, and making\n * a fresh screen wait out an interval that exists to damp a broadcast stream\n * would be the floor working against its own purpose.\n */\n runNow(): void {\n if (this.disposed) return;\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.inFlight) {\n this.rerun = true;\n return;\n }\n this.execute();\n }\n\n private execute(): void {\n this.inFlight = true;\n void this.run().finally(() => {\n this.inFlight = false;\n this.lastFinishedAt = this.now();\n if (this.disposed || !this.rerun) return;\n this.rerun = false;\n this.request();\n });\n }\n\n dispose(): void {\n this.disposed = true;\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n}\n\n/* --- The staleness driver --------------------------------------------------- */\n\n/** One mounted read, as the driver sees it. */\nexport interface ActiveRead {\n /** The keys this read is responsible for. Re-read per signal: a list's move. */\n roots(): readonly string[];\n /** Ask this read to re-issue the request it already made. */\n request(): void;\n}\n\nlet nextId = 1;\nconst activeReads = new Map<number, ActiveRead>();\nlet stopStaleness: (() => void) | null = null;\nlet stopEpoch: (() => void) | null = null;\nlet lastStaleness: unknown = null;\n\n/**\n * Register a read so staleness and liveness recovery can reach it.\n *\n * @returns unregister\n */\nexport function registerActiveRead(read: ActiveRead): () => void {\n const id = nextId++;\n activeReads.set(id, read);\n ensureDriver();\n return () => {\n activeReads.delete(id);\n if (activeReads.size === 0) teardownDriver();\n };\n}\n\nfunction ensureDriver(): void {\n if (stopStaleness) return;\n lastStaleness = readStaleness();\n /* An event from before this driver existed signals no read that is not yet mounted. */\n takeStaleEvents();\n stopStaleness = subscribeToStaleness(onStaleness);\n stopEpoch = subscribeToRealtimeEpoch(reissueMountedReads);\n}\n\nfunction teardownDriver(): void {\n stopStaleness?.();\n stopEpoch?.();\n stopStaleness = null;\n stopEpoch = null;\n lastStaleness = null;\n}\n\n/**\n * The store notifies staleness listeners on EVERY flush, so the signal is\n * compared by reference before anything is done with it.\n *\n * Without that comparison an ordinary write — a value changing, nothing stale —\n * would look like a staleness signal and every mounted read would refetch on\n * every broadcast. The store returns the identical array when the set has not\n * changed, which is exactly what makes this one comparison enough.\n */\nfunction onStaleness(): void {\n /* Events count beside the snapshot: an event on a record that was already stale, or still\n empty, moves nothing in it, and the read holding that record must still run again\n (DXUI-78, DEC-284). The two are merged first so a read asked for by both runs once. */\n const events = takeStaleEvents();\n const entries = readStaleness();\n const due = new Set(events);\n if (entries !== lastStaleness) {\n lastStaleness = entries;\n for (const entry of entries) due.add(entry.key);\n }\n if (due.size === 0) return;\n\n for (const read of [...activeReads.values()]) {\n if (read.roots().some((root) => due.has(root))) read.request();\n }\n}\n\n/**\n * Events were missed during a window nobody can enumerate: re-issue every\n * mounted read.\n *\n * EVERY MOUNTED READ RE-ISSUES, because \"which records changed while we were\n * not listening\" has no answer — the server stopped enqueueing broadcasts and\n * said nothing about what it dropped. It goes through each read's own runner,\n * so the floor and the in-flight dedup still apply.\n *\n * The library calls this on its realtime epoch. An app with its own transport\n * (its own stream feeding `write()`) has no epoch to move, so it calls this\n * itself after its connection drops and comes back.\n */\nexport function reissueMountedReads(): void {\n for (const read of [...activeReads.values()]) read.request();\n}\n\n/** Test seam. Nothing in the library calls this. */\nexport function resetActiveReads(): void {\n activeReads.clear();\n teardownDriver();\n}\n"],"names":["DEFAULT_MIN_INTERVAL_MS","MAX_DROPPED_RERUNS","RefetchRunner","run","options","droppedOlder","devWarn","wait","nextId","activeReads","stopStaleness","stopEpoch","lastStaleness","registerActiveRead","read","id","ensureDriver","teardownDriver","readStaleness","takeStaleEvents","subscribeToStaleness","onStaleness","subscribeToRealtimeEpoch","reissueMountedReads","events","entries","due","entry","root","resetActiveReads"],"mappings":"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"}
|