npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@fast-check/worker

v0.3.1

Published

Provide built-ins to run predicates directly within dedicated workers

Downloads

507

Readme

@fast-check/worker

fast-check logo

Provide built-ins to run predicates directly within dedicated workers


Why?

fast-check alone is great but what if it led your code into an infinite and synchronous loop for such inputs? In such case, it would neither be able to shrink the issue, nor to report any for you as the single threaded philosophy at the root of JavaScript will prevent it from anything except waiting for the main thread to come back.

This package tends to provide a way to run easily your properties within dedicated workers automatically spawed by it.

Example

Here are some of the changes you will have to do:

  • hoist properties so that they get declared on the root scope
  • replace fc.property by property coming from propertyFor(<path-to-file>)
  • replace fc.assert by assert coming from @fast-check/worker for automatic cleaning of the workers as the test ends
  • transpilation has not been addressed yet but it may probably work
  • in theory, if you were only using propertyFor and assert without any external framework for test, it and others, the separation of the property from the assertion would be useless as the check for main thread is fully handled within @fast-check/worker itself so no hoisting needing in such case
import { test } from '@jest/globals';
import fc from 'fast-check';
import { isMainThread } from 'node:worker_threads';
import { assert, propertyFor } from '@fast-check/worker';

const property = propertyFor(new URL(import.meta.url)); // or propertyFor(pathToFileURL(__filename)) in commonjs
const p1 = property(fc.nat(), fc.nat(), (start, end) => {
  // starting a possibly infinite loop
  for (let i = start; i !== end; ++i) {
    // doing stuff...
  }
});

if (isMainThread) {
  test('should assess p1', async () => {
    await assert(p1, { timeout: 1000 });
  });
}

Refer to the tests defined test/main.spec.ts for a living example of how you can use this package with a test runner such as Jest.

Extra options

The builder of properties propertyFor accepts a second parameter to customize how the workers will behave. By default, workers will be shared across properties. In case you want a more isolation between your runs, you can use:

const property = propertyFor(new URL(import.meta.url), { isolationLevel: 'predicate' });
// Other values:
// - "file": Re-use workers cross properties (default)
// - "property": Re-use workers for each run of the predicate. Not shared across properties!
// - "predicate": One worker per run of the predicate

By default, workers will receive the generated values from their parent thread. In some cases, such sending is made impossible as the generated values include non-serializable pieces. In such cases, you can opt-in to generate the values directly within the workers by using:

const property = propertyFor(new URL(import.meta.url), { randomSource: 'worker' });
// Other values:
// - "main-thread": The main thread will be responsible to generate the random values and send them to the worker thread. It unfortunately cannot send any value that cannot be serialized between threads. (default)
// - "worker": The worker is responsible to generate its own values based on the instructions provided by the main thread. Switching to a worker mode allows to support non-serializable values, unfortunately it drops all shrinking. capabilities.

Minimal requirements

  • Node ≥14.18.0(1)(2)(3)
  • TypeScript ≥4.1 (optional)

(1): worker_threads alone would only require Node ≥10.5.0, but our usage of require(node:*) forces us to request at least Node ≥14.18.0

(2): this package targets ES2020 specification which is quite well supported (more than 94%) by any Node ≥14.5.0

(3): this package requires a version of node able to understand package.json#exports, supported by any Node ≥12.17.0