UNPKG

@kayahr/ed-journal

Version:

Typescript library to read/watch the player journal of Frontier's game Elite Dangerous

335 lines (334 loc) 14.7 kB
import "./events/carrier/CarrierNameChange.ts"; import "./events/carrier/CarrierStats.ts"; import "./events/travel/Docked.ts"; import "./events/station/EngineerCraft.ts"; import "./events/station/EngineerProgress.ts"; import "./events/station/Market.ts"; import "./events/travel/FSDJump.ts"; import "./events/travel/Location.ts"; import "./events/exploration/Scan.ts"; import "./events/startup/Statistics.ts"; import "./events/other/Synthesis.ts"; import type { AnyJournalEvent, JournalEventName } from "./AnyJournalEvent.ts"; import type { Backpack } from "./events/odyssey/Backpack.ts"; import type { ExtendedFCMaterials } from "./events/odyssey/FCMaterials.ts"; import type { ExtendedModuleInfo } from "./events/other/ModuleInfo.ts"; import type { Status } from "./events/other/Status.ts"; import type { ExtendedMarket } from "./events/station/Market.ts"; import type { ExtendedOutfitting } from "./events/station/Outfitting.ts"; import type { ExtendedShipyard } from "./events/station/Shipyard.ts"; import type { ExtendedNavRoute } from "./events/travel/NavRoute.ts"; import type { JournalPosition, NamedJournalPosition } from "./JournalPosition.ts"; /** * Options for reading journal files. */ export interface JournalOptions { /** Optional journal directory. If not specified then automatically determined by looking in popular spots. */ directory?: string; /** * Optional position within the journal where to start at. Can be either a specific journal position or a string with the following meaning: * * - "start" : Indicates the very beginning of the earliest journal file. * - "end" : Indicates the end of the latest journal file. So only future events will be read (only makes sense in watch mode) * - event name : Any other string is treated as a journal event name. Indicates the last (newest) position of the given event in the journal. When * specifying 'FSDJump" for example then journal reading begins at the last FSDJump event found in the game. If there is no FSDJump in * the whole journal then reading begins a the end of the journal (same as specifying position "end"). * * Defaults to "start". */ position?: JournalPosition | NamedJournalPosition; /** * Set to true to watch the journal for new events. False (default) just reads the existing journal events and * does not wait for new ones. */ watch?: boolean; } /** * Journal reader/watcher. * * Reads or watches a journal directory. It implements the AsyncIterable interface so for reading/watching the * journal you simply iterate of the instance of this class with a for..of loop for example. If you prefer you can * also use the {@link next} method to read the next event from the journal until this method returns null to indicate * the end of the journal. * * In watch mode the iteration does not end and is continued every time a new event is appended to the journal by the * game. Watch mode can be stopped by calling the {@link close} method. Iteration loops will end when journal is closed. */ export declare class Journal implements AsyncIterable<AnyJournalEvent>, AsyncDisposable { /** The journal directory. */ private readonly directory; /** The journal position pointing to the last read event. */ private lastPosition; /** The current journal position pointing to the next event to read. */ private position; /** The generator used for reading journal events. */ private readonly generator; /** The currently open line reader. Null if currently none open. */ private lineReader; /** Controller used to abort watchers when journal is closed. */ private readonly abortController; /** * Creates journal read from given directory at given position. * * @param directory - The journal directory. * @param position - The position to start reading from. * @param watch - True to watch journal, false to just read it. */ private constructor(); /** @inheritdoc */ [Symbol.asyncDispose](): PromiseLike<void>; /** * Opens the journal. */ static open({ directory, position, watch }?: JournalOptions): Promise<Journal>; /** * Searches for the journal directory in common spaces. First it checks for existence of directory specified with * environment variable ED_JOURNAL_DIR. Then it looks into the standard directory on a windows system and then * it checks to standard directory within Proton (for Linux). * * If you know more common journal locations then please let me know so I can improve the search. * * @returns The found journal directory. * @throws JournalError - When journal directory was not found. */ static findDirectory(): Promise<string>; /** * Returns the journal directory. * * @returns The journal directory. */ getDirectory(): string; /** * Returns the current journal position which points to the next event to read. * * @returns The current journal position. */ getPosition(): JournalPosition; /** * Returns the journal position which points to the last read event. * * @returns The journal position of the last read event. */ getLastPosition(): JournalPosition; /** * Closes the journal by stopping the watcher (if any) and closing the line reader. */ close(): Promise<void>; /** * Finds the last position of the given event in the latest file of the journal and returns it. Returns end of journal if the latest journal file * does not contain this event. * * @param directory - The journal directory. * @param eventName - The event name to look for. * @returns Last position of given event in latest journal file or end of journal if not found. */ static findLastEvent(directory: string, eventName: JournalEventName): Promise<JournalPosition>; /** * Finds the end position of the journal and returns it. * * @returns End position of the journal. */ static findStart(directory: string): Promise<JournalPosition>; /** * Finds the end position of the journal and returns it. * * @returns End position of the journal. */ static findEnd(directory: string): Promise<JournalPosition>; /** * Watches the journal for new or changed files and returns filenames sorted by date. An optional starting file * can be specified to define the starting point for the watcher. If not specified then the whole journal * directory is scanned and all found journal files are returned before starting to watch for changed or new * files. * * @param startFile - Optional starting file. If not specified then the watcher starts with the oldest available * journal file. * @yields New/changed journal files in chronological order. */ private watchJournalFiles; /** * Lists journal files. An optional starting file can be specified to define the starting point for the watcher. * If not specified then the whole journal directory is scanned and all found files are returned.. * * @param startFile - Optional starting file. If not specified then the reader starts with the oldest available * journal file. * @returns The found journal files. */ private listJournalFiles; /** * Parses a single journal event line. Additionally to parsing the string into a JSON object this function also * updates old properties in the journal event to new ones if needed. * * @param line - The JSON line to parse. * @returns The parsed journal event. */ private parseJournalEvent; /** * Creates the journal event generator. * * @param watch - True to watch the journal instead of just reading it. * @yields The created journal event generator. */ private createGenerator; /** * Returns async iterator for the journal events. * * @returns Async iterator for the events in this journal. */ [Symbol.asyncIterator](): AsyncGenerator<AnyJournalEvent>; /** * Returns the next event from the journal. When end of journal is reached then in watch mode this method waits * until a new event arrives. When not in watch mode or when journal is closed this method returns null when no * more events are available. * * @returns The next journal event or null when end is reached. */ next(): Promise<AnyJournalEvent | null>; /** * Reads the given JSON file, parses it as at a journal event and returns it. * * @param filename - The filename of the JSON file to read. Relative to journal directory. * @returns The parsed journal event. Null when file is not present. */ private readFile; /** * Watches the given JSON file for changes and reports any new content. It always reports the current content as * first change. * * @param filename - The filename of the JSON file to read and watch. Relative to journal directory. * @yields Async iterator watching content changes. */ private watchFile; private watchFileContent; /** * Returns the current backpack inventory read from the Backpack.json file. * * @returns The current backpack inventory. Null if Backpack.json file does not exist or is not readable. */ readBackpack(): Promise<Backpack | null>; /** * Watches the Backpack.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching backpack inventory changes. */ watchBackpack(): AsyncGenerator<Backpack>; /** * Returns the current cargo data read from the Cargo.json file. * * @returns The current cargo data. Null if Cargo.json file does not exist or is not readable. */ readCargo(): Promise<Backpack | null>; /** * Watches the Cargo.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching cargo changes. */ watchCargo(): AsyncGenerator<Backpack>; /** * Returns the current fleet carrier materials data read from the FCMaterials.json file. * * @returns The current fleet carrier materials data. Null if FCMaterials.json file does not exist or * is not readable. */ readFCMaterials(): Promise<ExtendedFCMaterials | null>; /** * Watches the FCMaterials.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching fleet carrier materials data changes. */ watchFCMaterials(): AsyncGenerator<ExtendedFCMaterials>; /** * Returns the current market data read from the Market.json file. * * @returns The current market data. Null if Market.json file does not exist or is not readable. */ readMarket(): Promise<ExtendedMarket | null>; /** * Watches the Market.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching market data changes. */ watchMarket(): AsyncGenerator<ExtendedMarket>; /** * Returns the current modules info read from the ModulesInfo.json file. * * @returns The current modules info. Null if ModulesInfo.json file does not exist or is not readable. */ readModulesInfo(): Promise<ExtendedModuleInfo | null>; /** * Watches the ModulesInfo.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching modules info changes. */ watchModulesInfo(): AsyncGenerator<ExtendedModuleInfo>; /** * Returns the current nav route read from the NavRoute.json file. * * @returns The current nav route data. Null if NavRoute.json file does not exist or is not readable. */ readNavRoute(): Promise<ExtendedNavRoute | null>; /** * Watches the NavRoute.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching nav route data changes. */ watchNavRoute(): AsyncGenerator<ExtendedNavRoute>; /** * Returns the current outfitting data read from the Outfitting.json file. * * @returns The current outfitting data. Null if Outfitting.json file does not exist or is not readable. */ readOutfitting(): Promise<ExtendedOutfitting | null>; /** * Watches the Outfitting.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching outfitting data changes. */ watchOutfitting(): AsyncGenerator<ExtendedOutfitting>; /** * Returns the current contents of the ship locker from the ShipLocker.json file. * * @returns The current ship locker content. Null if ShipLocker.json file does not exist or is not readable. */ readShipLocker(): Promise<ExtendedShipyard | null>; /** * Watches the ShipLocker.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching ship locker content changes. */ watchShipLocker(): AsyncGenerator<ExtendedShipyard>; /** * Returns the current shipyard data read from the Shipyard.json file. * * @returns The current shipyard data. Null if Shipyard.json file does not exist or is not readable. */ readShipyard(): Promise<ExtendedShipyard | null>; /** * Watches the Shipyard.json file for changes and reports any new data. It always reports the current data as * first change. * * @returns Async iterator watching shipyard data changes. */ watchShipyard(): AsyncGenerator<ExtendedShipyard>; /** * Returns the current status read from the Status.json file. * * @returns The current status. Null if Status.json file does not exist or is not readable. */ readStatus(): Promise<Status | null>; /** * Watches the Status.json file for changes and reports any new status. It always reports the current status as * first change. * * @returns Async iterator watching status changes. */ watchStatus(): AsyncGenerator<Status>; }