Skip to content

Commit 14adb17

Browse files
committed
feat: fs.watch apis for filer and fs access paths
1 parent c478fe3 commit 14adb17

File tree

10 files changed

+317
-251
lines changed

10 files changed

+317
-251
lines changed

dist/virtualfs.js

Lines changed: 100 additions & 94 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/virtualfs.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/constants.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ const Constants = {
3333
MOUNT_POINT_ROOT: '/mnt',
3434
TAURI_ROOT: "/tauri",
3535
BINARY_ENCODING: "binary",
36-
BYTE_ARRAY_ENCODING: "byte_array"
36+
BYTE_ARRAY_ENCODING: "byte_array",
37+
WATCH_EVENTS: {
38+
ADD_FILE: "add",
39+
ADD_DIR: "addDir",
40+
CHANGE: "change",
41+
UNLINK_FILE: "unlink",
42+
UNLINK_DIR: "unlinkDir"
43+
}
3744
};
3845

3946
module.exports ={

src/fslib.js

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,15 @@ const fileSystemLib = {
140140
},
141141
writeFile: function (...args) { // (path, data, options, callback)
142142
let path = args[0];
143+
let newFileCreated = false;
143144
function callbackInterceptor(...interceptedArgs) {
144145
let err = interceptedArgs.length >= 1 ? interceptedArgs[0] : null;
145146
if(!err){
146-
FsWatch.reportChangeEvent(path);
147+
if(newFileCreated){
148+
FsWatch.reportCreateEvent(path, false);
149+
} else {
150+
FsWatch.reportChangeEvent(path);
151+
}
147152
}
148153
if(args.originalCallback){
149154
args.originalCallback(...interceptedArgs);
@@ -157,17 +162,23 @@ const fileSystemLib = {
157162

158163
if(TauriFS.isTauriSubPath(path)) {
159164
return TauriFS.writeFile(...args);
160-
} else if(Mounts.isMountSubPath(path)) {
161-
return NativeFS.writeFile(...args);
162165
}
163-
return FilerFSModified.writeFile(...args);
166+
fileSystemLib.stat(path, (err)=>{
167+
if(err && err.code === ERR_CODES.ERROR_CODES.ENOENT){
168+
newFileCreated = true;
169+
}
170+
if(Mounts.isMountSubPath(path)) {
171+
return NativeFS.writeFile(...args);
172+
}
173+
return FilerFSModified.writeFile(...args);
174+
});
164175
},
165176
mkdir: function (...args) { // (path, mode, callback)
166177
let path = args[0];
167178
function callbackInterceptor(...interceptedArgs) {
168179
let err = interceptedArgs.length >= 1 ? interceptedArgs[0] : null;
169180
if(!err){
170-
FsWatch.reportCreateEvent(path);
181+
FsWatch.reportCreateEvent(path, true);
171182
}
172183
if(args.originalCallback){
173184
args.originalCallback(...interceptedArgs);
@@ -191,8 +202,18 @@ const fileSystemLib = {
191202
function callbackInterceptor(...args) {
192203
let err = args.length >= 1 ? args[0] : null;
193204
if(!err){
194-
FsWatch.reportUnlinkEvent(oldPath);
195-
FsWatch.reportCreateEvent(newPath);
205+
if(!TauriFS.isTauriSubPath(oldPath) || !TauriFS.isTauriSubPath(newPath)) {
206+
// we only need to manually handle watch events for non tauri paths as tauri watch is done at node
207+
fileSystemLib.stat(newPath, (err, stat)=>{
208+
const isDir = !err && stat.isDirectory();
209+
if(!TauriFS.isTauriSubPath(oldPath)) {
210+
FsWatch.reportUnlinkEvent(oldPath, isDir);
211+
}
212+
if(!TauriFS.isTauriSubPath(newPath)) {
213+
FsWatch.reportCreateEvent(newPath, isDir);
214+
}
215+
});
216+
}
196217
}
197218
if(cb){
198219
cb(...args);
@@ -224,10 +245,11 @@ const fileSystemLib = {
224245
});
225246
},
226247
unlink: function (path, cb) {
248+
let isDir;
227249
function callbackInterceptor(...args) {
228250
let err = args.length >= 1 ? args[0] : null;
229251
if(!err){
230-
FsWatch.reportUnlinkEvent(path);
252+
FsWatch.reportUnlinkEvent(path, isDir);
231253
}
232254
if(cb){
233255
cb(...args);
@@ -239,20 +261,30 @@ const fileSystemLib = {
239261
return ;
240262
} else if(TauriFS.isTauriSubPath(path)) {
241263
return TauriFS.unlink(path, callbackInterceptor);
242-
} else if(Mounts.isMountSubPath(path)) {
243-
return NativeFS.unlink(path, callbackInterceptor);
244-
}
245-
if (typeof path !== 'string') {
246-
callbackInterceptor(new Errors.EINVAL('Invalid arguments.'));
247-
return;
248264
}
249-
return filerShell.rm(path, { recursive: true }, callbackInterceptor);
265+
266+
fileSystemLib.stat(path, (err, stat)=>{
267+
isDir = !err && stat.isDirectory();
268+
// we do this to emit fs watch events for non-tauri path unlinks.
269+
// We only need to manually handle watch events for non tauri paths as tauri watch is done at node
270+
if(Mounts.isMountSubPath(path)) {
271+
return NativeFS.unlink(path, callbackInterceptor);
272+
}
273+
if (typeof path !== 'string') {
274+
callbackInterceptor(new Errors.EINVAL('Invalid arguments.'));
275+
return;
276+
}
277+
return filerShell.rm(path, { recursive: true }, callbackInterceptor);
278+
});
250279
},
251280
copy: function (src, dst, cb) {
252281
function callbackInterceptor(...args) {
253282
let err = args.length >= 1 ? args[0] : null;
254283
if(!err){
255-
FsWatch.reportCreateEvent(dst);
284+
fileSystemLib.stat(dst, (err, stat)=>{
285+
const isDir = !err && stat.isDirectory();
286+
FsWatch.reportCreateEvent(dst, isDir);
287+
});
256288
}
257289
if(cb){
258290
cb(...args);
@@ -293,15 +325,6 @@ const fileSystemLib = {
293325
}
294326
return FsWatch.unwatchAsync(eventEmitter);
295327
},
296-
watch: function (...args) {
297-
return FsWatch.watch(...args);
298-
},
299-
unwatch: function (...args) {
300-
return FsWatch.unwatch(...args);
301-
},
302-
unwatchAll: function (...args) {
303-
return FsWatch.unwatchAll(...args);
304-
},
305328
moveToTrash: function () {
306329
throw new Errors.ENOSYS('Phoenix fs moveToTrash function not yet supported.');
307330
},
@@ -356,13 +379,7 @@ const fileSystemLib = {
356379
MOUNT_POINT_ROOT: Constants.MOUNT_POINT_ROOT,
357380
TAURI_ROOT: Constants.TAURI_ROOT,
358381
ERR_CODES: {},
359-
WATCH_EVENTS: {
360-
ADD_FILE: "add",
361-
ADD_DIR: "addDir",
362-
CHANGE: "change",
363-
UNLINK_FILE: "unlink",
364-
UNLINK_DIR: "unlinkDir"
365-
},
382+
WATCH_EVENTS: Constants.WATCH_EVENTS,
366383
isEncodingSupported: function (encoding) {
367384
if(encoding.toLowerCase() === Constants.BYTE_ARRAY_ENCODING){
368385
return true;

src/fslib_native.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ async function _mkdir(parentDirHandle, dirName, callback) {
7474
return childDirHandle;
7575
} catch (e) {
7676
if(callback){
77-
callback(new Errors.EIO('Filer native fs function not yet supported.', e));
77+
callback(new Errors.EIO('Filer native fs.mkdir failed.', e));
78+
return ;
7879
}
7980
throw new Errors.EIO('Filer native fs function not yet supported.', e);
8081
}

src/fslib_node_ws.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ function unlink(path, callback) {
493493
/**
494494
*
495495
* @param {string} path
496-
* @param {string} gitIgnorePaths The contents of the gitIgnore file as text. The watcher will ignore all files matching git ignore.
496+
* @param {string|Array<string>} gitIgnorePaths The contents of the gitIgnore file as text. The watcher will ignore all files matching git ignore.
497497
* @returns {Promise<EventEmitter>} That will be resolved with a watcher once the watcher is ready.
498498
*/
499499
async function watchAsync(path, gitIgnorePaths="") {

src/fslib_tauri.js

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,46 +26,10 @@ const {Errors, ERR_CODES} = require("./errno");
2626
const {Utils} = require("./utils");
2727
const {NodeTauriFS} = require("./fslib_node_ws");
2828

29-
const TAURI_PATH_PREFIX = Constants.TAURI_ROOT+ '/';
3029
const IS_WINDOWS = navigator.userAgent.includes('Windows');
3130
let preferNodeWs = false,
3231
forceNodeWs = false;
3332

34-
/**
35-
* Check if the given path is a subpath of the '/tauri' folder.
36-
* @param path
37-
*/
38-
function isTauriSubPath(path) {
39-
if (typeof path !== 'string') {
40-
return false;
41-
}
42-
if (path) {
43-
path = globalObject.path.normalize(path);
44-
if (path.startsWith(TAURI_PATH_PREFIX) && path.length > TAURI_PATH_PREFIX.length) {
45-
return true;
46-
}
47-
}
48-
return false;
49-
}
50-
51-
/**
52-
* Check if the given path is '/tauri' folder.
53-
* @param path
54-
*/
55-
function isTauriPath(path) {
56-
if (typeof path !== 'string') {
57-
return false;
58-
}
59-
if (path) {
60-
path = globalObject.path.normalize(path);
61-
if (path === Constants.TAURI_ROOT) {
62-
return true;
63-
}
64-
}
65-
return false;
66-
}
67-
68-
6933
/**
7034
* Opens the Tauri file picker asynchronously with given options. If options aren't provided, defaults to picking a single file.
7135
* If the `defaultPath` option isn't provided, it will default to the user's document directory.
@@ -637,8 +601,8 @@ function preferNodeWSEndpoint(use) {
637601
}
638602

639603
const TauriFS = {
640-
isTauriPath,
641-
isTauriSubPath,
604+
isTauriPath: Utils.isTauriPath,
605+
isTauriSubPath: Utils.isTauriSubPath,
642606
getTauriPlatformPath: Utils.getTauriPlatformPath,
643607
getTauriVirtualPath: Utils.getTauriVirtualPath,
644608
openTauriFilePickerAsync,

0 commit comments

Comments
 (0)