Add push operations to plugin
This commit is contained in:
parent
a2066cfc1c
commit
9ce8245abc
7 changed files with 78 additions and 53 deletions
|
|
@ -90,14 +90,17 @@ export class Database {
|
||||||
relativePath,
|
relativePath,
|
||||||
documentId,
|
documentId,
|
||||||
parentVersionId,
|
parentVersionId,
|
||||||
|
hash,
|
||||||
}: {
|
}: {
|
||||||
relativePath: RelativePath;
|
relativePath: RelativePath;
|
||||||
documentId: DocumentId;
|
documentId: DocumentId;
|
||||||
parentVersionId: DocumentVersionId;
|
parentVersionId: DocumentVersionId;
|
||||||
|
hash: string;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
this._documents.set(relativePath, {
|
this._documents.set(relativePath, {
|
||||||
documentId,
|
documentId,
|
||||||
parentVersionId,
|
parentVersionId,
|
||||||
|
hash,
|
||||||
});
|
});
|
||||||
await this.save();
|
await this.save();
|
||||||
}
|
}
|
||||||
|
|
@ -107,16 +110,19 @@ export class Database {
|
||||||
relativePath,
|
relativePath,
|
||||||
documentId,
|
documentId,
|
||||||
parentVersionId,
|
parentVersionId,
|
||||||
|
hash,
|
||||||
}: {
|
}: {
|
||||||
oldRelativePath: RelativePath;
|
oldRelativePath: RelativePath;
|
||||||
relativePath: RelativePath;
|
relativePath: RelativePath;
|
||||||
documentId: DocumentId;
|
documentId: DocumentId;
|
||||||
parentVersionId: DocumentVersionId;
|
parentVersionId: DocumentVersionId;
|
||||||
|
hash: string;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
this._documents.delete(oldRelativePath);
|
this._documents.delete(oldRelativePath);
|
||||||
this._documents.set(relativePath, {
|
this._documents.set(relativePath, {
|
||||||
documentId,
|
documentId,
|
||||||
parentVersionId,
|
parentVersionId,
|
||||||
|
hash,
|
||||||
});
|
});
|
||||||
await this.save();
|
await this.save();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,5 @@ export type RelativePath = string;
|
||||||
export interface DocumentMetadata {
|
export interface DocumentMetadata {
|
||||||
documentId: DocumentId;
|
documentId: DocumentId;
|
||||||
parentVersionId: DocumentVersionId;
|
parentVersionId: DocumentVersionId;
|
||||||
|
hash: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as plugin from "../../../backend/sync_lib/pkg/sync_lib.js";
|
import * as lib from "../../../backend/sync_lib/pkg/sync_lib.js";
|
||||||
|
|
||||||
import createClient, { Client } from "openapi-fetch";
|
import createClient, { Client } from "openapi-fetch";
|
||||||
import type { components, paths } from "./types"; // generated by openapi-typescript
|
import type { components, paths } from "./types"; // generated by openapi-typescript
|
||||||
|
|
@ -48,14 +48,13 @@ export class SyncServer {
|
||||||
|
|
||||||
public async create({
|
public async create({
|
||||||
relativePath,
|
relativePath,
|
||||||
content,
|
contentBytes,
|
||||||
createdDate,
|
createdDate,
|
||||||
}: {
|
}: {
|
||||||
content: ArrayBuffer;
|
contentBytes: Uint8Array;
|
||||||
relativePath: string;
|
relativePath: string;
|
||||||
createdDate: Date;
|
createdDate: Date;
|
||||||
}): Promise<components["schemas"]["DocumentVersion"]> {
|
}): Promise<components["schemas"]["DocumentVersion"]> {
|
||||||
let contentBytes = new Uint8Array(content);
|
|
||||||
let response = await this.client.POST("/vaults/{vault_id}/documents", {
|
let response = await this.client.POST("/vaults/{vault_id}/documents", {
|
||||||
params: {
|
params: {
|
||||||
path: { vault_id: SyncServer.VAULT_ID },
|
path: { vault_id: SyncServer.VAULT_ID },
|
||||||
|
|
@ -65,9 +64,8 @@ export class SyncServer {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
body: {
|
body: {
|
||||||
contentBase64: plugin.bytes_to_base64(contentBytes),
|
contentBase64: lib.bytes_to_base64(contentBytes),
|
||||||
createdDate: createdDate.toISOString(),
|
createdDate: createdDate.toISOString(),
|
||||||
isBinary: plugin.is_binary(contentBytes),
|
|
||||||
relativePath,
|
relativePath,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -87,17 +85,15 @@ export class SyncServer {
|
||||||
documentId,
|
documentId,
|
||||||
parentVersionId,
|
parentVersionId,
|
||||||
relativePath,
|
relativePath,
|
||||||
content,
|
contentBytes,
|
||||||
createdDate,
|
createdDate,
|
||||||
}: {
|
}: {
|
||||||
documentId: DocumentId;
|
documentId: DocumentId;
|
||||||
parentVersionId: DocumentVersionId;
|
parentVersionId: DocumentVersionId;
|
||||||
relativePath: string;
|
relativePath: string;
|
||||||
content: ArrayBuffer;
|
contentBytes: Uint8Array;
|
||||||
createdDate: Date;
|
createdDate: Date;
|
||||||
}): Promise<components["schemas"]["DocumentVersion"]> {
|
}): Promise<components["schemas"]["DocumentVersion"]> {
|
||||||
let contentBytes = new Uint8Array(content);
|
|
||||||
|
|
||||||
let response = await this.client.PUT(
|
let response = await this.client.PUT(
|
||||||
"/vaults/{vault_id}/documents/{document_id}",
|
"/vaults/{vault_id}/documents/{document_id}",
|
||||||
{
|
{
|
||||||
|
|
@ -113,9 +109,8 @@ export class SyncServer {
|
||||||
},
|
},
|
||||||
body: {
|
body: {
|
||||||
parentVersionId,
|
parentVersionId,
|
||||||
contentBase64: plugin.bytes_to_base64(contentBytes),
|
contentBase64: lib.bytes_to_base64(contentBytes),
|
||||||
createdDate: createdDate.toISOString(),
|
createdDate: createdDate.toISOString(),
|
||||||
isBinary: plugin.is_binary(contentBytes),
|
|
||||||
relativePath,
|
relativePath,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { TFile } from "obsidian";
|
|
||||||
import { Database } from "src/database/database";
|
import { Database } from "src/database/database";
|
||||||
import { RelativePath } from "src/database/document-metadata";
|
import { RelativePath } from "src/database/document-metadata";
|
||||||
import { SyncServer } from "src/services/sync_service";
|
import { SyncServer } from "src/services/sync_service";
|
||||||
|
|
@ -15,7 +14,8 @@ export async function syncLocallyDeletedFile(
|
||||||
|
|
||||||
await syncServer.delete({
|
await syncServer.delete({
|
||||||
documentId: metadata.documentId,
|
documentId: metadata.documentId,
|
||||||
createdDate: new Date(), // We got the event now, so it must have been deleted now
|
// We got the event now, so it must have been deleted just now
|
||||||
|
createdDate: new Date(),
|
||||||
});
|
});
|
||||||
|
|
||||||
await database.removeDocument(path);
|
await database.removeDocument(path);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
|
import * as lib from "../../../backend/sync_lib/pkg/sync_lib.js";
|
||||||
import { TFile } from "obsidian";
|
import { TFile } from "obsidian";
|
||||||
import { Database } from "src/database/database";
|
import { Database } from "src/database/database";
|
||||||
|
import { Logger } from "src/logger";
|
||||||
import { SyncServer } from "src/services/sync_service";
|
import { SyncServer } from "src/services/sync_service";
|
||||||
|
import { hash } from "src/utils";
|
||||||
|
|
||||||
export async function syncLocallyRenamedFile(
|
export async function syncLocallyRenamedFile(
|
||||||
database: Database,
|
database: Database,
|
||||||
|
|
@ -13,18 +16,42 @@ export async function syncLocallyRenamedFile(
|
||||||
throw `Document metadata not found for ${oldPath}`;
|
throw `Document metadata not found for ${oldPath}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await syncServer.update({
|
const contentBytes = new Uint8Array(await file.vault.readBinary(file));
|
||||||
|
const responsePromise = syncServer.update({
|
||||||
documentId: metadata.documentId,
|
documentId: metadata.documentId,
|
||||||
parentVersionId: metadata.parentVersionId,
|
parentVersionId: metadata.parentVersionId,
|
||||||
relativePath: file.path,
|
relativePath: file.path,
|
||||||
content: await file.vault.readBinary(file),
|
contentBytes,
|
||||||
createdDate: new Date(file.stat.ctime),
|
createdDate: new Date(file.stat.ctime),
|
||||||
});
|
});
|
||||||
|
|
||||||
await database.moveDocument({
|
const contentHash = hash(contentBytes);
|
||||||
|
const response = await responsePromise;
|
||||||
|
|
||||||
|
const localDbUpdatePromise = database.moveDocument({
|
||||||
oldRelativePath: oldPath,
|
oldRelativePath: oldPath,
|
||||||
relativePath: file.path,
|
relativePath: file.path,
|
||||||
documentId: response.documentId,
|
documentId: response.documentId,
|
||||||
parentVersionId: response.versionId,
|
parentVersionId: response.versionId,
|
||||||
|
hash: contentHash,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (file.path !== response.relativePath) {
|
||||||
|
await file.vault.rename(file, response.relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newContentBytes = new Uint8Array(await file.vault.readBinary(file));
|
||||||
|
const responseBytes = lib.base64_to_bytes(response.contentBase64);
|
||||||
|
|
||||||
|
if (contentBytes !== newContentBytes) {
|
||||||
|
Logger.getInstance().info(
|
||||||
|
`Content changed since sending original update request for ${file.path}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = lib.merge(contentBytes, newContentBytes, responseBytes);
|
||||||
|
|
||||||
|
await file.vault.modifyBinary(file, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
await localDbUpdatePromise;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,13 @@
|
||||||
import { TFile } from "obsidian";
|
import { TFile } from "obsidian";
|
||||||
import { Database } from "src/database/database";
|
import { Database } from "src/database/database";
|
||||||
import { SyncServer } from "src/services/sync_service";
|
import { SyncServer } from "src/services/sync_service";
|
||||||
|
import { hash } from "src/utils";
|
||||||
|
import { syncLocallyRenamedFile } from "./sync-locally-renamed-file";
|
||||||
|
|
||||||
export async function syncLocallyUpdatedFile(
|
export async function syncLocallyUpdatedFile(
|
||||||
database: Database,
|
database: Database,
|
||||||
syncServer: SyncServer,
|
syncServer: SyncServer,
|
||||||
file: TFile
|
file: TFile
|
||||||
) {
|
) {
|
||||||
const metadata = database.getDocument(file.path);
|
syncLocallyRenamedFile(database, syncServer, file, file.path);
|
||||||
if (!metadata) {
|
|
||||||
throw `Document metadata not found for ${file.path}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await syncServer.update({
|
|
||||||
documentId: metadata.documentId,
|
|
||||||
parentVersionId: metadata.parentVersionId,
|
|
||||||
relativePath: file.path,
|
|
||||||
content: await file.vault.readBinary(file),
|
|
||||||
createdDate: new Date(file.stat.ctime),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (file.path !== response.relativePath) {
|
|
||||||
file.vault.rename(file, response.relativePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((await file.vault.read(file)) !== response.contentBase64) {
|
|
||||||
// todo - reconcile
|
|
||||||
}
|
|
||||||
|
|
||||||
await database.setDocument({
|
|
||||||
relativePath: file.path,
|
|
||||||
documentId: response.documentId,
|
|
||||||
parentVersionId: response.versionId,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,48 @@
|
||||||
|
import * as lib from "../../../backend/sync_lib/pkg/sync_lib.js";
|
||||||
import { TFile } from "obsidian";
|
import { TFile } from "obsidian";
|
||||||
import { Database } from "src/database/database";
|
import { Database } from "src/database/database";
|
||||||
|
import { Logger } from "src/logger.js";
|
||||||
import { SyncServer } from "src/services/sync_service";
|
import { SyncServer } from "src/services/sync_service";
|
||||||
|
import { hash } from "src/utils";
|
||||||
|
|
||||||
export async function syncNewLocalFile(
|
export async function syncNewLocalFile(
|
||||||
database: Database,
|
database: Database,
|
||||||
syncServer: SyncServer,
|
syncServer: SyncServer,
|
||||||
file: TFile
|
file: TFile
|
||||||
) {
|
) {
|
||||||
const response = await syncServer.create({
|
const contentBytes = new Uint8Array(await file.vault.readBinary(file));
|
||||||
|
const responsePromise = syncServer.create({
|
||||||
relativePath: file.path,
|
relativePath: file.path,
|
||||||
content: await file.vault.readBinary(file),
|
contentBytes,
|
||||||
createdDate: new Date(file.stat.ctime),
|
createdDate: new Date(file.stat.ctime),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (file.path !== response.relativePath) {
|
const contentHash = hash(contentBytes);
|
||||||
file.vault.rename(file, response.relativePath);
|
const response = await responsePromise;
|
||||||
}
|
|
||||||
|
|
||||||
if ((await file.vault.read(file)) !== response.contentBase64) {
|
const localDbUpdatePromise = database.setDocument({
|
||||||
// todo - reconcile
|
|
||||||
}
|
|
||||||
|
|
||||||
await database.setDocument({
|
|
||||||
relativePath: response.relativePath,
|
relativePath: response.relativePath,
|
||||||
documentId: response.documentId,
|
documentId: response.documentId,
|
||||||
parentVersionId: response.versionId,
|
parentVersionId: response.versionId,
|
||||||
|
hash: contentHash,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (file.path !== response.relativePath) {
|
||||||
|
await file.vault.rename(file, response.relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newContentBytes = new Uint8Array(await file.vault.readBinary(file));
|
||||||
|
const responseBytes = lib.base64_to_bytes(response.contentBase64);
|
||||||
|
|
||||||
|
if (contentBytes !== newContentBytes) {
|
||||||
|
Logger.getInstance().info(
|
||||||
|
`Content changed since sending original create request for ${file.path}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = lib.merge(contentBytes, newContentBytes, responseBytes);
|
||||||
|
|
||||||
|
await file.vault.modifyBinary(file, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
await localDbUpdatePromise;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue