refactor: patch flushing

This commit is contained in:
cha0s 2021-01-30 20:44:40 -06:00
parent 83f3809b73
commit 4f5bbb5347
2 changed files with 45 additions and 16 deletions

View File

@ -1,7 +1,51 @@
import fs from 'fs';
import {join} from 'path';
import {promisify} from 'util';
import {decorateWithLatus} from '@latus/core'; import {decorateWithLatus} from '@latus/core';
import {applyPatch} from 'fast-json-patch';
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
export default { export default {
hooks: { hooks: {
'@latus/core/starting': (latus) => {
latus.set('%patches', []);
const flushPatches = async () => {
const patches = latus.get('%patches');
if (patches.length > 0) {
const patching = {};
while (patches.length > 0) {
const {patch, project, uri} = patches.shift();
const {decode, encode} = latus.get('%resource-controllers')(uri);
const path = join(process.cwd(), 'projects', project, uri);
if (!patching[path]) {
patching[path] = new Promise((resolve) => {
readFile(path).then((buffer) => {
resolve({
decode,
json: encode(buffer, latus),
});
});
});
}
// eslint-disable-next-line no-await-in-loop
const {json} = await patching[path];
applyPatch(json, patch);
}
const entries = Object.entries(patching);
for (let i = 0; i < entries.length; i++) {
const [path, promise] = entries[i];
// eslint-disable-next-line no-await-in-loop
const {decode, json} = await promise;
writeFile(path, decode(json, latus));
}
}
setTimeout(flushPatches, 0);
};
setTimeout(flushPatches, 0);
},
'@latus/socket/packets.decorate': decorateWithLatus( '@latus/socket/packets.decorate': decorateWithLatus(
require.context('./packets/decorators', false, /\.js$/), require.context('./packets/decorators', false, /\.js$/),
), ),

View File

@ -1,27 +1,12 @@
import fs from 'fs';
import {join} from 'path';
import {promisify} from 'util';
import {applyPatch} from 'fast-json-patch';
import {patchJsonResource} from '../../../state/json'; import {patchJsonResource} from '../../../state/json';
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
export default (Action, latus) => class ProjectAction extends Action { export default (Action, latus) => class ProjectAction extends Action {
static async respond(packet, socket) { static async respond(packet, socket) {
const {data: {type, payload}} = packet; const {data: {type, payload}} = packet;
switch (type) { switch (type) {
case patchJsonResource.toString(): { case patchJsonResource.toString(): {
const {patch, project, uri} = payload; latus.get('%patches').push(payload);
const path = join(process.cwd(), 'projects', project, uri);
const buffer = await readFile(path);
const {decode, encode} = latus.get('%resource-controllers')(uri);
const json = encode(buffer, latus);
applyPatch(json, patch);
writeFile(path, decode(json, latus));
break; break;
} }
default: default: