neaps 0.5.0 → 0.6.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 +10 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -17,7 +17,7 @@ const defaultUnits = "meters";
|
|
|
17
17
|
* longitude: -80.05, // or `lng` or `lon`
|
|
18
18
|
* start: new Date('2025-12-17'),
|
|
19
19
|
* end: new Date('2025-12-18'),
|
|
20
|
-
* datum: 'MLLW', // optional, defaults to
|
|
20
|
+
* datum: 'MLLW', // optional, defaults to station's datum
|
|
21
21
|
* })
|
|
22
22
|
*/
|
|
23
23
|
function getExtremesPrediction(options) {
|
|
@@ -67,7 +67,7 @@ function useStation(station, distance) {
|
|
|
67
67
|
let reference = station;
|
|
68
68
|
if (station.type === "subordinate" && station.offsets?.reference) reference = findStation(station.offsets?.reference);
|
|
69
69
|
const { datums, harmonic_constituents } = reference;
|
|
70
|
-
const defaultDatum =
|
|
70
|
+
const defaultDatum = station.chart_datum in datums ? station.chart_datum : void 0;
|
|
71
71
|
function getPredictor({ datum = defaultDatum, nodeCorrections } = {}) {
|
|
72
72
|
let offset = 0;
|
|
73
73
|
if (datum) {
|
|
@@ -104,7 +104,6 @@ function useStation(station, distance) {
|
|
|
104
104
|
};
|
|
105
105
|
},
|
|
106
106
|
getTimelinePrediction({ datum = defaultDatum, units = defaultUnits, nodeCorrections, ...options }) {
|
|
107
|
-
if (station.type === "subordinate") throw new Error(`Timeline predictions are not supported for subordinate stations.`);
|
|
108
107
|
return {
|
|
109
108
|
datum,
|
|
110
109
|
units,
|
|
@@ -113,11 +112,13 @@ function useStation(station, distance) {
|
|
|
113
112
|
timeline: getPredictor({
|
|
114
113
|
datum,
|
|
115
114
|
nodeCorrections
|
|
116
|
-
}).getTimelinePrediction(
|
|
115
|
+
}).getTimelinePrediction({
|
|
116
|
+
...options,
|
|
117
|
+
offsets: station.offsets
|
|
118
|
+
}).map((e) => toPreferredUnits(e, units))
|
|
117
119
|
};
|
|
118
120
|
},
|
|
119
121
|
getWaterLevelAtTime({ time, datum = defaultDatum, units = defaultUnits, nodeCorrections }) {
|
|
120
|
-
if (station.type === "subordinate") throw new Error(`Water level predictions are not supported for subordinate stations.`);
|
|
121
122
|
return {
|
|
122
123
|
datum,
|
|
123
124
|
units,
|
|
@@ -126,7 +127,10 @@ function useStation(station, distance) {
|
|
|
126
127
|
...toPreferredUnits(getPredictor({
|
|
127
128
|
datum,
|
|
128
129
|
nodeCorrections
|
|
129
|
-
}).getWaterLevelAtTime({
|
|
130
|
+
}).getWaterLevelAtTime({
|
|
131
|
+
time,
|
|
132
|
+
offsets: station.offsets
|
|
133
|
+
}), units)
|
|
130
134
|
};
|
|
131
135
|
}
|
|
132
136
|
};
|
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 { createTidePredictor, type ExtremesInput, type TimelineInput } from \"@neaps/tide-predictor\";\n\ntype Units = \"meters\" | \"feet\";\ntype PredictionOptions = {\n /** Datum to return predictions in. Defaults to
|
|
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 ExtremesInput, type TimelineInput } from \"@neaps/tide-predictor\";\n\ntype Units = \"meters\" | \"feet\";\ntype PredictionOptions = {\n /** Datum to return predictions in. Defaults to the nearest station's datum. */\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 = TimelineInput & 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 station's datum\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 station chart datum as the default datum if available\n const defaultDatum = station.chart_datum in datums ? station.chart_datum : 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 const timeline = getPredictor({ datum, nodeCorrections })\n .getTimelinePrediction({ ...options, offsets: station.offsets })\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 const prediction = toPreferredUnits(\n getPredictor({ datum, nodeCorrections }).getWaterLevelAtTime({\n time,\n offsets: station.offsets,\n }),\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/dist/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { ExtremesInput, TimelineInput } from "@neaps/tide-predictor";
|
|
|
5
5
|
//#region src/index.d.ts
|
|
6
6
|
type Units = "meters" | "feet";
|
|
7
7
|
type PredictionOptions = {
|
|
8
|
-
/** Datum to return predictions in. Defaults to
|
|
8
|
+
/** Datum to return predictions in. Defaults to the nearest station's datum. */datum?: string; /** Units for returned water levels. Defaults to 'meters'. */
|
|
9
9
|
units?: Units; /** Nodal correction fundamentals. Defaults to 'iho'. */
|
|
10
10
|
nodeCorrections?: "iho" | "schureman";
|
|
11
11
|
};
|
|
@@ -26,7 +26,7 @@ type WaterLevelOptions = {
|
|
|
26
26
|
* longitude: -80.05, // or `lng` or `lon`
|
|
27
27
|
* start: new Date('2025-12-17'),
|
|
28
28
|
* end: new Date('2025-12-18'),
|
|
29
|
-
* datum: 'MLLW', // optional, defaults to
|
|
29
|
+
* datum: 'MLLW', // optional, defaults to station's datum
|
|
30
30
|
* })
|
|
31
31
|
*/
|
|
32
32
|
declare function getExtremesPrediction(options: NearestOptions & ExtremesOptions): {
|
|
@@ -122,6 +122,11 @@ declare function nearestStation(options: NearestOptions): {
|
|
|
122
122
|
low: number;
|
|
123
123
|
};
|
|
124
124
|
};
|
|
125
|
+
chart_datum: string;
|
|
126
|
+
epoch?: {
|
|
127
|
+
start: string;
|
|
128
|
+
end: string;
|
|
129
|
+
};
|
|
125
130
|
};
|
|
126
131
|
/**
|
|
127
132
|
* Find stations near the given position.
|
|
@@ -196,6 +201,11 @@ declare function stationsNear(options: NearOptions): {
|
|
|
196
201
|
low: number;
|
|
197
202
|
};
|
|
198
203
|
};
|
|
204
|
+
chart_datum: string;
|
|
205
|
+
epoch?: {
|
|
206
|
+
start: string;
|
|
207
|
+
end: string;
|
|
208
|
+
};
|
|
199
209
|
}[];
|
|
200
210
|
/**
|
|
201
211
|
* Find a specific station by its ID or source ID.
|
|
@@ -269,6 +279,11 @@ declare function findStation(query: string): {
|
|
|
269
279
|
low: number;
|
|
270
280
|
};
|
|
271
281
|
};
|
|
282
|
+
chart_datum: string;
|
|
283
|
+
epoch?: {
|
|
284
|
+
start: string;
|
|
285
|
+
end: string;
|
|
286
|
+
};
|
|
272
287
|
};
|
|
273
288
|
declare function useStation(station: Station, distance?: number): {
|
|
274
289
|
distance: number | undefined;
|
|
@@ -339,6 +354,11 @@ declare function useStation(station: Station, distance?: number): {
|
|
|
339
354
|
low: number;
|
|
340
355
|
};
|
|
341
356
|
};
|
|
357
|
+
chart_datum: string;
|
|
358
|
+
epoch?: {
|
|
359
|
+
start: string;
|
|
360
|
+
end: string;
|
|
361
|
+
};
|
|
342
362
|
};
|
|
343
363
|
//#endregion
|
|
344
364
|
export { ExtremesOptions, TimelineOptions, WaterLevelOptions, findStation, getExtremesPrediction, getTimelinePrediction, getWaterLevelAtTime, nearestStation, stationsNear, useStation };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { ExtremesInput, TimelineInput } from "@neaps/tide-predictor";
|
|
|
5
5
|
//#region src/index.d.ts
|
|
6
6
|
type Units = "meters" | "feet";
|
|
7
7
|
type PredictionOptions = {
|
|
8
|
-
/** Datum to return predictions in. Defaults to
|
|
8
|
+
/** Datum to return predictions in. Defaults to the nearest station's datum. */datum?: string; /** Units for returned water levels. Defaults to 'meters'. */
|
|
9
9
|
units?: Units; /** Nodal correction fundamentals. Defaults to 'iho'. */
|
|
10
10
|
nodeCorrections?: "iho" | "schureman";
|
|
11
11
|
};
|
|
@@ -26,7 +26,7 @@ type WaterLevelOptions = {
|
|
|
26
26
|
* longitude: -80.05, // or `lng` or `lon`
|
|
27
27
|
* start: new Date('2025-12-17'),
|
|
28
28
|
* end: new Date('2025-12-18'),
|
|
29
|
-
* datum: 'MLLW', // optional, defaults to
|
|
29
|
+
* datum: 'MLLW', // optional, defaults to station's datum
|
|
30
30
|
* })
|
|
31
31
|
*/
|
|
32
32
|
declare function getExtremesPrediction(options: NearestOptions & ExtremesOptions): {
|
|
@@ -122,6 +122,11 @@ declare function nearestStation(options: NearestOptions): {
|
|
|
122
122
|
low: number;
|
|
123
123
|
};
|
|
124
124
|
};
|
|
125
|
+
chart_datum: string;
|
|
126
|
+
epoch?: {
|
|
127
|
+
start: string;
|
|
128
|
+
end: string;
|
|
129
|
+
};
|
|
125
130
|
};
|
|
126
131
|
/**
|
|
127
132
|
* Find stations near the given position.
|
|
@@ -196,6 +201,11 @@ declare function stationsNear(options: NearOptions): {
|
|
|
196
201
|
low: number;
|
|
197
202
|
};
|
|
198
203
|
};
|
|
204
|
+
chart_datum: string;
|
|
205
|
+
epoch?: {
|
|
206
|
+
start: string;
|
|
207
|
+
end: string;
|
|
208
|
+
};
|
|
199
209
|
}[];
|
|
200
210
|
/**
|
|
201
211
|
* Find a specific station by its ID or source ID.
|
|
@@ -269,6 +279,11 @@ declare function findStation(query: string): {
|
|
|
269
279
|
low: number;
|
|
270
280
|
};
|
|
271
281
|
};
|
|
282
|
+
chart_datum: string;
|
|
283
|
+
epoch?: {
|
|
284
|
+
start: string;
|
|
285
|
+
end: string;
|
|
286
|
+
};
|
|
272
287
|
};
|
|
273
288
|
declare function useStation(station: Station, distance?: number): {
|
|
274
289
|
distance: number | undefined;
|
|
@@ -339,6 +354,11 @@ declare function useStation(station: Station, distance?: number): {
|
|
|
339
354
|
low: number;
|
|
340
355
|
};
|
|
341
356
|
};
|
|
357
|
+
chart_datum: string;
|
|
358
|
+
epoch?: {
|
|
359
|
+
start: string;
|
|
360
|
+
end: string;
|
|
361
|
+
};
|
|
342
362
|
};
|
|
343
363
|
//#endregion
|
|
344
364
|
export { ExtremesOptions, TimelineOptions, WaterLevelOptions, findStation, getExtremesPrediction, getTimelinePrediction, getWaterLevelAtTime, nearestStation, stationsNear, useStation };
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ const defaultUnits = "meters";
|
|
|
16
16
|
* longitude: -80.05, // or `lng` or `lon`
|
|
17
17
|
* start: new Date('2025-12-17'),
|
|
18
18
|
* end: new Date('2025-12-18'),
|
|
19
|
-
* datum: 'MLLW', // optional, defaults to
|
|
19
|
+
* datum: 'MLLW', // optional, defaults to station's datum
|
|
20
20
|
* })
|
|
21
21
|
*/
|
|
22
22
|
function getExtremesPrediction(options) {
|
|
@@ -66,7 +66,7 @@ function useStation(station, distance) {
|
|
|
66
66
|
let reference = station;
|
|
67
67
|
if (station.type === "subordinate" && station.offsets?.reference) reference = findStation(station.offsets?.reference);
|
|
68
68
|
const { datums, harmonic_constituents } = reference;
|
|
69
|
-
const defaultDatum =
|
|
69
|
+
const defaultDatum = station.chart_datum in datums ? station.chart_datum : void 0;
|
|
70
70
|
function getPredictor({ datum = defaultDatum, nodeCorrections } = {}) {
|
|
71
71
|
let offset = 0;
|
|
72
72
|
if (datum) {
|
|
@@ -103,7 +103,6 @@ function useStation(station, distance) {
|
|
|
103
103
|
};
|
|
104
104
|
},
|
|
105
105
|
getTimelinePrediction({ datum = defaultDatum, units = defaultUnits, nodeCorrections, ...options }) {
|
|
106
|
-
if (station.type === "subordinate") throw new Error(`Timeline predictions are not supported for subordinate stations.`);
|
|
107
106
|
return {
|
|
108
107
|
datum,
|
|
109
108
|
units,
|
|
@@ -112,11 +111,13 @@ function useStation(station, distance) {
|
|
|
112
111
|
timeline: getPredictor({
|
|
113
112
|
datum,
|
|
114
113
|
nodeCorrections
|
|
115
|
-
}).getTimelinePrediction(
|
|
114
|
+
}).getTimelinePrediction({
|
|
115
|
+
...options,
|
|
116
|
+
offsets: station.offsets
|
|
117
|
+
}).map((e) => toPreferredUnits(e, units))
|
|
116
118
|
};
|
|
117
119
|
},
|
|
118
120
|
getWaterLevelAtTime({ time, datum = defaultDatum, units = defaultUnits, nodeCorrections }) {
|
|
119
|
-
if (station.type === "subordinate") throw new Error(`Water level predictions are not supported for subordinate stations.`);
|
|
120
121
|
return {
|
|
121
122
|
datum,
|
|
122
123
|
units,
|
|
@@ -125,7 +126,10 @@ function useStation(station, distance) {
|
|
|
125
126
|
...toPreferredUnits(getPredictor({
|
|
126
127
|
datum,
|
|
127
128
|
nodeCorrections
|
|
128
|
-
}).getWaterLevelAtTime({
|
|
129
|
+
}).getWaterLevelAtTime({
|
|
130
|
+
time,
|
|
131
|
+
offsets: station.offsets
|
|
132
|
+
}), units)
|
|
129
133
|
};
|
|
130
134
|
}
|
|
131
135
|
};
|
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 { createTidePredictor, type ExtremesInput, type TimelineInput } from \"@neaps/tide-predictor\";\n\ntype Units = \"meters\" | \"feet\";\ntype PredictionOptions = {\n /** Datum to return predictions in. Defaults to
|
|
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 ExtremesInput, type TimelineInput } from \"@neaps/tide-predictor\";\n\ntype Units = \"meters\" | \"feet\";\ntype PredictionOptions = {\n /** Datum to return predictions in. Defaults to the nearest station's datum. */\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 = TimelineInput & 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 station's datum\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 station chart datum as the default datum if available\n const defaultDatum = station.chart_datum in datums ? station.chart_datum : 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 const timeline = getPredictor({ datum, nodeCorrections })\n .getTimelinePrediction({ ...options, offsets: station.offsets })\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 const prediction = toPreferredUnits(\n getPredictor({ datum, nodeCorrections }).getWaterLevelAtTime({\n time,\n offsets: station.offsets,\n }),\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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neaps",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Tide predictions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tides",
|
|
@@ -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.6",
|
|
38
|
+
"@neaps/tide-predictor": "^0.8.0"
|
|
39
39
|
}
|
|
40
40
|
}
|