pikelet-wasm 0.7.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.
@@ -0,0 +1,289 @@
1
+ /**
2
+ * pikelet-wasm/complete — reader for complete .pancake artifacts
3
+ * (spec/COMPLETE_PROFILE.md, profile pancake-complete-v1). Opens any kind
4
+ * (1 student-inline, 2 declared-external, 3 inline-transformer) from a file
5
+ * path in Node or a range source anywhere.
6
+ */
7
+
8
+ /** A byte-range source: local file, HTTP, memory, or anything else. */
9
+ export interface CompleteRangeSource {
10
+ /** Total bytes, when known. Verified against the header when present. */
11
+ size?: number;
12
+ preferredParallelism?: number;
13
+ preferredGapBytes?: number;
14
+ read(offset: number, length: number): Promise<Uint8Array | ArrayBufferLike>;
15
+ close?(): Promise<void>;
16
+ }
17
+
18
+ export interface HttpRangeSourceStats {
19
+ requests: number;
20
+ bytes: number;
21
+ acceptRanges: string | null;
22
+ etag: string | null;
23
+ fullFallback: boolean;
24
+ /** Transient-status (429/502/503/504) retries issued, across all reads. */
25
+ retries: number;
26
+ /**
27
+ * Redirect hops resolved while pinning the final URL. A redirecting host
28
+ * (GitHub release assets) is resolved once and range reads go straight
29
+ * to the target, so its rate-limited front door is charged per mount,
30
+ * not per read; expired signed URLs (401/403) re-resolve automatically.
31
+ */
32
+ redirects: number;
33
+ }
34
+
35
+ export interface HttpRangeSource extends CompleteRangeSource {
36
+ stats: HttpRangeSourceStats;
37
+ init(): Promise<void>;
38
+ }
39
+
40
+ export declare function httpRangeSource(url: string, options?: {
41
+ preferredParallelism?: number;
42
+ preferredGapBytes?: number;
43
+ /** Cap on the one-time full download when a host ignores Range, enforced on received bytes. Default 64 MiB. */
44
+ maxFullFallbackBytes?: number;
45
+ /**
46
+ * Query parameter appended per range read so each read gets its own HTTP
47
+ * cache key (defeats Chromium's same-URL cache-entry lock). Default 'r';
48
+ * pass null for hosts that sign the full query string (presigned URLs) —
49
+ * range reads then share the unmodified URL.
50
+ */
51
+ cacheKeyParam?: string | null | false;
52
+ /**
53
+ * Retries per read for transient statuses (429/502/503/504), with capped
54
+ * exponential backoff (Retry-After honored when sane). Default 6; 0
55
+ * disables. CDNs rate-limit the parallel range bursts a query issues.
56
+ */
57
+ maxRetries?: number;
58
+ }): HttpRangeSource;
59
+
60
+ export interface CompleteQueryResult {
61
+ matchQuality: 'strong' | 'weak' | 'none' | 'unscored';
62
+ confidence?: number;
63
+ /**
64
+ * Each result is the hydrated corpus record plus the search's `id` and
65
+ * `distance`. Those two names are reserved: they always come from the
66
+ * search, and a record field of the same name is overwritten, never the
67
+ * other way round.
68
+ */
69
+ results: Array<{ id: number; distance: number } & Record<string, unknown>>;
70
+ }
71
+
72
+ export interface CompleteSearch {
73
+ info(): {
74
+ identity: string;
75
+ /** Container header formatVersion (1 or 2). */
76
+ formatVersion: number;
77
+ /** Manifest profile: 'pancake-complete-v1' | 'pancake-complete-v2'. */
78
+ profile: string;
79
+ /**
80
+ * Human-readable pack name from the identity-verified manifest
81
+ * (compile records it under corpus.provenance.name); null when the
82
+ * builder recorded none.
83
+ */
84
+ name: string | null;
85
+ /**
86
+ * Content license recorded at compile (SPDX id or free text) under
87
+ * corpus.provenance.license; null when the builder recorded none.
88
+ */
89
+ license: string | null;
90
+ records: number;
91
+ dim: number;
92
+ metric: string | number;
93
+ encoder: Record<string, unknown>;
94
+ /**
95
+ * Kind 2: true when the host encoder passed the declaration's verification
96
+ * vectors, false when served unverified (verifyEncoder:false or
97
+ * allowUnverifiedEncoder), null when no host encoder was supplied.
98
+ * Kind 3: whether the inline encoder verified against its own vectors —
99
+ * null while a lazily-opened encoder has not arrived yet (unknown, not
100
+ * unverified; it resolves before the first query completes). While
101
+ * deferred, `encoder` serves the identity-verified manifest declaration
102
+ * with `deferred: true`, replaced by the full declaration on arrival.
103
+ * Kind 1: null (inline student encoder, nothing external to verify).
104
+ */
105
+ encoderVerified: boolean | null;
106
+ /**
107
+ * 'per-record-sha256' on format 2 (each hydrated record verified on its
108
+ * own range read); 'segment-sha256' on format 1 (whole-segment digests
109
+ * only, lazy record reads not independently verifiable).
110
+ */
111
+ corpusIntegrity: string;
112
+ fileBytes: number;
113
+ residentBytes: number;
114
+ residentVerified: boolean;
115
+ /**
116
+ * True only after a full vectors pass (verifyIndexVectors at open, or
117
+ * verifyVectors() later). Until then, lazily fetched rerank rows are
118
+ * committed via the identity-anchored vectorsSha256 but not verified
119
+ * per read.
120
+ */
121
+ vectorsVerified: boolean;
122
+ /**
123
+ * Present when the artifact carries a lexical index segment (kind 5):
124
+ * queries run hybrid (BM25 candidates join the exact rerank; result
125
+ * order fuses distance and BM25 rankings by reciprocal rank). Null on
126
+ * vector-only artifacts.
127
+ */
128
+ lexical: { terms: number; docCount: number; lazy?: true } | null;
129
+ /**
130
+ * 'engine' once a WASM scan kernel serves the resident scan
131
+ * (auto-staged or injected via options.sketchScanner); 'js' before
132
+ * background staging resolves and forever if it fails or was disabled.
133
+ */
134
+ residentScan: 'engine' | 'js';
135
+ sampleQueries: string[];
136
+ };
137
+ /**
138
+ * Verify the index's lazy vector rows against the identity-anchored
139
+ * vectorsSha256 (streamed where a streaming hash exists). Resolves true
140
+ * on match; throws on mismatch.
141
+ */
142
+ verifyVectors(options?: { chunkBytes?: number }): Promise<true>;
143
+ query(text: string, options?: {
144
+ k?: number;
145
+ /**
146
+ * Retrieval mode on artifacts carrying a lexical segment: 'hybrid'
147
+ * (default — BM25 candidates join the rerank, RRF result order),
148
+ * 'vector' (ignore the lexical index), 'lexical' (BM25 ranking only),
149
+ * 'augmented' (BM25 candidates join the exact rerank but results stay
150
+ * in pure distance order — the mode for workloads scored against
151
+ * exact nearest neighbors, where RRF's reordering reads as loss by
152
+ * definition; measured on the 456k wiki eval it lifts recall@10 from
153
+ * 82.8% to 85.3% while RRF-ordered hybrid scores 45.9% on that
154
+ * metric). Abstention scores identically in every mode.
155
+ */
156
+ retrieval?: 'hybrid' | 'vector' | 'lexical' | 'augmented';
157
+ rerank?: number;
158
+ parallelism?: number;
159
+ gap?: number;
160
+ maxRangeBytes?: number;
161
+ }): Promise<CompleteQueryResult>;
162
+ /** Hydrate one corpus record by id (verified per record on format 2). */
163
+ record(id: number): Promise<Record<string, unknown>>;
164
+ /** The evaluation segment's JSON object, or null when the artifact carries none. */
165
+ evaluation(): Promise<Record<string, unknown> | null>;
166
+ close(): Promise<void>;
167
+ }
168
+
169
+ export declare function openPancakeFile(
170
+ input: string | CompleteRangeSource,
171
+ options?: {
172
+ /**
173
+ * Required to serve kind-2 (declared external encoder) artifacts. It is
174
+ * run against the declaration's verification vectors at open and the
175
+ * open fails if any disagree beyond the declared tolerance.
176
+ */
177
+ encodeQuery?: (text: string) => Promise<Float32Array | number[]> | Float32Array | number[];
178
+ /** Skip encoder verification (kind 2 host vectors, kind 3 inline vectors). Default true. */
179
+ verifyEncoder?: boolean;
180
+ /** Serve a kind-2 declaration that carries no verification vectors, marked unverified. Default false. */
181
+ allowUnverifiedEncoder?: boolean;
182
+ /** Verify each hydrated record against its digest on format 2. Default true. */
183
+ verifyRecords?: boolean;
184
+ /**
185
+ * Pin the expected manifest identity (sha256 hex). Checked against the
186
+ * header one 64-byte read in — a mismatched artifact is refused before
187
+ * anything else is fetched; the manifest-hash verification then binds
188
+ * the header's claim to the manifest bytes as always.
189
+ */
190
+ expectedIdentity?: string;
191
+ /**
192
+ * Kind-3 artifacts open lazily: the ~25 MiB inline-encoder region is not
193
+ * read at open, and by default starts downloading in the background the
194
+ * moment open resolves (the first query awaits it; the whole segment is
195
+ * digest-verified on arrival, and the header/calibration slices used at
196
+ * open are byte-compared against it before any result is returned).
197
+ * Set false to defer the transfer entirely to the first query. Default
198
+ * true.
199
+ */
200
+ prefetchEncoder?: boolean;
201
+ /**
202
+ * Fully verify the index's lazy vector rows at open (one streamed pass
203
+ * against the identity-anchored vectorsSha256). Default false: without
204
+ * it, rows that feed reranking are covered by the whole-segment
205
+ * commitment but not verified per read until verifyVectors() runs —
206
+ * the documented transitional stance (spec section 6).
207
+ */
208
+ verifyIndexVectors?: boolean;
209
+ /**
210
+ * Budget for any single open-path read (manifest, segment table,
211
+ * query-interp, corpus tables, evaluation, digest pages), honored
212
+ * strictly. Default 256 MiB; Infinity defers to the 2 GiB backstop.
213
+ */
214
+ maxReadBytes?: number;
215
+ /** Budget for a single corpus record read. Default 16 MiB. */
216
+ maxRecordBytes?: number;
217
+ /** Override the kind-3 wasm kernel loader. */
218
+ createEncoder?: () => Promise<unknown> | unknown;
219
+ /**
220
+ * Resident-scan acceleration. Default (undefined): in Node, when the
221
+ * corpus is large enough that the pure-JS sketch scan dominates query
222
+ * time (~16M sketch cells), the engine's SIMD scan kernel is staged in
223
+ * the background and serves queries once ready — the JS scan answers
224
+ * identically until then and permanently if staging fails. Pass false
225
+ * to force the JS scan; a ready scanner object (createSketchScanner's
226
+ * shape — caller-owned, not disposed by close()); or an async factory
227
+ * (sketchArtifact) => scanner, invoked once the sketch is fully
228
+ * resident (the injection point for browser bundles, which cannot load
229
+ * the Node engine entrypoint).
230
+ */
231
+ sketchScanner?: false | { scan: (pooledQuery: unknown, c: number) => unknown }
232
+ | ((sketch: unknown) => unknown | Promise<unknown>);
233
+ rerankParallelism?: number;
234
+ rerankGap?: number;
235
+ rerankMaxRangeBytes?: number;
236
+ }
237
+ ): Promise<CompleteSearch>;
238
+
239
+ /** Header formatVersion -> manifest profile accepted by this reader. */
240
+ export declare const SUPPORTED_PROFILES: Readonly<Record<number, string>>;
241
+ export declare const CORPUS_LAYOUT_V2: 'records-v2';
242
+ /**
243
+ * Check a host encoder against a kind-2 declaration's verification vectors
244
+ * (contract 4.4 mode 2) without opening an artifact. Throws on dimension
245
+ * or tolerance disagreement; resolves with the number of vectors checked.
246
+ */
247
+ export declare function verifyHostEncoder(
248
+ declaration: Record<string, unknown>,
249
+ encodeQuery: (text: string) => Promise<Float32Array | number[]> | Float32Array | number[],
250
+ dim: number
251
+ ): Promise<{ checked: number }>;
252
+
253
+ /** Kernel layout compiled into the kind-3 encoder (mirrors encoder.cpp). */
254
+ export declare const KERNEL_LAYOUT: Record<'V' | 'P' | 'T' | 'D' | 'F' | 'L' | 'B' | 'H', number>;
255
+ export declare function expectedBlobBytes(layout?: Record<string, number>): number;
256
+ export declare function parseInlineTransformerEncoder(encoderBytes: Uint8Array): {
257
+ declaration: Record<string, unknown>;
258
+ vocabText: string;
259
+ blob: Uint8Array;
260
+ };
261
+ export declare function createInlineTransformerEmbedder(input: {
262
+ declaration: Record<string, unknown>;
263
+ vocabText: string;
264
+ blob: Uint8Array;
265
+ createEncoder: () => Promise<unknown> | unknown;
266
+ verify?: boolean;
267
+ }): Promise<{
268
+ declaration: Record<string, unknown>;
269
+ dim: number;
270
+ maxSeq: number;
271
+ embed(text: string): Promise<{ vector: Float32Array; text: string; windows: number }>;
272
+ dispose(): void;
273
+ }>;
274
+ /**
275
+ * Assert an expected verification-vector embedding is exactly dim finite
276
+ * numbers; throws otherwise. Malformed expectations would otherwise make
277
+ * every comparison NaN and "pass".
278
+ */
279
+ export declare function validateExpectedEmbedding(values: unknown, dim: number, label: string): void;
280
+ /** Validate (or default to 1e-3) a verification vector's tolerance. */
281
+ export declare function validateTestVectorTolerance(tolerance: unknown, label: string): number;
282
+ export declare const INLINE_TEST_VECTOR_TEXTS: string[];
283
+ export declare function buildInlineTestVectors(embedder: unknown, texts?: string[]): Promise<Array<{
284
+ text: string; windows: number; embedding: number[]; tolerance: number;
285
+ }>>;
286
+ export declare function verifyInlineTestVectors(embedder: unknown): Promise<{ checked: number }>;
287
+
288
+ /** Documented alias for openPancakeFile — the project renamed to Pikelet; the reader's original export stays for compatibility. */
289
+ export declare const openPikeletFile: typeof openPancakeFile;