Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 1x 1x | /**
* @packageDocumentation
*
* IndexedDB persistence for project metadata (not file contents). Manages
* the list of known projects with CRUD operations, slug generation, and
* last-opened tracking.
*/
import { get, set } from "idb-keyval";
import { uuidv7 } from "uuidv7";
import type { Project, ProjectSource } from "./types";
import { slugify } from "./slugify";
const PROJECTS_KEY = "projects";
async function getAllProjects(): Promise<Project[]> {
return (await get(PROJECTS_KEY)) ?? [];
}
async function saveProjects(projects: Project[]): Promise<void> {
await set(PROJECTS_KEY, projects);
}
export async function listProjects(): Promise<Project[]> {
const projects = await getAllProjects();
return projects.toSorted(
(a, b) => new Date(b.lastOpenedAt).getTime() - new Date(a.lastOpenedAt).getTime(),
);
}
export async function addProject(displayName: string, source: ProjectSource): Promise<Project> {
const projects = await getAllProjects();
const baseSlug = slugify(displayName);
let slug = baseSlug;
let suffix = 1;
while (projects.some((p) => p.slug === slug)) {
slug = `${baseSlug}-${suffix}`;
suffix++;
}
const now = new Date().toISOString();
const project: Project = {
id: uuidv7(),
slug,
displayName,
source,
createdAt: now,
lastOpenedAt: now,
lastUpdatedAt: now,
};
projects.push(project);
await saveProjects(projects);
return project;
}
export async function removeProject(slug: string): Promise<void> {
const projects = await getAllProjects();
await saveProjects(projects.filter((p) => p.slug !== slug));
}
export async function touchProject(slug: string): Promise<void> {
const projects = await getAllProjects();
const project = projects.find((p) => p.slug === slug);
if (project) {
project.lastOpenedAt = new Date().toISOString();
await saveProjects(projects);
}
}
export async function getProjectBySlug(slug: string): Promise<Project | undefined> {
const projects = await getAllProjects();
return projects.find((p) => p.slug === slug);
}
export const DEMO_SLUG = "__demo__";
export function createDemoProject(name: string): Project {
const now = new Date().toISOString();
return {
id: uuidv7(),
slug: DEMO_SLUG,
displayName: name,
source: { provider: "examples", name },
createdAt: now,
lastOpenedAt: now,
lastUpdatedAt: now,
};
}
export { createDemoProjectFile } from "./demo-project";
|