openvibers/openvibe.sdk Commits
Add a shared usage-reading reporter to openvibe-sdk/usage (#16)
OP OpenVibers committed 5 Oct 2026 · tag v0.32. · 0 files, +0 −0
* Add a shared usage-reading reporter to openvibe-sdk/usage
**Files changed**
- `src/usage.js`: added `createUsageReporter({ db, service, source, table='usage_outbox', billingUrl, tokenClient, … })` — `key()`/`sample()` derive readings for one service, `record(t, reading)` validates via `validateUsageSample` and inserts an idempotency-keyed (`event_id = idempotency_key`) row inside the caller's transaction (`ON CONFLICT DO NOTHING`), and the relay is `createPgOutbox` (from `./outbox`) pointed at Billing's `/api/v1/usage` with a `tokenClient.getToken({audience})`. Transient failures retry with backoff; only 400/409/413/422 mark a row rejected, kept with its error. Without `billingUrl`/`tokenClient` readings still queue, relay off. Also softened the header's "no dependency at require time" claim since it now requires `./outbox`.
- `test/usage-reporter.test.js` (new): key derivation, replay refusal (same key stored once; wrong-body replay refused), transient retry/never-dropped, 422 rejected-and-kept, argument validation, disabled-relay queueing — on PGlite with a stub fetch/token client.
- `types/usage.d.ts`: declared `UsageTokenClient`, `UsageReporterOptions`, `UsageReporter`, `createUsageReporter`.
- `esm/usage.mjs`: regenerated (`node scripts/esm.js`), now exports `createUsageReporter`.
- `package.json`, `package-lock.json`, `src/core/index.js` (`SDK_VERSION`), `STATUS.json`, `README.md` status/install lines: bumped 0.31.0 → 0.32.0.
- `CHANGELOG.md`: new top `## 0.32.0 (2026-10-05)` section documenting the reporter.
- `browser/openvibe-sdk.mjs`: regenerated (`node scripts/browser-bundle.js`) — the bundle embeds the version; `src/usage.js` is not browser-reachable (`browser: null`).
The `./usage` subpath and its types already existed in `package.json` exports, so nothing needed adding there; `index.js` already re-exports the usage namespace, so `createUsageReporter` is reachable at the top level.
**Tests**
`ov test test/usage-reporter.test.js test/usage.test.js test/esm.test.js test/types.test.js test/version.test.js test/bundle.test.js test/pack.test.js` → **7 passed** (14 s). (Also ran `test/usage-reporter.test.js` alone first: 1 passed.)
**Not done / notes**
- No subpath addition was needed (already present), so `pack.test.js`'s `subpaths.length === 41` is unchanged.
- Did not commit, push, deploy, or install packages, per instructions.
* Usage reporter: refuse every 4xx but 401/403/404/408/425/429, invalidate the token on 401, document billing only real traffic (review)
All four tests pass and no commit was made. Summary of changes:
**Behavior fixes**
- `src/usage.js:95` — replaced `REFUSED` (400/409/413/422) with `RETRYABLE_4XX = {401, 403, 404, 408, 425, 429}` matching OpenVibe.Events' `server/billing.js`; any other 4xx (402/410/415 included) is now refused, while those six plus 5xx/network stay pending. (The events outbox's own set differs on 403/404/409, so a local set is used rather than `outbox.isPermanent`; noted at `src/usage.js:92-94`.)
- `src/usage.js:189` — `err.status = (4xx && !RETRYABLE_4XX.has(status)) ? 422 : 503`, preserving the real status in the message.
- `src/usage.js:184` — a 401 now calls `tokenClient.invalidate?.({ audience })` before the retry, as Events does.
**Billing-responsibility guard + docs**
- `src/usage.js:97,114-115,126,150-151,160-161` — new opt-in `requireProject` (default false) that makes `record()` refuse a reading whose `project` isn't `prj_…`; documented in the file header and `record()` JSDoc.
- `README.md:185` — documents `createUsageReporter` and that it bills whatever reading it is given (never first-party/sandbox; `requireProject: true` to refuse).
- `types/usage.d.ts:15-18,35-36,59-60` and `:69-74` — mirrored the `invalidate` capability, `requireProject` option, record() note, and corrected status list.
- `CHANGELOG.md:22-29` — corrected the 0.32.0 entry's status set and noted the 401 invalidation/guard.
**Tests** (`test/usage-reporter.test.js`)
- `:172` full status matrix: 401/403/404/408/425/429/500 stay pending; 400/402/409/410/413/415/422 are refused.
- `:191` network error (fetch throws) stays pending.
- `:198` 401 invalidates the cached token and the retry mints a fresh one.
- `:213` `requireProject` refuses a projectless reading, accepts a valid `prj_…` one.
- `:226` `start()` schedules one unref'd relay timer and `stop()` clears it.
**Artifacts:** `node scripts/esm.js` and `node scripts/browser-bundle.js` ran; both produced no diff (`src/usage.js` isn't reachable from `browser.js`, and its exports are unchanged).
**Test results:** `ov test test/usage-reporter.test.js test/version.test.js test/bundle.test.js test/pack.test.js` → **4 passed in 44 s** (bundle 0.2 s, pack 1.9 s, usage-reporter 43.5 s, version 0.1 s).
This commit has no diff to show.