yummies 3.0.16 → 3.0.18

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/README.md CHANGED
@@ -20,6 +20,9 @@ Yummies - a set of various utilities for JavaScript projects with open source co
20
20
  ## [yummies/async](src/async.ts)
21
21
  Utilities for working with asynchronous code
22
22
 
23
+ ## [yummies/common](src/common.ts)
24
+ All other utilities without groupping
25
+
23
26
  ## [yummies/cookie](src/cookie.ts)
24
27
  Utilities for working with cookies
25
28
 
package/common.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export type FnValue<TValue, TArgs extends any[] = []> = TValue | ((...args: TArgs) => TValue);
2
+ export declare const resolveFnValue: <TValue, TArgs extends any[] = []>(fn: FnValue<TValue, TArgs>, ...args: TArgs) => TValue;
3
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,CAAC,MAAM,EAAE,KAAK,SAAS,GAAG,EAAE,GAAG,EAAE,IAChD,MAAM,GACN,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC;AAEjC,eAAO,MAAM,cAAc,GAAI,MAAM,EAAE,KAAK,SAAS,GAAG,EAAE,WACpD,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,WACjB,KAAK,WAOf,CAAC"}
package/common.js ADDED
@@ -0,0 +1,6 @@
1
+ export const resolveFnValue = (fn, ...args) => {
2
+ if (typeof fn === 'function') {
3
+ return fn(...args);
4
+ }
5
+ return fn;
6
+ };
package/date-time.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Dayjs } from 'dayjs';
1
+ import dayjs, { Dayjs, ManipulateType } from 'dayjs';
2
2
  import { Maybe } from './utils/types.js';
3
3
  import 'dayjs/locale/ru';
4
4
  export declare const formatDate: (value: Maybe<string | number | Dayjs>, settings?: Maybe<{
@@ -6,10 +6,21 @@ export declare const formatDate: (value: Maybe<string | number | Dayjs>, setting
6
6
  pattern?: string;
7
7
  asTime?: boolean;
8
8
  }>) => string;
9
- export declare const getDatesDuration: (dateA: Date, dateB: Date) => string;
9
+ export declare const dayTimeDuration: (timeInMs: number) => {
10
+ days: number;
11
+ hours: number;
12
+ minutes: number;
13
+ seconds: number;
14
+ milliseconds: number;
15
+ };
16
+ type DateChangeParam = [amount: number, unit?: Maybe<ManipulateType>];
17
+ export declare const changeDate: (date: Maybe<Date | number | string>, amount: number, unit?: Maybe<dayjs.ManipulateType>, amount_1?: number | undefined, unit_1?: Maybe<dayjs.ManipulateType>, amount_2?: number | undefined, unit_2?: Maybe<dayjs.ManipulateType>, amount_3?: number | undefined, unit_3?: Maybe<dayjs.ManipulateType>, amount_4?: number | undefined, unit_4?: Maybe<dayjs.ManipulateType>, amount_5?: number | undefined, unit_5?: Maybe<dayjs.ManipulateType>) => Date;
10
18
  export declare const timeDuration: (timeInMs: number) => {
11
19
  hours: number;
20
+ milliseconds: number;
12
21
  minutes: number;
13
22
  seconds: number;
14
23
  };
24
+ export declare const getDatesFormatDuration: (dateA: Date, dateB: Date, compact?: boolean) => string;
25
+ export {};
15
26
  //# sourceMappingURL=date-time.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"date-time.d.ts","sourceRoot":"","sources":["../src/date-time.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAKrC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,iBAAiB,CAAC;AAwBzB,eAAO,MAAM,UAAU,UACd,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,aAC1B,KAAK,CAAC;IACf,MAAM,CAAC,EACH,OAAO,GACP,MAAM,GACN,OAAO,GACP,KAAK,GACL,UAAU,GACV,MAAM,GACN,OAAO,GACP,YAAY,GACZ,MAAM,GACN,YAAY,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC,WA6CH,CAAC;AAEF,eAAO,MAAM,gBAAgB,UAAW,IAAI,SAAS,IAAI,WAoBxD,CAAC;AAEF,eAAO,MAAM,YAAY,aAAc,MAAM;;;;CAQ5C,CAAC"}
1
+ {"version":3,"file":"date-time.d.ts","sourceRoot":"","sources":["../src/date-time.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAOrD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,iBAAiB,CAAC;AAwBzB,eAAO,MAAM,UAAU,UACd,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,aAC1B,KAAK,CAAC;IACf,MAAM,CAAC,EACH,OAAO,GACP,MAAM,GACN,OAAO,GACP,KAAK,GACL,UAAU,GACV,MAAM,GACN,OAAO,GACP,YAAY,GACZ,MAAM,GACN,YAAY,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC,WA6CH,CAAC;AAEF,eAAO,MAAM,eAAe,aAAc,MAAM;;;;;;CAwB/C,CAAC;AAEF,KAAK,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAEtE,eAAO,MAAM,UAAU,SACf,KAAK,CAAC,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,sZAqBpC,CAAC;AAEF,eAAO,MAAM,YAAY,aAAc,MAAM;;;;;CAU5C,CAAC;AASF,eAAO,MAAM,sBAAsB,UAC1B,IAAI,SACJ,IAAI,YACD,OAAO,WAoDlB,CAAC"}
package/date-time.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import dayjs from 'dayjs';
2
2
  import duration from 'dayjs/plugin/duration';
3
3
  import relativeTime from 'dayjs/plugin/relativeTime';
4
+ import { unitsToMs } from './ms.js';
5
+ import { declension } from './text.js';
4
6
  import { typeGuard } from './type-guard.js';
5
7
  import 'dayjs/locale/ru';
6
8
  dayjs.extend(relativeTime);
@@ -62,35 +64,88 @@ export const formatDate = function (value, settings) {
62
64
  }
63
65
  }
64
66
  };
65
- export const getDatesDuration = (dateA, dateB) => {
67
+ export const dayTimeDuration = (timeInMs) => {
68
+ let left = timeInMs;
69
+ const days = Math.floor(left / unitsToMs.day);
70
+ left = left % unitsToMs.day;
71
+ const hours = Math.floor(left / unitsToMs.hour);
72
+ left = left % unitsToMs.hour;
73
+ const minutes = Math.floor(left / unitsToMs.min);
74
+ left = left % unitsToMs.min;
75
+ const seconds = Math.floor(left / unitsToMs.sec);
76
+ left = left % unitsToMs.sec;
77
+ const milliseconds = Math.floor(left);
78
+ return {
79
+ days,
80
+ hours,
81
+ minutes,
82
+ seconds,
83
+ milliseconds,
84
+ };
85
+ };
86
+ export const changeDate = (date, ...args) => {
87
+ let wrappedDate = dayjs(date);
88
+ for (let i = 0; i < args.length; i += 2) {
89
+ const amount = args[i];
90
+ const unit = args[i + 1];
91
+ if (unit != null) {
92
+ wrappedDate = wrappedDate.add(amount, unit);
93
+ }
94
+ }
95
+ return wrappedDate.toDate();
96
+ };
97
+ export const timeDuration = (timeInMs) => {
98
+ const { days, hours, milliseconds, minutes, seconds } = dayTimeDuration(timeInMs);
99
+ return {
100
+ hours: hours + unitsToMs.day * days,
101
+ milliseconds,
102
+ minutes,
103
+ seconds,
104
+ };
105
+ };
106
+ const durationFormatLabels = {
107
+ days: { compact: 'д', full: ['день', 'дня', 'дней'] },
108
+ hours: { compact: 'ч', full: ['час', 'часа', 'часов'] },
109
+ minutes: { compact: 'мин', full: ['минута', 'минуты', 'минут'] },
110
+ seconds: { compact: 'сек', full: ['секунда', 'секунды', 'секунд'] },
111
+ };
112
+ export const getDatesFormatDuration = (dateA, dateB, compact) => {
66
113
  const startedDate = dayjs(dateA);
67
114
  const endedDate = dayjs(dateB);
68
115
  const diff = endedDate.diff(startedDate, 'ms');
69
- const duration = dayjs.duration(diff);
70
- if (duration.asSeconds() < 1) {
71
- return duration.format('SSS[ мс]');
72
- }
73
- else if (duration.asMinutes() < 1) {
74
- return duration.format('s[ сек]');
75
- }
76
- else if (duration.asHours() < 1) {
77
- return duration.format('m[ мин] s[ сек]');
116
+ const { days, hours, minutes, seconds } = dayTimeDuration(diff);
117
+ const formattedParts = [];
118
+ if (days) {
119
+ if (compact) {
120
+ formattedParts.push(`${days} ${durationFormatLabels.days.compact}`);
121
+ }
122
+ else {
123
+ formattedParts.push(`${days} ${declension(days, durationFormatLabels.days.full)}`);
124
+ }
78
125
  }
79
- else if (duration.asDays() < 1) {
80
- return duration.format('h[ ч] m[ мин] s[ сек]');
126
+ if (hours) {
127
+ if (compact) {
128
+ formattedParts.push(`${hours} ${durationFormatLabels.hours.compact}`);
129
+ }
130
+ else {
131
+ formattedParts.push(`${hours} ${declension(hours, durationFormatLabels.hours.full)}`);
132
+ }
81
133
  }
82
- else if (duration.asMonths() < 1) {
83
- return duration.format('D[ д] H[ ч] m[ мин] s[ сек]');
134
+ if (minutes) {
135
+ if (compact) {
136
+ formattedParts.push(`${minutes} ${durationFormatLabels.minutes.compact}`);
137
+ }
138
+ else {
139
+ formattedParts.push(`${minutes} ${declension(minutes, durationFormatLabels.minutes.full)}`);
140
+ }
84
141
  }
85
- else {
86
- return duration.format('M[ мес] D[ д] H[ ч] m[ мин] s[ сек]');
142
+ if (seconds) {
143
+ if (compact) {
144
+ formattedParts.push(`${seconds} ${durationFormatLabels.seconds.compact}`);
145
+ }
146
+ else {
147
+ formattedParts.push(`${seconds} ${declension(seconds, durationFormatLabels.seconds.full)}`);
148
+ }
87
149
  }
88
- };
89
- export const timeDuration = (timeInMs) => {
90
- const duration = dayjs.duration(timeInMs);
91
- return {
92
- hours: duration.hours(),
93
- minutes: duration.minutes(),
94
- seconds: duration.seconds(),
95
- };
150
+ return formattedParts.join(' ');
96
151
  };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=date-time.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-time.test.d.ts","sourceRoot":"","sources":["../src/date-time.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { changeDate, dayTimeDuration, getDatesFormatDuration, timeDuration, } from './date-time';
3
+ import { unitsToMs } from './ms';
4
+ describe('date-time', () => {
5
+ describe('dayTimeDuration', () => {
6
+ test('1 minute', () => {
7
+ expect(dayTimeDuration(unitsToMs.min)).toStrictEqual({
8
+ days: 0,
9
+ hours: 0,
10
+ seconds: 0,
11
+ minutes: 1,
12
+ milliseconds: 0,
13
+ });
14
+ });
15
+ test('30 minutes 45 seconds', () => {
16
+ expect(dayTimeDuration(unitsToMs.min * 30 + unitsToMs.sec * 45)).toStrictEqual({
17
+ days: 0,
18
+ hours: 0,
19
+ seconds: 45,
20
+ minutes: 30,
21
+ milliseconds: 0,
22
+ });
23
+ });
24
+ test('34 days 59 minutes 59 seconds', () => {
25
+ expect(dayTimeDuration(34 * unitsToMs.day + unitsToMs.min * 59 + unitsToMs.sec * 59)).toStrictEqual({
26
+ days: 34,
27
+ hours: 0,
28
+ minutes: 59,
29
+ seconds: 59,
30
+ milliseconds: 0,
31
+ });
32
+ });
33
+ });
34
+ describe('timeDuration', () => {
35
+ test('1 minute', () => {
36
+ expect(timeDuration(unitsToMs.min)).toStrictEqual({
37
+ hours: 0,
38
+ seconds: 0,
39
+ minutes: 1,
40
+ milliseconds: 0,
41
+ });
42
+ });
43
+ test('30 minutes 45 seconds', () => {
44
+ expect(timeDuration(unitsToMs.min * 30 + unitsToMs.sec * 45)).toStrictEqual({
45
+ hours: 0,
46
+ seconds: 45,
47
+ minutes: 30,
48
+ milliseconds: 0,
49
+ });
50
+ });
51
+ test('34 days 59 minutes 59 seconds', () => {
52
+ expect(timeDuration(34 * unitsToMs.day + unitsToMs.min * 59 + unitsToMs.sec * 59)).toStrictEqual({
53
+ hours: 2_937_600_000,
54
+ minutes: 59,
55
+ seconds: 59,
56
+ milliseconds: 0,
57
+ });
58
+ });
59
+ });
60
+ describe('getDatesFormatDuration', () => {
61
+ test('30 minutes', () => {
62
+ const dateA = new Date(`2025-02-10T09:53:00.000Z`);
63
+ const dateB = changeDate(dateA, 30, 'minutes');
64
+ expect(getDatesFormatDuration(dateA, dateB)).toBe('30 минут');
65
+ });
66
+ test('2 hours 45 minutes 10 seconds', () => {
67
+ const dateA = new Date(`2025-02-10T09:53:00.000Z`);
68
+ const dateB = changeDate(dateA, 2, 'hours', 45, 'minutes', 10, 'seconds');
69
+ expect(getDatesFormatDuration(dateA, dateB)).toBe('2 часа 45 минут 10 секунд');
70
+ });
71
+ test('2 hours 45 minutes 10 seconds (compact)', () => {
72
+ const dateA = new Date(`2025-02-10T09:53:00.000Z`);
73
+ const dateB = changeDate(dateA, 2, 'hours', 45, 'minutes', 10, 'seconds');
74
+ expect(getDatesFormatDuration(dateA, dateB, true)).toBe('2 ч 45 мин 10 сек');
75
+ });
76
+ });
77
+ });
package/ms.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare const MULTIPLY_BY_UNIT: {
1
+ export declare const unitsToMs: {
2
2
  readonly ms: 1;
3
3
  readonly sec: 1000;
4
4
  readonly min: number;
@@ -15,6 +15,5 @@ declare const MULTIPLY_BY_UNIT: {
15
15
  * ms(30, 'sec') // 30_000
16
16
  * ```
17
17
  */
18
- export declare const ms: (value: number, unit?: keyof typeof MULTIPLY_BY_UNIT) => number;
19
- export {};
18
+ export declare const ms: (value: number, unit?: keyof typeof unitsToMs) => number;
20
19
  //# sourceMappingURL=ms.d.ts.map
package/ms.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ms.d.ts","sourceRoot":"","sources":["../src/ms.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,gBAAgB;;;;;;;CAOZ,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,EAAE,UAAW,MAAM,SAAQ,MAAM,OAAO,gBAAgB,WACrC,CAAC"}
1
+ {"version":3,"file":"ms.d.ts","sourceRoot":"","sources":["../src/ms.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;;;;CAOZ,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,EAAE,UAAW,MAAM,SAAQ,MAAM,OAAO,SAAS,WACrC,CAAC"}
package/ms.js CHANGED
@@ -1,4 +1,4 @@
1
- const MULTIPLY_BY_UNIT = {
1
+ export const unitsToMs = {
2
2
  ms: 1,
3
3
  sec: 1000,
4
4
  min: 1000 * 60,
@@ -15,4 +15,4 @@ const MULTIPLY_BY_UNIT = {
15
15
  * ms(30, 'sec') // 30_000
16
16
  * ```
17
17
  */
18
- export const ms = (value, unit = 'ms') => value * MULTIPLY_BY_UNIT[unit];
18
+ export const ms = (value, unit = 'ms') => value * unitsToMs[unit];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yummies",
3
- "version": "3.0.16",
3
+ "version": "3.0.18",
4
4
  "keywords": [],
5
5
  "author": "js2me",
6
6
  "license": "MIT",
@@ -26,11 +26,16 @@
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^20.17.11",
29
+ "@vitejs/plugin-react-swc": "^3.8.0",
30
+ "@vitest/coverage-istanbul": "^3.0.5",
29
31
  "eslint": "^8.57.1",
30
32
  "js2me-eslint-config": "^1.0.7",
31
33
  "js2me-exports-post-build-script": "^2.0.17",
34
+ "jsdom": "^26.0.0",
32
35
  "rimraf": "^6.0.1",
33
- "typescript": "^5.7.2"
36
+ "typescript": "^5.7.2",
37
+ "unplugin-swc": "^1.5.1",
38
+ "vitest": "^3.0.5"
34
39
  },
35
40
  "exports": {
36
41
  "./async": {
@@ -38,6 +43,11 @@
38
43
  "default": "./async.js",
39
44
  "types": "./async.d.ts"
40
45
  },
46
+ "./common": {
47
+ "import": "./common.js",
48
+ "default": "./common.js",
49
+ "types": "./common.d.ts"
50
+ },
41
51
  "./complex": {
42
52
  "import": "./complex/index.js",
43
53
  "default": "./complex/index.js",
@@ -58,6 +68,11 @@
58
68
  "default": "./css.js",
59
69
  "types": "./css.d.ts"
60
70
  },
71
+ "./date-time.test": {
72
+ "import": "./date-time.test.js",
73
+ "default": "./date-time.test.js",
74
+ "types": "./date-time.test.d.ts"
75
+ },
61
76
  "./date-time": {
62
77
  "import": "./date-time.js",
63
78
  "default": "./date-time.js",
@@ -147,6 +162,10 @@
147
162
  "build": "tsc && node ./post-build.mjs",
148
163
  "pub:patch": "PUBLISH=true PUBLISH_VERSION=patch pnpm run build",
149
164
  "pub:minor": "PUBLISH=true PUBLISH_VERSION=minor pnpm run build",
150
- "pub:major": "PUBLISH=true PUBLISH_VERSION=major pnpm run build"
165
+ "pub:major": "PUBLISH=true PUBLISH_VERSION=major pnpm run build",
166
+ "test": "vitest run",
167
+ "test:watch": "vitest watch",
168
+ "test:coverage": "vitest run --coverage",
169
+ "dev": "pnpm test:watch"
151
170
  }
152
171
  }
package/text.d.ts CHANGED
@@ -7,5 +7,5 @@
7
7
  * @example
8
8
  * declension(5, ['слово', 'слова', 'слов']) // 'слов'
9
9
  */
10
- export declare const declension: (count: number, txt: [one: string, two: string, five: string], cases?: number[]) => string;
10
+ export declare const declension: (count: number, txt: readonly [one: string, two: string, five: string], cases?: number[]) => string;
11
11
  //# sourceMappingURL=text.d.ts.map
package/text.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,UACd,MAAM,OACR,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,6BAGgC,CAAC"}
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,UACd,MAAM,OACR,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,6BAGuB,CAAC"}