ais-web
Version:
Compact AIS decoder in TypeScript for browser and web apps
132 lines (131 loc) • 4.42 kB
TypeScript
import { EventEmitter } from 'events';
export interface PositionMessage {
type: 1 | 2 | 3;
channel: string;
repeat: number;
mmsi: number;
navStatus: number;
rateOfTurn: number;
speedOverGround: number;
accuracy: boolean;
lon: number;
lat: number;
courseOverGround: number;
heading: number;
utcSecond: number;
specialManoeuvre: number;
raim: boolean;
radio: number;
}
export interface StaticVoyageMessage {
type: 5;
mmsi: number;
repeat: number;
aisVersion: number;
imo: number;
callsign: string;
name: string;
shipType: number;
dimensionToBow: number;
dimensionToStern: number;
dimensionToPort: number;
dimensionToStarboard: number;
epfd: number;
etaMonth: number;
etaDay: number;
etaHour: number;
etaMinute: number;
draught: number;
destination: string;
dteAvailable: boolean;
channel: string;
}
interface AisReceiverEvents {
position: PositionMessage;
static: StaticVoyageMessage;
}
/**
* Events emitted by the AisReceiver:
*
* - 'position': Emitted when a Position Report message (AIS types 1, 2, or 3) is decoded.
* Listener receives a `PositionMessage` object containing dynamic vessel position and navigation data.
*
* - 'static': Emitted when a Static and Voyage Related Data message (AIS type 5) is decoded.
* Listener receives a `StaticVoyageMessage` object containing vessel identification and voyage details.
*
* Usage example:
* ```ts
* const receiver = new AisReceiver();
*
* receiver.on('position', (posMsg) => {
* console.log('Position update:', posMsg);
* });
*
* receiver.on('static', (staticMsg) => {
* console.log('Static vessel info:', staticMsg);
* });
* receiver.onMessage(aisSentence);
* ```
*/
type EventNames<T> = keyof T & string;
type EventListener<T, K extends EventNames<T>> = (payload: T[K]) => void;
declare class TypedEventEmitter<T> extends EventEmitter {
on<K extends EventNames<T>>(eventName: K, listener: EventListener<T, K>): this;
off<K extends EventNames<T>>(eventName: K, listener: EventListener<T, K>): this;
once<K extends EventNames<T>>(eventName: K, listener: EventListener<T, K>): this;
emit<K extends EventNames<T>>(eventName: K, payload: T[K]): boolean;
}
export declare class AisReceiver extends TypedEventEmitter<AisReceiverEvents> {
private multipartBuffers;
private static MULTIPART_TIMEOUT_MS;
/**
* Process one AIS sentence. Pass your messages to this function, once the message is decoded, it triggers an event
* on('position') or on('static') depending on the type of sentence decoded.
* @param sentence Raw NMEA AIS sentence, e.g. "!AIVDM,1,1,,A,...*hh"
* @param enableChecksum Whether to verify the checksum (default: true)
*/
onMessage(sentence: string, enableChecksum?: boolean): void;
/**
* Extracts raw AIS sentence raw fields along with the decoded MMSI.
*
* Parses a raw AIS NMEA sentence (e.g. "!AIVDM,...") to extract:
* - total number of fragments,
* - current fragment number,
* - sequence ID,
* - radio channel,
* - payload string,
* - fill bits,
* and additionally decodes the MMSI number from the AIS payload.
*
* @param sentence - Raw AIS NMEA sentence string.
* @param enableChecksum - Whether to verify the NMEA checksum (default: true).
* @returns An object containing:
* - channel: radio channel ('A' or 'B'),
* - payload: AIS payload string,
* - total: total number of sentence fragments,
* - part: current fragment number,
* - fillBits: number of fill bits in the payload,
* - key: sequence ID for multipart messages (or 'noprefix'),
* - mmsi: decoded MMSI number extracted from the payload,
* or undefined if the sentence is invalid or checksum verification fails.
*/
extractSentenceRawFields(sentence: string, enableChecksum?: boolean): {
mmsi: number;
channel: string;
payload: string;
total: number;
part: number;
fillBits: number;
key: string;
} | undefined;
private extractRawData;
private verifyChecksum;
private payloadToBits;
private processBits;
private decodePosition;
private decodeType5;
private readUInt;
private readInt;
private decodeText;
}
export {};