From de3886d41603c476e1559aa5505add283742c5b8 Mon Sep 17 00:00:00 2001 From: Huakun Date: Thu, 3 Apr 2025 12:42:27 -0400 Subject: [PATCH] feat: implement clipboard data cleaning for data older than 10 days (#267) * Update drizzle-orm to version 0.41.0 and implement clipboard cleanup functionality - Updated drizzle-orm dependency in package.json and pnpm-lock.yaml to version 0.41.0. - Added a new utility function `cleanClipboard` to remove clipboard entries older than 10 days. - Integrated clipboard cleanup into the initialization process, logging success or failure. - Refactored drizzle exports to include `proxyDB` for better access to the database proxy. - Minor cleanup in the proxy.ts file to remove commented-out debug logs. * Refactor clipboard cleanup logic to use configurable days parameter - Introduced a variable `nDays` to allow dynamic adjustment of the clipboard cleanup threshold. - Updated logging to reflect the configurable number of days for clipboard entry deletion instead of a hardcoded value. * Enhance clipboard and database management in initialization process - Added logging to `cleanClipboard` to indicate the number of clipboard entries older than a specified number of days. - Introduced a new utility function `vacuumSqlite` for database maintenance, which is now called during app initialization. - Updated the `init` function to await the completion of `cleanClipboard` and `vacuumSqlite` for better error handling and flow control. - Ensured that the console attachment in `onMount` is awaited for proper synchronization. * Update version in package.json from 0.1.37-beta.1 to 0.1.37 * Adds C11 standard flag for builds Try to fix windows build beta CI Adds the C11 standard flag to the build environment. This ensures that the code is compiled using the C11 standard, potentially improving compatibility and avoiding compiler-specific behavior. * Remove CFLAGS for C11 standard from beta build workflow This change eliminates the CFLAGS environment variable previously set for C11 standard compliance in the beta build process, streamlining the build configuration. --- apps/desktop/package.json | 4 +- apps/desktop/src/lib/utils/clipboard.ts | 44 +++++++++ apps/desktop/src/lib/utils/db.ts | 13 +++ apps/desktop/src/lib/utils/init.ts | 15 ++- apps/desktop/src/routes/app/+layout.svelte | 2 +- packages/drizzle/index.ts | 1 + packages/drizzle/package.json | 1 + packages/drizzle/src/proxy.ts | 12 +-- .../permissions/autogenerated/reference.md | 2 - pnpm-lock.yaml | 99 +------------------ 10 files changed, 82 insertions(+), 111 deletions(-) create mode 100644 apps/desktop/src/lib/utils/clipboard.ts create mode 100644 apps/desktop/src/lib/utils/db.ts diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 1649263..25c6195 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@kksh/desktop", - "version": "0.1.37-beta.1", + "version": "0.1.37", "description": "", "type": "module", "scripts": { @@ -32,7 +32,7 @@ "@tauri-apps/plugin-stronghold": "^2.2.0", "@tauri-store/svelte": "^2.1.1", "dompurify": "^3.2.4", - "drizzle-orm": "^0.40.1", + "drizzle-orm": "^0.41.0", "eslint": "^9.21.0", "fuse.js": "^7.1.0", "gsap": "^3.12.7", diff --git a/apps/desktop/src/lib/utils/clipboard.ts b/apps/desktop/src/lib/utils/clipboard.ts new file mode 100644 index 0000000..a1b604e --- /dev/null +++ b/apps/desktop/src/lib/utils/clipboard.ts @@ -0,0 +1,44 @@ +import { proxyDB, schema } from "@kksh/drizzle" +import { getExtClipboard } from "@kksh/drizzle/api" +import { error, info } from "@tauri-apps/plugin-log" +import * as orm from "drizzle-orm" + +/** + * For now, simply delete all clipboard data older than 10 days + */ +export async function cleanClipboard() { + const nDays = 10 + const clipboardExt = await getExtClipboard() + const nDaysAgo = new Date() + nDaysAgo.setDate(nDaysAgo.getDate() - nDays) + + try { + // Select data older than 10 days to check what will be deleted + const oldClipboardData = await proxyDB + .select({ count: orm.count() }) + .from(schema.extensionData) + .where( + orm.and( + orm.eq(schema.extensionData.extId, clipboardExt.extId), + orm.lt(schema.extensionData.createdAt, nDaysAgo.toISOString()) + ) + ) + const nLinesToDelete = oldClipboardData.at(0)?.count ?? 0 + console.info(`Found ${nLinesToDelete} clipboard entries older than ${nDays} days to clean up`) + info(`Found ${nLinesToDelete} clipboard entries older than ${nDays} days to clean up`) + + // Now delete the old data + const deleted = await proxyDB + .delete(schema.extensionData) + .where( + orm.and( + orm.eq(schema.extensionData.extId, clipboardExt.extId), + orm.lt(schema.extensionData.createdAt, nDaysAgo.toISOString()) + ) + ) + + console.log("deleted", deleted) + } catch (e) { + error(`Error during clipboard cleanup: ${e}`) + } +} diff --git a/apps/desktop/src/lib/utils/db.ts b/apps/desktop/src/lib/utils/db.ts new file mode 100644 index 0000000..44c46d2 --- /dev/null +++ b/apps/desktop/src/lib/utils/db.ts @@ -0,0 +1,13 @@ +import { proxyDB } from "@kksh/drizzle" +import { error, info } from "@tauri-apps/plugin-log" +import { sql } from "drizzle-orm" + +export async function vacuumSqlite() { + const statement = sql`VACUUM` + try { + await proxyDB.run(statement) + info("Vacuumed sqlite") + } catch (error) { + console.error(`Failed to vacuum sqlite: ${error}`) + } +} diff --git a/apps/desktop/src/lib/utils/init.ts b/apps/desktop/src/lib/utils/init.ts index bd8751c..44327e2 100644 --- a/apps/desktop/src/lib/utils/init.ts +++ b/apps/desktop/src/lib/utils/init.ts @@ -1,14 +1,16 @@ import { appConfig, extensions } from "@/stores" import { getCurrentWindow } from "@tauri-apps/api/window" -import { info } from "@tauri-apps/plugin-log" +import { error, info } from "@tauri-apps/plugin-log" import { dev } from "$app/environment" +import { cleanClipboard } from "./clipboard" +import { vacuumSqlite } from "./db" import { mapKeyToTauriKey, registerAppHotkey } from "./hotkey" import { listenToReloadOneExtension } from "./tauri-events" /** * Initialize the app */ -export function init() { +export async function init() { const window = getCurrentWindow() if (window.label === "main") { initMainWindow() @@ -17,7 +19,14 @@ export function init() { extensions.reloadExtension(extPath) }) } - + await cleanClipboard() + .then(() => { + info("Cleaned clipboard") + }) + .catch((e) => { + error(`Failed to clean clipboard: ${e}`) + }) + vacuumSqlite() if (!dev) { // document.addEventListener("contextmenu", function (event) { // event.preventDefault() diff --git a/apps/desktop/src/routes/app/+layout.svelte b/apps/desktop/src/routes/app/+layout.svelte index 51457ea..1616f5e 100644 --- a/apps/desktop/src/routes/app/+layout.svelte +++ b/apps/desktop/src/routes/app/+layout.svelte @@ -53,7 +53,7 @@ unlisteners.forEach((unlistener) => unlistener()) }) onMount(async () => { - attachConsole().then((unlistener) => unlisteners.push(unlistener)) + await attachConsole().then((unlistener) => unlisteners.push(unlistener)) initDeeplink().then((unlistener) => unlisteners.push(unlistener)) shellx .fixPathEnv() diff --git a/packages/drizzle/index.ts b/packages/drizzle/index.ts index 7be6aab..4e2652f 100644 --- a/packages/drizzle/index.ts +++ b/packages/drizzle/index.ts @@ -1,3 +1,4 @@ export * as schema from "./drizzle/schema" export * as relations from "./drizzle/relations" export * as db from "./src/apis" +export { db as proxyDB } from "./src/proxy" diff --git a/packages/drizzle/package.json b/packages/drizzle/package.json index 630ad3a..556f4d2 100644 --- a/packages/drizzle/package.json +++ b/packages/drizzle/package.json @@ -5,6 +5,7 @@ "exports": { ".": "./index.ts", "./api": "./src/apis.ts", + "./proxy": "./src/proxy.ts", "./schema": "./drizzle/schema.ts", "./relations": "./drizzle/relations.ts" }, diff --git a/packages/drizzle/src/proxy.ts b/packages/drizzle/src/proxy.ts index 2514b2f..7e780d8 100644 --- a/packages/drizzle/src/proxy.ts +++ b/packages/drizzle/src/proxy.ts @@ -11,12 +11,12 @@ export const db = drizzle( async (sqlQuery, params, method) => { let rows: any = [] let results = [] - console.log({ - sql: sqlQuery, - params, - method - }) - console.log(sqlQuery) + // console.log({ + // sql: sqlQuery, + // params, + // method + // }) + // console.log(sqlQuery) // If the query is a SELECT, use the select method if (isSelectQuery(sqlQuery)) { rows = await sql.select(sqlQuery, params).catch((e) => { diff --git a/packages/tauri-plugins/jarvis/permissions/autogenerated/reference.md b/packages/tauri-plugins/jarvis/permissions/autogenerated/reference.md index 06546b4..ddf14e4 100644 --- a/packages/tauri-plugins/jarvis/permissions/autogenerated/reference.md +++ b/packages/tauri-plugins/jarvis/permissions/autogenerated/reference.md @@ -1,4 +1,3 @@ - ## Permission Table @@ -7,7 +6,6 @@ -
Description
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1a08ad0..c72213c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -258,8 +258,8 @@ importers: specifier: ^3.2.4 version: 3.2.4 drizzle-orm: - specifier: ^0.40.1 - version: 0.40.1(@libsql/client@0.15.1)(bun-types@1.2.7)(gel@2.0.1) + specifier: ^0.41.0 + version: 0.41.0(@libsql/client@0.15.1)(bun-types@1.2.7)(gel@2.0.1) eslint: specifier: ^9.21.0 version: 9.21.0(jiti@2.4.0) @@ -7719,95 +7719,6 @@ packages: resolution: {integrity: sha512-l6dMSE100u7sDaTbLczibrQZjA35jLsHNqIV+jmhNVO3O8jzM6kywMOmV9uOz9ZVSCMPQhAZEFjL/qDPVrqpUA==} hasBin: true - drizzle-orm@0.40.1: - resolution: {integrity: sha512-aPNhtiJiPfm3qxz1czrnIDkfvkSdKGXYeZkpG55NPTVI186LmK2fBLMi4dsHpPHlJrZeQ92D322YFPHADBALew==} - peerDependencies: - '@aws-sdk/client-rds-data': '>=3' - '@cloudflare/workers-types': '>=4' - '@electric-sql/pglite': '>=0.2.0' - '@libsql/client': '>=0.10.0' - '@libsql/client-wasm': '>=0.10.0' - '@neondatabase/serverless': '>=0.10.0' - '@op-engineering/op-sqlite': '>=2' - '@opentelemetry/api': ^1.4.1 - '@planetscale/database': '>=1' - '@prisma/client': '*' - '@tidbcloud/serverless': '*' - '@types/better-sqlite3': '*' - '@types/pg': '*' - '@types/sql.js': '*' - '@vercel/postgres': '>=0.8.0' - '@xata.io/client': '*' - better-sqlite3: '>=7' - bun-types: '*' - expo-sqlite: '>=14.0.0' - gel: '>=2' - knex: '*' - kysely: '*' - mysql2: '>=2' - pg: '>=8' - postgres: '>=3' - prisma: '*' - sql.js: '>=1' - sqlite3: '>=5' - peerDependenciesMeta: - '@aws-sdk/client-rds-data': - optional: true - '@cloudflare/workers-types': - optional: true - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - '@libsql/client-wasm': - optional: true - '@neondatabase/serverless': - optional: true - '@op-engineering/op-sqlite': - optional: true - '@opentelemetry/api': - optional: true - '@planetscale/database': - optional: true - '@prisma/client': - optional: true - '@tidbcloud/serverless': - optional: true - '@types/better-sqlite3': - optional: true - '@types/pg': - optional: true - '@types/sql.js': - optional: true - '@vercel/postgres': - optional: true - '@xata.io/client': - optional: true - better-sqlite3: - optional: true - bun-types: - optional: true - expo-sqlite: - optional: true - gel: - optional: true - knex: - optional: true - kysely: - optional: true - mysql2: - optional: true - pg: - optional: true - postgres: - optional: true - prisma: - optional: true - sql.js: - optional: true - sqlite3: - optional: true - drizzle-orm@0.41.0: resolution: {integrity: sha512-7A4ZxhHk9gdlXmTdPj/lREtP+3u8KvZ4yEN6MYVxBzZGex5Wtdc+CWSbu7btgF6TB0N+MNPrvW7RKBbxJchs/Q==} peerDependencies: @@ -20759,12 +20670,6 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.40.1(@libsql/client@0.15.1)(bun-types@1.2.7)(gel@2.0.1): - optionalDependencies: - '@libsql/client': 0.15.1 - bun-types: 1.2.7 - gel: 2.0.1 - drizzle-orm@0.41.0(@libsql/client@0.15.1)(bun-types@1.2.7)(gel@2.0.1): optionalDependencies: '@libsql/client': 0.15.1