foldkit-primitives 0.15.4 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/device/fullscreen.d.ts +28 -0
- package/dist/device/fullscreen.d.ts.map +1 -0
- package/dist/device/fullscreen.js +69 -0
- package/dist/device/fullscreen.js.map +1 -0
- package/dist/device/geolocation.d.ts +56 -0
- package/dist/device/geolocation.d.ts.map +1 -0
- package/dist/device/geolocation.js +87 -0
- package/dist/device/geolocation.js.map +1 -0
- package/dist/device/index.d.ts +5 -0
- package/dist/device/index.js +6 -0
- package/dist/device/media-devices.d.ts +88 -0
- package/dist/device/media-devices.d.ts.map +1 -0
- package/dist/device/media-devices.js +117 -0
- package/dist/device/media-devices.js.map +1 -0
- package/dist/device/media-stream.d.ts +93 -0
- package/dist/device/media-stream.d.ts.map +1 -0
- package/dist/device/media-stream.js +106 -0
- package/dist/device/media-stream.js.map +1 -0
- package/dist/device/permissions.d.ts +106 -0
- package/dist/device/permissions.d.ts.map +1 -0
- package/dist/device/permissions.js +143 -0
- package/dist/device/permissions.js.map +1 -0
- package/dist/dom/autofocus.d.ts +15 -0
- package/dist/dom/autofocus.d.ts.map +1 -0
- package/dist/dom/autofocus.js +22 -0
- package/dist/dom/autofocus.js.map +1 -0
- package/dist/dom/clipboard.d.ts +30 -0
- package/dist/dom/clipboard.d.ts.map +1 -0
- package/dist/dom/clipboard.js +50 -0
- package/dist/dom/clipboard.js.map +1 -0
- package/dist/dom/editable-text.d.ts +72 -0
- package/dist/dom/editable-text.d.ts.map +1 -0
- package/dist/dom/editable-text.js +232 -0
- package/dist/dom/editable-text.js.map +1 -0
- package/dist/dom/fluid-hover.d.ts +93 -0
- package/dist/dom/fluid-hover.d.ts.map +1 -0
- package/dist/dom/fluid-hover.js +294 -0
- package/dist/dom/fluid-hover.js.map +1 -0
- package/dist/dom/focus-scope.d.ts +21 -0
- package/dist/dom/focus-scope.d.ts.map +1 -0
- package/dist/dom/focus-scope.js +93 -0
- package/dist/dom/focus-scope.js.map +1 -0
- package/dist/dom/follow-tab-stop.d.ts +11 -0
- package/dist/dom/follow-tab-stop.d.ts.map +1 -0
- package/dist/dom/follow-tab-stop.js +54 -0
- package/dist/dom/follow-tab-stop.js.map +1 -0
- package/dist/dom/image-decode.d.ts +27 -0
- package/dist/dom/image-decode.d.ts.map +1 -0
- package/dist/dom/image-decode.js +50 -0
- package/dist/dom/image-decode.js.map +1 -0
- package/dist/dom/index.d.ts +24 -0
- package/dist/dom/index.js +25 -0
- package/dist/dom/input-mask.d.ts +35 -0
- package/dist/dom/input-mask.d.ts.map +1 -0
- package/dist/dom/input-mask.js +90 -0
- package/dist/dom/input-mask.js.map +1 -0
- package/dist/dom/keep-in-view.d.ts +16 -0
- package/dist/dom/keep-in-view.d.ts.map +1 -0
- package/dist/dom/keep-in-view.js +38 -0
- package/dist/dom/keep-in-view.js.map +1 -0
- package/dist/dom/keyboard-inset.d.ts +29 -0
- package/dist/dom/keyboard-inset.d.ts.map +1 -0
- package/dist/dom/keyboard-inset.js +45 -0
- package/dist/dom/keyboard-inset.js.map +1 -0
- package/dist/dom/layers.d.ts +6 -0
- package/dist/dom/layers.d.ts.map +1 -0
- package/dist/dom/layers.js +35 -0
- package/dist/dom/layers.js.map +1 -0
- package/dist/dom/measure.d.ts +42 -0
- package/dist/dom/measure.d.ts.map +1 -0
- package/dist/dom/measure.js +123 -0
- package/dist/dom/measure.js.map +1 -0
- package/dist/dom/move.d.ts +45 -0
- package/dist/dom/move.d.ts.map +1 -0
- package/dist/dom/move.js +96 -0
- package/dist/dom/move.js.map +1 -0
- package/dist/dom/pointed-links.d.ts +13 -0
- package/dist/dom/pointed-links.d.ts.map +1 -0
- package/dist/dom/pointed-links.js +59 -0
- package/dist/dom/pointed-links.js.map +1 -0
- package/dist/dom/pointer-drag.d.ts +132 -0
- package/dist/dom/pointer-drag.d.ts.map +1 -0
- package/dist/dom/pointer-drag.js +307 -0
- package/dist/dom/pointer-drag.js.map +1 -0
- package/dist/dom/pointer-position.d.ts +133 -0
- package/dist/dom/pointer-position.d.ts.map +1 -0
- package/dist/dom/pointer-position.js +173 -0
- package/dist/dom/pointer-position.js.map +1 -0
- package/dist/dom/script-loader.d.ts +12 -0
- package/dist/dom/script-loader.d.ts.map +1 -0
- package/dist/dom/script-loader.js +54 -0
- package/dist/dom/script-loader.js.map +1 -0
- package/dist/dom/scroll-bars.d.ts +52 -0
- package/dist/dom/scroll-bars.d.ts.map +1 -0
- package/dist/dom/scroll-bars.js +259 -0
- package/dist/dom/scroll-bars.js.map +1 -0
- package/dist/dom/scroll-settle.d.ts +33 -0
- package/dist/dom/scroll-settle.d.ts.map +1 -0
- package/dist/dom/scroll-settle.js +84 -0
- package/dist/dom/scroll-settle.js.map +1 -0
- package/dist/dom/scroll.d.ts +21 -0
- package/dist/dom/scroll.d.ts.map +1 -0
- package/dist/dom/scroll.js +141 -0
- package/dist/dom/scroll.js.map +1 -0
- package/dist/dom/share.d.ts +19 -0
- package/dist/dom/share.d.ts.map +1 -0
- package/dist/dom/share.js +41 -0
- package/dist/dom/share.js.map +1 -0
- package/dist/dom/swipe.d.ts +121 -0
- package/dist/dom/swipe.d.ts.map +1 -0
- package/dist/dom/swipe.js +291 -0
- package/dist/dom/swipe.js.map +1 -0
- package/dist/dom/targets.d.ts +45 -0
- package/dist/dom/targets.d.ts.map +1 -0
- package/dist/dom/targets.js +70 -0
- package/dist/dom/targets.js.map +1 -0
- package/dist/dom/track-box.d.ts +61 -0
- package/dist/dom/track-box.d.ts.map +1 -0
- package/dist/dom/track-box.js +131 -0
- package/dist/dom/track-box.js.map +1 -0
- package/dist/events/active-element.d.ts +15 -0
- package/dist/events/active-element.d.ts.map +1 -0
- package/dist/events/active-element.js +33 -0
- package/dist/events/active-element.js.map +1 -0
- package/dist/events/hotkeys.d.ts +22 -0
- package/dist/events/hotkeys.d.ts.map +1 -0
- package/dist/events/hotkeys.js +56 -0
- package/dist/events/hotkeys.js.map +1 -0
- package/dist/events/idle.d.ts +29 -0
- package/dist/events/idle.d.ts.map +1 -0
- package/dist/events/idle.js +51 -0
- package/dist/events/idle.js.map +1 -0
- package/dist/events/index.d.ts +9 -0
- package/dist/events/index.js +10 -0
- package/dist/{input-modality-l7InESYh.d.mts → events/input-modality.d.ts} +9 -10
- package/dist/events/input-modality.d.ts.map +1 -0
- package/dist/{input-modality-XwQOFLip.mjs → events/input-modality.js} +2 -2
- package/dist/events/input-modality.js.map +1 -0
- package/dist/events/keyboard.d.ts +30 -0
- package/dist/events/keyboard.d.ts.map +1 -0
- package/dist/events/keyboard.js +55 -0
- package/dist/events/keyboard.js.map +1 -0
- package/dist/events/pointer.d.ts +15 -0
- package/dist/events/pointer.d.ts.map +1 -0
- package/dist/events/pointer.js +28 -0
- package/dist/events/pointer.js.map +1 -0
- package/dist/events/scroll.d.ts +16 -0
- package/dist/events/scroll.d.ts.map +1 -0
- package/dist/events/scroll.js +29 -0
- package/dist/events/scroll.js.map +1 -0
- package/dist/events/visibility.d.ts +25 -0
- package/dist/events/visibility.d.ts.map +1 -0
- package/dist/events/visibility.js +28 -0
- package/dist/events/visibility.js.map +1 -0
- package/dist/events/window-size.d.ts +30 -0
- package/dist/events/window-size.d.ts.map +1 -0
- package/dist/events/window-size.js +63 -0
- package/dist/events/window-size.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/interaction/bundle-behavior.d.ts +37 -0
- package/dist/interaction/bundle-behavior.d.ts.map +1 -0
- package/dist/interaction/bundle-behavior.js +34 -0
- package/dist/interaction/bundle-behavior.js.map +1 -0
- package/dist/interaction/dismiss-layer.d.ts +100 -0
- package/dist/interaction/dismiss-layer.d.ts.map +1 -0
- package/dist/interaction/dismiss-layer.js +140 -0
- package/dist/interaction/dismiss-layer.js.map +1 -0
- package/dist/interaction/editable-text.d.ts +13 -0
- package/dist/interaction/editable-text.d.ts.map +1 -0
- package/dist/interaction/editable-text.js +17 -0
- package/dist/interaction/editable-text.js.map +1 -0
- package/dist/interaction/focus-scope.d.ts +21 -0
- package/dist/interaction/focus-scope.d.ts.map +1 -0
- package/dist/interaction/focus-scope.js +25 -0
- package/dist/interaction/focus-scope.js.map +1 -0
- package/dist/interaction/focus-visible.d.ts +9 -0
- package/dist/interaction/focus-visible.d.ts.map +1 -0
- package/dist/interaction/focus-visible.js +10 -0
- package/dist/interaction/focus-visible.js.map +1 -0
- package/dist/interaction/grid-navigation.d.ts +73 -0
- package/dist/interaction/grid-navigation.d.ts.map +1 -0
- package/dist/interaction/grid-navigation.js +137 -0
- package/dist/interaction/grid-navigation.js.map +1 -0
- package/dist/interaction/index.d.ts +21 -0
- package/dist/interaction/index.js +21 -0
- package/dist/interaction/layers.d.ts +12 -0
- package/dist/interaction/layers.d.ts.map +1 -0
- package/dist/interaction/layers.js +14 -0
- package/dist/interaction/layers.js.map +1 -0
- package/dist/interaction/list-navigation.d.ts +105 -0
- package/dist/interaction/list-navigation.d.ts.map +1 -0
- package/dist/interaction/list-navigation.js +168 -0
- package/dist/interaction/list-navigation.js.map +1 -0
- package/dist/interaction/live-announce.d.ts +70 -0
- package/dist/interaction/live-announce.d.ts.map +1 -0
- package/dist/interaction/live-announce.js +115 -0
- package/dist/interaction/live-announce.js.map +1 -0
- package/dist/interaction/long-press.d.ts +102 -0
- package/dist/interaction/long-press.d.ts.map +1 -0
- package/dist/interaction/long-press.js +115 -0
- package/dist/interaction/long-press.js.map +1 -0
- package/dist/interaction/move.d.ts +10 -0
- package/dist/interaction/move.d.ts.map +1 -0
- package/dist/interaction/move.js +17 -0
- package/dist/interaction/move.js.map +1 -0
- package/dist/interaction/overlay.d.ts +45 -0
- package/dist/interaction/overlay.d.ts.map +1 -0
- package/dist/interaction/overlay.js +57 -0
- package/dist/interaction/overlay.js.map +1 -0
- package/dist/interaction/placing.d.ts +86 -0
- package/dist/interaction/placing.d.ts.map +1 -0
- package/dist/interaction/placing.js +239 -0
- package/dist/interaction/placing.js.map +1 -0
- package/dist/interaction/pointer-drag.d.ts +23 -0
- package/dist/interaction/pointer-drag.d.ts.map +1 -0
- package/dist/interaction/pointer-drag.js +21 -0
- package/dist/interaction/pointer-drag.js.map +1 -0
- package/dist/interaction/press.d.ts +152 -0
- package/dist/interaction/press.d.ts.map +1 -0
- package/dist/interaction/press.js +229 -0
- package/dist/interaction/press.js.map +1 -0
- package/dist/interaction/roving-tabindex.d.ts +85 -0
- package/dist/interaction/roving-tabindex.d.ts.map +1 -0
- package/dist/interaction/roving-tabindex.js +142 -0
- package/dist/interaction/roving-tabindex.js.map +1 -0
- package/dist/interaction/selection.d.ts +72 -0
- package/dist/interaction/selection.d.ts.map +1 -0
- package/dist/interaction/selection.js +129 -0
- package/dist/interaction/selection.js.map +1 -0
- package/dist/interaction/targets.d.ts +15 -0
- package/dist/interaction/targets.d.ts.map +1 -0
- package/dist/interaction/targets.js +20 -0
- package/dist/interaction/targets.js.map +1 -0
- package/dist/interaction/tree-navigation.d.ts +111 -0
- package/dist/interaction/tree-navigation.d.ts.map +1 -0
- package/dist/interaction/tree-navigation.js +207 -0
- package/dist/interaction/tree-navigation.js.map +1 -0
- package/dist/interaction/typeahead.d.ts +73 -0
- package/dist/interaction/typeahead.d.ts.map +1 -0
- package/dist/interaction/typeahead.js +113 -0
- package/dist/interaction/typeahead.js.map +1 -0
- package/dist/internal.d.ts +16 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/{internal-C4gHodLc.mjs → internal.js} +7 -5
- package/dist/internal.js.map +1 -0
- package/dist/media/breakpoints.d.ts +37 -0
- package/dist/media/breakpoints.d.ts.map +1 -0
- package/dist/media/breakpoints.js +64 -0
- package/dist/media/breakpoints.js.map +1 -0
- package/dist/media/index.d.ts +3 -0
- package/dist/media/index.js +4 -0
- package/dist/media/mediaquery.d.ts +40 -0
- package/dist/media/mediaquery.d.ts.map +1 -0
- package/dist/media/mediaquery.js +42 -0
- package/dist/media/mediaquery.js.map +1 -0
- package/dist/media/platform.d.ts +30 -0
- package/dist/media/platform.d.ts.map +1 -0
- package/dist/media/platform.js +50 -0
- package/dist/media/platform.js.map +1 -0
- package/dist/motion/index.d.ts +5 -0
- package/dist/motion/index.js +5 -0
- package/dist/motion/motion.d.ts +16 -0
- package/dist/motion/motion.d.ts.map +1 -0
- package/dist/motion/motion.js +25 -0
- package/dist/motion/motion.js.map +1 -0
- package/dist/motion/presence.d.ts +37 -0
- package/dist/motion/presence.d.ts.map +1 -0
- package/dist/motion/presence.js +65 -0
- package/dist/motion/presence.js.map +1 -0
- package/dist/motion/spring.d.ts +50 -0
- package/dist/motion/spring.d.ts.map +1 -0
- package/dist/motion/spring.js +92 -0
- package/dist/motion/spring.js.map +1 -0
- package/dist/motion/tween.d.ts +44 -0
- package/dist/motion/tween.d.ts.map +1 -0
- package/dist/motion/tween.js +65 -0
- package/dist/motion/tween.js.map +1 -0
- package/dist/net/broadcast.d.ts +39 -0
- package/dist/net/broadcast.d.ts.map +1 -0
- package/dist/net/broadcast.js +73 -0
- package/dist/net/broadcast.js.map +1 -0
- package/dist/net/index.d.ts +5 -0
- package/dist/net/index.js +6 -0
- package/dist/net/online.d.ts +24 -0
- package/dist/net/online.d.ts.map +1 -0
- package/dist/net/online.js +26 -0
- package/dist/net/online.js.map +1 -0
- package/dist/net/sharedHost.d.ts +64 -0
- package/dist/net/sharedHost.d.ts.map +1 -0
- package/dist/net/sharedHost.js +124 -0
- package/dist/net/sharedHost.js.map +1 -0
- package/dist/net/sse.d.ts +115 -0
- package/dist/net/sse.d.ts.map +1 -0
- package/dist/net/sse.js +138 -0
- package/dist/net/sse.js.map +1 -0
- package/dist/net/websocket.d.ts +172 -0
- package/dist/net/websocket.d.ts.map +1 -0
- package/dist/net/websocket.js +199 -0
- package/dist/net/websocket.js.map +1 -0
- package/dist/observers/bounds.d.ts +24 -0
- package/dist/observers/bounds.d.ts.map +1 -0
- package/dist/observers/bounds.js +51 -0
- package/dist/observers/bounds.js.map +1 -0
- package/dist/observers/index.d.ts +4 -0
- package/dist/observers/index.js +5 -0
- package/dist/observers/intersection.d.ts +18 -0
- package/dist/observers/intersection.d.ts.map +1 -0
- package/dist/observers/intersection.js +33 -0
- package/dist/observers/intersection.js.map +1 -0
- package/dist/observers/mutation.d.ts +25 -0
- package/dist/observers/mutation.d.ts.map +1 -0
- package/dist/observers/mutation.js +53 -0
- package/dist/observers/mutation.js.map +1 -0
- package/dist/observers/resize.d.ts +18 -0
- package/dist/observers/resize.d.ts.map +1 -0
- package/dist/observers/resize.js +33 -0
- package/dist/observers/resize.js.map +1 -0
- package/dist/state/history.d.ts +115 -0
- package/dist/state/history.d.ts.map +1 -0
- package/dist/state/history.js +167 -0
- package/dist/state/history.js.map +1 -0
- package/dist/state/index.d.ts +6 -0
- package/dist/state/index.js +7 -0
- package/dist/state/locale.d.ts +27 -0
- package/dist/state/locale.d.ts.map +1 -0
- package/dist/state/locale.js +25 -0
- package/dist/state/locale.js.map +1 -0
- package/dist/state/pagination.d.ts +53 -0
- package/dist/state/pagination.d.ts.map +1 -0
- package/dist/state/pagination.js +72 -0
- package/dist/state/pagination.js.map +1 -0
- package/dist/state/range.d.ts +9 -0
- package/dist/state/range.d.ts.map +1 -0
- package/dist/state/range.js +18 -0
- package/dist/state/range.js.map +1 -0
- package/dist/state/selection.d.ts +47 -0
- package/dist/state/selection.d.ts.map +1 -0
- package/dist/state/selection.js +39 -0
- package/dist/state/selection.js.map +1 -0
- package/dist/state/virtual.d.ts +201 -0
- package/dist/state/virtual.d.ts.map +1 -0
- package/dist/state/{index.mjs → virtual.js} +10 -306
- package/dist/state/virtual.js.map +1 -0
- package/dist/time/debounce.d.ts +43 -0
- package/dist/time/debounce.d.ts.map +1 -0
- package/dist/time/debounce.js +65 -0
- package/dist/time/debounce.js.map +1 -0
- package/dist/time/index.d.ts +6 -0
- package/dist/time/index.js +7 -0
- package/dist/time/interval.d.ts +37 -0
- package/dist/time/interval.d.ts.map +1 -0
- package/dist/time/interval.js +52 -0
- package/dist/time/interval.js.map +1 -0
- package/dist/time/relative.d.ts +8 -0
- package/dist/time/relative.d.ts.map +1 -0
- package/dist/time/relative.js +27 -0
- package/dist/time/relative.js.map +1 -0
- package/dist/time/throttle.d.ts +38 -0
- package/dist/time/throttle.d.ts.map +1 -0
- package/dist/time/throttle.js +39 -0
- package/dist/time/throttle.js.map +1 -0
- package/dist/time/ticks.d.ts +21 -0
- package/dist/time/ticks.d.ts.map +1 -0
- package/dist/time/ticks.js +30 -0
- package/dist/time/ticks.js.map +1 -0
- package/dist/time/timer.d.ts +32 -0
- package/dist/time/timer.d.ts.map +1 -0
- package/dist/time/timer.js +50 -0
- package/dist/time/timer.js.map +1 -0
- package/package.json +31 -31
- package/dist/device/index.d.mts +0 -335
- package/dist/device/index.d.mts.map +0 -1
- package/dist/device/index.mjs +0 -493
- package/dist/device/index.mjs.map +0 -1
- package/dist/dom/index.d.mts +0 -714
- package/dist/dom/index.d.mts.map +0 -1
- package/dist/dom/index.mjs +0 -1840
- package/dist/dom/index.mjs.map +0 -1
- package/dist/editable-text-Bg7vil7h.d.mts +0 -307
- package/dist/editable-text-Bg7vil7h.d.mts.map +0 -1
- package/dist/events/index.d.mts +0 -168
- package/dist/events/index.d.mts.map +0 -1
- package/dist/events/index.mjs +0 -307
- package/dist/events/index.mjs.map +0 -1
- package/dist/follow-tab-stop-DM5EI4Ci.mjs +0 -856
- package/dist/follow-tab-stop-DM5EI4Ci.mjs.map +0 -1
- package/dist/index-Bomdwb7e.d.mts +0 -142
- package/dist/index-Bomdwb7e.d.mts.map +0 -1
- package/dist/index.d.mts +0 -12
- package/dist/index.mjs +0 -12
- package/dist/input-modality-XwQOFLip.mjs.map +0 -1
- package/dist/input-modality-l7InESYh.d.mts.map +0 -1
- package/dist/interaction/index.d.mts +0 -1193
- package/dist/interaction/index.d.mts.map +0 -1
- package/dist/interaction/index.mjs +0 -1992
- package/dist/interaction/index.mjs.map +0 -1
- package/dist/internal-C4gHodLc.mjs.map +0 -1
- package/dist/media/index.d.mts +0 -103
- package/dist/media/index.d.mts.map +0 -1
- package/dist/media/index.mjs +0 -146
- package/dist/media/index.mjs.map +0 -1
- package/dist/motion/index.d.mts +0 -2
- package/dist/motion/index.mjs +0 -1
- package/dist/motion-BmlJCjn6.mjs +0 -236
- package/dist/motion-BmlJCjn6.mjs.map +0 -1
- package/dist/net/index.d.mts +0 -338
- package/dist/net/index.d.mts.map +0 -1
- package/dist/net/index.mjs +0 -530
- package/dist/net/index.mjs.map +0 -1
- package/dist/observers/index.d.mts +0 -76
- package/dist/observers/index.d.mts.map +0 -1
- package/dist/observers/index.mjs +0 -155
- package/dist/observers/index.mjs.map +0 -1
- package/dist/rolldown-runtime-D8jQpDG7.mjs +0 -12
- package/dist/state/index.d.mts +0 -432
- package/dist/state/index.d.mts.map +0 -1
- package/dist/state/index.mjs.map +0 -1
- package/dist/time/index.d.mts +0 -167
- package/dist/time/index.d.mts.map +0 -1
- package/dist/time/index.mjs +0 -236
- package/dist/time/index.mjs.map +0 -1
package/dist/time/index.d.mts
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { Option, Schema } from "effect";
|
|
2
|
-
import * as Subscription from "foldkit/subscription";
|
|
3
|
-
import { Bundle } from "foldkit-bundle";
|
|
4
|
-
/**
|
|
5
|
-
* Debounced input as a bundle factory: `Changed` restarts a timer, and the
|
|
6
|
-
* latest value settles as an OutMessage the placement must handle with
|
|
7
|
-
* `onOut`. Each `Changed` bumps a generation carried by the `Settled` fact
|
|
8
|
-
* it schedules, so a superseded timer's fact emits nothing — the same guard
|
|
9
|
-
* as Presence's exit timeout. Generic over the value Schema, like History.
|
|
10
|
-
* The clock is Effect's, so tests drive it with TestClock.
|
|
11
|
-
*/
|
|
12
|
-
export declare const debounce: <const Name extends string, Value>(config: {
|
|
13
|
-
readonly name: Name;
|
|
14
|
-
readonly value: Schema.Codec<Value, unknown>;
|
|
15
|
-
}) => Bundle.Bundle<Name, {
|
|
16
|
-
readonly delayMs: number;
|
|
17
|
-
}, {
|
|
18
|
-
readonly latest: Value | null;
|
|
19
|
-
readonly generation: number;
|
|
20
|
-
}, {
|
|
21
|
-
readonly _tag: "Changed";
|
|
22
|
-
readonly value: Value;
|
|
23
|
-
} | {
|
|
24
|
-
readonly _tag: "Settled";
|
|
25
|
-
readonly value: Value;
|
|
26
|
-
readonly generation: number;
|
|
27
|
-
}, {
|
|
28
|
-
readonly _tag: "Debounced";
|
|
29
|
-
readonly value: Value;
|
|
30
|
-
}, never, never, void, {}, {}> & {
|
|
31
|
-
Message: import("foldkit/message").MessageUnion<{
|
|
32
|
-
readonly Changed: {
|
|
33
|
-
value: Schema.Codec<Value, unknown, never, never>;
|
|
34
|
-
};
|
|
35
|
-
readonly Settled: {
|
|
36
|
-
value: Schema.Codec<Value, unknown, never, never>;
|
|
37
|
-
generation: Schema.Number;
|
|
38
|
-
};
|
|
39
|
-
}>;
|
|
40
|
-
Debounced: Schema.TaggedStruct<"Debounced", {
|
|
41
|
-
readonly value: Schema.Codec<Value, unknown, never, never>;
|
|
42
|
-
}>;
|
|
43
|
-
};
|
|
44
|
-
export declare const IntervalModel: Schema.Struct<{
|
|
45
|
-
readonly running: Schema.Boolean;
|
|
46
|
-
readonly lastAt: Schema.NullOr<Schema.Number>;
|
|
47
|
-
}>;
|
|
48
|
-
export type IntervalModel = typeof IntervalModel.Type;
|
|
49
|
-
export declare const IntervalMessage: import("foldkit/message").MessageUnion<{
|
|
50
|
-
readonly Started: {};
|
|
51
|
-
readonly Stopped: {};
|
|
52
|
-
readonly Ticked: {
|
|
53
|
-
at: Schema.Number;
|
|
54
|
-
};
|
|
55
|
-
}>;
|
|
56
|
-
export type IntervalMessage = typeof IntervalMessage.Type;
|
|
57
|
-
/**
|
|
58
|
-
* A wall-clock interval as a bundle: the last tick time in the Model,
|
|
59
|
-
* advanced by a tick stream while running. Sibling of Timer (which counts
|
|
60
|
-
* ticks); this one records *when* they happened, so views can render clocks
|
|
61
|
-
* and elapsed times. The clock is Effect's, so tests drive it with TestClock.
|
|
62
|
-
* For a clock whose running or interval the parent's Model decides, use the
|
|
63
|
-
* `ticks` entry instead.
|
|
64
|
-
*/
|
|
65
|
-
export declare const Interval: Bundle.Bundle<"Interval", {
|
|
66
|
-
readonly intervalMs: number;
|
|
67
|
-
}, {
|
|
68
|
-
readonly running: boolean;
|
|
69
|
-
readonly lastAt: number | null;
|
|
70
|
-
}, {
|
|
71
|
-
readonly _tag: "Started";
|
|
72
|
-
} | {
|
|
73
|
-
readonly _tag: "Stopped";
|
|
74
|
-
} | {
|
|
75
|
-
readonly _tag: "Ticked";
|
|
76
|
-
readonly at: number;
|
|
77
|
-
}, never, never, never, void, {}, {}>;
|
|
78
|
-
/**
|
|
79
|
-
* Relative time as a pure function: picks the unit (seconds through years)
|
|
80
|
-
* and delegates the wording to `Intl.RelativeTimeFormat`, so locales come
|
|
81
|
-
* from the platform, not a phrase table. `from` is the earlier moment;
|
|
82
|
-
* swap the arguments for future phrasing ("in 3 days").
|
|
83
|
-
*/
|
|
84
|
-
export declare const formatRelativeTime: (from: Date, to: Date, locale?: string) => string;
|
|
85
|
-
export declare const ThrottleModel: Schema.Struct<{
|
|
86
|
-
readonly lastAt: Schema.NullOr<Schema.Number>;
|
|
87
|
-
}>;
|
|
88
|
-
export type ThrottleModel = typeof ThrottleModel.Type;
|
|
89
|
-
export declare const ThrottleMessage: import("foldkit/message").MessageUnion<{
|
|
90
|
-
readonly Attempted: {};
|
|
91
|
-
readonly Evaluated: {
|
|
92
|
-
now: Schema.Number;
|
|
93
|
-
};
|
|
94
|
-
}>;
|
|
95
|
-
export type ThrottleMessage = typeof ThrottleMessage.Type;
|
|
96
|
-
export declare const Throttled: Schema.TaggedStruct<"Throttled", {
|
|
97
|
-
readonly at: Schema.Number;
|
|
98
|
-
}>;
|
|
99
|
-
export type Throttled = typeof Throttled.Type;
|
|
100
|
-
/**
|
|
101
|
-
* Leading-edge throttle as a bundle: the first `Attempted` in an interval
|
|
102
|
-
* surfaces a `Throttled` OutMessage, the rest are dropped. `Attempted`
|
|
103
|
-
* reads the clock through a Command, so the check runs against Effect time
|
|
104
|
-
* and tests drive it with TestClock. Trailing-edge needs are Debounce's:
|
|
105
|
-
* pair the two rather than adding a second timer here.
|
|
106
|
-
*/
|
|
107
|
-
export declare const Throttle: Bundle.Bundle<"Throttle", {
|
|
108
|
-
readonly intervalMs: number;
|
|
109
|
-
}, {
|
|
110
|
-
readonly lastAt: number | null;
|
|
111
|
-
}, {
|
|
112
|
-
readonly _tag: "Attempted";
|
|
113
|
-
} | {
|
|
114
|
-
readonly _tag: "Evaluated";
|
|
115
|
-
readonly now: number;
|
|
116
|
-
}, {
|
|
117
|
-
readonly _tag: "Throttled";
|
|
118
|
-
readonly at: number;
|
|
119
|
-
}, never, never, void, {}, {}>;
|
|
120
|
-
declare const TickDependencies: {
|
|
121
|
-
intervalMs: Schema.Option<Schema.Number>;
|
|
122
|
-
};
|
|
123
|
-
type TickDependencies = {
|
|
124
|
-
readonly intervalMs: Option.Option<number>;
|
|
125
|
-
};
|
|
126
|
-
/**
|
|
127
|
-
* Ticks while `intervalMs` answers `Some`, each tick one interval after the
|
|
128
|
-
* last and the first one interval after starting. A changed interval applies
|
|
129
|
-
* from the next tick, with no restart; other Model changes do nothing.
|
|
130
|
-
*/
|
|
131
|
-
export declare const ticks: <Model, Message>(config: {
|
|
132
|
-
/** The time between ticks for this Model, in milliseconds; `None` stops the clock. */
|
|
133
|
-
readonly intervalMs: (model: Model) => Option.Option<number>;
|
|
134
|
-
/** The Message a tick sends, given its time on Effect's clock. */
|
|
135
|
-
readonly onTick: (at: number) => Message;
|
|
136
|
-
}) => Subscription.Subscription<Model, Message, TickDependencies>;
|
|
137
|
-
export declare const TimerModel: Schema.Struct<{
|
|
138
|
-
readonly count: Schema.Number;
|
|
139
|
-
readonly running: Schema.Boolean;
|
|
140
|
-
}>;
|
|
141
|
-
export type TimerModel = typeof TimerModel.Type;
|
|
142
|
-
export declare const TimerMessage: import("foldkit/message").MessageUnion<{
|
|
143
|
-
readonly Started: {};
|
|
144
|
-
readonly Stopped: {};
|
|
145
|
-
readonly Ticked: {};
|
|
146
|
-
}>;
|
|
147
|
-
export type TimerMessage = typeof TimerMessage.Type;
|
|
148
|
-
/**
|
|
149
|
-
* A timer as a bundle: a count in the Model, advanced by a tick stream while
|
|
150
|
-
* running. The clock is Effect's, so tests drive it with TestClock instead of
|
|
151
|
-
* waiting. For a clock whose running or interval the parent's Model decides,
|
|
152
|
-
* use the `ticks` entry instead.
|
|
153
|
-
*/
|
|
154
|
-
export declare const Timer: Bundle.Bundle<"Timer", {
|
|
155
|
-
readonly intervalMs: number;
|
|
156
|
-
}, {
|
|
157
|
-
readonly count: number;
|
|
158
|
-
readonly running: boolean;
|
|
159
|
-
}, {
|
|
160
|
-
readonly _tag: "Started";
|
|
161
|
-
} | {
|
|
162
|
-
readonly _tag: "Stopped";
|
|
163
|
-
} | {
|
|
164
|
-
readonly _tag: "Ticked";
|
|
165
|
-
}, never, never, never, void, {}, {}>;
|
|
166
|
-
export {};
|
|
167
|
-
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/time/debounce.ts","../../src/time/interval.ts","../../src/time/relative.ts","../../src/time/throttle.ts","../../src/time/ticks.ts","../../src/time/timer.ts"],"mappings":";;;;;;;;;;;qBAaa,iBAAkB,qBAAqB,OAAK;WAC9C,MAAM;WACN,OAAO,OAAO,MAAM;MAC9B,OAAA,OAAA;;;;;;;;;;;;;;;;;;MAQc,OAAK,OAAA,MAAA;;;MACL,OAAK,OAAA,MAAA;MAAgB,YAAU,OAAA;;;;;;;qBCnBjC,eAAa,OAAA;;;;YAId,uBAAuB,cAAc;qBAEpC,2CAAe;;;;IAGhB,IAAE,OAAA;;;YAEF,yBAAyB,gBAAgB;;;;;;;;;qBAUxC,UAAQ,OAAA;;;;;;;;;;;;;;;;;;;qBCrBR,qBAAkB,MAAU,MAAI,IAAM,MAAI;qBCD1C,eAAa,OAAA;;;YACd,uBAAuB,cAAc;qBAEpC,2CAAe;;;IAEb,KAAG,OAAA;;;YAEN,yBAAyB,gBAAgB;qBAExC,WAAS,OAAA;;;YACV,mBAAmB,UAAU;;;;;;;;qBAS5B,UAAQ,OAAA;;;;;;;;;;;;;cCff;EAAqB,YAAU,OAAA,OAAA,OAAA;;KAChC;WAA8B,YAAY,OAAO;;;;;;;qBAezC,QAAS,OAAO,SAAO;;WAEzB,aAAa,OAAO,UAAU,OAAO;;WAErC,SAAS,eAAe;MAC/B,aAAa,aAAa,OAAO,SAAS;qBCzBjC,YAAU,OAAA;;;;YACX,oBAAoB,WAAW;qBAE9B,wCAAY;;;;;YAKb,sBAAsB,aAAa;;;;;;;qBAQlC,OAAK,OAAA"}
|
package/dist/time/index.mjs
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import { Clock, Effect, Option, Schema, Stream } from "effect";
|
|
2
|
-
import { defineMessageUnion } from "foldkit/message";
|
|
3
|
-
import * as Subscription from "foldkit/subscription";
|
|
4
|
-
import { Bundle } from "foldkit-bundle";
|
|
5
|
-
// src/time/debounce.ts
|
|
6
|
-
/**
|
|
7
|
-
* Debounced input as a bundle factory: `Changed` restarts a timer, and the
|
|
8
|
-
* latest value settles as an OutMessage the placement must handle with
|
|
9
|
-
* `onOut`. Each `Changed` bumps a generation carried by the `Settled` fact
|
|
10
|
-
* it schedules, so a superseded timer's fact emits nothing — the same guard
|
|
11
|
-
* as Presence's exit timeout. Generic over the value Schema, like History.
|
|
12
|
-
* The clock is Effect's, so tests drive it with TestClock.
|
|
13
|
-
*/
|
|
14
|
-
const debounce = (config) => {
|
|
15
|
-
const Model = Schema.Struct({
|
|
16
|
-
latest: Schema.NullOr(config.value),
|
|
17
|
-
generation: Schema.Number
|
|
18
|
-
});
|
|
19
|
-
const Message = defineMessageUnion({
|
|
20
|
-
Changed: { value: config.value },
|
|
21
|
-
Settled: {
|
|
22
|
-
value: config.value,
|
|
23
|
-
generation: Schema.Number
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
const Debounced = Schema.TaggedStruct("Debounced", { value: config.value });
|
|
27
|
-
const bundle = Bundle.make(config.name, {
|
|
28
|
-
Model,
|
|
29
|
-
Message,
|
|
30
|
-
args: Schema.Struct({ delayMs: Schema.Number.pipe(Schema.check(Schema.isGreaterThan(0)), Schema.check(Schema.isFinite())) }),
|
|
31
|
-
init: () => ({ model: {
|
|
32
|
-
latest: null,
|
|
33
|
-
generation: 0
|
|
34
|
-
} }),
|
|
35
|
-
update: (model, message, args) => Message.match(message, {
|
|
36
|
-
Changed: ({ value }) => {
|
|
37
|
-
const generation = model.generation + 1;
|
|
38
|
-
return {
|
|
39
|
-
model: {
|
|
40
|
-
latest: value,
|
|
41
|
-
generation
|
|
42
|
-
},
|
|
43
|
-
commands: [{
|
|
44
|
-
name: `${config.name}.settle`,
|
|
45
|
-
args: { generation },
|
|
46
|
-
effect: Effect.as(Effect.sleep(args.delayMs), Message.Settled({
|
|
47
|
-
value,
|
|
48
|
-
generation
|
|
49
|
-
}))
|
|
50
|
-
}]
|
|
51
|
-
};
|
|
52
|
-
},
|
|
53
|
-
Settled: ({ generation, value }) => generation === model.generation ? {
|
|
54
|
-
model,
|
|
55
|
-
outMessage: Debounced.make({ value })
|
|
56
|
-
} : { model }
|
|
57
|
-
})
|
|
58
|
-
});
|
|
59
|
-
return Object.assign(bundle, {
|
|
60
|
-
Message,
|
|
61
|
-
Debounced
|
|
62
|
-
});
|
|
63
|
-
};
|
|
64
|
-
// src/time/ticks.ts
|
|
65
|
-
/**
|
|
66
|
-
* A clock the parent owns, as an entry: whether it ticks and how fast are
|
|
67
|
-
* functions of the parent's Model, so nothing keeps a second running flag or
|
|
68
|
-
* interval beside the state they derive from (a game's phase and score).
|
|
69
|
-
* Timer and Interval are built on it, for a clock that owns its own flag.
|
|
70
|
-
*/
|
|
71
|
-
const TickDependencies = { intervalMs: Schema.Option(Schema.Number) };
|
|
72
|
-
const checked = (intervalMs) => {
|
|
73
|
-
if (Option.isSome(intervalMs) && !(intervalMs.value > 0 && Number.isFinite(intervalMs.value))) throw new Error(`ticks: intervalMs must be positive and finite, got ${intervalMs.value}`);
|
|
74
|
-
return intervalMs;
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* Ticks while `intervalMs` answers `Some`, each tick one interval after the
|
|
78
|
-
* last and the first one interval after starting. A changed interval applies
|
|
79
|
-
* from the next tick, with no restart; other Model changes do nothing.
|
|
80
|
-
*/
|
|
81
|
-
const ticks = (config) => Subscription.make()((entry) => ({ ticks: entry(TickDependencies, {
|
|
82
|
-
modelToDependencies: (model) => ({ intervalMs: checked(config.intervalMs(model)) }),
|
|
83
|
-
keepAliveEquivalence: (a, b) => Option.isSome(a.intervalMs) === Option.isSome(b.intervalMs),
|
|
84
|
-
dependenciesToStream: ({ intervalMs }, readDependencies) => Option.match(intervalMs, {
|
|
85
|
-
onNone: () => Stream.empty,
|
|
86
|
-
onSome: (started) => Stream.fromEffectRepeat(Effect.suspend(() => Effect.sleep(Option.getOrElse(readDependencies().intervalMs, () => started))).pipe(Effect.andThen(Clock.currentTimeMillis), Effect.map(config.onTick)))
|
|
87
|
-
})
|
|
88
|
-
}) })).ticks;
|
|
89
|
-
// src/time/interval.ts
|
|
90
|
-
const IntervalModel = Schema.Struct({
|
|
91
|
-
running: Schema.Boolean,
|
|
92
|
-
lastAt: Schema.NullOr(Schema.Number)
|
|
93
|
-
});
|
|
94
|
-
const IntervalMessage = defineMessageUnion({
|
|
95
|
-
Started: {},
|
|
96
|
-
Stopped: {},
|
|
97
|
-
Ticked: { at: Schema.Number }
|
|
98
|
-
});
|
|
99
|
-
/**
|
|
100
|
-
* A wall-clock interval as a bundle: the last tick time in the Model,
|
|
101
|
-
* advanced by a tick stream while running. Sibling of Timer (which counts
|
|
102
|
-
* ticks); this one records *when* they happened, so views can render clocks
|
|
103
|
-
* and elapsed times. The clock is Effect's, so tests drive it with TestClock.
|
|
104
|
-
* For a clock whose running or interval the parent's Model decides, use the
|
|
105
|
-
* `ticks` entry instead.
|
|
106
|
-
*/
|
|
107
|
-
const Interval = Bundle.make("Interval", {
|
|
108
|
-
Model: IntervalModel,
|
|
109
|
-
Message: IntervalMessage,
|
|
110
|
-
args: Schema.Struct({ intervalMs: Schema.Number.pipe(Schema.check(Schema.isGreaterThan(0)), Schema.check(Schema.isFinite())) }),
|
|
111
|
-
init: () => ({ model: {
|
|
112
|
-
running: false,
|
|
113
|
-
lastAt: null
|
|
114
|
-
} }),
|
|
115
|
-
update: (model, message) => IntervalMessage.match(message, {
|
|
116
|
-
Started: () => model.running ? { model } : { model: {
|
|
117
|
-
...model,
|
|
118
|
-
running: true
|
|
119
|
-
} },
|
|
120
|
-
Stopped: () => model.running ? { model: {
|
|
121
|
-
...model,
|
|
122
|
-
running: false
|
|
123
|
-
} } : { model },
|
|
124
|
-
Ticked: ({ at }) => ({ model: {
|
|
125
|
-
...model,
|
|
126
|
-
lastAt: at
|
|
127
|
-
} })
|
|
128
|
-
}),
|
|
129
|
-
subscriptions: ({ intervalMs }) => ({ ticks: ticks({
|
|
130
|
-
intervalMs: (model) => model.running ? Option.some(intervalMs) : Option.none(),
|
|
131
|
-
onTick: (at) => IntervalMessage.Ticked({ at })
|
|
132
|
-
}) })
|
|
133
|
-
});
|
|
134
|
-
// src/time/relative.ts
|
|
135
|
-
/**
|
|
136
|
-
* Relative time as a pure function: picks the unit (seconds through years)
|
|
137
|
-
* and delegates the wording to `Intl.RelativeTimeFormat`, so locales come
|
|
138
|
-
* from the platform, not a phrase table. `from` is the earlier moment;
|
|
139
|
-
* swap the arguments for future phrasing ("in 3 days").
|
|
140
|
-
*/
|
|
141
|
-
const formatRelativeTime = (from, to, locale = "en") => {
|
|
142
|
-
const format = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
|
|
143
|
-
const seconds = Math.round((to.getTime() - from.getTime()) / 1e3);
|
|
144
|
-
const abs = Math.abs(seconds);
|
|
145
|
-
if (abs < 60) return format.format(-seconds, "second");
|
|
146
|
-
const minutes = Math.round(seconds / 60);
|
|
147
|
-
if (abs < 3600) return format.format(-minutes, "minute");
|
|
148
|
-
const hours = Math.round(seconds / 3600);
|
|
149
|
-
if (abs < 86400) return format.format(-hours, "hour");
|
|
150
|
-
const days = Math.round(seconds / 86400);
|
|
151
|
-
if (abs < 604800) return format.format(-days, "day");
|
|
152
|
-
const weeks = Math.round(seconds / 604800);
|
|
153
|
-
if (abs < 2592e3) return format.format(-weeks, "week");
|
|
154
|
-
const months = Math.round(seconds / 2592e3);
|
|
155
|
-
if (abs < 31536e3) return format.format(-months, "month");
|
|
156
|
-
return format.format(-Math.round(seconds / 31536e3), "year");
|
|
157
|
-
};
|
|
158
|
-
// src/time/throttle.ts
|
|
159
|
-
const ThrottleModel = Schema.Struct({ lastAt: Schema.NullOr(Schema.Number) });
|
|
160
|
-
const ThrottleMessage = defineMessageUnion({
|
|
161
|
-
Attempted: {},
|
|
162
|
-
Evaluated: { now: Schema.Number }
|
|
163
|
-
});
|
|
164
|
-
const Throttled = Schema.TaggedStruct("Throttled", { at: Schema.Number });
|
|
165
|
-
/**
|
|
166
|
-
* Leading-edge throttle as a bundle: the first `Attempted` in an interval
|
|
167
|
-
* surfaces a `Throttled` OutMessage, the rest are dropped. `Attempted`
|
|
168
|
-
* reads the clock through a Command, so the check runs against Effect time
|
|
169
|
-
* and tests drive it with TestClock. Trailing-edge needs are Debounce's:
|
|
170
|
-
* pair the two rather than adding a second timer here.
|
|
171
|
-
*/
|
|
172
|
-
const Throttle = Bundle.make("Throttle", {
|
|
173
|
-
Model: ThrottleModel,
|
|
174
|
-
Message: ThrottleMessage,
|
|
175
|
-
args: Schema.Struct({ intervalMs: Schema.Number.pipe(Schema.check(Schema.isGreaterThan(0)), Schema.check(Schema.isFinite())) }),
|
|
176
|
-
init: () => ({ model: { lastAt: null } }),
|
|
177
|
-
update: (model, message, args) => ThrottleMessage.match(message, {
|
|
178
|
-
Attempted: () => ({
|
|
179
|
-
model,
|
|
180
|
-
commands: [{
|
|
181
|
-
name: "Throttle.evaluate",
|
|
182
|
-
effect: Effect.map(Clock.currentTimeMillis, (now) => ThrottleMessage.Evaluated({ now }))
|
|
183
|
-
}]
|
|
184
|
-
}),
|
|
185
|
-
Evaluated: ({ now }) => model.lastAt === null || now - model.lastAt >= args.intervalMs ? {
|
|
186
|
-
model: { lastAt: now },
|
|
187
|
-
outMessage: Throttled.make({ at: now })
|
|
188
|
-
} : { model }
|
|
189
|
-
})
|
|
190
|
-
});
|
|
191
|
-
// src/time/timer.ts
|
|
192
|
-
const TimerModel = Schema.Struct({
|
|
193
|
-
count: Schema.Number,
|
|
194
|
-
running: Schema.Boolean
|
|
195
|
-
});
|
|
196
|
-
const TimerMessage = defineMessageUnion({
|
|
197
|
-
Started: {},
|
|
198
|
-
Stopped: {},
|
|
199
|
-
Ticked: {}
|
|
200
|
-
});
|
|
201
|
-
/**
|
|
202
|
-
* A timer as a bundle: a count in the Model, advanced by a tick stream while
|
|
203
|
-
* running. The clock is Effect's, so tests drive it with TestClock instead of
|
|
204
|
-
* waiting. For a clock whose running or interval the parent's Model decides,
|
|
205
|
-
* use the `ticks` entry instead.
|
|
206
|
-
*/
|
|
207
|
-
const Timer = Bundle.make("Timer", {
|
|
208
|
-
Model: TimerModel,
|
|
209
|
-
Message: TimerMessage,
|
|
210
|
-
args: Schema.Struct({ intervalMs: Schema.Number.pipe(Schema.check(Schema.isGreaterThan(0)), Schema.check(Schema.isFinite())) }),
|
|
211
|
-
init: () => ({ model: {
|
|
212
|
-
count: 0,
|
|
213
|
-
running: false
|
|
214
|
-
} }),
|
|
215
|
-
update: (model, message) => TimerMessage.match(message, {
|
|
216
|
-
Started: () => model.running ? { model } : { model: {
|
|
217
|
-
...model,
|
|
218
|
-
running: true
|
|
219
|
-
} },
|
|
220
|
-
Stopped: () => model.running ? { model: {
|
|
221
|
-
...model,
|
|
222
|
-
running: false
|
|
223
|
-
} } : { model },
|
|
224
|
-
Ticked: () => ({ model: {
|
|
225
|
-
...model,
|
|
226
|
-
count: model.count + 1
|
|
227
|
-
} })
|
|
228
|
-
}),
|
|
229
|
-
subscriptions: ({ intervalMs }) => ({ ticks: ticks({
|
|
230
|
-
intervalMs: (model) => model.running ? Option.some(intervalMs) : Option.none(),
|
|
231
|
-
onTick: () => TimerMessage.Ticked()
|
|
232
|
-
}) })
|
|
233
|
-
});
|
|
234
|
-
export { Interval, IntervalMessage, IntervalModel, Throttle, ThrottleMessage, ThrottleModel, Throttled, Timer, TimerMessage, TimerModel, debounce, formatRelativeTime, ticks };
|
|
235
|
-
|
|
236
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/time/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/time/debounce.ts","../../src/time/ticks.ts","../../src/time/interval.ts","../../src/time/relative.ts","../../src/time/throttle.ts","../../src/time/timer.ts"],"sourcesContent":["import { Effect, Schema } from 'effect'\nimport { defineMessageUnion } from 'foldkit/message'\nimport type * as Update from 'foldkit/update'\nimport { Bundle } from 'foldkit-bundle'\n\n/**\n * Debounced input as a bundle factory: `Changed` restarts a timer, and the\n * latest value settles as an OutMessage the placement must handle with\n * `onOut`. Each `Changed` bumps a generation carried by the `Settled` fact\n * it schedules, so a superseded timer's fact emits nothing — the same guard\n * as Presence's exit timeout. Generic over the value Schema, like History.\n * The clock is Effect's, so tests drive it with TestClock.\n */\nexport const debounce = <const Name extends string, Value>(config: {\n readonly name: Name\n readonly value: Schema.Codec<Value, unknown>\n}) => {\n const Model = Schema.Struct({\n latest: Schema.NullOr(config.value),\n generation: Schema.Number,\n })\n type Model = typeof Model.Type\n\n const Message = defineMessageUnion({\n Changed: { value: config.value },\n Settled: { value: config.value, generation: Schema.Number },\n })\n type Message = typeof Message.Type\n\n const Debounced = Schema.TaggedStruct('Debounced', { value: config.value })\n type Debounced = typeof Debounced.Type\n\n const bundle = Bundle.make(config.name, {\n Model,\n Message,\n args: Schema.Struct({\n delayMs: Schema.Number.pipe(\n Schema.check(Schema.isGreaterThan(0)),\n Schema.check(Schema.isFinite()),\n ),\n }),\n init: () => ({ model: { latest: null, generation: 0 } }),\n update: (model, message, args) =>\n Message.match<Update.ReturnWithOutMessage<Model, Message, Debounced>>(message, {\n Changed: ({ value }) => {\n const generation = model.generation + 1\n return {\n model: { latest: value, generation },\n commands: [\n {\n name: `${config.name}.settle`,\n args: { generation },\n effect: Effect.as(\n Effect.sleep(args.delayMs),\n Message.Settled({ value, generation }),\n ),\n },\n ],\n }\n },\n // A superseded timer's fact arrives with an old generation: no\n // OutMessage, so the placement never sees it.\n Settled: ({ generation, value }) =>\n generation === model.generation\n ? { model, outMessage: Debounced.make({ value }) }\n : { model },\n }),\n })\n\n return Object.assign(bundle, { Message, Debounced })\n}\n","/**\n * A clock the parent owns, as an entry: whether it ticks and how fast are\n * functions of the parent's Model, so nothing keeps a second running flag or\n * interval beside the state they derive from (a game's phase and score).\n * Timer and Interval are built on it, for a clock that owns its own flag.\n */\nimport { Clock, Effect, Option, Schema, Stream } from 'effect'\nimport * as Subscription from 'foldkit/subscription'\n\nconst TickDependencies = { intervalMs: Schema.Option(Schema.Number) }\ntype TickDependencies = { readonly intervalMs: Option.Option<number> }\n\nconst checked = (intervalMs: Option.Option<number>): Option.Option<number> => {\n // A zero, negative or non-finite interval would spin or never tick; the\n // runtime crashes on a defect here, which names the mistake where it is made.\n if (Option.isSome(intervalMs) && !(intervalMs.value > 0 && Number.isFinite(intervalMs.value)))\n throw new Error(`ticks: intervalMs must be positive and finite, got ${intervalMs.value}`)\n return intervalMs\n}\n\n/**\n * Ticks while `intervalMs` answers `Some`, each tick one interval after the\n * last and the first one interval after starting. A changed interval applies\n * from the next tick, with no restart; other Model changes do nothing.\n */\nexport const ticks = <Model, Message>(config: {\n /** The time between ticks for this Model, in milliseconds; `None` stops the clock. */\n readonly intervalMs: (model: Model) => Option.Option<number>\n /** The Message a tick sends, given its time on Effect's clock. */\n readonly onTick: (at: number) => Message\n}): Subscription.Subscription<Model, Message, TickDependencies> =>\n Subscription.make<Model, Message>()(entry => ({\n ticks: entry(TickDependencies, {\n modelToDependencies: model => ({ intervalMs: checked(config.intervalMs(model)) }),\n // Stopping and starting restart the stream; a new interval does not, so\n // a clock that speeds up keeps its phase instead of ticking at once.\n keepAliveEquivalence: (a, b) => Option.isSome(a.intervalMs) === Option.isSome(b.intervalMs),\n dependenciesToStream: ({ intervalMs }, readDependencies) =>\n Option.match(intervalMs, {\n onNone: () => Stream.empty,\n onSome: started =>\n Stream.fromEffectRepeat(\n Effect.suspend(() =>\n Effect.sleep(Option.getOrElse(readDependencies().intervalMs, () => started)),\n ).pipe(Effect.andThen(Clock.currentTimeMillis), Effect.map(config.onTick)),\n ),\n }),\n }),\n })).ticks\n","import { Option, Schema } from 'effect'\nimport { defineMessageUnion } from 'foldkit/message'\nimport type * as Update from 'foldkit/update'\nimport { Bundle } from 'foldkit-bundle'\nimport { ticks } from './ticks.js'\n\nexport const IntervalModel = Schema.Struct({\n running: Schema.Boolean,\n lastAt: Schema.NullOr(Schema.Number),\n})\nexport type IntervalModel = typeof IntervalModel.Type\n\nexport const IntervalMessage = defineMessageUnion({\n Started: {},\n Stopped: {},\n Ticked: { at: Schema.Number },\n})\nexport type IntervalMessage = typeof IntervalMessage.Type\n\n/**\n * A wall-clock interval as a bundle: the last tick time in the Model,\n * advanced by a tick stream while running. Sibling of Timer (which counts\n * ticks); this one records *when* they happened, so views can render clocks\n * and elapsed times. The clock is Effect's, so tests drive it with TestClock.\n * For a clock whose running or interval the parent's Model decides, use the\n * `ticks` entry instead.\n */\nexport const Interval = Bundle.make('Interval', {\n Model: IntervalModel,\n Message: IntervalMessage,\n args: Schema.Struct({\n intervalMs: Schema.Number.pipe(\n Schema.check(Schema.isGreaterThan(0)),\n Schema.check(Schema.isFinite()),\n ),\n }),\n init: () => ({ model: { running: false, lastAt: null } }),\n update: (model, message) =>\n IntervalMessage.match<Update.ReturnWithOutMessage<IntervalModel, IntervalMessage, never>>(\n message,\n {\n Started: () => (model.running ? { model } : { model: { ...model, running: true } }),\n Stopped: () => (model.running ? { model: { ...model, running: false } } : { model }),\n Ticked: ({ at }) => ({ model: { ...model, lastAt: at } }),\n },\n ),\n subscriptions: ({ intervalMs }) => ({\n ticks: ticks<IntervalModel, IntervalMessage>({\n intervalMs: model => (model.running ? Option.some(intervalMs) : Option.none()),\n onTick: at => IntervalMessage.Ticked({ at }),\n }),\n }),\n})\n","/**\n * Relative time as a pure function: picks the unit (seconds through years)\n * and delegates the wording to `Intl.RelativeTimeFormat`, so locales come\n * from the platform, not a phrase table. `from` is the earlier moment;\n * swap the arguments for future phrasing (\"in 3 days\").\n */\nexport const formatRelativeTime = (from: Date, to: Date, locale = 'en'): string => {\n const format = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' })\n const seconds = Math.round((to.getTime() - from.getTime()) / 1000)\n const abs = Math.abs(seconds)\n if (abs < 60) return format.format(-seconds, 'second')\n const minutes = Math.round(seconds / 60)\n if (abs < 60 * 60) return format.format(-minutes, 'minute')\n const hours = Math.round(seconds / (60 * 60))\n if (abs < 24 * 60 * 60) return format.format(-hours, 'hour')\n const days = Math.round(seconds / (24 * 60 * 60))\n if (abs < 7 * 24 * 60 * 60) return format.format(-days, 'day')\n const weeks = Math.round(seconds / (7 * 24 * 60 * 60))\n if (abs < 30 * 24 * 60 * 60) return format.format(-weeks, 'week')\n const months = Math.round(seconds / (30 * 24 * 60 * 60))\n if (abs < 365 * 24 * 60 * 60) return format.format(-months, 'month')\n return format.format(-Math.round(seconds / (365 * 24 * 60 * 60)), 'year')\n}\n","import { Clock, Effect, Schema } from 'effect'\nimport { defineMessageUnion } from 'foldkit/message'\nimport type * as Update from 'foldkit/update'\nimport { Bundle } from 'foldkit-bundle'\n\nexport const ThrottleModel = Schema.Struct({ lastAt: Schema.NullOr(Schema.Number) })\nexport type ThrottleModel = typeof ThrottleModel.Type\n\nexport const ThrottleMessage = defineMessageUnion({\n Attempted: {},\n Evaluated: { now: Schema.Number },\n})\nexport type ThrottleMessage = typeof ThrottleMessage.Type\n\nexport const Throttled = Schema.TaggedStruct('Throttled', { at: Schema.Number })\nexport type Throttled = typeof Throttled.Type\n\n/**\n * Leading-edge throttle as a bundle: the first `Attempted` in an interval\n * surfaces a `Throttled` OutMessage, the rest are dropped. `Attempted`\n * reads the clock through a Command, so the check runs against Effect time\n * and tests drive it with TestClock. Trailing-edge needs are Debounce's:\n * pair the two rather than adding a second timer here.\n */\nexport const Throttle = Bundle.make('Throttle', {\n Model: ThrottleModel,\n Message: ThrottleMessage,\n args: Schema.Struct({\n intervalMs: Schema.Number.pipe(\n Schema.check(Schema.isGreaterThan(0)),\n Schema.check(Schema.isFinite()),\n ),\n }),\n init: () => ({ model: { lastAt: null } }),\n update: (model, message, args) =>\n ThrottleMessage.match<Update.ReturnWithOutMessage<ThrottleModel, ThrottleMessage, Throttled>>(\n message,\n {\n Attempted: () => ({\n model,\n commands: [\n {\n name: 'Throttle.evaluate',\n effect: Effect.map(Clock.currentTimeMillis, now =>\n ThrottleMessage.Evaluated({ now }),\n ),\n },\n ],\n }),\n // First attempt ever, or the interval has passed: fire and stamp.\n Evaluated: ({ now }) =>\n model.lastAt === null || now - model.lastAt >= args.intervalMs\n ? { model: { lastAt: now }, outMessage: Throttled.make({ at: now }) }\n : { model },\n },\n ),\n})\n","import { Option, Schema } from 'effect'\nimport { defineMessageUnion } from 'foldkit/message'\nimport { Bundle } from 'foldkit-bundle'\nimport { ticks } from './ticks.js'\n\nexport const TimerModel = Schema.Struct({ count: Schema.Number, running: Schema.Boolean })\nexport type TimerModel = typeof TimerModel.Type\n\nexport const TimerMessage = defineMessageUnion({\n Started: {},\n Stopped: {},\n Ticked: {},\n})\nexport type TimerMessage = typeof TimerMessage.Type\n\n/**\n * A timer as a bundle: a count in the Model, advanced by a tick stream while\n * running. The clock is Effect's, so tests drive it with TestClock instead of\n * waiting. For a clock whose running or interval the parent's Model decides,\n * use the `ticks` entry instead.\n */\nexport const Timer = Bundle.make('Timer', {\n Model: TimerModel,\n Message: TimerMessage,\n args: Schema.Struct({\n intervalMs: Schema.Number.pipe(\n Schema.check(Schema.isGreaterThan(0)),\n Schema.check(Schema.isFinite()),\n ),\n }),\n init: () => ({ model: { count: 0, running: false } }),\n update: (model, message) =>\n TimerMessage.match(message, {\n Started: () => (model.running ? { model } : { model: { ...model, running: true } }),\n Stopped: () => (model.running ? { model: { ...model, running: false } } : { model }),\n Ticked: () => ({ model: { ...model, count: model.count + 1 } }),\n }),\n subscriptions: ({ intervalMs }) => ({\n ticks: ticks<TimerModel, TimerMessage>({\n intervalMs: model => (model.running ? Option.some(intervalMs) : Option.none()),\n onTick: () => TimerMessage.Ticked(),\n }),\n }),\n})\n"],"mappings":"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"}
|