aeon-ui-engine 1.5.1 → 1.9.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/CHANGELOG.md +140 -0
- package/package.json +6 -3
- package/packages/core/dist/index.d.ts +116 -1
- package/packages/core/dist/index.js +202 -1
- package/packages/core/src/anatomy.ts +13 -1
- package/packages/core/src/index.ts +2 -0
- package/packages/core/src/list-window.ts +149 -0
- package/packages/core/src/sound.ts +154 -0
- package/packages/panda/package.json +6 -3
- package/packages/panda/panda.config.ts +12 -0
- package/packages/panda/src/recipes/clipboard.ts +40 -0
- package/packages/panda/src/recipes/composer.ts +4 -3
- package/packages/panda/src/recipes/index.ts +4 -0
- package/packages/panda/src/recipes/prose.ts +110 -0
- package/packages/panda/src/recipes/segment-group.ts +50 -0
- package/packages/panda/src/recipes/textarea.ts +60 -0
- package/packages/panda/styled-system/css/conditions.d.ts +7 -0
- package/packages/panda/styled-system/css/conditions.js +32 -0
- package/packages/panda/styled-system/css/css.d.ts +6 -6
- package/packages/panda/styled-system/css/css.js +63 -0
- package/packages/panda/styled-system/css/cva.d.ts +2 -3
- package/packages/panda/styled-system/css/cva.js +51 -0
- package/packages/panda/styled-system/css/cx.d.ts +5 -4
- package/packages/panda/styled-system/css/{cx.mjs → cx.js} +5 -4
- package/packages/panda/styled-system/css/first-that-works.d.ts +22 -0
- package/packages/panda/styled-system/css/first-that-works.js +1 -0
- package/packages/panda/styled-system/css/index.d.ts +6 -3
- package/packages/panda/styled-system/css/index.js +8 -0
- package/packages/panda/styled-system/css/keyframes.d.ts +5 -0
- package/packages/panda/styled-system/css/keyframes.js +8 -0
- package/packages/panda/styled-system/css/position-try.d.ts +5 -0
- package/packages/panda/styled-system/css/position-try.js +11 -0
- package/packages/panda/styled-system/css/sva.d.ts +1 -2
- package/packages/panda/styled-system/css/sva.js +49 -0
- package/packages/panda/styled-system/css/view-transition.d.ts +7 -0
- package/packages/panda/styled-system/css/view-transition.js +18 -0
- package/packages/panda/styled-system/helpers.d.ts +67 -0
- package/packages/panda/styled-system/helpers.js +624 -0
- package/packages/panda/styled-system/jsx/aspect-ratio.d.ts +3 -6
- package/packages/panda/styled-system/jsx/aspect-ratio.js +11 -0
- package/packages/panda/styled-system/jsx/bleed.d.ts +4 -7
- package/packages/panda/styled-system/jsx/bleed.js +11 -0
- package/packages/panda/styled-system/jsx/box.d.ts +4 -7
- package/packages/panda/styled-system/jsx/box.js +11 -0
- package/packages/panda/styled-system/jsx/center.d.ts +4 -7
- package/packages/panda/styled-system/jsx/center.js +11 -0
- package/packages/panda/styled-system/jsx/circle.d.ts +4 -7
- package/packages/panda/styled-system/jsx/circle.js +11 -0
- package/packages/panda/styled-system/jsx/container.d.ts +4 -7
- package/packages/panda/styled-system/jsx/container.js +11 -0
- package/packages/panda/styled-system/jsx/cq.d.ts +4 -7
- package/packages/panda/styled-system/jsx/cq.js +11 -0
- package/packages/panda/styled-system/jsx/create-recipe-context.d.ts +31 -0
- package/packages/panda/styled-system/jsx/create-recipe-context.js +38 -0
- package/packages/panda/styled-system/jsx/create-slot-recipe-context.d.ts +49 -0
- package/packages/panda/styled-system/jsx/create-slot-recipe-context.js +124 -0
- package/packages/panda/styled-system/jsx/divider.d.ts +4 -7
- package/packages/panda/styled-system/jsx/divider.js +11 -0
- package/packages/panda/styled-system/jsx/factory.d.ts +2 -2
- package/packages/panda/styled-system/jsx/factory.js +91 -0
- package/packages/panda/styled-system/jsx/flex.d.ts +4 -7
- package/packages/panda/styled-system/jsx/flex.js +11 -0
- package/packages/panda/styled-system/jsx/float.d.ts +4 -7
- package/packages/panda/styled-system/jsx/float.js +11 -0
- package/packages/panda/styled-system/jsx/grid-item.d.ts +4 -7
- package/packages/panda/styled-system/jsx/grid-item.js +11 -0
- package/packages/panda/styled-system/jsx/grid.d.ts +4 -7
- package/packages/panda/styled-system/jsx/grid.js +11 -0
- package/packages/panda/styled-system/jsx/helper.d.ts +34 -0
- package/packages/panda/styled-system/jsx/helper.js +92 -0
- package/packages/panda/styled-system/jsx/hstack.d.ts +4 -7
- package/packages/panda/styled-system/jsx/hstack.js +11 -0
- package/packages/panda/styled-system/jsx/index.d.ts +17 -17
- package/packages/panda/styled-system/jsx/index.js +24 -0
- package/packages/panda/styled-system/jsx/is-valid-prop.d.ts +5 -10
- package/packages/panda/styled-system/jsx/is-valid-prop.js +12 -0
- package/packages/panda/styled-system/jsx/link-overlay.d.ts +4 -7
- package/packages/panda/styled-system/jsx/link-overlay.js +11 -0
- package/packages/panda/styled-system/jsx/spacer.d.ts +4 -7
- package/packages/panda/styled-system/jsx/spacer.js +11 -0
- package/packages/panda/styled-system/jsx/square.d.ts +4 -7
- package/packages/panda/styled-system/jsx/square.js +11 -0
- package/packages/panda/styled-system/jsx/stack.d.ts +4 -7
- package/packages/panda/styled-system/jsx/stack.js +11 -0
- package/packages/panda/styled-system/jsx/visually-hidden.d.ts +4 -7
- package/packages/panda/styled-system/jsx/visually-hidden.js +11 -0
- package/packages/panda/styled-system/jsx/vstack.d.ts +4 -7
- package/packages/panda/styled-system/jsx/vstack.js +11 -0
- package/packages/panda/styled-system/jsx/wrap.d.ts +4 -7
- package/packages/panda/styled-system/jsx/wrap.js +11 -0
- package/packages/panda/styled-system/patterns/aspect-ratio.d.ts +8 -9
- package/packages/panda/styled-system/patterns/aspect-ratio.js +37 -0
- package/packages/panda/styled-system/patterns/bleed.d.ts +9 -10
- package/packages/panda/styled-system/patterns/bleed.js +30 -0
- package/packages/panda/styled-system/patterns/box.d.ts +8 -11
- package/packages/panda/styled-system/patterns/box.js +16 -0
- package/packages/panda/styled-system/patterns/center.d.ts +8 -9
- package/packages/panda/styled-system/patterns/center.js +22 -0
- package/packages/panda/styled-system/patterns/circle.d.ts +8 -9
- package/packages/panda/styled-system/patterns/circle.js +26 -0
- package/packages/panda/styled-system/patterns/container.d.ts +8 -11
- package/packages/panda/styled-system/patterns/container.js +26 -0
- package/packages/panda/styled-system/patterns/cq.d.ts +10 -10
- package/packages/panda/styled-system/patterns/cq.js +24 -0
- package/packages/panda/styled-system/patterns/divider.d.ts +11 -11
- package/packages/panda/styled-system/patterns/divider.js +31 -0
- package/packages/panda/styled-system/patterns/flex.d.ts +14 -15
- package/packages/panda/styled-system/patterns/flex.js +27 -0
- package/packages/panda/styled-system/patterns/float.d.ts +12 -12
- package/packages/panda/styled-system/patterns/float.js +84 -0
- package/packages/panda/styled-system/patterns/grid-item.d.ts +13 -14
- package/packages/panda/styled-system/patterns/grid-item.js +26 -0
- package/packages/panda/styled-system/patterns/grid.d.ts +13 -13
- package/packages/panda/styled-system/patterns/grid.js +30 -0
- package/packages/panda/styled-system/patterns/hstack.d.ts +9 -10
- package/packages/panda/styled-system/patterns/hstack.js +27 -0
- package/packages/panda/styled-system/patterns/index.d.ts +14 -15
- package/packages/panda/styled-system/patterns/index.js +20 -0
- package/packages/panda/styled-system/patterns/link-overlay.d.ts +8 -11
- package/packages/panda/styled-system/patterns/link-overlay.js +25 -0
- package/packages/panda/styled-system/patterns/runtime.js +25 -0
- package/packages/panda/styled-system/patterns/spacer.d.ts +9 -9
- package/packages/panda/styled-system/patterns/spacer.js +26 -0
- package/packages/panda/styled-system/patterns/square.d.ts +8 -9
- package/packages/panda/styled-system/patterns/square.js +25 -0
- package/packages/panda/styled-system/patterns/stack.d.ts +11 -12
- package/packages/panda/styled-system/patterns/stack.js +30 -0
- package/packages/panda/styled-system/patterns/visually-hidden.d.ts +8 -11
- package/packages/panda/styled-system/patterns/visually-hidden.js +19 -0
- package/packages/panda/styled-system/patterns/vstack.d.ts +9 -10
- package/packages/panda/styled-system/patterns/vstack.js +27 -0
- package/packages/panda/styled-system/patterns/wrap.d.ts +12 -13
- package/packages/panda/styled-system/patterns/wrap.js +26 -0
- package/packages/panda/styled-system/recipes/aeon-accordion.d.ts +9 -26
- package/packages/panda/styled-system/recipes/aeon-accordion.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-app-shell.d.ts +10 -26
- package/packages/panda/styled-system/recipes/aeon-app-shell.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-async.d.ts +9 -26
- package/packages/panda/styled-system/recipes/aeon-async.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-avatar.d.ts +10 -28
- package/packages/panda/styled-system/recipes/aeon-avatar.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-badge.d.ts +8 -26
- package/packages/panda/styled-system/recipes/aeon-badge.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-bar.d.ts +13 -32
- package/packages/panda/styled-system/recipes/aeon-bar.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-button-group.d.ts +10 -33
- package/packages/panda/styled-system/recipes/aeon-button-group.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-button.d.ts +10 -33
- package/packages/panda/styled-system/recipes/aeon-button.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-checkbox.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-checkbox.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-clipboard.d.ts +16 -0
- package/packages/panda/styled-system/recipes/aeon-clipboard.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-combobox.d.ts +9 -26
- package/packages/panda/styled-system/recipes/aeon-combobox.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-composer.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-composer.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-content.d.ts +10 -26
- package/packages/panda/styled-system/recipes/aeon-content.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-conversation.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-conversation.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-dialog.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-dialog.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-entry.d.ts +11 -30
- package/packages/panda/styled-system/recipes/aeon-entry.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-field.d.ts +9 -26
- package/packages/panda/styled-system/recipes/aeon-field.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-file-upload.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-file-upload.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-identity.d.ts +10 -28
- package/packages/panda/styled-system/recipes/aeon-identity.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-list-row.d.ts +9 -26
- package/packages/panda/styled-system/recipes/aeon-list-row.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-menu.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-menu.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-metric-strip.d.ts +10 -28
- package/packages/panda/styled-system/recipes/aeon-metric-strip.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-nav.d.ts +11 -30
- package/packages/panda/styled-system/recipes/aeon-nav.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-panel.d.ts +10 -26
- package/packages/panda/styled-system/recipes/aeon-panel.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-pin-input.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-pin-input.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-popover.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-popover.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-profile-header.d.ts +10 -28
- package/packages/panda/styled-system/recipes/aeon-profile-header.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-progress.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-progress.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-prose.d.ts +16 -0
- package/packages/panda/styled-system/recipes/aeon-prose.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-radio-group.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-radio-group.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-range-slider.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-range-slider.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-scroll.d.ts +12 -36
- package/packages/panda/styled-system/recipes/aeon-scroll.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-segment-group.d.ts +18 -0
- package/packages/panda/styled-system/recipes/aeon-segment-group.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-select.d.ts +9 -26
- package/packages/panda/styled-system/recipes/aeon-select.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-separator.d.ts +10 -26
- package/packages/panda/styled-system/recipes/aeon-separator.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-slider.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-slider.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-switch.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-switch.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-tabs.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-tabs.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-textarea.d.ts +18 -0
- package/packages/panda/styled-system/recipes/aeon-textarea.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-theme-switcher.d.ts +10 -26
- package/packages/panda/styled-system/recipes/aeon-theme-switcher.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-thread.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-thread.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-toast.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-toast.js +5 -0
- package/packages/panda/styled-system/recipes/aeon-tooltip.d.ts +9 -24
- package/packages/panda/styled-system/recipes/aeon-tooltip.js +5 -0
- package/packages/panda/styled-system/recipes/index.d.ts +31 -28
- package/packages/panda/styled-system/recipes/index.js +43 -0
- package/packages/panda/styled-system/recipes/runtime.js +133 -0
- package/packages/panda/styled-system/styles.css +1899 -2110
- package/packages/panda/styled-system/tokens/index.d.ts +4 -5
- package/packages/panda/styled-system/tokens/index.js +18 -0
- package/packages/panda/styled-system/types/index.d.ts +3 -6
- package/packages/panda/styled-system/types/jsx.d.ts +36 -27
- package/packages/panda/styled-system/types/pattern.d.ts +18 -70
- package/packages/panda/styled-system/types/recipe.d.ts +50 -154
- package/packages/panda/styled-system/types/system.d.ts +1826 -0
- package/packages/panda/styled-system/types/tokens.d.ts +65 -0
- package/packages/panda/tsconfig.json +3 -1
- package/packages/primitives/dist/chunk-5BNAV4S2.js +258 -0
- package/packages/primitives/dist/chunk-HYHCIMHC.js +45 -0
- package/packages/primitives/dist/index.d.ts +2 -0
- package/packages/primitives/dist/index.js +30 -12
- package/packages/primitives/dist/machines/app-nav.d.ts +3 -3
- package/packages/primitives/dist/machines/cache.d.ts +223 -0
- package/packages/primitives/dist/machines/cache.js +14 -0
- package/packages/primitives/dist/machines/clipboard.d.ts +46 -0
- package/packages/primitives/dist/machines/clipboard.js +8 -0
- package/packages/primitives/dist/machines/tabs.d.ts +2 -2
- package/packages/primitives/src/index.ts +2 -0
- package/packages/primitives/src/machines/cache.ts +395 -0
- package/packages/primitives/src/machines/clipboard.ts +56 -0
- package/packages/react/dist/index.d.ts +134 -13
- package/packages/react/dist/index.js +1429 -1016
- package/packages/react/src/clipboard/index.tsx +117 -0
- package/packages/react/src/composer/index.tsx +14 -5
- package/packages/react/src/dialog/index.tsx +11 -3
- package/packages/react/src/floating/FloatingPositioner.tsx +11 -1
- package/packages/react/src/index.ts +4 -0
- package/packages/react/src/menu/index.tsx +8 -3
- package/packages/react/src/popover/index.tsx +25 -4
- package/packages/react/src/prose/index.tsx +11 -0
- package/packages/react/src/radio-group/index.tsx +2 -1
- package/packages/react/src/scroll/index.tsx +1 -0
- package/packages/react/src/scroll/use-windowed-range.ts +118 -0
- package/packages/react/src/segment-group/index.tsx +171 -0
- package/packages/react/src/select/index.tsx +11 -2
- package/packages/react/src/slider/index.tsx +13 -6
- package/packages/react/src/tabs/index.tsx +19 -7
- package/packages/react/src/textarea/index.tsx +75 -0
- package/packages/react/src/utils/assign-ref.ts +7 -0
- package/packages/schemas/dist/index.d.ts +8 -0
- package/packages/schemas/dist/index.js +62 -1
- package/packages/schemas/json/catalog.json +493 -0
- package/packages/schemas/json/clipboard.json +136 -0
- package/packages/schemas/json/prose.json +103 -0
- package/packages/schemas/json/segmentGroup.json +131 -0
- package/packages/schemas/json/textarea.json +119 -0
- package/packages/schemas/prompts/statecharts.md +1 -1
- package/packages/schemas/registry/catalog.json +34 -0
- package/packages/schemas/registry/components/clipboard.json +136 -0
- package/packages/schemas/registry/components/prose.json +103 -0
- package/packages/schemas/registry/components/segmentGroup.json +131 -0
- package/packages/schemas/registry/components/textarea.json +119 -0
- package/packages/schemas/registry/machines/clipboard.json +110 -0
- package/packages/schemas/registry/machines/slider.json +18 -1
- package/packages/schemas/scripts/emit.ts +2 -0
- package/packages/schemas/src/components.ts +63 -0
- package/packages/tree/README.md +29 -0
- package/packages/tree/dist/index.d.ts +97 -0
- package/packages/tree/dist/index.js +107 -0
- package/packages/tree/package.json +42 -0
- package/packages/tree/src/exclusive-action.ts +104 -0
- package/packages/tree/src/index.ts +7 -0
- package/packages/tree/src/interpret.tsx +45 -0
- package/packages/tree/src/totality.ts +20 -0
- package/packages/tree/src/widget.ts +31 -0
- package/packages/tree/tsconfig.json +8 -0
- package/packages/tree/vitest.config.ts +8 -0
- package/packages/ui/dist/index.d.ts +27 -3
- package/packages/ui/dist/index.js +232 -165
- package/packages/ui/src/clipboard.tsx +51 -0
- package/packages/ui/src/index.ts +4 -0
- package/packages/ui/src/prose.tsx +15 -0
- package/packages/ui/src/segment-group.tsx +28 -0
- package/packages/ui/src/textarea.tsx +17 -0
- package/scripts/vite-aliases.mjs +5 -2
- package/packages/cli/node_modules/.bin/esbuild +0 -21
- package/packages/cli/node_modules/.bin/jiti +0 -21
- package/packages/cli/node_modules/.bin/tsc +0 -21
- package/packages/cli/node_modules/.bin/tsserver +0 -21
- package/packages/cli/node_modules/.bin/tsup +0 -21
- package/packages/cli/node_modules/.bin/tsup-node +0 -21
- package/packages/cli/node_modules/.bin/tsx +0 -21
- package/packages/cli/node_modules/.bin/vite +0 -21
- package/packages/cli/node_modules/.bin/vitest +0 -21
- package/packages/core/node_modules/.bin/esbuild +0 -21
- package/packages/core/node_modules/.bin/jiti +0 -21
- package/packages/core/node_modules/.bin/tsc +0 -21
- package/packages/core/node_modules/.bin/tsserver +0 -21
- package/packages/core/node_modules/.bin/tsup +0 -21
- package/packages/core/node_modules/.bin/tsup-node +0 -21
- package/packages/core/node_modules/.bin/tsx +0 -21
- package/packages/core/node_modules/.bin/vite +0 -21
- package/packages/core/node_modules/.bin/vitest +0 -21
- package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/core/src/identicon.test.ts +0 -39
- package/packages/core/src/machine.test.ts +0 -79
- package/packages/core/src/theme.test.ts +0 -14
- package/packages/geometry/node_modules/.bin/esbuild +0 -21
- package/packages/geometry/node_modules/.bin/jiti +0 -21
- package/packages/geometry/node_modules/.bin/tsc +0 -21
- package/packages/geometry/node_modules/.bin/tsserver +0 -21
- package/packages/geometry/node_modules/.bin/tsup +0 -21
- package/packages/geometry/node_modules/.bin/tsup-node +0 -21
- package/packages/geometry/node_modules/.bin/tsx +0 -21
- package/packages/panda/styled-system/css/conditions.mjs +0 -36
- package/packages/panda/styled-system/css/css.mjs +0 -45
- package/packages/panda/styled-system/css/cva.mjs +0 -87
- package/packages/panda/styled-system/css/index.mjs +0 -4
- package/packages/panda/styled-system/css/sva.mjs +0 -46
- package/packages/panda/styled-system/helpers.mjs +0 -328
- package/packages/panda/styled-system/jsx/aspect-ratio.mjs +0 -14
- package/packages/panda/styled-system/jsx/bleed.mjs +0 -14
- package/packages/panda/styled-system/jsx/box.mjs +0 -14
- package/packages/panda/styled-system/jsx/center.mjs +0 -14
- package/packages/panda/styled-system/jsx/circle.mjs +0 -14
- package/packages/panda/styled-system/jsx/container.mjs +0 -14
- package/packages/panda/styled-system/jsx/cq.mjs +0 -14
- package/packages/panda/styled-system/jsx/create-style-context.d.ts +0 -54
- package/packages/panda/styled-system/jsx/create-style-context.mjs +0 -121
- package/packages/panda/styled-system/jsx/divider.mjs +0 -14
- package/packages/panda/styled-system/jsx/factory-helper.mjs +0 -22
- package/packages/panda/styled-system/jsx/factory.mjs +0 -89
- package/packages/panda/styled-system/jsx/flex.mjs +0 -14
- package/packages/panda/styled-system/jsx/float.mjs +0 -14
- package/packages/panda/styled-system/jsx/grid-item.mjs +0 -14
- package/packages/panda/styled-system/jsx/grid.mjs +0 -14
- package/packages/panda/styled-system/jsx/hstack.mjs +0 -14
- package/packages/panda/styled-system/jsx/index.mjs +0 -23
- package/packages/panda/styled-system/jsx/is-valid-prop.mjs +0 -17
- package/packages/panda/styled-system/jsx/link-overlay.mjs +0 -14
- package/packages/panda/styled-system/jsx/spacer.mjs +0 -14
- package/packages/panda/styled-system/jsx/square.mjs +0 -14
- package/packages/panda/styled-system/jsx/stack.mjs +0 -14
- package/packages/panda/styled-system/jsx/visually-hidden.mjs +0 -14
- package/packages/panda/styled-system/jsx/vstack.mjs +0 -14
- package/packages/panda/styled-system/jsx/wrap.mjs +0 -14
- package/packages/panda/styled-system/patterns/aspect-ratio.mjs +0 -38
- package/packages/panda/styled-system/patterns/bleed.mjs +0 -24
- package/packages/panda/styled-system/patterns/box.mjs +0 -15
- package/packages/panda/styled-system/patterns/center.mjs +0 -21
- package/packages/panda/styled-system/patterns/circle.mjs +0 -25
- package/packages/panda/styled-system/patterns/container.mjs +0 -21
- package/packages/panda/styled-system/patterns/cq.mjs +0 -21
- package/packages/panda/styled-system/patterns/divider.mjs +0 -25
- package/packages/panda/styled-system/patterns/flex.mjs +0 -26
- package/packages/panda/styled-system/patterns/float.mjs +0 -52
- package/packages/panda/styled-system/patterns/grid-item.mjs +0 -25
- package/packages/panda/styled-system/patterns/grid.mjs +0 -27
- package/packages/panda/styled-system/patterns/hstack.mjs +0 -24
- package/packages/panda/styled-system/patterns/index.mjs +0 -20
- package/packages/panda/styled-system/patterns/link-overlay.mjs +0 -24
- package/packages/panda/styled-system/patterns/spacer.mjs +0 -25
- package/packages/panda/styled-system/patterns/square.mjs +0 -24
- package/packages/panda/styled-system/patterns/stack.mjs +0 -24
- package/packages/panda/styled-system/patterns/visually-hidden.mjs +0 -18
- package/packages/panda/styled-system/patterns/vstack.mjs +0 -24
- package/packages/panda/styled-system/patterns/wrap.mjs +0 -25
- package/packages/panda/styled-system/recipes/aeon-accordion.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-app-shell.mjs +0 -70
- package/packages/panda/styled-system/recipes/aeon-async.mjs +0 -57
- package/packages/panda/styled-system/recipes/aeon-avatar.mjs +0 -57
- package/packages/panda/styled-system/recipes/aeon-badge.mjs +0 -32
- package/packages/panda/styled-system/recipes/aeon-bar.mjs +0 -77
- package/packages/panda/styled-system/recipes/aeon-button-group.mjs +0 -37
- package/packages/panda/styled-system/recipes/aeon-button.mjs +0 -39
- package/packages/panda/styled-system/recipes/aeon-checkbox.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-combobox.mjs +0 -53
- package/packages/panda/styled-system/recipes/aeon-composer.mjs +0 -57
- package/packages/panda/styled-system/recipes/aeon-content.mjs +0 -70
- package/packages/panda/styled-system/recipes/aeon-conversation.mjs +0 -61
- package/packages/panda/styled-system/recipes/aeon-dialog.mjs +0 -61
- package/packages/panda/styled-system/recipes/aeon-entry.mjs +0 -100
- package/packages/panda/styled-system/recipes/aeon-field.mjs +0 -53
- package/packages/panda/styled-system/recipes/aeon-file-upload.mjs +0 -61
- package/packages/panda/styled-system/recipes/aeon-identity.mjs +0 -63
- package/packages/panda/styled-system/recipes/aeon-list-row.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-menu.mjs +0 -53
- package/packages/panda/styled-system/recipes/aeon-metric-strip.mjs +0 -54
- package/packages/panda/styled-system/recipes/aeon-nav.mjs +0 -69
- package/packages/panda/styled-system/recipes/aeon-panel.mjs +0 -58
- package/packages/panda/styled-system/recipes/aeon-pin-input.mjs +0 -37
- package/packages/panda/styled-system/recipes/aeon-popover.mjs +0 -53
- package/packages/panda/styled-system/recipes/aeon-profile-header.mjs +0 -62
- package/packages/panda/styled-system/recipes/aeon-progress.mjs +0 -45
- package/packages/panda/styled-system/recipes/aeon-radio-group.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-range-slider.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-scroll.mjs +0 -64
- package/packages/panda/styled-system/recipes/aeon-select.mjs +0 -57
- package/packages/panda/styled-system/recipes/aeon-separator.mjs +0 -42
- package/packages/panda/styled-system/recipes/aeon-slider.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-switch.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-tabs.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-theme-switcher.mjs +0 -59
- package/packages/panda/styled-system/recipes/aeon-thread.mjs +0 -73
- package/packages/panda/styled-system/recipes/aeon-toast.mjs +0 -49
- package/packages/panda/styled-system/recipes/aeon-tooltip.mjs +0 -49
- package/packages/panda/styled-system/recipes/create-recipe.mjs +0 -82
- package/packages/panda/styled-system/recipes/index.mjs +0 -39
- package/packages/panda/styled-system/tokens/index.mjs +0 -2224
- package/packages/panda/styled-system/tokens/tokens.d.ts +0 -60
- package/packages/panda/styled-system/types/composition.d.ts +0 -227
- package/packages/panda/styled-system/types/conditions.d.ts +0 -346
- package/packages/panda/styled-system/types/csstype.d.ts +0 -22570
- package/packages/panda/styled-system/types/global.d.ts +0 -20
- package/packages/panda/styled-system/types/parts.d.ts +0 -8
- package/packages/panda/styled-system/types/prop-type.d.ts +0 -250
- package/packages/panda/styled-system/types/selectors.d.ts +0 -59
- package/packages/panda/styled-system/types/static-css.d.ts +0 -56
- package/packages/panda/styled-system/types/style-props.d.ts +0 -8089
- package/packages/panda/styled-system/types/system-types.d.ts +0 -151
- package/packages/primitives/node_modules/.bin/esbuild +0 -21
- package/packages/primitives/node_modules/.bin/jiti +0 -21
- package/packages/primitives/node_modules/.bin/tsc +0 -21
- package/packages/primitives/node_modules/.bin/tsserver +0 -21
- package/packages/primitives/node_modules/.bin/tsup +0 -21
- package/packages/primitives/node_modules/.bin/tsup-node +0 -21
- package/packages/primitives/node_modules/.bin/tsx +0 -21
- package/packages/primitives/node_modules/.bin/vite +0 -21
- package/packages/primitives/node_modules/.bin/vitest +0 -21
- package/packages/primitives/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/primitives/src/__tests__/app-nav.test.ts +0 -30
- package/packages/primitives/src/__tests__/file-upload.test.ts +0 -25
- package/packages/primitives/src/__tests__/floating-surface.test.ts +0 -29
- package/packages/primitives/src/__tests__/range-slider.test.ts +0 -39
- package/packages/react/node_modules/.bin/esbuild +0 -21
- package/packages/react/node_modules/.bin/jiti +0 -21
- package/packages/react/node_modules/.bin/tsc +0 -21
- package/packages/react/node_modules/.bin/tsserver +0 -21
- package/packages/react/node_modules/.bin/tsup +0 -21
- package/packages/react/node_modules/.bin/tsup-node +0 -21
- package/packages/react/node_modules/.bin/tsx +0 -21
- package/packages/react/node_modules/.bin/vite +0 -21
- package/packages/react/node_modules/.bin/vitest +0 -21
- package/packages/react/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/react/src/avatar/avatar.test.tsx +0 -27
- package/packages/react/src/dialog/dialog.test.tsx +0 -50
- package/packages/react/src/select/select.test.tsx +0 -81
- package/packages/react/src/toast/toast.test.tsx +0 -40
- package/packages/react/src/tooltip/tooltip.test.tsx +0 -122
- package/packages/react-scene/node_modules/.bin/jiti +0 -21
- package/packages/react-scene/node_modules/.bin/tsc +0 -21
- package/packages/react-scene/node_modules/.bin/tsserver +0 -21
- package/packages/react-scene/node_modules/.bin/tsup +0 -21
- package/packages/react-scene/node_modules/.bin/tsup-node +0 -21
- package/packages/react-scene/node_modules/.bin/tsx +0 -21
- package/packages/scene/node_modules/.bin/jiti +0 -21
- package/packages/scene/node_modules/.bin/tsc +0 -21
- package/packages/scene/node_modules/.bin/tsserver +0 -21
- package/packages/scene/node_modules/.bin/tsup +0 -21
- package/packages/scene/node_modules/.bin/tsup-node +0 -21
- package/packages/scene/node_modules/.bin/tsx +0 -21
- package/packages/schemas/node_modules/.bin/esbuild +0 -21
- package/packages/schemas/node_modules/.bin/jiti +0 -21
- package/packages/schemas/node_modules/.bin/tsc +0 -21
- package/packages/schemas/node_modules/.bin/tsserver +0 -21
- package/packages/schemas/node_modules/.bin/tsup +0 -21
- package/packages/schemas/node_modules/.bin/tsup-node +0 -21
- package/packages/schemas/node_modules/.bin/tsx +0 -21
- package/packages/schemas/node_modules/.bin/vite +0 -21
- package/packages/schemas/node_modules/.bin/vitest +0 -21
- package/packages/schemas/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/schemas/src/aeon-to-schema.test.ts +0 -70
- package/packages/schemas/src/index.test.ts +0 -108
- package/packages/signal/node_modules/.bin/jiti +0 -21
- package/packages/signal/node_modules/.bin/tsc +0 -21
- package/packages/signal/node_modules/.bin/tsserver +0 -21
- package/packages/signal/node_modules/.bin/tsup +0 -21
- package/packages/signal/node_modules/.bin/tsup-node +0 -21
- package/packages/signal/node_modules/.bin/tsx +0 -21
- package/packages/site/node_modules/.bin/jiti +0 -21
- package/packages/site/node_modules/.bin/tsc +0 -21
- package/packages/site/node_modules/.bin/tsserver +0 -21
- package/packages/site/node_modules/.bin/tsup +0 -21
- package/packages/site/node_modules/.bin/tsup-node +0 -21
- package/packages/site/node_modules/.bin/tsx +0 -21
- package/packages/solid/node_modules/.bin/jiti +0 -21
- package/packages/solid/node_modules/.bin/tsc +0 -21
- package/packages/solid/node_modules/.bin/tsserver +0 -21
- package/packages/solid/node_modules/.bin/tsup +0 -21
- package/packages/solid/node_modules/.bin/tsup-node +0 -21
- package/packages/solid/node_modules/.bin/tsx +0 -21
- package/packages/surface/node_modules/.bin/jiti +0 -21
- package/packages/surface/node_modules/.bin/tsc +0 -21
- package/packages/surface/node_modules/.bin/tsserver +0 -21
- package/packages/surface/node_modules/.bin/tsup +0 -21
- package/packages/surface/node_modules/.bin/tsup-node +0 -21
- package/packages/surface/node_modules/.bin/tsx +0 -21
- package/packages/svelte/node_modules/.bin/acorn +0 -21
- package/packages/svelte/node_modules/.bin/esbuild +0 -21
- package/packages/svelte/node_modules/.bin/jiti +0 -21
- package/packages/svelte/node_modules/.bin/svelte-check +0 -21
- package/packages/svelte/node_modules/.bin/tsc +0 -21
- package/packages/svelte/node_modules/.bin/tsserver +0 -21
- package/packages/svelte/node_modules/.bin/tsup +0 -21
- package/packages/svelte/node_modules/.bin/tsup-node +0 -21
- package/packages/svelte/node_modules/.bin/tsx +0 -21
- package/packages/svelte/node_modules/.bin/vite +0 -21
- package/packages/ui/node_modules/.bin/jiti +0 -21
- package/packages/ui/node_modules/.bin/tsc +0 -21
- package/packages/ui/node_modules/.bin/tsserver +0 -21
- package/packages/ui/node_modules/.bin/tsup +0 -21
- package/packages/ui/node_modules/.bin/tsup-node +0 -21
- package/packages/ui/node_modules/.bin/tsx +0 -21
- package/packages/vue/node_modules/.bin/jiti +0 -21
- package/packages/vue/node_modules/.bin/tsc +0 -21
- package/packages/vue/node_modules/.bin/tsserver +0 -21
- package/packages/vue/node_modules/.bin/tsup +0 -21
- package/packages/vue/node_modules/.bin/tsup-node +0 -21
- package/packages/vue/node_modules/.bin/tsx +0 -21
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import { assign, createActor, fromCallback, fromPromise, setup, type ActorRefFrom, type SnapshotFrom } from 'xstate'
|
|
2
|
+
|
|
3
|
+
/** Stable lifecycle states of one cache entry (see STATES.md). */
|
|
4
|
+
export const CACHE_STATES = ['idle', 'loading', 'ready', 'stale', 'refreshing', 'failed'] as const
|
|
5
|
+
|
|
6
|
+
export type CacheState = (typeof CACHE_STATES)[number]
|
|
7
|
+
|
|
8
|
+
/** Longest delay a timer can hold; a longer time-to-live is checked again when read. */
|
|
9
|
+
const MAX_DELAY_MS = 2_147_483_647
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Caches named for secrets, keys or spend decisions are refused: those must be
|
|
13
|
+
* read fresh every time, never served from memory.
|
|
14
|
+
*/
|
|
15
|
+
const NEVER_CACHE = /\b(secrets?|private[-_ ]?keys?|mnemonics?|seeds?|passwords?|passphrases?|wif|xprv|signing[-_ ]?keys?|spend)\b/i
|
|
16
|
+
|
|
17
|
+
export function isCacheableId(id: string): boolean {
|
|
18
|
+
return id.trim().length > 0 && !NEVER_CACHE.test(id)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CacheEntryContext<T, K> {
|
|
22
|
+
key: K
|
|
23
|
+
ttl: number
|
|
24
|
+
data: T | undefined
|
|
25
|
+
error: string | null
|
|
26
|
+
/** When `data` was loaded; null while there is none. */
|
|
27
|
+
loadedAt: number | null
|
|
28
|
+
/** An invalidation landed mid-load: the result may predate the write, so load once more. */
|
|
29
|
+
dirty: boolean
|
|
30
|
+
now: () => number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type CacheEntryEvent =
|
|
34
|
+
| { type: 'FETCH' }
|
|
35
|
+
| { type: 'REFRESH' }
|
|
36
|
+
| { type: 'INVALIDATE'; refetch?: boolean }
|
|
37
|
+
| { type: 'CLEAR' }
|
|
38
|
+
|
|
39
|
+
export interface CacheEntryInput<K> {
|
|
40
|
+
key: K
|
|
41
|
+
ttl: number
|
|
42
|
+
now?: () => number
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const message = (error: unknown) => (error instanceof Error ? error.message : String(error))
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* One keyed entry: idle until fetched, loading the first time, ready while
|
|
49
|
+
* younger than its time-to-live, then stale. FETCH on a stale or expired entry
|
|
50
|
+
* revalidates in `refreshing` while the old data stays readable; FETCH while a
|
|
51
|
+
* load runs is dropped, so one load serves every caller. INVALIDATE marks the
|
|
52
|
+
* entry stale (and reloads when `refetch`); CLEAR drops the data and cancels a
|
|
53
|
+
* running load so its result never lands.
|
|
54
|
+
*/
|
|
55
|
+
export function createCacheEntryMachine<T, K = string>() {
|
|
56
|
+
return setup({
|
|
57
|
+
types: {
|
|
58
|
+
context: {} as CacheEntryContext<T, K>,
|
|
59
|
+
events: {} as CacheEntryEvent,
|
|
60
|
+
input: {} as CacheEntryInput<K>,
|
|
61
|
+
},
|
|
62
|
+
actors: {
|
|
63
|
+
load: fromPromise<T, { key: K }>(async () => {
|
|
64
|
+
throw new Error('cache entry load is not provided')
|
|
65
|
+
}),
|
|
66
|
+
},
|
|
67
|
+
delays: {
|
|
68
|
+
ttl: ({ context }) => {
|
|
69
|
+
const age = context.loadedAt === null ? 0 : context.now() - context.loadedAt
|
|
70
|
+
return Math.min(Math.max(0, context.ttl - age), MAX_DELAY_MS)
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
guards: {
|
|
74
|
+
expired: ({ context }) => context.loadedAt !== null && context.now() - context.loadedAt >= context.ttl,
|
|
75
|
+
dirty: ({ context }) => context.dirty,
|
|
76
|
+
refetch: ({ event }) => event.type === 'INVALIDATE' && event.refetch === true,
|
|
77
|
+
},
|
|
78
|
+
actions: {
|
|
79
|
+
markDirty: assign({ dirty: true }),
|
|
80
|
+
clear: assign({ data: undefined, error: null, loadedAt: null, dirty: false }),
|
|
81
|
+
},
|
|
82
|
+
}).createMachine({
|
|
83
|
+
id: 'cacheEntry',
|
|
84
|
+
context: ({ input }) => ({
|
|
85
|
+
key: input.key,
|
|
86
|
+
ttl: input.ttl,
|
|
87
|
+
data: undefined,
|
|
88
|
+
error: null,
|
|
89
|
+
loadedAt: null,
|
|
90
|
+
dirty: false,
|
|
91
|
+
now: input.now ?? Date.now,
|
|
92
|
+
}),
|
|
93
|
+
initial: 'idle',
|
|
94
|
+
on: { CLEAR: { target: '.idle', actions: 'clear' } },
|
|
95
|
+
states: {
|
|
96
|
+
idle: {
|
|
97
|
+
on: { FETCH: 'loading', REFRESH: 'loading', INVALIDATE: { guard: 'refetch', target: 'loading' } },
|
|
98
|
+
},
|
|
99
|
+
loading: {
|
|
100
|
+
invoke: {
|
|
101
|
+
src: 'load',
|
|
102
|
+
input: ({ context }) => ({ key: context.key }),
|
|
103
|
+
onDone: [
|
|
104
|
+
{
|
|
105
|
+
guard: 'dirty',
|
|
106
|
+
target: 'refreshing',
|
|
107
|
+
actions: assign(({ context, event }) => ({ data: event.output, error: null, loadedAt: context.now(), dirty: false })),
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
target: 'ready',
|
|
111
|
+
actions: assign(({ context, event }) => ({ data: event.output, error: null, loadedAt: context.now() })),
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
onError: { target: 'failed', actions: assign(({ event }) => ({ error: message(event.error), dirty: false })) },
|
|
115
|
+
},
|
|
116
|
+
on: { INVALIDATE: { actions: 'markDirty' } },
|
|
117
|
+
},
|
|
118
|
+
ready: {
|
|
119
|
+
after: { ttl: { guard: 'expired', target: 'stale' } },
|
|
120
|
+
on: {
|
|
121
|
+
FETCH: { guard: 'expired', target: 'refreshing' },
|
|
122
|
+
REFRESH: 'refreshing',
|
|
123
|
+
INVALIDATE: [{ guard: 'refetch', target: 'refreshing' }, { target: 'stale' }],
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
stale: {
|
|
127
|
+
on: { FETCH: 'refreshing', REFRESH: 'refreshing', INVALIDATE: { guard: 'refetch', target: 'refreshing' } },
|
|
128
|
+
},
|
|
129
|
+
refreshing: {
|
|
130
|
+
invoke: {
|
|
131
|
+
src: 'load',
|
|
132
|
+
input: ({ context }) => ({ key: context.key }),
|
|
133
|
+
onDone: [
|
|
134
|
+
{
|
|
135
|
+
guard: 'dirty',
|
|
136
|
+
target: 'refreshing',
|
|
137
|
+
reenter: true,
|
|
138
|
+
actions: assign(({ context, event }) => ({ data: event.output, error: null, loadedAt: context.now(), dirty: false })),
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
target: 'ready',
|
|
142
|
+
actions: assign(({ context, event }) => ({ data: event.output, error: null, loadedAt: context.now() })),
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
onError: { target: 'stale', actions: assign(({ event }) => ({ error: message(event.error), dirty: false })) },
|
|
146
|
+
},
|
|
147
|
+
on: { INVALIDATE: { actions: 'markDirty' } },
|
|
148
|
+
},
|
|
149
|
+
failed: {
|
|
150
|
+
on: { FETCH: 'loading', REFRESH: 'loading', INVALIDATE: { guard: 'refetch', target: 'loading' } },
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export const cacheEntryMachine = createCacheEntryMachine()
|
|
157
|
+
|
|
158
|
+
export type CacheEntryActor<T, K = string> = ActorRefFrom<ReturnType<typeof createCacheEntryMachine<T, K>>>
|
|
159
|
+
type CacheEntrySnapshot<T, K> = SnapshotFrom<ReturnType<typeof createCacheEntryMachine<T, K>>>
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* What a reader sees of one entry. The same object comes back until the entry
|
|
163
|
+
* changes, and `data` keeps its identity across ready, stale and refreshing,
|
|
164
|
+
* so selectors over a view never cause a re-render on their own.
|
|
165
|
+
*/
|
|
166
|
+
export interface CacheView<T> {
|
|
167
|
+
readonly state: CacheState
|
|
168
|
+
readonly data: T | undefined
|
|
169
|
+
readonly error: string | null
|
|
170
|
+
readonly loadedAt: number | null
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const IDLE_VIEW: CacheView<never> = Object.freeze({ state: 'idle', data: undefined, error: null, loadedAt: null })
|
|
174
|
+
|
|
175
|
+
/** Commands a chart sends the cache, directly or through the invoked cache actor. */
|
|
176
|
+
export type CacheCommand<K> =
|
|
177
|
+
| { type: 'CACHE.FETCH'; key?: K }
|
|
178
|
+
| { type: 'CACHE.REFRESH'; key?: K }
|
|
179
|
+
| { type: 'CACHE.INVALIDATE'; key?: K; tag?: string }
|
|
180
|
+
| { type: 'CACHE.KEY'; key: K }
|
|
181
|
+
| { type: 'CACHE.CLEAR' }
|
|
182
|
+
|
|
183
|
+
/** What the invoked cache actor sends its parent chart whenever its entry changes. */
|
|
184
|
+
export interface CacheUpdate<T, K> {
|
|
185
|
+
type: 'CACHE.UPDATE'
|
|
186
|
+
cache: string
|
|
187
|
+
key: K
|
|
188
|
+
view: CacheView<T>
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface ChartCacheOptions<T, K> {
|
|
192
|
+
/** Names the cache in logs and errors. Names of secrets, keys or spend decisions are refused. */
|
|
193
|
+
id: string
|
|
194
|
+
load: (key: K, context: { signal: AbortSignal }) => Promise<T>
|
|
195
|
+
/** Milliseconds an entry stays fresh, for every key or per key. */
|
|
196
|
+
ttl: number | ((key: K) => number)
|
|
197
|
+
tags?: (key: K) => readonly string[]
|
|
198
|
+
/** Turns a key into the string entries are stored under. Defaults to `String` for strings, else JSON. */
|
|
199
|
+
keyOf?: (key: K) => string
|
|
200
|
+
/** Most entries kept; the least recently used unwatched, settled ones go first. Default 100. */
|
|
201
|
+
maxEntries?: number
|
|
202
|
+
now?: () => number
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface ChartCache<T, K = string> {
|
|
206
|
+
readonly id: string
|
|
207
|
+
/** Entries currently held. */
|
|
208
|
+
readonly size: number
|
|
209
|
+
/** The entry's current view, without loading it. Stable until the entry changes. */
|
|
210
|
+
peek(key: K): CacheView<T>
|
|
211
|
+
/** Loads the entry if it is missing, failed, stale or expired; a running load is reused. */
|
|
212
|
+
fetch(key: K): void
|
|
213
|
+
/** Reloads now, keeping the old data readable meanwhile. */
|
|
214
|
+
refresh(key: K): void
|
|
215
|
+
/** Resolves with the entry's data, serving stale data at once while it revalidates. */
|
|
216
|
+
read(key: K): Promise<T>
|
|
217
|
+
/** Marks entries stale; watched ones reload at once. */
|
|
218
|
+
invalidate(target: { key: K } | { tag: string }): void
|
|
219
|
+
/** Drops every entry's data and cancels running loads (lock, account or network switch). */
|
|
220
|
+
clear(): void
|
|
221
|
+
subscribe(key: K, listener: (view: CacheView<T>) => void): () => void
|
|
222
|
+
send(command: CacheCommand<K>): void
|
|
223
|
+
/**
|
|
224
|
+
* Invoke from a chart: `invoke: { id: 'cache', src: cache.actor, input: { key } }`.
|
|
225
|
+
* It fetches the key, sends `CACHE.UPDATE` on every change, and takes
|
|
226
|
+
* `CACHE.*` commands from the parent (`sendTo('cache', …)`); commands without
|
|
227
|
+
* a key apply to its own, and `CACHE.KEY` moves it to another key.
|
|
228
|
+
*/
|
|
229
|
+
readonly actor: ReturnType<typeof fromCallback<CacheCommand<K>, { key: K; fetch?: boolean }>>
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
interface Slot<T, K> {
|
|
233
|
+
key: K
|
|
234
|
+
tags: readonly string[]
|
|
235
|
+
actor: CacheEntryActor<T, K>
|
|
236
|
+
view: CacheView<T>
|
|
237
|
+
listeners: Set<(view: CacheView<T>) => void>
|
|
238
|
+
usedAt: number
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const defaultKeyOf = (key: unknown) => (typeof key === 'string' ? key : JSON.stringify(key))
|
|
242
|
+
|
|
243
|
+
function viewOf<T, K>(snapshot: CacheEntrySnapshot<T, K>, previous: CacheView<T>): CacheView<T> {
|
|
244
|
+
const state = snapshot.value as CacheState
|
|
245
|
+
const { data, error, loadedAt } = snapshot.context
|
|
246
|
+
if (previous.state === state && previous.data === data && previous.error === error && previous.loadedAt === loadedAt) return previous
|
|
247
|
+
return Object.freeze({ state, data, error, loadedAt })
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* A keyed cache shared by every chart that reads it, so a remounted chart is
|
|
252
|
+
* served from memory instead of loading again. Each entry is its own
|
|
253
|
+
* `cacheEntryMachine`; create one cache per kind of data at module scope.
|
|
254
|
+
*/
|
|
255
|
+
export function createChartCache<T, K = string>(options: ChartCacheOptions<T, K>): ChartCache<T, K> {
|
|
256
|
+
if (!isCacheableId(options.id)) throw new Error(`refusing to cache "${options.id}": secrets, keys and spend decisions are never cached`)
|
|
257
|
+
const keyOf = options.keyOf ?? defaultKeyOf
|
|
258
|
+
const maxEntries = Math.max(1, options.maxEntries ?? 100)
|
|
259
|
+
const ttlOf = typeof options.ttl === 'function' ? options.ttl : () => options.ttl as number
|
|
260
|
+
const machine = createCacheEntryMachine<T, K>().provide({
|
|
261
|
+
actors: { load: fromPromise<T, { key: K }>(({ input, signal }) => options.load(input.key, { signal })) },
|
|
262
|
+
})
|
|
263
|
+
const slots = new Map<string, Slot<T, K>>()
|
|
264
|
+
let clock = 0
|
|
265
|
+
|
|
266
|
+
const busy = (slot: Slot<T, K>) => slot.view.state === 'loading' || slot.view.state === 'refreshing'
|
|
267
|
+
|
|
268
|
+
const evict = (keep?: Slot<T, K>) => {
|
|
269
|
+
if (slots.size <= maxEntries) return
|
|
270
|
+
const idle = [...slots.entries()]
|
|
271
|
+
.filter(([, slot]) => slot !== keep && slot.listeners.size === 0 && !busy(slot))
|
|
272
|
+
.sort((a, b) => a[1].usedAt - b[1].usedAt)
|
|
273
|
+
for (const [id, slot] of idle) {
|
|
274
|
+
if (slots.size <= maxEntries) break
|
|
275
|
+
slot.actor.stop()
|
|
276
|
+
slots.delete(id)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const slotFor = (key: K): Slot<T, K> => {
|
|
281
|
+
const id = keyOf(key)
|
|
282
|
+
const existing = slots.get(id)
|
|
283
|
+
if (existing) {
|
|
284
|
+
existing.usedAt = ++clock
|
|
285
|
+
return existing
|
|
286
|
+
}
|
|
287
|
+
const actor = createActor(machine, { input: { key, ttl: ttlOf(key), now: options.now } })
|
|
288
|
+
const slot: Slot<T, K> = { key, tags: options.tags?.(key) ?? [], actor, view: IDLE_VIEW, listeners: new Set(), usedAt: ++clock }
|
|
289
|
+
actor.subscribe((snapshot) => {
|
|
290
|
+
const next = viewOf(snapshot, slot.view)
|
|
291
|
+
if (next === slot.view) return
|
|
292
|
+
slot.view = next
|
|
293
|
+
for (const listener of [...slot.listeners]) listener(next)
|
|
294
|
+
})
|
|
295
|
+
slots.set(id, slot)
|
|
296
|
+
actor.start()
|
|
297
|
+
evict(slot)
|
|
298
|
+
return slot
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const invalidateSlot = (slot: Slot<T, K>) => slot.actor.send({ type: 'INVALIDATE', refetch: slot.listeners.size > 0 })
|
|
302
|
+
|
|
303
|
+
const cache: Omit<ChartCache<T, K>, 'actor' | 'size'> & { actor?: ChartCache<T, K>['actor'] } = {
|
|
304
|
+
id: options.id,
|
|
305
|
+
peek: (key) => slots.get(keyOf(key))?.view ?? IDLE_VIEW,
|
|
306
|
+
fetch: (key) => slotFor(key).actor.send({ type: 'FETCH' }),
|
|
307
|
+
refresh: (key) => slotFor(key).actor.send({ type: 'REFRESH' }),
|
|
308
|
+
read: (key) =>
|
|
309
|
+
new Promise<T>((resolve, reject) => {
|
|
310
|
+
const slot = slotFor(key)
|
|
311
|
+
const settle = (view: CacheView<T>) => {
|
|
312
|
+
if (view.loadedAt !== null && view.state !== 'loading') resolve(view.data as T)
|
|
313
|
+
else if (view.state === 'failed') reject(new Error(view.error ?? `${options.id} failed to load`))
|
|
314
|
+
else return false
|
|
315
|
+
return true
|
|
316
|
+
}
|
|
317
|
+
slot.actor.send({ type: 'FETCH' })
|
|
318
|
+
if (settle(slot.view)) return
|
|
319
|
+
const stop = cache.subscribe(key, (view) => {
|
|
320
|
+
if (settle(view)) stop()
|
|
321
|
+
})
|
|
322
|
+
}),
|
|
323
|
+
invalidate: (target) => {
|
|
324
|
+
if ('key' in target) {
|
|
325
|
+
const slot = slots.get(keyOf(target.key))
|
|
326
|
+
if (slot) invalidateSlot(slot)
|
|
327
|
+
return
|
|
328
|
+
}
|
|
329
|
+
for (const slot of slots.values()) if (slot.tags.includes(target.tag)) invalidateSlot(slot)
|
|
330
|
+
},
|
|
331
|
+
clear: () => {
|
|
332
|
+
for (const [id, slot] of [...slots.entries()]) {
|
|
333
|
+
slot.actor.send({ type: 'CLEAR' })
|
|
334
|
+
if (slot.listeners.size === 0) {
|
|
335
|
+
slot.actor.stop()
|
|
336
|
+
slots.delete(id)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
subscribe: (key, listener) => {
|
|
341
|
+
const slot = slotFor(key)
|
|
342
|
+
slot.listeners.add(listener)
|
|
343
|
+
return () => {
|
|
344
|
+
slot.listeners.delete(listener)
|
|
345
|
+
evict()
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
send: (command) => {
|
|
349
|
+
switch (command.type) {
|
|
350
|
+
case 'CACHE.FETCH':
|
|
351
|
+
if (command.key !== undefined) cache.fetch(command.key)
|
|
352
|
+
return
|
|
353
|
+
case 'CACHE.REFRESH':
|
|
354
|
+
if (command.key !== undefined) cache.refresh(command.key)
|
|
355
|
+
return
|
|
356
|
+
case 'CACHE.INVALIDATE':
|
|
357
|
+
if (command.tag !== undefined) cache.invalidate({ tag: command.tag })
|
|
358
|
+
else if (command.key !== undefined) cache.invalidate({ key: command.key })
|
|
359
|
+
return
|
|
360
|
+
case 'CACHE.KEY':
|
|
361
|
+
cache.fetch(command.key)
|
|
362
|
+
return
|
|
363
|
+
case 'CACHE.CLEAR':
|
|
364
|
+
cache.clear()
|
|
365
|
+
return
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
cache.actor = fromCallback<CacheCommand<K>, { key: K; fetch?: boolean }>(({ input, sendBack, receive }) => {
|
|
371
|
+
let key = input.key
|
|
372
|
+
let stop = () => {}
|
|
373
|
+
const watch = (next: K, fetch: boolean) => {
|
|
374
|
+
stop()
|
|
375
|
+
key = next
|
|
376
|
+
const report = (view: CacheView<T>) => sendBack({ type: 'CACHE.UPDATE', cache: options.id, key: next, view } satisfies CacheUpdate<T, K>)
|
|
377
|
+
stop = cache.subscribe(next, report)
|
|
378
|
+
report(cache.peek(next))
|
|
379
|
+
if (fetch) cache.fetch(next)
|
|
380
|
+
}
|
|
381
|
+
watch(key, input.fetch !== false)
|
|
382
|
+
receive((command) => {
|
|
383
|
+
if (command.type === 'CACHE.KEY') {
|
|
384
|
+
if (keyOf(command.key) !== keyOf(key)) watch(command.key, true)
|
|
385
|
+
return
|
|
386
|
+
}
|
|
387
|
+
if (command.type === 'CACHE.CLEAR') return cache.clear()
|
|
388
|
+
if (command.type === 'CACHE.INVALIDATE' && command.tag !== undefined) return cache.send(command)
|
|
389
|
+
cache.send({ ...command, key: command.key ?? key } as CacheCommand<K>)
|
|
390
|
+
})
|
|
391
|
+
return () => stop()
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
return Object.defineProperty(cache, 'size', { get: () => slots.size, enumerable: true }) as ChartCache<T, K>
|
|
395
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { playSound } from '@aeon-ui/core'
|
|
2
|
+
import { fromPromise, setup } from 'xstate'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Copy-to-clipboard feedback.
|
|
6
|
+
*
|
|
7
|
+
* Events: COPY { value } writes `value` to the system clipboard.
|
|
8
|
+
* States: idle → copying → copied | failed, back to idle after `timeout` ms. COPY again restarts.
|
|
9
|
+
* Entering copied / failed plays the `copy` / `error` sound (silent unless the app enabled sounds).
|
|
10
|
+
*/
|
|
11
|
+
export interface ClipboardContext {
|
|
12
|
+
/** How long `copied` / `failed` show before returning to idle, in ms. */
|
|
13
|
+
timeout: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type ClipboardEvent = { type: 'COPY'; value: string }
|
|
17
|
+
|
|
18
|
+
export const CLIPBOARD_STATES = ['idle', 'copying', 'copied', 'failed'] as const
|
|
19
|
+
export type ClipboardStatus = (typeof CLIPBOARD_STATES)[number]
|
|
20
|
+
|
|
21
|
+
export const clipboardMachine = setup({
|
|
22
|
+
types: {
|
|
23
|
+
context: {} as ClipboardContext,
|
|
24
|
+
events: {} as ClipboardEvent,
|
|
25
|
+
input: {} as Partial<ClipboardContext> | undefined,
|
|
26
|
+
},
|
|
27
|
+
actors: {
|
|
28
|
+
write: fromPromise<void, { value: string }>(async ({ input }) => {
|
|
29
|
+
await navigator.clipboard.writeText(input.value)
|
|
30
|
+
}),
|
|
31
|
+
},
|
|
32
|
+
actions: {
|
|
33
|
+
soundCopied: () => playSound('copy'),
|
|
34
|
+
soundFailed: () => playSound('error'),
|
|
35
|
+
},
|
|
36
|
+
delays: {
|
|
37
|
+
timeout: ({ context }) => context.timeout,
|
|
38
|
+
},
|
|
39
|
+
}).createMachine({
|
|
40
|
+
id: 'clipboard',
|
|
41
|
+
context: ({ input }) => ({ timeout: input?.timeout ?? 1500 }),
|
|
42
|
+
initial: 'idle',
|
|
43
|
+
states: {
|
|
44
|
+
idle: { on: { COPY: 'copying' } },
|
|
45
|
+
copying: {
|
|
46
|
+
invoke: {
|
|
47
|
+
src: 'write',
|
|
48
|
+
input: ({ event }) => ({ value: (event as ClipboardEvent).value }),
|
|
49
|
+
onDone: 'copied',
|
|
50
|
+
onError: 'failed',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
copied: { entry: 'soundCopied', after: { timeout: 'idle' }, on: { COPY: 'copying' } },
|
|
54
|
+
failed: { entry: 'soundFailed', after: { timeout: 'idle' }, on: { COPY: 'copying' } },
|
|
55
|
+
},
|
|
56
|
+
})
|