Open curran opened 2 months ago
Some ideas from ChatGPT:
To achieve automatic synchronization between external file changes and VZCode, you can use NPM packages that allow for file system watching. Here are a few popular tools for this purpose:
chokidar: This is one of the most widely used packages for watching the file system in Node.js. It efficiently detects changes in files and directories and can trigger callbacks on events like file creation, modification, or deletion.
npm install chokidar
Example usage:
const chokidar = require('chokidar');
// Initialize watcher
const watcher = chokidar.watch('/path/to/watch', {
ignored: /(^|[\/\\])\../, // ignore dotfiles
persistent: true
});
// Add event listeners
watcher
.on('change', path => console.log(`File ${path} has been changed`))
.on('unlink', path => console.log(`File ${path} has been removed`));
fs.watch (built into Node.js): If you want a minimal solution, you can use Node.js's built-in fs.watch
method. However, it may have some limitations on certain platforms (e.g., fewer features on macOS).
Example usage:
const fs = require('fs');
fs.watch('/path/to/watch', (eventType, filename) => {
if (filename) {
console.log(`${filename} file Changed`);
}
});
node-watch: Another lightweight alternative that offers a simpler API to monitor file changes in the file system.
npm install node-watch
Example usage:
const watch = require('node-watch');
watch('/path/to/watch', { recursive: true }, function(evt, name) {
console.log('%s changed.', name);
});
nsfw (Node's simple file watcher): This is an efficient file system watcher that scales well to large file trees and is particularly known for performance.
npm install nsfw
Example usage:
const nsfw = require('nsfw');
nsfw('/path/to/watch', events => {
events.forEach(event => {
console.log(`File ${event.action} detected in ${event.directory}`);
});
}).then(watcher => watcher.start());
Any of these tools should help track external file changes and synchronize them with VZCode, allowing the desired multi-editor setup. For a balance of simplicity and power, chokidar is often the go-to choice.
This is a relevant snippet from VizHub that deals with figuring out FileIDs. We would need to consider how to get the fresh FS updates into the VZCode data structure, where the file at the same path should get the same FileID:
import { Content, Files, FileV2, FilesV2 } from 'entities';
import { v4 as uuid } from 'uuid';
// A file ID is an 8 character uuid (random characters).
let generateFileId = () => uuid().substring(0, 8);
export const setPredictableGenerateFileId = () => {
let i = 0;
generateFileId = () => {
i++;
return i.toString();
};
};
export const computeV3Files = (
goodFiles: FilesV2,
oldContentV3?: Content,
): Files => {
let getFileId: (file?: FileV2) => string = generateFileId;
// If we fork from an existing V3 viz,
// optimize the file diffs.
// Not relevant for the primordial viz.
if (oldContentV3) {
const keys = Object.keys(oldContentV3.files);
const fileIdByName = new Map<string, string>(
keys.map((fileId) => [
oldContentV3.files[fileId].name,
fileId,
]),
);
const fileIdByText = new Map<string, string>(
keys.map((fileId) => [
oldContentV3.files[fileId].text,
fileId,
]),
);
// Try to match on the name, in case text was changed (most common case).
// Try to match on the text, in case name was changed (file renamed).
// If no match, consider it a new file and mint a new file id.
getFileId = (file) =>
(file && fileIdByName.get(file.name)) ||
(file && fileIdByText.get(file.text)) ||
generateFileId();
}
const filesOutOfOrder = goodFiles.reduce(
(accumulator, file) => ({
...accumulator,
[getFileId(file)]: file,
}),
{},
);
const files = {};
// Ensure ordering of keys matches that of the files
// in the forked from viz, to minimize JSON1 OT Diff.
if (oldContentV3) {
Object.keys(oldContentV3.files).forEach((fileId) => {
if (fileId in filesOutOfOrder) {
files[fileId] = filesOutOfOrder[fileId];
}
});
}
// Get the rest, whatever wasn't in forkedFrom viz
Object.keys(filesOutOfOrder).forEach((fileId) => {
files[fileId] = filesOutOfOrder[fileId];
});
return files;
};
This is the sort of thing that we could have really solid unit tests for!
Ultimately we'd need to write a function like
updateChangedFiles(content: VZCodeContent, filesChanged: string[])
As a person using VZCode locally on my own machine, I want to be able to open and edit the same files in VSCode or other editors, and have the changes propagate automatically from the file system to VZCode, so that I can use multiple editors at once.
Current behavior: Changes only go from VZCode to the file system, not the other way.
Desired behavior: Changes made to files external to VZCode should be tracked by VZCode.