pace-calculator 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Nicholas Wallace
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,80 @@
1
+ # pace-calculator
2
+
3
+ [![CI](https://github.com/nwallace534/pace-calculator/actions/workflows/ci.yml/badge.svg)](https://github.com/nwallace534/pace-calculator/actions/workflows/ci.yml)
4
+
5
+ A small, UI-agnostic TypeScript library for running pace, time, distance, and split calculations.
6
+
7
+ ## Core tenets
8
+
9
+ - **One conversion path.** Every distance conversion goes through a single meter↔yard ratio, so any rounding stays consistent and never compounds.
10
+ - **UI-agnostic.** The library knows nothing about any app — the same package can power a web app, an iOS app, or anything else.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install pace-calculator
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import {calculatePace, DistanceUnit} from 'pace-calculator';
22
+
23
+ const pace = calculatePace({
24
+ time: {minutes: 20},
25
+ distance: {distanceValue: 5, distanceUnit: DistanceUnit.Kilometers},
26
+ });
27
+ // → {
28
+ // perKilometer: {hours: 0, minutes: 4, seconds: 0, milliseconds: 0},
29
+ // perMile: {hours: 0, minutes: 6, seconds: 26, milliseconds: 244},
30
+ // speedKph: 15,
31
+ // speedMph: 9.32,
32
+ // }
33
+ ```
34
+
35
+ ## API
36
+
37
+ - `calculatePace({ time, distance })` — pace and speed across units
38
+ - `calculateTime({ pace, distance })` — finish time
39
+ - `calculateDistance({ pace, time })` — distance covered
40
+ - `calculateSplits({ time, distance, splitInterval? })` — per-interval splits
41
+ - `getDistanceInAllUnits(distance)` — a distance expressed in km, miles and meters
42
+ - `getTimesForPace({ pace, distances? })` — finish times across multiple distances
43
+
44
+ ### getTimesForPace
45
+
46
+ The most useful function: give it a pace and get the finish time for a whole set of distances at once.
47
+
48
+ Called with just a pace, it uses a default set of standard races — 5K, 10K, half and full marathon:
49
+
50
+ ```ts
51
+ import {getTimesForPace, DistanceUnit} from 'pace-calculator';
52
+
53
+ getTimesForPace({pace: {minutes: 4, unit: DistanceUnit.Kilometers}});
54
+ // → {
55
+ // '5K': {hours: 0, minutes: 20, seconds: 0, milliseconds: 0},
56
+ // '10K': {hours: 0, minutes: 40, seconds: 0, milliseconds: 0},
57
+ // '13.1mi': {hours: 1, minutes: 24, seconds: 19, milliseconds: 793},
58
+ // '26.2mi': {hours: 2, minutes: 48, seconds: 39, milliseconds: 586},
59
+ // }
60
+ ```
61
+
62
+ Pass your own `distances` to use a different set — the keys are your labels, and the result is keyed to match:
63
+
64
+ ```ts
65
+ getTimesForPace({
66
+ pace: {minutes: 4, unit: DistanceUnit.Kilometers},
67
+ distances: {
68
+ Parkrun: {distanceValue: 5, distanceUnit: DistanceUnit.Kilometers},
69
+ 'Track lap': {distanceValue: 400, distanceUnit: DistanceUnit.Meters},
70
+ },
71
+ });
72
+ // → {
73
+ // Parkrun: {hours: 0, minutes: 20, seconds: 0, milliseconds: 0},
74
+ // 'Track lap': {hours: 0, minutes: 1, seconds: 36, milliseconds: 0},
75
+ // }
76
+ ```
77
+
78
+ ## License
79
+
80
+ MIT
@@ -0,0 +1,9 @@
1
+ import { Distance, DistanceInAllUnits, DistanceInputs } from './types/distance';
2
+ import { CalculateSplitsInput, CalculateSplitsOutput, MultiPace, PaceInputs, TimesForPaceInput } from './types/pace';
3
+ import { Time, TimeInputs } from './types/time';
4
+ export declare const calculatePace: ({ time, distance }: PaceInputs) => MultiPace;
5
+ export declare const getTimesForPace: ({ pace, distances, }: TimesForPaceInput) => Record<string, Time>;
6
+ export declare const calculateTime: ({ distance, pace }: TimeInputs) => Time;
7
+ export declare const getDistanceInAllUnits: (distance: Distance) => DistanceInAllUnits;
8
+ export declare const calculateDistance: ({ pace, time }: DistanceInputs) => Distance;
9
+ export declare const calculateSplits: ({ time, distance, splitInterval, }: CalculateSplitsInput) => CalculateSplitsOutput;
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateSplits = exports.calculateDistance = exports.getDistanceInAllUnits = exports.calculateTime = exports.getTimesForPace = exports.calculatePace = void 0;
4
+ const conversion_constants_1 = require("./conversion.constants");
5
+ const distance_1 = require("./types/distance");
6
+ const validation_1 = require("./validation");
7
+ const defaultDistanceList = [
8
+ { distanceValue: 5, distanceUnit: distance_1.DistanceUnit.Kilometers },
9
+ { distanceValue: 10, distanceUnit: distance_1.DistanceUnit.Kilometers },
10
+ { distanceValue: 13.1, distanceUnit: distance_1.DistanceUnit.Miles }, // half
11
+ { distanceValue: 26.2, distanceUnit: distance_1.DistanceUnit.Miles }, // full
12
+ ];
13
+ const defaultDistances = defaultDistanceList.reduce((acc, dist) => {
14
+ acc[`${dist.distanceValue}${distance_1.DistanceUnitShorthand[dist.distanceUnit]}`] =
15
+ dist;
16
+ return acc;
17
+ }, {});
18
+ const calculatePace = ({ time, distance }) => {
19
+ (0, validation_1.validateTime)(time);
20
+ (0, validation_1.validateDistance)(distance);
21
+ const distanceInMeters = getDistanceInMeters(distance);
22
+ const timeInMilliseconds = getTimeInMilliseconds(time);
23
+ const millisecondsPerMeter = timeInMilliseconds / distanceInMeters;
24
+ // Conversion constants
25
+ const metersPerKilometer = conversion_constants_1.ConversionConstants.MetersInOneKilometer;
26
+ const metersPerMile = conversion_constants_1.ConversionConstants.YardsInOneMile / conversion_constants_1.ConversionConstants.YardsInOneMeter;
27
+ // Calculate paces
28
+ const millisecondsPerKilometer = millisecondsPerMeter * metersPerKilometer;
29
+ const millisecondsPerMile = millisecondsPerMeter * metersPerMile;
30
+ // Calculate speeds
31
+ const hours = timeInMilliseconds / (1000 * 60 * 60);
32
+ const kilometers = distanceInMeters / metersPerKilometer;
33
+ const miles = distanceInMeters / metersPerMile;
34
+ const speedKph = Math.round((kilometers / hours) * 100) / 100;
35
+ const speedMph = Math.round((miles / hours) * 100) / 100;
36
+ return {
37
+ perKilometer: getTimeFromMilliseconds(millisecondsPerKilometer),
38
+ perMile: getTimeFromMilliseconds(millisecondsPerMile),
39
+ speedKph,
40
+ speedMph,
41
+ };
42
+ };
43
+ exports.calculatePace = calculatePace;
44
+ const getTimesForPace = ({ pace, distances = defaultDistances, }) => {
45
+ return Object.entries(distances).reduce((acc, [key, distance]) => {
46
+ acc[key] = (0, exports.calculateTime)({ pace, distance });
47
+ return acc;
48
+ }, {});
49
+ };
50
+ exports.getTimesForPace = getTimesForPace;
51
+ const calculateTime = ({ distance, pace }) => {
52
+ (0, validation_1.validatePace)(pace);
53
+ (0, validation_1.validateDistance)(distance);
54
+ const distanceInMeters = getDistanceInMeters(distance);
55
+ const paceInMilliseconds = getTimeInMilliseconds(pace);
56
+ let millisecondsPerMeter;
57
+ switch (pace.unit) {
58
+ case distance_1.DistanceUnit.Meters:
59
+ millisecondsPerMeter = paceInMilliseconds;
60
+ break;
61
+ case distance_1.DistanceUnit.Kilometers:
62
+ millisecondsPerMeter =
63
+ paceInMilliseconds / conversion_constants_1.ConversionConstants.MetersInOneKilometer;
64
+ break;
65
+ case distance_1.DistanceUnit.Miles:
66
+ millisecondsPerMeter =
67
+ paceInMilliseconds /
68
+ (conversion_constants_1.ConversionConstants.YardsInOneMile /
69
+ conversion_constants_1.ConversionConstants.YardsInOneMeter);
70
+ break;
71
+ }
72
+ const totalMillisecondsForDistance = millisecondsPerMeter * distanceInMeters;
73
+ return getTimeFromMilliseconds(totalMillisecondsForDistance);
74
+ };
75
+ exports.calculateTime = calculateTime;
76
+ const getDistanceInAllUnits = (distance) => {
77
+ const inputUnit = distance.distanceUnit;
78
+ const inputValue = distance.distanceValue;
79
+ const meters = getDistanceInMeters(distance);
80
+ const inKilometers = inputUnit === distance_1.DistanceUnit.Kilometers
81
+ ? { distanceValue: inputValue, distanceUnit: distance_1.DistanceUnit.Kilometers }
82
+ : {
83
+ distanceValue: Math.round((meters / conversion_constants_1.ConversionConstants.MetersInOneKilometer) * 100) / 100,
84
+ distanceUnit: distance_1.DistanceUnit.Kilometers,
85
+ };
86
+ const inMeters = inputUnit === distance_1.DistanceUnit.Meters
87
+ ? { distanceValue: inputValue, distanceUnit: distance_1.DistanceUnit.Meters }
88
+ : {
89
+ distanceValue: Math.round(meters * 100) / 100,
90
+ distanceUnit: distance_1.DistanceUnit.Meters,
91
+ };
92
+ const inMiles = inputUnit === distance_1.DistanceUnit.Miles
93
+ ? { distanceValue: inputValue, distanceUnit: distance_1.DistanceUnit.Miles }
94
+ : {
95
+ distanceValue: Math.round((MetersToYards(meters) / conversion_constants_1.ConversionConstants.YardsInOneMile) *
96
+ 100) / 100,
97
+ distanceUnit: distance_1.DistanceUnit.Miles,
98
+ };
99
+ return { inKilometers, inMeters, inMiles };
100
+ };
101
+ exports.getDistanceInAllUnits = getDistanceInAllUnits;
102
+ const calculateDistance = ({ pace, time }) => {
103
+ (0, validation_1.validatePace)(pace);
104
+ (0, validation_1.validateTime)(time);
105
+ const timeInMilliseconds = getTimeInMilliseconds(time);
106
+ const paceInMetersPerMillisecond = getPaceInMetersPerMillisecond(pace);
107
+ const totalMetersDistance = timeInMilliseconds * paceInMetersPerMillisecond;
108
+ return getDistanceInUnitFormat(totalMetersDistance, pace.unit);
109
+ };
110
+ exports.calculateDistance = calculateDistance;
111
+ const calculateSplits = ({ time, distance, splitInterval = 1, }) => {
112
+ (0, validation_1.validateTime)(time);
113
+ (0, validation_1.validateDistance)(distance);
114
+ const totalDistanceInMeters = getDistanceInMeters(distance);
115
+ const totalTimeInMs = getTimeInMilliseconds(time);
116
+ const msPerMeter = totalTimeInMs / totalDistanceInMeters;
117
+ const unit = distance.distanceUnit;
118
+ // Convert split interval to meters
119
+ const splitIntervalInMeters = unit === distance_1.DistanceUnit.Miles
120
+ ? splitInterval *
121
+ (conversion_constants_1.ConversionConstants.YardsInOneMile /
122
+ conversion_constants_1.ConversionConstants.YardsInOneMeter)
123
+ : unit === distance_1.DistanceUnit.Kilometers
124
+ ? splitInterval * conversion_constants_1.ConversionConstants.MetersInOneKilometer
125
+ : splitInterval; // if already in meters
126
+ const splits = [];
127
+ let currentDistanceInMeters = 0;
128
+ let splitNumber = 1;
129
+ while (currentDistanceInMeters + splitIntervalInMeters <
130
+ totalDistanceInMeters) {
131
+ currentDistanceInMeters += splitIntervalInMeters;
132
+ const elapsedMs = currentDistanceInMeters * msPerMeter;
133
+ splits.push({
134
+ splitNumber,
135
+ distance: splitNumber * splitInterval,
136
+ time: getTimeFromMilliseconds(elapsedMs),
137
+ });
138
+ splitNumber++;
139
+ }
140
+ if (currentDistanceInMeters < totalDistanceInMeters) {
141
+ const elapsedMs = totalTimeInMs;
142
+ splits.push({
143
+ splitNumber,
144
+ distance: distance.distanceValue, // full distance
145
+ time: getTimeFromMilliseconds(elapsedMs),
146
+ });
147
+ }
148
+ return splits;
149
+ };
150
+ exports.calculateSplits = calculateSplits;
151
+ const getDistanceInUnitFormat = (totalMetersDistance, distanceUnit) => {
152
+ let distanceValue;
153
+ switch (distanceUnit) {
154
+ case distance_1.DistanceUnit.Kilometers:
155
+ distanceValue =
156
+ totalMetersDistance / conversion_constants_1.ConversionConstants.MetersInOneKilometer;
157
+ break;
158
+ case distance_1.DistanceUnit.Miles:
159
+ distanceValue =
160
+ MetersToYards(totalMetersDistance) / conversion_constants_1.ConversionConstants.YardsInOneMile;
161
+ break;
162
+ case distance_1.DistanceUnit.Meters:
163
+ distanceValue = totalMetersDistance;
164
+ break;
165
+ }
166
+ distanceValue = Math.round(distanceValue * 100) / 100;
167
+ return {
168
+ distanceValue,
169
+ distanceUnit,
170
+ };
171
+ };
172
+ const MetersToYards = (meters) => {
173
+ return meters / conversion_constants_1.METER_YARD_RATIO;
174
+ };
175
+ const getPaceInMetersPerMillisecond = (pace) => {
176
+ const paceInMilliseconds = getTimeInMilliseconds(pace);
177
+ switch (pace.unit) {
178
+ case distance_1.DistanceUnit.Meters:
179
+ return 1 / paceInMilliseconds;
180
+ case distance_1.DistanceUnit.Kilometers:
181
+ return conversion_constants_1.ConversionConstants.MetersInOneKilometer / paceInMilliseconds;
182
+ case distance_1.DistanceUnit.Miles:
183
+ return (conversion_constants_1.ConversionConstants.YardsInOneMile /
184
+ conversion_constants_1.ConversionConstants.YardsInOneMeter /
185
+ paceInMilliseconds);
186
+ }
187
+ };
188
+ const getTimeFromMilliseconds = (totalMilliseconds) => {
189
+ const hours = Math.floor(totalMilliseconds / 3600000);
190
+ const minutes = Math.floor((totalMilliseconds / 60000) % 60);
191
+ const seconds = Math.floor((totalMilliseconds % 60000) / 1000);
192
+ const milliseconds = Math.round(totalMilliseconds % 1000);
193
+ return { hours, minutes, seconds, milliseconds };
194
+ };
195
+ const getDistanceInMeters = (distance) => {
196
+ switch (distance.distanceUnit) {
197
+ case distance_1.DistanceUnit.Kilometers:
198
+ return distance.distanceValue * conversion_constants_1.ConversionConstants.MetersInOneKilometer;
199
+ case distance_1.DistanceUnit.Miles:
200
+ return ((distance.distanceValue * conversion_constants_1.ConversionConstants.YardsInOneMile) /
201
+ conversion_constants_1.ConversionConstants.YardsInOneMeter);
202
+ default:
203
+ return distance.distanceValue;
204
+ }
205
+ };
206
+ const getTimeInMilliseconds = (time) => {
207
+ return ((time?.hours ?? 0) * 3600000 +
208
+ (time?.minutes ?? 0) * 60000 +
209
+ (time?.seconds ?? 0) * 1000 +
210
+ (time?.milliseconds ?? 0));
211
+ };
212
+ //# sourceMappingURL=calculator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculator.js","sourceRoot":"","sources":["../src/calculator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare const ConversionConstants: {
2
+ YardsInOneMeter: number;
3
+ YardsInOneMile: number;
4
+ MetersInOneKilometer: number;
5
+ };
6
+ export declare const METER_YARD_RATIO: number;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.METER_YARD_RATIO = exports.ConversionConstants = void 0;
4
+ exports.ConversionConstants = {
5
+ YardsInOneMeter: 1.09361,
6
+ YardsInOneMile: 1760,
7
+ MetersInOneKilometer: 1000,
8
+ };
9
+ exports.METER_YARD_RATIO = 1 / exports.ConversionConstants.YardsInOneMeter;
10
+ //# sourceMappingURL=conversion.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversion.constants.js","sourceRoot":"","sources":["../src/conversion.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,mBAAmB,GAAG;IACjC,eAAe,EAAE,OAAO;IACxB,cAAc,EAAE,IAAI;IACpB,oBAAoB,EAAE,IAAI;CAC3B,CAAC;AAEW,QAAA,gBAAgB,GAAG,CAAC,GAAG,2BAAmB,CAAC,eAAe,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare enum DistanceUnit {
2
+ Kilometres = "Kilometres",
3
+ Miles = "Miles",
4
+ Metres = "Metres"
5
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DistanceUnit = void 0;
4
+ var DistanceUnit;
5
+ (function (DistanceUnit) {
6
+ DistanceUnit["Kilometres"] = "Kilometres";
7
+ DistanceUnit["Miles"] = "Miles";
8
+ DistanceUnit["Metres"] = "Metres";
9
+ })(DistanceUnit || (exports.DistanceUnit = DistanceUnit = {}));
10
+ //# sourceMappingURL=distance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distance.js","sourceRoot":"","sources":["../src/distance.ts"],"names":[],"mappings":";;;AAAA,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,yCAAyB,CAAA;IACzB,+BAAe,CAAA;IACf,iCAAiB,CAAA;AACnB,CAAC,EAJW,YAAY,4BAAZ,YAAY,QAIvB"}
@@ -0,0 +1,3 @@
1
+ export declare class InvalidInputError extends Error {
2
+ constructor(message: string);
3
+ }
package/dist/error.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidInputError = void 0;
4
+ class InvalidInputError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = 'InvalidInputError';
8
+ }
9
+ }
10
+ exports.InvalidInputError = InvalidInputError;
11
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":";;;AAAA,MAAa,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AALD,8CAKC"}
@@ -0,0 +1,22 @@
1
+ import { DistanceUnit } from "./distance";
2
+ export type Event = {
3
+ value: string;
4
+ distanceValue: string;
5
+ distanceDecimal: string;
6
+ distanceUnit: DistanceUnit;
7
+ eventName: string;
8
+ };
9
+ export declare const Events: {
10
+ value: string;
11
+ label: string;
12
+ distanceValue: string;
13
+ distanceDecimal: string;
14
+ distanceUnit: DistanceUnit;
15
+ }[];
16
+ export declare const EventsOther: {
17
+ value: string;
18
+ label: string;
19
+ distanceValue: string;
20
+ distanceDecimal: string;
21
+ distanceUnit: DistanceUnit;
22
+ }[];
package/dist/events.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventsOther = exports.Events = void 0;
4
+ const distance_1 = require("./distance");
5
+ exports.Events = [
6
+ { value: 'fiveK', label: '5K', distanceValue: '5', distanceDecimal: '0', distanceUnit: distance_1.DistanceUnit.Kilometres },
7
+ // { value: 'tenK', label: '10K', distanceValue: '10', distanceDecimal: '0', distanceUnit: DistanceUnit.Kilometres },
8
+ // { value: 'halfMarathon', label: 'Half-marathon', distanceValue: '13', distanceDecimal: '1', distanceUnit: DistanceUnit.Miles },
9
+ // { value: 'marathon', label: 'Marathon', distanceValue: '26', distanceDecimal: '2', distanceUnit: DistanceUnit.Miles }
10
+ ];
11
+ exports.EventsOther = [
12
+ { value: 'oneHundredMetres', label: '100m', distanceValue: '100', distanceDecimal: '0', distanceUnit: distance_1.DistanceUnit.Metres },
13
+ { value: 'twoHundredMetres', label: '200m', distanceValue: '200', distanceDecimal: '0', distanceUnit: distance_1.DistanceUnit.Metres },
14
+ { value: 'fourHundredMeters', label: '400m', distanceValue: '400', distanceDecimal: '0', distanceUnit: distance_1.DistanceUnit.Metres },
15
+ { value: 'oneK', label: '1K', distanceValue: '1', distanceDecimal: '0', distanceUnit: distance_1.DistanceUnit.Kilometres }
16
+ ];
17
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":";;;AAAA,yCAA0C;AAU7B,QAAA,MAAM,GAAG;IAClB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,uBAAY,CAAC,UAAU,EAAE;IAChH,qHAAqH;IACrH,kIAAkI;IAClI,wHAAwH;CAC3H,CAAA;AAEY,QAAA,WAAW,GAAG;IACvB,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,uBAAY,CAAC,MAAM,EAAE;IAC3H,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,uBAAY,CAAC,MAAM,EAAE;IAC3H,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,uBAAY,CAAC,MAAM,EAAE;IAC5H,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,uBAAY,CAAC,UAAU,EAAE;CAClH,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './calculator';
2
+ export * from './types';
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./calculator"), exports);
18
+ __exportStar(require("./types"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,0CAAwB"}
@@ -0,0 +1,26 @@
1
+ import { PaceInput } from './pace';
2
+ import { PartialTime } from './time';
3
+ export declare enum DistanceUnit {
4
+ Kilometers = "Kilometers",
5
+ Miles = "Miles",
6
+ Meters = "Meters"
7
+ }
8
+ export declare enum ShorthandUnit {
9
+ K = "K",
10
+ M = "M",
11
+ mi = "mi"
12
+ }
13
+ export declare const DistanceUnitShorthand: Record<DistanceUnit, ShorthandUnit>;
14
+ export interface Distance {
15
+ distanceValue: number;
16
+ distanceUnit: DistanceUnit;
17
+ }
18
+ export interface DistanceInputs {
19
+ pace: PaceInput;
20
+ time: PartialTime;
21
+ }
22
+ export interface DistanceInAllUnits {
23
+ inKilometers: Distance;
24
+ inMeters: Distance;
25
+ inMiles: Distance;
26
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DistanceUnitShorthand = exports.ShorthandUnit = exports.DistanceUnit = void 0;
4
+ var DistanceUnit;
5
+ (function (DistanceUnit) {
6
+ DistanceUnit["Kilometers"] = "Kilometers";
7
+ DistanceUnit["Miles"] = "Miles";
8
+ DistanceUnit["Meters"] = "Meters";
9
+ })(DistanceUnit || (exports.DistanceUnit = DistanceUnit = {}));
10
+ var ShorthandUnit;
11
+ (function (ShorthandUnit) {
12
+ ShorthandUnit["K"] = "K";
13
+ ShorthandUnit["M"] = "M";
14
+ ShorthandUnit["mi"] = "mi";
15
+ })(ShorthandUnit || (exports.ShorthandUnit = ShorthandUnit = {}));
16
+ exports.DistanceUnitShorthand = {
17
+ [DistanceUnit.Kilometers]: ShorthandUnit.K,
18
+ [DistanceUnit.Miles]: ShorthandUnit.mi,
19
+ [DistanceUnit.Meters]: ShorthandUnit.M,
20
+ };
21
+ //# sourceMappingURL=distance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distance.js","sourceRoot":"","sources":["../../src/types/distance.ts"],"names":[],"mappings":";;;AAGA,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,yCAAyB,CAAA;IACzB,+BAAe,CAAA;IACf,iCAAiB,CAAA;AACnB,CAAC,EAJW,YAAY,4BAAZ,YAAY,QAIvB;AAED,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,wBAAO,CAAA;IACP,wBAAO,CAAA;IACP,0BAAS,CAAA;AACX,CAAC,EAJW,aAAa,6BAAb,aAAa,QAIxB;AAEY,QAAA,qBAAqB,GAAwC;IACxE,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,CAAC;IAC1C,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,EAAE;IACtC,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC;CACvC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './time';
2
+ export * from './distance';
3
+ export * from './pace';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./time"), exports);
18
+ __exportStar(require("./distance"), exports);
19
+ __exportStar(require("./pace"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,6CAA2B;AAC3B,yCAAuB"}
@@ -0,0 +1,36 @@
1
+ import { Distance, DistanceUnit } from './distance';
2
+ import { PartialTime, Time } from './time';
3
+ export interface PaceInputs {
4
+ distance: Distance;
5
+ time: PartialTime;
6
+ }
7
+ export interface Pace extends Time {
8
+ unit: DistanceUnit;
9
+ }
10
+ export interface PaceInput extends PartialTime {
11
+ unit: DistanceUnit;
12
+ }
13
+ export interface MultiPace {
14
+ perKilometer: Time;
15
+ perMile: Time;
16
+ speedKph: number;
17
+ speedMph: number;
18
+ }
19
+ export interface CalculateSplitsInput {
20
+ time: PartialTime;
21
+ distance: {
22
+ distanceValue: number;
23
+ distanceUnit: DistanceUnit;
24
+ };
25
+ splitInterval?: number;
26
+ }
27
+ export interface Split {
28
+ splitNumber: number;
29
+ distance: number;
30
+ time: Time;
31
+ }
32
+ export type CalculateSplitsOutput = Split[];
33
+ export interface TimesForPaceInput {
34
+ pace: PaceInput;
35
+ distances?: Record<string, Distance>;
36
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=pace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pace.js","sourceRoot":"","sources":["../../src/types/pace.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { Distance } from './distance';
2
+ import { PaceInput } from './pace';
3
+ export interface Time {
4
+ hours: number;
5
+ minutes: number;
6
+ seconds: number;
7
+ milliseconds: number;
8
+ }
9
+ export type PartialTime = Partial<Time>;
10
+ export interface TimeInputs {
11
+ pace: PaceInput;
12
+ distance: Distance;
13
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/types/time.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { Distance } from './types/distance';
2
+ import { PaceInput } from './types/pace';
3
+ import { Time } from './types/time';
4
+ export declare const validateTime: (time: Partial<Time>) => void;
5
+ export declare const validatePace: (pace: PaceInput) => void;
6
+ export declare const validateDistance: (distanceValue: Distance) => void;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateDistance = exports.validatePace = exports.validateTime = void 0;
4
+ const error_1 = require("./error");
5
+ const distance_1 = require("./types/distance");
6
+ const validateTimeUnits = (time, source) => {
7
+ // Validate time object: no negative values, at least one > 0
8
+ const timeValues = [
9
+ time.hours ?? 0,
10
+ time.minutes ?? 0,
11
+ time.seconds ?? 0,
12
+ time.milliseconds ?? 0,
13
+ ];
14
+ if (timeValues.some(v => v < 0)) {
15
+ throw new error_1.InvalidInputError(`${source} values cannot be negative.`);
16
+ }
17
+ if (timeValues.every(v => v === 0)) {
18
+ throw new error_1.InvalidInputError(`At least one ${source.toLowerCase()} value must be greater than zero.`);
19
+ }
20
+ };
21
+ const validateTime = (time) => {
22
+ validateTimeUnits(time, 'Time');
23
+ };
24
+ exports.validateTime = validateTime;
25
+ const validatePace = (pace) => {
26
+ validateTimeUnits(pace, 'Pace time');
27
+ if (!Object.values(distance_1.DistanceUnit).includes(pace.unit)) {
28
+ throw new error_1.InvalidInputError('Invalid distance unit provided.');
29
+ }
30
+ };
31
+ exports.validatePace = validatePace;
32
+ const validateDistance = (distanceValue) => {
33
+ if (distanceValue.distanceValue <= 0) {
34
+ throw new error_1.InvalidInputError('Distance value must be greater than zero.');
35
+ }
36
+ if (!Object.values(distance_1.DistanceUnit).includes(distanceValue.distanceUnit)) {
37
+ throw new error_1.InvalidInputError('Invalid distance unit provided.');
38
+ }
39
+ };
40
+ exports.validateDistance = validateDistance;
41
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":";;;AAAA,mCAA0C;AAC1C,+CAAwD;AAIxD,MAAM,iBAAiB,GAAG,CAAC,IAAmB,EAAE,MAAc,EAAQ,EAAE;IACtE,6DAA6D;IAC7D,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,KAAK,IAAI,CAAC;QACf,IAAI,CAAC,OAAO,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,IAAI,CAAC;QACjB,IAAI,CAAC,YAAY,IAAI,CAAC;KACvB,CAAC;IAEF,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,yBAAiB,CAAC,GAAG,MAAM,6BAA6B,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,yBAAiB,CACzB,gBAAgB,MAAM,CAAC,WAAW,EAAE,mCAAmC,CACxE,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEK,MAAM,YAAY,GAAG,CAAC,IAAmB,EAAQ,EAAE;IACxD,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAClC,CAAC,CAAC;AAFW,QAAA,YAAY,gBAEvB;AAEK,MAAM,YAAY,GAAG,CAAC,IAAe,EAAQ,EAAE;IACpD,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAErC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,uBAAY,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,yBAAiB,CAAC,iCAAiC,CAAC,CAAC;IACjE,CAAC;AACH,CAAC,CAAC;AANW,QAAA,YAAY,gBAMvB;AAEK,MAAM,gBAAgB,GAAG,CAAC,aAAuB,EAAE,EAAE;IAC1D,IAAI,aAAa,CAAC,aAAa,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,yBAAiB,CAAC,2CAA2C,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,uBAAY,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,yBAAiB,CAAC,iCAAiC,CAAC,CAAC;IACjE,CAAC;AACH,CAAC,CAAC;AAPW,QAAA,gBAAgB,oBAO3B"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "pace-calculator",
3
+ "version": "1.0.0",
4
+ "description": "A small, UI-agnostic TypeScript library for running pace, time, distance and split calculations.",
5
+ "keywords": [
6
+ "running",
7
+ "pace",
8
+ "pace-calculator",
9
+ "splits",
10
+ "marathon",
11
+ "distance",
12
+ "speed",
13
+ "typescript"
14
+ ],
15
+ "homepage": "https://github.com/nwallace534/pace-calculator#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/nwallace534/pace-calculator/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/nwallace534/pace-calculator.git"
22
+ },
23
+ "license": "MIT",
24
+ "author": "Nicholas Wallace",
25
+ "main": "dist/index.js",
26
+ "types": "dist/index.d.ts",
27
+ "scripts": {
28
+ "lint": "gts lint",
29
+ "clean": "gts clean",
30
+ "compile": "tsc",
31
+ "compile:clean": "tsc --build --clean && tsc --build",
32
+ "fix": "gts fix",
33
+ "prepare": "npm run compile",
34
+ "prepublishOnly": "npm test",
35
+ "pretest": "npm run compile",
36
+ "posttest": "npm run lint",
37
+ "test": "jest --coverage"
38
+ },
39
+ "files": [
40
+ "dist",
41
+ "README.md",
42
+ "LICENSE"
43
+ ],
44
+ "devDependencies": {
45
+ "@types/jest": "^30.0.0",
46
+ "@types/node": "^25.8.0",
47
+ "gts": "^7.0.0",
48
+ "jest": "^30.4.2",
49
+ "ts-jest": "^29.4.9",
50
+ "typescript": "^6.0.3"
51
+ }
52
+ }