Преглед изворни кода

perf(app): performance improvements

adamelmore пре 3 недеља
родитељ
комит
d03c5f6b3f

+ 40 - 13
packages/app/src/context/command.tsx

@@ -24,6 +24,15 @@ function normalizeKey(key: string) {
   return key.toLowerCase()
   return key.toLowerCase()
 }
 }
 
 
+function signature(key: string, ctrl: boolean, meta: boolean, shift: boolean, alt: boolean) {
+  const mask = (ctrl ? 1 : 0) | (meta ? 2 : 0) | (shift ? 4 : 0) | (alt ? 8 : 0)
+  return `${key}:${mask}`
+}
+
+function signatureFromEvent(event: KeyboardEvent) {
+  return signature(normalizeKey(event.key), event.ctrlKey, event.metaKey, event.shiftKey, event.altKey)
+}
+
 export type KeybindConfig = string
 export type KeybindConfig = string
 
 
 export interface Keybind {
 export interface Keybind {
@@ -223,6 +232,30 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
 
 
     const suspended = () => suspendCount() > 0
     const suspended = () => suspendCount() > 0
 
 
+    const palette = createMemo(() => {
+      const config = settings.keybinds.get(PALETTE_ID) ?? DEFAULT_PALETTE_KEYBIND
+      const keybinds = parseKeybind(config)
+      return new Set(keybinds.map((kb) => signature(kb.key, kb.ctrl, kb.meta, kb.shift, kb.alt)))
+    })
+
+    const keymap = createMemo(() => {
+      const map = new Map<string, CommandOption>()
+      for (const option of options()) {
+        if (option.id.startsWith(SUGGESTED_PREFIX)) continue
+        if (option.disabled) continue
+        if (!option.keybind) continue
+
+        const keybinds = parseKeybind(option.keybind)
+        for (const kb of keybinds) {
+          if (!kb.key) continue
+          const sig = signature(kb.key, kb.ctrl, kb.meta, kb.shift, kb.alt)
+          if (map.has(sig)) continue
+          map.set(sig, option)
+        }
+      }
+      return map
+    })
+
     const run = (id: string, source?: "palette" | "keybind" | "slash") => {
     const run = (id: string, source?: "palette" | "keybind" | "slash") => {
       for (const option of options()) {
       for (const option of options()) {
         if (option.id === id || option.id === "suggested." + id) {
         if (option.id === id || option.id === "suggested." + id) {
@@ -239,24 +272,18 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
     const handleKeyDown = (event: KeyboardEvent) => {
     const handleKeyDown = (event: KeyboardEvent) => {
       if (suspended() || dialog.active) return
       if (suspended() || dialog.active) return
 
 
-      const paletteKeybinds = parseKeybind(settings.keybinds.get(PALETTE_ID) ?? DEFAULT_PALETTE_KEYBIND)
-      if (matchKeybind(paletteKeybinds, event)) {
+      const sig = signatureFromEvent(event)
+
+      if (palette().has(sig)) {
         event.preventDefault()
         event.preventDefault()
         showPalette()
         showPalette()
         return
         return
       }
       }
 
 
-      for (const option of options()) {
-        if (option.disabled) continue
-        if (!option.keybind) continue
-
-        const keybinds = parseKeybind(option.keybind)
-        if (matchKeybind(keybinds, event)) {
-          event.preventDefault()
-          option.onSelect?.("keybind")
-          return
-        }
-      }
+      const option = keymap().get(sig)
+      if (!option) return
+      event.preventDefault()
+      option.onSelect?.("keybind")
     }
     }
 
 
     onMount(() => {
     onMount(() => {

+ 1 - 1
packages/app/src/context/layout.tsx

@@ -218,7 +218,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
     }
     }
 
 
     function enrich(project: { worktree: string; expanded: boolean }) {
     function enrich(project: { worktree: string; expanded: boolean }) {
-      const [childStore] = globalSync.child(project.worktree)
+      const [childStore] = globalSync.child(project.worktree, { bootstrap: false })
       const projectID = childStore.project
       const projectID = childStore.project
       const metadata = projectID
       const metadata = projectID
         ? globalSync.data.project.find((x) => x.id === projectID)
         ? globalSync.data.project.find((x) => x.id === projectID)

+ 2 - 2
packages/app/src/context/notification.tsx

@@ -88,7 +88,7 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
       switch (event.type) {
       switch (event.type) {
         case "session.idle": {
         case "session.idle": {
           const sessionID = event.properties.sessionID
           const sessionID = event.properties.sessionID
-          const [syncStore] = globalSync.child(directory)
+          const [syncStore] = globalSync.child(directory, { bootstrap: false })
           const match = Binary.search(syncStore.session, sessionID, (s) => s.id)
           const match = Binary.search(syncStore.session, sessionID, (s) => s.id)
           const session = match.found ? syncStore.session[match.index] : undefined
           const session = match.found ? syncStore.session[match.index] : undefined
           if (session?.parentID) break
           if (session?.parentID) break
@@ -115,7 +115,7 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
         }
         }
         case "session.error": {
         case "session.error": {
           const sessionID = event.properties.sessionID
           const sessionID = event.properties.sessionID
-          const [syncStore] = globalSync.child(directory)
+          const [syncStore] = globalSync.child(directory, { bootstrap: false })
           const match = sessionID ? Binary.search(syncStore.session, sessionID, (s) => s.id) : undefined
           const match = sessionID ? Binary.search(syncStore.session, sessionID, (s) => s.id) : undefined
           const session = sessionID && match?.found ? syncStore.session[match.index] : undefined
           const session = sessionID && match?.found ? syncStore.session[match.index] : undefined
           if (session?.parentID) break
           if (session?.parentID) break