@atmosx/event-product-parser 2.0.1 → 2.0.12

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.
@@ -0,0 +1,10 @@
1
+ # Code of Conduct
2
+ AtmosphericX is an independent, open source project and is **not** affiliated with, endorsed by, or sponsored by any government agency, meteorological organization, emergency management service, or official weather provider. This project may reference, parse, or process publicly available weather data, including but **not** limited to services operated by the National Weather Service (NWS) and the National Oceanic and Atmospheric Administration (NOAA). All trademarks, service marks, and data rights remain the property of their respective owners. AtmosphericX is provided "as is", without warranty of any kind, express or implied, including but **not** limited to:
3
+
4
+ - Accuracy or completeness of parsed weather data
5
+ - Fitness for a particular purpose
6
+ - Protection against sources and data retrieval
7
+ - Availability or reliability of upstream data sources
8
+ - Protection against service interruptions or data delays
9
+
10
+ AtmosphericX should **not** be relied upon for life safety decisions, emergency response coordination, aviation, marine navigation, or other critical applications. Always consult official sources for authoritative weather information. By using this software, you acknowledge and agree that the maintainers and contributors are **not** liable for any damages, losses, or consequences resulting from its use.
@@ -0,0 +1,30 @@
1
+ # Contributing
2
+
3
+ This project is community driven and primarily maintained by `k3yomi` and `StarflightWx`
4
+
5
+ ## How to Contribute
6
+
7
+ At this time, contributions are limited to:
8
+
9
+ - **Corrections** – Fix broken TypeScript syntax, outdated operations, or errors.
10
+ - **Additions** – Add new functions, tools, or services.
11
+ - **Clarity Improvements** – Improve explanations in plain English.
12
+ - **Documentation** – Add helpful content to the documentation.
13
+
14
+ ## What Will Not Be Accepted
15
+
16
+ - Content that introduces new packages.
17
+ - Anything that violates GitHub's Terms of Service.
18
+
19
+ ## How to Submit
20
+
21
+ 1. Fork the repository.
22
+ 2. Create a new branch: `fix/description` or `add/description`.
23
+ 3. Make your changes.
24
+ 4. Open a pull request with a clear description of **what changed and why**.
25
+
26
+ ## Requirements
27
+
28
+ - Use **plain English first, details later**.
29
+ - Provide **real working examples only** (do not make up syntax).
30
+ - Follow the existing **file structure and function signature format**.
package/README.md CHANGED
@@ -12,8 +12,7 @@
12
12
 
13
13
  ## Installation (NPM)
14
14
  ```bash
15
- npm install @atmosx/event-product-parser@latest # Latest
16
- npm install @atmosx/event-product-parser@beta # Beta
15
+ npm install @atmosx/event-product-parser@latest
17
16
  ```
18
17
 
19
18
  ## Example Usage
package/SECURITY.md ADDED
@@ -0,0 +1,21 @@
1
+ # Security Policy
2
+
3
+ ## Reporting Vulnerabilities
4
+ If you discover a security vulnerability or issue in this repository such as exposed sensitive data, misconfigurations, or content that could cause harm. Please report it **immediately and responsibly**.
5
+
6
+ **Do not report security issues publicly.**
7
+ Instead, report privately by emailing **antimal@scriptkitty.cafe**, clearly describing the vulnerability.
8
+
9
+ ## What to Include
10
+ When reporting a vulnerability, please include:
11
+ - A detailed description of the issue
12
+ - Affected files (include line numbers if possible)
13
+ - Any recommendations
14
+
15
+ ## Response
16
+ All reports will be reviewed and addressed as quickly as possible.
17
+ This is a community driven project, so response times may vary. Please allow up to a few weeks for a full response.
18
+
19
+ ## Scope
20
+ This repository **does not contain any credentials, keys, tokens, or personally identifiable information (PII)**.
21
+ If you discover any such data, report it immediately.
@@ -4910,18 +4910,6 @@ var definitions = {
4910
4910
  dump_cache_complete: `Completed dumping all cached alert files.`
4911
4911
  }
4912
4912
  };
4913
- process.on("uncaughtException", (err) => {
4914
- if ((err == null ? void 0 : err.code) === "ETIMEDOUT") {
4915
- return;
4916
- }
4917
- if ((err == null ? void 0 : err.code) === "ECONNRESET") {
4918
- return;
4919
- }
4920
- if ((err == null ? void 0 : err.code) === "EHOSTUNREACH") {
4921
- return;
4922
- }
4923
- throw err;
4924
- });
4925
4913
 
4926
4914
  // src/@parsers/text.ts
4927
4915
  var TextParser = class {
@@ -6513,6 +6501,41 @@ var Database = class {
6513
6501
  }
6514
6502
  });
6515
6503
  }
6504
+ /**
6505
+ * @function loadCollectionCache
6506
+ * @description
6507
+ * Loads cached stanzas from the database, validates them, and processes them through the event parser.
6508
+ * Only processes stanzas that are not marked to be ignored and match the CAP preferences.
6509
+ *
6510
+ * @static
6511
+ * @async
6512
+ * @returns {Promise<void>}
6513
+ */
6514
+ static loadCollectionCache() {
6515
+ return __async(this, null, function* () {
6516
+ var _a;
6517
+ try {
6518
+ const settings2 = settings;
6519
+ if (settings2.noaa_weather_wire_service_settings.cache.enabled) {
6520
+ const maxRows = (_a = settings2.noaa_weather_wire_service_settings.cache.max_db_cache_size) != null ? _a : 5e3;
6521
+ const rows = yield cache.db.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(maxRows);
6522
+ utils_default.warn(definitions.messages.dump_cache.replace(`{count}`, rows.length.toString()), true);
6523
+ const eventsToProcess = rows.map((row) => {
6524
+ return JSON.parse(row.stanza);
6525
+ }).filter((validate) => {
6526
+ if (!validate) return false;
6527
+ const skip = validate.ignore || validate.isCap && !settings2.noaa_weather_wire_service_settings.preferences.cap_only || !validate.isCap && settings2.noaa_weather_wire_service_settings.preferences.cap_only || validate.isCap && !validate.isCapDescription;
6528
+ return !skip;
6529
+ });
6530
+ yield Promise.all(eventsToProcess.map((validate) => events_default.eventHandler(validate)));
6531
+ utils_default.warn(definitions.messages.dump_cache_complete, true);
6532
+ return;
6533
+ }
6534
+ } catch (error) {
6535
+ utils_default.warn(`Failed to load cache: ${error.stack}`);
6536
+ }
6537
+ });
6538
+ }
6516
6539
  };
6517
6540
  var database_default = Database;
6518
6541
 
@@ -6686,41 +6709,6 @@ var Utils = class _Utils {
6686
6709
  cache.lastWarn = Date.now();
6687
6710
  console.warn(`\x1B[33m[ATMOSX-PARSER]\x1B[0m [${(/* @__PURE__ */ new Date()).toLocaleString()}] ${message}`);
6688
6711
  }
6689
- /**
6690
- * @function loadCollectionCache
6691
- * @description
6692
- * Loads cached stanzas from the database, validates them, and processes them through the event parser.
6693
- * Only processes stanzas that are not marked to be ignored and match the CAP preferences.
6694
- *
6695
- * @static
6696
- * @async
6697
- * @returns {Promise<void>}
6698
- */
6699
- static loadCollectionCache() {
6700
- return __async(this, null, function* () {
6701
- var _a;
6702
- try {
6703
- const settings2 = settings;
6704
- if (settings2.noaa_weather_wire_service_settings.cache.enabled) {
6705
- const maxRows = (_a = settings2.noaa_weather_wire_service_settings.cache.max_db_cache_size) != null ? _a : 5e3;
6706
- const rows = yield cache.db.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(maxRows);
6707
- this.warn(definitions.messages.dump_cache.replace(`{count}`, rows.length.toString()), true);
6708
- const eventsToProcess = rows.map((row) => {
6709
- return JSON.parse(row.stanza);
6710
- }).filter((validate) => {
6711
- if (!validate) return false;
6712
- const skip = validate.ignore || validate.isCap && !settings2.noaa_weather_wire_service_settings.preferences.cap_only || !validate.isCap && settings2.noaa_weather_wire_service_settings.preferences.cap_only || validate.isCap && !validate.isCapDescription;
6713
- return !skip;
6714
- });
6715
- yield Promise.all(eventsToProcess.map((validate) => events_default.eventHandler(validate)));
6716
- this.warn(definitions.messages.dump_cache_complete, true);
6717
- return;
6718
- }
6719
- } catch (error) {
6720
- _Utils.warn(`Failed to load cache: ${error.stack}`);
6721
- }
6722
- });
6723
- }
6724
6712
  /**
6725
6713
  * @function loadGeoJsonData
6726
6714
  * @description
@@ -7338,6 +7326,7 @@ var eas_default = EAS;
7338
7326
  // src/index.ts
7339
7327
  var Manager = class {
7340
7328
  constructor(metadata) {
7329
+ this.sigCatch();
7341
7330
  this.start(metadata);
7342
7331
  }
7343
7332
  /**
@@ -7480,7 +7469,7 @@ var Manager = class {
7480
7469
  (() => __async(this, null, function* () {
7481
7470
  try {
7482
7471
  yield xmpp_default.deploySession();
7483
- yield utils_default.loadCollectionCache();
7472
+ yield database_default.loadCollectionCache();
7484
7473
  } catch (err) {
7485
7474
  const msg = err instanceof Error ? err.message : String(err);
7486
7475
  utils_default.warn(`Failed to initialize NWWS services: ${msg}`);
@@ -7537,6 +7526,25 @@ var Manager = class {
7537
7526
  }
7538
7527
  });
7539
7528
  }
7529
+ /**
7530
+ * @function sigCatch
7531
+ * @description
7532
+ * Sets up a global handler for uncaught exceptions, ignoring specific error codes
7533
+ *
7534
+ * @async
7535
+ * @returns void
7536
+ */
7537
+ sigCatch() {
7538
+ process.on("uncaughtException", (err) => {
7539
+ var _a;
7540
+ const ignored = ["ETIMEDOUT", "ECONNRESET", "EHOSTUNREACH", "STARTTLS_FAILURE"];
7541
+ if (ignored.includes(err == null ? void 0 : err.code)) {
7542
+ utils_default.warn(`XMPP Critical Error: ${(_a = err == null ? void 0 : err.code) != null ? _a : "Unknown error code"}. This may indicate a connection issue. Attempting to continue...`);
7543
+ return;
7544
+ }
7545
+ utils_default.warn(`Uncaught Exception: ${err instanceof Error ? err.stack || err.message : String(err)}`);
7546
+ });
7547
+ }
7540
7548
  };
7541
7549
  var index_default = Manager;
7542
7550
  // Annotate the CommonJS export names for ESM import in node:
@@ -4898,18 +4898,6 @@ var definitions = {
4898
4898
  dump_cache_complete: `Completed dumping all cached alert files.`
4899
4899
  }
4900
4900
  };
4901
- process.on("uncaughtException", (err) => {
4902
- if ((err == null ? void 0 : err.code) === "ETIMEDOUT") {
4903
- return;
4904
- }
4905
- if ((err == null ? void 0 : err.code) === "ECONNRESET") {
4906
- return;
4907
- }
4908
- if ((err == null ? void 0 : err.code) === "EHOSTUNREACH") {
4909
- return;
4910
- }
4911
- throw err;
4912
- });
4913
4901
 
4914
4902
  // src/@parsers/text.ts
4915
4903
  var TextParser = class {
@@ -6501,6 +6489,41 @@ var Database = class {
6501
6489
  }
6502
6490
  });
6503
6491
  }
6492
+ /**
6493
+ * @function loadCollectionCache
6494
+ * @description
6495
+ * Loads cached stanzas from the database, validates them, and processes them through the event parser.
6496
+ * Only processes stanzas that are not marked to be ignored and match the CAP preferences.
6497
+ *
6498
+ * @static
6499
+ * @async
6500
+ * @returns {Promise<void>}
6501
+ */
6502
+ static loadCollectionCache() {
6503
+ return __async(this, null, function* () {
6504
+ var _a;
6505
+ try {
6506
+ const settings2 = settings;
6507
+ if (settings2.noaa_weather_wire_service_settings.cache.enabled) {
6508
+ const maxRows = (_a = settings2.noaa_weather_wire_service_settings.cache.max_db_cache_size) != null ? _a : 5e3;
6509
+ const rows = yield cache.db.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(maxRows);
6510
+ utils_default.warn(definitions.messages.dump_cache.replace(`{count}`, rows.length.toString()), true);
6511
+ const eventsToProcess = rows.map((row) => {
6512
+ return JSON.parse(row.stanza);
6513
+ }).filter((validate) => {
6514
+ if (!validate) return false;
6515
+ const skip = validate.ignore || validate.isCap && !settings2.noaa_weather_wire_service_settings.preferences.cap_only || !validate.isCap && settings2.noaa_weather_wire_service_settings.preferences.cap_only || validate.isCap && !validate.isCapDescription;
6516
+ return !skip;
6517
+ });
6518
+ yield Promise.all(eventsToProcess.map((validate) => events_default.eventHandler(validate)));
6519
+ utils_default.warn(definitions.messages.dump_cache_complete, true);
6520
+ return;
6521
+ }
6522
+ } catch (error) {
6523
+ utils_default.warn(`Failed to load cache: ${error.stack}`);
6524
+ }
6525
+ });
6526
+ }
6504
6527
  };
6505
6528
  var database_default = Database;
6506
6529
 
@@ -6674,41 +6697,6 @@ var Utils = class _Utils {
6674
6697
  cache.lastWarn = Date.now();
6675
6698
  console.warn(`\x1B[33m[ATMOSX-PARSER]\x1B[0m [${(/* @__PURE__ */ new Date()).toLocaleString()}] ${message}`);
6676
6699
  }
6677
- /**
6678
- * @function loadCollectionCache
6679
- * @description
6680
- * Loads cached stanzas from the database, validates them, and processes them through the event parser.
6681
- * Only processes stanzas that are not marked to be ignored and match the CAP preferences.
6682
- *
6683
- * @static
6684
- * @async
6685
- * @returns {Promise<void>}
6686
- */
6687
- static loadCollectionCache() {
6688
- return __async(this, null, function* () {
6689
- var _a;
6690
- try {
6691
- const settings2 = settings;
6692
- if (settings2.noaa_weather_wire_service_settings.cache.enabled) {
6693
- const maxRows = (_a = settings2.noaa_weather_wire_service_settings.cache.max_db_cache_size) != null ? _a : 5e3;
6694
- const rows = yield cache.db.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(maxRows);
6695
- this.warn(definitions.messages.dump_cache.replace(`{count}`, rows.length.toString()), true);
6696
- const eventsToProcess = rows.map((row) => {
6697
- return JSON.parse(row.stanza);
6698
- }).filter((validate) => {
6699
- if (!validate) return false;
6700
- const skip = validate.ignore || validate.isCap && !settings2.noaa_weather_wire_service_settings.preferences.cap_only || !validate.isCap && settings2.noaa_weather_wire_service_settings.preferences.cap_only || validate.isCap && !validate.isCapDescription;
6701
- return !skip;
6702
- });
6703
- yield Promise.all(eventsToProcess.map((validate) => events_default.eventHandler(validate)));
6704
- this.warn(definitions.messages.dump_cache_complete, true);
6705
- return;
6706
- }
6707
- } catch (error) {
6708
- _Utils.warn(`Failed to load cache: ${error.stack}`);
6709
- }
6710
- });
6711
- }
6712
6700
  /**
6713
6701
  * @function loadGeoJsonData
6714
6702
  * @description
@@ -7326,6 +7314,7 @@ var eas_default = EAS;
7326
7314
  // src/index.ts
7327
7315
  var Manager = class {
7328
7316
  constructor(metadata) {
7317
+ this.sigCatch();
7329
7318
  this.start(metadata);
7330
7319
  }
7331
7320
  /**
@@ -7468,7 +7457,7 @@ var Manager = class {
7468
7457
  (() => __async(this, null, function* () {
7469
7458
  try {
7470
7459
  yield xmpp_default.deploySession();
7471
- yield utils_default.loadCollectionCache();
7460
+ yield database_default.loadCollectionCache();
7472
7461
  } catch (err) {
7473
7462
  const msg = err instanceof Error ? err.message : String(err);
7474
7463
  utils_default.warn(`Failed to initialize NWWS services: ${msg}`);
@@ -7525,6 +7514,25 @@ var Manager = class {
7525
7514
  }
7526
7515
  });
7527
7516
  }
7517
+ /**
7518
+ * @function sigCatch
7519
+ * @description
7520
+ * Sets up a global handler for uncaught exceptions, ignoring specific error codes
7521
+ *
7522
+ * @async
7523
+ * @returns void
7524
+ */
7525
+ sigCatch() {
7526
+ process.on("uncaughtException", (err) => {
7527
+ var _a;
7528
+ const ignored = ["ETIMEDOUT", "ECONNRESET", "EHOSTUNREACH", "STARTTLS_FAILURE"];
7529
+ if (ignored.includes(err == null ? void 0 : err.code)) {
7530
+ utils_default.warn(`XMPP Critical Error: ${(_a = err == null ? void 0 : err.code) != null ? _a : "Unknown error code"}. This may indicate a connection issue. Attempting to continue...`);
7531
+ return;
7532
+ }
7533
+ utils_default.warn(`Uncaught Exception: ${err instanceof Error ? err.stack || err.message : String(err)}`);
7534
+ });
7535
+ }
7528
7536
  };
7529
7537
  var index_default = Manager;
7530
7538
  export {
package/package.json CHANGED
@@ -1,14 +1,9 @@
1
1
  {
2
2
  "name": "@atmosx/event-product-parser",
3
- "version": "2.0.01",
3
+ "version": "2.0.012",
4
4
  "description": "NOAA Weather Wire & NWS API Parser - Built for standalone and Project AtmosphericX Integration.",
5
5
  "main": "dist/cjs/index.cjs",
6
6
  "module": "dist/esm/index.mjs",
7
- "types": "dist/index.d.ts",
8
- "files": [
9
- "dist/**/*",
10
- "src/**/*"
11
- ],
12
7
  "repository": {
13
8
  "type": "git",
14
9
  "url": "git+https://github.com/AtmosphericX/event-product-parser",
@@ -30,7 +30,7 @@ export class TextParser {
30
30
  * @param {string[]} [removal=[]]
31
31
  * @returns {string | null}
32
32
  */
33
- public static textProductToString(message: string,value: string,removal: string[] = []): string | null {
33
+ public static textProductToString(message: string, value: string, removal: string[] = []): string | null {
34
34
  const lines = message.split('\n');
35
35
  for (const line of lines) {
36
36
  if (line.includes(value)) {
@@ -14,6 +14,7 @@
14
14
  import * as loader from '../bootstrap';
15
15
  import * as types from '../types';
16
16
  import Utils from './utils';
17
+ import EventParser from '../@parsers/events';
17
18
 
18
19
  export class Database {
19
20
 
@@ -157,6 +158,43 @@ export class Database {
157
158
  Utils.warn(`Failed to load database: ${msg}`);
158
159
  }
159
160
  }
161
+
162
+ /**
163
+ * @function loadCollectionCache
164
+ * @description
165
+ * Loads cached stanzas from the database, validates them, and processes them through the event parser.
166
+ * Only processes stanzas that are not marked to be ignored and match the CAP preferences.
167
+ *
168
+ * @static
169
+ * @async
170
+ * @returns {Promise<void>}
171
+ */
172
+ public static async loadCollectionCache(): Promise<void> {
173
+ try {
174
+ const settings = loader.settings as types.ClientSettingsTypes;
175
+ if (settings.noaa_weather_wire_service_settings.cache.enabled) {
176
+ const maxRows = settings.noaa_weather_wire_service_settings.cache.max_db_cache_size ?? 5000;
177
+ const rows = await loader.cache.db.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`)
178
+ .all(maxRows) as { rowid: number; stanza: string }[];
179
+ Utils.warn(loader.definitions.messages.dump_cache.replace(`{count}`, rows.length.toString()), true);
180
+ const eventsToProcess = rows
181
+ .map(row => {return JSON.parse(row.stanza)})
182
+ .filter(validate => {
183
+ if (!validate) return false;
184
+ const skip = validate.ignore ||
185
+ (validate.isCap && !settings.noaa_weather_wire_service_settings.preferences.cap_only) ||
186
+ (!validate.isCap && settings.noaa_weather_wire_service_settings.preferences.cap_only) ||
187
+ (validate.isCap && !validate.isCapDescription);
188
+ return !skip;
189
+ });
190
+ await Promise.all(eventsToProcess.map(validate => EventParser.eventHandler(validate)));
191
+ Utils.warn(loader.definitions.messages.dump_cache_complete, true);
192
+ return;
193
+ }
194
+ } catch (error: any) {
195
+ Utils.warn(`Failed to load cache: ${error.stack}`);
196
+ }
197
+ }
160
198
  }
161
199
 
162
200
  export default Database;
@@ -13,7 +13,6 @@
13
13
 
14
14
  import * as loader from '../bootstrap';
15
15
  import * as types from '../types';
16
- import StanzaParser from '../@parsers/stanza';
17
16
  import EventParser from '../@parsers/events';
18
17
  import Xmpp from './xmpp';
19
18
 
@@ -52,43 +51,6 @@ export class Utils {
52
51
  console.warn(`\x1b[33m[ATMOSX-PARSER]\x1b[0m [${new Date().toLocaleString()}] ${message}`);
53
52
  }
54
53
 
55
- /**
56
- * @function loadCollectionCache
57
- * @description
58
- * Loads cached stanzas from the database, validates them, and processes them through the event parser.
59
- * Only processes stanzas that are not marked to be ignored and match the CAP preferences.
60
- *
61
- * @static
62
- * @async
63
- * @returns {Promise<void>}
64
- */
65
- public static async loadCollectionCache(): Promise<void> {
66
- try {
67
- const settings = loader.settings as types.ClientSettingsTypes;
68
- if (settings.noaa_weather_wire_service_settings.cache.enabled) {
69
- const maxRows = settings.noaa_weather_wire_service_settings.cache.max_db_cache_size ?? 5000;
70
- const rows = await loader.cache.db.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`)
71
- .all(maxRows) as { rowid: number; stanza: string }[];
72
- this.warn(loader.definitions.messages.dump_cache.replace(`{count}`, rows.length.toString()), true);
73
- const eventsToProcess = rows
74
- .map(row => {return JSON.parse(row.stanza)})
75
- .filter(validate => {
76
- if (!validate) return false;
77
- const skip = validate.ignore ||
78
- (validate.isCap && !settings.noaa_weather_wire_service_settings.preferences.cap_only) ||
79
- (!validate.isCap && settings.noaa_weather_wire_service_settings.preferences.cap_only) ||
80
- (validate.isCap && !validate.isCapDescription);
81
- return !skip;
82
- });
83
- await Promise.all(eventsToProcess.map(validate => EventParser.eventHandler(validate)));
84
- this.warn(loader.definitions.messages.dump_cache_complete, true);
85
- return;
86
- }
87
- } catch (error: any) {
88
- Utils.warn(`Failed to load cache: ${error.stack}`);
89
- }
90
- }
91
-
92
54
  /**
93
55
  * @function loadGeoJsonData
94
56
  * @description
package/src/bootstrap.ts CHANGED
@@ -179,12 +179,4 @@ export const definitions = {
179
179
  dump_cache: `Found {count} cached events and will begin dumping them shortly. This may take a while depending on the number of cached events.`,
180
180
  dump_cache_complete: `Completed dumping all cached alert files.`,
181
181
  }
182
- };
183
-
184
-
185
- process.on('uncaughtException', (err: any) => {
186
- if (err?.code === 'ETIMEDOUT') { return; }
187
- if (err?.code === 'ECONNRESET') { return; }
188
- if (err?.code === 'EHOSTUNREACH') { return; }
189
- throw err;
190
- })
182
+ };
package/src/index.ts CHANGED
@@ -27,7 +27,10 @@ import UGCParser from './@parsers/ugc';
27
27
  export class Manager {
28
28
  isNoaaWeatherWireService: boolean
29
29
  job: any
30
- constructor(metadata: types.ClientSettingsTypes) { this.start(metadata) }
30
+ constructor(metadata: types.ClientSettingsTypes) {
31
+ this.sigCatch();
32
+ this.start(metadata)
33
+ }
31
34
 
32
35
  /**
33
36
  * @function setDisplayName
@@ -168,7 +171,7 @@ export class Manager {
168
171
  (async () => {
169
172
  try {
170
173
  await Xmpp.deploySession();
171
- await Utils.loadCollectionCache();
174
+ await Database.loadCollectionCache();
172
175
  } catch (err: unknown) {
173
176
  const msg = err instanceof Error ? err.message : String(err);
174
177
  Utils.warn(`Failed to initialize NWWS services: ${msg}`);
@@ -211,6 +214,25 @@ export class Manager {
211
214
  this.isNoaaWeatherWireService = false;
212
215
  }
213
216
  }
217
+
218
+ /**
219
+ * @function sigCatch
220
+ * @description
221
+ * Sets up a global handler for uncaught exceptions, ignoring specific error codes
222
+ *
223
+ * @async
224
+ * @returns void
225
+ */
226
+ private sigCatch() {
227
+ process.on('uncaughtException', (err: any) => {
228
+ const ignored = ['ETIMEDOUT', 'ECONNRESET', 'EHOSTUNREACH', 'STARTTLS_FAILURE'];
229
+ if (ignored.includes(err?.code)) {
230
+ Utils.warn(`XMPP Critical Error: ${err?.code ?? 'Unknown error code'}. This may indicate a connection issue. Attempting to continue...`);
231
+ return;
232
+ }
233
+ Utils.warn(`Uncaught Exception: ${err instanceof Error ? err.stack || err.message : String(err)}`);
234
+ })
235
+ }
214
236
  }
215
237
 
216
238
  export default Manager;
package/test.js ADDED
@@ -0,0 +1,62 @@
1
+ const { AlertManager } = require(`@atmosx/event-product-parser`)
2
+
3
+
4
+ const parser = new AlertManager({
5
+ database: `shapefile-manager.db`,
6
+ is_wire: true,
7
+ journal: true,
8
+ noaa_weather_wire_service_settings: {
9
+ reconnection_settings: {
10
+ enabled: true,
11
+ interval: 60,
12
+ },
13
+ credentials: {
14
+ username: `username123`,
15
+ password: `password123`,
16
+ nickname: "AtmosphericX Standalone Parser",
17
+ },
18
+ cache: {
19
+ enabled: false,
20
+ max_db_history: 5000,
21
+ max_db_cache_size: 1000,
22
+ },
23
+ preferences: {
24
+ disable_ugc: false,
25
+ disable_vtec: false,
26
+ disable_text: false,
27
+ cap_only: false,
28
+ }
29
+ },
30
+ national_weather_service_settings: {
31
+ interval: 15,
32
+ endpoint: `https://api.weather.gov/alerts/active`,
33
+ },
34
+ global_settings: {
35
+ parent_events_only: true,
36
+ better_event_parsing: true,
37
+ ignore_geometry_parsing: false,
38
+ shapefile_coordinates: true,
39
+ filtering: {
40
+ events: [`Severe Thunderstorm Warning`],
41
+ filtered_icao: ["PAFC"],
42
+ ignored_icao: [],
43
+ ignored_events: [`Xx`, `Test Message`],
44
+ ugc_filter: [],
45
+ state_filter: [],
46
+ check_expired: true,
47
+ ignore_test_products: true,
48
+ },
49
+ eas_settings: {
50
+ directory: null,
51
+ intro_wav: null,
52
+ }
53
+ }
54
+ })
55
+
56
+ parser.on(`onEvents`, (alerts) => {
57
+ for (const alert of alerts) {
58
+ if (alert.geometry != null) {
59
+ console.log(`[${ new Date(alert.properties.issued).toLocaleString()}] ${alert.properties.event} for ${alert.properties.locations} (ID: ${alert.properties.details.tracking})`);
60
+ }
61
+ }
62
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES6",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Node",
6
+ "outDir": "dist",
7
+ "declaration": true,
8
+ "declarationDir": "dist/types",
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "skipLibCheck": true
12
+ },
13
+ "include": ["src"]
14
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ outDir: 'dist',
6
+ format: ['esm', 'cjs'],
7
+ noExternal: ["@xmpp/client", "@xmpp/sasl", "@xmpp/sasl-plain"],
8
+ clean: true,
9
+ outExtension({ format }) {
10
+ return { js: format === 'esm' ? '.mjs' : '.cjs' }
11
+ },
12
+ esbuildOptions(options, context) {
13
+ options.outdir = `dist/${context.format}`
14
+ },
15
+ })