@atmosx/event-product-parser 3.0.48 → 3.0.52

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 (141) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/CODE_OF_CONDUCT.md +9 -9
  3. package/CONTRIBUTING.md +29 -29
  4. package/LICENSE +17 -17
  5. package/README.md +443 -417
  6. package/SECURITY.md +20 -20
  7. package/SUPPORTED_EVENTS.md +369 -368
  8. package/dist/cjs/index.cjs +1925 -1885
  9. package/dist/esm/index.mjs +1927 -1887
  10. package/package.json +52 -52
  11. package/src/@building/building.attachments.ts +82 -82
  12. package/src/@building/building.clean.ts +29 -29
  13. package/src/@building/building.create.ts +55 -41
  14. package/src/@building/building.enhance.ts +59 -59
  15. package/src/@building/building.geometry.ts +47 -47
  16. package/src/@building/building.headers.ts +36 -36
  17. package/src/@building/building.office.ts +42 -42
  18. package/src/@building/building.polygon.ts +69 -70
  19. package/src/@building/building.properties.ts +95 -95
  20. package/src/@building/building.signature.ts +60 -61
  21. package/src/@building/building.tags.ts +23 -23
  22. package/src/@building/building.tracking.ts +67 -67
  23. package/src/@building/building.validate.ts +152 -146
  24. package/src/@core/core.clearEvents.ts +30 -31
  25. package/src/@core/core.createListener.ts +23 -23
  26. package/src/@core/core.getEvents.ts +23 -24
  27. package/src/@core/core.getNodes.ts +23 -24
  28. package/src/@core/core.getRandomEvent.ts +23 -24
  29. package/src/@core/core.getVersion.ts +23 -24
  30. package/src/@core/core.manualEvent.ts +38 -0
  31. package/src/@core/core.query.ts +38 -38
  32. package/src/@core/core.setNode.ts +80 -80
  33. package/src/@core/core.start.ts +60 -60
  34. package/src/@core/core.stop.ts +31 -31
  35. package/src/@dictionaries/dictionaries.actions.ts +27 -27
  36. package/src/@dictionaries/dictionaries.awips.ts +363 -363
  37. package/src/@dictionaries/dictionaries.cancellation.ts +30 -30
  38. package/src/@dictionaries/dictionaries.causes.ts +35 -35
  39. package/src/@dictionaries/dictionaries.correlations.ts +42 -42
  40. package/src/@dictionaries/dictionaries.enhanced.ts +66 -109
  41. package/src/@dictionaries/dictionaries.events.ts +82 -82
  42. package/src/@dictionaries/dictionaries.expressions.ts +28 -28
  43. package/src/@dictionaries/dictionaries.global.ts +24 -0
  44. package/src/@dictionaries/dictionaries.hail.ts +35 -35
  45. package/src/@dictionaries/dictionaries.icao.ts +258 -258
  46. package/src/@dictionaries/dictionaries.matches.ts +54 -35
  47. package/src/@dictionaries/dictionaries.products.ts +24 -24
  48. package/src/@dictionaries/dictionaries.records.ts +25 -25
  49. package/src/@dictionaries/dictionaries.severity.ts +27 -27
  50. package/src/@dictionaries/dictionaries.shapefiles.ts +35 -35
  51. package/src/@dictionaries/dictionaries.states.ts +71 -71
  52. package/src/@dictionaries/dictionaries.status.ts +30 -30
  53. package/src/@dictionaries/dictionaries.tags.ts +92 -92
  54. package/src/@dictionaries/dictionaries.testing.ts +24 -24
  55. package/src/@events/events.api.ts +116 -118
  56. package/src/@events/events.text.ts +84 -81
  57. package/src/@events/events.ugc.ts +89 -85
  58. package/src/@events/events.vtec.ts +86 -87
  59. package/src/@manager/manager.mkEvent.ts +97 -88
  60. package/src/@manager/manager.rmEvent.ts +56 -49
  61. package/src/@manager/manager.setHash.ts +35 -36
  62. package/src/@manager/manager.updateEvents.ts +32 -34
  63. package/src/@manager/manager.updateListener.ts +154 -159
  64. package/src/@manager/manager.updateNodes.ts +53 -54
  65. package/src/@modules/@database/database.broadcastify.ts +66 -66
  66. package/src/@modules/@database/database.cache.ts +49 -47
  67. package/src/@modules/@database/database.init.ts +58 -57
  68. package/src/@modules/@database/database.shapefiles.ts +92 -92
  69. package/src/@modules/@database/database.stanza.ts +46 -47
  70. package/src/@modules/@eas/eas.getCleanDescription.ts +91 -91
  71. package/src/@modules/@eas/eas.getFloatPCM16.ts +29 -29
  72. package/src/@modules/@eas/eas.getMergedPCM16.ts +32 -32
  73. package/src/@modules/@eas/eas.getPCM16.ts +52 -52
  74. package/src/@modules/@eas/eas.getPCMToFloat.ts +26 -26
  75. package/src/@modules/@eas/eas.getSampledPCM16.ts +36 -36
  76. package/src/@modules/@eas/eas.getTTS.ts +54 -54
  77. package/src/@modules/@eas/eas.getWavPCM16.ts +52 -52
  78. package/src/@modules/@eas/eas.setAFSK.ts +51 -52
  79. package/src/@modules/@eas/eas.setAsciiToBits.ts +31 -32
  80. package/src/@modules/@eas/eas.setAttentionTone.ts +40 -40
  81. package/src/@modules/@eas/eas.setEasTone.ts +151 -147
  82. package/src/@modules/@eas/eas.setNoise.ts +32 -31
  83. package/src/@modules/@eas/eas.setRadioEffect.ts +50 -49
  84. package/src/@modules/@eas/eas.setSameHeader.ts +44 -45
  85. package/src/@modules/@stanza/stanza.getAwipsType.ts +45 -45
  86. package/src/@modules/@stanza/stanza.validate.ts +49 -49
  87. package/src/@modules/@utilities/utilities.createHttp.ts +70 -70
  88. package/src/@modules/@utilities/utilities.getFormattedTime.ts +43 -43
  89. package/src/@modules/@utilities/utilities.getLatestIssuance.ts +32 -32
  90. package/src/@modules/@utilities/utilities.getMatched.ts +33 -0
  91. package/src/@modules/@utilities/utilities.getSettings.ts +25 -25
  92. package/src/@modules/@utilities/utilities.getShapeNearestPoint.ts +114 -114
  93. package/src/@modules/@utilities/utilities.setCronSchedule.ts +94 -94
  94. package/src/@modules/@utilities/utilities.setDebug.ts +38 -0
  95. package/src/@modules/@utilities/utilities.setEventEmit.ts +41 -41
  96. package/src/@modules/@utilities/utilities.setListener.ts +30 -30
  97. package/src/@modules/@utilities/utilities.setSettings.ts +42 -42
  98. package/src/@modules/@utilities/utilities.setSleep.ts +33 -33
  99. package/src/@modules/@utilities/utilities.setTimeoutAction.ts +62 -58
  100. package/src/@modules/@utilities/utilities.setWarning.ts +34 -34
  101. package/src/@modules/@xmpp/xmpp.xDeploy.ts +57 -58
  102. package/src/@modules/@xmpp/xmpp.xError.ts +26 -28
  103. package/src/@modules/@xmpp/xmpp.xOffline.ts +36 -37
  104. package/src/@modules/@xmpp/xmpp.xOnline.ts +45 -44
  105. package/src/@modules/@xmpp/xmpp.xReconnect.ts +64 -64
  106. package/src/@modules/@xmpp/xmpp.xStanza.ts +62 -62
  107. package/src/@parsers/@hvtec/hvtec.extract.ts +39 -39
  108. package/src/@parsers/@pvtec/pvtec.expires.ts +25 -25
  109. package/src/@parsers/@pvtec/pvtec.extract.ts +48 -48
  110. package/src/@parsers/@text/text.getDescriptionFromProduct.ts +52 -52
  111. package/src/@parsers/@text/text.getEmbed.ts +55 -57
  112. package/src/@parsers/@text/text.getPolygonFromProduct.ts +53 -32
  113. package/src/@parsers/@text/text.getTextFromProduct.ts +42 -42
  114. package/src/@parsers/@text/text.getXML.ts +60 -60
  115. package/src/@parsers/@ugc/ugc.coordinates.ts +110 -109
  116. package/src/@parsers/@ugc/ugc.expiry.ts +31 -31
  117. package/src/@parsers/@ugc/ugc.extract.ts +36 -36
  118. package/src/@parsers/@ugc/ugc.getCache.ts +24 -0
  119. package/src/@parsers/@ugc/ugc.header.ts +29 -29
  120. package/src/@parsers/@ugc/ugc.locations.ts +57 -29
  121. package/src/@parsers/@ugc/ugc.setCache.ts +28 -0
  122. package/src/@parsers/@ugc/ugc.zones.ts +51 -51
  123. package/src/@types/type.attributes.ts +28 -28
  124. package/src/@types/type.compiled.ts +34 -34
  125. package/src/@types/type.event.ts +69 -69
  126. package/src/@types/type.hash.ts +24 -24
  127. package/src/@types/type.hvtec.ts +25 -25
  128. package/src/@types/type.listener.ts +32 -32
  129. package/src/@types/type.properties.ts +77 -77
  130. package/src/@types/type.pvtec.ts +30 -30
  131. package/src/@types/type.settings.ts +84 -83
  132. package/src/@types/type.stanza.ts +37 -37
  133. package/src/@types/type.ugc.ts +24 -24
  134. package/src/bootstrap.ts +115 -112
  135. package/src/index.ts +74 -74
  136. package/test.js +92 -98
  137. package/tsconfig.json +13 -13
  138. package/tsup.config.ts +15 -15
  139. package/dist/index.d.mts +0 -299
  140. package/dist/index.d.ts +0 -299
  141. package/src/@core/core.createEvent.ts +0 -83
package/README.md CHANGED
@@ -1,417 +1,443 @@
1
- # Project AtmosphericX - Event Product Parser (v3.0.0)
2
-
3
- <div align="center">
4
- <div align="center" style="border: none;">
5
- <img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/AtmosphericX/event-product-parser">
6
- <img alt="GitHub forks" src="https://img.shields.io/github/forks/AtmosphericX/event-product-parser">
7
- <img alt="GitHub issues" src="https://img.shields.io/github/issues/AtmosphericX/event-product-parser">
8
- <img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/AtmosphericX/event-product-parser">
9
- </div>
10
- </div>
11
-
12
- ## What is `@atmosx/event-product-parser`
13
- This repository contains the primary function to obtain, parse, cache, and deliver products and events from the National Weather Service. There are two primary sources to obtain these products. By default, the repository uses the **National Weather Service API**. However, there is **FULL** support for **NOAA Weather Wire Service (Open Interface)**. This parser is intended for developers who want to integrate real-time weather alerts, watches, warnings, and forecast data from the NWS seamlessly into their applications or services without having to use external APIs from other sources / parsers. If you wish to access data without programming, consider using our end user project, which leverages this parser and provides an easy-to-use interface for tracking weather alerts. See [Documentation](https://atmosphericx.scriptkitty.cafe).
14
-
15
- ## Installation (NPM)
16
- ```bash
17
- npm install @atmosx/event-product-parser
18
- ```
19
-
20
- ## Configurations & Usage
21
- ```ts
22
- const { Manager } = require(`@atmosx/event-product-parser`) // CJS Importing
23
- import { Manager } from '@atmosx/event-product-parser' // EJS Importing
24
-
25
- const Client = new Manager({
26
- Database: `shapefiles.db`,
27
- EnableWireService: false,
28
- EnableJournal: true,
29
- NOAAWeatherWireServiceSettings: {
30
- ReconnectionSettings: {
31
- Enabled: true,
32
- ReconnectionInterval: 60,
33
- },
34
- CredentialSettings: {
35
- Username: `username`,
36
- Password: `password`,
37
- Nickname: "nickname (@atmosx/event-product-parser/3.0)",
38
- },
39
- CacheSettings: {
40
- Enabled: true,
41
- MaxDatabaseHistory: 5000,
42
- MaxRetentionHistory: 555,
43
- },
44
- StanzaSettings: {
45
- DisableUGC: false,
46
- DisableVTEC: false,
47
- DisableText: false,
48
- }
49
- },
50
- NationalWeatherServiceSettings: {
51
- CallbackInterval: 30,
52
- EventsEndpoint: `https://api.weather.gov/alerts/active`,
53
- },
54
- BroadcastifySettings: {
55
- BroadcastifyAttachments: true,
56
- BroadcastifyTags: [`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`]
57
- },
58
- ListenerSettings: [
59
- {
60
- events: [`*Thunderstorm Warning*`, `* Watch`],
61
- webhook: {
62
- enabled: true,
63
- destination: "https://discord.com/api/XXXXXXXXXX/XXXXXXXXXXX",
64
- title: "AtmosphericX - (Thunderstorm Warnings and Watches)",
65
- message: "<@&XXXXXXXXXXXXXXXXXXXXX>",
66
- ratelimit: 1
67
- },
68
- uploads: {
69
- eas: true,
70
- file: true,
71
- event: true
72
- }
73
- }
74
- ],
75
- GlobalSettings: {
76
- EventManagement: true,
77
- BetterEventNames: true,
78
- DisableGeometryParsing: false,
79
- UseShapefileCoordinates: true,
80
- SPCWatchesOnly: true,
81
- ShapefileSkipPoints: 0,
82
- NodeTTL: 60,
83
- NodeMinDistance: 120,
84
- EventFiltering: {
85
- ListeningEvents: [
86
- "Tornado Emergency", "PDS Tornado Warning", "Tornado Warning",
87
- "Confirmed Tornado Warning", "Radar Indicated Tornado Warning",
88
- "Special Marine Warning (TPROB)", "PDS Tornado Watch", "Tornado Watch",
89
- "EDS Severe Thunderstorm Warning (TPROB)", "EDS Severe Thunderstorm Warning",
90
- "Destructive Severe Thunderstorm Warning (TPROB)", "Destructive Severe Thunderstorm Warning",
91
- "Considerable Severe Thunderstorm Warning (TPROB)", "Considerable Severe Thunderstorm Warning",
92
- "Severe Thunderstorm Warning (TPROB)", "Severe Thunderstorm Warning",
93
- "Severe Thunderstorm Watch",
94
- "Flash Flood Emergency", "Flash Flood Warning",
95
- "Flash Flood Watch",
96
- "Tsunami Warning", "Tsunami Watch",
97
- "Tsunami Advisory", "Special Marine Warning",
98
- "Earthquake Warning",
99
- "Hurricane Warning", "Hurricane Watch",
100
- "Tropical Storm Warning",
101
- "Winter Storm Warning", "Blizzard Warning",
102
- "Ice Storm Warning", "Snow Squall Warning",
103
- "Winter Weather Advisory", "Extreme Cold Watch"
104
- ],
105
- ListeningICAO: [],
106
- IgnoredICAO: [],
107
- IgnoredEvents: [],
108
- ListeningUGC: [],
109
- ListeningStates: [],
110
- NodeLocationFiltering: false,
111
- IgnoreTestProducts: true,
112
- },
113
- ArchiveSettings: {
114
- TTL: 600,
115
- EventDirectory: `Storage/EventProducts`,
116
- TextDirectory: `Storage/TextProducts`,
117
- EasDirectory: `Storage/EasScenarios`,
118
- EasToneout: `tone.wav`,
119
- }
120
- }
121
- })
122
- ```
123
- ### General Settings
124
- - **Database**: The database file name and location, please make sure to include the `.db` extension.
125
- - **EnableWireService**: Whether to enable `NOAA Weather Wire Service` within the parser. This requires credentials from [NOAA Weather Wire Service](https://www.weather.gov/nwws/).
126
- - **EnableJournal**: Whether to output logs without requiring event `listeners`.
127
-
128
- ### NOAAWeatherWireServiceSettings
129
- - **ReconnectionSettings**: When the XMPP client gets disconnected or has an error, choose to reconnect to the service again. This contains a reconnection check interval.
130
- - **CredentialSettings**: The username (nickname) and password that is required for using `NOAA Weather Wire Service`.
131
- - **CacheSettings**: The ability to use the cache system so when you relaunch the parser, it will have a event retention history of all the stanzas collected.
132
- - **StanzaSettings**: Modify what type of products metadata you'd like to receive. (UGC, VTEC, RawText)
133
-
134
- ### NationalWeatherServiceSettings
135
- - **CallbackInterval**: The interval at which the parser will check for new alerts from the National Weather Service API.
136
- - **EventsEndpoint**: The URL that directs to the API.
137
-
138
- ## BroadcastifySettings
139
- - **BroadcastifyAttachments**: Whether to enable broadcastify attachments for events.
140
- - **BroadcastifyDatabase**: The download url to point to for the collection of broadcastify feeds. (Stored locally once downloaded)
141
- - **BroadcastifyTags**: An array of tags to filter broadcastify feeds. (`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`)
142
-
143
- ### ListenerSettings
144
- - **events**: An array of event types that will trigger the listener when they are received by the parser. If this array is empty, the listener will be triggered for all events.
145
-
146
- #### Webhook
147
- - **enabled**: If the webhook is enabled or not
148
- - **destination**: Webhook URL
149
- - **title**: The title of the webhook
150
- - **message**: The message you'd like to use for the webhook
151
- - **ratelimit**: How many messages can it send before being ratelimited
152
-
153
- #### Uploads
154
- - **eas**: Whether to enable auto eas generated audio files
155
- - **file**: Wheather to generate text files
156
-
157
-
158
- ### GlobalSettings
159
- - **EventManagement**: Whether to enable the event management system which includes filtering, tracking nodes, and custom messages.
160
- - **BetterEventNames**: Changes events to a more specific version depending on parameters, message types, etc. `(Ex. "Tornado Warning" -> "Observed Tornado Warning")`
161
- - **DisableGeometryParsing**: Disable automatically appending GeoJSON geometry data to the events to save on memory consumption.
162
- - **UseShapefileCoordinates**: Whether to use the shapefile database to obtain the coordinates for events with specified UGC zones.
163
- - **SPCWatchesOnly**: Whether to only listen for SPC watches only (TOR/SVR) (If using the API, this is ignored).
164
- - **ShapefileSkipPoints**: When using the shapefile database to obtain coordinates, you can choose to skip a certain amount of points to reduce the number of coordinates for large events. (Ex. If an event has 1000 coordinates and you set this to `2`, it will only use every other coordinate, therefore using 500 coordinates instead of 1000).
165
- - **NodeTTL**: How often nodes should be checked per event. (Tracking/Filtering)
166
- - **NodeMinDistance**: The minimum distance to filter events from the node (Miles)
167
- - **ListeningEvents**: Events you'd like to listen for. If this array is left empty, it will listen for **ALL** events and products.
168
- - **ListeningICAO**: ICAO codes for the weather stations you'd like to listen for. Filtering all events that do not contain the codes. `(Ex. ["KLOT", "TORD"])`
169
- - **IgnoredICAO**: Ignored ICAO codes `(Ex. ["KWNS"])`
170
- - **IgnoredEvents**: Ignored events / products.
171
- - **ListeningUGC**: Zones you'd like to listen to `(Ex. ["ILZ001"])`
172
- - **ListeningStates**: States you'd like to listen to `(Ex. ["IL"])`
173
- - **NodeLocationFiltering**: If you want tracking nodes to filter out events based on radius. (Miles)\
174
- - **IgnoreTextProducts**: If you want to ignore test products and events.
175
- - **TTL**: How long files live for before getting automatically deleted
176
- - **TextDirectory**: The location to store text products that are generated.
177
- - **EasDirectory**: The location to store audio eas files that are generated.
178
- - **EasToneout**: The toneout prefix to use for generated eas messages.
179
-
180
- ## Events and Listeners
181
-
182
- ### Event `*`
183
- Triggers for every event and product received by the parser. This is useful if you want to handle all events with a single listener.
184
- ```ts
185
- Client.on(`*`, (data: any) => {
186
- /*
187
- event: string
188
- data: object
189
- */
190
- })
191
- ```
192
-
193
- ### Event `onServiceStatus`
194
- Triggers when an update to the XMPP / API service status occurs.
195
- ```ts
196
- Client.on(`onServiceStatus`, (xmpp) => {
197
- /*
198
- message: string
199
- data: object
200
- type: string
201
- error: boolean
202
- */
203
- })
204
- ```
205
-
206
- ### Event `onTestProduct`
207
- Triggers when a event is labeled as a **test message**. See [`types.event.ts`](./src/@types/type.event.ts) for properties.
208
- ```ts
209
- Client.on(`onTestProduct`, (product: TypeEvent) => {})
210
- ```
211
-
212
- ### Event `onExpiredProduct`
213
- Triggers when a event is cancelled, expired, or terminated. See [`types.event.ts`](./src/@types/type.event.ts) for properties.
214
- ```ts
215
- Client.on(`onExpiredProduct`, (product: TypeEvent) => {})
216
- ```
217
-
218
- ### Event `onProductType`
219
- Supports all events and product, simply append the event name to the end like `onProductTypeRadarIndicatedTornadoWarning` and you will receive the event in the listener.
220
- This listener returns [`types.event.ts`](./src/@types/type.event.ts).
221
- ```ts
222
- Client.on(`onProductTypeRadarIndicatedTornadoWarning`, (product: TypeEvent) => {})
223
- ```
224
-
225
- ### Event `onFilteredEvent`, `onIgnoredEvent`, `onFilteredICAO`, `onIgnoredICAO`, `onFilteredUGC`, `onFilteredState`
226
- These events all support [`types.event.ts`](./src/@types/type.event.ts) and are used to filter out events and products based on your settings.
227
- ```ts
228
- Client.on(`onFilteredEvent`, (product: TypeEvent) => {})
229
- ```
230
-
231
- ### Event `onEventCache`
232
- When all events in a batch have finished processing, a cache update will trigger allowing you to get a copy of all registered events in a listener. (**GeoJSON**)
233
- ```ts
234
- Client.on(`onEventCache`, (cache) => {})
235
- ```
236
-
237
- ### Event `onNodeAdd`, `onNodeUpdate`, `onNodeDelete`
238
- Triggers when a tracking node gets added, updated, or deleted.
239
- ```ts
240
- Client.on(`onNodeAdd`, (cache) => {
241
- /*
242
- type: string
243
- node: object
244
- */
245
- })
246
- ```
247
-
248
- ### Event `onStormPredictionWatch`, `onNonStormPredictionWatch`
249
- Triggers when a SPC watch gets added, updated, or cancelled. This will also add a custom message if using jorunal or the `log` listener.
250
- ```ts
251
- Client.on(`onProductTypeRadarIndicatedTornadoWarning`, (product: TypeEvent) => {})
252
- ```
253
-
254
- ### Event `onEventStatus`
255
- Triggers when a single event gets added, updated, or cancelled. This will also add a custom message if using jorunal or the `log` listener.
256
- ```ts
257
- Client.on(`onEventStatus`, (cache) => {
258
- /*
259
- type: string
260
- event: <TypeEvent>
261
- */
262
- })
263
- ```
264
-
265
- ### Function `setSettings`
266
- Allows you to dynamically update parser settings without restarting the service.
267
- ```ts
268
- import { setSettings } from "@atmosx/event-product-parser"
269
- setSettings({
270
- Database: `NewDatabaseFile.db`
271
- })
272
- ```
273
-
274
- ### Function `getEventGeometry`
275
- Fetches the `events` geometry (GeoJSON) coordinates table.
276
- ```ts
277
- import { getEventGeometry } from "@atmosx/event-product-parser"
278
- const event = {...}
279
- const geometry = await getEventGeometry(event); // Returns GeoJSON
280
- ```
281
-
282
- ### Function `getRandomEvent`
283
- Fetches a random event from the cache
284
- ```ts
285
- import { getRandomEvent } from "@atmosx/event-product-parser"
286
- const event = getRandomEvent(event); // Returns GeoJSON of an event.
287
- ```
288
-
289
- ### Function `getVersion`
290
- Returns the current version of the parser.
291
- ```ts
292
- import { getVersion } from "@atmosx/event-product-parser"
293
- const version = getVersion(); // Returns the current version of the parser.
294
- ```
295
-
296
-
297
- ### Function `getCleanedEvent`
298
- Removed any `NULL` values from the event itself. Therefore cleaning it up from any properties that are `NULL`.
299
- ```ts
300
- import { getCleanedEvent } from "@atmosx/event-product-parser"
301
- const event = {...}
302
- const cleanedEvent = await getCleanedEvent(event); // Returns cleaned event object.
303
- ```
304
-
305
-
306
- ### Function `startService`
307
- Starts the event product parser service.
308
- ```ts
309
- import { startService } from "@atmosx/event-product-parser"
310
- startService()
311
- ```
312
-
313
-
314
- ### Function `setNode`
315
- Sets up a tracking node using an identifier, longitude, and latitude values.
316
- ```ts
317
- import { setNode } from "@atmosx/event-product-parser"
318
- setNode({
319
- identifier: `TestNode`,
320
- coordinates: {longitude: -122.4194, latitude: 37.7749},
321
- delete: false
322
- })
323
- ```
324
-
325
-
326
- ### Function `getEvents`
327
- Fetches the list of events from the parser.
328
- ```ts
329
- import { getEvents } from "@atmosx/event-product-parser"
330
- const events = getEvents() // Returns in GeoJSON (Similar to the onEventCache listener)
331
- console.log(events)
332
- ```
333
-
334
- ### Function `clearEvents`
335
- Clears the event cache of all events.
336
- ```ts
337
- import { clearEvents } from "@atmosx/event-product-parser"
338
- clearEvents() // Clears the event cache of all events.
339
- ```
340
-
341
- ### Function `getNodes`
342
- Fetches the list of tracking nodes from the parser.
343
- ```ts
344
- import { getNodes } from "@atmosx/event-product-parser"
345
- const nodes = getNodes()
346
- console.log(nodes)
347
- ```
348
-
349
- ### Function `createEvent`
350
- Creates a new event in the parser.
351
- ```ts
352
- import { createEvent } from "@atmosx/event-product-parser"
353
- createEvent({
354
- event: `PDS Ice Storm Warning`,
355
- status: `Upgraded`,
356
- issued: new Date(),
357
- expires: new Date(Date.now() + 3600000),
358
- locations: `Somewhere USA`,
359
- description: `This is a test event sample.`,
360
- coordinates: [
361
- [-122.4194, 37.7749],
362
- [-122.4194, 37.7749]
363
- ]
364
- })
365
- ```
366
-
367
- ### Function `query`
368
- Queries the event cache (datbase) for specific events based on text.
369
- ```ts
370
- import { query } from "@atmosx/event-product-parser"
371
- query({search: "Tornado Warning", limit: 3}).then(results => {
372
- console.log(results)
373
- })
374
- ````
375
-
376
- ### Function `setEasTone`
377
- Fetches an EAS audio message for an event (Simulated)
378
- ```ts
379
- import { setEasTone } from "@atmosx/event-product-parser"
380
- const event = {...}
381
- await setEasTone({message: event.properties.description, header: event.properties.metadata.header, title: `eas_audio_message`})
382
- ```
383
-
384
-
385
- ## Types
386
- [Event](./src/@types/type.event.ts) |
387
- [Properties](./src/@types/type.properties.ts) |
388
- [HVTec](./src/@types/type.hvtec.ts) |
389
- [PVTec](./src/@types/type.pvtec.ts) |\
390
- [UGC](./src/@types/type.ugc.ts) |
391
- [Stanzas](./src/@types/type.stanza.ts) |
392
- [Attributes](./src/@types/type.attributes.ts) |
393
-
394
- ## Supported Events
395
- `@atmosx/event-product-parser` natively supports and ingests **300+** NWS Text products using VTEC, UGC, and various text parsing techniues.
396
- If you wish to view all supported products, please see: [SUPPORTED_EVENTS.md](./SUPPORTED_EVENTS.md)
397
-
398
-
399
- ## Performance Recommendations
400
- - Enable cache retention
401
- - Disable geometry parsing if GeoJSON is unnecessary.
402
-
403
- ## References
404
- [NOAA NWWS Information](https://www.weather.gov/nwws/) |
405
- [NWS API Documentation](https://www.weather.gov/documentation/services-web-api) |
406
- [XMPP Protocol](https://xmpp.org/about/technology-overview/) |
407
- [AtmosphericX](https://github.com/k3yomi/AtmosphericX) |\
408
- [Documentation](https://atmosphericx.scriptkitty.cafe/documentation) |
409
- [Discord Server](https://atmosphericx-discord.scriptkitty.cafe) |
410
- [Project Board](https://github.com/users/AtmosphericX/projects/2) |\
411
- [Code of Conduct](/CODE_OF_CONDUCT.md) |
412
- [Contributing](/CONTRIBUTING.md) |
413
- [License](/LICENSE) |
414
- [Security](/SECURITY.md) |
415
-
416
- ## Acknowledgements
417
- - [k3yomi](https://github.com/k3yomi)
1
+ # Project AtmosphericX - Event Product Parser (v3.0.0)
2
+
3
+ <div align="center">
4
+ <div align="center" style="border: none;">
5
+ <img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/AtmosphericX/event-product-parser">
6
+ <img alt="GitHub forks" src="https://img.shields.io/github/forks/AtmosphericX/event-product-parser">
7
+ <img alt="GitHub issues" src="https://img.shields.io/github/issues/AtmosphericX/event-product-parser">
8
+ <img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/AtmosphericX/event-product-parser">
9
+ </div>
10
+ </div>
11
+
12
+ ## What is `@atmosx/event-product-parser`
13
+ This repository contains the primary function to obtain, parse, cache, and deliver products and events from the National Weather Service. There are two primary sources to obtain these products. By default, the repository uses the **National Weather Service API**. However, there is **FULL** support for **NOAA Weather Wire Service (Open Interface)**. This parser is intended for developers who want to integrate real-time weather alerts, watches, warnings, and forecast data from the NWS seamlessly into their applications or services without having to use external APIs from other sources / parsers. If you wish to access data without programming, consider using our end user project, which leverages this parser and provides an easy-to-use interface for tracking weather alerts. See [Documentation](https://atmosphericx.scriptkitty.cafe).
14
+
15
+ ## Installation (NPM)
16
+ ```bash
17
+ npm install @atmosx/event-product-parser
18
+ ```
19
+
20
+ ## Configurations & Usage
21
+ ```ts
22
+ const { Manager } = require(`@atmosx/event-product-parser`) // CJS Importing
23
+ import { Manager } from '@atmosx/event-product-parser' // EJS Importing
24
+
25
+ const Client = new Manager({
26
+ Database: `shapefiles.db`,
27
+ EnableWireService: false,
28
+ EnableJournal: true,
29
+ EnableDebugging: false,
30
+ NOAAWeatherWireServiceSettings: {
31
+ ReconnectionSettings: {
32
+ Enabled: true,
33
+ ReconnectionInterval: 60,
34
+ },
35
+ CredentialSettings: {
36
+ Username: `username`,
37
+ Password: `password`,
38
+ Nickname: "nickname (@atmosx/event-product-parser/3.0)",
39
+ },
40
+ CacheSettings: {
41
+ Enabled: true,
42
+ MaxDatabaseHistory: 5000,
43
+ MaxRetentionHistory: 555,
44
+ },
45
+ StanzaSettings: {
46
+ DisableUGC: false,
47
+ DisableVTEC: false,
48
+ DisableText: false,
49
+ }
50
+ },
51
+ NationalWeatherServiceSettings: {
52
+ CallbackInterval: 30,
53
+ EventsEndpoint: `https://api.weather.gov/alerts/active`,
54
+ },
55
+ BroadcastifySettings: {
56
+ BroadcastifyAttachments: true,
57
+ BroadcastifyTags: [`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`]
58
+ },
59
+ ListenerSettings: [
60
+ {
61
+ events: [`*Thunderstorm Warning*`, `* Watch`],
62
+ webhook: {
63
+ enabled: true,
64
+ destination: "https://discord.com/api/XXXXXXXXXX/XXXXXXXXXXX",
65
+ title: "AtmosphericX - (Thunderstorm Warnings and Watches)",
66
+ message: "<@&XXXXXXXXXXXXXXXXXXXXX>",
67
+ ratelimit: 1
68
+ },
69
+ uploads: {
70
+ eas: true,
71
+ file: true,
72
+ event: true
73
+ }
74
+ }
75
+ ],
76
+ GlobalSettings: {
77
+ EventManagement: true,
78
+ BetterEventNames: true,
79
+ DisableGeometryParsing: false,
80
+ UseShapefileCoordinates: true,
81
+ SPCWatchesOnly: true,
82
+ ShapefileSkipPoints: 0,
83
+ NodeTTL: 60,
84
+ NodeMinDistance: 120,
85
+ EventFiltering: {
86
+ ListeningEvents: [
87
+ "*Severe Thunderstorm Warning*",
88
+ "*Blizzard*", "*Ice Storm*", "*Winter Storm*", "*Snow Squall*",
89
+ "Tornado Emergency", "*Tornado Warning*",
90
+ "Special Weather Statement", "Marine Weather Statement",
91
+ "*Tsunami*", "*Hurricane*", "*Tropical Storm*", "*Special Marine*",
92
+ "*Flash Flood Warning*", "*Flash Flood Watch*", "*Flash Flood Advisory*",
93
+ "Mesoscale Discussion",
94
+ "SPC Day 1 Outlook", "SPC Day 2 Outlook", "SPC Day 3 Outlook",
95
+ "PDS Tornado Watch", "Tornado Watch", "Severe Thunderstorm Watch", "Flash Flood Watch", "PDS Severe Thunderstorm Watch",
96
+ "*Administrative*", "National Weather Service Policy",
97
+ "Fire Weather Warning", "Fire Weather Watch", "Fire Weather Advisory",
98
+ ],
99
+ ListeningICAO: [`KLOT`],
100
+ IgnoredICAO: [],
101
+ IgnoredEvents: [],
102
+ ListeningUGC: [`WIC001`],
103
+ ListeningStates: [`MO`, `IA`],
104
+ NodeLocationFiltering: false,
105
+ IgnoreTestProducts: true,
106
+ },
107
+ ArchiveSettings: {
108
+ TTL: 600,
109
+ EventDirectory: `Storage/EventProducts`,
110
+ TextDirectory: `Storage/TextProducts`,
111
+ EasDirectory: `Storage/EasScenarios`,
112
+ EasToneout: `tone.wav`,
113
+ }
114
+ }
115
+ })
116
+ ```
117
+ ### General Settings
118
+ - **Database**: The database file name and location, please make sure to include the `.db` extension.
119
+ - **EnableWireService**: Whether to enable `NOAA Weather Wire Service` within the parser. This requires credentials from [NOAA Weather Wire Service](https://www.weather.gov/nwws/).
120
+ - **EnableJournal**: Whether to output logs without requiring event `listeners`.
121
+
122
+ ### NOAAWeatherWireServiceSettings
123
+ - **ReconnectionSettings**: When the XMPP client gets disconnected or has an error, choose to reconnect to the service again. This contains a reconnection check interval.
124
+ - **CredentialSettings**: The username (nickname) and password that is required for using `NOAA Weather Wire Service`.
125
+ - **CacheSettings**: The ability to use the cache system so when you relaunch the parser, it will have a event retention history of all the stanzas collected.
126
+ - **StanzaSettings**: Modify what type of products metadata you'd like to receive. (UGC, VTEC, RawText)
127
+
128
+ ### NationalWeatherServiceSettings
129
+ - **CallbackInterval**: The interval at which the parser will check for new alerts from the National Weather Service API.
130
+ - **EventsEndpoint**: The URL that directs to the API.
131
+
132
+ ## BroadcastifySettings
133
+ - **BroadcastifyAttachments**: Whether to enable broadcastify attachments for events.
134
+ - **BroadcastifyDatabase**: The download url to point to for the collection of broadcastify feeds. (Stored locally once downloaded)
135
+ - **BroadcastifyTags**: An array of tags to filter broadcastify feeds. (`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`)
136
+
137
+ ### ListenerSettings
138
+ - **events**: An array of event types that will trigger the listener when they are received by the parser. If this array is empty, the listener will be triggered for all events.
139
+
140
+ #### Webhook
141
+ - **enabled**: If the webhook is enabled or not
142
+ - **destination**: Webhook URL
143
+ - **title**: The title of the webhook
144
+ - **message**: The message you'd like to use for the webhook
145
+ - **ratelimit**: How many messages can it send before being ratelimited
146
+
147
+ #### Uploads
148
+ - **eas**: Whether to enable auto eas generated audio files
149
+ - **file**: Wheather to generate text files
150
+
151
+
152
+ ### GlobalSettings
153
+ - **EventManagement**: Whether to enable the event management system which includes filtering, tracking nodes, and custom messages.
154
+ - **BetterEventNames**: Changes events to a more specific version depending on parameters, message types, etc. `(Ex. "Tornado Warning" -> "Observed Tornado Warning")`
155
+ - **DisableGeometryParsing**: Disable automatically appending GeoJSON geometry data to the events to save on memory consumption.
156
+ - **UseShapefileCoordinates**: Whether to use the shapefile database to obtain the coordinates for events with specified UGC zones.
157
+ - **SPCWatchesOnly**: Whether to only listen for SPC watches only (TOR/SVR) (If using the API, this is ignored).
158
+ - **ShapefileSkipPoints**: When using the shapefile database to obtain coordinates, you can choose to skip a certain amount of points to reduce the number of coordinates for large events. (Ex. If an event has 1000 coordinates and you set this to `2`, it will only use every other coordinate, therefore using 500 coordinates instead of 1000).
159
+ - **NodeTTL**: How often nodes should be checked per event. (Tracking/Filtering)
160
+ - **NodeMinDistance**: The minimum distance to filter events from the node (Miles)
161
+ - **ListeningEvents**: Events you'd like to listen for. If this array is left empty, it will listen for **ALL** events and products.
162
+ - **ListeningICAO**: ICAO codes for the weather stations you'd like to listen for. Filtering all events that do not contain the codes. `(Ex. ["KLOT", "TORD"])`
163
+ - **IgnoredICAO**: Ignored ICAO codes `(Ex. ["KWNS"])`
164
+ - **IgnoredEvents**: Ignored events / products.
165
+ - **ListeningUGC**: Zones you'd like to listen to `(Ex. ["ILZ001"])`
166
+ - **ListeningStates**: States you'd like to listen to `(Ex. ["IL"])`
167
+ - **NodeLocationFiltering**: If you want tracking nodes to filter out events based on radius. (Miles)\
168
+ - **IgnoreTextProducts**: If you want to ignore test products and events.
169
+ - **TTL**: How long files live for before getting automatically deleted
170
+ - **TextDirectory**: The location to store text products that are generated.
171
+ - **EasDirectory**: The location to store audio eas files that are generated.
172
+ - **EasToneout**: The toneout prefix to use for generated eas messages.
173
+
174
+
175
+ ## How do custom listeners work?
176
+
177
+ Custom listeners are case insensitive rules used by `ListeningEvents`, `IgnoredEvents`, and ListenerSettings `events` to determine whether an input matches.
178
+
179
+ They support:
180
+ - Exact matches (e.g. `"Tornado Watch"`)
181
+ - Global wildcard (`"*"` matches everything)
182
+ - Partial wildcards (`*text*` matches anything containing that text)
183
+
184
+ Example rules:
185
+ ```json
186
+ ["*Severe Thunderstorm Warning*", "Tornado Watch", "*Flash Flood Warning*"]
187
+ ```
188
+
189
+ Example Results:
190
+ - Considerable Severe Thunderstorm Warning: ✅
191
+ - Tornado Warning: ❌
192
+ - Severe Thunderstorm Warning (TPROB): ✅
193
+ - Flash Flood Emergency: ❌
194
+
195
+ ## Events and Listeners
196
+
197
+ ### Event `*`
198
+ Triggers for every event and product received by the parser. This is useful if you want to handle all events with a single listener.
199
+ ```ts
200
+ Client.on(`*`, (data: any) => {
201
+ /*
202
+ event: string
203
+ data: object
204
+ */
205
+ })
206
+ ```
207
+
208
+ ### Event `onServiceStatus`
209
+ Triggers when an update to the XMPP / API service status occurs.
210
+ ```ts
211
+ Client.on(`onServiceStatus`, (xmpp) => {
212
+ /*
213
+ message: string
214
+ data: object
215
+ type: string
216
+ error: boolean
217
+ */
218
+ })
219
+ ```
220
+
221
+ ### Event `onTestProduct`
222
+ Triggers when a event is labeled as a **test message**. See [`types.event.ts`](./src/@types/type.event.ts) for properties.
223
+ ```ts
224
+ Client.on(`onTestProduct`, (product: TypeEvent) => {})
225
+ ```
226
+
227
+ ### Event `onExpiredProduct`
228
+ Triggers when a event is cancelled, expired, or terminated. See [`types.event.ts`](./src/@types/type.event.ts) for properties.
229
+ ```ts
230
+ Client.on(`onExpiredProduct`, (product: TypeEvent) => {})
231
+ ```
232
+
233
+ ### Event `onProductType`
234
+ Supports all events and product, simply append the event name to the end like `onProductTypeRadarIndicatedTornadoWarning` and you will receive the event in the listener.
235
+ **If the event has been filtered, it will not include attachments and coordinates.** See [`types.event.ts`](./src/@types/type.event.ts) for properties.
236
+
237
+ ```ts
238
+ This listener returns [`types.event.ts`](./src/@types/type.event.ts).
239
+ ```ts
240
+ Client.on(`onProductTypeRadarIndicatedTornadoWarning`, (product: TypeEvent) => {})
241
+ ```
242
+
243
+ ### Event `onFilteredEvent`, `onIgnoredEvent`, `onFilteredICAO`, `onIgnoredICAO`, `onFilteredUGC`, `onFilteredState`
244
+ These events all support [`types.event.ts`](./src/@types/type.event.ts) and are used to filter out events and products based on your settings.
245
+ ```ts
246
+ Client.on(`onFilteredEvent`, (product: TypeEvent) => {})
247
+ ```
248
+
249
+ ### Event `onEventCache`
250
+ When all events in a batch have finished processing, a cache update will trigger allowing you to get a copy of all registered events in a listener. (**GeoJSON**)
251
+ ```ts
252
+ Client.on(`onEventCache`, (cache) => {})
253
+ ```
254
+
255
+ ### Event `onNodeAdd`, `onNodeUpdate`, `onNodeDelete`
256
+ Triggers when a tracking node gets added, updated, or deleted.
257
+ ```ts
258
+ Client.on(`onNodeAdd`, (cache) => {
259
+ /*
260
+ type: string
261
+ node: object
262
+ */
263
+ })
264
+ ```
265
+
266
+ ### Event `onStormPredictionWatch`, `onNonStormPredictionWatch`
267
+ Triggers when a SPC watch gets added, updated, or cancelled. This will also add a custom message if using jorunal or the `log` listener.
268
+ ```ts
269
+ Client.on(`onProductTypeRadarIndicatedTornadoWarning`, (product: TypeEvent) => {})
270
+ ```
271
+
272
+ ### Event `onEventStatus`
273
+ Triggers when a single event gets added, updated, or cancelled. This will also add a custom message if using jorunal or the `log` listener.
274
+ ```ts
275
+ Client.on(`onEventStatus`, (cache) => {
276
+ /*
277
+ type: string
278
+ event: <TypeEvent>
279
+ */
280
+ })
281
+ ```
282
+
283
+ ### Event `debug`
284
+ Triggers when a debug message gets emitted, this can automatically be used without the listener by enabling `EnableDebugger`. This also includes the `parent` and the `function` names.
285
+ ```ts
286
+ Client.on(`debug`, (debug) => {
287
+ /*
288
+ message: string
289
+ parent: string
290
+ function: string
291
+ */
292
+ })
293
+ ```
294
+
295
+ ### Function `setSettings`
296
+ Allows you to dynamically update parser settings without restarting the service.
297
+ ```ts
298
+ import { setSettings } from "@atmosx/event-product-parser"
299
+ setSettings({
300
+ Database: `NewDatabaseFile.db`
301
+ })
302
+ ```
303
+
304
+ ### Function `getEventGeometry`
305
+ Fetches the `events` geometry (GeoJSON) coordinates table.
306
+ ```ts
307
+ import { getEventGeometry } from "@atmosx/event-product-parser"
308
+ const event = {...}
309
+ const geometry = await getEventGeometry(event); // Returns GeoJSON
310
+ ```
311
+
312
+ ### Function `getRandomEvent`
313
+ Fetches a random event from the cache
314
+ ```ts
315
+ import { getRandomEvent } from "@atmosx/event-product-parser"
316
+ const event = getRandomEvent(event); // Returns GeoJSON of an event.
317
+ ```
318
+
319
+ ### Function `getVersion`
320
+ Returns the current version of the parser.
321
+ ```ts
322
+ import { getVersion } from "@atmosx/event-product-parser"
323
+ const version = getVersion(); // Returns the current version of the parser.
324
+ ```
325
+
326
+
327
+ ### Function `getCleanedEvent`
328
+ Removed any `NULL` values from the event itself. Therefore cleaning it up from any properties that are `NULL`.
329
+ ```ts
330
+ import { getCleanedEvent } from "@atmosx/event-product-parser"
331
+ const event = {...}
332
+ const cleanedEvent = await getCleanedEvent(event); // Returns cleaned event object.
333
+ ```
334
+
335
+
336
+ ### Function `startService`
337
+ Starts the event product parser service.
338
+ ```ts
339
+ import { startService } from "@atmosx/event-product-parser"
340
+ startService()
341
+ ```
342
+
343
+
344
+ ### Function `setNode`
345
+ Sets up a tracking node using an identifier, longitude, and latitude values.
346
+ ```ts
347
+ import { setNode } from "@atmosx/event-product-parser"
348
+ setNode({
349
+ identifier: `TestNode`,
350
+ coordinates: {longitude: -122.4194, latitude: 37.7749},
351
+ delete: false
352
+ })
353
+ ```
354
+
355
+
356
+ ### Function `getEvents`
357
+ Fetches the list of events from the parser.
358
+ ```ts
359
+ import { getEvents } from "@atmosx/event-product-parser"
360
+ const events = getEvents() // Returns in GeoJSON (Similar to the onEventCache listener)
361
+ console.log(events)
362
+ ```
363
+
364
+ ### Function `clearEvents`
365
+ Clears the event cache of all events.
366
+ ```ts
367
+ import { clearEvents } from "@atmosx/event-product-parser"
368
+ clearEvents() // Clears the event cache of all events.
369
+ ```
370
+
371
+ ### Function `getNodes`
372
+ Fetches the list of tracking nodes from the parser.
373
+ ```ts
374
+ import { getNodes } from "@atmosx/event-product-parser"
375
+ const nodes = getNodes()
376
+ console.log(nodes)
377
+ ```
378
+
379
+ ### Function `manualEvent`
380
+ Creates a new event in the parser.
381
+ ```ts
382
+ import { manualEvent } from "@atmosx/event-product-parser"
383
+ manualEvent({
384
+ message: `__DESCRIPTION__`,
385
+ attributes: {
386
+ "issue": new Date().toISOString(),
387
+ "cccc": "KLOT",
388
+ "awipsid": "TORLOT",
389
+ }
390
+ })
391
+ ```
392
+
393
+ ### Function `query`
394
+ Queries the event cache (datbase) for specific events based on text.
395
+ ```ts
396
+ import { query } from "@atmosx/event-product-parser"
397
+ query({search: "Tornado Warning", limit: 3}).then(results => {
398
+ console.log(results)
399
+ })
400
+ ````
401
+
402
+ ### Function `setEasTone`
403
+ Fetches an EAS audio message for an event (Simulated)
404
+ ```ts
405
+ import { setEasTone } from "@atmosx/event-product-parser"
406
+ const event = {...}
407
+ await setEasTone({message: event.properties.description, header: event.properties.metadata.header, title: `eas_audio_message`})
408
+ ```
409
+
410
+
411
+ ## Types
412
+ [Event](./src/@types/type.event.ts) |
413
+ [Properties](./src/@types/type.properties.ts) |
414
+ [HVTec](./src/@types/type.hvtec.ts) |
415
+ [PVTec](./src/@types/type.pvtec.ts) |\
416
+ [UGC](./src/@types/type.ugc.ts) |
417
+ [Stanzas](./src/@types/type.stanza.ts) |
418
+ [Attributes](./src/@types/type.attributes.ts) |
419
+
420
+ ## Supported Events
421
+ `@atmosx/event-product-parser` natively supports and ingests **300+** NWS Text products using VTEC, UGC, and various text parsing techniues.
422
+ If you wish to view all supported products, please see: [SUPPORTED_EVENTS.md](./SUPPORTED_EVENTS.md)
423
+
424
+
425
+ ## Performance Recommendations
426
+ - Enable cache retention
427
+ - Disable geometry parsing if GeoJSON is unnecessary.
428
+
429
+ ## References
430
+ [NOAA NWWS Information](https://www.weather.gov/nwws/) |
431
+ [NWS API Documentation](https://www.weather.gov/documentation/services-web-api) |
432
+ [XMPP Protocol](https://xmpp.org/about/technology-overview/) |
433
+ [AtmosphericX](https://github.com/k3yomi/AtmosphericX) |\
434
+ [Documentation](https://atmosphericx.scriptkitty.cafe/documentation) |
435
+ [Discord Server](https://atmosphericx-discord.scriptkitty.cafe) |
436
+ [Project Board](https://github.com/users/AtmosphericX/projects/2) |\
437
+ [Code of Conduct](/CODE_OF_CONDUCT.md) |
438
+ [Contributing](/CONTRIBUTING.md) |
439
+ [License](/LICENSE) |
440
+ [Security](/SECURITY.md) |
441
+
442
+ ## Acknowledgements
443
+ - [k3yomi](https://github.com/k3yomi)