@ausecon/core
v0.2.0
Published
Read Australian economic data from the ABS and RBA.
Readme
@ausecon/core
@ausecon/core is a TypeScript library that reads Australian economic data
from the Australian Bureau of Statistics (ABS) and the Reserve Bank of
Australia (RBA). It ports the readabs and readrba R packages and uses
Effect.
The library uses no Node, Bun, or Deno APIs. It runs on Node 22.18 or later, Bun, and Deno.
Install
npm install @ausecon/core effectRead ABS Time Series
readAbs reads ABS time series from the latest release. It reads every
table of a catalogue number, chosen tables by table number, or a list of
series IDs from any catalogue numbers.
readAbs returns an Effect that needs an HttpClient. To run it without
writing Effect code, provide Effect's fetch-based client and call
Effect.runPromise:
import { AbsRequest, readAbs } from "@ausecon/core";
import { Effect } from "effect";
import { FetchHttpClient } from "effect/http";
// Table 1 of the Wage Price Index.
const wages = await Effect.runPromise(
readAbs(AbsRequest.Catalogue({ catalogueNumber: "6345.0", tableNumbers: ["1"] })).pipe(
Effect.provide(FetchHttpClient.layer),
),
);
console.log(wages[0]);readAbs returns a read-only array of series, one per series ID and sheet.
Each series carries its metadata once, the table it came from, and its
observations:
{
seriesId: "A2603039T",
seriesDescription: "Quarterly Index ; Total hourly rates of pay excluding bonuses ; ...",
unit: "Index Numbers",
seriesType: "Original",
dataType: "INDEX",
frequency: "Quarter",
collectionMonth: "3",
table: { tableId: "634501", tableTitle: "Table 1. Total Hourly Rates of Pay ..." },
sheet: "Data1",
observations: [
{ date: "1997-09-01", value: 67.4 },
// ...
],
}Series come in table order, then sheet order, then column order, and
observations in row order. Dates are ISO 8601 strings such as 1997-09-01, so
time zones never shift a period. Blank and text cells give no observation.
The Series, Table, and Observation types describe this shape.
Leave out tableNumbers to read every table of the catalogue number. To read
series IDs instead, pass a series request:
const series = await Effect.runPromise(
readAbs(AbsRequest.Series({ seriesIds: ["A2603039T", "A2454446F"] })).pipe(
Effect.provide(FetchHttpClient.layer),
),
);A series request returns only the requested series.
The read trims spaces from each catalogue number, table number, and series
ID, and upper-cases table numbers and series IDs. A four-digit catalogue
number such as 6345 gains .0.
Parse a Table You Hold
parseTable reads the series of one ABS time series table from its .xlsx
bytes, with no network. It is the parser that readAbs uses. Pass the bytes
and the table, with the table ID and, if you know it, the title:
import { readFile } from "node:fs/promises";
import { TableId, parseTable } from "@ausecon/core";
import { Effect, Schema } from "effect";
const bytes = new Uint8Array(await readFile("634501.xlsx"));
const wages = await Effect.runPromise(
parseTable(bytes, { tableId: Schema.decodeSync(TableId)("634501") }),
);Each series carries the table as you passed it, so tableTitle is absent
when you leave it out. A table without the ABS time series layout fails with
TableLayoutError.
Errors
Effect.runPromise rejects when the read fails. Inside Effect code, the
error channel holds one of these tagged errors:
InvalidRequest: a catalogue number, table number, or series ID is not valid.CatalogueNotFound: the Time Series Directory has no series for the catalogue number.TableNotFound: the catalogue number has no table with a requested table number.SeriesNotFound: the Time Series Directory has no record of a series ID.TableLayoutError: a table does not have the ABS time series layout.TimeSeriesDirectoryError: a Time Series Directory response is not a series index, such as an error document or malformed XML. It names the URL and the reason.AbsUnavailable: a request to the ABS got no response, or a status outside 2xx. It names the URL, the status if the ABS answered, and the cause as text indetail.
Every error is a type the library defines. No effect/http error reaches
the error channel.
TableLayoutError names the table ID and, when a sheet fails the check,
the sheet. A file that does not open as .xlsx gives the error without a
sheet. Each data sheet must hold Series ID in column A of row 10, and the
five metadata labels Unit, Series Type, Data Type, Frequency, and
Collection Month in column A of rows 2 to 9. Each filled cell of row 10
must hold a series ID. Below row 10, column A must hold a date, a blank, or a
note that contains Trend Break or see.
Your Own HttpClient
Any HttpClient layer works. The library sends its own User-Agent, follows
redirects, and fails on any status outside 2xx, so the client only needs to
send requests.
Links
License
MIT. The license keeps the copyright notices of readabs and readrba.
