@bjornpagen/bumbledb 1.1.0 → 1.2.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/COOKBOOK.md +114 -11
- package/README.md +52 -9
- package/dist/capacity.d.ts +15 -55
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +63 -12
- package/dist/capacity.js.map +1 -1
- package/dist/changes.d.ts +26 -3
- package/dist/changes.d.ts.map +1 -1
- package/dist/changes.js +89 -44
- package/dist/changes.js.map +1 -1
- package/dist/closed.d.ts +23 -51
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +110 -168
- package/dist/closed.js.map +1 -1
- package/dist/codec.d.ts +4 -9
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +108 -183
- package/dist/codec.js.map +1 -1
- package/dist/compile.d.ts +16 -16
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +36 -15
- package/dist/compile.js.map +1 -1
- package/dist/db-native.d.ts +39 -0
- package/dist/db-native.d.ts.map +1 -1
- package/dist/db-native.js +8 -0
- package/dist/db-native.js.map +1 -1
- package/dist/db.d.ts +28 -8
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +91 -38
- package/dist/db.js.map +1 -1
- package/dist/errors.d.ts +11 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +13 -1
- package/dist/errors.js.map +1 -1
- package/dist/face.d.ts +19 -25
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +30 -24
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +13 -26
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +89 -116
- package/dist/fields.js.map +1 -1
- package/dist/immutable.d.ts +10 -0
- package/dist/immutable.d.ts.map +1 -0
- package/dist/immutable.js +75 -0
- package/dist/immutable.js.map +1 -0
- package/dist/index.d.ts +14 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/internal/log.d.ts +2 -0
- package/dist/internal/log.d.ts.map +1 -1
- package/dist/internal/log.js +2 -0
- package/dist/internal/log.js.map +1 -1
- package/dist/law.d.ts +10 -10
- package/dist/law.d.ts.map +1 -1
- package/dist/law.js +1 -1
- package/dist/law.js.map +1 -1
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +11 -6
- package/dist/lower.js.map +1 -1
- package/dist/native.d.ts +1 -1
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +1 -1
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js.map +1 -1
- package/dist/query/description.d.ts +33 -0
- package/dist/query/description.d.ts.map +1 -0
- package/dist/query/description.js +302 -0
- package/dist/query/description.js.map +1 -0
- package/dist/query/lower.d.ts +60 -4
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +126 -161
- package/dist/query/lower.js.map +1 -1
- package/dist/query/parse-ir.d.ts +7 -2
- package/dist/query/parse-ir.d.ts.map +1 -1
- package/dist/query/parse-ir.js +240 -53
- package/dist/query/parse-ir.js.map +1 -1
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +8 -10
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +3 -4
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +5 -10
- package/dist/query/scope.js.map +1 -1
- package/dist/relation.d.ts +22 -48
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +30 -82
- package/dist/relation.js.map +1 -1
- package/dist/rows.d.ts +7 -4
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +44 -198
- package/dist/rows.js.map +1 -1
- package/dist/runtime-errors.d.ts +26 -2
- package/dist/runtime-errors.d.ts.map +1 -1
- package/dist/runtime-errors.js +43 -3
- package/dist/runtime-errors.js.map +1 -1
- package/dist/schema.d.ts +9 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +85 -24
- package/dist/schema.js.map +1 -1
- package/dist/selection.d.ts +27 -0
- package/dist/selection.d.ts.map +1 -0
- package/dist/selection.js +104 -0
- package/dist/selection.js.map +1 -0
- package/dist/shape.d.ts +6 -9
- package/dist/shape.d.ts.map +1 -1
- package/dist/statements.d.ts +17 -52
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +92 -111
- package/dist/statements.js.map +1 -1
- package/dist/values.d.ts +25 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +203 -0
- package/dist/values.js.map +1 -0
- package/pack-provenance.json +3 -3
- package/package.json +4 -4
- package/src/capacity.ts +86 -76
- package/src/changes.ts +183 -54
- package/src/closed.ts +161 -314
- package/src/codec.ts +116 -190
- package/src/compile.ts +56 -32
- package/src/db-native.ts +42 -0
- package/src/db.ts +134 -52
- package/src/errors.ts +16 -1
- package/src/face.ts +44 -74
- package/src/fields.ts +100 -146
- package/src/immutable.ts +76 -0
- package/src/index.ts +34 -28
- package/src/internal/log.ts +2 -0
- package/src/law.ts +13 -13
- package/src/lower.ts +13 -10
- package/src/native.ts +2 -0
- package/src/query/atom.ts +1 -0
- package/src/query/description.ts +394 -0
- package/src/query/lower.ts +139 -173
- package/src/query/parse-ir.ts +247 -54
- package/src/query/run.ts +15 -9
- package/src/query/scope.ts +10 -18
- package/src/relation.ts +58 -142
- package/src/rows.ts +62 -205
- package/src/runtime-errors.ts +47 -3
- package/src/schema.ts +99 -29
- package/src/selection.ts +124 -0
- package/src/shape.ts +9 -9
- package/src/statements.ts +138 -189
- package/src/values.ts +223 -0
package/COOKBOOK.md
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
closed,
|
|
19
19
|
contained,
|
|
20
20
|
Db,
|
|
21
|
+
describeQuery,
|
|
21
22
|
duration,
|
|
22
23
|
f64,
|
|
23
24
|
i64,
|
|
@@ -29,11 +30,11 @@ import {
|
|
|
29
30
|
NativeRuntime,
|
|
30
31
|
on,
|
|
31
32
|
query,
|
|
33
|
+
queryFromDescription,
|
|
32
34
|
ref,
|
|
33
35
|
relation,
|
|
34
36
|
Scalar,
|
|
35
37
|
schema,
|
|
36
|
-
span,
|
|
37
38
|
str,
|
|
38
39
|
u64,
|
|
39
40
|
v,
|
|
@@ -44,6 +45,8 @@ import type {
|
|
|
44
45
|
ApplyOutcome,
|
|
45
46
|
CompleteResult,
|
|
46
47
|
Fact,
|
|
48
|
+
FloatIntervalValue,
|
|
49
|
+
IntervalValue,
|
|
47
50
|
QueryReader
|
|
48
51
|
} from "@bjornpagen/bumbledb"
|
|
49
52
|
|
|
@@ -163,18 +166,83 @@ const applyOnce = Effect.scoped(
|
|
|
163
166
|
void applyOnce
|
|
164
167
|
```
|
|
165
168
|
|
|
169
|
+
For a noncommitting check, `db.judge` runs the same admission procedure and
|
|
170
|
+
aborts its private candidate on the native worker. It briefly takes the
|
|
171
|
+
writer; it does not hold a writer session open in JavaScript. Admitted and
|
|
172
|
+
rejected judgments include the actual base and net proposed fact counts.
|
|
173
|
+
Operational errors stay in the Effect error channel.
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const judgeOnce = Effect.scoped(
|
|
177
|
+
Effect.gen(function* () {
|
|
178
|
+
const db = yield* Db.open(localPath, Tasks)
|
|
179
|
+
const draft = yield* ChangeSet.builder(Tasks)
|
|
180
|
+
const id = yield* Effect.sync(() => crypto.randomUUID())
|
|
181
|
+
yield* draft.insert(Task, [{ id, title: "inspect a candidate", done: 0n }])
|
|
182
|
+
return yield* db.judge(yield* draft.finish(), { expected: { kind: "any" } })
|
|
183
|
+
})
|
|
184
|
+
)
|
|
185
|
+
void judgeOnce
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Judgment is optional: `apply` always judges for itself. To act on a judgment,
|
|
189
|
+
use its base as an exact expected witness and handle `moved`; do not assume
|
|
190
|
+
another writer could not change the database between these operations.
|
|
191
|
+
|
|
192
|
+
Change sets also work as inspectable values without a database. Their
|
|
193
|
+
`counts` report distinct requested additions/removals, not the net change
|
|
194
|
+
against any store. `records()` yields `{ relation, kind, fact }` records;
|
|
195
|
+
the relation name narrows the fact type. Every traversal opens an independent
|
|
196
|
+
cursor over the shared native bytes. Early termination, failure and interruption
|
|
197
|
+
close it, without consuming the change set. Delivery is bounded to 256 records
|
|
198
|
+
and a 64 KiB canonical-byte target per batch; a larger individual row is allowed.
|
|
199
|
+
|
|
200
|
+
`toBytes()` explicitly copies the complete canonical payload. `fromBytes`
|
|
201
|
+
checks its schema fingerprint, framing, scalar values, order and uniqueness;
|
|
202
|
+
it refuses malformed bytes instead of silently normalizing them. Input bytes
|
|
203
|
+
must remain stable until the Effect exits, and returned bytes are independently
|
|
204
|
+
owned. Native byte order is canonical encoding order, not insertion order.
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
const inspectAndCompose = Effect.scoped(
|
|
208
|
+
Effect.gen(function* () {
|
|
209
|
+
const draft = yield* ChangeSet.builder(Tasks)
|
|
210
|
+
const id = yield* Effect.sync(() => crypto.randomUUID())
|
|
211
|
+
yield* draft.insert(Task, [{ id, title: "inspect typed changes", done: 0n }])
|
|
212
|
+
const changes = yield* draft.finish()
|
|
213
|
+
const bytes = yield* changes.toBytes()
|
|
214
|
+
const decoded = yield* ChangeSet.fromBytes(Tasks, bytes)
|
|
215
|
+
const combined = yield* changes.compose(decoded)
|
|
216
|
+
const preview = yield* Stream.runCollect(combined.records().pipe(Stream.take(10)))
|
|
217
|
+
return { counts: combined.counts, byteLength: combined.byteLength,
|
|
218
|
+
titles: preview.map((record) => record.fact.title) }
|
|
219
|
+
})
|
|
220
|
+
)
|
|
221
|
+
void inspectAndCompose
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`compose` performs a native linear merge without decoding/re-encoding rows.
|
|
225
|
+
It is commutative, associative and idempotent: the identical fact's add wins
|
|
226
|
+
over its removal within the combined command. Two distinct rows sharing a key
|
|
227
|
+
both survive composition and can still be rejected by admission. Applying two
|
|
228
|
+
commands sequentially has different semantics: a later removal removes a
|
|
229
|
+
previously added fact. Neither input is consumed by composition.
|
|
230
|
+
|
|
166
231
|
## 4. Keyed reads are Options
|
|
167
232
|
|
|
168
|
-
`get`
|
|
233
|
+
`get` takes the exact key descriptor used in the schema and its complete
|
|
234
|
+
projected value. Every declared key is usable; there is no implicit primary key.
|
|
235
|
+
A missing key is
|
|
169
236
|
`Option.none` — never a fake I/O error, never a nullable row.
|
|
170
237
|
|
|
171
238
|
```ts
|
|
172
239
|
const Person = relation("Person", { id: uuid, name: str })
|
|
173
|
-
const
|
|
240
|
+
const PersonById = key(Person, ["id"])
|
|
241
|
+
const People = schema("People", { Person }, [PersonById])
|
|
174
242
|
|
|
175
243
|
const lookup = (reader: QueryReader<typeof People>, personId: Uuid) =>
|
|
176
244
|
Effect.gen(function* () {
|
|
177
|
-
const found = yield* reader.get(
|
|
245
|
+
const found = yield* reader.get(PersonById, { id: personId })
|
|
178
246
|
return Option.isSome(found) ? found.value.name : "unknown"
|
|
179
247
|
})
|
|
180
248
|
void lookup
|
|
@@ -245,6 +313,39 @@ const readTwoAuthors = (reader: QueryReader<typeof Library>) =>
|
|
|
245
313
|
void readTwoAuthors
|
|
246
314
|
```
|
|
247
315
|
|
|
316
|
+
Generated queries use the same checked rule, scalar, and execution machinery.
|
|
317
|
+
`describeQuery` exposes the logical IR and its names as owned data. Its relation
|
|
318
|
+
ordinals refer to the supplied schema's declaration order; variables are local
|
|
319
|
+
to each rule. Intermediate names are local labels. The result-field record
|
|
320
|
+
passed to `queryFromDescription` must match the actual derived head, including
|
|
321
|
+
closed vocabularies, and determines the returned row type. Parameters supplied
|
|
322
|
+
to a generated query are checked against their uses during execution.
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
const Event = relation("Event", { id: uuid, amount: u64 })
|
|
326
|
+
const Events = schema("Events", { Event }, [key(Event, ["id"])])
|
|
327
|
+
const countEvents = query(Events).rule((r) =>
|
|
328
|
+
r.match(Event, {}).find({ count: r.count() })
|
|
329
|
+
)
|
|
330
|
+
const description = describeQuery(countEvents)
|
|
331
|
+
const totalEvents = queryFromDescription(
|
|
332
|
+
Events,
|
|
333
|
+
{ ...description, columns: ["total"] },
|
|
334
|
+
{ total: u64 }
|
|
335
|
+
)
|
|
336
|
+
const readTotal = (reader: QueryReader<typeof Events>) =>
|
|
337
|
+
Effect.scoped(Effect.gen(function* () {
|
|
338
|
+
const result = yield* reader.execute(totalEvents, {})
|
|
339
|
+
const rows: readonly { readonly total: bigint }[] = yield* result.collect()
|
|
340
|
+
return rows
|
|
341
|
+
}))
|
|
342
|
+
void readTotal
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Descriptions contain bigint and byte values, so they are not a JSON wire format.
|
|
346
|
+
An accepted description is an authored query; native preparation still checks
|
|
347
|
+
engine semantics. It carries no snapshot, prepared handle, or result rows.
|
|
348
|
+
|
|
248
349
|
## 6. Grouped exact aggregates
|
|
249
350
|
|
|
250
351
|
Aggregates fold the group's distinct full bindings: keep the identity-bearing
|
|
@@ -358,7 +459,8 @@ the apply instead of silently overwriting.
|
|
|
358
459
|
|
|
359
460
|
```ts
|
|
360
461
|
const Account = relation("Account", { id: uuid, balance: i64 })
|
|
361
|
-
const
|
|
462
|
+
const AccountById = key(Account, ["id"])
|
|
463
|
+
const Bank = schema("Bank", { Account }, [AccountById])
|
|
362
464
|
|
|
363
465
|
const correct = (accountId: Uuid) =>
|
|
364
466
|
Effect.scoped(
|
|
@@ -367,7 +469,7 @@ const correct = (accountId: Uuid) =>
|
|
|
367
469
|
const observed = yield* Effect.scoped(
|
|
368
470
|
Effect.gen(function* () {
|
|
369
471
|
const snapshot = yield* db.snapshot()
|
|
370
|
-
const previous = yield* snapshot.get(
|
|
472
|
+
const previous = yield* snapshot.get(AccountById, { id: accountId })
|
|
371
473
|
if (Option.isNone(previous)) {
|
|
372
474
|
return yield* Effect.fail({ missing: accountId })
|
|
373
475
|
}
|
|
@@ -389,16 +491,17 @@ void correct
|
|
|
389
491
|
`f64` is a real schema scalar: NaN canonicalizes to the one quiet NaN,
|
|
390
492
|
`-0` to `+0`, and the relational order is total. `interval(f64)` is the
|
|
391
493
|
parameterized dense interval — half-open, NaN-free, strictly ordered.
|
|
392
|
-
|
|
494
|
+
Interval values are structural records. Their field descriptor validates
|
|
495
|
+
endpoint ranges, nonemptiness and fixed width at the boundary. Integer rays
|
|
496
|
+
end at the element's maximum; fixed-width intervals cannot be rays.
|
|
393
497
|
|
|
394
498
|
```ts
|
|
395
499
|
const Window = relation("Window", { id: uuid, confidence: interval(f64), during: interval(i64) })
|
|
396
500
|
const Windows = schema("Windows", { Window }, [key(Window, ["id"])])
|
|
397
501
|
|
|
398
|
-
const discrete =
|
|
399
|
-
const dense =
|
|
400
|
-
|
|
401
|
-
void [Windows, bothChecked]
|
|
502
|
+
const discrete: IntervalValue = { start: 0n, end: 60n }
|
|
503
|
+
const dense: FloatIntervalValue = { start: 0.25, end: 1.5 }
|
|
504
|
+
void [Windows, discrete, dense]
|
|
402
505
|
```
|
|
403
506
|
|
|
404
507
|
## 12. Scoped ownership and honest close
|
package/README.md
CHANGED
|
@@ -19,6 +19,11 @@ ordinary `bigint`, `number` (for `f64`), `string`, boolean, byte, `Uuid`,
|
|
|
19
19
|
and interval values; queries infer their parameter and result types from how
|
|
20
20
|
those values are used.
|
|
21
21
|
|
|
22
|
+
Relations, closed rosters, keys, selections, and constraints are checked
|
|
23
|
+
structural descriptions. Schema construction owns copies of declarations.
|
|
24
|
+
Independently constructed equivalent declarations work in queries, codecs,
|
|
25
|
+
writes, and key lookups; ordered fields and enum handles must agree.
|
|
26
|
+
|
|
22
27
|
## Platform support
|
|
23
28
|
|
|
24
29
|
The TypeScript package ships native binaries for **darwin-arm64**
|
|
@@ -33,12 +38,12 @@ correctness CI is distinct from the Apple Silicon performance measurements.
|
|
|
33
38
|
|
|
34
39
|
## Install
|
|
35
40
|
|
|
36
|
-
This guide follows the 1.
|
|
41
|
+
This guide follows the 1.2.0 source API. Use the guide from the Git tag matching
|
|
37
42
|
your installed package. GitHub release tarballs and npm publication are separate;
|
|
38
43
|
the npm command below applies once that version is published.
|
|
39
44
|
|
|
40
45
|
```sh
|
|
41
|
-
pnpm add @bjornpagen/bumbledb@1.
|
|
46
|
+
pnpm add @bjornpagen/bumbledb@1.2.0 effect@4.0.0-rc.112
|
|
42
47
|
```
|
|
43
48
|
|
|
44
49
|
## Quick start
|
|
@@ -85,8 +90,9 @@ const Attempt = relation("Attempt", {
|
|
|
85
90
|
})
|
|
86
91
|
|
|
87
92
|
// Keys are declared statements; references and capacity are laws.
|
|
93
|
+
const StudentById = key(Student, ["id"])
|
|
88
94
|
const Learning = schema("Learning", { Student, Attempt }, [
|
|
89
|
-
|
|
95
|
+
StudentById,
|
|
90
96
|
key(Attempt, ["id"]),
|
|
91
97
|
contained(on(Attempt, "student"), on(Student, "id")),
|
|
92
98
|
capacity(on(Student, "id"), {
|
|
@@ -127,7 +133,7 @@ const program = Effect.scoped(
|
|
|
127
133
|
return outcome
|
|
128
134
|
}
|
|
129
135
|
const snapshot = yield* db.snapshot()
|
|
130
|
-
const found = yield* snapshot.get(
|
|
136
|
+
const found = yield* snapshot.get(StudentById, { id: studentId })
|
|
131
137
|
if (Option.isNone(found)) {
|
|
132
138
|
return outcome
|
|
133
139
|
}
|
|
@@ -151,8 +157,8 @@ The SDK translates TypeScript values directly into the engine's shared schema
|
|
|
151
157
|
and query representations.
|
|
152
158
|
|
|
153
159
|
- Fields use `bool`, `bytes`, `f64`, `i64`, `uuid`, `u64`, `str`, and
|
|
154
|
-
`interval` (`interval(f64)` is the dense float interval)
|
|
155
|
-
checked
|
|
160
|
+
`interval` (`interval(f64)` is the dense float interval). Interval values
|
|
161
|
+
are plain `{ start, end }` records checked against their field. `relation()` declares stored records, while
|
|
156
162
|
`closed()` declares a fixed enum-like set whose values may carry typed
|
|
157
163
|
columns. `Infer` exposes the resulting TypeScript value type. `Uuid` is
|
|
158
164
|
a structural template-literal string, not a nominal brand or a cast helper.
|
|
@@ -162,7 +168,9 @@ and query representations.
|
|
|
162
168
|
- `schema()` accepts `key`, `contained`, `mirrors`, and `capacity`
|
|
163
169
|
statements. Keys are declared statements — there is no minted identity.
|
|
164
170
|
`capacity(target, { from, weight?, within })` takes named options;
|
|
165
|
-
|
|
171
|
+
`select(relation, { field: value })` makes a reference conditional,
|
|
172
|
+
`closedId(roster)` supplies a field that accepts named enum handles,
|
|
173
|
+
`within` sets a count or
|
|
166
174
|
measurement range, and `weigh` chooses a numeric field or interval
|
|
167
175
|
duration. Harmless equivalent window spellings lower to one canonical
|
|
168
176
|
law; genuinely different meanings still refuse.
|
|
@@ -172,10 +180,24 @@ and query representations.
|
|
|
172
180
|
existing authority. `db.apply(changes, { expected })` judges one
|
|
173
181
|
immutable final-state change: `accepted`, `no-change`,
|
|
174
182
|
`invariant-rejected` (complete statement diagnostics), or `moved`.
|
|
183
|
+
`db.judge(changes, { expected })` uses the same admission path but aborts
|
|
184
|
+
the private candidate. It returns `admitted` or `invariant-rejected` with
|
|
185
|
+
the actual base witness and net additions/removals, or `moved` without
|
|
186
|
+
judging. Both use `WriteOptions`; judgment never guarantees a later apply.
|
|
175
187
|
- `ChangeSet.builder(schema)` acquires a scoped database-free draft;
|
|
176
188
|
`insert`/`delete` are lazy bounded ingestion effects, `finish()` seals the
|
|
177
|
-
immutable `ChangeSet`.
|
|
178
|
-
`
|
|
189
|
+
immutable `ChangeSet`. It exposes `schemaId`, `counts`, and `byteLength`.
|
|
190
|
+
`records()` is a reusable, bounded stream of relation-name-discriminated
|
|
191
|
+
facts; each traversal owns an independent scoped cursor. `toBytes()`
|
|
192
|
+
explicitly materializes canonical bytes; `ChangeSet.fromBytes(schema, bytes)`
|
|
193
|
+
checks them without normalizing malformed input. `left.compose(right)`
|
|
194
|
+
merges native records into one add-wins command without decoding rows.
|
|
195
|
+
Composition is commutative, associative, and idempotent, not sequential
|
|
196
|
+
replay. Its counts describe requested distinct actions; only `judge`
|
|
197
|
+
measures their effect against a store.
|
|
198
|
+
- Snapshots satisfy the shared `QueryReader`: typed
|
|
199
|
+
`get(keyDescriptor, keyValues)` chooses an explicit declared key and returns
|
|
200
|
+
`Option`; `execute` returns a sealed `CompleteResult` whose
|
|
179
201
|
`collect()` explicitly materializes all rows and whose
|
|
180
202
|
`pages()` is a one-shot consuming `Stream` of owned page
|
|
181
203
|
arrays after complete evaluation. Each page contains up to 256 rows; this
|
|
@@ -188,6 +210,21 @@ and query representations.
|
|
|
188
210
|
`f64` are deterministic with one final rounding), named intermediate
|
|
189
211
|
results, nonrecursive composition of query templates, and linear
|
|
190
212
|
recursive reachability.
|
|
213
|
+
- `describeQuery(q)` returns owned logical IR, result names, intermediate
|
|
214
|
+
table names, and parameter names. `queryFromDescription(S, description,
|
|
215
|
+
resultFields)` checks a generated description through the same rule builder,
|
|
216
|
+
scalar grammar, lowering, and execution paths. The result-field record is
|
|
217
|
+
checked against the derived head and infers the returned row type; it is
|
|
218
|
+
not an unchecked cast. Generated parameters are validated by their uses at
|
|
219
|
+
execution. Ordinals refer to the supplied schema's ordered declarations;
|
|
220
|
+
variable ordinals are local to each rule. Native preparation still checks
|
|
221
|
+
engine semantics. The description contains plain values, including bigint
|
|
222
|
+
and byte arrays, rather than native resources or a JSON encoding.
|
|
223
|
+
Query `data` and `schema`, and compiled-schema inspection properties,
|
|
224
|
+
return detached snapshots: editing their byte buffers cannot change the
|
|
225
|
+
query or compilation. Checked immutable branches may be shared. Structural
|
|
226
|
+
declarations with byte payloads are copied when consumed; JavaScript byte
|
|
227
|
+
buffers themselves are mutable and are never treated as immutable cache keys.
|
|
191
228
|
- `Scalar.field("units")` is an unresolved source-field leaf.
|
|
192
229
|
`Scalar.add(Scalar.field("units"), Scalar.u64(1n))` authors synchronously
|
|
193
230
|
without native loading. Native schema binding typechecks it, including
|
|
@@ -196,6 +233,12 @@ and query representations.
|
|
|
196
233
|
Effect error channel; interruption and finalizer problems stay in
|
|
197
234
|
`Cause`. Resource owners are scoped and report honest `CloseReport`s;
|
|
198
235
|
incomplete teardown surfaces as a structured `CloseFailure` defect.
|
|
236
|
+
`error.message` contains the operation and reason code for safe default
|
|
237
|
+
display. Inspect `error.reason` explicitly for engine details, or
|
|
238
|
+
`InvalidArgument.detail` for authoring text and available structured
|
|
239
|
+
diagnostics such as `MissingField`, `UnknownField`, and `InvalidValue`.
|
|
240
|
+
Those details can contain application names or values and should not be
|
|
241
|
+
copied into public logs indiscriminately.
|
|
199
242
|
|
|
200
243
|
## Cookbook
|
|
201
244
|
|
package/dist/capacity.d.ts
CHANGED
|
@@ -1,50 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* the
|
|
4
|
-
* § the canonical-utterance law, restated
|
|
5
|
-
* around the aggregate form). `within` is the ONE window spelling —
|
|
6
|
-
* `within(n)` exact (`within(0n)` IS the exclusion's one spelling),
|
|
7
|
-
* `within(lo, hi)` range (`within(0n, hi)` the canonical ceiling),
|
|
8
|
-
* `within(lo, "*")` floor — `weigh` names the measure on the SOURCE row
|
|
9
|
-
* (`weigh("watts")` a u64 field, `weigh(duration("booked"))` an interval's
|
|
10
|
-
* measure), and `ref`/`duration` read a dependent bound from the
|
|
11
|
-
* TARGET row (hi slot only — ruled 2026-07-24, C6). The ban table is
|
|
12
|
-
* enforced REPRESENTATIONALLY in two tiers, split per-aggregate where
|
|
13
|
-
* weight-sensitive (design § 6: a ban is canonical-utterance policing when
|
|
14
|
-
* it is weight-independent, semantic deduplication when it is not):
|
|
15
|
-
*
|
|
16
|
-
* - **The type tier**: a banned spelling written as a LITERAL does not
|
|
17
|
-
* compile — every negative bound, `within(n, n)`, `within(0n, 0n)`, and
|
|
18
|
-
* `within(0n, "*")` are type errors naming the canonical form. The
|
|
19
|
-
* weight-SENSITIVE row rides the `capacity` overloads themselves:
|
|
20
|
-
* `within(1n, "*")` is banned on the unit overload only (`{1..*}` on the
|
|
21
|
-
* count instance is the bare containment respelled —
|
|
22
|
-
* `window_floor_containment`), and LEGAL on the weighted one ("positive
|
|
23
|
-
* total" is not an existence claim over rows).
|
|
24
|
-
* - **The construction tier**: a bound the type level cannot judge — a
|
|
25
|
-
* COMPUTED `bigint`, or an inverted `within(lo, hi)` order — is judged at
|
|
26
|
-
* construction with the same canonical-naming errors; and past both
|
|
27
|
-
* tiers the engine's own spec validation remains the law for a hostile
|
|
28
|
-
* FFI caller (the standing two-tier ban enforcement).
|
|
29
|
-
*
|
|
30
|
-
* The weight vocabulary is closed at the row (ruled 2026-07-24, ruling 6):
|
|
31
|
-
* a path weight (`weigh("model.watts")`) is a typed refusal at BOTH tiers
|
|
32
|
-
* whose diagnostic names the pinned-column idiom — the two-column
|
|
33
|
-
* containment IS the join, stated as a law. Bounds are `bigint` (u64
|
|
34
|
-
* crosses as bigint always, PRD-04's law); the witnessed measure comes
|
|
35
|
-
* back as `bigint` too (u128-wide engine accumulator, C3).
|
|
36
|
-
*/
|
|
1
|
+
/** Structural capacity measures and windows. Constructors and generated
|
|
2
|
+
* descriptions share the same checked representation. Bounds are u64;
|
|
3
|
+
* dependent bounds read the target row, measures read the source row. */
|
|
37
4
|
import type { AnyFace, FaceFields, FaceSource, ProjectedShape } from "./face.js";
|
|
38
5
|
import type { CapacityWindowSpec, WeightSpec } from "./spec.js";
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
readonly window: S;
|
|
42
|
-
readonly [admitted]: true;
|
|
43
|
-
}
|
|
44
|
-
interface CapacityWeight<S extends WeightSpec = WeightSpec> {
|
|
45
|
-
readonly weight: S;
|
|
46
|
-
readonly [admitted]: true;
|
|
47
|
-
}
|
|
6
|
+
type CapacityWindow<S extends CapacityWindowSpec = CapacityWindowSpec> = S;
|
|
7
|
+
type CapacityWeight<S extends WeightSpec = WeightSpec> = S;
|
|
48
8
|
interface FieldRef<F extends string = string> {
|
|
49
9
|
readonly kind: "field";
|
|
50
10
|
readonly field: F;
|
|
@@ -53,8 +13,6 @@ interface DurationRef<F extends string = string> {
|
|
|
53
13
|
readonly kind: "durationField";
|
|
54
14
|
readonly field: F;
|
|
55
15
|
}
|
|
56
|
-
declare function isCapacityWindow(value: unknown): value is CapacityWindow;
|
|
57
|
-
declare function isCapacityWeight(value: unknown): value is CapacityWeight;
|
|
58
16
|
interface BannedWindow<Canonical extends string> {
|
|
59
17
|
readonly "banned window spelling — the canonical-utterance law names the one legal form": Canonical;
|
|
60
18
|
}
|
|
@@ -92,7 +50,7 @@ type RangeBan<Lo extends bigint, Hi extends bigint> = bigint extends Lo ? unknow
|
|
|
92
50
|
* only: Duration weights pair with Duration-capable bounds, so the
|
|
93
51
|
* weighted overload takes the same window freely.
|
|
94
52
|
*/
|
|
95
|
-
type UnitDimensionBan<W extends CapacityWindow> = W
|
|
53
|
+
type UnitDimensionBan<W extends CapacityWindow> = W extends {
|
|
96
54
|
readonly hi: {
|
|
97
55
|
readonly kind: "durationField";
|
|
98
56
|
};
|
|
@@ -110,10 +68,10 @@ interface BoundKindMismatch<K, Want> {
|
|
|
110
68
|
Want
|
|
111
69
|
];
|
|
112
70
|
}
|
|
113
|
-
type BoundOnTarget<K extends string, Want extends "u64" | "interval", B extends AnyFace> = string extends K ? unknown : K extends FaceFields<B["
|
|
114
|
-
type BoundsOnTarget<W extends CapacityWindow, B extends AnyFace> = W
|
|
71
|
+
type BoundOnTarget<K extends string, Want extends "u64" | "interval", B extends AnyFace> = string extends K ? unknown : K extends FaceFields<B["owner"]> ? KindAt<B["owner"], K> extends Want ? unknown : BoundKindMismatch<K, Want> : BoundOffTargetRoster<K, FaceFields<B["owner"]>>;
|
|
72
|
+
type BoundsOnTarget<W extends CapacityWindow, B extends AnyFace> = W extends {
|
|
115
73
|
readonly hi: FieldRef<infer K>;
|
|
116
|
-
} ? BoundOnTarget<K, "u64", B> : W
|
|
74
|
+
} ? BoundOnTarget<K, "u64", B> : W extends {
|
|
117
75
|
readonly hi: DurationRef<infer K>;
|
|
118
76
|
} ? BoundOnTarget<K, "interval", B> : unknown;
|
|
119
77
|
interface WeightOffSourceRoster<K, Roster> {
|
|
@@ -135,13 +93,13 @@ interface WeightKindMismatch<K, Want> {
|
|
|
135
93
|
* position. Checked at the `capacity` call where the source face is
|
|
136
94
|
* inferred — the proven constrain-after-inference pattern.
|
|
137
95
|
*/
|
|
138
|
-
type WeightOnSource<M extends CapacityWeight, A extends AnyFace> = M
|
|
96
|
+
type WeightOnSource<M extends CapacityWeight, A extends AnyFace> = M extends {
|
|
139
97
|
readonly kind: "field";
|
|
140
98
|
readonly field: infer K extends string;
|
|
141
|
-
} ? string extends K ? unknown : K extends FaceFields<A["
|
|
99
|
+
} ? string extends K ? unknown : K extends FaceFields<A["owner"]> ? KindAt<A["owner"], K> extends "u64" ? unknown : WeightKindMismatch<K, "u64"> : WeightOffSourceRoster<K, FaceFields<A["owner"]>> : M extends {
|
|
142
100
|
readonly kind: "durationField";
|
|
143
101
|
readonly field: infer K extends string;
|
|
144
|
-
} ? string extends K ? unknown : K extends FaceFields<A["
|
|
102
|
+
} ? string extends K ? unknown : K extends FaceFields<A["owner"]> ? KindAt<A["owner"], K> extends "interval" ? unknown : WeightKindMismatch<K, "interval"> : WeightOffSourceRoster<K, FaceFields<A["owner"]>> : unknown;
|
|
145
103
|
declare const unitWeight: WeightSpec;
|
|
146
104
|
declare function within<const N extends bigint>(n: N & NegativeBan<N>): CapacityWindow<{
|
|
147
105
|
readonly kind: "exact";
|
|
@@ -211,5 +169,7 @@ declare function ref<const F extends string>(field: F & PathBan<F>): FieldRef<F>
|
|
|
211
169
|
*/
|
|
212
170
|
declare function duration<const F extends string>(field: F & PathBan<F>): DurationRef<F>;
|
|
213
171
|
export type { BoundsOnTarget, CapacityWeight, CapacityWindow, DurationRef, FieldRef, UnitDimensionBan, WeightOnSource };
|
|
214
|
-
|
|
172
|
+
declare function capacityWindow(input: unknown): CapacityWindow;
|
|
173
|
+
declare function capacityWeight(input: unknown): CapacityWeight;
|
|
174
|
+
export { capacityWeight, capacityWindow, duration, ref, unitWeight, weigh, within };
|
|
215
175
|
//# sourceMappingURL=capacity.d.ts.map
|
package/dist/capacity.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capacity.d.ts","sourceRoot":"","sources":["../src/capacity.ts"],"names":[],"mappings":"AACA
|
|
1
|
+
{"version":3,"file":"capacity.d.ts","sourceRoot":"","sources":["../src/capacity.ts"],"names":[],"mappings":"AACA;;yEAEyE;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/E,OAAO,KAAK,EAAqB,kBAAkB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAGjF,KAAK,cAAc,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,IAAI,CAAC,CAAA;AAE1E,KAAK,cAAc,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI,CAAC,CAAA;AAE1D,UAAU,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC3C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CACjB;AAED,UAAU,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC9C,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CACjB;AAED,UAAU,YAAY,CAAC,SAAS,SAAS,MAAM;IAC9C,QAAQ,CAAC,+EAA+E,EAAE,SAAS,CAAA;CACnG;AAED;;;;GAIG;AACH,UAAU,WAAW,CAAC,KAAK,SAAS,MAAM;IACzC,QAAQ,CAAC,6DAA6D,EAAE,KAAK,CAAA;CAC7E;AAED,KAAK,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI,GAAG,CAAC,EAAE,SAAS,IAAI,MAAM,EAAE,GAAG,IAAI,GAAG,KAAK,CAAA;AAE9E;;;;;GAKG;AACH,KAAK,OAAO,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,SAAS,CAAC,GAC9C,OAAO,GACP,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,EAAE,GAC9B,WAAW,CAAC,+HAA+H,CAAC,GAC5I,OAAO,CAAA;AAEX,KAAK,WAAW,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,SAAS,CAAC,GAClD,OAAO,GACP,UAAU,CAAC,CAAC,CAAC,SAAS,IAAI,GACzB,YAAY,CAAC,6DAA6D,CAAC,GAC3E,OAAO,CAAA;AAEX;;;;;;GAMG;AACH,KAAK,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,CAAA;AAEhD,KAAK,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,MAAM,IAAI,MAAM,SAAS,EAAE,GACpE,OAAO,GACP,MAAM,SAAS,EAAE,GAChB,OAAO,GACP,UAAU,CAAC,EAAE,CAAC,SAAS,IAAI,GAC1B,YAAY,CAAC,6DAA6D,CAAC,GAC3E,UAAU,CAAC,EAAE,CAAC,SAAS,IAAI,GAC1B,YAAY,CAAC,6DAA6D,CAAC,GAC3E,OAAO,CAAA;AAEb;;;;;;;GAOG;AACH,KAAK,gBAAgB,CAAC,CAAC,SAAS,cAAc,IAAI,CAAC,SAAS;IAC3D,QAAQ,CAAC,EAAE,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAA;CAC/C,GACE,YAAY,CAAC,sJAAsJ,CAAC,GACpK,OAAO,CAAA;AAEV,KAAK,MAAM,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,MAAM,IACjD,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;AAEpF,UAAU,oBAAoB,CAAC,CAAC,EAAE,MAAM;IACvC,QAAQ,CAAC,kHAAkH,EAAE,SAAS;QACrI,CAAC;QACD,MAAM;KACN,CAAA;CACD;AAED,UAAU,iBAAiB,CAAC,CAAC,EAAE,IAAI;IAClC,QAAQ,CAAC,0GAA0G,EAAE,SAAS;QAC7H,CAAC;QACD,IAAI;KACJ,CAAA;CACD;AAED,KAAK,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,SAAS,KAAK,GAAG,UAAU,EAAE,CAAC,SAAS,OAAO,IAAI,MAAM,SAAS,CAAC,GACxG,OAAO,GACP,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAC/B,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,IAAI,GACjC,OAAO,GACP,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,GAC3B,oBAAoB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AAEnD,KAAK,cAAc,CAAC,CAAC,SAAS,cAAc,EAAE,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS;IAC5E,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;CAC9B,GACE,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,GAC1B,CAAC,SAAS;IAAE,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;CAAE,GAC9C,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,GAC/B,OAAO,CAAA;AAEX,UAAU,qBAAqB,CAAC,CAAC,EAAE,MAAM;IACxC,QAAQ,CAAC,+FAA+F,EAAE,SAAS;QAClH,CAAC;QACD,MAAM;KACN,CAAA;CACD;AAED,UAAU,kBAAkB,CAAC,CAAC,EAAE,IAAI;IACnC,QAAQ,CAAC,oHAAoH,EAAE,SAAS;QACvI,CAAC;QACD,IAAI;KACJ,CAAA;CACD;AAED;;;;;;GAMG;AACH,KAAK,cAAc,CAAC,CAAC,SAAS,cAAc,EAAE,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS;IAC5E,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,MAAM,CAAA;CACtC,GACE,MAAM,SAAS,CAAC,GACf,OAAO,GACP,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAC/B,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,KAAK,GAClC,OAAO,GACP,kBAAkB,CAAC,CAAC,EAAE,KAAK,CAAC,GAC7B,qBAAqB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAClD,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,MAAM,CAAA;CAAE,GACnF,MAAM,SAAS,CAAC,GACf,OAAO,GACP,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAC/B,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,UAAU,GACvC,OAAO,GACP,kBAAkB,CAAC,CAAC,EAAE,UAAU,CAAC,GAClC,qBAAqB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAClD,OAAO,CAAA;AAEX,QAAA,MAAM,UAAU,EAAE,UAA4C,CAAA;AAsB9D,iBAAS,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EACrC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GACnB,cAAc,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;KAAE,CAAA;CAAE,CAAC,CAAA;AAEtG,iBAAS,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EACtC,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC,EACrB,EAAE,EAAE,GAAG,GACL,cAAc,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAA;KAAE,CAAA;CAAE,CAAC,CAAA;AACxG;;;;;GAKG;AACH,iBAAS,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,QAAQ,GAAG,WAAW,EAC9E,EAAE,EAAE,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,EACxB,EAAE,EAAE,CAAC,GACH,cAAc,CAAC;IACjB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAA;KAAE,CAAA;IACzD,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;CACd,CAAC,CAAA;AAEF,iBAAS,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,MAAM,EAC/D,EAAE,EAAE,EAAE,EACN,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,GACvB,cAAc,CACd;IACA,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAA;KAAE,CAAA;IACzD,QAAQ,CAAC,EAAE,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAA;KAAE,CAAA;CACxD,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAA;KAAE,CAAA;CAAE,CACtF,CAAA;AA6CD;;;;;GAKG;AACH,iBAAS,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EACpC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACnB,cAAc,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,CAAA;AAChE,iBAAS,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EACpC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,cAAc,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,CAAA;AAQxE,iBAAS,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAEvE;AAED;;;;;GAKG;AACH,iBAAS,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAE/E;AAED,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAA;AAwBvH,iBAAS,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAkBtD;AAED,iBAAS,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAStD;AAED,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA"}
|
package/dist/capacity.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { AuthoringError } from "#errors.ts";
|
|
2
|
-
|
|
3
|
-
function isCapacityWindow(value) {
|
|
4
|
-
return typeof value === "object" && value !== null && admitted in value && "window" in value;
|
|
5
|
-
}
|
|
6
|
-
function isCapacityWeight(value) {
|
|
7
|
-
return typeof value === "object" && value !== null && admitted in value && "weight" in value;
|
|
8
|
-
}
|
|
2
|
+
import { integerValue, recordValue } from "#values.ts";
|
|
9
3
|
const unitWeight = Object.freeze({ kind: "unit" });
|
|
10
4
|
function assertRowLocal(field, role) {
|
|
5
|
+
if (typeof field !== "string" || !field.isWellFormed())
|
|
6
|
+
throw new AuthoringError({ message: `${role}: expected a well-formed field name` });
|
|
11
7
|
if (field.includes(".")) {
|
|
12
8
|
throw new AuthoringError({
|
|
13
9
|
message: `${role} \`${field}\` walks a reference — the vocabulary is closed at the row (ruling 6): pin the column with a two-column containment (Source(ref, f) <= Catalog(id, f)) and name the local field`
|
|
@@ -16,13 +12,16 @@ function assertRowLocal(field, role) {
|
|
|
16
12
|
return field;
|
|
17
13
|
}
|
|
18
14
|
function admitWindow(window) {
|
|
19
|
-
|
|
20
|
-
return Object.freeze(
|
|
15
|
+
capacityWindow(window);
|
|
16
|
+
return Object.freeze(window);
|
|
21
17
|
}
|
|
22
18
|
function lit(value) {
|
|
23
19
|
return Object.freeze({ kind: "lit", value });
|
|
24
20
|
}
|
|
25
21
|
function within(lo, hi) {
|
|
22
|
+
integerValue("capacity lower bound", "u64", lo);
|
|
23
|
+
if (typeof hi === "bigint")
|
|
24
|
+
integerValue("capacity upper bound", "u64", hi);
|
|
26
25
|
if (lo < 0n) {
|
|
27
26
|
throw new AuthoringError({
|
|
28
27
|
message: `capacity bounds are u64: within(${lo}${hi === undefined ? "" : ", …"}) is out of domain`
|
|
@@ -59,8 +58,8 @@ function within(lo, hi) {
|
|
|
59
58
|
return admitWindow({ kind: "range", lo: lit(lo), hi: Object.freeze({ kind: "field", field }) });
|
|
60
59
|
}
|
|
61
60
|
function admitWeight(weight) {
|
|
62
|
-
|
|
63
|
-
return Object.freeze(
|
|
61
|
+
capacityWeight(weight);
|
|
62
|
+
return Object.freeze(weight);
|
|
64
63
|
}
|
|
65
64
|
function weigh(measure) {
|
|
66
65
|
if (typeof measure === "string") {
|
|
@@ -80,5 +79,57 @@ function ref(field) {
|
|
|
80
79
|
function duration(field) {
|
|
81
80
|
return Object.freeze({ kind: "durationField", field: assertRowLocal(field, "Duration measure") });
|
|
82
81
|
}
|
|
83
|
-
|
|
82
|
+
/** Read a checked bound without retaining a caller-owned record. */
|
|
83
|
+
function capacityBound(input) {
|
|
84
|
+
const kind = typeof input === "object" && input !== null && "kind" in input ? input.kind : undefined;
|
|
85
|
+
if (kind === "lit") {
|
|
86
|
+
const bound = recordValue("capacity bound", input, ["kind", "value"]);
|
|
87
|
+
return Object.freeze({ kind, value: integerValue("capacity bound", "u64", bound.value) });
|
|
88
|
+
}
|
|
89
|
+
if (kind === "field" || kind === "durationField") {
|
|
90
|
+
const bound = recordValue("capacity bound", input, ["kind", "field"]);
|
|
91
|
+
if (typeof bound.field !== "string")
|
|
92
|
+
throw new AuthoringError({ message: "capacity bound: expected a field name" });
|
|
93
|
+
return Object.freeze({ kind, field: assertRowLocal(bound.field, "dependent bound") });
|
|
94
|
+
}
|
|
95
|
+
throw new AuthoringError({ message: "capacity bound: unknown kind" });
|
|
96
|
+
}
|
|
97
|
+
function literalBound(input) {
|
|
98
|
+
const bound = capacityBound(input);
|
|
99
|
+
if (bound.kind !== "lit")
|
|
100
|
+
throw new AuthoringError({ message: "dependent bounds are allowed only at a range's upper bound" });
|
|
101
|
+
return bound;
|
|
102
|
+
}
|
|
103
|
+
function capacityWindow(input) {
|
|
104
|
+
const kind = typeof input === "object" && input !== null && "kind" in input ? input.kind : undefined;
|
|
105
|
+
if (kind === "exact") {
|
|
106
|
+
const window = recordValue("capacity window", input, ["kind", "n"]);
|
|
107
|
+
return Object.freeze({ kind, n: literalBound(window.n) });
|
|
108
|
+
}
|
|
109
|
+
if (kind === "floor") {
|
|
110
|
+
const window = recordValue("capacity window", input, ["kind", "lo"]);
|
|
111
|
+
return Object.freeze({ kind, lo: literalBound(window.lo) });
|
|
112
|
+
}
|
|
113
|
+
if (kind === "range") {
|
|
114
|
+
const window = recordValue("capacity window", input, ["kind", "lo", "hi"]);
|
|
115
|
+
const lo = literalBound(window.lo);
|
|
116
|
+
const hi = capacityBound(window.hi);
|
|
117
|
+
if (hi.kind === "lit" && hi.value < lo.value)
|
|
118
|
+
throw new AuthoringError({ message: "capacity window is inverted" });
|
|
119
|
+
return Object.freeze({ kind, lo, hi });
|
|
120
|
+
}
|
|
121
|
+
throw new AuthoringError({ message: "capacity window: unknown kind" });
|
|
122
|
+
}
|
|
123
|
+
function capacityWeight(input) {
|
|
124
|
+
const kind = typeof input === "object" && input !== null && "kind" in input ? input.kind : undefined;
|
|
125
|
+
if (kind === "unit") {
|
|
126
|
+
recordValue("capacity weight", input, ["kind"]);
|
|
127
|
+
return unitWeight;
|
|
128
|
+
}
|
|
129
|
+
const weight = capacityBound(input);
|
|
130
|
+
if (weight.kind === "lit")
|
|
131
|
+
throw new AuthoringError({ message: "capacity weight: expected unit or a source field" });
|
|
132
|
+
return weight;
|
|
133
|
+
}
|
|
134
|
+
export { capacityWeight, capacityWindow, duration, ref, unitWeight, weigh, within };
|
|
84
135
|
//# sourceMappingURL=capacity.js.map
|
package/dist/capacity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capacity.js","sourceRoot":"","sources":["../src/capacity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"capacity.js","sourceRoot":"","sources":["../src/capacity.ts"],"names":[],"mappings":"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"}
|