fix: duplicate api calls from comlink (#27)

* refactor: replace comlink with kkrpc

* fix: import path in api pkg and btn styling in ui iframe page

* fix: fixed fetch API from kkRPC migrate

* refactor: replace comlink-stdio with kkrpc

* update deno lock

* bump @kksh/api

* update API version

* publish api pkg again to fix kkrpc version

* update pnpm lock

* dep: fix dependency problems

* dep: update deno.lock

* chore: remove 2 submodules

they were added only for integration development

* update pnpm lock

* fix: test template path

* format: with prettier

* downgrade next version

* ci: try to fix next build on windows

* try to fix CI

* Revert "try to fix CI"

This reverts commit b9c63c392f50f1d2d3ceec406e49b1af2348c740.

* upgrade tauri-api-adapter

* try to fix next

* remove templates from pnpm workspace

* update CI test

* publish @kksh/api with upgraded tauri-api-adapter to fix nextjs template
This commit is contained in:
Huakun Shen 2024-11-19 05:57:31 -05:00 committed by GitHub
parent e812d4229d
commit ad30a8c3bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
61 changed files with 14435 additions and 2124 deletions

2
.gitmodules vendored
View File

@ -6,4 +6,4 @@
url = https://github.com/HuakunShen/tauri-plugin-network.git url = https://github.com/HuakunShen/tauri-plugin-network.git
[submodule "vendors/tauri-plugin-system-info"] [submodule "vendors/tauri-plugin-system-info"]
path = vendors/tauri-plugin-system-info path = vendors/tauri-plugin-system-info
url = https://github.com/HuakunShen/tauri-plugin-system-info.git url = https://github.com/HuakunShen/tauri-plugin-system-info.git

View File

@ -1,3 +1,4 @@
.svelte-kit/ .svelte-kit/
target/ target/
vendors vendors
.nuxt/

View File

@ -9,5 +9,6 @@
"titleBar.activeBackground": "#2f0ec4", "titleBar.activeBackground": "#2f0ec4",
"titleBar.activeForeground": "#FFFBFC" "titleBar.activeForeground": "#FFFBFC"
}, },
"svelte.enable-ts-plugin": true "svelte.enable-ts-plugin": true,
"deno.enable": false
} }

View File

@ -3,26 +3,22 @@
> Kunkun is a cross-platform extensible app launcher like Raycast or Alfred. > Kunkun is a cross-platform extensible app launcher like Raycast or Alfred.
> All extensions run in a sandboxed environment by default to ensure security. > All extensions run in a sandboxed environment by default to ensure security.
[![wakatime](https://wakatime.com/badge/user/94be0fbf-cb9d-411d-8526-d0c4a4e82e1a/project/455bfd3f-4faf-4c2a-afe9-556d9ee1a0f7.svg)](https://wakatime.com/badge/user/94be0fbf-cb9d-411d-8526-d0c4a4e82e1a/project/455bfd3f-4faf-4c2a-afe9-556d9ee1a0f7) [![wakatime](https://wakatime.com/badge/user/94be0fbf-cb9d-411d-8526-d0c4a4e82e1a/project/455bfd3f-4faf-4c2a-afe9-556d9ee1a0f7.svg)](https://wakatime.com/badge/user/94be0fbf-cb9d-411d-8526-d0c4a4e82e1a/project/455bfd3f-4faf-4c2a-afe9-556d9ee1a0f7)
![GitHub last commit](https://img.shields.io/github/last-commit/kunkunsh/kunkun) ![GitHub last commit](https://img.shields.io/github/last-commit/kunkunsh/kunkun)
[![YouTube badge][]][YouTube link] [![YouTube badge][]][YouTube link]
[![Discord Invite](https://dcbadge.limes.pink/api/server/7dzw3TYeTU)](https://discord.gg/7dzw3TYeTU) [![Discord Invite](https://dcbadge.limes.pink/api/server/7dzw3TYeTU)](https://discord.gg/7dzw3TYeTU)
- Website: https://kunkun.sh/ - Website: https://kunkun.sh/
- Documentation: https://docs.kunkun.sh/ - Documentation: https://docs.kunkun.sh/
[YouTube badge]: https://img.shields.io/youtube/channel/subscribers/UC1gJeFbvRcQXDC_C8nKetdA?style=social [YouTube badge]: https://img.shields.io/youtube/channel/subscribers/UC1gJeFbvRcQXDC_C8nKetdA?style=social
[YouTube link]: https://www.youtube.com/@huakun [YouTube link]: https://www.youtube.com/@huakun
## Download ## Download
- From the Website: https://kunkun.sh/download/ - From the Website: https://kunkun.sh/download/
- From GitHub Releases: https://github.com/kunkunsh/kunkun/releases - From GitHub Releases: https://github.com/kunkunsh/kunkun/releases
## Platforms ## Platforms
- [x] MacOS - [x] MacOS

View File

@ -20,17 +20,15 @@ const templateNames = ["react", "vue", "nuxt", "svelte", "sveltekit", "next", "t
fs.rmdirSync(testDir, { recursive: true }) fs.rmdirSync(testDir, { recursive: true })
fs.mkdirpSync(testDir) fs.mkdirpSync(testDir)
const testTemplateDirs: string[] = [] const testTemplateDirs: string[] = []
await Promise.all( for (const templateName of templateNames) {
templateNames.map(async (templateName) => { const folderName = `${templateName}-ext`
const folderName = `${templateName}-ext` await $`node ${createKKIndexjsPath} --outdir ${testDir} --name ${folderName} --template ${templateName}`
await $`node ${createKKIndexjsPath} --outdir ${testDir} --name ${folderName} --template ${templateName}` const templateDir = path.join(testDir, folderName)
const templateDir = path.join(testDir, folderName) console.log("templateDir", templateDir)
console.log("templateDir", templateDir) await $`pnpm install`.cwd(templateDir).quiet()
await $`pnpm install`.cwd(templateDir).quiet() await $`pnpm build`.cwd(templateDir).quiet()
await $`pnpm build`.cwd(templateDir).quiet() testTemplateDirs.push(templateDir)
testTemplateDirs.push(templateDir) }
})
)
test("Build And Verify", async () => { test("Build And Verify", async () => {
for (const templateDir of testTemplateDirs) { for (const templateDir of testTemplateDirs) {

View File

@ -1,12 +1,12 @@
import { expect, test } from "bun:test"
import path from "path" import path from "path"
import { getRootDir } from "@/constants" import { getRootDir } from "@/constants"
import { expect, test } from "bun:test"
import fs from "fs-extra" import fs from "fs-extra"
import { verifyCmd } from "../src/commands/verify" import { verifyCmd } from "../src/commands/verify"
const rootDir = getRootDir() const rootDir = getRootDir()
const extensionsDir = path.join(rootDir, "../../packages/extensions") const extensionsDir = path.join(rootDir, "../../packages/extensions")
const templatesDir = path.join(rootDir, "../../templates") const templatesDir = path.join(rootDir, "../../packages/templates")
const extsPaths = fs const extsPaths = fs
.readdirSync(extensionsDir) .readdirSync(extensionsDir)

View File

@ -2,10 +2,10 @@
* This is a E2E test, create every template from production build and run `npm install` and `npm run build` * This is a E2E test, create every template from production build and run `npm install` and `npm run build`
* When running `npm install` with bun shell, it fails in bun test environment, so I simply run everything as regular ts without test() * When running `npm install` with bun shell, it fails in bun test environment, so I simply run everything as regular ts without test()
*/ */
import { $ } from "bun"
import { afterAll, beforeAll, describe, expect, test } from "bun:test"
import os from "os" import os from "os"
import path from "path" import path from "path"
import { $ } from "bun"
import { afterAll, beforeAll, describe, expect, test } from "bun:test"
import fs from "fs-extra" import fs from "fs-extra"
import { getRootDir } from "../src/constants" import { getRootDir } from "../src/constants"

View File

@ -64,7 +64,7 @@ if (!fs.existsSync(outdir)) {
async function copyTemplate(templateTgz: string, targetFolderName: string): Promise<string> { async function copyTemplate(templateTgz: string, targetFolderName: string): Promise<string> {
const destDir = path.join(outdir, targetFolderName) const destDir = path.join(outdir, targetFolderName)
if (!fs.existsSync(templateTgz)) { if (!fs.existsSync(templateTgz)) {
console.error(`Worker Extension Template not found at ${templateTgz}`) console.error(`Worker Extension Template not found at ${templateTgz}`)
process.exit(1) process.exit(1)

View File

@ -15,29 +15,28 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@formkit/auto-animate": "^0.8.2", "@formkit/auto-animate": "^0.8.2",
"@huakunshen/comlink": "^4.4.1",
"@kksh/extension": "workspace:*", "@kksh/extension": "workspace:*",
"@kksh/supabase": "workspace:*", "@kksh/supabase": "workspace:*",
"@kksh/ui": "workspace:*", "@kksh/ui": "workspace:*",
"@kksh/utils": "workspace:*", "@kksh/utils": "workspace:*",
"@std/semver": "npm:@jsr/std__semver@^1.0.3", "@std/semver": "npm:@jsr/std__semver@^1.0.3",
"@tanstack/table-core": "^8.20.5", "@tanstack/table-core": "^8.20.5",
"@tauri-apps/api": "^2.1.0", "@tauri-apps/api": "^2.1.1",
"@tauri-apps/plugin-shell": "^2", "@tauri-apps/plugin-shell": "^2.0.1",
"gsap": "^3.12.5", "gsap": "^3.12.5",
"kkrpc": "^0.0.12",
"lz-string": "^1.5.0", "lz-string": "^1.5.0",
"mode-watcher": "^0.4.1",
"semver": "^7.6.3", "semver": "^7.6.3",
"svelte-sonner": "^0.3.28", "svelte-sonner": "^0.3.28",
"sveltekit-superforms": "^2.20.0", "sveltekit-superforms": "^2.20.1",
"tauri-plugin-clipboard-api": "^2.1.11", "tauri-plugin-clipboard-api": "^2.1.11",
"uuid": "^11.0.3" "uuid": "^11.0.3"
}, },
"devDependencies": { "devDependencies": {
"@kksh/types": "workspace:*", "@kksh/types": "workspace:*",
"@sveltejs/adapter-static": "^3.0.6", "@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.8.0", "@sveltejs/kit": "^2.8.1",
"@sveltejs/vite-plugin-svelte": "^4.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.1",
"@tailwindcss/aspect-ratio": "^0.4.2", "@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/forms": "^0.5.9", "@tailwindcss/forms": "^0.5.9",
@ -46,19 +45,16 @@
"@types/bun": "latest", "@types/bun": "latest",
"@types/semver": "^7.5.8", "@types/semver": "^7.5.8",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"bits-ui": "1.0.0-next.49", "bits-ui": "1.0.0-next.60",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"embla-carousel-svelte": "^8.3.1", "lucide-svelte": "^0.460.1",
"formsnap": "^1.0.1",
"lucide-svelte": "^0.456.0",
"svelte-radix": "^2.0.1", "svelte-radix": "^2.0.1",
"tailwind-merge": "^2.5.4", "tailwind-merge": "^2.5.4",
"tailwind-variants": "^0.2.1", "tailwind-variants": "^0.3.0",
"tailwindcss": "^3.4.14", "tailwindcss": "^3.4.15",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.6.3", "typescript": "^5.6.3",
"vaul-svelte": "^0.3.2", "vite": "^5.4.11"
"vite": "^5.4.10"
} }
} }

View File

@ -109,7 +109,7 @@
} }
</script> </script>
<div class="flex justify-center gap-3 my-3"> <div class="my-3 flex justify-center gap-3">
<Button size="sm" onclick={pickExtFolders}>Install from Extension Folders</Button> <Button size="sm" onclick={pickExtFolders}>Install from Extension Folders</Button>
<Button size="sm" onclick={pickExtFiles}>Install from Extension Tarball File</Button> <Button size="sm" onclick={pickExtFiles}>Install from Extension Tarball File</Button>
</div> </div>

View File

@ -1,6 +1,6 @@
import { type ClassValue, clsx } from "clsx"; import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)); return twMerge(clsx(inputs))
} }

View File

@ -12,23 +12,45 @@ export function positionToTailwindClasses(position: Position) {
case "bottom-right": case "bottom-right":
return "bottom-2 right-2" return "bottom-2 right-2"
default: default:
let className = "" return ""
const parseOutput = v.safeParse(CustomPosition, position)
if (!parseOutput.success) {
return ""
}
if (parseOutput.output.top) {
className += ` top-[${parseOutput.output.top / 4}rem]`
}
if (parseOutput.output.right) {
className += ` right-[${parseOutput.output.right / 4}rem]`
}
if (parseOutput.output.bottom) {
className += ` bottom-[${parseOutput.output.bottom / 4}rem]`
}
if (parseOutput.output.left) {
className += ` left-[${parseOutput.output.left / 4}rem]`
}
return className
} }
} }
export function positionToCssStyleObj(position?: Position) {
if (!position) {
return {}
}
if (typeof position === "string") {
return {}
}
const parseRes = v.safeParse(CustomPosition, position)
if (!parseRes.success) {
return {}
}
const customPos = parseRes.output
const ret: {
top?: string
bottom?: string
left?: string
right?: string
} = {}
if (customPos.bottom != undefined) {
ret.bottom = `${customPos.bottom}rem`
}
if (customPos.top != undefined) {
ret.top = `${customPos.top}rem`
}
if (customPos.left != undefined) {
ret.left = `${customPos.left}rem`
}
if (customPos.right != undefined) {
ret.right = `${customPos.right}rem`
}
return ret
}
export function positionToCssStyleString(position?: Position) {
return Object.entries(positionToCssStyleObj(position))
.map(([key, value]) => `${key}: ${value}`)
.join(";")
}

View File

@ -0,0 +1 @@
export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))

View File

@ -25,12 +25,6 @@
import { onMount } from "svelte" import { onMount } from "svelte"
import { hasCommand, whereIsCommand } from "tauri-plugin-shellx-api" import { hasCommand, whereIsCommand } from "tauri-plugin-shellx-api"
onMount(() => {
hasCommand("ffmpeg").then((has) => {
console.log("has", has)
})
})
let inputEle: HTMLInputElement | null = null let inputEle: HTMLInputElement | null = null
function onKeyDown(event: KeyboardEvent) { function onKeyDown(event: KeyboardEvent) {
if (event.key === "Escape") { if (event.key === "Escape") {

View File

@ -8,12 +8,7 @@
</script> </script>
<svelte:window on:keydown={goBackOnEscape} /> <svelte:window on:keydown={goBackOnEscape} />
<Button <Button variant="outline" size="icon" onclick={goBack} class="absolute left-2 top-2">
variant="outline"
size="icon"
onclick={goBack}
class="absolute left-2 top-2"
>
<ArrowLeft class="size-4" /> <ArrowLeft class="size-4" />
</Button> </Button>
<Layouts.Center class="h-screen w-screen" data-tauri-drag-region> <Layouts.Center class="h-screen w-screen" data-tauri-drag-region>

View File

@ -3,13 +3,13 @@
import { appConfig, winExtMap } from "@/stores" import { appConfig, winExtMap } from "@/stores"
import { goBackOnEscape } from "@/utils/key" import { goBackOnEscape } from "@/utils/key"
import { goHome } from "@/utils/route" import { goHome } from "@/utils/route"
import { positionToTailwindClasses } from "@/utils/style" import { positionToCssStyleString, positionToTailwindClasses } from "@/utils/style"
import { isInMainWindow } from "@/utils/window" import { isInMainWindow } from "@/utils/window"
import { db } from "@kksh/api/commands" import { db } from "@kksh/api/commands"
import { ThemeColor, type Position } from "@kksh/api/models" import { CustomPosition, ThemeColor, type Position } from "@kksh/api/models"
import { import {
constructJarvisServerAPIWithPermissions, constructJarvisServerAPIWithPermissions,
exposeApiToWindow, // exposeApiToWindow,
type IApp, type IApp,
type IUiIframe type IUiIframe
} from "@kksh/api/ui" } from "@kksh/api/ui"
@ -18,8 +18,10 @@
import { cn } from "@kksh/ui/utils" import { cn } from "@kksh/ui/utils"
import { getCurrentWindow } from "@tauri-apps/api/window" import { getCurrentWindow } from "@tauri-apps/api/window"
import { goto } from "$app/navigation" import { goto } from "$app/navigation"
import { IframeParentIO, RPCChannel } from "kkrpc/browser"
import { ArrowLeftIcon, MoveIcon, RefreshCcwIcon, XIcon } from "lucide-svelte" import { ArrowLeftIcon, MoveIcon, RefreshCcwIcon, XIcon } from "lucide-svelte"
import { onDestroy, onMount } from "svelte" import { onDestroy, onMount } from "svelte"
import * as v from "valibot"
import type { PageData } from "./$types" import type { PageData } from "./$types"
let { data }: { data: PageData } = $props() let { data }: { data: PageData } = $props()
@ -64,6 +66,8 @@
uiControl.showRefreshBtn = false uiControl.showRefreshBtn = false
}, },
showBackButton: async (position?: Position) => { showBackButton: async (position?: Position) => {
console.log("showBackBtn", position)
uiControl.showBackBtn = true uiControl.showBackBtn = true
uiControl.backBtnPosition = position ?? "top-left" uiControl.backBtnPosition = position ?? "top-left"
}, },
@ -129,7 +133,9 @@
onMount(() => { onMount(() => {
appWin.show() appWin.show()
if (iframeRef?.contentWindow) { if (iframeRef?.contentWindow) {
exposeApiToWindow(iframeRef.contentWindow, serverAPI) const io = new IframeParentIO(iframeRef.contentWindow)
const rpc = new RPCChannel(io, { expose: serverAPI })
// exposeApiToWindow(iframeRef.contentWindow, serverAPI)
} else { } else {
toast.warning("iframeRef.contentWindow not available") toast.warning("iframeRef.contentWindow not available")
} }
@ -144,19 +150,16 @@
onDestroy(() => { onDestroy(() => {
winExtMap.unregisterExtensionFromWindow(appWin.label) winExtMap.unregisterExtensionFromWindow(appWin.label)
}) })
const backBtnPositionClass = $derived(positionToTailwindClasses(uiControl.backBtnPosition))
const moveBtnPositionClass = $derived(positionToTailwindClasses(uiControl.moveBtnPosition))
const refreshBtnPositionClass = $derived(positionToTailwindClasses(uiControl.refreshBtnPosition))
</script> </script>
<svelte:window on:keydown={goBackOnEscape} /> <svelte:window on:keydown={goBackOnEscape} />
{#if uiControl.backBtnPosition} {#if uiControl.backBtnPosition}
<Button <Button
class={cn("absolute", backBtnPositionClass)} class={cn("absolute", positionToTailwindClasses(uiControl.backBtnPosition))}
size="icon" size="icon"
variant="outline" variant="outline"
onclick={onBackBtnClicked} onclick={onBackBtnClicked}
style={`${positionToCssStyleString(uiControl.backBtnPosition)}`}
> >
{#if appWin.label === "main"} {#if appWin.label === "main"}
<ArrowLeftIcon class="w-4" /> <ArrowLeftIcon class="w-4" />
@ -167,7 +170,8 @@
{/if} {/if}
{#if uiControl.moveBtnPosition} {#if uiControl.moveBtnPosition}
<Button <Button
class={cn("absolute", moveBtnPositionClass)} class={cn("absolute", positionToTailwindClasses(uiControl.moveBtnPosition))}
style={`${positionToCssStyleString(uiControl.moveBtnPosition)}`}
size="icon" size="icon"
variant="outline" variant="outline"
data-tauri-drag-region data-tauri-drag-region
@ -177,7 +181,8 @@
{/if} {/if}
{#if uiControl.refreshBtnPosition} {#if uiControl.refreshBtnPosition}
<Button <Button
class={cn("absolute", refreshBtnPositionClass)} class={cn("absolute", positionToTailwindClasses(uiControl.refreshBtnPosition))}
style={`${positionToCssStyleString(uiControl.refreshBtnPosition)}`}
size="icon" size="icon"
variant="outline" variant="outline"
onclick={iframeUiAPI.reloadPage} onclick={iframeUiAPI.reloadPage}

View File

@ -3,15 +3,16 @@
import { winExtMap } from "@/stores/winExtMap.js" import { winExtMap } from "@/stores/winExtMap.js"
import { listenToFileDrop, listenToRefreshDevExt } from "@/utils/tauri-events.js" import { listenToFileDrop, listenToRefreshDevExt } from "@/utils/tauri-events.js"
import { isInMainWindow } from "@/utils/window.js" import { isInMainWindow } from "@/utils/window.js"
import { type Remote } from "@huakunshen/comlink" // import { type Remote } from "@huakunshen/comlink"
import { db } from "@kksh/api/commands" import { db } from "@kksh/api/commands"
import { import {
constructJarvisServerAPIWithPermissions, constructJarvisServerAPIWithPermissions,
exposeApiToWorker, // exposeApiToWorker,
type IApp, type IApp,
type IUiWorker type IUiWorker
} from "@kksh/api/ui" } from "@kksh/api/ui"
import { import {
clipboard,
// constructJarvisExtDBToServerDbAPI, // constructJarvisExtDBToServerDbAPI,
FormNodeNameEnum, FormNodeNameEnum,
FormSchema, FormSchema,
@ -20,7 +21,7 @@
MarkdownSchema, MarkdownSchema,
NodeNameEnum, NodeNameEnum,
toast, toast,
wrap, // wrap,
type IComponent, type IComponent,
type IDb, type IDb,
type WorkerExtension type WorkerExtension
@ -32,15 +33,18 @@
import type { UnlistenFn } from "@tauri-apps/api/event" import type { UnlistenFn } from "@tauri-apps/api/event"
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow" import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
import { readTextFile } from "@tauri-apps/plugin-fs" import { readTextFile } from "@tauri-apps/plugin-fs"
import { fetch } from "@tauri-apps/plugin-http"
import { debug } from "@tauri-apps/plugin-log" import { debug } from "@tauri-apps/plugin-log"
import { goto } from "$app/navigation" import { goto } from "$app/navigation"
import { RPCChannel, WorkerParentIO } from "kkrpc/browser"
// import { RPCChannel, WorkerParentIO } from "kkrpc/worker"
import { ArrowLeftIcon } from "lucide-svelte" import { ArrowLeftIcon } from "lucide-svelte"
import { onDestroy, onMount } from "svelte" import { onDestroy, onMount } from "svelte"
import * as v from "valibot" import * as v from "valibot"
const { data } = $props() const { data } = $props()
let { loadedExt, scriptPath, extInfoInDB } = $derived(data) let { loadedExt, scriptPath, extInfoInDB } = $derived(data)
let workerAPI: Remote<WorkerExtension> | undefined = undefined let workerAPI: WorkerExtension | undefined = undefined
let unlistenRefreshWorkerExt: UnlistenFn | undefined let unlistenRefreshWorkerExt: UnlistenFn | undefined
let unlistenFileDrop: UnlistenFn | undefined let unlistenFileDrop: UnlistenFn | undefined
let worker: Worker | undefined let worker: Worker | undefined
@ -81,7 +85,15 @@
async render(view: IComponent<ListSchema.List | FormSchema.Form | MarkdownSchema>) { async render(view: IComponent<ListSchema.List | FormSchema.Form | MarkdownSchema>) {
if (view.nodeName === NodeNameEnum.List) { if (view.nodeName === NodeNameEnum.List) {
clearViewContent("list") clearViewContent("list")
const parsedListView = v.parse(ListSchema.List, view) const parsedListViewRes = v.safeParse(ListSchema.List, view)
if (!parsedListViewRes.success) {
toast.error("Invalid List View", {
description: "See console for details"
})
console.error("Fail to parse List View", v.flatten(parsedListViewRes.issues))
return
}
const parsedListView = parsedListViewRes.output
const updateFields = { const updateFields = {
sections: true, sections: true,
items: true, items: true,
@ -203,8 +215,13 @@
serverAPI.app = { serverAPI.app = {
language: () => Promise.resolve("en") language: () => Promise.resolve("en")
} satisfies IApp } satisfies IApp
exposeApiToWorker(worker, serverAPI) const io = new WorkerParentIO(worker)
workerAPI = wrap<WorkerExtension>(worker) const rpc = new RPCChannel<typeof serverAPI, WorkerExtension>(io, {
expose: serverAPI
})
workerAPI = rpc.getAPI()
// exposeApiToWorker(worker, serverAPI)
// workerAPI = wrap<WorkerExtension>(worker)
await workerAPI.load() await workerAPI.load()
} }

View File

@ -21,6 +21,7 @@ import type { PageLoad } from "./$types"
export const load: PageLoad = async ({ url }) => { export const load: PageLoad = async ({ url }) => {
// both query parameter must exist // both query parameter must exist
const extPath = url.searchParams.get("extPath") const extPath = url.searchParams.get("extPath")
const cmdName = url.searchParams.get("cmdName") const cmdName = url.searchParams.get("cmdName")
if (!extPath || !cmdName) { if (!extPath || !cmdName) {
@ -63,6 +64,7 @@ export const load: PageLoad = async ({ url }) => {
if (!(await exists(scriptPath))) { if (!(await exists(scriptPath))) {
sbError(404, `Command script not found at ${scriptPath}`) sbError(404, `Command script not found at ${scriptPath}`)
} }
// const workerScript = await readTextFile(scriptPath) // const workerScript = await readTextFile(scriptPath)
return { return {
extPath: extPath!, extPath: extPath!,

View File

@ -25,5 +25,5 @@
There are 4 options to install an extension in developer mode. Either load it from your local There are 4 options to install an extension in developer mode. Either load it from your local
tarball file, a tarball remote URL, npm package name or load from a remote URL. tarball file, a tarball remote URL, npm package name or load from a remote URL.
</small> </small>
<AddDevExtForm /> <AddDevExtForm />
</main> </main>

2088
deno.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,16 +10,16 @@
"format": "prettier --write \"**/*.{ts,tsx,md,svelte}\"" "format": "prettier --write \"**/*.{ts,tsx,md,svelte}\""
}, },
"devDependencies": { "devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.3.1", "@ianvs/prettier-plugin-sort-imports": "^4.4.0",
"@kksh/api": "workspace:*", "@kksh/api": "workspace:*",
"@kksh/svelte5": "0.1.9", "@kksh/svelte5": "0.1.10",
"prettier": "^3.2.5", "prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.7", "prettier-plugin-svelte": "^3.2.8",
"prettier-plugin-tailwindcss": "^0.6.8", "prettier-plugin-tailwindcss": "^0.6.8",
"svelte": "^5.0.0", "svelte": "^5.2.3",
"svelte-check": "^4.0.0", "svelte-check": "^4.0.9",
"turbo": "^2.2.3", "turbo": "^2.3.0",
"typescript": "5.5.4" "typescript": "5.6.3"
}, },
"packageManager": "pnpm@9.12.3", "packageManager": "pnpm@9.12.3",
"engines": { "engines": {
@ -29,11 +29,11 @@
"@changesets/cli": "^2.27.9", "@changesets/cli": "^2.27.9",
"@iconify/svelte": "^4.0.2", "@iconify/svelte": "^4.0.2",
"@supabase/supabase-js": "^2.46.1", "@supabase/supabase-js": "^2.46.1",
"@tauri-apps/api": "^2.0.3", "@tauri-apps/api": "^2.1.1",
"@tauri-apps/cli": "^2.0.4", "@tauri-apps/cli": "^2.1.0",
"@tauri-apps/plugin-deep-link": "^2.0.0", "@tauri-apps/plugin-deep-link": "^2.0.0",
"@tauri-apps/plugin-dialog": "^2.0.1", "@tauri-apps/plugin-dialog": "^2.0.1",
"@tauri-apps/plugin-fs": "^2.0.1", "@tauri-apps/plugin-fs": "^2.0.2",
"@tauri-apps/plugin-global-shortcut": "^2.0.0", "@tauri-apps/plugin-global-shortcut": "^2.0.0",
"@tauri-apps/plugin-http": "^2.0.1", "@tauri-apps/plugin-http": "^2.0.1",
"@tauri-apps/plugin-log": "^2.0.0", "@tauri-apps/plugin-log": "^2.0.0",
@ -43,8 +43,8 @@
"@tauri-apps/plugin-shell": "^2.0.1", "@tauri-apps/plugin-shell": "^2.0.1",
"@tauri-apps/plugin-store": "^2.1.0", "@tauri-apps/plugin-store": "^2.1.0",
"@tauri-apps/plugin-updater": "^2.0.0", "@tauri-apps/plugin-updater": "^2.0.0",
"@tauri-apps/plugin-upload": "^2.0.0", "@tauri-apps/plugin-upload": "^2.1.0",
"supabase": "^1.207.9", "supabase": "^1.219.2",
"tauri-plugin-network-api": "workspace:*", "tauri-plugin-network-api": "workspace:*",
"tauri-plugin-shellx-api": "^2.0.14", "tauri-plugin-shellx-api": "^2.0.14",
"tauri-plugin-system-info-api": "workspace:*", "tauri-plugin-system-info-api": "workspace:*",

View File

@ -1,7 +1,7 @@
{ {
"$schema": "https://jsr.io/schema/config-file.v1.json", "$schema": "https://jsr.io/schema/config-file.v1.json",
"name": "@kunkun/api", "name": "@kunkun/api",
"version": "0.0.32", "version": "0.0.41",
"license": "MIT", "license": "MIT",
"exports": { "exports": {
".": "./src/index.ts", ".": "./src/index.ts",
@ -17,7 +17,5 @@
"./dev": "./src/dev/index.ts", "./dev": "./src/dev/index.ts",
"./events": "./src/events.ts" "./events": "./src/events.ts"
}, },
"imports": { "imports": {}
"@hk/comlink-stdio": "jsr:@hk/comlink-stdio@^0.1.6"
}
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@kksh/api", "name": "@kksh/api",
"version": "0.0.33", "version": "0.0.41",
"type": "module", "type": "module",
"exports": { "exports": {
".": "./src/index.ts", ".": "./src/index.ts",
@ -36,16 +36,14 @@
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"madge": "^8.0.0", "madge": "^8.0.0",
"typedoc": "^0.26.11", "typedoc": "^0.26.11",
"typescript": "^5.0.0" "typescript": "^5.6.3"
}, },
"dependencies": { "dependencies": {
"@hk/comlink-stdio": "npm:comlink-stdio@^0.1.7", "@tauri-apps/api": "^2.1.1",
"@huakunshen/comlink": "^4.4.1", "@tauri-apps/cli": "^2.1.0",
"@tauri-apps/api": "^2.0.3",
"@tauri-apps/cli": "^2.0.4",
"@tauri-apps/plugin-deep-link": "^2.0.0", "@tauri-apps/plugin-deep-link": "^2.0.0",
"@tauri-apps/plugin-dialog": "^2.0.1", "@tauri-apps/plugin-dialog": "^2.0.1",
"@tauri-apps/plugin-fs": "^2.0.1", "@tauri-apps/plugin-fs": "^2.0.2",
"@tauri-apps/plugin-global-shortcut": "^2.0.0", "@tauri-apps/plugin-global-shortcut": "^2.0.0",
"@tauri-apps/plugin-http": "^2.0.1", "@tauri-apps/plugin-http": "^2.0.1",
"@tauri-apps/plugin-log": "^2.0.0", "@tauri-apps/plugin-log": "^2.0.0",
@ -55,13 +53,13 @@
"@tauri-apps/plugin-shell": "^2.0.1", "@tauri-apps/plugin-shell": "^2.0.1",
"@tauri-apps/plugin-store": "^2.1.0", "@tauri-apps/plugin-store": "^2.1.0",
"@tauri-apps/plugin-updater": "^2.0.0", "@tauri-apps/plugin-updater": "^2.0.0",
"@tauri-apps/plugin-upload": "^2.0.0", "@tauri-apps/plugin-upload": "^2.1.0",
"comlink": "^4.4.1", "kkrpc": "^0.0.12",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",
"semver": "^7.6.3", "semver": "^7.6.3",
"svelte-sonner": "^0.3.28", "svelte-sonner": "^0.3.28",
"tauri-api-adapter": "0.3.8", "tauri-api-adapter": "^0.3.13",
"tauri-plugin-network-api": "2.0.4", "tauri-plugin-network-api": "2.0.4",
"tauri-plugin-shellx-api": "^2.0.14", "tauri-plugin-shellx-api": "^2.0.14",
"tauri-plugin-system-info-api": "2.0.8", "tauri-plugin-system-info-api": "2.0.8",

View File

@ -1,10 +1,10 @@
import { DenoStdio, RPCChannel } from "@hk/comlink-stdio" import { DenoIo, RPCChannel } from "kkrpc"
// deno-lint-ignore no-explicit-any // deno-lint-ignore no-explicit-any
export function expose(api: Record<string, any>) { export function expose(api: Record<string, any>) {
const stdio = new DenoStdio(Deno.stdin.readable, Deno.stdout.writable) const stdio = new DenoIo(Deno.stdin.readable, Deno.stdout.writable)
const channel = new RPCChannel(stdio, api) const channel = new RPCChannel(stdio, { expose: api })
return channel return channel
} }
export { DenoStdio, RPCChannel } from "@hk/comlink-stdio" export { DenoIo, RPCChannel } from "kkrpc"

View File

@ -1,17 +1,16 @@
import { proxy, type Remote } from "@huakunshen/comlink" // import { proxy, type Remote } from "@huakunshen/comlink"
import type { DragDropPayload, DragEnterPayload, DragOverPayload, IEvent } from "../client" import type { DragDropPayload, DragEnterPayload, DragOverPayload, IEvent } from "../client"
// event API listens for events, event callback functions are proxied with comlink, thus I have to provide this constructor function // event API listens for events, event callback functions are proxied with comlink, thus I have to provide this constructor function
export function constructEventAPI(api: Remote<IEvent>): IEvent { export function constructEventAPI(api: IEvent): IEvent {
return { return {
onDragDrop: (callback: (payload: DragDropPayload) => void) => api.onDragDrop(proxy(callback)), onDragDrop: (callback: (payload: DragDropPayload) => void) => api.onDragDrop(callback),
onDragEnter: (callback: (payload: DragEnterPayload) => void) => onDragEnter: (callback: (payload: DragEnterPayload) => void) => api.onDragEnter(callback),
api.onDragEnter(proxy(callback)), onDragLeave: (callback: () => void) => api.onDragLeave(callback),
onDragLeave: (callback: () => void) => api.onDragLeave(proxy(callback)), onDragOver: (callback: (payload: DragOverPayload) => void) => api.onDragOver(callback),
onDragOver: (callback: (payload: DragOverPayload) => void) => api.onDragOver(proxy(callback)), onWindowBlur: (callback: () => void) => api.onWindowBlur(callback),
onWindowBlur: (callback: () => void) => api.onWindowBlur(proxy(callback)), onWindowCloseRequested: (callback: () => void) => api.onWindowCloseRequested(callback),
onWindowCloseRequested: (callback: () => void) => api.onWindowCloseRequested(proxy(callback)), onWindowFocus: (callback: () => void) => api.onWindowFocus(callback)
onWindowFocus: (callback: () => void) => api.onWindowFocus(proxy(callback))
// onWindowThemeChanged: api.onWindowThemeChanged // onWindowThemeChanged: api.onWindowThemeChanged
} }
} }

View File

@ -1,13 +1,10 @@
import type { Remote } from "@huakunshen/comlink" // import type { Remote } from "@huakunshen/comlink"
import type { IOs } from "tauri-api-adapter/client" import type { IOs } from "tauri-api-adapter/client"
import { type IUiIframe } from "../client" import { type IUiIframe } from "../client"
export const KK_DRAG_REGION_ATTR = "data-kunkun-drag-region" export const KK_DRAG_REGION_ATTR = "data-kunkun-drag-region"
export function constructIframeUiAPI(api: { export function constructIframeUiAPI(api: { iframeUi: IUiIframe; os: IOs }): IUiIframe {
iframeUi: Remote<IUiIframe>
os: Remote<IOs>
}): IUiIframe {
return { return {
goBack: api.iframeUi.goBack, goBack: api.iframeUi.goBack,
hideBackButton: api.iframeUi.hideBackButton, hideBackButton: api.iframeUi.hideBackButton,

View File

@ -1,8 +1,8 @@
import type { Remote } from "@huakunshen/comlink" // import type { Remote } from "@huakunshen/comlink"
import { BaseDirectory } from "@tauri-apps/api/path" import { BaseDirectory } from "@tauri-apps/api/path"
import type { IPath } from "../client" import type { IPath } from "../client"
export function constructPathAPI(api: Remote<IPath>): IPath { export function constructPathAPI(api: IPath): IPath {
return { return {
BaseDirectory: BaseDirectory, BaseDirectory: BaseDirectory,
appCacheDir: api.appCacheDir, appCacheDir: api.appCacheDir,

View File

@ -1,7 +1,6 @@
import { type Buffer } from "node:buffer" import { type Buffer } from "node:buffer"
import { RPCChannel, type StdioInterface } from "@hk/comlink-stdio/browser"
import { proxy as comlinkProxy, type Remote } from "@huakunshen/comlink"
import { Channel, invoke } from "@tauri-apps/api/core" import { Channel, invoke } from "@tauri-apps/api/core"
import { RPCChannel, type IoInterface } from "kkrpc/browser"
import { constructShellAPI as constructShellAPI1 } from "tauri-api-adapter/client" import { constructShellAPI as constructShellAPI1 } from "tauri-api-adapter/client"
import { import {
// Child, // Child,
@ -25,8 +24,8 @@ import type { IShellServer } from "../server/server-types.ts"
export class Child { export class Child {
/** The child process `pid`. */ /** The child process `pid`. */
pid: number pid: number
api: Remote<IShellServer> api: IShellServer
constructor(pid: number, api: Remote<IShellServer>) { constructor(pid: number, api: IShellServer) {
this.pid = pid this.pid = pid
this.api = api this.api = api
} }
@ -102,12 +101,12 @@ class BaseShellCommand<O extends IOPayload> extends EventEmitter<CommandEvents>
} }
export class Command<O extends IOPayload> extends BaseShellCommand<O> { export class Command<O extends IOPayload> extends BaseShellCommand<O> {
api: Remote<IShellServer> api: IShellServer
constructor( constructor(
program: string, program: string,
args: string | string[] = [], args: string | string[] = [],
api: Remote<IShellServer>, api: IShellServer,
options?: SpawnOptions options?: SpawnOptions
) { ) {
super(program, args, options) super(program, args, options)
@ -122,27 +121,22 @@ export class Command<O extends IOPayload> extends BaseShellCommand<O> {
} }
return this.api return this.api
.rawSpawn( .rawSpawn(this.program, args, this.options, (evt) => {
this.program, switch (evt.event) {
args, case "Error":
this.options, this.emit("error", evt.payload)
comlinkProxy((evt) => { break
switch (evt.event) { case "Terminated":
case "Error": this.emit("close", evt.payload)
this.emit("error", evt.payload) break
break case "Stdout":
case "Terminated": this.stdout.emit("data", evt.payload as O)
this.emit("close", evt.payload) break
break case "Stderr":
case "Stdout": this.stderr.emit("data", evt.payload as O)
this.stdout.emit("data", evt.payload as O) break
break }
case "Stderr": })
this.stderr.emit("data", evt.payload as O)
break
}
})
)
.then(async (pid) => { .then(async (pid) => {
await this.api.recordSpawnedProcess(pid) // report spawned process to main process for process auto cleanup await this.api.recordSpawnedProcess(pid) // report spawned process to main process for process auto cleanup
return new Child(pid, this.api) return new Child(pid, this.api)
@ -161,14 +155,9 @@ export class Command<O extends IOPayload> extends BaseShellCommand<O> {
export class DenoCommand<O extends IOPayload> extends BaseShellCommand<O> { export class DenoCommand<O extends IOPayload> extends BaseShellCommand<O> {
config: DenoRunConfig config: DenoRunConfig
scriptPath: string scriptPath: string
api: Remote<IShellServer> api: IShellServer
constructor( constructor(scriptPath: string, args: string[], config: DenoRunConfig, api: IShellServer) {
scriptPath: string,
args: string[],
config: DenoRunConfig,
api: Remote<IShellServer>
) {
super("deno", args) super("deno", args)
this.config = config this.config = config
this.scriptPath = scriptPath this.scriptPath = scriptPath
@ -181,27 +170,22 @@ export class DenoCommand<O extends IOPayload> extends BaseShellCommand<O> {
spawn(): Promise<Child> { spawn(): Promise<Child> {
return this.api return this.api
.denoRawSpawn( .denoRawSpawn(this.scriptPath, this.config, this.args, (evt) => {
this.scriptPath, switch (evt.event) {
this.config, case "Error":
this.args, this.emit("error", evt.payload)
comlinkProxy((evt) => { break
switch (evt.event) { case "Terminated":
case "Error": this.emit("close", evt.payload)
this.emit("error", evt.payload) break
break case "Stdout":
case "Terminated": this.stdout.emit("data", evt.payload as O)
this.emit("close", evt.payload) break
break case "Stderr":
case "Stdout": this.stderr.emit("data", evt.payload as O)
this.stdout.emit("data", evt.payload as O) break
break }
case "Stderr": })
this.stderr.emit("data", evt.payload as O)
break
}
})
)
.then(async (pid) => { .then(async (pid) => {
await this.api.recordSpawnedProcess(pid) await this.api.recordSpawnedProcess(pid)
return new Child(pid, this.api) return new Child(pid, this.api)
@ -253,7 +237,8 @@ export type IShell = {
whereIsCommand: (command: string) => Promise<string | null> whereIsCommand: (command: string) => Promise<string | null>
} }
export class TauriShellStdio implements StdioInterface { export class TauriShellStdio implements IoInterface {
name = "tauri-shell-stdio"
constructor( constructor(
private readStream: EventEmitter<OutputEvents<IOPayload>>, // stdout of child process private readStream: EventEmitter<OutputEvents<IOPayload>>, // stdout of child process
private childProcess: Child private childProcess: Child
@ -271,7 +256,7 @@ export class TauriShellStdio implements StdioInterface {
} }
} }
export function constructShellAPI(api: Remote<IShellServer>): IShell { export function constructShellAPI(api: IShellServer): IShell {
// const originalAPI = constructShellAPI1(api) // const originalAPI = constructShellAPI1(api)
function createCommand(program: string, args: string | string[] = [], options?: SpawnOptions) { function createCommand(program: string, args: string | string[] = [], options?: SpawnOptions) {
return new Command<string>(program, args, api, options) return new Command<string>(program, args, api, options)
@ -294,7 +279,7 @@ export function constructShellAPI(api: Remote<IShellServer>): IShell {
const denoCmd = createDenoCommand(scriptPath, args, config) const denoCmd = createDenoCommand(scriptPath, args, config)
const denoProcess = await denoCmd.spawn() const denoProcess = await denoCmd.spawn()
const stdio = new TauriShellStdio(denoCmd.stdout, denoProcess) const stdio = new TauriShellStdio(denoCmd.stdout, denoProcess)
const stdioRPC = new RPCChannel<LocalAPI, RemoteAPI>(stdio, localAPIImplementation) const stdioRPC = new RPCChannel<LocalAPI, RemoteAPI>(stdio, { expose: localAPIImplementation })
return { return {
rpcChannel: stdioRPC, rpcChannel: stdioRPC,
process: denoProcess, process: denoProcess,
@ -389,4 +374,4 @@ export function constructShellAPI(api: Remote<IShellServer>): IShell {
} }
} }
export { RPCChannel } from "@hk/comlink-stdio/browser" export { RPCChannel } from "kkrpc/browser"

View File

@ -1,17 +1,17 @@
import { proxy as comlinkProxy, type Remote } from "@huakunshen/comlink" // import { proxy as comlinkProxy, type Remote } from "@huakunshen/comlink"
import type { GeneralToastParams, IToast } from "../client" import type { GeneralToastParams, IToast } from "../client"
export function constructToastAPI(api: Remote<IToast>) { export function constructToastAPI(api: IToast) {
return { return {
message: (message: string, options?: GeneralToastParams, action?: () => void) => message: (message: string, options?: GeneralToastParams, action?: () => void) =>
api.message(message, options, action ? comlinkProxy(action) : undefined), api.message(message, options, action ? action : undefined),
info: (message: string, options?: GeneralToastParams, action?: () => void) => info: (message: string, options?: GeneralToastParams, action?: () => void) =>
api.info(message, options, action ? comlinkProxy(action) : undefined), api.info(message, options, action ? action : undefined),
success: (message: string, options?: GeneralToastParams, action?: () => void) => success: (message: string, options?: GeneralToastParams, action?: () => void) =>
api.success(message, options, action ? comlinkProxy(action) : undefined), api.success(message, options, action ? action : undefined),
warning: (message: string, options?: GeneralToastParams, action?: () => void) => warning: (message: string, options?: GeneralToastParams, action?: () => void) =>
api.warning(message, options, action ? comlinkProxy(action) : undefined), api.warning(message, options, action ? action : undefined),
error: (message: string, options?: GeneralToastParams, action?: () => void) => error: (message: string, options?: GeneralToastParams, action?: () => void) =>
api.error(message, options, action ? comlinkProxy(action) : undefined) api.error(message, options, action ? action : undefined)
} }
} }

View File

@ -1,4 +1,5 @@
import { windowEndpoint, wrap, type Remote } from "@huakunshen/comlink" // import { windowEndpoint, wrap, type Remote } from "@huakunshen/comlink"
import { IframeChildIO, RPCChannel, type DestroyableIoInterface } from "kkrpc/browser"
import type { import type {
IClipboard, IClipboard,
IDialog, IDialog,
@ -39,7 +40,7 @@ import type {
import type { IShellServer } from "../server/server-types" import type { IShellServer } from "../server/server-types"
export { type IUiIframe } from "../client" export { type IUiIframe } from "../client"
export { expose, wrap } from "@huakunshen/comlink" // export { expose, wrap } from "@huakunshen/comlink"
// export { type IDbServer } from "../server/db" // export { type IDbServer } from "../server/db"
export { type IUiIframeServer2, type IUiIframeServer1 } from "../server/server-types" export { type IUiIframeServer2, type IUiIframeServer1 } from "../server/server-types"
@ -48,35 +49,39 @@ export { type IUiIframeServer2, type IUiIframeServer1 } from "../server/server-t
* There may be server API changes for them, but the client API can be inherited * There may be server API changes for them, but the client API can be inherited
*/ */
type API = { type API = {
db: Remote<IDb> // for kunkun db: IDb // for kunkun
system: Remote<ISystem> // for kunkun system: ISystem // for kunkun
open: Remote<IOpen> // for kunkun open: IOpen // for kunkun
clipboard: Remote<IClipboard> // inherit from tauri-api-adapter clipboard: IClipboard // inherit from tauri-api-adapter
dialog: Remote<IDialog> // inherit from tauri-api-adapter dialog: IDialog // inherit from tauri-api-adapter
fetch: Remote<IFetchInternal> // inherit from tauri-api-adapter fetch: IFetchInternal // inherit from tauri-api-adapter
event: Remote<IEvent> // for kunkun, override tauri-api-adapter's event API, expose only specified event, disallow, emit and listen event: IEvent // for kunkun, override tauri-api-adapter's event API, expose only specified event, disallow, emit and listen
fs: Remote<IFs> // customized for kunkun, add file search API on top of tauri-api-adapter's fs API fs: IFs // customized for kunkun, add file search API on top of tauri-api-adapter's fs API
log: Remote<ILogger> // inherit from tauri-api-adapter log: ILogger // inherit from tauri-api-adapter
notification: Remote<INotification> // inherit from tauri-api-adapter notification: INotification // inherit from tauri-api-adapter
toast: Remote<IToast> // for kunkun toast: IToast // for kunkun
os: Remote<IOs> // inherit from tauri-api-adapter os: IOs // inherit from tauri-api-adapter
path: Remote<IPath> // inherit from tauri-api-adapter path: IPath // inherit from tauri-api-adapter
shell: Remote<IShellServer> // inherit from tauri-api-adapter shell: IShellServer // inherit from tauri-api-adapter
updownload: IUpdownload // inherit from tauri-api-adapter updownload: IUpdownload // inherit from tauri-api-adapter
sysInfo: Remote<ISystemInfo> // inherit from tauri-api-adapter sysInfo: ISystemInfo // inherit from tauri-api-adapter
network: Remote<INetwork> // inherit from tauri-api-adapter network: INetwork // inherit from tauri-api-adapter
iframeUi: Remote<IUiIframe> // for kunkun iframeUi: IUiIframe // for kunkun
utils: IUtils // for kunkun utils: IUtils // for kunkun
security: ISecurity // for kunkun security: ISecurity // for kunkun
app: IApp app: IApp
} }
const _api = wrap(windowEndpoint(globalThis.parent)) as unknown as API // export const api = wrap(windowEndpoint(globalThis.parent)) as unknown as API
export const event = constructEventAPI(_api.event) // this is different from event api from tauri-api-adapter const io = new IframeChildIO()
export const fetch = constructFetchAPI(_api.fetch) const rpc = new RPCChannel<{}, API, DestroyableIoInterface>(io, {})
export const path = constructPathAPI(_api.path) export const api = rpc.getAPI()
export const shell = constructShellAPI(_api.shell)
export const updownload = constructUpdownloadAPI(_api.updownload) export const event = constructEventAPI(api.event) // this is different from event api from tauri-api-adapter
export const ui = constructIframeUiAPI(_api) export const fetch = constructFetchAPI(api.fetch)
export const path = constructPathAPI(api.path)
export const shell = constructShellAPI(api.shell)
export const updownload = constructUpdownloadAPI(api.updownload)
export const ui = constructIframeUiAPI(api)
export const { export const {
db, db,
os, os,
@ -92,5 +97,5 @@ export const {
utils, utils,
open, open,
app app
} = _api } = api
export { Child, RPCChannel } from "../api/shell" export { Child, RPCChannel } from "../api/shell"

View File

@ -19,8 +19,8 @@
export { constructJarvisServerAPIWithPermissions } from "./server" export { constructJarvisServerAPIWithPermissions } from "./server"
// export { type IUiWorkerServer, type IUiIframeServer } from "./server/ui" // export { type IUiWorkerServer, type IUiIframeServer } from "./server/ui"
export * from "./client" // all client types export * from "./client" // all client types
export { expose, wrap } from "@huakunshen/comlink" // export { expose, wrap } from "@huakunshen/comlink"
export { getWorkerApiClient, exposeApiToWorker, exposeApiToWindow } from "tauri-api-adapter" // export { getWorkerApiClient, exposeApiToWorker, exposeApiToWindow } from "tauri-api-adapter"
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* API Interfaces */ /* API Interfaces */

View File

@ -255,6 +255,8 @@ export async function verifyDenoCmdPermission(
// now we have command requested permissions, we need to compare with permissions defined in manifest // now we have command requested permissions, we need to compare with permissions defined in manifest
/* ----------------------- Check Allow All Permissions ---------------------- */ /* ----------------------- Check Allow All Permissions ---------------------- */
console.log("config: ", config)
console.log("allowAllEnv: ", allowAllEnv)
if (config.allowAllEnv && !allowAllEnv) { if (config.allowAllEnv && !allowAllEnv) {
throw new Error("allowAllEnv is not allowed") throw new Error("allowAllEnv is not allowed")

View File

@ -1,6 +1,6 @@
import { macSecurity } from "@kksh/api/commands"
import { Command, open } from "tauri-plugin-shellx-api" import { Command, open } from "tauri-plugin-shellx-api"
import * as v from "valibot" import * as v from "valibot"
import { macSecurity } from "../../commands"
import { SecurityPermissionMap, type SecurityPermission } from "../../permissions" import { SecurityPermissionMap, type SecurityPermission } from "../../permissions"
import { checkPermission } from "../../utils/permission-check" import { checkPermission } from "../../utils/permission-check"
import { MacSecurityOptions, type ISecurity } from "../client" import { MacSecurityOptions, type ISecurity } from "../client"

View File

@ -1,7 +1,9 @@
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* API */ /* API */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
import { wrap, type Endpoint, type Remote } from "@huakunshen/comlink" // import { wrap, type Endpoint, type Remote } from "@huakunshen/comlink"
// import { RPCChannel, WorkerChildIO, type DestroyableIoInterface } from "kkrpc/browser"
import { RPCChannel, WorkerChildIO, type DestroyableIoInterface } from "kkrpc/browser"
import type { import type {
IClipboard, IClipboard,
IDialog, IDialog,
@ -41,8 +43,9 @@ import type {
IUtils IUtils
} from "../client" } from "../client"
import type { IShellServer } from "../server/server-types" import type { IShellServer } from "../server/server-types"
import type { WorkerExtension } from "./ext"
export { expose, wrap } from "@huakunshen/comlink" // export { expose, wrap } from "@huakunshen/comlink"
export { WorkerExtension } from "./ext" export { WorkerExtension } from "./ext"
export type { IDb } from "../client" export type { IDb } from "../client"
/** /**
@ -50,36 +53,44 @@ export type { IDb } from "../client"
* There may be server API changes for them, but the client API can be inherited * There may be server API changes for them, but the client API can be inherited
*/ */
type API = { type API = {
db: Remote<IDb> // for kunkun db: IDb // for kunkun
system: Remote<ISystem> // for kunkun system: ISystem // for kunkun
open: Remote<IOpen> // for kunkun open: IOpen // for kunkun
clipboard: Remote<IClipboard> // inherit from tauri-api-adapter clipboard: IClipboard // inherit from tauri-api-adapter
dialog: Remote<IDialog> // inherit from tauri-api-adapter dialog: IDialog // inherit from tauri-api-adapter
fetch: Remote<IFetchInternal> // inherit from tauri-api-adapter fetch: IFetchInternal // inherit from tauri-api-adapter
event: Remote<IEvent> // for kunkun, override tauri-api-adapter's event API, expose only specified event, disallow, emit and listen event: IEvent // for kunkun, override tauri-api-adapter's event API, expose only specified event, disallow, emit and listen
fs: Remote<IFs> // customized for kunkun, add file search API on top of tauri-api-adapter's fs API fs: IFs // customized for kunkun, add file search API on top of tauri-api-adapter's fs API
log: Remote<ILogger> // inherit from tauri-api-adapter log: ILogger // inherit from tauri-api-adapter
notification: Remote<INotification> // inherit from tauri-api-adapter notification: INotification // inherit from tauri-api-adapter
toast: Remote<IToast> // for kunkun toast: IToast // for kunkun
os: Remote<IOs> // inherit from tauri-api-adapter os: IOs // inherit from tauri-api-adapter
path: Remote<IPath> // inherit from tauri-api-adapter path: IPath // inherit from tauri-api-adapter
shell: Remote<IShellServer> // inherit from tauri-api-adapter shell: IShellServer // inherit from tauri-api-adapter
updownload: IUpdownload // inherit from tauri-api-adapter updownload: IUpdownload // inherit from tauri-api-adapter
sysInfo: Remote<ISystemInfo> // inherit from tauri-api-adapter sysInfo: ISystemInfo // inherit from tauri-api-adapter
network: Remote<INetwork> // inherit from tauri-api-adapter network: INetwork // inherit from tauri-api-adapter
workerUi: Remote<IUiWorker> // for kunkun workerUi: IUiWorker // for kunkun
security: ISecurity // for kunkun security: ISecurity // for kunkun
utils: IUtils // for kunkun utils: IUtils // for kunkun
app: IApp app: IApp
} }
const _api = wrap(globalThis as Endpoint) as unknown as API // const _api = wrap(globalThis as Endpoint) as unknown as API
export const event = constructEventAPI(_api.event) // this is different from event api from tauri-api-adapter const io = new WorkerChildIO()
export const fetch = constructFetchAPI(_api.fetch) const rpc = new RPCChannel<{}, API, DestroyableIoInterface>(io, {})
export const path = constructPathAPI(_api.path) export const api = rpc.getAPI()
export const shell = constructShellAPI(_api.shell)
export const toast = constructToastAPI(_api.toast) export function expose(api: WorkerExtension) {
export const updownload = constructUpdownloadAPI(_api.updownload) rpc.expose(api)
}
export const event = constructEventAPI(api.event) // this is different from event api from tauri-api-adapter
export const fetch = constructFetchAPI(api.fetch)
export const path = constructPathAPI(api.path)
export const shell = constructShellAPI(api.shell)
export const toast = constructToastAPI(api.toast)
export const updownload = constructUpdownloadAPI(api.updownload)
export const { export const {
db, db,
os, os,
@ -96,7 +107,7 @@ export const {
app, app,
security, security,
workerUi: ui workerUi: ui
} = _api } = api
export { Child, RPCChannel, Command, DenoCommand } from "../api/shell" export { Child, RPCChannel, Command, DenoCommand } from "../api/shell"
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* UI Component Schema */ /* UI Component Schema */
@ -112,3 +123,14 @@ export { Icon } from "./components/icon"
export { IconEnum, IconType, IconNode } from "../../models/icon" export { IconEnum, IconType, IconNode } from "../../models/icon"
export * as schema from "./schema" export * as schema from "./schema"
export { NodeName, NodeNameEnum, FormNodeName, FormNodeNameEnum } from "../../models/constants" export { NodeName, NodeNameEnum, FormNodeName, FormNodeNameEnum } from "../../models/constants"
/* -------------------------------------------------------------------------- */
/* Expose */
/* -------------------------------------------------------------------------- */
// export function expose(api: WorkerExtension) {
// const io = new WorkerChildIO()
// const rpc = new RPCChannel(io, {
// expose: api
// })
// return rpc.getAPI()
// }

View File

@ -8,12 +8,16 @@ export const breakingChangesVersionCheckpoints = [
{ {
version: "0.0.17", version: "0.0.17",
changelog: "New Custom UI loading method, remove base url config requirement." changelog: "New Custom UI loading method, remove base url config requirement."
},
{
version: "0.0.34",
changelog: "Replace comlink with kkrpc, extensions using comlink won't work anymore."
} }
] ]
const checkpointVersions = breakingChangesVersionCheckpoints.map((c) => c.version) const checkpointVersions = breakingChangesVersionCheckpoints.map((c) => c.version)
const sortedCheckpointVersions = sort(checkpointVersions) const sortedCheckpointVersions = sort(checkpointVersions)
export const version = "0.0.33" export const version = "0.0.41"
export function isVersionBetween(v: string, start: string, end: string) { export function isVersionBetween(v: string, start: string, end: string) {
const vCleaned = clean(v) const vCleaned = clean(v)

View File

@ -1,14 +1,14 @@
{ {
"name": "@kksh/eslint-config", "name": "@kksh/eslint-config",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/eslint-plugin": "^8.15.0",
"@typescript-eslint/parser": "^7.1.0", "@typescript-eslint/parser": "^8.15.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-config-turbo": "^2.0.0", "eslint-config-turbo": "^2.3.0",
"eslint-plugin-svelte": "^2.35.1" "eslint-plugin-svelte": "^2.46.0"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
} }
} }

View File

@ -12,7 +12,6 @@ async function build() {
minify: true, minify: true,
target: "browser" target: "browser"
}) })
console.log(output)
await refreshTemplateWorkerExtension() await refreshTemplateWorkerExtension()
} catch (error) { } catch (error) {
console.error(error) console.error(error)

View File

@ -1,6 +1,6 @@
{ {
"imports": { "imports": {
"@hk/photographer-toolbox": "jsr:@hk/photographer-toolbox@^0.1.3", "@hk/photographer-toolbox": "jsr:@hk/photographer-toolbox@^0.1.8",
"@kunkun/api": "jsr:@kunkun/api@^0.0.27" "@kunkun/api": "jsr:@kunkun/api@^0.0.38"
} }
} }

View File

@ -1,32 +1,17 @@
{ {
"version": "4", "version": "4",
"specifiers": { "specifiers": {
"jsr:@hk/comlink-stdio@~0.1.6": "0.1.7", "jsr:@hk/photographer-toolbox@~0.1.8": "0.1.8",
"jsr:@hk/photographer-toolbox@~0.1.3": "0.1.3", "jsr:@kunkun/api@^0.0.38": "0.0.38",
"jsr:@kunkun/api@^0.0.27": "0.0.27",
"jsr:@valibot/valibot@~0.42.1": "0.42.1", "jsr:@valibot/valibot@~0.42.1": "0.42.1",
"npm:@huakunshen/comlink@^4.4.1": "4.4.1",
"npm:@kksh/api@^0.0.27": "0.0.27_rollup@4.25.0",
"npm:@tauri-apps/api@2.0.0-rc.3": "2.0.0-rc.3",
"npm:@tauri-apps/plugin-fs@2.0.0-rc.1": "2.0.0-rc.1",
"npm:@tauri-apps/plugin-os@2.0.0-rc.0": "2.0.0-rc.0",
"npm:exiftool-vendored@28.5.0": "28.5.0", "npm:exiftool-vendored@28.5.0": "28.5.0",
"npm:fluent-ffmpeg@2.1.3": "2.1.3", "npm:fluent-ffmpeg@2.1.3": "2.1.3",
"npm:lodash@^4.17.21": "4.17.21", "npm:kkrpc@^0.0.10": "0.0.10_typescript@5.6.3",
"npm:minimatch@^10.0.1": "10.0.1", "npm:sharp@0.33.5": "0.33.5"
"npm:semver@^7.6.3": "7.6.3",
"npm:sharp@0.33.5": "0.33.5",
"npm:tauri-api-adapter@0.3.8": "0.3.8_typescript@5.6.3_rollup@4.25.0",
"npm:tauri-plugin-shellx-api@^2.0.10": "2.0.11",
"npm:valibot@0.40": "0.40.0_typescript@5.6.3",
"npm:vue-sonner@^1.1.3": "1.2.5"
}, },
"jsr": { "jsr": {
"@hk/comlink-stdio@0.1.7": { "@hk/photographer-toolbox@0.1.8": {
"integrity": "17fb2c039b282fe79fe119e14a9e4b4f4bf952f2cd5361f0a560c15fdb59afba" "integrity": "6cf1162f1eef019164ec158d9114fe705c22cc11a4866113a3237b77d515050b",
},
"@hk/photographer-toolbox@0.1.3": {
"integrity": "818e914f8a09b2d48057637a126a09d512ccaf266ef270b84177c647adda6196",
"dependencies": [ "dependencies": [
"jsr:@valibot/valibot", "jsr:@valibot/valibot",
"npm:exiftool-vendored", "npm:exiftool-vendored",
@ -34,22 +19,10 @@
"npm:sharp" "npm:sharp"
] ]
}, },
"@kunkun/api@0.0.27": { "@kunkun/api@0.0.38": {
"integrity": "0556926321b08406edffbb85d087a23d2d96f95dda5c95b2c432c15b62638b12", "integrity": "22f0263e02956c1327fc54214770ef3799e7dcf3b51fa82d6769c6c93b8de91e",
"dependencies": [ "dependencies": [
"jsr:@hk/comlink-stdio", "npm:kkrpc"
"npm:@huakunshen/comlink",
"npm:@kksh/api",
"npm:@tauri-apps/api",
"npm:@tauri-apps/plugin-fs",
"npm:@tauri-apps/plugin-os",
"npm:lodash",
"npm:minimatch",
"npm:semver",
"npm:tauri-api-adapter",
"npm:tauri-plugin-shellx-api",
"npm:valibot",
"npm:vue-sonner"
] ]
}, },
"@valibot/valibot@0.42.1": { "@valibot/valibot@0.42.1": {
@ -63,9 +36,6 @@
"tslib" "tslib"
] ]
}, },
"@huakunshen/comlink@4.4.1": {
"integrity": "sha512-rxWFQ0NEc28z/r6Ixy0ZllNaRqvkqbmuT3oTwzVnwVyDFdIkqoicrwr1Z718ZQbWoVFBdmqSjm93N273ludHMA=="
},
"@img/sharp-darwin-arm64@0.33.5": { "@img/sharp-darwin-arm64@0.33.5": {
"integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
"dependencies": [ "dependencies": [
@ -150,322 +120,18 @@
"@img/sharp-win32-x64@0.33.5": { "@img/sharp-win32-x64@0.33.5": {
"integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==" "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="
}, },
"@isaacs/cliui@8.0.2": {
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dependencies": [
"string-width@5.1.2",
"string-width-cjs@npm:string-width@4.2.3",
"strip-ansi@7.1.0",
"strip-ansi-cjs@npm:strip-ansi@6.0.1",
"wrap-ansi@8.1.0",
"wrap-ansi-cjs@npm:wrap-ansi@7.0.0"
]
},
"@kksh/api@0.0.27_rollup@4.25.0": {
"integrity": "sha512-M+wnJNETTp/WjEi/XOQIql+Xx4AXkyhc590DQ91HOHP9WXiRVZ9j1dnIQjmw9SZoOQimDDAFLdEsAlYhxvi8dw==",
"dependencies": [
"@hk/comlink-stdio@npm:comlink-stdio@0.1.7_typescript@5.6.3",
"@huakunshen/comlink",
"@rollup/plugin-typescript",
"@tauri-apps/api@2.0.0-rc.3",
"@tauri-apps/plugin-dialog",
"@tauri-apps/plugin-fs",
"@tauri-apps/plugin-global-shortcut",
"@tauri-apps/plugin-http@2.0.0-rc.1",
"@tauri-apps/plugin-log@2.0.0-rc.0",
"@tauri-apps/plugin-notification@2.0.0-rc.0",
"@tauri-apps/plugin-os",
"@tauri-apps/plugin-store",
"@tauri-apps/plugin-updater",
"@tauri-apps/plugin-upload@2.0.0-rc.0",
"comlink",
"lodash",
"minimatch@10.0.1",
"rollup",
"semver",
"tauri-api-adapter",
"tauri-plugin-network-api@2.0.3",
"tauri-plugin-shellx-api",
"tauri-plugin-system-info-api@2.0.6",
"valibot",
"vue-sonner"
]
},
"@nodelib/fs.scandir@2.1.5": {
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dependencies": [
"@nodelib/fs.stat",
"run-parallel"
]
},
"@nodelib/fs.stat@2.0.5": {
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="
},
"@nodelib/fs.walk@1.2.8": {
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dependencies": [
"@nodelib/fs.scandir",
"fastq"
]
},
"@photostructure/tz-lookup@11.0.0": { "@photostructure/tz-lookup@11.0.0": {
"integrity": "sha512-QMV5/dWtY/MdVPXZs/EApqzyhnqDq1keYEqpS+Xj2uidyaqw2Nk/fWcsszdruIXjdqp1VoWNzsgrO6bUHU1mFw==" "integrity": "sha512-QMV5/dWtY/MdVPXZs/EApqzyhnqDq1keYEqpS+Xj2uidyaqw2Nk/fWcsszdruIXjdqp1VoWNzsgrO6bUHU1mFw=="
}, },
"@pkgjs/parseargs@0.11.0": {
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="
},
"@rollup/plugin-alias@5.1.1_rollup@4.25.0": {
"integrity": "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==",
"dependencies": [
"rollup"
]
},
"@rollup/plugin-typescript@11.1.6_rollup@4.25.0_typescript@5.6.3": {
"integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==",
"dependencies": [
"@rollup/pluginutils",
"resolve",
"rollup",
"typescript"
]
},
"@rollup/pluginutils@5.1.3_rollup@4.25.0": {
"integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==",
"dependencies": [
"@types/estree",
"estree-walker",
"picomatch@4.0.2",
"rollup"
]
},
"@rollup/rollup-android-arm-eabi@4.25.0": {
"integrity": "sha512-CC/ZqFZwlAIbU1wUPisHyV/XRc5RydFrNLtgl3dGYskdwPZdt4HERtKm50a/+DtTlKeCq9IXFEWR+P6blwjqBA=="
},
"@rollup/rollup-android-arm64@4.25.0": {
"integrity": "sha512-/Y76tmLGUJqVBXXCfVS8Q8FJqYGhgH4wl4qTA24E9v/IJM0XvJCGQVSW1QZ4J+VURO9h8YCa28sTFacZXwK7Rg=="
},
"@rollup/rollup-darwin-arm64@4.25.0": {
"integrity": "sha512-YVT6L3UrKTlC0FpCZd0MGA7NVdp7YNaEqkENbWQ7AOVOqd/7VzyHpgIpc1mIaxRAo1ZsJRH45fq8j4N63I/vvg=="
},
"@rollup/rollup-darwin-x64@4.25.0": {
"integrity": "sha512-ZRL+gexs3+ZmmWmGKEU43Bdn67kWnMeWXLFhcVv5Un8FQcx38yulHBA7XR2+KQdYIOtD0yZDWBCudmfj6lQJoA=="
},
"@rollup/rollup-freebsd-arm64@4.25.0": {
"integrity": "sha512-xpEIXhiP27EAylEpreCozozsxWQ2TJbOLSivGfXhU4G1TBVEYtUPi2pOZBnvGXHyOdLAUUhPnJzH3ah5cqF01g=="
},
"@rollup/rollup-freebsd-x64@4.25.0": {
"integrity": "sha512-sC5FsmZGlJv5dOcURrsnIK7ngc3Kirnx3as2XU9uER+zjfyqIjdcMVgzy4cOawhsssqzoAX19qmxgJ8a14Qrqw=="
},
"@rollup/rollup-linux-arm-gnueabihf@4.25.0": {
"integrity": "sha512-uD/dbLSs1BEPzg564TpRAQ/YvTnCds2XxyOndAO8nJhaQcqQGFgv/DAVko/ZHap3boCvxnzYMa3mTkV/B/3SWA=="
},
"@rollup/rollup-linux-arm-musleabihf@4.25.0": {
"integrity": "sha512-ZVt/XkrDlQWegDWrwyC3l0OfAF7yeJUF4fq5RMS07YM72BlSfn2fQQ6lPyBNjt+YbczMguPiJoCfaQC2dnflpQ=="
},
"@rollup/rollup-linux-arm64-gnu@4.25.0": {
"integrity": "sha512-qboZ+T0gHAW2kkSDPHxu7quaFaaBlynODXpBVnPxUgvWYaE84xgCKAPEYE+fSMd3Zv5PyFZR+L0tCdYCMAtG0A=="
},
"@rollup/rollup-linux-arm64-musl@4.25.0": {
"integrity": "sha512-ndWTSEmAaKr88dBuogGH2NZaxe7u2rDoArsejNslugHZ+r44NfWiwjzizVS1nUOHo+n1Z6qV3X60rqE/HlISgw=="
},
"@rollup/rollup-linux-powerpc64le-gnu@4.25.0": {
"integrity": "sha512-BVSQvVa2v5hKwJSy6X7W1fjDex6yZnNKy3Kx1JGimccHft6HV0THTwNtC2zawtNXKUu+S5CjXslilYdKBAadzA=="
},
"@rollup/rollup-linux-riscv64-gnu@4.25.0": {
"integrity": "sha512-G4hTREQrIdeV0PE2JruzI+vXdRnaK1pg64hemHq2v5fhv8C7WjVaeXc9P5i4Q5UC06d/L+zA0mszYIKl+wY8oA=="
},
"@rollup/rollup-linux-s390x-gnu@4.25.0": {
"integrity": "sha512-9T/w0kQ+upxdkFL9zPVB6zy9vWW1deA3g8IauJxojN4bnz5FwSsUAD034KpXIVX5j5p/rn6XqumBMxfRkcHapQ=="
},
"@rollup/rollup-linux-x64-gnu@4.25.0": {
"integrity": "sha512-ThcnU0EcMDn+J4B9LD++OgBYxZusuA7iemIIiz5yzEcFg04VZFzdFjuwPdlURmYPZw+fgVrFzj4CA64jSTG4Ig=="
},
"@rollup/rollup-linux-x64-musl@4.25.0": {
"integrity": "sha512-zx71aY2oQxGxAT1JShfhNG79PnjYhMC6voAjzpu/xmMjDnKNf6Nl/xv7YaB/9SIa9jDYf8RBPWEnjcdlhlv1rQ=="
},
"@rollup/rollup-win32-arm64-msvc@4.25.0": {
"integrity": "sha512-JT8tcjNocMs4CylWY/CxVLnv8e1lE7ff1fi6kbGocWwxDq9pj30IJ28Peb+Y8yiPNSF28oad42ApJB8oUkwGww=="
},
"@rollup/rollup-win32-ia32-msvc@4.25.0": {
"integrity": "sha512-dRLjLsO3dNOfSN6tjyVlG+Msm4IiZnGkuZ7G5NmpzwF9oOc582FZG05+UdfTbz5Jd4buK/wMb6UeHFhG18+OEg=="
},
"@rollup/rollup-win32-x64-msvc@4.25.0": {
"integrity": "sha512-/RqrIFtLB926frMhZD0a5oDa4eFIbyNEwLLloMTEjmqfwZWXywwVVOVmwTsuyhC9HKkVEZcOOi+KV4U9wmOdlg=="
},
"@tauri-apps/api@2.0.0-rc.3": {
"integrity": "sha512-k1erUfnoOFJwL5VNFZz0BQZ2agNstG7CNOjwpdWMl1vOaVuSn4DhJtXB0Deh9lZaaDlfrykKOyZs9c3XXpMi5Q=="
},
"@tauri-apps/api@2.0.1": {
"integrity": "sha512-eoQWT+Tq1qSwQpHV+nw1eNYe5B/nm1PoRjQCRiEOS12I1b+X4PUcREfXVX8dPcBT6GrzWGDtaecY0+1p0Rfqlw=="
},
"@tauri-apps/api@2.1.1": {
"integrity": "sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A=="
},
"@tauri-apps/plugin-dialog@2.0.1": {
"integrity": "sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-fs@2.0.0-rc.1": {
"integrity": "sha512-r6N5dqBNXy9YAK9XbiEqAq3ZKBIN+TWevE7ZFmSRdvdSB1urrLweYu4wxycY2kDaDPzSeeOIJhCmqdNrFT9OSA==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-global-shortcut@2.0.0-rc.0": {
"integrity": "sha512-rcefV4AG+vnbTtGc07hDn4Uj8u//NpuqHVg1CShACyiCS0q2sZrDVC3qPN3RGhzQyeIOPq4bY1kQRHODffKXZA==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-http@2.0.0-rc.1": {
"integrity": "sha512-j4WdTEKx0CFa6u8ubke0mo75pCrnu6XtrFtvjsh+zjuNYgMG/l0+A1woWXHm73f2Levskhs+KbKcLQA/nr8k2w==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-http@2.0.1": {
"integrity": "sha512-j6IA3pVBybSCwPpsihpX4z8bs6PluuGtr06ahL/xy4D8HunNBTmRmadJrFOQi0gOAbaig4MkQ15nzNLBLy8R1A==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-log@2.0.0": {
"integrity": "sha512-C+NII9vzswqnOQE8k7oRtnaw0z5TZsMmnirRhXkCKDEhQQH9841Us/PC1WHtGiAaJ8za1A1JB2xXndEq/47X/w==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-log@2.0.0-rc.0": {
"integrity": "sha512-ztKfzUcq03dtr08vBu+xcwIEPusP6mCpuLAt6kpXEwG+HvYsC8e1/KFFokn3xvfwD+oBJ3UTL1h4kdM30GAqGw==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-notification@2.0.0": {
"integrity": "sha512-6qEDYJS7mgXZWLXA0EFL+DVCJh8sJlzSoyw6B50pxhLPVFjc5Vr5DVzl5W3mUHaYhod5wsC984eQnlCCGqxYDA==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-notification@2.0.0-rc.0": {
"integrity": "sha512-0qsT/kvxQ6Ky4g6eQ4SUiHXzM4szTVc6thjz9vnGPYaApLoZrCJ9GdG+vEqeB+cT2dvE+wmxUFETh3ZXYVw8UA==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-os@2.0.0-rc.0": {
"integrity": "sha512-OWAl8mooKnGykSD4iog8WRqcnOSx0gGmTJBlEExHdFeIuOHg0Ezvd+WiVLhT9LBg7go3ibNWRWpe/ZG7YEp4Vw==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-shell@2.0.1": {
"integrity": "sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-store@2.0.0-rc.0": {
"integrity": "sha512-KqiEzq6EdRwxrl0/FwyNLwumDBM91xTchdu2a8vfkNub30GuP9z7RskP9ifVRI1gbxfa5TUDi0hKFk/SP7TANQ==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-updater@2.0.0-rc.0": {
"integrity": "sha512-EKajf/sBpFif0cwXhTo3BmNvTZ2t2DDLRyhA8FFKugZNoOeqU97bHhPT5DIqMUPRE1tyDk9o7sXm8dKf7oz+EA==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-upload@2.0.0": {
"integrity": "sha512-MdBZn4RCVmFDjuC2rbpFGjAZAbePkxrc9T35+SKJJgfXbXYw0YOzvUTsDiU7F3NzDWepO+6EbVN3Upzi9rqt/A==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@tauri-apps/plugin-upload@2.0.0-rc.0": {
"integrity": "sha512-wlRzL4syShxMlvuM7YfeG3Mcj4Ii2UkuQ8HaBh3YnBl0bPoKuVOGP/PaJ3FF84z1pgMfA5Pb1eSG34hlMCYLsw==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"@types/estree@1.0.6": {
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
},
"@types/luxon@3.4.2": { "@types/luxon@3.4.2": {
"integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==" "integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA=="
}, },
"ansi-regex@5.0.1": {
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-regex@6.1.0": {
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="
},
"ansi-styles@4.3.0": {
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": [
"color-convert"
]
},
"ansi-styles@6.2.1": {
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="
},
"anymatch@3.1.3": {
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dependencies": [
"normalize-path",
"picomatch@2.3.1"
]
},
"array-union@2.1.0": {
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="
},
"async@0.2.10": { "async@0.2.10": {
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
}, },
"balanced-match@1.0.2": {
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"batch-cluster@13.0.0": { "batch-cluster@13.0.0": {
"integrity": "sha512-EreW0Vi8TwovhYUHBXXRA5tthuU2ynGsZFlboyMJHCCUXYa2AjgwnE3ubBOJs2xJLcuXFJbi6c/8pH5+FVj8Og==" "integrity": "sha512-EreW0Vi8TwovhYUHBXXRA5tthuU2ynGsZFlboyMJHCCUXYa2AjgwnE3ubBOJs2xJLcuXFJbi6c/8pH5+FVj8Og=="
}, },
"binary-extensions@2.3.0": {
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="
},
"brace-expansion@1.1.11": {
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dependencies": [
"balanced-match",
"concat-map"
]
},
"brace-expansion@2.0.1": {
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dependencies": [
"balanced-match"
]
},
"braces@3.0.3": {
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dependencies": [
"fill-range"
]
},
"chokidar@3.6.0": {
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dependencies": [
"anymatch",
"braces",
"fsevents",
"glob-parent",
"is-binary-path",
"is-glob",
"normalize-path",
"readdirp"
]
},
"color-convert@2.0.1": { "color-convert@2.0.1": {
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": [ "dependencies": [
@ -489,50 +155,9 @@
"color-string" "color-string"
] ]
}, },
"comlink-stdio@0.1.7_typescript@5.6.3": {
"integrity": "sha512-LTTyZfEq3KuDKnNSFDsDbJzNh5F6h+MTd13D6K7yRt9zvnP2nxZ5DgyaAaw2H87vQUzJ1T93Se1o3FHk9Ch7cw==",
"dependencies": [
"typescript"
]
},
"comlink@4.4.2": {
"integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g=="
},
"commander@9.5.0": {
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="
},
"concat-map@0.0.1": {
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"cross-spawn@7.0.5": {
"integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==",
"dependencies": [
"path-key",
"shebang-command",
"which@2.0.2"
]
},
"detect-libc@2.0.3": { "detect-libc@2.0.3": {
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==" "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw=="
}, },
"dir-glob@3.0.1": {
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dependencies": [
"path-type"
]
},
"eastasianwidth@0.2.0": {
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
"emoji-regex@8.0.0": {
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"emoji-regex@9.2.2": {
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"estree-walker@2.0.2": {
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
"exiftool-vendored.exe@12.96.0": { "exiftool-vendored.exe@12.96.0": {
"integrity": "sha512-pKPN9F/Evw2yyO5/+ml3spbXIqejzOxyF7jEnj8tLU2JPSmIlziPUZ75XIhcPbilX86jVKmuiso7FUDicOg8pQ==" "integrity": "sha512-pKPN9F/Evw2yyO5/+ml3spbXIqejzOxyF7jEnj8tLU2JPSmIlziPUZ75XIhcPbilX86jVKmuiso7FUDicOg8pQ=="
}, },
@ -551,310 +176,32 @@
"luxon" "luxon"
] ]
}, },
"fast-glob@3.3.2": {
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
"dependencies": [
"@nodelib/fs.stat",
"@nodelib/fs.walk",
"glob-parent",
"merge2",
"micromatch"
]
},
"fastq@1.17.1": {
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
"dependencies": [
"reusify"
]
},
"fill-range@7.1.1": {
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dependencies": [
"to-regex-range"
]
},
"fluent-ffmpeg@2.1.3": { "fluent-ffmpeg@2.1.3": {
"integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==", "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==",
"dependencies": [ "dependencies": [
"async", "async",
"which@1.3.1" "which"
]
},
"foreground-child@3.3.0": {
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
"dependencies": [
"cross-spawn",
"signal-exit"
]
},
"fs.realpath@1.0.0": {
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"fsevents@2.3.3": {
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="
},
"function-bind@1.1.2": {
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"glob-parent@5.1.2": {
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dependencies": [
"is-glob"
]
},
"glob@10.4.5": {
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dependencies": [
"foreground-child",
"jackspeak",
"minimatch@9.0.5",
"minipass",
"package-json-from-dist",
"path-scurry"
]
},
"glob@7.2.3": {
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dependencies": [
"fs.realpath",
"inflight",
"inherits",
"minimatch@3.1.2",
"once",
"path-is-absolute"
]
},
"globby@11.1.0": {
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
"dependencies": [
"array-union",
"dir-glob",
"fast-glob",
"ignore",
"merge2",
"slash"
]
},
"hasown@2.0.2": {
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dependencies": [
"function-bind"
] ]
}, },
"he@1.2.0": { "he@1.2.0": {
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
}, },
"ignore@5.3.2": {
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="
},
"inflight@1.0.6": {
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dependencies": [
"once",
"wrappy"
]
},
"inherits@2.0.4": {
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"interpret@1.4.0": {
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
},
"is-arrayish@0.3.2": { "is-arrayish@0.3.2": {
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
}, },
"is-binary-path@2.1.0": {
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dependencies": [
"binary-extensions"
]
},
"is-core-module@2.15.1": {
"integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
"dependencies": [
"hasown"
]
},
"is-extglob@2.1.1": {
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
},
"is-fullwidth-code-point@3.0.0": {
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"is-glob@4.0.3": {
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dependencies": [
"is-extglob"
]
},
"is-number@7.0.0": {
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
},
"isexe@2.0.0": { "isexe@2.0.0": {
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
}, },
"jackspeak@3.4.3": { "kkrpc@0.0.10_typescript@5.6.3": {
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "integrity": "sha512-lkQKVnN9f6JrS4ybKbGkV4mtuGhWYLTnaWx60ysytEap+sP5jcTbAuJlSrY6JqlwaohiS0X3ZbvJ2rAXYRdTng==",
"dependencies": [ "dependencies": [
"@isaacs/cliui", "typescript",
"@pkgjs/parseargs" "ws"
] ]
}, },
"lodash@4.17.21": {
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lru-cache@10.4.3": {
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
},
"luxon@3.5.0": { "luxon@3.5.0": {
"integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==" "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ=="
}, },
"merge2@1.4.1": {
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
},
"micromatch@4.0.8": {
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dependencies": [
"braces",
"picomatch@2.3.1"
]
},
"minimatch@10.0.1": {
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
"dependencies": [
"brace-expansion@2.0.1"
]
},
"minimatch@3.1.2": {
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": [
"brace-expansion@1.1.11"
]
},
"minimatch@9.0.5": {
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dependencies": [
"brace-expansion@2.0.1"
]
},
"minimist@1.2.8": {
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
},
"minipass@7.1.2": {
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
},
"mylas@2.1.13": {
"integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg=="
},
"normalize-path@3.0.0": {
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
},
"once@1.4.0": {
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": [
"wrappy"
]
},
"package-json-from-dist@1.0.1": {
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
},
"path-is-absolute@1.0.1": {
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
},
"path-key@3.1.1": {
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
"path-parse@1.0.7": {
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"path-scurry@1.11.1": {
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dependencies": [
"lru-cache",
"minipass"
]
},
"path-type@4.0.0": {
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
},
"picomatch@2.3.1": {
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
},
"picomatch@4.0.2": {
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="
},
"plimit-lit@1.6.1": {
"integrity": "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==",
"dependencies": [
"queue-lit"
]
},
"queue-lit@1.5.2": {
"integrity": "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw=="
},
"queue-microtask@1.2.3": {
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
},
"readdirp@3.6.0": {
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dependencies": [
"picomatch@2.3.1"
]
},
"rechoir@0.6.2": {
"integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
"dependencies": [
"resolve"
]
},
"resolve@1.22.8": {
"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
"dependencies": [
"is-core-module",
"path-parse",
"supports-preserve-symlinks-flag"
]
},
"reusify@1.0.4": {
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
},
"rimraf@5.0.10": {
"integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
"dependencies": [
"glob@10.4.5"
]
},
"rollup@4.25.0": {
"integrity": "sha512-uVbClXmR6wvx5R1M3Od4utyLUxrmOcEm3pAtMphn73Apq19PDtHpgZoEvqH2YnnaNUuvKmg2DgRd2Sqv+odyqg==",
"dependencies": [
"@rollup/rollup-android-arm-eabi",
"@rollup/rollup-android-arm64",
"@rollup/rollup-darwin-arm64",
"@rollup/rollup-darwin-x64",
"@rollup/rollup-freebsd-arm64",
"@rollup/rollup-freebsd-x64",
"@rollup/rollup-linux-arm-gnueabihf",
"@rollup/rollup-linux-arm-musleabihf",
"@rollup/rollup-linux-arm64-gnu",
"@rollup/rollup-linux-arm64-musl",
"@rollup/rollup-linux-powerpc64le-gnu",
"@rollup/rollup-linux-riscv64-gnu",
"@rollup/rollup-linux-s390x-gnu",
"@rollup/rollup-linux-x64-gnu",
"@rollup/rollup-linux-x64-musl",
"@rollup/rollup-win32-arm64-msvc",
"@rollup/rollup-win32-ia32-msvc",
"@rollup/rollup-win32-x64-msvc",
"@types/estree",
"fsevents"
]
},
"run-parallel@1.2.0": {
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dependencies": [
"queue-microtask"
]
},
"semver@7.6.3": { "semver@7.6.3": {
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="
}, },
@ -885,209 +232,32 @@
"semver" "semver"
] ]
}, },
"shebang-command@2.0.0": {
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dependencies": [
"shebang-regex"
]
},
"shebang-regex@3.0.0": {
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
},
"shelljs@0.8.5": {
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
"dependencies": [
"glob@7.2.3",
"interpret",
"rechoir"
]
},
"shx@0.3.4": {
"integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==",
"dependencies": [
"minimist",
"shelljs"
]
},
"signal-exit@4.1.0": {
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
},
"simple-swizzle@0.2.2": { "simple-swizzle@0.2.2": {
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
"dependencies": [ "dependencies": [
"is-arrayish" "is-arrayish"
] ]
}, },
"slash@3.0.0": {
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
},
"string-width@4.2.3": {
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": [
"emoji-regex@8.0.0",
"is-fullwidth-code-point",
"strip-ansi@6.0.1"
]
},
"string-width@5.1.2": {
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dependencies": [
"eastasianwidth",
"emoji-regex@9.2.2",
"strip-ansi@7.1.0"
]
},
"strip-ansi@6.0.1": {
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dependencies": [
"ansi-regex@5.0.1"
]
},
"strip-ansi@7.1.0": {
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dependencies": [
"ansi-regex@6.1.0"
]
},
"supports-preserve-symlinks-flag@1.0.0": {
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
},
"tauri-api-adapter@0.3.8_typescript@5.6.3_rollup@4.25.0": {
"integrity": "sha512-HX6VMCWLzMIhTVuEaKbgLbQXR3YpIrzAgZGPv0Nge7zIn352G5vA/QJxQ9rlpFO4Y8S+Ro7VXR7DpVPMisTHaQ==",
"dependencies": [
"@huakunshen/comlink",
"@rollup/plugin-alias",
"@rollup/plugin-typescript",
"@tauri-apps/api@2.1.1",
"@tauri-apps/plugin-dialog",
"@tauri-apps/plugin-fs",
"@tauri-apps/plugin-http@2.0.1",
"@tauri-apps/plugin-log@2.0.0",
"@tauri-apps/plugin-notification@2.0.0",
"@tauri-apps/plugin-os",
"@tauri-apps/plugin-shell",
"@tauri-apps/plugin-upload@2.0.0",
"rimraf",
"rollup",
"shx",
"tauri-plugin-clipboard-api",
"tauri-plugin-network-api@2.0.4_typescript@5.6.3",
"tauri-plugin-shellx-api",
"tauri-plugin-system-info-api@2.0.8_typescript@5.6.3",
"tsc-alias",
"typescript",
"valibot"
]
},
"tauri-plugin-clipboard-api@2.1.11_typescript@5.6.3": {
"integrity": "sha512-VNkGaVPPfRoHg7/rJBcWqsvLvn4/kNEOOlzqwyI9Qdf6g54B3mc31GLZdnq/HWtX0vZskw3J8b/EF9YkASDCBQ==",
"dependencies": [
"@tauri-apps/api@2.0.1",
"valibot"
]
},
"tauri-plugin-network-api@2.0.3": {
"integrity": "sha512-aj/o315shIntam+vxVlgRJE8NnKcf0d93CQBK6zOb3Ia4V4HM+kYdFxg8Ji5jM5Yay8nq1HEJaqNIOIv7R1NpA==",
"dependencies": [
"@tauri-apps/api@2.1.1",
"valibot"
]
},
"tauri-plugin-network-api@2.0.4_typescript@5.6.3": {
"integrity": "sha512-CJWF2g+uQifcIlE/AXUnezVjjbyY0FDBxoz4P6BmjNRR/qubpNMfdUnKLqdjX98o5MIXGW+UnyZTfbJo998dFw==",
"dependencies": [
"@tauri-apps/api@2.1.1",
"valibot"
]
},
"tauri-plugin-shellx-api@2.0.11": {
"integrity": "sha512-+FKIP1FBHdIQ6tASohww3MOf/8CDvYMYpPg9glO59h8TGVxTNP2ofiOEKLYk8M/o2H4tP7mxxca11QpDAT2LXw==",
"dependencies": [
"@tauri-apps/api@2.1.1"
]
},
"tauri-plugin-system-info-api@2.0.6": {
"integrity": "sha512-7q8ieMK1bweMiLDbIWNNX3Dy7KNNwiB+WNEqKQutl0TKEGAb+efpy2SAzVLGu+i9tjDagCai8fZNuLLIpoQ9TA==",
"dependencies": [
"@tauri-apps/api@2.1.1",
"valibot"
]
},
"tauri-plugin-system-info-api@2.0.8_typescript@5.6.3": {
"integrity": "sha512-EFdLXNGp6Zu9SNsZCkU+55A8027OnrVw/TQrd0oJHgfZzs4qvm1iMmSvyid4MLftt33iZDhjCzxYijaaOxeKSg==",
"dependencies": [
"@tauri-apps/api@2.1.1",
"valibot"
]
},
"to-regex-range@5.0.1": {
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dependencies": [
"is-number"
]
},
"tsc-alias@1.8.10": {
"integrity": "sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==",
"dependencies": [
"chokidar",
"commander",
"globby",
"mylas",
"normalize-path",
"plimit-lit"
]
},
"tslib@2.8.1": { "tslib@2.8.1": {
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
}, },
"typescript@5.6.3": { "typescript@5.6.3": {
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==" "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="
}, },
"valibot@0.40.0_typescript@5.6.3": {
"integrity": "sha512-XHKnaVtwHqxPwnGOsLrwka9CEaL7yNeLNp707OKv/bmT29GnPVdl6PxBOZ6BW7hF66/6QT6iVbOlnW7qVPmoKw==",
"dependencies": [
"typescript"
]
},
"vue-sonner@1.2.5": {
"integrity": "sha512-dAFCdq2cYxEwvW4gHuJhySCXklmxOWzjl5QwkNL9IIdkqyvSkdu+YnAbnJBdIAH/zo1bhXTuGG+m0Two4AX/KA=="
},
"which@1.3.1": { "which@1.3.1": {
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dependencies": [ "dependencies": [
"isexe" "isexe"
] ]
}, },
"which@2.0.2": { "ws@8.18.0": {
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="
"dependencies": [
"isexe"
]
},
"wrap-ansi@7.0.0": {
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dependencies": [
"ansi-styles@4.3.0",
"string-width@4.2.3",
"strip-ansi@6.0.1"
]
},
"wrap-ansi@8.1.0": {
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dependencies": [
"ansi-styles@6.2.1",
"string-width@5.1.2",
"strip-ansi@7.1.0"
]
},
"wrappy@1.0.2": {
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
} }
}, },
"workspace": { "workspace": {
"dependencies": [ "dependencies": [
"jsr:@hk/photographer-toolbox@~0.1.3", "jsr:@hk/photographer-toolbox@~0.1.8",
"jsr:@kunkun/api@^0.0.27" "jsr:@kunkun/api@^0.0.38"
] ]
} }
} }

View File

@ -5,4 +5,4 @@ import { image } from "@hk/photographer-toolbox"
// "/Users/hacker/Dev/projects/photographer-lib-deno/data/DJI_20241002175820_0054_D.JPG" // "/Users/hacker/Dev/projects/photographer-lib-deno/data/DJI_20241002175820_0054_D.JPG"
// ) // )
// .then(console.log) // .then(console.log)
console.log(image); console.log(image)

View File

@ -3,18 +3,38 @@ import { expose } from "@kunkun/api/runtime/deno"
// import { image } from "jsr:@hk/photographer-toolbox@^0.1.3" // import { image } from "jsr:@hk/photographer-toolbox@^0.1.3"
const files = [
"/Users/hacker/Dev/projects/photographer-lib-deno/data/DSC03635.JPG"
// "/Users/hacker/Dev/projects/photographer-lib-deno/data/IMG_3181.HEIC",
// "/Users/hacker/Dev/projects/photographer-lib-deno/data/DJI_20241002175820_0054_D.JPG",
// "/Users/hacker/Dev/projects/photographer-lib-deno/data/DJI_20241002175651_0051_D.DNG",
// "/Users/hacker/Dev/projects/photographer-lib-deno/data/DSC03635.ARW"
]
export interface API { export interface API {
add(a: number, b: number): Promise<number> add(a: number, b: number): Promise<number>
subtract(a: number, b: number): Promise<number> subtract(a: number, b: number): Promise<number>
// readImageMetadata: (path: string) => Promise<any> readImageMetadata: (path: string) => Promise<any>
batchReadImageMetadata: (paths: string[]) => Promise<any[]>
// readImageMetadata: typeof image.readImageMetadata // readImageMetadata: typeof image.readImageMetadata
} }
// Define your API methods // Define your API methods
export const apiMethods: API = { export const apiMethods: API = {
add: async (a: number, b: number) => a + b, add: async (a: number, b: number) => a + b,
subtract: async (a: number, b: number) => a - b subtract: async (a: number, b: number) => a - b,
// readImageMetadata: (path: string) => Promise.resolve(`path + ${path}`) readImageMetadata: async (path: string) => {
console.error("readImageMetadata", path.trim())
const metadata = await image.readImageMetadata(path.trim())
console.error("metadata", metadata)
return metadata
},
batchReadImageMetadata: async (paths: string[]) => {
console.error("batchReadImageMetadata", paths)
const metadata = await image.batchReadImageMetadata(paths)
// console.error("metadata", metadata)
return metadata
}
// readImageMetadata: image.readImageMetadata // readImageMetadata: image.readImageMetadata
} }
expose(apiMethods) expose(apiMethods)

View File

@ -12,12 +12,10 @@
"fetch:all", "fetch:all",
"shell:kill", "shell:kill",
"security:mac:all", "security:mac:all",
"clipboard:read-all",
{ {
"permission": "shell:deno:spawn", "permission": "shell:deno:spawn",
"allow": [ "allow": [
{
"path": "$EXTENSION/deno-src/deno-script.ts"
},
{ {
"path": "$EXTENSION/deno-src/rpc.ts", "path": "$EXTENSION/deno-src/rpc.ts",
"env": "*", "env": "*",
@ -89,7 +87,6 @@
"build": "bun build.ts" "build": "bun build.ts"
}, },
"dependencies": { "dependencies": {
"@hk/comlink-stdio": "npm:@jsr/hk__comlink-stdio@^0.1.6",
"@kksh/api": "workspace:*", "@kksh/api": "workspace:*",
"@kunkun/api": "npm:@jsr/kunkun__api@^0.0.13" "@kunkun/api": "npm:@jsr/kunkun__api@^0.0.13"
}, },

View File

@ -1,8 +1,8 @@
import type { RPCChannel } from "@hk/comlink-stdio/browser"
import { import {
Action, Action,
app, app,
Child, Child,
clipboard,
expose, expose,
Form, Form,
fs, fs,
@ -32,43 +32,29 @@ const allItems: List.Item[] = itemsTitle.map(
}) })
) )
const files = [
"/Users/hacker/Dev/projects/photographer-lib-deno/data/DSC03635.JPG",
"/Users/hacker/Dev/projects/photographer-lib-deno/data/IMG_3181.HEIC",
"/Users/hacker/Dev/projects/photographer-lib-deno/data/DJI_20241002175820_0054_D.JPG",
"/Users/hacker/Dev/projects/photographer-lib-deno/data/DJI_20241002175651_0051_D.DNG",
"/Users/hacker/Dev/projects/photographer-lib-deno/data/DSC03635.ARW"
]
class ExtensionTemplate extends WorkerExtension { class ExtensionTemplate extends WorkerExtension {
async onBeforeGoBack() {
console.log("onBeforeGoBack")
// console.log(`Try killing pid: ${this.apiProcess?.pid}`)
// await this.apiProcess?.kill()
// console.log("apiProcess killed")
}
async onFormSubmit(value: Record<string, any>): Promise<void> {
console.log("Form submitted", value)
}
async onEnterPressedOnSearchBar(): Promise<void> {
console.log("Enter pressed on search bar")
}
async load() { async load() {
// console.log("Check screen capture permission:", await security.mac.checkScreenCapturePermission())
// await security.mac.revealSecurityPane("AllFiles")
// console.log(await security.mac.verifyFingerprint())
ui.setSearchBarPlaceholder("Search for items")
ui.showLoadingBar(true)
setTimeout(() => {
ui.showLoadingBar(false)
}, 2000)
const { rpcChannel, process, command } = await shell.createDenoRpcChannel< const { rpcChannel, process, command } = await shell.createDenoRpcChannel<
{}, {},
{ {
add(a: number, b: number): Promise<number> add(a: number, b: number): Promise<number>
subtract(a: number, b: number): Promise<number> subtract(a: number, b: number): Promise<number>
// readImageMetadata(path: string): Promise<any> readImageMetadata(path: string): Promise<any>
batchReadImageMetadata: (paths: string[]) => Promise<any[]>
} }
>( >(
"$EXTENSION/deno-src/rpc.ts", "$EXTENSION/deno-src/rpc.ts",
[], [],
{ {
allowEnv: ["npm_package_config_libvips"], // allowEnv: ["npm_package_config_libvips"],
// allowAllEnv: true, allowAllEnv: true,
// allowFfi: ["*sharp-darwin-arm64.node"], // allowFfi: ["*sharp-darwin-arm64.node"],
allowAllFfi: true, allowAllFfi: true,
allowAllRead: true, allowAllRead: true,
@ -78,126 +64,196 @@ class ExtensionTemplate extends WorkerExtension {
}, },
{} {}
) )
// const child = new Child(process.pid) const api = rpcChannel.getAPI()
command.stdout.on("data", (data) => { const metadata = await api.batchReadImageMetadata(files)
console.log("stdout", data.toString()) console.log(metadata)
})
command.stderr.on("data", (data) => {
console.log("stderr", data.toString())
})
const api = rpcChannel.getApi()
await api.add(1, 2).then(console.log)
await api.subtract(1, 2).then(console.log)
await process.kill()
const extPath = await path.extensionDir()
// console.log("Extension path:", extPath)
const tagList = new List.ItemDetailMetadataTagList({
title: "Tag List Title",
tags: [
new List.ItemDetailMetadataTagListItem({
text: "red",
color: "#ff0000"
}),
new List.ItemDetailMetadataTagListItem({
text: "yellow",
color: "#ffff00"
})
]
})
const list = new List.List({
items: allItems,
defaultAction: "Top Default Action",
detail: new List.ItemDetail({
children: [
new List.ItemDetailMetadata([
new List.ItemDetailMetadataLabel({
title: "Label Title",
text: "Label Text"
}),
new List.ItemDetailMetadataLabel({
title: "Label Title",
text: "Label Text",
icon: new Icon({
type: IconType.enum.Iconify,
value: "mingcute:appstore-fill"
})
}),
new List.ItemDetailMetadataSeparator(),
new List.ItemDetailMetadataLabel({
title: "Label Title",
text: "Label Text"
}),
new List.ItemDetailMetadataLink({
title: "Link Title",
text: "Link Text",
url: "https://github.com/huakunshen"
}),
new List.ItemDetailMetadataLabel({
title: "Label Title",
text: "Label Text"
}),
tagList
]),
new Markdown(`
# Hello World
<img src="https://github.com/huakunshen.png" />
<img src="https://github.com/huakunshen.png" />
<img src="https://github.com/huakunshen.png" />
`)
],
width: 50
}),
actions: new Action.ActionPanel({
items: [
new Action.Action({
title: "Action 1",
value: "action 1",
icon: new Icon({ type: IconType.enum.Iconify, value: "material-symbols:add-reaction" })
}),
new Action.Action({ title: "Action 2", value: "action 2" }),
new Action.Action({ title: "Action 3", value: "action 3" }),
new Action.Action({ title: "Action 4", value: "action 4" })
]
})
})
return ui.render(list)
}
async onSearchTermChange(term: string): Promise<void> {
return ui.render(
new List.List({
// items: allItems.filter((item) => item.title.toLowerCase().includes(term.toLowerCase())),
inherits: ["items", "sections"],
defaultAction: "Top Default Action",
detail: new List.ItemDetail({
children: [
new List.ItemDetailMetadata([
new List.ItemDetailMetadataLabel({
title: "Label Title",
text: "Label Text"
})
])
// new Markdown(`
// ## Search results for "${term}"
// <img src="https://github.com/huakunshen.png" />
// <img src="https://github.com/huakunshen.png" />
// <img src="https://github.com/huakunshen.png" />
// `)
],
width: term.length > 3 ? 70 : 30
})
})
)
}
async onListItemSelected(value: string): Promise<void> {
console.log("Item selected:", value)
}
async onActionSelected(value: string): Promise<void> {
console.log("Action selected:", value)
} }
} }
// class ExtensionTemplate extends WorkerExtension {
// async onBeforeGoBack() {
// console.log("onBeforeGoBack")
// // console.log(`Try killing pid: ${this.apiProcess?.pid}`)
// // await this.apiProcess?.kill()
// // console.log("apiProcess killed")
// }
// async onFormSubmit(value: Record<string, any>): Promise<void> {
// console.log("Form submitted", value)
// }
// async onEnterPressedOnSearchBar(): Promise<void> {
// console.log("Enter pressed on search bar")
// }
// async load() {
// clipboard.readText().then((text) => {
// console.log("Clipboard text:", text)
// })
// // console.log("Check screen capture permission:", await security.mac.checkScreenCapturePermission())
// // await security.mac.revealSecurityPane("AllFiles")
// // console.log(await security.mac.verifyFingerprint())
// ui.setSearchBarPlaceholder("Search for items")
// ui.showLoadingBar(true)
// setTimeout(() => {
// ui.showLoadingBar(false)
// }, 2000)
// const { rpcChannel, process, command } = await shell.createDenoRpcChannel<
// {},
// {
// add(a: number, b: number): Promise<number>
// subtract(a: number, b: number): Promise<number>
// readImageMetadata(path: string): Promise<any>
// batchReadImageMetadata: (paths: string[]) => Promise<any[]>
// }
// >(
// "$EXTENSION/deno-src/rpc.ts",
// [],
// {
// // allowEnv: ["npm_package_config_libvips"],
// allowAllEnv: true,
// // allowFfi: ["*sharp-darwin-arm64.node"],
// allowAllFfi: true,
// allowAllRead: true,
// allowAllSys: true,
// // allowRun: ["*exiftool"]
// allowAllRun: true
// },
// {}
// )
// // const child = new Child(process.pid)
// command.stdout.on("data", (data) => {
// console.log("stdout", data.toString())
// })
// command.stderr.on("data", (data) => {
// console.log("stderr", data.toString())
// })
// const api = rpcChannel.getAPI()
// await api
// .batchReadImageMetadata(files)
// .then((metadata) => {
// console.log("metadata", metadata)
// })
// .catch(console.error)
// // await api
// // .readImageMetadata("/Users/hacker/Pictures/3D-Image/pics/IMG_0767.jpeg")
// // .then((data) => {
// // console.log("metadata", data)
// // })
// // .catch((err) => {
// // console.error("error", err)
// // })
// // await api.add(1, 2).then(console.log)
// // await api.subtract(1, 2).then(console.log)
// await process.kill()
// const extPath = await path.extensionDir()
// // console.log("Extension path:", extPath)
// const tagList = new List.ItemDetailMetadataTagList({
// title: "Tag List Title",
// tags: [
// new List.ItemDetailMetadataTagListItem({
// text: "red",
// color: "#ff0000"
// }),
// new List.ItemDetailMetadataTagListItem({
// text: "yellow",
// color: "#ffff00"
// })
// ]
// })
// const list = new List.List({
// items: allItems,
// defaultAction: "Top Default Action",
// detail: new List.ItemDetail({
// children: [
// new List.ItemDetailMetadata([
// new List.ItemDetailMetadataLabel({
// title: "Label Title",
// text: "Label Text"
// }),
// new List.ItemDetailMetadataLabel({
// title: "Label Title",
// text: "Label Text",
// icon: new Icon({
// type: IconType.enum.Iconify,
// value: "mingcute:appstore-fill"
// })
// }),
// new List.ItemDetailMetadataSeparator(),
// new List.ItemDetailMetadataLabel({
// title: "Label Title",
// text: "Label Text"
// }),
// new List.ItemDetailMetadataLink({
// title: "Link Title",
// text: "Link Text",
// url: "https://github.com/huakunshen"
// }),
// new List.ItemDetailMetadataLabel({
// title: "Label Title",
// text: "Label Text"
// }),
// tagList
// ]),
// new Markdown(`
// # Hello World
// <img src="https://github.com/huakunshen.png" />
// <img src="https://github.com/huakunshen.png" />
// <img src="https://github.com/huakunshen.png" />
// `)
// ],
// width: 50
// }),
// actions: new Action.ActionPanel({
// items: [
// new Action.Action({
// title: "Action 1",
// value: "action 1",
// icon: new Icon({ type: IconType.enum.Iconify, value: "material-symbols:add-reaction" })
// }),
// new Action.Action({ title: "Action 2", value: "action 2" }),
// new Action.Action({ title: "Action 3", value: "action 3" }),
// new Action.Action({ title: "Action 4", value: "action 4" })
// ]
// })
// })
// return ui.render(list)
// }
// async onSearchTermChange(term: string): Promise<void> {
// return ui.render(
// new List.List({
// // items: allItems.filter((item) => item.title.toLowerCase().includes(term.toLowerCase())),
// inherits: ["items", "sections"],
// defaultAction: "Top Default Action",
// detail: new List.ItemDetail({
// children: [
// new List.ItemDetailMetadata([
// new List.ItemDetailMetadataLabel({
// title: "Label Title",
// text: "Label Text"
// })
// ])
// // new Markdown(`
// // ## Search results for "${term}"
// // <img src="https://github.com/huakunshen.png" />
// // <img src="https://github.com/huakunshen.png" />
// // <img src="https://github.com/huakunshen.png" />
// // `)
// ],
// width: term.length > 3 ? 70 : 30
// })
// })
// )
// }
// async onListItemSelected(value: string): Promise<void> {
// console.log("Item selected:", value)
// }
// async onActionSelected(value: string): Promise<void> {
// console.log("Action selected:", value)
// }
// }
expose(new ExtensionTemplate()) expose(new ExtensionTemplate())

View File

@ -1,35 +1,29 @@
{ {
"$schema": "./node_modules/@kksh/api/dist/schema.json", "$schema": "https://schema.kunkun.sh",
"name": "template-ext-sveltekit", "name": "ext-sveltekit-exp",
"version": "0.0.3", "version": "0.0.3",
"private": true, "private": true,
"kunkun": { "kunkun": {
"name": "TODO: Change Display Name", "name": "TODO: Change Display Name",
"shortDescription": "A Custom UI template for sveltekit", "shortDescription": "A Custom UI template for sveltekit",
"longDescription": "A Custom UI template for sveltekit", "longDescription": "A Custom UI template for sveltekit",
"identifier": "template-ext-sveltekit", "identifier": "ext-sveltekit-exp",
"icon": { "icon": {
"type": "iconify", "type": "iconify",
"value": "logos:svelte-icon" "value": "carbon:debug"
}, },
"demoImages": [], "demoImages": [],
"permissions": [ "permissions": [
"clipboard:read-text", "clipboard:read-text",
"notification:all" "notification:all",
"dialog:all"
], ],
"customUiCmds": [ "customUiCmds": [
{ {
"main": "/", "main": "/",
"dist": "build", "dist": "build",
"devMain": "http://localhost:5173", "devMain": "http://localhost:5173",
"name": "Sveltekit Template Home Page", "name": "Custom UI Command Playground",
"cmds": []
},
{
"main": "about",
"dist": "build",
"devMain": "http://localhost:5173/about",
"name": "Sveltekit Template About Page",
"cmds": [] "cmds": []
} }
], ],

View File

@ -1,7 +1,7 @@
import { type ClassValue, clsx } from "clsx"; import { type ClassValue, clsx } from 'clsx';
import { twMerge } from "tailwind-merge"; import { twMerge } from 'tailwind-merge';
import { cubicOut } from "svelte/easing"; import { cubicOut } from 'svelte/easing';
import type { TransitionConfig } from "svelte/transition"; import type { TransitionConfig } from 'svelte/transition';
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)); return twMerge(clsx(inputs));
@ -19,13 +19,9 @@ export const flyAndScale = (
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 } params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
): TransitionConfig => { ): TransitionConfig => {
const style = getComputedStyle(node); const style = getComputedStyle(node);
const transform = style.transform === "none" ? "" : style.transform; const transform = style.transform === 'none' ? '' : style.transform;
const scaleConversion = ( const scaleConversion = (valueA: number, scaleA: [number, number], scaleB: [number, number]) => {
valueA: number,
scaleA: [number, number],
scaleB: [number, number]
) => {
const [minA, maxA] = scaleA; const [minA, maxA] = scaleA;
const [minB, maxB] = scaleB; const [minB, maxB] = scaleB;
@ -35,13 +31,11 @@ export const flyAndScale = (
return valueB; return valueB;
}; };
const styleToString = ( const styleToString = (style: Record<string, number | string | undefined>): string => {
style: Record<string, number | string | undefined>
): string => {
return Object.keys(style).reduce((str, key) => { return Object.keys(style).reduce((str, key) => {
if (style[key] === undefined) return str; if (style[key] === undefined) return str;
return str + `${key}:${style[key]};`; return str + `${key}:${style[key]};`;
}, ""); }, '');
}; };
return { return {
@ -59,4 +53,4 @@ export const flyAndScale = (
}, },
easing: cubicOut easing: cubicOut
}; };
}; };

View File

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { base } from '$app/paths'; import { base } from '$app/paths';
import { clipboard, notification, ui, toast } from '@kksh/api/ui/iframe'; import { clipboard, notification, ui, toast, dialog } from '@kksh/api/ui/iframe';
import { import {
ModeToggle, ModeToggle,
Button, Button,
@ -11,92 +11,24 @@
ThemeWrapper, ThemeWrapper,
updateTheme updateTheme
} from '@kksh/svelte'; } from '@kksh/svelte';
import ThemeCustomizer from '$lib/components/ThemeCustomizer.svelte';
import {
Calculator,
Calendar,
CreditCard,
Settings,
SettingsIcon,
Smile,
User
} from 'lucide-svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
onMount(() => { onMount(() => {
ui.registerDragRegion(); clipboard.readText().then((text) => {
notification.sendNotification('Hello from template-ext-svelte'); console.log('clipboard text', text);
ui.getTheme().then((theme) => {
updateTheme(theme);
}); });
}); });
let highlighted = ''; function showDialog() {
let searchTerm = ''; dialog
.open({ directory: false })
.then((res: any) => console.log(res))
.catch((err: any) => {
console.error(err);
});
}
</script> </script>
<ModeWatcher /> <div class="container mt-16">
<Button onclick={showDialog}>Show Dialog</Button>
<ThemeWrapper> </div>
<Command.Root class="h-screen rounded-lg border shadow-md" bind:value={highlighted}>
<Command.Input placeholder="Type a command or search..." autofocus bind:value={searchTerm} />
<div class="grow">
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item onSelect={(v) => console.log('selected:', v)}>
<Calendar class="mr-2 h-4 w-4" />
<span>Calendar</span>
</Command.Item>
<Command.Item onSelect={(v) => console.log('selected:', v)}>
<Smile class="mr-2 h-4 w-4" />
<span>Search Emoji</span>
</Command.Item>
<Command.Item onSelect={(v) => console.log('selected:', v)}>
<Calculator class="mr-2 h-4 w-4" />
<span>Calculator</span>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Settings">
<Command.Item onSelect={(v) => console.log('selected:', v)}>
<User class="mr-2 h-4 w-4" />
<span>Profile</span>
<Command.Shortcut>⌘P</Command.Shortcut>
</Command.Item>
<Command.Item value="billllling">
<CreditCard class="mr-2 h-4 w-4" />
<span>Billing</span>
<Command.Shortcut>⌘B</Command.Shortcut>
</Command.Item>
<Command.Item onSelect={(v) => console.log('selected:', v)}>
<Settings class="mr-2 h-4 w-4" />
<span>Settings</span>
<Command.Shortcut>⌘S</Command.Shortcut>
</Command.Item>
</Command.Group>
</Command.List>
</div>
<CommandFooter>
<SettingsIcon class="ml-2 h-4 w-4" />
<div class="flex items-center space-x-2">
<Button variant="ghost" size="sm">
Open Application
<kbd class="ml-1"></kbd>
</Button>
<Separator orientation="vertical" />
<a href="{base}/about"><Button>About Page</Button></a>
<Button
on:click={async () => {
toast.success(await clipboard.readText());
}}
>
Read Clipboard
</Button>
<ModeToggle />
<ThemeCustomizer />
</div>
</CommandFooter>
</Command.Root>
</ThemeWrapper>

View File

@ -21,6 +21,7 @@ class ExtensionTemplate extends WorkerExtension {
toast.success(`Form submitted: ${JSON.stringify(value)}`) toast.success(`Form submitted: ${JSON.stringify(value)}`)
} }
async load() { async load() {
console.log("form-view load")
const markdown = new Markdown(`# Hello World const markdown = new Markdown(`# Hello World
<img src="https://github.com/huakunshen.png" />`) <img src="https://github.com/huakunshen.png" />`)
// markdown.toModel // markdown.toModel

View File

@ -1,4 +1,3 @@
## Permission Table ## Permission Table
<table> <table>
@ -7,7 +6,6 @@
<th>Description</th> <th>Description</th>
</tr> </tr>
<tr> <tr>
<td> <td>

View File

@ -1,7 +1,11 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
output: "export", output: "export",
transpilePackages: ["@kksh/api", "comlink-stdio"] transpilePackages: ["@kksh/api"],
experimental: {
workerThreads: false,
cpus: 1 // Limit to 1 CPU
}
} }
export default nextConfig export default nextConfig

View File

@ -41,8 +41,8 @@
"dependencies": { "dependencies": {
"@kksh/api": "workspace:*", "@kksh/api": "workspace:*",
"@kksh/react": "0.1.1", "@kksh/react": "0.1.1",
"@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-icons": "^1.3.2",
"next": "14.2.15", "next": "14.2.18",
"react": "^18", "react": "^18",
"react-dom": "^18" "react-dom": "^18"
}, },

View File

@ -1,22 +1,22 @@
import type { Metadata } from "next"; import type { Metadata } from "next"
import { Inter } from "next/font/google"; import { Inter } from "next/font/google"
import "./globals.css"; import "./globals.css"
const inter = Inter({ subsets: ["latin"] }); const inter = Inter({ subsets: ["latin"] })
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Create Next App", title: "Create Next App",
description: "Generated by create next app", description: "Generated by create next app"
}; }
export default function RootLayout({ export default function RootLayout({
children, children
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode
}>) { }>) {
return ( return (
<html lang="en"> <html lang="en">
<body className={inter.className}>{children}</body> <body className={inter.className}>{children}</body>
</html> </html>
); )
} }

View File

@ -1,20 +1,19 @@
import type { Config } from "tailwindcss"; import type { Config } from "tailwindcss"
const config: Config = { const config: Config = {
content: [ content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}", "./src/app/**/*.{js,ts,jsx,tsx,mdx}"
], ],
theme: { theme: {
extend: { extend: {
backgroundImage: { backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))", "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"gradient-conic": "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))"
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", }
}, }
}, },
}, plugins: []
plugins: [], }
}; export default config
export default config;

View File

@ -1,6 +1,10 @@
{ {
"compilerOptions": { "compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"], "lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true, "allowJs": true,
"skipLibCheck": true, "skipLibCheck": true,
"strict": true, "strict": true,
@ -19,9 +23,19 @@
} }
], ],
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": [
} "./src/*"
]
},
"target": "ES2017"
}, },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "include": [
"exclude": ["node_modules"] "next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
} }

View File

@ -1,10 +1,10 @@
import React from 'react' import React from "react"
import ReactDOM from 'react-dom/client' import ReactDOM from "react-dom/client"
import App from './App.tsx' import App from "./App.tsx"
import './index.css' import "./index.css"
ReactDOM.createRoot(document.getElementById('root')!).render( ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode> <React.StrictMode>
<App /> <App />
</React.StrictMode>, </React.StrictMode>
) )

View File

@ -1,10 +1,10 @@
<script lang="ts"> <script lang="ts">
let count: number = 0 let count: number = 0
const increment = () => { const increment = () => {
count += 1 count += 1
} }
</script> </script>
<button on:click={increment}> <button on:click={increment}>
count is {count} count is {count}
</button> </button>

View File

@ -1,20 +1,20 @@
<script lang="ts"> <script lang="ts">
import { ThemeCustomizerButton, type ThemeConfig, updateTheme } from '@kksh/svelte'; import { ui } from "@kksh/api/ui/iframe"
import { ui } from '@kksh/api/ui/iframe'; import { ThemeCustomizerButton, updateTheme, type ThemeConfig } from "@kksh/svelte"
import { onMount } from 'svelte'; import { onMount } from "svelte"
let config: ThemeConfig = { let config: ThemeConfig = {
radius: 0.5, radius: 0.5,
theme: 'zinc', theme: "zinc",
lightMode: 'auto' lightMode: "auto"
}; }
onMount(() => { onMount(() => {
ui.getTheme().then((theme) => { ui.getTheme().then((theme) => {
config = theme; config = theme
}); })
}); })
$: updateTheme(config); $: updateTheme(config)
</script> </script>
<ThemeCustomizerButton bind:config /> <ThemeCustomizerButton bind:config />

View File

@ -1,62 +1,56 @@
import { type ClassValue, clsx } from "clsx"; import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"; import { cubicOut } from "svelte/easing"
import { cubicOut } from "svelte/easing"; import type { TransitionConfig } from "svelte/transition"
import type { TransitionConfig } from "svelte/transition"; import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)); return twMerge(clsx(inputs))
} }
type FlyAndScaleParams = { type FlyAndScaleParams = {
y?: number; y?: number
x?: number; x?: number
start?: number; start?: number
duration?: number; duration?: number
}; }
export const flyAndScale = ( export const flyAndScale = (
node: Element, node: Element,
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 } params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
): TransitionConfig => { ): TransitionConfig => {
const style = getComputedStyle(node); const style = getComputedStyle(node)
const transform = style.transform === "none" ? "" : style.transform; const transform = style.transform === "none" ? "" : style.transform
const scaleConversion = ( const scaleConversion = (valueA: number, scaleA: [number, number], scaleB: [number, number]) => {
valueA: number, const [minA, maxA] = scaleA
scaleA: [number, number], const [minB, maxB] = scaleB
scaleB: [number, number]
) => {
const [minA, maxA] = scaleA;
const [minB, maxB] = scaleB;
const percentage = (valueA - minA) / (maxA - minA); const percentage = (valueA - minA) / (maxA - minA)
const valueB = percentage * (maxB - minB) + minB; const valueB = percentage * (maxB - minB) + minB
return valueB; return valueB
}; }
const styleToString = ( const styleToString = (style: Record<string, number | string | undefined>): string => {
style: Record<string, number | string | undefined>
): string => {
return Object.keys(style).reduce((str, key) => { return Object.keys(style).reduce((str, key) => {
if (style[key] === undefined) return str; if (style[key] === undefined) return str
return str + `${key}:${style[key]};`; return str + `${key}:${style[key]};`
}, ""); }, "")
}; }
return { return {
duration: params.duration ?? 200, duration: params.duration ?? 200,
delay: 0, delay: 0,
css: (t) => { css: (t) => {
const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]); const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0])
const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]); const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0])
const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]); const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1])
return styleToString({ return styleToString({
transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`, transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`,
opacity: t opacity: t
}); })
}, },
easing: cubicOut easing: cubicOut
}; }
}; }

View File

@ -1,7 +1,7 @@
import { type ClassValue, clsx } from "clsx"; import { type ClassValue, clsx } from 'clsx';
import { twMerge } from "tailwind-merge"; import { twMerge } from 'tailwind-merge';
import { cubicOut } from "svelte/easing"; import { cubicOut } from 'svelte/easing';
import type { TransitionConfig } from "svelte/transition"; import type { TransitionConfig } from 'svelte/transition';
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)); return twMerge(clsx(inputs));
@ -19,13 +19,9 @@ export const flyAndScale = (
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 } params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
): TransitionConfig => { ): TransitionConfig => {
const style = getComputedStyle(node); const style = getComputedStyle(node);
const transform = style.transform === "none" ? "" : style.transform; const transform = style.transform === 'none' ? '' : style.transform;
const scaleConversion = ( const scaleConversion = (valueA: number, scaleA: [number, number], scaleB: [number, number]) => {
valueA: number,
scaleA: [number, number],
scaleB: [number, number]
) => {
const [minA, maxA] = scaleA; const [minA, maxA] = scaleA;
const [minB, maxB] = scaleB; const [minB, maxB] = scaleB;
@ -35,13 +31,11 @@ export const flyAndScale = (
return valueB; return valueB;
}; };
const styleToString = ( const styleToString = (style: Record<string, number | string | undefined>): string => {
style: Record<string, number | string | undefined>
): string => {
return Object.keys(style).reduce((str, key) => { return Object.keys(style).reduce((str, key) => {
if (style[key] === undefined) return str; if (style[key] === undefined) return str;
return str + `${key}:${style[key]};`; return str + `${key}:${style[key]};`;
}, ""); }, '');
}; };
return { return {
@ -59,4 +53,4 @@ export const flyAndScale = (
}, },
easing: cubicOut easing: cubicOut
}; };
}; };

View File

@ -36,21 +36,21 @@
"devDependencies": { "devDependencies": {
"@iconify/svelte": "^4.0.2", "@iconify/svelte": "^4.0.2",
"@kksh/api": "workspace:*", "@kksh/api": "workspace:*",
"@kksh/svelte5": "^0.1.9", "@kksh/svelte5": "^0.1.10",
"@types/bun": "latest", "@types/bun": "latest",
"bits-ui": "1.0.0-next.49", "bits-ui": "1.0.0-next.60",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"formsnap": "2.0.0-next.1", "formsnap": "2.0.0-next.1",
"lucide-svelte": "^0.454.0", "lucide-svelte": "^0.460.1",
"mode-watcher": "^0.4.1", "mode-watcher": "^0.5.0",
"paneforge": "1.0.0-next.1", "paneforge": "1.0.0-next.1",
"shiki": "^1.22.2", "shiki": "^1.23.1",
"svelte-radix": "^2.0.1", "svelte-radix": "^2.0.1",
"svelte-sonner": "^0.3.28", "svelte-sonner": "^0.3.28",
"sveltekit-superforms": "^2.20.0", "sveltekit-superforms": "^2.20.1",
"tailwind-merge": "^2.5.4", "tailwind-merge": "^2.5.4",
"tailwind-variants": "^0.2.1", "tailwind-variants": "^0.3.0",
"tailwindcss": "^3.4.14", "tailwindcss": "^3.4.15",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"tauri-plugin-shellx-api": "^2.0.14", "tauri-plugin-shellx-api": "^2.0.14",
"zod": "^3.23.8" "zod": "^3.23.8"

12235
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -4,4 +4,8 @@ packages:
- "packages/extensions/*" - "packages/extensions/*"
- "packages/templates/*" - "packages/templates/*"
- "packages/tauri-plugins/*" - "packages/tauri-plugins/*"
- "vendors/*" - "vendors/tauri-plugin-network"
- "vendors/tauri-plugin-system-info"
- "vendors/kkrpc/packages/kkrpc"
- "vendors/tauri-api-adapter/packages/tauri-api-adapter"