TypeScript/JavaScript bindings for MEOS, the C library that powers MobilityDB spatiotemporal types.
MEOS is compiled to WebAssembly (wasm64/MEMORY64) via Emscripten. MEOS.js wraps the resulting .wasm module in a typed TypeScript API so you can work with temporal values, spans, sets, and bounding boxes in Node.js or the browser.
Documentation: https://mobilitydb.github.io/MEOS.js/
- Requirements
- Project Structure
- Installation
- Quick start
- Memory management
- Implemented types
- Code Generation
- Tests
- Doc
- Use Case Examples
-
Docker: only needed to build the WASM module from source. Not needed if you use the prebuilt files.
-
A JS engine with WebAssembly MEMORY64 support: needed to run MEOS.js, because
meos.wasmis compiled with-sMEMORY64=1. In practice:- server-side: Node.js 22+
- browser-side: recent Chromium-based browsers or Firefox with the MEMORY64 proposal enabled
initMeos()probes for MEMORY64 at startup and throws a clear error if the engine doesn't support it.
Node.js 22+ is additionally required to run the tests, the code generator, the TypeScript build and the docs. Not needed for the WASM build itself.
MEOS.js/
├── codegen/ ← Code generator
│ ├── res/
│ │ ├── meos-idl.json ← MEOS API description
│ │ ├── meos.h, meos_geo.h ← Cached upstream headers
│ │ ├── bindings_c_header.c.template
│ │ └── functions_ts_header.ts.template
│ └── FunctionsGenerator.ts ← Eemits the C glue + TS bindings
├── core/
│ ├── c-src/
│ │ └── bindings.c ← Generated C glue
│ ├── functions/
│ │ ├── functions.generated.ts ← Generated TS bindings
│ │ ├── errors.ts ← MEOS error code handling
│ │ └── ptr_array.ts ← Pointer-array marshalling helpers
│ ├── runtime/
│ │ └── meos.ts ← WASM module loader
│ ├── types/ ← High-level typed wrappers
│ │ ├── basic/ ← TBool, TInt, TFloat, TText...
│ │ ├── boxes/ ← TBox, STBox
│ │ ├── collections/ ← Span, SpanSet, MeoSet...
│ │ └── temporal/ ← Temporal base class + factory
│ └── index.ts ← Public exports
├── wasm/ ← Build output (meos.js, meos.wasm)
├── test/ ← Unit tests (node:test + tsx)
├── docs/ ← TypeDoc + VitePress sources & HTML
├── Dockerfile ← Multi-stage build: MEOS → WASM
└── package.json
The two-layer architecture consists of:
codegen/: readscodegen/res/meos-idl.jsonand generatescore/c-src/bindings.candcore/functions/functions.generated.ts.core/: implements the high-level typed wrappers on top of the generated bindings, plus the runtime that loads the WASM module.
Option A build from source (Docker only)
docker build --output type=local,dest=./wasm --target wasm .This produces wasm/meos.js and wasm/meos.wasm. The first build may take a while as it compiles GEOS, PROJ, SQLite, GSL, JSON-C, and MobilityDB from source.
Option B use the prebuilt files
todo
npm installnpm testComing soon: MEOS.js is supposed to be published on npm so you can just
npm install meos.jsand skip the WASM build and source checkout entirely.
The codegen/ directory contains the generator that produces core/c-src/bindings.c and core/functions/functions.generated.ts from the MEOS API description file (codegen/res/meos-idl.json).
When to regenerate: whenever meos-idl.json is updated (e.g. after a MEOS version upgrade) or whenever FunctionsGenerator.ts / the templates change.
npm run generateThis reads codegen/res/meos-idl.json, applies the templates in codegen/res/, and overwrites both generated files.
Do not edit
bindings.corfunctions.generated.tsmanually: any change will be lost the next time the generator runs. Manual overrides live in the templates (codegen/res/*_header.*.template).
The canonical meos-idl.json is produced by MEOS-API. To refresh against a newer MEOS surface:
# in a MEOS-API checkout
python setup.py
python run.py
cp output/meos-idl.json /path/to/MEOS.js/codegen/res/meos-idl.json
# back in MEOS.js
npm run generateBump the MOBILITYDB_COMMIT pin in the Dockerfile together with the IDL refresh so the WASM build stays in sync with the bindings.
Unit tests live in test/ and use Node's built-in test runner with tsx for on-the-fly TypeScript transpilation.
npm testnode --import tsx/esm --test test/types/boxes/test_TBox.tsnode --import tsx/esm --test --test-name-pattern="fromString" test/types/boxes/test_TBox.tsThe API reference is generated by TypeDoc and served by VitePress. The published site lives at https://mobilitydb.github.io/MEOS.js/ and is rebuilt by .github/workflows/docs.yml on every push to main.
npm run docs:apiThis invokes TypeDoc with the config in typedoc.json and writes Markdown pages to docs/api/.
npm run docs:devnpm run docs:buildThe output is placed under docs/.vitepress/dist/, which is what the GitHub Pages workflow deploys.
npm run docs:previewEvery MEOS.js object wraps a raw pointer allocated in WASM memory. This memory is not managed by the JavaScript garbage collector and must be freed explicitly.
Option 1: manual free()
const span = TsTzSpan.fromString('[2020-01-01, 2021-01-01)');
// ... use span ...
span.free();Option 2: using (recommended)
All types implement [Symbol.dispose](), so you can use the Explicit Resource Management syntax. The object is freed automatically when the block exits, even if an exception is thrown.
{
using span = TsTzSpan.fromString('[2020-01-01, 2021-01-01)');
console.log(span.toString());
} // span.free() called automatically here
usingrequires TypeScript 5.2+ with"lib": ["ES2022"]or"ESNext"intsconfig.json.
Click any type name to open its API reference.
Abstract bases: Span · SpanSet
Number spans & sets: IntSpan · IntSpanSet · IntSet · FloatSpan · FloatSpanSet · FloatSet · BigIntSpan · BigIntSpanSet · BigIntSet
Text: TextSet
Time: TsTzSpan · TsTzSpanSet · TsTzSet · DateSpan · DateSpanSet · DateSet
Temporal booleans: TBool · TBoolInst · TBoolSeq · TBoolSeqSet
Temporal integers: TInt · TIntInst · TIntSeq · TIntSeqSet
Temporal floats: TFloat · TFloatInst · TFloatSeq · TFloatSeqSet
Temporal text: TText · TTextInst · TTextSeq · TTextSeqSet
Temporal geometry point (planar, 2D/3D): TGeomPoint · TGeomPointInst · TGeomPointSeq · TGeomPointSeqSet
Temporal geography point (geodetic, 2D/3D): TGeogPoint · TGeogPointInst · TGeogPointSeq · TGeogPointSeqSet
Factory functions createTBool, createTInt, createTFloat, createTText, createTGeomPoint, createTGeogPoint dispatch to the right subtype based on the MEOS internal type flag.
Coming soon: a dedicated examples repository / section will walk through end-to-end workflows: ingesting GPS trajectories, computing temporal aggregates, and integrating with visualization tools such as deck.gl.