@voltro/protocol 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -39,6 +39,26 @@ _Changes staged for the next release accumulate here (rolled up from
39
39
 
40
40
  ---
41
41
 
42
+ ## [0.1.5] — 2026-07-16
43
+
44
+ ### Added
45
+
46
+ - **@voltro/cli** — `voltro build` now precompiles an API app (previously it only handled web apps). It bundles the whole handler closure — every procedure/executor, workflow, subscriber, reaction, aggregate, agent, tool, webhook, cron, startup, `app.config`, and their shared `database`/`lib` deps — into a single `.framework/dist-api/apiEntry.js` (framework/npm kept external), via a two-pass esbuild build (pass 1 discovers the full module closure so shared side-effectful modules like the schema are covered; pass 2 emits the bundle + a module map). `voltro serve` loads that one bundle at boot and resolves every app module from it — no `node --import tsx` runtime transpilation, and a SINGLE instance of each module (so side-effectful modules like the table registry aren't evaluated twice). Without a build — `voltro dev`, or `voltro serve` on an unbuilt app — every module still loads from source exactly as before, and a per-module miss falls back to source too, so a stale/partial bundle degrades safely. Note: an API's boot is dominated by the framework/Effect module-graph evaluation, not app-module transpilation, so the bundle is primarily a correctness/hygiene win (no source transpilation in production) rather than a large cold-start reduction.
47
+ - **@voltro/i18n** — Two message accessors that react-intl parity was missing. `useMessages()` returns the active locale's RAW (unformatted ICU) catalog — `useMessages()['some.id']` gives the template, not the formatted output — for when you need the raw string. `pickCatalog(catalogs, locale, defaultLocale)` resolves a catalog for an ARBITRARY locale OUTSIDE React (for `meta({ locale })` and other non-hook call sites where `useT` can't run); it returns the concrete catalog type, so a known-key lookup is `string` (not `string | undefined`) — the exact shape `PageMeta.title` needs, replacing the hand-rolled `getCatalog(locale)` helper apps kept copying.
48
+ - **@voltro/cli, @voltro/workflow** — `VOLTRO_WORKFLOW_RUNNER_STORAGE` (`memory` | `sql`) forces the workflow-engine runner storage instead of always deriving it from the store dialect. The load-bearing case is `memory` on a real SQL dialect (postgres / mysql / mariadb / mssql): it runs the single-process durable engine — workflow run state stays SQL-backed via `@effect/cluster`'s `SqlMessageStorage` — but SKIPS `SqlRunnerStorage` entirely, so there is no `cluster_runners` / `cluster_locks` table and none of its `GET_LOCK` advisory-lock acquisition. That unblocks a managed MySQL / MariaDB reached through a connection-load-balancing Service or a non-session-pinned pooler, where the advisory-lock connection can't be pinned to one backend and the runner-storage bootstrap wedges before it ever creates its table (the pod stays un-Ready while a shard-lock refresher errors forever). The tradeoff is no cross-pod shard handoff. An invalid value — or `sql` on sqlite / turso — fails boot loudly rather than silently selecting a broken engine. The `voltro cluster status` snapshot and the boot log both report the resolved storage.
49
+ - **@voltro/cli, @voltro/workflow** — Durable-workflow clustering now keeps **cross-pod handoff on Galera / Percona XtraDB (multi-primary) clusters**. `@effect/cluster`'s default shard-ownership coordination uses session advisory locks (`GET_LOCK` / `pg_advisory_lock`), which are node-local and can't coordinate a fleet whose connections span cluster nodes — so on a Galera cluster behind a load-balancing Service, pods split-brain shard ownership and the runner-storage bootstrap can wedge (pod never becomes Ready). The new **`VOLTRO_WORKFLOW_SHARD_LOCK`** (`auto` | `row` | `advisory`, default `auto`) fixes this: `auto` probes the live connection (`@@wsrep_on`) and, on a wsrep cluster, switches `SqlRunnerStorage` to a certified row-lease on the `cluster_locks` table (`INSERT … ON DUPLICATE KEY UPDATE … WHERE acquired_at < expiry`) instead of advisory locks — Galera certifies that write across all nodes, so shard ownership and dead-pod handoff stay correct without a single-writer proxy. A single-primary server keeps the faster advisory path. The resolved mode is reported in the boot log and in `voltro cluster status` (`shard-lock=row`). Non-wsrep multi-primary topologies (e.g. MySQL Group Replication) can force it with `VOLTRO_WORKFLOW_SHARD_LOCK=row`; an unrecognized value fails boot loudly.
50
+
51
+ ### Fixed
52
+
53
+ - **@voltro/cli** — `voltro start` no longer loads every page module at boot, so a large mostly-static site (e.g. a docs site with hundreds of prerendered routes) boots with memory proportional to its ssr/isr routes instead of its total routes — it used to OOM a modest container even though only a handful of routes ever need a runtime module. The SSR bundle (`voltro build`) now emits page/layout modules as lazy `() => import()` loaders plus a build-time `pageMeta` manifest; `voltro start` reads render mode / tenant-awareness / revalidate from the manifest and imports a page's module (and its content chunk) only when that ssr/isr route is actually rendered. A 500+ route docs site that OOMed a 512 MB container now boots at ~190 MB. Bundles without a `pageMeta` manifest (older builds) fall back to the previous load-every-module behaviour, and `voltro dev` (Vite middleware mode) is unchanged.
54
+ - **@voltro/web** — Static prerendering (`voltro build`) no longer crashes with "Router hooks must be used inside <Router>" on pages whose layout reads router/i18n context (e.g. URL-prefix locale). The framework's React contexts are now process-wide singletons pinned on the global symbol registry, so the SSG renderer (loaded via Vite's `ssrLoadModule('@voltro/web/ssr')`) and the app's page modules (with `@voltro/web` externalised to Node) always resolve the SAME context instance even though the prerender loads the package through two module instances. This only bit consumers building against the published npm package; the framework's own workspace build resolves `@voltro/web`'s source and masked it.
55
+
56
+ ### Internal (no consumer-facing effect)
57
+
58
+ - **@voltro/voltro** — Package READMEs no longer carry a relative `[Changelog](./CHANGELOG.md)` link — npm resolved it to a 404 (`npmjs.com/package/@voltro/CHANGELOG.md`) because relative README links don't resolve for scoped packages, and there is no public changelog URL (the repo is private). The `CHANGELOG.md` is still bundled in each package tarball. The README link row is now Documentation · voltro.dev · Voltro Cloud.
59
+
60
+ ---
61
+
42
62
  ## [0.1.1] — 2026-07-15
43
63
 
44
64
  ### Fixed
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **The Voltro wire + plugin contract — defineQuery/Mutation/Action/Stream, definePlugin, sessions / JWT / API-keys, and the RPC protocol.**
6
6
 
7
- [📖 Documentation](https://docs.voltro.dev/docs/data/wire-protocol) · [Changelog](./CHANGELOG.md) · [voltro.dev](https://voltro.dev) · [Voltro Cloud](https://voltro.cloud)
7
+ [📖 Documentation](https://docs.voltro.dev/docs/data/wire-protocol) · [voltro.dev](https://voltro.dev) · [Voltro Cloud](https://voltro.cloud)
8
8
 
9
9
  </div>
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/protocol",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "The Voltro wire + plugin contract — defineQuery/Mutation/Action/Stream, definePlugin, sessions / JWT / API-keys, and the RPC protocol.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@effect/sql": "^0.51.1",
56
- "@voltro/database": "0.1.3",
56
+ "@voltro/database": "0.1.5",
57
57
  "jose": "^6.2.3"
58
58
  },
59
59
  "peerDependencies": {