fix(git-backend): reload on publish

This commit is contained in:
Denys Konovalov 2024-12-28 16:09:27 +01:00
parent 6c77032636
commit 6750272521
Signed by: Denys Konovalov
GPG Key ID: 0037E1B0E33BD2C9
3 changed files with 81 additions and 62 deletions

View File

@ -635,8 +635,8 @@ export function loadEntry(collection: CollectionWithDefaults, slug: string, sile
try {
await dispatch(loadMedia());
const loadedEntry = await tryLoadEntry(getState(), collection, slug);
dispatch(entryLoaded(collection, loadedEntry));
dispatch(createDraftFromEntry(collection, loadedEntry));
dispatch(entryLoaded(collection, loadedEntry));
} catch (error: unknown) {
console.error(error);
if (error instanceof Error) {
@ -668,7 +668,7 @@ export async function tryLoadEntry(
}
const backend = currentBackend(configState.config);
return backend.getEntry(state, collection, configState.config, slug);
return await backend.getEntry(state, collection, configState.config, slug);
}
interface AppendAction {

View File

@ -2,25 +2,28 @@ import FS from '@isomorphic-git/lightning-fs';
import * as git from 'isomorphic-git';
import http from 'isomorphic-git/http/web';
import type { WorkflowStatus } from '@staticcms/core/constants/publishModes';
import type { AssetProxy } from '@staticcms/core/valueObjects';
import type {
Backend,
BackendClass,
BackendEntry,
Config,
ConfigWithDefaults,
Credentials,
Cursor,
DisplayURL,
ImplementationEntry,
ImplementationFile,
PersistOptions,
User,
import {
asyncLock,
runWithLock,
type AsyncLock,
type Backend,
type BackendClass,
type BackendEntry,
type Config,
type ConfigWithDefaults,
type Credentials,
type Cursor,
type DisplayURL,
type ImplementationEntry,
type ImplementationFile,
type PersistOptions,
type User,
} from '@staticcms/core';
import type { WorkflowStatus } from '@staticcms/core/constants/publishModes';
import type { AssetProxy } from '@staticcms/core/valueObjects';
const dir = '/repo';
let singleton: Promise<string[]>;
function determineRepositoryURL(backend: Backend): string {
const name = backend.name;
@ -50,7 +53,8 @@ export default function GitProxyBackEndGenerator(
fs: FS;
pfs: FS.PromisifiedFS;
repositoryUrl: string;
repository: Promise<string[]>;
lock: AsyncLock;
sha: string;
constructor(config: ConfigWithDefaults, options = {}) {
this.backend = new T(config, options);
@ -58,48 +62,63 @@ export default function GitProxyBackEndGenerator(
this.fs = new FS('decapfs');
this.pfs = this.fs.promises;
this.repositoryUrl = determineRepositoryURL(config.backend);
if (!singleton) {
singleton = this.getRepository();
}
this.repository = singleton;
this.lock = asyncLock();
this.sha = '';
}
async getRepository() {
const branch = this.config.backend.branch || 'main';
try {
await this.pfs.stat(dir);
} catch (e) {
await this.pfs.mkdir(dir);
await git.init({
fs: this.fs,
dir,
defaultBranch: branch,
});
}
await git.addRemote({
fs: this.fs,
dir,
url: this.repositoryUrl,
remote: 'origin',
force: true,
});
await git.fetch({
fs: this.fs,
http,
dir,
remote: 'origin',
ref: branch,
singleBranch: true,
depth: 1,
});
await git.checkout({
fs: this.fs,
dir,
ref: branch,
force: true,
track: false,
});
return this.pfs.readdir(dir);
return await runWithLock(
this.lock,
async () => {
const branch = this.config.backend.branch || 'main';
try {
await this.pfs.stat(dir);
} catch (e) {
await this.pfs.mkdir(dir);
await git.init({
fs: this.fs,
dir,
defaultBranch: branch,
});
}
await git.addRemote({
fs: this.fs,
dir,
url: this.repositoryUrl,
remote: 'origin',
force: true,
});
console.log('Fetching repo...');
await git.fetch({
fs: this.fs,
http,
dir,
remote: 'origin',
ref: branch,
singleBranch: true,
depth: 1,
onMessage: message => console.log(message),
});
const newSHA = await git.resolveRef({ fs: this.fs, dir, ref: `origin/${branch}` });
console.log(`Current SHA: ${this.sha}, new SHA: ${newSHA}`);
if (this.sha !== newSHA) {
console.log('Run checkout...');
await git.checkout({
fs: this.fs,
dir,
ref: `origin/${branch}`,
noUpdateHead: false,
force: true,
track: false,
onPostCheckout: post => {
this.sha = post.newHead;
console.log(`New HEAD: ${post.newHead}`);
},
});
}
},
'Failed to get async lock',
);
}
isGitBackend() {
@ -108,7 +127,7 @@ export default function GitProxyBackEndGenerator(
async entriesByFolder(folder: string, extension: string) {
try {
await this.repository;
await this.getRepository();
const files = await this.pfs.readdir(`${dir}/${folder}`);
const relevantFiles = files.filter((name: string) => name.endsWith(extension));
return Promise.all(
@ -130,7 +149,7 @@ export default function GitProxyBackEndGenerator(
}
}
async getEntry(path: string) {
await this.repository;
await this.getRepository();
let data = await this.pfs.readFile(`${dir}/${path}`, 'utf8');
if (data instanceof Uint8Array) {
data = new TextDecoder().decode(data);

View File

@ -105,10 +105,10 @@ const MediaLibraryCard: FC<MediaLibraryCardProps> = ({
}, [displayURL.url, text]);
useEffect(() => {
if (!displayURL.url) {
if (!isDirectory && !displayURL.url) {
loadDisplayURL();
}
}, [displayURL.url, loadDisplayURL]);
}, [displayURL.url, loadDisplayURL, isDirectory]);
const shortenedText = useMemo(
() =>