quidproquo 0.1.16 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +191 -8
  2. package/package.json +10 -7
package/README.md CHANGED
@@ -1,15 +1,198 @@
1
- # quidproquo
1
+ <div align="center">
2
2
 
3
- JS Library for building web servers using pure functions and generators.
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/qpqjs/quidproquo/main/assets/qpq-lockup-dark.svg">
5
+ <img src="https://raw.githubusercontent.com/qpqjs/quidproquo/main/assets/qpq-lockup.svg" alt="quidproquo" width="440">
6
+ </picture>
4
7
 
5
- ** THIS IS NO PROD READY DO NOT USED **
8
+ <p><strong>Build web applications out of pure functions.</strong></p>
6
9
 
7
- ## tsconfig
10
+ [![npm](https://img.shields.io/npm/v/quidproquo.svg?color=0a7bbb&label=npm)](https://www.npmjs.com/package/quidproquo)
11
+ [![license](https://img.shields.io/badge/license-MIT-0a7bbb.svg)](https://github.com/qpqjs/quidproquo/blob/main/LICENSE)
12
+ [![node](https://img.shields.io/badge/node-%3E%3D24-0a7bbb.svg)](https://nodejs.org)
8
13
 
9
- core for quidproquo library packages ~ Should probably not be used by itself
14
+ [Getting started](#getting-started) &nbsp;·&nbsp; [How it works](#how-it-works) &nbsp;·&nbsp; [Packages](#packages) &nbsp;·&nbsp; [Docs](https://docs.quidproquojs.com)
10
15
 
11
- use `quidproquo`
16
+ </div>
12
17
 
13
- ### Note
18
+ ---
14
19
 
15
- Currently under development ~ Not for production
20
+ Business logic in quidproquo is written as generator functions called **stories**. A story never calls the clock, the database, or the network directly. It yields a typed action describing what it wants, and the runtime hands that action to whichever implementation fits the platform it is running on.
21
+
22
+ The same story runs on AWS Lambda, in a Node process, in a browser, or against fixtures in a test, with no changes to the code.
23
+
24
+ ```typescript
25
+ function* askGreet(name: string): AskResponse<string> {
26
+ const now = yield* askDateNow();
27
+ return `hello ${name}, it is ${now}`;
28
+ }
29
+ ```
30
+
31
+ `askDateNow()` does not read the clock. It yields `{ type: '@quidproquo-core/Date/Now' }` and suspends, and the runtime resolves it and resumes the generator with the answer.
32
+
33
+ ## Getting started
34
+
35
+ ```bash
36
+ npx create-qpq-app myapp
37
+ cd myapp
38
+ npm run dev
39
+ ```
40
+
41
+ That scaffolds a complete working app (five services, a local dev server, and a one-image docker deploy), installs it, builds it, and makes the first commit. `npm run dev` runs the backend and every frontend dev server in one process, so one ctrl+c stops everything.
42
+
43
+ The api comes up on `http://localhost:8080` and the web on `http://localhost:3080`. Check it is alive:
44
+
45
+ ```bash
46
+ curl http://localhost:8080/api/shell/v1/health
47
+ # {"status":"healthy","service":"shell","checkedAt":"..."}
48
+ ```
49
+
50
+ You need **Node.js 24 or newer**. Docker is only needed when you deploy, not for local dev.
51
+
52
+ <details>
53
+ <summary>Scaffolder options</summary>
54
+
55
+ ```bash
56
+ npx create-qpq-app <app-name> [options]
57
+
58
+ --language <typescript|javascript> skip the language prompt
59
+ --domain <domain> app domain (default: <app-name>.example.com)
60
+ --no-git skip git init
61
+ --no-install skip npm install
62
+ ```
63
+
64
+ Pass `--language javascript` and you get the same app with type annotations stripped and JSX preserved, running on the same toolchain.
65
+
66
+ </details>
67
+
68
+ ## How it works
69
+
70
+ Here is the health route the scaffolded app ships with:
71
+
72
+ ```typescript
73
+ import { askDateNow, AskResponse, HTTPEvent, HTTPEventResponse, qpqWebServerUtils } from 'quidproquo';
74
+ import { dynamicRoute } from 'quidproquo-features';
75
+
76
+ export const health = dynamicRoute(
77
+ ['GET', '/health'],
78
+ function* healthCheck(event: HTTPEvent): AskResponse<HTTPEventResponse> {
79
+ const checkedAt = yield* askDateNow();
80
+
81
+ return qpqWebServerUtils.toJsonEventResponse({
82
+ status: 'healthy',
83
+ service: 'shell',
84
+ checkedAt,
85
+ });
86
+ },
87
+ );
88
+ ```
89
+
90
+ Locally the clock is answered by the dev server, in production by whatever platform you deployed to, and in a test by a fixed timestamp you supply. That is why every function you call from a story is named `ask*`: it is a request, it has an answer, and it must be called with `yield*`.
91
+
92
+ | Term | What it is |
93
+ | --- | --- |
94
+ | **Action** | A plain, serializable object with a type and an optional payload |
95
+ | **Requester** | The `ask*` generator your story calls to yield an action |
96
+ | **Story** | A generator function composing requesters into business logic |
97
+ | **Processor** | The platform-specific function that actually performs an action |
98
+ | **Runtime** | The loop that runs a story, routes each yielded action to a processor, and logs the whole thing |
99
+
100
+ Three things fall out of that arrangement:
101
+
102
+ - **Tests need no infrastructure.** Mock actions by type and assert on the result.
103
+ ```typescript
104
+ const result = runStory(askGreet('world'), { [DateActionType.Now]: '2026-01-01T00:00:00.000Z' });
105
+ ```
106
+ - **Moving platforms is a config change.** The stories do not know or care which processor set answered them.
107
+ - **Every run leaves a complete log.** Because all side effects pass through the runtime, you get execution logs, replay, and statement-level traces without instrumenting anything. That is what the [admin console](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-web-admin) reads.
108
+
109
+ The [ESLint plugin](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-eslint-config) enforces both halves of the `ask` contract: always `yield*` an ask call, never name a plain function `ask*`.
110
+
111
+ ## Packages
112
+
113
+ **Start here**
114
+
115
+ | Package | Description |
116
+ | --- | --- |
117
+ | [create-qpq-app](https://github.com/qpqjs/quidproquo/tree/main/create-qpq-app) | Scaffolder. `npx create-qpq-app my-app` |
118
+ | [quidproquo](https://github.com/qpqjs/quidproquo/tree/main/quidproquo) | The main entry point. Re-exports core and webserver |
119
+ | [quidproquo-cli](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-cli) | The `qpq` CLI: dev, build, deploy and teardown |
120
+
121
+ **Framework**
122
+
123
+ | Package | Description |
124
+ | --- | --- |
125
+ | [quidproquo-core](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-core) | Actions, stories, the runtime, and the config system |
126
+ | [quidproquo-webserver](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-webserver) | Routes, apis, websockets, dns, email, and the web-side config |
127
+ | [quidproquo-features](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-features) | Ready-made features: admin, auth users, tenants, event documents |
128
+
129
+ **Runtimes**
130
+
131
+ | Package | Description |
132
+ | --- | --- |
133
+ | [quidproquo-actionprocessor-js](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-actionprocessor-js) | Processors that need no platform at all |
134
+ | [quidproquo-actionprocessor-node](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-actionprocessor-node) | Node processors |
135
+ | [quidproquo-actionprocessor-awslambda](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-actionprocessor-awslambda) | AWS processors and the Lambda entry handlers |
136
+ | [quidproquo-actionprocessor-web](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-actionprocessor-web) | Browser processors |
137
+ | [quidproquo-dev-server](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-dev-server) | Runs your whole app locally on real code paths |
138
+
139
+ **Frontend**
140
+
141
+ | Package | Description |
142
+ | --- | --- |
143
+ | [quidproquo-web](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-web) | Browser utilities, no UI framework required |
144
+ | [quidproquo-web-react](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-web-react) | React bindings: state store, hooks, auth, websockets |
145
+ | [quidproquo-web-admin](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-web-admin) | The admin console: logs, traces, config, maintenance |
146
+
147
+ **Build and deploy**
148
+
149
+ | Package | Description |
150
+ | --- | --- |
151
+ | [quidproquo-config-aws](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-config-aws) | AWS-specific config settings |
152
+ | [quidproquo-deploy-awscdk](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-deploy-awscdk) | Turns a qpq config into CDK stacks |
153
+ | [quidproquo-deploy-rspack](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-deploy-rspack) | Rspack bundling for services and federated remotes |
154
+ | [quidproquo-deploy-webpack](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-deploy-webpack) | The same, on webpack |
155
+
156
+ **Tooling**
157
+
158
+ | Package | Description |
159
+ | --- | --- |
160
+ | [quidproquo-tsconfig](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-tsconfig) | Shared TypeScript config |
161
+ | [quidproquo-eslint-config](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-eslint-config) | Shared ESLint config and the qpq lint rules |
162
+ | [quidproquo-testing](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-testing) | Generator assertions and vitest matchers |
163
+
164
+ **Integrations**
165
+
166
+ | Package | Description |
167
+ | --- | --- |
168
+ | [quidproquo-neo4j](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-neo4j) | Neo4j behind the graph database actions |
169
+ | [quidproquo-xstate](https://github.com/qpqjs/quidproquo/tree/main/quidproquo-xstate) | XState machines as qpq actions |
170
+
171
+ ## Working on the framework
172
+
173
+ The repo is an npm workspace. From the root:
174
+
175
+ ```bash
176
+ npm install
177
+ npm run build # build every package
178
+ npm run build:lite # only what changed since the last build
179
+ npm run test # vitest across the workspace
180
+ npm run lint # eslint across the workspace
181
+ npm run validate # lint, build, test, and typecheck the test suite
182
+ ```
183
+
184
+ Target a single package with `-w`, for example `npm run watch -w quidproquo-core`.
185
+
186
+ Tests run on vitest and alias sibling packages to their `src`, so you do not need to build before running them.
187
+
188
+ ## Status
189
+
190
+ Pre-1.0. The whole family releases in lockstep, so any set of `quidproquo-*` versions that share a number was built and tested together. Expect APIs to move between releases, and pin your versions.
191
+
192
+ ## Documentation
193
+
194
+ Full docs, including the action reference, live at **[docs.quidproquojs.com](https://docs.quidproquojs.com)**. The site is built from [quidproquojs.com/docusaurus](https://github.com/qpqjs/quidproquo/tree/main/quidproquojs.com/docusaurus) in this repo, and the app around it is a real qpq workspace that doubles as the `create-qpq-app` template.
195
+
196
+ ## License
197
+
198
+ MIT. See [LICENSE](https://github.com/qpqjs/quidproquo/blob/main/LICENSE).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -9,6 +9,9 @@
9
9
  "files": [
10
10
  "lib/**/*"
11
11
  ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
12
15
  "scripts": {
13
16
  "test": "vitest run",
14
17
  "test:watch": "vitest",
@@ -23,21 +26,21 @@
23
26
  },
24
27
  "repository": {
25
28
  "type": "git",
26
- "url": "git+https://github.com/joe-coady/quidproquo.git"
29
+ "url": "git+https://github.com/qpqjs/quidproquo.git"
27
30
  },
28
31
  "keywords": [],
29
32
  "author": "",
30
33
  "license": "MIT",
31
34
  "bugs": {
32
- "url": "https://github.com/joe-coady/quidproquo/issues"
35
+ "url": "https://github.com/qpqjs/quidproquo/issues"
33
36
  },
34
- "homepage": "https://github.com/joe-coady/quidproquo#readme",
37
+ "homepage": "https://github.com/qpqjs/quidproquo#readme",
35
38
  "devDependencies": {
36
39
  "typescript": "^5.8.2",
37
- "quidproquo-tsconfig": "0.1.16"
40
+ "quidproquo-tsconfig": "0.1.17"
38
41
  },
39
42
  "dependencies": {
40
- "quidproquo-core": "0.1.16",
41
- "quidproquo-webserver": "0.1.16"
43
+ "quidproquo-core": "0.1.17",
44
+ "quidproquo-webserver": "0.1.17"
42
45
  }
43
46
  }