From 63f7e39d284d963cea7c13e82da16bb9d9d7196e Mon Sep 17 00:00:00 2001 From: Daniel Freytag Date: Thu, 12 Dec 2024 17:25:00 +0100 Subject: [PATCH 1/4] feat: add `formatDuration` to dates --- README.md | 18 +++++++++++++++- dates/CHANGELOG.md | 9 ++++++++ dates/dates.ts | 9 ++++++++ dates/deno.jsonc | 3 ++- dates/duration.test.ts | 21 +++++++++++++++++++ deno.lock | 5 +++++ logger/CHANGELOG.md | 5 +++++ ...t.test.ts => logger-format-errors.test.ts} | 0 8 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 dates/CHANGELOG.md create mode 100644 dates/duration.test.ts create mode 100644 logger/CHANGELOG.md rename logger/{logger-format.test.ts => logger-format-errors.test.ts} (100%) diff --git a/README.md b/README.md index d0c23d9..fa070df 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ This repository is work in progress. ## Tools - [`@frytg/check-required-env`](./check-required-env/README.md) - Check a required environment variable -- [`@frytg/logger`](./logger/README.md) - Winston logging wrapper +- [`@frytg/dates`](./dates/README.md) - Date utilities around Luxon +- [`@frytg/logger`](./logger/README.md) - Pre-configuredWinston logging wrapper ## Lint @@ -23,6 +24,14 @@ deno task check See [_Writing documentation_](https://jsr.io/docs/writing-docs) for details about writing JSDoc. +## Testing + +This uses [`@cross/test`](https://jsr.io/@cross/test) and [`sinon`](https://sinonjs.org) to run the tests. + +```bash +deno task test +``` + ## Publish Locally check if everything is ok: @@ -34,6 +43,13 @@ deno publish --dry-run Then once everything is pushed or merged on `main`, run the GitHub actions workflow to publish the packages to JSR (see [_publishing packages_](https://jsr.io/docs/publishing-packages) for more details). +## More Tooling + +Other tools that I regularly use and don't feel the need to optimize or re-create in this utility package: + +- [`axios`](https://github.com/axios/axios) - _Promise based HTTP client for the browser and node.js_ +- [`hono`](https://jsr.io/@hono/hono) - _small, simple, and ultrafast web framework built on Web Standards_ + ## Author Created by [@frytg](https://github.com/frytg) / [frytg.digital](https://www.frytg.digital) diff --git a/dates/CHANGELOG.md b/dates/CHANGELOG.md new file mode 100644 index 0000000..e1e6583 --- /dev/null +++ b/dates/CHANGELOG.md @@ -0,0 +1,9 @@ +# Dates Changelog + +## 2024-12-12 - 0.1.0 + +- feat: added `formatDuration` function to format durations in milliseconds to a human readable string. + +## 2024-11-23 - 0.0.1 + +- feat: added basic setup diff --git a/dates/dates.ts b/dates/dates.ts index c55f852..ea894b6 100644 --- a/dates/dates.ts +++ b/dates/dates.ts @@ -1,4 +1,5 @@ // load package +import { format as stdFormat } from '@std/fmt/duration' import { DateTime } from 'luxon' const LOCAL_TIMEZONE = 'Europe/Amsterdam' @@ -199,3 +200,11 @@ export const getDateHourMinutes = (date: DateTime): string => * ``` */ export const getFullRelativeTime = (date: DateTime): string => `${getDateHourMinutes(date)} (${getRelative(date)})` + +/** + * Format a duration in milliseconds to a human readable string. + * + * @param {number} duration - the duration in milliseconds + * @returns {string} the formatted duration (e.g. `1m 39s`) + */ +export const formatDuration = (duration: number) => stdFormat(duration, { ignoreZero: true }) diff --git a/dates/deno.jsonc b/dates/deno.jsonc index ef113df..5141f2b 100644 --- a/dates/deno.jsonc +++ b/dates/deno.jsonc @@ -1,9 +1,10 @@ { "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@frytg/dates", - "version": "0.0.1", + "version": "0.1.0", "exports": "./dates.ts", "imports": { + "@std/fmt": "jsr:@std/fmt@^1.0.3", "luxon": "npm:luxon@^3.5.0" } } diff --git a/dates/duration.test.ts b/dates/duration.test.ts new file mode 100644 index 0000000..d1d1b45 --- /dev/null +++ b/dates/duration.test.ts @@ -0,0 +1,21 @@ +import { test } from '@cross/test' +import { assertEquals } from '@std/assert' + +import { formatDuration } from './dates.ts' + +test('formatDuration - formats milliseconds correctly', () => { + const testCases = [ + { input: 1000, expected: '1s' }, + { input: 60000, expected: '1m' }, + { input: 3600000, expected: '1h' }, + { input: 86400000, expected: '1d' }, + { input: 99123, expected: '1m 39s 123ms' }, + { input: 3723000, expected: '1h 2m 3s' }, + { input: 0, expected: '' }, + { input: 500, expected: '500ms' }, + ] + + for (const { input, expected } of testCases) { + assertEquals(formatDuration(input), expected, `formatDuration(${input}) should return "${expected}"`) + } +}) diff --git a/deno.lock b/deno.lock index f3828d9..15773d7 100644 --- a/deno.lock +++ b/deno.lock @@ -5,6 +5,7 @@ "jsr:@cross/test@^0.0.10": "0.0.10", "jsr:@frytg/logger@0.0.2": "0.0.2", "jsr:@std/assert@^1.0.9": "1.0.9", + "jsr:@std/fmt@^1.0.3": "1.0.3", "jsr:@std/internal@^1.0.5": "1.0.5", "npm:@biomejs/biome@1.9.4": "1.9.4", "npm:@biomejs/biome@^1.9.4": "1.9.4", @@ -36,6 +37,9 @@ "jsr:@std/internal" ] }, + "@std/fmt@1.0.3": { + "integrity": "97765c16aa32245ff4e2204ecf7d8562496a3cb8592340a80e7e554e0bb9149f" + }, "@std/internal@1.0.5": { "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" } @@ -394,6 +398,7 @@ }, "dates": { "dependencies": [ + "jsr:@std/fmt@^1.0.3", "npm:luxon@^3.5.0" ] }, diff --git a/logger/CHANGELOG.md b/logger/CHANGELOG.md new file mode 100644 index 0000000..1d2db63 --- /dev/null +++ b/logger/CHANGELOG.md @@ -0,0 +1,5 @@ +# Logger Changelog + +## 2024-11-22 - 0.0.2 + +- feat: added basic setup diff --git a/logger/logger-format.test.ts b/logger/logger-format-errors.test.ts similarity index 100% rename from logger/logger-format.test.ts rename to logger/logger-format-errors.test.ts From d3f1d8b79a890a7b18bcbc105050119309adfe4f Mon Sep 17 00:00:00 2001 From: Daniel Freytag Date: Thu, 12 Dec 2024 17:27:43 +0100 Subject: [PATCH 2/4] chore: add example --- dates/dates.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dates/dates.ts b/dates/dates.ts index ea894b6..6874369 100644 --- a/dates/dates.ts +++ b/dates/dates.ts @@ -206,5 +206,16 @@ export const getFullRelativeTime = (date: DateTime): string => `${getDateHourMin * * @param {number} duration - the duration in milliseconds * @returns {string} the formatted duration (e.g. `1m 39s`) + * + * @example + * ```ts + * import { formatDuration } from 'jsr:@frytg/dates' + * + * formatDuration(1000) // 1s + * + * const startTs = getMs() + * // do something... + * formatDuration(getMsOffset(startTs)) // time taken + * ``` */ export const formatDuration = (duration: number) => stdFormat(duration, { ignoreZero: true }) From fb8ce5b1f43ea91dd6fd815cd84330d015041236 Mon Sep 17 00:00:00 2001 From: Daniel Freytag Date: Thu, 12 Dec 2024 17:33:05 +0100 Subject: [PATCH 3/4] fix: return type for function --- dates/dates.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dates/dates.ts b/dates/dates.ts index 6874369..1f18bdb 100644 --- a/dates/dates.ts +++ b/dates/dates.ts @@ -218,4 +218,4 @@ export const getFullRelativeTime = (date: DateTime): string => `${getDateHourMin * formatDuration(getMsOffset(startTs)) // time taken * ``` */ -export const formatDuration = (duration: number) => stdFormat(duration, { ignoreZero: true }) +export const formatDuration = (duration: number): string => stdFormat(duration, { ignoreZero: true }) From 7943f275cb7d088cbb690cd5a3587d16748710de Mon Sep 17 00:00:00 2001 From: Daniel Freytag Date: Thu, 12 Dec 2024 17:33:50 +0100 Subject: [PATCH 4/4] fix: add jsr deps --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5102a59..a7190b1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ permissions: contents: read env: - JSR_DEPENDENCIES: "@cross/test @std/assert @frytg/logger" + JSR_DEPENDENCIES: "@cross/test @std/assert @std/fmt @frytg/logger @frytg/dates" NPM_DEPENDENCIES: "luxon sinon" jobs: