neaps 0.5.1 → 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 CHANGED
@@ -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(options).map((e) => toPreferredUnits(e, units))
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({ time }), units)
130
+ }).getWaterLevelAtTime({
131
+ time,
132
+ offsets: station.offsets
133
+ }), units)
130
134
  };
131
135
  }
132
136
  };
@@ -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 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 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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"}
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
@@ -1,7 +1,6 @@
1
- import * as _neaps_tide_predictor0 from "@neaps/tide-predictor";
2
- import { ExtremesInput, TimelineInput } 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, TimelineInput } from "@neaps/tide-predictor";
5
4
 
6
5
  //#region src/index.d.ts
7
6
  type Units = "meters" | "feet";
@@ -31,34 +30,26 @@ type WaterLevelOptions = {
31
30
  * })
32
31
  */
33
32
  declare function getExtremesPrediction(options: NearestOptions & ExtremesOptions): {
34
- datum: string | undefined;
35
- units: Units;
33
+ datum: any;
34
+ units: any;
36
35
  station: Station;
37
36
  distance: number | undefined;
38
- extremes: _neaps_tide_predictor0.Extreme[];
37
+ extremes: any;
39
38
  };
40
39
  /**
41
40
  * Get timeline prediction using the nearest station to the given position.
42
41
  */
43
42
  declare function getTimelinePrediction(options: NearestOptions & TimelineOptions): {
44
- datum: string | undefined;
45
- units: Units;
43
+ datum: any;
44
+ units: any;
46
45
  station: Station;
47
46
  distance: number | undefined;
48
- timeline: _neaps_tide_predictor0.TimelinePoint[];
47
+ timeline: any;
49
48
  };
50
49
  /**
51
50
  * Get water level at a specific time using the nearest station to the given position.
52
51
  */
53
- declare function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions): {
54
- time: Date;
55
- hour: number;
56
- level: number;
57
- datum: string | undefined;
58
- units: Units;
59
- station: Station;
60
- distance: number | undefined;
61
- };
52
+ declare function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions): any;
62
53
  /**
63
54
  * Find the nearest station to the given position.
64
55
  */
@@ -73,11 +64,11 @@ declare function nearestStation(options: NearestOptions): {
73
64
  nodeCorrections,
74
65
  ...options
75
66
  }: ExtremesOptions): {
76
- datum: string | undefined;
77
- units: Units;
67
+ datum: any;
68
+ units: any;
78
69
  station: Station;
79
70
  distance: number | undefined;
80
- extremes: _neaps_tide_predictor0.Extreme[];
71
+ extremes: any;
81
72
  };
82
73
  getTimelinePrediction({
83
74
  datum,
@@ -85,26 +76,18 @@ declare function nearestStation(options: NearestOptions): {
85
76
  nodeCorrections,
86
77
  ...options
87
78
  }: TimelineOptions): {
88
- datum: string | undefined;
89
- units: Units;
79
+ datum: any;
80
+ units: any;
90
81
  station: Station;
91
82
  distance: number | undefined;
92
- timeline: _neaps_tide_predictor0.TimelinePoint[];
83
+ timeline: any;
93
84
  };
94
85
  getWaterLevelAtTime({
95
86
  time,
96
87
  datum,
97
88
  units,
98
89
  nodeCorrections
99
- }: WaterLevelOptions): {
100
- time: Date;
101
- hour: number;
102
- level: number;
103
- datum: string | undefined;
104
- units: Units;
105
- station: Station;
106
- distance: number | undefined;
107
- };
90
+ }: WaterLevelOptions): any;
108
91
  id: string;
109
92
  name: string;
110
93
  continent: string;
@@ -160,11 +143,11 @@ declare function stationsNear(options: NearOptions): {
160
143
  nodeCorrections,
161
144
  ...options
162
145
  }: ExtremesOptions): {
163
- datum: string | undefined;
164
- units: Units;
146
+ datum: any;
147
+ units: any;
165
148
  station: Station;
166
149
  distance: number | undefined;
167
- extremes: _neaps_tide_predictor0.Extreme[];
150
+ extremes: any;
168
151
  };
169
152
  getTimelinePrediction({
170
153
  datum,
@@ -172,26 +155,18 @@ declare function stationsNear(options: NearOptions): {
172
155
  nodeCorrections,
173
156
  ...options
174
157
  }: TimelineOptions): {
175
- datum: string | undefined;
176
- units: Units;
158
+ datum: any;
159
+ units: any;
177
160
  station: Station;
178
161
  distance: number | undefined;
179
- timeline: _neaps_tide_predictor0.TimelinePoint[];
162
+ timeline: any;
180
163
  };
181
164
  getWaterLevelAtTime({
182
165
  time,
183
166
  datum,
184
167
  units,
185
168
  nodeCorrections
186
- }: WaterLevelOptions): {
187
- time: Date;
188
- hour: number;
189
- level: number;
190
- datum: string | undefined;
191
- units: Units;
192
- station: Station;
193
- distance: number | undefined;
194
- };
169
+ }: WaterLevelOptions): any;
195
170
  id: string;
196
171
  name: string;
197
172
  continent: string;
@@ -246,11 +221,11 @@ declare function findStation(query: string): {
246
221
  nodeCorrections,
247
222
  ...options
248
223
  }: ExtremesOptions): {
249
- datum: string | undefined;
250
- units: Units;
224
+ datum: any;
225
+ units: any;
251
226
  station: Station;
252
227
  distance: number | undefined;
253
- extremes: _neaps_tide_predictor0.Extreme[];
228
+ extremes: any;
254
229
  };
255
230
  getTimelinePrediction({
256
231
  datum,
@@ -258,26 +233,18 @@ declare function findStation(query: string): {
258
233
  nodeCorrections,
259
234
  ...options
260
235
  }: TimelineOptions): {
261
- datum: string | undefined;
262
- units: Units;
236
+ datum: any;
237
+ units: any;
263
238
  station: Station;
264
239
  distance: number | undefined;
265
- timeline: _neaps_tide_predictor0.TimelinePoint[];
240
+ timeline: any;
266
241
  };
267
242
  getWaterLevelAtTime({
268
243
  time,
269
244
  datum,
270
245
  units,
271
246
  nodeCorrections
272
- }: WaterLevelOptions): {
273
- time: Date;
274
- hour: number;
275
- level: number;
276
- datum: string | undefined;
277
- units: Units;
278
- station: Station;
279
- distance: number | undefined;
280
- };
247
+ }: WaterLevelOptions): any;
281
248
  id: string;
282
249
  name: string;
283
250
  continent: string;
@@ -329,11 +296,11 @@ declare function useStation(station: Station, distance?: number): {
329
296
  nodeCorrections,
330
297
  ...options
331
298
  }: ExtremesOptions): {
332
- datum: string | undefined;
333
- units: Units;
299
+ datum: any;
300
+ units: any;
334
301
  station: Station;
335
302
  distance: number | undefined;
336
- extremes: _neaps_tide_predictor0.Extreme[];
303
+ extremes: any;
337
304
  };
338
305
  getTimelinePrediction({
339
306
  datum,
@@ -341,26 +308,18 @@ declare function useStation(station: Station, distance?: number): {
341
308
  nodeCorrections,
342
309
  ...options
343
310
  }: TimelineOptions): {
344
- datum: string | undefined;
345
- units: Units;
311
+ datum: any;
312
+ units: any;
346
313
  station: Station;
347
314
  distance: number | undefined;
348
- timeline: _neaps_tide_predictor0.TimelinePoint[];
315
+ timeline: any;
349
316
  };
350
317
  getWaterLevelAtTime({
351
318
  time,
352
319
  datum,
353
320
  units,
354
321
  nodeCorrections
355
- }: WaterLevelOptions): {
356
- time: Date;
357
- hour: number;
358
- level: number;
359
- datum: string | undefined;
360
- units: Units;
361
- station: Station;
362
- distance: number | undefined;
363
- };
322
+ }: WaterLevelOptions): any;
364
323
  id: string;
365
324
  name: string;
366
325
  continent: string;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
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, TimelineInput } from "@neaps/tide-predictor";
5
4
 
6
5
  //#region src/index.d.ts
@@ -31,34 +30,26 @@ type WaterLevelOptions = {
31
30
  * })
32
31
  */
33
32
  declare function getExtremesPrediction(options: NearestOptions & ExtremesOptions): {
34
- datum: string | undefined;
35
- units: Units;
33
+ datum: any;
34
+ units: any;
36
35
  station: Station;
37
36
  distance: number | undefined;
38
- extremes: _neaps_tide_predictor0.Extreme[];
37
+ extremes: any;
39
38
  };
40
39
  /**
41
40
  * Get timeline prediction using the nearest station to the given position.
42
41
  */
43
42
  declare function getTimelinePrediction(options: NearestOptions & TimelineOptions): {
44
- datum: string | undefined;
45
- units: Units;
43
+ datum: any;
44
+ units: any;
46
45
  station: Station;
47
46
  distance: number | undefined;
48
- timeline: _neaps_tide_predictor0.TimelinePoint[];
47
+ timeline: any;
49
48
  };
50
49
  /**
51
50
  * Get water level at a specific time using the nearest station to the given position.
52
51
  */
53
- declare function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions): {
54
- time: Date;
55
- hour: number;
56
- level: number;
57
- datum: string | undefined;
58
- units: Units;
59
- station: Station;
60
- distance: number | undefined;
61
- };
52
+ declare function getWaterLevelAtTime(options: NearestOptions & WaterLevelOptions): any;
62
53
  /**
63
54
  * Find the nearest station to the given position.
64
55
  */
@@ -73,11 +64,11 @@ declare function nearestStation(options: NearestOptions): {
73
64
  nodeCorrections,
74
65
  ...options
75
66
  }: ExtremesOptions): {
76
- datum: string | undefined;
77
- units: Units;
67
+ datum: any;
68
+ units: any;
78
69
  station: Station;
79
70
  distance: number | undefined;
80
- extremes: _neaps_tide_predictor0.Extreme[];
71
+ extremes: any;
81
72
  };
82
73
  getTimelinePrediction({
83
74
  datum,
@@ -85,26 +76,18 @@ declare function nearestStation(options: NearestOptions): {
85
76
  nodeCorrections,
86
77
  ...options
87
78
  }: TimelineOptions): {
88
- datum: string | undefined;
89
- units: Units;
79
+ datum: any;
80
+ units: any;
90
81
  station: Station;
91
82
  distance: number | undefined;
92
- timeline: _neaps_tide_predictor0.TimelinePoint[];
83
+ timeline: any;
93
84
  };
94
85
  getWaterLevelAtTime({
95
86
  time,
96
87
  datum,
97
88
  units,
98
89
  nodeCorrections
99
- }: WaterLevelOptions): {
100
- time: Date;
101
- hour: number;
102
- level: number;
103
- datum: string | undefined;
104
- units: Units;
105
- station: Station;
106
- distance: number | undefined;
107
- };
90
+ }: WaterLevelOptions): any;
108
91
  id: string;
109
92
  name: string;
110
93
  continent: string;
@@ -160,11 +143,11 @@ declare function stationsNear(options: NearOptions): {
160
143
  nodeCorrections,
161
144
  ...options
162
145
  }: ExtremesOptions): {
163
- datum: string | undefined;
164
- units: Units;
146
+ datum: any;
147
+ units: any;
165
148
  station: Station;
166
149
  distance: number | undefined;
167
- extremes: _neaps_tide_predictor0.Extreme[];
150
+ extremes: any;
168
151
  };
169
152
  getTimelinePrediction({
170
153
  datum,
@@ -172,26 +155,18 @@ declare function stationsNear(options: NearOptions): {
172
155
  nodeCorrections,
173
156
  ...options
174
157
  }: TimelineOptions): {
175
- datum: string | undefined;
176
- units: Units;
158
+ datum: any;
159
+ units: any;
177
160
  station: Station;
178
161
  distance: number | undefined;
179
- timeline: _neaps_tide_predictor0.TimelinePoint[];
162
+ timeline: any;
180
163
  };
181
164
  getWaterLevelAtTime({
182
165
  time,
183
166
  datum,
184
167
  units,
185
168
  nodeCorrections
186
- }: WaterLevelOptions): {
187
- time: Date;
188
- hour: number;
189
- level: number;
190
- datum: string | undefined;
191
- units: Units;
192
- station: Station;
193
- distance: number | undefined;
194
- };
169
+ }: WaterLevelOptions): any;
195
170
  id: string;
196
171
  name: string;
197
172
  continent: string;
@@ -246,11 +221,11 @@ declare function findStation(query: string): {
246
221
  nodeCorrections,
247
222
  ...options
248
223
  }: ExtremesOptions): {
249
- datum: string | undefined;
250
- units: Units;
224
+ datum: any;
225
+ units: any;
251
226
  station: Station;
252
227
  distance: number | undefined;
253
- extremes: _neaps_tide_predictor0.Extreme[];
228
+ extremes: any;
254
229
  };
255
230
  getTimelinePrediction({
256
231
  datum,
@@ -258,26 +233,18 @@ declare function findStation(query: string): {
258
233
  nodeCorrections,
259
234
  ...options
260
235
  }: TimelineOptions): {
261
- datum: string | undefined;
262
- units: Units;
236
+ datum: any;
237
+ units: any;
263
238
  station: Station;
264
239
  distance: number | undefined;
265
- timeline: _neaps_tide_predictor0.TimelinePoint[];
240
+ timeline: any;
266
241
  };
267
242
  getWaterLevelAtTime({
268
243
  time,
269
244
  datum,
270
245
  units,
271
246
  nodeCorrections
272
- }: WaterLevelOptions): {
273
- time: Date;
274
- hour: number;
275
- level: number;
276
- datum: string | undefined;
277
- units: Units;
278
- station: Station;
279
- distance: number | undefined;
280
- };
247
+ }: WaterLevelOptions): any;
281
248
  id: string;
282
249
  name: string;
283
250
  continent: string;
@@ -329,11 +296,11 @@ declare function useStation(station: Station, distance?: number): {
329
296
  nodeCorrections,
330
297
  ...options
331
298
  }: ExtremesOptions): {
332
- datum: string | undefined;
333
- units: Units;
299
+ datum: any;
300
+ units: any;
334
301
  station: Station;
335
302
  distance: number | undefined;
336
- extremes: _neaps_tide_predictor0.Extreme[];
303
+ extremes: any;
337
304
  };
338
305
  getTimelinePrediction({
339
306
  datum,
@@ -341,26 +308,18 @@ declare function useStation(station: Station, distance?: number): {
341
308
  nodeCorrections,
342
309
  ...options
343
310
  }: TimelineOptions): {
344
- datum: string | undefined;
345
- units: Units;
311
+ datum: any;
312
+ units: any;
346
313
  station: Station;
347
314
  distance: number | undefined;
348
- timeline: _neaps_tide_predictor0.TimelinePoint[];
315
+ timeline: any;
349
316
  };
350
317
  getWaterLevelAtTime({
351
318
  time,
352
319
  datum,
353
320
  units,
354
321
  nodeCorrections
355
- }: WaterLevelOptions): {
356
- time: Date;
357
- hour: number;
358
- level: number;
359
- datum: string | undefined;
360
- units: Units;
361
- station: Station;
362
- distance: number | undefined;
363
- };
322
+ }: WaterLevelOptions): any;
364
323
  id: string;
365
324
  name: string;
366
325
  continent: string;
package/dist/index.js CHANGED
@@ -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(options).map((e) => toPreferredUnits(e, units))
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({ time }), units)
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 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 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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"}
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.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Tide predictions",
5
5
  "keywords": [
6
6
  "tides",
@@ -35,6 +35,6 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@neaps/tide-database": "0.6",
38
- "@neaps/tide-predictor": "^0.7.0"
38
+ "@neaps/tide-predictor": "^0.8.0"
39
39
  }
40
40
  }