diff --git a/index.js b/index.js index 8f76d311..5a637369 100644 --- a/index.js +++ b/index.js @@ -5,16 +5,13 @@ let dir = process.cwd(); async function run() { try { - let token = fs.readFileSync(dir + '/token.txt', 'utf8'); - let changes = await fschanges.getEventsSince(dir, token); + let changes = await fschanges.getEventsSince(dir, dir + '/token.txt'); console.log(changes); } catch (err) { console.log(err) } - let token = await fschanges.getCurrentToken(dir); - console.log('token', token) - fs.writeFileSync(dir + '/token.txt', token); + await fschanges.writeSnapshot(dir, dir + '/token.txt'); } -run(); \ No newline at end of file +run(); diff --git a/src/FSChanges.cc b/src/FSChanges.cc index 23a63a5f..68609fc9 100644 --- a/src/FSChanges.cc +++ b/src/FSChanges.cc @@ -6,22 +6,24 @@ using namespace v8; -std::string getCurrentTokenImpl(std::string *dir); -EventList *getEventsSinceImpl(std::string *dir, std::string *token); +void writeSnapshotImpl(std::string *dir, std::string *snapshotPath); +EventList *getEventsSinceImpl(std::string *dir, std::string *snapshotPath); struct AsyncRequest { uv_work_t work; std::string directory; - std::string token; + std::string snapshotPath; EventList *events; Nan::Persistent *resolver; - AsyncRequest(Local d, Local cb, Local r) { + AsyncRequest(Local d, Local s, Local r) { work.data = (void *)this; // copy the string since the JS garbage collector might run before the async request is finished Nan::Utf8String dir(d); + Nan::Utf8String sp(s); directory = std::string(*dir); + snapshotPath = std::string(*sp); events = NULL; resolver = new Nan::Persistent(r); @@ -45,7 +47,7 @@ void asyncCallback(uv_work_t *work) { if (req->events) { result = req->events->toJS(); } else { - result = Nan::New(req->token).ToLocalChecked(); + result = Nan::Null(); } auto resolver = Nan::New(*req->resolver); @@ -53,24 +55,24 @@ void asyncCallback(uv_work_t *work) { delete req; } -void getCurrentTokenAsync(uv_work_t *work) { +void writeSnapshotAsync(uv_work_t *work) { AsyncRequest *req = (AsyncRequest *) work->data; - req->token = getCurrentTokenImpl(&req->directory); + writeSnapshotImpl(&req->directory, &req->snapshotPath); } void getEventsSinceAsync(uv_work_t *work) { AsyncRequest *req = (AsyncRequest *) work->data; - req->events = getEventsSinceImpl(&req->directory, &req->token); + req->events = getEventsSinceImpl(&req->directory, &req->snapshotPath); } -NAN_METHOD(getCurrentToken) { +NAN_METHOD(writeSnapshot) { if (info.Length() < 1 || !info[0]->IsString()) { return Nan::ThrowTypeError("Expected a string"); } auto resolver = Promise::Resolver::New(info.GetIsolate()); AsyncRequest *req = new AsyncRequest(info[0], info[1], resolver); - uv_queue_work(uv_default_loop(), &req->work, getCurrentTokenAsync, (uv_after_work_cb) asyncCallback); + uv_queue_work(uv_default_loop(), &req->work, writeSnapshotAsync, (uv_after_work_cb) asyncCallback); info.GetReturnValue().Set(resolver->GetPromise()); } @@ -85,16 +87,14 @@ NAN_METHOD(getEventsSince) { } auto resolver = Promise::Resolver::New(info.GetIsolate()); - AsyncRequest *req = new AsyncRequest(info[0], info[2], resolver); - Nan::Utf8String token(info[1]); - req->token = std::string(*token); + AsyncRequest *req = new AsyncRequest(info[0], info[1], resolver); uv_queue_work(uv_default_loop(), &req->work, getEventsSinceAsync, (uv_after_work_cb) asyncCallback); info.GetReturnValue().Set(resolver->GetPromise()); } NAN_MODULE_INIT(Init) { - Nan::Export(target, "getCurrentToken", getCurrentToken); + Nan::Export(target, "writeSnapshot", writeSnapshot); Nan::Export(target, "getEventsSince", getEventsSince); } diff --git a/src/macos/FSEvents.cc b/src/macos/FSEvents.cc index 0a7929cb..69c2054b 100644 --- a/src/macos/FSEvents.cc +++ b/src/macos/FSEvents.cc @@ -1,10 +1,12 @@ #include #include +#include #include "../Event.hh" -std::string getCurrentTokenImpl(std::string *dir) { +void writeSnapshotImpl(std::string *dir, std::string *snapshotPath) { FSEventStreamEventId id = FSEventsGetCurrentEventId(); - return std::to_string(id); + std::ofstream ofs(*snapshotPath); + ofs << id; } void FSEventsCallback( @@ -55,8 +57,16 @@ void FSEventsCallback( } } -EventList *getEventsSinceImpl(std::string *dir, std::string *token) { - FSEventStreamEventId id = std::stoull(*token); +EventList *getEventsSinceImpl(std::string *dir, std::string *snapshotPath) { + EventList *list = new EventList(); + + std::ifstream ifs(*snapshotPath); + if (ifs.fail()) { + return list; + } + + FSEventStreamEventId id; + ifs >> id; CFAbsoluteTime latency = 0.001; CFStringRef fileWatchPath = CFStringCreateWithCString( @@ -72,8 +82,6 @@ EventList *getEventsSinceImpl(std::string *dir, std::string *token) { NULL ); - EventList *list = new EventList(); - FSEventStreamContext callbackInfo {0, (void *)list, nullptr, nullptr, nullptr}; FSEventStreamRef stream = FSEventStreamCreate( NULL, diff --git a/src/shared/brute.cc b/src/shared/brute.cc index d8de9848..9e90b4ec 100644 --- a/src/shared/brute.cc +++ b/src/shared/brute.cc @@ -1,20 +1,23 @@ #include -#include +#include #include "../DirTree.hh" #include "../Event.hh" DirTree *getDirTree(std::string *dir); -std::string getCurrentTokenImpl(std::string *dir) { +void writeSnapshotImpl(std::string *dir, std::string *snapshotPath) { auto tree = getDirTree(dir); - std::ostringstream os; - tree->write(os); - return os.str(); + std::ofstream ofs(*snapshotPath); + tree->write(ofs); } -EventList *getEventsSinceImpl(std::string *dir, std::string *token) { - std::istringstream is(*token); - auto snapshot = new DirTree(is); +EventList *getEventsSinceImpl(std::string *dir, std::string *snapshotPath) { + std::ifstream ifs(*snapshotPath); + if (ifs.fail()) { + return new EventList(); + } + + auto snapshot = new DirTree(ifs); auto now = getDirTree(dir); return now->getChanges(snapshot); }