@fortemi/core 2026.6.2 → 2026.6.4
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 +2 -1
- package/dist/aiwg-index.d.ts +31 -1
- package/dist/aiwg-index.js +177 -10
- package/dist/aiwg-index.js.map +1 -1
- package/dist/index.d.ts +303 -28
- package/dist/index.js +403 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Headless browser knowledge-management core powered by PGlite, typed repositories, semantic retrieval, and agent tool helpers**
|
|
6
6
|
|
|
7
|
-
Build local-first knowledge apps
|
|
7
|
+
Build local-first knowledge apps where data stays in the browser on the user's device — no server, no account — with PostgreSQL-compatible storage, production-ready repositories, hybrid search primitives, portable Knowledge Shard archives, opt-in bring-your-own AI wiring, and bridge-ready tool metadata.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
pnpm add @fortemi/core
|
|
@@ -15,6 +15,7 @@ pnpm add @fortemi/core
|
|
|
15
15
|
[](https://github.com/Fortemi/fortemi-react/blob/main/LICENSE)
|
|
16
16
|
[](https://nodejs.org)
|
|
17
17
|
[](https://www.typescriptlang.org)
|
|
18
|
+
[](https://www.npmjs.com/package/aiwg)
|
|
18
19
|
|
|
19
20
|
[**Install**](#installation) · [**Why Fortemi**](#why-fortemi-core) · [**Quick Start**](#quick-start) · [**Surface**](#what-you-get) · [**Tools**](#tool-surface) · [**Docs**](#documentation) · [**License**](#license)
|
|
20
21
|
|
package/dist/aiwg-index.d.ts
CHANGED
|
@@ -51,6 +51,11 @@ interface AiwgFortemiChunkPartRef {
|
|
|
51
51
|
offset: number;
|
|
52
52
|
count: number;
|
|
53
53
|
}
|
|
54
|
+
declare const AIWG_SCAN_REQUIRED_FIELDS: Array<keyof AiwgFortemiRecord>;
|
|
55
|
+
type AiwgFortemiProjectedRecord = Pick<AiwgFortemiRecord, 'schema_version' | 'id' | 'type' | 'title' | 'text' | 'facets' | 'tags' | 'concepts' | 'privacy'> & Partial<AiwgFortemiRecord>;
|
|
56
|
+
interface AiwgFortemiChunkDetailRef {
|
|
57
|
+
href: string;
|
|
58
|
+
}
|
|
54
59
|
interface AiwgFortemiChunkManifest {
|
|
55
60
|
schema_version: 'aiwg.fortemi.index.chunk-manifest.v1';
|
|
56
61
|
generated_at: string;
|
|
@@ -58,6 +63,8 @@ interface AiwgFortemiChunkManifest {
|
|
|
58
63
|
total: number;
|
|
59
64
|
part_size: number;
|
|
60
65
|
facets?: Record<string, Record<string, number>>;
|
|
66
|
+
projection?: Array<keyof AiwgFortemiRecord>;
|
|
67
|
+
detail?: AiwgFortemiChunkDetailRef;
|
|
61
68
|
parts: AiwgFortemiChunkPartRef[];
|
|
62
69
|
}
|
|
63
70
|
interface AiwgFortemiChunkPart {
|
|
@@ -113,8 +120,11 @@ interface AiwgIndexQueryResult {
|
|
|
113
120
|
rankedItems?: AiwgIndexQueryRankedItem[];
|
|
114
121
|
}
|
|
115
122
|
type AiwgChunkedIndexLoader = (part: AiwgFortemiChunkPartRef, manifest: AiwgFortemiChunkManifest) => Promise<unknown>;
|
|
123
|
+
type AiwgChunkedIndexDetailLoader = (id: string, manifest: AiwgFortemiChunkManifest) => Promise<unknown>;
|
|
116
124
|
interface AiwgChunkedIndexLoadOptions {
|
|
117
125
|
maxCachedParts?: number;
|
|
126
|
+
detailLoader?: AiwgChunkedIndexDetailLoader;
|
|
127
|
+
maxCachedDetails?: number;
|
|
118
128
|
}
|
|
119
129
|
type AiwgChunkedIndexProgressPhase = 'part' | 'query';
|
|
120
130
|
interface AiwgChunkedIndexProgress {
|
|
@@ -175,6 +185,7 @@ interface AiwgIndexController {
|
|
|
175
185
|
getSnapshot(): AiwgIndexControllerSnapshot;
|
|
176
186
|
query(query?: string, options?: AiwgIndexQueryOptions): AiwgIndexQueryResult;
|
|
177
187
|
queryChunked(query?: string, options?: AiwgChunkedIndexQueryOptions): Promise<AiwgChunkedIndexQueryResult>;
|
|
188
|
+
getRecord(id: string): Promise<AiwgFortemiRecord>;
|
|
178
189
|
clearChunkCache(): void;
|
|
179
190
|
toCommunityGraph(options?: AiwgIndexGraphOptions): ReturnType<typeof aiwgFortemiIndexToCommunityGraph>;
|
|
180
191
|
setReviewDecision(input: AiwgReviewInput): AiwgReviewDecision;
|
|
@@ -189,7 +200,26 @@ declare function assertAiwgFortemiChunkManifest(value: unknown): AiwgFortemiChun
|
|
|
189
200
|
declare function validateAiwgFortemiChunkPart(value: unknown, partRef?: AiwgFortemiChunkPartRef, manifest?: AiwgFortemiChunkManifest): AiwgChunkedIndexValidationResult;
|
|
190
201
|
declare function assertAiwgFortemiChunkPart(value: unknown, partRef?: AiwgFortemiChunkPartRef, manifest?: AiwgFortemiChunkManifest): AiwgFortemiChunkPart;
|
|
191
202
|
declare function createAiwgFetchChunkLoader(baseUrl?: string | URL): AiwgChunkedIndexLoader;
|
|
203
|
+
declare function createAiwgFetchDetailLoader(baseUrl?: string | URL): AiwgChunkedIndexDetailLoader;
|
|
192
204
|
declare function getAiwgFortemiFacets(items: AiwgFortemiRecord[]): Record<string, Record<string, number>>;
|
|
205
|
+
interface AiwgChunkedIndexBuildOptions {
|
|
206
|
+
partSize?: number;
|
|
207
|
+
projection?: Array<keyof AiwgFortemiRecord>;
|
|
208
|
+
detailHref?: string;
|
|
209
|
+
generatedAt?: string;
|
|
210
|
+
}
|
|
211
|
+
interface AiwgChunkedIndexBuildResult {
|
|
212
|
+
manifest: AiwgFortemiChunkManifest;
|
|
213
|
+
parts: Array<{
|
|
214
|
+
href: string;
|
|
215
|
+
part: AiwgFortemiChunkPart;
|
|
216
|
+
}>;
|
|
217
|
+
details: Array<{
|
|
218
|
+
id: string;
|
|
219
|
+
record: AiwgFortemiRecord;
|
|
220
|
+
}>;
|
|
221
|
+
}
|
|
222
|
+
declare function buildAiwgChunkedIndex(index: AiwgFortemiIndexExport, options?: AiwgChunkedIndexBuildOptions): AiwgChunkedIndexBuildResult;
|
|
193
223
|
declare function queryAiwgFortemiIndex(index: AiwgFortemiIndexExport, query?: string, options?: AiwgIndexQueryOptions): AiwgIndexQueryResult;
|
|
194
224
|
declare function createAiwgReviewDecisionExport(source: AiwgFortemiIndexExport, decisions: AiwgReviewDecision[], generatedAt?: string): AiwgReviewDecisionExport;
|
|
195
225
|
declare function createAiwgIndexController(initialIndex?: AiwgFortemiIndexExport): AiwgIndexController;
|
|
@@ -209,4 +239,4 @@ declare function aiwgFortemiIndexToCommunityGraph(index: AiwgFortemiIndexExport,
|
|
|
209
239
|
}[];
|
|
210
240
|
};
|
|
211
241
|
|
|
212
|
-
export { type AiwgChunkedIndexLoadOptions, type AiwgChunkedIndexLoader, type AiwgChunkedIndexProgress, type AiwgChunkedIndexProgressPhase, type AiwgChunkedIndexQueryOptions, type AiwgChunkedIndexQueryResult, type AiwgChunkedIndexValidationResult, type AiwgFortemiChunkManifest, type AiwgFortemiChunkPart, type AiwgFortemiChunkPartRef, type AiwgFortemiIndexExport, type AiwgFortemiProvenance, type AiwgFortemiRecord, type AiwgFortemiRecordSource, type AiwgFortemiRecordType, type AiwgFortemiRelationship, type AiwgIndexController, type AiwgIndexControllerListener, type AiwgIndexControllerSnapshot, type AiwgIndexGraphOptions, type AiwgIndexQueryMatch, type AiwgIndexQueryOptions, type AiwgIndexQueryRankedItem, type AiwgIndexQueryResult, type AiwgIndexQueryWeights, type AiwgIndexValidationResult, type AiwgPrivacyClassification, type AiwgProvenanceConfidence, type AiwgReviewAction, type AiwgReviewDecision, type AiwgReviewDecisionExport, type AiwgReviewInput, aiwgFortemiIndexToCommunityGraph, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, createAiwgFetchChunkLoader, createAiwgIndexController, createAiwgReviewDecisionExport, getAiwgFortemiFacets, queryAiwgFortemiIndex, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport };
|
|
242
|
+
export { AIWG_SCAN_REQUIRED_FIELDS, type AiwgChunkedIndexBuildOptions, type AiwgChunkedIndexBuildResult, type AiwgChunkedIndexDetailLoader, type AiwgChunkedIndexLoadOptions, type AiwgChunkedIndexLoader, type AiwgChunkedIndexProgress, type AiwgChunkedIndexProgressPhase, type AiwgChunkedIndexQueryOptions, type AiwgChunkedIndexQueryResult, type AiwgChunkedIndexValidationResult, type AiwgFortemiChunkDetailRef, type AiwgFortemiChunkManifest, type AiwgFortemiChunkPart, type AiwgFortemiChunkPartRef, type AiwgFortemiIndexExport, type AiwgFortemiProjectedRecord, type AiwgFortemiProvenance, type AiwgFortemiRecord, type AiwgFortemiRecordSource, type AiwgFortemiRecordType, type AiwgFortemiRelationship, type AiwgIndexController, type AiwgIndexControllerListener, type AiwgIndexControllerSnapshot, type AiwgIndexGraphOptions, type AiwgIndexQueryMatch, type AiwgIndexQueryOptions, type AiwgIndexQueryRankedItem, type AiwgIndexQueryResult, type AiwgIndexQueryWeights, type AiwgIndexValidationResult, type AiwgPrivacyClassification, type AiwgProvenanceConfidence, type AiwgReviewAction, type AiwgReviewDecision, type AiwgReviewDecisionExport, type AiwgReviewInput, aiwgFortemiIndexToCommunityGraph, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, buildAiwgChunkedIndex, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, getAiwgFortemiFacets, queryAiwgFortemiIndex, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport };
|
package/dist/aiwg-index.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
// src/aiwg-index.ts
|
|
2
|
+
var AIWG_SCAN_REQUIRED_FIELDS = [
|
|
3
|
+
"schema_version",
|
|
4
|
+
"id",
|
|
5
|
+
"type",
|
|
6
|
+
"title",
|
|
7
|
+
"text",
|
|
8
|
+
"facets",
|
|
9
|
+
"tags",
|
|
10
|
+
"concepts",
|
|
11
|
+
"privacy"
|
|
12
|
+
];
|
|
2
13
|
var REQUIRED_RECORD_FIELDS = [
|
|
3
14
|
"schema_version",
|
|
4
15
|
"id",
|
|
@@ -110,6 +121,20 @@ function validateAiwgFortemiChunkManifest(value) {
|
|
|
110
121
|
if (data.facets !== void 0 && !isFacetCounts(data.facets)) {
|
|
111
122
|
errors.push("facets must be a nested string-to-number count object");
|
|
112
123
|
}
|
|
124
|
+
if (data.projection !== void 0) {
|
|
125
|
+
if (!Array.isArray(data.projection) || !data.projection.every((field) => typeof field === "string")) {
|
|
126
|
+
errors.push("projection must be an array of field names");
|
|
127
|
+
} else {
|
|
128
|
+
const present = new Set(data.projection);
|
|
129
|
+
for (const field of AIWG_SCAN_REQUIRED_FIELDS) {
|
|
130
|
+
if (!present.has(field)) errors.push("projection must include scan-required field " + field);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (data.detail !== void 0) {
|
|
135
|
+
if (!hasString(data.detail.href)) errors.push("detail.href is required");
|
|
136
|
+
else if (!data.detail.href.includes("{id}")) errors.push("detail.href must contain the {id} placeholder");
|
|
137
|
+
}
|
|
113
138
|
if (!Array.isArray(data?.parts)) errors.push("parts must be an array");
|
|
114
139
|
let expectedOffset = 0;
|
|
115
140
|
const parts = Array.isArray(data?.parts) ? data.parts : [];
|
|
@@ -134,6 +159,35 @@ function assertAiwgFortemiChunkManifest(value) {
|
|
|
134
159
|
}
|
|
135
160
|
return value;
|
|
136
161
|
}
|
|
162
|
+
function validateProjectedRecords(items) {
|
|
163
|
+
const errors = [];
|
|
164
|
+
const ids = /* @__PURE__ */ new Set();
|
|
165
|
+
let previousId = "";
|
|
166
|
+
for (const [index, item] of items.entries()) {
|
|
167
|
+
if (item.schema_version !== "aiwg.fortemi.index.record.v1") {
|
|
168
|
+
errors.push("items[" + index + "].schema_version must be aiwg.fortemi.index.record.v1");
|
|
169
|
+
}
|
|
170
|
+
if (!hasString(item.id)) errors.push("items[" + index + "].id is required");
|
|
171
|
+
if (hasString(item.id) && ids.has(item.id)) errors.push("duplicate id: " + item.id);
|
|
172
|
+
if (hasString(item.id)) ids.add(item.id);
|
|
173
|
+
if (previousId && hasString(item.id) && previousId.localeCompare(item.id) > 0) {
|
|
174
|
+
errors.push("items must be sorted by id: " + previousId + " before " + item.id);
|
|
175
|
+
}
|
|
176
|
+
if (hasString(item.id)) previousId = item.id;
|
|
177
|
+
if (!item.type || !VALID_TYPES.has(item.type)) errors.push("items[" + index + "].type is invalid");
|
|
178
|
+
if (!hasString(item.title)) errors.push("items[" + index + "].title is required");
|
|
179
|
+
if (typeof item.text !== "string") errors.push("items[" + index + "].text is required");
|
|
180
|
+
if (!item.facets || typeof item.facets !== "object" || Array.isArray(item.facets)) {
|
|
181
|
+
errors.push("items[" + index + "].facets must be an object");
|
|
182
|
+
}
|
|
183
|
+
if (!Array.isArray(item.tags)) errors.push("items[" + index + "].tags must be an array");
|
|
184
|
+
if (!Array.isArray(item.concepts)) errors.push("items[" + index + "].concepts must be an array");
|
|
185
|
+
if (!item.privacy || !hasString(item.privacy.classification)) {
|
|
186
|
+
errors.push("items[" + index + "].privacy.classification is required");
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return errors;
|
|
190
|
+
}
|
|
137
191
|
function validateAiwgFortemiChunkPart(value, partRef, manifest) {
|
|
138
192
|
const errors = [];
|
|
139
193
|
const data = value;
|
|
@@ -152,13 +206,17 @@ function validateAiwgFortemiChunkPart(value, partRef, manifest) {
|
|
|
152
206
|
errors.push("items length must match manifest part count " + partRef.count);
|
|
153
207
|
}
|
|
154
208
|
if (Array.isArray(data?.items)) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
209
|
+
if (manifest?.projection) {
|
|
210
|
+
errors.push(...validateProjectedRecords(data.items).map((error) => "items." + error));
|
|
211
|
+
} else {
|
|
212
|
+
const validation = validateAiwgFortemiIndexExport({
|
|
213
|
+
schema_version: "aiwg.fortemi.index.export.v1",
|
|
214
|
+
generated_at: manifest?.generated_at ?? "1970-01-01T00:00:00.000Z",
|
|
215
|
+
source: manifest?.source ?? { repo: "chunk", privacy: "public" },
|
|
216
|
+
items: data.items
|
|
217
|
+
});
|
|
218
|
+
errors.push(...validation.errors.map((error) => "items." + error));
|
|
219
|
+
}
|
|
162
220
|
}
|
|
163
221
|
return { valid: errors.length === 0, errors };
|
|
164
222
|
}
|
|
@@ -177,6 +235,16 @@ function createAiwgFetchChunkLoader(baseUrl) {
|
|
|
177
235
|
return response.json();
|
|
178
236
|
};
|
|
179
237
|
}
|
|
238
|
+
function createAiwgFetchDetailLoader(baseUrl) {
|
|
239
|
+
return async (id, manifest) => {
|
|
240
|
+
if (!manifest.detail?.href) throw new Error("Manifest has no detail.href for record resolution");
|
|
241
|
+
const relative = manifest.detail.href.replace("{id}", encodeURIComponent(id));
|
|
242
|
+
const href = baseUrl ? new URL(relative, baseUrl).toString() : relative;
|
|
243
|
+
const response = await fetch(href);
|
|
244
|
+
if (!response.ok) throw new Error("Failed to fetch AIWG index detail " + href + ": " + response.status);
|
|
245
|
+
return response.json();
|
|
246
|
+
};
|
|
247
|
+
}
|
|
180
248
|
function getAiwgFortemiFacets(items) {
|
|
181
249
|
const result = {};
|
|
182
250
|
for (const item of items) {
|
|
@@ -190,6 +258,49 @@ function getAiwgFortemiFacets(items) {
|
|
|
190
258
|
}
|
|
191
259
|
return result;
|
|
192
260
|
}
|
|
261
|
+
function buildAiwgChunkedIndex(index, options = {}) {
|
|
262
|
+
const partSize = hasPositiveInteger(options.partSize) ? options.partSize : 500;
|
|
263
|
+
const projection = options.projection;
|
|
264
|
+
const items = index.items;
|
|
265
|
+
const pad = (value) => String(value).padStart(4, "0");
|
|
266
|
+
const project = (record) => {
|
|
267
|
+
if (!projection) return record;
|
|
268
|
+
const slim = {};
|
|
269
|
+
for (const field of projection) slim[field] = record[field];
|
|
270
|
+
return slim;
|
|
271
|
+
};
|
|
272
|
+
const parts = [];
|
|
273
|
+
const partRefs = [];
|
|
274
|
+
for (let offset = 0, partIndex = 0; offset < items.length; offset += partSize, partIndex += 1) {
|
|
275
|
+
const slice = items.slice(offset, offset + partSize);
|
|
276
|
+
const href = "part-" + pad(partIndex) + ".json";
|
|
277
|
+
parts.push({
|
|
278
|
+
href,
|
|
279
|
+
part: {
|
|
280
|
+
schema_version: "aiwg.fortemi.index.chunk.v1",
|
|
281
|
+
manifest_schema_version: "aiwg.fortemi.index.chunk-manifest.v1",
|
|
282
|
+
offset,
|
|
283
|
+
items: slice.map(project)
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
partRefs.push({ href, offset, count: slice.length });
|
|
287
|
+
}
|
|
288
|
+
const manifest = {
|
|
289
|
+
schema_version: "aiwg.fortemi.index.chunk-manifest.v1",
|
|
290
|
+
generated_at: options.generatedAt ?? index.generated_at,
|
|
291
|
+
source: index.source,
|
|
292
|
+
total: items.length,
|
|
293
|
+
part_size: partSize,
|
|
294
|
+
facets: getAiwgFortemiFacets(items),
|
|
295
|
+
parts: partRefs,
|
|
296
|
+
...projection ? { projection, detail: { href: options.detailHref ?? "detail/{id}.json" } } : {}
|
|
297
|
+
};
|
|
298
|
+
return {
|
|
299
|
+
manifest,
|
|
300
|
+
parts,
|
|
301
|
+
details: projection ? items.map((record) => ({ id: record.id, record })) : []
|
|
302
|
+
};
|
|
303
|
+
}
|
|
193
304
|
function includesAll(actual, expected) {
|
|
194
305
|
if (!expected || expected.length === 0) return true;
|
|
195
306
|
const actualSet = new Set(actual);
|
|
@@ -244,7 +355,7 @@ function createRankedEntries(items, q, options, ordinalBase = 0) {
|
|
|
244
355
|
if (!includesAll(item.tags, options.tags)) return false;
|
|
245
356
|
if (!includesAll(item.concepts, options.concepts)) return false;
|
|
246
357
|
if (!matchesFacetFilters(item, options.facets)) return false;
|
|
247
|
-
if (options.relationshipTargetId && !item.relationships.some((rel) => rel.target_id === options.relationshipTargetId)) {
|
|
358
|
+
if (options.relationshipTargetId && !(item.relationships ?? []).some((rel) => rel.target_id === options.relationshipTargetId)) {
|
|
248
359
|
return false;
|
|
249
360
|
}
|
|
250
361
|
return true;
|
|
@@ -293,6 +404,10 @@ function clampMaxCachedParts(value) {
|
|
|
293
404
|
if (!hasPositiveInteger(value)) return 3;
|
|
294
405
|
return value;
|
|
295
406
|
}
|
|
407
|
+
function clampMaxCachedDetails(value) {
|
|
408
|
+
if (!hasPositiveInteger(value)) return 32;
|
|
409
|
+
return value;
|
|
410
|
+
}
|
|
296
411
|
function isDirectChunkBrowse(query, options) {
|
|
297
412
|
return query.trim() === "" && !options.rank && !options.snippets && !options.includeMatches && !options.types && !options.facets && !options.tags && !options.concepts && !options.privacy && !options.relationshipTargetId;
|
|
298
413
|
}
|
|
@@ -317,6 +432,40 @@ async function loadChunkPart(runtime, part) {
|
|
|
317
432
|
}
|
|
318
433
|
return { part: parsed, fetched: true };
|
|
319
434
|
}
|
|
435
|
+
async function getChunkRecord(runtime, id) {
|
|
436
|
+
const cached = runtime.detailCache.get(id);
|
|
437
|
+
if (cached) {
|
|
438
|
+
runtime.detailCache.delete(id);
|
|
439
|
+
runtime.detailCache.set(id, cached);
|
|
440
|
+
return cached;
|
|
441
|
+
}
|
|
442
|
+
if (!runtime.manifest.projection) {
|
|
443
|
+
for (const part of runtime.partCache.values()) {
|
|
444
|
+
const found = part.items.find((item) => item.id === id);
|
|
445
|
+
if (found) return found;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (!runtime.detailLoader) {
|
|
449
|
+
throw new Error("No detailLoader configured to resolve record " + id);
|
|
450
|
+
}
|
|
451
|
+
const raw = await runtime.detailLoader(id, runtime.manifest);
|
|
452
|
+
const record = assertAiwgFortemiIndexExport({
|
|
453
|
+
schema_version: "aiwg.fortemi.index.export.v1",
|
|
454
|
+
generated_at: runtime.manifest.generated_at,
|
|
455
|
+
source: runtime.manifest.source,
|
|
456
|
+
items: [raw]
|
|
457
|
+
}).items[0];
|
|
458
|
+
if (record.id !== id) {
|
|
459
|
+
throw new Error("Detail record id mismatch: expected " + id + ", got " + record.id);
|
|
460
|
+
}
|
|
461
|
+
runtime.detailCache.set(id, record);
|
|
462
|
+
while (runtime.detailCache.size > runtime.maxCachedDetails) {
|
|
463
|
+
const oldest = runtime.detailCache.keys().next().value;
|
|
464
|
+
if (oldest === void 0) break;
|
|
465
|
+
runtime.detailCache.delete(oldest);
|
|
466
|
+
}
|
|
467
|
+
return record;
|
|
468
|
+
}
|
|
320
469
|
async function queryChunkedAiwgFortemiIndex(runtime, query = "", options = {}) {
|
|
321
470
|
const q = query.trim().toLowerCase();
|
|
322
471
|
let scannedParts = 0;
|
|
@@ -421,7 +570,10 @@ function createAiwgIndexController(initialIndex) {
|
|
|
421
570
|
manifest: parsed,
|
|
422
571
|
loader,
|
|
423
572
|
maxCachedParts: clampMaxCachedParts(options.maxCachedParts),
|
|
424
|
-
partCache: /* @__PURE__ */ new Map()
|
|
573
|
+
partCache: /* @__PURE__ */ new Map(),
|
|
574
|
+
detailLoader: options.detailLoader,
|
|
575
|
+
maxCachedDetails: clampMaxCachedDetails(options.maxCachedDetails),
|
|
576
|
+
detailCache: /* @__PURE__ */ new Map()
|
|
425
577
|
};
|
|
426
578
|
data = null;
|
|
427
579
|
reviewDecisions = [];
|
|
@@ -464,8 +616,23 @@ function createAiwgIndexController(initialIndex) {
|
|
|
464
616
|
throw error;
|
|
465
617
|
}
|
|
466
618
|
},
|
|
619
|
+
async getRecord(id) {
|
|
620
|
+
if (chunked) {
|
|
621
|
+
try {
|
|
622
|
+
return await getChunkRecord(chunked, id);
|
|
623
|
+
} catch (err) {
|
|
624
|
+
error = err instanceof Error ? err : new Error(String(err));
|
|
625
|
+
notify();
|
|
626
|
+
throw error;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
const found = requireIndex().items.find((item) => item.id === id);
|
|
630
|
+
if (!found) throw new Error("Record not found: " + id);
|
|
631
|
+
return found;
|
|
632
|
+
},
|
|
467
633
|
clearChunkCache() {
|
|
468
634
|
chunked?.partCache.clear();
|
|
635
|
+
chunked?.detailCache.clear();
|
|
469
636
|
error = null;
|
|
470
637
|
notify();
|
|
471
638
|
},
|
|
@@ -545,6 +712,6 @@ function communityIdsFor(item, options) {
|
|
|
545
712
|
return [`type:${item.type}`];
|
|
546
713
|
}
|
|
547
714
|
|
|
548
|
-
export { aiwgFortemiIndexToCommunityGraph, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, createAiwgFetchChunkLoader, createAiwgIndexController, createAiwgReviewDecisionExport, getAiwgFortemiFacets, queryAiwgFortemiIndex, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport };
|
|
715
|
+
export { AIWG_SCAN_REQUIRED_FIELDS, aiwgFortemiIndexToCommunityGraph, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, buildAiwgChunkedIndex, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, getAiwgFortemiFacets, queryAiwgFortemiIndex, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport };
|
|
549
716
|
//# sourceMappingURL=aiwg-index.js.map
|
|
550
717
|
//# sourceMappingURL=aiwg-index.js.map
|