Skip to content

Commit

Permalink
improve(plugin): support abortable controller of request api
Browse files Browse the repository at this point in the history
  • Loading branch information
xyhp915 authored and tiensonqin committed Jun 15, 2022
1 parent 7b2ce59 commit e4b71a4
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 15 deletions.
39 changes: 30 additions & 9 deletions libs/src/modules/LSPlugin.Request.ts
Expand Up @@ -3,6 +3,7 @@ import { EventEmitter } from 'eventemitter3'

export type IRequestOptions<R = any> = {
url: string
abortable: boolean
headers: Record<string, string>
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
data: Object | ArrayBuffer
Expand Down Expand Up @@ -40,8 +41,11 @@ export class LSPluginRequestTask<R = any> {
this._client.once(
genTaskCallbackType(this._requestId),
(e) => {
// handle error
resolve(e)
if (e && e instanceof Error) {
reject(e)
} else {
resolve(e)
}
}
)
})
Expand All @@ -61,9 +65,17 @@ export class LSPluginRequestTask<R = any> {
}

abort() {
if (this._aborted) return
if (
!this._requestOptions.abortable ||
this._aborted
) return

this._client.ctx._execCallableAPI(
'http_request_abort',
this._requestId
)

// TODO: impl
this._aborted = true
}

get promise(): Promise<R> {
Expand All @@ -83,7 +95,7 @@ export class LSPluginRequestTask<R = any> {
* A simple request client
*/
export class LSPluginRequest extends EventEmitter {
constructor(private ctx: LSPluginUser) {
constructor(private _ctx: LSPluginUser) {
super()

// request callback listener
Expand All @@ -108,17 +120,26 @@ export class LSPluginRequest extends EventEmitter {
)
}

_request<R = any>(options: WithOptional<IRequestOptions<R>, keyof Omit<IRequestOptions, 'url'>>): LSPluginRequestTask<R> {
async _request<R extends {},
T extends WithOptional<IRequestOptions<R>, keyof Omit<IRequestOptions, 'url'>>>(options: T):
Promise<T extends Pick<IRequestOptions, 'abortable'> ? LSPluginRequestTask<R> : R> {
const pid = this.ctx.baseInfo.id
const { success, fail, final, ...requestOptions } = options
const reqID = this.ctx.Experiments.invokeExperMethod('request', pid, requestOptions)

// TODO: impl
const task = LSPluginRequest.createRequestTask(
this.ctx.Request,
reqID, { success, fail, final }
reqID, options
)

return task
if (!requestOptions.abortable) {
return task.promise
}

return task as any
}

get ctx(): LSPluginUser {
return this._ctx
}
}
3 changes: 2 additions & 1 deletion resources/package.json
Expand Up @@ -37,7 +37,8 @@
"@sentry/electron": "2.5.1",
"posthog-js": "1.10.2",
"@logseq/rsapi": "0.0.20",
"electron-deeplink": "1.0.10"
"electron-deeplink": "1.0.10",
"abort-controller": "3.0.0"
},
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.57",
Expand Down
23 changes: 20 additions & 3 deletions src/electron/electron/handler.cljs
Expand Up @@ -8,6 +8,7 @@
["os" :as os]
["diff-match-patch" :as google-diff]
["/electron/utils" :as js-utils]
["abort-controller" :as AbortController]
[electron.fs-watcher :as watcher]
[electron.configs :as cfgs]
[promesa.core :as p]
Expand Down Expand Up @@ -368,8 +369,10 @@
(defmethod handle :uninstallMarketPlugin [_ [_ id]]
(plugin/uninstall! id))

(def *request-abort-signals (atom {}))

(defmethod handle :httpRequest [_ [_ _req-id opts]]
(let [{:keys [url method data returnType headers]} opts]
(let [{:keys [url abortable method data returnType headers]} opts]
(when-let [[method type] (and (not (string/blank? url))
[(keyword (string/upper-case (or method "GET")))
(keyword (string/lower-case (or returnType "json")))])]
Expand All @@ -378,7 +381,11 @@
:headers (and headers (bean/->js headers))}
(merge (when (and (not (contains? #{:GET :HEAD} method)) data)
;; TODO: support type of arrayBuffer
{:body (js/JSON.stringify (bean/->js data))}))))
{:body (js/JSON.stringify (bean/->js data))})

(when-let [^js controller (and abortable (AbortController.))]
(swap! *request-abort-signals assoc _req-id controller)
{:signal (.-signal controller)}))))
(p/then (fn [^js res]
(case type
:json
Expand All @@ -393,7 +400,17 @@

:text
(.text res))))
(p/catch identity)))))
(p/catch
(fn [^js e]
;; TODO: handle special cases
(throw e)))
(p/finally
(fn []
(swap! *request-abort-signals dissoc _req-id)))))))

(defmethod handle :httpRequestAbort [_ [_ _req-id]]
(when-let [^js controller (get @*request-abort-signals _req-id)]
(.abort controller)))

(defmethod handle :quitAndInstall []
(.quitAndInstall autoUpdater))
Expand Down
4 changes: 2 additions & 2 deletions src/main/logseq/api.cljs
Expand Up @@ -820,9 +820,9 @@
(p/catch #(req-cb %)))
req-id)))

(defn ^:export exper_abort_request
(defn ^:export http_request_abort
[req-id]
nil)
(ipc/ipc :httpRequestAbort req-id))

;; helpers
(defn ^:export query_element_by_id
Expand Down

0 comments on commit e4b71a4

Please sign in to comment.