@atmosx/event-product-parser 3.0.61 → 3.0.63
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/.github/docs/docs-functions.md +1 -1
- package/.github/docs/docs-general-configurations.md +1 -1
- package/.github/docs/docs-integrations.md +1 -1
- package/.github/docs/docs-listeners.md +1 -1
- package/.github/docs/docs-source-configuration.md +1 -1
- package/.github/docs/docs-technical.md +1 -1
- package/README.md +7 -5
- package/dist/cjs/index.cjs +21216 -6908
- package/dist/esm/index.mjs +21207 -6900
- package/package.json +49 -47
- package/pnpm-workspace.yaml +4 -0
- package/src/@building/CreateEvent.ts +20 -22
- package/src/@building/GetEventAttachments.ts +8 -8
- package/src/@building/GetEventEnhancedName.ts +2 -4
- package/src/@building/GetEventGeometry.ts +5 -5
- package/src/@building/GetEventHeader.ts +11 -11
- package/src/@building/GetEventNodes.ts +12 -12
- package/src/@building/GetEventOffice.ts +11 -11
- package/src/@building/GetEventProperties.ts +60 -55
- package/src/@building/GetEventSignature.ts +7 -7
- package/src/@building/GetEventTags.ts +1 -1
- package/src/@building/GetEventTracking.ts +28 -32
- package/src/@core/ClearEvents.ts +7 -7
- package/src/@core/CreateListener.ts +2 -2
- package/src/@core/GetEvents.ts +2 -2
- package/src/@core/GetNodes.ts +2 -2
- package/src/@core/GetRandomEvent.ts +2 -2
- package/src/@core/GetVersion.ts +2 -2
- package/src/@core/ManualEvent.ts +20 -21
- package/src/@core/QueryStanza.ts +7 -7
- package/src/@core/SetNode.ts +32 -26
- package/src/@core/StartService.ts +18 -18
- package/src/@core/StopService.ts +8 -8
- package/src/@enums/Expressions.ts +1 -1
- package/src/@enums/Tags.ts +1 -1
- package/src/@events/ParseAPI.ts +44 -39
- package/src/@events/ParseText.ts +19 -19
- package/src/@events/ParseUGC.ts +21 -21
- package/src/@events/ParseVTEC.ts +32 -33
- package/src/@manager/MakeEvents.ts +33 -30
- package/src/@manager/RemoveEvent.ts +38 -34
- package/src/@manager/SetHash.ts +16 -11
- package/src/@manager/UpdateEvents.ts +10 -10
- package/src/@manager/UpdateNode.ts +13 -13
- package/src/@manager/ValidateEvents.ts +36 -37
- package/src/@modules/@database/GetCachedEvents.ts +10 -12
- package/src/@modules/@database/ImportBroadcastify.ts +12 -13
- package/src/@modules/@database/ImportShapefiles.ts +17 -18
- package/src/@modules/@database/ImportStanza.ts +11 -11
- package/src/@modules/@database/InitializeDatabase.ts +16 -16
- package/src/@modules/@eas/GenerateEASMessage.ts +53 -47
- package/src/@modules/@eas/GetPCM16.ts +11 -6
- package/src/@modules/@eas/GetSampledPCM16.ts +12 -6
- package/src/@modules/@eas/GetTTS.ts +12 -7
- package/src/@modules/@eas/GetWavPCM16.ts +5 -5
- package/src/@modules/@eas/SetAFSK.ts +11 -6
- package/src/@modules/@eas/SetAttentionTone.ts +9 -4
- package/src/@modules/@eas/SetNoise.ts +10 -5
- package/src/@modules/@eas/SetRadioEffect.ts +10 -5
- package/src/@modules/@eas/SetSameHeader.ts +20 -12
- package/src/@modules/@stanza/GetAwipsType.ts +14 -15
- package/src/@modules/@stanza/ValidateStanza.ts +25 -13
- package/src/@modules/@utilities/CreateHttp.ts +24 -24
- package/src/@modules/@utilities/GetMatched.ts +8 -3
- package/src/@modules/@utilities/GetSettings.ts +3 -3
- package/src/@modules/@utilities/GetShapeNearestPoint.ts +22 -17
- package/src/@modules/@utilities/QueueManager.ts +70 -0
- package/src/@modules/@utilities/SetCronSchedule.ts +20 -20
- package/src/@modules/@utilities/SetDebug.ts +10 -10
- package/src/@modules/@utilities/SetEventEmit.ts +15 -15
- package/src/@modules/@utilities/SetListener.ts +6 -6
- package/src/@modules/@utilities/SetSettings.ts +5 -5
- package/src/@modules/@utilities/SetSleep.ts +3 -3
- package/src/@modules/@utilities/SetTimeoutAction.ts +25 -25
- package/src/@modules/@utilities/SetWarning.ts +8 -8
- package/src/@modules/@xmpp/DeployXMPP.ts +16 -16
- package/src/@modules/@xmpp/ErrorXMPP.ts +4 -4
- package/src/@modules/@xmpp/OfflineXMPP.ts +11 -11
- package/src/@modules/@xmpp/OnlineXMPP.ts +16 -16
- package/src/@modules/@xmpp/ReconnectXMPP.ts +27 -27
- package/src/@modules/@xmpp/StanzaXMPP.ts +23 -23
- package/src/@parsers/@hvtec/HVExtract.ts +9 -9
- package/src/@parsers/@text/GetDescriptionFromProduct.ts +18 -19
- package/src/@parsers/@text/GetEmbededText.ts +3 -3
- package/src/@parsers/@text/GetStringText.ts +6 -6
- package/src/@parsers/@text/GetTextFromProduct.ts +10 -10
- package/src/@parsers/@text/GetXML.ts +5 -5
- package/src/@parsers/@ugc/GetCache.ts +2 -2
- package/src/@parsers/@ugc/{GetUGCHeader.ts → GetHeader.ts} +2 -2
- package/src/@parsers/@ugc/GetLocations.ts +5 -5
- package/src/@parsers/@ugc/GetZonePolygon.ts +10 -10
- package/src/@parsers/@ugc/GetZones.ts +1 -1
- package/src/@parsers/@ugc/SetCache.ts +11 -6
- package/src/@parsers/@ugc/UGCExtract.ts +10 -10
- package/src/@parsers/{@pvtec → @vtec}/VTECExtract.ts +19 -19
- package/src/@tasks/CreateTasks.ts +110 -0
- package/src/@tasks/TaskGenerateAudio.ts +34 -0
- package/src/@tasks/TaskGenerateJSON.ts +34 -0
- package/src/@tasks/TaskGenerateText.ts +34 -0
- package/src/@tasks/TaskSendNTFY.ts +91 -0
- package/src/@tasks/TaskSendWebhook.ts +100 -0
- package/src/@types/HVTEC.ts +4 -4
- package/src/@types/Hash.ts +3 -3
- package/src/@types/Settings.ts +1 -1
- package/src/@types/StanzaCompiled.ts +13 -13
- package/src/@types/UGC.ts +3 -3
- package/src/@types/VTEC.ts +10 -10
- package/src/{@types → @types-lower}/Event.ts +4 -4
- package/src/{@types → @types-lower}/Properties.ts +2 -1
- package/src/{@types → @types-lower}/Stanza.ts +1 -1
- package/src/bootstrap.ts +26 -26
- package/src/index.ts +30 -27
- package/tools/build.js +45 -0
- package/tsconfig.json +21 -1
- package/src/@manager/Tasks.ts +0 -246
- package/tsup.config.ts +0 -16
- /package/src/@parsers/{@pvtec → @vtec}/GetExpiry.ts +0 -0
- /package/src/{@types → @types-lower}/Attributes.ts +0 -0
|
@@ -18,17 +18,17 @@
|
|
|
18
18
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { TypeSettings } from "
|
|
22
|
-
import { ReconnectXMPP } from "
|
|
23
|
-
import {
|
|
24
|
-
import { CreateHttp } from "
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { readdirSync, unlinkSync, statSync, existsSync } from "fs"
|
|
28
|
-
import { join } from "path"
|
|
21
|
+
import { TypeSettings } from "types/Settings"
|
|
22
|
+
import { ReconnectXMPP } from "@xmpp/ReconnectXMPP"
|
|
23
|
+
import { Bootstrap } from "@bootstrap"
|
|
24
|
+
import { CreateHttp } from "@utilities/CreateHttp"
|
|
25
|
+
import { SetEventEmit } from "@utilities/SetEventEmit"
|
|
26
|
+
import { CreateEvent } from "@building/CreateEvent"
|
|
27
|
+
import { readdirSync, unlinkSync, statSync, existsSync } from "fs"
|
|
28
|
+
import { join } from "path"
|
|
29
29
|
|
|
30
30
|
export const SetCronSchedule = async (): Promise<void> => {
|
|
31
|
-
const settings =
|
|
31
|
+
const settings = Bootstrap.Settings as TypeSettings;
|
|
32
32
|
|
|
33
33
|
const TTL = settings.GlobalSettings.ArchiveSettings.TTL
|
|
34
34
|
const TTLCUT = Date.now() - TTL * 1000;
|
|
@@ -62,15 +62,15 @@ export const SetCronSchedule = async (): Promise<void> => {
|
|
|
62
62
|
}
|
|
63
63
|
} else {
|
|
64
64
|
const response = await CreateHttp({
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
URL: settings.NationalWeatherServiceSettings.EventsEndpoint,
|
|
66
|
+
Headers: {
|
|
67
67
|
"User-Agent": "@atmosx/event-product-parser"
|
|
68
68
|
}
|
|
69
69
|
})
|
|
70
70
|
if (response.error) {
|
|
71
71
|
return SetEventEmit({
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
Event: `onServiceStatus`,
|
|
73
|
+
Metadata: {
|
|
74
74
|
type: "fetch-api",
|
|
75
75
|
message: `Failed to fetch latest events from National Weather Service API - ${response.message}`,
|
|
76
76
|
data: {},
|
|
@@ -79,15 +79,15 @@ export const SetCronSchedule = async (): Promise<void> => {
|
|
|
79
79
|
})
|
|
80
80
|
}
|
|
81
81
|
SetEventEmit({
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
Event: `onServiceStatus`,
|
|
83
|
+
Metadata: {
|
|
84
|
+
Message: `Fetched latest events from National Weather Service API`,
|
|
85
|
+
Data: {},
|
|
86
|
+
Type: "fetch-api",
|
|
87
|
+
Error: false
|
|
88
88
|
},
|
|
89
89
|
})
|
|
90
|
-
await CreateEvent({
|
|
90
|
+
await CreateEvent({ Message: response.message, NWWS: false })
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -17,21 +17,21 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeSettings } from "
|
|
21
|
-
import {
|
|
20
|
+
import { TypeSettings } from "types/Settings"
|
|
21
|
+
import { Bootstrap } from "@bootstrap"
|
|
22
22
|
|
|
23
23
|
interface SetDebugOptions {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
Title?: string
|
|
25
|
+
Message: string
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export const SetDebug = (
|
|
29
|
-
const settings =
|
|
30
|
-
|
|
31
|
-
message:
|
|
32
|
-
function:
|
|
28
|
+
export const SetDebug = ({ Title, Message }: SetDebugOptions): void => {
|
|
29
|
+
const settings = Bootstrap.Settings as TypeSettings;
|
|
30
|
+
Bootstrap.Listener.emit(`debug`, {
|
|
31
|
+
message: Message,
|
|
32
|
+
function: Title ?? `debug`,
|
|
33
33
|
})
|
|
34
34
|
if (settings.EnableDebugging) {
|
|
35
|
-
console.log(`[${
|
|
35
|
+
console.log(`[${Bootstrap.Colors.Blue}${Title ?? `debug`}${Bootstrap.Colors.Reset}] ${Message}`)
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -17,25 +17,25 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
21
|
-
import { SetTimeoutAction } from "
|
|
22
|
-
import { SetWarning } from "
|
|
20
|
+
import { Bootstrap } from "@bootstrap"
|
|
21
|
+
import { SetTimeoutAction } from "@utilities/SetTimeoutAction"
|
|
22
|
+
import { SetWarning } from "@utilities/SetWarning"
|
|
23
23
|
|
|
24
24
|
interface SetEventEmitOptions {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
Event: string
|
|
26
|
+
Metadata: any
|
|
27
|
+
Message?: string
|
|
28
|
+
Limited?: boolean
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export const SetEventEmit = (
|
|
32
|
-
if (
|
|
33
|
-
const isTimeout = SetTimeoutAction({
|
|
34
|
-
if (isTimeout.
|
|
31
|
+
export const SetEventEmit = ({ Event, Metadata, Message, Limited }: SetEventEmitOptions): void => {
|
|
32
|
+
if (Limited) {
|
|
33
|
+
const isTimeout = SetTimeoutAction({ Identifier: `event.${Event}`, AddTime: true, Max: 1, Interval: 1 })
|
|
34
|
+
if (isTimeout.Limited) return;
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
if (
|
|
38
|
-
if (
|
|
39
|
-
SetWarning({
|
|
36
|
+
Bootstrap.Listener.emit(Event, Metadata)
|
|
37
|
+
if (Event != `log`) { Bootstrap.Listener.emit(`*`, {event: Event, data: Metadata}) }
|
|
38
|
+
if (Message) {
|
|
39
|
+
SetWarning({ Message: Message })
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { Bootstrap } from "@bootstrap"
|
|
21
21
|
|
|
22
22
|
interface SetListenerOptions {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
Event: string,
|
|
24
|
+
Callback: () => void
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export const SetListener = (
|
|
28
|
-
|
|
29
|
-
return () => { void
|
|
27
|
+
export const SetListener = ({ Event, Callback }: SetListenerOptions): (() => void) => {
|
|
28
|
+
Bootstrap.Listener.on(Event, Callback)
|
|
29
|
+
return () => { void Bootstrap.Listener.off(Event, Callback) };
|
|
30
30
|
}
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeSettings } from
|
|
21
|
-
import {
|
|
20
|
+
import { TypeSettings } from "types/Settings"
|
|
21
|
+
import { Bootstrap } from "@bootstrap"
|
|
22
22
|
|
|
23
|
-
export const SetSettings = (
|
|
24
|
-
const settings =
|
|
23
|
+
export const SetSettings = (imported: TypeSettings): TypeSettings => {
|
|
24
|
+
const settings = Bootstrap.Settings as Record<string, unknown>;
|
|
25
25
|
const merge = (target: Record<string, unknown>, source: Record<string, unknown>) => {
|
|
26
26
|
for (const key in source) {
|
|
27
27
|
if (!Object.prototype.hasOwnProperty.call(source, key)) continue;
|
|
@@ -37,6 +37,6 @@ export const SetSettings = (newSettings: TypeSettings): TypeSettings => {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
|
-
merge(settings,
|
|
40
|
+
merge(settings, imported as Record<string, unknown>);
|
|
41
41
|
return settings as TypeSettings;
|
|
42
42
|
}
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
interface SetSleepOptions {
|
|
22
|
-
|
|
22
|
+
Timeout: number
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export const SetSleep = async (
|
|
25
|
+
export const SetSleep = async ({ Timeout }: SetSleepOptions): Promise<void> => {
|
|
26
26
|
return new Promise((resolve) => {
|
|
27
27
|
setTimeout(() => {
|
|
28
28
|
resolve();
|
|
29
|
-
},
|
|
29
|
+
}, Timeout);
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -17,48 +17,48 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { Bootstrap } from "@bootstrap"
|
|
21
21
|
|
|
22
22
|
interface SetTimeoutActionOptions {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
Identifier: string
|
|
24
|
+
AddTime?: boolean
|
|
25
|
+
Max?: number
|
|
26
|
+
Interval?: number
|
|
27
|
+
Expire?: boolean
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
type SetTimeoutActionResponse = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
Limited: boolean
|
|
32
|
+
Remaining?: number
|
|
33
|
+
Response?: string
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export const SetTimeoutAction = (
|
|
37
|
-
let target =
|
|
36
|
+
export const SetTimeoutAction = ({ Identifier, AddTime, Max, Interval, Expire }: SetTimeoutActionOptions): SetTimeoutActionResponse => {
|
|
37
|
+
let target = Bootstrap?.Ratelimits?.[Identifier];
|
|
38
38
|
if (!target) {
|
|
39
|
-
|
|
40
|
-
target =
|
|
39
|
+
Bootstrap.Ratelimits[Identifier] = [];
|
|
40
|
+
target = Bootstrap.Ratelimits[Identifier];
|
|
41
41
|
}
|
|
42
|
-
if (
|
|
43
|
-
delete
|
|
44
|
-
return {
|
|
42
|
+
if (Expire) {
|
|
43
|
+
delete Bootstrap.Ratelimits[Identifier];
|
|
44
|
+
return { Limited: false };
|
|
45
45
|
}
|
|
46
46
|
if (target?.length > 0) {
|
|
47
|
-
|
|
48
|
-
target =
|
|
47
|
+
Bootstrap.Ratelimits[Identifier] = target.filter((ts: number) => Date.now() - ts < Interval * 1000);
|
|
48
|
+
target = Bootstrap.Ratelimits[Identifier];
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const oldestTimestamp = target?.[0];
|
|
52
|
-
const getWait = oldestTimestamp ? Math.ceil((
|
|
53
|
-
const max =
|
|
52
|
+
const getWait = oldestTimestamp ? Math.ceil((Interval * 1000) - (Date.now() - oldestTimestamp)) : 0;
|
|
53
|
+
const max = Max ?? 1;
|
|
54
54
|
|
|
55
55
|
if (target?.length >= max && getWait > 0) {
|
|
56
56
|
return {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
Limited: true,
|
|
58
|
+
Remaining: getWait,
|
|
59
|
+
Response: `You are being rate limited, please wait ${(getWait / 1e3).toFixed(1)} second(s) before performing this action again.`
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
|
|
63
|
-
return {
|
|
62
|
+
Bootstrap.Ratelimits[Identifier].push(Date.now());
|
|
63
|
+
return { Limited: false };
|
|
64
64
|
}
|
|
@@ -17,18 +17,18 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
21
|
-
import { TypeSettings } from "
|
|
20
|
+
import { Bootstrap } from "@bootstrap"
|
|
21
|
+
import { TypeSettings } from "types/Settings"
|
|
22
22
|
|
|
23
23
|
interface SetWarningOptions {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
Title?: string
|
|
25
|
+
Message: string
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export const SetWarning = (
|
|
29
|
-
const settings =
|
|
30
|
-
|
|
28
|
+
export const SetWarning = ({ Title, Message }: SetWarningOptions): void => {
|
|
29
|
+
const settings = Bootstrap.Settings as TypeSettings;
|
|
30
|
+
Bootstrap.Listener.emit(`log`, `${Title ?? `[${Bootstrap.Colors.Yellow}@atmosx/product-parser${Bootstrap.Colors.Reset}]`} ${Message}`)
|
|
31
31
|
if (settings.EnableJournal) {
|
|
32
|
-
console.log(`${
|
|
32
|
+
console.log(`${Title ?? `[${Bootstrap.Colors.Yellow}@atmosx/product-parser${Bootstrap.Colors.Reset}]`} ${Message}`)
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -17,21 +17,21 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeSettings } from "
|
|
21
|
-
import {
|
|
22
|
-
import { OnlineXMPP } from "
|
|
23
|
-
import { OfflineXMPP } from "
|
|
24
|
-
import { ErrorXMPP } from "
|
|
25
|
-
import { StanzaXMPP } from "
|
|
26
|
-
import { SetEventEmit } from
|
|
27
|
-
import { client } from
|
|
20
|
+
import { TypeSettings } from "types/Settings"
|
|
21
|
+
import { Bootstrap } from "@bootstrap"
|
|
22
|
+
import { OnlineXMPP } from "@xmpp/OnlineXMPP"
|
|
23
|
+
import { OfflineXMPP } from "@xmpp/OfflineXMPP"
|
|
24
|
+
import { ErrorXMPP } from "@xmpp/ErrorXMPP"
|
|
25
|
+
import { StanzaXMPP } from "@xmpp/StanzaXMPP"
|
|
26
|
+
import { SetEventEmit } from "@utilities/SetEventEmit"
|
|
27
|
+
import { client } from "@xmpp/client"
|
|
28
28
|
|
|
29
29
|
export const DeployXMPP = async (): Promise<void> => {
|
|
30
30
|
let session;
|
|
31
|
-
const settings =
|
|
31
|
+
const settings = Bootstrap.Settings as TypeSettings
|
|
32
32
|
settings.NOAAWeatherWireServiceSettings.CredentialSettings.Nickname
|
|
33
33
|
??= settings.NOAAWeatherWireServiceSettings.CredentialSettings.Username;
|
|
34
|
-
session =
|
|
34
|
+
session = Bootstrap.Session = client({
|
|
35
35
|
service: 'xmpp://nwws-oi.weather.gov',
|
|
36
36
|
domain: 'nwws-oi.weather.gov',
|
|
37
37
|
username: settings.NOAAWeatherWireServiceSettings.CredentialSettings.Username,
|
|
@@ -45,12 +45,12 @@ export const DeployXMPP = async (): Promise<void> => {
|
|
|
45
45
|
await session.start()
|
|
46
46
|
} catch (error) {
|
|
47
47
|
SetEventEmit({
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
Event: `onServiceStatus`,
|
|
49
|
+
Metadata: {
|
|
50
|
+
Message: `Error occured while starting XMPP Session: ${error}`,
|
|
51
|
+
Data: {},
|
|
52
|
+
Type: `error`,
|
|
53
|
+
Error: true
|
|
54
54
|
},
|
|
55
55
|
})
|
|
56
56
|
}
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { Bootstrap } from "@bootstrap"
|
|
21
21
|
|
|
22
22
|
export const ErrorXMPP = () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
Bootstrap.Session.on(`error`, async () => {
|
|
24
|
+
Bootstrap.Cache.Connected = false;
|
|
25
|
+
Bootstrap.Cache.Hault = true;
|
|
26
26
|
})
|
|
27
27
|
}
|
|
@@ -17,20 +17,20 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
21
|
-
import { SetEventEmit } from "
|
|
20
|
+
import { Bootstrap } from "@bootstrap"
|
|
21
|
+
import { SetEventEmit } from "@utilities/SetEventEmit"
|
|
22
22
|
|
|
23
23
|
export const OfflineXMPP = () => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
Bootstrap.Session.on(`offline`, async () => {
|
|
25
|
+
Bootstrap.Cache.Connected = false;
|
|
26
|
+
Bootstrap.Cache.Hault = true;
|
|
27
27
|
SetEventEmit({
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
Event: `onServiceStatus`,
|
|
29
|
+
Metadata: {
|
|
30
|
+
Message: `Client has gone offline`,
|
|
31
|
+
Data: {},
|
|
32
|
+
Type: `offline`,
|
|
33
|
+
Error: true
|
|
34
34
|
},
|
|
35
35
|
})
|
|
36
36
|
})
|
|
@@ -17,30 +17,30 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
21
|
-
import { SetEventEmit } from
|
|
22
|
-
import { xml } from
|
|
20
|
+
import { Bootstrap } from "@bootstrap"
|
|
21
|
+
import { SetEventEmit } from "@utilities/SetEventEmit"
|
|
22
|
+
import { xml } from "@xmpp/client"
|
|
23
23
|
|
|
24
24
|
export const OnlineXMPP = () => {
|
|
25
|
-
const settings =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const settings = Bootstrap.Settings;
|
|
26
|
+
Bootstrap.Session.on(`online`, async () => {
|
|
27
|
+
Bootstrap.Cache.Hault = false;
|
|
28
|
+
Bootstrap.Cache.Connected = true;
|
|
29
|
+
Bootstrap.Cache.TotalReconnects = 0;
|
|
30
30
|
const nickname = settings.NOAAWeatherWireServiceSettings.CredentialSettings.Nickname;
|
|
31
|
-
|
|
31
|
+
Bootstrap.Session.send(xml('presence', {
|
|
32
32
|
to: `nwws@conference.nwws-oi.weather.gov/${nickname}`,
|
|
33
33
|
xmlns: 'http://jabber.org/protocol/muc',
|
|
34
34
|
}))
|
|
35
35
|
SetEventEmit({
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
Event: `onServiceStatus`,
|
|
37
|
+
Metadata: {
|
|
38
|
+
Message: `Succesfully connected to NOAA Weather Wire Service as "${nickname}"`,
|
|
39
|
+
Data: {},
|
|
40
|
+
Type: `online`,
|
|
41
|
+
Error: false
|
|
42
42
|
},
|
|
43
|
-
|
|
43
|
+
Message: `Succesfully connected to NOAA Weather Wire Service as "${nickname}"`,
|
|
44
44
|
})
|
|
45
45
|
})
|
|
46
46
|
}
|
|
@@ -17,47 +17,47 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeSettings } from "
|
|
21
|
-
import {
|
|
22
|
-
import { SetEventEmit } from "
|
|
23
|
-
import { SetWarning } from "
|
|
20
|
+
import { TypeSettings } from "types/Settings"
|
|
21
|
+
import { Bootstrap } from "@bootstrap"
|
|
22
|
+
import { SetEventEmit } from "@utilities/SetEventEmit"
|
|
23
|
+
import { SetWarning } from "@utilities/SetWarning"
|
|
24
24
|
|
|
25
25
|
export const ReconnectXMPP = async (interval: number): Promise<void> => {
|
|
26
|
-
const settings =
|
|
27
|
-
const
|
|
26
|
+
const settings = Bootstrap.Settings as TypeSettings;
|
|
27
|
+
const last = Date.now() - Bootstrap.Cache.LastStanzaTime
|
|
28
28
|
if (interval < 15) {
|
|
29
|
-
SetWarning({
|
|
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
|
}
|
|
33
33
|
const reconnectThreshold = interval * 1e3
|
|
34
|
-
if ((!
|
|
34
|
+
if ((!Bootstrap.Cache.Connected && !Bootstrap.Cache.Hault) || !Bootstrap.Session) {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
if (
|
|
38
|
-
if (!
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
if (last > reconnectThreshold) {
|
|
38
|
+
if (!Bootstrap.Cache.Reconnecting) {
|
|
39
|
+
Bootstrap.Cache.Reconnecting = true;
|
|
40
|
+
Bootstrap.Cache.Connected = false;
|
|
41
|
+
Bootstrap.Cache.TotalReconnects += 1;
|
|
42
42
|
try {
|
|
43
43
|
SetEventEmit({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
Event: `onServiceStatus`,
|
|
45
|
+
Metadata: {
|
|
46
|
+
Message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${Bootstrap.Cache.TotalReconnects})`,
|
|
47
|
+
Data: {
|
|
48
|
+
Last: last,
|
|
49
|
+
Nickname: settings.NOAAWeatherWireServiceSettings.CredentialSettings.Nickname
|
|
50
50
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
},
|
|
51
|
+
Type: `reconnect`,
|
|
52
|
+
Error: true
|
|
53
|
+
}, Message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${Bootstrap.Cache.TotalReconnects})`,
|
|
54
54
|
})
|
|
55
|
-
await
|
|
56
|
-
await
|
|
55
|
+
await Bootstrap.Session.stop().catch(() => {});
|
|
56
|
+
await Bootstrap.Session.start().catch(() => {});
|
|
57
57
|
} catch (error) {
|
|
58
|
-
SetWarning({
|
|
58
|
+
SetWarning({ Message: `XMPP Reconnect Failed - ${(error as Error).message}` })
|
|
59
59
|
} finally {
|
|
60
|
-
|
|
60
|
+
Bootstrap.Cache.Reconnecting = false;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -17,31 +17,31 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeStanza } from "
|
|
21
|
-
import {
|
|
22
|
-
import { ValidateStanza } from "
|
|
23
|
-
import { CreateEvent } from "
|
|
24
|
-
import { ImportStanza } from "
|
|
25
|
-
import { SetEventEmit } from "
|
|
20
|
+
import { TypeStanza } from "types-lower/Stanza"
|
|
21
|
+
import { Bootstrap } from "@bootstrap"
|
|
22
|
+
import { ValidateStanza } from "@stanza/ValidateStanza"
|
|
23
|
+
import { CreateEvent } from "@building/CreateEvent"
|
|
24
|
+
import { ImportStanza } from "@database/ImportStanza"
|
|
25
|
+
import { SetEventEmit } from "@utilities/SetEventEmit"
|
|
26
26
|
|
|
27
27
|
export const StanzaXMPP = () => {
|
|
28
|
-
|
|
28
|
+
Bootstrap.Session.on(`stanza`, async (stanza: TypeStanza) => {
|
|
29
29
|
const msgFrom = stanza?.attrs?.from ?? ``
|
|
30
30
|
const msgType = stanza?.attrs?.type ?? ``
|
|
31
31
|
SetEventEmit({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
Event: `onServiceStatus`,
|
|
33
|
+
Metadata: {
|
|
34
|
+
Message: stanza,
|
|
35
|
+
From: msgFrom,
|
|
36
|
+
Type: `stanza`
|
|
37
37
|
},
|
|
38
38
|
})
|
|
39
|
-
|
|
39
|
+
Bootstrap.Cache.LastStanzaTime = Date.now();
|
|
40
40
|
if (stanza.is(`message`)) {
|
|
41
|
-
const result = ValidateStanza({ stanza });
|
|
42
|
-
const isSkippable = result.
|
|
43
|
-
(result.
|
|
44
|
-
(result.
|
|
41
|
+
const result = ValidateStanza({ Stanza: stanza });
|
|
42
|
+
const isSkippable = result.Ignored ||
|
|
43
|
+
(result.CapEvent) ||
|
|
44
|
+
(result.CapEvent && !result.CapAreaDescription)
|
|
45
45
|
if (isSkippable) { return; }
|
|
46
46
|
await CreateEvent(result);
|
|
47
47
|
await ImportStanza(result);
|
|
@@ -50,12 +50,12 @@ export const StanzaXMPP = () => {
|
|
|
50
50
|
const getOccupant = msgFrom.split(`/`).slice(1).join(`/`)
|
|
51
51
|
const getAvailability = msgType === `unavailable`
|
|
52
52
|
SetEventEmit({
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
Event: `onServiceStatus`,
|
|
54
|
+
Metadata: {
|
|
55
|
+
Message: `Occupant ${getOccupant} has ${getAvailability ? `left` : `joined`} the room`,
|
|
56
|
+
Data: {},
|
|
57
|
+
Type: `occupant`,
|
|
58
|
+
Error: false
|
|
59
59
|
},
|
|
60
60
|
})
|
|
61
61
|
}
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { TypeHVTEC } from "
|
|
21
|
-
import { EnumCauses } from "
|
|
22
|
-
import { EnumRecords } from "
|
|
23
|
-
import { EnumExpressions } from "
|
|
24
|
-
import { EnumSeverity } from "
|
|
20
|
+
import { TypeHVTEC } from "types/HVTEC"
|
|
21
|
+
import { EnumCauses } from "@enums/Causes"
|
|
22
|
+
import { EnumRecords } from "@enums/Records"
|
|
23
|
+
import { EnumExpressions } from "@enums/Expressions"
|
|
24
|
+
import { EnumSeverity } from "@enums/Severity"
|
|
25
25
|
|
|
26
26
|
export const HVExtract = (message: string): TypeHVTEC[] | null => {
|
|
27
27
|
const getHVTECs = message.match(EnumExpressions.hvtec) ?? [];
|
|
@@ -30,10 +30,10 @@ export const HVExtract = (message: string): TypeHVTEC[] | null => {
|
|
|
30
30
|
const sub = vtec.split(`.`);
|
|
31
31
|
if (sub.length < 7) continue;
|
|
32
32
|
vtecs.push({
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
HVTEC: vtec,
|
|
34
|
+
Severity: EnumSeverity[sub[1]],
|
|
35
|
+
Cause: EnumCauses[sub[2]],
|
|
36
|
+
Record: EnumRecords[sub[6]]
|
|
37
37
|
})
|
|
38
38
|
}
|
|
39
39
|
return vtecs.length > 0 ? vtecs : null;
|