connect-surreal
Version:
SurrealDB session store for Connect
115 lines (114 loc) • 5.04 kB
JavaScript
import { Store as n } from "express-session";
import { Surreal as i, RecordId as r, Table as l } from "surrealdb";
class g extends n {
constructor(e) {
if (super(), this.options = e, this.lastConnectionAttempt = 0, this.hasConnected = !1, this.isConnected = !1, this.db = e.surreal ?? new i(), this.tableName = e.tableName ?? "user_session", this._connect().then(async () => {
this.hasConnected = !0, e.logger?.info?.("SurrealDBStore: Creating schema...");
try {
await this.db.query(`DEFINE TABLE OVERWRITE ${this.tableName} COMMENT 'Automatically created by express-session SurrealDB Store'`), e.logger?.info?.("SurrealDBStore: Schema created successfully.");
} catch (t) {
e.logger?.error?.("SurrealDBStore: Failed to create schema: " + t.message);
}
}), this.options.autoSweepExpired) {
const t = this.options.autoSweepIntervalMs ?? 6e5;
setInterval(() => {
this.db.query(
"DELETE type::table($table) WHERE expires < time::now()",
{ table: this.tableName }
).then(() => {
e.logger?.info?.(`SurrealDBStore: Swept expired sessions from table ${this.tableName}`);
}).catch((s) => {
e.logger?.error?.(`SurrealDBStore: Failed to sweep expired sessions: ${s.message}`);
});
}, t);
}
}
/**
* Perform the initial connection to the database. This also sets the scope of our connection.
*/
async _connect() {
this.options.logger?.info?.("SurrealDBStore: Connecting to SurrealDB...");
const e = {
namespace: this.options.useOpts?.namespace,
database: this.options.useOpts?.database,
authentication: this.options.signinOpts,
...this.options.connectionOpts
};
await this.db.connect(this.options.url, e).then(() => {
this.hasConnected = !0, this.options.logger?.info?.("SurrealDBStore: Connected to SurrealDB.");
}).catch((t) => {
this.options.logger?.error?.(`SurrealDBStore: Failed to connect to SurrealDB!
` + t.message + `
` + t.stack);
}), this.isConnected = !0, this.hasConnected = !0;
}
/**
* Get session data by session ID
*/
get(e, t) {
const s = this.options.customGetter ? this.options.customGetter(this.db, e) : this.db.select(new r(this.tableName, e));
this.options.logger?.debug?.("SurrealDBStore: Getting session data for session ID: " + e), s.then((o) => {
this.options.logger?.debug?.("SurrealDBStore: Got session data for session ID: " + e), t(null, o);
}).catch((o) => {
this.options.logger?.error?.("SurrealDBStore: Failed to get session data for session ID: " + e + `
` + o.message + `
` + o.stack), t(o);
});
}
/**
* Set session data for a given session ID
*/
set(e, t, s) {
const o = this.options.customSetter ? this.options.customSetter(this.db, e, t) : this.db.upsert(new r(this.tableName, e)).content(t);
this.options.logger?.debug?.("SurrealDBStore: Setting session data for session ID: " + e), o.then((a) => {
this.options.logger?.debug?.("SurrealDBStore: Set session data for session ID: " + e), s(null, a);
}).catch((a) => {
this.options.logger?.error?.("SurrealDBStore: Failed to set session data for session ID: " + e + `
` + a.message + `
` + a.stack), s(a);
});
}
touch(e, t, s) {
this.set(e, t, s);
}
destroy(e, t) {
this.db.delete(new r(this.tableName, e)).then(() => {
this.options.logger?.debug?.("SurrealDBStore: Destroyed session data for session ID: " + e), t(null);
}).catch((s) => {
s.message.includes("Expected a single result output when using the ONLY keyword") ? (this.options.logger?.debug?.("SurrealDBStore: SurrealDB returned a known SDK error when destroying session: " + e), t(null)) : (this.options.logger?.error?.("SurrealDBStore: Failed to destroy session data for session ID: " + e + `
` + s.message + `
` + s.stack), t(s));
});
}
length(e) {
this.db.query("SELECT count() FROM type::table($table) GROUP ALL", { table: this.tableName }).collect().then(([t]) => {
this.options.logger?.debug?.("SurrealDBStore: Got session count: " + t[0].count), e(t[0].count);
}).catch((t) => {
this.options.logger?.error?.(`SurrealDBStore: Failed to get session count
` + t.message + `
` + t.stack), e(t);
});
}
all(e) {
this.db.select(new l(this.tableName)).then(([t]) => {
this.options.logger?.debug?.("SurrealDBStore: Got all session data"), e(t);
}).catch((t) => {
this.options.logger?.error?.(`SurrealDBStore: Failed to get all session data
` + t.message + `
` + t.stack), e(t);
});
}
clear(e) {
this.db.query("DELETE type::table($table)", { table: this.tableName }).then(() => {
this.options.logger?.debug?.("SurrealDBStore: Cleared all session data"), e(null);
}).catch((t) => {
this.options.logger?.error?.(`SurrealDBStore: Failed to clear all session data
` + t.message + `
` + t.stack), e(t);
});
}
}
export {
g as SurrealDBStore
};
//# sourceMappingURL=connect-surreal.js.map