1
0

API refinements

This commit is contained in:
Zef Hemel 2023-08-15 20:15:27 +02:00
parent 5cf97272c1
commit 7cce83b240
4 changed files with 21 additions and 7 deletions

View File

@ -163,7 +163,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
: +res.headers.get("Content-Length")!,
contentType: res.headers.get("Content-type")!,
lastModified: +(res.headers.get("X-Last-Modified") || "0"),
perm: (res.headers.get("X-Permission") as "rw" | "ro") || "rw",
perm: (res.headers.get("X-Permission") as "rw" | "ro") || "ro",
};
}

View File

@ -182,8 +182,13 @@ export async function deleteFile(
export async function getFileMeta(name: string): Promise<FileMeta> {
const url = federatedPathToUrl(name);
console.log("Fetching federation file meta", url);
const r = await nativeFetch(url, { method: "HEAD" });
console.info("Fetching federation file meta", url);
const r = await nativeFetch(url, {
method: "GET",
headers: {
"X-Get-Meta": "true",
},
});
if (r.status === 503) {
throw new Error("Offline");
}

View File

@ -245,6 +245,16 @@ export class SyncService {
}
try {
remoteHash = (await this.remoteSpace!.getFileMeta(name)).lastModified;
if (!remoteHash) {
console.info(
"Not syncing file, because remote didn't send X-Last-Modified header",
);
// This happens when the remote isn't a real SilverBullet server, specifically: it's not sending
// a X-Last-Modified header. In this case we'll just assume that the file is up to date.
await this.registerSyncStop(false);
// Jumping out, not saving snapshot nor triggering a sync event, because we did nothing
return;
}
} catch (e: any) {
if (e.message === "Not found") {
// File doesn't exist remotely, that's ok
@ -264,7 +274,6 @@ export class SyncService {
}
await this.saveSnapshot(snapshot);
await this.registerSyncStop(false);
// console.log("And done with file sync for", name);
}
async saveSnapshot(snapshot: Map<string, SyncStatusItem>) {

View File

@ -1,13 +1,13 @@
The server API is relatively small. The client primarily communicates with the server for file “CRUD” (Create, Read, Update, Delete) style operations.
All API requests from the client will always have the `X-Sync-Mode` header set to `true`. The server may use this fact to distinguish between requests coming from the client and regular e.g. `GET` requests from the browser (through navigation) and redirect appropriately (for instance to the UI URL associated with a specific `.md` file).
All API requests from the client will always set the `X-Sync-Mode` request header set to `true`. The server may use this fact to distinguish between requests coming from the client and regular e.g. `GET` requests from the browser (through navigation) and redirect appropriately (for instance to the UI URL associated with a specific `.md` file).
The API:
* `GET /index.json` will return a full listing of all files in your space including metadata like when the file was last modified, as well as permissions. This is primarily used for sync purposes with the client.
* `GET /*.*`: _Reads_ and returns the content of the file at the given path. This means that if you `GET /index.md` you will receive the content of your `index` page. If the the optional `X-Get-Meta` _request header_ is set, the server does not _need to_ return the body of the file (but it can). The `GET` _response_ will have a few additional SB-specific headers:
* `X-Last-Modified` as a UNIX timestamp in ms (as coming from `Data.now()`)
* `X-Permission`: either `rw` or `ro` which will change whether the editor opens in read-only or regular mode.
* (optional) `X-Last-Modified` the last modified time of the file as a UNIX timestamp in ms since the epoch (as coming from `Data.now()`). This timestamp _has_ to match the `lastModified` listed for this file in `/index.json` otherwise syncing issues may occur. When this header is missing, frequent polling-based sync will be disabled for this file.
* (optional) `X-Permission`: either `rw` or `ro` which will change whether the editor opens in read-only or edit mode. When missing, `ro` is assumed.
* (optional) `X-Content-Length`: which will be the same as `Content-Length` except if the request was sent with a `X-Get-Meta` header and the body is not returned (then `Content-Length` will be `0` and `X-Content-Length` will be the size of the file)
* `PUT /*.*`: The same as `GET` except that it takes the body of the request and _writes_ it to a file.
* `DELETE /*.*`: Again the same, except this will _delete_ the given file.