@jestek-dev/scripture-engine 0.7.0 → 0.14.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/LICENSE +21 -0
- package/README.md +35 -0
- package/dist/config/engineVersion.d.ts +1 -1
- package/dist/config/engineVersion.js +47 -1
- package/dist/corpus/repository.d.ts +189 -2
- package/dist/corpus/repository.js +332 -1
- package/dist/createEngine.d.ts +76 -1
- package/dist/createEngine.js +716 -52
- package/dist/index.d.ts +20 -14
- package/dist/index.js +15 -13
- package/dist/intents/concept.d.ts +115 -2
- package/dist/intents/concept.js +323 -6
- package/dist/intents/lexical.d.ts +42 -3
- package/dist/intents/lexical.js +111 -11
- package/dist/intents/spelling.d.ts +93 -0
- package/dist/intents/spelling.js +124 -0
- package/dist/internal.d.ts +31 -0
- package/dist/internal.js +31 -0
- package/dist/ranking/budgets.d.ts +12 -0
- package/dist/ranking/budgets.js +39 -0
- package/dist/ranking/rank.js +20 -3
- package/dist/reasons/display.d.ts +86 -0
- package/dist/reasons/display.js +105 -0
- package/dist/reasons/types.d.ts +1 -1
- package/dist/reference/reference.d.ts +57 -0
- package/dist/reference/reference.js +210 -48
- package/dist/tokenizer/index.d.ts +35 -0
- package/dist/tokenizer/index.js +37 -1
- package/dist/types.d.ts +104 -0
- package/package.json +16 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jesse Freeman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @jestek-dev/scripture-engine
|
|
2
|
+
|
|
3
|
+
Pure, deterministic Scripture retrieval and ranking core. Zero I/O, zero
|
|
4
|
+
runtime AI, zero dependencies. Every result carries typed reasons and the
|
|
5
|
+
identities that make it reproducible:
|
|
6
|
+
`(engineVersion, corpusFingerprint, layerFingerprint, query)` yields identical
|
|
7
|
+
ordering on every platform.
|
|
8
|
+
|
|
9
|
+
The engine reads a prebuilt SQLite artifact (`content.db`) through the one
|
|
10
|
+
seam it knows, `ContentQueryPort` — supply it with any SQLite binding
|
|
11
|
+
(`node:sqlite`, OP-SQLite, expo-sqlite):
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createEngine } from '@jestek-dev/scripture-engine';
|
|
15
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
16
|
+
|
|
17
|
+
const db = new DatabaseSync('content.db', { readOnly: true });
|
|
18
|
+
const engine = await createEngine({
|
|
19
|
+
async execute(sql, params = []) { return { rows: db.prepare(sql).all(...params) }; },
|
|
20
|
+
async close() { db.close(); },
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const result = await engine.research('hearing and doing');
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The artifact ships separately as a
|
|
27
|
+
[GitHub Release asset](https://github.com/jestek-dev/scripture-search-engine/releases),
|
|
28
|
+
alongside a reviewed descriptor. Verify `content.db` against the descriptor's
|
|
29
|
+
`databaseSha256` before opening it.
|
|
30
|
+
|
|
31
|
+
Full documentation, architecture, data provenance and the admission gauntlet:
|
|
32
|
+
[jestek-dev/scripture-search-engine](https://github.com/jestek-dev/scripture-search-engine).
|
|
33
|
+
|
|
34
|
+
MIT — the code, not the corpora it is built from; those carry their own terms,
|
|
35
|
+
recorded per source in the repository's `docs/ATTRIBUTIONS.md`.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* tie-breaks — MUST bump this in the same commit. Gate G2 fails a PR whose
|
|
9
9
|
* ordering changed without a bump, so this is enforced, not merely asked for.
|
|
10
10
|
*/
|
|
11
|
-
export declare const ENGINE_VERSION = "0.
|
|
11
|
+
export declare const ENGINE_VERSION = "0.14.0";
|
|
12
12
|
/**
|
|
13
13
|
* Bumped independently of ENGINE_VERSION when the tokenizer changes, because
|
|
14
14
|
* a tokenizer change invalidates precomputed corpus term profiles: the
|
|
@@ -8,7 +8,53 @@
|
|
|
8
8
|
* tie-breaks — MUST bump this in the same commit. Gate G2 fails a PR whose
|
|
9
9
|
* ordering changed without a bump, so this is enforced, not merely asked for.
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
// 0.9.0: query-coverage scaling, IDF-thin bare-concept cue demotion, and
|
|
12
|
+
// one-significant-word phrase fallback suppression. These alter ordering and reasons.
|
|
13
|
+
// 0.10.0: ranking fixes, staged on one branch and landed as one squash. Stage 1
|
|
14
|
+
// (sole-evidence floor): a result whose only evidence is translation_variant is
|
|
15
|
+
// capped at 6 points — below any honest text match — so a bag-of-stems hint can
|
|
16
|
+
// accompany but never hold #1 alone. Later 0.10.0 stages ride this same bump.
|
|
17
|
+
// 0.11.0 (QR-4): reference-grammar extension. Space-separated chapter/verse
|
|
18
|
+
// resolves ("John 3 16"); un-resolving books earn a cited did-you-mean
|
|
19
|
+
// suggestion (suggestion only, never auto-resolve); bare-number dead ends fall
|
|
20
|
+
// through to discovery; the verse-1 range-label defect is fixed ("John 3:1-5"
|
|
21
|
+
// no longer labeled "John 3"). Kind flips and label changes are
|
|
22
|
+
// results-visible, so this bumps in the same commit as the behavior.
|
|
23
|
+
// 0.12.0 (QR-5): deterministic cited spelling correction, with artifact
|
|
24
|
+
// schema v7 (spelling_terms/spelling_deletes precomputed by the pipeline;
|
|
25
|
+
// curated_aliases shipped empty for QR-6). research() discovery substitutes
|
|
26
|
+
// the unique in-policy correction for tokens in NO vocabulary — bounded
|
|
27
|
+
// integer Damerau under the ONE edit-policy table — and every substitution is
|
|
28
|
+
// cited (token chips + the additive `corrections` list). Substituted tokens
|
|
29
|
+
// change which verses surface and how they are explained, so this bumps in
|
|
30
|
+
// the same commit as the behavior and the schema.
|
|
31
|
+
// 0.13.0 (QR-6): curated phrase/hymn aliases (no schema bump — the
|
|
32
|
+
// curated_aliases table shipped EMPTY in v7 and the engine probes
|
|
33
|
+
// presence-and-rows). research() discovery matches the TYPED query's
|
|
34
|
+
// normalizedPhrase (stopwords kept) against curated_aliases by whole-string
|
|
35
|
+
// EQUALITY — never containment — and surfaces the target concept's own
|
|
36
|
+
// curated anchors (or the named verse range) under the existing
|
|
37
|
+
// concept_anchor family with a full attribution chip
|
|
38
|
+
// (`Hymn: "<title>" → Theme: <label>`). New evidence on alias-keyed queries
|
|
39
|
+
// is results-visible, so this bumps in the same commit as the behavior;
|
|
40
|
+
// non-alias queries are untouched by construction (equality matching).
|
|
41
|
+
// Rollback: rebuild the artifact without alias rows (the probe reverts
|
|
42
|
+
// behavior); an engine revert is a new version.
|
|
43
|
+
// 0.14.0 (CO-3 PR 2): passage-level grouping over the schema-v8 pericope
|
|
44
|
+
// tiling. discover() merges ungoverned results that are consecutive in rank,
|
|
45
|
+
// verseId-consecutive, and members of ONE derived pericope into a single
|
|
46
|
+
// passage row; the existing curated-anchor collapse is unchanged in its
|
|
47
|
+
// merge rule but both mechanisms now EXPLAIN the merge — merged rows carry
|
|
48
|
+
// additive `verses[]` (per-member evidence, uncollapsed) and a typed
|
|
49
|
+
// `grouping` naming the section span and its source (anchor sources for
|
|
50
|
+
// anchor runs, 'openbible-sections' + the summed boundary vote for pericope
|
|
51
|
+
// runs; grouping is not a Reason and contributes zero points). Authority
|
|
52
|
+
// order is fixed: an anchor-claimed verse never joins a pericope run.
|
|
53
|
+
// Merged pericope rows change which rows the default page shows, so this
|
|
54
|
+
// bumps in the same commit as the behavior. Rollback: rebuild the artifact
|
|
55
|
+
// without pericope rows (the presence-and-rows probe reverts the pericope
|
|
56
|
+
// path); an engine revert is a new version.
|
|
57
|
+
export const ENGINE_VERSION = '0.14.0';
|
|
12
58
|
/**
|
|
13
59
|
* Bumped independently of ENGINE_VERSION when the tokenizer changes, because
|
|
14
60
|
* a tokenizer change invalidates precomputed corpus term profiles: the
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* lives in `ranking/`, so the ranker stays pure and unit-testable without a
|
|
7
7
|
* database.
|
|
8
8
|
*/
|
|
9
|
-
import { type ReferenceResolver, type ResolvedBook, type ResolvedReference } from '../reference/reference.js';
|
|
9
|
+
import { type BookAliasEntry, type ReferenceResolver, type ResolvedBook, type ResolvedReference } from '../reference/reference.js';
|
|
10
10
|
import type { ContentQueryPort, ScripturePassage, ScriptureVerse } from '../types.js';
|
|
11
11
|
export declare const MAX_PHRASE_LENGTH = 500;
|
|
12
12
|
export declare const MAX_CANDIDATES = 200;
|
|
@@ -41,6 +41,32 @@ export interface TokenMatch extends ScriptureVerse {
|
|
|
41
41
|
/** Distinct significant tokens in this verse — the precision denominator. */
|
|
42
42
|
readonly distinctTokenCount: number;
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* One derived pericope (schema v8, CO-3 PR 1). `boundaryVotes` is the
|
|
46
|
+
* summed boundary vote at `startVerseId` — a countable structural fact
|
|
47
|
+
* (how many of the 20 surveyed translations start a section there), never
|
|
48
|
+
* a relevance score.
|
|
49
|
+
*/
|
|
50
|
+
export interface PericopeRow {
|
|
51
|
+
readonly startVerseId: number;
|
|
52
|
+
readonly endVerseId: number;
|
|
53
|
+
readonly boundaryVotes: number;
|
|
54
|
+
readonly sourceId: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* One mined cross-reference phrase triple (schema v9, B3 Phase A). The
|
|
58
|
+
* `normalizedPhrase` is the tokenizer-normalized key of the TSK entry
|
|
59
|
+
* fragment under which the reference was printed — a lookup key, never
|
|
60
|
+
* displayed prose. Structural lineage only: the row says a curated source
|
|
61
|
+
* printed this link under that phrase; it scores nothing by itself.
|
|
62
|
+
*/
|
|
63
|
+
export interface CrossReferencePhraseRow {
|
|
64
|
+
readonly fromVerseId: number;
|
|
65
|
+
readonly normalizedPhrase: string;
|
|
66
|
+
readonly toStartVerseId: number;
|
|
67
|
+
readonly toEndVerseId: number;
|
|
68
|
+
readonly sourceId: string;
|
|
69
|
+
}
|
|
44
70
|
export interface CorpusMeta {
|
|
45
71
|
readonly schemaVersion: string;
|
|
46
72
|
readonly tokenizerVersion: string;
|
|
@@ -58,6 +84,15 @@ export interface CorpusMeta {
|
|
|
58
84
|
export declare class CorpusRepository implements ReferenceResolver {
|
|
59
85
|
private readonly database;
|
|
60
86
|
constructor(database: ContentQueryPort);
|
|
87
|
+
/**
|
|
88
|
+
* The alias vocabulary for the reference did-you-mean (0.11.0/QR-4),
|
|
89
|
+
* fetched through the port once per repository instance and cached: ~270
|
|
90
|
+
* rows that cannot change under a running engine (the artifact is
|
|
91
|
+
* immutable), so re-reading them per query would be waste, and caching
|
|
92
|
+
* keeps the engine's no-I/O covenant intact — the ONE read still goes
|
|
93
|
+
* through ContentQueryPort.
|
|
94
|
+
*/
|
|
95
|
+
private bookAliasCache;
|
|
61
96
|
close(): Promise<void>;
|
|
62
97
|
readMeta(): Promise<CorpusMeta>;
|
|
63
98
|
/** Total indexed verses per translation — the N in IDF. */
|
|
@@ -65,7 +100,8 @@ export declare class CorpusRepository implements ReferenceResolver {
|
|
|
65
100
|
resolveBookAlias(aliasKey: string): Promise<ResolvedBook | null>;
|
|
66
101
|
getChapterVerseCount(bookId: number, chapter: number): Promise<number | null>;
|
|
67
102
|
verseExists(bookId: number, chapter: number, verse: number): Promise<boolean>;
|
|
68
|
-
|
|
103
|
+
listBookAliases(): Promise<readonly BookAliasEntry[]>;
|
|
104
|
+
resolveReference(input: string): Promise<import("../internal.js").ReferenceResolutionAttempt>;
|
|
69
105
|
loadPassage(resolved: ResolvedReference): Promise<ScripturePassage>;
|
|
70
106
|
/**
|
|
71
107
|
* Exact phrase via FTS5, ranked by bm25.
|
|
@@ -89,6 +125,79 @@ export declare class CorpusRepository implements ReferenceResolver {
|
|
|
89
125
|
*/
|
|
90
126
|
searchTokens(tokens: readonly string[], documentCount: number, limit?: number): Promise<readonly TokenMatch[]>;
|
|
91
127
|
tokenDocumentCounts(tokens: readonly string[]): Promise<ReadonlyMap<string, number>>;
|
|
128
|
+
/**
|
|
129
|
+
* Whether this artifact carries the precomputed spelling index
|
|
130
|
+
* (schema v7, 0.12.0/QR-5). Presence-probed like the other optional
|
|
131
|
+
* layers: a v6 artifact simply has no tables, the probe returns false, and
|
|
132
|
+
* the engine gracefully does not correct — behaving exactly as the
|
|
133
|
+
* pre-spelling engine did. That probe IS the rollback story: rebuild the
|
|
134
|
+
* artifact without the tables and behavior reverts with no engine change.
|
|
135
|
+
*/
|
|
136
|
+
hasSpellingIndex(): Promise<boolean>;
|
|
137
|
+
/**
|
|
138
|
+
* Whether this artifact carries the derived pericope tiling (schema v8,
|
|
139
|
+
* CO-3 PR 1). Presence-and-rows probed like the other optional layers: a
|
|
140
|
+
* v7 artifact has no table, an emptied table disables the (future)
|
|
141
|
+
* grouping step silently, and behavior reverts to pre-pericope output
|
|
142
|
+
* with no engine change — the probe IS the rollback story.
|
|
143
|
+
*/
|
|
144
|
+
hasPericopes(): Promise<boolean>;
|
|
145
|
+
/**
|
|
146
|
+
* The pericopes containing any of the given verse ids, batched as ONE
|
|
147
|
+
* bounded query over the ranked window (G11): the window's min..max verse
|
|
148
|
+
* span overlaps few pericopes, and the caller maps verses to rows. Rows
|
|
149
|
+
* come back ordered by start verse for platform-stable iteration.
|
|
150
|
+
*
|
|
151
|
+
* NO CALL SITES in discover() yet (CO-3 PR 1 capability): the grouping
|
|
152
|
+
* behavior that consumes this lands with the PR 2 ENGINE_VERSION bump.
|
|
153
|
+
* boundaryVotes is the summed boundary vote at the pericope's start verse
|
|
154
|
+
* — the countable fact the artifact stores, so a future explanation and
|
|
155
|
+
* the shipped data cannot disagree.
|
|
156
|
+
*/
|
|
157
|
+
pericopesContaining(verseIds: readonly number[]): Promise<readonly PericopeRow[]>;
|
|
158
|
+
/**
|
|
159
|
+
* Whether this artifact carries the mined TSK cross-reference phrase keys
|
|
160
|
+
* (schema v9, B3 Phase A). Presence-and-rows probed like pericopes: a v8
|
|
161
|
+
* artifact has no table, an emptied table reads false, and (future)
|
|
162
|
+
* phrase-labeled behavior reverts to plain cross_references output with no
|
|
163
|
+
* engine change — the probe IS the rollback story.
|
|
164
|
+
*/
|
|
165
|
+
hasCrossReferencePhrases(): Promise<boolean>;
|
|
166
|
+
/**
|
|
167
|
+
* The cross-reference phrase triples whose FROM verse is one of the given
|
|
168
|
+
* verse ids, batched as ONE bounded query over the window's min..max span
|
|
169
|
+
* (G11) and filtered back to the asked-for verses. Rows come back ordered
|
|
170
|
+
* by (from, phrase, start, end, source) for platform-stable iteration —
|
|
171
|
+
* sorted HERE, in engine code, by UTF-16 code units (the same comparison
|
|
172
|
+
* buildConceptLayer's fingerprint feed uses), never by the port's SQL
|
|
173
|
+
* collation: SQLite's BINARY collation compares UTF-8 bytes, which
|
|
174
|
+
* disagrees with JS on some non-ASCII strings, and the ordering contract
|
|
175
|
+
* must not depend on which side compares.
|
|
176
|
+
*
|
|
177
|
+
* NO CALL SITES in discover() yet (B3 Phase A capability): the labeling
|
|
178
|
+
* and off-phrase-discount behavior that consumes this lands with the
|
|
179
|
+
* Phase B ENGINE_VERSION bump behind J26/J55.
|
|
180
|
+
*/
|
|
181
|
+
crossReferencePhrasesFor(verseIds: readonly number[]): Promise<readonly CrossReferencePhraseRow[]>;
|
|
182
|
+
/**
|
|
183
|
+
* Which of the given tokens exist in the artifact's spelling vocabulary
|
|
184
|
+
* (corpus tokens ∪ book aliases ∪ lexicon tokens ∪ translation tokens ∪
|
|
185
|
+
* Layer B verse terms).
|
|
186
|
+
* This is the OOV gate's second half: a token with corpus df 0 that is
|
|
187
|
+
* still a known name or curated word is IN vocabulary and never corrected.
|
|
188
|
+
*/
|
|
189
|
+
spellingTermsPresent(tokens: readonly string[]): Promise<ReadonlySet<string>>;
|
|
190
|
+
/**
|
|
191
|
+
* Dictionary terms whose precomputed delete variants intersect the given
|
|
192
|
+
* keys — the SymSpell candidate lookup (0.12.0/QR-5). Proposes only: every
|
|
193
|
+
* candidate is re-verified with the bounded Damerau DP before it may win
|
|
194
|
+
* (see intents/spelling.ts). ORDER BY term for a platform-stable row order,
|
|
195
|
+
* though the picker is proven row-order independent anyway.
|
|
196
|
+
*/
|
|
197
|
+
spellingCandidates(deleteKeys: readonly string[]): Promise<readonly {
|
|
198
|
+
term: string;
|
|
199
|
+
documentCount: number;
|
|
200
|
+
}[]>;
|
|
92
201
|
}
|
|
93
202
|
/**
|
|
94
203
|
* Finds the LONGEST verbatim fragment of the query present in the corpus.
|
|
@@ -121,6 +230,18 @@ export interface ConceptAnchorRow extends ScriptureVerse {
|
|
|
121
230
|
readonly sourceId: string;
|
|
122
231
|
readonly weight: number;
|
|
123
232
|
readonly locator: string | null;
|
|
233
|
+
/**
|
|
234
|
+
* The curated anchor's OWN span, carried through so results can be presented
|
|
235
|
+
* as the passage a human named rather than as N separate verses.
|
|
236
|
+
*
|
|
237
|
+
* A ranged anchor emits one candidate per verse, and authoritative results
|
|
238
|
+
* are exempt from group diversification by design — so `communion` returned
|
|
239
|
+
* 1 Cor 11:23, :24, :25 and :26 as four identical-scoring results occupying
|
|
240
|
+
* the whole top of the list. The span is the natural unit here because a
|
|
241
|
+
* human chose it; nothing has to be inferred.
|
|
242
|
+
*/
|
|
243
|
+
readonly anchorStartVerseId: number;
|
|
244
|
+
readonly anchorEndVerseId: number;
|
|
124
245
|
}
|
|
125
246
|
/** A verse reached by a curated cross-reference edge. */
|
|
126
247
|
export interface CrossReferenceRow extends ScriptureVerse {
|
|
@@ -128,6 +249,26 @@ export interface CrossReferenceRow extends ScriptureVerse {
|
|
|
128
249
|
readonly sourceId: string;
|
|
129
250
|
readonly votes: number;
|
|
130
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* One curated phrase/hymn alias (0.13.0/QR-6): a whole-query key mapping to
|
|
254
|
+
* exactly one of a curated concept or an explicit verse range (the schema's
|
|
255
|
+
* XOR CHECK). `title` and `locator` surface verbatim in the explanation chip
|
|
256
|
+
* — the attribution IS the product here (covenant 6: the engine reports that
|
|
257
|
+
* a named source connects this phrase to this target; it adjudicates
|
|
258
|
+
* nothing).
|
|
259
|
+
*/
|
|
260
|
+
export interface CuratedAliasRow {
|
|
261
|
+
readonly id: number;
|
|
262
|
+
readonly title: string;
|
|
263
|
+
readonly conceptId: string | null;
|
|
264
|
+
/** Label of the target concept; null exactly when conceptId is null. */
|
|
265
|
+
readonly conceptLabel: string | null;
|
|
266
|
+
readonly startVerseId: number | null;
|
|
267
|
+
readonly endVerseId: number | null;
|
|
268
|
+
readonly sourceId: string;
|
|
269
|
+
readonly weight: number;
|
|
270
|
+
readonly locator: string | null;
|
|
271
|
+
}
|
|
131
272
|
/**
|
|
132
273
|
* Concept lookup and anchor expansion — Layer A at query time.
|
|
133
274
|
*
|
|
@@ -181,6 +322,26 @@ export declare class ConceptRepository {
|
|
|
181
322
|
* it is a long way from the passage saying it. G6 caps it so no volume of
|
|
182
323
|
* homiletical vocabulary can outrank a curated anchor or a verbatim quote.
|
|
183
324
|
*/
|
|
325
|
+
/**
|
|
326
|
+
* Verses whose CROSS-TRANSLATION vocabulary matches the query.
|
|
327
|
+
*
|
|
328
|
+
* This is what lets someone search in the translation they learned a verse
|
|
329
|
+
* in. The stems here appear in some English translation of the verse but not
|
|
330
|
+
* in the one shipped, so a query using that wording reaches the verse
|
|
331
|
+
* anyway. See pipeline/src/schema.ts for what is and is not stored.
|
|
332
|
+
*
|
|
333
|
+
* Ranked by how MANY query stems a verse accounts for, then by verse id. No
|
|
334
|
+
* IDF weighting: these stems are already the residue after the shipped
|
|
335
|
+
* wording is subtracted, so a stem appearing here is by construction
|
|
336
|
+
* something the shipped text does not say.
|
|
337
|
+
*/
|
|
338
|
+
searchTranslationTokens(tokens: readonly string[], limit?: number): Promise<readonly (ScriptureVerse & {
|
|
339
|
+
matchedTokens: readonly string[];
|
|
340
|
+
})[]>;
|
|
341
|
+
/** How many verses carry each stem — the df for weighting alternate wording. */
|
|
342
|
+
translationTokenDocumentCounts(tokens: readonly string[]): Promise<ReadonlyMap<string, number>>;
|
|
343
|
+
/** Whether the artifact carries cross-translation vocabulary at all. */
|
|
344
|
+
hasTranslationTokens(): Promise<boolean>;
|
|
184
345
|
searchPassageTerms(terms: readonly string[], limit?: number): Promise<readonly (ScriptureVerse & {
|
|
185
346
|
matchedTerms: readonly string[];
|
|
186
347
|
pmiSum: number;
|
|
@@ -189,5 +350,31 @@ export declare class ConceptRepository {
|
|
|
189
350
|
locator: string;
|
|
190
351
|
})[]>;
|
|
191
352
|
hasPassageTerms(): Promise<boolean>;
|
|
353
|
+
/**
|
|
354
|
+
* Whether this artifact carries any curated phrase/hymn aliases
|
|
355
|
+
* (0.13.0/QR-6). Presence-AND-ROWS probed, deliberately stricter than the
|
|
356
|
+
* other layer probes: schema v7 ships the table EMPTY (QR-5), and an
|
|
357
|
+
* engine that ran the alias step against an empty table would pay a query
|
|
358
|
+
* per research() call for nothing — and, more importantly, the rollback
|
|
359
|
+
* story is "rebuild without alias rows", which must restore pre-QR-6
|
|
360
|
+
* behavior exactly. No table, or an empty one, and 0.13.0 behaves as
|
|
361
|
+
* 0.12.0 did.
|
|
362
|
+
*/
|
|
363
|
+
hasCuratedAliases(): Promise<boolean>;
|
|
364
|
+
/**
|
|
365
|
+
* The curated aliases whose whole-query key equals the given normalized
|
|
366
|
+
* phrase. EQUALITY, never containment — the line that keeps a curated
|
|
367
|
+
* phrase table from becoming a hidden second ranking system; brittleness
|
|
368
|
+
* to extra words is accepted BY DESIGN. `normalized_raw` is UNIQUE, so
|
|
369
|
+
* this returns at most one row; it is typed as a list so the caller does
|
|
370
|
+
* not encode that schema fact.
|
|
371
|
+
*/
|
|
372
|
+
matchAliases(normalizedQuery: string): Promise<readonly CuratedAliasRow[]>;
|
|
373
|
+
/**
|
|
374
|
+
* Verses of an explicit alias verse range (the XOR's other arm). A range
|
|
375
|
+
* absent from this corpus returns no rows — the alias then contributes
|
|
376
|
+
* nothing, honestly, rather than being guessed at.
|
|
377
|
+
*/
|
|
378
|
+
aliasRangeVerses(startVerseId: number, endVerseId: number): Promise<readonly ScriptureVerse[]>;
|
|
192
379
|
hasConceptLayer(): Promise<boolean>;
|
|
193
380
|
}
|