Add version history, screenshots, embed generator, collections, npm search, format-on-save, and custom fonts
This commit is contained in:
115
db.js
115
db.js
@@ -54,6 +54,47 @@ db.exec(`
|
||||
|
||||
db.exec(`CREATE INDEX IF NOT EXISTS idx_fiddles_listed_updated ON fiddles(listed, updated_at DESC)`);
|
||||
|
||||
// Migration: add screenshot column
|
||||
try {
|
||||
db.exec(`ALTER TABLE fiddles ADD COLUMN screenshot TEXT`);
|
||||
} catch (_) { /* column already exists */ }
|
||||
|
||||
// Version history table
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS fiddle_versions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
fiddle_id TEXT NOT NULL REFERENCES fiddles(id) ON DELETE CASCADE,
|
||||
version INTEGER NOT NULL,
|
||||
html TEXT NOT NULL DEFAULT '',
|
||||
css TEXT NOT NULL DEFAULT '',
|
||||
css_type TEXT NOT NULL DEFAULT 'css',
|
||||
js TEXT NOT NULL DEFAULT '',
|
||||
js_type TEXT NOT NULL DEFAULT 'javascript',
|
||||
options TEXT NOT NULL DEFAULT '{}',
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
)
|
||||
`);
|
||||
db.exec(`CREATE INDEX IF NOT EXISTS idx_versions_fiddle ON fiddle_versions(fiddle_id, version DESC)`);
|
||||
|
||||
// Collections tables
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS collections (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
)
|
||||
`);
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS collection_fiddles (
|
||||
collection_id TEXT NOT NULL REFERENCES collections(id) ON DELETE CASCADE,
|
||||
fiddle_id TEXT NOT NULL REFERENCES fiddles(id) ON DELETE CASCADE,
|
||||
position INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (collection_id, fiddle_id)
|
||||
)
|
||||
`);
|
||||
|
||||
export const stmts = {
|
||||
insert: db.prepare(`
|
||||
INSERT INTO fiddles (id, title, html, css, css_type, js, js_type, listed, options)
|
||||
@@ -86,6 +127,58 @@ export const stmts = {
|
||||
HAVING count > 0
|
||||
ORDER BY count DESC
|
||||
`),
|
||||
|
||||
// Versions
|
||||
insertVersion: db.prepare(`
|
||||
INSERT INTO fiddle_versions (fiddle_id, version, html, css, css_type, js, js_type, options)
|
||||
VALUES (@fiddle_id, @version, @html, @css, @css_type, @js, @js_type, @options)
|
||||
`),
|
||||
getMaxVersion: db.prepare('SELECT COALESCE(MAX(version), 0) as max_ver FROM fiddle_versions WHERE fiddle_id = ?'),
|
||||
listVersions: db.prepare('SELECT id, version, created_at FROM fiddle_versions WHERE fiddle_id = ? ORDER BY version DESC'),
|
||||
getVersion: db.prepare('SELECT * FROM fiddle_versions WHERE fiddle_id = ? AND version = ?'),
|
||||
deleteOldVersions: db.prepare(`
|
||||
DELETE FROM fiddle_versions WHERE fiddle_id = ? AND id NOT IN (
|
||||
SELECT id FROM fiddle_versions WHERE fiddle_id = ? ORDER BY version DESC LIMIT 50
|
||||
)
|
||||
`),
|
||||
|
||||
// Screenshot
|
||||
updateScreenshot: db.prepare('UPDATE fiddles SET screenshot = ? WHERE id = ?'),
|
||||
|
||||
// Collections
|
||||
insertCollection: db.prepare(`
|
||||
INSERT INTO collections (id, name, description) VALUES (@id, @name, @description)
|
||||
`),
|
||||
listCollections: db.prepare(`
|
||||
SELECT c.*, COUNT(cf.fiddle_id) as fiddle_count
|
||||
FROM collections c
|
||||
LEFT JOIN collection_fiddles cf ON cf.collection_id = c.id
|
||||
GROUP BY c.id
|
||||
ORDER BY c.updated_at DESC
|
||||
`),
|
||||
getCollection: db.prepare('SELECT * FROM collections WHERE id = ?'),
|
||||
updateCollection: db.prepare(`
|
||||
UPDATE collections SET name = @name, description = @description, updated_at = datetime('now') WHERE id = @id
|
||||
`),
|
||||
deleteCollection: db.prepare('DELETE FROM collections WHERE id = ?'),
|
||||
addFiddleToCollection: db.prepare(`
|
||||
INSERT OR IGNORE INTO collection_fiddles (collection_id, fiddle_id, position)
|
||||
VALUES (@collection_id, @fiddle_id, (SELECT COALESCE(MAX(position), 0) + 1 FROM collection_fiddles WHERE collection_id = @collection_id))
|
||||
`),
|
||||
removeFiddleFromCollection: db.prepare('DELETE FROM collection_fiddles WHERE collection_id = ? AND fiddle_id = ?'),
|
||||
getCollectionFiddles: db.prepare(`
|
||||
SELECT f.id, f.title, f.css_type, f.js_type, f.created_at, f.updated_at, f.screenshot,
|
||||
SUBSTR(f.html, 1, 200) as html_preview, SUBSTR(f.js, 1, 200) as js_preview
|
||||
FROM fiddles f
|
||||
JOIN collection_fiddles cf ON cf.fiddle_id = f.id
|
||||
WHERE cf.collection_id = ?
|
||||
ORDER BY cf.position
|
||||
`),
|
||||
getCollectionsForFiddle: db.prepare(`
|
||||
SELECT c.id, c.name FROM collections c
|
||||
JOIN collection_fiddles cf ON cf.collection_id = c.id
|
||||
WHERE cf.fiddle_id = ?
|
||||
`),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -102,4 +195,26 @@ export function setFiddleTags(fiddleId, tagNames) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Snapshot current fiddle state as a version before overwriting.
|
||||
*/
|
||||
export function snapshotVersion(fiddleId) {
|
||||
const fiddle = stmts.get.get(fiddleId);
|
||||
if (!fiddle) return;
|
||||
const { max_ver } = stmts.getMaxVersion.get(fiddleId);
|
||||
const version = max_ver + 1;
|
||||
stmts.insertVersion.run({
|
||||
fiddle_id: fiddleId,
|
||||
version,
|
||||
html: fiddle.html,
|
||||
css: fiddle.css,
|
||||
css_type: fiddle.css_type,
|
||||
js: fiddle.js,
|
||||
js_type: fiddle.js_type,
|
||||
options: fiddle.options || '{}',
|
||||
});
|
||||
// Cap at 50 versions
|
||||
stmts.deleteOldVersions.run(fiddleId, fiddleId);
|
||||
}
|
||||
|
||||
export default db;
|
||||
|
||||
Reference in New Issue
Block a user