chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
// Adapts better-sqlite3 to the Cloudflare Durable Object SQL interface, so the
// DO adapter's SQL and logic can run under plain vitest. This does NOT exercise
// the DO runtime itself — that is covered by the PLATFORM=cloudflare e2e path
// once later phases add endpoints touching space storage.
/**
* @typedef {Object} D1ShimCursor
* @property {() => any[]} toArray
*/
/**
* @param {import('better-sqlite3').Database} db
* @returns {{
* sql: {exec: (query: string, ...params: any[]) => D1ShimCursor},
* storage: {transactionSync: (fn: () => any) => any},
* }}
*/
export function createD1Shim(db) {
return {
sql: {
/**
* @param {string} query
* @param {...any} params
* @returns {D1ShimCursor}
*/
exec(query, ...params) {
const trimmed = query.trim();
// The DO's exec accepts multi-statement DDL; better-sqlite3 needs
// .exec() for that, and .prepare() rejects it.
if (params.length === 0 && trimmed.includes(';')) {
db.exec(query);
return { toArray: () => [] };
}
const stmt = db.prepare(query);
if (/^\s*select/i.test(trimmed)) {
const rows = stmt.all(...params);
return { toArray: () => rows };
}
stmt.run(...params);
return { toArray: () => [] };
},
},
storage: {
/**
* @param {() => any} fn
* @returns {any}
*/
transactionSync(fn) {
db.exec('BEGIN');
try {
const result = fn();
db.exec('COMMIT');
return result;
} catch (err) {
db.exec('ROLLBACK');
throw err;
}
},
},
};
}