@reddb-io/ui 0.1.1
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 +17 -0
- package/bin/red-ui.js +259 -0
- package/build/CNAME +1 -0
- package/build/_app/env.js +1 -0
- package/build/_app/immutable/assets/0.C63jY5jX.css +1 -0
- package/build/_app/immutable/assets/10.Dblyk0Kr.css +1 -0
- package/build/_app/immutable/assets/EmptyState.RXcH7ryE.css +1 -0
- package/build/_app/immutable/assets/Workspace.BCzG1DsH.css +1 -0
- package/build/_app/immutable/assets/inter-cyrillic-ext-wght-normal.BOeWTOD4.woff2 +0 -0
- package/build/_app/immutable/assets/inter-cyrillic-wght-normal.DqGufNeO.woff2 +0 -0
- package/build/_app/immutable/assets/inter-greek-ext-wght-normal.DlzME5K_.woff2 +0 -0
- package/build/_app/immutable/assets/inter-greek-wght-normal.CkhJZR-_.woff2 +0 -0
- package/build/_app/immutable/assets/inter-latin-ext-wght-normal.DO1Apj_S.woff2 +0 -0
- package/build/_app/immutable/assets/inter-latin-wght-normal.Dx4kXJAl.woff2 +0 -0
- package/build/_app/immutable/assets/inter-vietnamese-wght-normal.CBcvBZtf.woff2 +0 -0
- package/build/_app/immutable/assets/jetbrains-mono-cyrillic-wght-normal.D73BlboJ.woff2 +0 -0
- package/build/_app/immutable/assets/jetbrains-mono-greek-wght-normal.Bw9x6K1M.woff2 +0 -0
- package/build/_app/immutable/assets/jetbrains-mono-latin-ext-wght-normal.DBQx-q_a.woff2 +0 -0
- package/build/_app/immutable/assets/jetbrains-mono-latin-wght-normal.B9CIFXIH.woff2 +0 -0
- package/build/_app/immutable/assets/jetbrains-mono-vietnamese-wght-normal.Bt-aOZkq.woff2 +0 -0
- package/build/_app/immutable/chunks/3j4cZ58b.js +1 -0
- package/build/_app/immutable/chunks/69_IOA4Y.js +1 -0
- package/build/_app/immutable/chunks/ALqaDrNQ.js +2 -0
- package/build/_app/immutable/chunks/BGcIe2ep.js +2 -0
- package/build/_app/immutable/chunks/BMHKbvs8.js +1 -0
- package/build/_app/immutable/chunks/BQHbwf54.js +916 -0
- package/build/_app/immutable/chunks/Bgso8cDH.js +311 -0
- package/build/_app/immutable/chunks/Bmgx1mfv.js +310 -0
- package/build/_app/immutable/chunks/BrvvOVaJ.js +1 -0
- package/build/_app/immutable/chunks/Bzak7iHL.js +1 -0
- package/build/_app/immutable/chunks/D9CTkMjK.js +1 -0
- package/build/_app/immutable/chunks/DIeogL5L.js +1 -0
- package/build/_app/immutable/chunks/DXY_Rxa7.js +113 -0
- package/build/_app/immutable/chunks/DhEqZVGG.js +1 -0
- package/build/_app/immutable/chunks/Ov8N-vxt.js +1 -0
- package/build/_app/immutable/chunks/oiO4RLqp.js +1 -0
- package/build/_app/immutable/entry/app.D_IVtpdv.js +2 -0
- package/build/_app/immutable/entry/start.3oC0UQ_Q.js +1 -0
- package/build/_app/immutable/nodes/0.CHPiFxDo.js +1 -0
- package/build/_app/immutable/nodes/1.BC_4YZ0h.js +1 -0
- package/build/_app/immutable/nodes/10.B7DMKSNc.js +60 -0
- package/build/_app/immutable/nodes/2.CAG5_cGP.js +1 -0
- package/build/_app/immutable/nodes/3.CAG5_cGP.js +1 -0
- package/build/_app/immutable/nodes/4.CAG5_cGP.js +1 -0
- package/build/_app/immutable/nodes/5.CAG5_cGP.js +1 -0
- package/build/_app/immutable/nodes/6.CAG5_cGP.js +1 -0
- package/build/_app/immutable/nodes/7.BZX9Iird.js +134 -0
- package/build/_app/immutable/nodes/8.CAG5_cGP.js +1 -0
- package/build/_app/immutable/nodes/9.CAG5_cGP.js +1 -0
- package/build/_app/version.json +1 -0
- package/build/favicon.png +0 -0
- package/build/index.html +59 -0
- package/dist/embed/RedUiEmbedRoot-BGoLxJf1.js +26562 -0
- package/dist/embed/RedUiEmbedRoot-BGoLxJf1.js.map +1 -0
- package/dist/embed/bundle-mjs-UuVRz3O4.js +3047 -0
- package/dist/embed/bundle-mjs-UuVRz3O4.js.map +1 -0
- package/dist/embed/core-QuRYvMt8.js +118 -0
- package/dist/embed/core-QuRYvMt8.js.map +1 -0
- package/dist/embed/index-B6ZQhCsu.js +577 -0
- package/dist/embed/index-B6ZQhCsu.js.map +1 -0
- package/dist/embed/index-client-ItCEU64C.js +3087 -0
- package/dist/embed/index-client-ItCEU64C.js.map +1 -0
- package/dist/embed/index-fad77a13.esm-BqPj0saH.js +1318 -0
- package/dist/embed/index-fad77a13.esm-BqPj0saH.js.map +1 -0
- package/dist/embed/index.js +11 -0
- package/dist/embed/index.js.map +1 -0
- package/dist/embed/sigma-node-border.esm-CGtlgqmo.js +432 -0
- package/dist/embed/sigma-node-border.esm-CGtlgqmo.js.map +1 -0
- package/dist/embed/sigma.esm-y0qgY-OC.js +2355 -0
- package/dist/embed/sigma.esm-y0qgY-OC.js.map +1 -0
- package/dist/embed/ui.css +1 -0
- package/package.json +101 -0
- package/src/app.css +238 -0
- package/src/lib/ActivityIndicator.svelte +100 -0
- package/src/lib/ClusterNode.svelte +119 -0
- package/src/lib/ClusterView.svelte +541 -0
- package/src/lib/CollectionHistory.svelte +266 -0
- package/src/lib/CollectionsView.svelte +14 -0
- package/src/lib/CommandPalette.svelte +237 -0
- package/src/lib/ConnectDropdown.svelte +222 -0
- package/src/lib/EmptyState.svelte +27 -0
- package/src/lib/LiveChanges.svelte +195 -0
- package/src/lib/MasterPasswordDialog.svelte +168 -0
- package/src/lib/PageHeader.svelte +32 -0
- package/src/lib/PendingChangesPanel.svelte +153 -0
- package/src/lib/QueryEditor.svelte +122 -0
- package/src/lib/ResultsPane.svelte +747 -0
- package/src/lib/SchemaTree.svelte +193 -0
- package/src/lib/SecurityView.svelte +255 -0
- package/src/lib/ShortcutOverlay.svelte +104 -0
- package/src/lib/Splash.svelte +46 -0
- package/src/lib/StatusBar.svelte +163 -0
- package/src/lib/SubNav.svelte +62 -0
- package/src/lib/Topbar.svelte +119 -0
- package/src/lib/Workspace.svelte +247 -0
- package/src/lib/activity.svelte.ts +91 -0
- package/src/lib/build-info.ts +41 -0
- package/src/lib/capability.ts +221 -0
- package/src/lib/cn.ts +6 -0
- package/src/lib/collection-catalog.ts +116 -0
- package/src/lib/collection-pages.ts +33 -0
- package/src/lib/connection-history.ts +301 -0
- package/src/lib/connections.svelte.ts +493 -0
- package/src/lib/embed/RedUiEmbedRoot.svelte +31 -0
- package/src/lib/embed/index.ts +234 -0
- package/src/lib/graph-loader/contract.ts +336 -0
- package/src/lib/graph-loader/drilldown.ts +334 -0
- package/src/lib/graph-loader/index.ts +13 -0
- package/src/lib/index.ts +114 -0
- package/src/lib/pending-changes.svelte.ts +149 -0
- package/src/lib/query-tabs.svelte.ts +130 -0
- package/src/lib/reddb/boot-params.ts +254 -0
- package/src/lib/reddb/cdc-stream-client.ts +234 -0
- package/src/lib/reddb/client.ts +698 -0
- package/src/lib/reddb/connection-bootstrap.ts +260 -0
- package/src/lib/reddb/connection-provider.contract.ts +72 -0
- package/src/lib/reddb/connection-provider.ts +72 -0
- package/src/lib/reddb/index.ts +14 -0
- package/src/lib/reddb/injected-client-provider.ts +76 -0
- package/src/lib/reddb/local-url-provider.ts +245 -0
- package/src/lib/reddb/secure-store.ts +41 -0
- package/src/lib/reddb/server-capabilities.ts +71 -0
- package/src/lib/reddb/tauri-encrypted-store.ts +64 -0
- package/src/lib/reddb/transports.ts +89 -0
- package/src/lib/reddb/types.ts +32 -0
- package/src/lib/reddb/uri.ts +54 -0
- package/src/lib/reddb/web-encrypted-store.ts +201 -0
- package/src/lib/renderers/DiffRenderer.svelte +184 -0
- package/src/lib/renderers/DocumentRenderer.svelte +134 -0
- package/src/lib/renderers/GraphRenderer.svelte +1328 -0
- package/src/lib/renderers/HypertableRenderer.svelte +253 -0
- package/src/lib/renderers/JsonRenderer.svelte +30 -0
- package/src/lib/renderers/KvRenderer.svelte +150 -0
- package/src/lib/renderers/QueueRenderer.svelte +286 -0
- package/src/lib/renderers/StatsRenderer.svelte +123 -0
- package/src/lib/renderers/TableRenderer.svelte +440 -0
- package/src/lib/renderers/VectorRenderer.svelte +388 -0
- package/src/lib/renderers/diff-render.ts +122 -0
- package/src/lib/renderers/diff.ts +9 -0
- package/src/lib/renderers/document-render.ts +64 -0
- package/src/lib/renderers/document.ts +9 -0
- package/src/lib/renderers/graph-render.ts +631 -0
- package/src/lib/renderers/graph-sigma.ts +395 -0
- package/src/lib/renderers/graph.ts +9 -0
- package/src/lib/renderers/hypertable-render.ts +320 -0
- package/src/lib/renderers/hypertable.ts +9 -0
- package/src/lib/renderers/index.ts +42 -0
- package/src/lib/renderers/json-render.ts +89 -0
- package/src/lib/renderers/json.ts +10 -0
- package/src/lib/renderers/kv-render.ts +193 -0
- package/src/lib/renderers/kv.ts +9 -0
- package/src/lib/renderers/queue-render.ts +197 -0
- package/src/lib/renderers/queue.ts +9 -0
- package/src/lib/renderers/registry.ts +68 -0
- package/src/lib/renderers/stats-render.ts +73 -0
- package/src/lib/renderers/stats.ts +9 -0
- package/src/lib/renderers/table-render.ts +156 -0
- package/src/lib/renderers/table.ts +11 -0
- package/src/lib/renderers/types.ts +33 -0
- package/src/lib/renderers/vector-render.ts +154 -0
- package/src/lib/renderers/vector.ts +9 -0
- package/src/lib/router.svelte.ts +163 -0
- package/src/lib/secureStore.svelte.ts +148 -0
- package/src/lib/shadow-dom-spike/ShadowDomSpikeCore.svelte +198 -0
- package/src/lib/shadow-dom-spike/mount-shadow-dom-spike.ts +94 -0
- package/src/lib/shortcuts.ts +22 -0
- package/src/lib/surface.ts +80 -0
- package/src/lib/tabs.svelte.ts +115 -0
- package/src/lib/theme.svelte.ts +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.svelte-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.svelte-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #777;--xy-background-pattern-lines-color-default: #777;--xy-background-pattern-cross-color-default: #777;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.svelte-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.svelte-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.svelte-flow__pane{z-index:1}.svelte-flow__pane.draggable{cursor:grab}.svelte-flow__pane.dragging{cursor:grabbing}.svelte-flow__pane.selection{cursor:pointer}.svelte-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.svelte-flow__renderer{z-index:4}.svelte-flow__selection{z-index:6}.svelte-flow__nodesselection-rect:focus,.svelte-flow__nodesselection-rect:focus-visible{outline:none}.svelte-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.svelte-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.svelte-flow .svelte-flow__edges{position:absolute}.svelte-flow .svelte-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.svelte-flow__edge{pointer-events:visibleStroke}.svelte-flow__edge.selectable{cursor:pointer}.svelte-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.svelte-flow__edge.animated path.svelte-flow__edge-interaction{stroke-dasharray:none;animation:none}.svelte-flow__edge.inactive{pointer-events:none}.svelte-flow__edge.selected,.svelte-flow__edge:focus,.svelte-flow__edge:focus-visible{outline:none}.svelte-flow__edge.selected .svelte-flow__edge-path,.svelte-flow__edge.selectable:focus .svelte-flow__edge-path,.svelte-flow__edge.selectable:focus-visible .svelte-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.svelte-flow__edge-textwrapper{pointer-events:all}.svelte-flow__edge .svelte-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.svelte-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.svelte-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.svelte-flow__connection{pointer-events:none}.svelte-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.svelte-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.svelte-flow__nodes{pointer-events:none;transform-origin:0 0}.svelte-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.svelte-flow__node.selectable{cursor:pointer}.svelte-flow__node.draggable{cursor:grab;pointer-events:all}.svelte-flow__node.draggable.dragging{cursor:grabbing}.svelte-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.svelte-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.svelte-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.svelte-flow__handle.connectingfrom{pointer-events:all}.svelte-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.svelte-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.svelte-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.svelte-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.svelte-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.svelte-flow__edgeupdater{cursor:move;pointer-events:all}.svelte-flow__pane.selection .svelte-flow__panel{pointer-events:none}.svelte-flow__panel{position:absolute;z-index:5;margin:15px}.svelte-flow__panel.top{top:0}.svelte-flow__panel.bottom{bottom:0}.svelte-flow__panel.top.center,.svelte-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.svelte-flow__panel.left{left:0}.svelte-flow__panel.right{right:0}.svelte-flow__panel.left.center,.svelte-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.svelte-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.svelte-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.svelte-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.svelte-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.svelte-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.svelte-flow__minimap-svg{display:block}.svelte-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.svelte-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.svelte-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.svelte-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.svelte-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.svelte-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.svelte-flow__controls.horizontal{flex-direction:row}.svelte-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.svelte-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.svelte-flow__edge.updating .svelte-flow__edge-path{stroke:#777}.svelte-flow__edge-text{font-size:10px}.svelte-flow__node.selectable:focus,.svelte-flow__node.selectable:focus-visible{outline:none}.svelte-flow__node-input,.svelte-flow__node-default,.svelte-flow__node-output,.svelte-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.svelte-flow__node-input.selectable:hover,.svelte-flow__node-default.selectable:hover,.svelte-flow__node-output.selectable:hover,.svelte-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.svelte-flow__node-input.selectable.selected,.svelte-flow__node-input.selectable:focus,.svelte-flow__node-input.selectable:focus-visible,.svelte-flow__node-default.selectable.selected,.svelte-flow__node-default.selectable:focus,.svelte-flow__node-default.selectable:focus-visible,.svelte-flow__node-output.selectable.selected,.svelte-flow__node-output.selectable:focus,.svelte-flow__node-output.selectable:focus-visible,.svelte-flow__node-group.selectable.selected,.svelte-flow__node-group.selectable:focus,.svelte-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.svelte-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.svelte-flow__nodesselection-rect,.svelte-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.svelte-flow__nodesselection-rect:focus,.svelte-flow__nodesselection-rect:focus-visible,.svelte-flow__selection:focus,.svelte-flow__selection:focus-visible{outline:none}.svelte-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.svelte-flow__controls-button:disabled{pointer-events:none}.svelte-flow__controls-button:disabled svg{fill-opacity:.4}.svelte-flow__controls-button:last-child{border-bottom:none}.svelte-flow__controls.horizontal .svelte-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.svelte-flow__controls.horizontal .svelte-flow__controls-button:last-child{border-right:none}.svelte-flow__resize-control{position:absolute}.svelte-flow__resize-control.left,.svelte-flow__resize-control.right{cursor:ew-resize}.svelte-flow__resize-control.top,.svelte-flow__resize-control.bottom{cursor:ns-resize}.svelte-flow__resize-control.top.left,.svelte-flow__resize-control.bottom.right{cursor:nwse-resize}.svelte-flow__resize-control.bottom.left,.svelte-flow__resize-control.top.right{cursor:nesw-resize}.svelte-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.svelte-flow__resize-control.handle.left{left:0;top:50%}.svelte-flow__resize-control.handle.right{left:100%;top:50%}.svelte-flow__resize-control.handle.top{left:50%;top:0}.svelte-flow__resize-control.handle.bottom{left:50%;top:100%}.svelte-flow__resize-control.handle.top.left,.svelte-flow__resize-control.handle.bottom.left{left:0}.svelte-flow__resize-control.handle.top.right,.svelte-flow__resize-control.handle.bottom.right{left:100%}.svelte-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.svelte-flow__resize-control.line.left,.svelte-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.svelte-flow__resize-control.line.left{left:0;border-left-width:1px}.svelte-flow__resize-control.line.right{left:100%;border-right-width:1px}.svelte-flow__resize-control.line.top,.svelte-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.svelte-flow__resize-control.line.top{top:0;border-top-width:1px}.svelte-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.svelte-flow__edge-label{text-align:center;position:absolute;padding:2px;font-size:10px;color:var(--xy-edge-label-color, var(--xy-edge-label-color-default));background:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.svelte-flow__container{-webkit-user-select:none;-moz-user-select:none;user-select:none}
|
package/package.json
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reddb-io/ui",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "RedDB UI components and standalone web application.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"red-ui": "./bin/red-ui.js"
|
|
9
|
+
},
|
|
10
|
+
"svelte": "./src/lib/index.ts",
|
|
11
|
+
"imports": {
|
|
12
|
+
"#reddb": {
|
|
13
|
+
"types": "./src/lib/reddb/index.ts",
|
|
14
|
+
"default": "./src/lib/reddb/index.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"svelte": "./src/lib/index.ts",
|
|
20
|
+
"types": "./src/lib/index.ts"
|
|
21
|
+
},
|
|
22
|
+
"./app.css": "./src/app.css",
|
|
23
|
+
"./embed": {
|
|
24
|
+
"types": "./src/lib/embed/index.ts",
|
|
25
|
+
"import": "./dist/embed/index.js",
|
|
26
|
+
"default": "./dist/embed/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./renderers": {
|
|
29
|
+
"svelte": "./src/lib/renderers/index.ts",
|
|
30
|
+
"types": "./src/lib/renderers/index.ts"
|
|
31
|
+
},
|
|
32
|
+
"./build/*": "./build/*"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"bin",
|
|
36
|
+
"build",
|
|
37
|
+
"dist",
|
|
38
|
+
"src/app.css",
|
|
39
|
+
"src/lib/**/*.svelte",
|
|
40
|
+
"src/lib/**/*.ts",
|
|
41
|
+
"!src/lib/**/*.test.ts",
|
|
42
|
+
"README.md"
|
|
43
|
+
],
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@fontsource-variable/inter": "^5.2.8",
|
|
49
|
+
"@fontsource-variable/jetbrains-mono": "^5.2.8",
|
|
50
|
+
"@sigma/node-border": "^3.0.0",
|
|
51
|
+
"@tauri-apps/api": "^2.5.0",
|
|
52
|
+
"@xyflow/svelte": "^1.2.0",
|
|
53
|
+
"bits-ui": "^2.18.1",
|
|
54
|
+
"clsx": "^2.1.1",
|
|
55
|
+
"graphology": "^0.26.0",
|
|
56
|
+
"graphology-communities-louvain": "^2.0.2",
|
|
57
|
+
"graphology-layout-forceatlas2": "^0.10.1",
|
|
58
|
+
"lucide-svelte": "^0.475.0",
|
|
59
|
+
"sigma": "^3.0.3",
|
|
60
|
+
"tailwind-merge": "^3.6.0",
|
|
61
|
+
"tailwind-variants": "^2.1.0",
|
|
62
|
+
"@reddb-io/ui-mcp": "0.1.1",
|
|
63
|
+
"@reddb-io/ui-kit": "0.1.1"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@sveltejs/adapter-static": "^3.0.8",
|
|
67
|
+
"@sveltejs/kit": "^2.17.0",
|
|
68
|
+
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
69
|
+
"@tailwindcss/vite": "^4.3.0",
|
|
70
|
+
"@types/node": "^25.9.1",
|
|
71
|
+
"svelte": "^5.20.0",
|
|
72
|
+
"svelte-check": "^4.1.4",
|
|
73
|
+
"tailwindcss": "^4.3.0",
|
|
74
|
+
"typescript": "^5.7.2",
|
|
75
|
+
"vite": "^6.0.7",
|
|
76
|
+
"vitest": "^2.1.8"
|
|
77
|
+
},
|
|
78
|
+
"peerDependencies": {
|
|
79
|
+
"svelte": "^5.0.0"
|
|
80
|
+
},
|
|
81
|
+
"engines": {
|
|
82
|
+
"node": ">=20"
|
|
83
|
+
},
|
|
84
|
+
"license": "Apache-2.0",
|
|
85
|
+
"homepage": "https://github.com/reddb-io/red-ui",
|
|
86
|
+
"repository": {
|
|
87
|
+
"type": "git",
|
|
88
|
+
"url": "git+https://github.com/reddb-io/red-ui.git",
|
|
89
|
+
"directory": "packages/ui"
|
|
90
|
+
},
|
|
91
|
+
"bugs": {
|
|
92
|
+
"url": "https://github.com/reddb-io/red-ui/issues"
|
|
93
|
+
},
|
|
94
|
+
"scripts": {
|
|
95
|
+
"dev": "vite dev --host 127.0.0.1 --port 1420 --strictPort",
|
|
96
|
+
"build": "vite build && vite build --config vite.embed.config.ts",
|
|
97
|
+
"preview": "vite preview",
|
|
98
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
99
|
+
"test": "svelte-kit sync && vitest run"
|
|
100
|
+
}
|
|
101
|
+
}
|
package/src/app.css
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
@import '@fontsource-variable/inter';
|
|
3
|
+
@import '@fontsource-variable/jetbrains-mono';
|
|
4
|
+
|
|
5
|
+
/* ============================================================================
|
|
6
|
+
Design tokens. Linear/Vercel vibe — surgical accent, contemporary type.
|
|
7
|
+
|
|
8
|
+
Two themes live here:
|
|
9
|
+
- default (`:root`, no data-theme or `data-theme="light"`): light, white-leaning.
|
|
10
|
+
- opt-in (`:root[data-theme="dark"]`): dark, near-black with green tint.
|
|
11
|
+
|
|
12
|
+
Light is default for both OSS and cloud first-load. Dark is opt-in via the
|
|
13
|
+
topbar toggle / Cmd-K command. Selection is persisted in localStorage and
|
|
14
|
+
applied before paint by an inline script in app.html.
|
|
15
|
+
|
|
16
|
+
Hierarchy of layers (lowest to highest in z):
|
|
17
|
+
bg-0 — page background (the deepest base)
|
|
18
|
+
bg-1 — primary surfaces (cards, panels, topbar)
|
|
19
|
+
bg-2 — interactive surfaces (buttons, inputs, hover)
|
|
20
|
+
bg-3 — elevated / active surfaces
|
|
21
|
+
|
|
22
|
+
Text ramp (most readable to least):
|
|
23
|
+
fg-0 — primary text, h1/h2, important values
|
|
24
|
+
fg-1 — body text, secondary headings
|
|
25
|
+
fg-2 — labels, meta, captions, muted UI text
|
|
26
|
+
fg-3 — disabled, "tertiary noise" (e.g. helper hints)
|
|
27
|
+
============================================================================ */
|
|
28
|
+
|
|
29
|
+
@theme {
|
|
30
|
+
/* Surfaces — light, white-leaning ramp.
|
|
31
|
+
bg-0 white, surfaces step up in grey via the zinc family. */
|
|
32
|
+
--color-bg-0: #ffffff;
|
|
33
|
+
--color-bg-1: #fafafa;
|
|
34
|
+
--color-bg-2: #f4f4f5;
|
|
35
|
+
--color-bg-3: #e7e7ea;
|
|
36
|
+
|
|
37
|
+
/* Foreground ramp — every level is WCAG AA on bg-0/bg-1.
|
|
38
|
+
fg-3 floor is ~4.8:1 on white; below that is decorative only. */
|
|
39
|
+
--color-fg-0: #0a0a0b;
|
|
40
|
+
--color-fg-1: #3f3f46;
|
|
41
|
+
--color-fg-2: #52525b;
|
|
42
|
+
--color-fg-3: #71717a;
|
|
43
|
+
|
|
44
|
+
/* Lines */
|
|
45
|
+
--color-line-1: #ececef;
|
|
46
|
+
--color-line-2: #d4d4d8;
|
|
47
|
+
--color-line-3: #a1a1aa;
|
|
48
|
+
|
|
49
|
+
/* Surgical accent — rose 600. #ff2056 vibrates on white and fails AA when
|
|
50
|
+
paired with white text on accent fills; the slightly darker chroma
|
|
51
|
+
(#e11d48) keeps the same reddb identity while clearing 4.5:1 against
|
|
52
|
+
white surfaces and against white button labels. */
|
|
53
|
+
--color-accent: #e11d48;
|
|
54
|
+
--color-accent-soft: rgba(225, 29, 72, 0.10);
|
|
55
|
+
--color-accent-glow: rgba(225, 29, 72, 0.30);
|
|
56
|
+
|
|
57
|
+
/* Semantic — darker variants so they stay AA on white surfaces */
|
|
58
|
+
--color-ok: #16a34a;
|
|
59
|
+
--color-warn: #b45309;
|
|
60
|
+
--color-danger: #dc2626;
|
|
61
|
+
--color-info: #2563eb;
|
|
62
|
+
|
|
63
|
+
/* Node roles */
|
|
64
|
+
--color-role-primary: #e11d48;
|
|
65
|
+
--color-role-replica: #2563eb;
|
|
66
|
+
--color-role-embedded: #16a34a;
|
|
67
|
+
|
|
68
|
+
/* Ambient glow — soft red wash at top of viewport, scaled per theme */
|
|
69
|
+
--color-ambient-glow: rgba(225, 29, 72, 0.04);
|
|
70
|
+
|
|
71
|
+
/* Geometry */
|
|
72
|
+
--radius-sm: 3px;
|
|
73
|
+
--radius-md: 5px;
|
|
74
|
+
--radius-lg: 8px;
|
|
75
|
+
--radius-xl: 12px;
|
|
76
|
+
|
|
77
|
+
/* Typography — base text is 13px (Linear scale) */
|
|
78
|
+
--text-xs: 11px;
|
|
79
|
+
--text-xs--line-height: 1.45;
|
|
80
|
+
--text-sm: 12px;
|
|
81
|
+
--text-sm--line-height: 1.5;
|
|
82
|
+
--text-base: 13px;
|
|
83
|
+
--text-base--line-height: 1.5;
|
|
84
|
+
--text-md: 14px;
|
|
85
|
+
--text-md--line-height: 1.5;
|
|
86
|
+
--text-lg: 18px;
|
|
87
|
+
--text-lg--line-height: 1.3;
|
|
88
|
+
--text-xl: 22px;
|
|
89
|
+
--text-xl--line-height: 1.2;
|
|
90
|
+
--text-2xl: 28px;
|
|
91
|
+
--text-2xl--line-height: 1.15;
|
|
92
|
+
|
|
93
|
+
--font-sans: 'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif;
|
|
94
|
+
--font-mono: 'JetBrains Mono Variable', 'JetBrains Mono', ui-monospace, 'SF Mono', 'Menlo', monospace;
|
|
95
|
+
|
|
96
|
+
/* ease-out-expo for ambient transitions, ease-out-quart for snappier UI */
|
|
97
|
+
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
|
|
98
|
+
--ease-snap: cubic-bezier(0.25, 1, 0.5, 1);
|
|
99
|
+
|
|
100
|
+
/* Shadows — light variant: smaller alpha, slate tint */
|
|
101
|
+
--shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08), 0 0 0 1px var(--color-line-2);
|
|
102
|
+
--shadow-lg: 0 16px 48px rgba(15, 23, 42, 0.14), 0 0 0 1px var(--color-line-2);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Dark theme — opt-in via `data-theme="dark"` on the document root. */
|
|
106
|
+
:root[data-theme='dark'] {
|
|
107
|
+
--color-bg-0: #050607;
|
|
108
|
+
--color-bg-1: #0d0f13;
|
|
109
|
+
--color-bg-2: #181b21;
|
|
110
|
+
--color-bg-3: #232730;
|
|
111
|
+
|
|
112
|
+
--color-fg-0: #f7f8fa;
|
|
113
|
+
--color-fg-1: #c8ccd4;
|
|
114
|
+
--color-fg-2: #9ca1a9;
|
|
115
|
+
--color-fg-3: #7a7f87;
|
|
116
|
+
|
|
117
|
+
--color-line-1: #181b21;
|
|
118
|
+
--color-line-2: #2a2e36;
|
|
119
|
+
--color-line-3: #3d424b;
|
|
120
|
+
|
|
121
|
+
--color-accent: #ff2056;
|
|
122
|
+
--color-accent-soft: rgba(255, 32, 86, 0.12);
|
|
123
|
+
--color-accent-glow: rgba(255, 32, 86, 0.45);
|
|
124
|
+
|
|
125
|
+
--color-ok: #4ade80;
|
|
126
|
+
--color-warn: #fbbf24;
|
|
127
|
+
--color-danger: #ff5470;
|
|
128
|
+
--color-info: #60a5fa;
|
|
129
|
+
|
|
130
|
+
--color-role-primary: #ff2056;
|
|
131
|
+
--color-role-replica: #60a5fa;
|
|
132
|
+
--color-role-embedded: #4ade80;
|
|
133
|
+
|
|
134
|
+
--color-ambient-glow: rgba(255, 32, 86, 0.06);
|
|
135
|
+
|
|
136
|
+
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4), 0 0 0 1px var(--color-line-2);
|
|
137
|
+
--shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.6), 0 0 0 1px var(--color-line-2);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* shadcn-svelte semantic aliases — driven by the active theme's tokens */
|
|
141
|
+
@layer base {
|
|
142
|
+
:root {
|
|
143
|
+
--background: var(--color-bg-0);
|
|
144
|
+
--foreground: var(--color-fg-0);
|
|
145
|
+
--card: var(--color-bg-1);
|
|
146
|
+
--card-foreground: var(--color-fg-0);
|
|
147
|
+
--popover: var(--color-bg-1);
|
|
148
|
+
--popover-foreground: var(--color-fg-0);
|
|
149
|
+
--primary: var(--color-accent);
|
|
150
|
+
--primary-foreground: #ffffff;
|
|
151
|
+
--secondary: var(--color-bg-2);
|
|
152
|
+
--secondary-foreground: var(--color-fg-1);
|
|
153
|
+
--muted: var(--color-bg-2);
|
|
154
|
+
--muted-foreground: var(--color-fg-2);
|
|
155
|
+
--accent: var(--color-bg-3);
|
|
156
|
+
--accent-foreground: var(--color-fg-0);
|
|
157
|
+
--destructive: var(--color-danger);
|
|
158
|
+
--destructive-foreground: #ffffff;
|
|
159
|
+
--border: var(--color-line-2);
|
|
160
|
+
--input: var(--color-line-2);
|
|
161
|
+
--ring: var(--color-accent);
|
|
162
|
+
--radius: var(--radius-md);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
* { box-sizing: border-box; }
|
|
166
|
+
|
|
167
|
+
html, body {
|
|
168
|
+
background: var(--color-bg-0);
|
|
169
|
+
color: var(--color-fg-0);
|
|
170
|
+
font-family: var(--font-sans);
|
|
171
|
+
font-size: 13px;
|
|
172
|
+
line-height: 1.5;
|
|
173
|
+
font-feature-settings: 'cv11', 'ss01', 'ss03';
|
|
174
|
+
letter-spacing: -0.005em;
|
|
175
|
+
margin: 0;
|
|
176
|
+
-webkit-font-smoothing: antialiased;
|
|
177
|
+
text-rendering: optimizeLegibility;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* Explicit type system — every page should use these classes for hierarchy */
|
|
181
|
+
.type-h1 {
|
|
182
|
+
font-size: 22px;
|
|
183
|
+
font-weight: 600;
|
|
184
|
+
letter-spacing: -0.02em;
|
|
185
|
+
line-height: 1.2;
|
|
186
|
+
color: var(--color-fg-0);
|
|
187
|
+
}
|
|
188
|
+
.type-h2 {
|
|
189
|
+
font-size: 16px;
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
letter-spacing: -0.015em;
|
|
192
|
+
line-height: 1.3;
|
|
193
|
+
color: var(--color-fg-0);
|
|
194
|
+
}
|
|
195
|
+
.type-label {
|
|
196
|
+
font-family: var(--font-mono);
|
|
197
|
+
font-size: 10px;
|
|
198
|
+
font-weight: 500;
|
|
199
|
+
text-transform: uppercase;
|
|
200
|
+
letter-spacing: 0.1em;
|
|
201
|
+
color: var(--color-fg-2);
|
|
202
|
+
}
|
|
203
|
+
.type-caption {
|
|
204
|
+
font-size: 11px;
|
|
205
|
+
color: var(--color-fg-2);
|
|
206
|
+
line-height: 1.45;
|
|
207
|
+
}
|
|
208
|
+
.type-code {
|
|
209
|
+
font-family: var(--font-mono);
|
|
210
|
+
font-size: 12px;
|
|
211
|
+
color: var(--color-fg-1);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* Ambient grid — 96px squares; lines use line-1 so the texture
|
|
215
|
+
reads as "barely there" in both themes. */
|
|
216
|
+
body::before {
|
|
217
|
+
content: '';
|
|
218
|
+
position: fixed;
|
|
219
|
+
inset: 0;
|
|
220
|
+
background-image:
|
|
221
|
+
radial-gradient(ellipse 80% 50% at 50% -10%, var(--color-ambient-glow), transparent),
|
|
222
|
+
linear-gradient(var(--color-line-1) 1px, transparent 1px),
|
|
223
|
+
linear-gradient(90deg, var(--color-line-1) 1px, transparent 1px);
|
|
224
|
+
background-size: 100% 100%, 96px 96px, 96px 96px;
|
|
225
|
+
opacity: 0.35;
|
|
226
|
+
pointer-events: none;
|
|
227
|
+
z-index: 0;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
::selection { background: var(--color-accent-soft); color: var(--color-fg-0); }
|
|
231
|
+
|
|
232
|
+
/* Default scrollbar styling — border matches page bg so the thumb
|
|
233
|
+
"floats" off the surface in both themes. */
|
|
234
|
+
::-webkit-scrollbar { width: 10px; height: 10px; }
|
|
235
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
236
|
+
::-webkit-scrollbar-thumb { background: var(--color-line-2); border-radius: 8px; border: 2px solid var(--color-bg-0); }
|
|
237
|
+
::-webkit-scrollbar-thumb:hover { background: var(--color-line-3); }
|
|
238
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { activity } from './activity.svelte'
|
|
3
|
+
import { Activity, CheckCircle2, AlertCircle, Loader2 } from 'lucide-svelte'
|
|
4
|
+
|
|
5
|
+
let open = $state(false)
|
|
6
|
+
|
|
7
|
+
function fmtDuration(ms: number | null): string {
|
|
8
|
+
if (ms === null) return '…'
|
|
9
|
+
if (ms < 1000) return `${ms}ms`
|
|
10
|
+
return `${(ms / 1000).toFixed(1)}s`
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function fmtRel(at: number): string {
|
|
14
|
+
const d = Date.now() - at
|
|
15
|
+
if (d < 1000) return 'just now'
|
|
16
|
+
if (d < 60_000) return `${Math.round(d / 1000)}s ago`
|
|
17
|
+
return `${Math.round(d / 60_000)}m ago`
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<div class="relative">
|
|
22
|
+
<button
|
|
23
|
+
type="button"
|
|
24
|
+
onclick={() => (open = !open)}
|
|
25
|
+
aria-pressed={open}
|
|
26
|
+
title="reddb activity"
|
|
27
|
+
class={[
|
|
28
|
+
'inline-flex items-center gap-1.5 h-7 px-2 rounded-md border text-xs font-mono transition-colors cursor-pointer',
|
|
29
|
+
activity.inflight > 0
|
|
30
|
+
? 'border-accent/40 bg-accent/10 text-accent'
|
|
31
|
+
: 'border-line-2 bg-bg-2 text-fg-3 hover:text-fg-1',
|
|
32
|
+
].join(' ')}
|
|
33
|
+
>
|
|
34
|
+
{#if activity.inflight > 0}
|
|
35
|
+
<Loader2 class="size-3.5 animate-spin" />
|
|
36
|
+
<span>{activity.inflight}</span>
|
|
37
|
+
{:else}
|
|
38
|
+
<Activity class="size-3.5" />
|
|
39
|
+
<span class="text-fg-3">idle</span>
|
|
40
|
+
{/if}
|
|
41
|
+
</button>
|
|
42
|
+
|
|
43
|
+
{#if open}
|
|
44
|
+
<div class="fixed inset-0 z-40" role="presentation" onclick={() => (open = false)}></div>
|
|
45
|
+
<div
|
|
46
|
+
role="dialog"
|
|
47
|
+
aria-label="Activity log"
|
|
48
|
+
class="absolute top-[calc(100%+6px)] right-0 z-50 w-[360px] bg-bg-1 border border-line-2 rounded-lg shadow-2xl text-[11px] font-mono"
|
|
49
|
+
>
|
|
50
|
+
<header class="flex items-center justify-between px-3 py-2 border-b border-line-1">
|
|
51
|
+
<span class="type-label">Recent reddb requests</span>
|
|
52
|
+
<div class="flex items-center gap-2">
|
|
53
|
+
<span class="text-fg-3">{activity.inflight} active</span>
|
|
54
|
+
{#if activity.inflight > 0}
|
|
55
|
+
<button
|
|
56
|
+
type="button"
|
|
57
|
+
onclick={() => activity.reset()}
|
|
58
|
+
title="Force-clear the in-flight counter (use when a request hangs)"
|
|
59
|
+
class="px-1.5 py-0.5 rounded border border-line-1 text-fg-3 hover:text-fg-1 hover:border-line-2 cursor-pointer text-[10px]"
|
|
60
|
+
>
|
|
61
|
+
reset
|
|
62
|
+
</button>
|
|
63
|
+
{/if}
|
|
64
|
+
</div>
|
|
65
|
+
</header>
|
|
66
|
+
<div class="max-h-[320px] overflow-y-auto py-1">
|
|
67
|
+
{#if activity.log.length === 0}
|
|
68
|
+
<div class="px-3 py-3 text-fg-3">No activity yet.</div>
|
|
69
|
+
{:else}
|
|
70
|
+
{#each activity.log as e (e.id)}
|
|
71
|
+
<div class="px-3 py-1.5 border-b border-line-1/50 last:border-0 grid grid-cols-[16px_1fr_auto] items-center gap-2">
|
|
72
|
+
<span aria-hidden="true">
|
|
73
|
+
{#if e.status === 'pending'}
|
|
74
|
+
<Loader2 class="size-3 animate-spin text-accent" />
|
|
75
|
+
{:else if e.status === 'ok'}
|
|
76
|
+
<CheckCircle2 class="size-3 text-ok" />
|
|
77
|
+
{:else}
|
|
78
|
+
<AlertCircle class="size-3 text-danger" />
|
|
79
|
+
{/if}
|
|
80
|
+
</span>
|
|
81
|
+
<div class="min-w-0">
|
|
82
|
+
<div class="text-fg-1 truncate">{e.label}</div>
|
|
83
|
+
{#if e.status === 'error' && e.error}
|
|
84
|
+
<div class="text-danger text-[10px] truncate">{e.error}</div>
|
|
85
|
+
{/if}
|
|
86
|
+
</div>
|
|
87
|
+
<div class="text-fg-3 text-[10px] tabular-nums whitespace-nowrap">
|
|
88
|
+
{#if e.status === 'pending'}
|
|
89
|
+
{fmtRel(e.startedAt)}
|
|
90
|
+
{:else}
|
|
91
|
+
{fmtDuration(e.durationMs)}
|
|
92
|
+
{/if}
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
{/each}
|
|
96
|
+
{/if}
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
{/if}
|
|
100
|
+
</div>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Handle, Position } from '@xyflow/svelte'
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
data: {
|
|
6
|
+
label: string
|
|
7
|
+
role: string
|
|
8
|
+
collections: number
|
|
9
|
+
entities: number
|
|
10
|
+
url: string
|
|
11
|
+
}
|
|
12
|
+
selected?: boolean
|
|
13
|
+
}
|
|
14
|
+
let { data, selected }: Props = $props()
|
|
15
|
+
|
|
16
|
+
const roleClass = $derived(
|
|
17
|
+
data.role === 'primary' ? 'role-primary' :
|
|
18
|
+
data.role === 'replica' ? 'role-replica' :
|
|
19
|
+
'role-embedded'
|
|
20
|
+
)
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<Handle type="target" position={Position.Left} style="opacity:0;pointer-events:none" />
|
|
24
|
+
<Handle type="source" position={Position.Right} style="opacity:0;pointer-events:none" />
|
|
25
|
+
|
|
26
|
+
<div class="card {roleClass}" class:selected>
|
|
27
|
+
<div class="stripe"></div>
|
|
28
|
+
<div class="body">
|
|
29
|
+
<div class="head">
|
|
30
|
+
<span class="role">{data.role}</span>
|
|
31
|
+
<span class="dot"></span>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="label">{data.label}</div>
|
|
34
|
+
<div class="meta">
|
|
35
|
+
<span class="metric"><span class="n">{data.collections}</span><span class="u">colls</span></span>
|
|
36
|
+
<span class="sep">·</span>
|
|
37
|
+
<span class="metric"><span class="n">{data.entities.toLocaleString()}</span><span class="u">entities</span></span>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<style>
|
|
43
|
+
.card {
|
|
44
|
+
--c: #7a8088;
|
|
45
|
+
position: relative;
|
|
46
|
+
width: 240px;
|
|
47
|
+
background: var(--color-bg-1);
|
|
48
|
+
border: 1px solid var(--color-line-2);
|
|
49
|
+
border-radius: 8px;
|
|
50
|
+
overflow: hidden;
|
|
51
|
+
transition: border-color 160ms var(--ease-out), box-shadow 160ms var(--ease-out), transform 200ms var(--ease-snap);
|
|
52
|
+
cursor: pointer;
|
|
53
|
+
}
|
|
54
|
+
.card:hover {
|
|
55
|
+
border-color: color-mix(in srgb, var(--c) 50%, var(--color-line-3));
|
|
56
|
+
}
|
|
57
|
+
.card.selected {
|
|
58
|
+
border-color: var(--c);
|
|
59
|
+
box-shadow: 0 0 0 1px var(--c), 0 8px 28px -8px color-mix(in srgb, var(--c) 60%, transparent);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.role-primary { --c: var(--color-role-primary); }
|
|
63
|
+
.role-replica { --c: var(--color-role-replica); }
|
|
64
|
+
.role-embedded { --c: var(--color-role-embedded); }
|
|
65
|
+
|
|
66
|
+
.stripe {
|
|
67
|
+
position: absolute; left: 0; top: 0; bottom: 0;
|
|
68
|
+
width: 2px;
|
|
69
|
+
background: var(--c);
|
|
70
|
+
box-shadow: 0 0 8px var(--c);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.body { padding: 12px 14px 12px 16px; }
|
|
74
|
+
|
|
75
|
+
.head { display: flex; align-items: center; justify-content: space-between; }
|
|
76
|
+
.role {
|
|
77
|
+
font-family: var(--font-mono);
|
|
78
|
+
font-size: 9px;
|
|
79
|
+
font-weight: 500;
|
|
80
|
+
text-transform: uppercase;
|
|
81
|
+
letter-spacing: 0.14em;
|
|
82
|
+
color: var(--c);
|
|
83
|
+
}
|
|
84
|
+
.dot {
|
|
85
|
+
width: 6px; height: 6px;
|
|
86
|
+
border-radius: 9999px;
|
|
87
|
+
background: var(--c);
|
|
88
|
+
box-shadow: 0 0 6px var(--c);
|
|
89
|
+
animation: pulse 2.4s ease-in-out infinite;
|
|
90
|
+
}
|
|
91
|
+
@keyframes pulse {
|
|
92
|
+
0%, 100% { opacity: 1; transform: scale(1); }
|
|
93
|
+
50% { opacity: 0.5; transform: scale(0.9); }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.label {
|
|
97
|
+
font-family: var(--font-mono);
|
|
98
|
+
font-size: 13px;
|
|
99
|
+
font-weight: 500;
|
|
100
|
+
color: var(--color-fg-0);
|
|
101
|
+
margin-top: 4px;
|
|
102
|
+
letter-spacing: -0.01em;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.meta {
|
|
106
|
+
margin-top: 10px;
|
|
107
|
+
padding-top: 10px;
|
|
108
|
+
border-top: 1px solid var(--color-line-1);
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: baseline;
|
|
111
|
+
gap: 6px;
|
|
112
|
+
font-family: var(--font-mono);
|
|
113
|
+
font-size: 11px;
|
|
114
|
+
}
|
|
115
|
+
.metric { display: inline-flex; align-items: baseline; gap: 4px; }
|
|
116
|
+
.metric .n { color: var(--color-fg-0); font-weight: 500; }
|
|
117
|
+
.metric .u { color: var(--color-fg-3); font-size: 10px; }
|
|
118
|
+
.sep { color: var(--color-fg-3); }
|
|
119
|
+
</style>
|