CJS-Task 0.0.8 Release

The JavaScript ecosystem encourages creating and using small utility functions and libraries.

While this encourages code reuse and interoperability, you’re left with the responsibility of writing glue code to marshal oft misaligned paradigms to accomplish your objective.

CJS-Task was created with the desire to bring simplicity by acting as a high-quality glue between all the pieces you’ll use.

How? A few tricks.

  1. The task is broken down to logical steps. The user is “encouraged” to do so by enforcing a name for each step.
    task.step('verify bearer token', function(){
      // do bearer verification
    });
    
    task.step('verify user is authorized for action', function(){
      // verify user level
    });
    
    task.step('perform action', function(){
      // execute user-requested action
    });
  2. Each step has the ability to end the task. Unlike a promise, a task stops running as soon as any step signals its end.
    task.step('validate user', function(){
      // do validation
    
      if( !validation ) task.end('user not validated');
      else task.next(); 
    });
    
    task.step('get all updates', function(){
      // fetch all updates
    
      if( !updates ) task.end('no user updates');
      else task.next(); 
    });
    
    task.step('apply user filters', function(){
      // filter data
      task.next(); 
    });
  3. Each step is isolated from the next to prevent intermingling of concerns and dependencies. Your approach or tooling to do a step may need to change and it should be relatively easy to do so.

    CJS-Task helps with this in two ways.

    First is an interface to call the next step. Steps are blissfully unaware of each other: they doesn’t need to know what happens when its done. Each runs its course and signals when the next step, whatever it may be, should run.

    This independence means you can slot new steps in or replace the components of an existing one effortlessly.

    task.step('validate user', function(){
      // do validation
      task.next(); 
    });
    
    task.step('get all updates', function(){
      // fetch all updates
      task.next(); 
    });
    
    task.step('apply user filters', function(){
      // filter data
      task.next(); 
    });

Second is a key-value store. Even if a step isn’t fetching or transforming data, it could be as simple as setting a flag that may modify another step in the task. There should be no pointless steps, so there must be a central place to store the result of a step.

task.step('get weather forecast', function(){
  // get forecast
  if( !forecast ) return task.end('could not get forecast');
  
  task.set('forecast', forecast);
  task.next();
});

task.step('convert to user-preferred unit', function(){
  // get user-preferred unit

  var forecast = task.get('forecast'), 
      user_forecast = user_unit ? convert( forecast, user_unit ) : forecast;

  task.set('user-forecast', user_forecast);
  task.next();
});

What’s Special About 0.0.8?

Nothing much really. It’s a bit better than 0.0.7 in a few ways, so it’s a decent-enough version to put out there for others to play with. Here are a few reasons though.

  1. More Tests

    Testing CJS-Task
    Me Testing CJS-Task

    This is probably the most tested piece of software I’ve made. I check for expected (as well as unexpected) properties on a Task instance and the behavior of every exposed method, right down to what types of arguments can be passed to them and when it will throw errors.

    0.0.8 is more tests which means more reliability in development and use.

  2. Smarter Default Behavior

    My favorite new behavior is automatically triggering the task callback at when you call task.next() and there are no more steps.

    Previously this did nothing. You needed to either create a final step just for triggering task.end() or remember to swap it with a next step call if you ever adjust what the last step is. Unnecessary busywork.

    Now you can simply call task.next()  when a step is done and it will do the smart thing when there are no more steps. Very minor code change, but makes using CJS-Task that much more pleasant.

    A new behavior I really like is throwing an error when task.start() is called more than once per task instance. It’s unlikely you’d intentionally call it multiple times in the lifecycle of a task, so it’s an indicator that something is wrong somewhere. It will fail loudly and bring the entire process down with it. Something is wrong with your code and CJS-Task isn’t going to let it slip by unnoticed.

    Overall I’m happy with the shape CJS-Task is taking and just wanted to take the opportunity to share something from my toolkit with the world 🙂

    Picture of the Wright Brothers toolbox. I hope to build a simple yet effective collection of tools like theirs.
    Picture of the Wright Brothers toolbox. I hope to build a simple yet effective collection of tools like theirs.