6 Commits
Author SHA1 Message Date
funkpower 93b597302a 1.1.2 — one sentence, in all five places a reader meets it
1.1.1 changed the description in Cargo.toml and in the npm package and
missed pyproject.toml, which is the one maturin publishes. PyPI took the
old summary and neither registry lets that be edited afterwards, so the
correction needs a version of its own.

The two READMEs had drifted further than the description fields. A
registry page leads with the README rather than the summary, and npm's
opened by saying the package needs no network without ever saying it
covers the Byzantine Catholic churches — which is most of what the
sentence was changed to convey.

Five files now carry it, and a test reads all five and names the ones
that disagree. It was written against the mistake above and fails on it.
2026-09-21 07:46:58 -04:00
funkpower dde50192c7 1.1.1
The README stops explaining how the project tests and releases itself.
Someone arriving at it wants to know what a day of the Great Fast
permits, not how the wheels get built; the parity suite and the release
workflow are in docs/, where the person who needs them will look.

The published description now says how many churches are covered, on
both registries. That is a number in two files nobody editing the
jurisdiction table will open, so a test pins it and names them.
2026-09-21 07:29:05 -04:00
funkpower 33441113ce ask every binding the same question and insist on the same answer
There is one engine and nine doors into it, and nothing until now checked
that the doors agree. CI tested each binding against itself: the Python
wheel imported, the C demo compiled, the npm package type-checked. None
of that would have caught a field that crosses one boundary wrong, which
is the failure this library is most exposed to, because a wrong answer
about a fast day looks exactly like a right one.

So: twelve days, chosen where the bindings could plausibly differ, and
all twenty-two fields compared against what the command line says. The
days are Pascha itself, the Nativity on both calendars, a Wednesday of
the Great Fast under Byzantine Catholic law and again at the Typikon, a
weekday of the Nativity Fast where Greek and Slavic usage part, the one
Orthodox church on the Gregorian Paschalion, and a day with no feast.

A release now runs what a push runs. It had been gated on cargo test
alone, so the C ABI, the Lua binding, the Python parity check and the
README examples were checked on the branch that led to a release and not
on the release. Neither registry will reuse a version, so the gate
belongs before the upload.

Writing it found three things. The npm exports map did not expose the
wasm by package path, so a bundler asked for typikon/web/typikon_bg.wasm
was told no such path exists and had to reach into node_modules; the
documented init() call was never affected. The suite could hang instead
of fail, because the test web server was backgrounded inside a subshell
and killed by job spec, leaving bash in do_wait forever. And pointing
XDG_CONFIG_HOME at a path that does not exist isolates typikon and
breaks every other program that keeps state under it, a browser included.

A surface whose toolchain is missing is named as skipped, and fewer than
three surfaces running is a failure rather than a pass, so a container
with nothing installed cannot come out green.
2026-09-18 16:08:41 -04:00
funkpower f68f8a7c02 the year 50 is the year 50, not 1950
new Date(50, 0, 1) is 1950: the Date constructor reads a year of 0..99
as 1900 + n, and the setter does not. This calendar answers from the
year 1, so pascha() for an early year had been quietly reporting a
twentieth-century date.
2026-09-18 14:56:57 -04:00
funkpower 899d9d9b00 check wasm-bindgen against the version Cargo.lock pins
The generator refuses a module built by a different version, and the
error it gives names two versions without saying which is which. Reading
the wanted one out of the lock file also fixes the install hint, which
had been printing the requirement from Cargo.toml: "0.2", which is not
a version anything can be installed at.
2026-09-18 14:56:15 -04:00
funkpower 69907eb186 javascript and typescript, as one wasm package for every runtime
WebAssembly rather than a native Node addon: one artifact serves Node,
Deno, Bun, a browser and anything built on them, where napi would have
meant a prebuilt binary per platform and a source build for whoever the
matrix missed. The engine is pure computation and the menologion is
already compiled in, so there is nothing for it to give up.

A day comes back as a plain object, not a handle. A wasm class would
have meant a .free() that every caller eventually forgets, and this way
JSON.stringify works and the thing spreads into state. Two serializer
defaults had to be overridden to keep the promise that it is the same
document --json emits: maps as objects, and an absent field as null
rather than undefined, which stringify would otherwise drop entirely.

The TypeScript is hand-written, because the generated types for a value
crossing as JsValue are `any`, and a binding that types its whole
return as `any` is a binding TypeScript cannot check. tsc --strict is a release
gate now, the way mypy --strict already is, and the check includes three
lines that must fail to compile.

The one place this differs from every other binding: no remembered
default jurisdiction, because a browser has nowhere to keep one. It is
called out in the README, in the types and in docs/versioning.md.

The test resolves typikon through a staged node_modules rather than a
relative path, so what it exercises is the exports map, and it compares
a year of days field by field against the command line for four
jurisdictions.
2026-09-18 14:55:40 -04:00