neaps 0.3.0 → 0.4.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/dist/index.cjs +21 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -5
- package/dist/index.d.ts +18 -5
- package/dist/index.js +21 -9
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -1,33 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
-
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
-
key = keys[i];
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
-
__defProp(to, key, {
|
|
14
|
-
get: ((k) => from[k]).bind(null, key),
|
|
15
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return to;
|
|
21
|
-
};
|
|
22
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
-
value: mod,
|
|
24
|
-
enumerable: true
|
|
25
|
-
}) : target, mod));
|
|
26
|
-
|
|
27
|
-
//#endregion
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
28
2
|
let _neaps_tide_database = require("@neaps/tide-database");
|
|
29
3
|
let _neaps_tide_predictor = require("@neaps/tide-predictor");
|
|
30
|
-
_neaps_tide_predictor = __toESM(_neaps_tide_predictor);
|
|
31
4
|
|
|
32
5
|
//#region src/index.ts
|
|
33
6
|
const feetPerMeter = 3.2808399;
|
|
@@ -95,7 +68,7 @@ function useStation(station, distance) {
|
|
|
95
68
|
if (station.type === "subordinate" && station.offsets?.reference) reference = findStation(station.offsets?.reference);
|
|
96
69
|
const { datums, harmonic_constituents } = reference;
|
|
97
70
|
const defaultDatum = "MLLW" in datums ? "MLLW" : void 0;
|
|
98
|
-
function getPredictor({ datum = defaultDatum } = {}) {
|
|
71
|
+
function getPredictor({ datum = defaultDatum, nodeCorrections } = {}) {
|
|
99
72
|
let offset = 0;
|
|
100
73
|
if (datum) {
|
|
101
74
|
const datumOffset = datums?.[datum];
|
|
@@ -104,7 +77,10 @@ function useStation(station, distance) {
|
|
|
104
77
|
if (typeof mslOffset !== "number") throw new Error(`Station ${station.id} missing MSL datum, so predictions can't be given in ${datum}.`);
|
|
105
78
|
offset = mslOffset - datumOffset;
|
|
106
79
|
}
|
|
107
|
-
return (0, _neaps_tide_predictor.
|
|
80
|
+
return (0, _neaps_tide_predictor.createTidePredictor)(harmonic_constituents, {
|
|
81
|
+
offset,
|
|
82
|
+
nodeCorrections
|
|
83
|
+
});
|
|
108
84
|
}
|
|
109
85
|
return {
|
|
110
86
|
...station,
|
|
@@ -112,36 +88,45 @@ function useStation(station, distance) {
|
|
|
112
88
|
datums,
|
|
113
89
|
harmonic_constituents,
|
|
114
90
|
defaultDatum,
|
|
115
|
-
getExtremesPrediction({ datum = defaultDatum, units = defaultUnits, ...options }) {
|
|
91
|
+
getExtremesPrediction({ datum = defaultDatum, units = defaultUnits, nodeCorrections, ...options }) {
|
|
116
92
|
return {
|
|
117
93
|
datum,
|
|
118
94
|
units,
|
|
119
95
|
station,
|
|
120
96
|
distance,
|
|
121
|
-
extremes: getPredictor({
|
|
97
|
+
extremes: getPredictor({
|
|
98
|
+
datum,
|
|
99
|
+
nodeCorrections
|
|
100
|
+
}).getExtremesPrediction({
|
|
122
101
|
...options,
|
|
123
102
|
offsets: station.offsets
|
|
124
103
|
}).map((e) => toPreferredUnits(e, units))
|
|
125
104
|
};
|
|
126
105
|
},
|
|
127
|
-
getTimelinePrediction({ datum = defaultDatum, units = defaultUnits, ...options }) {
|
|
106
|
+
getTimelinePrediction({ datum = defaultDatum, units = defaultUnits, nodeCorrections, ...options }) {
|
|
128
107
|
if (station.type === "subordinate") throw new Error(`Timeline predictions are not supported for subordinate stations.`);
|
|
129
108
|
return {
|
|
130
109
|
datum,
|
|
131
110
|
units,
|
|
132
111
|
station,
|
|
133
112
|
distance,
|
|
134
|
-
timeline: getPredictor({
|
|
113
|
+
timeline: getPredictor({
|
|
114
|
+
datum,
|
|
115
|
+
nodeCorrections
|
|
116
|
+
}).getTimelinePrediction(options).map((e) => toPreferredUnits(e, units))
|
|
135
117
|
};
|
|
136
118
|
},
|
|
137
|
-
getWaterLevelAtTime({ time, datum = defaultDatum, units = defaultUnits }) {
|
|
119
|
+
getWaterLevelAtTime({ time, datum = defaultDatum, units = defaultUnits, nodeCorrections }) {
|
|
138
120
|
if (station.type === "subordinate") throw new Error(`Water level predictions are not supported for subordinate stations.`);
|
|
139
121
|
return {
|
|
140
122
|
datum,
|
|
141
123
|
units,
|
|
142
124
|
station,
|
|
143
125
|
distance,
|
|
144
|
-
...toPreferredUnits(getPredictor({
|
|
126
|
+
...toPreferredUnits(getPredictor({
|
|
127
|
+
datum,
|
|
128
|
+
nodeCorrections
|
|
129
|
+
}).getWaterLevelAtTime({ time }), units)
|
|
145
130
|
};
|
|
146
131
|
}
|
|
147
132
|
};
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["stations"],"sources":["../src/index.ts"],"sourcesContent":["import {\n stations,\n near,\n nearest,\n type Station,\n type NearOptions,\n type NearestOptions,\n} from \"@neaps/tide-database\";\nimport
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["stations"],"sources":["../src/index.ts"],"sourcesContent":["import {\n stations,\n near,\n nearest,\n type Station,\n type NearOptions,\n type NearestOptions,\n} from \"@neaps/tide-database\";\nimport { createTidePredictor, type TimeSpan, type ExtremesInput } from \"@neaps/tide-predictor\";\n\ntype Units = \"meters\" | \"feet\";\ntype PredictionOptions = {\n /** Datum to return predictions in. Defaults to 'MLLW' if available for the nearest station. */\n datum?: string;\n\n /** Units for returned water levels. Defaults to 'meters'. */\n units?: Units;\n\n /** Nodal correction fundamentals. Defaults to 'iho'. */\n nodeCorrections?: \"iho\" | \"schureman\";\n};\n\nexport type ExtremesOptions = ExtremesInput & PredictionOptions;\nexport type TimelineOptions = TimeSpan & PredictionOptions;\nexport type WaterLevelOptions = { time: Date } & PredictionOptions;\n\nconst feetPerMeter = 3.2808399;\nconst defaultUnits: Units = \"meters\";\n\n/**\n * Get extremes prediction using the nearest station to the given position.\n *\n * @example\n * ```ts\n * import { getExtremesPrediction } from 'neaps'\n *\n * const prediction = getExtremesPrediction({\n * latitude: 26.7, // or `lat`\n * longitude: -80.05, // or `lng` or `lon`\n * start: new Date('2025-12-17'),\n * end: new Date('2025-12-18'),\n * datum: 'MLLW', // optional, defaults to MLLW if available\n * })\n */\nexport function getExtremesPrediction(options: NearestOptions & ExtremesOptions) {\n return nearestStation(options).getExtremesPrediction(options);\n}\n\n/**\n * Get timeline prediction using the nearest station to the given position.\n */\nexport function getTimelinePrediction(options: NearestOptions & TimelineOptions) {\n return nearestStation(options).getTimelinePrediction(options);\n}\n\n/**\n * Get water level at a specific time using the nearest station to the given position.\n */\nexport function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions) {\n return nearestStation(options).getWaterLevelAtTime(options);\n}\n\n/**\n * Find the nearest station to the given position.\n */\nexport function nearestStation(options: NearestOptions) {\n const data = nearest(options);\n if (!data) throw new Error(`No stations found with options: ${JSON.stringify(options)}`);\n return useStation(...data);\n}\n\n/**\n * Find stations near the given position.\n * @param limit Maximum number of stations to return (default: 10)\n */\nexport function stationsNear(options: NearOptions) {\n return near(options).map(([station, distance]) => useStation(station, distance));\n}\n\n/**\n * Find a specific station by its ID or source ID.\n */\nexport function findStation(query: string) {\n const searches = [(s: Station) => s.id === query, (s: Station) => s.source.id === query];\n\n let found: Station | undefined = undefined;\n\n for (const search of searches) {\n found = stations.find(search);\n if (found) break;\n }\n\n if (!found) throw new Error(`Station not found: ${query}`);\n\n return useStation(found);\n}\n\nexport function useStation(station: Station, distance?: number) {\n // If subordinate station, use the reference station for datums and constituents\n let reference = station;\n if (station.type === \"subordinate\" && station.offsets?.reference) {\n reference = findStation(station.offsets?.reference);\n }\n const { datums, harmonic_constituents } = reference;\n\n // Use MLLW as the default datum if available\n const defaultDatum = \"MLLW\" in datums ? \"MLLW\" : undefined;\n\n function getPredictor({ datum = defaultDatum, nodeCorrections }: PredictionOptions = {}) {\n let offset = 0;\n\n if (datum) {\n const datumOffset = datums?.[datum];\n const mslOffset = datums?.[\"MSL\"];\n\n if (typeof datumOffset !== \"number\") {\n throw new Error(\n `Station ${station.id} missing ${datum} datum. Available datums: ${Object.keys(datums).join(\", \")}`,\n );\n }\n\n if (typeof mslOffset !== \"number\") {\n throw new Error(\n `Station ${station.id} missing MSL datum, so predictions can't be given in ${datum}.`,\n );\n }\n\n offset = mslOffset - datumOffset;\n }\n\n return createTidePredictor(harmonic_constituents, { offset, nodeCorrections });\n }\n\n return {\n ...station,\n distance,\n datums,\n harmonic_constituents,\n defaultDatum,\n getExtremesPrediction({\n datum = defaultDatum,\n units = defaultUnits,\n nodeCorrections,\n ...options\n }: ExtremesOptions) {\n const extremes = getPredictor({ datum, nodeCorrections })\n .getExtremesPrediction({ ...options, offsets: station.offsets })\n .map((e) => toPreferredUnits(e, units));\n\n return { datum, units, station, distance, extremes };\n },\n\n getTimelinePrediction({\n datum = defaultDatum,\n units = defaultUnits,\n nodeCorrections,\n ...options\n }: TimelineOptions) {\n if (station.type === \"subordinate\") {\n throw new Error(`Timeline predictions are not supported for subordinate stations.`);\n }\n const timeline = getPredictor({ datum, nodeCorrections })\n .getTimelinePrediction(options)\n .map((e) => toPreferredUnits(e, units));\n\n return { datum, units, station, distance, timeline };\n },\n\n getWaterLevelAtTime({\n time,\n datum = defaultDatum,\n units = defaultUnits,\n nodeCorrections,\n }: WaterLevelOptions) {\n if (station.type === \"subordinate\") {\n throw new Error(`Water level predictions are not supported for subordinate stations.`);\n }\n\n const prediction = toPreferredUnits(\n getPredictor({ datum, nodeCorrections }).getWaterLevelAtTime({ time }),\n units,\n );\n\n return { datum, units, station, distance, ...prediction };\n },\n };\n}\n\nfunction toPreferredUnits<T extends { level: number }>(prediction: T, units: Units): T {\n let { level } = prediction;\n if (units === \"feet\") level *= feetPerMeter;\n else if (units !== \"meters\") throw new Error(`Unsupported units: ${units}`);\n return { ...prediction, level };\n}\n"],"mappings":";;;;;AA0BA,MAAM,eAAe;AACrB,MAAM,eAAsB;;;;;;;;;;;;;;;;AAiB5B,SAAgB,sBAAsB,SAA2C;AAC/E,QAAO,eAAe,QAAQ,CAAC,sBAAsB,QAAQ;;;;;AAM/D,SAAgB,sBAAsB,SAA2C;AAC/E,QAAO,eAAe,QAAQ,CAAC,sBAAsB,QAAQ;;;;;AAM/D,SAAgB,oBAAoB,SAA6C;AAC/E,QAAO,eAAe,QAAQ,CAAC,oBAAoB,QAAQ;;;;;AAM7D,SAAgB,eAAe,SAAyB;CACtD,MAAM,yCAAe,QAAQ;AAC7B,KAAI,CAAC,KAAM,OAAM,IAAI,MAAM,mCAAmC,KAAK,UAAU,QAAQ,GAAG;AACxF,QAAO,WAAW,GAAG,KAAK;;;;;;AAO5B,SAAgB,aAAa,SAAsB;AACjD,uCAAY,QAAQ,CAAC,KAAK,CAAC,SAAS,cAAc,WAAW,SAAS,SAAS,CAAC;;;;;AAMlF,SAAgB,YAAY,OAAe;CACzC,MAAM,WAAW,EAAE,MAAe,EAAE,OAAO,QAAQ,MAAe,EAAE,OAAO,OAAO,MAAM;CAExF,IAAI,QAA6B;AAEjC,MAAK,MAAM,UAAU,UAAU;AAC7B,UAAQA,8BAAS,KAAK,OAAO;AAC7B,MAAI,MAAO;;AAGb,KAAI,CAAC,MAAO,OAAM,IAAI,MAAM,sBAAsB,QAAQ;AAE1D,QAAO,WAAW,MAAM;;AAG1B,SAAgB,WAAW,SAAkB,UAAmB;CAE9D,IAAI,YAAY;AAChB,KAAI,QAAQ,SAAS,iBAAiB,QAAQ,SAAS,UACrD,aAAY,YAAY,QAAQ,SAAS,UAAU;CAErD,MAAM,EAAE,QAAQ,0BAA0B;CAG1C,MAAM,eAAe,UAAU,SAAS,SAAS;CAEjD,SAAS,aAAa,EAAE,QAAQ,cAAc,oBAAuC,EAAE,EAAE;EACvF,IAAI,SAAS;AAEb,MAAI,OAAO;GACT,MAAM,cAAc,SAAS;GAC7B,MAAM,YAAY,SAAS;AAE3B,OAAI,OAAO,gBAAgB,SACzB,OAAM,IAAI,MACR,WAAW,QAAQ,GAAG,WAAW,MAAM,4BAA4B,OAAO,KAAK,OAAO,CAAC,KAAK,KAAK,GAClG;AAGH,OAAI,OAAO,cAAc,SACvB,OAAM,IAAI,MACR,WAAW,QAAQ,GAAG,uDAAuD,MAAM,GACpF;AAGH,YAAS,YAAY;;AAGvB,wDAA2B,uBAAuB;GAAE;GAAQ;GAAiB,CAAC;;AAGhF,QAAO;EACL,GAAG;EACH;EACA;EACA;EACA;EACA,sBAAsB,EACpB,QAAQ,cACR,QAAQ,cACR,iBACA,GAAG,WACe;AAKlB,UAAO;IAAE;IAAO;IAAO;IAAS;IAAU,UAJzB,aAAa;KAAE;KAAO;KAAiB,CAAC,CACtD,sBAAsB;KAAE,GAAG;KAAS,SAAS,QAAQ;KAAS,CAAC,CAC/D,KAAK,MAAM,iBAAiB,GAAG,MAAM,CAAC;IAEW;;EAGtD,sBAAsB,EACpB,QAAQ,cACR,QAAQ,cACR,iBACA,GAAG,WACe;AAClB,OAAI,QAAQ,SAAS,cACnB,OAAM,IAAI,MAAM,mEAAmE;AAMrF,UAAO;IAAE;IAAO;IAAO;IAAS;IAAU,UAJzB,aAAa;KAAE;KAAO;KAAiB,CAAC,CACtD,sBAAsB,QAAQ,CAC9B,KAAK,MAAM,iBAAiB,GAAG,MAAM,CAAC;IAEW;;EAGtD,oBAAoB,EAClB,MACA,QAAQ,cACR,QAAQ,cACR,mBACoB;AACpB,OAAI,QAAQ,SAAS,cACnB,OAAM,IAAI,MAAM,sEAAsE;AAQxF,UAAO;IAAE;IAAO;IAAO;IAAS;IAAU,GALvB,iBACjB,aAAa;KAAE;KAAO;KAAiB,CAAC,CAAC,oBAAoB,EAAE,MAAM,CAAC,EACtE,MACD;IAEwD;;EAE5D;;AAGH,SAAS,iBAA8C,YAAe,OAAiB;CACrF,IAAI,EAAE,UAAU;AAChB,KAAI,UAAU,OAAQ,UAAS;UACtB,UAAU,SAAU,OAAM,IAAI,MAAM,sBAAsB,QAAQ;AAC3E,QAAO;EAAE,GAAG;EAAY;EAAO"}
|
package/dist/index.d.cts
CHANGED
|
@@ -6,7 +6,8 @@ import { ExtremesInput, TimeSpan } from "@neaps/tide-predictor";
|
|
|
6
6
|
type Units = "meters" | "feet";
|
|
7
7
|
type PredictionOptions = {
|
|
8
8
|
/** Datum to return predictions in. Defaults to 'MLLW' if available for the nearest station. */datum?: string; /** Units for returned water levels. Defaults to 'meters'. */
|
|
9
|
-
units?: Units;
|
|
9
|
+
units?: Units; /** Nodal correction fundamentals. Defaults to 'iho'. */
|
|
10
|
+
nodeCorrections?: "iho" | "schureman";
|
|
10
11
|
};
|
|
11
12
|
type ExtremesOptions = ExtremesInput & PredictionOptions;
|
|
12
13
|
type TimelineOptions = TimeSpan & PredictionOptions;
|
|
@@ -60,6 +61,7 @@ declare function nearestStation(options: NearestOptions): {
|
|
|
60
61
|
getExtremesPrediction({
|
|
61
62
|
datum,
|
|
62
63
|
units,
|
|
64
|
+
nodeCorrections,
|
|
63
65
|
...options
|
|
64
66
|
}: ExtremesOptions): {
|
|
65
67
|
datum: any;
|
|
@@ -71,6 +73,7 @@ declare function nearestStation(options: NearestOptions): {
|
|
|
71
73
|
getTimelinePrediction({
|
|
72
74
|
datum,
|
|
73
75
|
units,
|
|
76
|
+
nodeCorrections,
|
|
74
77
|
...options
|
|
75
78
|
}: TimelineOptions): {
|
|
76
79
|
datum: any;
|
|
@@ -82,7 +85,8 @@ declare function nearestStation(options: NearestOptions): {
|
|
|
82
85
|
getWaterLevelAtTime({
|
|
83
86
|
time,
|
|
84
87
|
datum,
|
|
85
|
-
units
|
|
88
|
+
units,
|
|
89
|
+
nodeCorrections
|
|
86
90
|
}: WaterLevelOptions): any;
|
|
87
91
|
id: string;
|
|
88
92
|
name: string;
|
|
@@ -131,6 +135,7 @@ declare function stationsNear(options: NearOptions): {
|
|
|
131
135
|
getExtremesPrediction({
|
|
132
136
|
datum,
|
|
133
137
|
units,
|
|
138
|
+
nodeCorrections,
|
|
134
139
|
...options
|
|
135
140
|
}: ExtremesOptions): {
|
|
136
141
|
datum: any;
|
|
@@ -142,6 +147,7 @@ declare function stationsNear(options: NearOptions): {
|
|
|
142
147
|
getTimelinePrediction({
|
|
143
148
|
datum,
|
|
144
149
|
units,
|
|
150
|
+
nodeCorrections,
|
|
145
151
|
...options
|
|
146
152
|
}: TimelineOptions): {
|
|
147
153
|
datum: any;
|
|
@@ -153,7 +159,8 @@ declare function stationsNear(options: NearOptions): {
|
|
|
153
159
|
getWaterLevelAtTime({
|
|
154
160
|
time,
|
|
155
161
|
datum,
|
|
156
|
-
units
|
|
162
|
+
units,
|
|
163
|
+
nodeCorrections
|
|
157
164
|
}: WaterLevelOptions): any;
|
|
158
165
|
id: string;
|
|
159
166
|
name: string;
|
|
@@ -201,6 +208,7 @@ declare function findStation(query: string): {
|
|
|
201
208
|
getExtremesPrediction({
|
|
202
209
|
datum,
|
|
203
210
|
units,
|
|
211
|
+
nodeCorrections,
|
|
204
212
|
...options
|
|
205
213
|
}: ExtremesOptions): {
|
|
206
214
|
datum: any;
|
|
@@ -212,6 +220,7 @@ declare function findStation(query: string): {
|
|
|
212
220
|
getTimelinePrediction({
|
|
213
221
|
datum,
|
|
214
222
|
units,
|
|
223
|
+
nodeCorrections,
|
|
215
224
|
...options
|
|
216
225
|
}: TimelineOptions): {
|
|
217
226
|
datum: any;
|
|
@@ -223,7 +232,8 @@ declare function findStation(query: string): {
|
|
|
223
232
|
getWaterLevelAtTime({
|
|
224
233
|
time,
|
|
225
234
|
datum,
|
|
226
|
-
units
|
|
235
|
+
units,
|
|
236
|
+
nodeCorrections
|
|
227
237
|
}: WaterLevelOptions): any;
|
|
228
238
|
id: string;
|
|
229
239
|
name: string;
|
|
@@ -268,6 +278,7 @@ declare function useStation(station: Station, distance?: number): {
|
|
|
268
278
|
getExtremesPrediction({
|
|
269
279
|
datum,
|
|
270
280
|
units,
|
|
281
|
+
nodeCorrections,
|
|
271
282
|
...options
|
|
272
283
|
}: ExtremesOptions): {
|
|
273
284
|
datum: any;
|
|
@@ -279,6 +290,7 @@ declare function useStation(station: Station, distance?: number): {
|
|
|
279
290
|
getTimelinePrediction({
|
|
280
291
|
datum,
|
|
281
292
|
units,
|
|
293
|
+
nodeCorrections,
|
|
282
294
|
...options
|
|
283
295
|
}: TimelineOptions): {
|
|
284
296
|
datum: any;
|
|
@@ -290,7 +302,8 @@ declare function useStation(station: Station, distance?: number): {
|
|
|
290
302
|
getWaterLevelAtTime({
|
|
291
303
|
time,
|
|
292
304
|
datum,
|
|
293
|
-
units
|
|
305
|
+
units,
|
|
306
|
+
nodeCorrections
|
|
294
307
|
}: WaterLevelOptions): any;
|
|
295
308
|
id: string;
|
|
296
309
|
name: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ import { ExtremesInput, TimeSpan } from "@neaps/tide-predictor";
|
|
|
6
6
|
type Units = "meters" | "feet";
|
|
7
7
|
type PredictionOptions = {
|
|
8
8
|
/** Datum to return predictions in. Defaults to 'MLLW' if available for the nearest station. */datum?: string; /** Units for returned water levels. Defaults to 'meters'. */
|
|
9
|
-
units?: Units;
|
|
9
|
+
units?: Units; /** Nodal correction fundamentals. Defaults to 'iho'. */
|
|
10
|
+
nodeCorrections?: "iho" | "schureman";
|
|
10
11
|
};
|
|
11
12
|
type ExtremesOptions = ExtremesInput & PredictionOptions;
|
|
12
13
|
type TimelineOptions = TimeSpan & PredictionOptions;
|
|
@@ -60,6 +61,7 @@ declare function nearestStation(options: NearestOptions): {
|
|
|
60
61
|
getExtremesPrediction({
|
|
61
62
|
datum,
|
|
62
63
|
units,
|
|
64
|
+
nodeCorrections,
|
|
63
65
|
...options
|
|
64
66
|
}: ExtremesOptions): {
|
|
65
67
|
datum: any;
|
|
@@ -71,6 +73,7 @@ declare function nearestStation(options: NearestOptions): {
|
|
|
71
73
|
getTimelinePrediction({
|
|
72
74
|
datum,
|
|
73
75
|
units,
|
|
76
|
+
nodeCorrections,
|
|
74
77
|
...options
|
|
75
78
|
}: TimelineOptions): {
|
|
76
79
|
datum: any;
|
|
@@ -82,7 +85,8 @@ declare function nearestStation(options: NearestOptions): {
|
|
|
82
85
|
getWaterLevelAtTime({
|
|
83
86
|
time,
|
|
84
87
|
datum,
|
|
85
|
-
units
|
|
88
|
+
units,
|
|
89
|
+
nodeCorrections
|
|
86
90
|
}: WaterLevelOptions): any;
|
|
87
91
|
id: string;
|
|
88
92
|
name: string;
|
|
@@ -131,6 +135,7 @@ declare function stationsNear(options: NearOptions): {
|
|
|
131
135
|
getExtremesPrediction({
|
|
132
136
|
datum,
|
|
133
137
|
units,
|
|
138
|
+
nodeCorrections,
|
|
134
139
|
...options
|
|
135
140
|
}: ExtremesOptions): {
|
|
136
141
|
datum: any;
|
|
@@ -142,6 +147,7 @@ declare function stationsNear(options: NearOptions): {
|
|
|
142
147
|
getTimelinePrediction({
|
|
143
148
|
datum,
|
|
144
149
|
units,
|
|
150
|
+
nodeCorrections,
|
|
145
151
|
...options
|
|
146
152
|
}: TimelineOptions): {
|
|
147
153
|
datum: any;
|
|
@@ -153,7 +159,8 @@ declare function stationsNear(options: NearOptions): {
|
|
|
153
159
|
getWaterLevelAtTime({
|
|
154
160
|
time,
|
|
155
161
|
datum,
|
|
156
|
-
units
|
|
162
|
+
units,
|
|
163
|
+
nodeCorrections
|
|
157
164
|
}: WaterLevelOptions): any;
|
|
158
165
|
id: string;
|
|
159
166
|
name: string;
|
|
@@ -201,6 +208,7 @@ declare function findStation(query: string): {
|
|
|
201
208
|
getExtremesPrediction({
|
|
202
209
|
datum,
|
|
203
210
|
units,
|
|
211
|
+
nodeCorrections,
|
|
204
212
|
...options
|
|
205
213
|
}: ExtremesOptions): {
|
|
206
214
|
datum: any;
|
|
@@ -212,6 +220,7 @@ declare function findStation(query: string): {
|
|
|
212
220
|
getTimelinePrediction({
|
|
213
221
|
datum,
|
|
214
222
|
units,
|
|
223
|
+
nodeCorrections,
|
|
215
224
|
...options
|
|
216
225
|
}: TimelineOptions): {
|
|
217
226
|
datum: any;
|
|
@@ -223,7 +232,8 @@ declare function findStation(query: string): {
|
|
|
223
232
|
getWaterLevelAtTime({
|
|
224
233
|
time,
|
|
225
234
|
datum,
|
|
226
|
-
units
|
|
235
|
+
units,
|
|
236
|
+
nodeCorrections
|
|
227
237
|
}: WaterLevelOptions): any;
|
|
228
238
|
id: string;
|
|
229
239
|
name: string;
|
|
@@ -268,6 +278,7 @@ declare function useStation(station: Station, distance?: number): {
|
|
|
268
278
|
getExtremesPrediction({
|
|
269
279
|
datum,
|
|
270
280
|
units,
|
|
281
|
+
nodeCorrections,
|
|
271
282
|
...options
|
|
272
283
|
}: ExtremesOptions): {
|
|
273
284
|
datum: any;
|
|
@@ -279,6 +290,7 @@ declare function useStation(station: Station, distance?: number): {
|
|
|
279
290
|
getTimelinePrediction({
|
|
280
291
|
datum,
|
|
281
292
|
units,
|
|
293
|
+
nodeCorrections,
|
|
282
294
|
...options
|
|
283
295
|
}: TimelineOptions): {
|
|
284
296
|
datum: any;
|
|
@@ -290,7 +302,8 @@ declare function useStation(station: Station, distance?: number): {
|
|
|
290
302
|
getWaterLevelAtTime({
|
|
291
303
|
time,
|
|
292
304
|
datum,
|
|
293
|
-
units
|
|
305
|
+
units,
|
|
306
|
+
nodeCorrections
|
|
294
307
|
}: WaterLevelOptions): any;
|
|
295
308
|
id: string;
|
|
296
309
|
name: string;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { near, nearest, stations } from "@neaps/tide-database";
|
|
2
|
-
import
|
|
2
|
+
import { createTidePredictor } from "@neaps/tide-predictor";
|
|
3
3
|
|
|
4
4
|
//#region src/index.ts
|
|
5
5
|
const feetPerMeter = 3.2808399;
|
|
@@ -67,7 +67,7 @@ function useStation(station, distance) {
|
|
|
67
67
|
if (station.type === "subordinate" && station.offsets?.reference) reference = findStation(station.offsets?.reference);
|
|
68
68
|
const { datums, harmonic_constituents } = reference;
|
|
69
69
|
const defaultDatum = "MLLW" in datums ? "MLLW" : void 0;
|
|
70
|
-
function getPredictor({ datum = defaultDatum } = {}) {
|
|
70
|
+
function getPredictor({ datum = defaultDatum, nodeCorrections } = {}) {
|
|
71
71
|
let offset = 0;
|
|
72
72
|
if (datum) {
|
|
73
73
|
const datumOffset = datums?.[datum];
|
|
@@ -76,7 +76,10 @@ function useStation(station, distance) {
|
|
|
76
76
|
if (typeof mslOffset !== "number") throw new Error(`Station ${station.id} missing MSL datum, so predictions can't be given in ${datum}.`);
|
|
77
77
|
offset = mslOffset - datumOffset;
|
|
78
78
|
}
|
|
79
|
-
return
|
|
79
|
+
return createTidePredictor(harmonic_constituents, {
|
|
80
|
+
offset,
|
|
81
|
+
nodeCorrections
|
|
82
|
+
});
|
|
80
83
|
}
|
|
81
84
|
return {
|
|
82
85
|
...station,
|
|
@@ -84,36 +87,45 @@ function useStation(station, distance) {
|
|
|
84
87
|
datums,
|
|
85
88
|
harmonic_constituents,
|
|
86
89
|
defaultDatum,
|
|
87
|
-
getExtremesPrediction({ datum = defaultDatum, units = defaultUnits, ...options }) {
|
|
90
|
+
getExtremesPrediction({ datum = defaultDatum, units = defaultUnits, nodeCorrections, ...options }) {
|
|
88
91
|
return {
|
|
89
92
|
datum,
|
|
90
93
|
units,
|
|
91
94
|
station,
|
|
92
95
|
distance,
|
|
93
|
-
extremes: getPredictor({
|
|
96
|
+
extremes: getPredictor({
|
|
97
|
+
datum,
|
|
98
|
+
nodeCorrections
|
|
99
|
+
}).getExtremesPrediction({
|
|
94
100
|
...options,
|
|
95
101
|
offsets: station.offsets
|
|
96
102
|
}).map((e) => toPreferredUnits(e, units))
|
|
97
103
|
};
|
|
98
104
|
},
|
|
99
|
-
getTimelinePrediction({ datum = defaultDatum, units = defaultUnits, ...options }) {
|
|
105
|
+
getTimelinePrediction({ datum = defaultDatum, units = defaultUnits, nodeCorrections, ...options }) {
|
|
100
106
|
if (station.type === "subordinate") throw new Error(`Timeline predictions are not supported for subordinate stations.`);
|
|
101
107
|
return {
|
|
102
108
|
datum,
|
|
103
109
|
units,
|
|
104
110
|
station,
|
|
105
111
|
distance,
|
|
106
|
-
timeline: getPredictor({
|
|
112
|
+
timeline: getPredictor({
|
|
113
|
+
datum,
|
|
114
|
+
nodeCorrections
|
|
115
|
+
}).getTimelinePrediction(options).map((e) => toPreferredUnits(e, units))
|
|
107
116
|
};
|
|
108
117
|
},
|
|
109
|
-
getWaterLevelAtTime({ time, datum = defaultDatum, units = defaultUnits }) {
|
|
118
|
+
getWaterLevelAtTime({ time, datum = defaultDatum, units = defaultUnits, nodeCorrections }) {
|
|
110
119
|
if (station.type === "subordinate") throw new Error(`Water level predictions are not supported for subordinate stations.`);
|
|
111
120
|
return {
|
|
112
121
|
datum,
|
|
113
122
|
units,
|
|
114
123
|
station,
|
|
115
124
|
distance,
|
|
116
|
-
...toPreferredUnits(getPredictor({
|
|
125
|
+
...toPreferredUnits(getPredictor({
|
|
126
|
+
datum,
|
|
127
|
+
nodeCorrections
|
|
128
|
+
}).getWaterLevelAtTime({ time }), units)
|
|
117
129
|
};
|
|
118
130
|
}
|
|
119
131
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import {\n stations,\n near,\n nearest,\n type Station,\n type NearOptions,\n type NearestOptions,\n} from \"@neaps/tide-database\";\nimport
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import {\n stations,\n near,\n nearest,\n type Station,\n type NearOptions,\n type NearestOptions,\n} from \"@neaps/tide-database\";\nimport { createTidePredictor, type TimeSpan, type ExtremesInput } from \"@neaps/tide-predictor\";\n\ntype Units = \"meters\" | \"feet\";\ntype PredictionOptions = {\n /** Datum to return predictions in. Defaults to 'MLLW' if available for the nearest station. */\n datum?: string;\n\n /** Units for returned water levels. Defaults to 'meters'. */\n units?: Units;\n\n /** Nodal correction fundamentals. Defaults to 'iho'. */\n nodeCorrections?: \"iho\" | \"schureman\";\n};\n\nexport type ExtremesOptions = ExtremesInput & PredictionOptions;\nexport type TimelineOptions = TimeSpan & PredictionOptions;\nexport type WaterLevelOptions = { time: Date } & PredictionOptions;\n\nconst feetPerMeter = 3.2808399;\nconst defaultUnits: Units = \"meters\";\n\n/**\n * Get extremes prediction using the nearest station to the given position.\n *\n * @example\n * ```ts\n * import { getExtremesPrediction } from 'neaps'\n *\n * const prediction = getExtremesPrediction({\n * latitude: 26.7, // or `lat`\n * longitude: -80.05, // or `lng` or `lon`\n * start: new Date('2025-12-17'),\n * end: new Date('2025-12-18'),\n * datum: 'MLLW', // optional, defaults to MLLW if available\n * })\n */\nexport function getExtremesPrediction(options: NearestOptions & ExtremesOptions) {\n return nearestStation(options).getExtremesPrediction(options);\n}\n\n/**\n * Get timeline prediction using the nearest station to the given position.\n */\nexport function getTimelinePrediction(options: NearestOptions & TimelineOptions) {\n return nearestStation(options).getTimelinePrediction(options);\n}\n\n/**\n * Get water level at a specific time using the nearest station to the given position.\n */\nexport function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions) {\n return nearestStation(options).getWaterLevelAtTime(options);\n}\n\n/**\n * Find the nearest station to the given position.\n */\nexport function nearestStation(options: NearestOptions) {\n const data = nearest(options);\n if (!data) throw new Error(`No stations found with options: ${JSON.stringify(options)}`);\n return useStation(...data);\n}\n\n/**\n * Find stations near the given position.\n * @param limit Maximum number of stations to return (default: 10)\n */\nexport function stationsNear(options: NearOptions) {\n return near(options).map(([station, distance]) => useStation(station, distance));\n}\n\n/**\n * Find a specific station by its ID or source ID.\n */\nexport function findStation(query: string) {\n const searches = [(s: Station) => s.id === query, (s: Station) => s.source.id === query];\n\n let found: Station | undefined = undefined;\n\n for (const search of searches) {\n found = stations.find(search);\n if (found) break;\n }\n\n if (!found) throw new Error(`Station not found: ${query}`);\n\n return useStation(found);\n}\n\nexport function useStation(station: Station, distance?: number) {\n // If subordinate station, use the reference station for datums and constituents\n let reference = station;\n if (station.type === \"subordinate\" && station.offsets?.reference) {\n reference = findStation(station.offsets?.reference);\n }\n const { datums, harmonic_constituents } = reference;\n\n // Use MLLW as the default datum if available\n const defaultDatum = \"MLLW\" in datums ? \"MLLW\" : undefined;\n\n function getPredictor({ datum = defaultDatum, nodeCorrections }: PredictionOptions = {}) {\n let offset = 0;\n\n if (datum) {\n const datumOffset = datums?.[datum];\n const mslOffset = datums?.[\"MSL\"];\n\n if (typeof datumOffset !== \"number\") {\n throw new Error(\n `Station ${station.id} missing ${datum} datum. Available datums: ${Object.keys(datums).join(\", \")}`,\n );\n }\n\n if (typeof mslOffset !== \"number\") {\n throw new Error(\n `Station ${station.id} missing MSL datum, so predictions can't be given in ${datum}.`,\n );\n }\n\n offset = mslOffset - datumOffset;\n }\n\n return createTidePredictor(harmonic_constituents, { offset, nodeCorrections });\n }\n\n return {\n ...station,\n distance,\n datums,\n harmonic_constituents,\n defaultDatum,\n getExtremesPrediction({\n datum = defaultDatum,\n units = defaultUnits,\n nodeCorrections,\n ...options\n }: ExtremesOptions) {\n const extremes = getPredictor({ datum, nodeCorrections })\n .getExtremesPrediction({ ...options, offsets: station.offsets })\n .map((e) => toPreferredUnits(e, units));\n\n return { datum, units, station, distance, extremes };\n },\n\n getTimelinePrediction({\n datum = defaultDatum,\n units = defaultUnits,\n nodeCorrections,\n ...options\n }: TimelineOptions) {\n if (station.type === \"subordinate\") {\n throw new Error(`Timeline predictions are not supported for subordinate stations.`);\n }\n const timeline = getPredictor({ datum, nodeCorrections })\n .getTimelinePrediction(options)\n .map((e) => toPreferredUnits(e, units));\n\n return { datum, units, station, distance, timeline };\n },\n\n getWaterLevelAtTime({\n time,\n datum = defaultDatum,\n units = defaultUnits,\n nodeCorrections,\n }: WaterLevelOptions) {\n if (station.type === \"subordinate\") {\n throw new Error(`Water level predictions are not supported for subordinate stations.`);\n }\n\n const prediction = toPreferredUnits(\n getPredictor({ datum, nodeCorrections }).getWaterLevelAtTime({ time }),\n units,\n );\n\n return { datum, units, station, distance, ...prediction };\n },\n };\n}\n\nfunction toPreferredUnits<T extends { level: number }>(prediction: T, units: Units): T {\n let { level } = prediction;\n if (units === \"feet\") level *= feetPerMeter;\n else if (units !== \"meters\") throw new Error(`Unsupported units: ${units}`);\n return { ...prediction, level };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neaps",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Tide predictions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tides",
|
|
7
7
|
"harmonics"
|
|
8
8
|
],
|
|
9
|
-
"homepage": "https://
|
|
9
|
+
"homepage": "https://openwaters.io/tides/neaps",
|
|
10
10
|
"bugs": {
|
|
11
|
-
"url": "https://github.com/
|
|
11
|
+
"url": "https://github.com/openwatersio/neaps/issues"
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "git+https://github.com/
|
|
15
|
+
"url": "git+https://github.com/openwatersio/neaps.git",
|
|
16
16
|
"directory": "packages/neaps"
|
|
17
17
|
},
|
|
18
18
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"prepack": "npm run build"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@neaps/tide-database": "0.
|
|
38
|
-
"@neaps/tide-predictor": "^0.
|
|
37
|
+
"@neaps/tide-database": "0.4",
|
|
38
|
+
"@neaps/tide-predictor": "^0.6.0"
|
|
39
39
|
}
|
|
40
40
|
}
|