@hyperfrontend/time-utils 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
+
5
+ ## 0.0.1 (2026-02-15)
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrew Redican
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,260 @@
1
+ # @hyperfrontend/time-utils
2
+
3
+ <p align="center">
4
+ <a href="https://github.com/AndrewRedican/hyperfrontend/actions/workflows/ci-lib-time-utils.yml">
5
+ <img src="https://img.shields.io/github/actions/workflow/status/AndrewRedican/hyperfrontend/ci-lib-time-utils.yml?style=flat-square&logo=github&label=build" alt="Build">
6
+ </a>
7
+ <a href="https://codecov.io/gh/AndrewRedican/hyperfrontend/flags?flags%5B0%5D=time-utils">
8
+ <img src="https://codecov.io/gh/AndrewRedican/hyperfrontend/graph/badge.svg?flag=time-utils" alt="Coverage">
9
+ </a>
10
+ <a href="https://www.npmjs.com/package/@hyperfrontend/time-utils">
11
+ <img src="https://img.shields.io/npm/v/@hyperfrontend/time-utils?style=flat-square" alt="npm version">
12
+ </a>
13
+ </p>
14
+ <p align="center">
15
+ <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
16
+ <a href="#contributors">
17
+ <img src="https://img.shields.io/github/all-contributors/AndrewRedican/hyperfrontend?color=ee8449&style=flat-square" alt="All Contributors">
18
+ </a>
19
+ <!-- ALL-CONTRIBUTORS-BADGE:END -->
20
+ <a href="https://github.com/AndrewRedican/hyperfrontend/blob/main/LICENSE.md">
21
+ <img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License">
22
+ </a>
23
+ <a href="https://www.npmjs.com/package/@hyperfrontend/time-utils">
24
+ <img src="https://img.shields.io/npm/dm/@hyperfrontend/time-utils?style=flat-square" alt="npm downloads">
25
+ </a>
26
+ <a href="https://github.com/AndrewRedican/hyperfrontend">
27
+ <img src="https://img.shields.io/github/stars/AndrewRedican/hyperfrontend?style=flat-square" alt="GitHub stars">
28
+ </a>
29
+ <a href="https://bundlephobia.com/package/@hyperfrontend/time-utils">
30
+ <img src="https://img.shields.io/bundlephobia/minzip/@hyperfrontend/time-utils?style=flat-square" alt="Bundle Size">
31
+ </a>
32
+ <img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen?style=flat-square&logo=node.js" alt="Node Version">
33
+ <img src="https://img.shields.io/badge/tree%20shakeable-%E2%9C%93-success?style=flat-square" alt="Tree Shakeable">
34
+ </p>
35
+
36
+ Functional time utilities for async operations, intervals, and time normalization.
37
+
38
+ ## What is @hyperfrontend/time-utils?
39
+
40
+ `@hyperfrontend/time-utils` provides composable, testable utilities for working with time-based operations in JavaScript. The library focuses on enhancing the control and flexibility of standard timing APIs (`setTimeout`, `setInterval`) while adding specialized utilities for async workflows and time window calculations.
41
+
42
+ Unlike the native timing APIs which offer limited lifecycle control, this library wraps them in functional interfaces that support pausing, resuming, resetting, and subscription management. All utilities return immutable objects with frozen APIs, preventing accidental mutation while maintaining predictable behavior.
43
+
44
+ ### Key Features
45
+
46
+ - **Controllable timers** - Pause, resume, and reset `setTimeout` operations with tracked remaining time
47
+ - **Multi-subscriber clocks** - Observable interval loops supporting multiple callbacks with unified start/stop control
48
+ - **Promise-based delays** - Async/await compatible `sleep()` utility for sequential code flows
49
+ - **Time window normalization** - Bucket timestamps into fixed intervals (e.g., 5-minute windows for aggregation)
50
+ - **Functional cleanup** - All repeating operations return cleanup functions for straightforward teardown
51
+ - **Immutable APIs** - All returned objects are frozen, preventing accidental state modifications
52
+ - **Zero dependencies** - Self-contained timing utilities with no external dependencies
53
+ - **TypeScript native** - Full type definitions with comprehensive JSDoc documentation
54
+
55
+ ### Architecture Highlights
56
+
57
+ All timing abstractions maintain internal state privately while exposing frozen API objects, following the revealing module pattern. Timer implementations track elapsed time explicitly to enable pause/resume functionality, while clock implementations manage subscriber arrays with simple filter-based unsubscription. The library avoids classes and prototypes in favor of factory functions that return object literals.
58
+
59
+ ## Why Use @hyperfrontend/time-utils?
60
+
61
+ ### 1. Pause/Resume Capabilities Native APIs Lack
62
+
63
+ JavaScript's `setTimeout` and `setInterval` cannot be paused—once started, they either complete or get cancelled. This creates problems for features like user-initiated pauses in games, animations during background tabs, or request throttling. `createTimer()` tracks elapsed time internally, enabling pause/resume without restarting from the beginning or losing progress.
64
+
65
+ **Example:** A countdown timer in a game needs to pause when the user switches tabs. With `setTimeout`, you'd need to calculate remaining time manually and create a new timeout. With `createTimer`, just call `timer.pause()`.
66
+
67
+ ### 2. Multi-Subscriber Interval Management
68
+
69
+ Native `setInterval` requires creating separate intervals for each callback that needs to run at the same frequency, leading to drift and coordination issues. `createClock()` lets multiple callbacks subscribe to a single interval loop, ensuring they all fire synchronously at exact intervals. Perfect for real-time dashboards, clocks, or animation frames.
70
+
71
+ **Example:** A dashboard with 5 widgets updating every second would require 5 separate `setInterval` calls, potentially drifting apart. A single clock can notify all widgets simultaneously from one interval.
72
+
73
+ ### 3. Async/Await Integration for Sequential Delays
74
+
75
+ Writing readable sequential code with delays requires nested callbacks or promise chains with `setTimeout`. `sleep()` provides a clean async/await compatible delay utility that works naturally with modern async functions. This is essential for testing, retry logic, rate limiting, and animation sequences.
76
+
77
+ **Example:** Retry logic becomes `await sleep(1000); retry()` instead of `setTimeout(() => retry(), 1000)`, maintaining the sequential flow of async functions.
78
+
79
+ ### 4. Time Window Normalization for Aggregation
80
+
81
+ Real-time data aggregation often requires grouping events into time buckets (5-minute windows, hourly intervals, etc.). `normalizeToBaseTimeWindow()` rounds timestamps down to the nearest window boundary, simplifying time-series data grouping for metrics, logs, and analytics.
82
+
83
+ **Example:** Events at 10:03, 10:07, and 10:12 with a 5-minute window all normalize to 10:00, 10:05, and 10:10 respectively, creating clean bucket keys for aggregation.
84
+
85
+ ### 5. Immutable, Testable Timing Abstractions
86
+
87
+ Testing code with `setTimeout` and `setInterval` typically requires jest timers or sinon fakes, adding complexity. These utilities use standard timing APIs internally but expose functional interfaces that are easier to mock and test. The frozen return objects prevent accidental mutations that could cause subtle timing bugs.
88
+
89
+ ## Installation
90
+
91
+ ```bash
92
+ npm install @hyperfrontend/time-utils
93
+ ```
94
+
95
+ ## Quick Start
96
+
97
+ **Pauseable timer:**
98
+
99
+ ```typescript
100
+ import { createTimer } from '@hyperfrontend/time-utils'
101
+
102
+ const timer = createTimer(() => console.log('Done!'), 5000)
103
+
104
+ timer.resume() // Start the 5-second countdown
105
+
106
+ // After 3 seconds, user pauses
107
+ timer.pause() // Pauses with 2 seconds remaining
108
+
109
+ // Later, resume from where we left off
110
+ timer.resume() // Continues with remaining 2 seconds
111
+
112
+ // Or reset with a new duration
113
+ timer.reset(10000) // Restart with 10 seconds
114
+ ```
115
+
116
+ **Multi-subscriber clock:**
117
+
118
+ ```typescript
119
+ import { createClock } from '@hyperfrontend/time-utils'
120
+
121
+ // Create a clock that ticks every second
122
+ const clock = createClock(1000)
123
+
124
+ // Multiple subscribers can listen
125
+ clock.subscribe((time) => console.log('Widget 1:', time))
126
+ clock.subscribe((time) => console.log('Widget 2:', time))
127
+
128
+ clock.start() // Both widgets update every second
129
+
130
+ // Later, stop all updates
131
+ clock.stop()
132
+
133
+ // Unsubscribe specific callbacks
134
+ clock.unsubscribe(callback)
135
+ ```
136
+
137
+ **Async delays:**
138
+
139
+ ```typescript
140
+ import { sleep } from '@hyperfrontend/time-utils'
141
+
142
+ async function retryWithDelay(fn, attempts = 3) {
143
+ for (let i = 0; i < attempts; i++) {
144
+ try {
145
+ return await fn()
146
+ } catch (error) {
147
+ if (i < attempts - 1) {
148
+ await sleep(1000 * Math.pow(2, i)) // Exponential backoff
149
+ }
150
+ }
151
+ }
152
+ throw new Error('All retries failed')
153
+ }
154
+ ```
155
+
156
+ **Time window normalization:**
157
+
158
+ ```typescript
159
+ import { normalizeToBaseTimeWindow } from '@hyperfrontend/time-utils'
160
+
161
+ // Group metrics into 5-minute windows
162
+ const events = [new Date('2024-01-17T10:03:45Z'), new Date('2024-01-17T10:07:22Z'), new Date('2024-01-17T10:12:03Z')]
163
+
164
+ const buckets = new Map()
165
+ events.forEach((timestamp) => {
166
+ const bucket = normalizeToBaseTimeWindow(timestamp, 5)
167
+ const key = bucket.toISOString()
168
+ buckets.set(key, (buckets.get(key) || 0) + 1)
169
+ })
170
+
171
+ // Results:
172
+ // "2024-01-17T10:00:00Z" → 2 events
173
+ // "2024-01-17T10:10:00Z" → 1 event
174
+ ```
175
+
176
+ **Simple interval with cleanup:**
177
+
178
+ ```typescript
179
+ import { setIntervalCallback } from '@hyperfrontend/time-utils'
180
+
181
+ // Returns a cleanup function
182
+ const cleanup = setIntervalCallback(() => {
183
+ console.log('Polling...')
184
+ }, 5000)
185
+
186
+ // Later, stop polling
187
+ cleanup()
188
+ ```
189
+
190
+ ## API Overview
191
+
192
+ **Timing Abstractions:**
193
+
194
+ - **`createTimer(callback, delay)`** - Creates a pauseable, resumable timer (enhanced setTimeout)
195
+ - `timer.pause()` - Pauses timer, preserving remaining time
196
+ - `timer.resume()` - Resumes timer from remaining time
197
+ - `timer.reset(newDelay?)` - Restarts timer with optional new duration
198
+
199
+ - **`createClock(interval?)`** - Creates a multi-subscriber interval loop (default: 1000ms)
200
+ - `clock.start()` - Begins interval loop
201
+ - `clock.stop()` - Stops interval loop
202
+ - `clock.subscribe(callback)` - Adds callback to subscriber list
203
+ - `clock.unsubscribe(callback)` - Removes callback from subscribers
204
+ - `clock.interval` - Read-only interval duration
205
+
206
+ **Utility Functions:**
207
+
208
+ - **`sleep(milliseconds)`** - Returns promise that resolves after delay (async/await compatible)
209
+ - **`setIntervalCallback(callback, interval)`** - Simple setInterval wrapper returning cleanup function
210
+ - **`normalizeToBaseTimeWindow(time, baseTimeWindow)`** - Rounds timestamp down to nearest time window boundary (window in minutes)
211
+
212
+ ## Compatibility
213
+
214
+ | Platform | Support |
215
+ | ----------------------------- | :-----: |
216
+ | Browser | ✅ |
217
+ | Node.js | ✅ |
218
+ | Web Workers | ✅ |
219
+ | Deno, Bun, Cloudflare Workers | ✅ |
220
+
221
+ ### Output Formats
222
+
223
+ | Format | File | Tree-Shakeable |
224
+ | ------ | -------------------------- | :------------: |
225
+ | ESM | `index.esm.js` | ✅ |
226
+ | CJS | `index.cjs.js` | ❌ |
227
+ | IIFE | `bundle/index.iife.min.js` | ❌ |
228
+ | UMD | `bundle/index.umd.min.js` | ❌ |
229
+
230
+ **Bundle size:** 1 KB (minified, self-contained)
231
+
232
+ ### CDN Usage
233
+
234
+ ```html
235
+ <!-- unpkg -->
236
+ <script src="https://unpkg.com/@hyperfrontend/time-utils"></script>
237
+
238
+ <!-- jsDelivr -->
239
+ <script src="https://cdn.jsdelivr.net/npm/@hyperfrontend/time-utils"></script>
240
+
241
+ <script>
242
+ const { createResumableInterval, sleep } = HyperfrontendTimeUtils
243
+ </script>
244
+ ```
245
+
246
+ **Global variable:** `HyperfrontendTimeUtils`
247
+
248
+ ### Dependencies
249
+
250
+ None — zero external dependencies.
251
+
252
+ ## Part of hyperfrontend
253
+
254
+ This library is part of the [hyperfrontend](https://github.com/AndrewRedican/hyperfrontend) monorepo. [Full documentation](https://hyperfrontend.dev).
255
+
256
+ - Used by [@hyperfrontend/cryptography](https://github.com/AndrewRedican/hyperfrontend/tree/main/libs/cryptography) for time-window password generation
257
+
258
+ ## License
259
+
260
+ MIT
package/SECURITY.md ADDED
@@ -0,0 +1,82 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ We take the security of hyperfrontend seriously. If you discover a security vulnerability, please help us protect our users by following responsible disclosure practices.
6
+
7
+ ### How to Report
8
+
9
+ **Please DO NOT report security vulnerabilities through public GitHub issues.**
10
+
11
+ Instead, please report security vulnerabilities directly via email to:
12
+
13
+ **<andrew.redican.mejia@gmail.com>**
14
+
15
+ ### What to Include
16
+
17
+ To help us understand and resolve the issue quickly, please include the following information in your report:
18
+
19
+ - **Description**: A clear description of the vulnerability
20
+ - **Impact**: The potential impact and severity of the issue
21
+ - **Reproduction Steps**: Detailed steps to reproduce the vulnerability
22
+ - **Environment**: The version of hyperfrontend affected, browser/Node.js version, operating system, etc.
23
+ - **Proof of Concept**: If possible, include a minimal code example or proof of concept
24
+ - **Suggested Fix**: If you have ideas on how to fix the issue (optional)
25
+
26
+ ### Response Timeline
27
+
28
+ - **Acknowledgment**: We will acknowledge receipt of your vulnerability report within 2 business days
29
+ - **Initial Assessment**: We will provide an initial assessment within 5 business days
30
+ - **Patch Development**: We aim to develop and test a patch within 10 days of acknowledgment
31
+ - **Public Disclosure**: Please allow at least **10 days** from the initial report before making the vulnerability publicly known
32
+
33
+ This grace period gives us time to:
34
+
35
+ - Verify and reproduce the issue
36
+ - Develop and test a fix
37
+ - Release a patched version
38
+ - Notify users to update their dependencies
39
+
40
+ ### Coordinated Disclosure
41
+
42
+ We believe in coordinated disclosure and appreciate your cooperation in:
43
+
44
+ - Not exploiting the vulnerability beyond what is necessary to demonstrate it
45
+ - Not accessing, modifying, or deleting data that doesn't belong to you
46
+ - Allowing us reasonable time to address the issue before public disclosure
47
+ - Making a good faith effort to avoid privacy violations, data destruction, and service interruption
48
+
49
+ ### Recognition
50
+
51
+ Once the vulnerability is patched and publicly disclosed, we will acknowledge your responsible disclosure in:
52
+
53
+ - Our release notes
54
+ - Our security advisories (if applicable)
55
+ - This SECURITY.md file (with your permission)
56
+
57
+ Thank you for helping keep hyperfrontend and its users safe!
58
+
59
+ ## Security Best Practices
60
+
61
+ When using hyperfrontend in your applications:
62
+
63
+ 1. **Keep Dependencies Updated**: Regularly update to the latest version to receive security patches
64
+ 2. **Content Security Policy**: Implement appropriate CSP headers when embedding features
65
+ 3. **Input Validation**: Validate and sanitize all data passed between features
66
+ 4. **Origin Verification**: Always verify the origin of messages in cross-frame communication
67
+ 5. **Authentication**: Implement proper authentication and authorization for sensitive features
68
+ 6. **HTTPS**: Always serve hyperfrontend features over HTTPS in production
69
+
70
+ ## Security Updates
71
+
72
+ Security updates will be released as patch versions and documented in the [CHANGELOG](https://github.com/AndrewRedican/hyperfrontend/releases) and GitHub Security Advisories.
73
+
74
+ ## Supported Versions
75
+
76
+ We currently provide security updates for:
77
+
78
+ | Version | Supported |
79
+ | ------- | ------------------ |
80
+ | 0.0.x | :white_check_mark: |
81
+
82
+ As the project matures, we will update this table to reflect our long-term support policy.
@@ -0,0 +1,131 @@
1
+ var HyperfrontendTimeUtils = (function (exports) {
2
+ 'use strict';
3
+
4
+ /**
5
+ * Creates an interval loop that invokes one or more subscribed callback functions
6
+ * at the specified internal (in milliseconds).
7
+ *
8
+ * Allows you to start or stop the interval loop, much like a stop watch.
9
+ * Allows you to unsubscribe callback functions.
10
+ *
11
+ * @param interval - Time in milliseconds between each callback invocation (default: 1000ms)
12
+ * @returns A Clock instance with start, stop, subscribe, and unsubscribe methods
13
+ */
14
+ function createClock(interval = 1000) {
15
+ let clockId = null;
16
+ let subscribers = [];
17
+ const start = () => {
18
+ if (clockId === null) {
19
+ clockId = setInterval(() => {
20
+ const currentTime = new Date();
21
+ subscribers.forEach((subscriber) => subscriber(currentTime));
22
+ }, interval);
23
+ }
24
+ };
25
+ const stop = () => {
26
+ if (clockId !== null) {
27
+ clearInterval(clockId);
28
+ clockId = null;
29
+ }
30
+ };
31
+ const subscribe = (callback) => {
32
+ subscribers.push(callback);
33
+ };
34
+ const unsubscribe = (callback) => {
35
+ subscribers = subscribers.filter((subscriber) => subscriber !== callback);
36
+ };
37
+ return Object.freeze({ start, stop, subscribe, unsubscribe, interval });
38
+ }
39
+
40
+ /**
41
+ * Invokes callback function after the designated time has passed, much like a timer.
42
+ * Allows you to pause, resume, or reset the progress of time tracked.
43
+ *
44
+ * @param callback - The function to invoke after the delay
45
+ * @param delay - Time in milliseconds to wait until callback is invoked
46
+ * @returns A Timer instance with pause, resume, and reset methods
47
+ */
48
+ function createTimer(callback, delay) {
49
+ let timerId = null;
50
+ let start = null;
51
+ let remaining = delay;
52
+ const pause = () => {
53
+ if (timerId !== null) {
54
+ clearTimeout(timerId);
55
+ const now = Date.now();
56
+ /* istanbul ignore else - start is always set when timerId is not null */
57
+ if (start !== null) {
58
+ remaining -= now - start;
59
+ }
60
+ timerId = null;
61
+ }
62
+ };
63
+ const resume = () => {
64
+ if (timerId === null) {
65
+ start = Date.now();
66
+ timerId = setTimeout(() => {
67
+ callback();
68
+ timerId = null;
69
+ }, remaining);
70
+ }
71
+ };
72
+ const reset = (newDelay = delay) => {
73
+ pause();
74
+ remaining = newDelay;
75
+ resume();
76
+ };
77
+ return Object.freeze({ pause, resume, reset });
78
+ }
79
+
80
+ /**
81
+ * Normalizes a given time to the nearest base time window.
82
+ *
83
+ * @param time - The Date object to normalize to the nearest time window
84
+ * @param baseTimeWindow - The size of the time window in minutes for normalization
85
+ * @returns A new Date object normalized to the start of the time window
86
+ */
87
+ function normalizeToBaseTimeWindow(time, baseTimeWindow) {
88
+ if (!time || !(time instanceof Date) || isNaN(time.getTime())) {
89
+ throw new Error('Invalid time input');
90
+ }
91
+ if (baseTimeWindow <= 0) {
92
+ throw new Error('Base time window must be positive');
93
+ }
94
+ const timeInMs = time.getTime();
95
+ const windowInMs = baseTimeWindow * 60 * 1000;
96
+ const normalizedTimeInMs = Math.floor(timeInMs / windowInMs) * windowInMs;
97
+ return new Date(normalizedTimeInMs);
98
+ }
99
+
100
+ /**
101
+ * Creates a repeating interval that invokes a callback function at regular intervals.
102
+ *
103
+ * @param callback - The function to invoke at each interval
104
+ * @param interval - Time in milliseconds between each callback invocation
105
+ * @returns A cleanup function that stops the interval when called
106
+ */
107
+ function setIntervalCallback(callback, interval) {
108
+ const timerId = setInterval(callback, interval);
109
+ return () => clearInterval(timerId);
110
+ }
111
+
112
+ /**
113
+ * Pauses execution for a specified duration.
114
+ *
115
+ * @param milliseconds - The duration to sleep in milliseconds
116
+ * @returns A promise that resolves after the specified duration
117
+ */
118
+ function sleep(milliseconds) {
119
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
120
+ }
121
+
122
+ exports.createClock = createClock;
123
+ exports.createTimer = createTimer;
124
+ exports.normalizeToBaseTimeWindow = normalizeToBaseTimeWindow;
125
+ exports.setIntervalCallback = setIntervalCallback;
126
+ exports.sleep = sleep;
127
+
128
+ return exports;
129
+
130
+ })({});
131
+ //# sourceMappingURL=index.iife.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.iife.js","sources":["../../../../../../../../../../libs/utils/time/src/create-clock.ts","../../../../../../../../../../libs/utils/time/src/create-timer.ts","../../../../../../../../../../libs/utils/time/src/normalize-to-base-time-window.ts","../../../../../../../../../../libs/utils/time/src/set-interval-callback.ts","../../../../../../../../../../libs/utils/time/src/sleep.ts"],"sourcesContent":[null,null,null,null,null],"names":[],"mappings":";;;IASA;;;;;;;;;IASG;IACG,SAAU,WAAW,CAAC,QAAQ,GAAG,IAAI,EAAA;QACzC,IAAI,OAAO,GAA0B,IAAI;QACzC,IAAI,WAAW,GAAoC,EAAE;QAErD,MAAM,KAAK,GAAG,MAAW;IACvB,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;IACpB,YAAA,OAAO,GAAG,WAAW,CAAC,MAAK;IACzB,gBAAA,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE;IAC9B,gBAAA,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,WAAW,CAAC,CAAC;gBAC9D,CAAC,EAAE,QAAQ,CAAC;YACd;IACF,IAAA,CAAC;QAED,MAAM,IAAI,GAAG,MAAW;IACtB,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;gBACpB,aAAa,CAAC,OAAO,CAAC;gBACtB,OAAO,GAAG,IAAI;YAChB;IACF,IAAA,CAAC;IAED,IAAA,MAAM,SAAS,GAAG,CAAC,QAAqC,KAAU;IAChE,QAAA,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC5B,IAAA,CAAC;IAED,IAAA,MAAM,WAAW,GAAG,CAAC,QAAqC,KAAU;IAClE,QAAA,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,KAAK,UAAU,KAAK,QAAQ,CAAC;IAC3E,IAAA,CAAC;IAED,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACzE;;ICvCA;;;;;;;IAOG;IACG,SAAU,WAAW,CAAC,QAAoB,EAAE,KAAa,EAAA;QAC7D,IAAI,OAAO,GAA0B,IAAI;QACzC,IAAI,KAAK,GAAkB,IAAI;QAC/B,IAAI,SAAS,GAAW,KAAK;QAE7B,MAAM,KAAK,GAAG,MAAW;IACvB,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;gBACpB,YAAY,CAAC,OAAO,CAAC;IACrB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;;IAEtB,YAAA,IAAI,KAAK,KAAK,IAAI,EAAE;IAClB,gBAAA,SAAS,IAAI,GAAG,GAAG,KAAK;gBAC1B;gBACA,OAAO,GAAG,IAAI;YAChB;IACF,IAAA,CAAC;QAED,MAAM,MAAM,GAAG,MAAW;IACxB,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;IACpB,YAAA,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;IAClB,YAAA,OAAO,GAAG,UAAU,CAAC,MAAK;IACxB,gBAAA,QAAQ,EAAE;oBACV,OAAO,GAAG,IAAI;gBAChB,CAAC,EAAE,SAAS,CAAC;YACf;IACF,IAAA,CAAC;IAED,IAAA,MAAM,KAAK,GAAG,CAAC,QAAA,GAAmB,KAAK,KAAU;IAC/C,QAAA,KAAK,EAAE;YACP,SAAS,GAAG,QAAQ;IACpB,QAAA,MAAM,EAAE;IACV,IAAA,CAAC;IAED,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAChD;;ICnDA;;;;;;IAMG;IACG,SAAU,yBAAyB,CAAC,IAAU,EAAE,cAAsB,EAAA;IAC1E,IAAA,IAAI,CAAC,IAAI,IAAI,EAAE,IAAI,YAAY,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;IAC7D,QAAA,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC;QACvC;IAEA,IAAA,IAAI,cAAc,IAAI,CAAC,EAAE;IACvB,QAAA,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC;QACtD;IAEA,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE;IAC/B,IAAA,MAAM,UAAU,GAAG,cAAc,GAAG,EAAE,GAAG,IAAI;IAC7C,IAAA,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,UAAU;IACzE,IAAA,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC;IACrC;;ICpBA;;;;;;IAMG;IACG,SAAU,mBAAmB,CAAC,QAAoB,EAAE,QAAgB,EAAA;QACxE,MAAM,OAAO,GAAmB,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC/D,IAAA,OAAO,MAAY,aAAa,CAAC,OAAO,CAAC;IAC3C;;ICVA;;;;;IAKG;IACG,SAAU,KAAK,CAAC,YAAoB,EAAA;IACxC,IAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACpE;;;;;;;;;;;;;;"}
@@ -0,0 +1,2 @@
1
+ var HyperfrontendTimeUtils=function(e){"use strict";return e.createClock=function(e=1e3){let t=null,n=[];return Object.freeze({start:()=>{null===t&&(t=setInterval(()=>{const e=new Date;n.forEach(t=>t(e))},e))},stop:()=>{null!==t&&(clearInterval(t),t=null)},subscribe:e=>{n.push(e)},unsubscribe:e=>{n=n.filter(t=>t!==e)},interval:e})},e.createTimer=function(e,t){let n=null,r=null,l=t;const i=()=>{if(null!==n){clearTimeout(n);const e=Date.now();null!==r&&(l-=e-r),n=null}},u=()=>{null===n&&(r=Date.now(),n=setTimeout(()=>{e(),n=null},l))};return Object.freeze({pause:i,resume:u,reset:(e=t)=>{i(),l=e,u()}})},e.normalizeToBaseTimeWindow=function(e,t){if(!e||!(e instanceof Date)||isNaN(e.getTime()))throw new Error("Invalid time input");if(t<=0)throw new Error("Base time window must be positive");const n=e.getTime(),r=60*t*1e3,l=Math.floor(n/r)*r;return new Date(l)},e.setIntervalCallback=function(e,t){const n=setInterval(e,t);return()=>clearInterval(n)},e.sleep=function(e){return new Promise(t=>setTimeout(t,e))},e}({});
2
+ //# sourceMappingURL=index.iife.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.iife.min.js","sources":["../../../../../../../../../../libs/utils/time/src/create-clock.ts","../../../../../../../../../../libs/utils/time/src/create-timer.ts","../../../../../../../../../../libs/utils/time/src/normalize-to-base-time-window.ts","../../../../../../../../../../libs/utils/time/src/set-interval-callback.ts","../../../../../../../../../../libs/utils/time/src/sleep.ts"],"sourcesContent":[null,null,null,null,null],"names":["interval","clockId","subscribers","Object","freeze","start","setInterval","currentTime","Date","forEach","subscriber","stop","clearInterval","subscribe","callback","push","unsubscribe","filter","delay","timerId","remaining","pause","clearTimeout","now","resume","setTimeout","reset","newDelay","time","baseTimeWindow","isNaN","getTime","Error","timeInMs","windowInMs","normalizedTimeInMs","Math","floor","milliseconds","Promise","resolve"],"mappings":"yEAmBM,SAAsBA,EAAW,KACrC,IAAIC,EAAiC,KACjCC,EAA+C,GA0BnD,OAAOC,OAAOC,OAAO,CAAEC,MAxBT,KACI,OAAZJ,IACFA,EAAUK,YAAY,KACpB,MAAMC,EAAc,IAAIC,KACxBN,EAAYO,QAASC,GAAeA,EAAWH,KAC9CP,KAmBuBW,KAfjB,KACK,OAAZV,IACFW,cAAcX,GACdA,EAAU,OAYsBY,UARjBC,IACjBZ,EAAYa,KAAKD,IAO4BE,YAJ1BF,IACnBZ,EAAcA,EAAYe,OAAQP,GAAeA,IAAeI,IAGNd,YAC9D,gBC/BM,SAAsBc,EAAsBI,GAChD,IAAIC,EAAiC,KACjCd,EAAuB,KACvBe,EAAoBF,EAExB,MAAMG,EAAQ,KACZ,GAAgB,OAAZF,EAAkB,CACpBG,aAAaH,GACb,MAAMI,EAAMf,KAAKe,MAEH,OAAVlB,IACFe,GAAaG,EAAMlB,GAErBc,EAAU,IACZ,GAGIK,EAAS,KACG,OAAZL,IACFd,EAAQG,KAAKe,MACbJ,EAAUM,WAAW,KACnBX,IACAK,EAAU,MACTC,KAUP,OAAOjB,OAAOC,OAAO,CAAEiB,QAAOG,SAAQE,MANxB,CAACC,EAAmBT,KAChCG,IACAD,EAAYO,EACZH,MAIJ,8BC5CM,SAAoCI,EAAYC,GACpD,IAAKD,KAAUA,aAAgBpB,OAASsB,MAAMF,EAAKG,WACjD,MAAM,IAAIC,MAAM,sBAGlB,GAAIH,GAAkB,EACpB,MAAM,IAAIG,MAAM,qCAGlB,MAAMC,EAAWL,EAAKG,UAChBG,EAA8B,GAAjBL,EAAsB,IACnCM,EAAqBC,KAAKC,MAAMJ,EAAWC,GAAcA,EAC/D,OAAO,IAAI1B,KAAK2B,EAClB,wBCbM,SAA8BrB,EAAsBd,GACxD,MAAMmB,EAA0Bb,YAAYQ,EAAUd,GACtD,MAAO,IAAYY,cAAcO,EACnC,UCJM,SAAgBmB,GACpB,OAAO,IAAIC,QAASC,GAAYf,WAAWe,EAASF,GACtD"}
@@ -0,0 +1,132 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.HyperfrontendTimeUtils = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ /**
8
+ * Creates an interval loop that invokes one or more subscribed callback functions
9
+ * at the specified internal (in milliseconds).
10
+ *
11
+ * Allows you to start or stop the interval loop, much like a stop watch.
12
+ * Allows you to unsubscribe callback functions.
13
+ *
14
+ * @param interval - Time in milliseconds between each callback invocation (default: 1000ms)
15
+ * @returns A Clock instance with start, stop, subscribe, and unsubscribe methods
16
+ */
17
+ function createClock(interval = 1000) {
18
+ let clockId = null;
19
+ let subscribers = [];
20
+ const start = () => {
21
+ if (clockId === null) {
22
+ clockId = setInterval(() => {
23
+ const currentTime = new Date();
24
+ subscribers.forEach((subscriber) => subscriber(currentTime));
25
+ }, interval);
26
+ }
27
+ };
28
+ const stop = () => {
29
+ if (clockId !== null) {
30
+ clearInterval(clockId);
31
+ clockId = null;
32
+ }
33
+ };
34
+ const subscribe = (callback) => {
35
+ subscribers.push(callback);
36
+ };
37
+ const unsubscribe = (callback) => {
38
+ subscribers = subscribers.filter((subscriber) => subscriber !== callback);
39
+ };
40
+ return Object.freeze({ start, stop, subscribe, unsubscribe, interval });
41
+ }
42
+
43
+ /**
44
+ * Invokes callback function after the designated time has passed, much like a timer.
45
+ * Allows you to pause, resume, or reset the progress of time tracked.
46
+ *
47
+ * @param callback - The function to invoke after the delay
48
+ * @param delay - Time in milliseconds to wait until callback is invoked
49
+ * @returns A Timer instance with pause, resume, and reset methods
50
+ */
51
+ function createTimer(callback, delay) {
52
+ let timerId = null;
53
+ let start = null;
54
+ let remaining = delay;
55
+ const pause = () => {
56
+ if (timerId !== null) {
57
+ clearTimeout(timerId);
58
+ const now = Date.now();
59
+ /* istanbul ignore else - start is always set when timerId is not null */
60
+ if (start !== null) {
61
+ remaining -= now - start;
62
+ }
63
+ timerId = null;
64
+ }
65
+ };
66
+ const resume = () => {
67
+ if (timerId === null) {
68
+ start = Date.now();
69
+ timerId = setTimeout(() => {
70
+ callback();
71
+ timerId = null;
72
+ }, remaining);
73
+ }
74
+ };
75
+ const reset = (newDelay = delay) => {
76
+ pause();
77
+ remaining = newDelay;
78
+ resume();
79
+ };
80
+ return Object.freeze({ pause, resume, reset });
81
+ }
82
+
83
+ /**
84
+ * Normalizes a given time to the nearest base time window.
85
+ *
86
+ * @param time - The Date object to normalize to the nearest time window
87
+ * @param baseTimeWindow - The size of the time window in minutes for normalization
88
+ * @returns A new Date object normalized to the start of the time window
89
+ */
90
+ function normalizeToBaseTimeWindow(time, baseTimeWindow) {
91
+ if (!time || !(time instanceof Date) || isNaN(time.getTime())) {
92
+ throw new Error('Invalid time input');
93
+ }
94
+ if (baseTimeWindow <= 0) {
95
+ throw new Error('Base time window must be positive');
96
+ }
97
+ const timeInMs = time.getTime();
98
+ const windowInMs = baseTimeWindow * 60 * 1000;
99
+ const normalizedTimeInMs = Math.floor(timeInMs / windowInMs) * windowInMs;
100
+ return new Date(normalizedTimeInMs);
101
+ }
102
+
103
+ /**
104
+ * Creates a repeating interval that invokes a callback function at regular intervals.
105
+ *
106
+ * @param callback - The function to invoke at each interval
107
+ * @param interval - Time in milliseconds between each callback invocation
108
+ * @returns A cleanup function that stops the interval when called
109
+ */
110
+ function setIntervalCallback(callback, interval) {
111
+ const timerId = setInterval(callback, interval);
112
+ return () => clearInterval(timerId);
113
+ }
114
+
115
+ /**
116
+ * Pauses execution for a specified duration.
117
+ *
118
+ * @param milliseconds - The duration to sleep in milliseconds
119
+ * @returns A promise that resolves after the specified duration
120
+ */
121
+ function sleep(milliseconds) {
122
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
123
+ }
124
+
125
+ exports.createClock = createClock;
126
+ exports.createTimer = createTimer;
127
+ exports.normalizeToBaseTimeWindow = normalizeToBaseTimeWindow;
128
+ exports.setIntervalCallback = setIntervalCallback;
129
+ exports.sleep = sleep;
130
+
131
+ }));
132
+ //# sourceMappingURL=index.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.umd.js","sources":["../../../../../../../../../../libs/utils/time/src/create-clock.ts","../../../../../../../../../../libs/utils/time/src/create-timer.ts","../../../../../../../../../../libs/utils/time/src/normalize-to-base-time-window.ts","../../../../../../../../../../libs/utils/time/src/set-interval-callback.ts","../../../../../../../../../../libs/utils/time/src/sleep.ts"],"sourcesContent":[null,null,null,null,null],"names":[],"mappings":";;;;;;IASA;;;;;;;;;IASG;IACG,SAAU,WAAW,CAAC,QAAQ,GAAG,IAAI,EAAA;QACzC,IAAI,OAAO,GAA0B,IAAI;QACzC,IAAI,WAAW,GAAoC,EAAE;QAErD,MAAM,KAAK,GAAG,MAAW;IACvB,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;IACpB,YAAA,OAAO,GAAG,WAAW,CAAC,MAAK;IACzB,gBAAA,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE;IAC9B,gBAAA,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,WAAW,CAAC,CAAC;gBAC9D,CAAC,EAAE,QAAQ,CAAC;YACd;IACF,IAAA,CAAC;QAED,MAAM,IAAI,GAAG,MAAW;IACtB,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;gBACpB,aAAa,CAAC,OAAO,CAAC;gBACtB,OAAO,GAAG,IAAI;YAChB;IACF,IAAA,CAAC;IAED,IAAA,MAAM,SAAS,GAAG,CAAC,QAAqC,KAAU;IAChE,QAAA,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC5B,IAAA,CAAC;IAED,IAAA,MAAM,WAAW,GAAG,CAAC,QAAqC,KAAU;IAClE,QAAA,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,KAAK,UAAU,KAAK,QAAQ,CAAC;IAC3E,IAAA,CAAC;IAED,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACzE;;ICvCA;;;;;;;IAOG;IACG,SAAU,WAAW,CAAC,QAAoB,EAAE,KAAa,EAAA;QAC7D,IAAI,OAAO,GAA0B,IAAI;QACzC,IAAI,KAAK,GAAkB,IAAI;QAC/B,IAAI,SAAS,GAAW,KAAK;QAE7B,MAAM,KAAK,GAAG,MAAW;IACvB,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;gBACpB,YAAY,CAAC,OAAO,CAAC;IACrB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;;IAEtB,YAAA,IAAI,KAAK,KAAK,IAAI,EAAE;IAClB,gBAAA,SAAS,IAAI,GAAG,GAAG,KAAK;gBAC1B;gBACA,OAAO,GAAG,IAAI;YAChB;IACF,IAAA,CAAC;QAED,MAAM,MAAM,GAAG,MAAW;IACxB,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;IACpB,YAAA,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;IAClB,YAAA,OAAO,GAAG,UAAU,CAAC,MAAK;IACxB,gBAAA,QAAQ,EAAE;oBACV,OAAO,GAAG,IAAI;gBAChB,CAAC,EAAE,SAAS,CAAC;YACf;IACF,IAAA,CAAC;IAED,IAAA,MAAM,KAAK,GAAG,CAAC,QAAA,GAAmB,KAAK,KAAU;IAC/C,QAAA,KAAK,EAAE;YACP,SAAS,GAAG,QAAQ;IACpB,QAAA,MAAM,EAAE;IACV,IAAA,CAAC;IAED,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAChD;;ICnDA;;;;;;IAMG;IACG,SAAU,yBAAyB,CAAC,IAAU,EAAE,cAAsB,EAAA;IAC1E,IAAA,IAAI,CAAC,IAAI,IAAI,EAAE,IAAI,YAAY,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;IAC7D,QAAA,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC;QACvC;IAEA,IAAA,IAAI,cAAc,IAAI,CAAC,EAAE;IACvB,QAAA,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC;QACtD;IAEA,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE;IAC/B,IAAA,MAAM,UAAU,GAAG,cAAc,GAAG,EAAE,GAAG,IAAI;IAC7C,IAAA,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,UAAU;IACzE,IAAA,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC;IACrC;;ICpBA;;;;;;IAMG;IACG,SAAU,mBAAmB,CAAC,QAAoB,EAAE,QAAgB,EAAA;QACxE,MAAM,OAAO,GAAmB,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC/D,IAAA,OAAO,MAAY,aAAa,CAAC,OAAO,CAAC;IAC3C;;ICVA;;;;;IAKG;IACG,SAAU,KAAK,CAAC,YAAoB,EAAA;IACxC,IAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACpE;;;;;;;;;;;;"}
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).HyperfrontendTimeUtils={})}(this,function(e){"use strict";e.createClock=function(e=1e3){let t=null,n=[];return Object.freeze({start:()=>{null===t&&(t=setInterval(()=>{const e=new Date;n.forEach(t=>t(e))},e))},stop:()=>{null!==t&&(clearInterval(t),t=null)},subscribe:e=>{n.push(e)},unsubscribe:e=>{n=n.filter(t=>t!==e)},interval:e})},e.createTimer=function(e,t){let n=null,l=null,r=t;const o=()=>{if(null!==n){clearTimeout(n);const e=Date.now();null!==l&&(r-=e-l),n=null}},i=()=>{null===n&&(l=Date.now(),n=setTimeout(()=>{e(),n=null},r))};return Object.freeze({pause:o,resume:i,reset:(e=t)=>{o(),r=e,i()}})},e.normalizeToBaseTimeWindow=function(e,t){if(!e||!(e instanceof Date)||isNaN(e.getTime()))throw new Error("Invalid time input");if(t<=0)throw new Error("Base time window must be positive");const n=e.getTime(),l=60*t*1e3,r=Math.floor(n/l)*l;return new Date(r)},e.setIntervalCallback=function(e,t){const n=setInterval(e,t);return()=>clearInterval(n)},e.sleep=function(e){return new Promise(t=>setTimeout(t,e))}});
2
+ //# sourceMappingURL=index.umd.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.umd.min.js","sources":["../../../../../../../../../../libs/utils/time/src/create-clock.ts","../../../../../../../../../../libs/utils/time/src/create-timer.ts","../../../../../../../../../../libs/utils/time/src/normalize-to-base-time-window.ts","../../../../../../../../../../libs/utils/time/src/set-interval-callback.ts","../../../../../../../../../../libs/utils/time/src/sleep.ts"],"sourcesContent":[null,null,null,null,null],"names":["interval","clockId","subscribers","Object","freeze","start","setInterval","currentTime","Date","forEach","subscriber","stop","clearInterval","subscribe","callback","push","unsubscribe","filter","delay","timerId","remaining","pause","clearTimeout","now","resume","setTimeout","reset","newDelay","time","baseTimeWindow","isNaN","getTime","Error","timeInMs","windowInMs","normalizedTimeInMs","Math","floor","milliseconds","Promise","resolve"],"mappings":"2QAmBM,SAAsBA,EAAW,KACrC,IAAIC,EAAiC,KACjCC,EAA+C,GA0BnD,OAAOC,OAAOC,OAAO,CAAEC,MAxBT,KACI,OAAZJ,IACFA,EAAUK,YAAY,KACpB,MAAMC,EAAc,IAAIC,KACxBN,EAAYO,QAASC,GAAeA,EAAWH,KAC9CP,KAmBuBW,KAfjB,KACK,OAAZV,IACFW,cAAcX,GACdA,EAAU,OAYsBY,UARjBC,IACjBZ,EAAYa,KAAKD,IAO4BE,YAJ1BF,IACnBZ,EAAcA,EAAYe,OAAQP,GAAeA,IAAeI,IAGNd,YAC9D,gBC/BM,SAAsBc,EAAsBI,GAChD,IAAIC,EAAiC,KACjCd,EAAuB,KACvBe,EAAoBF,EAExB,MAAMG,EAAQ,KACZ,GAAgB,OAAZF,EAAkB,CACpBG,aAAaH,GACb,MAAMI,EAAMf,KAAKe,MAEH,OAAVlB,IACFe,GAAaG,EAAMlB,GAErBc,EAAU,IACZ,GAGIK,EAAS,KACG,OAAZL,IACFd,EAAQG,KAAKe,MACbJ,EAAUM,WAAW,KACnBX,IACAK,EAAU,MACTC,KAUP,OAAOjB,OAAOC,OAAO,CAAEiB,QAAOG,SAAQE,MANxB,CAACC,EAAmBT,KAChCG,IACAD,EAAYO,EACZH,MAIJ,8BC5CM,SAAoCI,EAAYC,GACpD,IAAKD,KAAUA,aAAgBpB,OAASsB,MAAMF,EAAKG,WACjD,MAAM,IAAIC,MAAM,sBAGlB,GAAIH,GAAkB,EACpB,MAAM,IAAIG,MAAM,qCAGlB,MAAMC,EAAWL,EAAKG,UAChBG,EAA8B,GAAjBL,EAAsB,IACnCM,EAAqBC,KAAKC,MAAMJ,EAAWC,GAAcA,EAC/D,OAAO,IAAI1B,KAAK2B,EAClB,wBCbM,SAA8BrB,EAAsBd,GACxD,MAAMmB,EAA0Bb,YAAYQ,EAAUd,GACtD,MAAO,IAAYY,cAAcO,EACnC,UCJM,SAAgBmB,GACpB,OAAO,IAAIC,QAASC,GAAYf,WAAWe,EAASF,GACtD"}
@@ -0,0 +1,20 @@
1
+ export interface Clock {
2
+ readonly start: () => void;
3
+ readonly stop: () => void;
4
+ readonly subscribe: (callback: (currentTime: Date) => void) => void;
5
+ readonly unsubscribe: (callback: (currentTime: Date) => void) => void;
6
+ /** Interval in milliseconds */
7
+ readonly interval: number;
8
+ }
9
+ /**
10
+ * Creates an interval loop that invokes one or more subscribed callback functions
11
+ * at the specified internal (in milliseconds).
12
+ *
13
+ * Allows you to start or stop the interval loop, much like a stop watch.
14
+ * Allows you to unsubscribe callback functions.
15
+ *
16
+ * @param interval - Time in milliseconds between each callback invocation (default: 1000ms)
17
+ * @returns A Clock instance with start, stop, subscribe, and unsubscribe methods
18
+ */
19
+ export declare function createClock(interval?: number): Clock;
20
+ //# sourceMappingURL=create-clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-clock.d.ts","sourceRoot":"","sources":["../../../../libs/utils/time/src/create-clock.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,IAAI,KAAK,IAAI,KAAK,IAAI,CAAA;IACnE,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,IAAI,KAAK,IAAI,KAAK,IAAI,CAAA;IACrE,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,QAAQ,SAAO,GAAG,KAAK,CA6BlD"}
@@ -0,0 +1,18 @@
1
+ export interface Timer {
2
+ /** Stops the progression of tracked time until further notice. */
3
+ readonly pause: () => void;
4
+ /** Reinstates the progression of tracked time. */
5
+ readonly resume: () => void;
6
+ /** Assigns a new wait time before function is invoked. */
7
+ readonly reset: (newDelay?: number) => void;
8
+ }
9
+ /**
10
+ * Invokes callback function after the designated time has passed, much like a timer.
11
+ * Allows you to pause, resume, or reset the progress of time tracked.
12
+ *
13
+ * @param callback - The function to invoke after the delay
14
+ * @param delay - Time in milliseconds to wait until callback is invoked
15
+ * @returns A Timer instance with pause, resume, and reset methods
16
+ */
17
+ export declare function createTimer(callback: () => void, delay: number): Timer;
18
+ //# sourceMappingURL=create-timer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-timer.d.ts","sourceRoot":"","sources":["../../../../libs/utils/time/src/create-timer.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAA;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAA;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAC5C;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAkCtE"}
package/index.cjs.js ADDED
@@ -0,0 +1,126 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Creates an interval loop that invokes one or more subscribed callback functions
5
+ * at the specified internal (in milliseconds).
6
+ *
7
+ * Allows you to start or stop the interval loop, much like a stop watch.
8
+ * Allows you to unsubscribe callback functions.
9
+ *
10
+ * @param interval - Time in milliseconds between each callback invocation (default: 1000ms)
11
+ * @returns A Clock instance with start, stop, subscribe, and unsubscribe methods
12
+ */
13
+ function createClock(interval = 1000) {
14
+ let clockId = null;
15
+ let subscribers = [];
16
+ const start = () => {
17
+ if (clockId === null) {
18
+ clockId = setInterval(() => {
19
+ const currentTime = new Date();
20
+ subscribers.forEach((subscriber) => subscriber(currentTime));
21
+ }, interval);
22
+ }
23
+ };
24
+ const stop = () => {
25
+ if (clockId !== null) {
26
+ clearInterval(clockId);
27
+ clockId = null;
28
+ }
29
+ };
30
+ const subscribe = (callback) => {
31
+ subscribers.push(callback);
32
+ };
33
+ const unsubscribe = (callback) => {
34
+ subscribers = subscribers.filter((subscriber) => subscriber !== callback);
35
+ };
36
+ return Object.freeze({ start, stop, subscribe, unsubscribe, interval });
37
+ }
38
+
39
+ /**
40
+ * Invokes callback function after the designated time has passed, much like a timer.
41
+ * Allows you to pause, resume, or reset the progress of time tracked.
42
+ *
43
+ * @param callback - The function to invoke after the delay
44
+ * @param delay - Time in milliseconds to wait until callback is invoked
45
+ * @returns A Timer instance with pause, resume, and reset methods
46
+ */
47
+ function createTimer(callback, delay) {
48
+ let timerId = null;
49
+ let start = null;
50
+ let remaining = delay;
51
+ const pause = () => {
52
+ if (timerId !== null) {
53
+ clearTimeout(timerId);
54
+ const now = Date.now();
55
+ /* istanbul ignore else - start is always set when timerId is not null */
56
+ if (start !== null) {
57
+ remaining -= now - start;
58
+ }
59
+ timerId = null;
60
+ }
61
+ };
62
+ const resume = () => {
63
+ if (timerId === null) {
64
+ start = Date.now();
65
+ timerId = setTimeout(() => {
66
+ callback();
67
+ timerId = null;
68
+ }, remaining);
69
+ }
70
+ };
71
+ const reset = (newDelay = delay) => {
72
+ pause();
73
+ remaining = newDelay;
74
+ resume();
75
+ };
76
+ return Object.freeze({ pause, resume, reset });
77
+ }
78
+
79
+ /**
80
+ * Normalizes a given time to the nearest base time window.
81
+ *
82
+ * @param time - The Date object to normalize to the nearest time window
83
+ * @param baseTimeWindow - The size of the time window in minutes for normalization
84
+ * @returns A new Date object normalized to the start of the time window
85
+ */
86
+ function normalizeToBaseTimeWindow(time, baseTimeWindow) {
87
+ if (!time || !(time instanceof Date) || isNaN(time.getTime())) {
88
+ throw new Error('Invalid time input');
89
+ }
90
+ if (baseTimeWindow <= 0) {
91
+ throw new Error('Base time window must be positive');
92
+ }
93
+ const timeInMs = time.getTime();
94
+ const windowInMs = baseTimeWindow * 60 * 1000;
95
+ const normalizedTimeInMs = Math.floor(timeInMs / windowInMs) * windowInMs;
96
+ return new Date(normalizedTimeInMs);
97
+ }
98
+
99
+ /**
100
+ * Creates a repeating interval that invokes a callback function at regular intervals.
101
+ *
102
+ * @param callback - The function to invoke at each interval
103
+ * @param interval - Time in milliseconds between each callback invocation
104
+ * @returns A cleanup function that stops the interval when called
105
+ */
106
+ function setIntervalCallback(callback, interval) {
107
+ const timerId = setInterval(callback, interval);
108
+ return () => clearInterval(timerId);
109
+ }
110
+
111
+ /**
112
+ * Pauses execution for a specified duration.
113
+ *
114
+ * @param milliseconds - The duration to sleep in milliseconds
115
+ * @returns A promise that resolves after the specified duration
116
+ */
117
+ function sleep(milliseconds) {
118
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
119
+ }
120
+
121
+ exports.createClock = createClock;
122
+ exports.createTimer = createTimer;
123
+ exports.normalizeToBaseTimeWindow = normalizeToBaseTimeWindow;
124
+ exports.setIntervalCallback = setIntervalCallback;
125
+ exports.sleep = sleep;
126
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../libs/utils/time/src/create-clock.ts","../../../../libs/utils/time/src/create-timer.ts","../../../../libs/utils/time/src/normalize-to-base-time-window.ts","../../../../libs/utils/time/src/set-interval-callback.ts","../../../../libs/utils/time/src/sleep.ts"],"sourcesContent":[null,null,null,null,null],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './create-clock';
2
+ export * from './create-timer';
3
+ export * from './normalize-to-base-time-window';
4
+ export * from './set-interval-callback';
5
+ export * from './sleep';
6
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../libs/utils/time/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iCAAiC,CAAA;AAC/C,cAAc,yBAAyB,CAAA;AACvC,cAAc,SAAS,CAAA"}
package/index.esm.js ADDED
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Creates an interval loop that invokes one or more subscribed callback functions
3
+ * at the specified internal (in milliseconds).
4
+ *
5
+ * Allows you to start or stop the interval loop, much like a stop watch.
6
+ * Allows you to unsubscribe callback functions.
7
+ *
8
+ * @param interval - Time in milliseconds between each callback invocation (default: 1000ms)
9
+ * @returns A Clock instance with start, stop, subscribe, and unsubscribe methods
10
+ */
11
+ function createClock(interval = 1000) {
12
+ let clockId = null;
13
+ let subscribers = [];
14
+ const start = () => {
15
+ if (clockId === null) {
16
+ clockId = setInterval(() => {
17
+ const currentTime = new Date();
18
+ subscribers.forEach((subscriber) => subscriber(currentTime));
19
+ }, interval);
20
+ }
21
+ };
22
+ const stop = () => {
23
+ if (clockId !== null) {
24
+ clearInterval(clockId);
25
+ clockId = null;
26
+ }
27
+ };
28
+ const subscribe = (callback) => {
29
+ subscribers.push(callback);
30
+ };
31
+ const unsubscribe = (callback) => {
32
+ subscribers = subscribers.filter((subscriber) => subscriber !== callback);
33
+ };
34
+ return Object.freeze({ start, stop, subscribe, unsubscribe, interval });
35
+ }
36
+
37
+ /**
38
+ * Invokes callback function after the designated time has passed, much like a timer.
39
+ * Allows you to pause, resume, or reset the progress of time tracked.
40
+ *
41
+ * @param callback - The function to invoke after the delay
42
+ * @param delay - Time in milliseconds to wait until callback is invoked
43
+ * @returns A Timer instance with pause, resume, and reset methods
44
+ */
45
+ function createTimer(callback, delay) {
46
+ let timerId = null;
47
+ let start = null;
48
+ let remaining = delay;
49
+ const pause = () => {
50
+ if (timerId !== null) {
51
+ clearTimeout(timerId);
52
+ const now = Date.now();
53
+ /* istanbul ignore else - start is always set when timerId is not null */
54
+ if (start !== null) {
55
+ remaining -= now - start;
56
+ }
57
+ timerId = null;
58
+ }
59
+ };
60
+ const resume = () => {
61
+ if (timerId === null) {
62
+ start = Date.now();
63
+ timerId = setTimeout(() => {
64
+ callback();
65
+ timerId = null;
66
+ }, remaining);
67
+ }
68
+ };
69
+ const reset = (newDelay = delay) => {
70
+ pause();
71
+ remaining = newDelay;
72
+ resume();
73
+ };
74
+ return Object.freeze({ pause, resume, reset });
75
+ }
76
+
77
+ /**
78
+ * Normalizes a given time to the nearest base time window.
79
+ *
80
+ * @param time - The Date object to normalize to the nearest time window
81
+ * @param baseTimeWindow - The size of the time window in minutes for normalization
82
+ * @returns A new Date object normalized to the start of the time window
83
+ */
84
+ function normalizeToBaseTimeWindow(time, baseTimeWindow) {
85
+ if (!time || !(time instanceof Date) || isNaN(time.getTime())) {
86
+ throw new Error('Invalid time input');
87
+ }
88
+ if (baseTimeWindow <= 0) {
89
+ throw new Error('Base time window must be positive');
90
+ }
91
+ const timeInMs = time.getTime();
92
+ const windowInMs = baseTimeWindow * 60 * 1000;
93
+ const normalizedTimeInMs = Math.floor(timeInMs / windowInMs) * windowInMs;
94
+ return new Date(normalizedTimeInMs);
95
+ }
96
+
97
+ /**
98
+ * Creates a repeating interval that invokes a callback function at regular intervals.
99
+ *
100
+ * @param callback - The function to invoke at each interval
101
+ * @param interval - Time in milliseconds between each callback invocation
102
+ * @returns A cleanup function that stops the interval when called
103
+ */
104
+ function setIntervalCallback(callback, interval) {
105
+ const timerId = setInterval(callback, interval);
106
+ return () => clearInterval(timerId);
107
+ }
108
+
109
+ /**
110
+ * Pauses execution for a specified duration.
111
+ *
112
+ * @param milliseconds - The duration to sleep in milliseconds
113
+ * @returns A promise that resolves after the specified duration
114
+ */
115
+ function sleep(milliseconds) {
116
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
117
+ }
118
+
119
+ export { createClock, createTimer, normalizeToBaseTimeWindow, setIntervalCallback, sleep };
120
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../../../../libs/utils/time/src/create-clock.ts","../../../../libs/utils/time/src/create-timer.ts","../../../../libs/utils/time/src/normalize-to-base-time-window.ts","../../../../libs/utils/time/src/set-interval-callback.ts","../../../../libs/utils/time/src/sleep.ts"],"sourcesContent":[null,null,null,null,null],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Normalizes a given time to the nearest base time window.
3
+ *
4
+ * @param time - The Date object to normalize to the nearest time window
5
+ * @param baseTimeWindow - The size of the time window in minutes for normalization
6
+ * @returns A new Date object normalized to the start of the time window
7
+ */
8
+ export declare function normalizeToBaseTimeWindow(time: Date, baseTimeWindow: number): Date;
9
+ //# sourceMappingURL=normalize-to-base-time-window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-to-base-time-window.d.ts","sourceRoot":"","sources":["../../../../libs/utils/time/src/normalize-to-base-time-window.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAalF"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@hyperfrontend/time-utils",
3
+ "version": "0.0.1",
4
+ "description": "Functional time utilities for async operations, intervals, and time normalization.",
5
+ "license": "MIT",
6
+ "sideEffects": false,
7
+ "engines": {
8
+ "node": ">=18.0.0",
9
+ "npm": ">=8.0.0"
10
+ },
11
+ "keywords": [
12
+ "timer",
13
+ "clock",
14
+ "interval",
15
+ "timeout",
16
+ "sleep",
17
+ "delay",
18
+ "pause",
19
+ "resume",
20
+ "time-window",
21
+ "time-normalization",
22
+ "async",
23
+ "promise",
24
+ "zero-dependencies",
25
+ "typescript",
26
+ "functional",
27
+ "immutable"
28
+ ],
29
+ "main": "./index.cjs.js",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/AndrewRedican/hyperfrontend.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/AndrewRedican/hyperfrontend/issues"
36
+ },
37
+ "homepage": "https://github.com/AndrewRedican/hyperfrontend#readme",
38
+ "author": {
39
+ "name": "andrew.redican.mejia@gmail.com",
40
+ "url": "https://hyperfrontend.dev"
41
+ },
42
+ "exports": {
43
+ "./package.json": "./package.json",
44
+ ".": {
45
+ "types": "./index.d.ts",
46
+ "import": "./index.esm.js",
47
+ "require": "./index.cjs.js"
48
+ },
49
+ "./bundle": {
50
+ "import": "./bundle/index.iife.min.js",
51
+ "require": "./bundle/index.iife.min.js"
52
+ }
53
+ },
54
+ "module": "./index.esm.js",
55
+ "types": "./index.d.ts",
56
+ "unpkg": "./bundle/index.umd.min.js",
57
+ "jsdelivr": "./bundle/index.umd.min.js"
58
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Creates a repeating interval that invokes a callback function at regular intervals.
3
+ *
4
+ * @param callback - The function to invoke at each interval
5
+ * @param interval - Time in milliseconds between each callback invocation
6
+ * @returns A cleanup function that stops the interval when called
7
+ */
8
+ export declare function setIntervalCallback(callback: () => void, interval: number): () => void;
9
+ //# sourceMappingURL=set-interval-callback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-interval-callback.d.ts","sourceRoot":"","sources":["../../../../libs/utils/time/src/set-interval-callback.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,IAAI,CAGtF"}
package/sleep.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Pauses execution for a specified duration.
3
+ *
4
+ * @param milliseconds - The duration to sleep in milliseconds
5
+ * @returns A promise that resolves after the specified duration
6
+ */
7
+ export declare function sleep(milliseconds: number): Promise<void>;
8
+ //# sourceMappingURL=sleep.d.ts.map
package/sleep.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../../../libs/utils/time/src/sleep.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzD"}