import type { ElementSet } from "./types.ts"; /** * The text formats `parseElements` reads: CCSDS OMM as JSON (what CelesTrak's `FORMAT=json` and Space-Track's JSON serve), the same as CSV (CelesTrak's default), and two- or three-line TLE text. * * @example * ```ts * import type { ElementFormat } from "@johnmorrisdotca/chikyu-earth/satellites"; * * const format: ElementFormat = "tle"; * console.log(format); * ``` */ export type ElementFormat = "omm-json" | "omm-csv" | "tle"; /** * What `parseElements` found: the element sets that can be used, and the ones it left out with the reason. * * @example * ```ts * import type { ParsedElements } from "@johnmorrisdotca/chikyu-earth/satellites"; * * const count = (parsed: ParsedElements): number => parsed.sets.length; * console.log(typeof count); * ``` */ export interface ParsedElements { format: ElementFormat; sets: ElementSet[]; skipped: { name: string; reason: string; }[]; } /** A record with the fields of an OMM, from text or numbers, or the reason it is not one. */ export declare function toElementSet(record: Record): ElementSet | string; /** The cells of one CSV line (a cell may be in double quotes, with `""` for a quote). */ export declare function cellsOf(line: string): string[]; /** * Read element sets from text: OMM as JSON (an array or a single object), OMM as CSV (a header row, then one satellite a row) or TLE (two lines, or three with the name first). The format is found from the text. * An element set that is missing a number, has a wrong TLE checksum or is not a possible orbit is left out, with the reason, in `skipped`. It throws if the text is none of the three. * * @param text - What the source answered. * @returns The element sets that can be used and the ones that cannot. * @example * ```js * import { parseElements } from "@johnmorrisdotca/chikyu-earth/satellites"; * * const csv = [ * "OBJECT_NAME,OBJECT_ID,EPOCH,MEAN_MOTION,ECCENTRICITY,INCLINATION,RA_OF_ASC_NODE,ARG_OF_PERICENTER,MEAN_ANOMALY,NORAD_CAT_ID,BSTAR,MEAN_MOTION_DOT,MEAN_MOTION_DDOT", * "MADE-UP 1,2026-001A,2026-11-03T12:00:00,15.2,0.0002,53,10,90,20,900001,0.0001,0.00001,0", * ].join("\n"); * const { sets, format } = parseElements(csv); * console.log(format, sets.length, sets[0].OBJECT_NAME); * ``` */ export declare function parseElements(text: string): ParsedElements; /** * Why a source could not be used: the address was refused before any request, the source answered something other than 200 (and will not be asked again for a while), the answer was too big, or it could not be read. * * @param message - What went wrong, in a sentence. * @param details - The HTTP status the source answered and when it may be asked again, when they are known. * @example * ```ts * import { ElementSourceError } from "@johnmorrisdotca/chikyu-earth/satellites"; * * const error = new ElementSourceError("refused", { status: 403 }); * console.log(error.status); * ``` */ export declare class ElementSourceError extends Error { /** The HTTP status the source answered, when it answered. */ readonly status: number | undefined; /** When, in milliseconds since the Unix epoch, the source may be asked again (it is not asked before). */ readonly retryAt: number | undefined; constructor(message: string, details?: { status?: number; retryAt?: number; }); } /** * What `fetchElements` can be told. Every one has a safe default. * * @example * ```ts * import type { FetchElementsOptions } from "@johnmorrisdotca/chikyu-earth/satellites"; * * const options: FetchElementsOptions = { minIntervalMs: 3 * 3_600_000 }; * console.log(options.minIntervalMs); * ``` */ export interface FetchElementsOptions { /** The shortest time between two requests to the same address; within it the answer already read is returned (2 hours by default: CelesTrak's elements change every 2 hours and it asks for one download an update). */ minIntervalMs?: number; /** How long a source that answered anything but 200 (or did not answer) is left alone (1 hour by default). */ blockedMs?: number; /** The most bytes of answer read (20 million by default). */ maxBytes?: number; /** The most element sets kept (50,000 by default). */ maxSets?: number; /** Where answers and refusals are kept between page loads: `localStorage` by default where there is one; `null` keeps them for this page only. */ store?: Pick | null; /** The fetch function (the browser's by default). */ fetch?: typeof fetch; /** The time, in milliseconds since the Unix epoch (`Date.now` by default). */ now?: () => number; signal?: AbortSignal; } /** * Element sets read from a source: where from, when, and whether this answer was kept from earlier rather than asked for now. * * @example * ```ts * import type { ElementSource } from "@johnmorrisdotca/chikyu-earth/satellites"; * * const describe = (source: ElementSource): string => `${source.sets.length} from ${source.url}, ${source.fromCache ? "kept" : "new"}`; * console.log(typeof describe); * ``` */ export interface ElementSource extends ParsedElements { url: string; /** When the source was asked, in milliseconds since the Unix epoch. */ retrievedAt: number; fromCache: boolean; } /** * Forget what `fetchElements` kept in this page and which sources it is leaving alone: for a test. It does not clear `localStorage`, and a page that asks again at once is asking against the source's rules. * * @returns Nothing. * @example * ```ts * import { forgetElements } from "@johnmorrisdotca/chikyu-earth/satellites"; * * forgetElements(); * console.log("forgotten"); * ``` */ export declare function forgetElements(): void; /** * Ask a source of your own choosing for element sets, in the visitor's browser, and read them. The package has no address of its own: you pass one, and you are the one to read that source's terms * (docs/satellite-sources.md has what CelesTrak, Space-Track and others say). It is polite by design: * - only `https` (or `http` on `localhost`), with no cookies and no referrer sent; * - the same address is not asked again within `minIntervalMs` (2 hours): the answer already read is returned, from this page or from `localStorage`; * - any answer that is not 200, or no answer, stops the asking: the address is left alone for `blockedMs` (1 hour) and a `ElementSourceError` with the status says so (the answer already read, if there is one, is returned instead); * - an answer over `maxBytes` or `maxSets` is refused. * The source must send the headers a browser needs to let a page read it (CORS); one that does not cannot be read from a page, and no workaround is made here. * * @param url - The address of OMM JSON, OMM CSV or TLE text. * @param options - See `FetchElementsOptions`. * @returns The element sets, ready for `createSatellites`, with where and when they came from. * @example * ```ts no-run * import { createSatellites, fetchElements } from "@johnmorrisdotca/chikyu-earth/satellites"; * * // An address you chose, whose terms you have read. This one answers made-up elements. * const source = await fetchElements("https://example.org/my-elements.json"); * const group = createSatellites(source.sets); * console.log(group.count, source.skipped.length, source.fromCache); * ``` */ export declare function fetchElements(url: string, options?: FetchElementsOptions): Promise;