@lde/search 0.4.1 → 0.6.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 +26 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/project.d.ts +18 -5
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +11 -8
- package/dist/schema.d.ts +16 -13
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +7 -7
- package/dist/testing.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The core of the LDE search family: packages that together act as a **generator
|
|
4
4
|
for search engines**. You write one declarative `SearchSchema`, and everything
|
|
5
5
|
a running search engine needs is derived from it: the document projection, the
|
|
6
|
-
engine collection
|
|
6
|
+
engine collection definition, the query semantics, and the API surface. All these
|
|
7
7
|
are kept in sync automatically rather than handwritten per deployment.
|
|
8
8
|
|
|
9
9
|
The core itself is **engine-, API- and domain-agnostic**: it bakes in no search
|
|
@@ -34,7 +34,7 @@ It provides four things:
|
|
|
34
34
|
|
|
35
35
|
```
|
|
36
36
|
SearchSchema ─┬─► projection (projectGraph → flat documents) [here]
|
|
37
|
-
├─► engine adapter (collection
|
|
37
|
+
├─► engine adapter (collection definition + query compiler) e.g. @lde/search-typesense
|
|
38
38
|
├─► query semantics (SearchQuery, filter/sort/facet) [here]
|
|
39
39
|
└─► API surface (GraphQL / REST) e.g. @lde/search-api-graphql
|
|
40
40
|
```
|
|
@@ -50,7 +50,7 @@ results: engine response ──parse──► SearchResult ──shape──
|
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
Validation happens before the first arrow (SHACL over the RDF) and inside the
|
|
53
|
-
last (the engine enforces its collection
|
|
53
|
+
last (the engine enforces its collection definition); between them every stage is
|
|
54
54
|
a typed, deterministic function — easy to test, and swappable per deployment.
|
|
55
55
|
|
|
56
56
|
## Entry points
|
|
@@ -72,11 +72,11 @@ Exports are stratified by audience:
|
|
|
72
72
|
The model has three levels, with analogues in SHACL ([one possible source](#why-a-declarative-model))
|
|
73
73
|
and GraphQL (one of the surfaces):
|
|
74
74
|
|
|
75
|
-
| Term | What it is
|
|
76
|
-
| -------------- |
|
|
77
|
-
| `SearchField` | One queryable field: a `kind`, the IR `path` it projects from, and the capability flags it opts into
|
|
78
|
-
| `SearchType` | One root type’s complete declaration: its logical API `name`, its `
|
|
79
|
-
| `SearchSchema` | The whole search declaration: every `SearchType`, keyed by `
|
|
75
|
+
| Term | What it is | SHACL | GraphQL |
|
|
76
|
+
| -------------- | ---------------------------------------------------------------------------------------------------------------- | -------------- | ----------- |
|
|
77
|
+
| `SearchField` | One queryable field: a `kind`, the IR `path` it projects from, and the capability flags it opts into | property shape | field |
|
|
78
|
+
| `SearchType` | One root type’s complete declaration: its logical API `name`, its `class` IRI and its fields (incl. derived) | NodeShape | object type |
|
|
79
|
+
| `SearchSchema` | The whole search declaration: every `SearchType`, keyed by `class` IRI — build one with `searchSchema(...types)` | shapes graph | schema |
|
|
80
80
|
|
|
81
81
|
`projectGraph` and the GraphQL surface consume a `SearchSchema` (projecting
|
|
82
82
|
every type in one pass); the engine port executes one `SearchType` at a time.
|
|
@@ -92,7 +92,7 @@ Two conventions hold across the whole family:
|
|
|
92
92
|
`engine.search(type, query)`.
|
|
93
93
|
- **Factory verbs** — the verb tells you what kind of thing comes back.
|
|
94
94
|
`define*` captures a declaration as a literal (`defineSearchType`);
|
|
95
|
-
`build*` is a pure data-to-data constructor (`
|
|
95
|
+
`build*` is a pure data-to-data constructor (`buildCollectionDefinition`,
|
|
96
96
|
`buildSearchParams`, `buildGraphQLSchema`); `create*` makes a stateful
|
|
97
97
|
instance (`createTypesenseSearchEngine`). A bare noun (`searchSchema`)
|
|
98
98
|
constructs the trivial container it names.
|
|
@@ -104,7 +104,7 @@ read (or a `derive` function for a **derived** field, computed from the framed
|
|
|
104
104
|
node in declaration order — so it may read fields declared before it), and the
|
|
105
105
|
capabilities it opts into. The physical field names a declaration fans out to
|
|
106
106
|
(per-locale search/sort keys) come from
|
|
107
|
-
`physicalFields`, the single convention projection, the collection
|
|
107
|
+
`physicalFields`, the single convention projection, the collection definition and the
|
|
108
108
|
query compiler all share.
|
|
109
109
|
|
|
110
110
|
```ts
|
|
@@ -117,7 +117,7 @@ import {
|
|
|
117
117
|
|
|
118
118
|
const DATASET = defineSearchType({
|
|
119
119
|
name: 'Dataset', // logical API name: names the GraphQL type, a REST path, …
|
|
120
|
-
|
|
120
|
+
class: 'http://www.w3.org/ns/dcat#Dataset',
|
|
121
121
|
fields: [
|
|
122
122
|
// → title_nl, title_en, title_search_nl/_en, title_sort_nl/_en
|
|
123
123
|
{
|
|
@@ -150,8 +150,14 @@ const DATASET = defineSearchType({
|
|
|
150
150
|
],
|
|
151
151
|
});
|
|
152
152
|
|
|
153
|
-
for await (const document of projectGraph(
|
|
154
|
-
|
|
153
|
+
for await (const { searchType, document } of projectGraph(
|
|
154
|
+
quads,
|
|
155
|
+
searchSchema(DATASET),
|
|
156
|
+
)) {
|
|
157
|
+
// one flat search document per matching subject, streamed and tagged with the
|
|
158
|
+
// SearchType it was framed from — so a multi-collection writer can route each
|
|
159
|
+
// document to the collection for its type. A single-collection consumer just
|
|
160
|
+
// reads `document`.
|
|
155
161
|
}
|
|
156
162
|
```
|
|
157
163
|
|
|
@@ -183,7 +189,7 @@ rejects a structurally invalid declaration (duplicate field names, an `output`
|
|
|
183
189
|
reference without `ref`, `text` without locales, `locales` on a non-text kind,
|
|
184
190
|
`facetRanges` on a non-numeric kind, `searchable`/`transform` on a kind whose
|
|
185
191
|
projection cannot honour it, `filterable`/`facetable` on `text`, two types
|
|
186
|
-
sharing a `
|
|
192
|
+
sharing a `class` IRI or `name`) — the declaration-time counterpart of the
|
|
187
193
|
port’s always-on query validation, so a bad schema fails at startup rather
|
|
188
194
|
than per document at index time. `validateSearchType` /
|
|
189
195
|
`assertValidSearchType` are exported for validating a single declaration
|
|
@@ -218,6 +224,12 @@ triples are collapsed first, because some SPARQL engines (e.g. QLever) do not
|
|
|
218
224
|
deduplicate `CONSTRUCT` output. The IR carries no `@context`, so a `derive` function
|
|
219
225
|
reading it sees full predicate IRIs with language tags preserved.
|
|
220
226
|
|
|
227
|
+
Each yielded value is a `{ searchType, document }` pair: the whole schema
|
|
228
|
+
projects into **one** mixed stream, and every document is tagged with the
|
|
229
|
+
`SearchType` it was framed from. That tag is what lets the write side fan the
|
|
230
|
+
stream out to per-type collections without re-deriving the type from the
|
|
231
|
+
document — see `@lde/search-pipeline`’s multi-collection writer.
|
|
232
|
+
|
|
221
233
|
`projectGraph` **consumes the quads once** – a single scan builds the subject
|
|
222
234
|
index every type frames off – and so accepts any `Iterable<Quad>`, not just a
|
|
223
235
|
materialized array. A caller merging several sources can pass a chained
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { projectGraph, irisOf, literalsOf, firstLiteralOf } from './project.js';
|
|
2
|
-
export type { SearchDocument } from './project.js';
|
|
2
|
+
export type { SearchDocument, TypedSearchDocument } from './project.js';
|
|
3
3
|
export { defineSearchType, searchSchema, validateSearchType, assertValidSearchType, } from './schema.js';
|
|
4
4
|
export type { FieldKind, SearchField, SearchFieldBase, TextField, KeywordField, ReferenceField, NumericField, BooleanField, SearchType, SearchTypeIssue, SearchSchema, FacetRange, } from './schema.js';
|
|
5
5
|
export type { SearchQuery, Filter, Sort } from './query.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAKxE,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EACZ,UAAU,GACX,MAAM,aAAa,CAAC;AAIrB,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAI5D,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,cAAc,EACd,WAAW,EACX,cAAc,EACd,SAAS,EACT,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/project.d.ts
CHANGED
|
@@ -5,27 +5,40 @@ import { type SearchSchema, type SearchType } from './schema.js';
|
|
|
5
5
|
export type SearchDocument = {
|
|
6
6
|
id: string;
|
|
7
7
|
} & Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* A projected document tagged with the {@link SearchType} it was projected
|
|
10
|
+
* from — one element of {@link projectGraph}’s mixed, whole-schema stream. The
|
|
11
|
+
* tag is what lets a multi-collection writer route each document to the
|
|
12
|
+
* collection for its type without re-deriving the type from the document.
|
|
13
|
+
*/
|
|
14
|
+
export interface TypedSearchDocument {
|
|
15
|
+
readonly searchType: SearchType;
|
|
16
|
+
readonly document: SearchDocument;
|
|
17
|
+
}
|
|
8
18
|
/**
|
|
9
19
|
* Project one framed JSON-LD node into a flat search document: apply each field
|
|
10
20
|
* of the type in declaration order. A field with a `derive` function computes
|
|
11
21
|
* its value from the node and the document as populated so far (so a derived
|
|
12
22
|
* field may read fields declared before it). The physical field names a field
|
|
13
23
|
* fans out to come from {@link physicalFields}, the single source shared with
|
|
14
|
-
* the engine collection
|
|
24
|
+
* the engine collection definition and the query compiler.
|
|
15
25
|
*/
|
|
16
26
|
export declare function projectDocument(node: FramedNode, searchType: SearchType): SearchDocument;
|
|
17
27
|
/**
|
|
18
28
|
* Frame `quads` for every root type in the schema and project each node with its
|
|
19
|
-
* type’s declaration — the multi-shape pipeline.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
29
|
+
* type’s declaration — the multi-shape pipeline. Yields each document tagged
|
|
30
|
+
* with its {@link SearchType} ({@link TypedSearchDocument}), so a downstream
|
|
31
|
+
* multi-collection writer can route it to that type’s collection; a
|
|
32
|
+
* single-collection consumer just reads `.document`. Streams one document at a
|
|
33
|
+
* time so memory stays flat. The IR maps to a declaration by type, so adding a
|
|
34
|
+
* shape is adding a `SearchType` to the schema (no engine change).
|
|
22
35
|
*
|
|
23
36
|
* Consumes `quads` once (a single scan builds the shared subject index that
|
|
24
37
|
* every type frames off), so it accepts any `Iterable` – a materialized array or
|
|
25
38
|
* a chained generator merging several sources (`function* () { yield* a; yield* b; }`)
|
|
26
39
|
* with no intermediate copy at the projection peak.
|
|
27
40
|
*/
|
|
28
|
-
export declare function projectGraph(quads: Iterable<Quad>, schema: SearchSchema): AsyncIterable<
|
|
41
|
+
export declare function projectGraph(quads: Iterable<Quad>, schema: SearchSchema): AsyncIterable<TypedSearchDocument>;
|
|
29
42
|
export declare function literalsOf(node: FramedNode, path: string): string[];
|
|
30
43
|
export declare function firstLiteralOf(node: FramedNode, path: string): string | undefined;
|
|
31
44
|
export declare function irisOf(node: FramedNode, path: string): string[];
|
package/dist/project.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAC;AAErB,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtE;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,UAAU,GACrB,cAAc,CAYhB;AAED
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAC;AAErB,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,UAAU,GACrB,cAAc,CAYhB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAuB,YAAY,CACjC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EACrB,MAAM,EAAE,YAAY,GACnB,aAAa,CAAC,mBAAmB,CAAC,CAWpC;AAsID,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAInE;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAI/D"}
|
package/dist/project.js
CHANGED
|
@@ -7,12 +7,12 @@ import { isoToUnixSeconds, physicalFields, } from './schema.js';
|
|
|
7
7
|
* its value from the node and the document as populated so far (so a derived
|
|
8
8
|
* field may read fields declared before it). The physical field names a field
|
|
9
9
|
* fans out to come from {@link physicalFields}, the single source shared with
|
|
10
|
-
* the engine collection
|
|
10
|
+
* the engine collection definition and the query compiler.
|
|
11
11
|
*/
|
|
12
12
|
export function projectDocument(node, searchType) {
|
|
13
13
|
const id = node['@id'];
|
|
14
14
|
if (typeof id !== 'string') {
|
|
15
|
-
throw new Error(`Cannot project a ${searchType.
|
|
15
|
+
throw new Error(`Cannot project a ${searchType.class} node without an @id: every search document needs a stable key, and an empty one would collide with other keyless nodes.`);
|
|
16
16
|
}
|
|
17
17
|
const document = { id };
|
|
18
18
|
for (const field of searchType.fields) {
|
|
@@ -22,9 +22,12 @@ export function projectDocument(node, searchType) {
|
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Frame `quads` for every root type in the schema and project each node with its
|
|
25
|
-
* type’s declaration — the multi-shape pipeline.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* type’s declaration — the multi-shape pipeline. Yields each document tagged
|
|
26
|
+
* with its {@link SearchType} ({@link TypedSearchDocument}), so a downstream
|
|
27
|
+
* multi-collection writer can route it to that type’s collection; a
|
|
28
|
+
* single-collection consumer just reads `.document`. Streams one document at a
|
|
29
|
+
* time so memory stays flat. The IR maps to a declaration by type, so adding a
|
|
30
|
+
* shape is adding a `SearchType` to the schema (no engine change).
|
|
28
31
|
*
|
|
29
32
|
* Consumes `quads` once (a single scan builds the shared subject index that
|
|
30
33
|
* every type frames off), so it accepts any `Iterable` – a materialized array or
|
|
@@ -33,10 +36,10 @@ export function projectDocument(node, searchType) {
|
|
|
33
36
|
*/
|
|
34
37
|
export async function* projectGraph(quads, schema) {
|
|
35
38
|
const types = [...schema.values()];
|
|
36
|
-
const index = buildSubjectIndex(quads, types.map((searchType) => searchType.
|
|
39
|
+
const index = buildSubjectIndex(quads, types.map((searchType) => searchType.class));
|
|
37
40
|
for (const searchType of types) {
|
|
38
|
-
for await (const node of frameSubjects(index, searchType.
|
|
39
|
-
yield projectDocument(node, searchType);
|
|
41
|
+
for await (const node of frameSubjects(index, searchType.class)) {
|
|
42
|
+
yield { searchType, document: projectDocument(node, searchType) };
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { SearchDocument } from './project.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* The engine-neutral kind of a queryable field. It drives every downstream
|
|
5
5
|
* behavior: which physical fields the projection emits, the engine
|
|
6
|
-
* collection-
|
|
6
|
+
* collection-definition type, the `where`/facet/sort semantics, and the GraphQL
|
|
7
7
|
* output/input type. The Typesense-vocabulary types (`string`, `int32`, …) are
|
|
8
8
|
* *derived* from this by the engine adapter, never declared here.
|
|
9
9
|
*/
|
|
@@ -20,7 +20,7 @@ export type FilterOperator = 'in' | 'range' | 'is';
|
|
|
20
20
|
export declare function filterOperatorFor(kind: FieldKind): FilterOperator | undefined;
|
|
21
21
|
/**
|
|
22
22
|
* One queryable field — the single declarative source that drives all four
|
|
23
|
-
* consumers (projection, engine collection
|
|
23
|
+
* consumers (projection, engine collection definition, query semantics, and the
|
|
24
24
|
* GraphQL surface).
|
|
25
25
|
*
|
|
26
26
|
* A **discriminated union by `kind`**: each kind declares exactly the
|
|
@@ -38,7 +38,7 @@ export declare function filterOperatorFor(kind: FieldKind): FilterOperator | und
|
|
|
38
38
|
*
|
|
39
39
|
* The physical field names a declaration fans out to (per-locale search/sort
|
|
40
40
|
* keys) follow one convention, owned by
|
|
41
|
-
* {@link physicalFields} so projection, collection-
|
|
41
|
+
* {@link physicalFields} so projection, collection-definition and query compiler
|
|
42
42
|
* cannot disagree.
|
|
43
43
|
*
|
|
44
44
|
* SHACL is one possible *source*, not a dependency: a generator can emit a
|
|
@@ -193,19 +193,22 @@ export interface FacetRange {
|
|
|
193
193
|
}
|
|
194
194
|
/**
|
|
195
195
|
* One root type’s complete search declaration: its logical API `name`, the
|
|
196
|
-
* `
|
|
197
|
-
* (including {@link SearchField.derive derived} ones). A SHACL
|
|
198
|
-
* emit one per NodeShape (`name`←`sh:name`/local name,
|
|
199
|
-
* `fields`←its property shapes), but that is a source,
|
|
196
|
+
* `class` IRI its documents are instances of (the RDF class), and the queryable
|
|
197
|
+
* `fields` (including {@link SearchField.derive derived} ones). A SHACL
|
|
198
|
+
* generator can emit one per NodeShape (`name`←`sh:name`/local name,
|
|
199
|
+
* `class`←`sh:targetClass`, `fields`←its property shapes), but that is a source,
|
|
200
|
+
* not a requirement.
|
|
200
201
|
*/
|
|
201
202
|
export interface SearchType {
|
|
202
203
|
/** Logical API name (PascalCase, e.g. `Dataset`) — names the type in the API
|
|
203
204
|
* surfaces (GraphQL type names, a REST path), the way each field’s
|
|
204
205
|
* {@link SearchField.name} names that field. Deliberately declared rather
|
|
205
|
-
* than derived from the `
|
|
206
|
+
* than derived from the `class` IRI, so re-modelling the vocabulary cannot
|
|
206
207
|
* silently rename the public contract. */
|
|
207
208
|
readonly name: string;
|
|
208
|
-
|
|
209
|
+
/** The RDF class IRI its documents are instances of (`sh:targetClass`); the
|
|
210
|
+
* key a {@link SearchSchema} maps this type under. */
|
|
211
|
+
readonly class: string;
|
|
209
212
|
readonly fields: readonly SearchField[];
|
|
210
213
|
}
|
|
211
214
|
/**
|
|
@@ -219,7 +222,7 @@ export interface SearchType {
|
|
|
219
222
|
export declare function defineSearchType<const Type extends SearchType>(searchType: Type): Type;
|
|
220
223
|
/**
|
|
221
224
|
* The complete search declaration of a deployment: every root {@link SearchType},
|
|
222
|
-
* keyed by its `
|
|
225
|
+
* keyed by its `class` IRI. Build one with {@link searchSchema}, which captures
|
|
223
226
|
* the declared types as a literal tuple (`Types`), so schema-bound consumers
|
|
224
227
|
* (the engine port) can type their per-type behaviour off it. A plain
|
|
225
228
|
* `: SearchSchema` annotation widens gracefully to `SearchType`.
|
|
@@ -233,11 +236,11 @@ export interface SearchSchema<Types extends readonly SearchType[] = readonly Sea
|
|
|
233
236
|
readonly [validSearchSchema]: true;
|
|
234
237
|
}
|
|
235
238
|
/**
|
|
236
|
-
* Build a {@link SearchSchema} from root-type declarations, keyed by `
|
|
239
|
+
* Build a {@link SearchSchema} from root-type declarations, keyed by `class`.
|
|
237
240
|
*
|
|
238
241
|
* Every declaration is validated ({@link assertValidSearchType}) — the
|
|
239
242
|
* declaration-time counterpart of the port’s `assertValidQuery` — and the
|
|
240
|
-
* schema-wide invariants are enforced: no two types may share a `
|
|
243
|
+
* schema-wide invariants are enforced: no two types may share a `class` IRI
|
|
241
244
|
* (they would silently overwrite each other in the map) or a `name` (names
|
|
242
245
|
* key the API surfaces). Throws on the first invalid declaration, so a bad
|
|
243
246
|
* schema fails at startup, not per document at index time or per query.
|
|
@@ -301,7 +304,7 @@ export declare function assertValidSearchType(searchType: SearchType): void;
|
|
|
301
304
|
/**
|
|
302
305
|
* The physical engine fields one {@link SearchField} fans out into, grouped by
|
|
303
306
|
* the role each plays. The single source of truth for the naming convention, so
|
|
304
|
-
* the projection (writes them), the collection
|
|
307
|
+
* the projection (writes them), the collection definition (declares them) and the
|
|
305
308
|
* query compiler (reads them) cannot disagree.
|
|
306
309
|
*/
|
|
307
310
|
export interface PhysicalFields {
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,SAAS,GACT,SAAS,GACT,QAAQ,GACR,SAAS,GACT,MAAM,GACN,WAAW,CAAC;AAEhB;oEACoE;AACpE,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;AAcnD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,cAAc,GAAG,SAAS,CAE7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,YAAY,GACZ,cAAc,GACd,YAAY,GACZ,YAAY,CAAC;AAEjB,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B;wCACoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;+EAC2E;IAC3E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB;IACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB;;yCAEqC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,yBAAyB;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,iCAAiC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC;CAC3E;AAED;kEACkE;AAClE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACnD;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAU,SAAQ,eAAe,EAAE,UAAU;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;CAC9B;AAED;gCACgC;AAChC,MAAM,WAAW,YAAa,SAAQ,eAAe,EAAE,UAAU;IAC/D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,wEAAwE;IACxE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;CAC9B;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAe,SAAQ,eAAe,EAAE,UAAU;IACjE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;0DAEsD;IACtD,QAAQ,CAAC,GAAG,CAAC,EAAE;QACb;;;;;qCAK6B;QAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B;;;;6EAIqE;QACrE,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;KACtD,CAAC;CACH;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CAC9C;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAa,SAAQ,eAAe,EAAE,cAAc;IACnE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;CAC7B;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB;;;;+CAI2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;2DACuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,IAAI,SAAS,UAAU,EAC5D,UAAU,EAAE,IAAI,GACf,IAAI,CAEN;AAED;;;;;;GAMG;AACH;;;uCAGuC;AACvC,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,MAAM,CAAC;AAEtD,MAAM,WAAW,YAAY,CAC3B,KAAK,SAAS,SAAS,UAAU,EAAE,GAAG,SAAS,UAAU,EAAE,CAC3D,SAAQ,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,KAAK,SAAS,SAAS,UAAU,EAAE,EACpE,GAAG,KAAK,EAAE,KAAK,GACd,YAAY,CAAC,KAAK,CAAC,CAuBrB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAQ1E;AAsCD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EACX,sBAAsB,GACtB,aAAa,GACb,iBAAiB,GACjB,uBAAuB,GACvB,qBAAqB,GACrB,0BAA0B,GAC1B,wBAAwB,GACxB,uBAAuB,GACvB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,CAAC;CAC1B;AAQD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,GACrB,SAAS,eAAe,EAAE,CAkE5B;AAWD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,UAAU,GACrB,IAAI,CAUN;AAED;+EAC+E;AAC/E,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAQlE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;sEACkE;IAClE,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;4EACwE;IACxE,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,UAAU,GACrB,SAAS,CAAC,WAAW,GAAG;IACzB,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD,CAAC,EAAE,CAOH;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAC7B,UAAU,EAAE,UAAU,GACrB,SAAS,WAAW,EAAE,CAExB;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,UAAU,GACrB,SAAS,WAAW,EAAE,CAExB;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,WAAW,EAAE,CAE7E;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,WAAW,EAAE,CAE3E;AAED,qFAAqF;AACrF,wBAAgB,eAAe,CAC7B,UAAU,EAAE,UAAU,GACrB,SAAS,cAAc,EAAE,CAE3B;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,CACxB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,GACX,WAAW,GAAG,SAAS,CAEzB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,WAAW,GACjB,KAAK,IAAI,YAAY,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CAEzE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGhE;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc,CAoBjE"}
|
package/dist/schema.js
CHANGED
|
@@ -28,11 +28,11 @@ export function defineSearchType(searchType) {
|
|
|
28
28
|
return searchType;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
* Build a {@link SearchSchema} from root-type declarations, keyed by `
|
|
31
|
+
* Build a {@link SearchSchema} from root-type declarations, keyed by `class`.
|
|
32
32
|
*
|
|
33
33
|
* Every declaration is validated ({@link assertValidSearchType}) — the
|
|
34
34
|
* declaration-time counterpart of the port’s `assertValidQuery` — and the
|
|
35
|
-
* schema-wide invariants are enforced: no two types may share a `
|
|
35
|
+
* schema-wide invariants are enforced: no two types may share a `class` IRI
|
|
36
36
|
* (they would silently overwrite each other in the map) or a `name` (names
|
|
37
37
|
* key the API surfaces). Throws on the first invalid declaration, so a bad
|
|
38
38
|
* schema fails at startup, not per document at index time or per query.
|
|
@@ -42,18 +42,18 @@ export function searchSchema(...types) {
|
|
|
42
42
|
const names = new Set();
|
|
43
43
|
for (const searchType of types) {
|
|
44
44
|
assertValidSearchType(searchType);
|
|
45
|
-
if (typeIris.has(searchType.
|
|
46
|
-
throw new Error(`Duplicate search type IRI “${searchType.
|
|
45
|
+
if (typeIris.has(searchType.class)) {
|
|
46
|
+
throw new Error(`Duplicate search type IRI “${searchType.class}”; each SearchType must declare a distinct class.`);
|
|
47
47
|
}
|
|
48
48
|
if (names.has(searchType.name)) {
|
|
49
49
|
throw new Error(`Duplicate search type name “${searchType.name}”; each SearchType must declare a distinct name.`);
|
|
50
50
|
}
|
|
51
|
-
typeIris.add(searchType.
|
|
51
|
+
typeIris.add(searchType.class);
|
|
52
52
|
names.add(searchType.name);
|
|
53
53
|
}
|
|
54
54
|
assertResolvableLabelSources(types);
|
|
55
55
|
// The one blessed cast: only this validated constructor mints the brand.
|
|
56
|
-
return new Map(types.map((searchType) => [searchType.
|
|
56
|
+
return new Map(types.map((searchType) => [searchType.class, searchType]));
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
59
|
* The text field a label source serves labels from – the ‘label’ convention
|
|
@@ -193,7 +193,7 @@ export function validateSearchType(searchType) {
|
|
|
193
193
|
* declaration object must be in the schema, not a lookalike.
|
|
194
194
|
*/
|
|
195
195
|
export function assertTypeInSchema(schema, searchType) {
|
|
196
|
-
if (schema.get(searchType.
|
|
196
|
+
if (schema.get(searchType.class) !== searchType) {
|
|
197
197
|
throw new Error(`Search type “${searchType.name}” is not in this engine’s schema; it serves ${[
|
|
198
198
|
...schema.values(),
|
|
199
199
|
]
|
package/dist/testing.js
CHANGED
|
@@ -32,13 +32,13 @@ export function describeSearchEngineContract(name, engine) {
|
|
|
32
32
|
expect(types().length).toBeGreaterThan(0);
|
|
33
33
|
for (const searchType of types()) {
|
|
34
34
|
expect(typeof searchType.name).toBe('string');
|
|
35
|
-
expect(typeof searchType.
|
|
35
|
+
expect(typeof searchType.class).toBe('string');
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
it('rejects a search type outside its schema', async () => {
|
|
39
39
|
const foreign = {
|
|
40
40
|
name: 'NotInSchema',
|
|
41
|
-
|
|
41
|
+
class: 'urn:test:not-in-schema',
|
|
42
42
|
fields: [],
|
|
43
43
|
};
|
|
44
44
|
await expect(engine().search(foreign, browse(foreign))).rejects.toThrow(/not in this engine/);
|
|
@@ -78,7 +78,7 @@ export function describeSearchEngineContract(name, engine) {
|
|
|
78
78
|
it('rejects a searchFacets batch for a type outside its schema', async () => {
|
|
79
79
|
const foreign = {
|
|
80
80
|
name: 'NotInSchema',
|
|
81
|
-
|
|
81
|
+
class: 'urn:test:not-in-schema',
|
|
82
82
|
fields: [],
|
|
83
83
|
};
|
|
84
84
|
await expect(engine().searchFacets(foreign, [browse(foreign)])).rejects.toThrow(/not in this engine/);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/search",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Engine- and domain-agnostic core for RDF-backed search: a unified declarative field model (SearchField/SearchType/SearchSchema), a neutral query IR, the SearchEngine port with logical result types, and a streaming CONSTRUCT-to-document projection. Bakes in no engine, protocol, or domain.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "git+https://github.com/ldelements/lde.git",
|