JavaScript release of unitsdb-ruby, published as @unitsml/unitsdb on npm.
This is a release-only repo. All source lives in unitsml/unitsdb-ruby; this repo just packages the database and a thin JS read API. Don't edit dist/ — it is rebuilt from the Ruby source on every release.
npm install @unitsml/unitsdbimport { Unitsdb } from '@unitsml/unitsdb';
const db = Unitsdb.bundled(); // load the bundled units database
const meter = db.getById('NISTu1'); // → Unit entity
const hits = db.search('meter'); // → array of matching entities
const siUnits = db.findBySymbol('m'); // → units whose ASCII symbol is 'm'
const matches = db.matchEntities({ value: 'meter' }); // { exact: [...] }The full method surface mirrors Unitsdb::Database, camelCased:
| JS method | Ruby method |
|---|---|
getById(id, type?) |
get_by_id(id:, type:) |
findById(id, type) |
find_by_type(id:, type:) |
findByIdAndType(id, idType, type?) |
get_by_id(id:, type:) (with both filters) |
search(text, type?) |
search(text:, type:) |
findBySymbol(symbol, entityType?) |
find_by_symbol(symbol, entity_type) |
matchEntities({value, matchType, entityType}) |
match_entities(value:, match_type:, entity_type:) |
validateUniqueness() |
validate_uniqueness |
validateReferences() |
validate_references |
collection(name) |
collection(name) |
Versions are 1:1 with the Ruby gem. When unitsdb-ruby publishes 2.2.5, this repo publishes @unitsml/unitsdb@2.2.5 automatically. The dispatch chain (below) is the only path that produces a release.
┌──────────────────────┐ push: Bump unitsdb to X.Y.Z ┌──────────────────────┐
│ unitsdb-ruby │ ─────────────────────────────────▶│ unitsdb-ruby │
│ release.yml │ │ notify-unitsdb-js │
│ (Cimas chain) │ │ .yml │
└──────────────────────┘ └──────────┬───────────┘
│
repository_dispatch: do-release
payload: { version, ruby_ref }
│
▼
┌──────────────────────┐
│ unitsdb-js │
│ release.yml │
└──────────┬───────────┘
│
idempotency check
`npm view @unitsml/unitsdb@X.Y.Z`
│
┌──────────────────┴───────────────────┐
│ not yet published │ already published
▼ ▼
checkout unitsdb-ruby@ruby_ref skip with warning
bundle install exit 0
bundle exec ruby dump (Database#to_json)
esbuild CJS + ESM bundle (inlined JSON)
npm publish --access public
- Ruby gem release. Triggered by either:
- A maintainer running
gh workflow run release.yml --repo unitsml/unitsdb-ruby -f next_version=patch(orminor/major), or - A
repository_dispatchfrom upstream CI on a successful build.
- A maintainer running
- Ruby release workflow (Cimas-managed
release.ymlinunitsdb-ruby):- Bumps
lib/unitsdb/version.rbtoX.Y.Z. - Commits "Bump unitsdb to X.Y.Z" on
main. - Tags
vX.Y.Z. - Runs gated tests; on pass, pushes the gem to RubyGems.
- Bumps
- Cross-repo dispatch. The bump commit triggers
notify-unitsdb-js.ymlinunitsdb-ruby, which:- Extracts the new version from
lib/unitsdb/version.rb. - Fires
repository_dispatch(do-release) tounitsml/unitsdb-jswith payload{ version, ruby_ref }, authenticated viaUNITSML_CI_PAT_TOKEN.
- Extracts the new version from
- JS release.
unitsdb-js/.github/workflows/release.ymlreceives the dispatch and:- Idempotency check.
npm view @unitsml/unitsdb@X.Y.Z— if the version is already on npm, exit green with a warning. Re-dispatching after a transient failure is always safe. - Checkout. Pulls
unitsml/unitsdb-rubyatruby_ref(the tag) intounitsdb-ruby/. - Bundle.
bundle installagainst unitsdb-ruby's Gemfile (gives uslutaml-model+unitsdbitself). - Dump.
bundle exec rubyrunsUnitsdb.database.to_jsonand writes it todist/unitsdb-data.json(~430 KB). - Build.
scripts/build.jsgenerates a small JS façade (src/database.js) withgetById/search/findBySymbol/matchEntities/validateUniqueness/validateReferences, then esbuilds it into CJS + ESM bundles with the JSON inlined. - Publish.
npm publish --access publicusing theNPM_TOKENrepo secret.
- Idempotency check.
The earlier plan was to Opal-compile the whole gem into one JS bundle. That hit a wall: Opal::Builder hangs on lutaml-model's load tree (unitsdb-ruby's own Opal spec stubs it for the same reason), and even when it compiled, the bundle was multi-MB and shipped an embedded Ruby runtime.
The current approach ships a ~430 KB JSON dump (re-built from Database#to_json every release) plus a ~2 KB pure-JS façade that re-implements the read API. The Ruby gem stays the single source of truth for both data and reference-validation behavior; the JS package just re-expresses the read API in idiomatic JS.
The release workflow also accepts workflow_dispatch with a version input. Use this to re-trigger a failed release without going through the Ruby chain:
gh workflow run release.yml --repo unitsml/unitsdb-js -f version=2.2.5The idempotency guard means re-runs are always safe — if @unitsml/unitsdb@2.2.5 is already live, the workflow exits green.
| Secret | Where | Used by |
|---|---|---|
UNITSML_CI_PAT_TOKEN |
unitsml/unitsdb-ruby |
notify-unitsdb-js.yml to dispatch cross-repo |
NPM_TOKEN |
unitsml/unitsdb-js |
release.yml for npm publish (automation token from the unitsml npm org) |
BSD-2-Clause — same as unitsdb-ruby.