neaps 0.3.1 → 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 CHANGED
@@ -1,33 +1,6 @@
1
- //#region rolldown:runtime
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.default)(harmonic_constituents, { offset });
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({ datum }).getExtremesPrediction({
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({ datum }).getTimelinePrediction(options).map((e) => toPreferredUnits(e, units))
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({ datum }).getWaterLevelAtTime({ time }), units)
126
+ ...toPreferredUnits(getPredictor({
127
+ datum,
128
+ nodeCorrections
129
+ }).getWaterLevelAtTime({ time }), units)
145
130
  };
146
131
  }
147
132
  };
@@ -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 tidePredictor, { 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\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 }: 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 tidePredictor(harmonic_constituents, { offset });\n }\n\n return {\n ...station,\n distance,\n datums,\n harmonic_constituents,\n defaultDatum,\n getExtremesPrediction({\n datum = defaultDatum,\n units = defaultUnits,\n ...options\n }: ExtremesOptions) {\n const extremes = getPredictor({ datum })\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 ...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 })\n .getTimelinePrediction(options)\n .map((e) => toPreferredUnits(e, units));\n\n return { datum, units, station, distance, timeline };\n },\n\n getWaterLevelAtTime({ time, datum = defaultDatum, units = defaultUnits }: 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 }).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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"}
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":"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"}
package/dist/index.d.cts CHANGED
@@ -1,13 +1,13 @@
1
- import * as _neaps_tide_predictor0 from "@neaps/tide-predictor";
2
- import { ExtremesInput, TimeSpan } from "@neaps/tide-predictor";
3
1
  import * as _neaps_tide_database0 from "@neaps/tide-database";
4
2
  import { NearOptions, NearestOptions, Station } from "@neaps/tide-database";
3
+ import { ExtremesInput, TimeSpan } from "@neaps/tide-predictor";
5
4
 
6
5
  //#region src/index.d.ts
7
6
  type Units = "meters" | "feet";
8
7
  type PredictionOptions = {
9
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'. */
10
- units?: Units;
9
+ units?: Units; /** Nodal correction fundamentals. Defaults to 'iho'. */
10
+ nodeCorrections?: "iho" | "schureman";
11
11
  };
12
12
  type ExtremesOptions = ExtremesInput & PredictionOptions;
13
13
  type TimelineOptions = TimeSpan & PredictionOptions;
@@ -30,34 +30,26 @@ type WaterLevelOptions = {
30
30
  * })
31
31
  */
32
32
  declare function getExtremesPrediction(options: NearestOptions & ExtremesOptions): {
33
- datum: string | undefined;
34
- units: Units;
33
+ datum: any;
34
+ units: any;
35
35
  station: Station;
36
36
  distance: number | undefined;
37
- extremes: _neaps_tide_predictor0.Extreme[];
37
+ extremes: any;
38
38
  };
39
39
  /**
40
40
  * Get timeline prediction using the nearest station to the given position.
41
41
  */
42
42
  declare function getTimelinePrediction(options: NearestOptions & TimelineOptions): {
43
- datum: string | undefined;
44
- units: Units;
43
+ datum: any;
44
+ units: any;
45
45
  station: Station;
46
46
  distance: number | undefined;
47
- timeline: _neaps_tide_predictor0.TimelinePoint[];
47
+ timeline: any;
48
48
  };
49
49
  /**
50
50
  * Get water level at a specific time using the nearest station to the given position.
51
51
  */
52
- declare function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions): {
53
- time: Date;
54
- hour: number;
55
- level: number;
56
- datum: string | undefined;
57
- units: Units;
58
- station: Station;
59
- distance: number | undefined;
60
- };
52
+ declare function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions): any;
61
53
  /**
62
54
  * Find the nearest station to the given position.
63
55
  */
@@ -69,38 +61,33 @@ declare function nearestStation(options: NearestOptions): {
69
61
  getExtremesPrediction({
70
62
  datum,
71
63
  units,
64
+ nodeCorrections,
72
65
  ...options
73
66
  }: ExtremesOptions): {
74
- datum: string | undefined;
75
- units: Units;
67
+ datum: any;
68
+ units: any;
76
69
  station: Station;
77
70
  distance: number | undefined;
78
- extremes: _neaps_tide_predictor0.Extreme[];
71
+ extremes: any;
79
72
  };
80
73
  getTimelinePrediction({
81
74
  datum,
82
75
  units,
76
+ nodeCorrections,
83
77
  ...options
84
78
  }: TimelineOptions): {
85
- datum: string | undefined;
86
- units: Units;
79
+ datum: any;
80
+ units: any;
87
81
  station: Station;
88
82
  distance: number | undefined;
89
- timeline: _neaps_tide_predictor0.TimelinePoint[];
83
+ timeline: any;
90
84
  };
91
85
  getWaterLevelAtTime({
92
86
  time,
93
87
  datum,
94
- units
95
- }: WaterLevelOptions): {
96
- time: Date;
97
- hour: number;
98
- level: number;
99
- datum: string | undefined;
100
- units: Units;
101
- station: Station;
102
- distance: number | undefined;
103
- };
88
+ units,
89
+ nodeCorrections
90
+ }: WaterLevelOptions): any;
104
91
  id: string;
105
92
  name: string;
106
93
  continent: string;
@@ -148,38 +135,33 @@ declare function stationsNear(options: NearOptions): {
148
135
  getExtremesPrediction({
149
136
  datum,
150
137
  units,
138
+ nodeCorrections,
151
139
  ...options
152
140
  }: ExtremesOptions): {
153
- datum: string | undefined;
154
- units: Units;
141
+ datum: any;
142
+ units: any;
155
143
  station: Station;
156
144
  distance: number | undefined;
157
- extremes: _neaps_tide_predictor0.Extreme[];
145
+ extremes: any;
158
146
  };
159
147
  getTimelinePrediction({
160
148
  datum,
161
149
  units,
150
+ nodeCorrections,
162
151
  ...options
163
152
  }: TimelineOptions): {
164
- datum: string | undefined;
165
- units: Units;
153
+ datum: any;
154
+ units: any;
166
155
  station: Station;
167
156
  distance: number | undefined;
168
- timeline: _neaps_tide_predictor0.TimelinePoint[];
157
+ timeline: any;
169
158
  };
170
159
  getWaterLevelAtTime({
171
160
  time,
172
161
  datum,
173
- units
174
- }: WaterLevelOptions): {
175
- time: Date;
176
- hour: number;
177
- level: number;
178
- datum: string | undefined;
179
- units: Units;
180
- station: Station;
181
- distance: number | undefined;
182
- };
162
+ units,
163
+ nodeCorrections
164
+ }: WaterLevelOptions): any;
183
165
  id: string;
184
166
  name: string;
185
167
  continent: string;
@@ -226,38 +208,33 @@ declare function findStation(query: string): {
226
208
  getExtremesPrediction({
227
209
  datum,
228
210
  units,
211
+ nodeCorrections,
229
212
  ...options
230
213
  }: ExtremesOptions): {
231
- datum: string | undefined;
232
- units: Units;
214
+ datum: any;
215
+ units: any;
233
216
  station: Station;
234
217
  distance: number | undefined;
235
- extremes: _neaps_tide_predictor0.Extreme[];
218
+ extremes: any;
236
219
  };
237
220
  getTimelinePrediction({
238
221
  datum,
239
222
  units,
223
+ nodeCorrections,
240
224
  ...options
241
225
  }: TimelineOptions): {
242
- datum: string | undefined;
243
- units: Units;
226
+ datum: any;
227
+ units: any;
244
228
  station: Station;
245
229
  distance: number | undefined;
246
- timeline: _neaps_tide_predictor0.TimelinePoint[];
230
+ timeline: any;
247
231
  };
248
232
  getWaterLevelAtTime({
249
233
  time,
250
234
  datum,
251
- units
252
- }: WaterLevelOptions): {
253
- time: Date;
254
- hour: number;
255
- level: number;
256
- datum: string | undefined;
257
- units: Units;
258
- station: Station;
259
- distance: number | undefined;
260
- };
235
+ units,
236
+ nodeCorrections
237
+ }: WaterLevelOptions): any;
261
238
  id: string;
262
239
  name: string;
263
240
  continent: string;
@@ -301,38 +278,33 @@ declare function useStation(station: Station, distance?: number): {
301
278
  getExtremesPrediction({
302
279
  datum,
303
280
  units,
281
+ nodeCorrections,
304
282
  ...options
305
283
  }: ExtremesOptions): {
306
- datum: string | undefined;
307
- units: Units;
284
+ datum: any;
285
+ units: any;
308
286
  station: Station;
309
287
  distance: number | undefined;
310
- extremes: _neaps_tide_predictor0.Extreme[];
288
+ extremes: any;
311
289
  };
312
290
  getTimelinePrediction({
313
291
  datum,
314
292
  units,
293
+ nodeCorrections,
315
294
  ...options
316
295
  }: TimelineOptions): {
317
- datum: string | undefined;
318
- units: Units;
296
+ datum: any;
297
+ units: any;
319
298
  station: Station;
320
299
  distance: number | undefined;
321
- timeline: _neaps_tide_predictor0.TimelinePoint[];
300
+ timeline: any;
322
301
  };
323
302
  getWaterLevelAtTime({
324
303
  time,
325
304
  datum,
326
- units
327
- }: WaterLevelOptions): {
328
- time: Date;
329
- hour: number;
330
- level: number;
331
- datum: string | undefined;
332
- units: Units;
333
- station: Station;
334
- distance: number | undefined;
335
- };
305
+ units,
306
+ nodeCorrections
307
+ }: WaterLevelOptions): any;
336
308
  id: string;
337
309
  name: string;
338
310
  continent: string;
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import * as _neaps_tide_database0 from "@neaps/tide-database";
2
2
  import { NearOptions, NearestOptions, Station } from "@neaps/tide-database";
3
- import * as _neaps_tide_predictor0 from "@neaps/tide-predictor";
4
3
  import { ExtremesInput, TimeSpan } from "@neaps/tide-predictor";
5
4
 
6
5
  //#region src/index.d.ts
7
6
  type Units = "meters" | "feet";
8
7
  type PredictionOptions = {
9
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'. */
10
- units?: Units;
9
+ units?: Units; /** Nodal correction fundamentals. Defaults to 'iho'. */
10
+ nodeCorrections?: "iho" | "schureman";
11
11
  };
12
12
  type ExtremesOptions = ExtremesInput & PredictionOptions;
13
13
  type TimelineOptions = TimeSpan & PredictionOptions;
@@ -30,34 +30,26 @@ type WaterLevelOptions = {
30
30
  * })
31
31
  */
32
32
  declare function getExtremesPrediction(options: NearestOptions & ExtremesOptions): {
33
- datum: string | undefined;
34
- units: Units;
33
+ datum: any;
34
+ units: any;
35
35
  station: Station;
36
36
  distance: number | undefined;
37
- extremes: _neaps_tide_predictor0.Extreme[];
37
+ extremes: any;
38
38
  };
39
39
  /**
40
40
  * Get timeline prediction using the nearest station to the given position.
41
41
  */
42
42
  declare function getTimelinePrediction(options: NearestOptions & TimelineOptions): {
43
- datum: string | undefined;
44
- units: Units;
43
+ datum: any;
44
+ units: any;
45
45
  station: Station;
46
46
  distance: number | undefined;
47
- timeline: _neaps_tide_predictor0.TimelinePoint[];
47
+ timeline: any;
48
48
  };
49
49
  /**
50
50
  * Get water level at a specific time using the nearest station to the given position.
51
51
  */
52
- declare function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions): {
53
- time: Date;
54
- hour: number;
55
- level: number;
56
- datum: string | undefined;
57
- units: Units;
58
- station: Station;
59
- distance: number | undefined;
60
- };
52
+ declare function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions): any;
61
53
  /**
62
54
  * Find the nearest station to the given position.
63
55
  */
@@ -69,38 +61,33 @@ declare function nearestStation(options: NearestOptions): {
69
61
  getExtremesPrediction({
70
62
  datum,
71
63
  units,
64
+ nodeCorrections,
72
65
  ...options
73
66
  }: ExtremesOptions): {
74
- datum: string | undefined;
75
- units: Units;
67
+ datum: any;
68
+ units: any;
76
69
  station: Station;
77
70
  distance: number | undefined;
78
- extremes: _neaps_tide_predictor0.Extreme[];
71
+ extremes: any;
79
72
  };
80
73
  getTimelinePrediction({
81
74
  datum,
82
75
  units,
76
+ nodeCorrections,
83
77
  ...options
84
78
  }: TimelineOptions): {
85
- datum: string | undefined;
86
- units: Units;
79
+ datum: any;
80
+ units: any;
87
81
  station: Station;
88
82
  distance: number | undefined;
89
- timeline: _neaps_tide_predictor0.TimelinePoint[];
83
+ timeline: any;
90
84
  };
91
85
  getWaterLevelAtTime({
92
86
  time,
93
87
  datum,
94
- units
95
- }: WaterLevelOptions): {
96
- time: Date;
97
- hour: number;
98
- level: number;
99
- datum: string | undefined;
100
- units: Units;
101
- station: Station;
102
- distance: number | undefined;
103
- };
88
+ units,
89
+ nodeCorrections
90
+ }: WaterLevelOptions): any;
104
91
  id: string;
105
92
  name: string;
106
93
  continent: string;
@@ -148,38 +135,33 @@ declare function stationsNear(options: NearOptions): {
148
135
  getExtremesPrediction({
149
136
  datum,
150
137
  units,
138
+ nodeCorrections,
151
139
  ...options
152
140
  }: ExtremesOptions): {
153
- datum: string | undefined;
154
- units: Units;
141
+ datum: any;
142
+ units: any;
155
143
  station: Station;
156
144
  distance: number | undefined;
157
- extremes: _neaps_tide_predictor0.Extreme[];
145
+ extremes: any;
158
146
  };
159
147
  getTimelinePrediction({
160
148
  datum,
161
149
  units,
150
+ nodeCorrections,
162
151
  ...options
163
152
  }: TimelineOptions): {
164
- datum: string | undefined;
165
- units: Units;
153
+ datum: any;
154
+ units: any;
166
155
  station: Station;
167
156
  distance: number | undefined;
168
- timeline: _neaps_tide_predictor0.TimelinePoint[];
157
+ timeline: any;
169
158
  };
170
159
  getWaterLevelAtTime({
171
160
  time,
172
161
  datum,
173
- units
174
- }: WaterLevelOptions): {
175
- time: Date;
176
- hour: number;
177
- level: number;
178
- datum: string | undefined;
179
- units: Units;
180
- station: Station;
181
- distance: number | undefined;
182
- };
162
+ units,
163
+ nodeCorrections
164
+ }: WaterLevelOptions): any;
183
165
  id: string;
184
166
  name: string;
185
167
  continent: string;
@@ -226,38 +208,33 @@ declare function findStation(query: string): {
226
208
  getExtremesPrediction({
227
209
  datum,
228
210
  units,
211
+ nodeCorrections,
229
212
  ...options
230
213
  }: ExtremesOptions): {
231
- datum: string | undefined;
232
- units: Units;
214
+ datum: any;
215
+ units: any;
233
216
  station: Station;
234
217
  distance: number | undefined;
235
- extremes: _neaps_tide_predictor0.Extreme[];
218
+ extremes: any;
236
219
  };
237
220
  getTimelinePrediction({
238
221
  datum,
239
222
  units,
223
+ nodeCorrections,
240
224
  ...options
241
225
  }: TimelineOptions): {
242
- datum: string | undefined;
243
- units: Units;
226
+ datum: any;
227
+ units: any;
244
228
  station: Station;
245
229
  distance: number | undefined;
246
- timeline: _neaps_tide_predictor0.TimelinePoint[];
230
+ timeline: any;
247
231
  };
248
232
  getWaterLevelAtTime({
249
233
  time,
250
234
  datum,
251
- units
252
- }: WaterLevelOptions): {
253
- time: Date;
254
- hour: number;
255
- level: number;
256
- datum: string | undefined;
257
- units: Units;
258
- station: Station;
259
- distance: number | undefined;
260
- };
235
+ units,
236
+ nodeCorrections
237
+ }: WaterLevelOptions): any;
261
238
  id: string;
262
239
  name: string;
263
240
  continent: string;
@@ -301,38 +278,33 @@ declare function useStation(station: Station, distance?: number): {
301
278
  getExtremesPrediction({
302
279
  datum,
303
280
  units,
281
+ nodeCorrections,
304
282
  ...options
305
283
  }: ExtremesOptions): {
306
- datum: string | undefined;
307
- units: Units;
284
+ datum: any;
285
+ units: any;
308
286
  station: Station;
309
287
  distance: number | undefined;
310
- extremes: _neaps_tide_predictor0.Extreme[];
288
+ extremes: any;
311
289
  };
312
290
  getTimelinePrediction({
313
291
  datum,
314
292
  units,
293
+ nodeCorrections,
315
294
  ...options
316
295
  }: TimelineOptions): {
317
- datum: string | undefined;
318
- units: Units;
296
+ datum: any;
297
+ units: any;
319
298
  station: Station;
320
299
  distance: number | undefined;
321
- timeline: _neaps_tide_predictor0.TimelinePoint[];
300
+ timeline: any;
322
301
  };
323
302
  getWaterLevelAtTime({
324
303
  time,
325
304
  datum,
326
- units
327
- }: WaterLevelOptions): {
328
- time: Date;
329
- hour: number;
330
- level: number;
331
- datum: string | undefined;
332
- units: Units;
333
- station: Station;
334
- distance: number | undefined;
335
- };
305
+ units,
306
+ nodeCorrections
307
+ }: WaterLevelOptions): any;
336
308
  id: string;
337
309
  name: string;
338
310
  continent: string;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { near, nearest, stations } from "@neaps/tide-database";
2
- import tidePredictor from "@neaps/tide-predictor";
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 tidePredictor(harmonic_constituents, { offset });
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({ datum }).getExtremesPrediction({
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({ datum }).getTimelinePrediction(options).map((e) => toPreferredUnits(e, units))
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({ datum }).getWaterLevelAtTime({ time }), units)
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 tidePredictor, { 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\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 }: 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 tidePredictor(harmonic_constituents, { offset });\n }\n\n return {\n ...station,\n distance,\n datums,\n harmonic_constituents,\n defaultDatum,\n getExtremesPrediction({\n datum = defaultDatum,\n units = defaultUnits,\n ...options\n }: ExtremesOptions) {\n const extremes = getPredictor({ datum })\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 ...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 })\n .getTimelinePrediction(options)\n .map((e) => toPreferredUnits(e, units));\n\n return { datum, units, station, distance, timeline };\n },\n\n getWaterLevelAtTime({ time, datum = defaultDatum, units = defaultUnits }: 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 }).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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"}
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.1",
3
+ "version": "0.4.0",
4
4
  "description": "Tide predictions",
5
5
  "keywords": [
6
6
  "tides",
7
7
  "harmonics"
8
8
  ],
9
- "homepage": "https://github.com/neaps/neaps#readme",
9
+ "homepage": "https://openwaters.io/tides/neaps",
10
10
  "bugs": {
11
- "url": "https://github.com/neaps/neaps/issues"
11
+ "url": "https://github.com/openwatersio/neaps/issues"
12
12
  },
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git+https://github.com/neaps/neaps.git",
15
+ "url": "git+https://github.com/openwatersio/neaps.git",
16
16
  "directory": "packages/neaps"
17
17
  },
18
18
  "license": "MIT",
@@ -35,6 +35,6 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@neaps/tide-database": "0.4",
38
- "@neaps/tide-predictor": "^0.5.0"
38
+ "@neaps/tide-predictor": "^0.6.0"
39
39
  }
40
40
  }