bun-sqlite-session-store
Version:
A bun:sqlite session store to be used with express-session
115 lines (114 loc) • 3.25 kB
JavaScript
import { Store } from 'express-session';
export class SQLiteStore extends Store {
db;
ttl;
constructor(options = { db: null }) {
super(options);
this.ttl = options.ttl ?? 86400; // Default TTL: 1 day in seconds
this.db = options.db;
this.initializeDb();
}
initializeDb() {
try {
this.db.exec(`
CREATE TABLE IF NOT EXISTS sessions (
sid TEXT PRIMARY KEY,
expires INTEGER,
data TEXT,
created_at INTEGER
)
`);
this.db.exec('CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions (expires)');
}
catch (err) {
console.error('Failed to initialize SQLite session store:', err);
}
}
get(sid, callback) {
try {
const row = this.db
.prepare('SELECT * FROM sessions WHERE sid = ? AND expires > ?')
.get(sid, Date.now());
if (!row) {
return callback(null, null);
}
const data = JSON.parse(row.data);
return callback(null, data);
}
catch (err) {
return callback(err);
}
}
set(sid, session, callback) {
try {
const expires = typeof session.cookie.maxAge === 'number'
? Date.now() + session.cookie.maxAge
: Date.now() + (this.ttl * 1000);
const data = JSON.stringify(session);
this.db
.prepare(`INSERT OR REPLACE INTO sessions (sid, expires, data, created_at)
VALUES (?, ?, ?, ?)`)
.run(sid, expires, data, Date.now());
callback();
}
catch (err) {
callback(err);
}
}
destroy(sid, callback) {
try {
this.db
.prepare('DELETE FROM sessions WHERE sid = ?')
.run(sid);
callback();
}
catch (err) {
callback(err);
}
}
clear(callback) {
try {
this.db.exec('DELETE FROM sessions');
callback();
}
catch (err) {
callback(err);
}
}
length(callback) {
try {
const row = this.db
.prepare('SELECT COUNT(*) AS count FROM sessions')
.get();
callback(null, row ? row.count : 0);
}
catch (err) {
callback(err);
}
}
touch(sid, session, callback) {
try {
const expires = typeof session.cookie.maxAge === 'number'
? Date.now() + session.cookie.maxAge
: Date.now() + (this.ttl * 1000);
this.db
.prepare('UPDATE sessions SET expires = ? WHERE sid = ?')
.run(expires, sid);
callback();
}
catch (err) {
callback(err);
}
}
prune() {
try {
this.db
.prepare('DELETE FROM sessions WHERE expires < ?')
.run(Date.now());
}
catch (err) {
console.error('Failed to prune expired sessions:', err);
}
}
}
export default SQLiteStore;