CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-fibers

Cooperative multi-tasking for JavaScript through fibers (coroutines)

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

fiber-core.mddocs/

Core Fiber Operations

Low-level fiber creation, execution control, and cooperative yielding functionality. These primitives enable building custom async abstractions and implementing synchronous-style APIs over asynchronous operations.

Capabilities

Fiber Constructor

Creates a new fiber that executes the given function when run.

/**
 * Instantiate a new Fiber. You may invoke this either as a function or as
 * a constructor; the behavior is the same.
 *
 * When run() is called on this fiber for the first time, `fn` will be
 * invoked as the first frame on a new stack. Execution will continue on
 * this new stack until `fn` returns, or Fiber.yield() is called.
 *
 * After the function returns the fiber is reset to original state and
 * may be restarted with another call to run().
 * 
 * @param {Function} fn - Function to execute in the fiber
 * @returns {Fiber} New fiber instance
 */
function Fiber(fn) { /* [native code] */ }

Usage Examples:

var Fiber = require('fibers');

// Create and run a simple fiber
var fiber = Fiber(function() {
  console.log('Inside fiber');
  Fiber.yield('yielded value');
  console.log('Resumed fiber');
  return 'final value';
});

var result1 = fiber.run(); // Logs: "Inside fiber", returns: "yielded value"
var result2 = fiber.run(); // Logs: "Resumed fiber", returns: "final value"

Current Fiber Reference

Static property containing the currently-running fiber.

/**
 * `Fiber.current` will contain the currently-running Fiber. It will be
 * `undefined` if there is no fiber (i.e. the main stack of execution).
 *
 * See "Garbage Collection" for more information on responsible use of
 * `Fiber.current`.
 */
Fiber.current = undefined;

Usage Examples:

function getCurrentFiber() {
  if (Fiber.current) {
    console.log('Running in fiber');
    return Fiber.current;
  } else {
    console.log('Running on main stack');
    return null;
  }
}

Fiber(function() {
  var current = getCurrentFiber(); // Returns the current fiber
}).run();

getCurrentFiber(); // Returns null

Fiber Yielding

Halts execution of the current fiber and returns control back to the caller.

/**
 * `Fiber.yield()` will halt execution of the current fiber and return control
 * back to original caller of run(). If an argument is supplied to yield(),
 * run() will return that value.
 *
 * When run() is called again, yield() will return.
 *
 * Note that this function is a global to allow for correct garbage
 * collection. This results in no loss of functionality because it is only
 * valid to yield from the currently running fiber anyway.
 *
 * Note also that `yield` is a reserved word in Javascript. This is normally
 * not an issue, however some code linters may complain. Rest assured that it
 * will run fine now and in future versions of Javascript.
 * 
 * @param {*} param - Optional value to return to caller
 * @returns {*} Value passed to next run() call
 */
Fiber.yield = function(param) { /* [native code] */ }

Usage Examples:

// Incremental generator example
var inc = Fiber(function(start) {
  var total = start;
  while (true) {
    total += Fiber.yield(total);
  }
});

for (var ii = inc.run(1); ii <= 10; ii = inc.run(1)) {
  console.log(ii); // Prints: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
}

Run Method

Starts or resumes fiber execution.

/**
 * run() will start execution of this Fiber, or if it is currently yielding,
 * it will resume execution. If an argument is supplied, this argument will
 * be passed to the fiber, either as the first parameter to the main
 * function [if the fiber has not been started] or as the return value of
 * yield() [if the fiber is currently yielding].
 *
 * This function will return either the parameter passed to yield(), or the
 * returned value from the fiber's main function.
 * 
 * @param {*} param - Optional parameter to pass to fiber
 * @returns {*} Value passed to yield() or fiber return value
 */
Fiber.prototype.run = function(param) { /* [native code] */ }

Reset Method

Terminates a running fiber and restores it to its original state.

/**
 * reset() will terminate a running Fiber and restore it to its original
 * state, as if it had returned execution.
 *
 * This is accomplished by causing yield() to throw an exception, and any
 * futher calls to yield() will also throw an exception. This continues
 * until the fiber has completely unwound and returns.
 *
 * If the fiber returns a value it will be returned by reset().
 *
 * If the fiber is not running, reset() will have no effect.
 * 
 * @returns {*} Return value from fiber if any
 */
Fiber.prototype.reset = function() { /* [native code] */ }

Usage Examples:

var fiber = Fiber(function() {
  try {
    while (true) {
      Fiber.yield('continuing');
    }
  } catch (e) {
    console.log('Fiber was reset');
    return 'cleaned up';
  }
});

fiber.run(); // Returns: 'continuing'
var result = fiber.reset(); // Logs: "Fiber was reset", returns: 'cleaned up'

Throw Into Method

Causes a yielding fiber's yield() call to throw instead of return.

/**
 * throwInto() will cause a currently yielding fiber's yield() call to
 * throw instead of return gracefully. This can be useful for notifying a
 * fiber that you are no longer interested in its task, and that it should
 * give up.
 *
 * Note that if the fiber does not handle the exception it will continue to
 * bubble up and throwInto() will throw the exception right back at you.
 * 
 * @param {Error} exception - Exception to throw in fiber
 */
Fiber.prototype.throwInto = function(exception) { /* [native code] */ }

Usage Examples:

var fiber = Fiber(function() {
  try {
    Fiber.yield('yielding');
    console.log('This will not execute');
  } catch (e) {
    console.log('Caught exception:', e.message);
    return 'handled error';
  }
});

fiber.run(); // Returns: 'yielding'
var result = fiber.throwInto(new Error('Stop processing'));
// Logs: "Caught exception: Stop processing", returns: 'handled error'

Error Handling

Fibers are exception-safe; exceptions will continue travelling through fiber boundaries:

var fn = Fiber(function() {
  console.log('async work here...');
  Fiber.yield();
  console.log('still working...');
  Fiber.yield();
  console.log('just a little bit more...');
  Fiber.yield();
  throw new Error('oh crap!');
});

try {
  while (true) {
    fn.run();
  }
} catch(e) {
  console.log('safely caught that error!');
  console.log(e.stack);
}

Garbage Collection Considerations

  • All fibers must eventually unwind to prevent memory leaks
  • Avoid grabbing references to Fiber.current without proper cleanup
  • Library will force unwinding by causing yield() to throw when necessary
  • Never catch and ignore exceptions thrown during fiber unwinding

docs

fiber-core.md

future.md

index.md

tile.json