@verifyhash/climate-normals 0.1.0 → 0.1.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/LICENSE +1 -1
- package/README.md +2 -12
- package/index.d.ts +166 -0
- package/package.json +4 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
# climate-normals
|
|
2
2
|
|
|
3
|
-
<!-- publish-prep -->
|
|
4
|
-
> **TODO (owner): pick the final npm name/scope before publishing.**
|
|
5
|
-
> The npm package name is **not** finalized by this project. Convention used here:
|
|
6
|
-
> `package.json` keeps the working slug `climate-normals` as a placeholder — replace it
|
|
7
|
-
> (and the `npm install` line below) with the real published name/scope before
|
|
8
|
-
> running `npm publish`.
|
|
9
|
-
|
|
10
3
|
A tiny, **zero-dependency** Node library of climate math over **monthly
|
|
11
4
|
normals** — heating/cooling degree-days, apparent ("feels like") temperature,
|
|
12
5
|
diurnal range, a continentality index, and a monthly pleasantness score.
|
|
@@ -198,15 +191,12 @@ MIT.
|
|
|
198
191
|
|
|
199
192
|
## Install
|
|
200
193
|
|
|
201
|
-
> Placeholder name: the `climate-normals` below is the working slug, not a finalized
|
|
202
|
-
> npm name — see the owner TODO near the top of this README.
|
|
203
|
-
|
|
204
194
|
```sh
|
|
205
|
-
npm install climate-normals
|
|
195
|
+
npm install @verifyhash/climate-normals
|
|
206
196
|
```
|
|
207
197
|
|
|
208
198
|
```js
|
|
209
|
-
const climate = require('climate-normals');
|
|
199
|
+
const climate = require('@verifyhash/climate-normals');
|
|
210
200
|
|
|
211
201
|
const july = { hi: 23.5, lo: 14.0, pr: 45, rh: 65, ws: 3.2 };
|
|
212
202
|
climate.meanTemp(july); // 18.75 (°C, midpoint of hi/lo)
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type declarations for @verifyhash/climate-normals — zero-dependency climate
|
|
3
|
+
* math over monthly normals.
|
|
4
|
+
*
|
|
5
|
+
* The canonical month object is { hi, lo, pr?, rh?, ws? }: average daily high
|
|
6
|
+
* / low temperature (°C), monthly precipitation (mm, pleasantness only),
|
|
7
|
+
* relative humidity (%, apparent-temp only), wind speed (m/s, apparent-temp
|
|
8
|
+
* only). Functions only read the fields they document. "months" arrays are in
|
|
9
|
+
* calendar order (index 0 = January); year-summarising functions require
|
|
10
|
+
* exactly 12 entries.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** One month of normals. Only hi/lo are always required. */
|
|
14
|
+
export interface MonthNormal {
|
|
15
|
+
/** Average daily HIGH temperature, °C. */
|
|
16
|
+
hi: number;
|
|
17
|
+
/** Average daily LOW temperature, °C. */
|
|
18
|
+
lo: number;
|
|
19
|
+
/** Average monthly PRECIPITATION, mm (pleasantness only). */
|
|
20
|
+
pr?: number;
|
|
21
|
+
/** Average RELATIVE HUMIDITY, % (apparent-temp only). */
|
|
22
|
+
rh?: number;
|
|
23
|
+
/** Average WIND SPEED, m/s (apparent-temp only). */
|
|
24
|
+
ws?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Non-leap days per month (Feb = 28). */
|
|
28
|
+
export const DAYS_IN_MONTH: number[];
|
|
29
|
+
/** Default degree-day base temperature, °C (18). */
|
|
30
|
+
export const HDD_BASE: number;
|
|
31
|
+
/** Comfort band lower bound, °C mean daily temperature (18). */
|
|
32
|
+
export const COMFORT_LO: number;
|
|
33
|
+
/** Comfort band upper bound, °C mean daily temperature (24). */
|
|
34
|
+
export const COMFORT_HI: number;
|
|
35
|
+
/** Rain penalty per mm for the pleasantness heuristic (0.03). */
|
|
36
|
+
export const RAIN_PENALTY_PER_MM: number;
|
|
37
|
+
/** Avg high (°C) at/above which the heat index applies (27). */
|
|
38
|
+
export const FEELS_WARM_HI: number;
|
|
39
|
+
/** Avg low (°C) at/below which wind chill applies (10). */
|
|
40
|
+
export const FEELS_COLD_LO: number;
|
|
41
|
+
|
|
42
|
+
/** Mean daily temperature of a month = (hi + lo) / 2, in °C. */
|
|
43
|
+
export function meanTemp(month: { hi: number; lo: number }): number;
|
|
44
|
+
|
|
45
|
+
/** Result of degreeDays(). */
|
|
46
|
+
export interface DegreeDaysResult {
|
|
47
|
+
/** Per-month raw (unrounded) degree-days. */
|
|
48
|
+
rows: Array<{ i: number; mean: number; hdd: number; cdd: number }>;
|
|
49
|
+
/** Rounded annual heating degree-day total. */
|
|
50
|
+
hdd: number;
|
|
51
|
+
/** Rounded annual cooling degree-day total. */
|
|
52
|
+
cdd: number;
|
|
53
|
+
/** Whichever total is larger (ties count as heating). */
|
|
54
|
+
dominated: 'heating' | 'cooling';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Heating & cooling degree-days for a year of monthly normals (exactly 12
|
|
59
|
+
* months, Jan..Dec). Base defaults to 18 °C.
|
|
60
|
+
*/
|
|
61
|
+
export function degreeDays(
|
|
62
|
+
months: Array<{ hi: number; lo: number }>,
|
|
63
|
+
base?: number
|
|
64
|
+
): DegreeDaysResult;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* NWS Heat Index (Rothfusz regression): apparent temperature in °C for air
|
|
68
|
+
* temperature tC (°C) and relative humidity rh (%).
|
|
69
|
+
*/
|
|
70
|
+
export function heatIndex(tC: number, rh: number): number;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* NWS wind chill (2001 revision): apparent temperature in °C for air
|
|
74
|
+
* temperature tC (°C) and wind speed ws (m/s). Below ~4.8 km/h wind the air
|
|
75
|
+
* temperature is returned unchanged; never warmer than tC.
|
|
76
|
+
*/
|
|
77
|
+
export function windChill(tC: number, ws: number): number;
|
|
78
|
+
|
|
79
|
+
/** Options for apparentTemperature(). */
|
|
80
|
+
export interface ApparentTemperatureOptions {
|
|
81
|
+
/** Avg high (°C) at/above which the heat index applies (default 27). */
|
|
82
|
+
warmThreshold?: number;
|
|
83
|
+
/** Avg low (°C) at/below which wind chill applies (default 10). */
|
|
84
|
+
coldThreshold?: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Result of apparentTemperature(). */
|
|
88
|
+
export interface ApparentTemperatureResult {
|
|
89
|
+
feelsHi: number;
|
|
90
|
+
feelsLo: number;
|
|
91
|
+
hiMode: 'actual' | 'heat';
|
|
92
|
+
loMode: 'actual' | 'wind';
|
|
93
|
+
/** feelsHi - hi (≥ 0): how much hotter humidity makes the day. */
|
|
94
|
+
dHot: number;
|
|
95
|
+
/** lo - feelsLo (≥ 0): how much colder wind makes the night. */
|
|
96
|
+
dCold: number;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Apparent ("feels like") daily high and low for one month of normals,
|
|
101
|
+
* folding in humidity (heat index) and/or wind (wind chill) when the
|
|
102
|
+
* thresholds are met.
|
|
103
|
+
*/
|
|
104
|
+
export function apparentTemperature(
|
|
105
|
+
month: { hi: number; lo: number; rh?: number; ws?: number },
|
|
106
|
+
opts?: ApparentTemperatureOptions
|
|
107
|
+
): ApparentTemperatureResult;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Day-to-night temperature swing across a year (exactly 12 months). `annual`
|
|
111
|
+
* is the mean of the 12 swings; `big`/`small` are the month indices of the
|
|
112
|
+
* largest and smallest swings (first month wins ties).
|
|
113
|
+
*/
|
|
114
|
+
export function diurnalRange(months: Array<{ hi: number; lo: number }>): {
|
|
115
|
+
swings: number[];
|
|
116
|
+
annual: number;
|
|
117
|
+
big: number;
|
|
118
|
+
small: number;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Annual mean-temperature range and its continentality classification
|
|
123
|
+
* (exactly 12 months). `warm`/`cold` are month indices; `range` is rounded to
|
|
124
|
+
* one decimal °C; `klass` is 'maritime / oceanic',
|
|
125
|
+
* 'transitional / moderately continental', or 'continental'.
|
|
126
|
+
*/
|
|
127
|
+
export function continentality(months: Array<{ hi: number; lo: number }>): {
|
|
128
|
+
warm: number;
|
|
129
|
+
cold: number;
|
|
130
|
+
warmMean: number;
|
|
131
|
+
coldMean: number;
|
|
132
|
+
range: number;
|
|
133
|
+
klass: string;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Pleasantness (comfort) score for a single month — LOWER is more
|
|
138
|
+
* comfortable; a month inside the 18–24 °C band with no rain scores 0.
|
|
139
|
+
*/
|
|
140
|
+
export function pleasantnessScore(month: {
|
|
141
|
+
hi: number;
|
|
142
|
+
lo: number;
|
|
143
|
+
pr?: number;
|
|
144
|
+
}): {
|
|
145
|
+
mean: number;
|
|
146
|
+
tempPenalty: number;
|
|
147
|
+
rainPenalty: number;
|
|
148
|
+
score: number;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Rank a year of months (exactly 12) from most to least pleasant. `ranked`
|
|
153
|
+
* holds month indices best-first; ties keep calendar order.
|
|
154
|
+
*/
|
|
155
|
+
export function rankMonths(
|
|
156
|
+
months: Array<{ hi: number; lo: number; pr?: number }>
|
|
157
|
+
): {
|
|
158
|
+
scored: Array<{
|
|
159
|
+
i: number;
|
|
160
|
+
mean: number;
|
|
161
|
+
tempPenalty: number;
|
|
162
|
+
rainPenalty: number;
|
|
163
|
+
score: number;
|
|
164
|
+
}>;
|
|
165
|
+
ranked: number[];
|
|
166
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verifyhash/climate-normals",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Zero-dependency climate math over monthly normals: heating/cooling degree-days, apparent (\"feels like\") temperature, diurnal range, a continentality index, and a monthly pleasantness score.",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
6
7
|
"type": "commonjs",
|
|
7
8
|
"scripts": {
|
|
8
9
|
"test": "node test/index.test.js"
|
|
@@ -23,7 +24,8 @@
|
|
|
23
24
|
"license": "MIT",
|
|
24
25
|
"files": [
|
|
25
26
|
"index.js",
|
|
26
|
-
"README.md"
|
|
27
|
+
"README.md",
|
|
28
|
+
"index.d.ts"
|
|
27
29
|
],
|
|
28
30
|
"publishConfig": {
|
|
29
31
|
"access": "public"
|