Browse Source

enhance(libs): types

charlie 9 months ago
parent
commit
72c09e5c30
2 changed files with 82 additions and 66 deletions
  1. 2 0
      libs/src/LSPlugin.ts
  2. 80 66
      libs/src/LSPlugin.user.ts

+ 2 - 0
libs/src/LSPlugin.ts

@@ -687,6 +687,8 @@ export interface IEditorProxy extends Record<string, any> {
    */
   newBlockUUID: () => Promise<string>
 
+  isPageBlock: (block: BlockEntity | PageEntity) => Boolean
+
   /**
    * @example https://github.com/logseq/logseq-plugin-samples/tree/master/logseq-reddit-hot-news
    *

+ 80 - 66
libs/src/LSPlugin.user.ts

@@ -37,6 +37,7 @@ import {
   IAssetsProxy,
   AppInfo,
   IPluginSearchServiceHooks,
+  PageEntity,
 } from './LSPlugin'
 import Debug from 'debug'
 import * as CSS from 'csstype'
@@ -64,7 +65,7 @@ const logger = new PluginLogger('', { console: true })
  * @param opts
  * @param action
  */
-function registerSimpleCommand (
+function registerSimpleCommand(
   this: LSPluginUser,
   type: string,
   opts: {
@@ -109,7 +110,7 @@ function registerSimpleCommand (
   })
 }
 
-function shouldValidUUID (uuid: string) {
+function shouldValidUUID(uuid: string) {
   if (!isValidUUID(uuid)) {
     logger.error(`#${uuid} is not a valid UUID string.`)
     return false
@@ -118,7 +119,7 @@ function shouldValidUUID (uuid: string) {
   return true
 }
 
-function checkEffect (p: LSPluginUser) {
+function checkEffect(p: LSPluginUser) {
   return p && (p.baseInfo?.effect || !p.baseInfo?.iir)
 }
 
@@ -126,7 +127,7 @@ let _appBaseInfo: AppInfo = null
 let _searchServices: Map<string, LSPluginSearchService> = new Map()
 
 const app: Partial<IAppProxy> = {
-  async getInfo (this: LSPluginUser, key) {
+  async getInfo(this: LSPluginUser, key) {
     if (!_appBaseInfo) {
       _appBaseInfo = await this._execCallableAPIAsync('get-app-info')
     }
@@ -135,7 +136,7 @@ const app: Partial<IAppProxy> = {
 
   registerCommand: registerSimpleCommand,
 
-  registerSearchService<T extends IPluginSearchServiceHooks> (
+  registerSearchService<T extends IPluginSearchServiceHooks>(
     this: LSPluginUser,
     s: T
   ) {
@@ -146,7 +147,7 @@ const app: Partial<IAppProxy> = {
     _searchServices.set(s.name, new LSPluginSearchService(this, s))
   },
 
-  registerCommandPalette (
+  registerCommandPalette(
     opts: { key: string; label: string; keybinding?: SimpleCommandKeybinding },
     action: SimpleCommandCallback
   ) {
@@ -161,7 +162,7 @@ const app: Partial<IAppProxy> = {
     )
   },
 
-  registerCommandShortcut (
+  registerCommandShortcut(
     keybinding: SimpleCommandKeybinding | string,
     action: SimpleCommandCallback,
     opts: Partial<{
@@ -190,7 +191,7 @@ const app: Partial<IAppProxy> = {
     )
   },
 
-  registerUIItem (
+  registerUIItem(
     type: 'toolbar' | 'pagebar',
     opts: { key: string; template: string }
   ) {
@@ -203,7 +204,7 @@ const app: Partial<IAppProxy> = {
     })
   },
 
-  registerPageMenuItem (
+  registerPageMenuItem(
     this: LSPluginUser,
     tag: string,
     action: (e: IHookEvent & { page: string }) => void
@@ -227,7 +228,7 @@ const app: Partial<IAppProxy> = {
     )
   },
 
-  onBlockRendererSlotted (uuid, callback: (payload: any) => void) {
+  onBlockRendererSlotted(uuid, callback: (payload: any) => void) {
     if (!shouldValidUUID(uuid)) return
 
     const pid = this.baseInfo.id
@@ -242,7 +243,7 @@ const app: Partial<IAppProxy> = {
     }
   },
 
-  invokeExternalPlugin (this: LSPluginUser, type: string, ...args: Array<any>) {
+  invokeExternalPlugin(this: LSPluginUser, type: string, ...args: Array<any>) {
     type = type?.trim()
     if (!type) return
     let [pid, group] = type.split('.')
@@ -263,7 +264,7 @@ const app: Partial<IAppProxy> = {
     )
   },
 
-  setFullScreen (flag) {
+  setFullScreen(flag) {
     const sf = (...args) => this._callWin('setFullScreen', ...args)
 
     if (flag === 'toggle') {
@@ -279,11 +280,18 @@ const app: Partial<IAppProxy> = {
 let registeredCmdUid = 0
 
 const editor: Partial<IEditorProxy> = {
-  newBlockUUID (this: LSPluginUser): Promise<string> {
+  newBlockUUID(this: LSPluginUser): Promise<string> {
     return this._execCallableAPIAsync('new_block_uuid')
   },
 
-  registerSlashCommand (
+  isPageBlock(
+    this: LSPluginUser,
+    block: BlockEntity | PageEntity
+  ): Boolean {
+    return block.uuid && block.hasOwnProperty('name')
+  },
+
+  registerSlashCommand(
     this: LSPluginUser,
     tag: string,
     actions: BlockCommandCallback | Array<SlashCommandAction>
@@ -331,7 +339,7 @@ const editor: Partial<IEditorProxy> = {
     })
   },
 
-  registerBlockContextMenuItem (
+  registerBlockContextMenuItem(
     this: LSPluginUser,
     label: string,
     action: BlockCommandCallback
@@ -354,7 +362,7 @@ const editor: Partial<IEditorProxy> = {
     )
   },
 
-  registerHighlightContextMenuItem (
+  registerHighlightContextMenuItem(
     this: LSPluginUser,
     label: string,
     action: SimpleCommandCallback,
@@ -379,7 +387,7 @@ const editor: Partial<IEditorProxy> = {
     )
   },
 
-  scrollToBlockInPage (
+  scrollToBlockInPage(
     this: LSPluginUser,
     pageName: BlockPageName,
     blockId: BlockIdentity,
@@ -395,7 +403,7 @@ const editor: Partial<IEditorProxy> = {
 }
 
 const db: Partial<IDBProxy> = {
-  onBlockChanged (
+  onBlockChanged(
     this: LSPluginUser,
     uuid: BlockUUID,
     callback: (
@@ -425,7 +433,7 @@ const db: Partial<IDBProxy> = {
     }
   },
 
-  datascriptQuery<T = any> (
+  datascriptQuery<T = any>(
     this: LSPluginUser,
     query: string,
     ...inputs: Array<any>
@@ -447,7 +455,7 @@ const git: Partial<IGitProxy> = {}
 const ui: Partial<IUIProxy> = {}
 
 const assets: Partial<IAssetsProxy> = {
-  makeSandboxStorage (this: LSPluginUser): IAsyncStorage {
+  makeSandboxStorage(this: LSPluginUser): IAsyncStorage {
     return new LSPluginFileStorage(this, { assets: true })
   },
 }
@@ -496,7 +504,7 @@ export class LSPluginUser
    * @param _baseInfo
    * @param _caller
    */
-  constructor (
+  constructor(
     private _baseInfo: LSPluginBaseInfo,
     private _caller: LSPluginCaller
   ) {
@@ -529,7 +537,7 @@ export class LSPluginUser
   }
 
   // Life related
-  async ready (model?: any, callback?: any) {
+  async ready(model?: any, callback?: any) {
     if (this._connected) return
 
     try {
@@ -576,39 +584,39 @@ export class LSPluginUser
     }
   }
 
-  ensureConnected () {
+  ensureConnected() {
     if (!this._connected) {
       throw new Error('not connected')
     }
   }
 
-  beforeunload (callback: (e: any) => Promise<void>): void {
+  beforeunload(callback: (e: any) => Promise<void>): void {
     if (typeof callback !== 'function') return
     this._beforeunloadCallback = callback
   }
 
-  provideModel (model: Record<string, any>) {
+  provideModel(model: Record<string, any>) {
     this.caller._extendUserModel(model)
     return this
   }
 
-  provideTheme (theme: Theme) {
+  provideTheme(theme: Theme) {
     this.caller.call('provider:theme', theme)
     return this
   }
 
-  provideStyle (style: StyleString) {
+  provideStyle(style: StyleString) {
     this.caller.call('provider:style', style)
     return this
   }
 
-  provideUI (ui: UIOptions) {
+  provideUI(ui: UIOptions) {
     this.caller.call('provider:ui', ui)
     return this
   }
 
   // Settings related
-  useSettingsSchema (schema: Array<SettingSchemaDesc>) {
+  useSettingsSchema(schema: Array<SettingSchemaDesc>) {
     if (this.connected) {
       this.caller.call('settings:schema', {
         schema,
@@ -620,35 +628,35 @@ export class LSPluginUser
     return this
   }
 
-  updateSettings (attrs: Record<string, any>) {
+  updateSettings(attrs: Record<string, any>) {
     this.caller.call('settings:update', attrs)
     // TODO: update associated baseInfo settings
   }
 
-  onSettingsChanged<T = any> (cb: (a: T, b: T) => void): IUserOffHook {
+  onSettingsChanged<T = any>(cb: (a: T, b: T) => void): IUserOffHook {
     const type = 'settings:changed'
     this.on(type, cb)
     return () => this.off(type, cb)
   }
 
-  showSettingsUI () {
+  showSettingsUI() {
     this.caller.call('settings:visible:changed', { visible: true })
   }
 
-  hideSettingsUI () {
+  hideSettingsUI() {
     this.caller.call('settings:visible:changed', { visible: false })
   }
 
   // UI related
-  setMainUIAttrs (attrs: Partial<UIContainerAttrs>): void {
+  setMainUIAttrs(attrs: Partial<UIContainerAttrs>): void {
     this.caller.call('main-ui:attrs', attrs)
   }
 
-  setMainUIInlineStyle (style: CSS.Properties): void {
+  setMainUIInlineStyle(style: CSS.Properties): void {
     this.caller.call('main-ui:style', style)
   }
 
-  hideMainUI (opts?: { restoreEditingCursor: boolean }): void {
+  hideMainUI(opts?: { restoreEditingCursor: boolean }): void {
     const payload = {
       key: KEY_MAIN_UI,
       visible: false,
@@ -659,7 +667,7 @@ export class LSPluginUser
     this._ui.set(payload.key, payload)
   }
 
-  showMainUI (opts?: { autoFocus: boolean }): void {
+  showMainUI(opts?: { autoFocus: boolean }): void {
     const payload = {
       key: KEY_MAIN_UI,
       visible: true,
@@ -670,7 +678,7 @@ export class LSPluginUser
     this._ui.set(payload.key, payload)
   }
 
-  toggleMainUI (): void {
+  toggleMainUI(): void {
     const payload = { key: KEY_MAIN_UI, toggle: true }
     const state = this._ui.get(payload.key)
     if (state && state.visible) {
@@ -681,40 +689,40 @@ export class LSPluginUser
   }
 
   // Getters
-  get version (): string {
+  get version(): string {
     return this._version
   }
 
-  get isMainUIVisible (): boolean {
+  get isMainUIVisible(): boolean {
     const state = this._ui.get(KEY_MAIN_UI)
     return Boolean(state && state.visible)
   }
 
-  get connected (): boolean {
+  get connected(): boolean {
     return this._connected
   }
 
-  get baseInfo (): LSPluginBaseInfo {
+  get baseInfo(): LSPluginBaseInfo {
     return this._baseInfo
   }
 
-  get effect (): Boolean {
+  get effect(): Boolean {
     return checkEffect(this)
   }
 
-  get logger () {
+  get logger() {
     return logger
   }
 
-  get settings () {
+  get settings() {
     return this.baseInfo?.settings
   }
 
-  get caller (): LSPluginCaller {
+  get caller(): LSPluginCaller {
     return this._caller
   }
 
-  resolveResourceFullUrl (filePath: string) {
+  resolveResourceFullUrl(filePath: string) {
     this.ensureConnected()
     if (!filePath) return
     filePath = filePath.replace(/^[.\\/]+/, '')
@@ -724,12 +732,12 @@ export class LSPluginUser
   /**
    * @internal
    */
-  _makeUserProxy (target: any, tag?: UserProxyTags) {
+  _makeUserProxy(target: any, tag?: UserProxyTags) {
     const that = this
     const caller = this.caller
 
     return new Proxy(target, {
-      get (target: any, propKey, receiver) {
+      get(target: any, propKey, _receiver) {
         const origMethod = target[propKey]
 
         return function (this: any, ...args: any) {
@@ -800,68 +808,74 @@ export class LSPluginUser
     })
   }
 
-  _execCallableAPIAsync (method: callableMethods, ...args) {
+  _execCallableAPIAsync(method: callableMethods, ...args) {
     return this._caller.callAsync(`api:call`, {
       method,
       args,
     })
   }
 
-  _execCallableAPI (method: callableMethods, ...args) {
+  _execCallableAPI(method: callableMethods, ...args) {
     this._caller.call(`api:call`, {
       method,
       args,
     })
   }
 
-  _callWin (...args) {
+  _callWin(...args) {
     return this._execCallableAPIAsync(`_callMainWin`, ...args)
   }
 
   // User Proxies
   #appProxy: IAppProxy
+  #editorProxy: IEditorProxy
+  #dbProxy: IDBProxy
+  #uiProxy: IUIProxy
 
   /**
    * The interface methods of {@link IAppProxy}
    */
-  get App (): IAppProxy {
+  get App(): IAppProxy {
     if (this.#appProxy) return this.#appProxy
     return (this.#appProxy = this._makeUserProxy(app, 'app'))
   }
 
-  get Editor (): IEditorProxy {
-    return this._makeUserProxy(editor, 'editor')
+  get Editor(): IEditorProxy {
+    if (this.#editorProxy) return this.#editorProxy
+    return (this.#editorProxy = this._makeUserProxy(editor, 'editor'))
   }
 
-  get DB (): IDBProxy {
-    return this._makeUserProxy(db, 'db')
+  get DB(): IDBProxy {
+    if (this.#dbProxy) return this.#dbProxy
+    return (this.#dbProxy = this._makeUserProxy(db, 'db'))
   }
 
-  get Git (): IGitProxy {
-    return this._makeUserProxy(git, 'git')
+  get UI(): IUIProxy {
+    if (this.#uiProxy) return this.#uiProxy
+    return (this.#uiProxy = this._makeUserProxy(ui, 'ui'))
   }
 
-  get UI (): IUIProxy {
-    return this._makeUserProxy(ui, 'ui')
+  get Git(): IGitProxy {
+    return this._makeUserProxy(git, 'git')
   }
 
-  get Assets (): IAssetsProxy {
+  get Assets(): IAssetsProxy {
     return this._makeUserProxy(assets, 'assets')
   }
 
-  get FileStorage (): LSPluginFileStorage {
+  get FileStorage(): LSPluginFileStorage {
     let m = this._mFileStorage
     if (!m) m = this._mFileStorage = new LSPluginFileStorage(this)
     return m
   }
 
-  get Request (): LSPluginRequest {
+  get Request(): LSPluginRequest {
     let m = this._mRequest
     if (!m) m = this._mRequest = new LSPluginRequest(this)
     return m
   }
 
-  get Experiments (): LSPluginExperiments {
+  get Experiments(): LSPluginExperiments {
     let m = this._mExperiments
     if (!m) m = this._mExperiments = new LSPluginExperiments(this)
     return m
@@ -873,7 +887,7 @@ export * from './LSPlugin'
 /**
  * @internal
  */
-export function setupPluginUserInstance (
+export function setupPluginUserInstance(
   pluginBaseInfo: LSPluginBaseInfo,
   pluginCaller: LSPluginCaller
 ) {