@atmosx/event-product-parser 3.0.4 → 3.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/cjs/index.cjs +75 -57
- package/dist/esm/index.mjs +74 -57
- package/dist/index.d.mts +28 -3
- package/dist/index.d.ts +28 -3
- package/package.json +1 -1
- package/src/@building/building.office.ts +1 -1
- package/src/@building/building.properties.ts +5 -1
- package/src/@building/building.signature.ts +1 -1
- package/src/@building/building.tracking.ts +7 -7
- package/src/@building/building.validate.ts +1 -3
- package/src/@core/core.query.ts +39 -0
- package/src/@core/core.setNode.ts +2 -2
- package/src/@core/core.start.ts +1 -1
- package/src/@dictionaries/dictionaries.officeICAOs.ts +2 -0
- package/src/{@modules/@utilities/utilities.createWebhook.ts → @manager/manager.createWebhook.ts} +12 -10
- package/src/@manager/manager.mkEvent.ts +5 -12
- package/src/@manager/manager.setHash.ts +1 -1
- package/src/@manager/manager.updateWebhooks.ts +1 -2
- package/src/@modules/@utilities/utilities.setTimeoutAction.ts +1 -1
- package/src/@modules/@xmpp/xmpp.xReconnect.ts +1 -1
- package/src/@parsers/@pvtec/pvtec.extract.ts +1 -1
- package/src/@parsers/@ugc/ugc.coordinates.ts +2 -2
- package/src/bootstrap.ts +1 -1
- package/src/index.ts +3 -2
package/src/@core/core.start.ts
CHANGED
|
@@ -47,7 +47,7 @@ export const startService = async (configurations: TypeSettings): Promise<void>
|
|
|
47
47
|
await setCronSchedule()
|
|
48
48
|
let scheduleInterval = !settings.EnableWireService ? settings.NationalWeatherServiceSettings.CallbackInterval : 1;
|
|
49
49
|
if (!settings.EnableWireService && scheduleInterval < 15) {
|
|
50
|
-
setWarning({ message: `Schedule
|
|
50
|
+
setWarning({ message: `Schedule interval of ${scheduleInterval} seconds is too low, setting to 15 seconds` })
|
|
51
51
|
bootstrap.settings.NationalWeatherServiceSettings.CallbackInterval = 15;
|
|
52
52
|
scheduleInterval = 15;
|
|
53
53
|
}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
export const officeICAOs: Record<string, string> = {
|
|
21
|
+
"KLUB": "Lubbock, TX",
|
|
21
22
|
"KLCH": "Lake Charles, LA",
|
|
22
23
|
"TSTL": "St. Louis, MO",
|
|
23
24
|
"PABC": "Bethel, AK",
|
|
@@ -253,5 +254,6 @@ export const officeICAOs: Record<string, string> = {
|
|
|
253
254
|
"KCAR": "Caribou, ME",
|
|
254
255
|
"KMFR": "Medford, OR",
|
|
255
256
|
"PGUM": "Guam, GU",
|
|
257
|
+
"PACR": "Cordova, AK",
|
|
256
258
|
"PAJK": "Juneau, AK"
|
|
257
259
|
};
|
package/src/{@modules/@utilities/utilities.createWebhook.ts → @manager/manager.createWebhook.ts}
RENAMED
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeEvent } from "
|
|
21
|
-
import { setTimeoutAction } from "
|
|
22
|
-
import { createHttp } from "
|
|
23
|
-
import { TypeWebhook } from "
|
|
24
|
-
import { getCleanedEvent } from "
|
|
20
|
+
import { TypeEvent } from "../@types/type.event";
|
|
21
|
+
import { setTimeoutAction } from "../@modules/@utilities/utilities.setTimeoutAction"
|
|
22
|
+
import { createHttp } from "../@modules/@utilities/utilities.createHttp"
|
|
23
|
+
import { TypeWebhook } from "../@types/types.webhook";
|
|
24
|
+
import { getCleanedEvent } from "../@building/building.clean";
|
|
25
25
|
import FormData from "form-data";
|
|
26
26
|
|
|
27
27
|
interface CreateWebhookOptions {
|
|
@@ -35,7 +35,7 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
|
|
|
35
35
|
|
|
36
36
|
let body = [
|
|
37
37
|
event.locations ? `**Locations**: ${event.locations.slice(0,100)}` : null,
|
|
38
|
-
event.issued ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime()/1000)}:R>` : null,
|
|
38
|
+
event.issued && event.status != `Expired` ? `**Issued**: <t:${Math.floor(new Date(event.issued).getTime()/1000)}:R>` : null,
|
|
39
39
|
event.expires && event.status != `Statement` ? `**Expires**: <t:${Math.floor(new Date(event.expires).getTime()/1000)}:R>` : null,
|
|
40
40
|
(() => {
|
|
41
41
|
const val = event.parameters.estimated_wind_gusts ?? null
|
|
@@ -46,7 +46,7 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
|
|
|
46
46
|
(() => {
|
|
47
47
|
const val = event.parameters.estimated_hail_size ?? null
|
|
48
48
|
const th = event.parameters.hail_threat ?? null
|
|
49
|
-
return (val
|
|
49
|
+
return (val ?? th) ? `**Hail Threat**: ${val} ${th ? `(${th})` : ''}` : null;
|
|
50
50
|
})(),
|
|
51
51
|
event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
|
|
52
52
|
event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
|
|
@@ -69,11 +69,13 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
|
|
|
69
69
|
(() => {
|
|
70
70
|
const val = event.geocode?.office?.name ?? `N/A`
|
|
71
71
|
const th = event.geocode?.office?.office ?? null
|
|
72
|
-
return (val
|
|
72
|
+
return (val ?? th) ? `**Sender**: ${val} ${th ? `(${th})` : ''}` : null;
|
|
73
73
|
})(),
|
|
74
74
|
event.metadata?.tracking ? `**Tracking**: ${event.metadata.tracking}` : null,
|
|
75
|
+
event.metadata.history?.length > 0 ? `**Logs**: ${event.metadata.history.length}` : null,
|
|
75
76
|
(() => {
|
|
76
|
-
|
|
77
|
+
if (event.status == `Expired`) { return null }
|
|
78
|
+
const desc = (event.description ?? '').split('\n').map(l => l.trim()).filter(Boolean).join('\n');
|
|
77
79
|
return desc ? '```' + '\n' + desc + '\n' + '```' : null;
|
|
78
80
|
})(),
|
|
79
81
|
].filter(Boolean).join('\n');
|
|
@@ -83,7 +85,7 @@ export const createWebhook = async (options: CreateWebhookOptions): Promise<void
|
|
|
83
85
|
|
|
84
86
|
if (body.length > 1900) {
|
|
85
87
|
body = body.substring(0, 1900) + "\n\n[Message truncated due to length]";
|
|
86
|
-
const blocks = (body.match(/```/g)
|
|
88
|
+
const blocks = (body.match(/```/g) ?? []).length;
|
|
87
89
|
if (blocks % 2 !== 0) body += "```";
|
|
88
90
|
}
|
|
89
91
|
const form = new FormData();
|
|
@@ -28,22 +28,15 @@ import { TypeSettings } from "../@types/types.settings";
|
|
|
28
28
|
export const mkEvent = async (event: TypeEvent): Promise<void> => {
|
|
29
29
|
const settings = bootstrap.settings as TypeSettings;
|
|
30
30
|
const features = bootstrap.cache.events.features;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for (const f of features) {
|
|
34
|
-
const key = f?.properties?.metadata?.tracking;
|
|
35
|
-
if (!key) continue;
|
|
36
|
-
map.set(key, f);
|
|
37
|
-
}
|
|
38
|
-
|
|
31
|
+
|
|
39
32
|
const getHash = event.properties.metadata.hash;
|
|
40
33
|
const getTracking = event.properties.metadata.tracking;
|
|
41
34
|
const isEntry = bootstrap.cache.hashes?.find(hash => hash.tracking === getTracking)
|
|
42
35
|
const isHashed = isEntry?.hashes?.includes(getHash) ?? false;
|
|
43
|
-
const getFeature =
|
|
44
|
-
|
|
36
|
+
const getFeature = features.find(feature => feature.properties.metadata.tracking === getTracking);
|
|
45
37
|
if (isHashed || event.properties.status_metadata.is_expired) return
|
|
46
|
-
|
|
38
|
+
setHash(event, isEntry)
|
|
39
|
+
|
|
47
40
|
const isFilteredLocation = await updateNode(event).then(() => event.properties.metadata.filtered_proximity);
|
|
48
41
|
if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) { return }
|
|
49
42
|
|
|
@@ -67,7 +60,7 @@ export const mkEvent = async (event: TypeEvent): Promise<void> => {
|
|
|
67
60
|
const iLocations = event.properties?.locations?.split(";").map((l: string) => l.trim()) ?? [];
|
|
68
61
|
const iUgc = event.properties?.geocode?.ugc ?? [];
|
|
69
62
|
|
|
70
|
-
const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i);
|
|
63
|
+
const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i).filter((v, i, a) => a.findIndex(h => h.description === v.description && h.issued === v.issued) === i);
|
|
71
64
|
const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join('; ');
|
|
72
65
|
const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
|
|
73
66
|
|
|
@@ -22,7 +22,7 @@ import { TypeHash } from "../@types/types.hash"
|
|
|
22
22
|
import { bootstrap } from "../bootstrap"
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
export const setHash =
|
|
25
|
+
export const setHash = (event: TypeEvent, entry: TypeHash): void => {
|
|
26
26
|
if (entry) {
|
|
27
27
|
entry.hashes.push(event.properties.metadata.hash);
|
|
28
28
|
entry.expires = event.properties.expires;
|
|
@@ -17,12 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { createWebhook } from "
|
|
20
|
+
import { createWebhook } from "./manager.createWebhook";
|
|
21
21
|
import { TypeEvent } from "../@types/type.event";
|
|
22
22
|
import { TypeWebhook } from "../@types/types.webhook";
|
|
23
23
|
import { bootstrap } from "../bootstrap"
|
|
24
24
|
|
|
25
|
-
|
|
26
25
|
export const updateWebhooks = async (event: TypeEvent): Promise<void> => {
|
|
27
26
|
const settings = bootstrap.settings;
|
|
28
27
|
const webhooks = settings.WebhookSettings as TypeWebhook[];
|
|
@@ -45,7 +45,7 @@ export const setTimeoutAction = (options: SetTimeoutActionOptions): SetTimeoutAc
|
|
|
45
45
|
|
|
46
46
|
const oldestTimestamp = target?.[0];
|
|
47
47
|
const getWait = oldestTimestamp ? Math.ceil((options?.interval * 1000) - (Date.now() - oldestTimestamp)) : 0;
|
|
48
|
-
const max = options?.max
|
|
48
|
+
const max = options?.max ?? 1;
|
|
49
49
|
|
|
50
50
|
if (target?.length >= max && getWait > 0) {
|
|
51
51
|
return {
|
|
@@ -26,7 +26,7 @@ export const xReconnect = async (interval: number): Promise<void> => {
|
|
|
26
26
|
const settings = bootstrap.settings as TypeSettings;
|
|
27
27
|
const lastStanza = Date.now() - bootstrap.cache.lastStanza
|
|
28
28
|
if (interval < 15) {
|
|
29
|
-
setWarning({ message: `Reconnection
|
|
29
|
+
setWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` })
|
|
30
30
|
interval = 15;
|
|
31
31
|
bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
|
|
32
32
|
}
|
|
@@ -35,7 +35,7 @@ export const pvExtract = (message: string): TypePVTEC[] | null => {
|
|
|
35
35
|
vtecs.push({
|
|
36
36
|
vtec: vtec,
|
|
37
37
|
product: eventProducts[sub[0]],
|
|
38
|
-
tracking: `${sub[2]}
|
|
38
|
+
tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
|
|
39
39
|
event: `${eventTypes[sub[3]]} ${eventActions[sub[4]]}`,
|
|
40
40
|
status: eventStatus[sub[1]],
|
|
41
41
|
organization: message.match(regExp.wmo)?.[0] ?? null,
|
|
@@ -70,7 +70,7 @@ export const getZonePolygon = (options: CoordinatesOptions): CoordinatesResponse
|
|
|
70
70
|
}
|
|
71
71
|
if (!bestPoly || bestPoly.length === 0) return null;
|
|
72
72
|
const outerRing = bestPoly[0];
|
|
73
|
-
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)
|
|
73
|
+
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10) ?? 1);
|
|
74
74
|
let skipped = outerRing.filter((_: any, idx: number) => idx % skip === 0);
|
|
75
75
|
if (skipped.length < 4) {
|
|
76
76
|
skipped = outerRing.slice();
|
|
@@ -89,7 +89,7 @@ export const getZonePolygon = (options: CoordinatesOptions): CoordinatesResponse
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
if (multi.length === 0) return null;
|
|
92
|
-
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10)
|
|
92
|
+
const skip = Math.max(1, parseInt(String(bootstrap.settings.GlobalSettings.ShapefileSkipPoints), 10) ?? 1);
|
|
93
93
|
if (skip > 1) {
|
|
94
94
|
for (let p = 0; p < multi.length; p++) {
|
|
95
95
|
for (let r = 0; r < multi[p].length; r++) {
|
package/src/bootstrap.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { setNode } from "./@core/core.setNode"
|
|
|
31
31
|
import { getEvents } from "./@core/core.getEvents"
|
|
32
32
|
import { getNodes } from "./@core/core.getNodes"
|
|
33
33
|
import { getRandomEvent } from './@core/core.getRandomEvent';
|
|
34
|
+
import { query } from './@core/core.query';
|
|
34
35
|
import { clearEvents } from './@core/core.clearEvents';
|
|
35
36
|
|
|
36
37
|
export class Manager {
|
|
@@ -55,7 +56,7 @@ export class Manager {
|
|
|
55
56
|
})
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
|
-
setWarning({message: `Uncaught Exception: ${err instanceof Error ? err.stack
|
|
59
|
+
setWarning({message: `Uncaught Exception: ${err instanceof Error ? err.stack ?? err.message : String(err)}`})
|
|
59
60
|
})
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -66,7 +67,7 @@ export {
|
|
|
66
67
|
setSettings, getEventGeometry,
|
|
67
68
|
getCleanedEvent, stopService, clearEvents,
|
|
68
69
|
startService, setNode, getRandomEvent,
|
|
69
|
-
getEvents, getNodes, setEasTone
|
|
70
|
+
getEvents, getNodes, setEasTone, query
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
|