Skip to content

Instantly share code, notes, and snippets.

@342b45
Last active May 16, 2024 00:06
Show Gist options
  • Save 342b45/b9dcdd8832b51d6fa25af7dbd6ba9597 to your computer and use it in GitHub Desktop.
Save 342b45/b9dcdd8832b51d6fa25af7dbd6ba9597 to your computer and use it in GitHub Desktop.
import { prefixStorage } from "unstorage";
import type { Storage } from "unstorage";
type Session = {
id: string
userId: string
expiredAt: Date
}
export const DEFAULT_SESSION_PREFIX = "session";
export const DEFAULT_USER_SESSION_PREFIX = "user_session";
export class unstorageAdapter {
private kv: Storage;
private prefixes?: {
session: string;
userSession: string;
};
constructor(
storage: Storage,
prefixes?: {
session: string;
userSession: string;
},
) {
this.kv = storage;
this.prefixes = prefixes;
}
private sessionStorage() {
return prefixStorage<Session>(
this.kv,
this.prefixes?.session ?? DEFAULT_SESSION_PREFIX,
);
}
private getUserSessionStorage(userId: string) {
const prefix = [
this.prefixes?.userSession ?? DEFAULT_USER_SESSION_PREFIX,
userId,
].join(":");
return prefixStorage<"">(this.kv, prefix);
}
public async getSession(sessionId: string) {
const sessionResult = await this.sessionStorage().getItem(sessionId);
if (!sessionResult) {
return null;
}
return sessionResult;
}
public async getSessionByUserId(userId: string) {
const userSessionStorage = this.getUserSessionStorage(userId);
const sessionIds = await userSessionStorage.getKeys();
const sessionResults = await Promise.allSettled(
sessionIds.map((id) => {
return this.sessionStorage().getItem(id);
}),
);
return sessionResults.filter(
(sessionResult): sessionResult is NonNullable<typeof sessionResult> => {
return sessionResult !== null;
},
);
}
public async setSession(session: Session) {
const userSessionStorage = this.getUserSessionStorage(session.userId);
await Promise.allSettled([
userSessionStorage.setItem(session.id, ""),
this.sessionStorage().setItem(session.id, session),
]);
}
public async deleteSession(sessionId: string) {
const sessionResult = await this.sessionStorage().getItem(sessionId);
if (!sessionResult) return null;
await Promise.all([
this.sessionStorage().removeItem(sessionId),
this.kv.removeItem(
`user_session:${sessionResult.userId}:${sessionResult.id}`,
),
]);
}
public async deleteSessionByUserId(userId: string) {
const userSessionStorage = this.getUserSessionStorage(userId);
const sessionIds = await userSessionStorage.getKeys();
await Promise.all([
...sessionIds.map((sessionId) => {
return this.sessionStorage().removeItem(sessionId);
}),
...sessionIds.map((sessionId) => {
return this.kv.removeItem(`user_session:${userId}:${sessionId}`);
}),
]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment