From f61fef862b7eb293c0c5d413932f0d031110bc2e Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Wed, 19 Mar 2025 01:58:44 -0400 Subject: [PATCH] chore: update kkrpc and tauri-api-adapter versions, enhance serialization handling - Bump kkrpc version to 0.2.2 in multiple packages including desktop and api. - Update tauri-api-adapter version to 0.3.27. - Introduce a new utility function to determine kkrpc serialization based on API version. - Refactor RPC channel initialization to include serialization version in desktop extension handling. - Increment desktop package version to 0.1.36 and api package version to 0.1.7. --- apps/desktop/package.json | 4 +- apps/desktop/src/lib/cmds/ext.ts | 12 +++++- apps/desktop/src/lib/utils/kkrpc.ts | 19 +++++++++ .../app/extension/ui-iframe/+page.svelte | 13 +++++- .../app/extension/ui-worker/+page.svelte | 12 +++++- deno.lock | 18 ++++----- packages/api/package.json | 6 +-- packages/api/src/models/manifest.ts | 3 +- packages/api/src/version.ts | 2 +- packages/extension/src/load.ts | 15 ++++++- pnpm-lock.yaml | 40 ++++++++----------- 11 files changed, 98 insertions(+), 46 deletions(-) create mode 100644 apps/desktop/src/lib/utils/kkrpc.ts diff --git a/apps/desktop/package.json b/apps/desktop/package.json index f3163ed..5e2ed15 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@kksh/desktop", - "version": "0.1.35", + "version": "0.1.36", "description": "", "type": "module", "scripts": { @@ -33,7 +33,7 @@ "eslint": "^9.21.0", "fuse.js": "^7.1.0", "gsap": "^3.12.7", - "kkrpc": "^0.2.1", + "kkrpc": "^0.2.2", "lz-string": "^1.5.0", "pretty-bytes": "^6.1.1", "semver": "^7.7.1", diff --git a/apps/desktop/src/lib/cmds/ext.ts b/apps/desktop/src/lib/cmds/ext.ts index dd35023..ff2c17c 100644 --- a/apps/desktop/src/lib/cmds/ext.ts +++ b/apps/desktop/src/lib/cmds/ext.ts @@ -3,6 +3,7 @@ import { appState } from "@/stores" import { winExtMap } from "@/stores/winExtMap" import { helperAPI } from "@/utils/helper" import { paste } from "@/utils/hotkey" +import { decideKkrpcSerialization } from "@/utils/kkrpc" import { sleep } from "@/utils/time" import { trimSlash } from "@/utils/url" import { constructExtensionSupportDir } from "@kksh/api" @@ -16,6 +17,7 @@ import { convertFileSrc } from "@tauri-apps/api/core" import * as path from "@tauri-apps/api/path" import { getCurrentWindow } from "@tauri-apps/api/window" import * as fs from "@tauri-apps/plugin-fs" +import { info } from "@tauri-apps/plugin-log" import { platform } from "@tauri-apps/plugin-os" import { goto } from "$app/navigation" import { RPCChannel, WorkerParentIO } from "kkrpc/browser" @@ -85,6 +87,7 @@ export async function onHeadlessCmdSelect( const loadedExt = await loadExtensionManifestFromDisk( await path.join(ext.extPath, "package.json") ) + const scriptPath = await path.join(loadedExt.extPath, cmd.main) const workerScript = await fs.readTextFile(scriptPath) const blob = new Blob([workerScript], { type: "application/javascript" }) @@ -124,8 +127,15 @@ export async function onHeadlessCmdSelect( } satisfies IApp } const io = new WorkerParentIO(worker) + const kkrpcSerialization = decideKkrpcSerialization(loadedExt) + info( + `Establishing kkrpc connection for ${loadedExt.kunkun.identifier} with serialization: ${kkrpcSerialization}` + ) const rpc = new RPCChannel(io, { - expose: serverAPI2 + expose: serverAPI2, + serialization: { + version: kkrpcSerialization + } }) const workerAPI = rpc.getAPI() await workerAPI.load() diff --git a/apps/desktop/src/lib/utils/kkrpc.ts b/apps/desktop/src/lib/utils/kkrpc.ts new file mode 100644 index 0000000..7281048 --- /dev/null +++ b/apps/desktop/src/lib/utils/kkrpc.ts @@ -0,0 +1,19 @@ +import { parseAPIVersion } from "@kksh/extension/load" +import type { ExtPackageJsonExtra } from "@kunkunapi/src/models/manifest" +import semver from "semver" + +/** + * Decide the serialization method for kkrpc based on the api version + * apiVersion is populated in loadExtensionManifestFromDisk, but we parse it again + * @param apiVersion - The version of the @kksh/api + * @returns "superjson" or "json" + */ +export function decideKkrpcSerialization(ext: ExtPackageJsonExtra): "superjson" | "json" { + const apiVersion = parseAPIVersion(ext.dependencies || {}) + if (apiVersion && semver.lte(apiVersion, "0.1.5")) { + // 0.1.6 is the first version that supports superjson and default to use superjson + return "json" + } + // fallback default to use superjson, some extensions might not install @kksh/api + return "superjson" +} diff --git a/apps/desktop/src/routes/app/extension/ui-iframe/+page.svelte b/apps/desktop/src/routes/app/extension/ui-iframe/+page.svelte index 7405b3b..4fc1d2d 100644 --- a/apps/desktop/src/routes/app/extension/ui-iframe/+page.svelte +++ b/apps/desktop/src/routes/app/extension/ui-iframe/+page.svelte @@ -5,6 +5,7 @@ import { helperAPI } from "@/utils/helper" import { paste } from "@/utils/hotkey" import { goBackOnEscape } from "@/utils/key" + import { decideKkrpcSerialization } from "@/utils/kkrpc" import { goHome } from "@/utils/route" import { positionToCssStyleString, positionToTailwindClasses } from "@/utils/style" import { sleep } from "@/utils/time" @@ -27,6 +28,7 @@ } from "@kunkunapi/src/events" import { emitTo } from "@tauri-apps/api/event" import { getCurrentWindow } from "@tauri-apps/api/window" + import { info } from "@tauri-apps/plugin-log" import { goto } from "$app/navigation" import { IframeParentIO, RPCChannel } from "kkrpc/browser" import { ArrowLeftIcon, MoveIcon, RefreshCcwIcon, XIcon } from "lucide-svelte" @@ -170,7 +172,16 @@ }, 200) if (iframeRef?.contentWindow) { const io = new IframeParentIO(iframeRef.contentWindow) - const rpc = new RPCChannel(io, { expose: serverAPI2 }) + const kkrpcSerialization = decideKkrpcSerialization(loadedExt) + info( + `Establishing kkrpc connection for ${loadedExt.kunkun.identifier} with serialization: ${kkrpcSerialization}` + ) + const rpc = new RPCChannel(io, { + expose: serverAPI2, + serialization: { + version: kkrpcSerialization + } + }) } else { toast.warning("iframeRef.contentWindow not available") } diff --git a/apps/desktop/src/routes/app/extension/ui-worker/+page.svelte b/apps/desktop/src/routes/app/extension/ui-worker/+page.svelte index 6aef00e..8f569f6 100644 --- a/apps/desktop/src/routes/app/extension/ui-worker/+page.svelte +++ b/apps/desktop/src/routes/app/extension/ui-worker/+page.svelte @@ -5,6 +5,7 @@ import { winExtMap } from "@/stores/winExtMap.js" import { helperAPI } from "@/utils/helper.js" import { paste } from "@/utils/hotkey" + import { decideKkrpcSerialization } from "@/utils/kkrpc.js" import { emitReloadOneExtension, listenToFileDrop, @@ -43,7 +44,7 @@ import { getCurrentWindow } from "@tauri-apps/api/window" import * as fs from "@tauri-apps/plugin-fs" import { readTextFile } from "@tauri-apps/plugin-fs" - import { debug } from "@tauri-apps/plugin-log" + import { debug, info } from "@tauri-apps/plugin-log" import { platform } from "@tauri-apps/plugin-os" import { goto } from "$app/navigation" import { RPCChannel, WorkerParentIO } from "kkrpc/browser" @@ -270,8 +271,15 @@ } satisfies IApp } const io = new WorkerParentIO(worker) + const kkrpcSerialization = decideKkrpcSerialization(loadedExt) + info( + `Establishing kkrpc connection for ${loadedExt.kunkun.identifier} with serialization: ${kkrpcSerialization}` + ) const rpc = new RPCChannel(io, { - expose: serverAPI2 + expose: serverAPI2, + serialization: { + version: kkrpcSerialization + } }) workerAPI = rpc.getAPI() await workerAPI.load() diff --git a/deno.lock b/deno.lock index 45fd2e5..90645c5 100644 --- a/deno.lock +++ b/deno.lock @@ -141,7 +141,7 @@ "npm:i18next@^23.15.1": "23.16.8", "npm:inquirer@^10.1.2": "10.2.2", "npm:katex@~0.16.21": "0.16.21", - "npm:kkrpc@~0.2.1": "0.2.1_typescript@5.6.3", + "npm:kkrpc@~0.2.2": "0.2.2_typescript@5.6.3", "npm:lodash@^4.17.21": "4.17.21", "npm:lucide-svelte@0.469": "0.469.0_svelte@5.19.6__acorn@8.14.0", "npm:lucide-svelte@0.471": "0.471.0_svelte@5.19.6__acorn@8.14.0", @@ -206,7 +206,7 @@ "npm:tailwindcss@^3.4.6": "3.4.17_postcss@8.5.1", "npm:tailwindcss@^3.4.7": "3.4.17_postcss@8.5.1", "npm:tar@^7.4.3": "7.4.3", - "npm:tauri-api-adapter@~0.3.26": "0.3.26_typescript@5.6.3", + "npm:tauri-api-adapter@~0.3.27": "0.3.27_typescript@5.6.3", "npm:tauri-plugin-clipboard-api@^2.1.11": "2.1.11_typescript@5.6.3", "npm:tauri-plugin-shellx-api@^2.0.14": "2.0.14", "npm:tauri-plugin-shellx-api@^2.0.16": "2.0.16", @@ -10726,8 +10726,8 @@ "kind-of@6.0.3": { "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, - "kkrpc@0.2.1_typescript@5.6.3": { - "integrity": "sha512-LjB7OMMJYA5W+g7LcyCvYuskwMKOaF/TmeAkmHYZIEp1BUor69I/P7hNOZYAf2oAwpTbhSGOR7Bso+QhkjqxGA==", + "kkrpc@0.2.2_typescript@5.6.3": { + "integrity": "sha512-EliGFPRf+dplMiqNipPUUj89WX9vEWfQkQU05ztbMfdK/SSgnHBbvm7QySGlEIlUb9Y55dSXPkROuxjHz2JbfA==", "dependencies": [ "@tauri-apps/plugin-shell@2.2.0", "superjson", @@ -14839,8 +14839,8 @@ "yallist@5.0.0" ] }, - "tauri-api-adapter@0.3.26_typescript@5.6.3": { - "integrity": "sha512-AfdxF6EIBrpkhciySkLheYBlpFkUG3dIXHTJXLhhn00fibKBZBSiLps7u9s1WVGcSonGrqXzqgsAjRX1nOHyhQ==", + "tauri-api-adapter@0.3.27_typescript@5.6.3": { + "integrity": "sha512-YzfdVlOdwlRqjRRPxvXNTb6acclbrfHC4FtotzAXcbZv7UckEE3Orzvg4AteP5Gb1veyam+NW0MFMU5Ime5vWw==", "dependencies": [ "@tauri-apps/api@2.3.0", "@tauri-apps/plugin-dialog@2.2.0", @@ -16353,7 +16353,7 @@ "npm:fuse.js@^7.1.0", "npm:globals@^15.14.0", "npm:gsap@^3.12.7", - "npm:kkrpc@~0.2.1", + "npm:kkrpc@~0.2.2", "npm:lucide-svelte@0.474", "npm:lz-string@^1.5.0", "npm:prettier@^3.5.2", @@ -16404,14 +16404,14 @@ "npm:@types/node@^22.10.5", "npm:@types/semver@^7.5.8", "npm:fs-extra@^11.2.0", - "npm:kkrpc@~0.2.1", + "npm:kkrpc@~0.2.2", "npm:lodash@^4.17.21", "npm:madge@8", "npm:minimatch@^10.0.1", "npm:node-fetch@^3.3.2", "npm:semver@^7.6.3", "npm:svelte-sonner@~0.3.28", - "npm:tauri-api-adapter@~0.3.26", + "npm:tauri-api-adapter@~0.3.27", "npm:tauri-plugin-network-api@2.0.5", "npm:tauri-plugin-shellx-api@^2.0.16", "npm:tauri-plugin-system-info-api@2.0.8", diff --git a/packages/api/package.json b/packages/api/package.json index ebf25c9..dff64fa 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@kksh/api", - "version": "0.1.6", + "version": "0.1.7", "type": "module", "repository": { "type": "git", @@ -65,13 +65,13 @@ "@tauri-apps/plugin-store": "^2.2.0", "@tauri-apps/plugin-updater": "^2.3.0", "@tauri-apps/plugin-upload": "^2.2.1", - "kkrpc": "^0.2.1", + "kkrpc": "^0.2.2", "lodash": "^4.17.21", "minimatch": "^10.0.1", "node-fetch": "^3.3.2", "semver": "^7.6.3", "svelte-sonner": "^0.3.28", - "tauri-api-adapter": "^0.3.26", + "tauri-api-adapter": "^0.3.27", "tauri-plugin-network-api": "2.0.5", "tauri-plugin-shellx-api": "^2.0.16", "tauri-plugin-system-info-api": "2.0.8", diff --git a/packages/api/src/models/manifest.ts b/packages/api/src/models/manifest.ts index 2fa8bc0..8ce5405 100644 --- a/packages/api/src/models/manifest.ts +++ b/packages/api/src/models/manifest.ts @@ -195,7 +195,8 @@ export const ExtPackageJsonExtra = v.object({ ...ExtPackageJson.entries, ...{ extPath: v.string(), - extFolderName: v.string() + extFolderName: v.string(), + apiVersion: v.optional(v.string("API version of the extension")) } }) diff --git a/packages/api/src/version.ts b/packages/api/src/version.ts index 62671f1..f28c86d 100644 --- a/packages/api/src/version.ts +++ b/packages/api/src/version.ts @@ -21,7 +21,7 @@ export const breakingChangesVersionCheckpoints = [ const checkpointVersions = breakingChangesVersionCheckpoints.map((c) => c.version) const sortedCheckpointVersions = sort(checkpointVersions) -export const version = "0.1.6" +export const version = "0.1.7" export function isVersionBetween(v: string, start: string, end: string) { const vCleaned = clean(v) diff --git a/packages/extension/src/load.ts b/packages/extension/src/load.ts index 9ff330d..5af4543 100644 --- a/packages/extension/src/load.ts +++ b/packages/extension/src/load.ts @@ -3,6 +3,7 @@ import { ExtPackageJson, ExtPackageJsonExtra, License } from "@kksh/api/models" import { basename, dirname, join } from "@tauri-apps/api/path" import { readDir, readTextFile } from "@tauri-apps/plugin-fs" import { debug, error } from "@tauri-apps/plugin-log" +import semver from "semver" import * as v from "valibot" import { upsertExtension } from "./db" @@ -11,6 +12,15 @@ const OptionalExtPackageJson = v.object({ license: v.optional(License, "MIT") // TODO: remove this optional package json later }) +export function parseAPIVersion(dependencies: Record) { + const stripPrefix = (version: string) => version.replace(/^[^0-9]+/, "") // Remove leading ^, ~, etc. + const apiVersion = dependencies["@kksh/api"] + if (apiVersion) { + return semver.clean(stripPrefix(apiVersion)) ?? undefined + } + return undefined +} + /** * * @param manifestPath absolute path to package.json @@ -26,12 +36,13 @@ export function loadExtensionManifestFromDisk(manifestPath: string): Promise(parse.issues)) throw new Error(`Invalid manifest: ${manifestPath}`) } else { - // debug(`Loaded extension ${parse.output.kunkun.identifier} from ${manifestPath}`) + const apiVersion = parseAPIVersion(parse.output.dependencies || {}) const extPath = await dirname(manifestPath) const extFolderName = await basename(extPath) return Object.assign(parse.output, { extPath, - extFolderName + extFolderName, + apiVersion }) } }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a81535..a7c2917 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -255,8 +255,8 @@ importers: specifier: ^3.12.7 version: 3.12.7 kkrpc: - specifier: ^0.2.1 - version: 0.2.1(typescript@5.6.3) + specifier: ^0.2.2 + version: 0.2.2(typescript@5.6.3) lz-string: specifier: ^1.5.0 version: 1.5.0 @@ -442,8 +442,8 @@ importers: specifier: ^2.2.1 version: 2.2.1 kkrpc: - specifier: ^0.2.1 - version: 0.2.1(typescript@5.7.2) + specifier: ^0.2.2 + version: 0.2.2(typescript@5.7.2) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -460,8 +460,8 @@ importers: specifier: ^0.3.28 version: 0.3.28(svelte@5.20.5) tauri-api-adapter: - specifier: ^0.3.26 - version: 0.3.26(typescript@5.7.2) + specifier: ^0.3.27 + version: 0.3.27(typescript@5.7.2) tauri-plugin-network-api: specifier: 2.0.5 version: 2.0.5(typescript@5.7.2) @@ -8799,8 +8799,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - kkrpc@0.2.1: - resolution: {integrity: sha512-LjB7OMMJYA5W+g7LcyCvYuskwMKOaF/TmeAkmHYZIEp1BUor69I/P7hNOZYAf2oAwpTbhSGOR7Bso+QhkjqxGA==} + kkrpc@0.2.2: + resolution: {integrity: sha512-EliGFPRf+dplMiqNipPUUj89WX9vEWfQkQU05ztbMfdK/SSgnHBbvm7QySGlEIlUb9Y55dSXPkROuxjHz2JbfA==} peerDependencies: typescript: ^5.0.0 @@ -11173,10 +11173,6 @@ packages: supercluster@7.1.5: resolution: {integrity: sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==} - superjson@2.2.1: - resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} - engines: {node: '>=16'} - superjson@2.2.2: resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} engines: {node: '>=16'} @@ -11366,8 +11362,8 @@ packages: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} - tauri-api-adapter@0.3.26: - resolution: {integrity: sha512-AfdxF6EIBrpkhciySkLheYBlpFkUG3dIXHTJXLhhn00fibKBZBSiLps7u9s1WVGcSonGrqXzqgsAjRX1nOHyhQ==} + tauri-api-adapter@0.3.27: + resolution: {integrity: sha512-YzfdVlOdwlRqjRRPxvXNTb6acclbrfHC4FtotzAXcbZv7UckEE3Orzvg4AteP5Gb1veyam+NW0MFMU5Ime5vWw==} peerDependencies: typescript: ^5.0.0 @@ -18526,7 +18522,7 @@ snapshots: mitt: 3.0.1 perfect-debounce: 1.0.0 speakingurl: 14.0.1 - superjson: 2.2.1 + superjson: 2.2.2 '@vue/devtools-kit@7.6.4': dependencies: @@ -18536,7 +18532,7 @@ snapshots: mitt: 3.0.1 perfect-debounce: 1.0.0 speakingurl: 14.0.1 - superjson: 2.2.1 + superjson: 2.2.2 '@vue/devtools-shared@7.6.4': dependencies: @@ -21836,7 +21832,7 @@ snapshots: kind-of@6.0.3: {} - kkrpc@0.2.1(typescript@5.6.3): + kkrpc@0.2.2(typescript@5.6.3): dependencies: '@tauri-apps/plugin-shell': 2.2.0 superjson: 2.2.2 @@ -21846,7 +21842,7 @@ snapshots: - bufferutil - utf-8-validate - kkrpc@0.2.1(typescript@5.7.2): + kkrpc@0.2.2(typescript@5.7.2): dependencies: '@tauri-apps/plugin-shell': 2.2.0 superjson: 2.2.2 @@ -24655,10 +24651,6 @@ snapshots: dependencies: kdbush: 3.0.0 - superjson@2.2.1: - dependencies: - copy-anything: 3.0.5 - superjson@2.2.2: dependencies: copy-anything: 3.0.5 @@ -25089,7 +25081,7 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 - tauri-api-adapter@0.3.26(typescript@5.7.2): + tauri-api-adapter@0.3.27(typescript@5.7.2): dependencies: '@tauri-apps/api': 2.3.0 '@tauri-apps/plugin-dialog': 2.2.0 @@ -25100,7 +25092,7 @@ snapshots: '@tauri-apps/plugin-os': 2.2.0 '@tauri-apps/plugin-shell': 2.2.0 '@tauri-apps/plugin-upload': 2.2.1 - kkrpc: 0.2.1(typescript@5.7.2) + kkrpc: 0.2.2(typescript@5.7.2) rimraf: 6.0.1 shx: 0.3.4 tauri-plugin-clipboard-api: 2.1.11(typescript@5.7.2)