Request Abstraction
Sync Engine exposes two typed request functions:
Requestfor remote HTTP operationsVaultRequestfor local Obsidian vault operations
Both are function objects returning promises. They provide a small, middleware-friendly boundary between file-system implementations and their underlying platform APIs.
Request
Request is defined in packages/plugin/src/modules/Registrar.ts:
ts
type Request = (params: RequestParam | string) => Promise<RequestResponse>;RequestParam follows Obsidian's RequestUrlParam, except body uses the project's Binary (Uint8Array) instead of ArrayBuffer in Obsidian raw API. A string argument is treated as a GET toward this URL.
RequestResponse is an exported SDK type describing the response returned by Request.
Implementation
The base implementation:
- Converts a
Uint8Arraybody to anArrayBuffer. - Calls Obsidian
requestUrl(). - Wraps the result as:
status: HTTP status codeheaders: response headerstext(): response textjson(): parsed JSONbytes(): responseArrayBufferconverted toBinary
Remote file-system modules receive getRequest() in context, not the base function directly. Registrar applies registered remote request middleware in priority order before returning it. Each remote FS operation therefore uses the same abstraction for authentication, headers, retries, rate limiting, and cancellation.
Limitations
- Obsidian
requestUrl()accepts only a complete string orArrayBufferbody.Requestcannot upload aReadableStream. requestUrl()does not expose a response body stream through this abstraction.bytes()materializes the complete response.- Streaming remote reads must be implemented above
Request, normally with multiple ranged requests. Streaming writes must either buffer the input or use a backend-specific chunked-upload protocol. - Request errors are normally thrown by
requestUrl()for HTTP status400and above. Retry behavior belongs to request middleware, not this base implementation.
Vault Request
VaultRequest is the local counterpart used by VaultFs, uses Obsidian vault cache smartly to improve performance. It is a discriminated operation function:
ts
type VaultRequest = <T extends VaultRequestParam>(
params: T,
) => Promise<VaultRequestResponseMap[T['method']]>;Supported methods are GET, GET_STREAM, PUT, APPEND, DELETE, MOVE, MKDIR, EXISTS, STAT, and LIST. The method determines both required parameters and response type.
createVaultRequest(app) captures app.vault, its DataAdapter, and app.workspace. Registrar applies local request middleware before injecting the function into VaultFs.
Path conversion
The request key uses the unified file-system key schema.
Before calling the adapter, VaultRequest removes a trailing slash from every non-root path because Obsidian paths do not use folder slashes. LIST converts returned folder paths back to the unified form.
Operation mapping
GET:adapter.readBinary(), converted toBinary.GET_STREAM: fetchesadapter.getResourcePath(path)and returnsresponse.body; throws when no body is available. File read streaming is achieved in this way.PUT:adapter.writeBinary(), convertingBinarytoArrayBufferand forwarding optionalmtime/ctimeheaders.APPEND:adapter.appendBinary()with the same conversion and headers.DELETE: permanent deletes calladapter.remove(). Otherwise it follows the vault trash setting, falling back totrashLocal()whentrashSystem()fails.MOVE:adapter.rename()to the normalized destination path.MKDIR: callsadapter.mkdir(). Creating/is a no-op.EXISTS: checksvault.getAbstractFileByPath()first, then fallback toadapter.exists(path, true).STAT: returns an stat object typed in ObsidianStat; withcachedenabled, uses cachedTFile/TFolderobjects whenworkspace.layoutReady, otherwise falls back toadapter.stat().LIST: withcachedenabled, uses cachedTFolder.childrenwhen the layout is ready and the key is not/; otherwise usesadapter.list(). Folder results are normalized with trailing slashes.
Boundary
Request abstracts HTTP transport; VaultRequest abstracts vault adapter access. Neither performs file-system policy such as retries, memory control, path flattening, or cancellation. Those behaviors are supplied by the corresponding middleware and FS wrappers.