.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / @mrmlnc / readdir-enhanced / lib / call.js
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/@mrmlnc/readdir-enhanced/lib/call.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/@mrmlnc/readdir-enhanced/lib/call.js
new file mode 100644 (file)
index 0000000..07e3d84
--- /dev/null
@@ -0,0 +1,54 @@
+'use strict';
+
+let call = module.exports = {
+  safe: safeCall,
+  once: callOnce,
+};
+
+/**
+ * Calls a function with the given arguments, and ensures that the error-first callback is _always_
+ * invoked exactly once, even if the function throws an error.
+ *
+ * @param {function} fn - The function to invoke
+ * @param {...*} args - The arguments to pass to the function. The final argument must be a callback function.
+ */
+function safeCall (fn, args) {
+  // Get the function arguments as an array
+  args = Array.prototype.slice.call(arguments, 1);
+
+  // Replace the callback function with a wrapper that ensures it will only be called once
+  let callback = call.once(args.pop());
+  args.push(callback);
+
+  try {
+    fn.apply(null, args);
+  }
+  catch (err) {
+    callback(err);
+  }
+}
+
+/**
+ * Returns a wrapper function that ensures the given callback function is only called once.
+ * Subsequent calls are ignored, unless the first argument is an Error, in which case the
+ * error is thrown.
+ *
+ * @param {function} fn - The function that should only be called once
+ * @returns {function}
+ */
+function callOnce (fn) {
+  let fulfilled = false;
+
+  return function onceWrapper (err) {
+    if (!fulfilled) {
+      fulfilled = true;
+      return fn.apply(this, arguments);
+    }
+    else if (err) {
+      // The callback has already been called, but now an error has occurred
+      // (most likely inside the callback function). So re-throw the error,
+      // so it gets handled further up the call stack
+      throw err;
+    }
+  };
+}