feat: undo/redo
This commit is contained in:
parent
025ecb72c6
commit
71d53095fb
|
@ -51,8 +51,8 @@
|
|||
show: false
|
||||
quitOnClosed: false
|
||||
window:
|
||||
- '@persea/core'
|
||||
- '...'
|
||||
- '@persea/core'
|
||||
'@flecks/governor': {}
|
||||
'@flecks/react':
|
||||
providers:
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import {patchJsonResource, replaceResource} from '@avocado/resource/persea';
|
||||
import {
|
||||
patchJsonResource,
|
||||
redo,
|
||||
replaceResource,
|
||||
undo,
|
||||
} from '@avocado/resource/persea';
|
||||
import {Hooks} from '@flecks/core';
|
||||
|
||||
import Persea from './components/persea';
|
||||
|
@ -17,14 +22,23 @@ export default {
|
|||
'@flecks/react.roots': () => Persea,
|
||||
'@flecks/redux.effects': (flecks) => {
|
||||
const withSocket = (fn) => (...args) => fn(...args.concat(flecks.get('$flecks/socket.socket')));
|
||||
return {
|
||||
[patchJsonResource]: withSocket((store, action, socket) => {
|
||||
socket.send(['Action', action]);
|
||||
}),
|
||||
[replaceResource]: withSocket((store, action, socket) => {
|
||||
socket.send(['Action', action]);
|
||||
}),
|
||||
};
|
||||
return Object.fromEntries(
|
||||
[
|
||||
patchJsonResource,
|
||||
redo,
|
||||
replaceResource,
|
||||
undo,
|
||||
]
|
||||
.map((action) => [
|
||||
action,
|
||||
withSocket((store, action, socket) => {
|
||||
if (action.meta?.isRemote) {
|
||||
return;
|
||||
}
|
||||
socket.send(['Action', action]);
|
||||
}),
|
||||
]),
|
||||
);
|
||||
},
|
||||
'@flecks/redux.slices': () => ({
|
||||
project,
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
import {patchJsonResource, replaceResource} from '@avocado/resource/persea';
|
||||
import {readFile, writeFile} from 'fs/promises';
|
||||
import {join} from 'path';
|
||||
|
||||
import {
|
||||
patchJsonResource,
|
||||
redo,
|
||||
replaceResource,
|
||||
undo,
|
||||
} from '@avocado/resource/persea';
|
||||
import {applyPatch, compare} from 'fast-json-patch';
|
||||
|
||||
export default (Action, flecks) => class ProjectAction extends Action {
|
||||
|
||||
|
@ -9,10 +18,44 @@ export default (Action, flecks) => class ProjectAction extends Action {
|
|||
flecks.get('$persea/core.patches').push(payload);
|
||||
break;
|
||||
}
|
||||
case redo.toString(): {
|
||||
const {project, uri} = payload;
|
||||
const path = join(process.cwd(), 'projects', project, uri);
|
||||
const {toBuffer, fromBuffer} = flecks.get('$avocado/resource/persea.controllers')
|
||||
.find(({matcher}) => uri.match(matcher));
|
||||
const buffer = await readFile(path);
|
||||
const json = fromBuffer(buffer, flecks);
|
||||
if (json.history?.redo?.length) {
|
||||
const patch = json.history.redo[json.history.redo.length - 1];
|
||||
socket.send(['Action', patchJsonResource({patch, project, uri}, true)]);
|
||||
applyPatch(json, patch);
|
||||
json.history.undo.push(compare(json, fromBuffer(buffer, flecks)));
|
||||
json.history.redo.pop();
|
||||
await writeFile(path, toBuffer(json, flecks));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case replaceResource.toString(): {
|
||||
flecks.get('$persea/core.replacements').push(payload);
|
||||
break;
|
||||
}
|
||||
case undo.toString(): {
|
||||
const {project, uri} = payload;
|
||||
const path = join(process.cwd(), 'projects', project, uri);
|
||||
const {toBuffer, fromBuffer} = flecks.get('$avocado/resource/persea.controllers')
|
||||
.find(({matcher}) => uri.match(matcher));
|
||||
const buffer = await readFile(path);
|
||||
const json = fromBuffer(buffer, flecks);
|
||||
if (json.history?.undo?.length) {
|
||||
const patch = json.history.undo[json.history.undo.length - 1];
|
||||
socket.send(['Action', patchJsonResource({patch, project, uri}, true)]);
|
||||
applyPatch(json, patch);
|
||||
json.history.redo.push(compare(json, fromBuffer(buffer, flecks)));
|
||||
json.history.undo.pop();
|
||||
await writeFile(path, toBuffer(json, flecks));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
return super.respond(packet, socket);
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import fs from 'fs';
|
||||
import {readFile, writeFile} from 'fs/promises';
|
||||
import {join} from 'path';
|
||||
import {promisify} from 'util';
|
||||
|
||||
import {applyPatch} from 'fast-json-patch';
|
||||
|
||||
const readFile = promisify(fs.readFile);
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
import {applyPatch, compare} from 'fast-json-patch';
|
||||
|
||||
const startFlush = (flecks) => {
|
||||
const flushPatches = async () => {
|
||||
|
@ -21,6 +17,7 @@ const startFlush = (flecks) => {
|
|||
patching[path] = new Promise((resolve) => {
|
||||
readFile(path).then((buffer) => {
|
||||
resolve({
|
||||
fromBuffer,
|
||||
toBuffer,
|
||||
json: fromBuffer(buffer, flecks),
|
||||
});
|
||||
|
@ -34,7 +31,12 @@ const startFlush = (flecks) => {
|
|||
await Promise.all(
|
||||
Object.entries(patching)
|
||||
.map(async ([path, promise]) => {
|
||||
const {toBuffer, json} = await promise;
|
||||
const {fromBuffer, toBuffer, json} = await promise;
|
||||
const buffer = await readFile(path);
|
||||
const undo = compare(json, fromBuffer(buffer, flecks));
|
||||
json.history = json.history || {redo: [], undo: []};
|
||||
json.history.redo = [];
|
||||
json.history.undo.push(undo);
|
||||
return writeFile(path, toBuffer(json, flecks));
|
||||
}),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue
Block a user