From de3886d41603c476e1559aa5505add283742c5b8 Mon Sep 17 00:00:00 2001 From: Huakun Date: Thu, 3 Apr 2025 12:42:27 -0400 Subject: [PATCH 1/2] 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 From 3542eec2778ac726d8ea04fde16e8c524ef242cb Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Thu, 3 Apr 2025 16:46:40 -0400 Subject: [PATCH 2/2] feat: add GitHub Actions workflow for desktop test builds --- .github/workflows/test-build.yml | 121 +++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 .github/workflows/test-build.yml diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml new file mode 100644 index 0000000..cb8931a --- /dev/null +++ b/.github/workflows/test-build.yml @@ -0,0 +1,121 @@ +name: "Desktop Test build" + +on: + push: + branches: + - "test-build" + tags: + - "v*" + workflow_dispatch: + +jobs: + publish-tauri: + permissions: + contents: write + strategy: + fail-fast: false + matrix: + settings: + - platform: "macos-14" # for Arm based macs (M1 and above). + args: "--target aarch64-apple-darwin --verbose --config src-tauri/tauri.conf.publish.json" + - platform: "macos-13" # for Intel based macs. + args: "--target x86_64-apple-darwin --verbose --config src-tauri/tauri.conf.publish.json" + # Universal Build no longer supported after adding openssl, which is not cross-compilable. + - platform: "macos-14" # for Both Arm and Intel based macs. + args: "--target universal-apple-darwin --verbose --config src-tauri/tauri.conf.publish.json" + - platform: "ubuntu-22.04" # for Tauri v1 you could replace this with ubuntu-20.04. + args: "--verbose --config src-tauri/tauri.conf.publish.json" + - platform: "windows-latest" + args: "--verbose --config src-tauri/tauri.conf.publish.json" + + runs-on: ${{ matrix.settings.platform }} + steps: + - uses: actions/checkout@v4 + with: + submodules: "true" + + - name: Install Dependencies (ubuntu only) + if: matrix.settings.platform == 'ubuntu-22.04' # This must match the platform value defined above. + run: | + sudo apt-get update + sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libxdo-dev + # You can remove the one that doesn't apply to your app to speed up the workflow a bit. + - name: Install protobuf (Mac) + if: startsWith(matrix.settings.platform, 'macos') + run: | + brew install protobuf + brew install openssl + - name: Install Protobuf (Ubuntu) + if: matrix.settings.platform == 'ubuntu-22.04' + run: | + sudo apt install -y protobuf-compiler + - uses: pnpm/action-setup@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: "pnpm" # Set this to npm, yarn or pnpm. + cache-dependency-path: ./pnpm-lock.yaml + - name: Install protoc and openssl for windows + if: matrix.settings.platform == 'windows-latest' + run: | + choco install protoc + choco install openssl + echo OPENSSL_DIR='C:\Program Files\OpenSSL' >> $env:GITHUB_ENV + echo OPENSSL_INCLUDE_DIR='C:\Program Files\OpenSSL\include' >> $env:GITHUB_ENV + echo OPENSSL_LIB_DIR='C:\Program Files\OpenSSL\lib\VC\x64\MDd' >> $env:GITHUB_ENV + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + # Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds. + targets: ${{ matrix.settings.platform == 'macos-14' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} + - name: Add rust target (macos only) + if: matrix.settings.platform == 'macos-14' + run: | + rustup target add aarch64-apple-darwin + rustup target add x86_64-apple-darwin + - name: Rust Cache + uses: swatinem/rust-cache@v2 + with: + workspaces: ". -> target" + - uses: oven-sh/setup-bun@v1 + with: + bun-version: latest + - name: Install Dependencies + run: pnpm install + - name: Environment Check + run: | + # pnpm --filter=@kksh/ci run ci-env-check + bun packages/ci/scripts/ci-env-check.ts + - name: Build Packages + env: + NODE_OPTIONS: --max-old-space-size=4096 + run: pnpm build + - name: Get App Version + if: matrix.settings.platform == 'windows-latest' + id: appversion + run: | + echo "version=$(node -p "require('./apps/desktop/package.json').version")" >> $env:GITHUB_OUTPUT + - uses: tauri-apps/tauri-action@v0 + env: + CI: false + KUNKUN_PUBLISH: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_OPTIONS: --max-old-space-size=4096 + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + with: + tagName: Kunkun-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version. + releaseName: "Kunkun v__VERSION__" + releaseBody: "See the assets to download this version and install." + releaseDraft: false + prerelease: false + args: ${{ matrix.settings.args }} ${{ contains(steps.appversion.outputs.version, 'beta') && matrix.settings.platform == 'windows-latest' && '-b nsis' || '' }} + projectPath: "./apps/desktop"