diff --git a/watcher-nodejs/lib/watcher-napi.cpp b/watcher-nodejs/lib/watcher-napi.cpp index 8615c046..f47360b3 100644 --- a/watcher-nodejs/lib/watcher-napi.cpp +++ b/watcher-nodejs/lib/watcher-napi.cpp @@ -16,65 +16,34 @@ an event is ready. - A reference to the user's callback, which we release when the watcher is closed. */ -struct WatcherWrapper { +struct watcher_lifetime { napi_ref js_callback_ref = NULL; napi_threadsafe_function tsfn = NULL; void* watcher = NULL; }; -static void effect_type_js_obj(napi_env env, napi_value* effect_obj) -{ - napi_create_object(env, effect_obj); - napi_value rename, modify, create, destroy, owner, other; - napi_create_int32(env, WTR_WATCHER_EFFECT_RENAME, &rename); - napi_create_int32(env, WTR_WATCHER_EFFECT_MODIFY, &modify); - napi_create_int32(env, WTR_WATCHER_EFFECT_CREATE, &create); - napi_create_int32(env, WTR_WATCHER_EFFECT_DESTROY, &destroy); - napi_create_int32(env, WTR_WATCHER_EFFECT_OWNER, &owner); - napi_create_int32(env, WTR_WATCHER_EFFECT_OTHER, &other); - napi_set_named_property(env, *effect_obj, "rename", rename); - napi_set_named_property(env, *effect_obj, "modify", modify); - napi_set_named_property(env, *effect_obj, "create", create); - napi_set_named_property(env, *effect_obj, "destroy", destroy); - napi_set_named_property(env, *effect_obj, "owner", owner); - napi_set_named_property(env, *effect_obj, "other", other); -} - -static void path_type_js_obj(napi_env env, napi_value* path_type_obj) -{ - napi_create_object(env, path_type_obj); - napi_value dir, file, hard_link, sym_link, watcher, other; - napi_create_int32(env, WTR_WATCHER_PATH_DIR, &dir); - napi_create_int32(env, WTR_WATCHER_PATH_FILE, &file); - napi_create_int32(env, WTR_WATCHER_PATH_HARD_LINK, &hard_link); - napi_create_int32(env, WTR_WATCHER_PATH_SYM_LINK, &sym_link); - napi_create_int32(env, WTR_WATCHER_PATH_WATCHER, &watcher); - napi_create_int32(env, WTR_WATCHER_PATH_OTHER, &other); - napi_set_named_property(env, *path_type_obj, "dir", dir); - napi_set_named_property(env, *path_type_obj, "file", file); - napi_set_named_property(env, *path_type_obj, "hardLink", hard_link); - napi_set_named_property(env, *path_type_obj, "symLink", sym_link); - napi_set_named_property(env, *path_type_obj, "watcher", watcher); - napi_set_named_property(env, *path_type_obj, "other", other); -} - static napi_value event_to_js_obj(napi_env env, wtr_watcher_event* event) { - napi_value event_obj, path_name, effect_type, path_type, effect_time, associated_path_name; + napi_value event_obj = NULL; + napi_value path_name = NULL; + napi_value effect_type = NULL; + napi_value path_type = NULL; + napi_value effect_time = NULL; + napi_value associated_path_name = NULL; napi_create_object(env, &event_obj); napi_create_string_utf8(env, event->path_name, NAPI_AUTO_LENGTH, &path_name); napi_create_int32(env, event->effect_type, &effect_type); napi_create_int32(env, event->path_type, &path_type); napi_create_bigint_int64(env, event->effect_time, &effect_time); - napi_set_named_property(env, event_obj, "pathName", path_name); - napi_set_named_property(env, event_obj, "effectType", effect_type); - napi_set_named_property(env, event_obj, "pathType", path_type); - napi_set_named_property(env, event_obj, "effectTime", effect_time); if (event->associated_path_name) { napi_create_string_utf8(env, event->associated_path_name, NAPI_AUTO_LENGTH, &associated_path_name); } else { napi_get_null(env, &associated_path_name); } + napi_set_named_property(env, event_obj, "pathName", path_name); + napi_set_named_property(env, event_obj, "effectType", effect_type); + napi_set_named_property(env, event_obj, "pathType", path_type); + napi_set_named_property(env, event_obj, "effectTime", effect_time); napi_set_named_property(env, event_obj, "associatedPathName", associated_path_name); return event_obj; } @@ -86,9 +55,9 @@ static void callback_js_receiver(napi_env env, napi_value js_callback, void* _un { wtr_watcher_event* event = (wtr_watcher_event*)ctx; napi_value event_obj = event_to_js_obj(env, event); - napi_value global; + napi_value global = NULL; napi_get_global(env, &global); - napi_value result; + napi_value result = NULL; napi_call_function(env, global, js_callback, 1, &event_obj, &result); #if WITH_TSFN_NONBLOCKING free((void*)event->path_name); @@ -102,7 +71,7 @@ static void callback_js_receiver(napi_env env, napi_value js_callback, void* _un Expects the event it to be freed in the wrapper's stored function. */ static void callback_bridge(struct wtr_watcher_event event_view, void* ctx) { - WatcherWrapper* wrapper = (WatcherWrapper*)ctx; + struct watcher_lifetime* w = (struct watcher_lifetime*)ctx; #if WITH_TSFN_NONBLOCKING wtr_watcher_event* event_owned = (wtr_watcher_event*)malloc(sizeof(wtr_watcher_event)); event_owned->path_name = event_view.path_name ? strdup(event_view.path_name) : NULL; @@ -110,42 +79,42 @@ static void callback_bridge(struct wtr_watcher_event event_view, void* ctx) event_owned->path_type = event_view.path_type; event_owned->effect_time = event_view.effect_time; event_owned->associated_path_name = event_view.associated_path_name ? strdup(event_view.associated_path_name) : NULL; - if (wrapper->tsfn) { - napi_call_threadsafe_function(wrapper->tsfn, event_owned, napi_tsfn_nonblocking); + if (w->tsfn) { + napi_call_threadsafe_function(w->tsfn, event_owned, napi_tsfn_nonblocking); + } #else napi_call_threadsafe_function(wrapper->tsfn, &event_view, napi_tsfn_blocking); #endif - } } /* Should be called by the user when they are done with the watcher. Ends event processing and releases any owned resources. */ static napi_value close(napi_env env, napi_callback_info func_arg_info) { - void* ctx; + void* ctx = NULL; napi_get_cb_info(env, func_arg_info, NULL, NULL, NULL, &ctx); - napi_value result; + napi_value result = NULL; napi_get_boolean(env, false, &result); if (! ctx) { return result; } - WatcherWrapper* wrapper = (WatcherWrapper*)ctx; - bool closed_ok = wtr_watcher_close(wrapper->watcher); + watcher_lifetime* w = (watcher_lifetime*)ctx; + bool closed_ok = wtr_watcher_close(w->watcher); napi_get_boolean(env, closed_ok, &result); - if (wrapper->tsfn) { - napi_release_threadsafe_function(wrapper->tsfn, napi_tsfn_release); - wrapper->tsfn = NULL; + if (w->tsfn) { + napi_release_threadsafe_function(w->tsfn, napi_tsfn_release); + w->tsfn = NULL; } else { napi_get_boolean(env, false, &result); } - if (wrapper->js_callback_ref) { - napi_delete_reference(env, wrapper->js_callback_ref); - wrapper->js_callback_ref = NULL; + if (w->js_callback_ref) { + napi_delete_reference(env, w->js_callback_ref); + w->js_callback_ref = NULL; } else { napi_get_boolean(env, false, &result); } - free(wrapper); - wrapper = NULL; + free(w); + w = NULL; return result; } @@ -165,9 +134,10 @@ static napi_value watch(napi_env env, napi_callback_info func_arg_info) return NULL; } char path[4096]; - size_t path_len; + memset(path, 0, sizeof(path)); + size_t path_len = 0; napi_get_value_string_utf8(env, args[0], path, sizeof(path), &path_len); - WatcherWrapper* wrapper = (WatcherWrapper*)malloc(sizeof(WatcherWrapper)); + watcher_lifetime* wrapper = (watcher_lifetime*)malloc(sizeof(watcher_lifetime)); napi_value js_callback = args[1]; napi_create_reference(env, js_callback, 1, &wrapper->js_callback_ref); napi_value work_name; @@ -190,9 +160,9 @@ static napi_value watch(napi_env env, napi_callback_info func_arg_info) napi_throw_error(env, NULL, "Failed to open watcher"); return NULL; } - napi_value watcher_obj; + napi_value watcher_obj = NULL; napi_create_object(env, &watcher_obj); - napi_value close_func; + napi_value close_func = NULL; napi_create_function(env, "close", NAPI_AUTO_LENGTH, close, wrapper, &close_func); napi_set_named_property(env, watcher_obj, "close", close_func); napi_wrap(env, watcher_obj, wrapper, NULL, NULL, NULL); @@ -202,15 +172,9 @@ static napi_value watch(napi_env env, napi_callback_info func_arg_info) /* Module initialization */ static napi_value mod_init(napi_env env, napi_value exports) { - napi_value watch_func; + napi_value watch_func = NULL; napi_create_function(env, NULL, 0, watch, NULL, &watch_func); napi_set_named_property(env, exports, "watch", watch_func); - napi_value effect_type_obj; - effect_type_js_obj(env, &effect_type_obj); - napi_set_named_property(env, exports, "EffectType", effect_type_obj); - napi_value path_type_obj; - path_type_js_obj(env, &path_type_obj); - napi_set_named_property(env, exports, "PathType", path_type_obj); return exports; } diff --git a/watcher-nodejs/lib/watcher.ts b/watcher-nodejs/lib/watcher.ts index 3ebad2c9..a227a041 100644 --- a/watcher-nodejs/lib/watcher.ts +++ b/watcher-nodejs/lib/watcher.ts @@ -34,13 +34,14 @@ interface CEvent { } export const watch = (path: string, cb: (event: Event) => void): { close: () => boolean } => { - let typedCb: null | ((_: CEvent) => void) = (event) => { - cb({ - pathName: event.pathName, - effectType: Object.keys(EffectType)[event.effectType] as EffectType, - pathType: Object.keys(PathType)[event.pathType] as PathType, - associatedPathName: event.associatedPathName, - }); + let typedCb: null | ((_: CEvent) => void) = (cEvent) => { + let event: Event = { + pathName: cEvent.pathName, + effectType: Object.keys(EffectType)[cEvent.effectType] as EffectType, + pathType: Object.keys(PathType)[cEvent.pathType] as PathType, + associatedPathName: cEvent.associatedPathName, + }; + cb(event); }; let watcher = wcw.watch(path, typedCb); return {