@lde/search 0.8.0 → 0.8.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/dist/frame-by-type.d.ts +13 -8
- package/dist/frame-by-type.d.ts.map +1 -1
- package/dist/frame-by-type.js +16 -13
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/project.d.ts +15 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +29 -2
- package/package.json +1 -1
package/dist/frame-by-type.d.ts
CHANGED
|
@@ -26,15 +26,20 @@ export interface SubjectIndex {
|
|
|
26
26
|
*/
|
|
27
27
|
export declare function buildSubjectIndex(quads: Iterable<Quad>, rootTypes: Iterable<string>): SubjectIndex;
|
|
28
28
|
/**
|
|
29
|
-
* Frame
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
29
|
+
* Frame each of the given `roots` from a prebuilt {@link SubjectIndex} into one
|
|
30
|
+
* JSON-LD node. Each root subject’s own triples plus the one-hop nodes it
|
|
31
|
+
* references (e.g. nested publisher/distribution resources) are framed one
|
|
32
|
+
* subject at a time, so beyond the shared subject index only a single subgraph
|
|
33
|
+
* is held (whole-graph `jsonld.frame()` is ~O(N²)). The frame carries no
|
|
34
|
+
* `@context`, so framed keys are full predicate IRIs.
|
|
35
|
+
*
|
|
36
|
+
* The roots are supplied explicitly rather than discovered from `rdf:type`: a
|
|
37
|
+
* caller with the roots already in hand ({@link projectRoots}, from the pipeline
|
|
38
|
+
* selector) passes them directly; a whole-graph caller ({@link frameByType},
|
|
39
|
+
* {@link projectGraph}) passes {@link SubjectIndex.rootsByType}. A root absent
|
|
40
|
+
* from the index simply frames nothing.
|
|
36
41
|
*/
|
|
37
|
-
export declare function frameSubjects(index: SubjectIndex,
|
|
42
|
+
export declare function frameSubjects(index: SubjectIndex, roots: readonly string[]): AsyncIterable<FramedNode>;
|
|
38
43
|
/**
|
|
39
44
|
* Frame CONSTRUCT quads into one JSON-LD node per subject of `rootType`, for a
|
|
40
45
|
* single root type. Consumes `quads` once (see {@link buildSubjectIndex}), so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-by-type.d.ts","sourceRoot":"","sources":["../src/frame-by-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMzC,4EAA4E;AAC5E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAIjD;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;IACzD,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;CAC9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EACrB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC1B,YAAY,CA8Bd;AAED
|
|
1
|
+
{"version":3,"file":"frame-by-type.d.ts","sourceRoot":"","sources":["../src/frame-by-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMzC,4EAA4E;AAC5E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAIjD;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;IACzD,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;CAC9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EACrB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC1B,YAAY,CA8Bd;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAuB,aAAa,CAClC,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,aAAa,CAAC,UAAU,CAAC,CA4B3B;AAED;;;;;;GAMG;AACH,wBAAuB,WAAW,CAChC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EACrB,QAAQ,EAAE,MAAM,GACf,aAAa,CAAC,UAAU,CAAC,CAG3B"}
|
package/dist/frame-by-type.js
CHANGED
|
@@ -44,19 +44,21 @@ export function buildSubjectIndex(quads, rootTypes) {
|
|
|
44
44
|
return { bySubject, rootsByType };
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
* Frame
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
47
|
+
* Frame each of the given `roots` from a prebuilt {@link SubjectIndex} into one
|
|
48
|
+
* JSON-LD node. Each root subject’s own triples plus the one-hop nodes it
|
|
49
|
+
* references (e.g. nested publisher/distribution resources) are framed one
|
|
50
|
+
* subject at a time, so beyond the shared subject index only a single subgraph
|
|
51
|
+
* is held (whole-graph `jsonld.frame()` is ~O(N²)). The frame carries no
|
|
52
|
+
* `@context`, so framed keys are full predicate IRIs.
|
|
53
|
+
*
|
|
54
|
+
* The roots are supplied explicitly rather than discovered from `rdf:type`: a
|
|
55
|
+
* caller with the roots already in hand ({@link projectRoots}, from the pipeline
|
|
56
|
+
* selector) passes them directly; a whole-graph caller ({@link frameByType},
|
|
57
|
+
* {@link projectGraph}) passes {@link SubjectIndex.rootsByType}. A root absent
|
|
58
|
+
* from the index simply frames nothing.
|
|
54
59
|
*/
|
|
55
|
-
export async function* frameSubjects(index,
|
|
60
|
+
export async function* frameSubjects(index, roots) {
|
|
56
61
|
const { bySubject } = index;
|
|
57
|
-
// A type the index was not built for has no roots, so it frames nothing; the
|
|
58
|
-
// `projectType`/`projectGraph` callers only pass types they registered.
|
|
59
|
-
const roots = index.rootsByType.get(rootType) ?? [];
|
|
60
62
|
for (const rootIri of roots) {
|
|
61
63
|
const owned = bySubject.get(rootIri) ?? [];
|
|
62
64
|
const referenced = owned
|
|
@@ -68,7 +70,7 @@ export async function* frameSubjects(index, rootType) {
|
|
|
68
70
|
// Frame for THIS specific root subject by `@id`, not just by root type. A
|
|
69
71
|
// one-hop reference can itself be of `rootType` (e.g. a terminology source
|
|
70
72
|
// that is also a separately registered dataset), so framing by type alone
|
|
71
|
-
// returns several root nodes and `[0]` could be the referenced one
|
|
73
|
+
// returns several root nodes and `[0]` could be the referenced one – which
|
|
72
74
|
// would emit it twice and drop this subject entirely.
|
|
73
75
|
const framed = await jsonld.frame(expanded, { '@id': rootIri }, FRAME_OPTIONS);
|
|
74
76
|
const node = framed['@graph']?.[0];
|
|
@@ -85,5 +87,6 @@ export async function* frameSubjects(index, rootType) {
|
|
|
85
87
|
* one index across types rather than re-scanning per type.
|
|
86
88
|
*/
|
|
87
89
|
export async function* frameByType(quads, rootType) {
|
|
88
|
-
|
|
90
|
+
const index = buildSubjectIndex(quads, [rootType]);
|
|
91
|
+
yield* frameSubjects(index, index.rootsByType.get(rootType) ?? []);
|
|
89
92
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { projectGraph, irisOf, literalsOf, firstLiteralOf } from './project.js';
|
|
1
|
+
export { projectGraph, projectRoots, irisOf, literalsOf, firstLiteralOf, } from './project.js';
|
|
2
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';
|
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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,UAAU,EACV,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,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/index.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
// Projection: RDF CONSTRUCT quads → flat search documents, driven by the
|
|
7
7
|
// unified SearchField/SearchType model. The IR readers (irisOf, …) are here
|
|
8
8
|
// because `derive` functions are written against them.
|
|
9
|
-
export { projectGraph, irisOf, literalsOf, firstLiteralOf } from './project.js';
|
|
9
|
+
export { projectGraph, projectRoots, irisOf, literalsOf, firstLiteralOf, } from './project.js';
|
|
10
10
|
// Unified field model: one declaration drives projection, engine collection
|
|
11
|
-
// schema, query semantics and the GraphQL surface
|
|
11
|
+
// schema, query semantics and the GraphQL surface – a discriminated union by
|
|
12
12
|
// `kind`, validated again at runtime when the schema is built.
|
|
13
13
|
export { defineSearchType, searchSchema, validateSearchType, assertValidSearchType, } from './schema.js';
|
package/dist/project.d.ts
CHANGED
|
@@ -39,6 +39,21 @@ export declare function projectDocument(node: FramedNode, searchType: SearchType
|
|
|
39
39
|
* with no intermediate copy at the projection peak.
|
|
40
40
|
*/
|
|
41
41
|
export declare function projectGraph(quads: Iterable<Quad>, schema: SearchSchema): AsyncIterable<TypedSearchDocument>;
|
|
42
|
+
/**
|
|
43
|
+
* Project a single type over a known set of `roots` – the per-type, roots-given
|
|
44
|
+
* projection. Unlike {@link projectGraph}, the roots are supplied by the caller
|
|
45
|
+
* (the pipeline selector) rather than discovered from `rdf:type`, so `quads`
|
|
46
|
+
* need carry no type triples and the projection frames each distinct subject
|
|
47
|
+
* once. {@link assertTypeInSchema} guards that `searchType` belongs to `schema`
|
|
48
|
+
* – the port’s own membership check – so no schema is ever forged to scope a
|
|
49
|
+
* projection to one type. Yields a bare {@link SearchDocument}: tagging a
|
|
50
|
+
* document with its type is a routing concern, owned by the pipeline glue, not
|
|
51
|
+
* the projection.
|
|
52
|
+
*
|
|
53
|
+
* Consumes `quads` once, so it accepts any `Iterable` – a batch’s materialized
|
|
54
|
+
* array or a chained generator merging several readers.
|
|
55
|
+
*/
|
|
56
|
+
export declare function projectRoots(quads: Iterable<Quad>, roots: readonly string[], schema: SearchSchema, searchType: SearchType): AsyncIterable<SearchDocument>;
|
|
42
57
|
export declare function literalsOf(node: FramedNode, path: string): string[];
|
|
43
58
|
export declare function firstLiteralOf(node: FramedNode, path: string): string | undefined;
|
|
44
59
|
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,
|
|
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,EAQL,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,CAYpC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAuB,YAAY,CACjC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EACrB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,UAAU,GACrB,aAAa,CAAC,cAAc,CAAC,CAW/B;AAqJD,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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fold } from '@lde/text-normalization';
|
|
2
2
|
import { buildSubjectIndex, frameSubjects, } from './frame-by-type.js';
|
|
3
|
-
import { displayFieldName, isoToUnixSeconds, physicalFields, } from './schema.js';
|
|
3
|
+
import { assertTypeInSchema, displayFieldName, isoToUnixSeconds, physicalFields, } from './schema.js';
|
|
4
4
|
/**
|
|
5
5
|
* Project one framed JSON-LD node into a flat search document: apply each field
|
|
6
6
|
* of the type in declaration order. A field with a `derive` function computes
|
|
@@ -38,11 +38,38 @@ export async function* projectGraph(quads, schema) {
|
|
|
38
38
|
const types = [...schema.values()];
|
|
39
39
|
const index = buildSubjectIndex(quads, types.map((searchType) => searchType.class));
|
|
40
40
|
for (const searchType of types) {
|
|
41
|
-
|
|
41
|
+
const roots = index.rootsByType.get(searchType.class) ?? [];
|
|
42
|
+
for await (const node of frameSubjects(index, roots)) {
|
|
42
43
|
yield { searchType, document: projectDocument(node, searchType) };
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Project a single type over a known set of `roots` – the per-type, roots-given
|
|
49
|
+
* projection. Unlike {@link projectGraph}, the roots are supplied by the caller
|
|
50
|
+
* (the pipeline selector) rather than discovered from `rdf:type`, so `quads`
|
|
51
|
+
* need carry no type triples and the projection frames each distinct subject
|
|
52
|
+
* once. {@link assertTypeInSchema} guards that `searchType` belongs to `schema`
|
|
53
|
+
* – the port’s own membership check – so no schema is ever forged to scope a
|
|
54
|
+
* projection to one type. Yields a bare {@link SearchDocument}: tagging a
|
|
55
|
+
* document with its type is a routing concern, owned by the pipeline glue, not
|
|
56
|
+
* the projection.
|
|
57
|
+
*
|
|
58
|
+
* Consumes `quads` once, so it accepts any `Iterable` – a batch’s materialized
|
|
59
|
+
* array or a chained generator merging several readers.
|
|
60
|
+
*/
|
|
61
|
+
export async function* projectRoots(quads, roots, schema, searchType) {
|
|
62
|
+
assertTypeInSchema(schema, searchType);
|
|
63
|
+
const index = buildSubjectIndex(quads, []);
|
|
64
|
+
// Distinct roots only. A selector may return an IRI more than once – a
|
|
65
|
+
// non-`DISTINCT` `SELECT` over a one-to-many join yields the same subject per
|
|
66
|
+
// matched row – and a repeated root would otherwise frame and emit a
|
|
67
|
+
// duplicate document under the same `id`. (`projectGraph`’s roots come from
|
|
68
|
+
// `rootsByType`, which is inherently unique, so it never needs this.)
|
|
69
|
+
for await (const node of frameSubjects(index, [...new Set(roots)])) {
|
|
70
|
+
yield projectDocument(node, searchType);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
46
73
|
function applyField(document, node, field) {
|
|
47
74
|
if (field.derive !== undefined) {
|
|
48
75
|
const value = field.derive(node, document);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/search",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
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",
|