@delali/narsil 0.2.0 → 0.2.1-next.25

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.
Files changed (151) hide show
  1. package/dist/adapters/filesystem.d.ts +23 -1
  2. package/dist/adapters/filesystem.mjs +1 -1
  3. package/dist/adapters/indexeddb.d.ts +25 -1
  4. package/dist/adapters/indexeddb.mjs +1 -1
  5. package/dist/adapters/memory.d.ts +14 -1
  6. package/dist/adapters-CVqI5NBt.d.ts +149 -0
  7. package/dist/{chunk-S6IAXOBA.mjs → chunk-ASI6AOW2.mjs} +1 -1
  8. package/dist/{chunk-AUMKFYTG.mjs → chunk-FKK76OR7.mjs} +56 -55
  9. package/dist/{chunk-M2EDG55Y.mjs → chunk-UNJZ7ZDB.mjs} +10 -0
  10. package/dist/{chunk-XAKNSWIK.mjs → chunk-WLR5BFL3.mjs} +16 -14
  11. package/dist/config-CAjTHzkH.d.ts +256 -0
  12. package/dist/{direct-executor-2FV3MEDD.mjs → direct-executor-3W4QRA4E.mjs} +2 -2
  13. package/dist/distribution/coordinator/etcd.d.ts +44 -3
  14. package/dist/distribution/coordinator/etcd.mjs +2 -2
  15. package/dist/distribution/coordinator/in-memory.d.ts +14 -3
  16. package/dist/distribution.d.ts +312 -45
  17. package/dist/distribution.mjs +4 -4
  18. package/dist/embeddings/openai.d.ts +28 -1
  19. package/dist/embeddings/openai.mjs +1 -1
  20. package/dist/engine-CCrlfLyq.d.ts +431 -0
  21. package/dist/index.browser.mjs +24 -12
  22. package/dist/index.d.ts +173 -8
  23. package/dist/index.mjs +3 -3
  24. package/dist/invalidation/broadcast-channel.d.ts +20 -1
  25. package/dist/invalidation/filesystem.d.ts +24 -1
  26. package/dist/invalidation/noop.d.ts +14 -1
  27. package/dist/language-DB8KG1z5.d.ts +53 -0
  28. package/dist/languages/albanian.d.ts +11 -1
  29. package/dist/languages/amharic.d.ts +11 -1
  30. package/dist/languages/arabic.d.ts +10 -1
  31. package/dist/languages/armenian.d.ts +10 -1
  32. package/dist/languages/azerbaijani.d.ts +11 -1
  33. package/dist/languages/bambara.d.ts +11 -1
  34. package/dist/languages/basque.d.ts +10 -1
  35. package/dist/languages/belarusian.d.ts +11 -1
  36. package/dist/languages/bengali.d.ts +11 -1
  37. package/dist/languages/bosnian.d.ts +11 -1
  38. package/dist/languages/breton.d.ts +11 -1
  39. package/dist/languages/bulgarian.d.ts +10 -1
  40. package/dist/languages/burmese.d.ts +11 -1
  41. package/dist/languages/catalan.d.ts +10 -1
  42. package/dist/languages/chinese.d.ts +11 -1
  43. package/dist/languages/croatian.d.ts +11 -1
  44. package/dist/languages/czech.d.ts +10 -1
  45. package/dist/languages/dagbani.d.ts +11 -1
  46. package/dist/languages/danish.d.ts +10 -1
  47. package/dist/languages/dutch.d.ts +10 -1
  48. package/dist/languages/english.d.ts +10 -1
  49. package/dist/languages/esperanto.d.ts +10 -1
  50. package/dist/languages/estonian.d.ts +10 -1
  51. package/dist/languages/ewe.d.ts +11 -1
  52. package/dist/languages/faroese.d.ts +11 -1
  53. package/dist/languages/fijian.d.ts +11 -1
  54. package/dist/languages/finnish.d.ts +10 -1
  55. package/dist/languages/french.d.ts +10 -1
  56. package/dist/languages/ga.d.ts +11 -1
  57. package/dist/languages/galician.d.ts +11 -1
  58. package/dist/languages/georgian.d.ts +11 -1
  59. package/dist/languages/german.d.ts +10 -1
  60. package/dist/languages/greek.d.ts +10 -1
  61. package/dist/languages/guarani.d.ts +11 -1
  62. package/dist/languages/gujarati.d.ts +11 -1
  63. package/dist/languages/haitian-creole.d.ts +11 -1
  64. package/dist/languages/hausa.d.ts +11 -1
  65. package/dist/languages/hawaiian.d.ts +11 -1
  66. package/dist/languages/hebrew.d.ts +11 -1
  67. package/dist/languages/hindi.d.ts +10 -1
  68. package/dist/languages/hungarian.d.ts +10 -1
  69. package/dist/languages/icelandic.d.ts +11 -1
  70. package/dist/languages/igbo.d.ts +11 -1
  71. package/dist/languages/indonesian.d.ts +10 -1
  72. package/dist/languages/irish.d.ts +10 -1
  73. package/dist/languages/italian.d.ts +10 -1
  74. package/dist/languages/japanese.d.ts +11 -1
  75. package/dist/languages/kannada.d.ts +11 -1
  76. package/dist/languages/kazakh.d.ts +11 -1
  77. package/dist/languages/khmer.d.ts +11 -1
  78. package/dist/languages/kinyarwanda.d.ts +11 -1
  79. package/dist/languages/kirundi.d.ts +11 -1
  80. package/dist/languages/korean.d.ts +11 -1
  81. package/dist/languages/kurmanji.d.ts +11 -1
  82. package/dist/languages/kyrgyz.d.ts +11 -1
  83. package/dist/languages/lao.d.ts +11 -1
  84. package/dist/languages/latin.d.ts +11 -1
  85. package/dist/languages/latvian.d.ts +11 -1
  86. package/dist/languages/lingala.d.ts +11 -1
  87. package/dist/languages/lithuanian.d.ts +10 -1
  88. package/dist/languages/luxembourgish.d.ts +11 -1
  89. package/dist/languages/macedonian.d.ts +11 -1
  90. package/dist/languages/malagasy.d.ts +11 -1
  91. package/dist/languages/malay.d.ts +11 -1
  92. package/dist/languages/malayalam.d.ts +11 -1
  93. package/dist/languages/maltese.d.ts +11 -1
  94. package/dist/languages/maori.d.ts +11 -1
  95. package/dist/languages/marathi.d.ts +11 -1
  96. package/dist/languages/nepali.d.ts +10 -1
  97. package/dist/languages/norwegian.d.ts +10 -1
  98. package/dist/languages/oromo.d.ts +11 -1
  99. package/dist/languages/persian.d.ts +10 -1
  100. package/dist/languages/polish.d.ts +10 -1
  101. package/dist/languages/portuguese.d.ts +10 -1
  102. package/dist/languages/punjabi.d.ts +11 -1
  103. package/dist/languages/romanian.d.ts +10 -1
  104. package/dist/languages/russian.d.ts +10 -1
  105. package/dist/languages/samoan.d.ts +11 -1
  106. package/dist/languages/sanskrit.d.ts +10 -1
  107. package/dist/languages/scottish-gaelic.d.ts +11 -1
  108. package/dist/languages/serbian.d.ts +10 -1
  109. package/dist/languages/shona.d.ts +11 -1
  110. package/dist/languages/sinhala.d.ts +11 -1
  111. package/dist/languages/slovak.d.ts +11 -1
  112. package/dist/languages/slovenian.d.ts +10 -1
  113. package/dist/languages/sorani.d.ts +11 -1
  114. package/dist/languages/spanish.d.ts +10 -1
  115. package/dist/languages/swahili.d.ts +10 -1
  116. package/dist/languages/swedish.d.ts +10 -1
  117. package/dist/languages/tagalog.d.ts +11 -1
  118. package/dist/languages/tamil.d.ts +10 -1
  119. package/dist/languages/tatar.d.ts +11 -1
  120. package/dist/languages/telugu.d.ts +11 -1
  121. package/dist/languages/thai.d.ts +11 -1
  122. package/dist/languages/tibetan.d.ts +11 -1
  123. package/dist/languages/tigrinya.d.ts +11 -1
  124. package/dist/languages/tongan.d.ts +11 -1
  125. package/dist/languages/turkish.d.ts +10 -1
  126. package/dist/languages/twi.d.ts +11 -1
  127. package/dist/languages/ukrainian.d.ts +10 -1
  128. package/dist/languages/urdu.d.ts +11 -1
  129. package/dist/languages/vietnamese.d.ts +11 -1
  130. package/dist/languages/welsh.d.ts +11 -1
  131. package/dist/languages/wolof.d.ts +11 -1
  132. package/dist/languages/xhosa.d.ts +11 -1
  133. package/dist/languages/yoruba.d.ts +11 -1
  134. package/dist/languages/zulu.d.ts +11 -1
  135. package/dist/persistence/durability/checkpoint-worker.d.ts +2 -2
  136. package/dist/persistence/durability/checkpoint-worker.mjs +3 -3
  137. package/dist/schema-CE6S_aAr.d.ts +208 -0
  138. package/dist/search-CgQQIciB.d.ts +786 -0
  139. package/dist/server.d.ts +213 -12
  140. package/dist/server.mjs +29 -1
  141. package/dist/types-BV3nAKTL.d.ts +302 -0
  142. package/dist/vector/hnsw-build-worker.d.ts +68 -2
  143. package/dist/vector/hnsw-build-worker.mjs +0 -2
  144. package/dist/workers/entry.mjs +1 -1
  145. package/package.json +5 -2
  146. package/dist/adapters-Bo2JQg8b.d.ts +0 -37
  147. package/dist/config-P27AtSn4.d.ts +0 -502
  148. package/dist/language-CmJBHf1j.d.ts +0 -17
  149. package/dist/narsil-CMZRPDlQ.d.ts +0 -159
  150. package/dist/schema-BnvLvjRp.d.ts +0 -67
  151. package/dist/types-BRTcBgAp.d.ts +0 -73
@@ -0,0 +1,302 @@
1
+ import { b as SchemaDefinition } from './schema-CE6S_aAr.js';
2
+
3
+ /**
4
+ * What a node does in a cluster. A node may hold several roles at once.
5
+ *
6
+ * A `data` node holds partitions and answers queries, a `coordinator` node
7
+ * routes requests without holding data, and a `controller` node runs the
8
+ * allocation decisions for the whole cluster.
9
+ *
10
+ * @public
11
+ */
12
+ type NodeRole = 'data' | 'coordinator' | 'controller';
13
+ /**
14
+ * Where one partition stands in its move between nodes.
15
+ *
16
+ * `ACTIVE` is the steady state. `INITIALISING` means a node is still filling
17
+ * it, `MIGRATING` means it is moving, `DECOMMISSIONING` means it is being
18
+ * drained, and `UNASSIGNED` means no node holds it.
19
+ *
20
+ * @public
21
+ */
22
+ type PartitionState = 'UNASSIGNED' | 'INITIALISING' | 'ACTIVE' | 'MIGRATING' | 'DECOMMISSIONING';
23
+ /**
24
+ * What one node has to offer, which the allocator weighs when it places
25
+ * partitions.
26
+ *
27
+ * @public
28
+ */
29
+ interface NodeCapacity {
30
+ /** The node can give this much memory to indexes. */
31
+ memoryBytes: number;
32
+ /** The node has this many cores available. */
33
+ cpuCores: number;
34
+ /** The node can give this much disk to durability, and reports `null` when it keeps nothing on disk. */
35
+ diskBytes: number | null;
36
+ }
37
+ /**
38
+ * What a node publishes about itself when it joins a cluster.
39
+ *
40
+ * @public
41
+ */
42
+ interface NodeRegistration {
43
+ /** This identifies the node across the cluster, and must stay stable across restarts. */
44
+ nodeId: string;
45
+ /** Peers reach the node at this address, as the transport writes it. */
46
+ address: string;
47
+ /** The node holds these roles in the cluster. */
48
+ roles: NodeRole[];
49
+ /** The node offers this much capacity. */
50
+ capacity: NodeCapacity;
51
+ /** The node started at this ISO 8601 timestamp. */
52
+ startedAt: string;
53
+ /** The node runs this engine version, which is what a mixed-version cluster reads. */
54
+ version: string;
55
+ /** These free-form labels are where a zone or rack goes for zone-aware allocation. */
56
+ metadata?: Record<string, string>;
57
+ }
58
+ /**
59
+ * Which nodes hold one partition, and where that partition stands.
60
+ *
61
+ * @public
62
+ */
63
+ interface PartitionAssignment {
64
+ /** This node accepts writes, and it is `null` while no node holds the partition. */
65
+ primary: string | null;
66
+ /** These nodes each hold a copy, including the primary. */
67
+ replicas: string[];
68
+ /** These replicas are current enough to be promoted, which is the set a failover picks from. */
69
+ inSyncSet: string[];
70
+ /** This says where the partition stands in its move between nodes. */
71
+ state: PartitionState;
72
+ /** This rises each time the primary changes, which is what makes a stale primary's writes detectable. */
73
+ primaryTerm: number;
74
+ }
75
+ /**
76
+ * How one index's partitions are spread across the cluster.
77
+ *
78
+ * @public
79
+ */
80
+ interface AllocationTable {
81
+ /** The table covers this index. */
82
+ indexName: string;
83
+ /** This rises on every change, so a writer detects that another controller got there first. */
84
+ version: number;
85
+ /** The cluster keeps this many copies of each partition. */
86
+ replicationFactor: number;
87
+ /** These assignments are keyed by partition id. */
88
+ assignments: Map<number, PartitionAssignment>;
89
+ }
90
+ /**
91
+ * Tells watchers that a node joined or left.
92
+ *
93
+ * @public
94
+ */
95
+ interface NodeEvent {
96
+ /** This says which change it is. */
97
+ type: 'node_joined' | 'node_left';
98
+ /** This node joined or left. */
99
+ nodeId: string;
100
+ /** The node published this on joining, and it is `null` when the node left. */
101
+ registration: NodeRegistration | null;
102
+ }
103
+ /**
104
+ * Tells watchers that an index's allocation changed.
105
+ *
106
+ * @public
107
+ */
108
+ interface AllocationEvent {
109
+ /** This index's allocation changed. */
110
+ indexName: string;
111
+ /** The allocation now stands like this. */
112
+ table: AllocationTable;
113
+ }
114
+ /**
115
+ * Tells watchers that an index's schema was published or dropped.
116
+ *
117
+ * @public
118
+ */
119
+ interface SchemaEvent {
120
+ /** This says which change it is. */
121
+ type: 'schema_created' | 'schema_dropped';
122
+ /** This index's schema changed. */
123
+ indexName: string;
124
+ /** This is the schema, and it is `null` when the index was dropped. */
125
+ schema: SchemaDefinition | null;
126
+ }
127
+ /**
128
+ * The rules the allocator respects when it places partitions.
129
+ *
130
+ * The controller stores these with each index's metadata, so every node
131
+ * allocating that index applies the same rules.
132
+ *
133
+ * @public
134
+ */
135
+ interface AllocationConstraints {
136
+ /** Setting this spreads an index's replicas across zones, so losing one zone never costs every copy. */
137
+ zoneAwareness: boolean;
138
+ /** This names the key in a node's `metadata` that carries its zone. */
139
+ zoneAttribute: string;
140
+ /** One node may hold this many partitions of an index, and `null` lifts the ceiling. */
141
+ maxShardsPerNode: number | null;
142
+ }
143
+ /**
144
+ * The shared state every cluster node reads and writes: which nodes exist,
145
+ * which node holds each partition, who holds which lease, and what each
146
+ * index's schema is.
147
+ *
148
+ * The package includes an etcd-backed coordinator for real deployments and an
149
+ * in-memory one for tests, and this is the contract either satisfies. Write
150
+ * your own to run a cluster on another store, so long as
151
+ * {@link ClusterCoordinator.compareAndSet} and the lease calls are atomic,
152
+ * because the controller election depends on them.
153
+ *
154
+ * @public
155
+ */
156
+ interface ClusterCoordinator {
157
+ /**
158
+ * Publishes a node so that peers find it, and keeps it published while the
159
+ * node heartbeats.
160
+ *
161
+ * @param registration - What the node publishes about itself.
162
+ */
163
+ registerNode(registration: NodeRegistration): Promise<void>;
164
+ /**
165
+ * Removes a node, so the controller reallocates whatever it held.
166
+ *
167
+ * @param nodeId - The node to remove.
168
+ */
169
+ deregisterNode(nodeId: string): Promise<void>;
170
+ /**
171
+ * Lists the nodes currently published.
172
+ *
173
+ * @returns One registration per live node.
174
+ */
175
+ listNodes(): Promise<NodeRegistration[]>;
176
+ /**
177
+ * Watches nodes joining and leaving.
178
+ *
179
+ * @param handler - Called once per change.
180
+ * @returns A function that ends the watch.
181
+ */
182
+ watchNodes(handler: (event: NodeEvent) => void): Promise<() => void>;
183
+ /**
184
+ * Reads one index's allocation.
185
+ *
186
+ * @param indexName - The index to read.
187
+ * @returns Its allocation, or `null` when the index has none yet.
188
+ */
189
+ getAllocation(indexName: string): Promise<AllocationTable | null>;
190
+ /**
191
+ * Writes one index's allocation, optionally only while nobody else has
192
+ * changed it first.
193
+ *
194
+ * @param indexName - The index to write.
195
+ * @param table - The allocation to store.
196
+ * @param expectedVersion - The version the caller read, `null` to write only
197
+ * while no allocation exists, or omit it to write unconditionally.
198
+ * @returns True when the write went through, and false when the expected
199
+ * version no longer matched.
200
+ */
201
+ putAllocation(indexName: string, table: AllocationTable, expectedVersion?: number | null): Promise<boolean>;
202
+ /**
203
+ * Watches allocations changing.
204
+ *
205
+ * @param handler - Called once per change.
206
+ * @returns A function that ends the watch.
207
+ */
208
+ watchAllocation(handler: (event: AllocationEvent) => void): Promise<() => void>;
209
+ /**
210
+ * Reads where one partition stands.
211
+ *
212
+ * @param indexName - Index the partition belongs to.
213
+ * @param partitionId - The partition to read.
214
+ * @returns Its state, or `UNASSIGNED` when nothing is recorded.
215
+ */
216
+ getPartitionState(indexName: string, partitionId: number): Promise<PartitionState>;
217
+ /**
218
+ * Records where one partition stands.
219
+ *
220
+ * @param indexName - Index the partition belongs to.
221
+ * @param partitionId - The partition to record.
222
+ * @param state - Its new state.
223
+ */
224
+ putPartitionState(indexName: string, partitionId: number, state: PartitionState): Promise<void>;
225
+ /**
226
+ * Takes a lease, which is how one node wins the controller election.
227
+ *
228
+ * @param key - The lease to take.
229
+ * @param nodeId - The node taking it.
230
+ * @param ttlMs - Milliseconds the lease survives without renewal.
231
+ * @returns True when this node now holds the lease.
232
+ */
233
+ acquireLease(key: string, nodeId: string, ttlMs: number): Promise<boolean>;
234
+ /**
235
+ * Extends a lease this node already holds.
236
+ *
237
+ * @param key - The lease to extend.
238
+ * @param nodeId - The node that holds it.
239
+ * @param ttlMs - Milliseconds the lease survives from now.
240
+ * @returns True when the lease was extended, and false once it has been
241
+ * lost, which means the node has to step down.
242
+ */
243
+ renewLease(key: string, nodeId: string, ttlMs: number): Promise<boolean>;
244
+ /**
245
+ * Gives a lease up straight away, rather than waiting for it to expire.
246
+ *
247
+ * @param key - The lease to release.
248
+ */
249
+ releaseLease(key: string): Promise<void>;
250
+ /**
251
+ * Reads one key of cluster metadata.
252
+ *
253
+ * @param key - The key to read.
254
+ * @returns Its bytes, or `null` when the key holds nothing.
255
+ */
256
+ get(key: string): Promise<Uint8Array | null>;
257
+ /**
258
+ * Writes one key of cluster metadata only while it still holds what the
259
+ * caller read, which is what makes concurrent controllers safe.
260
+ *
261
+ * @param key - The key to write.
262
+ * @param expected - The bytes the caller read, or `null` to write only while
263
+ * the key holds nothing.
264
+ * @param value - The bytes to store.
265
+ * @returns True when the write went through.
266
+ */
267
+ compareAndSet(key: string, expected: Uint8Array | null, value: Uint8Array): Promise<boolean>;
268
+ /**
269
+ * Reads one index's schema, which is how a node joining later learns the
270
+ * layout of an index it has never held.
271
+ *
272
+ * @param indexName - The index to read.
273
+ * @returns Its schema, or `null` when the index is unknown.
274
+ */
275
+ getSchema(indexName: string): Promise<SchemaDefinition | null>;
276
+ /**
277
+ * Publishes one index's schema to the cluster.
278
+ *
279
+ * @param indexName - The index to publish.
280
+ * @param schema - Its field layout.
281
+ */
282
+ putSchema(indexName: string, schema: SchemaDefinition): Promise<void>;
283
+ /**
284
+ * Watches schemas being published and dropped.
285
+ *
286
+ * @param handler - Called once per change.
287
+ * @returns A function that ends the watch.
288
+ */
289
+ watchSchemas(handler: (event: SchemaEvent) => void): Promise<() => void>;
290
+ /**
291
+ * Reads which node holds a lease, which is how a node finds the active
292
+ * controller.
293
+ *
294
+ * @param key - The lease to look up.
295
+ * @returns The holder's node id, or `null` when nobody holds it.
296
+ */
297
+ getLeaseHolder(key: string): Promise<string | null>;
298
+ /** Releases every lease and watch this node opened, then closes the connection. */
299
+ shutdown(): Promise<void>;
300
+ }
301
+
302
+ export type { AllocationTable as A, ClusterCoordinator as C, NodeRole as N, PartitionAssignment as P, SchemaEvent as S, NodeCapacity as a, AllocationConstraints as b, AllocationEvent as c, NodeEvent as d, NodeRegistration as e, PartitionState as f };
@@ -1,44 +1,110 @@
1
+ /**
2
+ * Similarity metric a vector search ranks by.
3
+ *
4
+ * @internal
5
+ */
1
6
  type VectorMetric = 'cosine' | 'dotProduct' | 'euclidean';
2
7
 
8
+ /**
9
+ * How an HNSW graph is built.
10
+ *
11
+ * @internal
12
+ */
3
13
  interface HNSWConfig {
14
+ /** Each node keeps this many neighbours per layer. */
4
15
  m?: number;
16
+ /** The builder explores this many candidates while placing each node. */
5
17
  efConstruction?: number;
18
+ /** The graph ranks by this metric. */
6
19
  metric?: VectorMetric;
7
20
  }
21
+ /**
22
+ * An HNSW graph in the form the engine passes between threads.
23
+ *
24
+ * @internal
25
+ */
8
26
  interface SerializedHNSWGraph {
27
+ /** Every search starts at this node, and it is `null` while the graph is empty. */
9
28
  entryPoint: string | null;
29
+ /** The graph reaches this many layers. */
10
30
  maxLayer: number;
31
+ /** Each node keeps this many neighbours per layer. */
11
32
  m: number;
33
+ /** The builder explored this many candidates while placing each node. */
12
34
  efConstruction: number;
35
+ /** The graph ranks by this metric. */
13
36
  metric?: VectorMetric;
37
+ /** Each entry holds a document id, its top layer, and its neighbours per layer. */
14
38
  nodes: Array<[string, number, Array<[number, string[]]>]>;
15
39
  }
16
40
 
41
+ /**
42
+ * Asks the build worker to construct a graph from vectors sent as arrays.
43
+ *
44
+ * This module is the worker's own entry point, and the engine posts these
45
+ * messages to it. It exists so that a bundler can resolve the worker file, and
46
+ * nothing here is part of the engine's supported surface.
47
+ *
48
+ * @internal
49
+ */
17
50
  interface HNSWBuildRequest {
51
+ /** This marks the message as an array-form build request. */
18
52
  type: 'build';
53
+ /** The worker indexes these vectors, each carrying the document id it belongs to. */
19
54
  vectors: Array<{
20
55
  docId: string;
21
56
  values: number[];
22
57
  }>;
58
+ /** Each vector carries this many components. */
23
59
  dimension: number;
60
+ /** The worker builds to this graph shape, clamped to safe bounds first. */
24
61
  config: HNSWConfig;
25
62
  }
63
+ /**
64
+ * Asks the build worker to construct a graph from vectors packed into one
65
+ * transferable buffer, which is what the engine sends for a large field.
66
+ *
67
+ * @internal
68
+ */
26
69
  interface HNSWBuildRequestBinary {
70
+ /** This marks the message as a packed-buffer build request. */
27
71
  type: 'build-binary';
72
+ /** These document ids run in the order their vectors appear in the buffer. */
28
73
  docIds: string[];
74
+ /** This holds every vector end to end, `docIds.length * dimension` components long. */
29
75
  vectorData: Float32Array;
76
+ /** Each vector carries this many components. */
30
77
  dimension: number;
78
+ /** The worker builds to this graph shape, clamped to safe bounds first. */
31
79
  config: HNSWConfig;
32
80
  }
81
+ /**
82
+ * What the build worker returns once a graph is built.
83
+ *
84
+ * @internal
85
+ */
33
86
  interface HNSWBuildResponse {
87
+ /** This marks the message as a completed build. */
34
88
  type: 'success';
89
+ /** This graph is ready for the engine to adopt. */
35
90
  graph: SerializedHNSWGraph;
36
91
  }
92
+ /**
93
+ * What the build worker returns when a build fails.
94
+ *
95
+ * @internal
96
+ */
37
97
  interface HNSWBuildError {
98
+ /** This marks the message as a failed build. */
38
99
  type: 'error';
100
+ /** This says why the build failed. */
39
101
  message: string;
40
102
  }
103
+ /**
104
+ * Either message the build worker posts back.
105
+ *
106
+ * @internal
107
+ */
41
108
  type HNSWWorkerMessage = HNSWBuildResponse | HNSWBuildError;
42
- declare function handleBuildRequest(request: HNSWBuildRequest): SerializedHNSWGraph;
43
109
 
44
- export { type HNSWBuildError, type HNSWBuildRequest, type HNSWBuildRequestBinary, type HNSWBuildResponse, type HNSWWorkerMessage, handleBuildRequest };
110
+ export type { HNSWBuildError, HNSWBuildRequest, HNSWBuildRequestBinary, HNSWBuildResponse, HNSWConfig, HNSWWorkerMessage, SerializedHNSWGraph, VectorMetric };
@@ -121,5 +121,3 @@ async function setupAsync() {
121
121
  }
122
122
  }
123
123
  setupWorker();
124
-
125
- export { handleBuildRequest };
@@ -15,7 +15,7 @@ async function setup() {
15
15
  } catch {
16
16
  parentPort = null;
17
17
  }
18
- const { createDirectExecutor } = await import('../direct-executor-2FV3MEDD.mjs');
18
+ const { createDirectExecutor } = await import('../direct-executor-3W4QRA4E.mjs');
19
19
  const executor = createDirectExecutor();
20
20
  function buildErrorResponse(requestId, code, message) {
21
21
  return { type: "error", requestId, code, message };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delali/narsil",
3
- "version": "0.2.0",
3
+ "version": "0.2.1-next.25",
4
4
  "type": "module",
5
5
  "description": "A distributed full-text search engine with cross-language portable binary format.",
6
6
  "author": "Delali (https://sondelali.com)",
@@ -117,6 +117,7 @@
117
117
  },
118
118
  "devDependencies": {
119
119
  "@biomejs/biome": "2.4.4",
120
+ "@microsoft/api-extractor": "7.58.12",
120
121
  "@types/node": "22.15.32",
121
122
  "@vitest/coverage-v8": "4.0.18",
122
123
  "etcd3": "1.1.2",
@@ -143,7 +144,7 @@
143
144
  }
144
145
  },
145
146
  "scripts": {
146
- "build": "tsup && node scripts/check-browser-bundle.mjs",
147
+ "build": "tsup && node scripts/check-browser-bundle.mjs && tsx scripts/api-surface.ts",
147
148
  "test": "vitest run --exclude='**/vector/recall.test.ts'",
148
149
  "test:etcd": "vitest run src/__tests__/distribution/coordinator/etcd-integration/*.test.ts",
149
150
  "test:watch": "vitest",
@@ -154,6 +155,8 @@
154
155
  "stemmers": "tsx snowball/build.ts",
155
156
  "revisions": "tsx scripts/analysis-revisions.ts",
156
157
  "revisions:write": "tsx scripts/analysis-revisions.ts --write",
158
+ "api": "tsx scripts/api-surface.ts",
159
+ "api:write": "tsx scripts/api-surface.ts --write",
157
160
  "lookalikes": "tsx scripts/lookalike-counts.ts",
158
161
  "lookalikes:collect": "tsx scripts/lookalike-counts.ts --collect",
159
162
  "lint": "biome check src/",
@@ -1,37 +0,0 @@
1
- interface PersistenceAdapter {
2
- save(key: string, data: Uint8Array): Promise<void>;
3
- load(key: string): Promise<Uint8Array | null>;
4
- delete(key: string): Promise<void>;
5
- list(prefix: string): Promise<string[]>;
6
- readonly directory?: string;
7
- }
8
- interface InvalidationAdapter {
9
- publish(event: InvalidationEvent): Promise<void>;
10
- subscribe(handler: (event: InvalidationEvent) => void): Promise<void>;
11
- shutdown(): Promise<void>;
12
- }
13
- type InvalidationEvent = {
14
- type: 'partition';
15
- indexName: string;
16
- partitions: number[];
17
- timestamp: number;
18
- sourceInstanceId: string;
19
- } | {
20
- type: 'statistics';
21
- indexName: string;
22
- instanceId: string;
23
- stats: PartitionStatistics;
24
- };
25
- interface PartitionStatistics {
26
- totalDocs: number;
27
- docFrequencies: Record<string, number>;
28
- totalFieldLengths: Record<string, number>;
29
- }
30
- interface EmbeddingAdapter {
31
- embed(input: string, purpose: 'document' | 'query', signal?: AbortSignal): Promise<Float32Array>;
32
- embedBatch?(inputs: string[], purpose: 'document' | 'query', signal?: AbortSignal): Promise<Float32Array[]>;
33
- readonly dimensions: number;
34
- shutdown?(): Promise<void>;
35
- }
36
-
37
- export type { EmbeddingAdapter as E, InvalidationAdapter as I, PartitionStatistics as P, InvalidationEvent as a, PersistenceAdapter as b };