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 🙏

© 2026 – Pkg Stats / Ryan Hefner

quidproquo-core

v0.1.33

Published

The heart of the [quidproquo](https://github.com/qpqjs/quidproquo) framework: the action catalogue, the story runtime, and the config system that everything else builds on.

Readme

quidproquo-core

The heart of the quidproquo framework: the action catalogue, the story runtime, and the config system that everything else builds on.

Most applications should install quidproquo instead, which re-exports this package along with quidproquo-webserver. Install this one directly only if you want core without the web server.

npm install quidproquo-core

How it works

An action is a plain object with a type and an optional payload. A requester is the ask* generator your code calls to yield one. Here is the whole of askDateNow:

export function* askDateNow(): DateNowActionRequester {
  return yield { type: DateActionType.Now };
}

It never calls new Date(). A story composes requesters:

function* askGreet(name: string): AskResponse<string> {
  const now = yield* askDateNow();
  return `hello ${name}, it is ${now}`;
}

The runtime drives the story, takes each yielded action, looks up the processor registered for that action type, awaits the result, and resumes the generator with it. Processors live in the quidproquo-actionprocessor-* packages, one set per platform. Swap the set and the same story runs somewhere else.

Every action that passes through the runtime is recorded, which is where the execution logs, replay, and tracing come from.

What is in here

Actions, grouped by domain in src/actions/:

| Domain | Covers | | --- | --- | | config | Parameters, secrets, globals | | keyValueStore | Key value storage, queries, and streams | | file | Object storage: read, write, list, signed urls | | userDirectory | Sign in, sign up, tokens, user management | | eventBus, queue | Publish and subscribe, message queues | | network | HTTP requests | | graphDatabase | Graph queries | | ai | Prompting and streaming completions | | crypto | Encrypt and decrypt against a managed key | | date, guid, math | The non-deterministic primitives a story must not call directly | | log, metric, event | Observability | | state | Reducer-driven state for frontend modules | | stream, system, platform | Streams, process, and platform utilities | | dynamicFunctions, inlineFunction | Calling code that is resolved at runtime | | error, context | Error handling and execution context |

Stories in src/stories/: the composable helpers, including askCatch for try/finally semantics and askRunParallel for concurrency.

Config in src/config/: the define* helpers that declare resources (key value stores, queues, secrets, and so on). A qpq config is a plain array of settings, which is what the deploy packages read to build infrastructure.

Testing in src/testing/: runStory runs a story with actions mocked by type, so you can assert on behaviour without a runtime or any infrastructure.

import { DateActionType, runStory } from 'quidproquo-core';

const result = runStory(askGreet('world'), {
  [DateActionType.Now]: '2026-01-01T00:00:00.000Z',
});

expect(result).toBe('hello world, it is 2026-01-01T00:00:00.000Z');

A mock can be a literal value or a function, and a function mock is re-invoked per matching action, so it can be stateful.

Conventions worth knowing

  • Anything named ask* is a generator and must be called with yield*. The ESLint plugin enforces this and auto-fixes a missing yield*.
  • Stories must be deterministic. No Date.now(), Math.random(), or crypto.randomUUID(). Yield askDateNow() or askNewGuid() so logs replay and tests stay stable.
  • Throw with return yield* askThrowError(...), which tells TypeScript that control stops there.

Status

Pre-1.0. The whole quidproquo-* family releases in lockstep, so versions that share a number were built and tested together. Expect APIs to move between releases, and pin your versions.

Documentation

docs.quidproquojs.com

License

MIT. See LICENSE.