SqlSessionDriver
interfaz
Driver SQL de SqlSessionStore: la aplicación escribe las sentencias con su cliente. replace
y revokeFamily deben ser atómicos. D1SessionDriver de @meekojs/meeko/cloudflare es una
implementación.
import type { SqlSessionDriver } from "@meekojs/meeko/server";Source code src/server/runtime/session-stores.ts:251
Declaración #
interface SqlSessionDriver {
read(id: string): Promise<SqlSessionRow | undefined>
write(row: SqlSessionRow): Promise<void>
remove(id: string): Promise<void>
replace(previousId: string, row: SqlSessionRow, now: number): Promise<boolean>
revokeFamily(familyId: string): Promise<void>
rateLimit?(key: Uint8Array, windowMs: number, now: number): Promise<SqlRateLimitRow>
close?(): Promise<void>
}Example #
import type { SqlSessionDriver } from "@meekojs/meeko/server";
const driver: SqlSessionDriver = {
read: (id) => db.get("SELECT * FROM sessions WHERE id = ?", id),
write: (row) => db.run("INSERT OR REPLACE INTO sessions VALUES (?, ?, ?, ?, ?, ?)", row.id, row.familyId, row.csrfToken, row.dataJson, row.createdAt, row.expiresAt),
remove: (id) => db.run("DELETE FROM sessions WHERE id = ?", id),
replace: (previousId, row, now) => db.transaction(() => replaceRow(previousId, row, now)),
revokeFamily: (familyId) => db.run("DELETE FROM sessions WHERE family_id = ?", familyId),
};Miembros #
write
#
write(row: SqlSessionRow): Promise<void>Inserta o actualiza una fila por su ID opaco; debe imponer un único ID activo por familia.
replace
#
replace(previousId: string, row: SqlSessionRow, now: number): Promise<boolean>Sustituye en una transacción una fila no caducada de la misma familia; false si no existe.
revokeFamily
#
revokeFamily(familyId: string): Promise<void>Borra en una operación atómica la fila activa de la familia, también desde un handle anterior.
rateLimit
#
rateLimit?(key: Uint8Array, windowMs: number, now: number): Promise<SqlRateLimitRow>Cuenta una petición en la ventana fija de key con una sola sentencia atómica y devuelve la
fila resultante (desde 1.7). Opcional: con él, SqlSessionStore implementa
SessionStore.rateLimit y los límites de rateLimit se comparten entre instancias; sin él,
se cuentan en la memoria de cada instancia, con un aviso en producción.
key son los 32 bytes del SHA-256 de la clave del contador, que Meeko ya calcula como un
resumen de la ruta y el sujeto: nunca llega una IP en claro y la columna tiene ancho fijo
(bytea en PostgreSQL, BLOB en SQLite). Si no existe una fila para key, o su ventana
terminó (window_ends_at <= now), la sentencia escribe count = 1 y
window_ends_at = now + windowMs; si no, suma uno y conserva el final de la ventana. Debe ser
atómica frente a peticiones concurrentes, como INSERT … ON CONFLICT DO UPDATE … RETURNING.
Si falla, la petición limitada se rechaza.
See also #
- Sessions and security Framework full-stack