@lde/search 0.4.1 → 0.5.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 CHANGED
@@ -150,8 +150,14 @@ const DATASET = defineSearchType({
150
150
  ],
151
151
  });
152
152
 
153
- for await (const document of projectGraph(quads, searchSchema(DATASET))) {
154
- // one flat search document per matching subject, streamed
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
 
@@ -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';
@@ -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;AAKnD,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"}
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,6 +5,16 @@ 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
@@ -16,16 +26,19 @@ export type SearchDocument = {
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. Streams one document at a time
20
- * so memory stays flat. The IR maps to a declaration by type, so adding a shape
21
- * is adding a `SearchType` to the schema (no engine change).
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<SearchDocument>;
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[];
@@ -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;;;;;;;;;;GAUG;AACH,wBAAuB,YAAY,CACjC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EACrB,MAAM,EAAE,YAAY,GACnB,aAAa,CAAC,cAAc,CAAC,CAW/B;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"}
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
@@ -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. Streams one document at a time
26
- * so memory stays flat. The IR maps to a declaration by type, so adding a shape
27
- * is adding a `SearchType` to the schema (no engine change).
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
@@ -36,7 +39,7 @@ export async function* projectGraph(quads, schema) {
36
39
  const index = buildSubjectIndex(quads, types.map((searchType) => searchType.type));
37
40
  for (const searchType of types) {
38
41
  for await (const node of frameSubjects(index, searchType.type)) {
39
- yield projectDocument(node, searchType);
42
+ yield { searchType, document: projectDocument(node, searchType) };
40
43
  }
41
44
  }
42
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/search",
3
- "version": "0.4.1",
3
+ "version": "0.5.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",