@jarenjs/linq 0.83.3 → 0.85.0

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.
package/README.md CHANGED
@@ -16,7 +16,7 @@ it by hand, as JSON, with nothing checking it until it ran.
16
16
  This package removes the price. You write the query, the schema, the
17
17
  model, the migration, the contract, the stylesheet, the state machine,
18
18
  the dataflow, the application, the form, chart, project, text template,
19
- message catalog or AI program as ordinary typed JavaScript,
19
+ message catalog as ordinary typed JavaScript,
20
20
  and what comes back is the document — exactly the one its engine
21
21
  already takes, byte for byte, with its types derived beside it. The
22
22
  chain is the pen; the document is the deliverable.
@@ -49,7 +49,7 @@ SQL — and nothing is hidden: the chain's `explain()` shows the document
49
49
  it sent, and the store's `explain(document)` shows what that became,
50
50
  `SELECT … FROM "User" WHERE "age" > ? ORDER BY "name"`.
51
51
 
52
- Coverage: <!--fact:coverage.pens-->15 public pen/client subpaths beside the chain; 69/69 owned schema keywords have dedicated emission routes.<!--/fact-->
52
+ Coverage: <!--fact:coverage.pens-->15 public pen/client/authoring subpaths beside the chain; 69/69 owned schema keywords have dedicated emission routes.<!--/fact-->
53
53
 
54
54
  ## What you gain
55
55
 
@@ -100,7 +100,6 @@ Coverage: <!--fact:coverage.pens-->15 public pen/client subpaths beside the chai
100
100
  | a state machine, a dataflow | `@jarenjs/linq/flow` | `@jarenjs/flow` | [flow pen](#by-code-the-flow-pen) · [FLOW-PEN](docs/FLOW-PEN.md) |
101
101
  | an application | `@jarenjs/linq/app` | `@jarenjs/app` | [app pen](#by-code-the-app-pen) · [APP-PEN](docs/APP-PEN.md) |
102
102
  | a form | `@jarenjs/linq/forms` | `@jarenjs/forms` | [forms pen](#by-code-the-forms-pen) · [FORMS-PEN](docs/FORMS-PEN.md) |
103
- | an AI action program | `@jarenjs/linq/ai` | `@jarenjs/ai` | [AI-PEN](docs/AI-PEN.md) |
104
103
  | a message catalog | `@jarenjs/linq/messages` | `@jarenjs/core/message` | [MESSAGES-PEN](docs/MESSAGES-PEN.md) |
105
104
  | a text template | `@jarenjs/linq/jtlt` | `@jarenjs/json/jtlt` | [JTLT-PEN](docs/JTLT-PEN.md) |
106
105
  | a Studio project | `@jarenjs/linq/project` | `@jarenjs/studio` | [PROJECT-PEN](docs/PROJECT-PEN.md) |
@@ -730,8 +729,8 @@ Every subpath a consumer can import, derived from the manifest by
730
729
  | `@jarenjs/linq/project` | JavaScript | declared |
731
730
  | `@jarenjs/linq/jtlt` | JavaScript | declared |
732
731
  | `@jarenjs/linq/messages` | JavaScript | declared |
733
- | `@jarenjs/linq/ai` | JavaScript | declared |
734
732
  | `@jarenjs/linq/formula` | JavaScript | declared |
733
+ | `@jarenjs/linq/authoring` | JavaScript | declared |
735
734
  <!--/fact-->
736
735
 
737
736
  Explicit cross-provider joins use `federate({ sources, maxRows, maxBytes,
@@ -744,3 +743,13 @@ planning, buffering limits and cleanup guarantees.
744
743
  ## Saved formula documents
745
744
 
746
745
  `@jarenjs/linq/formula` exports `defineFormula` for immutable JSON Query profiles with revision, bindings and schema/helper references. See [FORMULA-PEN](docs/FORMULA-PEN.md); execution remains in json/formula.
746
+
747
+ ## Authoring custom documents
748
+
749
+ `@jarenjs/linq/authoring` exposes `DocumentBuilder`, `snapshot`, `optionsOf` and
750
+ `captureQuery` for pens that produce ordinary JSON documents. Builder snapshots
751
+ are deeply frozen; `with()` creates a new instance of the same subclass.
752
+ `optionsOf` enforces a closed set of option keys. `captureQuery` uses the same
753
+ expression capture as the built-in pens; external names are explicit and an
754
+ undeclared name retains the `JL0104` refusal. Compilation remains the consumer's
755
+ responsibility. Use expression `get()` for field names that overlap methods.
package/docs/DB-CLIENT.md CHANGED
@@ -843,10 +843,10 @@ never builds one; the migration between two of them is
843
843
 
844
844
  ## 7. Cost
845
845
 
846
- `@jarenjs/linq/db` builds to **<!--fact:bundle.db-->675,752<!--/fact--> bytes** as a minified,
846
+ `@jarenjs/linq/db` builds to **<!--fact:bundle.db-->724,099<!--/fact--> bytes** as a minified,
847
847
  tree-shaken ESM bundle — the figure `scripts/check-tree-shaking.js`
848
848
  measures and `npm run test:tree-shaking` reports, published rounded
849
- (<!--fact:bundle.db.kb-->676<!--/fact--> kB) beside the other nine subpath prices in
849
+ (<!--fact:bundle.db.kb-->724<!--/fact--> kB) beside the other nine subpath prices in
850
850
  [docs/CONSUMING.md](../../../docs/CONSUMING.md).
851
851
 
852
852
  It is by far the largest of the ten, and the reason is §1.1's edge rather
package/docs/JSLT-PEN.md CHANGED
@@ -893,7 +893,7 @@ non-judgement is itself gated.
893
893
  ### 6.6 When not to reach for this pen
894
894
 
895
895
  - **The stylesheet is data.** A `$jslt` document loaded from a file,
896
- authored by a model ([@jarenjs/ai](../../ai/README.md)'s authoring
896
+ authored by a model ([Tangle authoring](https://github.com/jklarenbeek/tangleai/blob/main/packages/jaren/docs/AUTHORING.md)'s authoring
897
897
  profile writes them) or edited in the studio is a value;
898
898
  `compileJsltStylesheet` takes it directly and nothing here has to be in
899
899
  the path.
@@ -16,9 +16,9 @@ A **pen** is a by-code front-end to one of the suite's document formats:
16
16
  named functions that build a standard document — a JSON Schema, a
17
17
  `$model`, a `$jslt` stylesheet — the way the chain builds a query
18
18
  document. `@jarenjs/linq` exports each pen under its own subpath
19
- (<!--fact:coverage.subpaths-->`./ai`, `./app`, `./charts`, `./contract`, `./db`, `./flow`, `./forms`, `./formula`, `./jslt`, `./jtlt`, `./messages`, `./migration`, `./model`, `./project`, `./schema`<!--/fact-->); `.` stays the chain.
19
+ (<!--fact:coverage.subpaths-->`./app`, `./authoring`, `./charts`, `./contract`, `./db`, `./flow`, `./forms`, `./formula`, `./jslt`, `./jtlt`, `./messages`, `./migration`, `./model`, `./project`, `./schema`<!--/fact-->); `.` stays the chain.
20
20
 
21
- Coverage: <!--fact:coverage.pens-->15 public pen/client subpaths beside the chain; 69/69 owned schema keywords have dedicated emission routes.<!--/fact-->
21
+ Coverage: <!--fact:coverage.pens-->15 public pen/client/authoring subpaths beside the chain; 69/69 owned schema keywords have dedicated emission routes.<!--/fact-->
22
22
 
23
23
  **This document is the family's normative reference**: §1 states the
24
24
  rules every pen keeps, §1.3 the error codes they share, and §4–§7 the
@@ -36,8 +36,8 @@ is the index of those guides, and it is how a reader reaches any of them.
36
36
  <!--fact:pens.index-->
37
37
  | Document | Lines | What it writes, and when to open it |
38
38
  |---|---:|---|
39
- | [LINQ-FORMAT.md](LINQ-FORMAT.md) | 965 | this file, the binder and the family's **normative reference**: what a pen is, the rules all of them keep, the shared `JL01xx` table, and the cross-pen views derived from the guides it indexes. **Read it when** you want a rule that is true of every pen, an index of the documents, or one place to look up a method without knowing which pen owns it |
40
- | [QUERY-PEN.md](QUERY-PEN.md) | 1,752 | the chain, `.` — query documents (`jaren-query`) and the provider seam. **Read it when** you are querying data, or implementing a provider that answers a query document |
39
+ | [LINQ-FORMAT.md](LINQ-FORMAT.md) | 944 | this file, the binder and the family's **normative reference**: what a pen is, the rules all of them keep, the shared `JL01xx` table, and the cross-pen views derived from the guides it indexes. **Read it when** you want a rule that is true of every pen, an index of the documents, or one place to look up a method without knowing which pen owns it |
40
+ | [QUERY-PEN.md](QUERY-PEN.md) | 1,761 | the chain, `.` — query documents (`jaren-query`) and the provider seam. **Read it when** you are querying data, or implementing a provider that answers a query document |
41
41
  | [SCHEMA-PEN.md](SCHEMA-PEN.md) | 1,205 | `./schema` — JSON Schema 2020-12: the structural keywords, the constraints and the annotations, each with a method of its own, plus `$query`, `$defs`/`$ref` recursion and the normalizer's per-field predicates. **Read it when** you are describing the shape of data — for validation, for a form, or as the base of an entity |
42
42
  | [MODEL-PEN.md](MODEL-PEN.md) | 1,116 | `./model` — the `x-entity` vocabulary on JSON Schema, and the `$model` 0.1 document `openStore` accepts unchanged. **Read it when** you are declaring a store's entities, their keys and their relations |
43
43
  | [JSLT-PEN.md](JSLT-PEN.md) | 955 | `./jslt` — `$jslt` 0.1 stylesheets: the envelope and its rules, whose bodies are captured over the matched value. **Read it when** you are transforming one document into another |
@@ -46,7 +46,6 @@ is the index of those guides, and it is how a reader reaches any of them.
46
46
  | [FLOW-PEN.md](FLOW-PEN.md) | 1,033 | `./flow` — `jaren-fsm` 0.1 machines and `jaren-dag` 0.1 dataflows, every query-valued member captured. **Read it when** you are declaring a state machine or a dependency graph of tasks |
47
47
  | [APP-PEN.md](APP-PEN.md) | 1,143 | `./app` — the `jaren-app` 0.1 document `createApp` runs, and the JSON Schema of its state beside it. **Read it when** you are declaring a whole application: state, view, actions, effects |
48
48
  | [FORMS-PEN.md](FORMS-PEN.md) | 940 | `./forms` — the `x-form` vocabulary on JSON Schema, and `assertOnSubmit()`, the same rules' layer-3 `$query` twin. **Read it when** you are turning a schema into a form |
49
- | [AI-PEN.md](AI-PEN.md) | 98 | `./ai` — the public action program over environment slots. **Read it when** you want typed fixtures or host-authored programs without a model client. |
50
49
  | [MESSAGES-PEN.md](MESSAGES-PEN.md) | 105 | `./messages` — JSON message catalogs and message references. **Read it when** you want checked translation keys, placeholders and explicit completeness. |
51
50
  | [JTLT-PEN.md](JTLT-PEN.md) | 83 | `./jtlt` — text templates with JSLT dispatch and query expressions. **Read it when** you want to author Markdown, XML or source text as portable JSON. |
52
51
  | [PROJECT-PEN.md](PROJECT-PEN.md) | 81 | `./project` — Studio projects with named, typed files. **Read it when** you want a portable editor workspace containing documents written by several pens. |
@@ -95,7 +94,6 @@ data rather than for a program has no compile step to be faithful to.
95
94
  | `$fsm` 0.1, `$dag` 0.1 (`jaren-fsm`, `jaren-dag`) | `@jarenjs/flow` | **`./flow`** | [FLOW-PEN.md](FLOW-PEN.md) |
96
95
  | `jaren-app` 0.1 | `@jarenjs/app` | **`./app`** | [APP-PEN.md](APP-PEN.md) |
97
96
  | `x-form` on JSON Schema | `@jarenjs/forms` | **`./forms`** | [FORMS-PEN.md](FORMS-PEN.md) |
98
- | AI action program | `@jarenjs/ai` | **`./ai`** | [AI-PEN.md](AI-PEN.md) |
99
97
  | message catalogs / MessageSpec | `@jarenjs/core`, validate/forms/contract | **`./messages`** | [MESSAGES-PEN.md](MESSAGES-PEN.md) |
100
98
  | `$jtlt` 0.1 (`jaren-jtlt`) | `@jarenjs/json` | **`./jtlt`** | [JTLT-PEN.md](JTLT-PEN.md) |
101
99
  | `jaren-project` | `@jarenjs/studio` | **`./project`** | [PROJECT-PEN.md](PROJECT-PEN.md) |
@@ -205,8 +203,8 @@ and the bundle is the byte count the tree-shaking probe builds.
205
203
  <!--fact:pens.census-->
206
204
  | Document | Subpath | Lines | Mapping rows | Worked examples | Refusals | Bundle |
207
205
  |---|---|---:|---:|---:|---:|---:|
208
- | [LINQ-FORMAT.md](LINQ-FORMAT.md) | — | 965 | — | — | — | — |
209
- | [QUERY-PEN.md](QUERY-PEN.md) | `.` | 1,752 | 34 | 8 | 15 | 175,221 B |
206
+ | [LINQ-FORMAT.md](LINQ-FORMAT.md) | — | 944 | — | — | — | — |
207
+ | [QUERY-PEN.md](QUERY-PEN.md) | `.` | 1,761 | 34 | 8 | 15 | 175,560 B |
210
208
  | [SCHEMA-PEN.md](SCHEMA-PEN.md) | `./schema` | 1,205 | 82 | 10 | 4 | 35,285 B |
211
209
  | [MODEL-PEN.md](MODEL-PEN.md) | `./model` | 1,116 | 30 | 6 | 3 | 44,143 B |
212
210
  | [JSLT-PEN.md](JSLT-PEN.md) | `./jslt` | 955 | 17 | 8 | 3 | 18,424 B |
@@ -215,14 +213,13 @@ and the bundle is the byte count the tree-shaking probe builds.
215
213
  | [FLOW-PEN.md](FLOW-PEN.md) | `./flow` | 1,033 | 16 | 7 | 3 | 18,478 B |
216
214
  | [APP-PEN.md](APP-PEN.md) | `./app` | 1,143 | 22 | 7 | 3 | 49,574 B |
217
215
  | [FORMS-PEN.md](FORMS-PEN.md) | `./forms` | 940 | 18 | 6 | 3 | 39,441 B |
218
- | [AI-PEN.md](AI-PEN.md) | `./ai` | 98 | 12 | 1 | 3 | 15,472 B |
219
216
  | [MESSAGES-PEN.md](MESSAGES-PEN.md) | `./messages` | 105 | 9 | 2 | 1 | 16,931 B |
220
217
  | [JTLT-PEN.md](JTLT-PEN.md) | `./jtlt` | 83 | 13 | 1 | 2 | 15,293 B |
221
218
  | [PROJECT-PEN.md](PROJECT-PEN.md) | `./project` | 81 | 9 | 1 | 1 | 13,793 B |
222
219
  | [CHARTS-PEN.md](CHARTS-PEN.md) | `./charts` | 94 | 21 | 1 | 1 | 15,582 B |
223
- | [DB-CLIENT.md](DB-CLIENT.md) | `./db` | 1,085 | 46 | 4 | 2 | 675,752 B |
220
+ | [DB-CLIENT.md](DB-CLIENT.md) | `./db` | 1,085 | 46 | 4 | 2 | 724,099 B |
224
221
  | [FORMULA-PEN.md](FORMULA-PEN.md) | `./formula` | 41 | 2 | — | — | 14,850 B |
225
- | **17 documents** | | **12,698** | **380** | **73** | | |
222
+ | **16 documents** | | **12,588** | **368** | **72** | | |
226
223
  <!--/fact-->
227
224
 
228
225
  A pen whose mapping rows are far below its worked examples is a pen
@@ -241,10 +238,10 @@ throws, so this table moves when a pen's source does.
241
238
  <!--fact:pens.codes-->
242
239
  | Code | Raised by |
243
240
  |---|---|
244
- | `JL0101` | [SCHEMA-PEN.md](SCHEMA-PEN.md), [MODEL-PEN.md](MODEL-PEN.md), [JSLT-PEN.md](JSLT-PEN.md), [MIGRATION-PEN.md](MIGRATION-PEN.md), [CONTRACT-PEN.md](CONTRACT-PEN.md), [FLOW-PEN.md](FLOW-PEN.md), [APP-PEN.md](APP-PEN.md), [FORMS-PEN.md](FORMS-PEN.md), [AI-PEN.md](AI-PEN.md), [MESSAGES-PEN.md](MESSAGES-PEN.md), [JTLT-PEN.md](JTLT-PEN.md), [PROJECT-PEN.md](PROJECT-PEN.md), [CHARTS-PEN.md](CHARTS-PEN.md), [DB-CLIENT.md](DB-CLIENT.md) |
245
- | `JL0102` | [SCHEMA-PEN.md](SCHEMA-PEN.md), [MODEL-PEN.md](MODEL-PEN.md), [JSLT-PEN.md](JSLT-PEN.md), [MIGRATION-PEN.md](MIGRATION-PEN.md), [CONTRACT-PEN.md](CONTRACT-PEN.md), [FLOW-PEN.md](FLOW-PEN.md), [APP-PEN.md](APP-PEN.md), [FORMS-PEN.md](FORMS-PEN.md), [AI-PEN.md](AI-PEN.md) |
241
+ | `JL0101` | [SCHEMA-PEN.md](SCHEMA-PEN.md), [MODEL-PEN.md](MODEL-PEN.md), [JSLT-PEN.md](JSLT-PEN.md), [MIGRATION-PEN.md](MIGRATION-PEN.md), [CONTRACT-PEN.md](CONTRACT-PEN.md), [FLOW-PEN.md](FLOW-PEN.md), [APP-PEN.md](APP-PEN.md), [FORMS-PEN.md](FORMS-PEN.md), [MESSAGES-PEN.md](MESSAGES-PEN.md), [JTLT-PEN.md](JTLT-PEN.md), [PROJECT-PEN.md](PROJECT-PEN.md), [CHARTS-PEN.md](CHARTS-PEN.md), [DB-CLIENT.md](DB-CLIENT.md) |
242
+ | `JL0102` | [SCHEMA-PEN.md](SCHEMA-PEN.md), [MODEL-PEN.md](MODEL-PEN.md), [JSLT-PEN.md](JSLT-PEN.md), [MIGRATION-PEN.md](MIGRATION-PEN.md), [CONTRACT-PEN.md](CONTRACT-PEN.md), [FLOW-PEN.md](FLOW-PEN.md), [APP-PEN.md](APP-PEN.md), [FORMS-PEN.md](FORMS-PEN.md) |
246
243
  | `JL0103` | [SCHEMA-PEN.md](SCHEMA-PEN.md), [CONTRACT-PEN.md](CONTRACT-PEN.md) |
247
- | `JL0104` | [SCHEMA-PEN.md](SCHEMA-PEN.md), [MODEL-PEN.md](MODEL-PEN.md), [JSLT-PEN.md](JSLT-PEN.md), [MIGRATION-PEN.md](MIGRATION-PEN.md), [FLOW-PEN.md](FLOW-PEN.md), [APP-PEN.md](APP-PEN.md), [FORMS-PEN.md](FORMS-PEN.md), [AI-PEN.md](AI-PEN.md), [JTLT-PEN.md](JTLT-PEN.md) |
244
+ | `JL0104` | [SCHEMA-PEN.md](SCHEMA-PEN.md), [MODEL-PEN.md](MODEL-PEN.md), [JSLT-PEN.md](JSLT-PEN.md), [MIGRATION-PEN.md](MIGRATION-PEN.md), [FLOW-PEN.md](FLOW-PEN.md), [APP-PEN.md](APP-PEN.md), [FORMS-PEN.md](FORMS-PEN.md), [JTLT-PEN.md](JTLT-PEN.md) |
248
245
  | `JL0105` | [QUERY-PEN.md](QUERY-PEN.md) |
249
246
  | `JL0106` | [MIGRATION-PEN.md](MIGRATION-PEN.md) |
250
247
  | `JL0107` | [DB-CLIENT.md](DB-CLIENT.md) |
@@ -264,7 +261,7 @@ it and each document publishes it. The rounded column is what
264
261
  <!--fact:pens.cost-->
265
262
  | Subpath | Document | Bundle | Rounded |
266
263
  |---|---|---:|---:|
267
- | `@jarenjs/linq` | [QUERY-PEN.md](QUERY-PEN.md) | 175,221 B | 175 kB |
264
+ | `@jarenjs/linq` | [QUERY-PEN.md](QUERY-PEN.md) | 175,560 B | 176 kB |
268
265
  | `@jarenjs/linq/schema` | [SCHEMA-PEN.md](SCHEMA-PEN.md) | 35,285 B | 35 kB |
269
266
  | `@jarenjs/linq/model` | [MODEL-PEN.md](MODEL-PEN.md) | 44,143 B | 44 kB |
270
267
  | `@jarenjs/linq/jslt` | [JSLT-PEN.md](JSLT-PEN.md) | 18,424 B | 18 kB |
@@ -273,12 +270,11 @@ it and each document publishes it. The rounded column is what
273
270
  | `@jarenjs/linq/flow` | [FLOW-PEN.md](FLOW-PEN.md) | 18,478 B | 18 kB |
274
271
  | `@jarenjs/linq/app` | [APP-PEN.md](APP-PEN.md) | 49,574 B | 50 kB |
275
272
  | `@jarenjs/linq/forms` | [FORMS-PEN.md](FORMS-PEN.md) | 39,441 B | 39 kB |
276
- | `@jarenjs/linq/ai` | [AI-PEN.md](AI-PEN.md) | 15,472 B | 15 kB |
277
273
  | `@jarenjs/linq/messages` | [MESSAGES-PEN.md](MESSAGES-PEN.md) | 16,931 B | 17 kB |
278
274
  | `@jarenjs/linq/jtlt` | [JTLT-PEN.md](JTLT-PEN.md) | 15,293 B | 15 kB |
279
275
  | `@jarenjs/linq/project` | [PROJECT-PEN.md](PROJECT-PEN.md) | 13,793 B | 14 kB |
280
276
  | `@jarenjs/linq/charts` | [CHARTS-PEN.md](CHARTS-PEN.md) | 15,582 B | 16 kB |
281
- | `@jarenjs/linq/db` | [DB-CLIENT.md](DB-CLIENT.md) | 675,752 B | 676 kB |
277
+ | `@jarenjs/linq/db` | [DB-CLIENT.md](DB-CLIENT.md) | 724,099 B | 724 kB |
282
278
  | `@jarenjs/linq/formula` | [FORMULA-PEN.md](FORMULA-PEN.md) | 14,850 B | 15 kB |
283
279
  <!--/fact-->
284
280
 
@@ -796,23 +792,6 @@ it says.
796
792
  | `computed` | query | `x-form.computed` | the field's derived value, mapped to plain JSON. A failure leaves the value absent |
797
793
  | `message` | string or MessageSpec | `x-form.message`, verbatim | what an `assert` failure renders — an inline template, or `{ $msgid, message?, params? }` for the catalog |
798
794
 
799
- ### The AI program pen — [AI-PEN.md §2](AI-PEN.md)
800
-
801
- | Factory / method | Emits | Type | Status |
802
- |---|---|---|---|
803
- | `program(slots?)` | empty `steps` | declared input names | native |
804
- | `chunk(from, as, options?)`, `.chunk(...)` | chunk; strategy and size | result family | native |
805
- | `grep(from, as, options)`, `.grep(...)` | grep; pattern, flags, limit | match-list slot | native |
806
- | `select(from, as, query)`, `.select(...)` | select; query JSON | result slot | native |
807
- | `stat(from, as)`, `.stat(...)` | stat | result slot | native |
808
- | `peek(from, as)`, `.peek(...)` | peek | result slot | native |
809
- | `map(from, as, prompt)`, `.map(...)` | map; bounded instruction | result family | native |
810
- | `reduce(from, as, query, options?)`, `.reduce(...)` | reduce; query JSON and optional `outputSchema` | result slot | native |
811
- | `answer(from, options?)`, `.answer(...)` | answer; optional chars, no as | terminal program | native |
812
- | `.step(step)` | appends a public step | tracks its input/result names | native |
813
- | `from(document)` | raw program | no binding-order inference | native |
814
- | `.schema`, `.toJSON()` | frozen public JSON | program document | native |
815
-
816
795
  ### The messages pen — [MESSAGES-PEN.md §2](MESSAGES-PEN.md)
817
796
 
818
797
  | Method | Emits | Type | Status |
package/docs/QUERY-PEN.md CHANGED
@@ -1683,14 +1683,14 @@ are shorter:
1683
1683
  ## 17. Cost
1684
1684
 
1685
1685
  A consumer importing `from` from `@jarenjs/linq` and calling one
1686
- terminal bundles **<!--fact:bundle.chain-->175,221<!--/fact--> bytes** (esbuild, ESM, minified, tree-shaken,
1686
+ terminal bundles **<!--fact:bundle.chain-->175,560<!--/fact--> bytes** (esbuild, ESM, minified, tree-shaken,
1687
1687
  `platform: 'neutral'`). The figure is measured by
1688
1688
  `scripts/check-tree-shaking.js`'s chain probe and compared with this
1689
1689
  section on every `npm run test:tree-shaking`: it is derived, never typed,
1690
1690
  and a stale one is red here rather than wrong in a document somebody
1691
1691
  reads.
1692
1692
 
1693
- Of that, **<!--fact:bundle.chain.own-->38,701<!--/fact--> bytes** are the chain's own modules — `sequence.js`,
1693
+ Of that, **<!--fact:bundle.chain.own-->39,040<!--/fact--> bytes** are the chain's own modules — `sequence.js`,
1694
1694
  `async.js`, `expression.js`, `document.js`, `provider.js`,
1695
1695
  `concurrency.js`, `errors.js` and `schema-of.js`. The remaining ~134 kB
1696
1696
  is the query ENGINE and the core it stands on: a chain's document has to
@@ -1716,8 +1716,8 @@ making:
1716
1716
 
1717
1717
  `docs/CONSUMING.md` states the rounded price of all ten subpaths in one
1718
1718
  table, each figure held equal to the same measurements. Two of its rows
1719
- are the ones to read together: the chain at <!--fact:bundle.chain.kb-->175<!--/fact--> kB and
1720
- `./db` at <!--fact:bundle.db.kb-->676<!--/fact--> kB.
1719
+ are the ones to read together: the chain at <!--fact:bundle.chain.kb-->176<!--/fact--> kB and
1720
+ `./db` at <!--fact:bundle.db.kb-->724<!--/fact--> kB.
1721
1721
  The client costs what the store costs, by construction, and the chain
1722
1722
  costs what running a query costs.
1723
1723
 
@@ -1726,7 +1726,7 @@ the reason is worth knowing: a bundler counts a shared module once, and
1726
1726
  the chain and every pen share the expression capture (`expression.js`)
1727
1727
  and the coded errors under it (`errors.js`, and `@jarenjs/core`'s error
1728
1728
  and object helpers). A consumer importing the chain AND the schema pen
1729
- bundles **<!--fact:bundle.chain.withSchemaPen-->199,375<!--/fact--> bytes** — **<!--fact:bundle.chain.shared-->11,131<!--/fact--> bytes** less than the sum of the
1729
+ bundles **<!--fact:bundle.chain.withSchemaPen-->199,716<!--/fact--> bytes** — **<!--fact:bundle.chain.shared-->11,129<!--/fact--> bytes** less than the sum of the
1730
1730
  figure above and [SCHEMA-PEN.md](SCHEMA-PEN.md#7-cost) §7's, which is
1731
1731
  what those shared modules weigh. The probe measures that pair too, so
1732
1732
  the saving is derived like everything else here. What the chain does NOT
@@ -1750,3 +1750,12 @@ never builds an index or runs a second ranker. Compile the emitted document with
1750
1750
  `createLexicalProvider` capability that a hand-written query uses. The ordinary
1751
1751
  sequence provider has no implicit search catalog. Filters/facets run before top-k,
1752
1752
  continuations bind the source snapshot, and `$search` remains regex-based.
1753
+
1754
+ For synchronous providers, iteration uses an available `syncQuery(document,
1755
+ options)` cursor and propagates early return to release it. Providers without
1756
+ that member retain their collecting behavior. SQLite entity planning flattens
1757
+ safe identity/object projection chains and projected joins followed by filters
1758
+ and ordering; it retains barriers around windows, grouping and inner ordering.
1759
+ Standalone supported physical min/max and integer sum/average use guarded native
1760
+ aggregates. Explicit SQLite null, collation, raw JSON text and byte semantics are
1761
+ available through [the data layer native surface](../../db/docs/SQLITE-RELATIONAL.md).
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jarenjs/linq",
3
3
  "private": false,
4
- "version": "0.83.3",
4
+ "version": "0.85.0",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "types": "./types/index.d.ts",
@@ -64,13 +64,13 @@
64
64
  "types": "./types/messages.d.ts",
65
65
  "default": "./src/messages/index.js"
66
66
  },
67
- "./ai": {
68
- "types": "./types/ai.d.ts",
69
- "default": "./src/ai/index.js"
70
- },
71
67
  "./formula": {
72
68
  "types": "./types/formula.d.ts",
73
69
  "default": "./src/formula/index.js"
70
+ },
71
+ "./authoring": {
72
+ "types": "./types/authoring.d.ts",
73
+ "default": "./src/authoring.js"
74
74
  }
75
75
  },
76
76
  "files": [
@@ -108,13 +108,13 @@
108
108
  "prepack": "npm run build:types"
109
109
  },
110
110
  "dependencies": {
111
- "@jarenjs/core": "^0.83.3",
112
- "@jarenjs/json": "^0.83.3"
111
+ "@jarenjs/core": "^0.85.0",
112
+ "@jarenjs/json": "^0.85.0"
113
113
  },
114
114
  "peerDependencies": {
115
- "@jarenjs/db": "^0.83.3",
116
- "@jarenjs/formats": "^0.83.3",
117
- "@jarenjs/validate": "^0.83.3"
115
+ "@jarenjs/db": "^0.85.0",
116
+ "@jarenjs/formats": "^0.85.0",
117
+ "@jarenjs/validate": "^0.85.0"
118
118
  },
119
119
  "peerDependenciesMeta": {
120
120
  "@jarenjs/db": {
@@ -0,0 +1,4 @@
1
+ //@ts-check
2
+ /** Immutable document building and query capture for authored-format pens. */
3
+ export { DocumentBuilder, optionsOf, snapshot } from './authored.js';
4
+ export { captureQuery } from './capture-root.js';
package/src/sequence.js CHANGED
@@ -507,6 +507,16 @@ export class Sequence {
507
507
  }
508
508
 
509
509
  * [Symbol.iterator]() {
510
+ if (this.#sourceKind === 'provider' && typeof this.#source.syncQuery === 'function') {
511
+ const document = this.toDocument();
512
+ const cursor = this.#source.syncQuery(document === this.#root
513
+ ? { $for: { it: this.#root }, $return: '$it' } : document,
514
+ { externals: Object.fromEntries(this.#params) });
515
+ if (cursor == null || typeof cursor[Symbol.iterator] !== 'function')
516
+ throw new LinqRuntimeError('JL2004', 'syncQuery() must return a synchronous iterable cursor');
517
+ yield* cursor;
518
+ return;
519
+ }
510
520
  yield* this.toArray();
511
521
  }
512
522
 
@@ -0,0 +1,17 @@
1
+ import type { Expr } from './index.js';
2
+
3
+ /** A captured immutable JSON document; replacement preserves subclasses. */
4
+ export class DocumentBuilder<T extends object = Record<string, unknown>> {
5
+ constructor(document: T);
6
+ readonly schema: Readonly<T>;
7
+ toJSON(): Readonly<T>;
8
+ with(patch: Partial<T>): this;
9
+ }
10
+ /** Snapshot and freeze a JSON value; invalid JSON retains LinqBuildError codes. */
11
+ export function snapshot<T>(value: T): Readonly<T>;
12
+ /** Reject options outside the named closed boundary, then snapshot. */
13
+ export function optionsOf<T extends object>(value: T, keys: readonly string[], what: string): Readonly<T>;
14
+ /** Capture a query; undeclared external names retain JL0104 errors. */
15
+ export function captureQuery<T, E extends string>(what: string, externals: readonly E[],
16
+ rule: (value: Expr<T>, externals: Record<E, unknown>) => unknown,
17
+ options?: { advice?: (name: string) => string; fold?: boolean; noun?: string }): unknown;
@@ -408,7 +408,7 @@ export type ToolName<S extends string> =
408
408
  S extends `${infer A}.${infer B}` ? `${A}_${ToolName<B>}` : S;
409
409
 
410
410
  /** One tool definition, typed by the operation it invokes — the
411
- * `ToolDef` shape `@jarenjs/ai`'s `createToolbox().add` takes. */
411
+ * `ToolDef` shape browser or host operation registries takes. */
412
412
  export type TypedTool<C> = {
413
413
  [K in keyof InvokableOf<C>]: {
414
414
  name: ToolName<Extract<K, string>>;
package/types/index.d.ts CHANGED
@@ -457,6 +457,8 @@ export interface Provider<T = unknown> {
457
457
  /** The item phantom: never present at runtime; what `from` infers `T` from. */
458
458
  readonly __item?: T;
459
459
  execute(document: unknown, options: { externals: Record<string, unknown> }): unknown;
460
+ /** Optional native synchronous cursor; iteration closes it on early return. */
461
+ syncQuery?(document: unknown, options: { externals: Record<string, unknown> }): Iterable<T>;
460
462
  /** The root expression the items are bound through (`'$.Post[*]'`);
461
463
  * absent means the whole input, `'$[*]'`. */
462
464
  readonly root?: string;
package/types/model.d.ts CHANGED
@@ -66,12 +66,24 @@ export interface PhysicalLayout {
66
66
  readonly table: string;
67
67
  readonly kind?: 'table' | 'view';
68
68
  readonly keys?: readonly string[];
69
+ readonly constraints?: readonly object[];
70
+ readonly indexes?: readonly object[];
71
+ readonly triggers?: readonly object[];
72
+ readonly strict?: boolean;
73
+ readonly withoutRowid?: boolean;
69
74
  readonly columns: Readonly<Record<string, {
70
75
  readonly name: string;
71
76
  readonly codec: 'text' | 'integer' | 'number' | 'boolean' | 'json' | 'date' | 'datetime' | 'epoch-ms' | 'bigint' | 'decimal' | 'blob-hex';
72
77
  readonly null: 'null' | 'absent' | 'reject';
73
78
  readonly default?: 'database';
74
79
  readonly generated?: boolean;
80
+ readonly type?: 'INTEGER' | 'REAL' | 'TEXT' | 'BLOB' | 'NUMERIC';
81
+ readonly defaultValue?: unknown;
82
+ readonly collation?: 'BINARY' | 'NOCASE' | 'RTRIM';
83
+ readonly identity?: 'rowid' | 'autoincrement';
84
+ readonly check?: unknown;
85
+ readonly generatedExpression?: unknown;
86
+ readonly stored?: boolean;
75
87
  }>>;
76
88
  }
77
89
 
package/docs/AI-PEN.md DELETED
@@ -1,98 +0,0 @@
1
- # The AI program pen
2
-
3
- > `./ai` — the public action program over environment slots. **Read it when**
4
- > you want typed fixtures or host-authored programs without a model client.
5
-
6
- ## 1. What it writes
7
-
8
- The pen emits exactly `{ steps: [...] }`, the document consumed by the AI
9
- program schema, compiler and runner. It imports no AI engine or environment.
10
- `.schema` is an independent, deeply frozen JSON snapshot; `JSON.stringify()`
11
- writes that document. Updates return a new builder.
12
-
13
- `program(['corpus'])` declares input names for TypeScript; those names never
14
- become extra document members or an embedded registry. The compiler checks the
15
- real environment. Queries can be raw JSON or callbacks recorded over the input
16
- document, using the same capture as other pens and no runtime query engine.
17
-
18
- ## 2. The mapping table
19
-
20
- Factories return frozen public steps. The same method on a program appends that
21
- step. Every non-answer step writes `op`, `from` and `as` before its options.
22
-
23
- | Factory / method | Emits | Type | Status |
24
- |---|---|---|---|
25
- | `program(slots?)` | empty `steps` | declared input names | native |
26
- | `chunk(from, as, options?)`, `.chunk(...)` | chunk; strategy and size | result family | native |
27
- | `grep(from, as, options)`, `.grep(...)` | grep; pattern, flags, limit | match-list slot | native |
28
- | `select(from, as, query)`, `.select(...)` | select; query JSON | result slot | native |
29
- | `stat(from, as)`, `.stat(...)` | stat | result slot | native |
30
- | `peek(from, as)`, `.peek(...)` | peek | result slot | native |
31
- | `map(from, as, prompt)`, `.map(...)` | map; bounded instruction | result family | native |
32
- | `reduce(from, as, query, options?)`, `.reduce(...)` | reduce; query JSON and optional `outputSchema` | result slot | native |
33
- | `answer(from, options?)`, `.answer(...)` | answer; optional chars, no as | terminal program | native |
34
- | `.step(step)` | appends a public step | tracks its input/result names | native |
35
- | `from(document)` | raw program | no binding-order inference | native |
36
- | `.schema`, `.toJSON()` | frozen public JSON | program document | native |
37
-
38
- `chunk` options are `strategy: 'size' | 'line' | 'separator'` and `size`.
39
- `grep` requires `pattern`, with optional `flags: 'i' | 'm' | 'im' | ''` and
40
- `limit`. `answer` takes `chars`. The schema owns numeric and string bounds.
41
-
42
- ## 3. Worked examples
43
-
44
- ```js
45
- import { program } from '@jarenjs/linq/ai';
46
- export const plan = program(['corpus'])
47
- .chunk('corpus', 'pieces', { strategy: 'line', size: 200 })
48
- .map('pieces', 'found', 'Return the number in this piece as JSON')
49
- .reduce('found', 'count', { $count: '$[*]' })
50
- .answer('count', { chars: 50 });
51
- ```
52
- ```json
53
- {"steps":[{"op":"chunk","from":"corpus","as":"pieces","strategy":"line","size":200},{"op":"map","from":"pieces","as":"found","prompt":"Return the number in this piece as JSON"},{"op":"reduce","from":"found","as":"count","query":{"$count":"$[*]"}},{"op":"answer","from":"count","chars":50}]}
54
- ```
55
-
56
- Validate with `PROGRAM_SCHEMA` (or `programSchema({ queryRef })`), then
57
- `compileProgram`/`programGate` with the query compiler and known environment
58
- names. `createProgramRunner` does both shape and compile checks before execution.
59
- The standalone compile gate checks semantics; it does not replace the shape
60
- schema's numeric ranges, member closure or step-count cap.
61
-
62
- ## 4. Refusals
63
-
64
- | Code | Condition |
65
- |---|---|
66
- | `JL0101` | invalid slot/result name shape, unknown option/operation, non-JSON input, or a malformed input-name list |
67
- | `JL0102` | appending a step after answer |
68
- | `JL0104` | a query callback reads an external; program queries bind only their input document |
69
-
70
- The schema/compiler own unknown environment names, duplicate result bindings,
71
- missing answers, limits, query validity and family/slot semantics. `from()`
72
- preserves raw programs for those checks rather than carrying a second compiler.
73
-
74
- ## 5. The types
75
-
76
- `ProgramBuilder<Bindings, Done>` tracks names and whether answer has closed the
77
- program. `ProgramDocument`, `Step`, `StepDocument`, `StepOptions`, `Operation`,
78
- `Query`, `ChunkOptions`, `GrepOptions` and `AnswerOptions` are types only.
79
-
80
- A later step may read only a declared input or previous result. `select` and
81
- `answer` read individual slots, not chunk/map families; `reduce` reads map
82
- results. A result cannot be rebound, although an input slot can be shadowed as
83
- in the compiler. Standalone step factories retain literal names and `.step()`
84
- checks them on insertion. Raw documents claim neither binding order nor a
85
- terminal state. No inferred data schema, budget or successful-run guarantee is
86
- attached to a program.
87
-
88
- ## 6. What it cannot spell
89
-
90
- This is the action document, not a prompt/client wrapper. It neither pastes
91
- corpus contents into a private envelope nor runs model calls in query expressions.
92
- Only the existing runner's map step calls a model. Cancellation, concurrency,
93
- sub-call budgets, storage and result interpretation remain runner concerns.
94
-
95
- ## 7. Cost
96
-
97
- The isolated AI program pen costs **<!--fact:bundle.ai-->15,472<!--/fact--> bytes**.
98
- Its tree probe excludes AI, other target engines and the query chain.
package/src/ai/index.js DELETED
@@ -1,76 +0,0 @@
1
- //@ts-check
2
- /** The AI action document, authored without an AI client, environment or engine. */
3
- import { DocumentBuilder, optionsOf, snapshot } from '../authored.js';
4
- import { captureQuery } from '../capture-root.js';
5
- import { LinqBuildError } from '../errors.js';
6
-
7
- const FIELDS = {
8
- chunk: ['strategy', 'size'], grep: ['pattern', 'flags', 'limit'], select: ['query'],
9
- stat: [], peek: [], map: ['prompt'], reduce: ['query', 'outputSchema'], answer: ['chars'],
10
- };
11
- function make(op, from, as, options) {
12
- if (typeof from !== 'string' || !from || (op !== 'answer' && (typeof as !== 'string' || !as)))
13
- throw new LinqBuildError('JL0101', 'A step needs a source name and, except answer, a result name');
14
- return snapshot({ op, from, ...(op === 'answer' ? {} : { as }), ...optionsOf(options, FIELDS[op], `${op}()`) });
15
- }
16
- function expression(value) {
17
- // The program query receives only its input document: an undeclared external
18
- // is the shared capture's JL0104 refusal, not an invented environment lookup.
19
- return typeof value === 'function' ? captureQuery('program query', [], value, { fold: false }) : value;
20
- }
21
- /** Split a slot into a family of pieces. */
22
- export function chunk(from, as, options = {}) { return make('chunk', from, as, options); }
23
- /** Find matching slots with a bounded pattern and options. */
24
- export function grep(from, as, options) { return make('grep', from, as, options); }
25
- /** Query one JSON slot; a callback is captured as ordinary query JSON. */
26
- export function select(from, as, query) { return make('select', from, as, { query: expression(query) }); }
27
- /** Inspect counts and shape. */
28
- export function stat(from, as) { return make('stat', from, as, {}); }
29
- /** Inspect a slot's metadata and excerpt. */
30
- export function peek(from, as) { return make('peek', from, as, {}); }
31
- /** Ask one bounded prompt per member of a slot/family. */
32
- export function map(from, as, prompt) { return make('map', from, as, { prompt }); }
33
- /** Query the collected results of an earlier map. */
34
- export function reduce(from, as, query, options = {}) {
35
- return make('reduce', from, as, { query: expression(query), ...optionsOf(options, ['outputSchema'], 'reduce()') });
36
- }
37
- /** Declare the final answer slot and optional excerpt bound. */
38
- export function answer(from, options = {}) { return make('answer', from, undefined, options); }
39
-
40
- /** An immutable ordered program; binding types are phantoms. */
41
- export class ProgramBuilder extends DocumentBuilder {
42
- /** Append a public step. An answer closes this builder. @param {any} value */
43
- step(value) {
44
- if (this.schema.steps.at(-1)?.op === 'answer')
45
- throw new LinqBuildError('JL0102', 'answer is terminal; start another program to append work');
46
- if (value === null || typeof value !== 'object' || !Object.hasOwn(FIELDS, value.op))
47
- throw new LinqBuildError('JL0101', 'step() needs a known program operation');
48
- const step = optionsOf(value, ['op', 'from', ...(value.op === 'answer' ? [] : ['as']), ...FIELDS[value.op]], 'step()');
49
- return this.with({ steps: [...this.schema.steps, step] });
50
- }
51
- /** Append a chunk step. */
52
- chunk(from, as, options = {}) { return this.step(chunk(from, as, options)); }
53
- /** Append a grep step. */
54
- grep(from, as, options) { return this.step(grep(from, as, options)); }
55
- /** Append a select step. */
56
- select(from, as, query) { return this.step(select(from, as, query)); }
57
- /** Append a stat step. */
58
- stat(from, as) { return this.step(stat(from, as)); }
59
- /** Append a peek step. */
60
- peek(from, as) { return this.step(peek(from, as)); }
61
- /** Append a map step. */
62
- map(from, as, prompt) { return this.step(map(from, as, prompt)); }
63
- /** Append a reduce step. */
64
- reduce(from, as, query, options = {}) { return this.step(reduce(from, as, query, options)); }
65
- /** Append the terminal answer. */
66
- answer(from, options = {}) { return this.step(answer(from, options)); }
67
- }
68
-
69
- /** Declare input slot names for TypeScript; they never become document members. @param {readonly string[]} slots */
70
- export function program(slots = []) {
71
- if (!Array.isArray(slots) || slots.some((name) => typeof name !== 'string' || !name))
72
- throw new LinqBuildError('JL0101', 'program() takes input slot names');
73
- return new ProgramBuilder({ steps: [] });
74
- }
75
- /** A raw public program. Compilation remains authoritative for names and semantics. @param {any} document */
76
- export function from(document) { return new ProgramBuilder(document); }
package/types/ai.d.ts DELETED
@@ -1,56 +0,0 @@
1
- import type { Json } from './schema.js';
2
- import type { ExprBase, UnknownExpr } from './index.js';
3
- export type Query = Json | ((value: UnknownExpr) => ExprBase<unknown> | Json);
4
- export interface ChunkOptions { readonly strategy?: 'size' | 'line' | 'separator'; readonly size?: number }
5
- export interface GrepOptions { readonly pattern: string; readonly flags?: 'i' | 'm' | 'im' | ''; readonly limit?: number }
6
- export interface AnswerOptions { readonly chars?: number }
7
- export interface ReduceOptions { readonly outputSchema?: Json }
8
- export interface StepOptions {
9
- chunk: ChunkOptions; grep: GrepOptions; select: { readonly query: Json };
10
- stat: {}; peek: {}; map: { readonly prompt: string }; reduce: { readonly query: Json } & ReduceOptions; answer: AnswerOptions;
11
- }
12
- export type Operation = keyof StepOptions;
13
- export type Step<K extends Operation, F extends string = string, N extends string = string> = {
14
- readonly op: K; readonly from: F;
15
- } & (K extends 'answer' ? {} : { readonly as: N }) & StepOptions[K];
16
- export type StepDocument = { [K in Operation]: Step<K> }[Operation];
17
- export interface ProgramDocument { readonly steps: readonly StepDocument[] }
18
- export function chunk<const F extends string, const N extends string>(from: F, as: N, options?: ChunkOptions): Step<'chunk', F, N>;
19
- export function grep<const F extends string, const N extends string>(from: F, as: N, options: GrepOptions): Step<'grep', F, N>;
20
- export function select<const F extends string, const N extends string>(from: F, as: N, query: Query): Step<'select', F, N>;
21
- export function stat<const F extends string, const N extends string>(from: F, as: N): Step<'stat', F, N>;
22
- export function peek<const F extends string, const N extends string>(from: F, as: N): Step<'peek', F, N>;
23
- export function map<const F extends string, const N extends string>(from: F, as: N, prompt: string): Step<'map', F, N>;
24
- export function reduce<const F extends string, const N extends string>(from: F, as: N, query: Query, options?: ReduceOptions): Step<'reduce', F, N>;
25
- export function answer<const F extends string>(from: F, options?: AnswerOptions): Step<'answer', F>;
26
-
27
- type Kind = Exclude<Operation, 'answer'> | 'slot';
28
- type Bindings = Record<string, Kind>;
29
- type Names<B, K extends Kind = Kind> = { [N in keyof B]: B[N] extends K ? N : never }[keyof B] & string;
30
- type Single<B> = Names<B, Exclude<Kind, 'chunk' | 'map'>>;
31
- type Fresh<B, N extends string> = N extends keyof B ? B[N] extends 'slot' ? N : never : N;
32
- type Add<B, N extends string, K extends Kind> = Omit<B, N> & Record<N, K>;
33
- type InputFor<B, K extends Operation> = K extends 'reduce' ? Names<B, 'map'> : K extends 'select' | 'answer' ? Single<B> : Names<B>;
34
- type StepKeys<K extends Operation> = 'op' | 'from' | (K extends 'answer' ? never : 'as') | keyof StepOptions[K];
35
- type CheckStep<B, T extends StepDocument> = Exclude<keyof T, StepKeys<T['op']>> extends never ? T['from'] extends InputFor<B, T['op']>
36
- ? T extends { readonly as: infer N extends string } ? N extends Fresh<B, N> ? unknown : never : unknown : never : never;
37
- type AfterStep<B, T extends StepDocument> = T extends { readonly as: infer N extends string; readonly op: infer K extends Kind } ? Add<B, N, K> : B;
38
- export class ProgramBuilder<B extends Bindings = {}, Done extends boolean = false> {
39
- protected constructor();
40
- readonly __bindings: B;
41
- readonly __done: Done;
42
- readonly schema: ProgramDocument;
43
- toJSON(): ProgramDocument;
44
- step<const T extends StepDocument>(this: ProgramBuilder<B, false>, step: T & CheckStep<B, T>): ProgramBuilder<AfterStep<B, T>, T['op'] extends 'answer' ? true : false>;
45
- chunk<N extends string>(this: ProgramBuilder<B, false>, from: Names<B>, as: Fresh<B, N>, options?: ChunkOptions): ProgramBuilder<Add<B, N, 'chunk'>>;
46
- grep<N extends string>(this: ProgramBuilder<B, false>, from: Names<B>, as: Fresh<B, N>, options: GrepOptions): ProgramBuilder<Add<B, N, 'grep'>>;
47
- select<N extends string>(this: ProgramBuilder<B, false>, from: Single<B>, as: Fresh<B, N>, query: Query): ProgramBuilder<Add<B, N, 'select'>>;
48
- stat<N extends string>(this: ProgramBuilder<B, false>, from: Names<B>, as: Fresh<B, N>): ProgramBuilder<Add<B, N, 'stat'>>;
49
- peek<N extends string>(this: ProgramBuilder<B, false>, from: Names<B>, as: Fresh<B, N>): ProgramBuilder<Add<B, N, 'peek'>>;
50
- map<N extends string>(this: ProgramBuilder<B, false>, from: Names<B>, as: Fresh<B, N>, prompt: string): ProgramBuilder<Add<B, N, 'map'>>;
51
- reduce<N extends string>(this: ProgramBuilder<B, false>, from: Names<B, 'map'>, as: Fresh<B, N>, query: Query, options?: ReduceOptions): ProgramBuilder<Add<B, N, 'reduce'>>;
52
- answer(this: ProgramBuilder<B, false>, from: Single<B>, options?: AnswerOptions): ProgramBuilder<B, true>;
53
- }
54
- export function program<const S extends readonly string[] = []>(slots?: S): ProgramBuilder<Record<S[number], 'slot'>>;
55
- /** Raw documents make no binding-order or terminal-state inference. */
56
- export function from(document: ProgramDocument): ProgramBuilder<Record<string, Kind>, boolean>;