@jarenjs/linq 0.34.0 → 0.43.1
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 +10 -0
- package/docs/LINQ-FORMAT.md +16 -1
- package/package.json +3 -3
- package/src/expression.js +21 -0
package/README.md
CHANGED
|
@@ -42,6 +42,16 @@ played by the provider seam below.
|
|
|
42
42
|
concurrency bound and the `parallel`/`concat`/`switch`/`exhaust`
|
|
43
43
|
vocabulary; barrier operators buffer and run through the one engine
|
|
44
44
|
so streaming answers equal in-memory answers by construction.
|
|
45
|
+
- **Geography is spellable.** The whole §8.14 family is on the
|
|
46
|
+
expression surface: `p.location.within(region)`,
|
|
47
|
+
`p.location.distance(here)`, `p.route.geoLength()`,
|
|
48
|
+
`p.location.geohash(6)`, and the conversion pair `geoParse`/`geoText`
|
|
49
|
+
that reads a WKT column and writes one back. A plain GeoJSON object
|
|
50
|
+
embeds as a literal; `.params({ region })` binds it at call time
|
|
51
|
+
instead, which is the shape a spatial index can be probed with. The
|
|
52
|
+
spatial measurements are `geoArea`/`geoLength` because `length` on
|
|
53
|
+
this surface is already `$string-length` — the mapping table says so
|
|
54
|
+
in its own row.
|
|
45
55
|
- **The provider contract.** Any object with
|
|
46
56
|
`execute(queryDocument, { externals })` is a provider.
|
|
47
57
|
`@jarenjs/db` implements it — a chain over a SQLite-backed
|
package/docs/LINQ-FORMAT.md
CHANGED
|
@@ -115,7 +115,22 @@ is part of THIS design.
|
|
|
115
115
|
| `Cast<S>` | `$assert` per item | native | `(schema)` → `Seq<S>`; needs `compileTypeTest` (`JL0003`) |
|
|
116
116
|
| `Zip` | — no positional co-iteration in the grammar | unsupported (`JL0006`) | — |
|
|
117
117
|
| expression methods | `eq ne lt le gt ge` → `$eq…$ge`; `and or not`; `add sub mul div idiv mod neg`; `startsWith endsWith contains matches upper lower length concat substring replace` → §8.7; `count sum avg min max` → §8.8 (aggregates as expressions, e.g. over a group); `year month day epoch` → §8.13; `exists isEmpty`; `at all get` | native | on `Expr<…>`, per the typed-surface order |
|
|
118
|
-
| spatial family (§8.14) |
|
|
118
|
+
| spatial family (§8.14) | `bbox geoArea geoLength centroid` → `$bbox $area $length $centroid`; `distance within bboxIntersects` → `$distance $within $bbox-intersects`; `geohash(precision?)` → `$geohash` (optional arity, like `substring`); `geoParse geoText geohashBounds geohashNeighbours` → the conversion family; `geoSimplify(tolerance)` → `$geo-simplify`. A plain JSON polygon embeds as a literal (`p.at.within(poly)`); `.params({ region })` makes it an external instead | native | on `Expr<…>`, per the typed-surface order |
|
|
119
|
+
|
|
120
|
+
Two spatial names are deliberately not the obvious ones, and the reason
|
|
121
|
+
is the same one that made §8.14's `$length` and §8.7's `$string-length`
|
|
122
|
+
two operators: **`length` on this surface is already `$string-length`**,
|
|
123
|
+
and §8.14's `$length` is a geodesic line measurement. One method name
|
|
124
|
+
cannot carry both, and renaming the shipped string method for symmetry
|
|
125
|
+
would break a published surface for a cosmetic gain — so the spatial one
|
|
126
|
+
is **`geoLength`**, and **`geoArea`** joins it, because a bare `area()`
|
|
127
|
+
on an arbitrary expression reads as arithmetic to a C# eye. The prefix
|
|
128
|
+
names the family the way `geoParse`/`geoText` already do.
|
|
129
|
+
|
|
130
|
+
Every method name shadows a data member of the same name — that is what
|
|
131
|
+
the null prototype on the method table is for, and what `get(name)`
|
|
132
|
+
escapes. A position stored as `at` is the case that bites: `p.at` is the
|
|
133
|
+
index method, so it reads `p.get('at').within(region)`.
|
|
119
134
|
|
|
120
135
|
## 5. Deferred execution and re-enumeration
|
|
121
136
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jarenjs/linq",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.43.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./types/index.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"prepack": "npm run build:types"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@jarenjs/core": "^0.
|
|
51
|
-
"@jarenjs/json": "^0.
|
|
50
|
+
"@jarenjs/core": "^0.43.1",
|
|
51
|
+
"@jarenjs/json": "^0.43.1"
|
|
52
52
|
}
|
|
53
53
|
}
|
package/src/expression.js
CHANGED
|
@@ -216,6 +216,27 @@ const METHODS = {
|
|
|
216
216
|
// arrives with the relational order)
|
|
217
217
|
year: unary('$year'), month: unary('$month'), day: unary('$day'),
|
|
218
218
|
epoch: unary('$epoch'),
|
|
219
|
+
// §8.14 spatial. `geoArea`/`geoLength` rather than `area`/`length`:
|
|
220
|
+
// `length` is already `$string-length` on this surface and renaming a
|
|
221
|
+
// shipped method for symmetry is a breaking change for a cosmetic
|
|
222
|
+
// gain, while a bare `area()` on an arbitrary expression reads as
|
|
223
|
+
// arithmetic. The prefix names the family the way `geoParse`/`geoText`
|
|
224
|
+
// do, and it is the same reason `$length` and `$string-length` are two
|
|
225
|
+
// operators in the first place.
|
|
226
|
+
bbox: unary('$bbox'), geoArea: unary('$area'),
|
|
227
|
+
geoLength: unary('$length'), centroid: unary('$centroid'),
|
|
228
|
+
distance: binary('$distance'), within: binary('$within'),
|
|
229
|
+
bboxIntersects: binary('$bbox-intersects'),
|
|
230
|
+
geoParse: unary('$geo-parse'), geoText: unary('$geo-text'),
|
|
231
|
+
geohashBounds: unary('$geohash-bounds'),
|
|
232
|
+
geohashNeighbours: unary('$geohash-neighbours'),
|
|
233
|
+
geoSimplify: binary('$geo-simplify'),
|
|
234
|
+
geohash(record, precision) {
|
|
235
|
+
const args = precision === undefined
|
|
236
|
+
? record.doc
|
|
237
|
+
: [record.doc, toExpression(precision)];
|
|
238
|
+
return makeExpr({ $geohash: args }, record.epoch, false);
|
|
239
|
+
},
|
|
219
240
|
// path navigation
|
|
220
241
|
at(record, index) {
|
|
221
242
|
if (record.pathable && Number.isInteger(index)) {
|