0.2.0 • Public • Published

Simplify concurrency using the strategies described in using input gates and output gates by allowing certain actions to block other actions or to block the responses of other actions. To "block" an action or response means to defer it until after the blocking actions have been processed. This allows the state of an object to be consistent and avoid race conditions which may be hard to discover. It is a good idea to use this in conjunction with a cache for blockable actions (e.g. a storage mechanism) to ensure the blocking doesn't slow down the system.


  • "blockable" methods won't execute until after being unblocked. They will be deferred to run afterwards.
  • "blockableResponse" methods will execute but won't deliver a response until after being unblocked.
  • "blocking" methods will block blockable calls and responses.

In the article linked above, and are blocking, fetch has a blockable response, and this.getUniqueNumber() is a blockable method.

Note that blockable methods also have blockable responses. I.E. if you return a response while a storage operation is in progress, the response will return after the storage operation completes. If the storage operation fails, the response will be the error of the storage operation.

Usage - with decorators (recommended):

import { simplifiedConcurrency } from 'simplified-concurrency';

const { blockable, blocking, blockableResponse } = simplifiedConcurrency();

class MyDurableObject {
  storage: Storage;

  constructor() { = new Storage();

  async getUniqueNumber() {
    await this.fetch("");
    let val = await"counter");"counter", val + 1);
    return val;

  async fetch(input: RequestInfo, init?: RequestInit): Promise<Response> {
    return fetch(input, init);

// Simple storage with cache
class Storage {
  cache: Map<string, any>;

  constructor() {
    this.cache = new Map();

  async get(key) {
    if (this.cache.has(key)) {
      return this.cache.get(key);
    } else {
      // if fetch is used in a blocking method, be sure to use the global fetch and not the blockable-response fetch
      // provided which would never return since it is blocked by the method calling it.
      const response = await fetch(BACKEND_URL + key);
      return await response.json();

  async put(key, value) {
    this.cache.set(key, value);

    const response = await fetch(BACKEND_URL + key, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' }},
      body: JSON.stringify(value)

    return await response.json();

These APIs work in the browser and in Node.js as they are just plain JavaScript promises.



Package Sidebar


npm i simplified-concurrency

Weekly Downloads






Unpacked Size

38.6 kB

Total Files


Last publish


  • jacwright