diff --git a/packages/core/src/server/packets/decorators/action.js b/packages/core/src/server/packets/decorators/action.js index 56a017d..4acc446 100644 --- a/packages/core/src/server/packets/decorators/action.js +++ b/packages/core/src/server/packets/decorators/action.js @@ -26,10 +26,10 @@ export default (Action, flecks) => class ProjectAction extends Action { 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]; + const {group, patch} = json.history.redo.at(-1); socket.send(['Action', patchJsonResource({patch, project, uri}, true)]); applyPatch(json, patch); - json.history.undo.push(compare(json, fromBuffer(buffer, flecks))); + json.history.undo.push({group, patch: compare(json, fromBuffer(buffer, flecks))}); json.history.redo.pop(); await writeFile(path, toBuffer(json, flecks)); } @@ -47,10 +47,10 @@ export default (Action, flecks) => class ProjectAction extends Action { 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]; + const {group, patch} = json.history.undo.at(-1); socket.send(['Action', patchJsonResource({patch, project, uri}, true)]); applyPatch(json, patch); - json.history.redo.push(compare(json, fromBuffer(buffer, flecks))); + json.history.redo.push({group, patch: compare(json, fromBuffer(buffer, flecks))}); json.history.undo.pop(); await writeFile(path, toBuffer(json, flecks)); } diff --git a/packages/core/src/server/start-flush.js b/packages/core/src/server/start-flush.js index 528beda..260e125 100644 --- a/packages/core/src/server/start-flush.js +++ b/packages/core/src/server/start-flush.js @@ -7,39 +7,37 @@ const startFlush = (flecks) => { const flushPatches = async () => { const patches = flecks.get('$persea/core.patches'); if (patches.length > 0) { - const patching = {}; while (patches.length > 0) { - const {patch, project, uri} = patches.shift(); + const { + group, + patch, + project, + uri, + } = patches.shift(); const path = join(process.cwd(), 'projects', project, uri); - if (!patching[path]) { - const {toBuffer, fromBuffer} = flecks.get('$avocado/resource/persea.controllers') - .find(({matcher}) => uri.match(matcher)); - patching[path] = new Promise((resolve) => { - readFile(path).then((buffer) => { - resolve({ - fromBuffer, - toBuffer, - json: fromBuffer(buffer, flecks), - }); - }); - }); - } + // Get controller. + const {toBuffer, fromBuffer} = flecks.get('$avocado/resource/persea.controllers') + .find(({matcher}) => uri.match(matcher)); + // Load. // eslint-disable-next-line no-await-in-loop - const {json} = await patching[path]; + const buffer = await readFile(path); + const json = fromBuffer(buffer, flecks); + // Patch. applyPatch(json, patch); + // Manage history. + const undo = compare(json, fromBuffer(buffer, flecks)); + json.history = json.history || {redo: [], undo: []}; + json.history.redo = []; + if ( + 0 === json.history.undo.length + || group !== json.history.undo.at(-1).group + ) { + json.history.undo.push({group, patch: undo}); + } + // Flush. + // eslint-disable-next-line no-await-in-loop + await writeFile(path, toBuffer(json, flecks)); } - await Promise.all( - Object.entries(patching) - .map(async ([path, 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)); - }), - ); } setTimeout(flushPatches, 0); };