local-risk-alert-feed 0.1.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.
Files changed (283) hide show
  1. package/dist/cjs/adapters/index.js +8 -0
  2. package/dist/cjs/adapters/index.js.map +1 -0
  3. package/dist/cjs/adapters/lambda.js +143 -0
  4. package/dist/cjs/adapters/lambda.js.map +1 -0
  5. package/dist/cjs/adapters/vercel.js +119 -0
  6. package/dist/cjs/adapters/vercel.js.map +1 -0
  7. package/dist/cjs/core/alert-aggregator.js +207 -0
  8. package/dist/cjs/core/alert-aggregator.js.map +1 -0
  9. package/dist/cjs/core/alert-feed.js +236 -0
  10. package/dist/cjs/core/alert-feed.js.map +1 -0
  11. package/dist/cjs/core/index.js +22 -0
  12. package/dist/cjs/core/index.js.map +1 -0
  13. package/dist/cjs/core/plugin-registry.js +193 -0
  14. package/dist/cjs/core/plugin-registry.js.map +1 -0
  15. package/dist/cjs/core/plugin-resolver.js +121 -0
  16. package/dist/cjs/core/plugin-resolver.js.map +1 -0
  17. package/dist/cjs/core/time-range.js +67 -0
  18. package/dist/cjs/core/time-range.js.map +1 -0
  19. package/dist/cjs/errors/fetch-error.js +71 -0
  20. package/dist/cjs/errors/fetch-error.js.map +1 -0
  21. package/dist/cjs/errors/index.js +15 -0
  22. package/dist/cjs/errors/index.js.map +1 -0
  23. package/dist/cjs/errors/plugin-error.js +80 -0
  24. package/dist/cjs/errors/plugin-error.js.map +1 -0
  25. package/dist/cjs/errors/validation-error.js +49 -0
  26. package/dist/cjs/errors/validation-error.js.map +1 -0
  27. package/dist/cjs/geo/distance.js +94 -0
  28. package/dist/cjs/geo/distance.js.map +1 -0
  29. package/dist/cjs/geo/index.js +18 -0
  30. package/dist/cjs/geo/index.js.map +1 -0
  31. package/dist/cjs/geo/point-in-radius.js +86 -0
  32. package/dist/cjs/geo/point-in-radius.js.map +1 -0
  33. package/dist/cjs/index.js +90 -0
  34. package/dist/cjs/index.js.map +1 -0
  35. package/dist/cjs/plugins/air-quality/airnow.plugin.js +343 -0
  36. package/dist/cjs/plugins/air-quality/airnow.plugin.js.map +1 -0
  37. package/dist/cjs/plugins/air-quality/index.js +6 -0
  38. package/dist/cjs/plugins/air-quality/index.js.map +1 -0
  39. package/dist/cjs/plugins/base-plugin.js +213 -0
  40. package/dist/cjs/plugins/base-plugin.js.map +1 -0
  41. package/dist/cjs/plugins/events/index.js +6 -0
  42. package/dist/cjs/plugins/events/index.js.map +1 -0
  43. package/dist/cjs/plugins/events/phoenix-events.plugin.js +382 -0
  44. package/dist/cjs/plugins/events/phoenix-events.plugin.js.map +1 -0
  45. package/dist/cjs/plugins/fire-emt/index.js +6 -0
  46. package/dist/cjs/plugins/fire-emt/index.js.map +1 -0
  47. package/dist/cjs/plugins/fire-emt/phoenix-fire.plugin.js +262 -0
  48. package/dist/cjs/plugins/fire-emt/phoenix-fire.plugin.js.map +1 -0
  49. package/dist/cjs/plugins/index.js +28 -0
  50. package/dist/cjs/plugins/index.js.map +1 -0
  51. package/dist/cjs/plugins/police-blotter/index.js +6 -0
  52. package/dist/cjs/plugins/police-blotter/index.js.map +1 -0
  53. package/dist/cjs/plugins/police-blotter/phoenix-police.plugin.js +198 -0
  54. package/dist/cjs/plugins/police-blotter/phoenix-police.plugin.js.map +1 -0
  55. package/dist/cjs/plugins/pulsepoint/index.js +6 -0
  56. package/dist/cjs/plugins/pulsepoint/index.js.map +1 -0
  57. package/dist/cjs/plugins/pulsepoint/pulsepoint.plugin.js +275 -0
  58. package/dist/cjs/plugins/pulsepoint/pulsepoint.plugin.js.map +1 -0
  59. package/dist/cjs/plugins/traffic/arizona-traffic.plugin.js +391 -0
  60. package/dist/cjs/plugins/traffic/arizona-traffic.plugin.js.map +1 -0
  61. package/dist/cjs/plugins/traffic/index.js +6 -0
  62. package/dist/cjs/plugins/traffic/index.js.map +1 -0
  63. package/dist/cjs/plugins/weather/index.js +6 -0
  64. package/dist/cjs/plugins/weather/index.js.map +1 -0
  65. package/dist/cjs/plugins/weather/nws-weather.plugin.js +180 -0
  66. package/dist/cjs/plugins/weather/nws-weather.plugin.js.map +1 -0
  67. package/dist/cjs/schemas/alert.schema.js +93 -0
  68. package/dist/cjs/schemas/alert.schema.js.map +1 -0
  69. package/dist/cjs/schemas/index.js +24 -0
  70. package/dist/cjs/schemas/index.js.map +1 -0
  71. package/dist/cjs/schemas/query.schema.js +76 -0
  72. package/dist/cjs/schemas/query.schema.js.map +1 -0
  73. package/dist/cjs/types/alert.js +35 -0
  74. package/dist/cjs/types/alert.js.map +1 -0
  75. package/dist/cjs/types/config.js +13 -0
  76. package/dist/cjs/types/config.js.map +1 -0
  77. package/dist/cjs/types/geo.js +3 -0
  78. package/dist/cjs/types/geo.js.map +1 -0
  79. package/dist/cjs/types/index.js +16 -0
  80. package/dist/cjs/types/index.js.map +1 -0
  81. package/dist/cjs/types/plugin.js +3 -0
  82. package/dist/cjs/types/plugin.js.map +1 -0
  83. package/dist/cjs/types/query.js +28 -0
  84. package/dist/cjs/types/query.js.map +1 -0
  85. package/dist/cjs/utils/cache.js +188 -0
  86. package/dist/cjs/utils/cache.js.map +1 -0
  87. package/dist/cjs/utils/csv.js +189 -0
  88. package/dist/cjs/utils/csv.js.map +1 -0
  89. package/dist/cjs/utils/date.js +153 -0
  90. package/dist/cjs/utils/date.js.map +1 -0
  91. package/dist/cjs/utils/index.js +28 -0
  92. package/dist/cjs/utils/index.js.map +1 -0
  93. package/dist/cjs/utils/retry.js +109 -0
  94. package/dist/cjs/utils/retry.js.map +1 -0
  95. package/dist/esm/adapters/index.js +3 -0
  96. package/dist/esm/adapters/index.js.map +1 -0
  97. package/dist/esm/adapters/lambda.js +140 -0
  98. package/dist/esm/adapters/lambda.js.map +1 -0
  99. package/dist/esm/adapters/vercel.js +116 -0
  100. package/dist/esm/adapters/vercel.js.map +1 -0
  101. package/dist/esm/core/alert-aggregator.js +203 -0
  102. package/dist/esm/core/alert-aggregator.js.map +1 -0
  103. package/dist/esm/core/alert-feed.js +232 -0
  104. package/dist/esm/core/alert-feed.js.map +1 -0
  105. package/dist/esm/core/index.js +6 -0
  106. package/dist/esm/core/index.js.map +1 -0
  107. package/dist/esm/core/plugin-registry.js +189 -0
  108. package/dist/esm/core/plugin-registry.js.map +1 -0
  109. package/dist/esm/core/plugin-resolver.js +117 -0
  110. package/dist/esm/core/plugin-resolver.js.map +1 -0
  111. package/dist/esm/core/time-range.js +57 -0
  112. package/dist/esm/core/time-range.js.map +1 -0
  113. package/dist/esm/errors/fetch-error.js +67 -0
  114. package/dist/esm/errors/fetch-error.js.map +1 -0
  115. package/dist/esm/errors/index.js +4 -0
  116. package/dist/esm/errors/index.js.map +1 -0
  117. package/dist/esm/errors/plugin-error.js +71 -0
  118. package/dist/esm/errors/plugin-error.js.map +1 -0
  119. package/dist/esm/errors/validation-error.js +45 -0
  120. package/dist/esm/errors/validation-error.js.map +1 -0
  121. package/dist/esm/geo/distance.js +85 -0
  122. package/dist/esm/geo/distance.js.map +1 -0
  123. package/dist/esm/geo/index.js +3 -0
  124. package/dist/esm/geo/index.js.map +1 -0
  125. package/dist/esm/geo/point-in-radius.js +79 -0
  126. package/dist/esm/geo/point-in-radius.js.map +1 -0
  127. package/dist/esm/index.js +30 -0
  128. package/dist/esm/index.js.map +1 -0
  129. package/dist/esm/plugins/air-quality/airnow.plugin.js +339 -0
  130. package/dist/esm/plugins/air-quality/airnow.plugin.js.map +1 -0
  131. package/dist/esm/plugins/air-quality/index.js +2 -0
  132. package/dist/esm/plugins/air-quality/index.js.map +1 -0
  133. package/dist/esm/plugins/base-plugin.js +209 -0
  134. package/dist/esm/plugins/base-plugin.js.map +1 -0
  135. package/dist/esm/plugins/events/index.js +2 -0
  136. package/dist/esm/plugins/events/index.js.map +1 -0
  137. package/dist/esm/plugins/events/phoenix-events.plugin.js +378 -0
  138. package/dist/esm/plugins/events/phoenix-events.plugin.js.map +1 -0
  139. package/dist/esm/plugins/fire-emt/index.js +2 -0
  140. package/dist/esm/plugins/fire-emt/index.js.map +1 -0
  141. package/dist/esm/plugins/fire-emt/phoenix-fire.plugin.js +258 -0
  142. package/dist/esm/plugins/fire-emt/phoenix-fire.plugin.js.map +1 -0
  143. package/dist/esm/plugins/index.js +17 -0
  144. package/dist/esm/plugins/index.js.map +1 -0
  145. package/dist/esm/plugins/police-blotter/index.js +2 -0
  146. package/dist/esm/plugins/police-blotter/index.js.map +1 -0
  147. package/dist/esm/plugins/police-blotter/phoenix-police.plugin.js +194 -0
  148. package/dist/esm/plugins/police-blotter/phoenix-police.plugin.js.map +1 -0
  149. package/dist/esm/plugins/pulsepoint/index.js +2 -0
  150. package/dist/esm/plugins/pulsepoint/index.js.map +1 -0
  151. package/dist/esm/plugins/pulsepoint/pulsepoint.plugin.js +271 -0
  152. package/dist/esm/plugins/pulsepoint/pulsepoint.plugin.js.map +1 -0
  153. package/dist/esm/plugins/traffic/arizona-traffic.plugin.js +387 -0
  154. package/dist/esm/plugins/traffic/arizona-traffic.plugin.js.map +1 -0
  155. package/dist/esm/plugins/traffic/index.js +2 -0
  156. package/dist/esm/plugins/traffic/index.js.map +1 -0
  157. package/dist/esm/plugins/weather/index.js +2 -0
  158. package/dist/esm/plugins/weather/index.js.map +1 -0
  159. package/dist/esm/plugins/weather/nws-weather.plugin.js +176 -0
  160. package/dist/esm/plugins/weather/nws-weather.plugin.js.map +1 -0
  161. package/dist/esm/schemas/alert.schema.js +90 -0
  162. package/dist/esm/schemas/alert.schema.js.map +1 -0
  163. package/dist/esm/schemas/index.js +5 -0
  164. package/dist/esm/schemas/index.js.map +1 -0
  165. package/dist/esm/schemas/query.schema.js +72 -0
  166. package/dist/esm/schemas/query.schema.js.map +1 -0
  167. package/dist/esm/types/alert.js +32 -0
  168. package/dist/esm/types/alert.js.map +1 -0
  169. package/dist/esm/types/config.js +10 -0
  170. package/dist/esm/types/config.js.map +1 -0
  171. package/dist/esm/types/geo.js +2 -0
  172. package/dist/esm/types/geo.js.map +1 -0
  173. package/dist/esm/types/index.js +4 -0
  174. package/dist/esm/types/index.js.map +1 -0
  175. package/dist/esm/types/plugin.js +2 -0
  176. package/dist/esm/types/plugin.js.map +1 -0
  177. package/dist/esm/types/query.js +25 -0
  178. package/dist/esm/types/query.js.map +1 -0
  179. package/dist/esm/utils/cache.js +181 -0
  180. package/dist/esm/utils/cache.js.map +1 -0
  181. package/dist/esm/utils/csv.js +185 -0
  182. package/dist/esm/utils/csv.js.map +1 -0
  183. package/dist/esm/utils/date.js +142 -0
  184. package/dist/esm/utils/date.js.map +1 -0
  185. package/dist/esm/utils/index.js +5 -0
  186. package/dist/esm/utils/index.js.map +1 -0
  187. package/dist/esm/utils/retry.js +102 -0
  188. package/dist/esm/utils/retry.js.map +1 -0
  189. package/dist/types/adapters/index.d.ts +5 -0
  190. package/dist/types/adapters/index.d.ts.map +1 -0
  191. package/dist/types/adapters/lambda.d.ts +37 -0
  192. package/dist/types/adapters/lambda.d.ts.map +1 -0
  193. package/dist/types/adapters/vercel.d.ts +54 -0
  194. package/dist/types/adapters/vercel.d.ts.map +1 -0
  195. package/dist/types/core/alert-aggregator.d.ts +81 -0
  196. package/dist/types/core/alert-aggregator.d.ts.map +1 -0
  197. package/dist/types/core/alert-feed.d.ts +80 -0
  198. package/dist/types/core/alert-feed.d.ts.map +1 -0
  199. package/dist/types/core/index.d.ts +8 -0
  200. package/dist/types/core/index.d.ts.map +1 -0
  201. package/dist/types/core/plugin-registry.d.ts +91 -0
  202. package/dist/types/core/plugin-registry.d.ts.map +1 -0
  203. package/dist/types/core/plugin-resolver.d.ts +78 -0
  204. package/dist/types/core/plugin-resolver.d.ts.map +1 -0
  205. package/dist/types/core/time-range.d.ts +40 -0
  206. package/dist/types/core/time-range.d.ts.map +1 -0
  207. package/dist/types/errors/fetch-error.d.ts +46 -0
  208. package/dist/types/errors/fetch-error.d.ts.map +1 -0
  209. package/dist/types/errors/index.d.ts +5 -0
  210. package/dist/types/errors/index.d.ts.map +1 -0
  211. package/dist/types/errors/plugin-error.d.ts +42 -0
  212. package/dist/types/errors/plugin-error.d.ts.map +1 -0
  213. package/dist/types/errors/validation-error.d.ts +34 -0
  214. package/dist/types/errors/validation-error.d.ts.map +1 -0
  215. package/dist/types/geo/distance.d.ts +50 -0
  216. package/dist/types/geo/distance.d.ts.map +1 -0
  217. package/dist/types/geo/index.d.ts +3 -0
  218. package/dist/types/geo/index.d.ts.map +1 -0
  219. package/dist/types/geo/point-in-radius.d.ts +44 -0
  220. package/dist/types/geo/point-in-radius.d.ts.map +1 -0
  221. package/dist/types/index.d.ts +32 -0
  222. package/dist/types/index.d.ts.map +1 -0
  223. package/dist/types/plugins/air-quality/airnow.plugin.d.ts +84 -0
  224. package/dist/types/plugins/air-quality/airnow.plugin.d.ts.map +1 -0
  225. package/dist/types/plugins/air-quality/index.d.ts +3 -0
  226. package/dist/types/plugins/air-quality/index.d.ts.map +1 -0
  227. package/dist/types/plugins/base-plugin.d.ts +99 -0
  228. package/dist/types/plugins/base-plugin.d.ts.map +1 -0
  229. package/dist/types/plugins/events/index.d.ts +3 -0
  230. package/dist/types/plugins/events/index.d.ts.map +1 -0
  231. package/dist/types/plugins/events/phoenix-events.plugin.d.ts +71 -0
  232. package/dist/types/plugins/events/phoenix-events.plugin.d.ts.map +1 -0
  233. package/dist/types/plugins/fire-emt/index.d.ts +3 -0
  234. package/dist/types/plugins/fire-emt/index.d.ts.map +1 -0
  235. package/dist/types/plugins/fire-emt/phoenix-fire.plugin.d.ts +47 -0
  236. package/dist/types/plugins/fire-emt/phoenix-fire.plugin.d.ts.map +1 -0
  237. package/dist/types/plugins/index.d.ts +17 -0
  238. package/dist/types/plugins/index.d.ts.map +1 -0
  239. package/dist/types/plugins/police-blotter/index.d.ts +3 -0
  240. package/dist/types/plugins/police-blotter/index.d.ts.map +1 -0
  241. package/dist/types/plugins/police-blotter/phoenix-police.plugin.d.ts +49 -0
  242. package/dist/types/plugins/police-blotter/phoenix-police.plugin.d.ts.map +1 -0
  243. package/dist/types/plugins/pulsepoint/index.d.ts +3 -0
  244. package/dist/types/plugins/pulsepoint/index.d.ts.map +1 -0
  245. package/dist/types/plugins/pulsepoint/pulsepoint.plugin.d.ts +61 -0
  246. package/dist/types/plugins/pulsepoint/pulsepoint.plugin.d.ts.map +1 -0
  247. package/dist/types/plugins/traffic/arizona-traffic.plugin.d.ts +83 -0
  248. package/dist/types/plugins/traffic/arizona-traffic.plugin.d.ts.map +1 -0
  249. package/dist/types/plugins/traffic/index.d.ts +3 -0
  250. package/dist/types/plugins/traffic/index.d.ts.map +1 -0
  251. package/dist/types/plugins/weather/index.d.ts +3 -0
  252. package/dist/types/plugins/weather/index.d.ts.map +1 -0
  253. package/dist/types/plugins/weather/nws-weather.plugin.d.ts +50 -0
  254. package/dist/types/plugins/weather/nws-weather.plugin.d.ts.map +1 -0
  255. package/dist/types/schemas/alert.schema.d.ts +266 -0
  256. package/dist/types/schemas/alert.schema.d.ts.map +1 -0
  257. package/dist/types/schemas/index.d.ts +5 -0
  258. package/dist/types/schemas/index.d.ts.map +1 -0
  259. package/dist/types/schemas/query.schema.d.ts +150 -0
  260. package/dist/types/schemas/query.schema.d.ts.map +1 -0
  261. package/dist/types/types/alert.d.ts +96 -0
  262. package/dist/types/types/alert.d.ts.map +1 -0
  263. package/dist/types/types/config.d.ts +63 -0
  264. package/dist/types/types/config.d.ts.map +1 -0
  265. package/dist/types/types/geo.d.ts +33 -0
  266. package/dist/types/types/geo.d.ts.map +1 -0
  267. package/dist/types/types/index.d.ts +9 -0
  268. package/dist/types/types/index.d.ts.map +1 -0
  269. package/dist/types/types/plugin.d.ts +125 -0
  270. package/dist/types/types/plugin.d.ts.map +1 -0
  271. package/dist/types/types/query.d.ts +86 -0
  272. package/dist/types/types/query.d.ts.map +1 -0
  273. package/dist/types/utils/cache.d.ts +112 -0
  274. package/dist/types/utils/cache.d.ts.map +1 -0
  275. package/dist/types/utils/csv.d.ts +38 -0
  276. package/dist/types/utils/csv.d.ts.map +1 -0
  277. package/dist/types/utils/date.d.ts +47 -0
  278. package/dist/types/utils/date.d.ts.map +1 -0
  279. package/dist/types/utils/index.d.ts +7 -0
  280. package/dist/types/utils/index.d.ts.map +1 -0
  281. package/dist/types/utils/retry.d.ts +51 -0
  282. package/dist/types/utils/retry.d.ts.map +1 -0
  283. package/package.json +115 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Earth's radius in meters (mean radius).
3
+ */
4
+ export const EARTH_RADIUS_METERS = 6_371_008.8;
5
+ /**
6
+ * Convert degrees to radians.
7
+ */
8
+ export function toRadians(degrees) {
9
+ return degrees * (Math.PI / 180);
10
+ }
11
+ /**
12
+ * Convert radians to degrees.
13
+ */
14
+ export function toDegrees(radians) {
15
+ return radians * (180 / Math.PI);
16
+ }
17
+ /**
18
+ * Calculate the Haversine distance between two geographic points.
19
+ *
20
+ * The Haversine formula calculates the great-circle distance between two points
21
+ * on a sphere given their latitudes and longitudes.
22
+ *
23
+ * @param point1 - First geographic point
24
+ * @param point2 - Second geographic point
25
+ * @returns Distance in meters
26
+ */
27
+ export function haversineDistance(point1, point2) {
28
+ const lat1 = toRadians(point1.latitude);
29
+ const lat2 = toRadians(point2.latitude);
30
+ const deltaLat = toRadians(point2.latitude - point1.latitude);
31
+ const deltaLon = toRadians(point2.longitude - point1.longitude);
32
+ const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
33
+ Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
34
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
35
+ return EARTH_RADIUS_METERS * c;
36
+ }
37
+ /**
38
+ * Calculate distance between two points (alias for haversineDistance).
39
+ *
40
+ * @param point1 - First geographic point
41
+ * @param point2 - Second geographic point
42
+ * @returns Distance in meters
43
+ */
44
+ export function calculateDistance(point1, point2) {
45
+ return haversineDistance(point1, point2);
46
+ }
47
+ /**
48
+ * Calculate the bearing (direction) from one point to another.
49
+ *
50
+ * @param from - Starting point
51
+ * @param to - Ending point
52
+ * @returns Bearing in degrees (0-360, where 0 is north)
53
+ */
54
+ export function calculateBearing(from, to) {
55
+ const lat1 = toRadians(from.latitude);
56
+ const lat2 = toRadians(to.latitude);
57
+ const deltaLon = toRadians(to.longitude - from.longitude);
58
+ const y = Math.sin(deltaLon) * Math.cos(lat2);
59
+ const x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(deltaLon);
60
+ const bearing = toDegrees(Math.atan2(y, x));
61
+ return (bearing + 360) % 360;
62
+ }
63
+ /**
64
+ * Calculate a destination point given a start point, bearing, and distance.
65
+ *
66
+ * @param start - Starting point
67
+ * @param bearingDegrees - Bearing in degrees (0-360)
68
+ * @param distanceMeters - Distance in meters
69
+ * @returns Destination point
70
+ */
71
+ export function destinationPoint(start, bearingDegrees, distanceMeters) {
72
+ const lat1 = toRadians(start.latitude);
73
+ const lon1 = toRadians(start.longitude);
74
+ const bearing = toRadians(bearingDegrees);
75
+ const angularDistance = distanceMeters / EARTH_RADIUS_METERS;
76
+ const lat2 = Math.asin(Math.sin(lat1) * Math.cos(angularDistance) +
77
+ Math.cos(lat1) * Math.sin(angularDistance) * Math.cos(bearing));
78
+ const lon2 = lon1 +
79
+ Math.atan2(Math.sin(bearing) * Math.sin(angularDistance) * Math.cos(lat1), Math.cos(angularDistance) - Math.sin(lat1) * Math.sin(lat2));
80
+ return {
81
+ latitude: toDegrees(lat2),
82
+ longitude: toDegrees(lon2),
83
+ };
84
+ }
85
+ //# sourceMappingURL=distance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distance.js","sourceRoot":"","sources":["../../../src/geo/distance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { EARTH_RADIUS_METERS, toRadians, toDegrees, haversineDistance, calculateDistance, calculateBearing, destinationPoint, } from './distance';
2
+ export { isPointInRadius, isPointInCircle, isPointInBoundingBox, doCirclesOverlap, getBoundingBoxForRadius, } from './point-in-radius';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/geo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,79 @@
1
+ import { haversineDistance } from './distance';
2
+ /**
3
+ * Check if a point is within a given radius of a center point.
4
+ *
5
+ * @param point - The point to check
6
+ * @param center - The center point
7
+ * @param radiusMeters - The radius in meters
8
+ * @returns true if the point is within the radius
9
+ */
10
+ export function isPointInRadius(point, center, radiusMeters) {
11
+ const distance = haversineDistance(point, center);
12
+ return distance <= radiusMeters;
13
+ }
14
+ /**
15
+ * Check if a point is within a GeoCircle.
16
+ *
17
+ * @param point - The point to check
18
+ * @param circle - The circle definition
19
+ * @returns true if the point is within the circle
20
+ */
21
+ export function isPointInCircle(point, circle) {
22
+ return isPointInRadius(point, circle.center, circle.radiusMeters);
23
+ }
24
+ /**
25
+ * Check if a point is within a bounding box.
26
+ *
27
+ * @param point - The point to check
28
+ * @param box - The bounding box
29
+ * @returns true if the point is within the bounding box
30
+ */
31
+ export function isPointInBoundingBox(point, box) {
32
+ const { southwest, northeast } = box;
33
+ // Handle the case where the bounding box crosses the antimeridian
34
+ if (southwest.longitude > northeast.longitude) {
35
+ // Box crosses antimeridian
36
+ return (point.latitude >= southwest.latitude &&
37
+ point.latitude <= northeast.latitude &&
38
+ (point.longitude >= southwest.longitude || point.longitude <= northeast.longitude));
39
+ }
40
+ return (point.latitude >= southwest.latitude &&
41
+ point.latitude <= northeast.latitude &&
42
+ point.longitude >= southwest.longitude &&
43
+ point.longitude <= northeast.longitude);
44
+ }
45
+ /**
46
+ * Check if two circles overlap.
47
+ *
48
+ * @param circle1 - First circle
49
+ * @param circle2 - Second circle
50
+ * @returns true if the circles overlap
51
+ */
52
+ export function doCirclesOverlap(circle1, circle2) {
53
+ const distance = haversineDistance(circle1.center, circle2.center);
54
+ return distance <= circle1.radiusMeters + circle2.radiusMeters;
55
+ }
56
+ /**
57
+ * Calculate a bounding box that contains a circle.
58
+ * This is useful for quick filtering before doing precise distance calculations.
59
+ *
60
+ * @param center - Center point of the circle
61
+ * @param radiusMeters - Radius in meters
62
+ * @returns A bounding box that contains the circle
63
+ */
64
+ export function getBoundingBoxForRadius(center, radiusMeters) {
65
+ // Approximate degrees per meter at the given latitude
66
+ const latDelta = radiusMeters / 111_320; // ~111.32km per degree latitude
67
+ const lonDelta = radiusMeters / (111_320 * Math.cos((center.latitude * Math.PI) / 180));
68
+ return {
69
+ southwest: {
70
+ latitude: Math.max(-90, center.latitude - latDelta),
71
+ longitude: center.longitude - lonDelta,
72
+ },
73
+ northeast: {
74
+ latitude: Math.min(90, center.latitude + latDelta),
75
+ longitude: center.longitude + lonDelta,
76
+ },
77
+ };
78
+ }
79
+ //# sourceMappingURL=point-in-radius.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"point-in-radius.js","sourceRoot":"","sources":["../../../src/geo/point-in-radius.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,KAAe,EAAE,MAAgB,EAAE,YAAoB;IACrF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,OAAO,QAAQ,IAAI,YAAY,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAAe,EAAE,MAAiB;IAChE,OAAO,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAe,EAAE,GAAmB;IACvE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC;IAErC,kEAAkE;IAClE,IAAI,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;QAC9C,2BAA2B;QAC3B,OAAO,CACL,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;YACpC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;YACpC,CAAC,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,CACnF,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;QACpC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;QACpC,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS;QACtC,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CACvC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAkB,EAAE,OAAkB;IACrE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE,OAAO,QAAQ,IAAI,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;AACjE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAgB,EAAE,YAAoB;IAC5E,sDAAsD;IACtD,MAAM,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,CAAC,gCAAgC;IACzE,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAExF,OAAO;QACL,SAAS,EAAE;YACT,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACnD,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,QAAQ;SACvC;QACD,SAAS,EAAE;YACT,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAClD,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,QAAQ;SACvC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ // Main AlertFeed class
2
+ export { AlertFeed } from './core';
3
+ // Core components
4
+ export { PluginRegistry, PluginResolver, AlertAggregator } from './core';
5
+ export { resolveTimeRange, normalizeTimeRange } from './core';
6
+ // Type constants
7
+ export { RISK_LEVEL_VALUES, RISK_LEVELS, ALERT_CATEGORIES, ALERT_TEMPORAL_TYPES, TIME_RANGE_PRESETS, DEFAULT_QUERY_RADIUS_METERS, DEFAULT_QUERY_LIMIT, MAX_QUERY_LIMIT, DEFAULT_CONFIG, } from './types';
8
+ // Schemas
9
+ export { AlertSchema, AlertQuerySchema, AlertQueryRequestSchema, GeoPointSchema, TimeRangeSchema, transformRequestToQuery, } from './schemas';
10
+ // Errors
11
+ export { PluginError, PluginInitializationError, PluginFetchError, PluginTimeoutError, DuplicatePluginError, PluginNotFoundError, ValidationError, FetchError, } from './errors';
12
+ // Geo utilities
13
+ export { haversineDistance, calculateDistance, calculateBearing, destinationPoint, isPointInRadius, isPointInCircle, isPointInBoundingBox, doCirclesOverlap, getBoundingBoxForRadius, } from './geo';
14
+ // Cache providers
15
+ export { InMemoryCacheProvider, VercelKVCacheProvider, DynamoDBCacheProvider, generateCacheKey, } from './utils';
16
+ // Utility functions
17
+ export { withRetry, withTimeout, sleep, TimeoutError } from './utils';
18
+ // Base plugin for building custom plugins
19
+ export { BasePlugin } from './plugins';
20
+ // Built-in plugins
21
+ export { NWSWeatherPlugin } from './plugins/weather';
22
+ export { PhoenixPolicePlugin } from './plugins/police-blotter';
23
+ export { PhoenixFirePlugin } from './plugins/fire-emt';
24
+ export { PulsepointPlugin } from './plugins/pulsepoint';
25
+ export { PhoenixEventsPlugin } from './plugins/events';
26
+ export { ArizonaTrafficPlugin } from './plugins/traffic';
27
+ export { AirNowPlugin } from './plugins/air-quality';
28
+ // CSV utilities (for custom plugins that need CSV parsing)
29
+ export { parseCSV, toCSV } from './utils';
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAwC9D,iBAAiB;AACjB,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,UAAU;AACV,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAEnB,SAAS;AACT,OAAO,EACL,WAAW,EACX,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,UAAU,GACX,MAAM,UAAU,CAAC;AAGlB,gBAAgB;AAChB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,OAAO,CAAC;AAEf,kBAAkB;AAClB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGtE,0CAA0C;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,mBAAmB;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD,2DAA2D;AAC3D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,339 @@
1
+ import { BasePlugin } from '../base-plugin';
2
+ /**
3
+ * AQI Category to risk level mapping.
4
+ * Based on EPA AQI scale:
5
+ * 1: Good (0-50)
6
+ * 2: Moderate (51-100)
7
+ * 3: Unhealthy for Sensitive Groups (101-150)
8
+ * 4: Unhealthy (151-200)
9
+ * 5: Very Unhealthy (201-300)
10
+ * 6: Hazardous (301+)
11
+ */
12
+ const AQI_CATEGORY_RISK_MAP = {
13
+ 1: 'low', // Good
14
+ 2: 'low', // Moderate
15
+ 3: 'moderate', // Unhealthy for Sensitive Groups
16
+ 4: 'high', // Unhealthy
17
+ 5: 'severe', // Very Unhealthy
18
+ 6: 'extreme', // Hazardous
19
+ };
20
+ /**
21
+ * AQI Category descriptions.
22
+ */
23
+ const AQI_CATEGORY_DESCRIPTIONS = {
24
+ 1: 'Good - Air quality is satisfactory and poses little or no risk.',
25
+ 2: 'Moderate - Air quality is acceptable; some pollutants may affect unusually sensitive people.',
26
+ 3: 'Unhealthy for Sensitive Groups - Members of sensitive groups may experience health effects.',
27
+ 4: 'Unhealthy - Everyone may begin to experience health effects.',
28
+ 5: 'Very Unhealthy - Health alert: everyone may experience more serious health effects.',
29
+ 6: 'Hazardous - Health warnings of emergency conditions.',
30
+ };
31
+ /**
32
+ * Plugin that fetches air quality data from AirNow API.
33
+ *
34
+ * Provides current AQI observations and forecasts for US locations.
35
+ * Important for Phoenix due to dust storms and air quality concerns.
36
+ *
37
+ * @see https://docs.airnowapi.org
38
+ */
39
+ export class AirNowPlugin extends BasePlugin {
40
+ metadata = {
41
+ id: 'airnow',
42
+ name: 'AirNow Air Quality',
43
+ version: '1.0.0',
44
+ description: 'Air quality index (AQI) data from EPA AirNow',
45
+ coverage: {
46
+ type: 'global',
47
+ description: 'United States',
48
+ },
49
+ supportedTemporalTypes: ['real-time', 'scheduled'],
50
+ supportedCategories: ['weather'], // Air quality is weather-related
51
+ refreshIntervalMs: 60 * 60 * 1000, // 1 hour - AQI updates hourly
52
+ };
53
+ airNowConfig;
54
+ constructor(config) {
55
+ super(config);
56
+ if (!config.apiKey) {
57
+ throw new Error('AirNow API key is required');
58
+ }
59
+ this.airNowConfig = {
60
+ includeForecast: true,
61
+ distanceMiles: 25,
62
+ ...config,
63
+ };
64
+ }
65
+ async fetchAlerts(options) {
66
+ const { location } = options;
67
+ const cacheKey = this.generateCacheKey(options);
68
+ const warnings = [];
69
+ try {
70
+ const { data, fromCache } = await this.getCachedOrFetch(cacheKey, () => this.fetchAirQualityData(location, warnings), this.config.cacheTtlMs);
71
+ return {
72
+ alerts: data,
73
+ fromCache,
74
+ cacheKey,
75
+ warnings: warnings.length > 0 ? warnings : undefined,
76
+ };
77
+ }
78
+ catch (error) {
79
+ console.error('AirNow fetch error:', error);
80
+ throw error;
81
+ }
82
+ }
83
+ /**
84
+ * Fetch air quality data from AirNow API.
85
+ */
86
+ async fetchAirQualityData(location, warnings) {
87
+ const allAlerts = [];
88
+ // Fetch current observations
89
+ try {
90
+ const observations = await this.fetchCurrentObservations(location);
91
+ const observationAlerts = observations.map((obs) => this.transformObservation(obs));
92
+ allAlerts.push(...observationAlerts);
93
+ }
94
+ catch (error) {
95
+ warnings.push(`Failed to fetch current observations: ${error instanceof Error ? error.message : 'Unknown error'}`);
96
+ }
97
+ // Fetch forecasts if enabled
98
+ if (this.airNowConfig.includeForecast) {
99
+ try {
100
+ const forecasts = await this.fetchForecasts(location);
101
+ const forecastAlerts = forecasts.map((forecast) => this.transformForecast(forecast));
102
+ allAlerts.push(...forecastAlerts);
103
+ }
104
+ catch (error) {
105
+ warnings.push(`Failed to fetch forecasts: ${error instanceof Error ? error.message : 'Unknown error'}`);
106
+ }
107
+ }
108
+ // Deduplicate and prioritize by AQI
109
+ return this.deduplicateAlerts(allAlerts);
110
+ }
111
+ /**
112
+ * Fetch current air quality observations.
113
+ */
114
+ async fetchCurrentObservations(location) {
115
+ const url = new URL('https://www.airnowapi.org/aq/observation/latLong/current/');
116
+ url.searchParams.set('format', 'application/json');
117
+ url.searchParams.set('latitude', String(location.latitude));
118
+ url.searchParams.set('longitude', String(location.longitude));
119
+ url.searchParams.set('distance', String(this.airNowConfig.distanceMiles));
120
+ url.searchParams.set('API_KEY', this.airNowConfig.apiKey);
121
+ return this.fetchJson(url.toString());
122
+ }
123
+ /**
124
+ * Fetch air quality forecasts.
125
+ */
126
+ async fetchForecasts(location) {
127
+ const url = new URL('https://www.airnowapi.org/aq/forecast/latLong/');
128
+ url.searchParams.set('format', 'application/json');
129
+ url.searchParams.set('latitude', String(location.latitude));
130
+ url.searchParams.set('longitude', String(location.longitude));
131
+ url.searchParams.set('distance', String(this.airNowConfig.distanceMiles));
132
+ url.searchParams.set('API_KEY', this.airNowConfig.apiKey);
133
+ // Get next 3 days of forecasts
134
+ const today = new Date();
135
+ const endDate = new Date(today);
136
+ endDate.setDate(endDate.getDate() + 3);
137
+ url.searchParams.set('date', this.formatDate(today));
138
+ return this.fetchJson(url.toString());
139
+ }
140
+ /**
141
+ * Transform an observation to an alert.
142
+ */
143
+ transformObservation(obs) {
144
+ const riskLevel = this.mapAqiToRiskLevel(obs.AQI, obs.Category.Number);
145
+ // Only create alerts for notable air quality (category 3+)
146
+ // Or always create if the AQI is significant
147
+ const issued = `${obs.DateObserved}T${String(obs.HourObserved).padStart(2, '0')}:00:00`;
148
+ return this.createAlert({
149
+ id: `airnow-obs-${obs.ReportingArea}-${obs.ParameterName}-${obs.DateObserved}`,
150
+ externalId: `${obs.ReportingArea}-${obs.ParameterName}`,
151
+ title: this.buildObservationTitle(obs),
152
+ description: this.buildObservationDescription(obs),
153
+ riskLevel,
154
+ priority: this.riskLevelToPriority(riskLevel),
155
+ category: 'weather',
156
+ temporalType: 'real-time',
157
+ location: {
158
+ point: { latitude: obs.Latitude, longitude: obs.Longitude },
159
+ address: `${obs.ReportingArea}, ${obs.StateCode}`,
160
+ },
161
+ timestamps: {
162
+ issued,
163
+ eventStart: issued,
164
+ },
165
+ metadata: {
166
+ parameterName: obs.ParameterName,
167
+ aqi: obs.AQI,
168
+ categoryNumber: obs.Category.Number,
169
+ categoryName: obs.Category.Name,
170
+ reportingArea: obs.ReportingArea,
171
+ isObservation: true,
172
+ },
173
+ });
174
+ }
175
+ /**
176
+ * Transform a forecast to an alert.
177
+ */
178
+ transformForecast(forecast) {
179
+ const riskLevel = this.mapAqiToRiskLevel(forecast.AQI, forecast.Category.Number);
180
+ return this.createAlert({
181
+ id: `airnow-fcst-${forecast.ReportingArea}-${forecast.ParameterName}-${forecast.DateForecast}`,
182
+ externalId: `${forecast.ReportingArea}-${forecast.ParameterName}-${forecast.DateForecast}`,
183
+ title: this.buildForecastTitle(forecast),
184
+ description: this.buildForecastDescription(forecast),
185
+ riskLevel,
186
+ priority: this.riskLevelToPriority(riskLevel),
187
+ category: 'weather',
188
+ temporalType: 'scheduled',
189
+ location: {
190
+ point: { latitude: forecast.Latitude, longitude: forecast.Longitude },
191
+ address: `${forecast.ReportingArea}, ${forecast.StateCode}`,
192
+ },
193
+ timestamps: {
194
+ issued: forecast.DateIssue,
195
+ eventStart: `${forecast.DateForecast}T00:00:00`,
196
+ eventEnd: `${forecast.DateForecast}T23:59:59`,
197
+ },
198
+ metadata: {
199
+ parameterName: forecast.ParameterName,
200
+ aqi: forecast.AQI,
201
+ categoryNumber: forecast.Category.Number,
202
+ categoryName: forecast.Category.Name,
203
+ reportingArea: forecast.ReportingArea,
204
+ actionDay: forecast.ActionDay,
205
+ discussion: forecast.Discussion,
206
+ isForecast: true,
207
+ },
208
+ });
209
+ }
210
+ /**
211
+ * Map AQI value to risk level.
212
+ */
213
+ mapAqiToRiskLevel(aqi, categoryNumber) {
214
+ // Use category number if available
215
+ if (AQI_CATEGORY_RISK_MAP[categoryNumber]) {
216
+ return AQI_CATEGORY_RISK_MAP[categoryNumber];
217
+ }
218
+ // Fall back to AQI value ranges
219
+ if (aqi <= 50)
220
+ return 'low';
221
+ if (aqi <= 100)
222
+ return 'low';
223
+ if (aqi <= 150)
224
+ return 'moderate';
225
+ if (aqi <= 200)
226
+ return 'high';
227
+ if (aqi <= 300)
228
+ return 'severe';
229
+ return 'extreme';
230
+ }
231
+ /**
232
+ * Build observation title.
233
+ */
234
+ buildObservationTitle(obs) {
235
+ const pollutant = this.formatPollutant(obs.ParameterName);
236
+ return `Air Quality ${obs.Category.Name} - ${pollutant} AQI ${obs.AQI}`;
237
+ }
238
+ /**
239
+ * Build forecast title.
240
+ */
241
+ buildForecastTitle(forecast) {
242
+ const pollutant = this.formatPollutant(forecast.ParameterName);
243
+ const dateStr = this.formatForecastDate(forecast.DateForecast);
244
+ const actionDay = forecast.ActionDay ? ' (Action Day)' : '';
245
+ return `${dateStr} Air Quality Forecast: ${pollutant} AQI ${forecast.AQI}${actionDay}`;
246
+ }
247
+ /**
248
+ * Format pollutant name for display.
249
+ */
250
+ formatPollutant(parameterName) {
251
+ const names = {
252
+ O3: 'Ozone',
253
+ 'PM2.5': 'Fine Particles (PM2.5)',
254
+ PM10: 'Coarse Particles (PM10)',
255
+ };
256
+ return names[parameterName] ?? parameterName;
257
+ }
258
+ /**
259
+ * Format forecast date.
260
+ */
261
+ formatForecastDate(dateStr) {
262
+ const date = new Date(dateStr);
263
+ const today = new Date();
264
+ const tomorrow = new Date(today);
265
+ tomorrow.setDate(tomorrow.getDate() + 1);
266
+ if (date.toDateString() === today.toDateString()) {
267
+ return 'Today';
268
+ }
269
+ if (date.toDateString() === tomorrow.toDateString()) {
270
+ return 'Tomorrow';
271
+ }
272
+ return date.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' });
273
+ }
274
+ /**
275
+ * Build observation description.
276
+ */
277
+ buildObservationDescription(obs) {
278
+ const parts = [];
279
+ parts.push(`${this.formatPollutant(obs.ParameterName)}: AQI ${obs.AQI}`);
280
+ parts.push(`Category: ${obs.Category.Name}`);
281
+ parts.push('');
282
+ parts.push(AQI_CATEGORY_DESCRIPTIONS[obs.Category.Number] ?? '');
283
+ parts.push('');
284
+ parts.push(`Reporting Area: ${obs.ReportingArea}, ${obs.StateCode}`);
285
+ parts.push(`Observed: ${obs.DateObserved} ${obs.HourObserved}:00 ${obs.LocalTimeZone}`);
286
+ return parts.join('\n');
287
+ }
288
+ /**
289
+ * Build forecast description.
290
+ */
291
+ buildForecastDescription(forecast) {
292
+ const parts = [];
293
+ parts.push(`${this.formatPollutant(forecast.ParameterName)}: AQI ${forecast.AQI}`);
294
+ parts.push(`Category: ${forecast.Category.Name}`);
295
+ if (forecast.ActionDay) {
296
+ parts.push('');
297
+ parts.push('⚠️ ACTION DAY - Consider reducing outdoor activities');
298
+ }
299
+ parts.push('');
300
+ parts.push(AQI_CATEGORY_DESCRIPTIONS[forecast.Category.Number] ?? '');
301
+ if (forecast.Discussion) {
302
+ parts.push('');
303
+ parts.push(`Forecast Discussion: ${forecast.Discussion}`);
304
+ }
305
+ parts.push('');
306
+ parts.push(`Reporting Area: ${forecast.ReportingArea}, ${forecast.StateCode}`);
307
+ parts.push(`Forecast Date: ${forecast.DateForecast}`);
308
+ return parts.join('\n');
309
+ }
310
+ /**
311
+ * Format date as YYYY-MM-DD.
312
+ */
313
+ formatDate(date) {
314
+ return date.toISOString().split('T')[0];
315
+ }
316
+ /**
317
+ * Deduplicate alerts, keeping highest AQI per location/date.
318
+ */
319
+ deduplicateAlerts(alerts) {
320
+ const seen = new Map();
321
+ for (const alert of alerts) {
322
+ const key = `${alert.location.address}-${alert.temporalType}-${alert.timestamps.eventStart?.split('T')[0]}`;
323
+ const existing = seen.get(key);
324
+ if (!existing) {
325
+ seen.set(key, alert);
326
+ }
327
+ else {
328
+ // Keep higher AQI
329
+ const existingAqi = existing.metadata?.aqi ?? 0;
330
+ const currentAqi = alert.metadata?.aqi ?? 0;
331
+ if (currentAqi > existingAqi) {
332
+ seen.set(key, alert);
333
+ }
334
+ }
335
+ }
336
+ return Array.from(seen.values());
337
+ }
338
+ }
339
+ //# sourceMappingURL=airnow.plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"airnow.plugin.js","sourceRoot":"","sources":["../../../../src/plugins/air-quality/airnow.plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { AirNowPlugin } from './airnow.plugin';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/air-quality/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}