@jarenjs/linq 0.72.2 → 0.72.3
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/ARCHITECTURE.md +4 -0
- package/docs/DB-CLIENT.md +1 -1
- package/docs/LINQ-FORMAT.md +4 -4
- package/docs/QUERY-PEN.md +3 -3
- package/package.json +6 -6
- package/src/async.js +5 -13
- package/src/db/ledger.js +2 -1
- package/src/document.js +13 -0
- package/src/sequence.js +5 -13
package/ARCHITECTURE.md
CHANGED
|
@@ -49,6 +49,10 @@ document (`{ $count: … }`), and `groupBy` packs its default return as
|
|
|
49
49
|
`{ key: …, items: [ '$it' ] }` because an object member takes exactly
|
|
50
50
|
one item.
|
|
51
51
|
|
|
52
|
+
The emitter also owns `requireNonNegativeInteger`, the shared count/index guard
|
|
53
|
+
for synchronous and asynchronous sequence windows and positional terminals.
|
|
54
|
+
Both surfaces report the same `JL0005` refusal at their existing call boundary.
|
|
55
|
+
|
|
52
56
|
## The typed surface (`types/index.d.ts`)
|
|
53
57
|
|
|
54
58
|
Hand-authored declarations are the public type contract (the runtime
|
package/docs/DB-CLIENT.md
CHANGED
|
@@ -826,7 +826,7 @@ never builds one; the migration between two of them is
|
|
|
826
826
|
|
|
827
827
|
## 7. Cost
|
|
828
828
|
|
|
829
|
-
`@jarenjs/linq/db` builds to **<!--fact:bundle.db-->627,
|
|
829
|
+
`@jarenjs/linq/db` builds to **<!--fact:bundle.db-->627,769<!--/fact--> bytes** as a minified,
|
|
830
830
|
tree-shaken ESM bundle — the figure `scripts/check-tree-shaking.js`
|
|
831
831
|
measures and `npm run test:tree-shaking` reports, published rounded
|
|
832
832
|
(<!--fact:bundle.db.kb-->628<!--/fact--> kB) beside the other nine subpath prices in
|
package/docs/LINQ-FORMAT.md
CHANGED
|
@@ -205,7 +205,7 @@ and the bundle is the byte count the tree-shaking probe builds.
|
|
|
205
205
|
| Document | Subpath | Lines | Mapping rows | Worked examples | Refusals | Bundle |
|
|
206
206
|
|---|---|---:|---:|---:|---:|---:|
|
|
207
207
|
| [LINQ-FORMAT.md](LINQ-FORMAT.md) | — | 948 | — | — | — | — |
|
|
208
|
-
| [QUERY-PEN.md](QUERY-PEN.md) | `.` | 1,725 | 34 | 8 | 15 | 174,
|
|
208
|
+
| [QUERY-PEN.md](QUERY-PEN.md) | `.` | 1,725 | 34 | 8 | 15 | 174,131 B |
|
|
209
209
|
| [SCHEMA-PEN.md](SCHEMA-PEN.md) | `./schema` | 1,205 | 82 | 10 | 4 | 36,717 B |
|
|
210
210
|
| [MODEL-PEN.md](MODEL-PEN.md) | `./model` | 1,092 | 28 | 6 | 3 | 45,143 B |
|
|
211
211
|
| [JSLT-PEN.md](JSLT-PEN.md) | `./jslt` | 955 | 17 | 8 | 3 | 19,856 B |
|
|
@@ -219,7 +219,7 @@ and the bundle is the byte count the tree-shaking probe builds.
|
|
|
219
219
|
| [JTLT-PEN.md](JTLT-PEN.md) | `./jtlt` | 83 | 13 | 1 | 2 | 16,725 B |
|
|
220
220
|
| [PROJECT-PEN.md](PROJECT-PEN.md) | `./project` | 75 | 9 | 1 | 1 | 15,132 B |
|
|
221
221
|
| [CHARTS-PEN.md](CHARTS-PEN.md) | `./charts` | 94 | 21 | 1 | 1 | 17,014 B |
|
|
222
|
-
| [DB-CLIENT.md](DB-CLIENT.md) | `./db` | 893 | 41 | 4 | 2 | 627,
|
|
222
|
+
| [DB-CLIENT.md](DB-CLIENT.md) | `./db` | 893 | 41 | 4 | 2 | 627,769 B |
|
|
223
223
|
| **16 documents** | | **12,391** | **371** | **73** | | |
|
|
224
224
|
<!--/fact-->
|
|
225
225
|
|
|
@@ -262,7 +262,7 @@ it and each document publishes it. The rounded column is what
|
|
|
262
262
|
<!--fact:pens.cost-->
|
|
263
263
|
| Subpath | Document | Bundle | Rounded |
|
|
264
264
|
|---|---|---:|---:|
|
|
265
|
-
| `@jarenjs/linq` | [QUERY-PEN.md](QUERY-PEN.md) | 174,
|
|
265
|
+
| `@jarenjs/linq` | [QUERY-PEN.md](QUERY-PEN.md) | 174,131 B | 174 kB |
|
|
266
266
|
| `@jarenjs/linq/schema` | [SCHEMA-PEN.md](SCHEMA-PEN.md) | 36,717 B | 37 kB |
|
|
267
267
|
| `@jarenjs/linq/model` | [MODEL-PEN.md](MODEL-PEN.md) | 45,143 B | 45 kB |
|
|
268
268
|
| `@jarenjs/linq/jslt` | [JSLT-PEN.md](JSLT-PEN.md) | 19,856 B | 20 kB |
|
|
@@ -276,7 +276,7 @@ it and each document publishes it. The rounded column is what
|
|
|
276
276
|
| `@jarenjs/linq/jtlt` | [JTLT-PEN.md](JTLT-PEN.md) | 16,725 B | 17 kB |
|
|
277
277
|
| `@jarenjs/linq/project` | [PROJECT-PEN.md](PROJECT-PEN.md) | 15,132 B | 15 kB |
|
|
278
278
|
| `@jarenjs/linq/charts` | [CHARTS-PEN.md](CHARTS-PEN.md) | 17,014 B | 17 kB |
|
|
279
|
-
| `@jarenjs/linq/db` | [DB-CLIENT.md](DB-CLIENT.md) | 627,
|
|
279
|
+
| `@jarenjs/linq/db` | [DB-CLIENT.md](DB-CLIENT.md) | 627,769 B | 628 kB |
|
|
280
280
|
<!--/fact-->
|
|
281
281
|
|
|
282
282
|
Read these as prices, not as scores. `./db` is the largest by an order of
|
package/docs/QUERY-PEN.md
CHANGED
|
@@ -1672,14 +1672,14 @@ are shorter:
|
|
|
1672
1672
|
## 17. Cost
|
|
1673
1673
|
|
|
1674
1674
|
A consumer importing `from` from `@jarenjs/linq` and calling one
|
|
1675
|
-
terminal bundles **<!--fact:bundle.chain-->174,
|
|
1675
|
+
terminal bundles **<!--fact:bundle.chain-->174,131<!--/fact--> bytes** (esbuild, ESM, minified, tree-shaken,
|
|
1676
1676
|
`platform: 'neutral'`). The figure is measured by
|
|
1677
1677
|
`scripts/check-tree-shaking.js`'s chain probe and compared with this
|
|
1678
1678
|
section on every `npm run test:tree-shaking`: it is derived, never typed,
|
|
1679
1679
|
and a stale one is red here rather than wrong in a document somebody
|
|
1680
1680
|
reads.
|
|
1681
1681
|
|
|
1682
|
-
Of that, **<!--fact:bundle.chain.own-->40,
|
|
1682
|
+
Of that, **<!--fact:bundle.chain.own-->40,131<!--/fact--> bytes** are the chain's own modules — `sequence.js`,
|
|
1683
1683
|
`async.js`, `expression.js`, `document.js`, `provider.js`,
|
|
1684
1684
|
`concurrency.js`, `errors.js` and `schema-of.js`. The remaining ~134 kB
|
|
1685
1685
|
is the query ENGINE and the core it stands on: a chain's document has to
|
|
@@ -1715,7 +1715,7 @@ the reason is worth knowing: a bundler counts a shared module once, and
|
|
|
1715
1715
|
the chain and every pen share the expression capture (`expression.js`)
|
|
1716
1716
|
and the coded errors under it (`errors.js`, and `@jarenjs/core`'s error
|
|
1717
1717
|
and object helpers). A consumer importing the chain AND the schema pen
|
|
1718
|
-
bundles **<!--fact:bundle.chain.withSchemaPen-->198,
|
|
1718
|
+
bundles **<!--fact:bundle.chain.withSchemaPen-->198,801<!--/fact--> bytes** — **<!--fact:bundle.chain.shared-->12,047<!--/fact--> bytes** less than the sum of the
|
|
1719
1719
|
figure above and [SCHEMA-PEN.md](SCHEMA-PEN.md#7-cost) §7's, which is
|
|
1720
1720
|
what those shared modules weigh. The probe measures that pair too, so
|
|
1721
1721
|
the saving is derived like everything else here. What the chain does NOT
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jarenjs/linq",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.72.
|
|
4
|
+
"version": "0.72.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./types/index.d.ts",
|
|
@@ -104,13 +104,13 @@
|
|
|
104
104
|
"prepack": "npm run build:types"
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
|
-
"@jarenjs/core": "^0.72.
|
|
108
|
-
"@jarenjs/json": "^0.72.
|
|
107
|
+
"@jarenjs/core": "^0.72.3",
|
|
108
|
+
"@jarenjs/json": "^0.72.3"
|
|
109
109
|
},
|
|
110
110
|
"peerDependencies": {
|
|
111
|
-
"@jarenjs/db": "^0.72.
|
|
112
|
-
"@jarenjs/formats": "^0.72.
|
|
113
|
-
"@jarenjs/validate": "^0.72.
|
|
111
|
+
"@jarenjs/db": "^0.72.3",
|
|
112
|
+
"@jarenjs/formats": "^0.72.3",
|
|
113
|
+
"@jarenjs/validate": "^0.72.3"
|
|
114
114
|
},
|
|
115
115
|
"peerDependenciesMeta": {
|
|
116
116
|
"@jarenjs/db": {
|
package/src/async.js
CHANGED
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
} from './provider.js';
|
|
46
46
|
import {
|
|
47
47
|
emitDocument, wrapTerminal, snapshot, fanProjection, isReservedBinding, RESERVED_BINDINGS_TEXT,
|
|
48
|
-
PROJECTING_STAGES,
|
|
48
|
+
PROJECTING_STAGES, requireNonNegativeInteger,
|
|
49
49
|
} from './document.js';
|
|
50
50
|
import { adaptAsyncSource } from './sources.js';
|
|
51
51
|
import { applyMapAsync, normalizeMapAsyncOptions } from './concurrency.js';
|
|
@@ -369,8 +369,8 @@ export class AsyncSequence {
|
|
|
369
369
|
}, params);
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
skip(count) { return this.#with({ kind: 'skip', count:
|
|
373
|
-
take(count) { return this.#with({ kind: 'take', count:
|
|
372
|
+
skip(count) { return this.#with({ kind: 'skip', count: requireNonNegativeInteger(count, 'skip') }); }
|
|
373
|
+
take(count) { return this.#with({ kind: 'take', count: requireNonNegativeInteger(count, 'take') }); }
|
|
374
374
|
distinct() { return this.#with({ kind: 'distinct' }); }
|
|
375
375
|
reverse() { return this.#with({ kind: 'reverse' }); }
|
|
376
376
|
|
|
@@ -722,7 +722,7 @@ export class AsyncSequence {
|
|
|
722
722
|
|
|
723
723
|
/** @param {number} index */
|
|
724
724
|
async elementAt(index) {
|
|
725
|
-
|
|
725
|
+
requireNonNegativeInteger(index, 'elementAt');
|
|
726
726
|
const w = this.#pushable()
|
|
727
727
|
? await this.#pushWindow('elementAt', [index]) : await this.skip(index).#window(1);
|
|
728
728
|
if (w.length === 0) throw new LinqRuntimeError('JL2003', `elementAt(${index}) is out of range`);
|
|
@@ -731,7 +731,7 @@ export class AsyncSequence {
|
|
|
731
731
|
|
|
732
732
|
/** @param {number} index @param {any} [defaultValue] */
|
|
733
733
|
async elementAtOrDefault(index, defaultValue) {
|
|
734
|
-
|
|
734
|
+
requireNonNegativeInteger(index, 'elementAtOrDefault');
|
|
735
735
|
const w = this.#pushable()
|
|
736
736
|
? await this.#pushWindow('elementAt', [index]) : await this.skip(index).#window(1);
|
|
737
737
|
return w.length === 0 ? defaultValue : w[0];
|
|
@@ -832,14 +832,6 @@ async function collect(stream) {
|
|
|
832
832
|
return out;
|
|
833
833
|
}
|
|
834
834
|
|
|
835
|
-
/** @param {number} value @param {string} what */
|
|
836
|
-
function requireIndex(value, what) {
|
|
837
|
-
if (!Number.isInteger(value) || value < 0) {
|
|
838
|
-
throw new LinqBuildError('JL0005', `${what} takes a non-negative integer, got ${value}`);
|
|
839
|
-
}
|
|
840
|
-
return value;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
835
|
/** @param {any} bindings */
|
|
844
836
|
function validateParams(bindings) {
|
|
845
837
|
if (bindings === null || typeof bindings !== 'object' || Array.isArray(bindings)) {
|
package/src/db/ledger.js
CHANGED
|
@@ -132,7 +132,8 @@ export function createDbLedger(client, options = {}) {
|
|
|
132
132
|
return inside(async (tx) => {
|
|
133
133
|
const c = rows(tx);
|
|
134
134
|
const record = await c.get(r.id);
|
|
135
|
-
if (record === undefined || record.generation !== r.generation || record.status !== 'started'
|
|
135
|
+
if (record === undefined || record.generation !== r.generation || record.status !== 'started'
|
|
136
|
+
|| record.expiresAt <= at) {
|
|
136
137
|
throw stale(ref, 'the key expired, was reclaimed under a newer generation, or was settled already');
|
|
137
138
|
}
|
|
138
139
|
await c.put({ ...record, ...changes, updatedAt: at }, r.id);
|
package/src/document.js
CHANGED
|
@@ -39,6 +39,19 @@
|
|
|
39
39
|
|
|
40
40
|
import { LinqBuildError } from './errors.js';
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Validate a sequence window's count or a positional terminal's index.
|
|
44
|
+
* @param {number} value
|
|
45
|
+
* @param {string} what - The operator named by a refusal
|
|
46
|
+
* @returns {number} The unchanged count or index
|
|
47
|
+
*/
|
|
48
|
+
export function requireNonNegativeInteger(value, what) {
|
|
49
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
50
|
+
throw new LinqBuildError('JL0005', `${what} takes a non-negative integer, got ${value}`);
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
/** The binding names the emitted documents own (QUERY-PEN §7): the
|
|
43
56
|
* item bindings, the accumulator and the group — and the relation-hop
|
|
44
57
|
* bindings `r1`, `r2`, … a capture allocates (expression.js). A
|
package/src/sequence.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from './expression.js';
|
|
21
21
|
import {
|
|
22
22
|
emitDocument, wrapTerminal, snapshot, fanProjection, isReservedBinding, RESERVED_BINDINGS_TEXT,
|
|
23
|
-
PROJECTING_STAGES,
|
|
23
|
+
PROJECTING_STAGES, requireNonNegativeInteger,
|
|
24
24
|
} from './document.js';
|
|
25
25
|
import {
|
|
26
26
|
classifySource, compileDocument, executeInMemory, providerRoot, providerRelations, sharesScope,
|
|
@@ -31,14 +31,6 @@ import { schemaOf } from './schema-of.js';
|
|
|
31
31
|
|
|
32
32
|
const VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
33
33
|
|
|
34
|
-
/** @param {number} value @param {string} what */
|
|
35
|
-
function requireIndex(value, what) {
|
|
36
|
-
if (!Number.isInteger(value) || value < 0) {
|
|
37
|
-
throw new LinqBuildError('JL0005', `${what} takes a non-negative integer, got ${value}`);
|
|
38
|
-
}
|
|
39
|
-
return value;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
34
|
/** The immutable query sequence. Construct via `from`/`fromDocument`. */
|
|
43
35
|
export class Sequence {
|
|
44
36
|
#source;
|
|
@@ -315,11 +307,11 @@ export class Sequence {
|
|
|
315
307
|
}
|
|
316
308
|
|
|
317
309
|
skip(count) {
|
|
318
|
-
return this.#with({ kind: 'skip', count:
|
|
310
|
+
return this.#with({ kind: 'skip', count: requireNonNegativeInteger(count, 'skip') });
|
|
319
311
|
}
|
|
320
312
|
|
|
321
313
|
take(count) {
|
|
322
|
-
return this.#with({ kind: 'take', count:
|
|
314
|
+
return this.#with({ kind: 'take', count: requireNonNegativeInteger(count, 'take') });
|
|
323
315
|
}
|
|
324
316
|
|
|
325
317
|
distinct() {
|
|
@@ -557,7 +549,7 @@ export class Sequence {
|
|
|
557
549
|
}
|
|
558
550
|
|
|
559
551
|
elementAt(index) {
|
|
560
|
-
|
|
552
|
+
requireNonNegativeInteger(index, 'elementAt');
|
|
561
553
|
const w = this.#window('elementAt', [index]);
|
|
562
554
|
if (w.length === 0) throw new LinqRuntimeError('JL2003', `elementAt(${index}) is out of range`);
|
|
563
555
|
return w[0];
|
|
@@ -565,7 +557,7 @@ export class Sequence {
|
|
|
565
557
|
|
|
566
558
|
/** @param {number} index @param {any} [defaultValue] */
|
|
567
559
|
elementAtOrDefault(index, defaultValue) {
|
|
568
|
-
|
|
560
|
+
requireNonNegativeInteger(index, 'elementAtOrDefault');
|
|
569
561
|
const w = this.#window('elementAt', [index]);
|
|
570
562
|
return w.length === 0 ? defaultValue : w[0];
|
|
571
563
|
}
|