2023-05-23 18:53:53 +00:00
|
|
|
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
|
|
|
|
2023-05-23 18:53:53 +00:00
|
|
|
async readFile(name: string): Promise<{ data: Uint8Array; meta: FileMeta }> {
|
|
|
|
try {
|
|
|
|
return await this.primary.readFile(name);
|
2023-07-10 11:06:57 +00:00
|
|
|
} catch (e) {
|
2023-07-27 09:41:44 +00:00
|
|
|
console.info(
|
2023-07-28 16:06:49 +00:00
|
|
|
`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
|
|
|
);
|
2023-07-10 11:06:57 +00:00
|
|
|
try {
|
2023-07-28 19:22:06 +00:00
|
|
|
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);
|
2023-07-10 11:06:57 +00:00
|
|
|
// Fallback failed, so let's throw the original error
|
|
|
|
throw e;
|
|
|
|
}
|
2023-05-23 18:53:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
async getFileMeta(name: string): Promise<FileMeta> {
|
|
|
|
try {
|
|
|
|
return await this.primary.getFileMeta(name);
|
2023-07-10 11:06:57 +00:00
|
|
|
} catch (e) {
|
2023-07-27 09:41:44 +00:00
|
|
|
console.info(
|
2023-07-28 16:06:49 +00:00
|
|
|
`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
|
|
|
);
|
2023-07-10 11:06:57 +00:00
|
|
|
try {
|
2023-07-28 19:22:06 +00:00
|
|
|
const meta = await this.fallback.getFileMeta(name);
|
|
|
|
return { ...meta, neverSync: true };
|
2023-07-10 11:06:57 +00:00
|
|
|
} catch (fallbackError) {
|
2023-07-28 11:54:44 +00:00
|
|
|
console.error(
|
|
|
|
"Error during getFileMeta fallback",
|
|
|
|
fallbackError.message,
|
|
|
|
);
|
2023-07-10 11:06:57 +00:00
|
|
|
// Fallback failed, so let's throw the original error
|
|
|
|
throw e;
|
|
|
|
}
|
2023-05-23 18:53:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
writeFile(
|
|
|
|
name: string,
|
|
|
|
data: Uint8Array,
|
|
|
|
selfUpdate?: boolean | undefined,
|
2023-07-02 09:25:32 +00:00
|
|
|
meta?: FileMeta,
|
2023-05-23 18:53:53 +00:00
|
|
|
): Promise<FileMeta> {
|
2023-07-02 09:25:32 +00:00
|
|
|
return this.primary.writeFile(name, data, selfUpdate, meta);
|
2023-05-23 18:53:53 +00:00
|
|
|
}
|
|
|
|
deleteFile(name: string): Promise<void> {
|
|
|
|
return this.primary.deleteFile(name);
|
|
|
|
}
|
|
|
|
}
|