Skip to content

Allows for programming with assertions/invariant-based programming during development without slowing down production.

License

Notifications You must be signed in to change notification settings

RebeccaStevens/deassert

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deassert Mono Repo

CI Coverage Status
code style: prettier GitHub Discussions BSD 3 Clause license Commitizen friendly semantic-release

Allows for programming with assertions/invariant-based programming during development without slowing down production.

Donate

Any donations would be much appreciated. 😄

Enterprise Users

deassert is available as part of the Tidelift Subscription.

Tidelift is working with the maintainers of deassert and a growing network of open source maintainers to ensure your open source software supply chain meets enterprise standards now and into the future. Learn more.

Installation

# Install with npm
npm install -D deassert

# Install with pnpm
pnpm add -D deassert

# Install with yarn
yarn add -D deassert

# Install with bun
bun add -D deassert

Thinking about Invariants

Invariant checks in your code should be thought of as a way of saying:

If this check fails, something is very wrong elsewhere in my code.

Do not try to recover from Assertion Errors. If your error is recoverable, use a different type of error object.

Usage

You probably don't want to use this library in your development builds. It's designed to be used in your production builds.

Packages

Example

Given the following code that uses assertion calls to enforce known invariants, some of which may be expensive (line 25):

import { AssertionError, ok as assert, fail as assertNever } from "node:assert/strict";

const stack = [
  {
    type: "foo",
    children: [
      /* ... */
    ],
  },
];
const result = [];

try {
  do {
    const element = stack.pop() ?? assertNever("stack is empty (or contains undefined).");

    switch (element.type) {
      case "foo": {
        assert(children.every(isExpectedType), "unexpected child type.");
        stack.push(...children);
        break;
      }

      case "bar": {
        assert(element.children.length === 0, "bar elements should not have children.");
        result.push(element.data);
        break;
      }

      case "baz": {
        throw new Error("Not Implemented yet.");
      }

      default: {
        assertNever(`Unexpected type: "${element.type}"`);
      }
    }
  } while (stack.length > 0);

  console.log((assert(result.length > 0), result));
} catch (error) {
  assert(error instanceof Error, "Unexpected Error.");
  assert(!(error instanceof AssertionError), error);

  console.error(error);
}

This library will transform the code into essentially the following:

const stack = [
  {
    type: "foo",
    children: [
      /* ... */
    ],
  },
];
const result = [];

try {
  do {
    const element = stack.pop();

    switch (element.type) {
      case "foo": {
        stack.push(...children);
        break;
      }

      case "bar": {
        result.push(element.data);
        break;
      }

      case "baz": {
        throw new Error("Not Implemented yet.");
      }
    }
  } while (stack.length > 0);

  console.log(result);
} catch (error) {
  console.error(error);
}

Similar Projects

This project was inspired by Unassert which has the same objective as this project.

While unassert works by modifying the inputted AST, this library works directly on the inputted code.