openvibers/openvibe.sdk Commits
v0.21.3: createTestDb returns url and directUrl for a spawned service process; sqlfix's envelope rewrite is idempotent.
Changes
@@@ -8,6 +8,11 @@ release may change an API and says so here.++## 0.21.3 (2026-09-28)++++- `openvibe-sdk/testing` `createTestDb`: on the containers it also returns `url` and `directUrl`, the `DATABASE_URL` and `DATABASE_DIRECT_URL` of its schema, for a test that spawns a process of the service (OpenRe's transport workers); `null` on PGlite.++- `tools/asyncify/sqlfix.py`: the outbox-envelope rewrite no longer nests on a second run.++## 0.21.2 (2026-09-28)- `openvibe-sdk/events` outboxes (SQLite and PostgreSQL): a `flush()` called while a relay pass runs now gets the next pass, which starts when that one ends. It used to share the running pass, so it could return before the rows committed after that pass claimed were published (a caller's "flush, then assert both went out" saw one). Calls made during a pass share that next pass; `stop()` waits for both.@@@ -3,7 +3,7 @@"stage": "alpha","code": true,"wave": "W2",-- "version": "0.21.2",++ "version": "0.21.3","plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §3.2; roadmap §30","deployed": false,"deployment": "none: a package released as git tags; services and apps pin a tag",@@@ -1,4 +1,4 @@--// Generated by scripts/browser-bundle.js from browser.js (openvibe-sdk 0.21.2, MIT). Do not edit.++// Generated by scripts/browser-bundle.js from browser.js (openvibe-sdk 0.21.3, MIT). Do not edit.// One self-contained ES module: core at the top level plus the browser-safe subpaths as namespaces// (auth, registry, modules, realtime, media, community, search, chat, ai, jobs, tools, projects, geo). No server-only code: no service tokens, JWT verification, events, identity./* eslint-disable */@@@ -41,7 +41,7 @@ const { paginate, offsetPager } = __load(7);const semver = __load(6);/** The package version (test/version.test.js keeps it equal to package.json). */--const SDK_VERSION = '0.21.2';++const SDK_VERSION = '0.21.3';module.exports = {createClient,@@@ -1,12 +1,12 @@{"name": "openvibe-sdk",-- "version": "0.21.2",++ "version": "0.21.3","lockfileVersion": 3,"requires": true,"packages": {"": {"name": "openvibe-sdk",-- "version": "0.21.2",++ "version": "0.21.3","license": "MIT","devDependencies": {"@electric-sql/pglite": "^0.5.8",@@@ -1,6 +1,6 @@{"name": "openvibe-sdk",-- "version": "0.21.2",++ "version": "0.21.3","description": "Supported browser and server clients for the OpenVibe platform: auth (incl. developer apps), registry discovery, identity, user modules, events, realtime, media, community, search, chat, AI runs, Tools (registry, run API and jobs), VIP memberships and developer projects, the async PostgreSQL data layer (db) and the Valkey cache, limits store, queue and pub/sub, with deadlines, safe retries, problem errors and trace propagation.","main": "index.js","types": "types/index.d.ts",@@@ -8,7 +8,7 @@ const { paginate, offsetPager } = require('./paginate');const semver = require('./semver');/** The package version (test/version.test.js keeps it equal to package.json). */--const SDK_VERSION = '0.21.2';++const SDK_VERSION = '0.21.3';module.exports = {createClient,@@@ -28,7 +28,7 @@ async function createTestDb({ migrations, store = process.env.OV_TEST_STORE || 'if (store !== 'pg') {const db = createDb({ pglite: true, service: `${service}-test`, log });if (migrations) await db.migrate({ dir: migrations, log });-- return { db, store: 'pglite', open: null, close: () => db.close().catch(() => {}) };++ return { db, store: 'pglite', url: null, directUrl: null, open: null, close: () => db.close().catch(() => {}) };}if (!pgAvailable()) throw new Error('store pg needs OV_TEST_PG_URL and OV_TEST_PG_DIRECT_URL (openvibe-sdk scripts/test-services.sh up)');const safe = String(service).replace(/[^a-z0-9]/g, '').slice(0, 12) || 'svc';@@@ -74,6 +74,9 @@ async function createTestDb({ migrations, store = process.env.OV_TEST_STORE || '} catch (e) { await drop().catch(() => {}); throw e; } // a failed setup leaves nothing behindreturn {db, store: 'postgresql', schema: name,++ // For a process of its own (a worker the test spawns): DATABASE_URL (through PgBouncer, the service role) and++ // DATABASE_DIRECT_URL (the owner, for its boot's migrate, which finds everything applied).++ url: as(process.env.OV_TEST_PG_URL, name), directUrl: as(process.env.OV_TEST_PG_DIRECT_URL, owner),open: (o = {}) => createDb({ url: as(process.env.OV_TEST_PG_URL, name), service: `${service}-test`, max, log, ...o }),async close() { await db.close().catch(() => {}); await drop(); },};@@@ -81,7 +81,7 @@ for p in files:# assert.throws(() => db.prepare(…).run(…), re): the statement rejects now.s = re.sub(r"assert\.throws\(\(\) => ((?:t\.)?[\w.]*db\.prepare\((?:[^()]|\([^()]*\))*\)\.(?:run|get|all)\((?:[^()]|\([^()]*\))*\)), ", r"await assert.rejects(\1, ", s)# A jsonb column (the SDK outbox's envelope) comes back as an object.-- s = re.sub(r"JSON\.parse\((\w+)\.envelope\)", r"(typeof \1.envelope === 'string' ? JSON.parse(\1.envelope) : \1.envelope)", s)++ s = re.sub(r"(?<!\? )JSON\.parse\((\w+)\.envelope\)", r"(typeof \1.envelope === 'string' ? JSON.parse(\1.envelope) : \1.envelope)", s)# db.transaction(fn)() → db.tx(fn) (balanced parentheses; the codemod then awaits it and makes fn async).out, i = [], 0while True:@@@ -156,6 +156,10 @@ export interface TestDb {schema?: string;/** Another pooled handle on the same database (a second process); null on PGlite. */open: ((o?: object) => Db) | null;++ /** DATABASE_URL for a spawned process (the service role through PgBouncer); null on PGlite. */++ url: string | null;++ /** DATABASE_DIRECT_URL for a spawned process (the owner, direct: its boot's migrate); null on PGlite. */++ directUrl: string | null;close(): Promise<void>;}/** A migrated database for one test run: PGlite, or (store 'pg') roles and a schema of its own on the containers. */
@@ -8,6 +8,11 @@ release may change an API and says so here.
@@ -8,6 +8,11 @@ release may change an API and says so here.
+## 0.21.3 (2026-09-28)
+
+- `openvibe-sdk/testing` `createTestDb`: on the containers it also returns `url` and `directUrl`, the `DATABASE_URL` and `DATABASE_DIRECT_URL` of its schema, for a test that spawns a process of the service (OpenRe's transport workers); `null` on PGlite.
+- `tools/asyncify/sqlfix.py`: the outbox-envelope rewrite no longer nests on a second run.
+
## 0.21.2 (2026-09-28)
## 0.21.2 (2026-09-28)
- `openvibe-sdk/events` outboxes (SQLite and PostgreSQL): a `flush()` called while a relay pass runs now gets the next pass, which starts when that one ends. It used to share the running pass, so it could return before the rows committed after that pass claimed were published (a caller's "flush, then assert both went out" saw one). Calls made during a pass share that next pass; `stop()` waits for both.
- `openvibe-sdk/events` outboxes (SQLite and PostgreSQL): a `flush()` called while a relay pass runs now gets the next pass, which starts when that one ends. It used to share the running pass, so it could return before the rows committed after that pass claimed were published (a caller's "flush, then assert both went out" saw one). Calls made during a pass share that next pass; `stop()` waits for both.
@@ -3,7 +3,7 @@
@@ -3,7 +3,7 @@
"stage": "alpha",
"stage": "alpha",
"code": true,
"code": true,
"wave": "W2",
"wave": "W2",
- "version": "0.21.2",
+ "version": "0.21.3",
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §3.2; roadmap §30",
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §3.2; roadmap §30",
"deployed": false,
"deployed": false,
"deployment": "none: a package released as git tags; services and apps pin a tag",
"deployment": "none: a package released as git tags; services and apps pin a tag",
@@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
-// Generated by scripts/browser-bundle.js from browser.js (openvibe-sdk 0.21.2, MIT). Do not edit.
+// Generated by scripts/browser-bundle.js from browser.js (openvibe-sdk 0.21.3, MIT). Do not edit.
// One self-contained ES module: core at the top level plus the browser-safe subpaths as namespaces
// One self-contained ES module: core at the top level plus the browser-safe subpaths as namespaces
// (auth, registry, modules, realtime, media, community, search, chat, ai, jobs, tools, projects, geo). No server-only code: no service tokens, JWT verification, events, identity.
// (auth, registry, modules, realtime, media, community, search, chat, ai, jobs, tools, projects, geo). No server-only code: no service tokens, JWT verification, events, identity.
/* eslint-disable */
/* eslint-disable */
@@ -41,7 +41,7 @@ const { paginate, offsetPager } = __load(7);
@@ -41,7 +41,7 @@ const { paginate, offsetPager } = __load(7);
const semver = __load(6);
const semver = __load(6);
/** The package version (test/version.test.js keeps it equal to package.json). */
/** The package version (test/version.test.js keeps it equal to package.json). */
-const SDK_VERSION = '0.21.2';
+const SDK_VERSION = '0.21.3';
module.exports = {
module.exports = {
createClient,
createClient,
@@ -1,12 +1,12 @@
@@ -1,12 +1,12 @@
{
{
"name": "openvibe-sdk",
"name": "openvibe-sdk",
- "version": "0.21.2",
+ "version": "0.21.3",
"lockfileVersion": 3,
"lockfileVersion": 3,
"requires": true,
"requires": true,
"packages": {
"packages": {
"": {
"": {
"name": "openvibe-sdk",
"name": "openvibe-sdk",
- "version": "0.21.2",
+ "version": "0.21.3",
"license": "MIT",
"license": "MIT",
"devDependencies": {
"devDependencies": {
"@electric-sql/pglite": "^0.5.8",
"@electric-sql/pglite": "^0.5.8",
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-sdk",
"name": "openvibe-sdk",
- "version": "0.21.2",
+ "version": "0.21.3",
"description": "Supported browser and server clients for the OpenVibe platform: auth (incl. developer apps), registry discovery, identity, user modules, events, realtime, media, community, search, chat, AI runs, Tools (registry, run API and jobs), VIP memberships and developer projects, the async PostgreSQL data layer (db) and the Valkey cache, limits store, queue and pub/sub, with deadlines, safe retries, problem errors and trace propagation.",
"description": "Supported browser and server clients for the OpenVibe platform: auth (incl. developer apps), registry discovery, identity, user modules, events, realtime, media, community, search, chat, AI runs, Tools (registry, run API and jobs), VIP memberships and developer projects, the async PostgreSQL data layer (db) and the Valkey cache, limits store, queue and pub/sub, with deadlines, safe retries, problem errors and trace propagation.",
"main": "index.js",
"main": "index.js",
"types": "types/index.d.ts",
"types": "types/index.d.ts",
@@ -8,7 +8,7 @@ const { paginate, offsetPager } = require('./paginate');
@@ -8,7 +8,7 @@ const { paginate, offsetPager } = require('./paginate');
const semver = require('./semver');
const semver = require('./semver');
/** The package version (test/version.test.js keeps it equal to package.json). */
/** The package version (test/version.test.js keeps it equal to package.json). */
-const SDK_VERSION = '0.21.2';
+const SDK_VERSION = '0.21.3';
module.exports = {
module.exports = {
createClient,
createClient,
@@ -28,7 +28,7 @@ async function createTestDb({ migrations, store = process.env.OV_TEST_STORE || '
@@ -28,7 +28,7 @@ async function createTestDb({ migrations, store = process.env.OV_TEST_STORE || '
if (store !== 'pg') {
if (store !== 'pg') {
const db = createDb({ pglite: true, service: `${service}-test`, log });
const db = createDb({ pglite: true, service: `${service}-test`, log });
if (migrations) await db.migrate({ dir: migrations, log });
if (migrations) await db.migrate({ dir: migrations, log });
- return { db, store: 'pglite', open: null, close: () => db.close().catch(() => {}) };
+ return { db, store: 'pglite', url: null, directUrl: null, open: null, close: () => db.close().catch(() => {}) };
}
}
if (!pgAvailable()) throw new Error('store pg needs OV_TEST_PG_URL and OV_TEST_PG_DIRECT_URL (openvibe-sdk scripts/test-services.sh up)');
if (!pgAvailable()) throw new Error('store pg needs OV_TEST_PG_URL and OV_TEST_PG_DIRECT_URL (openvibe-sdk scripts/test-services.sh up)');
const safe = String(service).replace(/[^a-z0-9]/g, '').slice(0, 12) || 'svc';
const safe = String(service).replace(/[^a-z0-9]/g, '').slice(0, 12) || 'svc';
@@ -74,6 +74,9 @@ async function createTestDb({ migrations, store = process.env.OV_TEST_STORE || '
@@ -74,6 +74,9 @@ async function createTestDb({ migrations, store = process.env.OV_TEST_STORE || '
} catch (e) { await drop().catch(() => {}); throw e; } // a failed setup leaves nothing behind
} catch (e) { await drop().catch(() => {}); throw e; } // a failed setup leaves nothing behind
return {
return {
db, store: 'postgresql', schema: name,
db, store: 'postgresql', schema: name,
+ // For a process of its own (a worker the test spawns): DATABASE_URL (through PgBouncer, the service role) and
+ // DATABASE_DIRECT_URL (the owner, for its boot's migrate, which finds everything applied).
+ url: as(process.env.OV_TEST_PG_URL, name), directUrl: as(process.env.OV_TEST_PG_DIRECT_URL, owner),
open: (o = {}) => createDb({ url: as(process.env.OV_TEST_PG_URL, name), service: `${service}-test`, max, log, ...o }),
open: (o = {}) => createDb({ url: as(process.env.OV_TEST_PG_URL, name), service: `${service}-test`, max, log, ...o }),
async close() { await db.close().catch(() => {}); await drop(); },
async close() { await db.close().catch(() => {}); await drop(); },
};
};
@@ -81,7 +81,7 @@ for p in files:
@@ -81,7 +81,7 @@ for p in files:
# assert.throws(() => db.prepare(…).run(…), re): the statement rejects now.
# assert.throws(() => db.prepare(…).run(…), re): the statement rejects now.
s = re.sub(r"assert\.throws\(\(\) => ((?:t\.)?[\w.]*db\.prepare\((?:[^()]|\([^()]*\))*\)\.(?:run|get|all)\((?:[^()]|\([^()]*\))*\)), ", r"await assert.rejects(\1, ", s)
s = re.sub(r"assert\.throws\(\(\) => ((?:t\.)?[\w.]*db\.prepare\((?:[^()]|\([^()]*\))*\)\.(?:run|get|all)\((?:[^()]|\([^()]*\))*\)), ", r"await assert.rejects(\1, ", s)
# A jsonb column (the SDK outbox's envelope) comes back as an object.
# A jsonb column (the SDK outbox's envelope) comes back as an object.
- s = re.sub(r"JSON\.parse\((\w+)\.envelope\)", r"(typeof \1.envelope === 'string' ? JSON.parse(\1.envelope) : \1.envelope)", s)
+ s = re.sub(r"(?<!\? )JSON\.parse\((\w+)\.envelope\)", r"(typeof \1.envelope === 'string' ? JSON.parse(\1.envelope) : \1.envelope)", s)
# db.transaction(fn)() → db.tx(fn) (balanced parentheses; the codemod then awaits it and makes fn async).
# db.transaction(fn)() → db.tx(fn) (balanced parentheses; the codemod then awaits it and makes fn async).
out, i = [], 0
out, i = [], 0
while True:
while True:
@@ -156,6 +156,10 @@ export interface TestDb {
@@ -156,6 +156,10 @@ export interface TestDb {
schema?: string;
schema?: string;
/** Another pooled handle on the same database (a second process); null on PGlite. */
/** Another pooled handle on the same database (a second process); null on PGlite. */
open: ((o?: object) => Db) | null;
open: ((o?: object) => Db) | null;
+ /** DATABASE_URL for a spawned process (the service role through PgBouncer); null on PGlite. */
+ url: string | null;
+ /** DATABASE_DIRECT_URL for a spawned process (the owner, direct: its boot's migrate); null on PGlite. */
+ directUrl: string | null;
close(): Promise<void>;
close(): Promise<void>;
}
}
/** A migrated database for one test run: PGlite, or (store 'pg') roles and a schema of its own on the containers. */
/** A migrated database for one test run: PGlite, or (store 'pg') roles and a schema of its own on the containers. */