Skip to content

Commit 493656b

Browse files
committed
refactor!: migrate from cancelable promise to AbortSignal
AbortSignal (provided by AbortController) is the standard way of doing this and is in-line with how e.g. the webdav library, axios or native fetch work. Also `cancelable-promise` is deprecated in favor of this. Signed-off-by: Ferdinand Thiessen <[email protected]>
1 parent af703f9 commit 493656b

File tree

4 files changed

+49
-41
lines changed

4 files changed

+49
-41
lines changed

lib/dav/dav.ts

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import type { Node, NodeData } from '../node/index.ts'
99
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
1010
import { getSharingToken, isPublicShare } from '@nextcloud/sharing/public'
1111
import { generateRemoteUrl } from '@nextcloud/router'
12-
import { CancelablePromise } from 'cancelable-promise'
1312
import { createClient, getPatcher } from 'webdav'
1413
import { parsePermissions } from './davPermissions.ts'
1514
import { getFavoritesReport } from './davProperties.ts'
@@ -112,44 +111,52 @@ export const getClient = function(remoteURL = defaultRemoteURL, headers: Record<
112111
/**
113112
* Use WebDAV to query for favorite Nodes
114113
*
115-
* @param davClient The WebDAV client to use for performing the request
116-
* @param path Base path for the favorites, if unset all favorites are queried
117-
* @param davRoot The root path for the DAV user (defaults to `defaultRootPath`)
114+
* @param options - Options for the favorite query
115+
* @param options.client - The WebDAV client to use for performing the request
116+
* @param options.path - Base path for the favorites, if unset all favorites are queried
117+
* @param options.davRoot - The root path for the DAV user (defaults to `defaultRootPath`)
118+
* @param options.signal - Optional abort signal to cancel the request
119+
*
120+
* @example
121+
* ```js
122+
* import { getFavoriteNodes } from '@nextcloud/files'
123+
*
124+
* // query favorites for the root
125+
* const favorites = await getFavoriteNodes()
126+
* ```
118127
* @example
119128
* ```js
129+
* // Advanced usage with custom client and path
120130
* import { getClient, defaultRootPath, getFavoriteNodes } from '@nextcloud/files'
121131
*
122132
* const client = getClient()
123-
* // query favorites for the root
124-
* const favorites = await getFavoriteNodes(client)
125-
* // which is the same as writing:
126-
* const favorites = await getFavoriteNodes(client, '/', defaultRootPath)
133+
* const controller = new AbortController()
134+
* const favoritesPromise = getFavoriteNodes({ client, path: '/some/folder', signal: controller.signal })
135+
* // you can abort the request if needed
136+
* controller.abort()
137+
* // or await the result
138+
* const favorites = await favoritesPromise
127139
* ```
128140
*/
129-
export const getFavoriteNodes = (davClient: WebDAVClient, path = '/', davRoot = defaultRootPath): CancelablePromise<Node[]> => {
130-
const controller = new AbortController()
131-
return new CancelablePromise(async (resolve, reject, onCancel) => {
132-
onCancel(() => controller.abort())
133-
try {
134-
const contentsResponse = await davClient.getDirectoryContents(`${davRoot}${path}`, {
135-
signal: controller.signal,
136-
details: true,
137-
data: getFavoritesReport(),
138-
headers: {
139-
// see getClient for patched webdav client
140-
method: 'REPORT',
141-
},
142-
includeSelf: true,
143-
}) as ResponseDataDetailed<FileStat[]>
144-
145-
const nodes = contentsResponse.data
146-
.filter(node => node.filename !== path) // exclude current dir
147-
.map((result) => resultToNode(result, davRoot))
148-
resolve(nodes)
149-
} catch (error) {
150-
reject(error)
151-
}
152-
})
141+
export async function getFavoriteNodes(options: { client?: WebDAVClient, path?: string, davRoot?: string, signal?: AbortSignal } = {}): Promise<Node[]> {
142+
const client = options.client ?? getClient()
143+
const path = options.path ?? '/'
144+
const davRoot = options.davRoot ?? defaultRootPath
145+
146+
const contentsResponse = await client.getDirectoryContents(`${davRoot}${path}`, {
147+
signal: options.signal,
148+
details: true,
149+
data: getFavoritesReport(),
150+
headers: {
151+
// see getClient for patched webdav client
152+
method: 'REPORT',
153+
},
154+
includeSelf: true,
155+
}) as ResponseDataDetailed<FileStat[]>
156+
157+
return contentsResponse.data
158+
.filter(node => node.filename !== path) // exclude current dir
159+
.map((result) => resultToNode(result, davRoot))
153160
}
154161

155162
/**

lib/navigation/view.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,16 @@ export interface IView {
3737
emptyView?: (div: HTMLDivElement) => void
3838

3939
/**
40-
* Method return the content of the provided path
41-
* This ideally should be a cancellable promise.
42-
* promise.cancel(reason) will be called when the directory
43-
* change and the promise is not resolved yet.
44-
* You _must_ also return the current directory
40+
* Method return the content of the provided path.
41+
*
42+
* This method _must_ also return the current directory
4543
* information alongside with its content.
44+
*
45+
* Usually a abort signal is provided to be able to
46+
* cancel the request if the user change directory
47+
* {@see https://developer.mozilla.org/en-US/docs/Web/API/AbortController }.
4648
*/
47-
getContents: (path: string) => Promise<ContentsWithRoot>
49+
getContents(path: string, options: { signal: AbortSignal }): Promise<ContentsWithRoot>
4850

4951
/**
5052
* If set then the view will be hidden from the navigation unless its the active view.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
"@nextcloud/paths": "^2.4.0",
6161
"@nextcloud/router": "^3.1.0",
6262
"@nextcloud/sharing": "^0.3.0",
63-
"cancelable-promise": "^4.3.1",
6463
"is-svg": "^6.1.0",
6564
"typescript-event-target": "^1.1.1",
6665
"webdav": "^5.8.0"

0 commit comments

Comments
 (0)