Sync engine (#298)

Fixes #261
This commit is contained in:
Zef Hemel
2023-01-13 15:41:29 +01:00
committed by GitHub
parent de6f531e91
commit a56e14bff1
51 changed files with 1033 additions and 1418 deletions
+40 -28
View File
@@ -1,36 +1,48 @@
import { syscall } from "./syscall.ts";
import type { FileMeta, ProxyFileSystem } from "./types.ts";
export type FileMeta = {
name: string;
lastModified: number;
};
export class LocalFileSystem implements ProxyFileSystem {
constructor(readonly root: string) {
}
export function readFile(
path: string,
encoding: "utf8" | "dataurl" = "utf8",
): Promise<string> {
return syscall("fs.readFile", path, encoding);
}
readFile(
path: string,
encoding: "utf8" | "dataurl" = "utf8",
): Promise<string> {
return syscall("fs.readFile", `${this.root}/${path}`, encoding);
}
export function getFileMeta(path: string): Promise<FileMeta> {
return syscall("fs.getFileMeta", path);
}
async getFileMeta(path: string): Promise<FileMeta> {
return this.removeRootDir(
await syscall("fs.getFileMeta", `${this.root}/${path}`),
);
}
export function writeFile(
path: string,
text: string,
encoding: "utf8" | "dataurl" = "utf8",
): Promise<FileMeta> {
return syscall("fs.writeFile", path, text, encoding);
}
writeFile(
path: string,
text: string,
encoding: "utf8" | "dataurl" = "utf8",
): Promise<FileMeta> {
return syscall("fs.writeFile", `${this.root}/${path}`, text, encoding);
}
export function deleteFile(path: string): Promise<void> {
return syscall("fs.deleteFile", path);
}
deleteFile(path: string): Promise<void> {
return syscall("fs.deleteFile", `${this.root}/${path}`);
}
export function listFiles(
dirName: string,
recursive = false,
): Promise<FileMeta[]> {
return syscall("fs.listFiles", dirName, recursive);
async listFiles(
dirName: string,
recursive = false,
): Promise<FileMeta[]> {
return (await syscall(
"fs.listFiles",
`${this.root}/${dirName}`,
recursive,
)).map(this.removeRootDir.bind(this));
}
private removeRootDir(fileMeta: FileMeta): FileMeta {
fileMeta.name = fileMeta.name.substring(this.root.length + 1);
return fileMeta;
}
}
+2 -1
View File
@@ -1,6 +1,7 @@
export * as asset from "./asset.ts";
export * as events from "./event.ts";
export * as fs from "./fs.ts";
// export * as fs from "./fs.ts";
export { LocalFileSystem } from "./fs.ts";
export * as sandbox from "./sandbox.ts";
export * as fulltext from "./fulltext.ts";
export * as shell from "./shell.ts";
+25
View File
@@ -0,0 +1,25 @@
export type FileMeta = {
name: string;
lastModified: number;
};
export interface ProxyFileSystem {
readFile(
path: string,
encoding: "utf8" | "dataurl",
): Promise<string>;
getFileMeta(path: string): Promise<FileMeta>;
writeFile(
path: string,
text: string,
encoding: "utf8" | "dataurl",
): Promise<FileMeta>;
deleteFile(path: string): Promise<void>;
listFiles(
path: string,
): Promise<FileMeta[]>;
}
+2 -1
View File
@@ -3,6 +3,7 @@ export * as editor from "./editor.ts";
export * as index from "./index.ts";
export * as markdown from "./markdown.ts";
export * as sandbox from "./sandbox.ts";
export * as space from "./space.ts";
export { default as space } from "./space.ts";
export * as system from "./system.ts";
export * as collab from "./collab.ts";
export * as sync from "./sync.ts";
+93 -65
View File
@@ -1,70 +1,98 @@
import { syscall } from "./syscall.ts";
import { AttachmentMeta, PageMeta } from "../../common/types.ts";
import { FileMeta, ProxyFileSystem } from "../plugos-syscall/types.ts";
export function listPages(unfiltered = false): Promise<PageMeta[]> {
return syscall("space.listPages", unfiltered);
export class SpaceFileSystem implements ProxyFileSystem {
// More space-specific methods
listPages(unfiltered = false): Promise<PageMeta[]> {
return syscall("space.listPages", unfiltered);
}
getPageMeta(name: string): Promise<PageMeta> {
return syscall("space.getPageMeta", name);
}
readPage(
name: string,
): Promise<string> {
return syscall("space.readPage", name);
}
writePage(name: string, text: string): Promise<PageMeta> {
return syscall("space.writePage", name, text);
}
deletePage(name: string): Promise<void> {
return syscall("space.deletePage", name);
}
listPlugs(): Promise<string[]> {
return syscall("space.listPlugs");
}
listAttachments(): Promise<PageMeta[]> {
return syscall("space.listAttachments");
}
getAttachmentMeta(name: string): Promise<AttachmentMeta> {
return syscall("space.getAttachmentMeta", name);
}
/**
* Read an attachment from the space
* @param name path of the attachment to read
* @returns the attachment data encoded as a data URL
*/
readAttachment(
name: string,
): Promise<string> {
return syscall("space.readAttachment", name);
}
/**
* Writes an attachment to the space
* @param name path of the attachment to write
* @param encoding encoding of the data ("utf8" or "dataurl)
* @param data data itself
* @returns
*/
writeAttachment(
name: string,
encoding: "utf8" | "dataurl",
data: string,
): Promise<AttachmentMeta> {
return syscall("space.writeAttachment", name, encoding, data);
}
/**
* Deletes an attachment from the space
* @param name path of the attachment to delete
*/
deleteAttachment(name: string): Promise<void> {
return syscall("space.deleteAttachment", name);
}
// Filesystem implementation
readFile(path: string, encoding: "dataurl" | "utf8"): Promise<string> {
return syscall("space.readFile", path, encoding);
}
getFileMeta(path: string): Promise<FileMeta> {
return syscall("space.getFileMeta", path);
}
writeFile(
path: string,
text: string,
encoding: "dataurl" | "utf8",
): Promise<FileMeta> {
return syscall("space.writeFile", path, text, encoding);
}
deleteFile(path: string): Promise<void> {
return syscall("space.deleteFile", path);
}
listFiles(path: string): Promise<FileMeta[]> {
return syscall("space.listFiles", path);
}
}
export function getPageMeta(name: string): Promise<PageMeta> {
return syscall("space.getPageMeta", name);
}
export function readPage(
name: string,
): Promise<string> {
return syscall("space.readPage", name);
}
export function writePage(name: string, text: string): Promise<PageMeta> {
return syscall("space.writePage", name, text);
}
export function deletePage(name: string): Promise<void> {
return syscall("space.deletePage", name);
}
export function listPlugs(): Promise<string[]> {
return syscall("space.listPlugs");
}
export function listAttachments(): Promise<PageMeta[]> {
return syscall("space.listAttachments");
}
export function getAttachmentMeta(name: string): Promise<AttachmentMeta> {
return syscall("space.getAttachmentMeta", name);
}
/**
* Read an attachment from the space
* @param name path of the attachment to read
* @returns the attachment data encoded as a data URL
*/
export function readAttachment(
name: string,
): Promise<string> {
return syscall("space.readAttachment", name);
}
/**
* Writes an attachment to the space
* @param name path of the attachment to write
* @param encoding encoding of the data ("string" or "dataurl)
* @param data data itself
* @returns
*/
export function writeAttachment(
name: string,
encoding: "string" | "dataurl",
data: string,
): Promise<AttachmentMeta> {
return syscall("space.writeAttachment", name, encoding, data);
}
/**
* Deletes an attachment from the space
* @param name path of the attachment to delete
*/
export function deleteAttachment(name: string): Promise<void> {
return syscall("space.deleteAttachment", name);
}
export default new SpaceFileSystem();
+28
View File
@@ -0,0 +1,28 @@
import type { SyncStatusItem } from "../../common/spaces/sync.ts";
import { syscall } from "./syscall.ts";
export type SyncEndpoint = {
url: string;
user?: string;
password?: string;
};
// Perform a sync with the server, based on the given status (to be persisted)
// returns a new sync status to persist
export function sync(
endpoint: SyncEndpoint,
snapshot: Record<string, SyncStatusItem>,
): Promise<
{
snapshot: Record<string, SyncStatusItem>;
operations: number;
error?: string;
}
> {
return syscall("sync.sync", endpoint, snapshot);
}
// Checks the sync endpoint for connectivity and authentication, throws and Error on failure
export function check(endpoint: SyncEndpoint): Promise<void> {
return syscall("sync.check", endpoint);
}