1
0
silverbullet/common/spaces/fallback_space_primitives.ts

75 lines
2.3 KiB
TypeScript
Raw Normal View History

import { FileMeta } from "../types.ts";
import type { SpacePrimitives } from "./space_primitives.ts";
/**
* FallbackSpacePrimitives is a SpacePrimitives implementation that will try to fall back to another SpacePrimitives implementation for two
* operations:
* - readFile
* - getFileMeta
* The use case is primarily sync: when sync hasn't completed yet, we can fall back to HttpSpacePrimitives to fetch the file from the server.
*/
export class FallbackSpacePrimitives implements SpacePrimitives {
constructor(
private primary: SpacePrimitives,
private fallback: SpacePrimitives,
) {
}
fetchFileList(): Promise<FileMeta[]> {
return this.primary.fetchFileList();
}
2023-07-27 09:41:44 +00:00
async readFile(name: string): Promise<{ data: Uint8Array; meta: FileMeta }> {
try {
return await this.primary.readFile(name);
} catch (e) {
2023-07-27 09:41:44 +00:00
console.info(
`Could not read file ${name} from primary, trying fallback, primary read error:`,
2023-07-28 11:54:44 +00:00
e.message,
2023-07-27 09:41:44 +00:00
);
try {
const result = await this.fallback.readFile(name);
return {
data: result.data,
meta: { ...result.meta, neverSync: true },
};
2023-07-27 09:41:44 +00:00
} catch (fallbackError: any) {
2023-07-28 11:54:44 +00:00
console.error("Error during readFile fallback", fallbackError.message);
// Fallback failed, so let's throw the original error
throw e;
}
}
}
async getFileMeta(name: string): Promise<FileMeta> {
try {
return await this.primary.getFileMeta(name);
} catch (e) {
2023-07-27 09:41:44 +00:00
console.info(
`Could not fetch file ${name} metadata from primary, trying fallback, primary read error`,
2023-07-28 11:54:44 +00:00
e.message,
2023-07-27 09:41:44 +00:00
);
try {
const meta = await this.fallback.getFileMeta(name);
return { ...meta, neverSync: true };
} catch (fallbackError) {
2023-07-28 11:54:44 +00:00
console.error(
"Error during getFileMeta fallback",
fallbackError.message,
);
// Fallback failed, so let's throw the original error
throw e;
}
}
}
writeFile(
name: string,
data: Uint8Array,
selfUpdate?: boolean | undefined,
meta?: FileMeta,
): Promise<FileMeta> {
return this.primary.writeFile(name, data, selfUpdate, meta);
}
deleteFile(name: string): Promise<void> {
return this.primary.deleteFile(name);
}
}