openvibers/openvibe.shared Commits
Floating-promise check: in a repository that depends on better-sqlite3, an outbox .enqueue() and db.close() are synchronous and never reported (as with db.run/get/all/exec); they are reported again as soon as the dependency goes, so no '// floating-ok' annotation is needed today that would hide a real finding after a PostgreSQL move.
Changes
@@@ -101,8 +101,8 @@ function ruleB(callee, args, { asyncDb = true } = {}) {if (asyncDb && (objName === 'db' || objName === 'tx') && DB_METHODS.has(prop)) return true; // db.run/get/all/exec/query, tx.run/get/all/execif (objName === 'pool' && prop === 'query') return true;if (objName === 'client' && prop === 'query') return true;-- if (prop === 'enqueue') return true;-- if (prop === 'close' && CLOSE_OBJECTS.has(objName)) return true; // .close() on db/pool/client/server/store++ if (prop === 'enqueue' && asyncDb) return true; // an outbox on better-sqlite3 enqueues synchronously++ if (prop === 'close' && CLOSE_OBJECTS.has(objName) && (asyncDb || objName !== 'db')) return true; // better-sqlite3's db.close() is synchronous // .close() on db/pool/client/server/storereturn false;}@@@ -57,11 +57,11 @@ try {// A better-sqlite3 service: its db calls are synchronous, so db.run() never floats there (fetch still does).{-- const src = ['async function handler() {', ' db.run("x");', ' fetch("u");', '}'].join('\n') + '\n';++ const src = ['async function handler() {', ' db.run("x");', ' outbox.enqueue(e);', ' db.close();', ' fetch("u");', '}'].join('\n') + '\n';const sync = fixture({ 'package.json': JSON.stringify({ dependencies: { 'better-sqlite3': '^11' } }), 'server/s.js': src });-- assert.deepStrictEqual(callees(scan(sync)), ['fetch'], 'db.run is synchronous with better-sqlite3');++ assert.deepStrictEqual(callees(scan(sync)), ['fetch'], 'db.run, an outbox enqueue and db.close are synchronous with better-sqlite3');const pg = fixture({ 'package.json': JSON.stringify({ dependencies: { pg: '^8' } }), 'server/s.js': src });-- assert.deepStrictEqual(callees(scan(pg)), ['db.run', 'fetch'], 'db.run is a promise without better-sqlite3');++ assert.deepStrictEqual(callees(scan(pg)), ['db.close', 'db.run', 'fetch', 'outbox.enqueue'], 'all promises without better-sqlite3');}// Rule b: every known async API.
@@ -101,8 +101,8 @@ function ruleB(callee, args, { asyncDb = true } = {}) {
@@ -101,8 +101,8 @@ function ruleB(callee, args, { asyncDb = true } = {}) {
if (asyncDb && (objName === 'db' || objName === 'tx') && DB_METHODS.has(prop)) return true; // db.run/get/all/exec/query, tx.run/get/all/exec
if (asyncDb && (objName === 'db' || objName === 'tx') && DB_METHODS.has(prop)) return true; // db.run/get/all/exec/query, tx.run/get/all/exec
if (objName === 'pool' && prop === 'query') return true;
if (objName === 'pool' && prop === 'query') return true;
if (objName === 'client' && prop === 'query') return true;
if (objName === 'client' && prop === 'query') return true;
- if (prop === 'enqueue') return true;
- if (prop === 'close' && CLOSE_OBJECTS.has(objName)) return true; // .close() on db/pool/client/server/store
+ if (prop === 'enqueue' && asyncDb) return true; // an outbox on better-sqlite3 enqueues synchronously
+ if (prop === 'close' && CLOSE_OBJECTS.has(objName) && (asyncDb || objName !== 'db')) return true; // better-sqlite3's db.close() is synchronous // .close() on db/pool/client/server/store
return false;
return false;
}
}
@@ -57,11 +57,11 @@ try {
@@ -57,11 +57,11 @@ try {
// A better-sqlite3 service: its db calls are synchronous, so db.run() never floats there (fetch still does).
// A better-sqlite3 service: its db calls are synchronous, so db.run() never floats there (fetch still does).
{
{
- const src = ['async function handler() {', ' db.run("x");', ' fetch("u");', '}'].join('\n') + '\n';
+ const src = ['async function handler() {', ' db.run("x");', ' outbox.enqueue(e);', ' db.close();', ' fetch("u");', '}'].join('\n') + '\n';
const sync = fixture({ 'package.json': JSON.stringify({ dependencies: { 'better-sqlite3': '^11' } }), 'server/s.js': src });
const sync = fixture({ 'package.json': JSON.stringify({ dependencies: { 'better-sqlite3': '^11' } }), 'server/s.js': src });
- assert.deepStrictEqual(callees(scan(sync)), ['fetch'], 'db.run is synchronous with better-sqlite3');
+ assert.deepStrictEqual(callees(scan(sync)), ['fetch'], 'db.run, an outbox enqueue and db.close are synchronous with better-sqlite3');
const pg = fixture({ 'package.json': JSON.stringify({ dependencies: { pg: '^8' } }), 'server/s.js': src });
const pg = fixture({ 'package.json': JSON.stringify({ dependencies: { pg: '^8' } }), 'server/s.js': src });
- assert.deepStrictEqual(callees(scan(pg)), ['db.run', 'fetch'], 'db.run is a promise without better-sqlite3');
+ assert.deepStrictEqual(callees(scan(pg)), ['db.close', 'db.run', 'fetch', 'outbox.enqueue'], 'all promises without better-sqlite3');
}
}
// Rule b: every known async API.
// Rule b: every known async API.